feat(cli): add --resume and --continue flags to launch
Some checks failed
CI / Lint (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Broker tests (Postgres) (push) Has been cancelled
CI / Docker build (linux/amd64) (push) Has been cancelled

claudemesh launch now supports:
  --resume <id> / -r  — resume a previous Claude Code session
  --continue / -c     — continue the most recent conversation

When resuming, skips generating a new session ID so the mesh peer
identity persists. The detectClaudeSessionId() fallback in ws/client.ts
picks up the existing session UUID from the .jsonl file.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alejandro Gutiérrez
2026-04-08 11:57:24 +01:00
parent 52393429f9
commit 02a165dd76
3 changed files with 24 additions and 8 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "claudemesh-cli", "name": "claudemesh-cli",
"version": "0.8.2", "version": "0.8.3",
"description": "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.", "description": "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
"keywords": [ "keywords": [
"claude-code", "claude-code",

View File

@@ -32,6 +32,8 @@ export interface LaunchFlags {
mesh?: string; mesh?: string;
"message-mode"?: string; "message-mode"?: string;
"system-prompt"?: string; "system-prompt"?: string;
resume?: string;
continue?: boolean;
yes?: boolean; yes?: boolean;
quiet?: boolean; quiet?: boolean;
} }
@@ -171,6 +173,8 @@ export async function runLaunch(flags: LaunchFlags, rawArgs: string[]): Promise<
? flags["message-mode"] as "push" | "inbox" | "off" ? flags["message-mode"] as "push" | "inbox" | "off"
: null), : null),
systemPrompt: flags["system-prompt"] ?? null, systemPrompt: flags["system-prompt"] ?? null,
resume: flags.resume ?? null,
continueSession: flags.continue ?? false,
quiet: flags.quiet ?? false, quiet: flags.quiet ?? false,
skipPermConfirm: flags.yes ?? false, skipPermConfirm: flags.yes ?? false,
claudeArgs: claudePassthrough, claudeArgs: claudePassthrough,
@@ -422,16 +426,17 @@ export async function runLaunch(flags: LaunchFlags, rawArgs: string[]): Promise<
// passes -y / --yes. Without it, claudemesh tools still work because // passes -y / --yes. Without it, claudemesh tools still work because
// `claudemesh install` pre-approves them via allowedTools in settings.json. // `claudemesh install` pre-approves them via allowedTools in settings.json.
// This keeps permissions tight for multi-person meshes. // This keeps permissions tight for multi-person meshes.
// Generate a stable session ID for this launch. Used by the broker to: // Session identity: --resume reuses existing session, otherwise generate new.
// - detect reconnections (same session ID = restore state) // When resuming, Claude Code reuses the session ID so the mesh peer identity persists.
// - disambiguate multiple peers in the same project const isResume = args.resume !== null || args.continueSession;
// - persist identity across --resume (Claude reuses the session ID) const claudeSessionId = isResume ? undefined : randomUUID();
const claudeSessionId = randomUUID();
const claudeArgs = [ const claudeArgs = [
"--dangerously-load-development-channels", "--dangerously-load-development-channels",
"server:claudemesh", "server:claudemesh",
"--session-id", claudeSessionId, ...(claudeSessionId ? ["--session-id", claudeSessionId] : []),
...(args.resume ? ["--resume", args.resume] : []),
...(args.continueSession ? ["--continue"] : []),
...(args.skipPermConfirm ? ["--dangerously-skip-permissions"] : []), ...(args.skipPermConfirm ? ["--dangerously-skip-permissions"] : []),
...(args.systemPrompt ? ["--system-prompt", args.systemPrompt] : []), ...(args.systemPrompt ? ["--system-prompt", args.systemPrompt] : []),
...filtered, ...filtered,
@@ -445,7 +450,7 @@ export async function runLaunch(flags: LaunchFlags, rawArgs: string[]): Promise<
...process.env, ...process.env,
CLAUDEMESH_CONFIG_DIR: tmpDir, CLAUDEMESH_CONFIG_DIR: tmpDir,
CLAUDEMESH_DISPLAY_NAME: displayName, CLAUDEMESH_DISPLAY_NAME: displayName,
CLAUDEMESH_SESSION_ID: claudeSessionId, ...(claudeSessionId ? { CLAUDEMESH_SESSION_ID: claudeSessionId } : {}),
MCP_TIMEOUT: process.env.MCP_TIMEOUT ?? "30000", MCP_TIMEOUT: process.env.MCP_TIMEOUT ?? "30000",
MAX_MCP_OUTPUT_TOKENS: process.env.MAX_MCP_OUTPUT_TOKENS ?? "50000", MAX_MCP_OUTPUT_TOKENS: process.env.MAX_MCP_OUTPUT_TOKENS ?? "50000",
...(role ? { CLAUDEMESH_ROLE: role } : {}), ...(role ? { CLAUDEMESH_ROLE: role } : {}),

View File

@@ -71,6 +71,17 @@ const launch = defineCommand({
description: "Skip the --dangerously-skip-permissions confirmation", description: "Skip the --dangerously-skip-permissions confirmation",
default: false, default: false,
}, },
resume: {
type: "string",
alias: "r",
description: "Resume a previous Claude Code session by ID, or pass `true` for interactive picker",
},
continue: {
type: "boolean",
alias: "c",
description: "Continue the most recent conversation in this directory",
default: false,
},
quiet: { quiet: {
type: "boolean", type: "boolean",
description: "Suppress banner and interactive prompts", description: "Suppress banner and interactive prompts",