@sema-agent/core 5.20.0 → 5.21.1

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 (313) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/agents/agent-definition.d.ts +7 -0
  3. package/dist/agents/agent-transcript-tool.d.ts +30 -0
  4. package/dist/agents/builtin-agents.d.ts +60 -0
  5. package/dist/agents/cascade.d.ts +107 -0
  6. package/dist/agents/cumulative-stats.d.ts +56 -0
  7. package/dist/agents/observer.d.ts +162 -0
  8. package/dist/agents/peer-admission.d.ts +95 -0
  9. package/dist/agents/repair-loop.d.ts +226 -0
  10. package/dist/agents/retain-ledger.d.ts +141 -0
  11. package/dist/agents/roster-store.d.ts +105 -0
  12. package/dist/agents/send-message-tool.d.ts +92 -0
  13. package/dist/agents/session-util.d.ts +5 -0
  14. package/dist/agents/subagent-steps.d.ts +66 -0
  15. package/dist/agents/subagent.d.ts +600 -0
  16. package/dist/agents/suspend-guard.d.ts +29 -0
  17. package/dist/agents/teacher.d.ts +75 -0
  18. package/dist/agents/team.d.ts +120 -1
  19. package/dist/agents/tool-filter.d.ts +34 -0
  20. package/dist/agents/verify.d.ts +198 -0
  21. package/dist/bench/metrics.d.ts +455 -0
  22. package/dist/brain/anthropic.d.ts +30 -0
  23. package/dist/brain/circuit-breaker.d.ts +33 -0
  24. package/dist/brain/context-overflow.d.ts +60 -3
  25. package/dist/brain/degrading.d.ts +67 -0
  26. package/dist/brain/errors.d.ts +42 -0
  27. package/dist/brain/failover.d.ts +15 -0
  28. package/dist/brain/media-degrade.d.ts +39 -0
  29. package/dist/brain/model-presets.d.ts +31 -0
  30. package/dist/brain/open-responses.d.ts +19 -0
  31. package/dist/brain/openai.d.ts +46 -0
  32. package/dist/brain/reasoning.d.ts +106 -1
  33. package/dist/brain/repetition.d.ts +83 -0
  34. package/dist/brain/request-params.d.ts +56 -0
  35. package/dist/brain/retry.d.ts +46 -0
  36. package/dist/brain/routing.d.ts +12 -0
  37. package/dist/brain/status-sink.d.ts +30 -1
  38. package/dist/brain/stream-engine.d.ts +147 -0
  39. package/dist/brain/stream-shared.d.ts +34 -0
  40. package/dist/brain/terminal-cause.d.ts +31 -0
  41. package/dist/brain/timeout.d.ts +107 -0
  42. package/dist/brain/tool-call-id.d.ts +20 -0
  43. package/dist/brain/tool-call-repair.d.ts +13 -0
  44. package/dist/config/catalog.d.ts +47 -0
  45. package/dist/config/defaults.d.ts +33 -0
  46. package/dist/core/a2a-task-state.d.ts +53 -0
  47. package/dist/core/a2a.d.ts +51 -0
  48. package/dist/core/arg-summary.d.ts +62 -0
  49. package/dist/core/ask-question.d.ts +272 -2
  50. package/dist/core/auto-compaction.d.ts +467 -0
  51. package/dist/core/auto-compaction.js +20 -6
  52. package/dist/core/auto-mode-prompt-assets.d.ts +8 -0
  53. package/dist/core/auto-mode-prompt.d.ts +27 -0
  54. package/dist/core/auto-mode.d.ts +54 -3
  55. package/dist/core/auto-promote.d.ts +100 -0
  56. package/dist/core/background-agent-store.d.ts +292 -0
  57. package/dist/core/background-shell.d.ts +110 -0
  58. package/dist/core/cache-break-detector.d.ts +34 -0
  59. package/dist/core/canonical-json.d.ts +57 -0
  60. package/dist/core/checkpoint-store.d.ts +1574 -16
  61. package/dist/core/compliance.d.ts +30 -0
  62. package/dist/core/consolidate-scope.d.ts +75 -0
  63. package/dist/core/context-edit.d.ts +99 -0
  64. package/dist/core/context-guard.d.ts +46 -0
  65. package/dist/core/exec-gate.d.ts +44 -0
  66. package/dist/core/exec-output-tail.d.ts +61 -0
  67. package/dist/core/file-snapshot-store.d.ts +104 -0
  68. package/dist/core/fs-write-gate-policy.d.ts +36 -0
  69. package/dist/core/git-worktree-env.d.ts +31 -0
  70. package/dist/core/governance-codes.d.ts +19 -0
  71. package/dist/core/hooks.d.ts +608 -1
  72. package/dist/core/human-input-projection.d.ts +37 -0
  73. package/dist/core/human-input-projection.js +13 -0
  74. package/dist/core/image-downsample.d.ts +74 -0
  75. package/dist/core/locked-config.d.ts +37 -0
  76. package/dist/core/lsp-diagnostics.d.ts +77 -0
  77. package/dist/core/lsp-protocol.d.ts +29 -0
  78. package/dist/core/lsp-session.d.ts +60 -1
  79. package/dist/core/lsp.d.ts +150 -1
  80. package/dist/core/mailbox-store.d.ts +57 -0
  81. package/dist/core/mcp.d.ts +381 -0
  82. package/dist/core/media-byte-cap.d.ts +21 -0
  83. package/dist/core/memory-admission.d.ts +71 -0
  84. package/dist/core/memory-engine/content-origin.d.ts +64 -0
  85. package/dist/core/memory-engine/data-plane.d.ts +43 -0
  86. package/dist/core/memory-engine/dual-root.d.ts +24 -0
  87. package/dist/core/memory-engine/engine.d.ts +230 -0
  88. package/dist/core/memory-engine/engine.js +103 -35
  89. package/dist/core/memory-engine/file-backend.d.ts +155 -0
  90. package/dist/core/memory-engine/frontmatter.d.ts +16 -0
  91. package/dist/core/memory-engine/layout.d.ts +217 -0
  92. package/dist/core/memory-engine/memory-backend-contract.d.ts +12 -0
  93. package/dist/core/memory-engine/migrate.d.ts +9 -0
  94. package/dist/core/memory-engine/scan.d.ts +12 -0
  95. package/dist/core/memory-engine/scope-contract.d.ts +61 -1
  96. package/dist/core/memory-engine/sync-client.d.ts +87 -0
  97. package/dist/core/memory-engine/sync.d.ts +60 -0
  98. package/dist/core/memory-engine/tools.d.ts +41 -0
  99. package/dist/core/memory-engine/types.d.ts +188 -0
  100. package/dist/core/memory-recall.d.ts +141 -0
  101. package/dist/core/memory-vector.d.ts +20 -0
  102. package/dist/core/memory.d.ts +458 -0
  103. package/dist/core/message-utils.d.ts +6 -0
  104. package/dist/core/oracle-isolation.d.ts +69 -0
  105. package/dist/core/permission-rule-consent.d.ts +138 -0
  106. package/dist/core/permission-rule-model.d.ts +122 -0
  107. package/dist/core/permission-rule-store.d.ts +119 -3
  108. package/dist/core/permission-rules.d.ts +87 -1
  109. package/dist/core/present-plan-tool.d.ts +20 -0
  110. package/dist/core/pricing.d.ts +26 -0
  111. package/dist/core/property-harness.d.ts +86 -0
  112. package/dist/core/protocol-naming.d.ts +38 -0
  113. package/dist/core/protocol-table.d.ts +61 -0
  114. package/dist/core/push-queue.d.ts +1 -0
  115. package/dist/core/remote-env.d.ts +383 -1
  116. package/dist/core/retention-policy.d.ts +33 -0
  117. package/dist/core/retention.d.ts +51 -0
  118. package/dist/core/roles.d.ts +59 -0
  119. package/dist/core/runner/active-skill-scope.d.ts +34 -0
  120. package/dist/core/runner/assemble-result.d.ts +134 -0
  121. package/dist/core/runner/compaction-call-options.d.ts +97 -1
  122. package/dist/core/runner/grounding-signal.d.ts +10 -0
  123. package/dist/core/runner/image.d.ts +17 -0
  124. package/dist/core/runner/image.js +29 -15
  125. package/dist/core/runner/memory-consolidation.d.ts +60 -0
  126. package/dist/core/runner/prepare-memory.d.ts +59 -0
  127. package/dist/core/runner/prepare-task.d.ts +1011 -2
  128. package/dist/core/runner/prepare-task.js +12 -11
  129. package/dist/core/runner/prompt-suggestions.d.ts +7 -0
  130. package/dist/core/runner/runtask.d.ts +304 -3
  131. package/dist/core/runner/session-file-state-replay.d.ts +49 -0
  132. package/dist/core/runner/session-rule-policy.d.ts +58 -0
  133. package/dist/core/runner/strict-output-schema.d.ts +18 -3
  134. package/dist/core/runner/synthetic-tools.d.ts +113 -0
  135. package/dist/core/runner/teardown-bounded.d.ts +34 -0
  136. package/dist/core/runner/tool-disclosure.d.ts +227 -0
  137. package/dist/core/runner/tool-output-projection.d.ts +6 -0
  138. package/dist/core/runner/turn-attachments.d.ts +634 -0
  139. package/dist/core/runner/usage-accounting.d.ts +32 -0
  140. package/dist/core/runtime.d.ts +9 -0
  141. package/dist/core/safe-notify.d.ts +64 -0
  142. package/dist/core/safety-axis-vocab.d.ts +23 -0
  143. package/dist/core/safety-merge-corpus.d.ts +37 -0
  144. package/dist/core/scheduler.d.ts +121 -0
  145. package/dist/core/secret-env.d.ts +32 -0
  146. package/dist/core/select-model.d.ts +15 -0
  147. package/dist/core/sensitive-path-policy.d.ts +42 -0
  148. package/dist/core/session-policy-store.d.ts +94 -0
  149. package/dist/core/session-reconcile.d.ts +80 -0
  150. package/dist/core/session-store.d.ts +85 -0
  151. package/dist/core/session.d.ts +153 -0
  152. package/dist/core/shared-memory/contract.d.ts +22 -0
  153. package/dist/core/shared-memory/normalize.d.ts +123 -2
  154. package/dist/core/shared-memory/tools.d.ts +14 -0
  155. package/dist/core/shared-memory/types.d.ts +105 -0
  156. package/dist/core/shutdown-debug.d.ts +6 -0
  157. package/dist/core/side-query.d.ts +38 -0
  158. package/dist/core/side-query.js +6 -1
  159. package/dist/core/skill-tool-specifier.d.ts +72 -0
  160. package/dist/core/skills-directory.d.ts +100 -1
  161. package/dist/core/spec-contract.d.ts +89 -0
  162. package/dist/core/store-contracts/background-agent-store-contract.d.ts +31 -0
  163. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +26 -0
  164. package/dist/core/store-contracts/contract-harness.d.ts +20 -0
  165. package/dist/core/store-contracts/contract-kit-version.d.ts +27 -0
  166. package/dist/core/store-contracts/file-snapshot-store-contract.d.ts +8 -0
  167. package/dist/core/store-contracts/mailbox-store-contract.d.ts +42 -0
  168. package/dist/core/store-contracts/tool-result-store-contract.d.ts +13 -0
  169. package/dist/core/strategy-store.d.ts +37 -0
  170. package/dist/core/stub-env.d.ts +7 -0
  171. package/dist/core/surrogate-safe-slice.d.ts +35 -0
  172. package/dist/core/task-notification.d.ts +202 -0
  173. package/dist/core/task-outcome.d.ts +53 -0
  174. package/dist/core/task-registry-agent.d.ts +337 -1
  175. package/dist/core/task-registry-monitor.d.ts +12 -0
  176. package/dist/core/task-registry-shared.d.ts +540 -0
  177. package/dist/core/task-registry.d.ts +343 -0
  178. package/dist/core/task-registry.js +13 -2
  179. package/dist/core/task-tool-shape.d.ts +44 -0
  180. package/dist/core/tighten-task-spec.d.ts +21 -0
  181. package/dist/core/tool-detach.d.ts +21 -0
  182. package/dist/core/tool-errors.d.ts +131 -0
  183. package/dist/core/tool-errors.js +4 -0
  184. package/dist/core/tool-name-aliases.d.ts +27 -0
  185. package/dist/core/tool-policy.d.ts +555 -0
  186. package/dist/core/tool-result-budget.d.ts +32 -0
  187. package/dist/core/tool-result-store.d.ts +174 -1
  188. package/dist/core/tools.d.ts +45 -0
  189. package/dist/core/trace.d.ts +323 -0
  190. package/dist/core/types.d.ts +3859 -2
  191. package/dist/core/untrusted-egress.d.ts +8 -0
  192. package/dist/core/untrusted-text.d.ts +156 -0
  193. package/dist/core/usage-window-store.d.ts +95 -0
  194. package/dist/core/version.d.ts +1 -0
  195. package/dist/core/warm-resume.d.ts +17 -0
  196. package/dist/core/wiring-manifest.d.ts +169 -0
  197. package/dist/core/with-retry.d.ts +24 -0
  198. package/dist/core/workflow-journal-store.d.ts +160 -0
  199. package/dist/core/workflow-run-store-contract.d.ts +25 -0
  200. package/dist/core/workflow-run-store.d.ts +119 -0
  201. package/dist/engine/compaction/compaction.d.ts +256 -1
  202. package/dist/engine/compaction/utils.d.ts +94 -0
  203. package/dist/engine/execution-env/kill-tree.d.ts +29 -0
  204. package/dist/engine/execution-env/node-execution-env.d.ts +94 -0
  205. package/dist/engine/harness/agent-harness.d.ts +116 -0
  206. package/dist/engine/harness/agent-harness.js +3 -14
  207. package/dist/engine/harness/messages.d.ts +15 -0
  208. package/dist/engine/harness/types.d.ts +464 -2
  209. package/dist/engine/llm/diagnostics.d.ts +4 -0
  210. package/dist/engine/llm/event-stream.d.ts +3 -0
  211. package/dist/engine/llm/index.d.ts +7 -0
  212. package/dist/engine/llm/types.d.ts +500 -3
  213. package/dist/engine/llm/validation.d.ts +3 -0
  214. package/dist/engine/loop/agent-loop.d.ts +87 -2
  215. package/dist/engine/loop/runtime-deps.d.ts +7 -0
  216. package/dist/engine/loop/types.d.ts +424 -0
  217. package/dist/engine/lsp/frame-decoder.d.ts +13 -0
  218. package/dist/engine/lsp/node-lsp-manager.d.ts +107 -0
  219. package/dist/engine/lsp/stdio-lsp-transport.d.ts +7 -0
  220. package/dist/engine/session/import-validate.d.ts +27 -0
  221. package/dist/engine/session/log-digest.d.ts +93 -0
  222. package/dist/engine/session/memory-repo.d.ts +6 -0
  223. package/dist/engine/session/memory-storage.d.ts +2 -0
  224. package/dist/engine/session/session.d.ts +75 -0
  225. package/dist/engine/session/storage-base.d.ts +8 -0
  226. package/dist/fixtures/index.d.ts +36 -0
  227. package/dist/index.d.ts +16 -1
  228. package/dist/index.js +0 -1
  229. package/dist/internal/harness-types.d.ts +6 -0
  230. package/dist/internal/harness.d.ts +11 -0
  231. package/dist/internal/llm.d.ts +6 -0
  232. package/dist/orchestration/builtin-workflows.d.ts +53 -0
  233. package/dist/orchestration/dev-vm-script-runner.d.ts +19 -0
  234. package/dist/orchestration/goal.d.ts +57 -0
  235. package/dist/orchestration/goal.js +3 -0
  236. package/dist/orchestration/run-spec.d.ts +42 -0
  237. package/dist/orchestration/run-workflow-tool.d.ts +169 -0
  238. package/dist/orchestration/workflow-governance.d.ts +61 -0
  239. package/dist/orchestration/workflow-meta.d.ts +28 -0
  240. package/dist/orchestration/workflow-observe.d.ts +60 -0
  241. package/dist/orchestration/workflow-primitives.d.ts +23 -1
  242. package/dist/orchestration/workflow-sandbox-conformance.d.ts +38 -0
  243. package/dist/orchestration/workflow-script-runner.d.ts +88 -0
  244. package/dist/orchestration/workflow-script-store.d.ts +98 -0
  245. package/dist/orchestration/workflow-size-guideline.d.ts +67 -0
  246. package/dist/orchestration/workflow-types.d.ts +169 -2
  247. package/dist/orchestration/workflow.d.ts +358 -0
  248. package/dist/prompt-assembly/artifact-store.d.ts +33 -0
  249. package/dist/prompt-assembly/artifact.d.ts +25 -0
  250. package/dist/prompt-assembly/assemble.d.ts +20 -0
  251. package/dist/prompt-assembly/composer.d.ts +29 -0
  252. package/dist/prompt-assembly/epoch.d.ts +55 -1
  253. package/dist/prompt-assembly/event-registry.d.ts +35 -0
  254. package/dist/prompt-assembly/explain.d.ts +12 -0
  255. package/dist/prompt-assembly/tool-catalog.d.ts +38 -0
  256. package/dist/prompt-assembly/turn-snapshot.d.ts +40 -0
  257. package/dist/prompt-assembly/types.d.ts +115 -0
  258. package/dist/prompts/coordinator.d.ts +27 -0
  259. package/dist/prompts/default.d.ts +539 -0
  260. package/dist/prompts/simple-sections.d.ts +45 -0
  261. package/dist/prompts/supervisor.d.ts +66 -0
  262. package/dist/scenarios/env.d.ts +28 -0
  263. package/dist/scenarios/full-body.d.ts +50 -0
  264. package/dist/scenarios/scenario-registry.d.ts +60 -0
  265. package/dist/scenarios/teacher-quickstart.d.ts +27 -0
  266. package/dist/server/http.d.ts +17 -0
  267. package/dist/stores/cc/lockfile.d.ts +6 -0
  268. package/dist/stores/cc/mailbox-store.d.ts +8 -0
  269. package/dist/stores/cc/roster-adapter.d.ts +4 -0
  270. package/dist/stores/cc/sidecar-transcript.d.ts +66 -0
  271. package/dist/stores/file/background-agent-store.d.ts +24 -0
  272. package/dist/stores/file/checkpoint-store.d.ts +38 -0
  273. package/dist/stores/file/file-snapshot-store.d.ts +25 -0
  274. package/dist/stores/file/fs-atomic.d.ts +155 -0
  275. package/dist/stores/file/index.d.ts +89 -0
  276. package/dist/stores/file/mailbox-store.d.ts +36 -0
  277. package/dist/stores/file/memory-store.d.ts +82 -0
  278. package/dist/stores/file/permission-rule-store.d.ts +79 -0
  279. package/dist/stores/file/session-policy-store.d.ts +28 -0
  280. package/dist/stores/file/session-store.d.ts +40 -0
  281. package/dist/stores/file/shared-ledger.d.ts +83 -0
  282. package/dist/stores/file/tool-result-store.d.ts +11 -0
  283. package/dist/stores/file/usage-window-store.d.ts +18 -0
  284. package/dist/stores/file/workflow-journal-store.d.ts +100 -0
  285. package/dist/stores/file/workflow-run-store.d.ts +11 -0
  286. package/dist/tools/fs/bash-readonly-classifier.d.ts +282 -0
  287. package/dist/tools/fs/encoding.d.ts +60 -0
  288. package/dist/tools/fs/fs-bash.d.ts +133 -0
  289. package/dist/tools/fs/fs-pdf.d.ts +28 -0
  290. package/dist/tools/fs/fs-search-tools.d.ts +5 -0
  291. package/dist/tools/fs/fs-search-tools.js +0 -1
  292. package/dist/tools/fs/fs-shared.d.ts +360 -0
  293. package/dist/tools/fs/fs-write.d.ts +16 -0
  294. package/dist/tools/fs/gh-rate-limit.d.ts +22 -0
  295. package/dist/tools/fs/index.d.ts +79 -0
  296. package/dist/tools/fs/notebook.d.ts +56 -0
  297. package/dist/tools/fs/pdf.d.ts +70 -0
  298. package/dist/tools/fs/pdf.js +8 -2
  299. package/dist/tools/fs/repo-map.d.ts +10 -0
  300. package/dist/tools/fs/safety.d.ts +376 -0
  301. package/dist/tools/fs/search.d.ts +131 -0
  302. package/dist/tools/loop-tick.d.ts +24 -0
  303. package/dist/tools/monitor.d.ts +55 -0
  304. package/dist/tools/scheduler-tools.d.ts +51 -0
  305. package/dist/tools/sql-adapters.d.ts +18 -0
  306. package/dist/tools/sql.d.ts +25 -0
  307. package/dist/tools/task-list.d.ts +77 -0
  308. package/dist/tools/todo.d.ts +8 -0
  309. package/dist/tools/web.d.ts +184 -0
  310. package/dist/tools/worktree.d.ts +81 -0
  311. package/package.json +2 -2
  312. package/dist/tools/gitea-issue.d.ts +0 -13
  313. package/dist/tools/gitea-issue.js +0 -75
@@ -2,17 +2,43 @@ import { type SessionWarmup } from "../../core/lsp-session.js";
2
2
  import { type LspChildProcess } from "./stdio-lsp-transport.js";
3
3
  import { type LspServerManager, type LspSession, type LspReadText } from "../../core/lsp.js";
4
4
  import type { ExecutionEnv } from "../../internal/harness-types.js";
5
+ /**
6
+ * Default language → server command table (the DETERMINED supported set). Each value is a `command [args…]`
7
+ * whose binary must be on the host `PATH`; absent ⇒ that language degrades. Mirrors the servers service bakes
8
+ * into its sandbox templates (so TOC & TOB expose the SAME languages when installed), plus the common
9
+ * rust/c/cpp servers a local dev box usually has. Override/extend via {@link NodeLspManagerOptions.servers}
10
+ * (a `null` value disables a language). All of these speak LSP over stdio by default.
11
+ */
5
12
  export declare const DEFAULT_LSP_SERVERS: Readonly<Record<string, string>>;
13
+ /** Spawn a child (default). Resolves the child on a successful `spawn`, or `undefined` on `error` (ENOENT =
14
+ * server not installed → the manager degrades that language). Waiting for the 'spawn'/'error' race before use
15
+ * is CRITICAL: `spawn()` returns synchronously but ENOENT fires 'error' asynchronously (CC's LSPClient §1.5). */
6
16
  export type LspSpawn = (command: string, args: string[], cwd: string, signal?: AbortSignal) => Promise<LspChildProcess | undefined>;
7
17
  export interface NodeLspManagerOptions {
18
+ /** Override/extend {@link DEFAULT_LSP_SERVERS} (merged over it; a `null` value disables that language). */
8
19
  servers?: Record<string, string | null>;
20
+ /** Injectable spawn (tests supply a fake server; default = {@link defaultLspSpawn} over `child_process.spawn`). */
9
21
  spawn?: LspSpawn;
22
+ /** Read a file's CURRENT text for the session's didOpen/didChange re-sync (default = local `fs.readFile` utf8). */
10
23
  readText?: LspReadText;
24
+ /** Resolve the server `cwd`/`rootUri` for a file (default = env.cwd ?? nearest project marker ?? file dir). */
11
25
  resolveRoot?: (filePath: string, env?: ExecutionEnv) => string;
26
+ /** Observability hook (open/heal/degrade/evict events). */
12
27
  log?: (event: string, fields: Record<string, unknown>) => void;
28
+ /** Warm-up window override (see {@link TransportLspSession}); default 10s/1s. */
13
29
  warmup?: SessionWarmup;
30
+ /** Max concurrently-cached language servers before LRU eviction (default 16, min 1). A safety net bounding
31
+ * the cache when a deployment can't call {@link NodeLspManager.evict} at task-end (e.g. ephemeral/worktree
32
+ * roots). Each cached server is a real process (jdtls = a JVM), so keep this modest. */
14
33
  maxSessions?: number;
34
+ /** Idle-TTL (ms) after which an unused server is auto-reclaimed by a background sweep (default 600_000 = 10
35
+ * min; 0 disables). Self-healing complement to {@link NodeLspManager.evict}: a deployment that can't call
36
+ * `evict` at task-end still won't leak — an abandoned server dies on its own. An actively reused server never
37
+ * goes idle (its last-used stamp refreshes on every lookup), so a modest TTL doesn't churn the happy path. */
15
38
  idleTtlMs?: number;
39
+ /** design/121: the workspace diagnostics registry every session feeds from publishDiagnostics.
40
+ * WORKSPACE-scoped, not server-scoped — it survives heal/evict (diagnostics belong to files, not to a
41
+ * server instance). Absent ⇒ notifications stay dropped (pre-121 behavior byte-for-byte). */
16
42
  diagnostics?: import("../../core/lsp-diagnostics.js").LspDiagnosticsRegistry;
17
43
  }
18
44
  export declare class NodeLspManager implements LspServerManager {
@@ -22,33 +48,114 @@ export declare class NodeLspManager implements LspServerManager {
22
48
  private readonly resolveRootFn;
23
49
  private readonly log;
24
50
  private readonly warmup?;
51
+ /** design/121: the workspace diagnostics registry (see {@link NodeLspManagerOptions.diagnostics}) —
52
+ * public so the Runner drains it at turn boundaries via {@link LspServerManager.diagnostics}. */
25
53
  readonly diagnostics: import("../../core/lsp-diagnostics.js").LspDiagnosticsRegistry;
26
54
  private readonly maxSessions;
27
55
  private readonly idleTtlMs;
28
56
  private sweepTimer?;
57
+ /** `<language> <root>` → the live session + its root + last-used stamp (reused across ops; healed when its
58
+ * transport dies; idle-TTL swept; LRU-evicted over {@link maxSessions}; `evict(root)` drops a task's servers
59
+ * at task-end). Space-separated key is unambiguous — a languageId never contains a space. */
29
60
  private readonly cache;
61
+ /** In-flight opens (concurrent ops on the same language+root share ONE spawn/initialize). Tracks each open's
62
+ * `root` + a `cancelled` flag so {@link evict}/{@link dispose} can reclaim a server whose open resolves AFTER
63
+ * the teardown already ran (else its `.then` caches a live child that nothing reclaims — permanently after
64
+ * dispose, since the sweep timer is cleared). */
30
65
  private readonly opening;
66
+ /** RB-376 — the NEGATIVE spawn cache, the missing twin of {@link cache}: a `(language, root)` key
67
+ * whose real `spawn()` already failed (binary not on PATH). Without it, every successful
68
+ * Edit/Write/NotebookEdit re-triggered a full spawn attempt for the same missing server — a
69
+ * production leg recorded 205 `lsp_spawn_degraded` events with the model never calling LSP once.
70
+ * Same key construction as the positive cache. NO TTL by design: a missing binary does not appear
71
+ * mid-task, and a time-based retry would just resume the re-spawn storm — {@link clearFailed} is
72
+ * the explicit recovery valve. `attempts` counts suppressed hits (first failure logs once via
73
+ * `lsp_spawn_degraded`; cache hits stay silent; the count surfaces on the cleared log line). */
31
74
  private readonly failed;
75
+ /** HRD-LSP-14: consecutive `initialize` failures per key, BEFORE the latch (see {@link INIT_FAILURE_LATCH}). */
32
76
  private readonly initFailures;
77
+ /** Set by {@link dispose}: an in-flight open that resolves after dispose self-closes instead of caching. */
33
78
  private disposed;
34
79
  constructor(opts?: NodeLspManagerOptions);
80
+ /** Close + drop every server idle past {@link idleTtlMs}. Runs on a timer; best-effort. */
35
81
  private sweepIdle;
36
82
  sessionFor(filePath: string, signal?: AbortSignal, env?: ExecutionEnv): Promise<LspSession | undefined>;
83
+ /** Spawn + initialize a fresh session for `key`, deduping concurrent opens. `carry` = files to re-open
84
+ * before the session becomes visible (heal). */
37
85
  private open;
86
+ /** LRU-evict (close) the least-recently-used server(s) until there is room for one more under {@link maxSessions}.
87
+ * A safety net: without an explicit {@link evict}, a long-lived process spawning tasks with EPHEMERAL roots
88
+ * (worktree / per-task cwd) would otherwise leak one heavyweight language server per (task × language). */
38
89
  private evictOverCap;
90
+ /**
91
+ * Evict + kill every cached language server rooted at `root`. Call this at TASK-END for an ephemeral/worktree
92
+ * cwd so a heavyweight server (e.g. a jdtls JVM) doesn't outlive the task that spawned it — the deterministic
93
+ * complement to the LRU cap. `root` must match what `resolveRoot` produced for the task (the host lane uses the
94
+ * task's `env.cwd`). Best-effort + idempotent (an unknown/already-evicted root is a no-op).
95
+ */
39
96
  evict(root: string): Promise<void>;
97
+ /**
98
+ * RB-376 — drop negative spawn-cache entries so the NEXT op may retry the real spawn: the explicit
99
+ * recovery valve for "I just installed that language server" (the entries deliberately have no TTL —
100
+ * see the `failed` field doc). No arg ⇒ clear everything; `root` ⇒ only that root's entries (the
101
+ * {@link evict} shape). Each cleared entry logs its suppressed-attempt count (evict-log parity).
102
+ * Idempotent; an unknown root is a no-op.
103
+ */
40
104
  clearFailed(root?: string): void;
105
+ /**
106
+ * HRD-LSP-14 (optional {@link LspServerManager} member): WHY the last `sessionFor` for this file degraded.
107
+ * `openSession` collapses three very different situations into one `undefined` — the language has no
108
+ * server configured, the binary is not installed, or the server IS installed and failed to initialize —
109
+ * and the tool rendered the same "no language server for its language in this environment" for all of
110
+ * them. The first is a fact about the deployment; the third is an incident the operator can fix, and
111
+ * telling the model (and the transcript) they are the same thing is how "we have no LSP for Go" survives
112
+ * for months in an environment where gopls is installed and crashing.
113
+ */
41
114
  unavailableReason(filePath: string, env?: ExecutionEnv): string | undefined;
42
115
  private openSession;
43
116
  private serverCmd;
117
+ /** Kill every running server + stop the idle sweep (call on runner/deployment shutdown). Best-effort. */
44
118
  dispose(): Promise<void>;
45
119
  }
120
+ /** Resolve a file path to a languageId via its extension (undefined = no mapping → degrade). */
46
121
  export declare function languageFor(filePath: string): string | undefined;
122
+ /** CC 2.1.220's LSP file cap — single-sourced in core (`src/core/lsp.ts`), where the tool-layer check
123
+ * enforces it model-visibly; re-exported here so engine-path importers keep working. */
47
124
  export { MAX_LSP_FILE_BYTES } from "../../core/lsp.js";
125
+ /**
126
+ * RB-232(黑板 [1937]): the local default {@link LspReadText}, hardened with a stat-first precondition (CC
127
+ * 2.1.220 validateInput does the same before ever reading — "Path is not a file", pretty220.js ~474700).
128
+ * The stat check is the LOAD-BEARING part, do not "simplify" it away: a plain `readFile` on a FIFO/socket
129
+ * blocks forever on the FIRST read and PINS a libuv threadpool thread (default pool = 4) for the process
130
+ * lifetime — measured: `readFile(fifo, { signal })` with an abort fired at 2s was still unsettled at 10s,
131
+ * because Node only checks the signal between chunk reads. `{ signal }` is kept as a bonus for regular
132
+ * files; it cannot rescue the FIFO case on its own. (The tool layer additionally rejects such paths via
133
+ * `env.fileInfo` before any read — this is defense in depth for direct/embedder callers.)
134
+ */
48
135
  export declare const defaultLspReadText: LspReadText;
136
+ /** service [377] ask ②: on Windows, npm-global language servers materialize as `.cmd` shims and
137
+ * Node 20+ `spawn(cmd, args)` without a shell rejects them (EINVAL, CVE-2024-27980 hardening) —
138
+ * every DEFAULT_LSP_SERVERS entry would silently degrade to "no LSP". `shell:true` routes through
139
+ * cmd.exe so PATHEXT/.cmd resolution works. Injection surface: `command`/`args` come from
140
+ * LspServerSpec (deployment configuration, trusted) or DEFAULT_LSP_SERVERS constants — never from
141
+ * the model. Exported as a pure function so the win32 branch is testable off-platform. */
49
142
  export declare function lspSpawnOptions(cwd: string): {
50
143
  cwd: string;
51
144
  stdio: ["pipe", "pipe", "ignore"];
52
145
  shell?: boolean;
53
146
  };
147
+ /**
148
+ * Default spawn over `child_process.spawn`, resolving on 'spawn' / `undefined` on 'error' (ENOENT = degrade)
149
+ * / REJECTING with the errno error for any other spawn failure (see {@link NodeLspManager}'s `failed` map:
150
+ * "not installed" is permanent and worth caching, EACCES/EMFILE/a transient cwd is not — HRD-LSP-15).
151
+ *
152
+ * 🔴 HRD-LSP-4 — the ABSORBER below is load-bearing, do not "simplify" it away. `ChildProcess` is an
153
+ * `EventEmitter`, and an 'error' emitted with ZERO 'error' listeners is re-thrown by Node as an uncaught
154
+ * exception — in a library that means TAKING THE HOST PROCESS DOWN. `spawn()` returns synchronously while
155
+ * ENOENT arrives asynchronously (CC's LSPClient §1.5), so every path that removes our own listener before
156
+ * that event lands is a live crash: `onAbort` (cancel a spawn that is about to fail = a routine task
157
+ * cancellation) and `onSpawn` (the window between resolving and `StdioLspTransport`'s constructor attaching
158
+ * its handler). A permanent no-op listener, attached before anything can fire and never removed, makes the
159
+ * emitter unable to throw; the transport's own handler still receives every runtime error afterwards.
160
+ */
54
161
  export declare const defaultLspSpawn: LspSpawn;
@@ -1,4 +1,5 @@
1
1
  import { type LspTransport } from "../../core/lsp.js";
2
+ /** The slice of a spawned child process the transport uses (so a test can drive a fake duplex — no real spawn). */
2
3
  export interface LspChildProcess {
3
4
  stdin: {
4
5
  write(data: Buffer): void;
@@ -9,6 +10,7 @@ export interface LspChildProcess {
9
10
  };
10
11
  on(event: "exit" | "error", cb: (arg?: unknown) => void): void;
11
12
  kill(signal?: string): void;
13
+ /** Present on a real child process; used on win32 (shell:true shim) to tree-kill on close. */
12
14
  pid?: number;
13
15
  }
14
16
  export declare class StdioLspTransport implements LspTransport {
@@ -18,11 +20,16 @@ export declare class StdioLspTransport implements LspTransport {
18
20
  private readonly pending;
19
21
  private isClosed;
20
22
  private readonly decode;
23
+ /** design/121: server→client notification subscribers (publishDiagnostics, …). Empty = pre-121 behavior. */
21
24
  private readonly notificationHandlers;
22
25
  constructor(child: LspChildProcess, requestTimeoutMs?: number);
26
+ /** Manager-visible liveness: evict + reopen instead of reusing a dead server (crashed / killed). */
23
27
  get closed(): boolean;
24
28
  private onMessage;
29
+ /** design/121 {@link LspTransport.onNotification}: subscribe to server notifications; returns unsubscribe. */
25
30
  onNotification(handler: (method: string, params: unknown) => void): () => void;
31
+ /** RB-232: every failAll caller — child exit, child error, AND deliberate close() — means "server is
32
+ * gone" to the model, so all are branded `server_terminated` alike (no exit-vs-close distinction). */
26
33
  private failAll;
27
34
  private send;
28
35
  request(method: string, params: unknown, signal?: AbortSignal): Promise<unknown>;
@@ -1,18 +1,45 @@
1
1
  import { type SessionTreeEntry } from "../harness/types.js";
2
+ /** Options for {@link StreamingImportValidator} / {@link validateEntriesForImport}. */
2
3
  export interface ImportValidatorOptions {
4
+ /**
5
+ * design/171 §6.4 — the import door's SECOND WRITE GATE for `UserMessage.actor`. Default `false`
6
+ * (fail-closed): imported history has its `actor` assertions STRIPPED — an importer must never
7
+ * re-assert who spoke in a history it did not witness (`hostAsserted:true` is an ingress-derived
8
+ * claim, and import is not an ingress). `true` = the operator DECLARES the source trusted
9
+ * (e.g. a same-deployment backend migration) and well-formed assertions are preserved verbatim;
10
+ * shape-poisoned ones are still stripped like the sibling metadata fields.
11
+ */
3
12
  preserveActorAssertions?: boolean;
4
13
  }
5
14
  export declare class StreamingImportValidator {
6
15
  private readonly seen;
16
+ /** RB-129: entry id → parentId, so the compaction floor check can walk ANCESTRY rather than stream order. */
7
17
  private readonly parentOf;
8
18
  private rootCount;
9
19
  private runningLeaf;
10
20
  private done;
21
+ /** design/171 — see {@link ImportValidatorOptions.preserveActorAssertions}. */
11
22
  private readonly preserveActorAssertions;
12
23
  constructor(options?: ImportValidatorOptions);
24
+ /** Validate ONE entry, in oldest-first order. Throws `SessionError("invalid_session")` on the first violation
25
+ * (duplicate id, or a parent/structural reference not stepped before this entry). */
13
26
  step(entry: SessionTreeEntry): void;
27
+ /** Finalize the stream: exactly one root (for a non-empty log) + the derived leaf resolves to a stepped entry.
28
+ * Returns the resolved leaf id (null for an empty session). Throws on violation; single-use. */
14
29
  finish(): {
15
30
  leafId: string | null;
16
31
  };
17
32
  }
33
+ /**
34
+ * Validate a verbatim session-entry log for cross-backend IMPORT (2c session-sync, service [266]②). The ARRAY
35
+ * form of {@link StreamingImportValidator} (ONE source of truth — this just drives step()/finish() over the
36
+ * array, kept for `fork`/tests that already hold the whole log). Fail-CLOSED: any violation throws
37
+ * `SessionError("invalid_session")` and nothing is written.
38
+ *
39
+ * Returns the validated log with ids/parents/timestamps preserved (the imported session is
40
+ * byte-identical to the source; only the owner is re-stamped by the caller, not here), modulo the
41
+ * single engine-provenance normalization carve-out ([c209-C] R4 double-stamp + R5 shape + design/171
42
+ * actor gate) documented on {@link StreamingImportValidator} — applied to a PROTECTED COPY of each
43
+ * message entry, never to the caller's shared objects (see the clone note in the body).
44
+ */
18
45
  export declare function validateEntriesForImport(entries: SessionTreeEntry[], options?: ImportValidatorOptions): SessionTreeEntry[];
@@ -1,5 +1,98 @@
1
1
  import type { SessionTreeEntry } from "../harness/types.js";
2
+ /**
3
+ * [1701] session-sync — the SHARED content digest for a session entry log.
4
+ *
5
+ * ## The gap this closes
6
+ * `classifySyncRelationshipByIds` compares only the SET of entry ids. Entry ids are uuidv7, not content
7
+ * addresses, so "same ids, different payload" is structurally ordinary — and the wire accepts whatever
8
+ * entries a client sends. The measured consequences were: an `identical` 200 returned while the destination
9
+ * still holds different text; a `fast_forward` classified "clean append, safe to apply" while it destroys
10
+ * corrections on the destination without the 409 that promise depends on.
11
+ *
12
+ * ## Why RE-computing a canonical form on both sides is safe HERE (and is not, elsewhere)
13
+ * There is a load-bearing ruling against exactly this pattern — design/80 r3, "绝不让两个运行时各算
14
+ * canonical-JSON" — which is why `boundInputHash` is minted once and treated as opaque by every consumer,
15
+ * and why `canonicalize` is not exported from the package index. Read at the source rather than through its
16
+ * paraphrase in `canonical-json.ts`, that ruling rests on TWO legs, and only one of them still stands:
17
+ *
18
+ * 1. **There was no vetted canonical serializer.** The verbatim reasoning is "deps 只 typebox+MCP、core 无
19
+ * canonical/stable JSON serializer、JS JSON.stringify 非规范". The remedy prescribed in the same
20
+ * sentence was "ship 一个 vetted canonical serializer" — which shipped as `canonical-json.ts`. This leg
21
+ * described the state of the codebase at the time, and it no longer holds.
22
+ * 2. **The blast radius of a false mismatch**: "false-mismatch 会 fail-closed 拒掉合法审批". A serializer
23
+ * divergence on the approval path DENIES a legitimate human decision. This leg stands, and it is the
24
+ * one that decides whether the ruling transfers to a new use.
25
+ *
26
+ * Here the blast radius is inverted, and deliberately so:
27
+ * - digests EQUAL ⇒ short-circuit as `identical`;
28
+ * - digests DIFFER ⇒ **do not short-circuit** — run the full sync path.
29
+ *
30
+ * So a serializer divergence between two core versions costs extra work (a sync that would have short-
31
+ * circuited now runs), never a wrong answer and never a refusal. That asymmetry is the whole reason this
32
+ * function may be exported while `canonicalize` itself stays internal. **Consumers must preserve it**: a
33
+ * digest mismatch may never be turned into an error, a 409, or a refusal to sync — only into "compare
34
+ * properly instead of trusting the ids".
35
+ *
36
+ * ## Versioning
37
+ * `test/session-log-digest.test.ts` freezes the digest of a fixture that exercises every value shape the
38
+ * serializer distinguishes. If a change moves a frozen value, the documented response is to ADD a row for a
39
+ * new {@link SESSION_LOG_DIGEST_SCHEME} — never to edit a frozen value in place, because peers on different
40
+ * core versions compare these strings to each other and the old row records what was on the wire.
41
+ *
42
+ * A scheme mismatch is reported as "not comparable", which — by the rule above — degrades to the full sync
43
+ * path, exactly like a value mismatch.
44
+ *
45
+ * ## What is hashed, and why not the engine's canonical serializer
46
+ * v1 hashed `canonicalize` (the approval-binding serializer). An adversarial review of the shipped v1 found
47
+ * that choice unsound for a WIRE digest, on four counts that all trace to the same root — that serializer is
48
+ * built for a single runtime comparing a value to ITSELF, not for two runtimes comparing what they hold:
49
+ *
50
+ * - It distinguishes `{a: undefined}` from `{}` by design. On a wire there is no such distinction, and core
51
+ * itself produces own-keys-set-to-undefined routinely (clearing a label; a custom entry with no data). So
52
+ * the SAME log digested different on an in-memory backend than after a JSON round-trip — measured end to
53
+ * end — and the short-circuit this whole mechanism exists for would simply never have fired.
54
+ * - Its number token has no terminator, so a numeric value can run into the following key: two genuinely
55
+ * different payloads produced one canonical form (demonstrated).
56
+ * - It collapses every host object to `o0:{}` (any two Dates, any two Maps) and everything past a depth
57
+ * limit to one sentinel — acceptable when the alternative is refusing an approval, not acceptable when the
58
+ * consequence is "these two logs are the same, skip the sync".
59
+ * - Lone surrogates became U+FFFD at the UTF-8 hashing step, so a payload that survived one byte round-trip
60
+ * on one peer collided with the original on the other.
61
+ *
62
+ * v2 hashes a **stable JSON serialization of the JSON-representable form** instead: each entry goes through
63
+ * `JSON.stringify`/`parse` (so both peers digest the same thing the wire carries), then a key-sorted
64
+ * serializer. JSON's own grammar is unambiguous — strings are quoted, numbers are delimited — so the
65
+ * adhesion above cannot occur; `JSON.stringify` escapes lone surrogates as `\uXXXX`; depth is unlimited; and
66
+ * a Date/Map has already become its wire form before hashing. It also means this module no longer shares a
67
+ * serializer with the approval path at all, which removes the tension with that path's ruling at the root
68
+ * rather than arguing about its blast radius.
69
+ *
70
+ * ## What is covered
71
+ * Every field of every entry that survives to JSON, in the order given — id, parentId, type, timestamp and
72
+ * the whole payload. Key ORDER within an entry is not (that is what the sort is for); entry order is (a
73
+ * reordered log is a different log — one of the three measured failure shapes).
74
+ */
2
75
  export declare const SESSION_LOG_DIGEST_SCHEME = "sema-log-v3";
76
+ /** Digest of ONE entry (same scheme and rules as {@link sessionLogDigest}; useful for per-entry reporting). */
3
77
  export declare function sessionEntryDigest(entry: SessionTreeEntry): string;
78
+ /**
79
+ * Digest of an ORDERED entry log. Two logs with the same digest hold the same entries, in the same order,
80
+ * with the same payloads and the same parent structure — as far as JSON can express them.
81
+ *
82
+ * Length-prefixing each entry's serialized form keeps concatenation unambiguous (without it, two adjacent
83
+ * entries could be re-partitioned into a different pair with the same bytes). The domain tag (`log` vs
84
+ * `entry`) keeps the two digest families from ever being equal by accident.
85
+ */
4
86
  export declare function sessionLogDigest(entries: readonly SessionTreeEntry[] | null | undefined): string;
87
+ /**
88
+ * Are two digests comparable at all? False for a different scheme version, an absent value, or anything that
89
+ * is not a well-formed digest string.
90
+ *
91
+ * Every rejection path returns `false` rather than throwing. That is load-bearing: this function sits on the
92
+ * classification path, and the contract it serves says a digest problem must degrade to "do the full sync",
93
+ * never to an error. v1 guarded only `undefined` — but JSON has no `undefined`, so "the peer sent no digest"
94
+ * arrives as `null`, which threw. v1 also derived the scheme with `slice(0, indexOf(":sha256:"))`, and a
95
+ * missing separator yields -1, so any string shaped like the scheme plus one character passed as a valid
96
+ * digest of that scheme — two peers holding the same truncated non-digest would have compared equal.
97
+ */
5
98
  export declare function sessionLogDigestsComparable(a: string | null | undefined, b: string | null | undefined): boolean;
@@ -10,7 +10,13 @@ export declare class InMemorySessionRepo implements SessionRepo<SessionMetadata,
10
10
  list(): Promise<SessionMetadata[]>;
11
11
  delete(metadata: SessionMetadata): Promise<void>;
12
12
  fork(sourceMetadata: SessionMetadata, options: SessionForkOptions): Promise<Session>;
13
+ /** 2c session-sync ([266]②): the FULL log for export. InMemory holds everything (no F3 floor), so
14
+ * `getEntries()` IS the full oldest-first log with `id`/`parentId` verbatim. */
13
15
  exportEntries(sessionId: string): Promise<SessionTreeEntry[]>;
16
+ /** 2c session-sync ([266]②): import a verbatim log into `sessionId`. The single invariant gate runs first
17
+ * ({@link validateEntriesForImport}, fail-closed); `owner` is a durable multi-tenant concept that the local
18
+ * in-memory backend has no field for, so it is accepted but unused here. design/171: the operator's
19
+ * trusted-import flag is forwarded to the gate that persists — see SessionRepo.importEntries. */
14
20
  importEntries(sessionId: string, owner: string | undefined, entries: SessionTreeEntry[], options?: {
15
21
  preserveActorAssertions?: boolean;
16
22
  }): Promise<void>;
@@ -1,9 +1,11 @@
1
1
  import type { SessionMetadata, SessionTreeEntry, SessionWriteOptions } from "../harness/types.js";
2
2
  import { BaseSessionStorage } from "./storage-base.js";
3
+ /** Volatile session storage used by tests and in-process harness callers. */
3
4
  export declare class InMemorySessionStorage<TMetadata extends SessionMetadata = SessionMetadata> extends BaseSessionStorage<TMetadata> {
4
5
  constructor(options?: {
5
6
  entries?: SessionTreeEntry[];
6
7
  metadata?: TMetadata;
8
+ /** Branch floor for a bounded-window load (F3); the entries must start at this id. */
7
9
  floorEntryId?: string | null;
8
10
  });
9
11
  setLeafId(leafId: string | null, opts?: SessionWriteOptions): Promise<void>;
@@ -3,7 +3,15 @@ import type { AgentMessage } from "../loop/types.js";
3
3
  import type { Session, SessionContext, SessionMetadata, SessionStorage, SessionTreeEntry, WorkspaceState } from "../harness/types.js";
4
4
  import type { BuildContextOptions } from "../harness/types.js";
5
5
  import type { PromptEpochDescriptor } from "../../prompt-assembly/epoch.js";
6
+ /** Build model context from the active session branch and its latest state markers.
7
+ * `opts` (window awareness, see {@link BuildContextOptions}): when the caller declares the
8
+ * consuming model's window, the compaction summary's retained invoked-skills area is defensively
9
+ * re-clamped so 「summary + retained area」 can never push the rebuilt context out of that window
10
+ * on its own. Absent ⇒ byte-identical legacy rendering. */
6
11
  export declare function buildSessionContext(pathEntries: SessionTreeEntry[], opts?: BuildContextOptions): SessionContext;
12
+ /** High-level session API backed by pluggable tree storage. Implements the vendored `Session` CONTRACT
13
+ * (`SessionContract`) the harness consumes — dependency inversion so the vendored substrate needs no
14
+ * `import` of this concrete class (de-vendoring prep); `implements` makes the contract drift caught here. */
7
15
  export declare class StoredSession<TMetadata extends SessionMetadata = SessionMetadata> implements Session<TMetadata> {
8
16
  private storage;
9
17
  constructor(storage: SessionStorage<TMetadata>);
@@ -20,23 +28,90 @@ export declare class StoredSession<TMetadata extends SessionMetadata = SessionMe
20
28
  appendMessage(message: AgentMessage): Promise<string>;
21
29
  appendThinkingLevelChange(thinkingLevel: string): Promise<string>;
22
30
  appendModelChange(provider: string, modelId: string): Promise<string>;
31
+ /**
32
+ * Campaign S3 (prompt-assembly §9.2): persist the session's prompt-epoch pin as a first-class
33
+ * typed entry. Written at session start (BEFORE the first conversation entry — the resume path
34
+ * must never see user entries with no pin) and on legacy migration; compactions restate the pin
35
+ * in their own `details.promptEpoch` instead (same-CAS with the new baseline).
36
+ */
23
37
  appendPromptEpoch(descriptor: PromptEpochDescriptor): Promise<string>;
38
+ /**
39
+ * design/150 (RB-25): persist the listing announced name-sets as a first-class typed entry.
40
+ * Called best-effort at every listing COMMIT point (the run loop's announce mirror sites) —
41
+ * an append failure degrades to the checkpoint-mirror/transcript-probe rungs, never fails the run.
42
+ */
24
43
  appendAnnouncedListing(snapshot: {
25
44
  agents?: readonly string[];
26
45
  skills?: readonly string[];
27
46
  models?: readonly string[];
28
47
  }): Promise<string>;
48
+ /**
49
+ * design/155 (cli [1580]): persist the settle-time workspace state (tracked cwd + active
50
+ * EnterWorktree session) as a first-class typed entry. Called best-effort at task settle when the
51
+ * state changed — an append failure degrades to "the next turn starts at the task root", exactly
52
+ * the pre-155 behavior, never fails the run. The same shape gate guards append, read, and the
53
+ * import door (self-generated data must round-trip its own validator).
54
+ */
29
55
  appendWorkspaceState(state: WorkspaceState): Promise<string>;
56
+ /**
57
+ * design/155: recover the workspace-state snapshot for the ACTIVE branch — the nearest
58
+ * `workspace_state` entry walking back from the leaf (SNAPSHOT semantics: first hit wins; a CLEAR
59
+ * snapshot — no cwd, no worktree — is a real hit that shadows older state). Malformed entries are
60
+ * skipped (defense in depth behind the import door). Undefined ⇒ no snapshot VISIBLE on this
61
+ * branch: a fresh session, a pre-155 session, or a bounded-tail backend whose load floor cut every
62
+ * snapshot — all degrade to fresh defaults (the task root), the pre-155 behavior. Rewind gets the
63
+ * correct semantics for free: the branch path ends at the cut, so the walk finds the state that
64
+ * was current THEN.
65
+ */
30
66
  getWorkspaceState(): Promise<WorkspaceState | undefined>;
67
+ /**
68
+ * design/150 (RB-25): recover the announced listing snapshot for the ACTIVE branch — the nearest
69
+ * carrier walking back from the leaf (an `announced_listing` entry or a compaction's
70
+ * `details.announcedListings` restatement; SNAPSHOT semantics: first hit wins). Malformed
71
+ * carriers are skipped (defense in depth behind the import door), never returned.
72
+ * Undefined ⇒ no carrier VISIBLE on this branch — callers fall back to the checkpoint mirror /
73
+ * transcript probe. Honest bound (codex 1358 F2, RB-33): a bounded-tail backend whose load floor
74
+ * cut every carrier (and a rewind cut between the floor and the newest compaction) also returns
75
+ * undefined — the ladder degrades to the lower rungs (worst case a duplicate re-announce, never a
76
+ * loss). A floor-anchor seam (the getEpochAnchor analog) is deliberately deferred until a real
77
+ * deployment hits that window.
78
+ */
31
79
  getAnnouncedListing(): Promise<{
32
80
  agents?: string[];
33
81
  skills?: string[];
34
82
  models?: string[];
35
83
  } | undefined>;
84
+ /**
85
+ * Recover the pinned prompt epoch for the ACTIVE branch (campaign S3). Walks the branch from the
86
+ * leaf backwards: the nearest `compaction` entry's `details.promptEpoch` restatement wins (the
87
+ * bounded-tail/F3 floor may have cut everything older); else the nearest `prompt_epoch` entry
88
+ * (root pin / legacy migration). Undefined ⇒ pre-epoch session (upgrade-in-place migration path).
89
+ * Rewind/resumeAt legs get the SAME semantics for free: the branch path already ends at the
90
+ * historical cut point, so the walk finds the pin that was current THEN, not the latest.
91
+ */
36
92
  getPromptEpoch(): Promise<import("../../prompt-assembly/epoch.js").PromptEpochDescriptor | undefined>;
93
+ /**
94
+ * RB-103 (2026-07-25, defect probe): the compaction entry CARRIES the branch's derived conversation
95
+ * state — thinking level and active model — restated automatically here.
96
+ *
97
+ * Both are reconstructed by scanning path entries ({@link buildSessionContext}), so a bounded-tail (F3)
98
+ * wake that loads only `[firstKeptEntryId .. leaf]` cannot see a `thinking_level_change` /
99
+ * `model_change` that sits below the floor: the user's chosen thinking level silently reverted to "off"
100
+ * and the model to null. Until RB-95 the compaction cut point's back-off loop happened to drag those
101
+ * entries above the floor much of the time — an accident, not a mechanism, and one that broke the
102
+ * floor's own "always a user/assistant message" contract to do it.
103
+ *
104
+ * Unlike `promptEpoch` / `announcedListings` — which the CALLER restates because selecting them needs
105
+ * caller-side logic — these two are derived from this session's own branch, so the session computes
106
+ * them itself and every caller of `appendCompaction` gets the carry for free. A caller-supplied
107
+ * `details` still wins if it names the same keys (explicit intent beats the automatic restatement).
108
+ */
37
109
  appendCompaction(summary: string, firstKeptEntryId: string, tokensBefore: number, details?: unknown, fromHook?: boolean): Promise<string>;
110
+ /** Append a non-LLM transcript marker for harness-specific state. */
38
111
  appendCustomEntry(customType: string, data?: unknown): Promise<string>;
112
+ /** Append harness-specific content that can also be replayed into model context. */
39
113
  appendCustomMessageEntry(customType: string, content: string | (TextContent | ImageContent)[], display: boolean, details?: unknown): Promise<string>;
114
+ /** Record or clear the display label for an existing session entry. */
40
115
  appendLabel(targetId: string, label: string | undefined): Promise<string>;
41
116
  appendSessionName(name: string): Promise<string>;
42
117
  }
@@ -1,4 +1,5 @@
1
1
  import { type LeafEntry, type SessionMetadata, type SessionStorage, type SessionTreeEntry, type SessionWriteOptions } from "../harness/types.js";
2
+ /** Return the effective branch leaf after applying a session tree entry. */
2
3
  export declare function leafIdAfterEntry(entry: SessionTreeEntry): string | null;
3
4
  export declare abstract class BaseSessionStorage<TMetadata extends SessionMetadata = SessionMetadata> implements SessionStorage<TMetadata> {
4
5
  private readonly metadata;
@@ -10,11 +11,18 @@ export declare abstract class BaseSessionStorage<TMetadata extends SessionMetada
10
11
  protected constructor(metadata: TMetadata, entries: SessionTreeEntry[], leafId?: string | null, opts?: {
11
12
  floorEntryId?: string | null;
12
13
  });
14
+ /** The bounded-window root this storage was woken with, or null for a full-tree load (F3). */
13
15
  getFloorId(): string | null;
14
16
  getMetadata(): Promise<TMetadata>;
15
17
  getLeafId(): Promise<string | null>;
16
18
  protected createLeafEntry(leafId: string | null): LeafEntry;
17
19
  createEntryId(): Promise<string>;
20
+ /**
21
+ * Optimistic-lock check (F2). Throws `SessionError("conflict")` when `opts.expectedLeafId` is
22
+ * provided and does not match the current in-memory leaf. Concrete `appendEntry`/`setLeafId`
23
+ * implementations call this before persisting; durable backends should instead perform the same
24
+ * check atomically against shared state (a conditional write) so concurrent instances can't fork.
25
+ */
18
26
  protected assertExpectedLeaf(opts?: SessionWriteOptions): void;
19
27
  protected recordEntry(entry: SessionTreeEntry): void;
20
28
  getEntry(id: string): Promise<SessionTreeEntry | undefined>;
@@ -1,7 +1,43 @@
1
+ /**
2
+ * `@sema-agent/core/fixtures` — GOLDEN SHAPE fixtures for downstream consumers (server/SDK/cli),
3
+ * the L2 layer of the [1549] anti-drift defense: downstream tests consume THESE shapes instead of
4
+ * hand-building requests/frames, so an upstream shape change breaks a test instead of shipping a
5
+ * silent mismatch (the [1546] "bare req = false-green pins" class).
6
+ *
7
+ * CONTRACT — shape truth, not value truth:
8
+ * - Every volatile value is NORMALIZED to an angle-bracket placeholder (`"<issuing-session-id>"`,
9
+ * `"<tool-call-id>"`, …). Downstream asserts KEY SETS and SHAPES (optionality, nesting, enum
10
+ * membership), never placeholder values.
11
+ * - Each fixture is PINNED against the live engine by test/fixtures-golden.test.ts: the pin runs
12
+ * the real code path (a real gate, a real delegated child), captures the real object, applies
13
+ * the same normalization, and requires deep equality with the fixture. A shape change upstream
14
+ * turns THAT pin red first — the fixture can never drift from the engine.
15
+ * - Additions here are additive API: removing/renaming a fixture key is a downstream-visible
16
+ * BREAKING change and belongs in the release notes' frame-shape section ([1552] L1.5).
17
+ */
1
18
  import type { AskRequest } from "../core/tool-policy.js";
19
+ /** The normalization placeholders used across all fixtures (downstream may match on the form). */
2
20
  export declare const FIXTURE_PLACEHOLDER_RE: RegExp;
21
+ /**
22
+ * AskRequest, HOST form — the shape a live `onAsk` approver receives when the HOST task's own
23
+ * gate raises a permission ask. Key facts downstream must not re-derive by guessing ([1546] MED-1):
24
+ * - `sourceTaskId` is PRESENT on host asks too (always the issuing task's session id) — it is
25
+ * NOT a subagent discriminator;
26
+ * - `fromSubagent` / `sourceAgentName` are ABSENT on host asks (design/153 §1: `fromSubagent`
27
+ * is THE discriminator);
28
+ * - `principal` is absent unless the deployment sets TaskSpec.principal.
29
+ */
3
30
  export declare const ASK_REQUEST_HOST: AskRequest;
31
+ /**
32
+ * AskRequest, DELEGATED-SUBAGENT form — the shape the approver receives when a delegated child's
33
+ * gate raises the ask (bubbled through the inherited chain or the child's own caller slot):
34
+ * - `fromSubagent: true` — the explicit, unforgeable discriminator (1.378);
35
+ * - `sourceAgentName` — display identity (UNTRUSTED-for-display; redact + bound before render);
36
+ * present only when the spawn named the child (an unnamed child omits it);
37
+ * - `sourceTaskId` — the CHILD's session id (≠ the host's).
38
+ */
4
39
  export declare const ASK_REQUEST_SUBAGENT: AskRequest;
40
+ /** Both AskRequest forms, keyed for iteration in downstream key-set diff gates. */
5
41
  export declare const ASK_REQUEST_FIXTURES: {
6
42
  readonly host: AskRequest;
7
43
  readonly subagent: AskRequest;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,10 @@
1
+ /**
2
+ * sema-core — a stateless, task-oriented AI agent core distilled from openclaw.
3
+ *
4
+ * Bring your own brain (an OpenAI-compatible model gateway), define tools / MCP servers
5
+ * per task, and run single-agent tasks against in-memory sessions with zero-config
6
+ * auto-compaction.
7
+ */
1
8
  export { Runner, runTask } from "./core/runner/runtask.js";
2
9
  export { resolveTaskLimits } from "./core/runner/prepare-task.js";
3
10
  export type { BudgetAxis } from "./core/runner/assemble-result.js";
@@ -33,7 +40,6 @@ export { cacheFamilyOf, promptTokensOf, uncachedInputTokensOf, type CacheFamily
33
40
  export { emitTrace, type ToolDisclosureManifest, type TraceEvent, type TracerHook } from "./core/trace.js";
34
41
  export { InMemoryStrategyStore, type StrategyStore, type StoredStrategy } from "./core/strategy-store.js";
35
42
  export { createSqlTool, validateReadOnlySql, type SqlToolOptions } from "./tools/sql.js";
36
- export { createGiteaIssueTool, type GiteaIssueToolOptions } from "./tools/gitea-issue.js";
37
43
  export { runWithTeacher, parseTeacherAdvice, TEACHER_PROMPT, type TeacherConfig, type TeacherAdvice, type EscalationRecord, type EscalationTrigger, type TeacherRunResult, } from "./agents/teacher.js";
38
44
  export { runWithVerification, resumeWithVerification, verifyCompleted, runDeveloperTask, VERIFICATION_PROMPT, STATIC_VERIFICATION_PROMPT, VerdictSchema, type Verdict, type VerifyConfig, type UnverifiedReason, type VerificationOutcome, type VerificationResult, type DeveloperTaskConfig, } from "./agents/verify.js";
39
45
  export { runRepairLoop, terminalForTier, repairBundleFromCheckpoint, isolationPermitsAutoAccept, type OracleTier, type RepairTerminal, type OracleResult, type RepairOracle, type RepairBundle, type RepairLoopConfig, type RepairResult, } from "./agents/repair-loop.js";
@@ -127,6 +133,15 @@ export { parseAutoModeResponse, createAutoModeDecider, type AutoModeVerdict, typ
127
133
  export { buildAutoModePrompt, renderAutoModeWindow, renderAutoModeAction, AUTO_MODE_DEFAULTS_SENTINEL, type AutoModeRules, type BuildAutoModePromptOptions, type AutoModeWindowOptions, } from "./core/auto-mode-prompt.js";
128
134
  export { AUTO_MODE_BASE_PROMPT, AUTO_MODE_PERMISSIONS_EXTERNAL } from "./core/auto-mode-prompt-assets.js";
129
135
  export { createPermissionRulePolicy, validatePermissionRules, parsePermissionRule, wildcardMatch, type PermissionRule, type ParsedPermissionRule, type PermissionRuleIssue, type PermissionRuleCaps, type PermissionRulePolicyOptions, } from "./core/permission-rules.js";
136
+ /**
137
+ * design/179 — persisted ALLOW rules: the standing form of approvals a person already gave.
138
+ *
139
+ * Note what is NOT here. `PermissionRuleWriter` is core-private and never exported, so a deployment has
140
+ * no API path that puts a rule in the store; every rule that enters through the engine comes out of the
141
+ * consent protocol below (a durable approval record, an authenticated confirmation, a principal-bound
142
+ * redemption). Removal is exported without that ceremony, because narrowing on a user's behalf is allowed
143
+ * and widening is not.
144
+ */
130
145
  export { parseAllowRuleText, formatAllowRuleText, ruleAdmitsCommand, findAdmittingRule, suggestRulesForCommand, scopeCoversCwd, pathWithinRoot, isRuleLive, BARE_INTERPRETER_NAMES, MAX_RULE_TEXT_CHARS, type PersistedAllowRule, type RuleTombstone, type RuleScope, type RuleDot, type RuleAdd, type RuleAddOrigin, type RuleSuggestion, type RuleReject, type RuleRejectCode, type ParsedAllowRule, type PersistedRuleTool, type PersistedRuleMatch, } from "./core/permission-rule-model.js";
131
146
  export { removePersistedRule, applyTombstones, sameScope, InMemoryPermissionRuleStore, EMPTY_RULE_STORE, type PermissionRuleStore, type PermissionRuleStoreProvider, type StoredAllowRules, type RemoveResult, type PutResult, } from "./core/permission-rule-store.js";
132
147
  export { prepareCardApproval, confirmRuleApproval, type ConfirmResult, type ConfirmRefusalReason, redeemRuleTicket, redeemRuleBatch, prepareCcImport, prepareStarterBatch, mintRuleTicket, STARTER_RULES, InMemoryRuleApprovalRecordStore, type RuleTicket, type RuleCandidate, type RuleApprovalKind, type RuleApprovalRecord, type RuleApprovalRecordStore, type RuleConsentDeps, type RedeemResult, type CcImportLayer, type ImportedSettingsLayer, type ImportPreview, type ImportResult, } from "./core/permission-rule-consent.js";
package/dist/index.js CHANGED
@@ -29,7 +29,6 @@ export { cacheFamilyOf, promptTokensOf, uncachedInputTokensOf } from "./core/run
29
29
  export { emitTrace } from "./core/trace.js";
30
30
  export { InMemoryStrategyStore } from "./core/strategy-store.js";
31
31
  export { createSqlTool, validateReadOnlySql } from "./tools/sql.js";
32
- export { createGiteaIssueTool } from "./tools/gitea-issue.js";
33
32
  export { runWithTeacher, parseTeacherAdvice, TEACHER_PROMPT, } from "./agents/teacher.js";
34
33
  export { runWithVerification, resumeWithVerification, verifyCompleted, runDeveloperTask, VERIFICATION_PROMPT, STATIC_VERIFICATION_PROMPT, VerdictSchema, } from "./agents/verify.js";
35
34
  export { runRepairLoop, terminalForTier, repairBundleFromCheckpoint, isolationPermitsAutoAccept, } from "./agents/repair-loop.js";
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Pure-type re-exports split out of harness.ts (S1, design/157) — see harness.ts for the full
3
+ * design/33 + design/118 facade narrative. This file exists to break an engine-import SCC: consumers
4
+ * that only need harness types (not the NodeExecutionEnv value export) import from here instead, so
5
+ * their compile-time dependency graph never has to reach the value side of the facade.
6
+ */
1
7
  export type { CompactionPreparation, SummarizationClampDryRun } from "../engine/compaction/compaction.js";
2
8
  export type { InvokedSkillRetention } from "../engine/compaction/utils.js";
3
9
  export type { AgentCoreRuntimeDeps } from "../engine/loop/runtime-deps.js";
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Internal boundary to the engine's harness layer (design/33; de-vendored by design/118). Everything
3
+ * in `src/` (outside `src/internal/`) imports these symbols from HERE, never via a deep
4
+ * `../engine/...` path — one auditable coupling point (CI-guarded by test/vendor-insulation.test.ts).
5
+ * The vendored tree this facade used to front is fully retired (design/118 ⓪-⑤); the facade stays so
6
+ * consumers never notice which module a symbol lives in.
7
+ *
8
+ * Pure-type re-exports live in ./harness-types.js (S1, design/157) — split out to break an
9
+ * engine-import SCC for type-only consumers. Re-exported here too so existing `harness.js` imports
10
+ * keep working unchanged.
11
+ */
1
12
  export * from "./harness-types.js";
2
13
  export { AgentHarness } from "../engine/harness/agent-harness.js";
3
14
  export { CompactionError, ExecutionError, FileError, ok, err } from "../engine/harness/types.js";
@@ -1,2 +1,8 @@
1
+ /**
2
+ * Internal boundary to the llm layer (design/33). Everything in `src/` (outside `src/internal/`)
3
+ * imports these symbols from HERE, never via a deep path — one auditable coupling point (CI-guarded).
4
+ * design/118 ①②: the layer is now first-party (`src/engine/llm/`, naturalized out of the vendored
5
+ * llm-core); the facade stays so consumers never notice which side a symbol lives on.
6
+ */
1
7
  export { createAssistantMessageEventStream, snapshotActorAssertion, stripEngineMetadata } from "../engine/llm/index.js";
2
8
  export type { ActorAssertion, AnthropicMessagesCompat, OpenAICompletionsCompat, OpenAIResponsesCompat, AssistantMessage, AssistantMessageDiagnostic, AssistantMessageEvent, CompleteSimpleFn, Context, DocumentContent, ImageContent, Message, Model, ResilienceOptions, SimpleStreamOptions, StallTimeouts, StopReason, StreamFn, TextContent, ThinkingContent, Tool, ToolCall, ToolResultMessage, Usage, UserMessage, } from "../engine/llm/index.js";