@supaku/agentfactory-nextjs 0.3.0 → 0.4.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/dist/src/factory.d.ts +34 -6
- package/dist/src/factory.d.ts.map +1 -1
- package/dist/src/factory.js +37 -7
- package/dist/src/handlers/oauth/callback.d.ts +36 -0
- package/dist/src/handlers/oauth/callback.d.ts.map +1 -0
- package/dist/src/handlers/oauth/callback.js +92 -0
- package/dist/src/index.d.ts +11 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +11 -2
- package/dist/src/linear-client-resolver.d.ts +37 -0
- package/dist/src/linear-client-resolver.d.ts.map +1 -0
- package/dist/src/linear-client-resolver.js +60 -0
- package/dist/src/middleware/factory.d.ts +32 -0
- package/dist/src/middleware/factory.d.ts.map +1 -0
- package/dist/src/middleware/factory.js +115 -0
- package/dist/src/middleware/types.d.ts +35 -0
- package/dist/src/middleware/types.d.ts.map +1 -0
- package/dist/src/middleware/types.js +4 -0
- package/dist/src/orchestrator/error-formatting.d.ts +8 -0
- package/dist/src/orchestrator/error-formatting.d.ts.map +1 -0
- package/dist/src/orchestrator/error-formatting.js +35 -0
- package/dist/src/orchestrator/index.d.ts +4 -0
- package/dist/src/orchestrator/index.d.ts.map +1 -0
- package/dist/src/orchestrator/index.js +2 -0
- package/dist/src/orchestrator/types.d.ts +53 -0
- package/dist/src/orchestrator/types.d.ts.map +1 -0
- package/dist/src/orchestrator/types.js +4 -0
- package/dist/src/orchestrator/webhook-orchestrator.d.ts +32 -0
- package/dist/src/orchestrator/webhook-orchestrator.d.ts.map +1 -0
- package/dist/src/orchestrator/webhook-orchestrator.js +300 -0
- package/dist/src/types.d.ts +16 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/webhook/handlers/issue-updated.d.ts +2 -2
- package/dist/src/webhook/handlers/issue-updated.d.ts.map +1 -1
- package/dist/src/webhook/handlers/session-created.d.ts +2 -2
- package/dist/src/webhook/handlers/session-created.d.ts.map +1 -1
- package/dist/src/webhook/handlers/session-prompted.d.ts +2 -2
- package/dist/src/webhook/handlers/session-prompted.d.ts.map +1 -1
- package/dist/src/webhook/handlers/session-updated.d.ts +2 -2
- package/dist/src/webhook/handlers/session-updated.d.ts.map +1 -1
- package/dist/src/webhook/processor.d.ts +2 -2
- package/dist/src/webhook/processor.d.ts.map +1 -1
- package/dist/src/webhook/utils.d.ts +5 -5
- package/dist/src/webhook/utils.d.ts.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-formatting.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/error-formatting.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CA+B1D"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic error formatting for Linear comments.
|
|
3
|
+
*/
|
|
4
|
+
import { AgentSpawnError } from '@supaku/agentfactory-linear';
|
|
5
|
+
/**
|
|
6
|
+
* Format an error for posting as a Linear comment with markdown.
|
|
7
|
+
*/
|
|
8
|
+
export function formatErrorForComment(error) {
|
|
9
|
+
const lines = ['## Agent Error', '', `**${error.name}**: ${error.message}`];
|
|
10
|
+
if (error instanceof AgentSpawnError) {
|
|
11
|
+
lines.push('');
|
|
12
|
+
lines.push(`- Issue ID: ${error.issueId}`);
|
|
13
|
+
if (error.sessionId) {
|
|
14
|
+
lines.push(`- Session ID: ${error.sessionId}`);
|
|
15
|
+
}
|
|
16
|
+
lines.push(`- Retryable: ${error.isRetryable ? 'Yes' : 'No'}`);
|
|
17
|
+
if (error.cause) {
|
|
18
|
+
lines.push(`- Cause: ${error.cause.message}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (error.stack) {
|
|
22
|
+
lines.push('');
|
|
23
|
+
lines.push('<details>');
|
|
24
|
+
lines.push('<summary>Stack Trace</summary>');
|
|
25
|
+
lines.push('');
|
|
26
|
+
lines.push('```');
|
|
27
|
+
lines.push(error.stack);
|
|
28
|
+
lines.push('```');
|
|
29
|
+
lines.push('</details>');
|
|
30
|
+
}
|
|
31
|
+
lines.push('');
|
|
32
|
+
lines.push(`---`);
|
|
33
|
+
lines.push(`*Error occurred at ${new Date().toISOString()}*`);
|
|
34
|
+
return lines.join('\n');
|
|
35
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { createWebhookOrchestrator } from './webhook-orchestrator.js';
|
|
2
|
+
export { formatErrorForComment } from './error-formatting.js';
|
|
3
|
+
export type { WebhookOrchestratorConfig, WebhookOrchestratorHooks, WebhookOrchestratorInstance, } from './types.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAA;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,YAAY,EACV,yBAAyB,EACzB,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the webhook orchestrator factory.
|
|
3
|
+
*/
|
|
4
|
+
import type { AgentProcess, StopAgentResult, ForwardPromptResult } from '@supaku/agentfactory';
|
|
5
|
+
import type { RetryConfig } from '@supaku/agentfactory-linear';
|
|
6
|
+
/**
|
|
7
|
+
* Configuration for the webhook orchestrator.
|
|
8
|
+
*/
|
|
9
|
+
export interface WebhookOrchestratorConfig {
|
|
10
|
+
/** Maximum concurrent agents (default: 10) */
|
|
11
|
+
maxConcurrent?: number;
|
|
12
|
+
/** Enable auto-transition of Linear statuses (default: true) */
|
|
13
|
+
autoTransition?: boolean;
|
|
14
|
+
/** Retry configuration for agent spawning */
|
|
15
|
+
retryConfig?: Required<RetryConfig>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Lifecycle hooks for agent events.
|
|
19
|
+
* Consumers use these to add custom behavior (e.g., marking agent-worked).
|
|
20
|
+
*/
|
|
21
|
+
export interface WebhookOrchestratorHooks {
|
|
22
|
+
/** Called when an agent starts successfully */
|
|
23
|
+
onAgentComplete?: (agent: AgentProcess) => Promise<void> | void;
|
|
24
|
+
/** Called when an agent fails with an error */
|
|
25
|
+
onAgentError?: (agent: AgentProcess, error: Error) => Promise<void> | void;
|
|
26
|
+
/** Called when an agent is stopped (e.g., by user) */
|
|
27
|
+
onAgentStopped?: (agent: AgentProcess) => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The webhook orchestrator instance provides methods to spawn, stop,
|
|
31
|
+
* and forward prompts to agents.
|
|
32
|
+
*/
|
|
33
|
+
export interface WebhookOrchestratorInstance {
|
|
34
|
+
/**
|
|
35
|
+
* Spawn an agent for an issue with idempotency and retry logic.
|
|
36
|
+
* Returns immediately after spawning — does not wait for completion.
|
|
37
|
+
*/
|
|
38
|
+
spawnAgentAsync(issueId: string, sessionId: string, webhookId?: string): Promise<{
|
|
39
|
+
spawned: boolean;
|
|
40
|
+
reason?: string;
|
|
41
|
+
agent?: AgentProcess;
|
|
42
|
+
error?: Error;
|
|
43
|
+
}>;
|
|
44
|
+
/** Stop an agent by session ID */
|
|
45
|
+
stopAgentBySession(sessionId: string, cleanupWorktree?: boolean): Promise<StopAgentResult>;
|
|
46
|
+
/** Get an active agent by session ID */
|
|
47
|
+
getAgentBySession(sessionId: string): AgentProcess | undefined;
|
|
48
|
+
/** Check if an agent is already running for an issue */
|
|
49
|
+
isAgentRunningForIssue(issueId: string): boolean;
|
|
50
|
+
/** Forward a follow-up prompt to an existing or new agent */
|
|
51
|
+
forwardPromptAsync(issueId: string, sessionId: string, promptText: string): Promise<ForwardPromptResult>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC9F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAE9D;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,8CAA8C;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,gEAAgE;IAChE,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,+CAA+C;IAC/C,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC/D,+CAA+C;IAC/C,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC1E,sDAAsD;IACtD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;CAC/C;AAED;;;GAGG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;OAGG;IACH,eAAe,CACb,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAA;QAChB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,KAAK,CAAC,EAAE,YAAY,CAAA;QACpB,KAAK,CAAC,EAAE,KAAK,CAAA;KACd,CAAC,CAAA;IAEF,kCAAkC;IAClC,kBAAkB,CAChB,SAAS,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,OAAO,GACxB,OAAO,CAAC,eAAe,CAAC,CAAA;IAE3B,wCAAwC;IACxC,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAA;IAE9D,wDAAwD;IACxD,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;IAEhD,6DAA6D;IAC7D,kBAAkB,CAChB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,mBAAmB,CAAC,CAAA;CAChC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook Orchestrator Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates a singleton orchestrator instance configured for webhook-triggered
|
|
5
|
+
* agent spawning. Includes retry logic, idempotency, session state persistence,
|
|
6
|
+
* and error activity emission to Linear.
|
|
7
|
+
*
|
|
8
|
+
* Consumers provide lifecycle hooks (e.g., onAgentComplete) for custom behavior
|
|
9
|
+
* like marking issues as "agent-worked" for automated QA.
|
|
10
|
+
*/
|
|
11
|
+
import type { WebhookOrchestratorConfig, WebhookOrchestratorHooks, WebhookOrchestratorInstance } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Create a webhook orchestrator instance.
|
|
14
|
+
*
|
|
15
|
+
* @param config - Orchestrator configuration
|
|
16
|
+
* @param hooks - Lifecycle hooks for custom behavior
|
|
17
|
+
* @returns A webhook orchestrator instance
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const orchestrator = createWebhookOrchestrator(
|
|
22
|
+
* { maxConcurrent: 10 },
|
|
23
|
+
* {
|
|
24
|
+
* onAgentComplete: async (agent) => {
|
|
25
|
+
* await markAgentWorked(agent.issueId, { ... })
|
|
26
|
+
* },
|
|
27
|
+
* }
|
|
28
|
+
* )
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function createWebhookOrchestrator(config?: WebhookOrchestratorConfig, hooks?: WebhookOrchestratorHooks): WebhookOrchestratorInstance;
|
|
32
|
+
//# sourceMappingURL=webhook-orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-orchestrator.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/webhook-orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA2BH,OAAO,KAAK,EACV,yBAAyB,EACzB,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,YAAY,CAAA;AAyFnB;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,CAAC,EAAE,yBAAyB,EAClC,KAAK,CAAC,EAAE,wBAAwB,GAC/B,2BAA2B,CAsO7B"}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook Orchestrator Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates a singleton orchestrator instance configured for webhook-triggered
|
|
5
|
+
* agent spawning. Includes retry logic, idempotency, session state persistence,
|
|
6
|
+
* and error activity emission to Linear.
|
|
7
|
+
*
|
|
8
|
+
* Consumers provide lifecycle hooks (e.g., onAgentComplete) for custom behavior
|
|
9
|
+
* like marking issues as "agent-worked" for automated QA.
|
|
10
|
+
*/
|
|
11
|
+
import { createOrchestrator, } from '@supaku/agentfactory';
|
|
12
|
+
import { withRetry, AgentSpawnError, isRetryableError, createAgentSession, createLinearAgentClient, } from '@supaku/agentfactory-linear';
|
|
13
|
+
import { createLogger, generateIdempotencyKey, isWebhookProcessed, markWebhookProcessed, unmarkWebhookProcessed, storeSessionState, getSessionState, updateClaudeSessionId, updateSessionStatus, } from '@supaku/agentfactory-server';
|
|
14
|
+
import { formatErrorForComment } from './error-formatting.js';
|
|
15
|
+
const log = createLogger('webhook-orchestrator');
|
|
16
|
+
const DEFAULT_RETRY_CONFIG = {
|
|
17
|
+
maxRetries: 2,
|
|
18
|
+
initialDelayMs: 1000,
|
|
19
|
+
backoffMultiplier: 2,
|
|
20
|
+
maxDelayMs: 5000,
|
|
21
|
+
retryableStatusCodes: [429, 500, 502, 503, 504],
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the Linear client lazily from environment.
|
|
25
|
+
* Used for error activity emission.
|
|
26
|
+
*/
|
|
27
|
+
function getLinearClientFromEnv() {
|
|
28
|
+
const apiKey = process.env.LINEAR_ACCESS_TOKEN;
|
|
29
|
+
if (!apiKey)
|
|
30
|
+
return null;
|
|
31
|
+
return createLinearAgentClient({ apiKey });
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Determine if a spawn error is retryable.
|
|
35
|
+
*/
|
|
36
|
+
function isSpawnErrorRetryable(error) {
|
|
37
|
+
if (isRetryableError(error))
|
|
38
|
+
return true;
|
|
39
|
+
if (error instanceof Error) {
|
|
40
|
+
const message = error.message.toLowerCase();
|
|
41
|
+
if (message.includes('lock') || message.includes('busy') || message.includes('temporary')) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
if (message.includes('not found') || message.includes('enoent')) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Clean up resources after a failed spawn attempt.
|
|
52
|
+
*/
|
|
53
|
+
async function cleanupFailedSpawn(issueId, idempotencyKey) {
|
|
54
|
+
try {
|
|
55
|
+
await unmarkWebhookProcessed(idempotencyKey);
|
|
56
|
+
log.debug('Cleaned up resources for failed spawn', { issueId, idempotencyKey });
|
|
57
|
+
}
|
|
58
|
+
catch (cleanupError) {
|
|
59
|
+
log.error('Cleanup error', { issueId, idempotencyKey, error: cleanupError });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Emit an error activity to Linear for tracking agent failures.
|
|
64
|
+
*/
|
|
65
|
+
async function emitAgentErrorActivity(issueId, error, sessionId) {
|
|
66
|
+
try {
|
|
67
|
+
const client = getLinearClientFromEnv();
|
|
68
|
+
if (!client) {
|
|
69
|
+
log.warn('Cannot emit error activity: LINEAR_ACCESS_TOKEN not set');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (sessionId) {
|
|
73
|
+
const session = createAgentSession({
|
|
74
|
+
client: client.linearClient,
|
|
75
|
+
issueId,
|
|
76
|
+
sessionId,
|
|
77
|
+
autoTransition: false,
|
|
78
|
+
});
|
|
79
|
+
await session.emitError(error);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const errorMessage = formatErrorForComment(error);
|
|
83
|
+
await client.createComment(issueId, errorMessage);
|
|
84
|
+
}
|
|
85
|
+
log.debug('Error activity emitted to Linear', { issueId, sessionId });
|
|
86
|
+
}
|
|
87
|
+
catch (emitError) {
|
|
88
|
+
log.error('Failed to emit error activity', { issueId, sessionId, error: emitError });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Create a webhook orchestrator instance.
|
|
93
|
+
*
|
|
94
|
+
* @param config - Orchestrator configuration
|
|
95
|
+
* @param hooks - Lifecycle hooks for custom behavior
|
|
96
|
+
* @returns A webhook orchestrator instance
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* const orchestrator = createWebhookOrchestrator(
|
|
101
|
+
* { maxConcurrent: 10 },
|
|
102
|
+
* {
|
|
103
|
+
* onAgentComplete: async (agent) => {
|
|
104
|
+
* await markAgentWorked(agent.issueId, { ... })
|
|
105
|
+
* },
|
|
106
|
+
* }
|
|
107
|
+
* )
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export function createWebhookOrchestrator(config, hooks) {
|
|
111
|
+
const retryConfig = config?.retryConfig ?? DEFAULT_RETRY_CONFIG;
|
|
112
|
+
let _orchestrator = null;
|
|
113
|
+
function getOrchestrator() {
|
|
114
|
+
if (!_orchestrator) {
|
|
115
|
+
const apiKey = process.env.LINEAR_ACCESS_TOKEN;
|
|
116
|
+
if (!apiKey) {
|
|
117
|
+
throw new Error('LINEAR_ACCESS_TOKEN not set - orchestrator initialization failed');
|
|
118
|
+
}
|
|
119
|
+
_orchestrator = createOrchestrator({
|
|
120
|
+
linearApiKey: apiKey,
|
|
121
|
+
maxConcurrent: config?.maxConcurrent ?? 10,
|
|
122
|
+
autoTransition: config?.autoTransition ?? true,
|
|
123
|
+
}, {
|
|
124
|
+
onAgentStart: (agent) => {
|
|
125
|
+
log.info('Agent started', {
|
|
126
|
+
agentIdentifier: agent.identifier,
|
|
127
|
+
agentPid: agent.pid,
|
|
128
|
+
issueId: agent.issueId,
|
|
129
|
+
sessionId: agent.sessionId,
|
|
130
|
+
});
|
|
131
|
+
},
|
|
132
|
+
onAgentComplete: async (agent) => {
|
|
133
|
+
log.info('Agent completed', {
|
|
134
|
+
agentIdentifier: agent.identifier,
|
|
135
|
+
issueId: agent.issueId,
|
|
136
|
+
sessionId: agent.sessionId,
|
|
137
|
+
});
|
|
138
|
+
try {
|
|
139
|
+
await hooks?.onAgentComplete?.(agent);
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
log.error('Hook onAgentComplete failed', { error: err });
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
onAgentError: (agent, error) => {
|
|
146
|
+
log.error('Agent failed', {
|
|
147
|
+
agentIdentifier: agent.identifier,
|
|
148
|
+
issueId: agent.issueId,
|
|
149
|
+
sessionId: agent.sessionId,
|
|
150
|
+
error,
|
|
151
|
+
});
|
|
152
|
+
emitAgentErrorActivity(agent.issueId, error, agent.sessionId).catch((err) => log.error('Failed to emit error activity', { error: err }));
|
|
153
|
+
try {
|
|
154
|
+
hooks?.onAgentError?.(agent, error);
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
log.error('Hook onAgentError failed', { error: err });
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
onAgentStopped: (agent) => {
|
|
161
|
+
log.info('Agent stopped', {
|
|
162
|
+
agentIdentifier: agent.identifier,
|
|
163
|
+
issueId: agent.issueId,
|
|
164
|
+
sessionId: agent.sessionId,
|
|
165
|
+
});
|
|
166
|
+
if (agent.sessionId) {
|
|
167
|
+
updateSessionStatus(agent.sessionId, 'stopped').catch((err) => log.error('Failed to update session status', { error: err }));
|
|
168
|
+
}
|
|
169
|
+
hooks?.onAgentStopped?.(agent);
|
|
170
|
+
},
|
|
171
|
+
onClaudeSessionId: async (linearSessionId, claudeSessionId) => {
|
|
172
|
+
log.info('Claude session ID captured', { linearSessionId, claudeSessionId });
|
|
173
|
+
await updateClaudeSessionId(linearSessionId, claudeSessionId);
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return _orchestrator;
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
async spawnAgentAsync(issueId, sessionId, webhookId) {
|
|
181
|
+
const idempotencyKey = generateIdempotencyKey(webhookId, sessionId);
|
|
182
|
+
if (await isWebhookProcessed(idempotencyKey)) {
|
|
183
|
+
return { spawned: false, reason: 'duplicate_webhook' };
|
|
184
|
+
}
|
|
185
|
+
const orch = getOrchestrator();
|
|
186
|
+
if (orch.getActiveAgents().some((a) => a.issueId === issueId)) {
|
|
187
|
+
return { spawned: false, reason: 'agent_already_running' };
|
|
188
|
+
}
|
|
189
|
+
await markWebhookProcessed(idempotencyKey);
|
|
190
|
+
const spawnLog = log.child({ issueId, sessionId });
|
|
191
|
+
try {
|
|
192
|
+
const agent = await withRetry(async () => {
|
|
193
|
+
return getOrchestrator().spawnAgentForIssue(issueId, sessionId);
|
|
194
|
+
}, {
|
|
195
|
+
config: retryConfig,
|
|
196
|
+
shouldRetry: isSpawnErrorRetryable,
|
|
197
|
+
onRetry: ({ attempt, delay, lastError }) => {
|
|
198
|
+
spawnLog.warn('Spawn retry attempt', {
|
|
199
|
+
attempt: attempt + 1,
|
|
200
|
+
maxRetries: retryConfig.maxRetries,
|
|
201
|
+
delayMs: delay,
|
|
202
|
+
lastErrorMessage: lastError?.message,
|
|
203
|
+
});
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
spawnLog.info('Agent spawn successful', {
|
|
207
|
+
agentIdentifier: agent.identifier,
|
|
208
|
+
agentPid: agent.pid,
|
|
209
|
+
});
|
|
210
|
+
await storeSessionState(sessionId, {
|
|
211
|
+
issueId,
|
|
212
|
+
claudeSessionId: agent.claudeSessionId ?? null,
|
|
213
|
+
worktreePath: agent.worktreePath,
|
|
214
|
+
status: 'running',
|
|
215
|
+
});
|
|
216
|
+
return { spawned: true, agent };
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
const spawnError = error instanceof Error ? error : new Error(String(error));
|
|
220
|
+
const typedError = new AgentSpawnError(`Failed to spawn agent: ${spawnError.message}`, issueId, sessionId, isSpawnErrorRetryable(error), spawnError);
|
|
221
|
+
spawnLog.error('Failed to spawn agent after retries', {
|
|
222
|
+
error: typedError,
|
|
223
|
+
isRetryable: typedError.isRetryable,
|
|
224
|
+
});
|
|
225
|
+
await emitAgentErrorActivity(issueId, typedError, sessionId);
|
|
226
|
+
await cleanupFailedSpawn(issueId, idempotencyKey);
|
|
227
|
+
return { spawned: false, reason: 'spawn_failed', error: typedError };
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
async stopAgentBySession(sessionId, cleanupWorktree = true) {
|
|
231
|
+
const stopLog = log.child({ sessionId });
|
|
232
|
+
try {
|
|
233
|
+
const orch = getOrchestrator();
|
|
234
|
+
const result = await orch.stopAgentBySession(sessionId, cleanupWorktree);
|
|
235
|
+
if (result.stopped) {
|
|
236
|
+
stopLog.info('Agent stopped by session', {
|
|
237
|
+
agentIdentifier: result.agent?.identifier,
|
|
238
|
+
cleanedWorktree: cleanupWorktree,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
stopLog.info('Could not stop agent', { reason: result.reason });
|
|
243
|
+
}
|
|
244
|
+
return result;
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
stopLog.error('Failed to stop agent', { error });
|
|
248
|
+
throw error;
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
getAgentBySession(sessionId) {
|
|
252
|
+
return getOrchestrator().getAgentBySession(sessionId);
|
|
253
|
+
},
|
|
254
|
+
isAgentRunningForIssue(issueId) {
|
|
255
|
+
return getOrchestrator().getActiveAgents().some((a) => a.issueId === issueId);
|
|
256
|
+
},
|
|
257
|
+
async forwardPromptAsync(issueId, sessionId, promptText) {
|
|
258
|
+
const promptLog = log.child({ issueId, sessionId });
|
|
259
|
+
try {
|
|
260
|
+
const sessionState = await getSessionState(sessionId);
|
|
261
|
+
promptLog.info('Forwarding prompt to agent', {
|
|
262
|
+
hasSessionState: !!sessionState,
|
|
263
|
+
hasClaudeSessionId: !!sessionState?.claudeSessionId,
|
|
264
|
+
promptLength: promptText.length,
|
|
265
|
+
workType: sessionState?.workType ?? 'development',
|
|
266
|
+
});
|
|
267
|
+
const orch = getOrchestrator();
|
|
268
|
+
const result = await orch.forwardPrompt(issueId, sessionId, promptText, sessionState?.claudeSessionId ?? undefined, sessionState?.workType);
|
|
269
|
+
if (result.forwarded) {
|
|
270
|
+
promptLog.info('Prompt forwarded successfully', {
|
|
271
|
+
resumed: result.resumed,
|
|
272
|
+
agentIdentifier: result.agent?.identifier,
|
|
273
|
+
agentPid: result.agent?.pid,
|
|
274
|
+
});
|
|
275
|
+
if (result.agent) {
|
|
276
|
+
await storeSessionState(sessionId, {
|
|
277
|
+
issueId,
|
|
278
|
+
claudeSessionId: result.agent.claudeSessionId ?? null,
|
|
279
|
+
worktreePath: result.agent.worktreePath,
|
|
280
|
+
status: 'running',
|
|
281
|
+
workType: sessionState?.workType,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
promptLog.warn('Prompt not forwarded', {
|
|
287
|
+
reason: result.reason,
|
|
288
|
+
error: result.error?.message,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
return result;
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
const errorMsg = error instanceof Error ? error : new Error(String(error));
|
|
295
|
+
promptLog.error('Failed to forward prompt', { error: errorMsg });
|
|
296
|
+
return { forwarded: false, resumed: false, reason: 'spawn_failed', error: errorMsg };
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -35,8 +35,24 @@ export interface AutoTriggerConfig {
|
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* Configuration for the webhook processor.
|
|
38
|
+
*
|
|
39
|
+
* `generatePrompt` is optional — if not provided, falls back to
|
|
40
|
+
* `defaultGeneratePrompt` from @supaku/agentfactory-linear.
|
|
38
41
|
*/
|
|
39
42
|
export interface WebhookConfig extends RouteConfig {
|
|
43
|
+
webhookSecret?: string;
|
|
44
|
+
generatePrompt?: (identifier: string, workType: AgentWorkType, mentionContext?: string) => string;
|
|
45
|
+
detectWorkTypeFromPrompt?: (prompt: string, validWorkTypes: AgentWorkType[]) => AgentWorkType | undefined;
|
|
46
|
+
getPriority?: (workType: AgentWorkType) => number;
|
|
47
|
+
autoTrigger?: AutoTriggerConfig;
|
|
48
|
+
buildParentQAContext?: (identifier: string, subIssues: SubIssueStatus[]) => string;
|
|
49
|
+
buildParentAcceptanceContext?: (identifier: string, subIssues: SubIssueStatus[]) => string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Resolved webhook config with all defaults applied.
|
|
53
|
+
* Used internally by webhook handlers — generatePrompt is guaranteed to be set.
|
|
54
|
+
*/
|
|
55
|
+
export interface ResolvedWebhookConfig extends RouteConfig {
|
|
40
56
|
webhookSecret?: string;
|
|
41
57
|
generatePrompt: (identifier: string, workType: AgentWorkType, mentionContext?: string) => string;
|
|
42
58
|
detectWorkTypeFromPrompt?: (prompt: string, validWorkTypes: AgentWorkType[]) => AgentWorkType | undefined;
|
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
|
|
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;CAC3F;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACxD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAChG,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;CAC3F;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;GAMG;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { NextResponse } from 'next/server';
|
|
10
10
|
import type { LinearWebhookPayload } from '@supaku/agentfactory-linear';
|
|
11
|
-
import type {
|
|
11
|
+
import type { ResolvedWebhookConfig } from '../../types.js';
|
|
12
12
|
import type { createLogger } from '@supaku/agentfactory-server';
|
|
13
|
-
export declare function handleIssueUpdated(config:
|
|
13
|
+
export declare function handleIssueUpdated(config: ResolvedWebhookConfig, payload: LinearWebhookPayload, log: ReturnType<typeof createLogger>): Promise<NextResponse | null>;
|
|
14
14
|
//# sourceMappingURL=issue-updated.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issue-updated.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/issue-updated.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AAsBtF,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"issue-updated.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/issue-updated.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AAsBtF,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,CAmhB9B"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { NextResponse } from 'next/server';
|
|
5
5
|
import type { LinearWebhookPayload } from '@supaku/agentfactory-linear';
|
|
6
|
-
import type {
|
|
6
|
+
import type { ResolvedWebhookConfig } from '../../types.js';
|
|
7
7
|
import type { createLogger } from '@supaku/agentfactory-server';
|
|
8
|
-
export declare function handleSessionCreated(config:
|
|
8
|
+
export declare function handleSessionCreated(config: ResolvedWebhookConfig, payload: LinearWebhookPayload, rawPayload: Record<string, unknown>, log: ReturnType<typeof createLogger>): Promise<NextResponse | null>;
|
|
9
9
|
//# sourceMappingURL=session-created.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-created.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/session-created.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AAiBtF,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"session-created.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/session-created.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AAiBtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAQ3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,oBAAoB,EAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACnC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA0Q9B"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { NextResponse } from 'next/server';
|
|
5
5
|
import type { LinearWebhookPayload } from '@supaku/agentfactory-linear';
|
|
6
|
-
import type {
|
|
6
|
+
import type { ResolvedWebhookConfig } from '../../types.js';
|
|
7
7
|
import type { createLogger } from '@supaku/agentfactory-server';
|
|
8
|
-
export declare function handleSessionPrompted(config:
|
|
8
|
+
export declare function handleSessionPrompted(config: ResolvedWebhookConfig, payload: LinearWebhookPayload, rawPayload: Record<string, unknown>, log: ReturnType<typeof createLogger>): Promise<NextResponse | null>;
|
|
9
9
|
//# sourceMappingURL=session-prompted.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-prompted.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/session-prompted.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AAatF,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"session-prompted.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/session-prompted.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAA;AAatF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,oBAAoB,EAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACnC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAkP9B"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { NextResponse } from 'next/server';
|
|
5
5
|
import type { LinearWebhookPayload } from '@supaku/agentfactory-linear';
|
|
6
|
-
import type {
|
|
6
|
+
import type { ResolvedWebhookConfig } from '../../types.js';
|
|
7
7
|
import type { createLogger } from '@supaku/agentfactory-server';
|
|
8
|
-
export declare function handleSessionUpdated(config:
|
|
8
|
+
export declare function handleSessionUpdated(config: ResolvedWebhookConfig, payload: LinearWebhookPayload, rawPayload: Record<string, unknown>, log: ReturnType<typeof createLogger>): Promise<NextResponse | null>;
|
|
9
9
|
//# sourceMappingURL=session-updated.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-updated.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/session-updated.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AACvE,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"session-updated.d.ts","sourceRoot":"","sources":["../../../../src/webhook/handlers/session-updated.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AACvE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,oBAAoB,EAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,GAAG,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,GACnC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA6B9B"}
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
* checks, and dispatches to sub-handlers.
|
|
6
6
|
*/
|
|
7
7
|
import { NextRequest, NextResponse } from 'next/server';
|
|
8
|
-
import type {
|
|
8
|
+
import type { ResolvedWebhookConfig } from '../types.js';
|
|
9
9
|
/**
|
|
10
10
|
* Create webhook route handlers from config.
|
|
11
11
|
*
|
|
12
12
|
* Returns { POST, GET } for use as Next.js App Router exports.
|
|
13
13
|
*/
|
|
14
|
-
export declare function createWebhookHandler(config:
|
|
14
|
+
export declare function createWebhookHandler(config: ResolvedWebhookConfig): {
|
|
15
15
|
POST: (request: NextRequest) => Promise<NextResponse<unknown>>;
|
|
16
16
|
GET: () => Promise<NextResponse<{
|
|
17
17
|
status: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processor.d.ts","sourceRoot":"","sources":["../../../src/webhook/processor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AASvD,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"processor.d.ts","sourceRoot":"","sources":["../../../src/webhook/processor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AASvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AASxD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,qBAAqB;oBACnC,WAAW;;;;;;EA2FzC"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Shared helpers used by webhook sub-handlers.
|
|
5
5
|
*/
|
|
6
6
|
import type { LinearAgentClient, AgentWorkType } from '@supaku/agentfactory-linear';
|
|
7
|
-
import type {
|
|
7
|
+
import type { ResolvedWebhookConfig } from '../types.js';
|
|
8
8
|
/**
|
|
9
9
|
* Activity types for Linear Agent API
|
|
10
10
|
*/
|
|
@@ -22,11 +22,11 @@ export declare function emitActivity(client: LinearAgentClient, sessionId: strin
|
|
|
22
22
|
* - pending: Removes from global work queue and/or issue-pending queue
|
|
23
23
|
* - Any other non-terminal state: Updates status and cleans up
|
|
24
24
|
*/
|
|
25
|
-
export declare function handleStopSignal(config:
|
|
25
|
+
export declare function handleStopSignal(config: ResolvedWebhookConfig, sessionId: string, issueId: string, organizationId?: string): Promise<void>;
|
|
26
26
|
/**
|
|
27
27
|
* Resolve a state ID to its name using the Linear API.
|
|
28
28
|
*/
|
|
29
|
-
export declare function resolveStateName(config:
|
|
29
|
+
export declare function resolveStateName(config: ResolvedWebhookConfig, organizationId: string | undefined, issueId: string, stateId: string): Promise<string | undefined>;
|
|
30
30
|
/**
|
|
31
31
|
* Check if a project is allowed for auto-trigger.
|
|
32
32
|
*/
|
|
@@ -48,11 +48,11 @@ export declare function defaultGetPriority(workType: AgentWorkType): number;
|
|
|
48
48
|
/**
|
|
49
49
|
* Get the app URL for constructing dashboard links.
|
|
50
50
|
*/
|
|
51
|
-
export declare function getAppUrl(config:
|
|
51
|
+
export declare function getAppUrl(config: ResolvedWebhookConfig): string;
|
|
52
52
|
/**
|
|
53
53
|
* Get the priority for a work type, using config override if available.
|
|
54
54
|
*/
|
|
55
|
-
export declare function getPriority(config:
|
|
55
|
+
export declare function getPriority(config: ResolvedWebhookConfig, workType: AgentWorkType): number;
|
|
56
56
|
/**
|
|
57
57
|
* Work type messages for queuing acknowledgment.
|
|
58
58
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/webhook/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAanF,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/webhook/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAanF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAIxD;;GAEG;AACH,KAAK,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAA;AAEpD;;;GAGG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,iBAAiB,EACzB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,qBAAqB,EAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CA4Cf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,qBAAqB,EAC7B,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAgB7B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,OAAO,CAIpG;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAI/G;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAG3E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAalE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAE/D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,qBAAqB,EAAE,QAAQ,EAAE,aAAa,GAAG,MAAM,CAE1F;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAW5D,CAAA"}
|