feat: add session resume capability with automatic continuation

Add ability to resume inactive sessions and automatically continue with new
session ID. Includes message merging for preserving conversation history,
UI improvements to allow sending during inactive state, and database schema
migration. close #87
This commit is contained in:
weishu
2026-01-27 14:44:53 +08:00
parent 7a8f1c3e87
commit 87c79c3b94
24 changed files with 534 additions and 70 deletions
+2 -1
View File
@@ -101,7 +101,7 @@ export class ApiMachineClient {
setRPCHandlers({ spawnSession, stopSession, requestShutdown }: MachineRpcHandlers): void {
this.rpcHandlerManager.registerHandler('spawn-happy-session', async (params: any) => {
const { directory, sessionId, machineId, approvedNewDirectoryCreation, agent, model, yolo, token, sessionType, worktreeName } = params || {}
const { directory, sessionId, resumeSessionId, machineId, approvedNewDirectoryCreation, agent, model, yolo, token, sessionType, worktreeName } = params || {}
if (!directory) {
throw new Error('Directory is required')
@@ -110,6 +110,7 @@ export class ApiMachineClient {
const result = await spawnSession({
directory,
sessionId,
resumeSessionId,
machineId,
approvedNewDirectoryCreation,
agent,
+1
View File
@@ -2,6 +2,7 @@ export interface SpawnSessionOptions {
machineId?: string
directory: string
sessionId?: string
resumeSessionId?: string
approvedNewDirectoryCreation?: boolean
agent?: 'claude' | 'codex' | 'gemini'
model?: string
+10 -7
View File
@@ -328,11 +328,15 @@ export async function startRunner(): Promise<void> {
: agent === 'gemini'
? 'gemini'
: 'claude';
const args = [
agentCommand,
'--hapi-starting-mode', 'remote',
'--started-by', 'runner'
];
const args = [agentCommand];
if (options.resumeSessionId) {
if (agent === 'codex') {
args.push('resume', options.resumeSessionId);
} else {
args.push('--resume', options.resumeSessionId);
}
}
args.push('--hapi-starting-mode', 'remote', '--started-by', 'runner');
if (options.model) {
args.push('--model', options.model);
}
@@ -340,8 +344,7 @@ export async function startRunner(): Promise<void> {
args.push('--yolo');
}
// TODO: In future, sessionId could be used with --resume to continue existing sessions
// For now, we ignore it - each spawn creates a new session
// sessionId reserved for future use
const MAX_TAIL_CHARS = 4000;
let stderrTail = '';
const appendTail = (current: string, chunk: Buffer | string): string => {