@sema-agent/core 7.48.0 → 7.49.0

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 (418) hide show
  1. package/CHANGELOG.md +418 -0
  2. package/README.md +2 -2
  3. package/dist/agents/cascade.d.ts +2 -5
  4. package/dist/agents/child-failure.d.ts +20 -0
  5. package/dist/agents/child-failure.js +28 -0
  6. package/dist/agents/cross-session-ref.d.ts +11 -3
  7. package/dist/agents/cross-session-ref.js +6 -0
  8. package/dist/agents/cumulative-stats.d.ts +12 -15
  9. package/dist/agents/cumulative-stats.js +1 -1
  10. package/dist/agents/extra-tool-names.js +1 -1
  11. package/dist/agents/inherited-tool-pool.d.ts +17 -13
  12. package/dist/agents/inherited-tool-pool.js +4 -3
  13. package/dist/agents/peer-session-drain.d.ts +3 -2
  14. package/dist/agents/peer-session-drain.js +5 -4
  15. package/dist/agents/send-message-tool.js +2 -9
  16. package/dist/agents/subagent.d.ts +10 -29
  17. package/dist/agents/subagent.js +65 -53
  18. package/dist/agents/suspend-guard.d.ts +1 -1
  19. package/dist/agents/tool-filter.d.ts +76 -65
  20. package/dist/agents/tool-filter.js +122 -92
  21. package/dist/agents/verify.d.ts +4 -7
  22. package/dist/agents/verify.js +6 -7
  23. package/dist/bench/metrics.d.ts +1 -2
  24. package/dist/brain/anthropic.js +133 -79
  25. package/dist/brain/errors.d.ts +53 -6
  26. package/dist/brain/errors.js +22 -2
  27. package/dist/brain/input-too-long.d.ts +40 -19
  28. package/dist/brain/input-too-long.js +3 -16
  29. package/dist/brain/open-responses.js +19 -10
  30. package/dist/brain/openai.js +123 -32
  31. package/dist/brain/provider-dialect.d.ts +214 -0
  32. package/dist/brain/provider-dialect.js +186 -0
  33. package/dist/brain/request-params.d.ts +27 -8
  34. package/dist/brain/request-params.js +7 -12
  35. package/dist/brain/request-route.d.ts +84 -0
  36. package/dist/brain/request-route.js +41 -0
  37. package/dist/brain/retry.d.ts +8 -0
  38. package/dist/brain/retry.js +10 -4
  39. package/dist/brain/route-adjudicator.d.ts +7 -0
  40. package/dist/brain/route-adjudicator.js +5 -1
  41. package/dist/brain/status-sink.d.ts +20 -0
  42. package/dist/brain/status-sink.js +11 -0
  43. package/dist/brain/stream-engine.d.ts +52 -1
  44. package/dist/brain/stream-engine.js +81 -24
  45. package/dist/brain/stream-shared.d.ts +57 -11
  46. package/dist/brain/stream-shared.js +28 -2
  47. package/dist/core/a2a.d.ts +1 -0
  48. package/dist/core/agent-config-dir.js +3 -2
  49. package/dist/core/allow-entry.d.ts +21 -12
  50. package/dist/core/allow-entry.js +38 -31
  51. package/dist/core/arg-summary.d.ts +17 -24
  52. package/dist/core/arg-summary.js +169 -68
  53. package/dist/core/ask-origin.d.ts +42 -24
  54. package/dist/core/ask-origin.js +18 -13
  55. package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
  56. package/dist/core/auto-mode-prompt-assets.js +1 -1
  57. package/dist/core/auto-mode-prompt.d.ts +11 -1
  58. package/dist/core/auto-mode-prompt.js +13 -10
  59. package/dist/core/auto-mode-rebuild.d.ts +7 -0
  60. package/dist/core/auto-mode-rebuild.js +4 -1
  61. package/dist/core/canonical-json.d.ts +3 -0
  62. package/dist/core/canonical-json.js +2 -1
  63. package/dist/core/checkpoint-requirements.d.ts +892 -0
  64. package/dist/core/checkpoint-requirements.js +333 -0
  65. package/dist/core/checkpoint-store.d.ts +94 -65
  66. package/dist/core/checkpoint-store.js +14 -26
  67. package/dist/core/child-clamp-seats.d.ts +228 -69
  68. package/dist/core/child-clamp-seats.js +211 -17
  69. package/dist/core/classifier-unavailable-arm.d.ts +5 -1
  70. package/dist/core/classifier-unavailable-arm.js +3 -3
  71. package/dist/core/compliance.d.ts +3 -0
  72. package/dist/core/compliance.js +9 -4
  73. package/dist/core/credential-vocabulary.d.ts +140 -0
  74. package/dist/core/credential-vocabulary.js +131 -0
  75. package/dist/core/decision-receipt.js +1 -1
  76. package/dist/core/effective-path-target.d.ts +73 -16
  77. package/dist/core/effective-path-target.js +63 -33
  78. package/dist/core/engine-notice.d.ts +32 -7
  79. package/dist/core/file-history-store.js +2 -2
  80. package/dist/core/fs-write-gate-policy.d.ts +4 -0
  81. package/dist/core/fs-write-gate-policy.js +22 -5
  82. package/dist/core/gate-bounded-await.d.ts +28 -13
  83. package/dist/core/gate-bounded-await.js +41 -4
  84. package/dist/core/gate-fold.d.ts +1 -1
  85. package/dist/core/gate-fold.js +24 -25
  86. package/dist/core/gate-lanes.js +16 -15
  87. package/dist/core/gate-outcome.d.ts +20 -5
  88. package/dist/core/gate-outcome.js +5 -0
  89. package/dist/core/governance-codes.d.ts +11 -4
  90. package/dist/core/governance-codes.js +14 -3
  91. package/dist/core/hooks.d.ts +4 -0
  92. package/dist/core/locked-config.d.ts +8 -0
  93. package/dist/core/locked-config.js +14 -2
  94. package/dist/core/lsp.js +3 -5
  95. package/dist/core/mailbox-store.d.ts +3 -4
  96. package/dist/core/mcp-connection-pool.d.ts +75 -0
  97. package/dist/core/mcp-connection-pool.js +128 -0
  98. package/dist/core/mcp-failure.d.ts +2 -1
  99. package/dist/core/mcp-failure.js +13 -2
  100. package/dist/core/mcp.d.ts +4 -0
  101. package/dist/core/mcp.js +70 -43
  102. package/dist/core/memory-engine/content-origin.js +2 -14
  103. package/dist/core/memory-engine/engine.d.ts +32 -22
  104. package/dist/core/memory-engine/engine.js +103 -55
  105. package/dist/core/memory-engine/file-backend.d.ts +13 -30
  106. package/dist/core/memory-engine/file-backend.js +37 -252
  107. package/dist/core/memory-engine/index.d.ts +1 -1
  108. package/dist/core/memory-engine/index.js +1 -1
  109. package/dist/core/memory-engine/layout.d.ts +139 -9
  110. package/dist/core/memory-engine/layout.js +350 -7
  111. package/dist/core/memory-engine/scope-contract.d.ts +10 -0
  112. package/dist/core/memory-engine/scope-contract.js +8 -0
  113. package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
  114. package/dist/core/memory-engine/session-incarnation.js +5 -2
  115. package/dist/core/memory-engine/types.d.ts +10 -1
  116. package/dist/core/memory.js +5 -17
  117. package/dist/core/model-seat.d.ts +4 -4
  118. package/dist/core/model-seat.js +1 -1
  119. package/dist/core/mounted-mcp.d.ts +57 -0
  120. package/dist/core/mounted-mcp.js +19 -0
  121. package/dist/core/namespaced-rule-name.d.ts +29 -0
  122. package/dist/core/namespaced-rule-name.js +52 -0
  123. package/dist/core/park-selfcheck.d.ts +1 -1
  124. package/dist/core/park-selfcheck.js +16 -6
  125. package/dist/core/path-guard-rows.d.ts +99 -0
  126. package/dist/core/path-guard-rows.js +45 -0
  127. package/dist/core/path-identity.d.ts +22 -16
  128. package/dist/core/path-identity.js +10 -10
  129. package/dist/core/path-rule-binding.d.ts +2 -1
  130. package/dist/core/path-rule-binding.js +3 -1
  131. package/dist/core/pause-registry.d.ts +16 -2
  132. package/dist/core/pause-registry.js +6 -0
  133. package/dist/core/permission-rule-consent.js +0 -7
  134. package/dist/core/permission-rule-model.d.ts +68 -24
  135. package/dist/core/permission-rule-model.js +105 -24
  136. package/dist/core/permission-rule-store.js +2 -2
  137. package/dist/core/permission-rules.d.ts +3 -30
  138. package/dist/core/permission-rules.js +4 -54
  139. package/dist/core/read-root-candidate.d.ts +1 -3
  140. package/dist/core/read-root-candidate.js +4 -15
  141. package/dist/core/real-approval.d.ts +4 -3
  142. package/dist/core/retired-keys.d.ts +13 -0
  143. package/dist/core/retired-keys.js +14 -0
  144. package/dist/core/roles.d.ts +2 -3
  145. package/dist/core/roles.js +15 -6
  146. package/dist/core/runner/assemble-result.d.ts +0 -7
  147. package/dist/core/runner/assemble-result.js +19 -31
  148. package/dist/core/runner/caller-roster.d.ts +78 -0
  149. package/dist/core/runner/caller-roster.js +219 -0
  150. package/dist/core/runner/checkpoint-scope.d.ts +16 -16
  151. package/dist/core/runner/checkpoint-scope.js +2 -2
  152. package/dist/core/runner/child-tree.js +2 -2
  153. package/dist/core/runner/contracts.d.ts +68 -35
  154. package/dist/core/runner/decide-continuation.d.ts +51 -3
  155. package/dist/core/runner/decide-continuation.js +76 -21
  156. package/dist/core/runner/denial-limit-arms.d.ts +17 -5
  157. package/dist/core/runner/denial-limit-arms.js +11 -9
  158. package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
  159. package/dist/core/runner/extra-body-dropped-seat.js +22 -0
  160. package/dist/core/runner/finish-reason-seat.d.ts +9 -0
  161. package/dist/core/runner/finish-reason-seat.js +40 -0
  162. package/dist/core/runner/gate-exit.d.ts +44 -32
  163. package/dist/core/runner/gate-exit.js +112 -25
  164. package/dist/core/runner/inherited-ask-grants.js +6 -4
  165. package/dist/core/runner/mcp-redial.d.ts +3 -3
  166. package/dist/core/runner/mcp-redial.js +3 -4
  167. package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
  168. package/dist/core/runner/permission-rule-lanes.js +5 -4
  169. package/dist/core/runner/prepare-artifact.d.ts +4 -0
  170. package/dist/core/runner/prepare-artifact.js +2 -1
  171. package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
  172. package/dist/core/runner/prepare-ask-lane.js +12 -6
  173. package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
  174. package/dist/core/runner/prepare-boundary-parks.js +4 -7
  175. package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
  176. package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
  177. package/dist/core/runner/prepare-config-doors.d.ts +9 -9
  178. package/dist/core/runner/prepare-config-doors.js +10 -5
  179. package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
  180. package/dist/core/runner/prepare-defer-classify.js +5 -3
  181. package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
  182. package/dist/core/runner/prepare-delegation-surface.js +3 -3
  183. package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
  184. package/dist/core/runner/prepare-gate-stations.js +9 -7
  185. package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
  186. package/dist/core/runner/prepare-hands-readface.js +7 -7
  187. package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
  188. package/dist/core/runner/prepare-inherited-gate.js +14 -15
  189. package/dist/core/runner/prepare-listings.d.ts +7 -24
  190. package/dist/core/runner/prepare-listings.js +4 -5
  191. package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
  192. package/dist/core/runner/prepare-memory-engine-session.js +4 -3
  193. package/dist/core/runner/prepare-memory.d.ts +6 -0
  194. package/dist/core/runner/prepare-memory.js +13 -13
  195. package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
  196. package/dist/core/runner/prepare-offload-wrappers.js +3 -3
  197. package/dist/core/runner/prepare-park-ask.d.ts +7 -8
  198. package/dist/core/runner/prepare-park-ask.js +17 -10
  199. package/dist/core/runner/prepare-policy-chain.js +24 -44
  200. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  201. package/dist/core/runner/prepare-project-context.js +3 -4
  202. package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
  203. package/dist/core/runner/prepare-protocol-tools.js +3 -4
  204. package/dist/core/runner/prepare-run-refs.d.ts +3 -0
  205. package/dist/core/runner/prepare-run-refs.js +2 -1
  206. package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
  207. package/dist/core/runner/prepare-safety-scan.js +1 -2
  208. package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
  209. package/dist/core/runner/prepare-suspend-saga.js +28 -12
  210. package/dist/core/runner/prepare-task.d.ts +1 -1
  211. package/dist/core/runner/prepare-task.js +67 -56
  212. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
  213. package/dist/core/runner/prepare-wiring-manifest.js +5 -8
  214. package/dist/core/runner/resume-apply.js +7 -14
  215. package/dist/core/runner/resume-checkpoint-screen.js +11 -4
  216. package/dist/core/runner/resume-internals-and-config.js +2 -2
  217. package/dist/core/runner/resume-policy-outcome.js +5 -32
  218. package/dist/core/runner/resume-review-outcome.js +4 -1
  219. package/dist/core/runner/retired-runner-deps.d.ts +6 -0
  220. package/dist/core/runner/retired-runner-deps.js +10 -1
  221. package/dist/core/runner/run-brain-sinks.d.ts +4 -0
  222. package/dist/core/runner/run-brain-sinks.js +5 -2
  223. package/dist/core/runner/run-harness-handlers.js +27 -34
  224. package/dist/core/runner/run-leg.d.ts +0 -2
  225. package/dist/core/runner/run-leg.js +32 -33
  226. package/dist/core/runner/run-terminal-adoption.js +4 -3
  227. package/dist/core/runner/runtask.js +8 -8
  228. package/dist/core/runner/session-rule-policy.js +5 -5
  229. package/dist/core/runner/stream-settle-backstop.js +7 -4
  230. package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
  231. package/dist/core/runner/sub-agent-deny-lists.js +111 -80
  232. package/dist/core/runner/terminal-account.d.ts +48 -0
  233. package/dist/core/runner/terminal-account.js +186 -0
  234. package/dist/core/runner/tool-end-body.d.ts +54 -17
  235. package/dist/core/runner/tool-end-body.js +27 -2
  236. package/dist/core/runner/tool-face-overlay.d.ts +3 -1
  237. package/dist/core/runner/tool-face-overlay.js +6 -4
  238. package/dist/core/runner/tool-occurrence.d.ts +106 -0
  239. package/dist/core/runner/tool-occurrence.js +123 -0
  240. package/dist/core/runner/tool-progress-lane.d.ts +16 -8
  241. package/dist/core/runner/tool-progress-lane.js +25 -34
  242. package/dist/core/runner/turn-attachments.d.ts +1 -1
  243. package/dist/core/runner/write-protection-station.d.ts +21 -9
  244. package/dist/core/runner/write-protection-station.js +20 -17
  245. package/dist/core/runner-deps.d.ts +12 -22
  246. package/dist/core/secret-env.d.ts +16 -5
  247. package/dist/core/secret-env.js +23 -63
  248. package/dist/core/sensitive-path-policy.d.ts +19 -18
  249. package/dist/core/sensitive-path-policy.js +73 -49
  250. package/dist/core/session-reconcile.d.ts +3 -0
  251. package/dist/core/session-reconcile.js +5 -4
  252. package/dist/core/session-store.d.ts +5 -0
  253. package/dist/core/session-store.js +12 -0
  254. package/dist/core/session.d.ts +13 -0
  255. package/dist/core/shared-memory/normalize.d.ts +17 -4
  256. package/dist/core/shared-memory/normalize.js +7 -7
  257. package/dist/core/shell-lexer.js +5 -4
  258. package/dist/core/skill-grant.js +1 -1
  259. package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
  260. package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
  261. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
  262. package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
  263. package/dist/core/stub-env.d.ts +2 -0
  264. package/dist/core/stub-env.js +1 -0
  265. package/dist/core/synthetic-read-verdict.js +2 -2
  266. package/dist/core/task-event.d.ts +59 -5
  267. package/dist/core/task-result.d.ts +1 -1
  268. package/dist/core/task-spec.d.ts +42 -9
  269. package/dist/core/terminal-cause.d.ts +94 -11
  270. package/dist/core/tighten-task-spec.d.ts +5 -4
  271. package/dist/core/tighten-task-spec.js +20 -25
  272. package/dist/core/tool-catalog-entries.d.ts +5 -7
  273. package/dist/core/tool-catalog-entries.js +14 -15
  274. package/dist/core/tool-face.d.ts +47 -0
  275. package/dist/core/tool-face.js +5 -0
  276. package/dist/core/tool-model-gate.d.ts +5 -5
  277. package/dist/core/tool-name-aliases.d.ts +26 -2
  278. package/dist/core/tool-name-aliases.js +13 -0
  279. package/dist/core/tool-name-list.d.ts +30 -0
  280. package/dist/core/tool-name-list.js +55 -0
  281. package/dist/core/tool-name-readings.d.ts +1 -9
  282. package/dist/core/tool-name-readings.js +1 -3
  283. package/dist/core/tool-policy.d.ts +195 -85
  284. package/dist/core/tool-policy.js +165 -380
  285. package/dist/core/tool-registry.d.ts +44 -1
  286. package/dist/core/tool-registry.js +26 -0
  287. package/dist/core/tool-roster.d.ts +19 -1
  288. package/dist/core/tool-roster.js +21 -2
  289. package/dist/core/tool-spec-members.d.ts +45 -0
  290. package/dist/core/tool-spec-members.js +169 -0
  291. package/dist/core/tool-spec.d.ts +46 -8
  292. package/dist/core/tools.d.ts +6 -2
  293. package/dist/core/tools.js +8 -4
  294. package/dist/core/untrusted-egress.js +29 -26
  295. package/dist/core/untrusted-text.d.ts +13 -10
  296. package/dist/core/untrusted-text.js +6 -44
  297. package/dist/core/workflow-journal-store.d.ts +4 -1
  298. package/dist/core/write-protect.d.ts +65 -29
  299. package/dist/core/write-protect.js +235 -177
  300. package/dist/engine/compaction/compaction.d.ts +2 -2
  301. package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
  302. package/dist/engine/execution-env/node-execution-env.js +16 -38
  303. package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
  304. package/dist/engine/execution-env/symlink-chain.js +32 -0
  305. package/dist/engine/harness/types.d.ts +7 -0
  306. package/dist/engine/llm/tool-turns.d.ts +3 -0
  307. package/dist/engine/llm/tool-turns.js +1 -0
  308. package/dist/engine/llm/types.d.ts +59 -23
  309. package/dist/engine/loop/agent-loop.js +16 -2
  310. package/dist/engine/session/memory-repo.js +11 -3
  311. package/dist/engine/session/repo-utils.d.ts +8 -0
  312. package/dist/engine/session/repo-utils.js +13 -0
  313. package/dist/index.d.ts +20 -23
  314. package/dist/index.js +17 -20
  315. package/dist/internal/harness.d.ts +1 -1
  316. package/dist/internal/harness.js +1 -1
  317. package/dist/internal/llm.d.ts +2 -2
  318. package/dist/internal/llm.js +1 -1
  319. package/dist/orchestration/governance-baseline-validity.js +1 -1
  320. package/dist/orchestration/run-spec.js +3 -3
  321. package/dist/orchestration/run-workflow-tool.d.ts +16 -35
  322. package/dist/orchestration/run-workflow-tool.js +38 -78
  323. package/dist/orchestration/workflow-governance.d.ts +21 -25
  324. package/dist/orchestration/workflow-governance.js +38 -78
  325. package/dist/orchestration/workflow-primitives.d.ts +7 -22
  326. package/dist/orchestration/workflow-primitives.js +5 -12
  327. package/dist/orchestration/workflow-types.d.ts +1 -1
  328. package/dist/orchestration/workflow.d.ts +61 -11
  329. package/dist/orchestration/workflow.js +189 -117
  330. package/dist/scenarios/full-body.d.ts +1 -1
  331. package/dist/shell/lex.d.ts +0 -21
  332. package/dist/shell/lex.js +250 -68
  333. package/dist/shell/shell-words.d.ts +35 -0
  334. package/dist/shell/shell-words.js +65 -0
  335. package/dist/stores/file/checkpoint-store.d.ts +5 -5
  336. package/dist/stores/file/checkpoint-store.js +5 -2
  337. package/dist/stores/file/index.d.ts +0 -8
  338. package/dist/stores/file/index.js +0 -12
  339. package/dist/stores/file/session-store.d.ts +3 -0
  340. package/dist/stores/file/session-store.js +44 -19
  341. package/dist/tools/artifact/artifact-tool.js +2 -0
  342. package/dist/tools/fs/bash-program-position.d.ts +10 -3
  343. package/dist/tools/fs/bash-program-position.js +21 -9
  344. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  345. package/dist/tools/fs/bash-readonly-classifier.js +8 -7
  346. package/dist/tools/fs/containment-face.d.ts +4 -0
  347. package/dist/tools/fs/containment-face.js +3 -0
  348. package/dist/tools/fs/fs-shared.d.ts +10 -0
  349. package/dist/tools/fs/fs-shared.js +18 -0
  350. package/dist/tools/fs/fs-write.js +4 -2
  351. package/dist/tools/fs/index.d.ts +1 -1
  352. package/dist/tools/fs/program-read-model.d.ts +39 -18
  353. package/dist/tools/fs/program-read-model.js +29 -19
  354. package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
  355. package/dist/tools/fs/program-read-model.rows.js +5 -5
  356. package/dist/tools/fs/read-deny-home.d.ts +33 -47
  357. package/dist/tools/fs/read-deny-home.js +35 -49
  358. package/dist/tools/fs/read-deny.d.ts +23 -22
  359. package/dist/tools/fs/read-deny.js +114 -89
  360. package/dist/tools/fs/removal-targets.d.ts +56 -23
  361. package/dist/tools/fs/removal-targets.js +65 -87
  362. package/dist/tools/fs/safety.d.ts +29 -22
  363. package/dist/tools/fs/safety.js +17 -11
  364. package/dist/tools/fs/search.js +10 -8
  365. package/dist/tools/fs/shell-read-argv.js +1 -1
  366. package/dist/tools/fs/shell-read-bindings.d.ts +169 -37
  367. package/dist/tools/fs/shell-read-bindings.js +324 -86
  368. package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
  369. package/dist/tools/fs/shell-read-builtins.js +43 -0
  370. package/dist/tools/fs/shell-read-check.d.ts +15 -1
  371. package/dist/tools/fs/shell-read-check.js +51 -42
  372. package/dist/tools/fs/shell-read-establish.js +6 -6
  373. package/dist/tools/fs/shell-read-functions.d.ts +22 -0
  374. package/dist/tools/fs/shell-read-functions.js +29 -0
  375. package/dist/tools/fs/shell-read-judge.d.ts +48 -18
  376. package/dist/tools/fs/shell-read-judge.js +33 -4
  377. package/dist/tools/fs/shell-read-plan.d.ts +12 -6
  378. package/dist/tools/fs/shell-read-plan.js +118 -113
  379. package/dist/tools/fs/shell-read-start.d.ts +29 -6
  380. package/dist/tools/fs/shell-read-start.js +16 -9
  381. package/dist/tools/fs/shell-read-word.js +4 -0
  382. package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
  383. package/dist/tools/fs/shell-read-workdir.js +281 -0
  384. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
  385. package/dist/tools/fs/shell-read-write-targets.js +14 -5
  386. package/dist/tools/fs/shell-reentry-text.d.ts +4 -6
  387. package/dist/tools/fs/shell-reentry-text.js +3 -11
  388. package/dist/tools/task-list.d.ts +1 -2
  389. package/dist/tools/web.js +1 -1
  390. package/package.json +4 -1
  391. package/test/export-surface.snapshot.json +107 -143
  392. package/wire-changes/core@7.49.0.json +4765 -0
  393. package/dist/agents/teacher.d.ts +0 -159
  394. package/dist/agents/teacher.js +0 -577
  395. package/dist/agents/team.d.ts +0 -226
  396. package/dist/agents/team.js +0 -257
  397. package/dist/core/strategy-store.d.ts +0 -238
  398. package/dist/core/strategy-store.js +0 -253
  399. package/dist/orchestration/builtin-workflows.d.ts +0 -133
  400. package/dist/orchestration/builtin-workflows.js +0 -159
  401. package/dist/scenarios/env.d.ts +0 -40
  402. package/dist/scenarios/env.js +0 -39
  403. package/dist/scenarios/scenario-registry.d.ts +0 -110
  404. package/dist/scenarios/scenario-registry.js +0 -140
  405. package/dist/scenarios/teacher-quickstart.d.ts +0 -40
  406. package/dist/scenarios/teacher-quickstart.js +0 -12
  407. package/dist/stores/cc/lockfile.d.ts +0 -10
  408. package/dist/stores/cc/lockfile.js +0 -98
  409. package/dist/stores/cc/mailbox-store.d.ts +0 -20
  410. package/dist/stores/cc/mailbox-store.js +0 -255
  411. package/dist/stores/cc/roster-adapter.d.ts +0 -12
  412. package/dist/stores/cc/roster-adapter.js +0 -117
  413. package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
  414. package/dist/stores/cc/sidecar-transcript.js +0 -264
  415. package/dist/stores/cc/task-list-store.d.ts +0 -2
  416. package/dist/stores/cc/task-list-store.js +0 -125
  417. package/dist/stores/file/strategy-store.d.ts +0 -97
  418. package/dist/stores/file/strategy-store.js +0 -341
@@ -1,117 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync } from "node:fs";
2
- import { basename, join, resolve } from "node:path";
3
- import { entryAccessible } from "../../agents/roster-store.js";
4
- import { normalizeAgentName } from "../../core/task-registry.js";
5
- import { atomicWriteFile } from "../file/fs-atomic.js";
6
- import { withCcLock } from "./lockfile.js";
7
- export function createCcTeamsRosterAdapter(opts) {
8
- const scope = opts.scope ?? "default";
9
- if (scope !== "default") {
10
- throw new Error(`CcTeamsRosterAdapter: CC team files carry no tenant axis — this adapter is licensed for single-tenant scope:"default" deployments only (D-1); got scope ${JSON.stringify(scope)}`);
11
- }
12
- const dir = resolve(opts.teamDir);
13
- const configPath = join(dir, "config.json");
14
- const now = opts.now ?? Date.now;
15
- const load = () => {
16
- try {
17
- return JSON.parse(readFileSync(configPath, "utf8"));
18
- }
19
- catch (err) {
20
- if (err.code === "ENOENT")
21
- return undefined;
22
- throw err;
23
- }
24
- };
25
- const save = (config) => {
26
- atomicWriteFile(dir, configPath, JSON.stringify(config, null, 2));
27
- };
28
- const toEntry = (m) => ({
29
- name: m.name,
30
- agentId: m.agentId,
31
- ...(typeof m.semaSessionId === "string" ? { sessionId: m.semaSessionId } : {}),
32
- ...(typeof m.semaToolUseId === "string" ? { toolUseId: m.semaToolUseId } : {}),
33
- ...(typeof m.semaRootSessionId === "string" ? { rootSessionId: m.semaRootSessionId } : {}),
34
- ...(typeof m.semaModel === "string" ? { model: m.semaModel } : {}),
35
- ...(m.semaSessionScoped === true ? { sessionScoped: true } : {}),
36
- owner: typeof m.semaOwner === "string" ? m.semaOwner : opts.owner,
37
- scope,
38
- createdAt: typeof m.joinedAt === "number" ? m.joinedAt : 0,
39
- });
40
- const absent = () => !existsSync(configPath);
41
- return {
42
- record: (entry) => {
43
- if (entry.scope !== scope) {
44
- throw new Error(`CcTeamsRosterAdapter: cannot record entry with scope ${JSON.stringify(entry.scope)} — this adapter persists scope:"${scope}" bindings only (D-1 single-tenant)`);
45
- }
46
- mkdirSync(dir, { recursive: true });
47
- return withCcLock(configPath, () => {
48
- const config = load() ?? {
49
- name: basename(dir),
50
- createdAt: now(),
51
- members: [],
52
- };
53
- const members = Array.isArray(config.members) ? config.members : [];
54
- const prior = members.find((m) => m.agentId === entry.agentId);
55
- const member = {
56
- ...(prior ?? {}),
57
- agentId: entry.agentId,
58
- name: entry.name,
59
- ...(entry.model !== undefined ? { semaModel: entry.model } : {}),
60
- ...(entry.sessionId !== undefined ? { semaSessionId: entry.sessionId } : {}),
61
- ...(entry.toolUseId !== undefined ? { semaToolUseId: entry.toolUseId } : {}),
62
- ...(entry.rootSessionId !== undefined ? { semaRootSessionId: entry.rootSessionId } : {}),
63
- ...(entry.sessionScoped === true ? { semaSessionScoped: true } : {}),
64
- semaOwner: entry.owner,
65
- joinedAt: entry.createdAt,
66
- };
67
- config.members = [...members.filter((m) => m.agentId !== entry.agentId), member];
68
- save(config);
69
- });
70
- },
71
- resolve: (name, access) => {
72
- if (absent())
73
- return undefined;
74
- return withCcLock(configPath, () => {
75
- const config = load();
76
- if (config === undefined || !Array.isArray(config.members))
77
- return undefined;
78
- const key = normalizeAgentName(name);
79
- if (key === "")
80
- return undefined;
81
- const pool = config.members
82
- .filter((m) => typeof m.agentId === "string" && typeof m.name === "string")
83
- .map(toEntry)
84
- .filter((e) => normalizeAgentName(e.name) === key && entryAccessible(e, access));
85
- let best;
86
- for (const e of pool)
87
- if (best === undefined || e.createdAt >= best.createdAt)
88
- best = e;
89
- return best;
90
- });
91
- },
92
- list: () => {
93
- if (absent())
94
- return [];
95
- return withCcLock(configPath, () => {
96
- const config = load();
97
- if (config === undefined || !Array.isArray(config.members))
98
- return [];
99
- return config.members.filter((m) => typeof m.agentId === "string" && typeof m.name === "string").map(toEntry);
100
- });
101
- },
102
- releaseAgent: (agentId) => {
103
- if (absent())
104
- return;
105
- return withCcLock(configPath, () => {
106
- const config = load();
107
- if (config === undefined || !Array.isArray(config.members))
108
- return;
109
- const next = config.members.filter((m) => m.agentId !== agentId);
110
- if (next.length === config.members.length)
111
- return;
112
- config.members = next;
113
- save(config);
114
- });
115
- },
116
- };
117
- }
@@ -1,97 +0,0 @@
1
- import type { Message } from "../../internal/llm.js";
2
- /**
3
- * design/152 S4b D-2 — READ-ONLY adapter over the Claude Code subagent transcript sidecars
4
- * (`~/.claude/projects/<proj>/<sid>/subagents/agent-<id>.jsonl` + companion
5
- * `agent-<id>.meta.json`), so a sema engine taking over a CC-created team (D-3: sequential
6
- * handover) can enumerate the teammates' transcript sidecars and project them into sema message
7
- * shapes for resume context.
8
- *
9
- * D-2 ruling (design/152 §3): the sidecar is CC→sema ONE-WAY. sema's transcript truth source
10
- * is the SessionStore — this module never writes, and nothing here mints a second truth source
11
- * (the dual-truth-source pathology design/151 just eliminated stays eliminated). Dual-write is a
12
- * separate ruling gated on a real user need.
13
- *
14
- * Disk shape (cc-teams-diskform README):
15
- * - flat sidecars: `subagents/agent-<id>.jsonl`
16
- * - nested children: `subagents/<parentSeg>/agent-<id>.jsonl` (parent-segment subdirectories)
17
- * - workflow runs: `subagents/workflows/<runId>/agent-<t>.jsonl`
18
- * - remote agents: `subagents/remote-agents/...` (CC's own migration walks the three siblings;
19
- * we walk EVERY subdirectory — symlinks are not followed)
20
- * - companion meta: `agent-<id>.meta.json` = `{agentType, description, name, toolUseId,
21
- * spawnDepth}` (revival lookup keys; same family as BackgroundAgentRecord's meta-sidecar parity
22
- * fields). Absent meta is tolerated (fail-soft) — the jsonl alone still enumerates.
23
- *
24
- * Line container = the CC session-entry envelope (same container as the main-session transcript):
25
- * `{type:"user"|"assistant", message:{...}, uuid, parentUuid, timestamp, ...}` interleaved with
26
- * attachment/marker lines that carry no `message`. Projection keeps ONLY the message-bearing
27
- * user/assistant lines; everything else is counted, never silently vanished.
28
- *
29
- * Locking: none. CC appends whole lines; reads tolerate a torn trailing line as one malformed line
30
- * (counted). D-3 promises sequential handover only — a concurrently-writing CC process is outside
31
- * the supported envelope, and read-side locks would not widen it.
32
- */
33
- /** Companion `agent-<id>.meta.json` shape (loose — unknown keys ride through verbatim). */
34
- export interface CcSidecarMeta extends Record<string, unknown> {
35
- agentType?: string;
36
- description?: string;
37
- name?: string;
38
- toolUseId?: string;
39
- spawnDepth?: number;
40
- }
41
- /** One enumerated sidecar transcript (jsonl + optional companion meta). */
42
- export interface CcSidecarHandle {
43
- /** The `<id>` from the `agent-<id>.jsonl` filename. */
44
- agentId: string;
45
- /** Absolute path to the transcript jsonl. */
46
- jsonlPath: string;
47
- /** Directory segments under `subagents/` (nesting/workflows/remote-agents); flat sidecar = []. */
48
- segments: string[];
49
- /** Parsed companion meta; `undefined` when the meta file is absent or unparseable (fail-soft). */
50
- meta?: CcSidecarMeta;
51
- }
52
- /**
53
- * Enumerate every transcript sidecar under a CC `subagents/` directory, walking nested
54
- * parent-segment subdirectories (symlinks not followed). Missing directory ⇒ `[]` — the CC tree is
55
- * a PARTIAL tree (headless runs write sidecars but a REPL-only subtree may be absent entirely), so
56
- * absence is a normal state, never a throw.
57
- * Order is deterministic: lexicographic by (segments join, agentId).
58
- */
59
- export declare function listCcSidecarAgents(subagentsDir: string): CcSidecarHandle[];
60
- /** One parsed jsonl line, verbatim (the raw CC session-entry envelope). */
61
- export interface CcSidecarLine {
62
- raw: Record<string, unknown>;
63
- }
64
- /** A parsed sidecar transcript: verbatim lines + an honest malformed-line count. */
65
- export interface CcSidecarTranscript {
66
- lines: CcSidecarLine[];
67
- /** Lines that failed JSON.parse or were not objects (e.g. a torn trailing append). */
68
- malformedLines: number;
69
- }
70
- export declare function readCcSidecarTranscript(jsonlPath: string): CcSidecarTranscript;
71
- /** Projection result: sema-shaped messages + honest counts for what was NOT projected. */
72
- export interface CcSidecarMessages {
73
- messages: Message[];
74
- /** Envelope lines without a projectable user/assistant message (attachments, markers, …). */
75
- skippedLines: number;
76
- }
77
- /**
78
- * Project parsed sidecar lines into sema message shapes for resume context.
79
- *
80
- * Mapping (CC session-entry → sema):
81
- * - `type:"user"`, string content → {@link UserMessage} verbatim.
82
- * - `type:"user"`, array content → contiguous `text`/`image` runs fold into
83
- * {@link UserMessage}s and `tool_result` blocks become {@link ToolResultMessage} rows, in DISK
84
- * BLOCK ORDER (toolName recovered from the preceding assistant `tool_use` id — "unknown" when
85
- * the pairing is outside the file; base64 image sources map to sema ImageContent).
86
- * - `type:"assistant"` → {@link AssistantMessage}; `text`/`thinking`/
87
- * `redacted_thinking`/`tool_use` blocks map to their sema block shapes; `api:"anthropic-messages"`,
88
- * `provider:"claude-code"` (an honest origin label — this transcript was produced by CC, not by
89
- * a sema brain), model/usage/stop_reason carried over (`cost` unpriced-zero).
90
- * - anything else (attachment lines, marker lines, unknown block types) → counted in
91
- * `skippedLines`, never a throw and never a silent drop.
92
- */
93
- export declare function ccSidecarToMessages(lines: CcSidecarLine[]): CcSidecarMessages;
94
- /** Convenience: enumerate + parse + project one sidecar in a single read-only call. */
95
- export declare function readCcSidecarMessages(handle: CcSidecarHandle): CcSidecarMessages & {
96
- malformedLines: number;
97
- };
@@ -1,264 +0,0 @@
1
- import { existsSync, readFileSync, readdirSync } from "node:fs";
2
- import { join } from "node:path";
3
- const SIDECAR_RE = /^agent-(.+)\.jsonl$/;
4
- export function listCcSidecarAgents(subagentsDir) {
5
- if (!existsSync(subagentsDir))
6
- return [];
7
- const out = [];
8
- const walk = (dir, segments) => {
9
- let entries;
10
- try {
11
- entries = readdirSync(dir, { withFileTypes: true });
12
- }
13
- catch {
14
- return;
15
- }
16
- for (const ent of entries) {
17
- if (ent.isDirectory()) {
18
- walk(join(dir, ent.name), [...segments, ent.name]);
19
- continue;
20
- }
21
- if (!ent.isFile())
22
- continue;
23
- const m = SIDECAR_RE.exec(ent.name);
24
- if (!m)
25
- continue;
26
- const agentId = m[1];
27
- const jsonlPath = join(dir, ent.name);
28
- const metaPath = join(dir, `agent-${agentId}.meta.json`);
29
- let meta;
30
- if (existsSync(metaPath)) {
31
- try {
32
- const parsed = JSON.parse(readFileSync(metaPath, "utf8"));
33
- if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
34
- meta = parsed;
35
- }
36
- }
37
- catch {
38
- meta = undefined;
39
- }
40
- }
41
- out.push({ agentId, jsonlPath, segments, meta });
42
- }
43
- };
44
- walk(subagentsDir, []);
45
- out.sort((a, b) => {
46
- const sa = a.segments.join("/");
47
- const sb = b.segments.join("/");
48
- return sa < sb ? -1 : sa > sb ? 1 : a.agentId < b.agentId ? -1 : a.agentId > b.agentId ? 1 : 0;
49
- });
50
- return out;
51
- }
52
- function splitLines(bytes) {
53
- const out = [];
54
- let start = 0;
55
- for (let i = 0; i < bytes.length; i++) {
56
- if (bytes[i] === 0x0a) {
57
- out.push(bytes.subarray(start, i));
58
- start = i + 1;
59
- }
60
- }
61
- out.push(bytes.subarray(start));
62
- return out;
63
- }
64
- export function readCcSidecarTranscript(jsonlPath) {
65
- let bytes;
66
- try {
67
- bytes = readFileSync(jsonlPath);
68
- }
69
- catch (err) {
70
- const code = err.code;
71
- if (code === "ENOENT" || code === "ENOTDIR")
72
- return { lines: [], malformedLines: 0 };
73
- throw err;
74
- }
75
- const lines = [];
76
- let malformedLines = 0;
77
- const decoder = new TextDecoder("utf-8", { fatal: true });
78
- for (const lineBytes of splitLines(bytes)) {
79
- let rawLine;
80
- try {
81
- rawLine = decoder.decode(lineBytes);
82
- }
83
- catch {
84
- if (lineBytes.length > 0)
85
- malformedLines += 1;
86
- continue;
87
- }
88
- if (rawLine.trim() === "")
89
- continue;
90
- try {
91
- const parsed = JSON.parse(rawLine);
92
- if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
93
- lines.push({ raw: parsed });
94
- }
95
- else {
96
- malformedLines += 1;
97
- }
98
- }
99
- catch {
100
- malformedLines += 1;
101
- }
102
- }
103
- return { lines, malformedLines };
104
- }
105
- function asRecord(v) {
106
- return v !== null && typeof v === "object" && !Array.isArray(v) ? v : undefined;
107
- }
108
- function toMs(iso) {
109
- if (typeof iso !== "string")
110
- return 0;
111
- const ms = Date.parse(iso);
112
- return Number.isFinite(ms) ? ms : 0;
113
- }
114
- function num(v) {
115
- return typeof v === "number" && Number.isFinite(v) ? v : 0;
116
- }
117
- function mapStopReason(v) {
118
- switch (v) {
119
- case "tool_use":
120
- return "toolUse";
121
- case "max_tokens":
122
- return "length";
123
- default:
124
- return "stop";
125
- }
126
- }
127
- function mapUsage(v) {
128
- const u = asRecord(v);
129
- const input = num(u?.input_tokens);
130
- const output = num(u?.output_tokens);
131
- const cacheRead = num(u?.cache_read_input_tokens);
132
- const cacheWrite = num(u?.cache_creation_input_tokens);
133
- return {
134
- usage: {
135
- input,
136
- output,
137
- cacheRead,
138
- cacheWrite,
139
- totalTokens: input + output + cacheRead + cacheWrite,
140
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
141
- },
142
- usageMissing: u === undefined,
143
- };
144
- }
145
- export function ccSidecarToMessages(lines) {
146
- const messages = [];
147
- let skippedLines = 0;
148
- const toolNames = new Map();
149
- for (const { raw } of lines) {
150
- const message = asRecord(raw.message);
151
- const timestamp = toMs(raw.timestamp);
152
- if (raw.type === "user" && message !== undefined) {
153
- const content = message.content;
154
- if (typeof content === "string") {
155
- const m = { role: "user", content, timestamp };
156
- messages.push(m);
157
- continue;
158
- }
159
- if (Array.isArray(content)) {
160
- let userBlocks = [];
161
- let projectedAny = false;
162
- const flushUser = () => {
163
- if (userBlocks.length > 0) {
164
- messages.push({ role: "user", content: userBlocks, timestamp });
165
- userBlocks = [];
166
- projectedAny = true;
167
- }
168
- };
169
- for (const block of content) {
170
- const b = asRecord(block);
171
- if (b?.type === "text" && typeof b.text === "string") {
172
- userBlocks.push({ type: "text", text: b.text });
173
- }
174
- else if (b?.type === "image") {
175
- const source = asRecord(b.source);
176
- if (source?.type === "base64" && typeof source.data === "string" && typeof source.media_type === "string") {
177
- userBlocks.push({ type: "image", data: source.data, mimeType: source.media_type });
178
- }
179
- }
180
- else if (b?.type === "tool_result" && typeof b.tool_use_id === "string") {
181
- flushUser();
182
- const m = {
183
- role: "toolResult",
184
- toolCallId: b.tool_use_id,
185
- toolName: toolNames.get(b.tool_use_id) ?? "unknown",
186
- content: projectToolResultContent(b.content),
187
- isError: b.is_error === true,
188
- timestamp,
189
- };
190
- messages.push(m);
191
- projectedAny = true;
192
- }
193
- }
194
- flushUser();
195
- if (!projectedAny)
196
- skippedLines += 1;
197
- continue;
198
- }
199
- skippedLines += 1;
200
- continue;
201
- }
202
- if (raw.type === "assistant" && message !== undefined && Array.isArray(message.content)) {
203
- const blocks = [];
204
- for (const block of message.content) {
205
- const b = asRecord(block);
206
- if (b?.type === "text" && typeof b.text === "string") {
207
- blocks.push({ type: "text", text: b.text });
208
- }
209
- else if (b?.type === "thinking" && typeof b.thinking === "string") {
210
- const t = { type: "thinking", thinking: b.thinking };
211
- if (typeof b.signature === "string")
212
- t.thinkingSignature = b.signature;
213
- blocks.push(t);
214
- }
215
- else if (b?.type === "redacted_thinking" && typeof b.data === "string") {
216
- blocks.push({ type: "thinking", thinking: "", thinkingSignature: b.data, redacted: true });
217
- }
218
- else if (b?.type === "tool_use" && typeof b.id === "string" && typeof b.name === "string") {
219
- toolNames.set(b.id, b.name);
220
- blocks.push({ type: "toolCall", id: b.id, name: b.name, arguments: asRecord(b.input) ?? {} });
221
- }
222
- }
223
- if (blocks.length === 0) {
224
- skippedLines += 1;
225
- continue;
226
- }
227
- const { usage, usageMissing } = mapUsage(message.usage);
228
- const m = {
229
- role: "assistant",
230
- content: blocks,
231
- api: "anthropic-messages",
232
- provider: "claude-code",
233
- model: typeof message.model === "string" ? message.model : "unknown",
234
- usage,
235
- stopReason: mapStopReason(message.stop_reason),
236
- timestamp,
237
- };
238
- if (usageMissing)
239
- m.usageMissing = true;
240
- messages.push(m);
241
- continue;
242
- }
243
- skippedLines += 1;
244
- }
245
- return { messages, skippedLines };
246
- }
247
- function projectToolResultContent(content) {
248
- if (typeof content === "string")
249
- return [{ type: "text", text: content }];
250
- if (!Array.isArray(content))
251
- return [];
252
- const out = [];
253
- for (const block of content) {
254
- const b = asRecord(block);
255
- if (b?.type === "text" && typeof b.text === "string")
256
- out.push({ type: "text", text: b.text });
257
- }
258
- return out;
259
- }
260
- export function readCcSidecarMessages(handle) {
261
- const { lines, malformedLines } = readCcSidecarTranscript(handle.jsonlPath);
262
- const projected = ccSidecarToMessages(lines);
263
- return { ...projected, malformedLines };
264
- }
@@ -1,2 +0,0 @@
1
- import type { TaskListStore } from "../../tools/task-list.js";
2
- export declare function createCcFileTaskListStore(listDir: string): TaskListStore;
@@ -1,125 +0,0 @@
1
- import { readFileSync, readdirSync, mkdirSync, unlinkSync } from "node:fs";
2
- import { join, resolve } from "node:path";
3
- import { assertJsonMetadata, normalizeTaskShape } from "../../tools/task-list.js";
4
- import { atomicWriteFile } from "../file/fs-atomic.js";
5
- import { physicalPathOf } from "../../core/physical-path.js";
6
- import { withCcLock } from "./lockfile.js";
7
- export function createCcFileTaskListStore(listDir) {
8
- const dir = resolve(listDir);
9
- mkdirSync(dir, { recursive: true });
10
- const hwmPath = join(dir, ".highwatermark");
11
- const lockTarget = physicalPathOf(dir);
12
- const CC_TASK_ID_RE = /^[A-Za-z0-9_-]+$/;
13
- const validId = (id) => CC_TASK_ID_RE.test(id);
14
- const taskPath = (id) => {
15
- if (!validId(id))
16
- throw new Error(`cc task-list store: invalid task id ${JSON.stringify(id)} (CC id charset [A-Za-z0-9_-] required)`);
17
- return join(dir, `${id}.json`);
18
- };
19
- const scanIds = () => readdirSync(dir)
20
- .filter((f) => f.endsWith(".json"))
21
- .map((f) => f.slice(0, -".json".length))
22
- .filter((id) => validId(id));
23
- const scanNumericIds = () => scanIds()
24
- .map((id) => Number.parseInt(id, 10))
25
- .filter((n) => Number.isFinite(n));
26
- const orderIds = (ids) => {
27
- const num = (id) => (/^\d+$/.test(id) ? Number.parseInt(id, 10) : Number.NaN);
28
- return [...ids].sort((a, b) => {
29
- const [na, nb] = [num(a), num(b)];
30
- if (Number.isFinite(na) && Number.isFinite(nb))
31
- return na - nb || a.localeCompare(b);
32
- if (Number.isFinite(na))
33
- return -1;
34
- if (Number.isFinite(nb))
35
- return 1;
36
- return a.localeCompare(b);
37
- });
38
- };
39
- const readHwm = () => {
40
- try {
41
- const raw = readFileSync(hwmPath, "utf8").trim();
42
- const n = Number.parseInt(raw, 10);
43
- return Number.isFinite(n) ? n : 0;
44
- }
45
- catch {
46
- return 0;
47
- }
48
- };
49
- const readTask = (id) => {
50
- if (!validId(id))
51
- return undefined;
52
- try {
53
- return JSON.parse(readFileSync(taskPath(id), "utf8"));
54
- }
55
- catch (err) {
56
- if (err.code === "ENOENT")
57
- return undefined;
58
- throw err;
59
- }
60
- };
61
- const writeTask = (id, item) => {
62
- atomicWriteFile(dir, taskPath(id), JSON.stringify(item, null, 2));
63
- };
64
- const snap = (t) => structuredClone(t);
65
- const store = {
66
- get: (id) => withCcLock(lockTarget, () => {
67
- const t = readTask(id);
68
- return t ? snap(t) : undefined;
69
- }),
70
- set: (id, item) => withCcLock(lockTarget, () => {
71
- if (item.metadata)
72
- assertJsonMetadata(item.metadata);
73
- const prior = readTask(id);
74
- writeTask(id, { ...(prior ?? {}), ...normalizeTaskShape(snap(item)) });
75
- }),
76
- delete: (id) => withCcLock(lockTarget, () => {
77
- if (readTask(id) === undefined)
78
- return false;
79
- unlinkSync(taskPath(id));
80
- return true;
81
- }),
82
- list: () => withCcLock(lockTarget, () => orderIds(scanIds())
83
- .map((id) => readTask(id))
84
- .filter((t) => t !== undefined)
85
- .map(snap)),
86
- allocateId: () => withCcLock(lockTarget, () => {
87
- const scanned = scanNumericIds();
88
- const next = Math.max(readHwm(), scanned.length > 0 ? Math.max(...scanned) : 0) + 1;
89
- atomicWriteFile(dir, hwmPath, String(next));
90
- return String(next);
91
- }),
92
- mutate: (fn) => withCcLock(lockTarget, () => {
93
- const tx = {
94
- get: (id) => {
95
- const t = readTask(id);
96
- return t ? snap(t) : undefined;
97
- },
98
- set: (id, item) => {
99
- if (item.metadata)
100
- assertJsonMetadata(item.metadata);
101
- const prior = readTask(id);
102
- writeTask(id, { ...(prior ?? {}), ...normalizeTaskShape(snap(item)) });
103
- },
104
- delete: (id) => {
105
- if (readTask(id) === undefined)
106
- return false;
107
- unlinkSync(taskPath(id));
108
- return true;
109
- },
110
- list: () => orderIds(scanIds())
111
- .map((id) => readTask(id))
112
- .filter((t) => t !== undefined)
113
- .map(snap),
114
- allocateId: () => {
115
- const scanned = scanNumericIds();
116
- const next = Math.max(readHwm(), scanned.length > 0 ? Math.max(...scanned) : 0) + 1;
117
- atomicWriteFile(dir, hwmPath, String(next));
118
- return String(next);
119
- },
120
- };
121
- return fn(tx);
122
- }),
123
- };
124
- return store;
125
- }