@voybio/ace-swarm 2.4.3 → 2.4.6

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 (144) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/README.md +72 -532
  3. package/assets/agent-state/INTERFACE_REGISTRY.md +2 -2
  4. package/assets/agent-state/MODULES/gates/gate-autonomy.json +4 -2
  5. package/assets/agent-state/MODULES/gates/gate-completeness.json +4 -2
  6. package/assets/agent-state/MODULES/gates/gate-operability.json +4 -2
  7. package/assets/agent-state/MODULES/gates/gate-security.json +3 -1
  8. package/assets/agent-state/MODULES/registry.json +1 -4
  9. package/assets/agent-state/MODULES/roles/capability-build.json +1 -2
  10. package/assets/agent-state/MODULES/roles/capability-eval.json +1 -1
  11. package/assets/agent-state/MODULES/roles/capability-qa.json +1 -2
  12. package/assets/agent-state/QUALITY_GATES.md +25 -9
  13. package/assets/agent-state/TEAL_CONFIG.md +2 -11
  14. package/assets/eval-battery/battery.json +85 -0
  15. package/assets/eval-battery/fixtures/edit-target.js +3 -0
  16. package/assets/scripts/render-mcp-configs.sh +12 -0
  17. package/dist/ace-context.d.ts +18 -0
  18. package/dist/ace-context.js +161 -16
  19. package/dist/ace-server-instructions.js +36 -9
  20. package/dist/astgrep-index.d.ts +7 -1
  21. package/dist/astgrep-index.js +66 -39
  22. package/dist/bridge-trace.d.ts +17 -0
  23. package/dist/bridge-trace.js +23 -0
  24. package/dist/cli.d.ts +9 -1
  25. package/dist/cli.js +619 -10
  26. package/dist/discovery-runtime-wrappers.d.ts +16 -1
  27. package/dist/discovery-runtime-wrappers.js +65 -9
  28. package/dist/eval-harness.d.ts +110 -0
  29. package/dist/eval-harness.js +254 -0
  30. package/dist/experience-reflector.d.ts +13 -0
  31. package/dist/experience-reflector.js +62 -0
  32. package/dist/gate-contract.d.ts +63 -0
  33. package/dist/gate-contract.js +178 -0
  34. package/dist/goal-engine.d.ts +155 -0
  35. package/dist/goal-engine.js +795 -0
  36. package/dist/helpers/store-resolution.js +40 -39
  37. package/dist/hermes/session-manager.d.ts +10 -0
  38. package/dist/hermes/session-manager.js +130 -27
  39. package/dist/job-scheduler.d.ts +58 -0
  40. package/dist/job-scheduler.js +202 -2
  41. package/dist/job-worker.d.ts +87 -0
  42. package/dist/job-worker.js +182 -0
  43. package/dist/local-model-policy.d.ts +8 -2
  44. package/dist/local-model-policy.js +31 -17
  45. package/dist/local-model-runtime.d.ts +6 -0
  46. package/dist/local-model-runtime.js +130 -2
  47. package/dist/measured-classing.d.ts +66 -0
  48. package/dist/measured-classing.js +165 -0
  49. package/dist/model-bridge.d.ts +45 -0
  50. package/dist/model-bridge.js +502 -44
  51. package/dist/orchestrator-supervisor.js +1 -1
  52. package/dist/plan-proposal.d.ts +7 -0
  53. package/dist/plan-proposal.js +74 -4
  54. package/dist/playbook-adaptation.d.ts +37 -0
  55. package/dist/playbook-adaptation.js +159 -0
  56. package/dist/playbook-curator.d.ts +16 -0
  57. package/dist/playbook-curator.js +106 -0
  58. package/dist/playbook-llm-reflector.d.ts +26 -0
  59. package/dist/playbook-llm-reflector.js +157 -0
  60. package/dist/public-surface.d.ts +2 -0
  61. package/dist/public-surface.js +26 -14
  62. package/dist/runtime-executor.js +45 -2
  63. package/dist/runtime-tool-specs.d.ts +8 -1
  64. package/dist/runtime-tool-specs.js +19 -1
  65. package/dist/safe-edit.d.ts +20 -0
  66. package/dist/safe-edit.js +355 -78
  67. package/dist/schemas.js +16 -15
  68. package/dist/server.d.ts +11 -2
  69. package/dist/server.js +55 -5
  70. package/dist/shared.d.ts +12 -0
  71. package/dist/shared.js +13 -1
  72. package/dist/source-mutation-coordinator.d.ts +54 -0
  73. package/dist/source-mutation-coordinator.js +259 -0
  74. package/dist/status-events.d.ts +4 -1
  75. package/dist/status-events.js +41 -6
  76. package/dist/store/ace-packed-store.d.ts +28 -9
  77. package/dist/store/ace-packed-store.js +324 -57
  78. package/dist/store/bgzf.d.ts +4 -0
  79. package/dist/store/bgzf.js +94 -0
  80. package/dist/store/bootstrap-store.d.ts +4 -1
  81. package/dist/store/bootstrap-store.js +87 -9
  82. package/dist/store/cache-workspace.d.ts +8 -0
  83. package/dist/store/cache-workspace.js +67 -1
  84. package/dist/store/crc32.d.ts +2 -0
  85. package/dist/store/crc32.js +16 -0
  86. package/dist/store/fsck.d.ts +16 -0
  87. package/dist/store/fsck.js +240 -0
  88. package/dist/store/gate-contract-migration.d.ts +10 -0
  89. package/dist/store/gate-contract-migration.js +413 -0
  90. package/dist/store/materializers/context-snapshot-materializer.d.ts +1 -0
  91. package/dist/store/materializers/context-snapshot-materializer.js +4 -1
  92. package/dist/store/materializers/projection-manager.d.ts +7 -0
  93. package/dist/store/materializers/projection-manager.js +37 -0
  94. package/dist/store/materializers/scheduler-projection-materializer.js +10 -3
  95. package/dist/store/repositories/goal-repository.d.ts +112 -0
  96. package/dist/store/repositories/goal-repository.js +157 -0
  97. package/dist/store/repositories/playbook-repository.d.ts +107 -0
  98. package/dist/store/repositories/playbook-repository.js +314 -0
  99. package/dist/store/store-artifacts.js +44 -2
  100. package/dist/store/store-authority-audit.js +1 -0
  101. package/dist/store/store-cli.d.ts +30 -0
  102. package/dist/store/store-cli.js +242 -0
  103. package/dist/store/store-snapshot.d.ts +12 -0
  104. package/dist/store/store-snapshot.js +74 -11
  105. package/dist/store/types.d.ts +1 -0
  106. package/dist/store/write-coordinator.d.ts +7 -0
  107. package/dist/store/write-coordinator.js +11 -0
  108. package/dist/todo-state.d.ts +21 -0
  109. package/dist/todo-state.js +150 -53
  110. package/dist/tools-agent.js +86 -22
  111. package/dist/tools-discovery.js +5 -3
  112. package/dist/tools-files.js +107 -23
  113. package/dist/tools-framework.js +146 -40
  114. package/dist/tools-goal.d.ts +11 -0
  115. package/dist/tools-goal.js +108 -0
  116. package/dist/tools-handoff.js +7 -11
  117. package/dist/tools-lifecycle.js +2 -0
  118. package/dist/tools-scheduler.js +44 -1
  119. package/dist/tools-skills.js +3 -2
  120. package/dist/tools-todo.js +64 -3
  121. package/dist/tools.js +2 -0
  122. package/dist/tui/chat.js +4 -0
  123. package/dist/tui/index.js +4 -1
  124. package/dist/tui/ollama.d.ts +2 -0
  125. package/dist/tui/openai-compatible.d.ts +14 -0
  126. package/dist/tui/openai-compatible.js +15 -2
  127. package/dist/tui/provider-discovery.d.ts +1 -0
  128. package/dist/tui/provider-discovery.js +2 -2
  129. package/docs/cli-reference.md +125 -0
  130. package/docs/development.md +46 -0
  131. package/docs/evaluation-safety.md +27 -0
  132. package/docs/experience-playbook.md +35 -0
  133. package/docs/hermes.md +129 -0
  134. package/docs/library-api.md +31 -0
  135. package/docs/mcp-tool-reference.md +290 -0
  136. package/docs/provider-security.md +85 -0
  137. package/docs/state-model.md +113 -0
  138. package/docs/troubleshooting.md +95 -0
  139. package/docs/tui-operator-guide.md +75 -0
  140. package/package.json +5 -1
  141. package/scripts/dev/run_hermes_crispr_live.mjs +212 -0
  142. package/assets/agent-state/MODULES/gates/gate-correctness.json +0 -7
  143. package/assets/agent-state/MODULES/gates/gate-evaluation.json +0 -7
  144. package/assets/agent-state/MODULES/gates/gate-typescript-public-surface.json +0 -7
@@ -57,6 +57,8 @@ const MUTATION_PREFIXES = [
57
57
  "update_",
58
58
  "write_",
59
59
  ];
60
+ const DIGEST_CACHE_TTL_MS = 60_000;
61
+ const digestCache = new Map();
60
62
  function readIfPresent(filePath) {
61
63
  if (!existsSync(filePath))
62
64
  return undefined;
@@ -188,6 +190,15 @@ export function buildAceDigest(workspaceRoot) {
188
190
  ].filter((value) => Boolean(value));
189
191
  return parts.length > 0 ? parts.join(" | ") : "ACE state detected; load recall_context for task and status.";
190
192
  }
193
+ function buildAceDigestCached(workspaceRoot) {
194
+ const now = Date.now();
195
+ const cached = digestCache.get(workspaceRoot);
196
+ if (cached && cached.expiresAt > now)
197
+ return cached.value;
198
+ const value = buildAceDigest(workspaceRoot);
199
+ digestCache.set(workspaceRoot, { value, expiresAt: now + DIGEST_CACHE_TTL_MS });
200
+ return value;
201
+ }
191
202
  export function buildServerInstructions(workspaceRoot) {
192
203
  const coreFiles = listExistingCoreFiles(workspaceRoot);
193
204
  const stateDirs = listExistingStateDirs(workspaceRoot);
@@ -224,13 +235,14 @@ export function buildHostInstructionText(host, workspaceRoot) {
224
235
  "Full instructions, skills, task packs, and runtime state live in ACE artifacts and should be accessed through the ACE MCP server.",
225
236
  "",
226
237
  "Session start protocol:",
227
- "1. Call `recall_context` to load task, scope, and status from ACE state.",
238
+ "1. Call `recall_context` to load task, scope, and status through the ACE MCP server.",
228
239
  "2. Call `route_task` and `get_agent_instructions` before choosing a role.",
229
240
  "3. Prefer ACE prompts/resources (`ace-orchestrator`, `get_task_pack`, `get_skill_instructions`) over relying on this file.",
241
+ "4. Read/write task state through MCP tools (`recall_context`, `read_workspace_file`, `write_workspace_file`, lifecycle append tools); do not create files under `agent-state/` directly.",
230
242
  "",
231
243
  "Ground truth:",
232
- "- `agent-state/*` is the visible runtime state surface for this workspace.",
233
- "- `agent-state/ace-state.ace` is the canonical store path; legacy nested store layouts are compatibility fallback only.",
244
+ "- ACE MCP tools are the authoritative interface for task state and lifecycle updates.",
245
+ "- `agent-state/ace-state.ace` is the canonical store path; visible `agent-state/*` files are compatibility projections or sweep inputs.",
234
246
  "- `.agents/ACE/tasks/todo.md` is the human-facing todo surface.",
235
247
  "- Hook context is store-backed in `agent-state/ace-state.ace` and consumed without extra workspace projections.",
236
248
  "",
@@ -241,26 +253,26 @@ export function buildBootstrapNudge(workspaceRoot) {
241
253
  const coreFiles = listExistingCoreFiles(workspaceRoot);
242
254
  return [
243
255
  "ACE bootstrap hint: call `recall_context` before significant work so task and scope come from file-backed state.",
244
- `ACE digest: ${buildAceDigest(workspaceRoot)}.`,
256
+ `ACE digest: ${buildAceDigestCached(workspaceRoot)}.`,
245
257
  coreFiles.length > 0 ? `Current core files: ${coreFiles.join(", ")}.` : undefined,
246
258
  ]
247
259
  .filter((value) => Boolean(value))
248
260
  .join(" ");
249
261
  }
250
262
  export function buildBootstrapGuidance(workspaceRoot, toolName) {
251
- return `ACE context loaded via \`${toolName}\`. Current digest: ${buildAceDigest(workspaceRoot)}.`;
263
+ return `ACE context loaded via \`${toolName}\`. Current digest: ${buildAceDigestCached(workspaceRoot)}.`;
252
264
  }
253
265
  export function buildMutationGuidance(workspaceRoot, toolName) {
254
266
  const evidencePath = displayWorkspacePath(workspaceRoot, "agent-state/EVIDENCE_LOG.md");
255
267
  return [
256
- `ACE digest after \`${toolName}\`: ${buildAceDigest(workspaceRoot)}.`,
268
+ `ACE digest after \`${toolName}\`: ${buildAceDigestCached(workspaceRoot)}.`,
257
269
  `If this changed code or state, reconcile \`${evidencePath}\`, run \`execute_gates\` when appropriate, and use structured handoffs/process posts for delegated follow-up.`,
258
270
  ].join(" ");
259
271
  }
260
272
  export function buildRefreshGuidance(workspaceRoot, toolName) {
261
273
  return [
262
274
  `ACE snapshot refresh completed via \`${toolName}\`.`,
263
- `Current digest: ${buildAceDigest(workspaceRoot)}.`,
275
+ `Current digest: ${buildAceDigestCached(workspaceRoot)}.`,
264
276
  ].join(" ");
265
277
  }
266
278
  function isBootstrapTool(toolName) {
@@ -298,6 +310,8 @@ function isCallToolResult(value) {
298
310
  }
299
311
  export function installAceToolGovernance(server, workspaceRoot) {
300
312
  const bootstrappedSessions = new Set();
313
+ const bootstrapNudgeCounts = new Map();
314
+ const mutationGuidanceState = new Map();
301
315
  const wrapToolCallback = (toolName, callback) => async (...args) => {
302
316
  const extra = args.at(-1);
303
317
  const sessionId = typeof extra?.sessionId === "string" ? extra.sessionId : undefined;
@@ -311,7 +325,11 @@ export function installAceToolGovernance(server, workspaceRoot) {
311
325
  }
312
326
  let next = rawResult;
313
327
  if (sessionId && !bootstrappedSessions.has(sessionId) && !isBootstrapTool(toolName)) {
314
- next = appendTextContent(next, buildBootstrapNudge(workspaceRoot));
328
+ const callCount = (bootstrapNudgeCounts.get(sessionId) ?? 0) + 1;
329
+ bootstrapNudgeCounts.set(sessionId, callCount);
330
+ if (callCount === 1 || callCount % 10 === 0) {
331
+ next = appendTextContent(next, buildBootstrapNudge(workspaceRoot));
332
+ }
315
333
  }
316
334
  if (isBootstrapTool(toolName)) {
317
335
  next = appendTextContent(next, buildBootstrapGuidance(workspaceRoot, toolName));
@@ -320,7 +338,16 @@ export function installAceToolGovernance(server, workspaceRoot) {
320
338
  next = appendTextContent(next, buildRefreshGuidance(workspaceRoot, toolName));
321
339
  }
322
340
  else if (isMutationTool(toolName)) {
323
- next = appendTextContent(next, buildMutationGuidance(workspaceRoot, toolName));
341
+ const mutationKey = sessionId ?? "__global__";
342
+ const currentDigest = buildAceDigestCached(workspaceRoot);
343
+ const state = mutationGuidanceState.get(mutationKey) ?? { count: 0 };
344
+ state.count += 1;
345
+ const shouldAppend = state.lastDigest === undefined || state.lastDigest !== currentDigest || state.count % 10 === 0;
346
+ state.lastDigest = currentDigest;
347
+ mutationGuidanceState.set(mutationKey, state);
348
+ if (shouldAppend) {
349
+ next = appendTextContent(next, buildMutationGuidance(workspaceRoot, toolName));
350
+ }
324
351
  }
325
352
  return next;
326
353
  };
@@ -10,11 +10,17 @@ interface AstGrepMatch {
10
10
  line?: number;
11
11
  column?: number;
12
12
  };
13
+ byteOffset?: {
14
+ start?: number;
15
+ end?: number;
16
+ };
13
17
  };
14
- metaVariables?: Record<string, unknown>;
18
+ metaVariables?: unknown;
15
19
  kind?: string;
16
20
  nodeKind?: string;
21
+ replacement?: string;
17
22
  }
23
+ export declare function flattenMetaVariables(raw: unknown): Record<string, string>;
18
24
  export interface AstgrepMatch {
19
25
  file: string;
20
26
  line: number;
@@ -4,6 +4,57 @@ import { isAbsolute, relative, resolve } from "node:path";
4
4
  import { spawnSync } from "node:child_process";
5
5
  import { appendStatusEventSafe } from "./status-events.js";
6
6
  import { safeRead, safeWrite, WORKSPACE_ROOT, wsPath } from "./helpers.js";
7
+ function textFromMetaValue(value) {
8
+ if (typeof value === "string")
9
+ return value;
10
+ if (value && typeof value === "object") {
11
+ const text = value.text;
12
+ if (typeof text === "string")
13
+ return text;
14
+ }
15
+ return undefined;
16
+ }
17
+ const META_SINGLE_BUCKETS = ["single", "transformed"];
18
+ const META_MULTI_BUCKETS = ["multi"];
19
+ export function flattenMetaVariables(raw) {
20
+ const out = {};
21
+ if (!raw || typeof raw !== "object")
22
+ return out;
23
+ const root = raw;
24
+ for (const bucketKey of META_SINGLE_BUCKETS) {
25
+ const bucket = root[bucketKey];
26
+ if (bucket && typeof bucket === "object") {
27
+ for (const [name, value] of Object.entries(bucket)) {
28
+ const text = textFromMetaValue(value);
29
+ if (typeof text === "string" && text.length > 0)
30
+ out[name] = text;
31
+ }
32
+ }
33
+ }
34
+ for (const bucketKey of META_MULTI_BUCKETS) {
35
+ const bucket = root[bucketKey];
36
+ if (bucket && typeof bucket === "object") {
37
+ for (const [name, value] of Object.entries(bucket)) {
38
+ if (!Array.isArray(value))
39
+ continue;
40
+ const texts = value
41
+ .map(textFromMetaValue)
42
+ .filter((text) => typeof text === "string" && text.length > 0);
43
+ if (texts.length > 0)
44
+ out[name] = texts.join("");
45
+ }
46
+ }
47
+ }
48
+ const reserved = new Set([...META_SINGLE_BUCKETS, ...META_MULTI_BUCKETS]);
49
+ for (const [name, value] of Object.entries(root)) {
50
+ if (reserved.has(name) || out[name] !== undefined)
51
+ continue;
52
+ const text = textFromMetaValue(value);
53
+ if (typeof text === "string" && text.length > 0)
54
+ out[name] = text;
55
+ }
56
+ return out;
57
+ }
7
58
  export function runAstgrepQuery(pattern, lang, roots, _contextLines) {
8
59
  const cmd = detectAstgrepCommand();
9
60
  const raw = runAstgrep(cmd, pattern, lang, roots);
@@ -32,15 +83,8 @@ function nodeKindForMatch(match) {
32
83
  return undefined;
33
84
  }
34
85
  function captureMapForMatch(match) {
35
- if (!match.metaVariables)
36
- return undefined;
37
- const captures = Object.entries(match.metaVariables).reduce((acc, [key]) => {
38
- const text = extractMetaVarText(match, key);
39
- if (typeof text === "string" && text.length > 0)
40
- acc[key] = text;
41
- return acc;
42
- }, {});
43
- return Object.keys(captures).length > 0 ? captures : undefined;
86
+ const flat = flattenMetaVariables(match.metaVariables);
87
+ return Object.keys(flat).length > 0 ? flat : undefined;
44
88
  }
45
89
  function computeMatchId(input) {
46
90
  const encoded = [
@@ -59,12 +103,8 @@ function computeMatchId(input) {
59
103
  function matchUsesSymbolHint(match, symbolHint) {
60
104
  if ((match.text ?? "").includes(symbolHint))
61
105
  return true;
62
- if (!match.metaVariables)
63
- return false;
64
- return Object.keys(match.metaVariables).some((key) => {
65
- const text = extractMetaVarText(match, key);
66
- return typeof text === "string" && text.includes(symbolHint);
67
- });
106
+ const flat = flattenMetaVariables(match.metaVariables);
107
+ return Object.values(flat).some((text) => text.includes(symbolHint));
68
108
  }
69
109
  export function locateAstgrepMatches(input) {
70
110
  const scope = resolveScope(input.scope ?? "src");
@@ -109,6 +149,14 @@ export function locateAstgrepMatches(input) {
109
149
  line: match.range.end?.line ?? 0,
110
150
  column: match.range.end?.column ?? 0,
111
151
  },
152
+ ...(match.range.byteOffset
153
+ ? {
154
+ byteOffset: {
155
+ start: match.range.byteOffset.start ?? 0,
156
+ end: match.range.byteOffset.end ?? 0,
157
+ },
158
+ }
159
+ : {}),
112
160
  };
113
161
  return [{
114
162
  match_id: computeMatchId({
@@ -270,27 +318,6 @@ function runAstgrep(astgrepCmd, pattern, lang, paths) {
270
318
  return [];
271
319
  return parseAstgrepOutput(res.stdout);
272
320
  }
273
- function extractMetaVarText(match, key) {
274
- const raw = match.metaVariables?.[key];
275
- if (!raw)
276
- return undefined;
277
- if (typeof raw === "string")
278
- return raw;
279
- if (raw && typeof raw === "object" && "text" in raw && typeof raw.text === "string") {
280
- return raw.text;
281
- }
282
- if (Array.isArray(raw)) {
283
- const first = raw[0];
284
- if (typeof first === "string")
285
- return first;
286
- if (first && typeof first === "object" && "text" in first) {
287
- const text = first.text;
288
- if (typeof text === "string")
289
- return text;
290
- }
291
- }
292
- return undefined;
293
- }
294
321
  function uniqueSorted(values, limit) {
295
322
  return [...new Set(values.filter(Boolean))].sort((a, b) => a.localeCompare(b)).slice(0, limit);
296
323
  }
@@ -357,13 +384,13 @@ export async function refreshAstgrepIndex(input = {}) {
357
384
  const pyTestMatches = runAstgrep(astgrepCmd, "def test_$NAME($$$ARGS):", "python", pyRoots);
358
385
  const handoffRefMatches = runAstgrep(astgrepCmd, '$X(\"SWARM_HANDOFF.$Y\")', "ts", tsRoots);
359
386
  const exportedFunctions = uniqueSorted(exportedFnMatches
360
- .map((m) => extractMetaVarText(m, "NAME"))
387
+ .map((m) => flattenMetaVariables(m.metaVariables).NAME)
361
388
  .filter((v) => Boolean(v)), 40);
362
389
  const exportedClasses = uniqueSorted(exportedClassMatches
363
- .map((m) => extractMetaVarText(m, "NAME"))
390
+ .map((m) => flattenMetaVariables(m.metaVariables).NAME)
364
391
  .filter((v) => Boolean(v)), 30);
365
392
  const asyncFunctions = uniqueSorted(asyncFnMatches
366
- .map((m) => extractMetaVarText(m, "NAME"))
393
+ .map((m) => flattenMetaVariables(m.metaVariables).NAME)
367
394
  .filter((v) => Boolean(v)), 40);
368
395
  // Fallback symbol extraction when AST match shapes differ across language versions.
369
396
  const tsFiles = codeFiles.filter((file) => /\.(ts|tsx|js)$/i.test(file));
@@ -0,0 +1,17 @@
1
+ import type { BridgeUsageTotals } from "./model-bridge.js";
2
+ export interface BridgeTraceLine {
3
+ turn: number;
4
+ envelope_status: string;
5
+ parse_repairs: number;
6
+ drift_repairs: number;
7
+ tool_calls: Array<{
8
+ tool: string;
9
+ ok: boolean;
10
+ reason_code?: string;
11
+ }>;
12
+ usage?: BridgeUsageTotals;
13
+ compressed?: boolean;
14
+ }
15
+ export declare function bridgeTracePath(workspaceRoot: string, runId: string): string;
16
+ export declare function readBridgeTrace(workspaceRoot: string, runId: string): BridgeTraceLine[];
17
+ //# sourceMappingURL=bridge-trace.d.ts.map
@@ -0,0 +1,23 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ export function bridgeTracePath(workspaceRoot, runId) {
4
+ const safeRunId = runId.replace(/[^a-zA-Z0-9_.-]/g, "_");
5
+ return resolve(workspaceRoot, "agent-state", "bridge-traces", `${safeRunId}.ndjson`);
6
+ }
7
+ export function readBridgeTrace(workspaceRoot, runId) {
8
+ const path = bridgeTracePath(workspaceRoot, runId);
9
+ if (!existsSync(path))
10
+ return [];
11
+ return readFileSync(path, "utf8")
12
+ .split(/\r?\n/)
13
+ .filter(Boolean)
14
+ .flatMap((line) => {
15
+ try {
16
+ return [JSON.parse(line)];
17
+ }
18
+ catch {
19
+ return [];
20
+ }
21
+ });
22
+ }
23
+ //# sourceMappingURL=bridge-trace.js.map
package/dist/cli.d.ts CHANGED
@@ -1,3 +1,11 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ /**
3
+ * Positional arguments, with value-taking flags and their values removed.
4
+ * A bare `.filter(a => !a.startsWith("--"))` drops the flag but keeps its value,
5
+ * which silently folds `--budget-hours 2` into a goal objective. Supports both
6
+ * `--flag value` and `--flag=value`, plus `--` as an end-of-flags separator.
7
+ */
8
+ export declare function positionalArgs(args: readonly string[], valueFlags: ReadonlySet<string>): string[];
9
+ export declare const GOAL_VALUE_FLAGS: ReadonlySet<string>;
10
+ export declare const PLAYBOOK_ADD_VALUE_FLAGS: ReadonlySet<string>;
3
11
  //# sourceMappingURL=cli.d.ts.map