@supaku/agentfactory-cli 0.7.6 → 0.7.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linear-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/linear-runner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,CAAA;IACjD,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAA;CAChB;AAOD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAC/C,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,CAAA;IACjD,cAAc,EAAE,MAAM,EAAE,CAAA;CACzB,CA2CA;
|
|
1
|
+
{"version":3,"file":"linear-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/linear-runner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,CAAA;IACjD,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAA;CAChB;AAOD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAC/C,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,CAAA;IACjD,cAAc,EAAE,MAAM,EAAE,CAAA;CACzB,CA2CA;AAymBD,wBAAsB,SAAS,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA2MvF"}
|
|
@@ -393,6 +393,121 @@ async function checkDeployment(prNumber, format = 'json') {
|
|
|
393
393
|
}
|
|
394
394
|
return result;
|
|
395
395
|
}
|
|
396
|
+
async function createBlocker(client, options) {
|
|
397
|
+
// 1. Fetch source issue to resolve team/project
|
|
398
|
+
const sourceIssue = await client.getIssue(options.sourceIssueId);
|
|
399
|
+
const sourceTeam = await sourceIssue.team;
|
|
400
|
+
const sourceProject = await sourceIssue.project;
|
|
401
|
+
const teamName = options.team ?? sourceTeam?.name;
|
|
402
|
+
if (!teamName) {
|
|
403
|
+
throw new Error('Could not resolve team from source issue. Provide --team explicitly.');
|
|
404
|
+
}
|
|
405
|
+
const team = await client.getTeam(teamName);
|
|
406
|
+
const projectName = options.project ?? sourceProject?.name;
|
|
407
|
+
// 2. Deduplicate: check for existing Icebox issues with same title + "Needs Human" label
|
|
408
|
+
if (projectName) {
|
|
409
|
+
const projects = await client.linearClient.projects({
|
|
410
|
+
filter: { name: { eqIgnoreCase: projectName } },
|
|
411
|
+
});
|
|
412
|
+
if (projects.nodes.length > 0) {
|
|
413
|
+
const existingIssues = await client.linearClient.issues({
|
|
414
|
+
filter: {
|
|
415
|
+
project: { id: { eq: projects.nodes[0].id } },
|
|
416
|
+
state: { name: { eqIgnoreCase: 'Icebox' } },
|
|
417
|
+
labels: { name: { eqIgnoreCase: 'Needs Human' } },
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
const duplicate = existingIssues.nodes.find((i) => i.title.toLowerCase() === options.title.toLowerCase());
|
|
421
|
+
if (duplicate) {
|
|
422
|
+
// Add a +1 comment to the existing issue
|
|
423
|
+
await client.createComment(duplicate.id, `+1 — Also needed by ${sourceIssue.identifier}`);
|
|
424
|
+
return {
|
|
425
|
+
id: duplicate.id,
|
|
426
|
+
identifier: duplicate.identifier,
|
|
427
|
+
title: duplicate.title,
|
|
428
|
+
url: duplicate.url,
|
|
429
|
+
sourceIssue: sourceIssue.identifier,
|
|
430
|
+
relation: 'blocks',
|
|
431
|
+
deduplicated: true,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
// 3. Create the blocker issue
|
|
437
|
+
const createPayload = {
|
|
438
|
+
teamId: team.id,
|
|
439
|
+
title: options.title,
|
|
440
|
+
};
|
|
441
|
+
// Description with source reference
|
|
442
|
+
const descParts = [];
|
|
443
|
+
if (options.description) {
|
|
444
|
+
descParts.push(options.description);
|
|
445
|
+
}
|
|
446
|
+
descParts.push(`\n---\n*Source issue: ${sourceIssue.identifier}*`);
|
|
447
|
+
createPayload.description = descParts.join('\n\n');
|
|
448
|
+
// Set state to Icebox
|
|
449
|
+
const statuses = await client.getTeamStatuses(team.id);
|
|
450
|
+
const iceboxStateId = statuses['Icebox'];
|
|
451
|
+
if (iceboxStateId) {
|
|
452
|
+
createPayload.stateId = iceboxStateId;
|
|
453
|
+
}
|
|
454
|
+
// Set "Needs Human" label
|
|
455
|
+
const allLabels = await client.linearClient.issueLabels();
|
|
456
|
+
const needsHumanLabel = allLabels.nodes.find((l) => l.name.toLowerCase() === 'needs human');
|
|
457
|
+
if (needsHumanLabel) {
|
|
458
|
+
createPayload.labelIds = [needsHumanLabel.id];
|
|
459
|
+
}
|
|
460
|
+
// Set project
|
|
461
|
+
if (projectName) {
|
|
462
|
+
const projects = await client.linearClient.projects({
|
|
463
|
+
filter: { name: { eqIgnoreCase: projectName } },
|
|
464
|
+
});
|
|
465
|
+
if (projects.nodes.length > 0) {
|
|
466
|
+
createPayload.projectId = projects.nodes[0].id;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
const payload = await client.linearClient.createIssue(createPayload);
|
|
470
|
+
if (!payload.success) {
|
|
471
|
+
throw new Error('Failed to create blocker issue');
|
|
472
|
+
}
|
|
473
|
+
const blockerIssue = await payload.issue;
|
|
474
|
+
if (!blockerIssue) {
|
|
475
|
+
throw new Error('Blocker issue created but not returned');
|
|
476
|
+
}
|
|
477
|
+
// 4. Create blocking relation: blocker blocks source
|
|
478
|
+
await client.createIssueRelation({
|
|
479
|
+
issueId: blockerIssue.id,
|
|
480
|
+
relatedIssueId: sourceIssue.id,
|
|
481
|
+
type: 'blocks',
|
|
482
|
+
});
|
|
483
|
+
// 5. Post comment on source issue
|
|
484
|
+
await client.createComment(sourceIssue.id, `\u{1F6A7} Human blocker created: [${blockerIssue.identifier}](${blockerIssue.url}) — ${options.title}`);
|
|
485
|
+
// 6. Optionally assign
|
|
486
|
+
if (options.assignee) {
|
|
487
|
+
const users = await client.linearClient.users({
|
|
488
|
+
filter: {
|
|
489
|
+
or: [
|
|
490
|
+
{ name: { eqIgnoreCase: options.assignee } },
|
|
491
|
+
{ email: { eq: options.assignee } },
|
|
492
|
+
],
|
|
493
|
+
},
|
|
494
|
+
});
|
|
495
|
+
if (users.nodes.length > 0) {
|
|
496
|
+
await client.linearClient.updateIssue(blockerIssue.id, {
|
|
497
|
+
assigneeId: users.nodes[0].id,
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return {
|
|
502
|
+
id: blockerIssue.id,
|
|
503
|
+
identifier: blockerIssue.identifier,
|
|
504
|
+
title: blockerIssue.title,
|
|
505
|
+
url: blockerIssue.url,
|
|
506
|
+
sourceIssue: sourceIssue.identifier,
|
|
507
|
+
relation: 'blocks',
|
|
508
|
+
deduplicated: false,
|
|
509
|
+
};
|
|
510
|
+
}
|
|
396
511
|
// ── Commands that don't require LINEAR_API_KEY ─────────────────────
|
|
397
512
|
const NO_API_KEY_COMMANDS = new Set(['check-deployment']);
|
|
398
513
|
// ── Main runner ────────────────────────────────────────────────────
|
|
@@ -544,6 +659,21 @@ export async function runLinear(config) {
|
|
|
544
659
|
output = await checkDeployment(prNumber, format);
|
|
545
660
|
break;
|
|
546
661
|
}
|
|
662
|
+
case 'create-blocker': {
|
|
663
|
+
const sourceIssueId = requirePositional('source-issue-id');
|
|
664
|
+
if (!args.title) {
|
|
665
|
+
throw new Error('Usage: af-linear create-blocker <source-issue-id> --title "Title" [--description "..."] [--team "..."] [--project "..."] [--assignee "user@email.com"]');
|
|
666
|
+
}
|
|
667
|
+
output = await createBlocker(client(), {
|
|
668
|
+
title: args.title,
|
|
669
|
+
sourceIssueId,
|
|
670
|
+
description: args.description,
|
|
671
|
+
team: args.team,
|
|
672
|
+
project: args.project,
|
|
673
|
+
assignee: args.assignee,
|
|
674
|
+
});
|
|
675
|
+
break;
|
|
676
|
+
}
|
|
547
677
|
default:
|
|
548
678
|
throw new Error(`Unknown command: ${command}`);
|
|
549
679
|
}
|
package/dist/src/linear.d.ts
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* list-sub-issue-statuses <id> List sub-issue statuses (lightweight)
|
|
24
24
|
* update-sub-issue <id> Update sub-issue status with comment
|
|
25
25
|
* check-deployment <PR> Check Vercel deployment status for a PR
|
|
26
|
+
* create-blocker <source-id> Create a human-needed blocker issue
|
|
26
27
|
*
|
|
27
28
|
* Array Values:
|
|
28
29
|
* --labels accepts comma-separated: --labels "Bug,Feature"
|
package/dist/src/linear.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linear.d.ts","sourceRoot":"","sources":["../../src/linear.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"linear.d.ts","sourceRoot":"","sources":["../../src/linear.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG"}
|
package/dist/src/linear.js
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* list-sub-issue-statuses <id> List sub-issue statuses (lightweight)
|
|
24
24
|
* update-sub-issue <id> Update sub-issue status with comment
|
|
25
25
|
* check-deployment <PR> Check Vercel deployment status for a PR
|
|
26
|
+
* create-blocker <source-id> Create a human-needed blocker issue
|
|
26
27
|
*
|
|
27
28
|
* Array Values:
|
|
28
29
|
* --labels accepts comma-separated: --labels "Bug,Feature"
|
|
@@ -60,6 +61,7 @@ Commands:
|
|
|
60
61
|
list-sub-issue-statuses <id> List sub-issue statuses (lightweight)
|
|
61
62
|
update-sub-issue <id> Update sub-issue status with comment
|
|
62
63
|
check-deployment <PR> Check Vercel deployment status for a PR
|
|
64
|
+
create-blocker <source-id> Create a human-needed blocker issue
|
|
63
65
|
help Show this help message
|
|
64
66
|
|
|
65
67
|
Options:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supaku/agentfactory-cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI tools for AgentFactory — local orchestrator, remote worker, queue admin",
|
|
6
6
|
"author": "Supaku (https://supaku.com)",
|
|
@@ -88,9 +88,9 @@
|
|
|
88
88
|
],
|
|
89
89
|
"dependencies": {
|
|
90
90
|
"dotenv": "^17.2.3",
|
|
91
|
-
"@supaku/agentfactory": "0.7.
|
|
92
|
-
"@supaku/agentfactory-linear": "0.7.
|
|
93
|
-
"@supaku/agentfactory-server": "0.7.
|
|
91
|
+
"@supaku/agentfactory": "0.7.8",
|
|
92
|
+
"@supaku/agentfactory-linear": "0.7.8",
|
|
93
|
+
"@supaku/agentfactory-server": "0.7.8"
|
|
94
94
|
},
|
|
95
95
|
"devDependencies": {
|
|
96
96
|
"@types/node": "^22.5.4",
|