@supaku/agentfactory-server 0.7.27 → 0.7.29

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.
@@ -175,4 +175,27 @@ export declare function clearAcceptanceQueued(issueId: string): Promise<void>;
175
175
  * Called after successful acceptance processing to remove all Redis state
176
176
  */
177
177
  export declare function cleanupAcceptedIssue(issueId: string): Promise<void>;
178
+ /**
179
+ * Maximum total sessions (across all phases) allowed per issue.
180
+ * Once reached, no more automated sessions will be created.
181
+ */
182
+ export declare const MAX_TOTAL_SESSIONS = 8;
183
+ /**
184
+ * Get the total number of sessions across all workflow phases for an issue.
185
+ * Returns 0 if no workflow state exists.
186
+ */
187
+ export declare function getTotalSessionCount(issueId: string): Promise<number>;
188
+ /**
189
+ * Mark an issue as having just completed acceptance.
190
+ * Prevents re-triggering acceptance within the cooldown window.
191
+ */
192
+ export declare function markAcceptanceCompleted(issueId: string): Promise<void>;
193
+ /**
194
+ * Check if acceptance was recently completed for an issue (within cooldown period)
195
+ */
196
+ export declare function didAcceptanceJustComplete(issueId: string): Promise<boolean>;
197
+ /**
198
+ * Clear acceptance completed marker
199
+ */
200
+ export declare function clearAcceptanceCompleted(issueId: string): Promise<void>;
178
201
  //# sourceMappingURL=agent-tracking.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-tracking.d.ts","sourceRoot":"","sources":["../../src/agent-tracking.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-tracking.d.ts","sourceRoot":"","sources":["../../src/agent-tracking.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6BH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,KAAK,CAAC;QACtB,SAAS,EAAE,MAAM,CAAA;QACjB,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAC,CAAA;CACH;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,kBAAkB,GAAG,WAAW,GAAG,gBAAgB,CAAA;AAE/F;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,IAAI,GAAG,YAAY,GAAG,YAAY,CAAA;AAE9E;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAA;IACxC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,MAAM,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE;QACN,WAAW,EAAE,WAAW,EAAE,CAAA;QAC1B,EAAE,EAAE,WAAW,EAAE,CAAA;QACjB,UAAU,EAAE,WAAW,EAAE,CAAA;QACzB,UAAU,EAAE,WAAW,EAAE,CAAA;KAC1B,CAAA;IACD,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,CAKtE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAGrF;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,GAAG;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9E,OAAO,CAAC,aAAa,CAAC,CAsBxB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,aAAa,CAAC,CAMxB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAOjF;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC,CAQxB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CA6B9E;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,aAAa,CAAC,GACrD,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAGjC;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CA2B1B;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIxE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGrE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIlE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIpE;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI1E;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG/E;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3E;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIzE;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG9E;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI1E;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAazE;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAEnC;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAU3E;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI5E;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGjF;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7E"}
@@ -17,13 +17,15 @@ const QA_ATTEMPT_PREFIX = 'qa:attempt:';
17
17
  const QA_FAILED_PREFIX = 'qa:failed:';
18
18
  const DEV_QUEUED_PREFIX = 'agent:dev-queued:';
19
19
  const ACCEPTANCE_QUEUED_PREFIX = 'agent:acceptance-queued:';
20
+ const ACCEPTANCE_COMPLETED_PREFIX = 'agent:acceptance-completed:';
20
21
  const WORKFLOW_STATE_PREFIX = 'workflow:state:';
21
22
  // TTLs in seconds
22
23
  const AGENT_WORKED_TTL = 7 * 24 * 60 * 60; // 7 days
23
24
  const QA_ATTEMPT_TTL = 24 * 60 * 60; // 24 hours
24
25
  const QA_FAILED_TTL = 60 * 60; // 1 hour
25
- const DEV_QUEUED_TTL = 10; // 10 seconds - just enough to prevent duplicate webhooks
26
- const ACCEPTANCE_QUEUED_TTL = 10; // 10 seconds - just enough to prevent duplicate webhooks
26
+ const DEV_QUEUED_TTL = 300; // 5 minutes
27
+ const ACCEPTANCE_QUEUED_TTL = 300; // 5 minutes
28
+ const ACCEPTANCE_COMPLETED_TTL = 30 * 60; // 30 minutes
27
29
  const WORKFLOW_STATE_TTL = 30 * 24 * 60 * 60; // 30 days
28
30
  /**
29
31
  * Compute escalation strategy deterministically from cycle count.
@@ -297,8 +299,51 @@ export async function cleanupAcceptedIssue(issueId) {
297
299
  `${QA_FAILED_PREFIX}${issueId}`,
298
300
  `${DEV_QUEUED_PREFIX}${issueId}`,
299
301
  `${ACCEPTANCE_QUEUED_PREFIX}${issueId}`,
302
+ `${ACCEPTANCE_COMPLETED_PREFIX}${issueId}`,
300
303
  `${WORKFLOW_STATE_PREFIX}${issueId}`,
301
304
  ];
302
305
  await Promise.all(keysToDelete.map((key) => redisDel(key)));
303
306
  log.info('Cleaned up all tracking data for accepted issue', { issueId });
304
307
  }
308
+ /**
309
+ * Maximum total sessions (across all phases) allowed per issue.
310
+ * Once reached, no more automated sessions will be created.
311
+ */
312
+ export const MAX_TOTAL_SESSIONS = 8;
313
+ /**
314
+ * Get the total number of sessions across all workflow phases for an issue.
315
+ * Returns 0 if no workflow state exists.
316
+ */
317
+ export async function getTotalSessionCount(issueId) {
318
+ const state = await getWorkflowState(issueId);
319
+ if (!state)
320
+ return 0;
321
+ return (state.phases.development.length +
322
+ state.phases.qa.length +
323
+ state.phases.refinement.length +
324
+ state.phases.acceptance.length);
325
+ }
326
+ /**
327
+ * Mark an issue as having just completed acceptance.
328
+ * Prevents re-triggering acceptance within the cooldown window.
329
+ */
330
+ export async function markAcceptanceCompleted(issueId) {
331
+ const key = `${ACCEPTANCE_COMPLETED_PREFIX}${issueId}`;
332
+ await redisSet(key, { completedAt: Date.now() }, ACCEPTANCE_COMPLETED_TTL);
333
+ log.info('Marked acceptance completed', { issueId });
334
+ }
335
+ /**
336
+ * Check if acceptance was recently completed for an issue (within cooldown period)
337
+ */
338
+ export async function didAcceptanceJustComplete(issueId) {
339
+ const key = `${ACCEPTANCE_COMPLETED_PREFIX}${issueId}`;
340
+ return redisExists(key);
341
+ }
342
+ /**
343
+ * Clear acceptance completed marker
344
+ */
345
+ export async function clearAcceptanceCompleted(issueId) {
346
+ const key = `${ACCEPTANCE_COMPLETED_PREFIX}${issueId}`;
347
+ await redisDel(key);
348
+ log.debug('Cleared acceptance completed marker', { issueId });
349
+ }
@@ -142,7 +142,7 @@ export async function cleanupOrphanedSessions(callbacks) {
142
142
  await resetSessionForRequeue(session.linearSessionId);
143
143
  // Re-queue the work with higher priority
144
144
  // IMPORTANT: Preserve workType to prevent incorrect status transitions
145
- // NOTE: Do NOT preserve claudeSessionId - the old session may be corrupted
145
+ // NOTE: Do NOT preserve providerSessionId - the old session may be corrupted
146
146
  // from the crash that caused the orphan. Starting fresh is safer.
147
147
  const work = {
148
148
  sessionId: session.linearSessionId,
@@ -151,7 +151,7 @@ export async function cleanupOrphanedSessions(callbacks) {
151
151
  priority: Math.max(1, (session.priority || 3) - 1), // Boost priority
152
152
  queuedAt: Date.now(),
153
153
  prompt: session.promptContext,
154
- // claudeSessionId intentionally omitted - don't resume crashed sessions
154
+ // providerSessionId intentionally omitted - don't resume crashed sessions
155
155
  workType: session.workType,
156
156
  };
157
157
  const dispatchResult = await dispatchWork(work);
@@ -20,8 +20,8 @@ export interface AgentSessionState {
20
20
  issueId: string;
21
21
  /** Issue identifier (e.g., SUP-123) */
22
22
  issueIdentifier?: string;
23
- /** Claude CLI session ID for resuming with --resume */
24
- claudeSessionId: string | null;
23
+ /** Provider CLI session ID for resuming with --resume */
24
+ providerSessionId: string | null;
25
25
  /** Git worktree path */
26
26
  worktreePath: string;
27
27
  /** Current agent status */
@@ -48,6 +48,8 @@ export interface AgentSessionState {
48
48
  agentId?: string;
49
49
  /** Linear project name (for routing and dashboard visibility) */
50
50
  projectName?: string;
51
+ /** Agent provider name (claude, codex, amp) — set by worker on claim */
52
+ provider?: string;
51
53
  /** Total cost in USD for this session */
52
54
  totalCostUsd?: number;
53
55
  /** Total input tokens consumed */
@@ -70,13 +72,13 @@ export declare function storeSessionState(linearSessionId: string, state: Omit<A
70
72
  */
71
73
  export declare function getSessionState(linearSessionId: string): Promise<AgentSessionState | null>;
72
74
  /**
73
- * Update the Claude session ID for a session
75
+ * Update the provider session ID for a session
74
76
  * Called when the Claude init event is received with the session ID
75
77
  *
76
78
  * @param linearSessionId - The Linear session ID
77
- * @param claudeSessionId - The Claude CLI session ID
79
+ * @param providerSessionId - The Provider CLI session ID
78
80
  */
79
- export declare function updateClaudeSessionId(linearSessionId: string, claudeSessionId: string): Promise<boolean>;
81
+ export declare function updateProviderSessionId(linearSessionId: string, providerSessionId: string): Promise<boolean>;
80
82
  /**
81
83
  * Update session status
82
84
  *
@@ -1 +1 @@
1
- {"version":3,"file":"session-storage.d.ts","sourceRoot":"","sources":["../../src/session-storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAS/C;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,SAAS,GACT,SAAS,GACT,YAAY,GACZ,WAAW,GACX,QAAQ,GACR,SAAS,CAAA;AAEb;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,uCAAuC;IACvC,eAAe,EAAE,MAAM,CAAA;IACvB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,uDAAuD;IACvD,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,wBAAwB;IACxB,YAAY,EAAE,MAAM,CAAA;IACpB,2BAA2B;IAC3B,MAAM,EAAE,kBAAkB,CAAA;IAC1B,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAA;IACjB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAA;IAGjB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qCAAqC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAA;IAGtB,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,CAAA;IAGvB,4GAA4G;IAC5G,QAAQ,CAAC,EAAE,aAAa,CAAA;IAGxB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAA;IAGpB,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mCAAmC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAoBD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,WAAW,GAAG,WAAW,CAAC,GAC5E,OAAO,CAAC,iBAAiB,CAAC,CAmC5B;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAkBnC;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CA0BlB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,GAClC,OAAO,CAAC,OAAO,CAAC,CA0BlB;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/E,OAAO,CAAC,OAAO,CAAC,CA+BlB;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CA+BlB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWlF;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAiBnC;AAMD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAmClB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC,CA2BlB;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAwBnE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,EAAE,GAChD,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAI9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAyCpD"}
1
+ {"version":3,"file":"session-storage.d.ts","sourceRoot":"","sources":["../../src/session-storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAS/C;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,SAAS,GACT,SAAS,GACT,YAAY,GACZ,WAAW,GACX,QAAQ,GACR,SAAS,CAAA;AAEb;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,uCAAuC;IACvC,eAAe,EAAE,MAAM,CAAA;IACvB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,yDAAyD;IACzD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,wBAAwB;IACxB,YAAY,EAAE,MAAM,CAAA;IACpB,2BAA2B;IAC3B,MAAM,EAAE,kBAAkB,CAAA;IAC1B,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAA;IACjB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAA;IAGjB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qCAAqC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAA;IAGtB,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,CAAA;IAGvB,4GAA4G;IAC5G,QAAQ,CAAC,EAAE,aAAa,CAAA;IAGxB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAA;IAGjB,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mCAAmC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAoBD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,WAAW,GAAG,WAAW,CAAC,GAC5E,OAAO,CAAC,iBAAiB,CAAC,CAmC5B;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAkBnC;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,eAAe,EAAE,MAAM,EACvB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,OAAO,CAAC,CA0BlB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,GAClC,OAAO,CAAC,OAAO,CAAC,CA0BlB;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/E,OAAO,CAAC,OAAO,CAAC,CA+BlB;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CA+BlB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWlF;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAiBnC;AAMD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAmClB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC,CA2BlB;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAwBnE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,EAAE,GAChD,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAI9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAyCpD"}
@@ -52,7 +52,7 @@ export async function storeSessionState(linearSessionId, state) {
52
52
  linearSessionId,
53
53
  issueId: state.issueId,
54
54
  status: state.status,
55
- hasClaudeSessionId: !!state.claudeSessionId,
55
+ hasProviderSessionId: !!state.providerSessionId,
56
56
  });
57
57
  return sessionState;
58
58
  }
@@ -79,31 +79,31 @@ export async function getSessionState(linearSessionId) {
79
79
  return state;
80
80
  }
81
81
  /**
82
- * Update the Claude session ID for a session
82
+ * Update the provider session ID for a session
83
83
  * Called when the Claude init event is received with the session ID
84
84
  *
85
85
  * @param linearSessionId - The Linear session ID
86
- * @param claudeSessionId - The Claude CLI session ID
86
+ * @param providerSessionId - The Provider CLI session ID
87
87
  */
88
- export async function updateClaudeSessionId(linearSessionId, claudeSessionId) {
88
+ export async function updateProviderSessionId(linearSessionId, providerSessionId) {
89
89
  if (!isRedisConfigured()) {
90
- log.warn('Redis not configured, cannot update Claude session ID');
90
+ log.warn('Redis not configured, cannot update provider session ID');
91
91
  return false;
92
92
  }
93
93
  const existing = await getSessionState(linearSessionId);
94
94
  if (!existing) {
95
- log.warn('Session not found for Claude session ID update', { linearSessionId });
95
+ log.warn('Session not found for provider session ID update', { linearSessionId });
96
96
  return false;
97
97
  }
98
98
  const key = buildSessionKey(linearSessionId);
99
99
  const now = Math.floor(Date.now() / 1000);
100
100
  const updated = {
101
101
  ...existing,
102
- claudeSessionId,
102
+ providerSessionId,
103
103
  updatedAt: now,
104
104
  };
105
105
  await redisSet(key, updated, SESSION_TTL_SECONDS);
106
- log.info('Updated Claude session ID', { linearSessionId, claudeSessionId });
106
+ log.info('Updated provider session ID', { linearSessionId, providerSessionId });
107
107
  return true;
108
108
  }
109
109
  /**
@@ -31,7 +31,7 @@ export interface QueuedWork {
31
31
  priority: number;
32
32
  queuedAt: number;
33
33
  prompt?: string;
34
- claudeSessionId?: string;
34
+ providerSessionId?: string;
35
35
  workType?: AgentWorkType;
36
36
  sourceSessionId?: string;
37
37
  projectName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"work-queue.d.ts","sourceRoot":"","sources":["../../src/work-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAqBH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAoB/C;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAA;AAEpC;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAeD;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CA4BlE;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAuCxE;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAWtD;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgE5B;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAatE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAY7E;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAY1E;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,UAAU,EAChB,aAAa,GAAE,MAAU,GACxB,OAAO,CAAC,OAAO,CAAC,CAwBlB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAgC/D;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAczE;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC;IACtD,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf,CAAC,CA8CD"}
1
+ {"version":3,"file":"work-queue.d.ts","sourceRoot":"","sources":["../../src/work-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAqBH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAoB/C;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAA;AAEpC;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAeD;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CA4BlE;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAuCxE;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAWtD;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgE5B;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAatE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAY7E;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAY1E;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,UAAU,EAChB,aAAa,GAAE,MAAU,GACxB,OAAO,CAAC,OAAO,CAAC,CAwBlB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAgC/D;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAczE;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC;IACtD,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf,CAAC,CA8CD"}
@@ -23,7 +23,7 @@ vi.mock('./redis.js', () => ({
23
23
  }),
24
24
  redisExists: vi.fn(async (key) => store.has(key)),
25
25
  }));
26
- import { computeStrategy, getWorkflowState, updateWorkflowState, recordPhaseAttempt, incrementCycleCount, appendFailureSummary, clearWorkflowState, extractFailureReason, } from './agent-tracking.js';
26
+ import { computeStrategy, getWorkflowState, updateWorkflowState, recordPhaseAttempt, incrementCycleCount, appendFailureSummary, clearWorkflowState, extractFailureReason, getTotalSessionCount, MAX_TOTAL_SESSIONS, markAcceptanceCompleted, didAcceptanceJustComplete, clearAcceptanceCompleted, } from './agent-tracking.js';
27
27
  beforeEach(() => {
28
28
  store.clear();
29
29
  });
@@ -279,3 +279,64 @@ describe('escalate-human blocker creation data', () => {
279
279
  }
280
280
  });
281
281
  });
282
+ describe('getTotalSessionCount', () => {
283
+ const issueId = 'session-count-test-001';
284
+ const issueIdentifier = 'TEST-SC';
285
+ it('returns 0 for nonexistent issue', async () => {
286
+ const count = await getTotalSessionCount('nonexistent-issue-id');
287
+ expect(count).toBe(0);
288
+ });
289
+ it('correctly sums across all phases', async () => {
290
+ await updateWorkflowState(issueId, { issueIdentifier });
291
+ // Add 2 development, 2 qa, 1 refinement, 1 acceptance
292
+ await recordPhaseAttempt(issueId, 'development', {
293
+ attempt: 1, sessionId: 'dev-1', startedAt: Date.now(), result: 'passed', costUsd: 1.0,
294
+ });
295
+ await recordPhaseAttempt(issueId, 'development', {
296
+ attempt: 2, sessionId: 'dev-2', startedAt: Date.now(), result: 'passed', costUsd: 1.0,
297
+ });
298
+ await recordPhaseAttempt(issueId, 'qa', {
299
+ attempt: 1, sessionId: 'qa-1', startedAt: Date.now(), result: 'failed', costUsd: 0.5,
300
+ });
301
+ await recordPhaseAttempt(issueId, 'qa', {
302
+ attempt: 2, sessionId: 'qa-2', startedAt: Date.now(), result: 'passed', costUsd: 0.5,
303
+ });
304
+ await recordPhaseAttempt(issueId, 'refinement', {
305
+ attempt: 1, sessionId: 'ref-1', startedAt: Date.now(), result: 'passed', costUsd: 0.3,
306
+ });
307
+ await recordPhaseAttempt(issueId, 'acceptance', {
308
+ attempt: 1, sessionId: 'acc-1', startedAt: Date.now(), result: 'passed', costUsd: 0.2,
309
+ });
310
+ const count = await getTotalSessionCount(issueId);
311
+ expect(count).toBe(6); // 2 + 2 + 1 + 1
312
+ });
313
+ it('returns count that would hit MAX_TOTAL_SESSIONS', async () => {
314
+ await updateWorkflowState(issueId, { issueIdentifier });
315
+ // Add exactly MAX_TOTAL_SESSIONS phase records
316
+ for (let i = 0; i < MAX_TOTAL_SESSIONS; i++) {
317
+ const phase = i % 2 === 0 ? 'development' : 'qa';
318
+ await recordPhaseAttempt(issueId, phase, {
319
+ attempt: i + 1, sessionId: `session-${i}`, startedAt: Date.now(), result: 'passed',
320
+ });
321
+ }
322
+ const count = await getTotalSessionCount(issueId);
323
+ expect(count).toBe(MAX_TOTAL_SESSIONS);
324
+ expect(count >= MAX_TOTAL_SESSIONS).toBe(true);
325
+ });
326
+ });
327
+ describe('acceptance completion lock', () => {
328
+ const issueId = 'acceptance-lock-test-001';
329
+ it('returns false before marking, true after marking', async () => {
330
+ const beforeMark = await didAcceptanceJustComplete(issueId);
331
+ expect(beforeMark).toBe(false);
332
+ await markAcceptanceCompleted(issueId);
333
+ const afterMark = await didAcceptanceJustComplete(issueId);
334
+ expect(afterMark).toBe(true);
335
+ });
336
+ it('returns false after clearing', async () => {
337
+ await markAcceptanceCompleted(issueId);
338
+ expect(await didAcceptanceJustComplete(issueId)).toBe(true);
339
+ await clearAcceptanceCompleted(issueId);
340
+ expect(await didAcceptanceJustComplete(issueId)).toBe(false);
341
+ });
342
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supaku/agentfactory-server",
3
- "version": "0.7.27",
3
+ "version": "0.7.29",
4
4
  "type": "module",
5
5
  "description": "Webhook server and distributed worker pool for AgentFactory — Redis queues, issue locks, session management",
6
6
  "author": "Supaku (https://supaku.com)",
@@ -44,8 +44,8 @@
44
44
  ],
45
45
  "dependencies": {
46
46
  "ioredis": "^5.4.2",
47
- "@supaku/agentfactory": "0.7.27",
48
- "@supaku/agentfactory-linear": "0.7.27"
47
+ "@supaku/agentfactory": "0.7.29",
48
+ "@supaku/agentfactory-linear": "0.7.29"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^22.5.4",