@supaku/agentfactory-cli 0.7.11 → 0.7.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/README.md CHANGED
@@ -24,6 +24,15 @@ af-orchestrator --single PROJ-123
24
24
  # Dry run — preview what would be processed
25
25
  af-orchestrator --project MyProject --dry-run
26
26
 
27
+ # Start the Workflow Governor (event-driven + poll sweep)
28
+ af-governor --project MyProject --project OtherProject
29
+
30
+ # Governor: single scan and exit (for cron jobs)
31
+ af-governor --project MyProject --once
32
+
33
+ # Governor: poll-only mode (no event bus)
34
+ af-governor --project MyProject --mode poll-only
35
+
27
36
  # Start a remote worker
28
37
  af-worker --api-url https://your-app.vercel.app --api-key your-key
29
38
 
@@ -41,6 +50,30 @@ af-queue-admin drain
41
50
  af-analyze-logs --follow
42
51
  ```
43
52
 
53
+ ### Governor
54
+
55
+ The Workflow Governor scans projects and decides what work to dispatch based on issue status, active sessions, cooldowns, and human overrides.
56
+
57
+ **Modes:**
58
+ - `event-driven` (default) — Listens to a GovernorEventBus for real-time webhook events, with a periodic poll sweep as safety net
59
+ - `poll-only` — Periodic scan loop only
60
+
61
+ **Options:**
62
+ ```
63
+ --project <name> Project to scan (repeatable)
64
+ --scan-interval <ms> Poll interval (default: 60000 for poll-only, 300000 for event-driven)
65
+ --max-dispatches <n> Max concurrent dispatches per scan (default: 3)
66
+ --mode <mode> poll-only or event-driven (default: event-driven)
67
+ --once Single scan pass and exit
68
+ --no-auto-research Disable Icebox → research
69
+ --no-auto-backlog-creation Disable Icebox → backlog-creation
70
+ --no-auto-development Disable Backlog → development
71
+ --no-auto-qa Disable Finished → QA
72
+ --no-auto-acceptance Disable Delivered → acceptance
73
+ ```
74
+
75
+ When `LINEAR_API_KEY` and `REDIS_URL` are set, the governor uses real dependencies (Linear SDK + Redis). Without them, it falls back to stub dependencies for testing.
76
+
44
77
  ## Programmatic Usage
45
78
 
46
79
  All CLI tools are available as importable functions via subpath exports:
@@ -72,10 +105,10 @@ Each function accepts a config object and returns a Promise — use them to buil
72
105
 
73
106
  | Variable | Used By | Description |
74
107
  |----------|---------|-------------|
75
- | `LINEAR_API_KEY` | orchestrator | Linear API key |
108
+ | `LINEAR_API_KEY` | orchestrator, governor | Linear API key |
109
+ | `REDIS_URL` | governor, queue-admin | Redis connection URL |
76
110
  | `WORKER_API_URL` | worker, fleet | Webhook server URL |
77
111
  | `WORKER_API_KEY` | worker, fleet | API key for authentication |
78
- | `REDIS_URL` | queue-admin | Redis connection URL |
79
112
 
80
113
  ## Related Packages
81
114
 
@@ -1 +1 @@
1
- {"version":3,"file":"governor-dependencies.d.ts","sourceRoot":"","sources":["../../../src/lib/governor-dependencies.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,KAAK,EACV,oBAAoB,EAGrB,MAAM,sBAAsB,CAAA;AA+B7B,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,iBAAiB,CAAA;CAChC;AAmFD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,sBAAsB,GAC7B,oBAAoB,CA+NtB"}
1
+ {"version":3,"file":"governor-dependencies.d.ts","sourceRoot":"","sources":["../../../src/lib/governor-dependencies.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,KAAK,EACV,oBAAoB,EAGrB,MAAM,sBAAsB,CAAA;AAgC7B,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,iBAAiB,CAAA;CAChC;AAmFD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,sBAAsB,GAC7B,oBAAoB,CAsPtB"}
@@ -6,7 +6,7 @@
6
6
  * (from @supaku/agentfactory-server).
7
7
  */
8
8
  import { isHeld as checkIsHeld, getOverridePriority as checkOverridePriority, } from '@supaku/agentfactory';
9
- import { getSessionStateByIssue, didJustFailQA, getWorkflowState, RedisProcessingStateStorage, queueWork, } from '@supaku/agentfactory-server';
9
+ import { getSessionStateByIssue, didJustFailQA, getWorkflowState, RedisProcessingStateStorage, queueWork, storeSessionState, } from '@supaku/agentfactory-server';
10
10
  // ---------------------------------------------------------------------------
11
11
  // Logging
12
12
  // ---------------------------------------------------------------------------
@@ -244,14 +244,17 @@ export function createRealDependencies(config) {
244
244
  try {
245
245
  const workType = actionToWorkType(action);
246
246
  log.info('Dispatching work', { issueId, action, workType });
247
- // Fetch the issue to get its identifier for the queue entry
247
+ // Fetch the issue to get its identifier and project for the queue entry
248
248
  let issueIdentifier = issueId;
249
+ let projectName;
249
250
  try {
250
251
  const issue = await config.linearClient.getIssue(issueId);
251
252
  issueIdentifier = issue.identifier;
253
+ const project = await issue.project;
254
+ projectName = project?.name;
252
255
  }
253
256
  catch {
254
- log.warn('Could not fetch issue identifier, using issueId', { issueId });
257
+ log.warn('Could not fetch issue details, using issueId', { issueId });
255
258
  }
256
259
  // Create a Linear Agent Session on the issue so the UI shows activity
257
260
  let sessionId;
@@ -267,14 +270,31 @@ export function createRealDependencies(config) {
267
270
  error: err instanceof Error ? err.message : String(err),
268
271
  });
269
272
  }
273
+ const finalSessionId = sessionId ?? `governor-${issueId}-${Date.now()}`;
274
+ const now = Date.now();
275
+ // Register a pending session FIRST so hasActiveSession() returns true
276
+ // immediately, preventing re-dispatch on subsequent poll sweeps.
277
+ await storeSessionState(finalSessionId, {
278
+ issueId,
279
+ issueIdentifier,
280
+ claudeSessionId: null,
281
+ worktreePath: '',
282
+ status: 'pending',
283
+ workerId: null,
284
+ queuedAt: now,
285
+ priority: 3,
286
+ workType: workType,
287
+ projectName,
288
+ });
270
289
  // Queue the work item for a worker to pick up
271
290
  const queuedWork = {
272
- sessionId: sessionId ?? `governor-${issueId}-${Date.now()}`,
291
+ sessionId: finalSessionId,
273
292
  issueId,
274
293
  issueIdentifier,
275
- priority: 3, // Default priority; PRIORITY overrides are handled by the governor sort
276
- queuedAt: Date.now(),
294
+ priority: 3,
295
+ queuedAt: now,
277
296
  workType: workType,
297
+ projectName,
278
298
  };
279
299
  const queued = await queueWork(queuedWork);
280
300
  if (!queued) {
@@ -289,7 +309,8 @@ export function createRealDependencies(config) {
289
309
  issueIdentifier,
290
310
  action,
291
311
  workType,
292
- sessionId: queuedWork.sessionId,
312
+ projectName,
313
+ sessionId: finalSessionId,
293
314
  });
294
315
  }
295
316
  }
@@ -14,9 +14,9 @@ export interface GovernorRunnerConfig {
14
14
  scanIntervalMs?: number;
15
15
  /** Maximum concurrent dispatches per scan (default: 3) */
16
16
  maxConcurrentDispatches?: number;
17
- /** Enable auto-research from Icebox (default: true) */
17
+ /** Enable auto-research from Icebox (default: false) */
18
18
  enableAutoResearch?: boolean;
19
- /** Enable auto-backlog-creation from Icebox (default: true) */
19
+ /** Enable auto-backlog-creation from Icebox (default: false) */
20
20
  enableAutoBacklogCreation?: boolean;
21
21
  /** Enable auto-development from Backlog (default: true) */
22
22
  enableAutoDevelopment?: boolean;
@@ -82,8 +82,10 @@ export interface GovernorCLIArgs {
82
82
  * --project <name> Project to scan (can be repeated)
83
83
  * --scan-interval <ms> Scan interval in milliseconds (default: 60000)
84
84
  * --max-dispatches <n> Maximum concurrent dispatches per scan (default: 3)
85
- * --no-auto-research Disable auto-research from Icebox
86
- * --no-auto-backlog-creation Disable auto-backlog-creation from Icebox
85
+ * --auto-research Enable auto-research from Icebox (default: off)
86
+ * --auto-backlog-creation Enable auto-backlog-creation from Icebox (default: off)
87
+ * --no-auto-research Disable auto-research (explicit override)
88
+ * --no-auto-backlog-creation Disable auto-backlog-creation (explicit override)
87
89
  * --no-auto-development Disable auto-development from Backlog
88
90
  * --no-auto-qa Disable auto-QA from Finished
89
91
  * --no-auto-acceptance Disable auto-acceptance from Delivered
@@ -1 +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,EACvB,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;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,CAAA;IAChD,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,CAuD/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;CACnC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,eAAe,CAuDzF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CA6CxC"}
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,EACvB,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,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,CAAA;IAChD,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,CAuD/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;CACnC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,eAAe,CA6DzF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CA6CxC"}
@@ -44,8 +44,8 @@ export async function runGovernor(config) {
44
44
  projects: config.projects,
45
45
  scanIntervalMs: config.scanIntervalMs ?? 60_000,
46
46
  maxConcurrentDispatches: config.maxConcurrentDispatches ?? 3,
47
- enableAutoResearch: config.enableAutoResearch ?? true,
48
- enableAutoBacklogCreation: config.enableAutoBacklogCreation ?? true,
47
+ enableAutoResearch: config.enableAutoResearch ?? false,
48
+ enableAutoBacklogCreation: config.enableAutoBacklogCreation ?? false,
49
49
  enableAutoDevelopment: config.enableAutoDevelopment ?? true,
50
50
  enableAutoQA: config.enableAutoQA ?? true,
51
51
  enableAutoAcceptance: config.enableAutoAcceptance ?? true,
@@ -78,8 +78,10 @@ export async function runGovernor(config) {
78
78
  * --project <name> Project to scan (can be repeated)
79
79
  * --scan-interval <ms> Scan interval in milliseconds (default: 60000)
80
80
  * --max-dispatches <n> Maximum concurrent dispatches per scan (default: 3)
81
- * --no-auto-research Disable auto-research from Icebox
82
- * --no-auto-backlog-creation Disable auto-backlog-creation from Icebox
81
+ * --auto-research Enable auto-research from Icebox (default: off)
82
+ * --auto-backlog-creation Enable auto-backlog-creation from Icebox (default: off)
83
+ * --no-auto-research Disable auto-research (explicit override)
84
+ * --no-auto-backlog-creation Disable auto-backlog-creation (explicit override)
83
85
  * --no-auto-development Disable auto-development from Backlog
84
86
  * --no-auto-qa Disable auto-QA from Finished
85
87
  * --no-auto-acceptance Disable auto-acceptance from Delivered
@@ -91,8 +93,8 @@ export function parseGovernorArgs(argv = process.argv.slice(2)) {
91
93
  projects: [],
92
94
  scanIntervalMs: 60_000,
93
95
  maxConcurrentDispatches: 3,
94
- enableAutoResearch: true,
95
- enableAutoBacklogCreation: true,
96
+ enableAutoResearch: false,
97
+ enableAutoBacklogCreation: false,
96
98
  enableAutoDevelopment: true,
97
99
  enableAutoQA: true,
98
100
  enableAutoAcceptance: true,
@@ -111,9 +113,15 @@ export function parseGovernorArgs(argv = process.argv.slice(2)) {
111
113
  case '--max-dispatches':
112
114
  result.maxConcurrentDispatches = parseInt(argv[++i], 10);
113
115
  break;
116
+ case '--auto-research':
117
+ result.enableAutoResearch = true;
118
+ break;
114
119
  case '--no-auto-research':
115
120
  result.enableAutoResearch = false;
116
121
  break;
122
+ case '--auto-backlog-creation':
123
+ result.enableAutoBacklogCreation = true;
124
+ break;
117
125
  case '--no-auto-backlog-creation':
118
126
  result.enableAutoBacklogCreation = false;
119
127
  break;
@@ -155,8 +163,8 @@ Options:
155
163
  --scan-interval <ms> Scan interval in milliseconds (default: 60000)
156
164
  --max-dispatches <n> Maximum concurrent dispatches per scan (default: 3)
157
165
  --mode <mode> Execution mode: poll-only (default) or event-driven
158
- --no-auto-research Disable auto-research from Icebox
159
- --no-auto-backlog-creation Disable auto-backlog-creation from Icebox
166
+ --auto-research Enable auto-research from Icebox (default: off)
167
+ --auto-backlog-creation Enable auto-backlog-creation from Icebox (default: off)
160
168
  --no-auto-development Disable auto-development from Backlog
161
169
  --no-auto-qa Disable auto-QA from Finished
162
170
  --no-auto-acceptance Disable auto-acceptance from Delivered
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supaku/agentfactory-cli",
3
- "version": "0.7.11",
3
+ "version": "0.7.13",
4
4
  "type": "module",
5
5
  "description": "CLI tools for AgentFactory — local orchestrator, remote worker, queue admin",
6
6
  "author": "Supaku (https://supaku.com)",
@@ -89,9 +89,9 @@
89
89
  ],
90
90
  "dependencies": {
91
91
  "dotenv": "^17.2.3",
92
- "@supaku/agentfactory-linear": "0.7.11",
93
- "@supaku/agentfactory": "0.7.11",
94
- "@supaku/agentfactory-server": "0.7.11"
92
+ "@supaku/agentfactory-server": "0.7.13",
93
+ "@supaku/agentfactory-linear": "0.7.13",
94
+ "@supaku/agentfactory": "0.7.13"
95
95
  },
96
96
  "devDependencies": {
97
97
  "@types/node": "^22.5.4",