agent-dealer 1.2.6 → 1.2.8

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 (96) hide show
  1. package/bundle/server/dist/adapters/agent-deck-bind.js +16 -6
  2. package/bundle/server/dist/adapters/agent-deck-bind.test.js +74 -0
  3. package/bundle/server/dist/adapters/agent-health.js +14 -3
  4. package/bundle/server/dist/adapters/github.js +4 -1
  5. package/bundle/server/dist/adapters/muse-capability.js +443 -24
  6. package/bundle/server/dist/adapters/muse-capability.test.js +469 -25
  7. package/bundle/server/dist/adapters/muse-visual-qa.js +114 -0
  8. package/bundle/server/dist/adapters/muse-visual-qa.test.js +68 -0
  9. package/bundle/server/dist/capacity/muse-probe.js +56 -9
  10. package/bundle/server/dist/capacity/muse-probe.test.js +188 -1
  11. package/bundle/server/dist/coordinator/admission.js +14 -1
  12. package/bundle/server/dist/coordinator/admission.test.js +197 -4
  13. package/bundle/server/dist/coordinator/auto-merge.integration.test.js +276 -0
  14. package/bundle/server/dist/coordinator/auto-merge.js +39 -3
  15. package/bundle/server/dist/coordinator/commands.js +90 -5
  16. package/bundle/server/dist/coordinator/deck-outage.integration.test.js +4 -2
  17. package/bundle/server/dist/coordinator/developer-effect.js +79 -1
  18. package/bundle/server/dist/coordinator/execution-report.js +6 -0
  19. package/bundle/server/dist/coordinator/execution-report.test.js +7 -0
  20. package/bundle/server/dist/coordinator/failure-cause.js +64 -1
  21. package/bundle/server/dist/coordinator/failure-cause.test.js +92 -1
  22. package/bundle/server/dist/coordinator/failure-reason.js +7 -0
  23. package/bundle/server/dist/coordinator/failure-reason.test.js +14 -0
  24. package/bundle/server/dist/coordinator/human-resolution.js +17 -1
  25. package/bundle/server/dist/coordinator/merge-conflict-sync.js +647 -0
  26. package/bundle/server/dist/coordinator/merge-conflict-sync.test.js +121 -0
  27. package/bundle/server/dist/coordinator/muse-developer.integration.test.js +9 -4
  28. package/bundle/server/dist/coordinator/muse-spawn.js +122 -29
  29. package/bundle/server/dist/coordinator/muse-spawn.test.js +210 -0
  30. package/bundle/server/dist/coordinator/playbook-feedback.js +690 -0
  31. package/bundle/server/dist/coordinator/playbook-feedback.test.js +702 -0
  32. package/bundle/server/dist/coordinator/prompts-execution-contract.test.js +107 -0
  33. package/bundle/server/dist/coordinator/prompts.js +78 -2
  34. package/bundle/server/dist/coordinator/prompts.test.js +83 -0
  35. package/bundle/server/dist/coordinator/reflect-trigger.js +33 -169
  36. package/bundle/server/dist/coordinator/reflect-trigger.test.js +149 -200
  37. package/bundle/server/dist/coordinator/reviewer-effect.js +10 -1
  38. package/bundle/server/dist/coordinator/reviewer-result.js +6 -0
  39. package/bundle/server/dist/coordinator/routing.test.js +14 -0
  40. package/bundle/server/dist/coordinator/session-timeouts.js +30 -0
  41. package/bundle/server/dist/coordinator/usage-cap.integration.test.js +1 -1
  42. package/bundle/server/dist/coordinator/worker-loop.js +18 -4
  43. package/bundle/server/dist/db/index.js +5 -0
  44. package/bundle/server/dist/db/schema.sql +3 -0
  45. package/bundle/server/dist/docs-execution-analysis.test.js +1 -0
  46. package/bundle/server/dist/repository/artifacts-for-issue.js +3 -3
  47. package/bundle/server/dist/repository/human-actions.js +14 -0
  48. package/bundle/server/dist/repository/issues.js +29 -4
  49. package/bundle/server/dist/repository/worker-sessions.js +51 -2
  50. package/bundle/server/dist/routes/human-actions.js +10 -8
  51. package/bundle/server/dist/routes/issues-execution-contract.test.js +321 -0
  52. package/bundle/server/dist/routes/issues.js +19 -2
  53. package/bundle/server/dist/runners/muse-code-jsonl.js +106 -11
  54. package/bundle/server/dist/runners/muse-config-core.js +18 -1
  55. package/bundle/server/dist/runners/muse-config.test.js +37 -0
  56. package/bundle/server/dist/runners/muse-serve-session.js +5 -0
  57. package/bundle/server/dist/runners/spawn-cli.js +116 -0
  58. package/bundle/server/dist/runners/spawn-cli.test.js +124 -0
  59. package/bundle/server/package.json +2 -2
  60. package/bundle/server/static-ui/assets/index-B6SVCzMR.js +64 -0
  61. package/bundle/server/static-ui/assets/index-K_YcYkQU.css +1 -0
  62. package/bundle/server/static-ui/index.html +2 -2
  63. package/bundle/shared/dist/action-presentation.d.ts +51 -0
  64. package/bundle/shared/dist/action-presentation.js +280 -0
  65. package/bundle/shared/dist/action-presentation.test.d.ts +1 -0
  66. package/bundle/shared/dist/action-presentation.test.js +180 -0
  67. package/bundle/shared/dist/attempt-waste.d.ts +2 -2
  68. package/bundle/shared/dist/execution-analysis.d.ts +22 -22
  69. package/bundle/shared/dist/execution-contract.d.ts +117 -0
  70. package/bundle/shared/dist/execution-contract.js +307 -0
  71. package/bundle/shared/dist/execution-contract.test.d.ts +2 -0
  72. package/bundle/shared/dist/execution-contract.test.js +499 -0
  73. package/bundle/shared/dist/execution-report.d.ts +11 -11
  74. package/bundle/shared/dist/execution-report.js +2 -0
  75. package/bundle/shared/dist/failure-cause.d.ts +4 -4
  76. package/bundle/shared/dist/failure-cause.js +2 -0
  77. package/bundle/shared/dist/human-actions.d.ts +14 -14
  78. package/bundle/shared/dist/human-actions.js +9 -0
  79. package/bundle/shared/dist/index.d.ts +126 -124
  80. package/bundle/shared/dist/index.js +4 -0
  81. package/bundle/shared/dist/issues.d.ts +158 -28
  82. package/bundle/shared/dist/issues.js +8 -0
  83. package/bundle/shared/dist/issues.test.js +1 -0
  84. package/bundle/shared/dist/outbound-draft.d.ts +18 -18
  85. package/bundle/shared/dist/profile-snapshot.d.ts +2 -2
  86. package/bundle/shared/dist/usage-events.d.ts +2 -2
  87. package/bundle/shared/dist/worker-sessions.d.ts +16 -6
  88. package/bundle/shared/dist/worker-sessions.js +8 -0
  89. package/bundle/shared/dist/worker-sessions.test.js +1 -0
  90. package/bundle/shared/dist/workflow.d.ts +6 -6
  91. package/bundle/shared/dist/workflow.js +10 -0
  92. package/bundle/shared/dist/workflow.test.js +2 -0
  93. package/bundle/shared/package.json +1 -1
  94. package/package.json +1 -1
  95. package/bundle/server/static-ui/assets/index-BII-LgB8.css +0 -1
  96. package/bundle/server/static-ui/assets/index-CoDzZcsz.js +0 -60
@@ -153,20 +153,29 @@ function readAmbientCodexAuthPolicy(ambientCodexHome) {
153
153
  return {};
154
154
  }
155
155
  }
156
- function deckLaunchHeaders(deckId, worktreePath) {
157
- return {
156
+ /**
157
+ * NOT-305: header carrying the session's opaque Deck correlation UUID. Observability
158
+ * metadata only — Deck uses it to attribute its normalized playbook-fetch stream back
159
+ * to this durable Dealer session; it grants no authority.
160
+ */
161
+ export const DECK_CORRELATION_HEADER = "x-agent-deck-correlation-id";
162
+ function deckLaunchHeaders(deckId, worktreePath, correlationId) {
163
+ const headers = {
158
164
  "x-agent-deck-deck-id": deckId,
159
165
  "x-agent-deck-workspace": worktreePath,
160
166
  };
167
+ if (correlationId)
168
+ headers[DECK_CORRELATION_HEADER] = correlationId;
169
+ return headers;
161
170
  }
162
171
  /** claude's `--mcp-config` file schema — deck headers only, no Authorization. */
163
- function urlHeaderMcpConfig(mcpUrl, deckId, worktreePath) {
172
+ function urlHeaderMcpConfig(mcpUrl, deckId, worktreePath, correlationId) {
164
173
  return {
165
174
  mcpServers: {
166
175
  "agent-deck": {
167
176
  type: "http",
168
177
  url: mcpUrl,
169
- headers: deckLaunchHeaders(deckId, worktreePath),
178
+ headers: deckLaunchHeaders(deckId, worktreePath, correlationId),
170
179
  },
171
180
  },
172
181
  };
@@ -202,7 +211,7 @@ function ensureCursorMcpExcluded(worktreePath) {
202
211
  async function materializeWorkerMcpConfig(opts) {
203
212
  const mcpBase = getAgentDeckMcpUrl().replace(/\/mcp\/?$/, "");
204
213
  const mcpUrl = `${mcpBase}/mcp`;
205
- const headers = deckLaunchHeaders(opts.deckId, opts.worktreePath);
214
+ const headers = deckLaunchHeaders(opts.deckId, opts.worktreePath, opts.correlationId);
206
215
  // NOT-278: Muse Code settings come only from `prepareMuseAttempt`
207
216
  // (runners/muse-config.ts) — never emit a Claude/Codex/Cursor config for Muse. Refuse
208
217
  // before anything is written rather than fall through to the Claude config below.
@@ -257,7 +266,7 @@ async function materializeWorkerMcpConfig(opts) {
257
266
  const dir = getWorkerMcpConfigDir();
258
267
  const filePath = path.join(dir, `claude-mcp-${opts.deckId.slice(0, 8)}-${randomUUID()}.json`);
259
268
  try {
260
- fs.writeFileSync(filePath, JSON.stringify(urlHeaderMcpConfig(mcpUrl, opts.deckId, opts.worktreePath)), { mode: 0o600 });
269
+ fs.writeFileSync(filePath, JSON.stringify(urlHeaderMcpConfig(mcpUrl, opts.deckId, opts.worktreePath, opts.correlationId)), { mode: 0o600 });
261
270
  }
262
271
  catch (err) {
263
272
  fs.rmSync(filePath, { force: true });
@@ -416,6 +425,7 @@ export async function prepareWorkerDeckConnection(opts) {
416
425
  deckId: opts.deckId,
417
426
  worktreePath: opts.worktreePath,
418
427
  policy: opts.policy,
428
+ correlationId: opts.correlationId,
419
429
  });
420
430
  }
421
431
  catch (err) {
@@ -528,3 +528,77 @@ test("a deck that loses the connection mid-playbook is deck_unavailable", async
528
528
  if (!result.ok)
529
529
  assert.equal(result.kind, "deck_unavailable");
530
530
  });
531
+ // NOT-305: every new worker session persists an opaque Deck correlation UUID before
532
+ // spawn, and every runtime launch config carries it as the exact
533
+ // `x-agent-deck-correlation-id` observability header (never authority).
534
+ const CORRELATION_ID = "aaaaaaaa-1111-4111-a111-aaaaaaaaaaaa";
535
+ test("prepareWorkerDeckConnection writes the exact correlation header for claude_code", async () => {
536
+ const result = await prepareWorkerDeckConnection({
537
+ policy: DENIED,
538
+ ...BASE_OPTS,
539
+ correlationId: CORRELATION_ID,
540
+ verifyCallTool: async (name) => {
541
+ assert.equal(name, "get_bound_deck");
542
+ return textResult({ id: DECK, name: "personal-dev" });
543
+ },
544
+ });
545
+ assert.equal(result.ok, true);
546
+ if (result.ok) {
547
+ const written = JSON.parse(fs.readFileSync(result.mcpConfigPath, "utf8"));
548
+ const headers = written.mcpServers["agent-deck"].headers;
549
+ assert.equal(headers["x-agent-deck-correlation-id"], CORRELATION_ID);
550
+ await releaseWorkerDeckConnection({ mcpConfigPath: result.mcpConfigPath });
551
+ }
552
+ });
553
+ test("prepareWorkerDeckConnection omits the correlation header when the session has none", async () => {
554
+ const result = await prepareWorkerDeckConnection({
555
+ policy: DENIED,
556
+ ...BASE_OPTS,
557
+ verifyCallTool: async () => textResult({ id: DECK, name: "personal-dev" }),
558
+ });
559
+ assert.equal(result.ok, true);
560
+ if (result.ok) {
561
+ const written = JSON.parse(fs.readFileSync(result.mcpConfigPath, "utf8"));
562
+ const headers = written.mcpServers["agent-deck"].headers;
563
+ assert.equal("x-agent-deck-correlation-id" in headers, false);
564
+ await releaseWorkerDeckConnection({ mcpConfigPath: result.mcpConfigPath });
565
+ }
566
+ });
567
+ test("prepareWorkerDeckConnection writes the exact correlation header for codex_local", async () => {
568
+ const result = await prepareWorkerDeckConnection({
569
+ policy: DENIED,
570
+ ...BASE_OPTS,
571
+ runtime: "codex_local",
572
+ correlationId: CORRELATION_ID,
573
+ verifyCallTool: async () => textResult({ id: DECK }),
574
+ });
575
+ assert.equal(result.ok, true);
576
+ if (result.ok) {
577
+ const toml = fs.readFileSync(path.join(result.mcpConfigPath, "config.toml"), "utf8");
578
+ assert.match(toml, new RegExp(`x-agent-deck-correlation-id = "${CORRELATION_ID}"`));
579
+ await releaseWorkerDeckConnection({ mcpConfigPath: result.mcpConfigPath });
580
+ }
581
+ });
582
+ test("prepareWorkerDeckConnection writes the exact correlation header for cursor_local", async () => {
583
+ const repo = fs.mkdtempSync(path.join(os.tmpdir(), "dealer-cursor-correlation-"));
584
+ initGitRepo(repo);
585
+ try {
586
+ const result = await prepareWorkerDeckConnection({
587
+ policy: DENIED,
588
+ deckId: DECK,
589
+ worktreePath: repo,
590
+ runtime: "cursor_local",
591
+ correlationId: CORRELATION_ID,
592
+ verifyCallTool: async () => textResult({ id: DECK }),
593
+ });
594
+ assert.equal(result.ok, true);
595
+ if (result.ok) {
596
+ const written = JSON.parse(fs.readFileSync(result.mcpConfigPath, "utf8"));
597
+ assert.equal(written.mcpServers["agent-deck"].headers["x-agent-deck-correlation-id"], CORRELATION_ID);
598
+ await releaseWorkerDeckConnection({ mcpConfigPath: result.mcpConfigPath });
599
+ }
600
+ }
601
+ finally {
602
+ fs.rmSync(repo, { recursive: true, force: true });
603
+ }
604
+ });
@@ -107,6 +107,15 @@ export function setRunCommandForTests(fn) {
107
107
  function runCommand(cmd, args, timeoutMs = DEFAULT_PROBE_TIMEOUT_MS, env) {
108
108
  return runCommandImpl(cmd, args, timeoutMs, env);
109
109
  }
110
+ /**
111
+ * NOT-308: drop only the cached muse runtime issues — the `muse_capability` acknowledge
112
+ * path calls this so the lifted block is seen on the next health read instead of after
113
+ * the 60s TTL. Never touches capability state itself (unlike clearAgentHealthCaches,
114
+ * which resets it for tests).
115
+ */
116
+ export function invalidateMuseHealthCache() {
117
+ runtimeIssueCache.delete("muse_code");
118
+ }
110
119
  /** Exported for tests — clears the shared github + runtime health caches and soft-fail streak. */
111
120
  export function clearAgentHealthCaches() {
112
121
  runtimeIssueCache.clear();
@@ -199,9 +208,11 @@ async function cursorRuntimeIssues() {
199
208
  * existence only, never read.
200
209
  *
201
210
  * NOT-277: with CLI and credentials present, the reported version is handed to the capability
202
- * check — a version not yet checked runs one real developer-shell probe (muse-capability.ts);
203
- * `runtime_capability` blocks while it runs, when it finds shell/write missing, or when it could
204
- * not complete.
211
+ * check — a version not yet checked runs one real developer-shell probe (muse-capability.ts).
212
+ * NOT-308: `runtime_capability` blocks only on a confirmed shell/write loss (`missing`,
213
+ * not operator-overridden); while the version is unchecked or inconclusive the check
214
+ * runs in the background and admission proceeds on the last confirmed baseline
215
+ * (fresh installs with no baseline still fail closed).
205
216
  */
206
217
  async function museRuntimeIssues() {
207
218
  const bin = resolveMuseBin();
@@ -527,7 +527,10 @@ const NONE_STREAK_REQUIRED = 2;
527
527
  * between resets the streak); if the deadline is hit before that streak completes, the
528
528
  * poll fails closed as "timeout" rather than silently waving the handoff through.
529
529
  */
530
- export async function pollPrChecks(adapter, opts) {
530
+ export async function pollPrChecks(
531
+ // NOT-310: narrowed to what the poll actually calls — the merge-conflict sync
532
+ // passes only a checks reader, and full adapters still satisfy this shape.
533
+ adapter, opts) {
531
534
  const deadline = Date.now() + opts.timeoutMs;
532
535
  let noneStreak = 0;
533
536
  for (;;) {