feat(coding-agent): print resume hint on interactive exit

This commit is contained in:
Michael Yu
2026-05-29 15:56:42 +08:00
parent 7be8a10d23
commit 17e9e87576
3 changed files with 246 additions and 1 deletions

View File

@@ -47,6 +47,7 @@ import {
TUI,
visibleWidth,
} from "@earendil-works/pi-tui";
import chalk from "chalk";
import { spawn, spawnSync } from "child_process";
import {
APP_NAME,
@@ -194,6 +195,28 @@ function isUnknownModel(model: Model<any> | undefined): boolean {
return !!model && model.provider === "unknown" && model.id === "unknown" && model.api === "unknown";
}
function quoteIfNeeded(value: string): string {
if (value.length > 0 && !/[^a-zA-Z0-9_\-./~:@]/.test(value)) {
return value;
}
return `'${value.replace(/'/g, `'\\''`)}'`;
}
export function formatResumeCommand(sessionManager: SessionManager): string | undefined {
if (!process.stdout.isTTY) return undefined;
if (!sessionManager.isPersisted()) return undefined;
const sessionFile = sessionManager.getSessionFile();
if (!sessionFile || !fs.existsSync(sessionFile)) return undefined;
const args = [APP_NAME];
if (!sessionManager.usesDefaultSessionDir()) {
args.push("--session-dir", quoteIfNeeded(sessionManager.getSessionDir()));
}
args.push("--session", sessionManager.getSessionId());
return args.join(" ");
}
function hasDefaultModelProvider(providerId: string): providerId is keyof typeof defaultModelPerProvider {
return providerId in defaultModelPerProvider;
}
@@ -3276,6 +3299,12 @@ export class InteractiveMode {
this.stop();
await this.runtimeHost.dispose();
const resumeCommand = formatResumeCommand(this.sessionManager);
if (resumeCommand) {
process.stdout.write(` ${chalk.dim("To resume this session:")} ${resumeCommand}\n`);
}
process.exit(0);
}