@selesai/code 0.5.14 → 0.5.16
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.
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +2 -0
- package/dist/bun/cli.js.map +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +3 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/list-models.d.ts +2 -2
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +3 -3
- package/dist/cli/list-models.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-auto-handoff.test.d.ts.map +1 -1
- package/dist/core/agent-session-auto-handoff.test.js +2 -2
- package/dist/core/agent-session-auto-handoff.test.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +3 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +3 -6
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +23 -9
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +28 -10
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +136 -90
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +20 -98
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +59 -251
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/built-in-extensions.d.ts +3 -0
- package/dist/core/built-in-extensions.d.ts.map +1 -0
- package/dist/core/built-in-extensions.js +3 -0
- package/dist/core/built-in-extensions.js.map +1 -0
- package/dist/core/cache-stats.d.ts +2 -2
- package/dist/core/cache-stats.d.ts.map +1 -1
- package/dist/core/cache-stats.js +1 -1
- package/dist/core/cache-stats.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +8 -2
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +8 -11
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +19 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +63 -26
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/utils.d.ts +1 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +6 -17
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +21 -4
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +4 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +39 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +24 -3
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +22 -3
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/keybindings.d.ts +8 -3
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +7 -3
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/llama/client.d.ts +61 -0
- package/dist/core/llama/client.d.ts.map +1 -0
- package/dist/core/llama/client.js +302 -0
- package/dist/core/llama/client.js.map +1 -0
- package/dist/core/llama/huggingface.d.ts +23 -0
- package/dist/core/llama/huggingface.d.ts.map +1 -0
- package/dist/core/llama/huggingface.js +141 -0
- package/dist/core/llama/huggingface.js.map +1 -0
- package/dist/core/llama/index.d.ts +3 -0
- package/dist/core/llama/index.d.ts.map +1 -0
- package/dist/core/llama/index.js +208 -0
- package/dist/core/llama/index.js.map +1 -0
- package/dist/core/llama/provider.d.ts +10 -0
- package/dist/core/llama/provider.d.ts.map +1 -0
- package/dist/core/llama/provider.js +102 -0
- package/dist/core/llama/provider.js.map +1 -0
- package/dist/core/llama/ui.d.ts +42 -0
- package/dist/core/llama/ui.d.ts.map +1 -0
- package/dist/core/llama/ui.js +416 -0
- package/dist/core/llama/ui.js.map +1 -0
- package/dist/core/model-config.d.ts +513 -0
- package/dist/core/model-config.d.ts.map +1 -0
- package/dist/core/model-config.js +272 -0
- package/dist/core/model-config.js.map +1 -0
- package/dist/core/model-registry.d.ts +20 -126
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +62 -780
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +6 -6
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +21 -18
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +83 -0
- package/dist/core/model-runtime.d.ts.map +1 -0
- package/dist/core/model-runtime.js +451 -0
- package/dist/core/model-runtime.js.map +1 -0
- package/dist/core/models-store.d.ts +17 -0
- package/dist/core/models-store.d.ts.map +1 -0
- package/dist/core/models-store.js +45 -0
- package/dist/core/models-store.js.map +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +7 -2
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +1 -0
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +4 -4
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-composer.d.ts +55 -0
- package/dist/core/provider-composer.d.ts.map +1 -0
- package/dist/core/provider-composer.js +375 -0
- package/dist/core/provider-composer.js.map +1 -0
- package/dist/core/radius.d.ts +2 -0
- package/dist/core/radius.d.ts.map +1 -0
- package/dist/core/radius.js +2 -0
- package/dist/core/radius.js.map +1 -0
- package/dist/core/remote-catalog-provider.d.ts +5 -0
- package/dist/core/remote-catalog-provider.d.ts.map +1 -0
- package/dist/core/remote-catalog-provider.js +102 -0
- package/dist/core/remote-catalog-provider.js.map +1 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +1 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts +17 -0
- package/dist/core/runtime-credentials.d.ts.map +1 -0
- package/dist/core/runtime-credentials.js +42 -0
- package/dist/core/runtime-credentials.js.map +1 -0
- package/dist/core/sdk.d.ts +4 -7
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +18 -25
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +12 -7
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +103 -27
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +1 -11
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/usage-totals.d.ts +19 -0
- package/dist/core/usage-totals.d.ts.map +1 -0
- package/dist/core/usage-totals.js +52 -0
- package/dist/core/usage-totals.js.map +1 -0
- package/dist/defaults/settings.json +2 -2
- package/dist/extensions/index.d.ts +3 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +9 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/llama/client.d.ts +61 -0
- package/dist/extensions/llama/client.d.ts.map +1 -0
- package/dist/extensions/llama/client.js +309 -0
- package/dist/extensions/llama/client.js.map +1 -0
- package/dist/extensions/llama/huggingface.d.ts +23 -0
- package/dist/extensions/llama/huggingface.d.ts.map +1 -0
- package/dist/extensions/llama/huggingface.js +146 -0
- package/dist/extensions/llama/huggingface.js.map +1 -0
- package/dist/extensions/llama/index.d.ts +3 -0
- package/dist/extensions/llama/index.d.ts.map +1 -0
- package/dist/extensions/llama/index.js +211 -0
- package/dist/extensions/llama/index.js.map +1 -0
- package/dist/extensions/llama/provider.d.ts +10 -0
- package/dist/extensions/llama/provider.d.ts.map +1 -0
- package/dist/extensions/llama/provider.js +106 -0
- package/dist/extensions/llama/provider.js.map +1 -0
- package/dist/extensions/llama/ui.d.ts +42 -0
- package/dist/extensions/llama/ui.d.ts.map +1 -0
- package/dist/extensions/llama/ui.js +420 -0
- package/dist/extensions/llama/ui.js.map +1 -0
- package/dist/extensions/tokenin-onboarding.ts +3 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +21 -19
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +22 -10
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +24 -23
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +5 -5
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +17 -8
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +11 -4
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +72 -41
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +4 -4
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +14 -27
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +5 -0
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +49 -12
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +8 -5
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +253 -225
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +4 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +7 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +6 -2
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +11 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +67 -5
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts +1 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +13 -0
- package/dist/utils/clipboard.js.map +1 -1
- package/package.json +4 -4
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\taccessSync,\n\tchmodSync,\n\tconstants,\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trealpathSync,\n\tunlinkSync,\n\twriteFileSync,\n} from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { spawnProcessSync } from \"./utils/child-process.ts\";\nimport { normalizePath } from \"./utils/paths.ts\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"source\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nexport type SelfUpdatePackageTarget = string | { packageName: string; installSpec?: string };\n\nfunction normalizeSelfUpdatePackageTarget(target: SelfUpdatePackageTarget): {\n\tpackageName: string;\n\tinstallSpec: string;\n} {\n\tif (typeof target === \"string\") {\n\t\treturn { packageName: target, installSpec: target };\n\t}\n\treturn { packageName: target.packageName, installSpec: target.installSpec ?? target.packageName };\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tif (existsSync(join(getPackageDir(), \".git\"))) {\n\t\treturn \"source\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageTarget: SelfUpdatePackageTarget = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"source\": {\n\t\t\tif (target.packageName !== installedPackageName) return undefined;\n\t\t\tconst packageDir = getPackageDir();\n\t\t\tconst steps = [\n\t\t\t\tmakeSelfUpdateCommandStep(\"git\", [\"-C\", packageDir, \"pull\", \"--ff-only\"]),\n\t\t\t\tmakeSelfUpdateCommandStep(\"npm\", [\"--prefix\", packageDir, \"install\"]),\n\t\t\t\tmakeSelfUpdateCommandStep(\"npm\", [\"--prefix\", packageDir, \"run\", \"build\"]),\n\t\t\t];\n\t\t\treturn { ...steps[0], display: steps.map((step) => step.display).join(\" && \"), steps };\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst match = readCommandOutput(\"pnpm\", [\"root\", \"-g\"])\n\t\t\t\t? undefined\n\t\t\t\t: /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\tconst binDirArgs = match\n\t\t\t\t? [`--config.global-bin-dir=${process.env.PNPM_HOME || dirname(dirname(match[1]))}`]\n\t\t\t\t: [];\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--config.minimumReleaseAge=0\",\n\t\t\t\t\t...binDirArgs,\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", ...binDirArgs, installedPackageName]),\n\t\t\t);\n\t\t}\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", \"--ignore-scripts\", target.installSpec]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--minimum-release-age=0\",\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [\n\t\t\t\t...prefixArgs,\n\t\t\t\t\"install\",\n\t\t\t\t\"-g\",\n\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\"--min-release-age=0\",\n\t\t\t\ttarget.installSpec,\n\t\t\t]);\n\t\t\tconst uninstallStep =\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnProcessSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\tif (root) return [root, dirname(root)];\n\t\t\tconst match = /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\treturn match ? [match[1]] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"source\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string, resolveSymlinks: boolean): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath = resolvedPath;\n\tif (resolveSymlinks) {\n\t\ttry {\n\t\t\tnormalizedPath = realpathSync(resolvedPath);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction getPathComparisonCandidates(path: string): string[] {\n\treturn Array.from(\n\t\tnew Set(\n\t\t\t[normalizeExistingPathForComparison(path, false), normalizeExistingPathForComparison(path, true)].filter(\n\t\t\t\t(candidate): candidate is string => !!candidate,\n\t\t\t),\n\t\t),\n\t);\n}\n\nfunction getEntrypointPackageDir(): string | undefined {\n\tconst entrypoint = process.argv[1];\n\tif (!entrypoint) return undefined;\n\tlet dir = dirname(entrypoint);\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\treturn undefined;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDirs = [getPackageDir(), getEntrypointPackageDir()].filter((dir): dir is string => !!dir);\n\tconst packageDirCandidates = packageDirs.flatMap((dir) => getPathComparisonCandidates(dir));\n\treturn getGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\treturn getPathComparisonCandidates(root).some((normalizedRoot) => {\n\t\t\tconst rootPrefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;\n\t\t\treturn packageDirCandidates.some((packageDir) => packageDir.startsWith(rootPrefix));\n\t\t});\n\t});\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageTarget, npmCommand);\n\tif (!command || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\tif (method !== \"source\" && !isManagedByGlobalPackageManager(method, packageName, npmCommand)) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tif (method === \"bun-binary\") {\n\t\treturn `Download from: https://github.com/earendil-works/pi-mono/releases/latest`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, target, npmCommand);\n\tif (command) {\n\t\tif (method === \"source\") {\n\t\t\treturn isSelfUpdatePathWritable()\n\t\t\t\t? `Update the source checkout yourself with: ${command.display}`\n\t\t\t\t: `This source checkout is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${target.installSpec} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = process.env.PI_PACKAGE_DIR;\n\tif (envDir) {\n\t\treturn normalizePath(envDir);\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n/**\n * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/**\n * Resolve a bundled subdirectory shipped with the package (defaults/extensions/themes).\n * - For Bun binary: <dir>/ next to executable\n * - For Node.js (dist/): dist/<dir>/\n * - For tsx (src/): src/<dir>/\n */\nfunction getBundledSubdir(name: string): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), name);\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, name);\n}\n\n/**\n * Get path to bundled default config directory (shipped with package).\n * Holds bundled defaults. settings.json is copied on first run; models.json is loaded directly.\n */\nexport function getBundledDefaultsDir(): string {\n\treturn getBundledSubdir(\"defaults\");\n}\n\n/**\n * Get path to bundled built-in extensions directory (shipped with package).\n * Loaded directly via additionalExtensionPaths at boot (not copied into the\n * user agent dir) — same hook as CLI --extension. .ts ships as-is (jiti loads it).\n * - For Bun binary: extensions/ next to executable\n * - For Node.js (dist/): dist/extensions/\n * - For tsx (src/): src/extensions/\n */\nexport function getBundledExtensionsDir(): string {\n\treturn getBundledSubdir(\"extensions\");\n}\n\n/**\n * Get path to bundled built-in themes directory (shipped with package).\n * Loaded directly via additionalThemePaths at boot.\n */\nexport function getBundledThemesDir(): string {\n\treturn getBundledSubdir(\"themes\");\n}\n\n/**\n * Get path to bundled built-in skills directory (shipped with package).\n * Loaded directly via additionalSkillPaths at boot.\n */\nexport function getBundledSkillsDir(): string {\n\treturn getBundledSubdir(\"skills\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n// =============================================================================\n// App Config (from package.json piConfig)\n// =============================================================================\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\tpiConfig?: {\n\t\tname?: string;\n\t\tconfigDir?: string;\n\t};\n}\n\nlet pkg: PackageJson = {};\ntry {\n\tpkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n} catch (e: unknown) {\n\tconst err = e as NodeJS.ErrnoException;\n\tif (err.code !== \"ENOENT\") throw e;\n}\n\nconst piConfigName: string | undefined = pkg.piConfig?.name;\nexport const PACKAGE_NAME: string = pkg.name || \"@earendil-works/pi-coding-agent\";\nexport const APP_NAME: string = piConfigName || \"pi\";\nexport const APP_TITLE: string = piConfigName ? APP_NAME : \"π\";\nexport const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || \".pi\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\n// e.g., PI_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\treturn normalizePath(path);\n}\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://pi.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl = process.env.PI_SHARE_VIEWER_URL || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.pi/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.pi/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json */\nexport function getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n\n/**\n * Marker file written once first-time onboarding completes. Decouples the\n * first-run dialog gate from settings.json existence so that bootstrapping a\n * bundled default settings.json does not suppress the dialog.\n */\nexport function getFirstRunMarkerPath(agentDir: string = getAgentDir()): string {\n\treturn join(agentDir, \".firstRunComplete\");\n}\n\n/**\n * Mark first-run onboarding as complete. Safe to call repeatedly.\n */\nexport function markFirstRunComplete(agentDir: string = getAgentDir()): void {\n\tmkdirSync(agentDir, { recursive: true, mode: 0o700 });\n\twriteFileSync(getFirstRunMarkerPath(agentDir), \"1\", { mode: 0o600 });\n}\n\n// =============================================================================\n// Agent Dir Bootstrap (first-run seeding)\n// =============================================================================\n\n/** Subdirectories created under the agent dir on first run. */\nconst AGENT_SUBDIRS = [\n\t\"themes\",\n\t\"tools\",\n\t\"bin\",\n\t\"prompts\",\n\t\"sessions\",\n\t\"extensions\",\n\t\"skills\",\n] as const;\n\n/**\n * Ensure the agent dir and standard subdirs exist (mode 0o700 for privacy).\n * Safe to call on every startup; no-op when dirs already exist.\n */\nexport function ensureAgentDir(agentDir: string = getAgentDir()): void {\n\tmkdirSync(agentDir, { recursive: true, mode: 0o700 });\n\tfor (const sub of AGENT_SUBDIRS) {\n\t\tmkdirSync(join(agentDir, sub), { recursive: true, mode: 0o700 });\n\t}\n}\n\n/**\n * Seed a default config file from the bundled defaults dir if it does not yet\n * exist. Never overwrites an existing user file. Returns the destination path\n * when a seed was written, undefined when the file already existed or the\n * bundled source is missing.\n */\nexport function seedDefaultConfigFile(\n\tdestPath: string,\n\tbundledName: string,\n\tbundledDefaultsDir: string = getBundledDefaultsDir(),\n): string | undefined {\n\tif (existsSync(destPath)) return undefined;\n\tconst source = join(bundledDefaultsDir, bundledName);\n\tif (!existsSync(source)) return undefined;\n\tmkdirSync(dirname(destPath), { recursive: true, mode: 0o700 });\n\tcopyFileSync(source, destPath);\n\ttry {\n\t\tchmodSync(destPath, 0o600);\n\t} catch {\n\t\t// chmod is best-effort (no-op on platforms that don't support it).\n\t}\n\treturn destPath;\n}\n\n/**\n * Recursively copy a bundled directory tree into the user's agent dir, skipping\n * any file that already exists (user edits survive). Never overwrites. Used to\n * seed bundled skills/themes so the user can inspect and edit them.\n * Returns the list of destination paths that were written.\n */\nfunction seedBundledDir(\n\tdestDir: string,\n\tbundledDir: string,\n): string[] {\n\tif (!existsSync(bundledDir)) return [];\n\tmkdirSync(destDir, { recursive: true, mode: 0o700 });\n\tconst written: string[] = [];\n\tconst stack: Array<{ src: string; dst: string }> = [{ src: bundledDir, dst: destDir }];\n\twhile (stack.length > 0) {\n\t\tconst { src, dst } = stack.pop()!;\n\t\tmkdirSync(dst, { recursive: true, mode: 0o700 });\n\t\tfor (const entry of readdirSync(src, { withFileTypes: true })) {\n\t\t\tif (entry.name === \".DS_Store\" || entry.name === \"node_modules\") continue;\n\t\t\tconst srcPath = join(src, entry.name);\n\t\t\tconst dstPath = join(dst, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tif (!existsSync(dstPath)) mkdirSync(dstPath, { recursive: true, mode: 0o700 });\n\t\t\t\tstack.push({ src: srcPath, dst: dstPath });\n\t\t\t} else if (entry.isFile() || entry.isSymbolicLink()) {\n\t\t\t\tif (existsSync(dstPath)) continue;\n\t\t\t\tcopyFileSync(srcPath, dstPath);\n\t\t\t\ttry {\n\t\t\t\t\tchmodSync(dstPath, 0o600);\n\t\t\t\t} catch {\n\t\t\t\t\t// best-effort\n\t\t\t\t}\n\t\t\t\twritten.push(dstPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn written;\n}\n\nfunction removeIdenticalBundledFiles(destDir: string, bundledDir: string): string[] {\n\tif (!existsSync(destDir) || !existsSync(bundledDir)) return [];\n\tconst removed: string[] = [];\n\tconst stack: Array<{ src: string; dst: string }> = [{ src: bundledDir, dst: destDir }];\n\twhile (stack.length > 0) {\n\t\tconst { src, dst } = stack.pop()!;\n\t\tif (!existsSync(dst)) continue;\n\t\tfor (const entry of readdirSync(src, { withFileTypes: true })) {\n\t\t\tif (entry.name === \".DS_Store\" || entry.name === \"node_modules\") continue;\n\t\t\tconst srcPath = join(src, entry.name);\n\t\t\tconst dstPath = join(dst, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tstack.push({ src: srcPath, dst: dstPath });\n\t\t\t} else if (existsSync(dstPath) && readFileSync(srcPath).equals(readFileSync(dstPath))) {\n\t\t\t\tunlinkSync(dstPath);\n\t\t\t\tremoved.push(dstPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn removed;\n}\n\n/**\n * Bundled extensions load directly from the installed package. Do not copy them\n * into the user's agent dir, otherwise startup discovers both copies and tool\n * registration conflicts with itself.\n * Remove files copied by older releases only when they are byte-identical to\n * bundled files, so user-edited extensions survive.\n */\nexport function seedDefaultExtensions(\n\tagentDir: string,\n\tbundledExtensionsDir: string = getBundledExtensionsDir(),\n): string[] {\n\tremoveIdenticalBundledFiles(join(agentDir, \"extensions\"), bundledExtensionsDir);\n\treturn [];\n}\n\n/**\n * Seed bundled built-in skills into the user's agent dir/skills.\n * Skips existing files (user edits survive). Never overwrites.\n * Returns the list of destination paths that were written.\n */\nexport function seedDefaultSkills(\n\tagentDir: string,\n\tbundledSkillsDir: string = getBundledSkillsDir(),\n): string[] {\n\treturn seedBundledDir(join(agentDir, \"skills\"), bundledSkillsDir);\n}\n\n/**\n * Seed bundled built-in themes into the user's agent dir/themes.\n * Skips existing files (user edits survive). Never overwrites.\n * Returns the list of destination paths that were written.\n */\nexport function seedDefaultThemes(\n\tagentDir: string,\n\tbundledThemesDir: string = getBundledThemesDir(),\n): string[] {\n\treturn seedBundledDir(join(agentDir, \"themes\"), bundledThemesDir);\n}\n\n/**\n * Run full first-run bootstrap for the agent dir: ensure directories and seed\n * settings.json from bundled defaults. Idempotent — safe on every startup.\n * Bundled models load package-locally; copying them would expose internal\n * providers as user config. Bundled extensions also stay package-local.\n */\nexport function bootstrapAgentDir(agentDir: string = getAgentDir()): void {\n\tensureAgentDir(agentDir);\n\tseedDefaultConfigFile(join(agentDir, \"settings.json\"), \"settings.json\");\n\tseedDefaultExtensions(agentDir);\n\tseedDefaultSkills(agentDir);\n\tseedDefaultThemes(agentDir);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\taccessSync,\n\tchmodSync,\n\tconstants,\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trealpathSync,\n\tunlinkSync,\n\twriteFileSync,\n} from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { spawnProcessSync } from \"./utils/child-process.ts\";\nimport { normalizePath } from \"./utils/paths.ts\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"source\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nexport type SelfUpdatePackageTarget = string | { packageName: string; installSpec?: string };\n\nfunction normalizeSelfUpdatePackageTarget(target: SelfUpdatePackageTarget): {\n\tpackageName: string;\n\tinstallSpec: string;\n} {\n\tif (typeof target === \"string\") {\n\t\treturn { packageName: target, installSpec: target };\n\t}\n\treturn { packageName: target.packageName, installSpec: target.installSpec ?? target.packageName };\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tif (existsSync(join(getPackageDir(), \".git\"))) {\n\t\treturn \"source\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageTarget: SelfUpdatePackageTarget = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"source\": {\n\t\t\tif (target.packageName !== installedPackageName) return undefined;\n\t\t\tconst packageDir = getPackageDir();\n\t\t\tconst steps = [\n\t\t\t\tmakeSelfUpdateCommandStep(\"git\", [\"-C\", packageDir, \"pull\", \"--ff-only\"]),\n\t\t\t\tmakeSelfUpdateCommandStep(\"npm\", [\"--prefix\", packageDir, \"install\"]),\n\t\t\t\tmakeSelfUpdateCommandStep(\"npm\", [\"--prefix\", packageDir, \"run\", \"build\"]),\n\t\t\t];\n\t\t\treturn { ...steps[0], display: steps.map((step) => step.display).join(\" && \"), steps };\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst match = readCommandOutput(\"pnpm\", [\"root\", \"-g\"])\n\t\t\t\t? undefined\n\t\t\t\t: /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\tconst binDirArgs = match\n\t\t\t\t? [`--config.global-bin-dir=${process.env.PNPM_HOME || dirname(dirname(match[1]))}`]\n\t\t\t\t: [];\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--config.minimumReleaseAge=0\",\n\t\t\t\t\t...binDirArgs,\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", ...binDirArgs, installedPackageName]),\n\t\t\t);\n\t\t}\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", \"--ignore-scripts\", target.installSpec]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--minimum-release-age=0\",\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [\n\t\t\t\t...prefixArgs,\n\t\t\t\t\"install\",\n\t\t\t\t\"-g\",\n\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\"--min-release-age=0\",\n\t\t\t\ttarget.installSpec,\n\t\t\t]);\n\t\t\tconst uninstallStep =\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnProcessSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\tif (root) return [root, dirname(root)];\n\t\t\tconst match = /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\treturn match ? [match[1]] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"source\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string, resolveSymlinks: boolean): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath = resolvedPath;\n\tif (resolveSymlinks) {\n\t\ttry {\n\t\t\tnormalizedPath = realpathSync(resolvedPath);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction getPathComparisonCandidates(path: string): string[] {\n\treturn Array.from(\n\t\tnew Set(\n\t\t\t[normalizeExistingPathForComparison(path, false), normalizeExistingPathForComparison(path, true)].filter(\n\t\t\t\t(candidate): candidate is string => !!candidate,\n\t\t\t),\n\t\t),\n\t);\n}\n\nfunction getEntrypointPackageDir(): string | undefined {\n\tconst entrypoint = process.argv[1];\n\tif (!entrypoint) return undefined;\n\tlet dir = dirname(entrypoint);\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\treturn undefined;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDirs = [getPackageDir(), getEntrypointPackageDir()].filter((dir): dir is string => !!dir);\n\tconst packageDirCandidates = packageDirs.flatMap((dir) => getPathComparisonCandidates(dir));\n\treturn getGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\treturn getPathComparisonCandidates(root).some((normalizedRoot) => {\n\t\t\tconst rootPrefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;\n\t\t\treturn packageDirCandidates.some((packageDir) => packageDir.startsWith(rootPrefix));\n\t\t});\n\t});\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageTarget, npmCommand);\n\tif (!command || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\tif (method !== \"source\" && !isManagedByGlobalPackageManager(method, packageName, npmCommand)) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tif (method === \"bun-binary\") {\n\t\treturn `Download from: https://github.com/earendil-works/pi-mono/releases/latest`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, target, npmCommand);\n\tif (command) {\n\t\tif (method === \"source\") {\n\t\t\treturn isSelfUpdatePathWritable()\n\t\t\t\t? `Update the source checkout yourself with: ${command.display}`\n\t\t\t\t: `This source checkout is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${target.installSpec} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = process.env.PI_PACKAGE_DIR;\n\tif (envDir) {\n\t\treturn normalizePath(envDir);\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n/**\n * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/**\n * Resolve a bundled subdirectory shipped with the package (defaults/extensions/themes).\n * - For Bun binary: <dir>/ next to executable\n * - For Node.js (dist/): dist/<dir>/\n * - For tsx (src/): src/<dir>/\n */\nfunction getBundledSubdir(name: string): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), name);\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, name);\n}\n\n/**\n * Get path to bundled default config directory (shipped with package).\n * Holds bundled defaults. settings.json is copied on first run; models.json is loaded directly.\n */\nexport function getBundledDefaultsDir(): string {\n\treturn getBundledSubdir(\"defaults\");\n}\n\n/**\n * Get path to bundled built-in extensions directory (shipped with package).\n * Loaded directly via additionalExtensionPaths at boot (not copied into the\n * user agent dir) — same hook as CLI --extension. .ts ships as-is (jiti loads it).\n * - For Bun binary: extensions/ next to executable\n * - For Node.js (dist/): dist/extensions/\n * - For tsx (src/): src/extensions/\n */\nexport function getBundledExtensionsDir(): string {\n\treturn getBundledSubdir(\"extensions\");\n}\n\n/**\n * Get path to bundled built-in themes directory (shipped with package).\n * Loaded directly via additionalThemePaths at boot.\n */\nexport function getBundledThemesDir(): string {\n\treturn getBundledSubdir(\"themes\");\n}\n\n/**\n * Get path to bundled built-in skills directory (shipped with package).\n * Loaded directly via additionalSkillPaths at boot.\n */\nexport function getBundledSkillsDir(): string {\n\treturn getBundledSubdir(\"skills\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n// =============================================================================\n// App Config (from package.json piConfig)\n// =============================================================================\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\tpiConfig?: {\n\t\tname?: string;\n\t\tconfigDir?: string;\n\t};\n}\n\nlet pkg: PackageJson = {};\ntry {\n\tpkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n} catch (e: unknown) {\n\tconst err = e as NodeJS.ErrnoException;\n\tif (err.code !== \"ENOENT\") throw e;\n}\n\nconst piConfigName: string | undefined = pkg.piConfig?.name;\nexport const PACKAGE_NAME: string = pkg.name || \"@earendil-works/pi-coding-agent\";\nexport const APP_NAME: string = piConfigName || \"pi\";\nexport const APP_TITLE: string = piConfigName ? APP_NAME : \"π\";\nexport const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || \".pi\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\n// e.g., PI_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\treturn normalizePath(path);\n}\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://pi.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl = process.env.PI_SHARE_VIEWER_URL || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/<configured-dir>/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.selesai/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json */\nexport function getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n\n/**\n * Marker file written once first-time onboarding completes. Decouples the\n * first-run dialog gate from settings.json existence so that bootstrapping a\n * bundled default settings.json does not suppress the dialog.\n */\nexport function getFirstRunMarkerPath(agentDir: string = getAgentDir()): string {\n\treturn join(agentDir, \".firstRunComplete\");\n}\n\n/**\n * Mark first-run onboarding as complete. Safe to call repeatedly.\n */\nexport function markFirstRunComplete(agentDir: string = getAgentDir()): void {\n\tmkdirSync(agentDir, { recursive: true, mode: 0o700 });\n\twriteFileSync(getFirstRunMarkerPath(agentDir), \"1\", { mode: 0o600 });\n}\n\n// =============================================================================\n// Agent Dir Bootstrap (first-run seeding)\n// =============================================================================\n\n/** Subdirectories created under the agent dir on first run. */\nconst AGENT_SUBDIRS = [\n\t\"themes\",\n\t\"tools\",\n\t\"bin\",\n\t\"prompts\",\n\t\"sessions\",\n\t\"extensions\",\n\t\"skills\",\n] as const;\n\n/**\n * Ensure the agent dir and standard subdirs exist (mode 0o700 for privacy).\n * Safe to call on every startup; no-op when dirs already exist.\n */\nexport function ensureAgentDir(agentDir: string = getAgentDir()): void {\n\tmkdirSync(agentDir, { recursive: true, mode: 0o700 });\n\tfor (const sub of AGENT_SUBDIRS) {\n\t\tmkdirSync(join(agentDir, sub), { recursive: true, mode: 0o700 });\n\t}\n}\n\n/**\n * Seed a default config file from the bundled defaults dir if it does not yet\n * exist. Never overwrites an existing user file. Returns the destination path\n * when a seed was written, undefined when the file already existed or the\n * bundled source is missing.\n */\nexport function seedDefaultConfigFile(\n\tdestPath: string,\n\tbundledName: string,\n\tbundledDefaultsDir: string = getBundledDefaultsDir(),\n): string | undefined {\n\tif (existsSync(destPath)) return undefined;\n\tconst source = join(bundledDefaultsDir, bundledName);\n\tif (!existsSync(source)) return undefined;\n\tmkdirSync(dirname(destPath), { recursive: true, mode: 0o700 });\n\tcopyFileSync(source, destPath);\n\ttry {\n\t\tchmodSync(destPath, 0o600);\n\t} catch {\n\t\t// chmod is best-effort (no-op on platforms that don't support it).\n\t}\n\treturn destPath;\n}\n\n/**\n * Recursively copy a bundled directory tree into the user's agent dir, skipping\n * any file that already exists (user edits survive). Never overwrites. Used to\n * seed bundled skills/themes so the user can inspect and edit them.\n * Returns the list of destination paths that were written.\n */\nfunction seedBundledDir(\n\tdestDir: string,\n\tbundledDir: string,\n): string[] {\n\tif (!existsSync(bundledDir)) return [];\n\tmkdirSync(destDir, { recursive: true, mode: 0o700 });\n\tconst written: string[] = [];\n\tconst stack: Array<{ src: string; dst: string }> = [{ src: bundledDir, dst: destDir }];\n\twhile (stack.length > 0) {\n\t\tconst { src, dst } = stack.pop()!;\n\t\tmkdirSync(dst, { recursive: true, mode: 0o700 });\n\t\tfor (const entry of readdirSync(src, { withFileTypes: true })) {\n\t\t\tif (entry.name === \".DS_Store\" || entry.name === \"node_modules\") continue;\n\t\t\tconst srcPath = join(src, entry.name);\n\t\t\tconst dstPath = join(dst, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tif (!existsSync(dstPath)) mkdirSync(dstPath, { recursive: true, mode: 0o700 });\n\t\t\t\tstack.push({ src: srcPath, dst: dstPath });\n\t\t\t} else if (entry.isFile() || entry.isSymbolicLink()) {\n\t\t\t\tif (existsSync(dstPath)) continue;\n\t\t\t\tcopyFileSync(srcPath, dstPath);\n\t\t\t\ttry {\n\t\t\t\t\tchmodSync(dstPath, 0o600);\n\t\t\t\t} catch {\n\t\t\t\t\t// best-effort\n\t\t\t\t}\n\t\t\t\twritten.push(dstPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn written;\n}\n\nfunction removeIdenticalBundledFiles(destDir: string, bundledDir: string): string[] {\n\tif (!existsSync(destDir) || !existsSync(bundledDir)) return [];\n\tconst removed: string[] = [];\n\tconst stack: Array<{ src: string; dst: string }> = [{ src: bundledDir, dst: destDir }];\n\twhile (stack.length > 0) {\n\t\tconst { src, dst } = stack.pop()!;\n\t\tif (!existsSync(dst)) continue;\n\t\tfor (const entry of readdirSync(src, { withFileTypes: true })) {\n\t\t\tif (entry.name === \".DS_Store\" || entry.name === \"node_modules\") continue;\n\t\t\tconst srcPath = join(src, entry.name);\n\t\t\tconst dstPath = join(dst, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tstack.push({ src: srcPath, dst: dstPath });\n\t\t\t} else if (existsSync(dstPath) && readFileSync(srcPath).equals(readFileSync(dstPath))) {\n\t\t\t\tunlinkSync(dstPath);\n\t\t\t\tremoved.push(dstPath);\n\t\t\t}\n\t\t}\n\t}\n\treturn removed;\n}\n\n/**\n * Bundled extensions load directly from the installed package. Do not copy them\n * into the user's agent dir, otherwise startup discovers both copies and tool\n * registration conflicts with itself.\n * Remove files copied by older releases only when they are byte-identical to\n * bundled files, so user-edited extensions survive.\n */\nexport function seedDefaultExtensions(\n\tagentDir: string,\n\tbundledExtensionsDir: string = getBundledExtensionsDir(),\n): string[] {\n\tremoveIdenticalBundledFiles(join(agentDir, \"extensions\"), bundledExtensionsDir);\n\treturn [];\n}\n\n/**\n * Seed bundled built-in skills into the user's agent dir/skills.\n * Skips existing files (user edits survive). Never overwrites.\n * Returns the list of destination paths that were written.\n */\nexport function seedDefaultSkills(\n\tagentDir: string,\n\tbundledSkillsDir: string = getBundledSkillsDir(),\n): string[] {\n\treturn seedBundledDir(join(agentDir, \"skills\"), bundledSkillsDir);\n}\n\n/**\n * Seed bundled built-in themes into the user's agent dir/themes.\n * Skips existing files (user edits survive). Never overwrites.\n * Returns the list of destination paths that were written.\n */\nexport function seedDefaultThemes(\n\tagentDir: string,\n\tbundledThemesDir: string = getBundledThemesDir(),\n): string[] {\n\treturn seedBundledDir(join(agentDir, \"themes\"), bundledThemesDir);\n}\n\n/**\n * Run full first-run bootstrap for the agent dir: ensure directories and seed\n * settings.json from bundled defaults. Idempotent — safe on every startup.\n * Bundled models load package-locally; copying them would expose internal\n * providers as user config. Bundled extensions also stay package-local.\n */\nexport function bootstrapAgentDir(agentDir: string = getAgentDir()): void {\n\tensureAgentDir(agentDir);\n\tseedDefaultConfigFile(join(agentDir, \"settings.json\"), \"settings.json\");\n\tseedDefaultExtensions(agentDir);\n\tseedDefaultSkills(agentDir);\n\tseedDefaultThemes(agentDir);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-auto-handoff.test.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-auto-handoff.test.ts"],"names":[],"mappings":"","sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport type { ExtensionRunner } from \"./extensions/runner.ts\";\nimport type { ResolvedCommand } from \"./extensions/types.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\nfunction createMockSession({\n\tenabled,\n\tthreshold = 128_000,\n\ttokens,\n\tmode = \"tui\",\n\tcommand,\n}: {\n\tenabled: boolean;\n\tthreshold?: number;\n\ttokens: number | null;\n\tmode?: \"tui\" | \"print\" | \"rpc\";\n\tcommand?: ResolvedCommand | undefined;\n}) {\n\tconst settings = SettingsManager.inMemory({\n\t\tautoHandoff: { enabled, thresholdTokens: threshold },\n\t});\n\n\tconst getCommand = vi.fn(() => command);\n\tconst handler = command?.handler ?? vi.fn();\n\tconst createCommandContext = vi.fn(() => ({ mock: \"ctx\" }) as unknown as never);\n\tconst emitError = vi.fn();\n\n\tconst extensionRunner = {\n\t\tgetCommand,\n\t\tcreateCommandContext,\n\t\temitError,\n\t\temit: vi.fn(),\n\t} as unknown as ExtensionRunner;\n\n\tconst resourceLoader = {\n\t\tgetExtensions: () => ({ extensions: [], errors: [], runtime: { flagValues: new Map(), pendingProviderRegistrations: [], assertActive: () => {} } }),\n\t\tgetSkills: () => ({ skills: [], diagnostics: [] }),\n\t\tgetPrompts: () => ({ prompts: [], diagnostics: [] }),\n\t\tgetThemes: () => ({ themes: [], diagnostics: [] }),\n\t\tgetAgents: () => ({ agents: [], diagnostics: [] }),\n\t\tgetAgentsFiles: () => ({ agentsFiles: [] }),\n\t\tgetSystemPrompt: () => undefined,\n\t\tgetAppendSystemPrompt: () => [],\n\t\tgetExtensionDiagnostics: () => [],\n\t\textendResources: () => {},\n\t\treload: vi.fn(),\n\t};\n\n\tconst modelRegistry = {\n\t\tregisterProvider: vi.fn(),\n\t\tunregisterProvider: vi.fn(),\n\t\tgetProvider: vi.fn(),\n\t\tgetProviders: vi.fn(() => []),\n\t\tgetModels: vi.fn(() => []),\n\t};\n\n\tconst agent = {\n\t\tstate: { messages: [], tools: [] },\n\t\tsubscribe: vi.fn(() => () => {}),\n\t};\n\n\tconst session = new AgentSession({\n\t\tagent: agent as unknown as never,\n\t\tsessionManager: { getBranch: () => [] } as unknown as never,\n\t\tsettingsManager: settings,\n\t\tcwd: \"/tmp\",\n\t\tresourceLoader: resourceLoader as unknown as never,\n\t\
|
|
1
|
+
{"version":3,"file":"agent-session-auto-handoff.test.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-auto-handoff.test.ts"],"names":[],"mappings":"","sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport type { ExtensionRunner } from \"./extensions/runner.ts\";\nimport type { ResolvedCommand } from \"./extensions/types.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\nfunction createMockSession({\n\tenabled,\n\tthreshold = 128_000,\n\ttokens,\n\tmode = \"tui\",\n\tcommand,\n}: {\n\tenabled: boolean;\n\tthreshold?: number;\n\ttokens: number | null;\n\tmode?: \"tui\" | \"print\" | \"rpc\";\n\tcommand?: ResolvedCommand | undefined;\n}) {\n\tconst settings = SettingsManager.inMemory({\n\t\tautoHandoff: { enabled, thresholdTokens: threshold },\n\t});\n\n\tconst getCommand = vi.fn(() => command);\n\tconst handler = command?.handler ?? vi.fn();\n\tconst createCommandContext = vi.fn(() => ({ mock: \"ctx\" }) as unknown as never);\n\tconst emitError = vi.fn();\n\n\tconst extensionRunner = {\n\t\tgetCommand,\n\t\tcreateCommandContext,\n\t\temitError,\n\t\temit: vi.fn(),\n\t} as unknown as ExtensionRunner;\n\n\tconst resourceLoader = {\n\t\tgetExtensions: () => ({ extensions: [], errors: [], runtime: { flagValues: new Map(), pendingProviderRegistrations: [], pendingNativeProviderRegistrations: [], assertActive: () => {} } }),\n\t\tgetSkills: () => ({ skills: [], diagnostics: [] }),\n\t\tgetPrompts: () => ({ prompts: [], diagnostics: [] }),\n\t\tgetThemes: () => ({ themes: [], diagnostics: [] }),\n\t\tgetAgents: () => ({ agents: [], diagnostics: [] }),\n\t\tgetAgentsFiles: () => ({ agentsFiles: [] }),\n\t\tgetSystemPrompt: () => undefined,\n\t\tgetAppendSystemPrompt: () => [],\n\t\tgetExtensionDiagnostics: () => [],\n\t\textendResources: () => {},\n\t\treload: vi.fn(),\n\t};\n\n\tconst modelRegistry = {\n\t\tregisterProvider: vi.fn(),\n\t\tunregisterProvider: vi.fn(),\n\t\tgetProvider: vi.fn(),\n\t\tgetProviders: vi.fn(() => []),\n\t\tgetModels: vi.fn(() => []),\n\t};\n\n\tconst agent = {\n\t\tstate: { messages: [], tools: [] },\n\t\tsubscribe: vi.fn(() => () => {}),\n\t};\n\n\tconst session = new AgentSession({\n\t\tagent: agent as unknown as never,\n\t\tsessionManager: { getBranch: () => [] } as unknown as never,\n\t\tsettingsManager: settings,\n\t\tcwd: \"/tmp\",\n\t\tresourceLoader: resourceLoader as unknown as never,\n\t\tmodelRuntime: modelRegistry as unknown as never,\n\t});\n\n\t(session as any)._extensionRunner = extensionRunner;\n\t(session as any)._extensionMode = mode;\n\t(session as any).getContextUsage = () =>\n\t\ttokens === null ? null : { tokens, contextWindow: 200_000, percent: tokens / 200_000 };\n\n\treturn { session, getCommand, createCommandContext, handler, emitError, settings };\n}\n\ndescribe(\"AgentSession auto handoff\", () => {\n\tit(\"invokes handoff-new once when enabled and threshold reached in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand, createCommandContext, emitError } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 128_000,\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t\texpect(createCommandContext).toHaveBeenCalled();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t\texpect(command.handler).toHaveBeenCalledWith(\"\", expect.anything());\n\t\texpect(emitError).not.toHaveBeenCalled();\n\t});\n\n\tit(\"dispatches auto handoff via _emitAgentSettled in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({ enabled: true, tokens: 200_000, command });\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t});\n\n\tit(\"_emitAgentSettled does not auto-handoff in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"print\",\n\t\t\tcommand,\n\t\t});\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when disabled\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: false, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 127_999, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are null\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: null, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"rpc\",\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when handoff-new command is not registered\", async () => {\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command: undefined });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t});\n\n\tit(\"emits error when handoff-new throws but does not rethrow\", async () => {\n\t\tconst command = {\n\t\t\thandler: vi.fn(() => Promise.reject(new Error(\"boom\"))),\n\t\t} as unknown as ResolvedCommand;\n\t\tconst { session, emitError } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait expect((session as any)._checkAutoHandoff()).resolves.toBeUndefined();\n\n\t\texpect(emitError).toHaveBeenCalledWith({\n\t\t\textensionPath: \"command:handoff-new\",\n\t\t\tevent: \"auto-handoff\",\n\t\t\terror: \"boom\",\n\t\t});\n\t});\n\n\tit(\"resets triggered flag when tokens drop below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\n\t\t// Simulate tokens dropping below threshold (e.g. compaction/new session)\n\t\t(session as any).getContextUsage = () => ({ tokens: 1000, contextWindow: 200_000, percent: 0.5 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1); // still once\n\n\t\t// Tokens rise above threshold again\n\t\t(session as any).getContextUsage = () => ({ tokens: 200_000, contextWindow: 200_000, percent: 100 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(2);\n\t});\n});\n"]}
|
|
@@ -16,7 +16,7 @@ function createMockSession({ enabled, threshold = 128_000, tokens, mode = "tui",
|
|
|
16
16
|
emit: vi.fn(),
|
|
17
17
|
};
|
|
18
18
|
const resourceLoader = {
|
|
19
|
-
getExtensions: () => ({ extensions: [], errors: [], runtime: { flagValues: new Map(), pendingProviderRegistrations: [], assertActive: () => { } } }),
|
|
19
|
+
getExtensions: () => ({ extensions: [], errors: [], runtime: { flagValues: new Map(), pendingProviderRegistrations: [], pendingNativeProviderRegistrations: [], assertActive: () => { } } }),
|
|
20
20
|
getSkills: () => ({ skills: [], diagnostics: [] }),
|
|
21
21
|
getPrompts: () => ({ prompts: [], diagnostics: [] }),
|
|
22
22
|
getThemes: () => ({ themes: [], diagnostics: [] }),
|
|
@@ -45,7 +45,7 @@ function createMockSession({ enabled, threshold = 128_000, tokens, mode = "tui",
|
|
|
45
45
|
settingsManager: settings,
|
|
46
46
|
cwd: "/tmp",
|
|
47
47
|
resourceLoader: resourceLoader,
|
|
48
|
-
|
|
48
|
+
modelRuntime: modelRegistry,
|
|
49
49
|
});
|
|
50
50
|
session._extensionRunner = extensionRunner;
|
|
51
51
|
session._extensionMode = mode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-auto-handoff.test.js","sourceRoot":"","sources":["../../src/core/agent-session-auto-handoff.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport type { ExtensionRunner } from \"./extensions/runner.ts\";\nimport type { ResolvedCommand } from \"./extensions/types.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\nfunction createMockSession({\n\tenabled,\n\tthreshold = 128_000,\n\ttokens,\n\tmode = \"tui\",\n\tcommand,\n}: {\n\tenabled: boolean;\n\tthreshold?: number;\n\ttokens: number | null;\n\tmode?: \"tui\" | \"print\" | \"rpc\";\n\tcommand?: ResolvedCommand | undefined;\n}) {\n\tconst settings = SettingsManager.inMemory({\n\t\tautoHandoff: { enabled, thresholdTokens: threshold },\n\t});\n\n\tconst getCommand = vi.fn(() => command);\n\tconst handler = command?.handler ?? vi.fn();\n\tconst createCommandContext = vi.fn(() => ({ mock: \"ctx\" }) as unknown as never);\n\tconst emitError = vi.fn();\n\n\tconst extensionRunner = {\n\t\tgetCommand,\n\t\tcreateCommandContext,\n\t\temitError,\n\t\temit: vi.fn(),\n\t} as unknown as ExtensionRunner;\n\n\tconst resourceLoader = {\n\t\tgetExtensions: () => ({ extensions: [], errors: [], runtime: { flagValues: new Map(), pendingProviderRegistrations: [], assertActive: () => {} } }),\n\t\tgetSkills: () => ({ skills: [], diagnostics: [] }),\n\t\tgetPrompts: () => ({ prompts: [], diagnostics: [] }),\n\t\tgetThemes: () => ({ themes: [], diagnostics: [] }),\n\t\tgetAgents: () => ({ agents: [], diagnostics: [] }),\n\t\tgetAgentsFiles: () => ({ agentsFiles: [] }),\n\t\tgetSystemPrompt: () => undefined,\n\t\tgetAppendSystemPrompt: () => [],\n\t\tgetExtensionDiagnostics: () => [],\n\t\textendResources: () => {},\n\t\treload: vi.fn(),\n\t};\n\n\tconst modelRegistry = {\n\t\tregisterProvider: vi.fn(),\n\t\tunregisterProvider: vi.fn(),\n\t\tgetProvider: vi.fn(),\n\t\tgetProviders: vi.fn(() => []),\n\t\tgetModels: vi.fn(() => []),\n\t};\n\n\tconst agent = {\n\t\tstate: { messages: [], tools: [] },\n\t\tsubscribe: vi.fn(() => () => {}),\n\t};\n\n\tconst session = new AgentSession({\n\t\tagent: agent as unknown as never,\n\t\tsessionManager: { getBranch: () => [] } as unknown as never,\n\t\tsettingsManager: settings,\n\t\tcwd: \"/tmp\",\n\t\tresourceLoader: resourceLoader as unknown as never,\n\t\tmodelRegistry: modelRegistry as unknown as never,\n\t});\n\n\t(session as any)._extensionRunner = extensionRunner;\n\t(session as any)._extensionMode = mode;\n\t(session as any).getContextUsage = () =>\n\t\ttokens === null ? null : { tokens, contextWindow: 200_000, percent: tokens / 200_000 };\n\n\treturn { session, getCommand, createCommandContext, handler, emitError, settings };\n}\n\ndescribe(\"AgentSession auto handoff\", () => {\n\tit(\"invokes handoff-new once when enabled and threshold reached in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand, createCommandContext, emitError } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 128_000,\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t\texpect(createCommandContext).toHaveBeenCalled();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t\texpect(command.handler).toHaveBeenCalledWith(\"\", expect.anything());\n\t\texpect(emitError).not.toHaveBeenCalled();\n\t});\n\n\tit(\"dispatches auto handoff via _emitAgentSettled in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({ enabled: true, tokens: 200_000, command });\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t});\n\n\tit(\"_emitAgentSettled does not auto-handoff in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"print\",\n\t\t\tcommand,\n\t\t});\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when disabled\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: false, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 127_999, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are null\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: null, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"rpc\",\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when handoff-new command is not registered\", async () => {\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command: undefined });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t});\n\n\tit(\"emits error when handoff-new throws but does not rethrow\", async () => {\n\t\tconst command = {\n\t\t\thandler: vi.fn(() => Promise.reject(new Error(\"boom\"))),\n\t\t} as unknown as ResolvedCommand;\n\t\tconst { session, emitError } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait expect((session as any)._checkAutoHandoff()).resolves.toBeUndefined();\n\n\t\texpect(emitError).toHaveBeenCalledWith({\n\t\t\textensionPath: \"command:handoff-new\",\n\t\t\tevent: \"auto-handoff\",\n\t\t\terror: \"boom\",\n\t\t});\n\t});\n\n\tit(\"resets triggered flag when tokens drop below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\n\t\t// Simulate tokens dropping below threshold (e.g. compaction/new session)\n\t\t(session as any).getContextUsage = () => ({ tokens: 1000, contextWindow: 200_000, percent: 0.5 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1); // still once\n\n\t\t// Tokens rise above threshold again\n\t\t(session as any).getContextUsage = () => ({ tokens: 200_000, contextWindow: 200_000, percent: 100 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(2);\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"agent-session-auto-handoff.test.js","sourceRoot":"","sources":["../../src/core/agent-session-auto-handoff.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport type { ExtensionRunner } from \"./extensions/runner.ts\";\nimport type { ResolvedCommand } from \"./extensions/types.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\nfunction createMockSession({\n\tenabled,\n\tthreshold = 128_000,\n\ttokens,\n\tmode = \"tui\",\n\tcommand,\n}: {\n\tenabled: boolean;\n\tthreshold?: number;\n\ttokens: number | null;\n\tmode?: \"tui\" | \"print\" | \"rpc\";\n\tcommand?: ResolvedCommand | undefined;\n}) {\n\tconst settings = SettingsManager.inMemory({\n\t\tautoHandoff: { enabled, thresholdTokens: threshold },\n\t});\n\n\tconst getCommand = vi.fn(() => command);\n\tconst handler = command?.handler ?? vi.fn();\n\tconst createCommandContext = vi.fn(() => ({ mock: \"ctx\" }) as unknown as never);\n\tconst emitError = vi.fn();\n\n\tconst extensionRunner = {\n\t\tgetCommand,\n\t\tcreateCommandContext,\n\t\temitError,\n\t\temit: vi.fn(),\n\t} as unknown as ExtensionRunner;\n\n\tconst resourceLoader = {\n\t\tgetExtensions: () => ({ extensions: [], errors: [], runtime: { flagValues: new Map(), pendingProviderRegistrations: [], pendingNativeProviderRegistrations: [], assertActive: () => {} } }),\n\t\tgetSkills: () => ({ skills: [], diagnostics: [] }),\n\t\tgetPrompts: () => ({ prompts: [], diagnostics: [] }),\n\t\tgetThemes: () => ({ themes: [], diagnostics: [] }),\n\t\tgetAgents: () => ({ agents: [], diagnostics: [] }),\n\t\tgetAgentsFiles: () => ({ agentsFiles: [] }),\n\t\tgetSystemPrompt: () => undefined,\n\t\tgetAppendSystemPrompt: () => [],\n\t\tgetExtensionDiagnostics: () => [],\n\t\textendResources: () => {},\n\t\treload: vi.fn(),\n\t};\n\n\tconst modelRegistry = {\n\t\tregisterProvider: vi.fn(),\n\t\tunregisterProvider: vi.fn(),\n\t\tgetProvider: vi.fn(),\n\t\tgetProviders: vi.fn(() => []),\n\t\tgetModels: vi.fn(() => []),\n\t};\n\n\tconst agent = {\n\t\tstate: { messages: [], tools: [] },\n\t\tsubscribe: vi.fn(() => () => {}),\n\t};\n\n\tconst session = new AgentSession({\n\t\tagent: agent as unknown as never,\n\t\tsessionManager: { getBranch: () => [] } as unknown as never,\n\t\tsettingsManager: settings,\n\t\tcwd: \"/tmp\",\n\t\tresourceLoader: resourceLoader as unknown as never,\n\t\tmodelRuntime: modelRegistry as unknown as never,\n\t});\n\n\t(session as any)._extensionRunner = extensionRunner;\n\t(session as any)._extensionMode = mode;\n\t(session as any).getContextUsage = () =>\n\t\ttokens === null ? null : { tokens, contextWindow: 200_000, percent: tokens / 200_000 };\n\n\treturn { session, getCommand, createCommandContext, handler, emitError, settings };\n}\n\ndescribe(\"AgentSession auto handoff\", () => {\n\tit(\"invokes handoff-new once when enabled and threshold reached in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand, createCommandContext, emitError } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 128_000,\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t\texpect(createCommandContext).toHaveBeenCalled();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t\texpect(command.handler).toHaveBeenCalledWith(\"\", expect.anything());\n\t\texpect(emitError).not.toHaveBeenCalled();\n\t});\n\n\tit(\"dispatches auto handoff via _emitAgentSettled in tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({ enabled: true, tokens: 200_000, command });\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\t});\n\n\tit(\"_emitAgentSettled does not auto-handoff in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"print\",\n\t\t\tcommand,\n\t\t});\n\t\tconst events: string[] = [];\n\t\tsession.subscribe((event) => {\n\t\t\tif (event.type === \"agent_settled\") events.push(event.type);\n\t\t});\n\n\t\tawait (session as any)._emitAgentSettled();\n\n\t\texpect(events).toEqual([\"agent_settled\"]);\n\t\texpect(command.handler).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when disabled\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: false, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 127_999, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when tokens are null\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: null, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing in non-tui mode\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({\n\t\t\tenabled: true,\n\t\t\ttokens: 200_000,\n\t\t\tmode: \"rpc\",\n\t\t\tcommand,\n\t\t});\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).not.toHaveBeenCalled();\n\t});\n\n\tit(\"does nothing when handoff-new command is not registered\", async () => {\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command: undefined });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\n\t\texpect(getCommand).toHaveBeenCalledWith(\"handoff-new\");\n\t});\n\n\tit(\"emits error when handoff-new throws but does not rethrow\", async () => {\n\t\tconst command = {\n\t\t\thandler: vi.fn(() => Promise.reject(new Error(\"boom\"))),\n\t\t} as unknown as ResolvedCommand;\n\t\tconst { session, emitError } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait expect((session as any)._checkAutoHandoff()).resolves.toBeUndefined();\n\n\t\texpect(emitError).toHaveBeenCalledWith({\n\t\t\textensionPath: \"command:handoff-new\",\n\t\t\tevent: \"auto-handoff\",\n\t\t\terror: \"boom\",\n\t\t});\n\t});\n\n\tit(\"resets triggered flag when tokens drop below threshold\", async () => {\n\t\tconst command = { handler: vi.fn() } as unknown as ResolvedCommand;\n\t\tconst { session, getCommand } = createMockSession({ enabled: true, tokens: 200_000, command });\n\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1);\n\n\t\t// Simulate tokens dropping below threshold (e.g. compaction/new session)\n\t\t(session as any).getContextUsage = () => ({ tokens: 1000, contextWindow: 200_000, percent: 0.5 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(1); // still once\n\n\t\t// Tokens rise above threshold again\n\t\t(session as any).getContextUsage = () => ({ tokens: 200_000, contextWindow: 200_000, percent: 100 });\n\t\tawait (session as any)._checkAutoHandoff();\n\t\texpect(command.handler).toHaveBeenCalledTimes(2);\n\t});\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-runtime.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { copyFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { basename, join, resolve } from \"node:path\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport type { AgentSession } from \"./agent-session.ts\";\nimport type { AgentSessionRuntimeDiagnostic, AgentSessionServices } from \"./agent-session-services.ts\";\nimport type {\n\tProjectTrustContext,\n\tReplacedSessionContext,\n\tSessionShutdownEvent,\n\tSessionStartEvent,\n} from \"./extensions/index.ts\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.ts\";\nimport type { CreateAgentSessionResult } from \"./sdk.ts\";\nimport { assertSessionCwdExists } from \"./session-cwd.ts\";\nimport { SessionManager } from \"./session-manager.ts\";\n\n/**\n * Result returned by runtime creation.\n *\n * The caller gets the created session, its cwd-bound services, and all\n * diagnostics collected during setup.\n */\nexport interface CreateAgentSessionRuntimeResult extends CreateAgentSessionResult {\n\tservices: AgentSessionServices;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n}\n\n/**\n * Creates a full runtime for a target cwd and session manager.\n *\n * The factory closes over process-global fixed inputs, recreates cwd-bound\n * services for the effective cwd, resolves session options against those\n * services, and finally creates the AgentSession.\n */\nexport type CreateAgentSessionRuntimeFactory = (options: {\n\tcwd: string;\n\tagentDir: string;\n\tsessionManager: SessionManager;\n\tsessionStartEvent?: SessionStartEvent;\n\tprojectTrustContext?: ProjectTrustContext;\n}) => Promise<CreateAgentSessionRuntimeResult>;\n\n/**\n * Thrown when /import references a JSONL file path that does not exist.\n */\nexport class SessionImportFileNotFoundError extends Error {\n\treadonly filePath: string;\n\n\tconstructor(filePath: string) {\n\t\tsuper(`File not found: ${filePath}`);\n\t\tthis.name = \"SessionImportFileNotFoundError\";\n\t\tthis.filePath = filePath;\n\t}\n}\n\nfunction extractUserMessageText(content: string | Array<{ type: string; text?: string }>): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is { type: \"text\"; text: string } => part.type === \"text\" && typeof part.text === \"string\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\");\n}\n\n/**\n * Owns the current AgentSession plus its cwd-bound services.\n *\n * Session replacement methods tear down the current runtime first, then create\n * and apply the next runtime. If creation fails, the error is propagated to the\n * caller. The caller is responsible for user-facing error handling.\n */\nexport class AgentSessionRuntime {\n\tprivate rebindSession?: (session: AgentSession) => Promise<void>;\n\tprivate beforeSessionInvalidate?: () => void;\n\tprivate _session: AgentSession;\n\tprivate _services: AgentSessionServices;\n\tprivate readonly createRuntime: CreateAgentSessionRuntimeFactory;\n\tprivate _diagnostics: AgentSessionRuntimeDiagnostic[];\n\tprivate _modelFallbackMessage?: string;\n\n\tconstructor(\n\t\t_session: AgentSession,\n\t\t_services: AgentSessionServices,\n\t\tcreateRuntime: CreateAgentSessionRuntimeFactory,\n\t\t_diagnostics: AgentSessionRuntimeDiagnostic[] = [],\n\t\t_modelFallbackMessage?: string,\n\t) {\n\t\tthis._session = _session;\n\t\tthis._services = _services;\n\t\tthis.createRuntime = createRuntime;\n\t\tthis._diagnostics = _diagnostics;\n\t\tthis._modelFallbackMessage = _modelFallbackMessage;\n\t}\n\n\tget services(): AgentSessionServices {\n\t\treturn this._services;\n\t}\n\n\tget session(): AgentSession {\n\t\treturn this._session;\n\t}\n\n\tget cwd(): string {\n\t\treturn this._services.cwd;\n\t}\n\n\tget diagnostics(): readonly AgentSessionRuntimeDiagnostic[] {\n\t\treturn this._diagnostics;\n\t}\n\n\tget modelFallbackMessage(): string | undefined {\n\t\treturn this._modelFallbackMessage;\n\t}\n\n\tsetRebindSession(rebindSession?: (session: AgentSession) => Promise<void>): void {\n\t\tthis.rebindSession = rebindSession;\n\t}\n\n\t/**\n\t * Set a synchronous callback that runs after `session_shutdown` handlers finish\n\t * but before the current session is invalidated.\n\t *\n\t * This is for host-owned UI teardown that must not yield to the event loop,\n\t * such as detaching extension-provided TUI components before the old extension\n\t * context becomes stale.\n\t */\n\tsetBeforeSessionInvalidate(beforeSessionInvalidate?: () => void): void {\n\t\tthis.beforeSessionInvalidate = beforeSessionInvalidate;\n\t}\n\n\tprivate async emitBeforeSwitch(\n\t\treason: \"new\" | \"resume\",\n\t\ttargetSessionFile?: string,\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst runner = this.session.extensionRunner;\n\t\tif (!runner.hasHandlers(\"session_before_switch\")) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\tconst result = await runner.emit({\n\t\t\ttype: \"session_before_switch\",\n\t\t\treason,\n\t\t\ttargetSessionFile,\n\t\t});\n\t\treturn { cancelled: result?.cancel === true };\n\t}\n\n\tprivate async emitBeforeFork(\n\t\tentryId: string,\n\t\toptions: { position: \"before\" | \"at\" },\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst runner = this.session.extensionRunner;\n\t\tif (!runner.hasHandlers(\"session_before_fork\")) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\tconst result = await runner.emit({\n\t\t\ttype: \"session_before_fork\",\n\t\t\tentryId,\n\t\t\t...options,\n\t\t});\n\t\treturn { cancelled: result?.cancel === true };\n\t}\n\n\tprivate async teardownCurrent(reason: SessionShutdownEvent[\"reason\"], targetSessionFile?: string): Promise<void> {\n\t\tawait emitSessionShutdownEvent(this.session.extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason,\n\t\t\ttargetSessionFile,\n\t\t});\n\t\tthis.beforeSessionInvalidate?.();\n\t\tthis.session.dispose();\n\t}\n\n\tprivate apply(result: CreateAgentSessionRuntimeResult): void {\n\t\tthis._session = result.session;\n\t\tthis._services = result.services;\n\t\tthis._diagnostics = result.diagnostics;\n\t\tthis._modelFallbackMessage = result.modelFallbackMessage;\n\t}\n\n\tprivate async finishSessionReplacement(withSession?: (ctx: ReplacedSessionContext) => Promise<void>): Promise<void> {\n\t\tif (this.rebindSession) {\n\t\t\tawait this.rebindSession(this.session);\n\t\t}\n\t\tif (withSession) {\n\t\t\tawait withSession(this.session.createReplacedSessionContext());\n\t\t}\n\t}\n\n\tasync switchSession(\n\t\tsessionPath: string,\n\t\toptions?: {\n\t\t\tcwdOverride?: string;\n\t\t\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\t\t\tprojectTrustContextFactory?: (cwd: string) => ProjectTrustContext;\n\t\t},\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"resume\", sessionPath);\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tconst sessionManager = SessionManager.open(sessionPath, undefined, options?.cwdOverride);\n\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\tawait this.teardownCurrent(\"resume\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: sessionManager.getCwd(),\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"resume\", previousSessionFile },\n\t\t\t\tprojectTrustContext: options?.projectTrustContextFactory?.(sessionManager.getCwd()),\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false };\n\t}\n\n\tasync newSession(options?: {\n\t\tparentSession?: string;\n\t\tsetup?: (sessionManager: SessionManager) => Promise<void>;\n\t\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\t}): Promise<{ cancelled: boolean }> {\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"new\");\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tconst sessionDir = this.session.sessionManager.getSessionDir();\n\t\tconst sessionManager = this.session.sessionManager.isPersisted()\n\t\t\t? SessionManager.create(this.cwd, sessionDir)\n\t\t\t: SessionManager.inMemory(this.cwd);\n\t\tif (options?.parentSession) {\n\t\t\tsessionManager.newSession({ parentSession: options.parentSession });\n\t\t}\n\n\t\tawait this.teardownCurrent(\"new\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: this.cwd,\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"new\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tif (options?.setup) {\n\t\t\tawait options.setup(this.session.sessionManager);\n\t\t\tthis.session.agent.state.messages = this.session.sessionManager.buildSessionContext().messages;\n\t\t}\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false };\n\t}\n\n\tasync fork(\n\t\tentryId: string,\n\t\toptions?: { position?: \"before\" | \"at\"; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean; selectedText?: string }> {\n\t\tconst position = options?.position ?? \"before\";\n\t\tconst beforeResult = await this.emitBeforeFork(entryId, { position });\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn { cancelled: true };\n\t\t}\n\t\tlet targetLeafId: string | null;\n\t\tlet selectedText: string | undefined;\n\n\t\tconst selectedEntry = this.session.sessionManager.getEntry(entryId);\n\t\tif (!selectedEntry) {\n\t\t\tthrow new Error(\"Invalid entry ID for forking\");\n\t\t}\n\n\t\tif (position === \"at\") {\n\t\t\ttargetLeafId = selectedEntry.id;\n\t\t} else {\n\t\t\tif (selectedEntry.type !== \"message\" || selectedEntry.message.role !== \"user\") {\n\t\t\t\tthrow new Error(\"Invalid entry ID for forking\");\n\t\t\t}\n\t\t\ttargetLeafId = selectedEntry.parentId;\n\t\t\tselectedText = extractUserMessageText(selectedEntry.message.content);\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tif (this.session.sessionManager.isPersisted()) {\n\t\t\tconst currentSessionFile = this.session.sessionFile;\n\t\t\tif (!currentSessionFile) {\n\t\t\t\tthrow new Error(\"Persisted session is missing a session file\");\n\t\t\t}\n\t\t\tconst sessionDir = this.session.sessionManager.getSessionDir();\n\t\t\tif (!targetLeafId) {\n\t\t\t\tconst sessionManager = SessionManager.create(this.cwd, sessionDir);\n\t\t\t\tsessionManager.newSession({ parentSession: currentSessionFile });\n\t\t\t\tawait this.teardownCurrent(\"fork\", sessionManager.getSessionFile());\n\t\t\t\tthis.apply(\n\t\t\t\t\tawait this.createRuntime({\n\t\t\t\t\t\tcwd: this.cwd,\n\t\t\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\t\t\tsessionManager,\n\t\t\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"fork\", previousSessionFile },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\t\t\treturn { cancelled: false, selectedText };\n\t\t\t}\n\n\t\t\tconst sessionManager = SessionManager.open(currentSessionFile, sessionDir);\n\t\t\tconst forkedSessionPath = sessionManager.createBranchedSession(targetLeafId);\n\t\t\tif (!forkedSessionPath) {\n\t\t\t\tthrow new Error(\"Failed to create forked session\");\n\t\t\t}\n\t\t\tawait this.teardownCurrent(\"fork\", sessionManager.getSessionFile());\n\t\t\tthis.apply(\n\t\t\t\tawait this.createRuntime({\n\t\t\t\t\tcwd: sessionManager.getCwd(),\n\t\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\t\tsessionManager,\n\t\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"fork\", previousSessionFile },\n\t\t\t\t}),\n\t\t\t);\n\t\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\t\treturn { cancelled: false, selectedText };\n\t\t}\n\n\t\tconst sessionManager = this.session.sessionManager;\n\t\tif (!targetLeafId) {\n\t\t\tsessionManager.newSession({ parentSession: this.session.sessionFile });\n\t\t} else {\n\t\t\tsessionManager.createBranchedSession(targetLeafId);\n\t\t}\n\t\tawait this.teardownCurrent(\"fork\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: this.cwd,\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"fork\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false, selectedText };\n\t}\n\n\t/**\n\t * Import a session JSONL file and switch runtime state to the imported session.\n\t *\n\t * @returns `{ cancelled: true }` when cancelled by `session_before_switch`, otherwise `{ cancelled: false }`.\n\t * @throws {SessionImportFileNotFoundError} When the input path does not exist.\n\t * @throws {MissingSessionCwdError} When the imported session cwd cannot be resolved and no override is provided.\n\t */\n\tasync importFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }> {\n\t\tconst resolvedPath = resolvePath(inputPath);\n\t\tif (!existsSync(resolvedPath)) {\n\t\t\tthrow new SessionImportFileNotFoundError(resolvedPath);\n\t\t}\n\n\t\tconst sessionDir = this.session.sessionManager.getSessionDir();\n\t\tif (!existsSync(sessionDir)) {\n\t\t\tmkdirSync(sessionDir, { recursive: true });\n\t\t}\n\n\t\tconst destinationPath = join(sessionDir, basename(resolvedPath));\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"resume\", destinationPath);\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tif (resolve(destinationPath) !== resolvedPath) {\n\t\t\tcopyFileSync(resolvedPath, destinationPath);\n\t\t}\n\n\t\tconst sessionManager = SessionManager.open(destinationPath, sessionDir, cwdOverride);\n\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\tawait this.teardownCurrent(\"resume\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: sessionManager.getCwd(),\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"resume\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement();\n\t\treturn { cancelled: false };\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tawait emitSessionShutdownEvent(this.session.extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason: \"quit\",\n\t\t});\n\t\tthis.beforeSessionInvalidate?.();\n\t\tthis.session.dispose();\n\t}\n}\n\n/**\n * Create the initial runtime from a runtime factory and initial session target.\n *\n * The same factory is stored on the returned AgentSessionRuntime and reused for\n * later /new, /resume, /fork, and import flows.\n */\nexport async function createAgentSessionRuntime(\n\tcreateRuntime: CreateAgentSessionRuntimeFactory,\n\toptions: {\n\t\tcwd: string;\n\t\tagentDir: string;\n\t\tsessionManager: SessionManager;\n\t\tsessionStartEvent?: SessionStartEvent;\n\t},\n): Promise<AgentSessionRuntime> {\n\tassertSessionCwdExists(options.sessionManager, options.cwd);\n\tconst result = await createRuntime(options);\n\treturn new AgentSessionRuntime(\n\t\tresult.session,\n\t\tresult.services,\n\t\tcreateRuntime,\n\t\tresult.diagnostics,\n\t\tresult.modelFallbackMessage,\n\t);\n}\n\nexport {\n\ttype AgentSessionRuntimeDiagnostic,\n\ttype AgentSessionServices,\n\ttype CreateAgentSessionFromServicesOptions,\n\ttype CreateAgentSessionServicesOptions,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionServices,\n} from \"./agent-session-services.ts\";\n"]}
|
|
1
|
+
{"version":3,"file":"agent-session-runtime.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { copyFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { basename, join, resolve } from \"node:path\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport type { AgentSession } from \"./agent-session.ts\";\nimport type { AgentSessionRuntimeDiagnostic, AgentSessionServices } from \"./agent-session-services.ts\";\nimport type {\n\tProjectTrustContext,\n\tReplacedSessionContext,\n\tSessionShutdownEvent,\n\tSessionStartEvent,\n} from \"./extensions/index.ts\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.ts\";\nimport type { CreateAgentSessionResult } from \"./sdk.ts\";\nimport { assertSessionCwdExists } from \"./session-cwd.ts\";\nimport { SessionManager } from \"./session-manager.ts\";\n\n/**\n * Result returned by runtime creation.\n *\n * The caller gets the created session, its cwd-bound services, and all\n * diagnostics collected during setup.\n */\nexport interface CreateAgentSessionRuntimeResult extends CreateAgentSessionResult {\n\tservices: AgentSessionServices;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n}\n\n/**\n * Creates a full runtime for a target cwd and session manager.\n *\n * The factory closes over process-global fixed inputs, recreates cwd-bound\n * services for the effective cwd, resolves session options against those\n * services, and finally creates the AgentSession.\n */\nexport type CreateAgentSessionRuntimeFactory = (options: {\n\tcwd: string;\n\tagentDir: string;\n\tsessionManager: SessionManager;\n\tsessionStartEvent?: SessionStartEvent;\n\tprojectTrustContext?: ProjectTrustContext;\n}) => Promise<CreateAgentSessionRuntimeResult>;\n\n/**\n * Thrown when /import references a JSONL file path that does not exist.\n */\nexport class SessionImportFileNotFoundError extends Error {\n\treadonly filePath: string;\n\n\tconstructor(filePath: string) {\n\t\tsuper(`File not found: ${filePath}`);\n\t\tthis.name = \"SessionImportFileNotFoundError\";\n\t\tthis.filePath = filePath;\n\t}\n}\n\nfunction extractUserMessageText(content: string | Array<{ type: string; text?: string }>): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is { type: \"text\"; text: string } => part.type === \"text\" && typeof part.text === \"string\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\");\n}\n\n/**\n * Owns the current AgentSession plus its cwd-bound services.\n *\n * Session replacement methods tear down the current runtime first, then create\n * and apply the next runtime. If creation fails, the error is propagated to the\n * caller. The caller is responsible for user-facing error handling.\n */\nexport class AgentSessionRuntime {\n\tprivate rebindSession?: (session: AgentSession) => Promise<void>;\n\tprivate beforeSessionInvalidate?: () => void;\n\tprivate _session: AgentSession;\n\tprivate _services: AgentSessionServices;\n\tprivate readonly createRuntime: CreateAgentSessionRuntimeFactory;\n\tprivate _diagnostics: AgentSessionRuntimeDiagnostic[];\n\tprivate _modelFallbackMessage?: string;\n\n\tconstructor(\n\t\t_session: AgentSession,\n\t\t_services: AgentSessionServices,\n\t\tcreateRuntime: CreateAgentSessionRuntimeFactory,\n\t\t_diagnostics: AgentSessionRuntimeDiagnostic[] = [],\n\t\t_modelFallbackMessage?: string,\n\t) {\n\t\tthis._session = _session;\n\t\tthis._services = _services;\n\t\tthis.createRuntime = createRuntime;\n\t\tthis._diagnostics = _diagnostics;\n\t\tthis._modelFallbackMessage = _modelFallbackMessage;\n\t}\n\n\tget services(): AgentSessionServices {\n\t\treturn this._services;\n\t}\n\n\tget session(): AgentSession {\n\t\treturn this._session;\n\t}\n\n\tget cwd(): string {\n\t\treturn this._services.cwd;\n\t}\n\n\tget diagnostics(): readonly AgentSessionRuntimeDiagnostic[] {\n\t\treturn this._diagnostics;\n\t}\n\n\tget modelFallbackMessage(): string | undefined {\n\t\treturn this._modelFallbackMessage;\n\t}\n\n\tsetRebindSession(rebindSession?: (session: AgentSession) => Promise<void>): void {\n\t\tthis.rebindSession = rebindSession;\n\t}\n\n\t/**\n\t * Set a synchronous callback that runs after `session_shutdown` handlers finish\n\t * but before the current session is invalidated.\n\t *\n\t * This is for host-owned UI teardown that must not yield to the event loop,\n\t * such as detaching extension-provided TUI components before the old extension\n\t * context becomes stale.\n\t */\n\tsetBeforeSessionInvalidate(beforeSessionInvalidate?: () => void): void {\n\t\tthis.beforeSessionInvalidate = beforeSessionInvalidate;\n\t}\n\n\tprivate async emitBeforeSwitch(\n\t\treason: \"new\" | \"resume\",\n\t\ttargetSessionFile?: string,\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst runner = this.session.extensionRunner;\n\t\tif (!runner.hasHandlers(\"session_before_switch\")) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\tconst result = await runner.emit({\n\t\t\ttype: \"session_before_switch\",\n\t\t\treason,\n\t\t\ttargetSessionFile,\n\t\t});\n\t\treturn { cancelled: result?.cancel === true };\n\t}\n\n\tprivate async emitBeforeFork(\n\t\tentryId: string,\n\t\toptions: { position: \"before\" | \"at\" },\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst runner = this.session.extensionRunner;\n\t\tif (!runner.hasHandlers(\"session_before_fork\")) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\tconst result = await runner.emit({\n\t\t\ttype: \"session_before_fork\",\n\t\t\tentryId,\n\t\t\t...options,\n\t\t});\n\t\treturn { cancelled: result?.cancel === true };\n\t}\n\n\tprivate async teardownCurrent(reason: SessionShutdownEvent[\"reason\"], targetSessionFile?: string): Promise<void> {\n\t\tawait emitSessionShutdownEvent(this.session.extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason,\n\t\t\ttargetSessionFile,\n\t\t});\n\t\tthis.beforeSessionInvalidate?.();\n\t\tthis.session.dispose();\n\t}\n\n\tprivate apply(result: CreateAgentSessionRuntimeResult): void {\n\t\tthis._session = result.session;\n\t\tthis._services = result.services;\n\t\tthis._diagnostics = result.diagnostics;\n\t\tthis._modelFallbackMessage = result.modelFallbackMessage;\n\t}\n\n\tprivate async finishSessionReplacement(withSession?: (ctx: ReplacedSessionContext) => Promise<void>): Promise<void> {\n\t\tif (this.rebindSession) {\n\t\t\tawait this.rebindSession(this.session);\n\t\t}\n\t\tif (withSession) {\n\t\t\tawait withSession(this.session.createReplacedSessionContext());\n\t\t}\n\t}\n\n\tasync switchSession(\n\t\tsessionPath: string,\n\t\toptions?: {\n\t\t\tcwdOverride?: string;\n\t\t\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\t\t\tprojectTrustContextFactory?: (cwd: string) => ProjectTrustContext;\n\t\t},\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"resume\", sessionPath);\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tconst sessionManager = SessionManager.open(sessionPath, undefined, options?.cwdOverride);\n\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\tawait this.teardownCurrent(\"resume\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: sessionManager.getCwd(),\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"resume\", previousSessionFile },\n\t\t\t\tprojectTrustContext: options?.projectTrustContextFactory?.(sessionManager.getCwd()),\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false };\n\t}\n\n\tasync newSession(options?: {\n\t\tparentSession?: string;\n\t\tsetup?: (sessionManager: SessionManager) => Promise<void>;\n\t\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\t}): Promise<{ cancelled: boolean }> {\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"new\");\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tconst sessionDir = this.session.sessionManager.getSessionDir();\n\t\tconst sessionManager = this.session.sessionManager.isPersisted()\n\t\t\t? SessionManager.create(this.cwd, sessionDir)\n\t\t\t: SessionManager.inMemory(this.cwd);\n\t\tif (options?.parentSession) {\n\t\t\tsessionManager.newSession({ parentSession: options.parentSession });\n\t\t}\n\n\t\tawait this.teardownCurrent(\"new\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: this.cwd,\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"new\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tif (options?.setup) {\n\t\t\tawait options.setup(this.session.sessionManager);\n\t\t\tthis.session.agent.state.messages = this.session.sessionManager.buildSessionContext().messages;\n\t\t}\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false };\n\t}\n\n\tasync fork(\n\t\tentryId: string,\n\t\toptions?: { position?: \"before\" | \"at\"; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean; selectedText?: string }> {\n\t\tconst position = options?.position ?? \"before\";\n\t\tconst beforeResult = await this.emitBeforeFork(entryId, { position });\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn { cancelled: true };\n\t\t}\n\t\tlet targetLeafId: string | null;\n\t\tlet selectedText: string | undefined;\n\n\t\tconst selectedEntry = this.session.sessionManager.getEntry(entryId);\n\t\tif (!selectedEntry) {\n\t\t\tthrow new Error(\"Invalid entry ID for forking\");\n\t\t}\n\n\t\tif (position === \"at\") {\n\t\t\ttargetLeafId = selectedEntry.id;\n\t\t} else {\n\t\t\tif (selectedEntry.type !== \"message\" || selectedEntry.message.role !== \"user\") {\n\t\t\t\tthrow new Error(\"Invalid entry ID for forking\");\n\t\t\t}\n\t\t\ttargetLeafId = selectedEntry.parentId;\n\t\t\tselectedText = extractUserMessageText(selectedEntry.message.content);\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tif (this.session.sessionManager.isPersisted()) {\n\t\t\tconst currentSessionFile = this.session.sessionFile;\n\t\t\tif (!currentSessionFile) {\n\t\t\t\tthrow new Error(\"Persisted session is missing a session file\");\n\t\t\t}\n\t\t\tconst sessionDir = this.session.sessionManager.getSessionDir();\n\t\t\tif (!targetLeafId) {\n\t\t\t\tconst sessionManager = SessionManager.create(this.cwd, sessionDir);\n\t\t\t\tsessionManager.newSession({ parentSession: currentSessionFile });\n\t\t\t\tawait this.teardownCurrent(\"fork\", sessionManager.getSessionFile());\n\t\t\t\tthis.apply(\n\t\t\t\t\tawait this.createRuntime({\n\t\t\t\t\t\tcwd: this.cwd,\n\t\t\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\t\t\tsessionManager,\n\t\t\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"fork\", previousSessionFile },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\t\t\treturn { cancelled: false, selectedText };\n\t\t\t}\n\n\t\t\tif (!existsSync(currentSessionFile)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"This session has not been saved yet. Wait for the first assistant response before cloning or forking it.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst sessionManager = SessionManager.open(currentSessionFile, sessionDir);\n\t\t\tconst forkedSessionPath = sessionManager.createBranchedSession(targetLeafId);\n\t\t\tif (!forkedSessionPath) {\n\t\t\t\tthrow new Error(\"Failed to create forked session\");\n\t\t\t}\n\t\t\tawait this.teardownCurrent(\"fork\", sessionManager.getSessionFile());\n\t\t\tthis.apply(\n\t\t\t\tawait this.createRuntime({\n\t\t\t\t\tcwd: sessionManager.getCwd(),\n\t\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\t\tsessionManager,\n\t\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"fork\", previousSessionFile },\n\t\t\t\t}),\n\t\t\t);\n\t\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\t\treturn { cancelled: false, selectedText };\n\t\t}\n\n\t\tconst sessionManager = this.session.sessionManager;\n\t\tif (!targetLeafId) {\n\t\t\tsessionManager.newSession({ parentSession: this.session.sessionFile });\n\t\t} else {\n\t\t\tsessionManager.createBranchedSession(targetLeafId);\n\t\t}\n\t\tawait this.teardownCurrent(\"fork\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: this.cwd,\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"fork\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false, selectedText };\n\t}\n\n\t/**\n\t * Import a session JSONL file and switch runtime state to the imported session.\n\t *\n\t * @returns `{ cancelled: true }` when cancelled by `session_before_switch`, otherwise `{ cancelled: false }`.\n\t * @throws {SessionImportFileNotFoundError} When the input path does not exist.\n\t * @throws {MissingSessionCwdError} When the imported session cwd cannot be resolved and no override is provided.\n\t */\n\tasync importFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }> {\n\t\tconst resolvedPath = resolvePath(inputPath);\n\t\tif (!existsSync(resolvedPath)) {\n\t\t\tthrow new SessionImportFileNotFoundError(resolvedPath);\n\t\t}\n\n\t\tconst sessionDir = this.session.sessionManager.getSessionDir();\n\t\tif (!existsSync(sessionDir)) {\n\t\t\tmkdirSync(sessionDir, { recursive: true });\n\t\t}\n\n\t\tconst destinationPath = join(sessionDir, basename(resolvedPath));\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"resume\", destinationPath);\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tif (resolve(destinationPath) !== resolvedPath) {\n\t\t\tcopyFileSync(resolvedPath, destinationPath);\n\t\t}\n\n\t\tconst sessionManager = SessionManager.open(destinationPath, sessionDir, cwdOverride);\n\t\tassertSessionCwdExists(sessionManager, this.cwd);\n\t\tawait this.teardownCurrent(\"resume\", sessionManager.getSessionFile());\n\t\tthis.apply(\n\t\t\tawait this.createRuntime({\n\t\t\t\tcwd: sessionManager.getCwd(),\n\t\t\t\tagentDir: this.services.agentDir,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent: { type: \"session_start\", reason: \"resume\", previousSessionFile },\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement();\n\t\treturn { cancelled: false };\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tawait emitSessionShutdownEvent(this.session.extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason: \"quit\",\n\t\t});\n\t\tthis.beforeSessionInvalidate?.();\n\t\tthis.session.dispose();\n\t}\n}\n\n/**\n * Create the initial runtime from a runtime factory and initial session target.\n *\n * The same factory is stored on the returned AgentSessionRuntime and reused for\n * later /new, /resume, /fork, and import flows.\n */\nexport async function createAgentSessionRuntime(\n\tcreateRuntime: CreateAgentSessionRuntimeFactory,\n\toptions: {\n\t\tcwd: string;\n\t\tagentDir: string;\n\t\tsessionManager: SessionManager;\n\t\tsessionStartEvent?: SessionStartEvent;\n\t},\n): Promise<AgentSessionRuntime> {\n\tassertSessionCwdExists(options.sessionManager, options.cwd);\n\tconst result = await createRuntime(options);\n\treturn new AgentSessionRuntime(\n\t\tresult.session,\n\t\tresult.services,\n\t\tcreateRuntime,\n\t\tresult.diagnostics,\n\t\tresult.modelFallbackMessage,\n\t);\n}\n\nexport {\n\ttype AgentSessionRuntimeDiagnostic,\n\ttype AgentSessionServices,\n\ttype CreateAgentSessionFromServicesOptions,\n\ttype CreateAgentSessionServicesOptions,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionServices,\n} from \"./agent-session-services.ts\";\n"]}
|
|
@@ -210,6 +210,9 @@ export class AgentSessionRuntime {
|
|
|
210
210
|
await this.finishSessionReplacement(options?.withSession);
|
|
211
211
|
return { cancelled: false, selectedText };
|
|
212
212
|
}
|
|
213
|
+
if (!existsSync(currentSessionFile)) {
|
|
214
|
+
throw new Error("This session has not been saved yet. Wait for the first assistant response before cloning or forking it.");
|
|
215
|
+
}
|
|
213
216
|
const sessionManager = SessionManager.open(currentSessionFile, sessionDir);
|
|
214
217
|
const forkedSessionPath = sessionManager.createBranchedSession(targetLeafId);
|
|
215
218
|
if (!forkedSessionPath) {
|