@supaku/agentfactory-cli 0.7.8 → 0.7.10
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/dist/src/governor.d.ts +25 -0
- package/dist/src/governor.d.ts.map +1 -0
- package/dist/src/governor.js +137 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -0
- package/dist/src/lib/governor-runner.d.ts +85 -0
- package/dist/src/lib/governor-runner.d.ts.map +1 -0
- package/dist/src/lib/governor-runner.js +147 -0
- package/dist/src/lib/linear-runner.d.ts.map +1 -1
- package/dist/src/lib/linear-runner.js +6 -4
- package/dist/src/lib/orchestrator-runner.d.ts +2 -0
- package/dist/src/lib/orchestrator-runner.d.ts.map +1 -1
- package/dist/src/lib/orchestrator-runner.js +6 -2
- package/dist/src/orchestrator.js +6 -0
- package/package.json +6 -5
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AgentFactory Governor CLI
|
|
4
|
+
*
|
|
5
|
+
* Thin wrapper around the governor runner.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* af-governor [options]
|
|
9
|
+
*
|
|
10
|
+
* Options:
|
|
11
|
+
* --project <name> Project to scan (can be repeated)
|
|
12
|
+
* --scan-interval <ms> Scan interval in milliseconds (default: 60000)
|
|
13
|
+
* --max-dispatches <n> Maximum concurrent dispatches per scan (default: 3)
|
|
14
|
+
* --no-auto-research Disable auto-research from Icebox
|
|
15
|
+
* --no-auto-backlog-creation Disable auto-backlog-creation from Icebox
|
|
16
|
+
* --no-auto-development Disable auto-development from Backlog
|
|
17
|
+
* --no-auto-qa Disable auto-QA from Finished
|
|
18
|
+
* --no-auto-acceptance Disable auto-acceptance from Delivered
|
|
19
|
+
* --once Run a single scan pass and exit
|
|
20
|
+
*
|
|
21
|
+
* Environment:
|
|
22
|
+
* LINEAR_API_KEY Required API key for Linear authentication
|
|
23
|
+
*/
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=governor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"governor.d.ts","sourceRoot":"","sources":["../../src/governor.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AgentFactory Governor CLI
|
|
4
|
+
*
|
|
5
|
+
* Thin wrapper around the governor runner.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* af-governor [options]
|
|
9
|
+
*
|
|
10
|
+
* Options:
|
|
11
|
+
* --project <name> Project to scan (can be repeated)
|
|
12
|
+
* --scan-interval <ms> Scan interval in milliseconds (default: 60000)
|
|
13
|
+
* --max-dispatches <n> Maximum concurrent dispatches per scan (default: 3)
|
|
14
|
+
* --no-auto-research Disable auto-research from Icebox
|
|
15
|
+
* --no-auto-backlog-creation Disable auto-backlog-creation from Icebox
|
|
16
|
+
* --no-auto-development Disable auto-development from Backlog
|
|
17
|
+
* --no-auto-qa Disable auto-QA from Finished
|
|
18
|
+
* --no-auto-acceptance Disable auto-acceptance from Delivered
|
|
19
|
+
* --once Run a single scan pass and exit
|
|
20
|
+
*
|
|
21
|
+
* Environment:
|
|
22
|
+
* LINEAR_API_KEY Required API key for Linear authentication
|
|
23
|
+
*/
|
|
24
|
+
import path from 'path';
|
|
25
|
+
import { config } from 'dotenv';
|
|
26
|
+
// Load environment variables from .env.local
|
|
27
|
+
config({ path: path.resolve(process.cwd(), '.env.local') });
|
|
28
|
+
import { parseGovernorArgs, runGovernor, } from './lib/governor-runner.js';
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Stub dependencies
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
/**
|
|
33
|
+
* Create placeholder dependencies for the Governor.
|
|
34
|
+
*
|
|
35
|
+
* In a production deployment, these would be backed by the Linear SDK
|
|
36
|
+
* and Redis (via packages/server). For now we provide stubs that log
|
|
37
|
+
* calls and return safe defaults. The WorkSchedulingFrontend (SUP-709
|
|
38
|
+
* Wave 3) will provide the real implementations.
|
|
39
|
+
*/
|
|
40
|
+
function createStubDependencies() {
|
|
41
|
+
const log = {
|
|
42
|
+
warn: (msg, data) => console.warn(`[governor-stub] ${msg}`, data ? JSON.stringify(data) : ''),
|
|
43
|
+
};
|
|
44
|
+
return {
|
|
45
|
+
listIssues: async (_project) => {
|
|
46
|
+
log.warn('listIssues stub called — no issues returned', { project: _project });
|
|
47
|
+
return [];
|
|
48
|
+
},
|
|
49
|
+
hasActiveSession: async (_issueId) => false,
|
|
50
|
+
isWithinCooldown: async (_issueId) => false,
|
|
51
|
+
isParentIssue: async (_issueId) => false,
|
|
52
|
+
isHeld: async (_issueId) => false,
|
|
53
|
+
getOverridePriority: async (_issueId) => null,
|
|
54
|
+
getWorkflowStrategy: async (_issueId) => undefined,
|
|
55
|
+
isResearchCompleted: async (_issueId) => false,
|
|
56
|
+
isBacklogCreationCompleted: async (_issueId) => false,
|
|
57
|
+
dispatchWork: async (_issueId, _action) => {
|
|
58
|
+
log.warn('dispatchWork stub called', { issueId: _issueId, action: _action });
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Main
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
async function main() {
|
|
66
|
+
const args = parseGovernorArgs();
|
|
67
|
+
if (args.projects.length === 0) {
|
|
68
|
+
console.error('Error: at least one --project is required');
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
console.log('AgentFactory Governor');
|
|
72
|
+
console.log('=====================');
|
|
73
|
+
console.log(`Projects: ${args.projects.join(', ')}`);
|
|
74
|
+
console.log(`Scan interval: ${args.scanIntervalMs}ms`);
|
|
75
|
+
console.log(`Max dispatches per scan: ${args.maxConcurrentDispatches}`);
|
|
76
|
+
console.log(`Mode: ${args.once ? 'single scan' : 'continuous'}`);
|
|
77
|
+
console.log('');
|
|
78
|
+
const runnerConfig = {
|
|
79
|
+
projects: args.projects,
|
|
80
|
+
scanIntervalMs: args.scanIntervalMs,
|
|
81
|
+
maxConcurrentDispatches: args.maxConcurrentDispatches,
|
|
82
|
+
enableAutoResearch: args.enableAutoResearch,
|
|
83
|
+
enableAutoBacklogCreation: args.enableAutoBacklogCreation,
|
|
84
|
+
enableAutoDevelopment: args.enableAutoDevelopment,
|
|
85
|
+
enableAutoQA: args.enableAutoQA,
|
|
86
|
+
enableAutoAcceptance: args.enableAutoAcceptance,
|
|
87
|
+
once: args.once,
|
|
88
|
+
dependencies: createStubDependencies(),
|
|
89
|
+
callbacks: {
|
|
90
|
+
onScanComplete: (results) => {
|
|
91
|
+
for (const result of results) {
|
|
92
|
+
console.log(`[${result.project}] Scanned ${result.scannedIssues} issues, dispatched ${result.actionsDispatched}`);
|
|
93
|
+
if (result.errors.length > 0) {
|
|
94
|
+
for (const err of result.errors) {
|
|
95
|
+
console.error(` Error: ${err.issueId} — ${err.error}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
onError: (error) => {
|
|
101
|
+
console.error('Governor error:', error.message);
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
try {
|
|
106
|
+
const { governor, scanResults } = await runGovernor(runnerConfig);
|
|
107
|
+
if (args.once && scanResults) {
|
|
108
|
+
// Print summary and exit
|
|
109
|
+
let totalDispatched = 0;
|
|
110
|
+
let totalErrors = 0;
|
|
111
|
+
for (const result of scanResults) {
|
|
112
|
+
totalDispatched += result.actionsDispatched;
|
|
113
|
+
totalErrors += result.errors.length;
|
|
114
|
+
}
|
|
115
|
+
console.log('');
|
|
116
|
+
console.log(`Scan complete: ${totalDispatched} actions dispatched, ${totalErrors} errors`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// Continuous mode — handle graceful shutdown
|
|
120
|
+
console.log('Governor running. Press Ctrl+C to stop.');
|
|
121
|
+
const shutdown = () => {
|
|
122
|
+
console.log('\nShutting down governor...');
|
|
123
|
+
governor.stop();
|
|
124
|
+
process.exit(0);
|
|
125
|
+
};
|
|
126
|
+
process.on('SIGINT', shutdown);
|
|
127
|
+
process.on('SIGTERM', shutdown);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.error('Governor failed:', error instanceof Error ? error.message : error);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
main().catch((error) => {
|
|
135
|
+
console.error('Fatal error:', error);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
});
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,QAAA,MAAM,OAAO,QAAkB,CAAA;AAE/B,iBAAS,SAAS,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,QAAA,MAAM,OAAO,QAAkB,CAAA;AAE/B,iBAAS,SAAS,IAAI,IAAI,CAsBzB"}
|
package/dist/src/index.js
CHANGED
|
@@ -16,6 +16,7 @@ Usage:
|
|
|
16
16
|
|
|
17
17
|
Commands:
|
|
18
18
|
orchestrator Spawn concurrent agents on backlog issues
|
|
19
|
+
governor Automated workflow scan loop with configurable triggers
|
|
19
20
|
worker Start a remote worker that polls for queued work
|
|
20
21
|
worker-fleet Spawn and manage multiple worker processes
|
|
21
22
|
cleanup Clean up orphaned git worktrees
|
|
@@ -33,6 +34,9 @@ switch (command) {
|
|
|
33
34
|
case 'orchestrator':
|
|
34
35
|
import('./orchestrator');
|
|
35
36
|
break;
|
|
37
|
+
case 'governor':
|
|
38
|
+
import('./governor');
|
|
39
|
+
break;
|
|
36
40
|
case 'worker':
|
|
37
41
|
import('./worker');
|
|
38
42
|
break;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Governor Runner -- Programmatic API for the governor CLI.
|
|
3
|
+
*
|
|
4
|
+
* Exports `runGovernor()` so the governor can be invoked from code
|
|
5
|
+
* (e.g. Next.js route handlers, tests, or custom scripts) without going
|
|
6
|
+
* through process.argv / process.env / process.exit.
|
|
7
|
+
*/
|
|
8
|
+
import { WorkflowGovernor, type GovernorDependencies } from '@supaku/agentfactory';
|
|
9
|
+
import type { ScanResult } from '@supaku/agentfactory';
|
|
10
|
+
export interface GovernorRunnerConfig {
|
|
11
|
+
/** Projects to scan */
|
|
12
|
+
projects: string[];
|
|
13
|
+
/** Scan interval in milliseconds (default: 60000) */
|
|
14
|
+
scanIntervalMs?: number;
|
|
15
|
+
/** Maximum concurrent dispatches per scan (default: 3) */
|
|
16
|
+
maxConcurrentDispatches?: number;
|
|
17
|
+
/** Enable auto-research from Icebox (default: true) */
|
|
18
|
+
enableAutoResearch?: boolean;
|
|
19
|
+
/** Enable auto-backlog-creation from Icebox (default: true) */
|
|
20
|
+
enableAutoBacklogCreation?: boolean;
|
|
21
|
+
/** Enable auto-development from Backlog (default: true) */
|
|
22
|
+
enableAutoDevelopment?: boolean;
|
|
23
|
+
/** Enable auto-QA from Finished (default: true) */
|
|
24
|
+
enableAutoQA?: boolean;
|
|
25
|
+
/** Enable auto-acceptance from Delivered (default: true) */
|
|
26
|
+
enableAutoAcceptance?: boolean;
|
|
27
|
+
/** Run a single scan pass and exit (for testing / cron) */
|
|
28
|
+
once?: boolean;
|
|
29
|
+
/** Dependency injection for the governor (required) */
|
|
30
|
+
dependencies: GovernorDependencies;
|
|
31
|
+
/** Callbacks for governor lifecycle events */
|
|
32
|
+
callbacks?: GovernorRunnerCallbacks;
|
|
33
|
+
}
|
|
34
|
+
export interface GovernorRunnerCallbacks {
|
|
35
|
+
onScanComplete?: (results: ScanResult[]) => void;
|
|
36
|
+
onError?: (error: Error) => void;
|
|
37
|
+
}
|
|
38
|
+
export interface GovernorRunnerResult {
|
|
39
|
+
governor: WorkflowGovernor;
|
|
40
|
+
/** Only populated in --once mode */
|
|
41
|
+
scanResults?: ScanResult[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Start the Workflow Governor with the given configuration.
|
|
45
|
+
*
|
|
46
|
+
* In `once` mode, runs a single scan pass and returns the results.
|
|
47
|
+
* Otherwise, starts the scan loop and returns the governor instance
|
|
48
|
+
* (caller is responsible for calling `governor.stop()` on shutdown).
|
|
49
|
+
*/
|
|
50
|
+
export declare function runGovernor(config: GovernorRunnerConfig): Promise<GovernorRunnerResult>;
|
|
51
|
+
export interface GovernorCLIArgs {
|
|
52
|
+
projects: string[];
|
|
53
|
+
scanIntervalMs: number;
|
|
54
|
+
maxConcurrentDispatches: number;
|
|
55
|
+
enableAutoResearch: boolean;
|
|
56
|
+
enableAutoBacklogCreation: boolean;
|
|
57
|
+
enableAutoDevelopment: boolean;
|
|
58
|
+
enableAutoQA: boolean;
|
|
59
|
+
enableAutoAcceptance: boolean;
|
|
60
|
+
once: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Parse CLI arguments for the governor command.
|
|
64
|
+
*
|
|
65
|
+
* Usage:
|
|
66
|
+
* agentfactory governor --project <name> [--project <name>] [options]
|
|
67
|
+
*
|
|
68
|
+
* Options:
|
|
69
|
+
* --project <name> Project to scan (can be repeated)
|
|
70
|
+
* --scan-interval <ms> Scan interval in milliseconds (default: 60000)
|
|
71
|
+
* --max-dispatches <n> Maximum concurrent dispatches per scan (default: 3)
|
|
72
|
+
* --no-auto-research Disable auto-research from Icebox
|
|
73
|
+
* --no-auto-backlog-creation Disable auto-backlog-creation from Icebox
|
|
74
|
+
* --no-auto-development Disable auto-development from Backlog
|
|
75
|
+
* --no-auto-qa Disable auto-QA from Finished
|
|
76
|
+
* --no-auto-acceptance Disable auto-acceptance from Delivered
|
|
77
|
+
* --once Run a single scan pass and exit
|
|
78
|
+
* --help, -h Show help
|
|
79
|
+
*/
|
|
80
|
+
export declare function parseGovernorArgs(argv?: string[]): GovernorCLIArgs;
|
|
81
|
+
/**
|
|
82
|
+
* Print help text for the governor command.
|
|
83
|
+
*/
|
|
84
|
+
export declare function printGovernorHelp(): void;
|
|
85
|
+
//# sourceMappingURL=governor-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"governor-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/governor-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,gBAAgB,EAChB,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAIV,UAAU,EACX,MAAM,sBAAsB,CAAA;AAM7B,MAAM,WAAW,oBAAoB;IACnC,uBAAuB;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,0DAA0D;IAC1D,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,uDAAuD;IACvD,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,+DAA+D;IAC/D,yBAAyB,CAAC,EAAE,OAAO,CAAA;IACnC,2DAA2D;IAC3D,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,mDAAmD;IACnD,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,4DAA4D;IAC5D,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,2DAA2D;IAC3D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uDAAuD;IACvD,YAAY,EAAE,oBAAoB,CAAA;IAClC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,uBAAuB,CAAA;CACpC;AAED,MAAM,WAAW,uBAAuB;IACtC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,CAAA;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,oCAAoC;IACpC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAA;CAC3B;AAMD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,oBAAoB,CAAC,CAwB/B;AAMD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,uBAAuB,EAAE,MAAM,CAAA;IAC/B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,yBAAyB,EAAE,OAAO,CAAA;IAClC,qBAAqB,EAAE,OAAO,CAAA;IAC9B,YAAY,EAAE,OAAO,CAAA;IACrB,oBAAoB,EAAE,OAAO,CAAA;IAC7B,IAAI,EAAE,OAAO,CAAA;CACd;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,eAAe,CAmDzF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAmCxC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Governor Runner -- Programmatic API for the governor CLI.
|
|
3
|
+
*
|
|
4
|
+
* Exports `runGovernor()` so the governor can be invoked from code
|
|
5
|
+
* (e.g. Next.js route handlers, tests, or custom scripts) without going
|
|
6
|
+
* through process.argv / process.env / process.exit.
|
|
7
|
+
*/
|
|
8
|
+
import { WorkflowGovernor, } from '@supaku/agentfactory';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Runner
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* Start the Workflow Governor with the given configuration.
|
|
14
|
+
*
|
|
15
|
+
* In `once` mode, runs a single scan pass and returns the results.
|
|
16
|
+
* Otherwise, starts the scan loop and returns the governor instance
|
|
17
|
+
* (caller is responsible for calling `governor.stop()` on shutdown).
|
|
18
|
+
*/
|
|
19
|
+
export async function runGovernor(config) {
|
|
20
|
+
const governorConfig = {
|
|
21
|
+
projects: config.projects,
|
|
22
|
+
scanIntervalMs: config.scanIntervalMs,
|
|
23
|
+
maxConcurrentDispatches: config.maxConcurrentDispatches,
|
|
24
|
+
enableAutoResearch: config.enableAutoResearch,
|
|
25
|
+
enableAutoBacklogCreation: config.enableAutoBacklogCreation,
|
|
26
|
+
enableAutoDevelopment: config.enableAutoDevelopment,
|
|
27
|
+
enableAutoQA: config.enableAutoQA,
|
|
28
|
+
enableAutoAcceptance: config.enableAutoAcceptance,
|
|
29
|
+
};
|
|
30
|
+
const governor = new WorkflowGovernor(governorConfig, config.dependencies);
|
|
31
|
+
// -- Single scan mode (--once) --
|
|
32
|
+
if (config.once) {
|
|
33
|
+
const results = await governor.scanOnce();
|
|
34
|
+
config.callbacks?.onScanComplete?.(results);
|
|
35
|
+
return { governor, scanResults: results };
|
|
36
|
+
}
|
|
37
|
+
// -- Continuous scan loop --
|
|
38
|
+
governor.start();
|
|
39
|
+
return { governor };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Parse CLI arguments for the governor command.
|
|
43
|
+
*
|
|
44
|
+
* Usage:
|
|
45
|
+
* agentfactory governor --project <name> [--project <name>] [options]
|
|
46
|
+
*
|
|
47
|
+
* Options:
|
|
48
|
+
* --project <name> Project to scan (can be repeated)
|
|
49
|
+
* --scan-interval <ms> Scan interval in milliseconds (default: 60000)
|
|
50
|
+
* --max-dispatches <n> Maximum concurrent dispatches per scan (default: 3)
|
|
51
|
+
* --no-auto-research Disable auto-research from Icebox
|
|
52
|
+
* --no-auto-backlog-creation Disable auto-backlog-creation from Icebox
|
|
53
|
+
* --no-auto-development Disable auto-development from Backlog
|
|
54
|
+
* --no-auto-qa Disable auto-QA from Finished
|
|
55
|
+
* --no-auto-acceptance Disable auto-acceptance from Delivered
|
|
56
|
+
* --once Run a single scan pass and exit
|
|
57
|
+
* --help, -h Show help
|
|
58
|
+
*/
|
|
59
|
+
export function parseGovernorArgs(argv = process.argv.slice(2)) {
|
|
60
|
+
const result = {
|
|
61
|
+
projects: [],
|
|
62
|
+
scanIntervalMs: 60_000,
|
|
63
|
+
maxConcurrentDispatches: 3,
|
|
64
|
+
enableAutoResearch: true,
|
|
65
|
+
enableAutoBacklogCreation: true,
|
|
66
|
+
enableAutoDevelopment: true,
|
|
67
|
+
enableAutoQA: true,
|
|
68
|
+
enableAutoAcceptance: true,
|
|
69
|
+
once: false,
|
|
70
|
+
};
|
|
71
|
+
for (let i = 0; i < argv.length; i++) {
|
|
72
|
+
const arg = argv[i];
|
|
73
|
+
switch (arg) {
|
|
74
|
+
case '--project':
|
|
75
|
+
result.projects.push(argv[++i]);
|
|
76
|
+
break;
|
|
77
|
+
case '--scan-interval':
|
|
78
|
+
result.scanIntervalMs = parseInt(argv[++i], 10);
|
|
79
|
+
break;
|
|
80
|
+
case '--max-dispatches':
|
|
81
|
+
result.maxConcurrentDispatches = parseInt(argv[++i], 10);
|
|
82
|
+
break;
|
|
83
|
+
case '--no-auto-research':
|
|
84
|
+
result.enableAutoResearch = false;
|
|
85
|
+
break;
|
|
86
|
+
case '--no-auto-backlog-creation':
|
|
87
|
+
result.enableAutoBacklogCreation = false;
|
|
88
|
+
break;
|
|
89
|
+
case '--no-auto-development':
|
|
90
|
+
result.enableAutoDevelopment = false;
|
|
91
|
+
break;
|
|
92
|
+
case '--no-auto-qa':
|
|
93
|
+
result.enableAutoQA = false;
|
|
94
|
+
break;
|
|
95
|
+
case '--no-auto-acceptance':
|
|
96
|
+
result.enableAutoAcceptance = false;
|
|
97
|
+
break;
|
|
98
|
+
case '--once':
|
|
99
|
+
result.once = true;
|
|
100
|
+
break;
|
|
101
|
+
case '--help':
|
|
102
|
+
case '-h':
|
|
103
|
+
printGovernorHelp();
|
|
104
|
+
process.exit(0);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Print help text for the governor command.
|
|
111
|
+
*/
|
|
112
|
+
export function printGovernorHelp() {
|
|
113
|
+
console.log(`
|
|
114
|
+
AgentFactory Governor — Automated workflow scan loop
|
|
115
|
+
|
|
116
|
+
Usage:
|
|
117
|
+
agentfactory governor [options]
|
|
118
|
+
|
|
119
|
+
Options:
|
|
120
|
+
--project <name> Project to scan (can be repeated for multiple projects)
|
|
121
|
+
--scan-interval <ms> Scan interval in milliseconds (default: 60000)
|
|
122
|
+
--max-dispatches <n> Maximum concurrent dispatches per scan (default: 3)
|
|
123
|
+
--no-auto-research Disable auto-research from Icebox
|
|
124
|
+
--no-auto-backlog-creation Disable auto-backlog-creation from Icebox
|
|
125
|
+
--no-auto-development Disable auto-development from Backlog
|
|
126
|
+
--no-auto-qa Disable auto-QA from Finished
|
|
127
|
+
--no-auto-acceptance Disable auto-acceptance from Delivered
|
|
128
|
+
--once Run a single scan pass and exit
|
|
129
|
+
--help, -h Show this help message
|
|
130
|
+
|
|
131
|
+
Environment:
|
|
132
|
+
LINEAR_API_KEY Required API key for Linear authentication
|
|
133
|
+
|
|
134
|
+
Examples:
|
|
135
|
+
# Start the governor for a project
|
|
136
|
+
agentfactory governor --project MyProject
|
|
137
|
+
|
|
138
|
+
# Scan multiple projects with custom interval
|
|
139
|
+
agentfactory governor --project ProjectA --project ProjectB --scan-interval 30000
|
|
140
|
+
|
|
141
|
+
# Run a single scan and exit (useful for cron jobs)
|
|
142
|
+
agentfactory governor --project MyProject --once
|
|
143
|
+
|
|
144
|
+
# Disable auto-QA (only scan for development work)
|
|
145
|
+
agentfactory governor --project MyProject --no-auto-qa --no-auto-acceptance
|
|
146
|
+
`);
|
|
147
|
+
}
|
|
@@ -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;AAymBD,wBAAsB,SAAS,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,
|
|
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,CA6MvF"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* All 15 command implementations extracted from packages/core/src/linear-cli.ts.
|
|
5
5
|
* This module does NOT call process.exit, read process.argv, or load dotenv.
|
|
6
6
|
*/
|
|
7
|
-
import { createLinearAgentClient } from '@supaku/agentfactory-linear';
|
|
7
|
+
import { createLinearAgentClient, getDefaultTeamName } from '@supaku/agentfactory-linear';
|
|
8
8
|
import { checkPRDeploymentStatus, formatDeploymentStatus, } from '@supaku/agentfactory';
|
|
9
9
|
// ── Arg parsing ────────────────────────────────────────────────────
|
|
10
10
|
/** Fields that should be split on commas to create arrays */
|
|
@@ -548,12 +548,14 @@ export async function runLinear(config) {
|
|
|
548
548
|
break;
|
|
549
549
|
}
|
|
550
550
|
case 'create-issue': {
|
|
551
|
-
|
|
552
|
-
|
|
551
|
+
const teamArg = args.team ?? (getDefaultTeamName() || undefined);
|
|
552
|
+
if (!args.title || !teamArg) {
|
|
553
|
+
throw new Error('Usage: af-linear create-issue --title "Title" --team "Team" [--description "..."] [--project "..."] [--labels "Label1,Label2"] [--state "Backlog"] [--parentId "..."]\n' +
|
|
554
|
+
'Tip: Set LINEAR_TEAM_NAME env var to provide a default team.');
|
|
553
555
|
}
|
|
554
556
|
output = await createIssue(client(), {
|
|
555
557
|
title: args.title,
|
|
556
|
-
team:
|
|
558
|
+
team: teamArg,
|
|
557
559
|
description: args.description,
|
|
558
560
|
project: args.project,
|
|
559
561
|
labels: args.labels,
|
|
@@ -23,6 +23,8 @@ export interface OrchestratorRunnerConfig {
|
|
|
23
23
|
gitRoot?: string;
|
|
24
24
|
/** Callbacks for agent lifecycle events */
|
|
25
25
|
callbacks?: OrchestratorCallbacks;
|
|
26
|
+
/** Custom workflow template directory path */
|
|
27
|
+
templateDir?: string;
|
|
26
28
|
}
|
|
27
29
|
export interface OrchestratorCallbacks {
|
|
28
30
|
onIssueSelected?: (issue: OrchestratorIssue) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/orchestrator-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAA;AAM7B,MAAM,WAAW,wBAAwB;IACvC,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAA;IACpB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6CAA6C;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kDAAkD;IAClD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"orchestrator-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/orchestrator-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAA;AAM7B,MAAM,WAAW,wBAAwB;IACvC,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAA;IACpB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6CAA6C;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kDAAkD;IAClD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,qBAAqB,CAAA;IACjC,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACpD,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IAC5C,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IAC/C,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAC1D,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;CAClD;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAA;IAChD,SAAS,EAAE,YAAY,EAAE,CAAA;CAC1B;AAMD,wBAAgB,UAAU,IAAI,MAAM,CASnC;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAYjD;AA0CD,wBAAsB,eAAe,CACnC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,wBAAwB,CAAC,CA0FnC"}
|
|
@@ -77,12 +77,16 @@ export async function runOrchestrator(config) {
|
|
|
77
77
|
const dryRun = config.dryRun ?? false;
|
|
78
78
|
const gitRoot = config.gitRoot ?? getGitRoot();
|
|
79
79
|
const cb = config.callbacks ?? defaultCallbacks();
|
|
80
|
-
const
|
|
80
|
+
const orchestratorConfig = {
|
|
81
81
|
project: config.project,
|
|
82
82
|
maxConcurrent,
|
|
83
83
|
worktreePath: path.resolve(gitRoot, '.worktrees'),
|
|
84
84
|
linearApiKey: config.linearApiKey,
|
|
85
|
-
}
|
|
85
|
+
};
|
|
86
|
+
if (config.templateDir) {
|
|
87
|
+
orchestratorConfig.templateDir = config.templateDir;
|
|
88
|
+
}
|
|
89
|
+
const orchestrator = createOrchestrator(orchestratorConfig, {
|
|
86
90
|
onIssueSelected: cb.onIssueSelected,
|
|
87
91
|
onAgentStart: cb.onAgentStart,
|
|
88
92
|
onAgentComplete: cb.onAgentComplete,
|
package/dist/src/orchestrator.js
CHANGED
|
@@ -30,6 +30,7 @@ function parseArgs() {
|
|
|
30
30
|
single: undefined,
|
|
31
31
|
wait: true,
|
|
32
32
|
dryRun: false,
|
|
33
|
+
templates: undefined,
|
|
33
34
|
};
|
|
34
35
|
for (let i = 0; i < args.length; i++) {
|
|
35
36
|
const arg = args[i];
|
|
@@ -49,6 +50,9 @@ function parseArgs() {
|
|
|
49
50
|
case '--dry-run':
|
|
50
51
|
result.dryRun = true;
|
|
51
52
|
break;
|
|
53
|
+
case '--templates':
|
|
54
|
+
result.templates = args[++i];
|
|
55
|
+
break;
|
|
52
56
|
case '--help':
|
|
53
57
|
case '-h':
|
|
54
58
|
printHelp();
|
|
@@ -70,6 +74,7 @@ Options:
|
|
|
70
74
|
--single <id> Process a single issue by ID
|
|
71
75
|
--no-wait Don't wait for agents to complete
|
|
72
76
|
--dry-run Show what would be done without executing
|
|
77
|
+
--templates <path> Custom workflow template directory
|
|
73
78
|
--help, -h Show this help message
|
|
74
79
|
|
|
75
80
|
Environment:
|
|
@@ -113,6 +118,7 @@ async function main() {
|
|
|
113
118
|
single: args.single,
|
|
114
119
|
wait: args.wait,
|
|
115
120
|
dryRun: args.dryRun,
|
|
121
|
+
templateDir: args.templates,
|
|
116
122
|
});
|
|
117
123
|
if (!args.single && !args.dryRun) {
|
|
118
124
|
console.log('');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supaku/agentfactory-cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI tools for AgentFactory — local orchestrator, remote worker, queue admin",
|
|
6
6
|
"author": "Supaku (https://supaku.com)",
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"af-cleanup": "./dist/src/cleanup.js",
|
|
35
35
|
"af-queue-admin": "./dist/src/queue-admin.js",
|
|
36
36
|
"af-analyze-logs": "./dist/src/analyze-logs.js",
|
|
37
|
-
"af-linear": "./dist/src/linear.js"
|
|
37
|
+
"af-linear": "./dist/src/linear.js",
|
|
38
|
+
"af-governor": "./dist/src/governor.js"
|
|
38
39
|
},
|
|
39
40
|
"main": "./dist/src/index.js",
|
|
40
41
|
"module": "./dist/src/index.js",
|
|
@@ -88,9 +89,9 @@
|
|
|
88
89
|
],
|
|
89
90
|
"dependencies": {
|
|
90
91
|
"dotenv": "^17.2.3",
|
|
91
|
-
"@supaku/agentfactory": "0.7.
|
|
92
|
-
"@supaku/agentfactory-linear": "0.7.
|
|
93
|
-
"@supaku/agentfactory-server": "0.7.
|
|
92
|
+
"@supaku/agentfactory": "0.7.10",
|
|
93
|
+
"@supaku/agentfactory-linear": "0.7.10",
|
|
94
|
+
"@supaku/agentfactory-server": "0.7.10"
|
|
94
95
|
},
|
|
95
96
|
"devDependencies": {
|
|
96
97
|
"@types/node": "^22.5.4",
|