agent-dealer 1.3.3 → 1.3.5

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 (33) hide show
  1. package/bundle/server/dist/coordinator/commands.js +79 -1
  2. package/bundle/server/dist/coordinator/commands.test.js +2 -0
  3. package/bundle/server/dist/coordinator/developer-effect.test.js +2 -0
  4. package/bundle/server/dist/coordinator/operator-verification.integration.test.js +20 -2
  5. package/bundle/server/dist/coordinator/repair-cycle.integration.test.js +2 -0
  6. package/bundle/server/dist/coordinator/reviewer-effect.test.js +2 -0
  7. package/bundle/server/dist/coordinator/reviewer-visual-evidence.js +44 -4
  8. package/bundle/server/dist/coordinator/reviewer-visual-evidence.test.js +129 -1
  9. package/bundle/server/dist/coordinator/worker-loop.test.js +2 -0
  10. package/bundle/server/dist/db/auto-merge-default-migration.test.js +52 -0
  11. package/bundle/server/dist/db/index.js +4 -2
  12. package/bundle/server/dist/db/schema.sql +1 -1
  13. package/bundle/server/dist/dev-review-cli-happy-path.integration.test.js +2 -0
  14. package/bundle/server/dist/routes/auto-merge-policy.test.js +378 -0
  15. package/bundle/server/dist/routes/human-actions.test.js +4 -4
  16. package/bundle/server/dist/routes/issues-execution-contract.test.js +4 -3
  17. package/bundle/server/dist/routes/issues.js +32 -2
  18. package/bundle/server/dist/routes/issues.test.js +25 -2
  19. package/bundle/server/package.json +2 -2
  20. package/bundle/server/static-ui/assets/index-CHCiztRI.css +1 -0
  21. package/bundle/server/static-ui/assets/index-CrLQFFpw.js +64 -0
  22. package/bundle/server/static-ui/index.html +2 -2
  23. package/bundle/shared/dist/issues.d.ts +8 -5
  24. package/bundle/shared/dist/issues.js +7 -4
  25. package/bundle/shared/dist/issues.test.js +11 -1
  26. package/bundle/shared/package.json +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/issue.d.ts +1 -0
  29. package/dist/issue.js +3 -2
  30. package/dist/issue.test.js +37 -0
  31. package/package.json +1 -1
  32. package/bundle/server/static-ui/assets/index-B_pNUDRY.js +0 -64
  33. package/bundle/server/static-ui/assets/index-DL8mEXzN.css +0 -1
@@ -8,8 +8,8 @@
8
8
  <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
9
9
  <meta name="theme-color" content="#0a0e14" />
10
10
  <link rel="preload" href="/fonts/Monaco.ttf" as="font" type="font/ttf" crossorigin />
11
- <script type="module" crossorigin src="/assets/index-B_pNUDRY.js"></script>
12
- <link rel="stylesheet" crossorigin href="/assets/index-DL8mEXzN.css">
11
+ <script type="module" crossorigin src="/assets/index-CrLQFFpw.js"></script>
12
+ <link rel="stylesheet" crossorigin href="/assets/index-CHCiztRI.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="root"></div>
@@ -96,8 +96,8 @@ export declare const Issue: z.ZodObject<{
96
96
  prUrl: z.ZodNullable<z.ZodString>;
97
97
  /**
98
98
  * When true, reviewer `approved` merges the PR and marks the issue done (skips
99
- * `final_review`). Kick UI defaults this on; API/CLI omit → false so existing
100
- * callers keep the human final-review path.
99
+ * `final_review`). NOT-489: every create surface (web, API, CLI, agents) defaults
100
+ * this on; `false` is the explicit opt-in to final human review.
101
101
  */
102
102
  autoMerge: z.ZodBoolean;
103
103
  createdAt: z.ZodString;
@@ -197,7 +197,10 @@ export declare const CreateIssueInput: z.ZodObject<{
197
197
  reviewerAgentId: z.ZodString;
198
198
  maxReviewRounds: z.ZodDefault<z.ZodNumber>;
199
199
  maxInfraAttempts: z.ZodDefault<z.ZodNumber>;
200
- /** Kick UI sends true; omit/false preserves final_review after approve. */
200
+ /**
201
+ * NOT-489: omitted means auto-merge (reviewer approval enters the guarded merge path);
202
+ * only an explicit `false` parks the approved PR at final human review.
203
+ */
201
204
  autoMerge: z.ZodDefault<z.ZodBoolean>;
202
205
  source: z.ZodDefault<z.ZodEnum<["manual", "linear", "agent"]>>;
203
206
  externalId: z.ZodOptional<z.ZodString>;
@@ -438,8 +441,8 @@ export declare const CreateIssueResult: z.ZodObject<{
438
441
  prUrl: z.ZodNullable<z.ZodString>;
439
442
  /**
440
443
  * When true, reviewer `approved` merges the PR and marks the issue done (skips
441
- * `final_review`). Kick UI defaults this on; API/CLI omit → false so existing
442
- * callers keep the human final-review path.
444
+ * `final_review`). NOT-489: every create surface (web, API, CLI, agents) defaults
445
+ * this on; `false` is the explicit opt-in to final human review.
443
446
  */
444
447
  autoMerge: z.ZodBoolean;
445
448
  createdAt: z.ZodString;
@@ -69,8 +69,8 @@ export const Issue = z.object({
69
69
  prUrl: z.string().nullable(),
70
70
  /**
71
71
  * When true, reviewer `approved` merges the PR and marks the issue done (skips
72
- * `final_review`). Kick UI defaults this on; API/CLI omit → false so existing
73
- * callers keep the human final-review path.
72
+ * `final_review`). NOT-489: every create surface (web, API, CLI, agents) defaults
73
+ * this on; `false` is the explicit opt-in to final human review.
74
74
  */
75
75
  autoMerge: z.boolean(),
76
76
  createdAt: z.string(),
@@ -87,8 +87,11 @@ export const CreateIssueInput = z.object({
87
87
  reviewerAgentId: z.string().uuid(),
88
88
  maxReviewRounds: z.number().int().min(1).default(3),
89
89
  maxInfraAttempts: z.number().int().min(0).default(3),
90
- /** Kick UI sends true; omit/false preserves final_review after approve. */
91
- autoMerge: z.boolean().default(false),
90
+ /**
91
+ * NOT-489: omitted means auto-merge (reviewer approval enters the guarded merge path);
92
+ * only an explicit `false` parks the approved PR at final human review.
93
+ */
94
+ autoMerge: z.boolean().default(true),
92
95
  source: IssueSource.default("manual"),
93
96
  externalId: z.string().optional(),
94
97
  externalLabel: z.string().optional(),
@@ -62,9 +62,19 @@ test("CreateIssueInput defaults baseBranch to main and maxReviewRounds to 3", ()
62
62
  assert.equal(parsed.baseBranch, "main");
63
63
  assert.equal(parsed.maxReviewRounds, 3);
64
64
  assert.equal(parsed.source, "manual");
65
- assert.equal(parsed.autoMerge, false);
66
65
  assert.equal(parsed.repo, "github.com/acme/app");
67
66
  });
67
+ test("NOT-489: CreateIssueInput defaults an omitted autoMerge to true and preserves an explicit false", () => {
68
+ const base = {
69
+ title: "Fix login bug",
70
+ repo: "acme/app",
71
+ developerAgentId: "22222222-2222-2222-2222-222222222222",
72
+ reviewerAgentId: "33333333-3333-3333-3333-333333333333"
73
+ };
74
+ assert.equal(CreateIssueInput.parse(base).autoMerge, true);
75
+ assert.equal(CreateIssueInput.parse({ ...base, autoMerge: false }).autoMerge, false);
76
+ assert.equal(CreateIssueInput.parse({ ...base, autoMerge: true }).autoMerge, true);
77
+ });
68
78
  test("CreateIssueInput rejects local filesystem paths (NOT-149)", () => {
69
79
  assert.throws(() => CreateIssueInput.parse({
70
80
  title: "Local",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-dealer/shared",
3
- "version": "1.3.3",
3
+ "version": "1.3.5",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ function printUsage() {
17
17
  agent-dealer install [--to VERSION] [--migrate-cli] [--purge-global]
18
18
  agent-dealer upgrade [--to VERSION] [--yes] [--check]
19
19
  agent-dealer agent list
20
- agent-dealer issue create --title T --repo owner/repo --developer-agent ID --reviewer-agent ID [--description D] [--acceptance-criteria A] [--base-branch B] [--no-enqueue]
20
+ agent-dealer issue create --title T --repo owner/repo --developer-agent ID --reviewer-agent ID [--description D] [--acceptance-criteria A] [--base-branch B] [--no-enqueue] [--no-auto-merge]
21
21
  agent-dealer issue import --external-id ID --title T --repo owner/repo --developer-agent ID --reviewer-agent ID [--external-label L]
22
22
  agent-dealer issue list [--status S1,S2]
23
23
  agent-dealer issue show <id> [--include evidence]
package/dist/issue.d.ts CHANGED
@@ -8,6 +8,7 @@ export type ParsedIssueArgs = {
8
8
  acceptanceCriteria?: string;
9
9
  baseBranch?: string;
10
10
  enqueue: boolean;
11
+ autoMerge: boolean;
11
12
  } | {
12
13
  subcommand: "import";
13
14
  externalId: string;
package/dist/issue.js CHANGED
@@ -48,7 +48,8 @@ export function parseIssueArgs(args) {
48
48
  return { subcommand: "import", externalId, externalLabel: flag(rest, "--external-label"), title, repo, developerAgentId, reviewerAgentId };
49
49
  }
50
50
  // NOT-118: create enqueues for admission by default; --no-enqueue leaves a draft out.
51
- return { subcommand: "create", title, repo, developerAgentId, reviewerAgentId, description: flag(rest, "--description"), acceptanceCriteria: flag(rest, "--acceptance-criteria"), baseBranch: flag(rest, "--base-branch"), enqueue: !rest.includes("--no-enqueue") };
51
+ // NOT-489: auto-merge by default; --no-auto-merge opts into final human review.
52
+ return { subcommand: "create", title, repo, developerAgentId, reviewerAgentId, description: flag(rest, "--description"), acceptanceCriteria: flag(rest, "--acceptance-criteria"), baseBranch: flag(rest, "--base-branch"), enqueue: !rest.includes("--no-enqueue"), autoMerge: !rest.includes("--no-auto-merge") };
52
53
  }
53
54
  case "list": {
54
55
  return { subcommand: "list", status: flag(rest, "--status") };
@@ -111,7 +112,7 @@ export async function runIssueCommand(args) {
111
112
  try {
112
113
  switch (parsed.subcommand) {
113
114
  case "create": {
114
- const result = (await apiFetch("/api/issues", { method: "POST", body: { title: parsed.title, repo: parsed.repo, developerAgentId: parsed.developerAgentId, reviewerAgentId: parsed.reviewerAgentId, description: parsed.description, acceptanceCriteria: parsed.acceptanceCriteria, baseBranch: parsed.baseBranch, source: "agent", enqueue: parsed.enqueue } }));
115
+ const result = (await apiFetch("/api/issues", { method: "POST", body: { title: parsed.title, repo: parsed.repo, developerAgentId: parsed.developerAgentId, reviewerAgentId: parsed.reviewerAgentId, description: parsed.description, acceptanceCriteria: parsed.acceptanceCriteria, baseBranch: parsed.baseBranch, source: "agent", enqueue: parsed.enqueue, autoMerge: parsed.autoMerge } }));
115
116
  console.log(JSON.stringify(result, null, 2));
116
117
  // stdout stays pure JSON for agents that pipe it — the hint goes to stderr.
117
118
  console.error(createOutcomeHint(result));
@@ -84,6 +84,43 @@ test("issue create sends enqueue:true by default and enqueue:false with --no-enq
84
84
  draft.restore();
85
85
  }
86
86
  });
87
+ test("NOT-489: issue create sends autoMerge:true by default and autoMerge:false only with --no-auto-merge", async () => {
88
+ const args = ["create", "--title", "T", "--repo", "owner/repo", "--developer-agent", "a1", "--reviewer-agent", "a2"];
89
+ assert.equal(parseIssueArgs(args).autoMerge, true);
90
+ assert.equal(parseIssueArgs([...args, "--no-auto-merge"]).autoMerge, false);
91
+ const byDefault = stubFetch("/api/issues", "POST", { id: "i1", status: "ready", created: true, queue: "enqueued", priorPasses: 0 });
92
+ try {
93
+ assert.equal(await runIssueCommand(args), 0);
94
+ assert.deepEqual(byDefault.assertCalled(), {
95
+ title: "T",
96
+ repo: "owner/repo",
97
+ developerAgentId: "a1",
98
+ reviewerAgentId: "a2",
99
+ source: "agent",
100
+ enqueue: true,
101
+ autoMerge: true,
102
+ });
103
+ }
104
+ finally {
105
+ byDefault.restore();
106
+ }
107
+ const optedOut = stubFetch("/api/issues", "POST", { id: "i2", status: "ready", created: true, queue: "enqueued", priorPasses: 0 });
108
+ try {
109
+ assert.equal(await runIssueCommand([...args, "--no-auto-merge"]), 0);
110
+ assert.deepEqual(optedOut.assertCalled(), {
111
+ title: "T",
112
+ repo: "owner/repo",
113
+ developerAgentId: "a1",
114
+ reviewerAgentId: "a2",
115
+ source: "agent",
116
+ enqueue: true,
117
+ autoMerge: false,
118
+ });
119
+ }
120
+ finally {
121
+ optedOut.restore();
122
+ }
123
+ });
87
124
  /** Runs the command with stderr captured — the hints go to stderr, stdout stays JSON. */
88
125
  async function captureStderr(args) {
89
126
  const errs = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-dealer",
3
- "version": "1.3.3",
3
+ "version": "1.3.5",
4
4
  "description": "Human control plane for agent execution — queue, plan approval, audit",
5
5
  "license": "MIT",
6
6
  "type": "module",