@renseiai/agentfactory-cli 0.8.0
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/LICENSE +21 -0
- package/README.md +123 -0
- package/dist/src/agent.d.ts +20 -0
- package/dist/src/agent.d.ts.map +1 -0
- package/dist/src/agent.js +109 -0
- package/dist/src/analyze-logs.d.ts +26 -0
- package/dist/src/analyze-logs.d.ts.map +1 -0
- package/dist/src/analyze-logs.js +152 -0
- package/dist/src/cleanup.d.ts +17 -0
- package/dist/src/cleanup.d.ts.map +1 -0
- package/dist/src/cleanup.js +111 -0
- package/dist/src/governor.d.ts +26 -0
- package/dist/src/governor.d.ts.map +1 -0
- package/dist/src/governor.js +305 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +76 -0
- package/dist/src/lib/agent-runner.d.ts +28 -0
- package/dist/src/lib/agent-runner.d.ts.map +1 -0
- package/dist/src/lib/agent-runner.js +272 -0
- package/dist/src/lib/analyze-logs-runner.d.ts +47 -0
- package/dist/src/lib/analyze-logs-runner.d.ts.map +1 -0
- package/dist/src/lib/analyze-logs-runner.js +216 -0
- package/dist/src/lib/auto-updater.d.ts +40 -0
- package/dist/src/lib/auto-updater.d.ts.map +1 -0
- package/dist/src/lib/auto-updater.js +109 -0
- package/dist/src/lib/cleanup-runner.d.ts +29 -0
- package/dist/src/lib/cleanup-runner.d.ts.map +1 -0
- package/dist/src/lib/cleanup-runner.js +295 -0
- package/dist/src/lib/governor-dependencies.d.ts +23 -0
- package/dist/src/lib/governor-dependencies.d.ts.map +1 -0
- package/dist/src/lib/governor-dependencies.js +361 -0
- package/dist/src/lib/governor-logger.d.ts +30 -0
- package/dist/src/lib/governor-logger.d.ts.map +1 -0
- package/dist/src/lib/governor-logger.js +210 -0
- package/dist/src/lib/governor-runner.d.ts +103 -0
- package/dist/src/lib/governor-runner.d.ts.map +1 -0
- package/dist/src/lib/governor-runner.js +210 -0
- package/dist/src/lib/linear-runner.d.ts +8 -0
- package/dist/src/lib/linear-runner.d.ts.map +1 -0
- package/dist/src/lib/linear-runner.js +7 -0
- package/dist/src/lib/orchestrator-runner.d.ts +51 -0
- package/dist/src/lib/orchestrator-runner.d.ts.map +1 -0
- package/dist/src/lib/orchestrator-runner.js +151 -0
- package/dist/src/lib/queue-admin-runner.d.ts +30 -0
- package/dist/src/lib/queue-admin-runner.d.ts.map +1 -0
- package/dist/src/lib/queue-admin-runner.js +378 -0
- package/dist/src/lib/sync-routes-runner.d.ts +28 -0
- package/dist/src/lib/sync-routes-runner.d.ts.map +1 -0
- package/dist/src/lib/sync-routes-runner.js +110 -0
- package/dist/src/lib/version.d.ts +35 -0
- package/dist/src/lib/version.d.ts.map +1 -0
- package/dist/src/lib/version.js +168 -0
- package/dist/src/lib/worker-fleet-runner.d.ts +32 -0
- package/dist/src/lib/worker-fleet-runner.d.ts.map +1 -0
- package/dist/src/lib/worker-fleet-runner.js +256 -0
- package/dist/src/lib/worker-runner.d.ts +33 -0
- package/dist/src/lib/worker-runner.d.ts.map +1 -0
- package/dist/src/lib/worker-runner.js +781 -0
- package/dist/src/linear.d.ts +37 -0
- package/dist/src/linear.d.ts.map +1 -0
- package/dist/src/linear.js +118 -0
- package/dist/src/orchestrator.d.ts +21 -0
- package/dist/src/orchestrator.d.ts.map +1 -0
- package/dist/src/orchestrator.js +190 -0
- package/dist/src/queue-admin.d.ts +25 -0
- package/dist/src/queue-admin.d.ts.map +1 -0
- package/dist/src/queue-admin.js +96 -0
- package/dist/src/sync-routes.d.ts +17 -0
- package/dist/src/sync-routes.d.ts.map +1 -0
- package/dist/src/sync-routes.js +100 -0
- package/dist/src/worker-fleet.d.ts +25 -0
- package/dist/src/worker-fleet.d.ts.map +1 -0
- package/dist/src/worker-fleet.js +140 -0
- package/dist/src/worker.d.ts +26 -0
- package/dist/src/worker.d.ts.map +1 -0
- package/dist/src/worker.js +135 -0
- package/package.json +175 -0
|
@@ -0,0 +1,103 @@
|
|
|
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, EventDrivenGovernor, type GovernorDependencies, type GovernorEventBus, type EventDeduplicator } from '@renseiai/agentfactory';
|
|
9
|
+
import type { ScanResult } from '@renseiai/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: false) */
|
|
18
|
+
enableAutoResearch?: boolean;
|
|
19
|
+
/** Enable auto-backlog-creation from Icebox (default: false) */
|
|
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
|
+
/** Governor execution mode (default: 'poll-only') */
|
|
34
|
+
mode?: 'poll-only' | 'event-driven';
|
|
35
|
+
/** Event bus for event-driven mode (created automatically if not provided) */
|
|
36
|
+
eventBus?: GovernorEventBus;
|
|
37
|
+
/** Event deduplicator for event-driven mode (created automatically if not provided) */
|
|
38
|
+
deduplicator?: EventDeduplicator;
|
|
39
|
+
}
|
|
40
|
+
export interface GovernorRunnerCallbacks {
|
|
41
|
+
onScanComplete?: (results: ScanResult[]) => void | Promise<void>;
|
|
42
|
+
onError?: (error: Error) => void;
|
|
43
|
+
}
|
|
44
|
+
export interface GovernorRunnerResult {
|
|
45
|
+
governor: WorkflowGovernor | EventDrivenGovernor;
|
|
46
|
+
/** Only populated in --once mode (poll-only) */
|
|
47
|
+
scanResults?: ScanResult[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Start the Workflow Governor with the given configuration.
|
|
51
|
+
*
|
|
52
|
+
* In `poll-only` mode (default):
|
|
53
|
+
* - `once` mode: runs a single scan pass and returns the results.
|
|
54
|
+
* - Otherwise: starts the scan loop and returns the governor instance
|
|
55
|
+
* (caller is responsible for calling `governor.stop()` on shutdown).
|
|
56
|
+
*
|
|
57
|
+
* In `event-driven` mode:
|
|
58
|
+
* - Creates an EventDrivenGovernor with an event bus and optional deduplicator.
|
|
59
|
+
* - Starts the event loop and periodic poll sweep.
|
|
60
|
+
* - `once` mode is not supported in event-driven mode (falls back to poll-only).
|
|
61
|
+
*/
|
|
62
|
+
export declare function runGovernor(config: GovernorRunnerConfig): Promise<GovernorRunnerResult>;
|
|
63
|
+
export interface GovernorCLIArgs {
|
|
64
|
+
projects: string[];
|
|
65
|
+
scanIntervalMs: number;
|
|
66
|
+
maxConcurrentDispatches: number;
|
|
67
|
+
enableAutoResearch: boolean;
|
|
68
|
+
enableAutoBacklogCreation: boolean;
|
|
69
|
+
enableAutoDevelopment: boolean;
|
|
70
|
+
enableAutoQA: boolean;
|
|
71
|
+
enableAutoAcceptance: boolean;
|
|
72
|
+
once: boolean;
|
|
73
|
+
mode: 'poll-only' | 'event-driven';
|
|
74
|
+
autoUpdate?: boolean;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Parse CLI arguments for the governor command.
|
|
78
|
+
*
|
|
79
|
+
* Usage:
|
|
80
|
+
* agentfactory governor --project <name> [--project <name>] [options]
|
|
81
|
+
*
|
|
82
|
+
* Options:
|
|
83
|
+
* --project <name> Project to scan (can be repeated)
|
|
84
|
+
* --scan-interval <ms> Scan interval in milliseconds (default: 60000)
|
|
85
|
+
* --max-dispatches <n> Maximum concurrent dispatches per scan (default: 3)
|
|
86
|
+
* --auto-research Enable auto-research from Icebox (default: off)
|
|
87
|
+
* --auto-backlog-creation Enable auto-backlog-creation from Icebox (default: off)
|
|
88
|
+
* --no-auto-research Disable auto-research (explicit override)
|
|
89
|
+
* --no-auto-backlog-creation Disable auto-backlog-creation (explicit override)
|
|
90
|
+
* --no-auto-development Disable auto-development from Backlog
|
|
91
|
+
* --no-auto-qa Disable auto-QA from Finished
|
|
92
|
+
* --no-auto-acceptance Disable auto-acceptance from Delivered
|
|
93
|
+
* --once Run a single scan pass and exit
|
|
94
|
+
* --auto-update Enable automatic updates
|
|
95
|
+
* --no-auto-update Disable automatic updates
|
|
96
|
+
* --help, -h Show help
|
|
97
|
+
*/
|
|
98
|
+
export declare function parseGovernorArgs(argv?: string[]): GovernorCLIArgs;
|
|
99
|
+
/**
|
|
100
|
+
* Print help text for the governor command.
|
|
101
|
+
*/
|
|
102
|
+
export declare function printGovernorHelp(): void;
|
|
103
|
+
//# 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,mBAAmB,EAGnB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAEvB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAIV,UAAU,EACX,MAAM,wBAAwB,CAAA;AAM/B,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,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,gEAAgE;IAChE,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;IACnC,qDAAqD;IACrD,IAAI,CAAC,EAAE,WAAW,GAAG,cAAc,CAAA;IACnC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,gBAAgB,CAAA;IAC3B,uFAAuF;IACvF,YAAY,CAAC,EAAE,iBAAiB,CAAA;CACjC;AAED,MAAM,WAAW,uBAAuB;IACtC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,gBAAgB,GAAG,mBAAmB,CAAA;IAChD,gDAAgD;IAChD,WAAW,CAAC,EAAE,UAAU,EAAE,CAAA;CAC3B;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,oBAAoB,CAAC,CAyD/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;IACb,IAAI,EAAE,WAAW,GAAG,cAAc,CAAA;IAClC,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,eAAe,CAmEzF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CA8CxC"}
|
|
@@ -0,0 +1,210 @@
|
|
|
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, EventDrivenGovernor, InMemoryEventBus, InMemoryEventDeduplicator, } from '@renseiai/agentfactory';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Runner
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* Start the Workflow Governor with the given configuration.
|
|
14
|
+
*
|
|
15
|
+
* In `poll-only` mode (default):
|
|
16
|
+
* - `once` mode: runs a single scan pass and returns the results.
|
|
17
|
+
* - Otherwise: starts the scan loop and returns the governor instance
|
|
18
|
+
* (caller is responsible for calling `governor.stop()` on shutdown).
|
|
19
|
+
*
|
|
20
|
+
* In `event-driven` mode:
|
|
21
|
+
* - Creates an EventDrivenGovernor with an event bus and optional deduplicator.
|
|
22
|
+
* - Starts the event loop and periodic poll sweep.
|
|
23
|
+
* - `once` mode is not supported in event-driven mode (falls back to poll-only).
|
|
24
|
+
*/
|
|
25
|
+
export async function runGovernor(config) {
|
|
26
|
+
const governorConfig = {
|
|
27
|
+
projects: config.projects,
|
|
28
|
+
scanIntervalMs: config.scanIntervalMs,
|
|
29
|
+
maxConcurrentDispatches: config.maxConcurrentDispatches,
|
|
30
|
+
enableAutoResearch: config.enableAutoResearch,
|
|
31
|
+
enableAutoBacklogCreation: config.enableAutoBacklogCreation,
|
|
32
|
+
enableAutoDevelopment: config.enableAutoDevelopment,
|
|
33
|
+
enableAutoQA: config.enableAutoQA,
|
|
34
|
+
enableAutoAcceptance: config.enableAutoAcceptance,
|
|
35
|
+
};
|
|
36
|
+
const mode = config.mode ?? 'poll-only';
|
|
37
|
+
// -- Event-driven mode --
|
|
38
|
+
if (mode === 'event-driven' && !config.once) {
|
|
39
|
+
const eventBus = config.eventBus ?? new InMemoryEventBus();
|
|
40
|
+
const deduplicator = config.deduplicator ?? new InMemoryEventDeduplicator();
|
|
41
|
+
const governor = new EventDrivenGovernor({
|
|
42
|
+
...governorConfig,
|
|
43
|
+
// Spread required GovernorConfig defaults so TypeScript is happy
|
|
44
|
+
projects: config.projects,
|
|
45
|
+
scanIntervalMs: config.scanIntervalMs ?? 60_000,
|
|
46
|
+
maxConcurrentDispatches: config.maxConcurrentDispatches ?? 3,
|
|
47
|
+
enableAutoResearch: config.enableAutoResearch ?? false,
|
|
48
|
+
enableAutoBacklogCreation: config.enableAutoBacklogCreation ?? false,
|
|
49
|
+
enableAutoDevelopment: config.enableAutoDevelopment ?? true,
|
|
50
|
+
enableAutoQA: config.enableAutoQA ?? true,
|
|
51
|
+
enableAutoAcceptance: config.enableAutoAcceptance ?? true,
|
|
52
|
+
humanResponseTimeoutMs: 4 * 60 * 60 * 1000,
|
|
53
|
+
eventBus,
|
|
54
|
+
deduplicator,
|
|
55
|
+
}, config.dependencies);
|
|
56
|
+
await governor.start();
|
|
57
|
+
return { governor };
|
|
58
|
+
}
|
|
59
|
+
// -- Poll-only mode (default) --
|
|
60
|
+
const governorCallbacks = {
|
|
61
|
+
onScanComplete: config.callbacks?.onScanComplete,
|
|
62
|
+
};
|
|
63
|
+
const governor = new WorkflowGovernor(governorConfig, config.dependencies, governorCallbacks);
|
|
64
|
+
// -- Single scan mode (--once) --
|
|
65
|
+
if (config.once) {
|
|
66
|
+
const results = await governor.scanOnce();
|
|
67
|
+
return { governor, scanResults: results };
|
|
68
|
+
}
|
|
69
|
+
// -- Continuous scan loop --
|
|
70
|
+
governor.start();
|
|
71
|
+
return { governor };
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Parse CLI arguments for the governor command.
|
|
75
|
+
*
|
|
76
|
+
* Usage:
|
|
77
|
+
* agentfactory governor --project <name> [--project <name>] [options]
|
|
78
|
+
*
|
|
79
|
+
* Options:
|
|
80
|
+
* --project <name> Project to scan (can be repeated)
|
|
81
|
+
* --scan-interval <ms> Scan interval in milliseconds (default: 60000)
|
|
82
|
+
* --max-dispatches <n> Maximum concurrent dispatches per scan (default: 3)
|
|
83
|
+
* --auto-research Enable auto-research from Icebox (default: off)
|
|
84
|
+
* --auto-backlog-creation Enable auto-backlog-creation from Icebox (default: off)
|
|
85
|
+
* --no-auto-research Disable auto-research (explicit override)
|
|
86
|
+
* --no-auto-backlog-creation Disable auto-backlog-creation (explicit override)
|
|
87
|
+
* --no-auto-development Disable auto-development from Backlog
|
|
88
|
+
* --no-auto-qa Disable auto-QA from Finished
|
|
89
|
+
* --no-auto-acceptance Disable auto-acceptance from Delivered
|
|
90
|
+
* --once Run a single scan pass and exit
|
|
91
|
+
* --auto-update Enable automatic updates
|
|
92
|
+
* --no-auto-update Disable automatic updates
|
|
93
|
+
* --help, -h Show help
|
|
94
|
+
*/
|
|
95
|
+
export function parseGovernorArgs(argv = process.argv.slice(2)) {
|
|
96
|
+
const result = {
|
|
97
|
+
projects: [],
|
|
98
|
+
scanIntervalMs: 60_000,
|
|
99
|
+
maxConcurrentDispatches: 3,
|
|
100
|
+
enableAutoResearch: false,
|
|
101
|
+
enableAutoBacklogCreation: false,
|
|
102
|
+
enableAutoDevelopment: true,
|
|
103
|
+
enableAutoQA: true,
|
|
104
|
+
enableAutoAcceptance: true,
|
|
105
|
+
once: false,
|
|
106
|
+
mode: 'poll-only',
|
|
107
|
+
};
|
|
108
|
+
for (let i = 0; i < argv.length; i++) {
|
|
109
|
+
const arg = argv[i];
|
|
110
|
+
switch (arg) {
|
|
111
|
+
case '--project':
|
|
112
|
+
result.projects.push(argv[++i]);
|
|
113
|
+
break;
|
|
114
|
+
case '--scan-interval':
|
|
115
|
+
result.scanIntervalMs = parseInt(argv[++i], 10);
|
|
116
|
+
break;
|
|
117
|
+
case '--max-dispatches':
|
|
118
|
+
result.maxConcurrentDispatches = parseInt(argv[++i], 10);
|
|
119
|
+
break;
|
|
120
|
+
case '--auto-research':
|
|
121
|
+
result.enableAutoResearch = true;
|
|
122
|
+
break;
|
|
123
|
+
case '--no-auto-research':
|
|
124
|
+
result.enableAutoResearch = false;
|
|
125
|
+
break;
|
|
126
|
+
case '--auto-backlog-creation':
|
|
127
|
+
result.enableAutoBacklogCreation = true;
|
|
128
|
+
break;
|
|
129
|
+
case '--no-auto-backlog-creation':
|
|
130
|
+
result.enableAutoBacklogCreation = false;
|
|
131
|
+
break;
|
|
132
|
+
case '--no-auto-development':
|
|
133
|
+
result.enableAutoDevelopment = false;
|
|
134
|
+
break;
|
|
135
|
+
case '--no-auto-qa':
|
|
136
|
+
result.enableAutoQA = false;
|
|
137
|
+
break;
|
|
138
|
+
case '--no-auto-acceptance':
|
|
139
|
+
result.enableAutoAcceptance = false;
|
|
140
|
+
break;
|
|
141
|
+
case '--auto-update':
|
|
142
|
+
result.autoUpdate = true;
|
|
143
|
+
break;
|
|
144
|
+
case '--no-auto-update':
|
|
145
|
+
result.autoUpdate = false;
|
|
146
|
+
break;
|
|
147
|
+
case '--once':
|
|
148
|
+
result.once = true;
|
|
149
|
+
break;
|
|
150
|
+
case '--mode':
|
|
151
|
+
result.mode = argv[++i];
|
|
152
|
+
break;
|
|
153
|
+
case '--help':
|
|
154
|
+
case '-h':
|
|
155
|
+
printGovernorHelp();
|
|
156
|
+
process.exit(0);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Print help text for the governor command.
|
|
163
|
+
*/
|
|
164
|
+
export function printGovernorHelp() {
|
|
165
|
+
console.log(`
|
|
166
|
+
AgentFactory Governor — Automated workflow scan loop
|
|
167
|
+
|
|
168
|
+
Usage:
|
|
169
|
+
agentfactory governor [options]
|
|
170
|
+
|
|
171
|
+
Options:
|
|
172
|
+
--project <name> Project to scan (can be repeated for multiple projects)
|
|
173
|
+
--scan-interval <ms> Scan interval in milliseconds (default: 60000)
|
|
174
|
+
--max-dispatches <n> Maximum concurrent dispatches per scan (default: 3)
|
|
175
|
+
--mode <mode> Execution mode: poll-only (default) or event-driven
|
|
176
|
+
--auto-research Enable auto-research from Icebox (default: off)
|
|
177
|
+
--auto-backlog-creation Enable auto-backlog-creation from Icebox (default: off)
|
|
178
|
+
--no-auto-development Disable auto-development from Backlog
|
|
179
|
+
--no-auto-qa Disable auto-QA from Finished
|
|
180
|
+
--no-auto-acceptance Disable auto-acceptance from Delivered
|
|
181
|
+
--once Run a single scan pass and exit
|
|
182
|
+
--help, -h Show this help message
|
|
183
|
+
|
|
184
|
+
Modes:
|
|
185
|
+
poll-only Periodic scan loop using WorkflowGovernor (default)
|
|
186
|
+
event-driven Hybrid event-driven + poll sweep using EventDrivenGovernor.
|
|
187
|
+
Reacts to events in real time with a periodic safety-net poll.
|
|
188
|
+
|
|
189
|
+
Environment:
|
|
190
|
+
LINEAR_API_KEY Required API key for Linear authentication
|
|
191
|
+
REDIS_URL Redis connection URL (required for real dependencies)
|
|
192
|
+
GOVERNOR_PROJECTS Comma-separated project names (fallback for --project)
|
|
193
|
+
|
|
194
|
+
Examples:
|
|
195
|
+
# Start the governor for a project
|
|
196
|
+
agentfactory governor --project MyProject
|
|
197
|
+
|
|
198
|
+
# Scan multiple projects with custom interval
|
|
199
|
+
agentfactory governor --project ProjectA --project ProjectB --scan-interval 30000
|
|
200
|
+
|
|
201
|
+
# Run a single scan and exit (useful for cron jobs)
|
|
202
|
+
agentfactory governor --project MyProject --once
|
|
203
|
+
|
|
204
|
+
# Disable auto-QA (only scan for development work)
|
|
205
|
+
agentfactory governor --project MyProject --no-auto-qa --no-auto-acceptance
|
|
206
|
+
|
|
207
|
+
# Use event-driven mode
|
|
208
|
+
agentfactory governor --project MyProject --mode event-driven
|
|
209
|
+
`);
|
|
210
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linear CLI Runner — re-exports from @renseiai/agentfactory (core).
|
|
3
|
+
*
|
|
4
|
+
* The canonical implementation lives in packages/core/src/tools/linear-runner.ts
|
|
5
|
+
* so both the CLI and the in-process tool plugin share a single source of truth.
|
|
6
|
+
*/
|
|
7
|
+
export { runLinear, parseLinearArgs, type LinearRunnerConfig, type LinearRunnerResult, } from '@renseiai/agentfactory';
|
|
8
|
+
//# sourceMappingURL=linear-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/linear-runner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,SAAS,EACT,eAAe,EACf,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,wBAAwB,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linear CLI Runner — re-exports from @renseiai/agentfactory (core).
|
|
3
|
+
*
|
|
4
|
+
* The canonical implementation lives in packages/core/src/tools/linear-runner.ts
|
|
5
|
+
* so both the CLI and the in-process tool plugin share a single source of truth.
|
|
6
|
+
*/
|
|
7
|
+
export { runLinear, parseLinearArgs, } from '@renseiai/agentfactory';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrator Runner -- Programmatic API for the orchestrator CLI.
|
|
3
|
+
*
|
|
4
|
+
* Exports `runOrchestrator()` so the orchestrator 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 { type AgentProcess, type OrchestratorIssue } from '@renseiai/agentfactory';
|
|
9
|
+
export interface OrchestratorRunnerConfig {
|
|
10
|
+
/** Linear API key for authentication */
|
|
11
|
+
linearApiKey: string;
|
|
12
|
+
/** Filter issues by project name */
|
|
13
|
+
project?: string;
|
|
14
|
+
/** Maximum concurrent agents (default: 3) */
|
|
15
|
+
max?: number;
|
|
16
|
+
/** Process a single issue by ID */
|
|
17
|
+
single?: string;
|
|
18
|
+
/** Wait for agents to complete (default: true) */
|
|
19
|
+
wait?: boolean;
|
|
20
|
+
/** Show what would be done without executing (default: false) */
|
|
21
|
+
dryRun?: boolean;
|
|
22
|
+
/** Git repository root (default: auto-detect) */
|
|
23
|
+
gitRoot?: string;
|
|
24
|
+
/** Callbacks for agent lifecycle events */
|
|
25
|
+
callbacks?: OrchestratorCallbacks;
|
|
26
|
+
/** Custom workflow template directory path */
|
|
27
|
+
templateDir?: string;
|
|
28
|
+
/** Git repository URL for worktree cloning */
|
|
29
|
+
repository?: string;
|
|
30
|
+
/** Force a specific work type (used with --single) */
|
|
31
|
+
workType?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface OrchestratorCallbacks {
|
|
34
|
+
onIssueSelected?: (issue: OrchestratorIssue) => void;
|
|
35
|
+
onAgentStart?: (agent: AgentProcess) => void;
|
|
36
|
+
onAgentComplete?: (agent: AgentProcess) => void;
|
|
37
|
+
onAgentError?: (agent: AgentProcess, error: Error) => void;
|
|
38
|
+
onAgentIncomplete?: (agent: AgentProcess) => void;
|
|
39
|
+
}
|
|
40
|
+
export interface OrchestratorRunnerResult {
|
|
41
|
+
agentsSpawned: number;
|
|
42
|
+
errors: Array<{
|
|
43
|
+
issueId: string;
|
|
44
|
+
error: Error;
|
|
45
|
+
}>;
|
|
46
|
+
completed: AgentProcess[];
|
|
47
|
+
}
|
|
48
|
+
export declare function getGitRoot(): string;
|
|
49
|
+
export declare function formatDuration(ms: number): string;
|
|
50
|
+
export declare function runOrchestrator(config: OrchestratorRunnerConfig): Promise<OrchestratorRunnerResult>;
|
|
51
|
+
//# sourceMappingURL=orchestrator-runner.d.ts.map
|
|
@@ -0,0 +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,wBAAwB,CAAA;AAM/B,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;IACpB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;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,CA6FnC"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrator Runner -- Programmatic API for the orchestrator CLI.
|
|
3
|
+
*
|
|
4
|
+
* Exports `runOrchestrator()` so the orchestrator 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 path from 'path';
|
|
9
|
+
import { execSync } from 'child_process';
|
|
10
|
+
import { createOrchestrator, } from '@renseiai/agentfactory';
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Helpers
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
export function getGitRoot() {
|
|
15
|
+
try {
|
|
16
|
+
return execSync('git rev-parse --show-toplevel', {
|
|
17
|
+
encoding: 'utf-8',
|
|
18
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
19
|
+
}).trim();
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return process.cwd();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function formatDuration(ms) {
|
|
26
|
+
const seconds = Math.floor(ms / 1000);
|
|
27
|
+
const minutes = Math.floor(seconds / 60);
|
|
28
|
+
const hours = Math.floor(minutes / 60);
|
|
29
|
+
if (hours > 0) {
|
|
30
|
+
return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
|
|
31
|
+
}
|
|
32
|
+
if (minutes > 0) {
|
|
33
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
34
|
+
}
|
|
35
|
+
return `${seconds}s`;
|
|
36
|
+
}
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Default callbacks (console.log-based, matching the original CLI output)
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
function defaultCallbacks() {
|
|
41
|
+
return {
|
|
42
|
+
onIssueSelected: (issue) => {
|
|
43
|
+
console.log(`Selected: ${issue.identifier} - ${issue.title}`);
|
|
44
|
+
console.log(` URL: ${issue.url}`);
|
|
45
|
+
console.log(` Labels: ${issue.labels.join(', ') || 'none'}`);
|
|
46
|
+
},
|
|
47
|
+
onAgentStart: (agent) => {
|
|
48
|
+
console.log(`Agent started: ${agent.identifier} (PID: ${agent.pid})`);
|
|
49
|
+
console.log(` Worktree: ${agent.worktreePath}`);
|
|
50
|
+
},
|
|
51
|
+
onAgentComplete: (agent) => {
|
|
52
|
+
const duration = agent.completedAt
|
|
53
|
+
? formatDuration(agent.completedAt.getTime() - agent.startedAt.getTime())
|
|
54
|
+
: 'unknown';
|
|
55
|
+
console.log(`Agent completed: ${agent.identifier} (${duration})`);
|
|
56
|
+
},
|
|
57
|
+
onAgentError: (_agent, error) => {
|
|
58
|
+
console.error(`Agent failed: ${_agent.identifier}`);
|
|
59
|
+
console.error(` Error: ${error.message}`);
|
|
60
|
+
},
|
|
61
|
+
onAgentIncomplete: (agent) => {
|
|
62
|
+
const duration = agent.completedAt
|
|
63
|
+
? formatDuration(agent.completedAt.getTime() - agent.startedAt.getTime())
|
|
64
|
+
: 'unknown';
|
|
65
|
+
console.warn(`Agent incomplete: ${agent.identifier} (${duration})`);
|
|
66
|
+
console.warn(` Reason: ${agent.incompleteReason ?? 'unknown'}`);
|
|
67
|
+
console.warn(` Worktree preserved: ${agent.worktreePath}`);
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Runner
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
export async function runOrchestrator(config) {
|
|
75
|
+
const maxConcurrent = config.max ?? 3;
|
|
76
|
+
const wait = config.wait ?? true;
|
|
77
|
+
const dryRun = config.dryRun ?? false;
|
|
78
|
+
const gitRoot = config.gitRoot ?? getGitRoot();
|
|
79
|
+
const cb = config.callbacks ?? defaultCallbacks();
|
|
80
|
+
const orchestratorConfig = {
|
|
81
|
+
project: config.project,
|
|
82
|
+
maxConcurrent,
|
|
83
|
+
worktreePath: path.resolve(gitRoot, '.worktrees'),
|
|
84
|
+
linearApiKey: config.linearApiKey,
|
|
85
|
+
};
|
|
86
|
+
if (config.templateDir) {
|
|
87
|
+
orchestratorConfig.templateDir = config.templateDir;
|
|
88
|
+
}
|
|
89
|
+
if (config.repository) {
|
|
90
|
+
orchestratorConfig.repository = config.repository;
|
|
91
|
+
}
|
|
92
|
+
const orchestrator = createOrchestrator(orchestratorConfig, {
|
|
93
|
+
onIssueSelected: cb.onIssueSelected,
|
|
94
|
+
onAgentStart: cb.onAgentStart,
|
|
95
|
+
onAgentComplete: cb.onAgentComplete,
|
|
96
|
+
onAgentError: cb.onAgentError,
|
|
97
|
+
onAgentIncomplete: cb.onAgentIncomplete,
|
|
98
|
+
});
|
|
99
|
+
const result = {
|
|
100
|
+
agentsSpawned: 0,
|
|
101
|
+
errors: [],
|
|
102
|
+
completed: [],
|
|
103
|
+
};
|
|
104
|
+
// --single mode ----------------------------------------------------------
|
|
105
|
+
if (config.single) {
|
|
106
|
+
if (dryRun) {
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
await orchestrator.spawnAgentForIssue(config.single, undefined, config.workType);
|
|
110
|
+
result.agentsSpawned = 1;
|
|
111
|
+
if (wait) {
|
|
112
|
+
// Wire up SIGINT so callers running from a terminal can stop agents
|
|
113
|
+
const sigintHandler = () => {
|
|
114
|
+
orchestrator.stopAll();
|
|
115
|
+
};
|
|
116
|
+
process.on('SIGINT', sigintHandler);
|
|
117
|
+
try {
|
|
118
|
+
const completed = await orchestrator.waitForAll();
|
|
119
|
+
result.completed = completed;
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
process.removeListener('SIGINT', sigintHandler);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
// --dry-run mode ---------------------------------------------------------
|
|
128
|
+
if (dryRun) {
|
|
129
|
+
await orchestrator.getBacklogIssues();
|
|
130
|
+
// Nothing to spawn in dry-run; caller can inspect issues via callbacks
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
// Normal run -------------------------------------------------------------
|
|
134
|
+
const runResult = await orchestrator.run();
|
|
135
|
+
result.agentsSpawned = runResult.agents.length;
|
|
136
|
+
result.errors = runResult.errors;
|
|
137
|
+
if (wait && runResult.agents.length > 0) {
|
|
138
|
+
const sigintHandler = () => {
|
|
139
|
+
orchestrator.stopAll();
|
|
140
|
+
};
|
|
141
|
+
process.on('SIGINT', sigintHandler);
|
|
142
|
+
try {
|
|
143
|
+
const completed = await orchestrator.waitForAll();
|
|
144
|
+
result.completed = completed;
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
process.removeListener('SIGINT', sigintHandler);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue Admin Runner -- Programmatic API for the queue admin CLI.
|
|
3
|
+
*
|
|
4
|
+
* Extracts ALL command handlers from the queue-admin bin script so they can be
|
|
5
|
+
* invoked programmatically (e.g. from a Next.js route handler or test) without
|
|
6
|
+
* process.exit / dotenv / argv coupling.
|
|
7
|
+
*/
|
|
8
|
+
export type QueueAdminCommand = 'list' | 'sessions' | 'workers' | 'clear-claims' | 'clear-queue' | 'clear-all' | 'reset' | 'remove';
|
|
9
|
+
export interface QueueAdminRunnerConfig {
|
|
10
|
+
/** Command to execute */
|
|
11
|
+
command: QueueAdminCommand;
|
|
12
|
+
/** Session ID for 'remove' command (partial match) */
|
|
13
|
+
sessionId?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const C: {
|
|
16
|
+
readonly reset: "\u001B[0m";
|
|
17
|
+
readonly red: "\u001B[31m";
|
|
18
|
+
readonly green: "\u001B[32m";
|
|
19
|
+
readonly yellow: "\u001B[33m";
|
|
20
|
+
readonly cyan: "\u001B[36m";
|
|
21
|
+
readonly gray: "\u001B[90m";
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Run a queue admin command programmatically.
|
|
25
|
+
*
|
|
26
|
+
* Throws if REDIS_URL is not set or if the 'remove' command is called without
|
|
27
|
+
* a sessionId.
|
|
28
|
+
*/
|
|
29
|
+
export declare function runQueueAdmin(config: QueueAdminRunnerConfig): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=queue-admin-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-admin-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/queue-admin-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAkBH,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,UAAU,GACV,SAAS,GACT,cAAc,GACd,aAAa,GACb,WAAW,GACX,OAAO,GACP,QAAQ,CAAA;AAEZ,MAAM,WAAW,sBAAsB;IACrC,yBAAyB;IACzB,OAAO,EAAE,iBAAiB,CAAA;IAC1B,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAgBD,eAAO,MAAM,CAAC;;;;;;;CAOJ,CAAA;AAgZV;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BjF"}
|