@robota-sdk/agent-framework 3.0.0-beta.79 → 3.0.0-beta.82

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 +0,0 @@
1
- {"version":3,"file":"interactive-C93XBn4U.js","names":["pathRelative","pathSeparator","resolveAgentDefinition","extractFirstArg","resolveAgentDefinition","toSummary","existsSync","readFileSync","join","LIST_KEYS","parseListValue","parseFrontmatter","extractJson","SessionWithAutoCompact","existsSync","readFileSync","mergeSettings","mergeProviders","join","memoryRoot","join","existsSync","readFileSync","readdirSync","basename","resolve","join","existsSync","dirname","hasUsableRequiredProviderCredential","resolveProviderCredentialValue"],"sources":["../../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/adapters/node-file-system.ts","../../src/context/prompt-file-reference-resolver.ts","../../src/interactive/interactive-session-execution.ts","../../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/context/context-file-tracker.ts","../../src/interactive/interactive-session-context-refresh.ts","../../src/interactive/interactive-session-streaming.ts","../../src/utils/error-humanizer.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/memory/memory-event-format.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/config/settings-parse-error.ts","../../src/config/settings-io.ts","../../src/goal/goal-status-tool.ts","../../src/goal/goal-prompts.ts","../../src/goal/goal-controller.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/bundle-plugin-utils.ts","../../src/plugins/bundle-plugin-loader.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/command-api/provider/provider-configuration.ts","../../src/command-api/provider/provider-factory.ts","../../src/commands/plugin-source.ts","../../src/commands/command-module-selection.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/language/language-command-api.ts","../../src/command-api/permissions/permission-mode-command-api.ts","../../src/command-api/preset/preset-application.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/command-api/org-policy/org-policy-loader.ts","../../src/interaction/user-interaction-port.ts","../../src/interactive/interactive-session.ts","../../src/interactive/session-persistence.ts","../../src/interactive/session-naming.ts"],"sourcesContent":["import type {\n IPromptFileReferenceRecord,\n TPromptFileReferenceReason,\n} from './prompt-file-reference-types.js';\n// Context-reference contracts SSOT relocated to @robota-sdk/agent-interface-transport (DATA-001).\nimport type {\n IContextReferenceItem,\n TContextReferenceLoadType,\n TContextReferenceStatus,\n} from '@robota-sdk/agent-interface-transport';\n\nexport type { IContextReferenceItem, TContextReferenceLoadType, TContextReferenceStatus };\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\n .filter((reference) => reference.loadType !== 'system')\n .map((reference) => ({\n originalReference: reference.originalReference,\n sourcePath: reference.sourcePath,\n relativePath: reference.relativePath,\n reason: reference.loadType as TPromptFileReferenceReason,\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 {\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 { 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';\nimport type { IUsageSource } from '@robota-sdk/agent-interface-transport';\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 */\nfunction extractToolSummaries(history: TUniversalMessage[], historyBefore: number): 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\n/**\n * ANALYTICS-001 (Phase 2): build a usage-summary entry attributed to a non-main source (a subagent /\n * background task) so the parent session log can report token usage per source. Context fields are\n * not meaningful for a child run and are left at 0; the usage reducer only reads the token totals.\n */\nexport function createSourceUsageSummaryEntry(\n totals: { promptTokens: number; completionTokens: number; totalTokens: number },\n source: IUsageSource,\n): IHistoryEntry<IUsageSnapshot> {\n return createUsageSummaryEntry({\n kind: 'exact',\n scope: 'turn',\n totalTokens: totals.totalTokens,\n promptTokens: totals.promptTokens,\n completionTokens: totals.completionTokens,\n contextUsedTokens: 0,\n contextMaxTokens: 0,\n contextUsedPercentage: 0,\n costStatus: 'exact',\n source,\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","import {\n isTerminalBackgroundTaskStatus,\n type IBackgroundTaskManager,\n} from '@robota-sdk/agent-executor';\n\n// Background job-group contracts SSOT relocated to @robota-sdk/agent-interface-transport (DATA-001).\nimport type {\n IBackgroundJobGroupCreateRequest,\n IBackgroundJobGroupState,\n IBackgroundJobGroupSummary,\n IBackgroundJobResultEnvelope,\n TBackgroundJobGroupEvent,\n TBackgroundJobGroupEventListener,\n TBackgroundJobGroupIdFactory,\n} from '@robota-sdk/agent-interface-transport';\n\nexport type {\n TBackgroundJobWaitPolicy,\n TBackgroundJobGroupStatus,\n IBackgroundJobResultEnvelope,\n IBackgroundJobGroupState,\n IBackgroundJobGroupSummary,\n IBackgroundJobGroupCreateRequest,\n TBackgroundJobGroupEvent,\n TBackgroundJobGroupEventListener,\n TBackgroundJobGroupIdFactory,\n} from '@robota-sdk/agent-interface-transport';\nimport type {\n IBackgroundTaskState,\n TBackgroundTaskEvent,\n TBackgroundTaskStatus,\n} from '@robota-sdk/agent-interface-transport';\n\nconst DEFAULT_SUMMARY_LENGTH = 1_000;\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","// Execution-workspace contracts SSOT relocated to @robota-sdk/agent-interface-transport (DATA-001).\nimport type {\n IExecutionOrigin,\n IExecutionWorkspaceEntryRef,\n} from '@robota-sdk/agent-interface-transport';\n\nexport type {\n TExecutionEntryKind,\n TExecutionWorkspaceStatus,\n TExecutionAttention,\n TExecutionWorkspaceVisibility,\n TExecutionControl,\n TExecutionOriginKind,\n TExecutionDetailRecordKind,\n TExecutionWorkspaceUpdateCause,\n IExecutionOrigin,\n IExecutionWorkspaceEntry,\n IExecutionWorkspaceFilter,\n IExecutionWorkspaceSnapshot,\n IExecutionWorkspaceSnapshotOptions,\n IExecutionWorkspaceEvent,\n IExecutionDetailCursor,\n IExecutionDetailRecord,\n IExecutionDetailPage,\n ICreateMainThreadEntryInput,\n ICreateExecutionWorkspaceSnapshotInput,\n IExecutionWorkspaceEntryRef,\n ICreateMainThreadDetailPageInput,\n ICreateLineDetailPageInput,\n} from '@robota-sdk/agent-interface-transport';\nimport type { TBackgroundPrimitive } from '@robota-sdk/agent-interface-transport';\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 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 {\n IBackgroundTaskState,\n TBackgroundPrimitive,\n} from '@robota-sdk/agent-interface-transport';\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\n/** FLOW-006: max characters of the wake instruction shown inline in the workspace row. */\nconst WAKE_PREVIEW_LENGTH = 32;\n\nfunction createTaskSubtitle(state: IBackgroundTaskState): string | undefined {\n if (state.kind === 'agent') return state.agentType ?? state.cwd;\n // FLOW-006: distinguish an agent-wake schedule (carries an instruction) from a shell-only\n // schedule with a `↻ wake` marker + a truncated instruction preview, beside `next: Xm`.\n const wakeInstruction = state.schedule?.agentInstruction;\n if (state.status === 'sleeping' && state.nextFireAt !== undefined) {\n const next = `next: ${formatNextFireAt(state.nextFireAt)}`;\n if (wakeInstruction !== undefined) {\n return `↻ wake \"${truncateWakePreview(wakeInstruction)}\" · ${next}`;\n }\n return next;\n }\n return state.cwd;\n}\n\nfunction truncateWakePreview(instruction: string): string {\n const trimmed = instruction.trim();\n return trimmed.length > WAKE_PREVIEW_LENGTH\n ? `${trimmed.slice(0, WAKE_PREVIEW_LENGTH)}…`\n : trimmed;\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\n// SCREEN-010: order by a STABLE key (creation/start order), not by `lastActivityAt`. Sorting by\n// last activity made every running task jump to the top on each activity tick, so the list churned\n// constantly. `startedAt` is fixed once a task starts, so ascending order keeps each row in its slot\n// once it appears; new tasks append. `id` is the deterministic tiebreaker for not-yet-started tasks.\nfunction sortTasks(tasks: readonly IBackgroundTaskState[]): IBackgroundTaskState[] {\n return [...tasks].sort((left, right) => {\n const leftKey = left.startedAt ?? left.updatedAt;\n const rightKey = right.startedAt ?? right.updatedAt;\n const byStart = leftKey.localeCompare(rightKey);\n return byStart !== 0 ? byStart : left.id.localeCompare(right.id);\n });\n}\n\nfunction sortGroups(groups: readonly IBackgroundJobGroupState[]): IBackgroundJobGroupState[] {\n // Stable order too (SCREEN-010): groups carry no start time, so order by their creation id.\n return [...groups].sort((left, right) => left.id.localeCompare(right.id));\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 { IBackgroundTaskManager } from '@robota-sdk/agent-executor';\nimport type {\n IAgentBackgroundTaskRequest,\n IBackgroundTaskState,\n IProcessBackgroundTaskRequest,\n TBackgroundPermissionPolicy,\n TBackgroundTaskIsolation,\n TBackgroundTaskMode,\n} from '@robota-sdk/agent-interface-transport';\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 toolCallId?: string,\n ) => ISubagentSpawnRequest;\n toolCallId?: string;\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(\n job.job,\n job.agentType,\n job.agentDef,\n input.deps,\n job.label,\n input.toolCallId,\n ),\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\n/**\n * PRESET-016 — terminal result returned when the runtime gate refuses subagent dispatch.\n * No job is started, so all counts are zero and `success` is false.\n */\nexport function stringifyParallelSubagentsDisabled(): string {\n return JSON.stringify({\n success: false,\n mode: 'single',\n requestedJobCount: 0,\n startedJobCount: 0,\n failedJobCount: 0,\n output: '',\n error: 'Parallel subagents are disabled for the active preset.',\n provenance: {\n source: 'agent-tool-single',\n requestedJobCount: 0,\n startedJobCount: 0,\n failedJobCount: 0,\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 subagents; 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';\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<\n ICapabilityDescriptor,\n 'name' | 'description' | 'argumentHint' | 'requiresPermission'\n>;\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 /** Mirrors the source command's requiresPermission flag. false = auto-approved. */\n readonly requiresPermission: boolean;\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\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 requiresPermission: descriptor.requiresPermission !== false,\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 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 executionId?: 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 { sumHistoryUsage } from '@robota-sdk/agent-core';\n\nimport { 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 executionId?: 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\n/** Best-effort total token usage of a finished subagent session; never throws. */\nfunction readSubagentUsage(\n session: ReturnType<typeof createSubagentSession>,\n): ReturnType<typeof sumHistoryUsage> {\n try {\n return sumHistoryUsage(session.getFullHistory());\n } catch {\n // allow-fallback: usage capture is auxiliary — a failure to read history must not fail the subagent run\n return undefined;\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 // ANALYTICS-001 (Phase 2): capture the subagent's total token usage so the parent log can\n // attribute it to this agent as a source. Best-effort — never let usage capture fail the run.\n const usage = readSubagentUsage(session);\n return { jobId: job.jobId, output, ...(usage ? { usage } : {}) };\n }),\n cancel: () => {\n session.abort();\n return Promise.resolve();\n },\n };\n },\n };\n}\n","/**\n * AgentTool — spawn a subagent 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 * subagent 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 stringifyParallelSubagentsDisabled,\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 { IToolExecutionContext } from '@robota-sdk/agent-core';\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\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 /** PRESET-016 — runtime gate; when present and returns false, subagent dispatch is refused. */\n isParallelSubagentsEnabled?: () => boolean;\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 toolCallId?: string,\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 ...(toolCallId ? { toolCallId } : {}),\n }),\n };\n}\n\nasync function runManagedAgent(\n args: TAgentArgs,\n deps: IAgentToolDeps,\n manager: ISubagentManager,\n toolCallId?: string,\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(\n createSpawnRequest(singleArgs, agentType, agentDef, deps, undefined, toolCallId),\n );\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 AgentSchema,\n async (params, context) => {\n const args = params as TAgentArgs;\n const toolCallId = (context as IToolExecutionContext | undefined)?.executionId;\n // PRESET-016 runtime gate: refuse dispatch without spawning anything when the active preset\n // has disabled parallel subagents on this (already-constructed) session.\n if (deps.isParallelSubagentsEnabled !== undefined && !deps.isParallelSubagentsEnabled()) {\n return stringifyParallelSubagentsDisabled();\n }\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 toolCallId,\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 toolCallId,\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 { createSourceUsageSummaryEntry } from './interactive-session-execution.js';\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 IBackgroundTaskManager,\n IExecutionDetailCursor,\n IExecutionDetailPage,\n TBackgroundJobGroupEvent,\n TExecutionWorkspaceUpdateCause,\n} from '../background-tasks/index.js';\nimport type { IHistoryEntry } from '@robota-sdk/agent-core';\nimport type {\n IBackgroundTaskInput,\n IBackgroundTaskListFilter,\n IBackgroundTaskLogCursor,\n IBackgroundTaskLogPage,\n IBackgroundTaskState,\n TBackgroundTaskEvent,\n} from '@robota-sdk/agent-interface-transport';\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 // FLOW-002: invoked when a background task fires a wake carrying an agent instruction.\n private readonly onWake?: (instruction: string, taskId: string) => void,\n // FLOW-003: append a user-visible system note (e.g. a missed-wake notice) to history.\n private readonly appendSystemNote?: (message: string) => void,\n // ANALYTICS-001 (Phase 2): append a structured history entry (a source-attributed usage summary).\n private readonly appendHistoryEntry?: (entry: IHistoryEntry) => 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 // FLOW-002: a wake carrying an instruction re-enters the agent loop with a non-user turn.\n if (event.type === 'background_task_waking' && event.instruction !== undefined) {\n this.onWake?.(event.instruction, event.taskId);\n }\n });\n this.reArmRestoredSchedules(manager);\n }\n\n /**\n * FLOW-003: re-spawn restored sleeping scheduled wakes so they fire again after a resume,\n * and surface a one-time note for any whose fire time elapsed while the CLI was closed.\n */\n private reArmRestoredSchedules(manager: IBackgroundTaskManager): void {\n const nowMs = Date.now();\n for (const task of this.backgroundTasks) {\n if (task.kind !== 'scheduled' || task.status !== 'sleeping' || !task.schedule) continue;\n if (task.nextFireAt !== undefined && new Date(task.nextFireAt).getTime() < nowMs) {\n this.appendSystemNote?.(\n `Missed scheduled wake \"${task.label}\" (was due ${task.nextFireAt} while the session was closed); re-arming.`,\n );\n }\n void manager.spawn({\n kind: 'scheduled',\n cronExpression: task.schedule.cronExpression,\n label: task.label,\n mode: task.mode,\n parentSessionId: task.parentSessionId,\n depth: task.depth,\n cwd: task.cwd,\n ...(task.schedule.agentInstruction !== undefined\n ? { agentInstruction: task.schedule.agentInstruction }\n : {}),\n ...(task.schedule.command !== undefined ? { command: task.schedule.command } : {}),\n ...(task.schedule.shell !== undefined ? { shell: task.schedule.shell } : {}),\n ...(task.schedule.env !== undefined ? { env: { ...task.schedule.env } } : {}),\n });\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.recordCompletedTaskUsage(event);\n this.persistSession();\n this.onChanged('background_task', getTaskEventEntryId(event));\n }\n\n /**\n * ANALYTICS-001 (Phase 2): when a background agent task completes with token usage, append a\n * source-attributed usage-summary to the parent history so the usage report attributes those tokens\n * to that task (not the main thread).\n */\n private recordCompletedTaskUsage(event: TBackgroundTaskEvent): void {\n if (event.type !== 'background_task_completed') return;\n const usage = event.task.result?.usage;\n if (!usage || usage.totalTokens <= 0) return;\n this.appendHistoryEntry?.(\n createSourceUsageSummaryEntry(usage, {\n scope: 'background',\n id: event.task.id,\n label: event.task.agentType ?? event.task.label,\n }),\n );\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 { TCommandInvocationSource } from '../commands/index.js';\nimport type { ISubagentJobResult } from '../subagents/index.js';\nimport type {\n ISubagentJobState,\n TBackgroundTaskIsolation,\n} from '@robota-sdk/agent-interface-transport';\nimport type { Session } from '@robota-sdk/agent-session';\n\n/** Retrieve agent tool deps or throw. */\nfunction 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. */\nfunction 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 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 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 } from '../subagents/index.js';\nimport type { IHistoryEntry, TUniversalMessage, IContextWindowState } from '@robota-sdk/agent-core';\nimport type {\n IBackgroundTaskInput,\n IBackgroundTaskListFilter,\n IBackgroundTaskLogCursor,\n IBackgroundTaskLogPage,\n IBackgroundTaskState,\n ISubagentJobState,\n} from '@robota-sdk/agent-interface-transport';\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<{\n name: string;\n displayName?: string;\n description: string;\n example?: string;\n }> {\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 async spawnScheduledWake(input: {\n label: string;\n cronExpression: string;\n agentInstruction: string;\n }): Promise<IBackgroundTaskState> {\n await this.ensureInitialized();\n return this.bgTracker.getManagerOrThrow().spawn({\n kind: 'scheduled',\n label: input.label,\n mode: 'background',\n parentSessionId: this.getSessionOrThrow().getSessionId(),\n depth: 0,\n cwd: this.getCwd(),\n cronExpression: input.cronExpression,\n agentInstruction: input.agentInstruction,\n });\n }\n\n async spawnMonitorWake(input: {\n label: string;\n command: string;\n matchPattern: string;\n agentInstruction: string;\n }): Promise<IBackgroundTaskState> {\n await this.ensureInitialized();\n return this.bgTracker.getManagerOrThrow().spawn({\n kind: 'process',\n label: input.label,\n mode: 'background',\n parentSessionId: this.getSessionOrThrow().getSessionId(),\n depth: 0,\n cwd: this.getCwd(),\n command: input.command,\n matchPattern: input.matchPattern,\n agentInstruction: input.agentInstruction,\n });\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","/**\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. */\nconst TOOL_ARG_DISPLAY_MAX = 80;\nconst TAIL_KEEP = 30;\n/** Max completed tools to keep in the activeTools array during a single response. */\nconst 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 executionId?: 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. */\nfunction 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; executionId?: string },\n): IToolState {\n const firstArg = extractFirstArg(event.toolArgs);\n const toolState: IToolState = {\n toolName: event.toolName,\n firstArg,\n isRunning: true,\n ...(event.executionId ? { executionId: event.executionId } : {}),\n };\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","import {\n AuthenticationError,\n RateLimitError,\n NetworkError,\n ProviderError,\n} from '@robota-sdk/agent-core';\n\nconst HTTP_PATTERNS: Array<{ pattern: RegExp; message: string }> = [\n {\n pattern: /\\b401\\b|invalid.*api.?key|authentication.*fail|unauthorized/i,\n message:\n 'Invalid API key. Run `/provider` to reconfigure, or check your settings file (~/.robota/settings.json).',\n },\n {\n pattern: /\\b403\\b|permission.*denied|forbidden/i,\n message:\n 'Access denied. Your API key may lack permission for this model. Check your provider plan or run `/provider` to switch accounts.',\n },\n {\n pattern: /\\b429\\b|rate.?limit|too many requests|quota.*exceeded/i,\n message:\n 'Rate limit reached. Wait a moment and try again. Consider switching to a different model with `/model`.',\n },\n {\n pattern: /\\b500\\b|internal server error/i,\n message: 'The AI provider returned an internal error. This is usually temporary — try again.',\n },\n {\n pattern: /\\b503\\b|service.*unavailable|overloaded/i,\n message:\n 'The AI provider is temporarily unavailable or overloaded. Try again in a few seconds.',\n },\n {\n pattern: /\\b502\\b|bad gateway/i,\n message: 'The AI provider gateway is unreachable. Check your network or try again shortly.',\n },\n {\n pattern: /\\btimeout\\b|timed.?out|ETIMEDOUT/i,\n message:\n 'The request timed out. Check your internet connection, or try a shorter prompt to reduce response time.',\n },\n {\n pattern: /ENOTFOUND|ECONNREFUSED|ECONNRESET|network.*error|fetch.*fail/i,\n message:\n 'Network connection failed. Check your internet connection and verify your provider URL in settings.',\n },\n];\n\n/**\n * Maps a raw provider/network error to a user-friendly message with resolution hints.\n * Falls back to the original message if no pattern matches.\n */\nexport function humanizeApiError(error: Error): string {\n if (error instanceof AuthenticationError) {\n return 'Invalid API key. Run `/provider` to reconfigure, or check your settings file (~/.robota/settings.json).';\n }\n if (error instanceof RateLimitError) {\n const hint = error.retryAfter ? ` (retry after ${error.retryAfter}s)` : '';\n return `Rate limit reached${hint}. Wait a moment and try again. Consider switching to a different model with \\`/model\\`.`;\n }\n if (error instanceof NetworkError) {\n return 'Network connection failed. Check your internet connection and verify your provider URL in settings.';\n }\n if (error instanceof ProviderError && error.originalError) {\n return humanizeApiError(error.originalError);\n }\n\n const msg = error.message;\n for (const { pattern, message } of HTTP_PATTERNS) {\n if (pattern.test(msg)) {\n return message;\n }\n }\n\n return msg;\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';\nimport { humanizeApiError } from '../utils/error-humanizer.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 /** Accumulated streamed text of the in-flight turn (ERR-001: preserved on error). */\n getStreamingText: () => string;\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 // ERR-001: a mid-stream failure must not evaporate the partial answer — commit it\n // to history marked interrupted before clearing the stream buffer.\n const partial = ctx.getStreamingText();\n ctx.clearStreaming();\n if (partial.trim().length > 0) {\n const partialMessage = createAssistantMessage(partial);\n partialMessage.state = 'interrupted';\n history.push(messageToHistoryEntry(partialMessage));\n }\n const errObj = err instanceof Error ? err : new Error(String(err));\n const errMsg = humanizeApiError(errObj);\n // metadata.kind lets transports render a styled error block instead of a plain system note.\n history.push(\n messageToHistoryEntry(\n createSystemMessage(`Error: ${errMsg}`, { metadata: { kind: 'error' } }),\n ),\n );\n ctx.onError(errObj);\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';\nimport { humanizeApiError } from '../utils/error-humanizer.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 { TTurnSource } from '@robota-sdk/agent-interface-transport';\nimport type { ICompactEvent } from '@robota-sdk/agent-interface-transport';\nimport type { Session } from '@robota-sdk/agent-session';\n\nexport type { TTurnSource };\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}\n\n/** Options threaded through submit/executePrompt for non-user turns (FLOW-002). */\nexport interface ITurnOptions {\n turnSource?: TTurnSource;\n /** When set, the in-flight wake for this background task id is cleared on turn completion. */\n wakeTaskId?: string;\n}\n\n/** A submit callback that optionally carries turn options (default = user turn). */\nexport type TSubmitFn = (\n prompt: string,\n displayInput?: string,\n rawInput?: string,\n options?: ITurnOptions,\n) => Promise<void>;\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 pendingTurnOptions: ITurnOptions = {};\n shuttingDown = false;\n\n /** FLOW-002: background task ids with an in-flight wake turn (coalesces duplicate wakes). */\n readonly wakeTaskIds = new Set<string>();\n\n constructor(\n private readonly histTracker: SessionHistoryTracker,\n private readonly skillRouter: SessionSkillRouter,\n private readonly callbacks: IExecutionControllerCallbacks,\n ) {}\n\n clearPendingQueue(): void {\n // CORE-024 (RUNTIME-19): a queued wake that is dropped here (abort/shutdown/re-queue) must\n // release its wake-tracking id — otherwise the `wakeTaskIds` gate rejects every future wake\n // for that task forever, since the id is only cleared on a wake that runs to a completed turn.\n if (this.pendingTurnOptions.wakeTaskId !== undefined) {\n this.wakeTaskIds.delete(this.pendingTurnOptions.wakeTaskId);\n }\n this.pendingPrompt = null;\n this.pendingDisplayInput = undefined;\n this.pendingRawInput = undefined;\n this.pendingTurnOptions = {};\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 executionId?: 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: TSubmitFn): void {\n if (!this.shuttingDown && this.pendingPrompt) {\n const queued = this.pendingPrompt;\n const queuedDisplay = this.pendingDisplayInput;\n const queuedRaw = this.pendingRawInput;\n const queuedOptions = this.pendingTurnOptions;\n this.clearPendingQueue();\n setTimeout(() => void submit(queued, queuedDisplay, queuedRaw, queuedOptions), 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: TSubmitFn,\n turnOptions: ITurnOptions = {},\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 // FLOW-002: surface the turn origin so consumers (hooks, TUI) can distinguish a human\n // prompt from an agent-wakeup re-entry.\n this.callbacks.emit('turn_source', turnOptions.turnSource ?? 'user');\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.listInjectionContextReferences(),\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 getStreamingText: () => this.streamingText,\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 // FLOW-002: the wake for this task id is no longer in flight; allow future wakes to inject.\n if (turnOptions.wakeTaskId !== undefined) this.wakeTaskIds.delete(turnOptions.wakeTaskId);\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 // allow-fallback: fork-skill errors must not crash the main execution thread\n const error = err instanceof Error ? err : new Error(String(err));\n this.histTracker.append(\n messageToHistoryEntry(createSystemMessage(`Error: ${humanizeApiError(error)}`)),\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\nfunction 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 { relative } from 'node:path';\n\nimport {\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 { IContextFileEntry } from '../context/context-file-tracker.js';\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\nexport function createSystemContextReferenceItems(\n entries: readonly IContextFileEntry[],\n cwd: string,\n): IContextReferenceItem[] {\n const now = new Date().toISOString();\n return entries.map((entry) => {\n const relativePath = relative(cwd, entry.filePath);\n return {\n id: `system:${relativePath}`,\n sourcePath: entry.filePath,\n relativePath,\n originalReference: relativePath,\n loadType: 'system' as const,\n status: 'active' as const,\n byteLength: Buffer.byteLength(entry.content, 'utf-8'),\n loadedAt: now,\n lastUsedAt: now,\n };\n });\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 onboarded: string;\n} {\n const base = join(homedir(), '.robota');\n return {\n settings: join(base, 'settings.json'),\n sessions: join(base, 'sessions'),\n onboarded: join(base, 'onboarded'),\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// Skill-activation event contracts SSOT relocated to @robota-sdk/agent-interface-transport (DATA-001).\nimport type {\n ISkillActivationEvent,\n TSkillActivationInvocation,\n TSkillActivationSource,\n TSkillActivationMode,\n TSkillActivationStatus,\n} from '@robota-sdk/agent-interface-transport';\n\nexport type {\n TSkillActivationSource,\n TSkillActivationInvocation,\n TSkillActivationMode,\n TSkillActivationStatus,\n ISkillActivationEvent,\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\nfunction getSkillActivationSource(skill: ICommand): TSkillActivationSource {\n return skill.source === 'plugin' ? 'plugin' : 'skill';\n}\n\nfunction 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","import type { IMemoryEvent } from './automatic-memory-types.js';\n\n/** Memory event types that produce a visible transcript notice. */\nexport const VISIBLE_MEMORY_EVENT_TYPES: ReadonlySet<IMemoryEvent['type']> = new Set([\n 'memory_candidate_saved',\n 'memory_candidate_approved',\n 'memory_candidate_rejected',\n 'memory_retrieved',\n]);\n\n/** Format a memory event into the user-facing transcript message. */\nexport function formatMemoryEventMessage(event: IMemoryEvent): string {\n const topic = event.topic ? `: ${event.topic}` : '';\n switch (event.type) {\n case 'memory_candidate_saved':\n return `Memory saved${topic}`;\n case 'memory_candidate_approved':\n return `Memory approved${topic}`;\n case 'memory_candidate_rejected':\n return `Memory rejected${topic}${event.reason ? ` (${event.reason})` : ''}`;\n case 'memory_retrieved':\n return `Memory recalled${topic}`;\n case 'memory_candidate_extracted':\n return `Memory candidate extracted${topic}`;\n case 'memory_candidate_queued':\n return `Memory candidate queued${topic}`;\n case 'memory_candidate_skipped':\n return `Memory candidate skipped${topic}${event.reason ? ` (${event.reason})` : ''}`;\n }\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 createSystemContextReferenceItems,\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';\nimport {\n VISIBLE_MEMORY_EVENT_TYPES,\n formatMemoryEventMessage,\n} from '../memory/memory-event-format.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 { IContextFileEntry } from '../context/context-file-tracker.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, TUniversalValue } 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 systemContextReferences: 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 private readonly emitMemoryEvent: (event: IMemoryEvent) => 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 if (VISIBLE_MEMORY_EVENT_TYPES.has(event.type)) {\n this.history.push({\n id: randomUUID(),\n timestamp: new Date(event.at),\n category: 'event',\n type: 'memory-event',\n data: {\n ...(event as unknown as Record<string, TUniversalValue>),\n message: formatMemoryEventMessage(event),\n },\n });\n }\n this.emitMemoryEvent(event);\n this.persistSession();\n }\n\n recordSystemContextFiles(entries: readonly IContextFileEntry[]): void {\n this.systemContextReferences = createSystemContextReferenceItems(entries, this.cwd);\n }\n\n listContextReferences(): IContextReferenceItem[] {\n return [...this.systemContextReferences, ...this.contextReferences];\n }\n\n listInjectionContextReferences(): 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 TBackgroundJobGroupEvent,\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 { IGoalState } from '@robota-sdk/agent-interface-transport';\nimport type {\n IBackgroundTaskState,\n TBackgroundTaskEvent,\n TBackgroundTaskStatus,\n} from '@robota-sdk/agent-interface-transport';\nimport type { Session } from '@robota-sdk/agent-session';\n\n/** Inject a saved message into a session, preserving all fields including toolCalls. */\nexport function injectSavedMessage(session: Session, msg: TUniversalMessage): void {\n session.injectRawMessage(msg);\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 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 goal: IGoalState | 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 goal: 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 // CLI-073: forks restore the conversation too — the SPEC promises\n // \"new session (fresh UUID) but restores context\"; only the session id is new.\n if (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 goal: record.goal,\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 // FLOW-003: a sleeping scheduled wake that carries a reconstructable schedule is re-armed\n // (re-spawned) by the background tracker on subscribe — keep it as-is rather than failing it.\n if (isReArmableSchedule(task)) 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\n/** FLOW-003: a restored sleeping scheduled task that can be re-armed from its persisted schedule. */\nfunction isReArmableSchedule(task: IBackgroundTaskState): boolean {\n return task.kind === 'scheduled' && task.status === 'sleeping' && task.schedule !== undefined;\n}\n","import { runHooks } from '@robota-sdk/agent-core';\n\nimport type {\n IHookInput,\n IHookTypeExecutor,\n THooksConfig,\n THookEvent,\n} from '@robota-sdk/agent-core';\nimport type { TBackgroundTaskEvent } from '@robota-sdk/agent-interface-transport';\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 createAskUserQuestionTool,\n createShellTool,\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 'Shell — execute host shell commands (OS-aware: bash/PowerShell)',\n 'Bash — alias of Shell (model-familiar name)',\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 'AskUserQuestion — ask the user structured questions (options/multi-select/free text) mid-task',\n];\n\n/**\n * Create the default set of CLI tools.\n * Returns the standard tools as IToolWithEventService[].\n */\nexport interface ICreateDefaultToolsOptions {\n sandboxClient?: ISandboxClient;\n cwd?: string;\n}\n\nexport function createDefaultTools(\n options: ICreateDefaultToolsOptions = {},\n): IToolWithEventService[] {\n return [\n createShellTool(options) as IToolWithEventService,\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 createAskUserQuestionTool() 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 { IProjectInfo } from './project-detector.js';\nimport type { ISystemPromptSection } from './system-prompt-types.js';\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { TPermissionMode } from '@robota-sdk/agent-core';\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\n/**\n * PRESET-003: a preset persona is a normal section with a declared priority, not a\n * hardcoded slot. Priority `5` sits in the top band (5 < AGENTS.md=10) so the persona\n * establishes identity/behaviour before project instructions — the position is decided\n * by `composeSystemPrompt`'s priority sort, never by array order.\n */\nexport function createPersonaSection(persona: string): ISystemPromptSection {\n return createSection('preset-persona', undefined, 5, persona, 'persona');\n}\n\n/**\n * PRESET-017: a concise verify-before-done directive injected when a preset enables\n * `selfVerification`. The content must stay English, brief, and avoid heavy emphasis cues.\n */\nconst SELF_VERIFICATION_CONTENT =\n \"Before you report a task complete, verify your work against this session's tool \" +\n 'results — re-run the relevant checks and confirm the outcome matches what was asked. ' +\n 'If something is not yet verified, say so plainly rather than implying it is done.';\n\n/**\n * PRESET-017: when a preset enables selfVerification, inject a concise verify-before-done\n * section as a normal priority-sorted section (priority 6 = just after persona=5, before\n * AGENTS.md=10), never a hardcoded slot.\n */\nexport function createSelfVerificationSection(): ISystemPromptSection {\n return createSection(\n 'preset-self-verification',\n undefined,\n 6,\n SELF_VERIFICATION_CONTENT,\n 'self-verification',\n );\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\n/**\n * CLI-072: the prompt names the ACTIVE permission mode — the same value the\n * permission gate enforces — so the model's explanations can never quote a\n * stale trust-level label.\n */\nexport function createPermissionSection(permissionMode: TPermissionMode): ISystemPromptSection {\n return createSection(\n 'permission-mode',\n 'Permission Mode',\n 50,\n `- **Permission mode:** ${permissionMode}`,\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 createPersonaSection,\n createProjectMemorySection,\n createProjectSection,\n createResponseLanguageSection,\n createSelfVerificationSection,\n createTaskContextSection,\n createToolDescriptionSection,\n createWorkingDirectorySection,\n} from './system-prompt-section-providers.js';\n\nimport type { IProjectInfo } from './project-detector.js';\nimport type { ISystemPromptSection } from './system-prompt-types.js';\nimport type { ICapabilityDescriptor } from '../capabilities/types.js';\nimport type { TPermissionMode } from '@robota-sdk/agent-core';\n\nexport interface ISystemPromptParams {\n /**\n * Preset persona block (portable personality/behaviour). When set and non-blank it is\n * composed as a `source: 'persona'` section with priority 5; empty/undefined adds no section.\n */\n persona?: string;\n /**\n * PRESET-017: when true, a concise verify-before-done directive is composed as a\n * `source: 'self-verification'` section with priority 6; false/undefined adds no section.\n */\n selfVerification?: boolean;\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 permission mode — the value the permission gate enforces */\n permissionMode: TPermissionMode;\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(\n sections,\n params.persona !== undefined && params.persona.trim().length > 0\n ? createPersonaSection(params.persona)\n : undefined,\n );\n appendOptionalSection(\n sections,\n params.selfVerification === true ? createSelfVerificationSection() : undefined,\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.permissionMode));\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 } from '../background-tasks/index.js';\nimport type { TBackgroundPrimitive } from '@robota-sdk/agent-interface-transport';\n\nconst DEFAULT_PROCESS_TIMEOUT_MS = 120_000;\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 BackgroundProcessSchema,\n async (params) => startBackgroundProcess(params as TBackgroundProcessArgs, deps),\n );\n}\n","import { TRUST_TO_MODE } from '@robota-sdk/agent-core';\nimport { 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 } 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 { TBackgroundTaskEvent } from '@robota-sdk/agent-interface-transport';\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 // PRESET-004: a preset opting into parallel subagents activates the agent runtime\n // (subagent/background dispatch) exactly like an explicit enableAgentRuntime.\n if (options.enableAgentRuntime || options.enableParallelSubagents) {\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: (\n agentsMd: string,\n claudeMd: string,\n overrides?: { persona?: string; selfVerification?: boolean },\n ) => string;\n}\n\n/**\n * Build the static system-prompt params shared by the initial build and every rebuild. Persona\n * (PRESET-014) and selfVerification (PRESET-017) are composed separately per-build so their mutable\n * closure values always take precedence over these static params.\n */\nfunction buildStaticPromptParams(\n options: ICreateSessionOptions,\n cwd: string,\n resolvedToolDescriptions: string[],\n modelVisibleSkills: Array<{\n name: string;\n description: string;\n disableModelInvocation?: boolean;\n }>,\n agentDefinitions: IAgentDefinition[],\n): Omit<ISystemPromptParams, 'persona' | 'selfVerification'> {\n return {\n agentsMd: options.context.agentsMd,\n claudeMd: options.context.claudeMd,\n memoryMd: options.context.memoryMd,\n taskContext: options.context.taskContext,\n toolDescriptions: resolvedToolDescriptions,\n // CLI-072: the prompt names the mode the gate enforces — same resolution\n // as agent-session (explicit mode, else trust-level mapping, else default).\n permissionMode:\n options.permissionMode ?? TRUST_TO_MODE[options.config.defaultTrustLevel] ?? 'default',\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}\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 // PRESET-014: persona is mutable for the lifetime of this closure. A live preset switch can\n // re-apply a new persona mid-session (via `rebuildSystemMessage(..., { persona })`); later\n // staleness rebuilds (no override) must keep the most recently applied persona.\n let currentPersona = options.persona;\n\n // PRESET-017: selfVerification is mutable for the lifetime of this closure, mirroring persona. A\n // live preset switch can toggle the verify-before-done section mid-session (via\n // `rebuildSystemMessage(..., { selfVerification })`); later staleness rebuilds (no override) must\n // keep the most recently applied value.\n let currentSelfVerification = options.selfVerification;\n\n // Persona/selfVerification are composed per-build (initial + each rebuild) so the mutable closure\n // values always win; they are therefore excluded from these static params.\n const staticPromptParams = buildStaticPromptParams(\n options,\n cwd,\n resolvedToolDescriptions,\n modelVisibleSkills,\n agentDefinitions,\n );\n const systemMessage = buildPrompt({\n ...staticPromptParams,\n ...(currentPersona !== undefined ? { persona: currentPersona } : {}),\n ...(currentSelfVerification !== undefined ? { selfVerification: currentSelfVerification } : {}),\n });\n const finalSystemMessage = options.appendSystemPrompt\n ? `${systemMessage}\\n\\n${options.appendSystemPrompt}`\n : systemMessage;\n\n const rebuildSystemMessage = (\n newAgentsMd: string,\n newClaudeMd: string,\n overrides?: { persona?: string; selfVerification?: boolean },\n ): string => {\n // PRESET-014: a persona override mutates the retained persona so subsequent rebuilds\n // (e.g. staleness refresh, which passes no override) keep the latest applied persona.\n if (overrides?.persona !== undefined) {\n currentPersona = overrides.persona;\n }\n // PRESET-017: a selfVerification override mutates the retained flag the same way, so later\n // override-less rebuilds keep the latest applied value.\n if (overrides?.selfVerification !== undefined) {\n currentSelfVerification = overrides.selfVerification;\n }\n const rebuilt = buildPrompt({\n ...staticPromptParams,\n ...(currentPersona !== undefined ? { persona: currentPersona } : {}),\n ...(currentSelfVerification !== undefined\n ? { selfVerification: currentSelfVerification }\n : {}),\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 // PRESET-016: wire the runtime gate to the session's live flag so a preset switch can\n // enable/disable subagent dispatch on this already-constructed session.\n if (agentToolDeps) {\n agentToolDeps.isParallelSubagentsEnabled = () => session.getParallelSubagentsEnabled();\n }\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 const correlationFields: Record<string, string> = {};\n if (event.type === 'background_task_created') {\n correlationFields['taskId'] = event.task.id;\n const originToolCallId = event.task.metadata?.['executionOriginToolCallId'];\n if (typeof originToolCallId === 'string') {\n correlationFields['originToolCallId'] = originToolCallId;\n }\n }\n logger.log(sessionId, 'background_task_event', {\n backgroundEventType: event.type,\n backgroundEvent: event,\n ...correlationFields,\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 * CLI-069: an EXISTING settings file that fails to parse is an error condition,\n * never silently equated with a missing file (forbidden-fallback class). Thrown\n * by the settings readers; session start propagates it (fail fast, exit 1),\n * reporting consumers (e.g. diagnose) catch it and present it as a finding.\n */\nexport class SettingsParseError extends Error {\n readonly filePath: string;\n\n constructor(filePath: string, parseMessage: string) {\n super(\n `Settings file ${filePath} contains invalid JSON: ${parseMessage}. ` +\n 'Fix or delete the file, or run robota diagnose.',\n );\n this.name = 'SettingsParseError';\n this.filePath = filePath;\n }\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\n\nimport { SettingsParseError } from './settings-parse-error.js';\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\n/**\n * CLI-069: missing file → empty defaults (non-error); an EXISTING file that\n * fails to parse throws SettingsParseError — no warn-and-continue masking.\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 (error) {\n // allow-fallback: rethrown as typed SettingsParseError — fail-fast, not a fallback\n throw new SettingsParseError(path, error instanceof Error ? error.message : String(error));\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","/**\n * GOAL-001: the structured completion-signal tool.\n *\n * While an autonomous goal is active the agent reports its assessment by calling\n * `report_goal_status({ status, reason })`. The {@link GoalController} reads this call\n * deterministically from the completed turn's tool summaries — no fragile prose parsing. The\n * tool itself is stateless: it validates the arguments and acknowledges; the loop decision is\n * owned by the controller.\n */\n\nimport { createZodFunctionTool } from '@robota-sdk/agent-tools';\nimport { z } from 'zod';\n\nimport type { IToolWithEventService } from '@robota-sdk/agent-core';\n\n/** Tool name the agent calls to report goal status. Vendor-neutral, generic. */\nexport const GOAL_SIGNAL_TOOL_NAME = 'report_goal_status';\n\nconst goalStatusSchema = z.object({\n status: z\n .enum(['continue', 'satisfied'])\n .describe('\"satisfied\" when the assigned goal is fully achieved; otherwise \"continue\".'),\n reason: z\n .string()\n .describe('A short justification for the status — what was achieved or what remains.'),\n});\n\n/**\n * Create the goal completion-signal tool. Included in the session tool set only when goal\n * pursuit is enabled (interactive sessions). The agent must call it only while pursuing an\n * assigned goal; outside a goal it is a harmless no-op acknowledgement.\n */\nexport function createGoalStatusTool(): IToolWithEventService {\n return createZodFunctionTool(\n GOAL_SIGNAL_TOOL_NAME,\n 'Report progress toward the currently assigned autonomous goal. Call this only when you have ' +\n 'an assigned goal: use status \"satisfied\" once it is fully achieved, or \"continue\" with the ' +\n 'remaining work. Do not call it when no goal has been assigned.',\n goalStatusSchema,\n async (parameters) => {\n const status = parameters['status'] === 'satisfied' ? 'satisfied' : 'continue';\n return { acknowledged: true, status };\n },\n ) as unknown as IToolWithEventService;\n}\n","/**\n * GOAL-001: prompt composition for autonomous objective pursuit.\n *\n * These prompts inject the objective into each goal-driven turn and instruct the agent to use the\n * {@link GOAL_SIGNAL_TOOL_NAME} completion-signal tool. They are deliberately vendor-neutral.\n */\n\nimport { GOAL_SIGNAL_TOOL_NAME } from './goal-status-tool.js';\n\nimport type { IGoalState } from '@robota-sdk/agent-interface-transport';\n\nconst SIGNAL_INSTRUCTION =\n `When you have made as much progress as you can this turn, call \\`${GOAL_SIGNAL_TOOL_NAME}\\`: ` +\n `use status \"satisfied\" once the goal is fully achieved, or status \"continue\" with a short ` +\n `reason describing the remaining work. Do the actual work with your tools first; the signal ` +\n `only reports your assessment.`;\n\n/** The prompt that kicks off goal pursuit (first iteration). */\nexport function buildGoalStartPrompt(objective: string): string {\n return [\n `You have been assigned an autonomous goal to pursue across multiple turns:`,\n ``,\n `GOAL: ${objective}`,\n ``,\n `Work toward this goal now. ${SIGNAL_INSTRUCTION}`,\n ].join('\\n');\n}\n\n/** The continuation prompt for each subsequent goal-driven turn. */\nexport function buildGoalContinuationPrompt(goal: IGoalState): string {\n const last = goal.progress[goal.progress.length - 1];\n const remaining = last?.reason ? `\\nMost recent assessment: ${last.reason}` : '';\n return [\n `Continue pursuing the assigned goal (iteration ${goal.iterations + 1} of at most ${goal.maxIterations}).`,\n ``,\n `GOAL: ${goal.objective}${remaining}`,\n ``,\n `Keep going from where you left off. ${SIGNAL_INSTRUCTION}`,\n ].join('\\n');\n}\n","/**\n * GOAL-001: autonomous objective-pursuit controller.\n *\n * Pure decision logic (no session/IO dependency) so it is unit-testable in isolation. It owns the\n * goal state machine: it reads the deterministic completion signal from a finished turn, advances\n * the goal, and decides whether to continue (with a continuation prompt) or stop (with a reason).\n *\n * Stop conditions, all mandatory: explicit `satisfied` signal, max-iterations (turn budget),\n * no-progress convergence guard (consecutive idle turns), and user cancellation.\n */\n\nimport { buildGoalStartPrompt, buildGoalContinuationPrompt } from './goal-prompts.js';\nimport { GOAL_SIGNAL_TOOL_NAME } from './goal-status-tool.js';\n\nimport type {\n IExecutionResult,\n IGoalState,\n IToolSummary,\n TGoalStopReason,\n} from '@robota-sdk/agent-interface-transport';\n\nexport const DEFAULT_GOAL_MAX_ITERATIONS = 25;\nexport const DEFAULT_GOAL_NO_PROGRESS_LIMIT = 2;\n\n/** Parsed structured completion signal emitted by the agent via the goal-status tool. */\nexport interface IGoalSignal {\n status: 'continue' | 'satisfied';\n reason: string;\n}\n\n/** The controller's decision after a goal-driven turn completes. */\nexport type TGoalDecision =\n | { action: 'continue'; prompt: string; goal: IGoalState }\n | { action: 'stop'; reason: TGoalStopReason; goal: IGoalState };\n\n/** Options for {@link GoalController.start}. */\nexport interface IGoalStartOptions {\n maxIterations?: number;\n noProgressLimit?: number;\n}\n\n/** Injected seams so the controller stays deterministic and testable. */\nexport interface IGoalControllerDeps {\n now: () => string;\n createId: () => string;\n}\n\nconst defaultDeps: IGoalControllerDeps = {\n now: () => new Date().toISOString(),\n createId: () => `goal_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\n};\n\nfunction parseSignalArgs(args: string): IGoalSignal | null {\n let parsed: { status?: unknown; reason?: unknown };\n try {\n parsed = JSON.parse(args) as { status?: unknown; reason?: unknown };\n } catch {\n // allow-fallback: malformed args → treat as \"no signal\" so the loop falls through to its progress/iteration guards\n return null;\n }\n const status = parsed.status === 'satisfied' ? 'satisfied' : 'continue';\n const reason = typeof parsed.reason === 'string' ? parsed.reason : '';\n return { status, reason };\n}\n\n/**\n * Read the structured completion signal from a finished turn's tool summaries. Returns the LAST\n * `report_goal_status` call's validated payload, or `null` when the agent did not signal. The\n * payload is schema-validated at the tool layer, so this is deterministic — never prose parsing.\n */\nexport function extractGoalSignal(toolSummaries: readonly IToolSummary[]): IGoalSignal | null {\n for (let i = toolSummaries.length - 1; i >= 0; i--) {\n const summary = toolSummaries[i];\n if (!summary || summary.name !== GOAL_SIGNAL_TOOL_NAME) continue;\n return parseSignalArgs(summary.args);\n }\n return null;\n}\n\nfunction countNonSignalToolCalls(toolSummaries: readonly IToolSummary[]): number {\n return toolSummaries.filter((s) => s.name !== GOAL_SIGNAL_TOOL_NAME).length;\n}\n\nexport class GoalController {\n private goal: IGoalState | null = null;\n private consecutiveIdleTurns = 0;\n private noProgressLimit = DEFAULT_GOAL_NO_PROGRESS_LIMIT;\n\n constructor(private readonly deps: IGoalControllerDeps = defaultDeps) {}\n\n getState(): IGoalState | null {\n return this.goal;\n }\n\n isActive(): boolean {\n return this.goal?.status === 'active';\n }\n\n /**\n * Begin pursuing a new goal. Throws on an empty objective. Returns the seeded state and the\n * first-turn prompt the caller should submit.\n */\n start(objective: string, options: IGoalStartOptions = {}): { goal: IGoalState; prompt: string } {\n const trimmed = objective.trim();\n if (trimmed.length === 0) {\n throw new Error('A goal objective must be a non-empty string.');\n }\n const maxIterations =\n options.maxIterations && options.maxIterations > 0\n ? Math.floor(options.maxIterations)\n : DEFAULT_GOAL_MAX_ITERATIONS;\n this.noProgressLimit =\n options.noProgressLimit && options.noProgressLimit > 0\n ? Math.floor(options.noProgressLimit)\n : DEFAULT_GOAL_NO_PROGRESS_LIMIT;\n this.consecutiveIdleTurns = 0;\n this.goal = {\n id: this.deps.createId(),\n objective: trimmed,\n status: 'active',\n iterations: 0,\n maxIterations,\n startedAt: this.deps.now(),\n progress: [],\n };\n return { goal: this.goal, prompt: buildGoalStartPrompt(trimmed) };\n }\n\n /** Restore a persisted goal on resume. Only an `active` goal resumes pursuit. */\n restore(goal: IGoalState, noProgressLimit = DEFAULT_GOAL_NO_PROGRESS_LIMIT): void {\n this.goal = goal.status === 'active' ? goal : null;\n this.noProgressLimit = noProgressLimit;\n this.consecutiveIdleTurns = 0;\n }\n\n /** User-requested cancellation. Returns the stopped state, or `null` when no goal is active. */\n cancel(): IGoalState | null {\n if (!this.goal || this.goal.status !== 'active') return null;\n this.goal = { ...this.goal, status: 'stopped', stopReason: 'cancelled' };\n return this.goal;\n }\n\n /**\n * Advance the goal after a goal-driven turn completes. Returns the next decision, or `null`\n * when no goal is active (the caller should ignore non-goal turns).\n */\n onTurnComplete(result: IExecutionResult): TGoalDecision | null {\n if (!this.goal || this.goal.status !== 'active') return null;\n\n const signal = extractGoalSignal(result.toolSummaries);\n const iteration = this.goal.iterations + 1;\n this.goal = {\n ...this.goal,\n iterations: iteration,\n progress: [\n ...this.goal.progress,\n { iteration, signal: signal?.status ?? 'continue', reason: signal?.reason ?? '' },\n ],\n };\n\n if (signal?.status === 'satisfied') {\n return this.stop('satisfied');\n }\n\n const didWork = countNonSignalToolCalls(result.toolSummaries) > 0;\n this.consecutiveIdleTurns = didWork ? 0 : this.consecutiveIdleTurns + 1;\n if (this.consecutiveIdleTurns >= this.noProgressLimit) {\n return this.stop('no-progress');\n }\n\n if (iteration >= this.goal.maxIterations) {\n return this.stop('max-iterations');\n }\n\n return { action: 'continue', prompt: buildGoalContinuationPrompt(this.goal), goal: this.goal };\n }\n\n private stop(reason: TGoalStopReason): TGoalDecision {\n const status = reason === 'satisfied' ? 'satisfied' : 'stopped';\n this.goal = { ...this.goal!, status, stopReason: reason };\n return { action: 'stop', reason, goal: this.goal };\n }\n}\n","/**\n * Agent hook executor — delegates to a subagent 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 subagent 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(['Shell', '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 { join } from 'node:path';\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 { readSettings, writeSettings } from '../config/settings-io.js';\nimport { createGoalStatusTool } from '../goal/index.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, cwd });\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 = [\n ...defaultTools,\n ...(options.additionalTools ?? []),\n ...(options.includeGoalTool ? [createGoalStatusTool()] : []),\n ];\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\n // Commands with requiresPermission: false are auto-approved — no prompt needed.\n const commandAutoAllow = modelCommandToolProjection\n ? modelCommandToolProjection.commandTools\n .filter((t) => !t.requiresPermission)\n .map((t) => t.toolName)\n : [];\n\n const allowedToolPatterns = (options.allowedTools ?? []).map((name) => `${name}(*)`);\n const deniedToolPatterns = (options.deniedTools ?? []).map((name) => `${name}(*)`);\n const mergedPermissions = {\n allow: [\n ...defaultAllow,\n ...commandAutoAllow,\n ...(options.config.permissions.allow ?? []),\n ...allowedToolPatterns,\n ],\n deny: [...(options.config.permissions.deny ?? []), ...deniedToolPatterns],\n };\n\n const projectSettingsPath = join(cwd, '.robota', 'settings.local.json');\n function onProjectAllowTool(toolName: string): void {\n const pattern = `${toolName}(*)`;\n const settings = readSettings(projectSettingsPath);\n const currentAllow = Array.isArray(settings.permissions)\n ? []\n : (((settings.permissions as Record<string, unknown> | undefined)?.allow as\n | string[]\n | undefined) ?? []);\n if (!currentAllow.includes(pattern)) {\n writeSettings(projectSettingsPath, {\n ...settings,\n permissions: {\n ...((settings.permissions as Record<string, unknown>) ?? {}),\n allow: [...currentAllow, pattern],\n },\n });\n }\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.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 // CMD-005: model-invoked tools solicit structured answers through this port.\n ...(options.ask ? { ask: options.ask } : {}),\n onProjectAllowTool,\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 ...(options.activePresetId !== undefined ? { activePresetId: options.activePresetId } : {}),\n ...(options.responseFormat ? { responseFormat: options.responseFormat } : {}),\n ...(options.effort !== undefined ? { effort: options.effort } : {}),\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 /** Selected preset id (overridden by --preset). */\n preset: 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\n// TMemoryType SSOT relocated to @robota-sdk/agent-interface-transport (DATA-001).\nimport type { TMemoryType } from '@robota-sdk/agent-interface-transport';\n\nexport type { TMemoryType };\n\nexport const MEMORY_INDEX_MAX_LINES = 200;\nexport const MEMORY_INDEX_MAX_BYTES = Number('25600');\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 * 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 * 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 { Session } from '@robota-sdk/agent-session';\n\nexport type {\n IInteractiveSessionStandardOptions,\n IInteractiveSessionInjectedOptions,\n TInteractiveSessionOptions,\n IInitOptions,\n} from './interactive-session-options.js';\nimport type { ICompactEvent } from '@robota-sdk/agent-interface-transport';\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 /**\n * Rebuilds the system message given updated agentsMd and claudeMd strings. PRESET-014: an\n * optional `overrides.persona` re-applies a preset persona to the live prompt; PRESET-017: an\n * optional `overrides.selfVerification` toggles the verify-before-done section. Either override\n * is retained for subsequent (override-less) rebuilds.\n */\n rebuildSystemMessage: (\n agentsMd: string,\n claudeMd: string,\n overrides?: { persona?: string; selfVerification?: boolean },\n ) => 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 // CMD-005: the channel's unified ask renderer doubles as the model-question seam for tools.\n ...(options.askHandler ? { ask: options.askHandler } : {}),\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 deniedTools: options.deniedTools,\n model: options.model,\n appendSystemPrompt: options.appendSystemPrompt,\n ...(options.persona !== undefined ? { persona: options.persona } : {}),\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.enableParallelSubagents !== undefined\n ? { enableParallelSubagents: options.enableParallelSubagents }\n : {}),\n ...(options.selfVerification !== undefined\n ? { selfVerification: options.selfVerification }\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 ...(options.activePresetId !== undefined ? { activePresetId: options.activePresetId } : {}),\n ...(options.additionalTools ? { additionalTools: options.additionalTools } : {}),\n // GOAL-001: every interactive session exposes the goal completion-signal tool so /goal and\n // --goal can drive autonomous pursuit. It is inert unless a goal is active.\n includeGoalTool: true,\n ...(options.responseFormat ? { responseFormat: options.responseFormat } : {}),\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 ...(options.askHandler ? { askHandler: options.askHandler } : {}),\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 deniedTools: options.deniedTools,\n model: options.model,\n appendSystemPrompt: options.appendSystemPrompt,\n ...(options.persona !== undefined ? { persona: options.persona } : {}),\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 ...(options.activePresetId !== undefined ? { activePresetId: options.activePresetId } : {}),\n ...(options.enableParallelSubagents !== undefined\n ? { enableParallelSubagents: options.enableParallelSubagents }\n : {}),\n ...(options.selfVerification !== undefined\n ? { selfVerification: options.selfVerification }\n : {}),\n ...(options.additionalTools ? { additionalTools: options.additionalTools } : {}),\n ...(options.responseFormat ? { responseFormat: options.responseFormat } : {}),\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 created.session.syncContextFromHistory();\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 TBackgroundJobGroupEvent,\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 { IGoalState } from '@robota-sdk/agent-interface-transport';\nimport type {\n IBackgroundTaskState,\n TBackgroundTaskEvent,\n} from '@robota-sdk/agent-interface-transport';\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 goalState?: IGoalState,\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 ...(goalState !== undefined ? { goalState } : {}),\n }),\n );\n } catch {\n // allow-fallback: persistence is best-effort for interactive execution and must not break a turn\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 goalState?: IGoalState;\n}\n\nfunction buildInteractiveSessionRecord(\n input: IBuildInteractiveSessionRecordInput,\n): IInteractiveSessionRecord {\n return {\n id: input.sessionId,\n ...(input.goalState !== undefined ? { goal: input.goalState } : {}),\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 /** Replace the entire command set (used by live preset command-module re-selection — PRESET-015). */\n replaceCommands(commands: readonly ISystemCommand[]): void {\n this.commands.clear();\n for (const command of commands) 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 requiresPermission: this.resolveRequiresPermission(command),\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 ICommandResult,\n TCommandEffect,\n TCommandResultDataValue,\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 {\n findProviderDefinition,\n formatSupportedProviderTypes,\n getProviderCredentialRequirement,\n} 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 /** Environment map for configure-time checks (test seam, default: process.env). */\n env?: Record<string, string | undefined>;\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 // CLI-068: causal order — an unknown provider must be diagnosed as unknown,\n // not as a missing field that its (nonexistent) defaults failed to fill.\n const definitions = options.providerDefinitions ?? [];\n const definition = findProviderDefinition(definitions, profile.type);\n if (definition === undefined && definitions.length > 0) {\n throw new Error(\n `Unknown provider \"${profile.type}\". Supported providers: ${formatSupportedProviderTypes(definitions)}`,\n );\n }\n if (!profile.model) {\n throw new Error(`Provider profile \"${profileName}\" is missing model`);\n }\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 if (input.apiKey !== undefined && input.apiKeyEnv === undefined) {\n // eslint-disable-next-line no-console -- security warning surfaced to CLI user at setup time; no logger injected in this pure-function context\n console.warn(\n 'API key stored as plain text in settings. Use --api-key-env for better security.',\n ); // allow-console: security warning at setup time\n }\n if (input.apiKeyEnv !== undefined) {\n // CLI-068: the referenced variable must exist when configuring — failing at\n // first run with a generic missing-apiKey message diagnoses the wrong cause.\n const envValue = (options.env ?? process.env)[input.apiKeyEnv];\n if (envValue === undefined || envValue.length === 0) {\n throw new Error(\n `Environment variable ${input.apiKeyEnv} is not set — set it before configuring ` +\n `(the profile will reference $ENV:${input.apiKeyEnv})`,\n );\n }\n }\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';\nimport { SettingsParseError } from '../../config/settings-parse-error.js';\n\nimport type { IProviderProfileSettings, TProviderSettingsDocument } from './provider-settings.js';\nimport type { IFileSystem } from '@robota-sdk/agent-core';\nimport type { IProviderDefinitionConfig, 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\n/**\n * CLI-069: a missing file is a non-error (undefined); an EXISTING file that\n * fails to parse throws SettingsParseError — corrupt is never treated as missing.\n */\nfunction readSettingsFile(\n filePath: string,\n fs: IFileSystem,\n): TProviderSettingsDocument | undefined {\n if (!fs.existsSync(filePath)) {\n return undefined;\n }\n const raw = fs.readFileSync(filePath, 'utf8');\n try {\n return JSON.parse(raw) as TProviderSettingsDocument;\n } catch (error) {\n // allow-fallback: rethrown as typed SettingsParseError — fail-fast, not a fallback\n throw new SettingsParseError(filePath, error instanceof Error ? error.message : String(error));\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): IProviderDefinitionConfig | 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 { 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 { ENV_REFERENCE_PREFIX, isEnvReference } from '@robota-sdk/agent-core';\nimport { 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 {\n IAIProvider,\n IProviderDefinitionConfig,\n IProviderDefinition,\n} from '@robota-sdk/agent-core';\n\nexport interface IReadProviderSettingsOptions {\n providerOverride?: string;\n providerDefinitions?: readonly IProviderDefinition[];\n /** Environment map for env-default synthesis (test seam, default: process.env). */\n env?: Record<string, string | undefined>;\n}\n\n/**\n * Missing or unusable provider configuration at session start.\n * Typed so callers can map it to a distinct exit code without message matching.\n */\nexport class ProviderConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ProviderConfigError';\n }\n}\n\nexport function readMergedProviderSettings(cwd: string): TProviderSettingsDocument {\n return readMergedProviderSettingsFromPaths(getProviderSettingsPaths(cwd));\n}\n\n/**\n * Zero-config fallback: synthesize an in-memory provider config from the first\n * definition (in order) whose defaults are complete — `$ENV:` apiKey reference with the\n * referenced variable set, plus a default model. Settings profiles always win; nothing\n * is persisted. Returns undefined when no definition qualifies.\n */\nexport function resolveEnvDefaultProvider(\n providerDefinitions: readonly IProviderDefinition[],\n env: Record<string, string | undefined> = process.env,\n): IProviderDefinitionConfig | undefined {\n for (const definition of providerDefinitions) {\n const defaults = definition.defaults;\n if (defaults?.apiKey === undefined || defaults.model === undefined) continue;\n if (!isEnvReference(defaults.apiKey)) continue;\n const envName = defaults.apiKey.slice(ENV_REFERENCE_PREFIX.length).trim();\n if (envName.length === 0) continue;\n const envValue = env[envName];\n if (envValue === undefined || envValue.length === 0) continue;\n // The key is resolved here (profile-path parity: resolveActiveProvider also returns\n // resolved keys via normalizeProviderConfig); the env var NAME travels separately in\n // sourceEnvVar so notices never need the value.\n return {\n name: definition.type,\n model: defaults.model,\n apiKey: envValue,\n ...(defaults.baseURL !== undefined && { baseURL: defaults.baseURL }),\n ...(defaults.timeout !== undefined && { timeout: defaults.timeout }),\n ...(defaults.options !== undefined && { options: defaults.options }),\n source: 'env-default',\n sourceEnvVar: envName,\n };\n }\n return undefined;\n}\n\nexport function readProviderSettings(\n cwd: string,\n options: IReadProviderSettingsOptions = {},\n): IProviderDefinitionConfig {\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 const envDefault = resolveEnvDefaultProvider(options.providerDefinitions ?? [], options.env);\n if (envDefault !== undefined) {\n return envDefault;\n }\n\n throw new ProviderConfigError('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 type { ICommandModule } from '../command-api/index.js';\n\n/**\n * Filter command modules by allow (`enabled`) then deny (`disabled`) name lists. Pure.\n *\n * Rules: if `enabled` is provided, keep only modules whose `name` is in it; then remove any module\n * whose `name` is in `disabled` (deny > allow). Neither given → the input set is returned unchanged.\n *\n * This is the framework-owned counterpart of agent-command's `applyModuleSelection` — duplicated\n * here deliberately so agent-framework does not depend on agent-command (PRESET-015).\n */\nexport function selectCommandModules(\n modules: readonly ICommandModule[],\n enabled: readonly string[] | undefined,\n disabled: readonly string[] | undefined,\n): readonly ICommandModule[] {\n let selected = modules;\n if (enabled !== undefined) {\n const allow = new Set(enabled);\n selected = selected.filter((module) => allow.has(module.name));\n }\n if (disabled !== undefined) {\n const deny = new Set(disabled);\n selected = selected.filter((module) => !deny.has(module.name));\n }\n return selected;\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 beforeMessageCount: number;\n afterMessageCount: number;\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 const beforeMessageCount = context.getSession().getMessageCount();\n await context.compactContext(instructions);\n const after = readCommandContextState(context);\n const afterMessageCount = context.getSession().getMessageCount();\n return { before, after, beforeMessageCount, afterMessageCount };\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.flatMap((command) => {\n const displayLabel = command.displayName ?? command.name;\n const invocation = `/${command.name}`;\n const label = command.displayName ? `${displayLabel} (${invocation})` : invocation;\n const mainLine = ` ${label.padEnd(HELP_COMMAND_NAME_COLUMN_WIDTH * 2)} — ${command.description}`;\n if (command.example) {\n return [mainLine, ` Example: ${command.example}`];\n }\n return [mainLine];\n }),\n ].join('\\n');\n}\n","import type { ICommandHostContext } from '../host-context.js';\nimport type { ICommand } from '../types.js';\nimport type {\n IBackgroundTaskListFilter,\n IBackgroundTaskLogCursor,\n IBackgroundTaskLogPage,\n IBackgroundTaskState,\n} from '@robota-sdk/agent-interface-transport';\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 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 { writeCommandPermissionMode } from '../permissions/permission-mode-command-api.js';\n\nimport type { ICommandHostContext, IModelReapplyOptions } from '../host-context.js';\nimport type { TModelEffort, TPermissionMode } from '@robota-sdk/agent-core';\n\n/**\n * Resolved-preset option subset that can be re-applied to a *live* session.\n *\n * This is a framework-owned shape. The agent-preset package's `IResolvedPresetOptions` satisfies it\n * structurally, so a consumer can hand a `resolvePreset(...)` result straight to\n * {@link applyPresetToSession} without framework importing agent-preset (no dependency cycle).\n *\n * PRESET-012 carries the permission/trust group (`permissionMode`); PRESET-013 adds the model group\n * (`model`, `effort`, `temperature`, `maxOutputTokens`); PRESET-014 adds the `persona` block,\n * re-applied to the live system prompt; PRESET-015 adds the command-module selection group\n * (`enabledCommandModules`/`disabledCommandModules`), re-filtered against the session-start set.\n */\nexport interface IPresetApplicationOptions {\n permissionMode?: TPermissionMode;\n model?: string;\n effort?: TModelEffort;\n temperature?: number;\n maxOutputTokens?: number;\n /** PRESET-014 — preset persona re-applied to the live system prompt. */\n persona?: string;\n /** PRESET-015 — allowlist of command-module names to keep on the live session. */\n enabledCommandModules?: readonly string[];\n /** PRESET-015 — denylist of command-module names to remove from the live session. */\n disabledCommandModules?: readonly string[];\n /** PRESET-016 — runtime gate toggle for subagent dispatch on the live session. */\n enableParallelSubagents?: boolean;\n /** PRESET-017 — toggle the verify-before-done self-verification section on the live prompt. */\n selfVerification?: boolean;\n}\n\n/** Outcome of {@link applyPresetToSession}: which option groups were re-applied vs. skipped. */\nexport interface IPresetApplicationResult {\n /** Option-group keys whose value was present and applied to the live session. */\n readonly applied: readonly string[];\n /** Option-group keys absent from the resolved options (left untouched). */\n readonly skipped: readonly string[];\n}\n\n/**\n * Re-apply a resolved preset to a live session and record it as the active preset.\n *\n * This is the single entry point for live preset switching. It first records the active preset id\n * (PRESET-011 runtime state) — the runtime's `setActivePresetId` is optional, so it is invoked\n * defensively. It then re-applies each option group it owns; PRESET-012 applies the permission\n * posture via the existing `writeCommandPermissionMode` seam, and PRESET-013 re-applies the model\n * group (`model`/`effort`/`temperature`/`maxOutputTokens`) via the runtime's optional\n * `applyModelOptions`. PRESET-014 re-applies the `persona` group via the host context's optional\n * `applyPersona` seam. PRESET-015 re-applies the command-module selection group via the host\n * context's optional `applyCommandModuleSelection` seam. PRESET-016 toggles the parallel-subagents\n * runtime gate via the runtime's optional `setParallelSubagentsEnabled` seam. PRESET-017 toggles\n * the verify-before-done self-verification section via the host context's optional\n * `applySelfVerification` seam. Groups absent from `options` are left untouched and reported under\n * `skipped`.\n */\nexport async function applyPresetToSession(\n context: ICommandHostContext,\n presetId: string,\n options: IPresetApplicationOptions,\n): Promise<IPresetApplicationResult> {\n const applied: string[] = [];\n const skipped: string[] = [];\n\n // PRESET-011 state — optional runtime method, applied defensively.\n context.getSession().setActivePresetId?.(presetId);\n\n if (options.permissionMode !== undefined) {\n writeCommandPermissionMode(context, options.permissionMode);\n applied.push('permissionMode');\n } else {\n skipped.push('permissionMode');\n }\n\n // PRESET-013 model group — re-applied via the runtime's optional applyModelOptions seam.\n const modelOptions: IModelReapplyOptions = {\n ...(options.model !== undefined && { model: options.model }),\n ...(options.effort !== undefined && { effort: options.effort }),\n ...(options.temperature !== undefined && { temperature: options.temperature }),\n ...(options.maxOutputTokens !== undefined && { maxOutputTokens: options.maxOutputTokens }),\n };\n for (const key of ['model', 'effort', 'temperature', 'maxOutputTokens'] as const) {\n if (options[key] !== undefined) {\n applied.push(key);\n } else {\n skipped.push(key);\n }\n }\n if (Object.keys(modelOptions).length > 0) {\n await context.getSession().applyModelOptions?.(modelOptions);\n }\n\n // PRESET-014 persona group — re-applied via the host context's optional applyPersona seam.\n if (options.persona !== undefined) {\n context.applyPersona?.(options.persona);\n applied.push('persona');\n } else {\n skipped.push('persona');\n }\n\n // PRESET-015 command-module group — re-applied via the host context's optional\n // applyCommandModuleSelection seam (re-filters the session-start module set).\n if (options.enabledCommandModules !== undefined || options.disabledCommandModules !== undefined) {\n context.applyCommandModuleSelection?.(\n options.enabledCommandModules,\n options.disabledCommandModules,\n );\n applied.push('commandModules');\n } else {\n skipped.push('commandModules');\n }\n\n // PRESET-016 parallel-subagents gate — toggled via the runtime's optional\n // setParallelSubagentsEnabled seam (live gate on an already-constructed session).\n if (options.enableParallelSubagents !== undefined) {\n context.getSession().setParallelSubagentsEnabled?.(options.enableParallelSubagents);\n applied.push('enableParallelSubagents');\n } else {\n skipped.push('enableParallelSubagents');\n }\n\n // PRESET-017 self-verification group — toggled via the host context's optional\n // applySelfVerification seam (recomposes the live system prompt).\n if (options.selfVerification !== undefined) {\n context.applySelfVerification?.(options.selfVerification);\n applied.push('selfVerification');\n } else {\n skipped.push('selfVerification');\n }\n\n return { applied, skipped };\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// Status-line command settings contracts SSOT relocated to @robota-sdk/agent-interface-transport (DATA-001).\nimport type {\n IStatusLineCommandSettings,\n TStatusLineCommandSettingsPatch,\n} from '@robota-sdk/agent-interface-transport';\n\nexport type { IStatusLineCommandSettings, TStatusLineCommandSettingsPatch };\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 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// Plugin command adapter contracts SSOT relocated to @robota-sdk/agent-interface-transport (DATA-001).\nimport type { ICommandPluginAdapter } from '@robota-sdk/agent-interface-transport';\n\nexport type {\n TPluginInstallScope,\n ICommandInstalledPlugin,\n ICommandAvailablePlugin,\n ICommandMarketplaceSource,\n ICommandPluginReloadResult,\n ICommandPluginAdapter,\n} from '@robota-sdk/agent-interface-transport';\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 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 =\n 'Show session token usage and estimated cost. /cost budget <amount> sets a monthly budget.';\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 ISkillPromptContext {\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?: ISkillPromptContext,\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 ISkillPromptContext,\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?: ISkillPromptContext,\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?: ISkillPromptContext,\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?: ISkillPromptContext,\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 {\n executeSkill,\n selectCommandModules,\n SkillCommandSource,\n SystemCommandExecutor,\n} 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 /** Command modules received at construction — retained for live re-selection (PRESET-015). */\n private readonly allCommandModules: readonly ICommandModule[];\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.allCommandModules = commandModules;\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 /** PRESET-015 — re-filter the session's command modules and rebuild the executor live. */\n reapplyCommandModuleSelection(\n enabled: readonly string[] | undefined,\n disabled: readonly string[] | undefined,\n ): void {\n const selected = selectCommandModules(this.allCommandModules, enabled, disabled);\n this.commandExecutor.replaceCommands(selected.flatMap((module) => module.systemCommands ?? []));\n }\n\n getCommandInvocationSource(): TCommandInvocationSource {\n return this.commandInvocationSource;\n }\n\n getCommandHostAdapters(): ICommandHostAdapters {\n return this.commandHostAdapters ?? {};\n }\n\n listCommands(): Array<{\n name: string;\n displayName?: string;\n description: string;\n example?: string;\n }> {\n return this.commandExecutor.listCommands().map((cmd) => ({\n name: cmd.name,\n ...(cmd.displayName !== undefined ? { displayName: cmd.displayName } : {}),\n description: cmd.description,\n ...(cmd.example !== undefined ? { example: cmd.example } : {}),\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 { existsSync, readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nimport type { IOrgPolicy } from './org-policy-types.js';\n\nexport function loadOrgPolicy(): IOrgPolicy | null {\n const policyPath = join(homedir(), '.robota', 'org-policy.json');\n if (!existsSync(policyPath)) return null;\n try {\n const raw = readFileSync(policyPath, 'utf8');\n return JSON.parse(raw) as IOrgPolicy;\n } catch {\n // allow-fallback: malformed org-policy.json must not crash CLI startup\n return null;\n }\n}\n\nexport function formatOrgPolicyViolationMessage(\n reason: string,\n adminContact: string | undefined,\n): string {\n const contact = adminContact ? `\\nContact your administrator: ${adminContact}` : '';\n return `${reason}${contact}`;\n}\n\nexport function isApiKeyPlaintext(apiKey: string | undefined): boolean {\n if (!apiKey) return false;\n return !apiKey.startsWith('$ENV:');\n}\n","/**\n * Builds the guarded \"ask the user\" port for a session (CMD-004).\n *\n * Kept as a pure function (separate from the InteractiveSession god-class) so the model-invocation\n * guard is unit-testable without constructing a session.\n */\n\nimport type { TCommandInvocationSource } from '../command-api/host-context.js';\nimport type { IUserInteraction, TActionResponse } from '@robota-sdk/agent-core';\n\n/**\n * Return the injected ask port, or `undefined` when no ask handler is attached (headless/automation —\n * callers treat absence as \"no human available\", never a silent guess).\n *\n * When the active command was invoked by the model, the port resolves `cancelled` instead of asking:\n * a model-invoked command runs inside an executing turn, where blocking on a human prompt would\n * deadlock. (Letting the model issue an interactive ask is CMD-005's separate turn-suspension design.)\n */\nexport function createUserInteractionPort(\n handler: IUserInteraction['ask'] | undefined,\n getInvocationSource: () => TCommandInvocationSource,\n): IUserInteraction | undefined {\n if (!handler) return undefined;\n const cancelled: TActionResponse = { type: 'cancelled' };\n return {\n ask: (request) =>\n getInvocationSource() === 'model' ? Promise.resolve(cancelled) : handler(request),\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 { formatOrgPolicyViolationMessage } from '../command-api/org-policy/org-policy-loader.js';\nimport {\n createProviderFromSettings,\n readProviderSettings,\n} from '../command-api/provider/provider-factory.js';\nimport { GoalController, buildGoalContinuationPrompt } from '../goal/index.js';\nimport { createUserInteractionPort } from '../interaction/user-interaction-port.js';\nimport { retrieveAgentToolDeps } from '../tools/agent-tool.js';\nimport { humanizeApiError } from '../utils/error-humanizer.js';\n\nimport type { IInteractiveSession } from './i-interactive-session.js';\nimport type { ITurnOptions } from './interactive-session-execution-controller.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 {\n TInteractiveEventName,\n IInteractiveSessionEvents,\n IExecutionResult,\n} from './types.js';\nimport type { IBackgroundTaskManager } from '../background-tasks/index.js';\nimport type { ICommandHostContext } from '../command-api/index.js';\nimport type {\n IAgentJobHostContext,\n ICommandResult,\n TAutoCompactThresholdSource,\n TAutoCompactThreshold,\n} from '../commands/index.js';\nimport type { IContextFileEntry } from '../context/context-file-tracker.js';\nimport type { IGoalStartOptions } from '../goal/index.js';\nimport type {\n TUniversalMessage,\n TSessionEndReason,\n IProviderDefinition,\n IUserInteraction,\n} from '@robota-sdk/agent-core';\nimport type { ISession } from '@robota-sdk/agent-core';\nimport type {\n ITransportAdapter,\n IGoalState,\n ITerminalHandoff,\n TTurnSource,\n} 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 private providerDefinitions: readonly IProviderDefinition[] = [];\n private orgPolicy: import('../command-api/org-policy/org-policy-types.js').IOrgPolicy | null =\n null;\n protected readonly bgTracker: SessionBackgroundTaskTracker;\n protected readonly histTracker: SessionHistoryTracker;\n protected readonly skillRouter: SessionSkillRouter;\n protected readonly execCtrl: SessionExecutionController;\n /** GOAL-001: autonomous objective-pursuit controller (inert until a goal is set). */\n private readonly goalController = new GoalController();\n /** GOAL-001: origin of the most recently started turn — gates goal-loop advancement. */\n private currentTurnSource: TTurnSource = 'user';\n /** TERM-001: transport-provided terminal-handoff capability (undefined when none). */\n private readonly terminalHandoff?: ITerminalHandoff;\n /** CMD-004: transport-provided \"ask the user\" handler (undefined when no interactive renderer). */\n private readonly askHandler?: IUserInteraction['ask'];\n /** TERM-001: guards handoff exclusivity (one handoff at a time). */\n private terminalHandoffActive = false;\n\n constructor(options: TInteractiveSessionOptions) {\n super();\n this.sessionStore = options.sessionStore;\n this.sessionName = options.sessionName;\n this.terminalHandoff = options.terminalHandoff;\n this.askHandler = options.askHandler;\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 (instruction, taskId) => this.requestWakeup(instruction, taskId),\n (message) => this.histTracker.append(messageToHistoryEntry(createSystemMessage(message))),\n (entry) => this.histTracker.append(entry),\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 (event) => this.emit('memory_event', 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 if ('providerDefinitions' in options) {\n this.providerDefinitions =\n (options as IInteractiveSessionStandardOptions).providerDefinitions ?? [];\n }\n if ('orgPolicy' in options) {\n this.orgPolicy = (options as IInteractiveSessionStandardOptions).orgPolicy ?? null;\n }\n\n // GOAL-001: observe turn origin and completion to drive the autonomous goal loop.\n this.on('turn_source', (source) => {\n this.currentTurnSource = source;\n });\n this.on('complete', (result) => this.handleGoalTurnComplete(result));\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 this.resumeGoalIfActive();\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(this.sessionStore, options.resumeSessionId, this.session);\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 // GOAL-001: a fork starts fresh; a true resume restores any in-flight goal so pursuit continues.\n if (!this.forkSession && restored.goal) this.goalController.restore(restored.goal);\n if (this.session && restored.pendingRestoreMessages === null) {\n // Injected-session path: messages were injected immediately — sync context estimate.\n this.session.syncContextFromHistory();\n this.emit('context_update', this.getContextState());\n }\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.histTracker.recordSystemContextFiles([\n ...result.agentsFileEntries,\n ...result.claudeFileEntries,\n ]);\n this.pendingRestoreMessages = null;\n this.initialized = true;\n this.bgTracker.subscribe(this.session);\n this.persistCurrentSession();\n this.emit('context_update', this.getContextState());\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(\n input: string,\n displayInput?: string,\n rawInput?: string,\n options: ITurnOptions = {},\n ): 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 this.execCtrl.pendingTurnOptions = options;\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 this.histTracker.recordSystemContextFiles([...agents, ...claude]);\n },\n (p, d, r, o) => this.submit(p, d, r, o),\n options,\n );\n }\n\n /**\n * FLOW-002: re-enter the agent loop with a non-user turn triggered by a background wake\n * (a scheduled fire or, later, a monitor match). Coalesces by source task id so repeated\n * wakes for the same task while one is still in flight collapse to a single turn.\n */\n requestWakeup(instruction: string, sourceTaskId: string): boolean {\n if (this.execCtrl.shuttingDown) return false;\n if (this.execCtrl.wakeTaskIds.has(sourceTaskId)) return false;\n this.execCtrl.wakeTaskIds.add(sourceTaskId);\n void this.submit(instruction, undefined, undefined, {\n turnSource: 'agent-wakeup',\n wakeTaskId: sourceTaskId,\n });\n return true;\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 this.listeners.clear();\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 /**\n * PRESET-014: re-apply a preset persona to the live system prompt. Recomposes the system\n * message from the currently tracked AGENTS.md/CLAUDE.md entries (the same content the staleness\n * refresh uses) plus the new persona, then propagates it to the session. No-op before init,\n * when the rebuild closure is not yet available.\n */\n applyPersona(persona: string): void {\n if (this.rebuildSystemMessage === null) return;\n const currentAgents = this.agentsFileEntries.map((e) => e.content).join('\\n\\n');\n const currentClaude = this.claudeFileEntries.map((e) => e.content).join('\\n\\n');\n const msg = this.rebuildSystemMessage(currentAgents, currentClaude, { persona });\n this.getSessionOrThrow().updateSystemMessage(msg);\n }\n\n /**\n * PRESET-017: toggle the verify-before-done self-verification section on the live system prompt.\n * Recomposes the system message from the currently tracked AGENTS.md/CLAUDE.md entries plus the\n * new selfVerification flag, then propagates it to the session. No-op before init, when the\n * rebuild closure is not yet available.\n */\n applySelfVerification(enabled: boolean): void {\n if (this.rebuildSystemMessage === null) return;\n const currentAgents = this.agentsFileEntries.map((e) => e.content).join('\\n\\n');\n const currentClaude = this.claudeFileEntries.map((e) => e.content).join('\\n\\n');\n const msg = this.rebuildSystemMessage(currentAgents, currentClaude, {\n selfVerification: enabled,\n });\n this.getSessionOrThrow().updateSystemMessage(msg);\n }\n\n /**\n * PRESET-015: re-apply a preset's command-module selection to the live session by delegating to\n * the skill router, which re-filters the session-start module set and rebuilds the executor.\n */\n applyCommandModuleSelection(\n enabled: readonly string[] | undefined,\n disabled: readonly string[] | undefined,\n ): void {\n this.skillRouter.reapplyCommandModuleSelection(enabled, disabled);\n }\n\n getAgentJobCapability(): IAgentJobHostContext {\n return this;\n }\n\n /**\n * CMD-004: the injected \"ask the user\" port, or undefined when no interactive renderer is attached\n * (headless/automation) — a command must treat absence as \"no human available\", never a silent\n * guess. The model-invocation guard lives in {@link createUserInteractionPort}.\n */\n getUserInteraction(): IUserInteraction | undefined {\n return createUserInteractionPort(this.askHandler, () => this.getCommandInvocationSource());\n }\n\n /**\n * TERM-001: whether the active transport can hand the real terminal to a child process. False\n * when no handoff capability was injected or its `canHandoffTerminal` is false (e.g. headless).\n */\n canHandoffTerminal(): boolean {\n return this.terminalHandoff?.canHandoffTerminal === true;\n }\n\n /**\n * TERM-001: suspend the display, run `fn` (which spawns a child with inherited stdio), then\n * restore. The framework owns the ORCHESTRATION: it enforces exclusivity (one handoff at a time)\n * and fast-fails when no interactive terminal is available, instead of hanging. The transport\n * implements the underlying suspend/resume; the caller's `fn` spawns whatever child it wants — the\n * framework stays platform-neutral and never spawns a shell.\n */\n async runWithTerminal<T>(fn: () => Promise<T>): Promise<T> {\n if (!this.canHandoffTerminal() || this.terminalHandoff === undefined) {\n throw new Error(\n 'Terminal handoff is unavailable: no interactive terminal (headless or non-TTY output).',\n );\n }\n if (this.terminalHandoffActive) {\n throw new Error('A terminal handoff is already in progress.');\n }\n this.terminalHandoffActive = true;\n try {\n return await this.terminalHandoff.runWithTerminal(fn);\n } finally {\n this.terminalHandoffActive = false;\n }\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 /**\n * Surface an error that happened OUTSIDE the turn boundary (background task, catalog\n * refresh, persistence, un-caught promise) into the conversation (ERR-001 G1). The entry\n * carries `metadata.kind: 'error'` so transports render it as a styled error block, and the\n * 'error' event drives transport error state. The session stays fully usable.\n */\n reportBackgroundError(error: Error, source = 'background'): void {\n const message = humanizeApiError(error);\n this.histTracker.append(\n messageToHistoryEntry(\n createSystemMessage(`Error: ${message}`, { metadata: { kind: 'error', source } }),\n ),\n );\n this.emit('error', error);\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 this.goalController.getState() ?? undefined,\n );\n }\n\n /**\n * GOAL-001: assign an autonomous goal and begin pursuing it. The agent takes follow-up turns\n * on its own until it signals the goal satisfied or a bound fires (max iterations, no-progress,\n * or {@link cancelGoal}). Returns the seeded goal state. Throws on an empty objective.\n */\n async setGoal(objective: string, options: IGoalStartOptions = {}): Promise<IGoalState> {\n await this.ensureInitialized();\n const { goal, prompt } = this.goalController.start(objective, options);\n this.emit('goal_event', { type: 'goal_started', goal });\n this.persistCurrentSession();\n this.scheduleGoalTurn(prompt, goal);\n return goal;\n }\n\n /** GOAL-001: the current goal state, or `null` when no goal has been set. */\n getGoalState(): IGoalState | null {\n return this.goalController.getState();\n }\n\n /** GOAL-001: cancel an in-flight goal. Returns the stopped state, or `null` when none is active. */\n cancelGoal(): IGoalState | null {\n const stopped = this.goalController.cancel();\n if (stopped) {\n this.emit('goal_event', { type: 'goal_stopped', goal: stopped });\n this.persistCurrentSession();\n }\n return stopped;\n }\n\n /** GOAL-001: schedule the next goal-driven turn via the FLOW-002 wakeup primitive. */\n private scheduleGoalTurn(prompt: string, goal: IGoalState): void {\n if (this.execCtrl.shuttingDown) return;\n const wakeId = `goal:${goal.id}:${goal.iterations}`;\n // Defer past the current turn's finalization so the wakeup is not coalesced away and the\n // just-completed turn's bookkeeping (executing flag, wake ids) has settled.\n setTimeout(() => this.requestWakeup(prompt, wakeId), 0);\n }\n\n /** GOAL-001: advance the goal loop after an agent-driven turn completes. */\n private handleGoalTurnComplete(result: IExecutionResult): void {\n if (!this.goalController.isActive()) return;\n // Only agent-driven turns advance the goal; a user's own message is not a goal iteration.\n if (this.currentTurnSource !== 'agent-wakeup') return;\n const decision = this.goalController.onTurnComplete(result);\n if (!decision) return;\n this.persistCurrentSession();\n if (decision.action === 'continue') {\n this.emit('goal_event', { type: 'goal_progress', goal: decision.goal });\n this.scheduleGoalTurn(decision.prompt, decision.goal);\n } else {\n this.emit('goal_event', { type: 'goal_stopped', goal: decision.goal });\n }\n }\n\n /** GOAL-001: after a resume, continue pursuing a restored active goal once initialized. */\n private resumeGoalIfActive(): void {\n const goal = this.goalController.getState();\n if (!goal || goal.status !== 'active') return;\n void this.ensureInitialized().then(() => {\n if (!this.goalController.isActive() || this.execCtrl.shuttingDown) return;\n this.scheduleGoalTurn(buildGoalContinuationPrompt(goal), goal);\n });\n }\n\n private async switchProvider(profileName: string): Promise<void> {\n const session = this.getSessionOrThrow();\n const cwd = this.getCwd();\n const settings = readProviderSettings(cwd, {\n providerOverride: profileName,\n providerDefinitions: this.providerDefinitions,\n });\n const provider = createProviderFromSettings(cwd, undefined, {\n providerOverride: profileName,\n providerDefinitions: this.providerDefinitions,\n });\n session.swapProvider(provider, settings.model);\n }\n\n override async executeCommand(\n name: string,\n args: string,\n ): Promise<import('../commands/index.js').ICommandResult | null> {\n if (this.orgPolicy?.blockedCommands?.includes(name)) {\n return {\n message: formatOrgPolicyViolationMessage(\n `Command /${name} is blocked by your organization policy.`,\n this.orgPolicy.adminContact,\n ),\n success: false,\n };\n }\n const result = await super.executeCommand(name, args);\n if (result === null) return null;\n const hotSwapEffect = result.effects?.find(\n (e): e is { type: 'provider-hot-swap-requested'; profileName: string } =>\n e.type === 'provider-hot-swap-requested',\n );\n if (hotSwapEffect) {\n const { orgPolicy } = this;\n if (\n orgPolicy?.allowedProviders &&\n !orgPolicy.allowedProviders.includes(hotSwapEffect.profileName)\n ) {\n return {\n message: formatOrgPolicyViolationMessage(\n `Provider \"${hotSwapEffect.profileName}\" is not allowed by your organization policy. Allowed: ${orgPolicy.allowedProviders.join(', ')}.`,\n orgPolicy.adminContact,\n ),\n success: false,\n };\n }\n await this.switchProvider(hotSwapEffect.profileName);\n return {\n ...result,\n effects: result.effects?.filter((e) => e.type !== 'provider-hot-swap-requested'),\n };\n }\n return result;\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, userPaths } from '../paths.js';\n\nimport type {\n IBackgroundJobGroupState,\n TBackgroundJobGroupEvent,\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, TUniversalMessage } from '@robota-sdk/agent-core';\n// Session persistence contracts SSOT relocated to @robota-sdk/agent-interface-transport (DATA-001).\nimport type {\n IInteractiveSessionRecord,\n IInteractiveSessionStore,\n IResumableSessionSummary,\n} from '@robota-sdk/agent-interface-transport';\nimport type {\n IBackgroundTaskState,\n TBackgroundTaskEvent,\n} from '@robota-sdk/agent-interface-transport';\n\nexport type { IInteractiveSessionRecord, IInteractiveSessionStore, IResumableSessionSummary };\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\n/**\n * User-level session store (`~/.robota/sessions`). Symmetric to {@link createProjectSessionStore};\n * there is no user-level replay-log directory, so it reads persisted records only.\n */\nexport function createUserSessionStore(\n fs: IFileSystem = new NodeFileSystem(),\n): IInteractiveSessionStore {\n return new ProjectSessionStoreFacade(userPaths().sessions, undefined, 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 * LLM-based session auto-naming. Owned by the framework (interactive-session lifecycle layer) so\n * the prompt/policy lives with session ownership, not in a transport. Transports invoke this and\n * apply the result via `IInteractiveSession.setName`.\n */\n\nimport { createSystemMessage, createUserMessage } from '@robota-sdk/agent-core';\n\nimport type { IAIProvider } from '@robota-sdk/agent-core';\n\nconst SYSTEM_PROMPT =\n 'You generate short session titles. Respond with ONLY a 3-5 word lowercase-hyphenated title (e.g. refactor-auth-middleware). No explanation, no punctuation, no quotes.';\n\nconst MAX_FIRST_MESSAGE_CHARS = 200;\nconst MAX_TITLE_TOKENS = 20;\nconst MAX_NAME_CHARS = 60;\nconst MIN_NAME_CHARS = 3;\n\nfunction sanitizeName(raw: string): string {\n return raw\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .slice(0, MAX_NAME_CHARS);\n}\n\n/**\n * Generate a short session title from the first user message using the active provider.\n * Falls back to a sanitized form of the message when the model returns nothing usable.\n */\nexport async function generateSessionName(\n provider: IAIProvider,\n firstMessage: string,\n): Promise<string> {\n const truncated = firstMessage.slice(0, MAX_FIRST_MESSAGE_CHARS);\n const response = await provider.chat(\n [createSystemMessage(SYSTEM_PROMPT), createUserMessage(truncated)],\n { maxTokens: MAX_TITLE_TOKENS },\n );\n const raw = typeof response.content === 'string' ? response.content : '';\n const name = sanitizeName(raw);\n if (!name || name.length < MIN_NAME_CHARS) return sanitizeName(firstMessage);\n return name;\n}\n"],"mappings":"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"}