@robota-sdk/agent-framework 3.0.0-beta.66 → 3.0.0-beta.67

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["asZodSchema","resolveAgentDefinition","extractFirstArg","asZodSchema","resolveAgentDefinition","pathRelative","pathSeparator","toSummary","existsSync","readFileSync","join","LIST_KEYS","parseListValue","parseFrontmatter","asZodSchema","extractJson","SessionWithAutoCompact","existsSync","readFileSync","mergeSettings","mergeProviders","resolveActiveProviderProfile","join","memoryRoot","join","existsSync","readFileSync","readdirSync","basename","resolve","join","existsSync","dirname","obj","hasUsableRequiredProviderCredential","formatEnvReference","hasUsableSecretReference","resolveProviderCredentialValue","hasUsableSecretReference","resolveEnvReference","formatIsoDate"],"sources":["../../src/background-tasks/background-job-orchestrator.ts","../../src/background-tasks/execution-workspace-types.ts","../../src/background-tasks/execution-workspace-projection.ts","../../src/background-tasks/execution-workspace-detail.ts","../../src/background-tasks/execution-workspace-spawner.ts","../../src/background-tasks/session-background-store.ts","../../src/tools/agent-tool-batch.ts","../../src/tools/agent-tool-output.ts","../../src/agents/built-in-agents.ts","../../src/assembly/subagent-prompts.ts","../../src/tools/model-command-tool-projection.ts","../../src/assembly/create-subagent-session.ts","../../src/subagents/in-process-subagent-runner.ts","../../src/tools/agent-tool.ts","../../src/interactive/interactive-session-background-tracker.ts","../../src/interactive/interactive-session-agent-jobs.ts","../../src/interactive/interactive-session-workspace.ts","../../src/interactive/interactive-session-base.ts","../../src/adapters/node-file-system.ts","../../src/context/context-file-tracker.ts","../../src/interactive/interactive-session-context-refresh.ts","../../src/context/context-reference-inventory.ts","../../src/context/prompt-file-reference-format.ts","../../src/context/prompt-file-reference-parser.ts","../../src/context/prompt-file-reference-paths.ts","../../src/context/prompt-file-reference-resolver.ts","../../src/interactive/interactive-session-execution.ts","../../src/interactive/interactive-session-streaming.ts","../../src/interactive/interactive-session-prompt.ts","../../src/interactive/interactive-session-execution-controller.ts","../../src/interactive/interactive-session-fork.ts","../../src/interactive/interactive-session-context-references.ts","../../src/paths.ts","../../src/checkpoints/edit-checkpoint-inspection.ts","../../src/checkpoints/edit-checkpoint-store.ts","../../src/commands/skill-activation-events.ts","../../src/interactive/interactive-session-history-tracker.ts","../../src/context/project-detector.ts","../../src/interactive/interactive-session-restore.ts","../../src/assembly/background-task-hooks.ts","../../src/assembly/create-tools.ts","../../src/agents/agent-definition-loader.ts","../../src/context/system-prompt-composer.ts","../../src/context/system-prompt-section-providers.ts","../../src/context/system-prompt-builder.ts","../../src/tools/background-process-tool.ts","../../src/assembly/create-session-runtime.ts","../../src/checkpoints/edit-checkpoint-tools.ts","../../src/commands/skill-source.ts","../../src/hooks/agent-executor.ts","../../src/hooks/prompt-executor.ts","../../src/reversible-execution/reversible-execution-policy.ts","../../src/assembly/create-session.ts","../../src/assembly/subagent-logger.ts","../../src/config/config-types.ts","../../src/config/config-loader.ts","../../src/context/task-context.ts","../../src/memory/project-memory-store.ts","../../src/context/context-loader.ts","../../src/plugins/plugin-settings-store.ts","../../src/plugins/bundle-plugin-utils.ts","../../src/plugins/bundle-plugin-loader.ts","../../src/plugins/bundle-plugin-installer.ts","../../src/plugins/marketplace-registry.ts","../../src/plugins/marketplace-client.ts","../../src/plugins/plugin-hooks-merger.ts","../../src/interactive/interactive-session-init.ts","../../src/interactive/interactive-session-persistence.ts","../../src/commands/capability-descriptors.ts","../../src/commands/command-registry.ts","../../src/commands/system-command-executor.ts","../../src/commands/system-command.ts","../../src/commands/builtin-source.ts","../../src/command-api/provider/provider-settings.ts","../../src/command-api/provider/provider-command-probe.ts","../../src/command-api/provider/settings-check.ts","../../src/command-api/provider/provider-merge.ts","../../src/config/provider-paths.ts","../../src/config/settings-io.ts","../../src/command-api/provider/provider-configuration.ts","../../src/command-api/provider/provider-factory.ts","../../src/commands/plugin-source.ts","../../src/command-api/context/context-command-api.ts","../../src/command-api/provider/provider-profile-names.ts","../../src/command-api/help/help-command-api.ts","../../src/command-api/background/background-command-api.ts","../../src/command-api/model/model-command-api.ts","../../src/command-api/language/language-command-api.ts","../../src/command-api/permissions/permission-mode-command-api.ts","../../src/command-api/statusline/statusline-command-api.ts","../../src/command-api/plugin/plugin-command-api.ts","../../src/command-api/session/session-command-api.ts","../../src/command-api/checkpoint/rewind-command-api.ts","../../src/memory/memory-policy-evaluator.ts","../../src/memory/pending-memory-store.ts","../../src/command-api/memory/memory-command-api.ts","../../src/utils/skill-prompt.ts","../../src/commands/skill-executor.ts","../../src/interactive/interactive-session-skill-router.ts","../../src/interactive/interactive-session.ts","../../src/interactive/session-persistence.ts","../../src/query.ts","../../src/user-local/storage.ts","../../src/user-local/memory-types.ts","../../src/user-local/memory.ts","../../src/self-hosting/self-hosting-verification.ts","../../src/tools/command-execution-tool.ts","../../src/permissions/permission-prompt.ts","../../src/testing/create-test-interactive-session.ts","../../src/config/reset-user-config.ts","../../src/git/git-branch.ts","../../src/utils/semver-compare.ts","../../src/runtime/agent-runtime.ts","../../src/utils/read-package-version.ts","../../src/update-check/update-check.ts"],"sourcesContent":["import {\n isTerminalBackgroundTaskStatus,\n type IBackgroundTaskError,\n type IBackgroundTaskManager,\n type IBackgroundTaskState,\n type TBackgroundTaskEvent,\n type TBackgroundTaskStatus,\n} from '@robota-sdk/agent-executor';\n\nconst DEFAULT_SUMMARY_LENGTH = 1_000;\n\nexport type TBackgroundJobWaitPolicy = 'detached' | 'wait_all' | 'wait_any' | 'manual';\n\nexport type TBackgroundJobGroupStatus = 'running' | 'completed';\n\nexport interface IBackgroundJobResultEnvelope {\n taskId: string;\n label: string;\n status: TBackgroundTaskStatus;\n summary?: string;\n outputRef?: string;\n error?: IBackgroundTaskError;\n startedAt?: string;\n completedAt?: string;\n}\n\nexport interface IBackgroundJobGroupState {\n id: string;\n parentSessionId: string;\n waitPolicy: TBackgroundJobWaitPolicy;\n taskIds: string[];\n status: TBackgroundJobGroupStatus;\n createdAt: string;\n updatedAt: string;\n label?: string;\n completedAt?: string;\n results: IBackgroundJobResultEnvelope[];\n}\n\nexport interface IBackgroundJobGroupSummary {\n groupId: string;\n status: TBackgroundJobGroupStatus;\n total: number;\n completed: number;\n failed: number;\n cancelled: number;\n pending: number;\n lines: string[];\n}\n\nexport interface IBackgroundJobGroupCreateRequest {\n parentSessionId: string;\n waitPolicy: TBackgroundJobWaitPolicy;\n taskIds: string[];\n label?: string;\n}\n\nexport type TBackgroundJobGroupEvent =\n | { type: 'background_job_group_created'; group: IBackgroundJobGroupState }\n | { type: 'background_job_group_updated'; group: IBackgroundJobGroupState }\n | { type: 'background_job_group_completed'; group: IBackgroundJobGroupState };\n\nexport type TBackgroundJobGroupEventListener = (event: TBackgroundJobGroupEvent) => void;\n\nexport type TBackgroundJobGroupIdFactory = (request: IBackgroundJobGroupCreateRequest) => string;\n\nexport interface IBackgroundJobOrchestratorOptions {\n manager: IBackgroundTaskManager;\n now?: () => string;\n idFactory?: TBackgroundJobGroupIdFactory;\n initialGroups?: readonly IBackgroundJobGroupState[];\n}\n\ninterface IBackgroundJobGroupRecord {\n state: IBackgroundJobGroupState;\n completion: Promise<IBackgroundJobGroupState>;\n resolve: (state: IBackgroundJobGroupState) => void;\n}\n\nexport class BackgroundJobOrchestrator {\n private readonly manager: IBackgroundTaskManager;\n private readonly now: () => string;\n private readonly idFactory: TBackgroundJobGroupIdFactory;\n private readonly unsubscribeManager: () => void;\n private readonly listeners = new Set<TBackgroundJobGroupEventListener>();\n private readonly groups = new Map<string, IBackgroundJobGroupRecord>();\n private sequence = 0;\n\n constructor(options: IBackgroundJobOrchestratorOptions) {\n this.manager = options.manager;\n this.now = options.now ?? (() => new Date().toISOString());\n this.idFactory = options.idFactory ?? (() => this.nextGroupId());\n this.sequence = options.initialGroups?.length ?? 0;\n for (const group of options.initialGroups ?? []) this.restoreGroup(group);\n this.unsubscribeManager = this.manager.subscribe((event) => this.handleTaskEvent(event));\n }\n\n createGroup(request: IBackgroundJobGroupCreateRequest): IBackgroundJobGroupState {\n const now = this.now();\n const state: IBackgroundJobGroupState = {\n id: this.idFactory(request),\n parentSessionId: request.parentSessionId,\n waitPolicy: request.waitPolicy,\n taskIds: [...request.taskIds],\n status: 'running',\n createdAt: now,\n updatedAt: now,\n results: [],\n ...(request.label ? { label: request.label } : {}),\n };\n const record = this.createRecord(state);\n this.groups.set(state.id, record);\n this.captureExistingTerminalTasks(record);\n this.emit({ type: 'background_job_group_created', group: cloneGroup(record.state) });\n this.evaluateCompletion(record);\n return cloneGroup(record.state);\n }\n\n listGroups(): IBackgroundJobGroupState[] {\n return [...this.groups.values()].map((record) => cloneGroup(record.state));\n }\n\n getGroup(groupId: string): IBackgroundJobGroupState | undefined {\n const record = this.groups.get(groupId);\n return record ? cloneGroup(record.state) : undefined;\n }\n\n waitGroup(groupId: string): Promise<IBackgroundJobGroupState> {\n const record = this.groups.get(groupId);\n if (!record) return Promise.reject(new Error(`Unknown background job group: ${groupId}`));\n return record.completion;\n }\n\n subscribe(listener: TBackgroundJobGroupEventListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n dispose(): void {\n this.unsubscribeManager();\n this.listeners.clear();\n }\n\n private nextGroupId(): string {\n this.sequence += 1;\n return `group_${this.sequence}`;\n }\n\n private restoreGroup(group: IBackgroundJobGroupState): void {\n const record = this.createRecord(cloneGroup(group));\n this.groups.set(group.id, record);\n if (group.status === 'completed') record.resolve(cloneGroup(group));\n }\n\n private createRecord(state: IBackgroundJobGroupState): IBackgroundJobGroupRecord {\n let resolveGroup: (state: IBackgroundJobGroupState) => void = () => {};\n const completion = new Promise<IBackgroundJobGroupState>((resolve) => {\n resolveGroup = resolve;\n });\n return { state, completion, resolve: resolveGroup };\n }\n\n private captureExistingTerminalTasks(record: IBackgroundJobGroupRecord): void {\n for (const taskId of record.state.taskIds) {\n const task = this.manager.get(taskId);\n if (task && isTerminalBackgroundTaskStatus(task.status)) this.captureTask(record, task);\n }\n }\n\n private handleTaskEvent(event: TBackgroundTaskEvent): void {\n const task = getTerminalTask(event);\n if (!task) return;\n for (const record of this.groups.values()) {\n if (!record.state.taskIds.includes(task.id)) continue;\n if (!this.captureTask(record, task)) continue;\n if (record.state.status === 'running') this.evaluateCompletion(record);\n else this.emit({ type: 'background_job_group_updated', group: cloneGroup(record.state) });\n }\n }\n\n private captureTask(record: IBackgroundJobGroupRecord, task: IBackgroundTaskState): boolean {\n if (record.state.results.some((result) => result.taskId === task.id)) return false;\n record.state.results = [...record.state.results, createResultEnvelope(task)];\n record.state.updatedAt = this.now();\n return true;\n }\n\n private evaluateCompletion(record: IBackgroundJobGroupRecord): void {\n if (record.state.status === 'completed') return;\n if (!shouldComplete(record.state)) {\n this.emit({ type: 'background_job_group_updated', group: cloneGroup(record.state) });\n return;\n }\n const now = this.now();\n record.state.status = 'completed';\n record.state.completedAt = now;\n record.state.updatedAt = now;\n const completed = cloneGroup(record.state);\n record.resolve(completed);\n this.emit({ type: 'background_job_group_completed', group: completed });\n }\n\n private emit(event: TBackgroundJobGroupEvent): void {\n for (const listener of this.listeners) listener(event);\n }\n}\n\nfunction getTerminalTask(event: TBackgroundTaskEvent): IBackgroundTaskState | undefined {\n if (\n event.type === 'background_task_completed' ||\n event.type === 'background_task_failed' ||\n event.type === 'background_task_cancelled'\n ) {\n return event.task;\n }\n return undefined;\n}\n\nfunction shouldComplete(group: IBackgroundJobGroupState): boolean {\n if (group.waitPolicy === 'manual') return false;\n if (group.waitPolicy === 'wait_any') return group.results.length > 0;\n return group.taskIds.every((taskId) => group.results.some((result) => result.taskId === taskId));\n}\n\nfunction createResultEnvelope(task: IBackgroundTaskState): IBackgroundJobResultEnvelope {\n return {\n taskId: task.id,\n label: task.label,\n status: task.status,\n ...(task.result?.output ? { summary: summarizeOutput(task.result.output) } : {}),\n ...(task.transcriptPath || task.logPath\n ? { outputRef: task.transcriptPath ?? task.logPath }\n : {}),\n ...(task.error ? { error: { ...task.error } } : {}),\n ...(task.startedAt ? { startedAt: task.startedAt } : {}),\n ...(task.completedAt ? { completedAt: task.completedAt } : {}),\n };\n}\n\nfunction summarizeOutput(output: string): string {\n const trimmed = output.trim();\n if (trimmed.length <= DEFAULT_SUMMARY_LENGTH) return trimmed;\n return `${trimmed.slice(0, DEFAULT_SUMMARY_LENGTH)}...`;\n}\n\nexport function summarizeBackgroundJobGroup(\n group: IBackgroundJobGroupState,\n): IBackgroundJobGroupSummary {\n const completed = countResults(group, 'completed');\n const failed = countResults(group, 'failed');\n const cancelled = countResults(group, 'cancelled');\n return {\n groupId: group.id,\n status: group.status,\n total: group.taskIds.length,\n completed,\n failed,\n cancelled,\n pending: Math.max(group.taskIds.length - group.results.length, 0),\n lines: group.results.map((result) => formatResultLine(result)),\n };\n}\n\nfunction countResults(group: IBackgroundJobGroupState, status: TBackgroundTaskStatus): number {\n return group.results.filter((result) => result.status === status).length;\n}\n\nfunction formatResultLine(result: IBackgroundJobResultEnvelope): string {\n const detail = normalizeResultDetail(result);\n const output = result.outputRef && result.summary ? ` (output: ${result.outputRef})` : '';\n return `[${result.status}] ${result.label} ${result.taskId}: ${detail}${output}`;\n}\n\nfunction normalizeResultDetail(result: IBackgroundJobResultEnvelope): string {\n const detail = result.error?.message ?? result.summary ?? '';\n const normalized = detail.replace(/\\s+/g, ' ').trim();\n return normalized.length > 0 ? normalized : '(no summary)';\n}\n\nfunction cloneGroup(group: IBackgroundJobGroupState): IBackgroundJobGroupState {\n return {\n ...group,\n taskIds: [...group.taskIds],\n results: group.results.map((result) => ({\n ...result,\n ...(result.error ? { error: { ...result.error } } : {}),\n })),\n };\n}\n","import type { IBackgroundJobGroupState } from './background-job-orchestrator.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\nimport type {\n IBackgroundTaskLogCursor,\n IBackgroundTaskState,\n TBackgroundPrimitive,\n TBackgroundTaskKind,\n TBackgroundTaskStatus,\n} from '@robota-sdk/agent-executor';\n\nexport const MAIN_THREAD_ENTRY_PREFIX = 'main';\nexport const BACKGROUND_TASK_ENTRY_PREFIX = 'task';\nexport const BACKGROUND_GROUP_ENTRY_PREFIX = 'group';\nexport const ENTRY_ID_SEPARATOR = ':';\n\nexport const EXECUTION_ORIGIN_METADATA_KEYS = {\n kind: 'executionOriginKind',\n sessionId: 'executionOriginSessionId',\n turnId: 'executionOriginTurnId',\n commandName: 'executionOriginCommandName',\n toolCallId: 'executionOriginToolCallId',\n skillId: 'executionOriginSkillId',\n label: 'executionOriginLabel',\n} as const;\n\nexport type TExecutionEntryKind = 'main_thread' | 'background_task' | 'background_group';\nexport type TExecutionWorkspaceStatus = 'active' | 'idle' | TBackgroundTaskStatus;\nexport type TExecutionAttention = 'none' | 'unread' | 'failed' | 'permission' | 'completed';\nexport type TExecutionWorkspaceVisibility = 'default' | 'collapsed';\nexport type TExecutionControl = 'select' | 'cancel' | 'close' | 'send' | 'read_log' | 'wait';\nexport type TExecutionOriginKind =\n | 'user_prompt'\n | 'slash_command'\n | 'model_command'\n | 'tool_call'\n | 'skill'\n | 'transport'\n | 'system';\nexport type TExecutionDetailRecordKind =\n | 'message'\n | 'tool_activity'\n | 'process_output'\n | 'progress'\n | 'result'\n | 'error'\n | 'group_summary';\nexport type TExecutionWorkspaceUpdateCause = 'main_thread' | 'background_task' | 'background_group';\n\nexport interface IExecutionOrigin {\n readonly kind: TExecutionOriginKind;\n readonly sessionId: string;\n readonly turnId?: string;\n readonly commandName?: string;\n readonly toolCallId?: string;\n readonly skillId?: string;\n readonly label?: string;\n}\n\nexport interface IExecutionWorkspaceEntry {\n readonly id: string;\n readonly sourceId: string;\n readonly kind: TExecutionEntryKind;\n readonly parentId?: string;\n readonly groupId?: string;\n readonly origin: IExecutionOrigin;\n readonly taskKind?: TBackgroundTaskKind;\n readonly status: TExecutionWorkspaceStatus;\n readonly title: string;\n readonly subtitle?: string;\n readonly preview?: string;\n readonly currentAction?: string;\n readonly unread: boolean;\n readonly attention: TExecutionAttention;\n readonly visibility: TExecutionWorkspaceVisibility;\n readonly updatedAt: string;\n readonly controls: readonly TExecutionControl[];\n}\n\nexport interface IExecutionWorkspaceFilter {\n readonly includeMainThread?: boolean;\n readonly kinds?: readonly TExecutionEntryKind[];\n readonly visibility?: readonly TExecutionWorkspaceVisibility[];\n}\n\nexport interface IExecutionWorkspaceSnapshot {\n readonly sessionId: string;\n readonly selectedEntryId?: string;\n readonly updatedAt: string;\n readonly entries: readonly IExecutionWorkspaceEntry[];\n}\n\nexport interface IExecutionWorkspaceSnapshotOptions {\n readonly selectedEntryId?: string;\n readonly filter?: IExecutionWorkspaceFilter;\n}\n\nexport interface IExecutionWorkspaceEvent {\n readonly type: 'execution_workspace_updated';\n readonly cause: TExecutionWorkspaceUpdateCause;\n readonly entryId?: string;\n readonly snapshot: IExecutionWorkspaceSnapshot;\n}\n\nexport interface IExecutionDetailCursor {\n readonly offset: number;\n}\n\nexport interface IExecutionDetailRecord {\n readonly id: string;\n readonly kind: TExecutionDetailRecordKind;\n readonly text: string;\n readonly timestamp?: string;\n readonly sourceId?: string;\n}\n\nexport interface IExecutionDetailPage {\n readonly entryId: string;\n readonly cursor?: IExecutionDetailCursor;\n readonly nextCursor?: IExecutionDetailCursor;\n readonly records: readonly IExecutionDetailRecord[];\n}\n\nexport interface ICreateMainThreadEntryInput {\n readonly sessionId: string;\n readonly isExecuting: boolean;\n readonly hasPendingPrompt: boolean;\n readonly historyLength: number;\n readonly updatedAt: string;\n readonly preview?: string;\n}\n\nexport interface ICreateExecutionWorkspaceSnapshotInput {\n readonly sessionId: string;\n readonly mainThread: ICreateMainThreadEntryInput;\n readonly tasks: readonly IBackgroundTaskState[];\n readonly groups: readonly IBackgroundJobGroupState[];\n readonly selectedEntryId?: string;\n readonly filter?: IExecutionWorkspaceFilter;\n}\n\nexport interface IExecutionWorkspaceEntryRef {\n readonly kind: TExecutionEntryKind;\n readonly sourceId: string;\n}\n\nexport interface ICreateMainThreadDetailPageInput {\n readonly entryId: string;\n readonly history: readonly IHistoryEntry[];\n readonly cursor?: IExecutionDetailCursor;\n}\n\nexport interface ICreateLineDetailPageInput {\n readonly entryId: string;\n readonly lines: readonly string[];\n readonly cursor?: IBackgroundTaskLogCursor;\n readonly nextCursor?: IBackgroundTaskLogCursor;\n readonly kind?: TExecutionDetailRecordKind;\n}\n\nexport function createMainThreadExecutionEntryId(sessionId: string): string {\n return [MAIN_THREAD_ENTRY_PREFIX, sessionId].join(ENTRY_ID_SEPARATOR);\n}\n\nexport function createBackgroundTaskExecutionEntryId(taskId: string): string {\n return [BACKGROUND_TASK_ENTRY_PREFIX, taskId].join(ENTRY_ID_SEPARATOR);\n}\n\nexport function createBackgroundGroupExecutionEntryId(groupId: string): string {\n return [BACKGROUND_GROUP_ENTRY_PREFIX, groupId].join(ENTRY_ID_SEPARATOR);\n}\n\nexport function parseExecutionWorkspaceEntryId(\n entryId: string,\n): IExecutionWorkspaceEntryRef | undefined {\n const [prefix, sourceId] = entryId.split(ENTRY_ID_SEPARATOR, 2);\n if (!sourceId) return undefined;\n if (prefix === MAIN_THREAD_ENTRY_PREFIX) return { kind: 'main_thread', sourceId };\n if (prefix === BACKGROUND_TASK_ENTRY_PREFIX) return { kind: 'background_task', sourceId };\n if (prefix === BACKGROUND_GROUP_ENTRY_PREFIX) return { kind: 'background_group', sourceId };\n return undefined;\n}\n\nexport function createExecutionOriginMetadata(\n origin: IExecutionOrigin,\n): Record<string, TBackgroundPrimitive> {\n return {\n [EXECUTION_ORIGIN_METADATA_KEYS.kind]: origin.kind,\n [EXECUTION_ORIGIN_METADATA_KEYS.sessionId]: origin.sessionId,\n ...(origin.turnId ? { [EXECUTION_ORIGIN_METADATA_KEYS.turnId]: origin.turnId } : {}),\n ...(origin.commandName\n ? { [EXECUTION_ORIGIN_METADATA_KEYS.commandName]: origin.commandName }\n : {}),\n ...(origin.toolCallId\n ? { [EXECUTION_ORIGIN_METADATA_KEYS.toolCallId]: origin.toolCallId }\n : {}),\n ...(origin.skillId ? { [EXECUTION_ORIGIN_METADATA_KEYS.skillId]: origin.skillId } : {}),\n ...(origin.label ? { [EXECUTION_ORIGIN_METADATA_KEYS.label]: origin.label } : {}),\n };\n}\n","import { isTerminalBackgroundTaskStatus } from '@robota-sdk/agent-executor';\n\nimport {\n EXECUTION_ORIGIN_METADATA_KEYS,\n createBackgroundGroupExecutionEntryId,\n createBackgroundTaskExecutionEntryId,\n createMainThreadExecutionEntryId,\n type ICreateExecutionWorkspaceSnapshotInput,\n type ICreateMainThreadEntryInput,\n type IExecutionOrigin,\n type IExecutionWorkspaceEntry,\n type IExecutionWorkspaceFilter,\n type IExecutionWorkspaceSnapshot,\n type TExecutionAttention,\n type TExecutionControl,\n type TExecutionOriginKind,\n type TExecutionWorkspaceVisibility,\n} from './execution-workspace-types.js';\n\nimport type { IBackgroundJobGroupState } from './background-job-orchestrator.js';\nimport type { IBackgroundTaskState, TBackgroundPrimitive } from '@robota-sdk/agent-executor';\n\nconst PREVIEW_MAX_LENGTH = 120;\nconst SUCCESS_EXIT_CODE = 0;\n\nexport function createExecutionWorkspaceSnapshot(\n input: ICreateExecutionWorkspaceSnapshotInput,\n): IExecutionWorkspaceSnapshot {\n const taskGroupIds = createTaskGroupIdMap(input.groups);\n const entries = [\n createMainThreadEntry(input.mainThread),\n ...sortGroups(input.groups).map((group) => createBackgroundGroupEntry(group)),\n ...sortTasks(input.tasks).map((task) =>\n createBackgroundTaskEntry(task, taskGroupIds.get(task.id)),\n ),\n ].filter((entry) => matchesExecutionWorkspaceFilter(entry, input.filter));\n return {\n sessionId: input.sessionId,\n selectedEntryId:\n input.selectedEntryId ??\n entries.find((entry) => entry.kind === 'main_thread')?.id ??\n createMainThreadExecutionEntryId(input.sessionId),\n updatedAt: entries[0]?.updatedAt ?? input.mainThread.updatedAt,\n entries,\n };\n}\n\nfunction createMainThreadEntry(input: ICreateMainThreadEntryInput): IExecutionWorkspaceEntry {\n return {\n id: createMainThreadExecutionEntryId(input.sessionId),\n sourceId: input.sessionId,\n kind: 'main_thread',\n origin: { kind: 'user_prompt', sessionId: input.sessionId },\n status: input.isExecuting ? 'active' : 'idle',\n title: 'Main thread',\n subtitle: input.hasPendingPrompt ? 'prompt queued' : `${input.historyLength} history entries`,\n preview: trimPreview(input.preview),\n unread: false,\n attention: 'none',\n visibility: 'default',\n updatedAt: input.updatedAt,\n controls: ['select'],\n };\n}\n\nfunction createBackgroundTaskEntry(\n state: IBackgroundTaskState,\n groupId: string | undefined,\n): IExecutionWorkspaceEntry {\n return {\n id: createBackgroundTaskExecutionEntryId(state.id),\n sourceId: state.id,\n kind: 'background_task',\n parentId: state.parentTaskId\n ? createBackgroundTaskExecutionEntryId(state.parentTaskId)\n : createMainThreadExecutionEntryId(state.parentSessionId),\n ...(groupId ? { groupId: createBackgroundGroupExecutionEntryId(groupId) } : {}),\n origin: readExecutionOrigin(state.metadata, {\n kind: 'system',\n sessionId: state.parentSessionId,\n }),\n taskKind: state.kind,\n status: state.status,\n title: state.label,\n subtitle: createTaskSubtitle(state),\n preview: createTaskPreview(state),\n currentAction: state.currentAction,\n unread: state.unread,\n attention: createTaskAttention(state),\n visibility: createTaskVisibility(state),\n updatedAt: state.lastActivityAt ?? state.updatedAt,\n controls: createTaskControls(state),\n };\n}\n\nfunction createBackgroundGroupEntry(group: IBackgroundJobGroupState): IExecutionWorkspaceEntry {\n const preview = trimPreview(\n group.results.map((result) => result.summary ?? result.error?.message).join(' '),\n );\n return {\n id: createBackgroundGroupExecutionEntryId(group.id),\n sourceId: group.id,\n kind: 'background_group',\n parentId: createMainThreadExecutionEntryId(group.parentSessionId),\n origin: { kind: 'system', sessionId: group.parentSessionId, label: group.label },\n status: group.status,\n title: group.label ?? group.id,\n subtitle: `${group.results.length}/${group.taskIds.length} tasks`,\n preview,\n unread: false,\n attention: createGroupAttention(group),\n visibility: group.status === 'completed' ? 'collapsed' : 'default',\n updatedAt: group.updatedAt,\n controls: group.status === 'running' ? ['select', 'wait'] : ['select'],\n };\n}\n\nfunction readExecutionOrigin(\n metadata: Record<string, TBackgroundPrimitive> | undefined,\n fallback: IExecutionOrigin,\n): IExecutionOrigin {\n const kind = toExecutionOriginKind(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.kind]);\n const sessionId = toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.sessionId]);\n return {\n kind: kind ?? fallback.kind,\n sessionId: sessionId ?? fallback.sessionId,\n turnId: toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.turnId]) ?? fallback.turnId,\n commandName:\n toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.commandName]) ?? fallback.commandName,\n toolCallId:\n toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.toolCallId]) ?? fallback.toolCallId,\n skillId: toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.skillId]) ?? fallback.skillId,\n label: toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.label]) ?? fallback.label,\n };\n}\n\nfunction createTaskGroupIdMap(groups: readonly IBackgroundJobGroupState[]): Map<string, string> {\n return new Map(groups.flatMap((group) => group.taskIds.map((taskId) => [taskId, group.id])));\n}\n\nfunction createTaskControls(state: IBackgroundTaskState): readonly TExecutionControl[] {\n const controls: TExecutionControl[] = ['select'];\n if (isTerminalBackgroundTaskStatus(state.status)) controls.push('close');\n else controls.push('cancel');\n if (state.kind === 'agent' && state.status === 'running') controls.push('send');\n if (state.logPath || state.transcriptPath) controls.push('read_log');\n return controls;\n}\n\nfunction createTaskSubtitle(state: IBackgroundTaskState): string | undefined {\n if (state.kind === 'agent') return state.agentType ?? state.cwd;\n if (state.status === 'sleeping' && state.nextFireAt !== undefined) {\n return `next: ${formatNextFireAt(state.nextFireAt)}`;\n }\n return state.cwd;\n}\n\nfunction formatNextFireAt(isoString: string): string {\n const date = new Date(isoString);\n const now = new Date();\n const diffMs = date.getTime() - now.getTime();\n if (diffMs <= 0) return 'now';\n const diffSec = Math.round(diffMs / 1000);\n if (diffSec < 60) return `${diffSec}s`;\n const diffMin = Math.round(diffSec / 60);\n if (diffMin < 60) return `${diffMin}m`;\n return `${Math.round(diffMin / 60)}h`;\n}\n\nfunction createTaskPreview(state: IBackgroundTaskState): string | undefined {\n if (state.status === 'failed') return trimPreview(state.error?.message);\n if (state.status === 'completed') return trimPreview(state.result?.output);\n return trimPreview(state.promptPreview ?? state.commandPreview);\n}\n\nfunction createTaskAttention(state: IBackgroundTaskState): TExecutionAttention {\n if (state.status === 'failed') return 'failed';\n if (state.status === 'waiting_permission') return 'permission';\n if (state.unread) return 'unread';\n if (state.status === 'completed') return 'completed';\n return 'none';\n}\n\nfunction createTaskVisibility(state: IBackgroundTaskState): TExecutionWorkspaceVisibility {\n if (\n state.status === 'completed' &&\n !state.unread &&\n !state.error &&\n (state.result?.exitCode ?? SUCCESS_EXIT_CODE) === SUCCESS_EXIT_CODE &&\n !state.result?.signalCode &&\n !state.worktreePath &&\n !state.branchName\n ) {\n return 'collapsed';\n }\n return 'default';\n}\n\nfunction createGroupAttention(group: IBackgroundJobGroupState): TExecutionAttention {\n if (group.results.some((result) => result.status === 'failed')) return 'failed';\n if (group.status === 'completed') return 'completed';\n return 'none';\n}\n\nfunction matchesExecutionWorkspaceFilter(\n entry: IExecutionWorkspaceEntry,\n filter: IExecutionWorkspaceFilter | undefined,\n): boolean {\n if (!filter) return true;\n if (filter.includeMainThread === false && entry.kind === 'main_thread') return false;\n if (filter.kinds && !filter.kinds.includes(entry.kind)) return false;\n if (filter.visibility && !filter.visibility.includes(entry.visibility)) return false;\n return true;\n}\n\nfunction sortTasks(tasks: readonly IBackgroundTaskState[]): IBackgroundTaskState[] {\n return [...tasks].sort((left, right) =>\n (right.lastActivityAt ?? right.updatedAt).localeCompare(left.lastActivityAt ?? left.updatedAt),\n );\n}\n\nfunction sortGroups(groups: readonly IBackgroundJobGroupState[]): IBackgroundJobGroupState[] {\n return [...groups].sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));\n}\n\nfunction trimPreview(value: string | undefined): string | undefined {\n const normalized = value?.trim().replace(/\\s+/g, ' ');\n if (!normalized) return undefined;\n return normalized.length > PREVIEW_MAX_LENGTH\n ? `${normalized.slice(0, PREVIEW_MAX_LENGTH)}...`\n : normalized;\n}\n\nfunction toStringValue(value: TBackgroundPrimitive | undefined): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction toExecutionOriginKind(\n value: TBackgroundPrimitive | undefined,\n): TExecutionOriginKind | undefined {\n if (\n value === 'user_prompt' ||\n value === 'slash_command' ||\n value === 'model_command' ||\n value === 'tool_call' ||\n value === 'skill' ||\n value === 'transport' ||\n value === 'system'\n ) {\n return value;\n }\n return undefined;\n}\n","import type {\n ICreateLineDetailPageInput,\n ICreateMainThreadDetailPageInput,\n IExecutionDetailPage,\n} from './execution-workspace-types.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\n\nconst EXECUTION_DETAIL_PAGE_SIZE = 80;\n\nexport function createMainThreadDetailPage(\n input: ICreateMainThreadDetailPageInput,\n): IExecutionDetailPage {\n const offset = normalizeOffset(input.cursor?.offset);\n const page = input.history.slice(offset, offset + EXECUTION_DETAIL_PAGE_SIZE);\n const records = page.map((entry) => ({\n id: entry.id,\n kind: entry.category === 'chat' ? ('message' as const) : ('progress' as const),\n text: formatHistoryEntry(entry),\n timestamp: entry.timestamp.toISOString(),\n sourceId: entry.type,\n }));\n return {\n entryId: input.entryId,\n ...(input.cursor ? { cursor: input.cursor } : {}),\n ...(offset + page.length < input.history.length\n ? { nextCursor: { offset: offset + page.length } }\n : {}),\n records,\n };\n}\n\nexport function createLineDetailPage(input: ICreateLineDetailPageInput): IExecutionDetailPage {\n const offset = input.cursor?.offset ?? 0;\n const records = input.lines.map((line, index) => ({\n id: `${input.entryId}:${offset}:${index}`,\n kind: input.kind ?? ('process_output' as const),\n text: line,\n }));\n return {\n entryId: input.entryId,\n ...(input.cursor ? { cursor: input.cursor } : {}),\n ...(input.nextCursor ? { nextCursor: input.nextCursor } : {}),\n records,\n };\n}\n\nfunction normalizeOffset(offset: number | undefined): number {\n return typeof offset === 'number' && Number.isFinite(offset) && offset > 0\n ? Math.floor(offset)\n : 0;\n}\n\nfunction formatHistoryEntry(entry: IHistoryEntry): string {\n if (typeof entry.data === 'string') return entry.data;\n return entry.type;\n}\n","import {\n createExecutionOriginMetadata,\n type IExecutionOrigin,\n} from './execution-workspace-types.js';\n\nimport type { BackgroundJobOrchestrator } from './background-job-orchestrator.js';\nimport type {\n IBackgroundJobGroupCreateRequest,\n IBackgroundJobGroupState,\n} from './background-job-orchestrator.js';\nimport type {\n IAgentBackgroundTaskRequest,\n IBackgroundTaskManager,\n IBackgroundTaskState,\n IProcessBackgroundTaskRequest,\n TBackgroundPermissionPolicy,\n TBackgroundTaskIsolation,\n TBackgroundTaskMode,\n} from '@robota-sdk/agent-executor';\n\nexport interface ISpawnAgentTaskRequest {\n readonly label: string;\n readonly agentType: string;\n readonly prompt: string;\n readonly mode?: TBackgroundTaskMode;\n readonly parentTaskId?: string;\n readonly depth?: number;\n readonly cwd?: string;\n readonly model?: string;\n readonly isolation?: TBackgroundTaskIsolation;\n readonly allowedTools?: readonly string[];\n readonly disallowedTools?: readonly string[];\n readonly permissionPolicy?: TBackgroundPermissionPolicy;\n readonly timeoutMs?: number;\n readonly idleTimeoutMs?: number;\n readonly maxRuntimeMs?: number;\n readonly outputLimitBytes?: number;\n readonly maxTextDeltas?: number;\n readonly repetitionWindow?: number;\n readonly repetitionThreshold?: number;\n}\n\nexport interface ISpawnProcessTaskRequest {\n readonly command: string;\n readonly label?: string;\n readonly mode?: TBackgroundTaskMode;\n readonly parentTaskId?: string;\n readonly depth?: number;\n readonly cwd?: string;\n readonly shell?: string;\n readonly env?: Record<string, string>;\n readonly stdin?: string;\n readonly timeoutMs?: number;\n readonly idleTimeoutMs?: number;\n readonly maxRuntimeMs?: number;\n readonly outputLimitBytes?: number;\n}\n\nexport interface IBackgroundTaskSpawnerGroupRequest {\n readonly waitPolicy: IBackgroundJobGroupCreateRequest['waitPolicy'];\n readonly taskIds: readonly string[];\n readonly label?: string;\n}\n\nexport interface IExecutionWorkspaceTaskSpawner {\n spawnAgent(request: ISpawnAgentTaskRequest): Promise<IBackgroundTaskState>;\n spawnProcess(request: ISpawnProcessTaskRequest): Promise<IBackgroundTaskState>;\n createGroup(request: IBackgroundTaskSpawnerGroupRequest): IBackgroundJobGroupState;\n}\n\nexport interface ICreateExecutionWorkspaceTaskSpawnerOptions {\n readonly manager: IBackgroundTaskManager;\n readonly groupOrchestrator: BackgroundJobOrchestrator;\n readonly sessionId: string;\n readonly cwd: string;\n readonly origin: IExecutionOrigin;\n}\n\nexport function createExecutionWorkspaceTaskSpawner(\n options: ICreateExecutionWorkspaceTaskSpawnerOptions,\n): IExecutionWorkspaceTaskSpawner {\n return {\n spawnAgent: (request) => options.manager.spawn(createAgentRequest(options, request)),\n spawnProcess: (request) => options.manager.spawn(createProcessRequest(options, request)),\n createGroup: (request) =>\n options.groupOrchestrator.createGroup({\n parentSessionId: options.sessionId,\n waitPolicy: request.waitPolicy,\n taskIds: [...request.taskIds],\n label: request.label,\n }),\n };\n}\n\nfunction createAgentRequest(\n options: ICreateExecutionWorkspaceTaskSpawnerOptions,\n request: ISpawnAgentTaskRequest,\n): IAgentBackgroundTaskRequest {\n return {\n kind: 'agent',\n label: request.label,\n mode: request.mode ?? 'background',\n parentSessionId: options.sessionId,\n parentTaskId: request.parentTaskId,\n depth: request.depth ?? 1,\n cwd: request.cwd ?? options.cwd,\n agentType: request.agentType,\n prompt: request.prompt,\n model: request.model,\n isolation: request.isolation,\n allowedTools: request.allowedTools ? [...request.allowedTools] : undefined,\n disallowedTools: request.disallowedTools ? [...request.disallowedTools] : undefined,\n permissionPolicy: request.permissionPolicy ?? 'inherit-allowlist',\n timeoutMs: request.timeoutMs,\n idleTimeoutMs: request.idleTimeoutMs,\n maxRuntimeMs: request.maxRuntimeMs,\n outputLimitBytes: request.outputLimitBytes,\n maxTextDeltas: request.maxTextDeltas,\n repetitionWindow: request.repetitionWindow,\n repetitionThreshold: request.repetitionThreshold,\n metadata: createExecutionOriginMetadata(options.origin),\n };\n}\n\nfunction createProcessRequest(\n options: ICreateExecutionWorkspaceTaskSpawnerOptions,\n request: ISpawnProcessTaskRequest,\n): IProcessBackgroundTaskRequest {\n return {\n kind: 'process',\n label: request.label ?? request.command,\n mode: request.mode ?? 'background',\n parentSessionId: options.sessionId,\n parentTaskId: request.parentTaskId,\n depth: request.depth ?? 0,\n cwd: request.cwd ?? options.cwd,\n command: request.command,\n shell: request.shell,\n env: request.env,\n stdin: request.stdin,\n timeoutMs: request.timeoutMs,\n idleTimeoutMs: request.idleTimeoutMs,\n maxRuntimeMs: request.maxRuntimeMs,\n outputLimitBytes: request.outputLimitBytes,\n metadata: createExecutionOriginMetadata(options.origin),\n };\n}\n","import type { IBackgroundTaskManager } from './index.js';\n\nconst sessionBackgroundTaskManagers = new WeakMap<object, IBackgroundTaskManager>();\n\nexport function storeSessionBackgroundTaskManager(\n key: object,\n manager: IBackgroundTaskManager,\n): void {\n sessionBackgroundTaskManagers.set(key, manager);\n}\n\nexport function retrieveSessionBackgroundTaskManager(\n key: object,\n): IBackgroundTaskManager | undefined {\n return sessionBackgroundTaskManagers.get(key);\n}\n","import type { IAgentToolDeps } from './agent-tool.js';\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type {\n ISubagentJobResult,\n ISubagentManager,\n ISubagentSpawnRequest,\n} from '../subagents/index.js';\n\nexport interface IAgentToolBatchJobArgs {\n label?: string;\n prompt: string;\n subagent_type?: string;\n model?: string;\n isolation?: 'none' | 'worktree';\n}\n\ninterface IAgentBatchJobResult {\n index: number;\n success: boolean;\n groupId: string;\n label: string;\n agentId?: string;\n subagent_type: string;\n prompt: string;\n output?: string;\n error?: string;\n metadata?: ISubagentJobResult['metadata'];\n}\n\ninterface IResolvedBatchJob {\n index: number;\n job: IAgentToolBatchJobArgs;\n agentType: string;\n agentDef?: IAgentDefinition;\n label: string;\n}\n\ntype TValidResolvedBatchJob = IResolvedBatchJob & { agentDef: IAgentDefinition };\ntype TStartedBatchJob = TValidResolvedBatchJob &\n ({ agentId: string; spawnError?: undefined } | { agentId?: undefined; spawnError: string });\n\ninterface IRunManagedAgentBatchInput {\n jobs: IAgentToolBatchJobArgs[];\n deps: IAgentToolDeps;\n manager: ISubagentManager;\n resolveAgentDefinition: (\n agentType: string,\n customRegistry?: (name: string) => IAgentDefinition | undefined,\n ) => IAgentDefinition | undefined;\n createSpawnRequest: (\n args: IAgentToolBatchJobArgs,\n agentType: string,\n agentDef: IAgentDefinition,\n deps: IAgentToolDeps,\n label?: string,\n ) => ISubagentSpawnRequest;\n}\n\nfunction stringifyAgentBatchResult(input: {\n groupId: string;\n requestedJobCount: number;\n jobs: IAgentBatchJobResult[];\n}): string {\n const successfulJobs = input.jobs.filter((job) => job.success);\n const agentIds = input.jobs\n .map((job) => job.agentId)\n .filter((agentId): agentId is string => typeof agentId === 'string' && agentId.length > 0);\n const failedJobCount = input.jobs.filter((job) => !job.success).length;\n return JSON.stringify({\n success: input.jobs.every((job) => job.success),\n mode: 'batch',\n output: successfulJobs\n .map((job) => job.output ?? '')\n .filter(Boolean)\n .join('\\n\\n'),\n groupId: input.groupId,\n requestedJobCount: input.requestedJobCount,\n startedJobCount: agentIds.length,\n failedJobCount,\n agentIds,\n jobs: input.jobs,\n provenance: {\n source: 'agent-tool-batch',\n groupId: input.groupId,\n requestedJobCount: input.requestedJobCount,\n startedJobCount: agentIds.length,\n failedJobCount,\n },\n });\n}\n\nfunction createBatchGroupId(): string {\n const idRadix = 36;\n const randomStartIndex = 2;\n const randomEndIndex = 10;\n return `agent_group_${Date.now()}_${Math.random()\n .toString(idRadix)\n .slice(randomStartIndex, randomEndIndex)}`;\n}\n\nfunction normalizeJobLabel(label: string | undefined, fallback: string): string {\n const trimmed = label?.trim();\n return trimmed && trimmed.length > 0 ? trimmed : fallback;\n}\n\nfunction resolveBatchJob(\n job: IAgentToolBatchJobArgs,\n index: number,\n input: IRunManagedAgentBatchInput,\n): IResolvedBatchJob {\n const agentType = job.subagent_type ?? 'general-purpose';\n const agentDef = input.resolveAgentDefinition(agentType, input.deps.customAgentRegistry);\n const label = normalizeJobLabel(job.label, agentDef?.name ?? agentType);\n return { index, job, agentType, agentDef, label };\n}\n\nfunction isValidBatchJob(job: IResolvedBatchJob): job is TValidResolvedBatchJob {\n return job.agentDef !== undefined;\n}\n\nfunction createUnknownAgentBatchResult(\n job: IResolvedBatchJob,\n groupId: string,\n): IAgentBatchJobResult {\n return {\n index: job.index,\n success: false,\n groupId,\n label: job.label,\n subagent_type: job.agentType,\n prompt: job.job.prompt,\n error: `Unknown agent type: ${job.agentType}`,\n };\n}\n\nasync function spawnBatchJob(\n job: TValidResolvedBatchJob,\n input: IRunManagedAgentBatchInput,\n): Promise<TStartedBatchJob> {\n try {\n const state = await input.manager.spawn(\n input.createSpawnRequest(job.job, job.agentType, job.agentDef, input.deps, job.label),\n );\n return { ...job, agentId: state.id };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { ...job, spawnError: message };\n }\n}\n\nfunction createBatchSpawnErrorResult(job: TStartedBatchJob, groupId: string): IAgentBatchJobResult {\n return {\n index: job.index,\n success: false,\n groupId,\n label: job.label,\n subagent_type: job.agentType,\n prompt: job.job.prompt,\n error: `Sub-agent error: ${job.spawnError ?? 'missing agent id'}`,\n };\n}\n\nfunction createBatchSuccessResult(\n job: TStartedBatchJob & { agentId: string },\n groupId: string,\n result: ISubagentJobResult,\n): IAgentBatchJobResult {\n return {\n index: job.index,\n success: true,\n groupId,\n label: job.label,\n agentId: result.jobId,\n subagent_type: job.agentType,\n prompt: job.job.prompt,\n output: result.output,\n metadata: result.metadata,\n };\n}\n\nfunction createBatchWaitErrorResult(\n job: TStartedBatchJob & { agentId: string },\n groupId: string,\n message: string,\n): IAgentBatchJobResult {\n return {\n index: job.index,\n success: false,\n groupId,\n label: job.label,\n agentId: job.agentId,\n subagent_type: job.agentType,\n prompt: job.job.prompt,\n error: `Sub-agent error: ${message}`,\n };\n}\n\nasync function waitBatchJob(\n job: TStartedBatchJob,\n groupId: string,\n manager: ISubagentManager,\n): Promise<IAgentBatchJobResult> {\n if (job.agentId === undefined) {\n return createBatchSpawnErrorResult(job, groupId);\n }\n\n try {\n const result = await manager.wait(job.agentId);\n return createBatchSuccessResult({ ...job, agentId: job.agentId }, groupId, result);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return createBatchWaitErrorResult({ ...job, agentId: job.agentId }, groupId, message);\n }\n}\n\nexport async function runManagedAgentBatch(input: IRunManagedAgentBatchInput): Promise<string> {\n const groupId = createBatchGroupId();\n const resolvedJobs = input.jobs.map((job, index) => resolveBatchJob(job, index, input));\n const invalidJobs = resolvedJobs\n .filter((job) => !isValidBatchJob(job))\n .map((job) => createUnknownAgentBatchResult(job, groupId));\n const startedJobs = await Promise.all(\n resolvedJobs.filter(isValidBatchJob).map((job) => spawnBatchJob(job, input)),\n );\n const terminalJobs = await Promise.all(\n startedJobs.map((job) => waitBatchJob(job, groupId, input.manager)),\n );\n const batchJobs = [...invalidJobs, ...terminalJobs].sort(\n (left, right) => left.index - right.index,\n );\n\n return stringifyAgentBatchResult({\n groupId,\n requestedJobCount: input.jobs.length,\n jobs: batchJobs,\n });\n}\n","import type { ISubagentJobResult } from '../subagents/index.js';\n\nexport function stringifyUnknownAgentType(agentType: string): string {\n return JSON.stringify({\n success: false,\n mode: 'single',\n requestedJobCount: 1,\n startedJobCount: 0,\n failedJobCount: 1,\n output: '',\n error: `Unknown agent type: ${agentType}`,\n provenance: {\n source: 'agent-tool-single',\n requestedJobCount: 1,\n startedJobCount: 0,\n failedJobCount: 1,\n },\n });\n}\n\nexport function stringifyAgentSuccess(result: ISubagentJobResult): string {\n const worktreePath = result.metadata?.['worktreePath'];\n const branchName = result.metadata?.['branchName'];\n const worktreeStatus = result.metadata?.['worktreeStatus'];\n const worktreeNextAction = result.metadata?.['worktreeNextAction'];\n return JSON.stringify({\n success: true,\n mode: 'single',\n requestedJobCount: 1,\n startedJobCount: 1,\n failedJobCount: 0,\n output: result.output,\n agentId: result.jobId,\n agentIds: [result.jobId],\n provenance: {\n source: 'agent-tool-single',\n requestedJobCount: 1,\n startedJobCount: 1,\n failedJobCount: 0,\n },\n metadata: result.metadata,\n ...(typeof worktreePath === 'string' ? { worktreePath } : {}),\n ...(typeof branchName === 'string' ? { branchName } : {}),\n ...(typeof worktreeStatus === 'string' ? { worktreeStatus } : {}),\n ...(typeof worktreeNextAction === 'string' ? { worktreeNextAction } : {}),\n });\n}\n\nexport function stringifyAgentError(message: string, agentId?: string): string {\n const startedJobCount = agentId === undefined ? 0 : 1;\n return JSON.stringify({\n success: false,\n mode: 'single',\n requestedJobCount: 1,\n startedJobCount,\n failedJobCount: 1,\n output: '',\n error: `Sub-agent error: ${message}`,\n agentId,\n ...(agentId !== undefined ? { agentIds: [agentId] } : {}),\n provenance: {\n source: 'agent-tool-single',\n requestedJobCount: 1,\n startedJobCount,\n failedJobCount: 1,\n },\n });\n}\n","import type { IAgentDefinition } from './agent-definition-types.js';\n\nconst GENERAL_PURPOSE_SYSTEM_PROMPT = `You are a general-purpose task execution agent. You have access to all tools available in the parent session and can perform any task delegated to you.\n\nYour role is to complete the assigned task thoroughly and accurately. Follow these guidelines:\n\n- Execute the task as described in the prompt. Do not expand scope beyond what is requested.\n- Use the most appropriate tools for each step. Prefer precise tools (Read, Grep, Glob) over broad ones (Bash) when possible.\n- Report your findings clearly and concisely when the task is complete.\n- If a task cannot be completed, explain why and what information is missing.\n- Maintain the same code quality standards as the parent session (strict types, no fallbacks, proper error handling).`;\n\nconst EXPLORE_SYSTEM_PROMPT = `You are a codebase exploration and analysis agent. Your purpose is to search, read, and understand code without making any modifications.\n\nYou operate in read-only mode. You must NEVER attempt to write or edit files. Your tools are restricted to read-only operations: reading files, searching with grep and glob, and running non-destructive bash commands.\n\nYour role is to answer questions about the codebase by:\n\n- Searching for relevant files, symbols, and patterns using Glob and Grep.\n- Reading source files, configuration, and documentation to understand structure and behavior.\n- Tracing code paths across modules to understand how components interact.\n- Summarizing findings in a clear, structured format with file paths and line references.\n- Identifying architectural patterns, dependencies, and potential issues.\n\nWhen exploring, prefer targeted searches over broad scans. Start with the most likely locations and narrow down. Always include absolute file paths in your responses so the caller can navigate directly to relevant code.`;\n\nconst PLAN_SYSTEM_PROMPT = `You are a planning, research, and architecture agent. Your purpose is to analyze requirements, research approaches, and produce structured plans without making any code modifications.\n\nYou operate in read-only mode. You must NEVER attempt to write or edit files. Your tools are restricted to read-only operations.\n\nYour role is to:\n\n- Analyze the current codebase state relevant to the task by reading specs, source code, and tests.\n- Research implementation approaches by examining existing patterns and architectural conventions in the repository.\n- Identify affected files, modules, and interfaces that a proposed change would touch.\n- Assess risks, dependencies, and potential breaking changes.\n- Produce a structured implementation plan with clear steps, file lists, and ordering.\n- Consider edge cases, error handling, and test coverage requirements.\n\nOutput your plan in a structured format with numbered steps. For each step, specify which files are involved and what changes are needed. Flag any decisions that require human judgment or clarification.`;\n\n/**\n * All built-in agent definitions shipped with the SDK.\n * Order matters: general-purpose is the default fallback.\n */\nexport const BUILT_IN_AGENTS: IAgentDefinition[] = [\n {\n name: 'general-purpose',\n description: 'General-purpose task execution agent with full tool access.',\n systemPrompt: GENERAL_PURPOSE_SYSTEM_PROMPT,\n },\n {\n name: 'Explore',\n description: 'Read-only codebase exploration and analysis agent.',\n systemPrompt: EXPLORE_SYSTEM_PROMPT,\n disallowedTools: ['Write', 'Edit'],\n },\n {\n name: 'Plan',\n description: 'Read-only planning, research, and architecture agent.',\n systemPrompt: PLAN_SYSTEM_PROMPT,\n disallowedTools: ['Write', 'Edit'],\n },\n];\n\n/**\n * Look up a built-in agent definition by name.\n * Returns `undefined` if no built-in agent matches.\n */\nexport function getBuiltInAgent(name: string): IAgentDefinition | undefined {\n return BUILT_IN_AGENTS.find((agent) => agent.name === name);\n}\n","/**\n * Framework system prompt suffixes for subagent sessions.\n *\n * These functions generate the standard prompt content injected into\n * subagent sessions to control output format and behavior.\n */\n\n/** Options for assembling a subagent system prompt. */\nexport interface ISubagentPromptOptions {\n /** Agent definition markdown body. */\n agentBody: string;\n /** CLAUDE.md content to include. */\n claudeMd?: string;\n /** AGENTS.md content to include. */\n agentsMd?: string;\n /** When true, use fork worker suffix instead of standard subagent suffix. */\n isForkWorker: boolean;\n}\n\n/**\n * Returns the standard subagent suffix appended to agent body for normal subagents.\n */\nexport function getSubagentSuffix(): string {\n return `When you complete the task, respond with a concise report covering what was done and any key findings — the caller will relay this to the user, so it only needs the essentials.\n\nIn your final response, share file paths (always absolute, never relative) that are relevant to the task. Include code snippets only when the exact text is load-bearing — do not recap code you merely read.\n\nDo not use emojis.`;\n}\n\n/**\n * Returns the fork worker suffix for context:fork skill workers.\n */\nexport function getForkWorkerSuffix(): string {\n return `You are a worker subagent executing a specific task. Do NOT spawn sub-agents; execute directly. Keep your report under 500 words. Use this structure:\n- Scope: What was requested\n- Result: What was done\n- Key files: Relevant file paths (absolute)\n- Files changed: List of modifications\n- Issues: Any problems encountered`;\n}\n\n/**\n * Assembles the full system prompt for a subagent.\n *\n * Assembly order:\n * 1. Agent definition body\n * 2. CLAUDE.md content (if provided)\n * 3. AGENTS.md content (if provided)\n * 4. Framework suffix (fork worker OR standard subagent)\n */\nexport function assembleSubagentPrompt(options: ISubagentPromptOptions): string {\n const parts: string[] = [options.agentBody];\n\n if (options.claudeMd) {\n parts.push(options.claudeMd);\n }\n\n if (options.agentsMd) {\n parts.push(options.agentsMd);\n }\n\n const suffix = options.isForkWorker ? getForkWorkerSuffix() : getSubagentSuffix();\n parts.push(suffix);\n\n return parts.join('\\n\\n');\n}\n","import { createHash } from 'node:crypto';\n\nimport { createZodFunctionTool } from '@robota-sdk/agent-tools';\nimport { z } from 'zod';\n\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { ICommandResult } from '../commands/index.js';\nimport type { IZodSchema } from '@robota-sdk/agent-tools';\n\nexport const MODEL_COMMAND_TOOL_PREFIX = 'robota_command_' as const;\nexport const PROVIDER_SAFE_TOOL_NAME_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;\n\nconst MAX_PROVIDER_TOOL_NAME_LENGTH = 64;\nconst HASH_LENGTH = 8;\nconst HASH_SEPARATOR_LENGTH = 1;\n\ntype TModelCommandDescriptor = Pick<ICapabilityDescriptor, 'name' | 'description' | 'argumentHint'>;\n\ninterface IProjectedCommandArgs {\n args?: string;\n}\n\nexport interface IProjectedModelCommandTool {\n readonly commandName: string;\n readonly toolName: string;\n readonly description: string;\n readonly descriptor: TModelCommandDescriptor;\n}\n\nexport interface IModelCommandToolProjection {\n readonly commandTools: readonly IProjectedModelCommandTool[];\n readonly toolNameToCommandName: ReadonlyMap<string, string>;\n readonly commandNameToToolName: ReadonlyMap<string, string>;\n}\n\nexport interface IProjectedCommandExecutionToolsDeps {\n isModelInvocable: (command: string) => boolean;\n execute: (command: string, args: string) => Promise<ICommandResult | null>;\n commandDescriptors: readonly TModelCommandDescriptor[];\n}\n\nfunction asZodSchema(schema: z.ZodType): IZodSchema {\n return schema as IZodSchema;\n}\n\nexport function normalizeModelCommandName(command: string): string {\n return command.trim().replace(/^\\/+/, '').split(/\\s+/)[0] ?? '';\n}\n\nexport function createProviderSafeModelCommandToolName(commandName: string): string {\n const normalizedCommandName = normalizeModelCommandName(commandName);\n if (!normalizedCommandName) {\n throw new Error('Model command descriptor name must not be empty.');\n }\n\n const safeBody = normalizedCommandName\n .replace(/[^A-Za-z0-9_-]/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_+|_+$/g, '');\n if (!safeBody) {\n throw new Error(`Model command descriptor name cannot be projected safely: ${commandName}`);\n }\n\n const rawToolName = `${MODEL_COMMAND_TOOL_PREFIX}${safeBody}`;\n if (PROVIDER_SAFE_TOOL_NAME_PATTERN.test(rawToolName)) {\n return rawToolName;\n }\n\n const hash = createHash('sha256')\n .update(normalizedCommandName)\n .digest('hex')\n .slice(0, HASH_LENGTH);\n const maxBodyLength =\n MAX_PROVIDER_TOOL_NAME_LENGTH -\n MODEL_COMMAND_TOOL_PREFIX.length -\n HASH_SEPARATOR_LENGTH -\n HASH_LENGTH;\n if (maxBodyLength < 1) {\n throw new Error('Model command tool prefix leaves no room for command names.');\n }\n\n const truncatedBody = safeBody.slice(0, maxBodyLength).replace(/[_-]+$/g, '') || 'command';\n const toolName = `${MODEL_COMMAND_TOOL_PREFIX}${truncatedBody}_${hash}`;\n if (!PROVIDER_SAFE_TOOL_NAME_PATTERN.test(toolName)) {\n throw new Error(`Projected model command tool name is not provider-safe: ${toolName}`);\n }\n return toolName;\n}\n\nexport function createModelCommandToolProjection(\n commandDescriptors: readonly TModelCommandDescriptor[],\n): IModelCommandToolProjection {\n const commandNames = new Set<string>();\n const toolNameToCommandName = new Map<string, string>();\n const commandNameToToolName = new Map<string, string>();\n const commandTools: IProjectedModelCommandTool[] = [];\n\n for (const descriptor of commandDescriptors) {\n const commandName = normalizeModelCommandName(descriptor.name);\n if (!commandName) {\n throw new Error('Model command descriptor name must not be empty.');\n }\n if (commandNames.has(commandName)) {\n throw new Error(`Duplicate model command descriptor: ${commandName}`);\n }\n commandNames.add(commandName);\n\n const toolName = createProviderSafeModelCommandToolName(commandName);\n const existingCommandName = toolNameToCommandName.get(toolName);\n if (existingCommandName !== undefined) {\n throw new Error(\n `Model command projection collision: ${existingCommandName} and ${commandName} both map to ${toolName}`,\n );\n }\n\n toolNameToCommandName.set(toolName, commandName);\n commandNameToToolName.set(commandName, toolName);\n commandTools.push({\n commandName,\n toolName,\n description: formatProjectedModelCommandToolDescription(commandName, descriptor),\n descriptor,\n });\n }\n\n return {\n commandTools,\n toolNameToCommandName,\n commandNameToToolName,\n };\n}\n\nexport function formatProjectedModelCommandToolPromptDescription(\n projection: IProjectedModelCommandTool,\n): string {\n return `${projection.toolName} — ${projection.descriptor.description}`;\n}\n\nexport function stringifyModelCommandResult(\n command: string,\n result: ICommandResult | null,\n): string {\n if (!result) {\n return JSON.stringify({\n success: false,\n command,\n error: `Unknown command: ${command}`,\n });\n }\n return JSON.stringify({\n success: result.success,\n command,\n message: result.message,\n data: result.data,\n });\n}\n\nexport function createProjectedCommandExecutionTools(\n deps: IProjectedCommandExecutionToolsDeps,\n): Array<ReturnType<typeof createZodFunctionTool>> {\n const projection = createModelCommandToolProjection(deps.commandDescriptors);\n return projection.commandTools.map((projectedTool) => {\n const schema = createProjectedCommandArgsSchema(projectedTool.descriptor);\n return createZodFunctionTool(\n projectedTool.toolName,\n projectedTool.description,\n asZodSchema(schema),\n async (params) => {\n const parsedParams: IProjectedCommandArgs = schema.parse(params);\n if (!deps.isModelInvocable(projectedTool.commandName)) {\n return JSON.stringify({\n success: false,\n command: projectedTool.commandName,\n error: `Command is not model-invocable: ${projectedTool.commandName}`,\n });\n }\n return stringifyModelCommandResult(\n projectedTool.commandName,\n await deps.execute(projectedTool.commandName, parsedParams.args ?? ''),\n );\n },\n );\n });\n}\n\nfunction createProjectedCommandArgsSchema(\n descriptor: TModelCommandDescriptor,\n): z.ZodType<IProjectedCommandArgs> {\n const argsDescription = descriptor.argumentHint\n ? `Arguments for the command. Expected grammar: ${descriptor.argumentHint}`\n : 'Arguments for the command as a single string.';\n\n return z.object({\n args: z.string().optional().describe(argsDescription),\n });\n}\n\nfunction formatProjectedModelCommandToolDescription(\n commandName: string,\n descriptor: TModelCommandDescriptor,\n): string {\n const lines = [descriptor.description.trim(), `Robota command id: ${commandName}.`];\n if (descriptor.argumentHint) {\n lines.push(`Argument grammar: ${descriptor.argumentHint}`);\n }\n return lines.filter((line) => line.length > 0).join('\\n\\n');\n}\n","/**\n * Subagent session factory — assembles an isolated child Session for subagent execution.\n *\n * Unlike `createSession`, this factory does not load config files or context from disk.\n * It receives pre-resolved config and context from the parent session, applies tool\n * filtering and model resolution from the agent definition, and creates a lightweight\n * Session suitable for subagent use.\n */\n\nimport { Session } from '@robota-sdk/agent-session';\n\nimport { assembleSubagentPrompt } from './subagent-prompts.js';\nimport { createProviderSafeModelCommandToolName } from '../tools/model-command-tool-projection.js';\n\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type { IResolvedConfig } from '../config/config-types.js';\nimport type { ILoadedContext } from '../context/context-loader.js';\nimport type { IToolWithEventService, IHookTypeExecutor } from '@robota-sdk/agent-core';\nimport type { TPermissionMode, TToolArgs } from '@robota-sdk/agent-core';\nimport type { IAIProvider } from '@robota-sdk/agent-core';\nimport type {\n ISessionLogger,\n ITerminalOutput,\n TPermissionHandler,\n} from '@robota-sdk/agent-session';\n\n/** Model shortcut names mapped to full Anthropic model IDs. */\nconst MODEL_SHORTCUTS: Record<string, string> = {\n sonnet: 'claude-sonnet-4-6',\n haiku: 'claude-haiku-4-5',\n opus: 'claude-opus-4-6',\n};\nconst LEGACY_AGENT_TOOL_NAME = 'Agent';\nconst PROJECTED_AGENT_COMMAND_TOOL_NAME = createProviderSafeModelCommandToolName('agent');\n\n/** Options for creating a subagent session. */\nexport interface ISubagentOptions {\n /** Agent definition (built-in or custom). */\n agentDefinition: IAgentDefinition;\n /** Parent's resolved config (for provider, permissions, etc.). */\n parentConfig: IResolvedConfig;\n /** Parent's loaded context (CLAUDE.md, AGENTS.md). */\n parentContext: ILoadedContext;\n /** Parent session's available tools (to inherit/filter). */\n parentTools: IToolWithEventService[];\n /** AI provider instance. */\n provider: IAIProvider;\n /** Terminal output interface. */\n terminal: ITerminalOutput;\n /** Stable session ID for transcript files. */\n sessionId?: string;\n /** Optional logger for subagent transcripts. */\n sessionLogger?: ISessionLogger;\n /** Whether this is a fork worker (uses fork suffix instead of standard). */\n isForkWorker?: boolean;\n /** Permission mode from parent (bypassPermissions, acceptEdits, etc.). */\n permissionMode?: TPermissionMode;\n /** Permission handler from parent. */\n permissionHandler?: TPermissionHandler;\n /** Plugin hooks configuration from parent session. */\n hooks?: Record<string, unknown>;\n /** Hook type executors from parent session (prompt, agent, etc.). */\n hookTypeExecutors?: IHookTypeExecutor[];\n /** Streaming callback. */\n onTextDelta?: (delta: string) => void;\n /** Tool execution callback. */\n onToolExecution?: (event: {\n type: 'start' | 'end';\n toolName: string;\n toolArgs?: TToolArgs;\n success?: boolean;\n denied?: boolean;\n toolResultData?: string;\n }) => void;\n}\n\n/**\n * Resolve a model shortcut name to a full model ID.\n * Returns the shortcut mapping if found, otherwise returns the input as-is.\n */\nfunction resolveModelId(shortName: string, _parentModel: string): string {\n return MODEL_SHORTCUTS[shortName] ?? shortName;\n}\n\n/**\n * Filter parent tools according to the agent definition's tool constraints.\n *\n * Filtering order:\n * 1. Remove disallowed tools (denylist)\n * 2. Keep only allowed tools (allowlist), if specified\n * 3. Always remove agent-spawning tools (subagents cannot spawn subagents)\n */\nfunction filterTools(\n parentTools: IToolWithEventService[],\n agentDefinition: IAgentDefinition,\n): IToolWithEventService[] {\n let tools = [...parentTools];\n\n // Step 1: Remove disallowed tools\n if (agentDefinition.disallowedTools) {\n const denySet = new Set(agentDefinition.disallowedTools);\n tools = tools.filter((t) => !denySet.has(t.getName()));\n }\n\n // Step 2: Keep only allowed tools (if allowlist specified)\n if (agentDefinition.tools) {\n const allowSet = new Set(agentDefinition.tools);\n tools = tools.filter((t) => allowSet.has(t.getName()));\n }\n\n // Step 3: Always remove agent-spawning tools\n tools = tools.filter(\n (t) =>\n t.getName() !== LEGACY_AGENT_TOOL_NAME && t.getName() !== PROJECTED_AGENT_COMMAND_TOOL_NAME,\n );\n\n return tools;\n}\n\n/**\n * Create a fully-configured Session for subagent execution.\n *\n * Assembles provider, tools, and system prompt from parent context and\n * agent definition, then returns a new Session instance.\n */\nexport function createSubagentSession(options: ISubagentOptions): Session {\n const { agentDefinition, parentConfig, parentContext, parentTools, terminal } = options;\n\n // Filter tools based on agent definition constraints\n const tools = filterTools(parentTools, agentDefinition);\n\n // Resolve model: agent override or parent model\n const model = agentDefinition.model\n ? resolveModelId(agentDefinition.model, parentConfig.provider.model)\n : parentConfig.provider.model;\n\n // Assemble system prompt with framework suffix\n const systemMessage = assembleSubagentPrompt({\n agentBody: agentDefinition.systemPrompt,\n claudeMd: parentContext.claudeMd,\n agentsMd: parentContext.agentsMd,\n isForkWorker: options.isForkWorker ?? false,\n });\n\n const provider = options.provider;\n\n return new Session({\n tools,\n provider,\n systemMessage,\n terminal,\n ...(options.sessionId !== undefined ? { sessionId: options.sessionId } : {}),\n ...(options.sessionLogger !== undefined ? { sessionLogger: options.sessionLogger } : {}),\n model,\n maxTurns: agentDefinition.maxTurns,\n permissions: parentConfig.permissions,\n permissionMode: options.permissionMode,\n defaultTrustLevel: parentConfig.defaultTrustLevel,\n permissionHandler: options.permissionHandler,\n hooks: options.hooks,\n hookTypeExecutors: options.hookTypeExecutors,\n onTextDelta: options.onTextDelta,\n onToolExecution: options.onToolExecution,\n });\n}\n","import { getBuiltInAgent } from '../agents/built-in-agents.js';\nimport { createSubagentSession } from '../assembly/create-subagent-session.js';\n\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type { ISubagentOptions } from '../assembly/create-subagent-session.js';\nimport type { IResolvedConfig } from '../config/config-types.js';\nimport type { ILoadedContext } from '../context/context-loader.js';\nimport type { ITerminalOutput } from '@robota-sdk/agent-core';\nimport type {\n IAIProvider,\n IHookTypeExecutor,\n IToolWithEventService,\n TPermissionMode,\n TToolArgs,\n} from '@robota-sdk/agent-core';\nimport type {\n ISubagentJobHandle,\n ISubagentJobStart,\n ISubagentRunner,\n} from '@robota-sdk/agent-executor';\nimport type { TPermissionHandler } from '@robota-sdk/agent-session';\n\ntype TSubagentToolExecutionEvent = Parameters<\n NonNullable<IInProcessSubagentRunnerDeps['onToolExecution']>\n>[0];\n\nexport interface IInProcessSubagentRunnerDeps {\n config: IResolvedConfig;\n context: ILoadedContext;\n tools: IToolWithEventService[];\n terminal: ITerminalOutput;\n provider: IAIProvider;\n permissionMode?: TPermissionMode;\n permissionHandler?: TPermissionHandler;\n hooks?: ISubagentOptions['hooks'];\n hookTypeExecutors?: IHookTypeExecutor[];\n onTextDelta?: (delta: string) => void;\n onToolExecution?: (event: {\n type: 'start' | 'end';\n toolName: string;\n toolArgs?: TToolArgs;\n success?: boolean;\n denied?: boolean;\n toolResultData?: string;\n }) => void;\n customAgentRegistry?: (name: string) => IAgentDefinition | undefined;\n}\n\nexport type TSubagentRunnerFactory = (deps: IInProcessSubagentRunnerDeps) => ISubagentRunner;\n\nfunction resolveAgentDefinition(\n agentType: string,\n customRegistry?: (name: string) => IAgentDefinition | undefined,\n): IAgentDefinition {\n const definition = customRegistry?.(agentType) ?? getBuiltInAgent(agentType);\n if (!definition) {\n throw new Error(`Unknown agent type: ${agentType}`);\n }\n return definition;\n}\n\nfunction applyRequestOverrides(\n definition: IAgentDefinition,\n job: ISubagentJobStart,\n): IAgentDefinition {\n return {\n ...definition,\n ...(job.request.model ? { model: job.request.model } : {}),\n ...(job.request.allowedTools ? { tools: job.request.allowedTools } : {}),\n ...(job.request.disallowedTools ? { disallowedTools: job.request.disallowedTools } : {}),\n };\n}\n\nfunction extractFirstArg(toolArgs?: TToolArgs): string | undefined {\n if (!toolArgs) return undefined;\n const firstValue = Object.values(toolArgs)[0];\n if (firstValue === undefined) return undefined;\n return typeof firstValue === 'object' ? JSON.stringify(firstValue) : String(firstValue);\n}\n\nfunction assertSupportedIsolation(job: ISubagentJobStart): void {\n if (job.request.isolation === 'worktree') {\n throw new Error('Worktree isolation requires a runtime shell subagent runner');\n }\n}\n\nfunction emitToolExecutionEvent(job: ISubagentJobStart, event: TSubagentToolExecutionEvent): void {\n if (event.type === 'start') {\n job.emit?.({\n type: 'background_task_tool_start',\n toolName: event.toolName,\n firstArg: extractFirstArg(event.toolArgs),\n });\n return;\n }\n\n job.emit?.({\n type: 'background_task_tool_end',\n toolName: event.toolName,\n success: event.success ?? true,\n });\n}\n\nexport function createInProcessSubagentRunner(deps: IInProcessSubagentRunnerDeps): ISubagentRunner {\n return {\n start(job: ISubagentJobStart): ISubagentJobHandle {\n assertSupportedIsolation(job);\n const definition = resolveAgentDefinition(job.request.type, deps.customAgentRegistry);\n const session = createSubagentSession({\n agentDefinition: applyRequestOverrides(definition, job),\n parentConfig: deps.config,\n parentContext: deps.context,\n parentTools: deps.tools,\n provider: deps.provider,\n terminal: deps.terminal,\n permissionMode: deps.permissionMode,\n permissionHandler: deps.permissionHandler,\n hooks: deps.hooks,\n hookTypeExecutors: deps.hookTypeExecutors,\n onTextDelta: (delta) => {\n job.emit?.({ type: 'background_task_text_delta', delta });\n deps.onTextDelta?.(delta);\n },\n onToolExecution: (event) => {\n emitToolExecutionEvent(job, event);\n deps.onToolExecution?.(event);\n },\n });\n\n return {\n jobId: job.jobId,\n result: session.run(job.request.prompt).then((output) => ({\n jobId: job.jobId,\n output,\n })),\n cancel: () => {\n session.abort();\n return Promise.resolve();\n },\n };\n },\n };\n}\n","/**\n * AgentTool — spawn a sub-agent with isolated context.\n *\n * Uses `SubagentManager` with an in-process runner to assemble a child Session\n * with filtered tools, model resolution, and framework system prompt. The\n * sub-agent shares the same config and context but has its own conversation\n * history.\n *\n * Each call to `createAgentTool(deps)` returns a fresh tool instance with deps\n * captured in closure, eliminating module-level mutable state and enabling\n * multiple concurrent sessions without race conditions.\n */\n\nimport { SubagentManager } from '@robota-sdk/agent-executor';\nimport { createZodFunctionTool } from '@robota-sdk/agent-tools';\nimport { z } from 'zod';\n\nimport { runManagedAgentBatch } from './agent-tool-batch.js';\nimport {\n stringifyAgentError,\n stringifyAgentSuccess,\n stringifyUnknownAgentType,\n} from './agent-tool-output.js';\nimport { getBuiltInAgent } from '../agents/built-in-agents.js';\nimport { createExecutionOriginMetadata } from '../background-tasks/index.js';\nimport { createInProcessSubagentRunner } from '../subagents/in-process-subagent-runner.js';\n\nimport type { IAgentToolBatchJobArgs } from './agent-tool-batch.js';\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type { IBackgroundTaskManager } from '../background-tasks/index.js';\nimport type {\n IInProcessSubagentRunnerDeps,\n ISubagentManager,\n ISubagentJobResult,\n ISubagentSpawnRequest,\n} from '../subagents/index.js';\nimport type { IZodSchema } from '@robota-sdk/agent-tools';\n\nexport const AGENT_TOOL_DESCRIPTION = [\n 'Creates delegated subagent jobs in isolated contexts.',\n 'Without jobs, one tool call creates one subagent job from prompt.',\n 'For explicit multi-agent or parallel-agent requests, use one Agent tool call with jobs containing one entry per requested role and a stable label for each role.',\n 'When the user explicitly asks to create, run, spawn, delegate to, or use agents/subagents, start the requested subagent job immediately.',\n 'Do not ask a follow-up question unless execution is impossible or unsafe.',\n 'Subagent jobs run as background tasks by default.',\n 'The tool waits for a terminal result and returns completed, failed, or timed-out outcome data with structured requested/started job counts.',\n 'After the tool returns, base user-facing claims on returned mode and counts; do not say parallel or multiple jobs started unless the result proves those jobs started.',\n 'Execution is represented by a real tool call and runtime background task event.',\n].join(' ');\n\nexport function createAgentToolPromptDescription(\n agentDefinitions: readonly Pick<IAgentDefinition, 'name' | 'description'>[] = [],\n): string {\n const availableAgents =\n agentDefinitions.length > 0\n ? ` Available agent types: ${agentDefinitions\n .map((agent) => `${agent.name} (${agent.description})`)\n .join(', ')}.`\n : '';\n return [\n 'Agent — creates isolated subagent jobs.',\n 'Without jobs, one Agent tool call corresponds to one subagent job.',\n 'For explicit multi-agent or parallel-agent requests, use one Agent tool call with jobs containing one entry per requested role and a stable label for each role.',\n 'When the user explicitly asks to create, run, spawn, delegate to, or use agents/subagents, start the requested subagent job immediately.',\n 'Do not ask a follow-up question unless execution is impossible or unsafe.',\n 'The tool returns terminal result data with mode, requestedJobCount, startedJobCount, failedJobCount, and provenance.',\n 'After the tool returns, base user-facing claims on returned mode and counts; do not say parallel or multiple jobs started unless the result proves those jobs started.',\n 'Runtime mode is background.',\n availableAgents,\n ]\n .join(' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/** Cast a Zod schema to the IZodSchema interface expected by createZodFunctionTool */\nfunction asZodSchema(schema: z.ZodType): IZodSchema {\n return schema as IZodSchema;\n}\n\nconst AgentSchema = z\n .object({\n prompt: z\n .string()\n .optional()\n .describe('The task for a single subagent to perform. Required when jobs is omitted.'),\n subagent_type: z\n .string()\n .optional()\n .describe('Agent type: \"general-purpose\", \"Explore\", \"Plan\", or a custom agent name'),\n model: z.string().optional().describe('Optional model override'),\n isolation: z\n .enum(['none', 'worktree'])\n .optional()\n .describe('Optional runtime isolation mode. \"worktree\" runs in a Git worktree.'),\n jobs: z\n .array(\n z\n .object({\n label: z.string().optional().describe('Stable role label for this batch job'),\n prompt: z.string().describe('The task for this subagent to perform'),\n subagent_type: z.string().optional().describe('Agent type for this job'),\n model: z.string().optional().describe('Optional model override for this job'),\n isolation: z.enum(['none', 'worktree']).optional().describe('Isolation for this job'),\n })\n .passthrough(),\n )\n .optional()\n .describe('Batch of subagent jobs to start in one Agent tool call'),\n })\n .passthrough();\n\ntype TAgentArgs = z.infer<typeof AgentSchema>;\ntype TAgentJobArgs = IAgentToolBatchJobArgs;\ntype TSingleAgentArgs = TAgentArgs & { prompt: string };\n\n/** Dependencies injected at creation time via createAgentTool factory */\nexport interface IAgentToolDeps extends IInProcessSubagentRunnerDeps {\n cwd?: string;\n parentSessionId?: string;\n subagentDepth?: number;\n subagentManager?: ISubagentManager;\n backgroundTaskManager?: IBackgroundTaskManager;\n /** Optional custom agent registry for resolving non-built-in agent types. */\n customAgentRegistry?: (name: string) => IAgentDefinition | undefined;\n /** Model-visible and command-visible agent definitions available to this session. */\n agentDefinitions?: IAgentDefinition[];\n}\n\n/**\n * Per-session deps store — maps an opaque key (typically a Session instance) to\n * the IAgentToolDeps used when creating that session's agent tool.\n *\n * This replaces the former module-level singleton, enabling concurrent sessions\n * without overwriting each other's deps.\n */\nconst sessionDepsStore = new WeakMap<object, IAgentToolDeps>();\n\n/** Store agent tool deps keyed by a session (or any object). */\nexport function storeAgentToolDeps(key: object, deps: IAgentToolDeps): void {\n sessionDepsStore.set(key, deps);\n}\n\n/** Retrieve agent tool deps for a given session key. */\nexport function retrieveAgentToolDeps(key: object): IAgentToolDeps | undefined {\n return sessionDepsStore.get(key);\n}\n\n/**\n * Resolve an agent type name to an IAgentDefinition.\n * Checks custom registry first so project/user definitions can override built-ins.\n */\nfunction resolveAgentDefinition(\n agentType: string,\n customRegistry?: (name: string) => IAgentDefinition | undefined,\n): IAgentDefinition | undefined {\n if (customRegistry) {\n const custom = customRegistry(agentType);\n if (custom) return custom;\n }\n const builtIn = getBuiltInAgent(agentType);\n if (builtIn) return builtIn;\n return undefined;\n}\n\nfunction createSubagentManager(deps: IAgentToolDeps): ISubagentManager {\n return (\n deps.subagentManager ??\n new SubagentManager({\n runner: createInProcessSubagentRunner(deps),\n })\n );\n}\n\nfunction createSpawnRequest(\n args: TSingleAgentArgs | TAgentJobArgs,\n agentType: string,\n agentDef: IAgentDefinition,\n deps: IAgentToolDeps,\n label = agentDef.name,\n): ISubagentSpawnRequest {\n return {\n type: agentType,\n label,\n parentSessionId: deps.parentSessionId ?? 'unknown-session',\n mode: 'background',\n depth: deps.subagentDepth ?? 1,\n cwd: deps.cwd ?? process.cwd(),\n prompt: args.prompt,\n model: args.model,\n isolation: args.isolation,\n metadata: createExecutionOriginMetadata({\n kind: 'tool_call',\n sessionId: deps.parentSessionId ?? 'unknown-session',\n label,\n }),\n };\n}\n\nasync function runManagedAgent(\n args: TAgentArgs,\n deps: IAgentToolDeps,\n manager: ISubagentManager,\n): Promise<string> {\n if (typeof args.prompt !== 'string' || args.prompt.length === 0) {\n return stringifyAgentError('prompt is required when jobs is omitted');\n }\n\n const singleArgs: TSingleAgentArgs = { ...args, prompt: args.prompt };\n const agentType = args.subagent_type ?? 'general-purpose';\n const agentDef = resolveAgentDefinition(agentType, deps.customAgentRegistry);\n if (!agentDef) {\n return stringifyUnknownAgentType(agentType);\n }\n\n let agentId: string | undefined;\n try {\n const state = await manager.spawn(createSpawnRequest(singleArgs, agentType, agentDef, deps));\n agentId = state.id;\n const response = await manager.wait(state.id);\n return stringifyAgentSuccess(response);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return stringifyAgentError(message, agentId);\n }\n}\n\n/**\n * Create an agent tool instance with deps captured in closure.\n *\n * Each session gets its own tool instance — no shared mutable state.\n */\nexport function createAgentTool(deps: IAgentToolDeps): ReturnType<typeof createZodFunctionTool> {\n const manager = createSubagentManager(deps);\n\n return createZodFunctionTool(\n 'Agent',\n AGENT_TOOL_DESCRIPTION,\n asZodSchema(AgentSchema),\n async (params) => {\n const args = params as TAgentArgs;\n if (Array.isArray(args.jobs) && args.jobs.length > 0) {\n return runManagedAgentBatch({\n jobs: args.jobs as TAgentJobArgs[],\n deps,\n manager,\n resolveAgentDefinition,\n createSpawnRequest,\n });\n }\n return runManagedAgent(\n {\n prompt: args.prompt,\n ...(args.subagent_type !== undefined ? { subagent_type: args.subagent_type } : {}),\n ...(args.model !== undefined ? { model: args.model } : {}),\n ...(args.isolation !== undefined ? { isolation: args.isolation } : {}),\n },\n deps,\n manager,\n );\n },\n );\n}\n","/**\n * SessionBackgroundTaskTracker — manages background task and job group state\n * for an InteractiveSession. Handles subscriptions, events, and persistence\n * integration without owning the session or store directly.\n */\n\nimport {\n BackgroundJobOrchestrator,\n createBackgroundGroupExecutionEntryId,\n createBackgroundTaskExecutionEntryId,\n createLineDetailPage,\n summarizeBackgroundJobGroup,\n} from '../background-tasks/index.js';\nimport { retrieveSessionBackgroundTaskManager } from '../background-tasks/session-background-store.js';\nimport { retrieveAgentToolDeps } from '../tools/agent-tool.js';\n\nimport type {\n IBackgroundJobGroupCreateRequest,\n IBackgroundJobGroupState,\n IBackgroundTaskInput,\n IBackgroundTaskListFilter,\n IBackgroundTaskLogCursor,\n IBackgroundTaskLogPage,\n IBackgroundTaskManager,\n IBackgroundTaskState,\n IExecutionDetailCursor,\n IExecutionDetailPage,\n TBackgroundJobGroupEvent,\n TBackgroundTaskEvent,\n TExecutionWorkspaceUpdateCause,\n} from '../background-tasks/index.js';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport interface IBackgroundTrackerState {\n tasks: IBackgroundTaskState[];\n taskEvents: TBackgroundTaskEvent[];\n groups: IBackgroundJobGroupState[];\n groupEvents: TBackgroundJobGroupEvent[];\n}\n\nexport class SessionBackgroundTaskTracker {\n private backgroundTasks: IBackgroundTaskState[] = [];\n private backgroundTaskEvents: TBackgroundTaskEvent[] = [];\n private backgroundJobGroups: IBackgroundJobGroupState[] = [];\n private backgroundJobGroupEvents: TBackgroundJobGroupEvent[] = [];\n private backgroundTaskUnsubscribe: (() => void) | null = null;\n private backgroundJobUnsubscribe: (() => void) | null = null;\n private backgroundJobOrchestrator: BackgroundJobOrchestrator | null = null;\n\n constructor(\n private readonly getManager: () => IBackgroundTaskManager | undefined,\n private readonly onChanged: (cause: TExecutionWorkspaceUpdateCause, entryId?: string) => void,\n private readonly emitTaskEvent: (event: TBackgroundTaskEvent) => void,\n private readonly emitGroupEvent: (event: TBackgroundJobGroupEvent) => void,\n private readonly persistSession: () => void,\n ) {}\n\n subscribe(session: Session): void {\n if (this.backgroundTaskUnsubscribe) return;\n const manager =\n retrieveSessionBackgroundTaskManager(session) ??\n retrieveAgentToolDeps(session)?.backgroundTaskManager;\n if (!manager) return;\n this.backgroundTaskUnsubscribe = manager.subscribe((event) => {\n this.recordTaskEvent(event);\n this.emitTaskEvent(event);\n });\n }\n\n dispose(): void {\n this.backgroundTaskUnsubscribe?.();\n this.backgroundTaskUnsubscribe = null;\n this.backgroundJobUnsubscribe?.();\n this.backgroundJobUnsubscribe = null;\n this.backgroundJobOrchestrator?.dispose();\n this.backgroundJobOrchestrator = null;\n }\n\n restoreState(state: IBackgroundTrackerState): void {\n this.backgroundTasks = state.tasks;\n this.backgroundTaskEvents = state.taskEvents;\n this.backgroundJobGroups = state.groups;\n this.backgroundJobGroupEvents = state.groupEvents;\n }\n\n getState(): IBackgroundTrackerState {\n return {\n tasks: this.getTaskSnapshots(),\n taskEvents: this.backgroundTaskEvents,\n groups: this.getGroupSnapshots(),\n groupEvents: this.backgroundJobGroupEvents,\n };\n }\n\n getManagerOrThrow(): IBackgroundTaskManager {\n const manager = this.getManager();\n if (!manager) {\n throw new Error('Background task manager is not available for this session.');\n }\n return manager;\n }\n\n getOrchestratorOrThrow(sessionId: string): BackgroundJobOrchestrator {\n if (this.backgroundJobOrchestrator) return this.backgroundJobOrchestrator;\n const manager = this.getManagerOrThrow();\n this.backgroundJobOrchestrator = new BackgroundJobOrchestrator({\n manager,\n initialGroups: this.backgroundJobGroups,\n });\n this.subscribeGroupEvents(sessionId);\n return this.backgroundJobOrchestrator;\n }\n\n async cancelTask(taskId: string, reason?: string): Promise<void> {\n await this.getManagerOrThrow().cancel(taskId, reason);\n }\n\n async closeTask(taskId: string): Promise<void> {\n await this.getManagerOrThrow().close(taskId);\n }\n\n async sendTask(taskId: string, input: IBackgroundTaskInput): Promise<void> {\n await this.getManagerOrThrow().send(taskId, input);\n }\n\n async readTaskLog(\n taskId: string,\n cursor?: IBackgroundTaskLogCursor,\n ): Promise<IBackgroundTaskLogPage> {\n return this.getManagerOrThrow().readLog(taskId, cursor);\n }\n\n listTasks(filter?: IBackgroundTaskListFilter): IBackgroundTaskState[] {\n return this.getManagerOrThrow().list(filter);\n }\n\n getTask(taskId: string): IBackgroundTaskState | undefined {\n return this.getManagerOrThrow().get(taskId);\n }\n\n createGroup(\n input: Omit<IBackgroundJobGroupCreateRequest, 'parentSessionId'>,\n sessionId: string,\n ): IBackgroundJobGroupState {\n return this.getOrchestratorOrThrow(sessionId).createGroup({\n ...input,\n parentSessionId: sessionId,\n });\n }\n\n listGroups(sessionId: string): IBackgroundJobGroupState[] {\n return this.getOrchestratorOrThrow(sessionId).listGroups();\n }\n\n getGroup(groupId: string, sessionId: string): IBackgroundJobGroupState | undefined {\n return this.getOrchestratorOrThrow(sessionId).getGroup(groupId);\n }\n\n async waitGroup(groupId: string, sessionId: string): Promise<IBackgroundJobGroupState> {\n return this.getOrchestratorOrThrow(sessionId).waitGroup(groupId);\n }\n\n async readTaskDetail(\n entryId: string,\n taskId: string,\n cursor?: IExecutionDetailCursor,\n ): Promise<IExecutionDetailPage> {\n const task = this.getManagerOrThrow().get(taskId);\n if (!task) throw new Error(`Unknown background task: ${taskId}`);\n if (task.logPath || task.transcriptPath) {\n const page = await this.getManagerOrThrow().readLog(taskId, cursor);\n return createLineDetailPage({\n entryId,\n lines: page.lines,\n cursor: page.cursor,\n nextCursor: page.nextCursor,\n kind: task.kind === 'process' ? 'process_output' : 'progress',\n });\n }\n const detailKind =\n task.status === 'failed' ? 'error' : task.status === 'completed' ? 'result' : 'progress';\n const text =\n task.error?.message ??\n task.result?.output ??\n task.currentAction ??\n task.promptPreview ??\n task.commandPreview ??\n task.status;\n return createLineDetailPage({ entryId, lines: [text], cursor, kind: detailKind });\n }\n\n readGroupDetail(entryId: string, groupId: string, sessionId: string): IExecutionDetailPage {\n const group = this.getOrchestratorOrThrow(sessionId).getGroup(groupId);\n if (!group) throw new Error(`Unknown background job group: ${groupId}`);\n const summary = summarizeBackgroundJobGroup(group);\n return createLineDetailPage({ entryId, lines: summary.lines, kind: 'group_summary' });\n }\n\n getTaskSnapshots(): IBackgroundTaskState[] {\n try {\n return this.getManagerOrThrow().list();\n } catch {\n return this.backgroundTasks;\n }\n }\n\n getGroupSnapshots(): IBackgroundJobGroupState[] {\n try {\n return this.backgroundJobOrchestrator?.listGroups() ?? this.backgroundJobGroups;\n } catch {\n return this.backgroundJobGroups;\n }\n }\n\n private subscribeGroupEvents(sessionId: string): void {\n if (this.backgroundJobUnsubscribe || !this.backgroundJobOrchestrator) return;\n this.backgroundJobUnsubscribe = this.backgroundJobOrchestrator.subscribe((event) => {\n this.recordGroupEvent(event, sessionId);\n this.emitGroupEvent(event);\n });\n }\n\n private recordTaskEvent(event: TBackgroundTaskEvent): void {\n this.backgroundTasks = this.getTaskSnapshots();\n this.backgroundTaskEvents.push(event);\n this.persistSession();\n this.onChanged('background_task', getTaskEventEntryId(event));\n }\n\n private recordGroupEvent(event: TBackgroundJobGroupEvent, _sessionId: string): void {\n this.backgroundJobGroups = this.getGroupSnapshots();\n this.backgroundJobGroupEvents.push(event);\n this.persistSession();\n this.onChanged('background_group', createBackgroundGroupExecutionEntryId(event.group.id));\n }\n}\n\nfunction getTaskEventEntryId(event: TBackgroundTaskEvent): string | undefined {\n if ('task' in event) return createBackgroundTaskExecutionEntryId(event.task.id);\n if ('taskId' in event) return createBackgroundTaskExecutionEntryId(event.taskId);\n return undefined;\n}\n","/**\n * Agent job helpers for InteractiveSession.\n *\n * Pure functions for spawning, waiting, sending, cancelling, and closing\n * agent jobs. The class delegates to these with thin wrappers.\n */\n\nimport { createExecutionOriginMetadata } from '../background-tasks/index.js';\nimport { retrieveAgentToolDeps } from '../tools/agent-tool.js';\n\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type { TBackgroundTaskIsolation } from '../background-tasks/index.js';\nimport type { TCommandInvocationSource } from '../commands/index.js';\nimport type { ISubagentJobResult, ISubagentJobState } from '../subagents/index.js';\nimport type { Session } from '@robota-sdk/agent-session';\n\n/** Retrieve agent tool deps or throw. */\nexport function getAgentToolDepsOrThrow(\n session: Session,\n): NonNullable<ReturnType<typeof retrieveAgentToolDeps>> {\n const deps = retrieveAgentToolDeps(session);\n if (!deps) throw new Error('Agent runtime dependencies are not available for this session.');\n if (!deps.backgroundTaskManager)\n throw new Error('Background task manager is not available for this session.');\n return deps;\n}\n\n/** Retrieve subagent manager or throw. */\nexport function getSubagentManagerOrThrow(\n session: Session,\n): NonNullable<ReturnType<typeof getAgentToolDepsOrThrow>['subagentManager']> {\n const deps = getAgentToolDepsOrThrow(session);\n if (!deps.subagentManager) throw new Error('Subagent manager is not available for this session.');\n return deps.subagentManager;\n}\n\n/** Resolve an agent definition by type or throw. */\nexport function resolveAgentDefinition(\n agentType: string,\n deps: NonNullable<ReturnType<typeof retrieveAgentToolDeps>>,\n): IAgentDefinition {\n const definition = deps.customAgentRegistry?.(agentType);\n if (!definition) throw new Error(`Unknown agent type: ${agentType}`);\n return definition;\n}\n\n/** List agent definitions available in the session. */\nexport function listAgentDefinitionsFromSession(\n session: Session,\n): Array<{ name: string; description: string }> {\n const deps = retrieveAgentToolDeps(session);\n return (deps?.agentDefinitions ?? []).map((agent) => ({\n name: agent.name,\n description: agent.description,\n }));\n}\n\nexport interface ISpawnAgentJobInput {\n agentType: string;\n label: string;\n mode: 'foreground' | 'background';\n prompt: string;\n model?: string;\n isolation?: TBackgroundTaskIsolation;\n}\n\n/** Spawn a new agent job with the given parameters. */\nexport async function spawnAgentJobFromSession(\n session: Session,\n input: ISpawnAgentJobInput,\n cwd: string | undefined,\n invocationSource: TCommandInvocationSource,\n): Promise<ISubagentJobState> {\n const deps = getAgentToolDepsOrThrow(session);\n const definition = resolveAgentDefinition(input.agentType, deps);\n const sessionId = session.getSessionId();\n const manager = getSubagentManagerOrThrow(session);\n return manager.spawn({\n type: input.agentType,\n label: input.label,\n parentSessionId: sessionId,\n mode: input.mode,\n depth: (deps.subagentDepth ?? 0) + 1,\n cwd: deps.cwd ?? cwd ?? process.cwd(),\n prompt: input.prompt,\n model: input.model ?? definition.model,\n isolation: input.isolation,\n allowedTools: definition.tools,\n disallowedTools: definition.disallowedTools,\n metadata: createExecutionOriginMetadata({\n kind: invocationSource === 'model' ? 'model_command' : 'slash_command',\n sessionId,\n commandName: 'agent',\n label: input.label,\n }),\n });\n}\n\n/** Wait for an agent job to complete and return its result. */\nexport async function waitAgentJobFromSession(\n session: Session,\n jobId: string,\n): Promise<ISubagentJobResult> {\n return getSubagentManagerOrThrow(session).wait(jobId);\n}\n\n/** Send a prompt to a running agent job. */\nexport async function sendAgentJobFromSession(\n session: Session,\n jobId: string,\n prompt: string,\n): Promise<void> {\n await getSubagentManagerOrThrow(session).send(jobId, prompt);\n}\n\n/** Cancel a running agent job. */\nexport async function cancelAgentJobFromSession(\n session: Session,\n jobId: string,\n reason?: string,\n): Promise<void> {\n await getSubagentManagerOrThrow(session).cancel(jobId, reason);\n}\n\n/** Close a completed or failed agent job. */\nexport async function closeAgentJobFromSession(session: Session, jobId: string): Promise<void> {\n await getSubagentManagerOrThrow(session).close(jobId);\n}\n\n/** List all agent jobs in the session. */\nexport function listAgentJobsFromSession(session: Session): ISubagentJobState[] {\n return getSubagentManagerOrThrow(session).list();\n}\n","/**\n * Execution workspace helpers for InteractiveSession.\n *\n * Pure functions that build workspace snapshots, list/get entries,\n * read detail pages, and create task spawners. The class delegates to\n * these with thin wrappers.\n */\n\nimport {\n createExecutionWorkspaceSnapshot,\n createExecutionWorkspaceTaskSpawner,\n createMainThreadDetailPage,\n parseExecutionWorkspaceEntryId,\n} from '../background-tasks/index.js';\n\nimport type { SessionBackgroundTaskTracker } from './interactive-session-background-tracker.js';\nimport type { SessionExecutionController } from './interactive-session-execution-controller.js';\nimport type { SessionHistoryTracker } from './interactive-session-history-tracker.js';\nimport type {\n IExecutionDetailCursor,\n IExecutionDetailPage,\n IExecutionOrigin,\n IExecutionWorkspaceEntry,\n IExecutionWorkspaceFilter,\n IExecutionWorkspaceSnapshot,\n IExecutionWorkspaceSnapshotOptions,\n IExecutionWorkspaceTaskSpawner,\n} from '../background-tasks/index.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\n\nexport interface IWorkspaceSnapshotDeps {\n sessionId: string;\n execCtrl: Pick<SessionExecutionController, 'executing' | 'pendingPrompt' | 'streamingText'>;\n histTracker: Pick<SessionHistoryTracker, 'getHistory'>;\n bgTracker: Pick<SessionBackgroundTaskTracker, 'getTaskSnapshots' | 'getGroupSnapshots'>;\n}\n\nexport function buildExecutionWorkspaceSnapshot(\n deps: IWorkspaceSnapshotDeps,\n options: IExecutionWorkspaceSnapshotOptions = {},\n): IExecutionWorkspaceSnapshot {\n const { sessionId, execCtrl, histTracker, bgTracker } = deps;\n const history = histTracker.getHistory();\n return createExecutionWorkspaceSnapshot({\n sessionId,\n mainThread: {\n sessionId,\n isExecuting: execCtrl.executing,\n hasPendingPrompt: execCtrl.pendingPrompt !== null,\n historyLength: history.length,\n updatedAt: history.at(-1)?.timestamp.toISOString() ?? new Date(0).toISOString(),\n preview:\n execCtrl.streamingText.trim().length > 0\n ? execCtrl.streamingText\n : (history.at(-1)?.type as string | undefined),\n },\n tasks: bgTracker.getTaskSnapshots(),\n groups: bgTracker.getGroupSnapshots(),\n selectedEntryId: options.selectedEntryId,\n filter: options.filter,\n });\n}\n\nexport function listWorkspaceEntries(\n getSnapshot: (options?: IExecutionWorkspaceSnapshotOptions) => IExecutionWorkspaceSnapshot,\n filter?: IExecutionWorkspaceFilter,\n): IExecutionWorkspaceEntry[] {\n return [...getSnapshot({ filter }).entries];\n}\n\nexport function getWorkspaceEntry(\n getSnapshot: (options?: IExecutionWorkspaceSnapshotOptions) => IExecutionWorkspaceSnapshot,\n entryId: string,\n): IExecutionWorkspaceEntry | undefined {\n return getSnapshot().entries.find((entry) => entry.id === entryId);\n}\n\nexport async function readWorkspaceDetail(\n entryId: string,\n getHistory: () => IHistoryEntry[],\n bgTracker: Pick<SessionBackgroundTaskTracker, 'readGroupDetail' | 'readTaskDetail'>,\n sessionId: string,\n cursor?: IExecutionDetailCursor,\n): Promise<IExecutionDetailPage> {\n const entryRef = parseExecutionWorkspaceEntryId(entryId);\n if (!entryRef) throw new Error(`Unknown execution workspace entry: ${entryId}`);\n if (entryRef.kind === 'main_thread') {\n return createMainThreadDetailPage({ entryId, history: getHistory(), cursor });\n }\n if (entryRef.kind === 'background_group') {\n return bgTracker.readGroupDetail(entryId, entryRef.sourceId, sessionId);\n }\n return bgTracker.readTaskDetail(entryId, entryRef.sourceId, cursor);\n}\n\nexport function buildWorkspaceTaskSpawner(\n bgTracker: Pick<SessionBackgroundTaskTracker, 'getManagerOrThrow' | 'getOrchestratorOrThrow'>,\n sessionId: string,\n cwd: string,\n origin: IExecutionOrigin,\n): IExecutionWorkspaceTaskSpawner {\n return createExecutionWorkspaceTaskSpawner({\n manager: bgTracker.getManagerOrThrow(),\n groupOrchestrator: bgTracker.getOrchestratorOrThrow(sessionId),\n sessionId,\n cwd,\n origin: { ...origin, sessionId: origin.sessionId || sessionId },\n });\n}\n","/**\n * Abstract base for InteractiveSession.\n *\n * Contains all delegating public methods that only require the four\n * adapter instances (bgTracker, histTracker, skillRouter, execCtrl)\n * plus the abstract accessors declared here.\n */\n\nimport {\n listAgentDefinitionsFromSession,\n listAgentJobsFromSession,\n spawnAgentJobFromSession,\n waitAgentJobFromSession,\n sendAgentJobFromSession,\n cancelAgentJobFromSession,\n closeAgentJobFromSession,\n type ISpawnAgentJobInput,\n} from './interactive-session-agent-jobs.js';\nimport {\n buildExecutionWorkspaceSnapshot,\n buildWorkspaceTaskSpawner,\n readWorkspaceDetail,\n} from './interactive-session-workspace.js';\n\nimport type { SessionBackgroundTaskTracker } from './interactive-session-background-tracker.js';\nimport type { SessionExecutionController } from './interactive-session-execution-controller.js';\nimport type { SessionHistoryTracker } from './interactive-session-history-tracker.js';\nimport type { SessionSkillRouter } from './interactive-session-skill-router.js';\nimport type {\n IBackgroundJobGroupCreateRequest,\n IBackgroundJobGroupState,\n IBackgroundTaskInput,\n IBackgroundTaskListFilter,\n IBackgroundTaskLogCursor,\n IBackgroundTaskLogPage,\n IBackgroundTaskState,\n IExecutionDetailCursor,\n IExecutionDetailPage,\n IExecutionOrigin,\n IExecutionWorkspaceEntry,\n IExecutionWorkspaceFilter,\n IExecutionWorkspaceSnapshot,\n IExecutionWorkspaceSnapshotOptions,\n IExecutionWorkspaceTaskSpawner,\n} from '../background-tasks/index.js';\nimport type {\n IEditCheckpointInspection,\n IEditCheckpointRestoreResult,\n IEditCheckpointSummary,\n} from '../checkpoints/edit-checkpoint-types.js';\nimport type {\n ICommandHostAdapters,\n ICommandResult,\n ICommandSkillListEntry,\n ICommandSkillActivationRequest,\n TCommandInvocationSource,\n} from '../commands/index.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type {\n IContextReferenceAddResult,\n IContextReferenceClearResult,\n IContextReferenceItem,\n IContextReferenceRemoveResult,\n} from '../context/context-reference-inventory.js';\nimport type { IMemoryEvent, IMemoryReference } from '../memory/automatic-memory-types.js';\nimport type { ISubagentJobResult, ISubagentJobState } from '../subagents/index.js';\nimport type { IHistoryEntry, TUniversalMessage, IContextWindowState } from '@robota-sdk/agent-core';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport abstract class InteractiveSessionBase {\n protected abstract readonly bgTracker: SessionBackgroundTaskTracker;\n protected abstract readonly histTracker: SessionHistoryTracker;\n protected abstract readonly skillRouter: SessionSkillRouter;\n protected abstract readonly execCtrl: SessionExecutionController;\n protected abstract getSessionOrThrow(): Session;\n protected abstract ensureInitialized(): Promise<void>;\n protected abstract getCwd(): string;\n\n isExecuting(): boolean {\n return this.execCtrl.executing;\n }\n getPendingPrompt(): string | null {\n return this.execCtrl.pendingPrompt;\n }\n getStreamingText(): string {\n return this.execCtrl.streamingText;\n }\n getActiveTools(): SessionExecutionController['activeTools'] {\n return this.execCtrl.activeTools;\n }\n cancelQueue(): void {\n this.execCtrl.clearPendingQueue();\n }\n\n async executeCommand(name: string, args: string): Promise<ICommandResult | null> {\n await this.ensureInitialized();\n if (this.execCtrl.executing)\n return {\n success: false,\n message: 'Another prompt or command is already running. Wait for it to finish.',\n };\n return this.skillRouter.executeCommand(name, args);\n }\n async executeModelCommand(name: string, args: string): Promise<ICommandResult | null> {\n await this.ensureInitialized();\n return this.skillRouter.executeModelCommand(name, args);\n }\n getCommandInvocationSource(): TCommandInvocationSource {\n return this.skillRouter.getCommandInvocationSource();\n }\n async executeSkillCommandByName(\n name: string,\n args: string,\n request: ICommandSkillActivationRequest,\n ): Promise<ICommandResult | null> {\n await this.ensureInitialized();\n return this.skillRouter.executeSkillCommandByName(name, args, request);\n }\n listCommands(): Array<{ name: string; displayName?: string; description: string }> {\n return this.skillRouter.listCommands();\n }\n listSkills(): ICommandSkillListEntry[] {\n return this.skillRouter.listSkills();\n }\n listModelInvocableCommands(): Array<{ name: string; description: string }> {\n return this.skillRouter.listModelInvocableCommands();\n }\n getCommandHostAdapters(): ICommandHostAdapters {\n return this.skillRouter.getCommandHostAdapters();\n }\n getSkillActivationEvents(): ISkillActivationEvent[] {\n return this.histTracker.getSkillActivationEvents();\n }\n\n getContextState(): IContextWindowState {\n return this.getSessionOrThrow().getContextState();\n }\n async compactContext(instructions?: string): Promise<void> {\n await this.getSessionOrThrow().compact(instructions);\n }\n\n getFullHistory(): IHistoryEntry[] {\n return this.histTracker.getHistory();\n }\n getMessages(): TUniversalMessage[] {\n return this.histTracker\n .getHistory()\n .filter((e) => e.category === 'chat')\n .map((e) => e.data as TUniversalMessage);\n }\n listEditCheckpoints(): IEditCheckpointSummary[] {\n return this.histTracker.listEditCheckpoints();\n }\n inspectEditCheckpoint(checkpointId: string): IEditCheckpointInspection {\n return this.histTracker.inspectEditCheckpoint(checkpointId);\n }\n async restoreEditCheckpoint(checkpointId: string): Promise<IEditCheckpointRestoreResult> {\n await this.ensureInitialized();\n return this.histTracker.restoreEditCheckpoint(checkpointId);\n }\n async rollbackEditCheckpoint(checkpointId: string): Promise<IEditCheckpointRestoreResult> {\n await this.ensureInitialized();\n return this.histTracker.rollbackEditCheckpoint(checkpointId);\n }\n\n getUsedMemoryReferences(): IMemoryReference[] {\n return this.histTracker.getUsedMemoryReferences();\n }\n recordMemoryEvent(event: IMemoryEvent): void {\n this.histTracker.recordMemoryEvent(event);\n }\n\n listContextReferences(): IContextReferenceItem[] {\n return this.histTracker.listContextReferences();\n }\n async addContextReference(path: string): Promise<IContextReferenceAddResult> {\n return this.histTracker.addContextReference(path);\n }\n removeContextReference(path: string): IContextReferenceRemoveResult {\n return this.histTracker.removeContextReference(path);\n }\n clearContextReferences(): IContextReferenceClearResult {\n return this.histTracker.clearContextReferences();\n }\n\n listBackgroundTasks(filter?: IBackgroundTaskListFilter): IBackgroundTaskState[] {\n return this.bgTracker.listTasks(filter);\n }\n getBackgroundTask(taskId: string): IBackgroundTaskState | undefined {\n return this.bgTracker.getTask(taskId);\n }\n async cancelBackgroundTask(taskId: string, reason?: string): Promise<void> {\n await this.ensureInitialized();\n await this.bgTracker.cancelTask(taskId, reason);\n }\n async closeBackgroundTask(taskId: string): Promise<void> {\n await this.ensureInitialized();\n await this.bgTracker.closeTask(taskId);\n }\n async sendBackgroundTask(taskId: string, input: IBackgroundTaskInput): Promise<void> {\n await this.ensureInitialized();\n await this.bgTracker.sendTask(taskId, input);\n }\n async readBackgroundTaskLog(\n taskId: string,\n cursor?: IBackgroundTaskLogCursor,\n ): Promise<IBackgroundTaskLogPage> {\n await this.ensureInitialized();\n return this.bgTracker.readTaskLog(taskId, cursor);\n }\n createBackgroundJobGroup(\n input: Omit<IBackgroundJobGroupCreateRequest, 'parentSessionId'>,\n ): IBackgroundJobGroupState {\n return this.bgTracker.createGroup(input, this.getSessionOrThrow().getSessionId());\n }\n listBackgroundJobGroups(): IBackgroundJobGroupState[] {\n return this.bgTracker.listGroups(this.getSessionOrThrow().getSessionId());\n }\n getBackgroundJobGroup(groupId: string): IBackgroundJobGroupState | undefined {\n return this.bgTracker.getGroup(groupId, this.getSessionOrThrow().getSessionId());\n }\n async waitBackgroundJobGroup(groupId: string): Promise<IBackgroundJobGroupState> {\n await this.ensureInitialized();\n return this.bgTracker.waitGroup(groupId, this.getSessionOrThrow().getSessionId());\n }\n\n getExecutionWorkspaceSnapshot(\n options: IExecutionWorkspaceSnapshotOptions = {},\n ): IExecutionWorkspaceSnapshot {\n return buildExecutionWorkspaceSnapshot(\n {\n sessionId: this.getSessionOrThrow().getSessionId(),\n execCtrl: this.execCtrl,\n histTracker: this.histTracker,\n bgTracker: this.bgTracker,\n },\n options,\n );\n }\n listExecutionWorkspaceEntries(filter?: IExecutionWorkspaceFilter): IExecutionWorkspaceEntry[] {\n return [...this.getExecutionWorkspaceSnapshot({ filter }).entries];\n }\n getExecutionWorkspaceEntry(entryId: string): IExecutionWorkspaceEntry | undefined {\n return this.getExecutionWorkspaceSnapshot().entries.find((e) => e.id === entryId);\n }\n async readExecutionWorkspaceDetail(\n entryId: string,\n cursor?: IExecutionDetailCursor,\n ): Promise<IExecutionDetailPage> {\n await this.ensureInitialized();\n return readWorkspaceDetail(\n entryId,\n () => this.histTracker.getHistory(),\n this.bgTracker,\n this.getSessionOrThrow().getSessionId(),\n cursor,\n );\n }\n createExecutionWorkspaceTaskSpawner(origin: IExecutionOrigin): IExecutionWorkspaceTaskSpawner {\n return buildWorkspaceTaskSpawner(\n this.bgTracker,\n this.getSessionOrThrow().getSessionId(),\n this.getCwd(),\n origin,\n );\n }\n\n listAgentDefinitions(): Array<{ name: string; description: string }> {\n return listAgentDefinitionsFromSession(this.getSessionOrThrow());\n }\n listAgentJobs(): ISubagentJobState[] {\n return listAgentJobsFromSession(this.getSessionOrThrow());\n }\n async spawnAgentJob(input: ISpawnAgentJobInput): Promise<ISubagentJobState> {\n await this.ensureInitialized();\n return spawnAgentJobFromSession(\n this.getSessionOrThrow(),\n input,\n this.getCwd(),\n this.skillRouter.getCommandInvocationSource(),\n );\n }\n async waitAgentJob(jobId: string): Promise<ISubagentJobResult> {\n await this.ensureInitialized();\n return waitAgentJobFromSession(this.getSessionOrThrow(), jobId);\n }\n async sendAgentJob(jobId: string, prompt: string): Promise<void> {\n await this.ensureInitialized();\n await sendAgentJobFromSession(this.getSessionOrThrow(), jobId, prompt);\n }\n async cancelAgentJob(jobId: string, reason?: string): Promise<void> {\n await this.ensureInitialized();\n await cancelAgentJobFromSession(this.getSessionOrThrow(), jobId, reason);\n }\n async closeAgentJob(jobId: string): Promise<void> {\n await this.ensureInitialized();\n await closeAgentJobFromSession(this.getSessionOrThrow(), jobId);\n }\n}\n","import {\n constants,\n cpSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from 'node:fs';\nimport {\n access,\n copyFile,\n mkdir,\n readFile,\n readdir,\n realpath,\n rename,\n rm,\n stat,\n writeFile,\n} from 'node:fs/promises';\n\nimport type { IDirent, IFileSystem, IFileSystemAsync, IStats } from '@robota-sdk/agent-core';\n\nexport class NodeFileSystem implements IFileSystem {\n existsSync(path: string): boolean {\n return existsSync(path);\n }\n\n readFileSync(path: string, encoding: BufferEncoding): string {\n return readFileSync(path, encoding);\n }\n\n writeFileSync(path: string, data: string, encoding?: BufferEncoding): void {\n writeFileSync(path, data, encoding ?? 'utf8');\n }\n\n mkdirSync(path: string, options?: { recursive?: boolean }): void {\n mkdirSync(path, options);\n }\n\n readdirSync(path: string): string[];\n // eslint-disable-next-line no-dupe-class-members\n readdirSync(path: string, options: { withFileTypes: true }): IDirent[];\n // eslint-disable-next-line no-dupe-class-members\n readdirSync(path: string, options?: { withFileTypes?: true }): string[] | IDirent[] {\n if (options?.withFileTypes) {\n return readdirSync(path, { withFileTypes: true }) as IDirent[];\n }\n return readdirSync(path) as string[];\n }\n\n statSync(path: string): IStats {\n return statSync(path) as IStats;\n }\n\n rmSync(path: string, options?: { recursive?: boolean; force?: boolean }): void {\n rmSync(path, options);\n }\n\n cpSync(source: string, destination: string, options?: { recursive?: boolean }): void {\n cpSync(source, destination, options);\n }\n\n renameSync(oldPath: string, newPath: string): void {\n renameSync(oldPath, newPath);\n }\n\n get constants(): { F_OK: number; R_OK: number; W_OK: number } {\n return constants;\n }\n}\n\nexport class NodeFileSystemAsync implements IFileSystemAsync {\n async access(path: string, mode?: number): Promise<void> {\n await access(path, mode);\n }\n\n async copyFile(src: string, dest: string, flags?: number): Promise<void> {\n await copyFile(src, dest, flags);\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await mkdir(path, options);\n }\n\n async readFile(path: string, encoding: BufferEncoding): Promise<string> {\n return readFile(path, encoding);\n }\n\n async readdir(path: string): Promise<string[]>;\n // eslint-disable-next-line no-dupe-class-members\n async readdir(path: string, options: { withFileTypes: true }): Promise<IDirent[]>;\n // eslint-disable-next-line no-dupe-class-members\n async readdir(path: string, options?: { withFileTypes?: true }): Promise<string[] | IDirent[]> {\n if (options?.withFileTypes) {\n const result = await readdir(path, { withFileTypes: true });\n return result as IDirent[];\n }\n return readdir(path) as Promise<string[]>;\n }\n\n async realpath(path: string): Promise<string> {\n return realpath(path);\n }\n\n async rename(oldPath: string, newPath: string): Promise<void> {\n await rename(oldPath, newPath);\n }\n\n async rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void> {\n await rm(path, options);\n }\n\n async stat(path: string): Promise<IStats> {\n return stat(path) as Promise<IStats>;\n }\n\n async writeFile(path: string, data: string, encoding?: BufferEncoding): Promise<void> {\n await writeFile(path, data, encoding ?? 'utf8');\n }\n}\n","import { createHash } from 'node:crypto';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/** A single context file entry tracked with its content hash. */\nexport interface IContextFileEntry {\n /** Absolute path to the file. */\n filePath: string;\n /** Content as read at load time. */\n content: string;\n /** SHA-256 hex digest of `content`. */\n contentHash: string;\n}\n\n/** Compute a SHA-256 hex digest of the given string content. */\nexport function computeContentHash(content: string): string {\n return createHash('sha256').update(content, 'utf-8').digest('hex');\n}\n\n/** Read a file from disk and return an entry with its content hash. */\nexport function loadFileWithHash(\n filePath: string,\n fs: IFileSystem = new NodeFileSystem(),\n): IContextFileEntry {\n const content = fs.readFileSync(filePath, 'utf-8');\n return { filePath, content, contentHash: computeContentHash(content) };\n}\n\n/** Result of a staleness check. */\nexport interface IContextStalenessCheckResult {\n stale: IContextFileEntry[];\n fresh: IContextFileEntry[];\n}\n\n/**\n * Compare stored content hashes against what is currently on disk.\n * Files that no longer exist on disk are treated as fresh (not changed).\n */\nexport async function checkContextStaleness(\n entries: readonly IContextFileEntry[],\n fs: IFileSystem = new NodeFileSystem(),\n): Promise<IContextStalenessCheckResult> {\n const stale: IContextFileEntry[] = [];\n const fresh: IContextFileEntry[] = [];\n\n for (const entry of entries) {\n if (!fs.existsSync(entry.filePath)) {\n fresh.push(entry);\n continue;\n }\n const diskContent = fs.readFileSync(entry.filePath, 'utf-8');\n const diskHash = computeContentHash(diskContent);\n if (diskHash !== entry.contentHash) {\n stale.push(entry);\n } else {\n fresh.push(entry);\n }\n }\n\n return { stale, fresh };\n}\n\n/** Result of refreshing stale context entries. */\nexport interface IContextRefreshResult {\n /** All entries, with stale ones replaced by their re-read versions. */\n updated: IContextFileEntry[];\n /** File paths that were refreshed (had stale content). */\n refreshed: string[];\n}\n\n/**\n * Re-read any stale files from disk and return updated entries.\n * Fresh entries are returned unchanged.\n */\nexport async function refreshContextEntries(\n entries: readonly IContextFileEntry[],\n fs: IFileSystem = new NodeFileSystem(),\n): Promise<IContextRefreshResult> {\n const { stale } = await checkContextStaleness(entries, fs);\n const staleSet = new Set(stale.map((e) => e.filePath));\n const refreshed: string[] = [];\n\n const updated = entries.map((entry) => {\n if (!staleSet.has(entry.filePath)) return entry;\n const diskContent = fs.readFileSync(entry.filePath, 'utf-8');\n refreshed.push(entry.filePath);\n return {\n filePath: entry.filePath,\n content: diskContent,\n contentHash: computeContentHash(diskContent),\n };\n });\n\n return { updated, refreshed };\n}\n","/**\n * Context file refresh helper for InteractiveSession.\n *\n * Checks if AGENTS.md/CLAUDE.md context entries are stale and\n * refreshes them before each prompt turn.\n */\n\nimport { refreshContextEntries } from '../context/context-file-tracker.js';\n\nimport type { ICreatedInteractiveSession } from './interactive-session-init.js';\nimport type { IContextFileEntry } from '../context/context-file-tracker.js';\n\nexport async function checkAndRefreshContextIfStale(\n agentsFileEntries: IContextFileEntry[],\n claudeFileEntries: IContextFileEntry[],\n rebuildSystemMessage: ICreatedInteractiveSession['rebuildSystemMessage'] | null,\n setEntries: (agents: IContextFileEntry[], claude: IContextFileEntry[]) => void,\n getSessionOrThrow: () => { updateSystemMessage: (msg: string) => void },\n emit: (event: string, payload: unknown) => void,\n): Promise<void> {\n if (!rebuildSystemMessage) return;\n const allEntries = [...agentsFileEntries, ...claudeFileEntries];\n if (allEntries.length === 0) return;\n\n const agentsCount = agentsFileEntries.length;\n const { updated, refreshed } = await refreshContextEntries(allEntries);\n if (refreshed.length === 0) return;\n\n const newAgents = updated.slice(0, agentsCount);\n const newClaude = updated.slice(agentsCount);\n setEntries(newAgents, newClaude);\n\n const newSystemMessage = rebuildSystemMessage(\n newAgents.map((e) => e.content).join('\\n\\n'),\n newClaude.map((e) => e.content).join('\\n\\n'),\n );\n getSessionOrThrow().updateSystemMessage(newSystemMessage);\n\n for (const filePath of refreshed) {\n emit('context_file_refreshed', { filePath });\n }\n}\n","import type { IPromptFileReferenceRecord } from './prompt-file-reference-types.js';\n\nexport type TContextReferenceLoadType = 'manual' | 'prompt-reference';\nexport type TContextReferenceStatus = 'active' | 'observed';\n\nexport interface IContextReferenceItem {\n id: string;\n sourcePath: string;\n relativePath: string;\n originalReference: string;\n loadType: TContextReferenceLoadType;\n status: TContextReferenceStatus;\n byteLength: number;\n loadedAt: string;\n lastUsedAt?: string;\n}\n\nexport interface IContextReferenceInventoryLimits {\n maxActiveReferences?: number;\n maxActiveBytes?: number;\n maxObservedReferences?: number;\n}\n\nexport interface IContextReferenceAddResult {\n reference?: IContextReferenceItem;\n evicted: IContextReferenceItem[];\n diagnostics: string[];\n}\n\nexport interface IContextReferenceRemoveResult {\n removed?: IContextReferenceItem;\n}\n\nexport interface IContextReferenceClearResult {\n removed: IContextReferenceItem[];\n}\n\nexport interface IContextReferenceUpsertResult {\n references: IContextReferenceItem[];\n evicted: IContextReferenceItem[];\n}\n\nconst DEFAULT_MAX_ACTIVE_REFERENCES = Number('8');\nconst BYTES_PER_KIB = Number('1024');\nconst DEFAULT_MAX_ACTIVE_BYTES = Number('256') * BYTES_PER_KIB;\nconst DEFAULT_MAX_OBSERVED_REFERENCES = Number('32');\n\nexport function createContextReferenceItem(\n record: IPromptFileReferenceRecord,\n loadType: TContextReferenceLoadType,\n status: TContextReferenceStatus,\n timestamp = new Date().toISOString(),\n): IContextReferenceItem {\n return {\n id: `${loadType}:${record.relativePath}`,\n sourcePath: record.sourcePath,\n relativePath: record.relativePath,\n originalReference: record.originalReference,\n loadType,\n status,\n byteLength: record.byteLength,\n loadedAt: timestamp,\n lastUsedAt: timestamp,\n };\n}\n\nexport function upsertContextReference(\n references: readonly IContextReferenceItem[],\n item: IContextReferenceItem,\n limits?: IContextReferenceInventoryLimits,\n): IContextReferenceUpsertResult {\n const existing = references.find((reference) => reference.sourcePath === item.sourcePath);\n const retained = references.filter((reference) => reference.sourcePath !== item.sourcePath);\n const nextItem = existing ? mergeContextReference(existing, item) : item;\n return enforceContextReferenceLimits([...retained, nextItem], limits);\n}\n\nexport function removeContextReference(\n references: readonly IContextReferenceItem[],\n query: string,\n): { references: IContextReferenceItem[]; result: IContextReferenceRemoveResult } {\n const normalized = normalizeReferenceQuery(query);\n const removed = references.find((reference) => matchesContextReference(reference, normalized));\n if (!removed) return { references: [...references], result: {} };\n return {\n references: references.filter((reference) => reference.sourcePath !== removed.sourcePath),\n result: { removed },\n };\n}\n\nexport function clearContextReferences(\n references: readonly IContextReferenceItem[],\n): IContextReferenceClearResult {\n return { removed: [...references] };\n}\n\nexport function listActiveContextReferences(\n references: readonly IContextReferenceItem[],\n): IContextReferenceItem[] {\n return references.filter((reference) => reference.status === 'active');\n}\n\nexport function toContextReferenceRecords(\n references: readonly IContextReferenceItem[],\n): IPromptFileReferenceRecord[] {\n return references.map((reference) => ({\n originalReference: reference.originalReference,\n sourcePath: reference.sourcePath,\n relativePath: reference.relativePath,\n reason: reference.loadType,\n depth: 0,\n byteLength: reference.byteLength,\n }));\n}\n\nfunction mergeContextReference(\n existing: IContextReferenceItem,\n incoming: IContextReferenceItem,\n): IContextReferenceItem {\n if (incoming.status === 'active') return { ...incoming, loadedAt: existing.loadedAt };\n return {\n ...existing,\n byteLength: incoming.byteLength,\n originalReference: incoming.originalReference,\n lastUsedAt: incoming.lastUsedAt,\n };\n}\n\nfunction enforceContextReferenceLimits(\n references: readonly IContextReferenceItem[],\n limits?: IContextReferenceInventoryLimits,\n): IContextReferenceUpsertResult {\n const maxActiveReferences = limits?.maxActiveReferences ?? DEFAULT_MAX_ACTIVE_REFERENCES;\n const maxActiveBytes = limits?.maxActiveBytes ?? DEFAULT_MAX_ACTIVE_BYTES;\n const maxObservedReferences = limits?.maxObservedReferences ?? DEFAULT_MAX_OBSERVED_REFERENCES;\n const evicted: IContextReferenceItem[] = [];\n let next = [...references];\n\n while (\n countActiveReferences(next) > maxActiveReferences ||\n countActiveBytes(next) > maxActiveBytes\n ) {\n const candidate = next.find((reference) => reference.status === 'active');\n if (!candidate) break;\n evicted.push(candidate);\n next = next.filter((reference) => reference.sourcePath !== candidate.sourcePath);\n }\n\n const observed = next.filter((reference) => reference.status === 'observed');\n if (observed.length > maxObservedReferences) {\n const overflow = observed.slice(0, observed.length - maxObservedReferences);\n evicted.push(...overflow);\n next = next.filter(\n (reference) =>\n reference.status !== 'observed' ||\n !overflow.some((removed) => removed.sourcePath === reference.sourcePath),\n );\n }\n\n return { references: next, evicted };\n}\n\nfunction countActiveReferences(references: readonly IContextReferenceItem[]): number {\n return references.filter((reference) => reference.status === 'active').length;\n}\n\nfunction countActiveBytes(references: readonly IContextReferenceItem[]): number {\n return references.reduce(\n (total, reference) => total + (reference.status === 'active' ? reference.byteLength : 0),\n 0,\n );\n}\n\nfunction normalizeReferenceQuery(query: string): string {\n return query.startsWith('@') ? query.slice(1) : query;\n}\n\nfunction matchesContextReference(reference: IContextReferenceItem, query: string): boolean {\n return (\n reference.relativePath === query ||\n reference.sourcePath === query ||\n reference.originalReference === query ||\n reference.originalReference === `@${query}`\n );\n}\n","import { randomUUID } from 'node:crypto';\n\nimport type {\n IPromptFileReferenceDiagnostic,\n IPromptFileReferenceHistoryData,\n IPromptFileReferenceRecord,\n IResolvedPromptFileReference,\n} from './prompt-file-reference-types.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\n\nexport function buildPromptWithFileReferences(\n input: string,\n references: readonly IResolvedPromptFileReference[],\n): string {\n if (references.length === 0) return input;\n\n const blocks = references.map((reference) => {\n const content = reference.content.replaceAll('</file>', '<\\\\/file>');\n return [\n `<file path=\"${escapeAttribute(reference.relativePath)}\" bytes=\"${reference.byteLength}\" reason=\"${reference.reason}\">`,\n content,\n '</file>',\n ].join('\\n');\n });\n\n return [input, '<robota_file_references>', ...blocks, '</robota_file_references>'].join('\\n\\n');\n}\n\nexport function hasBlockingPromptFileReferenceDiagnostics(\n diagnostics: readonly IPromptFileReferenceDiagnostic[],\n): boolean {\n return diagnostics.some((diagnostic) => diagnostic.severity === 'error');\n}\n\nexport function formatPromptFileReferenceDiagnostics(\n diagnostics: readonly IPromptFileReferenceDiagnostic[],\n): string {\n if (diagnostics.length === 0) return '';\n return [\n 'File reference error:',\n ...diagnostics.map((diagnostic) => `- ${diagnostic.reference}: ${diagnostic.message}`),\n ].join('\\n');\n}\n\nexport function toPromptFileReferenceRecords(\n references: readonly IResolvedPromptFileReference[],\n): IPromptFileReferenceRecord[] {\n return references.map(({ content: _content, ...record }) => record);\n}\n\nexport function createPromptFileReferenceHistoryEntry(\n references: readonly IResolvedPromptFileReference[],\n): IHistoryEntry<IPromptFileReferenceHistoryData> {\n const records = toPromptFileReferenceRecords(references);\n return {\n id: `prompt_file_reference_${randomUUID()}`,\n timestamp: new Date(),\n category: 'event',\n type: 'prompt-file-reference',\n data: {\n message: formatLoadedPromptFileReferencesMessage(records),\n references: records,\n },\n };\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replaceAll('&', '&amp;')\n .replaceAll('\"', '&quot;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;');\n}\n\nfunction formatLoadedPromptFileReferencesMessage(\n references: readonly IPromptFileReferenceRecord[],\n): string {\n const list = references\n .map((reference) => `${reference.relativePath} (${reference.byteLength} B)`)\n .join(', ');\n return `Loaded file references: ${list}`;\n}\n","import type { IPromptFileReferenceToken } from './prompt-file-reference-types.js';\n\nconst REFERENCE_PATTERN = /(^|[\\s([{])@([^\\s)\\]}>,;\"'`]+)/g;\n\nexport function parsePromptFileReferences(input: string): IPromptFileReferenceToken[] {\n const references: IPromptFileReferenceToken[] = [];\n for (const match of input.matchAll(REFERENCE_PATTERN)) {\n const token = stripTrailingPunctuation(match[2] ?? '');\n if (!isPathLikeReference(token)) continue;\n references.push({\n original: `@${token}`,\n path: token,\n index: match.index ?? 0,\n });\n }\n return references;\n}\n\nfunction stripTrailingPunctuation(token: string): string {\n let end = token.length;\n while (end > 0 && /[.,:;!?]/.test(token[end - 1] ?? '')) {\n end -= 1;\n }\n return token.slice(0, end);\n}\n\nfunction isPathLikeReference(referencePath: string): boolean {\n if (referencePath.length === 0) return false;\n if (referencePath.includes('://')) return false;\n return (\n referencePath.startsWith('./') ||\n referencePath.startsWith('../') ||\n referencePath.startsWith('/') ||\n referencePath.startsWith('~/') ||\n referencePath.startsWith('.') ||\n referencePath.includes('.')\n );\n}\n","import { homedir } from 'node:os';\nimport { isAbsolute, relative as pathRelative, resolve, sep as pathSeparator } from 'node:path';\n\nexport function resolveCandidatePath(referencePath: string, rootPath: string): string {\n if (referencePath.startsWith('~/')) {\n return resolve(homedir(), referencePath.slice('~/'.length));\n }\n if (isAbsolute(referencePath)) {\n return resolve(referencePath);\n }\n return resolve(rootPath, referencePath);\n}\n\nexport function isPathWithinRoot(candidatePath: string, rootPath: string): boolean {\n const relativePath = pathRelative(rootPath, candidatePath);\n return relativePath === '' || (!relativePath.startsWith('..') && !isAbsolute(relativePath));\n}\n\nexport function normalizeRelativePath(rootPath: string, sourcePath: string): string {\n return pathRelative(rootPath, sourcePath).split(pathSeparator).join('/');\n}\n","import { resolve } from 'node:path';\n\nimport { parsePromptFileReferences } from './prompt-file-reference-parser.js';\nimport {\n isPathWithinRoot,\n normalizeRelativePath,\n resolveCandidatePath,\n} from './prompt-file-reference-paths.js';\nimport { NodeFileSystemAsync } from '../adapters/node-file-system.js';\n\nimport type {\n IPromptFileReferenceDiagnostic,\n IPromptFileReferenceLimits,\n IPromptFileReferenceResolveOptions,\n IPromptFileReferenceToken,\n IResolvedPromptFileReference,\n IResolvedPromptFileReferences,\n TPromptFileReferenceDiagnosticCode,\n TPromptFileReferenceReason,\n} from './prompt-file-reference-types.js';\nimport type { IFileSystemAsync } from '@robota-sdk/agent-core';\n\nconst DEFAULT_MAX_DEPTH = Number('2');\nconst DEFAULT_MAX_REFERENCES = Number('8');\nconst BYTES_PER_KIB = Number('1024');\nconst DEFAULT_MAX_FILE_BYTES = Number('64') * BYTES_PER_KIB;\nconst DEFAULT_MAX_TOTAL_BYTES = Number('256') * BYTES_PER_KIB;\n\ninterface IResolvedLimits {\n maxDepth: number;\n maxReferences: number;\n maxFileBytes: number;\n maxTotalBytes: number;\n}\n\ninterface IResolveState {\n rootPath: string;\n limits: IResolvedLimits;\n reason: TPromptFileReferenceReason;\n references: IResolvedPromptFileReference[];\n diagnostics: IPromptFileReferenceDiagnostic[];\n loadedPaths: Set<string>;\n totalBytes: number;\n fsAsync: IFileSystemAsync;\n}\n\ninterface IReferenceFileInfo {\n sourcePath: string;\n byteLength: number;\n}\n\nexport async function resolvePromptFileReferences(\n input: string,\n options: IPromptFileReferenceResolveOptions,\n): Promise<IResolvedPromptFileReferences> {\n const state = await createResolveState(options);\n for (const reference of parsePromptFileReferences(input)) {\n await resolveReference(reference, 0, [], state);\n }\n return toResolvedReferences(state);\n}\n\nexport async function resolvePromptFileReferencePaths(\n referencePaths: readonly string[],\n options: IPromptFileReferenceResolveOptions,\n): Promise<IResolvedPromptFileReferences> {\n const state = await createResolveState(options);\n for (const referencePath of referencePaths) {\n await resolveReference(\n { original: `@${referencePath}`, path: referencePath, index: 0 },\n 0,\n [],\n state,\n );\n }\n return toResolvedReferences(state);\n}\n\nasync function createResolveState(\n options: IPromptFileReferenceResolveOptions,\n): Promise<IResolveState> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n return {\n rootPath: await resolveWorkspaceRoot(options.cwd, fsAsync),\n limits: resolveLimits(options.limits),\n reason: options.reason ?? 'prompt-reference',\n references: [],\n diagnostics: [],\n loadedPaths: new Set<string>(),\n totalBytes: 0,\n fsAsync,\n };\n}\n\nfunction toResolvedReferences(state: IResolveState): IResolvedPromptFileReferences {\n return {\n references: state.references,\n diagnostics: state.diagnostics,\n };\n}\n\nfunction resolveLimits(limits: IPromptFileReferenceLimits | undefined): IResolvedLimits {\n return {\n maxDepth: limits?.maxDepth ?? DEFAULT_MAX_DEPTH,\n maxReferences: limits?.maxReferences ?? DEFAULT_MAX_REFERENCES,\n maxFileBytes: limits?.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES,\n maxTotalBytes: limits?.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES,\n };\n}\n\nasync function resolveWorkspaceRoot(cwd: string, fsAsync: IFileSystemAsync): Promise<string> {\n try {\n return await fsAsync.realpath(cwd);\n } catch {\n // allow-fallback: realpath fails for non-existent cwd; resolve() gives a usable absolute path\n return resolve(cwd);\n }\n}\n\nasync function resolveReference(\n reference: IPromptFileReferenceToken,\n depth: number,\n activePaths: readonly string[],\n state: IResolveState,\n): Promise<void> {\n if (!checkReferenceBudget(reference, depth, state)) return;\n\n const sourcePath = await resolveReferencePath(reference, state);\n if (sourcePath === undefined) return;\n if (!checkReferenceCycleAndDuplicate(reference, sourcePath, activePaths, state)) return;\n\n const fileInfo = await inspectReferenceFile(reference, sourcePath, state);\n if (fileInfo === undefined) return;\n\n const content = await readReferenceFile(reference, sourcePath, state);\n if (content === undefined) return;\n\n state.loadedPaths.add(sourcePath);\n state.totalBytes += fileInfo.byteLength;\n state.references.push(buildResolvedReference(reference, fileInfo, depth, content, state));\n await resolveNestedReferences(content, depth, [...activePaths, sourcePath], state);\n}\n\nfunction checkReferenceBudget(\n reference: IPromptFileReferenceToken,\n depth: number,\n state: IResolveState,\n): boolean {\n if (state.references.length >= state.limits.maxReferences) {\n pushDiagnostic(state, 'too-many-references', reference, 'Too many file references.');\n return false;\n }\n if (depth > state.limits.maxDepth) {\n pushDiagnostic(state, 'max-depth', reference, 'File reference nesting is too deep.');\n return false;\n }\n return true;\n}\n\nasync function resolveReferencePath(\n reference: IPromptFileReferenceToken,\n state: IResolveState,\n): Promise<string | undefined> {\n const candidatePath = resolveCandidatePath(reference.path, state.rootPath);\n if (!isPathWithinRoot(candidatePath, state.rootPath)) {\n pushDiagnostic(state, 'outside-root', reference, 'Referenced path is outside the workspace.');\n return undefined;\n }\n\n try {\n const sourcePath = await state.fsAsync.realpath(candidatePath);\n if (isPathWithinRoot(sourcePath, state.rootPath)) return sourcePath;\n pushDiagnostic(\n state,\n 'outside-root',\n reference,\n 'Referenced path resolves outside the workspace.',\n );\n } catch {\n // allow-fallback: realpath failure means file absent; diagnostic is the intended result\n pushDiagnostic(state, 'not-found', reference, 'Referenced file was not found.');\n }\n return undefined;\n}\n\nfunction checkReferenceCycleAndDuplicate(\n reference: IPromptFileReferenceToken,\n sourcePath: string,\n activePaths: readonly string[],\n state: IResolveState,\n): boolean {\n if (activePaths.includes(sourcePath)) {\n pushDiagnostic(state, 'circular-reference', reference, 'Circular file reference detected.');\n return false;\n }\n return !state.loadedPaths.has(sourcePath);\n}\n\nasync function inspectReferenceFile(\n reference: IPromptFileReferenceToken,\n sourcePath: string,\n state: IResolveState,\n): Promise<IReferenceFileInfo | undefined> {\n try {\n const fileStat = await state.fsAsync.stat(sourcePath);\n if (fileStat.isDirectory()) {\n pushDiagnostic(\n state,\n 'directory-not-supported',\n reference,\n 'Directory references are not supported.',\n );\n return undefined;\n }\n if (fileStat.size > state.limits.maxFileBytes) {\n pushDiagnostic(\n state,\n 'file-too-large',\n reference,\n 'Referenced file exceeds the per-file size limit.',\n );\n return undefined;\n }\n if (state.totalBytes + fileStat.size > state.limits.maxTotalBytes) {\n pushDiagnostic(\n state,\n 'total-too-large',\n reference,\n 'Referenced files exceed the total size limit.',\n );\n return undefined;\n }\n return { sourcePath, byteLength: fileStat.size };\n } catch {\n // allow-fallback: stat failure means unreadable; diagnostic is the intended result\n pushDiagnostic(state, 'unreadable', reference, 'Referenced file could not be inspected.');\n return undefined;\n }\n}\n\nasync function readReferenceFile(\n reference: IPromptFileReferenceToken,\n sourcePath: string,\n state: IResolveState,\n): Promise<string | undefined> {\n try {\n return await state.fsAsync.readFile(sourcePath, 'utf8');\n } catch {\n // allow-fallback: read failure means unreadable; diagnostic is the intended result\n pushDiagnostic(state, 'unreadable', reference, 'Referenced file could not be read.');\n return undefined;\n }\n}\n\nfunction buildResolvedReference(\n reference: IPromptFileReferenceToken,\n fileInfo: IReferenceFileInfo,\n depth: number,\n content: string,\n state: IResolveState,\n): IResolvedPromptFileReference {\n return {\n originalReference: reference.original,\n sourcePath: fileInfo.sourcePath,\n relativePath: normalizeRelativePath(state.rootPath, fileInfo.sourcePath),\n reason: state.reason,\n depth,\n byteLength: fileInfo.byteLength,\n content,\n };\n}\n\nasync function resolveNestedReferences(\n content: string,\n depth: number,\n activePaths: readonly string[],\n state: IResolveState,\n): Promise<void> {\n for (const nestedReference of parsePromptFileReferences(content)) {\n await resolveReference(nestedReference, depth + 1, activePaths, state);\n }\n}\n\nfunction pushDiagnostic(\n state: IResolveState,\n code: TPromptFileReferenceDiagnosticCode,\n reference: IPromptFileReferenceToken,\n message: string,\n): void {\n state.diagnostics.push({\n code,\n severity: 'error',\n reference: reference.original,\n message,\n path: reference.path,\n });\n}\n","/**\n * Prompt execution helpers for InteractiveSession.\n *\n * Contains abort detection, tool-summary extraction, and prompt preparation utilities.\n */\n\nimport { randomUUID } from 'node:crypto';\n\nimport { collectAssistantUsageMetadata } from '@robota-sdk/agent-core';\n\nimport { listActiveContextReferences } from '../context/context-reference-inventory.js';\nimport {\n buildPromptWithFileReferences,\n createPromptFileReferenceHistoryEntry,\n formatPromptFileReferenceDiagnostics,\n hasBlockingPromptFileReferenceDiagnostics,\n resolvePromptFileReferences,\n resolvePromptFileReferencePaths,\n toPromptFileReferenceRecords,\n} from '../context/prompt-file-references.js';\n\nimport type { IExecutionResult, IToolSummary, IUsageSnapshot } from './types.js';\nimport type { IContextReferenceItem } from '../context/context-reference-inventory.js';\nimport type { IPromptFileReferenceRecord } from '../context/prompt-file-references.js';\nimport type { IContextWindowState, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\n\nexport interface IPreparedPromptInput {\n modelInput: string;\n hookInput?: string;\n promptFileReferenceRecords: IPromptFileReferenceRecord[];\n activeContextReferenceRecords: IPromptFileReferenceRecord[];\n promptFileReferenceEntry?: IHistoryEntry;\n}\n\n/** Detect whether an error represents an abort/cancel action. */\nexport function isAbortError(err: unknown): boolean {\n return (\n (err instanceof DOMException && err.name === 'AbortError') ||\n (err instanceof Error && (err.message.includes('aborted') || err.message.includes('abort')))\n );\n}\n\n/**\n * Extract tool call summaries from a session history slice.\n *\n * Scans history entries from `historyBefore` onwards and collects\n * tool call records from assistant messages.\n */\nexport function extractToolSummaries(\n history: TUniversalMessage[],\n historyBefore: number,\n): IToolSummary[] {\n const summaries: IToolSummary[] = [];\n for (let i = historyBefore; i < history.length; i++) {\n const msg = history[i];\n if (msg?.role === 'assistant' && msg.toolCalls) {\n for (const tc of msg.toolCalls as Array<{\n function: { name: string; arguments: string };\n }>) {\n summaries.push({ name: tc.function.name, args: tc.function.arguments });\n }\n }\n }\n return summaries;\n}\n\n/**\n * Build an IExecutionResult from a completed response.\n */\nexport function buildResult(\n response: string,\n sessionHistory: TUniversalMessage[],\n interactiveHistory: IHistoryEntry[],\n historyBefore: number,\n contextState: IContextWindowState,\n promptFileReferences?: readonly IPromptFileReferenceRecord[],\n): IExecutionResult {\n const toolSummaries = extractToolSummaries(sessionHistory, historyBefore);\n const usage = extractTurnUsage(sessionHistory, historyBefore, contextState);\n return {\n response,\n history: interactiveHistory,\n toolSummaries,\n contextState,\n ...(usage && { usage }),\n ...(promptFileReferences && promptFileReferences.length > 0\n ? { promptFileReferences: [...promptFileReferences] }\n : {}),\n };\n}\n\n/**\n * Build an IExecutionResult for an interrupted (aborted) execution.\n * Collects any partial assistant text accumulated before the abort.\n */\nexport function buildInterruptedResult(\n sessionHistory: TUniversalMessage[],\n interactiveHistory: IHistoryEntry[],\n historyBefore: number,\n contextState: IContextWindowState,\n): IExecutionResult {\n const toolSummaries = extractToolSummaries(sessionHistory, historyBefore);\n const parts: string[] = [];\n for (let i = historyBefore; i < sessionHistory.length; i++) {\n const msg = sessionHistory[i];\n if (msg?.role === 'assistant' && msg.content) parts.push(msg.content);\n }\n const usage = extractTurnUsage(sessionHistory, historyBefore, contextState);\n return {\n response: parts.join('\\n\\n'),\n history: interactiveHistory,\n toolSummaries,\n contextState,\n ...(usage && { usage }),\n };\n}\n\nexport function createUsageSummaryEntry(usage: IUsageSnapshot): IHistoryEntry<IUsageSnapshot> {\n return {\n id: `usage_${randomUUID()}`,\n timestamp: new Date(),\n category: 'event',\n type: 'usage-summary',\n data: usage,\n };\n}\n\nexport async function preparePromptInput(\n input: string,\n cwd: string,\n rawInput?: string,\n contextReferences: readonly IContextReferenceItem[] = [],\n): Promise<IPreparedPromptInput> {\n const activeReferenceResult = await resolvePromptFileReferencePaths(\n listActiveContextReferences(contextReferences).map((reference) => reference.sourcePath),\n { cwd, reason: 'manual' },\n );\n const promptFileReferenceResult = await resolvePromptFileReferences(input, { cwd });\n const diagnostics = [\n ...activeReferenceResult.diagnostics,\n ...promptFileReferenceResult.diagnostics,\n ];\n if (hasBlockingPromptFileReferenceDiagnostics(diagnostics)) {\n throw new Error(formatPromptFileReferenceDiagnostics(diagnostics));\n }\n\n const resolvedReferences = dedupeResolvedReferences([\n ...activeReferenceResult.references,\n ...promptFileReferenceResult.references,\n ]);\n const modelInput = buildPromptWithFileReferences(input, resolvedReferences);\n const hookInput = rawInput ?? (modelInput === input ? undefined : input);\n const activeContextReferenceRecords = toPromptFileReferenceRecords(\n activeReferenceResult.references,\n );\n const promptFileReferenceRecords = toPromptFileReferenceRecords(\n promptFileReferenceResult.references,\n );\n const promptFileReferenceEntry =\n promptFileReferenceResult.references.length > 0\n ? createPromptFileReferenceHistoryEntry(promptFileReferenceResult.references)\n : undefined;\n\n return {\n modelInput,\n ...(hookInput !== undefined ? { hookInput } : {}),\n activeContextReferenceRecords,\n promptFileReferenceRecords,\n ...(promptFileReferenceEntry !== undefined ? { promptFileReferenceEntry } : {}),\n };\n}\n\nfunction dedupeResolvedReferences(\n references: readonly (IPromptFileReferenceRecord & { content: string })[],\n): Array<IPromptFileReferenceRecord & { content: string }> {\n return [...new Map(references.map((reference) => [reference.sourcePath, reference])).values()];\n}\n\nfunction extractTurnUsage(\n sessionHistory: TUniversalMessage[],\n historyBefore: number,\n contextState: IContextWindowState,\n): IUsageSnapshot | undefined {\n const turnMessages = sessionHistory.slice(historyBefore);\n let promptTokens = 0;\n let completionTokens = 0;\n let foundUsage = false;\n\n for (const message of turnMessages) {\n if (message.role !== 'assistant') continue;\n const usage = collectAssistantUsageMetadata(message);\n if (!usage) continue;\n foundUsage = true;\n promptTokens += usage.inputTokens;\n completionTokens += usage.outputTokens;\n }\n\n if (!foundUsage) return undefined;\n return {\n kind: 'exact',\n scope: 'turn',\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n contextUsedTokens: contextState.usedTokens,\n contextMaxTokens: contextState.maxTokens,\n contextUsedPercentage: contextState.usedPercentage,\n costStatus: 'unknown',\n };\n}\n\n/** No-op terminal implementation used during async initialization. */\nexport const NOOP_TERMINAL = {\n write: (): void => {},\n writeLine: (): void => {},\n writeMarkdown: (): void => {},\n writeError: (): void => {},\n prompt: (): Promise<string> => Promise.resolve(''),\n select: (): Promise<number> => Promise.resolve(0),\n spinner: () => ({ stop: () => {}, update: () => {} }),\n};\n","/**\n * Streaming and tool-event helpers for InteractiveSession.\n *\n * Pure functions that process streaming text deltas and tool execution events,\n * updating state passed in by reference. No class dependency.\n */\n\nimport { randomUUID } from 'node:crypto';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { IDiffLine, IToolState } from './types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\nimport type { TToolArgs } from '@robota-sdk/agent-core';\n\n/** Max chars to display from first tool argument. */\nexport const TOOL_ARG_DISPLAY_MAX = 80;\nconst TAIL_KEEP = 30;\n/** Max completed tools to keep in the activeTools array during a single response. */\nexport const MAX_COMPLETED_TOOLS = 50;\n/** Streaming text flush interval (ms) — ~60fps. */\nexport const STREAMING_FLUSH_INTERVAL_MS = 16;\nconst DEFAULT_START_LINE = 1;\nconst EDIT_DIFF_CONTEXT_LINES = 3;\n\n/** Extract a short display string from the first tool argument. */\nexport function extractFirstArg(toolArgs?: TToolArgs): string {\n if (!toolArgs) return '';\n const firstVal = Object.values(toolArgs)[0];\n const raw = typeof firstVal === 'string' ? firstVal : JSON.stringify(firstVal ?? '');\n return raw.length > TOOL_ARG_DISPLAY_MAX\n ? raw.slice(0, TOOL_ARG_DISPLAY_MAX - TAIL_KEEP - 3) + '...' + raw.slice(-TAIL_KEEP)\n : raw;\n}\n\n/** Mutable streaming state passed between helpers. */\nexport interface IStreamingState {\n activeTools: IToolState[];\n history: IHistoryEntry[];\n}\n\ninterface IToolEndEvent {\n type?: 'start' | 'end';\n toolName: string;\n toolArgs?: TToolArgs;\n success?: boolean;\n denied?: boolean;\n toolResultData?: string;\n}\n\nfunction getStringArg(args: TToolArgs | undefined, snake: string, camel: string): string | null {\n const value = args?.[snake] ?? args?.[camel];\n return typeof value === 'string' ? value : null;\n}\n\nfunction parseStartLine(toolResultData: string | undefined): number {\n if (!toolResultData) return DEFAULT_START_LINE;\n try {\n const parsed = JSON.parse(toolResultData) as Partial<{ startLine: number }>;\n return typeof parsed.startLine === 'number' && Number.isFinite(parsed.startLine)\n ? parsed.startLine\n : DEFAULT_START_LINE;\n } catch {\n return DEFAULT_START_LINE;\n }\n}\n\nfunction buildEditDiffState(event: IToolEndEvent): Pick<IToolState, 'diffFile' | 'diffLines'> {\n if (event.toolName !== 'Edit') return {};\n const filePath = getStringArg(event.toolArgs, 'file_path', 'filePath');\n const oldString = getStringArg(event.toolArgs, 'old_string', 'oldString');\n const newString = getStringArg(event.toolArgs, 'new_string', 'newString');\n if (!filePath || oldString === null || newString === null || oldString === newString) return {};\n\n const startLine = parseStartLine(event.toolResultData);\n return {\n diffFile: filePath,\n diffLines: buildEditDiffLinesWithContext(oldString, newString, startLine, filePath),\n };\n}\n\nfunction buildEditDiffLines(oldString: string, newString: string, startLine: number): IDiffLine[] {\n return [\n ...oldString.split('\\n').map((text, index) => ({\n type: 'remove' as const,\n text,\n lineNumber: startLine + index,\n })),\n ...newString.split('\\n').map((text, index) => ({\n type: 'add' as const,\n text,\n lineNumber: startLine + index,\n })),\n ];\n}\n\nfunction buildEditDiffLinesWithContext(\n oldString: string,\n newString: string,\n startLine: number,\n filePath: string,\n fs: IFileSystem = new NodeFileSystem(),\n): IDiffLine[] {\n const diffLines = buildEditDiffLines(oldString, newString, startLine);\n\n let fileLines: string[];\n try {\n fileLines = fs.readFileSync(filePath, 'utf8').split('\\n');\n } catch {\n // allow-fallback: unreadable file returns diff without context lines\n return diffLines;\n }\n\n const beforeContext: IDiffLine[] = [];\n const contextStart = Math.max(0, startLine - 1 - EDIT_DIFF_CONTEXT_LINES);\n for (let index = contextStart; index < startLine - 1; index++) {\n if (index < fileLines.length) {\n beforeContext.push({ type: 'context', text: fileLines[index], lineNumber: index + 1 });\n }\n }\n\n const afterContext: IDiffLine[] = [];\n const afterStart = startLine - 1 + newString.split('\\n').length;\n for (let index = afterStart; index < afterStart + EDIT_DIFF_CONTEXT_LINES; index++) {\n if (index < fileLines.length) {\n afterContext.push({ type: 'context', text: fileLines[index], lineNumber: index + 1 });\n }\n }\n\n const hunkStart =\n beforeContext[0]?.lineNumber ??\n diffLines[0]?.lineNumber ??\n afterContext[0]?.lineNumber ??\n startLine;\n const oldLineCount = oldString.split('\\n').length;\n const newLineCount = newString.split('\\n').length;\n const oldHunkLineCount = beforeContext.length + oldLineCount + afterContext.length;\n const newHunkLineCount = beforeContext.length + newLineCount + afterContext.length;\n\n return [\n {\n type: 'hunk',\n text: `@@ -${hunkStart},${oldHunkLineCount} +${hunkStart},${newHunkLineCount} @@`,\n lineNumber: hunkStart,\n },\n ...beforeContext,\n ...diffLines,\n ...afterContext,\n ];\n}\n\n/** Build a tool-summary history entry from current active tools and push it into history. */\nexport function pushToolSummaryToHistory(state: IStreamingState): void {\n if (state.activeTools.length === 0) return;\n const summary = state.activeTools\n .map((t) => {\n const status = t.isRunning\n ? '⟳'\n : t.result === 'success'\n ? '✓'\n : t.result === 'error'\n ? '✗'\n : '⊘';\n return `${status} ${t.toolName}${t.firstArg ? `(${t.firstArg})` : ''}`;\n })\n .join('\\n');\n\n state.history.push({\n id: randomUUID(),\n timestamp: new Date(),\n category: 'event',\n type: 'tool-summary',\n data: {\n tools: state.activeTools.map((t) => ({\n toolName: t.toolName,\n firstArg: t.firstArg,\n isRunning: t.isRunning,\n result: t.result,\n diffFile: t.diffFile,\n diffLines: t.diffLines,\n toolResultData: t.toolResultData,\n })),\n summary,\n },\n });\n}\n\n/** Trim oldest completed tools from the activeTools array if over the limit. */\nexport function trimCompletedTools(activeTools: IToolState[]): IToolState[] {\n const completed = activeTools.filter((t) => !t.isRunning);\n if (completed.length <= MAX_COMPLETED_TOOLS) return activeTools;\n\n const excess = completed.length - MAX_COMPLETED_TOOLS;\n let removed = 0;\n return activeTools.filter((t) => {\n if (!t.isRunning && removed < excess) {\n removed++;\n return false;\n }\n return true;\n });\n}\n\n/** Process a tool-start event: add to activeTools and push to history. */\nexport function applyToolStart(\n state: IStreamingState,\n event: { toolName: string; toolArgs?: TToolArgs },\n): IToolState {\n const firstArg = extractFirstArg(event.toolArgs);\n const toolState: IToolState = { toolName: event.toolName, firstArg, isRunning: true };\n state.activeTools.push(toolState);\n\n state.history.push({\n id: randomUUID(),\n timestamp: new Date(),\n category: 'event',\n type: 'tool-start',\n data: { toolName: event.toolName, firstArg, isRunning: true },\n });\n\n return toolState;\n}\n\n/** Process a tool-end event: mark the tool finished and push to history. Returns updated tool or null. */\nexport function applyToolEnd(state: IStreamingState, event: IToolEndEvent): IToolState | null {\n const result: IToolState['result'] = event.denied\n ? 'denied'\n : event.success === false\n ? 'error'\n : 'success';\n\n const idx = state.activeTools.findIndex((t) => t.toolName === event.toolName && t.isRunning);\n if (idx === -1) return null;\n\n const finished: IToolState = {\n ...state.activeTools[idx]!,\n ...buildEditDiffState(event),\n isRunning: false,\n result,\n toolResultData: event.toolResultData,\n };\n state.activeTools[idx] = finished;\n state.activeTools = trimCompletedTools(state.activeTools);\n\n state.history.push({\n id: randomUUID(),\n timestamp: new Date(),\n category: 'event',\n type: 'tool-end',\n data: {\n toolName: finished.toolName,\n firstArg: finished.firstArg,\n isRunning: false,\n result,\n toolResultData: event.toolResultData,\n },\n });\n\n return finished;\n}\n","/**\n * Prompt turn execution for InteractiveSession.\n *\n * Standalone function that runs one prompt turn, using callbacks to access\n * InteractiveSession state without coupling to the class directly.\n */\n\nimport {\n createUserMessage,\n createAssistantMessage,\n createSystemMessage,\n messageToHistoryEntry,\n} from '@robota-sdk/agent-core';\n\nimport {\n isAbortError,\n buildResult,\n buildInterruptedResult,\n createUsageSummaryEntry,\n preparePromptInput,\n} from './interactive-session-execution.js';\nimport { pushToolSummaryToHistory } from './interactive-session-streaming.js';\n\nimport type { IToolState, IExecutionResult } from './types.js';\nimport type { IContextReferenceItem } from '../context/context-reference-inventory.js';\nimport type { IPromptFileReferenceRecord } from '../context/prompt-file-references.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport interface IPromptTurnContext {\n getSession: () => Session;\n getCwd: () => string;\n getHistory: () => IHistoryEntry[];\n getContextReferences: () => readonly IContextReferenceItem[];\n getActiveTools: () => IToolState[];\n resetUsedMemoryReferences: () => void;\n recordContextReferenceUsage: (records: readonly IPromptFileReferenceRecord[]) => void;\n recordPromptContextReferences: (records: readonly IPromptFileReferenceRecord[]) => void;\n beginEditCheckpointTurn: (prompt: string) => Promise<void>;\n flushStreaming: () => void;\n clearStreaming: () => void;\n onComplete: (result: IExecutionResult) => void;\n onInterrupted: (result: IExecutionResult) => void;\n onError: (err: Error) => void;\n onContextUpdate: () => void;\n onWorkspaceUpdated: () => void;\n}\n\nexport async function executePromptTurn(\n input: string,\n displayInput: string | undefined,\n rawInput: string | undefined,\n ctx: IPromptTurnContext,\n): Promise<void> {\n const history = ctx.getHistory();\n history.push(messageToHistoryEntry(createUserMessage(displayInput ?? input)));\n ctx.onWorkspaceUpdated();\n const historyBefore = ctx.getSession().getHistory().length;\n ctx.resetUsedMemoryReferences();\n\n try {\n const preparedPrompt = await preparePromptInput(\n input,\n ctx.getCwd(),\n rawInput,\n ctx.getContextReferences(),\n );\n if (preparedPrompt.promptFileReferenceEntry) {\n history.push(preparedPrompt.promptFileReferenceEntry);\n }\n ctx.recordContextReferenceUsage(preparedPrompt.activeContextReferenceRecords);\n ctx.recordPromptContextReferences(preparedPrompt.promptFileReferenceRecords);\n\n await ctx.beginEditCheckpointTurn(displayInput ?? input);\n const response = await ctx\n .getSession()\n .run(preparedPrompt.modelInput, preparedPrompt.hookInput);\n ctx.flushStreaming();\n pushToolSummaryToHistory({ activeTools: ctx.getActiveTools(), history });\n ctx.clearStreaming();\n const result = buildResult(\n response || '(empty response)',\n ctx.getSession().getHistory(),\n history,\n historyBefore,\n ctx.getSession().getContextState(),\n preparedPrompt.promptFileReferenceRecords,\n );\n history.push(messageToHistoryEntry(createAssistantMessage(result.response)));\n if (result.usage) history.push(createUsageSummaryEntry(result.usage));\n ctx.onComplete(result);\n ctx.onContextUpdate();\n } catch (err) {\n ctx.flushStreaming();\n if (isAbortError(err)) {\n const result = buildInterruptedResult(\n ctx.getSession().getHistory(),\n history,\n historyBefore,\n ctx.getSession().getContextState(),\n );\n pushToolSummaryToHistory({ activeTools: ctx.getActiveTools(), history });\n ctx.clearStreaming();\n if (result.response)\n history.push(messageToHistoryEntry(createAssistantMessage(result.response)));\n if (result.usage) history.push(createUsageSummaryEntry(result.usage));\n history.push(messageToHistoryEntry(createSystemMessage('Interrupted by user.')));\n ctx.onInterrupted(result);\n } else {\n pushToolSummaryToHistory({ activeTools: ctx.getActiveTools(), history });\n ctx.clearStreaming();\n const errMsg = err instanceof Error ? err.message : String(err);\n history.push(messageToHistoryEntry(createSystemMessage(`Error: ${errMsg}`)));\n ctx.onError(err instanceof Error ? err : new Error(errMsg));\n }\n }\n}\n","/**\n * SessionExecutionController — owns execution lifecycle state and methods\n * for InteractiveSession.\n *\n * Manages: executing flag, streaming text, active tools, pending queue,\n * shutting-down flag, and all private execution lifecycle methods.\n */\n\nimport {\n createUserMessage,\n createAssistantMessage,\n createSystemMessage,\n messageToHistoryEntry,\n} from '@robota-sdk/agent-core';\n\nimport { checkAndRefreshContextIfStale } from './interactive-session-context-refresh.js';\nimport { executePromptTurn } from './interactive-session-prompt.js';\nimport {\n STREAMING_FLUSH_INTERVAL_MS,\n pushToolSummaryToHistory,\n applyToolStart,\n applyToolEnd,\n} from './interactive-session-streaming.js';\n\nimport type { SessionHistoryTracker } from './interactive-session-history-tracker.js';\nimport type { ICreatedInteractiveSession } from './interactive-session-init.js';\nimport type { SessionSkillRouter } from './interactive-session-skill-router.js';\nimport type { IToolState } from './types.js';\nimport type { IExecutionResult } from './types.js';\nimport type {\n IExecutionWorkspaceSnapshot,\n TExecutionWorkspaceUpdateCause,\n} from '../background-tasks/index.js';\nimport type { ICommand, ICommandResult, ISkillExecutionResult } from '../commands/index.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type { IContextFileEntry } from '../context/context-file-tracker.js';\nimport type { IContextWindowState, TToolArgs } from '@robota-sdk/agent-core';\nimport type { ICompactEvent } from '@robota-sdk/agent-session';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport interface IExecutionControllerCallbacks {\n getSession: () => Session;\n getSessionOrThrow: () => Session;\n getCwd: () => string;\n getContextState: () => IContextWindowState;\n getExecutionWorkspaceSnapshot: () => IExecutionWorkspaceSnapshot;\n emit: <E extends string>(event: E, ...args: unknown[]) => void;\n persistSession: () => void;\n}\nexport class SessionExecutionController {\n executing = false;\n streamingText = '';\n flushTimer: ReturnType<typeof setTimeout> | null = null;\n activeTools: IToolState[] = [];\n pendingPrompt: string | null = null;\n pendingDisplayInput: string | undefined;\n pendingRawInput: string | undefined;\n shuttingDown = false;\n\n constructor(\n private readonly histTracker: SessionHistoryTracker,\n private readonly skillRouter: SessionSkillRouter,\n private readonly callbacks: IExecutionControllerCallbacks,\n ) {}\n\n clearPendingQueue(): void {\n this.pendingPrompt = null;\n this.pendingDisplayInput = undefined;\n this.pendingRawInput = undefined;\n }\n\n clearStreaming(): void {\n this.streamingText = '';\n this.activeTools = [];\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n }\n\n flushStreaming(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n }\n\n handleTextDelta(delta: string): void {\n this.streamingText += delta;\n this.callbacks.emit('text_delta', delta);\n if (!this.flushTimer) {\n this.flushTimer = setTimeout(() => {\n this.flushTimer = null;\n }, STREAMING_FLUSH_INTERVAL_MS);\n }\n }\n\n handleCompactEvent(event: ICompactEvent): void {\n if (event.trigger === 'auto') {\n this.histTracker.append(\n messageToHistoryEntry(\n createSystemMessage(\n `Auto compacted context: ${Math.round(event.before.usedPercentage)}% -> ${Math.round(event.after.usedPercentage)}%`,\n ),\n ),\n );\n }\n this.callbacks.emit('compact', event);\n this.callbacks.emit('context_update', event.after);\n }\n\n handleToolExecution(event: {\n type: 'start' | 'end';\n toolName: string;\n toolArgs?: TToolArgs;\n success?: boolean;\n denied?: boolean;\n toolResultData?: string;\n }): void {\n const streamingState = {\n activeTools: this.activeTools,\n history: this.histTracker.getHistory(),\n };\n if (event.type === 'start') {\n const toolState = applyToolStart(streamingState, event);\n this.activeTools = streamingState.activeTools;\n this.callbacks.emit('tool_start', toolState);\n } else {\n const finished = applyToolEnd(streamingState, event);\n this.activeTools = streamingState.activeTools;\n if (finished) this.callbacks.emit('tool_end', finished);\n }\n }\n\n emitExecutionWorkspaceUpdated(cause: TExecutionWorkspaceUpdateCause, entryId?: string): void {\n const session = this.callbacks.getSession();\n if (!session) return;\n this.callbacks.emit('execution_workspace_event', {\n type: 'execution_workspace_updated',\n cause,\n ...(entryId ? { entryId } : {}),\n snapshot: this.callbacks.getExecutionWorkspaceSnapshot(),\n });\n }\n\n private drainPendingQueue(submit: (p: string, d?: string, r?: string) => Promise<void>): void {\n if (!this.shuttingDown && this.pendingPrompt) {\n const queued = this.pendingPrompt;\n const queuedDisplay = this.pendingDisplayInput;\n const queuedRaw = this.pendingRawInput;\n this.clearPendingQueue();\n setTimeout(() => void submit(queued, queuedDisplay, queuedRaw), 0);\n }\n }\n\n async executePrompt(\n input: string,\n displayInput: string | undefined,\n rawInput: string | undefined,\n agentsFileEntries: IContextFileEntry[],\n claudeFileEntries: IContextFileEntry[],\n rebuildSystemMessage: ICreatedInteractiveSession['rebuildSystemMessage'] | null,\n setEntries: (agents: IContextFileEntry[], claude: IContextFileEntry[]) => void,\n submit: (p: string, d?: string, r?: string) => Promise<void>,\n ): Promise<void> {\n await checkAndRefreshContextIfStale(\n agentsFileEntries,\n claudeFileEntries,\n rebuildSystemMessage,\n setEntries,\n () => this.callbacks.getSessionOrThrow(),\n (event: string, payload: unknown) => this.callbacks.emit(event, payload),\n );\n this.executing = true;\n this.clearStreaming();\n this.callbacks.emit('user_message', displayInput ?? input);\n this.callbacks.emit('thinking', true);\n try {\n await executePromptTurn(input, displayInput, rawInput, {\n getSession: () => this.callbacks.getSessionOrThrow(),\n getCwd: () => this.callbacks.getCwd(),\n getHistory: () => this.histTracker.getHistory(),\n getContextReferences: () => this.histTracker.listContextReferences(),\n getActiveTools: () => this.activeTools,\n resetUsedMemoryReferences: () => this.histTracker.resetUsedMemoryReferences(),\n recordContextReferenceUsage: (r) => this.histTracker.recordContextReferenceUsage(r),\n recordPromptContextReferences: (r) => this.histTracker.recordPromptContextReferences(r),\n beginEditCheckpointTurn: (p) => this.histTracker.beginEditCheckpointTurn(p),\n flushStreaming: () => this.flushStreaming(),\n clearStreaming: () => this.clearStreaming(),\n onWorkspaceUpdated: () => this.emitExecutionWorkspaceUpdated('main_thread'),\n onComplete: (result: IExecutionResult) => {\n this.callbacks.emit('complete', result);\n },\n onInterrupted: (result: IExecutionResult) => {\n this.callbacks.emit('interrupted', result);\n },\n onError: (err: Error) => {\n this.callbacks.emit('error', err);\n },\n onContextUpdate: () => {\n this.callbacks.emit('context_update', this.callbacks.getContextState());\n },\n });\n } finally {\n try {\n await this.histTracker.finalizeEditCheckpointTurn();\n } catch (error) {\n this.callbacks.emit('error', error instanceof Error ? error : new Error(String(error)));\n }\n this.executing = false;\n this.callbacks.emit('thinking', false);\n this.emitExecutionWorkspaceUpdated('main_thread');\n this.callbacks.persistSession();\n this.drainPendingQueue(submit);\n }\n }\n\n async executeForkSkillCommand(\n skill: ICommand,\n args: string,\n displayInput: string | undefined,\n qualifiedName: string | undefined,\n invocation: ISkillActivationEvent['invocation'],\n submit: (p: string, d?: string, r?: string) => Promise<void>,\n ): Promise<ISkillExecutionResult> {\n if (this.executing) {\n throw new Error('Cannot execute fork skill while another prompt is running.');\n }\n this.executing = true;\n this.clearStreaming();\n this.callbacks.emit('thinking', true);\n this.histTracker.append(\n messageToHistoryEntry(createUserMessage(displayInput ?? `/${skill.name}`)),\n );\n this.emitExecutionWorkspaceUpdated('main_thread');\n\n try {\n const result = await this.skillRouter.executeSkillWithActivation(\n skill,\n args,\n invocation,\n qualifiedName,\n );\n await this.applyForkSkillResult(result.result ?? '(empty response)');\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.histTracker.append(\n messageToHistoryEntry(createSystemMessage(`Error: ${error.message}`)),\n );\n this.callbacks.emit('error', error);\n return { mode: 'fork', result: '' };\n } finally {\n this.executing = false;\n this.callbacks.emit('thinking', false);\n this.emitExecutionWorkspaceUpdated('main_thread');\n this.callbacks.persistSession();\n this.drainPendingQueue(submit);\n }\n }\n\n async executeForegroundCommand(\n execute: () => Promise<ICommandResult>,\n submit: (p: string, d?: string, r?: string) => Promise<void>,\n ): Promise<ICommandResult> {\n this.executing = true;\n this.clearStreaming();\n this.callbacks.emit('thinking', true);\n this.emitExecutionWorkspaceUpdated('main_thread');\n try {\n const result = await execute();\n this.callbacks.emit('context_update', this.callbacks.getContextState());\n return result;\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n return { success: false, message: `Error: ${errMsg}` };\n } finally {\n this.executing = false;\n this.callbacks.emit('thinking', false);\n this.emitExecutionWorkspaceUpdated('main_thread');\n this.callbacks.persistSession();\n this.drainPendingQueue(submit);\n }\n }\n\n async applyForkSkillResult(result: string): Promise<void> {\n this.flushStreaming();\n pushToolSummaryToHistory({\n activeTools: this.activeTools,\n history: this.histTracker.getHistory(),\n });\n this.clearStreaming();\n const executionResult = {\n response: result,\n history: this.histTracker.getHistory(),\n toolSummaries: [],\n contextState: this.callbacks.getContextState(),\n };\n this.histTracker.append(messageToHistoryEntry(createAssistantMessage(result)));\n this.callbacks.emit('complete', executionResult);\n this.callbacks.emit('context_update', this.callbacks.getContextState());\n }\n}\n","/**\n * Fork skill execution helpers for InteractiveSession.\n *\n * Standalone functions for running skills in forked agent sessions.\n */\n\nimport { getBuiltInAgent } from '../agents/built-in-agents.js';\nimport { createSubagentSession } from '../assembly/create-subagent-session.js';\nimport { retrieveAgentToolDeps } from '../tools/agent-tool.js';\n\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type { IForkExecutionOptions } from '../commands/index.js';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport function resolveForkAgentDefinition(\n agentType: string,\n options: IForkExecutionOptions,\n parentSession: Session,\n): IAgentDefinition {\n const deps = retrieveAgentToolDeps(parentSession);\n const definition = deps?.customAgentRegistry?.(agentType) ?? getBuiltInAgent(agentType);\n if (!definition) {\n throw new Error(`Unknown agent type: ${agentType}`);\n }\n if (options.allowedTools) {\n return { ...definition, tools: options.allowedTools };\n }\n return definition;\n}\n\nexport async function runSkillInFork(\n content: string,\n options: IForkExecutionOptions,\n parentSession: Session,\n): Promise<string> {\n const deps = retrieveAgentToolDeps(parentSession);\n if (!deps) {\n throw new Error('Fork execution is not available. Agent runtime deps may not be initialized.');\n }\n const agentType = options.agent ?? 'general-purpose';\n const agentDefinition = resolveForkAgentDefinition(agentType, options, parentSession);\n const forkSession = createSubagentSession({\n agentDefinition,\n parentConfig: deps.config,\n parentContext: deps.context,\n parentTools: deps.tools,\n provider: deps.provider,\n terminal: deps.terminal,\n isForkWorker: true,\n permissionMode: deps.permissionMode,\n permissionHandler: deps.permissionHandler,\n hooks: deps.hooks,\n hookTypeExecutors: deps.hookTypeExecutors,\n onTextDelta: deps.onTextDelta,\n onToolExecution: deps.onToolExecution,\n });\n return forkSession.run(content);\n}\n","import {\n createContextReferenceItem,\n upsertContextReference,\n} from '../context/context-reference-inventory.js';\nimport {\n formatPromptFileReferenceDiagnostics,\n hasBlockingPromptFileReferenceDiagnostics,\n resolvePromptFileReferencePaths,\n toPromptFileReferenceRecords,\n} from '../context/prompt-file-references.js';\n\nimport type {\n IContextReferenceAddResult,\n IContextReferenceItem,\n} from '../context/context-reference-inventory.js';\nimport type { IPromptFileReferenceRecord } from '../context/prompt-file-references.js';\n\nexport interface IAddInteractiveContextReferenceResult {\n references: IContextReferenceItem[];\n result: IContextReferenceAddResult;\n}\n\nexport async function addInteractiveContextReference(\n references: readonly IContextReferenceItem[],\n path: string,\n cwd: string,\n): Promise<IAddInteractiveContextReferenceResult> {\n const result = await resolvePromptFileReferencePaths([path], {\n cwd,\n reason: 'manual',\n });\n if (hasBlockingPromptFileReferenceDiagnostics(result.diagnostics)) {\n return {\n references: [...references],\n result: {\n evicted: [],\n diagnostics: [formatPromptFileReferenceDiagnostics(result.diagnostics)],\n },\n };\n }\n\n const reference = result.references[0];\n if (!reference) {\n return {\n references: [...references],\n result: { evicted: [], diagnostics: ['No context reference was resolved.'] },\n };\n }\n\n const item = createContextReferenceItem(\n toPromptFileReferenceRecords([reference])[0]!,\n 'manual',\n 'active',\n );\n const upserted = upsertContextReference(references, item);\n return {\n references: upserted.references,\n result: {\n reference: item,\n evicted: upserted.evicted,\n diagnostics: [],\n },\n };\n}\n\nexport function recordInteractiveContextReferences(\n references: readonly IContextReferenceItem[],\n records: readonly IPromptFileReferenceRecord[],\n options: { loadType: 'manual' | 'prompt-reference'; status: 'active' | 'observed' },\n): IContextReferenceItem[] {\n if (records.length === 0) return [...references];\n const now = new Date().toISOString();\n let next = [...references];\n for (const record of records) {\n const item = createContextReferenceItem(record, options.loadType, options.status, now);\n next = upsertContextReference(next, item).references;\n }\n return next;\n}\n","/**\n * Standard Robota storage paths.\n *\n * All CLI runtime data lives under .robota/ (project) or ~/.robota/ (user).\n * .agents/ is read-only from CLI's perspective (owned by AGENTS.md standard).\n */\n\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/** Project-level .robota/ paths (relative to cwd). */\nexport function projectPaths(cwd: string): {\n settings: string;\n settingsLocal: string;\n logs: string;\n sessions: string;\n memory: string;\n checkpoints: string;\n} {\n const base = join(cwd, '.robota');\n return {\n settings: join(base, 'settings.json'),\n settingsLocal: join(base, 'settings.local.json'),\n logs: join(base, 'logs'),\n sessions: join(base, 'sessions'),\n memory: join(base, 'memory'),\n checkpoints: join(base, 'checkpoints'),\n };\n}\n\n/** User-level ~/.robota/ paths. */\nexport function userPaths(): {\n settings: string;\n sessions: string;\n} {\n const base = join(homedir(), '.robota');\n return {\n settings: join(base, 'settings.json'),\n sessions: join(base, 'sessions'),\n };\n}\n","import { join, relative } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type {\n IEditCheckpointInspection,\n IEditCheckpointInspectionPlan,\n IEditCheckpointManifest,\n IEditCheckpointSummary,\n} from './edit-checkpoint-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\ninterface IEditCheckpointInspectionInput {\n cwd: string;\n sessionId: string;\n target: IEditCheckpointManifest;\n manifests: readonly IEditCheckpointManifest[];\n checkpointDir: (sessionId: string, checkpointId: string) => string;\n fs?: IFileSystem;\n}\n\nexport function buildEditCheckpointInspection(\n input: IEditCheckpointInspectionInput,\n): IEditCheckpointInspection {\n const fs = input.fs ?? new NodeFileSystem();\n const later = input.manifests.filter((manifest) => manifest.sequence > input.target.sequence);\n const rollbackRange = input.manifests.filter(\n (manifest) => manifest.sequence >= input.target.sequence,\n );\n\n return {\n target: toSummary(input.target),\n capturedFiles: input.target.files.map((file) => {\n const snapshotPath = file.snapshotFile\n ? join(input.checkpointDir(input.sessionId, input.target.id), file.snapshotFile)\n : undefined;\n const snapshotStats = snapshotPath ? statSafe(snapshotPath, fs) : undefined;\n return {\n originalPath: file.originalPath,\n relativePath: relative(input.cwd, file.originalPath),\n existed: file.existed,\n restoreAction: file.existed ? 'restore-preimage' : 'delete-created-file',\n snapshotAvailable: file.existed ? snapshotStats !== undefined : false,\n ...(snapshotStats ? { snapshotSizeBytes: snapshotStats.size } : {}),\n };\n }),\n restoreToCheckpoint: toInspectionPlan(later),\n rollbackThroughCheckpoint: toInspectionPlan(rollbackRange),\n };\n}\n\nfunction toSummary(manifest: IEditCheckpointManifest): IEditCheckpointSummary {\n return {\n id: manifest.id,\n sessionId: manifest.sessionId,\n sequence: manifest.sequence,\n prompt: manifest.prompt,\n createdAt: manifest.createdAt,\n fileCount: manifest.fileCount,\n };\n}\n\nfunction toInspectionPlan(\n manifests: readonly IEditCheckpointManifest[],\n): IEditCheckpointInspectionPlan {\n return {\n checkpointIds: manifests.map((manifest) => manifest.id),\n fileCount: manifests.reduce((count, manifest) => count + manifest.fileCount, 0),\n };\n}\n\nfunction statSafe(path: string, fs: IFileSystem): { size: number } | undefined {\n try {\n return fs.statSync(path);\n } catch {\n // allow-fallback: missing snapshot file returns undefined to mark snapshot unavailable\n return undefined;\n }\n}\n","import { dirname, join, relative, resolve } from 'node:path';\n\nimport { NodeFileSystem, NodeFileSystemAsync } from '../adapters/node-file-system.js';\nimport { projectPaths } from '../paths.js';\nimport { buildEditCheckpointInspection } from './edit-checkpoint-inspection.js';\n\nimport type {\n IEditCheckpointFileRecord,\n IEditCheckpointInspection,\n IEditCheckpointManifest,\n IEditCheckpointRestoreResult,\n IEditCheckpointSummary,\n IEditCheckpointTurnInput,\n} from './edit-checkpoint-types.js';\nimport type { IFileSystem, IFileSystemAsync } from '@robota-sdk/agent-core';\n\nconst MANIFEST_FILE = 'manifest.json';\nconst SNAPSHOT_DIR = 'files';\nconst ID_PAD = 4;\nconst SNAPSHOT_PAD = 6;\ninterface IActiveEditCheckpointTurn {\n manifest: IEditCheckpointManifest;\n dir: string;\n capturedPaths: Set<string>;\n}\n\ninterface IEditCheckpointStoreOptions {\n cwd: string;\n now?: () => Date;\n}\nexport class EditCheckpointStore {\n private readonly cwd: string;\n private readonly rootDir: string;\n private readonly now: () => Date;\n private activeTurn: IActiveEditCheckpointTurn | null = null;\n\n constructor(\n options: IEditCheckpointStoreOptions,\n private readonly fs: IFileSystem = new NodeFileSystem(),\n private readonly fsAsync: IFileSystemAsync = new NodeFileSystemAsync(),\n ) {\n this.cwd = resolve(options.cwd);\n this.rootDir = projectPaths(this.cwd).checkpoints;\n this.now = options.now ?? (() => new Date());\n }\n\n async beginTurn(input: IEditCheckpointTurnInput): Promise<IEditCheckpointSummary> {\n if (this.activeTurn) {\n await this.finalizeTurn();\n }\n\n const nextSequence = this.nextSequence(input.sessionId);\n const id = `turn-${String(nextSequence).padStart(ID_PAD, '0')}`;\n const dir = join(this.sessionDir(input.sessionId), id);\n await this.fsAsync.mkdir(join(dir, SNAPSHOT_DIR), { recursive: true });\n\n const manifest: IEditCheckpointManifest = {\n version: 1,\n id,\n sessionId: input.sessionId,\n sequence: nextSequence,\n prompt: input.prompt,\n createdAt: this.now().toISOString(),\n fileCount: 0,\n files: [],\n };\n\n this.activeTurn = {\n manifest,\n dir,\n capturedPaths: new Set<string>(),\n };\n\n return toSummary(manifest);\n }\n\n async captureFile(filePath: string): Promise<void> {\n if (!this.activeTurn) return;\n\n const originalPath = resolve(this.cwd, filePath);\n if (this.activeTurn.capturedPaths.has(originalPath)) return;\n if (isInside(this.rootDir, originalPath)) return;\n\n const record = await this.createFileRecord(originalPath, this.activeTurn);\n this.activeTurn.manifest.files.push(record);\n this.activeTurn.manifest.fileCount = this.activeTurn.manifest.files.length;\n this.activeTurn.capturedPaths.add(originalPath);\n }\n\n async finalizeTurn(): Promise<IEditCheckpointSummary | undefined> {\n if (!this.activeTurn) return undefined;\n const active = this.activeTurn;\n this.activeTurn = null;\n await this.writeManifest(active.dir, active.manifest);\n return toSummary(active.manifest);\n }\n\n list(sessionId: string): IEditCheckpointSummary[] {\n return this.loadManifests(sessionId).map(toSummary);\n }\n\n inspect(sessionId: string, checkpointId: string): IEditCheckpointInspection {\n const manifests = this.loadManifests(sessionId);\n const target = manifests.find((manifest) => manifest.id === checkpointId);\n if (!target) {\n throw new Error(`Unknown edit checkpoint: ${checkpointId}`);\n }\n\n return buildEditCheckpointInspection({\n cwd: this.cwd,\n sessionId,\n target,\n manifests,\n checkpointDir: (inputSessionId, inputCheckpointId) =>\n this.checkpointDir(inputSessionId, inputCheckpointId),\n });\n }\n\n async restoreToCheckpoint(\n sessionId: string,\n checkpointId: string,\n ): Promise<IEditCheckpointRestoreResult> {\n const manifests = this.loadManifests(sessionId);\n const target = manifests.find((manifest) => manifest.id === checkpointId);\n if (!target) {\n throw new Error(`Unknown edit checkpoint: ${checkpointId}`);\n }\n\n const later = manifests\n .filter((manifest) => manifest.sequence > target.sequence)\n .sort((a, b) => b.sequence - a.sequence);\n\n let restoredFileCount = 0;\n for (const manifest of later) {\n for (const file of manifest.files) {\n await this.restoreFile(sessionId, manifest.id, file);\n restoredFileCount += 1;\n }\n }\n\n for (const manifest of later) {\n await this.fsAsync.rm(this.checkpointDir(sessionId, manifest.id), {\n recursive: true,\n force: true,\n });\n }\n\n return {\n target: toSummary(target),\n restoredCheckpointCount: later.length,\n restoredFileCount,\n removedCheckpointCount: later.length,\n };\n }\n\n async rollbackThroughCheckpoint(\n sessionId: string,\n checkpointId: string,\n ): Promise<IEditCheckpointRestoreResult> {\n const manifests = this.loadManifests(sessionId);\n const target = manifests.find((manifest) => manifest.id === checkpointId);\n if (!target) {\n throw new Error(`Unknown edit checkpoint: ${checkpointId}`);\n }\n\n const rollbackRange = manifests\n .filter((manifest) => manifest.sequence >= target.sequence)\n .sort((a, b) => b.sequence - a.sequence);\n\n let restoredFileCount = 0;\n for (const manifest of rollbackRange) {\n for (const file of manifest.files) {\n await this.restoreFile(sessionId, manifest.id, file);\n restoredFileCount += 1;\n }\n }\n\n for (const manifest of rollbackRange) {\n await this.fsAsync.rm(this.checkpointDir(sessionId, manifest.id), {\n recursive: true,\n force: true,\n });\n }\n\n return {\n target: toSummary(target),\n restoredCheckpointCount: rollbackRange.length,\n restoredFileCount,\n removedCheckpointCount: rollbackRange.length,\n };\n }\n\n private async createFileRecord(\n originalPath: string,\n active: IActiveEditCheckpointTurn,\n ): Promise<IEditCheckpointFileRecord> {\n const existed = await pathExists(this.fsAsync, this.fs, originalPath);\n if (!existed) {\n return {\n originalPath,\n existed: false,\n };\n }\n\n const snapshotFile = join(\n SNAPSHOT_DIR,\n `${String(active.manifest.files.length + 1).padStart(SNAPSHOT_PAD, '0')}.content`,\n );\n await this.fsAsync.copyFile(originalPath, join(active.dir, snapshotFile));\n return {\n originalPath,\n existed: true,\n snapshotFile,\n };\n }\n\n private async restoreFile(\n sessionId: string,\n checkpointId: string,\n record: IEditCheckpointFileRecord,\n ): Promise<void> {\n if (!record.existed) {\n await this.fsAsync.rm(record.originalPath, { force: true });\n return;\n }\n if (!record.snapshotFile) {\n throw new Error(`Checkpoint file record is missing a snapshot: ${record.originalPath}`);\n }\n await this.fsAsync.mkdir(dirname(record.originalPath), { recursive: true });\n await this.fsAsync.copyFile(\n join(this.checkpointDir(sessionId, checkpointId), record.snapshotFile),\n record.originalPath,\n );\n }\n\n private loadManifests(sessionId: string): IEditCheckpointManifest[] {\n const dir = this.sessionDir(sessionId);\n return readDirSyncSafe(this.fs, dir)\n .map((entry) => join(dir, entry, MANIFEST_FILE))\n .map((manifestPath) => readJsonManifest(this.fs, manifestPath))\n .filter((manifest): manifest is IEditCheckpointManifest => manifest !== undefined)\n .sort((a, b) => a.sequence - b.sequence);\n }\n\n private nextSequence(sessionId: string): number {\n const last = this.list(sessionId).at(-1);\n return (last?.sequence ?? 0) + 1;\n }\n\n private async writeManifest(dir: string, manifest: IEditCheckpointManifest): Promise<void> {\n await this.fsAsync.mkdir(dir, { recursive: true });\n const path = join(dir, MANIFEST_FILE);\n const tmp = `${path}.tmp`;\n await this.fsAsync.writeFile(tmp, JSON.stringify(manifest, null, 2), 'utf8');\n await this.fsAsync.rename(tmp, path);\n }\n\n private sessionDir(sessionId: string): string {\n return join(this.rootDir, safePathSegment(sessionId));\n }\n\n private checkpointDir(sessionId: string, checkpointId: string): string {\n return join(this.sessionDir(sessionId), safePathSegment(checkpointId));\n }\n}\n\nfunction toSummary(manifest: IEditCheckpointManifest): IEditCheckpointSummary {\n return {\n id: manifest.id,\n sessionId: manifest.sessionId,\n sequence: manifest.sequence,\n prompt: manifest.prompt,\n createdAt: manifest.createdAt,\n fileCount: manifest.fileCount,\n };\n}\n\nfunction safePathSegment(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]/g, '_');\n}\n\nfunction isInside(parent: string, child: string): boolean {\n const rel = relative(parent, child);\n return rel.length === 0 || (!rel.startsWith('..') && !rel.startsWith('/'));\n}\n\nasync function pathExists(\n fsAsync: IFileSystemAsync,\n fs: IFileSystem,\n path: string,\n): Promise<boolean> {\n try {\n await fsAsync.access(path, fs.constants.F_OK);\n return true;\n } catch {\n // allow-fallback: access failure means file absent, false is the correct result\n return false;\n }\n}\n\nfunction readDirSyncSafe(fs: IFileSystem, dir: string): string[] {\n try {\n return fs.readdirSync(dir);\n } catch {\n // allow-fallback: missing directory returns empty list, not an error\n return [];\n }\n}\n\nfunction readJsonManifest(fs: IFileSystem, path: string): IEditCheckpointManifest | undefined {\n try {\n const raw = fs.readFileSync(path, 'utf8');\n return JSON.parse(raw) as IEditCheckpointManifest;\n } catch {\n // allow-fallback: corrupted/missing manifest is filtered out by caller\n return undefined;\n }\n}\n","import type { ICommand } from '../command-api/types.js';\n\nexport type TSkillActivationSource = 'skill' | 'plugin';\nexport type TSkillActivationInvocation = 'user-slash' | 'model-tool';\nexport type TSkillActivationMode = 'inject' | 'fork';\nexport type TSkillActivationStatus = 'started' | 'completed' | 'failed';\n\nexport interface ISkillActivationEvent {\n readonly type: 'skill-activation';\n readonly skillName: string;\n readonly source: TSkillActivationSource;\n readonly invocation: TSkillActivationInvocation;\n readonly mode: TSkillActivationMode;\n readonly status: TSkillActivationStatus;\n readonly timestamp: string;\n readonly qualifiedName?: string;\n readonly error?: string;\n}\n\nexport interface ISkillActivationHistoryData extends ISkillActivationEvent {\n readonly message: string;\n}\n\nexport interface ICreateSkillActivationEventInput {\n readonly skill: ICommand;\n readonly invocation: TSkillActivationInvocation;\n readonly status: TSkillActivationStatus;\n readonly qualifiedName?: string;\n readonly error?: string;\n}\n\nexport function getSkillActivationSource(skill: ICommand): TSkillActivationSource {\n return skill.source === 'plugin' ? 'plugin' : 'skill';\n}\n\nexport function getSkillActivationMode(skill: ICommand): TSkillActivationMode {\n return skill.context === 'fork' ? 'fork' : 'inject';\n}\n\nexport function createSkillActivationEvent(\n input: ICreateSkillActivationEventInput,\n): ISkillActivationEvent {\n return {\n type: 'skill-activation',\n skillName: input.skill.name,\n source: getSkillActivationSource(input.skill),\n invocation: input.invocation,\n mode: getSkillActivationMode(input.skill),\n status: input.status,\n timestamp: new Date().toISOString(),\n ...(input.qualifiedName !== undefined ? { qualifiedName: input.qualifiedName } : {}),\n ...(input.error !== undefined ? { error: input.error } : {}),\n };\n}\n\nexport function formatSkillActivationMessage(event: ISkillActivationEvent): string {\n const sourceLabel = event.source === 'plugin' ? 'plugin skill' : 'skill';\n if (event.status === 'failed') {\n return `Skill failed: ${event.skillName}${event.error ? ` (${event.error})` : ''}`;\n }\n if (event.status === 'completed') {\n return `Skill completed: ${event.skillName}`;\n }\n return `Invoking ${sourceLabel}: ${event.skillName}`;\n}\n","/**\n * SessionHistoryTracker — manages history, edit checkpoints, memory events,\n * context references, and skill activation events for an InteractiveSession.\n */\n\nimport { randomUUID } from 'node:crypto';\n\nimport { createSystemMessage, messageToHistoryEntry } from '@robota-sdk/agent-core';\n\nimport {\n addInteractiveContextReference,\n recordInteractiveContextReferences,\n} from './interactive-session-context-references.js';\nimport { EditCheckpointStore } from '../checkpoints/edit-checkpoint-store.js';\nimport { formatSkillActivationMessage } from '../commands/skill-activation-events.js';\nimport {\n clearContextReferences,\n removeContextReference,\n} from '../context/context-reference-inventory.js';\n\nimport type {\n IEditCheckpointInspection,\n IEditCheckpointRestoreResult,\n IEditCheckpointSummary,\n} from '../checkpoints/edit-checkpoint-types.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type {\n IContextReferenceAddResult,\n IContextReferenceClearResult,\n IContextReferenceItem,\n IContextReferenceRemoveResult,\n} from '../context/context-reference-inventory.js';\nimport type { IPromptFileReferenceRecord } from '../context/prompt-file-references.js';\nimport type { IMemoryEvent, IMemoryReference } from '../memory/automatic-memory-types.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\n\nexport interface IHistoryTrackerState {\n history: IHistoryEntry[];\n memoryEvents: IMemoryEvent[];\n usedMemoryReferences: IMemoryReference[];\n contextReferences: IContextReferenceItem[];\n skillActivationEvents: ISkillActivationEvent[];\n}\n\nexport class SessionHistoryTracker {\n private history: IHistoryEntry[] = [];\n private editCheckpointStore: EditCheckpointStore | null = null;\n private memoryEvents: IMemoryEvent[] = [];\n private usedMemoryReferences: IMemoryReference[] = [];\n private contextReferences: IContextReferenceItem[] = [];\n private skillActivationEvents: ISkillActivationEvent[] = [];\n\n constructor(\n private readonly cwd: string,\n private readonly getSessionId: () => string,\n private readonly getExecuting: () => boolean,\n private readonly persistSession: () => void,\n private readonly emitSkillActivation: (event: ISkillActivationEvent) => void,\n editCheckpointStore: EditCheckpointStore | null = null,\n ) {\n this.editCheckpointStore = editCheckpointStore;\n }\n\n restoreState(state: IHistoryTrackerState): void {\n this.history = state.history;\n this.memoryEvents = state.memoryEvents;\n this.usedMemoryReferences = state.usedMemoryReferences;\n this.contextReferences = state.contextReferences;\n this.skillActivationEvents = state.skillActivationEvents;\n }\n\n getState(): IHistoryTrackerState {\n return {\n history: this.history,\n memoryEvents: this.memoryEvents,\n usedMemoryReferences: this.usedMemoryReferences,\n contextReferences: this.contextReferences,\n skillActivationEvents: this.skillActivationEvents,\n };\n }\n\n append(entry: IHistoryEntry): void {\n this.history.push(entry);\n }\n\n getHistory(): IHistoryEntry[] {\n return this.history;\n }\n\n clearHistory(): void {\n this.history = [];\n this.memoryEvents = [];\n this.usedMemoryReferences = [];\n }\n\n resetUsedMemoryReferences(): void {\n this.usedMemoryReferences = [];\n }\n\n recordContextReferenceUsage(records: readonly IPromptFileReferenceRecord[]): void {\n this.contextReferences = recordInteractiveContextReferences(this.contextReferences, records, {\n loadType: 'manual',\n status: 'active',\n });\n this.persistSession();\n }\n\n recordPromptContextReferences(records: readonly IPromptFileReferenceRecord[]): void {\n this.contextReferences = recordInteractiveContextReferences(this.contextReferences, records, {\n loadType: 'prompt-reference',\n status: 'observed',\n });\n this.persistSession();\n }\n\n listEditCheckpoints(): IEditCheckpointSummary[] {\n const sessionId = this.getSessionId();\n return this.getCheckpointStore().list(sessionId);\n }\n\n inspectEditCheckpoint(checkpointId: string): IEditCheckpointInspection {\n const sessionId = this.getSessionId();\n return this.getCheckpointStore().inspect(sessionId, checkpointId);\n }\n\n async restoreEditCheckpoint(checkpointId: string): Promise<IEditCheckpointRestoreResult> {\n if (this.getExecuting()) {\n throw new Error('Cannot restore edit checkpoint while a prompt is running.');\n }\n const result = await this.getCheckpointStore().restoreToCheckpoint(\n this.getSessionId(),\n checkpointId,\n );\n this.history.push(\n messageToHistoryEntry(createSystemMessage(`Restored edit checkpoint: ${checkpointId}`)),\n );\n this.persistSession();\n return result;\n }\n\n async rollbackEditCheckpoint(checkpointId: string): Promise<IEditCheckpointRestoreResult> {\n if (this.getExecuting()) {\n throw new Error('Cannot rollback edit checkpoint while a prompt is running.');\n }\n const result = await this.getCheckpointStore().rollbackThroughCheckpoint(\n this.getSessionId(),\n checkpointId,\n );\n this.history.push(\n messageToHistoryEntry(createSystemMessage(`Rolled back edit checkpoint: ${checkpointId}`)),\n );\n this.persistSession();\n return result;\n }\n\n async beginEditCheckpointTurn(prompt: string): Promise<void> {\n if (!this.editCheckpointStore) return;\n await this.editCheckpointStore.beginTurn({ sessionId: this.getSessionId(), prompt });\n }\n\n async finalizeEditCheckpointTurn(): Promise<void> {\n if (!this.editCheckpointStore) return;\n try {\n await this.editCheckpointStore.finalizeTurn();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.history.push(\n messageToHistoryEntry(createSystemMessage(`Checkpoint error: ${err.message}`)),\n );\n throw err;\n }\n }\n\n setEditCheckpointStore(store: EditCheckpointStore): void {\n this.editCheckpointStore = store;\n }\n\n getUsedMemoryReferences(): IMemoryReference[] {\n return [...this.usedMemoryReferences];\n }\n\n recordMemoryEvent(event: IMemoryEvent): void {\n this.memoryEvents.push(event);\n this.persistSession();\n }\n\n listContextReferences(): IContextReferenceItem[] {\n return [...this.contextReferences];\n }\n\n async addContextReference(path: string): Promise<IContextReferenceAddResult> {\n const { references, result } = await addInteractiveContextReference(\n this.contextReferences,\n path,\n this.cwd,\n );\n this.contextReferences = references;\n this.persistSession();\n return result;\n }\n\n removeContextReference(path: string): IContextReferenceRemoveResult {\n const result = removeContextReference(this.contextReferences, path);\n this.contextReferences = result.references;\n this.persistSession();\n return result.result;\n }\n\n clearContextReferences(): IContextReferenceClearResult {\n const result = clearContextReferences(this.contextReferences);\n this.contextReferences = [];\n this.persistSession();\n return result;\n }\n\n getSkillActivationEvents(): ISkillActivationEvent[] {\n return [...this.skillActivationEvents];\n }\n\n recordSkillActivationEvent(event: ISkillActivationEvent, appendHistory: boolean): void {\n this.skillActivationEvents.push(event);\n if (appendHistory) {\n this.history.push({\n id: randomUUID(),\n timestamp: new Date(event.timestamp),\n category: 'event',\n type: 'skill-activation',\n data: {\n ...event,\n message: formatSkillActivationMessage(event),\n },\n });\n }\n this.emitSkillActivation(event);\n this.persistSession();\n }\n\n private getCheckpointStore(): EditCheckpointStore {\n if (!this.editCheckpointStore) {\n this.editCheckpointStore = new EditCheckpointStore({ cwd: this.cwd });\n }\n return this.editCheckpointStore;\n }\n}\n","/**\n * Project detector — infers project type, name, package manager, and language\n * from files present in the given directory.\n */\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\n\nexport type TProjectType = 'node' | 'python' | 'rust' | 'go' | 'unknown';\nexport type TPackageManager = 'pnpm' | 'yarn' | 'npm' | 'bun';\nexport type TLanguage = 'typescript' | 'javascript' | 'python' | 'rust' | 'go' | 'unknown';\n\nexport interface IProjectInfo {\n type: TProjectType;\n name?: string;\n packageManager?: TPackageManager;\n language: TLanguage;\n}\n\ninterface IPackageJson {\n name?: string;\n packageManager?: string;\n}\n\nfunction tryReadJson(filePath: string): IPackageJson | undefined {\n if (!existsSync(filePath)) return undefined;\n try {\n return JSON.parse(readFileSync(filePath, 'utf-8')) as IPackageJson;\n } catch {\n return undefined;\n }\n}\n\nfunction detectPackageManager(cwd: string): TPackageManager | undefined {\n if (existsSync(join(cwd, 'pnpm-workspace.yaml')) || existsSync(join(cwd, 'pnpm-lock.yaml'))) {\n return 'pnpm';\n }\n if (existsSync(join(cwd, 'yarn.lock'))) {\n return 'yarn';\n }\n if (existsSync(join(cwd, 'bun.lockb'))) {\n return 'bun';\n }\n if (existsSync(join(cwd, 'package-lock.json'))) {\n return 'npm';\n }\n return undefined;\n}\n\n/**\n * Detect the project type, language, name, and package manager from `cwd`.\n */\nexport async function detectProject(cwd: string): Promise<IProjectInfo> {\n const pkgJsonPath = join(cwd, 'package.json');\n const tsconfigPath = join(cwd, 'tsconfig.json');\n const pyprojectPath = join(cwd, 'pyproject.toml');\n const cargoPath = join(cwd, 'Cargo.toml');\n const goModPath = join(cwd, 'go.mod');\n\n // Node.js project\n if (existsSync(pkgJsonPath)) {\n const pkgJson = tryReadJson(pkgJsonPath);\n const language: TLanguage = existsSync(tsconfigPath) ? 'typescript' : 'javascript';\n const packageManager = detectPackageManager(cwd);\n return {\n type: 'node',\n name: pkgJson?.name,\n packageManager,\n language,\n };\n }\n\n // Python project\n if (existsSync(pyprojectPath) || existsSync(join(cwd, 'setup.py'))) {\n return {\n type: 'python',\n language: 'python',\n };\n }\n\n // Rust project\n if (existsSync(cargoPath)) {\n return {\n type: 'rust',\n language: 'rust',\n };\n }\n\n // Go project\n if (existsSync(goModPath)) {\n return {\n type: 'go',\n language: 'go',\n };\n }\n\n return {\n type: 'unknown',\n language: 'unknown',\n };\n}\n","/**\n * Session restore helpers for InteractiveSession.\n *\n * Handles message injection into an existing session and loading a persisted\n * session record back into the tracker state on resume/fork.\n */\n\nimport type { IInteractiveSessionStore } from './session-persistence.js';\nimport type {\n IBackgroundJobGroupState,\n IBackgroundTaskState,\n TBackgroundJobGroupEvent,\n TBackgroundTaskEvent,\n TBackgroundTaskStatus,\n} from '../background-tasks/index.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type { IContextReferenceItem } from '../context/context-reference-inventory.js';\nimport type { IMemoryEvent, IMemoryReference } from '../memory/automatic-memory-types.js';\nimport type { TUniversalMessage, IHistoryEntry } from '@robota-sdk/agent-core';\nimport type { Session } from '@robota-sdk/agent-session';\n\n/** Inject a saved message into a session, supporting all roles including 'tool'. */\nexport function injectSavedMessage(session: Session, msg: TUniversalMessage): void {\n if (typeof msg.content !== 'string') return;\n if (msg.role === 'tool') {\n session.injectMessage('tool', msg.content, {\n toolCallId: msg.toolCallId,\n ...(msg.name !== undefined ? { name: msg.name } : {}),\n });\n } else {\n session.injectMessage(msg.role, msg.content);\n }\n}\n\n/**\n * Restore session history and messages from a persisted session record.\n * Returns the loaded history and any pending messages that need injection once session is ready.\n */\nexport function loadSessionRecord(\n sessionStore: IInteractiveSessionStore,\n resumeSessionId: string,\n forkSession: boolean,\n existingSession: Session | null,\n): {\n history: IHistoryEntry[];\n sessionName: string | undefined;\n pendingRestoreMessages: TUniversalMessage[] | null;\n backgroundTasks: IBackgroundTaskState[];\n backgroundTaskEvents: TBackgroundTaskEvent[];\n backgroundJobGroups: IBackgroundJobGroupState[];\n backgroundJobGroupEvents: TBackgroundJobGroupEvent[];\n skillActivationEvents: ISkillActivationEvent[];\n memoryEvents: IMemoryEvent[];\n usedMemoryReferences: IMemoryReference[];\n contextReferences: IContextReferenceItem[];\n sandboxSnapshotId: string | undefined;\n} {\n const record = sessionStore.load(resumeSessionId);\n if (!record) {\n return {\n history: [],\n sessionName: undefined,\n pendingRestoreMessages: null,\n backgroundTasks: [],\n backgroundTaskEvents: [],\n backgroundJobGroups: [],\n backgroundJobGroupEvents: [],\n skillActivationEvents: [],\n memoryEvents: [],\n usedMemoryReferences: [],\n contextReferences: [],\n sandboxSnapshotId: undefined,\n };\n }\n\n const history = record.history ?? [];\n const restoredBackgroundTasks = record.backgroundTasks ?? [];\n const restoredBackgroundTaskEvents = record.backgroundTaskEvents ?? [];\n const backgroundJobGroups = record.backgroundJobGroups ?? [];\n const backgroundJobGroupEvents = record.backgroundJobGroupEvents ?? [];\n const skillActivationEvents = record.skillActivationEvents ?? [];\n const memoryEvents = record.memoryEvents ?? [];\n const usedMemoryReferences = record.usedMemoryReferences ?? [];\n const contextReferences = record.contextReferences ?? [];\n const sandboxSnapshotId = record.sandboxSnapshotId;\n const { backgroundTasks, backgroundTaskEvents } = reconcileRestoredBackgroundTasks(\n restoredBackgroundTasks,\n restoredBackgroundTaskEvents,\n );\n const sessionName = record.name;\n let pendingRestoreMessages: TUniversalMessage[] | null = null;\n\n if (!forkSession && record.messages) {\n if (existingSession) {\n for (const msg of record.messages) {\n injectSavedMessage(existingSession, msg);\n }\n } else {\n pendingRestoreMessages = record.messages;\n }\n }\n\n return {\n history,\n sessionName,\n pendingRestoreMessages,\n backgroundTasks,\n backgroundTaskEvents,\n backgroundJobGroups,\n backgroundJobGroupEvents,\n skillActivationEvents,\n memoryEvents,\n usedMemoryReferences,\n contextReferences,\n sandboxSnapshotId,\n };\n}\n\nfunction reconcileRestoredBackgroundTasks(\n tasks: IBackgroundTaskState[],\n events: TBackgroundTaskEvent[],\n): { backgroundTasks: IBackgroundTaskState[]; backgroundTaskEvents: TBackgroundTaskEvent[] } {\n const now = new Date().toISOString();\n const syntheticEvents: TBackgroundTaskEvent[] = [];\n const backgroundTasks = tasks.map((task) => {\n if (isRestoredTerminalStatus(task.status)) return task;\n const reconciled: IBackgroundTaskState = {\n ...task,\n status: 'failed',\n timeoutReason: 'stale_worker',\n error: {\n category: 'timeout',\n message: 'Restored background task is stale; worker cannot be reattached',\n recoverable: true,\n },\n unread: true,\n completedAt: now,\n updatedAt: now,\n };\n syntheticEvents.push({ type: 'background_task_failed', task: reconciled });\n return reconciled;\n });\n return {\n backgroundTasks,\n backgroundTaskEvents: [...events, ...syntheticEvents],\n };\n}\n\nfunction isRestoredTerminalStatus(status: TBackgroundTaskStatus): boolean {\n return status === 'completed' || status === 'failed' || status === 'cancelled';\n}\n","import { runHooks } from '@robota-sdk/agent-core';\n\nimport type { TBackgroundTaskEvent } from '../background-tasks/index.js';\nimport type {\n IHookInput,\n IHookTypeExecutor,\n THooksConfig,\n THookEvent,\n} from '@robota-sdk/agent-core';\n\nfunction getSubagentHookEvent(event: TBackgroundTaskEvent): THookEvent | undefined {\n if (event.type === 'background_task_started' && event.task.kind === 'agent') {\n return 'SubagentStart';\n }\n if (\n (event.type === 'background_task_completed' ||\n event.type === 'background_task_failed' ||\n event.type === 'background_task_cancelled') &&\n event.task.kind === 'agent'\n ) {\n return 'SubagentStop';\n }\n return undefined;\n}\n\nexport function fireSubagentLifecycleHook(\n event: TBackgroundTaskEvent,\n cwd: string,\n hooks: THooksConfig | undefined,\n hookTypeExecutors: IHookTypeExecutor[] | undefined,\n): void {\n const hookEventName = getSubagentHookEvent(event);\n if (!hookEventName || !('task' in event)) return;\n\n const input: IHookInput = {\n session_id: event.task.parentSessionId,\n cwd,\n hook_event_name: hookEventName,\n agent_id: event.task.id,\n agent_type: event.task.agentType ?? event.task.label,\n ...(event.task.transcriptPath\n ? {\n agent_transcript_path: event.task.transcriptPath,\n transcript_path: event.task.transcriptPath,\n }\n : {}),\n ...(event.task.error?.message || event.task.timeoutReason\n ? { reason: event.task.error?.message ?? event.task.timeoutReason }\n : {}),\n ...(hookEventName === 'SubagentStop'\n ? {\n stop_hook_active: false,\n ...(event.task.result?.output\n ? { last_assistant_message: event.task.result.output }\n : {}),\n }\n : {}),\n env: {\n CLAUDE_PROJECT_DIR: cwd,\n CLAUDE_SESSION_ID: event.task.parentSessionId,\n ROBOTA_AGENT_ID: event.task.id,\n ROBOTA_AGENT_TYPE: event.task.agentType ?? event.task.label,\n },\n };\n\n void runHooks(hooks, hookEventName, input, hookTypeExecutors).catch(() => undefined);\n}\n","/**\n * Default tool set factory — creates the standard set of CLI tools.\n */\n\nimport {\n createBashTool,\n createReadTool,\n createWriteTool,\n createEditTool,\n globTool,\n grepTool,\n webFetchTool,\n webSearchTool,\n} from '@robota-sdk/agent-tools';\n\nimport type { IToolWithEventService } from '@robota-sdk/agent-core';\nimport type { ISandboxClient } from '@robota-sdk/agent-tools';\n\n/** Human-readable descriptions of the built-in tools (for system prompt) */\nexport const DEFAULT_TOOL_DESCRIPTIONS = [\n 'Bash — execute shell commands',\n 'Read — read file contents with line numbers',\n 'Write — write content to a file',\n 'Edit — replace a string in a file',\n 'Glob — find files matching a pattern',\n 'Grep — search file contents with regex',\n 'WebFetch — fetch URL content as text',\n 'WebSearch — search the internet through the configured local tool',\n];\n\n/**\n * Create the default set of CLI tools.\n * Returns the 8 standard tools as IToolWithEventService[].\n */\nexport interface ICreateDefaultToolsOptions {\n sandboxClient?: ISandboxClient;\n}\n\nexport function createDefaultTools(\n options: ICreateDefaultToolsOptions = {},\n): IToolWithEventService[] {\n return [\n createBashTool(options) as IToolWithEventService,\n createReadTool(options) as IToolWithEventService,\n createWriteTool(options) as IToolWithEventService,\n createEditTool(options) as IToolWithEventService,\n globTool as IToolWithEventService,\n grepTool as IToolWithEventService,\n webFetchTool as IToolWithEventService,\n webSearchTool as IToolWithEventService,\n ];\n}\n","import { homedir } from 'node:os';\nimport { join, basename } from 'node:path';\n\nimport { BUILT_IN_AGENTS } from './built-in-agents.js';\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { IAgentDefinition } from './agent-definition-types.js';\nimport type { IFileSystem, IDirent } from '@robota-sdk/agent-core';\n\n/** Known frontmatter keys that should be parsed as comma-separated or whitespace-separated lists. */\nconst LIST_KEYS = new Set(['tools', 'disallowedTools']);\n\n/** Known frontmatter keys that should be parsed as numbers. */\nconst NUMBER_KEYS = new Set(['maxTurns']);\n\ninterface IRawFrontmatter {\n name?: string;\n description?: string;\n model?: string;\n maxTurns?: number;\n tools?: string[];\n disallowedTools?: string[];\n}\n\nfunction parseListValue(rawValue: string): string[] {\n const separator = rawValue.includes(',') ? /\\s*,\\s*/ : /\\s+/;\n return rawValue\n .split(separator)\n .map((value) => value.trim())\n .filter((value) => value.length > 0);\n}\n\n/**\n * Parse simple YAML-like frontmatter between `---` markers.\n * Returns null when no frontmatter block is found.\n */\nfunction parseFrontmatter(content: string): { frontmatter: IRawFrontmatter | null; body: string } {\n const lines = content.split('\\n');\n if (lines[0]?.trim() !== '---') {\n return { frontmatter: null, body: content };\n }\n\n let endIndex = -1;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i]?.trim() === '---') {\n endIndex = i;\n break;\n }\n }\n\n if (endIndex === -1) {\n return { frontmatter: null, body: content };\n }\n\n const result: Record<string, unknown> = {};\n\n for (let i = 1; i < endIndex; i++) {\n const line = lines[i]!;\n const match = line.match(/^([a-zA-Z][a-zA-Z0-9]*(?:[A-Z][a-z]*)*):\\s*(.+)/);\n if (!match) continue;\n\n const key = match[1]!;\n const rawValue = match[2]!.trim();\n\n if (LIST_KEYS.has(key)) {\n result[key] = parseListValue(rawValue);\n } else if (NUMBER_KEYS.has(key)) {\n result[key] = parseInt(rawValue, 10);\n } else {\n result[key] = rawValue;\n }\n }\n\n const body = lines\n .slice(endIndex + 1)\n .join('\\n')\n .trim();\n\n return {\n frontmatter: Object.keys(result).length > 0 ? (result as IRawFrontmatter) : null,\n body,\n };\n}\n\n/** Scan a directory for .md files and return parsed agent definitions. */\nfunction scanAgentsDir(dir: string, fs: IFileSystem): IAgentDefinition[] {\n if (!fs.existsSync(dir)) return [];\n\n const agents: IAgentDefinition[] = [];\n let entries: IDirent[];\n\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n // allow-fallback: unreadable agents directory returns empty list\n return [];\n }\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md')) continue;\n\n const filePath = join(dir, entry.name);\n const content = fs.readFileSync(filePath, 'utf-8');\n const { frontmatter, body } = parseFrontmatter(content);\n const fallbackName = basename(entry.name, '.md');\n\n const agent: IAgentDefinition = {\n name: frontmatter?.name ?? fallbackName,\n description: frontmatter?.description ?? '',\n systemPrompt: body,\n };\n\n if (frontmatter?.model !== undefined) agent.model = frontmatter.model;\n if (frontmatter?.maxTurns !== undefined) agent.maxTurns = frontmatter.maxTurns;\n if (frontmatter?.tools !== undefined) agent.tools = frontmatter.tools;\n if (frontmatter?.disallowedTools !== undefined)\n agent.disallowedTools = frontmatter.disallowedTools;\n\n agents.push(agent);\n }\n\n return agents;\n}\n\n/**\n * Loads agent definitions from project and user directories, merging\n * them with built-in agents.\n *\n * Scan directories (highest priority first):\n * 1. `<cwd>/.robota/agents/` — project-level Robota native\n * 2. `<cwd>/.agents/agents/` — project-level Robota repository convention\n * 3. `<cwd>/.claude/agents/` — project-level Claude Code compatible\n * 4. `<home>/.robota/agents/` — user-level Robota native\n * 5. `<home>/.claude/agents/` — user-level Claude Code compatible\n *\n * Custom agents override built-in agents on name collision.\n */\nexport class AgentDefinitionLoader {\n private readonly cwd: string;\n private readonly home: string;\n private readonly fs: IFileSystem;\n\n constructor(cwd: string, home?: string, fs: IFileSystem = new NodeFileSystem()) {\n this.cwd = cwd;\n this.home = home ?? homedir();\n this.fs = fs;\n }\n\n /** Load all agent definitions, merged with built-in agents. Custom overrides built-in on name collision. */\n loadAll(): IAgentDefinition[] {\n const sources: IAgentDefinition[][] = [\n scanAgentsDir(join(this.cwd, '.robota', 'agents'), this.fs),\n scanAgentsDir(join(this.cwd, '.agents', 'agents'), this.fs),\n scanAgentsDir(join(this.cwd, '.claude', 'agents'), this.fs),\n scanAgentsDir(join(this.home, '.robota', 'agents'), this.fs),\n scanAgentsDir(join(this.home, '.claude', 'agents'), this.fs),\n ];\n\n // Deduplicate custom agents: higher-priority source wins\n const seen = new Set<string>();\n const customAgents: IAgentDefinition[] = [];\n\n for (const agents of sources) {\n for (const agent of agents) {\n if (!seen.has(agent.name)) {\n seen.add(agent.name);\n customAgents.push(agent);\n }\n }\n }\n\n // Merge with built-in: custom overrides built-in on name collision\n const result = [...customAgents];\n for (const builtIn of BUILT_IN_AGENTS) {\n if (!seen.has(builtIn.name)) {\n result.push(builtIn);\n }\n }\n\n return result;\n }\n\n /** Get a specific agent by name (custom or built-in). */\n getAgent(name: string): IAgentDefinition | undefined {\n return this.loadAll().find((agent) => agent.name === name);\n }\n}\n","import type { ISystemPromptSection } from './system-prompt-types.js';\n\nfunction renderSection(section: ISystemPromptSection): string {\n const content = section.content.trim();\n if (!section.title) return content;\n return [`## ${section.title}`, content].join('\\n');\n}\n\nexport function composeSystemPrompt(sections: readonly ISystemPromptSection[]): string {\n return [...sections]\n .filter((section) => section.content.trim().length > 0)\n .sort((a, b) => a.priority - b.priority || a.id.localeCompare(b.id))\n .map((section) => renderSection(section))\n .join('\\n\\n');\n}\n","import type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { TTrustLevel } from '../types.js';\nimport type { IProjectInfo } from './project-detector.js';\nimport type { ISystemPromptSection } from './system-prompt-types.js';\n\nconst TRUST_LEVEL_LABELS: Record<TTrustLevel, string> = {\n safe: 'safe',\n moderate: 'moderate',\n full: 'full',\n};\nconst PROJECT_MEMORY_PRIORITY = Number('25');\nconst TASK_CONTEXT_PRIORITY = Number('27');\n\nfunction createSection(\n id: string,\n title: string | undefined,\n priority: number,\n content: string,\n source: ISystemPromptSection['source'],\n): ISystemPromptSection {\n return { id, title, priority, content, source };\n}\n\nexport function createWorkingDirectorySection(cwd?: string): ISystemPromptSection | undefined {\n if (!cwd) return undefined;\n return createSection('runtime-cwd', 'Working Directory', 30, `\\`${cwd}\\``, 'runtime');\n}\n\nexport function createProjectSection(info: IProjectInfo): ISystemPromptSection {\n const lines: string[] = [];\n if (info.name !== undefined) {\n lines.push(`- **Name:** ${info.name}`);\n }\n if (info.type !== 'unknown') {\n lines.push(`- **Type:** ${info.type}`);\n }\n if (info.language !== 'unknown') {\n lines.push(`- **Language:** ${info.language}`);\n }\n if (info.packageManager !== undefined) {\n lines.push(`- **Package manager:** ${info.packageManager}`);\n }\n return createSection('runtime-project', 'Current Project', 40, lines.join('\\n'), 'runtime');\n}\n\nexport function createPermissionSection(trustLevel: TTrustLevel): ISystemPromptSection {\n return createSection(\n 'permission-mode',\n 'Permission Mode',\n 50,\n `- **Trust level:** ${TRUST_LEVEL_LABELS[trustLevel]}`,\n 'permissions',\n );\n}\n\nexport function createResponseLanguageSection(language?: string): ISystemPromptSection | undefined {\n if (language === undefined || language.trim().length === 0) return undefined;\n return createSection('runtime-response-language', 'Response Language', 45, language, 'runtime');\n}\n\nexport function createAgentsMdSection(agentsMd: string): ISystemPromptSection | undefined {\n if (agentsMd.trim().length === 0) return undefined;\n return createSection(\n 'project-agents-md',\n 'Agent Instructions',\n 10,\n agentsMd,\n 'project-instructions',\n );\n}\n\nexport function createClaudeMdSection(claudeMd: string): ISystemPromptSection | undefined {\n if (claudeMd.trim().length === 0) return undefined;\n return createSection('project-claude-md', 'Project Notes', 20, claudeMd, 'project-instructions');\n}\n\nexport function createProjectMemorySection(memoryMd?: string): ISystemPromptSection | undefined {\n if (memoryMd === undefined || memoryMd.trim().length === 0) return undefined;\n return createSection(\n 'project-memory',\n 'Project Memory',\n PROJECT_MEMORY_PRIORITY,\n memoryMd,\n 'project-instructions',\n );\n}\n\nexport function createTaskContextSection(taskContext?: string): ISystemPromptSection | undefined {\n if (taskContext === undefined || taskContext.trim().length === 0) return undefined;\n return createSection(\n 'active-task-context',\n 'Active Task Context',\n TASK_CONTEXT_PRIORITY,\n taskContext,\n 'project-instructions',\n );\n}\n\nexport function createToolDescriptionSection(\n descriptions: readonly string[],\n): ISystemPromptSection | undefined {\n if (descriptions.length === 0) return undefined;\n return createSection(\n 'tool-descriptions',\n 'Available Tools',\n 60,\n descriptions.map((description) => `- ${description}`).join('\\n'),\n 'tool',\n );\n}\n\nfunction formatCapability(descriptor: ICapabilityDescriptor): string {\n const arg = descriptor.argumentHint ? ` ${descriptor.argumentHint}` : '';\n return `- ${descriptor.name}${arg}: ${descriptor.description}`;\n}\n\nfunction createCapabilityKindSection(\n kind: ICapabilityDescriptor['kind'],\n title: string,\n priority: number,\n source: ISystemPromptSection['source'],\n descriptors: readonly ICapabilityDescriptor[],\n): ISystemPromptSection | undefined {\n const formattedDescriptors = descriptors\n .filter((descriptor) => descriptor.modelInvocable && descriptor.kind === kind)\n .map(formatCapability);\n if (formattedDescriptors.length === 0) return undefined;\n return createSection(\n `capability-${kind}`,\n title,\n priority,\n formattedDescriptors.join('\\n'),\n source,\n );\n}\n\nexport function createCapabilitySections(\n descriptors: readonly ICapabilityDescriptor[],\n): ISystemPromptSection[] {\n const sections: ISystemPromptSection[] = [];\n const commandSection = createCapabilityKindSection(\n 'builtin-command',\n 'Built-in Commands',\n 70,\n 'command',\n descriptors,\n );\n const skillSection = createCapabilityKindSection('skill', 'Skills', 80, 'skill', descriptors);\n const agentSection = createCapabilityKindSection('agent', 'Agents', 90, 'agent', descriptors);\n const toolSection = createCapabilityKindSection('tool', 'Tools', 100, 'tool', descriptors);\n\n if (commandSection) sections.push(commandSection);\n if (skillSection) sections.push(skillSection);\n if (agentSection) sections.push(agentSection);\n if (toolSection) sections.push(toolSection);\n return sections;\n}\n\nexport function createCapabilitySection(\n descriptors: readonly ICapabilityDescriptor[],\n): ISystemPromptSection {\n return createSection(\n 'capability-descriptors',\n 'Capabilities',\n 70,\n descriptors\n .filter((descriptor) => descriptor.modelInvocable)\n .map(formatCapability)\n .join('\\n'),\n 'command',\n );\n}\n","import { composeSystemPrompt } from './system-prompt-composer.js';\nimport {\n createAgentsMdSection,\n createCapabilitySections,\n createClaudeMdSection,\n createPermissionSection,\n createProjectMemorySection,\n createProjectSection,\n createResponseLanguageSection,\n createTaskContextSection,\n createToolDescriptionSection,\n createWorkingDirectorySection,\n} from './system-prompt-section-providers.js';\n\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { TTrustLevel } from '../types.js';\nimport type { IProjectInfo } from './project-detector.js';\nimport type { ISystemPromptSection } from './system-prompt-types.js';\n\nexport interface ISystemPromptParams {\n /** Concatenated AGENTS.md content (may be empty string) */\n agentsMd: string;\n /** Concatenated CLAUDE.md content (may be empty string) */\n claudeMd: string;\n /** Startup project memory index loaded from .robota/memory/MEMORY.md */\n memoryMd?: string;\n /** Formatted active task context loaded from .agents/tasks/*.md */\n taskContext?: string;\n /** Human-readable tool descriptions, one per entry */\n toolDescriptions: string[];\n /** Active trust level governing permission checks */\n trustLevel: TTrustLevel;\n /** Detected project metadata */\n projectInfo: IProjectInfo;\n /** Current working directory */\n cwd?: string;\n /** Response language code (e.g., \"ko\", \"en\"). If set, AI must respond in this language. */\n language?: string;\n /** Discovered skills to expose in the system prompt */\n skills?: Array<{ name: string; description: string; disableModelInvocation?: boolean }>;\n /** Discovered agents to expose in the system prompt */\n agents?: Array<{ name: string; description: string }>;\n /** Command descriptors to expose to the model */\n commandDescriptors?: ICapabilityDescriptor[];\n}\n\nfunction appendOptionalSection(\n sections: ISystemPromptSection[],\n section: ISystemPromptSection | undefined,\n): void {\n if (section !== undefined) sections.push(section);\n}\n\nfunction mapSkillDescriptors(\n skills: NonNullable<ISystemPromptParams['skills']>,\n): ICapabilityDescriptor[] {\n return skills.map((skill) => ({\n name: skill.name,\n kind: 'skill',\n description: skill.description,\n userInvocable: true,\n modelInvocable: skill.disableModelInvocation !== true,\n }));\n}\n\nfunction mapAgentDescriptors(\n agents: NonNullable<ISystemPromptParams['agents']>,\n): ICapabilityDescriptor[] {\n return agents.map((agent) => ({\n name: agent.name,\n kind: 'agent',\n description: agent.description,\n userInvocable: false,\n modelInvocable: true,\n safety: 'background-agent',\n }));\n}\n\nfunction buildCapabilityDescriptors(params: ISystemPromptParams): ICapabilityDescriptor[] {\n return [\n ...(params.commandDescriptors ?? []),\n ...(params.skills ? mapSkillDescriptors(params.skills) : []),\n ...(params.agents ? mapAgentDescriptors(params.agents) : []),\n ];\n}\n\nexport function buildSystemPrompt(params: ISystemPromptParams): string {\n const sections: ISystemPromptSection[] = [];\n\n appendOptionalSection(sections, createAgentsMdSection(params.agentsMd));\n appendOptionalSection(sections, createClaudeMdSection(params.claudeMd));\n appendOptionalSection(sections, createProjectMemorySection(params.memoryMd));\n appendOptionalSection(sections, createTaskContextSection(params.taskContext));\n appendOptionalSection(sections, createWorkingDirectorySection(params.cwd));\n sections.push(createProjectSection(params.projectInfo));\n appendOptionalSection(sections, createResponseLanguageSection(params.language));\n sections.push(createPermissionSection(params.trustLevel));\n appendOptionalSection(sections, createToolDescriptionSection(params.toolDescriptions));\n sections.push(...createCapabilitySections(buildCapabilityDescriptors(params)));\n\n return composeSystemPrompt(sections);\n}\n","import { createZodFunctionTool } from '@robota-sdk/agent-tools';\nimport { z } from 'zod';\n\nimport type { IBackgroundTaskManager, TBackgroundPrimitive } from '../background-tasks/index.js';\nimport type { IZodSchema } from '@robota-sdk/agent-tools';\n\nconst DEFAULT_PROCESS_TIMEOUT_MS = 120_000;\n\nfunction asZodSchema(schema: z.ZodType): IZodSchema {\n return schema as IZodSchema;\n}\n\nconst BackgroundProcessSchema = z.object({\n command: z.string().describe('The shell command to start in the background'),\n timeout: z.number().optional().describe('Optional timeout in milliseconds. Default is 120000.'),\n workingDirectory: z\n .string()\n .optional()\n .describe('Working directory for the command. Defaults to the current project directory.'),\n stdin: z.string().optional().describe('Optional stdin to write after the process starts.'),\n outputLimitBytes: z\n .number()\n .optional()\n .describe('Maximum captured output bytes kept in the task result.'),\n});\n\ntype TBackgroundProcessArgs = z.infer<typeof BackgroundProcessSchema>;\n\nexport interface IBackgroundProcessToolDeps {\n backgroundTaskManager: IBackgroundTaskManager;\n cwd?: string;\n parentSessionId?: string;\n metadata?: Record<string, TBackgroundPrimitive>;\n}\n\nfunction stringifyStarted(taskId: string, status: string, command: string): string {\n return JSON.stringify({\n success: true,\n background: true,\n output: '',\n taskId,\n status,\n command,\n });\n}\n\nfunction stringifyProcessError(message: string): string {\n return JSON.stringify({\n success: false,\n background: true,\n output: '',\n error: `Background process error: ${message}`,\n });\n}\n\nasync function startBackgroundProcess(\n args: TBackgroundProcessArgs,\n deps: IBackgroundProcessToolDeps,\n): Promise<string> {\n try {\n const state = await deps.backgroundTaskManager.spawn({\n kind: 'process',\n label: args.command,\n mode: 'background',\n parentSessionId: deps.parentSessionId ?? 'unknown-session',\n depth: 0,\n cwd: args.workingDirectory ?? deps.cwd ?? process.cwd(),\n command: args.command,\n stdin: args.stdin,\n timeoutMs: args.timeout ?? DEFAULT_PROCESS_TIMEOUT_MS,\n outputLimitBytes: args.outputLimitBytes,\n metadata: deps.metadata,\n });\n return stringifyStarted(state.id, state.status, args.command);\n } catch (error) {\n return stringifyProcessError(error instanceof Error ? error.message : String(error));\n }\n}\n\nexport function createBackgroundProcessTool(\n deps: IBackgroundProcessToolDeps,\n): ReturnType<typeof createZodFunctionTool> {\n return createZodFunctionTool(\n 'BackgroundProcess',\n 'Start a shell command as a managed background task. Use this for long-running commands that should not block the current conversation. Use /background list, /background read <taskId>, /background cancel <taskId>, or /background close <taskId> to inspect or control it.',\n asZodSchema(BackgroundProcessSchema),\n async (params) => startBackgroundProcess(params as TBackgroundProcessArgs, deps),\n );\n}\n","import { SubagentManager, BackgroundTaskManager } from '@robota-sdk/agent-executor';\n\nimport { fireSubagentLifecycleHook } from './background-task-hooks.js';\nimport { DEFAULT_TOOL_DESCRIPTIONS } from './create-tools.js';\nimport { AgentDefinitionLoader } from '../agents/agent-definition-loader.js';\nimport { createExecutionOriginMetadata } from '../background-tasks/index.js';\nimport { storeSessionBackgroundTaskManager } from '../background-tasks/session-background-store.js';\nimport { buildSystemPrompt } from '../context/system-prompt-builder.js';\nimport { createInProcessSubagentRunner } from '../subagents/in-process-subagent-runner.js';\nimport { storeAgentToolDeps } from '../tools/agent-tool.js';\nimport { createBackgroundProcessTool } from '../tools/background-process-tool.js';\nimport { formatProjectedModelCommandToolPromptDescription } from '../tools/model-command-tool-projection.js';\n\nimport type { ICreateSessionOptions } from './create-session-types.js';\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type { IBackgroundTaskManager, TBackgroundTaskEvent } from '../background-tasks/index.js';\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { ISystemPromptParams } from '../context/system-prompt-builder.js';\nimport type { IAgentToolDeps } from '../tools/agent-tool.js';\nimport type { IBackgroundProcessToolDeps } from '../tools/background-process-tool.js';\nimport type { createModelCommandToolProjection } from '../tools/model-command-tool-projection.js';\nimport type { IAIProvider, IToolWithEventService, IHookTypeExecutor } from '@robota-sdk/agent-core';\nimport type { ISessionLogger } from '@robota-sdk/agent-session';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport interface IAgentRuntimeResult {\n agentToolDeps: IAgentToolDeps | undefined;\n agentDefinitions: IAgentDefinition[];\n backgroundTaskManager: IBackgroundTaskManager;\n}\n\nexport function buildAgentRuntime(\n options: ICreateSessionOptions,\n sessionId: string,\n cwd: string,\n provider: IAIProvider,\n tools: IToolWithEventService[],\n hookTypeExecutors: IHookTypeExecutor[],\n): IAgentRuntimeResult {\n let agentToolDeps: IAgentToolDeps | undefined;\n let agentDefinitions: IAgentDefinition[] = [];\n let backgroundTaskManager: IBackgroundTaskManager;\n\n if (options.enableAgentRuntime) {\n const agentLoader = new AgentDefinitionLoader(cwd);\n agentDefinitions = agentLoader.loadAll();\n agentToolDeps = {\n config: options.config,\n context: options.context,\n tools,\n terminal: options.terminal,\n provider,\n cwd,\n parentSessionId: sessionId,\n permissionMode: options.permissionMode,\n permissionHandler: options.permissionHandler,\n hooks: options.config.hooks,\n hookTypeExecutors: hookTypeExecutors.length > 0 ? hookTypeExecutors : undefined,\n onTextDelta: options.onTextDelta,\n onToolExecution: options.onToolExecution,\n customAgentRegistry: (name: string) => agentLoader.getAgent(name),\n agentDefinitions,\n };\n const subagentManager = new SubagentManager({\n runner: (options.subagentRunnerFactory ?? createInProcessSubagentRunner)(agentToolDeps),\n backgroundTaskRunners: options.backgroundTaskRunners,\n });\n agentToolDeps.subagentManager = subagentManager;\n backgroundTaskManager = subagentManager.getBackgroundTaskManager();\n agentToolDeps.backgroundTaskManager = backgroundTaskManager;\n } else {\n backgroundTaskManager = new BackgroundTaskManager({\n runners: options.backgroundTaskRunners ?? [],\n });\n }\n\n const sessionLogger = options.sessionLogger;\n if (sessionLogger) {\n backgroundTaskManager.subscribe((event) =>\n logBackgroundTaskEvent(sessionLogger, sessionId, event),\n );\n }\n backgroundTaskManager.subscribe((event) =>\n fireSubagentLifecycleHook(\n event,\n cwd,\n options.config.hooks,\n hookTypeExecutors.length > 0 ? hookTypeExecutors : undefined,\n ),\n );\n\n return { agentToolDeps, agentDefinitions, backgroundTaskManager };\n}\n\nexport interface IBackgroundProcessResult {\n backgroundProcessToolDeps: IBackgroundProcessToolDeps | undefined;\n}\n\nexport function buildBackgroundProcessTool(\n options: ICreateSessionOptions,\n backgroundTaskManager: IBackgroundTaskManager,\n sessionId: string,\n cwd: string,\n tools: IToolWithEventService[],\n): IBackgroundProcessResult {\n const hasProcessRunner = options.backgroundTaskRunners?.some((r) => r.kind === 'process');\n if (!hasProcessRunner) return { backgroundProcessToolDeps: undefined };\n const backgroundProcessToolDeps: IBackgroundProcessToolDeps = {\n backgroundTaskManager,\n cwd,\n parentSessionId: sessionId,\n metadata: createExecutionOriginMetadata({\n kind: 'tool_call',\n sessionId,\n label: 'BackgroundProcess',\n }),\n };\n tools.push(createBackgroundProcessTool(backgroundProcessToolDeps));\n return { backgroundProcessToolDeps };\n}\n\nexport interface ISystemPromptResult {\n finalSystemMessage: string;\n rebuildSystemMessage: (agentsMd: string, claudeMd: string) => string;\n}\n\nexport function buildSessionSystemPrompt(\n options: ICreateSessionOptions,\n cwd: string,\n modelInvocableCommandDescriptors: ICapabilityDescriptor[],\n modelCommandToolProjection: ReturnType<typeof createModelCommandToolProjection> | undefined,\n backgroundProcessToolDeps: IBackgroundProcessToolDeps | undefined,\n modelVisibleSkills: Array<{\n name: string;\n description: string;\n disableModelInvocation?: boolean;\n }>,\n agentDefinitions: IAgentDefinition[],\n): ISystemPromptResult {\n const buildPrompt = options.systemPromptBuilder ?? buildSystemPrompt;\n const defaultToolDescriptions = [\n ...DEFAULT_TOOL_DESCRIPTIONS,\n ...(modelCommandToolProjection\n ? modelCommandToolProjection.commandTools.map(\n formatProjectedModelCommandToolPromptDescription,\n )\n : []),\n ];\n const resolvedToolDescriptions =\n options.toolDescriptions ??\n (backgroundProcessToolDeps\n ? [\n ...defaultToolDescriptions,\n 'BackgroundProcess — start long-running shell commands as managed background tasks',\n ]\n : defaultToolDescriptions);\n\n const staticPromptParams: ISystemPromptParams = {\n agentsMd: options.context.agentsMd,\n claudeMd: options.context.claudeMd,\n memoryMd: options.context.memoryMd,\n taskContext: options.context.taskContext,\n toolDescriptions: resolvedToolDescriptions,\n trustLevel: options.config.defaultTrustLevel,\n projectInfo: options.projectInfo ?? { type: 'unknown', language: 'unknown' },\n cwd,\n language: options.config.language,\n skills: modelVisibleSkills.map((skill) => ({\n name: skill.name,\n description: skill.description,\n disableModelInvocation: skill.disableModelInvocation,\n })),\n ...(agentDefinitions.length > 0\n ? {\n agents: agentDefinitions.map((agent) => ({\n name: agent.name,\n description: agent.description,\n })),\n }\n : {}),\n commandDescriptors: options.commandDescriptors ?? [],\n };\n const systemMessage = buildPrompt(staticPromptParams);\n const finalSystemMessage = options.appendSystemPrompt\n ? `${systemMessage}\\n\\n${options.appendSystemPrompt}`\n : systemMessage;\n\n const rebuildSystemMessage = (newAgentsMd: string, newClaudeMd: string): string => {\n const rebuilt = buildPrompt({\n ...staticPromptParams,\n agentsMd: newAgentsMd,\n claudeMd: newClaudeMd,\n });\n return options.appendSystemPrompt ? `${rebuilt}\\n\\n${options.appendSystemPrompt}` : rebuilt;\n };\n\n return { finalSystemMessage, rebuildSystemMessage };\n}\n\nexport function wireSessionDeps(\n session: Session,\n agentToolDeps: IAgentToolDeps | undefined,\n backgroundProcessToolDeps: IBackgroundProcessToolDeps | undefined,\n backgroundTaskManager: IBackgroundTaskManager,\n): void {\n if (agentToolDeps) agentToolDeps.parentSessionId = session.getSessionId();\n if (backgroundProcessToolDeps) backgroundProcessToolDeps.parentSessionId = session.getSessionId();\n storeSessionBackgroundTaskManager(session, backgroundTaskManager);\n if (agentToolDeps) storeAgentToolDeps(session, agentToolDeps);\n}\n\nfunction logBackgroundTaskEvent(\n logger: ISessionLogger,\n sessionId: string,\n event: TBackgroundTaskEvent,\n): void {\n logger.log(sessionId, 'background_task_event', {\n backgroundEventType: event.type,\n backgroundEvent: event,\n });\n}\n","import type { IEditCheckpointRecorder } from './edit-checkpoint-types.js';\nimport type {\n IEventService,\n IParameterValidationResult,\n IToolExecutionContext,\n IToolResult,\n IToolSchema,\n IToolWithEventService,\n TToolParameters,\n} from '@robota-sdk/agent-core';\n\nconst CHECKPOINTED_TOOL_NAMES = new Set(['Write', 'Edit']);\n\nexport function wrapEditCheckpointTools(\n tools: readonly IToolWithEventService[],\n recorder: IEditCheckpointRecorder,\n): IToolWithEventService[] {\n return tools.map((tool) =>\n CHECKPOINTED_TOOL_NAMES.has(tool.getName())\n ? new EditCheckpointToolWrapper(tool, recorder)\n : tool,\n );\n}\n\nclass EditCheckpointToolWrapper implements IToolWithEventService {\n readonly schema: IToolSchema;\n\n constructor(\n private readonly delegate: IToolWithEventService,\n private readonly recorder: IEditCheckpointRecorder,\n ) {\n this.schema = delegate.schema;\n }\n\n setEventService(eventService: IEventService | undefined): void {\n this.delegate.setEventService(eventService);\n }\n\n async execute(parameters: TToolParameters, context: IToolExecutionContext): Promise<IToolResult> {\n const filePath = extractFilePath(parameters);\n if (filePath) {\n await this.recorder.captureFile(filePath);\n }\n return this.delegate.execute(parameters, context);\n }\n\n validate(parameters: TToolParameters): boolean {\n return this.delegate.validate(parameters);\n }\n\n validateParameters(parameters: TToolParameters): IParameterValidationResult {\n return this.delegate.validateParameters(parameters);\n }\n\n getDescription(): string {\n return this.delegate.getDescription();\n }\n\n getName(): string {\n return this.delegate.getName();\n }\n}\n\nfunction extractFilePath(parameters: TToolParameters): string | undefined {\n if (!parameters || typeof parameters !== 'object') return undefined;\n const value = parameters.filePath;\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n","import { homedir } from 'node:os';\nimport { join, basename } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { ICommandSource, ICommand } from '../command-api/types.js';\nimport type { IFileSystem, IDirent } from '@robota-sdk/agent-core';\n\ninterface IFrontmatter {\n name?: string;\n description?: string;\n argumentHint?: string;\n disableModelInvocation?: boolean;\n userInvocable?: boolean;\n allowedTools?: string[];\n model?: string;\n effort?: string;\n context?: string;\n agent?: string;\n}\n\n/** Known boolean frontmatter keys */\nconst BOOLEAN_KEYS = new Set(['disable-model-invocation', 'user-invocable']);\n\n/** Known comma-separated or whitespace-separated list frontmatter keys */\nconst LIST_KEYS = new Set(['allowed-tools']);\n\n/** Convert kebab-case to camelCase */\nfunction kebabToCamel(key: string): string {\n return key.replace(/-([a-z])/g, (_match, letter: string) => letter.toUpperCase());\n}\n\nfunction parseListValue(rawValue: string): string[] {\n const separator = rawValue.includes(',') ? /\\s*,\\s*/ : /\\s+/;\n return rawValue\n .split(separator)\n .map((value) => value.trim())\n .filter((value) => value.length > 0);\n}\n\n/** Parse YAML-like frontmatter between --- markers */\nexport function parseFrontmatter(content: string): IFrontmatter | null {\n const lines = content.split('\\n');\n if (lines[0]?.trim() !== '---') return null;\n\n const result: Record<string, unknown> = {};\n\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i]!;\n if (line.trim() === '---') break;\n\n const match = line.match(/^([a-z][a-z0-9-]*):\\s*(.+)/);\n if (!match) continue;\n\n const key = match[1]!;\n const rawValue = match[2]!.trim();\n const camelKey = kebabToCamel(key);\n\n if (BOOLEAN_KEYS.has(key)) {\n result[camelKey] = rawValue === 'true';\n } else if (LIST_KEYS.has(key)) {\n result[camelKey] = parseListValue(rawValue);\n } else {\n result[camelKey] = rawValue;\n }\n }\n\n return Object.keys(result).length > 0 ? (result as IFrontmatter) : null;\n}\n\n/** Build a command from frontmatter, content, and a fallback name */\nfunction buildCommand(\n frontmatter: IFrontmatter | null,\n content: string,\n fallbackName: string,\n): ICommand {\n const cmd: ICommand = {\n name: frontmatter?.name ?? fallbackName,\n description: frontmatter?.description ?? `Skill: ${fallbackName}`,\n source: 'skill',\n skillContent: content,\n };\n\n if (frontmatter?.argumentHint !== undefined) cmd.argumentHint = frontmatter.argumentHint;\n if (frontmatter?.disableModelInvocation !== undefined)\n cmd.disableModelInvocation = frontmatter.disableModelInvocation;\n if (frontmatter?.userInvocable !== undefined) cmd.userInvocable = frontmatter.userInvocable;\n if (frontmatter?.allowedTools !== undefined) cmd.allowedTools = frontmatter.allowedTools;\n if (frontmatter?.model !== undefined) cmd.model = frontmatter.model;\n if (frontmatter?.effort !== undefined) cmd.effort = frontmatter.effort;\n if (frontmatter?.context !== undefined) cmd.context = frontmatter.context;\n if (frontmatter?.agent !== undefined) cmd.agent = frontmatter.agent;\n\n return cmd;\n}\n\n/** Scan a skills directory for subdirectories containing SKILL.md */\nfunction scanSkillsDir(skillsDir: string, fs: IFileSystem): ICommand[] {\n if (!fs.existsSync(skillsDir)) return [];\n\n const commands: ICommand[] = [];\n const entries: IDirent[] = fs.readdirSync(skillsDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const skillFile = join(skillsDir, entry.name, 'SKILL.md');\n if (!fs.existsSync(skillFile)) continue;\n\n const content = fs.readFileSync(skillFile, 'utf-8');\n const frontmatter = parseFrontmatter(content);\n commands.push(buildCommand(frontmatter, content, entry.name));\n }\n\n return commands;\n}\n\n/** Scan a commands directory for .md files (Claude Code legacy format) */\nfunction scanCommandsDir(commandsDir: string, fs: IFileSystem): ICommand[] {\n if (!fs.existsSync(commandsDir)) return [];\n\n const commands: ICommand[] = [];\n const entries: IDirent[] = fs.readdirSync(commandsDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md')) continue;\n const filePath = join(commandsDir, entry.name);\n const content = fs.readFileSync(filePath, 'utf-8');\n const frontmatter = parseFrontmatter(content);\n const fallbackName = basename(entry.name, '.md');\n commands.push(buildCommand(frontmatter, content, fallbackName));\n }\n\n return commands;\n}\n\n/** Command source that discovers skills from multiple directories */\nexport class SkillCommandSource implements ICommandSource {\n readonly name = 'skill';\n private readonly cwd: string;\n private readonly home: string;\n private readonly fs: IFileSystem;\n private cachedCommands: ICommand[] | null = null;\n\n constructor(cwd: string, home?: string, fs: IFileSystem = new NodeFileSystem()) {\n this.cwd = cwd;\n this.home = home ?? homedir();\n this.fs = fs;\n }\n\n getCommands(): ICommand[] {\n if (this.cachedCommands) return this.cachedCommands;\n\n const sources: ICommand[][] = [\n scanSkillsDir(join(this.cwd, '.claude', 'skills'), this.fs),\n scanCommandsDir(join(this.cwd, '.claude', 'commands'), this.fs),\n scanSkillsDir(join(this.home, '.robota', 'skills'), this.fs),\n scanSkillsDir(join(this.cwd, '.agents', 'skills'), this.fs),\n ];\n\n const seen = new Set<string>();\n const merged: ICommand[] = [];\n\n for (const commands of sources) {\n for (const cmd of commands) {\n if (!seen.has(cmd.name)) {\n seen.add(cmd.name);\n merged.push(cmd);\n }\n }\n }\n\n this.cachedCommands = merged;\n return this.cachedCommands;\n }\n\n getModelInvocableSkills(): ICommand[] {\n return this.getCommands().filter((cmd) => cmd.disableModelInvocation !== true);\n }\n\n getUserInvocableSkills(): ICommand[] {\n return this.getCommands().filter((cmd) => cmd.userInvocable !== false);\n }\n}\n","/**\n * Agent hook executor — delegates to a sub-agent session.\n *\n * Creates a subagent session with maxTurns and timeout limits,\n * runs hook input as the initial prompt, and parses the result.\n *\n * Exit codes:\n * - 0: ok: true (allow/proceed)\n * - 2: ok: false (block/deny), reason in stderr\n * - 1: execution error (session failure, parse error)\n */\n\nimport type {\n IAgentHookDefinition,\n IHookInput,\n IHookResult,\n IHookTypeExecutor,\n THookDefinition,\n} from '@robota-sdk/agent-core';\n\n/** Default maximum turns for the sub-agent session. */\nconst DEFAULT_MAX_TURNS = 50;\n\n/** Default timeout in seconds. */\nconst DEFAULT_TIMEOUT_SECONDS = 60;\n\n/** A minimal session interface for running a prompt. */\nexport interface IAgentSession {\n run(prompt: string): Promise<string>;\n}\n\n/** Factory that creates a session instance with the given options. */\nexport type TSessionFactory = (options: { maxTurns?: number; timeout?: number }) => IAgentSession;\n\n/** Constructor options for AgentExecutor. */\nexport interface IAgentExecutorOptions {\n sessionFactory: TSessionFactory;\n}\n\n/** Extract JSON from a string, handling markdown code blocks. */\nfunction extractJson(raw: string): string {\n const codeBlockMatch = /```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?\\s*```/.exec(raw);\n if (codeBlockMatch) {\n return codeBlockMatch[1].trim();\n }\n return raw.trim();\n}\n\nexport class AgentExecutor implements IHookTypeExecutor {\n readonly type = 'agent' as const;\n\n private readonly sessionFactory: TSessionFactory;\n\n constructor(options: IAgentExecutorOptions) {\n this.sessionFactory = options.sessionFactory;\n }\n\n async execute(definition: THookDefinition, input: IHookInput): Promise<IHookResult> {\n const agentDef = definition as IAgentHookDefinition;\n const maxTurns = agentDef.maxTurns ?? DEFAULT_MAX_TURNS;\n const timeout = agentDef.timeout ?? DEFAULT_TIMEOUT_SECONDS;\n\n try {\n const session = this.sessionFactory({ maxTurns, timeout });\n const prompt = `Hook input:\\n${JSON.stringify(input)}\\n\\nRespond with JSON: { \"ok\": boolean, \"reason\"?: string }`;\n const rawResponse = await session.run(prompt);\n const jsonStr = extractJson(rawResponse);\n\n let parsed: { ok: boolean; reason?: string };\n try {\n parsed = JSON.parse(jsonStr) as { ok: boolean; reason?: string };\n } catch {\n return {\n exitCode: 1,\n stdout: '',\n stderr: `Failed to parse agent response as JSON: ${rawResponse}`,\n };\n }\n\n if (parsed.ok) {\n return { exitCode: 0, stdout: JSON.stringify(parsed), stderr: '' };\n }\n\n return {\n exitCode: 2,\n stdout: '',\n stderr: parsed.reason ?? 'Blocked by agent hook',\n };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { exitCode: 1, stdout: '', stderr: message };\n }\n }\n}\n","/**\n * Prompt hook executor — evaluates a prompt via an AI model.\n *\n * Makes a single-turn LLM call with hook input context as the prompt.\n * Parses { ok: boolean, reason?: string } from the AI response.\n *\n * Exit codes:\n * - 0: ok: true (allow/proceed)\n * - 2: ok: false (block/deny), reason in stderr\n * - 1: execution error (provider failure, parse error)\n */\n\nimport type {\n IPromptHookDefinition,\n IHookInput,\n IHookResult,\n IHookTypeExecutor,\n THookDefinition,\n} from '@robota-sdk/agent-core';\n\n/** A minimal provider interface for single-turn completion. */\nexport interface IPromptProvider {\n complete(prompt: string): Promise<string>;\n}\n\n/** Factory that creates a provider instance, optionally for a specific model. */\nexport type TProviderFactory = (model?: string) => IPromptProvider;\n\n/** Constructor options for PromptExecutor. */\nexport interface IPromptExecutorOptions {\n providerFactory: TProviderFactory;\n defaultModel?: string;\n}\n\n/** Extract JSON from a string, handling markdown code blocks. */\nfunction extractJson(raw: string): string {\n const codeBlockMatch = /```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?\\s*```/.exec(raw);\n if (codeBlockMatch) {\n return codeBlockMatch[1].trim();\n }\n return raw.trim();\n}\n\nexport class PromptExecutor implements IHookTypeExecutor {\n readonly type = 'prompt' as const;\n\n private readonly providerFactory: TProviderFactory;\n private readonly defaultModel: string | undefined;\n\n constructor(options: IPromptExecutorOptions) {\n this.providerFactory = options.providerFactory;\n this.defaultModel = options.defaultModel;\n }\n\n async execute(definition: THookDefinition, input: IHookInput): Promise<IHookResult> {\n const promptDef = definition as IPromptHookDefinition;\n const model = promptDef.model ?? this.defaultModel;\n\n try {\n const provider = this.providerFactory(model);\n const prompt = `${promptDef.prompt}\\n\\nContext:\\n${JSON.stringify(input)}\\n\\nRespond with JSON: { \"ok\": boolean, \"reason\"?: string }`;\n const rawResponse = await provider.complete(prompt);\n const jsonStr = extractJson(rawResponse);\n\n let parsed: { ok: boolean; reason?: string };\n try {\n parsed = JSON.parse(jsonStr) as { ok: boolean; reason?: string };\n } catch {\n return {\n exitCode: 1,\n stdout: '',\n stderr: `Failed to parse AI response as JSON: ${rawResponse}`,\n };\n }\n\n if (parsed.ok) {\n return { exitCode: 0, stdout: JSON.stringify(parsed), stderr: '' };\n }\n\n return {\n exitCode: 2,\n stdout: '',\n stderr: parsed.reason ?? 'Blocked by prompt hook',\n };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { exitCode: 1, stdout: '', stderr: message };\n }\n }\n}\n","import type {\n IEventService,\n IParameterValidationResult,\n IToolExecutionContext,\n IToolResult,\n IToolSchema,\n IToolWithEventService,\n TToolArgs,\n TToolParameters,\n} from '@robota-sdk/agent-core';\n\nconst FILE_MUTATION_TOOLS = new Set(['Write', 'Edit']);\nconst HOST_SHELL_TOOLS = new Set(['Bash', 'BackgroundProcess']);\nconst READ_ONLY_TOOLS = new Set(['Read', 'Glob', 'Grep', 'WebFetch', 'WebSearch']);\n\nexport type TReversibleExecutionIsolation = 'none' | 'worktree' | 'provider-sandbox';\nexport type TReversibleRollbackLayer = 'none' | 'edit-checkpoint' | 'worktree' | 'provider-sandbox';\nexport type TReversibleSideEffect =\n | 'none'\n | 'file-mutation'\n | 'shell-process'\n | 'subagent'\n | 'unknown';\nexport type TReversibleSafetyStatus =\n | 'reversible'\n | 'read-only'\n | 'requires-checkpoint'\n | 'requires-isolation'\n | 'unknown';\n\nexport interface IReversibleExecutionOptions {\n mode: 'local-first';\n isolation?: TReversibleExecutionIsolation;\n enforceUntrackedSideEffects?: boolean;\n}\n\nexport interface IReversibleToolSafetyContext {\n checkpointAvailable: boolean;\n isolation: TReversibleExecutionIsolation;\n}\n\nexport interface IReversibleToolSafetyInput {\n toolName: string;\n toolArgs?: TToolArgs;\n context: IReversibleToolSafetyContext;\n}\n\nexport interface IReversibleToolSafetyReport {\n toolName: string;\n reversible: boolean;\n sideEffect: TReversibleSideEffect;\n rollbackLayer: TReversibleRollbackLayer;\n status: TReversibleSafetyStatus;\n message: string;\n}\n\ninterface IReversibleExecutionToolWrapperOptions {\n safetyContext: IReversibleToolSafetyContext;\n enforceUntrackedSideEffects: boolean;\n}\n\ntype TReversibleToolArgValue = string | number | boolean | object | undefined;\ntype TReversibleToolArgRecord = Record<string, TReversibleToolArgValue>;\n\nexport function evaluateReversibleToolSafety(\n input: IReversibleToolSafetyInput,\n): IReversibleToolSafetyReport {\n const toolName = input.toolName;\n if (READ_ONLY_TOOLS.has(toolName)) {\n return {\n toolName,\n reversible: true,\n sideEffect: 'none',\n rollbackLayer: 'none',\n status: 'read-only',\n message: `${toolName} does not mutate the local workspace.`,\n };\n }\n\n if (FILE_MUTATION_TOOLS.has(toolName)) {\n if (input.context.isolation === 'worktree' || input.context.isolation === 'provider-sandbox') {\n return evaluateIsolatedSideEffect(toolName, 'file-mutation', input.context);\n }\n if (input.context.checkpointAvailable) {\n return {\n toolName,\n reversible: true,\n sideEffect: 'file-mutation',\n rollbackLayer: 'edit-checkpoint',\n status: 'reversible',\n message: `${toolName} is reversible through the active edit checkpoint.`,\n };\n }\n return {\n toolName,\n reversible: false,\n sideEffect: 'file-mutation',\n rollbackLayer: 'none',\n status: 'requires-checkpoint',\n message: `${toolName} requires an edit checkpoint before file mutation.`,\n };\n }\n\n if (HOST_SHELL_TOOLS.has(toolName)) {\n return evaluateIsolatedSideEffect(toolName, 'shell-process', input.context);\n }\n\n if (toolName === 'Agent') {\n return evaluateAgentSafety(input.toolArgs, input.context);\n }\n\n return {\n toolName,\n reversible: false,\n sideEffect: 'unknown',\n rollbackLayer: 'none',\n status: 'unknown',\n message: `${toolName} has no reversible execution contract.`,\n };\n}\n\nexport function wrapReversibleExecutionTools(\n tools: readonly IToolWithEventService[],\n options: IReversibleExecutionOptions & { checkpointAvailable: boolean },\n): IToolWithEventService[] {\n const safetyContext: IReversibleToolSafetyContext = {\n checkpointAvailable: options.checkpointAvailable,\n isolation: options.isolation ?? 'none',\n };\n const enforceUntrackedSideEffects = options.enforceUntrackedSideEffects ?? true;\n return tools.map(\n (tool) =>\n new ReversibleExecutionToolWrapper(tool, {\n safetyContext,\n enforceUntrackedSideEffects,\n }),\n );\n}\n\nclass ReversibleExecutionToolWrapper implements IToolWithEventService {\n readonly schema: IToolSchema;\n\n constructor(\n private readonly delegate: IToolWithEventService,\n private readonly options: IReversibleExecutionToolWrapperOptions,\n ) {\n this.schema = delegate.schema;\n }\n\n setEventService(eventService: IEventService | undefined): void {\n this.delegate.setEventService(eventService);\n }\n\n async execute(parameters: TToolParameters, context: IToolExecutionContext): Promise<IToolResult> {\n const report = evaluateReversibleToolSafety({\n toolName: this.getName(),\n toolArgs: toToolArgs(parameters),\n context: this.options.safetyContext,\n });\n if (!report.reversible && this.options.enforceUntrackedSideEffects) {\n return createBlockedResult(report);\n }\n return this.delegate.execute(parameters, context);\n }\n\n validate(parameters: TToolParameters): boolean {\n return this.delegate.validate(parameters);\n }\n\n validateParameters(parameters: TToolParameters): IParameterValidationResult {\n return this.delegate.validateParameters(parameters);\n }\n\n getDescription(): string {\n return this.delegate.getDescription();\n }\n\n getName(): string {\n return this.delegate.getName();\n }\n}\n\nfunction evaluateIsolatedSideEffect(\n toolName: string,\n sideEffect: TReversibleSideEffect,\n context: IReversibleToolSafetyContext,\n): IReversibleToolSafetyReport {\n if (context.isolation === 'worktree') {\n return {\n toolName,\n reversible: true,\n sideEffect,\n rollbackLayer: 'worktree',\n status: 'reversible',\n message: `${toolName} side effects are contained in an isolated Git worktree.`,\n };\n }\n if (context.isolation === 'provider-sandbox') {\n return {\n toolName,\n reversible: true,\n sideEffect,\n rollbackLayer: 'provider-sandbox',\n status: 'reversible',\n message: `${toolName} side effects are contained in a provider sandbox snapshot.`,\n };\n }\n return {\n toolName,\n reversible: false,\n sideEffect,\n rollbackLayer: 'none',\n status: 'requires-isolation',\n message: `${toolName} can create host shell side effects that edit checkpoints cannot restore; use worktree or provider sandbox isolation.`,\n };\n}\n\nfunction evaluateAgentSafety(\n toolArgs: TToolArgs | undefined,\n context: IReversibleToolSafetyContext,\n): IReversibleToolSafetyReport {\n if (context.isolation === 'worktree' || context.isolation === 'provider-sandbox') {\n return evaluateIsolatedSideEffect('Agent', 'subagent', context);\n }\n\n if (agentRequestUsesWorktree(toolArgs)) {\n return {\n toolName: 'Agent',\n reversible: true,\n sideEffect: 'subagent',\n rollbackLayer: 'worktree',\n status: 'reversible',\n message:\n 'Agent jobs request worktree isolation, so shell side effects stay outside the parent workspace.',\n };\n }\n\n return {\n toolName: 'Agent',\n reversible: false,\n sideEffect: 'subagent',\n rollbackLayer: 'none',\n status: 'requires-isolation',\n message: 'Agent jobs must request worktree isolation to be reversible in local-first mode.',\n };\n}\n\nfunction agentRequestUsesWorktree(toolArgs: TToolArgs | undefined): boolean {\n if (!toolArgs) return false;\n const jobs = toolArgs.jobs;\n if (Array.isArray(jobs)) {\n return (\n jobs.length > 0 &&\n jobs.every((job: TReversibleToolArgValue) => {\n if (!isToolArgRecord(job)) return false;\n return readIsolation(job) === 'worktree';\n })\n );\n }\n return readIsolation(toolArgs) === 'worktree';\n}\n\nfunction readIsolation(value: TReversibleToolArgRecord): string | undefined {\n const isolation = value['isolation'];\n return typeof isolation === 'string' ? isolation : undefined;\n}\n\nfunction isToolArgRecord(value: TReversibleToolArgValue): value is TReversibleToolArgRecord {\n return value !== undefined && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction toToolArgs(parameters: TToolParameters): TToolArgs | undefined {\n if (!parameters || typeof parameters !== 'object' || Array.isArray(parameters)) return undefined;\n return parameters as TToolArgs;\n}\n\nfunction createBlockedResult(report: IReversibleToolSafetyReport): IToolResult {\n return {\n success: true,\n data: {\n success: false,\n output: '',\n error: report.message,\n reversibleSafety: {\n toolName: report.toolName,\n sideEffect: report.sideEffect,\n rollbackLayer: report.rollbackLayer,\n status: report.status,\n },\n },\n metadata: {\n reversibleSafetyStatus: report.status,\n rollbackLayer: report.rollbackLayer,\n },\n };\n}\n","/**\n * Session factory — assembles a fully-configured Session from config, context,\n * tools, and provider.\n */\n\nimport { Session } from '@robota-sdk/agent-session';\n\nimport {\n buildAgentRuntime,\n buildBackgroundProcessTool,\n buildSessionSystemPrompt,\n wireSessionDeps,\n} from './create-session-runtime.js';\nimport { createDefaultTools, DEFAULT_TOOL_DESCRIPTIONS } from './create-tools.js';\nimport { wrapEditCheckpointTools } from '../checkpoints/edit-checkpoint-tools.js';\nimport { SkillCommandSource } from '../commands/skill-source.js';\nimport { AgentExecutor } from '../hooks/agent-executor.js';\nimport { PromptExecutor } from '../hooks/prompt-executor.js';\nimport { wrapReversibleExecutionTools } from '../reversible-execution/index.js';\nimport {\n createModelCommandToolProjection,\n createProjectedCommandExecutionTools,\n} from '../tools/model-command-tool-projection.js';\n\nimport type {\n ICreateSessionOptions,\n ICreateSessionResult,\n TSessionConstructorWithAutoCompact,\n} from './create-session-types.js';\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { TSessionFactory } from '../hooks/agent-executor.js';\nimport type { TProviderFactory } from '../hooks/prompt-executor.js';\nimport type { IToolWithEventService, IHookTypeExecutor } from '@robota-sdk/agent-core';\n\nexport type { ICreateSessionOptions, ICreateSessionResult } from './create-session-types.js';\n\nconst ID_RADIX = 36;\nconst ID_RANDOM_LENGTH = 9;\nconst DEFAULT_PROVIDER_IDLE_TIMEOUT_MS = 120_000;\n\nfunction getModelInvocableCommandDescriptors(\n descriptors: readonly ICapabilityDescriptor[] | undefined,\n): ICapabilityDescriptor[] {\n return (descriptors ?? []).filter(\n (descriptor) => descriptor.modelInvocable && descriptor.kind === 'builtin-command',\n );\n}\n\nfunction normalizeCommandDescriptorName(name: string): string {\n return name.trim().replace(/^\\/+/, '').split(/\\s+/)[0] ?? '';\n}\n\nfunction hasModelInvocableCommandDescriptor(\n descriptors: readonly ICapabilityDescriptor[],\n name: string,\n): boolean {\n return descriptors.some((descriptor) => normalizeCommandDescriptorName(descriptor.name) === name);\n}\n\n/**\n * Create a fully-configured Session instance.\n *\n * Assembles provider, tools, and system prompt, then passes them\n * to Session as pre-constructed dependencies.\n */\nexport function createSession(options: ICreateSessionOptions): ICreateSessionResult {\n if (!options.provider) {\n throw new Error(\n 'provider is required. SDK is provider-neutral — consumer must create and pass a provider instance.',\n );\n }\n const provider = options.provider;\n const cwd = options.cwd ?? process.cwd();\n const sessionId = options.sessionId ?? createSessionId();\n const skillCommandSource = new SkillCommandSource(cwd);\n const modelInvocableCommandDescriptors = getModelInvocableCommandDescriptors(\n options.commandDescriptors,\n );\n const modelCommandToolsEnabled =\n modelInvocableCommandDescriptors.length > 0 &&\n options.modelCommandExecutor !== undefined &&\n options.isModelCommandInvocable !== undefined;\n const modelCommandToolProjection = modelCommandToolsEnabled\n ? createModelCommandToolProjection(modelInvocableCommandDescriptors)\n : undefined;\n const modelVisibleSkills = hasModelInvocableCommandDescriptor(\n modelInvocableCommandDescriptors,\n 'skills',\n )\n ? skillCommandSource.getModelInvocableSkills()\n : [];\n\n const baseDefaultTools = createDefaultTools({ sandboxClient: options.sandboxClient });\n const shouldWrapHostEditCheckpoints =\n options.editCheckpointRecorder !== undefined && options.sandboxClient === undefined;\n const defaultTools =\n shouldWrapHostEditCheckpoints && options.editCheckpointRecorder\n ? wrapEditCheckpointTools(baseDefaultTools, options.editCheckpointRecorder)\n : baseDefaultTools;\n const assembledTools = [...defaultTools, ...(options.additionalTools ?? [])];\n const reversibleExecution = options.reversibleExecution\n ? {\n ...options.reversibleExecution,\n isolation:\n options.reversibleExecution.isolation ??\n (options.sandboxClient ? ('provider-sandbox' as const) : undefined),\n }\n : undefined;\n const tools: IToolWithEventService[] = reversibleExecution\n ? wrapReversibleExecutionTools(assembledTools, {\n ...reversibleExecution,\n checkpointAvailable: shouldWrapHostEditCheckpoints,\n })\n : assembledTools;\n if (\n modelCommandToolsEnabled &&\n options.modelCommandExecutor !== undefined &&\n options.isModelCommandInvocable !== undefined\n ) {\n tools.push(\n ...createProjectedCommandExecutionTools({\n execute: options.modelCommandExecutor,\n isModelInvocable: options.isModelCommandInvocable,\n commandDescriptors: modelInvocableCommandDescriptors,\n }),\n );\n }\n\n const hookTypeExecutors: IHookTypeExecutor[] = [];\n if (options.providerFactory) {\n hookTypeExecutors.push(\n new PromptExecutor({\n providerFactory: options.providerFactory,\n defaultModel: options.config.provider.model,\n }),\n );\n }\n if (options.sessionFactory) {\n hookTypeExecutors.push(new AgentExecutor({ sessionFactory: options.sessionFactory }));\n }\n if (options.additionalHookExecutors) {\n hookTypeExecutors.push(...options.additionalHookExecutors);\n }\n\n const { agentToolDeps, agentDefinitions, backgroundTaskManager } = buildAgentRuntime(\n options,\n sessionId,\n cwd,\n provider,\n tools,\n hookTypeExecutors,\n );\n\n const { backgroundProcessToolDeps } = buildBackgroundProcessTool(\n options,\n backgroundTaskManager,\n sessionId,\n cwd,\n tools,\n );\n\n const { finalSystemMessage, rebuildSystemMessage } = buildSessionSystemPrompt(\n options,\n cwd,\n modelInvocableCommandDescriptors,\n modelCommandToolProjection,\n backgroundProcessToolDeps,\n modelVisibleSkills,\n agentDefinitions,\n );\n\n const defaultAllow = [\n 'Read(.agents/**)',\n 'Read(.claude/**)',\n 'Read(.robota/**)',\n 'Glob(.agents/**)',\n 'Glob(.claude/**)',\n 'Glob(.robota/**)',\n ];\n const allowedToolPatterns = (options.allowedTools ?? []).map((name) => `${name}(*)`);\n const mergedPermissions = {\n allow: [...defaultAllow, ...(options.config.permissions.allow ?? []), ...allowedToolPatterns],\n deny: options.config.permissions.deny ?? [],\n };\n\n const SessionWithAutoCompact = Session as TSessionConstructorWithAutoCompact;\n const session = new SessionWithAutoCompact({\n tools,\n provider,\n systemMessage: finalSystemMessage,\n terminal: options.terminal,\n permissions: mergedPermissions,\n hooks: options.config.hooks,\n permissionMode: options.permissionMode,\n defaultTrustLevel: options.config.defaultTrustLevel,\n model: options.config.provider.model,\n providerTimeout: options.config.provider.timeout ?? DEFAULT_PROVIDER_IDLE_TIMEOUT_MS,\n maxTurns: options.maxTurns,\n sessionStore: options.sessionStore,\n sessionId,\n permissionHandler: options.permissionHandler,\n onTextDelta: options.onTextDelta,\n onContextUpdate: options.onContextUpdate,\n onToolExecution: options.onToolExecution,\n promptForApproval: options.promptForApproval,\n onCompact: options.onCompact,\n onCompactEvent: options.onCompactEvent,\n compactInstructions: options.compactInstructions ?? options.context.compactInstructions,\n autoCompactThreshold: options.autoCompactThreshold ?? options.config.autoCompactThreshold,\n sessionLogger: options.sessionLogger,\n hookTypeExecutors: hookTypeExecutors.length > 0 ? hookTypeExecutors : undefined,\n agentName: options.agentName,\n });\n\n wireSessionDeps(session, agentToolDeps, backgroundProcessToolDeps, backgroundTaskManager);\n\n return { session, rebuildSystemMessage };\n}\n\nfunction createSessionId(): string {\n return `session_${Date.now()}_${Math.random().toString(ID_RADIX).substr(2, ID_RANDOM_LENGTH)}`;\n}\n","/**\n * Subagent transcript logger — creates a FileSessionLogger that writes\n * subagent session logs into a subdirectory of the parent session's log folder.\n *\n * Log structure:\n * {baseLogsDir}/{parentSessionId}/subagents/{agentId}.jsonl\n */\n\nimport { join } from 'node:path';\n\nimport { FileSessionLogger } from '@robota-sdk/agent-session';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/**\n * Create a FileSessionLogger for a subagent session.\n *\n * The logger writes JSONL files into a `subagents/` subdirectory under the\n * parent session's log folder. The directory is created if it does not exist.\n *\n * @param parentSessionId - ID of the parent session (used as directory name)\n * @param agentId - Unique identifier for this subagent run\n * @param baseLogsDir - Root logs directory (e.g., `.robota/logs`)\n * @returns A FileSessionLogger writing to the subagent directory\n */\nexport function createSubagentLogger(\n parentSessionId: string,\n _agentId: string,\n baseLogsDir: string,\n fs: IFileSystem = new NodeFileSystem(),\n): FileSessionLogger {\n const subagentDir = join(baseLogsDir, parentSessionId, 'subagents');\n fs.mkdirSync(subagentDir, { recursive: true });\n return new FileSessionLogger(subagentDir);\n}\n\n/**\n * Resolve the subagent log directory path without creating it.\n *\n * Useful when the caller needs the path for display or configuration\n * but does not want to create the directory immediately.\n *\n * @param parentSessionId - ID of the parent session\n * @param baseLogsDir - Root logs directory\n * @returns The resolved subagent log directory path\n */\nexport function resolveSubagentLogDir(parentSessionId: string, baseLogsDir: string): string {\n return join(baseLogsDir, parentSessionId, 'subagents');\n}\n","/**\n * Zod schemas and TypeScript types for Robota CLI settings\n */\nimport { z } from 'zod';\n\nimport type { THooksConfig } from '@robota-sdk/agent-core';\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\n\nconst UniversalValueSchema: z.ZodType<TUniversalValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.undefined(),\n z.date(),\n z.array(UniversalValueSchema),\n z.record(UniversalValueSchema),\n ]),\n);\n\nconst ProviderSchema = z.object({\n name: z.string().optional(),\n model: z.string().optional(),\n apiKey: z.string().optional(),\n baseURL: z.string().optional(),\n timeout: z.number().optional(),\n options: z.record(UniversalValueSchema).optional(),\n});\n\nconst ProviderProfileSchema = z.object({\n type: z.string().optional(),\n model: z.string().optional(),\n apiKey: z.string().optional(),\n baseURL: z.string().optional(),\n timeout: z.number().optional(),\n options: z.record(UniversalValueSchema).optional(),\n});\n\nconst PermissionsSchema = z.object({\n /** Patterns that are always approved without prompting */\n allow: z.array(z.string()).optional(),\n /** Patterns that are always denied */\n deny: z.array(z.string()).optional(),\n});\n\nconst EnvSchema = z.record(z.string()).optional();\n\n/** Command hook definition */\nconst CommandHookDefinitionSchema = z.object({\n type: z.literal('command'),\n command: z.string(),\n timeout: z.number().optional(),\n});\n\n/** HTTP hook definition */\nconst HttpHookDefinitionSchema = z.object({\n type: z.literal('http'),\n url: z.string(),\n headers: z.record(z.string()).optional(),\n timeout: z.number().optional(),\n});\n\n/** Prompt hook definition */\nconst PromptHookDefinitionSchema = z.object({\n type: z.literal('prompt'),\n prompt: z.string(),\n model: z.string().optional(),\n});\n\n/** Agent hook definition */\nconst AgentHookDefinitionSchema = z.object({\n type: z.literal('agent'),\n agent: z.string(),\n maxTurns: z.number().optional(),\n timeout: z.number().optional(),\n});\n\n/** Discriminated union of all hook definition types */\nconst HookDefinitionSchema = z.discriminatedUnion('type', [\n CommandHookDefinitionSchema,\n HttpHookDefinitionSchema,\n PromptHookDefinitionSchema,\n AgentHookDefinitionSchema,\n]);\n\nconst HookGroupSchema = z.object({\n matcher: z.string(),\n hooks: z.array(HookDefinitionSchema),\n});\n\n/** Supported hook events */\nconst HooksSchema = z\n .object({\n PreToolUse: z.array(HookGroupSchema).optional(),\n PostToolUse: z.array(HookGroupSchema).optional(),\n SessionStart: z.array(HookGroupSchema).optional(),\n SessionEnd: z.array(HookGroupSchema).optional(),\n Stop: z.array(HookGroupSchema).optional(),\n StopFailure: z.array(HookGroupSchema).optional(),\n PreCompact: z.array(HookGroupSchema).optional(),\n PostCompact: z.array(HookGroupSchema).optional(),\n UserPromptSubmit: z.array(HookGroupSchema).optional(),\n SubagentStart: z.array(HookGroupSchema).optional(),\n SubagentStop: z.array(HookGroupSchema).optional(),\n WorktreeCreate: z.array(HookGroupSchema).optional(),\n WorktreeRemove: z.array(HookGroupSchema).optional(),\n })\n .optional();\n\n/** Plugin enablement map: plugin name -> enabled flag */\nconst EnabledPluginsSchema = z.record(z.boolean()).optional();\n\n/** Extra marketplace sources: name -> { source: TMarketplaceSource } */\nconst MarketplaceSourceSchema = z.object({\n source: z.object({\n type: z.enum(['github', 'git', 'local', 'url']),\n repo: z.string().optional(),\n url: z.string().optional(),\n path: z.string().optional(),\n ref: z.string().optional(),\n }),\n});\nconst ExtraKnownMarketplacesSchema = z.record(MarketplaceSourceSchema).optional().catch(undefined);\nconst AutoCompactThresholdSchema = z.union([z.number().gt(0).lte(1), z.literal(false)]).optional();\n\nconst TransportSettingsSchema = z.object({\n enabled: z.boolean().optional(),\n options: z.record(UniversalValueSchema).optional(),\n});\n\nexport const SettingsSchema = z.object({\n /** Trust level used when no --permission-mode flag is given */\n defaultTrustLevel: z.enum(['safe', 'moderate', 'full']).optional(),\n /** Response language (e.g., \"ko\", \"en\", \"ja\"). Injected into system prompt. */\n language: z.string().optional(),\n /** Active provider profile key from providers. */\n currentProvider: z.string().optional(),\n /** Provider profiles keyed by user-facing profile name. */\n providers: z.record(ProviderProfileSchema).optional(),\n /** Legacy single-provider settings. Prefer currentProvider + providers for new config. */\n provider: ProviderSchema.optional(),\n permissions: PermissionsSchema.optional(),\n env: EnvSchema,\n hooks: HooksSchema,\n /** Plugin enablement map: plugin name -> enabled/disabled */\n enabledPlugins: EnabledPluginsSchema,\n /** Extra marketplace URLs for BundlePlugin discovery */\n extraKnownMarketplaces: ExtraKnownMarketplacesSchema,\n /** Auto-compact threshold as a 0-1 fraction. Set false to disable automatic compaction. */\n autoCompactThreshold: AutoCompactThresholdSchema,\n /** Transport enable/disable + options: transport name -> config */\n transports: z.record(TransportSettingsSchema).optional(),\n});\n\nexport type TSettings = z.infer<typeof SettingsSchema>;\nexport type TProviderSettings = z.infer<typeof ProviderSchema>;\nexport type TPermissionsSettings = z.infer<typeof PermissionsSchema>;\n\n/**\n * Fully resolved config after merging all settings files and applying defaults.\n */\nexport interface IResolvedConfig {\n defaultTrustLevel: 'safe' | 'moderate' | 'full';\n /** Response language code (e.g., \"ko\", \"en\"). Undefined = no language constraint. */\n language?: string;\n /** Active provider profile key when providers/currentProvider are used. */\n currentProvider?: string;\n provider: {\n name: string;\n model: string;\n apiKey: string | undefined;\n baseURL?: string;\n timeout?: number;\n options?: Record<string, TUniversalValue>;\n };\n permissions: {\n allow: string[];\n deny: string[];\n };\n env: Record<string, string>;\n hooks?: THooksConfig;\n /** Plugin enablement map: plugin name -> enabled/disabled */\n enabledPlugins?: Record<string, boolean>;\n /** Extra marketplace sources: name -> { source } */\n extraKnownMarketplaces?: Record<\n string,\n { source: { type: string; repo?: string; url?: string; path?: string; ref?: string } }\n >;\n /** Auto-compact threshold as a 0-1 fraction. Set false to disable automatic compaction. */\n autoCompactThreshold?: number | false;\n /** Transport enable/disable + options: transport name -> { enabled, options } */\n transports?: Record<string, { enabled?: boolean; options?: Record<string, unknown> }>;\n}\n","/**\n * Config loader — discovers, merges, and validates settings files.\n *\n * Precedence (lowest → highest):\n * 1. ~/.robota/settings.json (user)\n * 2. ~/.claude/settings.json (user, Claude Code compat)\n * 3. .robota/settings.json (project)\n * 4. .robota/settings.local.json (project-local)\n * 5. .claude/settings.json (project, Claude Code compat)\n * 6. .claude/settings.local.json (project-local, highest priority)\n */\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\n\nimport { SettingsSchema, type TSettings, type IResolvedConfig } from './config-types.js';\n\n/**\n * Return the current user home directory.\n * Reads process.env.HOME at call time so tests can override it.\n */\nfunction getHomeDir(): string {\n return process.env.HOME ?? process.env.USERPROFILE ?? '/';\n}\n\n/** Default resolved config values */\nconst DEFAULTS: IResolvedConfig = {\n defaultTrustLevel: 'moderate',\n provider: {\n name: 'anthropic',\n model: 'claude-opus-4-5',\n apiKey: undefined,\n },\n permissions: {\n allow: [],\n deny: [],\n },\n env: {},\n};\n\n/**\n * Read and parse a JSON file. Returns undefined if the file does not exist.\n * Throws on parse errors.\n */\nfunction readJsonFile(filePath: string): unknown {\n if (!existsSync(filePath)) {\n return undefined;\n }\n const raw = readFileSync(filePath, 'utf-8').trim();\n if (raw.length === 0) {\n // Empty file — likely from a crash during write. Treat as missing.\n return undefined;\n }\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n // Corrupt JSON — likely from a crash during write. Treat as missing.\n return undefined;\n }\n}\n\n/**\n * Resolve a string value that may use the `$ENV:VAR_NAME` prefix to\n * substitute an environment variable.\n */\nfunction resolveEnvRef(value: string): string {\n const ENV_PREFIX = '$ENV:';\n if (value.startsWith(ENV_PREFIX)) {\n const varName = value.slice(ENV_PREFIX.length);\n return process.env[varName] ?? value;\n }\n return value;\n}\n\n/**\n * Apply env-ref resolution to all string fields in a settings object.\n */\nfunction resolveEnvRefs(settings: TSettings): TSettings {\n const provider =\n settings.provider?.apiKey !== undefined\n ? resolveProviderCredentialEnvRefs(settings.provider)\n : settings.provider;\n\n if (settings.providers !== undefined) {\n const providers = Object.fromEntries(\n Object.entries(settings.providers).map(([name, profile]) => [\n name,\n resolveProviderCredentialEnvRefs(profile),\n ]),\n );\n return {\n ...settings,\n provider,\n providers,\n };\n }\n\n return {\n ...settings,\n provider,\n };\n}\n\nfunction resolveProviderCredentialEnvRefs<TProvider extends { apiKey?: string }>(\n provider: TProvider,\n): TProvider {\n return {\n ...provider,\n ...(provider.apiKey !== undefined && { apiKey: resolveEnvRef(provider.apiKey) }),\n };\n}\n\n/**\n * Deep-merge settings objects. Later entries in the array win.\n * Arrays are replaced (not concatenated) so that project settings\n * fully override user settings for list-type fields.\n */\nfunction mergeSettings(layers: TSettings[]): TSettings {\n return layers.reduce<TSettings>((merged, layer) => {\n return {\n ...merged,\n ...layer,\n provider:\n merged.provider !== undefined || layer.provider !== undefined\n ? { ...merged.provider, ...layer.provider }\n : undefined,\n permissions:\n merged.permissions !== undefined || layer.permissions !== undefined\n ? {\n allow: layer.permissions?.allow ?? merged.permissions?.allow,\n deny: layer.permissions?.deny ?? merged.permissions?.deny,\n }\n : undefined,\n env: {\n ...(merged.env ?? {}),\n ...(layer.env ?? {}),\n },\n providers:\n merged.providers !== undefined || layer.providers !== undefined\n ? mergeProviders(merged.providers, layer.providers)\n : undefined,\n enabledPlugins:\n merged.enabledPlugins !== undefined || layer.enabledPlugins !== undefined\n ? { ...(merged.enabledPlugins ?? {}), ...(layer.enabledPlugins ?? {}) }\n : undefined,\n extraKnownMarketplaces: layer.extraKnownMarketplaces ?? merged.extraKnownMarketplaces,\n autoCompactThreshold: layer.autoCompactThreshold ?? merged.autoCompactThreshold,\n };\n }, {});\n}\n\nfunction mergeProviders(\n base: TSettings['providers'],\n override: TSettings['providers'],\n): TSettings['providers'] {\n const result: NonNullable<TSettings['providers']> = { ...(base ?? {}) };\n for (const [name, profile] of Object.entries(override ?? {})) {\n result[name] = {\n ...result[name],\n ...profile,\n };\n }\n return result;\n}\n\nfunction resolveProvider(merged: TSettings): IResolvedConfig['provider'] {\n if (merged.currentProvider !== undefined) {\n return resolveActiveProviderProfile(merged);\n }\n if (merged.provider !== undefined) {\n throw new Error(\n 'Legacy flat \"provider\" settings are not supported. Migrate to \"currentProvider\" + \"providers\" format.',\n );\n }\n return { ...DEFAULTS.provider };\n}\n\nfunction resolveActiveProviderProfile(merged: TSettings): IResolvedConfig['provider'] {\n const currentProvider = merged.currentProvider;\n if (currentProvider === undefined) {\n throw new Error('currentProvider is required');\n }\n const profile = merged.providers?.[currentProvider];\n if (profile === undefined) {\n throw new Error(`currentProvider \"${currentProvider}\" was not found in providers`);\n }\n if (profile.type === undefined) {\n throw new Error(`Provider profile \"${currentProvider}\" is missing type`);\n }\n return {\n name: profile.type,\n model: profile.model ?? DEFAULTS.provider.model,\n apiKey: profile.apiKey ?? DEFAULTS.provider.apiKey,\n ...(profile.baseURL !== undefined && { baseURL: profile.baseURL }),\n ...(profile.timeout !== undefined && { timeout: profile.timeout }),\n ...(profile.options !== undefined && { options: profile.options }),\n };\n}\n\n/**\n * Convert merged TSettings into a fully-resolved IResolvedConfig with defaults.\n */\nfunction toResolvedConfig(merged: TSettings): IResolvedConfig {\n return {\n defaultTrustLevel: merged.defaultTrustLevel ?? DEFAULTS.defaultTrustLevel,\n language: merged.language,\n currentProvider: merged.currentProvider,\n provider: resolveProvider(merged),\n permissions: {\n allow: merged.permissions?.allow ?? DEFAULTS.permissions.allow,\n deny: merged.permissions?.deny ?? DEFAULTS.permissions.deny,\n },\n env: merged.env ?? DEFAULTS.env,\n hooks: merged.hooks ?? undefined,\n enabledPlugins: merged.enabledPlugins ?? undefined,\n extraKnownMarketplaces: merged.extraKnownMarketplaces ?? undefined,\n autoCompactThreshold: merged.autoCompactThreshold,\n };\n}\n\n/**\n * Build the ordered list of settings file paths (lowest → highest priority).\n */\nfunction getSettingsPaths(cwd: string): string[] {\n const home = getHomeDir();\n return [\n join(home, '.robota', 'settings.json'), // 1. user (lowest)\n join(home, '.claude', 'settings.json'), // 1b. user (Claude Code compat)\n join(cwd, '.robota', 'settings.json'), // 2. project\n join(cwd, '.robota', 'settings.local.json'), // 3. project-local\n join(cwd, '.claude', 'settings.json'), // 4. project, Claude Code compat\n join(cwd, '.claude', 'settings.local.json'), // 5. project-local (highest)\n ];\n}\n\n/**\n * Load and merge all settings files, validate with Zod, return resolved config.\n *\n * @param cwd - The working directory (project root) to search for settings\n */\nexport async function loadConfig(cwd: string): Promise<IResolvedConfig> {\n const allPaths = getSettingsPaths(cwd);\n\n const rawEntries: Array<{ raw: unknown; path: string }> = [];\n for (const filePath of allPaths) {\n const raw = readJsonFile(filePath);\n if (raw !== undefined) {\n rawEntries.push({ raw, path: filePath });\n }\n }\n\n const parsedLayers: TSettings[] = rawEntries.map(({ raw, path }) => {\n const result = SettingsSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(`Invalid settings in ${path}: ${result.error.message}`);\n }\n return resolveEnvRefs(result.data);\n });\n\n const merged = mergeSettings(parsedLayers);\n return toResolvedConfig(merged);\n}\n","import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\nexport type TTaskFileStatus = 'todo' | 'in-progress' | 'blocked' | 'completed' | 'unknown';\n\nexport interface ITaskContextFile {\n path: string;\n relativePath: string;\n title: string;\n status: TTaskFileStatus;\n branch?: string;\n scope?: string;\n objective?: string;\n openItems: readonly string[];\n}\n\nexport interface ITaskSelectionOptions {\n currentBranch?: string;\n maxTasks?: number;\n}\n\nexport interface IUpdateTaskFileStatusOptions {\n now?: Date;\n progressMessage?: string;\n}\n\nconst TASKS_DIR = join('.agents', 'tasks');\nconst README_FILENAME = 'README.md';\nconst MARKDOWN_EXTENSION = '.md';\nconst DEFAULT_MAX_TASKS = Number('3');\nconst STATUS_PRIORITIES: Record<TTaskFileStatus, number> = {\n 'in-progress': Number('1'),\n todo: Number('2'),\n blocked: Number('3'),\n unknown: Number('4'),\n completed: Number('5'),\n};\n\nfunction normalizeStatus(value: string | undefined): TTaskFileStatus {\n const normalized = value?.trim().toLowerCase();\n if (\n normalized === 'todo' ||\n normalized === 'in-progress' ||\n normalized === 'blocked' ||\n normalized === 'completed'\n ) {\n return normalized;\n }\n return 'unknown';\n}\n\nfunction extractTitle(content: string, taskPath: string): string {\n const heading = content.split(/\\r?\\n/).find((line) => /^#\\s+/.test(line));\n return heading?.replace(/^#\\s+/, '').trim() || basename(taskPath, MARKDOWN_EXTENSION);\n}\n\nfunction extractMetadata(content: string, key: string): string | undefined {\n const matcher = new RegExp(`^- \\\\*\\\\*${key}\\\\*\\\\*:\\\\s*(.+)$`, 'im');\n return matcher.exec(content)?.[1]?.trim();\n}\n\nfunction extractSection(content: string, title: string): string | undefined {\n const lines = content.split(/\\r?\\n/);\n const heading = new RegExp(`^(#{2,6})\\\\s+${title}\\\\b`, 'i');\n const startIndex = lines.findIndex((line) => heading.test(line));\n if (startIndex < 0) {\n return undefined;\n }\n\n const collected: string[] = [];\n for (const line of lines.slice(startIndex + Number('1'))) {\n if (/^##\\s+/.test(line)) {\n break;\n }\n collected.push(line);\n }\n\n const result = collected.join('\\n').trim();\n return result.length > 0 ? result : undefined;\n}\n\nfunction extractOpenItems(content: string): string[] {\n return content\n .split(/\\r?\\n/)\n .map((line) => /^- \\[ \\]\\s+(.+)$/.exec(line)?.[1]?.trim())\n .filter((item): item is string => item !== undefined && item.length > 0);\n}\n\nfunction taskSortScore(task: ITaskContextFile, currentBranch?: string): number {\n if (currentBranch && task.branch === currentBranch) {\n return Number('0');\n }\n return STATUS_PRIORITIES[task.status];\n}\n\nfunction formatTask(task: ITaskContextFile): string {\n const lines = [`### ${task.title}`, `- **Path:** \\`${task.relativePath}\\``];\n lines.push(`- **Status:** ${task.status}`);\n if (task.branch) lines.push(`- **Branch:** ${task.branch}`);\n if (task.scope) lines.push(`- **Scope:** ${task.scope}`);\n if (task.objective) lines.push(`- **Objective:** ${task.objective}`);\n if (task.openItems.length > 0) {\n lines.push('- **Open items:**');\n lines.push(...task.openItems.map((item) => ` - ${item}`));\n }\n return lines.join('\\n');\n}\n\nfunction formatDate(date: Date): string {\n return date.toISOString().slice(Number('0'), Number('10'));\n}\n\nfunction upsertStatusLine(content: string, status: TTaskFileStatus): string {\n const lines = content.split(/\\r?\\n/);\n const statusLine = `- **Status**: ${status}`;\n const statusIndex = lines.findIndex((line) => /^- \\*\\*Status\\*\\*:\\s*/.test(line));\n if (statusIndex >= Number('0')) {\n lines[statusIndex] = statusLine;\n return lines.join('\\n');\n }\n\n const hasTopHeading = lines.length > Number('0') && /^#\\s+/.test(lines[Number('0')]);\n if (hasTopHeading) {\n lines.splice(Number('1'), Number('0'), '', statusLine);\n } else {\n lines.unshift(statusLine, '');\n }\n return lines.join('\\n');\n}\n\nfunction appendProgressEntry(content: string, now: Date, progressMessage: string): string {\n const entryLines = [`### ${formatDate(now)}`, `- ${progressMessage.trim()}`];\n const lines = content.replace(/\\s+$/u, '').split(/\\r?\\n/);\n const progressIndex = lines.findIndex((line) => /^## Progress\\s*$/.test(line));\n if (progressIndex < Number('0')) {\n return [...lines, '', '## Progress', '', ...entryLines, ''].join('\\n');\n }\n\n const nextHeadingIndex = lines.findIndex(\n (line, index) => index > progressIndex && /^##\\s+/.test(line),\n );\n if (nextHeadingIndex < Number('0')) {\n return [...lines, '', ...entryLines, ''].join('\\n');\n }\n\n lines.splice(nextHeadingIndex, Number('0'), '', ...entryLines, '');\n return lines.join('\\n');\n}\n\nfunction resolveGitDirectory(cwd: string, fs: IFileSystem): string | undefined {\n let current = resolve(cwd);\n let reachedRoot = false;\n while (!reachedRoot) {\n const gitPath = join(current, '.git');\n if (fs.existsSync(gitPath)) {\n const stats = fs.statSync(gitPath);\n if (stats.isDirectory()) return gitPath;\n const content = fs.readFileSync(gitPath, 'utf8').trim();\n const gitdir = content.match(/^gitdir:\\s*(.+)$/)?.[1];\n if (gitdir) return isAbsolute(gitdir) ? gitdir : resolve(current, gitdir);\n }\n\n const parent = dirname(current);\n reachedRoot = parent === current;\n current = parent;\n }\n return undefined;\n}\n\nexport function readCurrentGitBranch(\n cwd: string,\n fs: IFileSystem = new NodeFileSystem(),\n): string | undefined {\n const gitDir = resolveGitDirectory(cwd, fs);\n if (!gitDir) return undefined;\n const headPath = join(gitDir, 'HEAD');\n if (!fs.existsSync(headPath)) return undefined;\n\n const head = fs.readFileSync(headPath, 'utf8').trim();\n const branch = head.match(/^ref:\\s+refs\\/heads\\/(.+)$/)?.[1];\n return branch?.trim();\n}\n\nexport function discoverTaskFiles(cwd: string, fs: IFileSystem = new NodeFileSystem()): string[] {\n const tasksDir = join(cwd, TASKS_DIR);\n if (!fs.existsSync(tasksDir)) {\n return [];\n }\n\n return fs\n .readdirSync(tasksDir, { withFileTypes: true })\n .filter((entry) => entry.isFile())\n .map((entry) => entry.name)\n .filter((name) => name !== README_FILENAME && name.endsWith(MARKDOWN_EXTENSION))\n .sort((a, b) => a.localeCompare(b))\n .map((name) => join(tasksDir, name));\n}\n\nexport function parseTaskFile(\n taskPath: string,\n cwd: string,\n fs: IFileSystem = new NodeFileSystem(),\n): ITaskContextFile {\n const content = fs.readFileSync(taskPath, 'utf8');\n return {\n path: taskPath,\n relativePath: relative(cwd, taskPath),\n title: extractTitle(content, taskPath),\n status: normalizeStatus(extractMetadata(content, 'Status')),\n branch: extractMetadata(content, 'Branch'),\n scope: extractMetadata(content, 'Scope'),\n objective: extractSection(content, 'Objective'),\n openItems: extractOpenItems(content),\n };\n}\n\nexport function selectRelevantTasks(\n tasks: readonly ITaskContextFile[],\n options: ITaskSelectionOptions = {},\n): ITaskContextFile[] {\n const maxTasks = options.maxTasks ?? DEFAULT_MAX_TASKS;\n return [...tasks]\n .filter((task) => task.status !== 'completed')\n .sort(\n (left, right) =>\n taskSortScore(left, options.currentBranch) - taskSortScore(right, options.currentBranch) ||\n left.relativePath.localeCompare(right.relativePath),\n )\n .slice(Number('0'), maxTasks);\n}\n\nexport function formatTaskContext(tasks: readonly ITaskContextFile[]): string {\n return tasks.map(formatTask).join('\\n\\n');\n}\n\nexport function loadTaskContext(\n cwd: string,\n options: ITaskSelectionOptions = {},\n fs: IFileSystem = new NodeFileSystem(),\n): string {\n const currentBranch = options.currentBranch ?? readCurrentGitBranch(cwd, fs);\n const tasks = discoverTaskFiles(cwd, fs).map((path) => parseTaskFile(path, cwd, fs));\n return formatTaskContext(selectRelevantTasks(tasks, { ...options, currentBranch }));\n}\n\nexport function updateTaskFileStatus(\n taskPath: string,\n status: TTaskFileStatus,\n options: IUpdateTaskFileStatusOptions = {},\n fs: IFileSystem = new NodeFileSystem(),\n): void {\n const updated = upsertStatusLine(fs.readFileSync(taskPath, 'utf8'), status);\n const withProgress = options.progressMessage\n ? appendProgressEntry(updated, options.now ?? new Date(), options.progressMessage)\n : updated;\n fs.writeFileSync(taskPath, withProgress, 'utf8');\n}\n","import {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n writeFileSync,\n appendFileSync,\n} from 'fs';\nimport { basename, join } from 'path';\n\nexport const MEMORY_INDEX_MAX_LINES = 200;\nexport const MEMORY_INDEX_MAX_BYTES = Number('25600');\n\nexport type TMemoryType = 'user' | 'feedback' | 'project' | 'reference';\n\nexport interface IStartupMemory {\n content: string;\n path: string;\n lineCount: number;\n truncated: boolean;\n}\n\nexport interface IMemoryTopicSummary {\n name: string;\n path: string;\n}\n\nexport interface IProjectMemorySummary {\n indexPath: string;\n topicsPath: string;\n topics: IMemoryTopicSummary[];\n}\n\nexport interface IAppendMemoryInput {\n type: TMemoryType;\n topic: string;\n text: string;\n}\n\nexport interface IAppendMemoryResult {\n indexPath: string;\n topicPath: string;\n topic: string;\n deduplicated: boolean;\n}\n\nconst INDEX_FILENAME = 'MEMORY.md';\nconst TOPICS_DIRNAME = 'topics';\nconst DATE_LENGTH = 10;\nconst MAX_TOPIC_LENGTH = 80;\nconst DEFAULT_TOPIC = 'general';\nconst TOPIC_EXTENSION = '.md';\n\nconst VALID_TYPES: readonly TMemoryType[] = ['user', 'feedback', 'project', 'reference'];\n\nexport function isMemoryType(value: string): value is TMemoryType {\n return VALID_TYPES.includes(value as TMemoryType);\n}\n\nfunction memoryRoot(cwd: string): string {\n return join(cwd, '.robota', 'memory');\n}\n\nfunction truncateToUtf8Bytes(value: string, maxBytes: number): string {\n const buffer = Buffer.from(value, 'utf8');\n if (buffer.byteLength <= maxBytes) return value;\n return buffer.subarray(0, maxBytes).toString('utf8');\n}\n\nfunction limitLines(value: string, maxLines: number): { content: string; truncated: boolean } {\n const lines = value.split(/\\r?\\n/);\n const limited = lines.slice(0, maxLines);\n return {\n content: limited.join('\\n').trimEnd(),\n truncated: lines.length > maxLines,\n };\n}\n\nfunction sanitizeTopic(topic: string): string {\n const normalized = topic\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9가-힣_-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, MAX_TOPIC_LENGTH);\n return normalized || DEFAULT_TOPIC;\n}\n\nfunction formatEntry(date: Date, input: IAppendMemoryInput, topic: string): string {\n const day = date.toISOString().slice(0, DATE_LENGTH);\n const text = input.text.trim().replace(/\\s+/g, ' ');\n return `[${day}] (${input.type}/${topic}) ${text}`;\n}\n\nfunction normalizeMemoryText(text: string): string {\n return text.trim().replace(/\\s+/g, ' ');\n}\n\nexport class ProjectMemoryStore {\n private readonly cwd: string;\n private readonly now: () => Date;\n\n constructor(cwd: string, now: () => Date = () => new Date()) {\n this.cwd = cwd;\n this.now = now;\n }\n\n getIndexPath(): string {\n return join(memoryRoot(this.cwd), INDEX_FILENAME);\n }\n\n getTopicsPath(): string {\n return join(memoryRoot(this.cwd), TOPICS_DIRNAME);\n }\n\n loadStartupMemory(): IStartupMemory {\n const path = this.getIndexPath();\n if (!existsSync(path)) {\n return { content: '', path, lineCount: 0, truncated: false };\n }\n\n const raw = readFileSync(path, 'utf8');\n const byBytes = truncateToUtf8Bytes(raw, MEMORY_INDEX_MAX_BYTES);\n const byteTruncated = Buffer.byteLength(raw, 'utf8') > MEMORY_INDEX_MAX_BYTES;\n const byLines = limitLines(byBytes, MEMORY_INDEX_MAX_LINES);\n\n return {\n content: byLines.content,\n path,\n lineCount: byLines.content.length === 0 ? 0 : byLines.content.split(/\\r?\\n/).length,\n truncated: byteTruncated || byLines.truncated,\n };\n }\n\n list(): IProjectMemorySummary {\n const topicsPath = this.getTopicsPath();\n const topics = existsSync(topicsPath)\n ? readdirSync(topicsPath, { withFileTypes: true })\n .filter((entry) => entry.isFile() && entry.name.endsWith(TOPIC_EXTENSION))\n .map((entry) => ({\n name: basename(entry.name, TOPIC_EXTENSION),\n path: join(topicsPath, entry.name),\n }))\n .sort((a, b) => a.name.localeCompare(b.name))\n : [];\n\n return {\n indexPath: this.getIndexPath(),\n topicsPath,\n topics,\n };\n }\n\n readTopic(topic: string): string {\n const normalized = sanitizeTopic(topic);\n const path = join(this.getTopicsPath(), `${normalized}${TOPIC_EXTENSION}`);\n if (!existsSync(path)) return '';\n return readFileSync(path, 'utf8').trimEnd();\n }\n\n append(input: IAppendMemoryInput): IAppendMemoryResult {\n const topic = sanitizeTopic(input.topic);\n const root = memoryRoot(this.cwd);\n const topicsPath = this.getTopicsPath();\n mkdirSync(topicsPath, { recursive: true });\n\n const indexPath = this.getIndexPath();\n const topicPath = join(topicsPath, `${topic}${TOPIC_EXTENSION}`);\n const entry = formatEntry(this.now(), input, topic);\n const topicHeader = existsSync(topicPath) ? '' : `# ${topic}\\n\\n`;\n const normalizedText = normalizeMemoryText(input.text);\n\n if (existsSync(topicPath) && readFileSync(topicPath, 'utf8').includes(`) ${normalizedText}`)) {\n return { indexPath, topicPath, topic, deduplicated: true };\n }\n\n if (!existsSync(indexPath)) {\n mkdirSync(root, { recursive: true });\n writeFileSync(indexPath, '# Project Memory\\n\\n', 'utf8');\n }\n\n appendFileSync(indexPath, `- ${entry}\\n`, 'utf8');\n appendFileSync(topicPath, `${topicHeader}- ${entry}\\n`, 'utf8');\n\n return { indexPath, topicPath, topic, deduplicated: false };\n }\n}\n","/**\n * Context loader — walks up the directory tree from `cwd` collecting\n * AGENTS.md and CLAUDE.md files, then concatenates them root-first\n * so that more-specific (closer) instructions appear last.\n */\nimport { existsSync } from 'fs';\nimport { join, dirname, resolve } from 'path';\n\nimport { loadFileWithHash } from './context-file-tracker.js';\nimport { loadTaskContext } from './task-context.js';\nimport { ProjectMemoryStore } from '../memory/project-memory-store.js';\n\nimport type { IContextFileEntry } from './context-file-tracker.js';\n\nexport type { IContextFileEntry };\n\nexport interface ILoadedContext {\n /** Concatenated content of all AGENTS.md files found (root-first) */\n agentsMd: string;\n /** Concatenated content of all CLAUDE.md files found (root-first) */\n claudeMd: string;\n /** Startup project memory index loaded from .robota/memory/MEMORY.md, if present */\n memoryMd?: string;\n /** Formatted active task context loaded from .agents/tasks/*.md, if present */\n taskContext?: string;\n /** Extracted \"Compact Instructions\" section from CLAUDE.md, if present */\n compactInstructions?: string;\n /** Per-file entries for all AGENTS.md files, root-first. Present for staleness detection. */\n agentsFileEntries?: IContextFileEntry[];\n /** Per-file entries for all CLAUDE.md files, root-first. Present for staleness detection. */\n claudeFileEntries?: IContextFileEntry[];\n}\n\nconst AGENTS_FILENAME = 'AGENTS.md';\nconst CLAUDE_FILENAME = 'CLAUDE.md';\n\n/**\n * Walk up directory tree from `startDir`, collecting absolute paths of\n * files named `filename`. Stops at filesystem root.\n * Returns paths ordered root-first (farthest ancestor first).\n */\nfunction collectFilesWalkingUp(startDir: string, filename: string): string[] {\n const found: string[] = [];\n let current = resolve(startDir);\n\n let atRoot = false;\n while (!atRoot) {\n const candidate = join(current, filename);\n if (existsSync(candidate)) {\n found.push(candidate);\n }\n const parent = dirname(current);\n atRoot = parent === current;\n if (!atRoot) {\n current = parent;\n }\n }\n\n // Reverse so that root (farthest) comes first\n return found.reverse();\n}\n\n/**\n * Extract the \"Compact Instructions\" section from CLAUDE.md content.\n * Looks for a markdown heading (any level) containing \"Compact Instructions\"\n * and returns all content until the next heading of the same or higher level.\n */\nfunction extractCompactInstructions(content: string): string | undefined {\n const lines = content.split('\\n');\n let capturing = false;\n let headingLevel = 0;\n const captured: string[] = [];\n\n for (const line of lines) {\n const headingMatch = /^(#{1,6})\\s+/.exec(line);\n if (headingMatch) {\n if (capturing) {\n // Stop if we hit a heading of same or higher level\n if (headingMatch[1].length <= headingLevel) break;\n }\n if (/compact\\s+instructions/i.test(line)) {\n capturing = true;\n headingLevel = headingMatch[1].length;\n continue;\n }\n }\n if (capturing) {\n captured.push(line);\n }\n }\n\n const result = captured.join('\\n').trim();\n return result || undefined;\n}\n\n/**\n * Load all AGENTS.md and CLAUDE.md files found by walking up from `cwd`.\n * Files from higher directories appear before files from lower directories.\n *\n * @param cwd - Starting directory for the walk-up search\n */\nexport async function loadContext(cwd: string): Promise<ILoadedContext> {\n const agentsPaths = collectFilesWalkingUp(cwd, AGENTS_FILENAME);\n const claudePaths = collectFilesWalkingUp(cwd, CLAUDE_FILENAME);\n\n const agentsEntries = agentsPaths.map((p) => loadFileWithHash(p));\n const claudeEntries = claudePaths.map((p) => loadFileWithHash(p));\n\n const agentsMd = agentsEntries.map((e) => e.content).join('\\n\\n');\n const claudeMd = claudeEntries.map((e) => e.content).join('\\n\\n');\n\n const compactInstructions = extractCompactInstructions(claudeMd);\n const startupMemory = new ProjectMemoryStore(cwd).loadStartupMemory();\n const memoryMd = startupMemory.content || undefined;\n const loadedTaskContext = loadTaskContext(cwd);\n const taskContext = loadedTaskContext.trim().length > 0 ? loadedTaskContext : undefined;\n\n return {\n agentsMd,\n claudeMd,\n memoryMd,\n taskContext,\n compactInstructions,\n agentsFileEntries: agentsEntries,\n claudeFileEntries: claudeEntries,\n };\n}\n","/**\n * PluginSettingsStore — single point of read/write for plugin-related settings.\n *\n * Shared by MarketplaceClient and BundlePluginInstaller to prevent\n * concurrent writes from overwriting each other's changes.\n */\n\nimport { dirname } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { TMarketplaceSource } from './marketplace-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/** Persisted marketplace source entry. */\nexport interface IPersistedMarketplaceSource {\n source: TMarketplaceSource;\n}\n\n/** Shape of the plugin-related keys in settings.json. */\nexport interface IPluginSettings {\n enabledPlugins: Record<string, boolean>;\n extraKnownMarketplaces: Record<string, IPersistedMarketplaceSource>;\n}\n\n/** Centralized settings store for plugin configuration. */\nexport class PluginSettingsStore {\n private readonly settingsPath: string;\n private readonly fs: IFileSystem;\n\n constructor(settingsPath: string, fs: IFileSystem = new NodeFileSystem()) {\n this.settingsPath = settingsPath;\n this.fs = fs;\n }\n\n /** Read the full settings file from disk. */\n private readAll(): Record<string, unknown> {\n if (!this.fs.existsSync(this.settingsPath)) {\n return {};\n }\n try {\n const raw = this.fs.readFileSync(this.settingsPath, 'utf-8');\n const data: unknown = JSON.parse(raw);\n if (typeof data === 'object' && data !== null) {\n return data as Record<string, unknown>;\n }\n return {};\n } catch {\n // allow-fallback: corrupt settings file returns empty object to allow recovery\n return {};\n }\n }\n\n /** Write the full settings file to disk. */\n private writeAll(settings: Record<string, unknown>): void {\n const dir = dirname(this.settingsPath);\n if (!this.fs.existsSync(dir)) {\n this.fs.mkdirSync(dir, { recursive: true });\n }\n this.fs.writeFileSync(this.settingsPath, JSON.stringify(settings, null, 2), 'utf-8');\n }\n\n // --- enabledPlugins ---\n\n /** Get the enabledPlugins map. */\n getEnabledPlugins(): Record<string, boolean> {\n const settings = this.readAll();\n const ep = settings.enabledPlugins;\n if (typeof ep === 'object' && ep !== null) {\n return ep as Record<string, boolean>;\n }\n return {};\n }\n\n /** Set a single plugin's enabled state. */\n setPluginEnabled(pluginId: string, enabled: boolean): void {\n const settings = this.readAll();\n const ep = this.getEnabledPluginsFrom(settings);\n ep[pluginId] = enabled;\n settings.enabledPlugins = ep;\n this.writeAll(settings);\n }\n\n /** Remove a plugin from enabledPlugins. */\n removePluginEntry(pluginId: string): void {\n const settings = this.readAll();\n const ep = this.getEnabledPluginsFrom(settings);\n delete ep[pluginId];\n settings.enabledPlugins = ep;\n this.writeAll(settings);\n }\n\n // --- extraKnownMarketplaces ---\n\n /** Get all persisted marketplace sources. */\n getMarketplaceSources(): Record<string, IPersistedMarketplaceSource> {\n const settings = this.readAll();\n const extra = settings.extraKnownMarketplaces;\n if (typeof extra === 'object' && extra !== null) {\n return extra as Record<string, IPersistedMarketplaceSource>;\n }\n return {};\n }\n\n /** Add or update a marketplace source. */\n setMarketplaceSource(name: string, source: TMarketplaceSource): void {\n const settings = this.readAll();\n const extra = this.getMarketplaceSourcesFrom(settings);\n extra[name] = { source };\n settings.extraKnownMarketplaces = extra;\n this.writeAll(settings);\n }\n\n /** Remove a marketplace source. */\n removeMarketplaceSource(name: string): void {\n const settings = this.readAll();\n const extra = this.getMarketplaceSourcesFrom(settings);\n delete extra[name];\n settings.extraKnownMarketplaces = extra;\n this.writeAll(settings);\n }\n\n // --- helpers ---\n\n private getEnabledPluginsFrom(settings: Record<string, unknown>): Record<string, boolean> {\n const ep = settings.enabledPlugins;\n if (typeof ep === 'object' && ep !== null) {\n return ep as Record<string, boolean>;\n }\n return {};\n }\n\n private getMarketplaceSourcesFrom(\n settings: Record<string, unknown>,\n ): Record<string, IPersistedMarketplaceSource> {\n const extra = settings.extraKnownMarketplaces;\n if (typeof extra === 'object' && extra !== null) {\n return extra as Record<string, IPersistedMarketplaceSource>;\n }\n return {};\n }\n}\n","/**\n * Utility functions for bundle plugin loading.\n *\n * Provides frontmatter parsing, manifest validation, and filesystem helpers\n * used by BundlePluginLoader.\n */\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { IBundlePluginManifest } from './bundle-plugin-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/**\n * Parse simple YAML-like frontmatter from a skill markdown file.\n *\n * Handles `key: value` and `key: [item1, item2]` patterns.\n * Returns the parsed metadata and the remaining content after the frontmatter block.\n */\nexport function parseSkillFrontmatter(raw: string): {\n metadata: Record<string, unknown>;\n content: string;\n} {\n const trimmed = raw.trimStart();\n if (!trimmed.startsWith('---')) {\n return { metadata: {}, content: raw };\n }\n\n const endIndex = trimmed.indexOf('---', 3);\n if (endIndex === -1) {\n return { metadata: {}, content: raw };\n }\n\n const frontmatterBlock = trimmed.slice(3, endIndex).trim();\n const content = trimmed.slice(endIndex + 3).trimStart();\n const metadata: Record<string, unknown> = {};\n\n for (const line of frontmatterBlock.split('\\n')) {\n const colonIndex = line.indexOf(':');\n if (colonIndex === -1) continue;\n\n const key = line.slice(0, colonIndex).trim();\n let value: unknown = line.slice(colonIndex + 1).trim();\n\n // Parse inline array: [item1, item2]\n if (typeof value === 'string' && value.startsWith('[') && value.endsWith(']')) {\n const inner = value.slice(1, -1);\n value = inner\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n }\n\n if (key) {\n metadata[key] = value;\n }\n }\n\n return { metadata, content };\n}\n\n/**\n * Validate that a parsed JSON object has the required manifest fields.\n * Returns the typed manifest or null if invalid.\n */\nexport function validateManifest(data: unknown): IBundlePluginManifest | null {\n if (typeof data !== 'object' || data === null) return null;\n\n const obj = data as Record<string, unknown>;\n if (typeof obj.name !== 'string') return null;\n if (typeof obj.version !== 'string') return null;\n if (typeof obj.description !== 'string') return null;\n\n const features =\n typeof obj.features === 'object' && obj.features !== null\n ? (obj.features as Record<string, unknown>)\n : {};\n\n return {\n name: obj.name,\n version: obj.version,\n description: obj.description,\n features: {\n commands: features.commands === true ? true : undefined,\n agents: features.agents === true ? true : undefined,\n skills: features.skills === true ? true : undefined,\n hooks: features.hooks === true ? true : undefined,\n mcp: features.mcp === true ? true : undefined,\n },\n };\n}\n\n/**\n * Get sorted subdirectories from a directory.\n * Returns directory names sorted lexicographically.\n */\nexport function getSortedSubdirs(\n dirPath: string,\n fs: IFileSystem = new NodeFileSystem(),\n): string[] {\n if (!fs.existsSync(dirPath)) return [];\n try {\n const entries = fs.readdirSync(dirPath, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .sort();\n } catch {\n // allow-fallback: unreadable directory returns empty list to allow plugin discovery to continue\n return [];\n }\n}\n","/**\n * BundlePluginLoader — discovers and loads directory-based bundle plugins.\n *\n * Scans the cache directory (`<pluginsDir>/cache/<marketplace>/<plugin>/<version>/`)\n * for subdirectories containing `.claude-plugin/plugin.json`,\n * reads manifests, loads skills (with frontmatter parsing), hooks, and agent definitions.\n *\n * For each plugin, the latest version directory (lexicographically last) is loaded.\n */\n\nimport { join } from 'node:path';\n\nimport {\n parseSkillFrontmatter,\n validateManifest,\n getSortedSubdirs,\n} from './bundle-plugin-utils.js';\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type {\n IBundlePluginManifest,\n IBundleSkill,\n ILoadedBundlePlugin,\n TEnabledPlugins,\n} from './bundle-plugin-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/** Loader for directory-based bundle plugins from the cache directory. */\nexport class BundlePluginLoader {\n private readonly pluginsDir: string;\n private readonly enabledPlugins: TEnabledPlugins;\n private readonly fs: IFileSystem;\n\n constructor(\n pluginsDir: string,\n enabledPlugins?: TEnabledPlugins,\n fs: IFileSystem = new NodeFileSystem(),\n ) {\n this.pluginsDir = pluginsDir;\n this.enabledPlugins = enabledPlugins ?? {};\n this.fs = fs;\n }\n\n /** Load all discovered and enabled bundle plugins (sync). */\n loadPluginsSync(): ILoadedBundlePlugin[] {\n return this.discoverAndLoad();\n }\n\n /** Load all discovered and enabled bundle plugins (async wrapper). */\n async loadAll(): Promise<ILoadedBundlePlugin[]> {\n return this.discoverAndLoad();\n }\n\n /**\n * Discover and load plugins from the cache directory.\n *\n * Directory structure: `<pluginsDir>/cache/<marketplace>/<plugin>/<version>/`\n * For each marketplace/plugin pair, the latest version (lexicographically last) is loaded.\n */\n private discoverAndLoad(): ILoadedBundlePlugin[] {\n const cacheDir = join(this.pluginsDir, 'cache');\n if (!this.fs.existsSync(cacheDir)) {\n return [];\n }\n\n const results: ILoadedBundlePlugin[] = [];\n\n // Iterate marketplaces\n const marketplaces = getSortedSubdirs(cacheDir, this.fs);\n for (const marketplace of marketplaces) {\n const marketplaceDir = join(cacheDir, marketplace);\n const plugins = getSortedSubdirs(marketplaceDir, this.fs);\n\n for (const pluginName of plugins) {\n const pluginDir = join(marketplaceDir, pluginName);\n const versions = getSortedSubdirs(pluginDir, this.fs);\n\n if (versions.length === 0) continue;\n\n // Use the latest version (lexicographically last)\n const latestVersion = versions[versions.length - 1];\n const versionDir = join(pluginDir, latestVersion);\n\n const manifestPath = join(versionDir, '.claude-plugin', 'plugin.json');\n if (!this.fs.existsSync(manifestPath)) continue;\n\n const manifest = this.readManifest(manifestPath);\n if (!manifest) continue;\n\n // Check enabled/disabled state using pluginName@marketplace key\n const pluginId = `${manifest.name}@${marketplace}`;\n if (this.isDisabled(pluginId, manifest.name)) continue;\n\n const loaded = this.loadPlugin(versionDir, manifest);\n results.push(loaded);\n }\n }\n\n return results;\n }\n\n /** Read and validate a plugin.json manifest. Returns null if the manifest structure is invalid. */\n private readManifest(path: string): IBundlePluginManifest | null {\n const raw = this.fs.readFileSync(path, 'utf-8');\n const data: unknown = JSON.parse(raw);\n return validateManifest(data);\n }\n\n /**\n * Check if a plugin is explicitly disabled.\n * Checks both `name@marketplace` and `name` keys.\n * Plugins not listed in enabledPlugins are enabled by default.\n */\n private isDisabled(pluginId: string, pluginName: string): boolean {\n if (pluginId in this.enabledPlugins) {\n return this.enabledPlugins[pluginId] === false;\n }\n if (pluginName in this.enabledPlugins) {\n return this.enabledPlugins[pluginName] === false;\n }\n\n return false;\n }\n\n /** Load a single plugin's skills, hooks, agents, and MCP config. */\n private loadPlugin(pluginDir: string, manifest: IBundlePluginManifest): ILoadedBundlePlugin {\n return {\n manifest,\n skills: this.loadSkills(pluginDir, manifest.name),\n commands: this.loadCommands(pluginDir, manifest.name),\n hooks: this.loadHooks(pluginDir),\n mcpConfig: this.loadMcpConfig(pluginDir),\n agents: this.loadAgents(pluginDir),\n pluginDir,\n };\n }\n\n /** Load skills from the plugin's skills/ directory. */\n private loadSkills(pluginDir: string, pluginName: string): IBundleSkill[] {\n const skillsDir = join(pluginDir, 'skills');\n if (!this.fs.existsSync(skillsDir)) return [];\n\n const entries = this.fs.readdirSync(skillsDir, { withFileTypes: true });\n const skills: IBundleSkill[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const skillFile = join(skillsDir, entry.name, 'SKILL.md');\n if (!this.fs.existsSync(skillFile)) continue;\n\n const raw = this.fs.readFileSync(skillFile, 'utf-8');\n const { metadata, content } = parseSkillFrontmatter(raw);\n\n const description = typeof metadata.description === 'string' ? metadata.description : '';\n\n const skill: IBundleSkill = {\n name: entry.name,\n description,\n skillContent: content,\n ...metadata,\n };\n\n skills.push(skill);\n }\n\n return skills;\n }\n\n /** Load commands from the plugin's commands/ directory (flat .md files). */\n private loadCommands(pluginDir: string, pluginName: string): IBundleSkill[] {\n const commandsDir = join(pluginDir, 'commands');\n if (!this.fs.existsSync(commandsDir)) return [];\n\n const entries = this.fs.readdirSync(commandsDir, { withFileTypes: true });\n const commands: IBundleSkill[] = [];\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md')) continue;\n\n const raw = this.fs.readFileSync(join(commandsDir, entry.name), 'utf-8');\n const { metadata, content } = parseSkillFrontmatter(raw);\n\n const name =\n typeof metadata.name === 'string' ? metadata.name : entry.name.replace(/\\.md$/, '');\n const description = typeof metadata.description === 'string' ? metadata.description : '';\n\n commands.push({\n ...metadata,\n name: `${pluginName}:${name}`,\n description,\n skillContent: content,\n });\n }\n\n return commands;\n }\n\n /** Load hooks from hooks/hooks.json if present. */\n private loadHooks(pluginDir: string): Record<string, unknown> {\n const hooksPath = join(pluginDir, 'hooks', 'hooks.json');\n if (!this.fs.existsSync(hooksPath)) return {};\n\n const raw = this.fs.readFileSync(hooksPath, 'utf-8');\n const data: unknown = JSON.parse(raw);\n if (typeof data === 'object' && data !== null) {\n return data as Record<string, unknown>;\n }\n return {};\n }\n\n /** Load MCP server configuration from `.mcp.json` at the plugin root if present. */\n private loadMcpConfig(pluginDir: string): unknown | undefined {\n const mcpPath = join(pluginDir, '.mcp.json');\n if (!this.fs.existsSync(mcpPath)) return undefined;\n\n const raw = this.fs.readFileSync(mcpPath, 'utf-8');\n return JSON.parse(raw) as unknown;\n }\n\n /** Load agent definitions from agents/ directory if present. */\n private loadAgents(pluginDir: string): string[] {\n const agentsDir = join(pluginDir, 'agents');\n if (!this.fs.existsSync(agentsDir)) return [];\n\n const entries = this.fs.readdirSync(agentsDir, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory() || e.name.endsWith('.md'))\n .map((e) => e.name.replace(/\\.md$/, ''));\n }\n}\n","/**\n * BundlePluginInstaller — installs, uninstalls, enables, and disables bundle plugins.\n *\n * Resolves plugin sources from marketplace manifests, copies/clones to the\n * cache directory, and tracks installations in `installed_plugins.json`.\n */\n\nimport { join, dirname } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { MarketplaceClient, IMarketplacePluginEntry, TExecFn } from './marketplace-client.js';\nimport type { PluginSettingsStore } from './plugin-settings-store.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/** Record of an installed plugin in installed_plugins.json. */\nexport interface IInstalledPluginRecord {\n pluginName: string;\n marketplace: string;\n version: string;\n installPath: string;\n installedAt: string;\n}\n\n/** Shape of installed_plugins.json. */\nexport type TInstalledPluginsRegistry = Record<string, IInstalledPluginRecord>;\n\n/** Options for constructing a BundlePluginInstaller. */\nexport interface IBundlePluginInstallerOptions {\n /** Base plugins directory (e.g., `~/.robota/plugins`). */\n pluginsDir: string;\n /** Shared settings store for enable/disable persistence. */\n settingsStore: PluginSettingsStore;\n /** MarketplaceClient for reading marketplace manifests. */\n marketplaceClient: MarketplaceClient;\n /** Shell exec adapter — must be provided at composition root (e.g., execSync). */\n exec: TExecFn;\n /** File system adapter for testability. */\n fs?: IFileSystem;\n}\n\n/** Default git clone timeout in milliseconds (60 seconds). */\nconst GIT_CLONE_TIMEOUT_MS = 60_000;\n\n/** Installs, uninstalls, enables, and disables bundle plugins. */\nexport class BundlePluginInstaller {\n private readonly pluginsDir: string;\n private readonly cacheDir: string;\n private readonly registryPath: string;\n private readonly settingsStore: PluginSettingsStore;\n private readonly marketplaceClient: MarketplaceClient;\n private readonly exec: TExecFn;\n private readonly fs: IFileSystem;\n\n constructor(options: IBundlePluginInstallerOptions) {\n this.pluginsDir = options.pluginsDir;\n this.cacheDir = join(this.pluginsDir, 'cache');\n this.registryPath = join(this.pluginsDir, 'installed_plugins.json');\n this.settingsStore = options.settingsStore;\n this.marketplaceClient = options.marketplaceClient;\n this.exec = options.exec;\n this.fs = options.fs ?? new NodeFileSystem();\n }\n\n /**\n * Install a plugin from a marketplace.\n *\n * 1. Read marketplace manifest to find the plugin entry.\n * 2. Resolve source (relative path, github, or url).\n * 3. Copy/clone to `cache/<marketplace>/<plugin>/<version>/`.\n * 4. Record in `installed_plugins.json`.\n */\n async install(pluginName: string, marketplaceName: string): Promise<void> {\n // Read marketplace manifest\n const manifest = this.marketplaceClient.fetchManifest(marketplaceName);\n const entry = manifest.plugins.find((p) => p.name === pluginName);\n if (!entry) {\n throw new Error(`Plugin \"${pluginName}\" not found in marketplace \"${marketplaceName}\"`);\n }\n\n // Determine version\n const version = this.resolveVersion(entry, marketplaceName);\n\n // Target directory: cache/<marketplace>/<plugin>/<version>/\n const targetDir = join(this.cacheDir, marketplaceName, pluginName, version);\n\n if (this.fs.existsSync(targetDir)) {\n throw new Error(\n `Plugin \"${pluginName}\" version \"${version}\" is already installed from \"${marketplaceName}\"`,\n );\n }\n\n // Resolve and install from source\n this.resolveAndInstall(entry.source, marketplaceName, pluginName, targetDir);\n\n // Record in installed_plugins.json\n const pluginId = `${pluginName}@${marketplaceName}`;\n const registry = this.readRegistry();\n registry[pluginId] = {\n pluginName,\n marketplace: marketplaceName,\n version,\n installPath: targetDir,\n installedAt: new Date().toISOString(),\n };\n this.writeRegistry(registry);\n }\n\n /**\n * Uninstall a plugin.\n * Removes from cache and from installed_plugins.json.\n */\n async uninstall(pluginId: string): Promise<void> {\n const registry = this.readRegistry();\n const record = registry[pluginId];\n\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed`);\n }\n\n // Remove the installed directory\n if (this.fs.existsSync(record.installPath)) {\n this.fs.rmSync(record.installPath, { recursive: true, force: true });\n }\n\n // Remove from registry\n delete registry[pluginId];\n this.writeRegistry(registry);\n\n // Remove from enabled plugins settings\n this.settingsStore.removePluginEntry(pluginId);\n }\n\n /** Enable a plugin by setting its enabledPlugins entry to true. */\n async enable(pluginId: string): Promise<void> {\n this.settingsStore.setPluginEnabled(pluginId, true);\n }\n\n /** Disable a plugin by setting its enabledPlugins entry to false. */\n async disable(pluginId: string): Promise<void> {\n this.settingsStore.setPluginEnabled(pluginId, false);\n }\n\n /** Get all installed plugins. */\n getInstalledPlugins(): TInstalledPluginsRegistry {\n return this.readRegistry();\n }\n\n /** Get plugins installed from a specific marketplace. */\n getPluginsByMarketplace(marketplaceName: string): IInstalledPluginRecord[] {\n const registry = this.readRegistry();\n return Object.values(registry).filter((r) => r.marketplace === marketplaceName);\n }\n\n // --- Private helpers ---\n\n /** Resolve the version for a plugin entry. */\n private resolveVersion(entry: IMarketplacePluginEntry, marketplaceName: string): string {\n // If the entry has an explicit version field (the manifest may include it),\n // use it. Otherwise use git SHA.\n const entryWithVersion = entry as unknown as Record<string, unknown>;\n if (typeof entryWithVersion.version === 'string' && entryWithVersion.version) {\n return entryWithVersion.version as string;\n }\n return this.marketplaceClient.getMarketplaceSha(marketplaceName);\n }\n\n /**\n * Normalize source object — Claude Code manifests use `source` key instead of `type`.\n * e.g., { source: \"url\", url: \"...\" } → { type: \"url\", url: \"...\" }\n */\n private normalizeSource(\n source: IMarketplacePluginEntry['source'],\n ): IMarketplacePluginEntry['source'] {\n if (typeof source === 'string') return source;\n const obj = source as Record<string, unknown>;\n if (!obj.type && typeof obj.source === 'string') {\n return { ...obj, type: obj.source } as IMarketplacePluginEntry['source'];\n }\n return source;\n }\n\n /** Resolve the source and install the plugin. */\n private resolveAndInstall(\n rawSource: IMarketplacePluginEntry['source'],\n marketplaceName: string,\n pluginName: string,\n targetDir: string,\n ): void {\n this.fs.mkdirSync(targetDir, { recursive: true });\n\n const source = this.normalizeSource(rawSource);\n\n try {\n if (typeof source === 'string') {\n // Relative path — copy from the marketplace clone\n const marketplaceDir = this.marketplaceClient.getMarketplaceDir(marketplaceName);\n const sourcePath = join(marketplaceDir, source);\n\n if (!this.fs.existsSync(sourcePath)) {\n throw new Error(\n `Plugin source path \"${source}\" not found in marketplace \"${marketplaceName}\"`,\n );\n }\n\n this.fs.cpSync(sourcePath, targetDir, { recursive: true });\n } else if (source.type === 'github') {\n // Clone from GitHub\n const repoUrl = `https://github.com/${source.repo}.git`;\n this.cloneToDir(repoUrl, targetDir, pluginName);\n } else if (\n source.type === 'url' &&\n typeof source.url === 'string' &&\n source.url.endsWith('.git')\n ) {\n // Git URL — clone directly\n this.cloneToDir(source.url, targetDir, pluginName);\n } else if (source.type === 'url') {\n throw new Error(`URL source \"${source.url}\" is not a git repository (must end with .git)`);\n } else {\n throw new Error(`Unknown source type: ${JSON.stringify(source)}`);\n }\n } catch (err) {\n // Clean up empty target directory on failure\n if (this.fs.existsSync(targetDir)) {\n this.fs.rmSync(targetDir, { recursive: true, force: true });\n }\n throw err;\n }\n }\n\n /** Clone a git repository to the target directory. */\n private cloneToDir(repoUrl: string, targetDir: string, pluginName: string): void {\n // Remove the directory first since mkdirSync already created it\n this.fs.rmSync(targetDir, { recursive: true, force: true });\n\n const command = `git clone --depth 1 ${repoUrl} ${targetDir}`;\n try {\n this.exec(command, { timeout: GIT_CLONE_TIMEOUT_MS, stdio: 'pipe' });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to clone plugin \"${pluginName}\": ${message}`);\n }\n }\n\n /** Read the installed_plugins.json registry. */\n private readRegistry(): TInstalledPluginsRegistry {\n if (!this.fs.existsSync(this.registryPath)) {\n return {};\n }\n try {\n const raw = this.fs.readFileSync(this.registryPath, 'utf-8');\n const data: unknown = JSON.parse(raw);\n if (typeof data === 'object' && data !== null) {\n return data as TInstalledPluginsRegistry;\n }\n return {};\n } catch {\n // allow-fallback: corrupt installed_plugins.json returns empty registry to allow recovery\n return {};\n }\n }\n\n /** Write the installed_plugins.json registry. */\n private writeRegistry(registry: TInstalledPluginsRegistry): void {\n const dir = dirname(this.registryPath);\n if (!this.fs.existsSync(dir)) {\n this.fs.mkdirSync(dir, { recursive: true });\n }\n this.fs.writeFileSync(this.registryPath, JSON.stringify(registry, null, 2), 'utf-8');\n }\n}\n","/**\n * Marketplace registry I/O helpers.\n *\n * Manages read/write operations for `known_marketplaces.json` and\n * cleanup of installed plugins when a marketplace is removed.\n */\n\nimport { join, dirname } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { TKnownMarketplacesRegistry } from './marketplace-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/** Read the known_marketplaces.json registry. Returns empty object if missing or corrupt. */\nexport function readRegistry(\n registryPath: string,\n fs: IFileSystem = new NodeFileSystem(),\n): TKnownMarketplacesRegistry {\n if (!fs.existsSync(registryPath)) {\n return {};\n }\n try {\n const raw = fs.readFileSync(registryPath, 'utf-8');\n const data: unknown = JSON.parse(raw);\n if (typeof data === 'object' && data !== null) {\n return data as TKnownMarketplacesRegistry;\n }\n return {};\n } catch {\n // allow-fallback: corrupt registry file returns empty object to allow recovery\n return {};\n }\n}\n\n/** Write the known_marketplaces.json registry, creating parent dirs if needed. */\nexport function writeRegistry(\n registryPath: string,\n registry: TKnownMarketplacesRegistry,\n fs: IFileSystem = new NodeFileSystem(),\n): void {\n const dir = dirname(registryPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2), 'utf-8');\n}\n\n/**\n * Remove all installed plugins that belong to a given marketplace.\n * Reads installed_plugins.json, deletes cache directories for matching plugins,\n * and updates the registry.\n */\nexport function removeInstalledPluginsForMarketplace(\n pluginsDir: string,\n marketplaceName: string,\n fs: IFileSystem = new NodeFileSystem(),\n): void {\n const installedPath = join(pluginsDir, 'installed_plugins.json');\n if (!fs.existsSync(installedPath)) return;\n\n let registry: Record<string, { marketplace?: string; installPath?: string }>;\n try {\n const raw = fs.readFileSync(installedPath, 'utf-8');\n const data: unknown = JSON.parse(raw);\n if (typeof data !== 'object' || data === null) return;\n registry = data as Record<string, { marketplace?: string; installPath?: string }>;\n } catch {\n // allow-fallback: corrupt installed_plugins.json is skipped, no plugins removed\n return;\n }\n\n let changed = false;\n for (const [pluginId, record] of Object.entries(registry)) {\n if (record.marketplace === marketplaceName) {\n // Remove the cache directory for this plugin\n if (record.installPath && fs.existsSync(record.installPath)) {\n fs.rmSync(record.installPath, { recursive: true, force: true });\n }\n delete registry[pluginId];\n changed = true;\n }\n }\n\n if (changed) {\n const dir = dirname(installedPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(installedPath, JSON.stringify(registry, null, 2), 'utf-8');\n }\n}\n","/**\n * MarketplaceClient — manages marketplace registries via shallow git clones.\n *\n * Marketplaces are git repositories containing `.claude-plugin/marketplace.json`.\n * They are cloned to `~/.robota/plugins/marketplaces/<name>/` and tracked\n * in `known_marketplaces.json`.\n */\n\nimport { join } from 'node:path';\n\nimport {\n readRegistry,\n writeRegistry,\n removeInstalledPluginsForMarketplace,\n} from './marketplace-registry.js';\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type {\n TMarketplaceSource,\n IMarketplacePluginEntry,\n IMarketplaceManifest,\n IMarketplaceClientOptions,\n TExecFn,\n} from './marketplace-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\nexport type {\n TMarketplaceSource,\n IMarketplacePluginEntry,\n IMarketplaceManifest,\n IMarketplaceClientOptions,\n TExecFn,\n} from './marketplace-types.js';\nexport type { IKnownMarketplaceEntry, TKnownMarketplacesRegistry } from './marketplace-types.js';\n\n/** Default git operation timeout in milliseconds (60 seconds). */\nconst GIT_TIMEOUT_MS = 60_000;\n\n/** Manages marketplace registries via shallow git clones. */\nexport class MarketplaceClient {\n private readonly pluginsDir: string;\n private readonly exec: TExecFn;\n private readonly marketplacesDir: string;\n private readonly registryPath: string;\n private readonly fs: IFileSystem;\n\n constructor(options: IMarketplaceClientOptions & { fs?: IFileSystem }) {\n this.pluginsDir = options.pluginsDir;\n this.exec = options.exec;\n this.marketplacesDir = join(this.pluginsDir, 'marketplaces');\n this.registryPath = join(this.pluginsDir, 'known_marketplaces.json');\n this.fs = options.fs ?? new NodeFileSystem();\n }\n\n /**\n * Add a marketplace by cloning its repository.\n *\n * 1. Shallow git clone (`--depth 1`) to `marketplaces/<name>/`.\n * 2. Read `.claude-plugin/marketplace.json` for the `name` field.\n * 3. Register in `known_marketplaces.json`.\n *\n * Returns the registered marketplace name from the manifest.\n */\n addMarketplace(source: TMarketplaceSource): string {\n // Clone to a temp name first, then read the manifest to get the real name\n const tempName = 'temp-' + Date.now().toString(36);\n const tempDir = join(this.marketplacesDir, tempName);\n\n this.fs.mkdirSync(this.marketplacesDir, { recursive: true });\n\n if (source.type === 'local') {\n if (!this.fs.existsSync(source.path)) {\n throw new Error(`Local marketplace path does not exist: ${source.path}`);\n }\n this.fs.cpSync(source.path, tempDir, { recursive: true });\n } else {\n const cloneUrl = this.resolveCloneUrl(source);\n const command = `git clone --depth 1 ${cloneUrl} ${tempDir}`;\n try {\n this.exec(command, { timeout: GIT_TIMEOUT_MS, stdio: 'pipe' });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to clone marketplace: ${message}`);\n }\n }\n\n const manifestPath = join(tempDir, '.claude-plugin', 'marketplace.json');\n if (!this.fs.existsSync(manifestPath)) {\n this.fs.rmSync(tempDir, { recursive: true, force: true });\n throw new Error(\n source.type === 'local'\n ? 'Local directory does not contain .claude-plugin/marketplace.json'\n : 'Cloned repository does not contain .claude-plugin/marketplace.json',\n );\n }\n\n const manifest = this.readManifestFromPath(manifestPath);\n const name = manifest.name;\n\n if (!name) {\n this.fs.rmSync(tempDir, { recursive: true, force: true });\n throw new Error('Marketplace manifest does not contain a \"name\" field');\n }\n\n const registry = readRegistry(this.registryPath, this.fs);\n if (registry[name]) {\n this.fs.rmSync(tempDir, { recursive: true, force: true });\n throw new Error(`Marketplace \"${name}\" already exists`);\n }\n\n const finalDir = join(this.marketplacesDir, name);\n this.fs.renameSync(tempDir, finalDir);\n\n registry[name] = {\n source,\n installLocation: finalDir,\n lastUpdated: new Date().toISOString(),\n };\n writeRegistry(this.registryPath, registry, this.fs);\n\n return name;\n }\n\n /**\n * Remove a marketplace.\n * Uninstalls all plugins from that marketplace, then deletes the clone directory\n * and removes from the registry.\n */\n removeMarketplace(name: string): void {\n const registry = readRegistry(this.registryPath, this.fs);\n const entry = registry[name];\n if (!entry) {\n throw new Error(`Marketplace \"${name}\" not found`);\n }\n\n removeInstalledPluginsForMarketplace(this.pluginsDir, name, this.fs);\n\n if (this.fs.existsSync(entry.installLocation)) {\n this.fs.rmSync(entry.installLocation, { recursive: true, force: true });\n }\n\n delete registry[name];\n writeRegistry(this.registryPath, registry, this.fs);\n }\n\n /**\n * Update a marketplace by running git pull on its clone.\n * The manifest is re-read from disk on demand (via fetchManifest), so the\n * updated manifest is automatically available after pull.\n */\n updateMarketplace(name: string): void {\n const registry = readRegistry(this.registryPath, this.fs);\n const entry = registry[name];\n if (!entry) {\n throw new Error(`Marketplace \"${name}\" not found`);\n }\n\n if (!this.fs.existsSync(entry.installLocation)) {\n throw new Error(`Marketplace directory for \"${name}\" does not exist`);\n }\n\n if (entry.source.type === 'local') {\n const localSource = entry.source as { type: 'local'; path: string };\n if (!this.fs.existsSync(localSource.path)) {\n throw new Error(`Local marketplace path does not exist: ${localSource.path}`);\n }\n this.fs.rmSync(entry.installLocation, { recursive: true, force: true });\n this.fs.cpSync(localSource.path, entry.installLocation, { recursive: true });\n } else {\n const command = `git -C ${entry.installLocation} pull`;\n try {\n this.exec(command, { timeout: GIT_TIMEOUT_MS, stdio: 'pipe' });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to update marketplace \"${name}\": ${message}`);\n }\n }\n\n entry.lastUpdated = new Date().toISOString();\n writeRegistry(this.registryPath, registry, this.fs);\n }\n\n /** List all registered marketplaces. */\n listMarketplaces(): Array<{ name: string; source: TMarketplaceSource; lastUpdated: string }> {\n const registry = readRegistry(this.registryPath, this.fs);\n return Object.entries(registry).map(([name, entry]) => ({\n name,\n source: entry.source,\n lastUpdated: entry.lastUpdated,\n }));\n }\n\n /** Read the marketplace manifest from a registered marketplace's clone. */\n fetchManifest(marketplaceName: string): IMarketplaceManifest {\n const registry = readRegistry(this.registryPath, this.fs);\n const entry = registry[marketplaceName];\n if (!entry) {\n throw new Error(`Marketplace \"${marketplaceName}\" not found`);\n }\n\n const manifestPath = join(entry.installLocation, '.claude-plugin', 'marketplace.json');\n if (!this.fs.existsSync(manifestPath)) {\n throw new Error(\n `Marketplace \"${marketplaceName}\" does not contain .claude-plugin/marketplace.json`,\n );\n }\n\n return this.readManifestFromPath(manifestPath);\n }\n\n /** Get the clone directory path for a registered marketplace. */\n getMarketplaceDir(name: string): string {\n const registry = readRegistry(this.registryPath, this.fs);\n const entry = registry[name];\n if (!entry) {\n throw new Error(`Marketplace \"${name}\" not found`);\n }\n return entry.installLocation;\n }\n\n /**\n * Get the current git SHA (first 12 chars) for a marketplace clone.\n * Used as a version identifier when plugins lack explicit versions.\n */\n getMarketplaceSha(name: string): string {\n const dir = this.getMarketplaceDir(name);\n try {\n const result = this.exec(`git -C ${dir} rev-parse HEAD`, {\n timeout: GIT_TIMEOUT_MS,\n stdio: 'pipe',\n });\n return result.toString().trim().slice(0, 12);\n } catch {\n // allow-fallback: git SHA unavailable returns 'unknown' as version identifier\n return 'unknown';\n }\n }\n\n /** List all available plugins across all marketplaces. */\n listAvailablePlugins(): Array<IMarketplacePluginEntry & { marketplace: string }> {\n const results: Array<IMarketplacePluginEntry & { marketplace: string }> = [];\n const marketplaces = this.listMarketplaces();\n\n for (const { name } of marketplaces) {\n try {\n const manifest = this.fetchManifest(name);\n for (const plugin of manifest.plugins) {\n results.push({ ...plugin, marketplace: name });\n }\n } catch {\n // allow-fallback: failed marketplace is skipped to allow other marketplaces to load\n // Skip failed marketplaces\n }\n }\n\n return results;\n }\n\n // --- Private helpers ---\n\n /** Resolve a marketplace source to a git clone URL. */\n private resolveCloneUrl(source: TMarketplaceSource): string {\n switch (source.type) {\n case 'github':\n return `https://github.com/${source.repo}.git`;\n case 'git':\n return source.url;\n case 'local':\n throw new Error('Local source type does not use git cloning');\n case 'url':\n throw new Error('URL marketplace source is not yet supported');\n }\n }\n\n /** Read and parse a marketplace.json from a file path. */\n private readManifestFromPath(path: string): IMarketplaceManifest {\n const raw = this.fs.readFileSync(path, 'utf-8');\n const data: unknown = JSON.parse(raw);\n\n if (typeof data !== 'object' || data === null) {\n throw new Error('Invalid marketplace manifest: not an object');\n }\n\n const obj = data as Record<string, unknown>;\n if (typeof obj.name !== 'string') {\n throw new Error('Invalid marketplace manifest: missing \"name\" field');\n }\n\n return data as IMarketplaceManifest;\n }\n}\n","/**\n * Plugin hooks merger — merges plugin hooks into session config.\n */\n\nimport { join, dirname } from 'node:path';\n\nimport type { ILoadedBundlePlugin } from './bundle-plugin-types.js';\nimport type { THooksConfig } from '@robota-sdk/agent-core';\n\n/** Build plugin env vars for a plugin. */\nfunction buildPluginEnv(plugin: ILoadedBundlePlugin): Record<string, string> {\n const dataDir = join(dirname(dirname(plugin.pluginDir)), 'data', plugin.manifest.name);\n return {\n CLAUDE_PLUGIN_ROOT: plugin.pluginDir,\n CLAUDE_PLUGIN_PATH: plugin.pluginDir,\n CLAUDE_PLUGIN_DATA: dataDir,\n };\n}\n\ninterface IHookGroup {\n hooks?: Array<{ command?: string; [key: string]: string | undefined }>;\n env?: Record<string, string>;\n [key: string]: unknown;\n}\n\n/** Replace ${CLAUDE_PLUGIN_ROOT} in hook command strings. */\nfunction resolvePluginRoot(group: IHookGroup, pluginDir: string): IHookGroup {\n if (Array.isArray(group.hooks)) {\n return {\n ...group,\n hooks: group.hooks.map((h) => {\n if (typeof h.command === 'string') {\n return {\n ...h,\n command: h.command.replace(/\\$\\{CLAUDE_PLUGIN_ROOT\\}/g, pluginDir),\n };\n }\n return h;\n }),\n };\n }\n return group;\n}\n\n/** Merge plugin hooks into a single THooksConfig. */\nexport function mergePluginHooks(plugins: ILoadedBundlePlugin[]): THooksConfig {\n const merged: Record<string, IHookGroup[]> = {};\n for (const plugin of plugins) {\n const hooksObj = plugin.hooks as Record<string, IHookGroup | IHookGroup[]> | undefined;\n if (!hooksObj) continue;\n const pluginEnv = buildPluginEnv(plugin);\n const innerHooks = (hooksObj.hooks ?? hooksObj) as Record<string, IHookGroup[]>;\n for (const [event, groups] of Object.entries(innerHooks)) {\n if (!Array.isArray(groups)) continue;\n if (!merged[event]) merged[event] = [];\n const resolved = groups.map((group) => {\n const r = resolvePluginRoot(group, plugin.pluginDir);\n r.env = pluginEnv;\n return r;\n });\n merged[event]!.push(...resolved);\n }\n }\n return merged as THooksConfig;\n}\n\n/** Merge plugin hooks into config hooks (plugin hooks have lowest priority). */\nexport function mergeHooksIntoConfig(\n configHooks: Record<string, IHookGroup[]> | undefined,\n pluginHooks: Record<string, IHookGroup[]>,\n): Record<string, IHookGroup[]> | undefined {\n const pluginKeys = Object.keys(pluginHooks);\n if (pluginKeys.length === 0) return configHooks;\n const merged: Record<string, IHookGroup[]> = {};\n for (const [event, groups] of Object.entries(pluginHooks)) {\n merged[event] = [...groups];\n }\n if (configHooks) {\n for (const [event, groups] of Object.entries(configHooks)) {\n if (!Array.isArray(groups)) continue;\n if (!merged[event]) merged[event] = [];\n merged[event]!.push(...groups);\n }\n }\n return merged;\n}\n","/**\n * Session initialization helpers for InteractiveSession.\n *\n * Handles async config/context loading, plugin merging, and session creation.\n * Option interfaces live in interactive-session-options.ts.\n * Session restore logic lives in interactive-session-restore.ts.\n */\n\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nimport { FileSessionLogger } from '@robota-sdk/agent-session';\nimport { applyWorkspaceManifest } from '@robota-sdk/agent-tools';\n\nimport { NOOP_TERMINAL } from './interactive-session-execution.js';\nimport { detectProject } from '../context/project-detector.js';\nimport { projectPaths } from '../paths.js';\nimport { injectSavedMessage } from './interactive-session-restore.js';\nimport { createSession } from '../assembly/index.js';\nimport { EditCheckpointStore } from '../checkpoints/edit-checkpoint-store.js';\nimport { loadConfig } from '../config/config-loader.js';\nimport { loadContext } from '../context/context-loader.js';\nimport { BundlePluginLoader } from '../plugins/index.js';\nimport { mergePluginHooks, mergeHooksIntoConfig } from '../plugins/plugin-hooks-merger.js';\n\nimport type {\n IInteractiveSessionStandardOptions,\n IInitOptions,\n} from './interactive-session-options.js';\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { ICommandResult } from '../commands/index.js';\nimport type { IResolvedConfig } from '../config/config-types.js';\nimport type { IContextFileEntry } from '../context/context-loader.js';\nimport type { IContextWindowState, TToolArgs, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type { ICompactEvent } from '@robota-sdk/agent-session';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport type {\n IInteractiveSessionStandardOptions,\n IInteractiveSessionInjectedOptions,\n TInteractiveSessionOptions,\n IInitOptions,\n} from './interactive-session-options.js';\nexport { injectSavedMessage, loadSessionRecord } from './interactive-session-restore.js';\n\n/** Return value of createInteractiveSession — session plus staleness tracking data. */\nexport interface ICreatedInteractiveSession {\n session: Session;\n /** Per-file entries for AGENTS.md files loaded at startup. Used for staleness detection. */\n agentsFileEntries: IContextFileEntry[];\n /** Per-file entries for CLAUDE.md files loaded at startup. Used for staleness detection. */\n claudeFileEntries: IContextFileEntry[];\n /** Rebuilds the system message given updated agentsMd and claudeMd strings. */\n rebuildSystemMessage: (agentsMd: string, claudeMd: string) => string;\n}\n\n/**\n * Create and return a fully initialized Session.\n *\n * Loads config, context, project info in parallel, merges plugin hooks,\n * then constructs the session via createSession().\n */\nexport async function createInteractiveSession(\n options: IInitOptions,\n): Promise<ICreatedInteractiveSession> {\n const cwd = options.cwd;\n const [config, context, projectInfo] = await Promise.all([\n options.config ? Promise.resolve(options.config) : loadConfig(cwd),\n options.bare\n ? Promise.resolve({\n agentsMd: '',\n claudeMd: '',\n agentsFileEntries: [],\n claudeFileEntries: [],\n })\n : loadContext(cwd),\n options.bare\n ? Promise.resolve({ type: 'unknown' as const, language: 'unknown' as const })\n : detectProject(cwd),\n ]);\n\n let mergedConfig: IResolvedConfig = options.language\n ? { ...config, language: options.language }\n : config;\n\n const pluginsDir = join(homedir(), '.robota', 'plugins');\n const pluginLoader = new BundlePluginLoader(pluginsDir);\n if (!options.bare) {\n try {\n const plugins = pluginLoader.loadPluginsSync();\n if (plugins.length > 0) {\n const pluginHooks = mergePluginHooks(plugins);\n mergedConfig = {\n ...mergedConfig,\n hooks: mergeHooksIntoConfig(\n mergedConfig.hooks as Record<string, Array<Record<string, unknown>>> | undefined,\n pluginHooks as Record<string, Array<Record<string, unknown>>>,\n ),\n };\n }\n } catch {\n // No plugins dir or load failed\n }\n }\n\n const paths = projectPaths(cwd);\n\n const sandboxRestored = await restoreInteractiveSandboxSnapshot(options);\n if (!sandboxRestored) {\n await applyInteractiveWorkspaceManifest(options, cwd);\n }\n\n const sessionId =\n options.resumeSessionId && !options.forkSession ? options.resumeSessionId : undefined;\n\n const { session, rebuildSystemMessage } = createSession({\n config: mergedConfig,\n cwd,\n context,\n projectInfo,\n permissionMode: options.permissionMode,\n maxTurns: options.maxTurns,\n terminal: NOOP_TERMINAL,\n sessionLogger: new FileSessionLogger(paths.logs),\n permissionHandler: options.permissionHandler,\n provider: options.provider,\n onTextDelta: options.onTextDelta,\n onContextUpdate: options.onContextUpdate,\n onCompactEvent: options.onCompactEvent,\n onToolExecution: options.onToolExecution,\n sessionId,\n allowedTools: options.allowedTools,\n appendSystemPrompt: options.appendSystemPrompt,\n backgroundTaskRunners: options.backgroundTaskRunners,\n subagentRunnerFactory: options.subagentRunnerFactory,\n ...(options.commandModules?.some((module) =>\n module.sessionRequirements?.includes('agent-runtime'),\n )\n ? { enableAgentRuntime: true }\n : {}),\n ...(options.commandModules || options.commandDescriptors\n ? {\n commandDescriptors: [\n ...(options.commandDescriptors ?? []),\n ...(options.commandModules?.flatMap((module) => module.commandDescriptors ?? []) ?? []),\n ],\n }\n : {}),\n modelCommandExecutor: options.modelCommandExecutor,\n isModelCommandInvocable: options.isModelCommandInvocable,\n editCheckpointRecorder: options.editCheckpointRecorder,\n reversibleExecution: options.reversibleExecution,\n sandboxClient: options.sandboxClient,\n agentName: options.agentName,\n });\n\n return {\n session,\n agentsFileEntries: context.agentsFileEntries ?? [],\n claudeFileEntries: context.claudeFileEntries ?? [],\n rebuildSystemMessage,\n };\n}\n\nasync function applyInteractiveWorkspaceManifest(\n options: IInitOptions,\n cwd: string,\n): Promise<void> {\n if (!options.workspaceManifest) return;\n if (!options.sandboxClient) {\n throw new Error('workspaceManifest requires sandboxClient.');\n }\n await applyWorkspaceManifest(options.sandboxClient, options.workspaceManifest, {\n hostRoot: cwd,\n ...(options.sandboxWorkspaceRoot ? { targetRoot: options.sandboxWorkspaceRoot } : {}),\n });\n}\n\nasync function restoreInteractiveSandboxSnapshot(options: IInitOptions): Promise<boolean> {\n if (!options.sandboxSnapshotId) return false;\n if (!options.sandboxClient?.restore) {\n throw new Error('sandboxSnapshotId requires sandboxClient with restore().');\n }\n await options.sandboxClient.restore(options.sandboxSnapshotId);\n return true;\n}\n\n/** Dependencies injected into initializeInteractiveSessionAsync from the class. */\nexport interface IAsyncInitDeps {\n /** Currently stored sandbox snapshot ID (may be set by restore). */\n sandboxSnapshotId: string | undefined;\n /** Session ID to resume (may be set by restore). */\n resumeSessionId: string | undefined;\n /** Messages deferred until the session is created (set during restore). */\n pendingRestoreMessages: TUniversalMessage[] | null;\n /** Callbacks for handling events during initialization. */\n onTextDelta: (delta: string) => void;\n onContextUpdate: (state: IContextWindowState) => void;\n onCompactEvent: (event: ICompactEvent) => void;\n onToolExecution: (event: {\n type: 'start' | 'end';\n toolName: string;\n toolArgs?: TToolArgs;\n success?: boolean;\n denied?: boolean;\n toolResultData?: string;\n }) => void;\n executeModelCommand: (command: string, args: string) => Promise<ICommandResult | null>;\n isModelCommandInvocable: (command: string) => boolean;\n commandDescriptors: readonly ICapabilityDescriptor[];\n setEditCheckpointStore: (store: EditCheckpointStore) => void;\n}\n\n/** Result returned from initializeInteractiveSessionAsync. */\nexport interface IAsyncInitResult {\n session: Session;\n agentsFileEntries: IContextFileEntry[];\n claudeFileEntries: IContextFileEntry[];\n rebuildSystemMessage: ICreatedInteractiveSession['rebuildSystemMessage'];\n autoCompactThresholdSource: 'default' | 'settings';\n}\n\n/**\n * Async initialization flow extracted from InteractiveSession.initializeAsync.\n *\n * Loads config, creates the session, injects pending restore messages, and\n * returns the initialized session plus metadata. The caller is responsible\n * for wiring the result back into the class (bgTracker.subscribe, persist, etc.).\n */\nexport async function initializeInteractiveSessionAsync(\n options: IInteractiveSessionStandardOptions,\n deps: IAsyncInitDeps,\n): Promise<IAsyncInitResult> {\n const config = options.config ?? (await loadConfig(options.cwd));\n const autoCompactThresholdSource =\n config.autoCompactThreshold === undefined ? 'default' : 'settings';\n const checkpointStore = new EditCheckpointStore({ cwd: options.cwd });\n deps.setEditCheckpointStore(checkpointStore);\n\n const created = await createInteractiveSession({\n cwd: options.cwd,\n provider: options.provider,\n config,\n permissionMode: options.permissionMode,\n maxTurns: options.maxTurns,\n permissionHandler: options.permissionHandler,\n resumeSessionId: deps.resumeSessionId,\n forkSession: options.forkSession,\n onTextDelta: deps.onTextDelta,\n onContextUpdate: deps.onContextUpdate,\n onCompactEvent: deps.onCompactEvent,\n onToolExecution: deps.onToolExecution,\n bare: options.bare,\n allowedTools: options.allowedTools,\n appendSystemPrompt: options.appendSystemPrompt,\n language: options.language,\n backgroundTaskRunners: options.backgroundTaskRunners,\n subagentRunnerFactory: options.subagentRunnerFactory,\n ...(options.commandModules ? { commandModules: options.commandModules } : {}),\n editCheckpointRecorder: checkpointStore,\n ...(options.reversibleExecution ? { reversibleExecution: options.reversibleExecution } : {}),\n ...(options.sandboxClient ? { sandboxClient: options.sandboxClient } : {}),\n ...(options.workspaceManifest ? { workspaceManifest: options.workspaceManifest } : {}),\n ...(options.sandboxWorkspaceRoot ? { sandboxWorkspaceRoot: options.sandboxWorkspaceRoot } : {}),\n ...(deps.sandboxSnapshotId ? { sandboxSnapshotId: deps.sandboxSnapshotId } : {}),\n ...(options.agentName ? { agentName: options.agentName } : {}),\n commandDescriptors: deps.commandDescriptors,\n ...(deps.commandDescriptors.length > 0\n ? {\n modelCommandExecutor: deps.executeModelCommand,\n isModelCommandInvocable: deps.isModelCommandInvocable,\n }\n : {}),\n });\n\n if (deps.pendingRestoreMessages) {\n for (const msg of deps.pendingRestoreMessages) injectSavedMessage(created.session, msg);\n }\n\n return {\n session: created.session,\n agentsFileEntries: created.agentsFileEntries,\n claudeFileEntries: created.claudeFileEntries,\n rebuildSystemMessage: created.rebuildSystemMessage,\n autoCompactThresholdSource,\n };\n}\n","import type { IInteractiveSessionRecord, IInteractiveSessionStore } from './session-persistence.js';\nimport type {\n IBackgroundJobGroupState,\n IBackgroundTaskState,\n TBackgroundJobGroupEvent,\n TBackgroundTaskEvent,\n} from '../background-tasks/index.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type { IContextReferenceItem } from '../context/context-reference-inventory.js';\nimport type { IMemoryEvent, IMemoryReference } from '../memory/automatic-memory-types.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\nimport type { Session } from '@robota-sdk/agent-session';\n\n/**\n * Persist the current session state to the session store.\n * Silently ignores errors because persistence failure must not break execution.\n */\nexport function persistSession(\n sessionStore: IInteractiveSessionStore,\n session: Session,\n sessionName: string | undefined,\n cwd: string,\n history: IHistoryEntry[],\n backgroundState?: {\n tasks: readonly IBackgroundTaskState[];\n events: readonly TBackgroundTaskEvent[];\n groups?: readonly IBackgroundJobGroupState[];\n groupEvents?: readonly TBackgroundJobGroupEvent[];\n },\n memoryState?: {\n events: readonly IMemoryEvent[];\n usedReferences: readonly IMemoryReference[];\n },\n skillActivationState?: {\n events: readonly ISkillActivationEvent[];\n },\n contextReferenceState?: {\n references: readonly IContextReferenceItem[];\n },\n sandboxState?: {\n snapshotId?: string;\n },\n): void {\n try {\n const sessionId = session.getSessionId();\n const existing = sessionStore.load(sessionId);\n const sandboxSnapshotId = sandboxState?.snapshotId ?? existing?.sandboxSnapshotId;\n sessionStore.save(\n buildInteractiveSessionRecord({\n session,\n sessionId,\n sessionName: sessionName ?? existing?.name,\n cwd,\n history,\n createdAt: existing?.createdAt,\n backgroundState,\n memoryState,\n skillActivationState,\n contextReferenceState,\n ...(sandboxSnapshotId !== undefined ? { sandboxSnapshotId } : {}),\n }),\n );\n } catch {\n // Persistence is best-effort for interactive execution.\n }\n}\n\ninterface IBuildInteractiveSessionRecordInput {\n session: Session;\n sessionId: string;\n sessionName?: string;\n cwd: string;\n history: IHistoryEntry[];\n createdAt?: string;\n backgroundState?: {\n tasks: readonly IBackgroundTaskState[];\n events: readonly TBackgroundTaskEvent[];\n groups?: readonly IBackgroundJobGroupState[];\n groupEvents?: readonly TBackgroundJobGroupEvent[];\n };\n memoryState?: {\n events: readonly IMemoryEvent[];\n usedReferences: readonly IMemoryReference[];\n };\n skillActivationState?: {\n events: readonly ISkillActivationEvent[];\n };\n contextReferenceState?: {\n references: readonly IContextReferenceItem[];\n };\n sandboxSnapshotId?: string;\n}\n\nfunction buildInteractiveSessionRecord(\n input: IBuildInteractiveSessionRecordInput,\n): IInteractiveSessionRecord {\n return {\n id: input.sessionId,\n ...(input.sessionName !== undefined ? { name: input.sessionName } : {}),\n cwd: input.cwd,\n createdAt: input.createdAt ?? new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n messages: input.session.getHistory(),\n history: input.history,\n systemPrompt: input.session.getSystemMessage(),\n toolSchemas: input.session.getToolSchemas(),\n ...(input.sandboxSnapshotId !== undefined\n ? { sandboxSnapshotId: input.sandboxSnapshotId }\n : {}),\n ...buildBackgroundRecordFields(input.backgroundState),\n ...buildMemoryRecordFields(input.memoryState),\n ...buildSkillActivationRecordFields(input.skillActivationState),\n ...buildContextReferenceRecordFields(input.contextReferenceState),\n };\n}\n\nfunction buildBackgroundRecordFields(\n state: IBuildInteractiveSessionRecordInput['backgroundState'],\n): Partial<IInteractiveSessionRecord> {\n if (!state) return {};\n return {\n backgroundTasks: [...state.tasks],\n backgroundTaskEvents: [...state.events],\n backgroundJobGroups: [...(state.groups ?? [])],\n backgroundJobGroupEvents: [...(state.groupEvents ?? [])],\n };\n}\n\nfunction buildMemoryRecordFields(\n state: IBuildInteractiveSessionRecordInput['memoryState'],\n): Partial<IInteractiveSessionRecord> {\n if (!state) return {};\n return {\n memoryEvents: [...state.events],\n usedMemoryReferences: [...state.usedReferences],\n };\n}\n\nfunction buildSkillActivationRecordFields(\n state: IBuildInteractiveSessionRecordInput['skillActivationState'],\n): Partial<IInteractiveSessionRecord> {\n if (!state) return {};\n return { skillActivationEvents: [...state.events] };\n}\n\nfunction buildContextReferenceRecordFields(\n state: IBuildInteractiveSessionRecordInput['contextReferenceState'],\n): Partial<IInteractiveSessionRecord> {\n if (!state) return {};\n return { contextReferences: [...state.references] };\n}\n","import type { ICapabilityDescriptor, TCapabilityKind } from '../capabilities/types.js';\nimport type { ICommand } from '../command-api/types.js';\n\nfunction inferKind(command: ICommand): TCapabilityKind {\n if (command.source === 'skill') return 'skill';\n if (command.source === 'plugin' && command.skillContent) return 'skill';\n return 'builtin-command';\n}\n\nexport function commandToCapabilityDescriptor(command: ICommand): ICapabilityDescriptor {\n const skillLike =\n command.source === 'skill' || (command.source === 'plugin' && Boolean(command.skillContent));\n return {\n name: command.name,\n kind: inferKind(command),\n description: command.description,\n userInvocable: command.userInvocable !== false,\n modelInvocable:\n command.modelInvocable === true || (skillLike && command.disableModelInvocation !== true),\n ...(command.argumentHint ? { argumentHint: command.argumentHint } : {}),\n ...(command.safety ? { safety: command.safety } : {}),\n };\n}\n","import { commandToCapabilityDescriptor } from './capability-descriptors.js';\n\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { ICommandModule } from '../command-api/command-module.js';\nimport type { ICommandSource, ICommand } from '../command-api/types.js';\n\n/** Aggregates commands from multiple sources */\nexport class CommandRegistry {\n private sources: ICommandSource[] = [];\n\n addSource(source: ICommandSource): void {\n this.sources.push(source);\n }\n\n replaceSource(name: string, source?: ICommandSource): void {\n this.sources = this.sources.filter((candidate) => candidate.name !== name);\n if (source !== undefined) {\n this.sources.push(source);\n }\n }\n\n addModule(module: ICommandModule): void {\n for (const source of module.commandSources ?? []) {\n this.addSource(source);\n }\n }\n\n /** Get all commands, optionally filtered by prefix */\n getCommands(filter?: string): ICommand[] {\n const all: ICommand[] = [];\n for (const source of this.sources) {\n all.push(...source.getCommands());\n }\n if (!filter) return all;\n const lower = filter.toLowerCase();\n return all.filter((cmd) => cmd.name.toLowerCase().startsWith(lower));\n }\n\n /** Resolve a short name to its fully qualified plugin:name form */\n resolveQualifiedName(shortName: string): string | null {\n const matches = this.getCommands().filter(\n (c) => c.source === 'plugin' && c.name.includes(':') && c.name.endsWith(`:${shortName}`),\n );\n if (matches.length !== 1) return null;\n return matches[0]!.name;\n }\n\n /** Get subcommands for a specific command */\n getSubcommands(commandName: string): ICommand[] {\n const lower = commandName.toLowerCase();\n for (const source of this.sources) {\n for (const cmd of source.getCommands()) {\n if (cmd.name.toLowerCase() === lower && cmd.subcommands) {\n return cmd.subcommands;\n }\n }\n }\n return [];\n }\n\n getCapabilityDescriptors(): ICapabilityDescriptor[] {\n return this.getCommands().map((command) => commandToCapabilityDescriptor(command));\n }\n}\n","import { createSystemCommands } from './system-command.js';\n\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { ICommandHostContext, ICommandResult, ISystemCommand } from '../command-api/index.js';\n\n/** Registry for system commands. */\nexport class SystemCommandExecutor {\n private readonly commands: Map<string, ISystemCommand>;\n\n constructor(commands?: ISystemCommand[]) {\n this.commands = new Map();\n for (const cmd of commands ?? createSystemCommands()) {\n this.commands.set(cmd.name, cmd);\n }\n }\n\n /** Register an additional command. */\n register(command: ISystemCommand): void {\n this.commands.set(command.name, command);\n }\n\n /** Execute a command by name. Returns null if command not found. */\n async execute(\n name: string,\n session: ICommandHostContext,\n args: string,\n ): Promise<ICommandResult | null> {\n const cmd = this.getCommand(name);\n if (!cmd) return null;\n return await this.executeCommand(cmd, session, args);\n }\n\n getCommand(name: string): ISystemCommand | undefined {\n return this.commands.get(name);\n }\n\n /** Resolve whether a command requires permission confirmation. */\n resolveRequiresPermission(command: ISystemCommand): boolean {\n if (command.requiresPermission !== undefined) return command.requiresPermission;\n return command.safety !== 'read-only';\n }\n\n async executeCommand(\n command: ISystemCommand,\n session: ICommandHostContext,\n args: string,\n ): Promise<ICommandResult> {\n return await command.execute(session, args);\n }\n\n /** List all registered commands. */\n listCommands(): ISystemCommand[] {\n return [...this.commands.values()];\n }\n\n listModelInvocableCommands(): ICapabilityDescriptor[] {\n return this.listCommands()\n .filter((command) => command.modelInvocable === true)\n .map((command) => ({\n name: command.name,\n kind: 'builtin-command',\n description: command.description,\n userInvocable: command.userInvocable !== false,\n modelInvocable: true,\n ...(command.argumentHint ? { argumentHint: command.argumentHint } : {}),\n ...(command.safety ? { safety: command.safety } : {}),\n }));\n }\n\n isModelInvocable(name: string): boolean {\n return this.commands.get(name)?.modelInvocable === true;\n }\n\n async executeModelInvocable(\n name: string,\n session: ICommandHostContext,\n args: string,\n ): Promise<ICommandResult | null> {\n if (!this.isModelInvocable(name)) return null;\n return this.execute(name, session, args);\n }\n\n /** Check if a command exists. */\n hasCommand(name: string): boolean {\n return this.commands.has(name);\n }\n}\n","import type { ISystemCommand } from '../command-api/index.js';\nexport { SystemCommandExecutor } from './system-command-executor.js';\nexport type {\n ICommandInteraction,\n ICommandChoicePromptOption,\n ICommandResult,\n TCommandEffect,\n TCommandResultDataValue,\n TCommandInteractionPrompt,\n} from '../command-api/index.js';\nexport type { ISystemCommand, TSystemCommandLifecycle } from '../command-api/index.js';\n\n/** Built-in system commands. */\nexport function createSystemCommands(): ISystemCommand[] {\n return [];\n}\n","import { createSystemCommands } from './system-command.js';\n\nimport type { ICommandModule } from '../command-api/command-module.js';\nimport type { ISystemCommand } from '../command-api/index.js';\nimport type { ICommandSource, ICommand } from '../command-api/types.js';\n\nfunction commandToPaletteEntry(command: ISystemCommand): ICommand {\n return {\n name: command.name,\n description: command.description,\n source: 'builtin',\n ...(command.subcommands ? { subcommands: [...command.subcommands] } : {}),\n ...(command.argumentHint ? { argumentHint: command.argumentHint } : {}),\n ...(command.modelInvocable !== undefined ? { modelInvocable: command.modelInvocable } : {}),\n ...(command.userInvocable !== undefined ? { userInvocable: command.userInvocable } : {}),\n ...(command.safety ? { safety: command.safety } : {}),\n };\n}\n\n/** Command source for SDK-owned built-in commands. */\nexport class BuiltinCommandSource implements ICommandSource {\n readonly name = 'builtin';\n private readonly commands: ICommand[];\n\n constructor(systemCommands: readonly ISystemCommand[] = createSystemCommands()) {\n this.commands = systemCommands.map(commandToPaletteEntry);\n }\n\n getCommands(): ICommand[] {\n return this.commands;\n }\n}\n\nexport function createBuiltinCommandModule(): ICommandModule {\n const systemCommands = createSystemCommands();\n return {\n name: 'sdk-builtin',\n commandSources: [new BuiltinCommandSource(systemCommands)],\n systemCommands,\n };\n}\n","import { findProviderDefinition, getProviderCredentialRequirement } from '@robota-sdk/agent-core';\nimport { formatEnvReference, hasUsableSecretReference } from '@robota-sdk/agent-core';\n\nimport type {\n IProviderDefinition,\n IProviderCredentialRequirement,\n IProviderProfileConfig,\n TProviderCredentialField,\n TUniversalValue,\n} from '@robota-sdk/agent-core';\n\nexport interface IProviderProfileSettings extends IProviderProfileConfig {\n [key: string]: TUniversalValue;\n}\n\nexport interface ILegacyProviderSettings {\n [key: string]: TUniversalValue;\n name?: string;\n model?: string;\n apiKey?: string;\n baseURL?: string;\n timeout?: number;\n options?: Record<string, TUniversalValue>;\n}\n\nexport type TProviderSettingsDocument = Record<string, TUniversalValue> & {\n currentProvider?: string;\n providers?: Record<string, IProviderProfileSettings>;\n provider?: ILegacyProviderSettings;\n};\n\nexport interface IProviderSetupInput {\n profile: string;\n type: string;\n model?: string;\n apiKey?: string;\n apiKeyEnv?: string;\n baseURL?: string;\n timeout?: number;\n setCurrent?: boolean;\n}\n\nexport interface IProviderSetupPatch {\n currentProvider?: string;\n providers: Record<string, IProviderProfileSettings>;\n}\n\nexport interface IProviderSettingsBuildOptions {\n providerDefinitions?: readonly IProviderDefinition[];\n}\n\nexport function upsertProviderProfile(\n settings: TProviderSettingsDocument,\n profileName: string,\n profile: IProviderProfileSettings,\n): TProviderSettingsDocument {\n return {\n ...settings,\n providers: {\n ...(settings.providers ?? {}),\n [profileName]: profile,\n },\n };\n}\n\nexport function setCurrentProvider(\n settings: TProviderSettingsDocument,\n profileName: string,\n): TProviderSettingsDocument {\n if (!settings.providers?.[profileName]) {\n throw new Error(`Provider profile \"${profileName}\" was not found`);\n }\n return {\n ...settings,\n currentProvider: profileName,\n };\n}\n\nexport function deleteProviderProfile(\n settings: TProviderSettingsDocument,\n profileName: string,\n options: { replacementCurrentProvider?: string } = {},\n): TProviderSettingsDocument {\n if (!settings.providers?.[profileName]) {\n throw new Error(`Provider profile \"${profileName}\" was not found`);\n }\n const providers = { ...settings.providers };\n delete providers[profileName];\n if (\n options.replacementCurrentProvider !== undefined &&\n providers[options.replacementCurrentProvider] === undefined\n ) {\n throw new Error(`Provider profile \"${options.replacementCurrentProvider}\" was not found`);\n }\n const next: TProviderSettingsDocument = {\n ...settings,\n providers,\n };\n if (settings.currentProvider !== profileName) {\n return next;\n }\n if (options.replacementCurrentProvider !== undefined) {\n return {\n ...next,\n currentProvider: options.replacementCurrentProvider,\n };\n }\n const withoutCurrentProvider = { ...next };\n delete withoutCurrentProvider.currentProvider;\n return withoutCurrentProvider;\n}\n\nexport function validateProviderProfile(\n profileName: string,\n profile: IProviderProfileSettings,\n options: IProviderSettingsBuildOptions = {},\n): void {\n if (!profile.type) {\n throw new Error(`Provider profile \"${profileName}\" is missing type`);\n }\n if (!profile.model) {\n throw new Error(`Provider profile \"${profileName}\" is missing model`);\n }\n const definition = findProviderDefinition(options.providerDefinitions ?? [], profile.type);\n const credentialRequirement = getProviderCredentialRequirement(definition);\n if (\n credentialRequirement !== undefined &&\n !hasUsableRequiredProviderCredential(profile, definition?.defaults, credentialRequirement)\n ) {\n throw new Error(\n `Provider profile \"${profileName}\" is missing ${formatCredentialRequirement(credentialRequirement)}`,\n );\n }\n}\n\nexport function buildProviderSetupPatch(\n input: IProviderSetupInput,\n options: IProviderSettingsBuildOptions = {},\n): IProviderSetupPatch {\n const profile = buildProviderProfile(input, options);\n validateProviderProfile(input.profile, profile, options);\n return {\n ...(input.setCurrent && { currentProvider: input.profile }),\n providers: {\n [input.profile]: profile,\n },\n };\n}\n\nexport function buildProviderProfile(\n input: IProviderSetupInput,\n options: IProviderSettingsBuildOptions = {},\n): IProviderProfileSettings {\n const defaults = getProviderDefaults(input.type, options.providerDefinitions ?? []);\n const apiKey =\n input.apiKeyEnv !== undefined\n ? formatEnvReference(input.apiKeyEnv)\n : (input.apiKey ?? defaults.apiKey);\n const baseURL = input.baseURL ?? defaults.baseURL;\n\n return {\n type: input.type,\n model: input.model ?? defaults.model,\n ...(isNonEmptyString(apiKey) && { apiKey }),\n ...(baseURL !== undefined && { baseURL }),\n ...(input.timeout !== undefined && { timeout: input.timeout }),\n };\n}\n\nexport function mergeProviderPatch(\n settings: TProviderSettingsDocument,\n patch: IProviderSetupPatch,\n): TProviderSettingsDocument {\n const [profileName, profile] = Object.entries(patch.providers)[0] ?? [];\n if (!profileName || !profile) {\n return settings;\n }\n const withProfile = upsertProviderProfile(settings, profileName, profile);\n return patch.currentProvider\n ? setCurrentProvider(withProfile, patch.currentProvider)\n : withProfile;\n}\n\nfunction getProviderDefaults(\n type: string,\n providerDefinitions: readonly IProviderDefinition[],\n): { model?: string; apiKey?: string; baseURL?: string } {\n return findProviderDefinition(providerDefinitions, type)?.defaults ?? {};\n}\n\nfunction hasUsableRequiredProviderCredential(\n profile: IProviderProfileSettings,\n defaults: IProviderDefinition['defaults'],\n requirement: IProviderCredentialRequirement,\n): boolean {\n return requirement.anyOf.some((field) =>\n hasUsableSecretReference(resolveProviderCredentialValue(field, profile, defaults)),\n );\n}\n\nfunction resolveProviderCredentialValue(\n field: TProviderCredentialField,\n profile: IProviderProfileSettings,\n defaults: IProviderDefinition['defaults'],\n): string | undefined {\n return profile[field] ?? defaults?.[field];\n}\n\nfunction formatCredentialRequirement(requirement: IProviderCredentialRequirement): string {\n return requirement.anyOf.join(' or ');\n}\n\nfunction isNonEmptyString(value: string | undefined): value is string {\n return value !== undefined && value.length > 0;\n}\n","import { findProviderDefinition } from '@robota-sdk/agent-core';\n\nimport { validateProviderProfile, type IProviderProfileSettings } from './provider-settings.js';\n\nimport type { ICommandResult } from '../command-result.js';\nimport type { IProviderCommandModuleOptions } from './provider-command-types.js';\nimport type { IProviderProbeResult, IProviderProfileConfig } from '@robota-sdk/agent-core';\n\nexport async function testProviderProfileCommand(\n currentProvider: string | undefined,\n providers: Record<string, IProviderProfileSettings> | undefined,\n profileArg: string | undefined,\n options: IProviderCommandModuleOptions,\n): Promise<ICommandResult> {\n const profileName = profileArg ?? currentProvider;\n if (!profileName) {\n return { message: 'No provider profile selected.', success: false };\n }\n const profile = providers?.[profileName];\n if (!profile) {\n return { message: `Provider profile \"${profileName}\" was not found.`, success: false };\n }\n try {\n validateProviderProfile(profileName, profile, {\n providerDefinitions: options.providerDefinitions,\n });\n } catch (error) {\n return { message: error instanceof Error ? error.message : String(error), success: false };\n }\n const definition = profile.type\n ? findProviderDefinition(options.providerDefinitions, profile.type)\n : undefined;\n const probe = definition?.probeProfile ?? probeProviderProfile;\n const result = await probe(profile);\n return {\n message: result.ok\n ? `Provider \"${profileName}\" test passed: ${result.message}`\n : `Provider \"${profileName}\" test failed: ${result.message}; manual configuration can continue.`,\n success: true,\n data: { providerTest: { profile: profileName } },\n };\n}\n\nexport async function probeProviderProfile(\n profile: IProviderProfileConfig,\n): Promise<IProviderProbeResult> {\n void profile;\n return { ok: true, message: 'Profile fields are valid; no endpoint probe configured.' };\n}\n","import { existsSync, readFileSync } from 'node:fs';\n\nimport {\n findProviderDefinition,\n getProviderCredentialRequirement,\n hasUsableSecretReference,\n type IProviderCredentialRequirement,\n type IProviderDefinition,\n type TProviderCredentialField,\n} from '@robota-sdk/agent-core';\n\nimport type { TProviderSettingsDocument } from './provider-settings.js';\n\nexport type TSettingsCheck = 'missing' | 'valid' | 'corrupt' | 'incomplete';\n\nexport function checkSettingsDocument(\n settings: TProviderSettingsDocument,\n providerDefinitions: readonly IProviderDefinition[] = [],\n): TSettingsCheck {\n return hasUsableProviderConfig(settings, providerDefinitions) ? 'valid' : 'incomplete';\n}\n\nfunction hasUsableProviderConfig(\n settings: TProviderSettingsDocument,\n providerDefinitions: readonly IProviderDefinition[],\n): boolean {\n if (typeof settings.currentProvider === 'string') {\n const profile = settings.providers?.[settings.currentProvider];\n return isUsableProviderProfile(profile?.type, profile, providerDefinitions);\n }\n if (\n settings.provider &&\n isUsableProviderProfile(settings.provider.name, settings.provider, providerDefinitions)\n ) {\n return true;\n }\n return false;\n}\n\nfunction isUsableProviderProfile(\n type: string | undefined,\n profile: { apiKey?: string } | undefined,\n providerDefinitions: readonly IProviderDefinition[],\n): boolean {\n if (!profile) return false;\n if (!type) return hasUsableSecretReference(profile.apiKey);\n const definition = findProviderDefinition(providerDefinitions, type);\n if (definition === undefined) return false;\n const credentialRequirement = getProviderCredentialRequirement(definition);\n if (credentialRequirement === undefined) return true;\n return hasUsableRequiredProviderCredential(profile, definition, credentialRequirement);\n}\n\nfunction hasUsableRequiredProviderCredential(\n profile: { apiKey?: string },\n definition: IProviderDefinition,\n requirement: IProviderCredentialRequirement,\n): boolean {\n return requirement.anyOf.some((field) =>\n hasUsableSecretReference(resolveProviderCredentialValue(field, profile, definition)),\n );\n}\n\nfunction resolveProviderCredentialValue(\n field: TProviderCredentialField,\n profile: { apiKey?: string },\n definition: IProviderDefinition,\n): string | undefined {\n return profile[field] ?? definition.defaults?.[field];\n}\n\nexport function checkSettingsFile(\n filePath: string,\n providerDefinitions: readonly IProviderDefinition[] = [],\n): TSettingsCheck {\n if (!existsSync(filePath)) return 'missing';\n try {\n const raw = readFileSync(filePath, 'utf8').trim();\n if (raw.length === 0) return 'incomplete';\n const parsed = JSON.parse(raw) as TProviderSettingsDocument;\n return checkSettingsDocument(parsed, providerDefinitions);\n } catch {\n // allow-fallback: corrupt settings file is a valid terminal state ('corrupt')\n return 'corrupt';\n }\n}\n","import { normalizeProviderConfig } from '@robota-sdk/agent-executor';\n\nimport { NodeFileSystem } from '../../adapters/node-file-system.js';\n\nimport type { IProviderProfileSettings, TProviderSettingsDocument } from './provider-settings.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\nimport type { IProviderConfig, IProviderDefinition } from '@robota-sdk/agent-core';\n\nexport function readMergedProviderSettingsFromPaths(\n paths: readonly string[],\n fs: IFileSystem = new NodeFileSystem(),\n): TProviderSettingsDocument {\n return paths.reduce<TProviderSettingsDocument>((settings, filePath) => {\n const parsed = readSettingsFile(filePath, fs);\n if (parsed === undefined) {\n return settings;\n }\n return mergeSettings(settings, parsed);\n }, {});\n}\n\nfunction readSettingsFile(\n filePath: string,\n fs: IFileSystem,\n): TProviderSettingsDocument | undefined {\n if (!fs.existsSync(filePath)) {\n return undefined;\n }\n try {\n const raw = fs.readFileSync(filePath, 'utf8');\n return JSON.parse(raw) as TProviderSettingsDocument;\n } catch {\n // allow-fallback: unparseable settings file is skipped to allow the config chain to continue\n return undefined;\n }\n}\n\nexport function mergeSettings(\n base: TProviderSettingsDocument,\n override: TProviderSettingsDocument,\n): TProviderSettingsDocument {\n return {\n ...base,\n ...override,\n provider:\n base.provider !== undefined || override.provider !== undefined\n ? { ...base.provider, ...override.provider }\n : undefined,\n providers:\n base.providers !== undefined || override.providers !== undefined\n ? mergeProviders(base.providers, override.providers)\n : undefined,\n };\n}\n\nexport function mergeProviders(\n base: TProviderSettingsDocument['providers'],\n override: TProviderSettingsDocument['providers'],\n): TProviderSettingsDocument['providers'] {\n const result: Record<string, IProviderProfileSettings> = { ...(base ?? {}) };\n for (const [name, profile] of Object.entries(override ?? {})) {\n result[name] = { ...result[name], ...profile };\n }\n return result;\n}\n\nexport function resolveActiveProvider(\n settings: TProviderSettingsDocument,\n providerOverride: string | undefined,\n providerDefinitions: readonly IProviderDefinition[],\n): IProviderConfig | undefined {\n const activeProvider = providerOverride ?? settings.currentProvider;\n if (activeProvider !== undefined) {\n const profile = settings.providers?.[activeProvider];\n if (profile === undefined) {\n throw new Error(`Provider profile \"${activeProvider}\" was not found in providers`);\n }\n if (!profile.type) {\n throw new Error(`Provider profile \"${activeProvider}\" is missing type`);\n }\n return normalizeProviderConfig(\n {\n name: profile.type,\n model: profile.model,\n apiKey: profile.apiKey,\n baseURL: profile.baseURL,\n timeout: profile.timeout,\n options: profile.options,\n },\n providerDefinitions,\n );\n }\n\n const provider = settings.provider;\n if (provider?.name) {\n return normalizeProviderConfig(\n {\n name: provider.name,\n model: provider.model,\n apiKey: provider.apiKey,\n baseURL: provider.baseURL,\n timeout: provider.timeout,\n options: provider.options,\n },\n providerDefinitions,\n );\n }\n\n return undefined;\n}\n","import { join } from 'node:path';\n\nfunction getUserHome(): string {\n return process.env.HOME ?? process.env.USERPROFILE ?? '/';\n}\n\nexport function getProviderSettingsPaths(cwd: string): string[] {\n const userHome = getUserHome();\n return [\n join(userHome, '.robota', 'settings.json'),\n join(userHome, '.claude', 'settings.json'),\n join(cwd, '.robota', 'settings.json'),\n join(cwd, '.robota', 'settings.local.json'),\n join(cwd, '.claude', 'settings.json'),\n join(cwd, '.claude', 'settings.local.json'),\n ];\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\n\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\n\nexport type TSettingsData = Record<string, TUniversalValue>;\n\nexport function getUserSettingsPath(): string {\n const home = process.env.HOME ?? process.env.USERPROFILE ?? '/';\n return join(home, '.robota', 'settings.json');\n}\n\nexport type TSettingsScope = 'user' | 'project-local';\n\nexport function resolveSettingsPathForScope(\n cwd: string,\n scope: TSettingsScope | undefined,\n): string {\n if (scope === undefined || scope === 'user') {\n return getUserSettingsPath();\n }\n return join(cwd, '.robota', 'settings.local.json');\n}\n\nexport function readSettings(path: string): TSettingsData {\n if (!existsSync(path)) return {};\n const raw = readFileSync(path, 'utf8');\n try {\n return JSON.parse(raw) as TSettingsData;\n } catch {\n // allow-fallback: corrupt settings file must not crash the CLI; reset to empty defaults\n process.stderr.write(`Warning: corrupt settings file at ${path}, resetting to defaults\\n`);\n return {};\n }\n}\n\nexport function writeSettings(path: string, settings: TSettingsData): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(settings, null, 2) + '\\n', 'utf8');\n}\n\nexport function updateModelInSettings(settingsPath: string, modelId: string): void {\n const settings = readSettings(settingsPath);\n const currentProvider = settings.currentProvider;\n const providers = settings.providers;\n if (typeof currentProvider === 'string' && isSettingsData(providers)) {\n const providerMap = providers as Record<string, TSettingsData | undefined>;\n providerMap[currentProvider] = {\n ...(isSettingsData(providerMap[currentProvider]) ? providerMap[currentProvider] : {}),\n model: modelId,\n };\n settings.providers = providerMap;\n } else {\n settings.provider = {\n ...(isSettingsData(settings.provider) ? settings.provider : {}),\n model: modelId,\n };\n }\n writeSettings(settingsPath, settings);\n}\n\nfunction isSettingsData(value: TUniversalValue): value is TSettingsData {\n return (\n value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)\n );\n}\n\nexport function deleteSettings(path: string): boolean {\n if (existsSync(path)) {\n unlinkSync(path);\n return true;\n }\n return false;\n}\n","import { readMergedProviderSettingsFromPaths } from './provider-merge.js';\nimport {\n buildProviderSetupPatch,\n mergeProviderPatch,\n setCurrentProvider,\n type IProviderProfileSettings,\n type IProviderSetupInput,\n type IProviderSettingsBuildOptions,\n type TProviderSettingsDocument,\n} from './provider-settings.js';\nimport { getProviderSettingsPaths } from '../../config/provider-paths.js';\nimport { readSettings, writeSettings } from '../../config/settings-io.js';\n\nexport interface IProviderSwitchOptions {\n knownProviders?: Record<string, IProviderProfileSettings>;\n}\n\nexport interface IActiveModelChangeOptions {\n settingsPaths?: readonly string[];\n providerOverride?: string | undefined;\n}\n\nexport interface IProviderSettingsWriteTargetOptions {\n settingsPaths?: readonly string[];\n}\n\nexport interface IActiveModelChangeResult {\n settingsPath: string;\n settings: TProviderSettingsDocument;\n profileName?: string;\n}\n\nexport function resolveProviderSettingsWriteTargetPath(\n cwd: string,\n options: IProviderSettingsWriteTargetOptions = {},\n): string {\n const settingsPaths = options.settingsPaths ?? getProviderSettingsPaths(cwd);\n const targetPath = findLastPathWithCurrentProvider(settingsPaths) ?? settingsPaths[0];\n if (targetPath === undefined) {\n throw new Error('No settings path available for provider update');\n }\n return targetPath;\n}\n\nfunction readProviderDocument(settingsPath: string): TProviderSettingsDocument {\n return readSettings(settingsPath) as TProviderSettingsDocument;\n}\n\nexport function applyProviderConfiguration(\n settingsPath: string,\n input: IProviderSetupInput,\n options: IProviderSettingsBuildOptions = {},\n): TProviderSettingsDocument {\n const settings = readProviderDocument(settingsPath);\n const patch = buildProviderSetupPatch(input, options);\n const next = mergeProviderPatch(settings, patch);\n writeSettings(settingsPath, next);\n return next;\n}\n\nexport function applyProviderSwitch(\n settingsPath: string,\n profileName: string,\n options: IProviderSwitchOptions = {},\n): TProviderSettingsDocument {\n const settings = readProviderDocument(settingsPath);\n const hasLocalProfile = settings.providers?.[profileName] !== undefined;\n const hasKnownProfile = options.knownProviders?.[profileName] !== undefined;\n const next =\n hasLocalProfile || hasKnownProfile\n ? { ...settings, currentProvider: profileName }\n : setCurrentProvider(settings, profileName);\n writeSettings(settingsPath, next);\n return next;\n}\n\nexport function applyActiveModelChange(\n cwd: string,\n modelId: string,\n options: IActiveModelChangeOptions = {},\n): IActiveModelChangeResult {\n const settingsPaths = options.settingsPaths ?? getProviderSettingsPaths(cwd);\n const merged = readMergedProviderSettingsFromPaths(settingsPaths);\n const activeProfileName = options.providerOverride ?? merged.currentProvider;\n\n if (typeof activeProfileName !== 'string') {\n throw new Error(\n 'Cannot update model: no active provider profile. Set \"currentProvider\" in settings.',\n );\n }\n\n return updateActiveProviderProfileModel(settingsPaths, activeProfileName, modelId);\n}\n\nfunction updateActiveProviderProfileModel(\n settingsPaths: readonly string[],\n profileName: string,\n modelId: string,\n): IActiveModelChangeResult {\n const settingsPath =\n findLastPathWithProviderProfile(settingsPaths, profileName) ?? settingsPaths[0];\n if (settingsPath === undefined) {\n throw new Error('No settings path available for model update');\n }\n\n const settings = readProviderDocument(settingsPath);\n const providers = settings.providers ?? {};\n const existing = providers[profileName] ?? {};\n const next: TProviderSettingsDocument = {\n ...settings,\n providers: {\n ...providers,\n [profileName]: {\n ...existing,\n model: modelId,\n },\n },\n };\n writeSettings(settingsPath, next);\n return { settingsPath, settings: next, profileName };\n}\n\nfunction findLastPathWithProviderProfile(\n settingsPaths: readonly string[],\n profileName: string,\n): string | undefined {\n for (let index = settingsPaths.length - 1; index >= 0; index -= 1) {\n const settingsPath = settingsPaths[index];\n if (settingsPath === undefined) continue;\n const settings = readProviderDocument(settingsPath);\n if (settings.providers?.[profileName] !== undefined) return settingsPath;\n }\n return undefined;\n}\n\nfunction findLastPathWithCurrentProvider(settingsPaths: readonly string[]): string | undefined {\n for (let index = settingsPaths.length - 1; index >= 0; index -= 1) {\n const settingsPath = settingsPaths[index];\n if (settingsPath === undefined) continue;\n const settings = readProviderDocument(settingsPath);\n if (settings.currentProvider !== undefined) return settingsPath;\n }\n return undefined;\n}\n","import { createProviderFromConfig } from '@robota-sdk/agent-executor';\n\nimport { readMergedProviderSettingsFromPaths, resolveActiveProvider } from './provider-merge.js';\nimport { getProviderSettingsPaths } from '../../config/provider-paths.js';\n\nimport type { TProviderSettingsDocument } from './provider-settings.js';\nimport type { IAIProvider, IProviderConfig, IProviderDefinition } from '@robota-sdk/agent-core';\n\nexport interface IReadProviderSettingsOptions {\n providerOverride?: string;\n providerDefinitions?: readonly IProviderDefinition[];\n}\n\nexport function readMergedProviderSettings(cwd: string): TProviderSettingsDocument {\n return readMergedProviderSettingsFromPaths(getProviderSettingsPaths(cwd));\n}\n\nexport function readProviderSettings(\n cwd: string,\n options: IReadProviderSettingsOptions = {},\n): IProviderConfig {\n const merged = readMergedProviderSettings(cwd);\n const providerConfig = resolveActiveProvider(\n merged,\n options.providerOverride,\n options.providerDefinitions ?? [],\n );\n if (providerConfig !== undefined) {\n return providerConfig;\n }\n\n throw new Error('No provider configuration found. Run `robota` to set up.');\n}\n\nexport function createProviderFromSettings(\n cwd: string,\n modelOverride?: string,\n options: IReadProviderSettingsOptions = {},\n): IAIProvider {\n const providerDefinitions = options.providerDefinitions ?? [];\n const settings = readProviderSettings(cwd, { ...options, providerDefinitions });\n const model = modelOverride ?? settings.model;\n\n return createProviderFromConfig({ ...settings, model }, providerDefinitions);\n}\n","import type { ICommandSource, ICommand } from '../command-api/types.js';\nimport type { ILoadedBundlePlugin } from '../plugins/index.js';\n\n/**\n * Command source that discovers skills and commands from loaded BundlePlugins.\n *\n * - Skills: exposed as `/name` with `(plugin-name)` hint in description.\n * - Commands: exposed as `/plugin:command` (already namespaced by the loader).\n */\nexport class PluginCommandSource implements ICommandSource {\n readonly name = 'plugin';\n private readonly plugins: ILoadedBundlePlugin[];\n\n constructor(plugins: ILoadedBundlePlugin[]) {\n this.plugins = plugins;\n }\n\n getCommands(): ICommand[] {\n const commands: ICommand[] = [];\n\n for (const plugin of this.plugins) {\n // Skills: /name with (plugin-name) hint in description\n for (const skill of plugin.skills) {\n const baseName = skill.name.includes('@') ? skill.name.split('@')[0] : skill.name;\n commands.push({\n name: baseName,\n description: `(${plugin.manifest.name}) ${skill.description}`,\n source: 'plugin',\n skillContent: skill.skillContent,\n pluginDir: plugin.pluginDir,\n });\n }\n\n // Commands: /plugin:name (already namespaced by loader)\n for (const cmd of plugin.commands) {\n commands.push({\n name: cmd.name,\n description: cmd.description,\n source: 'plugin',\n skillContent: cmd.skillContent,\n pluginDir: plugin.pluginDir,\n });\n }\n }\n\n return commands;\n }\n}\n","import { AUTO_COMPACT_THRESHOLD } from '@robota-sdk/agent-session';\n\nimport type {\n IContextReferenceAddResult,\n IContextReferenceClearResult,\n IContextReferenceItem,\n IContextReferenceRemoveResult,\n} from '../../context/context-reference-inventory.js';\nimport type { ICommandSettingsAdapter, ICommandSettingsDocument } from '../host-adapters.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { TAutoCompactThresholdSource } from '../host-context.js';\nimport type { IContextWindowState } from '@robota-sdk/agent-core';\nexport type {\n IContextReferenceAddResult,\n IContextReferenceClearResult,\n IContextReferenceItem,\n IContextReferenceRemoveResult,\n} from '../../context/context-reference-inventory.js';\n\nexport type TAutoCompactThreshold = number | false;\n\nexport const DEFAULT_AUTO_COMPACT_THRESHOLD = AUTO_COMPACT_THRESHOLD;\nexport const AUTO_COMPACT_THRESHOLD_SETTINGS_KEY = 'autoCompactThreshold';\n\nexport interface ICompactContextResult {\n before: IContextWindowState;\n after: IContextWindowState;\n}\n\n/** Read context-window state through the command host facade. */\nexport function readCommandContextState(context: ICommandHostContext): IContextWindowState {\n return context.getContextState();\n}\n\n/** Read the effective automatic compact policy through the command host facade. */\nexport function readAutoCompactThreshold(context: ICommandHostContext): TAutoCompactThreshold {\n return context.getAutoCompactThreshold();\n}\n\n/** Read the source of the effective automatic compact policy. */\nexport function readAutoCompactThresholdSource(\n context: ICommandHostContext,\n): TAutoCompactThresholdSource {\n return context.getAutoCompactThresholdSource?.() ?? 'session';\n}\n\n/** Update the active session's automatic compact policy through the command host facade. */\nexport function setCommandAutoCompactThreshold(\n context: ICommandHostContext,\n threshold: TAutoCompactThreshold,\n source: TAutoCompactThresholdSource,\n): void {\n if (context.setAutoCompactThreshold) {\n context.setAutoCompactThreshold(threshold, source);\n return;\n }\n\n const session = context.getSession();\n if (!session.setAutoCompactThreshold) {\n throw new Error('Command host does not support changing auto-compact threshold.');\n }\n session.setAutoCompactThreshold(threshold);\n}\n\n/** Persist an automatic compact policy value through the host settings adapter, when present. */\nexport function writeAutoCompactThresholdSetting(\n context: ICommandHostContext,\n threshold: TAutoCompactThreshold,\n): boolean {\n const settings = getSettingsAdapter(context);\n if (!settings) return false;\n\n settings.write({\n ...settings.read(),\n [AUTO_COMPACT_THRESHOLD_SETTINGS_KEY]: threshold,\n });\n return true;\n}\n\n/** Remove the persisted automatic compact policy through the host settings adapter, when present. */\nexport function resetAutoCompactThresholdSetting(context: ICommandHostContext): boolean {\n const settings = getSettingsAdapter(context);\n if (!settings) return false;\n\n const next: ICommandSettingsDocument = { ...settings.read() };\n delete next[AUTO_COMPACT_THRESHOLD_SETTINGS_KEY];\n settings.write(next);\n return true;\n}\n\n/** Run manual compaction through the command host facade and return before/after state. */\nexport async function compactCommandContext(\n context: ICommandHostContext,\n instructions?: string,\n): Promise<ICompactContextResult> {\n const before = readCommandContextState(context);\n await context.compactContext(instructions);\n const after = readCommandContextState(context);\n return { before, after };\n}\n\n/** List context reference inventory entries through the command host facade. */\nexport function listCommandContextReferences(\n context: ICommandHostContext,\n): IContextReferenceItem[] {\n return context.listContextReferences?.() ?? [];\n}\n\n/** Add a manual context reference through the command host facade. */\nexport async function addCommandContextReference(\n context: ICommandHostContext,\n path: string,\n): Promise<IContextReferenceAddResult> {\n if (!context.addContextReference) {\n return {\n evicted: [],\n diagnostics: ['Command host does not support context reference additions.'],\n };\n }\n return context.addContextReference(path);\n}\n\n/** Remove a context reference through the command host facade. */\nexport function removeCommandContextReference(\n context: ICommandHostContext,\n path: string,\n): IContextReferenceRemoveResult {\n return context.removeContextReference?.(path) ?? {};\n}\n\n/** Clear all context references through the command host facade. */\nexport function clearCommandContextReferences(\n context: ICommandHostContext,\n): IContextReferenceClearResult {\n return context.clearContextReferences?.() ?? { removed: [] };\n}\n\nfunction getSettingsAdapter(\n context: ICommandHostContext,\n): ICommandSettingsAdapter<ICommandSettingsDocument> | undefined {\n return context.getCommandHostAdapters?.().settings;\n}\n","const FALLBACK_PROFILE_NAME = 'provider';\nconst FIRST_DUPLICATE_SUFFIX = 2;\n\nexport interface IProviderProfileNameSuggestionInput {\n type: string;\n}\n\nexport interface IProviderProfileNameSuggestionOptions {\n existingProfileNames?: readonly string[];\n}\n\nexport function suggestProviderProfileName(\n input: IProviderProfileNameSuggestionInput,\n options: IProviderProfileNameSuggestionOptions = {},\n): string {\n const baseName = sanitizeProviderProfileName(input.type) ?? FALLBACK_PROFILE_NAME;\n const existing = new Set(options.existingProfileNames ?? []);\n if (!existing.has(baseName)) {\n return baseName;\n }\n\n let suffix = FIRST_DUPLICATE_SUFFIX;\n while (existing.has(`${baseName}-${suffix}`)) {\n suffix += 1;\n }\n return `${baseName}-${suffix}`;\n}\n\nexport function sanitizeProviderProfileName(value: string | undefined): string | undefined {\n const normalized = value\n ?.trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return normalized !== undefined && normalized.length > 0 ? normalized : undefined;\n}\n","import type { ICommandHostContext, ICommandListEntry } from '../host-context.js';\n\nexport const HELP_COMMAND_DESCRIPTION = 'Show available commands';\nconst HELP_COMMAND_NAME_COLUMN_WIDTH = 16;\n\nfunction readCommandList(context: ICommandHostContext): readonly ICommandListEntry[] {\n return context.listCommands?.() ?? [];\n}\n\nexport function formatCommandHelpMessage(context: ICommandHostContext): string {\n const commands = readCommandList(context);\n return [\n 'Available commands:',\n ...commands.map((command) => {\n const displayLabel = command.displayName ?? command.name;\n const invocation = `/${command.name}`;\n const label = command.displayName ? `${displayLabel} (${invocation})` : invocation;\n return ` ${label.padEnd(HELP_COMMAND_NAME_COLUMN_WIDTH * 2)} — ${command.description}`;\n }),\n ].join('\\n');\n}\n","import type {\n IBackgroundTaskListFilter,\n IBackgroundTaskLogCursor,\n IBackgroundTaskLogPage,\n IBackgroundTaskState,\n} from '../../background-tasks/index.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { ICommand } from '../types.js';\n\nconst DECIMAL_RADIX = 10;\nconst INLINE_METADATA_LIMIT = 160;\n\nexport const BACKGROUND_COMMAND_DESCRIPTION = 'List and control background tasks';\nexport const BACKGROUND_COMMAND_USAGE =\n 'Usage: background list | background read <task-id> [offset] | background cancel <task-id> | background close <task-id>';\n\nexport function buildBackgroundCommandSubcommands(): ICommand[] {\n return [\n { name: 'list', description: 'List background tasks', source: 'background' },\n { name: 'read', description: 'Read a background task log page', source: 'background' },\n { name: 'cancel', description: 'Cancel a running background task', source: 'background' },\n { name: 'close', description: 'Dismiss a terminal background task', source: 'background' },\n ];\n}\n\nexport function formatCommandBackgroundTask(task: IBackgroundTaskState): string {\n const preview = task.promptPreview ?? task.commandPreview ?? '';\n const unread = task.unread ? ' unread' : '';\n const action = task.currentAction ? ` (${task.currentAction})` : '';\n const timeout = task.timeoutReason ? ` timeout=${task.timeoutReason}` : '';\n const activity = task.lastActivityAt ? ` lastActivityAt=${task.lastActivityAt}` : '';\n const worktree = formatWorktreeMetadata(task);\n const suffix = preview ? ` — ${preview}` : '';\n return `${task.id} [${task.status}${unread}${timeout}${activity}${worktree}] ${task.kind}:${task.label}${action}${suffix}`;\n}\n\nexport function formatCommandBackgroundTaskList(tasks: IBackgroundTaskState[]): string {\n if (tasks.length === 0) return 'No background tasks.';\n return [\n 'Background tasks:',\n ...tasks.map((task) => ` ${formatCommandBackgroundTask(task)}`),\n ].join('\\n');\n}\n\nexport function parseCommandBackgroundLogCursor(\n value?: string,\n): IBackgroundTaskLogCursor | undefined {\n if (!value) return undefined;\n const offset = Number.parseInt(value, DECIMAL_RADIX);\n return Number.isNaN(offset) ? undefined : { offset };\n}\n\nfunction formatWorktreeMetadata(task: IBackgroundTaskState): string {\n const segments: string[] = [];\n if (task.worktreePath) segments.push(`worktree=${task.worktreePath}`);\n if (task.branchName) segments.push(`branch=${task.branchName}`);\n if (task.worktreeStatus) {\n segments.push(`worktreeStatus=\"${formatInlineMetadata(task.worktreeStatus)}\"`);\n }\n if (task.worktreeNextAction) {\n segments.push(`next=\"${formatInlineMetadata(task.worktreeNextAction)}\"`);\n }\n if (segments.length === 0) return '';\n return ` ${segments.join(' ')}`;\n}\n\nfunction formatInlineMetadata(value: string): string {\n const normalized = value.trim().replace(/\\s+/g, ' ');\n return normalized.length > INLINE_METADATA_LIMIT\n ? `${normalized.slice(0, INLINE_METADATA_LIMIT)}...`\n : normalized;\n}\n\nexport function listCommandBackgroundTasks(\n context: ICommandHostContext,\n filter?: IBackgroundTaskListFilter,\n): IBackgroundTaskState[] {\n return context.listBackgroundTasks(filter);\n}\n\nexport function readCommandBackgroundTaskLog(\n context: ICommandHostContext,\n taskId: string,\n cursor?: IBackgroundTaskLogCursor,\n): Promise<IBackgroundTaskLogPage> {\n return context.readBackgroundTaskLog(taskId, cursor);\n}\n\nexport function cancelCommandBackgroundTask(\n context: ICommandHostContext,\n taskId: string,\n reason?: string,\n): Promise<void> {\n return context.cancelBackgroundTask(taskId, reason);\n}\n\nexport function closeCommandBackgroundTask(\n context: ICommandHostContext,\n taskId: string,\n): Promise<void> {\n return context.closeBackgroundTask(taskId);\n}\n","import {\n CLAUDE_MODELS,\n findProviderDefinition,\n formatTokenCount,\n type IProviderDefinition,\n type IProviderModelCatalog,\n type IProviderModelCatalogEntry,\n type IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\nimport { resolveEnvReference } from '@robota-sdk/agent-core';\n\nimport type { TProviderSettingsDocument } from '../provider/provider-settings.js';\nimport type { ICommand } from '../types.js';\n\nexport const MODEL_COMMAND_DESCRIPTION = 'Change AI model';\nexport const MODEL_COMMAND_ARGUMENT_HINT = '<model-id>';\n\nexport interface IModelCommandSettingsAdapter {\n readMergedSettings(): TProviderSettingsDocument;\n}\n\nexport interface IModelCommandModuleOptions {\n providerDefinitions: readonly IProviderDefinition[];\n settings: IModelCommandSettingsAdapter;\n}\n\nexport interface IBuildModelCommandSubcommandsOptions {\n source?: string;\n providerDefinitions?: readonly IProviderDefinition[];\n settings?: TProviderSettingsDocument;\n}\n\nexport interface IActiveProviderModelCatalogState {\n providerType: string;\n catalog?: IProviderModelCatalog;\n refreshAttempted: boolean;\n refreshMessage?: string;\n}\n\nexport interface IResolveActiveProviderModelCatalogStateOptions {\n settings?: TProviderSettingsDocument;\n providerDefinitions?: readonly IProviderDefinition[];\n refresh?: boolean;\n}\n\nexport function buildModelCommandSubcommands(\n sourceOrOptions: string | IBuildModelCommandSubcommandsOptions = 'model',\n): ICommand[] {\n const options =\n typeof sourceOrOptions === 'string' ? { source: sourceOrOptions } : sourceOrOptions;\n const source = options.source ?? 'model';\n const catalog = resolveActiveProviderModelCatalog(options.settings, options.providerDefinitions);\n if (catalog !== undefined) {\n return buildCatalogSubcommands(catalog, source);\n }\n if (options.settings !== undefined) {\n return [];\n }\n return buildClaudeModelSubcommands(source);\n}\n\nexport function formatModelCommandUsageMessage(\n options: {\n settings?: TProviderSettingsDocument;\n providerDefinitions?: readonly IProviderDefinition[];\n } = {},\n): string {\n const snapshot = resolveActiveProviderModelCatalogSnapshot(\n options.settings,\n options.providerDefinitions,\n );\n return formatModelUsageMessage(snapshot === undefined ? undefined : toCatalogState(snapshot));\n}\n\nexport async function formatModelCommandUsageMessageAsync(\n options: IResolveActiveProviderModelCatalogStateOptions = {},\n): Promise<string> {\n return formatModelUsageMessage(await resolveActiveProviderModelCatalogState(options));\n}\n\nexport function resolveActiveProviderModelCatalog(\n settings: TProviderSettingsDocument | undefined,\n providerDefinitions: readonly IProviderDefinition[] = [],\n): IProviderModelCatalog | undefined {\n return resolveActiveProviderModelCatalogSnapshot(settings, providerDefinitions)?.catalog;\n}\n\nexport async function resolveActiveProviderModelCatalogState(\n options: IResolveActiveProviderModelCatalogStateOptions,\n): Promise<IActiveProviderModelCatalogState | undefined> {\n const snapshot = resolveActiveProviderModelCatalogSnapshot(\n options.settings,\n options.providerDefinitions,\n );\n if (snapshot === undefined) return undefined;\n const shouldRefresh =\n options.refresh === true ||\n isCatalogStale(snapshot.catalog, snapshot.definition?.modelCatalogCacheTtlSeconds);\n if (!shouldRefresh || snapshot.definition?.refreshModelCatalog === undefined) {\n return toCatalogState(snapshot);\n }\n\n try {\n const refreshed = await snapshot.definition.refreshModelCatalog({\n profile: resolveRefreshProfile(snapshot),\n });\n if (refreshed.status !== 'unavailable') {\n return {\n providerType: snapshot.providerType,\n catalog: refreshed,\n refreshAttempted: true,\n };\n }\n return {\n providerType: snapshot.providerType,\n catalog: snapshot.catalog ?? refreshed,\n refreshAttempted: true,\n ...(refreshed.message !== undefined ? { refreshMessage: refreshed.message } : {}),\n };\n } catch (error) {\n return {\n providerType: snapshot.providerType,\n ...(snapshot.catalog !== undefined ? { catalog: snapshot.catalog } : {}),\n refreshAttempted: true,\n refreshMessage: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nfunction buildClaudeModelSubcommands(source: string): ICommand[] {\n const seen = new Set<string>();\n const commands: ICommand[] = [];\n for (const model of Object.values(CLAUDE_MODELS)) {\n if (seen.has(model.name)) continue;\n seen.add(model.name);\n commands.push({\n name: model.id,\n description: `${model.name} (${formatTokenCount(model.contextWindow).toUpperCase()})`,\n source,\n });\n }\n return commands;\n}\n\nfunction buildCatalogSubcommands(catalog: IProviderModelCatalog, source: string): ICommand[] {\n return (catalog.entries ?? [])\n .filter((entry) => entry.lifecycle !== 'unavailable')\n .map((entry) => ({\n name: entry.id,\n description: formatCatalogEntryDescription(entry),\n source,\n }));\n}\n\nfunction formatCatalogEntryDescription(entry: IProviderModelCatalogEntry): string {\n if (entry.contextWindow === undefined) {\n return entry.displayName;\n }\n return `${entry.displayName} (${formatTokenCount(entry.contextWindow).toUpperCase()})`;\n}\n\ninterface IActiveProviderModelCatalogSnapshot {\n providerType: string;\n profile?: IProviderProfileConfig;\n definition?: IProviderDefinition;\n catalog?: IProviderModelCatalog;\n}\n\nfunction resolveActiveProviderModelCatalogSnapshot(\n settings: TProviderSettingsDocument | undefined,\n providerDefinitions: readonly IProviderDefinition[] = [],\n): IActiveProviderModelCatalogSnapshot | undefined {\n const profile = resolveActiveProviderProfile(settings);\n const providerType = profile?.type ?? profile?.name;\n if (providerType === undefined) {\n return undefined;\n }\n const definition = findProviderDefinition(providerDefinitions, providerType);\n return {\n providerType,\n ...(profile !== undefined ? { profile } : {}),\n ...(definition !== undefined ? { definition } : {}),\n ...(definition?.modelCatalog !== undefined ? { catalog: definition.modelCatalog } : {}),\n };\n}\n\nfunction resolveActiveProviderProfile(\n settings: TProviderSettingsDocument | undefined,\n): (IProviderProfileConfig & { name?: string }) | undefined {\n if (settings?.currentProvider !== undefined) {\n return settings.providers?.[settings.currentProvider];\n }\n return settings?.provider;\n}\n\nfunction toCatalogState(\n snapshot: IActiveProviderModelCatalogSnapshot,\n): IActiveProviderModelCatalogState {\n return {\n providerType: snapshot.providerType,\n ...(snapshot.catalog !== undefined ? { catalog: snapshot.catalog } : {}),\n refreshAttempted: false,\n };\n}\n\nfunction isCatalogStale(\n catalog: IProviderModelCatalog | undefined,\n ttlSeconds: number | undefined,\n): boolean {\n if (catalog === undefined || ttlSeconds === undefined || catalog.lastVerifiedAt === undefined) {\n return false;\n }\n const ageMs = Date.now() - new Date(catalog.lastVerifiedAt).getTime();\n return ageMs > ttlSeconds * 1000;\n}\n\nfunction resolveRefreshProfile(\n snapshot: IActiveProviderModelCatalogSnapshot,\n): IProviderProfileConfig {\n const profile = snapshot.profile;\n const defaults = snapshot.definition?.defaults;\n const apiKey = resolveOptionalEnvReference(profile?.apiKey ?? defaults?.apiKey);\n const model = resolveProfileValue(profile?.model, defaults?.model);\n const baseURL = resolveProfileValue(profile?.baseURL, defaults?.baseURL);\n const timeout = resolveProfileValue(profile?.timeout, defaults?.timeout);\n const options = resolveProfileValue(profile?.options, defaults?.options);\n const refreshProfile: IProviderProfileConfig = {\n type: profile?.type ?? snapshot.providerType,\n };\n\n if (model !== undefined) refreshProfile.model = model;\n if (apiKey !== undefined) refreshProfile.apiKey = apiKey;\n if (baseURL !== undefined) refreshProfile.baseURL = baseURL;\n if (timeout !== undefined) refreshProfile.timeout = timeout;\n if (options !== undefined) refreshProfile.options = options;\n return refreshProfile;\n}\n\nfunction resolveProfileValue<T>(\n profileValue: T | undefined,\n defaultValue: T | undefined,\n): T | undefined {\n return profileValue ?? defaultValue;\n}\n\nfunction resolveOptionalEnvReference(value: string | undefined): string | undefined {\n return value === undefined ? undefined : resolveEnvReference(value);\n}\n\nfunction formatModelUsageMessage(active: IActiveProviderModelCatalogState | undefined): string {\n const base =\n active?.providerType !== undefined &&\n (active.catalog?.entries === undefined || active.catalog.entries.length === 0)\n ? `No model catalog available for provider ${active.providerType}. Usage: model <model-id>`\n : 'Usage: model <model-id>';\n const freshness = formatCatalogFreshness(active);\n return freshness === undefined ? base : `${base}\\n${freshness}`;\n}\n\nfunction formatCatalogFreshness(\n active: IActiveProviderModelCatalogState | undefined,\n): string | undefined {\n const catalog = active?.catalog;\n if (catalog === undefined) return undefined;\n\n const parts = [`Catalog: ${catalog.status}`];\n if (catalog.entries !== undefined) {\n parts.push(`${catalog.entries.length} model(s)`);\n }\n if (catalog.lastVerifiedAt !== undefined) {\n parts.push(`verified ${catalog.lastVerifiedAt}`);\n }\n if (catalog.sourceUrl !== undefined) {\n parts.push(`source ${catalog.sourceUrl}`);\n }\n const refreshMessage = active?.refreshMessage;\n if (refreshMessage !== undefined) {\n parts.push(`refresh ${refreshMessage}`);\n } else if (catalog.message !== undefined) {\n parts.push(catalog.message);\n }\n return parts.join('; ');\n}\n","import type { ICommand } from '../types.js';\n\nexport const LANGUAGE_COMMAND_DESCRIPTION = 'Set response language';\nexport const LANGUAGE_COMMAND_ARGUMENT_HINT = '<code>';\n\nexport const RECOMMENDED_RESPONSE_LANGUAGES = [\n { code: 'ko', description: 'Korean' },\n { code: 'en', description: 'English' },\n { code: 'ja', description: 'Japanese' },\n { code: 'zh', description: 'Chinese' },\n] as const;\n\nexport type TRecommendedResponseLanguage = (typeof RECOMMENDED_RESPONSE_LANGUAGES)[number]['code'];\n\nexport function buildLanguageCommandSubcommands(source = 'language'): ICommand[] {\n return RECOMMENDED_RESPONSE_LANGUAGES.map((language) => ({\n name: language.code,\n description: language.description,\n source,\n }));\n}\n\nexport function parseLanguageArgument(args: string): string | undefined {\n const language = args.trim().split(/\\s+/)[0];\n return language !== undefined && language.length > 0 ? language : undefined;\n}\n\nexport function formatLanguageUsageMessage(commandName = 'language'): string {\n return `Usage: ${commandName} <code> (e.g., ko, en, ja, zh)`;\n}\n","import type { ICommandPermissionModeAdapter } from '../host-adapters.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { ICommand } from '../types.js';\nimport type { TPermissionMode } from '@robota-sdk/agent-core';\n\nexport const PERMISSION_MODE_COMMAND_DESCRIPTION = 'Show/change permission mode';\nexport const PERMISSION_MODE_ARGUMENT_HINT = 'plan | default | acceptEdits | bypassPermissions';\nexport const PERMISSIONS_COMMAND_DESCRIPTION = 'Show/change permission mode and permission rules';\n\nexport interface IPermissionsCommandState {\n readonly mode: TPermissionMode;\n readonly sessionAllowed: readonly string[];\n}\nexport const VALID_PERMISSION_MODES: readonly TPermissionMode[] = [\n 'plan',\n 'default',\n 'acceptEdits',\n 'bypassPermissions',\n];\n\nexport function buildPermissionModeSubcommands(source = 'mode'): ICommand[] {\n return [\n { name: 'plan', description: 'Plan only, no execution', source },\n { name: 'default', description: 'Ask before risky actions', source },\n { name: 'acceptEdits', description: 'Auto-approve file edits', source },\n { name: 'bypassPermissions', description: 'Skip all permission checks', source },\n ];\n}\n\nexport function parsePermissionModeArgument(args: string): string | undefined {\n const mode = args.trim().split(/\\s+/)[0];\n return mode !== undefined && mode.length > 0 ? mode : undefined;\n}\n\nexport function isPermissionMode(value: string): value is TPermissionMode {\n return (VALID_PERMISSION_MODES as readonly string[]).includes(value);\n}\n\nexport function formatInvalidPermissionModeMessage(): string {\n return `Invalid mode. Valid: ${VALID_PERMISSION_MODES.join(' | ')}`;\n}\n\nexport function resolvePermissionModeAdapter(\n context: ICommandHostContext,\n): ICommandPermissionModeAdapter {\n const adapter = context.getCommandHostAdapters?.().permissionMode;\n if (adapter !== undefined) {\n return adapter;\n }\n\n const runtime = context.getSession();\n return {\n getPermissionMode: () => runtime.getPermissionMode(),\n setPermissionMode: (mode) => runtime.setPermissionMode(mode),\n listSessionAllowedTools: () => runtime.getSessionAllowedTools(),\n };\n}\n\nexport function readCommandPermissionMode(context: ICommandHostContext): TPermissionMode {\n return resolvePermissionModeAdapter(context).getPermissionMode();\n}\n\nexport function writeCommandPermissionMode(\n context: ICommandHostContext,\n mode: TPermissionMode,\n): void {\n resolvePermissionModeAdapter(context).setPermissionMode(mode);\n}\n\nexport function listCommandSessionAllowedTools(context: ICommandHostContext): readonly string[] {\n return resolvePermissionModeAdapter(context).listSessionAllowedTools();\n}\n\nexport function readCommandPermissionsState(\n context: ICommandHostContext,\n): IPermissionsCommandState {\n return {\n mode: readCommandPermissionMode(context),\n sessionAllowed: listCommandSessionAllowedTools(context),\n };\n}\n\nexport function formatCommandPermissionsMessage(state: IPermissionsCommandState): string {\n const lines = [`Permission mode: ${state.mode}`];\n if (state.sessionAllowed.length > 0) {\n lines.push(`Session-approved tools: ${state.sessionAllowed.join(', ')}`);\n } else {\n lines.push('No session-approved tools.');\n }\n return lines.join('\\n');\n}\n","import { readSettings, writeSettings } from '../../config/settings-io.js';\n\nimport type { TSettingsData } from '../../config/settings-io.js';\nimport type { ICommand } from '../types.js';\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\n\nexport const STATUSLINE_COMMAND_DESCRIPTION =\n 'Configure TUI status-line visibility and fields such as model, context, tokens, session, and git branch.';\nexport const STATUSLINE_COMMAND_ARGUMENT_HINT = 'on | off | reset | git on | git off';\n\nexport interface IStatusLineCommandSettings {\n enabled: boolean;\n gitBranch: boolean;\n}\n\nexport type TStatusLineCommandSettingsPatch = Partial<IStatusLineCommandSettings> &\n Record<string, TUniversalValue>;\n\nexport const DEFAULT_STATUS_LINE_COMMAND_SETTINGS: Readonly<IStatusLineCommandSettings> = {\n enabled: true,\n gitBranch: true,\n};\n\nexport function buildStatusLineCommandSubcommands(source = 'statusline'): ICommand[] {\n return [\n { name: 'on', description: 'Show the status line', source },\n { name: 'off', description: 'Hide the status line', source },\n { name: 'reset', description: 'Restore default status-line fields', source },\n { name: 'git', description: 'Show or hide git branch field', source },\n ];\n}\n\nexport function isStatusLineCommandSettingsPatch(\n value: Record<string, TUniversalValue>,\n): value is TStatusLineCommandSettingsPatch {\n return (\n (value.enabled === undefined || typeof value.enabled === 'boolean') &&\n (value.gitBranch === undefined || typeof value.gitBranch === 'boolean')\n );\n}\n\nexport function readStatusLineSettings(settings: TSettingsData): IStatusLineCommandSettings {\n const raw = settings.statusline;\n if (!isRecord(raw)) {\n return { ...DEFAULT_STATUS_LINE_COMMAND_SETTINGS };\n }\n return {\n enabled:\n typeof raw.enabled === 'boolean' ? raw.enabled : DEFAULT_STATUS_LINE_COMMAND_SETTINGS.enabled,\n gitBranch:\n typeof raw.gitBranch === 'boolean'\n ? raw.gitBranch\n : DEFAULT_STATUS_LINE_COMMAND_SETTINGS.gitBranch,\n };\n}\n\nexport function applyStatusLineSettings(\n settingsPath: string,\n patch: TStatusLineCommandSettingsPatch,\n): IStatusLineCommandSettings {\n const settings = readSettings(settingsPath);\n const next = {\n ...readStatusLineSettings(settings),\n ...patch,\n };\n settings.statusline = next as TSettingsData;\n writeSettings(settingsPath, settings);\n return next;\n}\n\nfunction isRecord(value: TUniversalValue): value is Record<string, TUniversalValue> {\n return (\n value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)\n );\n}\n","import type { TCommandEffect } from '../effects.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { ICommand } from '../types.js';\n\nexport const PLUGIN_COMMAND_DESCRIPTION = 'Manage plugins';\nexport const PLUGIN_COMMAND_ARGUMENT_HINT =\n 'manage | install <name@marketplace> | uninstall <name@marketplace> | enable <name@marketplace> | disable <name@marketplace> | marketplace <action>';\nexport const RELOAD_PLUGINS_COMMAND_DESCRIPTION = 'Reload all plugin resources';\n\nexport type TPluginInstallScope = 'user' | 'project';\n\nexport interface ICommandInstalledPlugin {\n name: string;\n description: string;\n enabled: boolean;\n}\n\nexport interface ICommandAvailablePlugin {\n name: string;\n description: string;\n installed: boolean;\n}\n\nexport interface ICommandMarketplaceSource {\n name: string;\n type: string;\n}\n\nexport interface ICommandPluginReloadResult {\n loadedPluginCount: number;\n}\n\nexport interface ICommandPluginAdapter {\n listInstalled(): Promise<readonly ICommandInstalledPlugin[]>;\n listAvailablePlugins(marketplace: string): Promise<readonly ICommandAvailablePlugin[]>;\n install(pluginId: string, scope?: TPluginInstallScope): Promise<void>;\n uninstall(pluginId: string): Promise<void>;\n enable(pluginId: string): Promise<void>;\n disable(pluginId: string): Promise<void>;\n marketplaceAdd(source: string): Promise<string>;\n marketplaceRemove(name: string): Promise<void>;\n marketplaceUpdate(name: string): Promise<void>;\n marketplaceList(): Promise<readonly ICommandMarketplaceSource[]>;\n reloadPlugins(): Promise<ICommandPluginReloadResult>;\n}\n\nexport function createPluginTuiRequestedEffect(): TCommandEffect {\n return { type: 'plugin-tui-requested' };\n}\n\nexport function createPluginRegistryReloadRequestedEffect(): TCommandEffect {\n return { type: 'plugin-registry-reload-requested' };\n}\n\nexport function resolvePluginCommandAdapter(\n context: ICommandHostContext,\n): ICommandPluginAdapter | undefined {\n return context.getCommandHostAdapters?.().plugin;\n}\n\nexport function buildPluginCommandSubcommands(): ICommand[] {\n return [\n { name: 'manage', description: 'Open plugin manager', source: 'plugin-manager' },\n { name: 'install', description: 'Install a plugin', source: 'plugin-manager' },\n { name: 'uninstall', description: 'Uninstall a plugin', source: 'plugin-manager' },\n { name: 'enable', description: 'Enable a plugin', source: 'plugin-manager' },\n { name: 'disable', description: 'Disable a plugin', source: 'plugin-manager' },\n {\n name: 'marketplace',\n description: 'Manage plugin marketplaces',\n source: 'plugin-manager',\n subcommands: [\n { name: 'add', description: 'Add marketplace source', source: 'plugin-manager' },\n { name: 'remove', description: 'Remove marketplace source', source: 'plugin-manager' },\n { name: 'update', description: 'Update marketplace source', source: 'plugin-manager' },\n { name: 'list', description: 'List marketplace sources', source: 'plugin-manager' },\n ],\n },\n ];\n}\n","import { join } from 'node:path';\n\nimport { loadSessionLogEntries, validateSessionReplayLogEntries } from '@robota-sdk/agent-session';\n\nimport { projectPaths } from '../../paths.js';\n\nimport type { TCommandEffect } from '../effects.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { ICommandSessionReplayValidationReport } from '../host-context.js';\n\nexport const CLEAR_COMMAND_DESCRIPTION = 'Clear conversation history';\nexport const RENAME_COMMAND_DESCRIPTION = 'Rename the current session';\nexport const RENAME_COMMAND_USAGE = 'Usage: rename <name>';\nexport const RESUME_COMMAND_DESCRIPTION = 'Resume a previous session';\nexport const COST_COMMAND_DESCRIPTION = 'Show session info';\nexport const VALIDATE_SESSION_COMMAND_DESCRIPTION = 'Validate current session replay log';\nexport const EXIT_COMMAND_DESCRIPTION = 'Exit CLI';\n\nexport interface ICommandSessionInfo {\n sessionId: string;\n messageCount: number;\n}\n\nexport function clearConversationHistory(context: ICommandHostContext): void {\n if (context.clearConversationHistory !== undefined) {\n context.clearConversationHistory();\n return;\n }\n\n context.getSession().clearHistory();\n}\n\nexport function parseSessionNameArgument(args: string): string | undefined {\n const name = args.trim();\n return name.length > 0 ? name : undefined;\n}\n\nexport function createSessionRenamedEffect(name: string): TCommandEffect {\n return { type: 'session-renamed', name };\n}\n\nexport function createSessionPickerRequestedEffect(): TCommandEffect {\n return { type: 'session-picker-requested' };\n}\n\nexport function createSessionExitRequestedEffect(): TCommandEffect {\n return { type: 'session-exit-requested' };\n}\n\nexport function readCommandSessionInfo(context: ICommandHostContext): ICommandSessionInfo {\n const session = context.getSession();\n return {\n sessionId: session.getSessionId(),\n messageCount: session.getMessageCount(),\n };\n}\n\nexport function validateCommandSessionReplayLog(\n context: ICommandHostContext,\n): ICommandSessionReplayValidationReport {\n const hostReport = context.validateCurrentSessionReplayLog?.();\n if (hostReport !== undefined) {\n return hostReport;\n }\n\n const sessionId = context.getSession().getSessionId();\n const logFile = join(projectPaths(context.getCwd()).logs, `${sessionId}.jsonl`);\n const entries = loadSessionLogEntries(logFile);\n return {\n logFile,\n entryCount: entries.length,\n validation: validateSessionReplayLogEntries(entries),\n };\n}\n\nexport function formatCommandSessionReplayValidationReport(\n report: ICommandSessionReplayValidationReport,\n): string {\n const header = report.validation.ok\n ? 'Session replay log is valid.'\n : `Session replay log has ${report.validation.issues.length} issue(s).`;\n const details = [`Log: ${report.logFile}`, `Entries: ${report.entryCount}`];\n if (report.validation.ok) {\n return [header, ...details].join('\\n');\n }\n\n const issueLines = report.validation.issues.map((issue, index) => {\n const location = formatReplayValidationIssueLocation(issue);\n return `${index + 1}. ${issue.code}${location}: ${issue.message}`;\n });\n return [header, ...details, '', ...issueLines].join('\\n');\n}\n\nfunction formatReplayValidationIssueLocation(\n issue: ICommandSessionReplayValidationReport['validation']['issues'][number],\n): string {\n const parts: string[] = [];\n if (issue.executionId !== undefined) {\n parts.push(`execution=${issue.executionId}`);\n }\n if (issue.round !== undefined) {\n parts.push(`round=${issue.round}`);\n }\n if (issue.toolCallId !== undefined) {\n parts.push(`tool=${issue.toolCallId}`);\n }\n return parts.length > 0 ? ` (${parts.join(', ')})` : '';\n}\n\nexport type { ICommandSessionReplayValidationReport };\n","import type {\n IEditCheckpointInspection,\n IEditCheckpointRestoreResult,\n IEditCheckpointSummary,\n} from '../../checkpoints/index.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { ICommand } from '../types.js';\n\nexport const REWIND_COMMAND_DESCRIPTION = 'List, inspect, restore, or rollback edit checkpoints.';\nexport const REWIND_COMMAND_ARGUMENT_HINT =\n 'list | inspect CHECKPOINT_ID | restore CHECKPOINT_ID | code CHECKPOINT_ID | rollback CHECKPOINT_ID';\n\nexport function buildRewindCommandSubcommands(source = 'rewind'): ICommand[] {\n return [\n { name: 'list', description: 'List edit checkpoints', source },\n { name: 'inspect', description: 'Inspect captured files and restore plans', source },\n { name: 'restore', description: 'Restore code to a checkpoint', source },\n { name: 'code', description: 'Restore code to a checkpoint', source },\n { name: 'rollback', description: 'Rollback code through a checkpoint', source },\n ];\n}\n\nexport function listCommandEditCheckpoints(\n context: ICommandHostContext,\n): readonly IEditCheckpointSummary[] {\n return context.listEditCheckpoints();\n}\n\nexport function inspectCommandEditCheckpoint(\n context: ICommandHostContext,\n checkpointId: string,\n): IEditCheckpointInspection {\n if (!context.inspectEditCheckpoint) {\n throw new Error('Checkpoint inspection is not available in this command host.');\n }\n return context.inspectEditCheckpoint(checkpointId);\n}\n\nexport function restoreCommandEditCheckpoint(\n context: ICommandHostContext,\n checkpointId: string,\n): Promise<IEditCheckpointRestoreResult> {\n return context.restoreEditCheckpoint(checkpointId);\n}\n\nexport function rollbackCommandEditCheckpoint(\n context: ICommandHostContext,\n checkpointId: string,\n): Promise<IEditCheckpointRestoreResult> {\n return context.rollbackEditCheckpoint(checkpointId);\n}\n","import type {\n IAutomaticMemoryConfig,\n IMemoryCandidate,\n IMemoryDecision,\n} from './automatic-memory-types.js';\n\nconst AUTO_SAVE_CONFIDENCE_THRESHOLD = 0.85;\nconst SENSITIVE_PATTERNS: readonly RegExp[] = [\n /\\b(api[_-]?key|secret|token|password|private key)\\b/i,\n /\\b\\d{3}-\\d{2}-\\d{4}\\b/,\n /\\b\\d{4}[- ]?\\d{4}[- ]?\\d{4}[- ]?\\d{4}\\b/,\n /주민등록|비밀번호|시크릿|토큰/u,\n];\n\nexport function containsSensitiveMemoryContent(text: string): boolean {\n return SENSITIVE_PATTERNS.some((pattern) => pattern.test(text));\n}\n\nexport class MemoryPolicyEvaluator {\n evaluate(candidate: IMemoryCandidate, config: IAutomaticMemoryConfig): IMemoryDecision {\n if (config.policy === 'disabled') {\n return { action: 'skip', reason: 'memory-policy-disabled' };\n }\n\n if (containsSensitiveMemoryContent(candidate.text)) {\n return { action: 'skip', reason: 'sensitive-content' };\n }\n\n if (config.policy === 'approval_required') {\n return { action: 'queue', reason: 'approval-required' };\n }\n\n if (candidate.confidence >= AUTO_SAVE_CONFIDENCE_THRESHOLD) {\n return { action: 'save', reason: 'high-confidence-auto-save' };\n }\n\n return { action: 'queue', reason: 'low-confidence-auto-save-review' };\n }\n}\n","import { dirname, join } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type {\n IMemoryCandidate,\n IMemoryPendingRecord,\n TMemoryCandidateStatus,\n} from './automatic-memory-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\ninterface IPendingMemoryDocument {\n version: 1;\n records: IMemoryPendingRecord[];\n}\n\nconst PENDING_FILENAME = 'pending.json';\n\nfunction memoryRoot(cwd: string): string {\n return join(cwd, '.robota', 'memory');\n}\n\nfunction emptyDocument(): IPendingMemoryDocument {\n return { version: 1, records: [] };\n}\n\nexport class PendingMemoryStore {\n private readonly path: string;\n private readonly now: () => Date;\n\n constructor(\n cwd: string,\n now: () => Date = () => new Date(),\n private readonly fs: IFileSystem = new NodeFileSystem(),\n ) {\n this.path = join(memoryRoot(cwd), PENDING_FILENAME);\n this.now = now;\n }\n\n getPath(): string {\n return this.path;\n }\n\n list(status?: TMemoryCandidateStatus): IMemoryPendingRecord[] {\n const records = this.read().records;\n return status ? records.filter((record) => record.status === status) : records;\n }\n\n get(id: string): IMemoryPendingRecord | undefined {\n return this.read().records.find((record) => record.id === id);\n }\n\n upsert(candidate: IMemoryCandidate, status: TMemoryCandidateStatus, reason: string): void {\n const document = this.read();\n const updatedAt = this.now().toISOString();\n const existingIndex = document.records.findIndex((record) => record.id === candidate.id);\n const record: IMemoryPendingRecord = {\n ...candidate,\n status,\n updatedAt,\n decisionReason: reason,\n };\n if (existingIndex >= 0) {\n document.records[existingIndex] = { ...document.records[existingIndex], ...record };\n } else {\n document.records.push(record);\n }\n this.write(document);\n }\n\n mark(id: string, status: TMemoryCandidateStatus, reason: string): IMemoryPendingRecord {\n const document = this.read();\n const index = document.records.findIndex((record) => record.id === id);\n if (index < 0) throw new Error(`Memory candidate not found: ${id}`);\n const record = {\n ...document.records[index],\n status,\n updatedAt: this.now().toISOString(),\n decisionReason: reason,\n };\n document.records[index] = record;\n this.write(document);\n return record;\n }\n\n private read(): IPendingMemoryDocument {\n if (!this.fs.existsSync(this.path)) return emptyDocument();\n try {\n const parsed = JSON.parse(this.fs.readFileSync(this.path, 'utf8')) as IPendingMemoryDocument;\n return { version: 1, records: parsed.records ?? [] };\n } catch {\n // allow-fallback: corrupt JSON treated as empty document\n return emptyDocument();\n }\n }\n\n private write(document: IPendingMemoryDocument): void {\n this.fs.mkdirSync(dirname(this.path), { recursive: true });\n this.fs.writeFileSync(this.path, JSON.stringify(document, null, 2), 'utf8');\n }\n}\n","import { containsSensitiveMemoryContent } from '../../memory/memory-policy-evaluator.js';\nimport { PendingMemoryStore } from '../../memory/pending-memory-store.js';\nimport {\n ProjectMemoryStore,\n isMemoryType,\n type IAppendMemoryInput,\n type IAppendMemoryResult,\n type IProjectMemorySummary,\n type IStartupMemory,\n type TMemoryType,\n} from '../../memory/project-memory-store.js';\n\nimport type {\n IMemoryCandidate,\n IMemoryEvent,\n IMemoryPendingRecord,\n IMemoryReference,\n TMemoryCandidateStatus,\n} from '../../memory/automatic-memory-types.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { ICommand } from '../types.js';\n\nexport const MEMORY_COMMAND_DESCRIPTION =\n 'Project memory command. Use it to inspect project memory when stored context may help, save durable preferences, project conventions, feedback, or references worth reusing across sessions, review pending candidates, and report memory provenance. Do not store secrets, credentials, or transient facts.';\nexport const MEMORY_COMMAND_ARGUMENT_HINT =\n 'list | show [topic] | add <user|feedback|project|reference> <topic> <text> | pending | approve <id> | reject <id> | used';\nexport const MEMORY_COMMAND_USAGE =\n 'Usage: memory list | memory show [topic] | memory add <user|feedback|project|reference> <topic> <text> | memory pending | memory approve <id> | memory reject <id> | memory used';\n\nexport interface ICommandProjectMemoryStore {\n list(): IProjectMemorySummary;\n loadStartupMemory(): IStartupMemory;\n readTopic(topic: string): string;\n append(input: IAppendMemoryInput): IAppendMemoryResult;\n}\n\nexport interface ICommandPendingMemoryStore {\n get(id: string): IMemoryPendingRecord | undefined;\n list(status?: TMemoryCandidateStatus): IMemoryPendingRecord[];\n mark(id: string, status: TMemoryCandidateStatus, reason: string): IMemoryPendingRecord;\n upsert(candidate: IMemoryCandidate, status: TMemoryCandidateStatus, reason: string): void;\n}\n\nexport interface ICommandMemoryStores {\n project: ICommandProjectMemoryStore;\n pending: ICommandPendingMemoryStore;\n}\n\nexport type {\n IAppendMemoryInput,\n IAppendMemoryResult,\n IMemoryCandidate,\n IMemoryEvent,\n IMemoryPendingRecord,\n IMemoryReference,\n IProjectMemorySummary,\n IStartupMemory,\n TMemoryCandidateStatus,\n TMemoryType,\n};\n\nexport function buildMemoryCommandSubcommands(source = 'memory'): ICommand[] {\n return [\n { name: 'list', description: 'List project memory topics', source },\n { name: 'show', description: 'Show project memory index or a topic', source },\n { name: 'add', description: 'Save durable project memory', source },\n { name: 'pending', description: 'List pending memory candidates', source },\n { name: 'approve', description: 'Approve a pending memory candidate', source },\n { name: 'reject', description: 'Reject a pending memory candidate', source },\n {\n name: 'used',\n description: 'Show memory references used in the current turn',\n source,\n },\n ];\n}\n\nexport function createCommandProjectMemoryStore(\n cwd: string,\n now?: () => Date,\n): ICommandProjectMemoryStore {\n return new ProjectMemoryStore(cwd, now);\n}\n\nexport function createCommandPendingMemoryStore(\n cwd: string,\n now?: () => Date,\n): ICommandPendingMemoryStore {\n return new PendingMemoryStore(cwd, now);\n}\n\nexport function createCommandMemoryStores(\n context: ICommandHostContext,\n now?: () => Date,\n): ICommandMemoryStores {\n const cwd = context.getCwd();\n return {\n project: createCommandProjectMemoryStore(cwd, now),\n pending: createCommandPendingMemoryStore(cwd, now),\n };\n}\n\nexport function isCommandMemoryType(value: string): value is TMemoryType {\n return isMemoryType(value);\n}\n\nexport function hasSensitiveCommandMemoryContent(text: string): boolean {\n return containsSensitiveMemoryContent(text);\n}\n\nexport function listCommandUsedMemoryReferences(\n context: ICommandHostContext,\n): readonly IMemoryReference[] {\n return context.getUsedMemoryReferences();\n}\n\nexport function recordCommandMemoryEvent(\n context: ICommandHostContext,\n event: Omit<IMemoryEvent, 'at'>,\n now: () => Date = () => new Date(),\n): void {\n context.recordMemoryEvent({\n ...event,\n at: now().toISOString(),\n });\n}\n","/** Shell exec function for skill preprocessing — injected from composition root. */\nexport type TShellExecFn = (command: string) => string;\n\n/** Context variables available during skill prompt processing */\nexport interface SkillPromptContext {\n /** Current session ID — substituted for ${CLAUDE_SESSION_ID} */\n sessionId?: string;\n /** Directory containing SKILL.md — substituted for ${CLAUDE_SKILL_DIR} */\n skillDir?: string;\n}\n\n/**\n * Substitute variables in skill content.\n *\n * Supported variables:\n * - `$ARGUMENTS` — all arguments passed to the skill\n * - `$ARGUMENTS[N]` — argument by index (0-based)\n * - `$N` — shorthand for `$ARGUMENTS[N]` (single digit, 0-9)\n * - `${CLAUDE_SESSION_ID}` — current session ID\n * - `${CLAUDE_SKILL_DIR}` — directory containing SKILL.md\n */\nexport function substituteVariables(\n content: string,\n args: string,\n context?: SkillPromptContext,\n): string {\n const argParts = args ? args.split(/\\s+/) : [];\n\n let result = content;\n\n // Replace $ARGUMENTS[N] before $ARGUMENTS to avoid partial match\n result = result.replace(/\\$ARGUMENTS\\[(\\d+)]/g, (_match, index: string) => {\n return argParts[Number(index)] ?? '';\n });\n\n // Replace $ARGUMENTS with all args\n result = result.replace(/\\$ARGUMENTS/g, args);\n\n // Replace $N shorthand (single digit, 0-9)\n result = result.replace(/\\$(\\d)(?!\\d|\\w|\\[)/g, (_match, digit: string) => {\n return argParts[Number(digit)] ?? '';\n });\n\n // Replace ${CLAUDE_SESSION_ID}\n result = result.replace(/\\$\\{CLAUDE_SESSION_ID}/g, context?.sessionId ?? '');\n\n // Replace ${CLAUDE_SKILL_DIR}\n result = result.replace(/\\$\\{CLAUDE_SKILL_DIR}/g, context?.skillDir ?? '');\n\n return result;\n}\n\n/**\n * Preprocess shell commands in skill content.\n * Matches `` !`...` `` patterns and replaces them with command output.\n * If no exec function is provided, shell patterns are replaced with empty string.\n */\nexport async function preprocessShellCommands(\n content: string,\n exec?: TShellExecFn,\n): Promise<string> {\n const shellPattern = /!`([^`]+)`/g;\n\n if (!shellPattern.test(content)) {\n return content;\n }\n\n // Reset lastIndex after test()\n shellPattern.lastIndex = 0;\n\n let result = content;\n let match: RegExpExecArray | null;\n\n // Collect all matches first to avoid mutation issues during replacement\n const matches: Array<{ full: string; command: string }> = [];\n while ((match = shellPattern.exec(content)) !== null) {\n matches.push({ full: match[0], command: match[1] });\n }\n\n for (const { full, command } of matches) {\n let output = '';\n if (exec) {\n try {\n output = exec(command);\n } catch {\n output = '';\n }\n }\n result = result.replace(full, output);\n }\n\n return result;\n}\n","/**\n * Skill execution logic.\n * Handles both fork-based (subagent) and inject-based (user message) execution.\n */\n\nimport {\n preprocessShellCommands,\n substituteVariables,\n type SkillPromptContext,\n type TShellExecFn,\n} from '../utils/skill-prompt.js';\n\nimport type { ICommand } from '../command-api/types.js';\n\n/** Options passed to the fork execution callback */\nexport interface IForkExecutionOptions {\n /** Agent identity to use (e.g., 'Explore', 'Plan') */\n agent?: string;\n /** Tools the subagent is allowed to use */\n allowedTools?: string[];\n}\n\n/** Callback interface for skill execution infrastructure */\nexport interface ISkillExecutionCallbacks {\n /**\n * Run skill content in an isolated subagent session.\n * The content becomes the subagent's prompt.\n * Returns the subagent's response.\n */\n runInFork?: (content: string, options: IForkExecutionOptions) => Promise<string>;\n /** Shell exec function for preprocessing `` !`cmd` `` patterns — injected from composition root. */\n shellExec?: TShellExecFn;\n}\n\n/** Result of skill execution */\nexport interface ISkillExecutionResult {\n /** Execution mode used */\n mode: 'fork' | 'inject';\n /** For inject mode: the prompt to send as a user message */\n prompt?: string;\n /** For fork mode: the subagent's response */\n result?: string;\n}\n\n/**\n * Build the processed skill content with variable substitution.\n * Returns the raw content after substitution (no XML wrapping).\n */\nasync function buildProcessedContent(\n skill: ICommand,\n args: string,\n callbacks: ISkillExecutionCallbacks,\n context?: SkillPromptContext,\n): Promise<string | null> {\n if (!skill.skillContent) return null;\n const preprocessed = await preprocessShellCommands(skill.skillContent, callbacks.shellExec);\n return substituteVariables(preprocessed, args, context);\n}\n\n/**\n * Build an inject-mode prompt from a skill command.\n * Wraps content in skill XML tags for the model.\n */\nasync function buildInjectPrompt(\n skill: ICommand,\n args: string,\n callbacks: ISkillExecutionCallbacks,\n context?: SkillPromptContext,\n): Promise<string> {\n const processed = await buildProcessedContent(skill, args, callbacks, context);\n if (processed) {\n const userInstruction = args || skill.description;\n return `<skill name=\"${skill.name}\">\\n${processed}\\n</skill>\\n\\nExecute the \"${skill.name}\" skill: ${userInstruction}`;\n }\n return `Use the \"${skill.name}\" skill: ${args || skill.description}`;\n}\n\n/**\n * Execute a skill command.\n *\n * When `context: 'fork'`, the skill runs in an isolated subagent session\n * via the `runInFork` callback. Throws if `runInFork` is not available.\n * For non-fork skills, the content is returned as a prompt for injection\n * into the current session.\n */\nexport async function executeSkill(\n skill: ICommand,\n args: string,\n callbacks: ISkillExecutionCallbacks,\n context?: SkillPromptContext,\n): Promise<ISkillExecutionResult> {\n // Fork execution: isolated subagent session\n if (skill.context === 'fork') {\n if (!callbacks.runInFork) {\n throw new Error(\n 'Fork execution is not available. Agent runtime deps may not be initialized.',\n );\n }\n\n const content = await buildProcessedContent(skill, args, callbacks, context);\n const prompt = content ?? `Use the \"${skill.name}\" skill: ${args || skill.description}`;\n\n const options: IForkExecutionOptions = {};\n if (skill.agent) options.agent = skill.agent;\n if (skill.allowedTools) options.allowedTools = skill.allowedTools;\n\n const result = await callbacks.runInFork(prompt, options);\n return { mode: 'fork', result };\n }\n\n // Inject execution: return prompt for current session\n const prompt = await buildInjectPrompt(skill, args, callbacks, context);\n return { mode: 'inject', prompt };\n}\n","/**\n * SessionSkillRouter — manages command execution and skill routing\n * for an InteractiveSession. Handles SystemCommandExecutor, SkillCommandSource,\n * and all command/skill invocation logic.\n */\n\nimport { executeSkill, SkillCommandSource, SystemCommandExecutor } from '../commands/index.js';\nimport { createSkillActivationEvent } from '../commands/skill-activation-events.js';\n\nimport type { ICommandHostContext } from '../command-api/index.js';\nimport type {\n ICommand,\n ICommandHostAdapters,\n ICommandModule,\n ICommandResult,\n ICommandSkillListEntry,\n ISkillExecutionResult,\n IForkExecutionOptions,\n ICommandSkillActivationRequest,\n TCommandInvocationSource,\n ISystemCommand,\n} from '../commands/index.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type { TShellExecFn } from '../utils/skill-prompt.js';\n\nfunction normalizeSkillName(name: string): string {\n return name.trim().replace(/^\\/+/, '').split(/\\s+/)[0] ?? '';\n}\n\nfunction normalizeCommandName(name: string): string {\n return name.trim().replace(/^\\/+/, '').split(/\\s+/)[0] ?? '';\n}\n\nfunction formatSkillCommandArgs(skillName: string, args: string): string {\n const trimmedArgs = args.trim();\n return trimmedArgs.length > 0 ? `${skillName} ${trimmedArgs}` : skillName;\n}\n\nfunction getQualifiedSkillName(rawInput?: string): string | undefined {\n if (!rawInput?.startsWith('/')) return undefined;\n const firstToken = rawInput.slice(1).trim().split(/\\s+/)[0];\n return firstToken && firstToken.length > 0 ? firstToken : undefined;\n}\n\nexport class SessionSkillRouter {\n readonly commandExecutor: SystemCommandExecutor;\n private readonly skillCommandSource: SkillCommandSource;\n private readonly commandHostAdapters?: ICommandHostAdapters;\n private commandInvocationSource: TCommandInvocationSource = 'user';\n\n constructor(\n commandModules: readonly ICommandModule[],\n cwd: string,\n commandHostAdapters: ICommandHostAdapters | undefined,\n private readonly getSession: () => ICommandHostContext,\n private readonly getSessionId: () => string,\n private readonly onSubmit: (\n prompt: string,\n displayInput?: string,\n rawInput?: string,\n ) => Promise<void>,\n private readonly onApplyResult: (result: string) => Promise<void>,\n private readonly recordSkillActivation: (\n event: ISkillActivationEvent,\n appendHistory: boolean,\n ) => void,\n private readonly runSkillInFork: (\n content: string,\n options: IForkExecutionOptions,\n ) => Promise<string>,\n /** Called when a fork-context skill needs full lifecycle management (executing flag etc.) */\n private readonly onForkSkill: (\n skill: ICommand,\n args: string,\n displayInput: string | undefined,\n qualifiedName: string | undefined,\n invocation: ISkillActivationEvent['invocation'],\n ) => Promise<ISkillExecutionResult>,\n /** Called for blocking commands — wraps execution with thinking/executing lifecycle */\n private readonly onBlockingCommand: (\n execute: () => Promise<ICommandResult>,\n ) => Promise<ICommandResult>,\n private readonly shellExec?: TShellExecFn,\n ) {\n this.commandExecutor = new SystemCommandExecutor(\n commandModules.flatMap((module) => module.systemCommands ?? []),\n );\n this.skillCommandSource = new SkillCommandSource(cwd);\n this.commandHostAdapters = commandHostAdapters;\n }\n\n getCommandInvocationSource(): TCommandInvocationSource {\n return this.commandInvocationSource;\n }\n\n getCommandHostAdapters(): ICommandHostAdapters {\n return this.commandHostAdapters ?? {};\n }\n\n listCommands(): Array<{ name: string; displayName?: string; description: string }> {\n return this.commandExecutor.listCommands().map((cmd) => ({\n name: cmd.name,\n ...(cmd.displayName !== undefined ? { displayName: cmd.displayName } : {}),\n description: cmd.description,\n }));\n }\n\n listSkills(): ICommandSkillListEntry[] {\n return this.skillCommandSource.getCommands().map((skill) => ({\n name: skill.name,\n description: skill.description,\n source: skill.source,\n modelInvocable: skill.disableModelInvocation !== true,\n userInvocable: skill.userInvocable !== false,\n ...(skill.argumentHint !== undefined ? { argumentHint: skill.argumentHint } : {}),\n ...(skill.context !== undefined ? { context: skill.context } : {}),\n ...(skill.agent !== undefined ? { agent: skill.agent } : {}),\n }));\n }\n\n listModelInvocableCommands(): Array<{ name: string; description: string }> {\n return this.commandExecutor.listModelInvocableCommands().map((cmd) => ({\n name: cmd.name,\n description: cmd.description,\n }));\n }\n\n findSkillCommand(name: string): ICommand | undefined {\n const normalizedName = normalizeSkillName(name);\n return this.skillCommandSource\n .getCommands()\n .find((skill) => skill.name.toLowerCase() === normalizedName.toLowerCase());\n }\n\n async executeCommand(name: string, args: string): Promise<ICommandResult | null> {\n const normalizedName = normalizeCommandName(name);\n const command = this.commandExecutor.getCommand(normalizedName);\n const commandArgs = args.trim();\n if (!command) {\n const skill = this.findSkillCommand(normalizedName);\n const skillsCommand = this.commandExecutor.getCommand('skills');\n if (!skill || !skillsCommand) return null;\n return this.executeCommandWithSource(\n 'user',\n skillsCommand,\n formatSkillCommandArgs(skill.name, commandArgs),\n );\n }\n return this.executeCommandWithSource('user', command, commandArgs);\n }\n\n async executeCommandWithSource(\n source: TCommandInvocationSource,\n command: ISystemCommand,\n args: string,\n ): Promise<ICommandResult> {\n const previousSource = this.commandInvocationSource;\n this.commandInvocationSource = source;\n try {\n if (command.lifecycle === 'blocking') {\n return this.onBlockingCommand(() => this.executeForegroundCommand(command, args));\n }\n return await this.commandExecutor.executeCommand(command, this.getSession(), args);\n } finally {\n this.commandInvocationSource = previousSource;\n }\n }\n\n async executeModelCommand(name: string, args: string): Promise<ICommandResult | null> {\n const previousSource = this.commandInvocationSource;\n this.commandInvocationSource = 'model';\n try {\n return await this.commandExecutor.executeModelInvocable(name, this.getSession(), args);\n } finally {\n this.commandInvocationSource = previousSource;\n }\n }\n\n async executeSkillCommandByName(\n name: string,\n args: string,\n request: ICommandSkillActivationRequest,\n ): Promise<ICommandResult | null> {\n const skill = this.findSkillCommand(name);\n if (!skill) return null;\n\n if (request.invocationSource === 'model') {\n if (skill.disableModelInvocation === true) {\n return { success: false, message: `Skill is not model-invocable: ${skill.name}` };\n }\n const result = await this.executeSkillWithActivation(skill, args, 'model-tool');\n return {\n success: true,\n message: `Skill activated: ${skill.name}`,\n data: {\n skill: skill.name,\n mode: result.mode,\n ...(result.prompt !== undefined ? { prompt: result.prompt } : {}),\n ...(result.result !== undefined ? { result: result.result } : {}),\n },\n };\n }\n\n await this.executeUserResolvedSkillCommand(\n skill,\n args,\n request.displayInput,\n request.rawInput,\n 'user-slash',\n );\n return {\n success: true,\n message: '',\n data: { skill: skill.name, sessionExecution: true },\n effects: [{ type: 'session-execution-started' }],\n };\n }\n\n async executeUserResolvedSkillCommand(\n skill: ICommand,\n args: string,\n displayInput: string | undefined,\n rawInput: string | undefined,\n invocation: ISkillActivationEvent['invocation'],\n ): Promise<ISkillExecutionResult> {\n if (skill.userInvocable === false) {\n throw new Error(`Skill is not user-invocable: ${skill.name}`);\n }\n const qualifiedName = getQualifiedSkillName(rawInput);\n\n if (skill.context === 'fork') {\n return this.onForkSkill(skill, args, displayInput, qualifiedName, invocation);\n }\n\n const result = await this.executeSkillWithActivation(skill, args, invocation, qualifiedName);\n if (result.mode === 'inject') {\n if (result.prompt) await this.onSubmit(result.prompt, displayInput, rawInput);\n return result;\n }\n await this.onApplyResult(result.result ?? '(empty response)');\n return result;\n }\n\n async executeSkillWithActivation(\n skill: ICommand,\n args: string,\n invocation: ISkillActivationEvent['invocation'],\n qualifiedName?: string,\n ): Promise<ISkillExecutionResult> {\n this.emitSkillActivation(skill, invocation, 'started', qualifiedName);\n try {\n const result = await executeSkill(\n skill,\n args,\n {\n runInFork: (content, options) => this.runSkillInFork(content, options),\n ...(this.shellExec ? { shellExec: this.shellExec } : {}),\n },\n { sessionId: this.getSessionId() },\n );\n this.emitSkillActivation(skill, invocation, 'completed', qualifiedName, {\n appendHistory: false,\n });\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.emitSkillActivation(skill, invocation, 'failed', qualifiedName, {\n error: error.message,\n });\n throw error;\n }\n }\n\n private emitSkillActivation(\n skill: ICommand,\n invocation: ISkillActivationEvent['invocation'],\n status: ISkillActivationEvent['status'],\n qualifiedName?: string,\n options: { appendHistory?: boolean; error?: string } = {},\n ): void {\n const event = createSkillActivationEvent({\n skill,\n invocation,\n status,\n ...(qualifiedName !== undefined ? { qualifiedName } : {}),\n ...(options.error !== undefined ? { error: options.error } : {}),\n });\n this.recordSkillActivation(event, options.appendHistory ?? status !== 'completed');\n }\n\n private async executeForegroundCommand(\n command: ISystemCommand,\n args: string,\n ): Promise<ICommandResult> {\n try {\n return await this.commandExecutor.executeCommand(command, this.getSession(), args);\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n return { success: false, message: `Error: ${errMsg}` };\n }\n }\n}\n","import { createSystemMessage, messageToHistoryEntry } from '@robota-sdk/agent-core';\n\nimport { SessionBackgroundTaskTracker } from './interactive-session-background-tracker.js';\nimport { InteractiveSessionBase } from './interactive-session-base.js';\nimport { SessionExecutionController } from './interactive-session-execution-controller.js';\nimport { runSkillInFork } from './interactive-session-fork.js';\nimport { SessionHistoryTracker } from './interactive-session-history-tracker.js';\nimport { initializeInteractiveSessionAsync } from './interactive-session-init.js';\nimport { persistSession } from './interactive-session-persistence.js';\nimport { loadSessionRecord } from './interactive-session-restore.js';\nimport { SessionSkillRouter } from './interactive-session-skill-router.js';\nimport { retrieveSessionBackgroundTaskManager } from '../background-tasks/session-background-store.js';\nimport { EditCheckpointStore } from '../checkpoints/edit-checkpoint-store.js';\nimport { retrieveAgentToolDeps } from '../tools/agent-tool.js';\n\nimport type { IInteractiveSession } from './i-interactive-session.js';\nimport type { ICreatedInteractiveSession } from './interactive-session-init.js';\nimport type {\n TInteractiveSessionOptions,\n IInteractiveSessionStandardOptions,\n} from './interactive-session-options.js';\nimport type { IInteractiveSessionStore } from './session-persistence.js';\nimport type { TInteractiveEventName, IInteractiveSessionEvents } from './types.js';\nimport type { IBackgroundTaskManager } from '../background-tasks/index.js';\nimport type { ICommandHostContext } from '../command-api/index.js';\nimport type {\n IAgentJobHostContext,\n TAutoCompactThresholdSource,\n TAutoCompactThreshold,\n} from '../commands/index.js';\nimport type { IContextFileEntry } from '../context/context-file-tracker.js';\nimport type { TUniversalMessage, TSessionEndReason } from '@robota-sdk/agent-core';\nimport type { ISession } from '@robota-sdk/agent-core';\nimport type { ITransportAdapter } from '@robota-sdk/agent-interface-transport';\nimport type { Session } from '@robota-sdk/agent-session';\nimport type { ISandboxClient } from '@robota-sdk/agent-tools';\nexport type { TInteractiveSessionOptions } from './interactive-session-options.js';\n\nexport interface IInteractiveSessionShutdownOptions {\n reason?: TSessionEndReason;\n message?: string;\n}\n\nexport class InteractiveSession\n extends InteractiveSessionBase\n implements ISession, IAgentJobHostContext, IInteractiveSession\n{\n private session: Session | null = null;\n private readonly listeners = new Map<string, Set<(...args: unknown[]) => void>>();\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n private sessionStore?: IInteractiveSessionStore;\n private sessionName?: string;\n private cwd?: string;\n private pendingRestoreMessages: TUniversalMessage[] | null = null;\n private resumeSessionId?: string;\n private forkSession: boolean;\n private autoCompactThresholdSource: TAutoCompactThresholdSource = 'default';\n private shutdownPromise: Promise<void> | null = null;\n private readonly sandboxClient?: ISandboxClient;\n private sandboxSnapshotId?: string;\n private agentsFileEntries: IContextFileEntry[] = [];\n private claudeFileEntries: IContextFileEntry[] = [];\n private rebuildSystemMessage: ICreatedInteractiveSession['rebuildSystemMessage'] | null = null;\n protected readonly bgTracker: SessionBackgroundTaskTracker;\n protected readonly histTracker: SessionHistoryTracker;\n protected readonly skillRouter: SessionSkillRouter;\n protected readonly execCtrl: SessionExecutionController;\n\n constructor(options: TInteractiveSessionOptions) {\n super();\n this.sessionStore = options.sessionStore;\n this.sessionName = options.sessionName;\n this.cwd = ('cwd' in options ? options.cwd : undefined) ?? '';\n this.resumeSessionId = options.resumeSessionId;\n this.forkSession = options.forkSession ?? false;\n this.sandboxClient = 'sandboxClient' in options ? options.sandboxClient : undefined;\n this.sandboxSnapshotId = 'sandboxSnapshotId' in options ? options.sandboxSnapshotId : undefined;\n\n const cwd = this.cwd;\n let initCheckpointStore: EditCheckpointStore | null = null;\n if ('session' in options && options.session && cwd) {\n initCheckpointStore = new EditCheckpointStore({ cwd });\n }\n\n this.bgTracker = new SessionBackgroundTaskTracker(\n () => this.getBackgroundTaskManager(),\n (cause, entryId) => this.execCtrl.emitExecutionWorkspaceUpdated(cause, entryId),\n (event) => this.emit('background_task_event', event),\n (event) => this.emit('background_job_group_event', event),\n () => this.persistCurrentSession(),\n );\n\n this.histTracker = new SessionHistoryTracker(\n cwd,\n () => this.getSessionOrThrow().getSessionId(),\n () => this.execCtrl.executing,\n () => this.persistCurrentSession(),\n (event) => this.emit('skill_activation', event),\n initCheckpointStore,\n );\n\n const commandModules = [...('commandModules' in options ? (options.commandModules ?? []) : [])];\n const commandHostAdapters =\n 'commandHostAdapters' in options ? options.commandHostAdapters : undefined;\n const shellExec = 'shellExec' in options ? options.shellExec : undefined;\n\n this.skillRouter = new SessionSkillRouter(\n commandModules,\n cwd,\n commandHostAdapters,\n () => this as unknown as ICommandHostContext,\n () => this.session?.getSessionId() ?? '',\n (prompt, displayInput, rawInput) => this.submit(prompt, displayInput, rawInput),\n (result) => this.execCtrl.applyForkSkillResult(result),\n (event, appendHistory) => this.histTracker.recordSkillActivationEvent(event, appendHistory),\n (content, forkOptions) => runSkillInFork(content, forkOptions, this.getSessionOrThrow()),\n (skill, args, displayInput, qualifiedName, invocation) =>\n this.execCtrl.executeForkSkillCommand(\n skill,\n args,\n displayInput,\n qualifiedName,\n invocation,\n (p, d, r) => this.submit(p, d, r),\n ),\n (execute) =>\n this.execCtrl.executeForegroundCommand(execute, (p, d, r) => this.submit(p, d, r)),\n shellExec,\n );\n\n this.execCtrl = new SessionExecutionController(this.histTracker, this.skillRouter, {\n getSession: () => this.session!,\n getSessionOrThrow: () => this.getSessionOrThrow(),\n getCwd: () => this.getCwd(),\n getContextState: () => this.getContextState(),\n getExecutionWorkspaceSnapshot: () => this.getExecutionWorkspaceSnapshot(),\n emit: (event, ...args) =>\n this.emit(\n event as TInteractiveEventName,\n ...(args as Parameters<IInteractiveSessionEvents[TInteractiveEventName]>),\n ),\n persistSession: () => this.persistCurrentSession(),\n });\n\n const hasInjectedSession = this.configureInjectedSession(options);\n this.restoreSessionRecordIfNeeded(options);\n this.startAsyncInitializationIfNeeded(options, hasInjectedSession);\n\n if (this.initialized) this.bgTracker.subscribe(this.session!);\n if (this.initialized) this.persistCurrentSession();\n }\n\n private configureInjectedSession(options: TInteractiveSessionOptions): boolean {\n if (!('session' in options && options.session)) return false;\n this.session = options.session;\n this.autoCompactThresholdSource = 'session';\n this.initialized = true;\n return true;\n }\n\n private restoreSessionRecordIfNeeded(options: TInteractiveSessionOptions): void {\n if (!options.resumeSessionId || !this.sessionStore) return;\n const restored = loadSessionRecord(\n this.sessionStore,\n options.resumeSessionId,\n this.forkSession,\n this.session,\n );\n this.histTracker.restoreState({\n history: restored.history,\n memoryEvents: restored.memoryEvents,\n usedMemoryReferences: restored.usedMemoryReferences,\n contextReferences: restored.contextReferences,\n skillActivationEvents: restored.skillActivationEvents,\n });\n if (restored.sessionName) this.sessionName = restored.sessionName;\n this.bgTracker.restoreState({\n tasks: restored.backgroundTasks,\n taskEvents: restored.backgroundTaskEvents,\n groups: restored.backgroundJobGroups,\n groupEvents: restored.backgroundJobGroupEvents,\n });\n this.pendingRestoreMessages = restored.pendingRestoreMessages;\n this.sandboxSnapshotId = this.forkSession ? undefined : restored.sandboxSnapshotId;\n }\n\n private startAsyncInitializationIfNeeded(\n options: TInteractiveSessionOptions,\n hasInjectedSession: boolean,\n ): void {\n if (hasInjectedSession) return;\n const stdOpts = options as IInteractiveSessionStandardOptions;\n this.initPromise = this.initializeAsync(stdOpts);\n }\n\n private async initializeAsync(options: IInteractiveSessionStandardOptions): Promise<void> {\n const result = await initializeInteractiveSessionAsync(options, {\n sandboxSnapshotId: this.sandboxSnapshotId,\n resumeSessionId: this.resumeSessionId,\n pendingRestoreMessages: this.pendingRestoreMessages,\n onTextDelta: (delta) => this.execCtrl.handleTextDelta(delta),\n onContextUpdate: (state) => this.emit('context_update', state),\n onCompactEvent: (event) => this.execCtrl.handleCompactEvent(event),\n onToolExecution: (event) => this.execCtrl.handleToolExecution(event),\n executeModelCommand: (command, args) => this.executeModelCommand(command, args),\n isModelCommandInvocable: (command) =>\n this.skillRouter.commandExecutor.isModelInvocable(command),\n commandDescriptors: this.skillRouter.commandExecutor.listModelInvocableCommands(),\n setEditCheckpointStore: (store) => this.histTracker.setEditCheckpointStore(store),\n });\n this.session = result.session;\n this.agentsFileEntries = result.agentsFileEntries;\n this.claudeFileEntries = result.claudeFileEntries;\n this.rebuildSystemMessage = result.rebuildSystemMessage;\n this.autoCompactThresholdSource = result.autoCompactThresholdSource;\n this.pendingRestoreMessages = null;\n this.initialized = true;\n this.bgTracker.subscribe(this.session);\n this.persistCurrentSession();\n }\n\n protected async ensureInitialized(): Promise<void> {\n if (!this.initialized && this.initPromise) await this.initPromise;\n }\n\n protected getSessionOrThrow(): Session {\n if (!this.session)\n throw new Error('InteractiveSession not initialized. Call submit() or await initialization.');\n return this.session;\n }\n\n getCwd(): string {\n if (!this.cwd) throw new Error('cwd is not set — provide cwd in session options');\n return this.cwd;\n }\n\n get sessionId(): string {\n return this.session?.getSessionId() ?? '';\n }\n\n on<E extends TInteractiveEventName>(event: E, handler: IInteractiveSessionEvents[E]): void {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set());\n this.listeners.get(event)!.add(handler as (...args: unknown[]) => void);\n }\n\n off<E extends TInteractiveEventName>(event: E, handler: IInteractiveSessionEvents[E]): void {\n this.listeners.get(event)?.delete(handler as (...args: unknown[]) => void);\n }\n\n private emit<E extends TInteractiveEventName>(\n event: E,\n ...args: Parameters<IInteractiveSessionEvents[E]>\n ): void {\n const handlers = this.listeners.get(event);\n if (handlers) for (const handler of handlers) handler(...args);\n }\n\n async submit(input: string, displayInput?: string, rawInput?: string): Promise<void> {\n await this.ensureInitialized();\n if (this.execCtrl.shuttingDown) throw new Error('Interactive session is shutting down.');\n if (this.execCtrl.executing) {\n this.execCtrl.pendingPrompt = input;\n this.execCtrl.pendingDisplayInput = displayInput;\n this.execCtrl.pendingRawInput = rawInput;\n return;\n }\n await this.execCtrl.executePrompt(\n input,\n displayInput,\n rawInput,\n this.agentsFileEntries,\n this.claudeFileEntries,\n this.rebuildSystemMessage,\n (agents, claude) => {\n this.agentsFileEntries = agents;\n this.claudeFileEntries = claude;\n },\n (p, d, r) => this.submit(p, d, r),\n );\n }\n\n abort(): void {\n this.execCtrl.clearPendingQueue();\n this.session?.abort();\n }\n\n shutdown(options: IInteractiveSessionShutdownOptions = {}): Promise<void> {\n if (this.shutdownPromise) return this.shutdownPromise;\n this.execCtrl.shuttingDown = true;\n this.shutdownPromise = (async () => {\n await this.ensureInitialized();\n this.execCtrl.clearPendingQueue();\n const session = this.session;\n session?.abort();\n await this.getBackgroundTaskManager()?.shutdown(options.message ?? 'Session shutdown');\n this.bgTracker.dispose();\n await this.captureSandboxSnapshot();\n this.persistCurrentSession();\n await session?.shutdown({ reason: options.reason ?? 'other' });\n })();\n return this.shutdownPromise;\n }\n\n get isInitialized(): boolean {\n return this.initialized;\n }\n\n getAutoCompactThresholdSource(): TAutoCompactThresholdSource {\n return this.autoCompactThresholdSource;\n }\n\n getAutoCompactThreshold(): number | false {\n return this.getSessionOrThrow().getAutoCompactThreshold();\n }\n getSession(): Session {\n return this.getSessionOrThrow();\n }\n\n getAgentJobCapability(): IAgentJobHostContext {\n return this;\n }\n\n setAutoCompactThreshold(\n threshold: TAutoCompactThreshold,\n source: TAutoCompactThresholdSource = 'session',\n ): void {\n this.getSessionOrThrow().setAutoCompactThreshold(threshold);\n this.autoCompactThresholdSource = source;\n this.emit('context_update', this.getContextState());\n this.persistCurrentSession();\n }\n\n clearConversationHistory(): void {\n this.getSessionOrThrow().clearHistory();\n this.histTracker.clearHistory();\n this.persistCurrentSession();\n this.emit('context_update', this.getContextState());\n }\n\n getName(): string | undefined {\n return this.sessionName;\n }\n\n attachTransport(transport: ITransportAdapter<IInteractiveSession>): void {\n transport.attach(this);\n }\n\n setName(name: string): void {\n this.sessionName = name;\n if (this.sessionStore && this.session) {\n try {\n const id = this.getSessionOrThrow().getSessionId();\n const existing = this.sessionStore.load(id);\n if (existing) {\n existing.name = name;\n existing.updatedAt = new Date().toISOString();\n this.sessionStore.save(existing);\n }\n } catch {\n /* Session not initialized yet */\n }\n }\n }\n\n private getBackgroundTaskManager(): IBackgroundTaskManager | undefined {\n if (!this.session) return undefined;\n return (\n retrieveSessionBackgroundTaskManager(this.session) ??\n retrieveAgentToolDeps(this.session)?.backgroundTaskManager\n );\n }\n\n private async captureSandboxSnapshot(): Promise<void> {\n if (!this.sandboxClient?.snapshot) return;\n try {\n this.sandboxSnapshotId = await this.sandboxClient.snapshot();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.histTracker.append(\n messageToHistoryEntry(createSystemMessage(`Sandbox snapshot error: ${err.message}`)),\n );\n this.emit('error', err);\n }\n }\n\n private persistCurrentSession(): void {\n if (!this.sessionStore || !this.session) return;\n const bgState = this.bgTracker.getState();\n const histState = this.histTracker.getState();\n persistSession(\n this.sessionStore,\n this.session,\n this.sessionName,\n this.cwd ?? '',\n histState.history,\n {\n tasks: bgState.tasks,\n events: bgState.taskEvents,\n groups: bgState.groups,\n groupEvents: bgState.groupEvents,\n },\n { events: histState.memoryEvents, usedReferences: histState.usedMemoryReferences },\n { events: histState.skillActivationEvents },\n { references: histState.contextReferences },\n { snapshotId: this.sandboxSnapshotId },\n );\n }\n}\n","import { join } from 'node:path';\n\nimport {\n loadSessionLogEntries,\n replaySessionLogEntries,\n SessionStore,\n type ISessionRecord,\n} from '@robota-sdk/agent-session';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\nimport { projectPaths } from '../paths.js';\n\nimport type {\n IBackgroundJobGroupState,\n IBackgroundTaskState,\n TBackgroundJobGroupEvent,\n TBackgroundTaskEvent,\n} from '../background-tasks/index.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type { IContextReferenceItem } from '../context/context-reference-inventory.js';\nimport type { IMemoryEvent, IMemoryReference } from '../memory/automatic-memory-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\nimport type { IHistoryEntry, IToolSchema, TUniversalMessage } from '@robota-sdk/agent-core';\n\nexport interface IInteractiveSessionRecord {\n id: string;\n name?: string;\n cwd: string;\n createdAt: string;\n updatedAt: string;\n messages: TUniversalMessage[];\n history?: IHistoryEntry[];\n systemPrompt?: string;\n toolSchemas?: IToolSchema[];\n backgroundTasks?: IBackgroundTaskState[];\n backgroundTaskEvents?: TBackgroundTaskEvent[];\n backgroundJobGroups?: IBackgroundJobGroupState[];\n backgroundJobGroupEvents?: TBackgroundJobGroupEvent[];\n skillActivationEvents?: ISkillActivationEvent[];\n memoryEvents?: IMemoryEvent[];\n usedMemoryReferences?: IMemoryReference[];\n contextReferences?: IContextReferenceItem[];\n sandboxSnapshotId?: string;\n}\n\nexport interface IInteractiveSessionStore {\n save(session: IInteractiveSessionRecord): void;\n load(id: string): IInteractiveSessionRecord | undefined;\n list(): IInteractiveSessionRecord[];\n delete(id: string): void;\n}\n\nexport interface IResumableSessionSummary {\n id: string;\n name?: string;\n cwd: string;\n updatedAt: string;\n messageCount: number;\n preview: string;\n}\n\nexport function createProjectSessionStore(\n cwd: string,\n fs: IFileSystem = new NodeFileSystem(),\n): IInteractiveSessionStore {\n const paths = projectPaths(cwd);\n return new ProjectSessionStoreFacade(paths.sessions, paths.logs, fs);\n}\n\nexport function listResumableSessionSummaries(\n sessionStore: IInteractiveSessionStore | undefined,\n cwd: string,\n): IResumableSessionSummary[] {\n return (sessionStore?.list() ?? [])\n .filter((session) => session.cwd === cwd)\n .sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())\n .map((session) => ({\n id: session.id,\n ...(session.name !== undefined ? { name: session.name } : {}),\n cwd: session.cwd,\n updatedAt: session.updatedAt,\n messageCount: session.messages.length,\n preview: getLastAssistantPreview(session.messages),\n }));\n}\n\nexport function resolveLatestSessionId(\n sessionStore: IInteractiveSessionStore | undefined,\n cwd: string,\n): string | undefined {\n return listResumableSessionSummaries(sessionStore, cwd)[0]?.id;\n}\n\nexport function resolveSessionIdByIdOrName(\n sessionStore: IInteractiveSessionStore | undefined,\n idOrName: string,\n): string | undefined {\n const match = (sessionStore?.list() ?? []).find(\n (session) => session.id === idOrName || session.name === idOrName,\n );\n return match?.id;\n}\n\nclass ProjectSessionStoreFacade implements IInteractiveSessionStore {\n private readonly store: SessionStore;\n private readonly logsDir: string | undefined;\n private readonly fs: IFileSystem;\n\n constructor(baseDir: string, logsDir?: string, fs: IFileSystem = new NodeFileSystem()) {\n this.store = new SessionStore(baseDir);\n this.logsDir = logsDir;\n this.fs = fs;\n }\n\n save(session: IInteractiveSessionRecord): void {\n this.store.save(toSessionRecord(session));\n }\n\n load(id: string): IInteractiveSessionRecord | undefined {\n const session = this.store.load(id);\n if (session !== undefined) {\n return fromSessionRecord(session);\n }\n return this.loadFromReplayLog(id);\n }\n\n list(): IInteractiveSessionRecord[] {\n const records = this.store.list().map(fromSessionRecord);\n const seen = new Set(records.map((record) => record.id));\n for (const replayRecord of this.listReplayLogRecords()) {\n if (!seen.has(replayRecord.id)) {\n records.push(replayRecord);\n }\n }\n return records.sort(\n (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),\n );\n }\n\n delete(id: string): void {\n this.store.delete(id);\n }\n\n private loadFromReplayLog(id: string): IInteractiveSessionRecord | undefined {\n if (!this.logsDir) return undefined;\n const replay = replaySessionLogEntries(\n loadSessionLogEntries(join(this.logsDir, `${id}.jsonl`)),\n );\n if (!replay.sessionId || replay.messages.length === 0) {\n return undefined;\n }\n const backgroundTaskEvents = replay.backgroundTaskEvents as TBackgroundTaskEvent[];\n const backgroundJobGroupEvents = replay.backgroundJobGroupEvents as TBackgroundJobGroupEvent[];\n return {\n id: replay.sessionId,\n cwd: replay.cwd ?? '',\n createdAt: replay.createdAt ?? replay.updatedAt ?? new Date(0).toISOString(),\n updatedAt: replay.updatedAt ?? replay.createdAt ?? new Date(0).toISOString(),\n messages: replay.messages,\n history: replay.history,\n backgroundTasks: deriveBackgroundTasks(backgroundTaskEvents),\n backgroundTaskEvents,\n backgroundJobGroups: deriveBackgroundJobGroups(backgroundJobGroupEvents),\n backgroundJobGroupEvents,\n skillActivationEvents: [],\n memoryEvents: replay.memoryEvents as IMemoryEvent[],\n };\n }\n\n private listReplayLogRecords(): IInteractiveSessionRecord[] {\n if (!this.logsDir || !this.fs.existsSync(this.logsDir)) {\n return [];\n }\n return this.fs\n .readdirSync(this.logsDir)\n .filter((file) => file.endsWith('.jsonl'))\n .map((file) => this.loadFromReplayLog(file.slice(0, -'.jsonl'.length)))\n .filter((record): record is IInteractiveSessionRecord => record !== undefined);\n }\n}\n\nfunction getLastAssistantPreview(messages: readonly TUniversalMessage[]): string {\n for (const message of [...messages].reverse()) {\n if (message.role !== 'assistant') continue;\n if (typeof message.content !== 'string') continue;\n return message.content.replace(/[\\n\\r]+/g, ' ').trim();\n }\n return '';\n}\n\nfunction toSessionRecord(session: IInteractiveSessionRecord): ISessionRecord {\n return { ...session };\n}\n\nfunction fromSessionRecord(session: ISessionRecord): IInteractiveSessionRecord {\n return {\n id: session.id,\n ...(session.name !== undefined ? { name: session.name } : {}),\n cwd: session.cwd,\n createdAt: session.createdAt,\n updatedAt: session.updatedAt,\n messages: session.messages as TUniversalMessage[],\n ...(session.history !== undefined ? { history: session.history as IHistoryEntry[] } : {}),\n ...(session.systemPrompt !== undefined ? { systemPrompt: session.systemPrompt } : {}),\n ...(session.toolSchemas !== undefined ? { toolSchemas: session.toolSchemas } : {}),\n ...(session.backgroundTasks !== undefined\n ? { backgroundTasks: session.backgroundTasks as IBackgroundTaskState[] }\n : {}),\n ...(session.backgroundTaskEvents !== undefined\n ? { backgroundTaskEvents: session.backgroundTaskEvents as TBackgroundTaskEvent[] }\n : {}),\n ...(session.backgroundJobGroups !== undefined\n ? { backgroundJobGroups: session.backgroundJobGroups as IBackgroundJobGroupState[] }\n : {}),\n ...(session.backgroundJobGroupEvents !== undefined\n ? { backgroundJobGroupEvents: session.backgroundJobGroupEvents as TBackgroundJobGroupEvent[] }\n : {}),\n ...(session.skillActivationEvents !== undefined\n ? { skillActivationEvents: session.skillActivationEvents as ISkillActivationEvent[] }\n : {}),\n ...(session.memoryEvents !== undefined\n ? { memoryEvents: session.memoryEvents as IMemoryEvent[] }\n : {}),\n ...(session.usedMemoryReferences !== undefined\n ? { usedMemoryReferences: session.usedMemoryReferences as IMemoryReference[] }\n : {}),\n ...(session.contextReferences !== undefined\n ? { contextReferences: session.contextReferences as IContextReferenceItem[] }\n : {}),\n ...(session.sandboxSnapshotId !== undefined\n ? { sandboxSnapshotId: session.sandboxSnapshotId }\n : {}),\n };\n}\n\nfunction deriveBackgroundTasks(events: readonly TBackgroundTaskEvent[]): IBackgroundTaskState[] {\n const tasks = new Map<string, IBackgroundTaskState>();\n for (const event of events) {\n const task = getBackgroundTaskSnapshot(event);\n if (task) tasks.set(task.id, task);\n }\n return [...tasks.values()];\n}\n\nfunction getBackgroundTaskSnapshot(event: TBackgroundTaskEvent): IBackgroundTaskState | undefined {\n switch (event.type) {\n case 'background_task_created':\n case 'background_task_started':\n case 'background_task_updated':\n case 'background_task_completed':\n case 'background_task_failed':\n case 'background_task_cancelled':\n return event.task;\n default:\n return undefined;\n }\n}\n\nfunction deriveBackgroundJobGroups(\n events: readonly TBackgroundJobGroupEvent[],\n): IBackgroundJobGroupState[] {\n const groups = new Map<string, IBackgroundJobGroupState>();\n for (const event of events) {\n groups.set(event.group.id, event.group);\n }\n return [...groups.values()];\n}\n","/**\n * createQuery() — factory that returns a prompt-only convenience function.\n *\n * Usage:\n * const query = createQuery({ provider });\n * const answer = await query('What files are here?');\n */\n\nimport { InteractiveSession } from './interactive/interactive-session.js';\n\nimport type { IExecutionResult, TInteractivePermissionHandler } from './interactive/types.js';\nimport type { IAIProvider } from '@robota-sdk/agent-core';\nimport type { TPermissionMode } from '@robota-sdk/agent-core';\n\nexport interface ICreateQueryOptions {\n /** AI provider instance (required). */\n provider: IAIProvider;\n /** Working directory. Defaults to process.cwd(). */\n cwd?: string;\n /** Permission mode. Defaults to 'bypassPermissions' for programmatic use. */\n permissionMode?: TPermissionMode;\n /** Maximum agentic turns per query. */\n maxTurns?: number;\n /** Permission handler callback. */\n permissionHandler?: TInteractivePermissionHandler;\n /** Streaming text callback. */\n onTextDelta?: (delta: string) => void;\n}\n\n/**\n * Create a prompt-only query function bound to a provider.\n *\n * ```typescript\n * import { createQuery } from '@robota-sdk/agent-framework';\n * import { AnthropicProvider } from '@robota-sdk/agent-provider/anthropic';\n *\n * const query = createQuery({ provider: new AnthropicProvider({ apiKey: '...' }) });\n * const answer = await query('List all TypeScript files');\n * ```\n */\nexport function createQuery(options: ICreateQueryOptions): (prompt: string) => Promise<string> {\n const session = new InteractiveSession({\n cwd: options.cwd ?? process.cwd(),\n provider: options.provider,\n permissionMode: options.permissionMode ?? 'bypassPermissions',\n maxTurns: options.maxTurns,\n permissionHandler: options.permissionHandler,\n });\n\n if (options.onTextDelta) {\n session.on('text_delta', options.onTextDelta);\n }\n\n return async (prompt: string): Promise<string> => {\n return new Promise<string>((resolve, reject) => {\n const onComplete = (result: IExecutionResult): void => {\n cleanup();\n resolve(result.response);\n };\n const onInterrupted = (result: IExecutionResult): void => {\n cleanup();\n resolve(result.response);\n };\n const onError = (error: Error): void => {\n cleanup();\n reject(error);\n };\n const cleanup = (): void => {\n session.off('complete', onComplete);\n session.off('interrupted', onInterrupted);\n session.off('error', onError);\n };\n\n session.on('complete', onComplete);\n session.on('interrupted', onInterrupted);\n session.on('error', onError);\n\n session.submit(prompt).catch((err) => {\n cleanup();\n reject(err instanceof Error ? err : new Error(String(err)));\n });\n });\n };\n}\n","import { homedir } from 'node:os';\nimport path from 'node:path';\n\nimport { NodeFileSystemAsync } from '../adapters/node-file-system.js';\n\nimport type { IDirent, IFileSystemAsync } from '@robota-sdk/agent-core';\n\nexport const USER_LOCAL_STORAGE_CATEGORIES = [\n 'preferences',\n 'view-state',\n 'memory-projections',\n 'task-associations',\n 'workflow-metadata',\n 'inspection-index',\n] as const;\n\nexport type TUserLocalStorageCategory = (typeof USER_LOCAL_STORAGE_CATEGORIES)[number];\n\nexport interface IUserLocalStorageCategoryDefinition {\n readonly category: TUserLocalStorageCategory;\n readonly purpose: string;\n readonly mayExecuteCommands: false;\n}\n\nexport interface IUserLocalStorageItemSummary {\n readonly root: string;\n readonly category: TUserLocalStorageCategory;\n readonly key: string;\n readonly summary: string;\n readonly source: string;\n readonly scope: string;\n readonly storageLocation: string;\n readonly createdAt?: string;\n readonly lastUsedAt?: string;\n readonly enabled: boolean;\n readonly deleteAvailable: boolean;\n readonly disableAvailable: boolean;\n}\n\nexport interface IUserLocalStorageCategoryProjection {\n readonly category: TUserLocalStorageCategory;\n readonly purpose: string;\n readonly mayExecuteCommands: false;\n readonly storageLocation: string;\n readonly itemCount: number;\n readonly items: readonly IUserLocalStorageItemSummary[];\n}\n\nexport interface IUserLocalStorageInspection {\n readonly root: string;\n readonly activeRepositoryRoot: string;\n readonly categories: readonly IUserLocalStorageCategoryProjection[];\n readonly generatedAt: string;\n}\n\nexport interface IResolveUserLocalStorageRootOptions {\n readonly activeRepositoryRoot: string;\n readonly homeDir?: string;\n readonly storageRoot?: string;\n readonly fsAsync?: IFileSystemAsync;\n}\n\nexport interface IInspectUserLocalStorageOptions extends IResolveUserLocalStorageRootOptions {\n readonly now?: () => Date;\n readonly createDirectories?: boolean;\n}\n\nexport const USER_LOCAL_STORAGE_CATEGORY_DEFINITIONS: readonly IUserLocalStorageCategoryDefinition[] =\n [\n {\n category: 'preferences',\n purpose: 'User-local UI and display preferences.',\n mayExecuteCommands: false,\n },\n {\n category: 'view-state',\n purpose: 'Last selected panels, filters, and navigation state.',\n mayExecuteCommands: false,\n },\n {\n category: 'memory-projections',\n purpose: 'Inspectable local memory item projections and user choices.',\n mayExecuteCommands: false,\n },\n {\n category: 'task-associations',\n purpose: 'User-local associations between sessions, tasks, and background items.',\n mayExecuteCommands: false,\n },\n {\n category: 'workflow-metadata',\n purpose: 'Transparent workflow metadata that is not repo-owned.',\n mayExecuteCommands: false,\n },\n {\n category: 'inspection-index',\n purpose: 'Category and item summaries for user inspection and deletion.',\n mayExecuteCommands: false,\n },\n ];\n\nfunction formatIsoDate(date: Date): string {\n return date.toISOString();\n}\n\nfunction assertAbsolutePath(name: string, value: string): void {\n if (value.trim().length === 0) {\n throw new Error(`${name} must not be empty.`);\n }\n if (!path.isAbsolute(value)) {\n throw new Error(`${name} must be an absolute path: ${value}`);\n }\n}\n\nfunction resolveDefaultHomeDir(): string {\n return process.env.HOME ?? homedir();\n}\n\nfunction isEqualOrInside(parentPath: string, candidatePath: string): boolean {\n const relative = path.relative(parentPath, candidatePath);\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\nasync function resolveForComparison(absPath: string, fsAsync: IFileSystemAsync): Promise<string> {\n let current = absPath;\n\n while (path.dirname(current) !== current) {\n try {\n const realCurrent = await fsAsync.realpath(current);\n const relativeMissingPath = path.relative(current, absPath);\n return path.resolve(realCurrent, relativeMissingPath);\n } catch {\n // allow-fallback: walk up to first existing ancestor, not an error suppression\n current = path.dirname(current);\n }\n }\n\n try {\n return await fsAsync.realpath(current);\n } catch {\n // allow-fallback: filesystem root unreachable; resolve() gives a safe absolute path\n return path.resolve(absPath);\n }\n}\n\nexport async function resolveUserLocalStorageRoot(\n options: IResolveUserLocalStorageRootOptions,\n): Promise<string> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const activeRepositoryRoot = path.resolve(options.activeRepositoryRoot);\n assertAbsolutePath('activeRepositoryRoot', activeRepositoryRoot);\n\n const candidateRoot =\n options.storageRoot !== undefined\n ? options.storageRoot\n : path.join(options.homeDir ?? resolveDefaultHomeDir(), '.robota');\n\n assertAbsolutePath('userLocalStorageRoot', candidateRoot);\n\n const resolvedRoot = path.resolve(candidateRoot);\n const comparableRoot = await resolveForComparison(resolvedRoot, fsAsync);\n const comparableRepositoryRoot = await resolveForComparison(activeRepositoryRoot, fsAsync);\n\n if (isEqualOrInside(comparableRepositoryRoot, comparableRoot)) {\n throw new Error(\n `User-local storage root must be outside the active repository: ${resolvedRoot}`,\n );\n }\n\n return resolvedRoot;\n}\n\nfunction resolveCategoryLocation(root: string, category: TUserLocalStorageCategory): string {\n return path.join(root, category);\n}\n\nasync function listItemSummaries(\n root: string,\n category: TUserLocalStorageCategory,\n fsAsync: IFileSystemAsync,\n): Promise<readonly IUserLocalStorageItemSummary[]> {\n const storageLocation = resolveCategoryLocation(root, category);\n let entries: readonly IDirent[];\n\n try {\n entries = await fsAsync.readdir(storageLocation, { withFileTypes: true });\n } catch {\n // allow-fallback: missing category directory returns empty list\n return [];\n }\n\n const summaries = await Promise.all(\n entries.map(async (entry): Promise<IUserLocalStorageItemSummary> => {\n const itemLocation = path.join(storageLocation, entry.name);\n const stats = await fsAsync.stat(itemLocation);\n const key = entry.name;\n return {\n root,\n category,\n key,\n summary: `${category}/${key}`,\n source: 'user-local-storage',\n scope: 'user',\n storageLocation: itemLocation,\n createdAt: formatIsoDate(new Date(stats.birthtimeMs)),\n lastUsedAt: formatIsoDate(new Date(stats.mtimeMs)),\n enabled: true,\n deleteAvailable: true,\n disableAvailable: false,\n };\n }),\n );\n\n return summaries.sort((left, right) => left.key.localeCompare(right.key));\n}\n\nexport async function inspectUserLocalStorage(\n options: IInspectUserLocalStorageOptions,\n): Promise<IUserLocalStorageInspection> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const root = await resolveUserLocalStorageRoot(options);\n const activeRepositoryRoot = path.resolve(options.activeRepositoryRoot);\n const createDirectories = options.createDirectories ?? true;\n\n if (createDirectories) {\n await fsAsync.mkdir(root, { recursive: true });\n }\n\n const categories = await Promise.all(\n USER_LOCAL_STORAGE_CATEGORY_DEFINITIONS.map(\n async (definition): Promise<IUserLocalStorageCategoryProjection> => {\n const storageLocation = resolveCategoryLocation(root, definition.category);\n if (createDirectories) {\n await fsAsync.mkdir(storageLocation, { recursive: true });\n }\n const items = await listItemSummaries(root, definition.category, fsAsync);\n return {\n category: definition.category,\n purpose: definition.purpose,\n mayExecuteCommands: definition.mayExecuteCommands,\n storageLocation,\n itemCount: items.length,\n items,\n };\n },\n ),\n );\n\n return {\n root,\n activeRepositoryRoot,\n categories,\n generatedAt: formatIsoDate((options.now ?? (() => new Date()))()),\n };\n}\n","import type { IResolveUserLocalStorageRootOptions } from './storage.js';\n\nexport const USER_LOCAL_MEMORY_CATEGORIES = [\n 'view-preference',\n 'last-visible-cwd',\n 'background-selection',\n 'task-association',\n 'display-preference',\n 'inspection-choice',\n] as const;\n\nexport type TUserLocalMemoryCategory = (typeof USER_LOCAL_MEMORY_CATEGORIES)[number];\nexport type TUserLocalMemoryCommandExecutionEffect = 'none';\n\nexport interface IUserLocalMemoryItemProjection {\n readonly root: string;\n readonly category: TUserLocalMemoryCategory;\n readonly key: string;\n readonly summary: string;\n readonly valueSummary: string;\n readonly source: string;\n readonly scope: string;\n readonly storageLocation: string;\n readonly createdAt: string;\n readonly lastUsedAt: string;\n readonly enabled: boolean;\n readonly displayNavigationRule: string;\n readonly commandExecutionEffect: TUserLocalMemoryCommandExecutionEffect;\n readonly deleteAvailable: true;\n readonly disableAvailable: true;\n}\n\nexport interface IUserLocalMemoryListProjection {\n readonly root: string;\n readonly activeRepositoryRoot: string;\n readonly items: readonly IUserLocalMemoryItemProjection[];\n}\n\nexport interface IUserLocalMemorySetOptions extends IResolveUserLocalStorageRootOptions {\n readonly category: TUserLocalMemoryCategory;\n readonly key: string;\n readonly value: string;\n readonly summary: string;\n readonly source: string;\n readonly scope?: string;\n readonly now?: () => Date;\n}\n\nexport interface IUserLocalMemoryItemOptions extends IResolveUserLocalStorageRootOptions {\n readonly category: TUserLocalMemoryCategory;\n readonly key: string;\n readonly now?: () => Date;\n}\n\nexport interface IUserLocalMemoryListOptions extends IResolveUserLocalStorageRootOptions {\n readonly now?: () => Date;\n}\n\nexport interface IUserLocalMemoryDeleteResult {\n readonly category: TUserLocalMemoryCategory;\n readonly key: string;\n readonly deleted: boolean;\n}\n\nexport interface IUserLocalMemoryFile {\n readonly schemaVersion: 1;\n readonly category: TUserLocalMemoryCategory;\n readonly key: string;\n readonly value: string;\n readonly summary: string;\n readonly source: string;\n readonly scope: string;\n readonly createdAt: string;\n readonly lastUsedAt: string;\n readonly enabled: boolean;\n}\n","import path from 'node:path';\n\nimport {\n USER_LOCAL_MEMORY_CATEGORIES,\n type IUserLocalMemoryDeleteResult,\n type IUserLocalMemoryFile,\n type IUserLocalMemoryItemOptions,\n type IUserLocalMemoryItemProjection,\n type IUserLocalMemoryListOptions,\n type IUserLocalMemoryListProjection,\n type IUserLocalMemorySetOptions,\n type TUserLocalMemoryCategory,\n} from './memory-types.js';\nimport { resolveUserLocalStorageRoot } from './storage.js';\nimport { NodeFileSystemAsync } from '../adapters/node-file-system.js';\n\nimport type { IResolveUserLocalStorageRootOptions } from './storage.js';\nimport type { IDirent, IFileSystemAsync } from '@robota-sdk/agent-core';\n\ntype TJsonValue =\n | string\n | number\n | boolean\n | null\n | readonly TJsonValue[]\n | { readonly [key: string]: TJsonValue };\ntype TJsonRecord = { readonly [key: string]: TJsonValue };\n\nconst MEMORY_STORAGE_CATEGORY = 'memory-projections';\nconst FILE_EXTENSION = '.json';\nconst MEMORY_SCHEMA_VERSION = 1;\nconst MAX_SEGMENT_LENGTH = 80;\nconst MAX_SUMMARY_LENGTH = 240;\nconst MAX_SOURCE_LENGTH = 80;\nconst MAX_SCOPE_LENGTH = 120;\nconst MAX_VALUE_SUMMARY_LENGTH = 240;\nconst DEFAULT_SCOPE = 'user';\nconst SAFE_SEGMENT_PATTERN = /^[a-z0-9][a-z0-9._-]*$/u;\n\nconst DISPLAY_NAVIGATION_RULES: Record<TUserLocalMemoryCategory, string> = {\n 'view-preference': 'May affect UI panel, filter, density, or sorting display/navigation only.',\n 'last-visible-cwd': 'May display or preselect an already visible workspace context only.',\n 'background-selection': 'May restore the selected background entry in local UI only.',\n 'task-association': 'May group visible tasks by a local association only.',\n 'display-preference': 'May affect local text wrapping, compactness, or visibility only.',\n 'inspection-choice': 'May affect inspection display choices only.',\n};\n\nfunction formatIsoDate(date: Date): string {\n return date.toISOString();\n}\n\nfunction isUserLocalMemoryCategory(value: string): value is TUserLocalMemoryCategory {\n return USER_LOCAL_MEMORY_CATEGORIES.includes(value as TUserLocalMemoryCategory);\n}\n\nfunction assertUserLocalMemoryCategory(value: string): TUserLocalMemoryCategory {\n if (!isUserLocalMemoryCategory(value)) {\n throw new Error(`Unsupported user-local memory category: ${value}`);\n }\n return value;\n}\n\nfunction assertSafeSegment(name: string, value: string): string {\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n throw new Error(`${name} must not be empty.`);\n }\n if (trimmed.length > MAX_SEGMENT_LENGTH || !SAFE_SEGMENT_PATTERN.test(trimmed)) {\n throw new Error(\n `${name} must use lowercase letters, numbers, dots, underscores, or hyphens: ${value}`,\n );\n }\n return trimmed;\n}\n\nfunction boundedText(name: string, value: string, maxLength: number): string {\n const normalized = value.trim().replace(/\\s+/g, ' ');\n if (normalized.length === 0) {\n throw new Error(`${name} must not be empty.`);\n }\n if (normalized.length > maxLength) {\n return normalized.slice(0, maxLength);\n }\n return normalized;\n}\n\nfunction summarizeValue(value: string): string {\n return boundedText('value', value, MAX_VALUE_SUMMARY_LENGTH);\n}\n\nfunction memoryFileName(category: TUserLocalMemoryCategory, key: string): string {\n return `${category}__${key}${FILE_EXTENSION}`;\n}\n\nasync function resolveMemoryRoot(\n options: IResolveUserLocalStorageRootOptions,\n): Promise<{ readonly root: string; readonly memoryRoot: string }> {\n const root = await resolveUserLocalStorageRoot(options);\n return {\n root,\n memoryRoot: path.join(root, MEMORY_STORAGE_CATEGORY),\n };\n}\n\nfunction parseMemoryRecord(raw: string, storageLocation: string): IUserLocalMemoryFile {\n const record = JSON.parse(raw) as TJsonRecord;\n const category = readString(record, 'category');\n const schemaVersion = record['schemaVersion'];\n\n if (schemaVersion !== MEMORY_SCHEMA_VERSION) {\n throw new Error(`Unsupported user-local memory schema at ${storageLocation}`);\n }\n\n return {\n schemaVersion: MEMORY_SCHEMA_VERSION,\n category: assertUserLocalMemoryCategory(category),\n key: readString(record, 'key'),\n value: readString(record, 'value'),\n summary: readString(record, 'summary'),\n source: readString(record, 'source'),\n scope: readString(record, 'scope'),\n createdAt: readString(record, 'createdAt'),\n lastUsedAt: readString(record, 'lastUsedAt'),\n enabled: readBoolean(record, 'enabled'),\n };\n}\n\nfunction readString(record: TJsonRecord, key: string): string {\n const value = record[key];\n if (typeof value !== 'string') {\n throw new Error(`Invalid user-local memory field: ${key}`);\n }\n return value;\n}\n\nfunction readBoolean(record: TJsonRecord, key: string): boolean {\n const value = record[key];\n if (typeof value !== 'boolean') {\n throw new Error(`Invalid user-local memory field: ${key}`);\n }\n return value;\n}\n\nfunction projectMemoryItem(\n root: string,\n storageLocation: string,\n item: IUserLocalMemoryFile,\n): IUserLocalMemoryItemProjection {\n return {\n root,\n category: item.category,\n key: item.key,\n summary: item.summary,\n valueSummary: summarizeValue(item.value),\n source: item.source,\n scope: item.scope,\n storageLocation,\n createdAt: item.createdAt,\n lastUsedAt: item.lastUsedAt,\n enabled: item.enabled,\n displayNavigationRule: DISPLAY_NAVIGATION_RULES[item.category],\n commandExecutionEffect: 'none',\n deleteAvailable: true,\n disableAvailable: true,\n };\n}\n\nasync function readMemoryFile(\n root: string,\n storageLocation: string,\n fsAsync: IFileSystemAsync,\n): Promise<IUserLocalMemoryItemProjection> {\n return projectMemoryItem(\n root,\n storageLocation,\n parseMemoryRecord(await fsAsync.readFile(storageLocation, 'utf8'), storageLocation),\n );\n}\n\nasync function resolveMemoryFile(\n options: IUserLocalMemoryItemOptions,\n): Promise<{ readonly root: string; readonly storageLocation: string }> {\n const category = assertUserLocalMemoryCategory(options.category);\n const key = assertSafeSegment('key', options.key);\n const { root, memoryRoot } = await resolveMemoryRoot(options);\n return {\n root,\n storageLocation: path.join(memoryRoot, memoryFileName(category, key)),\n };\n}\n\nexport async function setUserLocalMemoryItem(\n options: IUserLocalMemorySetOptions,\n): Promise<IUserLocalMemoryItemProjection> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const category = assertUserLocalMemoryCategory(options.category);\n const key = assertSafeSegment('key', options.key);\n const summary = boundedText('summary', options.summary, MAX_SUMMARY_LENGTH);\n const source = boundedText('source', options.source, MAX_SOURCE_LENGTH);\n const scope = boundedText('scope', options.scope ?? DEFAULT_SCOPE, MAX_SCOPE_LENGTH);\n const value = summarizeValue(options.value);\n const now = formatIsoDate((options.now ?? (() => new Date()))());\n const { root, memoryRoot } = await resolveMemoryRoot(options);\n const storageLocation = path.join(memoryRoot, memoryFileName(category, key));\n let createdAt = now;\n\n try {\n const existing = parseMemoryRecord(\n await fsAsync.readFile(storageLocation, 'utf8'),\n storageLocation,\n );\n createdAt = existing.createdAt;\n } catch (error) {\n if (error instanceof Error && error.message.includes('ENOENT')) {\n createdAt = now;\n } else {\n throw error;\n }\n }\n\n const item: IUserLocalMemoryFile = {\n schemaVersion: MEMORY_SCHEMA_VERSION,\n category,\n key,\n value,\n summary,\n source,\n scope,\n createdAt,\n lastUsedAt: now,\n enabled: true,\n };\n\n await fsAsync.mkdir(memoryRoot, { recursive: true });\n await fsAsync.writeFile(storageLocation, `${JSON.stringify(item, null, 2)}\\n`, 'utf8');\n return projectMemoryItem(root, storageLocation, item);\n}\n\nexport async function listUserLocalMemoryItems(\n options: IUserLocalMemoryListOptions,\n): Promise<IUserLocalMemoryListProjection> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const { root, memoryRoot } = await resolveMemoryRoot(options);\n let entries: readonly IDirent[];\n\n try {\n entries = await fsAsync.readdir(memoryRoot, { withFileTypes: true });\n } catch {\n // allow-fallback: missing memory directory means no items exist\n entries = [];\n }\n\n const items = await Promise.all(\n entries\n .filter((entry) => entry.isFile() && entry.name.endsWith(FILE_EXTENSION))\n .map((entry) => readMemoryFile(root, path.join(memoryRoot, entry.name), fsAsync)),\n );\n\n return {\n root,\n activeRepositoryRoot: path.resolve(options.activeRepositoryRoot),\n items: items.sort((left, right) =>\n `${left.category}/${left.key}`.localeCompare(`${right.category}/${right.key}`),\n ),\n };\n}\n\nexport async function inspectUserLocalMemoryItem(\n options: IUserLocalMemoryItemOptions,\n): Promise<IUserLocalMemoryItemProjection> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const { root, storageLocation } = await resolveMemoryFile(options);\n return readMemoryFile(root, storageLocation, fsAsync);\n}\n\nexport async function disableUserLocalMemoryItem(\n options: IUserLocalMemoryItemOptions,\n): Promise<IUserLocalMemoryItemProjection> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const { root, storageLocation } = await resolveMemoryFile(options);\n const existing = parseMemoryRecord(\n await fsAsync.readFile(storageLocation, 'utf8'),\n storageLocation,\n );\n const disabled: IUserLocalMemoryFile = {\n ...existing,\n enabled: false,\n lastUsedAt: formatIsoDate((options.now ?? (() => new Date()))()),\n };\n\n await fsAsync.writeFile(storageLocation, `${JSON.stringify(disabled, null, 2)}\\n`, 'utf8');\n return projectMemoryItem(root, storageLocation, disabled);\n}\n\nexport async function deleteUserLocalMemoryItem(\n options: IUserLocalMemoryItemOptions,\n): Promise<IUserLocalMemoryDeleteResult> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const { storageLocation } = await resolveMemoryFile(options);\n await fsAsync.rm(storageLocation);\n return {\n category: options.category,\n key: options.key,\n deleted: true,\n };\n}\n\nexport async function readEnabledUserLocalMemoryItem(\n options: IUserLocalMemoryItemOptions,\n): Promise<IUserLocalMemoryItemProjection | null> {\n const item = await inspectUserLocalMemoryItem(options);\n return item.enabled ? item : null;\n}\n","export type TSelfHostingVerificationPhase =\n | 'checkpoint'\n | 'edit'\n | 'handoff'\n | 'verify'\n | 'recover';\n\nexport type TSelfHostingLoopState =\n | 'idle'\n | 'checkpointed'\n | 'editing'\n | 'verifying'\n | 'passed'\n | 'failed'\n | 'rolled_back'\n | 'cancelled';\n\nexport type TSelfHostingLoopEvent =\n | 'checkpoint_created'\n | 'edits_started'\n | 'edits_applied'\n | 'verify_passed'\n | 'verify_failed'\n | 'rollback_completed'\n | 'cancelled';\n\nexport interface ISelfHostingVerificationPlanInput {\n changedFiles: readonly string[];\n packageScopes?: readonly string[];\n baseRef?: string;\n}\n\nexport interface ISelfHostingVerificationStep {\n id: string;\n phase: TSelfHostingVerificationPhase;\n description: string;\n required: boolean;\n command?: string;\n}\n\nexport interface ISelfHostingVerificationPlan {\n changedFiles: readonly string[];\n packageScopes: readonly string[];\n baseRef: string;\n steps: readonly ISelfHostingVerificationStep[];\n}\n\nconst DEFAULT_BASE_REF = 'origin/develop';\nconst PACKAGE_VERIFY_COMMANDS = ['test', 'typecheck', 'build'] as const;\n\nconst TRANSITIONS: Record<\n TSelfHostingLoopState,\n Partial<Record<TSelfHostingLoopEvent, TSelfHostingLoopState>>\n> = {\n idle: {\n checkpoint_created: 'checkpointed',\n cancelled: 'cancelled',\n },\n checkpointed: {\n edits_started: 'editing',\n cancelled: 'cancelled',\n },\n editing: {\n edits_applied: 'verifying',\n verify_failed: 'failed',\n cancelled: 'cancelled',\n },\n verifying: {\n verify_passed: 'passed',\n verify_failed: 'failed',\n cancelled: 'cancelled',\n },\n passed: {},\n failed: {\n rollback_completed: 'rolled_back',\n cancelled: 'cancelled',\n },\n rolled_back: {},\n cancelled: {},\n};\n\nfunction normalizePackageScopes(packageScopes: readonly string[] | undefined): readonly string[] {\n if (!packageScopes) {\n return [];\n }\n return Array.from(new Set(packageScopes.map((scope) => scope.trim()).filter(Boolean)));\n}\n\nfunction packageVerificationSteps(\n packageScopes: readonly string[],\n): ISelfHostingVerificationStep[] {\n return packageScopes.flatMap((scope) =>\n PACKAGE_VERIFY_COMMANDS.map(\n (commandName): ISelfHostingVerificationStep => ({\n id: `package-${commandName}:${scope}`,\n phase: 'verify',\n description: `Run ${commandName} for ${scope} in a child process against the new on-disk tree.`,\n required: true,\n command: `pnpm --filter ${scope} ${commandName}`,\n }),\n ),\n );\n}\n\nfunction preVerificationSteps(): ISelfHostingVerificationStep[] {\n return [\n {\n id: 'checkpoint',\n phase: 'checkpoint',\n description: 'Create a recoverable turn-level checkpoint before the first mutation.',\n required: true,\n },\n {\n id: 'atomic-edit',\n phase: 'edit',\n description:\n 'Apply Write/Edit mutations through same-directory temp files and atomic rename.',\n required: true,\n },\n {\n id: 'handoff',\n phase: 'handoff',\n description:\n 'Keep the current process on already-loaded code and run verification child processes against disk.',\n required: true,\n },\n ];\n}\n\nfunction harnessVerificationStep(baseRef: string): ISelfHostingVerificationStep {\n return {\n id: 'harness-verify',\n phase: 'verify',\n description: 'Run Robota harness verification as the local CI-like gate.',\n required: true,\n command: `pnpm harness:verify -- --base-ref ${baseRef} --skip-record-check`,\n };\n}\n\nfunction rollbackRecoveryStep(): ISelfHostingVerificationStep {\n return {\n id: 'rollback-on-failure',\n phase: 'recover',\n description: 'Use the existing edit checkpoint restore path if verification fails.',\n required: true,\n };\n}\n\nexport function planSelfHostingVerification(\n input: ISelfHostingVerificationPlanInput,\n): ISelfHostingVerificationPlan {\n if (input.changedFiles.length === 0) {\n throw new Error('Self-hosting verification requires at least one changed file.');\n }\n\n const baseRef = input.baseRef ?? DEFAULT_BASE_REF;\n const packageScopes = normalizePackageScopes(input.packageScopes);\n const steps: ISelfHostingVerificationStep[] = [\n ...preVerificationSteps(),\n ...packageVerificationSteps(packageScopes),\n harnessVerificationStep(baseRef),\n rollbackRecoveryStep(),\n ];\n\n return {\n changedFiles: [...input.changedFiles],\n packageScopes,\n baseRef,\n steps,\n };\n}\n\nexport function transitionSelfHostingLoop(\n state: TSelfHostingLoopState,\n event: TSelfHostingLoopEvent,\n): TSelfHostingLoopState {\n const nextState = TRANSITIONS[state][event];\n if (!nextState) {\n throw new Error(`Invalid self-hosting loop transition: ${state} -> ${event}`);\n }\n return nextState;\n}\n","import { createZodFunctionTool } from '@robota-sdk/agent-tools';\nimport { z } from 'zod';\n\nimport {\n normalizeModelCommandName,\n stringifyModelCommandResult,\n} from './model-command-tool-projection.js';\n\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { ICommandResult } from '../commands/index.js';\nimport type { IZodSchema } from '@robota-sdk/agent-tools';\n\ninterface ICommandExecutionArgs {\n command: string;\n args?: string;\n}\n\ntype TModelCommandDescriptor = Pick<ICapabilityDescriptor, 'name' | 'description' | 'argumentHint'>;\n\nexport interface ICommandExecutionToolDeps {\n isModelInvocable: (command: string) => boolean;\n execute: (command: string, args: string) => Promise<ICommandResult | null>;\n commandNames?: readonly string[];\n commandDescriptors?: readonly TModelCommandDescriptor[];\n}\n\nfunction asZodSchema(schema: z.ZodType): IZodSchema {\n return schema as IZodSchema;\n}\n\nfunction toNonEmptyCommandNames(\n commandNames?: readonly string[],\n): [string, ...string[]] | undefined {\n if (!commandNames || commandNames.length === 0) return undefined;\n const [first, ...rest] = commandNames;\n if (first === undefined) return undefined;\n return [first, ...rest];\n}\n\nfunction createCommandExecutionSchema(\n commandNames?: readonly string[],\n): z.ZodType<ICommandExecutionArgs> {\n const validCommandNames = toNonEmptyCommandNames(commandNames);\n const commandSchema =\n validCommandNames !== undefined\n ? z.enum(validCommandNames).describe('Registered model-invocable command name to execute')\n : z.string().describe('Registered model-invocable command name to execute');\n\n return z.object({\n command: commandSchema,\n args: z.string().optional().describe('Arguments to pass to the command'),\n });\n}\n\nfunction getCommandNames(deps: ICommandExecutionToolDeps): readonly string[] | undefined {\n if (deps.commandNames !== undefined) return deps.commandNames;\n if (deps.commandDescriptors === undefined) return undefined;\n return deps.commandDescriptors.map((descriptor) => normalizeModelCommandName(descriptor.name));\n}\n\nfunction formatCommandDescriptor(descriptor: TModelCommandDescriptor): string {\n const commandName = normalizeModelCommandName(descriptor.name);\n const argumentHint = descriptor.argumentHint ? ` ${descriptor.argumentHint}` : '';\n return `- ${commandName}${argumentHint}: ${descriptor.description}`;\n}\n\nfunction createToolDescription(commandDescriptors?: readonly TModelCommandDescriptor[]): string {\n const base =\n 'Executes a registered model-invocable Robota command through the command registry. Accepted command names and argument grammar come from registered command descriptors.';\n if (commandDescriptors === undefined || commandDescriptors.length === 0) return base;\n return [\n base,\n 'Use the registered command descriptors below as the authority for when to call this tool.',\n '',\n 'Registered model-invocable commands:',\n ...commandDescriptors.map(formatCommandDescriptor),\n ].join('\\n');\n}\n\nexport function createCommandExecutionTool(\n deps: ICommandExecutionToolDeps,\n): ReturnType<typeof createZodFunctionTool> {\n const commandExecutionSchema = createCommandExecutionSchema(getCommandNames(deps));\n return createZodFunctionTool(\n 'ExecuteCommand',\n createToolDescription(deps.commandDescriptors),\n asZodSchema(commandExecutionSchema),\n async (params) => {\n const args: ICommandExecutionArgs = commandExecutionSchema.parse(params);\n const command = normalizeModelCommandName(args.command);\n if (!deps.isModelInvocable(command)) {\n return JSON.stringify({\n success: false,\n command,\n error: `Command is not model-invocable: ${command}`,\n });\n }\n return stringifyModelCommandResult(command, await deps.execute(command, args.args ?? ''));\n },\n );\n}\n","/**\n * Interactive permission prompt — asks the user whether to allow a tool invocation\n * using an arrow-key selector. Canonical implementation (SSOT).\n * Used by both agent-sdk query() and agent-cli.\n */\n\nimport type { ITerminalOutput } from '../types.js';\nimport type { TToolArgs } from '@robota-sdk/agent-core';\n\nconst PERMISSION_OPTIONS = ['Allow', 'Deny'];\nconst ALLOW_INDEX = 0;\n\nfunction formatArgs(toolArgs: TToolArgs): string {\n const entries = Object.entries(toolArgs);\n if (entries.length === 0) {\n return '(no arguments)';\n }\n return entries\n .map(([k, v]) => `${k}: ${typeof v === 'string' ? v : JSON.stringify(v)}`)\n .join(', ');\n}\n\nexport async function promptForApproval(\n terminal: ITerminalOutput,\n toolName: string,\n toolArgs: TToolArgs,\n): Promise<boolean> {\n terminal.writeLine('');\n terminal.writeError(`[Permission Required] Tool: ${toolName}`);\n terminal.writeLine(` ${formatArgs(toolArgs)}`);\n terminal.writeLine('');\n\n const selected = await terminal.select(PERMISSION_OPTIONS, ALLOW_INDEX);\n return selected === ALLOW_INDEX;\n}\n","import type { IInteractiveSession } from '../interactive/i-interactive-session.js';\n\nconst EMPTY_CONTEXT_STATE = {\n usedTokens: 0,\n maxTokens: 200000,\n usedPercentage: 0,\n remainingPercentage: 100,\n};\n\nconst EMPTY_EXECUTION_WORKSPACE = {\n sessionId: 'test-session-id',\n updatedAt: new Date().toISOString(),\n entries: [] as [],\n};\n\nconst EMPTY_BACKGROUND_GROUP = {\n id: '',\n parentSessionId: 'test-session-id',\n waitPolicy: 'wait_all' as const,\n taskIds: [],\n status: 'completed' as const,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n results: [],\n};\n\n/** Creates a stub IInteractiveSession for use in tests. All methods return sensible defaults.\n * Pass overrides to spy on or replace specific methods. */\nexport function createTestInteractiveSession(\n overrides?: Partial<IInteractiveSession>,\n): IInteractiveSession {\n const base: IInteractiveSession = {\n submit: () => Promise.resolve(),\n abort: () => {},\n cancelQueue: () => {},\n shutdown: () => Promise.resolve(),\n isExecuting: () => false,\n getPendingPrompt: () => null,\n getMessages: () => [],\n getContextState: () => ({ ...EMPTY_CONTEXT_STATE }),\n getSession: () => ({ getSessionId: () => 'test-session-id' }),\n getCwd: () => '/workspace',\n executeCommand: () => Promise.resolve(null),\n listCommands: () => [],\n on: () => {},\n off: () => {},\n listBackgroundTasks: () => [],\n getBackgroundTask: () => undefined,\n cancelBackgroundTask: () => Promise.resolve(),\n closeBackgroundTask: () => Promise.resolve(),\n sendBackgroundTask: () => Promise.resolve(),\n readBackgroundTaskLog: () => Promise.resolve({ taskId: '', lines: [] }),\n listBackgroundJobGroups: () => [],\n getBackgroundJobGroup: () => undefined,\n createBackgroundJobGroup: () => ({ ...EMPTY_BACKGROUND_GROUP }),\n waitBackgroundJobGroup: () => Promise.resolve({ ...EMPTY_BACKGROUND_GROUP }),\n getExecutionWorkspaceSnapshot: () => ({ ...EMPTY_EXECUTION_WORKSPACE }),\n listAgentDefinitions: () => [],\n listAgentJobs: () => [],\n spawnAgentJob: () =>\n Promise.resolve({\n id: 'agent_1',\n type: 'general-purpose',\n label: 'general-purpose',\n parentSessionId: 'test-session-id',\n status: 'running' as const,\n mode: 'background' as const,\n depth: 1,\n cwd: '/workspace',\n promptPreview: '',\n updatedAt: new Date().toISOString(),\n }),\n sendAgentJob: () => Promise.resolve(),\n cancelAgentJob: () => Promise.resolve(),\n closeAgentJob: () => Promise.resolve(),\n ...overrides,\n };\n return base;\n}\n","import { deleteSettings, getUserSettingsPath } from './settings-io.js';\n\nexport interface IResetUserConfigResult {\n deleted: boolean;\n path: string;\n}\n\nexport function resetUserConfig(): IResetUserConfigResult {\n const path = getUserSettingsPath();\n const deleted = deleteSettings(path);\n return { deleted, path };\n}\n","import { existsSync, lstatSync, readFileSync } from 'node:fs';\nimport { dirname, isAbsolute, join, resolve } from 'node:path';\n\nconst DETACHED_HEAD_LENGTH = 7;\n\nexport function resolveGitBranch(cwd: string): string | undefined {\n try {\n const gitDir = findGitDir(cwd);\n if (!gitDir) return undefined;\n\n const head = readFileSync(join(gitDir, 'HEAD'), 'utf8').trim();\n if (!head) return undefined;\n if (head.startsWith('ref: ')) {\n const ref = head.slice('ref: '.length).trim();\n const branchPrefix = 'refs/heads/';\n return ref.startsWith(branchPrefix) ? ref.slice(branchPrefix.length) : ref;\n }\n return head.slice(0, DETACHED_HEAD_LENGTH);\n } catch {\n // allow-fallback: git I/O failures are non-fatal; return undefined to skip branch display\n return undefined;\n }\n}\n\nfunction findGitDir(start: string): string | undefined {\n let current = resolve(start);\n let parent = dirname(current);\n\n while (parent !== current) {\n const candidate = join(current, '.git');\n const resolved = resolveGitMetadata(candidate, current);\n if (resolved) return resolved;\n\n current = parent;\n parent = dirname(current);\n }\n\n const rootCandidate = join(current, '.git');\n return resolveGitMetadata(rootCandidate, current);\n}\n\nfunction resolveGitMetadata(candidate: string, repoDir: string): string | undefined {\n if (!existsSync(candidate)) return undefined;\n const stat = lstatSync(candidate);\n if (stat.isDirectory()) return candidate;\n if (!stat.isFile()) return undefined;\n\n const content = readFileSync(candidate, 'utf8').trim();\n const prefix = 'gitdir:';\n if (!content.startsWith(prefix)) return undefined;\n const rawPath = content.slice(prefix.length).trim();\n return isAbsolute(rawPath) ? rawPath : resolve(repoDir, rawPath);\n}\n","interface IParsedSemver {\n major: number;\n minor: number;\n patch: number;\n prerelease: string[];\n}\n\nexport function compareSemverVersions(left: string, right: string): number {\n const parsedLeft = parseSemver(left);\n const parsedRight = parseSemver(right);\n if (parsedLeft === undefined || parsedRight === undefined) {\n return Math.sign(left.localeCompare(right));\n }\n\n const coreCompare =\n compareNumber(parsedLeft.major, parsedRight.major) ||\n compareNumber(parsedLeft.minor, parsedRight.minor) ||\n compareNumber(parsedLeft.patch, parsedRight.patch);\n if (coreCompare !== 0) {\n return coreCompare;\n }\n\n return comparePrerelease(parsedLeft.prerelease, parsedRight.prerelease);\n}\n\nexport function isNewerSemverVersion(candidate: string, current: string): boolean {\n return compareSemverVersions(candidate, current) > 0;\n}\n\nfunction parseSemver(value: string): IParsedSemver | undefined {\n const normalized = value.trim().replace(/^v/, '').split('+')[0] ?? '';\n const [core, prereleaseText] = normalized.split('-', 2);\n const [majorText, minorText, patchText] = core.split('.');\n const major = parseNumericIdentifier(majorText);\n const minor = parseNumericIdentifier(minorText);\n const patch = parseNumericIdentifier(patchText);\n if (major === undefined || minor === undefined || patch === undefined) {\n return undefined;\n }\n return {\n major,\n minor,\n patch,\n prerelease: prereleaseText ? prereleaseText.split('.') : [],\n };\n}\n\nfunction parseNumericIdentifier(value: string | undefined): number | undefined {\n if (value === undefined || !/^\\d+$/.test(value)) {\n return undefined;\n }\n return Number(value);\n}\n\nfunction compareNumber(left: number, right: number): number {\n return Math.sign(left - right);\n}\n\nfunction comparePrerelease(left: string[], right: string[]): number {\n if (left.length === 0 && right.length === 0) {\n return 0;\n }\n if (left.length === 0) {\n return 1;\n }\n if (right.length === 0) {\n return -1;\n }\n const max = Math.max(left.length, right.length);\n for (let index = 0; index < max; index += 1) {\n const leftPart = left[index];\n const rightPart = right[index];\n if (leftPart === undefined) {\n return -1;\n }\n if (rightPart === undefined) {\n return 1;\n }\n const partCompare = comparePrereleaseIdentifier(leftPart, rightPart);\n if (partCompare !== 0) {\n return partCompare;\n }\n }\n return 0;\n}\n\nfunction comparePrereleaseIdentifier(left: string, right: string): number {\n const leftNumber = parseNumericIdentifier(left);\n const rightNumber = parseNumericIdentifier(right);\n if (leftNumber !== undefined && rightNumber !== undefined) {\n return compareNumber(leftNumber, rightNumber);\n }\n if (leftNumber !== undefined) {\n return -1;\n }\n if (rightNumber !== undefined) {\n return 1;\n }\n return Math.sign(left.localeCompare(right));\n}\n","import {\n createDefaultBackgroundTaskRunners,\n type IBackgroundTaskRunner,\n} from '@robota-sdk/agent-executor';\n\nimport { getUserSettingsPath, readSettings, writeSettings } from '../config/settings-io.js';\nimport { createProjectSessionStore } from '../interactive/session-persistence.js';\n\nimport type { ICommandHostAdapters, ICommandModule } from '../commands/index.js';\nimport type { CommandRegistry } from '../commands/index.js';\nimport type { IInteractiveSession, IInteractiveSessionStore } from '../interactive/index.js';\nimport type { TSubagentRunnerFactory } from '../subagents/index.js';\nimport type { IAIProvider } from '@robota-sdk/agent-core';\nimport type { ITransportRegistryView } from '@robota-sdk/agent-interface-transport';\n\nexport interface IAgentRuntimeConfig {\n cwd: string;\n provider: IAIProvider;\n commandModules?: readonly ICommandModule[];\n commandHostAdapters?: ICommandHostAdapters;\n backgroundTaskRunners?: IBackgroundTaskRunner[];\n subagentRunnerFactory?: TSubagentRunnerFactory;\n sessionStore?: IInteractiveSessionStore;\n transportRegistry?: ITransportRegistryView<IInteractiveSession>;\n reloadPluginCommandSource?: (registry: CommandRegistry) => void;\n}\n\nexport interface IAgentRuntime {\n readonly cwd: string;\n readonly provider: IAIProvider;\n readonly commandModules: readonly ICommandModule[];\n readonly commandHostAdapters: ICommandHostAdapters;\n readonly backgroundTaskRunners: IBackgroundTaskRunner[];\n readonly subagentRunnerFactory: TSubagentRunnerFactory | undefined;\n readonly sessionStore: IInteractiveSessionStore | undefined;\n readonly transportRegistry: ITransportRegistryView<IInteractiveSession> | undefined;\n readonly reloadPluginCommandSource: (registry: CommandRegistry) => void;\n}\n\nexport function createAgentRuntime(config: IAgentRuntimeConfig): IAgentRuntime {\n const settingsPath = getUserSettingsPath();\n const defaultCommandHostAdapters: ICommandHostAdapters = {\n settings: {\n read: () => readSettings(settingsPath),\n write: (settings) => writeSettings(settingsPath, settings),\n },\n };\n\n return {\n cwd: config.cwd,\n provider: config.provider,\n commandModules: config.commandModules ?? [],\n commandHostAdapters: config.commandHostAdapters ?? defaultCommandHostAdapters,\n backgroundTaskRunners: config.backgroundTaskRunners ?? createDefaultBackgroundTaskRunners(),\n subagentRunnerFactory: config.subagentRunnerFactory,\n sessionStore:\n 'sessionStore' in config ? config.sessionStore : createProjectSessionStore(config.cwd),\n transportRegistry: config.transportRegistry,\n reloadPluginCommandSource: config.reloadPluginCommandSource ?? (() => {}),\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport function readPackageVersion(importMetaUrl: string): string {\n const dir = dirname(fileURLToPath(importMetaUrl));\n const candidates = [join(dir, '..', '..', 'package.json'), join(dir, '..', 'package.json')];\n\n for (const pkgPath of candidates) {\n try {\n const raw = readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(raw) as { version?: string; name?: string };\n if (pkg.version !== undefined && pkg.name !== undefined) {\n return pkg.version;\n }\n } catch {\n // allow-fallback: package.json absent at this candidate path; advance to next\n continue;\n }\n }\n\n return '0.0.0'; // allow-fallback: version display must not crash startup when no package.json found\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { compareSemverVersions, isNewerSemverVersion } from '../utils/semver-compare.js';\n\nexport const CLI_UPDATE_PACKAGE_NAME = '@robota-sdk/agent-cli';\nexport const CLI_UPDATE_REGISTRY_URL = 'https://registry.npmjs.org';\nconst HOURS_PER_DAY = 24;\nconst MINUTES_PER_HOUR = 60;\nconst SECONDS_PER_MINUTE = 60;\nconst MS_PER_SECOND = 1000;\nexport const CLI_UPDATE_CACHE_TTL_MS =\n HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND;\nexport const CLI_UPDATE_TIMEOUT_MS = 1500;\n\nconst DEFAULT_INSTALL_COMMAND = \"npm install -g '@robota-sdk/agent-cli@latest'\";\n\nexport interface ICliUpdateNotice {\n currentVersion: string;\n latestVersion: string;\n installCommand: string;\n}\n\nexport interface IUpdateCheckCache {\n packageName: string;\n checkedAt: string;\n currentVersion: string;\n latestVersion?: string;\n errorMessage?: string;\n}\n\nexport type TCliUpdateCheckResult =\n | { status: 'skipped'; reason: 'disabled' }\n | { status: 'current'; currentVersion: string; latestVersion: string }\n | { status: 'update_available'; notice: ICliUpdateNotice }\n | { status: 'error'; errorMessage: string };\n\nexport interface ICheckForCliUpdateOptions {\n currentVersion: string;\n disabled?: boolean;\n force?: boolean;\n cachePath?: string;\n now?: Date;\n ttlMs?: number;\n timeoutMs?: number;\n registryUrl?: string;\n packageName?: string;\n fetchImpl?: typeof fetch;\n}\n\nexport interface IStartupCliUpdatePolicyInput {\n printMode: boolean;\n disableUpdateCheck: boolean;\n}\n\ninterface INpmPackageMetadata {\n 'dist-tags'?: {\n latest?: TJsonValue;\n };\n}\nexport { compareSemverVersions, isNewerSemverVersion };\n\ntype TJsonValue =\n | string\n | number\n | boolean\n | null\n | readonly TJsonValue[]\n | { readonly [key: string]: TJsonValue };\n\nexport function getUserUpdateCheckCachePath(\n home = process.env.HOME ?? process.env.USERPROFILE ?? '/',\n): string {\n return join(home, '.robota', 'update-check.json');\n}\n\nexport function readUpdateCheckCache(path: string): IUpdateCheckCache | undefined {\n if (!existsSync(path)) {\n return undefined;\n }\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8')) as TJsonValue;\n return parseUpdateCheckCache(parsed);\n } catch {\n // allow-fallback: corrupt cache must not block startup; silently discard and re-fetch\n return undefined;\n }\n}\n\nexport function writeUpdateCheckCache(path: string, cache: IUpdateCheckCache): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(cache, null, 2) + '\\n', 'utf8');\n}\n\nexport async function checkForCliUpdate(\n options: ICheckForCliUpdateOptions,\n): Promise<TCliUpdateCheckResult> {\n if (options.disabled === true) {\n return { status: 'skipped', reason: 'disabled' };\n }\n\n const packageName = options.packageName ?? CLI_UPDATE_PACKAGE_NAME;\n const cachePath = options.cachePath ?? getUserUpdateCheckCachePath();\n const now = options.now ?? new Date();\n const ttlMs = options.ttlMs ?? CLI_UPDATE_CACHE_TTL_MS;\n\n if (options.force !== true) {\n const cached = readUpdateCheckCache(cachePath);\n if (cached !== undefined && isFreshCache(cached, now, ttlMs, packageName)) {\n return resultFromCache(cached, options.currentVersion);\n }\n }\n\n const latestVersion = await fetchLatestVersionOrError(options, packageName, cachePath, now);\n if (typeof latestVersion !== 'string') {\n return latestVersion;\n }\n return resultFromLatestVersion(options.currentVersion, latestVersion);\n}\n\nasync function fetchLatestVersionOrError(\n options: ICheckForCliUpdateOptions,\n packageName: string,\n cachePath: string,\n now: Date,\n): Promise<string | TCliUpdateCheckResult> {\n const result = await attemptFetchLatestVersion({\n fetchImpl: options.fetchImpl ?? fetch,\n packageName,\n registryUrl: options.registryUrl ?? CLI_UPDATE_REGISTRY_URL,\n timeoutMs: options.timeoutMs ?? CLI_UPDATE_TIMEOUT_MS,\n });\n if (result.ok) {\n tryWriteUpdateCheckCache(cachePath, {\n packageName,\n checkedAt: now.toISOString(),\n currentVersion: options.currentVersion,\n latestVersion: result.version,\n });\n return result.version;\n }\n tryWriteUpdateCheckCache(cachePath, {\n packageName,\n checkedAt: now.toISOString(),\n currentVersion: options.currentVersion,\n errorMessage: result.errorMessage,\n });\n return { status: 'error', errorMessage: result.errorMessage };\n}\n\nfunction tryWriteUpdateCheckCache(path: string, cache: IUpdateCheckCache): void {\n try {\n writeUpdateCheckCache(path, cache);\n } catch {\n // allow-fallback: update cache I/O must not break CLI startup\n }\n}\n\nexport async function getStartupCliUpdateNotice(\n options: ICheckForCliUpdateOptions,\n): Promise<ICliUpdateNotice | undefined> {\n const result = await checkForCliUpdate(options);\n return result.status === 'update_available' ? result.notice : undefined;\n}\n\nexport function shouldRunStartupCliUpdateCheck(input: IStartupCliUpdatePolicyInput): boolean {\n return input.printMode === false && input.disableUpdateCheck === false;\n}\n\nexport function formatCliUpdateNotice(notice: ICliUpdateNotice): string {\n return [\n `Robota update available: ${notice.currentVersion} -> ${notice.latestVersion}.`,\n `Run ${notice.installCommand}`,\n ].join(' ');\n}\n\nexport function formatCliUpdateCheckMessage(result: TCliUpdateCheckResult): string {\n if (result.status === 'update_available') {\n return formatCliUpdateNotice(result.notice);\n }\n if (result.status === 'current') {\n return `Robota is up to date (${result.currentVersion}).`;\n }\n if (result.status === 'skipped') {\n return 'Robota update check skipped.';\n }\n return `Robota update check failed: ${result.errorMessage}`;\n}\n\nfunction resultFromCache(cache: IUpdateCheckCache, currentVersion: string): TCliUpdateCheckResult {\n if (cache.errorMessage !== undefined) {\n return { status: 'error', errorMessage: cache.errorMessage };\n }\n if (cache.latestVersion === undefined) {\n return { status: 'error', errorMessage: 'Cached update check has no latest version' };\n }\n return resultFromLatestVersion(currentVersion, cache.latestVersion);\n}\n\nfunction resultFromLatestVersion(\n currentVersion: string,\n latestVersion: string,\n): TCliUpdateCheckResult {\n if (isNewerSemverVersion(latestVersion, currentVersion)) {\n return {\n status: 'update_available',\n notice: {\n currentVersion,\n latestVersion,\n installCommand: DEFAULT_INSTALL_COMMAND,\n },\n };\n }\n return { status: 'current', currentVersion, latestVersion };\n}\n\nfunction isFreshCache(\n cache: IUpdateCheckCache,\n now: Date,\n ttlMs: number,\n packageName: string,\n): boolean {\n if (cache.packageName !== packageName) {\n return false;\n }\n const checkedAt = Date.parse(cache.checkedAt);\n if (!Number.isFinite(checkedAt)) {\n return false;\n }\n return now.getTime() - checkedAt < ttlMs;\n}\n\ntype TFetchResult = { ok: true; version: string } | { ok: false; errorMessage: string };\n\nasync function attemptFetchLatestVersion(options: {\n fetchImpl: typeof fetch;\n packageName: string;\n registryUrl: string;\n timeoutMs: number;\n}): Promise<TFetchResult> {\n try {\n const version = await fetchLatestVersion(options);\n return { ok: true, version };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return { ok: false, errorMessage };\n }\n}\n\nasync function fetchLatestVersion(options: {\n fetchImpl: typeof fetch;\n packageName: string;\n registryUrl: string;\n timeoutMs: number;\n}): Promise<string> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs);\n try {\n const packageUrl = buildPackageMetadataUrl(options.registryUrl, options.packageName);\n const response = await options.fetchImpl(packageUrl, {\n headers: { accept: 'application/json' },\n signal: controller.signal,\n });\n if (!response.ok) {\n throw new Error(`registry responded with HTTP ${response.status}`);\n }\n const metadata = (await response.json()) as INpmPackageMetadata;\n const latest = metadata['dist-tags']?.latest;\n if (typeof latest !== 'string' || latest.trim().length === 0) {\n throw new Error('registry metadata is missing dist-tags.latest');\n }\n return latest;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction buildPackageMetadataUrl(registryUrl: string, packageName: string): string {\n return `${registryUrl.replace(/\\/+$/, '')}/${encodeURIComponent(packageName)}`;\n}\n\nfunction parseUpdateCheckCache(value: TJsonValue): IUpdateCheckCache | undefined {\n if (!isJsonObject(value)) {\n return undefined;\n }\n const candidate = value;\n if (\n typeof candidate.packageName === 'string' &&\n typeof candidate.checkedAt === 'string' &&\n typeof candidate.currentVersion === 'string' &&\n (candidate.latestVersion === undefined || typeof candidate.latestVersion === 'string') &&\n (candidate.errorMessage === undefined || typeof candidate.errorMessage === 'string')\n ) {\n return {\n packageName: candidate.packageName,\n checkedAt: candidate.checkedAt,\n currentVersion: candidate.currentVersion,\n ...(candidate.latestVersion !== undefined && { latestVersion: candidate.latestVersion }),\n ...(candidate.errorMessage !== undefined && { errorMessage: candidate.errorMessage }),\n };\n }\n return undefined;\n}\n\nfunction isJsonObject(value: TJsonValue): value is { readonly [key: string]: TJsonValue } {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["asZodSchema","resolveAgentDefinition","extractFirstArg","asZodSchema","resolveAgentDefinition","pathRelative","pathSeparator","toSummary","existsSync","readFileSync","join","LIST_KEYS","parseListValue","parseFrontmatter","asZodSchema","extractJson","SessionWithAutoCompact","existsSync","readFileSync","mergeSettings","mergeProviders","resolveActiveProviderProfile","join","memoryRoot","join","existsSync","readFileSync","readdirSync","basename","resolve","join","existsSync","dirname","obj","hasUsableRequiredProviderCredential","formatEnvReference","hasUsableSecretReference","resolveProviderCredentialValue","hasUsableSecretReference","resolveEnvReference","formatIsoDate"],"sources":["../../src/background-tasks/background-job-orchestrator.ts","../../src/background-tasks/execution-workspace-types.ts","../../src/background-tasks/execution-workspace-projection.ts","../../src/background-tasks/execution-workspace-detail.ts","../../src/background-tasks/execution-workspace-spawner.ts","../../src/background-tasks/session-background-store.ts","../../src/tools/agent-tool-batch.ts","../../src/tools/agent-tool-output.ts","../../src/agents/built-in-agents.ts","../../src/assembly/subagent-prompts.ts","../../src/tools/model-command-tool-projection.ts","../../src/assembly/create-subagent-session.ts","../../src/subagents/in-process-subagent-runner.ts","../../src/tools/agent-tool.ts","../../src/interactive/interactive-session-background-tracker.ts","../../src/interactive/interactive-session-agent-jobs.ts","../../src/interactive/interactive-session-workspace.ts","../../src/interactive/interactive-session-base.ts","../../src/adapters/node-file-system.ts","../../src/context/context-file-tracker.ts","../../src/interactive/interactive-session-context-refresh.ts","../../src/context/context-reference-inventory.ts","../../src/context/prompt-file-reference-format.ts","../../src/context/prompt-file-reference-parser.ts","../../src/context/prompt-file-reference-paths.ts","../../src/context/prompt-file-reference-resolver.ts","../../src/interactive/interactive-session-execution.ts","../../src/interactive/interactive-session-streaming.ts","../../src/interactive/interactive-session-prompt.ts","../../src/interactive/interactive-session-execution-controller.ts","../../src/interactive/interactive-session-fork.ts","../../src/interactive/interactive-session-context-references.ts","../../src/paths.ts","../../src/checkpoints/edit-checkpoint-inspection.ts","../../src/checkpoints/edit-checkpoint-store.ts","../../src/commands/skill-activation-events.ts","../../src/interactive/interactive-session-history-tracker.ts","../../src/context/project-detector.ts","../../src/interactive/interactive-session-restore.ts","../../src/assembly/background-task-hooks.ts","../../src/assembly/create-tools.ts","../../src/agents/agent-definition-loader.ts","../../src/context/system-prompt-composer.ts","../../src/context/system-prompt-section-providers.ts","../../src/context/system-prompt-builder.ts","../../src/tools/background-process-tool.ts","../../src/assembly/create-session-runtime.ts","../../src/checkpoints/edit-checkpoint-tools.ts","../../src/commands/skill-source.ts","../../src/hooks/agent-executor.ts","../../src/hooks/prompt-executor.ts","../../src/reversible-execution/reversible-execution-policy.ts","../../src/assembly/create-session.ts","../../src/assembly/subagent-logger.ts","../../src/config/config-types.ts","../../src/config/config-loader.ts","../../src/context/task-context.ts","../../src/memory/project-memory-store.ts","../../src/context/context-loader.ts","../../src/plugins/plugin-settings-store.ts","../../src/plugins/bundle-plugin-utils.ts","../../src/plugins/bundle-plugin-loader.ts","../../src/plugins/bundle-plugin-installer.ts","../../src/plugins/marketplace-registry.ts","../../src/plugins/marketplace-client.ts","../../src/plugins/plugin-hooks-merger.ts","../../src/interactive/interactive-session-init.ts","../../src/interactive/interactive-session-persistence.ts","../../src/commands/capability-descriptors.ts","../../src/commands/command-registry.ts","../../src/commands/system-command-executor.ts","../../src/commands/system-command.ts","../../src/commands/builtin-source.ts","../../src/command-api/provider/provider-settings.ts","../../src/command-api/provider/provider-command-probe.ts","../../src/command-api/provider/settings-check.ts","../../src/command-api/provider/provider-merge.ts","../../src/config/provider-paths.ts","../../src/config/settings-io.ts","../../src/command-api/provider/provider-configuration.ts","../../src/command-api/provider/provider-factory.ts","../../src/commands/plugin-source.ts","../../src/command-api/context/context-command-api.ts","../../src/command-api/provider/provider-profile-names.ts","../../src/command-api/help/help-command-api.ts","../../src/command-api/background/background-command-api.ts","../../src/command-api/model/model-command-api.ts","../../src/command-api/language/language-command-api.ts","../../src/command-api/permissions/permission-mode-command-api.ts","../../src/command-api/statusline/statusline-command-api.ts","../../src/command-api/plugin/plugin-command-api.ts","../../src/command-api/session/session-command-api.ts","../../src/command-api/checkpoint/rewind-command-api.ts","../../src/memory/memory-policy-evaluator.ts","../../src/memory/pending-memory-store.ts","../../src/command-api/memory/memory-command-api.ts","../../src/utils/skill-prompt.ts","../../src/commands/skill-executor.ts","../../src/interactive/interactive-session-skill-router.ts","../../src/interactive/interactive-session.ts","../../src/interactive/session-persistence.ts","../../src/query.ts","../../src/user-local/storage.ts","../../src/user-local/memory-types.ts","../../src/user-local/memory.ts","../../src/self-hosting/self-hosting-verification.ts","../../src/tools/command-execution-tool.ts","../../src/permissions/permission-prompt.ts","../../src/testing/create-test-interactive-session.ts","../../src/config/reset-user-config.ts","../../src/git/git-branch.ts","../../src/utils/semver-compare.ts","../../src/runtime/agent-runtime.ts","../../src/utils/read-package-version.ts","../../src/update-check/update-check.ts"],"sourcesContent":["import {\n isTerminalBackgroundTaskStatus,\n type IBackgroundTaskError,\n type IBackgroundTaskManager,\n type IBackgroundTaskState,\n type TBackgroundTaskEvent,\n type TBackgroundTaskStatus,\n} from '@robota-sdk/agent-executor';\n\nconst DEFAULT_SUMMARY_LENGTH = 1_000;\n\nexport type TBackgroundJobWaitPolicy = 'detached' | 'wait_all' | 'wait_any' | 'manual';\n\nexport type TBackgroundJobGroupStatus = 'running' | 'completed';\n\nexport interface IBackgroundJobResultEnvelope {\n taskId: string;\n label: string;\n status: TBackgroundTaskStatus;\n summary?: string;\n outputRef?: string;\n error?: IBackgroundTaskError;\n startedAt?: string;\n completedAt?: string;\n}\n\nexport interface IBackgroundJobGroupState {\n id: string;\n parentSessionId: string;\n waitPolicy: TBackgroundJobWaitPolicy;\n taskIds: string[];\n status: TBackgroundJobGroupStatus;\n createdAt: string;\n updatedAt: string;\n label?: string;\n completedAt?: string;\n results: IBackgroundJobResultEnvelope[];\n}\n\nexport interface IBackgroundJobGroupSummary {\n groupId: string;\n status: TBackgroundJobGroupStatus;\n total: number;\n completed: number;\n failed: number;\n cancelled: number;\n pending: number;\n lines: string[];\n}\n\nexport interface IBackgroundJobGroupCreateRequest {\n parentSessionId: string;\n waitPolicy: TBackgroundJobWaitPolicy;\n taskIds: string[];\n label?: string;\n}\n\nexport type TBackgroundJobGroupEvent =\n | { type: 'background_job_group_created'; group: IBackgroundJobGroupState }\n | { type: 'background_job_group_updated'; group: IBackgroundJobGroupState }\n | { type: 'background_job_group_completed'; group: IBackgroundJobGroupState };\n\nexport type TBackgroundJobGroupEventListener = (event: TBackgroundJobGroupEvent) => void;\n\nexport type TBackgroundJobGroupIdFactory = (request: IBackgroundJobGroupCreateRequest) => string;\n\nexport interface IBackgroundJobOrchestratorOptions {\n manager: IBackgroundTaskManager;\n now?: () => string;\n idFactory?: TBackgroundJobGroupIdFactory;\n initialGroups?: readonly IBackgroundJobGroupState[];\n}\n\ninterface IBackgroundJobGroupRecord {\n state: IBackgroundJobGroupState;\n completion: Promise<IBackgroundJobGroupState>;\n resolve: (state: IBackgroundJobGroupState) => void;\n}\n\nexport class BackgroundJobOrchestrator {\n private readonly manager: IBackgroundTaskManager;\n private readonly now: () => string;\n private readonly idFactory: TBackgroundJobGroupIdFactory;\n private readonly unsubscribeManager: () => void;\n private readonly listeners = new Set<TBackgroundJobGroupEventListener>();\n private readonly groups = new Map<string, IBackgroundJobGroupRecord>();\n private sequence = 0;\n\n constructor(options: IBackgroundJobOrchestratorOptions) {\n this.manager = options.manager;\n this.now = options.now ?? (() => new Date().toISOString());\n this.idFactory = options.idFactory ?? (() => this.nextGroupId());\n this.sequence = options.initialGroups?.length ?? 0;\n for (const group of options.initialGroups ?? []) this.restoreGroup(group);\n this.unsubscribeManager = this.manager.subscribe((event) => this.handleTaskEvent(event));\n }\n\n createGroup(request: IBackgroundJobGroupCreateRequest): IBackgroundJobGroupState {\n const now = this.now();\n const state: IBackgroundJobGroupState = {\n id: this.idFactory(request),\n parentSessionId: request.parentSessionId,\n waitPolicy: request.waitPolicy,\n taskIds: [...request.taskIds],\n status: 'running',\n createdAt: now,\n updatedAt: now,\n results: [],\n ...(request.label ? { label: request.label } : {}),\n };\n const record = this.createRecord(state);\n this.groups.set(state.id, record);\n this.captureExistingTerminalTasks(record);\n this.emit({ type: 'background_job_group_created', group: cloneGroup(record.state) });\n this.evaluateCompletion(record);\n return cloneGroup(record.state);\n }\n\n listGroups(): IBackgroundJobGroupState[] {\n return [...this.groups.values()].map((record) => cloneGroup(record.state));\n }\n\n getGroup(groupId: string): IBackgroundJobGroupState | undefined {\n const record = this.groups.get(groupId);\n return record ? cloneGroup(record.state) : undefined;\n }\n\n waitGroup(groupId: string): Promise<IBackgroundJobGroupState> {\n const record = this.groups.get(groupId);\n if (!record) return Promise.reject(new Error(`Unknown background job group: ${groupId}`));\n return record.completion;\n }\n\n subscribe(listener: TBackgroundJobGroupEventListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n dispose(): void {\n this.unsubscribeManager();\n this.listeners.clear();\n }\n\n private nextGroupId(): string {\n this.sequence += 1;\n return `group_${this.sequence}`;\n }\n\n private restoreGroup(group: IBackgroundJobGroupState): void {\n const record = this.createRecord(cloneGroup(group));\n this.groups.set(group.id, record);\n if (group.status === 'completed') record.resolve(cloneGroup(group));\n }\n\n private createRecord(state: IBackgroundJobGroupState): IBackgroundJobGroupRecord {\n let resolveGroup: (state: IBackgroundJobGroupState) => void = () => {};\n const completion = new Promise<IBackgroundJobGroupState>((resolve) => {\n resolveGroup = resolve;\n });\n return { state, completion, resolve: resolveGroup };\n }\n\n private captureExistingTerminalTasks(record: IBackgroundJobGroupRecord): void {\n for (const taskId of record.state.taskIds) {\n const task = this.manager.get(taskId);\n if (task && isTerminalBackgroundTaskStatus(task.status)) this.captureTask(record, task);\n }\n }\n\n private handleTaskEvent(event: TBackgroundTaskEvent): void {\n const task = getTerminalTask(event);\n if (!task) return;\n for (const record of this.groups.values()) {\n if (!record.state.taskIds.includes(task.id)) continue;\n if (!this.captureTask(record, task)) continue;\n if (record.state.status === 'running') this.evaluateCompletion(record);\n else this.emit({ type: 'background_job_group_updated', group: cloneGroup(record.state) });\n }\n }\n\n private captureTask(record: IBackgroundJobGroupRecord, task: IBackgroundTaskState): boolean {\n if (record.state.results.some((result) => result.taskId === task.id)) return false;\n record.state.results = [...record.state.results, createResultEnvelope(task)];\n record.state.updatedAt = this.now();\n return true;\n }\n\n private evaluateCompletion(record: IBackgroundJobGroupRecord): void {\n if (record.state.status === 'completed') return;\n if (!shouldComplete(record.state)) {\n this.emit({ type: 'background_job_group_updated', group: cloneGroup(record.state) });\n return;\n }\n const now = this.now();\n record.state.status = 'completed';\n record.state.completedAt = now;\n record.state.updatedAt = now;\n const completed = cloneGroup(record.state);\n record.resolve(completed);\n this.emit({ type: 'background_job_group_completed', group: completed });\n }\n\n private emit(event: TBackgroundJobGroupEvent): void {\n for (const listener of this.listeners) listener(event);\n }\n}\n\nfunction getTerminalTask(event: TBackgroundTaskEvent): IBackgroundTaskState | undefined {\n if (\n event.type === 'background_task_completed' ||\n event.type === 'background_task_failed' ||\n event.type === 'background_task_cancelled'\n ) {\n return event.task;\n }\n return undefined;\n}\n\nfunction shouldComplete(group: IBackgroundJobGroupState): boolean {\n if (group.waitPolicy === 'manual') return false;\n if (group.waitPolicy === 'wait_any') return group.results.length > 0;\n return group.taskIds.every((taskId) => group.results.some((result) => result.taskId === taskId));\n}\n\nfunction createResultEnvelope(task: IBackgroundTaskState): IBackgroundJobResultEnvelope {\n return {\n taskId: task.id,\n label: task.label,\n status: task.status,\n ...(task.result?.output ? { summary: summarizeOutput(task.result.output) } : {}),\n ...(task.transcriptPath || task.logPath\n ? { outputRef: task.transcriptPath ?? task.logPath }\n : {}),\n ...(task.error ? { error: { ...task.error } } : {}),\n ...(task.startedAt ? { startedAt: task.startedAt } : {}),\n ...(task.completedAt ? { completedAt: task.completedAt } : {}),\n };\n}\n\nfunction summarizeOutput(output: string): string {\n const trimmed = output.trim();\n if (trimmed.length <= DEFAULT_SUMMARY_LENGTH) return trimmed;\n return `${trimmed.slice(0, DEFAULT_SUMMARY_LENGTH)}...`;\n}\n\nexport function summarizeBackgroundJobGroup(\n group: IBackgroundJobGroupState,\n): IBackgroundJobGroupSummary {\n const completed = countResults(group, 'completed');\n const failed = countResults(group, 'failed');\n const cancelled = countResults(group, 'cancelled');\n return {\n groupId: group.id,\n status: group.status,\n total: group.taskIds.length,\n completed,\n failed,\n cancelled,\n pending: Math.max(group.taskIds.length - group.results.length, 0),\n lines: group.results.map((result) => formatResultLine(result)),\n };\n}\n\nfunction countResults(group: IBackgroundJobGroupState, status: TBackgroundTaskStatus): number {\n return group.results.filter((result) => result.status === status).length;\n}\n\nfunction formatResultLine(result: IBackgroundJobResultEnvelope): string {\n const detail = normalizeResultDetail(result);\n const output = result.outputRef && result.summary ? ` (output: ${result.outputRef})` : '';\n return `[${result.status}] ${result.label} ${result.taskId}: ${detail}${output}`;\n}\n\nfunction normalizeResultDetail(result: IBackgroundJobResultEnvelope): string {\n const detail = result.error?.message ?? result.summary ?? '';\n const normalized = detail.replace(/\\s+/g, ' ').trim();\n return normalized.length > 0 ? normalized : '(no summary)';\n}\n\nfunction cloneGroup(group: IBackgroundJobGroupState): IBackgroundJobGroupState {\n return {\n ...group,\n taskIds: [...group.taskIds],\n results: group.results.map((result) => ({\n ...result,\n ...(result.error ? { error: { ...result.error } } : {}),\n })),\n };\n}\n","import type { IBackgroundJobGroupState } from './background-job-orchestrator.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\nimport type {\n IBackgroundTaskLogCursor,\n IBackgroundTaskState,\n TBackgroundPrimitive,\n TBackgroundTaskKind,\n TBackgroundTaskStatus,\n} from '@robota-sdk/agent-executor';\n\nexport const MAIN_THREAD_ENTRY_PREFIX = 'main';\nexport const BACKGROUND_TASK_ENTRY_PREFIX = 'task';\nexport const BACKGROUND_GROUP_ENTRY_PREFIX = 'group';\nexport const ENTRY_ID_SEPARATOR = ':';\n\nexport const EXECUTION_ORIGIN_METADATA_KEYS = {\n kind: 'executionOriginKind',\n sessionId: 'executionOriginSessionId',\n turnId: 'executionOriginTurnId',\n commandName: 'executionOriginCommandName',\n toolCallId: 'executionOriginToolCallId',\n skillId: 'executionOriginSkillId',\n label: 'executionOriginLabel',\n} as const;\n\nexport type TExecutionEntryKind = 'main_thread' | 'background_task' | 'background_group';\nexport type TExecutionWorkspaceStatus = 'active' | 'idle' | TBackgroundTaskStatus;\nexport type TExecutionAttention = 'none' | 'unread' | 'failed' | 'permission' | 'completed';\nexport type TExecutionWorkspaceVisibility = 'default' | 'collapsed';\nexport type TExecutionControl = 'select' | 'cancel' | 'close' | 'send' | 'read_log' | 'wait';\nexport type TExecutionOriginKind =\n | 'user_prompt'\n | 'slash_command'\n | 'model_command'\n | 'tool_call'\n | 'skill'\n | 'transport'\n | 'system';\nexport type TExecutionDetailRecordKind =\n | 'message'\n | 'tool_activity'\n | 'process_output'\n | 'progress'\n | 'result'\n | 'error'\n | 'group_summary';\nexport type TExecutionWorkspaceUpdateCause = 'main_thread' | 'background_task' | 'background_group';\n\nexport interface IExecutionOrigin {\n readonly kind: TExecutionOriginKind;\n readonly sessionId: string;\n readonly turnId?: string;\n readonly commandName?: string;\n readonly toolCallId?: string;\n readonly skillId?: string;\n readonly label?: string;\n}\n\nexport interface IExecutionWorkspaceEntry {\n readonly id: string;\n readonly sourceId: string;\n readonly kind: TExecutionEntryKind;\n readonly parentId?: string;\n readonly groupId?: string;\n readonly origin: IExecutionOrigin;\n readonly taskKind?: TBackgroundTaskKind;\n readonly status: TExecutionWorkspaceStatus;\n readonly title: string;\n readonly subtitle?: string;\n readonly preview?: string;\n readonly currentAction?: string;\n readonly unread: boolean;\n readonly attention: TExecutionAttention;\n readonly visibility: TExecutionWorkspaceVisibility;\n readonly updatedAt: string;\n readonly controls: readonly TExecutionControl[];\n}\n\nexport interface IExecutionWorkspaceFilter {\n readonly includeMainThread?: boolean;\n readonly kinds?: readonly TExecutionEntryKind[];\n readonly visibility?: readonly TExecutionWorkspaceVisibility[];\n}\n\nexport interface IExecutionWorkspaceSnapshot {\n readonly sessionId: string;\n readonly selectedEntryId?: string;\n readonly updatedAt: string;\n readonly entries: readonly IExecutionWorkspaceEntry[];\n}\n\nexport interface IExecutionWorkspaceSnapshotOptions {\n readonly selectedEntryId?: string;\n readonly filter?: IExecutionWorkspaceFilter;\n}\n\nexport interface IExecutionWorkspaceEvent {\n readonly type: 'execution_workspace_updated';\n readonly cause: TExecutionWorkspaceUpdateCause;\n readonly entryId?: string;\n readonly snapshot: IExecutionWorkspaceSnapshot;\n}\n\nexport interface IExecutionDetailCursor {\n readonly offset: number;\n}\n\nexport interface IExecutionDetailRecord {\n readonly id: string;\n readonly kind: TExecutionDetailRecordKind;\n readonly text: string;\n readonly timestamp?: string;\n readonly sourceId?: string;\n}\n\nexport interface IExecutionDetailPage {\n readonly entryId: string;\n readonly cursor?: IExecutionDetailCursor;\n readonly nextCursor?: IExecutionDetailCursor;\n readonly records: readonly IExecutionDetailRecord[];\n}\n\nexport interface ICreateMainThreadEntryInput {\n readonly sessionId: string;\n readonly isExecuting: boolean;\n readonly hasPendingPrompt: boolean;\n readonly historyLength: number;\n readonly updatedAt: string;\n readonly preview?: string;\n}\n\nexport interface ICreateExecutionWorkspaceSnapshotInput {\n readonly sessionId: string;\n readonly mainThread: ICreateMainThreadEntryInput;\n readonly tasks: readonly IBackgroundTaskState[];\n readonly groups: readonly IBackgroundJobGroupState[];\n readonly selectedEntryId?: string;\n readonly filter?: IExecutionWorkspaceFilter;\n}\n\nexport interface IExecutionWorkspaceEntryRef {\n readonly kind: TExecutionEntryKind;\n readonly sourceId: string;\n}\n\nexport interface ICreateMainThreadDetailPageInput {\n readonly entryId: string;\n readonly history: readonly IHistoryEntry[];\n readonly cursor?: IExecutionDetailCursor;\n}\n\nexport interface ICreateLineDetailPageInput {\n readonly entryId: string;\n readonly lines: readonly string[];\n readonly cursor?: IBackgroundTaskLogCursor;\n readonly nextCursor?: IBackgroundTaskLogCursor;\n readonly kind?: TExecutionDetailRecordKind;\n}\n\nexport function createMainThreadExecutionEntryId(sessionId: string): string {\n return [MAIN_THREAD_ENTRY_PREFIX, sessionId].join(ENTRY_ID_SEPARATOR);\n}\n\nexport function createBackgroundTaskExecutionEntryId(taskId: string): string {\n return [BACKGROUND_TASK_ENTRY_PREFIX, taskId].join(ENTRY_ID_SEPARATOR);\n}\n\nexport function createBackgroundGroupExecutionEntryId(groupId: string): string {\n return [BACKGROUND_GROUP_ENTRY_PREFIX, groupId].join(ENTRY_ID_SEPARATOR);\n}\n\nexport function parseExecutionWorkspaceEntryId(\n entryId: string,\n): IExecutionWorkspaceEntryRef | undefined {\n const [prefix, sourceId] = entryId.split(ENTRY_ID_SEPARATOR, 2);\n if (!sourceId) return undefined;\n if (prefix === MAIN_THREAD_ENTRY_PREFIX) return { kind: 'main_thread', sourceId };\n if (prefix === BACKGROUND_TASK_ENTRY_PREFIX) return { kind: 'background_task', sourceId };\n if (prefix === BACKGROUND_GROUP_ENTRY_PREFIX) return { kind: 'background_group', sourceId };\n return undefined;\n}\n\nexport function createExecutionOriginMetadata(\n origin: IExecutionOrigin,\n): Record<string, TBackgroundPrimitive> {\n return {\n [EXECUTION_ORIGIN_METADATA_KEYS.kind]: origin.kind,\n [EXECUTION_ORIGIN_METADATA_KEYS.sessionId]: origin.sessionId,\n ...(origin.turnId ? { [EXECUTION_ORIGIN_METADATA_KEYS.turnId]: origin.turnId } : {}),\n ...(origin.commandName\n ? { [EXECUTION_ORIGIN_METADATA_KEYS.commandName]: origin.commandName }\n : {}),\n ...(origin.toolCallId\n ? { [EXECUTION_ORIGIN_METADATA_KEYS.toolCallId]: origin.toolCallId }\n : {}),\n ...(origin.skillId ? { [EXECUTION_ORIGIN_METADATA_KEYS.skillId]: origin.skillId } : {}),\n ...(origin.label ? { [EXECUTION_ORIGIN_METADATA_KEYS.label]: origin.label } : {}),\n };\n}\n","import { isTerminalBackgroundTaskStatus } from '@robota-sdk/agent-executor';\n\nimport {\n EXECUTION_ORIGIN_METADATA_KEYS,\n createBackgroundGroupExecutionEntryId,\n createBackgroundTaskExecutionEntryId,\n createMainThreadExecutionEntryId,\n type ICreateExecutionWorkspaceSnapshotInput,\n type ICreateMainThreadEntryInput,\n type IExecutionOrigin,\n type IExecutionWorkspaceEntry,\n type IExecutionWorkspaceFilter,\n type IExecutionWorkspaceSnapshot,\n type TExecutionAttention,\n type TExecutionControl,\n type TExecutionOriginKind,\n type TExecutionWorkspaceVisibility,\n} from './execution-workspace-types.js';\n\nimport type { IBackgroundJobGroupState } from './background-job-orchestrator.js';\nimport type { IBackgroundTaskState, TBackgroundPrimitive } from '@robota-sdk/agent-executor';\n\nconst PREVIEW_MAX_LENGTH = 120;\nconst SUCCESS_EXIT_CODE = 0;\n\nexport function createExecutionWorkspaceSnapshot(\n input: ICreateExecutionWorkspaceSnapshotInput,\n): IExecutionWorkspaceSnapshot {\n const taskGroupIds = createTaskGroupIdMap(input.groups);\n const entries = [\n createMainThreadEntry(input.mainThread),\n ...sortGroups(input.groups).map((group) => createBackgroundGroupEntry(group)),\n ...sortTasks(input.tasks).map((task) =>\n createBackgroundTaskEntry(task, taskGroupIds.get(task.id)),\n ),\n ].filter((entry) => matchesExecutionWorkspaceFilter(entry, input.filter));\n return {\n sessionId: input.sessionId,\n selectedEntryId:\n input.selectedEntryId ??\n entries.find((entry) => entry.kind === 'main_thread')?.id ??\n createMainThreadExecutionEntryId(input.sessionId),\n updatedAt: entries[0]?.updatedAt ?? input.mainThread.updatedAt,\n entries,\n };\n}\n\nfunction createMainThreadEntry(input: ICreateMainThreadEntryInput): IExecutionWorkspaceEntry {\n return {\n id: createMainThreadExecutionEntryId(input.sessionId),\n sourceId: input.sessionId,\n kind: 'main_thread',\n origin: { kind: 'user_prompt', sessionId: input.sessionId },\n status: input.isExecuting ? 'active' : 'idle',\n title: 'Main thread',\n subtitle: input.hasPendingPrompt ? 'prompt queued' : `${input.historyLength} history entries`,\n preview: trimPreview(input.preview),\n unread: false,\n attention: 'none',\n visibility: 'default',\n updatedAt: input.updatedAt,\n controls: ['select'],\n };\n}\n\nfunction createBackgroundTaskEntry(\n state: IBackgroundTaskState,\n groupId: string | undefined,\n): IExecutionWorkspaceEntry {\n return {\n id: createBackgroundTaskExecutionEntryId(state.id),\n sourceId: state.id,\n kind: 'background_task',\n parentId: state.parentTaskId\n ? createBackgroundTaskExecutionEntryId(state.parentTaskId)\n : createMainThreadExecutionEntryId(state.parentSessionId),\n ...(groupId ? { groupId: createBackgroundGroupExecutionEntryId(groupId) } : {}),\n origin: readExecutionOrigin(state.metadata, {\n kind: 'system',\n sessionId: state.parentSessionId,\n }),\n taskKind: state.kind,\n status: state.status,\n title: state.label,\n subtitle: createTaskSubtitle(state),\n preview: createTaskPreview(state),\n currentAction: state.currentAction,\n unread: state.unread,\n attention: createTaskAttention(state),\n visibility: createTaskVisibility(state),\n updatedAt: state.lastActivityAt ?? state.updatedAt,\n controls: createTaskControls(state),\n };\n}\n\nfunction createBackgroundGroupEntry(group: IBackgroundJobGroupState): IExecutionWorkspaceEntry {\n const preview = trimPreview(\n group.results.map((result) => result.summary ?? result.error?.message).join(' '),\n );\n return {\n id: createBackgroundGroupExecutionEntryId(group.id),\n sourceId: group.id,\n kind: 'background_group',\n parentId: createMainThreadExecutionEntryId(group.parentSessionId),\n origin: { kind: 'system', sessionId: group.parentSessionId, label: group.label },\n status: group.status,\n title: group.label ?? group.id,\n subtitle: `${group.results.length}/${group.taskIds.length} tasks`,\n preview,\n unread: false,\n attention: createGroupAttention(group),\n visibility: group.status === 'completed' ? 'collapsed' : 'default',\n updatedAt: group.updatedAt,\n controls: group.status === 'running' ? ['select', 'wait'] : ['select'],\n };\n}\n\nfunction readExecutionOrigin(\n metadata: Record<string, TBackgroundPrimitive> | undefined,\n fallback: IExecutionOrigin,\n): IExecutionOrigin {\n const kind = toExecutionOriginKind(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.kind]);\n const sessionId = toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.sessionId]);\n return {\n kind: kind ?? fallback.kind,\n sessionId: sessionId ?? fallback.sessionId,\n turnId: toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.turnId]) ?? fallback.turnId,\n commandName:\n toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.commandName]) ?? fallback.commandName,\n toolCallId:\n toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.toolCallId]) ?? fallback.toolCallId,\n skillId: toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.skillId]) ?? fallback.skillId,\n label: toStringValue(metadata?.[EXECUTION_ORIGIN_METADATA_KEYS.label]) ?? fallback.label,\n };\n}\n\nfunction createTaskGroupIdMap(groups: readonly IBackgroundJobGroupState[]): Map<string, string> {\n return new Map(groups.flatMap((group) => group.taskIds.map((taskId) => [taskId, group.id])));\n}\n\nfunction createTaskControls(state: IBackgroundTaskState): readonly TExecutionControl[] {\n const controls: TExecutionControl[] = ['select'];\n if (isTerminalBackgroundTaskStatus(state.status)) controls.push('close');\n else controls.push('cancel');\n if (state.kind === 'agent' && state.status === 'running') controls.push('send');\n if (state.logPath || state.transcriptPath) controls.push('read_log');\n return controls;\n}\n\nfunction createTaskSubtitle(state: IBackgroundTaskState): string | undefined {\n if (state.kind === 'agent') return state.agentType ?? state.cwd;\n if (state.status === 'sleeping' && state.nextFireAt !== undefined) {\n return `next: ${formatNextFireAt(state.nextFireAt)}`;\n }\n return state.cwd;\n}\n\nfunction formatNextFireAt(isoString: string): string {\n const date = new Date(isoString);\n const now = new Date();\n const diffMs = date.getTime() - now.getTime();\n if (diffMs <= 0) return 'now';\n const diffSec = Math.round(diffMs / 1000);\n if (diffSec < 60) return `${diffSec}s`;\n const diffMin = Math.round(diffSec / 60);\n if (diffMin < 60) return `${diffMin}m`;\n return `${Math.round(diffMin / 60)}h`;\n}\n\nfunction createTaskPreview(state: IBackgroundTaskState): string | undefined {\n if (state.status === 'failed') return trimPreview(state.error?.message);\n if (state.status === 'completed') return trimPreview(state.result?.output);\n return trimPreview(state.promptPreview ?? state.commandPreview);\n}\n\nfunction createTaskAttention(state: IBackgroundTaskState): TExecutionAttention {\n if (state.status === 'failed') return 'failed';\n if (state.status === 'waiting_permission') return 'permission';\n if (state.unread) return 'unread';\n if (state.status === 'completed') return 'completed';\n return 'none';\n}\n\nfunction createTaskVisibility(state: IBackgroundTaskState): TExecutionWorkspaceVisibility {\n if (\n state.status === 'completed' &&\n !state.unread &&\n !state.error &&\n (state.result?.exitCode ?? SUCCESS_EXIT_CODE) === SUCCESS_EXIT_CODE &&\n !state.result?.signalCode &&\n !state.worktreePath &&\n !state.branchName\n ) {\n return 'collapsed';\n }\n return 'default';\n}\n\nfunction createGroupAttention(group: IBackgroundJobGroupState): TExecutionAttention {\n if (group.results.some((result) => result.status === 'failed')) return 'failed';\n if (group.status === 'completed') return 'completed';\n return 'none';\n}\n\nfunction matchesExecutionWorkspaceFilter(\n entry: IExecutionWorkspaceEntry,\n filter: IExecutionWorkspaceFilter | undefined,\n): boolean {\n if (!filter) return true;\n if (filter.includeMainThread === false && entry.kind === 'main_thread') return false;\n if (filter.kinds && !filter.kinds.includes(entry.kind)) return false;\n if (filter.visibility && !filter.visibility.includes(entry.visibility)) return false;\n return true;\n}\n\nfunction sortTasks(tasks: readonly IBackgroundTaskState[]): IBackgroundTaskState[] {\n return [...tasks].sort((left, right) =>\n (right.lastActivityAt ?? right.updatedAt).localeCompare(left.lastActivityAt ?? left.updatedAt),\n );\n}\n\nfunction sortGroups(groups: readonly IBackgroundJobGroupState[]): IBackgroundJobGroupState[] {\n return [...groups].sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));\n}\n\nfunction trimPreview(value: string | undefined): string | undefined {\n const normalized = value?.trim().replace(/\\s+/g, ' ');\n if (!normalized) return undefined;\n return normalized.length > PREVIEW_MAX_LENGTH\n ? `${normalized.slice(0, PREVIEW_MAX_LENGTH)}...`\n : normalized;\n}\n\nfunction toStringValue(value: TBackgroundPrimitive | undefined): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction toExecutionOriginKind(\n value: TBackgroundPrimitive | undefined,\n): TExecutionOriginKind | undefined {\n if (\n value === 'user_prompt' ||\n value === 'slash_command' ||\n value === 'model_command' ||\n value === 'tool_call' ||\n value === 'skill' ||\n value === 'transport' ||\n value === 'system'\n ) {\n return value;\n }\n return undefined;\n}\n","import type {\n ICreateLineDetailPageInput,\n ICreateMainThreadDetailPageInput,\n IExecutionDetailPage,\n} from './execution-workspace-types.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\n\nconst EXECUTION_DETAIL_PAGE_SIZE = 80;\n\nexport function createMainThreadDetailPage(\n input: ICreateMainThreadDetailPageInput,\n): IExecutionDetailPage {\n const offset = normalizeOffset(input.cursor?.offset);\n const page = input.history.slice(offset, offset + EXECUTION_DETAIL_PAGE_SIZE);\n const records = page.map((entry) => ({\n id: entry.id,\n kind: entry.category === 'chat' ? ('message' as const) : ('progress' as const),\n text: formatHistoryEntry(entry),\n timestamp: entry.timestamp.toISOString(),\n sourceId: entry.type,\n }));\n return {\n entryId: input.entryId,\n ...(input.cursor ? { cursor: input.cursor } : {}),\n ...(offset + page.length < input.history.length\n ? { nextCursor: { offset: offset + page.length } }\n : {}),\n records,\n };\n}\n\nexport function createLineDetailPage(input: ICreateLineDetailPageInput): IExecutionDetailPage {\n const offset = input.cursor?.offset ?? 0;\n const records = input.lines.map((line, index) => ({\n id: `${input.entryId}:${offset}:${index}`,\n kind: input.kind ?? ('process_output' as const),\n text: line,\n }));\n return {\n entryId: input.entryId,\n ...(input.cursor ? { cursor: input.cursor } : {}),\n ...(input.nextCursor ? { nextCursor: input.nextCursor } : {}),\n records,\n };\n}\n\nfunction normalizeOffset(offset: number | undefined): number {\n return typeof offset === 'number' && Number.isFinite(offset) && offset > 0\n ? Math.floor(offset)\n : 0;\n}\n\nfunction formatHistoryEntry(entry: IHistoryEntry): string {\n if (typeof entry.data === 'string') return entry.data;\n return entry.type;\n}\n","import {\n createExecutionOriginMetadata,\n type IExecutionOrigin,\n} from './execution-workspace-types.js';\n\nimport type { BackgroundJobOrchestrator } from './background-job-orchestrator.js';\nimport type {\n IBackgroundJobGroupCreateRequest,\n IBackgroundJobGroupState,\n} from './background-job-orchestrator.js';\nimport type {\n IAgentBackgroundTaskRequest,\n IBackgroundTaskManager,\n IBackgroundTaskState,\n IProcessBackgroundTaskRequest,\n TBackgroundPermissionPolicy,\n TBackgroundTaskIsolation,\n TBackgroundTaskMode,\n} from '@robota-sdk/agent-executor';\n\nexport interface ISpawnAgentTaskRequest {\n readonly label: string;\n readonly agentType: string;\n readonly prompt: string;\n readonly mode?: TBackgroundTaskMode;\n readonly parentTaskId?: string;\n readonly depth?: number;\n readonly cwd?: string;\n readonly model?: string;\n readonly isolation?: TBackgroundTaskIsolation;\n readonly allowedTools?: readonly string[];\n readonly disallowedTools?: readonly string[];\n readonly permissionPolicy?: TBackgroundPermissionPolicy;\n readonly timeoutMs?: number;\n readonly idleTimeoutMs?: number;\n readonly maxRuntimeMs?: number;\n readonly outputLimitBytes?: number;\n readonly maxTextDeltas?: number;\n readonly repetitionWindow?: number;\n readonly repetitionThreshold?: number;\n}\n\nexport interface ISpawnProcessTaskRequest {\n readonly command: string;\n readonly label?: string;\n readonly mode?: TBackgroundTaskMode;\n readonly parentTaskId?: string;\n readonly depth?: number;\n readonly cwd?: string;\n readonly shell?: string;\n readonly env?: Record<string, string>;\n readonly stdin?: string;\n readonly timeoutMs?: number;\n readonly idleTimeoutMs?: number;\n readonly maxRuntimeMs?: number;\n readonly outputLimitBytes?: number;\n}\n\nexport interface IBackgroundTaskSpawnerGroupRequest {\n readonly waitPolicy: IBackgroundJobGroupCreateRequest['waitPolicy'];\n readonly taskIds: readonly string[];\n readonly label?: string;\n}\n\nexport interface IExecutionWorkspaceTaskSpawner {\n spawnAgent(request: ISpawnAgentTaskRequest): Promise<IBackgroundTaskState>;\n spawnProcess(request: ISpawnProcessTaskRequest): Promise<IBackgroundTaskState>;\n createGroup(request: IBackgroundTaskSpawnerGroupRequest): IBackgroundJobGroupState;\n}\n\nexport interface ICreateExecutionWorkspaceTaskSpawnerOptions {\n readonly manager: IBackgroundTaskManager;\n readonly groupOrchestrator: BackgroundJobOrchestrator;\n readonly sessionId: string;\n readonly cwd: string;\n readonly origin: IExecutionOrigin;\n}\n\nexport function createExecutionWorkspaceTaskSpawner(\n options: ICreateExecutionWorkspaceTaskSpawnerOptions,\n): IExecutionWorkspaceTaskSpawner {\n return {\n spawnAgent: (request) => options.manager.spawn(createAgentRequest(options, request)),\n spawnProcess: (request) => options.manager.spawn(createProcessRequest(options, request)),\n createGroup: (request) =>\n options.groupOrchestrator.createGroup({\n parentSessionId: options.sessionId,\n waitPolicy: request.waitPolicy,\n taskIds: [...request.taskIds],\n label: request.label,\n }),\n };\n}\n\nfunction createAgentRequest(\n options: ICreateExecutionWorkspaceTaskSpawnerOptions,\n request: ISpawnAgentTaskRequest,\n): IAgentBackgroundTaskRequest {\n return {\n kind: 'agent',\n label: request.label,\n mode: request.mode ?? 'background',\n parentSessionId: options.sessionId,\n parentTaskId: request.parentTaskId,\n depth: request.depth ?? 1,\n cwd: request.cwd ?? options.cwd,\n agentType: request.agentType,\n prompt: request.prompt,\n model: request.model,\n isolation: request.isolation,\n allowedTools: request.allowedTools ? [...request.allowedTools] : undefined,\n disallowedTools: request.disallowedTools ? [...request.disallowedTools] : undefined,\n permissionPolicy: request.permissionPolicy ?? 'inherit-allowlist',\n timeoutMs: request.timeoutMs,\n idleTimeoutMs: request.idleTimeoutMs,\n maxRuntimeMs: request.maxRuntimeMs,\n outputLimitBytes: request.outputLimitBytes,\n maxTextDeltas: request.maxTextDeltas,\n repetitionWindow: request.repetitionWindow,\n repetitionThreshold: request.repetitionThreshold,\n metadata: createExecutionOriginMetadata(options.origin),\n };\n}\n\nfunction createProcessRequest(\n options: ICreateExecutionWorkspaceTaskSpawnerOptions,\n request: ISpawnProcessTaskRequest,\n): IProcessBackgroundTaskRequest {\n return {\n kind: 'process',\n label: request.label ?? request.command,\n mode: request.mode ?? 'background',\n parentSessionId: options.sessionId,\n parentTaskId: request.parentTaskId,\n depth: request.depth ?? 0,\n cwd: request.cwd ?? options.cwd,\n command: request.command,\n shell: request.shell,\n env: request.env,\n stdin: request.stdin,\n timeoutMs: request.timeoutMs,\n idleTimeoutMs: request.idleTimeoutMs,\n maxRuntimeMs: request.maxRuntimeMs,\n outputLimitBytes: request.outputLimitBytes,\n metadata: createExecutionOriginMetadata(options.origin),\n };\n}\n","import type { IBackgroundTaskManager } from './index.js';\n\nconst sessionBackgroundTaskManagers = new WeakMap<object, IBackgroundTaskManager>();\n\nexport function storeSessionBackgroundTaskManager(\n key: object,\n manager: IBackgroundTaskManager,\n): void {\n sessionBackgroundTaskManagers.set(key, manager);\n}\n\nexport function retrieveSessionBackgroundTaskManager(\n key: object,\n): IBackgroundTaskManager | undefined {\n return sessionBackgroundTaskManagers.get(key);\n}\n","import type { IAgentToolDeps } from './agent-tool.js';\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type {\n ISubagentJobResult,\n ISubagentManager,\n ISubagentSpawnRequest,\n} from '../subagents/index.js';\n\nexport interface IAgentToolBatchJobArgs {\n label?: string;\n prompt: string;\n subagent_type?: string;\n model?: string;\n isolation?: 'none' | 'worktree';\n}\n\ninterface IAgentBatchJobResult {\n index: number;\n success: boolean;\n groupId: string;\n label: string;\n agentId?: string;\n subagent_type: string;\n prompt: string;\n output?: string;\n error?: string;\n metadata?: ISubagentJobResult['metadata'];\n}\n\ninterface IResolvedBatchJob {\n index: number;\n job: IAgentToolBatchJobArgs;\n agentType: string;\n agentDef?: IAgentDefinition;\n label: string;\n}\n\ntype TValidResolvedBatchJob = IResolvedBatchJob & { agentDef: IAgentDefinition };\ntype TStartedBatchJob = TValidResolvedBatchJob &\n ({ agentId: string; spawnError?: undefined } | { agentId?: undefined; spawnError: string });\n\ninterface IRunManagedAgentBatchInput {\n jobs: IAgentToolBatchJobArgs[];\n deps: IAgentToolDeps;\n manager: ISubagentManager;\n resolveAgentDefinition: (\n agentType: string,\n customRegistry?: (name: string) => IAgentDefinition | undefined,\n ) => IAgentDefinition | undefined;\n createSpawnRequest: (\n args: IAgentToolBatchJobArgs,\n agentType: string,\n agentDef: IAgentDefinition,\n deps: IAgentToolDeps,\n label?: string,\n ) => ISubagentSpawnRequest;\n}\n\nfunction stringifyAgentBatchResult(input: {\n groupId: string;\n requestedJobCount: number;\n jobs: IAgentBatchJobResult[];\n}): string {\n const successfulJobs = input.jobs.filter((job) => job.success);\n const agentIds = input.jobs\n .map((job) => job.agentId)\n .filter((agentId): agentId is string => typeof agentId === 'string' && agentId.length > 0);\n const failedJobCount = input.jobs.filter((job) => !job.success).length;\n return JSON.stringify({\n success: input.jobs.every((job) => job.success),\n mode: 'batch',\n output: successfulJobs\n .map((job) => job.output ?? '')\n .filter(Boolean)\n .join('\\n\\n'),\n groupId: input.groupId,\n requestedJobCount: input.requestedJobCount,\n startedJobCount: agentIds.length,\n failedJobCount,\n agentIds,\n jobs: input.jobs,\n provenance: {\n source: 'agent-tool-batch',\n groupId: input.groupId,\n requestedJobCount: input.requestedJobCount,\n startedJobCount: agentIds.length,\n failedJobCount,\n },\n });\n}\n\nfunction createBatchGroupId(): string {\n const idRadix = 36;\n const randomStartIndex = 2;\n const randomEndIndex = 10;\n return `agent_group_${Date.now()}_${Math.random()\n .toString(idRadix)\n .slice(randomStartIndex, randomEndIndex)}`;\n}\n\nfunction normalizeJobLabel(label: string | undefined, fallback: string): string {\n const trimmed = label?.trim();\n return trimmed && trimmed.length > 0 ? trimmed : fallback;\n}\n\nfunction resolveBatchJob(\n job: IAgentToolBatchJobArgs,\n index: number,\n input: IRunManagedAgentBatchInput,\n): IResolvedBatchJob {\n const agentType = job.subagent_type ?? 'general-purpose';\n const agentDef = input.resolveAgentDefinition(agentType, input.deps.customAgentRegistry);\n const label = normalizeJobLabel(job.label, agentDef?.name ?? agentType);\n return { index, job, agentType, agentDef, label };\n}\n\nfunction isValidBatchJob(job: IResolvedBatchJob): job is TValidResolvedBatchJob {\n return job.agentDef !== undefined;\n}\n\nfunction createUnknownAgentBatchResult(\n job: IResolvedBatchJob,\n groupId: string,\n): IAgentBatchJobResult {\n return {\n index: job.index,\n success: false,\n groupId,\n label: job.label,\n subagent_type: job.agentType,\n prompt: job.job.prompt,\n error: `Unknown agent type: ${job.agentType}`,\n };\n}\n\nasync function spawnBatchJob(\n job: TValidResolvedBatchJob,\n input: IRunManagedAgentBatchInput,\n): Promise<TStartedBatchJob> {\n try {\n const state = await input.manager.spawn(\n input.createSpawnRequest(job.job, job.agentType, job.agentDef, input.deps, job.label),\n );\n return { ...job, agentId: state.id };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { ...job, spawnError: message };\n }\n}\n\nfunction createBatchSpawnErrorResult(job: TStartedBatchJob, groupId: string): IAgentBatchJobResult {\n return {\n index: job.index,\n success: false,\n groupId,\n label: job.label,\n subagent_type: job.agentType,\n prompt: job.job.prompt,\n error: `Sub-agent error: ${job.spawnError ?? 'missing agent id'}`,\n };\n}\n\nfunction createBatchSuccessResult(\n job: TStartedBatchJob & { agentId: string },\n groupId: string,\n result: ISubagentJobResult,\n): IAgentBatchJobResult {\n return {\n index: job.index,\n success: true,\n groupId,\n label: job.label,\n agentId: result.jobId,\n subagent_type: job.agentType,\n prompt: job.job.prompt,\n output: result.output,\n metadata: result.metadata,\n };\n}\n\nfunction createBatchWaitErrorResult(\n job: TStartedBatchJob & { agentId: string },\n groupId: string,\n message: string,\n): IAgentBatchJobResult {\n return {\n index: job.index,\n success: false,\n groupId,\n label: job.label,\n agentId: job.agentId,\n subagent_type: job.agentType,\n prompt: job.job.prompt,\n error: `Sub-agent error: ${message}`,\n };\n}\n\nasync function waitBatchJob(\n job: TStartedBatchJob,\n groupId: string,\n manager: ISubagentManager,\n): Promise<IAgentBatchJobResult> {\n if (job.agentId === undefined) {\n return createBatchSpawnErrorResult(job, groupId);\n }\n\n try {\n const result = await manager.wait(job.agentId);\n return createBatchSuccessResult({ ...job, agentId: job.agentId }, groupId, result);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return createBatchWaitErrorResult({ ...job, agentId: job.agentId }, groupId, message);\n }\n}\n\nexport async function runManagedAgentBatch(input: IRunManagedAgentBatchInput): Promise<string> {\n const groupId = createBatchGroupId();\n const resolvedJobs = input.jobs.map((job, index) => resolveBatchJob(job, index, input));\n const invalidJobs = resolvedJobs\n .filter((job) => !isValidBatchJob(job))\n .map((job) => createUnknownAgentBatchResult(job, groupId));\n const startedJobs = await Promise.all(\n resolvedJobs.filter(isValidBatchJob).map((job) => spawnBatchJob(job, input)),\n );\n const terminalJobs = await Promise.all(\n startedJobs.map((job) => waitBatchJob(job, groupId, input.manager)),\n );\n const batchJobs = [...invalidJobs, ...terminalJobs].sort(\n (left, right) => left.index - right.index,\n );\n\n return stringifyAgentBatchResult({\n groupId,\n requestedJobCount: input.jobs.length,\n jobs: batchJobs,\n });\n}\n","import type { ISubagentJobResult } from '../subagents/index.js';\n\nexport function stringifyUnknownAgentType(agentType: string): string {\n return JSON.stringify({\n success: false,\n mode: 'single',\n requestedJobCount: 1,\n startedJobCount: 0,\n failedJobCount: 1,\n output: '',\n error: `Unknown agent type: ${agentType}`,\n provenance: {\n source: 'agent-tool-single',\n requestedJobCount: 1,\n startedJobCount: 0,\n failedJobCount: 1,\n },\n });\n}\n\nexport function stringifyAgentSuccess(result: ISubagentJobResult): string {\n const worktreePath = result.metadata?.['worktreePath'];\n const branchName = result.metadata?.['branchName'];\n const worktreeStatus = result.metadata?.['worktreeStatus'];\n const worktreeNextAction = result.metadata?.['worktreeNextAction'];\n return JSON.stringify({\n success: true,\n mode: 'single',\n requestedJobCount: 1,\n startedJobCount: 1,\n failedJobCount: 0,\n output: result.output,\n agentId: result.jobId,\n agentIds: [result.jobId],\n provenance: {\n source: 'agent-tool-single',\n requestedJobCount: 1,\n startedJobCount: 1,\n failedJobCount: 0,\n },\n metadata: result.metadata,\n ...(typeof worktreePath === 'string' ? { worktreePath } : {}),\n ...(typeof branchName === 'string' ? { branchName } : {}),\n ...(typeof worktreeStatus === 'string' ? { worktreeStatus } : {}),\n ...(typeof worktreeNextAction === 'string' ? { worktreeNextAction } : {}),\n });\n}\n\nexport function stringifyAgentError(message: string, agentId?: string): string {\n const startedJobCount = agentId === undefined ? 0 : 1;\n return JSON.stringify({\n success: false,\n mode: 'single',\n requestedJobCount: 1,\n startedJobCount,\n failedJobCount: 1,\n output: '',\n error: `Sub-agent error: ${message}`,\n agentId,\n ...(agentId !== undefined ? { agentIds: [agentId] } : {}),\n provenance: {\n source: 'agent-tool-single',\n requestedJobCount: 1,\n startedJobCount,\n failedJobCount: 1,\n },\n });\n}\n","import type { IAgentDefinition } from './agent-definition-types.js';\n\nconst GENERAL_PURPOSE_SYSTEM_PROMPT = `You are a general-purpose task execution agent. You have access to all tools available in the parent session and can perform any task delegated to you.\n\nYour role is to complete the assigned task thoroughly and accurately. Follow these guidelines:\n\n- Execute the task as described in the prompt. Do not expand scope beyond what is requested.\n- Use the most appropriate tools for each step. Prefer precise tools (Read, Grep, Glob) over broad ones (Bash) when possible.\n- Report your findings clearly and concisely when the task is complete.\n- If a task cannot be completed, explain why and what information is missing.\n- Maintain the same code quality standards as the parent session (strict types, no fallbacks, proper error handling).`;\n\nconst EXPLORE_SYSTEM_PROMPT = `You are a codebase exploration and analysis agent. Your purpose is to search, read, and understand code without making any modifications.\n\nYou operate in read-only mode. You must NEVER attempt to write or edit files. Your tools are restricted to read-only operations: reading files, searching with grep and glob, and running non-destructive bash commands.\n\nYour role is to answer questions about the codebase by:\n\n- Searching for relevant files, symbols, and patterns using Glob and Grep.\n- Reading source files, configuration, and documentation to understand structure and behavior.\n- Tracing code paths across modules to understand how components interact.\n- Summarizing findings in a clear, structured format with file paths and line references.\n- Identifying architectural patterns, dependencies, and potential issues.\n\nWhen exploring, prefer targeted searches over broad scans. Start with the most likely locations and narrow down. Always include absolute file paths in your responses so the caller can navigate directly to relevant code.`;\n\nconst PLAN_SYSTEM_PROMPT = `You are a planning, research, and architecture agent. Your purpose is to analyze requirements, research approaches, and produce structured plans without making any code modifications.\n\nYou operate in read-only mode. You must NEVER attempt to write or edit files. Your tools are restricted to read-only operations.\n\nYour role is to:\n\n- Analyze the current codebase state relevant to the task by reading specs, source code, and tests.\n- Research implementation approaches by examining existing patterns and architectural conventions in the repository.\n- Identify affected files, modules, and interfaces that a proposed change would touch.\n- Assess risks, dependencies, and potential breaking changes.\n- Produce a structured implementation plan with clear steps, file lists, and ordering.\n- Consider edge cases, error handling, and test coverage requirements.\n\nOutput your plan in a structured format with numbered steps. For each step, specify which files are involved and what changes are needed. Flag any decisions that require human judgment or clarification.`;\n\n/**\n * All built-in agent definitions shipped with the SDK.\n * Order matters: general-purpose is the default fallback.\n */\nexport const BUILT_IN_AGENTS: IAgentDefinition[] = [\n {\n name: 'general-purpose',\n description: 'General-purpose task execution agent with full tool access.',\n systemPrompt: GENERAL_PURPOSE_SYSTEM_PROMPT,\n },\n {\n name: 'Explore',\n description: 'Read-only codebase exploration and analysis agent.',\n systemPrompt: EXPLORE_SYSTEM_PROMPT,\n disallowedTools: ['Write', 'Edit'],\n },\n {\n name: 'Plan',\n description: 'Read-only planning, research, and architecture agent.',\n systemPrompt: PLAN_SYSTEM_PROMPT,\n disallowedTools: ['Write', 'Edit'],\n },\n];\n\n/**\n * Look up a built-in agent definition by name.\n * Returns `undefined` if no built-in agent matches.\n */\nexport function getBuiltInAgent(name: string): IAgentDefinition | undefined {\n return BUILT_IN_AGENTS.find((agent) => agent.name === name);\n}\n","/**\n * Framework system prompt suffixes for subagent sessions.\n *\n * These functions generate the standard prompt content injected into\n * subagent sessions to control output format and behavior.\n */\n\n/** Options for assembling a subagent system prompt. */\nexport interface ISubagentPromptOptions {\n /** Agent definition markdown body. */\n agentBody: string;\n /** CLAUDE.md content to include. */\n claudeMd?: string;\n /** AGENTS.md content to include. */\n agentsMd?: string;\n /** When true, use fork worker suffix instead of standard subagent suffix. */\n isForkWorker: boolean;\n}\n\n/**\n * Returns the standard subagent suffix appended to agent body for normal subagents.\n */\nexport function getSubagentSuffix(): string {\n return `When you complete the task, respond with a concise report covering what was done and any key findings — the caller will relay this to the user, so it only needs the essentials.\n\nIn your final response, share file paths (always absolute, never relative) that are relevant to the task. Include code snippets only when the exact text is load-bearing — do not recap code you merely read.\n\nDo not use emojis.`;\n}\n\n/**\n * Returns the fork worker suffix for context:fork skill workers.\n */\nexport function getForkWorkerSuffix(): string {\n return `You are a worker subagent executing a specific task. Do NOT spawn sub-agents; execute directly. Keep your report under 500 words. Use this structure:\n- Scope: What was requested\n- Result: What was done\n- Key files: Relevant file paths (absolute)\n- Files changed: List of modifications\n- Issues: Any problems encountered`;\n}\n\n/**\n * Assembles the full system prompt for a subagent.\n *\n * Assembly order:\n * 1. Agent definition body\n * 2. CLAUDE.md content (if provided)\n * 3. AGENTS.md content (if provided)\n * 4. Framework suffix (fork worker OR standard subagent)\n */\nexport function assembleSubagentPrompt(options: ISubagentPromptOptions): string {\n const parts: string[] = [options.agentBody];\n\n if (options.claudeMd) {\n parts.push(options.claudeMd);\n }\n\n if (options.agentsMd) {\n parts.push(options.agentsMd);\n }\n\n const suffix = options.isForkWorker ? getForkWorkerSuffix() : getSubagentSuffix();\n parts.push(suffix);\n\n return parts.join('\\n\\n');\n}\n","import { createHash } from 'node:crypto';\n\nimport { createZodFunctionTool } from '@robota-sdk/agent-tools';\nimport { z } from 'zod';\n\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { ICommandResult } from '../commands/index.js';\nimport type { IZodSchema } from '@robota-sdk/agent-tools';\n\nexport const MODEL_COMMAND_TOOL_PREFIX = 'robota_command_' as const;\nexport const PROVIDER_SAFE_TOOL_NAME_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;\n\nconst MAX_PROVIDER_TOOL_NAME_LENGTH = 64;\nconst HASH_LENGTH = 8;\nconst HASH_SEPARATOR_LENGTH = 1;\n\ntype TModelCommandDescriptor = Pick<ICapabilityDescriptor, 'name' | 'description' | 'argumentHint'>;\n\ninterface IProjectedCommandArgs {\n args?: string;\n}\n\nexport interface IProjectedModelCommandTool {\n readonly commandName: string;\n readonly toolName: string;\n readonly description: string;\n readonly descriptor: TModelCommandDescriptor;\n}\n\nexport interface IModelCommandToolProjection {\n readonly commandTools: readonly IProjectedModelCommandTool[];\n readonly toolNameToCommandName: ReadonlyMap<string, string>;\n readonly commandNameToToolName: ReadonlyMap<string, string>;\n}\n\nexport interface IProjectedCommandExecutionToolsDeps {\n isModelInvocable: (command: string) => boolean;\n execute: (command: string, args: string) => Promise<ICommandResult | null>;\n commandDescriptors: readonly TModelCommandDescriptor[];\n}\n\nfunction asZodSchema(schema: z.ZodType): IZodSchema {\n return schema as IZodSchema;\n}\n\nexport function normalizeModelCommandName(command: string): string {\n return command.trim().replace(/^\\/+/, '').split(/\\s+/)[0] ?? '';\n}\n\nexport function createProviderSafeModelCommandToolName(commandName: string): string {\n const normalizedCommandName = normalizeModelCommandName(commandName);\n if (!normalizedCommandName) {\n throw new Error('Model command descriptor name must not be empty.');\n }\n\n const safeBody = normalizedCommandName\n .replace(/[^A-Za-z0-9_-]/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_+|_+$/g, '');\n if (!safeBody) {\n throw new Error(`Model command descriptor name cannot be projected safely: ${commandName}`);\n }\n\n const rawToolName = `${MODEL_COMMAND_TOOL_PREFIX}${safeBody}`;\n if (PROVIDER_SAFE_TOOL_NAME_PATTERN.test(rawToolName)) {\n return rawToolName;\n }\n\n const hash = createHash('sha256')\n .update(normalizedCommandName)\n .digest('hex')\n .slice(0, HASH_LENGTH);\n const maxBodyLength =\n MAX_PROVIDER_TOOL_NAME_LENGTH -\n MODEL_COMMAND_TOOL_PREFIX.length -\n HASH_SEPARATOR_LENGTH -\n HASH_LENGTH;\n if (maxBodyLength < 1) {\n throw new Error('Model command tool prefix leaves no room for command names.');\n }\n\n const truncatedBody = safeBody.slice(0, maxBodyLength).replace(/[_-]+$/g, '') || 'command';\n const toolName = `${MODEL_COMMAND_TOOL_PREFIX}${truncatedBody}_${hash}`;\n if (!PROVIDER_SAFE_TOOL_NAME_PATTERN.test(toolName)) {\n throw new Error(`Projected model command tool name is not provider-safe: ${toolName}`);\n }\n return toolName;\n}\n\nexport function createModelCommandToolProjection(\n commandDescriptors: readonly TModelCommandDescriptor[],\n): IModelCommandToolProjection {\n const commandNames = new Set<string>();\n const toolNameToCommandName = new Map<string, string>();\n const commandNameToToolName = new Map<string, string>();\n const commandTools: IProjectedModelCommandTool[] = [];\n\n for (const descriptor of commandDescriptors) {\n const commandName = normalizeModelCommandName(descriptor.name);\n if (!commandName) {\n throw new Error('Model command descriptor name must not be empty.');\n }\n if (commandNames.has(commandName)) {\n throw new Error(`Duplicate model command descriptor: ${commandName}`);\n }\n commandNames.add(commandName);\n\n const toolName = createProviderSafeModelCommandToolName(commandName);\n const existingCommandName = toolNameToCommandName.get(toolName);\n if (existingCommandName !== undefined) {\n throw new Error(\n `Model command projection collision: ${existingCommandName} and ${commandName} both map to ${toolName}`,\n );\n }\n\n toolNameToCommandName.set(toolName, commandName);\n commandNameToToolName.set(commandName, toolName);\n commandTools.push({\n commandName,\n toolName,\n description: formatProjectedModelCommandToolDescription(commandName, descriptor),\n descriptor,\n });\n }\n\n return {\n commandTools,\n toolNameToCommandName,\n commandNameToToolName,\n };\n}\n\nexport function formatProjectedModelCommandToolPromptDescription(\n projection: IProjectedModelCommandTool,\n): string {\n return `${projection.toolName} — ${projection.descriptor.description}`;\n}\n\nexport function stringifyModelCommandResult(\n command: string,\n result: ICommandResult | null,\n): string {\n if (!result) {\n return JSON.stringify({\n success: false,\n command,\n error: `Unknown command: ${command}`,\n });\n }\n return JSON.stringify({\n success: result.success,\n command,\n message: result.message,\n data: result.data,\n });\n}\n\nexport function createProjectedCommandExecutionTools(\n deps: IProjectedCommandExecutionToolsDeps,\n): Array<ReturnType<typeof createZodFunctionTool>> {\n const projection = createModelCommandToolProjection(deps.commandDescriptors);\n return projection.commandTools.map((projectedTool) => {\n const schema = createProjectedCommandArgsSchema(projectedTool.descriptor);\n return createZodFunctionTool(\n projectedTool.toolName,\n projectedTool.description,\n asZodSchema(schema),\n async (params) => {\n const parsedParams: IProjectedCommandArgs = schema.parse(params);\n if (!deps.isModelInvocable(projectedTool.commandName)) {\n return JSON.stringify({\n success: false,\n command: projectedTool.commandName,\n error: `Command is not model-invocable: ${projectedTool.commandName}`,\n });\n }\n return stringifyModelCommandResult(\n projectedTool.commandName,\n await deps.execute(projectedTool.commandName, parsedParams.args ?? ''),\n );\n },\n );\n });\n}\n\nfunction createProjectedCommandArgsSchema(\n descriptor: TModelCommandDescriptor,\n): z.ZodType<IProjectedCommandArgs> {\n const argsDescription = descriptor.argumentHint\n ? `Arguments for the command. Expected grammar: ${descriptor.argumentHint}`\n : 'Arguments for the command as a single string.';\n\n return z.object({\n args: z.string().optional().describe(argsDescription),\n });\n}\n\nfunction formatProjectedModelCommandToolDescription(\n commandName: string,\n descriptor: TModelCommandDescriptor,\n): string {\n const lines = [descriptor.description.trim(), `Robota command id: ${commandName}.`];\n if (descriptor.argumentHint) {\n lines.push(`Argument grammar: ${descriptor.argumentHint}`);\n }\n return lines.filter((line) => line.length > 0).join('\\n\\n');\n}\n","/**\n * Subagent session factory — assembles an isolated child Session for subagent execution.\n *\n * Unlike `createSession`, this factory does not load config files or context from disk.\n * It receives pre-resolved config and context from the parent session, applies tool\n * filtering and model resolution from the agent definition, and creates a lightweight\n * Session suitable for subagent use.\n */\n\nimport { Session } from '@robota-sdk/agent-session';\n\nimport { assembleSubagentPrompt } from './subagent-prompts.js';\nimport { createProviderSafeModelCommandToolName } from '../tools/model-command-tool-projection.js';\n\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type { IResolvedConfig } from '../config/config-types.js';\nimport type { ILoadedContext } from '../context/context-loader.js';\nimport type { IToolWithEventService, IHookTypeExecutor } from '@robota-sdk/agent-core';\nimport type { TPermissionMode, TToolArgs } from '@robota-sdk/agent-core';\nimport type { IAIProvider } from '@robota-sdk/agent-core';\nimport type {\n ISessionLogger,\n ITerminalOutput,\n TPermissionHandler,\n} from '@robota-sdk/agent-session';\n\n/** Model shortcut names mapped to full Anthropic model IDs. */\nconst MODEL_SHORTCUTS: Record<string, string> = {\n sonnet: 'claude-sonnet-4-6',\n haiku: 'claude-haiku-4-5',\n opus: 'claude-opus-4-6',\n};\nconst LEGACY_AGENT_TOOL_NAME = 'Agent';\nconst PROJECTED_AGENT_COMMAND_TOOL_NAME = createProviderSafeModelCommandToolName('agent');\n\n/** Options for creating a subagent session. */\nexport interface ISubagentOptions {\n /** Agent definition (built-in or custom). */\n agentDefinition: IAgentDefinition;\n /** Parent's resolved config (for provider, permissions, etc.). */\n parentConfig: IResolvedConfig;\n /** Parent's loaded context (CLAUDE.md, AGENTS.md). */\n parentContext: ILoadedContext;\n /** Parent session's available tools (to inherit/filter). */\n parentTools: IToolWithEventService[];\n /** AI provider instance. */\n provider: IAIProvider;\n /** Terminal output interface. */\n terminal: ITerminalOutput;\n /** Stable session ID for transcript files. */\n sessionId?: string;\n /** Optional logger for subagent transcripts. */\n sessionLogger?: ISessionLogger;\n /** Whether this is a fork worker (uses fork suffix instead of standard). */\n isForkWorker?: boolean;\n /** Permission mode from parent (bypassPermissions, acceptEdits, etc.). */\n permissionMode?: TPermissionMode;\n /** Permission handler from parent. */\n permissionHandler?: TPermissionHandler;\n /** Plugin hooks configuration from parent session. */\n hooks?: Record<string, unknown>;\n /** Hook type executors from parent session (prompt, agent, etc.). */\n hookTypeExecutors?: IHookTypeExecutor[];\n /** Streaming callback. */\n onTextDelta?: (delta: string) => void;\n /** Tool execution callback. */\n onToolExecution?: (event: {\n type: 'start' | 'end';\n toolName: string;\n toolArgs?: TToolArgs;\n success?: boolean;\n denied?: boolean;\n toolResultData?: string;\n }) => void;\n}\n\n/**\n * Resolve a model shortcut name to a full model ID.\n * Returns the shortcut mapping if found, otherwise returns the input as-is.\n */\nfunction resolveModelId(shortName: string, _parentModel: string): string {\n return MODEL_SHORTCUTS[shortName] ?? shortName;\n}\n\n/**\n * Filter parent tools according to the agent definition's tool constraints.\n *\n * Filtering order:\n * 1. Remove disallowed tools (denylist)\n * 2. Keep only allowed tools (allowlist), if specified\n * 3. Always remove agent-spawning tools (subagents cannot spawn subagents)\n */\nfunction filterTools(\n parentTools: IToolWithEventService[],\n agentDefinition: IAgentDefinition,\n): IToolWithEventService[] {\n let tools = [...parentTools];\n\n // Step 1: Remove disallowed tools\n if (agentDefinition.disallowedTools) {\n const denySet = new Set(agentDefinition.disallowedTools);\n tools = tools.filter((t) => !denySet.has(t.getName()));\n }\n\n // Step 2: Keep only allowed tools (if allowlist specified)\n if (agentDefinition.tools) {\n const allowSet = new Set(agentDefinition.tools);\n tools = tools.filter((t) => allowSet.has(t.getName()));\n }\n\n // Step 3: Always remove agent-spawning tools\n tools = tools.filter(\n (t) =>\n t.getName() !== LEGACY_AGENT_TOOL_NAME && t.getName() !== PROJECTED_AGENT_COMMAND_TOOL_NAME,\n );\n\n return tools;\n}\n\n/**\n * Create a fully-configured Session for subagent execution.\n *\n * Assembles provider, tools, and system prompt from parent context and\n * agent definition, then returns a new Session instance.\n */\nexport function createSubagentSession(options: ISubagentOptions): Session {\n const { agentDefinition, parentConfig, parentContext, parentTools, terminal } = options;\n\n // Filter tools based on agent definition constraints\n const tools = filterTools(parentTools, agentDefinition);\n\n // Resolve model: agent override or parent model\n const model = agentDefinition.model\n ? resolveModelId(agentDefinition.model, parentConfig.provider.model)\n : parentConfig.provider.model;\n\n // Assemble system prompt with framework suffix\n const systemMessage = assembleSubagentPrompt({\n agentBody: agentDefinition.systemPrompt,\n claudeMd: parentContext.claudeMd,\n agentsMd: parentContext.agentsMd,\n isForkWorker: options.isForkWorker ?? false,\n });\n\n const provider = options.provider;\n\n return new Session({\n tools,\n provider,\n systemMessage,\n terminal,\n ...(options.sessionId !== undefined ? { sessionId: options.sessionId } : {}),\n ...(options.sessionLogger !== undefined ? { sessionLogger: options.sessionLogger } : {}),\n model,\n maxTurns: agentDefinition.maxTurns,\n permissions: parentConfig.permissions,\n permissionMode: options.permissionMode,\n defaultTrustLevel: parentConfig.defaultTrustLevel,\n permissionHandler: options.permissionHandler,\n hooks: options.hooks,\n hookTypeExecutors: options.hookTypeExecutors,\n onTextDelta: options.onTextDelta,\n onToolExecution: options.onToolExecution,\n });\n}\n","import { getBuiltInAgent } from '../agents/built-in-agents.js';\nimport { createSubagentSession } from '../assembly/create-subagent-session.js';\n\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type { ISubagentOptions } from '../assembly/create-subagent-session.js';\nimport type { IResolvedConfig } from '../config/config-types.js';\nimport type { ILoadedContext } from '../context/context-loader.js';\nimport type { ITerminalOutput } from '@robota-sdk/agent-core';\nimport type {\n IAIProvider,\n IHookTypeExecutor,\n IToolWithEventService,\n TPermissionMode,\n TToolArgs,\n} from '@robota-sdk/agent-core';\nimport type {\n ISubagentJobHandle,\n ISubagentJobStart,\n ISubagentRunner,\n} from '@robota-sdk/agent-executor';\nimport type { TPermissionHandler } from '@robota-sdk/agent-session';\n\ntype TSubagentToolExecutionEvent = Parameters<\n NonNullable<IInProcessSubagentRunnerDeps['onToolExecution']>\n>[0];\n\nexport interface IInProcessSubagentRunnerDeps {\n config: IResolvedConfig;\n context: ILoadedContext;\n tools: IToolWithEventService[];\n terminal: ITerminalOutput;\n provider: IAIProvider;\n permissionMode?: TPermissionMode;\n permissionHandler?: TPermissionHandler;\n hooks?: ISubagentOptions['hooks'];\n hookTypeExecutors?: IHookTypeExecutor[];\n onTextDelta?: (delta: string) => void;\n onToolExecution?: (event: {\n type: 'start' | 'end';\n toolName: string;\n toolArgs?: TToolArgs;\n success?: boolean;\n denied?: boolean;\n toolResultData?: string;\n }) => void;\n customAgentRegistry?: (name: string) => IAgentDefinition | undefined;\n}\n\nexport type TSubagentRunnerFactory = (deps: IInProcessSubagentRunnerDeps) => ISubagentRunner;\n\nfunction resolveAgentDefinition(\n agentType: string,\n customRegistry?: (name: string) => IAgentDefinition | undefined,\n): IAgentDefinition {\n const definition = customRegistry?.(agentType) ?? getBuiltInAgent(agentType);\n if (!definition) {\n throw new Error(`Unknown agent type: ${agentType}`);\n }\n return definition;\n}\n\nfunction applyRequestOverrides(\n definition: IAgentDefinition,\n job: ISubagentJobStart,\n): IAgentDefinition {\n return {\n ...definition,\n ...(job.request.model ? { model: job.request.model } : {}),\n ...(job.request.allowedTools ? { tools: job.request.allowedTools } : {}),\n ...(job.request.disallowedTools ? { disallowedTools: job.request.disallowedTools } : {}),\n };\n}\n\nfunction extractFirstArg(toolArgs?: TToolArgs): string | undefined {\n if (!toolArgs) return undefined;\n const firstValue = Object.values(toolArgs)[0];\n if (firstValue === undefined) return undefined;\n return typeof firstValue === 'object' ? JSON.stringify(firstValue) : String(firstValue);\n}\n\nfunction assertSupportedIsolation(job: ISubagentJobStart): void {\n if (job.request.isolation === 'worktree') {\n throw new Error('Worktree isolation requires a runtime shell subagent runner');\n }\n}\n\nfunction emitToolExecutionEvent(job: ISubagentJobStart, event: TSubagentToolExecutionEvent): void {\n if (event.type === 'start') {\n job.emit?.({\n type: 'background_task_tool_start',\n toolName: event.toolName,\n firstArg: extractFirstArg(event.toolArgs),\n });\n return;\n }\n\n job.emit?.({\n type: 'background_task_tool_end',\n toolName: event.toolName,\n success: event.success ?? true,\n });\n}\n\nexport function createInProcessSubagentRunner(deps: IInProcessSubagentRunnerDeps): ISubagentRunner {\n return {\n start(job: ISubagentJobStart): ISubagentJobHandle {\n assertSupportedIsolation(job);\n const definition = resolveAgentDefinition(job.request.type, deps.customAgentRegistry);\n const session = createSubagentSession({\n agentDefinition: applyRequestOverrides(definition, job),\n parentConfig: deps.config,\n parentContext: deps.context,\n parentTools: deps.tools,\n provider: deps.provider,\n terminal: deps.terminal,\n permissionMode: deps.permissionMode,\n permissionHandler: deps.permissionHandler,\n hooks: deps.hooks,\n hookTypeExecutors: deps.hookTypeExecutors,\n onTextDelta: (delta) => {\n job.emit?.({ type: 'background_task_text_delta', delta });\n deps.onTextDelta?.(delta);\n },\n onToolExecution: (event) => {\n emitToolExecutionEvent(job, event);\n deps.onToolExecution?.(event);\n },\n });\n\n return {\n jobId: job.jobId,\n result: session.run(job.request.prompt).then((output) => ({\n jobId: job.jobId,\n output,\n })),\n cancel: () => {\n session.abort();\n return Promise.resolve();\n },\n };\n },\n };\n}\n","/**\n * AgentTool — spawn a sub-agent with isolated context.\n *\n * Uses `SubagentManager` with an in-process runner to assemble a child Session\n * with filtered tools, model resolution, and framework system prompt. The\n * sub-agent shares the same config and context but has its own conversation\n * history.\n *\n * Each call to `createAgentTool(deps)` returns a fresh tool instance with deps\n * captured in closure, eliminating module-level mutable state and enabling\n * multiple concurrent sessions without race conditions.\n */\n\nimport { SubagentManager } from '@robota-sdk/agent-executor';\nimport { createZodFunctionTool } from '@robota-sdk/agent-tools';\nimport { z } from 'zod';\n\nimport { runManagedAgentBatch } from './agent-tool-batch.js';\nimport {\n stringifyAgentError,\n stringifyAgentSuccess,\n stringifyUnknownAgentType,\n} from './agent-tool-output.js';\nimport { getBuiltInAgent } from '../agents/built-in-agents.js';\nimport { createExecutionOriginMetadata } from '../background-tasks/index.js';\nimport { createInProcessSubagentRunner } from '../subagents/in-process-subagent-runner.js';\n\nimport type { IAgentToolBatchJobArgs } from './agent-tool-batch.js';\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type { IBackgroundTaskManager } from '../background-tasks/index.js';\nimport type {\n IInProcessSubagentRunnerDeps,\n ISubagentManager,\n ISubagentJobResult,\n ISubagentSpawnRequest,\n} from '../subagents/index.js';\nimport type { IZodSchema } from '@robota-sdk/agent-tools';\n\nexport const AGENT_TOOL_DESCRIPTION = [\n 'Creates delegated subagent jobs in isolated contexts.',\n 'Without jobs, one tool call creates one subagent job from prompt.',\n 'For explicit multi-agent or parallel-agent requests, use one Agent tool call with jobs containing one entry per requested role and a stable label for each role.',\n 'When the user explicitly asks to create, run, spawn, delegate to, or use agents/subagents, start the requested subagent job immediately.',\n 'Do not ask a follow-up question unless execution is impossible or unsafe.',\n 'Subagent jobs run as background tasks by default.',\n 'The tool waits for a terminal result and returns completed, failed, or timed-out outcome data with structured requested/started job counts.',\n 'After the tool returns, base user-facing claims on returned mode and counts; do not say parallel or multiple jobs started unless the result proves those jobs started.',\n 'Execution is represented by a real tool call and runtime background task event.',\n].join(' ');\n\nexport function createAgentToolPromptDescription(\n agentDefinitions: readonly Pick<IAgentDefinition, 'name' | 'description'>[] = [],\n): string {\n const availableAgents =\n agentDefinitions.length > 0\n ? ` Available agent types: ${agentDefinitions\n .map((agent) => `${agent.name} (${agent.description})`)\n .join(', ')}.`\n : '';\n return [\n 'Agent — creates isolated subagent jobs.',\n 'Without jobs, one Agent tool call corresponds to one subagent job.',\n 'For explicit multi-agent or parallel-agent requests, use one Agent tool call with jobs containing one entry per requested role and a stable label for each role.',\n 'When the user explicitly asks to create, run, spawn, delegate to, or use agents/subagents, start the requested subagent job immediately.',\n 'Do not ask a follow-up question unless execution is impossible or unsafe.',\n 'The tool returns terminal result data with mode, requestedJobCount, startedJobCount, failedJobCount, and provenance.',\n 'After the tool returns, base user-facing claims on returned mode and counts; do not say parallel or multiple jobs started unless the result proves those jobs started.',\n 'Runtime mode is background.',\n availableAgents,\n ]\n .join(' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/** Cast a Zod schema to the IZodSchema interface expected by createZodFunctionTool */\nfunction asZodSchema(schema: z.ZodType): IZodSchema {\n return schema as IZodSchema;\n}\n\nconst AgentSchema = z\n .object({\n prompt: z\n .string()\n .optional()\n .describe('The task for a single subagent to perform. Required when jobs is omitted.'),\n subagent_type: z\n .string()\n .optional()\n .describe('Agent type: \"general-purpose\", \"Explore\", \"Plan\", or a custom agent name'),\n model: z.string().optional().describe('Optional model override'),\n isolation: z\n .enum(['none', 'worktree'])\n .optional()\n .describe('Optional runtime isolation mode. \"worktree\" runs in a Git worktree.'),\n jobs: z\n .array(\n z\n .object({\n label: z.string().optional().describe('Stable role label for this batch job'),\n prompt: z.string().describe('The task for this subagent to perform'),\n subagent_type: z.string().optional().describe('Agent type for this job'),\n model: z.string().optional().describe('Optional model override for this job'),\n isolation: z.enum(['none', 'worktree']).optional().describe('Isolation for this job'),\n })\n .passthrough(),\n )\n .optional()\n .describe('Batch of subagent jobs to start in one Agent tool call'),\n })\n .passthrough();\n\ntype TAgentArgs = z.infer<typeof AgentSchema>;\ntype TAgentJobArgs = IAgentToolBatchJobArgs;\ntype TSingleAgentArgs = TAgentArgs & { prompt: string };\n\n/** Dependencies injected at creation time via createAgentTool factory */\nexport interface IAgentToolDeps extends IInProcessSubagentRunnerDeps {\n cwd?: string;\n parentSessionId?: string;\n subagentDepth?: number;\n subagentManager?: ISubagentManager;\n backgroundTaskManager?: IBackgroundTaskManager;\n /** Optional custom agent registry for resolving non-built-in agent types. */\n customAgentRegistry?: (name: string) => IAgentDefinition | undefined;\n /** Model-visible and command-visible agent definitions available to this session. */\n agentDefinitions?: IAgentDefinition[];\n}\n\n/**\n * Per-session deps store — maps an opaque key (typically a Session instance) to\n * the IAgentToolDeps used when creating that session's agent tool.\n *\n * This replaces the former module-level singleton, enabling concurrent sessions\n * without overwriting each other's deps.\n */\nconst sessionDepsStore = new WeakMap<object, IAgentToolDeps>();\n\n/** Store agent tool deps keyed by a session (or any object). */\nexport function storeAgentToolDeps(key: object, deps: IAgentToolDeps): void {\n sessionDepsStore.set(key, deps);\n}\n\n/** Retrieve agent tool deps for a given session key. */\nexport function retrieveAgentToolDeps(key: object): IAgentToolDeps | undefined {\n return sessionDepsStore.get(key);\n}\n\n/**\n * Resolve an agent type name to an IAgentDefinition.\n * Checks custom registry first so project/user definitions can override built-ins.\n */\nfunction resolveAgentDefinition(\n agentType: string,\n customRegistry?: (name: string) => IAgentDefinition | undefined,\n): IAgentDefinition | undefined {\n if (customRegistry) {\n const custom = customRegistry(agentType);\n if (custom) return custom;\n }\n const builtIn = getBuiltInAgent(agentType);\n if (builtIn) return builtIn;\n return undefined;\n}\n\nfunction createSubagentManager(deps: IAgentToolDeps): ISubagentManager {\n return (\n deps.subagentManager ??\n new SubagentManager({\n runner: createInProcessSubagentRunner(deps),\n })\n );\n}\n\nfunction createSpawnRequest(\n args: TSingleAgentArgs | TAgentJobArgs,\n agentType: string,\n agentDef: IAgentDefinition,\n deps: IAgentToolDeps,\n label = agentDef.name,\n): ISubagentSpawnRequest {\n return {\n type: agentType,\n label,\n parentSessionId: deps.parentSessionId ?? 'unknown-session',\n mode: 'background',\n depth: deps.subagentDepth ?? 1,\n cwd: deps.cwd ?? process.cwd(),\n prompt: args.prompt,\n model: args.model,\n isolation: args.isolation,\n metadata: createExecutionOriginMetadata({\n kind: 'tool_call',\n sessionId: deps.parentSessionId ?? 'unknown-session',\n label,\n }),\n };\n}\n\nasync function runManagedAgent(\n args: TAgentArgs,\n deps: IAgentToolDeps,\n manager: ISubagentManager,\n): Promise<string> {\n if (typeof args.prompt !== 'string' || args.prompt.length === 0) {\n return stringifyAgentError('prompt is required when jobs is omitted');\n }\n\n const singleArgs: TSingleAgentArgs = { ...args, prompt: args.prompt };\n const agentType = args.subagent_type ?? 'general-purpose';\n const agentDef = resolveAgentDefinition(agentType, deps.customAgentRegistry);\n if (!agentDef) {\n return stringifyUnknownAgentType(agentType);\n }\n\n let agentId: string | undefined;\n try {\n const state = await manager.spawn(createSpawnRequest(singleArgs, agentType, agentDef, deps));\n agentId = state.id;\n const response = await manager.wait(state.id);\n return stringifyAgentSuccess(response);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return stringifyAgentError(message, agentId);\n }\n}\n\n/**\n * Create an agent tool instance with deps captured in closure.\n *\n * Each session gets its own tool instance — no shared mutable state.\n */\nexport function createAgentTool(deps: IAgentToolDeps): ReturnType<typeof createZodFunctionTool> {\n const manager = createSubagentManager(deps);\n\n return createZodFunctionTool(\n 'Agent',\n AGENT_TOOL_DESCRIPTION,\n asZodSchema(AgentSchema),\n async (params) => {\n const args = params as TAgentArgs;\n if (Array.isArray(args.jobs) && args.jobs.length > 0) {\n return runManagedAgentBatch({\n jobs: args.jobs as TAgentJobArgs[],\n deps,\n manager,\n resolveAgentDefinition,\n createSpawnRequest,\n });\n }\n return runManagedAgent(\n {\n prompt: args.prompt,\n ...(args.subagent_type !== undefined ? { subagent_type: args.subagent_type } : {}),\n ...(args.model !== undefined ? { model: args.model } : {}),\n ...(args.isolation !== undefined ? { isolation: args.isolation } : {}),\n },\n deps,\n manager,\n );\n },\n );\n}\n","/**\n * SessionBackgroundTaskTracker — manages background task and job group state\n * for an InteractiveSession. Handles subscriptions, events, and persistence\n * integration without owning the session or store directly.\n */\n\nimport {\n BackgroundJobOrchestrator,\n createBackgroundGroupExecutionEntryId,\n createBackgroundTaskExecutionEntryId,\n createLineDetailPage,\n summarizeBackgroundJobGroup,\n} from '../background-tasks/index.js';\nimport { retrieveSessionBackgroundTaskManager } from '../background-tasks/session-background-store.js';\nimport { retrieveAgentToolDeps } from '../tools/agent-tool.js';\n\nimport type {\n IBackgroundJobGroupCreateRequest,\n IBackgroundJobGroupState,\n IBackgroundTaskInput,\n IBackgroundTaskListFilter,\n IBackgroundTaskLogCursor,\n IBackgroundTaskLogPage,\n IBackgroundTaskManager,\n IBackgroundTaskState,\n IExecutionDetailCursor,\n IExecutionDetailPage,\n TBackgroundJobGroupEvent,\n TBackgroundTaskEvent,\n TExecutionWorkspaceUpdateCause,\n} from '../background-tasks/index.js';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport interface IBackgroundTrackerState {\n tasks: IBackgroundTaskState[];\n taskEvents: TBackgroundTaskEvent[];\n groups: IBackgroundJobGroupState[];\n groupEvents: TBackgroundJobGroupEvent[];\n}\n\nexport class SessionBackgroundTaskTracker {\n private backgroundTasks: IBackgroundTaskState[] = [];\n private backgroundTaskEvents: TBackgroundTaskEvent[] = [];\n private backgroundJobGroups: IBackgroundJobGroupState[] = [];\n private backgroundJobGroupEvents: TBackgroundJobGroupEvent[] = [];\n private backgroundTaskUnsubscribe: (() => void) | null = null;\n private backgroundJobUnsubscribe: (() => void) | null = null;\n private backgroundJobOrchestrator: BackgroundJobOrchestrator | null = null;\n\n constructor(\n private readonly getManager: () => IBackgroundTaskManager | undefined,\n private readonly onChanged: (cause: TExecutionWorkspaceUpdateCause, entryId?: string) => void,\n private readonly emitTaskEvent: (event: TBackgroundTaskEvent) => void,\n private readonly emitGroupEvent: (event: TBackgroundJobGroupEvent) => void,\n private readonly persistSession: () => void,\n ) {}\n\n subscribe(session: Session): void {\n if (this.backgroundTaskUnsubscribe) return;\n const manager =\n retrieveSessionBackgroundTaskManager(session) ??\n retrieveAgentToolDeps(session)?.backgroundTaskManager;\n if (!manager) return;\n this.backgroundTaskUnsubscribe = manager.subscribe((event) => {\n this.recordTaskEvent(event);\n this.emitTaskEvent(event);\n });\n }\n\n dispose(): void {\n this.backgroundTaskUnsubscribe?.();\n this.backgroundTaskUnsubscribe = null;\n this.backgroundJobUnsubscribe?.();\n this.backgroundJobUnsubscribe = null;\n this.backgroundJobOrchestrator?.dispose();\n this.backgroundJobOrchestrator = null;\n }\n\n restoreState(state: IBackgroundTrackerState): void {\n this.backgroundTasks = state.tasks;\n this.backgroundTaskEvents = state.taskEvents;\n this.backgroundJobGroups = state.groups;\n this.backgroundJobGroupEvents = state.groupEvents;\n }\n\n getState(): IBackgroundTrackerState {\n return {\n tasks: this.getTaskSnapshots(),\n taskEvents: this.backgroundTaskEvents,\n groups: this.getGroupSnapshots(),\n groupEvents: this.backgroundJobGroupEvents,\n };\n }\n\n getManagerOrThrow(): IBackgroundTaskManager {\n const manager = this.getManager();\n if (!manager) {\n throw new Error('Background task manager is not available for this session.');\n }\n return manager;\n }\n\n getOrchestratorOrThrow(sessionId: string): BackgroundJobOrchestrator {\n if (this.backgroundJobOrchestrator) return this.backgroundJobOrchestrator;\n const manager = this.getManagerOrThrow();\n this.backgroundJobOrchestrator = new BackgroundJobOrchestrator({\n manager,\n initialGroups: this.backgroundJobGroups,\n });\n this.subscribeGroupEvents(sessionId);\n return this.backgroundJobOrchestrator;\n }\n\n async cancelTask(taskId: string, reason?: string): Promise<void> {\n await this.getManagerOrThrow().cancel(taskId, reason);\n }\n\n async closeTask(taskId: string): Promise<void> {\n await this.getManagerOrThrow().close(taskId);\n }\n\n async sendTask(taskId: string, input: IBackgroundTaskInput): Promise<void> {\n await this.getManagerOrThrow().send(taskId, input);\n }\n\n async readTaskLog(\n taskId: string,\n cursor?: IBackgroundTaskLogCursor,\n ): Promise<IBackgroundTaskLogPage> {\n return this.getManagerOrThrow().readLog(taskId, cursor);\n }\n\n listTasks(filter?: IBackgroundTaskListFilter): IBackgroundTaskState[] {\n return this.getManagerOrThrow().list(filter);\n }\n\n getTask(taskId: string): IBackgroundTaskState | undefined {\n return this.getManagerOrThrow().get(taskId);\n }\n\n createGroup(\n input: Omit<IBackgroundJobGroupCreateRequest, 'parentSessionId'>,\n sessionId: string,\n ): IBackgroundJobGroupState {\n return this.getOrchestratorOrThrow(sessionId).createGroup({\n ...input,\n parentSessionId: sessionId,\n });\n }\n\n listGroups(sessionId: string): IBackgroundJobGroupState[] {\n return this.getOrchestratorOrThrow(sessionId).listGroups();\n }\n\n getGroup(groupId: string, sessionId: string): IBackgroundJobGroupState | undefined {\n return this.getOrchestratorOrThrow(sessionId).getGroup(groupId);\n }\n\n async waitGroup(groupId: string, sessionId: string): Promise<IBackgroundJobGroupState> {\n return this.getOrchestratorOrThrow(sessionId).waitGroup(groupId);\n }\n\n async readTaskDetail(\n entryId: string,\n taskId: string,\n cursor?: IExecutionDetailCursor,\n ): Promise<IExecutionDetailPage> {\n const task = this.getManagerOrThrow().get(taskId);\n if (!task) throw new Error(`Unknown background task: ${taskId}`);\n if (task.logPath || task.transcriptPath) {\n const page = await this.getManagerOrThrow().readLog(taskId, cursor);\n return createLineDetailPage({\n entryId,\n lines: page.lines,\n cursor: page.cursor,\n nextCursor: page.nextCursor,\n kind: task.kind === 'process' ? 'process_output' : 'progress',\n });\n }\n const detailKind =\n task.status === 'failed' ? 'error' : task.status === 'completed' ? 'result' : 'progress';\n const text =\n task.error?.message ??\n task.result?.output ??\n task.currentAction ??\n task.promptPreview ??\n task.commandPreview ??\n task.status;\n return createLineDetailPage({ entryId, lines: [text], cursor, kind: detailKind });\n }\n\n readGroupDetail(entryId: string, groupId: string, sessionId: string): IExecutionDetailPage {\n const group = this.getOrchestratorOrThrow(sessionId).getGroup(groupId);\n if (!group) throw new Error(`Unknown background job group: ${groupId}`);\n const summary = summarizeBackgroundJobGroup(group);\n return createLineDetailPage({ entryId, lines: summary.lines, kind: 'group_summary' });\n }\n\n getTaskSnapshots(): IBackgroundTaskState[] {\n try {\n return this.getManagerOrThrow().list();\n } catch {\n return this.backgroundTasks;\n }\n }\n\n getGroupSnapshots(): IBackgroundJobGroupState[] {\n try {\n return this.backgroundJobOrchestrator?.listGroups() ?? this.backgroundJobGroups;\n } catch {\n return this.backgroundJobGroups;\n }\n }\n\n private subscribeGroupEvents(sessionId: string): void {\n if (this.backgroundJobUnsubscribe || !this.backgroundJobOrchestrator) return;\n this.backgroundJobUnsubscribe = this.backgroundJobOrchestrator.subscribe((event) => {\n this.recordGroupEvent(event, sessionId);\n this.emitGroupEvent(event);\n });\n }\n\n private recordTaskEvent(event: TBackgroundTaskEvent): void {\n this.backgroundTasks = this.getTaskSnapshots();\n this.backgroundTaskEvents.push(event);\n this.persistSession();\n this.onChanged('background_task', getTaskEventEntryId(event));\n }\n\n private recordGroupEvent(event: TBackgroundJobGroupEvent, _sessionId: string): void {\n this.backgroundJobGroups = this.getGroupSnapshots();\n this.backgroundJobGroupEvents.push(event);\n this.persistSession();\n this.onChanged('background_group', createBackgroundGroupExecutionEntryId(event.group.id));\n }\n}\n\nfunction getTaskEventEntryId(event: TBackgroundTaskEvent): string | undefined {\n if ('task' in event) return createBackgroundTaskExecutionEntryId(event.task.id);\n if ('taskId' in event) return createBackgroundTaskExecutionEntryId(event.taskId);\n return undefined;\n}\n","/**\n * Agent job helpers for InteractiveSession.\n *\n * Pure functions for spawning, waiting, sending, cancelling, and closing\n * agent jobs. The class delegates to these with thin wrappers.\n */\n\nimport { createExecutionOriginMetadata } from '../background-tasks/index.js';\nimport { retrieveAgentToolDeps } from '../tools/agent-tool.js';\n\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type { TBackgroundTaskIsolation } from '../background-tasks/index.js';\nimport type { TCommandInvocationSource } from '../commands/index.js';\nimport type { ISubagentJobResult, ISubagentJobState } from '../subagents/index.js';\nimport type { Session } from '@robota-sdk/agent-session';\n\n/** Retrieve agent tool deps or throw. */\nexport function getAgentToolDepsOrThrow(\n session: Session,\n): NonNullable<ReturnType<typeof retrieveAgentToolDeps>> {\n const deps = retrieveAgentToolDeps(session);\n if (!deps) throw new Error('Agent runtime dependencies are not available for this session.');\n if (!deps.backgroundTaskManager)\n throw new Error('Background task manager is not available for this session.');\n return deps;\n}\n\n/** Retrieve subagent manager or throw. */\nexport function getSubagentManagerOrThrow(\n session: Session,\n): NonNullable<ReturnType<typeof getAgentToolDepsOrThrow>['subagentManager']> {\n const deps = getAgentToolDepsOrThrow(session);\n if (!deps.subagentManager) throw new Error('Subagent manager is not available for this session.');\n return deps.subagentManager;\n}\n\n/** Resolve an agent definition by type or throw. */\nexport function resolveAgentDefinition(\n agentType: string,\n deps: NonNullable<ReturnType<typeof retrieveAgentToolDeps>>,\n): IAgentDefinition {\n const definition = deps.customAgentRegistry?.(agentType);\n if (!definition) throw new Error(`Unknown agent type: ${agentType}`);\n return definition;\n}\n\n/** List agent definitions available in the session. */\nexport function listAgentDefinitionsFromSession(\n session: Session,\n): Array<{ name: string; description: string }> {\n const deps = retrieveAgentToolDeps(session);\n return (deps?.agentDefinitions ?? []).map((agent) => ({\n name: agent.name,\n description: agent.description,\n }));\n}\n\nexport interface ISpawnAgentJobInput {\n agentType: string;\n label: string;\n mode: 'foreground' | 'background';\n prompt: string;\n model?: string;\n isolation?: TBackgroundTaskIsolation;\n}\n\n/** Spawn a new agent job with the given parameters. */\nexport async function spawnAgentJobFromSession(\n session: Session,\n input: ISpawnAgentJobInput,\n cwd: string | undefined,\n invocationSource: TCommandInvocationSource,\n): Promise<ISubagentJobState> {\n const deps = getAgentToolDepsOrThrow(session);\n const definition = resolveAgentDefinition(input.agentType, deps);\n const sessionId = session.getSessionId();\n const manager = getSubagentManagerOrThrow(session);\n return manager.spawn({\n type: input.agentType,\n label: input.label,\n parentSessionId: sessionId,\n mode: input.mode,\n depth: (deps.subagentDepth ?? 0) + 1,\n cwd: deps.cwd ?? cwd ?? process.cwd(),\n prompt: input.prompt,\n model: input.model ?? definition.model,\n isolation: input.isolation,\n allowedTools: definition.tools,\n disallowedTools: definition.disallowedTools,\n metadata: createExecutionOriginMetadata({\n kind: invocationSource === 'model' ? 'model_command' : 'slash_command',\n sessionId,\n commandName: 'agent',\n label: input.label,\n }),\n });\n}\n\n/** Wait for an agent job to complete and return its result. */\nexport async function waitAgentJobFromSession(\n session: Session,\n jobId: string,\n): Promise<ISubagentJobResult> {\n return getSubagentManagerOrThrow(session).wait(jobId);\n}\n\n/** Send a prompt to a running agent job. */\nexport async function sendAgentJobFromSession(\n session: Session,\n jobId: string,\n prompt: string,\n): Promise<void> {\n await getSubagentManagerOrThrow(session).send(jobId, prompt);\n}\n\n/** Cancel a running agent job. */\nexport async function cancelAgentJobFromSession(\n session: Session,\n jobId: string,\n reason?: string,\n): Promise<void> {\n await getSubagentManagerOrThrow(session).cancel(jobId, reason);\n}\n\n/** Close a completed or failed agent job. */\nexport async function closeAgentJobFromSession(session: Session, jobId: string): Promise<void> {\n await getSubagentManagerOrThrow(session).close(jobId);\n}\n\n/** List all agent jobs in the session. */\nexport function listAgentJobsFromSession(session: Session): ISubagentJobState[] {\n return getSubagentManagerOrThrow(session).list();\n}\n","/**\n * Execution workspace helpers for InteractiveSession.\n *\n * Pure functions that build workspace snapshots, list/get entries,\n * read detail pages, and create task spawners. The class delegates to\n * these with thin wrappers.\n */\n\nimport {\n createExecutionWorkspaceSnapshot,\n createExecutionWorkspaceTaskSpawner,\n createMainThreadDetailPage,\n parseExecutionWorkspaceEntryId,\n} from '../background-tasks/index.js';\n\nimport type { SessionBackgroundTaskTracker } from './interactive-session-background-tracker.js';\nimport type { SessionExecutionController } from './interactive-session-execution-controller.js';\nimport type { SessionHistoryTracker } from './interactive-session-history-tracker.js';\nimport type {\n IExecutionDetailCursor,\n IExecutionDetailPage,\n IExecutionOrigin,\n IExecutionWorkspaceEntry,\n IExecutionWorkspaceFilter,\n IExecutionWorkspaceSnapshot,\n IExecutionWorkspaceSnapshotOptions,\n IExecutionWorkspaceTaskSpawner,\n} from '../background-tasks/index.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\n\nexport interface IWorkspaceSnapshotDeps {\n sessionId: string;\n execCtrl: Pick<SessionExecutionController, 'executing' | 'pendingPrompt' | 'streamingText'>;\n histTracker: Pick<SessionHistoryTracker, 'getHistory'>;\n bgTracker: Pick<SessionBackgroundTaskTracker, 'getTaskSnapshots' | 'getGroupSnapshots'>;\n}\n\nexport function buildExecutionWorkspaceSnapshot(\n deps: IWorkspaceSnapshotDeps,\n options: IExecutionWorkspaceSnapshotOptions = {},\n): IExecutionWorkspaceSnapshot {\n const { sessionId, execCtrl, histTracker, bgTracker } = deps;\n const history = histTracker.getHistory();\n return createExecutionWorkspaceSnapshot({\n sessionId,\n mainThread: {\n sessionId,\n isExecuting: execCtrl.executing,\n hasPendingPrompt: execCtrl.pendingPrompt !== null,\n historyLength: history.length,\n updatedAt: history.at(-1)?.timestamp.toISOString() ?? new Date(0).toISOString(),\n preview:\n execCtrl.streamingText.trim().length > 0\n ? execCtrl.streamingText\n : (history.at(-1)?.type as string | undefined),\n },\n tasks: bgTracker.getTaskSnapshots(),\n groups: bgTracker.getGroupSnapshots(),\n selectedEntryId: options.selectedEntryId,\n filter: options.filter,\n });\n}\n\nexport function listWorkspaceEntries(\n getSnapshot: (options?: IExecutionWorkspaceSnapshotOptions) => IExecutionWorkspaceSnapshot,\n filter?: IExecutionWorkspaceFilter,\n): IExecutionWorkspaceEntry[] {\n return [...getSnapshot({ filter }).entries];\n}\n\nexport function getWorkspaceEntry(\n getSnapshot: (options?: IExecutionWorkspaceSnapshotOptions) => IExecutionWorkspaceSnapshot,\n entryId: string,\n): IExecutionWorkspaceEntry | undefined {\n return getSnapshot().entries.find((entry) => entry.id === entryId);\n}\n\nexport async function readWorkspaceDetail(\n entryId: string,\n getHistory: () => IHistoryEntry[],\n bgTracker: Pick<SessionBackgroundTaskTracker, 'readGroupDetail' | 'readTaskDetail'>,\n sessionId: string,\n cursor?: IExecutionDetailCursor,\n): Promise<IExecutionDetailPage> {\n const entryRef = parseExecutionWorkspaceEntryId(entryId);\n if (!entryRef) throw new Error(`Unknown execution workspace entry: ${entryId}`);\n if (entryRef.kind === 'main_thread') {\n return createMainThreadDetailPage({ entryId, history: getHistory(), cursor });\n }\n if (entryRef.kind === 'background_group') {\n return bgTracker.readGroupDetail(entryId, entryRef.sourceId, sessionId);\n }\n return bgTracker.readTaskDetail(entryId, entryRef.sourceId, cursor);\n}\n\nexport function buildWorkspaceTaskSpawner(\n bgTracker: Pick<SessionBackgroundTaskTracker, 'getManagerOrThrow' | 'getOrchestratorOrThrow'>,\n sessionId: string,\n cwd: string,\n origin: IExecutionOrigin,\n): IExecutionWorkspaceTaskSpawner {\n return createExecutionWorkspaceTaskSpawner({\n manager: bgTracker.getManagerOrThrow(),\n groupOrchestrator: bgTracker.getOrchestratorOrThrow(sessionId),\n sessionId,\n cwd,\n origin: { ...origin, sessionId: origin.sessionId || sessionId },\n });\n}\n","/**\n * Abstract base for InteractiveSession.\n *\n * Contains all delegating public methods that only require the four\n * adapter instances (bgTracker, histTracker, skillRouter, execCtrl)\n * plus the abstract accessors declared here.\n */\n\nimport {\n listAgentDefinitionsFromSession,\n listAgentJobsFromSession,\n spawnAgentJobFromSession,\n waitAgentJobFromSession,\n sendAgentJobFromSession,\n cancelAgentJobFromSession,\n closeAgentJobFromSession,\n type ISpawnAgentJobInput,\n} from './interactive-session-agent-jobs.js';\nimport {\n buildExecutionWorkspaceSnapshot,\n buildWorkspaceTaskSpawner,\n readWorkspaceDetail,\n} from './interactive-session-workspace.js';\n\nimport type { SessionBackgroundTaskTracker } from './interactive-session-background-tracker.js';\nimport type { SessionExecutionController } from './interactive-session-execution-controller.js';\nimport type { SessionHistoryTracker } from './interactive-session-history-tracker.js';\nimport type { SessionSkillRouter } from './interactive-session-skill-router.js';\nimport type {\n IBackgroundJobGroupCreateRequest,\n IBackgroundJobGroupState,\n IBackgroundTaskInput,\n IBackgroundTaskListFilter,\n IBackgroundTaskLogCursor,\n IBackgroundTaskLogPage,\n IBackgroundTaskState,\n IExecutionDetailCursor,\n IExecutionDetailPage,\n IExecutionOrigin,\n IExecutionWorkspaceEntry,\n IExecutionWorkspaceFilter,\n IExecutionWorkspaceSnapshot,\n IExecutionWorkspaceSnapshotOptions,\n IExecutionWorkspaceTaskSpawner,\n} from '../background-tasks/index.js';\nimport type {\n IEditCheckpointInspection,\n IEditCheckpointRestoreResult,\n IEditCheckpointSummary,\n} from '../checkpoints/edit-checkpoint-types.js';\nimport type {\n ICommandHostAdapters,\n ICommandResult,\n ICommandSkillListEntry,\n ICommandSkillActivationRequest,\n TCommandInvocationSource,\n} from '../commands/index.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type {\n IContextReferenceAddResult,\n IContextReferenceClearResult,\n IContextReferenceItem,\n IContextReferenceRemoveResult,\n} from '../context/context-reference-inventory.js';\nimport type { IMemoryEvent, IMemoryReference } from '../memory/automatic-memory-types.js';\nimport type { ISubagentJobResult, ISubagentJobState } from '../subagents/index.js';\nimport type { IHistoryEntry, TUniversalMessage, IContextWindowState } from '@robota-sdk/agent-core';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport abstract class InteractiveSessionBase {\n protected abstract readonly bgTracker: SessionBackgroundTaskTracker;\n protected abstract readonly histTracker: SessionHistoryTracker;\n protected abstract readonly skillRouter: SessionSkillRouter;\n protected abstract readonly execCtrl: SessionExecutionController;\n protected abstract getSessionOrThrow(): Session;\n protected abstract ensureInitialized(): Promise<void>;\n protected abstract getCwd(): string;\n\n isExecuting(): boolean {\n return this.execCtrl.executing;\n }\n getPendingPrompt(): string | null {\n return this.execCtrl.pendingPrompt;\n }\n getStreamingText(): string {\n return this.execCtrl.streamingText;\n }\n getActiveTools(): SessionExecutionController['activeTools'] {\n return this.execCtrl.activeTools;\n }\n cancelQueue(): void {\n this.execCtrl.clearPendingQueue();\n }\n\n async executeCommand(name: string, args: string): Promise<ICommandResult | null> {\n await this.ensureInitialized();\n if (this.execCtrl.executing)\n return {\n success: false,\n message: 'Another prompt or command is already running. Wait for it to finish.',\n };\n return this.skillRouter.executeCommand(name, args);\n }\n async executeModelCommand(name: string, args: string): Promise<ICommandResult | null> {\n await this.ensureInitialized();\n return this.skillRouter.executeModelCommand(name, args);\n }\n getCommandInvocationSource(): TCommandInvocationSource {\n return this.skillRouter.getCommandInvocationSource();\n }\n async executeSkillCommandByName(\n name: string,\n args: string,\n request: ICommandSkillActivationRequest,\n ): Promise<ICommandResult | null> {\n await this.ensureInitialized();\n return this.skillRouter.executeSkillCommandByName(name, args, request);\n }\n listCommands(): Array<{ name: string; displayName?: string; description: string }> {\n return this.skillRouter.listCommands();\n }\n listSkills(): ICommandSkillListEntry[] {\n return this.skillRouter.listSkills();\n }\n listModelInvocableCommands(): Array<{ name: string; description: string }> {\n return this.skillRouter.listModelInvocableCommands();\n }\n getCommandHostAdapters(): ICommandHostAdapters {\n return this.skillRouter.getCommandHostAdapters();\n }\n getSkillActivationEvents(): ISkillActivationEvent[] {\n return this.histTracker.getSkillActivationEvents();\n }\n\n getContextState(): IContextWindowState {\n return this.getSessionOrThrow().getContextState();\n }\n async compactContext(instructions?: string): Promise<void> {\n await this.getSessionOrThrow().compact(instructions);\n }\n\n getFullHistory(): IHistoryEntry[] {\n return this.histTracker.getHistory();\n }\n getMessages(): TUniversalMessage[] {\n return this.histTracker\n .getHistory()\n .filter((e) => e.category === 'chat')\n .map((e) => e.data as TUniversalMessage);\n }\n listEditCheckpoints(): IEditCheckpointSummary[] {\n return this.histTracker.listEditCheckpoints();\n }\n inspectEditCheckpoint(checkpointId: string): IEditCheckpointInspection {\n return this.histTracker.inspectEditCheckpoint(checkpointId);\n }\n async restoreEditCheckpoint(checkpointId: string): Promise<IEditCheckpointRestoreResult> {\n await this.ensureInitialized();\n return this.histTracker.restoreEditCheckpoint(checkpointId);\n }\n async rollbackEditCheckpoint(checkpointId: string): Promise<IEditCheckpointRestoreResult> {\n await this.ensureInitialized();\n return this.histTracker.rollbackEditCheckpoint(checkpointId);\n }\n\n getUsedMemoryReferences(): IMemoryReference[] {\n return this.histTracker.getUsedMemoryReferences();\n }\n recordMemoryEvent(event: IMemoryEvent): void {\n this.histTracker.recordMemoryEvent(event);\n }\n\n listContextReferences(): IContextReferenceItem[] {\n return this.histTracker.listContextReferences();\n }\n async addContextReference(path: string): Promise<IContextReferenceAddResult> {\n return this.histTracker.addContextReference(path);\n }\n removeContextReference(path: string): IContextReferenceRemoveResult {\n return this.histTracker.removeContextReference(path);\n }\n clearContextReferences(): IContextReferenceClearResult {\n return this.histTracker.clearContextReferences();\n }\n\n listBackgroundTasks(filter?: IBackgroundTaskListFilter): IBackgroundTaskState[] {\n return this.bgTracker.listTasks(filter);\n }\n getBackgroundTask(taskId: string): IBackgroundTaskState | undefined {\n return this.bgTracker.getTask(taskId);\n }\n async cancelBackgroundTask(taskId: string, reason?: string): Promise<void> {\n await this.ensureInitialized();\n await this.bgTracker.cancelTask(taskId, reason);\n }\n async closeBackgroundTask(taskId: string): Promise<void> {\n await this.ensureInitialized();\n await this.bgTracker.closeTask(taskId);\n }\n async sendBackgroundTask(taskId: string, input: IBackgroundTaskInput): Promise<void> {\n await this.ensureInitialized();\n await this.bgTracker.sendTask(taskId, input);\n }\n async readBackgroundTaskLog(\n taskId: string,\n cursor?: IBackgroundTaskLogCursor,\n ): Promise<IBackgroundTaskLogPage> {\n await this.ensureInitialized();\n return this.bgTracker.readTaskLog(taskId, cursor);\n }\n createBackgroundJobGroup(\n input: Omit<IBackgroundJobGroupCreateRequest, 'parentSessionId'>,\n ): IBackgroundJobGroupState {\n return this.bgTracker.createGroup(input, this.getSessionOrThrow().getSessionId());\n }\n listBackgroundJobGroups(): IBackgroundJobGroupState[] {\n return this.bgTracker.listGroups(this.getSessionOrThrow().getSessionId());\n }\n getBackgroundJobGroup(groupId: string): IBackgroundJobGroupState | undefined {\n return this.bgTracker.getGroup(groupId, this.getSessionOrThrow().getSessionId());\n }\n async waitBackgroundJobGroup(groupId: string): Promise<IBackgroundJobGroupState> {\n await this.ensureInitialized();\n return this.bgTracker.waitGroup(groupId, this.getSessionOrThrow().getSessionId());\n }\n\n getExecutionWorkspaceSnapshot(\n options: IExecutionWorkspaceSnapshotOptions = {},\n ): IExecutionWorkspaceSnapshot {\n return buildExecutionWorkspaceSnapshot(\n {\n sessionId: this.getSessionOrThrow().getSessionId(),\n execCtrl: this.execCtrl,\n histTracker: this.histTracker,\n bgTracker: this.bgTracker,\n },\n options,\n );\n }\n listExecutionWorkspaceEntries(filter?: IExecutionWorkspaceFilter): IExecutionWorkspaceEntry[] {\n return [...this.getExecutionWorkspaceSnapshot({ filter }).entries];\n }\n getExecutionWorkspaceEntry(entryId: string): IExecutionWorkspaceEntry | undefined {\n return this.getExecutionWorkspaceSnapshot().entries.find((e) => e.id === entryId);\n }\n async readExecutionWorkspaceDetail(\n entryId: string,\n cursor?: IExecutionDetailCursor,\n ): Promise<IExecutionDetailPage> {\n await this.ensureInitialized();\n return readWorkspaceDetail(\n entryId,\n () => this.histTracker.getHistory(),\n this.bgTracker,\n this.getSessionOrThrow().getSessionId(),\n cursor,\n );\n }\n createExecutionWorkspaceTaskSpawner(origin: IExecutionOrigin): IExecutionWorkspaceTaskSpawner {\n return buildWorkspaceTaskSpawner(\n this.bgTracker,\n this.getSessionOrThrow().getSessionId(),\n this.getCwd(),\n origin,\n );\n }\n\n listAgentDefinitions(): Array<{ name: string; description: string }> {\n return listAgentDefinitionsFromSession(this.getSessionOrThrow());\n }\n listAgentJobs(): ISubagentJobState[] {\n return listAgentJobsFromSession(this.getSessionOrThrow());\n }\n async spawnAgentJob(input: ISpawnAgentJobInput): Promise<ISubagentJobState> {\n await this.ensureInitialized();\n return spawnAgentJobFromSession(\n this.getSessionOrThrow(),\n input,\n this.getCwd(),\n this.skillRouter.getCommandInvocationSource(),\n );\n }\n async waitAgentJob(jobId: string): Promise<ISubagentJobResult> {\n await this.ensureInitialized();\n return waitAgentJobFromSession(this.getSessionOrThrow(), jobId);\n }\n async sendAgentJob(jobId: string, prompt: string): Promise<void> {\n await this.ensureInitialized();\n await sendAgentJobFromSession(this.getSessionOrThrow(), jobId, prompt);\n }\n async cancelAgentJob(jobId: string, reason?: string): Promise<void> {\n await this.ensureInitialized();\n await cancelAgentJobFromSession(this.getSessionOrThrow(), jobId, reason);\n }\n async closeAgentJob(jobId: string): Promise<void> {\n await this.ensureInitialized();\n await closeAgentJobFromSession(this.getSessionOrThrow(), jobId);\n }\n}\n","import {\n constants,\n cpSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from 'node:fs';\nimport {\n access,\n copyFile,\n mkdir,\n readFile,\n readdir,\n realpath,\n rename,\n rm,\n stat,\n writeFile,\n} from 'node:fs/promises';\n\nimport type { IDirent, IFileSystem, IFileSystemAsync, IStats } from '@robota-sdk/agent-core';\n\nexport class NodeFileSystem implements IFileSystem {\n existsSync(path: string): boolean {\n return existsSync(path);\n }\n\n readFileSync(path: string, encoding: BufferEncoding): string {\n return readFileSync(path, encoding);\n }\n\n writeFileSync(path: string, data: string, encoding?: BufferEncoding): void {\n writeFileSync(path, data, encoding ?? 'utf8');\n }\n\n mkdirSync(path: string, options?: { recursive?: boolean }): void {\n mkdirSync(path, options);\n }\n\n readdirSync(path: string): string[];\n // eslint-disable-next-line no-dupe-class-members\n readdirSync(path: string, options: { withFileTypes: true }): IDirent[];\n // eslint-disable-next-line no-dupe-class-members\n readdirSync(path: string, options?: { withFileTypes?: true }): string[] | IDirent[] {\n if (options?.withFileTypes) {\n return readdirSync(path, { withFileTypes: true }) as IDirent[];\n }\n return readdirSync(path) as string[];\n }\n\n statSync(path: string): IStats {\n return statSync(path) as IStats;\n }\n\n rmSync(path: string, options?: { recursive?: boolean; force?: boolean }): void {\n rmSync(path, options);\n }\n\n cpSync(source: string, destination: string, options?: { recursive?: boolean }): void {\n cpSync(source, destination, options);\n }\n\n renameSync(oldPath: string, newPath: string): void {\n renameSync(oldPath, newPath);\n }\n\n get constants(): { F_OK: number; R_OK: number; W_OK: number } {\n return constants;\n }\n}\n\nexport class NodeFileSystemAsync implements IFileSystemAsync {\n async access(path: string, mode?: number): Promise<void> {\n await access(path, mode);\n }\n\n async copyFile(src: string, dest: string, flags?: number): Promise<void> {\n await copyFile(src, dest, flags);\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n await mkdir(path, options);\n }\n\n async readFile(path: string, encoding: BufferEncoding): Promise<string> {\n return readFile(path, encoding);\n }\n\n async readdir(path: string): Promise<string[]>;\n // eslint-disable-next-line no-dupe-class-members\n async readdir(path: string, options: { withFileTypes: true }): Promise<IDirent[]>;\n // eslint-disable-next-line no-dupe-class-members\n async readdir(path: string, options?: { withFileTypes?: true }): Promise<string[] | IDirent[]> {\n if (options?.withFileTypes) {\n const result = await readdir(path, { withFileTypes: true });\n return result as IDirent[];\n }\n return readdir(path) as Promise<string[]>;\n }\n\n async realpath(path: string): Promise<string> {\n return realpath(path);\n }\n\n async rename(oldPath: string, newPath: string): Promise<void> {\n await rename(oldPath, newPath);\n }\n\n async rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void> {\n await rm(path, options);\n }\n\n async stat(path: string): Promise<IStats> {\n return stat(path) as Promise<IStats>;\n }\n\n async writeFile(path: string, data: string, encoding?: BufferEncoding): Promise<void> {\n await writeFile(path, data, encoding ?? 'utf8');\n }\n}\n","import { createHash } from 'node:crypto';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/** A single context file entry tracked with its content hash. */\nexport interface IContextFileEntry {\n /** Absolute path to the file. */\n filePath: string;\n /** Content as read at load time. */\n content: string;\n /** SHA-256 hex digest of `content`. */\n contentHash: string;\n}\n\n/** Compute a SHA-256 hex digest of the given string content. */\nexport function computeContentHash(content: string): string {\n return createHash('sha256').update(content, 'utf-8').digest('hex');\n}\n\n/** Read a file from disk and return an entry with its content hash. */\nexport function loadFileWithHash(\n filePath: string,\n fs: IFileSystem = new NodeFileSystem(),\n): IContextFileEntry {\n const content = fs.readFileSync(filePath, 'utf-8');\n return { filePath, content, contentHash: computeContentHash(content) };\n}\n\n/** Result of a staleness check. */\nexport interface IContextStalenessCheckResult {\n stale: IContextFileEntry[];\n fresh: IContextFileEntry[];\n}\n\n/**\n * Compare stored content hashes against what is currently on disk.\n * Files that no longer exist on disk are treated as fresh (not changed).\n */\nexport async function checkContextStaleness(\n entries: readonly IContextFileEntry[],\n fs: IFileSystem = new NodeFileSystem(),\n): Promise<IContextStalenessCheckResult> {\n const stale: IContextFileEntry[] = [];\n const fresh: IContextFileEntry[] = [];\n\n for (const entry of entries) {\n if (!fs.existsSync(entry.filePath)) {\n fresh.push(entry);\n continue;\n }\n const diskContent = fs.readFileSync(entry.filePath, 'utf-8');\n const diskHash = computeContentHash(diskContent);\n if (diskHash !== entry.contentHash) {\n stale.push(entry);\n } else {\n fresh.push(entry);\n }\n }\n\n return { stale, fresh };\n}\n\n/** Result of refreshing stale context entries. */\nexport interface IContextRefreshResult {\n /** All entries, with stale ones replaced by their re-read versions. */\n updated: IContextFileEntry[];\n /** File paths that were refreshed (had stale content). */\n refreshed: string[];\n}\n\n/**\n * Re-read any stale files from disk and return updated entries.\n * Fresh entries are returned unchanged.\n */\nexport async function refreshContextEntries(\n entries: readonly IContextFileEntry[],\n fs: IFileSystem = new NodeFileSystem(),\n): Promise<IContextRefreshResult> {\n const { stale } = await checkContextStaleness(entries, fs);\n const staleSet = new Set(stale.map((e) => e.filePath));\n const refreshed: string[] = [];\n\n const updated = entries.map((entry) => {\n if (!staleSet.has(entry.filePath)) return entry;\n const diskContent = fs.readFileSync(entry.filePath, 'utf-8');\n refreshed.push(entry.filePath);\n return {\n filePath: entry.filePath,\n content: diskContent,\n contentHash: computeContentHash(diskContent),\n };\n });\n\n return { updated, refreshed };\n}\n","/**\n * Context file refresh helper for InteractiveSession.\n *\n * Checks if AGENTS.md/CLAUDE.md context entries are stale and\n * refreshes them before each prompt turn.\n */\n\nimport { refreshContextEntries } from '../context/context-file-tracker.js';\n\nimport type { ICreatedInteractiveSession } from './interactive-session-init.js';\nimport type { IContextFileEntry } from '../context/context-file-tracker.js';\n\nexport async function checkAndRefreshContextIfStale(\n agentsFileEntries: IContextFileEntry[],\n claudeFileEntries: IContextFileEntry[],\n rebuildSystemMessage: ICreatedInteractiveSession['rebuildSystemMessage'] | null,\n setEntries: (agents: IContextFileEntry[], claude: IContextFileEntry[]) => void,\n getSessionOrThrow: () => { updateSystemMessage: (msg: string) => void },\n emit: (event: string, payload: unknown) => void,\n): Promise<void> {\n if (!rebuildSystemMessage) return;\n const allEntries = [...agentsFileEntries, ...claudeFileEntries];\n if (allEntries.length === 0) return;\n\n const agentsCount = agentsFileEntries.length;\n const { updated, refreshed } = await refreshContextEntries(allEntries);\n if (refreshed.length === 0) return;\n\n const newAgents = updated.slice(0, agentsCount);\n const newClaude = updated.slice(agentsCount);\n setEntries(newAgents, newClaude);\n\n const newSystemMessage = rebuildSystemMessage(\n newAgents.map((e) => e.content).join('\\n\\n'),\n newClaude.map((e) => e.content).join('\\n\\n'),\n );\n getSessionOrThrow().updateSystemMessage(newSystemMessage);\n\n for (const filePath of refreshed) {\n emit('context_file_refreshed', { filePath });\n }\n}\n","import type { IPromptFileReferenceRecord } from './prompt-file-reference-types.js';\n\nexport type TContextReferenceLoadType = 'manual' | 'prompt-reference';\nexport type TContextReferenceStatus = 'active' | 'observed';\n\nexport interface IContextReferenceItem {\n id: string;\n sourcePath: string;\n relativePath: string;\n originalReference: string;\n loadType: TContextReferenceLoadType;\n status: TContextReferenceStatus;\n byteLength: number;\n loadedAt: string;\n lastUsedAt?: string;\n}\n\nexport interface IContextReferenceInventoryLimits {\n maxActiveReferences?: number;\n maxActiveBytes?: number;\n maxObservedReferences?: number;\n}\n\nexport interface IContextReferenceAddResult {\n reference?: IContextReferenceItem;\n evicted: IContextReferenceItem[];\n diagnostics: string[];\n}\n\nexport interface IContextReferenceRemoveResult {\n removed?: IContextReferenceItem;\n}\n\nexport interface IContextReferenceClearResult {\n removed: IContextReferenceItem[];\n}\n\nexport interface IContextReferenceUpsertResult {\n references: IContextReferenceItem[];\n evicted: IContextReferenceItem[];\n}\n\nconst DEFAULT_MAX_ACTIVE_REFERENCES = Number('8');\nconst BYTES_PER_KIB = Number('1024');\nconst DEFAULT_MAX_ACTIVE_BYTES = Number('256') * BYTES_PER_KIB;\nconst DEFAULT_MAX_OBSERVED_REFERENCES = Number('32');\n\nexport function createContextReferenceItem(\n record: IPromptFileReferenceRecord,\n loadType: TContextReferenceLoadType,\n status: TContextReferenceStatus,\n timestamp = new Date().toISOString(),\n): IContextReferenceItem {\n return {\n id: `${loadType}:${record.relativePath}`,\n sourcePath: record.sourcePath,\n relativePath: record.relativePath,\n originalReference: record.originalReference,\n loadType,\n status,\n byteLength: record.byteLength,\n loadedAt: timestamp,\n lastUsedAt: timestamp,\n };\n}\n\nexport function upsertContextReference(\n references: readonly IContextReferenceItem[],\n item: IContextReferenceItem,\n limits?: IContextReferenceInventoryLimits,\n): IContextReferenceUpsertResult {\n const existing = references.find((reference) => reference.sourcePath === item.sourcePath);\n const retained = references.filter((reference) => reference.sourcePath !== item.sourcePath);\n const nextItem = existing ? mergeContextReference(existing, item) : item;\n return enforceContextReferenceLimits([...retained, nextItem], limits);\n}\n\nexport function removeContextReference(\n references: readonly IContextReferenceItem[],\n query: string,\n): { references: IContextReferenceItem[]; result: IContextReferenceRemoveResult } {\n const normalized = normalizeReferenceQuery(query);\n const removed = references.find((reference) => matchesContextReference(reference, normalized));\n if (!removed) return { references: [...references], result: {} };\n return {\n references: references.filter((reference) => reference.sourcePath !== removed.sourcePath),\n result: { removed },\n };\n}\n\nexport function clearContextReferences(\n references: readonly IContextReferenceItem[],\n): IContextReferenceClearResult {\n return { removed: [...references] };\n}\n\nexport function listActiveContextReferences(\n references: readonly IContextReferenceItem[],\n): IContextReferenceItem[] {\n return references.filter((reference) => reference.status === 'active');\n}\n\nexport function toContextReferenceRecords(\n references: readonly IContextReferenceItem[],\n): IPromptFileReferenceRecord[] {\n return references.map((reference) => ({\n originalReference: reference.originalReference,\n sourcePath: reference.sourcePath,\n relativePath: reference.relativePath,\n reason: reference.loadType,\n depth: 0,\n byteLength: reference.byteLength,\n }));\n}\n\nfunction mergeContextReference(\n existing: IContextReferenceItem,\n incoming: IContextReferenceItem,\n): IContextReferenceItem {\n if (incoming.status === 'active') return { ...incoming, loadedAt: existing.loadedAt };\n return {\n ...existing,\n byteLength: incoming.byteLength,\n originalReference: incoming.originalReference,\n lastUsedAt: incoming.lastUsedAt,\n };\n}\n\nfunction enforceContextReferenceLimits(\n references: readonly IContextReferenceItem[],\n limits?: IContextReferenceInventoryLimits,\n): IContextReferenceUpsertResult {\n const maxActiveReferences = limits?.maxActiveReferences ?? DEFAULT_MAX_ACTIVE_REFERENCES;\n const maxActiveBytes = limits?.maxActiveBytes ?? DEFAULT_MAX_ACTIVE_BYTES;\n const maxObservedReferences = limits?.maxObservedReferences ?? DEFAULT_MAX_OBSERVED_REFERENCES;\n const evicted: IContextReferenceItem[] = [];\n let next = [...references];\n\n while (\n countActiveReferences(next) > maxActiveReferences ||\n countActiveBytes(next) > maxActiveBytes\n ) {\n const candidate = next.find((reference) => reference.status === 'active');\n if (!candidate) break;\n evicted.push(candidate);\n next = next.filter((reference) => reference.sourcePath !== candidate.sourcePath);\n }\n\n const observed = next.filter((reference) => reference.status === 'observed');\n if (observed.length > maxObservedReferences) {\n const overflow = observed.slice(0, observed.length - maxObservedReferences);\n evicted.push(...overflow);\n next = next.filter(\n (reference) =>\n reference.status !== 'observed' ||\n !overflow.some((removed) => removed.sourcePath === reference.sourcePath),\n );\n }\n\n return { references: next, evicted };\n}\n\nfunction countActiveReferences(references: readonly IContextReferenceItem[]): number {\n return references.filter((reference) => reference.status === 'active').length;\n}\n\nfunction countActiveBytes(references: readonly IContextReferenceItem[]): number {\n return references.reduce(\n (total, reference) => total + (reference.status === 'active' ? reference.byteLength : 0),\n 0,\n );\n}\n\nfunction normalizeReferenceQuery(query: string): string {\n return query.startsWith('@') ? query.slice(1) : query;\n}\n\nfunction matchesContextReference(reference: IContextReferenceItem, query: string): boolean {\n return (\n reference.relativePath === query ||\n reference.sourcePath === query ||\n reference.originalReference === query ||\n reference.originalReference === `@${query}`\n );\n}\n","import { randomUUID } from 'node:crypto';\n\nimport type {\n IPromptFileReferenceDiagnostic,\n IPromptFileReferenceHistoryData,\n IPromptFileReferenceRecord,\n IResolvedPromptFileReference,\n} from './prompt-file-reference-types.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\n\nexport function buildPromptWithFileReferences(\n input: string,\n references: readonly IResolvedPromptFileReference[],\n): string {\n if (references.length === 0) return input;\n\n const blocks = references.map((reference) => {\n const content = reference.content.replaceAll('</file>', '<\\\\/file>');\n return [\n `<file path=\"${escapeAttribute(reference.relativePath)}\" bytes=\"${reference.byteLength}\" reason=\"${reference.reason}\">`,\n content,\n '</file>',\n ].join('\\n');\n });\n\n return [input, '<robota_file_references>', ...blocks, '</robota_file_references>'].join('\\n\\n');\n}\n\nexport function hasBlockingPromptFileReferenceDiagnostics(\n diagnostics: readonly IPromptFileReferenceDiagnostic[],\n): boolean {\n return diagnostics.some((diagnostic) => diagnostic.severity === 'error');\n}\n\nexport function formatPromptFileReferenceDiagnostics(\n diagnostics: readonly IPromptFileReferenceDiagnostic[],\n): string {\n if (diagnostics.length === 0) return '';\n return [\n 'File reference error:',\n ...diagnostics.map((diagnostic) => `- ${diagnostic.reference}: ${diagnostic.message}`),\n ].join('\\n');\n}\n\nexport function toPromptFileReferenceRecords(\n references: readonly IResolvedPromptFileReference[],\n): IPromptFileReferenceRecord[] {\n return references.map(({ content: _content, ...record }) => record);\n}\n\nexport function createPromptFileReferenceHistoryEntry(\n references: readonly IResolvedPromptFileReference[],\n): IHistoryEntry<IPromptFileReferenceHistoryData> {\n const records = toPromptFileReferenceRecords(references);\n return {\n id: `prompt_file_reference_${randomUUID()}`,\n timestamp: new Date(),\n category: 'event',\n type: 'prompt-file-reference',\n data: {\n message: formatLoadedPromptFileReferencesMessage(records),\n references: records,\n },\n };\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replaceAll('&', '&amp;')\n .replaceAll('\"', '&quot;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;');\n}\n\nfunction formatLoadedPromptFileReferencesMessage(\n references: readonly IPromptFileReferenceRecord[],\n): string {\n const list = references\n .map((reference) => `${reference.relativePath} (${reference.byteLength} B)`)\n .join(', ');\n return `Loaded file references: ${list}`;\n}\n","import type { IPromptFileReferenceToken } from './prompt-file-reference-types.js';\n\nconst REFERENCE_PATTERN = /(^|[\\s([{])@([^\\s)\\]}>,;\"'`]+)/g;\n\nexport function parsePromptFileReferences(input: string): IPromptFileReferenceToken[] {\n const references: IPromptFileReferenceToken[] = [];\n for (const match of input.matchAll(REFERENCE_PATTERN)) {\n const token = stripTrailingPunctuation(match[2] ?? '');\n if (!isPathLikeReference(token)) continue;\n references.push({\n original: `@${token}`,\n path: token,\n index: match.index ?? 0,\n });\n }\n return references;\n}\n\nfunction stripTrailingPunctuation(token: string): string {\n let end = token.length;\n while (end > 0 && /[.,:;!?]/.test(token[end - 1] ?? '')) {\n end -= 1;\n }\n return token.slice(0, end);\n}\n\nfunction isPathLikeReference(referencePath: string): boolean {\n if (referencePath.length === 0) return false;\n if (referencePath.includes('://')) return false;\n return (\n referencePath.startsWith('./') ||\n referencePath.startsWith('../') ||\n referencePath.startsWith('/') ||\n referencePath.startsWith('~/') ||\n referencePath.startsWith('.') ||\n referencePath.includes('.')\n );\n}\n","import { homedir } from 'node:os';\nimport { isAbsolute, relative as pathRelative, resolve, sep as pathSeparator } from 'node:path';\n\nexport function resolveCandidatePath(referencePath: string, rootPath: string): string {\n if (referencePath.startsWith('~/')) {\n return resolve(homedir(), referencePath.slice('~/'.length));\n }\n if (isAbsolute(referencePath)) {\n return resolve(referencePath);\n }\n return resolve(rootPath, referencePath);\n}\n\nexport function isPathWithinRoot(candidatePath: string, rootPath: string): boolean {\n const relativePath = pathRelative(rootPath, candidatePath);\n return relativePath === '' || (!relativePath.startsWith('..') && !isAbsolute(relativePath));\n}\n\nexport function normalizeRelativePath(rootPath: string, sourcePath: string): string {\n return pathRelative(rootPath, sourcePath).split(pathSeparator).join('/');\n}\n","import { resolve } from 'node:path';\n\nimport { parsePromptFileReferences } from './prompt-file-reference-parser.js';\nimport {\n isPathWithinRoot,\n normalizeRelativePath,\n resolveCandidatePath,\n} from './prompt-file-reference-paths.js';\nimport { NodeFileSystemAsync } from '../adapters/node-file-system.js';\n\nimport type {\n IPromptFileReferenceDiagnostic,\n IPromptFileReferenceLimits,\n IPromptFileReferenceResolveOptions,\n IPromptFileReferenceToken,\n IResolvedPromptFileReference,\n IResolvedPromptFileReferences,\n TPromptFileReferenceDiagnosticCode,\n TPromptFileReferenceReason,\n} from './prompt-file-reference-types.js';\nimport type { IFileSystemAsync } from '@robota-sdk/agent-core';\n\nconst DEFAULT_MAX_DEPTH = Number('2');\nconst DEFAULT_MAX_REFERENCES = Number('8');\nconst BYTES_PER_KIB = Number('1024');\nconst DEFAULT_MAX_FILE_BYTES = Number('64') * BYTES_PER_KIB;\nconst DEFAULT_MAX_TOTAL_BYTES = Number('256') * BYTES_PER_KIB;\n\ninterface IResolvedLimits {\n maxDepth: number;\n maxReferences: number;\n maxFileBytes: number;\n maxTotalBytes: number;\n}\n\ninterface IResolveState {\n rootPath: string;\n limits: IResolvedLimits;\n reason: TPromptFileReferenceReason;\n references: IResolvedPromptFileReference[];\n diagnostics: IPromptFileReferenceDiagnostic[];\n loadedPaths: Set<string>;\n totalBytes: number;\n fsAsync: IFileSystemAsync;\n}\n\ninterface IReferenceFileInfo {\n sourcePath: string;\n byteLength: number;\n}\n\nexport async function resolvePromptFileReferences(\n input: string,\n options: IPromptFileReferenceResolveOptions,\n): Promise<IResolvedPromptFileReferences> {\n const state = await createResolveState(options);\n for (const reference of parsePromptFileReferences(input)) {\n await resolveReference(reference, 0, [], state);\n }\n return toResolvedReferences(state);\n}\n\nexport async function resolvePromptFileReferencePaths(\n referencePaths: readonly string[],\n options: IPromptFileReferenceResolveOptions,\n): Promise<IResolvedPromptFileReferences> {\n const state = await createResolveState(options);\n for (const referencePath of referencePaths) {\n await resolveReference(\n { original: `@${referencePath}`, path: referencePath, index: 0 },\n 0,\n [],\n state,\n );\n }\n return toResolvedReferences(state);\n}\n\nasync function createResolveState(\n options: IPromptFileReferenceResolveOptions,\n): Promise<IResolveState> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n return {\n rootPath: await resolveWorkspaceRoot(options.cwd, fsAsync),\n limits: resolveLimits(options.limits),\n reason: options.reason ?? 'prompt-reference',\n references: [],\n diagnostics: [],\n loadedPaths: new Set<string>(),\n totalBytes: 0,\n fsAsync,\n };\n}\n\nfunction toResolvedReferences(state: IResolveState): IResolvedPromptFileReferences {\n return {\n references: state.references,\n diagnostics: state.diagnostics,\n };\n}\n\nfunction resolveLimits(limits: IPromptFileReferenceLimits | undefined): IResolvedLimits {\n return {\n maxDepth: limits?.maxDepth ?? DEFAULT_MAX_DEPTH,\n maxReferences: limits?.maxReferences ?? DEFAULT_MAX_REFERENCES,\n maxFileBytes: limits?.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES,\n maxTotalBytes: limits?.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES,\n };\n}\n\nasync function resolveWorkspaceRoot(cwd: string, fsAsync: IFileSystemAsync): Promise<string> {\n try {\n return await fsAsync.realpath(cwd);\n } catch {\n // allow-fallback: realpath fails for non-existent cwd; resolve() gives a usable absolute path\n return resolve(cwd);\n }\n}\n\nasync function resolveReference(\n reference: IPromptFileReferenceToken,\n depth: number,\n activePaths: readonly string[],\n state: IResolveState,\n): Promise<void> {\n if (!checkReferenceBudget(reference, depth, state)) return;\n\n const sourcePath = await resolveReferencePath(reference, state);\n if (sourcePath === undefined) return;\n if (!checkReferenceCycleAndDuplicate(reference, sourcePath, activePaths, state)) return;\n\n const fileInfo = await inspectReferenceFile(reference, sourcePath, state);\n if (fileInfo === undefined) return;\n\n const content = await readReferenceFile(reference, sourcePath, state);\n if (content === undefined) return;\n\n state.loadedPaths.add(sourcePath);\n state.totalBytes += fileInfo.byteLength;\n state.references.push(buildResolvedReference(reference, fileInfo, depth, content, state));\n await resolveNestedReferences(content, depth, [...activePaths, sourcePath], state);\n}\n\nfunction checkReferenceBudget(\n reference: IPromptFileReferenceToken,\n depth: number,\n state: IResolveState,\n): boolean {\n if (state.references.length >= state.limits.maxReferences) {\n pushDiagnostic(state, 'too-many-references', reference, 'Too many file references.');\n return false;\n }\n if (depth > state.limits.maxDepth) {\n pushDiagnostic(state, 'max-depth', reference, 'File reference nesting is too deep.');\n return false;\n }\n return true;\n}\n\nasync function resolveReferencePath(\n reference: IPromptFileReferenceToken,\n state: IResolveState,\n): Promise<string | undefined> {\n const candidatePath = resolveCandidatePath(reference.path, state.rootPath);\n if (!isPathWithinRoot(candidatePath, state.rootPath)) {\n pushDiagnostic(state, 'outside-root', reference, 'Referenced path is outside the workspace.');\n return undefined;\n }\n\n try {\n const sourcePath = await state.fsAsync.realpath(candidatePath);\n if (isPathWithinRoot(sourcePath, state.rootPath)) return sourcePath;\n pushDiagnostic(\n state,\n 'outside-root',\n reference,\n 'Referenced path resolves outside the workspace.',\n );\n } catch {\n // allow-fallback: realpath failure means file absent; diagnostic is the intended result\n pushDiagnostic(state, 'not-found', reference, 'Referenced file was not found.');\n }\n return undefined;\n}\n\nfunction checkReferenceCycleAndDuplicate(\n reference: IPromptFileReferenceToken,\n sourcePath: string,\n activePaths: readonly string[],\n state: IResolveState,\n): boolean {\n if (activePaths.includes(sourcePath)) {\n pushDiagnostic(state, 'circular-reference', reference, 'Circular file reference detected.');\n return false;\n }\n return !state.loadedPaths.has(sourcePath);\n}\n\nasync function inspectReferenceFile(\n reference: IPromptFileReferenceToken,\n sourcePath: string,\n state: IResolveState,\n): Promise<IReferenceFileInfo | undefined> {\n try {\n const fileStat = await state.fsAsync.stat(sourcePath);\n if (fileStat.isDirectory()) {\n pushDiagnostic(\n state,\n 'directory-not-supported',\n reference,\n 'Directory references are not supported.',\n );\n return undefined;\n }\n if (fileStat.size > state.limits.maxFileBytes) {\n pushDiagnostic(\n state,\n 'file-too-large',\n reference,\n 'Referenced file exceeds the per-file size limit.',\n );\n return undefined;\n }\n if (state.totalBytes + fileStat.size > state.limits.maxTotalBytes) {\n pushDiagnostic(\n state,\n 'total-too-large',\n reference,\n 'Referenced files exceed the total size limit.',\n );\n return undefined;\n }\n return { sourcePath, byteLength: fileStat.size };\n } catch {\n // allow-fallback: stat failure means unreadable; diagnostic is the intended result\n pushDiagnostic(state, 'unreadable', reference, 'Referenced file could not be inspected.');\n return undefined;\n }\n}\n\nasync function readReferenceFile(\n reference: IPromptFileReferenceToken,\n sourcePath: string,\n state: IResolveState,\n): Promise<string | undefined> {\n try {\n return await state.fsAsync.readFile(sourcePath, 'utf8');\n } catch {\n // allow-fallback: read failure means unreadable; diagnostic is the intended result\n pushDiagnostic(state, 'unreadable', reference, 'Referenced file could not be read.');\n return undefined;\n }\n}\n\nfunction buildResolvedReference(\n reference: IPromptFileReferenceToken,\n fileInfo: IReferenceFileInfo,\n depth: number,\n content: string,\n state: IResolveState,\n): IResolvedPromptFileReference {\n return {\n originalReference: reference.original,\n sourcePath: fileInfo.sourcePath,\n relativePath: normalizeRelativePath(state.rootPath, fileInfo.sourcePath),\n reason: state.reason,\n depth,\n byteLength: fileInfo.byteLength,\n content,\n };\n}\n\nasync function resolveNestedReferences(\n content: string,\n depth: number,\n activePaths: readonly string[],\n state: IResolveState,\n): Promise<void> {\n for (const nestedReference of parsePromptFileReferences(content)) {\n await resolveReference(nestedReference, depth + 1, activePaths, state);\n }\n}\n\nfunction pushDiagnostic(\n state: IResolveState,\n code: TPromptFileReferenceDiagnosticCode,\n reference: IPromptFileReferenceToken,\n message: string,\n): void {\n state.diagnostics.push({\n code,\n severity: 'error',\n reference: reference.original,\n message,\n path: reference.path,\n });\n}\n","/**\n * Prompt execution helpers for InteractiveSession.\n *\n * Contains abort detection, tool-summary extraction, and prompt preparation utilities.\n */\n\nimport { randomUUID } from 'node:crypto';\n\nimport { collectAssistantUsageMetadata } from '@robota-sdk/agent-core';\n\nimport { listActiveContextReferences } from '../context/context-reference-inventory.js';\nimport {\n buildPromptWithFileReferences,\n createPromptFileReferenceHistoryEntry,\n formatPromptFileReferenceDiagnostics,\n hasBlockingPromptFileReferenceDiagnostics,\n resolvePromptFileReferences,\n resolvePromptFileReferencePaths,\n toPromptFileReferenceRecords,\n} from '../context/prompt-file-references.js';\n\nimport type { IExecutionResult, IToolSummary, IUsageSnapshot } from './types.js';\nimport type { IContextReferenceItem } from '../context/context-reference-inventory.js';\nimport type { IPromptFileReferenceRecord } from '../context/prompt-file-references.js';\nimport type { IContextWindowState, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\n\nexport interface IPreparedPromptInput {\n modelInput: string;\n hookInput?: string;\n promptFileReferenceRecords: IPromptFileReferenceRecord[];\n activeContextReferenceRecords: IPromptFileReferenceRecord[];\n promptFileReferenceEntry?: IHistoryEntry;\n}\n\n/** Detect whether an error represents an abort/cancel action. */\nexport function isAbortError(err: unknown): boolean {\n return (\n (err instanceof DOMException && err.name === 'AbortError') ||\n (err instanceof Error && (err.message.includes('aborted') || err.message.includes('abort')))\n );\n}\n\n/**\n * Extract tool call summaries from a session history slice.\n *\n * Scans history entries from `historyBefore` onwards and collects\n * tool call records from assistant messages.\n */\nexport function extractToolSummaries(\n history: TUniversalMessage[],\n historyBefore: number,\n): IToolSummary[] {\n const summaries: IToolSummary[] = [];\n for (let i = historyBefore; i < history.length; i++) {\n const msg = history[i];\n if (msg?.role === 'assistant' && msg.toolCalls) {\n for (const tc of msg.toolCalls as Array<{\n function: { name: string; arguments: string };\n }>) {\n summaries.push({ name: tc.function.name, args: tc.function.arguments });\n }\n }\n }\n return summaries;\n}\n\n/**\n * Build an IExecutionResult from a completed response.\n */\nexport function buildResult(\n response: string,\n sessionHistory: TUniversalMessage[],\n interactiveHistory: IHistoryEntry[],\n historyBefore: number,\n contextState: IContextWindowState,\n promptFileReferences?: readonly IPromptFileReferenceRecord[],\n): IExecutionResult {\n const toolSummaries = extractToolSummaries(sessionHistory, historyBefore);\n const usage = extractTurnUsage(sessionHistory, historyBefore, contextState);\n return {\n response,\n history: interactiveHistory,\n toolSummaries,\n contextState,\n ...(usage && { usage }),\n ...(promptFileReferences && promptFileReferences.length > 0\n ? { promptFileReferences: [...promptFileReferences] }\n : {}),\n };\n}\n\n/**\n * Build an IExecutionResult for an interrupted (aborted) execution.\n * Collects any partial assistant text accumulated before the abort.\n */\nexport function buildInterruptedResult(\n sessionHistory: TUniversalMessage[],\n interactiveHistory: IHistoryEntry[],\n historyBefore: number,\n contextState: IContextWindowState,\n): IExecutionResult {\n const toolSummaries = extractToolSummaries(sessionHistory, historyBefore);\n const parts: string[] = [];\n for (let i = historyBefore; i < sessionHistory.length; i++) {\n const msg = sessionHistory[i];\n if (msg?.role === 'assistant' && msg.content) parts.push(msg.content);\n }\n const usage = extractTurnUsage(sessionHistory, historyBefore, contextState);\n return {\n response: parts.join('\\n\\n'),\n history: interactiveHistory,\n toolSummaries,\n contextState,\n ...(usage && { usage }),\n };\n}\n\nexport function createUsageSummaryEntry(usage: IUsageSnapshot): IHistoryEntry<IUsageSnapshot> {\n return {\n id: `usage_${randomUUID()}`,\n timestamp: new Date(),\n category: 'event',\n type: 'usage-summary',\n data: usage,\n };\n}\n\nexport async function preparePromptInput(\n input: string,\n cwd: string,\n rawInput?: string,\n contextReferences: readonly IContextReferenceItem[] = [],\n): Promise<IPreparedPromptInput> {\n const activeReferenceResult = await resolvePromptFileReferencePaths(\n listActiveContextReferences(contextReferences).map((reference) => reference.sourcePath),\n { cwd, reason: 'manual' },\n );\n const promptFileReferenceResult = await resolvePromptFileReferences(input, { cwd });\n const diagnostics = [\n ...activeReferenceResult.diagnostics,\n ...promptFileReferenceResult.diagnostics,\n ];\n if (hasBlockingPromptFileReferenceDiagnostics(diagnostics)) {\n throw new Error(formatPromptFileReferenceDiagnostics(diagnostics));\n }\n\n const resolvedReferences = dedupeResolvedReferences([\n ...activeReferenceResult.references,\n ...promptFileReferenceResult.references,\n ]);\n const modelInput = buildPromptWithFileReferences(input, resolvedReferences);\n const hookInput = rawInput ?? (modelInput === input ? undefined : input);\n const activeContextReferenceRecords = toPromptFileReferenceRecords(\n activeReferenceResult.references,\n );\n const promptFileReferenceRecords = toPromptFileReferenceRecords(\n promptFileReferenceResult.references,\n );\n const promptFileReferenceEntry =\n promptFileReferenceResult.references.length > 0\n ? createPromptFileReferenceHistoryEntry(promptFileReferenceResult.references)\n : undefined;\n\n return {\n modelInput,\n ...(hookInput !== undefined ? { hookInput } : {}),\n activeContextReferenceRecords,\n promptFileReferenceRecords,\n ...(promptFileReferenceEntry !== undefined ? { promptFileReferenceEntry } : {}),\n };\n}\n\nfunction dedupeResolvedReferences(\n references: readonly (IPromptFileReferenceRecord & { content: string })[],\n): Array<IPromptFileReferenceRecord & { content: string }> {\n return [...new Map(references.map((reference) => [reference.sourcePath, reference])).values()];\n}\n\nfunction extractTurnUsage(\n sessionHistory: TUniversalMessage[],\n historyBefore: number,\n contextState: IContextWindowState,\n): IUsageSnapshot | undefined {\n const turnMessages = sessionHistory.slice(historyBefore);\n let promptTokens = 0;\n let completionTokens = 0;\n let foundUsage = false;\n\n for (const message of turnMessages) {\n if (message.role !== 'assistant') continue;\n const usage = collectAssistantUsageMetadata(message);\n if (!usage) continue;\n foundUsage = true;\n promptTokens += usage.inputTokens;\n completionTokens += usage.outputTokens;\n }\n\n if (!foundUsage) return undefined;\n return {\n kind: 'exact',\n scope: 'turn',\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n contextUsedTokens: contextState.usedTokens,\n contextMaxTokens: contextState.maxTokens,\n contextUsedPercentage: contextState.usedPercentage,\n costStatus: 'unknown',\n };\n}\n\n/** No-op terminal implementation used during async initialization. */\nexport const NOOP_TERMINAL = {\n write: (): void => {},\n writeLine: (): void => {},\n writeMarkdown: (): void => {},\n writeError: (): void => {},\n prompt: (): Promise<string> => Promise.resolve(''),\n select: (): Promise<number> => Promise.resolve(0),\n spinner: () => ({ stop: () => {}, update: () => {} }),\n};\n","/**\n * Streaming and tool-event helpers for InteractiveSession.\n *\n * Pure functions that process streaming text deltas and tool execution events,\n * updating state passed in by reference. No class dependency.\n */\n\nimport { randomUUID } from 'node:crypto';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { IDiffLine, IToolState } from './types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\nimport type { TToolArgs } from '@robota-sdk/agent-core';\n\n/** Max chars to display from first tool argument. */\nexport const TOOL_ARG_DISPLAY_MAX = 80;\nconst TAIL_KEEP = 30;\n/** Max completed tools to keep in the activeTools array during a single response. */\nexport const MAX_COMPLETED_TOOLS = 50;\n/** Streaming text flush interval (ms) — ~60fps. */\nexport const STREAMING_FLUSH_INTERVAL_MS = 16;\nconst DEFAULT_START_LINE = 1;\nconst EDIT_DIFF_CONTEXT_LINES = 3;\n\n/** Extract a short display string from the first tool argument. */\nexport function extractFirstArg(toolArgs?: TToolArgs): string {\n if (!toolArgs) return '';\n const firstVal = Object.values(toolArgs)[0];\n const raw = typeof firstVal === 'string' ? firstVal : JSON.stringify(firstVal ?? '');\n return raw.length > TOOL_ARG_DISPLAY_MAX\n ? raw.slice(0, TOOL_ARG_DISPLAY_MAX - TAIL_KEEP - 3) + '...' + raw.slice(-TAIL_KEEP)\n : raw;\n}\n\n/** Mutable streaming state passed between helpers. */\nexport interface IStreamingState {\n activeTools: IToolState[];\n history: IHistoryEntry[];\n}\n\ninterface IToolEndEvent {\n type?: 'start' | 'end';\n toolName: string;\n toolArgs?: TToolArgs;\n success?: boolean;\n denied?: boolean;\n toolResultData?: string;\n}\n\nfunction getStringArg(args: TToolArgs | undefined, snake: string, camel: string): string | null {\n const value = args?.[snake] ?? args?.[camel];\n return typeof value === 'string' ? value : null;\n}\n\nfunction parseStartLine(toolResultData: string | undefined): number {\n if (!toolResultData) return DEFAULT_START_LINE;\n try {\n const parsed = JSON.parse(toolResultData) as Partial<{ startLine: number }>;\n return typeof parsed.startLine === 'number' && Number.isFinite(parsed.startLine)\n ? parsed.startLine\n : DEFAULT_START_LINE;\n } catch {\n return DEFAULT_START_LINE;\n }\n}\n\nfunction buildEditDiffState(event: IToolEndEvent): Pick<IToolState, 'diffFile' | 'diffLines'> {\n if (event.toolName !== 'Edit') return {};\n const filePath = getStringArg(event.toolArgs, 'file_path', 'filePath');\n const oldString = getStringArg(event.toolArgs, 'old_string', 'oldString');\n const newString = getStringArg(event.toolArgs, 'new_string', 'newString');\n if (!filePath || oldString === null || newString === null || oldString === newString) return {};\n\n const startLine = parseStartLine(event.toolResultData);\n return {\n diffFile: filePath,\n diffLines: buildEditDiffLinesWithContext(oldString, newString, startLine, filePath),\n };\n}\n\nfunction buildEditDiffLines(oldString: string, newString: string, startLine: number): IDiffLine[] {\n return [\n ...oldString.split('\\n').map((text, index) => ({\n type: 'remove' as const,\n text,\n lineNumber: startLine + index,\n })),\n ...newString.split('\\n').map((text, index) => ({\n type: 'add' as const,\n text,\n lineNumber: startLine + index,\n })),\n ];\n}\n\nfunction buildEditDiffLinesWithContext(\n oldString: string,\n newString: string,\n startLine: number,\n filePath: string,\n fs: IFileSystem = new NodeFileSystem(),\n): IDiffLine[] {\n const diffLines = buildEditDiffLines(oldString, newString, startLine);\n\n let fileLines: string[];\n try {\n fileLines = fs.readFileSync(filePath, 'utf8').split('\\n');\n } catch {\n // allow-fallback: unreadable file returns diff without context lines\n return diffLines;\n }\n\n const beforeContext: IDiffLine[] = [];\n const contextStart = Math.max(0, startLine - 1 - EDIT_DIFF_CONTEXT_LINES);\n for (let index = contextStart; index < startLine - 1; index++) {\n if (index < fileLines.length) {\n beforeContext.push({ type: 'context', text: fileLines[index], lineNumber: index + 1 });\n }\n }\n\n const afterContext: IDiffLine[] = [];\n const afterStart = startLine - 1 + newString.split('\\n').length;\n for (let index = afterStart; index < afterStart + EDIT_DIFF_CONTEXT_LINES; index++) {\n if (index < fileLines.length) {\n afterContext.push({ type: 'context', text: fileLines[index], lineNumber: index + 1 });\n }\n }\n\n const hunkStart =\n beforeContext[0]?.lineNumber ??\n diffLines[0]?.lineNumber ??\n afterContext[0]?.lineNumber ??\n startLine;\n const oldLineCount = oldString.split('\\n').length;\n const newLineCount = newString.split('\\n').length;\n const oldHunkLineCount = beforeContext.length + oldLineCount + afterContext.length;\n const newHunkLineCount = beforeContext.length + newLineCount + afterContext.length;\n\n return [\n {\n type: 'hunk',\n text: `@@ -${hunkStart},${oldHunkLineCount} +${hunkStart},${newHunkLineCount} @@`,\n lineNumber: hunkStart,\n },\n ...beforeContext,\n ...diffLines,\n ...afterContext,\n ];\n}\n\n/** Build a tool-summary history entry from current active tools and push it into history. */\nexport function pushToolSummaryToHistory(state: IStreamingState): void {\n if (state.activeTools.length === 0) return;\n const summary = state.activeTools\n .map((t) => {\n const status = t.isRunning\n ? '⟳'\n : t.result === 'success'\n ? '✓'\n : t.result === 'error'\n ? '✗'\n : '⊘';\n return `${status} ${t.toolName}${t.firstArg ? `(${t.firstArg})` : ''}`;\n })\n .join('\\n');\n\n state.history.push({\n id: randomUUID(),\n timestamp: new Date(),\n category: 'event',\n type: 'tool-summary',\n data: {\n tools: state.activeTools.map((t) => ({\n toolName: t.toolName,\n firstArg: t.firstArg,\n isRunning: t.isRunning,\n result: t.result,\n diffFile: t.diffFile,\n diffLines: t.diffLines,\n toolResultData: t.toolResultData,\n })),\n summary,\n },\n });\n}\n\n/** Trim oldest completed tools from the activeTools array if over the limit. */\nexport function trimCompletedTools(activeTools: IToolState[]): IToolState[] {\n const completed = activeTools.filter((t) => !t.isRunning);\n if (completed.length <= MAX_COMPLETED_TOOLS) return activeTools;\n\n const excess = completed.length - MAX_COMPLETED_TOOLS;\n let removed = 0;\n return activeTools.filter((t) => {\n if (!t.isRunning && removed < excess) {\n removed++;\n return false;\n }\n return true;\n });\n}\n\n/** Process a tool-start event: add to activeTools and push to history. */\nexport function applyToolStart(\n state: IStreamingState,\n event: { toolName: string; toolArgs?: TToolArgs },\n): IToolState {\n const firstArg = extractFirstArg(event.toolArgs);\n const toolState: IToolState = { toolName: event.toolName, firstArg, isRunning: true };\n state.activeTools.push(toolState);\n\n state.history.push({\n id: randomUUID(),\n timestamp: new Date(),\n category: 'event',\n type: 'tool-start',\n data: { toolName: event.toolName, firstArg, isRunning: true },\n });\n\n return toolState;\n}\n\n/** Process a tool-end event: mark the tool finished and push to history. Returns updated tool or null. */\nexport function applyToolEnd(state: IStreamingState, event: IToolEndEvent): IToolState | null {\n const result: IToolState['result'] = event.denied\n ? 'denied'\n : event.success === false\n ? 'error'\n : 'success';\n\n const idx = state.activeTools.findIndex((t) => t.toolName === event.toolName && t.isRunning);\n if (idx === -1) return null;\n\n const finished: IToolState = {\n ...state.activeTools[idx]!,\n ...buildEditDiffState(event),\n isRunning: false,\n result,\n toolResultData: event.toolResultData,\n };\n state.activeTools[idx] = finished;\n state.activeTools = trimCompletedTools(state.activeTools);\n\n state.history.push({\n id: randomUUID(),\n timestamp: new Date(),\n category: 'event',\n type: 'tool-end',\n data: {\n toolName: finished.toolName,\n firstArg: finished.firstArg,\n isRunning: false,\n result,\n toolResultData: event.toolResultData,\n },\n });\n\n return finished;\n}\n","/**\n * Prompt turn execution for InteractiveSession.\n *\n * Standalone function that runs one prompt turn, using callbacks to access\n * InteractiveSession state without coupling to the class directly.\n */\n\nimport {\n createUserMessage,\n createAssistantMessage,\n createSystemMessage,\n messageToHistoryEntry,\n} from '@robota-sdk/agent-core';\n\nimport {\n isAbortError,\n buildResult,\n buildInterruptedResult,\n createUsageSummaryEntry,\n preparePromptInput,\n} from './interactive-session-execution.js';\nimport { pushToolSummaryToHistory } from './interactive-session-streaming.js';\n\nimport type { IToolState, IExecutionResult } from './types.js';\nimport type { IContextReferenceItem } from '../context/context-reference-inventory.js';\nimport type { IPromptFileReferenceRecord } from '../context/prompt-file-references.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport interface IPromptTurnContext {\n getSession: () => Session;\n getCwd: () => string;\n getHistory: () => IHistoryEntry[];\n getContextReferences: () => readonly IContextReferenceItem[];\n getActiveTools: () => IToolState[];\n resetUsedMemoryReferences: () => void;\n recordContextReferenceUsage: (records: readonly IPromptFileReferenceRecord[]) => void;\n recordPromptContextReferences: (records: readonly IPromptFileReferenceRecord[]) => void;\n beginEditCheckpointTurn: (prompt: string) => Promise<void>;\n flushStreaming: () => void;\n clearStreaming: () => void;\n onComplete: (result: IExecutionResult) => void;\n onInterrupted: (result: IExecutionResult) => void;\n onError: (err: Error) => void;\n onContextUpdate: () => void;\n onWorkspaceUpdated: () => void;\n}\n\nexport async function executePromptTurn(\n input: string,\n displayInput: string | undefined,\n rawInput: string | undefined,\n ctx: IPromptTurnContext,\n): Promise<void> {\n const history = ctx.getHistory();\n history.push(messageToHistoryEntry(createUserMessage(displayInput ?? input)));\n ctx.onWorkspaceUpdated();\n const historyBefore = ctx.getSession().getHistory().length;\n ctx.resetUsedMemoryReferences();\n\n try {\n const preparedPrompt = await preparePromptInput(\n input,\n ctx.getCwd(),\n rawInput,\n ctx.getContextReferences(),\n );\n if (preparedPrompt.promptFileReferenceEntry) {\n history.push(preparedPrompt.promptFileReferenceEntry);\n }\n ctx.recordContextReferenceUsage(preparedPrompt.activeContextReferenceRecords);\n ctx.recordPromptContextReferences(preparedPrompt.promptFileReferenceRecords);\n\n await ctx.beginEditCheckpointTurn(displayInput ?? input);\n const response = await ctx\n .getSession()\n .run(preparedPrompt.modelInput, preparedPrompt.hookInput);\n ctx.flushStreaming();\n pushToolSummaryToHistory({ activeTools: ctx.getActiveTools(), history });\n ctx.clearStreaming();\n const result = buildResult(\n response || '(empty response)',\n ctx.getSession().getHistory(),\n history,\n historyBefore,\n ctx.getSession().getContextState(),\n preparedPrompt.promptFileReferenceRecords,\n );\n history.push(messageToHistoryEntry(createAssistantMessage(result.response)));\n if (result.usage) history.push(createUsageSummaryEntry(result.usage));\n ctx.onComplete(result);\n ctx.onContextUpdate();\n } catch (err) {\n ctx.flushStreaming();\n if (isAbortError(err)) {\n const result = buildInterruptedResult(\n ctx.getSession().getHistory(),\n history,\n historyBefore,\n ctx.getSession().getContextState(),\n );\n pushToolSummaryToHistory({ activeTools: ctx.getActiveTools(), history });\n ctx.clearStreaming();\n if (result.response)\n history.push(messageToHistoryEntry(createAssistantMessage(result.response)));\n if (result.usage) history.push(createUsageSummaryEntry(result.usage));\n history.push(messageToHistoryEntry(createSystemMessage('Interrupted by user.')));\n ctx.onInterrupted(result);\n } else {\n pushToolSummaryToHistory({ activeTools: ctx.getActiveTools(), history });\n ctx.clearStreaming();\n const errMsg = err instanceof Error ? err.message : String(err);\n history.push(messageToHistoryEntry(createSystemMessage(`Error: ${errMsg}`)));\n ctx.onError(err instanceof Error ? err : new Error(errMsg));\n }\n }\n}\n","/**\n * SessionExecutionController — owns execution lifecycle state and methods\n * for InteractiveSession.\n *\n * Manages: executing flag, streaming text, active tools, pending queue,\n * shutting-down flag, and all private execution lifecycle methods.\n */\n\nimport {\n createUserMessage,\n createAssistantMessage,\n createSystemMessage,\n messageToHistoryEntry,\n} from '@robota-sdk/agent-core';\n\nimport { checkAndRefreshContextIfStale } from './interactive-session-context-refresh.js';\nimport { executePromptTurn } from './interactive-session-prompt.js';\nimport {\n STREAMING_FLUSH_INTERVAL_MS,\n pushToolSummaryToHistory,\n applyToolStart,\n applyToolEnd,\n} from './interactive-session-streaming.js';\n\nimport type { SessionHistoryTracker } from './interactive-session-history-tracker.js';\nimport type { ICreatedInteractiveSession } from './interactive-session-init.js';\nimport type { SessionSkillRouter } from './interactive-session-skill-router.js';\nimport type { IToolState } from './types.js';\nimport type { IExecutionResult } from './types.js';\nimport type {\n IExecutionWorkspaceSnapshot,\n TExecutionWorkspaceUpdateCause,\n} from '../background-tasks/index.js';\nimport type { ICommand, ICommandResult, ISkillExecutionResult } from '../commands/index.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type { IContextFileEntry } from '../context/context-file-tracker.js';\nimport type { IContextWindowState, TToolArgs } from '@robota-sdk/agent-core';\nimport type { ICompactEvent } from '@robota-sdk/agent-session';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport interface IExecutionControllerCallbacks {\n getSession: () => Session;\n getSessionOrThrow: () => Session;\n getCwd: () => string;\n getContextState: () => IContextWindowState;\n getExecutionWorkspaceSnapshot: () => IExecutionWorkspaceSnapshot;\n emit: <E extends string>(event: E, ...args: unknown[]) => void;\n persistSession: () => void;\n}\nexport class SessionExecutionController {\n executing = false;\n streamingText = '';\n flushTimer: ReturnType<typeof setTimeout> | null = null;\n activeTools: IToolState[] = [];\n pendingPrompt: string | null = null;\n pendingDisplayInput: string | undefined;\n pendingRawInput: string | undefined;\n shuttingDown = false;\n\n constructor(\n private readonly histTracker: SessionHistoryTracker,\n private readonly skillRouter: SessionSkillRouter,\n private readonly callbacks: IExecutionControllerCallbacks,\n ) {}\n\n clearPendingQueue(): void {\n this.pendingPrompt = null;\n this.pendingDisplayInput = undefined;\n this.pendingRawInput = undefined;\n }\n\n clearStreaming(): void {\n this.streamingText = '';\n this.activeTools = [];\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n }\n\n flushStreaming(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n }\n\n handleTextDelta(delta: string): void {\n this.streamingText += delta;\n this.callbacks.emit('text_delta', delta);\n if (!this.flushTimer) {\n this.flushTimer = setTimeout(() => {\n this.flushTimer = null;\n }, STREAMING_FLUSH_INTERVAL_MS);\n }\n }\n\n handleCompactEvent(event: ICompactEvent): void {\n if (event.trigger === 'auto') {\n this.histTracker.append(\n messageToHistoryEntry(\n createSystemMessage(\n `Auto compacted context: ${Math.round(event.before.usedPercentage)}% -> ${Math.round(event.after.usedPercentage)}%`,\n ),\n ),\n );\n }\n this.callbacks.emit('compact', event);\n this.callbacks.emit('context_update', event.after);\n }\n\n handleToolExecution(event: {\n type: 'start' | 'end';\n toolName: string;\n toolArgs?: TToolArgs;\n success?: boolean;\n denied?: boolean;\n toolResultData?: string;\n }): void {\n const streamingState = {\n activeTools: this.activeTools,\n history: this.histTracker.getHistory(),\n };\n if (event.type === 'start') {\n const toolState = applyToolStart(streamingState, event);\n this.activeTools = streamingState.activeTools;\n this.callbacks.emit('tool_start', toolState);\n } else {\n const finished = applyToolEnd(streamingState, event);\n this.activeTools = streamingState.activeTools;\n if (finished) this.callbacks.emit('tool_end', finished);\n }\n }\n\n emitExecutionWorkspaceUpdated(cause: TExecutionWorkspaceUpdateCause, entryId?: string): void {\n const session = this.callbacks.getSession();\n if (!session) return;\n this.callbacks.emit('execution_workspace_event', {\n type: 'execution_workspace_updated',\n cause,\n ...(entryId ? { entryId } : {}),\n snapshot: this.callbacks.getExecutionWorkspaceSnapshot(),\n });\n }\n\n private drainPendingQueue(submit: (p: string, d?: string, r?: string) => Promise<void>): void {\n if (!this.shuttingDown && this.pendingPrompt) {\n const queued = this.pendingPrompt;\n const queuedDisplay = this.pendingDisplayInput;\n const queuedRaw = this.pendingRawInput;\n this.clearPendingQueue();\n setTimeout(() => void submit(queued, queuedDisplay, queuedRaw), 0);\n }\n }\n\n async executePrompt(\n input: string,\n displayInput: string | undefined,\n rawInput: string | undefined,\n agentsFileEntries: IContextFileEntry[],\n claudeFileEntries: IContextFileEntry[],\n rebuildSystemMessage: ICreatedInteractiveSession['rebuildSystemMessage'] | null,\n setEntries: (agents: IContextFileEntry[], claude: IContextFileEntry[]) => void,\n submit: (p: string, d?: string, r?: string) => Promise<void>,\n ): Promise<void> {\n await checkAndRefreshContextIfStale(\n agentsFileEntries,\n claudeFileEntries,\n rebuildSystemMessage,\n setEntries,\n () => this.callbacks.getSessionOrThrow(),\n (event: string, payload: unknown) => this.callbacks.emit(event, payload),\n );\n this.executing = true;\n this.clearStreaming();\n this.callbacks.emit('user_message', displayInput ?? input);\n this.callbacks.emit('thinking', true);\n try {\n await executePromptTurn(input, displayInput, rawInput, {\n getSession: () => this.callbacks.getSessionOrThrow(),\n getCwd: () => this.callbacks.getCwd(),\n getHistory: () => this.histTracker.getHistory(),\n getContextReferences: () => this.histTracker.listContextReferences(),\n getActiveTools: () => this.activeTools,\n resetUsedMemoryReferences: () => this.histTracker.resetUsedMemoryReferences(),\n recordContextReferenceUsage: (r) => this.histTracker.recordContextReferenceUsage(r),\n recordPromptContextReferences: (r) => this.histTracker.recordPromptContextReferences(r),\n beginEditCheckpointTurn: (p) => this.histTracker.beginEditCheckpointTurn(p),\n flushStreaming: () => this.flushStreaming(),\n clearStreaming: () => this.clearStreaming(),\n onWorkspaceUpdated: () => this.emitExecutionWorkspaceUpdated('main_thread'),\n onComplete: (result: IExecutionResult) => {\n this.callbacks.emit('complete', result);\n },\n onInterrupted: (result: IExecutionResult) => {\n this.callbacks.emit('interrupted', result);\n },\n onError: (err: Error) => {\n this.callbacks.emit('error', err);\n },\n onContextUpdate: () => {\n this.callbacks.emit('context_update', this.callbacks.getContextState());\n },\n });\n } finally {\n try {\n await this.histTracker.finalizeEditCheckpointTurn();\n } catch (error) {\n this.callbacks.emit('error', error instanceof Error ? error : new Error(String(error)));\n }\n this.executing = false;\n this.callbacks.emit('thinking', false);\n this.emitExecutionWorkspaceUpdated('main_thread');\n this.callbacks.persistSession();\n this.drainPendingQueue(submit);\n }\n }\n\n async executeForkSkillCommand(\n skill: ICommand,\n args: string,\n displayInput: string | undefined,\n qualifiedName: string | undefined,\n invocation: ISkillActivationEvent['invocation'],\n submit: (p: string, d?: string, r?: string) => Promise<void>,\n ): Promise<ISkillExecutionResult> {\n if (this.executing) {\n throw new Error('Cannot execute fork skill while another prompt is running.');\n }\n this.executing = true;\n this.clearStreaming();\n this.callbacks.emit('thinking', true);\n this.histTracker.append(\n messageToHistoryEntry(createUserMessage(displayInput ?? `/${skill.name}`)),\n );\n this.emitExecutionWorkspaceUpdated('main_thread');\n\n try {\n const result = await this.skillRouter.executeSkillWithActivation(\n skill,\n args,\n invocation,\n qualifiedName,\n );\n await this.applyForkSkillResult(result.result ?? '(empty response)');\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.histTracker.append(\n messageToHistoryEntry(createSystemMessage(`Error: ${error.message}`)),\n );\n this.callbacks.emit('error', error);\n return { mode: 'fork', result: '' };\n } finally {\n this.executing = false;\n this.callbacks.emit('thinking', false);\n this.emitExecutionWorkspaceUpdated('main_thread');\n this.callbacks.persistSession();\n this.drainPendingQueue(submit);\n }\n }\n\n async executeForegroundCommand(\n execute: () => Promise<ICommandResult>,\n submit: (p: string, d?: string, r?: string) => Promise<void>,\n ): Promise<ICommandResult> {\n this.executing = true;\n this.clearStreaming();\n this.callbacks.emit('thinking', true);\n this.emitExecutionWorkspaceUpdated('main_thread');\n try {\n const result = await execute();\n this.callbacks.emit('context_update', this.callbacks.getContextState());\n return result;\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n return { success: false, message: `Error: ${errMsg}` };\n } finally {\n this.executing = false;\n this.callbacks.emit('thinking', false);\n this.emitExecutionWorkspaceUpdated('main_thread');\n this.callbacks.persistSession();\n this.drainPendingQueue(submit);\n }\n }\n\n async applyForkSkillResult(result: string): Promise<void> {\n this.flushStreaming();\n pushToolSummaryToHistory({\n activeTools: this.activeTools,\n history: this.histTracker.getHistory(),\n });\n this.clearStreaming();\n const executionResult = {\n response: result,\n history: this.histTracker.getHistory(),\n toolSummaries: [],\n contextState: this.callbacks.getContextState(),\n };\n this.histTracker.append(messageToHistoryEntry(createAssistantMessage(result)));\n this.callbacks.emit('complete', executionResult);\n this.callbacks.emit('context_update', this.callbacks.getContextState());\n }\n}\n","/**\n * Fork skill execution helpers for InteractiveSession.\n *\n * Standalone functions for running skills in forked agent sessions.\n */\n\nimport { getBuiltInAgent } from '../agents/built-in-agents.js';\nimport { createSubagentSession } from '../assembly/create-subagent-session.js';\nimport { retrieveAgentToolDeps } from '../tools/agent-tool.js';\n\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type { IForkExecutionOptions } from '../commands/index.js';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport function resolveForkAgentDefinition(\n agentType: string,\n options: IForkExecutionOptions,\n parentSession: Session,\n): IAgentDefinition {\n const deps = retrieveAgentToolDeps(parentSession);\n const definition = deps?.customAgentRegistry?.(agentType) ?? getBuiltInAgent(agentType);\n if (!definition) {\n throw new Error(`Unknown agent type: ${agentType}`);\n }\n if (options.allowedTools) {\n return { ...definition, tools: options.allowedTools };\n }\n return definition;\n}\n\nexport async function runSkillInFork(\n content: string,\n options: IForkExecutionOptions,\n parentSession: Session,\n): Promise<string> {\n const deps = retrieveAgentToolDeps(parentSession);\n if (!deps) {\n throw new Error('Fork execution is not available. Agent runtime deps may not be initialized.');\n }\n const agentType = options.agent ?? 'general-purpose';\n const agentDefinition = resolveForkAgentDefinition(agentType, options, parentSession);\n const forkSession = createSubagentSession({\n agentDefinition,\n parentConfig: deps.config,\n parentContext: deps.context,\n parentTools: deps.tools,\n provider: deps.provider,\n terminal: deps.terminal,\n isForkWorker: true,\n permissionMode: deps.permissionMode,\n permissionHandler: deps.permissionHandler,\n hooks: deps.hooks,\n hookTypeExecutors: deps.hookTypeExecutors,\n onTextDelta: deps.onTextDelta,\n onToolExecution: deps.onToolExecution,\n });\n return forkSession.run(content);\n}\n","import {\n createContextReferenceItem,\n upsertContextReference,\n} from '../context/context-reference-inventory.js';\nimport {\n formatPromptFileReferenceDiagnostics,\n hasBlockingPromptFileReferenceDiagnostics,\n resolvePromptFileReferencePaths,\n toPromptFileReferenceRecords,\n} from '../context/prompt-file-references.js';\n\nimport type {\n IContextReferenceAddResult,\n IContextReferenceItem,\n} from '../context/context-reference-inventory.js';\nimport type { IPromptFileReferenceRecord } from '../context/prompt-file-references.js';\n\nexport interface IAddInteractiveContextReferenceResult {\n references: IContextReferenceItem[];\n result: IContextReferenceAddResult;\n}\n\nexport async function addInteractiveContextReference(\n references: readonly IContextReferenceItem[],\n path: string,\n cwd: string,\n): Promise<IAddInteractiveContextReferenceResult> {\n const result = await resolvePromptFileReferencePaths([path], {\n cwd,\n reason: 'manual',\n });\n if (hasBlockingPromptFileReferenceDiagnostics(result.diagnostics)) {\n return {\n references: [...references],\n result: {\n evicted: [],\n diagnostics: [formatPromptFileReferenceDiagnostics(result.diagnostics)],\n },\n };\n }\n\n const reference = result.references[0];\n if (!reference) {\n return {\n references: [...references],\n result: { evicted: [], diagnostics: ['No context reference was resolved.'] },\n };\n }\n\n const item = createContextReferenceItem(\n toPromptFileReferenceRecords([reference])[0]!,\n 'manual',\n 'active',\n );\n const upserted = upsertContextReference(references, item);\n return {\n references: upserted.references,\n result: {\n reference: item,\n evicted: upserted.evicted,\n diagnostics: [],\n },\n };\n}\n\nexport function recordInteractiveContextReferences(\n references: readonly IContextReferenceItem[],\n records: readonly IPromptFileReferenceRecord[],\n options: { loadType: 'manual' | 'prompt-reference'; status: 'active' | 'observed' },\n): IContextReferenceItem[] {\n if (records.length === 0) return [...references];\n const now = new Date().toISOString();\n let next = [...references];\n for (const record of records) {\n const item = createContextReferenceItem(record, options.loadType, options.status, now);\n next = upsertContextReference(next, item).references;\n }\n return next;\n}\n","/**\n * Standard Robota storage paths.\n *\n * All CLI runtime data lives under .robota/ (project) or ~/.robota/ (user).\n * .agents/ is read-only from CLI's perspective (owned by AGENTS.md standard).\n */\n\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/** Project-level .robota/ paths (relative to cwd). */\nexport function projectPaths(cwd: string): {\n settings: string;\n settingsLocal: string;\n logs: string;\n sessions: string;\n memory: string;\n checkpoints: string;\n} {\n const base = join(cwd, '.robota');\n return {\n settings: join(base, 'settings.json'),\n settingsLocal: join(base, 'settings.local.json'),\n logs: join(base, 'logs'),\n sessions: join(base, 'sessions'),\n memory: join(base, 'memory'),\n checkpoints: join(base, 'checkpoints'),\n };\n}\n\n/** User-level ~/.robota/ paths. */\nexport function userPaths(): {\n settings: string;\n sessions: string;\n} {\n const base = join(homedir(), '.robota');\n return {\n settings: join(base, 'settings.json'),\n sessions: join(base, 'sessions'),\n };\n}\n","import { join, relative } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type {\n IEditCheckpointInspection,\n IEditCheckpointInspectionPlan,\n IEditCheckpointManifest,\n IEditCheckpointSummary,\n} from './edit-checkpoint-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\ninterface IEditCheckpointInspectionInput {\n cwd: string;\n sessionId: string;\n target: IEditCheckpointManifest;\n manifests: readonly IEditCheckpointManifest[];\n checkpointDir: (sessionId: string, checkpointId: string) => string;\n fs?: IFileSystem;\n}\n\nexport function buildEditCheckpointInspection(\n input: IEditCheckpointInspectionInput,\n): IEditCheckpointInspection {\n const fs = input.fs ?? new NodeFileSystem();\n const later = input.manifests.filter((manifest) => manifest.sequence > input.target.sequence);\n const rollbackRange = input.manifests.filter(\n (manifest) => manifest.sequence >= input.target.sequence,\n );\n\n return {\n target: toSummary(input.target),\n capturedFiles: input.target.files.map((file) => {\n const snapshotPath = file.snapshotFile\n ? join(input.checkpointDir(input.sessionId, input.target.id), file.snapshotFile)\n : undefined;\n const snapshotStats = snapshotPath ? statSafe(snapshotPath, fs) : undefined;\n return {\n originalPath: file.originalPath,\n relativePath: relative(input.cwd, file.originalPath),\n existed: file.existed,\n restoreAction: file.existed ? 'restore-preimage' : 'delete-created-file',\n snapshotAvailable: file.existed ? snapshotStats !== undefined : false,\n ...(snapshotStats ? { snapshotSizeBytes: snapshotStats.size } : {}),\n };\n }),\n restoreToCheckpoint: toInspectionPlan(later),\n rollbackThroughCheckpoint: toInspectionPlan(rollbackRange),\n };\n}\n\nfunction toSummary(manifest: IEditCheckpointManifest): IEditCheckpointSummary {\n return {\n id: manifest.id,\n sessionId: manifest.sessionId,\n sequence: manifest.sequence,\n prompt: manifest.prompt,\n createdAt: manifest.createdAt,\n fileCount: manifest.fileCount,\n };\n}\n\nfunction toInspectionPlan(\n manifests: readonly IEditCheckpointManifest[],\n): IEditCheckpointInspectionPlan {\n return {\n checkpointIds: manifests.map((manifest) => manifest.id),\n fileCount: manifests.reduce((count, manifest) => count + manifest.fileCount, 0),\n };\n}\n\nfunction statSafe(path: string, fs: IFileSystem): { size: number } | undefined {\n try {\n return fs.statSync(path);\n } catch {\n // allow-fallback: missing snapshot file returns undefined to mark snapshot unavailable\n return undefined;\n }\n}\n","import { dirname, join, relative, resolve } from 'node:path';\n\nimport { NodeFileSystem, NodeFileSystemAsync } from '../adapters/node-file-system.js';\nimport { projectPaths } from '../paths.js';\nimport { buildEditCheckpointInspection } from './edit-checkpoint-inspection.js';\n\nimport type {\n IEditCheckpointFileRecord,\n IEditCheckpointInspection,\n IEditCheckpointManifest,\n IEditCheckpointRestoreResult,\n IEditCheckpointSummary,\n IEditCheckpointTurnInput,\n} from './edit-checkpoint-types.js';\nimport type { IFileSystem, IFileSystemAsync } from '@robota-sdk/agent-core';\n\nconst MANIFEST_FILE = 'manifest.json';\nconst SNAPSHOT_DIR = 'files';\nconst ID_PAD = 4;\nconst SNAPSHOT_PAD = 6;\ninterface IActiveEditCheckpointTurn {\n manifest: IEditCheckpointManifest;\n dir: string;\n capturedPaths: Set<string>;\n}\n\ninterface IEditCheckpointStoreOptions {\n cwd: string;\n now?: () => Date;\n}\nexport class EditCheckpointStore {\n private readonly cwd: string;\n private readonly rootDir: string;\n private readonly now: () => Date;\n private activeTurn: IActiveEditCheckpointTurn | null = null;\n\n constructor(\n options: IEditCheckpointStoreOptions,\n private readonly fs: IFileSystem = new NodeFileSystem(),\n private readonly fsAsync: IFileSystemAsync = new NodeFileSystemAsync(),\n ) {\n this.cwd = resolve(options.cwd);\n this.rootDir = projectPaths(this.cwd).checkpoints;\n this.now = options.now ?? (() => new Date());\n }\n\n async beginTurn(input: IEditCheckpointTurnInput): Promise<IEditCheckpointSummary> {\n if (this.activeTurn) {\n await this.finalizeTurn();\n }\n\n const nextSequence = this.nextSequence(input.sessionId);\n const id = `turn-${String(nextSequence).padStart(ID_PAD, '0')}`;\n const dir = join(this.sessionDir(input.sessionId), id);\n await this.fsAsync.mkdir(join(dir, SNAPSHOT_DIR), { recursive: true });\n\n const manifest: IEditCheckpointManifest = {\n version: 1,\n id,\n sessionId: input.sessionId,\n sequence: nextSequence,\n prompt: input.prompt,\n createdAt: this.now().toISOString(),\n fileCount: 0,\n files: [],\n };\n\n this.activeTurn = {\n manifest,\n dir,\n capturedPaths: new Set<string>(),\n };\n\n return toSummary(manifest);\n }\n\n async captureFile(filePath: string): Promise<void> {\n if (!this.activeTurn) return;\n\n const originalPath = resolve(this.cwd, filePath);\n if (this.activeTurn.capturedPaths.has(originalPath)) return;\n if (isInside(this.rootDir, originalPath)) return;\n\n const record = await this.createFileRecord(originalPath, this.activeTurn);\n this.activeTurn.manifest.files.push(record);\n this.activeTurn.manifest.fileCount = this.activeTurn.manifest.files.length;\n this.activeTurn.capturedPaths.add(originalPath);\n }\n\n async finalizeTurn(): Promise<IEditCheckpointSummary | undefined> {\n if (!this.activeTurn) return undefined;\n const active = this.activeTurn;\n this.activeTurn = null;\n await this.writeManifest(active.dir, active.manifest);\n return toSummary(active.manifest);\n }\n\n list(sessionId: string): IEditCheckpointSummary[] {\n return this.loadManifests(sessionId).map(toSummary);\n }\n\n inspect(sessionId: string, checkpointId: string): IEditCheckpointInspection {\n const manifests = this.loadManifests(sessionId);\n const target = manifests.find((manifest) => manifest.id === checkpointId);\n if (!target) {\n throw new Error(`Unknown edit checkpoint: ${checkpointId}`);\n }\n\n return buildEditCheckpointInspection({\n cwd: this.cwd,\n sessionId,\n target,\n manifests,\n checkpointDir: (inputSessionId, inputCheckpointId) =>\n this.checkpointDir(inputSessionId, inputCheckpointId),\n });\n }\n\n async restoreToCheckpoint(\n sessionId: string,\n checkpointId: string,\n ): Promise<IEditCheckpointRestoreResult> {\n const manifests = this.loadManifests(sessionId);\n const target = manifests.find((manifest) => manifest.id === checkpointId);\n if (!target) {\n throw new Error(`Unknown edit checkpoint: ${checkpointId}`);\n }\n\n const later = manifests\n .filter((manifest) => manifest.sequence > target.sequence)\n .sort((a, b) => b.sequence - a.sequence);\n\n let restoredFileCount = 0;\n for (const manifest of later) {\n for (const file of manifest.files) {\n await this.restoreFile(sessionId, manifest.id, file);\n restoredFileCount += 1;\n }\n }\n\n for (const manifest of later) {\n await this.fsAsync.rm(this.checkpointDir(sessionId, manifest.id), {\n recursive: true,\n force: true,\n });\n }\n\n return {\n target: toSummary(target),\n restoredCheckpointCount: later.length,\n restoredFileCount,\n removedCheckpointCount: later.length,\n };\n }\n\n async rollbackThroughCheckpoint(\n sessionId: string,\n checkpointId: string,\n ): Promise<IEditCheckpointRestoreResult> {\n const manifests = this.loadManifests(sessionId);\n const target = manifests.find((manifest) => manifest.id === checkpointId);\n if (!target) {\n throw new Error(`Unknown edit checkpoint: ${checkpointId}`);\n }\n\n const rollbackRange = manifests\n .filter((manifest) => manifest.sequence >= target.sequence)\n .sort((a, b) => b.sequence - a.sequence);\n\n let restoredFileCount = 0;\n for (const manifest of rollbackRange) {\n for (const file of manifest.files) {\n await this.restoreFile(sessionId, manifest.id, file);\n restoredFileCount += 1;\n }\n }\n\n for (const manifest of rollbackRange) {\n await this.fsAsync.rm(this.checkpointDir(sessionId, manifest.id), {\n recursive: true,\n force: true,\n });\n }\n\n return {\n target: toSummary(target),\n restoredCheckpointCount: rollbackRange.length,\n restoredFileCount,\n removedCheckpointCount: rollbackRange.length,\n };\n }\n\n private async createFileRecord(\n originalPath: string,\n active: IActiveEditCheckpointTurn,\n ): Promise<IEditCheckpointFileRecord> {\n const existed = await pathExists(this.fsAsync, this.fs, originalPath);\n if (!existed) {\n return {\n originalPath,\n existed: false,\n };\n }\n\n const snapshotFile = join(\n SNAPSHOT_DIR,\n `${String(active.manifest.files.length + 1).padStart(SNAPSHOT_PAD, '0')}.content`,\n );\n await this.fsAsync.copyFile(originalPath, join(active.dir, snapshotFile));\n return {\n originalPath,\n existed: true,\n snapshotFile,\n };\n }\n\n private async restoreFile(\n sessionId: string,\n checkpointId: string,\n record: IEditCheckpointFileRecord,\n ): Promise<void> {\n if (!record.existed) {\n await this.fsAsync.rm(record.originalPath, { force: true });\n return;\n }\n if (!record.snapshotFile) {\n throw new Error(`Checkpoint file record is missing a snapshot: ${record.originalPath}`);\n }\n await this.fsAsync.mkdir(dirname(record.originalPath), { recursive: true });\n await this.fsAsync.copyFile(\n join(this.checkpointDir(sessionId, checkpointId), record.snapshotFile),\n record.originalPath,\n );\n }\n\n private loadManifests(sessionId: string): IEditCheckpointManifest[] {\n const dir = this.sessionDir(sessionId);\n return readDirSyncSafe(this.fs, dir)\n .map((entry) => join(dir, entry, MANIFEST_FILE))\n .map((manifestPath) => readJsonManifest(this.fs, manifestPath))\n .filter((manifest): manifest is IEditCheckpointManifest => manifest !== undefined)\n .sort((a, b) => a.sequence - b.sequence);\n }\n\n private nextSequence(sessionId: string): number {\n const last = this.list(sessionId).at(-1);\n return (last?.sequence ?? 0) + 1;\n }\n\n private async writeManifest(dir: string, manifest: IEditCheckpointManifest): Promise<void> {\n await this.fsAsync.mkdir(dir, { recursive: true });\n const path = join(dir, MANIFEST_FILE);\n const tmp = `${path}.tmp`;\n await this.fsAsync.writeFile(tmp, JSON.stringify(manifest, null, 2), 'utf8');\n await this.fsAsync.rename(tmp, path);\n }\n\n private sessionDir(sessionId: string): string {\n return join(this.rootDir, safePathSegment(sessionId));\n }\n\n private checkpointDir(sessionId: string, checkpointId: string): string {\n return join(this.sessionDir(sessionId), safePathSegment(checkpointId));\n }\n}\n\nfunction toSummary(manifest: IEditCheckpointManifest): IEditCheckpointSummary {\n return {\n id: manifest.id,\n sessionId: manifest.sessionId,\n sequence: manifest.sequence,\n prompt: manifest.prompt,\n createdAt: manifest.createdAt,\n fileCount: manifest.fileCount,\n };\n}\n\nfunction safePathSegment(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]/g, '_');\n}\n\nfunction isInside(parent: string, child: string): boolean {\n const rel = relative(parent, child);\n return rel.length === 0 || (!rel.startsWith('..') && !rel.startsWith('/'));\n}\n\nasync function pathExists(\n fsAsync: IFileSystemAsync,\n fs: IFileSystem,\n path: string,\n): Promise<boolean> {\n try {\n await fsAsync.access(path, fs.constants.F_OK);\n return true;\n } catch {\n // allow-fallback: access failure means file absent, false is the correct result\n return false;\n }\n}\n\nfunction readDirSyncSafe(fs: IFileSystem, dir: string): string[] {\n try {\n return fs.readdirSync(dir);\n } catch {\n // allow-fallback: missing directory returns empty list, not an error\n return [];\n }\n}\n\nfunction readJsonManifest(fs: IFileSystem, path: string): IEditCheckpointManifest | undefined {\n try {\n const raw = fs.readFileSync(path, 'utf8');\n return JSON.parse(raw) as IEditCheckpointManifest;\n } catch {\n // allow-fallback: corrupted/missing manifest is filtered out by caller\n return undefined;\n }\n}\n","import type { ICommand } from '../command-api/types.js';\n\nexport type TSkillActivationSource = 'skill' | 'plugin';\nexport type TSkillActivationInvocation = 'user-slash' | 'model-tool';\nexport type TSkillActivationMode = 'inject' | 'fork';\nexport type TSkillActivationStatus = 'started' | 'completed' | 'failed';\n\nexport interface ISkillActivationEvent {\n readonly type: 'skill-activation';\n readonly skillName: string;\n readonly source: TSkillActivationSource;\n readonly invocation: TSkillActivationInvocation;\n readonly mode: TSkillActivationMode;\n readonly status: TSkillActivationStatus;\n readonly timestamp: string;\n readonly qualifiedName?: string;\n readonly error?: string;\n}\n\nexport interface ISkillActivationHistoryData extends ISkillActivationEvent {\n readonly message: string;\n}\n\nexport interface ICreateSkillActivationEventInput {\n readonly skill: ICommand;\n readonly invocation: TSkillActivationInvocation;\n readonly status: TSkillActivationStatus;\n readonly qualifiedName?: string;\n readonly error?: string;\n}\n\nexport function getSkillActivationSource(skill: ICommand): TSkillActivationSource {\n return skill.source === 'plugin' ? 'plugin' : 'skill';\n}\n\nexport function getSkillActivationMode(skill: ICommand): TSkillActivationMode {\n return skill.context === 'fork' ? 'fork' : 'inject';\n}\n\nexport function createSkillActivationEvent(\n input: ICreateSkillActivationEventInput,\n): ISkillActivationEvent {\n return {\n type: 'skill-activation',\n skillName: input.skill.name,\n source: getSkillActivationSource(input.skill),\n invocation: input.invocation,\n mode: getSkillActivationMode(input.skill),\n status: input.status,\n timestamp: new Date().toISOString(),\n ...(input.qualifiedName !== undefined ? { qualifiedName: input.qualifiedName } : {}),\n ...(input.error !== undefined ? { error: input.error } : {}),\n };\n}\n\nexport function formatSkillActivationMessage(event: ISkillActivationEvent): string {\n const sourceLabel = event.source === 'plugin' ? 'plugin skill' : 'skill';\n if (event.status === 'failed') {\n return `Skill failed: ${event.skillName}${event.error ? ` (${event.error})` : ''}`;\n }\n if (event.status === 'completed') {\n return `Skill completed: ${event.skillName}`;\n }\n return `Invoking ${sourceLabel}: ${event.skillName}`;\n}\n","/**\n * SessionHistoryTracker — manages history, edit checkpoints, memory events,\n * context references, and skill activation events for an InteractiveSession.\n */\n\nimport { randomUUID } from 'node:crypto';\n\nimport { createSystemMessage, messageToHistoryEntry } from '@robota-sdk/agent-core';\n\nimport {\n addInteractiveContextReference,\n recordInteractiveContextReferences,\n} from './interactive-session-context-references.js';\nimport { EditCheckpointStore } from '../checkpoints/edit-checkpoint-store.js';\nimport { formatSkillActivationMessage } from '../commands/skill-activation-events.js';\nimport {\n clearContextReferences,\n removeContextReference,\n} from '../context/context-reference-inventory.js';\n\nimport type {\n IEditCheckpointInspection,\n IEditCheckpointRestoreResult,\n IEditCheckpointSummary,\n} from '../checkpoints/edit-checkpoint-types.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type {\n IContextReferenceAddResult,\n IContextReferenceClearResult,\n IContextReferenceItem,\n IContextReferenceRemoveResult,\n} from '../context/context-reference-inventory.js';\nimport type { IPromptFileReferenceRecord } from '../context/prompt-file-references.js';\nimport type { IMemoryEvent, IMemoryReference } from '../memory/automatic-memory-types.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\n\nexport interface IHistoryTrackerState {\n history: IHistoryEntry[];\n memoryEvents: IMemoryEvent[];\n usedMemoryReferences: IMemoryReference[];\n contextReferences: IContextReferenceItem[];\n skillActivationEvents: ISkillActivationEvent[];\n}\n\nexport class SessionHistoryTracker {\n private history: IHistoryEntry[] = [];\n private editCheckpointStore: EditCheckpointStore | null = null;\n private memoryEvents: IMemoryEvent[] = [];\n private usedMemoryReferences: IMemoryReference[] = [];\n private contextReferences: IContextReferenceItem[] = [];\n private skillActivationEvents: ISkillActivationEvent[] = [];\n\n constructor(\n private readonly cwd: string,\n private readonly getSessionId: () => string,\n private readonly getExecuting: () => boolean,\n private readonly persistSession: () => void,\n private readonly emitSkillActivation: (event: ISkillActivationEvent) => void,\n editCheckpointStore: EditCheckpointStore | null = null,\n ) {\n this.editCheckpointStore = editCheckpointStore;\n }\n\n restoreState(state: IHistoryTrackerState): void {\n this.history = state.history;\n this.memoryEvents = state.memoryEvents;\n this.usedMemoryReferences = state.usedMemoryReferences;\n this.contextReferences = state.contextReferences;\n this.skillActivationEvents = state.skillActivationEvents;\n }\n\n getState(): IHistoryTrackerState {\n return {\n history: this.history,\n memoryEvents: this.memoryEvents,\n usedMemoryReferences: this.usedMemoryReferences,\n contextReferences: this.contextReferences,\n skillActivationEvents: this.skillActivationEvents,\n };\n }\n\n append(entry: IHistoryEntry): void {\n this.history.push(entry);\n }\n\n getHistory(): IHistoryEntry[] {\n return this.history;\n }\n\n clearHistory(): void {\n this.history = [];\n this.memoryEvents = [];\n this.usedMemoryReferences = [];\n }\n\n resetUsedMemoryReferences(): void {\n this.usedMemoryReferences = [];\n }\n\n recordContextReferenceUsage(records: readonly IPromptFileReferenceRecord[]): void {\n this.contextReferences = recordInteractiveContextReferences(this.contextReferences, records, {\n loadType: 'manual',\n status: 'active',\n });\n this.persistSession();\n }\n\n recordPromptContextReferences(records: readonly IPromptFileReferenceRecord[]): void {\n this.contextReferences = recordInteractiveContextReferences(this.contextReferences, records, {\n loadType: 'prompt-reference',\n status: 'observed',\n });\n this.persistSession();\n }\n\n listEditCheckpoints(): IEditCheckpointSummary[] {\n const sessionId = this.getSessionId();\n return this.getCheckpointStore().list(sessionId);\n }\n\n inspectEditCheckpoint(checkpointId: string): IEditCheckpointInspection {\n const sessionId = this.getSessionId();\n return this.getCheckpointStore().inspect(sessionId, checkpointId);\n }\n\n async restoreEditCheckpoint(checkpointId: string): Promise<IEditCheckpointRestoreResult> {\n if (this.getExecuting()) {\n throw new Error('Cannot restore edit checkpoint while a prompt is running.');\n }\n const result = await this.getCheckpointStore().restoreToCheckpoint(\n this.getSessionId(),\n checkpointId,\n );\n this.history.push(\n messageToHistoryEntry(createSystemMessage(`Restored edit checkpoint: ${checkpointId}`)),\n );\n this.persistSession();\n return result;\n }\n\n async rollbackEditCheckpoint(checkpointId: string): Promise<IEditCheckpointRestoreResult> {\n if (this.getExecuting()) {\n throw new Error('Cannot rollback edit checkpoint while a prompt is running.');\n }\n const result = await this.getCheckpointStore().rollbackThroughCheckpoint(\n this.getSessionId(),\n checkpointId,\n );\n this.history.push(\n messageToHistoryEntry(createSystemMessage(`Rolled back edit checkpoint: ${checkpointId}`)),\n );\n this.persistSession();\n return result;\n }\n\n async beginEditCheckpointTurn(prompt: string): Promise<void> {\n if (!this.editCheckpointStore) return;\n await this.editCheckpointStore.beginTurn({ sessionId: this.getSessionId(), prompt });\n }\n\n async finalizeEditCheckpointTurn(): Promise<void> {\n if (!this.editCheckpointStore) return;\n try {\n await this.editCheckpointStore.finalizeTurn();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.history.push(\n messageToHistoryEntry(createSystemMessage(`Checkpoint error: ${err.message}`)),\n );\n throw err;\n }\n }\n\n setEditCheckpointStore(store: EditCheckpointStore): void {\n this.editCheckpointStore = store;\n }\n\n getUsedMemoryReferences(): IMemoryReference[] {\n return [...this.usedMemoryReferences];\n }\n\n recordMemoryEvent(event: IMemoryEvent): void {\n this.memoryEvents.push(event);\n this.persistSession();\n }\n\n listContextReferences(): IContextReferenceItem[] {\n return [...this.contextReferences];\n }\n\n async addContextReference(path: string): Promise<IContextReferenceAddResult> {\n const { references, result } = await addInteractiveContextReference(\n this.contextReferences,\n path,\n this.cwd,\n );\n this.contextReferences = references;\n this.persistSession();\n return result;\n }\n\n removeContextReference(path: string): IContextReferenceRemoveResult {\n const result = removeContextReference(this.contextReferences, path);\n this.contextReferences = result.references;\n this.persistSession();\n return result.result;\n }\n\n clearContextReferences(): IContextReferenceClearResult {\n const result = clearContextReferences(this.contextReferences);\n this.contextReferences = [];\n this.persistSession();\n return result;\n }\n\n getSkillActivationEvents(): ISkillActivationEvent[] {\n return [...this.skillActivationEvents];\n }\n\n recordSkillActivationEvent(event: ISkillActivationEvent, appendHistory: boolean): void {\n this.skillActivationEvents.push(event);\n if (appendHistory) {\n this.history.push({\n id: randomUUID(),\n timestamp: new Date(event.timestamp),\n category: 'event',\n type: 'skill-activation',\n data: {\n ...event,\n message: formatSkillActivationMessage(event),\n },\n });\n }\n this.emitSkillActivation(event);\n this.persistSession();\n }\n\n private getCheckpointStore(): EditCheckpointStore {\n if (!this.editCheckpointStore) {\n this.editCheckpointStore = new EditCheckpointStore({ cwd: this.cwd });\n }\n return this.editCheckpointStore;\n }\n}\n","/**\n * Project detector — infers project type, name, package manager, and language\n * from files present in the given directory.\n */\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\n\nexport type TProjectType = 'node' | 'python' | 'rust' | 'go' | 'unknown';\nexport type TPackageManager = 'pnpm' | 'yarn' | 'npm' | 'bun';\nexport type TLanguage = 'typescript' | 'javascript' | 'python' | 'rust' | 'go' | 'unknown';\n\nexport interface IProjectInfo {\n type: TProjectType;\n name?: string;\n packageManager?: TPackageManager;\n language: TLanguage;\n}\n\ninterface IPackageJson {\n name?: string;\n packageManager?: string;\n}\n\nfunction tryReadJson(filePath: string): IPackageJson | undefined {\n if (!existsSync(filePath)) return undefined;\n try {\n return JSON.parse(readFileSync(filePath, 'utf-8')) as IPackageJson;\n } catch {\n return undefined;\n }\n}\n\nfunction detectPackageManager(cwd: string): TPackageManager | undefined {\n if (existsSync(join(cwd, 'pnpm-workspace.yaml')) || existsSync(join(cwd, 'pnpm-lock.yaml'))) {\n return 'pnpm';\n }\n if (existsSync(join(cwd, 'yarn.lock'))) {\n return 'yarn';\n }\n if (existsSync(join(cwd, 'bun.lockb'))) {\n return 'bun';\n }\n if (existsSync(join(cwd, 'package-lock.json'))) {\n return 'npm';\n }\n return undefined;\n}\n\n/**\n * Detect the project type, language, name, and package manager from `cwd`.\n */\nexport async function detectProject(cwd: string): Promise<IProjectInfo> {\n const pkgJsonPath = join(cwd, 'package.json');\n const tsconfigPath = join(cwd, 'tsconfig.json');\n const pyprojectPath = join(cwd, 'pyproject.toml');\n const cargoPath = join(cwd, 'Cargo.toml');\n const goModPath = join(cwd, 'go.mod');\n\n // Node.js project\n if (existsSync(pkgJsonPath)) {\n const pkgJson = tryReadJson(pkgJsonPath);\n const language: TLanguage = existsSync(tsconfigPath) ? 'typescript' : 'javascript';\n const packageManager = detectPackageManager(cwd);\n return {\n type: 'node',\n name: pkgJson?.name,\n packageManager,\n language,\n };\n }\n\n // Python project\n if (existsSync(pyprojectPath) || existsSync(join(cwd, 'setup.py'))) {\n return {\n type: 'python',\n language: 'python',\n };\n }\n\n // Rust project\n if (existsSync(cargoPath)) {\n return {\n type: 'rust',\n language: 'rust',\n };\n }\n\n // Go project\n if (existsSync(goModPath)) {\n return {\n type: 'go',\n language: 'go',\n };\n }\n\n return {\n type: 'unknown',\n language: 'unknown',\n };\n}\n","/**\n * Session restore helpers for InteractiveSession.\n *\n * Handles message injection into an existing session and loading a persisted\n * session record back into the tracker state on resume/fork.\n */\n\nimport type { IInteractiveSessionStore } from './session-persistence.js';\nimport type {\n IBackgroundJobGroupState,\n IBackgroundTaskState,\n TBackgroundJobGroupEvent,\n TBackgroundTaskEvent,\n TBackgroundTaskStatus,\n} from '../background-tasks/index.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type { IContextReferenceItem } from '../context/context-reference-inventory.js';\nimport type { IMemoryEvent, IMemoryReference } from '../memory/automatic-memory-types.js';\nimport type { TUniversalMessage, IHistoryEntry } from '@robota-sdk/agent-core';\nimport type { Session } from '@robota-sdk/agent-session';\n\n/** Inject a saved message into a session, supporting all roles including 'tool'. */\nexport function injectSavedMessage(session: Session, msg: TUniversalMessage): void {\n if (typeof msg.content !== 'string') return;\n if (msg.role === 'tool') {\n session.injectMessage('tool', msg.content, {\n toolCallId: msg.toolCallId,\n ...(msg.name !== undefined ? { name: msg.name } : {}),\n });\n } else {\n session.injectMessage(msg.role, msg.content);\n }\n}\n\n/**\n * Restore session history and messages from a persisted session record.\n * Returns the loaded history and any pending messages that need injection once session is ready.\n */\nexport function loadSessionRecord(\n sessionStore: IInteractiveSessionStore,\n resumeSessionId: string,\n forkSession: boolean,\n existingSession: Session | null,\n): {\n history: IHistoryEntry[];\n sessionName: string | undefined;\n pendingRestoreMessages: TUniversalMessage[] | null;\n backgroundTasks: IBackgroundTaskState[];\n backgroundTaskEvents: TBackgroundTaskEvent[];\n backgroundJobGroups: IBackgroundJobGroupState[];\n backgroundJobGroupEvents: TBackgroundJobGroupEvent[];\n skillActivationEvents: ISkillActivationEvent[];\n memoryEvents: IMemoryEvent[];\n usedMemoryReferences: IMemoryReference[];\n contextReferences: IContextReferenceItem[];\n sandboxSnapshotId: string | undefined;\n} {\n const record = sessionStore.load(resumeSessionId);\n if (!record) {\n return {\n history: [],\n sessionName: undefined,\n pendingRestoreMessages: null,\n backgroundTasks: [],\n backgroundTaskEvents: [],\n backgroundJobGroups: [],\n backgroundJobGroupEvents: [],\n skillActivationEvents: [],\n memoryEvents: [],\n usedMemoryReferences: [],\n contextReferences: [],\n sandboxSnapshotId: undefined,\n };\n }\n\n const history = record.history ?? [];\n const restoredBackgroundTasks = record.backgroundTasks ?? [];\n const restoredBackgroundTaskEvents = record.backgroundTaskEvents ?? [];\n const backgroundJobGroups = record.backgroundJobGroups ?? [];\n const backgroundJobGroupEvents = record.backgroundJobGroupEvents ?? [];\n const skillActivationEvents = record.skillActivationEvents ?? [];\n const memoryEvents = record.memoryEvents ?? [];\n const usedMemoryReferences = record.usedMemoryReferences ?? [];\n const contextReferences = record.contextReferences ?? [];\n const sandboxSnapshotId = record.sandboxSnapshotId;\n const { backgroundTasks, backgroundTaskEvents } = reconcileRestoredBackgroundTasks(\n restoredBackgroundTasks,\n restoredBackgroundTaskEvents,\n );\n const sessionName = record.name;\n let pendingRestoreMessages: TUniversalMessage[] | null = null;\n\n if (!forkSession && record.messages) {\n if (existingSession) {\n for (const msg of record.messages) {\n injectSavedMessage(existingSession, msg);\n }\n } else {\n pendingRestoreMessages = record.messages;\n }\n }\n\n return {\n history,\n sessionName,\n pendingRestoreMessages,\n backgroundTasks,\n backgroundTaskEvents,\n backgroundJobGroups,\n backgroundJobGroupEvents,\n skillActivationEvents,\n memoryEvents,\n usedMemoryReferences,\n contextReferences,\n sandboxSnapshotId,\n };\n}\n\nfunction reconcileRestoredBackgroundTasks(\n tasks: IBackgroundTaskState[],\n events: TBackgroundTaskEvent[],\n): { backgroundTasks: IBackgroundTaskState[]; backgroundTaskEvents: TBackgroundTaskEvent[] } {\n const now = new Date().toISOString();\n const syntheticEvents: TBackgroundTaskEvent[] = [];\n const backgroundTasks = tasks.map((task) => {\n if (isRestoredTerminalStatus(task.status)) return task;\n const reconciled: IBackgroundTaskState = {\n ...task,\n status: 'failed',\n timeoutReason: 'stale_worker',\n error: {\n category: 'timeout',\n message: 'Restored background task is stale; worker cannot be reattached',\n recoverable: true,\n },\n unread: true,\n completedAt: now,\n updatedAt: now,\n };\n syntheticEvents.push({ type: 'background_task_failed', task: reconciled });\n return reconciled;\n });\n return {\n backgroundTasks,\n backgroundTaskEvents: [...events, ...syntheticEvents],\n };\n}\n\nfunction isRestoredTerminalStatus(status: TBackgroundTaskStatus): boolean {\n return status === 'completed' || status === 'failed' || status === 'cancelled';\n}\n","import { runHooks } from '@robota-sdk/agent-core';\n\nimport type { TBackgroundTaskEvent } from '../background-tasks/index.js';\nimport type {\n IHookInput,\n IHookTypeExecutor,\n THooksConfig,\n THookEvent,\n} from '@robota-sdk/agent-core';\n\nfunction getSubagentHookEvent(event: TBackgroundTaskEvent): THookEvent | undefined {\n if (event.type === 'background_task_started' && event.task.kind === 'agent') {\n return 'SubagentStart';\n }\n if (\n (event.type === 'background_task_completed' ||\n event.type === 'background_task_failed' ||\n event.type === 'background_task_cancelled') &&\n event.task.kind === 'agent'\n ) {\n return 'SubagentStop';\n }\n return undefined;\n}\n\nexport function fireSubagentLifecycleHook(\n event: TBackgroundTaskEvent,\n cwd: string,\n hooks: THooksConfig | undefined,\n hookTypeExecutors: IHookTypeExecutor[] | undefined,\n): void {\n const hookEventName = getSubagentHookEvent(event);\n if (!hookEventName || !('task' in event)) return;\n\n const input: IHookInput = {\n session_id: event.task.parentSessionId,\n cwd,\n hook_event_name: hookEventName,\n agent_id: event.task.id,\n agent_type: event.task.agentType ?? event.task.label,\n ...(event.task.transcriptPath\n ? {\n agent_transcript_path: event.task.transcriptPath,\n transcript_path: event.task.transcriptPath,\n }\n : {}),\n ...(event.task.error?.message || event.task.timeoutReason\n ? { reason: event.task.error?.message ?? event.task.timeoutReason }\n : {}),\n ...(hookEventName === 'SubagentStop'\n ? {\n stop_hook_active: false,\n ...(event.task.result?.output\n ? { last_assistant_message: event.task.result.output }\n : {}),\n }\n : {}),\n env: {\n CLAUDE_PROJECT_DIR: cwd,\n CLAUDE_SESSION_ID: event.task.parentSessionId,\n ROBOTA_AGENT_ID: event.task.id,\n ROBOTA_AGENT_TYPE: event.task.agentType ?? event.task.label,\n },\n };\n\n void runHooks(hooks, hookEventName, input, hookTypeExecutors).catch(() => undefined);\n}\n","/**\n * Default tool set factory — creates the standard set of CLI tools.\n */\n\nimport {\n createBashTool,\n createReadTool,\n createWriteTool,\n createEditTool,\n globTool,\n grepTool,\n webFetchTool,\n webSearchTool,\n} from '@robota-sdk/agent-tools';\n\nimport type { IToolWithEventService } from '@robota-sdk/agent-core';\nimport type { ISandboxClient } from '@robota-sdk/agent-tools';\n\n/** Human-readable descriptions of the built-in tools (for system prompt) */\nexport const DEFAULT_TOOL_DESCRIPTIONS = [\n 'Bash — execute shell commands',\n 'Read — read file contents with line numbers',\n 'Write — write content to a file',\n 'Edit — replace a string in a file',\n 'Glob — find files matching a pattern',\n 'Grep — search file contents with regex',\n 'WebFetch — fetch URL content as text',\n 'WebSearch — search the internet through the configured local tool',\n];\n\n/**\n * Create the default set of CLI tools.\n * Returns the 8 standard tools as IToolWithEventService[].\n */\nexport interface ICreateDefaultToolsOptions {\n sandboxClient?: ISandboxClient;\n}\n\nexport function createDefaultTools(\n options: ICreateDefaultToolsOptions = {},\n): IToolWithEventService[] {\n return [\n createBashTool(options) as IToolWithEventService,\n createReadTool(options) as IToolWithEventService,\n createWriteTool(options) as IToolWithEventService,\n createEditTool(options) as IToolWithEventService,\n globTool as IToolWithEventService,\n grepTool as IToolWithEventService,\n webFetchTool as IToolWithEventService,\n webSearchTool as IToolWithEventService,\n ];\n}\n","import { homedir } from 'node:os';\nimport { join, basename } from 'node:path';\n\nimport { BUILT_IN_AGENTS } from './built-in-agents.js';\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { IAgentDefinition } from './agent-definition-types.js';\nimport type { IFileSystem, IDirent } from '@robota-sdk/agent-core';\n\n/** Known frontmatter keys that should be parsed as comma-separated or whitespace-separated lists. */\nconst LIST_KEYS = new Set(['tools', 'disallowedTools']);\n\n/** Known frontmatter keys that should be parsed as numbers. */\nconst NUMBER_KEYS = new Set(['maxTurns']);\n\ninterface IRawFrontmatter {\n name?: string;\n description?: string;\n model?: string;\n maxTurns?: number;\n tools?: string[];\n disallowedTools?: string[];\n}\n\nfunction parseListValue(rawValue: string): string[] {\n const separator = rawValue.includes(',') ? /\\s*,\\s*/ : /\\s+/;\n return rawValue\n .split(separator)\n .map((value) => value.trim())\n .filter((value) => value.length > 0);\n}\n\n/**\n * Parse simple YAML-like frontmatter between `---` markers.\n * Returns null when no frontmatter block is found.\n */\nfunction parseFrontmatter(content: string): { frontmatter: IRawFrontmatter | null; body: string } {\n const lines = content.split('\\n');\n if (lines[0]?.trim() !== '---') {\n return { frontmatter: null, body: content };\n }\n\n let endIndex = -1;\n for (let i = 1; i < lines.length; i++) {\n if (lines[i]?.trim() === '---') {\n endIndex = i;\n break;\n }\n }\n\n if (endIndex === -1) {\n return { frontmatter: null, body: content };\n }\n\n const result: Record<string, unknown> = {};\n\n for (let i = 1; i < endIndex; i++) {\n const line = lines[i]!;\n const match = line.match(/^([a-zA-Z][a-zA-Z0-9]*(?:[A-Z][a-z]*)*):\\s*(.+)/);\n if (!match) continue;\n\n const key = match[1]!;\n const rawValue = match[2]!.trim();\n\n if (LIST_KEYS.has(key)) {\n result[key] = parseListValue(rawValue);\n } else if (NUMBER_KEYS.has(key)) {\n result[key] = parseInt(rawValue, 10);\n } else {\n result[key] = rawValue;\n }\n }\n\n const body = lines\n .slice(endIndex + 1)\n .join('\\n')\n .trim();\n\n return {\n frontmatter: Object.keys(result).length > 0 ? (result as IRawFrontmatter) : null,\n body,\n };\n}\n\n/** Scan a directory for .md files and return parsed agent definitions. */\nfunction scanAgentsDir(dir: string, fs: IFileSystem): IAgentDefinition[] {\n if (!fs.existsSync(dir)) return [];\n\n const agents: IAgentDefinition[] = [];\n let entries: IDirent[];\n\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n // allow-fallback: unreadable agents directory returns empty list\n return [];\n }\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md')) continue;\n\n const filePath = join(dir, entry.name);\n const content = fs.readFileSync(filePath, 'utf-8');\n const { frontmatter, body } = parseFrontmatter(content);\n const fallbackName = basename(entry.name, '.md');\n\n const agent: IAgentDefinition = {\n name: frontmatter?.name ?? fallbackName,\n description: frontmatter?.description ?? '',\n systemPrompt: body,\n };\n\n if (frontmatter?.model !== undefined) agent.model = frontmatter.model;\n if (frontmatter?.maxTurns !== undefined) agent.maxTurns = frontmatter.maxTurns;\n if (frontmatter?.tools !== undefined) agent.tools = frontmatter.tools;\n if (frontmatter?.disallowedTools !== undefined)\n agent.disallowedTools = frontmatter.disallowedTools;\n\n agents.push(agent);\n }\n\n return agents;\n}\n\n/**\n * Loads agent definitions from project and user directories, merging\n * them with built-in agents.\n *\n * Scan directories (highest priority first):\n * 1. `<cwd>/.robota/agents/` — project-level Robota native\n * 2. `<cwd>/.agents/agents/` — project-level Robota repository convention\n * 3. `<cwd>/.claude/agents/` — project-level Claude Code compatible\n * 4. `<home>/.robota/agents/` — user-level Robota native\n * 5. `<home>/.claude/agents/` — user-level Claude Code compatible\n *\n * Custom agents override built-in agents on name collision.\n */\nexport class AgentDefinitionLoader {\n private readonly cwd: string;\n private readonly home: string;\n private readonly fs: IFileSystem;\n\n constructor(cwd: string, home?: string, fs: IFileSystem = new NodeFileSystem()) {\n this.cwd = cwd;\n this.home = home ?? homedir();\n this.fs = fs;\n }\n\n /** Load all agent definitions, merged with built-in agents. Custom overrides built-in on name collision. */\n loadAll(): IAgentDefinition[] {\n const sources: IAgentDefinition[][] = [\n scanAgentsDir(join(this.cwd, '.robota', 'agents'), this.fs),\n scanAgentsDir(join(this.cwd, '.agents', 'agents'), this.fs),\n scanAgentsDir(join(this.cwd, '.claude', 'agents'), this.fs),\n scanAgentsDir(join(this.home, '.robota', 'agents'), this.fs),\n scanAgentsDir(join(this.home, '.claude', 'agents'), this.fs),\n ];\n\n // Deduplicate custom agents: higher-priority source wins\n const seen = new Set<string>();\n const customAgents: IAgentDefinition[] = [];\n\n for (const agents of sources) {\n for (const agent of agents) {\n if (!seen.has(agent.name)) {\n seen.add(agent.name);\n customAgents.push(agent);\n }\n }\n }\n\n // Merge with built-in: custom overrides built-in on name collision\n const result = [...customAgents];\n for (const builtIn of BUILT_IN_AGENTS) {\n if (!seen.has(builtIn.name)) {\n result.push(builtIn);\n }\n }\n\n return result;\n }\n\n /** Get a specific agent by name (custom or built-in). */\n getAgent(name: string): IAgentDefinition | undefined {\n return this.loadAll().find((agent) => agent.name === name);\n }\n}\n","import type { ISystemPromptSection } from './system-prompt-types.js';\n\nfunction renderSection(section: ISystemPromptSection): string {\n const content = section.content.trim();\n if (!section.title) return content;\n return [`## ${section.title}`, content].join('\\n');\n}\n\nexport function composeSystemPrompt(sections: readonly ISystemPromptSection[]): string {\n return [...sections]\n .filter((section) => section.content.trim().length > 0)\n .sort((a, b) => a.priority - b.priority || a.id.localeCompare(b.id))\n .map((section) => renderSection(section))\n .join('\\n\\n');\n}\n","import type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { TTrustLevel } from '../types.js';\nimport type { IProjectInfo } from './project-detector.js';\nimport type { ISystemPromptSection } from './system-prompt-types.js';\n\nconst TRUST_LEVEL_LABELS: Record<TTrustLevel, string> = {\n safe: 'safe',\n moderate: 'moderate',\n full: 'full',\n};\nconst PROJECT_MEMORY_PRIORITY = Number('25');\nconst TASK_CONTEXT_PRIORITY = Number('27');\n\nfunction createSection(\n id: string,\n title: string | undefined,\n priority: number,\n content: string,\n source: ISystemPromptSection['source'],\n): ISystemPromptSection {\n return { id, title, priority, content, source };\n}\n\nexport function createWorkingDirectorySection(cwd?: string): ISystemPromptSection | undefined {\n if (!cwd) return undefined;\n return createSection('runtime-cwd', 'Working Directory', 30, `\\`${cwd}\\``, 'runtime');\n}\n\nexport function createProjectSection(info: IProjectInfo): ISystemPromptSection {\n const lines: string[] = [];\n if (info.name !== undefined) {\n lines.push(`- **Name:** ${info.name}`);\n }\n if (info.type !== 'unknown') {\n lines.push(`- **Type:** ${info.type}`);\n }\n if (info.language !== 'unknown') {\n lines.push(`- **Language:** ${info.language}`);\n }\n if (info.packageManager !== undefined) {\n lines.push(`- **Package manager:** ${info.packageManager}`);\n }\n return createSection('runtime-project', 'Current Project', 40, lines.join('\\n'), 'runtime');\n}\n\nexport function createPermissionSection(trustLevel: TTrustLevel): ISystemPromptSection {\n return createSection(\n 'permission-mode',\n 'Permission Mode',\n 50,\n `- **Trust level:** ${TRUST_LEVEL_LABELS[trustLevel]}`,\n 'permissions',\n );\n}\n\nexport function createResponseLanguageSection(language?: string): ISystemPromptSection | undefined {\n if (language === undefined || language.trim().length === 0) return undefined;\n return createSection('runtime-response-language', 'Response Language', 45, language, 'runtime');\n}\n\nexport function createAgentsMdSection(agentsMd: string): ISystemPromptSection | undefined {\n if (agentsMd.trim().length === 0) return undefined;\n return createSection(\n 'project-agents-md',\n 'Agent Instructions',\n 10,\n agentsMd,\n 'project-instructions',\n );\n}\n\nexport function createClaudeMdSection(claudeMd: string): ISystemPromptSection | undefined {\n if (claudeMd.trim().length === 0) return undefined;\n return createSection('project-claude-md', 'Project Notes', 20, claudeMd, 'project-instructions');\n}\n\nexport function createProjectMemorySection(memoryMd?: string): ISystemPromptSection | undefined {\n if (memoryMd === undefined || memoryMd.trim().length === 0) return undefined;\n return createSection(\n 'project-memory',\n 'Project Memory',\n PROJECT_MEMORY_PRIORITY,\n memoryMd,\n 'project-instructions',\n );\n}\n\nexport function createTaskContextSection(taskContext?: string): ISystemPromptSection | undefined {\n if (taskContext === undefined || taskContext.trim().length === 0) return undefined;\n return createSection(\n 'active-task-context',\n 'Active Task Context',\n TASK_CONTEXT_PRIORITY,\n taskContext,\n 'project-instructions',\n );\n}\n\nexport function createToolDescriptionSection(\n descriptions: readonly string[],\n): ISystemPromptSection | undefined {\n if (descriptions.length === 0) return undefined;\n return createSection(\n 'tool-descriptions',\n 'Available Tools',\n 60,\n descriptions.map((description) => `- ${description}`).join('\\n'),\n 'tool',\n );\n}\n\nfunction formatCapability(descriptor: ICapabilityDescriptor): string {\n const arg = descriptor.argumentHint ? ` ${descriptor.argumentHint}` : '';\n return `- ${descriptor.name}${arg}: ${descriptor.description}`;\n}\n\nfunction createCapabilityKindSection(\n kind: ICapabilityDescriptor['kind'],\n title: string,\n priority: number,\n source: ISystemPromptSection['source'],\n descriptors: readonly ICapabilityDescriptor[],\n): ISystemPromptSection | undefined {\n const formattedDescriptors = descriptors\n .filter((descriptor) => descriptor.modelInvocable && descriptor.kind === kind)\n .map(formatCapability);\n if (formattedDescriptors.length === 0) return undefined;\n return createSection(\n `capability-${kind}`,\n title,\n priority,\n formattedDescriptors.join('\\n'),\n source,\n );\n}\n\nexport function createCapabilitySections(\n descriptors: readonly ICapabilityDescriptor[],\n): ISystemPromptSection[] {\n const sections: ISystemPromptSection[] = [];\n const commandSection = createCapabilityKindSection(\n 'builtin-command',\n 'Built-in Commands',\n 70,\n 'command',\n descriptors,\n );\n const skillSection = createCapabilityKindSection('skill', 'Skills', 80, 'skill', descriptors);\n const agentSection = createCapabilityKindSection('agent', 'Agents', 90, 'agent', descriptors);\n const toolSection = createCapabilityKindSection('tool', 'Tools', 100, 'tool', descriptors);\n\n if (commandSection) sections.push(commandSection);\n if (skillSection) sections.push(skillSection);\n if (agentSection) sections.push(agentSection);\n if (toolSection) sections.push(toolSection);\n return sections;\n}\n\nexport function createCapabilitySection(\n descriptors: readonly ICapabilityDescriptor[],\n): ISystemPromptSection {\n return createSection(\n 'capability-descriptors',\n 'Capabilities',\n 70,\n descriptors\n .filter((descriptor) => descriptor.modelInvocable)\n .map(formatCapability)\n .join('\\n'),\n 'command',\n );\n}\n","import { composeSystemPrompt } from './system-prompt-composer.js';\nimport {\n createAgentsMdSection,\n createCapabilitySections,\n createClaudeMdSection,\n createPermissionSection,\n createProjectMemorySection,\n createProjectSection,\n createResponseLanguageSection,\n createTaskContextSection,\n createToolDescriptionSection,\n createWorkingDirectorySection,\n} from './system-prompt-section-providers.js';\n\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { TTrustLevel } from '../types.js';\nimport type { IProjectInfo } from './project-detector.js';\nimport type { ISystemPromptSection } from './system-prompt-types.js';\n\nexport interface ISystemPromptParams {\n /** Concatenated AGENTS.md content (may be empty string) */\n agentsMd: string;\n /** Concatenated CLAUDE.md content (may be empty string) */\n claudeMd: string;\n /** Startup project memory index loaded from .robota/memory/MEMORY.md */\n memoryMd?: string;\n /** Formatted active task context loaded from .agents/tasks/*.md */\n taskContext?: string;\n /** Human-readable tool descriptions, one per entry */\n toolDescriptions: string[];\n /** Active trust level governing permission checks */\n trustLevel: TTrustLevel;\n /** Detected project metadata */\n projectInfo: IProjectInfo;\n /** Current working directory */\n cwd?: string;\n /** Response language code (e.g., \"ko\", \"en\"). If set, AI must respond in this language. */\n language?: string;\n /** Discovered skills to expose in the system prompt */\n skills?: Array<{ name: string; description: string; disableModelInvocation?: boolean }>;\n /** Discovered agents to expose in the system prompt */\n agents?: Array<{ name: string; description: string }>;\n /** Command descriptors to expose to the model */\n commandDescriptors?: ICapabilityDescriptor[];\n}\n\nfunction appendOptionalSection(\n sections: ISystemPromptSection[],\n section: ISystemPromptSection | undefined,\n): void {\n if (section !== undefined) sections.push(section);\n}\n\nfunction mapSkillDescriptors(\n skills: NonNullable<ISystemPromptParams['skills']>,\n): ICapabilityDescriptor[] {\n return skills.map((skill) => ({\n name: skill.name,\n kind: 'skill',\n description: skill.description,\n userInvocable: true,\n modelInvocable: skill.disableModelInvocation !== true,\n }));\n}\n\nfunction mapAgentDescriptors(\n agents: NonNullable<ISystemPromptParams['agents']>,\n): ICapabilityDescriptor[] {\n return agents.map((agent) => ({\n name: agent.name,\n kind: 'agent',\n description: agent.description,\n userInvocable: false,\n modelInvocable: true,\n safety: 'background-agent',\n }));\n}\n\nfunction buildCapabilityDescriptors(params: ISystemPromptParams): ICapabilityDescriptor[] {\n return [\n ...(params.commandDescriptors ?? []),\n ...(params.skills ? mapSkillDescriptors(params.skills) : []),\n ...(params.agents ? mapAgentDescriptors(params.agents) : []),\n ];\n}\n\nexport function buildSystemPrompt(params: ISystemPromptParams): string {\n const sections: ISystemPromptSection[] = [];\n\n appendOptionalSection(sections, createAgentsMdSection(params.agentsMd));\n appendOptionalSection(sections, createClaudeMdSection(params.claudeMd));\n appendOptionalSection(sections, createProjectMemorySection(params.memoryMd));\n appendOptionalSection(sections, createTaskContextSection(params.taskContext));\n appendOptionalSection(sections, createWorkingDirectorySection(params.cwd));\n sections.push(createProjectSection(params.projectInfo));\n appendOptionalSection(sections, createResponseLanguageSection(params.language));\n sections.push(createPermissionSection(params.trustLevel));\n appendOptionalSection(sections, createToolDescriptionSection(params.toolDescriptions));\n sections.push(...createCapabilitySections(buildCapabilityDescriptors(params)));\n\n return composeSystemPrompt(sections);\n}\n","import { createZodFunctionTool } from '@robota-sdk/agent-tools';\nimport { z } from 'zod';\n\nimport type { IBackgroundTaskManager, TBackgroundPrimitive } from '../background-tasks/index.js';\nimport type { IZodSchema } from '@robota-sdk/agent-tools';\n\nconst DEFAULT_PROCESS_TIMEOUT_MS = 120_000;\n\nfunction asZodSchema(schema: z.ZodType): IZodSchema {\n return schema as IZodSchema;\n}\n\nconst BackgroundProcessSchema = z.object({\n command: z.string().describe('The shell command to start in the background'),\n timeout: z.number().optional().describe('Optional timeout in milliseconds. Default is 120000.'),\n workingDirectory: z\n .string()\n .optional()\n .describe('Working directory for the command. Defaults to the current project directory.'),\n stdin: z.string().optional().describe('Optional stdin to write after the process starts.'),\n outputLimitBytes: z\n .number()\n .optional()\n .describe('Maximum captured output bytes kept in the task result.'),\n});\n\ntype TBackgroundProcessArgs = z.infer<typeof BackgroundProcessSchema>;\n\nexport interface IBackgroundProcessToolDeps {\n backgroundTaskManager: IBackgroundTaskManager;\n cwd?: string;\n parentSessionId?: string;\n metadata?: Record<string, TBackgroundPrimitive>;\n}\n\nfunction stringifyStarted(taskId: string, status: string, command: string): string {\n return JSON.stringify({\n success: true,\n background: true,\n output: '',\n taskId,\n status,\n command,\n });\n}\n\nfunction stringifyProcessError(message: string): string {\n return JSON.stringify({\n success: false,\n background: true,\n output: '',\n error: `Background process error: ${message}`,\n });\n}\n\nasync function startBackgroundProcess(\n args: TBackgroundProcessArgs,\n deps: IBackgroundProcessToolDeps,\n): Promise<string> {\n try {\n const state = await deps.backgroundTaskManager.spawn({\n kind: 'process',\n label: args.command,\n mode: 'background',\n parentSessionId: deps.parentSessionId ?? 'unknown-session',\n depth: 0,\n cwd: args.workingDirectory ?? deps.cwd ?? process.cwd(),\n command: args.command,\n stdin: args.stdin,\n timeoutMs: args.timeout ?? DEFAULT_PROCESS_TIMEOUT_MS,\n outputLimitBytes: args.outputLimitBytes,\n metadata: deps.metadata,\n });\n return stringifyStarted(state.id, state.status, args.command);\n } catch (error) {\n return stringifyProcessError(error instanceof Error ? error.message : String(error));\n }\n}\n\nexport function createBackgroundProcessTool(\n deps: IBackgroundProcessToolDeps,\n): ReturnType<typeof createZodFunctionTool> {\n return createZodFunctionTool(\n 'BackgroundProcess',\n 'Start a shell command as a managed background task. Use this for long-running commands that should not block the current conversation. Use /background list, /background read <taskId>, /background cancel <taskId>, or /background close <taskId> to inspect or control it.',\n asZodSchema(BackgroundProcessSchema),\n async (params) => startBackgroundProcess(params as TBackgroundProcessArgs, deps),\n );\n}\n","import { SubagentManager, BackgroundTaskManager } from '@robota-sdk/agent-executor';\n\nimport { fireSubagentLifecycleHook } from './background-task-hooks.js';\nimport { DEFAULT_TOOL_DESCRIPTIONS } from './create-tools.js';\nimport { AgentDefinitionLoader } from '../agents/agent-definition-loader.js';\nimport { createExecutionOriginMetadata } from '../background-tasks/index.js';\nimport { storeSessionBackgroundTaskManager } from '../background-tasks/session-background-store.js';\nimport { buildSystemPrompt } from '../context/system-prompt-builder.js';\nimport { createInProcessSubagentRunner } from '../subagents/in-process-subagent-runner.js';\nimport { storeAgentToolDeps } from '../tools/agent-tool.js';\nimport { createBackgroundProcessTool } from '../tools/background-process-tool.js';\nimport { formatProjectedModelCommandToolPromptDescription } from '../tools/model-command-tool-projection.js';\n\nimport type { ICreateSessionOptions } from './create-session-types.js';\nimport type { IAgentDefinition } from '../agents/agent-definition-types.js';\nimport type { IBackgroundTaskManager, TBackgroundTaskEvent } from '../background-tasks/index.js';\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { ISystemPromptParams } from '../context/system-prompt-builder.js';\nimport type { IAgentToolDeps } from '../tools/agent-tool.js';\nimport type { IBackgroundProcessToolDeps } from '../tools/background-process-tool.js';\nimport type { createModelCommandToolProjection } from '../tools/model-command-tool-projection.js';\nimport type { IAIProvider, IToolWithEventService, IHookTypeExecutor } from '@robota-sdk/agent-core';\nimport type { ISessionLogger } from '@robota-sdk/agent-session';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport interface IAgentRuntimeResult {\n agentToolDeps: IAgentToolDeps | undefined;\n agentDefinitions: IAgentDefinition[];\n backgroundTaskManager: IBackgroundTaskManager;\n}\n\nexport function buildAgentRuntime(\n options: ICreateSessionOptions,\n sessionId: string,\n cwd: string,\n provider: IAIProvider,\n tools: IToolWithEventService[],\n hookTypeExecutors: IHookTypeExecutor[],\n): IAgentRuntimeResult {\n let agentToolDeps: IAgentToolDeps | undefined;\n let agentDefinitions: IAgentDefinition[] = [];\n let backgroundTaskManager: IBackgroundTaskManager;\n\n if (options.enableAgentRuntime) {\n const agentLoader = new AgentDefinitionLoader(cwd);\n agentDefinitions = agentLoader.loadAll();\n agentToolDeps = {\n config: options.config,\n context: options.context,\n tools,\n terminal: options.terminal,\n provider,\n cwd,\n parentSessionId: sessionId,\n permissionMode: options.permissionMode,\n permissionHandler: options.permissionHandler,\n hooks: options.config.hooks,\n hookTypeExecutors: hookTypeExecutors.length > 0 ? hookTypeExecutors : undefined,\n onTextDelta: options.onTextDelta,\n onToolExecution: options.onToolExecution,\n customAgentRegistry: (name: string) => agentLoader.getAgent(name),\n agentDefinitions,\n };\n const subagentManager = new SubagentManager({\n runner: (options.subagentRunnerFactory ?? createInProcessSubagentRunner)(agentToolDeps),\n backgroundTaskRunners: options.backgroundTaskRunners,\n });\n agentToolDeps.subagentManager = subagentManager;\n backgroundTaskManager = subagentManager.getBackgroundTaskManager();\n agentToolDeps.backgroundTaskManager = backgroundTaskManager;\n } else {\n backgroundTaskManager = new BackgroundTaskManager({\n runners: options.backgroundTaskRunners ?? [],\n });\n }\n\n const sessionLogger = options.sessionLogger;\n if (sessionLogger) {\n backgroundTaskManager.subscribe((event) =>\n logBackgroundTaskEvent(sessionLogger, sessionId, event),\n );\n }\n backgroundTaskManager.subscribe((event) =>\n fireSubagentLifecycleHook(\n event,\n cwd,\n options.config.hooks,\n hookTypeExecutors.length > 0 ? hookTypeExecutors : undefined,\n ),\n );\n\n return { agentToolDeps, agentDefinitions, backgroundTaskManager };\n}\n\nexport interface IBackgroundProcessResult {\n backgroundProcessToolDeps: IBackgroundProcessToolDeps | undefined;\n}\n\nexport function buildBackgroundProcessTool(\n options: ICreateSessionOptions,\n backgroundTaskManager: IBackgroundTaskManager,\n sessionId: string,\n cwd: string,\n tools: IToolWithEventService[],\n): IBackgroundProcessResult {\n const hasProcessRunner = options.backgroundTaskRunners?.some((r) => r.kind === 'process');\n if (!hasProcessRunner) return { backgroundProcessToolDeps: undefined };\n const backgroundProcessToolDeps: IBackgroundProcessToolDeps = {\n backgroundTaskManager,\n cwd,\n parentSessionId: sessionId,\n metadata: createExecutionOriginMetadata({\n kind: 'tool_call',\n sessionId,\n label: 'BackgroundProcess',\n }),\n };\n tools.push(createBackgroundProcessTool(backgroundProcessToolDeps));\n return { backgroundProcessToolDeps };\n}\n\nexport interface ISystemPromptResult {\n finalSystemMessage: string;\n rebuildSystemMessage: (agentsMd: string, claudeMd: string) => string;\n}\n\nexport function buildSessionSystemPrompt(\n options: ICreateSessionOptions,\n cwd: string,\n modelInvocableCommandDescriptors: ICapabilityDescriptor[],\n modelCommandToolProjection: ReturnType<typeof createModelCommandToolProjection> | undefined,\n backgroundProcessToolDeps: IBackgroundProcessToolDeps | undefined,\n modelVisibleSkills: Array<{\n name: string;\n description: string;\n disableModelInvocation?: boolean;\n }>,\n agentDefinitions: IAgentDefinition[],\n): ISystemPromptResult {\n const buildPrompt = options.systemPromptBuilder ?? buildSystemPrompt;\n const defaultToolDescriptions = [\n ...DEFAULT_TOOL_DESCRIPTIONS,\n ...(modelCommandToolProjection\n ? modelCommandToolProjection.commandTools.map(\n formatProjectedModelCommandToolPromptDescription,\n )\n : []),\n ];\n const resolvedToolDescriptions =\n options.toolDescriptions ??\n (backgroundProcessToolDeps\n ? [\n ...defaultToolDescriptions,\n 'BackgroundProcess — start long-running shell commands as managed background tasks',\n ]\n : defaultToolDescriptions);\n\n const staticPromptParams: ISystemPromptParams = {\n agentsMd: options.context.agentsMd,\n claudeMd: options.context.claudeMd,\n memoryMd: options.context.memoryMd,\n taskContext: options.context.taskContext,\n toolDescriptions: resolvedToolDescriptions,\n trustLevel: options.config.defaultTrustLevel,\n projectInfo: options.projectInfo ?? { type: 'unknown', language: 'unknown' },\n cwd,\n language: options.config.language,\n skills: modelVisibleSkills.map((skill) => ({\n name: skill.name,\n description: skill.description,\n disableModelInvocation: skill.disableModelInvocation,\n })),\n ...(agentDefinitions.length > 0\n ? {\n agents: agentDefinitions.map((agent) => ({\n name: agent.name,\n description: agent.description,\n })),\n }\n : {}),\n commandDescriptors: options.commandDescriptors ?? [],\n };\n const systemMessage = buildPrompt(staticPromptParams);\n const finalSystemMessage = options.appendSystemPrompt\n ? `${systemMessage}\\n\\n${options.appendSystemPrompt}`\n : systemMessage;\n\n const rebuildSystemMessage = (newAgentsMd: string, newClaudeMd: string): string => {\n const rebuilt = buildPrompt({\n ...staticPromptParams,\n agentsMd: newAgentsMd,\n claudeMd: newClaudeMd,\n });\n return options.appendSystemPrompt ? `${rebuilt}\\n\\n${options.appendSystemPrompt}` : rebuilt;\n };\n\n return { finalSystemMessage, rebuildSystemMessage };\n}\n\nexport function wireSessionDeps(\n session: Session,\n agentToolDeps: IAgentToolDeps | undefined,\n backgroundProcessToolDeps: IBackgroundProcessToolDeps | undefined,\n backgroundTaskManager: IBackgroundTaskManager,\n): void {\n if (agentToolDeps) agentToolDeps.parentSessionId = session.getSessionId();\n if (backgroundProcessToolDeps) backgroundProcessToolDeps.parentSessionId = session.getSessionId();\n storeSessionBackgroundTaskManager(session, backgroundTaskManager);\n if (agentToolDeps) storeAgentToolDeps(session, agentToolDeps);\n}\n\nfunction logBackgroundTaskEvent(\n logger: ISessionLogger,\n sessionId: string,\n event: TBackgroundTaskEvent,\n): void {\n logger.log(sessionId, 'background_task_event', {\n backgroundEventType: event.type,\n backgroundEvent: event,\n });\n}\n","import type { IEditCheckpointRecorder } from './edit-checkpoint-types.js';\nimport type {\n IEventService,\n IParameterValidationResult,\n IToolExecutionContext,\n IToolResult,\n IToolSchema,\n IToolWithEventService,\n TToolParameters,\n} from '@robota-sdk/agent-core';\n\nconst CHECKPOINTED_TOOL_NAMES = new Set(['Write', 'Edit']);\n\nexport function wrapEditCheckpointTools(\n tools: readonly IToolWithEventService[],\n recorder: IEditCheckpointRecorder,\n): IToolWithEventService[] {\n return tools.map((tool) =>\n CHECKPOINTED_TOOL_NAMES.has(tool.getName())\n ? new EditCheckpointToolWrapper(tool, recorder)\n : tool,\n );\n}\n\nclass EditCheckpointToolWrapper implements IToolWithEventService {\n readonly schema: IToolSchema;\n\n constructor(\n private readonly delegate: IToolWithEventService,\n private readonly recorder: IEditCheckpointRecorder,\n ) {\n this.schema = delegate.schema;\n }\n\n setEventService(eventService: IEventService | undefined): void {\n this.delegate.setEventService(eventService);\n }\n\n async execute(parameters: TToolParameters, context: IToolExecutionContext): Promise<IToolResult> {\n const filePath = extractFilePath(parameters);\n if (filePath) {\n await this.recorder.captureFile(filePath);\n }\n return this.delegate.execute(parameters, context);\n }\n\n validate(parameters: TToolParameters): boolean {\n return this.delegate.validate(parameters);\n }\n\n validateParameters(parameters: TToolParameters): IParameterValidationResult {\n return this.delegate.validateParameters(parameters);\n }\n\n getDescription(): string {\n return this.delegate.getDescription();\n }\n\n getName(): string {\n return this.delegate.getName();\n }\n}\n\nfunction extractFilePath(parameters: TToolParameters): string | undefined {\n if (!parameters || typeof parameters !== 'object') return undefined;\n const value = parameters.filePath;\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n","import { homedir } from 'node:os';\nimport { join, basename } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { ICommandSource, ICommand } from '../command-api/types.js';\nimport type { IFileSystem, IDirent } from '@robota-sdk/agent-core';\n\ninterface IFrontmatter {\n name?: string;\n description?: string;\n argumentHint?: string;\n disableModelInvocation?: boolean;\n userInvocable?: boolean;\n allowedTools?: string[];\n model?: string;\n effort?: string;\n context?: string;\n agent?: string;\n}\n\n/** Known boolean frontmatter keys */\nconst BOOLEAN_KEYS = new Set(['disable-model-invocation', 'user-invocable']);\n\n/** Known comma-separated or whitespace-separated list frontmatter keys */\nconst LIST_KEYS = new Set(['allowed-tools']);\n\n/** Convert kebab-case to camelCase */\nfunction kebabToCamel(key: string): string {\n return key.replace(/-([a-z])/g, (_match, letter: string) => letter.toUpperCase());\n}\n\nfunction parseListValue(rawValue: string): string[] {\n const separator = rawValue.includes(',') ? /\\s*,\\s*/ : /\\s+/;\n return rawValue\n .split(separator)\n .map((value) => value.trim())\n .filter((value) => value.length > 0);\n}\n\n/** Parse YAML-like frontmatter between --- markers */\nexport function parseFrontmatter(content: string): IFrontmatter | null {\n const lines = content.split('\\n');\n if (lines[0]?.trim() !== '---') return null;\n\n const result: Record<string, unknown> = {};\n\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i]!;\n if (line.trim() === '---') break;\n\n const match = line.match(/^([a-z][a-z0-9-]*):\\s*(.+)/);\n if (!match) continue;\n\n const key = match[1]!;\n const rawValue = match[2]!.trim();\n const camelKey = kebabToCamel(key);\n\n if (BOOLEAN_KEYS.has(key)) {\n result[camelKey] = rawValue === 'true';\n } else if (LIST_KEYS.has(key)) {\n result[camelKey] = parseListValue(rawValue);\n } else {\n result[camelKey] = rawValue;\n }\n }\n\n return Object.keys(result).length > 0 ? (result as IFrontmatter) : null;\n}\n\n/** Build a command from frontmatter, content, and a fallback name */\nfunction buildCommand(\n frontmatter: IFrontmatter | null,\n content: string,\n fallbackName: string,\n): ICommand {\n const cmd: ICommand = {\n name: frontmatter?.name ?? fallbackName,\n description: frontmatter?.description ?? `Skill: ${fallbackName}`,\n source: 'skill',\n skillContent: content,\n };\n\n if (frontmatter?.argumentHint !== undefined) cmd.argumentHint = frontmatter.argumentHint;\n if (frontmatter?.disableModelInvocation !== undefined)\n cmd.disableModelInvocation = frontmatter.disableModelInvocation;\n if (frontmatter?.userInvocable !== undefined) cmd.userInvocable = frontmatter.userInvocable;\n if (frontmatter?.allowedTools !== undefined) cmd.allowedTools = frontmatter.allowedTools;\n if (frontmatter?.model !== undefined) cmd.model = frontmatter.model;\n if (frontmatter?.effort !== undefined) cmd.effort = frontmatter.effort;\n if (frontmatter?.context !== undefined) cmd.context = frontmatter.context;\n if (frontmatter?.agent !== undefined) cmd.agent = frontmatter.agent;\n\n return cmd;\n}\n\n/** Scan a skills directory for subdirectories containing SKILL.md */\nfunction scanSkillsDir(skillsDir: string, fs: IFileSystem): ICommand[] {\n if (!fs.existsSync(skillsDir)) return [];\n\n const commands: ICommand[] = [];\n const entries: IDirent[] = fs.readdirSync(skillsDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const skillFile = join(skillsDir, entry.name, 'SKILL.md');\n if (!fs.existsSync(skillFile)) continue;\n\n const content = fs.readFileSync(skillFile, 'utf-8');\n const frontmatter = parseFrontmatter(content);\n commands.push(buildCommand(frontmatter, content, entry.name));\n }\n\n return commands;\n}\n\n/** Scan a commands directory for .md files (Claude Code legacy format) */\nfunction scanCommandsDir(commandsDir: string, fs: IFileSystem): ICommand[] {\n if (!fs.existsSync(commandsDir)) return [];\n\n const commands: ICommand[] = [];\n const entries: IDirent[] = fs.readdirSync(commandsDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md')) continue;\n const filePath = join(commandsDir, entry.name);\n const content = fs.readFileSync(filePath, 'utf-8');\n const frontmatter = parseFrontmatter(content);\n const fallbackName = basename(entry.name, '.md');\n commands.push(buildCommand(frontmatter, content, fallbackName));\n }\n\n return commands;\n}\n\n/** Command source that discovers skills from multiple directories */\nexport class SkillCommandSource implements ICommandSource {\n readonly name = 'skill';\n private readonly cwd: string;\n private readonly home: string;\n private readonly fs: IFileSystem;\n private cachedCommands: ICommand[] | null = null;\n\n constructor(cwd: string, home?: string, fs: IFileSystem = new NodeFileSystem()) {\n this.cwd = cwd;\n this.home = home ?? homedir();\n this.fs = fs;\n }\n\n getCommands(): ICommand[] {\n if (this.cachedCommands) return this.cachedCommands;\n\n const sources: ICommand[][] = [\n scanSkillsDir(join(this.cwd, '.claude', 'skills'), this.fs),\n scanCommandsDir(join(this.cwd, '.claude', 'commands'), this.fs),\n scanSkillsDir(join(this.home, '.robota', 'skills'), this.fs),\n scanSkillsDir(join(this.cwd, '.agents', 'skills'), this.fs),\n ];\n\n const seen = new Set<string>();\n const merged: ICommand[] = [];\n\n for (const commands of sources) {\n for (const cmd of commands) {\n if (!seen.has(cmd.name)) {\n seen.add(cmd.name);\n merged.push(cmd);\n }\n }\n }\n\n this.cachedCommands = merged;\n return this.cachedCommands;\n }\n\n getModelInvocableSkills(): ICommand[] {\n return this.getCommands().filter((cmd) => cmd.disableModelInvocation !== true);\n }\n\n getUserInvocableSkills(): ICommand[] {\n return this.getCommands().filter((cmd) => cmd.userInvocable !== false);\n }\n}\n","/**\n * Agent hook executor — delegates to a sub-agent session.\n *\n * Creates a subagent session with maxTurns and timeout limits,\n * runs hook input as the initial prompt, and parses the result.\n *\n * Exit codes:\n * - 0: ok: true (allow/proceed)\n * - 2: ok: false (block/deny), reason in stderr\n * - 1: execution error (session failure, parse error)\n */\n\nimport type {\n IAgentHookDefinition,\n IHookInput,\n IHookResult,\n IHookTypeExecutor,\n THookDefinition,\n} from '@robota-sdk/agent-core';\n\n/** Default maximum turns for the sub-agent session. */\nconst DEFAULT_MAX_TURNS = 50;\n\n/** Default timeout in seconds. */\nconst DEFAULT_TIMEOUT_SECONDS = 60;\n\n/** A minimal session interface for running a prompt. */\nexport interface IAgentSession {\n run(prompt: string): Promise<string>;\n}\n\n/** Factory that creates a session instance with the given options. */\nexport type TSessionFactory = (options: { maxTurns?: number; timeout?: number }) => IAgentSession;\n\n/** Constructor options for AgentExecutor. */\nexport interface IAgentExecutorOptions {\n sessionFactory: TSessionFactory;\n}\n\n/** Extract JSON from a string, handling markdown code blocks. */\nfunction extractJson(raw: string): string {\n const codeBlockMatch = /```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?\\s*```/.exec(raw);\n if (codeBlockMatch) {\n return codeBlockMatch[1].trim();\n }\n return raw.trim();\n}\n\nexport class AgentExecutor implements IHookTypeExecutor {\n readonly type = 'agent' as const;\n\n private readonly sessionFactory: TSessionFactory;\n\n constructor(options: IAgentExecutorOptions) {\n this.sessionFactory = options.sessionFactory;\n }\n\n async execute(definition: THookDefinition, input: IHookInput): Promise<IHookResult> {\n const agentDef = definition as IAgentHookDefinition;\n const maxTurns = agentDef.maxTurns ?? DEFAULT_MAX_TURNS;\n const timeout = agentDef.timeout ?? DEFAULT_TIMEOUT_SECONDS;\n\n try {\n const session = this.sessionFactory({ maxTurns, timeout });\n const prompt = `Hook input:\\n${JSON.stringify(input)}\\n\\nRespond with JSON: { \"ok\": boolean, \"reason\"?: string }`;\n const rawResponse = await session.run(prompt);\n const jsonStr = extractJson(rawResponse);\n\n let parsed: { ok: boolean; reason?: string };\n try {\n parsed = JSON.parse(jsonStr) as { ok: boolean; reason?: string };\n } catch {\n return {\n exitCode: 1,\n stdout: '',\n stderr: `Failed to parse agent response as JSON: ${rawResponse}`,\n };\n }\n\n if (parsed.ok) {\n return { exitCode: 0, stdout: JSON.stringify(parsed), stderr: '' };\n }\n\n return {\n exitCode: 2,\n stdout: '',\n stderr: parsed.reason ?? 'Blocked by agent hook',\n };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { exitCode: 1, stdout: '', stderr: message };\n }\n }\n}\n","/**\n * Prompt hook executor — evaluates a prompt via an AI model.\n *\n * Makes a single-turn LLM call with hook input context as the prompt.\n * Parses { ok: boolean, reason?: string } from the AI response.\n *\n * Exit codes:\n * - 0: ok: true (allow/proceed)\n * - 2: ok: false (block/deny), reason in stderr\n * - 1: execution error (provider failure, parse error)\n */\n\nimport type {\n IPromptHookDefinition,\n IHookInput,\n IHookResult,\n IHookTypeExecutor,\n THookDefinition,\n} from '@robota-sdk/agent-core';\n\n/** A minimal provider interface for single-turn completion. */\nexport interface IPromptProvider {\n complete(prompt: string): Promise<string>;\n}\n\n/** Factory that creates a provider instance, optionally for a specific model. */\nexport type TProviderFactory = (model?: string) => IPromptProvider;\n\n/** Constructor options for PromptExecutor. */\nexport interface IPromptExecutorOptions {\n providerFactory: TProviderFactory;\n defaultModel?: string;\n}\n\n/** Extract JSON from a string, handling markdown code blocks. */\nfunction extractJson(raw: string): string {\n const codeBlockMatch = /```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?\\s*```/.exec(raw);\n if (codeBlockMatch) {\n return codeBlockMatch[1].trim();\n }\n return raw.trim();\n}\n\nexport class PromptExecutor implements IHookTypeExecutor {\n readonly type = 'prompt' as const;\n\n private readonly providerFactory: TProviderFactory;\n private readonly defaultModel: string | undefined;\n\n constructor(options: IPromptExecutorOptions) {\n this.providerFactory = options.providerFactory;\n this.defaultModel = options.defaultModel;\n }\n\n async execute(definition: THookDefinition, input: IHookInput): Promise<IHookResult> {\n const promptDef = definition as IPromptHookDefinition;\n const model = promptDef.model ?? this.defaultModel;\n\n try {\n const provider = this.providerFactory(model);\n const prompt = `${promptDef.prompt}\\n\\nContext:\\n${JSON.stringify(input)}\\n\\nRespond with JSON: { \"ok\": boolean, \"reason\"?: string }`;\n const rawResponse = await provider.complete(prompt);\n const jsonStr = extractJson(rawResponse);\n\n let parsed: { ok: boolean; reason?: string };\n try {\n parsed = JSON.parse(jsonStr) as { ok: boolean; reason?: string };\n } catch {\n return {\n exitCode: 1,\n stdout: '',\n stderr: `Failed to parse AI response as JSON: ${rawResponse}`,\n };\n }\n\n if (parsed.ok) {\n return { exitCode: 0, stdout: JSON.stringify(parsed), stderr: '' };\n }\n\n return {\n exitCode: 2,\n stdout: '',\n stderr: parsed.reason ?? 'Blocked by prompt hook',\n };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { exitCode: 1, stdout: '', stderr: message };\n }\n }\n}\n","import type {\n IEventService,\n IParameterValidationResult,\n IToolExecutionContext,\n IToolResult,\n IToolSchema,\n IToolWithEventService,\n TToolArgs,\n TToolParameters,\n} from '@robota-sdk/agent-core';\n\nconst FILE_MUTATION_TOOLS = new Set(['Write', 'Edit']);\nconst HOST_SHELL_TOOLS = new Set(['Bash', 'BackgroundProcess']);\nconst READ_ONLY_TOOLS = new Set(['Read', 'Glob', 'Grep', 'WebFetch', 'WebSearch']);\n\nexport type TReversibleExecutionIsolation = 'none' | 'worktree' | 'provider-sandbox';\nexport type TReversibleRollbackLayer = 'none' | 'edit-checkpoint' | 'worktree' | 'provider-sandbox';\nexport type TReversibleSideEffect =\n | 'none'\n | 'file-mutation'\n | 'shell-process'\n | 'subagent'\n | 'unknown';\nexport type TReversibleSafetyStatus =\n | 'reversible'\n | 'read-only'\n | 'requires-checkpoint'\n | 'requires-isolation'\n | 'unknown';\n\nexport interface IReversibleExecutionOptions {\n mode: 'local-first';\n isolation?: TReversibleExecutionIsolation;\n enforceUntrackedSideEffects?: boolean;\n}\n\nexport interface IReversibleToolSafetyContext {\n checkpointAvailable: boolean;\n isolation: TReversibleExecutionIsolation;\n}\n\nexport interface IReversibleToolSafetyInput {\n toolName: string;\n toolArgs?: TToolArgs;\n context: IReversibleToolSafetyContext;\n}\n\nexport interface IReversibleToolSafetyReport {\n toolName: string;\n reversible: boolean;\n sideEffect: TReversibleSideEffect;\n rollbackLayer: TReversibleRollbackLayer;\n status: TReversibleSafetyStatus;\n message: string;\n}\n\ninterface IReversibleExecutionToolWrapperOptions {\n safetyContext: IReversibleToolSafetyContext;\n enforceUntrackedSideEffects: boolean;\n}\n\ntype TReversibleToolArgValue = string | number | boolean | object | undefined;\ntype TReversibleToolArgRecord = Record<string, TReversibleToolArgValue>;\n\nexport function evaluateReversibleToolSafety(\n input: IReversibleToolSafetyInput,\n): IReversibleToolSafetyReport {\n const toolName = input.toolName;\n if (READ_ONLY_TOOLS.has(toolName)) {\n return {\n toolName,\n reversible: true,\n sideEffect: 'none',\n rollbackLayer: 'none',\n status: 'read-only',\n message: `${toolName} does not mutate the local workspace.`,\n };\n }\n\n if (FILE_MUTATION_TOOLS.has(toolName)) {\n if (input.context.isolation === 'worktree' || input.context.isolation === 'provider-sandbox') {\n return evaluateIsolatedSideEffect(toolName, 'file-mutation', input.context);\n }\n if (input.context.checkpointAvailable) {\n return {\n toolName,\n reversible: true,\n sideEffect: 'file-mutation',\n rollbackLayer: 'edit-checkpoint',\n status: 'reversible',\n message: `${toolName} is reversible through the active edit checkpoint.`,\n };\n }\n return {\n toolName,\n reversible: false,\n sideEffect: 'file-mutation',\n rollbackLayer: 'none',\n status: 'requires-checkpoint',\n message: `${toolName} requires an edit checkpoint before file mutation.`,\n };\n }\n\n if (HOST_SHELL_TOOLS.has(toolName)) {\n return evaluateIsolatedSideEffect(toolName, 'shell-process', input.context);\n }\n\n if (toolName === 'Agent') {\n return evaluateAgentSafety(input.toolArgs, input.context);\n }\n\n return {\n toolName,\n reversible: false,\n sideEffect: 'unknown',\n rollbackLayer: 'none',\n status: 'unknown',\n message: `${toolName} has no reversible execution contract.`,\n };\n}\n\nexport function wrapReversibleExecutionTools(\n tools: readonly IToolWithEventService[],\n options: IReversibleExecutionOptions & { checkpointAvailable: boolean },\n): IToolWithEventService[] {\n const safetyContext: IReversibleToolSafetyContext = {\n checkpointAvailable: options.checkpointAvailable,\n isolation: options.isolation ?? 'none',\n };\n const enforceUntrackedSideEffects = options.enforceUntrackedSideEffects ?? true;\n return tools.map(\n (tool) =>\n new ReversibleExecutionToolWrapper(tool, {\n safetyContext,\n enforceUntrackedSideEffects,\n }),\n );\n}\n\nclass ReversibleExecutionToolWrapper implements IToolWithEventService {\n readonly schema: IToolSchema;\n\n constructor(\n private readonly delegate: IToolWithEventService,\n private readonly options: IReversibleExecutionToolWrapperOptions,\n ) {\n this.schema = delegate.schema;\n }\n\n setEventService(eventService: IEventService | undefined): void {\n this.delegate.setEventService(eventService);\n }\n\n async execute(parameters: TToolParameters, context: IToolExecutionContext): Promise<IToolResult> {\n const report = evaluateReversibleToolSafety({\n toolName: this.getName(),\n toolArgs: toToolArgs(parameters),\n context: this.options.safetyContext,\n });\n if (!report.reversible && this.options.enforceUntrackedSideEffects) {\n return createBlockedResult(report);\n }\n return this.delegate.execute(parameters, context);\n }\n\n validate(parameters: TToolParameters): boolean {\n return this.delegate.validate(parameters);\n }\n\n validateParameters(parameters: TToolParameters): IParameterValidationResult {\n return this.delegate.validateParameters(parameters);\n }\n\n getDescription(): string {\n return this.delegate.getDescription();\n }\n\n getName(): string {\n return this.delegate.getName();\n }\n}\n\nfunction evaluateIsolatedSideEffect(\n toolName: string,\n sideEffect: TReversibleSideEffect,\n context: IReversibleToolSafetyContext,\n): IReversibleToolSafetyReport {\n if (context.isolation === 'worktree') {\n return {\n toolName,\n reversible: true,\n sideEffect,\n rollbackLayer: 'worktree',\n status: 'reversible',\n message: `${toolName} side effects are contained in an isolated Git worktree.`,\n };\n }\n if (context.isolation === 'provider-sandbox') {\n return {\n toolName,\n reversible: true,\n sideEffect,\n rollbackLayer: 'provider-sandbox',\n status: 'reversible',\n message: `${toolName} side effects are contained in a provider sandbox snapshot.`,\n };\n }\n return {\n toolName,\n reversible: false,\n sideEffect,\n rollbackLayer: 'none',\n status: 'requires-isolation',\n message: `${toolName} can create host shell side effects that edit checkpoints cannot restore; use worktree or provider sandbox isolation.`,\n };\n}\n\nfunction evaluateAgentSafety(\n toolArgs: TToolArgs | undefined,\n context: IReversibleToolSafetyContext,\n): IReversibleToolSafetyReport {\n if (context.isolation === 'worktree' || context.isolation === 'provider-sandbox') {\n return evaluateIsolatedSideEffect('Agent', 'subagent', context);\n }\n\n if (agentRequestUsesWorktree(toolArgs)) {\n return {\n toolName: 'Agent',\n reversible: true,\n sideEffect: 'subagent',\n rollbackLayer: 'worktree',\n status: 'reversible',\n message:\n 'Agent jobs request worktree isolation, so shell side effects stay outside the parent workspace.',\n };\n }\n\n return {\n toolName: 'Agent',\n reversible: false,\n sideEffect: 'subagent',\n rollbackLayer: 'none',\n status: 'requires-isolation',\n message: 'Agent jobs must request worktree isolation to be reversible in local-first mode.',\n };\n}\n\nfunction agentRequestUsesWorktree(toolArgs: TToolArgs | undefined): boolean {\n if (!toolArgs) return false;\n const jobs = toolArgs.jobs;\n if (Array.isArray(jobs)) {\n return (\n jobs.length > 0 &&\n jobs.every((job: TReversibleToolArgValue) => {\n if (!isToolArgRecord(job)) return false;\n return readIsolation(job) === 'worktree';\n })\n );\n }\n return readIsolation(toolArgs) === 'worktree';\n}\n\nfunction readIsolation(value: TReversibleToolArgRecord): string | undefined {\n const isolation = value['isolation'];\n return typeof isolation === 'string' ? isolation : undefined;\n}\n\nfunction isToolArgRecord(value: TReversibleToolArgValue): value is TReversibleToolArgRecord {\n return value !== undefined && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction toToolArgs(parameters: TToolParameters): TToolArgs | undefined {\n if (!parameters || typeof parameters !== 'object' || Array.isArray(parameters)) return undefined;\n return parameters as TToolArgs;\n}\n\nfunction createBlockedResult(report: IReversibleToolSafetyReport): IToolResult {\n return {\n success: true,\n data: {\n success: false,\n output: '',\n error: report.message,\n reversibleSafety: {\n toolName: report.toolName,\n sideEffect: report.sideEffect,\n rollbackLayer: report.rollbackLayer,\n status: report.status,\n },\n },\n metadata: {\n reversibleSafetyStatus: report.status,\n rollbackLayer: report.rollbackLayer,\n },\n };\n}\n","/**\n * Session factory — assembles a fully-configured Session from config, context,\n * tools, and provider.\n */\n\nimport { Session } from '@robota-sdk/agent-session';\n\nimport {\n buildAgentRuntime,\n buildBackgroundProcessTool,\n buildSessionSystemPrompt,\n wireSessionDeps,\n} from './create-session-runtime.js';\nimport { createDefaultTools, DEFAULT_TOOL_DESCRIPTIONS } from './create-tools.js';\nimport { wrapEditCheckpointTools } from '../checkpoints/edit-checkpoint-tools.js';\nimport { SkillCommandSource } from '../commands/skill-source.js';\nimport { AgentExecutor } from '../hooks/agent-executor.js';\nimport { PromptExecutor } from '../hooks/prompt-executor.js';\nimport { wrapReversibleExecutionTools } from '../reversible-execution/index.js';\nimport {\n createModelCommandToolProjection,\n createProjectedCommandExecutionTools,\n} from '../tools/model-command-tool-projection.js';\n\nimport type {\n ICreateSessionOptions,\n ICreateSessionResult,\n TSessionConstructorWithAutoCompact,\n} from './create-session-types.js';\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { TSessionFactory } from '../hooks/agent-executor.js';\nimport type { TProviderFactory } from '../hooks/prompt-executor.js';\nimport type { IToolWithEventService, IHookTypeExecutor } from '@robota-sdk/agent-core';\n\nexport type { ICreateSessionOptions, ICreateSessionResult } from './create-session-types.js';\n\nconst ID_RADIX = 36;\nconst ID_RANDOM_LENGTH = 9;\nconst DEFAULT_PROVIDER_IDLE_TIMEOUT_MS = 120_000;\n\nfunction getModelInvocableCommandDescriptors(\n descriptors: readonly ICapabilityDescriptor[] | undefined,\n): ICapabilityDescriptor[] {\n return (descriptors ?? []).filter(\n (descriptor) => descriptor.modelInvocable && descriptor.kind === 'builtin-command',\n );\n}\n\nfunction normalizeCommandDescriptorName(name: string): string {\n return name.trim().replace(/^\\/+/, '').split(/\\s+/)[0] ?? '';\n}\n\nfunction hasModelInvocableCommandDescriptor(\n descriptors: readonly ICapabilityDescriptor[],\n name: string,\n): boolean {\n return descriptors.some((descriptor) => normalizeCommandDescriptorName(descriptor.name) === name);\n}\n\n/**\n * Create a fully-configured Session instance.\n *\n * Assembles provider, tools, and system prompt, then passes them\n * to Session as pre-constructed dependencies.\n */\nexport function createSession(options: ICreateSessionOptions): ICreateSessionResult {\n if (!options.provider) {\n throw new Error(\n 'provider is required. SDK is provider-neutral — consumer must create and pass a provider instance.',\n );\n }\n const provider = options.provider;\n const cwd = options.cwd ?? process.cwd();\n const sessionId = options.sessionId ?? createSessionId();\n const skillCommandSource = new SkillCommandSource(cwd);\n const modelInvocableCommandDescriptors = getModelInvocableCommandDescriptors(\n options.commandDescriptors,\n );\n const modelCommandToolsEnabled =\n modelInvocableCommandDescriptors.length > 0 &&\n options.modelCommandExecutor !== undefined &&\n options.isModelCommandInvocable !== undefined;\n const modelCommandToolProjection = modelCommandToolsEnabled\n ? createModelCommandToolProjection(modelInvocableCommandDescriptors)\n : undefined;\n const modelVisibleSkills = hasModelInvocableCommandDescriptor(\n modelInvocableCommandDescriptors,\n 'skills',\n )\n ? skillCommandSource.getModelInvocableSkills()\n : [];\n\n const baseDefaultTools = createDefaultTools({ sandboxClient: options.sandboxClient });\n const shouldWrapHostEditCheckpoints =\n options.editCheckpointRecorder !== undefined && options.sandboxClient === undefined;\n const defaultTools =\n shouldWrapHostEditCheckpoints && options.editCheckpointRecorder\n ? wrapEditCheckpointTools(baseDefaultTools, options.editCheckpointRecorder)\n : baseDefaultTools;\n const assembledTools = [...defaultTools, ...(options.additionalTools ?? [])];\n const reversibleExecution = options.reversibleExecution\n ? {\n ...options.reversibleExecution,\n isolation:\n options.reversibleExecution.isolation ??\n (options.sandboxClient ? ('provider-sandbox' as const) : undefined),\n }\n : undefined;\n const tools: IToolWithEventService[] = reversibleExecution\n ? wrapReversibleExecutionTools(assembledTools, {\n ...reversibleExecution,\n checkpointAvailable: shouldWrapHostEditCheckpoints,\n })\n : assembledTools;\n if (\n modelCommandToolsEnabled &&\n options.modelCommandExecutor !== undefined &&\n options.isModelCommandInvocable !== undefined\n ) {\n tools.push(\n ...createProjectedCommandExecutionTools({\n execute: options.modelCommandExecutor,\n isModelInvocable: options.isModelCommandInvocable,\n commandDescriptors: modelInvocableCommandDescriptors,\n }),\n );\n }\n\n const hookTypeExecutors: IHookTypeExecutor[] = [];\n if (options.providerFactory) {\n hookTypeExecutors.push(\n new PromptExecutor({\n providerFactory: options.providerFactory,\n defaultModel: options.config.provider.model,\n }),\n );\n }\n if (options.sessionFactory) {\n hookTypeExecutors.push(new AgentExecutor({ sessionFactory: options.sessionFactory }));\n }\n if (options.additionalHookExecutors) {\n hookTypeExecutors.push(...options.additionalHookExecutors);\n }\n\n const { agentToolDeps, agentDefinitions, backgroundTaskManager } = buildAgentRuntime(\n options,\n sessionId,\n cwd,\n provider,\n tools,\n hookTypeExecutors,\n );\n\n const { backgroundProcessToolDeps } = buildBackgroundProcessTool(\n options,\n backgroundTaskManager,\n sessionId,\n cwd,\n tools,\n );\n\n const { finalSystemMessage, rebuildSystemMessage } = buildSessionSystemPrompt(\n options,\n cwd,\n modelInvocableCommandDescriptors,\n modelCommandToolProjection,\n backgroundProcessToolDeps,\n modelVisibleSkills,\n agentDefinitions,\n );\n\n const defaultAllow = [\n 'Read(.agents/**)',\n 'Read(.claude/**)',\n 'Read(.robota/**)',\n 'Glob(.agents/**)',\n 'Glob(.claude/**)',\n 'Glob(.robota/**)',\n ];\n const allowedToolPatterns = (options.allowedTools ?? []).map((name) => `${name}(*)`);\n const mergedPermissions = {\n allow: [...defaultAllow, ...(options.config.permissions.allow ?? []), ...allowedToolPatterns],\n deny: options.config.permissions.deny ?? [],\n };\n\n const SessionWithAutoCompact = Session as TSessionConstructorWithAutoCompact;\n const session = new SessionWithAutoCompact({\n tools,\n provider,\n systemMessage: finalSystemMessage,\n terminal: options.terminal,\n permissions: mergedPermissions,\n hooks: options.config.hooks,\n permissionMode: options.permissionMode,\n defaultTrustLevel: options.config.defaultTrustLevel,\n model: options.config.provider.model,\n providerTimeout: options.config.provider.timeout ?? DEFAULT_PROVIDER_IDLE_TIMEOUT_MS,\n maxTurns: options.maxTurns,\n sessionStore: options.sessionStore,\n sessionId,\n permissionHandler: options.permissionHandler,\n onTextDelta: options.onTextDelta,\n onContextUpdate: options.onContextUpdate,\n onToolExecution: options.onToolExecution,\n promptForApproval: options.promptForApproval,\n onCompact: options.onCompact,\n onCompactEvent: options.onCompactEvent,\n compactInstructions: options.compactInstructions ?? options.context.compactInstructions,\n autoCompactThreshold: options.autoCompactThreshold ?? options.config.autoCompactThreshold,\n sessionLogger: options.sessionLogger,\n hookTypeExecutors: hookTypeExecutors.length > 0 ? hookTypeExecutors : undefined,\n agentName: options.agentName,\n });\n\n wireSessionDeps(session, agentToolDeps, backgroundProcessToolDeps, backgroundTaskManager);\n\n return { session, rebuildSystemMessage };\n}\n\nfunction createSessionId(): string {\n return `session_${Date.now()}_${Math.random().toString(ID_RADIX).substr(2, ID_RANDOM_LENGTH)}`;\n}\n","/**\n * Subagent transcript logger — creates a FileSessionLogger that writes\n * subagent session logs into a subdirectory of the parent session's log folder.\n *\n * Log structure:\n * {baseLogsDir}/{parentSessionId}/subagents/{agentId}.jsonl\n */\n\nimport { join } from 'node:path';\n\nimport { FileSessionLogger } from '@robota-sdk/agent-session';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/**\n * Create a FileSessionLogger for a subagent session.\n *\n * The logger writes JSONL files into a `subagents/` subdirectory under the\n * parent session's log folder. The directory is created if it does not exist.\n *\n * @param parentSessionId - ID of the parent session (used as directory name)\n * @param agentId - Unique identifier for this subagent run\n * @param baseLogsDir - Root logs directory (e.g., `.robota/logs`)\n * @returns A FileSessionLogger writing to the subagent directory\n */\nexport function createSubagentLogger(\n parentSessionId: string,\n _agentId: string,\n baseLogsDir: string,\n fs: IFileSystem = new NodeFileSystem(),\n): FileSessionLogger {\n const subagentDir = join(baseLogsDir, parentSessionId, 'subagents');\n fs.mkdirSync(subagentDir, { recursive: true });\n return new FileSessionLogger(subagentDir);\n}\n\n/**\n * Resolve the subagent log directory path without creating it.\n *\n * Useful when the caller needs the path for display or configuration\n * but does not want to create the directory immediately.\n *\n * @param parentSessionId - ID of the parent session\n * @param baseLogsDir - Root logs directory\n * @returns The resolved subagent log directory path\n */\nexport function resolveSubagentLogDir(parentSessionId: string, baseLogsDir: string): string {\n return join(baseLogsDir, parentSessionId, 'subagents');\n}\n","/**\n * Zod schemas and TypeScript types for Robota CLI settings\n */\nimport { z } from 'zod';\n\nimport type { THooksConfig } from '@robota-sdk/agent-core';\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\n\nconst UniversalValueSchema: z.ZodType<TUniversalValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.undefined(),\n z.date(),\n z.array(UniversalValueSchema),\n z.record(UniversalValueSchema),\n ]),\n);\n\nconst ProviderSchema = z.object({\n name: z.string().optional(),\n model: z.string().optional(),\n apiKey: z.string().optional(),\n baseURL: z.string().optional(),\n timeout: z.number().optional(),\n options: z.record(UniversalValueSchema).optional(),\n});\n\nconst ProviderProfileSchema = z.object({\n type: z.string().optional(),\n model: z.string().optional(),\n apiKey: z.string().optional(),\n baseURL: z.string().optional(),\n timeout: z.number().optional(),\n options: z.record(UniversalValueSchema).optional(),\n});\n\nconst PermissionsSchema = z.object({\n /** Patterns that are always approved without prompting */\n allow: z.array(z.string()).optional(),\n /** Patterns that are always denied */\n deny: z.array(z.string()).optional(),\n});\n\nconst EnvSchema = z.record(z.string()).optional();\n\n/** Command hook definition */\nconst CommandHookDefinitionSchema = z.object({\n type: z.literal('command'),\n command: z.string(),\n timeout: z.number().optional(),\n});\n\n/** HTTP hook definition */\nconst HttpHookDefinitionSchema = z.object({\n type: z.literal('http'),\n url: z.string(),\n headers: z.record(z.string()).optional(),\n timeout: z.number().optional(),\n});\n\n/** Prompt hook definition */\nconst PromptHookDefinitionSchema = z.object({\n type: z.literal('prompt'),\n prompt: z.string(),\n model: z.string().optional(),\n});\n\n/** Agent hook definition */\nconst AgentHookDefinitionSchema = z.object({\n type: z.literal('agent'),\n agent: z.string(),\n maxTurns: z.number().optional(),\n timeout: z.number().optional(),\n});\n\n/** Discriminated union of all hook definition types */\nconst HookDefinitionSchema = z.discriminatedUnion('type', [\n CommandHookDefinitionSchema,\n HttpHookDefinitionSchema,\n PromptHookDefinitionSchema,\n AgentHookDefinitionSchema,\n]);\n\nconst HookGroupSchema = z.object({\n matcher: z.string(),\n hooks: z.array(HookDefinitionSchema),\n});\n\n/** Supported hook events */\nconst HooksSchema = z\n .object({\n PreToolUse: z.array(HookGroupSchema).optional(),\n PostToolUse: z.array(HookGroupSchema).optional(),\n SessionStart: z.array(HookGroupSchema).optional(),\n SessionEnd: z.array(HookGroupSchema).optional(),\n Stop: z.array(HookGroupSchema).optional(),\n StopFailure: z.array(HookGroupSchema).optional(),\n PreCompact: z.array(HookGroupSchema).optional(),\n PostCompact: z.array(HookGroupSchema).optional(),\n UserPromptSubmit: z.array(HookGroupSchema).optional(),\n SubagentStart: z.array(HookGroupSchema).optional(),\n SubagentStop: z.array(HookGroupSchema).optional(),\n WorktreeCreate: z.array(HookGroupSchema).optional(),\n WorktreeRemove: z.array(HookGroupSchema).optional(),\n })\n .optional();\n\n/** Plugin enablement map: plugin name -> enabled flag */\nconst EnabledPluginsSchema = z.record(z.boolean()).optional();\n\n/** Extra marketplace sources: name -> { source: TMarketplaceSource } */\nconst MarketplaceSourceSchema = z.object({\n source: z.object({\n type: z.enum(['github', 'git', 'local', 'url']),\n repo: z.string().optional(),\n url: z.string().optional(),\n path: z.string().optional(),\n ref: z.string().optional(),\n }),\n});\nconst ExtraKnownMarketplacesSchema = z.record(MarketplaceSourceSchema).optional().catch(undefined);\nconst AutoCompactThresholdSchema = z.union([z.number().gt(0).lte(1), z.literal(false)]).optional();\n\nconst TransportSettingsSchema = z.object({\n enabled: z.boolean().optional(),\n options: z.record(UniversalValueSchema).optional(),\n});\n\nexport const SettingsSchema = z.object({\n /** Trust level used when no --permission-mode flag is given */\n defaultTrustLevel: z.enum(['safe', 'moderate', 'full']).optional(),\n /** Response language (e.g., \"ko\", \"en\", \"ja\"). Injected into system prompt. */\n language: z.string().optional(),\n /** Active provider profile key from providers. */\n currentProvider: z.string().optional(),\n /** Provider profiles keyed by user-facing profile name. */\n providers: z.record(ProviderProfileSchema).optional(),\n /** Legacy single-provider settings. Prefer currentProvider + providers for new config. */\n provider: ProviderSchema.optional(),\n permissions: PermissionsSchema.optional(),\n env: EnvSchema,\n hooks: HooksSchema,\n /** Plugin enablement map: plugin name -> enabled/disabled */\n enabledPlugins: EnabledPluginsSchema,\n /** Extra marketplace URLs for BundlePlugin discovery */\n extraKnownMarketplaces: ExtraKnownMarketplacesSchema,\n /** Auto-compact threshold as a 0-1 fraction. Set false to disable automatic compaction. */\n autoCompactThreshold: AutoCompactThresholdSchema,\n /** Transport enable/disable + options: transport name -> config */\n transports: z.record(TransportSettingsSchema).optional(),\n});\n\nexport type TSettings = z.infer<typeof SettingsSchema>;\nexport type TProviderSettings = z.infer<typeof ProviderSchema>;\nexport type TPermissionsSettings = z.infer<typeof PermissionsSchema>;\n\n/**\n * Fully resolved config after merging all settings files and applying defaults.\n */\nexport interface IResolvedConfig {\n defaultTrustLevel: 'safe' | 'moderate' | 'full';\n /** Response language code (e.g., \"ko\", \"en\"). Undefined = no language constraint. */\n language?: string;\n /** Active provider profile key when providers/currentProvider are used. */\n currentProvider?: string;\n provider: {\n name: string;\n model: string;\n apiKey: string | undefined;\n baseURL?: string;\n timeout?: number;\n options?: Record<string, TUniversalValue>;\n };\n permissions: {\n allow: string[];\n deny: string[];\n };\n env: Record<string, string>;\n hooks?: THooksConfig;\n /** Plugin enablement map: plugin name -> enabled/disabled */\n enabledPlugins?: Record<string, boolean>;\n /** Extra marketplace sources: name -> { source } */\n extraKnownMarketplaces?: Record<\n string,\n { source: { type: string; repo?: string; url?: string; path?: string; ref?: string } }\n >;\n /** Auto-compact threshold as a 0-1 fraction. Set false to disable automatic compaction. */\n autoCompactThreshold?: number | false;\n /** Transport enable/disable + options: transport name -> { enabled, options } */\n transports?: Record<string, { enabled?: boolean; options?: Record<string, unknown> }>;\n}\n","/**\n * Config loader — discovers, merges, and validates settings files.\n *\n * Precedence (lowest → highest):\n * 1. ~/.robota/settings.json (user)\n * 2. ~/.claude/settings.json (user, Claude Code compat)\n * 3. .robota/settings.json (project)\n * 4. .robota/settings.local.json (project-local)\n * 5. .claude/settings.json (project, Claude Code compat)\n * 6. .claude/settings.local.json (project-local, highest priority)\n */\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\n\nimport { SettingsSchema, type TSettings, type IResolvedConfig } from './config-types.js';\n\n/**\n * Return the current user home directory.\n * Reads process.env.HOME at call time so tests can override it.\n */\nfunction getHomeDir(): string {\n return process.env.HOME ?? process.env.USERPROFILE ?? '/';\n}\n\n/** Default resolved config values */\nconst DEFAULTS: IResolvedConfig = {\n defaultTrustLevel: 'moderate',\n provider: {\n name: 'anthropic',\n model: 'claude-opus-4-5',\n apiKey: undefined,\n },\n permissions: {\n allow: [],\n deny: [],\n },\n env: {},\n};\n\n/**\n * Read and parse a JSON file. Returns undefined if the file does not exist.\n * Throws on parse errors.\n */\nfunction readJsonFile(filePath: string): unknown {\n if (!existsSync(filePath)) {\n return undefined;\n }\n const raw = readFileSync(filePath, 'utf-8').trim();\n if (raw.length === 0) {\n // Empty file — likely from a crash during write. Treat as missing.\n return undefined;\n }\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n // Corrupt JSON — likely from a crash during write. Treat as missing.\n return undefined;\n }\n}\n\n/**\n * Resolve a string value that may use the `$ENV:VAR_NAME` prefix to\n * substitute an environment variable.\n */\nfunction resolveEnvRef(value: string): string {\n const ENV_PREFIX = '$ENV:';\n if (value.startsWith(ENV_PREFIX)) {\n const varName = value.slice(ENV_PREFIX.length);\n return process.env[varName] ?? value;\n }\n return value;\n}\n\n/**\n * Apply env-ref resolution to all string fields in a settings object.\n */\nfunction resolveEnvRefs(settings: TSettings): TSettings {\n const provider =\n settings.provider?.apiKey !== undefined\n ? resolveProviderCredentialEnvRefs(settings.provider)\n : settings.provider;\n\n if (settings.providers !== undefined) {\n const providers = Object.fromEntries(\n Object.entries(settings.providers).map(([name, profile]) => [\n name,\n resolveProviderCredentialEnvRefs(profile),\n ]),\n );\n return {\n ...settings,\n provider,\n providers,\n };\n }\n\n return {\n ...settings,\n provider,\n };\n}\n\nfunction resolveProviderCredentialEnvRefs<TProvider extends { apiKey?: string }>(\n provider: TProvider,\n): TProvider {\n return {\n ...provider,\n ...(provider.apiKey !== undefined && { apiKey: resolveEnvRef(provider.apiKey) }),\n };\n}\n\n/**\n * Deep-merge settings objects. Later entries in the array win.\n * Arrays are replaced (not concatenated) so that project settings\n * fully override user settings for list-type fields.\n */\nfunction mergeSettings(layers: TSettings[]): TSettings {\n return layers.reduce<TSettings>((merged, layer) => {\n return {\n ...merged,\n ...layer,\n provider:\n merged.provider !== undefined || layer.provider !== undefined\n ? { ...merged.provider, ...layer.provider }\n : undefined,\n permissions:\n merged.permissions !== undefined || layer.permissions !== undefined\n ? {\n allow: layer.permissions?.allow ?? merged.permissions?.allow,\n deny: layer.permissions?.deny ?? merged.permissions?.deny,\n }\n : undefined,\n env: {\n ...(merged.env ?? {}),\n ...(layer.env ?? {}),\n },\n providers:\n merged.providers !== undefined || layer.providers !== undefined\n ? mergeProviders(merged.providers, layer.providers)\n : undefined,\n enabledPlugins:\n merged.enabledPlugins !== undefined || layer.enabledPlugins !== undefined\n ? { ...(merged.enabledPlugins ?? {}), ...(layer.enabledPlugins ?? {}) }\n : undefined,\n extraKnownMarketplaces: layer.extraKnownMarketplaces ?? merged.extraKnownMarketplaces,\n autoCompactThreshold: layer.autoCompactThreshold ?? merged.autoCompactThreshold,\n };\n }, {});\n}\n\nfunction mergeProviders(\n base: TSettings['providers'],\n override: TSettings['providers'],\n): TSettings['providers'] {\n const result: NonNullable<TSettings['providers']> = { ...(base ?? {}) };\n for (const [name, profile] of Object.entries(override ?? {})) {\n result[name] = {\n ...result[name],\n ...profile,\n };\n }\n return result;\n}\n\nfunction resolveProvider(merged: TSettings): IResolvedConfig['provider'] {\n if (merged.currentProvider !== undefined) {\n return resolveActiveProviderProfile(merged);\n }\n if (merged.provider !== undefined) {\n throw new Error(\n 'Legacy flat \"provider\" settings are not supported. Migrate to \"currentProvider\" + \"providers\" format.',\n );\n }\n return { ...DEFAULTS.provider };\n}\n\nfunction resolveActiveProviderProfile(merged: TSettings): IResolvedConfig['provider'] {\n const currentProvider = merged.currentProvider;\n if (currentProvider === undefined) {\n throw new Error('currentProvider is required');\n }\n const profile = merged.providers?.[currentProvider];\n if (profile === undefined) {\n throw new Error(`currentProvider \"${currentProvider}\" was not found in providers`);\n }\n if (profile.type === undefined) {\n throw new Error(`Provider profile \"${currentProvider}\" is missing type`);\n }\n return {\n name: profile.type,\n model: profile.model ?? DEFAULTS.provider.model,\n apiKey: profile.apiKey ?? DEFAULTS.provider.apiKey,\n ...(profile.baseURL !== undefined && { baseURL: profile.baseURL }),\n ...(profile.timeout !== undefined && { timeout: profile.timeout }),\n ...(profile.options !== undefined && { options: profile.options }),\n };\n}\n\n/**\n * Convert merged TSettings into a fully-resolved IResolvedConfig with defaults.\n */\nfunction toResolvedConfig(merged: TSettings): IResolvedConfig {\n return {\n defaultTrustLevel: merged.defaultTrustLevel ?? DEFAULTS.defaultTrustLevel,\n language: merged.language,\n currentProvider: merged.currentProvider,\n provider: resolveProvider(merged),\n permissions: {\n allow: merged.permissions?.allow ?? DEFAULTS.permissions.allow,\n deny: merged.permissions?.deny ?? DEFAULTS.permissions.deny,\n },\n env: merged.env ?? DEFAULTS.env,\n hooks: merged.hooks ?? undefined,\n enabledPlugins: merged.enabledPlugins ?? undefined,\n extraKnownMarketplaces: merged.extraKnownMarketplaces ?? undefined,\n autoCompactThreshold: merged.autoCompactThreshold,\n };\n}\n\n/**\n * Build the ordered list of settings file paths (lowest → highest priority).\n */\nfunction getSettingsPaths(cwd: string): string[] {\n const home = getHomeDir();\n return [\n join(home, '.robota', 'settings.json'), // 1. user (lowest)\n join(home, '.claude', 'settings.json'), // 1b. user (Claude Code compat)\n join(cwd, '.robota', 'settings.json'), // 2. project\n join(cwd, '.robota', 'settings.local.json'), // 3. project-local\n join(cwd, '.claude', 'settings.json'), // 4. project, Claude Code compat\n join(cwd, '.claude', 'settings.local.json'), // 5. project-local (highest)\n ];\n}\n\n/**\n * Load and merge all settings files, validate with Zod, return resolved config.\n *\n * @param cwd - The working directory (project root) to search for settings\n */\nexport async function loadConfig(cwd: string): Promise<IResolvedConfig> {\n const allPaths = getSettingsPaths(cwd);\n\n const rawEntries: Array<{ raw: unknown; path: string }> = [];\n for (const filePath of allPaths) {\n const raw = readJsonFile(filePath);\n if (raw !== undefined) {\n rawEntries.push({ raw, path: filePath });\n }\n }\n\n const parsedLayers: TSettings[] = rawEntries.map(({ raw, path }) => {\n const result = SettingsSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(`Invalid settings in ${path}: ${result.error.message}`);\n }\n return resolveEnvRefs(result.data);\n });\n\n const merged = mergeSettings(parsedLayers);\n return toResolvedConfig(merged);\n}\n","import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\nexport type TTaskFileStatus = 'todo' | 'in-progress' | 'blocked' | 'completed' | 'unknown';\n\nexport interface ITaskContextFile {\n path: string;\n relativePath: string;\n title: string;\n status: TTaskFileStatus;\n branch?: string;\n scope?: string;\n objective?: string;\n openItems: readonly string[];\n}\n\nexport interface ITaskSelectionOptions {\n currentBranch?: string;\n maxTasks?: number;\n}\n\nexport interface IUpdateTaskFileStatusOptions {\n now?: Date;\n progressMessage?: string;\n}\n\nconst TASKS_DIR = join('.agents', 'tasks');\nconst README_FILENAME = 'README.md';\nconst MARKDOWN_EXTENSION = '.md';\nconst DEFAULT_MAX_TASKS = Number('3');\nconst STATUS_PRIORITIES: Record<TTaskFileStatus, number> = {\n 'in-progress': Number('1'),\n todo: Number('2'),\n blocked: Number('3'),\n unknown: Number('4'),\n completed: Number('5'),\n};\n\nfunction normalizeStatus(value: string | undefined): TTaskFileStatus {\n const normalized = value?.trim().toLowerCase();\n if (\n normalized === 'todo' ||\n normalized === 'in-progress' ||\n normalized === 'blocked' ||\n normalized === 'completed'\n ) {\n return normalized;\n }\n return 'unknown';\n}\n\nfunction extractTitle(content: string, taskPath: string): string {\n const heading = content.split(/\\r?\\n/).find((line) => /^#\\s+/.test(line));\n return heading?.replace(/^#\\s+/, '').trim() || basename(taskPath, MARKDOWN_EXTENSION);\n}\n\nfunction extractMetadata(content: string, key: string): string | undefined {\n const matcher = new RegExp(`^- \\\\*\\\\*${key}\\\\*\\\\*:\\\\s*(.+)$`, 'im');\n return matcher.exec(content)?.[1]?.trim();\n}\n\nfunction extractSection(content: string, title: string): string | undefined {\n const lines = content.split(/\\r?\\n/);\n const heading = new RegExp(`^(#{2,6})\\\\s+${title}\\\\b`, 'i');\n const startIndex = lines.findIndex((line) => heading.test(line));\n if (startIndex < 0) {\n return undefined;\n }\n\n const collected: string[] = [];\n for (const line of lines.slice(startIndex + Number('1'))) {\n if (/^##\\s+/.test(line)) {\n break;\n }\n collected.push(line);\n }\n\n const result = collected.join('\\n').trim();\n return result.length > 0 ? result : undefined;\n}\n\nfunction extractOpenItems(content: string): string[] {\n return content\n .split(/\\r?\\n/)\n .map((line) => /^- \\[ \\]\\s+(.+)$/.exec(line)?.[1]?.trim())\n .filter((item): item is string => item !== undefined && item.length > 0);\n}\n\nfunction taskSortScore(task: ITaskContextFile, currentBranch?: string): number {\n if (currentBranch && task.branch === currentBranch) {\n return Number('0');\n }\n return STATUS_PRIORITIES[task.status];\n}\n\nfunction formatTask(task: ITaskContextFile): string {\n const lines = [`### ${task.title}`, `- **Path:** \\`${task.relativePath}\\``];\n lines.push(`- **Status:** ${task.status}`);\n if (task.branch) lines.push(`- **Branch:** ${task.branch}`);\n if (task.scope) lines.push(`- **Scope:** ${task.scope}`);\n if (task.objective) lines.push(`- **Objective:** ${task.objective}`);\n if (task.openItems.length > 0) {\n lines.push('- **Open items:**');\n lines.push(...task.openItems.map((item) => ` - ${item}`));\n }\n return lines.join('\\n');\n}\n\nfunction formatDate(date: Date): string {\n return date.toISOString().slice(Number('0'), Number('10'));\n}\n\nfunction upsertStatusLine(content: string, status: TTaskFileStatus): string {\n const lines = content.split(/\\r?\\n/);\n const statusLine = `- **Status**: ${status}`;\n const statusIndex = lines.findIndex((line) => /^- \\*\\*Status\\*\\*:\\s*/.test(line));\n if (statusIndex >= Number('0')) {\n lines[statusIndex] = statusLine;\n return lines.join('\\n');\n }\n\n const hasTopHeading = lines.length > Number('0') && /^#\\s+/.test(lines[Number('0')]);\n if (hasTopHeading) {\n lines.splice(Number('1'), Number('0'), '', statusLine);\n } else {\n lines.unshift(statusLine, '');\n }\n return lines.join('\\n');\n}\n\nfunction appendProgressEntry(content: string, now: Date, progressMessage: string): string {\n const entryLines = [`### ${formatDate(now)}`, `- ${progressMessage.trim()}`];\n const lines = content.replace(/\\s+$/u, '').split(/\\r?\\n/);\n const progressIndex = lines.findIndex((line) => /^## Progress\\s*$/.test(line));\n if (progressIndex < Number('0')) {\n return [...lines, '', '## Progress', '', ...entryLines, ''].join('\\n');\n }\n\n const nextHeadingIndex = lines.findIndex(\n (line, index) => index > progressIndex && /^##\\s+/.test(line),\n );\n if (nextHeadingIndex < Number('0')) {\n return [...lines, '', ...entryLines, ''].join('\\n');\n }\n\n lines.splice(nextHeadingIndex, Number('0'), '', ...entryLines, '');\n return lines.join('\\n');\n}\n\nfunction resolveGitDirectory(cwd: string, fs: IFileSystem): string | undefined {\n let current = resolve(cwd);\n let reachedRoot = false;\n while (!reachedRoot) {\n const gitPath = join(current, '.git');\n if (fs.existsSync(gitPath)) {\n const stats = fs.statSync(gitPath);\n if (stats.isDirectory()) return gitPath;\n const content = fs.readFileSync(gitPath, 'utf8').trim();\n const gitdir = content.match(/^gitdir:\\s*(.+)$/)?.[1];\n if (gitdir) return isAbsolute(gitdir) ? gitdir : resolve(current, gitdir);\n }\n\n const parent = dirname(current);\n reachedRoot = parent === current;\n current = parent;\n }\n return undefined;\n}\n\nexport function readCurrentGitBranch(\n cwd: string,\n fs: IFileSystem = new NodeFileSystem(),\n): string | undefined {\n const gitDir = resolveGitDirectory(cwd, fs);\n if (!gitDir) return undefined;\n const headPath = join(gitDir, 'HEAD');\n if (!fs.existsSync(headPath)) return undefined;\n\n const head = fs.readFileSync(headPath, 'utf8').trim();\n const branch = head.match(/^ref:\\s+refs\\/heads\\/(.+)$/)?.[1];\n return branch?.trim();\n}\n\nexport function discoverTaskFiles(cwd: string, fs: IFileSystem = new NodeFileSystem()): string[] {\n const tasksDir = join(cwd, TASKS_DIR);\n if (!fs.existsSync(tasksDir)) {\n return [];\n }\n\n return fs\n .readdirSync(tasksDir, { withFileTypes: true })\n .filter((entry) => entry.isFile())\n .map((entry) => entry.name)\n .filter((name) => name !== README_FILENAME && name.endsWith(MARKDOWN_EXTENSION))\n .sort((a, b) => a.localeCompare(b))\n .map((name) => join(tasksDir, name));\n}\n\nexport function parseTaskFile(\n taskPath: string,\n cwd: string,\n fs: IFileSystem = new NodeFileSystem(),\n): ITaskContextFile {\n const content = fs.readFileSync(taskPath, 'utf8');\n return {\n path: taskPath,\n relativePath: relative(cwd, taskPath),\n title: extractTitle(content, taskPath),\n status: normalizeStatus(extractMetadata(content, 'Status')),\n branch: extractMetadata(content, 'Branch'),\n scope: extractMetadata(content, 'Scope'),\n objective: extractSection(content, 'Objective'),\n openItems: extractOpenItems(content),\n };\n}\n\nexport function selectRelevantTasks(\n tasks: readonly ITaskContextFile[],\n options: ITaskSelectionOptions = {},\n): ITaskContextFile[] {\n const maxTasks = options.maxTasks ?? DEFAULT_MAX_TASKS;\n return [...tasks]\n .filter((task) => task.status !== 'completed')\n .sort(\n (left, right) =>\n taskSortScore(left, options.currentBranch) - taskSortScore(right, options.currentBranch) ||\n left.relativePath.localeCompare(right.relativePath),\n )\n .slice(Number('0'), maxTasks);\n}\n\nexport function formatTaskContext(tasks: readonly ITaskContextFile[]): string {\n return tasks.map(formatTask).join('\\n\\n');\n}\n\nexport function loadTaskContext(\n cwd: string,\n options: ITaskSelectionOptions = {},\n fs: IFileSystem = new NodeFileSystem(),\n): string {\n const currentBranch = options.currentBranch ?? readCurrentGitBranch(cwd, fs);\n const tasks = discoverTaskFiles(cwd, fs).map((path) => parseTaskFile(path, cwd, fs));\n return formatTaskContext(selectRelevantTasks(tasks, { ...options, currentBranch }));\n}\n\nexport function updateTaskFileStatus(\n taskPath: string,\n status: TTaskFileStatus,\n options: IUpdateTaskFileStatusOptions = {},\n fs: IFileSystem = new NodeFileSystem(),\n): void {\n const updated = upsertStatusLine(fs.readFileSync(taskPath, 'utf8'), status);\n const withProgress = options.progressMessage\n ? appendProgressEntry(updated, options.now ?? new Date(), options.progressMessage)\n : updated;\n fs.writeFileSync(taskPath, withProgress, 'utf8');\n}\n","import {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n writeFileSync,\n appendFileSync,\n} from 'fs';\nimport { basename, join } from 'path';\n\nexport const MEMORY_INDEX_MAX_LINES = 200;\nexport const MEMORY_INDEX_MAX_BYTES = Number('25600');\n\nexport type TMemoryType = 'user' | 'feedback' | 'project' | 'reference';\n\nexport interface IStartupMemory {\n content: string;\n path: string;\n lineCount: number;\n truncated: boolean;\n}\n\nexport interface IMemoryTopicSummary {\n name: string;\n path: string;\n}\n\nexport interface IProjectMemorySummary {\n indexPath: string;\n topicsPath: string;\n topics: IMemoryTopicSummary[];\n}\n\nexport interface IAppendMemoryInput {\n type: TMemoryType;\n topic: string;\n text: string;\n}\n\nexport interface IAppendMemoryResult {\n indexPath: string;\n topicPath: string;\n topic: string;\n deduplicated: boolean;\n}\n\nconst INDEX_FILENAME = 'MEMORY.md';\nconst TOPICS_DIRNAME = 'topics';\nconst DATE_LENGTH = 10;\nconst MAX_TOPIC_LENGTH = 80;\nconst DEFAULT_TOPIC = 'general';\nconst TOPIC_EXTENSION = '.md';\n\nconst VALID_TYPES: readonly TMemoryType[] = ['user', 'feedback', 'project', 'reference'];\n\nexport function isMemoryType(value: string): value is TMemoryType {\n return VALID_TYPES.includes(value as TMemoryType);\n}\n\nfunction memoryRoot(cwd: string): string {\n return join(cwd, '.robota', 'memory');\n}\n\nfunction truncateToUtf8Bytes(value: string, maxBytes: number): string {\n const buffer = Buffer.from(value, 'utf8');\n if (buffer.byteLength <= maxBytes) return value;\n return buffer.subarray(0, maxBytes).toString('utf8');\n}\n\nfunction limitLines(value: string, maxLines: number): { content: string; truncated: boolean } {\n const lines = value.split(/\\r?\\n/);\n const limited = lines.slice(0, maxLines);\n return {\n content: limited.join('\\n').trimEnd(),\n truncated: lines.length > maxLines,\n };\n}\n\nfunction sanitizeTopic(topic: string): string {\n const normalized = topic\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9가-힣_-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, MAX_TOPIC_LENGTH);\n return normalized || DEFAULT_TOPIC;\n}\n\nfunction formatEntry(date: Date, input: IAppendMemoryInput, topic: string): string {\n const day = date.toISOString().slice(0, DATE_LENGTH);\n const text = input.text.trim().replace(/\\s+/g, ' ');\n return `[${day}] (${input.type}/${topic}) ${text}`;\n}\n\nfunction normalizeMemoryText(text: string): string {\n return text.trim().replace(/\\s+/g, ' ');\n}\n\nexport class ProjectMemoryStore {\n private readonly cwd: string;\n private readonly now: () => Date;\n\n constructor(cwd: string, now: () => Date = () => new Date()) {\n this.cwd = cwd;\n this.now = now;\n }\n\n getIndexPath(): string {\n return join(memoryRoot(this.cwd), INDEX_FILENAME);\n }\n\n getTopicsPath(): string {\n return join(memoryRoot(this.cwd), TOPICS_DIRNAME);\n }\n\n loadStartupMemory(): IStartupMemory {\n const path = this.getIndexPath();\n if (!existsSync(path)) {\n return { content: '', path, lineCount: 0, truncated: false };\n }\n\n const raw = readFileSync(path, 'utf8');\n const byBytes = truncateToUtf8Bytes(raw, MEMORY_INDEX_MAX_BYTES);\n const byteTruncated = Buffer.byteLength(raw, 'utf8') > MEMORY_INDEX_MAX_BYTES;\n const byLines = limitLines(byBytes, MEMORY_INDEX_MAX_LINES);\n\n return {\n content: byLines.content,\n path,\n lineCount: byLines.content.length === 0 ? 0 : byLines.content.split(/\\r?\\n/).length,\n truncated: byteTruncated || byLines.truncated,\n };\n }\n\n list(): IProjectMemorySummary {\n const topicsPath = this.getTopicsPath();\n const topics = existsSync(topicsPath)\n ? readdirSync(topicsPath, { withFileTypes: true })\n .filter((entry) => entry.isFile() && entry.name.endsWith(TOPIC_EXTENSION))\n .map((entry) => ({\n name: basename(entry.name, TOPIC_EXTENSION),\n path: join(topicsPath, entry.name),\n }))\n .sort((a, b) => a.name.localeCompare(b.name))\n : [];\n\n return {\n indexPath: this.getIndexPath(),\n topicsPath,\n topics,\n };\n }\n\n readTopic(topic: string): string {\n const normalized = sanitizeTopic(topic);\n const path = join(this.getTopicsPath(), `${normalized}${TOPIC_EXTENSION}`);\n if (!existsSync(path)) return '';\n return readFileSync(path, 'utf8').trimEnd();\n }\n\n append(input: IAppendMemoryInput): IAppendMemoryResult {\n const topic = sanitizeTopic(input.topic);\n const root = memoryRoot(this.cwd);\n const topicsPath = this.getTopicsPath();\n mkdirSync(topicsPath, { recursive: true });\n\n const indexPath = this.getIndexPath();\n const topicPath = join(topicsPath, `${topic}${TOPIC_EXTENSION}`);\n const entry = formatEntry(this.now(), input, topic);\n const topicHeader = existsSync(topicPath) ? '' : `# ${topic}\\n\\n`;\n const normalizedText = normalizeMemoryText(input.text);\n\n if (existsSync(topicPath) && readFileSync(topicPath, 'utf8').includes(`) ${normalizedText}`)) {\n return { indexPath, topicPath, topic, deduplicated: true };\n }\n\n if (!existsSync(indexPath)) {\n mkdirSync(root, { recursive: true });\n writeFileSync(indexPath, '# Project Memory\\n\\n', 'utf8');\n }\n\n appendFileSync(indexPath, `- ${entry}\\n`, 'utf8');\n appendFileSync(topicPath, `${topicHeader}- ${entry}\\n`, 'utf8');\n\n return { indexPath, topicPath, topic, deduplicated: false };\n }\n}\n","/**\n * Context loader — walks up the directory tree from `cwd` collecting\n * AGENTS.md and CLAUDE.md files, then concatenates them root-first\n * so that more-specific (closer) instructions appear last.\n */\nimport { existsSync } from 'fs';\nimport { join, dirname, resolve } from 'path';\n\nimport { loadFileWithHash } from './context-file-tracker.js';\nimport { loadTaskContext } from './task-context.js';\nimport { ProjectMemoryStore } from '../memory/project-memory-store.js';\n\nimport type { IContextFileEntry } from './context-file-tracker.js';\n\nexport type { IContextFileEntry };\n\nexport interface ILoadedContext {\n /** Concatenated content of all AGENTS.md files found (root-first) */\n agentsMd: string;\n /** Concatenated content of all CLAUDE.md files found (root-first) */\n claudeMd: string;\n /** Startup project memory index loaded from .robota/memory/MEMORY.md, if present */\n memoryMd?: string;\n /** Formatted active task context loaded from .agents/tasks/*.md, if present */\n taskContext?: string;\n /** Extracted \"Compact Instructions\" section from CLAUDE.md, if present */\n compactInstructions?: string;\n /** Per-file entries for all AGENTS.md files, root-first. Present for staleness detection. */\n agentsFileEntries?: IContextFileEntry[];\n /** Per-file entries for all CLAUDE.md files, root-first. Present for staleness detection. */\n claudeFileEntries?: IContextFileEntry[];\n}\n\nconst AGENTS_FILENAME = 'AGENTS.md';\nconst CLAUDE_FILENAME = 'CLAUDE.md';\n\n/**\n * Walk up directory tree from `startDir`, collecting absolute paths of\n * files named `filename`. Stops at filesystem root.\n * Returns paths ordered root-first (farthest ancestor first).\n */\nfunction collectFilesWalkingUp(startDir: string, filename: string): string[] {\n const found: string[] = [];\n let current = resolve(startDir);\n\n let atRoot = false;\n while (!atRoot) {\n const candidate = join(current, filename);\n if (existsSync(candidate)) {\n found.push(candidate);\n }\n const parent = dirname(current);\n atRoot = parent === current;\n if (!atRoot) {\n current = parent;\n }\n }\n\n // Reverse so that root (farthest) comes first\n return found.reverse();\n}\n\n/**\n * Extract the \"Compact Instructions\" section from CLAUDE.md content.\n * Looks for a markdown heading (any level) containing \"Compact Instructions\"\n * and returns all content until the next heading of the same or higher level.\n */\nfunction extractCompactInstructions(content: string): string | undefined {\n const lines = content.split('\\n');\n let capturing = false;\n let headingLevel = 0;\n const captured: string[] = [];\n\n for (const line of lines) {\n const headingMatch = /^(#{1,6})\\s+/.exec(line);\n if (headingMatch) {\n if (capturing) {\n // Stop if we hit a heading of same or higher level\n if (headingMatch[1].length <= headingLevel) break;\n }\n if (/compact\\s+instructions/i.test(line)) {\n capturing = true;\n headingLevel = headingMatch[1].length;\n continue;\n }\n }\n if (capturing) {\n captured.push(line);\n }\n }\n\n const result = captured.join('\\n').trim();\n return result || undefined;\n}\n\n/**\n * Load all AGENTS.md and CLAUDE.md files found by walking up from `cwd`.\n * Files from higher directories appear before files from lower directories.\n *\n * @param cwd - Starting directory for the walk-up search\n */\nexport async function loadContext(cwd: string): Promise<ILoadedContext> {\n const agentsPaths = collectFilesWalkingUp(cwd, AGENTS_FILENAME);\n const claudePaths = collectFilesWalkingUp(cwd, CLAUDE_FILENAME);\n\n const agentsEntries = agentsPaths.map((p) => loadFileWithHash(p));\n const claudeEntries = claudePaths.map((p) => loadFileWithHash(p));\n\n const agentsMd = agentsEntries.map((e) => e.content).join('\\n\\n');\n const claudeMd = claudeEntries.map((e) => e.content).join('\\n\\n');\n\n const compactInstructions = extractCompactInstructions(claudeMd);\n const startupMemory = new ProjectMemoryStore(cwd).loadStartupMemory();\n const memoryMd = startupMemory.content || undefined;\n const loadedTaskContext = loadTaskContext(cwd);\n const taskContext = loadedTaskContext.trim().length > 0 ? loadedTaskContext : undefined;\n\n return {\n agentsMd,\n claudeMd,\n memoryMd,\n taskContext,\n compactInstructions,\n agentsFileEntries: agentsEntries,\n claudeFileEntries: claudeEntries,\n };\n}\n","/**\n * PluginSettingsStore — single point of read/write for plugin-related settings.\n *\n * Shared by MarketplaceClient and BundlePluginInstaller to prevent\n * concurrent writes from overwriting each other's changes.\n */\n\nimport { dirname } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { TMarketplaceSource } from './marketplace-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/** Persisted marketplace source entry. */\nexport interface IPersistedMarketplaceSource {\n source: TMarketplaceSource;\n}\n\n/** Shape of the plugin-related keys in settings.json. */\nexport interface IPluginSettings {\n enabledPlugins: Record<string, boolean>;\n extraKnownMarketplaces: Record<string, IPersistedMarketplaceSource>;\n}\n\n/** Centralized settings store for plugin configuration. */\nexport class PluginSettingsStore {\n private readonly settingsPath: string;\n private readonly fs: IFileSystem;\n\n constructor(settingsPath: string, fs: IFileSystem = new NodeFileSystem()) {\n this.settingsPath = settingsPath;\n this.fs = fs;\n }\n\n /** Read the full settings file from disk. */\n private readAll(): Record<string, unknown> {\n if (!this.fs.existsSync(this.settingsPath)) {\n return {};\n }\n try {\n const raw = this.fs.readFileSync(this.settingsPath, 'utf-8');\n const data: unknown = JSON.parse(raw);\n if (typeof data === 'object' && data !== null) {\n return data as Record<string, unknown>;\n }\n return {};\n } catch {\n // allow-fallback: corrupt settings file returns empty object to allow recovery\n return {};\n }\n }\n\n /** Write the full settings file to disk. */\n private writeAll(settings: Record<string, unknown>): void {\n const dir = dirname(this.settingsPath);\n if (!this.fs.existsSync(dir)) {\n this.fs.mkdirSync(dir, { recursive: true });\n }\n this.fs.writeFileSync(this.settingsPath, JSON.stringify(settings, null, 2), 'utf-8');\n }\n\n // --- enabledPlugins ---\n\n /** Get the enabledPlugins map. */\n getEnabledPlugins(): Record<string, boolean> {\n const settings = this.readAll();\n const ep = settings.enabledPlugins;\n if (typeof ep === 'object' && ep !== null) {\n return ep as Record<string, boolean>;\n }\n return {};\n }\n\n /** Set a single plugin's enabled state. */\n setPluginEnabled(pluginId: string, enabled: boolean): void {\n const settings = this.readAll();\n const ep = this.getEnabledPluginsFrom(settings);\n ep[pluginId] = enabled;\n settings.enabledPlugins = ep;\n this.writeAll(settings);\n }\n\n /** Remove a plugin from enabledPlugins. */\n removePluginEntry(pluginId: string): void {\n const settings = this.readAll();\n const ep = this.getEnabledPluginsFrom(settings);\n delete ep[pluginId];\n settings.enabledPlugins = ep;\n this.writeAll(settings);\n }\n\n // --- extraKnownMarketplaces ---\n\n /** Get all persisted marketplace sources. */\n getMarketplaceSources(): Record<string, IPersistedMarketplaceSource> {\n const settings = this.readAll();\n const extra = settings.extraKnownMarketplaces;\n if (typeof extra === 'object' && extra !== null) {\n return extra as Record<string, IPersistedMarketplaceSource>;\n }\n return {};\n }\n\n /** Add or update a marketplace source. */\n setMarketplaceSource(name: string, source: TMarketplaceSource): void {\n const settings = this.readAll();\n const extra = this.getMarketplaceSourcesFrom(settings);\n extra[name] = { source };\n settings.extraKnownMarketplaces = extra;\n this.writeAll(settings);\n }\n\n /** Remove a marketplace source. */\n removeMarketplaceSource(name: string): void {\n const settings = this.readAll();\n const extra = this.getMarketplaceSourcesFrom(settings);\n delete extra[name];\n settings.extraKnownMarketplaces = extra;\n this.writeAll(settings);\n }\n\n // --- helpers ---\n\n private getEnabledPluginsFrom(settings: Record<string, unknown>): Record<string, boolean> {\n const ep = settings.enabledPlugins;\n if (typeof ep === 'object' && ep !== null) {\n return ep as Record<string, boolean>;\n }\n return {};\n }\n\n private getMarketplaceSourcesFrom(\n settings: Record<string, unknown>,\n ): Record<string, IPersistedMarketplaceSource> {\n const extra = settings.extraKnownMarketplaces;\n if (typeof extra === 'object' && extra !== null) {\n return extra as Record<string, IPersistedMarketplaceSource>;\n }\n return {};\n }\n}\n","/**\n * Utility functions for bundle plugin loading.\n *\n * Provides frontmatter parsing, manifest validation, and filesystem helpers\n * used by BundlePluginLoader.\n */\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { IBundlePluginManifest } from './bundle-plugin-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/**\n * Parse simple YAML-like frontmatter from a skill markdown file.\n *\n * Handles `key: value` and `key: [item1, item2]` patterns.\n * Returns the parsed metadata and the remaining content after the frontmatter block.\n */\nexport function parseSkillFrontmatter(raw: string): {\n metadata: Record<string, unknown>;\n content: string;\n} {\n const trimmed = raw.trimStart();\n if (!trimmed.startsWith('---')) {\n return { metadata: {}, content: raw };\n }\n\n const endIndex = trimmed.indexOf('---', 3);\n if (endIndex === -1) {\n return { metadata: {}, content: raw };\n }\n\n const frontmatterBlock = trimmed.slice(3, endIndex).trim();\n const content = trimmed.slice(endIndex + 3).trimStart();\n const metadata: Record<string, unknown> = {};\n\n for (const line of frontmatterBlock.split('\\n')) {\n const colonIndex = line.indexOf(':');\n if (colonIndex === -1) continue;\n\n const key = line.slice(0, colonIndex).trim();\n let value: unknown = line.slice(colonIndex + 1).trim();\n\n // Parse inline array: [item1, item2]\n if (typeof value === 'string' && value.startsWith('[') && value.endsWith(']')) {\n const inner = value.slice(1, -1);\n value = inner\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n }\n\n if (key) {\n metadata[key] = value;\n }\n }\n\n return { metadata, content };\n}\n\n/**\n * Validate that a parsed JSON object has the required manifest fields.\n * Returns the typed manifest or null if invalid.\n */\nexport function validateManifest(data: unknown): IBundlePluginManifest | null {\n if (typeof data !== 'object' || data === null) return null;\n\n const obj = data as Record<string, unknown>;\n if (typeof obj.name !== 'string') return null;\n if (typeof obj.version !== 'string') return null;\n if (typeof obj.description !== 'string') return null;\n\n const features =\n typeof obj.features === 'object' && obj.features !== null\n ? (obj.features as Record<string, unknown>)\n : {};\n\n return {\n name: obj.name,\n version: obj.version,\n description: obj.description,\n features: {\n commands: features.commands === true ? true : undefined,\n agents: features.agents === true ? true : undefined,\n skills: features.skills === true ? true : undefined,\n hooks: features.hooks === true ? true : undefined,\n mcp: features.mcp === true ? true : undefined,\n },\n };\n}\n\n/**\n * Get sorted subdirectories from a directory.\n * Returns directory names sorted lexicographically.\n */\nexport function getSortedSubdirs(\n dirPath: string,\n fs: IFileSystem = new NodeFileSystem(),\n): string[] {\n if (!fs.existsSync(dirPath)) return [];\n try {\n const entries = fs.readdirSync(dirPath, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .sort();\n } catch {\n // allow-fallback: unreadable directory returns empty list to allow plugin discovery to continue\n return [];\n }\n}\n","/**\n * BundlePluginLoader — discovers and loads directory-based bundle plugins.\n *\n * Scans the cache directory (`<pluginsDir>/cache/<marketplace>/<plugin>/<version>/`)\n * for subdirectories containing `.claude-plugin/plugin.json`,\n * reads manifests, loads skills (with frontmatter parsing), hooks, and agent definitions.\n *\n * For each plugin, the latest version directory (lexicographically last) is loaded.\n */\n\nimport { join } from 'node:path';\n\nimport {\n parseSkillFrontmatter,\n validateManifest,\n getSortedSubdirs,\n} from './bundle-plugin-utils.js';\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type {\n IBundlePluginManifest,\n IBundleSkill,\n ILoadedBundlePlugin,\n TEnabledPlugins,\n} from './bundle-plugin-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/** Loader for directory-based bundle plugins from the cache directory. */\nexport class BundlePluginLoader {\n private readonly pluginsDir: string;\n private readonly enabledPlugins: TEnabledPlugins;\n private readonly fs: IFileSystem;\n\n constructor(\n pluginsDir: string,\n enabledPlugins?: TEnabledPlugins,\n fs: IFileSystem = new NodeFileSystem(),\n ) {\n this.pluginsDir = pluginsDir;\n this.enabledPlugins = enabledPlugins ?? {};\n this.fs = fs;\n }\n\n /** Load all discovered and enabled bundle plugins (sync). */\n loadPluginsSync(): ILoadedBundlePlugin[] {\n return this.discoverAndLoad();\n }\n\n /** Load all discovered and enabled bundle plugins (async wrapper). */\n async loadAll(): Promise<ILoadedBundlePlugin[]> {\n return this.discoverAndLoad();\n }\n\n /**\n * Discover and load plugins from the cache directory.\n *\n * Directory structure: `<pluginsDir>/cache/<marketplace>/<plugin>/<version>/`\n * For each marketplace/plugin pair, the latest version (lexicographically last) is loaded.\n */\n private discoverAndLoad(): ILoadedBundlePlugin[] {\n const cacheDir = join(this.pluginsDir, 'cache');\n if (!this.fs.existsSync(cacheDir)) {\n return [];\n }\n\n const results: ILoadedBundlePlugin[] = [];\n\n // Iterate marketplaces\n const marketplaces = getSortedSubdirs(cacheDir, this.fs);\n for (const marketplace of marketplaces) {\n const marketplaceDir = join(cacheDir, marketplace);\n const plugins = getSortedSubdirs(marketplaceDir, this.fs);\n\n for (const pluginName of plugins) {\n const pluginDir = join(marketplaceDir, pluginName);\n const versions = getSortedSubdirs(pluginDir, this.fs);\n\n if (versions.length === 0) continue;\n\n // Use the latest version (lexicographically last)\n const latestVersion = versions[versions.length - 1];\n const versionDir = join(pluginDir, latestVersion);\n\n const manifestPath = join(versionDir, '.claude-plugin', 'plugin.json');\n if (!this.fs.existsSync(manifestPath)) continue;\n\n const manifest = this.readManifest(manifestPath);\n if (!manifest) continue;\n\n // Check enabled/disabled state using pluginName@marketplace key\n const pluginId = `${manifest.name}@${marketplace}`;\n if (this.isDisabled(pluginId, manifest.name)) continue;\n\n const loaded = this.loadPlugin(versionDir, manifest);\n results.push(loaded);\n }\n }\n\n return results;\n }\n\n /** Read and validate a plugin.json manifest. Returns null if the manifest structure is invalid. */\n private readManifest(path: string): IBundlePluginManifest | null {\n const raw = this.fs.readFileSync(path, 'utf-8');\n const data: unknown = JSON.parse(raw);\n return validateManifest(data);\n }\n\n /**\n * Check if a plugin is explicitly disabled.\n * Checks both `name@marketplace` and `name` keys.\n * Plugins not listed in enabledPlugins are enabled by default.\n */\n private isDisabled(pluginId: string, pluginName: string): boolean {\n if (pluginId in this.enabledPlugins) {\n return this.enabledPlugins[pluginId] === false;\n }\n if (pluginName in this.enabledPlugins) {\n return this.enabledPlugins[pluginName] === false;\n }\n\n return false;\n }\n\n /** Load a single plugin's skills, hooks, agents, and MCP config. */\n private loadPlugin(pluginDir: string, manifest: IBundlePluginManifest): ILoadedBundlePlugin {\n return {\n manifest,\n skills: this.loadSkills(pluginDir, manifest.name),\n commands: this.loadCommands(pluginDir, manifest.name),\n hooks: this.loadHooks(pluginDir),\n mcpConfig: this.loadMcpConfig(pluginDir),\n agents: this.loadAgents(pluginDir),\n pluginDir,\n };\n }\n\n /** Load skills from the plugin's skills/ directory. */\n private loadSkills(pluginDir: string, pluginName: string): IBundleSkill[] {\n const skillsDir = join(pluginDir, 'skills');\n if (!this.fs.existsSync(skillsDir)) return [];\n\n const entries = this.fs.readdirSync(skillsDir, { withFileTypes: true });\n const skills: IBundleSkill[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const skillFile = join(skillsDir, entry.name, 'SKILL.md');\n if (!this.fs.existsSync(skillFile)) continue;\n\n const raw = this.fs.readFileSync(skillFile, 'utf-8');\n const { metadata, content } = parseSkillFrontmatter(raw);\n\n const description = typeof metadata.description === 'string' ? metadata.description : '';\n\n const skill: IBundleSkill = {\n name: entry.name,\n description,\n skillContent: content,\n ...metadata,\n };\n\n skills.push(skill);\n }\n\n return skills;\n }\n\n /** Load commands from the plugin's commands/ directory (flat .md files). */\n private loadCommands(pluginDir: string, pluginName: string): IBundleSkill[] {\n const commandsDir = join(pluginDir, 'commands');\n if (!this.fs.existsSync(commandsDir)) return [];\n\n const entries = this.fs.readdirSync(commandsDir, { withFileTypes: true });\n const commands: IBundleSkill[] = [];\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md')) continue;\n\n const raw = this.fs.readFileSync(join(commandsDir, entry.name), 'utf-8');\n const { metadata, content } = parseSkillFrontmatter(raw);\n\n const name =\n typeof metadata.name === 'string' ? metadata.name : entry.name.replace(/\\.md$/, '');\n const description = typeof metadata.description === 'string' ? metadata.description : '';\n\n commands.push({\n ...metadata,\n name: `${pluginName}:${name}`,\n description,\n skillContent: content,\n });\n }\n\n return commands;\n }\n\n /** Load hooks from hooks/hooks.json if present. */\n private loadHooks(pluginDir: string): Record<string, unknown> {\n const hooksPath = join(pluginDir, 'hooks', 'hooks.json');\n if (!this.fs.existsSync(hooksPath)) return {};\n\n const raw = this.fs.readFileSync(hooksPath, 'utf-8');\n const data: unknown = JSON.parse(raw);\n if (typeof data === 'object' && data !== null) {\n return data as Record<string, unknown>;\n }\n return {};\n }\n\n /** Load MCP server configuration from `.mcp.json` at the plugin root if present. */\n private loadMcpConfig(pluginDir: string): unknown | undefined {\n const mcpPath = join(pluginDir, '.mcp.json');\n if (!this.fs.existsSync(mcpPath)) return undefined;\n\n const raw = this.fs.readFileSync(mcpPath, 'utf-8');\n return JSON.parse(raw) as unknown;\n }\n\n /** Load agent definitions from agents/ directory if present. */\n private loadAgents(pluginDir: string): string[] {\n const agentsDir = join(pluginDir, 'agents');\n if (!this.fs.existsSync(agentsDir)) return [];\n\n const entries = this.fs.readdirSync(agentsDir, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory() || e.name.endsWith('.md'))\n .map((e) => e.name.replace(/\\.md$/, ''));\n }\n}\n","/**\n * BundlePluginInstaller — installs, uninstalls, enables, and disables bundle plugins.\n *\n * Resolves plugin sources from marketplace manifests, copies/clones to the\n * cache directory, and tracks installations in `installed_plugins.json`.\n */\n\nimport { join, dirname } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { MarketplaceClient, IMarketplacePluginEntry, TExecFn } from './marketplace-client.js';\nimport type { PluginSettingsStore } from './plugin-settings-store.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/** Record of an installed plugin in installed_plugins.json. */\nexport interface IInstalledPluginRecord {\n pluginName: string;\n marketplace: string;\n version: string;\n installPath: string;\n installedAt: string;\n}\n\n/** Shape of installed_plugins.json. */\nexport type TInstalledPluginsRegistry = Record<string, IInstalledPluginRecord>;\n\n/** Options for constructing a BundlePluginInstaller. */\nexport interface IBundlePluginInstallerOptions {\n /** Base plugins directory (e.g., `~/.robota/plugins`). */\n pluginsDir: string;\n /** Shared settings store for enable/disable persistence. */\n settingsStore: PluginSettingsStore;\n /** MarketplaceClient for reading marketplace manifests. */\n marketplaceClient: MarketplaceClient;\n /** Shell exec adapter — must be provided at composition root (e.g., execSync). */\n exec: TExecFn;\n /** File system adapter for testability. */\n fs?: IFileSystem;\n}\n\n/** Default git clone timeout in milliseconds (60 seconds). */\nconst GIT_CLONE_TIMEOUT_MS = 60_000;\n\n/** Installs, uninstalls, enables, and disables bundle plugins. */\nexport class BundlePluginInstaller {\n private readonly pluginsDir: string;\n private readonly cacheDir: string;\n private readonly registryPath: string;\n private readonly settingsStore: PluginSettingsStore;\n private readonly marketplaceClient: MarketplaceClient;\n private readonly exec: TExecFn;\n private readonly fs: IFileSystem;\n\n constructor(options: IBundlePluginInstallerOptions) {\n this.pluginsDir = options.pluginsDir;\n this.cacheDir = join(this.pluginsDir, 'cache');\n this.registryPath = join(this.pluginsDir, 'installed_plugins.json');\n this.settingsStore = options.settingsStore;\n this.marketplaceClient = options.marketplaceClient;\n this.exec = options.exec;\n this.fs = options.fs ?? new NodeFileSystem();\n }\n\n /**\n * Install a plugin from a marketplace.\n *\n * 1. Read marketplace manifest to find the plugin entry.\n * 2. Resolve source (relative path, github, or url).\n * 3. Copy/clone to `cache/<marketplace>/<plugin>/<version>/`.\n * 4. Record in `installed_plugins.json`.\n */\n async install(pluginName: string, marketplaceName: string): Promise<void> {\n // Read marketplace manifest\n const manifest = this.marketplaceClient.fetchManifest(marketplaceName);\n const entry = manifest.plugins.find((p) => p.name === pluginName);\n if (!entry) {\n throw new Error(`Plugin \"${pluginName}\" not found in marketplace \"${marketplaceName}\"`);\n }\n\n // Determine version\n const version = this.resolveVersion(entry, marketplaceName);\n\n // Target directory: cache/<marketplace>/<plugin>/<version>/\n const targetDir = join(this.cacheDir, marketplaceName, pluginName, version);\n\n if (this.fs.existsSync(targetDir)) {\n throw new Error(\n `Plugin \"${pluginName}\" version \"${version}\" is already installed from \"${marketplaceName}\"`,\n );\n }\n\n // Resolve and install from source\n this.resolveAndInstall(entry.source, marketplaceName, pluginName, targetDir);\n\n // Record in installed_plugins.json\n const pluginId = `${pluginName}@${marketplaceName}`;\n const registry = this.readRegistry();\n registry[pluginId] = {\n pluginName,\n marketplace: marketplaceName,\n version,\n installPath: targetDir,\n installedAt: new Date().toISOString(),\n };\n this.writeRegistry(registry);\n }\n\n /**\n * Uninstall a plugin.\n * Removes from cache and from installed_plugins.json.\n */\n async uninstall(pluginId: string): Promise<void> {\n const registry = this.readRegistry();\n const record = registry[pluginId];\n\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed`);\n }\n\n // Remove the installed directory\n if (this.fs.existsSync(record.installPath)) {\n this.fs.rmSync(record.installPath, { recursive: true, force: true });\n }\n\n // Remove from registry\n delete registry[pluginId];\n this.writeRegistry(registry);\n\n // Remove from enabled plugins settings\n this.settingsStore.removePluginEntry(pluginId);\n }\n\n /** Enable a plugin by setting its enabledPlugins entry to true. */\n async enable(pluginId: string): Promise<void> {\n this.settingsStore.setPluginEnabled(pluginId, true);\n }\n\n /** Disable a plugin by setting its enabledPlugins entry to false. */\n async disable(pluginId: string): Promise<void> {\n this.settingsStore.setPluginEnabled(pluginId, false);\n }\n\n /** Get all installed plugins. */\n getInstalledPlugins(): TInstalledPluginsRegistry {\n return this.readRegistry();\n }\n\n /** Get plugins installed from a specific marketplace. */\n getPluginsByMarketplace(marketplaceName: string): IInstalledPluginRecord[] {\n const registry = this.readRegistry();\n return Object.values(registry).filter((r) => r.marketplace === marketplaceName);\n }\n\n // --- Private helpers ---\n\n /** Resolve the version for a plugin entry. */\n private resolveVersion(entry: IMarketplacePluginEntry, marketplaceName: string): string {\n // If the entry has an explicit version field (the manifest may include it),\n // use it. Otherwise use git SHA.\n const entryWithVersion = entry as unknown as Record<string, unknown>;\n if (typeof entryWithVersion.version === 'string' && entryWithVersion.version) {\n return entryWithVersion.version as string;\n }\n return this.marketplaceClient.getMarketplaceSha(marketplaceName);\n }\n\n /**\n * Normalize source object — Claude Code manifests use `source` key instead of `type`.\n * e.g., { source: \"url\", url: \"...\" } → { type: \"url\", url: \"...\" }\n */\n private normalizeSource(\n source: IMarketplacePluginEntry['source'],\n ): IMarketplacePluginEntry['source'] {\n if (typeof source === 'string') return source;\n const obj = source as Record<string, unknown>;\n if (!obj.type && typeof obj.source === 'string') {\n return { ...obj, type: obj.source } as IMarketplacePluginEntry['source'];\n }\n return source;\n }\n\n /** Resolve the source and install the plugin. */\n private resolveAndInstall(\n rawSource: IMarketplacePluginEntry['source'],\n marketplaceName: string,\n pluginName: string,\n targetDir: string,\n ): void {\n this.fs.mkdirSync(targetDir, { recursive: true });\n\n const source = this.normalizeSource(rawSource);\n\n try {\n if (typeof source === 'string') {\n // Relative path — copy from the marketplace clone\n const marketplaceDir = this.marketplaceClient.getMarketplaceDir(marketplaceName);\n const sourcePath = join(marketplaceDir, source);\n\n if (!this.fs.existsSync(sourcePath)) {\n throw new Error(\n `Plugin source path \"${source}\" not found in marketplace \"${marketplaceName}\"`,\n );\n }\n\n this.fs.cpSync(sourcePath, targetDir, { recursive: true });\n } else if (source.type === 'github') {\n // Clone from GitHub\n const repoUrl = `https://github.com/${source.repo}.git`;\n this.cloneToDir(repoUrl, targetDir, pluginName);\n } else if (\n source.type === 'url' &&\n typeof source.url === 'string' &&\n source.url.endsWith('.git')\n ) {\n // Git URL — clone directly\n this.cloneToDir(source.url, targetDir, pluginName);\n } else if (source.type === 'url') {\n throw new Error(`URL source \"${source.url}\" is not a git repository (must end with .git)`);\n } else {\n throw new Error(`Unknown source type: ${JSON.stringify(source)}`);\n }\n } catch (err) {\n // Clean up empty target directory on failure\n if (this.fs.existsSync(targetDir)) {\n this.fs.rmSync(targetDir, { recursive: true, force: true });\n }\n throw err;\n }\n }\n\n /** Clone a git repository to the target directory. */\n private cloneToDir(repoUrl: string, targetDir: string, pluginName: string): void {\n // Remove the directory first since mkdirSync already created it\n this.fs.rmSync(targetDir, { recursive: true, force: true });\n\n const command = `git clone --depth 1 ${repoUrl} ${targetDir}`;\n try {\n this.exec(command, { timeout: GIT_CLONE_TIMEOUT_MS, stdio: 'pipe' });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to clone plugin \"${pluginName}\": ${message}`);\n }\n }\n\n /** Read the installed_plugins.json registry. */\n private readRegistry(): TInstalledPluginsRegistry {\n if (!this.fs.existsSync(this.registryPath)) {\n return {};\n }\n try {\n const raw = this.fs.readFileSync(this.registryPath, 'utf-8');\n const data: unknown = JSON.parse(raw);\n if (typeof data === 'object' && data !== null) {\n return data as TInstalledPluginsRegistry;\n }\n return {};\n } catch {\n // allow-fallback: corrupt installed_plugins.json returns empty registry to allow recovery\n return {};\n }\n }\n\n /** Write the installed_plugins.json registry. */\n private writeRegistry(registry: TInstalledPluginsRegistry): void {\n const dir = dirname(this.registryPath);\n if (!this.fs.existsSync(dir)) {\n this.fs.mkdirSync(dir, { recursive: true });\n }\n this.fs.writeFileSync(this.registryPath, JSON.stringify(registry, null, 2), 'utf-8');\n }\n}\n","/**\n * Marketplace registry I/O helpers.\n *\n * Manages read/write operations for `known_marketplaces.json` and\n * cleanup of installed plugins when a marketplace is removed.\n */\n\nimport { join, dirname } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type { TKnownMarketplacesRegistry } from './marketplace-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\n/** Read the known_marketplaces.json registry. Returns empty object if missing or corrupt. */\nexport function readRegistry(\n registryPath: string,\n fs: IFileSystem = new NodeFileSystem(),\n): TKnownMarketplacesRegistry {\n if (!fs.existsSync(registryPath)) {\n return {};\n }\n try {\n const raw = fs.readFileSync(registryPath, 'utf-8');\n const data: unknown = JSON.parse(raw);\n if (typeof data === 'object' && data !== null) {\n return data as TKnownMarketplacesRegistry;\n }\n return {};\n } catch {\n // allow-fallback: corrupt registry file returns empty object to allow recovery\n return {};\n }\n}\n\n/** Write the known_marketplaces.json registry, creating parent dirs if needed. */\nexport function writeRegistry(\n registryPath: string,\n registry: TKnownMarketplacesRegistry,\n fs: IFileSystem = new NodeFileSystem(),\n): void {\n const dir = dirname(registryPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2), 'utf-8');\n}\n\n/**\n * Remove all installed plugins that belong to a given marketplace.\n * Reads installed_plugins.json, deletes cache directories for matching plugins,\n * and updates the registry.\n */\nexport function removeInstalledPluginsForMarketplace(\n pluginsDir: string,\n marketplaceName: string,\n fs: IFileSystem = new NodeFileSystem(),\n): void {\n const installedPath = join(pluginsDir, 'installed_plugins.json');\n if (!fs.existsSync(installedPath)) return;\n\n let registry: Record<string, { marketplace?: string; installPath?: string }>;\n try {\n const raw = fs.readFileSync(installedPath, 'utf-8');\n const data: unknown = JSON.parse(raw);\n if (typeof data !== 'object' || data === null) return;\n registry = data as Record<string, { marketplace?: string; installPath?: string }>;\n } catch {\n // allow-fallback: corrupt installed_plugins.json is skipped, no plugins removed\n return;\n }\n\n let changed = false;\n for (const [pluginId, record] of Object.entries(registry)) {\n if (record.marketplace === marketplaceName) {\n // Remove the cache directory for this plugin\n if (record.installPath && fs.existsSync(record.installPath)) {\n fs.rmSync(record.installPath, { recursive: true, force: true });\n }\n delete registry[pluginId];\n changed = true;\n }\n }\n\n if (changed) {\n const dir = dirname(installedPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(installedPath, JSON.stringify(registry, null, 2), 'utf-8');\n }\n}\n","/**\n * MarketplaceClient — manages marketplace registries via shallow git clones.\n *\n * Marketplaces are git repositories containing `.claude-plugin/marketplace.json`.\n * They are cloned to `~/.robota/plugins/marketplaces/<name>/` and tracked\n * in `known_marketplaces.json`.\n */\n\nimport { join } from 'node:path';\n\nimport {\n readRegistry,\n writeRegistry,\n removeInstalledPluginsForMarketplace,\n} from './marketplace-registry.js';\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type {\n TMarketplaceSource,\n IMarketplacePluginEntry,\n IMarketplaceManifest,\n IMarketplaceClientOptions,\n TExecFn,\n} from './marketplace-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\nexport type {\n TMarketplaceSource,\n IMarketplacePluginEntry,\n IMarketplaceManifest,\n IMarketplaceClientOptions,\n TExecFn,\n} from './marketplace-types.js';\nexport type { IKnownMarketplaceEntry, TKnownMarketplacesRegistry } from './marketplace-types.js';\n\n/** Default git operation timeout in milliseconds (60 seconds). */\nconst GIT_TIMEOUT_MS = 60_000;\n\n/** Manages marketplace registries via shallow git clones. */\nexport class MarketplaceClient {\n private readonly pluginsDir: string;\n private readonly exec: TExecFn;\n private readonly marketplacesDir: string;\n private readonly registryPath: string;\n private readonly fs: IFileSystem;\n\n constructor(options: IMarketplaceClientOptions & { fs?: IFileSystem }) {\n this.pluginsDir = options.pluginsDir;\n this.exec = options.exec;\n this.marketplacesDir = join(this.pluginsDir, 'marketplaces');\n this.registryPath = join(this.pluginsDir, 'known_marketplaces.json');\n this.fs = options.fs ?? new NodeFileSystem();\n }\n\n /**\n * Add a marketplace by cloning its repository.\n *\n * 1. Shallow git clone (`--depth 1`) to `marketplaces/<name>/`.\n * 2. Read `.claude-plugin/marketplace.json` for the `name` field.\n * 3. Register in `known_marketplaces.json`.\n *\n * Returns the registered marketplace name from the manifest.\n */\n addMarketplace(source: TMarketplaceSource): string {\n // Clone to a temp name first, then read the manifest to get the real name\n const tempName = 'temp-' + Date.now().toString(36);\n const tempDir = join(this.marketplacesDir, tempName);\n\n this.fs.mkdirSync(this.marketplacesDir, { recursive: true });\n\n if (source.type === 'local') {\n if (!this.fs.existsSync(source.path)) {\n throw new Error(`Local marketplace path does not exist: ${source.path}`);\n }\n this.fs.cpSync(source.path, tempDir, { recursive: true });\n } else {\n const cloneUrl = this.resolveCloneUrl(source);\n const command = `git clone --depth 1 ${cloneUrl} ${tempDir}`;\n try {\n this.exec(command, { timeout: GIT_TIMEOUT_MS, stdio: 'pipe' });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to clone marketplace: ${message}`);\n }\n }\n\n const manifestPath = join(tempDir, '.claude-plugin', 'marketplace.json');\n if (!this.fs.existsSync(manifestPath)) {\n this.fs.rmSync(tempDir, { recursive: true, force: true });\n throw new Error(\n source.type === 'local'\n ? 'Local directory does not contain .claude-plugin/marketplace.json'\n : 'Cloned repository does not contain .claude-plugin/marketplace.json',\n );\n }\n\n const manifest = this.readManifestFromPath(manifestPath);\n const name = manifest.name;\n\n if (!name) {\n this.fs.rmSync(tempDir, { recursive: true, force: true });\n throw new Error('Marketplace manifest does not contain a \"name\" field');\n }\n\n const registry = readRegistry(this.registryPath, this.fs);\n if (registry[name]) {\n this.fs.rmSync(tempDir, { recursive: true, force: true });\n throw new Error(`Marketplace \"${name}\" already exists`);\n }\n\n const finalDir = join(this.marketplacesDir, name);\n this.fs.renameSync(tempDir, finalDir);\n\n registry[name] = {\n source,\n installLocation: finalDir,\n lastUpdated: new Date().toISOString(),\n };\n writeRegistry(this.registryPath, registry, this.fs);\n\n return name;\n }\n\n /**\n * Remove a marketplace.\n * Uninstalls all plugins from that marketplace, then deletes the clone directory\n * and removes from the registry.\n */\n removeMarketplace(name: string): void {\n const registry = readRegistry(this.registryPath, this.fs);\n const entry = registry[name];\n if (!entry) {\n throw new Error(`Marketplace \"${name}\" not found`);\n }\n\n removeInstalledPluginsForMarketplace(this.pluginsDir, name, this.fs);\n\n if (this.fs.existsSync(entry.installLocation)) {\n this.fs.rmSync(entry.installLocation, { recursive: true, force: true });\n }\n\n delete registry[name];\n writeRegistry(this.registryPath, registry, this.fs);\n }\n\n /**\n * Update a marketplace by running git pull on its clone.\n * The manifest is re-read from disk on demand (via fetchManifest), so the\n * updated manifest is automatically available after pull.\n */\n updateMarketplace(name: string): void {\n const registry = readRegistry(this.registryPath, this.fs);\n const entry = registry[name];\n if (!entry) {\n throw new Error(`Marketplace \"${name}\" not found`);\n }\n\n if (!this.fs.existsSync(entry.installLocation)) {\n throw new Error(`Marketplace directory for \"${name}\" does not exist`);\n }\n\n if (entry.source.type === 'local') {\n const localSource = entry.source as { type: 'local'; path: string };\n if (!this.fs.existsSync(localSource.path)) {\n throw new Error(`Local marketplace path does not exist: ${localSource.path}`);\n }\n this.fs.rmSync(entry.installLocation, { recursive: true, force: true });\n this.fs.cpSync(localSource.path, entry.installLocation, { recursive: true });\n } else {\n const command = `git -C ${entry.installLocation} pull`;\n try {\n this.exec(command, { timeout: GIT_TIMEOUT_MS, stdio: 'pipe' });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to update marketplace \"${name}\": ${message}`);\n }\n }\n\n entry.lastUpdated = new Date().toISOString();\n writeRegistry(this.registryPath, registry, this.fs);\n }\n\n /** List all registered marketplaces. */\n listMarketplaces(): Array<{ name: string; source: TMarketplaceSource; lastUpdated: string }> {\n const registry = readRegistry(this.registryPath, this.fs);\n return Object.entries(registry).map(([name, entry]) => ({\n name,\n source: entry.source,\n lastUpdated: entry.lastUpdated,\n }));\n }\n\n /** Read the marketplace manifest from a registered marketplace's clone. */\n fetchManifest(marketplaceName: string): IMarketplaceManifest {\n const registry = readRegistry(this.registryPath, this.fs);\n const entry = registry[marketplaceName];\n if (!entry) {\n throw new Error(`Marketplace \"${marketplaceName}\" not found`);\n }\n\n const manifestPath = join(entry.installLocation, '.claude-plugin', 'marketplace.json');\n if (!this.fs.existsSync(manifestPath)) {\n throw new Error(\n `Marketplace \"${marketplaceName}\" does not contain .claude-plugin/marketplace.json`,\n );\n }\n\n return this.readManifestFromPath(manifestPath);\n }\n\n /** Get the clone directory path for a registered marketplace. */\n getMarketplaceDir(name: string): string {\n const registry = readRegistry(this.registryPath, this.fs);\n const entry = registry[name];\n if (!entry) {\n throw new Error(`Marketplace \"${name}\" not found`);\n }\n return entry.installLocation;\n }\n\n /**\n * Get the current git SHA (first 12 chars) for a marketplace clone.\n * Used as a version identifier when plugins lack explicit versions.\n */\n getMarketplaceSha(name: string): string {\n const dir = this.getMarketplaceDir(name);\n try {\n const result = this.exec(`git -C ${dir} rev-parse HEAD`, {\n timeout: GIT_TIMEOUT_MS,\n stdio: 'pipe',\n });\n return result.toString().trim().slice(0, 12);\n } catch {\n // allow-fallback: git SHA unavailable returns 'unknown' as version identifier\n return 'unknown';\n }\n }\n\n /** List all available plugins across all marketplaces. */\n listAvailablePlugins(): Array<IMarketplacePluginEntry & { marketplace: string }> {\n const results: Array<IMarketplacePluginEntry & { marketplace: string }> = [];\n const marketplaces = this.listMarketplaces();\n\n for (const { name } of marketplaces) {\n try {\n const manifest = this.fetchManifest(name);\n for (const plugin of manifest.plugins) {\n results.push({ ...plugin, marketplace: name });\n }\n } catch {\n // allow-fallback: failed marketplace is skipped to allow other marketplaces to load\n // Skip failed marketplaces\n }\n }\n\n return results;\n }\n\n // --- Private helpers ---\n\n /** Resolve a marketplace source to a git clone URL. */\n private resolveCloneUrl(source: TMarketplaceSource): string {\n switch (source.type) {\n case 'github':\n return `https://github.com/${source.repo}.git`;\n case 'git':\n return source.url;\n case 'local':\n throw new Error('Local source type does not use git cloning');\n case 'url':\n throw new Error('URL marketplace source is not yet supported');\n }\n }\n\n /** Read and parse a marketplace.json from a file path. */\n private readManifestFromPath(path: string): IMarketplaceManifest {\n const raw = this.fs.readFileSync(path, 'utf-8');\n const data: unknown = JSON.parse(raw);\n\n if (typeof data !== 'object' || data === null) {\n throw new Error('Invalid marketplace manifest: not an object');\n }\n\n const obj = data as Record<string, unknown>;\n if (typeof obj.name !== 'string') {\n throw new Error('Invalid marketplace manifest: missing \"name\" field');\n }\n\n return data as IMarketplaceManifest;\n }\n}\n","/**\n * Plugin hooks merger — merges plugin hooks into session config.\n */\n\nimport { join, dirname } from 'node:path';\n\nimport type { ILoadedBundlePlugin } from './bundle-plugin-types.js';\nimport type { THooksConfig } from '@robota-sdk/agent-core';\n\n/** Build plugin env vars for a plugin. */\nfunction buildPluginEnv(plugin: ILoadedBundlePlugin): Record<string, string> {\n const dataDir = join(dirname(dirname(plugin.pluginDir)), 'data', plugin.manifest.name);\n return {\n CLAUDE_PLUGIN_ROOT: plugin.pluginDir,\n CLAUDE_PLUGIN_PATH: plugin.pluginDir,\n CLAUDE_PLUGIN_DATA: dataDir,\n };\n}\n\ninterface IHookGroup {\n hooks?: Array<{ command?: string; [key: string]: string | undefined }>;\n env?: Record<string, string>;\n [key: string]: unknown;\n}\n\n/** Replace ${CLAUDE_PLUGIN_ROOT} in hook command strings. */\nfunction resolvePluginRoot(group: IHookGroup, pluginDir: string): IHookGroup {\n if (Array.isArray(group.hooks)) {\n return {\n ...group,\n hooks: group.hooks.map((h) => {\n if (typeof h.command === 'string') {\n return {\n ...h,\n command: h.command.replace(/\\$\\{CLAUDE_PLUGIN_ROOT\\}/g, pluginDir),\n };\n }\n return h;\n }),\n };\n }\n return group;\n}\n\n/** Merge plugin hooks into a single THooksConfig. */\nexport function mergePluginHooks(plugins: ILoadedBundlePlugin[]): THooksConfig {\n const merged: Record<string, IHookGroup[]> = {};\n for (const plugin of plugins) {\n const hooksObj = plugin.hooks as Record<string, IHookGroup | IHookGroup[]> | undefined;\n if (!hooksObj) continue;\n const pluginEnv = buildPluginEnv(plugin);\n const innerHooks = (hooksObj.hooks ?? hooksObj) as Record<string, IHookGroup[]>;\n for (const [event, groups] of Object.entries(innerHooks)) {\n if (!Array.isArray(groups)) continue;\n if (!merged[event]) merged[event] = [];\n const resolved = groups.map((group) => {\n const r = resolvePluginRoot(group, plugin.pluginDir);\n r.env = pluginEnv;\n return r;\n });\n merged[event]!.push(...resolved);\n }\n }\n return merged as THooksConfig;\n}\n\n/** Merge plugin hooks into config hooks (plugin hooks have lowest priority). */\nexport function mergeHooksIntoConfig(\n configHooks: Record<string, IHookGroup[]> | undefined,\n pluginHooks: Record<string, IHookGroup[]>,\n): Record<string, IHookGroup[]> | undefined {\n const pluginKeys = Object.keys(pluginHooks);\n if (pluginKeys.length === 0) return configHooks;\n const merged: Record<string, IHookGroup[]> = {};\n for (const [event, groups] of Object.entries(pluginHooks)) {\n merged[event] = [...groups];\n }\n if (configHooks) {\n for (const [event, groups] of Object.entries(configHooks)) {\n if (!Array.isArray(groups)) continue;\n if (!merged[event]) merged[event] = [];\n merged[event]!.push(...groups);\n }\n }\n return merged;\n}\n","/**\n * Session initialization helpers for InteractiveSession.\n *\n * Handles async config/context loading, plugin merging, and session creation.\n * Option interfaces live in interactive-session-options.ts.\n * Session restore logic lives in interactive-session-restore.ts.\n */\n\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nimport { FileSessionLogger } from '@robota-sdk/agent-session';\nimport { applyWorkspaceManifest } from '@robota-sdk/agent-tools';\n\nimport { NOOP_TERMINAL } from './interactive-session-execution.js';\nimport { detectProject } from '../context/project-detector.js';\nimport { projectPaths } from '../paths.js';\nimport { injectSavedMessage } from './interactive-session-restore.js';\nimport { createSession } from '../assembly/index.js';\nimport { EditCheckpointStore } from '../checkpoints/edit-checkpoint-store.js';\nimport { loadConfig } from '../config/config-loader.js';\nimport { loadContext } from '../context/context-loader.js';\nimport { BundlePluginLoader } from '../plugins/index.js';\nimport { mergePluginHooks, mergeHooksIntoConfig } from '../plugins/plugin-hooks-merger.js';\n\nimport type {\n IInteractiveSessionStandardOptions,\n IInitOptions,\n} from './interactive-session-options.js';\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { ICommandResult } from '../commands/index.js';\nimport type { IResolvedConfig } from '../config/config-types.js';\nimport type { IContextFileEntry } from '../context/context-loader.js';\nimport type { IContextWindowState, TToolArgs, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type { ICompactEvent } from '@robota-sdk/agent-session';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport type {\n IInteractiveSessionStandardOptions,\n IInteractiveSessionInjectedOptions,\n TInteractiveSessionOptions,\n IInitOptions,\n} from './interactive-session-options.js';\nexport { injectSavedMessage, loadSessionRecord } from './interactive-session-restore.js';\n\n/** Return value of createInteractiveSession — session plus staleness tracking data. */\nexport interface ICreatedInteractiveSession {\n session: Session;\n /** Per-file entries for AGENTS.md files loaded at startup. Used for staleness detection. */\n agentsFileEntries: IContextFileEntry[];\n /** Per-file entries for CLAUDE.md files loaded at startup. Used for staleness detection. */\n claudeFileEntries: IContextFileEntry[];\n /** Rebuilds the system message given updated agentsMd and claudeMd strings. */\n rebuildSystemMessage: (agentsMd: string, claudeMd: string) => string;\n}\n\n/**\n * Create and return a fully initialized Session.\n *\n * Loads config, context, project info in parallel, merges plugin hooks,\n * then constructs the session via createSession().\n */\nexport async function createInteractiveSession(\n options: IInitOptions,\n): Promise<ICreatedInteractiveSession> {\n const cwd = options.cwd;\n const [config, context, projectInfo] = await Promise.all([\n options.config ? Promise.resolve(options.config) : loadConfig(cwd),\n options.bare\n ? Promise.resolve({\n agentsMd: '',\n claudeMd: '',\n agentsFileEntries: [],\n claudeFileEntries: [],\n })\n : loadContext(cwd),\n options.bare\n ? Promise.resolve({ type: 'unknown' as const, language: 'unknown' as const })\n : detectProject(cwd),\n ]);\n\n let mergedConfig: IResolvedConfig = options.language\n ? { ...config, language: options.language }\n : config;\n\n const pluginsDir = join(homedir(), '.robota', 'plugins');\n const pluginLoader = new BundlePluginLoader(pluginsDir);\n if (!options.bare) {\n try {\n const plugins = pluginLoader.loadPluginsSync();\n if (plugins.length > 0) {\n const pluginHooks = mergePluginHooks(plugins);\n mergedConfig = {\n ...mergedConfig,\n hooks: mergeHooksIntoConfig(\n mergedConfig.hooks as Record<string, Array<Record<string, unknown>>> | undefined,\n pluginHooks as Record<string, Array<Record<string, unknown>>>,\n ),\n };\n }\n } catch {\n // No plugins dir or load failed\n }\n }\n\n const paths = projectPaths(cwd);\n\n const sandboxRestored = await restoreInteractiveSandboxSnapshot(options);\n if (!sandboxRestored) {\n await applyInteractiveWorkspaceManifest(options, cwd);\n }\n\n const sessionId =\n options.resumeSessionId && !options.forkSession ? options.resumeSessionId : undefined;\n\n const { session, rebuildSystemMessage } = createSession({\n config: mergedConfig,\n cwd,\n context,\n projectInfo,\n permissionMode: options.permissionMode,\n maxTurns: options.maxTurns,\n terminal: NOOP_TERMINAL,\n sessionLogger: new FileSessionLogger(paths.logs),\n permissionHandler: options.permissionHandler,\n provider: options.provider,\n onTextDelta: options.onTextDelta,\n onContextUpdate: options.onContextUpdate,\n onCompactEvent: options.onCompactEvent,\n onToolExecution: options.onToolExecution,\n sessionId,\n allowedTools: options.allowedTools,\n appendSystemPrompt: options.appendSystemPrompt,\n ...(options.systemPrompt ? { systemPromptBuilder: () => options.systemPrompt! } : {}),\n backgroundTaskRunners: options.backgroundTaskRunners,\n subagentRunnerFactory: options.subagentRunnerFactory,\n ...(options.commandModules?.some((module) =>\n module.sessionRequirements?.includes('agent-runtime'),\n )\n ? { enableAgentRuntime: true }\n : {}),\n ...(options.commandModules || options.commandDescriptors\n ? {\n commandDescriptors: [\n ...(options.commandDescriptors ?? []),\n ...(options.commandModules?.flatMap((module) => module.commandDescriptors ?? []) ?? []),\n ],\n }\n : {}),\n modelCommandExecutor: options.modelCommandExecutor,\n isModelCommandInvocable: options.isModelCommandInvocable,\n editCheckpointRecorder: options.editCheckpointRecorder,\n reversibleExecution: options.reversibleExecution,\n sandboxClient: options.sandboxClient,\n agentName: options.agentName,\n });\n\n return {\n session,\n agentsFileEntries: context.agentsFileEntries ?? [],\n claudeFileEntries: context.claudeFileEntries ?? [],\n rebuildSystemMessage,\n };\n}\n\nasync function applyInteractiveWorkspaceManifest(\n options: IInitOptions,\n cwd: string,\n): Promise<void> {\n if (!options.workspaceManifest) return;\n if (!options.sandboxClient) {\n throw new Error('workspaceManifest requires sandboxClient.');\n }\n await applyWorkspaceManifest(options.sandboxClient, options.workspaceManifest, {\n hostRoot: cwd,\n ...(options.sandboxWorkspaceRoot ? { targetRoot: options.sandboxWorkspaceRoot } : {}),\n });\n}\n\nasync function restoreInteractiveSandboxSnapshot(options: IInitOptions): Promise<boolean> {\n if (!options.sandboxSnapshotId) return false;\n if (!options.sandboxClient?.restore) {\n throw new Error('sandboxSnapshotId requires sandboxClient with restore().');\n }\n await options.sandboxClient.restore(options.sandboxSnapshotId);\n return true;\n}\n\n/** Dependencies injected into initializeInteractiveSessionAsync from the class. */\nexport interface IAsyncInitDeps {\n /** Currently stored sandbox snapshot ID (may be set by restore). */\n sandboxSnapshotId: string | undefined;\n /** Session ID to resume (may be set by restore). */\n resumeSessionId: string | undefined;\n /** Messages deferred until the session is created (set during restore). */\n pendingRestoreMessages: TUniversalMessage[] | null;\n /** Callbacks for handling events during initialization. */\n onTextDelta: (delta: string) => void;\n onContextUpdate: (state: IContextWindowState) => void;\n onCompactEvent: (event: ICompactEvent) => void;\n onToolExecution: (event: {\n type: 'start' | 'end';\n toolName: string;\n toolArgs?: TToolArgs;\n success?: boolean;\n denied?: boolean;\n toolResultData?: string;\n }) => void;\n executeModelCommand: (command: string, args: string) => Promise<ICommandResult | null>;\n isModelCommandInvocable: (command: string) => boolean;\n commandDescriptors: readonly ICapabilityDescriptor[];\n setEditCheckpointStore: (store: EditCheckpointStore) => void;\n}\n\n/** Result returned from initializeInteractiveSessionAsync. */\nexport interface IAsyncInitResult {\n session: Session;\n agentsFileEntries: IContextFileEntry[];\n claudeFileEntries: IContextFileEntry[];\n rebuildSystemMessage: ICreatedInteractiveSession['rebuildSystemMessage'];\n autoCompactThresholdSource: 'default' | 'settings';\n}\n\n/**\n * Async initialization flow extracted from InteractiveSession.initializeAsync.\n *\n * Loads config, creates the session, injects pending restore messages, and\n * returns the initialized session plus metadata. The caller is responsible\n * for wiring the result back into the class (bgTracker.subscribe, persist, etc.).\n */\nexport async function initializeInteractiveSessionAsync(\n options: IInteractiveSessionStandardOptions,\n deps: IAsyncInitDeps,\n): Promise<IAsyncInitResult> {\n const config = options.config ?? (await loadConfig(options.cwd));\n const autoCompactThresholdSource =\n config.autoCompactThreshold === undefined ? 'default' : 'settings';\n const checkpointStore = new EditCheckpointStore({ cwd: options.cwd });\n deps.setEditCheckpointStore(checkpointStore);\n\n const created = await createInteractiveSession({\n cwd: options.cwd,\n provider: options.provider,\n config,\n permissionMode: options.permissionMode,\n maxTurns: options.maxTurns,\n permissionHandler: options.permissionHandler,\n resumeSessionId: deps.resumeSessionId,\n forkSession: options.forkSession,\n onTextDelta: deps.onTextDelta,\n onContextUpdate: deps.onContextUpdate,\n onCompactEvent: deps.onCompactEvent,\n onToolExecution: deps.onToolExecution,\n bare: options.bare,\n allowedTools: options.allowedTools,\n appendSystemPrompt: options.appendSystemPrompt,\n ...(options.systemPrompt ? { systemPrompt: options.systemPrompt } : {}),\n language: options.language,\n backgroundTaskRunners: options.backgroundTaskRunners,\n subagentRunnerFactory: options.subagentRunnerFactory,\n ...(options.commandModules ? { commandModules: options.commandModules } : {}),\n editCheckpointRecorder: checkpointStore,\n ...(options.reversibleExecution ? { reversibleExecution: options.reversibleExecution } : {}),\n ...(options.sandboxClient ? { sandboxClient: options.sandboxClient } : {}),\n ...(options.workspaceManifest ? { workspaceManifest: options.workspaceManifest } : {}),\n ...(options.sandboxWorkspaceRoot ? { sandboxWorkspaceRoot: options.sandboxWorkspaceRoot } : {}),\n ...(deps.sandboxSnapshotId ? { sandboxSnapshotId: deps.sandboxSnapshotId } : {}),\n ...(options.agentName ? { agentName: options.agentName } : {}),\n commandDescriptors: deps.commandDescriptors,\n ...(deps.commandDescriptors.length > 0\n ? {\n modelCommandExecutor: deps.executeModelCommand,\n isModelCommandInvocable: deps.isModelCommandInvocable,\n }\n : {}),\n });\n\n if (deps.pendingRestoreMessages) {\n for (const msg of deps.pendingRestoreMessages) injectSavedMessage(created.session, msg);\n }\n\n return {\n session: created.session,\n agentsFileEntries: created.agentsFileEntries,\n claudeFileEntries: created.claudeFileEntries,\n rebuildSystemMessage: created.rebuildSystemMessage,\n autoCompactThresholdSource,\n };\n}\n","import type { IInteractiveSessionRecord, IInteractiveSessionStore } from './session-persistence.js';\nimport type {\n IBackgroundJobGroupState,\n IBackgroundTaskState,\n TBackgroundJobGroupEvent,\n TBackgroundTaskEvent,\n} from '../background-tasks/index.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type { IContextReferenceItem } from '../context/context-reference-inventory.js';\nimport type { IMemoryEvent, IMemoryReference } from '../memory/automatic-memory-types.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\nimport type { Session } from '@robota-sdk/agent-session';\n\n/**\n * Persist the current session state to the session store.\n * Silently ignores errors because persistence failure must not break execution.\n */\nexport function persistSession(\n sessionStore: IInteractiveSessionStore,\n session: Session,\n sessionName: string | undefined,\n cwd: string,\n history: IHistoryEntry[],\n backgroundState?: {\n tasks: readonly IBackgroundTaskState[];\n events: readonly TBackgroundTaskEvent[];\n groups?: readonly IBackgroundJobGroupState[];\n groupEvents?: readonly TBackgroundJobGroupEvent[];\n },\n memoryState?: {\n events: readonly IMemoryEvent[];\n usedReferences: readonly IMemoryReference[];\n },\n skillActivationState?: {\n events: readonly ISkillActivationEvent[];\n },\n contextReferenceState?: {\n references: readonly IContextReferenceItem[];\n },\n sandboxState?: {\n snapshotId?: string;\n },\n): void {\n try {\n const sessionId = session.getSessionId();\n const existing = sessionStore.load(sessionId);\n const sandboxSnapshotId = sandboxState?.snapshotId ?? existing?.sandboxSnapshotId;\n sessionStore.save(\n buildInteractiveSessionRecord({\n session,\n sessionId,\n sessionName: sessionName ?? existing?.name,\n cwd,\n history,\n createdAt: existing?.createdAt,\n backgroundState,\n memoryState,\n skillActivationState,\n contextReferenceState,\n ...(sandboxSnapshotId !== undefined ? { sandboxSnapshotId } : {}),\n }),\n );\n } catch {\n // Persistence is best-effort for interactive execution.\n }\n}\n\ninterface IBuildInteractiveSessionRecordInput {\n session: Session;\n sessionId: string;\n sessionName?: string;\n cwd: string;\n history: IHistoryEntry[];\n createdAt?: string;\n backgroundState?: {\n tasks: readonly IBackgroundTaskState[];\n events: readonly TBackgroundTaskEvent[];\n groups?: readonly IBackgroundJobGroupState[];\n groupEvents?: readonly TBackgroundJobGroupEvent[];\n };\n memoryState?: {\n events: readonly IMemoryEvent[];\n usedReferences: readonly IMemoryReference[];\n };\n skillActivationState?: {\n events: readonly ISkillActivationEvent[];\n };\n contextReferenceState?: {\n references: readonly IContextReferenceItem[];\n };\n sandboxSnapshotId?: string;\n}\n\nfunction buildInteractiveSessionRecord(\n input: IBuildInteractiveSessionRecordInput,\n): IInteractiveSessionRecord {\n return {\n id: input.sessionId,\n ...(input.sessionName !== undefined ? { name: input.sessionName } : {}),\n cwd: input.cwd,\n createdAt: input.createdAt ?? new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n messages: input.session.getHistory(),\n history: input.history,\n systemPrompt: input.session.getSystemMessage(),\n toolSchemas: input.session.getToolSchemas(),\n ...(input.sandboxSnapshotId !== undefined\n ? { sandboxSnapshotId: input.sandboxSnapshotId }\n : {}),\n ...buildBackgroundRecordFields(input.backgroundState),\n ...buildMemoryRecordFields(input.memoryState),\n ...buildSkillActivationRecordFields(input.skillActivationState),\n ...buildContextReferenceRecordFields(input.contextReferenceState),\n };\n}\n\nfunction buildBackgroundRecordFields(\n state: IBuildInteractiveSessionRecordInput['backgroundState'],\n): Partial<IInteractiveSessionRecord> {\n if (!state) return {};\n return {\n backgroundTasks: [...state.tasks],\n backgroundTaskEvents: [...state.events],\n backgroundJobGroups: [...(state.groups ?? [])],\n backgroundJobGroupEvents: [...(state.groupEvents ?? [])],\n };\n}\n\nfunction buildMemoryRecordFields(\n state: IBuildInteractiveSessionRecordInput['memoryState'],\n): Partial<IInteractiveSessionRecord> {\n if (!state) return {};\n return {\n memoryEvents: [...state.events],\n usedMemoryReferences: [...state.usedReferences],\n };\n}\n\nfunction buildSkillActivationRecordFields(\n state: IBuildInteractiveSessionRecordInput['skillActivationState'],\n): Partial<IInteractiveSessionRecord> {\n if (!state) return {};\n return { skillActivationEvents: [...state.events] };\n}\n\nfunction buildContextReferenceRecordFields(\n state: IBuildInteractiveSessionRecordInput['contextReferenceState'],\n): Partial<IInteractiveSessionRecord> {\n if (!state) return {};\n return { contextReferences: [...state.references] };\n}\n","import type { ICapabilityDescriptor, TCapabilityKind } from '../capabilities/types.js';\nimport type { ICommand } from '../command-api/types.js';\n\nfunction inferKind(command: ICommand): TCapabilityKind {\n if (command.source === 'skill') return 'skill';\n if (command.source === 'plugin' && command.skillContent) return 'skill';\n return 'builtin-command';\n}\n\nexport function commandToCapabilityDescriptor(command: ICommand): ICapabilityDescriptor {\n const skillLike =\n command.source === 'skill' || (command.source === 'plugin' && Boolean(command.skillContent));\n return {\n name: command.name,\n kind: inferKind(command),\n description: command.description,\n userInvocable: command.userInvocable !== false,\n modelInvocable:\n command.modelInvocable === true || (skillLike && command.disableModelInvocation !== true),\n ...(command.argumentHint ? { argumentHint: command.argumentHint } : {}),\n ...(command.safety ? { safety: command.safety } : {}),\n };\n}\n","import { commandToCapabilityDescriptor } from './capability-descriptors.js';\n\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { ICommandModule } from '../command-api/command-module.js';\nimport type { ICommandSource, ICommand } from '../command-api/types.js';\n\n/** Aggregates commands from multiple sources */\nexport class CommandRegistry {\n private sources: ICommandSource[] = [];\n\n addSource(source: ICommandSource): void {\n this.sources.push(source);\n }\n\n replaceSource(name: string, source?: ICommandSource): void {\n this.sources = this.sources.filter((candidate) => candidate.name !== name);\n if (source !== undefined) {\n this.sources.push(source);\n }\n }\n\n addModule(module: ICommandModule): void {\n for (const source of module.commandSources ?? []) {\n this.addSource(source);\n }\n }\n\n /** Get all commands, optionally filtered by prefix */\n getCommands(filter?: string): ICommand[] {\n const all: ICommand[] = [];\n for (const source of this.sources) {\n all.push(...source.getCommands());\n }\n if (!filter) return all;\n const lower = filter.toLowerCase();\n return all.filter((cmd) => cmd.name.toLowerCase().startsWith(lower));\n }\n\n /** Resolve a short name to its fully qualified plugin:name form */\n resolveQualifiedName(shortName: string): string | null {\n const matches = this.getCommands().filter(\n (c) => c.source === 'plugin' && c.name.includes(':') && c.name.endsWith(`:${shortName}`),\n );\n if (matches.length !== 1) return null;\n return matches[0]!.name;\n }\n\n /** Get subcommands for a specific command */\n getSubcommands(commandName: string): ICommand[] {\n const lower = commandName.toLowerCase();\n for (const source of this.sources) {\n for (const cmd of source.getCommands()) {\n if (cmd.name.toLowerCase() === lower && cmd.subcommands) {\n return cmd.subcommands;\n }\n }\n }\n return [];\n }\n\n getCapabilityDescriptors(): ICapabilityDescriptor[] {\n return this.getCommands().map((command) => commandToCapabilityDescriptor(command));\n }\n}\n","import { createSystemCommands } from './system-command.js';\n\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { ICommandHostContext, ICommandResult, ISystemCommand } from '../command-api/index.js';\n\n/** Registry for system commands. */\nexport class SystemCommandExecutor {\n private readonly commands: Map<string, ISystemCommand>;\n\n constructor(commands?: ISystemCommand[]) {\n this.commands = new Map();\n for (const cmd of commands ?? createSystemCommands()) {\n this.commands.set(cmd.name, cmd);\n }\n }\n\n /** Register an additional command. */\n register(command: ISystemCommand): void {\n this.commands.set(command.name, command);\n }\n\n /** Execute a command by name. Returns null if command not found. */\n async execute(\n name: string,\n session: ICommandHostContext,\n args: string,\n ): Promise<ICommandResult | null> {\n const cmd = this.getCommand(name);\n if (!cmd) return null;\n return await this.executeCommand(cmd, session, args);\n }\n\n getCommand(name: string): ISystemCommand | undefined {\n return this.commands.get(name);\n }\n\n /** Resolve whether a command requires permission confirmation. */\n resolveRequiresPermission(command: ISystemCommand): boolean {\n if (command.requiresPermission !== undefined) return command.requiresPermission;\n return command.safety !== 'read-only';\n }\n\n async executeCommand(\n command: ISystemCommand,\n session: ICommandHostContext,\n args: string,\n ): Promise<ICommandResult> {\n return await command.execute(session, args);\n }\n\n /** List all registered commands. */\n listCommands(): ISystemCommand[] {\n return [...this.commands.values()];\n }\n\n listModelInvocableCommands(): ICapabilityDescriptor[] {\n return this.listCommands()\n .filter((command) => command.modelInvocable === true)\n .map((command) => ({\n name: command.name,\n kind: 'builtin-command',\n description: command.description,\n userInvocable: command.userInvocable !== false,\n modelInvocable: true,\n ...(command.argumentHint ? { argumentHint: command.argumentHint } : {}),\n ...(command.safety ? { safety: command.safety } : {}),\n }));\n }\n\n isModelInvocable(name: string): boolean {\n return this.commands.get(name)?.modelInvocable === true;\n }\n\n async executeModelInvocable(\n name: string,\n session: ICommandHostContext,\n args: string,\n ): Promise<ICommandResult | null> {\n if (!this.isModelInvocable(name)) return null;\n return this.execute(name, session, args);\n }\n\n /** Check if a command exists. */\n hasCommand(name: string): boolean {\n return this.commands.has(name);\n }\n}\n","import type { ISystemCommand } from '../command-api/index.js';\nexport { SystemCommandExecutor } from './system-command-executor.js';\nexport type {\n ICommandInteraction,\n ICommandChoicePromptOption,\n ICommandResult,\n TCommandEffect,\n TCommandResultDataValue,\n TCommandInteractionPrompt,\n} from '../command-api/index.js';\nexport type { ISystemCommand, TSystemCommandLifecycle } from '../command-api/index.js';\n\n/** Built-in system commands. */\nexport function createSystemCommands(): ISystemCommand[] {\n return [];\n}\n","import { createSystemCommands } from './system-command.js';\n\nimport type { ICommandModule } from '../command-api/command-module.js';\nimport type { ISystemCommand } from '../command-api/index.js';\nimport type { ICommandSource, ICommand } from '../command-api/types.js';\n\nfunction commandToPaletteEntry(command: ISystemCommand): ICommand {\n return {\n name: command.name,\n description: command.description,\n source: 'builtin',\n ...(command.subcommands ? { subcommands: [...command.subcommands] } : {}),\n ...(command.argumentHint ? { argumentHint: command.argumentHint } : {}),\n ...(command.modelInvocable !== undefined ? { modelInvocable: command.modelInvocable } : {}),\n ...(command.userInvocable !== undefined ? { userInvocable: command.userInvocable } : {}),\n ...(command.safety ? { safety: command.safety } : {}),\n };\n}\n\n/** Command source for SDK-owned built-in commands. */\nexport class BuiltinCommandSource implements ICommandSource {\n readonly name = 'builtin';\n private readonly commands: ICommand[];\n\n constructor(systemCommands: readonly ISystemCommand[] = createSystemCommands()) {\n this.commands = systemCommands.map(commandToPaletteEntry);\n }\n\n getCommands(): ICommand[] {\n return this.commands;\n }\n}\n\nexport function createBuiltinCommandModule(): ICommandModule {\n const systemCommands = createSystemCommands();\n return {\n name: 'sdk-builtin',\n commandSources: [new BuiltinCommandSource(systemCommands)],\n systemCommands,\n };\n}\n","import { findProviderDefinition, getProviderCredentialRequirement } from '@robota-sdk/agent-core';\nimport { formatEnvReference, hasUsableSecretReference } from '@robota-sdk/agent-core';\n\nimport type {\n IProviderDefinition,\n IProviderCredentialRequirement,\n IProviderProfileConfig,\n TProviderCredentialField,\n TUniversalValue,\n} from '@robota-sdk/agent-core';\n\nexport interface IProviderProfileSettings extends IProviderProfileConfig {\n [key: string]: TUniversalValue;\n}\n\nexport interface ILegacyProviderSettings {\n [key: string]: TUniversalValue;\n name?: string;\n model?: string;\n apiKey?: string;\n baseURL?: string;\n timeout?: number;\n options?: Record<string, TUniversalValue>;\n}\n\nexport type TProviderSettingsDocument = Record<string, TUniversalValue> & {\n currentProvider?: string;\n providers?: Record<string, IProviderProfileSettings>;\n provider?: ILegacyProviderSettings;\n};\n\nexport interface IProviderSetupInput {\n profile: string;\n type: string;\n model?: string;\n apiKey?: string;\n apiKeyEnv?: string;\n baseURL?: string;\n timeout?: number;\n setCurrent?: boolean;\n}\n\nexport interface IProviderSetupPatch {\n currentProvider?: string;\n providers: Record<string, IProviderProfileSettings>;\n}\n\nexport interface IProviderSettingsBuildOptions {\n providerDefinitions?: readonly IProviderDefinition[];\n}\n\nexport function upsertProviderProfile(\n settings: TProviderSettingsDocument,\n profileName: string,\n profile: IProviderProfileSettings,\n): TProviderSettingsDocument {\n return {\n ...settings,\n providers: {\n ...(settings.providers ?? {}),\n [profileName]: profile,\n },\n };\n}\n\nexport function setCurrentProvider(\n settings: TProviderSettingsDocument,\n profileName: string,\n): TProviderSettingsDocument {\n if (!settings.providers?.[profileName]) {\n throw new Error(`Provider profile \"${profileName}\" was not found`);\n }\n return {\n ...settings,\n currentProvider: profileName,\n };\n}\n\nexport function deleteProviderProfile(\n settings: TProviderSettingsDocument,\n profileName: string,\n options: { replacementCurrentProvider?: string } = {},\n): TProviderSettingsDocument {\n if (!settings.providers?.[profileName]) {\n throw new Error(`Provider profile \"${profileName}\" was not found`);\n }\n const providers = { ...settings.providers };\n delete providers[profileName];\n if (\n options.replacementCurrentProvider !== undefined &&\n providers[options.replacementCurrentProvider] === undefined\n ) {\n throw new Error(`Provider profile \"${options.replacementCurrentProvider}\" was not found`);\n }\n const next: TProviderSettingsDocument = {\n ...settings,\n providers,\n };\n if (settings.currentProvider !== profileName) {\n return next;\n }\n if (options.replacementCurrentProvider !== undefined) {\n return {\n ...next,\n currentProvider: options.replacementCurrentProvider,\n };\n }\n const withoutCurrentProvider = { ...next };\n delete withoutCurrentProvider.currentProvider;\n return withoutCurrentProvider;\n}\n\nexport function validateProviderProfile(\n profileName: string,\n profile: IProviderProfileSettings,\n options: IProviderSettingsBuildOptions = {},\n): void {\n if (!profile.type) {\n throw new Error(`Provider profile \"${profileName}\" is missing type`);\n }\n if (!profile.model) {\n throw new Error(`Provider profile \"${profileName}\" is missing model`);\n }\n const definition = findProviderDefinition(options.providerDefinitions ?? [], profile.type);\n const credentialRequirement = getProviderCredentialRequirement(definition);\n if (\n credentialRequirement !== undefined &&\n !hasUsableRequiredProviderCredential(profile, definition?.defaults, credentialRequirement)\n ) {\n throw new Error(\n `Provider profile \"${profileName}\" is missing ${formatCredentialRequirement(credentialRequirement)}`,\n );\n }\n}\n\nexport function buildProviderSetupPatch(\n input: IProviderSetupInput,\n options: IProviderSettingsBuildOptions = {},\n): IProviderSetupPatch {\n const profile = buildProviderProfile(input, options);\n validateProviderProfile(input.profile, profile, options);\n return {\n ...(input.setCurrent && { currentProvider: input.profile }),\n providers: {\n [input.profile]: profile,\n },\n };\n}\n\nexport function buildProviderProfile(\n input: IProviderSetupInput,\n options: IProviderSettingsBuildOptions = {},\n): IProviderProfileSettings {\n const defaults = getProviderDefaults(input.type, options.providerDefinitions ?? []);\n const apiKey =\n input.apiKeyEnv !== undefined\n ? formatEnvReference(input.apiKeyEnv)\n : (input.apiKey ?? defaults.apiKey);\n const baseURL = input.baseURL ?? defaults.baseURL;\n\n return {\n type: input.type,\n model: input.model ?? defaults.model,\n ...(isNonEmptyString(apiKey) && { apiKey }),\n ...(baseURL !== undefined && { baseURL }),\n ...(input.timeout !== undefined && { timeout: input.timeout }),\n };\n}\n\nexport function mergeProviderPatch(\n settings: TProviderSettingsDocument,\n patch: IProviderSetupPatch,\n): TProviderSettingsDocument {\n const [profileName, profile] = Object.entries(patch.providers)[0] ?? [];\n if (!profileName || !profile) {\n return settings;\n }\n const withProfile = upsertProviderProfile(settings, profileName, profile);\n return patch.currentProvider\n ? setCurrentProvider(withProfile, patch.currentProvider)\n : withProfile;\n}\n\nfunction getProviderDefaults(\n type: string,\n providerDefinitions: readonly IProviderDefinition[],\n): { model?: string; apiKey?: string; baseURL?: string } {\n return findProviderDefinition(providerDefinitions, type)?.defaults ?? {};\n}\n\nfunction hasUsableRequiredProviderCredential(\n profile: IProviderProfileSettings,\n defaults: IProviderDefinition['defaults'],\n requirement: IProviderCredentialRequirement,\n): boolean {\n return requirement.anyOf.some((field) =>\n hasUsableSecretReference(resolveProviderCredentialValue(field, profile, defaults)),\n );\n}\n\nfunction resolveProviderCredentialValue(\n field: TProviderCredentialField,\n profile: IProviderProfileSettings,\n defaults: IProviderDefinition['defaults'],\n): string | undefined {\n return profile[field] ?? defaults?.[field];\n}\n\nfunction formatCredentialRequirement(requirement: IProviderCredentialRequirement): string {\n return requirement.anyOf.join(' or ');\n}\n\nfunction isNonEmptyString(value: string | undefined): value is string {\n return value !== undefined && value.length > 0;\n}\n","import { findProviderDefinition } from '@robota-sdk/agent-core';\n\nimport { validateProviderProfile, type IProviderProfileSettings } from './provider-settings.js';\n\nimport type { ICommandResult } from '../command-result.js';\nimport type { IProviderCommandModuleOptions } from './provider-command-types.js';\nimport type { IProviderProbeResult, IProviderProfileConfig } from '@robota-sdk/agent-core';\n\nexport async function testProviderProfileCommand(\n currentProvider: string | undefined,\n providers: Record<string, IProviderProfileSettings> | undefined,\n profileArg: string | undefined,\n options: IProviderCommandModuleOptions,\n): Promise<ICommandResult> {\n const profileName = profileArg ?? currentProvider;\n if (!profileName) {\n return { message: 'No provider profile selected.', success: false };\n }\n const profile = providers?.[profileName];\n if (!profile) {\n return { message: `Provider profile \"${profileName}\" was not found.`, success: false };\n }\n try {\n validateProviderProfile(profileName, profile, {\n providerDefinitions: options.providerDefinitions,\n });\n } catch (error) {\n return { message: error instanceof Error ? error.message : String(error), success: false };\n }\n const definition = profile.type\n ? findProviderDefinition(options.providerDefinitions, profile.type)\n : undefined;\n const probe = definition?.probeProfile ?? probeProviderProfile;\n const result = await probe(profile);\n return {\n message: result.ok\n ? `Provider \"${profileName}\" test passed: ${result.message}`\n : `Provider \"${profileName}\" test failed: ${result.message}; manual configuration can continue.`,\n success: true,\n data: { providerTest: { profile: profileName } },\n };\n}\n\nexport async function probeProviderProfile(\n profile: IProviderProfileConfig,\n): Promise<IProviderProbeResult> {\n void profile;\n return { ok: true, message: 'Profile fields are valid; no endpoint probe configured.' };\n}\n","import { existsSync, readFileSync } from 'node:fs';\n\nimport {\n findProviderDefinition,\n getProviderCredentialRequirement,\n hasUsableSecretReference,\n type IProviderCredentialRequirement,\n type IProviderDefinition,\n type TProviderCredentialField,\n} from '@robota-sdk/agent-core';\n\nimport type { TProviderSettingsDocument } from './provider-settings.js';\n\nexport type TSettingsCheck = 'missing' | 'valid' | 'corrupt' | 'incomplete';\n\nexport function checkSettingsDocument(\n settings: TProviderSettingsDocument,\n providerDefinitions: readonly IProviderDefinition[] = [],\n): TSettingsCheck {\n return hasUsableProviderConfig(settings, providerDefinitions) ? 'valid' : 'incomplete';\n}\n\nfunction hasUsableProviderConfig(\n settings: TProviderSettingsDocument,\n providerDefinitions: readonly IProviderDefinition[],\n): boolean {\n if (typeof settings.currentProvider === 'string') {\n const profile = settings.providers?.[settings.currentProvider];\n return isUsableProviderProfile(profile?.type, profile, providerDefinitions);\n }\n if (\n settings.provider &&\n isUsableProviderProfile(settings.provider.name, settings.provider, providerDefinitions)\n ) {\n return true;\n }\n return false;\n}\n\nfunction isUsableProviderProfile(\n type: string | undefined,\n profile: { apiKey?: string } | undefined,\n providerDefinitions: readonly IProviderDefinition[],\n): boolean {\n if (!profile) return false;\n if (!type) return hasUsableSecretReference(profile.apiKey);\n const definition = findProviderDefinition(providerDefinitions, type);\n if (definition === undefined) return false;\n const credentialRequirement = getProviderCredentialRequirement(definition);\n if (credentialRequirement === undefined) return true;\n return hasUsableRequiredProviderCredential(profile, definition, credentialRequirement);\n}\n\nfunction hasUsableRequiredProviderCredential(\n profile: { apiKey?: string },\n definition: IProviderDefinition,\n requirement: IProviderCredentialRequirement,\n): boolean {\n return requirement.anyOf.some((field) =>\n hasUsableSecretReference(resolveProviderCredentialValue(field, profile, definition)),\n );\n}\n\nfunction resolveProviderCredentialValue(\n field: TProviderCredentialField,\n profile: { apiKey?: string },\n definition: IProviderDefinition,\n): string | undefined {\n return profile[field] ?? definition.defaults?.[field];\n}\n\nexport function checkSettingsFile(\n filePath: string,\n providerDefinitions: readonly IProviderDefinition[] = [],\n): TSettingsCheck {\n if (!existsSync(filePath)) return 'missing';\n try {\n const raw = readFileSync(filePath, 'utf8').trim();\n if (raw.length === 0) return 'incomplete';\n const parsed = JSON.parse(raw) as TProviderSettingsDocument;\n return checkSettingsDocument(parsed, providerDefinitions);\n } catch {\n // allow-fallback: corrupt settings file is a valid terminal state ('corrupt')\n return 'corrupt';\n }\n}\n","import { normalizeProviderConfig } from '@robota-sdk/agent-executor';\n\nimport { NodeFileSystem } from '../../adapters/node-file-system.js';\n\nimport type { IProviderProfileSettings, TProviderSettingsDocument } from './provider-settings.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\nimport type { IProviderConfig, IProviderDefinition } from '@robota-sdk/agent-core';\n\nexport function readMergedProviderSettingsFromPaths(\n paths: readonly string[],\n fs: IFileSystem = new NodeFileSystem(),\n): TProviderSettingsDocument {\n return paths.reduce<TProviderSettingsDocument>((settings, filePath) => {\n const parsed = readSettingsFile(filePath, fs);\n if (parsed === undefined) {\n return settings;\n }\n return mergeSettings(settings, parsed);\n }, {});\n}\n\nfunction readSettingsFile(\n filePath: string,\n fs: IFileSystem,\n): TProviderSettingsDocument | undefined {\n if (!fs.existsSync(filePath)) {\n return undefined;\n }\n try {\n const raw = fs.readFileSync(filePath, 'utf8');\n return JSON.parse(raw) as TProviderSettingsDocument;\n } catch {\n // allow-fallback: unparseable settings file is skipped to allow the config chain to continue\n return undefined;\n }\n}\n\nexport function mergeSettings(\n base: TProviderSettingsDocument,\n override: TProviderSettingsDocument,\n): TProviderSettingsDocument {\n return {\n ...base,\n ...override,\n provider:\n base.provider !== undefined || override.provider !== undefined\n ? { ...base.provider, ...override.provider }\n : undefined,\n providers:\n base.providers !== undefined || override.providers !== undefined\n ? mergeProviders(base.providers, override.providers)\n : undefined,\n };\n}\n\nexport function mergeProviders(\n base: TProviderSettingsDocument['providers'],\n override: TProviderSettingsDocument['providers'],\n): TProviderSettingsDocument['providers'] {\n const result: Record<string, IProviderProfileSettings> = { ...(base ?? {}) };\n for (const [name, profile] of Object.entries(override ?? {})) {\n result[name] = { ...result[name], ...profile };\n }\n return result;\n}\n\nexport function resolveActiveProvider(\n settings: TProviderSettingsDocument,\n providerOverride: string | undefined,\n providerDefinitions: readonly IProviderDefinition[],\n): IProviderConfig | undefined {\n const activeProvider = providerOverride ?? settings.currentProvider;\n if (activeProvider !== undefined) {\n const profile = settings.providers?.[activeProvider];\n if (profile === undefined) {\n throw new Error(`Provider profile \"${activeProvider}\" was not found in providers`);\n }\n if (!profile.type) {\n throw new Error(`Provider profile \"${activeProvider}\" is missing type`);\n }\n return normalizeProviderConfig(\n {\n name: profile.type,\n model: profile.model,\n apiKey: profile.apiKey,\n baseURL: profile.baseURL,\n timeout: profile.timeout,\n options: profile.options,\n },\n providerDefinitions,\n );\n }\n\n const provider = settings.provider;\n if (provider?.name) {\n return normalizeProviderConfig(\n {\n name: provider.name,\n model: provider.model,\n apiKey: provider.apiKey,\n baseURL: provider.baseURL,\n timeout: provider.timeout,\n options: provider.options,\n },\n providerDefinitions,\n );\n }\n\n return undefined;\n}\n","import { join } from 'node:path';\n\nfunction getUserHome(): string {\n return process.env.HOME ?? process.env.USERPROFILE ?? '/';\n}\n\nexport function getProviderSettingsPaths(cwd: string): string[] {\n const userHome = getUserHome();\n return [\n join(userHome, '.robota', 'settings.json'),\n join(userHome, '.claude', 'settings.json'),\n join(cwd, '.robota', 'settings.json'),\n join(cwd, '.robota', 'settings.local.json'),\n join(cwd, '.claude', 'settings.json'),\n join(cwd, '.claude', 'settings.local.json'),\n ];\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\n\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\n\nexport type TSettingsData = Record<string, TUniversalValue>;\n\nexport function getUserSettingsPath(): string {\n const home = process.env.HOME ?? process.env.USERPROFILE ?? '/';\n return join(home, '.robota', 'settings.json');\n}\n\nexport type TSettingsScope = 'user' | 'project-local';\n\nexport function resolveSettingsPathForScope(\n cwd: string,\n scope: TSettingsScope | undefined,\n): string {\n if (scope === undefined || scope === 'user') {\n return getUserSettingsPath();\n }\n return join(cwd, '.robota', 'settings.local.json');\n}\n\nexport function readSettings(path: string): TSettingsData {\n if (!existsSync(path)) return {};\n const raw = readFileSync(path, 'utf8');\n try {\n return JSON.parse(raw) as TSettingsData;\n } catch {\n // allow-fallback: corrupt settings file must not crash the CLI; reset to empty defaults\n process.stderr.write(`Warning: corrupt settings file at ${path}, resetting to defaults\\n`);\n return {};\n }\n}\n\nexport function writeSettings(path: string, settings: TSettingsData): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(settings, null, 2) + '\\n', 'utf8');\n}\n\nexport function updateModelInSettings(settingsPath: string, modelId: string): void {\n const settings = readSettings(settingsPath);\n const currentProvider = settings.currentProvider;\n const providers = settings.providers;\n if (typeof currentProvider === 'string' && isSettingsData(providers)) {\n const providerMap = providers as Record<string, TSettingsData | undefined>;\n providerMap[currentProvider] = {\n ...(isSettingsData(providerMap[currentProvider]) ? providerMap[currentProvider] : {}),\n model: modelId,\n };\n settings.providers = providerMap;\n } else {\n settings.provider = {\n ...(isSettingsData(settings.provider) ? settings.provider : {}),\n model: modelId,\n };\n }\n writeSettings(settingsPath, settings);\n}\n\nfunction isSettingsData(value: TUniversalValue): value is TSettingsData {\n return (\n value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)\n );\n}\n\nexport function deleteSettings(path: string): boolean {\n if (existsSync(path)) {\n unlinkSync(path);\n return true;\n }\n return false;\n}\n","import { readMergedProviderSettingsFromPaths } from './provider-merge.js';\nimport {\n buildProviderSetupPatch,\n mergeProviderPatch,\n setCurrentProvider,\n type IProviderProfileSettings,\n type IProviderSetupInput,\n type IProviderSettingsBuildOptions,\n type TProviderSettingsDocument,\n} from './provider-settings.js';\nimport { getProviderSettingsPaths } from '../../config/provider-paths.js';\nimport { readSettings, writeSettings } from '../../config/settings-io.js';\n\nexport interface IProviderSwitchOptions {\n knownProviders?: Record<string, IProviderProfileSettings>;\n}\n\nexport interface IActiveModelChangeOptions {\n settingsPaths?: readonly string[];\n providerOverride?: string | undefined;\n}\n\nexport interface IProviderSettingsWriteTargetOptions {\n settingsPaths?: readonly string[];\n}\n\nexport interface IActiveModelChangeResult {\n settingsPath: string;\n settings: TProviderSettingsDocument;\n profileName?: string;\n}\n\nexport function resolveProviderSettingsWriteTargetPath(\n cwd: string,\n options: IProviderSettingsWriteTargetOptions = {},\n): string {\n const settingsPaths = options.settingsPaths ?? getProviderSettingsPaths(cwd);\n const targetPath = findLastPathWithCurrentProvider(settingsPaths) ?? settingsPaths[0];\n if (targetPath === undefined) {\n throw new Error('No settings path available for provider update');\n }\n return targetPath;\n}\n\nfunction readProviderDocument(settingsPath: string): TProviderSettingsDocument {\n return readSettings(settingsPath) as TProviderSettingsDocument;\n}\n\nexport function applyProviderConfiguration(\n settingsPath: string,\n input: IProviderSetupInput,\n options: IProviderSettingsBuildOptions = {},\n): TProviderSettingsDocument {\n const settings = readProviderDocument(settingsPath);\n const patch = buildProviderSetupPatch(input, options);\n const next = mergeProviderPatch(settings, patch);\n writeSettings(settingsPath, next);\n return next;\n}\n\nexport function applyProviderSwitch(\n settingsPath: string,\n profileName: string,\n options: IProviderSwitchOptions = {},\n): TProviderSettingsDocument {\n const settings = readProviderDocument(settingsPath);\n const hasLocalProfile = settings.providers?.[profileName] !== undefined;\n const hasKnownProfile = options.knownProviders?.[profileName] !== undefined;\n const next =\n hasLocalProfile || hasKnownProfile\n ? { ...settings, currentProvider: profileName }\n : setCurrentProvider(settings, profileName);\n writeSettings(settingsPath, next);\n return next;\n}\n\nexport function applyActiveModelChange(\n cwd: string,\n modelId: string,\n options: IActiveModelChangeOptions = {},\n): IActiveModelChangeResult {\n const settingsPaths = options.settingsPaths ?? getProviderSettingsPaths(cwd);\n const merged = readMergedProviderSettingsFromPaths(settingsPaths);\n const activeProfileName = options.providerOverride ?? merged.currentProvider;\n\n if (typeof activeProfileName !== 'string') {\n throw new Error(\n 'Cannot update model: no active provider profile. Set \"currentProvider\" in settings.',\n );\n }\n\n return updateActiveProviderProfileModel(settingsPaths, activeProfileName, modelId);\n}\n\nfunction updateActiveProviderProfileModel(\n settingsPaths: readonly string[],\n profileName: string,\n modelId: string,\n): IActiveModelChangeResult {\n const settingsPath =\n findLastPathWithProviderProfile(settingsPaths, profileName) ?? settingsPaths[0];\n if (settingsPath === undefined) {\n throw new Error('No settings path available for model update');\n }\n\n const settings = readProviderDocument(settingsPath);\n const providers = settings.providers ?? {};\n const existing = providers[profileName] ?? {};\n const next: TProviderSettingsDocument = {\n ...settings,\n providers: {\n ...providers,\n [profileName]: {\n ...existing,\n model: modelId,\n },\n },\n };\n writeSettings(settingsPath, next);\n return { settingsPath, settings: next, profileName };\n}\n\nfunction findLastPathWithProviderProfile(\n settingsPaths: readonly string[],\n profileName: string,\n): string | undefined {\n for (let index = settingsPaths.length - 1; index >= 0; index -= 1) {\n const settingsPath = settingsPaths[index];\n if (settingsPath === undefined) continue;\n const settings = readProviderDocument(settingsPath);\n if (settings.providers?.[profileName] !== undefined) return settingsPath;\n }\n return undefined;\n}\n\nfunction findLastPathWithCurrentProvider(settingsPaths: readonly string[]): string | undefined {\n for (let index = settingsPaths.length - 1; index >= 0; index -= 1) {\n const settingsPath = settingsPaths[index];\n if (settingsPath === undefined) continue;\n const settings = readProviderDocument(settingsPath);\n if (settings.currentProvider !== undefined) return settingsPath;\n }\n return undefined;\n}\n","import { createProviderFromConfig } from '@robota-sdk/agent-executor';\n\nimport { readMergedProviderSettingsFromPaths, resolveActiveProvider } from './provider-merge.js';\nimport { getProviderSettingsPaths } from '../../config/provider-paths.js';\n\nimport type { TProviderSettingsDocument } from './provider-settings.js';\nimport type { IAIProvider, IProviderConfig, IProviderDefinition } from '@robota-sdk/agent-core';\n\nexport interface IReadProviderSettingsOptions {\n providerOverride?: string;\n providerDefinitions?: readonly IProviderDefinition[];\n}\n\nexport function readMergedProviderSettings(cwd: string): TProviderSettingsDocument {\n return readMergedProviderSettingsFromPaths(getProviderSettingsPaths(cwd));\n}\n\nexport function readProviderSettings(\n cwd: string,\n options: IReadProviderSettingsOptions = {},\n): IProviderConfig {\n const merged = readMergedProviderSettings(cwd);\n const providerConfig = resolveActiveProvider(\n merged,\n options.providerOverride,\n options.providerDefinitions ?? [],\n );\n if (providerConfig !== undefined) {\n return providerConfig;\n }\n\n throw new Error('No provider configuration found. Run `robota` to set up.');\n}\n\nexport function createProviderFromSettings(\n cwd: string,\n modelOverride?: string,\n options: IReadProviderSettingsOptions = {},\n): IAIProvider {\n const providerDefinitions = options.providerDefinitions ?? [];\n const settings = readProviderSettings(cwd, { ...options, providerDefinitions });\n const model = modelOverride ?? settings.model;\n\n return createProviderFromConfig({ ...settings, model }, providerDefinitions);\n}\n","import type { ICommandSource, ICommand } from '../command-api/types.js';\nimport type { ILoadedBundlePlugin } from '../plugins/index.js';\n\n/**\n * Command source that discovers skills and commands from loaded BundlePlugins.\n *\n * - Skills: exposed as `/name` with `(plugin-name)` hint in description.\n * - Commands: exposed as `/plugin:command` (already namespaced by the loader).\n */\nexport class PluginCommandSource implements ICommandSource {\n readonly name = 'plugin';\n private readonly plugins: ILoadedBundlePlugin[];\n\n constructor(plugins: ILoadedBundlePlugin[]) {\n this.plugins = plugins;\n }\n\n getCommands(): ICommand[] {\n const commands: ICommand[] = [];\n\n for (const plugin of this.plugins) {\n // Skills: /name with (plugin-name) hint in description\n for (const skill of plugin.skills) {\n const baseName = skill.name.includes('@') ? skill.name.split('@')[0] : skill.name;\n commands.push({\n name: baseName,\n description: `(${plugin.manifest.name}) ${skill.description}`,\n source: 'plugin',\n skillContent: skill.skillContent,\n pluginDir: plugin.pluginDir,\n });\n }\n\n // Commands: /plugin:name (already namespaced by loader)\n for (const cmd of plugin.commands) {\n commands.push({\n name: cmd.name,\n description: cmd.description,\n source: 'plugin',\n skillContent: cmd.skillContent,\n pluginDir: plugin.pluginDir,\n });\n }\n }\n\n return commands;\n }\n}\n","import { AUTO_COMPACT_THRESHOLD } from '@robota-sdk/agent-session';\n\nimport type {\n IContextReferenceAddResult,\n IContextReferenceClearResult,\n IContextReferenceItem,\n IContextReferenceRemoveResult,\n} from '../../context/context-reference-inventory.js';\nimport type { ICommandSettingsAdapter, ICommandSettingsDocument } from '../host-adapters.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { TAutoCompactThresholdSource } from '../host-context.js';\nimport type { IContextWindowState } from '@robota-sdk/agent-core';\nexport type {\n IContextReferenceAddResult,\n IContextReferenceClearResult,\n IContextReferenceItem,\n IContextReferenceRemoveResult,\n} from '../../context/context-reference-inventory.js';\n\nexport type TAutoCompactThreshold = number | false;\n\nexport const DEFAULT_AUTO_COMPACT_THRESHOLD = AUTO_COMPACT_THRESHOLD;\nexport const AUTO_COMPACT_THRESHOLD_SETTINGS_KEY = 'autoCompactThreshold';\n\nexport interface ICompactContextResult {\n before: IContextWindowState;\n after: IContextWindowState;\n}\n\n/** Read context-window state through the command host facade. */\nexport function readCommandContextState(context: ICommandHostContext): IContextWindowState {\n return context.getContextState();\n}\n\n/** Read the effective automatic compact policy through the command host facade. */\nexport function readAutoCompactThreshold(context: ICommandHostContext): TAutoCompactThreshold {\n return context.getAutoCompactThreshold();\n}\n\n/** Read the source of the effective automatic compact policy. */\nexport function readAutoCompactThresholdSource(\n context: ICommandHostContext,\n): TAutoCompactThresholdSource {\n return context.getAutoCompactThresholdSource?.() ?? 'session';\n}\n\n/** Update the active session's automatic compact policy through the command host facade. */\nexport function setCommandAutoCompactThreshold(\n context: ICommandHostContext,\n threshold: TAutoCompactThreshold,\n source: TAutoCompactThresholdSource,\n): void {\n if (context.setAutoCompactThreshold) {\n context.setAutoCompactThreshold(threshold, source);\n return;\n }\n\n const session = context.getSession();\n if (!session.setAutoCompactThreshold) {\n throw new Error('Command host does not support changing auto-compact threshold.');\n }\n session.setAutoCompactThreshold(threshold);\n}\n\n/** Persist an automatic compact policy value through the host settings adapter, when present. */\nexport function writeAutoCompactThresholdSetting(\n context: ICommandHostContext,\n threshold: TAutoCompactThreshold,\n): boolean {\n const settings = getSettingsAdapter(context);\n if (!settings) return false;\n\n settings.write({\n ...settings.read(),\n [AUTO_COMPACT_THRESHOLD_SETTINGS_KEY]: threshold,\n });\n return true;\n}\n\n/** Remove the persisted automatic compact policy through the host settings adapter, when present. */\nexport function resetAutoCompactThresholdSetting(context: ICommandHostContext): boolean {\n const settings = getSettingsAdapter(context);\n if (!settings) return false;\n\n const next: ICommandSettingsDocument = { ...settings.read() };\n delete next[AUTO_COMPACT_THRESHOLD_SETTINGS_KEY];\n settings.write(next);\n return true;\n}\n\n/** Run manual compaction through the command host facade and return before/after state. */\nexport async function compactCommandContext(\n context: ICommandHostContext,\n instructions?: string,\n): Promise<ICompactContextResult> {\n const before = readCommandContextState(context);\n await context.compactContext(instructions);\n const after = readCommandContextState(context);\n return { before, after };\n}\n\n/** List context reference inventory entries through the command host facade. */\nexport function listCommandContextReferences(\n context: ICommandHostContext,\n): IContextReferenceItem[] {\n return context.listContextReferences?.() ?? [];\n}\n\n/** Add a manual context reference through the command host facade. */\nexport async function addCommandContextReference(\n context: ICommandHostContext,\n path: string,\n): Promise<IContextReferenceAddResult> {\n if (!context.addContextReference) {\n return {\n evicted: [],\n diagnostics: ['Command host does not support context reference additions.'],\n };\n }\n return context.addContextReference(path);\n}\n\n/** Remove a context reference through the command host facade. */\nexport function removeCommandContextReference(\n context: ICommandHostContext,\n path: string,\n): IContextReferenceRemoveResult {\n return context.removeContextReference?.(path) ?? {};\n}\n\n/** Clear all context references through the command host facade. */\nexport function clearCommandContextReferences(\n context: ICommandHostContext,\n): IContextReferenceClearResult {\n return context.clearContextReferences?.() ?? { removed: [] };\n}\n\nfunction getSettingsAdapter(\n context: ICommandHostContext,\n): ICommandSettingsAdapter<ICommandSettingsDocument> | undefined {\n return context.getCommandHostAdapters?.().settings;\n}\n","const FALLBACK_PROFILE_NAME = 'provider';\nconst FIRST_DUPLICATE_SUFFIX = 2;\n\nexport interface IProviderProfileNameSuggestionInput {\n type: string;\n}\n\nexport interface IProviderProfileNameSuggestionOptions {\n existingProfileNames?: readonly string[];\n}\n\nexport function suggestProviderProfileName(\n input: IProviderProfileNameSuggestionInput,\n options: IProviderProfileNameSuggestionOptions = {},\n): string {\n const baseName = sanitizeProviderProfileName(input.type) ?? FALLBACK_PROFILE_NAME;\n const existing = new Set(options.existingProfileNames ?? []);\n if (!existing.has(baseName)) {\n return baseName;\n }\n\n let suffix = FIRST_DUPLICATE_SUFFIX;\n while (existing.has(`${baseName}-${suffix}`)) {\n suffix += 1;\n }\n return `${baseName}-${suffix}`;\n}\n\nexport function sanitizeProviderProfileName(value: string | undefined): string | undefined {\n const normalized = value\n ?.trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return normalized !== undefined && normalized.length > 0 ? normalized : undefined;\n}\n","import type { ICommandHostContext, ICommandListEntry } from '../host-context.js';\n\nexport const HELP_COMMAND_DESCRIPTION = 'Show available commands';\nconst HELP_COMMAND_NAME_COLUMN_WIDTH = 16;\n\nfunction readCommandList(context: ICommandHostContext): readonly ICommandListEntry[] {\n return context.listCommands?.() ?? [];\n}\n\nexport function formatCommandHelpMessage(context: ICommandHostContext): string {\n const commands = readCommandList(context);\n return [\n 'Available commands:',\n ...commands.map((command) => {\n const displayLabel = command.displayName ?? command.name;\n const invocation = `/${command.name}`;\n const label = command.displayName ? `${displayLabel} (${invocation})` : invocation;\n return ` ${label.padEnd(HELP_COMMAND_NAME_COLUMN_WIDTH * 2)} — ${command.description}`;\n }),\n ].join('\\n');\n}\n","import type {\n IBackgroundTaskListFilter,\n IBackgroundTaskLogCursor,\n IBackgroundTaskLogPage,\n IBackgroundTaskState,\n} from '../../background-tasks/index.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { ICommand } from '../types.js';\n\nconst DECIMAL_RADIX = 10;\nconst INLINE_METADATA_LIMIT = 160;\n\nexport const BACKGROUND_COMMAND_DESCRIPTION = 'List and control background tasks';\nexport const BACKGROUND_COMMAND_USAGE =\n 'Usage: background list | background read <task-id> [offset] | background cancel <task-id> | background close <task-id>';\n\nexport function buildBackgroundCommandSubcommands(): ICommand[] {\n return [\n { name: 'list', description: 'List background tasks', source: 'background' },\n { name: 'read', description: 'Read a background task log page', source: 'background' },\n { name: 'cancel', description: 'Cancel a running background task', source: 'background' },\n { name: 'close', description: 'Dismiss a terminal background task', source: 'background' },\n ];\n}\n\nexport function formatCommandBackgroundTask(task: IBackgroundTaskState): string {\n const preview = task.promptPreview ?? task.commandPreview ?? '';\n const unread = task.unread ? ' unread' : '';\n const action = task.currentAction ? ` (${task.currentAction})` : '';\n const timeout = task.timeoutReason ? ` timeout=${task.timeoutReason}` : '';\n const activity = task.lastActivityAt ? ` lastActivityAt=${task.lastActivityAt}` : '';\n const worktree = formatWorktreeMetadata(task);\n const suffix = preview ? ` — ${preview}` : '';\n return `${task.id} [${task.status}${unread}${timeout}${activity}${worktree}] ${task.kind}:${task.label}${action}${suffix}`;\n}\n\nexport function formatCommandBackgroundTaskList(tasks: IBackgroundTaskState[]): string {\n if (tasks.length === 0) return 'No background tasks.';\n return [\n 'Background tasks:',\n ...tasks.map((task) => ` ${formatCommandBackgroundTask(task)}`),\n ].join('\\n');\n}\n\nexport function parseCommandBackgroundLogCursor(\n value?: string,\n): IBackgroundTaskLogCursor | undefined {\n if (!value) return undefined;\n const offset = Number.parseInt(value, DECIMAL_RADIX);\n return Number.isNaN(offset) ? undefined : { offset };\n}\n\nfunction formatWorktreeMetadata(task: IBackgroundTaskState): string {\n const segments: string[] = [];\n if (task.worktreePath) segments.push(`worktree=${task.worktreePath}`);\n if (task.branchName) segments.push(`branch=${task.branchName}`);\n if (task.worktreeStatus) {\n segments.push(`worktreeStatus=\"${formatInlineMetadata(task.worktreeStatus)}\"`);\n }\n if (task.worktreeNextAction) {\n segments.push(`next=\"${formatInlineMetadata(task.worktreeNextAction)}\"`);\n }\n if (segments.length === 0) return '';\n return ` ${segments.join(' ')}`;\n}\n\nfunction formatInlineMetadata(value: string): string {\n const normalized = value.trim().replace(/\\s+/g, ' ');\n return normalized.length > INLINE_METADATA_LIMIT\n ? `${normalized.slice(0, INLINE_METADATA_LIMIT)}...`\n : normalized;\n}\n\nexport function listCommandBackgroundTasks(\n context: ICommandHostContext,\n filter?: IBackgroundTaskListFilter,\n): IBackgroundTaskState[] {\n return context.listBackgroundTasks(filter);\n}\n\nexport function readCommandBackgroundTaskLog(\n context: ICommandHostContext,\n taskId: string,\n cursor?: IBackgroundTaskLogCursor,\n): Promise<IBackgroundTaskLogPage> {\n return context.readBackgroundTaskLog(taskId, cursor);\n}\n\nexport function cancelCommandBackgroundTask(\n context: ICommandHostContext,\n taskId: string,\n reason?: string,\n): Promise<void> {\n return context.cancelBackgroundTask(taskId, reason);\n}\n\nexport function closeCommandBackgroundTask(\n context: ICommandHostContext,\n taskId: string,\n): Promise<void> {\n return context.closeBackgroundTask(taskId);\n}\n","import {\n CLAUDE_MODELS,\n findProviderDefinition,\n formatTokenCount,\n type IProviderDefinition,\n type IProviderModelCatalog,\n type IProviderModelCatalogEntry,\n type IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\nimport { resolveEnvReference } from '@robota-sdk/agent-core';\n\nimport type { TProviderSettingsDocument } from '../provider/provider-settings.js';\nimport type { ICommand } from '../types.js';\n\nexport const MODEL_COMMAND_DESCRIPTION = 'Change AI model';\nexport const MODEL_COMMAND_ARGUMENT_HINT = '<model-id>';\n\nexport interface IModelCommandSettingsAdapter {\n readMergedSettings(): TProviderSettingsDocument;\n}\n\nexport interface IModelCommandModuleOptions {\n providerDefinitions: readonly IProviderDefinition[];\n settings: IModelCommandSettingsAdapter;\n}\n\nexport interface IBuildModelCommandSubcommandsOptions {\n source?: string;\n providerDefinitions?: readonly IProviderDefinition[];\n settings?: TProviderSettingsDocument;\n}\n\nexport interface IActiveProviderModelCatalogState {\n providerType: string;\n catalog?: IProviderModelCatalog;\n refreshAttempted: boolean;\n refreshMessage?: string;\n}\n\nexport interface IResolveActiveProviderModelCatalogStateOptions {\n settings?: TProviderSettingsDocument;\n providerDefinitions?: readonly IProviderDefinition[];\n refresh?: boolean;\n}\n\nexport function buildModelCommandSubcommands(\n sourceOrOptions: string | IBuildModelCommandSubcommandsOptions = 'model',\n): ICommand[] {\n const options =\n typeof sourceOrOptions === 'string' ? { source: sourceOrOptions } : sourceOrOptions;\n const source = options.source ?? 'model';\n const catalog = resolveActiveProviderModelCatalog(options.settings, options.providerDefinitions);\n if (catalog !== undefined) {\n return buildCatalogSubcommands(catalog, source);\n }\n if (options.settings !== undefined) {\n return [];\n }\n return buildClaudeModelSubcommands(source);\n}\n\nexport function formatModelCommandUsageMessage(\n options: {\n settings?: TProviderSettingsDocument;\n providerDefinitions?: readonly IProviderDefinition[];\n } = {},\n): string {\n const snapshot = resolveActiveProviderModelCatalogSnapshot(\n options.settings,\n options.providerDefinitions,\n );\n return formatModelUsageMessage(snapshot === undefined ? undefined : toCatalogState(snapshot));\n}\n\nexport async function formatModelCommandUsageMessageAsync(\n options: IResolveActiveProviderModelCatalogStateOptions = {},\n): Promise<string> {\n return formatModelUsageMessage(await resolveActiveProviderModelCatalogState(options));\n}\n\nexport function resolveActiveProviderModelCatalog(\n settings: TProviderSettingsDocument | undefined,\n providerDefinitions: readonly IProviderDefinition[] = [],\n): IProviderModelCatalog | undefined {\n return resolveActiveProviderModelCatalogSnapshot(settings, providerDefinitions)?.catalog;\n}\n\nexport async function resolveActiveProviderModelCatalogState(\n options: IResolveActiveProviderModelCatalogStateOptions,\n): Promise<IActiveProviderModelCatalogState | undefined> {\n const snapshot = resolveActiveProviderModelCatalogSnapshot(\n options.settings,\n options.providerDefinitions,\n );\n if (snapshot === undefined) return undefined;\n const shouldRefresh =\n options.refresh === true ||\n isCatalogStale(snapshot.catalog, snapshot.definition?.modelCatalogCacheTtlSeconds);\n if (!shouldRefresh || snapshot.definition?.refreshModelCatalog === undefined) {\n return toCatalogState(snapshot);\n }\n\n try {\n const refreshed = await snapshot.definition.refreshModelCatalog({\n profile: resolveRefreshProfile(snapshot),\n });\n if (refreshed.status !== 'unavailable') {\n return {\n providerType: snapshot.providerType,\n catalog: refreshed,\n refreshAttempted: true,\n };\n }\n return {\n providerType: snapshot.providerType,\n catalog: snapshot.catalog ?? refreshed,\n refreshAttempted: true,\n ...(refreshed.message !== undefined ? { refreshMessage: refreshed.message } : {}),\n };\n } catch (error) {\n return {\n providerType: snapshot.providerType,\n ...(snapshot.catalog !== undefined ? { catalog: snapshot.catalog } : {}),\n refreshAttempted: true,\n refreshMessage: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nfunction buildClaudeModelSubcommands(source: string): ICommand[] {\n const seen = new Set<string>();\n const commands: ICommand[] = [];\n for (const model of Object.values(CLAUDE_MODELS)) {\n if (seen.has(model.name)) continue;\n seen.add(model.name);\n commands.push({\n name: model.id,\n description: `${model.name} (${formatTokenCount(model.contextWindow).toUpperCase()})`,\n source,\n });\n }\n return commands;\n}\n\nfunction buildCatalogSubcommands(catalog: IProviderModelCatalog, source: string): ICommand[] {\n return (catalog.entries ?? [])\n .filter((entry) => entry.lifecycle !== 'unavailable')\n .map((entry) => ({\n name: entry.id,\n description: formatCatalogEntryDescription(entry),\n source,\n }));\n}\n\nfunction formatCatalogEntryDescription(entry: IProviderModelCatalogEntry): string {\n if (entry.contextWindow === undefined) {\n return entry.displayName;\n }\n return `${entry.displayName} (${formatTokenCount(entry.contextWindow).toUpperCase()})`;\n}\n\ninterface IActiveProviderModelCatalogSnapshot {\n providerType: string;\n profile?: IProviderProfileConfig;\n definition?: IProviderDefinition;\n catalog?: IProviderModelCatalog;\n}\n\nfunction resolveActiveProviderModelCatalogSnapshot(\n settings: TProviderSettingsDocument | undefined,\n providerDefinitions: readonly IProviderDefinition[] = [],\n): IActiveProviderModelCatalogSnapshot | undefined {\n const profile = resolveActiveProviderProfile(settings);\n const providerType = profile?.type ?? profile?.name;\n if (providerType === undefined) {\n return undefined;\n }\n const definition = findProviderDefinition(providerDefinitions, providerType);\n return {\n providerType,\n ...(profile !== undefined ? { profile } : {}),\n ...(definition !== undefined ? { definition } : {}),\n ...(definition?.modelCatalog !== undefined ? { catalog: definition.modelCatalog } : {}),\n };\n}\n\nfunction resolveActiveProviderProfile(\n settings: TProviderSettingsDocument | undefined,\n): (IProviderProfileConfig & { name?: string }) | undefined {\n if (settings?.currentProvider !== undefined) {\n return settings.providers?.[settings.currentProvider];\n }\n return settings?.provider;\n}\n\nfunction toCatalogState(\n snapshot: IActiveProviderModelCatalogSnapshot,\n): IActiveProviderModelCatalogState {\n return {\n providerType: snapshot.providerType,\n ...(snapshot.catalog !== undefined ? { catalog: snapshot.catalog } : {}),\n refreshAttempted: false,\n };\n}\n\nfunction isCatalogStale(\n catalog: IProviderModelCatalog | undefined,\n ttlSeconds: number | undefined,\n): boolean {\n if (catalog === undefined || ttlSeconds === undefined || catalog.lastVerifiedAt === undefined) {\n return false;\n }\n const ageMs = Date.now() - new Date(catalog.lastVerifiedAt).getTime();\n return ageMs > ttlSeconds * 1000;\n}\n\nfunction resolveRefreshProfile(\n snapshot: IActiveProviderModelCatalogSnapshot,\n): IProviderProfileConfig {\n const profile = snapshot.profile;\n const defaults = snapshot.definition?.defaults;\n const apiKey = resolveOptionalEnvReference(profile?.apiKey ?? defaults?.apiKey);\n const model = resolveProfileValue(profile?.model, defaults?.model);\n const baseURL = resolveProfileValue(profile?.baseURL, defaults?.baseURL);\n const timeout = resolveProfileValue(profile?.timeout, defaults?.timeout);\n const options = resolveProfileValue(profile?.options, defaults?.options);\n const refreshProfile: IProviderProfileConfig = {\n type: profile?.type ?? snapshot.providerType,\n };\n\n if (model !== undefined) refreshProfile.model = model;\n if (apiKey !== undefined) refreshProfile.apiKey = apiKey;\n if (baseURL !== undefined) refreshProfile.baseURL = baseURL;\n if (timeout !== undefined) refreshProfile.timeout = timeout;\n if (options !== undefined) refreshProfile.options = options;\n return refreshProfile;\n}\n\nfunction resolveProfileValue<T>(\n profileValue: T | undefined,\n defaultValue: T | undefined,\n): T | undefined {\n return profileValue ?? defaultValue;\n}\n\nfunction resolveOptionalEnvReference(value: string | undefined): string | undefined {\n return value === undefined ? undefined : resolveEnvReference(value);\n}\n\nfunction formatModelUsageMessage(active: IActiveProviderModelCatalogState | undefined): string {\n const base =\n active?.providerType !== undefined &&\n (active.catalog?.entries === undefined || active.catalog.entries.length === 0)\n ? `No model catalog available for provider ${active.providerType}. Usage: model <model-id>`\n : 'Usage: model <model-id>';\n const freshness = formatCatalogFreshness(active);\n return freshness === undefined ? base : `${base}\\n${freshness}`;\n}\n\nfunction formatCatalogFreshness(\n active: IActiveProviderModelCatalogState | undefined,\n): string | undefined {\n const catalog = active?.catalog;\n if (catalog === undefined) return undefined;\n\n const parts = [`Catalog: ${catalog.status}`];\n if (catalog.entries !== undefined) {\n parts.push(`${catalog.entries.length} model(s)`);\n }\n if (catalog.lastVerifiedAt !== undefined) {\n parts.push(`verified ${catalog.lastVerifiedAt}`);\n }\n if (catalog.sourceUrl !== undefined) {\n parts.push(`source ${catalog.sourceUrl}`);\n }\n const refreshMessage = active?.refreshMessage;\n if (refreshMessage !== undefined) {\n parts.push(`refresh ${refreshMessage}`);\n } else if (catalog.message !== undefined) {\n parts.push(catalog.message);\n }\n return parts.join('; ');\n}\n","import type { ICommand } from '../types.js';\n\nexport const LANGUAGE_COMMAND_DESCRIPTION = 'Set response language';\nexport const LANGUAGE_COMMAND_ARGUMENT_HINT = '<code>';\n\nexport const RECOMMENDED_RESPONSE_LANGUAGES = [\n { code: 'ko', description: 'Korean' },\n { code: 'en', description: 'English' },\n { code: 'ja', description: 'Japanese' },\n { code: 'zh', description: 'Chinese' },\n] as const;\n\nexport type TRecommendedResponseLanguage = (typeof RECOMMENDED_RESPONSE_LANGUAGES)[number]['code'];\n\nexport function buildLanguageCommandSubcommands(source = 'language'): ICommand[] {\n return RECOMMENDED_RESPONSE_LANGUAGES.map((language) => ({\n name: language.code,\n description: language.description,\n source,\n }));\n}\n\nexport function parseLanguageArgument(args: string): string | undefined {\n const language = args.trim().split(/\\s+/)[0];\n return language !== undefined && language.length > 0 ? language : undefined;\n}\n\nexport function formatLanguageUsageMessage(commandName = 'language'): string {\n return `Usage: ${commandName} <code> (e.g., ko, en, ja, zh)`;\n}\n","import type { ICommandPermissionModeAdapter } from '../host-adapters.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { ICommand } from '../types.js';\nimport type { TPermissionMode } from '@robota-sdk/agent-core';\n\nexport const PERMISSION_MODE_COMMAND_DESCRIPTION = 'Show/change permission mode';\nexport const PERMISSION_MODE_ARGUMENT_HINT = 'plan | default | acceptEdits | bypassPermissions';\nexport const PERMISSIONS_COMMAND_DESCRIPTION = 'Show/change permission mode and permission rules';\n\nexport interface IPermissionsCommandState {\n readonly mode: TPermissionMode;\n readonly sessionAllowed: readonly string[];\n}\nexport const VALID_PERMISSION_MODES: readonly TPermissionMode[] = [\n 'plan',\n 'default',\n 'acceptEdits',\n 'bypassPermissions',\n];\n\nexport function buildPermissionModeSubcommands(source = 'mode'): ICommand[] {\n return [\n { name: 'plan', description: 'Plan only, no execution', source },\n { name: 'default', description: 'Ask before risky actions', source },\n { name: 'acceptEdits', description: 'Auto-approve file edits', source },\n { name: 'bypassPermissions', description: 'Skip all permission checks', source },\n ];\n}\n\nexport function parsePermissionModeArgument(args: string): string | undefined {\n const mode = args.trim().split(/\\s+/)[0];\n return mode !== undefined && mode.length > 0 ? mode : undefined;\n}\n\nexport function isPermissionMode(value: string): value is TPermissionMode {\n return (VALID_PERMISSION_MODES as readonly string[]).includes(value);\n}\n\nexport function formatInvalidPermissionModeMessage(): string {\n return `Invalid mode. Valid: ${VALID_PERMISSION_MODES.join(' | ')}`;\n}\n\nexport function resolvePermissionModeAdapter(\n context: ICommandHostContext,\n): ICommandPermissionModeAdapter {\n const adapter = context.getCommandHostAdapters?.().permissionMode;\n if (adapter !== undefined) {\n return adapter;\n }\n\n const runtime = context.getSession();\n return {\n getPermissionMode: () => runtime.getPermissionMode(),\n setPermissionMode: (mode) => runtime.setPermissionMode(mode),\n listSessionAllowedTools: () => runtime.getSessionAllowedTools(),\n };\n}\n\nexport function readCommandPermissionMode(context: ICommandHostContext): TPermissionMode {\n return resolvePermissionModeAdapter(context).getPermissionMode();\n}\n\nexport function writeCommandPermissionMode(\n context: ICommandHostContext,\n mode: TPermissionMode,\n): void {\n resolvePermissionModeAdapter(context).setPermissionMode(mode);\n}\n\nexport function listCommandSessionAllowedTools(context: ICommandHostContext): readonly string[] {\n return resolvePermissionModeAdapter(context).listSessionAllowedTools();\n}\n\nexport function readCommandPermissionsState(\n context: ICommandHostContext,\n): IPermissionsCommandState {\n return {\n mode: readCommandPermissionMode(context),\n sessionAllowed: listCommandSessionAllowedTools(context),\n };\n}\n\nexport function formatCommandPermissionsMessage(state: IPermissionsCommandState): string {\n const lines = [`Permission mode: ${state.mode}`];\n if (state.sessionAllowed.length > 0) {\n lines.push(`Session-approved tools: ${state.sessionAllowed.join(', ')}`);\n } else {\n lines.push('No session-approved tools.');\n }\n return lines.join('\\n');\n}\n","import { readSettings, writeSettings } from '../../config/settings-io.js';\n\nimport type { TSettingsData } from '../../config/settings-io.js';\nimport type { ICommand } from '../types.js';\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\n\nexport const STATUSLINE_COMMAND_DESCRIPTION =\n 'Configure TUI status-line visibility and fields such as model, context, tokens, session, and git branch.';\nexport const STATUSLINE_COMMAND_ARGUMENT_HINT = 'on | off | reset | git on | git off';\n\nexport interface IStatusLineCommandSettings {\n enabled: boolean;\n gitBranch: boolean;\n}\n\nexport type TStatusLineCommandSettingsPatch = Partial<IStatusLineCommandSettings> &\n Record<string, TUniversalValue>;\n\nexport const DEFAULT_STATUS_LINE_COMMAND_SETTINGS: Readonly<IStatusLineCommandSettings> = {\n enabled: true,\n gitBranch: true,\n};\n\nexport function buildStatusLineCommandSubcommands(source = 'statusline'): ICommand[] {\n return [\n { name: 'on', description: 'Show the status line', source },\n { name: 'off', description: 'Hide the status line', source },\n { name: 'reset', description: 'Restore default status-line fields', source },\n { name: 'git', description: 'Show or hide git branch field', source },\n ];\n}\n\nexport function isStatusLineCommandSettingsPatch(\n value: Record<string, TUniversalValue>,\n): value is TStatusLineCommandSettingsPatch {\n return (\n (value.enabled === undefined || typeof value.enabled === 'boolean') &&\n (value.gitBranch === undefined || typeof value.gitBranch === 'boolean')\n );\n}\n\nexport function readStatusLineSettings(settings: TSettingsData): IStatusLineCommandSettings {\n const raw = settings.statusline;\n if (!isRecord(raw)) {\n return { ...DEFAULT_STATUS_LINE_COMMAND_SETTINGS };\n }\n return {\n enabled:\n typeof raw.enabled === 'boolean' ? raw.enabled : DEFAULT_STATUS_LINE_COMMAND_SETTINGS.enabled,\n gitBranch:\n typeof raw.gitBranch === 'boolean'\n ? raw.gitBranch\n : DEFAULT_STATUS_LINE_COMMAND_SETTINGS.gitBranch,\n };\n}\n\nexport function applyStatusLineSettings(\n settingsPath: string,\n patch: TStatusLineCommandSettingsPatch,\n): IStatusLineCommandSettings {\n const settings = readSettings(settingsPath);\n const next = {\n ...readStatusLineSettings(settings),\n ...patch,\n };\n settings.statusline = next as TSettingsData;\n writeSettings(settingsPath, settings);\n return next;\n}\n\nfunction isRecord(value: TUniversalValue): value is Record<string, TUniversalValue> {\n return (\n value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)\n );\n}\n","import type { TCommandEffect } from '../effects.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { ICommand } from '../types.js';\n\nexport const PLUGIN_COMMAND_DESCRIPTION = 'Manage plugins';\nexport const PLUGIN_COMMAND_ARGUMENT_HINT =\n 'manage | install <name@marketplace> | uninstall <name@marketplace> | enable <name@marketplace> | disable <name@marketplace> | marketplace <action>';\nexport const RELOAD_PLUGINS_COMMAND_DESCRIPTION = 'Reload all plugin resources';\n\nexport type TPluginInstallScope = 'user' | 'project';\n\nexport interface ICommandInstalledPlugin {\n name: string;\n description: string;\n enabled: boolean;\n}\n\nexport interface ICommandAvailablePlugin {\n name: string;\n description: string;\n installed: boolean;\n}\n\nexport interface ICommandMarketplaceSource {\n name: string;\n type: string;\n}\n\nexport interface ICommandPluginReloadResult {\n loadedPluginCount: number;\n}\n\nexport interface ICommandPluginAdapter {\n listInstalled(): Promise<readonly ICommandInstalledPlugin[]>;\n listAvailablePlugins(marketplace: string): Promise<readonly ICommandAvailablePlugin[]>;\n install(pluginId: string, scope?: TPluginInstallScope): Promise<void>;\n uninstall(pluginId: string): Promise<void>;\n enable(pluginId: string): Promise<void>;\n disable(pluginId: string): Promise<void>;\n marketplaceAdd(source: string): Promise<string>;\n marketplaceRemove(name: string): Promise<void>;\n marketplaceUpdate(name: string): Promise<void>;\n marketplaceList(): Promise<readonly ICommandMarketplaceSource[]>;\n reloadPlugins(): Promise<ICommandPluginReloadResult>;\n}\n\nexport function createPluginTuiRequestedEffect(): TCommandEffect {\n return { type: 'plugin-tui-requested' };\n}\n\nexport function createPluginRegistryReloadRequestedEffect(): TCommandEffect {\n return { type: 'plugin-registry-reload-requested' };\n}\n\nexport function resolvePluginCommandAdapter(\n context: ICommandHostContext,\n): ICommandPluginAdapter | undefined {\n return context.getCommandHostAdapters?.().plugin;\n}\n\nexport function buildPluginCommandSubcommands(): ICommand[] {\n return [\n { name: 'manage', description: 'Open plugin manager', source: 'plugin-manager' },\n { name: 'install', description: 'Install a plugin', source: 'plugin-manager' },\n { name: 'uninstall', description: 'Uninstall a plugin', source: 'plugin-manager' },\n { name: 'enable', description: 'Enable a plugin', source: 'plugin-manager' },\n { name: 'disable', description: 'Disable a plugin', source: 'plugin-manager' },\n {\n name: 'marketplace',\n description: 'Manage plugin marketplaces',\n source: 'plugin-manager',\n subcommands: [\n { name: 'add', description: 'Add marketplace source', source: 'plugin-manager' },\n { name: 'remove', description: 'Remove marketplace source', source: 'plugin-manager' },\n { name: 'update', description: 'Update marketplace source', source: 'plugin-manager' },\n { name: 'list', description: 'List marketplace sources', source: 'plugin-manager' },\n ],\n },\n ];\n}\n","import { join } from 'node:path';\n\nimport { loadSessionLogEntries, validateSessionReplayLogEntries } from '@robota-sdk/agent-session';\n\nimport { projectPaths } from '../../paths.js';\n\nimport type { TCommandEffect } from '../effects.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { ICommandSessionReplayValidationReport } from '../host-context.js';\n\nexport const CLEAR_COMMAND_DESCRIPTION = 'Clear conversation history';\nexport const RENAME_COMMAND_DESCRIPTION = 'Rename the current session';\nexport const RENAME_COMMAND_USAGE = 'Usage: rename <name>';\nexport const RESUME_COMMAND_DESCRIPTION = 'Resume a previous session';\nexport const COST_COMMAND_DESCRIPTION = 'Show session info';\nexport const VALIDATE_SESSION_COMMAND_DESCRIPTION = 'Validate current session replay log';\nexport const EXIT_COMMAND_DESCRIPTION = 'Exit CLI';\n\nexport interface ICommandSessionInfo {\n sessionId: string;\n messageCount: number;\n}\n\nexport function clearConversationHistory(context: ICommandHostContext): void {\n if (context.clearConversationHistory !== undefined) {\n context.clearConversationHistory();\n return;\n }\n\n context.getSession().clearHistory();\n}\n\nexport function parseSessionNameArgument(args: string): string | undefined {\n const name = args.trim();\n return name.length > 0 ? name : undefined;\n}\n\nexport function createSessionRenamedEffect(name: string): TCommandEffect {\n return { type: 'session-renamed', name };\n}\n\nexport function createSessionPickerRequestedEffect(): TCommandEffect {\n return { type: 'session-picker-requested' };\n}\n\nexport function createSessionExitRequestedEffect(): TCommandEffect {\n return { type: 'session-exit-requested' };\n}\n\nexport function readCommandSessionInfo(context: ICommandHostContext): ICommandSessionInfo {\n const session = context.getSession();\n return {\n sessionId: session.getSessionId(),\n messageCount: session.getMessageCount(),\n };\n}\n\nexport function validateCommandSessionReplayLog(\n context: ICommandHostContext,\n): ICommandSessionReplayValidationReport {\n const hostReport = context.validateCurrentSessionReplayLog?.();\n if (hostReport !== undefined) {\n return hostReport;\n }\n\n const sessionId = context.getSession().getSessionId();\n const logFile = join(projectPaths(context.getCwd()).logs, `${sessionId}.jsonl`);\n const entries = loadSessionLogEntries(logFile);\n return {\n logFile,\n entryCount: entries.length,\n validation: validateSessionReplayLogEntries(entries),\n };\n}\n\nexport function formatCommandSessionReplayValidationReport(\n report: ICommandSessionReplayValidationReport,\n): string {\n const header = report.validation.ok\n ? 'Session replay log is valid.'\n : `Session replay log has ${report.validation.issues.length} issue(s).`;\n const details = [`Log: ${report.logFile}`, `Entries: ${report.entryCount}`];\n if (report.validation.ok) {\n return [header, ...details].join('\\n');\n }\n\n const issueLines = report.validation.issues.map((issue, index) => {\n const location = formatReplayValidationIssueLocation(issue);\n return `${index + 1}. ${issue.code}${location}: ${issue.message}`;\n });\n return [header, ...details, '', ...issueLines].join('\\n');\n}\n\nfunction formatReplayValidationIssueLocation(\n issue: ICommandSessionReplayValidationReport['validation']['issues'][number],\n): string {\n const parts: string[] = [];\n if (issue.executionId !== undefined) {\n parts.push(`execution=${issue.executionId}`);\n }\n if (issue.round !== undefined) {\n parts.push(`round=${issue.round}`);\n }\n if (issue.toolCallId !== undefined) {\n parts.push(`tool=${issue.toolCallId}`);\n }\n return parts.length > 0 ? ` (${parts.join(', ')})` : '';\n}\n\nexport type { ICommandSessionReplayValidationReport };\n","import type {\n IEditCheckpointInspection,\n IEditCheckpointRestoreResult,\n IEditCheckpointSummary,\n} from '../../checkpoints/index.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { ICommand } from '../types.js';\n\nexport const REWIND_COMMAND_DESCRIPTION = 'List, inspect, restore, or rollback edit checkpoints.';\nexport const REWIND_COMMAND_ARGUMENT_HINT =\n 'list | inspect CHECKPOINT_ID | restore CHECKPOINT_ID | code CHECKPOINT_ID | rollback CHECKPOINT_ID';\n\nexport function buildRewindCommandSubcommands(source = 'rewind'): ICommand[] {\n return [\n { name: 'list', description: 'List edit checkpoints', source },\n { name: 'inspect', description: 'Inspect captured files and restore plans', source },\n { name: 'restore', description: 'Restore code to a checkpoint', source },\n { name: 'code', description: 'Restore code to a checkpoint', source },\n { name: 'rollback', description: 'Rollback code through a checkpoint', source },\n ];\n}\n\nexport function listCommandEditCheckpoints(\n context: ICommandHostContext,\n): readonly IEditCheckpointSummary[] {\n return context.listEditCheckpoints();\n}\n\nexport function inspectCommandEditCheckpoint(\n context: ICommandHostContext,\n checkpointId: string,\n): IEditCheckpointInspection {\n if (!context.inspectEditCheckpoint) {\n throw new Error('Checkpoint inspection is not available in this command host.');\n }\n return context.inspectEditCheckpoint(checkpointId);\n}\n\nexport function restoreCommandEditCheckpoint(\n context: ICommandHostContext,\n checkpointId: string,\n): Promise<IEditCheckpointRestoreResult> {\n return context.restoreEditCheckpoint(checkpointId);\n}\n\nexport function rollbackCommandEditCheckpoint(\n context: ICommandHostContext,\n checkpointId: string,\n): Promise<IEditCheckpointRestoreResult> {\n return context.rollbackEditCheckpoint(checkpointId);\n}\n","import type {\n IAutomaticMemoryConfig,\n IMemoryCandidate,\n IMemoryDecision,\n} from './automatic-memory-types.js';\n\nconst AUTO_SAVE_CONFIDENCE_THRESHOLD = 0.85;\nconst SENSITIVE_PATTERNS: readonly RegExp[] = [\n /\\b(api[_-]?key|secret|token|password|private key)\\b/i,\n /\\b\\d{3}-\\d{2}-\\d{4}\\b/,\n /\\b\\d{4}[- ]?\\d{4}[- ]?\\d{4}[- ]?\\d{4}\\b/,\n /주민등록|비밀번호|시크릿|토큰/u,\n];\n\nexport function containsSensitiveMemoryContent(text: string): boolean {\n return SENSITIVE_PATTERNS.some((pattern) => pattern.test(text));\n}\n\nexport class MemoryPolicyEvaluator {\n evaluate(candidate: IMemoryCandidate, config: IAutomaticMemoryConfig): IMemoryDecision {\n if (config.policy === 'disabled') {\n return { action: 'skip', reason: 'memory-policy-disabled' };\n }\n\n if (containsSensitiveMemoryContent(candidate.text)) {\n return { action: 'skip', reason: 'sensitive-content' };\n }\n\n if (config.policy === 'approval_required') {\n return { action: 'queue', reason: 'approval-required' };\n }\n\n if (candidate.confidence >= AUTO_SAVE_CONFIDENCE_THRESHOLD) {\n return { action: 'save', reason: 'high-confidence-auto-save' };\n }\n\n return { action: 'queue', reason: 'low-confidence-auto-save-review' };\n }\n}\n","import { dirname, join } from 'node:path';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\n\nimport type {\n IMemoryCandidate,\n IMemoryPendingRecord,\n TMemoryCandidateStatus,\n} from './automatic-memory-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\n\ninterface IPendingMemoryDocument {\n version: 1;\n records: IMemoryPendingRecord[];\n}\n\nconst PENDING_FILENAME = 'pending.json';\n\nfunction memoryRoot(cwd: string): string {\n return join(cwd, '.robota', 'memory');\n}\n\nfunction emptyDocument(): IPendingMemoryDocument {\n return { version: 1, records: [] };\n}\n\nexport class PendingMemoryStore {\n private readonly path: string;\n private readonly now: () => Date;\n\n constructor(\n cwd: string,\n now: () => Date = () => new Date(),\n private readonly fs: IFileSystem = new NodeFileSystem(),\n ) {\n this.path = join(memoryRoot(cwd), PENDING_FILENAME);\n this.now = now;\n }\n\n getPath(): string {\n return this.path;\n }\n\n list(status?: TMemoryCandidateStatus): IMemoryPendingRecord[] {\n const records = this.read().records;\n return status ? records.filter((record) => record.status === status) : records;\n }\n\n get(id: string): IMemoryPendingRecord | undefined {\n return this.read().records.find((record) => record.id === id);\n }\n\n upsert(candidate: IMemoryCandidate, status: TMemoryCandidateStatus, reason: string): void {\n const document = this.read();\n const updatedAt = this.now().toISOString();\n const existingIndex = document.records.findIndex((record) => record.id === candidate.id);\n const record: IMemoryPendingRecord = {\n ...candidate,\n status,\n updatedAt,\n decisionReason: reason,\n };\n if (existingIndex >= 0) {\n document.records[existingIndex] = { ...document.records[existingIndex], ...record };\n } else {\n document.records.push(record);\n }\n this.write(document);\n }\n\n mark(id: string, status: TMemoryCandidateStatus, reason: string): IMemoryPendingRecord {\n const document = this.read();\n const index = document.records.findIndex((record) => record.id === id);\n if (index < 0) throw new Error(`Memory candidate not found: ${id}`);\n const record = {\n ...document.records[index],\n status,\n updatedAt: this.now().toISOString(),\n decisionReason: reason,\n };\n document.records[index] = record;\n this.write(document);\n return record;\n }\n\n private read(): IPendingMemoryDocument {\n if (!this.fs.existsSync(this.path)) return emptyDocument();\n try {\n const parsed = JSON.parse(this.fs.readFileSync(this.path, 'utf8')) as IPendingMemoryDocument;\n return { version: 1, records: parsed.records ?? [] };\n } catch {\n // allow-fallback: corrupt JSON treated as empty document\n return emptyDocument();\n }\n }\n\n private write(document: IPendingMemoryDocument): void {\n this.fs.mkdirSync(dirname(this.path), { recursive: true });\n this.fs.writeFileSync(this.path, JSON.stringify(document, null, 2), 'utf8');\n }\n}\n","import { containsSensitiveMemoryContent } from '../../memory/memory-policy-evaluator.js';\nimport { PendingMemoryStore } from '../../memory/pending-memory-store.js';\nimport {\n ProjectMemoryStore,\n isMemoryType,\n type IAppendMemoryInput,\n type IAppendMemoryResult,\n type IProjectMemorySummary,\n type IStartupMemory,\n type TMemoryType,\n} from '../../memory/project-memory-store.js';\n\nimport type {\n IMemoryCandidate,\n IMemoryEvent,\n IMemoryPendingRecord,\n IMemoryReference,\n TMemoryCandidateStatus,\n} from '../../memory/automatic-memory-types.js';\nimport type { ICommandHostContext } from '../host-context.js';\nimport type { ICommand } from '../types.js';\n\nexport const MEMORY_COMMAND_DESCRIPTION =\n 'Project memory command. Use it to inspect project memory when stored context may help, save durable preferences, project conventions, feedback, or references worth reusing across sessions, review pending candidates, and report memory provenance. Do not store secrets, credentials, or transient facts.';\nexport const MEMORY_COMMAND_ARGUMENT_HINT =\n 'list | show [topic] | add <user|feedback|project|reference> <topic> <text> | pending | approve <id> | reject <id> | used';\nexport const MEMORY_COMMAND_USAGE =\n 'Usage: memory list | memory show [topic] | memory add <user|feedback|project|reference> <topic> <text> | memory pending | memory approve <id> | memory reject <id> | memory used';\n\nexport interface ICommandProjectMemoryStore {\n list(): IProjectMemorySummary;\n loadStartupMemory(): IStartupMemory;\n readTopic(topic: string): string;\n append(input: IAppendMemoryInput): IAppendMemoryResult;\n}\n\nexport interface ICommandPendingMemoryStore {\n get(id: string): IMemoryPendingRecord | undefined;\n list(status?: TMemoryCandidateStatus): IMemoryPendingRecord[];\n mark(id: string, status: TMemoryCandidateStatus, reason: string): IMemoryPendingRecord;\n upsert(candidate: IMemoryCandidate, status: TMemoryCandidateStatus, reason: string): void;\n}\n\nexport interface ICommandMemoryStores {\n project: ICommandProjectMemoryStore;\n pending: ICommandPendingMemoryStore;\n}\n\nexport type {\n IAppendMemoryInput,\n IAppendMemoryResult,\n IMemoryCandidate,\n IMemoryEvent,\n IMemoryPendingRecord,\n IMemoryReference,\n IProjectMemorySummary,\n IStartupMemory,\n TMemoryCandidateStatus,\n TMemoryType,\n};\n\nexport function buildMemoryCommandSubcommands(source = 'memory'): ICommand[] {\n return [\n { name: 'list', description: 'List project memory topics', source },\n { name: 'show', description: 'Show project memory index or a topic', source },\n { name: 'add', description: 'Save durable project memory', source },\n { name: 'pending', description: 'List pending memory candidates', source },\n { name: 'approve', description: 'Approve a pending memory candidate', source },\n { name: 'reject', description: 'Reject a pending memory candidate', source },\n {\n name: 'used',\n description: 'Show memory references used in the current turn',\n source,\n },\n ];\n}\n\nexport function createCommandProjectMemoryStore(\n cwd: string,\n now?: () => Date,\n): ICommandProjectMemoryStore {\n return new ProjectMemoryStore(cwd, now);\n}\n\nexport function createCommandPendingMemoryStore(\n cwd: string,\n now?: () => Date,\n): ICommandPendingMemoryStore {\n return new PendingMemoryStore(cwd, now);\n}\n\nexport function createCommandMemoryStores(\n context: ICommandHostContext,\n now?: () => Date,\n): ICommandMemoryStores {\n const cwd = context.getCwd();\n return {\n project: createCommandProjectMemoryStore(cwd, now),\n pending: createCommandPendingMemoryStore(cwd, now),\n };\n}\n\nexport function isCommandMemoryType(value: string): value is TMemoryType {\n return isMemoryType(value);\n}\n\nexport function hasSensitiveCommandMemoryContent(text: string): boolean {\n return containsSensitiveMemoryContent(text);\n}\n\nexport function listCommandUsedMemoryReferences(\n context: ICommandHostContext,\n): readonly IMemoryReference[] {\n return context.getUsedMemoryReferences();\n}\n\nexport function recordCommandMemoryEvent(\n context: ICommandHostContext,\n event: Omit<IMemoryEvent, 'at'>,\n now: () => Date = () => new Date(),\n): void {\n context.recordMemoryEvent({\n ...event,\n at: now().toISOString(),\n });\n}\n","/** Shell exec function for skill preprocessing — injected from composition root. */\nexport type TShellExecFn = (command: string) => string;\n\n/** Context variables available during skill prompt processing */\nexport interface SkillPromptContext {\n /** Current session ID — substituted for ${CLAUDE_SESSION_ID} */\n sessionId?: string;\n /** Directory containing SKILL.md — substituted for ${CLAUDE_SKILL_DIR} */\n skillDir?: string;\n}\n\n/**\n * Substitute variables in skill content.\n *\n * Supported variables:\n * - `$ARGUMENTS` — all arguments passed to the skill\n * - `$ARGUMENTS[N]` — argument by index (0-based)\n * - `$N` — shorthand for `$ARGUMENTS[N]` (single digit, 0-9)\n * - `${CLAUDE_SESSION_ID}` — current session ID\n * - `${CLAUDE_SKILL_DIR}` — directory containing SKILL.md\n */\nexport function substituteVariables(\n content: string,\n args: string,\n context?: SkillPromptContext,\n): string {\n const argParts = args ? args.split(/\\s+/) : [];\n\n let result = content;\n\n // Replace $ARGUMENTS[N] before $ARGUMENTS to avoid partial match\n result = result.replace(/\\$ARGUMENTS\\[(\\d+)]/g, (_match, index: string) => {\n return argParts[Number(index)] ?? '';\n });\n\n // Replace $ARGUMENTS with all args\n result = result.replace(/\\$ARGUMENTS/g, args);\n\n // Replace $N shorthand (single digit, 0-9)\n result = result.replace(/\\$(\\d)(?!\\d|\\w|\\[)/g, (_match, digit: string) => {\n return argParts[Number(digit)] ?? '';\n });\n\n // Replace ${CLAUDE_SESSION_ID}\n result = result.replace(/\\$\\{CLAUDE_SESSION_ID}/g, context?.sessionId ?? '');\n\n // Replace ${CLAUDE_SKILL_DIR}\n result = result.replace(/\\$\\{CLAUDE_SKILL_DIR}/g, context?.skillDir ?? '');\n\n return result;\n}\n\n/**\n * Preprocess shell commands in skill content.\n * Matches `` !`...` `` patterns and replaces them with command output.\n * If no exec function is provided, shell patterns are replaced with empty string.\n */\nexport async function preprocessShellCommands(\n content: string,\n exec?: TShellExecFn,\n): Promise<string> {\n const shellPattern = /!`([^`]+)`/g;\n\n if (!shellPattern.test(content)) {\n return content;\n }\n\n // Reset lastIndex after test()\n shellPattern.lastIndex = 0;\n\n let result = content;\n let match: RegExpExecArray | null;\n\n // Collect all matches first to avoid mutation issues during replacement\n const matches: Array<{ full: string; command: string }> = [];\n while ((match = shellPattern.exec(content)) !== null) {\n matches.push({ full: match[0], command: match[1] });\n }\n\n for (const { full, command } of matches) {\n let output = '';\n if (exec) {\n try {\n output = exec(command);\n } catch {\n output = '';\n }\n }\n result = result.replace(full, output);\n }\n\n return result;\n}\n","/**\n * Skill execution logic.\n * Handles both fork-based (subagent) and inject-based (user message) execution.\n */\n\nimport {\n preprocessShellCommands,\n substituteVariables,\n type SkillPromptContext,\n type TShellExecFn,\n} from '../utils/skill-prompt.js';\n\nimport type { ICommand } from '../command-api/types.js';\n\n/** Options passed to the fork execution callback */\nexport interface IForkExecutionOptions {\n /** Agent identity to use (e.g., 'Explore', 'Plan') */\n agent?: string;\n /** Tools the subagent is allowed to use */\n allowedTools?: string[];\n}\n\n/** Callback interface for skill execution infrastructure */\nexport interface ISkillExecutionCallbacks {\n /**\n * Run skill content in an isolated subagent session.\n * The content becomes the subagent's prompt.\n * Returns the subagent's response.\n */\n runInFork?: (content: string, options: IForkExecutionOptions) => Promise<string>;\n /** Shell exec function for preprocessing `` !`cmd` `` patterns — injected from composition root. */\n shellExec?: TShellExecFn;\n}\n\n/** Result of skill execution */\nexport interface ISkillExecutionResult {\n /** Execution mode used */\n mode: 'fork' | 'inject';\n /** For inject mode: the prompt to send as a user message */\n prompt?: string;\n /** For fork mode: the subagent's response */\n result?: string;\n}\n\n/**\n * Build the processed skill content with variable substitution.\n * Returns the raw content after substitution (no XML wrapping).\n */\nasync function buildProcessedContent(\n skill: ICommand,\n args: string,\n callbacks: ISkillExecutionCallbacks,\n context?: SkillPromptContext,\n): Promise<string | null> {\n if (!skill.skillContent) return null;\n const preprocessed = await preprocessShellCommands(skill.skillContent, callbacks.shellExec);\n return substituteVariables(preprocessed, args, context);\n}\n\n/**\n * Build an inject-mode prompt from a skill command.\n * Wraps content in skill XML tags for the model.\n */\nasync function buildInjectPrompt(\n skill: ICommand,\n args: string,\n callbacks: ISkillExecutionCallbacks,\n context?: SkillPromptContext,\n): Promise<string> {\n const processed = await buildProcessedContent(skill, args, callbacks, context);\n if (processed) {\n const userInstruction = args || skill.description;\n return `<skill name=\"${skill.name}\">\\n${processed}\\n</skill>\\n\\nExecute the \"${skill.name}\" skill: ${userInstruction}`;\n }\n return `Use the \"${skill.name}\" skill: ${args || skill.description}`;\n}\n\n/**\n * Execute a skill command.\n *\n * When `context: 'fork'`, the skill runs in an isolated subagent session\n * via the `runInFork` callback. Throws if `runInFork` is not available.\n * For non-fork skills, the content is returned as a prompt for injection\n * into the current session.\n */\nexport async function executeSkill(\n skill: ICommand,\n args: string,\n callbacks: ISkillExecutionCallbacks,\n context?: SkillPromptContext,\n): Promise<ISkillExecutionResult> {\n // Fork execution: isolated subagent session\n if (skill.context === 'fork') {\n if (!callbacks.runInFork) {\n throw new Error(\n 'Fork execution is not available. Agent runtime deps may not be initialized.',\n );\n }\n\n const content = await buildProcessedContent(skill, args, callbacks, context);\n const prompt = content ?? `Use the \"${skill.name}\" skill: ${args || skill.description}`;\n\n const options: IForkExecutionOptions = {};\n if (skill.agent) options.agent = skill.agent;\n if (skill.allowedTools) options.allowedTools = skill.allowedTools;\n\n const result = await callbacks.runInFork(prompt, options);\n return { mode: 'fork', result };\n }\n\n // Inject execution: return prompt for current session\n const prompt = await buildInjectPrompt(skill, args, callbacks, context);\n return { mode: 'inject', prompt };\n}\n","/**\n * SessionSkillRouter — manages command execution and skill routing\n * for an InteractiveSession. Handles SystemCommandExecutor, SkillCommandSource,\n * and all command/skill invocation logic.\n */\n\nimport { executeSkill, SkillCommandSource, SystemCommandExecutor } from '../commands/index.js';\nimport { createSkillActivationEvent } from '../commands/skill-activation-events.js';\n\nimport type { ICommandHostContext } from '../command-api/index.js';\nimport type {\n ICommand,\n ICommandHostAdapters,\n ICommandModule,\n ICommandResult,\n ICommandSkillListEntry,\n ISkillExecutionResult,\n IForkExecutionOptions,\n ICommandSkillActivationRequest,\n TCommandInvocationSource,\n ISystemCommand,\n} from '../commands/index.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type { TShellExecFn } from '../utils/skill-prompt.js';\n\nfunction normalizeSkillName(name: string): string {\n return name.trim().replace(/^\\/+/, '').split(/\\s+/)[0] ?? '';\n}\n\nfunction normalizeCommandName(name: string): string {\n return name.trim().replace(/^\\/+/, '').split(/\\s+/)[0] ?? '';\n}\n\nfunction formatSkillCommandArgs(skillName: string, args: string): string {\n const trimmedArgs = args.trim();\n return trimmedArgs.length > 0 ? `${skillName} ${trimmedArgs}` : skillName;\n}\n\nfunction getQualifiedSkillName(rawInput?: string): string | undefined {\n if (!rawInput?.startsWith('/')) return undefined;\n const firstToken = rawInput.slice(1).trim().split(/\\s+/)[0];\n return firstToken && firstToken.length > 0 ? firstToken : undefined;\n}\n\nexport class SessionSkillRouter {\n readonly commandExecutor: SystemCommandExecutor;\n private readonly skillCommandSource: SkillCommandSource;\n private readonly commandHostAdapters?: ICommandHostAdapters;\n private commandInvocationSource: TCommandInvocationSource = 'user';\n\n constructor(\n commandModules: readonly ICommandModule[],\n cwd: string,\n commandHostAdapters: ICommandHostAdapters | undefined,\n private readonly getSession: () => ICommandHostContext,\n private readonly getSessionId: () => string,\n private readonly onSubmit: (\n prompt: string,\n displayInput?: string,\n rawInput?: string,\n ) => Promise<void>,\n private readonly onApplyResult: (result: string) => Promise<void>,\n private readonly recordSkillActivation: (\n event: ISkillActivationEvent,\n appendHistory: boolean,\n ) => void,\n private readonly runSkillInFork: (\n content: string,\n options: IForkExecutionOptions,\n ) => Promise<string>,\n /** Called when a fork-context skill needs full lifecycle management (executing flag etc.) */\n private readonly onForkSkill: (\n skill: ICommand,\n args: string,\n displayInput: string | undefined,\n qualifiedName: string | undefined,\n invocation: ISkillActivationEvent['invocation'],\n ) => Promise<ISkillExecutionResult>,\n /** Called for blocking commands — wraps execution with thinking/executing lifecycle */\n private readonly onBlockingCommand: (\n execute: () => Promise<ICommandResult>,\n ) => Promise<ICommandResult>,\n private readonly shellExec?: TShellExecFn,\n ) {\n this.commandExecutor = new SystemCommandExecutor(\n commandModules.flatMap((module) => module.systemCommands ?? []),\n );\n this.skillCommandSource = new SkillCommandSource(cwd);\n this.commandHostAdapters = commandHostAdapters;\n }\n\n getCommandInvocationSource(): TCommandInvocationSource {\n return this.commandInvocationSource;\n }\n\n getCommandHostAdapters(): ICommandHostAdapters {\n return this.commandHostAdapters ?? {};\n }\n\n listCommands(): Array<{ name: string; displayName?: string; description: string }> {\n return this.commandExecutor.listCommands().map((cmd) => ({\n name: cmd.name,\n ...(cmd.displayName !== undefined ? { displayName: cmd.displayName } : {}),\n description: cmd.description,\n }));\n }\n\n listSkills(): ICommandSkillListEntry[] {\n return this.skillCommandSource.getCommands().map((skill) => ({\n name: skill.name,\n description: skill.description,\n source: skill.source,\n modelInvocable: skill.disableModelInvocation !== true,\n userInvocable: skill.userInvocable !== false,\n ...(skill.argumentHint !== undefined ? { argumentHint: skill.argumentHint } : {}),\n ...(skill.context !== undefined ? { context: skill.context } : {}),\n ...(skill.agent !== undefined ? { agent: skill.agent } : {}),\n }));\n }\n\n listModelInvocableCommands(): Array<{ name: string; description: string }> {\n return this.commandExecutor.listModelInvocableCommands().map((cmd) => ({\n name: cmd.name,\n description: cmd.description,\n }));\n }\n\n findSkillCommand(name: string): ICommand | undefined {\n const normalizedName = normalizeSkillName(name);\n return this.skillCommandSource\n .getCommands()\n .find((skill) => skill.name.toLowerCase() === normalizedName.toLowerCase());\n }\n\n async executeCommand(name: string, args: string): Promise<ICommandResult | null> {\n const normalizedName = normalizeCommandName(name);\n const command = this.commandExecutor.getCommand(normalizedName);\n const commandArgs = args.trim();\n if (!command) {\n const skill = this.findSkillCommand(normalizedName);\n const skillsCommand = this.commandExecutor.getCommand('skills');\n if (!skill || !skillsCommand) return null;\n return this.executeCommandWithSource(\n 'user',\n skillsCommand,\n formatSkillCommandArgs(skill.name, commandArgs),\n );\n }\n return this.executeCommandWithSource('user', command, commandArgs);\n }\n\n async executeCommandWithSource(\n source: TCommandInvocationSource,\n command: ISystemCommand,\n args: string,\n ): Promise<ICommandResult> {\n const previousSource = this.commandInvocationSource;\n this.commandInvocationSource = source;\n try {\n if (command.lifecycle === 'blocking') {\n return this.onBlockingCommand(() => this.executeForegroundCommand(command, args));\n }\n return await this.commandExecutor.executeCommand(command, this.getSession(), args);\n } finally {\n this.commandInvocationSource = previousSource;\n }\n }\n\n async executeModelCommand(name: string, args: string): Promise<ICommandResult | null> {\n const previousSource = this.commandInvocationSource;\n this.commandInvocationSource = 'model';\n try {\n return await this.commandExecutor.executeModelInvocable(name, this.getSession(), args);\n } finally {\n this.commandInvocationSource = previousSource;\n }\n }\n\n async executeSkillCommandByName(\n name: string,\n args: string,\n request: ICommandSkillActivationRequest,\n ): Promise<ICommandResult | null> {\n const skill = this.findSkillCommand(name);\n if (!skill) return null;\n\n if (request.invocationSource === 'model') {\n if (skill.disableModelInvocation === true) {\n return { success: false, message: `Skill is not model-invocable: ${skill.name}` };\n }\n const result = await this.executeSkillWithActivation(skill, args, 'model-tool');\n return {\n success: true,\n message: `Skill activated: ${skill.name}`,\n data: {\n skill: skill.name,\n mode: result.mode,\n ...(result.prompt !== undefined ? { prompt: result.prompt } : {}),\n ...(result.result !== undefined ? { result: result.result } : {}),\n },\n };\n }\n\n await this.executeUserResolvedSkillCommand(\n skill,\n args,\n request.displayInput,\n request.rawInput,\n 'user-slash',\n );\n return {\n success: true,\n message: '',\n data: { skill: skill.name, sessionExecution: true },\n effects: [{ type: 'session-execution-started' }],\n };\n }\n\n async executeUserResolvedSkillCommand(\n skill: ICommand,\n args: string,\n displayInput: string | undefined,\n rawInput: string | undefined,\n invocation: ISkillActivationEvent['invocation'],\n ): Promise<ISkillExecutionResult> {\n if (skill.userInvocable === false) {\n throw new Error(`Skill is not user-invocable: ${skill.name}`);\n }\n const qualifiedName = getQualifiedSkillName(rawInput);\n\n if (skill.context === 'fork') {\n return this.onForkSkill(skill, args, displayInput, qualifiedName, invocation);\n }\n\n const result = await this.executeSkillWithActivation(skill, args, invocation, qualifiedName);\n if (result.mode === 'inject') {\n if (result.prompt) await this.onSubmit(result.prompt, displayInput, rawInput);\n return result;\n }\n await this.onApplyResult(result.result ?? '(empty response)');\n return result;\n }\n\n async executeSkillWithActivation(\n skill: ICommand,\n args: string,\n invocation: ISkillActivationEvent['invocation'],\n qualifiedName?: string,\n ): Promise<ISkillExecutionResult> {\n this.emitSkillActivation(skill, invocation, 'started', qualifiedName);\n try {\n const result = await executeSkill(\n skill,\n args,\n {\n runInFork: (content, options) => this.runSkillInFork(content, options),\n ...(this.shellExec ? { shellExec: this.shellExec } : {}),\n },\n { sessionId: this.getSessionId() },\n );\n this.emitSkillActivation(skill, invocation, 'completed', qualifiedName, {\n appendHistory: false,\n });\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.emitSkillActivation(skill, invocation, 'failed', qualifiedName, {\n error: error.message,\n });\n throw error;\n }\n }\n\n private emitSkillActivation(\n skill: ICommand,\n invocation: ISkillActivationEvent['invocation'],\n status: ISkillActivationEvent['status'],\n qualifiedName?: string,\n options: { appendHistory?: boolean; error?: string } = {},\n ): void {\n const event = createSkillActivationEvent({\n skill,\n invocation,\n status,\n ...(qualifiedName !== undefined ? { qualifiedName } : {}),\n ...(options.error !== undefined ? { error: options.error } : {}),\n });\n this.recordSkillActivation(event, options.appendHistory ?? status !== 'completed');\n }\n\n private async executeForegroundCommand(\n command: ISystemCommand,\n args: string,\n ): Promise<ICommandResult> {\n try {\n return await this.commandExecutor.executeCommand(command, this.getSession(), args);\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n return { success: false, message: `Error: ${errMsg}` };\n }\n }\n}\n","import { createSystemMessage, messageToHistoryEntry } from '@robota-sdk/agent-core';\n\nimport { SessionBackgroundTaskTracker } from './interactive-session-background-tracker.js';\nimport { InteractiveSessionBase } from './interactive-session-base.js';\nimport { SessionExecutionController } from './interactive-session-execution-controller.js';\nimport { runSkillInFork } from './interactive-session-fork.js';\nimport { SessionHistoryTracker } from './interactive-session-history-tracker.js';\nimport { initializeInteractiveSessionAsync } from './interactive-session-init.js';\nimport { persistSession } from './interactive-session-persistence.js';\nimport { loadSessionRecord } from './interactive-session-restore.js';\nimport { SessionSkillRouter } from './interactive-session-skill-router.js';\nimport { retrieveSessionBackgroundTaskManager } from '../background-tasks/session-background-store.js';\nimport { EditCheckpointStore } from '../checkpoints/edit-checkpoint-store.js';\nimport { retrieveAgentToolDeps } from '../tools/agent-tool.js';\n\nimport type { IInteractiveSession } from './i-interactive-session.js';\nimport type { ICreatedInteractiveSession } from './interactive-session-init.js';\nimport type {\n TInteractiveSessionOptions,\n IInteractiveSessionStandardOptions,\n} from './interactive-session-options.js';\nimport type { IInteractiveSessionStore } from './session-persistence.js';\nimport type { TInteractiveEventName, IInteractiveSessionEvents } from './types.js';\nimport type { IBackgroundTaskManager } from '../background-tasks/index.js';\nimport type { ICommandHostContext } from '../command-api/index.js';\nimport type {\n IAgentJobHostContext,\n TAutoCompactThresholdSource,\n TAutoCompactThreshold,\n} from '../commands/index.js';\nimport type { IContextFileEntry } from '../context/context-file-tracker.js';\nimport type { TUniversalMessage, TSessionEndReason } from '@robota-sdk/agent-core';\nimport type { ISession } from '@robota-sdk/agent-core';\nimport type { ITransportAdapter } from '@robota-sdk/agent-interface-transport';\nimport type { Session } from '@robota-sdk/agent-session';\nimport type { ISandboxClient } from '@robota-sdk/agent-tools';\nexport type { TInteractiveSessionOptions } from './interactive-session-options.js';\n\nexport interface IInteractiveSessionShutdownOptions {\n reason?: TSessionEndReason;\n message?: string;\n}\n\nexport class InteractiveSession\n extends InteractiveSessionBase\n implements ISession, IAgentJobHostContext, IInteractiveSession\n{\n private session: Session | null = null;\n private readonly listeners = new Map<string, Set<(...args: unknown[]) => void>>();\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n private sessionStore?: IInteractiveSessionStore;\n private sessionName?: string;\n private cwd?: string;\n private pendingRestoreMessages: TUniversalMessage[] | null = null;\n private resumeSessionId?: string;\n private forkSession: boolean;\n private autoCompactThresholdSource: TAutoCompactThresholdSource = 'default';\n private shutdownPromise: Promise<void> | null = null;\n private readonly sandboxClient?: ISandboxClient;\n private sandboxSnapshotId?: string;\n private agentsFileEntries: IContextFileEntry[] = [];\n private claudeFileEntries: IContextFileEntry[] = [];\n private rebuildSystemMessage: ICreatedInteractiveSession['rebuildSystemMessage'] | null = null;\n protected readonly bgTracker: SessionBackgroundTaskTracker;\n protected readonly histTracker: SessionHistoryTracker;\n protected readonly skillRouter: SessionSkillRouter;\n protected readonly execCtrl: SessionExecutionController;\n\n constructor(options: TInteractiveSessionOptions) {\n super();\n this.sessionStore = options.sessionStore;\n this.sessionName = options.sessionName;\n this.cwd = ('cwd' in options ? options.cwd : undefined) ?? '';\n this.resumeSessionId = options.resumeSessionId;\n this.forkSession = options.forkSession ?? false;\n this.sandboxClient = 'sandboxClient' in options ? options.sandboxClient : undefined;\n this.sandboxSnapshotId = 'sandboxSnapshotId' in options ? options.sandboxSnapshotId : undefined;\n\n const cwd = this.cwd;\n let initCheckpointStore: EditCheckpointStore | null = null;\n if ('session' in options && options.session && cwd) {\n initCheckpointStore = new EditCheckpointStore({ cwd });\n }\n\n this.bgTracker = new SessionBackgroundTaskTracker(\n () => this.getBackgroundTaskManager(),\n (cause, entryId) => this.execCtrl.emitExecutionWorkspaceUpdated(cause, entryId),\n (event) => this.emit('background_task_event', event),\n (event) => this.emit('background_job_group_event', event),\n () => this.persistCurrentSession(),\n );\n\n this.histTracker = new SessionHistoryTracker(\n cwd,\n () => this.getSessionOrThrow().getSessionId(),\n () => this.execCtrl.executing,\n () => this.persistCurrentSession(),\n (event) => this.emit('skill_activation', event),\n initCheckpointStore,\n );\n\n const commandModules = [...('commandModules' in options ? (options.commandModules ?? []) : [])];\n const commandHostAdapters =\n 'commandHostAdapters' in options ? options.commandHostAdapters : undefined;\n const shellExec = 'shellExec' in options ? options.shellExec : undefined;\n\n this.skillRouter = new SessionSkillRouter(\n commandModules,\n cwd,\n commandHostAdapters,\n () => this as unknown as ICommandHostContext,\n () => this.session?.getSessionId() ?? '',\n (prompt, displayInput, rawInput) => this.submit(prompt, displayInput, rawInput),\n (result) => this.execCtrl.applyForkSkillResult(result),\n (event, appendHistory) => this.histTracker.recordSkillActivationEvent(event, appendHistory),\n (content, forkOptions) => runSkillInFork(content, forkOptions, this.getSessionOrThrow()),\n (skill, args, displayInput, qualifiedName, invocation) =>\n this.execCtrl.executeForkSkillCommand(\n skill,\n args,\n displayInput,\n qualifiedName,\n invocation,\n (p, d, r) => this.submit(p, d, r),\n ),\n (execute) =>\n this.execCtrl.executeForegroundCommand(execute, (p, d, r) => this.submit(p, d, r)),\n shellExec,\n );\n\n this.execCtrl = new SessionExecutionController(this.histTracker, this.skillRouter, {\n getSession: () => this.session!,\n getSessionOrThrow: () => this.getSessionOrThrow(),\n getCwd: () => this.getCwd(),\n getContextState: () => this.getContextState(),\n getExecutionWorkspaceSnapshot: () => this.getExecutionWorkspaceSnapshot(),\n emit: (event, ...args) =>\n this.emit(\n event as TInteractiveEventName,\n ...(args as Parameters<IInteractiveSessionEvents[TInteractiveEventName]>),\n ),\n persistSession: () => this.persistCurrentSession(),\n });\n\n const hasInjectedSession = this.configureInjectedSession(options);\n this.restoreSessionRecordIfNeeded(options);\n this.startAsyncInitializationIfNeeded(options, hasInjectedSession);\n\n if (this.initialized) this.bgTracker.subscribe(this.session!);\n if (this.initialized) this.persistCurrentSession();\n }\n\n private configureInjectedSession(options: TInteractiveSessionOptions): boolean {\n if (!('session' in options && options.session)) return false;\n this.session = options.session;\n this.autoCompactThresholdSource = 'session';\n this.initialized = true;\n return true;\n }\n\n private restoreSessionRecordIfNeeded(options: TInteractiveSessionOptions): void {\n if (!options.resumeSessionId || !this.sessionStore) return;\n const restored = loadSessionRecord(\n this.sessionStore,\n options.resumeSessionId,\n this.forkSession,\n this.session,\n );\n this.histTracker.restoreState({\n history: restored.history,\n memoryEvents: restored.memoryEvents,\n usedMemoryReferences: restored.usedMemoryReferences,\n contextReferences: restored.contextReferences,\n skillActivationEvents: restored.skillActivationEvents,\n });\n if (restored.sessionName) this.sessionName = restored.sessionName;\n this.bgTracker.restoreState({\n tasks: restored.backgroundTasks,\n taskEvents: restored.backgroundTaskEvents,\n groups: restored.backgroundJobGroups,\n groupEvents: restored.backgroundJobGroupEvents,\n });\n this.pendingRestoreMessages = restored.pendingRestoreMessages;\n this.sandboxSnapshotId = this.forkSession ? undefined : restored.sandboxSnapshotId;\n }\n\n private startAsyncInitializationIfNeeded(\n options: TInteractiveSessionOptions,\n hasInjectedSession: boolean,\n ): void {\n if (hasInjectedSession) return;\n const stdOpts = options as IInteractiveSessionStandardOptions;\n this.initPromise = this.initializeAsync(stdOpts);\n }\n\n private async initializeAsync(options: IInteractiveSessionStandardOptions): Promise<void> {\n const result = await initializeInteractiveSessionAsync(options, {\n sandboxSnapshotId: this.sandboxSnapshotId,\n resumeSessionId: this.resumeSessionId,\n pendingRestoreMessages: this.pendingRestoreMessages,\n onTextDelta: (delta) => this.execCtrl.handleTextDelta(delta),\n onContextUpdate: (state) => this.emit('context_update', state),\n onCompactEvent: (event) => this.execCtrl.handleCompactEvent(event),\n onToolExecution: (event) => this.execCtrl.handleToolExecution(event),\n executeModelCommand: (command, args) => this.executeModelCommand(command, args),\n isModelCommandInvocable: (command) =>\n this.skillRouter.commandExecutor.isModelInvocable(command),\n commandDescriptors: this.skillRouter.commandExecutor.listModelInvocableCommands(),\n setEditCheckpointStore: (store) => this.histTracker.setEditCheckpointStore(store),\n });\n this.session = result.session;\n this.agentsFileEntries = result.agentsFileEntries;\n this.claudeFileEntries = result.claudeFileEntries;\n this.rebuildSystemMessage = result.rebuildSystemMessage;\n this.autoCompactThresholdSource = result.autoCompactThresholdSource;\n this.pendingRestoreMessages = null;\n this.initialized = true;\n this.bgTracker.subscribe(this.session);\n this.persistCurrentSession();\n }\n\n protected async ensureInitialized(): Promise<void> {\n if (!this.initialized && this.initPromise) await this.initPromise;\n }\n\n protected getSessionOrThrow(): Session {\n if (!this.session)\n throw new Error('InteractiveSession not initialized. Call submit() or await initialization.');\n return this.session;\n }\n\n getCwd(): string {\n if (!this.cwd) throw new Error('cwd is not set — provide cwd in session options');\n return this.cwd;\n }\n\n get sessionId(): string {\n return this.session?.getSessionId() ?? '';\n }\n\n on<E extends TInteractiveEventName>(event: E, handler: IInteractiveSessionEvents[E]): void {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set());\n this.listeners.get(event)!.add(handler as (...args: unknown[]) => void);\n }\n\n off<E extends TInteractiveEventName>(event: E, handler: IInteractiveSessionEvents[E]): void {\n this.listeners.get(event)?.delete(handler as (...args: unknown[]) => void);\n }\n\n private emit<E extends TInteractiveEventName>(\n event: E,\n ...args: Parameters<IInteractiveSessionEvents[E]>\n ): void {\n const handlers = this.listeners.get(event);\n if (handlers) for (const handler of handlers) handler(...args);\n }\n\n async submit(input: string, displayInput?: string, rawInput?: string): Promise<void> {\n await this.ensureInitialized();\n if (this.execCtrl.shuttingDown) throw new Error('Interactive session is shutting down.');\n if (this.execCtrl.executing) {\n this.execCtrl.pendingPrompt = input;\n this.execCtrl.pendingDisplayInput = displayInput;\n this.execCtrl.pendingRawInput = rawInput;\n return;\n }\n await this.execCtrl.executePrompt(\n input,\n displayInput,\n rawInput,\n this.agentsFileEntries,\n this.claudeFileEntries,\n this.rebuildSystemMessage,\n (agents, claude) => {\n this.agentsFileEntries = agents;\n this.claudeFileEntries = claude;\n },\n (p, d, r) => this.submit(p, d, r),\n );\n }\n\n abort(): void {\n this.execCtrl.clearPendingQueue();\n this.session?.abort();\n }\n\n shutdown(options: IInteractiveSessionShutdownOptions = {}): Promise<void> {\n if (this.shutdownPromise) return this.shutdownPromise;\n this.execCtrl.shuttingDown = true;\n this.shutdownPromise = (async () => {\n await this.ensureInitialized();\n this.execCtrl.clearPendingQueue();\n const session = this.session;\n session?.abort();\n await this.getBackgroundTaskManager()?.shutdown(options.message ?? 'Session shutdown');\n this.bgTracker.dispose();\n await this.captureSandboxSnapshot();\n this.persistCurrentSession();\n await session?.shutdown({ reason: options.reason ?? 'other' });\n })();\n return this.shutdownPromise;\n }\n\n get isInitialized(): boolean {\n return this.initialized;\n }\n\n getAutoCompactThresholdSource(): TAutoCompactThresholdSource {\n return this.autoCompactThresholdSource;\n }\n\n getAutoCompactThreshold(): number | false {\n return this.getSessionOrThrow().getAutoCompactThreshold();\n }\n getSession(): Session {\n return this.getSessionOrThrow();\n }\n\n getAgentJobCapability(): IAgentJobHostContext {\n return this;\n }\n\n setAutoCompactThreshold(\n threshold: TAutoCompactThreshold,\n source: TAutoCompactThresholdSource = 'session',\n ): void {\n this.getSessionOrThrow().setAutoCompactThreshold(threshold);\n this.autoCompactThresholdSource = source;\n this.emit('context_update', this.getContextState());\n this.persistCurrentSession();\n }\n\n clearConversationHistory(): void {\n this.getSessionOrThrow().clearHistory();\n this.histTracker.clearHistory();\n this.persistCurrentSession();\n this.emit('context_update', this.getContextState());\n }\n\n getName(): string | undefined {\n return this.sessionName;\n }\n\n attachTransport(transport: ITransportAdapter<IInteractiveSession>): void {\n transport.attach(this);\n }\n\n setName(name: string): void {\n this.sessionName = name;\n if (this.sessionStore && this.session) {\n try {\n const id = this.getSessionOrThrow().getSessionId();\n const existing = this.sessionStore.load(id);\n if (existing) {\n existing.name = name;\n existing.updatedAt = new Date().toISOString();\n this.sessionStore.save(existing);\n }\n } catch {\n /* Session not initialized yet */\n }\n }\n }\n\n private getBackgroundTaskManager(): IBackgroundTaskManager | undefined {\n if (!this.session) return undefined;\n return (\n retrieveSessionBackgroundTaskManager(this.session) ??\n retrieveAgentToolDeps(this.session)?.backgroundTaskManager\n );\n }\n\n private async captureSandboxSnapshot(): Promise<void> {\n if (!this.sandboxClient?.snapshot) return;\n try {\n this.sandboxSnapshotId = await this.sandboxClient.snapshot();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.histTracker.append(\n messageToHistoryEntry(createSystemMessage(`Sandbox snapshot error: ${err.message}`)),\n );\n this.emit('error', err);\n }\n }\n\n private persistCurrentSession(): void {\n if (!this.sessionStore || !this.session) return;\n const bgState = this.bgTracker.getState();\n const histState = this.histTracker.getState();\n persistSession(\n this.sessionStore,\n this.session,\n this.sessionName,\n this.cwd ?? '',\n histState.history,\n {\n tasks: bgState.tasks,\n events: bgState.taskEvents,\n groups: bgState.groups,\n groupEvents: bgState.groupEvents,\n },\n { events: histState.memoryEvents, usedReferences: histState.usedMemoryReferences },\n { events: histState.skillActivationEvents },\n { references: histState.contextReferences },\n { snapshotId: this.sandboxSnapshotId },\n );\n }\n}\n","import { join } from 'node:path';\n\nimport {\n loadSessionLogEntries,\n replaySessionLogEntries,\n SessionStore,\n type ISessionRecord,\n} from '@robota-sdk/agent-session';\n\nimport { NodeFileSystem } from '../adapters/node-file-system.js';\nimport { projectPaths } from '../paths.js';\n\nimport type {\n IBackgroundJobGroupState,\n IBackgroundTaskState,\n TBackgroundJobGroupEvent,\n TBackgroundTaskEvent,\n} from '../background-tasks/index.js';\nimport type { ISkillActivationEvent } from '../commands/skill-activation-events.js';\nimport type { IContextReferenceItem } from '../context/context-reference-inventory.js';\nimport type { IMemoryEvent, IMemoryReference } from '../memory/automatic-memory-types.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\nimport type { IHistoryEntry, IToolSchema, TUniversalMessage } from '@robota-sdk/agent-core';\n\nexport interface IInteractiveSessionRecord {\n id: string;\n name?: string;\n cwd: string;\n createdAt: string;\n updatedAt: string;\n messages: TUniversalMessage[];\n history?: IHistoryEntry[];\n systemPrompt?: string;\n toolSchemas?: IToolSchema[];\n backgroundTasks?: IBackgroundTaskState[];\n backgroundTaskEvents?: TBackgroundTaskEvent[];\n backgroundJobGroups?: IBackgroundJobGroupState[];\n backgroundJobGroupEvents?: TBackgroundJobGroupEvent[];\n skillActivationEvents?: ISkillActivationEvent[];\n memoryEvents?: IMemoryEvent[];\n usedMemoryReferences?: IMemoryReference[];\n contextReferences?: IContextReferenceItem[];\n sandboxSnapshotId?: string;\n}\n\nexport interface IInteractiveSessionStore {\n save(session: IInteractiveSessionRecord): void;\n load(id: string): IInteractiveSessionRecord | undefined;\n list(): IInteractiveSessionRecord[];\n delete(id: string): void;\n}\n\nexport interface IResumableSessionSummary {\n id: string;\n name?: string;\n cwd: string;\n updatedAt: string;\n messageCount: number;\n preview: string;\n}\n\nexport function createProjectSessionStore(\n cwd: string,\n fs: IFileSystem = new NodeFileSystem(),\n): IInteractiveSessionStore {\n const paths = projectPaths(cwd);\n return new ProjectSessionStoreFacade(paths.sessions, paths.logs, fs);\n}\n\nexport function listResumableSessionSummaries(\n sessionStore: IInteractiveSessionStore | undefined,\n cwd: string,\n): IResumableSessionSummary[] {\n return (sessionStore?.list() ?? [])\n .filter((session) => session.cwd === cwd)\n .sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())\n .map((session) => ({\n id: session.id,\n ...(session.name !== undefined ? { name: session.name } : {}),\n cwd: session.cwd,\n updatedAt: session.updatedAt,\n messageCount: session.messages.length,\n preview: getLastAssistantPreview(session.messages),\n }));\n}\n\nexport function resolveLatestSessionId(\n sessionStore: IInteractiveSessionStore | undefined,\n cwd: string,\n): string | undefined {\n return listResumableSessionSummaries(sessionStore, cwd)[0]?.id;\n}\n\nexport function resolveSessionIdByIdOrName(\n sessionStore: IInteractiveSessionStore | undefined,\n idOrName: string,\n): string | undefined {\n const match = (sessionStore?.list() ?? []).find(\n (session) => session.id === idOrName || session.name === idOrName,\n );\n return match?.id;\n}\n\nclass ProjectSessionStoreFacade implements IInteractiveSessionStore {\n private readonly store: SessionStore;\n private readonly logsDir: string | undefined;\n private readonly fs: IFileSystem;\n\n constructor(baseDir: string, logsDir?: string, fs: IFileSystem = new NodeFileSystem()) {\n this.store = new SessionStore(baseDir);\n this.logsDir = logsDir;\n this.fs = fs;\n }\n\n save(session: IInteractiveSessionRecord): void {\n this.store.save(toSessionRecord(session));\n }\n\n load(id: string): IInteractiveSessionRecord | undefined {\n const session = this.store.load(id);\n if (session !== undefined) {\n return fromSessionRecord(session);\n }\n return this.loadFromReplayLog(id);\n }\n\n list(): IInteractiveSessionRecord[] {\n const records = this.store.list().map(fromSessionRecord);\n const seen = new Set(records.map((record) => record.id));\n for (const replayRecord of this.listReplayLogRecords()) {\n if (!seen.has(replayRecord.id)) {\n records.push(replayRecord);\n }\n }\n return records.sort(\n (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),\n );\n }\n\n delete(id: string): void {\n this.store.delete(id);\n }\n\n private loadFromReplayLog(id: string): IInteractiveSessionRecord | undefined {\n if (!this.logsDir) return undefined;\n const replay = replaySessionLogEntries(\n loadSessionLogEntries(join(this.logsDir, `${id}.jsonl`)),\n );\n if (!replay.sessionId || replay.messages.length === 0) {\n return undefined;\n }\n const backgroundTaskEvents = replay.backgroundTaskEvents as TBackgroundTaskEvent[];\n const backgroundJobGroupEvents = replay.backgroundJobGroupEvents as TBackgroundJobGroupEvent[];\n return {\n id: replay.sessionId,\n cwd: replay.cwd ?? '',\n createdAt: replay.createdAt ?? replay.updatedAt ?? new Date(0).toISOString(),\n updatedAt: replay.updatedAt ?? replay.createdAt ?? new Date(0).toISOString(),\n messages: replay.messages,\n history: replay.history,\n backgroundTasks: deriveBackgroundTasks(backgroundTaskEvents),\n backgroundTaskEvents,\n backgroundJobGroups: deriveBackgroundJobGroups(backgroundJobGroupEvents),\n backgroundJobGroupEvents,\n skillActivationEvents: [],\n memoryEvents: replay.memoryEvents as IMemoryEvent[],\n };\n }\n\n private listReplayLogRecords(): IInteractiveSessionRecord[] {\n if (!this.logsDir || !this.fs.existsSync(this.logsDir)) {\n return [];\n }\n return this.fs\n .readdirSync(this.logsDir)\n .filter((file) => file.endsWith('.jsonl'))\n .map((file) => this.loadFromReplayLog(file.slice(0, -'.jsonl'.length)))\n .filter((record): record is IInteractiveSessionRecord => record !== undefined);\n }\n}\n\nfunction getLastAssistantPreview(messages: readonly TUniversalMessage[]): string {\n for (const message of [...messages].reverse()) {\n if (message.role !== 'assistant') continue;\n if (typeof message.content !== 'string') continue;\n return message.content.replace(/[\\n\\r]+/g, ' ').trim();\n }\n return '';\n}\n\nfunction toSessionRecord(session: IInteractiveSessionRecord): ISessionRecord {\n return { ...session };\n}\n\nfunction fromSessionRecord(session: ISessionRecord): IInteractiveSessionRecord {\n return {\n id: session.id,\n ...(session.name !== undefined ? { name: session.name } : {}),\n cwd: session.cwd,\n createdAt: session.createdAt,\n updatedAt: session.updatedAt,\n messages: session.messages as TUniversalMessage[],\n ...(session.history !== undefined ? { history: session.history as IHistoryEntry[] } : {}),\n ...(session.systemPrompt !== undefined ? { systemPrompt: session.systemPrompt } : {}),\n ...(session.toolSchemas !== undefined ? { toolSchemas: session.toolSchemas } : {}),\n ...(session.backgroundTasks !== undefined\n ? { backgroundTasks: session.backgroundTasks as IBackgroundTaskState[] }\n : {}),\n ...(session.backgroundTaskEvents !== undefined\n ? { backgroundTaskEvents: session.backgroundTaskEvents as TBackgroundTaskEvent[] }\n : {}),\n ...(session.backgroundJobGroups !== undefined\n ? { backgroundJobGroups: session.backgroundJobGroups as IBackgroundJobGroupState[] }\n : {}),\n ...(session.backgroundJobGroupEvents !== undefined\n ? { backgroundJobGroupEvents: session.backgroundJobGroupEvents as TBackgroundJobGroupEvent[] }\n : {}),\n ...(session.skillActivationEvents !== undefined\n ? { skillActivationEvents: session.skillActivationEvents as ISkillActivationEvent[] }\n : {}),\n ...(session.memoryEvents !== undefined\n ? { memoryEvents: session.memoryEvents as IMemoryEvent[] }\n : {}),\n ...(session.usedMemoryReferences !== undefined\n ? { usedMemoryReferences: session.usedMemoryReferences as IMemoryReference[] }\n : {}),\n ...(session.contextReferences !== undefined\n ? { contextReferences: session.contextReferences as IContextReferenceItem[] }\n : {}),\n ...(session.sandboxSnapshotId !== undefined\n ? { sandboxSnapshotId: session.sandboxSnapshotId }\n : {}),\n };\n}\n\nfunction deriveBackgroundTasks(events: readonly TBackgroundTaskEvent[]): IBackgroundTaskState[] {\n const tasks = new Map<string, IBackgroundTaskState>();\n for (const event of events) {\n const task = getBackgroundTaskSnapshot(event);\n if (task) tasks.set(task.id, task);\n }\n return [...tasks.values()];\n}\n\nfunction getBackgroundTaskSnapshot(event: TBackgroundTaskEvent): IBackgroundTaskState | undefined {\n switch (event.type) {\n case 'background_task_created':\n case 'background_task_started':\n case 'background_task_updated':\n case 'background_task_completed':\n case 'background_task_failed':\n case 'background_task_cancelled':\n return event.task;\n default:\n return undefined;\n }\n}\n\nfunction deriveBackgroundJobGroups(\n events: readonly TBackgroundJobGroupEvent[],\n): IBackgroundJobGroupState[] {\n const groups = new Map<string, IBackgroundJobGroupState>();\n for (const event of events) {\n groups.set(event.group.id, event.group);\n }\n return [...groups.values()];\n}\n","/**\n * createQuery() — factory that returns a prompt-only convenience function.\n *\n * Usage:\n * const query = createQuery({ provider });\n * const answer = await query('What files are here?');\n */\n\nimport { InteractiveSession } from './interactive/interactive-session.js';\n\nimport type { IExecutionResult, TInteractivePermissionHandler } from './interactive/types.js';\nimport type { IAIProvider } from '@robota-sdk/agent-core';\nimport type { TPermissionMode } from '@robota-sdk/agent-core';\n\nexport interface ICreateQueryOptions {\n /** AI provider instance (required). */\n provider: IAIProvider;\n /** Working directory. Defaults to process.cwd(). */\n cwd?: string;\n /** Permission mode. Defaults to 'bypassPermissions' for programmatic use. */\n permissionMode?: TPermissionMode;\n /** Maximum agentic turns per query. */\n maxTurns?: number;\n /** Permission handler callback. */\n permissionHandler?: TInteractivePermissionHandler;\n /** Streaming text callback. */\n onTextDelta?: (delta: string) => void;\n}\n\n/**\n * Create a prompt-only query function bound to a provider.\n *\n * ```typescript\n * import { createQuery } from '@robota-sdk/agent-framework';\n * import { AnthropicProvider } from '@robota-sdk/agent-provider/anthropic';\n *\n * const query = createQuery({ provider: new AnthropicProvider({ apiKey: '...' }) });\n * const answer = await query('List all TypeScript files');\n * ```\n */\nexport function createQuery(options: ICreateQueryOptions): (prompt: string) => Promise<string> {\n const session = new InteractiveSession({\n cwd: options.cwd ?? process.cwd(),\n provider: options.provider,\n permissionMode: options.permissionMode ?? 'bypassPermissions',\n maxTurns: options.maxTurns,\n permissionHandler: options.permissionHandler,\n });\n\n if (options.onTextDelta) {\n session.on('text_delta', options.onTextDelta);\n }\n\n return async (prompt: string): Promise<string> => {\n return new Promise<string>((resolve, reject) => {\n const onComplete = (result: IExecutionResult): void => {\n cleanup();\n resolve(result.response);\n };\n const onInterrupted = (result: IExecutionResult): void => {\n cleanup();\n resolve(result.response);\n };\n const onError = (error: Error): void => {\n cleanup();\n reject(error);\n };\n const cleanup = (): void => {\n session.off('complete', onComplete);\n session.off('interrupted', onInterrupted);\n session.off('error', onError);\n };\n\n session.on('complete', onComplete);\n session.on('interrupted', onInterrupted);\n session.on('error', onError);\n\n session.submit(prompt).catch((err) => {\n cleanup();\n reject(err instanceof Error ? err : new Error(String(err)));\n });\n });\n };\n}\n","import { homedir } from 'node:os';\nimport path from 'node:path';\n\nimport { NodeFileSystemAsync } from '../adapters/node-file-system.js';\n\nimport type { IDirent, IFileSystemAsync } from '@robota-sdk/agent-core';\n\nexport const USER_LOCAL_STORAGE_CATEGORIES = [\n 'preferences',\n 'view-state',\n 'memory-projections',\n 'task-associations',\n 'workflow-metadata',\n 'inspection-index',\n] as const;\n\nexport type TUserLocalStorageCategory = (typeof USER_LOCAL_STORAGE_CATEGORIES)[number];\n\nexport interface IUserLocalStorageCategoryDefinition {\n readonly category: TUserLocalStorageCategory;\n readonly purpose: string;\n readonly mayExecuteCommands: false;\n}\n\nexport interface IUserLocalStorageItemSummary {\n readonly root: string;\n readonly category: TUserLocalStorageCategory;\n readonly key: string;\n readonly summary: string;\n readonly source: string;\n readonly scope: string;\n readonly storageLocation: string;\n readonly createdAt?: string;\n readonly lastUsedAt?: string;\n readonly enabled: boolean;\n readonly deleteAvailable: boolean;\n readonly disableAvailable: boolean;\n}\n\nexport interface IUserLocalStorageCategoryProjection {\n readonly category: TUserLocalStorageCategory;\n readonly purpose: string;\n readonly mayExecuteCommands: false;\n readonly storageLocation: string;\n readonly itemCount: number;\n readonly items: readonly IUserLocalStorageItemSummary[];\n}\n\nexport interface IUserLocalStorageInspection {\n readonly root: string;\n readonly activeRepositoryRoot: string;\n readonly categories: readonly IUserLocalStorageCategoryProjection[];\n readonly generatedAt: string;\n}\n\nexport interface IResolveUserLocalStorageRootOptions {\n readonly activeRepositoryRoot: string;\n readonly homeDir?: string;\n readonly storageRoot?: string;\n readonly fsAsync?: IFileSystemAsync;\n}\n\nexport interface IInspectUserLocalStorageOptions extends IResolveUserLocalStorageRootOptions {\n readonly now?: () => Date;\n readonly createDirectories?: boolean;\n}\n\nexport const USER_LOCAL_STORAGE_CATEGORY_DEFINITIONS: readonly IUserLocalStorageCategoryDefinition[] =\n [\n {\n category: 'preferences',\n purpose: 'User-local UI and display preferences.',\n mayExecuteCommands: false,\n },\n {\n category: 'view-state',\n purpose: 'Last selected panels, filters, and navigation state.',\n mayExecuteCommands: false,\n },\n {\n category: 'memory-projections',\n purpose: 'Inspectable local memory item projections and user choices.',\n mayExecuteCommands: false,\n },\n {\n category: 'task-associations',\n purpose: 'User-local associations between sessions, tasks, and background items.',\n mayExecuteCommands: false,\n },\n {\n category: 'workflow-metadata',\n purpose: 'Transparent workflow metadata that is not repo-owned.',\n mayExecuteCommands: false,\n },\n {\n category: 'inspection-index',\n purpose: 'Category and item summaries for user inspection and deletion.',\n mayExecuteCommands: false,\n },\n ];\n\nfunction formatIsoDate(date: Date): string {\n return date.toISOString();\n}\n\nfunction assertAbsolutePath(name: string, value: string): void {\n if (value.trim().length === 0) {\n throw new Error(`${name} must not be empty.`);\n }\n if (!path.isAbsolute(value)) {\n throw new Error(`${name} must be an absolute path: ${value}`);\n }\n}\n\nfunction resolveDefaultHomeDir(): string {\n return process.env.HOME ?? homedir();\n}\n\nfunction isEqualOrInside(parentPath: string, candidatePath: string): boolean {\n const relative = path.relative(parentPath, candidatePath);\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\nasync function resolveForComparison(absPath: string, fsAsync: IFileSystemAsync): Promise<string> {\n let current = absPath;\n\n while (path.dirname(current) !== current) {\n try {\n const realCurrent = await fsAsync.realpath(current);\n const relativeMissingPath = path.relative(current, absPath);\n return path.resolve(realCurrent, relativeMissingPath);\n } catch {\n // allow-fallback: walk up to first existing ancestor, not an error suppression\n current = path.dirname(current);\n }\n }\n\n try {\n return await fsAsync.realpath(current);\n } catch {\n // allow-fallback: filesystem root unreachable; resolve() gives a safe absolute path\n return path.resolve(absPath);\n }\n}\n\nexport async function resolveUserLocalStorageRoot(\n options: IResolveUserLocalStorageRootOptions,\n): Promise<string> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const activeRepositoryRoot = path.resolve(options.activeRepositoryRoot);\n assertAbsolutePath('activeRepositoryRoot', activeRepositoryRoot);\n\n const candidateRoot =\n options.storageRoot !== undefined\n ? options.storageRoot\n : path.join(options.homeDir ?? resolveDefaultHomeDir(), '.robota');\n\n assertAbsolutePath('userLocalStorageRoot', candidateRoot);\n\n const resolvedRoot = path.resolve(candidateRoot);\n const comparableRoot = await resolveForComparison(resolvedRoot, fsAsync);\n const comparableRepositoryRoot = await resolveForComparison(activeRepositoryRoot, fsAsync);\n\n if (isEqualOrInside(comparableRepositoryRoot, comparableRoot)) {\n throw new Error(\n `User-local storage root must be outside the active repository: ${resolvedRoot}`,\n );\n }\n\n return resolvedRoot;\n}\n\nfunction resolveCategoryLocation(root: string, category: TUserLocalStorageCategory): string {\n return path.join(root, category);\n}\n\nasync function listItemSummaries(\n root: string,\n category: TUserLocalStorageCategory,\n fsAsync: IFileSystemAsync,\n): Promise<readonly IUserLocalStorageItemSummary[]> {\n const storageLocation = resolveCategoryLocation(root, category);\n let entries: readonly IDirent[];\n\n try {\n entries = await fsAsync.readdir(storageLocation, { withFileTypes: true });\n } catch {\n // allow-fallback: missing category directory returns empty list\n return [];\n }\n\n const summaries = await Promise.all(\n entries.map(async (entry): Promise<IUserLocalStorageItemSummary> => {\n const itemLocation = path.join(storageLocation, entry.name);\n const stats = await fsAsync.stat(itemLocation);\n const key = entry.name;\n return {\n root,\n category,\n key,\n summary: `${category}/${key}`,\n source: 'user-local-storage',\n scope: 'user',\n storageLocation: itemLocation,\n createdAt: formatIsoDate(new Date(stats.birthtimeMs)),\n lastUsedAt: formatIsoDate(new Date(stats.mtimeMs)),\n enabled: true,\n deleteAvailable: true,\n disableAvailable: false,\n };\n }),\n );\n\n return summaries.sort((left, right) => left.key.localeCompare(right.key));\n}\n\nexport async function inspectUserLocalStorage(\n options: IInspectUserLocalStorageOptions,\n): Promise<IUserLocalStorageInspection> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const root = await resolveUserLocalStorageRoot(options);\n const activeRepositoryRoot = path.resolve(options.activeRepositoryRoot);\n const createDirectories = options.createDirectories ?? true;\n\n if (createDirectories) {\n await fsAsync.mkdir(root, { recursive: true });\n }\n\n const categories = await Promise.all(\n USER_LOCAL_STORAGE_CATEGORY_DEFINITIONS.map(\n async (definition): Promise<IUserLocalStorageCategoryProjection> => {\n const storageLocation = resolveCategoryLocation(root, definition.category);\n if (createDirectories) {\n await fsAsync.mkdir(storageLocation, { recursive: true });\n }\n const items = await listItemSummaries(root, definition.category, fsAsync);\n return {\n category: definition.category,\n purpose: definition.purpose,\n mayExecuteCommands: definition.mayExecuteCommands,\n storageLocation,\n itemCount: items.length,\n items,\n };\n },\n ),\n );\n\n return {\n root,\n activeRepositoryRoot,\n categories,\n generatedAt: formatIsoDate((options.now ?? (() => new Date()))()),\n };\n}\n","import type { IResolveUserLocalStorageRootOptions } from './storage.js';\n\nexport const USER_LOCAL_MEMORY_CATEGORIES = [\n 'view-preference',\n 'last-visible-cwd',\n 'background-selection',\n 'task-association',\n 'display-preference',\n 'inspection-choice',\n] as const;\n\nexport type TUserLocalMemoryCategory = (typeof USER_LOCAL_MEMORY_CATEGORIES)[number];\nexport type TUserLocalMemoryCommandExecutionEffect = 'none';\n\nexport interface IUserLocalMemoryItemProjection {\n readonly root: string;\n readonly category: TUserLocalMemoryCategory;\n readonly key: string;\n readonly summary: string;\n readonly valueSummary: string;\n readonly source: string;\n readonly scope: string;\n readonly storageLocation: string;\n readonly createdAt: string;\n readonly lastUsedAt: string;\n readonly enabled: boolean;\n readonly displayNavigationRule: string;\n readonly commandExecutionEffect: TUserLocalMemoryCommandExecutionEffect;\n readonly deleteAvailable: true;\n readonly disableAvailable: true;\n}\n\nexport interface IUserLocalMemoryListProjection {\n readonly root: string;\n readonly activeRepositoryRoot: string;\n readonly items: readonly IUserLocalMemoryItemProjection[];\n}\n\nexport interface IUserLocalMemorySetOptions extends IResolveUserLocalStorageRootOptions {\n readonly category: TUserLocalMemoryCategory;\n readonly key: string;\n readonly value: string;\n readonly summary: string;\n readonly source: string;\n readonly scope?: string;\n readonly now?: () => Date;\n}\n\nexport interface IUserLocalMemoryItemOptions extends IResolveUserLocalStorageRootOptions {\n readonly category: TUserLocalMemoryCategory;\n readonly key: string;\n readonly now?: () => Date;\n}\n\nexport interface IUserLocalMemoryListOptions extends IResolveUserLocalStorageRootOptions {\n readonly now?: () => Date;\n}\n\nexport interface IUserLocalMemoryDeleteResult {\n readonly category: TUserLocalMemoryCategory;\n readonly key: string;\n readonly deleted: boolean;\n}\n\nexport interface IUserLocalMemoryFile {\n readonly schemaVersion: 1;\n readonly category: TUserLocalMemoryCategory;\n readonly key: string;\n readonly value: string;\n readonly summary: string;\n readonly source: string;\n readonly scope: string;\n readonly createdAt: string;\n readonly lastUsedAt: string;\n readonly enabled: boolean;\n}\n","import path from 'node:path';\n\nimport {\n USER_LOCAL_MEMORY_CATEGORIES,\n type IUserLocalMemoryDeleteResult,\n type IUserLocalMemoryFile,\n type IUserLocalMemoryItemOptions,\n type IUserLocalMemoryItemProjection,\n type IUserLocalMemoryListOptions,\n type IUserLocalMemoryListProjection,\n type IUserLocalMemorySetOptions,\n type TUserLocalMemoryCategory,\n} from './memory-types.js';\nimport { resolveUserLocalStorageRoot } from './storage.js';\nimport { NodeFileSystemAsync } from '../adapters/node-file-system.js';\n\nimport type { IResolveUserLocalStorageRootOptions } from './storage.js';\nimport type { IDirent, IFileSystemAsync } from '@robota-sdk/agent-core';\n\ntype TJsonValue =\n | string\n | number\n | boolean\n | null\n | readonly TJsonValue[]\n | { readonly [key: string]: TJsonValue };\ntype TJsonRecord = { readonly [key: string]: TJsonValue };\n\nconst MEMORY_STORAGE_CATEGORY = 'memory-projections';\nconst FILE_EXTENSION = '.json';\nconst MEMORY_SCHEMA_VERSION = 1;\nconst MAX_SEGMENT_LENGTH = 80;\nconst MAX_SUMMARY_LENGTH = 240;\nconst MAX_SOURCE_LENGTH = 80;\nconst MAX_SCOPE_LENGTH = 120;\nconst MAX_VALUE_SUMMARY_LENGTH = 240;\nconst DEFAULT_SCOPE = 'user';\nconst SAFE_SEGMENT_PATTERN = /^[a-z0-9][a-z0-9._-]*$/u;\n\nconst DISPLAY_NAVIGATION_RULES: Record<TUserLocalMemoryCategory, string> = {\n 'view-preference': 'May affect UI panel, filter, density, or sorting display/navigation only.',\n 'last-visible-cwd': 'May display or preselect an already visible workspace context only.',\n 'background-selection': 'May restore the selected background entry in local UI only.',\n 'task-association': 'May group visible tasks by a local association only.',\n 'display-preference': 'May affect local text wrapping, compactness, or visibility only.',\n 'inspection-choice': 'May affect inspection display choices only.',\n};\n\nfunction formatIsoDate(date: Date): string {\n return date.toISOString();\n}\n\nfunction isUserLocalMemoryCategory(value: string): value is TUserLocalMemoryCategory {\n return USER_LOCAL_MEMORY_CATEGORIES.includes(value as TUserLocalMemoryCategory);\n}\n\nfunction assertUserLocalMemoryCategory(value: string): TUserLocalMemoryCategory {\n if (!isUserLocalMemoryCategory(value)) {\n throw new Error(`Unsupported user-local memory category: ${value}`);\n }\n return value;\n}\n\nfunction assertSafeSegment(name: string, value: string): string {\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n throw new Error(`${name} must not be empty.`);\n }\n if (trimmed.length > MAX_SEGMENT_LENGTH || !SAFE_SEGMENT_PATTERN.test(trimmed)) {\n throw new Error(\n `${name} must use lowercase letters, numbers, dots, underscores, or hyphens: ${value}`,\n );\n }\n return trimmed;\n}\n\nfunction boundedText(name: string, value: string, maxLength: number): string {\n const normalized = value.trim().replace(/\\s+/g, ' ');\n if (normalized.length === 0) {\n throw new Error(`${name} must not be empty.`);\n }\n if (normalized.length > maxLength) {\n return normalized.slice(0, maxLength);\n }\n return normalized;\n}\n\nfunction summarizeValue(value: string): string {\n return boundedText('value', value, MAX_VALUE_SUMMARY_LENGTH);\n}\n\nfunction memoryFileName(category: TUserLocalMemoryCategory, key: string): string {\n return `${category}__${key}${FILE_EXTENSION}`;\n}\n\nasync function resolveMemoryRoot(\n options: IResolveUserLocalStorageRootOptions,\n): Promise<{ readonly root: string; readonly memoryRoot: string }> {\n const root = await resolveUserLocalStorageRoot(options);\n return {\n root,\n memoryRoot: path.join(root, MEMORY_STORAGE_CATEGORY),\n };\n}\n\nfunction parseMemoryRecord(raw: string, storageLocation: string): IUserLocalMemoryFile {\n const record = JSON.parse(raw) as TJsonRecord;\n const category = readString(record, 'category');\n const schemaVersion = record['schemaVersion'];\n\n if (schemaVersion !== MEMORY_SCHEMA_VERSION) {\n throw new Error(`Unsupported user-local memory schema at ${storageLocation}`);\n }\n\n return {\n schemaVersion: MEMORY_SCHEMA_VERSION,\n category: assertUserLocalMemoryCategory(category),\n key: readString(record, 'key'),\n value: readString(record, 'value'),\n summary: readString(record, 'summary'),\n source: readString(record, 'source'),\n scope: readString(record, 'scope'),\n createdAt: readString(record, 'createdAt'),\n lastUsedAt: readString(record, 'lastUsedAt'),\n enabled: readBoolean(record, 'enabled'),\n };\n}\n\nfunction readString(record: TJsonRecord, key: string): string {\n const value = record[key];\n if (typeof value !== 'string') {\n throw new Error(`Invalid user-local memory field: ${key}`);\n }\n return value;\n}\n\nfunction readBoolean(record: TJsonRecord, key: string): boolean {\n const value = record[key];\n if (typeof value !== 'boolean') {\n throw new Error(`Invalid user-local memory field: ${key}`);\n }\n return value;\n}\n\nfunction projectMemoryItem(\n root: string,\n storageLocation: string,\n item: IUserLocalMemoryFile,\n): IUserLocalMemoryItemProjection {\n return {\n root,\n category: item.category,\n key: item.key,\n summary: item.summary,\n valueSummary: summarizeValue(item.value),\n source: item.source,\n scope: item.scope,\n storageLocation,\n createdAt: item.createdAt,\n lastUsedAt: item.lastUsedAt,\n enabled: item.enabled,\n displayNavigationRule: DISPLAY_NAVIGATION_RULES[item.category],\n commandExecutionEffect: 'none',\n deleteAvailable: true,\n disableAvailable: true,\n };\n}\n\nasync function readMemoryFile(\n root: string,\n storageLocation: string,\n fsAsync: IFileSystemAsync,\n): Promise<IUserLocalMemoryItemProjection> {\n return projectMemoryItem(\n root,\n storageLocation,\n parseMemoryRecord(await fsAsync.readFile(storageLocation, 'utf8'), storageLocation),\n );\n}\n\nasync function resolveMemoryFile(\n options: IUserLocalMemoryItemOptions,\n): Promise<{ readonly root: string; readonly storageLocation: string }> {\n const category = assertUserLocalMemoryCategory(options.category);\n const key = assertSafeSegment('key', options.key);\n const { root, memoryRoot } = await resolveMemoryRoot(options);\n return {\n root,\n storageLocation: path.join(memoryRoot, memoryFileName(category, key)),\n };\n}\n\nexport async function setUserLocalMemoryItem(\n options: IUserLocalMemorySetOptions,\n): Promise<IUserLocalMemoryItemProjection> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const category = assertUserLocalMemoryCategory(options.category);\n const key = assertSafeSegment('key', options.key);\n const summary = boundedText('summary', options.summary, MAX_SUMMARY_LENGTH);\n const source = boundedText('source', options.source, MAX_SOURCE_LENGTH);\n const scope = boundedText('scope', options.scope ?? DEFAULT_SCOPE, MAX_SCOPE_LENGTH);\n const value = summarizeValue(options.value);\n const now = formatIsoDate((options.now ?? (() => new Date()))());\n const { root, memoryRoot } = await resolveMemoryRoot(options);\n const storageLocation = path.join(memoryRoot, memoryFileName(category, key));\n let createdAt = now;\n\n try {\n const existing = parseMemoryRecord(\n await fsAsync.readFile(storageLocation, 'utf8'),\n storageLocation,\n );\n createdAt = existing.createdAt;\n } catch (error) {\n if (error instanceof Error && error.message.includes('ENOENT')) {\n createdAt = now;\n } else {\n throw error;\n }\n }\n\n const item: IUserLocalMemoryFile = {\n schemaVersion: MEMORY_SCHEMA_VERSION,\n category,\n key,\n value,\n summary,\n source,\n scope,\n createdAt,\n lastUsedAt: now,\n enabled: true,\n };\n\n await fsAsync.mkdir(memoryRoot, { recursive: true });\n await fsAsync.writeFile(storageLocation, `${JSON.stringify(item, null, 2)}\\n`, 'utf8');\n return projectMemoryItem(root, storageLocation, item);\n}\n\nexport async function listUserLocalMemoryItems(\n options: IUserLocalMemoryListOptions,\n): Promise<IUserLocalMemoryListProjection> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const { root, memoryRoot } = await resolveMemoryRoot(options);\n let entries: readonly IDirent[];\n\n try {\n entries = await fsAsync.readdir(memoryRoot, { withFileTypes: true });\n } catch {\n // allow-fallback: missing memory directory means no items exist\n entries = [];\n }\n\n const items = await Promise.all(\n entries\n .filter((entry) => entry.isFile() && entry.name.endsWith(FILE_EXTENSION))\n .map((entry) => readMemoryFile(root, path.join(memoryRoot, entry.name), fsAsync)),\n );\n\n return {\n root,\n activeRepositoryRoot: path.resolve(options.activeRepositoryRoot),\n items: items.sort((left, right) =>\n `${left.category}/${left.key}`.localeCompare(`${right.category}/${right.key}`),\n ),\n };\n}\n\nexport async function inspectUserLocalMemoryItem(\n options: IUserLocalMemoryItemOptions,\n): Promise<IUserLocalMemoryItemProjection> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const { root, storageLocation } = await resolveMemoryFile(options);\n return readMemoryFile(root, storageLocation, fsAsync);\n}\n\nexport async function disableUserLocalMemoryItem(\n options: IUserLocalMemoryItemOptions,\n): Promise<IUserLocalMemoryItemProjection> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const { root, storageLocation } = await resolveMemoryFile(options);\n const existing = parseMemoryRecord(\n await fsAsync.readFile(storageLocation, 'utf8'),\n storageLocation,\n );\n const disabled: IUserLocalMemoryFile = {\n ...existing,\n enabled: false,\n lastUsedAt: formatIsoDate((options.now ?? (() => new Date()))()),\n };\n\n await fsAsync.writeFile(storageLocation, `${JSON.stringify(disabled, null, 2)}\\n`, 'utf8');\n return projectMemoryItem(root, storageLocation, disabled);\n}\n\nexport async function deleteUserLocalMemoryItem(\n options: IUserLocalMemoryItemOptions,\n): Promise<IUserLocalMemoryDeleteResult> {\n const fsAsync = options.fsAsync ?? new NodeFileSystemAsync();\n const { storageLocation } = await resolveMemoryFile(options);\n await fsAsync.rm(storageLocation);\n return {\n category: options.category,\n key: options.key,\n deleted: true,\n };\n}\n\nexport async function readEnabledUserLocalMemoryItem(\n options: IUserLocalMemoryItemOptions,\n): Promise<IUserLocalMemoryItemProjection | null> {\n const item = await inspectUserLocalMemoryItem(options);\n return item.enabled ? item : null;\n}\n","export type TSelfHostingVerificationPhase =\n | 'checkpoint'\n | 'edit'\n | 'handoff'\n | 'verify'\n | 'recover';\n\nexport type TSelfHostingLoopState =\n | 'idle'\n | 'checkpointed'\n | 'editing'\n | 'verifying'\n | 'passed'\n | 'failed'\n | 'rolled_back'\n | 'cancelled';\n\nexport type TSelfHostingLoopEvent =\n | 'checkpoint_created'\n | 'edits_started'\n | 'edits_applied'\n | 'verify_passed'\n | 'verify_failed'\n | 'rollback_completed'\n | 'cancelled';\n\nexport interface ISelfHostingVerificationPlanInput {\n changedFiles: readonly string[];\n packageScopes?: readonly string[];\n baseRef?: string;\n}\n\nexport interface ISelfHostingVerificationStep {\n id: string;\n phase: TSelfHostingVerificationPhase;\n description: string;\n required: boolean;\n command?: string;\n}\n\nexport interface ISelfHostingVerificationPlan {\n changedFiles: readonly string[];\n packageScopes: readonly string[];\n baseRef: string;\n steps: readonly ISelfHostingVerificationStep[];\n}\n\nconst DEFAULT_BASE_REF = 'origin/develop';\nconst PACKAGE_VERIFY_COMMANDS = ['test', 'typecheck', 'build'] as const;\n\nconst TRANSITIONS: Record<\n TSelfHostingLoopState,\n Partial<Record<TSelfHostingLoopEvent, TSelfHostingLoopState>>\n> = {\n idle: {\n checkpoint_created: 'checkpointed',\n cancelled: 'cancelled',\n },\n checkpointed: {\n edits_started: 'editing',\n cancelled: 'cancelled',\n },\n editing: {\n edits_applied: 'verifying',\n verify_failed: 'failed',\n cancelled: 'cancelled',\n },\n verifying: {\n verify_passed: 'passed',\n verify_failed: 'failed',\n cancelled: 'cancelled',\n },\n passed: {},\n failed: {\n rollback_completed: 'rolled_back',\n cancelled: 'cancelled',\n },\n rolled_back: {},\n cancelled: {},\n};\n\nfunction normalizePackageScopes(packageScopes: readonly string[] | undefined): readonly string[] {\n if (!packageScopes) {\n return [];\n }\n return Array.from(new Set(packageScopes.map((scope) => scope.trim()).filter(Boolean)));\n}\n\nfunction packageVerificationSteps(\n packageScopes: readonly string[],\n): ISelfHostingVerificationStep[] {\n return packageScopes.flatMap((scope) =>\n PACKAGE_VERIFY_COMMANDS.map(\n (commandName): ISelfHostingVerificationStep => ({\n id: `package-${commandName}:${scope}`,\n phase: 'verify',\n description: `Run ${commandName} for ${scope} in a child process against the new on-disk tree.`,\n required: true,\n command: `pnpm --filter ${scope} ${commandName}`,\n }),\n ),\n );\n}\n\nfunction preVerificationSteps(): ISelfHostingVerificationStep[] {\n return [\n {\n id: 'checkpoint',\n phase: 'checkpoint',\n description: 'Create a recoverable turn-level checkpoint before the first mutation.',\n required: true,\n },\n {\n id: 'atomic-edit',\n phase: 'edit',\n description:\n 'Apply Write/Edit mutations through same-directory temp files and atomic rename.',\n required: true,\n },\n {\n id: 'handoff',\n phase: 'handoff',\n description:\n 'Keep the current process on already-loaded code and run verification child processes against disk.',\n required: true,\n },\n ];\n}\n\nfunction harnessVerificationStep(baseRef: string): ISelfHostingVerificationStep {\n return {\n id: 'harness-verify',\n phase: 'verify',\n description: 'Run Robota harness verification as the local CI-like gate.',\n required: true,\n command: `pnpm harness:verify -- --base-ref ${baseRef} --skip-record-check`,\n };\n}\n\nfunction rollbackRecoveryStep(): ISelfHostingVerificationStep {\n return {\n id: 'rollback-on-failure',\n phase: 'recover',\n description: 'Use the existing edit checkpoint restore path if verification fails.',\n required: true,\n };\n}\n\nexport function planSelfHostingVerification(\n input: ISelfHostingVerificationPlanInput,\n): ISelfHostingVerificationPlan {\n if (input.changedFiles.length === 0) {\n throw new Error('Self-hosting verification requires at least one changed file.');\n }\n\n const baseRef = input.baseRef ?? DEFAULT_BASE_REF;\n const packageScopes = normalizePackageScopes(input.packageScopes);\n const steps: ISelfHostingVerificationStep[] = [\n ...preVerificationSteps(),\n ...packageVerificationSteps(packageScopes),\n harnessVerificationStep(baseRef),\n rollbackRecoveryStep(),\n ];\n\n return {\n changedFiles: [...input.changedFiles],\n packageScopes,\n baseRef,\n steps,\n };\n}\n\nexport function transitionSelfHostingLoop(\n state: TSelfHostingLoopState,\n event: TSelfHostingLoopEvent,\n): TSelfHostingLoopState {\n const nextState = TRANSITIONS[state][event];\n if (!nextState) {\n throw new Error(`Invalid self-hosting loop transition: ${state} -> ${event}`);\n }\n return nextState;\n}\n","import { createZodFunctionTool } from '@robota-sdk/agent-tools';\nimport { z } from 'zod';\n\nimport {\n normalizeModelCommandName,\n stringifyModelCommandResult,\n} from './model-command-tool-projection.js';\n\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { ICommandResult } from '../commands/index.js';\nimport type { IZodSchema } from '@robota-sdk/agent-tools';\n\ninterface ICommandExecutionArgs {\n command: string;\n args?: string;\n}\n\ntype TModelCommandDescriptor = Pick<ICapabilityDescriptor, 'name' | 'description' | 'argumentHint'>;\n\nexport interface ICommandExecutionToolDeps {\n isModelInvocable: (command: string) => boolean;\n execute: (command: string, args: string) => Promise<ICommandResult | null>;\n commandNames?: readonly string[];\n commandDescriptors?: readonly TModelCommandDescriptor[];\n}\n\nfunction asZodSchema(schema: z.ZodType): IZodSchema {\n return schema as IZodSchema;\n}\n\nfunction toNonEmptyCommandNames(\n commandNames?: readonly string[],\n): [string, ...string[]] | undefined {\n if (!commandNames || commandNames.length === 0) return undefined;\n const [first, ...rest] = commandNames;\n if (first === undefined) return undefined;\n return [first, ...rest];\n}\n\nfunction createCommandExecutionSchema(\n commandNames?: readonly string[],\n): z.ZodType<ICommandExecutionArgs> {\n const validCommandNames = toNonEmptyCommandNames(commandNames);\n const commandSchema =\n validCommandNames !== undefined\n ? z.enum(validCommandNames).describe('Registered model-invocable command name to execute')\n : z.string().describe('Registered model-invocable command name to execute');\n\n return z.object({\n command: commandSchema,\n args: z.string().optional().describe('Arguments to pass to the command'),\n });\n}\n\nfunction getCommandNames(deps: ICommandExecutionToolDeps): readonly string[] | undefined {\n if (deps.commandNames !== undefined) return deps.commandNames;\n if (deps.commandDescriptors === undefined) return undefined;\n return deps.commandDescriptors.map((descriptor) => normalizeModelCommandName(descriptor.name));\n}\n\nfunction formatCommandDescriptor(descriptor: TModelCommandDescriptor): string {\n const commandName = normalizeModelCommandName(descriptor.name);\n const argumentHint = descriptor.argumentHint ? ` ${descriptor.argumentHint}` : '';\n return `- ${commandName}${argumentHint}: ${descriptor.description}`;\n}\n\nfunction createToolDescription(commandDescriptors?: readonly TModelCommandDescriptor[]): string {\n const base =\n 'Executes a registered model-invocable Robota command through the command registry. Accepted command names and argument grammar come from registered command descriptors.';\n if (commandDescriptors === undefined || commandDescriptors.length === 0) return base;\n return [\n base,\n 'Use the registered command descriptors below as the authority for when to call this tool.',\n '',\n 'Registered model-invocable commands:',\n ...commandDescriptors.map(formatCommandDescriptor),\n ].join('\\n');\n}\n\nexport function createCommandExecutionTool(\n deps: ICommandExecutionToolDeps,\n): ReturnType<typeof createZodFunctionTool> {\n const commandExecutionSchema = createCommandExecutionSchema(getCommandNames(deps));\n return createZodFunctionTool(\n 'ExecuteCommand',\n createToolDescription(deps.commandDescriptors),\n asZodSchema(commandExecutionSchema),\n async (params) => {\n const args: ICommandExecutionArgs = commandExecutionSchema.parse(params);\n const command = normalizeModelCommandName(args.command);\n if (!deps.isModelInvocable(command)) {\n return JSON.stringify({\n success: false,\n command,\n error: `Command is not model-invocable: ${command}`,\n });\n }\n return stringifyModelCommandResult(command, await deps.execute(command, args.args ?? ''));\n },\n );\n}\n","/**\n * Interactive permission prompt — asks the user whether to allow a tool invocation\n * using an arrow-key selector. Canonical implementation (SSOT).\n * Used by both agent-sdk query() and agent-cli.\n */\n\nimport type { ITerminalOutput } from '../types.js';\nimport type { TToolArgs } from '@robota-sdk/agent-core';\n\nconst PERMISSION_OPTIONS = ['Allow', 'Deny'];\nconst ALLOW_INDEX = 0;\n\nfunction formatArgs(toolArgs: TToolArgs): string {\n const entries = Object.entries(toolArgs);\n if (entries.length === 0) {\n return '(no arguments)';\n }\n return entries\n .map(([k, v]) => `${k}: ${typeof v === 'string' ? v : JSON.stringify(v)}`)\n .join(', ');\n}\n\nexport async function promptForApproval(\n terminal: ITerminalOutput,\n toolName: string,\n toolArgs: TToolArgs,\n): Promise<boolean> {\n terminal.writeLine('');\n terminal.writeError(`[Permission Required] Tool: ${toolName}`);\n terminal.writeLine(` ${formatArgs(toolArgs)}`);\n terminal.writeLine('');\n\n const selected = await terminal.select(PERMISSION_OPTIONS, ALLOW_INDEX);\n return selected === ALLOW_INDEX;\n}\n","import type { IInteractiveSession } from '../interactive/i-interactive-session.js';\n\nconst EMPTY_CONTEXT_STATE = {\n usedTokens: 0,\n maxTokens: 200000,\n usedPercentage: 0,\n remainingPercentage: 100,\n};\n\nconst EMPTY_EXECUTION_WORKSPACE = {\n sessionId: 'test-session-id',\n updatedAt: new Date().toISOString(),\n entries: [] as [],\n};\n\nconst EMPTY_BACKGROUND_GROUP = {\n id: '',\n parentSessionId: 'test-session-id',\n waitPolicy: 'wait_all' as const,\n taskIds: [],\n status: 'completed' as const,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n results: [],\n};\n\n/** Creates a stub IInteractiveSession for use in tests. All methods return sensible defaults.\n * Pass overrides to spy on or replace specific methods. */\nexport function createTestInteractiveSession(\n overrides?: Partial<IInteractiveSession>,\n): IInteractiveSession {\n const base: IInteractiveSession = {\n submit: () => Promise.resolve(),\n abort: () => {},\n cancelQueue: () => {},\n shutdown: () => Promise.resolve(),\n isExecuting: () => false,\n getPendingPrompt: () => null,\n getMessages: () => [],\n getContextState: () => ({ ...EMPTY_CONTEXT_STATE }),\n getSession: () => ({ getSessionId: () => 'test-session-id' }),\n getCwd: () => '/workspace',\n executeCommand: () => Promise.resolve(null),\n listCommands: () => [],\n on: () => {},\n off: () => {},\n listBackgroundTasks: () => [],\n getBackgroundTask: () => undefined,\n cancelBackgroundTask: () => Promise.resolve(),\n closeBackgroundTask: () => Promise.resolve(),\n sendBackgroundTask: () => Promise.resolve(),\n readBackgroundTaskLog: () => Promise.resolve({ taskId: '', lines: [] }),\n listBackgroundJobGroups: () => [],\n getBackgroundJobGroup: () => undefined,\n createBackgroundJobGroup: () => ({ ...EMPTY_BACKGROUND_GROUP }),\n waitBackgroundJobGroup: () => Promise.resolve({ ...EMPTY_BACKGROUND_GROUP }),\n getExecutionWorkspaceSnapshot: () => ({ ...EMPTY_EXECUTION_WORKSPACE }),\n listAgentDefinitions: () => [],\n listAgentJobs: () => [],\n spawnAgentJob: () =>\n Promise.resolve({\n id: 'agent_1',\n type: 'general-purpose',\n label: 'general-purpose',\n parentSessionId: 'test-session-id',\n status: 'running' as const,\n mode: 'background' as const,\n depth: 1,\n cwd: '/workspace',\n promptPreview: '',\n updatedAt: new Date().toISOString(),\n }),\n sendAgentJob: () => Promise.resolve(),\n cancelAgentJob: () => Promise.resolve(),\n closeAgentJob: () => Promise.resolve(),\n ...overrides,\n };\n return base;\n}\n","import { deleteSettings, getUserSettingsPath } from './settings-io.js';\n\nexport interface IResetUserConfigResult {\n deleted: boolean;\n path: string;\n}\n\nexport function resetUserConfig(): IResetUserConfigResult {\n const path = getUserSettingsPath();\n const deleted = deleteSettings(path);\n return { deleted, path };\n}\n","import { existsSync, lstatSync, readFileSync } from 'node:fs';\nimport { dirname, isAbsolute, join, resolve } from 'node:path';\n\nconst DETACHED_HEAD_LENGTH = 7;\n\nexport function resolveGitBranch(cwd: string): string | undefined {\n try {\n const gitDir = findGitDir(cwd);\n if (!gitDir) return undefined;\n\n const head = readFileSync(join(gitDir, 'HEAD'), 'utf8').trim();\n if (!head) return undefined;\n if (head.startsWith('ref: ')) {\n const ref = head.slice('ref: '.length).trim();\n const branchPrefix = 'refs/heads/';\n return ref.startsWith(branchPrefix) ? ref.slice(branchPrefix.length) : ref;\n }\n return head.slice(0, DETACHED_HEAD_LENGTH);\n } catch {\n // allow-fallback: git I/O failures are non-fatal; return undefined to skip branch display\n return undefined;\n }\n}\n\nfunction findGitDir(start: string): string | undefined {\n let current = resolve(start);\n let parent = dirname(current);\n\n while (parent !== current) {\n const candidate = join(current, '.git');\n const resolved = resolveGitMetadata(candidate, current);\n if (resolved) return resolved;\n\n current = parent;\n parent = dirname(current);\n }\n\n const rootCandidate = join(current, '.git');\n return resolveGitMetadata(rootCandidate, current);\n}\n\nfunction resolveGitMetadata(candidate: string, repoDir: string): string | undefined {\n if (!existsSync(candidate)) return undefined;\n const stat = lstatSync(candidate);\n if (stat.isDirectory()) return candidate;\n if (!stat.isFile()) return undefined;\n\n const content = readFileSync(candidate, 'utf8').trim();\n const prefix = 'gitdir:';\n if (!content.startsWith(prefix)) return undefined;\n const rawPath = content.slice(prefix.length).trim();\n return isAbsolute(rawPath) ? rawPath : resolve(repoDir, rawPath);\n}\n","interface IParsedSemver {\n major: number;\n minor: number;\n patch: number;\n prerelease: string[];\n}\n\nexport function compareSemverVersions(left: string, right: string): number {\n const parsedLeft = parseSemver(left);\n const parsedRight = parseSemver(right);\n if (parsedLeft === undefined || parsedRight === undefined) {\n return Math.sign(left.localeCompare(right));\n }\n\n const coreCompare =\n compareNumber(parsedLeft.major, parsedRight.major) ||\n compareNumber(parsedLeft.minor, parsedRight.minor) ||\n compareNumber(parsedLeft.patch, parsedRight.patch);\n if (coreCompare !== 0) {\n return coreCompare;\n }\n\n return comparePrerelease(parsedLeft.prerelease, parsedRight.prerelease);\n}\n\nexport function isNewerSemverVersion(candidate: string, current: string): boolean {\n return compareSemverVersions(candidate, current) > 0;\n}\n\nfunction parseSemver(value: string): IParsedSemver | undefined {\n const normalized = value.trim().replace(/^v/, '').split('+')[0] ?? '';\n const [core, prereleaseText] = normalized.split('-', 2);\n const [majorText, minorText, patchText] = core.split('.');\n const major = parseNumericIdentifier(majorText);\n const minor = parseNumericIdentifier(minorText);\n const patch = parseNumericIdentifier(patchText);\n if (major === undefined || minor === undefined || patch === undefined) {\n return undefined;\n }\n return {\n major,\n minor,\n patch,\n prerelease: prereleaseText ? prereleaseText.split('.') : [],\n };\n}\n\nfunction parseNumericIdentifier(value: string | undefined): number | undefined {\n if (value === undefined || !/^\\d+$/.test(value)) {\n return undefined;\n }\n return Number(value);\n}\n\nfunction compareNumber(left: number, right: number): number {\n return Math.sign(left - right);\n}\n\nfunction comparePrerelease(left: string[], right: string[]): number {\n if (left.length === 0 && right.length === 0) {\n return 0;\n }\n if (left.length === 0) {\n return 1;\n }\n if (right.length === 0) {\n return -1;\n }\n const max = Math.max(left.length, right.length);\n for (let index = 0; index < max; index += 1) {\n const leftPart = left[index];\n const rightPart = right[index];\n if (leftPart === undefined) {\n return -1;\n }\n if (rightPart === undefined) {\n return 1;\n }\n const partCompare = comparePrereleaseIdentifier(leftPart, rightPart);\n if (partCompare !== 0) {\n return partCompare;\n }\n }\n return 0;\n}\n\nfunction comparePrereleaseIdentifier(left: string, right: string): number {\n const leftNumber = parseNumericIdentifier(left);\n const rightNumber = parseNumericIdentifier(right);\n if (leftNumber !== undefined && rightNumber !== undefined) {\n return compareNumber(leftNumber, rightNumber);\n }\n if (leftNumber !== undefined) {\n return -1;\n }\n if (rightNumber !== undefined) {\n return 1;\n }\n return Math.sign(left.localeCompare(right));\n}\n","import {\n createDefaultBackgroundTaskRunners,\n type IBackgroundTaskRunner,\n} from '@robota-sdk/agent-executor';\n\nimport { getUserSettingsPath, readSettings, writeSettings } from '../config/settings-io.js';\nimport { InteractiveSession } from '../interactive/interactive-session.js';\nimport { createProjectSessionStore } from '../interactive/session-persistence.js';\n\nimport type { ICommandHostAdapters, ICommandModule } from '../commands/index.js';\nimport type { CommandRegistry } from '../commands/index.js';\nimport type { IInteractiveSession, IInteractiveSessionStore } from '../interactive/index.js';\nimport type { TSubagentRunnerFactory } from '../subagents/index.js';\nimport type { TShellExecFn } from '../utils/skill-prompt.js';\nimport type { IAIProvider, TPermissionMode } from '@robota-sdk/agent-core';\nimport type { ITransportRegistryView } from '@robota-sdk/agent-interface-transport';\n\nexport interface IAgentRuntimeConfig {\n cwd: string;\n provider: IAIProvider;\n commandModules?: readonly ICommandModule[];\n commandHostAdapters?: ICommandHostAdapters;\n backgroundTaskRunners?: IBackgroundTaskRunner[];\n subagentRunnerFactory?: TSubagentRunnerFactory;\n sessionStore?: IInteractiveSessionStore;\n transportRegistry?: ITransportRegistryView<IInteractiveSession>;\n reloadPluginCommandSource?: (registry: CommandRegistry) => void;\n}\n\n/** Session-specific options for IAgentRuntime.createSession(). Runtime fields (cwd, provider, etc.) are inherited automatically. */\nexport interface IHeadlessSessionOptions {\n permissionMode?: TPermissionMode;\n maxTurns?: number;\n sessionStore?: IInteractiveSessionStore;\n sessionName?: string;\n bare?: boolean;\n allowedTools?: string[];\n appendSystemPrompt?: string;\n /** Replace the entire system prompt. Takes precedence over the default builder. */\n systemPrompt?: string;\n shellExec?: TShellExecFn;\n agentName?: string;\n}\n\nexport interface IAgentRuntime {\n readonly cwd: string;\n readonly provider: IAIProvider;\n readonly commandModules: readonly ICommandModule[];\n readonly commandHostAdapters: ICommandHostAdapters;\n readonly backgroundTaskRunners: IBackgroundTaskRunner[];\n readonly subagentRunnerFactory: TSubagentRunnerFactory | undefined;\n readonly sessionStore: IInteractiveSessionStore | undefined;\n readonly transportRegistry: ITransportRegistryView<IInteractiveSession> | undefined;\n readonly reloadPluginCommandSource: (registry: CommandRegistry) => void;\n createSession(opts: IHeadlessSessionOptions): InteractiveSession;\n}\n\nexport function createAgentRuntime(config: IAgentRuntimeConfig): IAgentRuntime {\n const settingsPath = getUserSettingsPath();\n const defaultCommandHostAdapters: ICommandHostAdapters = {\n settings: {\n read: () => readSettings(settingsPath),\n write: (settings) => writeSettings(settingsPath, settings),\n },\n };\n\n const backgroundTaskRunners =\n config.backgroundTaskRunners ?? createDefaultBackgroundTaskRunners();\n const commandModules = config.commandModules ?? [];\n const commandHostAdapters = config.commandHostAdapters ?? defaultCommandHostAdapters;\n const sessionStore =\n 'sessionStore' in config ? config.sessionStore : createProjectSessionStore(config.cwd);\n\n return {\n cwd: config.cwd,\n provider: config.provider,\n commandModules,\n commandHostAdapters,\n backgroundTaskRunners,\n subagentRunnerFactory: config.subagentRunnerFactory,\n sessionStore,\n transportRegistry: config.transportRegistry,\n reloadPluginCommandSource: config.reloadPluginCommandSource ?? (() => {}),\n createSession(opts: IHeadlessSessionOptions): InteractiveSession {\n return new InteractiveSession({\n cwd: config.cwd,\n provider: config.provider,\n backgroundTaskRunners,\n subagentRunnerFactory: config.subagentRunnerFactory,\n commandModules,\n commandHostAdapters,\n permissionMode: opts.permissionMode,\n maxTurns: opts.maxTurns,\n sessionStore: opts.sessionStore,\n sessionName: opts.sessionName,\n bare: opts.bare,\n allowedTools: opts.allowedTools,\n appendSystemPrompt: opts.appendSystemPrompt,\n systemPrompt: opts.systemPrompt,\n shellExec: opts.shellExec,\n agentName: opts.agentName,\n });\n },\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport function readPackageVersion(importMetaUrl: string): string {\n const dir = dirname(fileURLToPath(importMetaUrl));\n const candidates = [join(dir, '..', '..', 'package.json'), join(dir, '..', 'package.json')];\n\n for (const pkgPath of candidates) {\n try {\n const raw = readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(raw) as { version?: string; name?: string };\n if (pkg.version !== undefined && pkg.name !== undefined) {\n return pkg.version;\n }\n } catch {\n // allow-fallback: package.json absent at this candidate path; advance to next\n continue;\n }\n }\n\n return '0.0.0'; // allow-fallback: version display must not crash startup when no package.json found\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { compareSemverVersions, isNewerSemverVersion } from '../utils/semver-compare.js';\n\nexport const CLI_UPDATE_PACKAGE_NAME = '@robota-sdk/agent-cli';\nexport const CLI_UPDATE_REGISTRY_URL = 'https://registry.npmjs.org';\nconst HOURS_PER_DAY = 24;\nconst MINUTES_PER_HOUR = 60;\nconst SECONDS_PER_MINUTE = 60;\nconst MS_PER_SECOND = 1000;\nexport const CLI_UPDATE_CACHE_TTL_MS =\n HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND;\nexport const CLI_UPDATE_TIMEOUT_MS = 1500;\n\nconst DEFAULT_INSTALL_COMMAND = \"npm install -g '@robota-sdk/agent-cli@latest'\";\n\nexport interface ICliUpdateNotice {\n currentVersion: string;\n latestVersion: string;\n installCommand: string;\n}\n\nexport interface IUpdateCheckCache {\n packageName: string;\n checkedAt: string;\n currentVersion: string;\n latestVersion?: string;\n errorMessage?: string;\n}\n\nexport type TCliUpdateCheckResult =\n | { status: 'skipped'; reason: 'disabled' }\n | { status: 'current'; currentVersion: string; latestVersion: string }\n | { status: 'update_available'; notice: ICliUpdateNotice }\n | { status: 'error'; errorMessage: string };\n\nexport interface ICheckForCliUpdateOptions {\n currentVersion: string;\n disabled?: boolean;\n force?: boolean;\n cachePath?: string;\n now?: Date;\n ttlMs?: number;\n timeoutMs?: number;\n registryUrl?: string;\n packageName?: string;\n fetchImpl?: typeof fetch;\n}\n\nexport interface IStartupCliUpdatePolicyInput {\n printMode: boolean;\n disableUpdateCheck: boolean;\n}\n\ninterface INpmPackageMetadata {\n 'dist-tags'?: {\n latest?: TJsonValue;\n };\n}\nexport { compareSemverVersions, isNewerSemverVersion };\n\ntype TJsonValue =\n | string\n | number\n | boolean\n | null\n | readonly TJsonValue[]\n | { readonly [key: string]: TJsonValue };\n\nexport function getUserUpdateCheckCachePath(\n home = process.env.HOME ?? process.env.USERPROFILE ?? '/',\n): string {\n return join(home, '.robota', 'update-check.json');\n}\n\nexport function readUpdateCheckCache(path: string): IUpdateCheckCache | undefined {\n if (!existsSync(path)) {\n return undefined;\n }\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8')) as TJsonValue;\n return parseUpdateCheckCache(parsed);\n } catch {\n // allow-fallback: corrupt cache must not block startup; silently discard and re-fetch\n return undefined;\n }\n}\n\nexport function writeUpdateCheckCache(path: string, cache: IUpdateCheckCache): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(cache, null, 2) + '\\n', 'utf8');\n}\n\nexport async function checkForCliUpdate(\n options: ICheckForCliUpdateOptions,\n): Promise<TCliUpdateCheckResult> {\n if (options.disabled === true) {\n return { status: 'skipped', reason: 'disabled' };\n }\n\n const packageName = options.packageName ?? CLI_UPDATE_PACKAGE_NAME;\n const cachePath = options.cachePath ?? getUserUpdateCheckCachePath();\n const now = options.now ?? new Date();\n const ttlMs = options.ttlMs ?? CLI_UPDATE_CACHE_TTL_MS;\n\n if (options.force !== true) {\n const cached = readUpdateCheckCache(cachePath);\n if (cached !== undefined && isFreshCache(cached, now, ttlMs, packageName)) {\n return resultFromCache(cached, options.currentVersion);\n }\n }\n\n const latestVersion = await fetchLatestVersionOrError(options, packageName, cachePath, now);\n if (typeof latestVersion !== 'string') {\n return latestVersion;\n }\n return resultFromLatestVersion(options.currentVersion, latestVersion);\n}\n\nasync function fetchLatestVersionOrError(\n options: ICheckForCliUpdateOptions,\n packageName: string,\n cachePath: string,\n now: Date,\n): Promise<string | TCliUpdateCheckResult> {\n const result = await attemptFetchLatestVersion({\n fetchImpl: options.fetchImpl ?? fetch,\n packageName,\n registryUrl: options.registryUrl ?? CLI_UPDATE_REGISTRY_URL,\n timeoutMs: options.timeoutMs ?? CLI_UPDATE_TIMEOUT_MS,\n });\n if (result.ok) {\n tryWriteUpdateCheckCache(cachePath, {\n packageName,\n checkedAt: now.toISOString(),\n currentVersion: options.currentVersion,\n latestVersion: result.version,\n });\n return result.version;\n }\n tryWriteUpdateCheckCache(cachePath, {\n packageName,\n checkedAt: now.toISOString(),\n currentVersion: options.currentVersion,\n errorMessage: result.errorMessage,\n });\n return { status: 'error', errorMessage: result.errorMessage };\n}\n\nfunction tryWriteUpdateCheckCache(path: string, cache: IUpdateCheckCache): void {\n try {\n writeUpdateCheckCache(path, cache);\n } catch {\n // allow-fallback: update cache I/O must not break CLI startup\n }\n}\n\nexport async function getStartupCliUpdateNotice(\n options: ICheckForCliUpdateOptions,\n): Promise<ICliUpdateNotice | undefined> {\n const result = await checkForCliUpdate(options);\n return result.status === 'update_available' ? result.notice : undefined;\n}\n\nexport function shouldRunStartupCliUpdateCheck(input: IStartupCliUpdatePolicyInput): boolean {\n return input.printMode === false && input.disableUpdateCheck === false;\n}\n\nexport function formatCliUpdateNotice(notice: ICliUpdateNotice): string {\n return [\n `Robota update available: ${notice.currentVersion} -> ${notice.latestVersion}.`,\n `Run ${notice.installCommand}`,\n ].join(' ');\n}\n\nexport function formatCliUpdateCheckMessage(result: TCliUpdateCheckResult): string {\n if (result.status === 'update_available') {\n return formatCliUpdateNotice(result.notice);\n }\n if (result.status === 'current') {\n return `Robota is up to date (${result.currentVersion}).`;\n }\n if (result.status === 'skipped') {\n return 'Robota update check skipped.';\n }\n return `Robota update check failed: ${result.errorMessage}`;\n}\n\nfunction resultFromCache(cache: IUpdateCheckCache, currentVersion: string): TCliUpdateCheckResult {\n if (cache.errorMessage !== undefined) {\n return { status: 'error', errorMessage: cache.errorMessage };\n }\n if (cache.latestVersion === undefined) {\n return { status: 'error', errorMessage: 'Cached update check has no latest version' };\n }\n return resultFromLatestVersion(currentVersion, cache.latestVersion);\n}\n\nfunction resultFromLatestVersion(\n currentVersion: string,\n latestVersion: string,\n): TCliUpdateCheckResult {\n if (isNewerSemverVersion(latestVersion, currentVersion)) {\n return {\n status: 'update_available',\n notice: {\n currentVersion,\n latestVersion,\n installCommand: DEFAULT_INSTALL_COMMAND,\n },\n };\n }\n return { status: 'current', currentVersion, latestVersion };\n}\n\nfunction isFreshCache(\n cache: IUpdateCheckCache,\n now: Date,\n ttlMs: number,\n packageName: string,\n): boolean {\n if (cache.packageName !== packageName) {\n return false;\n }\n const checkedAt = Date.parse(cache.checkedAt);\n if (!Number.isFinite(checkedAt)) {\n return false;\n }\n return now.getTime() - checkedAt < ttlMs;\n}\n\ntype TFetchResult = { ok: true; version: string } | { ok: false; errorMessage: string };\n\nasync function attemptFetchLatestVersion(options: {\n fetchImpl: typeof fetch;\n packageName: string;\n registryUrl: string;\n timeoutMs: number;\n}): Promise<TFetchResult> {\n try {\n const version = await fetchLatestVersion(options);\n return { ok: true, version };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return { ok: false, errorMessage };\n }\n}\n\nasync function fetchLatestVersion(options: {\n fetchImpl: typeof fetch;\n packageName: string;\n registryUrl: string;\n timeoutMs: number;\n}): Promise<string> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs);\n try {\n const packageUrl = buildPackageMetadataUrl(options.registryUrl, options.packageName);\n const response = await options.fetchImpl(packageUrl, {\n headers: { accept: 'application/json' },\n signal: controller.signal,\n });\n if (!response.ok) {\n throw new Error(`registry responded with HTTP ${response.status}`);\n }\n const metadata = (await response.json()) as INpmPackageMetadata;\n const latest = metadata['dist-tags']?.latest;\n if (typeof latest !== 'string' || latest.trim().length === 0) {\n throw new Error('registry metadata is missing dist-tags.latest');\n }\n return latest;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction buildPackageMetadataUrl(registryUrl: string, packageName: string): string {\n return `${registryUrl.replace(/\\/+$/, '')}/${encodeURIComponent(packageName)}`;\n}\n\nfunction parseUpdateCheckCache(value: TJsonValue): IUpdateCheckCache | undefined {\n if (!isJsonObject(value)) {\n return undefined;\n }\n const candidate = value;\n if (\n typeof candidate.packageName === 'string' &&\n typeof candidate.checkedAt === 'string' &&\n typeof candidate.currentVersion === 'string' &&\n (candidate.latestVersion === undefined || typeof candidate.latestVersion === 'string') &&\n (candidate.errorMessage === undefined || typeof candidate.errorMessage === 'string')\n ) {\n return {\n packageName: candidate.packageName,\n checkedAt: candidate.checkedAt,\n currentVersion: candidate.currentVersion,\n ...(candidate.latestVersion !== undefined && { latestVersion: candidate.latestVersion }),\n ...(candidate.errorMessage !== undefined && { errorMessage: candidate.errorMessage }),\n };\n }\n return undefined;\n}\n\nfunction isJsonObject(value: TJsonValue): value is { readonly [key: string]: TJsonValue } {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n"],"mappings":"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"}