@groeponline/pi-missions 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/types.ts","../src/core/extension.ts","../src/core/state.ts","../src/utils/markdown.ts","../src/utils/fs.ts","../src/utils/context.ts","../src/utils/mission-builder.ts","../src/commands/handlers.ts","../src/ui/components.ts","../src/engines/metrics.ts","../src/ui/dashboard.ts","../src/engines/completion.ts","../src/engines/autopilot.ts","../src/engines/worker.ts","../src/tools/index.ts","../src/engines/recovery.ts","../src/commands/index.ts"],"sourcesContent":["import { Type, type Static, type TSchema } from \"@sinclair/typebox\";\nimport { Value } from \"@sinclair/typebox/value\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Constants\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport const SCHEMA_VERSION = 3;\n\nexport const DEFAULT_FEATURE_MAX_WALL_CLOCK_MS = 30 * 60 * 1000; // 30 min\nexport const DEFAULT_FEATURE_MAX_TOOL_CALLS = 150;\nexport const STALE_FEATURE_WARN_MS = 20 * 60 * 1000; // 20 min\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Literal union types\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport type MissionStatus =\n | \"planning\" | \"active\" | \"paused\" | \"blocked\"\n | \"complete\" | \"budget_limited\" | \"failed\";\n\nexport type FeatureStatus =\n | \"pending\" | \"waiting\" | \"active\" | \"done\" | \"blocked\" | \"failed\";\n\nexport type MilestoneStatus = \"pending\" | \"active\" | \"complete\";\n\nexport type CheckType = \"manual\" | \"bash\" | \"test_file\";\n\nexport type AutopilotMode = \"manual\" | \"assisted\" | \"autopilot\";\n\nexport type StopReason =\n | \"mission_complete\" | \"paused_by_user\" | \"blocked\" | \"disabled\"\n | \"max_iterations\" | \"max_consecutive_failures\" | \"context_limit\"\n | \"no_active_feature\" | \"needs_user_decision\" | \"no_progress\"\n | \"validation_failed\" | \"error\";\n\nexport type ToolPhase = \"planning\" | \"execution\" | \"verification\";\n\nexport type ErrorCategory =\n | \"transient\" | \"permanent\" | \"user\" | \"system\"\n | \"network\" | \"permission\" | \"unknown\";\n\nexport type ErrorSeverity = \"low\" | \"medium\" | \"high\" | \"critical\";\n\nexport type RecoveryAction =\n | \"retry\" | \"fallback\" | \"skip\" | \"block\" | \"ask_user\" | \"degrade\";\n\nexport type CompletionConfidence = \"low\" | \"medium\" | \"high\";\n\nexport type AgentSource = \"pi\" | \"devin\" | \"opencode\" | \"codex\" | \"unknown\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Core models\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface AcceptanceCriterion {\n id: string;\n description: string;\n checkType: CheckType;\n checkCommand?: string;\n evidence?: string;\n verified: boolean;\n waived?: boolean;\n}\n\nexport interface Feature {\n id: string;\n milestoneId: string;\n title: string;\n description: string;\n priority: number;\n dependsOn: string[];\n acceptance: AcceptanceCriterion[];\n status: FeatureStatus;\n sessions: string[];\n completedAt?: number;\n startedAt?: number;\n maxWallClockMs?: number;\n maxToolCalls?: number;\n /** Token usage attributed to this feature, when known. */\n tokensUsed?: number;\n toolCallCount: number;\n notes?: string;\n _execFn?: (command: string) => { code: number; stdout: string; stderr?: string };\n}\n\nexport interface Milestone {\n id: string;\n title: string;\n description: string;\n status: MilestoneStatus;\n features: Feature[];\n dependsOn?: string[];\n}\n\nexport interface MissionAutopilot {\n enabled: boolean;\n mode: AutopilotMode;\n iteration: number;\n maxIterations: number;\n consecutiveFailures: number;\n maxConsecutiveFailures: number;\n noProgressTurns: number;\n maxNoProgressTurns: number;\n maxContextPercent: number;\n startedAt: string;\n lastContinuationAt?: string;\n lastStopReason?: StopReason;\n lastStopMessage?: string;\n continueAcrossFeatures: boolean;\n requireEvidenceForDone: boolean;\n}\n\nexport const DEFAULT_AUTOPILOT: MissionAutopilot = {\n enabled: false,\n mode: \"manual\",\n iteration: 0,\n maxIterations: 25,\n consecutiveFailures: 0,\n maxConsecutiveFailures: 3,\n noProgressTurns: 0,\n maxNoProgressTurns: 3,\n maxContextPercent: 85,\n startedAt: \"\",\n continueAcrossFeatures: true,\n requireEvidenceForDone: true,\n};\n\nexport interface MissionState {\n schemaVersion: number;\n id: string;\n title: string;\n goal: string;\n status: MissionStatus;\n milestones: Milestone[];\n activeMilestoneId?: string;\n activeFeatureId?: string;\n tokensBudget?: number;\n tokensUsed: number;\n lastContextTokens: number;\n validationToken: string;\n autopilot: MissionAutopilot;\n userPreferences?: { allowBashInPlanning?: boolean };\n createdAt: number;\n updatedAt: number;\n}\n\nexport interface RuntimeState {\n activeMission: MissionState | null;\n autoSaveInterval: ReturnType<typeof setInterval> | null;\n phaseToolCallCount: number;\n currentPhase: ToolPhase;\n lastFeatureId?: string;\n pendingCompletionAction?: \"auto_done\" | \"suggest_done\" | \"continue\" | \"ask_user\";\n pendingCompletionReason?: string;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// History, metrics, evidence\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface MissionHistoryEntry {\n ts: number;\n missionId: string;\n event: string;\n milestoneId?: string;\n featureId?: string;\n note?: string;\n duration_ms?: number;\n tokensUsed?: number;\n details?: Record<string, unknown>;\n}\n\nexport interface MissionMetrics {\n missionId: string;\n created: number;\n completed?: number;\n totalFeatures: number;\n featuresDone: number;\n featuresFailed: number;\n totalTokensUsed: number;\n totalWallClockMs: number;\n acceptanceFailures: number;\n evidenceHashErrors: number;\n}\n\nexport interface MissionMetricsSummary {\n totalMissions: number;\n completedMissions: number;\n successRate: number;\n averageTokensPerMission: number;\n averageFeaturesPerMission: number;\n averageCompletionTimeMs: number;\n}\n\nexport interface SessionMetrics {\n sessionId: string;\n startTime: number;\n endTime?: number;\n toolCalls: { total: number; byTool: Record<string, number>; successful: number; failed: number };\n tokensUsed: number;\n featuresCompleted: number;\n errors: { total: number; byCategory: Record<string, number> };\n autoAdvanceCount: number;\n stuckDetectionCount: number;\n}\n\nexport interface StaleFeatureAlert {\n featureId: string;\n title: string;\n activeMs: number;\n maxMs: number;\n warnMs: number;\n toolCallsUsed: number;\n maxToolCalls: number;\n level: \"warn\" | \"critical\";\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Tool policy\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface ToolPolicy {\n phase: ToolPhase;\n allowedTools: string[];\n maxToolCalls: number;\n}\n\nexport const TOOL_POLICIES: Record<ToolPhase, ToolPolicy> = {\n planning: {\n phase: \"planning\",\n allowedTools: [\n \"read\", \"grep\", \"find\", \"ls\",\n \"mission_next_feature\", \"mission_feature_done\", \"mission_ask_user\",\n \"mission_block_self\", \"mission_fork\",\n \"mission_error_status\", \"mission_retry_error\",\n \"mission_spawn_worker\", \"mission_worker_status\", \"mission_kill_worker\",\n ],\n maxToolCalls: 30,\n },\n execution: {\n phase: \"execution\",\n allowedTools: [\n \"read\", \"write\", \"edit\", \"bash\", \"grep\", \"find\", \"ls\",\n \"mission_next_feature\", \"mission_feature_done\", \"mission_ask_user\",\n \"mission_block_self\", \"mission_fork\",\n \"mission_error_status\", \"mission_retry_error\",\n \"mission_spawn_worker\", \"mission_worker_status\", \"mission_kill_worker\",\n ],\n maxToolCalls: 120,\n },\n verification: {\n phase: \"verification\",\n allowedTools: [\n \"read\", \"bash\", \"grep\", \"find\", \"ls\",\n \"mission_next_feature\", \"mission_feature_done\", \"mission_ask_user\",\n \"mission_block_self\", \"mission_fork\",\n \"mission_error_status\", \"mission_retry_error\",\n \"mission_spawn_worker\", \"mission_worker_status\", \"mission_kill_worker\",\n ],\n maxToolCalls: 60,\n },\n};\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Error recovery types\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface ErrorContext {\n toolName?: string;\n featureId?: string;\n missionId?: string;\n timestamp: number;\n errorType: string;\n errorMessage: string;\n stackTrace?: string;\n}\n\nexport interface ErrorRecoveryStrategy {\n category: ErrorCategory;\n maxRetries: number;\n backoffMs: number;\n fallbackAction?: RecoveryAction;\n degradeAction?: () => void;\n}\n\nexport interface ErrorRecord {\n id: string;\n context: ErrorContext;\n category: ErrorCategory;\n severity: ErrorSeverity;\n retryCount: number;\n actionTaken: RecoveryAction;\n resolved: boolean;\n timestamp: number;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Completion detection types\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface CompletionSignal {\n type: \"keyword\" | \"acceptance\" | \"tool_pattern\" | \"error_free_streak\" | \"user_confirmation\";\n confidence: CompletionConfidence;\n evidence: string;\n timestamp: number;\n}\n\nexport interface CompletionDetectionResult {\n isComplete: boolean;\n confidence: CompletionConfidence;\n signals: CompletionSignal[];\n suggestedAction: \"auto_done\" | \"suggest_done\" | \"continue\" | \"ask_user\";\n reason: string;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Tool event types\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface ToolCallEvent {\n toolName: string;\n toolCallId?: string;\n input?: Record<string, unknown>;\n}\n\nexport interface ToolResultEvent {\n toolName: string;\n toolCallId?: string;\n input?: Record<string, unknown>;\n content?: Array<{ type?: string; text?: string }>;\n details?: unknown;\n isError: boolean;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Transition result types\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface CompleteFeatureOptions {\n evidence: string;\n notes?: string;\n autoVerify?: boolean;\n markAcceptanceVerified?: boolean;\n historyNote?: string;\n historyDetails?: Record<string, unknown>;\n}\n\nexport type CompleteFeatureResult =\n | { ok: true; feature: Feature; evidenceFile: string; missionComplete: boolean }\n | { ok: false; reason: string; unverifiedBashCount?: number };\n\nexport type ActivateNextResult =\n | { ok: true; next: Feature }\n | { ok: false; reason: \"active_not_done\"; active: Feature }\n | { ok: false; reason: \"mission_complete\" }\n | { ok: false; reason: \"no_unblocked_pending\" };\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Fork helper types\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface ForkSessionManager {\n getLeafId?: () => string | null;\n getSessionFile?: () => string | undefined;\n}\n\nexport interface ForkReplacementContext {\n sessionManager?: ForkSessionManager;\n sendUserMessage?: (message: string) => Promise<unknown>;\n ui: { notify: (message: string, severity: string) => void };\n}\n\nexport interface ContinuationDecision {\n continue: boolean;\n reason?: string;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Active mission session entry\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface ActiveMissionSessionEntry {\n missionId: string;\n validationToken?: string;\n}\n\nexport type ActiveMissionSessionEntryResult =\n | { kind: \"none\" }\n | { kind: \"valid\"; entry: ActiveMissionSessionEntry }\n | { kind: \"invalid\"; reason: string; data: unknown };\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Mission context session manager\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface MissionContextSessionManager {\n appendCustomMessageEntry?: (\n customType: string,\n content: string,\n display: boolean,\n details?: Record<string, unknown>,\n ) => string;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Degraded result for graceful fallbacks\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface DegradedResult<T> {\n ok: boolean;\n value: T | undefined;\n degraded: boolean;\n error?: unknown;\n}\n\nexport interface RetryOptions {\n maxRetries?: number;\n baseDelayMs?: number;\n maxDelayMs?: number;\n jitterFactor?: number;\n shouldRetry?: (error: unknown) => boolean;\n operationName?: string;\n}\n\nexport type LockOptions = {\n retries?: number;\n minTimeout?: number;\n maxTimeout?: number;\n stale?: number;\n};\n\n// ═══════════════════════════════════════════════════════════════════════════\n// TypeBox Schemas — for validation and wizard output\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport const CriterionSchema = Type.Object({\n id: Type.String({ minLength: 1, maxLength: 50 }),\n description: Type.String({ minLength: 1, maxLength: 500 }),\n checkType: Type.Union([Type.Literal(\"manual\"), Type.Literal(\"bash\"), Type.Literal(\"test_file\")]),\n checkCommand: Type.Optional(Type.String({ maxLength: 1000 })),\n evidence: Type.Optional(Type.String()),\n verified: Type.Boolean(),\n waived: Type.Optional(Type.Boolean()),\n});\n\nexport const FeatureSchema = Type.Object({\n id: Type.String({ pattern: \"^F[0-9]{3}$\" }),\n milestoneId: Type.String({ pattern: \"^M[0-9]{2}$\" }),\n title: Type.String({ minLength: 1, maxLength: 200 }),\n description: Type.String({ minLength: 1, maxLength: 2000 }),\n priority: Type.Integer({ minimum: 1, maximum: 5 }),\n dependsOn: Type.Array(Type.String({ pattern: \"^F[0-9]{3}$\" })),\n acceptance: Type.Array(CriterionSchema, { minItems: 1 }),\n status: Type.Union([\n Type.Literal(\"pending\"), Type.Literal(\"waiting\"), Type.Literal(\"active\"),\n Type.Literal(\"done\"), Type.Literal(\"blocked\"), Type.Literal(\"failed\"),\n ]),\n sessions: Type.Array(Type.String()),\n toolCallCount: Type.Integer({ minimum: 0 }),\n tokensUsed: Type.Optional(Type.Integer({ minimum: 0 })),\n startedAt: Type.Optional(Type.Integer()),\n completedAt: Type.Optional(Type.Integer()),\n maxWallClockMs: Type.Optional(Type.Integer({ minimum: 0 })),\n maxToolCalls: Type.Optional(Type.Integer({ minimum: 0 })),\n notes: Type.Optional(Type.String({ maxLength: 1000 })),\n}, { additionalProperties: false });\n\nexport const MilestoneSchema = Type.Object({\n id: Type.String({ pattern: \"^M[0-9]{2}$\" }),\n title: Type.String({ minLength: 1, maxLength: 200 }),\n description: Type.String({ maxLength: 1000 }),\n status: Type.Union([Type.Literal(\"pending\"), Type.Literal(\"active\"), Type.Literal(\"complete\")]),\n features: Type.Array(FeatureSchema, { minItems: 1 }),\n dependsOn: Type.Optional(Type.Array(Type.String({ pattern: \"^M[0-9]{2}$\" }))),\n});\n\nexport const WizardCriterionSchema = Type.Object({\n id: Type.Optional(Type.String({ minLength: 1, maxLength: 50 })),\n description: Type.String({ minLength: 1, maxLength: 500 }),\n checkType: Type.Union([Type.Literal(\"manual\"), Type.Literal(\"bash\"), Type.Literal(\"test_file\")]),\n checkCommand: Type.Optional(Type.String({ maxLength: 1000 })),\n}, { additionalProperties: false });\n\nexport const WizardFeatureSchema = Type.Object({\n id: Type.Optional(Type.String({ pattern: \"^F[0-9]{3}$\" })),\n title: Type.String({ minLength: 1, maxLength: 200 }),\n description: Type.String({ minLength: 1, maxLength: 2000 }),\n priority: Type.Integer({ minimum: 1, maximum: 5 }),\n dependsOn: Type.Array(Type.String({ pattern: \"^F[0-9]{3}$\" })),\n acceptance: Type.Array(WizardCriterionSchema, { minItems: 1 }),\n}, { additionalProperties: false });\n\nexport const WizardMilestoneSchema = Type.Object({\n id: Type.Optional(Type.String({ pattern: \"^M[0-9]{2}$\" })),\n title: Type.String({ minLength: 1, maxLength: 200 }),\n description: Type.String({ maxLength: 1000 }),\n features: Type.Array(WizardFeatureSchema, { minItems: 1 }),\n}, { additionalProperties: false });\n\nexport const WizardOutputSchema = Type.Object({\n title: Type.String({ minLength: 1, maxLength: 200 }),\n milestones: Type.Array(WizardMilestoneSchema, { minItems: 2, maxItems: 20 }),\n}, { additionalProperties: false });\n\n// Schema-derived static types\nexport type AcceptanceCriterionValidated = Static<typeof CriterionSchema>;\nexport type FeatureValidated = Static<typeof FeatureSchema>;\nexport type MilestoneValidated = Static<typeof MilestoneSchema>;\nexport type WizardOutput = Static<typeof WizardOutputSchema>;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Validation utilities\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface ValidationError {\n path: string;\n message: string;\n value: unknown;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n}\n\nexport function validate<T extends TSchema>(schema: T, value: unknown): ValidationResult {\n try {\n if (Value.Check(schema, value)) return { valid: true, errors: [] };\n const errors: ValidationError[] = [];\n for (const error of Value.Errors(schema, value)) {\n errors.push({ path: error.path, message: error.message, value: error.value });\n }\n return { valid: false, errors };\n } catch (e) {\n return {\n valid: false,\n errors: [{ path: \"root\", message: e instanceof Error ? e.message : String(e), value }],\n };\n }\n}\n\nexport function formatValidationErrors(errors: ValidationError[]): string {\n if (errors.length === 0) return \"\";\n const lines = [\"Validation errors:\"];\n for (const e of errors.slice(0, 10)) {\n lines.push(` - ${e.path}: ${e.message}`);\n if (e.value !== undefined) lines.push(` (value: ${JSON.stringify(e.value).slice(0, 50)})`);\n }\n if (errors.length > 10) lines.push(` ... and ${errors.length - 10} more errors`);\n return lines.join(\"\\n\");\n}\n","import { fileURLToPath } from 'node:url';\nimport { dirname, resolve } from 'node:path';\nimport * as fs from 'node:fs';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { ExtensionCommandContext } from '@earendil-works/pi-coding-agent';\nimport type { RuntimeState, ToolCallEvent, ToolResultEvent } from '../core/types.js';\nimport { getMissionPhase } from '../core/state.js';\nimport {\n appendHistory, autoBlockBlockedFeatures,\n getActiveFeature, loadMissionFromDisk, saveEvidence, saveMissionSafe,\n} from '../core/state.js';\nimport { registerMissionCommand, compactionCheckpoint, missionSummaryForTree, saveSessionLink } from '../commands/index.js';\nimport { registerMissionTools, enforceToolPolicy, enforceToolMax, toolResultErrorMessage } from '../tools/index.js';\nimport { updateFooter } from '../ui/components.js';\nimport { buildLeanContext } from '../utils/context.js';\nimport { getCompletionDetector } from '../engines/completion.js';\nimport { getErrorRecoveryEngine } from '../engines/recovery.js';\nimport { sessionMetrics } from '../engines/metrics.js';\nimport { processAgentEndForAutopilot } from '../engines/autopilot.js';\nimport { activateNextFeature, completeActiveFeature } from '../core/state.js';\nimport { handleDashboard } from '../commands/index.js';\nimport { isValidMissionId } from '../utils/fs.js';\n\n// Re-export types for external consumers\nexport type { ToolCallEvent, ToolResultEvent };\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Session entry types — avoids unsafe Record<string, unknown> casts\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface SessionEntryData {\n missionId?: unknown;\n validationToken?: unknown;\n [key: string]: unknown;\n}\n\nexport interface SessionEntry {\n type?: unknown;\n customType?: unknown;\n data?: SessionEntryData | null;\n role?: unknown;\n content?: unknown;\n}\n\nexport interface ActiveMissionEntry {\n missionId: string;\n validationToken?: string;\n}\n\n/**\n * Scans session entries in reverse to find the most recent pi-mission-active entry.\n * Handles both the native Pi API format (type: 'pi-mission-active') and the\n * test mock format (type: 'custom', customType: 'pi-mission-active').\n */\nexport function latestActiveEntry(entries: SessionEntry[]): ActiveMissionEntry | null {\n for (const e of [...entries].reverse()) {\n if (e.type === 'pi-mission-active' && e.data && typeof e.data === 'object') {\n if (typeof e.data.missionId === 'string') {\n return {\n missionId: e.data.missionId,\n validationToken: typeof e.data.validationToken === 'string' ? e.data.validationToken : undefined,\n };\n }\n }\n if (e.type === 'custom' && e.customType === 'pi-mission-active' && e.data && typeof e.data === 'object') {\n if (typeof e.data.missionId === 'string') {\n return {\n missionId: e.data.missionId,\n validationToken: typeof e.data.validationToken === 'string' ? e.data.validationToken : undefined,\n };\n }\n }\n }\n return null;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Typed hook emitter — lets us register untyped Pi events safely\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport type PiEventHandler = (...args: unknown[]) => unknown;\n\n/**\n * Registers a Pi extension event handler.\n *\n * ExtensionAPI.on() only types a fixed set of events; 'tool_result',\n * 'session_start', 'session_before_tree', 'session_before_compact', etc. are\n * valid at runtime but not present in the public types. Casting through unknown\n * preserves type safety for the handler while accepting any event name.\n */\nexport function hook(pi: ExtensionAPI, event: string, handler: PiEventHandler): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (pi as unknown as { on(event: string, handler: PiEventHandler): void }).on(event, handler);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Extension entrypoint\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport default function piMissions(pi: ExtensionAPI): void {\n // Expose extension path for worker child processes.\n // Prefer project-local .pi/extensions/pi-missions/ over global install.\n try {\n const extDir = dirname(fileURLToPath(import.meta.url));\n const globalPath = resolve(extDir, '..', 'index.ts');\n const cwd = typeof process.cwd === 'function' ? process.cwd() : '';\n const localPath = cwd ? resolve(cwd, '.pi', 'extensions', 'pi-missions', 'index.ts') : '';\n\n let extensionPath = globalPath;\n if (localPath && fs.existsSync(localPath)) {\n extensionPath = localPath;\n // Also append local templates/config dir to a discoverable env var\n const localDir = resolve(cwd, '.pi', 'extensions', 'pi-missions');\n process.env.PI_MISSIONS_PROJECT_DIR = localDir;\n }\n process.env.PI_MISSIONS_EXTENSION_PATH = extensionPath;\n } catch { /* non-ESM fallback, env var should be set manually */ }\n\n const runtime: RuntimeState = {\n activeMission: null, autoSaveInterval: null,\n phaseToolCallCount: 0, currentPhase: 'execution',\n lastFeatureId: undefined,\n };\n\n function scheduleAutoSave(rt: RuntimeState): void {\n if (!rt.autoSaveInterval) {\n rt.autoSaveInterval = setInterval(async () => {\n if (rt.activeMission?.status === 'active') await saveMissionSafe(rt.activeMission);\n }, 2 * 60 * 1000);\n }\n }\n\n registerMissionCommand(pi, runtime);\n registerMissionTools(pi, runtime);\n\n // ── session_start: auto-restore mission ────────────────────────────────\n\n hook(pi, 'session_start', async (...args: unknown[]) => {\n const _event = args[0];\n const ctx = args[1] as ExtensionCommandContext;\n sessionMetrics.reset();\n const entries = (ctx.sessionManager as unknown as { getEntries: () => SessionEntry[] }).getEntries();\n const active = latestActiveEntry(entries);\n if (!active) {\n const malformed = entries.some(e =>\n (e?.type === 'pi-mission-active' || (e?.type === 'custom' && e?.customType === 'pi-mission-active')) &&\n e?.data && typeof e.data === 'object' &&\n typeof (e.data as SessionEntryData).missionId !== 'string'\n );\n if (malformed) ctx.ui?.notify('⚠️ Ignoring invalid mission session entry.', 'warning');\n return;\n }\n\n const { missionId, validationToken } = active;\n if (!isValidMissionId(missionId)) {\n const fallback = loadMissionFromDisk(missionId);\n if (!fallback) { ctx.ui?.notify(`⚠️ Mission '${missionId}' not found on disk. /mission load.`, 'warning'); return; }\n runtime.activeMission = fallback;\n autoBlockBlockedFeatures(fallback);\n updateFooter(ctx, fallback);\n pi.setSessionName(`🎯 ${fallback.title}`);\n scheduleAutoSave(runtime);\n return;\n }\n\n const mission = loadMissionFromDisk(missionId);\n if (!mission) { ctx.ui?.notify(`⚠️ Mission '${missionId}' not found on disk. /mission load.`, 'warning'); return; }\n if (validationToken && validationToken !== mission.validationToken) { ctx.ui?.notify('⚠️ Invalid mission event token.', 'warning'); return; }\n\n runtime.activeMission = mission;\n autoBlockBlockedFeatures(mission);\n updateFooter(ctx, mission);\n pi.setSessionName(`🎯 ${mission.title}`);\n scheduleAutoSave(runtime);\n });\n\n // ── resources_discover ─────────────────────────────────────────────────\n\n hook(pi, 'resources_discover', async () => ({ skillPaths: [], promptPaths: [], themePaths: [] }));\n\n // ── session_before_tree ────────────────────────────────────────────────\n\n hook(pi, 'session_before_tree', async () => {\n const summary = missionSummaryForTree(runtime);\n if (!summary) return;\n return { summary: { summary, details: { missionId: runtime.activeMission?.id } } };\n });\n\n // ── before_agent_start: phase reset ────────────────────────────────────\n\n hook(pi, 'before_agent_start', async (..._args: unknown[]) => {\n runtime.pendingCompletionAction = undefined;\n runtime.pendingCompletionReason = undefined;\n runtime.phaseToolCallCount = 0;\n\n const mission = runtime.activeMission;\n if (!mission || mission.status !== 'active') return;\n runtime.currentPhase = getMissionPhase(mission);\n\n const feature = getActiveFeature(mission);\n if (feature?.status === 'active') {\n runtime.lastFeatureId = feature.id;\n getCompletionDetector().clearToolCallHistory();\n getErrorRecoveryEngine().clearErrorsForFeature(feature.id);\n\n getErrorRecoveryEngine().onAlert((alert) => {\n if (!runtime.activeMission) return;\n appendHistory(runtime.activeMission, {\n event: 'error_alert', featureId: feature.id,\n note: alert.message.slice(0, 200),\n details: { alertType: alert.type, errorCategory: alert.record.category, errorSeverity: alert.record.severity, errorCount: alert.stats?.total },\n });\n });\n }\n });\n\n // ── before_agent_start: inject lean context + update footer ─────────────\n\n hook(pi, 'before_agent_start', async (...args: unknown[]) => {\n const _event = args[0];\n const ctx = args[1] as ExtensionCommandContext;\n const mission = runtime.activeMission;\n if (!mission || mission.status !== 'active') return;\n\n updateFooter(ctx, mission);\n let lean = buildLeanContext(mission);\n\n if (runtime.pendingCompletionAction === 'ask_user') {\n const reason = (runtime.pendingCompletionReason ?? '').replace(/^(Medium|Low) confidence - /i, '') || 'completion is unclear';\n lean += `\\n\\n🚨 **STOP AND CALL THE TOOL**: ${reason}. Call **mission_ask_user** NOW. Do NOT describe — invoke the tool.`;\n } else if (runtime.pendingCompletionAction === 'suggest_done') {\n const reason = runtime.pendingCompletionReason || 'feature may be complete';\n lean += `\\n\\n💡 ${reason}. Consider **mission_feature_done** if you have concrete evidence.`;\n }\n\n return { message: { customType: 'pi-mission-context', content: lean, display: false } };\n });\n\n // ── tool_call: enforce policy ──────────────────────────────────────────\n\n hook(pi, 'tool_call', async (...args: unknown[]) => {\n const event = args[0] as ToolCallEvent;\n if (!runtime.activeMission) return;\n runtime.currentPhase = getMissionPhase(runtime.activeMission);\n\n const policyResult = enforceToolPolicy(\n event.toolName, runtime.currentPhase, event.input,\n runtime.activeMission.userPreferences?.allowBashInPlanning === true,\n runtime.phaseToolCallCount,\n );\n if (policyResult.blocked) return { block: true, reason: policyResult.reason };\n\n runtime.phaseToolCallCount++;\n const maxResult = enforceToolMax(runtime.currentPhase, runtime.phaseToolCallCount);\n if (maxResult.blocked) return { block: true, reason: maxResult.reason };\n });\n\n // ── tool_result: metrics + error recovery ──────────────────────────────\n\n hook(pi, 'tool_result', async (...args: unknown[]) => {\n const event = args[0] as ToolResultEvent;\n if (!runtime.activeMission) return;\n const mission = runtime.activeMission;\n const feature = getActiveFeature(mission);\n const detector = getCompletionDetector();\n\n if (feature?.id && feature.id !== runtime.lastFeatureId) {\n detector.clearToolCallHistory();\n getErrorRecoveryEngine().clearErrorsForFeature(feature.id);\n runtime.lastFeatureId = feature.id;\n }\n\n const success = !event.isError;\n detector.recordToolCall(event.toolName, success);\n sessionMetrics.recordToolCall(event.toolName, success);\n\n if (!event.isError) {\n getErrorRecoveryEngine().clearConsecutiveFailures(event.toolName, feature?.id);\n return;\n }\n\n const recovery = getErrorRecoveryEngine();\n const errorMessage = toolResultErrorMessage(event);\n const { action, shouldRetry, retryAfter, record } = recovery.handleError({\n toolName: event.toolName, featureId: feature?.id, missionId: mission.id,\n timestamp: Date.now(), errorType: 'ToolResultError', errorMessage,\n });\n\n sessionMetrics.recordError(record.category);\n appendHistory(mission, {\n event: 'error_detected', featureId: feature?.id,\n note: `${event.toolName} failed: ${errorMessage}`,\n details: { category: record.category, severity: record.severity, action, shouldRetry, retryAfter, retryCount: record.retryCount },\n });\n });\n\n // ── Keyboard shortcuts ─────────────────────────────────────────────────\n\n pi.registerShortcut('ctrl+shift+m', {\n description: 'Open Mission Control dashboard',\n handler: ((rawCtx: unknown) => handleDashboard(rawCtx as ExtensionCommandContext, runtime)) as unknown as (ctx: ExtensionContext) => void | Promise<void>,\n });\n\n pi.registerShortcut('ctrl+shift+d', {\n description: 'Mark current feature as done',\n handler: (async (rawCtx: unknown) => {\n const ctx = rawCtx as ExtensionCommandContext;\n const m = runtime.activeMission;\n const f = m ? getActiveFeature(m) : null;\n if (!m || !f) return ctx.ui?.notify('No active feature.', 'warning');\n\n let ok = true;\n if (ctx.hasUI) ok = await ctx.ui.confirm('Feature done?', `Mark '${f.title}' as completed?`);\n if (!ok) return;\n\n f.status = 'done'; f.completedAt = Date.now();\n for (const ac of f.acceptance) if (!ac.waived) ac.verified = true;\n const evidenceFile = saveEvidence(m, f, 'Done via keyboard shortcut.');\n appendHistory(m, { event: 'feature_done', featureId: f.id, note: 'Keyboard shortcut', details: { evidenceFile } });\n autoBlockBlockedFeatures(m);\n await saveMissionSafe(m); updateFooter(ctx, m);\n ctx.ui.notify(`✅ ${f.title} done!`, 'info');\n }) as unknown as (ctx: ExtensionContext) => void | Promise<void>,\n });\n\n // ── turn_end: stuck detection + token tracking ─────────────────────────\n\n hook(pi, 'turn_end', async (...args: unknown[]) => {\n const _event = args[0];\n const ctx = args[1] as ExtensionCommandContext;\n const m = runtime.activeMission;\n if (!m) return;\n\n const usage = (ctx as unknown as { getContextUsage?: () => { tokens?: number; percent?: number } }).getContextUsage?.();\n if (usage?.tokens !== undefined) {\n const delta = Math.max(0, usage.tokens - m.lastContextTokens);\n m.tokensUsed += delta;\n m.lastContextTokens = usage.tokens;\n if (m.tokensBudget && m.tokensUsed > m.tokensBudget * 0.8 && m.status === 'active') {\n m.status = 'budget_limited';\n ctx.ui.notify('⚠️ Token budget 80% used.', 'warning');\n }\n }\n\n const leafId = (ctx.sessionManager as unknown as { getLeafId?: () => string | null }).getLeafId?.();\n const active = getActiveFeature(m);\n if (leafId && active) pi.setLabel(leafId, `🎯 ${active.title}`);\n\n const detector = getCompletionDetector();\n try {\n const entries = (ctx.sessionManager as unknown as { getEntries: () => SessionEntry[] }).getEntries();\n const lastAsst = entries.filter(e => e?.role === 'assistant').slice(-1)[0];\n const content = lastAsst?.content;\n if (Array.isArray(content)) {\n const text = (content as Array<{ type?: string; text?: string }>).filter(c => c?.type === 'text').map(c => c.text ?? '').join('\\n');\n if (text) detector.recordTextOutput(text);\n } else if (typeof content === 'string') {\n detector.recordTextOutput(content);\n }\n } catch { /* best-effort */ }\n\n if (active?.status === 'active') {\n const stuck = detector.detectStuck();\n const textLoop = detector.detectTextLoop();\n const effective = textLoop.isStuck ? textLoop : stuck;\n\n if (effective.isStuck && effective.suggestedAction === 'block_self') {\n sessionMetrics.recordStuckDetection();\n appendHistory(m, { event: 'stuck_detected', featureId: active.id, note: effective.reason, details: { source: textLoop.isStuck ? 'text_loop' : 'tool_pattern' } });\n active.status = 'blocked';\n active.notes = `Auto-blocked: ${effective.reason}`;\n m.status = 'blocked';\n m.autopilot.enabled = false;\n m.autopilot.lastStopReason = 'blocked';\n m.autopilot.lastStopMessage = effective.reason;\n ctx.ui.notify(`🚫 Auto-blocked: ${effective.reason}`, 'warning');\n await saveMissionSafe(m);\n } else if (effective.isStuck) {\n ctx.ui.notify(`⚠️ Stuck detected: ${effective.reason}. Consider mission_block_self.`, 'warning');\n }\n }\n\n await saveMissionSafe(m);\n updateFooter(ctx, m);\n });\n\n // ── agent_end: completion detection + auto-advance ─────────────────────\n\n hook(pi, 'agent_end', async (...args: unknown[]) => {\n const event = args[0] as { messages?: Array<{ content?: Array<{ type?: string; text?: string }> | string }> };\n const ctx = args[1] as ExtensionCommandContext;\n const m = runtime.activeMission;\n if (m?.autopilot?.enabled) { await processAgentEndForAutopilot(pi, ctx, event, runtime); return; }\n\n const feature = m ? getActiveFeature(m) : null;\n if (!m || !feature || feature.status !== 'active') return;\n\n const text = (event.messages ?? [])\n .flatMap(msg => Array.isArray(msg.content) ? msg.content : [])\n .filter(c => c?.type === 'text' && typeof c.text === 'string')\n .map(c => c.text).join('\\n');\n\n const detector = getCompletionDetector();\n const detection = detector.detectCompletion(feature, text);\n\n appendHistory(m, {\n event: 'completion_detection', featureId: feature.id,\n note: detection.reason,\n details: { isComplete: detection.isComplete, confidence: detection.confidence, suggestedAction: detection.suggestedAction, signals: detection.signals },\n });\n\n if (detection.suggestedAction === 'auto_done') {\n const completed = completeActiveFeature(m, {\n evidence: `Auto-completed: ${detection.reason}\\n\\nSignals:\\n${detection.signals.map(s => `- ${s.type}: ${s.evidence}`).join('\\n')}`,\n markAcceptanceVerified: true,\n historyNote: 'Auto-completed',\n historyDetails: { auto: true },\n });\n\n if (!completed.ok) {\n ctx.ui.notify(`Feature looks complete but cannot auto-complete: ${completed.reason}`, 'info');\n await saveMissionSafe(m); updateFooter(ctx, m);\n return;\n }\n\n sessionMetrics.recordFeatureCompleted();\n const next = activateNextFeature(m, 'Auto-advanced');\n\n if (next.ok) {\n sessionMetrics.recordAutoAdvance();\n autoBlockBlockedFeatures(m);\n \n // Suggest handoff for large features (>50 tool calls or >10 min active)\n const wallMs = (completed.feature.startedAt && completed.feature.completedAt)\n ? completed.feature.completedAt - completed.feature.startedAt : 0;\n const isLarge = completed.feature.toolCallCount > 50 || wallMs > 600_000;\n const handoffHint = isLarge\n ? `\\n🤝 Large feature done (${completed.feature.toolCallCount} calls). Consider /handoff for a fresh session.`\n : '';\n \n ctx.ui.notify(`✅ Auto-completed ${completed.feature.id}. Advanced to ${next.next.id} — ${next.next.title}${handoffHint}`, 'info');\n } else if (next.reason === 'mission_complete') {\n ctx.ui.notify('🎉 Mission complete!', 'info');\n } else {\n autoBlockBlockedFeatures(m);\n ctx.ui.notify(`✅ Auto-completed ${completed.feature.id}. No pending features.`, 'info');\n }\n\n await saveMissionSafe(m); updateFooter(ctx, m);\n } else if (detection.suggestedAction === 'suggest_done') {\n runtime.pendingCompletionAction = 'suggest_done';\n runtime.pendingCompletionReason = detection.reason;\n ctx.ui.notify(`Feature '${feature.title}' may be complete (${detection.confidence}). ${detection.reason}`, 'info');\n } else if (detection.suggestedAction === 'ask_user') {\n runtime.pendingCompletionAction = 'ask_user';\n runtime.pendingCompletionReason = detection.reason;\n ctx.ui.notify(`Feature '${feature.title}' not clear if complete (${detection.confidence}). Model will be prompted to use mission_ask_user.`, 'info');\n }\n });\n\n // ── session_before_compact ─────────────────────────────────────────────\n\n hook(pi, 'session_before_compact', async () => compactionCheckpoint(pi, runtime));\n\n // ── session_shutdown ───────────────────────────────────────────────────\n\n hook(pi, 'session_shutdown', async (...args: unknown[]) => {\n const _event = args[0];\n const ctx = args[1] as ExtensionCommandContext;\n sessionMetrics.endSession();\n if (runtime.autoSaveInterval) clearInterval(runtime.autoSaveInterval);\n runtime.autoSaveInterval = null;\n if (runtime.activeMission) {\n saveSessionLink(runtime, (ctx.sessionManager as unknown as { getSessionFile?: () => string }).getSessionFile?.());\n await saveMissionSafe(runtime.activeMission);\n }\n updateFooter(ctx, null);\n });\n}","import * as fs from \"node:fs\";\nimport * as fsAsync from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport * as lockfile from \"proper-lockfile\";\nimport type {\n ActivateNextResult,\n CompleteFeatureOptions,\n CompleteFeatureResult,\n Feature,\n Milestone,\n MissionHistoryEntry,\n MissionMetrics,\n MissionState,\n StaleFeatureAlert,\n ToolPhase,\n} from \"./types.js\";\nimport { buildMissionGoalTree, type GoalTreeNode } from \"../utils/mission-builder.js\";\nimport {\n SCHEMA_VERSION,\n DEFAULT_AUTOPILOT,\n DEFAULT_FEATURE_MAX_TOOL_CALLS,\n DEFAULT_FEATURE_MAX_WALL_CLOCK_MS,\n STALE_FEATURE_WARN_MS,\n} from \"./types.js\";\nimport {\n createMissionId,\n createValidationToken,\n isValidMissionId,\n missionDirSafe,\n missionsRoot,\n sha256,\n slugify,\n} from \"../utils/fs.js\";\n\n// Re-export for consumers\nexport { missionsRoot, missionDirSafe, createMissionId, isValidMissionId, createValidationToken, slugify };\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Lock management\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function acquireMissionLock(missionId: string, stale = 30_000): Promise<() => Promise<void>> {\n const dir = missionDirSafe(missionId);\n fs.mkdirSync(dir, { recursive: true });\n return lockfile.lock(path.join(dir, \".lock\"), {\n retries: { retries: 10, minTimeout: 100, maxTimeout: 500 },\n stale,\n realpath: false,\n });\n}\n\nexport async function withLock<T>(\n lockPath: string,\n callback: () => Promise<T> | T,\n stale = 30_000,\n): Promise<T> {\n fs.mkdirSync(path.dirname(lockPath), { recursive: true });\n const release = await lockfile.lock(lockPath, {\n retries: { retries: 10, minTimeout: 100, maxTimeout: 500 },\n stale,\n realpath: false,\n });\n try {\n return await callback();\n } finally {\n await release();\n }\n}\n\nexport async function withMissionLock<T>(\n missionId: string,\n callback: () => Promise<T> | T,\n stale = 30_000,\n): Promise<T> {\n return withLock(path.join(missionDirSafe(missionId), \".lock\"), callback, stale);\n}\n\nexport async function cleanupStaleLocks(): Promise<void> {\n const root = missionsRoot();\n if (!fs.existsSync(root)) return;\n for (const entry of await fs.promises.readdir(root, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n try {\n await lockfile.unlock(path.join(root, entry.name, \".lock\"), { realpath: false });\n } catch { /* lock may not exist */ }\n }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Feature access helpers\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function getAllFeatures(mission: MissionState): Feature[] {\n const result: Feature[] = [];\n for (const m of mission.milestones) {\n for (const f of m.features) {\n result.push(f);\n }\n }\n return result;\n}\n\nexport function getMilestoneById(mission: MissionState, id: string): Milestone | undefined {\n return mission.milestones.find(m => m.id === id);\n}\n\nexport function getFeatureById(mission: MissionState, id: string): Feature | undefined {\n for (const m of mission.milestones) {\n for (const f of m.features) {\n if (f.id === id) return f;\n }\n }\n return undefined;\n}\n\nexport function getActiveFeature(mission: MissionState): Feature | null {\n if (!mission.activeFeatureId) return null;\n return getFeatureById(mission, mission.activeFeatureId) ?? null;\n}\n\nexport function dependenciesDone(mission: MissionState, feature: Feature): boolean {\n return feature.dependsOn.every(id => getFeatureById(mission, id)?.status === \"done\");\n}\n\nexport function getNextPendingFeature(mission: MissionState): Feature | null {\n return getAllFeatures(mission)\n .filter(f => (f.status === \"pending\" || f.status === \"waiting\") && dependenciesDone(mission, f))\n .sort((a, b) => a.priority - b.priority || a.id.localeCompare(b.id))[0] ?? null;\n}\n\nexport function progress(mission: MissionState): { done: number; total: number; pct: number } {\n let done = 0;\n let total = 0;\n for (const m of mission.milestones) {\n for (const f of m.features) {\n total++;\n if (f.status === \"done\") done++;\n }\n }\n return { done, total, pct: total ? Math.round((done / total) * 100) : 0 };\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Mission creation\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function createMission(title: string, goal: string, constraints = \"\"): MissionState {\n const id = createMissionId(title);\n const now = Date.now();\n return {\n schemaVersion: SCHEMA_VERSION,\n id,\n title,\n goal,\n status: \"active\",\n activeMilestoneId: \"M01\",\n activeFeatureId: \"F001\",\n tokensUsed: 0,\n lastContextTokens: 0,\n validationToken: createValidationToken(),\n autopilot: { ...DEFAULT_AUTOPILOT, startedAt: new Date(now).toISOString() },\n createdAt: now,\n updatedAt: now,\n milestones: [{\n id: \"M01\",\n title: \"Plan and execute\",\n description: constraints ? `Constraints: ${constraints}` : \"Initial mission execution milestone\",\n status: \"active\",\n features: [\n {\n id: \"F001\", milestoneId: \"M01\",\n title: \"Clarify scope and current state\",\n description: \"Read the repository, identify relevant files, constraints, and existing behavior.\",\n priority: 1, dependsOn: [], status: \"active\", sessions: [], toolCallCount: 0, startedAt: now,\n acceptance: [{ id: \"AC001\", description: \"Relevant files and constraints documented\", checkType: \"manual\", verified: false }],\n },\n {\n id: \"F002\", milestoneId: \"M01\",\n title: \"Implement the core change\",\n description: \"Make the smallest coherent implementation that satisfies the mission goal.\",\n priority: 2, dependsOn: [\"F001\"], status: \"pending\", sessions: [], toolCallCount: 0,\n acceptance: [{ id: \"AC001\", description: \"Implementation matches mission goal\", checkType: \"manual\", verified: false }],\n },\n {\n id: \"F003\", milestoneId: \"M01\",\n title: \"Verify and summarize\",\n description: \"Run relevant checks, capture evidence, and summarize results.\",\n priority: 3, dependsOn: [\"F002\"], status: \"pending\", sessions: [], toolCallCount: 0,\n acceptance: [{ id: \"AC001\", description: \"Verification evidence saved\", checkType: \"manual\", verified: false }],\n },\n ],\n }],\n };\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Migration\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function migrateMission(raw: unknown): MissionState {\n const value = raw as Partial<MissionState> & { features?: Feature[]; schemaVersion?: number };\n const version = value.schemaVersion ?? 1;\n if (version > SCHEMA_VERSION) throw new Error(`Unsupported mission schemaVersion ${version}`);\n if (version === SCHEMA_VERSION) {\n return { ...(value as MissionState), autopilot: { ...DEFAULT_AUTOPILOT, ...(value as MissionState).autopilot } };\n }\n // v1/v2 migration: flat features list → milestones\n const v1Features = (value.features ?? []).map((f) => ({\n ...f,\n toolCallCount: typeof f.toolCallCount === \"number\" ? f.toolCallCount : 0,\n } as unknown as Feature));\n return {\n schemaVersion: SCHEMA_VERSION,\n id: String(value.id ?? createMissionId(String(value.title ?? \"mission\"))),\n title: String(value.title ?? \"Untitled mission\"),\n goal: String(value.goal ?? \"\"),\n status: value.status ?? \"active\",\n activeFeatureId: value.activeFeatureId,\n activeMilestoneId: value.activeMilestoneId ?? \"M01\",\n tokensBudget: value.tokensBudget,\n tokensUsed: value.tokensUsed ?? 0,\n lastContextTokens: value.lastContextTokens ?? 0,\n validationToken: (value as MissionState).validationToken || createValidationToken(),\n autopilot: {\n ...DEFAULT_AUTOPILOT,\n ...(value as MissionState).autopilot,\n startedAt: (value as MissionState).autopilot?.startedAt ?? new Date(value.createdAt ?? Date.now()).toISOString(),\n },\n userPreferences: (value as MissionState).userPreferences,\n createdAt: value.createdAt ?? Date.now(),\n updatedAt: Date.now(),\n milestones: value.milestones ?? [{\n id: \"M01\", title: \"Migrated\", description: \"Migrated flat feature list\",\n status: \"active\", features: v1Features,\n }],\n };\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Disk I/O\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function saveMissionSafe(mission: MissionState): Promise<void> {\n const dir = missionDirSafe(mission.id);\n const target = path.join(dir, \"plan.json\");\n\n await withLock(target, async () => {\n await fsAsync.mkdir(dir, { recursive: true });\n await fsAsync.mkdir(path.join(dir, \"evidence\"), { recursive: true });\n await fsAsync.mkdir(path.join(dir, \"sessions\"), { recursive: true });\n\n const backup = path.join(dir, \"plan.json.bak\");\n const preMigration = path.join(dir, \"plan.json.pre-migration.bak\");\n const temp = path.join(dir, \"plan.json.tmp\");\n\n if (fs.existsSync(target)) {\n await fsAsync.copyFile(target, backup);\n if (!fs.existsSync(preMigration)) await fsAsync.copyFile(target, preMigration);\n }\n\n mission.updatedAt = Date.now();\n // Strip goalTree (circular .root refs) before serialization\n const { goalTree: _, ...serializable } = mission as MissionState & { goalTree?: unknown };\n const data = JSON.stringify(serializable, null, 2);\n\n // Retry the write once on failure\n try {\n await fsAsync.writeFile(temp, data, \"utf-8\");\n } catch {\n await new Promise(r => setTimeout(r, 100));\n await fsAsync.writeFile(temp, data, \"utf-8\");\n }\n await fsAsync.rename(temp, target);\n });\n}\n\nexport function loadMissionFromDisk(id: string): MissionState | null {\n const dir = missionDirSafe(id);\n for (const name of [\"plan.json\", \"plan.json.bak\"]) {\n try {\n const raw = JSON.parse(fs.readFileSync(path.join(dir, name), \"utf-8\"));\n return migrateMission(raw);\n } catch { /* try next fallback */ }\n }\n return null;\n}\n\n/** Read the raw schemaVersion from disk without migrating. Returns null if not found. */\nexport function readRawSchemaVersion(id: string): number | null {\n const dir = missionDirSafe(id);\n for (const name of [\"plan.json\", \"plan.json.bak\"]) {\n try {\n const raw = JSON.parse(fs.readFileSync(path.join(dir, name), \"utf-8\"));\n if (raw && typeof raw === \"object\" && !Array.isArray(raw) && \"schemaVersion\" in raw) {\n return (raw as Record<string, unknown>).schemaVersion as number;\n }\n return 1; // pre-schemaVersion missions\n } catch { /* try next fallback */ }\n }\n return null;\n}\n\n/** Migrate a mission, creating a pre-migration backup first. Returns the migrated mission or null. */\nexport async function migrateMissionOnDisk(id: string): Promise<MissionState | null> {\n const dir = missionDirSafe(id);\n const target = path.join(dir, \"plan.json\");\n if (!fs.existsSync(target)) return null;\n\n return withLock(target, async () => {\n // Create pre-migration backup\n const preBackup = path.join(dir, `plan.json.pre-migration-${Date.now()}.bak`);\n await fsAsync.copyFile(target, preBackup);\n\n const raw = JSON.parse(await fsAsync.readFile(target, \"utf-8\"));\n const migrated = migrateMission(raw);\n // Write migrated state atomically\n const temp = path.join(dir, \"plan.json.tmp\");\n await fsAsync.writeFile(temp, JSON.stringify(migrated, null, 2), \"utf-8\");\n await fsAsync.rename(temp, target);\n return migrated;\n });\n}\n\n/** Read raw plan.json to get pre-migration counts. Returns { milestones, features } or null. */\nexport function readRawMissionCounts(id: string): { milestones: number; features: number } | null {\n const dir = missionDirSafe(id);\n for (const name of [\"plan.json\", \"plan.json.bak\"]) {\n try {\n const raw = JSON.parse(fs.readFileSync(path.join(dir, name), \"utf-8\"));\n if (raw && typeof raw === \"object\") {\n const o = raw as Record<string, unknown>;\n if (Array.isArray(o.milestones)) {\n const features = o.milestones.reduce(\n (s: number, m: unknown) => s + (Array.isArray((m as Record<string, unknown>)?.features) ? ((m as Record<string, unknown>).features as unknown[]).length : 0),\n 0,\n );\n return { milestones: (o.milestones as unknown[]).length, features };\n }\n if (Array.isArray(o.features)) {\n return { milestones: 1, features: (o.features as unknown[]).length };\n }\n return { milestones: 0, features: 0 };\n }\n } catch { /* try next */ }\n }\n return null;\n}\n\nexport function listMissions(): MissionState[] {\n const root = missionsRoot();\n if (!fs.existsSync(root)) return [];\n return fs.readdirSync(root, { withFileTypes: true })\n .filter(e => e.isDirectory())\n .filter(e => {\n if (e.name.startsWith(\"pim-\")) return true;\n if (/^mission-\\d{17,}/.test(e.name)) return true;\n return false;\n })\n .map(e => loadMissionFromDisk(e.name))\n .filter((m): m is MissionState => Boolean(m))\n .sort((a, b) => b.updatedAt - a.updatedAt);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// History\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function appendHistory(\n mission: MissionState,\n entry: Omit<MissionHistoryEntry, \"ts\" | \"missionId\">,\n): void {\n const dir = missionDirSafe(mission.id);\n fs.mkdirSync(dir, { recursive: true });\n const line: MissionHistoryEntry = {\n ts: Math.floor(Date.now() / 1000),\n missionId: mission.id,\n ...entry,\n };\n fs.appendFileSync(path.join(dir, \"history.jsonl\"), JSON.stringify(line) + \"\\n\", \"utf-8\");\n}\n\nexport function readHistory(id: string): MissionHistoryEntry[] {\n const file = path.join(missionDirSafe(id), \"history.jsonl\");\n if (!fs.existsSync(file)) return [];\n return fs.readFileSync(file, \"utf-8\").split(\"\\n\").filter(Boolean).flatMap(line => {\n try { return [JSON.parse(line) as MissionHistoryEntry]; } catch { return []; }\n });\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Evidence\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function saveEvidence(mission: MissionState, feature: Feature, text: string): string {\n const dir = path.join(missionDirSafe(mission.id), \"evidence\");\n fs.mkdirSync(dir, { recursive: true });\n const file = path.join(dir, `${feature.id}.md`);\n fs.writeFileSync(file, text, \"utf-8\");\n return file;\n}\n\nexport function evidenceIntegrityHash(mission: MissionState, featureId: string): string | null {\n const evidenceFile = path.join(missionDirSafe(mission.id), \"evidence\", `${featureId}.md`);\n if (!fs.existsSync(evidenceFile)) return null;\n return sha256(fs.readFileSync(evidenceFile));\n}\n\nexport function evidenceIntegrityHashSafe(mission: MissionState, featureId: string): string | null {\n try { return evidenceIntegrityHash(mission, featureId); } catch { return null; }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Session linking\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function linkSession(mission: MissionState, sessionFile: string, agent?: string): void {\n const dir = path.join(missionDirSafe(mission.id), \"sessions\");\n fs.mkdirSync(dir, { recursive: true });\n const agentSource = agent || process.env.CODING_AGENT || \"unknown\";\n const refPath = path.join(dir, `${path.basename(sessionFile)}.${agentSource}.ref`);\n fs.writeFileSync(refPath, JSON.stringify({\n sessionFile,\n agent: agentSource,\n linkedAt: new Date().toISOString(),\n linkedAtMs: Date.now(),\n }, null, 2), \"utf-8\");\n}\n\nexport function listSessionRefs(missionId: string): Array<{ sessionFile: string; agent: string; linkedAt: string }> {\n const dir = path.join(missionDirSafe(missionId), \"sessions\");\n if (!fs.existsSync(dir)) return [];\n return fs.readdirSync(dir, { withFileTypes: true })\n .filter(e => e.isFile() && e.name.endsWith(\".ref\"))\n .flatMap(e => {\n try {\n const raw = fs.readFileSync(path.join(dir, e.name), \"utf-8\").trim();\n // Legacy plain-text refs: just a file path\n if (!raw.startsWith(\"{\")) {\n return [{ sessionFile: raw, agent: \"unknown\", linkedAt: \"\" }];\n }\n const parsed = JSON.parse(raw);\n return [{\n sessionFile: typeof parsed.sessionFile === \"string\" ? parsed.sessionFile : raw,\n agent: typeof parsed.agent === \"string\" ? parsed.agent : \"unknown\",\n linkedAt: typeof parsed.linkedAt === \"string\" ? parsed.linkedAt : \"\",\n }];\n } catch {\n return [];\n }\n });\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Auto-blocking / auto-unblocking\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function autoBlockBlockedFeatures(mission: MissionState): number {\n let changed = 0;\n for (const m of mission.milestones) {\n for (const f of m.features) {\n if (f.status === \"pending\" || f.status === \"active\") {\n const isBlocked = f.dependsOn.some((depId) => {\n const dep = getFeatureById(mission, depId);\n return dep && dep.status === \"blocked\";\n });\n if (isBlocked) {\n f.status = \"blocked\";\n f.notes = f.notes ? f.notes + \"\\nAuto-blocked: Dependency is blocked.\" : \"Auto-blocked: Dependency is blocked.\";\n changed++;\n }\n }\n }\n }\n return changed;\n}\n\nexport function autoUnblockResolved(mission: MissionState): number {\n let changed = 0;\n for (const m of mission.milestones) {\n for (const f of m.features) {\n if (f.status === \"blocked\") {\n const depsDone = dependenciesDone(mission, f);\n // Check if no dependencies are currently blocked\n const noBlockedDeps = !f.dependsOn.some((depId) => {\n const dep = getFeatureById(mission, depId);\n return dep && dep.status === \"blocked\";\n });\n if (depsDone || noBlockedDeps) {\n f.status = \"pending\";\n f.notes = f.notes ? f.notes + \"\\nAuto-unblocked: Dependencies resolved.\" : \"Auto-unblocked: Dependencies resolved.\";\n changed++;\n }\n }\n }\n }\n return changed;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Milestone auto-complete\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function autoCompleteMilestones(mission: MissionState): number {\n let completed = 0;\n for (const m of mission.milestones) {\n if (m.status === \"complete\") continue;\n if (m.features.every(f => f.status === \"done\")) {\n m.status = \"complete\";\n completed++;\n } else if (m.features.some(f => f.status === \"active\")) {\n m.status = \"active\";\n }\n }\n return completed;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Phase detection\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function getMissionPhase(mission: MissionState): ToolPhase {\n if (mission.status === \"planning\") return \"planning\";\n const active = getActiveFeature(mission);\n if (!active) return \"execution\";\n const t = `${active.title} ${active.description ?? \"\"}`.toLowerCase();\n if (t.includes(\"verify\") || t.includes(\"test\") || t.includes(\"summarize\")) return \"verification\";\n if (t.includes(\"clarify\") || t.includes(\"plan\") || t.includes(\"scope\") ||\n t.includes(\"research\") || t.includes(\"analyze\") || t.includes(\"analyse\") ||\n t.includes(\"inspect\") || t.includes(\"investigate\") || t.includes(\"discover\") ||\n t.includes(\"reconnaissance\") || t.includes(\"current state\")) {\n return \"planning\";\n }\n return \"execution\";\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Transitions: completeActiveFeature + activateNextFeature\n// ═══════════════════════════════════════════════════════════════════════════\n\nfunction allFeaturesDone(mission: MissionState): boolean {\n return getAllFeatures(mission).every(f => f.status === \"done\");\n}\n\nexport function autoVerifyAcceptance(\n feature: Feature,\n execFn: (cmd: string) => { code: number; stdout: string },\n): number {\n let verified = 0;\n for (const ac of feature.acceptance) {\n if (ac.verified || ac.waived || ac.checkType !== \"bash\" || !ac.checkCommand) continue;\n try {\n const result = execFn(ac.checkCommand);\n if (result.code === 0) {\n ac.verified = true;\n ac.evidence = result.stdout.slice(0, 1000);\n verified++;\n }\n } catch { /* leave unverified */ }\n }\n return verified;\n}\n\nexport function completeActiveFeature(\n mission: MissionState,\n options: CompleteFeatureOptions,\n): CompleteFeatureResult {\n const feature = getActiveFeature(mission);\n if (!feature) return { ok: false, reason: \"No active mission feature.\" };\n\n if (options.autoVerify && feature._execFn) {\n autoVerifyAcceptance(feature, feature._execFn);\n }\n\n const unverifiedBash = feature.acceptance.filter(\n ac => !ac.verified && !ac.waived && ac.checkType === \"bash\",\n );\n if (unverifiedBash.length > 0) {\n const details = unverifiedBash\n .map(ac => `${ac.id}: ${ac.description}${ac.checkCommand ? ` [bash: ${ac.checkCommand}]` : \"\"}`)\n .join(\"\\n\");\n return { ok: false, reason: `Cannot mark feature done: ${unverifiedBash.length} bash acceptance criteria need verification.\\n${details}`, unverifiedBashCount: unverifiedBash.length };\n }\n\n feature.status = \"done\";\n feature.completedAt = Date.now();\n if (options.notes !== undefined) feature.notes = options.notes;\n if (options.markAcceptanceVerified) {\n for (const ac of feature.acceptance) if (!ac.waived) ac.verified = true;\n }\n\n const evidenceFile = saveEvidence(mission, feature, options.evidence || \"Marked done.\");\n appendHistory(mission, {\n event: \"feature_done\",\n featureId: feature.id,\n note: options.historyNote ?? options.notes,\n details: { evidenceFile, ...options.historyDetails },\n });\n\n autoUnblockResolved(mission);\n const missionComplete = !getNextPendingFeature(mission) && allFeaturesDone(mission);\n if (missionComplete) {\n mission.status = \"complete\";\n mission.autopilot.enabled = false;\n mission.autopilot.lastStopReason = \"mission_complete\";\n }\n autoCompleteMilestones(mission);\n\n // Rebuild goalTree to keep it in sync after feature transitions\n (mission as { goalTree?: GoalTreeNode }).goalTree = buildMissionGoalTree(mission.title, mission.goal, mission.milestones);\n\n return { ok: true, feature, evidenceFile, missionComplete };\n}\n\nexport function activateNextFeature(mission: MissionState, note?: string): ActivateNextResult {\n const active = getActiveFeature(mission);\n if (active?.status === \"active\") return { ok: false, reason: \"active_not_done\", active };\n\n autoUnblockResolved(mission);\n const next = getNextPendingFeature(mission);\n if (!next) {\n if (allFeaturesDone(mission)) {\n mission.status = \"complete\";\n mission.autopilot.enabled = false;\n mission.autopilot.lastStopReason = \"mission_complete\";\n autoCompleteMilestones(mission);\n appendHistory(mission, { event: \"mission_complete\", note: note ?? \"All features complete\" });\n return { ok: false, reason: \"mission_complete\" };\n }\n return { ok: false, reason: \"no_unblocked_pending\" };\n }\n\n next.status = \"active\";\n next.startedAt = next.startedAt ?? Date.now();\n mission.status = \"active\";\n mission.activeFeatureId = next.id;\n mission.activeMilestoneId = next.milestoneId;\n appendHistory(mission, { event: \"feature_active\", featureId: next.id, note });\n return { ok: true, next };\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Stale feature detection\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function detectStaleFeature(mission: MissionState, now?: number): StaleFeatureAlert | null {\n if (mission.status !== \"active\") return null;\n const feature = getActiveFeature(mission);\n if (!feature || feature.status !== \"active\" || !feature.startedAt) return null;\n\n const ts = now ?? Date.now();\n const maxWallMs = feature.maxWallClockMs ?? DEFAULT_FEATURE_MAX_WALL_CLOCK_MS;\n const maxToolCalls = feature.maxToolCalls ?? DEFAULT_FEATURE_MAX_TOOL_CALLS;\n const activeMs = ts - feature.startedAt;\n const timeCritical = activeMs > maxWallMs;\n const timeWarn = activeMs > STALE_FEATURE_WARN_MS;\n const toolsExceeded = feature.toolCallCount > maxToolCalls;\n\n if (timeCritical || toolsExceeded) {\n return {\n featureId: feature.id, title: feature.title, activeMs,\n maxMs: maxWallMs, warnMs: STALE_FEATURE_WARN_MS,\n toolCallsUsed: feature.toolCallCount, maxToolCalls, level: \"critical\",\n };\n }\n if (timeWarn) {\n return {\n featureId: feature.id, title: feature.title, activeMs,\n maxMs: maxWallMs, warnMs: STALE_FEATURE_WARN_MS,\n toolCallsUsed: feature.toolCallCount, maxToolCalls, level: \"warn\",\n };\n }\n return null;\n}\n\nexport function detectStaleFeatureSafe(mission: MissionState, now?: number): StaleFeatureAlert | null {\n try { return detectStaleFeature(mission, now); } catch { return null; }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Metrics\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function computeMissionMetrics(mission: MissionState): MissionMetrics {\n const all = getAllFeatures(mission);\n const history = readHistory(mission.id);\n const doneFeatures = all.filter(f => f.status === \"done\");\n const failedFeatures = all.filter(f => f.status === \"failed\");\n let acceptanceFailures = 0;\n let evidenceHashErrors = 0;\n for (const f of all) {\n acceptanceFailures += f.acceptance.filter(ac => !ac.verified && !ac.waived).length;\n if (f.status === \"done\" && evidenceIntegrityHash(mission, f.id) === null) evidenceHashErrors++;\n }\n const completionEvent = history.find(h => h.event === \"mission_complete\");\n const totalWallMs = completionEvent\n ? (completionEvent.ts * 1000) - mission.createdAt\n : Date.now() - mission.createdAt;\n return {\n missionId: mission.id,\n created: mission.createdAt,\n completed: completionEvent?.ts ? completionEvent.ts * 1000 : undefined,\n totalFeatures: all.length,\n featuresDone: doneFeatures.length,\n featuresFailed: failedFeatures.length,\n totalTokensUsed: mission.tokensUsed,\n totalWallClockMs: totalWallMs,\n acceptanceFailures,\n evidenceHashErrors,\n };\n}\n\nexport function calculateMetricsSummary(): import(\"./types.js\").MissionMetricsSummary {\n const missions = listMissions();\n const metrics = missions.map(computeMissionMetrics);\n if (metrics.length === 0) {\n return {\n totalMissions: 0, completedMissions: 0, successRate: 0,\n averageTokensPerMission: 0, averageFeaturesPerMission: 0, averageCompletionTimeMs: 0,\n };\n }\n const completed = metrics.filter(m => m.completed !== undefined);\n const totalTokens = metrics.reduce((s, m) => s + m.totalTokensUsed, 0);\n const totalFeatures = metrics.reduce((s, m) => s + m.totalFeatures, 0);\n const totalTime = completed.reduce((s, m) => s + ((m.completed ?? m.created) - m.created), 0);\n return {\n totalMissions: metrics.length,\n completedMissions: completed.length,\n successRate: completed.length / metrics.length,\n averageTokensPerMission: totalTokens / metrics.length,\n averageFeaturesPerMission: totalFeatures / metrics.length,\n averageCompletionTimeMs: completed.length > 0 ? totalTime / completed.length : 0,\n };\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Worker prompt builder\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function buildWorkerPrompt(mission: MissionState, feature: Feature): string {\n const p = progress(mission);\n return [\n `## Mission: ${mission.title}`,\n `Goal: ${mission.goal}`,\n `Progress: ${p.done}/${p.total} features (${p.pct}%)`,\n \"\",\n `## Feature: ${feature.id} — ${feature.title}`,\n feature.description,\n \"\",\n \"### Acceptance Criteria\",\n ...feature.acceptance.map(ac => `- [ ] ${ac.id}: ${ac.description}${ac.checkCommand ? `\\n Command: \\`${ac.checkCommand}\\`` : \"\"}`),\n feature.dependsOn.length ? `\\n### Dependencies\\n${feature.dependsOn.join(\", \")}` : \"\",\n \"\",\n \"### Instructions\",\n \"1. Read the feature description and acceptance criteria carefully.\",\n \"2. Explore relevant code and understand the current state.\",\n \"3. Implement the smallest change that satisfies all acceptance criteria.\",\n \"4. Run checks to verify completion.\",\n \"5. Report completion with evidence — do NOT call mission_feature_done; the orchestrator will do that.\",\n \"\",\n \"Work ONLY on this feature. Do not advance to the next feature.\",\n ].join(\"\\n\");\n}\n","import { Type } from \"@sinclair/typebox\";\nimport type { Feature, Milestone, MissionState } from \"../core/types.js\";\nimport { SCHEMA_VERSION, type WizardOutput } from \"../core/types.js\";\nimport { createMissionId, createValidationToken } from \"./fs.js\";\nimport {\n acceptanceProgress, featureStatusIcon, missionStatusIcon,\n progressBar, clip,\n} from \"./context.js\";\nimport { getActiveFeature, getAllFeatures, progress, readHistory } from \"../core/state.js\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { missionDirSafe } from \"./fs.js\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Mission templates\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface MissionTemplate {\n id: string;\n label: string;\n description: string;\n goal: string;\n constraints: string;\n}\n\nexport const MISSION_TEMPLATES: MissionTemplate[] = [\n {\n id: \"refactor\", label: \"Refactor\", description: \"Safely refactor legacy code\",\n goal: \"Refactor a module or subsystem to improve maintainability without changing behavior.\",\n constraints: \"Existing tests must pass. No behavior changes. Keep the public API compatible.\",\n },\n {\n id: \"fix-bug\", label: \"Fix Bug\", description: \"Investigate and fix a bug\",\n goal: \"Identify the root cause of a reported bug and apply the minimal fix.\",\n constraints: \"Add a regression test. Do not refactor unrelated code. Verify the fix with evidence.\",\n },\n {\n id: \"add-feature\", label: \"Add Feature\", description: \"Implement a new feature\",\n goal: \"Implement a new capability or endpoint according to the specification.\",\n constraints: \"Add tests for the new functionality. Keep changes minimal and focused.\",\n },\n {\n id: \"docs\", label: \"Document\", description: \"Generate or update documentation\",\n goal: \"Produce accurate, verified documentation for a module, API, or workflow.\",\n constraints: \"Docs must be accurate and reflect current behavior. No stub or TODO content. Rendered output must be verified.\",\n },\n {\n id: \"investigate\", label: \"Investigate\", description: \"Research and analyze a codebase question\",\n goal: \"Answer a technical question about the codebase through exploration.\",\n constraints: \"Read-only exploration. No code changes. Provide evidence from the codebase.\",\n },\n {\n id: \"auth\", label: \"Auth implementation\", description: \"Implement authentication in a codebase\",\n goal: \"Add or refactor authentication in a codebase.\",\n constraints: \"Implement secure auth patterns. Add tests. Verify with evidence.\",\n },\n {\n id: \"ci-cd\", label: \"CI/CD Pipeline\", description: \"Set up or improve CI/CD pipeline\",\n goal: \"Implement or improve CI/CD pipeline.\",\n constraints: \"Ensure robust pipeline configuration. Verify with test runs.\",\n },\n {\n id: \"security-audit\", label: \"Security Audit\", description: \"Find and fix security vulnerabilities\",\n goal: \"Identify security vulnerabilities in a module, API, or workflow and document findings.\",\n constraints: \"Do not make permanent changes without explicit user approval. Document all findings with evidence. Prioritize critical/high severity issues.\",\n },\n {\n id: \"performance-opt\", label: \"Performance Optimization\", description: \"Improve performance of existing code\",\n goal: \"Identify and eliminate performance bottlenecks in a module or subsystem.\",\n constraints: \"Measure before and after. Do not degrade correctness or readability. Target meaningful improvements (≥20% speedup or ≥50% memory reduction).\",\n },\n];\n\nexport function createMissionFromTemplate(templateId: string, title: string): MissionState | null {\n const t = MISSION_TEMPLATES.find(t => t.id === templateId);\n if (!t) return null;\n return createStructuredMission(title || t.label, t.goal, t.constraints);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Mission builder\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function createStructuredMission(title: string, goal: string, constraints: string): MissionState {\n const id = createMissionId(title);\n const now = Date.now();\n return {\n schemaVersion: SCHEMA_VERSION,\n id, title, goal,\n status: \"active\",\n activeMilestoneId: \"M01\", activeFeatureId: \"F001\",\n tokensUsed: 0, lastContextTokens: 0,\n validationToken: createValidationToken(),\n autopilot: {\n enabled: false, mode: \"manual\", iteration: 0, maxIterations: 25,\n consecutiveFailures: 0, maxConsecutiveFailures: 3,\n noProgressTurns: 0, maxNoProgressTurns: 3, maxContextPercent: 85,\n startedAt: new Date(now).toISOString(), continueAcrossFeatures: true,\n requireEvidenceForDone: true,\n },\n createdAt: now, updatedAt: now,\n milestones: [\n {\n id: \"M01\", title: \"Plan and execute\",\n description: constraints ? `Constraints: ${constraints}` : \"Initial execution milestone\",\n status: \"active\",\n features: [\n { id: \"F001\", milestoneId: \"M01\", title: \"Clarify scope and current state\", description: \"Read the repository, identify relevant files, constraints, and existing behavior.\", priority: 1, dependsOn: [], status: \"active\", sessions: [], toolCallCount: 0, startedAt: now, acceptance: [{ id: \"AC001\", description: \"Relevant files and constraints documented\", checkType: \"manual\", verified: false }] },\n { id: \"F002\", milestoneId: \"M01\", title: \"Implement the core change\", description: \"Make the smallest coherent implementation that satisfies the mission goal.\", priority: 2, dependsOn: [\"F001\"], status: \"pending\", sessions: [], toolCallCount: 0, acceptance: [{ id: \"AC001\", description: \"Implementation matches mission goal\", checkType: \"manual\", verified: false }] },\n { id: \"F003\", milestoneId: \"M01\", title: \"Verify and summarize\", description: \"Run relevant checks, capture evidence, and summarize results.\", priority: 3, dependsOn: [\"F002\"], status: \"pending\", sessions: [], toolCallCount: 0, acceptance: [{ id: \"AC001\", description: \"Verification evidence saved\", checkType: \"manual\", verified: false }] },\n ],\n },\n ],\n };\n}\n\nexport function missionFromWizardOutput(raw: WizardOutput, title: string, goal: string): MissionState | null {\n const milestones = raw.milestones || [];\n if (milestones.length < 2) return null;\n\n const id = createMissionId(title);\n const now = Date.now();\n\n // ── Pass 1: Reassign global sequential feature IDs ───────────────────────\n // Build per-feature mapping: (oldId → newId)\n const mapping: Array<{ oldId: string; newId: string }> = [];\n let counter = 0;\n const intermediate = milestones.map((m, mi) => ({\n ...m, features: (m.features || []).map((f) => {\n const newId = `F${String(++counter).padStart(3, \"0\")}`;\n mapping.push({ oldId: f.id as string, newId });\n return { ...f, id: newId, dependsOn: [] as string[] };\n }),\n }));\n\n // ── Build lookups ─────────────────────────────────────────────────────────\n // oldId → set of newIds (may be multiple if old IDs were duplicated)\n const oldToNewSet = new Map<string, string[]>();\n for (const { oldId, newId } of mapping) {\n const arr = oldToNewSet.get(oldId) || [];\n arr.push(newId);\n oldToNewSet.set(oldId, arr);\n }\n\n // Wizard features flat list with original milestone/index for dep resolution\n const wizardFeatures = milestones.flatMap((wm, mi) =>\n wm.features.map((wf) => ({ ...wf, _mi: mi }))\n );\n\n // ── Pass 2: Remap dependencies using 1:1 mapping index ───────────────────\n let mapIdx = 0;\n for (let mi = 0; mi < intermediate.length; mi++) {\n const m = intermediate[mi]!;\n for (let fi = 0; fi < m.features.length; fi++) {\n const f = m.features[fi]!;\n mapIdx++;\n const orig = wizardFeatures[mapIdx - 1];\n if (!orig) continue;\n\n f.dependsOn = (orig.dependsOn || [])\n .filter((d: string) => oldToNewSet.has(d))\n .map((d: string) => {\n const candidates = oldToNewSet.get(d)!;\n // Resolve each candidate to its wizard feature via the 1:1 mapping index\n const resolveMilestone = (cid: string): number | undefined => {\n const idx = mapping.findIndex(me => me.newId === cid);\n return idx >= 0 ? wizardFeatures[idx]?._mi : undefined;\n };\n // Prefer candidate in the same original milestone\n const sameMilestone = candidates.find(cid => resolveMilestone(cid) === orig._mi);\n if (sameMilestone) return sameMilestone;\n // Next, prefer strictly earlier milestone candidates\n const earlier = candidates.find(cid => {\n const mi = resolveMilestone(cid);\n return mi !== undefined && mi < (orig._mi ?? 99);\n });\n if (earlier) return earlier;\n // Fallback to first candidate (will be validated later)\n return candidates[0]!;\n });\n }\n }\n\n // ── Build final migrated milestones ───────────────────────────────────────\n const migrated: Milestone[] = intermediate.map((m, mi) => {\n const milestoneId: string = (m.id ?? `M${String(mi + 1).padStart(2, \"0\")}`) as string;\n return {\n id: milestoneId,\n title: m.title,\n description: m.description || \"\",\n status: mi === 0 ? \"active\" : \"pending\" as Milestone[\"status\"],\n dependsOn: mi > 0 ? [milestones[mi - 1].id || `M${String(mi).padStart(2, \"0\")}`] : undefined,\n features: m.features.map((f, fi) => {\n const fid: string = f.id as string;\n return {\n id: fid,\n milestoneId,\n title: f.title,\n description: f.description || \"\",\n priority: f.priority || 1,\n dependsOn: f.dependsOn,\n status: mi === 0 && fi === 0 ? \"active\" : \"pending\" as Feature[\"status\"],\n sessions: [],\n toolCallCount: 0,\n acceptance: (f.acceptance || []).map((ac, ai) => ({\n id: ac.id || `AC${String(ai + 1).padStart(3, \"0\")}`,\n description: ac.description,\n checkType: ac.checkType || \"manual\",\n checkCommand: ac.checkCommand,\n verified: false,\n })),\n };\n }),\n };\n });\n\n const displayTitle = raw.title || title;\n return {\n schemaVersion: SCHEMA_VERSION, id, title: displayTitle, goal,\n status: \"active\", activeMilestoneId: migrated[0].id,\n activeFeatureId: migrated[0].features[0]?.id || \"F001\",\n tokensUsed: 0, lastContextTokens: 0, validationToken: createValidationToken(),\n autopilot: {\n enabled: false, mode: \"manual\", iteration: 0, maxIterations: 25,\n consecutiveFailures: 0, maxConsecutiveFailures: 3,\n noProgressTurns: 0, maxNoProgressTurns: 3, maxContextPercent: 85,\n startedAt: new Date(now).toISOString(), continueAcrossFeatures: true,\n requireEvidenceForDone: true,\n },\n createdAt: now, updatedAt: now, milestones: migrated,\n };\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Export helpers\n// ═══════════════════════════════════════════════════════════════════════════\n\n\nexport function exportMarkdown(mission: MissionState): string {\n const p = progress(mission);\n const active = getActiveFeature(mission);\n const all = getAllFeatures(mission);\n const done = all.filter(f => f.status === \"done\");\n const lines = [\n `# Mission Report: ${mission.title}`,\n \"\",\n `- **Goal**: ${mission.goal}`,\n `- **Status**: ${mission.status}`,\n `- **Goal tree**: ${p.done}/${p.total} leaf goals (${p.pct}%)`,\n `- **Progress**: ${p.done}/${p.total} (${p.pct}%)`,\n `- **Tokens used**: ${mission.tokensUsed.toLocaleString()}`,\n `- **Created**: ${new Date(mission.createdAt).toISOString()}`,\n \"\",\n \"## Executive Summary\",\n \"\",\n active ? `**Active feature**: ${active.id} — ${active.title} [${active.status}]` : \"**Active feature**: none\",\n `**Handoff**: ${mission.autopilot.lastStopReason ?? \"none\"}${mission.autopilot.lastStopMessage ? ` - ${mission.autopilot.lastStopMessage}` : \"\"}`,\n \"\",\n \"## Goal Tree\",\n \"\",\n ];\n\n for (const m of mission.milestones) {\n const mDone = m.features.filter(f => f.status === \"done\").length; lines.push(`## ${m.id}: ${m.title}`,\n `Status: ${m.status} | Progress: ${mDone}/${m.features.length}`,\n m.description ? `\\n${m.description}\\n` : \"\",\n `**Acceptance criteria:**`,\n );\n\n for (const f of m.features) {\n const icon = featureStatusIcon(f.status);\n const ac = acceptanceProgress(f);\n lines.push(`### ${f.id}: ${f.title}`,\n `- **Status**: ${f.status} | **Priority**: P${f.priority}`,\n `- **Acceptance**: ${ac.label}`,\n f.dependsOn.length ? `- **Dependencies**: ${f.dependsOn.join(\", \")}` : \"\",\n f.notes ? `- **Notes**: ${f.notes}` : \"\",\n f.description ? `\\n${f.description}\\n` : \"\",\n );\n\n for (const a of f.acceptance) {\n const mark = a.verified || a.waived ? \"✓\" : \"☐\";\n const waived = a.waived ? \" (waived)\" : \"\";\n const cmd = a.checkCommand ? ` \\`${a.checkCommand}\\`` : \"\";\n lines.push(`- [${mark}] ${a.id}: ${a.description}${cmd}${waived}`);\n }\n lines.push(\"\");\n }\n }\n\n // Evidence section\n if (done.length) {\n lines.push(\"\", \"## Evidence\");\n for (const f of done) {\n const evidenceFile = path.join(missionDirSafe(mission.id), \"evidence\", `${f.id}.md`);\n if (fs.existsSync(evidenceFile)) {\n const evidence = fs.readFileSync(evidenceFile, \"utf-8\");\n lines.push(`### ${f.id}: ${f.title}`, \"\", evidence.trim(), \"\");\n }\n }\n }\n\n // History section\n const history = readHistory(mission.id);\n if (history.length) {\n lines.push(\"## Recent History\");\n for (const h of history.slice(-10)) {\n const ts = new Date(h.ts * 1000).toISOString();\n lines.push(`- \\`${ts}\\` ${h.event}${h.featureId ? ` (${h.featureId})` : \"\"}${h.note ? ` - ${h.note}` : \"\"}`);\n }\n lines.push(\"\");\n }\n\n // Next runnable\n const nextRunnable = getActiveFeature(mission) ?? getAllFeatures(mission).find(f => f.status === \"pending\" || f.status === \"waiting\");\n if (nextRunnable) {\n lines.push(`**Next runnable**: ${nextRunnable.id} — ${nextRunnable.title}`);\n }\n\n lines.push(\"---\", `Generated by pi-missions at ${new Date().toISOString()}`);\n return lines.join(\"\\n\");\n}\n","import * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport * as crypto from \"node:crypto\";\n\n/**\n * Root directory for mission storage.\n *\n * Multi-agent: all coding agents share the same mission store by setting\n * MISSIONS_ROOT to a common directory.\n *\n * Priority:\n * 1. MISSIONS_ROOT env var (explicit override)\n * 2. PI_MISSIONS_ROOT env var (Pi-specific override)\n * 3. Default: ~/.pi/missions\n */\nexport function missionsRoot(): string {\n if (process.env.MISSIONS_ROOT) {\n if (!path.isAbsolute(process.env.MISSIONS_ROOT)) {\n throw new Error(`MISSIONS_ROOT must be an absolute path, got: ${process.env.MISSIONS_ROOT}`);\n }\n return process.env.MISSIONS_ROOT;\n }\n if (process.env.PI_MISSIONS_ROOT) {\n if (!path.isAbsolute(process.env.PI_MISSIONS_ROOT)) {\n throw new Error(`PI_MISSIONS_ROOT must be an absolute path, got: ${process.env.PI_MISSIONS_ROOT}`);\n }\n return process.env.PI_MISSIONS_ROOT;\n }\n const home = process.env.HOME || process.env.USERPROFILE || os.homedir();\n return path.join(home, \".pi\", \"missions\");\n}\n\n/**\n * Sanitize a mission ID for filesystem use.\n * Replaces all non-alphanumeric/dot/underscore/hyphen chars with hyphens.\n * Guards against path traversal attacks.\n */\nexport function missionDirSafe(id: string): string {\n const root = path.resolve(missionsRoot());\n const safeId = id.replace(/[^a-zA-Z0-9._-]/g, \"-\");\n const resolved = path.resolve(root, safeId);\n if (!resolved.startsWith(root + path.sep)) {\n throw new Error(`Invalid mission id: path traversal detected (${id})`);\n }\n return resolved;\n}\n\n/**\n * Create a mission ID in the format pim:<timestamp>:<slug>.\n */\nexport function createMissionId(title: string, now = Date.now()): string {\n const date = new Date(now).toISOString().replace(/[-:T.Z]/g, \"\");\n const stamp = date.slice(0, 17);\n const slug = slugify(title);\n return `pim:${stamp}:${slug}`;\n}\n\n/**\n * Validate whether a string matches the pim:<ts>:<slug> format.\n */\nexport function isValidMissionId(id: string): boolean {\n return id.startsWith(\"pim:\") && id.split(\":\").length === 3;\n}\n\n/**\n * Create a validation token (64 hex chars).\n */\nexport function createValidationToken(): string {\n return crypto.randomBytes(32).toString(\"hex\");\n}\n\n/**\n * Slugify a string for use in mission IDs.\n */\nexport function slugify(input: string): string {\n return input\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 64) || \"mission\";\n}\n\n/**\n * Compute a SHA-256 hash of a buffer or string.\n */\nexport function sha256(data: Buffer | string): string {\n return crypto.createHash(\"sha256\").update(data).digest(\"hex\");\n}\n","import type { Feature, MissionState } from \"../core/types.js\";\nimport { getActiveFeature, getAllFeatures, getMissionPhase, progress } from \"../core/state.js\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// UI Primitives (inline — tiny helpers, not worth a separate file)\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function clip(text: string, max = 88): string {\n return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n}\n\nexport function progressBar(done: number, total: number, width = 16): string {\n if (total === 0) return `[${\"░\".repeat(width)}]`;\n const ratio = Math.max(0, Math.min(1, done / total));\n const filled = Math.round(ratio * width);\n return `[${\"█\".repeat(filled)}${\"░\".repeat(width - filled)}]`;\n}\n\nexport function featureStatusIcon(status: string): string {\n switch (status) {\n case \"done\": return \"✅\";\n case \"active\": return \"➡️\";\n case \"blocked\": return \"⛔\";\n case \"failed\": return \"❌\";\n case \"waiting\": return \"⏳\";\n default: return \"•\";\n }\n}\n\nexport function missionStatusIcon(status: string): string {\n switch (status) {\n case \"complete\": return \"✅\";\n case \"paused\": return \"⏸\";\n case \"blocked\": return \"⛔\";\n case \"budget_limited\": return \"⚠️\";\n default: return \"🎯\";\n }\n}\n\nexport function acceptanceProgress(feature: Feature): { done: number; total: number; label: string } {\n const done = feature.acceptance.filter(ac => ac.verified || ac.waived).length;\n return { done, total: feature.acceptance.length, label: `${done}/${feature.acceptance.length}` };\n}\n\nexport function pendingAcceptance(feature: Feature, arrow = \"→\"): string[] {\n return feature.acceptance\n .filter(ac => !ac.verified && !ac.waived)\n .map(ac => ac.checkType === \"bash\" && ac.checkCommand\n ? `${ac.id}: ${ac.description} ${arrow} ${ac.checkCommand}`\n : `${ac.id}: ${ac.description}`);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Phase line\n// ═══════════════════════════════════════════════════════════════════════════\n\nfunction phaseLine(phase: string): string {\n switch (phase) {\n case \"planning\": return \"🔍 Phase: planning — explore, read, clarify. Avoid writes. Read-only bash.\";\n case \"verification\": return \"✅ Phase: verification — run checks, capture evidence, report exact gaps.\";\n default: return \"🔧 Phase: execution — smallest change that satisfies acceptance criteria.\";\n }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Layer 1: Mission banner (~6 lines)\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function buildMissionBanner(mission: MissionState): string {\n const active = getActiveFeature(mission);\n const p = progress(mission);\n const phase = getMissionPhase(mission);\n const bar = progressBar(p.done, p.total);\n\n const lines = [\n \"## Pi Missions Extension — Active\",\n `Mission: ${mission.title} | Goal: ${mission.goal}`,\n ` ${bar} ${p.done}/${p.total} leaf goals (${p.pct}%) — ${p.done}/${p.total} features`,\n ` Status: ${mission.status} | Phase: ${phase}`,\n ` State: ~/.pi/missions/${mission.id}/`,\n ];\n\n if (active) {\n lines.push(\"\", ` ▶ ${active.id}: ${active.title} [${phase}]`, ` ${active.description}`);\n } else {\n lines.push(\"\", \" No active feature.\");\n }\n return lines.join(\"\\n\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Layer 2: Feature brief (~8-12 lines)\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function buildFeatureBrief(mission: MissionState, feature: Feature, tokenBudget = 250): string {\n const phase = getMissionPhase(mission);\n const allFeatures = getAllFeatures(mission);\n const pendingCount = allFeatures.filter(f => f.status === \"pending\").length;\n const blockedCount = allFeatures.filter(f => f.status === \"blocked\").length;\n\n const lines: string[] = [];\n let used = 0;\n\n function add(...items: string[]): void {\n for (const item of items) {\n const cost = item.length / 4;\n if (used + cost > tokenBudget) return;\n lines.push(item);\n used += cost;\n }\n }\n\n // Goal path\n const milestoneTitle = mission.milestones.find(m => m.id === feature.milestoneId)?.title ?? \"\";\n add(`Goal path: ${milestoneTitle} > ${feature.title}`);\n add(\"\");\n\n // Acceptance criteria\n if (feature.acceptance.length) {\n add(\"**Acceptance:**\");\n for (const ac of feature.acceptance) {\n const mark = ac.verified || ac.waived ? \"x\" : \" \";\n const waived = ac.waived ? \" (waived)\" : \"\";\n add(`- [${mark}] ${ac.id}: ${ac.description}${waived}`);\n }\n }\n\n // Dependencies\n if (feature.dependsOn.length) {\n add(`Dependencies: ${feature.dependsOn.join(\", \")}`);\n }\n\n // Phase instruction\n add(\"\");\n add(phaseLine(phase));\n\n // Counts\n if (pendingCount) add(`📋 ${pendingCount} pending feature(s) queued.`);\n if (blockedCount) add(`⛔ ${blockedCount} blocked feature(s).`);\n\n return lines.join(\"\\n\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Layer 3: Mission help — full commands/tools reference\n// ═══════════════════════════════════════════════════════════════════════════\n\nconst MISSION_HELP = [\n \"### How To Work This Mission\",\n \"- Work only on the active feature unless the user explicitly redirects you or /mission next changes it.\",\n \"- During planning: gather context, avoid writes; read-only shell exploration is allowed.\",\n \"- During execution: make the smallest coherent change that satisfies the mission goal.\",\n \"- During verification: run relevant checks, capture evidence, and report exact gaps.\",\n \"- Do not silently mark work complete. Use /mission done or mission_feature_done only with concrete evidence.\",\n \"- If blocked, use /mission block <reason> or mission_block_self with a clear reason and next option.\",\n \"\",\n \"### Mission Commands\",\n \"- /mission start/new: create a new mission.\",\n \"- /mission load: resume an existing mission.\",\n \"- /mission status: show active mission, feature, progress, acceptance criteria.\",\n \"- /mission next: activate the next unblocked pending feature.\",\n \"- /mission done: mark the active feature done and save evidence.\",\n \"- /mission block: block the active feature.\",\n \"- /mission fork: create a linked alternative feature.\",\n \"- /mission dashboard: open mission control UI.\",\n \"- /mission debug: inspect recent mission history.\",\n \"- /mission metrics: show mission/session metrics.\",\n \"- /mission templates: create from a built-in template.\",\n \"- /mission export: export mission report as markdown.\",\n \"\",\n \"### Mission Tools\",\n \"- mission_next_feature: advance to the next pending feature.\",\n \"- mission_feature_done: mark the active feature done with evidence.\",\n \"- mission_ask_user: ask for clarification.\",\n \"- mission_block_self: self-block when stuck.\",\n \"- mission_fork: split into a linked fork.\",\n \"- mission_error_status: inspect error recovery state.\",\n \"- mission_retry_error: retry a retryable recorded error.\",\n].join(\"\\n\");\n\nexport function buildMissionHelp(): string {\n return MISSION_HELP;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Composed contexts\n// ═══════════════════════════════════════════════════════════════════════════\n\n/** Full context: banner + brief + help. Used on mission start/load. ~400 tokens */\nexport function buildMissionContext(mission: MissionState): string {\n const active = getActiveFeature(mission);\n const banner = buildMissionBanner(mission);\n const brief = active ? buildFeatureBrief(mission, active, 300) : \"\";\n const help = buildMissionHelp();\n\n const allFeatures = getAllFeatures(mission);\n const doneRecent = allFeatures.filter(f => f.status === \"done\").slice(-3);\n\n const parts = [banner];\n if (brief) parts.push(\"\", brief);\n parts.push(\"\", help);\n\n // Always show Goal Tree section\n parts.push(\"\", `### Goal Tree`);\n if (active) parts.push(`▶ ${active.title}`);\n if (doneRecent.length) {\n const recent = doneRecent.map(f => `✅ ${f.id} ${f.title}`).join(\" | \");\n if (recent) parts.push(`### Recently completed: ${recent}`);\n }\n\n parts.push(\"\", \"Work only on the active feature unless the user or /mission next changes it.\");\n return parts.join(\"\\n\");\n}\n\n/** Lean context: banner + feature brief only. ~250 tokens */\nexport function buildLeanContext(mission: MissionState): string {\n const active = getActiveFeature(mission);\n if (!active) return `${buildMissionBanner(mission)}\\n\\nNo active feature. Use \\`/mission status\\` for overview.`;\n\n const acLines = active.acceptance.map((a) => {\n const mark = a.verified || a.waived ? \"[x]\" : \"[ ]\";\n return `- ${mark} **${a.id}**: ${a.description}`;\n });\n\n return `${buildMissionBanner(mission)}\\n\\n${acLines.join(\"\\n\")}`;\n}\n\nexport function buildCompactionSummary(mission: MissionState): string {\n const active = getActiveFeature(mission);\n const p = progress(mission);\n let blocked = 0;\n let waiting = 0;\n for (const m of mission.milestones) {\n for (const f of m.features) {\n if (f.status === \"blocked\") blocked++;\n else if (f.status === \"waiting\") waiting++;\n }\n }\n\n return `Mission: ${mission.title} | ID: ${mission.id}\n Goal: ${mission.goal}\n Progress: ${p.done}/${p.total} features (${p.pct}%) | ${p.done}/${p.total} leaf goals (${p.pct}%) | Status: ${mission.status}\n ${active ? `Active: ${active.id} — ${active.title}` : \"Active: none\"}\n Blocked/Waiting: ${blocked}/${waiting}\n State: ~/.pi/missions/${mission.id}/\n Resume by loading mission state and continuing the active feature.`;\n}\n\nexport function completionSignal(text: string): boolean {\n if (!text) return false;\n const lower = text.toLowerCase();\n return [\n \"klaar\", \"done\", \"complete\", \"completed\", \"voltooid\",\n \"tests pass\", \"tests slagen\", \"implemented\",\n ].some(s => lower.includes(s));\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════════\n// Dependency chain helpers — for blocking chain visualization in dashboard\n// ═══════════════════════════════════════════════════════════════════════════════════\n\n/**\n * Returns the full upstream dependency chain for a feature.\n * Recursively traces dependsOn to find all features blocking this one.\n * Skips done dependencies since they're already satisfied.\n * Returns chain from immediate dep → root.\n */\nexport function dependsOnChain(mission: MissionState, feature: Feature): Array<{ id: string; status: string; title: string }> {\n const chain: Array<{ id: string; status: string; title: string }> = [];\n const visited = new Set<string>();\n\n function trace(fId: string): void {\n if (visited.has(fId)) return;\n visited.add(fId);\n const f = mission.milestones.flatMap(m => m.features).find(f => f.id === fId);\n if (!f) return;\n if (f.status === \"done\") return; // Skip satisfied deps\n chain.push({ id: f.id, status: f.status, title: f.title });\n for (const depId of f.dependsOn) {\n const dep = mission.milestones.flatMap(m => m.features).find(f => f.id === depId);\n if (!dep || dep.status === \"done\") continue;\n trace(depId);\n }\n }\n\n for (const depId of feature.dependsOn) trace(depId);\n return chain;\n}\n\n/**\n * Formats a dependency chain as a compact visual string.\n * E.g.: \"🔗 F001(•) Plan → F002(⏳) Scope → F003(⛔) Blocked\"\n */\nexport function formatDepChain(chain: Array<{ id: string; status: string; title?: string }>): string {\n if (!chain.length) return \"\";\n const statusIcon: Record<string, string> = {\n pending: \"•\", waiting: \"⏳\", blocked: \"⛔\", active: \"➡️\", done: \"✅\", failed: \"❌\",\n };\n const parts = chain.map(n => {\n const icon = statusIcon[n.status] ?? \"•\";\n const label = n.title ? ` ${clip(n.title, 20)}` : \"\";\n return `${n.id}(${icon}${label})`;\n });\n return `🔗 ${parts.join(\" → \")}`;\n}\n\nexport function featureSummary(feature: Feature): string {\n return `${feature.id}: ${feature.title} [${feature.status}]`;\n}\n","// Shim: mission-builder for backward compat with old tests\nimport type { Milestone, MissionState } from \"../core/types.js\";\nimport { missionFromWizardOutput as createMissionFromMarkdown } from \"./markdown.js\";\n\n// ── Goal tree types ──────────────────────────────────────────────────────\n\nexport interface GoalTreeNode {\n id: string;\n label: string;\n children: GoalTreeNode[];\n status: string;\n root: GoalTreeNode;\n}\n\nexport function buildMissionGoalTree(title: string, goal: string, milestones: Milestone[]): GoalTreeNode {\n const children = milestones.map((m) => ({\n id: m.id,\n label: m.title,\n status: m.status,\n children: m.features.map((f) => ({\n id: f.id,\n label: f.title,\n status: f.status,\n children: [] as GoalTreeNode[],\n root: {} as GoalTreeNode,\n })),\n root: {} as GoalTreeNode,\n }));\n\n const tree: GoalTreeNode = {\n id: \"root\",\n label: title,\n status: \"active\",\n children,\n root: {} as GoalTreeNode,\n };\n tree.root = tree;\n // Fix root references in children\n for (const mc of tree.children) {\n mc.root = tree;\n for (const fc of mc.children) fc.root = tree;\n }\n return tree;\n}\n\nexport function getMissionGoalTree(mission: MissionState): GoalTreeNode {\n if (mission.goalTree) {\n // Refresh stale goalTree: rebuild from current mission state\n const fresh = buildMissionGoalTree(mission.title, mission.goal, mission.milestones);\n mission.goalTree = fresh;\n return fresh;\n }\n const tree = buildMissionGoalTree(mission.title, mission.goal, mission.milestones);\n mission.goalTree = tree;\n return tree;\n}\n\nexport function goalTreeProgress(tree: GoalTreeNode): { done: number; total: number; pct: number } {\n if (!tree) return { done: 0, total: 0, pct: 0 };\n function count(n: GoalTreeNode): [number, number] {\n if (!n || !n.children || !n.children.length) return [n.status === \"done\" ? 1 : 0, 1];\n const results = n.children.map(count);\n return [results.reduce((s, r) => s + r[0], 0), results.reduce((s, r) => s + r[1], 0)];\n }\n const [done, total] = count(tree);\n return { done, total, pct: total ? Math.round((done / total) * 100) : 0 };\n}\n\nexport function renderGoalTree(tree: GoalTreeNode, maxNodes?: number): string {\n const lines: string[] = [];\n let count = 0;\n\n function walk(node: GoalTreeNode, indent: number): void {\n if (maxNodes !== undefined && count >= maxNodes) {\n if (count === maxNodes) lines.push(\" …\");\n count++;\n return;\n }\n const prefix = \" \".repeat(indent);\n const icon = node.status === \"done\" ? \"✅\" : node.status === \"active\" ? \"➡️\" : \"•\";\n lines.push(`${prefix}${icon} ${node.label}`);\n count++;\n for (const child of node.children) walk(child, indent + 1);\n }\n\n walk(tree, 0);\n return lines.join(\"\\n\");\n}\n\n// ── Wizard output ────────────────────────────────────────────────────────\n\nexport function missionFromWizardOutput(\n wizardOutput: {\n title: string;\n milestones: Array<{\n id: string;\n title: string;\n description: string;\n features: Array<{\n id: string;\n title: string;\n description: string;\n priority: number;\n dependsOn: string[];\n acceptance: Array<{ id: string; description: string; checkType: string }>;\n }>;\n }>;\n },\n fallbackTitle: string,\n goal: string,\n _mode?: number,\n): MissionState | null {\n // Build per-feature ID mapping: reassign all feature IDs sequentially.\n // Use a list of (oldId, newId) pairs to handle duplicate old IDs correctly.\n const mapping: Array<{ oldId: string; newId: string }> = [];\n let counter = 0;\n const normalizedOutput = {\n title: wizardOutput.title,\n milestones: wizardOutput.milestones.map((m) => ({\n ...m,\n features: m.features.map((f) => {\n const newId = `F${String(++counter).padStart(3, \"0\")}`;\n mapping.push({ oldId: f.id, newId });\n return { ...f, id: newId, dependsOn: [] as string[] };\n }),\n })),\n };\n\n // Build lookup: oldId → set of newIds (may be multiple if dupes)\n const oldToNewSet = new Map<string, string[]>();\n for (const { oldId, newId } of mapping) {\n const arr = oldToNewSet.get(oldId) || [];\n arr.push(newId);\n oldToNewSet.set(oldId, arr);\n }\n\n // Also build: newId → original wizard feature index for dep resolution\n const wizardFeatures = wizardOutput.milestones.flatMap((wm, mi) =>\n wm.features.map((wf, fi) => ({ ...wf, _mi: mi, _fi: fi }))\n );\n\n // Second pass: resolve deps using the mapping\n let mapIdx = 0;\n for (let mi = 0; mi < normalizedOutput.milestones.length; mi++) {\n const m = normalizedOutput.milestones[mi]!;\n for (let fi = 0; fi < m.features.length; fi++) {\n const f = m.features[fi]!;\n mapIdx++;\n const orig = wizardFeatures[mapIdx - 1];\n if (!orig) continue;\n f.dependsOn = (orig.dependsOn ?? [])\n .filter((d: string) => oldToNewSet.has(d))\n .map((d: string) => {\n const candidates = oldToNewSet.get(d)!;\n // Resolve each candidate to its wizard feature via the 1:1 mapping index\n const resolveMilestone = (cid: string): number | undefined => {\n const idx = mapping.findIndex(me => me.newId === cid);\n return idx >= 0 ? wizardFeatures[idx]?._mi : undefined;\n };\n // Prefer candidate in the same original milestone\n const sameMilestone = candidates.find(cid => resolveMilestone(cid) === orig._mi);\n if (sameMilestone) return sameMilestone;\n // Next, prefer earlier milestone candidates (strictly before orig._mi)\n const earlier = candidates.find(cid => {\n const mi = resolveMilestone(cid);\n return mi !== undefined && mi < (orig._mi ?? 99);\n });\n if (earlier) return earlier;\n return candidates[0]!;\n });\n }\n }\n\n return createMissionFromMarkdown(normalizedOutput as Parameters<typeof createMissionFromMarkdown>[0], fallbackTitle, goal);\n}\n\n// ── Augment MissionState with goalTree ───────────────────────────────────\ndeclare module \"../core/types.js\" {\n interface MissionState {\n goalTree?: GoalTreeNode;\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport type { RuntimeState } from \"../core/types.js\";\nimport { WizardOutputSchema, validate } from \"../core/types.js\";\nimport {\n activateNextFeature, appendHistory, autoBlockBlockedFeatures,\n completeActiveFeature, getActiveFeature, getFeatureById, getMilestoneById,\n getNextPendingFeature,\n loadMissionFromDisk, listMissions, progress, readHistory, saveMissionSafe,\n readRawSchemaVersion, readRawMissionCounts, migrateMissionOnDisk,\n} from \"../core/state.js\";\nimport { SCHEMA_VERSION } from \"../core/types.js\";\nimport { missionsRoot } from \"../utils/fs.js\";\nimport { buildMissionContext, buildMissionHelp } from \"../utils/context.js\";\nimport { createStructuredMission, missionFromWizardOutput, createMissionFromTemplate, MISSION_TEMPLATES, exportMarkdown } from \"../utils/markdown.js\";\nimport { updateFooter, statusText } from \"../ui/components.js\";\nimport { missionControlOverlay } from \"../ui/dashboard.js\";\nimport { sessionMetrics } from \"../engines/metrics.js\";\nimport { ensureActiveFeature, shouldContinue, triggerContinuation } from \"../engines/autopilot.js\";\nimport { spawnWorker, killWorker, getActiveWorker, isWorkerRunning } from \"../engines/worker.js\";\nimport { calculateMetricsSummary, computeMissionMetrics } from \"../core/state.js\";\nimport { injectMissionContext } from \"../tools/index.js\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Planning wizard prompt\n// ═══════════════════════════════════════════════════════════════════════════\n\nconst PLANNING_WIZARD_PROMPT = `You are the mission planner for a software development mission. Analyze the user's goal and produce a structured mission plan.\n\nGoal: {goal}\nConstraints: {constraints}\n\nRespond ONLY with a valid JSON object (no markdown, no explanation) in this exact format:\n{\n \"title\": \"short mission title\",\n \"milestones\": [\n {\n \"id\": \"M01\",\n \"title\": \"Milestone 1 title\",\n \"description\": \"What this milestone covers\",\n \"features\": [\n {\n \"id\": \"F001\",\n \"title\": \"Feature 1 title\",\n \"description\": \"What this feature does\",\n \"priority\": 1,\n \"dependsOn\": [],\n \"acceptance\": [\n { \"id\": \"AC001\", \"description\": \"Acceptance criterion\", \"checkType\": \"manual\" }\n ]\n }\n ]\n }\n ]\n}\n\nRules:\n- id format: M01, M02, ... for milestones; F001, F002, ... per milestone\n- At least 2 milestones, at least 5 total features\n- Each feature needs at least one acceptance criterion\n- checkType: \"manual\" | \"bash\" | \"test_file\"\n- priority: 1 (highest) to 5 (lowest)\n- Be specific and actionable\n`;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Injection helper — thin wrapper that builds context before injecting\n// ═══════════════════════════════════════════════════════════════════════════\n\nfunction injectMissionContextWrapper(\n pi: ExtensionAPI,\n ctx: ExtensionCommandContext,\n mission: NonNullable<RuntimeState[\"activeMission\"]>,\n reason: string,\n): void {\n injectMissionContext(pi, ctx, mission, reason, buildMissionContext(mission));\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission new / /mission start\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleNew(\n titleArg: string, ctx: ExtensionCommandContext,\n pi: ExtensionAPI, runtime: RuntimeState,\n): Promise<void> {\n const title = titleArg || \"Untitled mission\";\n let goal = title;\n let constraints = \"\";\n let usedWizard = false;\n\n if (ctx.hasUI) {\n goal = (await ctx.ui.input(\"Mission goal\", `What should '${title}' achieve?`)) || title;\n constraints = (await ctx.ui.input(\"Constraints\", \"Hard rules? (tests, no deps, etc.)\")) || \"\";\n }\n\n let parsedMission: ReturnType<typeof createStructuredMission> | null = null;\n const planningPrompt = PLANNING_WIZARD_PROMPT.replace(\"{goal}\", goal).replace(\"{constraints}\", constraints);\n\n const piWithSend = pi as ExtensionAPI & { sendUserMessage?: (m: string, o?: { timeoutMs: number }) => Promise<unknown> };\n if (piWithSend.sendUserMessage) {\n try {\n ctx.ui.notify(\"🤖 Planning wizard generating milestones…\", \"info\");\n const response = await piWithSend.sendUserMessage(planningPrompt, { timeoutMs: 60_000 });\n const text = typeof response === \"string\" ? response : String((response as Record<string, unknown>)?.content ?? JSON.stringify(response));\n const m = String(text).match(/\\{[\\s\\S]*\\}/);\n if (m) {\n const raw = JSON.parse(m[0]);\n const validation = validate(WizardOutputSchema, raw);\n if (!validation.valid) {\n ctx.ui.notify(\"Wizard output incomplete; falling back to structured scaffold.\", \"warning\");\n } else {\n parsedMission = missionFromWizardOutput(raw, title, goal);\n if (!parsedMission) ctx.ui.notify(\"Wizard output too little structure; falling back.\", \"warning\");\n else usedWizard = true;\n }\n }\n } catch { /* fall through */ }\n }\n\n const mission = parsedMission ?? createStructuredMission(title, goal, constraints);\n runtime.activeMission = mission;\n await saveMissionSafe(mission);\n appendHistory(mission, { event: \"mission_created\", note: goal, details: { usedWizard } });\n pi.appendEntry(\"pi-mission-active\", { missionId: mission.id, validationToken: mission.validationToken });\n injectMissionContextWrapper(pi, ctx, mission, \"mission_started\");\n pi.setSessionName(`🎯 ${mission.title}`);\n updateFooter(ctx, mission);\n const fc = mission.milestones.reduce((s, m) => s + m.features.length, 0);\n ctx.ui.notify(usedWizard\n ? `✅ Mission created: ${mission.milestones.length} milestones, ${fc} features (AI-generated)`\n : `✅ Mission created: ${mission.id} — /mission status or /mission next`, \"info\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission templates\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleTemplates(\n sub: string | undefined, arg: string | undefined, title: string,\n ctx: ExtensionCommandContext, pi: ExtensionAPI, runtime: RuntimeState,\n): Promise<void> {\n if (!sub || sub === \"list\") {\n const lines = [\"Available templates:\", \"\"];\n for (const t of MISSION_TEMPLATES) lines.push(` ${t.id.padEnd(12)} ${t.label.padEnd(20)} ${t.description}`);\n lines.push(\"\", \"/mission templates scaffold <id> [title]\");\n ctx.ui.notify(lines.join(\"\\n\"), \"info\");\n return;\n }\n if (sub === \"scaffold\" && arg) {\n const mission = createMissionFromTemplate(arg, title);\n if (!mission) return ctx.ui.notify(`Unknown template: ${arg}. Use /mission templates list.`, \"error\");\n runtime.activeMission = mission;\n await saveMissionSafe(mission);\n appendHistory(mission, { event: \"mission_created\", note: `From template: ${arg}` });\n pi.appendEntry(\"pi-mission-active\", { missionId: mission.id, validationToken: mission.validationToken });\n injectMissionContextWrapper(pi, ctx, mission, \"mission_started_from_template\");\n pi.setSessionName(`🎯 ${mission.title}`);\n updateFooter(ctx, mission);\n ctx.ui.notify(`✅ Mission created from '${arg}' template: ${mission.id}`, \"info\");\n return;\n }\n ctx.ui.notify(\"Usage: /mission templates [list|scaffold <id> [title]]\", \"warning\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission list\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleList(ctx: ExtensionCommandContext, pi: ExtensionAPI, runtime: RuntimeState): Promise<void> {\n const missions = listMissions();\n if (!missions.length) return ctx.ui.notify(\"No missions found.\", \"info\");\n if (!ctx.hasUI) {\n return ctx.ui.notify(missions.map(m => `${m.id} — ${m.title} (${m.status})`).join(\"\\n\"), \"info\");\n }\n const labels = missions.map(m => `${m.id} — ${m.title} [${progress(m).done}/${progress(m).total}] ${m.status}`);\n const choice = await ctx.ui.select(\"Load mission:\", labels);\n if (!choice) return;\n await handleLoad(choice.split(\" — \")[0], ctx, pi, runtime);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission load\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleLoad(id: string | undefined, ctx: ExtensionCommandContext, pi: ExtensionAPI, runtime: RuntimeState): Promise<void> {\n if (!id) return ctx.ui.notify(\"Usage: /mission load <id>\", \"warning\");\n const mission = loadMissionFromDisk(id);\n if (!mission) return ctx.ui.notify(`Mission not found: ${id}`, \"error\");\n\n autoBlockBlockedFeatures(mission);\n runtime.activeMission = mission;\n pi.appendEntry(\"pi-mission-active\", { missionId: mission.id, validationToken: mission.validationToken });\n injectMissionContextWrapper(pi, ctx, mission, \"mission_loaded\");\n pi.setSessionName(`🎯 ${mission.title}`);\n updateFooter(ctx, mission);\n ctx.ui.notify(`Loaded mission: ${mission.title}`, \"info\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission status\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleStatus(ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n const mission = runtime.activeMission;\n if (!mission) return ctx.ui.notify(\"No active mission. /mission new or /mission load.\", \"info\");\n updateFooter(ctx, mission);\n ctx.ui.notify(statusText(mission), \"info\");\n}\n\nexport async function handleHelp(ctx: ExtensionCommandContext): Promise<void> {\n ctx.ui.notify(buildMissionHelp(), \"info\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission next\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleNext(ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n const m = runtime.activeMission;\n if (!m) return ctx.ui.notify(\"No active mission.\", \"warning\");\n\n const result = activateNextFeature(m);\n if (!result.ok) {\n if (result.reason === \"active_not_done\") {\n return ctx.ui.notify(`Active feature not done yet: ${result.active.id} — ${result.active.title}\\n/mission done or /mission block.`, \"warning\");\n }\n if (result.reason === \"mission_complete\") {\n await saveMissionSafe(m); updateFooter(ctx, m);\n return ctx.ui.notify(\"🎉 Mission complete.\", \"info\");\n }\n return ctx.ui.notify(\"No unblocked pending feature found.\", \"warning\");\n }\n autoBlockBlockedFeatures(m);\n await saveMissionSafe(m); updateFooter(ctx, m);\n ctx.ui.notify(`➡️ Active feature: ${result.next.id} — ${result.next.title}\\n${result.next.description}`, \"info\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission done\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleDone(evidence: string, ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n const m = runtime.activeMission;\n const f = m ? getActiveFeature(m) : null;\n if (!m || !f) return ctx.ui.notify(\"No active feature.\", \"warning\");\n if (!evidence && ctx.hasUI) evidence = (await ctx.ui.input(\"Evidence\", \"Why is this feature done?\")) || \"Marked done.\";\n\n const result = completeActiveFeature(m, { evidence: evidence || \"Marked done.\", autoVerify: true });\n if (!result.ok) return ctx.ui.notify(`${result.reason}\\n\\n/mission edit to waive criteria.`, \"warning\");\n\n await saveMissionSafe(m); updateFooter(ctx, m);\n \n // Suggest handoff for large features (>50 tool calls or >10 min active)\n const wallMs = (f.startedAt && f.completedAt) ? f.completedAt - f.startedAt : 0;\n const isLarge = f.toolCallCount > 50 || wallMs > 600_000;\n const nextPending = getNextPendingFeature(m);\n \n let notify = `✅ ${result.feature.id} done. Evidence: ${result.evidenceFile}`;\n if (isLarge && nextPending && !result.missionComplete) {\n notify += `\\n\\n🤝 Large feature completed (${f.toolCallCount} calls, ${Math.round(wallMs / 60000)}min). Consider /handoff \"Continue ${m.title} from ${nextPending.id} — ${nextPending.title}\" for a fresh session.`;\n }\n ctx.ui.notify(notify, \"info\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission block\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleBlock(reason: string, ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n const m = runtime.activeMission;\n const f = m ? getActiveFeature(m) : null;\n if (!m || !f) return ctx.ui.notify(\"No active feature.\", \"warning\");\n f.status = \"blocked\";\n f.notes = reason || \"Blocked\";\n appendHistory(m, { event: \"feature_blocked\", featureId: f.id, note: f.notes });\n await saveMissionSafe(m); updateFooter(ctx, m);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission run / /mission autopilot / /mission stop / pause / resume / clear\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleRun(ctx: ExtensionCommandContext, pi: ExtensionAPI, runtime: RuntimeState): Promise<void> {\n const m = runtime.activeMission;\n if (!m) return ctx.ui.notify(\"No active mission.\", \"warning\");\n m.status = \"active\";\n m.autopilot = {\n ...m.autopilot, enabled: true, mode: \"autopilot\", iteration: 0,\n consecutiveFailures: 0, noProgressTurns: 0,\n startedAt: new Date().toISOString(), lastStopReason: undefined, lastStopMessage: undefined,\n };\n const f = ensureActiveFeature(m);\n if (!f) {\n m.autopilot.enabled = false; m.autopilot.lastStopReason = \"no_active_feature\";\n await saveMissionSafe(m); updateFooter(ctx, m);\n return ctx.ui.notify(\"No runnable feature available.\", \"warning\");\n }\n appendHistory(m, { event: \"autopilot_started\", featureId: f.id });\n await saveMissionSafe(m); updateFooter(ctx, m);\n await triggerContinuation(pi, ctx, m);\n ctx.ui.notify(`Autopilot started for ${f.id} - ${f.title}.`, \"info\");\n}\n\nexport async function handleAutopilot(ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n const m = runtime.activeMission;\n if (!m) return ctx.ui.notify(\"No active mission.\", \"warning\");\n const decision = shouldContinue(m, ctx);\n const a = m.autopilot;\n ctx.ui.notify([\n `Autopilot: ${a.enabled ? \"ON\" : \"OFF\"} (${a.mode})`,\n `Iteration: ${a.iteration}/${a.maxIterations}`,\n `Failures: ${a.consecutiveFailures}/${a.maxConsecutiveFailures}`,\n `No-progress: ${a.noProgressTurns}/${a.maxNoProgressTurns}`,\n `Last stop: ${a.lastStopReason ?? \"none\"}${a.lastStopMessage ? ` - ${a.lastStopMessage}` : \"\"}`,\n `Would continue: ${decision.continue ? \"yes\" : `no (${decision.reason})`}`,\n ].join(\"\\n\"), \"info\");\n}\n\nexport async function handleStop(ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n const m = runtime.activeMission;\n if (!m) return ctx.ui.notify(\"No active mission.\", \"warning\");\n m.autopilot.enabled = false; m.autopilot.mode = \"manual\";\n m.autopilot.lastStopReason = \"paused_by_user\"; m.autopilot.lastStopMessage = \"Stopped by user.\";\n appendHistory(m, { event: \"autopilot_stopped\" });\n await saveMissionSafe(m); updateFooter(ctx, m);\n ctx.ui.notify(\"Autopilot stopped.\", \"info\");\n}\n\nexport async function handlePause(ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n if (!runtime.activeMission) return ctx.ui.notify(\"No active mission.\", \"warning\");\n runtime.activeMission.status = \"paused\";\n runtime.activeMission.autopilot.enabled = false;\n runtime.activeMission.autopilot.lastStopReason = \"paused_by_user\";\n runtime.activeMission.autopilot.lastStopMessage = \"Paused by user.\";\n appendHistory(runtime.activeMission, { event: \"mission_paused\" });\n await saveMissionSafe(runtime.activeMission); updateFooter(ctx, runtime.activeMission);\n}\n\nexport async function handleResume(ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n if (!runtime.activeMission) return ctx.ui.notify(\"No active mission.\", \"warning\");\n runtime.activeMission.status = \"active\";\n runtime.activeMission.autopilot.enabled = true;\n runtime.activeMission.autopilot.mode = \"autopilot\";\n runtime.activeMission.autopilot.lastStopReason = undefined;\n runtime.activeMission.autopilot.lastStopMessage = undefined;\n ensureActiveFeature(runtime.activeMission);\n appendHistory(runtime.activeMission, { event: \"mission_resumed\" });\n await saveMissionSafe(runtime.activeMission); updateFooter(ctx, runtime.activeMission);\n ctx.ui.notify(\"Resumed. /mission run for immediate autopilot turn.\", \"info\");\n}\n\nexport async function handleClear(ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n runtime.activeMission = null;\n updateFooter(ctx, null);\n ctx.ui.notify(\"Mission detached.\", \"info\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission edit\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleEdit(featureId: string | undefined, ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n const m = runtime.activeMission;\n if (!m || !featureId) return ctx.ui.notify(\"Usage: /mission edit <feature-id>\", \"warning\");\n const f = getFeatureById(m, featureId);\n if (!f) return ctx.ui.notify(`Feature not found: ${featureId}`, \"error\");\n if (!ctx.hasUI) return ctx.ui.notify(JSON.stringify(f, null, 2), \"info\");\n\n const edited = await ctx.ui.editor(\"Edit feature JSON\", JSON.stringify(f, null, 2));\n if (!edited) return;\n let parsed: unknown;\n try { parsed = JSON.parse(edited); } catch (e) {\n return ctx.ui.notify(`Invalid feature JSON: ${e instanceof Error ? e.message : String(e)}`, \"error\");\n }\n const { FeatureSchema } = await import(\"../core/types.js\");\n const validation = validate(FeatureSchema, parsed);\n if (!validation.valid) {\n const errors = validation.errors.slice(0, 5).map(e => `- ${e.path}: ${e.message}`).join(\"\\n\");\n return ctx.ui.notify(`Invalid feature:\\n${errors}`, \"error\");\n }\n Object.assign(f, parsed);\n appendHistory(m, { event: \"feature_edited\", featureId });\n await saveMissionSafe(m); updateFooter(ctx, m);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission fork\n// ═══════════════════════════════════════════════════════════════════════════\n\nimport type { ForkSessionManager, ForkReplacementContext } from \"../core/types.js\";\nimport { buildForkKickoffMessage, buildManualForkHandoff, appendForkNote, pushSessionRef, cloneFeatureForFork } from \"../tools/index.js\";\n\n// The local fork handler delegates to the tool's fork helpers\n// We inline the fork logic here since it's command-specific\nasync function forkFeatureInternally(\n m: NonNullable<RuntimeState[\"activeMission\"]>,\n reason: string,\n pi: ExtensionAPI,\n ctx: ExtensionCommandContext,\n): Promise<void> {\n const f = getActiveFeature(m);\n if (!f) { ctx.ui.notify(\"No active feature. Use /mission next to advance, then fork.\", \"warning\"); return; }\n\n const sm = ctx.sessionManager as ForkSessionManager;\n const createdAt = new Date().toISOString();\n const parentLeafId = sm.getLeafId?.() ?? null;\n const parentSessionFile = sm.getSessionFile?.();\n const forkedId = `${f.id}-fork-${Date.now()}`;\n const forked = cloneFeatureForFork(f, forkedId, `${f.title} [fork]`, `Fork: ${reason}`);\n const milestone = getMilestoneById(m, f.milestoneId);\n if (!milestone) { ctx.ui.notify(\"Milestone not found.\", \"error\"); return; }\n\n f.status = \"blocked\";\n f.notes = appendForkNote(f.notes, [`Forked at ${createdAt}`, `Fork: ${forked.id}`, `Reason: ${reason}`, parentLeafId ? `Leaf: ${parentLeafId}` : \"\", parentSessionFile ? `Session: ${parentSessionFile}` : \"\"]);\n pushSessionRef(f, `fork:${forked.id}`); pushSessionRef(f, parentLeafId ? `leaf:${parentLeafId}` : undefined); pushSessionRef(f, parentSessionFile ? `session:${parentSessionFile}` : undefined);\n\n forked.notes = appendForkNote(forked.notes, [`Fork source: ${f.id}`, `Created: ${createdAt}`, `Reason: ${reason}`, parentSessionFile ? `Parent session: ${parentSessionFile}` : \"\"]);\n pushSessionRef(forked, `parent-feature:${f.id}`); pushSessionRef(forked, parentLeafId ? `parent-leaf:${parentLeafId}` : undefined); pushSessionRef(forked, parentSessionFile ? `parent-session:${parentSessionFile}` : undefined);\n\n milestone.features.push(forked);\n m.activeFeatureId = forked.id; m.status = \"active\";\n appendHistory(m, { event: \"feature_forked\", featureId: f.id, note: reason, details: { forkedFeatureId: forked.id, parentLeafId, parentSessionFile, forkApiAvailable: typeof ctx.fork === \"function\" } });\n await saveMissionSafe(m);\n\n const kickoff = buildForkKickoffMessage(m.title, f, forked, reason, undefined, parentSessionFile);\n\n let forkResult: { cancelled?: boolean } | undefined;\n if (parentLeafId && typeof ctx.fork === \"function\") {\n forkResult = await ctx.fork(parentLeafId, {\n position: \"at\",\n withSession: async (fc) => {\n const fcCtx = fc as unknown as ForkReplacementContext;\n const fsf = (fc.sessionManager as ForkSessionManager | undefined)?.getSessionFile?.();\n const pm = loadMissionFromDisk(m.id);\n const pf = pm ? getFeatureById(pm, forked.id) : null;\n if (pm && pf) {\n pushSessionRef(pf, fsf ? `session:${fsf}` : undefined);\n appendHistory(pm, { event: \"feature_fork_session_created\", featureId: forked.id, note: reason, details: { sourceFeatureId: f.id, forkSessionFile: fsf, parentLeafId } });\n await saveMissionSafe(pm);\n }\n if (typeof fc.sendUserMessage === \"function\") await fc.sendUserMessage(kickoff);\n else fc.ui.notify(`🌿 Fork: ${forked.title}\\n\\n${kickoff}`, \"info\");\n },\n });\n if (!forkResult?.cancelled) return;\n }\n\n const manual = buildManualForkHandoff(m.title, f, forked, reason, parentLeafId, parentSessionFile);\n ctx.ui.notify(`${manual}\\n\\n${kickoff}`, forkResult?.cancelled ? \"warning\" : \"info\");\n}\n\nexport async function handleFork(reason: string, ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n const m = runtime.activeMission;\n if (!m) return ctx.ui.notify(\"No active feature. Forks can only be created from an active feature.\", \"warning\");\n if (ctx.hasUI) reason = (await ctx.ui.input(\"Alternative approach\", reason || \"Try a smaller/safer approach\")) || reason;\n await forkFeatureInternally(m, reason || \"Alternative approach\", {} as ExtensionAPI, ctx);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission dashboard\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleDashboard(ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n const m = runtime.activeMission;\n if (!m) return ctx.ui.notify(\"No active mission.\", \"warning\");\n if (!ctx.hasUI) { ctx.ui.notify(statusText(m), \"info\"); return; }\n\n let selected: string | null = null;\n const ui = ctx.ui as unknown as Record<string, unknown>;\n if (typeof ui.custom === \"function\") {\n await (ui.custom as Function)(missionControlOverlay(m, (fid) => { selected = fid; }), { overlay: true });\n }\n if (selected) {\n const f = getFeatureById(m, selected);\n if (f && m.activeFeatureId !== selected) {\n f.status = \"active\"; m.activeFeatureId = selected; m.activeMilestoneId = f.milestoneId; m.status = \"active\";\n autoBlockBlockedFeatures(m);\n appendHistory(m, { event: \"feature_active\", featureId: selected });\n await saveMissionSafe(m); updateFooter(ctx, m);\n ctx.ui.notify(`➡️ Activated: ${selected} — ${f.title}`, \"info\");\n } else if (f) {\n ctx.ui.notify(`Already active: ${selected} — ${f.title}`, \"info\");\n }\n }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission debug\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleDebug(id: string | undefined, ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n const m = id ? loadMissionFromDisk(id) : runtime.activeMission;\n if (!m) return ctx.ui.notify(\"No mission to debug.\", \"warning\");\n const history = readHistory(m.id).slice(-25);\n ctx.ui.setWidget(\"pi-mission-debug\", [\n `Mission: ${m.title}`, `Status: ${m.status}`, `Active: ${m.activeFeatureId ?? \"none\"}`,\n \"─\".repeat(80),\n ...history.map(h => `${new Date(h.ts * 1000).toISOString()} ${h.event} ${h.featureId ?? \"\"} ${h.note ?? \"\"}`),\n ]);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission metrics\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleMetrics(ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n const summary = calculateMetricsSummary();\n const sess = sessionMetrics.getMetricsSummary();\n if (summary.totalMissions === 0) return ctx.ui.notify(\"No missions. /mission new <title>.\", \"info\");\n\n ctx.ui.notify([\n \"📊 Mission Metrics Summary\", \"=\".repeat(40),\n `Total: ${summary.totalMissions}`,\n `Completed: ${summary.completedMissions}`,\n `Success: ${(summary.successRate * 100).toFixed(1)}%`,\n `Avg tokens: ${summary.averageTokensPerMission.toFixed(0)}`,\n `Avg features: ${summary.averageFeaturesPerMission.toFixed(1)}`,\n `Avg time: ${(summary.averageCompletionTimeMs / 1000 / 60).toFixed(1)} min`,\n \"\", \"📈 Session\", \"=\".repeat(40), sess,\n ].join(\"\\n\"), \"info\");\n\n const metricsFile = path.join(missionsRoot(), \"metrics-export.json\");\n try {\n await fs.promises.mkdir(missionsRoot(), { recursive: true });\n await fs.promises.writeFile(metricsFile, JSON.stringify(listMissions().map(computeMissionMetrics), null, 2), \"utf-8\");\n ctx.ui.notify(`📁 Exported: ${metricsFile}`, \"info\");\n } catch (e) {\n ctx.ui.notify(`Export failed: ${e instanceof Error ? e.message : String(e)}`, \"warning\");\n }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission history\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleHistory(\n filter: string | undefined,\n ctx: ExtensionCommandContext,\n runtime: RuntimeState,\n): Promise<void> {\n const m = runtime.activeMission;\n if (!m) return ctx.ui.notify(\"No active mission. /mission load <id> first.\", \"warning\");\n\n const allEntries = readHistory(m.id);\n if (!allEntries.length) return ctx.ui.notify(\"No history entries yet.\", \"info\");\n\n let entries = allEntries;\n let label = \"All events\";\n\n // Sub-filters: feature, event type, or feature-id\n if (filter) {\n const lf = filter.toLowerCase();\n if (getFeatureById(m, filter)) {\n entries = entries.filter(e => e.featureId === filter);\n label = `Feature ${filter}`;\n } else {\n // Try event type filter first, then full-text search\n const eventMatch = entries.filter(e => e.event === filter);\n if (eventMatch.length > 0) {\n entries = eventMatch;\n label = `Event: ${filter}`;\n } else {\n // Full-text search in note and event fields\n entries = entries.filter(e =>\n e.event.includes(lf) || (e.note ?? \"\").toLowerCase().includes(lf) ||\n (e.featureId ?? \"\").toLowerCase().includes(lf),\n );\n label = `Search: \"${filter.slice(0, 40)}\"`;\n }\n }\n if (!entries.length) return ctx.ui.notify(`No history entries matching \"${filter}\".`, \"info\");\n }\n\n const recent = entries.slice(-40);\n const features = new Set(recent.map(e => e.featureId).filter(Boolean));\n const eventTypes = new Set(recent.map(e => e.event));\n\n const lines = [\n `📜 Mission History — ${label} (${recent.length} of ${entries.length} entries)`,\n `Features: ${[...features].join(\", \") || \"none\"}`,\n `Event types: ${[...eventTypes].join(\", \")}`,\n \"─\".repeat(80),\n ];\n\n // Compact table: timestamp event feature note\n for (const h of recent) {\n const ts = new Date(h.ts * 1000).toISOString().replace(\"T\", \" \").slice(0, 19);\n const evt = h.event.padEnd(24);\n const fid = (h.featureId ?? \"\").padEnd(8);\n const note = (h.note ?? \"\").slice(0, 60);\n lines.push(`${ts} ${evt} ${fid} ${note}`);\n }\n\n lines.push(\n \"─\".repeat(80),\n \"Filters: /mission history [feature_id|event_type|search_term]\",\n `Full log: ~/.pi/missions/${m.id}/history.jsonl`,\n \"jq replay: jq -r '.event + \\\" \\\" + (.featureId // \\\"\\\")' ~/.pi/missions/<id>/history.jsonl\",\n );\n\n ctx.ui.notify(lines.join(\"\\n\"), \"info\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission export\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleExport(filename: string | undefined, ctx: ExtensionCommandContext, runtime: RuntimeState): Promise<void> {\n const m = runtime.activeMission;\n if (!m) return ctx.ui.notify(\"No active mission.\", \"warning\");\n try {\n const md = exportMarkdown(m);\n if (filename) {\n await fs.promises.writeFile(filename, md, \"utf-8\");\n ctx.ui.notify(`✅ Exported to ${filename}`, \"info\");\n } else {\n ctx.ui.notify(md, \"info\");\n }\n } catch (e) {\n ctx.ui.notify(`Export failed: ${e instanceof Error ? e.message : String(e)}`, \"warning\");\n }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission worker / /mission worker-status / /mission kill-worker\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleWorker(\n featureId: string | undefined,\n ctx: ExtensionCommandContext,\n runtime: RuntimeState,\n): Promise<void> {\n const m = runtime.activeMission;\n if (!m) return ctx.ui.notify(\"No active mission.\", \"warning\");\n\n const fid = featureId || m.activeFeatureId;\n if (!fid) return ctx.ui.notify(\"No feature specified and no active feature.\", \"warning\");\n\n const f = getFeatureById(m, fid);\n if (!f) return ctx.ui.notify(`Feature not found: ${fid}`, \"error\");\n\n if (isWorkerRunning()) {\n const aw = getActiveWorker();\n const elapsed = aw ? Math.round((Date.now() - aw.startedAt) / 1000) : 0;\n return ctx.ui.notify(`Worker already running for ${aw?.featureId} (${elapsed}s). Use /mission worker-status.`, \"warning\");\n }\n\n // Mark feature active\n f.status = \"active\";\n m.activeFeatureId = f.id;\n m.activeMilestoneId = f.milestoneId;\n m.status = \"active\";\n\n appendHistory(m, {\n event: \"worker_spawned\",\n featureId: f.id,\n note: `Worker spawned for ${f.id} — ${f.title}`,\n });\n\n await saveMissionSafe(m);\n\n ctx.ui.notify(`🚀 Worker spawned for ${f.id} — ${f.title}. Check /mission worker-status for progress.`, \"info\");\n\n // Fire-and-forget: spawn async, report result when done\n spawnWorker(m, { featureId: f.id }).then((result) => {\n if (\"error\" in result) {\n ctx.ui.notify(`❌ Worker error: ${result.error}`, \"error\");\n return;\n }\n // Type assertion is redundant as TypeScript automatically narrows\n // 'result' to WorkerResult after the 'in' operator check above.\n const r = result;\n const duration = Math.round(r.durationMs / 1000);\n const statusIcon = r.killed ? \"⏱️\" : r.exitCode === 0 ? \"✅\" : \"❌\";\n const lines = [\n `${statusIcon} Worker finished for ${r.featureId}`,\n `Exit: ${r.exitCode}${r.signal ? ` (${r.signal})` : \"\"} | Duration: ${duration}s`,\n ];\n const outSummary = r.stdout.slice(-1500);\n if (outSummary) lines.push(\"\", \"── Output (last 1500 chars) ──\", outSummary);\n ctx.ui.notify(lines.join(\"\\n\"), \"info\");\n }).catch((err: unknown) => {\n ctx.ui.notify(`❌ Worker failed: ${err instanceof Error ? err.message : String(err)}`, \"error\");\n });\n}\n\nexport async function handleWorkerStatus(ctx: ExtensionCommandContext): Promise<void> {\n const aw = getActiveWorker();\n if (!aw) return ctx.ui.notify(\"No worker running.\", \"info\");\n\n const elapsed = Math.round((Date.now() - aw.startedAt) / 1000);\n const lines = [\n `🔧 Worker Status`,\n `Feature: ${aw.featureId}`,\n `Status: ${aw.status}`,\n `Running: ${elapsed}s`,\n ];\n\n if (aw.result) {\n lines.push(\n \"\", \"Last Result:\",\n `Exit: ${aw.result.exitCode}${aw.result.signal ? ` (${aw.result.signal})` : \"\"}`,\n `Duration: ${Math.round(aw.result.durationMs / 1000)}s`,\n );\n }\n\n ctx.ui.notify(lines.join(\"\\n\"), \"info\");\n}\n\nexport async function handleKillWorker(ctx: ExtensionCommandContext): Promise<void> {\n const killed = killWorker();\n if (!killed) return ctx.ui.notify(\"No worker running to kill.\", \"info\");\n ctx.ui.notify(\"🛑 Worker killed.\", \"info\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// /mission migrate — schema migration\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function handleMigrate(\n id: string | undefined,\n ctx: ExtensionCommandContext,\n runtime: RuntimeState,\n): Promise<void> {\n // List all missions and their schema versions\n if (!id) {\n const missions = listMissions();\n if (!missions.length) return ctx.ui.notify(\"No missions found.\", \"info\");\n\n const lines = [\"📋 Mission Schema Versions\", \"=\".repeat(60)];\n let needsMigration = 0;\n for (const m of missions) {\n const rawVersion = readRawSchemaVersion(m.id);\n const versionStr = rawVersion !== null ? `v${rawVersion}` : \"?\";\n const status = rawVersion === SCHEMA_VERSION ? \"✅\" : rawVersion !== null ? \"⬆️\" : \"❓\";\n if (rawVersion !== null && rawVersion < SCHEMA_VERSION) needsMigration++;\n lines.push(`${status} ${m.id.padEnd(28)} ${versionStr.padEnd(6)} ${m.title.slice(0, 30)}`);\n }\n lines.push(\n \"=\".repeat(60),\n `Current schema: v${SCHEMA_VERSION}`,\n needsMigration > 0\n ? `${needsMigration} mission(s) need migration. Use /mission migrate <id> to migrate.`\n : \"All missions up to date.\",\n );\n ctx.ui.notify(lines.join(\"\\n\"), \"info\");\n return;\n }\n\n // Migrate a specific mission\n const rawVersion = readRawSchemaVersion(id);\n if (rawVersion === null) return ctx.ui.notify(`Mission not found: ${id}`, \"error\");\n if (rawVersion >= SCHEMA_VERSION) {\n return ctx.ui.notify(`Mission ${id} already at v${rawVersion} (current: v${SCHEMA_VERSION}). No migration needed.`, \"info\");\n }\n\n // Show preview — use raw counts for accuracy (loadMissionFromDisk migrates in-memory)\n const rawCounts = readRawMissionCounts(id);\n const current = loadMissionFromDisk(id);\n if (!current) return ctx.ui.notify(`Could not load mission ${id}.`, \"error\");\n\n const featuresBefore = rawCounts?.features ?? current.milestones.reduce((s, m) => s + m.features.length, 0);\n const milestonesBefore = rawCounts?.milestones ?? current.milestones.length;\n const preview = [\n `⬆️ Migration preview for ${id}`,\n \"=\".repeat(60),\n `Title: ${current.title}`,\n `Schema: v${rawVersion} → v${SCHEMA_VERSION}`,\n `Status: ${current.status}`,\n `Milestones: ${milestonesBefore}`,\n `Features: ${featuresBefore}`,\n \"=\".repeat(60),\n \"\",\n \"Migration will:\",\n \"- Set schemaVersion to v3\",\n rawVersion <= 1 ? \"- Wrap flat features into a milestone if needed\" : null,\n rawVersion <= 2 ? \"- Add default autopilot settings\" : null,\n \"- Create a pre-migration backup\",\n \"\",\n `Run /mission migrate ${id} confirm to proceed.`,\n ].filter(Boolean).join(\"\\n\");\n\n ctx.ui.notify(preview, \"info\");\n}\n\nexport async function handleMigrateConfirm(\n id: string | undefined,\n ctx: ExtensionCommandContext,\n runtime: RuntimeState,\n): Promise<void> {\n if (!id) return ctx.ui.notify(\"Usage: /mission migrate <id> confirm\", \"warning\");\n\n const rawVersion = readRawSchemaVersion(id);\n if (rawVersion === null) return ctx.ui.notify(`Mission not found: ${id}`, \"error\");\n if (rawVersion >= SCHEMA_VERSION) {\n return ctx.ui.notify(`Already at v${rawVersion}. No migration needed.`, \"info\");\n }\n\n const migrated = await migrateMissionOnDisk(id);\n if (!migrated) return ctx.ui.notify(`Migration failed for ${id}.`, \"error\");\n\n // If this is the active mission, update runtime\n if (runtime.activeMission && runtime.activeMission.id === id) {\n runtime.activeMission = migrated;\n }\n\n const fc = migrated.milestones.reduce((s, m) => s + m.features.length, 0);\n ctx.ui.notify(\n `✅ Migrated ${id} from v${rawVersion} to v${SCHEMA_VERSION}.\\n` +\n `Milestones: ${migrated.milestones.length}, Features: ${fc}\\n` +\n `Backup saved to ~/.pi/missions/${id}/plan.json.pre-migration-*.bak`,\n \"info\",\n );\n}\n","import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport type { Feature, MissionState, Milestone } from \"../core/types.js\";\nimport { getActiveFeature, getAllFeatures, getMissionPhase, getNextPendingFeature, progress } from \"../core/state.js\";\nimport {\n acceptanceProgress, buildMissionBanner, buildMissionHelp,\n clip, dependsOnChain, featureStatusIcon, formatDepChain, missionStatusIcon, pendingAcceptance, progressBar,\n} from \"../utils/context.js\";\n\nfunction phaseLine(phase: string): string {\n switch (phase) {\n case \"planning\": return \"🔍 Phase: planning — explore, read, clarify. Avoid writes. Read-only bash.\";\n case \"verification\": return \"✅ Phase: verification — run checks, capture evidence, report exact gaps.\";\n default: return \"🔧 Phase: execution — smallest change that satisfies acceptance criteria.\";\n }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Mission Control Summary\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface MissionControlSummary {\n active: Feature | null;\n nextFeature: Feature | null;\n blocked: Feature[];\n waiting: Feature[];\n handoff: string;\n}\n\nfunction milestoneProgressBar(milestone: Milestone, width = 20): string {\n const done = milestone.features.filter(f => f.status === \"done\").length;\n return progressBar(done, milestone.features.length, width);\n}\n\nfunction milestoneProgressBarSimple(done: number, total: number, width = 16): string {\n return progressBar(done, total, width);\n}\n\nfunction tokenBudgetBar(used: number, budget: number | undefined, width = 20): string {\n if (!budget || budget <= 0) return `${used.toLocaleString()} tokens`;\n const ratio = Math.min(1, used / budget);\n const filled = Math.round(ratio * width);\n const bar = `[${\"█\".repeat(filled)}${\"░\".repeat(width - filled)}]`;\n const pct = Math.round(ratio * 100);\n return `${bar} ${used.toLocaleString()}/${budget.toLocaleString()} (${pct}%)`;\n}\n\nfunction deriveNextAction(feature: Feature): string {\n if (feature.status === \"blocked\") {\n return feature.notes ? `Unblock ${feature.id}: ${clip(feature.notes, 72)}` : `Unblock ${feature.id} before continuing`;\n }\n if (feature.status === \"waiting\") {\n return feature.dependsOn.length\n ? `Wait for ${feature.dependsOn.join(\", \")} before resuming ${feature.id}`\n : `Resume ${feature.id} when external dependency clears`;\n }\n const next = pendingAcceptance(feature, \"->\")[0];\n if (next) return `Finish ${feature.id}: ${clip(next, 72)}`;\n return `Advance ${feature.id}: ${clip(feature.description || feature.title, 72)}`;\n}\n\nfunction deriveHandoffSummary(mission: MissionState, active: Feature | null, next: Feature | null): string {\n const stop = mission.autopilot.lastStopReason;\n const msg = mission.autopilot.lastStopMessage;\n if (stop === \"needs_user_decision\" && msg) return `Needs user decision: ${clip(msg, 78)}`;\n if (stop === \"blocked\" && msg) return `Blocked: ${clip(msg, 78)}`;\n if (active?.notes) return `Carry over: ${clip(active.notes, 78)}`;\n if (next) return `After ${active?.id ?? \"current\"} hand off to ${next.id} ${clip(next.title, 52)}`;\n return \"Close out evidence and confirm mission state\";\n}\n\nexport function buildMissionControlSummary(mission: MissionState): MissionControlSummary {\n const active = getActiveFeature(mission);\n const blocked = getAllFeatures(mission).filter(f => f.status === \"blocked\");\n const waiting = getAllFeatures(mission).filter(f => f.status === \"waiting\");\n const nextFeature = getNextPendingFeature(mission);\n return { active, nextFeature, blocked, waiting, handoff: deriveHandoffSummary(mission, active, nextFeature) };\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Footer — compact single-line status\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function updateFooter(ctx: ExtensionCommandContext, mission: MissionState | null): void {\n if (!mission) {\n ctx.ui.setStatus(\"pi-mission\", \"\");\n return;\n }\n const p = progress(mission);\n const active = getActiveFeature(mission);\n const icon = missionStatusIcon(mission.status);\n const a = mission.autopilot;\n const ap = a.enabled\n ? ` · 🤖 ${a.iteration}/${a.maxIterations} np${a.noProgressTurns}/${a.maxNoProgressTurns} f${a.consecutiveFailures}/${a.maxConsecutiveFailures}`\n : \" · ⏹ off\";\n const line = active\n ? `${icon} ${mission.title} [${p.done}/${p.total} ${p.pct}%] — ${active.id} ${active.title}${ap}`\n : `${icon} ${mission.title} [${p.done}/${p.total} ${p.pct}%]${ap}`;\n ctx.ui.setStatus(\"pi-mission\", line);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Dashboard rows — string-based output for TUI and export\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function dashboardRows(mission: MissionState): string[] {\n const p = progress(mission);\n const icon = missionStatusIcon(mission.status);\n const s = buildMissionControlSummary(mission);\n const active = s.active;\n const nextAction = active\n ? deriveNextAction(active)\n : s.nextFeature ? `Start ${s.nextFeature.id}: ${clip(s.nextFeature.title, 68)}` : \"No runnable feature\";\n const acDone = active ? acceptanceProgress(active).done : 0;\n const acTotal = active?.acceptance.length ?? 0;\n const phase = getMissionPhase(mission);\n\n const rows: string[] = [\n \"\",\n ` ${icon} ${mission.title}`,\n ` Goal: ${clip(mission.goal || \"No goal\", 88)}`,\n ` Progress: ${progressBar(p.done, p.total)} ${p.done}/${p.total} — ${p.pct}%`,\n ` Focus: ${active ? `${active.id} [P${active.priority}] ${active.title}` : \"None\"}`,\n ` Feature progress: ${active ? `${acDone}/${acTotal} AC` : \"Waiting\"}`,\n ` Blocked/Waiting: ${s.blocked.length} blocked · ${s.waiting.length} waiting`,\n ` Next action: ${nextAction}`,\n ` Handoff: Carry over: ${s.handoff.startsWith(\"Carry over: \") ? s.handoff.slice(12) : s.handoff}`,\n ` Tokens: ${tokenBudgetBar(mission.tokensUsed, mission.tokensBudget)}`,\n ` Status: ${mission.status} | Autopilot: ${mission.autopilot.enabled ? \"ON\" : \"OFF\"} (${mission.autopilot.mode})`,\n \" \" + \"─\".repeat(76),\n ` ${phaseLine(phase)}`,\n \"\",\n ];\n\n if (s.blocked.length) {\n for (const f of s.blocked.slice(0, 2)) rows.push(` ⛔ Blocked: ${f.id} ${f.title} — ${clip(f.notes ?? \"No note\", 72)}`);\n if (s.blocked.length > 2) rows.push(` ⛔ +${s.blocked.length - 2} more`);\n rows.push(\"\");\n }\n if (s.waiting.length) {\n for (const f of s.waiting.slice(0, 3)) {\n const chain = dependsOnChain(mission, f);\n const chainStr = chain.length ? ` ${formatDepChain(chain)}` : \"\";\n const reason = f.dependsOn.length ? `waiting on ${f.dependsOn.join(\", \")}` : (f.notes ?? \"waiting\");\n rows.push(` ⏳ Waiting: ${f.id} ${f.title} — ${clip(reason, 60)}${chainStr}`);\n }\n if (s.waiting.length > 3) rows.push(` ⏳ +${s.waiting.length - 3} more waiting features`);\n rows.push(\"\");\n }\n\n // ── Milestone list: collapse done milestones (show last 2 done fully, rest as single line) ──\n const doneMilestones = mission.milestones.filter(m => m.status === \"complete\" && m.features.every(f => f.status === \"done\"));\n const undoneMilestones = mission.milestones.filter(m => m.status !== \"complete\" || !m.features.every(f => f.status === \"done\"));\n\n // Show all non-done + active milestones fully\n for (const m of undoneMilestones) {\n const mDone = m.features.filter(f => f.status === \"done\").length;\n const mTotal = m.features.length;\n const mi = m.status === \"active\" ? \"➡️\" : m.status === \"complete\" ? \"✅\" : \"•\";\n rows.push(` ${mi} ${m.id}: ${m.title} ${milestoneProgressBar(m, 24)} ${mDone}/${mTotal}`);\n\n const order: Record<string, number> = { active: 0, pending: 1, waiting: 2, blocked: 3, failed: 4, done: 5 };\n const sorted = [...m.features].sort((a, b) => (order[a.status] ?? 5) - (order[b.status] ?? 5) || a.priority - b.priority);\n\n for (const f of sorted) {\n const fi = featureStatusIcon(f.status);\n const deps = f.dependsOn.length ? ` 🔗${f.dependsOn.join(\",\")}` : \"\";\n const blocked = f.status === \"blocked\" && f.notes ? ` — ${clip(f.notes, 50)}` : \"\";\n const failed = f.status === \"failed\" ? \" ✗\" : \"\";\n const ac = acceptanceProgress(f);\n const badge = f.acceptance.length ? ` [${ac.label}]` : \"\";\n\n if (f.status === \"active\") {\n rows.push(` ▶ ${fi} ${f.id} [P${f.priority}] ${f.title}${badge}${deps}`);\n if (f.description) rows.push(` ${clip(f.description, 72)}`);\n const chain = dependsOnChain(mission, f);\n if (chain.length) rows.push(` 🔗 ${formatDepChain(chain)}`);\n for (const a of pendingAcceptance(f, \"->\")) rows.push(` ☐ ${clip(a, 68)}`);\n if (f.startedAt && Date.now() - f.startedAt > 600_000) {\n rows.push(` ⏱ Active ${Math.round((Date.now() - f.startedAt) / 60000)}min`);\n }\n if (f.toolCallCount > 50) rows.push(` 🔧 ${f.toolCallCount} tool calls`);\n rows.push(` 👉 ${deriveNextAction(f)}`);\n rows.push(` 🤝 ${s.handoff}`);\n } else {\n rows.push(` ${fi} ${f.id} [P${f.priority}] ${f.title}${badge}${deps}${blocked}${failed}`);\n }\n }\n rows.push(\"\");\n }\n\n // Collapse done milestones: show count + last 2 with full summary\n if (doneMilestones.length > 0) {\n const showFull = doneMilestones.slice(-2); // last 2 done milestones shown fully\n const collapsed = doneMilestones.slice(0, -2); // rest shown as single line\n if (showFull.length > 1) {\n // Multiple done milestones: show collapsed header, last 2 with progress bar\n rows.push(` ✅ ${doneMilestones.length} completed milestones (collapsed)`);\n for (const m of showFull) {\n const mDone = m.features.filter(f => f.status === \"done\").length;\n const mTotal = m.features.length;\n rows.push(` ${milestoneProgressBarSimple(mDone, mTotal, 16)} ${m.id}: ${m.title} [${mDone}/${mTotal}]`);\n }\n if (collapsed.length > 0) {\n rows.push(` +${collapsed.length} earlier milestone(s): ${collapsed.map(m => m.id).join(\", \")}`);\n }\n } else {\n // Single done milestone: use original format \"✅ M01: ... — all X features done\"\n const m = showFull[0]!;\n const mTotal = m.features.length;\n rows.push(` ✅ ${m.id}: ${m.title} — all ${mTotal} features done`);\n }\n rows.push(\"\");\n }\n\n rows.push(\" \" + \"─\".repeat(76));\n rows.push(\" /mission run | pause | resume | stop | autopilot | next | done | block | status | dashboard\");\n rows.push(\"\");\n return rows;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Status text — plain text overview for non-UI contexts\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function statusText(mission: MissionState): string {\n const p = progress(mission);\n const s = buildMissionControlSummary(mission);\n const active = s.active;\n const lines = [\n `🎯 Mission: ${mission.title}`,\n `ID: ${mission.id}`,\n `Status: ${mission.status}`,\n `Goal: ${mission.goal}`,\n `Progress: ${p.done}/${p.total} (${p.pct}%)`,\n active ? `Active: ${active.id} — ${active.title}` : \"Active: none\",\n `Blocked/Waiting: ${s.blocked.length}/${s.waiting.length}`,\n `Next action: ${active ? deriveNextAction(active) : s.nextFeature ? `Start ${s.nextFeature.id} — ${s.nextFeature.title}` : \"None\"}`,\n `Handoff: ${s.handoff}`,\n `Autopilot: ${mission.autopilot.enabled ? \"ON\" : \"OFF\"} (${mission.autopilot.mode})`,\n `Iteration: ${mission.autopilot.iteration}/${mission.autopilot.maxIterations}`,\n `Failures: ${mission.autopilot.consecutiveFailures}/${mission.autopilot.maxConsecutiveFailures}`,\n `No-progress: ${mission.autopilot.noProgressTurns}/${mission.autopilot.maxNoProgressTurns}`,\n `Last continuation: ${mission.autopilot.lastContinuationAt ?? \"never\"}`,\n `Last stop: ${mission.autopilot.lastStopReason ?? \"none\"}${mission.autopilot.lastStopMessage ? ` - ${mission.autopilot.lastStopMessage}` : \"\"}`,\n \"\",\n ];\n for (const m of mission.milestones) {\n const mi = m.status === \"complete\" ? \"✅\" : m.status === \"active\" ? \"➡️\" : \"•\";\n const mDone = m.features.filter(f => f.status === \"done\").length;\n lines.push(`${mi} ${m.id}: ${m.title} [${mDone}/${m.features.length}]`);\n for (const f of m.features) {\n const mark = featureStatusIcon(f.status);\n const blocked = f.status === \"blocked\" && f.notes ? ` — ${f.notes.slice(0, 50)}` : \"\";\n lines.push(` ${mark} ${f.id}: ${f.title} (${f.status})${blocked}`);\n }\n }\n return lines.join(\"\\n\");\n}\n","import type { SessionMetrics } from \"../core/types.js\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Session Metrics Collector\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport class SessionMetricsCollector {\n private metrics: SessionMetrics;\n private static instance: SessionMetricsCollector | null = null;\n\n private constructor() {\n this.metrics = this.freshMetrics();\n }\n\n static reset(): void {\n SessionMetricsCollector.instance = null;\n }\n\n private static get(): SessionMetricsCollector {\n if (!SessionMetricsCollector.instance) {\n SessionMetricsCollector.instance = new SessionMetricsCollector();\n }\n return SessionMetricsCollector.instance;\n }\n\n private freshMetrics(): SessionMetrics {\n return {\n sessionId: `session-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n startTime: Date.now(),\n toolCalls: { total: 0, byTool: {}, successful: 0, failed: 0 },\n tokensUsed: 0,\n featuresCompleted: 0,\n errors: { total: 0, byCategory: {} },\n autoAdvanceCount: 0,\n stuckDetectionCount: 0,\n };\n }\n\n // ── Public API ────────────────────────────────────────────────────────\n\n static getInstance(): SessionMetricsCollector {\n if (!SessionMetricsCollector.instance) {\n SessionMetricsCollector.instance = new SessionMetricsCollector();\n }\n return SessionMetricsCollector.instance;\n }\n\n // Instance methods (delegate to static)\n recordToolCall(tool: string, success: boolean): void {\n SessionMetricsCollector.recordToolCall(tool, success);\n }\n recordTokenUsage(tokens: number): void {\n SessionMetricsCollector.addTokens(tokens);\n }\n recordFeatureCompleted(): void {\n SessionMetricsCollector.recordFeatureCompleted();\n }\n recordError(category: string): void {\n SessionMetricsCollector.recordError(category);\n }\n recordAutoAdvance(): void {\n SessionMetricsCollector.recordAutoAdvance();\n }\n recordStuckDetection(): void {\n SessionMetricsCollector.recordStuckDetection();\n }\n endSession(): void {\n SessionMetricsCollector.endSession();\n }\n reset(): void {\n SessionMetricsCollector.reset();\n }\n getMetrics() {\n return SessionMetricsCollector.getMetrics();\n }\n getMetricsSummary(): string {\n return SessionMetricsCollector.getMetricsSummary();\n }\n exportMetrics(): string {\n return JSON.stringify(SessionMetricsCollector.getMetrics());\n }\n\n static recordToolCall(tool: string, success: boolean): void {\n const s = SessionMetricsCollector.get();\n s.metrics.toolCalls.total++;\n s.metrics.toolCalls.byTool[tool] = (s.metrics.toolCalls.byTool[tool] ?? 0) + 1;\n if (success) s.metrics.toolCalls.successful++;\n else s.metrics.toolCalls.failed++;\n }\n\n static recordError(category: string): void {\n const s = SessionMetricsCollector.get();\n s.metrics.errors.total++;\n s.metrics.errors.byCategory[category] = (s.metrics.errors.byCategory[category] ?? 0) + 1;\n }\n\n static recordFeatureCompleted(): void {\n SessionMetricsCollector.get().metrics.featuresCompleted++;\n }\n\n static recordAutoAdvance(): void {\n SessionMetricsCollector.get().metrics.autoAdvanceCount++;\n }\n\n static recordStuckDetection(): void {\n SessionMetricsCollector.get().metrics.stuckDetectionCount++;\n }\n\n static addTokens(count: number): void {\n SessionMetricsCollector.get().metrics.tokensUsed += count;\n }\n\n static endSession(): void {\n const s = SessionMetricsCollector.get();\n s.metrics.endTime = Date.now();\n }\n\n static getMetrics(): SessionMetrics {\n return { ...SessionMetricsCollector.get().metrics };\n }\n\n static getMetricsSummary(): string {\n const m = SessionMetricsCollector.get().metrics;\n const duration = m.endTime ? (m.endTime - m.startTime) / 1000 : (Date.now() - m.startTime) / 1000;\n const successRate = m.toolCalls.total === 0 ? 100 : (m.toolCalls.successful / m.toolCalls.total) * 100;\n return [\n `Session: ${m.sessionId}`,\n `Duration: ${duration.toFixed(1)}s`,\n `Tool Calls: ${m.toolCalls.total} (${successRate.toFixed(1)}% success)`,\n `Features Completed: ${m.featuresCompleted}`,\n `Auto-Advances: ${m.autoAdvanceCount}`,\n `Stuck Detections: ${m.stuckDetectionCount}`,\n `Errors: ${m.errors.total}`,\n `Tokens Used: ${m.tokensUsed}`,\n ].join(\"\\n\");\n }\n}\n\n// Shorthand alias — singleton instance (backward compat)\nexport const sessionMetrics = SessionMetricsCollector.getInstance();\n","import type { Component, TUI } from \"@earendil-works/pi-tui\";\nimport type { Feature, MissionState } from \"../core/types.js\";\nimport { getFeatureById, progress } from \"../core/state.js\";\nimport { acceptanceProgress, clip, dependsOnChain, featureStatusIcon, formatDepChain, missionStatusIcon, pendingAcceptance, progressBar } from \"../utils/context.js\";\nimport { sessionMetrics } from \"../engines/metrics.js\";\nimport { buildMissionControlSummary, updateFooter } from \"./components.js\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Feature label/description for the picker\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function featureNextAction(feature: Feature): string {\n if (feature.status === \"blocked\") return feature.notes ? `Unblock: ${clip(feature.notes)}` : \"Unblock before continuing\";\n if (feature.status === \"waiting\") return feature.dependsOn.length ? `Wait for ${feature.dependsOn.join(\", \")}` : \"Wait for external dependency\";\n const next = pendingAcceptance(feature)[0];\n if (next) return `Finish: ${clip(next)}`;\n return `Advance: ${clip(feature.description || feature.title)}`;\n}\n\nexport function featureLabel(f: Feature): string {\n const ac = acceptanceProgress(f);\n const badge = f.acceptance.length ? ` [${ac.label} AC]` : \"\";\n return `${featureStatusIcon(f.status)} ${f.id} [P${f.priority}] ${f.title}${badge}`;\n}\n\nexport function featureDescription(f: Feature, milestoneId: string): string {\n const deps = f.dependsOn.length ? ` 🔗${f.dependsOn.join(\",\")}` : \"\";\n return `${milestoneId}: ${f.description.slice(0, 70)}${deps}`;\n}\n\nexport function buildFeatureItems(mission: MissionState): Array<{ value: string; label: string; description: string }> {\n let len = 1;\n for (const m of mission.milestones) {\n len += m.features.length;\n }\n const items = new Array(len);\n items[0] = {\n value: \"__session_metrics__\", label: \"📊 Session Metrics\", description: \"View current session performance metrics\",\n };\n let idx = 1;\n for (const m of mission.milestones) {\n for (const f of m.features) {\n items[idx++] = { value: f.id, label: featureLabel(f), description: featureDescription(f, m.id) };\n }\n }\n return items;\n}\n\nexport function sessionMetricsLines(width: number): string[] {\n const m = sessionMetrics.getMetrics();\n const barW = Math.min(width - 4, 72);\n const bar = \"─\".repeat(barW > 0 ? barW : 40);\n const duration = m.endTime ? (m.endTime - m.startTime) / 1000 : (Date.now() - m.startTime) / 1000;\n const successRate = m.toolCalls.total === 0 ? 100 : (m.toolCalls.successful / m.toolCalls.total) * 100;\n const lines = [bar, \" 📊 Session Metrics\"];\n lines.push(` Session: ${m.sessionId}`);\n lines.push(` Health: ${m.errors.total === 0 ? \"clean\" : `${m.errors.total} errors`} | Tool success: ${successRate.toFixed(1)}%`);\n lines.push(` Throughput: ${m.featuresCompleted} features | ${m.toolCalls.total} tool calls | ${m.tokensUsed} tokens`);\n lines.push(` Duration: ${duration.toFixed(1)}s | Auto-advances: ${m.autoAdvanceCount} | Stuck: ${m.stuckDetectionCount}`);\n if (m.errors.total > 0) {\n lines.push(\" Error categories:\");\n for (const [cat, count] of Object.entries(m.errors.byCategory)) lines.push(` - ${cat}: ${count}`);\n }\n lines.push(bar);\n return lines;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Feature detail lines — used by dashboard views and tests\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function featureDetailLines(feature: Feature, width: number): string[] {\n const bar = \"─\".repeat(Math.min(width - 2, 78));\n const ac = acceptanceProgress(feature);\n\n\n const lines: string[] = [bar];\n\n lines.push(`📋 ${feature.id} — ${feature.title}`);\n lines.push(` Status: ${feature.status} Priority: P${feature.priority} Milestone: ${feature.milestoneId}`);\n\n const pending = pendingAcceptance(feature, \"→\");\n const nextAction = pending[0] ? `Finish: ${clip(pending[0], 72)}` : `Advance: ${clip(feature.description || feature.title, 72)}`;\n lines.push(`🎯 Next action: ${nextAction}`);\n lines.push(`📈 Acceptance progress: ${ac.done}/${feature.acceptance.length}`);\n\n if (feature.description) lines.push(`📝 ${clip(feature.description, 72)}`);\n if (feature.dependsOn.length) lines.push(`🔗 Depends on: ${feature.dependsOn.join(\", \")}`);\n if (feature.notes) lines.push(`📌 Note: ${clip(feature.notes, 72)}`);\n\n if (feature.acceptance.length) {\n lines.push(\"✅ Acceptance criteria\");\n for (const a of feature.acceptance) {\n const done = a.verified || a.waived;\n const icon = done ? \"☑\" : \"☐\";\n let line = ` ${icon} ${a.id}: ${a.description}`;\n if (a.checkType === \"bash\" && a.checkCommand && !a.verified) line += ` → ${a.checkCommand}`;\n lines.push(line);\n }\n }\n\n lines.push(bar);\n return lines;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// MissionControl — interactive overlay component\n// ═══════════════════════════════════════════════════════════════════════════\n\nclass MissionControl implements Component {\n private mission: MissionState;\n private tui: TUI;\n private onAction?: (featureId: string) => void;\n private selectedIdx = 0;\n private flatItems: Array<{ value: string; label: string; description: string }> = [];\n private filter = \"\";\n private searchMode = false;\n private width = 80;\n\n constructor(mission: MissionState, tui: TUI, onAction?: (featureId: string) => void) {\n this.mission = mission;\n this.tui = tui;\n this.onAction = onAction;\n this.flatItems = buildFeatureItems(mission);\n }\n\n private visibleItems(): Array<{ value: string; label: string; description: string }> {\n if (!this.filter) return this.flatItems;\n const q = this.filter.toLowerCase();\n return this.flatItems.filter(\n item => item.value !== \"__session_metrics__\" && `${item.value} ${item.label} ${item.description}`.toLowerCase().includes(q),\n );\n }\n\n private clampSelection(): void {\n const visible = this.visibleItems();\n this.selectedIdx = Math.max(0, Math.min(this.selectedIdx, Math.max(visible.length - 1, 0)));\n }\n\n private renderDashboardLines(): string[] {\n const p = progress(this.mission);\n const s = buildMissionControlSummary(this.mission);\n const visible = this.visibleItems();\n const selectedValue = visible[this.selectedIdx]?.value;\n const icon = missionStatusIcon(this.mission.status);\n\n const lines: string[] = [\n `${icon} Mission Control — ${this.mission.title}`,\n ` Goal: ${clip(this.mission.goal || \"No goal\", 88)}`,\n ` Focus: ${s.active ? `${s.active.id} ${s.active.title}` : \"None\"} | Progress: ${p.done}/${p.total} (${p.pct}%)`,\n ` Blocked/Waiting: ${s.blocked.length}/${s.waiting.length} | Handoff: ${clip(s.handoff, 76)}`,\n ];\n if (s.active) lines.push(` Next: ${featureNextAction(s.active)}`);\n lines.push(this.filter ? ` Filter: ${this.filter} (${visible.length} features)` : \" / to search\", \"\");\n lines.push(\" Milestones \" + progressBar(p.done, p.total, 12) + ` ${p.done}/${p.total} (${p.pct}%)`, \"\");\n\n if (this.filter && visible.length === 0) {\n lines.push(` No matching features for \"${this.filter}\"`, \"\");\n }\n\n // Render Session Metrics as first selectable item\n const smItem = this.flatItems[0];\n if (smItem && smItem.value === \"__session_metrics__\" && !this.filter) {\n const smSel = smItem.value === selectedValue;\n const smPrefix = smSel ? \"→\" : \" \";\n lines.push(`${smPrefix} ${smItem.label}`, \"\");\n if (smSel) {\n lines.push(...sessionMetricsLines(this.width));\n lines.push(\"\");\n }\n }\n\n for (const m of this.mission.milestones) {\n const mDone = m.features.filter(f => f.status === \"done\").length;\n const mTotal = m.features.length;\n const msIcon = m.status === \"complete\" ? \"✅\" : m.status === \"active\" ? \"➡️\" : \"•\";\n const order: Record<string, number> = { active: 0, pending: 1, waiting: 2, blocked: 3, failed: 4, done: 5 };\n const sorted = [...m.features].sort((a, b) => (order[a.status] ?? 5) - (order[b.status] ?? 5) || a.priority - b.priority);\n const shown = this.filter ? sorted.filter(f => visible.some(v => v.value === f.id)) : sorted;\n if (!shown.length) continue;\n\n lines.push(` ${msIcon} ${m.id}: ${m.title} ${progressBar(mDone, mTotal, 12)} ${mDone}/${mTotal}`);\n for (const f of shown) {\n const sel = f.id === selectedValue;\n const prefix = sel ? \"→\" : \" \";\n const ac = acceptanceProgress(f);\n const badge = f.acceptance.length ? ` [${ac.label} AC]` : \"\";\n const deps = f.dependsOn.length ? ` 🔗${f.dependsOn.join(\",\")}` : \"\";\n lines.push(`${prefix} ${featureStatusIcon(f.status)} ${f.id} [P${f.priority}] ${f.title}${badge}${deps}`);\n\n if (sel || f.id === this.mission.activeFeatureId) {\n lines.push(` ${f.id}: ${f.title}`);\n if (f.description) lines.push(` ${clip(f.description, 88)}`);\n const chain = dependsOnChain(this.mission, f);\n if (chain.length) lines.push(` 🔗 Chain: ${formatDepChain(chain)}`);\n lines.push(` AC: ${ac.label}${f.dependsOn.length ? ` | deps: ${f.dependsOn.join(\", \")}` : \"\"}`);\n lines.push(` Next: ${featureNextAction(f)}`);\n for (const a of pendingAcceptance(f).slice(0, 4)) lines.push(` ☐ ${clip(a, 82)}`);\n if (f.startedAt && Date.now() - f.startedAt > 600_000) {\n lines.push(` Active ${Math.round((Date.now() - f.startedAt) / 60000)}min`);\n }\n if (f.toolCallCount > 50) lines.push(` ${f.toolCallCount} tool calls`);\n if (f.notes) lines.push(` Note: ${clip(f.notes, 82)}`);\n }\n }\n lines.push(\"\");\n }\n\n lines.push(\" Keys: ↑↓/j/k navigate | Enter select | / search | Backspace/Ctrl+U clear | Esc close\");\n return lines;\n }\n\n // ── Component interface ────────────────────────────────────────────────\n\n render(width: number): string[] {\n this.width = width;\n return this.renderDashboardLines();\n }\n\n invalidate(): void { /* stateless render */ }\n\n handleInput(data: string): boolean {\n if (data === \"/\") {\n this.searchMode = true; this.filter = \"\"; this.selectedIdx = 0;\n this.tui.requestRender(); return true;\n }\n if (this.searchMode && data.length === 1 && data.charCodeAt(0) >= 32 && data.charCodeAt(0) <= 126) {\n this.filter += data; this.selectedIdx = 0; this.clampSelection();\n this.tui.requestRender(); return true;\n }\n if (data === \"\\b\" || data === \"\\x7f\") {\n if (this.filter) { this.filter = this.filter.slice(0, -1); this.selectedIdx = 0; this.clampSelection(); }\n this.tui.requestRender(); return true;\n }\n if (data === \"\\x15\") { this.filter = \"\"; this.searchMode = false; this.selectedIdx = 0; this.tui.requestRender(); return true; }\n if (data === \"\\x1b[B\" || data === \"j\") {\n this.selectedIdx = Math.min(this.selectedIdx + 1, Math.max(this.visibleItems().length - 1, 0));\n this.tui.requestRender(); return true;\n }\n if (data === \"\\x1b[A\" || data === \"k\") {\n this.selectedIdx = Math.max(this.selectedIdx - 1, 0);\n this.tui.requestRender(); return true;\n }\n if (data === \"\\r\" || data === \"\\n\") {\n const item = this.visibleItems()[this.selectedIdx];\n if (item && item.value !== \"__session_metrics__\") { this.onAction?.(item.value); this.tui.hideOverlay(); }\n return true;\n }\n if (data === \"\\x1b\") {\n if (this.filter || this.searchMode) { this.filter = \"\"; this.searchMode = false; this.selectedIdx = 0; this.tui.requestRender(); return true; }\n this.tui.hideOverlay(); return true;\n }\n return false;\n }\n\n dispose(): void { /* no resources */ }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Factory\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function missionControlOverlay(\n mission: MissionState,\n onAction?: (featureId: string) => void,\n): (tui: TUI) => Component & { dispose(): void; invalidate(): void } {\n return (tui: TUI) => new MissionControl(mission, tui, onAction);\n}\n","import type {\n CompletionConfidence,\n CompletionDetectionResult,\n CompletionSignal,\n Feature,\n} from \"../core/types.js\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Completion Detection Engine\n// ═══════════════════════════════════════════════════════════════════════════\n\nconst MAX_RECENT_TOOLS = 20;\nconst MAX_RECENT_TEXTS = 10;\nconst ERROR_FREE_STREAK_THRESHOLD = 5;\nconst STUCK_FAILURE_THRESHOLD = 3;\nconst STUCK_REPEAT_PATTERN_THRESHOLD = 5;\nconst TEXT_LOOP_SIMILARITY_THRESHOLD = 4;\n\nexport class CompletionDetector {\n private recentToolCalls: Array<{ tool: string; success: boolean; timestamp: number }> = [];\n private recentTextOutputs: Array<{ hash: string; timestamp: number }> = [];\n\n recordToolCall(tool: string, success: boolean): void {\n this.recentToolCalls.push({ tool, success, timestamp: Date.now() });\n if (this.recentToolCalls.length > MAX_RECENT_TOOLS) this.recentToolCalls.shift();\n }\n\n recordTextOutput(text: string): void {\n if (!text || text.length < 20) return;\n const hash = text.slice(0, 100).toLowerCase().replace(/\\s+/g, \" \").trim();\n this.recentTextOutputs.push({ hash, timestamp: Date.now() });\n if (this.recentTextOutputs.length > MAX_RECENT_TEXTS) this.recentTextOutputs.shift();\n }\n\n clearToolCallHistory(): void {\n this.recentToolCalls = [];\n this.recentTextOutputs = [];\n }\n\n // ── Completion detection ────────────────────────────────────────────────\n\n detectCompletion(feature: Feature, agentText: string): CompletionDetectionResult {\n const signals: CompletionSignal[] = [];\n const now = Date.now();\n\n const kw = this.detectKeywordSignal(agentText, now);\n if (kw) signals.push(kw);\n\n const ac = this.detectAcceptanceSignal(feature, now);\n if (ac) signals.push(ac);\n\n const tp = this.detectToolPatternSignal(now);\n if (tp) signals.push(tp);\n\n const ef = this.detectErrorFreeStreakSignal(now);\n if (ef) signals.push(ef);\n\n return this.aggregateSignals(signals, feature);\n }\n\n private detectKeywordSignal(text: string, now: number): CompletionSignal | null {\n const lower = text.toLowerCase();\n const keywords = [\n \"done\", \"complete\", \"completed\", \"finished\", \"implemented\",\n \"klaar\", \"voltooid\", \"tests pass\", \"tests slagen\", \"success\",\n \"working\", \"functional\", \"ready\",\n ];\n const found = keywords.filter(kw => lower.includes(kw));\n if (found.length === 0) return null;\n const confidence: CompletionConfidence = found.length >= 2 ? \"high\" : \"medium\";\n return { type: \"keyword\", confidence, evidence: `Found completion keywords: ${found.join(\", \")}`, timestamp: now };\n }\n\n private detectAcceptanceSignal(feature: Feature, now: number): CompletionSignal | null {\n if (feature.acceptance.length === 0) return null;\n const verified = feature.acceptance.filter(ac => ac.verified).length;\n const waived = feature.acceptance.filter(ac => ac.waived).length;\n const satisfied = verified + waived;\n const total = feature.acceptance.length;\n const pct = (satisfied / total) * 100;\n if (pct === 100) {\n return { type: \"acceptance\", confidence: \"high\", evidence: `All ${total} acceptance criteria satisfied (${verified} verified, ${waived} waived)`, timestamp: now };\n }\n if (pct >= 75) {\n return { type: \"acceptance\", confidence: \"medium\", evidence: `${satisfied}/${total} criteria satisfied (${pct.toFixed(0)}%)`, timestamp: now };\n }\n return null;\n }\n\n private detectToolPatternSignal(now: number): CompletionSignal | null {\n if (this.recentToolCalls.length < 3) return null;\n const reads = this.recentToolCalls.filter(tc => tc.tool === \"read\").length;\n const pct = (reads / this.recentToolCalls.length) * 100;\n if (pct >= 70) {\n return { type: \"tool_pattern\", confidence: \"medium\", evidence: `${pct.toFixed(0)}% of recent ${this.recentToolCalls.length} tool calls were read operations`, timestamp: now };\n }\n return null;\n }\n\n private detectErrorFreeStreakSignal(now: number): CompletionSignal | null {\n if (this.recentToolCalls.length < ERROR_FREE_STREAK_THRESHOLD) return null;\n const recent = this.recentToolCalls.slice(-ERROR_FREE_STREAK_THRESHOLD);\n if (recent.every(tc => tc.success)) {\n return { type: \"error_free_streak\", confidence: \"medium\", evidence: `Last ${ERROR_FREE_STREAK_THRESHOLD} tool calls successful`, timestamp: now };\n }\n return null;\n }\n\n // ── Stuck detection ─────────────────────────────────────────────────────\n\n detectTextLoop(): { isStuck: boolean; reason: string; suggestedAction: \"continue\" | \"block_self\" } {\n if (this.recentTextOutputs.length < TEXT_LOOP_SIMILARITY_THRESHOLD) {\n return { isStuck: false, reason: \"Insufficient text history\", suggestedAction: \"continue\" };\n }\n const recent = this.recentTextOutputs.slice(-TEXT_LOOP_SIMILARITY_THRESHOLD);\n const unique = new Set(recent.map(t => t.hash));\n if (unique.size <= 2) {\n return { isStuck: true, reason: `Text loop: ${unique.size} unique outputs in last ${TEXT_LOOP_SIMILARITY_THRESHOLD} turns`, suggestedAction: \"block_self\" };\n }\n const stuckPhrases = [\n \"i've been stuck in a loop\", \"i need to ask the user directly\",\n \"actually, let me just provide a final summary\", \"operation aborted\",\n ];\n let count = 0;\n for (const t of recent) {\n if (stuckPhrases.some(p => t.hash.includes(p))) count++;\n }\n if (count >= 3) {\n return { isStuck: true, reason: `Stuck phrases in ${count}/${TEXT_LOOP_SIMILARITY_THRESHOLD} recent turns`, suggestedAction: \"block_self\" };\n }\n return { isStuck: false, reason: \"No text loop detected\", suggestedAction: \"continue\" };\n }\n\n detectStuck(): { isStuck: boolean; reason: string; suggestedAction: \"continue\" | \"block_self\" } {\n if (this.recentToolCalls.length < STUCK_FAILURE_THRESHOLD) {\n return { isStuck: false, reason: \"Insufficient tool call history\", suggestedAction: \"continue\" };\n }\n // Consecutive failures\n const recent = this.recentToolCalls.slice(-STUCK_FAILURE_THRESHOLD);\n if (recent.every(tc => !tc.success)) {\n return { isStuck: true, reason: `${STUCK_FAILURE_THRESHOLD} consecutive failures`, suggestedAction: \"block_self\" };\n }\n // Repeated tool pattern\n const last5 = this.recentToolCalls.slice(-STUCK_REPEAT_PATTERN_THRESHOLD);\n if (last5.length >= STUCK_REPEAT_PATTERN_THRESHOLD) {\n const uniqueTools = new Set(last5.map(tc => tc.tool));\n if (uniqueTools.size === 1) {\n return { isStuck: true, reason: `${STUCK_REPEAT_PATTERN_THRESHOLD} consecutive calls to '${last5[0].tool}'`, suggestedAction: \"block_self\" };\n }\n }\n // High failure rate\n const recent10 = this.recentToolCalls.slice(-10);\n if (recent10.length >= 5) {\n const failures = recent10.filter(tc => !tc.success).length;\n if (failures / recent10.length >= 0.7) {\n return { isStuck: true, reason: `High failure rate: ${failures}/${recent10.length} recent calls`, suggestedAction: \"block_self\" };\n }\n }\n return { isStuck: false, reason: \"No stuck pattern\", suggestedAction: \"continue\" };\n }\n\n // ── Aggregation ─────────────────────────────────────────────────────────\n\n private aggregateSignals(signals: CompletionSignal[], feature: Feature): CompletionDetectionResult {\n if (signals.length === 0) {\n return { isComplete: false, confidence: \"low\", signals: [], suggestedAction: \"continue\", reason: \"No completion signals\" };\n }\n const high = signals.filter(s => s.confidence === \"high\").length;\n const medium = signals.filter(s => s.confidence === \"medium\").length;\n let confidence: CompletionConfidence;\n if (high >= 2 || (high === 1 && medium >= 2)) confidence = \"high\";\n else if (high === 1 || medium >= 2) confidence = \"medium\";\n else confidence = \"low\";\n\n const acPct = feature.acceptance.length > 0\n ? (feature.acceptance.filter(ac => ac.verified || ac.waived).length / feature.acceptance.length) * 100\n : 0;\n\n let suggestedAction: CompletionDetectionResult[\"suggestedAction\"];\n let reason: string;\n if (confidence === \"high\" && acPct >= 100) {\n suggestedAction = \"auto_done\"; reason = \"High confidence, all acceptance criteria satisfied\";\n } else if (confidence === \"high\" && acPct >= 75) {\n suggestedAction = \"suggest_done\"; reason = \"High confidence but some acceptance unverified\";\n } else if (confidence === \"medium\" && acPct >= 100) {\n suggestedAction = \"suggest_done\"; reason = \"Medium confidence, all acceptance satisfied\";\n } else if (confidence === \"medium\") {\n suggestedAction = \"ask_user\"; reason = \"Medium confidence — ask user\";\n } else {\n suggestedAction = \"continue\"; reason = \"Low confidence — continue\";\n }\n return {\n isComplete: suggestedAction === \"auto_done\" || suggestedAction === \"suggest_done\",\n confidence, signals, suggestedAction, reason,\n };\n }\n}\n\n// Singleton\nlet globalDetector: CompletionDetector | null = null;\n\nexport function getCompletionDetector(): CompletionDetector {\n if (!globalDetector) globalDetector = new CompletionDetector();\n return globalDetector;\n}\n\nexport function resetCompletionDetector(): void {\n globalDetector = null;\n}\n","import type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport type { ContinuationDecision, Feature, MissionState, RuntimeState } from \"../core/types.js\";\nimport {\n appendHistory, autoUnblockResolved, getActiveFeature, getNextPendingFeature, saveMissionSafe,\n} from \"../core/state.js\";\nimport { updateFooter } from \"../ui/components.js\";\nimport { getCompletionDetector } from \"./completion.js\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Continuation decision\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function shouldContinue(mission: MissionState, ctx?: ExtensionCommandContext): ContinuationDecision {\n const a = mission.autopilot;\n if (!a.enabled) return { continue: false, reason: \"disabled\" };\n if (mission.status === \"paused\") return { continue: false, reason: \"paused_by_user\" };\n if (mission.status === \"blocked\") return { continue: false, reason: \"blocked\" };\n if (mission.status === \"complete\") return { continue: false, reason: \"mission_complete\" };\n if (a.iteration >= a.maxIterations) return { continue: false, reason: \"max_iterations\" };\n if (a.consecutiveFailures >= a.maxConsecutiveFailures) return { continue: false, reason: \"max_consecutive_failures\" };\n if (a.noProgressTurns >= a.maxNoProgressTurns) return { continue: false, reason: \"no_progress\" };\n const usage = ctx?.getContextUsage?.() ?? { percent: 0 };\n if ((usage.percent ?? 0) > a.maxContextPercent) return { continue: false, reason: \"context_limit\" };\n return { continue: true };\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Ensure active feature\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function ensureActiveFeature(mission: MissionState): Feature | null {\n let feature = getActiveFeature(mission);\n if (feature && feature.status === \"active\") return feature;\n autoUnblockResolved(mission);\n const next = getNextPendingFeature(mission);\n if (next) {\n next.status = \"active\";\n mission.activeFeatureId = next.id;\n mission.activeMilestoneId = next.milestoneId;\n appendHistory(mission, { event: \"feature_active\", featureId: next.id });\n return next;\n }\n if (mission.milestones.every(m => m.features.every(f => f.status === \"done\"))) {\n mission.status = \"complete\";\n mission.autopilot.enabled = false;\n mission.autopilot.lastStopReason = \"mission_complete\";\n }\n return null;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Trigger continuation\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function buildContinuationPrompt(mission: MissionState): string {\n const feature = getActiveFeature(mission) || { id: \"none\", title: \"no active feature\" };\n return [\n `Mission: ${mission.title}`,\n `Active feature: ${feature.id} - ${feature.title}`,\n `Autopilot iteration: ${mission.autopilot.iteration}`,\n \"\",\n \"Continue the mission with ONE controlled turn. After this turn the autopilot will evaluate progress and decide whether to continue or stop.\",\n \"Stop conditions: mission complete, user stop, blocker, max iterations, etc.\",\n ].join(\"\\n\");\n}\n\nexport async function triggerContinuation(\n pi: ExtensionAPI,\n ctx: ExtensionCommandContext,\n mission: MissionState,\n): Promise<void> {\n const decision = shouldContinue(mission, ctx);\n if (!decision.continue) {\n mission.autopilot.lastStopReason = decision.reason as MissionState[\"autopilot\"][\"lastStopReason\"];\n await saveMissionSafe(mission);\n updateFooter(ctx, mission);\n return;\n }\n mission.autopilot.iteration++;\n mission.autopilot.lastContinuationAt = new Date().toISOString();\n await pi.sendUserMessage(buildContinuationPrompt(mission));\n await saveMissionSafe(mission);\n updateFooter(ctx, mission);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Process agent end for autopilot\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function processAgentEndForAutopilot(\n pi: ExtensionAPI,\n ctx: ExtensionCommandContext,\n event: { messages?: Array<{ content?: Array<{ type?: string; text?: string }> | string }> },\n runtime: RuntimeState,\n): Promise<void> {\n const mission = runtime.activeMission;\n if (!mission?.autopilot?.enabled) return;\n const feature = getActiveFeature(mission);\n\n const text = (event.messages ?? [])\n .flatMap(m => Array.isArray(m.content) ? m.content : [])\n .filter(c => c?.type === \"text\" && typeof c.text === \"string\")\n .map(c => c.text)\n .join(\"\\n\");\n const lower = text.toLowerCase();\n\n const wasAborted = /\\b(operation aborted|operation cancelled|action cancelled)\\b/i.test(text);\n const detector = getCompletionDetector();\n const textLoop = detector.detectTextLoop();\n const inTextLoop = textLoop.isStuck;\n\n const wantsToAskUser = /\\b(need to ask the user|should ask the user|must ask the user)\\b/i.test(lower) &&\n !lower.includes(\"mission_ask_user\");\n\n const isBlocked =\n mission.status === \"blocked\" ||\n (feature && feature.status === \"blocked\") ||\n /\\b(blocked|block self|self-block|stuck|cannot proceed|deadlock|need external|api key|permission)\\b/i.test(lower);\n\n if (inTextLoop || wasAborted) {\n mission.autopilot.noProgressTurns += (inTextLoop ? 2 : 0) + (wasAborted ? 1 : 0);\n }\n\n if (wantsToAskUser) {\n mission.autopilot.enabled = false;\n mission.autopilot.lastStopReason = \"needs_user_decision\";\n mission.autopilot.lastStopMessage = text.slice(0, 200);\n appendHistory(mission, { event: \"autopilot_stopped\", note: \"needs_user_decision (model wants to ask)\" });\n await saveMissionSafe(mission);\n updateFooter(ctx, mission);\n return;\n }\n\n if (isBlocked) {\n mission.autopilot.enabled = false;\n mission.autopilot.lastStopReason = \"blocked\";\n mission.autopilot.lastStopMessage = text.slice(0, 200);\n if (feature) feature.status = \"blocked\";\n appendHistory(mission, { event: \"autopilot_stopped\", note: \"blocked\" });\n await saveMissionSafe(mission);\n updateFooter(ctx, mission);\n return;\n }\n\n const madeProgress = !lower.includes(\"no progress\") && !lower.includes(\"same state\");\n if (!madeProgress) mission.autopilot.noProgressTurns++;\n else mission.autopilot.noProgressTurns = Math.max(0, mission.autopilot.noProgressTurns - 1);\n\n const hasError = lower.includes(\"error\") || lower.includes(\"failed\");\n if (hasError) mission.autopilot.consecutiveFailures++;\n else mission.autopilot.consecutiveFailures = 0;\n\n const decision = shouldContinue(mission, ctx);\n if (decision.continue) {\n await triggerContinuation(pi, ctx, mission);\n } else {\n mission.autopilot.enabled = false;\n mission.autopilot.lastStopReason = decision.reason as MissionState[\"autopilot\"][\"lastStopReason\"];\n appendHistory(mission, { event: \"autopilot_stopped\", note: decision.reason });\n await saveMissionSafe(mission);\n updateFooter(ctx, mission);\n }\n}\n","import { spawn, type ChildProcess } from \"node:child_process\";\nimport type { Feature, MissionState } from \"../core/types.js\";\nimport { appendHistory, getFeatureById, saveMissionSafe } from \"../core/state.js\";\nimport { buildLeanContext } from \"../utils/context.js\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Worker configuration & result types\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface WorkerConfig {\n featureId: string;\n customPrompt?: string;\n model?: string;\n timeoutMs?: number;\n}\n\nexport interface WorkerResult {\n featureId: string;\n exitCode: number | null;\n signal: string | null;\n stdout: string;\n stderr: string;\n durationMs: number;\n killed: boolean;\n}\n\nexport type WorkerStatus = \"idle\" | \"running\" | \"done\" | \"error\" | \"timeout\";\n\nexport interface ActiveWorker {\n process: ChildProcess;\n featureId: string;\n startedAt: number;\n result?: WorkerResult;\n status: WorkerStatus;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Active worker tracking (one worker at a time)\n// ═══════════════════════════════════════════════════════════════════════════\n\nlet activeWorker: ActiveWorker | null = null;\n\nexport function getActiveWorker(): ActiveWorker | null {\n return activeWorker;\n}\n\nexport function isWorkerRunning(): boolean {\n return activeWorker?.status === \"running\";\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Extension path for worker processes\n// Set by extension.ts at startup via PI_MISSIONS_EXTENSION_PATH env var.\n// Workers inherit this and use it to load pi-missions in the child process.\n// ═══════════════════════════════════════════════════════════════════════════\n\nfunction getExtensionPath(): string | null {\n return process.env.PI_MISSIONS_EXTENSION_PATH || null;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Build worker prompt\n// ═══════════════════════════════════════════════════════════════════════════\n\nconst MAX_STDOUT_BYTES = 50_000;\nconst MAX_STDERR_BYTES = 25_000;\n\nexport function buildWorkerPrompt(\n mission: MissionState,\n feature: Feature,\n customPrompt?: string,\n): string {\n const context = buildLeanContext(mission);\n const lines = [\n context,\n \"\",\n `You are a worker agent executing a single feature in a software development mission.`,\n ``,\n `## First: Load the mission`,\n `Run: /mission load ${mission.id}`,\n ``,\n `3. Implement the smallest, most coherent change that satisfies the acceptance criteria`,\n `4. When ALL acceptance criteria are satisfied, call **mission_feature_done** with evidence`,\n `5. If you get stuck, call **mission_block_self** with a clear reason`,\n `6. If you need user input, call **mission_ask_user**`,\n `7. Do NOT move to the NEXT feature — just complete this one and stop`,\n ];\n\n if (customPrompt) {\n lines.push(\"\", \"## Additional Instructions\", customPrompt);\n }\n\n lines.push(\n \"\",\n \"## Output\",\n \"Provide a brief summary of what you accomplished, then call mission_feature_done with evidence.\",\n );\n\n return lines.join(\"\\n\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Spawn worker — returns a Promise that resolves when the worker exits\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function spawnWorker(\n mission: MissionState,\n config: WorkerConfig,\n): Promise<WorkerResult | { error: string }> {\n if (isWorkerRunning()) {\n const running = activeWorker;\n if (running) {\n return Promise.resolve({ error: `Worker already running for feature ${running.featureId}. Wait for it to finish.` });\n }\n }\n\n const feature = getFeatureById(mission, config.featureId);\n if (!feature) {\n return Promise.resolve({ error: `Feature not found: ${config.featureId}` });\n }\n\n const prompt = buildWorkerPrompt(mission, feature, config.customPrompt);\n const piPath = process.env.PI_PATH || \"pi\";\n const model = config.model || process.env.PI_WORKER_MODEL || \"auto\";\n const timeoutMs = config.timeoutMs ?? 600_000; // 10 min default\n\n const extPath = getExtensionPath();\n const args: string[] = [\"--model\", model];\n\n if (extPath) {\n args.push(\"-e\", extPath);\n }\n\n // pi takes messages as positional arguments; pass prompt directly\n args.push(prompt);\n\n const child = spawn(piPath, args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, PI_NO_COLOR: \"1\" },\n });\n\n let stdout = \"\";\n let stderr = \"\";\n let killed = false;\n\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n if (stdout.length < MAX_STDOUT_BYTES) {\n stdout += chunk.toString().slice(0, MAX_STDOUT_BYTES - stdout.length);\n }\n });\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n if (stderr.length < MAX_STDERR_BYTES) {\n stderr += chunk.toString().slice(0, MAX_STDERR_BYTES - stderr.length);\n }\n });\n\n const startedAt = Date.now();\n\n activeWorker = {\n process: child, featureId: config.featureId,\n startedAt, status: \"running\",\n };\n\n const timeout = setTimeout(() => {\n killed = true;\n if (activeWorker) activeWorker.status = \"timeout\";\n child.kill(\"SIGTERM\");\n setTimeout(() => { if (!child.killed) child.kill(\"SIGKILL\"); }, 5000);\n }, timeoutMs);\n\n return new Promise<WorkerResult | { error: string }>((resolve) => {\n child.on(\"close\", (code, signal) => {\n clearTimeout(timeout);\n const durationMs = Date.now() - startedAt;\n\n const result: WorkerResult = {\n featureId: config.featureId,\n exitCode: code, signal: signal ?? null,\n stdout, stderr, durationMs, killed,\n };\n\n if (activeWorker) {\n activeWorker.result = result;\n activeWorker.status = result.killed ? \"timeout\" : result.exitCode === 0 ? \"done\" : \"error\";\n }\n\n // Log worker result to history (best-effort, may race with mission reload)\n try {\n // Re-read mission from disk to avoid stale state\n const missionId = mission.id;\n appendHistory(mission, {\n event: \"worker_finished\",\n featureId: config.featureId,\n note: `Exit ${code}${signal ? ` (${signal})` : \"\"} in ${Math.round(durationMs / 1000)}s`,\n details: {\n exitCode: code, signal: signal ?? undefined,\n durationMs, killed, missionId,\n stdoutLen: stdout.length, stderrLen: stderr.length,\n model,\n },\n });\n saveMissionSafe(mission).catch(() => { /* best-effort */ });\n } catch { /* history is best-effort for workers */ }\n\n resolve(result);\n });\n\n child.on(\"error\", (err) => {\n clearTimeout(timeout);\n activeWorker = null;\n resolve({\n error: `Worker process error: ${err.message}`,\n } as { error: string });\n });\n });\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Kill active worker\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function killWorker(): boolean {\n if (!activeWorker || activeWorker.status !== \"running\") return false;\n activeWorker.process.kill(\"SIGTERM\");\n return true;\n}\n","import { Type } from \"@sinclair/typebox\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport type { Feature, ForkSessionManager, ForkReplacementContext, MissionContextSessionManager, MissionState, RuntimeState, ToolPhase } from \"../core/types.js\";\nimport { TOOL_POLICIES } from \"../core/types.js\";\nimport {\n activateNextFeature, appendHistory, autoUnblockResolved,\n completeActiveFeature, getActiveFeature, getFeatureById, getMilestoneById,\n getNextPendingFeature, loadMissionFromDisk, saveMissionSafe,\n} from \"../core/state.js\";\nimport { getCompletionDetector } from \"../engines/completion.js\";\nimport { getErrorRecoveryEngine } from \"../engines/recovery.js\";\nimport { spawnWorker, killWorker, isWorkerRunning, getActiveWorker } from \"../engines/worker.js\";\nimport { updateFooter } from \"../ui/components.js\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Planning bash guard — read-only commands allowed in planning phase\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport const PLANNING_RO_BASH = new Set([\n \"cat\", \"grep\", \"head\", \"ls\", \"pwd\", \"rg\", \"tail\", \"wc\",\n]);\n\nfunction firstWord(cmd: string): string {\n const m = cmd.trim().match(/^([A-Za-z0-9_.-]+)/);\n return m?.[1] ?? \"\";\n}\n\nfunction hasOpt(cmd: string, opt: string): boolean {\n const escaped = opt.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return new RegExp(`(?:^|\\\\s)${escaped}(?:\\\\s|$)`).test(cmd);\n}\n\nfunction isReadOnlyFind(cmd: string): boolean {\n return /^find(?:\\s|$)/.test(cmd) && !/\\s-(?:delete|exec|execdir|ok|okdir|fls|fprint|fprint0|fprintf)(?:\\s|$)/.test(cmd);\n}\n\nfunction isReadOnlySed(cmd: string): boolean {\n return /^sed\\s+-n(?:\\s|$)/.test(cmd) && !hasOpt(cmd, \"-i\") && !hasOpt(cmd, \"--in-place\");\n}\n\nexport function isReadOnlyPlanningBash(input: Record<string, unknown> | undefined): boolean {\n const cmd = typeof input?.command === \"string\" ? input.command.trim() : \"\";\n if (!cmd) return false;\n if (/[;&|`$<>\\n\\r\\t]/.test(cmd)) return false;\n const w = firstWord(cmd);\n if (PLANNING_RO_BASH.has(w)) return true;\n // Require that the command doesn't contain a built-in tool that escapes bash like -exec or -e \"eval\"\n // But allow quotes for grep/rg/find.\n // Actually, we must use word tokenization or just block specific substrings entirely.\n // The vulnerability is that quotes bypass the regex checking flags.\n // Let's strip all quotes and backslashes before checking for bad flags.\n const strippedCmd = cmd.replace(/['\"\\\\]/g, \"\");\n if (w === \"find\") return isReadOnlyFind(strippedCmd);\n if (w === \"sed\") return isReadOnlySed(strippedCmd);\n if (w === \"git\") return /^git\\s+(?:status|diff|show|log)(?:\\s|$)/.test(cmd);\n return false;\n}\n\nexport function toolResultErrorMessage(event: { toolName: string; content?: Array<{ type?: string; text?: string }> }): string {\n const text = event.content\n ?.filter(c => c?.type === \"text\" && typeof c.text === \"string\")\n .map(c => c.text).join(\"\\n\").trim();\n return text || `Tool '${event.toolName}' failed`;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Fork helpers (inline — consolidated from fork-utils.ts)\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function cloneFeatureForFork(feature: Feature, id: string, title: string, notes: string): Feature {\n const acLen = feature.acceptance.length;\n const newAcceptance = new Array(acLen);\n for (let i = 0; i < acLen; i++) {\n const ac = feature.acceptance[i];\n newAcceptance[i] = { ...ac, verified: false, evidence: undefined };\n }\n return {\n ...feature, id, title, status: \"active\", notes,\n completedAt: undefined, dependsOn: [...feature.dependsOn], sessions: [...feature.sessions],\n acceptance: newAcceptance,\n };\n}\n\nexport function appendForkNote(existing: string | undefined, entries: string[]): string {\n const filtered = entries.filter(Boolean);\n return existing ? `${existing}\\n\\n${filtered.join(\"\\n\")}` : filtered.join(\"\\n\");\n}\n\nexport function pushSessionRef(feature: Feature, ref: string | undefined): void {\n if (ref) feature.sessions.push(ref);\n}\n\nexport function buildForkKickoffMessage(\n missionTitle: string, source: Feature, forked: Feature, reason: string,\n subtask: string | undefined, parentSessionFile: string | undefined,\n): string {\n const lines = [\n `## Forked Mission: ${missionTitle}`,\n `Source: ${source.id} — ${source.title}`,\n `Fork: ${forked.id} — ${forked.title}`,\n `Reason: ${reason}`,\n ]; if (subtask) lines.push(`Subtask: ${subtask}`);\n if (parentSessionFile) lines.push(`Parent session: ${parentSessionFile}`);\n lines.push(\n \"\", `Active fork feature: ${forked.id} — ${forked.title}`,\n \"Continue mission: work ONLY on the forked feature. When complete:\",\n `1. Call mission_feature_done with evidence.`,\n `2. The original ${source.id} is blocked — the user will resolve it.`,\n );\n return lines.join(\"\\n\");\n}\n\nexport function buildManualForkHandoff(\n missionTitle: string, source: Feature, forked: Feature, reason: string,\n parentLeafId: string | null, parentSessionFile: string | undefined,\n): string {\n const lines = [\n `🔀 Manual fork handoff for ${missionTitle}:`,\n ` Source: ${source.id} — ${source.title}`,\n ` Fork: ${forked.id} — ${forked.title}`,\n ` Reason: ${reason}`,\n ];\n if (parentLeafId) lines.push(` Parent leaf: ${parentLeafId}`);\n if (parentSessionFile) lines.push(` Parent session: ${parentSessionFile}`);\n lines.push(\n \"\", \"Action: open or clone a new Pi session and load this mission via /mission load <id>.\",\n `Focus on: ${forked.id} — ${forked.title}`,\n );\n return lines.join(\"\\n\");\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Inject mission context\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function injectMissionContext(pi: ExtensionAPI, ctx: ExtensionCommandContext, mission: MissionState, reason: string, content: string): void {\n const details = { missionId: mission.id, reason, injectedAt: Date.now() };\n const sm = ctx.sessionManager as MissionContextSessionManager;\n if (typeof sm.appendCustomMessageEntry === \"function\") {\n sm.appendCustomMessageEntry(\"pi-mission-context\", content, false, details);\n }\n pi.appendEntry(\"pi-mission-context\", { ...details, content });\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Tool policy enforcement (for use by extension.ts)\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function enforceToolPolicy(\n toolName: string,\n phase: ToolPhase,\n input: Record<string, unknown> | undefined,\n allowBashInPlanning: boolean,\n toolCallCount: number,\n): { blocked: true; reason: string } | { blocked: false } {\n const policy = TOOL_POLICIES[phase];\n if (policy.allowedTools.includes(toolName)) return { blocked: false };\n\n const allowedBash = phase === \"planning\" && toolName === \"bash\" && (allowBashInPlanning || isReadOnlyPlanningBash(input));\n if (allowedBash) return { blocked: false };\n\n if (phase === \"planning\" && toolName === \"bash\") {\n return { blocked: true, reason: \"Tool 'bash' is only allowed in planning phase for single read-only commands: pwd, ls, find, grep, rg, cat, sed -n, head, tail, wc, git status/diff/show/log.\" };\n }\n return { blocked: true, reason: `'${toolName}' not allowed in ${phase}. Allowed: ${policy.allowedTools.join(\", \")}` };\n}\n\nexport function enforceToolMax(phase: ToolPhase, count: number): { blocked: true; reason: string } | { blocked: false } {\n const max = TOOL_POLICIES[phase].maxToolCalls;\n if (count > max) return { blocked: true, reason: `Max tool calls (${max}) exceeded for ${phase} phase.` };\n return { blocked: false };\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Tool registration\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function registerMissionTools(_pi: ExtensionAPI, runtime: RuntimeState): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const pi = _pi as unknown as { registerTool: (def: Record<string, unknown>) => void };\n // ── mission_feature_done ──────────────────────────────────────────────\n\n pi.registerTool({\n name: \"mission_feature_done\",\n label: \"Mission Feature Done\",\n description: \"Mark the active mission feature as done with evidence.\",\n promptSnippet: \"Mark the active mission feature as done with evidence\",\n promptGuidelines: [\"Use only after all acceptance criteria are satisfied and evidence is available.\"],\n parameters: Type.Object({\n evidence: Type.String({ description: \"Completion evidence\" }),\n notes: Type.Optional(Type.String({ description: \"Optional notes\" })),\n }),\n async execute(_id: string, params: Record<string, unknown>, _sig: unknown, _upd: unknown, ctx: ExtensionCommandContext) {\n const m = runtime.activeMission;\n const f = m ? getActiveFeature(m) : null;\n if (!m || !f) return { isError: true, content: [{ type: \"text\", text: \"No active mission feature.\" }], details: {} };\n\n const result = completeActiveFeature(m, {\n evidence: String(params.evidence ?? \"\"),\n notes: typeof params.notes === \"string\" ? params.notes : undefined,\n });\n if (!result.ok) return { isError: true, content: [{ type: \"text\", text: `${result.reason}\\nUse /mission edit to waive criteria.` }], details: {} };\n\n await saveMissionSafe(m);\n updateFooter(ctx, m);\n return { content: [{ type: \"text\", text: `✅ Feature ${result.feature.id} done. Evidence: ${result.evidenceFile}` }], details: { featureId: result.feature.id, evidenceFile: result.evidenceFile }, isError: false };\n },\n });\n\n // ── mission_next_feature ──────────────────────────────────────────────\n\n pi.registerTool({\n name: \"mission_next_feature\",\n label: \"Next Feature\",\n description: \"Advance to the next pending mission feature.\",\n parameters: Type.Object({}),\n async execute(_id: string, _p: unknown, _sig: unknown, _upd: unknown, ctx: ExtensionCommandContext) {\n const m = runtime.activeMission;\n if (!m) return { isError: true, content: [{ type: \"text\", text: \"No active mission.\" }], details: {} };\n\n const result = activateNextFeature(m);\n if (!result.ok) {\n if (result.reason === \"active_not_done\") {\n return { isError: true, content: [{ type: \"text\", text: `Active feature not done yet: ${result.active.id} — ${result.active.title}. Use mission_feature_done or /mission block.` }], details: {} };\n }\n if (result.reason === \"mission_complete\") {\n await saveMissionSafe(m); updateFooter(ctx, m);\n return { content: [{ type: \"text\", text: \"🎉 Mission complete.\" }], details: { missionId: m.id }, isError: false };\n }\n return { isError: true, content: [{ type: \"text\", text: \"No unblocked pending feature found.\" }], details: {} };\n }\n\n await saveMissionSafe(m); updateFooter(ctx, m);\n return { content: [{ type: \"text\", text: `➡️ Active feature: ${result.next.id} — ${result.next.title}\\n${result.next.description}` }], details: { feature: result.next }, isError: false };\n },\n });\n\n // ── mission_ask_user ──────────────────────────────────────────────────\n\n pi.registerTool({\n name: \"mission_ask_user\",\n label: \"Ask User\",\n description: \"Ask the user a question during mission execution.\",\n promptSnippet: \"Ask the user a question\",\n promptGuidelines: [\n \"Use when you need user input to proceed.\",\n \"Use 'confirm' for yes/no, 'select' for choices, 'input' for text.\",\n \"Always provide a sensible default.\",\n ],\n parameters: Type.Object({\n question: Type.String({ description: \"The question to ask\" }),\n questionType: Type.Optional(Type.String({ description: \"input, confirm, or select\", enum: [\"input\", \"confirm\", \"select\"] })),\n options: Type.Optional(Type.Array(Type.String({ description: \"Options for select\" }))),\n defaultValue: Type.Optional(Type.String({ description: \"Default value\" })),\n context: Type.Optional(Type.String({ description: \"Additional context\" })),\n }),\n async execute(_id: string, params: Record<string, unknown>, _sig: unknown, _upd: unknown, ctx: ExtensionCommandContext) {\n const m = runtime.activeMission;\n if (!m) throw new Error(\"No active mission.\");\n const f = getActiveFeature(m);\n\n m.autopilot.enabled = false;\n m.autopilot.lastStopReason = \"needs_user_decision\";\n m.autopilot.lastStopMessage = String(params.question ?? \"\");\n\n appendHistory(m, { event: \"user_asked\", featureId: f?.id, note: `Q: ${params.question}`, details: { questionType: params.questionType, options: params.options, defaultValue: params.defaultValue } });\n\n const qType = String(params.questionType ?? \"input\");\n const dflt = typeof params.defaultValue === \"string\" ? params.defaultValue : null;\n let answer: string | null = null;\n let source = \"no_ui\";\n\n if (ctx.hasUI) {\n try {\n switch (qType) {\n case \"confirm\":\n answer = await ctx.ui.confirm(String(params.question ?? \"\"), String(params.context ?? \"\")) ? \"yes\" : \"no\";\n break;\n case \"select\": {\n const opts = Array.isArray(params.options) ? params.options.map(String) : [];\n if (!opts.length) throw new Error(\"Select requires options\");\n const choice = await ctx.ui.select(String(params.question ?? \"\"), opts);\n answer = choice || dflt || null;\n break;\n }\n default:\n answer = await ctx.ui.input(String(params.question ?? \"\"), String(params.context ?? \"\")) || dflt || null;\n }\n source = \"ui\";\n } catch { answer = dflt; source = \"default\"; }\n } else {\n answer = dflt || \"[No UI available]\";\n }\n\n if (f) appendHistory(m, { event: \"user_answered\", featureId: f.id, note: `A: ${answer}`, details: { answer, answerSource: source, questionType: qType } });\n if (answer === \"ALLOW_BASH_IN_PLANNING\") {\n m.userPreferences = m.userPreferences ?? {};\n m.userPreferences.allowBashInPlanning = true;\n await saveMissionSafe(m);\n }\n\n return { content: [{ type: \"text\", text: `User answered: ${answer}${source !== \"ui\" ? ` (via ${source})` : \"\"}` }], details: { question: params.question, answer, answerSource: source }, isError: false };\n },\n });\n\n // ── mission_block_self ────────────────────────────────────────────────\n\n pi.registerTool({\n name: \"mission_block_self\",\n label: \"Block Self\",\n description: \"Block the current feature when stuck.\",\n promptSnippet: \"Block the current feature\",\n promptGuidelines: [\"Use when stuck. Provide a clear reason.\"],\n parameters: Type.Object({\n reason: Type.String({ description: \"Reason for blocking\" }),\n context: Type.Optional(Type.String({ description: \"Additional context\" })),\n }),\n async execute(_id: string, params: Record<string, unknown>, _sig: unknown, _upd: unknown, ctx: ExtensionCommandContext) {\n const m = runtime.activeMission;\n const f = m ? getActiveFeature(m) : null;\n if (!m || !f) throw new Error(\"No active feature.\");\n\n f.status = \"blocked\";\n f.notes = `Self-blocked: ${params.reason}${params.context ? `\\n\\nContext: ${params.context}` : \"\"}`;\n m.status = \"blocked\";\n m.autopilot.enabled = false;\n m.autopilot.lastStopReason = \"blocked\";\n m.autopilot.lastStopMessage = String(params.reason ?? \"\");\n appendHistory(m, { event: \"feature_blocked\", featureId: f.id, note: String(params.reason ?? \"\"), details: { context: params.context, self: true } });\n\n autoUnblockResolved(m);\n const next = getNextPendingFeature(m);\n if (next) {\n next.status = \"active\"; m.status = \"active\"; m.activeFeatureId = next.id; m.activeMilestoneId = next.milestoneId;\n m.autopilot.lastStopReason = undefined; m.autopilot.lastStopMessage = undefined;\n appendHistory(m, { event: \"feature_active\", featureId: next.id, note: \"Auto-advanced after self-block\" });\n await saveMissionSafe(m); updateFooter(ctx, m);\n return { content: [{ type: \"text\", text: `🚫 Self-blocked ${f.id}: ${params.reason}\\n➡️ Auto-advanced to ${next.id} — ${next.title}` }], details: { featureId: f.id, nextFeatureId: next.id }, isError: false };\n }\n await saveMissionSafe(m); updateFooter(ctx, m);\n throw new Error(`Self-blocked ${f.id}: ${params.reason}. No pending features available.`);\n },\n });\n\n // ── mission_fork ──────────────────────────────────────────────────────\n\n pi.registerTool({\n name: \"mission_fork\",\n label: \"Fork Feature\",\n description: \"Fork the current feature into a separate session.\",\n promptSnippet: \"Fork the current feature\",\n promptGuidelines: [\"Use for parallel work or isolation. Provide a clear reason.\"],\n parameters: Type.Object({\n reason: Type.String({ description: \"Reason for forking\" }),\n subtask: Type.Optional(Type.String({ description: \"Specific subtask\" })),\n }),\n async execute(_id: string, params: Record<string, unknown>, _sig: unknown, _upd: unknown, ctx: ExtensionCommandContext) {\n const m = runtime.activeMission;\n const f = m ? getActiveFeature(m) : null;\n if (!m || !f) throw new Error(\"No active feature.\");\n\n const sm = ctx.sessionManager as ForkSessionManager;\n const reason = String(params.reason ?? \"Alternative approach\");\n const parentLeafId = sm.getLeafId?.() ?? null;\n const parentSessionFile = sm.getSessionFile?.();\n const createdAt = new Date().toISOString();\n const forked = cloneFeatureForFork(f, `${f.id}-fork-${Date.now()}`, `${f.title} [fork]`, `Fork: ${reason}${params.subtask ? ` (${params.subtask})` : \"\"}`);\n const milestone = getMilestoneById(m, f.milestoneId);\n if (!milestone) return { isError: true, content: [{ type: \"text\", text: \"Milestone not found.\" }], details: {} };\n\n f.status = \"blocked\";\n f.notes = appendForkNote(f.notes, [`Forked at ${createdAt}`, `Fork: ${forked.id}`, `Reason: ${reason}`, params.subtask ? `Subtask: ${params.subtask}` : \"\", parentLeafId ? `Leaf: ${parentLeafId}` : \"\", parentSessionFile ? `Session: ${parentSessionFile}` : \"\"]);\n pushSessionRef(f, `fork:${forked.id}`); pushSessionRef(f, parentLeafId ? `leaf:${parentLeafId}` : undefined); pushSessionRef(f, parentSessionFile ? `session:${parentSessionFile}` : undefined);\n\n forked.notes = appendForkNote(forked.notes, [`Fork source: ${f.id}`, `Created: ${createdAt}`, `Reason: ${reason}`, params.subtask ? `Subtask: ${params.subtask}` : \"\", parentSessionFile ? `Parent session: ${parentSessionFile}` : \"\"]);\n pushSessionRef(forked, `parent-feature:${f.id}`); pushSessionRef(forked, parentLeafId ? `parent-leaf:${parentLeafId}` : undefined); pushSessionRef(forked, parentSessionFile ? `parent-session:${parentSessionFile}` : undefined);\n\n milestone.features.push(forked);\n m.activeFeatureId = forked.id; m.activeMilestoneId = forked.milestoneId; m.status = \"active\";\n appendHistory(m, { event: \"feature_forked\", featureId: f.id, note: reason, details: { subtask: params.subtask, self: true, forkedFeatureId: forked.id, parentLeafId, parentSessionFile, forkApiAvailable: typeof ctx.fork === \"function\" } });\n await saveMissionSafe(m);\n\n const kickoff = buildForkKickoffMessage(m.title, f, forked, reason, typeof params.subtask === \"string\" ? params.subtask : undefined, parentSessionFile);\n const manual = buildManualForkHandoff(m.title, f, forked, reason, parentLeafId, parentSessionFile);\n\n if (parentLeafId && typeof ctx.fork === \"function\") {\n const result = await ctx.fork(parentLeafId, {\n position: \"at\",\n withSession: async (fc) => {\n const fcCtx = fc as unknown as ForkReplacementContext;\n const fsf = (fc.sessionManager as ForkSessionManager | undefined)?.getSessionFile?.();\n const pm = loadMissionFromDisk(m.id);\n const pf = pm ? getFeatureById(pm, forked.id) : null;\n if (pm && pf) {\n pushSessionRef(pf, fsf ? `session:${fsf}` : undefined);\n appendHistory(pm, { event: \"feature_fork_session_created\", featureId: forked.id, note: reason, details: { sourceFeatureId: f.id, subtask: params.subtask, forkSessionFile: fsf, parentLeafId, self: true } });\n await saveMissionSafe(pm);\n }\n if (typeof fc.sendUserMessage === \"function\") await fc.sendUserMessage(kickoff);\n else fc.ui.notify(`🌿 Fork active: ${forked.title}\\n\\n${kickoff}`, \"info\");\n },\n });\n if (!result?.cancelled) {\n return { content: [{ type: \"text\", text: `🔀 Forked ${f.id} into ${forked.id} — started a dedicated Pi session\\n\\n${kickoff}` }], details: { featureId: f.id, forkedFeatureId: forked.id, reason, subtask: params.subtask, mode: \"fork_api\" }, isError: false };\n }\n }\n\n return { content: [{ type: \"text\", text: `${manual}\\n\\nKickoff prompt:\\n${kickoff}` }], details: { featureId: f.id, forkedFeatureId: forked.id, reason, subtask: params.subtask, mode: \"manual\" }, isError: false };\n },\n });\n\n // ── mission_error_status ──────────────────────────────────────────────\n\n pi.registerTool({\n name: \"mission_error_status\",\n label: \"Error Status\",\n description: \"View error recovery statistics.\",\n promptSnippet: \"View error status\",\n promptGuidelines: [\"Check what errors occurred and their recovery status.\"],\n parameters: Type.Object({\n scope: Type.Optional(Type.String({ description: \"'feature' or 'mission'\", enum: [\"feature\", \"mission\"] })),\n }),\n async execute(_id: string, params: Record<string, unknown>, _sig: unknown, _upd: unknown, _ctx: ExtensionCommandContext) {\n const m = runtime.activeMission;\n if (!m) throw new Error(\"No active mission.\");\n const f = getActiveFeature(m);\n const recovery = getErrorRecoveryEngine();\n const scope = String(params.scope ?? \"feature\");\n const errors = scope === \"feature\" && f ? recovery.getErrorsForFeature(f.id) : recovery.getErrorsForMission(m.id);\n const stats = recovery.getStats();\n\n if (!errors.length) {\n return { content: [{ type: \"text\", text: `✅ No errors for ${scope === \"feature\" ? `feature ${f?.id}` : \"mission\"}.\\n\\nTotal: ${stats.total}, resolved: ${stats.resolved}` }], details: { scope, errorCount: 0, stats }, isError: false };\n }\n\n const lines = [\n `📋 Error Status (${scope})`,\n `Total: ${errors.length}, Resolved: ${errors.filter(e => e.resolved).length}`,\n \"\", \"Recent:\",\n ...errors.slice(-5).map(e => `- [${e.resolved ? \"✓\" : \"✗\"}] ${e.context.toolName ?? \"?\"}: ${e.context.errorMessage.slice(0, 50)}`),\n \"\", \"By category:\", ...Object.entries(stats.byCategory).map(([k, v]) => `- ${k}: ${v}`),\n \"\", \"By severity:\", ...Object.entries(stats.bySeverity).map(([k, v]) => `- ${k}: ${v}`),\n ];\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }], details: { scope, errors, stats }, isError: false };\n },\n });\n\n // ── mission_spawn_worker ─────────────────────────────────────────────\n\n pi.registerTool({\n name: \"mission_spawn_worker\",\n label: \"Spawn Worker\",\n description: \"Spawn a worker subprocess to autonomously execute a feature.\",\n promptSnippet: \"Spawn a worker to execute a feature autonomously\",\n promptGuidelines: [\n \"Use for large features that need focused execution.\",\n \"The worker runs in a separate pi process with the feature context.\",\n \"Only one worker runs at a time. Check status with mission_worker_status.\",\n ],\n parameters: Type.Object({\n featureId: Type.Optional(Type.String({ description: \"Feature ID (defaults to active feature)\" })),\n customPrompt: Type.Optional(Type.String({ description: \"Custom instructions for the worker\" })),\n model: Type.Optional(Type.String({ description: \"Model override (default: auto)\" })),\n }),\n async execute(_id: string, params: Record<string, unknown>, _sig: unknown, _upd: unknown, _ctx: ExtensionCommandContext) {\n const m = runtime.activeMission;\n const f = m ? getActiveFeature(m) : null;\n if (!m || !f) throw new Error(\"No active mission feature.\");\n\n const featureId = typeof params.featureId === \"string\" ? params.featureId : f.id;\n const feat = getFeatureById(m, featureId);\n if (!feat) throw new Error(`Feature not found: ${featureId}`);\n\n if (isWorkerRunning()) {\n const aw = getActiveWorker();\n return {\n isError: true,\n content: [{ type: \"text\", text: `Worker already running for ${aw?.featureId}. Use mission_worker_status to check.` }],\n details: { running: true, featureId: aw?.featureId },\n };\n }\n\n // Mark the feature as active\n feat.status = \"active\";\n m.activeFeatureId = feat.id;\n m.activeMilestoneId = feat.milestoneId;\n m.status = \"active\";\n\n appendHistory(m, {\n event: \"worker_spawned\",\n featureId: feat.id,\n note: `Spawning worker for ${feat.id} — ${feat.title}`,\n details: { model: params.model, hasCustomPrompt: !!params.customPrompt },\n });\n\n await saveMissionSafe(m);\n\n // Spawn async — don't await, return immediately\n spawnWorker(m, {\n featureId: feat.id,\n customPrompt: typeof params.customPrompt === \"string\" ? params.customPrompt : undefined,\n model: typeof params.model === \"string\" ? params.model : undefined,\n }).then((result) => {\n if (\"error\" in result) {\n appendHistory(m, { event: \"worker_error\", featureId: feat.id, note: result.error });\n saveMissionSafe(m).catch((saveErr) => {\n process.stderr.write(`[pi-missions] Failed to save after worker error: ${saveErr}\\n`);\n });\n }\n }).catch((spawnErr) => {\n process.stderr.write(`[pi-missions] Worker spawn failed for ${feat.id}: ${spawnErr}\\n`);\n });\n\n return {\n content: [{\n type: \"text\",\n text: `🚀 Worker spawned for ${feat.id} — ${feat.title}\\n\\nThe worker runs autonomously in a separate process. Results are logged to history.\\nCheck status: /mission worker-status`,\n }],\n details: { featureId: feat.id, mode: \"async\" },\n isError: false,\n };\n },\n });\n\n // ── mission_worker_status ─────────────────────────────────────────────\n\n pi.registerTool({\n name: \"mission_worker_status\",\n label: \"Worker Status\",\n description: \"Check the status of the currently running worker.\",\n promptSnippet: \"Check worker status\",\n promptGuidelines: [\"Check if a worker is running and its progress.\"],\n parameters: Type.Object({}),\n async execute(_id: string, _p: unknown, _sig: unknown, _upd: unknown, _ctx: ExtensionCommandContext) {\n const aw = getActiveWorker();\n if (!aw) {\n return { content: [{ type: \"text\", text: \"No worker running.\" }], details: { running: false }, isError: false };\n }\n\n const elapsed = Math.round((Date.now() - aw.startedAt) / 1000);\n const lines = [\n `🔧 Worker Status`,\n `Feature: ${aw.featureId}`,\n `Status: ${aw.status}`,\n `Running: ${elapsed}s`,\n ];\n\n if (aw.result) {\n lines.push(\n \"\", \"## Last Result\",\n `Exit: ${aw.result.exitCode}${aw.result.signal ? ` (${aw.result.signal})` : \"\"}`,\n `Duration: ${Math.round(aw.result.durationMs / 1000)}s`,\n `Stdout: ${aw.result.stdout.slice(0, 500)}`,\n aw.result.stderr ? `Stderr: ${aw.result.stderr.slice(0, 300)}` : \"\",\n );\n }\n\n return { content: [{ type: \"text\", text: lines.filter(Boolean).join(\"\\n\") }], details: { running: true, featureId: aw.featureId, status: aw.status, elapsedMs: Date.now() - aw.startedAt }, isError: false };\n },\n });\n\n // ── mission_kill_worker ───────────────────────────────────────────────\n\n pi.registerTool({\n name: \"mission_kill_worker\",\n label: \"Kill Worker\",\n description: \"Kill the currently running worker process.\",\n promptSnippet: \"Kill running worker\",\n promptGuidelines: [\"Use to stop a runaway or stuck worker.\"],\n parameters: Type.Object({}),\n async execute(_id: string, _p: unknown, _sig: unknown, _upd: unknown, _ctx: ExtensionCommandContext) {\n const killed = killWorker();\n if (!killed) {\n return { content: [{ type: \"text\", text: \"No worker running to kill.\" }], details: { killed: false }, isError: false };\n }\n return { content: [{ type: \"text\", text: \"🛑 Worker killed.\" }], details: { killed: true }, isError: false };\n },\n });\n\n // ── mission_retry_error ───────────────────────────────────────────────\n\n pi.registerTool({\n name: \"mission_retry_error\",\n label: \"Retry Error\",\n description: \"Retry a failed operation or clear errors.\",\n promptSnippet: \"Retry failed operation\",\n promptGuidelines: [\"Clear error state to allow retry after fixing the root cause.\"],\n parameters: Type.Object({\n errorId: Type.Optional(Type.String({ description: \"Error ID to retry\" })),\n }),\n async execute(_id: string, params: Record<string, unknown>, _sig: unknown, _upd: unknown, _ctx: ExtensionCommandContext) {\n const m = runtime.activeMission;\n const f = m ? getActiveFeature(m) : null;\n if (!m || !f) throw new Error(\"No active feature.\");\n const recovery = getErrorRecoveryEngine();\n\n if (typeof params.errorId === \"string\" && params.errorId) {\n recovery.markResolved(params.errorId);\n appendHistory(m, { event: \"error_resolved\", featureId: f.id, note: `Resolved ${params.errorId}` });\n return { content: [{ type: \"text\", text: `✅ Error ${params.errorId} resolved.` }], details: { errorId: params.errorId }, isError: false };\n }\n\n recovery.clearErrorsForFeature(f.id);\n appendHistory(m, { event: \"errors_cleared\", featureId: f.id, note: \"Cleared all errors\" });\n return { content: [{ type: \"text\", text: `✅ Cleared all errors for ${f.id}.` }], details: { featureId: f.id }, isError: false };\n },\n });\n}\n","import * as crypto from \"node:crypto\";\nimport type {\n ErrorCategory, ErrorSeverity, ErrorContext,\n ErrorRecoveryStrategy, ErrorRecord, RecoveryAction, RetryOptions, DegradedResult,\n} from \"../core/types.js\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Retry Utility — exponential backoff with jitter\n// ═══════════════════════════════════════════════════════════════════════════\n\nfunction backoffDelay(attempt: number, baseMs: number, maxMs: number, jitter: number): number {\n const delay = Math.min(baseMs * Math.pow(2, attempt), maxMs);\n const j = jitter > 0 ? delay * jitter * (Math.random() * 2 - 1) : 0;\n return Math.round(Math.max(0, delay + j));\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n opts: RetryOptions = {},\n): Promise<T> {\n const { maxRetries = 3, baseDelayMs = 1000, maxDelayMs = 30000, jitterFactor = 0.2, shouldRetry, operationName } = opts;\n let lastError: unknown;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n if (attempt >= maxRetries) break;\n if (shouldRetry && !shouldRetry(error)) break;\n const delay = backoffDelay(attempt, baseDelayMs, maxDelayMs, jitterFactor);\n const label = operationName ? `[${operationName}]` : \"\";\n if (typeof process !== \"undefined\" && process.stderr) {\n process.stderr.write(`${label} Attempt ${attempt + 1}/${maxRetries} failed, retrying in ${delay}ms...\\n`);\n }\n await new Promise(r => setTimeout(r, delay));\n }\n }\n throw lastError;\n}\n\nexport function withRetrySync<T>(fn: () => T, opts: RetryOptions = {}): T {\n const { maxRetries = 3, baseDelayMs = 1000, maxDelayMs = 30000, jitterFactor = 0.2, shouldRetry } = opts;\n let lastError: unknown;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try { return fn(); } catch (error) {\n lastError = error;\n if (attempt >= maxRetries) break;\n if (shouldRetry && !shouldRetry(error)) break;\n const delayMs = backoffDelay(attempt, baseDelayMs, maxDelayMs, jitterFactor);\n // Use Atomics.wait for CPU-friendly blocking sleep\n const sab = new SharedArrayBuffer(4);\n const int32 = new Int32Array(sab);\n Atomics.wait(int32, 0, 0, delayMs);\n }\n }\n throw lastError;\n}\n\nexport function defaultShouldRetry(error: unknown): boolean {\n if (!error) return false;\n const message = error instanceof Error\n ? error.message.toLowerCase()\n : typeof (error as Record<string, unknown>)?.message === \"string\"\n ? String((error as Record<string, unknown>).message).toLowerCase()\n : String(error).toLowerCase();\n // Non-retryable\n if (message.includes(\"syntax\") || message.includes(\"parse error\") || message.includes(\"invalid input\")) return false;\n if (message.includes(\"permission denied\") || message.includes(\"eacces\") || message.includes(\"eperm\")) return false;\n if (message.includes(\"validation\") && message.includes(\"failed\")) return false;\n // Retryable\n if (message.includes(\"timeout\") || message.includes(\"timed out\")) return true;\n if (message.includes(\"econnrefused\") || message.includes(\"econnreset\") || message.includes(\"enotfound\")) return true;\n if (message.includes(\"eagain\") || message.includes(\"ebusy\") || message.includes(\"elock\")) return true;\n if (message.includes(\"temporary\") || message.includes(\"transient\") || message.includes(\"retry\")) return true;\n if (message.includes(\"lock\") && message.includes(\"busy\")) return true;\n if (message.includes(\"resource temporarily\")) return true;\n if (message.includes(\"enomem\") || message.includes(\"cannot allocate\")) return true;\n if (message.includes(\"stale\") && message.includes(\"lock\")) return true;\n return false;\n}\n\nexport const RetryPresets = {\n fileIO: { maxRetries: 3, baseDelayMs: 500, maxDelayMs: 10000, jitterFactor: 0.1, shouldRetry: defaultShouldRetry },\n network: { maxRetries: 5, baseDelayMs: 2000, maxDelayMs: 60000, jitterFactor: 0.2, shouldRetry: defaultShouldRetry },\n lock: { maxRetries: 10, baseDelayMs: 100, maxDelayMs: 5000, jitterFactor: 0.05, shouldRetry: defaultShouldRetry },\n critical: { maxRetries: 1, baseDelayMs: 100, maxDelayMs: 2000, jitterFactor: 0, shouldRetry: defaultShouldRetry },\n persistence: { maxRetries: 5, baseDelayMs: 200, maxDelayMs: 5000, jitterFactor: 0.1, shouldRetry: defaultShouldRetry },\n} as const satisfies Record<string, RetryOptions>;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Graceful degradation\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport async function withDegradation<T>(\n primary: () => Promise<T>,\n fallback: (error: unknown) => Promise<T>,\n): Promise<DegradedResult<T>> {\n try {\n return { ok: true, value: await primary(), degraded: false };\n } catch (e) {\n try {\n return { ok: true, value: await fallback(e), degraded: true, error: e };\n } catch (fb) {\n return { ok: false, value: undefined, degraded: true, error: fb };\n }\n }\n}\n\nexport function withDegradationSync<T>(\n primary: () => T,\n fallback: (error: unknown) => T,\n): DegradedResult<T> {\n try {\n return { ok: true, value: primary(), degraded: false };\n } catch (e) {\n try {\n return { ok: true, value: fallback(e), degraded: true, error: e };\n } catch (fb) {\n return { ok: false, value: undefined, degraded: true, error: fb };\n }\n }\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Error Recovery Engine\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport type ErrorAlertType = \"error_critical\" | \"error_threshold\" | \"recovery_failed\" | \"retry_exhausted\";\n\nexport type ErrorAlertCallback = (alert: {\n type: ErrorAlertType;\n record: ErrorRecord;\n stats?: { total: number; critical: number; recent: number };\n message: string;\n}) => void;\n\nexport class ErrorRecoveryEngine {\n private errorRecords = new Map<string, ErrorRecord>();\n private activeRetries = new Map<string, { count: number; lastAttempt: number }>();\n private alertCallbacks = new Set<ErrorAlertCallback>();\n private consecutiveFailures = new Map<string, number>();\n private alertThresholds = {\n criticalErrors: 1,\n consecutiveFailures: 3,\n totalErrorsBeforeAlert: 5,\n windowMs: 60_000,\n };\n\n private strategies = new Map<ErrorCategory, ErrorRecoveryStrategy>([\n [\"transient\", { category: \"transient\", maxRetries: 3, backoffMs: 1000, fallbackAction: \"retry\" }],\n [\"network\", { category: \"network\", maxRetries: 5, backoffMs: 2000, fallbackAction: \"retry\" }],\n [\"permission\", { category: \"permission\", maxRetries: 0, backoffMs: 0, fallbackAction: \"ask_user\" }],\n [\"permanent\", { category: \"permanent\", maxRetries: 0, backoffMs: 0, fallbackAction: \"block\" }],\n [\"user\", { category: \"user\", maxRetries: 0, backoffMs: 0, fallbackAction: \"ask_user\" }],\n [\"system\", { category: \"system\", maxRetries: 2, backoffMs: 5000, fallbackAction: \"degrade\" }],\n [\"unknown\", { category: \"unknown\", maxRetries: 1, backoffMs: 1000, fallbackAction: \"skip\" }],\n ]);\n\n onAlert(cb: ErrorAlertCallback): () => void {\n this.alertCallbacks.add(cb);\n return () => this.alertCallbacks.delete(cb);\n }\n\n setAlertThresholds(t: Partial<typeof this.alertThresholds>): void {\n Object.assign(this.alertThresholds, t);\n }\n\n private fireAlert(type: ErrorAlertType, record: ErrorRecord, message: string): void {\n const recent = Array.from(this.errorRecords.values()).filter(\n r => Date.now() - r.timestamp < this.alertThresholds.windowMs,\n );\n const stats = {\n total: this.errorRecords.size,\n critical: recent.filter(r => r.severity === \"critical\").length,\n recent: recent.length,\n };\n for (const cb of this.alertCallbacks) {\n try { cb({ type, record, stats, message }); } catch { /* silent */ }\n }\n }\n\n private opKey(ctx: ErrorContext): string {\n return `${ctx.toolName ?? \"unknown\"}:${ctx.featureId ?? \"global\"}`;\n }\n\n categorizeError(ctx: ErrorContext): ErrorCategory {\n const msg = ctx.errorMessage.toLowerCase();\n if (msg.includes(\"network\") || msg.includes(\"connection\") || msg.includes(\"timeout\") ||\n msg.includes(\"econnrefused\") || msg.includes(\"enotfound\") || msg.includes(\"etimedout\")) return \"network\";\n if (msg.includes(\"permission\") || msg.includes(\"access denied\") || msg.includes(\"eacces\") ||\n msg.includes(\"eperm\") || ctx.errorType.toLowerCase().includes(\"permission\")) return \"permission\";\n if (msg.includes(\"invalid input\") || msg.includes(\"validation\") || msg.includes(\"user\") ||\n ctx.errorType.toLowerCase().includes(\"validation\") || ctx.errorType.toLowerCase().includes(\"user\")) return \"user\";\n if (msg.includes(\"temporary\") || msg.includes(\"retry\") || msg.includes(\"busy\") ||\n msg.includes(\"locked\") || msg.includes(\"eagain\") || msg.includes(\"ebusy\")) return \"transient\";\n if (msg.includes(\"memory\") || msg.includes(\"disk\") || msg.includes(\"space\") ||\n ctx.errorType.toLowerCase().includes(\"system\")) return \"system\";\n if (msg.includes(\"syntax\") || msg.includes(\"parse\") || ctx.errorType.toLowerCase().includes(\"syntax\") ||\n ctx.errorType.toLowerCase().includes(\"parse\")) return \"permanent\";\n return \"unknown\";\n }\n\n determineSeverity(category: ErrorCategory): ErrorSeverity {\n if (category === \"permanent\" || category === \"permission\") return \"critical\";\n if (category === \"system\") return \"high\";\n if (category === \"network\" || category === \"unknown\") return \"medium\";\n return \"low\";\n }\n\n handleError(ctx: ErrorContext): { action: RecoveryAction; shouldRetry: boolean; retryAfter?: number; record: ErrorRecord } {\n const category = this.categorizeError(ctx);\n const severity = this.determineSeverity(category);\n const strategy = this.strategies.get(category) ?? this.strategies.get(\"unknown\")!;\n const errorKey = `${ctx.toolName ?? \"unknown\"}:${ctx.errorType}:${ctx.featureId ?? \"none\"}`;\n const retryState = this.activeRetries.get(errorKey);\n const retryCount = retryState?.count ?? 0;\n const key = this.opKey(ctx);\n const consecutive = (this.consecutiveFailures.get(key) ?? 0) + 1;\n this.consecutiveFailures.set(key, consecutive);\n\n const record: ErrorRecord = {\n id: crypto.randomUUID(), context: ctx, category, severity,\n retryCount, actionTaken: \"skip\", resolved: false, timestamp: Date.now(),\n };\n\n let action: RecoveryAction;\n let shouldRetry = false;\n let retryAfter: number | undefined;\n if (retryCount < strategy.maxRetries) {\n action = strategy.fallbackAction ?? \"retry\";\n shouldRetry = action === \"retry\";\n if (shouldRetry) {\n retryAfter = strategy.backoffMs * Math.pow(2, retryCount);\n this.activeRetries.set(errorKey, { count: retryCount + 1, lastAttempt: Date.now() });\n }\n } else {\n action = strategy.fallbackAction ?? \"skip\";\n }\n\n record.actionTaken = action;\n this.errorRecords.set(record.id, record);\n\n if (severity === \"critical\") this.fireAlert(\"error_critical\", record, `Critical: ${ctx.errorMessage}`);\n if (consecutive >= this.alertThresholds.consecutiveFailures) this.fireAlert(\"error_threshold\", record, `${consecutive} consecutive failures for ${key}`);\n if (action === \"skip\" || action === \"block\") this.fireAlert(\"recovery_failed\", record, `Recovery failed: ${action}`);\n if (retryCount >= strategy.maxRetries && !shouldRetry) this.fireAlert(\"retry_exhausted\", record, `Retries exhausted after ${retryCount} for ${key}`);\n\n return { action, shouldRetry, retryAfter, record };\n }\n\n markResolved(recordId: string): void {\n const record = this.errorRecords.get(recordId);\n if (record) {\n record.resolved = true;\n this.activeRetries.delete(`${record.context.toolName ?? \"unknown\"}:${record.context.errorType}:${record.context.featureId ?? \"none\"}`);\n this.consecutiveFailures.delete(this.opKey(record.context));\n }\n }\n\n clearConsecutiveFailures(toolName?: string, featureId?: string): void {\n if (!toolName && !featureId) { this.consecutiveFailures.clear(); return; }\n const filter = `${toolName ?? \"unknown\"}:${featureId ?? \"global\"}`;\n for (const key of this.consecutiveFailures.keys()) {\n if (key === filter || (toolName && key.startsWith(`${toolName}:`)) || (featureId && key.endsWith(`:${featureId}`))) {\n this.consecutiveFailures.delete(key);\n }\n }\n }\n\n getErrorsForFeature(featureId: string): ErrorRecord[] {\n return Array.from(this.errorRecords.values()).filter(r => r.context.featureId === featureId);\n }\n\n getErrorsForMission(missionId: string): ErrorRecord[] {\n return Array.from(this.errorRecords.values()).filter(r => r.context.missionId === missionId);\n }\n\n clearErrors(): void {\n this.errorRecords.clear();\n this.activeRetries.clear();\n }\n\n clearErrorsForFeature(featureId: string): void {\n for (const [id, record] of this.errorRecords) {\n if (record.context.featureId === featureId) {\n this.activeRetries.delete(`${record.context.toolName ?? \"unknown\"}:${record.context.errorType}:${record.context.featureId ?? \"none\"}`);\n this.errorRecords.delete(id);\n }\n }\n }\n\n getStats(): { total: number; resolved: number; byCategory: Record<ErrorCategory, number>; bySeverity: Record<ErrorSeverity, number> } {\n const records = Array.from(this.errorRecords.values());\n const byCategory: Record<ErrorCategory, number> = { transient: 0, permanent: 0, user: 0, system: 0, network: 0, permission: 0, unknown: 0 };\n const bySeverity: Record<ErrorSeverity, number> = { low: 0, medium: 0, high: 0, critical: 0 };\n for (const r of records) { byCategory[r.category]++; bySeverity[r.severity]++; }\n return { total: records.length, resolved: records.filter(r => r.resolved).length, byCategory, bySeverity };\n }\n\n setStrategy(category: ErrorCategory, strategy: ErrorRecoveryStrategy): void {\n this.strategies.set(category, strategy);\n }\n}\n\nlet globalEngine: ErrorRecoveryEngine | null = null;\n\nexport function getErrorRecoveryEngine(): ErrorRecoveryEngine {\n if (!globalEngine) globalEngine = new ErrorRecoveryEngine();\n return globalEngine;\n}\n\nexport function resetErrorRecoveryEngine(): void {\n globalEngine = null;\n}\n","import type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport type { RuntimeState } from \"../core/types.js\";\nimport { handleNew, handleTemplates } from \"./handlers.js\";\nimport { handleList, handleLoad, handleStatus, handleHelp } from \"./handlers.js\";\nimport { handleNext, handleDone, handleBlock, handlePause, handleResume, handleClear, handleRun, handleAutopilot, handleStop } from \"./handlers.js\";\nimport { handleEdit, handleFork, handleDashboard, handleDebug, handleMetrics, handleExport, handleHistory, handleWorker, handleWorkerStatus, handleKillWorker, handleMigrate, handleMigrateConfirm } from \"./handlers.js\";\n\n// Re-export for consumers\nexport { handleNew, handleTemplates };\nexport { handleLoad, handleList, handleStatus, handleHelp };\nexport { handleNext, handleDone, handleBlock, handlePause, handleResume, handleClear, handleRun, handleAutopilot, handleStop };\nexport { handleEdit, handleFork, handleDashboard, handleDebug, handleMetrics, handleExport, handleHistory, handleWorker, handleWorkerStatus, handleKillWorker, handleMigrate, handleMigrateConfirm };\n\n// Re-export fork helpers for backward compat test imports\nexport { cloneFeatureForFork, appendForkNote, pushSessionRef, buildForkKickoffMessage, buildManualForkHandoff } from \"../tools/index.js\";\n\n// injectMissionContext wrapper: tools/index.ts takes 5 args, old tests call with 4\nimport { injectMissionContext as injectMissionCtx } from \"../tools/index.js\";\nimport { buildMissionContext } from \"../utils/context.js\";\nexport function injectMissionContext(pi: ExtensionAPI, ctx: ExtensionCommandContext, mission: NonNullable<RuntimeState[\"activeMission\"]>, reason: string, content?: string): void {\n injectMissionCtx(pi, ctx, mission, reason, content ?? buildMissionContext(mission));\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Main command registration\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport function registerMissionCommand(pi: ExtensionAPI, runtime: RuntimeState): void {\n const subs = [\"start\", \"new\", \"list\", \"load\", \"run\", \"pause\", \"resume\", \"stop\", \"clear\",\n \"status\", \"autopilot\", \"help\", \"next\", \"done\", \"block\", \"edit\", \"fork\", \"debug\",\n \"dashboard\", \"metrics\", \"export\", \"templates\", \"history\", \"worker\", \"worker-status\", \"kill-worker\", \"migrate\"];\n\n pi.registerCommand(\"mission\", {\n description: `Mission management: ${subs.join(\"|\")}`,\n getArgumentCompletions: (prefix: string) =>\n subs.filter(s => s.startsWith(prefix)).map(s => ({ value: s, label: s })),\n handler: async (args: string, ctx: ExtensionCommandContext) => {\n const [sub = \"status\", ...rest] = args.trim().split(/\\s+/).filter(Boolean);\n switch (sub) {\n case \"start\": case \"new\": return handleNew(rest.join(\" \"), ctx, pi, runtime);\n case \"list\": return handleList(ctx, pi, runtime);\n case \"load\": return handleLoad(rest[0], ctx, pi, runtime);\n case \"status\": return handleStatus(ctx, runtime);\n case \"help\": return handleHelp(ctx);\n case \"dashboard\": return handleDashboard(ctx, runtime);\n case \"next\": return handleNext(ctx, runtime);\n case \"done\": return handleDone(rest.join(\" \"), ctx, runtime);\n case \"block\": return handleBlock(rest.join(\" \"), ctx, runtime);\n case \"run\": return handleRun(ctx, pi, runtime);\n case \"pause\": return handlePause(ctx, runtime);\n case \"resume\": return handleResume(ctx, runtime);\n case \"stop\": return handleStop(ctx, runtime);\n case \"autopilot\": return handleAutopilot(ctx, runtime);\n case \"clear\": return handleClear(ctx, runtime);\n case \"edit\": return handleEdit(rest[0], ctx, runtime);\n case \"fork\": return handleFork(rest.join(\" \"), ctx, runtime);\n case \"debug\": return handleDebug(rest[0], ctx, runtime);\n case \"metrics\": return handleMetrics(ctx, runtime);\n case \"export\": return handleExport(rest[0], ctx, runtime);\n case \"templates\": return handleTemplates(rest[0], rest[1], rest.slice(2).join(\" \"), ctx, pi, runtime);\n case \"history\": return handleHistory(rest[0], ctx, runtime);\n case \"worker\": return handleWorker(rest[0], ctx, runtime);\n case \"worker-status\": return handleWorkerStatus(ctx);\n case \"kill-worker\": return handleKillWorker(ctx);\n case \"migrate\":\n if (rest[0] && rest[1] === \"confirm\") return handleMigrateConfirm(rest[0], ctx, runtime);\n return handleMigrate(rest[0], ctx, runtime);\n default: return ctx.ui.notify(`Unknown /mission subcommand: ${sub}`, \"warning\");\n }\n },\n });\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Compaction / tree helpers\n// ═══════════════════════════════════════════════════════════════════════════\n\nimport { buildCompactionSummary } from \"../utils/context.js\";\nimport { getActiveFeature, linkSession } from \"../core/state.js\";\n\nexport function compactionCheckpoint(pi: ExtensionAPI, runtime: RuntimeState): void {\n if (!runtime.activeMission) return;\n pi.appendEntry(\"pi-mission-compaction-checkpoint\", {\n missionId: runtime.activeMission.id,\n summary: buildCompactionSummary(runtime.activeMission),\n timestamp: Date.now(),\n });\n}\n\nexport function missionSummaryForTree(runtime: RuntimeState): string | null {\n const mission = runtime.activeMission;\n if (!mission) return null;\n const active = getActiveFeature(mission);\n return `Mission: ${mission.title}${active ? ` — Feature: ${active.title}` : \"\"}`;\n}\n\nexport function saveSessionLink(runtime: RuntimeState, sessionFile: string | undefined): void {\n if (runtime.activeMission && sessionFile) {\n const agent = process.env.CODING_AGENT || \"unknown\";\n linkSession(runtime.activeMission, sessionFile, agent);\n }\n}\n"],"mappings":"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","names":["dirname","resolve","fs","fs","path","f","path","t","mi","fs","path","resolve","Type","crypto","Type","FeatureSchema","rawVersion","dirname","resolve"]}