@itaila/archetype 0.3.30

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 (319) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +475 -0
  3. package/dist/audit/audit-persona.d.ts +163 -0
  4. package/dist/audit/audit-persona.d.ts.map +1 -0
  5. package/dist/audit/audit-persona.js +415 -0
  6. package/dist/audit/audit-persona.js.map +1 -0
  7. package/dist/audit/brain-reflection.d.ts +33 -0
  8. package/dist/audit/brain-reflection.d.ts.map +1 -0
  9. package/dist/audit/brain-reflection.js +148 -0
  10. package/dist/audit/brain-reflection.js.map +1 -0
  11. package/dist/audit/conversation-audit.d.ts +12 -0
  12. package/dist/audit/conversation-audit.d.ts.map +1 -0
  13. package/dist/audit/conversation-audit.js +76 -0
  14. package/dist/audit/conversation-audit.js.map +1 -0
  15. package/dist/audit/prompt-audit.d.ts +10 -0
  16. package/dist/audit/prompt-audit.d.ts.map +1 -0
  17. package/dist/audit/prompt-audit.js +153 -0
  18. package/dist/audit/prompt-audit.js.map +1 -0
  19. package/dist/audit/prompt-dump.d.ts +137 -0
  20. package/dist/audit/prompt-dump.d.ts.map +1 -0
  21. package/dist/audit/prompt-dump.js +269 -0
  22. package/dist/audit/prompt-dump.js.map +1 -0
  23. package/dist/audit/trace-integrity.d.ts +33 -0
  24. package/dist/audit/trace-integrity.d.ts.map +1 -0
  25. package/dist/audit/trace-integrity.js +109 -0
  26. package/dist/audit/trace-integrity.js.map +1 -0
  27. package/dist/audit/types.d.ts +92 -0
  28. package/dist/audit/types.d.ts.map +1 -0
  29. package/dist/audit/types.js +2 -0
  30. package/dist/audit/types.js.map +1 -0
  31. package/dist/audit/version.d.ts +14 -0
  32. package/dist/audit/version.d.ts.map +1 -0
  33. package/dist/audit/version.js +65 -0
  34. package/dist/audit/version.js.map +1 -0
  35. package/dist/brain.d.ts +7 -0
  36. package/dist/brain.d.ts.map +1 -0
  37. package/dist/brain.js +83 -0
  38. package/dist/brain.js.map +1 -0
  39. package/dist/builder/actions.d.ts +60 -0
  40. package/dist/builder/actions.d.ts.map +1 -0
  41. package/dist/builder/actions.js +257 -0
  42. package/dist/builder/actions.js.map +1 -0
  43. package/dist/builder/browser.d.ts +140 -0
  44. package/dist/builder/browser.d.ts.map +1 -0
  45. package/dist/builder/browser.js +232 -0
  46. package/dist/builder/browser.js.map +1 -0
  47. package/dist/builder/executor.d.ts +228 -0
  48. package/dist/builder/executor.d.ts.map +1 -0
  49. package/dist/builder/executor.js +1548 -0
  50. package/dist/builder/executor.js.map +1 -0
  51. package/dist/builder/index.d.ts +24 -0
  52. package/dist/builder/index.d.ts.map +1 -0
  53. package/dist/builder/index.js +24 -0
  54. package/dist/builder/index.js.map +1 -0
  55. package/dist/builder/node-test-discovery.d.ts +13 -0
  56. package/dist/builder/node-test-discovery.d.ts.map +1 -0
  57. package/dist/builder/node-test-discovery.js +45 -0
  58. package/dist/builder/node-test-discovery.js.map +1 -0
  59. package/dist/builder/sandbox.d.ts +172 -0
  60. package/dist/builder/sandbox.d.ts.map +1 -0
  61. package/dist/builder/sandbox.js +294 -0
  62. package/dist/builder/sandbox.js.map +1 -0
  63. package/dist/builder/workspace-files.d.ts +63 -0
  64. package/dist/builder/workspace-files.d.ts.map +1 -0
  65. package/dist/builder/workspace-files.js +190 -0
  66. package/dist/builder/workspace-files.js.map +1 -0
  67. package/dist/core/actions.d.ts +55 -0
  68. package/dist/core/actions.d.ts.map +1 -0
  69. package/dist/core/actions.js +311 -0
  70. package/dist/core/actions.js.map +1 -0
  71. package/dist/core/attachment-notes.d.ts +7 -0
  72. package/dist/core/attachment-notes.d.ts.map +1 -0
  73. package/dist/core/attachment-notes.js +38 -0
  74. package/dist/core/attachment-notes.js.map +1 -0
  75. package/dist/core/context.d.ts +10 -0
  76. package/dist/core/context.d.ts.map +1 -0
  77. package/dist/core/context.js +108 -0
  78. package/dist/core/context.js.map +1 -0
  79. package/dist/core/crud-prompt.d.ts +16 -0
  80. package/dist/core/crud-prompt.d.ts.map +1 -0
  81. package/dist/core/crud-prompt.js +268 -0
  82. package/dist/core/crud-prompt.js.map +1 -0
  83. package/dist/core/crud-schema.d.ts +12 -0
  84. package/dist/core/crud-schema.d.ts.map +1 -0
  85. package/dist/core/crud-schema.js +42 -0
  86. package/dist/core/crud-schema.js.map +1 -0
  87. package/dist/core/effective-config.d.ts +13 -0
  88. package/dist/core/effective-config.d.ts.map +1 -0
  89. package/dist/core/effective-config.js +33 -0
  90. package/dist/core/effective-config.js.map +1 -0
  91. package/dist/core/entities.d.ts +82 -0
  92. package/dist/core/entities.d.ts.map +1 -0
  93. package/dist/core/entities.js +116 -0
  94. package/dist/core/entities.js.map +1 -0
  95. package/dist/core/entity-helpers.d.ts +47 -0
  96. package/dist/core/entity-helpers.d.ts.map +1 -0
  97. package/dist/core/entity-helpers.js +122 -0
  98. package/dist/core/entity-helpers.js.map +1 -0
  99. package/dist/core/entity-registry.d.ts +47 -0
  100. package/dist/core/entity-registry.d.ts.map +1 -0
  101. package/dist/core/entity-registry.js +54 -0
  102. package/dist/core/entity-registry.js.map +1 -0
  103. package/dist/core/eq.d.ts +13 -0
  104. package/dist/core/eq.d.ts.map +1 -0
  105. package/dist/core/eq.js +41 -0
  106. package/dist/core/eq.js.map +1 -0
  107. package/dist/core/focus-context.d.ts +19 -0
  108. package/dist/core/focus-context.d.ts.map +1 -0
  109. package/dist/core/focus-context.js +46 -0
  110. package/dist/core/focus-context.js.map +1 -0
  111. package/dist/core/focus-mode-actions.d.ts +23 -0
  112. package/dist/core/focus-mode-actions.d.ts.map +1 -0
  113. package/dist/core/focus-mode-actions.js +74 -0
  114. package/dist/core/focus-mode-actions.js.map +1 -0
  115. package/dist/core/greeting.d.ts +10 -0
  116. package/dist/core/greeting.d.ts.map +1 -0
  117. package/dist/core/greeting.js +41 -0
  118. package/dist/core/greeting.js.map +1 -0
  119. package/dist/core/identity.d.ts +13 -0
  120. package/dist/core/identity.d.ts.map +1 -0
  121. package/dist/core/identity.js +54 -0
  122. package/dist/core/identity.js.map +1 -0
  123. package/dist/core/knowledge.d.ts +10 -0
  124. package/dist/core/knowledge.d.ts.map +1 -0
  125. package/dist/core/knowledge.js +40 -0
  126. package/dist/core/knowledge.js.map +1 -0
  127. package/dist/core/memory-actions.d.ts +38 -0
  128. package/dist/core/memory-actions.d.ts.map +1 -0
  129. package/dist/core/memory-actions.js +181 -0
  130. package/dist/core/memory-actions.js.map +1 -0
  131. package/dist/core/memory.d.ts +35 -0
  132. package/dist/core/memory.d.ts.map +1 -0
  133. package/dist/core/memory.js +168 -0
  134. package/dist/core/memory.js.map +1 -0
  135. package/dist/core/peer-actions.d.ts +15 -0
  136. package/dist/core/peer-actions.d.ts.map +1 -0
  137. package/dist/core/peer-actions.js +33 -0
  138. package/dist/core/peer-actions.js.map +1 -0
  139. package/dist/core/prompt-builder.d.ts +46 -0
  140. package/dist/core/prompt-builder.d.ts.map +1 -0
  141. package/dist/core/prompt-builder.js +543 -0
  142. package/dist/core/prompt-builder.js.map +1 -0
  143. package/dist/core/prompt-mode.d.ts +3 -0
  144. package/dist/core/prompt-mode.d.ts.map +1 -0
  145. package/dist/core/prompt-mode.js +6 -0
  146. package/dist/core/prompt-mode.js.map +1 -0
  147. package/dist/core/prompted-turn.d.ts +6 -0
  148. package/dist/core/prompted-turn.d.ts.map +1 -0
  149. package/dist/core/prompted-turn.js +48 -0
  150. package/dist/core/prompted-turn.js.map +1 -0
  151. package/dist/core/request-builder.d.ts +14 -0
  152. package/dist/core/request-builder.d.ts.map +1 -0
  153. package/dist/core/request-builder.js +64 -0
  154. package/dist/core/request-builder.js.map +1 -0
  155. package/dist/core/session-routing.d.ts +23 -0
  156. package/dist/core/session-routing.d.ts.map +1 -0
  157. package/dist/core/session-routing.js +59 -0
  158. package/dist/core/session-routing.js.map +1 -0
  159. package/dist/core/voice.d.ts +6 -0
  160. package/dist/core/voice.d.ts.map +1 -0
  161. package/dist/core/voice.js +30 -0
  162. package/dist/core/voice.js.map +1 -0
  163. package/dist/engine/chat.d.ts +45 -0
  164. package/dist/engine/chat.d.ts.map +1 -0
  165. package/dist/engine/chat.js +308 -0
  166. package/dist/engine/chat.js.map +1 -0
  167. package/dist/engine/continuity.d.ts +107 -0
  168. package/dist/engine/continuity.d.ts.map +1 -0
  169. package/dist/engine/continuity.js +320 -0
  170. package/dist/engine/continuity.js.map +1 -0
  171. package/dist/engine/crud.d.ts +62 -0
  172. package/dist/engine/crud.d.ts.map +1 -0
  173. package/dist/engine/crud.js +260 -0
  174. package/dist/engine/crud.js.map +1 -0
  175. package/dist/engine/side-effects.d.ts +93 -0
  176. package/dist/engine/side-effects.d.ts.map +1 -0
  177. package/dist/engine/side-effects.js +271 -0
  178. package/dist/engine/side-effects.js.map +1 -0
  179. package/dist/engine/staging.d.ts +29 -0
  180. package/dist/engine/staging.d.ts.map +1 -0
  181. package/dist/engine/staging.js +159 -0
  182. package/dist/engine/staging.js.map +1 -0
  183. package/dist/engine/working-set.d.ts +18 -0
  184. package/dist/engine/working-set.d.ts.map +1 -0
  185. package/dist/engine/working-set.js +246 -0
  186. package/dist/engine/working-set.js.map +1 -0
  187. package/dist/evals/action-contracts.d.ts +40 -0
  188. package/dist/evals/action-contracts.d.ts.map +1 -0
  189. package/dist/evals/action-contracts.js +208 -0
  190. package/dist/evals/action-contracts.js.map +1 -0
  191. package/dist/evals/brain-bloat.d.ts +39 -0
  192. package/dist/evals/brain-bloat.d.ts.map +1 -0
  193. package/dist/evals/brain-bloat.js +167 -0
  194. package/dist/evals/brain-bloat.js.map +1 -0
  195. package/dist/evals/brain-prescriptions.d.ts +30 -0
  196. package/dist/evals/brain-prescriptions.d.ts.map +1 -0
  197. package/dist/evals/brain-prescriptions.js +148 -0
  198. package/dist/evals/brain-prescriptions.js.map +1 -0
  199. package/dist/evals/cross-layer-duplicates.d.ts +49 -0
  200. package/dist/evals/cross-layer-duplicates.d.ts.map +1 -0
  201. package/dist/evals/cross-layer-duplicates.js +289 -0
  202. package/dist/evals/cross-layer-duplicates.js.map +1 -0
  203. package/dist/evals/entity-visibility.d.ts +28 -0
  204. package/dist/evals/entity-visibility.d.ts.map +1 -0
  205. package/dist/evals/entity-visibility.js +216 -0
  206. package/dist/evals/entity-visibility.js.map +1 -0
  207. package/dist/evals/index.d.ts +19 -0
  208. package/dist/evals/index.d.ts.map +1 -0
  209. package/dist/evals/index.js +11 -0
  210. package/dist/evals/index.js.map +1 -0
  211. package/dist/evals/judge.d.ts +22 -0
  212. package/dist/evals/judge.d.ts.map +1 -0
  213. package/dist/evals/judge.js +337 -0
  214. package/dist/evals/judge.js.map +1 -0
  215. package/dist/evals/operational-contract.d.ts +40 -0
  216. package/dist/evals/operational-contract.d.ts.map +1 -0
  217. package/dist/evals/operational-contract.js +115 -0
  218. package/dist/evals/operational-contract.js.map +1 -0
  219. package/dist/evals/prompt-content.d.ts +14 -0
  220. package/dist/evals/prompt-content.d.ts.map +1 -0
  221. package/dist/evals/prompt-content.js +104 -0
  222. package/dist/evals/prompt-content.js.map +1 -0
  223. package/dist/evals/runtime.d.ts +4 -0
  224. package/dist/evals/runtime.d.ts.map +1 -0
  225. package/dist/evals/runtime.js +197 -0
  226. package/dist/evals/runtime.js.map +1 -0
  227. package/dist/evals/sample-projects.d.ts +143 -0
  228. package/dist/evals/sample-projects.d.ts.map +1 -0
  229. package/dist/evals/sample-projects.js +644 -0
  230. package/dist/evals/sample-projects.js.map +1 -0
  231. package/dist/evals/types.d.ts +88 -0
  232. package/dist/evals/types.d.ts.map +1 -0
  233. package/dist/evals/types.js +2 -0
  234. package/dist/evals/types.js.map +1 -0
  235. package/dist/foundation/index.d.ts +158 -0
  236. package/dist/foundation/index.d.ts.map +1 -0
  237. package/dist/foundation/index.js +256 -0
  238. package/dist/foundation/index.js.map +1 -0
  239. package/dist/index.d.ts +223 -0
  240. package/dist/index.d.ts.map +1 -0
  241. package/dist/index.js +998 -0
  242. package/dist/index.js.map +1 -0
  243. package/dist/managed/autonomous-loop.d.ts +199 -0
  244. package/dist/managed/autonomous-loop.d.ts.map +1 -0
  245. package/dist/managed/autonomous-loop.js +451 -0
  246. package/dist/managed/autonomous-loop.js.map +1 -0
  247. package/dist/managed/conversation.d.ts +20 -0
  248. package/dist/managed/conversation.d.ts.map +1 -0
  249. package/dist/managed/conversation.js +40 -0
  250. package/dist/managed/conversation.js.map +1 -0
  251. package/dist/managed/knowledge.d.ts +7 -0
  252. package/dist/managed/knowledge.d.ts.map +1 -0
  253. package/dist/managed/knowledge.js +174 -0
  254. package/dist/managed/knowledge.js.map +1 -0
  255. package/dist/managed/memory-manager.d.ts +7 -0
  256. package/dist/managed/memory-manager.d.ts.map +1 -0
  257. package/dist/managed/memory-manager.js +18 -0
  258. package/dist/managed/memory-manager.js.map +1 -0
  259. package/dist/managed/memory-review.d.ts +45 -0
  260. package/dist/managed/memory-review.d.ts.map +1 -0
  261. package/dist/managed/memory-review.js +130 -0
  262. package/dist/managed/memory-review.js.map +1 -0
  263. package/dist/managed/storage.d.ts +2 -0
  264. package/dist/managed/storage.d.ts.map +1 -0
  265. package/dist/managed/storage.js +2 -0
  266. package/dist/managed/storage.js.map +1 -0
  267. package/dist/managed/work-history.d.ts +23 -0
  268. package/dist/managed/work-history.d.ts.map +1 -0
  269. package/dist/managed/work-history.js +31 -0
  270. package/dist/managed/work-history.js.map +1 -0
  271. package/dist/observability/index.d.ts +15 -0
  272. package/dist/observability/index.d.ts.map +1 -0
  273. package/dist/observability/index.js +15 -0
  274. package/dist/observability/index.js.map +1 -0
  275. package/dist/observability/render-run-markdown.d.ts +90 -0
  276. package/dist/observability/render-run-markdown.d.ts.map +1 -0
  277. package/dist/observability/render-run-markdown.js +231 -0
  278. package/dist/observability/render-run-markdown.js.map +1 -0
  279. package/dist/observability/turn-reporter.d.ts +20 -0
  280. package/dist/observability/turn-reporter.d.ts.map +1 -0
  281. package/dist/observability/turn-reporter.js +106 -0
  282. package/dist/observability/turn-reporter.js.map +1 -0
  283. package/dist/persona.d.ts +49 -0
  284. package/dist/persona.d.ts.map +1 -0
  285. package/dist/persona.js +287 -0
  286. package/dist/persona.js.map +1 -0
  287. package/dist/playbook/defaults.d.ts +25 -0
  288. package/dist/playbook/defaults.d.ts.map +1 -0
  289. package/dist/playbook/defaults.js +108 -0
  290. package/dist/playbook/defaults.js.map +1 -0
  291. package/dist/playbook/invariants.d.ts +244 -0
  292. package/dist/playbook/invariants.d.ts.map +1 -0
  293. package/dist/playbook/invariants.js +259 -0
  294. package/dist/playbook/invariants.js.map +1 -0
  295. package/dist/playbook/templates.d.ts +7 -0
  296. package/dist/playbook/templates.d.ts.map +1 -0
  297. package/dist/playbook/templates.js +437 -0
  298. package/dist/playbook/templates.js.map +1 -0
  299. package/dist/providers/gemini.d.ts +73 -0
  300. package/dist/providers/gemini.d.ts.map +1 -0
  301. package/dist/providers/gemini.js +536 -0
  302. package/dist/providers/gemini.js.map +1 -0
  303. package/dist/providers/types.d.ts +2 -0
  304. package/dist/providers/types.d.ts.map +1 -0
  305. package/dist/providers/types.js +2 -0
  306. package/dist/providers/types.js.map +1 -0
  307. package/dist/providers/zod-to-gemini.d.ts +8 -0
  308. package/dist/providers/zod-to-gemini.d.ts.map +1 -0
  309. package/dist/providers/zod-to-gemini.js +148 -0
  310. package/dist/providers/zod-to-gemini.js.map +1 -0
  311. package/dist/samples/pm-spec-agent.d.ts +22 -0
  312. package/dist/samples/pm-spec-agent.d.ts.map +1 -0
  313. package/dist/samples/pm-spec-agent.js +53 -0
  314. package/dist/samples/pm-spec-agent.js.map +1 -0
  315. package/dist/types.d.ts +920 -0
  316. package/dist/types.d.ts.map +1 -0
  317. package/dist/types.js +2 -0
  318. package/dist/types.js.map +1 -0
  319. package/package.json +68 -0
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Sandbox — the low-level confined-execution primitive every coder-
3
+ * persona builder needs.
4
+ *
5
+ * Contract:
6
+ * — `exec` one-shot command, awaits completion, returns result.
7
+ * — `spawn` long-running command with ready-pattern detection
8
+ * (for local HTTP servers, watchers, etc.).
9
+ * — `cleanup` terminate any still-running children.
10
+ *
11
+ * What belongs here (the archetype layer):
12
+ * — `Sandbox` interface
13
+ * — `SrtSandbox` default impl wrapping `@anthropic-ai/sandbox-runtime`
14
+ * (binary path is passed in — archetype does not resolve it)
15
+ * — `buildSandboxConfig` + `createAllowlistedEnv` helpers so host
16
+ * apps can compose per-preset configurations.
17
+ *
18
+ * What does NOT belong here:
19
+ * — Benchmark-specific presets (workspace-build, local-start, etc.)
20
+ * — those encode product decisions about what each tool should do.
21
+ * — Trusted-toolchain resolution (node/npm/eslint binary paths) — the
22
+ * host app owns which binaries are trusted.
23
+ * — Evidence file writing, telemetry, metric emission — orchestration
24
+ * layer, not runtime layer.
25
+ *
26
+ * Node-only: uses `node:child_process` + `node:fs`. Consumers that only
27
+ * need browser-safe archetype features (personas, actions, memory)
28
+ * should not reach for this module.
29
+ */
30
+ import { execFile, spawn } from 'node:child_process';
31
+ import { promisify } from 'node:util';
32
+ import fs from 'node:fs';
33
+ import os from 'node:os';
34
+ import path from 'node:path';
35
+ const execFileAsync = promisify(execFile);
36
+ /**
37
+ * Default list of environment variables the sandbox never forwards to
38
+ * child processes. Prevents credential leakage + shell-history pollution.
39
+ */
40
+ export const DEFAULT_BLOCKED_ENV_KEYS = new Set([
41
+ 'NODE_OPTIONS',
42
+ 'NODE_PATH',
43
+ 'OPENAI_API_KEY',
44
+ 'ANTHROPIC_API_KEY',
45
+ 'GEMINI_API_KEY',
46
+ 'AWS_SECRET_ACCESS_KEY',
47
+ 'AWS_ACCESS_KEY_ID',
48
+ 'GOOGLE_API_KEY',
49
+ 'SSH_AUTH_SOCK',
50
+ 'HISTFILE',
51
+ 'HISTFILESIZE',
52
+ 'HISTSIZE',
53
+ ]);
54
+ export class SrtSandbox {
55
+ workspaceRoot;
56
+ srtBinary;
57
+ sandboxTempRoot;
58
+ trustedReadPaths;
59
+ blockedEnvKeys;
60
+ settingsDir;
61
+ activeChildren = new Set();
62
+ constructor(options) {
63
+ this.workspaceRoot = path.resolve(options.workspaceRoot);
64
+ this.srtBinary = options.srtBinary;
65
+ this.sandboxTempRoot = path.resolve(options.sandboxTempRoot ?? path.join(this.workspaceRoot, '.sandbox-tmp'));
66
+ this.trustedReadPaths = options.trustedReadPaths ?? [];
67
+ this.blockedEnvKeys = new Set(DEFAULT_BLOCKED_ENV_KEYS);
68
+ for (const key of options.extraBlockedEnvKeys ?? [])
69
+ this.blockedEnvKeys.add(key);
70
+ this.settingsDir = path.resolve(options.settingsDir ?? this.sandboxTempRoot);
71
+ fs.mkdirSync(this.sandboxTempRoot, { recursive: true });
72
+ fs.mkdirSync(this.settingsDir, { recursive: true });
73
+ }
74
+ async exec(options) {
75
+ const { args, settingsPath, env, fullCommand, cwd } = this.prepareCall(options);
76
+ return execFileAsync(this.srtBinary, args, {
77
+ cwd,
78
+ env: env,
79
+ timeout: options.timeoutMs ?? 120_000,
80
+ maxBuffer: 1024 * 1024,
81
+ }).then(value => ({
82
+ ok: true,
83
+ exitCode: 0,
84
+ stdout: value.stdout,
85
+ stderr: value.stderr,
86
+ command: fullCommand,
87
+ settingsPath,
88
+ timedOut: false,
89
+ }), error => ({
90
+ ok: false,
91
+ exitCode: typeof error.code === 'number'
92
+ ? error.code
93
+ : 1,
94
+ stdout: error.stdout ?? '',
95
+ stderr: error.stderr ?? String(error),
96
+ command: fullCommand,
97
+ settingsPath,
98
+ timedOut: error.killed === true,
99
+ }));
100
+ }
101
+ async spawn(options) {
102
+ const { args, settingsPath, env, fullCommand, cwd } = this.prepareCall(options);
103
+ const child = spawn(this.srtBinary, args, {
104
+ cwd,
105
+ env: env,
106
+ stdio: ['ignore', 'pipe', 'pipe'],
107
+ });
108
+ // Track for cleanup: stays in the set until the child actually exits
109
+ // (whether by ready→background-running, or by error, or by SIGTERM
110
+ // from cleanup()). The exit handler is the only place that removes.
111
+ this.activeChildren.add(child);
112
+ child.on('exit', () => {
113
+ this.activeChildren.delete(child);
114
+ });
115
+ let stdout = '';
116
+ let stderr = '';
117
+ let readyMatch = null;
118
+ let resolved = false;
119
+ return new Promise((resolve) => {
120
+ const finalize = (result) => {
121
+ if (resolved)
122
+ return;
123
+ resolved = true;
124
+ resolve(result);
125
+ };
126
+ const timeout = setTimeout(() => {
127
+ if (!child.killed)
128
+ child.kill('SIGTERM');
129
+ finalize({
130
+ ok: false,
131
+ exitCode: 124,
132
+ stdout,
133
+ stderr: `${stderr}\nSpawn did not reach ready state before timeout.`.trim(),
134
+ command: fullCommand,
135
+ settingsPath,
136
+ timedOut: true,
137
+ readyMatch,
138
+ });
139
+ }, options.readyTimeoutMs ?? options.timeoutMs ?? 20_000);
140
+ child.stdout?.on('data', chunk => {
141
+ stdout += chunk.toString();
142
+ if (options.readyPattern && !readyMatch) {
143
+ const m = stdout.match(options.readyPattern);
144
+ if (m) {
145
+ readyMatch = m[1] ?? m[0];
146
+ clearTimeout(timeout);
147
+ // Child stays running in the background. Caller is expected
148
+ // to call cleanup() when done (or call spawn() again for a
149
+ // different long-running process, which also triggers the
150
+ // caller's own cleanup).
151
+ finalize({
152
+ ok: true,
153
+ exitCode: 0,
154
+ stdout,
155
+ stderr,
156
+ command: fullCommand,
157
+ settingsPath,
158
+ timedOut: false,
159
+ readyMatch,
160
+ });
161
+ }
162
+ }
163
+ });
164
+ child.stderr?.on('data', chunk => {
165
+ stderr += chunk.toString();
166
+ });
167
+ child.on('exit', code => {
168
+ if (readyMatch)
169
+ return;
170
+ clearTimeout(timeout);
171
+ finalize({
172
+ ok: false,
173
+ exitCode: code ?? 1,
174
+ stdout,
175
+ stderr,
176
+ command: fullCommand,
177
+ settingsPath,
178
+ timedOut: false,
179
+ readyMatch,
180
+ });
181
+ });
182
+ });
183
+ }
184
+ async cleanup() {
185
+ for (const child of this.activeChildren) {
186
+ if (!child.killed)
187
+ child.kill('SIGTERM');
188
+ }
189
+ this.activeChildren.clear();
190
+ }
191
+ prepareCall(options) {
192
+ const cwd = path.resolve(options.cwd ?? this.workspaceRoot);
193
+ const config = buildSandboxConfig({
194
+ workspaceRoot: this.workspaceRoot,
195
+ sandboxTempRoot: this.sandboxTempRoot,
196
+ trustedReadPaths: this.trustedReadPaths,
197
+ extraReadPaths: options.extraReadPaths,
198
+ extraWritePaths: options.extraWritePaths,
199
+ allowedNetworkDomains: options.allowedNetworkDomains,
200
+ allowLocalBinding: options.allowLocalBinding ?? false,
201
+ });
202
+ const settingsPath = path.join(this.settingsDir, `srt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.json`);
203
+ fs.writeFileSync(settingsPath, JSON.stringify(config, null, 2));
204
+ const env = createAllowlistedEnv(this.sandboxTempRoot, this.blockedEnvKeys);
205
+ const command = this.materializeInlineCommand(options.command);
206
+ const commandString = shellQuoteCommand(command);
207
+ const args = ['--settings', settingsPath, '-c', commandString];
208
+ const fullCommand = [this.srtBinary, ...args];
209
+ return { args, settingsPath, env, fullCommand, cwd };
210
+ }
211
+ materializeInlineCommand(command) {
212
+ const [binary, mode, script, ...rest] = command;
213
+ if (!binary || !mode || typeof script !== 'string')
214
+ return [...command];
215
+ const base = path.basename(binary);
216
+ if ((base === 'sh' || base === 'bash' || binary.endsWith('/sh') || binary.endsWith('/bash')) && mode === '-c') {
217
+ const scriptPath = this.writeInlineScript(script, 'sh');
218
+ return [binary, scriptPath, ...rest];
219
+ }
220
+ if ((mode === '-e' || mode === '--eval') && (base === 'node' || binary.endsWith('/node'))) {
221
+ const scriptPath = this.writeInlineScript(script, 'cjs');
222
+ return [binary, scriptPath, ...rest];
223
+ }
224
+ return [...command];
225
+ }
226
+ writeInlineScript(content, extension) {
227
+ const filePath = path.join(this.sandboxTempRoot, `inline-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.${extension}`);
228
+ fs.writeFileSync(filePath, content, 'utf8');
229
+ return filePath;
230
+ }
231
+ }
232
+ function shellQuoteCommand(argv) {
233
+ return argv.map(shellQuoteArg).join(' ');
234
+ }
235
+ function shellQuoteArg(value) {
236
+ if (value.length === 0)
237
+ return "''";
238
+ return `'${value.replace(/'/g, `'\\''`)}'`;
239
+ }
240
+ /**
241
+ * Build an SRT settings object from the knobs archetype exposes. Host
242
+ * apps can call this directly if they want to assemble settings without
243
+ * going through `SrtSandbox` (tests, one-off invocations).
244
+ *
245
+ * Default deny-read list covers sensitive host paths (home dir, /tmp,
246
+ * kernel mounts). Allow-read is workspace + sandbox temp + caller-
247
+ * supplied trusted paths + per-call extras.
248
+ */
249
+ export function buildSandboxConfig(input) {
250
+ const denyRead = [os.homedir(), '/tmp', '/private/tmp', '/proc', '/sys', '/dev'];
251
+ const allowRead = [
252
+ input.workspaceRoot,
253
+ input.sandboxTempRoot,
254
+ ...(input.trustedReadPaths ?? []),
255
+ ...(input.extraReadPaths ?? []),
256
+ ];
257
+ const allowWrite = [
258
+ input.workspaceRoot,
259
+ input.sandboxTempRoot,
260
+ ...(input.extraWritePaths ?? []),
261
+ ];
262
+ return {
263
+ network: {
264
+ allowedDomains: input.allowedNetworkDomains ?? [],
265
+ deniedDomains: [],
266
+ allowUnixSockets: [],
267
+ allowLocalBinding: input.allowLocalBinding ?? false,
268
+ },
269
+ filesystem: {
270
+ denyRead,
271
+ allowRead,
272
+ allowWrite,
273
+ denyWrite: [],
274
+ },
275
+ };
276
+ }
277
+ /**
278
+ * Build a minimal allowlisted child-process env. Copies only
279
+ * PATH/HOME/LANG/LC_ALL/TERM from the parent, redirects TMPDIR/TMP/TEMP
280
+ * to the sandbox temp root, and blocks everything in `blockedKeys`.
281
+ */
282
+ export function createAllowlistedEnv(tmpDir, blockedKeys = DEFAULT_BLOCKED_ENV_KEYS) {
283
+ const env = {};
284
+ for (const key of ['PATH', 'HOME', 'LANG', 'LC_ALL', 'TERM']) {
285
+ const value = process.env[key];
286
+ if (value && !blockedKeys.has(key))
287
+ env[key] = value;
288
+ }
289
+ env.TMPDIR = tmpDir;
290
+ env.TMP = tmpDir;
291
+ env.TEMP = tmpDir;
292
+ return env;
293
+ }
294
+ //# sourceMappingURL=sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/builder/sandbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ export interface WorkspaceFileEntry {
2
+ path: string;
3
+ bytes: number;
4
+ lines: number | null;
5
+ /** Present when entries come from workspace mounts. */
6
+ writable?: boolean;
7
+ }
8
+ export interface WorkspaceMount {
9
+ /**
10
+ * Virtual path prefix exposed to the model, e.g. "spec" or "artifact".
11
+ * Use "" only for a legacy single-root workspace.
12
+ */
13
+ prefix: string;
14
+ /** Absolute filesystem root backing this virtual prefix. */
15
+ root: string;
16
+ /** Defaults to true. Set false for spec/reference mounts. */
17
+ writable?: boolean;
18
+ /** Compact factual purpose of this mount, e.g. "implementation artifact". */
19
+ purpose?: string;
20
+ }
21
+ export interface ListWorkspaceFileEntriesOptions {
22
+ ignoreHidden?: boolean;
23
+ ignoreDirs?: readonly string[];
24
+ maxEntries?: number;
25
+ }
26
+ export interface RenderWorkspaceMountFileTreeOptions extends ListWorkspaceFileEntriesOptions {
27
+ /**
28
+ * Deprecated: mounted workspaces expose one canonical visible path per file.
29
+ * Kept only so older callers do not fail type-checks; rendering does not
30
+ * create a second "default" alias.
31
+ */
32
+ defaultMountPrefix?: string;
33
+ }
34
+ export interface RenderWorkspaceMountFileContentsOptions {
35
+ maxBytesPerFile?: number;
36
+ }
37
+ export declare function listWorkspaceFileEntries(workspaceRoot: string, options?: ListWorkspaceFileEntriesOptions): WorkspaceFileEntry[];
38
+ export declare function renderWorkspaceFileEntries(entries: readonly WorkspaceFileEntry[]): string[];
39
+ export declare function renderWorkspaceMountFileTree(mounts: readonly WorkspaceMount[], options?: RenderWorkspaceMountFileTreeOptions): string[];
40
+ export declare function renderWorkspaceMountFileContents(mounts: readonly WorkspaceMount[], visiblePaths: readonly string[], options?: RenderWorkspaceMountFileContentsOptions): string;
41
+ export interface ResolvedWorkspaceMountPath {
42
+ mount: WorkspaceMount;
43
+ /** Absolute path on disk. */
44
+ absolutePath: string;
45
+ /** Path relative to the selected mount root. */
46
+ relativePath: string;
47
+ /** Path as it should appear in prompts and action outcomes. */
48
+ visiblePath: string;
49
+ }
50
+ export declare function normalizeWorkspaceMounts(mounts: readonly WorkspaceMount[]): WorkspaceMount[];
51
+ export declare function listWorkspaceMountFileEntries(mounts: readonly WorkspaceMount[], options?: ListWorkspaceFileEntriesOptions): WorkspaceFileEntry[];
52
+ export declare function resolveWorkspaceMountPath(input: {
53
+ mounts: readonly WorkspaceMount[];
54
+ requestPath: string;
55
+ /**
56
+ * Deprecated. Mounted workspaces now use canonical visible paths only.
57
+ * A prefixed path such as artifact/index.html resolves to artifact; an
58
+ * unprefixed path resolves only when a mount with prefix "" exists.
59
+ */
60
+ defaultMountPrefix?: string;
61
+ }): ResolvedWorkspaceMountPath;
62
+ export declare function isWorkspaceMountPathWritable(resolved: ResolvedWorkspaceMountPath): boolean;
63
+ //# sourceMappingURL=workspace-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-files.d.ts","sourceRoot":"","sources":["../../src/builder/workspace-files.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAA;IACZ,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,+BAA+B;IAC9C,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,mCAAoC,SAAQ,+BAA+B;IAC1F;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,uCAAuC;IACtD,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,+BAAoC,GAC5C,kBAAkB,EAAE,CAoCtB;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,GAAG,MAAM,EAAE,CAS3F;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,SAAS,cAAc,EAAE,EACjC,OAAO,GAAE,mCAAwC,GAChD,MAAM,EAAE,CAsBV;AAED,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,SAAS,cAAc,EAAE,EACjC,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,OAAO,GAAE,uCAA4C,GACpD,MAAM,CA0CR;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,cAAc,CAAA;IACrB,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAA;IACpB,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAA;IACpB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,GAAG,cAAc,EAAE,CAa5F;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,SAAS,cAAc,EAAE,EACjC,OAAO,GAAE,+BAAoC,GAC5C,kBAAkB,EAAE,CAStB;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,MAAM,EAAE,SAAS,cAAc,EAAE,CAAA;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,GAAG,0BAA0B,CAyB7B;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,0BAA0B,GAAG,OAAO,CAE1F"}
@@ -0,0 +1,190 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ export function listWorkspaceFileEntries(workspaceRoot, options = {}) {
4
+ const ignoreHidden = options.ignoreHidden ?? true;
5
+ const ignoreDirs = new Set(options.ignoreDirs ?? ['node_modules', 'dist']);
6
+ const maxEntries = options.maxEntries ?? 500;
7
+ const entries = [];
8
+ const walk = (dir, prefix) => {
9
+ if (entries.length >= maxEntries)
10
+ return;
11
+ let items = [];
12
+ try {
13
+ items = fs.readdirSync(dir, { withFileTypes: true });
14
+ }
15
+ catch {
16
+ return;
17
+ }
18
+ items.sort((left, right) => left.name.localeCompare(right.name));
19
+ for (const item of items) {
20
+ if (entries.length >= maxEntries)
21
+ break;
22
+ if (ignoreHidden && item.name.startsWith('.'))
23
+ continue;
24
+ if (ignoreDirs.has(item.name))
25
+ continue;
26
+ const full = path.join(dir, item.name);
27
+ const relPath = prefix ? `${prefix}/${item.name}` : item.name;
28
+ if (item.isDirectory()) {
29
+ walk(full, relPath);
30
+ continue;
31
+ }
32
+ const stat = fs.statSync(full);
33
+ entries.push({
34
+ path: relPath,
35
+ bytes: stat.size,
36
+ lines: countTextLines(full),
37
+ });
38
+ }
39
+ };
40
+ walk(workspaceRoot, '');
41
+ return entries;
42
+ }
43
+ export function renderWorkspaceFileEntries(entries) {
44
+ if (entries.length === 0)
45
+ return ['(empty)'];
46
+ return entries.map(entry => {
47
+ const linePart = entry.lines == null ? 'binary/unknown lines' : `${entry.lines} lines`;
48
+ const accessPart = typeof entry.writable === 'boolean'
49
+ ? `, ${entry.writable ? 'writable' : 'read-only'}`
50
+ : '';
51
+ return `${entry.path} — ${linePart}, ${entry.bytes} bytes${accessPart}`;
52
+ });
53
+ }
54
+ export function renderWorkspaceMountFileTree(mounts, options = {}) {
55
+ const normalized = normalizeWorkspaceMounts(mounts);
56
+ if (normalized.length === 0)
57
+ return ['(empty)'];
58
+ const lines = [];
59
+ for (const mount of normalized) {
60
+ const entries = listWorkspaceFileEntries(mount.root, options);
61
+ const label = mount.prefix ? `${mount.prefix}/` : './';
62
+ const access = mount.writable === false ? 'read-only' : 'writable';
63
+ const purposeNote = mount.purpose?.trim() ? `, ${mount.purpose.trim()}` : '';
64
+ const emptyNote = entries.length === 0 ? ', empty' : '';
65
+ lines.push(`${label} — ${access}${purposeNote}${emptyNote}`);
66
+ if (entries.length > 0) {
67
+ const visibleEntries = entries.map(entry => ({
68
+ ...entry,
69
+ path: mount.prefix ? `${mount.prefix}/${entry.path}` : entry.path,
70
+ }));
71
+ lines.push(...renderWorkspaceFileEntries(visibleEntries).map(entry => ` ${entry}`));
72
+ }
73
+ }
74
+ return lines;
75
+ }
76
+ export function renderWorkspaceMountFileContents(mounts, visiblePaths, options = {}) {
77
+ const maxBytesPerFile = options.maxBytesPerFile ?? 8_000;
78
+ const sections = [];
79
+ for (const visiblePath of visiblePaths) {
80
+ let resolved;
81
+ try {
82
+ resolved = resolveWorkspaceMountPath({ mounts, requestPath: visiblePath });
83
+ }
84
+ catch {
85
+ continue;
86
+ }
87
+ let stat;
88
+ try {
89
+ stat = fs.statSync(resolved.absolutePath);
90
+ }
91
+ catch {
92
+ continue;
93
+ }
94
+ if (!stat.isFile())
95
+ continue;
96
+ const lines = countTextLines(resolved.absolutePath);
97
+ if (lines == null) {
98
+ sections.push(`## ${resolved.visiblePath}\n(binary file, ${stat.size} bytes; use readFile only if this file has a text representation)`);
99
+ continue;
100
+ }
101
+ if (stat.size > maxBytesPerFile) {
102
+ sections.push(`## ${resolved.visiblePath}\n${lines} lines, ${stat.size} bytes; content not inlined because it exceeds ${maxBytesPerFile} bytes. Use readFile if exact contents are needed.`);
103
+ continue;
104
+ }
105
+ const content = fs.readFileSync(resolved.absolutePath, 'utf8');
106
+ sections.push([
107
+ `## ${resolved.visiblePath}`,
108
+ `${lines} lines, ${stat.size} bytes`,
109
+ '```text',
110
+ content.replace(/\s+$/u, ''),
111
+ '```',
112
+ ].join('\n'));
113
+ }
114
+ return sections.join('\n\n');
115
+ }
116
+ export function normalizeWorkspaceMounts(mounts) {
117
+ const seen = new Set();
118
+ return mounts.map(mount => {
119
+ const prefix = normalizeMountPrefix(mount.prefix);
120
+ if (seen.has(prefix))
121
+ throw new Error(`Duplicate workspace mount prefix: ${prefix}`);
122
+ seen.add(prefix);
123
+ return {
124
+ ...mount,
125
+ prefix,
126
+ root: path.resolve(mount.root),
127
+ writable: mount.writable ?? true,
128
+ };
129
+ });
130
+ }
131
+ export function listWorkspaceMountFileEntries(mounts, options = {}) {
132
+ const normalized = normalizeWorkspaceMounts(mounts);
133
+ return normalized.flatMap(mount => listWorkspaceFileEntries(mount.root, options).map(entry => ({
134
+ ...entry,
135
+ path: mount.prefix ? `${mount.prefix}/${entry.path}` : entry.path,
136
+ writable: mount.writable !== false,
137
+ })));
138
+ }
139
+ export function resolveWorkspaceMountPath(input) {
140
+ const mounts = normalizeWorkspaceMounts(input.mounts);
141
+ if (mounts.length === 0)
142
+ throw new Error('No workspace mounts configured');
143
+ const requestPath = normalizeRequestPath(input.requestPath);
144
+ const explicitMount = mounts
145
+ .filter(mount => mount.prefix.length > 0)
146
+ .sort((left, right) => right.prefix.length - left.prefix.length)
147
+ .find(mount => requestPath === mount.prefix || requestPath.startsWith(`${mount.prefix}/`));
148
+ const rootMount = mounts.find(item => item.prefix.length === 0);
149
+ const mount = explicitMount ?? rootMount;
150
+ if (!mount) {
151
+ const visibleRoots = mounts.map(item => item.prefix ? `${item.prefix}/` : './').join(', ');
152
+ throw new Error(`Path "${requestPath}" is not a canonical visible workspace path. Use a visible path from FILES exactly as shown, including its mount prefix (${visibleRoots}).`);
153
+ }
154
+ const relativePath = explicitMount
155
+ ? requestPath.slice(explicitMount.prefix.length).replace(/^\/+/u, '')
156
+ : requestPath;
157
+ const absolutePath = resolveInsideRoot(mount.root, relativePath);
158
+ return {
159
+ mount,
160
+ absolutePath,
161
+ relativePath,
162
+ visiblePath: mount.prefix ? `${mount.prefix}/${relativePath}` : relativePath,
163
+ };
164
+ }
165
+ export function isWorkspaceMountPathWritable(resolved) {
166
+ return resolved.mount.writable !== false;
167
+ }
168
+ function normalizeMountPrefix(prefix) {
169
+ return prefix.replace(/^\/+|\/+$/gu, '');
170
+ }
171
+ function normalizeRequestPath(requestPath) {
172
+ const normalized = requestPath.replace(/^\.\/+/u, '').replace(/^\/+/u, '');
173
+ return normalized === '.' ? '' : normalized;
174
+ }
175
+ function resolveInsideRoot(root, relativePath) {
176
+ const resolved = path.resolve(root, relativePath);
177
+ const relative = path.relative(root, resolved);
178
+ if (relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative))) {
179
+ return resolved;
180
+ }
181
+ throw new Error(`Refusing to access outside workspace: ${relativePath}. Use a visible path from FILES, such as input/file.md or artifact/file.js; do not use ../ to cross mounts.`);
182
+ }
183
+ function countTextLines(filePath) {
184
+ const buffer = fs.readFileSync(filePath);
185
+ if (buffer.subarray(0, 512).includes(0))
186
+ return null;
187
+ const text = buffer.toString('utf8');
188
+ return text.length === 0 ? 0 : text.split(/\r?\n/u).length;
189
+ }
190
+ //# sourceMappingURL=workspace-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-files.js","sourceRoot":"","sources":["../../src/builder/workspace-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { ActionDefinition, PeerConsultation, PromptContractStyle, PromptMode } from '../types.js';
2
+ /**
3
+ * Build the actions rules section of the system prompt from action definitions.
4
+ * Each action's description IS a behavioral nudge (per playbook §4).
5
+ */
6
+ export declare function buildActionsBlock(actions: Record<string, ActionDefinition> | undefined, promptMode?: PromptMode, contractStyle?: PromptContractStyle): string;
7
+ /**
8
+ * Build an annotation string for a completed action (for history storage).
9
+ * Annotations are appended to stored messages so the AI doesn't re-process.
10
+ */
11
+ export declare function buildActionAnnotation(actionName: string, params: Record<string, unknown>): string;
12
+ /**
13
+ * Build a combined annotation string for multiple actions.
14
+ */
15
+ export declare function buildAnnotations(actions: Array<{
16
+ name: string;
17
+ params: Record<string, unknown>;
18
+ }>): string[];
19
+ /**
20
+ * Annotate a message with outcome notes and raw action annotations for storage.
21
+ *
22
+ * Two-layer annotation system:
23
+ * - `---outcomes:` — AI-written outcome notes, preserved in LLM history so the AI
24
+ * knows what it did on previous turns. Not shown to the user.
25
+ * - `---actions:` — Raw action data for debugging and UI pills. Stripped before
26
+ * the AI sees history (to prevent API format leakage into future turns).
27
+ *
28
+ * Ordering matters: outcomes BEFORE actions, so stripping ---actions: preserves outcomes.
29
+ */
30
+ export declare function annotateMessage(message: string, annotations: string[], outcomeNotes?: string[]): string;
31
+ /**
32
+ * Build annotation text for peer consultations that occurred mid-turn.
33
+ * Appended to the assistant message so the persona sees consultation context
34
+ * in its history on subsequent turns.
35
+ */
36
+ export declare function buildPeerAnnotation(consultations: PeerConsultation[]): string;
37
+ /**
38
+ * Strip all annotation markers from a message for user-facing display.
39
+ * Removes both `---outcomes:` and `---actions:` — the user sees neither.
40
+ * Use this when returning stored messages to the frontend.
41
+ */
42
+ export declare function stripAnnotationsForDisplay(content: string): string;
43
+ /**
44
+ * Strip `---actions:` suffixes from assistant messages in history.
45
+ * Preserves `---outcomes:` so the AI knows what it did on previous turns.
46
+ *
47
+ * The raw action data is stripped to prevent API format leakage — the AI
48
+ * must not learn action names or param schemas from historical messages.
49
+ * Outcome notes are safe because they're AI-written natural language.
50
+ */
51
+ export declare function stripActionAnnotations<T extends {
52
+ role: string;
53
+ content: string;
54
+ }>(history: T[]): T[];
55
+ //# sourceMappingURL=actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/core/actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAoB,gBAAgB,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AA6HxH;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,SAAS,EACrD,UAAU,GAAE,UAA2B,EACvC,aAAa,GAAE,mBAA4B,GAC1C,MAAM,CA8FR;AAcD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAMR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,GAChE,MAAM,EAAE,CAEV;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,MAAM,CASR;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAQ7E;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAWlE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAChF,OAAO,EAAE,CAAC,EAAE,GACX,CAAC,EAAE,CAOL"}