apex-code 0.0.1-alpha.10 → 0.0.1-alpha.11

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.
Files changed (130) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +9 -8
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js +24 -5
  5. package/dist/config.js.map +1 -1
  6. package/dist/core/agent-session.d.ts +26 -0
  7. package/dist/core/agent-session.d.ts.map +1 -1
  8. package/dist/core/agent-session.js +77 -1
  9. package/dist/core/agent-session.js.map +1 -1
  10. package/dist/core/bash-executor.d.ts.map +1 -1
  11. package/dist/core/bash-executor.js +7 -0
  12. package/dist/core/bash-executor.js.map +1 -1
  13. package/dist/core/checkpoints/git-checkpoints.d.ts +33 -0
  14. package/dist/core/checkpoints/git-checkpoints.d.ts.map +1 -0
  15. package/dist/core/checkpoints/git-checkpoints.js +230 -0
  16. package/dist/core/checkpoints/git-checkpoints.js.map +1 -0
  17. package/dist/core/checkpoints/session-checkpoints.d.ts +23 -0
  18. package/dist/core/checkpoints/session-checkpoints.d.ts.map +1 -0
  19. package/dist/core/checkpoints/session-checkpoints.js +29 -0
  20. package/dist/core/checkpoints/session-checkpoints.js.map +1 -0
  21. package/dist/core/exec.d.ts.map +1 -1
  22. package/dist/core/exec.js +5 -2
  23. package/dist/core/exec.js.map +1 -1
  24. package/dist/core/extensions/loader.d.ts.map +1 -1
  25. package/dist/core/extensions/loader.js +7 -1
  26. package/dist/core/extensions/loader.js.map +1 -1
  27. package/dist/core/mcp/config.d.ts +16 -0
  28. package/dist/core/mcp/config.d.ts.map +1 -0
  29. package/dist/core/mcp/config.js +152 -0
  30. package/dist/core/mcp/config.js.map +1 -0
  31. package/dist/core/mcp/connector.d.ts +10 -0
  32. package/dist/core/mcp/connector.d.ts.map +1 -0
  33. package/dist/core/mcp/connector.js +70 -0
  34. package/dist/core/mcp/connector.js.map +1 -0
  35. package/dist/core/mcp/contract.d.ts +19 -0
  36. package/dist/core/mcp/contract.d.ts.map +1 -0
  37. package/dist/core/mcp/contract.js +89 -0
  38. package/dist/core/mcp/contract.js.map +1 -0
  39. package/dist/core/mcp/mcp-tool.d.ts +32 -0
  40. package/dist/core/mcp/mcp-tool.d.ts.map +1 -0
  41. package/dist/core/mcp/mcp-tool.js +165 -0
  42. package/dist/core/mcp/mcp-tool.js.map +1 -0
  43. package/dist/core/mcp/metadata-cache.d.ts +29 -0
  44. package/dist/core/mcp/metadata-cache.d.ts.map +1 -0
  45. package/dist/core/mcp/metadata-cache.js +99 -0
  46. package/dist/core/mcp/metadata-cache.js.map +1 -0
  47. package/dist/core/mcp/runtime.d.ts +18 -0
  48. package/dist/core/mcp/runtime.d.ts.map +1 -0
  49. package/dist/core/mcp/runtime.js +35 -0
  50. package/dist/core/mcp/runtime.js.map +1 -0
  51. package/dist/core/mcp/schema.d.ts +22 -0
  52. package/dist/core/mcp/schema.d.ts.map +1 -0
  53. package/dist/core/mcp/schema.js +20 -0
  54. package/dist/core/mcp/schema.js.map +1 -0
  55. package/dist/core/mcp/server-manager.d.ts +43 -0
  56. package/dist/core/mcp/server-manager.d.ts.map +1 -0
  57. package/dist/core/mcp/server-manager.js +142 -0
  58. package/dist/core/mcp/server-manager.js.map +1 -0
  59. package/dist/core/mcp/types.d.ts +98 -0
  60. package/dist/core/mcp/types.d.ts.map +1 -0
  61. package/dist/core/mcp/types.js +8 -0
  62. package/dist/core/mcp/types.js.map +1 -0
  63. package/dist/core/sdk.d.ts.map +1 -1
  64. package/dist/core/sdk.js +14 -1
  65. package/dist/core/sdk.js.map +1 -1
  66. package/dist/core/session-manager.d.ts +13 -1
  67. package/dist/core/session-manager.d.ts.map +1 -1
  68. package/dist/core/session-manager.js +30 -3
  69. package/dist/core/session-manager.js.map +1 -1
  70. package/dist/core/settings-manager.d.ts +7 -0
  71. package/dist/core/settings-manager.d.ts.map +1 -1
  72. package/dist/core/settings-manager.js +3 -0
  73. package/dist/core/settings-manager.js.map +1 -1
  74. package/dist/core/slash-commands.d.ts.map +1 -1
  75. package/dist/core/slash-commands.js +1 -0
  76. package/dist/core/slash-commands.js.map +1 -1
  77. package/dist/core/tools/contract-snapshot.d.ts +58 -0
  78. package/dist/core/tools/contract-snapshot.d.ts.map +1 -0
  79. package/dist/core/tools/contract-snapshot.js +51 -0
  80. package/dist/core/tools/contract-snapshot.js.map +1 -0
  81. package/dist/core/tools/contract.d.ts +4 -2
  82. package/dist/core/tools/contract.d.ts.map +1 -1
  83. package/dist/core/tools/contract.js +4 -2
  84. package/dist/core/tools/contract.js.map +1 -1
  85. package/dist/core/tools/index.d.ts +9 -0
  86. package/dist/core/tools/index.d.ts.map +1 -1
  87. package/dist/core/tools/index.js +3 -0
  88. package/dist/core/tools/index.js.map +1 -1
  89. package/dist/index.d.ts +2 -0
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +2 -0
  92. package/dist/index.js.map +1 -1
  93. package/dist/main.d.ts.map +1 -1
  94. package/dist/main.js +6 -6
  95. package/dist/main.js.map +1 -1
  96. package/dist/modes/interactive/components/assistant-message.d.ts +29 -0
  97. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  98. package/dist/modes/interactive/components/assistant-message.js +182 -23
  99. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  100. package/dist/modes/interactive/components/bash-execution.d.ts +7 -0
  101. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  102. package/dist/modes/interactive/components/bash-execution.js +20 -0
  103. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  104. package/dist/modes/interactive/components/footer.d.ts +8 -0
  105. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  106. package/dist/modes/interactive/components/footer.js +29 -9
  107. package/dist/modes/interactive/components/footer.js.map +1 -1
  108. package/dist/modes/interactive/components/tool-execution.d.ts +12 -0
  109. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  110. package/dist/modes/interactive/components/tool-execution.js +31 -0
  111. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  112. package/dist/modes/interactive/interactive-mode.d.ts +29 -0
  113. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  114. package/dist/modes/interactive/interactive-mode.js +88 -4
  115. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  116. package/dist/package-manager-cli.d.ts.map +1 -1
  117. package/dist/package-manager-cli.js +0 -6
  118. package/dist/package-manager-cli.js.map +1 -1
  119. package/dist/utils/version-check.d.ts.map +1 -1
  120. package/dist/utils/version-check.js +6 -4
  121. package/dist/utils/version-check.js.map +1 -1
  122. package/docs/compaction.md +2 -0
  123. package/docs/environment-variables.md +1 -1
  124. package/examples/extensions/git-checkpoint.ts +24 -36
  125. package/npm-shrinkwrap.json +176 -28
  126. package/package.json +10 -8
  127. package/dist/server/create-harness.d.ts +0 -26
  128. package/dist/server/create-harness.d.ts.map +0 -1
  129. package/dist/server/create-harness.js +0 -107
  130. package/dist/server/create-harness.js.map +0 -1
@@ -5,11 +5,13 @@ import { getApexCodeUserAgent } from "./apex-code-user-agent.js";
5
5
  import { fetchWithRetry } from "./management-http.js";
6
6
  /**
7
7
  * npm's own per-tag registry endpoint, not a custom API this project would need to
8
- * host and operate. Compares against the "next" dist-tag rather than "latest": the
9
- * README documents `npm install --global apex-code@next` as the install channel
10
- * this pre-alpha project actually ships through.
8
+ * host and operate. Compares against "latest", which is the tag a release publishes
9
+ * under and the tag a bare `npm install apex-code` resolves (ADR 0026). While no
10
+ * stable version exists that is the newest prerelease; afterwards it is the newest
11
+ * stable. Querying "next" instead would report no update available for the whole
12
+ * pre-stable period, because "next" does not advance until a stable line exists.
11
13
  */
12
- const LATEST_VERSION_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/next`;
14
+ const LATEST_VERSION_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
13
15
  /** Exported so the sandbox's default allowlist cannot drift from the URL used here. */
14
16
  export const VERSION_CHECK_HOST = new URL(LATEST_VERSION_URL).host;
15
17
  const DEFAULT_VERSION_CHECK_TIMEOUT_MS = 10000;
@@ -1 +1 @@
1
- {"version":3,"file":"version-check.js","sourceRoot":"","sources":["../../src/utils/version-check.ts"],"names":[],"mappings":"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","sourcesContent":["import { compare, valid } from \"semver\";\nimport { PACKAGE_NAME } from \"../config.ts\";\nimport { getApexEnvironment } from \"../core/environment.ts\";\nimport { getApexCodeUserAgent } from \"./apex-code-user-agent.ts\";\nimport { fetchWithRetry } from \"./management-http.ts\";\n\n/**\n * npm's own per-tag registry endpoint, not a custom API this project would need to\n * host and operate. Compares against the \"next\" dist-tag rather than \"latest\": the\n * README documents `npm install --global apex-code@next` as the install channel\n * this pre-alpha project actually ships through.\n */\nconst LATEST_VERSION_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/next`;\n/** Exported so the sandbox's default allowlist cannot drift from the URL used here. */\nexport const VERSION_CHECK_HOST = new URL(LATEST_VERSION_URL).host;\nconst DEFAULT_VERSION_CHECK_TIMEOUT_MS = 10000;\n\nexport interface LatestApexCodeRelease {\n\tversion: string;\n\tpackageName?: string;\n\tnote?: string;\n}\n\n/** Include useful errno details hidden behind Node's generic \"fetch failed\" error. */\nexport function formatVersionCheckError(error: unknown): string {\n\tconst rootMessage = error instanceof Error && error.message ? error.message : String(error);\n\tconst cause = error instanceof Error ? error.cause : undefined;\n\tconst causes = cause instanceof AggregateError ? cause.errors : cause === undefined ? [] : [cause];\n\tconst codes = causes\n\t\t.map((value) =>\n\t\t\ttypeof value === \"object\" && value !== null && \"code\" in value && typeof value.code === \"string\"\n\t\t\t\t? value.code\n\t\t\t\t: undefined,\n\t\t)\n\t\t.filter((code): code is string => code !== undefined);\n\n\tif (codes.length > 0) return `${rootMessage} (${[...new Set(codes)].join(\", \")})`;\n\tconst causeMessage = causes.find(\n\t\t(value): value is Error => value instanceof Error && Boolean(value.message),\n\t)?.message;\n\treturn causeMessage ? `${rootMessage} (cause: ${causeMessage})` : rootMessage;\n}\n\nexport function comparePackageVersions(leftVersion: string, rightVersion: string): number | undefined {\n\tconst left = valid(leftVersion.trim());\n\tconst right = valid(rightVersion.trim());\n\tif (!left || !right) {\n\t\treturn undefined;\n\t}\n\treturn compare(left, right);\n}\n\nexport function isNewerPackageVersion(candidateVersion: string, currentVersion: string): boolean {\n\tconst comparison = comparePackageVersions(candidateVersion, currentVersion);\n\tif (comparison !== undefined) {\n\t\treturn comparison > 0;\n\t}\n\treturn candidateVersion.trim() !== currentVersion.trim();\n}\n\nexport async function getLatestApexCodeRelease(\n\tcurrentVersion: string,\n\toptions: { timeoutMs?: number; retry?: boolean } = {},\n): Promise<LatestApexCodeRelease | undefined> {\n\tif (getApexEnvironment(\"APEX_CODE_OFFLINE\")) return undefined;\n\n\tconst response = await fetchWithRetry(\n\t\tLATEST_VERSION_URL,\n\t\t{\n\t\t\theaders: {\n\t\t\t\t\"User-Agent\": getApexCodeUserAgent(currentVersion),\n\t\t\t\taccept: \"application/json\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tmaxRetries: options.retry ? 2 : 0,\n\t\t\ttimeoutMs: options.timeoutMs ?? DEFAULT_VERSION_CHECK_TIMEOUT_MS,\n\t\t},\n\t);\n\tif (!response.ok) return undefined;\n\n\t// npm's per-tag registry endpoint returns the full package manifest for that\n\t// version; \"packageName\"/\"note\" have no npm-registry equivalent and are left\n\t// undefined -- callers already treat both as optional with sensible fallbacks.\n\tconst data = (await response.json()) as {\n\t\tname?: unknown;\n\t\tversion?: unknown;\n\t};\n\tif (typeof data.version !== \"string\" || !data.version.trim()) {\n\t\treturn undefined;\n\t}\n\tconst packageName = typeof data.name === \"string\" && data.name.trim() ? data.name.trim() : undefined;\n\treturn {\n\t\tversion: data.version.trim(),\n\t\t...(packageName && packageName !== PACKAGE_NAME ? { packageName } : {}),\n\t};\n}\n\nexport async function getLatestApexCodeVersion(\n\tcurrentVersion: string,\n\toptions: { timeoutMs?: number; retry?: boolean } = {},\n): Promise<string | undefined> {\n\treturn (await getLatestApexCodeRelease(currentVersion, options))?.version;\n}\n\nexport async function checkForNewApexCodeVersion(currentVersion: string): Promise<LatestApexCodeRelease | undefined> {\n\tif (getApexEnvironment(\"APEX_CODE_SKIP_VERSION_CHECK\")) return undefined;\n\n\ttry {\n\t\tconst latestRelease = await getLatestApexCodeRelease(currentVersion);\n\t\tif (latestRelease && isNewerPackageVersion(latestRelease.version, currentVersion)) {\n\t\t\treturn latestRelease;\n\t\t}\n\t\treturn undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"version-check.js","sourceRoot":"","sources":["../../src/utils/version-check.ts"],"names":[],"mappings":"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","sourcesContent":["import { compare, valid } from \"semver\";\nimport { PACKAGE_NAME } from \"../config.ts\";\nimport { getApexEnvironment } from \"../core/environment.ts\";\nimport { getApexCodeUserAgent } from \"./apex-code-user-agent.ts\";\nimport { fetchWithRetry } from \"./management-http.ts\";\n\n/**\n * npm's own per-tag registry endpoint, not a custom API this project would need to\n * host and operate. Compares against \"latest\", which is the tag a release publishes\n * under and the tag a bare `npm install apex-code` resolves (ADR 0026). While no\n * stable version exists that is the newest prerelease; afterwards it is the newest\n * stable. Querying \"next\" instead would report no update available for the whole\n * pre-stable period, because \"next\" does not advance until a stable line exists.\n */\nconst LATEST_VERSION_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;\n/** Exported so the sandbox's default allowlist cannot drift from the URL used here. */\nexport const VERSION_CHECK_HOST = new URL(LATEST_VERSION_URL).host;\nconst DEFAULT_VERSION_CHECK_TIMEOUT_MS = 10000;\n\nexport interface LatestApexCodeRelease {\n\tversion: string;\n\tpackageName?: string;\n\tnote?: string;\n}\n\n/** Include useful errno details hidden behind Node's generic \"fetch failed\" error. */\nexport function formatVersionCheckError(error: unknown): string {\n\tconst rootMessage = error instanceof Error && error.message ? error.message : String(error);\n\tconst cause = error instanceof Error ? error.cause : undefined;\n\tconst causes = cause instanceof AggregateError ? cause.errors : cause === undefined ? [] : [cause];\n\tconst codes = causes\n\t\t.map((value) =>\n\t\t\ttypeof value === \"object\" && value !== null && \"code\" in value && typeof value.code === \"string\"\n\t\t\t\t? value.code\n\t\t\t\t: undefined,\n\t\t)\n\t\t.filter((code): code is string => code !== undefined);\n\n\tif (codes.length > 0) return `${rootMessage} (${[...new Set(codes)].join(\", \")})`;\n\tconst causeMessage = causes.find(\n\t\t(value): value is Error => value instanceof Error && Boolean(value.message),\n\t)?.message;\n\treturn causeMessage ? `${rootMessage} (cause: ${causeMessage})` : rootMessage;\n}\n\nexport function comparePackageVersions(leftVersion: string, rightVersion: string): number | undefined {\n\tconst left = valid(leftVersion.trim());\n\tconst right = valid(rightVersion.trim());\n\tif (!left || !right) {\n\t\treturn undefined;\n\t}\n\treturn compare(left, right);\n}\n\nexport function isNewerPackageVersion(candidateVersion: string, currentVersion: string): boolean {\n\tconst comparison = comparePackageVersions(candidateVersion, currentVersion);\n\tif (comparison !== undefined) {\n\t\treturn comparison > 0;\n\t}\n\treturn candidateVersion.trim() !== currentVersion.trim();\n}\n\nexport async function getLatestApexCodeRelease(\n\tcurrentVersion: string,\n\toptions: { timeoutMs?: number; retry?: boolean } = {},\n): Promise<LatestApexCodeRelease | undefined> {\n\tif (getApexEnvironment(\"APEX_CODE_OFFLINE\")) return undefined;\n\n\tconst response = await fetchWithRetry(\n\t\tLATEST_VERSION_URL,\n\t\t{\n\t\t\theaders: {\n\t\t\t\t\"User-Agent\": getApexCodeUserAgent(currentVersion),\n\t\t\t\taccept: \"application/json\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tmaxRetries: options.retry ? 2 : 0,\n\t\t\ttimeoutMs: options.timeoutMs ?? DEFAULT_VERSION_CHECK_TIMEOUT_MS,\n\t\t},\n\t);\n\tif (!response.ok) return undefined;\n\n\t// npm's per-tag registry endpoint returns the full package manifest for that\n\t// version; \"packageName\"/\"note\" have no npm-registry equivalent and are left\n\t// undefined -- callers already treat both as optional with sensible fallbacks.\n\tconst data = (await response.json()) as {\n\t\tname?: unknown;\n\t\tversion?: unknown;\n\t};\n\tif (typeof data.version !== \"string\" || !data.version.trim()) {\n\t\treturn undefined;\n\t}\n\tconst packageName = typeof data.name === \"string\" && data.name.trim() ? data.name.trim() : undefined;\n\treturn {\n\t\tversion: data.version.trim(),\n\t\t...(packageName && packageName !== PACKAGE_NAME ? { packageName } : {}),\n\t};\n}\n\nexport async function getLatestApexCodeVersion(\n\tcurrentVersion: string,\n\toptions: { timeoutMs?: number; retry?: boolean } = {},\n): Promise<string | undefined> {\n\treturn (await getLatestApexCodeRelease(currentVersion, options))?.version;\n}\n\nexport async function checkForNewApexCodeVersion(currentVersion: string): Promise<LatestApexCodeRelease | undefined> {\n\tif (getApexEnvironment(\"APEX_CODE_SKIP_VERSION_CHECK\")) return undefined;\n\n\ttry {\n\t\tconst latestRelease = await getLatestApexCodeRelease(currentVersion);\n\t\tif (latestRelease && isNewerPackageVersion(latestRelease.version, currentVersion)) {\n\t\t\treturn latestRelease;\n\t\t}\n\t\treturn undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
@@ -34,6 +34,8 @@ contextTokens > contextWindow - reserveTokens
34
34
 
35
35
  By default, `reserveTokens` is 16384 tokens (configurable in `~/.apex-code/agent/settings.json` or `<project-dir>/.apex-code/settings.json`). This leaves room for the LLM's response.
36
36
 
37
+ Apex Code checks this threshold after every completed tool batch that would otherwise start another provider request. If a long tool run crosses the threshold, it compacts at that safe boundary and resumes the unfinished run.
38
+
37
39
  You can also trigger manually with `/compact [instructions]`, where optional instructions focus the summary.
38
40
 
39
41
  ### How It Works
@@ -12,7 +12,7 @@ subprocess metadata. Provider API-key variables remain documented in
12
12
  | `APEX_CODE_CODING_AGENT_SESSION_DIR` | Override session storage |
13
13
  | `APEX_CODE_PACKAGE_DIR` | Override package assets (for Nix/Guix paths) |
14
14
  | `APEX_CODE_OFFLINE` | Disable startup network operations |
15
- | `APEX_CODE_SKIP_VERSION_CHECK` | Disable the npm `apex-code@next` version request |
15
+ | `APEX_CODE_SKIP_VERSION_CHECK` | Disable the npm `apex-code` version request |
16
16
  | `APEX_CODE_EXPERIMENTAL` | Enable experimental features when set to `1` |
17
17
  | `APEX_CODE_STARTUP_BENCHMARK` | Enable startup benchmarking |
18
18
  | `APEX_CODE_TIMING` | Enable timing diagnostics when set to `1` |
@@ -1,53 +1,41 @@
1
1
  /**
2
2
  * Git Checkpoint Extension
3
3
  *
4
- * Creates git stash checkpoints at each turn so /fork can restore code state.
5
- * When forking, offers to restore code to that point in history.
4
+ * Offers to restore code state when /fork rewinds the conversation to an earlier entry.
5
+ *
6
+ * Capture is not here. Setting `"checkpoints": { "enabled": true }` makes the harness
7
+ * snapshot the worktree at every turn, keyed to the session entry, into
8
+ * `refs/apex-code/checkpoints/<sessionId>/<entryId>`. This extension only asks the
9
+ * question, because whether to prompt is a UI decision and the harness stays headless.
10
+ *
11
+ * The engine is resolved from the workspace rather than handed over, because the
12
+ * registry is git itself. That is also why a checkpoint survives a restart.
6
13
  */
7
14
 
8
- import type { ExtensionAPI } from "apex-code";
15
+ import { createGitCheckpoints, type ExtensionAPI, type GitCheckpoints } from "apex-code";
9
16
 
10
17
  export default function (pi: ExtensionAPI) {
11
- const checkpoints = new Map<string, string>();
12
- let currentEntryId: string | undefined;
13
-
14
- // Track the current entry ID when user messages are saved
15
- pi.on("tool_result", async (_event, ctx) => {
16
- const leaf = ctx.sessionManager.getLeafEntry();
17
- if (leaf) currentEntryId = leaf.id;
18
- });
19
-
20
- pi.on("turn_start", async () => {
21
- // Create a git stash entry before LLM makes changes
22
- const { stdout } = await pi.exec("git", ["stash", "create"]);
23
- const ref = stdout.trim();
24
- if (ref && currentEntryId) {
25
- checkpoints.set(currentEntryId, ref);
26
- }
27
- });
18
+ let engine: Promise<GitCheckpoints | undefined> | undefined;
28
19
 
29
20
  pi.on("session_before_fork", async (event, ctx) => {
30
- const ref = checkpoints.get(event.entryId);
31
- if (!ref) return;
21
+ if (!ctx.hasUI) return;
32
22
 
33
- if (!ctx.hasUI) {
34
- // In non-interactive mode, don't restore automatically
35
- return;
36
- }
23
+ engine ??= createGitCheckpoints(ctx.cwd, ctx.sessionManager.getSessionId());
24
+ const checkpoint = await (await engine)?.lookup(event.entryId);
25
+ if (!checkpoint) return;
37
26
 
38
27
  const choice = await ctx.ui.select("Restore code state?", [
39
28
  "Yes, restore code to that point",
40
29
  "No, keep current code",
41
30
  ]);
42
-
43
- if (choice?.startsWith("Yes")) {
44
- await pi.exec("git", ["stash", "apply", ref]);
45
- ctx.ui.notify("Code restored to checkpoint", "info");
46
- }
47
- });
48
-
49
- pi.on("agent_settled", async () => {
50
- // Clear checkpoints after the full agent run completes
51
- checkpoints.clear();
31
+ if (!choice?.startsWith("Yes")) return;
32
+
33
+ const previous = await (await engine)?.restore(checkpoint);
34
+ ctx.ui.notify(
35
+ previous
36
+ ? `Code restored. Previous state kept at ${previous.commit.slice(0, 8)}.`
37
+ : "Checkpoint restore failed; code is unchanged.",
38
+ previous ? "info" : "error",
39
+ );
52
40
  });
53
41
  }
@@ -1,33 +1,35 @@
1
1
  {
2
2
  "name": "apex-code",
3
- "version": "0.0.1-alpha.10",
3
+ "version": "0.0.1-alpha.11",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "apex-code",
9
- "version": "0.0.1-alpha.10",
9
+ "version": "0.0.1-alpha.11",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "apex-code-agent-core": "0.0.1-alpha.10",
13
12
  "@earendil-works/pi-ai": "^0.84.3",
14
13
  "@earendil-works/pi-client": "^0.84.3",
15
14
  "@earendil-works/pi-protocol": "^0.84.3",
16
15
  "@earendil-works/pi-tui": "^0.84.3",
16
+ "@modelcontextprotocol/client": "2.0.0",
17
+ "@modelcontextprotocol/core": "2.0.0",
17
18
  "@silvia-odwyer/photon-node": "0.3.4",
19
+ "apex-code-agent-core": "0.0.1-alpha.11",
18
20
  "chalk": "5.6.2",
19
21
  "cross-spawn": "7.0.6",
20
- "diff": "8.0.4",
22
+ "diff": "9.0.0",
21
23
  "grok-mermaid": "0.2.2",
22
24
  "highlight.js": "10.7.3",
23
- "hosted-git-info": "9.0.3",
25
+ "hosted-git-info": "10.1.1",
24
26
  "ignore": "7.0.5",
25
27
  "jiti": "2.7.0",
26
- "minimatch": "10.2.5",
28
+ "minimatch": "10.2.6",
27
29
  "proper-lockfile": "4.1.2",
28
- "semver": "7.8.0",
30
+ "semver": "7.8.5",
29
31
  "typebox": "1.3.7",
30
- "undici": "8.9.0",
32
+ "undici": "8.10.0",
31
33
  "yaml": "2.9.0"
32
34
  },
33
35
  "optionalDependencies": {
@@ -784,6 +786,113 @@
784
786
  ],
785
787
  "optional": true
786
788
  },
789
+ "node_modules/@modelcontextprotocol/client": {
790
+ "version": "2.0.0",
791
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/client/-/client-2.0.0.tgz",
792
+ "integrity": "sha512-8f1OghQ2rjzIOfqgUCP+8GiUWqRs89njoWLNqAe8kWmDePv3s1fZXseej+QXemssEuuOvLLmLO/kqM3IQHtISw==",
793
+ "license": "MIT",
794
+ "dependencies": {
795
+ "@modelcontextprotocol/core": "2.0.0",
796
+ "cross-spawn": "^7.0.5",
797
+ "eventsource": "^3.0.2",
798
+ "eventsource-parser": "^3.0.0",
799
+ "jose": "^6.1.3",
800
+ "pkce-challenge": "^5.0.0",
801
+ "zod": "^4.2.0"
802
+ },
803
+ "engines": {
804
+ "node": ">=20"
805
+ }
806
+ },
807
+ "node_modules/@modelcontextprotocol/client/node_modules/cross-spawn": {
808
+ "version": "7.0.6",
809
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
810
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
811
+ "license": "MIT",
812
+ "dependencies": {
813
+ "path-key": "^3.1.0",
814
+ "shebang-command": "^2.0.0",
815
+ "which": "^2.0.1"
816
+ },
817
+ "engines": {
818
+ "node": ">= 8"
819
+ }
820
+ },
821
+ "node_modules/@modelcontextprotocol/client/node_modules/path-key": {
822
+ "version": "3.1.1",
823
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
824
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
825
+ "license": "MIT",
826
+ "engines": {
827
+ "node": ">=8"
828
+ }
829
+ },
830
+ "node_modules/@modelcontextprotocol/client/node_modules/shebang-command": {
831
+ "version": "2.0.0",
832
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
833
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
834
+ "license": "MIT",
835
+ "dependencies": {
836
+ "shebang-regex": "^3.0.0"
837
+ },
838
+ "engines": {
839
+ "node": ">=8"
840
+ }
841
+ },
842
+ "node_modules/@modelcontextprotocol/client/node_modules/shebang-regex": {
843
+ "version": "3.0.0",
844
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
845
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
846
+ "license": "MIT",
847
+ "engines": {
848
+ "node": ">=8"
849
+ }
850
+ },
851
+ "node_modules/@modelcontextprotocol/client/node_modules/which": {
852
+ "version": "2.0.2",
853
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
854
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
855
+ "license": "ISC",
856
+ "dependencies": {
857
+ "isexe": "^2.0.0"
858
+ },
859
+ "bin": {
860
+ "node-which": "bin/node-which"
861
+ },
862
+ "engines": {
863
+ "node": ">= 8"
864
+ }
865
+ },
866
+ "node_modules/@modelcontextprotocol/client/node_modules/zod": {
867
+ "version": "4.4.3",
868
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
869
+ "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
870
+ "license": "MIT",
871
+ "funding": {
872
+ "url": "https://github.com/sponsors/colinhacks"
873
+ }
874
+ },
875
+ "node_modules/@modelcontextprotocol/core": {
876
+ "version": "2.0.0",
877
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/core/-/core-2.0.0.tgz",
878
+ "integrity": "sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==",
879
+ "license": "MIT",
880
+ "dependencies": {
881
+ "zod": "^4.2.0"
882
+ },
883
+ "engines": {
884
+ "node": ">=20"
885
+ }
886
+ },
887
+ "node_modules/@modelcontextprotocol/core/node_modules/zod": {
888
+ "version": "4.4.3",
889
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
890
+ "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
891
+ "license": "MIT",
892
+ "funding": {
893
+ "url": "https://github.com/sponsors/colinhacks"
894
+ }
895
+ },
787
896
  "node_modules/@protobufjs/aspromise": {
788
897
  "version": "1.1.2",
789
898
  "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
@@ -991,13 +1100,13 @@
991
1100
  }
992
1101
  },
993
1102
  "node_modules/apex-code-agent-core": {
994
- "version": "0.0.1-alpha.10",
995
- "resolved": "https://registry.npmjs.org/apex-code-agent-core/-/apex-code-agent-core-0.0.1-alpha.10.tgz",
1103
+ "version": "0.0.1-alpha.11",
1104
+ "resolved": "https://registry.npmjs.org/apex-code-agent-core/-/apex-code-agent-core-0.0.1-alpha.11.tgz",
996
1105
  "license": "MIT",
997
1106
  "dependencies": {
998
1107
  "@earendil-works/pi-ai": "^0.84.3",
999
1108
  "@earendil-works/pi-telemetry": "^0.84.3",
1000
- "diff": "8.0.4",
1109
+ "diff": "9.0.0",
1001
1110
  "ignore": "7.0.5",
1002
1111
  "typebox": "1.3.7",
1003
1112
  "yaml": "2.9.0"
@@ -1119,9 +1228,9 @@
1119
1228
  }
1120
1229
  },
1121
1230
  "node_modules/diff": {
1122
- "version": "8.0.4",
1123
- "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz",
1124
- "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==",
1231
+ "version": "9.0.0",
1232
+ "resolved": "https://registry.npmjs.org/diff/-/diff-9.0.0.tgz",
1233
+ "integrity": "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==",
1125
1234
  "license": "BSD-3-Clause",
1126
1235
  "engines": {
1127
1236
  "node": ">=0.3.1"
@@ -1136,6 +1245,27 @@
1136
1245
  "safe-buffer": "^5.0.1"
1137
1246
  }
1138
1247
  },
1248
+ "node_modules/eventsource": {
1249
+ "version": "3.0.7",
1250
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
1251
+ "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
1252
+ "license": "MIT",
1253
+ "dependencies": {
1254
+ "eventsource-parser": "^3.0.1"
1255
+ },
1256
+ "engines": {
1257
+ "node": ">=18.0.0"
1258
+ }
1259
+ },
1260
+ "node_modules/eventsource-parser": {
1261
+ "version": "3.1.1",
1262
+ "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.1.tgz",
1263
+ "integrity": "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==",
1264
+ "license": "MIT",
1265
+ "engines": {
1266
+ "node": ">=18.0.0"
1267
+ }
1268
+ },
1139
1269
  "node_modules/extend": {
1140
1270
  "version": "3.0.2",
1141
1271
  "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -1268,15 +1398,15 @@
1268
1398
  }
1269
1399
  },
1270
1400
  "node_modules/hosted-git-info": {
1271
- "version": "9.0.3",
1272
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz",
1273
- "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==",
1401
+ "version": "10.1.1",
1402
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-10.1.1.tgz",
1403
+ "integrity": "sha512-DeOnSPAvOndYKfw075gt8yZzQ7S2hNztw34zBTfhIzLhmBTswIBg5/y+pqu/VD5cYWm5goAFTusDmUEmKZ0PEQ==",
1274
1404
  "license": "ISC",
1275
1405
  "dependencies": {
1276
1406
  "lru-cache": "^11.1.0"
1277
1407
  },
1278
1408
  "engines": {
1279
- "node": "^20.17.0 || >=22.9.0"
1409
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
1280
1410
  }
1281
1411
  },
1282
1412
  "node_modules/http-proxy-agent": {
@@ -1329,6 +1459,15 @@
1329
1459
  "jiti": "lib/jiti-cli.mjs"
1330
1460
  }
1331
1461
  },
1462
+ "node_modules/jose": {
1463
+ "version": "6.2.10",
1464
+ "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.10.tgz",
1465
+ "integrity": "sha512-iiW7J9qRFlGxvCOIBDBDxFePQSn7ZMAnrYGhrrOo6siO/MIqwfyilLR27pkfDgUk+raLuzADS8A3S/KLBisc0g==",
1466
+ "license": "MIT",
1467
+ "funding": {
1468
+ "url": "https://github.com/sponsors/panva"
1469
+ }
1470
+ },
1332
1471
  "node_modules/json-bigint": {
1333
1472
  "version": "1.0.0",
1334
1473
  "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
@@ -1400,12 +1539,12 @@
1400
1539
  }
1401
1540
  },
1402
1541
  "node_modules/minimatch": {
1403
- "version": "10.2.5",
1404
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
1405
- "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
1542
+ "version": "10.2.6",
1543
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
1544
+ "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
1406
1545
  "license": "BlueOak-1.0.0",
1407
1546
  "dependencies": {
1408
- "brace-expansion": "^5.0.5"
1547
+ "brace-expansion": "^5.0.8"
1409
1548
  },
1410
1549
  "engines": {
1411
1550
  "node": "18 || 20 || >=22"
@@ -1511,6 +1650,15 @@
1511
1650
  "node": ">=8"
1512
1651
  }
1513
1652
  },
1653
+ "node_modules/pkce-challenge": {
1654
+ "version": "5.0.1",
1655
+ "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz",
1656
+ "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==",
1657
+ "license": "MIT",
1658
+ "engines": {
1659
+ "node": ">=16.20.0"
1660
+ }
1661
+ },
1514
1662
  "node_modules/proper-lockfile": {
1515
1663
  "version": "4.1.2",
1516
1664
  "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz",
@@ -1575,9 +1723,9 @@
1575
1723
  ]
1576
1724
  },
1577
1725
  "node_modules/semver": {
1578
- "version": "7.8.0",
1579
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz",
1580
- "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==",
1726
+ "version": "7.8.5",
1727
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
1728
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
1581
1729
  "license": "ISC",
1582
1730
  "bin": {
1583
1731
  "semver": "bin/semver.js"
@@ -1628,9 +1776,9 @@
1628
1776
  "license": "MIT"
1629
1777
  },
1630
1778
  "node_modules/undici": {
1631
- "version": "8.9.0",
1632
- "resolved": "https://registry.npmjs.org/undici/-/undici-8.9.0.tgz",
1633
- "integrity": "sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA==",
1779
+ "version": "8.10.0",
1780
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.10.0.tgz",
1781
+ "integrity": "sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==",
1634
1782
  "license": "MIT",
1635
1783
  "engines": {
1636
1784
  "node": ">=22.19.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apex-code",
3
- "version": "0.0.1-alpha.10",
3
+ "version": "0.0.1-alpha.11",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -43,25 +43,27 @@
43
43
  "prepublishOnly": "npm run clean && npm run build && npm run shrinkwrap"
44
44
  },
45
45
  "dependencies": {
46
- "apex-code-agent-core": "0.0.1-alpha.10",
47
46
  "@earendil-works/pi-ai": "^0.84.3",
48
47
  "@earendil-works/pi-client": "^0.84.3",
49
48
  "@earendil-works/pi-protocol": "^0.84.3",
50
49
  "@earendil-works/pi-tui": "^0.84.3",
50
+ "@modelcontextprotocol/client": "2.0.0",
51
+ "@modelcontextprotocol/core": "2.0.0",
51
52
  "@silvia-odwyer/photon-node": "0.3.4",
53
+ "apex-code-agent-core": "0.0.1-alpha.11",
52
54
  "chalk": "5.6.2",
53
55
  "cross-spawn": "7.0.6",
54
- "diff": "8.0.4",
56
+ "diff": "9.0.0",
55
57
  "grok-mermaid": "0.2.2",
56
58
  "highlight.js": "10.7.3",
57
- "hosted-git-info": "9.0.3",
59
+ "hosted-git-info": "10.1.1",
58
60
  "ignore": "7.0.5",
59
61
  "jiti": "2.7.0",
60
- "minimatch": "10.2.5",
62
+ "minimatch": "10.2.6",
61
63
  "proper-lockfile": "4.1.2",
62
- "semver": "7.8.0",
64
+ "semver": "7.8.5",
63
65
  "typebox": "1.3.7",
64
- "undici": "8.9.0",
66
+ "undici": "8.10.0",
65
67
  "yaml": "2.9.0"
66
68
  },
67
69
  "overrides": {
@@ -79,7 +81,7 @@
79
81
  "@types/hosted-git-info": "3.0.5",
80
82
  "@types/node": "22.19.19",
81
83
  "@types/proper-lockfile": "4.1.4",
82
- "@types/semver": "7.7.1",
84
+ "@types/semver": "7.8.0",
83
85
  "glob": "13.0.6",
84
86
  "shx": "0.4.0",
85
87
  "typescript": "5.9.3",
@@ -1,26 +0,0 @@
1
- import { AgentHarness, type AgentHarnessOptions, type ExecutionEnv, type HarnessTool } from "apex-code-agent-core";
2
- import { type BuildSystemPromptOptions } from "../core/system-prompt.ts";
3
- export interface CodingAgentHarnessTool extends HarnessTool {
4
- promptSnippet?: string;
5
- promptGuidelines?: readonly string[];
6
- }
7
- export interface CreateCodingAgentHarnessOptions extends Omit<AgentHarnessOptions, "toolContext" | "tools"> {
8
- env: ExecutionEnv;
9
- bashCommandPrefix?: string;
10
- /** Path to the JSONL session file exposed to default bash commands as APEX_CODE_SESSION_FILE. */
11
- sessionFile?: string;
12
- tools?: CodingAgentHarnessTool[];
13
- systemPromptOptions?: Omit<BuildSystemPromptOptions, "cwd" | "promptGuidelines" | "selectedTools" | "toolSnippets">;
14
- }
15
- export interface BuildCodingAgentHarnessSystemPromptOptions {
16
- cwd: string;
17
- tools: readonly CodingAgentHarnessTool[];
18
- activeToolNames: readonly string[];
19
- systemPromptOptions?: CreateCodingAgentHarnessOptions["systemPromptOptions"];
20
- }
21
- export declare function buildCodingAgentHarnessSystemPrompt(options: BuildCodingAgentHarnessSystemPromptOptions): string;
22
- export declare function createCodingAgentHarness(options: CreateCodingAgentHarnessOptions): Promise<{
23
- harness: AgentHarness;
24
- suspended: import("apex-code-agent-core").SuspendedOperation[];
25
- }>;
26
- //# sourceMappingURL=create-harness.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-harness.d.ts","sourceRoot":"","sources":["../../src/server/create-harness.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EACZ,KAAK,mBAAmB,EAMxB,KAAK,YAAY,EAEjB,KAAK,WAAW,EAChB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,KAAK,wBAAwB,EAAqB,MAAM,0BAA0B,CAAC;AAM5F,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAgBD,MAAM,WAAW,+BAAgC,SAAQ,IAAI,CAAC,mBAAmB,EAAE,aAAa,GAAG,OAAO,CAAC;IAC1G,GAAG,EAAE,YAAY,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACjC,mBAAmB,CAAC,EAAE,IAAI,CAAC,wBAAwB,EAAE,KAAK,GAAG,kBAAkB,GAAG,eAAe,GAAG,cAAc,CAAC,CAAC;CACpH;AAED,MAAM,WAAW,0CAA0C;IAC1D,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACzC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,mBAAmB,CAAC,EAAE,+BAA+B,CAAC,qBAAqB,CAAC,CAAC;CAC7E;AAED,wBAAgB,mCAAmC,CAAC,OAAO,EAAE,0CAA0C,GAAG,MAAM,CAsB/G;AAED,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,+BAA+B;;;GAiFtF","sourcesContent":["import {\n\tAgentHarness,\n\ttype AgentHarnessOptions,\n\ttype AgentHarnessTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ExecutionEnv,\n\ttype ExecutionToolContext,\n\ttype HarnessTool,\n} from \"apex-code-agent-core\";\nimport type { Static, TSchema } from \"typebox\";\nimport { setApexEnvironment } from \"../core/environment.ts\";\nimport { getExperimentalToolSampling } from \"../core/experimental.ts\";\nimport { type BuildSystemPromptOptions, buildSystemPrompt } from \"../core/system-prompt.ts\";\nimport { bashToolSystemPromptContribution } from \"../core/tools/bash.ts\";\nimport { editToolSystemPromptContribution } from \"../core/tools/edit.ts\";\nimport { readToolSystemPromptContribution } from \"../core/tools/read.ts\";\nimport { writeToolSystemPromptContribution } from \"../core/tools/write.ts\";\n\nexport interface CodingAgentHarnessTool extends HarnessTool {\n\tpromptSnippet?: string;\n\tpromptGuidelines?: readonly string[];\n}\n\nfunction createCodingAgentHarnessTool<TParameters extends TSchema, TDetails>(\n\ttool: AgentHarnessTool<ExecutionToolContext, TParameters, TDetails>,\n\tcontext: ExecutionToolContext,\n\tprompt: Required<Pick<CodingAgentHarnessTool, \"promptSnippet\" | \"promptGuidelines\">>,\n): CodingAgentHarnessTool {\n\treturn {\n\t\t...tool,\n\t\t...prompt,\n\t\tconstrainedSampling: getExperimentalToolSampling(),\n\t\texecute: (toolCallId, params, signal, onUpdate) =>\n\t\t\ttool.execute(toolCallId, params as Static<TParameters>, signal, onUpdate, context),\n\t};\n}\n\nexport interface CreateCodingAgentHarnessOptions extends Omit<AgentHarnessOptions, \"toolContext\" | \"tools\"> {\n\tenv: ExecutionEnv;\n\tbashCommandPrefix?: string;\n\t/** Path to the JSONL session file exposed to default bash commands as APEX_CODE_SESSION_FILE. */\n\tsessionFile?: string;\n\ttools?: CodingAgentHarnessTool[];\n\tsystemPromptOptions?: Omit<BuildSystemPromptOptions, \"cwd\" | \"promptGuidelines\" | \"selectedTools\" | \"toolSnippets\">;\n}\n\nexport interface BuildCodingAgentHarnessSystemPromptOptions {\n\tcwd: string;\n\ttools: readonly CodingAgentHarnessTool[];\n\tactiveToolNames: readonly string[];\n\tsystemPromptOptions?: CreateCodingAgentHarnessOptions[\"systemPromptOptions\"];\n}\n\nexport function buildCodingAgentHarnessSystemPrompt(options: BuildCodingAgentHarnessSystemPromptOptions): string {\n\tconst activeTools = options.activeToolNames.flatMap((name) => {\n\t\tconst tool = options.tools.find((candidate) => candidate.name === name);\n\t\treturn tool ? [tool] : [];\n\t});\n\tconst toolSnippets = Object.fromEntries(\n\t\tactiveTools.flatMap((tool) => {\n\t\t\tconst promptSnippet = tool.promptSnippet\n\t\t\t\t?.replace(/[\\r\\n]+/g, \" \")\n\t\t\t\t.replace(/\\s+/g, \" \")\n\t\t\t\t.trim();\n\t\t\treturn promptSnippet ? [[tool.name, promptSnippet]] : [];\n\t\t}),\n\t);\n\tconst promptGuidelines = activeTools.flatMap((tool) => tool.promptGuidelines ?? []);\n\treturn buildSystemPrompt({\n\t\t...options.systemPromptOptions,\n\t\tcwd: options.cwd,\n\t\tselectedTools: activeTools.map((tool) => tool.name),\n\t\ttoolSnippets,\n\t\tpromptGuidelines,\n\t});\n}\n\nexport async function createCodingAgentHarness(options: CreateCodingAgentHarnessOptions) {\n\tconst {\n\t\tenv,\n\t\tbashCommandPrefix,\n\t\tsessionFile,\n\t\tsystemPromptOptions,\n\t\ttools: providedTools,\n\t\tactiveToolNames: providedActiveToolNames,\n\t\tsystemPrompt: providedSystemPrompt,\n\t\t...harnessOptions\n\t} = options;\n\tlet harness: AgentHarness | undefined;\n\tconst getHarness = (): AgentHarness => {\n\t\tif (!harness) throw new Error(\"Coding-agent Harness callback ran before Harness initialization\");\n\t\treturn harness;\n\t};\n\tlet tools = providedTools;\n\tif (tools === undefined) {\n\t\tconst metadata = await options.session.getMetadata();\n\t\tconst toolContext = { env } satisfies ExecutionToolContext;\n\t\ttools = [\n\t\t\tcreateCodingAgentHarnessTool(createReadTool<ExecutionToolContext>(), toolContext, {\n\t\t\t\tpromptSnippet: readToolSystemPromptContribution.snippet,\n\t\t\t\tpromptGuidelines: readToolSystemPromptContribution.guidelines,\n\t\t\t}),\n\t\t\tcreateCodingAgentHarnessTool(\n\t\t\t\tcreateBashTool<ExecutionToolContext>({\n\t\t\t\t\tcommandPrefix: bashCommandPrefix,\n\t\t\t\t\tprepare: async (execution) => {\n\t\t\t\t\t\tconst currentHarness = getHarness();\n\t\t\t\t\t\tconst [model, thinkingLevel] = await Promise.all([\n\t\t\t\t\t\t\tcurrentHarness.getModel(),\n\t\t\t\t\t\t\tcurrentHarness.getThinkingLevel(),\n\t\t\t\t\t\t]);\n\t\t\t\t\t\tsetApexEnvironment(\"APEX_CODE_SESSION_ID\", metadata.id, execution.env);\n\t\t\t\t\t\tsetApexEnvironment(\"APEX_CODE_SESSION_FILE\", sessionFile ?? \"\", execution.env);\n\t\t\t\t\t\tsetApexEnvironment(\"APEX_CODE_PROVIDER\", model.provider, execution.env);\n\t\t\t\t\t\tsetApexEnvironment(\"APEX_CODE_MODEL\", model.id, execution.env);\n\t\t\t\t\t\tsetApexEnvironment(\"APEX_CODE_REASONING_LEVEL\", thinkingLevel, execution.env);\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\ttoolContext,\n\t\t\t\t{\n\t\t\t\t\tpromptSnippet: bashToolSystemPromptContribution.snippet,\n\t\t\t\t\tpromptGuidelines: bashToolSystemPromptContribution.guidelines,\n\t\t\t\t},\n\t\t\t),\n\t\t\tcreateCodingAgentHarnessTool(createEditTool<ExecutionToolContext>(), toolContext, {\n\t\t\t\tpromptSnippet: editToolSystemPromptContribution.snippet,\n\t\t\t\tpromptGuidelines: editToolSystemPromptContribution.guidelines,\n\t\t\t}),\n\t\t\tcreateCodingAgentHarnessTool(createWriteTool<ExecutionToolContext>(), toolContext, {\n\t\t\t\tpromptSnippet: writeToolSystemPromptContribution.snippet,\n\t\t\t\tpromptGuidelines: writeToolSystemPromptContribution.guidelines,\n\t\t\t}),\n\t\t];\n\t}\n\tconst activeToolNames = [...(providedActiveToolNames ?? tools.map((tool) => tool.name))];\n\tconst systemPrompt =\n\t\tprovidedSystemPrompt ??\n\t\t(async () => {\n\t\t\tconst currentHarness = getHarness();\n\t\t\tconst [currentTools, currentActiveToolNames] = await Promise.all([\n\t\t\t\tcurrentHarness.getTools(),\n\t\t\t\tcurrentHarness.getActiveTools(),\n\t\t\t]);\n\t\t\treturn buildCodingAgentHarnessSystemPrompt({\n\t\t\t\tcwd: env.cwd,\n\t\t\t\ttools: currentTools,\n\t\t\t\tactiveToolNames: currentActiveToolNames,\n\t\t\t\tsystemPromptOptions,\n\t\t\t});\n\t\t});\n\tconst created = await AgentHarness.create({\n\t\t...harnessOptions,\n\t\ttools,\n\t\tactiveToolNames,\n\t\tsystemPrompt,\n\t});\n\tharness = created.harness;\n\treturn created;\n}\n"]}