@supaku/agentfactory-nextjs 0.7.10 → 0.7.12
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 +20 -0
- package/dist/src/handlers/sessions/status.d.ts.map +1 -1
- package/dist/src/handlers/sessions/status.js +25 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/types.d.ts +14 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/webhook/governor-bridge.d.ts +23 -0
- package/dist/src/webhook/governor-bridge.d.ts.map +1 -0
- package/dist/src/webhook/governor-bridge.js +36 -0
- package/dist/src/webhook/handlers/issue-updated.d.ts.map +1 -1
- package/dist/src/webhook/handlers/issue-updated.js +29 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -94,11 +94,31 @@ const routes = createAllRoutes({
|
|
|
94
94
|
autoAcceptanceExcludeLabels: [],
|
|
95
95
|
},
|
|
96
96
|
|
|
97
|
+
// Optional: governor integration
|
|
98
|
+
// 'direct' (default) — webhooks dispatch work directly
|
|
99
|
+
// 'event-bridge' — dispatch AND publish governor events (dual-write)
|
|
100
|
+
// 'governor-only' — only publish events, governor handles all dispatch
|
|
101
|
+
governorMode: 'event-bridge',
|
|
102
|
+
|
|
97
103
|
// Optional: OAuth
|
|
98
104
|
oauth: { clientId: '...', clientSecret: '...' },
|
|
99
105
|
})
|
|
100
106
|
```
|
|
101
107
|
|
|
108
|
+
### Governor Event Bridge
|
|
109
|
+
|
|
110
|
+
When `governorMode` is `event-bridge` or `governor-only`, webhook handlers publish events to a `GovernorEventBus`. Wire the bus at server startup:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { RedisEventBus } from '@supaku/agentfactory-server'
|
|
114
|
+
import { setGovernorEventBus } from '@supaku/agentfactory-nextjs'
|
|
115
|
+
|
|
116
|
+
const eventBus = new RedisEventBus()
|
|
117
|
+
setGovernorEventBus(eventBus)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The governor process (running `af-governor`) consumes from the same Redis Stream and dispatches work through the shared Redis queue.
|
|
121
|
+
|
|
102
122
|
## Middleware
|
|
103
123
|
|
|
104
124
|
Handles API key auth, rate limiting, and webhook signature verification:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../src/handlers/sessions/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../src/handlers/sessions/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAoBvD,UAAU,WAAW;IACnB,MAAM,EAAE,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAChC;AAYD,wBAAgB,8BAA8B,KACjB,SAAS,WAAW,EAAE,YAAY,WAAW,oCA6JzE;AAED,wBAAgB,6BAA6B,KACjB,SAAS,WAAW,EAAE,YAAY,WAAW;;;4EAsBxE"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { NextResponse } from 'next/server';
|
|
7
7
|
import { requireWorkerAuth } from '../../middleware/worker-auth.js';
|
|
8
|
-
import { getSessionState, updateSessionStatus, updateSessionCostData, updateClaudeSessionId, startSession, removeWorkerSession, releaseClaim, markAgentWorked, releaseIssueLock, promoteNextPendingWork, createLogger, } from '@supaku/agentfactory-server';
|
|
8
|
+
import { getSessionState, updateSessionStatus, updateSessionCostData, updateClaudeSessionId, startSession, removeWorkerSession, releaseClaim, markAgentWorked, releaseIssueLock, promoteNextPendingWork, RedisProcessingStateStorage, createLogger, } from '@supaku/agentfactory-server';
|
|
9
9
|
const log = createLogger('api:sessions:status');
|
|
10
10
|
const VALID_STATUSES = [
|
|
11
11
|
'running',
|
|
@@ -73,6 +73,30 @@ export function createSessionStatusPostHandler() {
|
|
|
73
73
|
catch (err) {
|
|
74
74
|
log.error('Failed to mark agent-worked', { sessionId, error: err });
|
|
75
75
|
}
|
|
76
|
+
// Mark research/backlog-creation phases as completed so the
|
|
77
|
+
// governor does not re-dispatch the same top-of-funnel work.
|
|
78
|
+
const phase = session.workType === 'research' ? 'research'
|
|
79
|
+
: session.workType === 'backlog-creation' ? 'backlog-creation'
|
|
80
|
+
: null;
|
|
81
|
+
if (phase) {
|
|
82
|
+
try {
|
|
83
|
+
const processingState = new RedisProcessingStateStorage();
|
|
84
|
+
await processingState.markPhaseCompleted(session.issueId, phase, sessionId);
|
|
85
|
+
log.info('Processing phase marked complete', {
|
|
86
|
+
issueId: session.issueId,
|
|
87
|
+
phase,
|
|
88
|
+
sessionId,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
log.error('Failed to mark processing phase complete', {
|
|
93
|
+
sessionId,
|
|
94
|
+
issueId: session.issueId,
|
|
95
|
+
phase,
|
|
96
|
+
error: err,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
76
100
|
}
|
|
77
101
|
await releaseClaim(sessionId);
|
|
78
102
|
await removeWorkerSession(workerId, sessionId);
|
package/dist/src/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export { verifyCronAuth } from './middleware/cron-auth.js';
|
|
|
20
20
|
export { verifyWorkerAuth, requireWorkerAuth, unauthorizedResponse, isWorkerAuthConfigured, } from './middleware/worker-auth.js';
|
|
21
21
|
export { createWebhookHandler } from './webhook/processor.js';
|
|
22
22
|
export { verifyWebhookSignature } from './webhook/signature.js';
|
|
23
|
+
export { setGovernorEventBus, getGovernorEventBus, publishGovernorEvent } from './webhook/governor-bridge.js';
|
|
23
24
|
export { createWorkerRegisterHandler } from './handlers/workers/register.js';
|
|
24
25
|
export { createWorkerListHandler } from './handlers/workers/list.js';
|
|
25
26
|
export { createWorkerGetHandler, createWorkerDeleteHandler } from './handlers/workers/get-delete.js';
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,YAAY,GACb,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAG9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAA;AACzE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAG/D,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAG7D,OAAO,EACL,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,yBAAyB,CAAA;AAChC,YAAY,EACV,yBAAyB,EACzB,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,yBAAyB,CAAA;AAGhC,OAAO,EAAE,iCAAiC,EAAE,MAAM,6BAA6B,CAAA;AAC/E,YAAY,EAAE,iCAAiC,EAAE,MAAM,6BAA6B,CAAA;AAGpF,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,6BAA6B,CAAA;AAGpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.js
CHANGED
|
@@ -21,6 +21,8 @@ export { verifyWorkerAuth, requireWorkerAuth, unauthorizedResponse, isWorkerAuth
|
|
|
21
21
|
// Webhook
|
|
22
22
|
export { createWebhookHandler } from './webhook/processor.js';
|
|
23
23
|
export { verifyWebhookSignature } from './webhook/signature.js';
|
|
24
|
+
// Governor bridge
|
|
25
|
+
export { setGovernorEventBus, getGovernorEventBus, publishGovernorEvent } from './webhook/governor-bridge.js';
|
|
24
26
|
// Individual handler factories (for custom wiring)
|
|
25
27
|
// Worker handlers
|
|
26
28
|
export { createWorkerRegisterHandler } from './handlers/workers/register.js';
|
package/dist/src/types.d.ts
CHANGED
|
@@ -54,6 +54,13 @@ export interface WebhookConfig extends RouteConfig {
|
|
|
54
54
|
* Templates in this directory override built-in defaults per work type.
|
|
55
55
|
*/
|
|
56
56
|
templateDir?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Governor integration mode:
|
|
59
|
+
* - 'direct' (default): Today's behavior -- webhooks dispatch work directly
|
|
60
|
+
* - 'event-bridge': Dual-write -- webhooks dispatch AND publish governor events
|
|
61
|
+
* - 'governor-only': Events only -- webhooks publish to governor, no direct dispatch
|
|
62
|
+
*/
|
|
63
|
+
governorMode?: 'direct' | 'event-bridge' | 'governor-only';
|
|
57
64
|
}
|
|
58
65
|
/**
|
|
59
66
|
* Resolved webhook config with all defaults applied.
|
|
@@ -69,6 +76,13 @@ export interface ResolvedWebhookConfig extends RouteConfig {
|
|
|
69
76
|
buildParentAcceptanceContext?: (identifier: string, subIssues: SubIssueStatus[]) => string;
|
|
70
77
|
/** Linear project names this server handles. Empty/undefined = all projects. */
|
|
71
78
|
projects?: string[];
|
|
79
|
+
/**
|
|
80
|
+
* Governor integration mode:
|
|
81
|
+
* - 'direct' (default): Today's behavior -- webhooks dispatch work directly
|
|
82
|
+
* - 'event-bridge': Dual-write -- webhooks dispatch AND publish governor events
|
|
83
|
+
* - 'governor-only': Events only -- webhooks publish to governor, no direct dispatch
|
|
84
|
+
*/
|
|
85
|
+
governorMode?: 'direct' | 'event-bridge' | 'governor-only';
|
|
72
86
|
}
|
|
73
87
|
/**
|
|
74
88
|
* Configuration for cron-authenticated routes.
|
package/dist/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAEnG;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,GAAG,iBAAiB,CAAA;CACnF;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,oBAAoB,CAAA;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,OAAO,CAAA;IACrB,oBAAoB,EAAE,OAAO,CAAA;IAC7B,wBAAwB,EAAE,OAAO,CAAA;IACjC,gCAAgC,EAAE,OAAO,CAAA;IACzC,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,sBAAsB,EAAE,MAAM,EAAE,CAAA;IAChC,mBAAmB,EAAE,MAAM,EAAE,CAAA;IAC7B,2BAA2B,EAAE,MAAM,EAAE,CAAA;CACtC;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IACjG,wBAAwB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,aAAa,GAAG,SAAS,CAAA;IACzG,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,MAAM,CAAA;IACjD,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,MAAM,CAAA;IAClF,4BAA4B,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,MAAM,CAAA;IAC1F,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Governor Bridge
|
|
3
|
+
*
|
|
4
|
+
* Connects webhook handlers to the GovernorEventBus. When configured,
|
|
5
|
+
* webhook handlers publish events to the bus in addition to (or instead of)
|
|
6
|
+
* their normal direct-dispatch behavior.
|
|
7
|
+
*/
|
|
8
|
+
import type { GovernorEventBus, GovernorEvent } from '@supaku/agentfactory';
|
|
9
|
+
/**
|
|
10
|
+
* Configure the governor event bus for webhook bridging.
|
|
11
|
+
* Call this during server initialization when governorMode != 'direct'.
|
|
12
|
+
*/
|
|
13
|
+
export declare function setGovernorEventBus(bus: GovernorEventBus): void;
|
|
14
|
+
/**
|
|
15
|
+
* Get the configured event bus, or null if not configured.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getGovernorEventBus(): GovernorEventBus | null;
|
|
18
|
+
/**
|
|
19
|
+
* Publish a GovernorEvent if a bus is configured.
|
|
20
|
+
* Returns the event ID if published, null if no bus is configured.
|
|
21
|
+
*/
|
|
22
|
+
export declare function publishGovernorEvent(event: GovernorEvent): Promise<string | null>;
|
|
23
|
+
//# sourceMappingURL=governor-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"governor-bridge.d.ts","sourceRoot":"","sources":["../../../src/webhook/governor-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAI3E;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAE/D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,GAAG,IAAI,CAE7D;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQvF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Governor Bridge
|
|
3
|
+
*
|
|
4
|
+
* Connects webhook handlers to the GovernorEventBus. When configured,
|
|
5
|
+
* webhook handlers publish events to the bus in addition to (or instead of)
|
|
6
|
+
* their normal direct-dispatch behavior.
|
|
7
|
+
*/
|
|
8
|
+
let _eventBus = null;
|
|
9
|
+
/**
|
|
10
|
+
* Configure the governor event bus for webhook bridging.
|
|
11
|
+
* Call this during server initialization when governorMode != 'direct'.
|
|
12
|
+
*/
|
|
13
|
+
export function setGovernorEventBus(bus) {
|
|
14
|
+
_eventBus = bus;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get the configured event bus, or null if not configured.
|
|
18
|
+
*/
|
|
19
|
+
export function getGovernorEventBus() {
|
|
20
|
+
return _eventBus;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Publish a GovernorEvent if a bus is configured.
|
|
24
|
+
* Returns the event ID if published, null if no bus is configured.
|
|
25
|
+
*/
|
|
26
|
+
export async function publishGovernorEvent(event) {
|
|
27
|
+
if (!_eventBus)
|
|
28
|
+
return null;
|
|
29
|
+
try {
|
|
30
|
+
return await _eventBus.publish(event);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
console.error('[governor-bridge] Failed to publish event:', err);
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-updated.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/issue-updated.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;
|
|
1
|
+
{"version":3,"file":"issue-updated.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/issue-updated.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AA0BtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAQ3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,oBAAoB,EAC7B,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACnC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAyxB9B"}
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { NextResponse } from 'next/server';
|
|
11
11
|
import { buildFailureContextBlock } from '@supaku/agentfactory-linear';
|
|
12
|
-
import { checkIssueDeploymentStatus, formatFailedDeployments, } from '@supaku/agentfactory';
|
|
12
|
+
import { checkIssueDeploymentStatus, formatFailedDeployments, eventTimestamp, } from '@supaku/agentfactory';
|
|
13
|
+
import { publishGovernorEvent } from '../governor-bridge.js';
|
|
13
14
|
import { generateIdempotencyKey, isWebhookProcessed, storeSessionState, getSessionStateByIssue, dispatchWork, wasAgentWorked, didJustFailQA, getQAAttemptCount, recordQAAttempt, clearQAFailed, didJustQueueDevelopment, markDevelopmentQueued, didJustQueueAcceptance, markAcceptanceQueued, getWorkflowState, } from '@supaku/agentfactory-server';
|
|
14
15
|
import { emitActivity, resolveStateName, isProjectAllowed, hasExcludedLabel, getAppUrl, } from '../utils.js';
|
|
15
16
|
export async function handleIssueUpdated(config, payload, log) {
|
|
@@ -26,6 +27,33 @@ export async function handleIssueUpdated(config, payload, log) {
|
|
|
26
27
|
return NextResponse.json({ success: true, skipped: true, reason: 'project_not_allowed' });
|
|
27
28
|
}
|
|
28
29
|
const autoTrigger = config.autoTrigger;
|
|
30
|
+
// --- Governor event bridge ---
|
|
31
|
+
if (currentStateName && updatedFrom?.stateId) {
|
|
32
|
+
const governorIssue = {
|
|
33
|
+
id: issueId,
|
|
34
|
+
identifier: issueIdentifier,
|
|
35
|
+
title: data.title ?? '',
|
|
36
|
+
description: data.description ?? undefined,
|
|
37
|
+
status: currentStateName,
|
|
38
|
+
labels: (data.labels ?? []).map(l => l.name),
|
|
39
|
+
createdAt: data.createdAt ? new Date(data.createdAt).getTime() : Date.now(),
|
|
40
|
+
parentId: data.parent?.id,
|
|
41
|
+
project: projectName,
|
|
42
|
+
};
|
|
43
|
+
await publishGovernorEvent({
|
|
44
|
+
type: 'issue-status-changed',
|
|
45
|
+
issueId,
|
|
46
|
+
issue: governorIssue,
|
|
47
|
+
previousStatus: updatedFrom.state?.name,
|
|
48
|
+
newStatus: currentStateName,
|
|
49
|
+
timestamp: eventTimestamp(),
|
|
50
|
+
source: 'webhook',
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
if (config.governorMode === 'governor-only') {
|
|
54
|
+
issueLog.info('Governor-only mode: skipping direct dispatch', { currentStateName });
|
|
55
|
+
return NextResponse.json({ success: true, governorMode: 'governor-only' });
|
|
56
|
+
}
|
|
29
57
|
// === Handle Finished transition (auto-QA) ===
|
|
30
58
|
if (currentStateName === 'Finished' && updatedFrom?.stateId) {
|
|
31
59
|
issueLog.info('Issue transitioned to Finished', {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supaku/agentfactory-nextjs",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Next.js API route handlers for AgentFactory — webhook processor, worker/session management, public stats",
|
|
6
6
|
"author": "Supaku (https://supaku.com)",
|
|
@@ -48,9 +48,9 @@
|
|
|
48
48
|
"LICENSE"
|
|
49
49
|
],
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@supaku/agentfactory": "0.7.
|
|
52
|
-
"@supaku/agentfactory-
|
|
53
|
-
"@supaku/agentfactory-
|
|
51
|
+
"@supaku/agentfactory": "0.7.12",
|
|
52
|
+
"@supaku/agentfactory-server": "0.7.12",
|
|
53
|
+
"@supaku/agentfactory-linear": "0.7.12"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"next": ">=14.0.0"
|