agent-dealer 1.2.11 → 1.2.13
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.
- package/bundle/server/dist/adapters/linear-inbox.js +72 -16
- package/bundle/server/dist/adapters/linear-inbox.test.js +183 -1
- package/bundle/server/dist/coordinator/commands.js +204 -5
- package/bundle/server/dist/coordinator/commands.test.js +288 -3
- package/bundle/server/dist/repository/intake-settings.js +50 -0
- package/bundle/server/dist/repository/intake-settings.test.js +72 -0
- package/bundle/server/dist/routes/index.js +6 -3
- package/bundle/server/dist/routes/intake-linear-config.js +31 -0
- package/bundle/server/dist/routes/intake-linear.test.js +95 -5
- package/bundle/server/dist/routes/issues.js +54 -7
- package/bundle/server/dist/routes/issues.test.js +326 -7
- package/bundle/server/package.json +2 -2
- package/bundle/server/static-ui/assets/index-BzLjMBI9.js +64 -0
- package/bundle/server/static-ui/assets/index-COYJxD1y.css +1 -0
- package/bundle/server/static-ui/index.html +2 -2
- package/bundle/shared/dist/index.d.ts +303 -0
- package/bundle/shared/dist/index.js +47 -0
- package/bundle/shared/dist/linear-intake.d.ts +14 -0
- package/bundle/shared/dist/linear-intake.js +23 -0
- package/bundle/shared/dist/linear-intake.test.js +41 -2
- package/bundle/shared/package.json +1 -1
- package/dist/index.js +2 -0
- package/dist/issue.d.ts +8 -0
- package/dist/issue.js +35 -0
- package/dist/issue.test.js +92 -0
- package/package.json +1 -1
- package/bundle/server/static-ui/assets/index-Cf4dipuK.js +0 -64
- package/bundle/server/static-ui/assets/index-K_YcYkQU.css +0 -1
package/dist/issue.js
CHANGED
|
@@ -71,6 +71,23 @@ export function parseIssueArgs(args) {
|
|
|
71
71
|
throw new Error("execute requires an issue id");
|
|
72
72
|
return { subcommand: "execute", id };
|
|
73
73
|
}
|
|
74
|
+
case "update": {
|
|
75
|
+
const id = rest[0];
|
|
76
|
+
if (!id)
|
|
77
|
+
throw new Error("update requires an issue id");
|
|
78
|
+
const developerAgentId = flag(rest, "--developer-agent");
|
|
79
|
+
const reviewerAgentId = flag(rest, "--reviewer-agent");
|
|
80
|
+
if (!developerAgentId && !reviewerAgentId) {
|
|
81
|
+
throw new Error("update requires --developer-agent and/or --reviewer-agent");
|
|
82
|
+
}
|
|
83
|
+
return { subcommand: "update", id, developerAgentId, reviewerAgentId };
|
|
84
|
+
}
|
|
85
|
+
case "park": {
|
|
86
|
+
const id = rest[0];
|
|
87
|
+
if (!id)
|
|
88
|
+
throw new Error("park requires an issue id");
|
|
89
|
+
return { subcommand: "park", id };
|
|
90
|
+
}
|
|
74
91
|
case "guide": {
|
|
75
92
|
const id = rest[0];
|
|
76
93
|
const message = flag(rest, "--message");
|
|
@@ -144,6 +161,24 @@ export async function runIssueCommand(args) {
|
|
|
144
161
|
console.error("Admitted — the workflow started immediately (queue order bypassed).");
|
|
145
162
|
return 0;
|
|
146
163
|
}
|
|
164
|
+
case "update": {
|
|
165
|
+
// NOT-358: swap the developer and/or reviewer profile on a parked issue.
|
|
166
|
+
// Either flag alone is valid; the server enforces the parked-edit surface.
|
|
167
|
+
const body = {};
|
|
168
|
+
if (parsed.developerAgentId)
|
|
169
|
+
body.developerAgentId = parsed.developerAgentId;
|
|
170
|
+
if (parsed.reviewerAgentId)
|
|
171
|
+
body.reviewerAgentId = parsed.reviewerAgentId;
|
|
172
|
+
const result = await apiFetch(`/api/issues/${parsed.id}`, { method: "PATCH", body });
|
|
173
|
+
console.log(JSON.stringify(result, null, 2));
|
|
174
|
+
return 0;
|
|
175
|
+
}
|
|
176
|
+
case "park": {
|
|
177
|
+
// NOT-358: park an issue waiting on a usage-cap or deck-outage window for a human.
|
|
178
|
+
const result = await apiFetch(`/api/issues/${parsed.id}/park`, { method: "POST" });
|
|
179
|
+
console.log(JSON.stringify(result, null, 2));
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
147
182
|
case "guide": {
|
|
148
183
|
const result = await apiFetch(`/api/issues/${parsed.id}/guidance`, { method: "POST", body: { markdown: parsed.message } });
|
|
149
184
|
console.log(JSON.stringify(result, null, 2));
|
package/dist/issue.test.js
CHANGED
|
@@ -266,6 +266,98 @@ test("issue execute prints the admitted response shape and exits 0", async () =>
|
|
|
266
266
|
stub.restore();
|
|
267
267
|
}
|
|
268
268
|
});
|
|
269
|
+
test("parseIssueArgs: update accepts either agent flag alone, park requires an id", () => {
|
|
270
|
+
assert.deepEqual(parseIssueArgs(["update", "issue-123", "--developer-agent", "a1"]), {
|
|
271
|
+
subcommand: "update",
|
|
272
|
+
id: "issue-123",
|
|
273
|
+
developerAgentId: "a1",
|
|
274
|
+
reviewerAgentId: undefined,
|
|
275
|
+
});
|
|
276
|
+
assert.deepEqual(parseIssueArgs(["update", "issue-123", "--reviewer-agent", "a2"]), {
|
|
277
|
+
subcommand: "update",
|
|
278
|
+
id: "issue-123",
|
|
279
|
+
developerAgentId: undefined,
|
|
280
|
+
reviewerAgentId: "a2",
|
|
281
|
+
});
|
|
282
|
+
assert.deepEqual(parseIssueArgs(["update", "issue-123", "--developer-agent", "a1", "--reviewer-agent", "a2"]), { subcommand: "update", id: "issue-123", developerAgentId: "a1", reviewerAgentId: "a2" });
|
|
283
|
+
assert.throws(() => parseIssueArgs(["update", "issue-123"]), /--developer-agent/);
|
|
284
|
+
assert.throws(() => parseIssueArgs(["update"]), /issue id/);
|
|
285
|
+
assert.deepEqual(parseIssueArgs(["park", "issue-123"]), { subcommand: "park", id: "issue-123" });
|
|
286
|
+
assert.throws(() => parseIssueArgs(["park"]), /issue id/);
|
|
287
|
+
});
|
|
288
|
+
test("NOT-358: issue update PATCHes the agents and prints the updated issue as JSON", async () => {
|
|
289
|
+
const updated = { id: "issue-123", status: "needs_human", developerAgentId: "a-new" };
|
|
290
|
+
for (const args of [
|
|
291
|
+
["update", "issue-123", "--developer-agent", "a-new"],
|
|
292
|
+
["update", "issue-123", "--reviewer-agent", "r-new"],
|
|
293
|
+
["update", "issue-123", "--developer-agent", "a-new", "--reviewer-agent", "r-new"],
|
|
294
|
+
]) {
|
|
295
|
+
const stub = stubFetch("/api/issues/issue-123", "PATCH", updated);
|
|
296
|
+
const logs = [];
|
|
297
|
+
const originalLog = console.log;
|
|
298
|
+
console.log = (message) => logs.push(String(message));
|
|
299
|
+
try {
|
|
300
|
+
const code = await runIssueCommand(args);
|
|
301
|
+
assert.equal(code, 0);
|
|
302
|
+
const sent = stub.assertCalled();
|
|
303
|
+
const expectedKeys = args
|
|
304
|
+
.filter((a) => a.startsWith("--"))
|
|
305
|
+
.map((a) => (a === "--developer-agent" ? "developerAgentId" : "reviewerAgentId"))
|
|
306
|
+
.sort();
|
|
307
|
+
assert.deepEqual(Object.keys(sent).sort(), expectedKeys);
|
|
308
|
+
const printed = JSON.parse(logs.join("\n"));
|
|
309
|
+
assert.equal(printed.id, "issue-123");
|
|
310
|
+
assert.equal(printed.status, "needs_human");
|
|
311
|
+
}
|
|
312
|
+
finally {
|
|
313
|
+
console.log = originalLog;
|
|
314
|
+
stub.restore();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
test("NOT-358: issue update returns nonzero on API failure", async () => {
|
|
319
|
+
const stub = stubFetch("/api/issues/issue-123", "PATCH", { error: "Cannot edit an issue with an active workflow" }, 409);
|
|
320
|
+
try {
|
|
321
|
+
const code = await runIssueCommand(["update", "issue-123", "--developer-agent", "a-new"]);
|
|
322
|
+
assert.equal(code, 1);
|
|
323
|
+
}
|
|
324
|
+
finally {
|
|
325
|
+
stub.restore();
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
test("NOT-358: issue park POSTs to the park route and prints the updated issue as JSON", async () => {
|
|
329
|
+
const stub = stubFetch("/api/issues/issue-123/park", "POST", {
|
|
330
|
+
id: "issue-123",
|
|
331
|
+
status: "needs_human",
|
|
332
|
+
humanActionId: "action-1",
|
|
333
|
+
});
|
|
334
|
+
const logs = [];
|
|
335
|
+
const originalLog = console.log;
|
|
336
|
+
console.log = (message) => logs.push(String(message));
|
|
337
|
+
try {
|
|
338
|
+
const code = await runIssueCommand(["park", "issue-123"]);
|
|
339
|
+
assert.equal(code, 0);
|
|
340
|
+
stub.assertCalled();
|
|
341
|
+
const printed = JSON.parse(logs.join("\n"));
|
|
342
|
+
assert.equal(printed.id, "issue-123");
|
|
343
|
+
assert.equal(printed.status, "needs_human");
|
|
344
|
+
assert.equal(printed.humanActionId, "action-1");
|
|
345
|
+
}
|
|
346
|
+
finally {
|
|
347
|
+
console.log = originalLog;
|
|
348
|
+
stub.restore();
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
test("NOT-358: issue park returns nonzero on API failure", async () => {
|
|
352
|
+
const stub = stubFetch("/api/issues/issue-123/park", "POST", { error: "Issue is not waiting on a usage-cap or deck-outage window" }, 409);
|
|
353
|
+
try {
|
|
354
|
+
const code = await runIssueCommand(["park", "issue-123"]);
|
|
355
|
+
assert.equal(code, 1);
|
|
356
|
+
}
|
|
357
|
+
finally {
|
|
358
|
+
stub.restore();
|
|
359
|
+
}
|
|
360
|
+
});
|
|
269
361
|
test("issue execute returns nonzero on refusal without claiming a queue action", async () => {
|
|
270
362
|
const stub = stubFetch("/api/issues/issue-123/execute", "POST", { error: "waiting for slot — running: Other issue" }, 409);
|
|
271
363
|
const errs = [];
|