@renseiai/plugin-linear 0.8.6

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.
Files changed (102) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +91 -0
  3. package/dist/src/__tests__/subpath-exports.test.d.ts +2 -0
  4. package/dist/src/__tests__/subpath-exports.test.d.ts.map +1 -0
  5. package/dist/src/__tests__/subpath-exports.test.js +136 -0
  6. package/dist/src/agent-client-project-repo.test.d.ts +2 -0
  7. package/dist/src/agent-client-project-repo.test.d.ts.map +1 -0
  8. package/dist/src/agent-client-project-repo.test.js +153 -0
  9. package/dist/src/agent-client.d.ts +261 -0
  10. package/dist/src/agent-client.d.ts.map +1 -0
  11. package/dist/src/agent-client.js +902 -0
  12. package/dist/src/agent-session.d.ts +303 -0
  13. package/dist/src/agent-session.d.ts.map +1 -0
  14. package/dist/src/agent-session.js +969 -0
  15. package/dist/src/checkbox-utils.d.ts +88 -0
  16. package/dist/src/checkbox-utils.d.ts.map +1 -0
  17. package/dist/src/checkbox-utils.js +120 -0
  18. package/dist/src/circuit-breaker.d.ts +76 -0
  19. package/dist/src/circuit-breaker.d.ts.map +1 -0
  20. package/dist/src/circuit-breaker.js +229 -0
  21. package/dist/src/circuit-breaker.test.d.ts +2 -0
  22. package/dist/src/circuit-breaker.test.d.ts.map +1 -0
  23. package/dist/src/circuit-breaker.test.js +292 -0
  24. package/dist/src/constants.d.ts +87 -0
  25. package/dist/src/constants.d.ts.map +1 -0
  26. package/dist/src/constants.js +101 -0
  27. package/dist/src/defaults/auto-trigger.d.ts +35 -0
  28. package/dist/src/defaults/auto-trigger.d.ts.map +1 -0
  29. package/dist/src/defaults/auto-trigger.js +36 -0
  30. package/dist/src/defaults/index.d.ts +12 -0
  31. package/dist/src/defaults/index.d.ts.map +1 -0
  32. package/dist/src/defaults/index.js +11 -0
  33. package/dist/src/defaults/priority.d.ts +20 -0
  34. package/dist/src/defaults/priority.d.ts.map +1 -0
  35. package/dist/src/defaults/priority.js +38 -0
  36. package/dist/src/defaults/prompts.d.ts +42 -0
  37. package/dist/src/defaults/prompts.d.ts.map +1 -0
  38. package/dist/src/defaults/prompts.js +313 -0
  39. package/dist/src/defaults/prompts.test.d.ts +2 -0
  40. package/dist/src/defaults/prompts.test.d.ts.map +1 -0
  41. package/dist/src/defaults/prompts.test.js +263 -0
  42. package/dist/src/defaults/work-type-detection.d.ts +19 -0
  43. package/dist/src/defaults/work-type-detection.d.ts.map +1 -0
  44. package/dist/src/defaults/work-type-detection.js +98 -0
  45. package/dist/src/errors.d.ts +91 -0
  46. package/dist/src/errors.d.ts.map +1 -0
  47. package/dist/src/errors.js +173 -0
  48. package/dist/src/frontend-adapter.d.ts +168 -0
  49. package/dist/src/frontend-adapter.d.ts.map +1 -0
  50. package/dist/src/frontend-adapter.js +314 -0
  51. package/dist/src/frontend-adapter.test.d.ts +2 -0
  52. package/dist/src/frontend-adapter.test.d.ts.map +1 -0
  53. package/dist/src/frontend-adapter.test.js +545 -0
  54. package/dist/src/index.d.ts +32 -0
  55. package/dist/src/index.d.ts.map +1 -0
  56. package/dist/src/index.js +35 -0
  57. package/dist/src/issue-tracker-adapter.d.ts +113 -0
  58. package/dist/src/issue-tracker-adapter.d.ts.map +1 -0
  59. package/dist/src/issue-tracker-adapter.js +169 -0
  60. package/dist/src/issue-tracker-proxy.d.ts +140 -0
  61. package/dist/src/issue-tracker-proxy.d.ts.map +1 -0
  62. package/dist/src/issue-tracker-proxy.js +10 -0
  63. package/dist/src/platform-adapter.d.ts +132 -0
  64. package/dist/src/platform-adapter.d.ts.map +1 -0
  65. package/dist/src/platform-adapter.js +260 -0
  66. package/dist/src/platform-adapter.test.d.ts +2 -0
  67. package/dist/src/platform-adapter.test.d.ts.map +1 -0
  68. package/dist/src/platform-adapter.test.js +468 -0
  69. package/dist/src/proxy-client.d.ts +103 -0
  70. package/dist/src/proxy-client.d.ts.map +1 -0
  71. package/dist/src/proxy-client.js +191 -0
  72. package/dist/src/rate-limiter.d.ts +64 -0
  73. package/dist/src/rate-limiter.d.ts.map +1 -0
  74. package/dist/src/rate-limiter.js +163 -0
  75. package/dist/src/rate-limiter.test.d.ts +2 -0
  76. package/dist/src/rate-limiter.test.d.ts.map +1 -0
  77. package/dist/src/rate-limiter.test.js +217 -0
  78. package/dist/src/retry.d.ts +59 -0
  79. package/dist/src/retry.d.ts.map +1 -0
  80. package/dist/src/retry.js +82 -0
  81. package/dist/src/retry.test.d.ts +2 -0
  82. package/dist/src/retry.test.d.ts.map +1 -0
  83. package/dist/src/retry.test.js +266 -0
  84. package/dist/src/tools/deployment-bridge.d.ts +34 -0
  85. package/dist/src/tools/deployment-bridge.d.ts.map +1 -0
  86. package/dist/src/tools/deployment-bridge.js +122 -0
  87. package/dist/src/tools/linear-plugin.d.ts +23 -0
  88. package/dist/src/tools/linear-plugin.d.ts.map +1 -0
  89. package/dist/src/tools/linear-plugin.js +175 -0
  90. package/dist/src/tools/linear-runner.d.ts +37 -0
  91. package/dist/src/tools/linear-runner.d.ts.map +1 -0
  92. package/dist/src/tools/linear-runner.js +810 -0
  93. package/dist/src/types.d.ts +492 -0
  94. package/dist/src/types.d.ts.map +1 -0
  95. package/dist/src/types.js +148 -0
  96. package/dist/src/utils.d.ts +52 -0
  97. package/dist/src/utils.d.ts.map +1 -0
  98. package/dist/src/utils.js +277 -0
  99. package/dist/src/webhook-types.d.ts +308 -0
  100. package/dist/src/webhook-types.d.ts.map +1 -0
  101. package/dist/src/webhook-types.js +46 -0
  102. package/package.json +73 -0
@@ -0,0 +1,492 @@
1
+ import type { LinearClient } from '@linear/sdk';
2
+ /**
3
+ * AgentSession states as defined by Linear Agent SDK
4
+ */
5
+ export type AgentSessionState = 'pending' | 'active' | 'error' | 'awaitingInput' | 'complete';
6
+ /**
7
+ * AgentActivity types as defined by Linear Agent API
8
+ */
9
+ export type AgentActivityType = 'thought' | 'action' | 'response' | 'elicitation' | 'error' | 'prompt';
10
+ /**
11
+ * AgentActivity signals - modifiers that provide additional instructions
12
+ * on how the activity should be interpreted
13
+ */
14
+ export type AgentActivitySignal = 'auth' | 'continue' | 'select' | 'stop';
15
+ /**
16
+ * Content for a thought activity - reasoning steps
17
+ */
18
+ export interface ThoughtActivityContent {
19
+ type: 'thought';
20
+ body: string;
21
+ }
22
+ /**
23
+ * Content for an action activity - tool calls
24
+ */
25
+ export interface ActionActivityContent {
26
+ type: 'action';
27
+ action: string;
28
+ parameter: string;
29
+ result?: string;
30
+ }
31
+ /**
32
+ * Content for a response activity - final responses
33
+ */
34
+ export interface ResponseActivityContent {
35
+ type: 'response';
36
+ body: string;
37
+ }
38
+ /**
39
+ * Content for an elicitation activity - asking for clarification
40
+ */
41
+ export interface ElicitationActivityContent {
42
+ type: 'elicitation';
43
+ body: string;
44
+ }
45
+ /**
46
+ * Content for an error activity - error reporting
47
+ */
48
+ export interface ErrorActivityContent {
49
+ type: 'error';
50
+ body: string;
51
+ }
52
+ /**
53
+ * Content for a prompt activity - prompts/instructions
54
+ */
55
+ export interface PromptActivityContent {
56
+ type: 'prompt';
57
+ body: string;
58
+ }
59
+ /**
60
+ * Union type for all activity content types
61
+ */
62
+ export type AgentActivityContentPayload = ThoughtActivityContent | ActionActivityContent | ResponseActivityContent | ElicitationActivityContent | ErrorActivityContent | PromptActivityContent;
63
+ /**
64
+ * Input for creating an agent activity via the native Linear API
65
+ */
66
+ export interface AgentActivityCreateInput {
67
+ agentSessionId: string;
68
+ content: AgentActivityContentPayload;
69
+ ephemeral?: boolean;
70
+ id?: string;
71
+ signal?: AgentActivitySignal;
72
+ }
73
+ /**
74
+ * Result of creating an agent activity
75
+ */
76
+ export interface AgentActivityResult {
77
+ success: boolean;
78
+ activityId?: string;
79
+ }
80
+ /**
81
+ * Legacy activity content for backward compatibility
82
+ * @deprecated Use AgentActivityContentPayload instead
83
+ */
84
+ export interface AgentActivityContent {
85
+ text: string;
86
+ metadata?: Record<string, unknown>;
87
+ }
88
+ /**
89
+ * Configuration for creating an agent activity (internal use)
90
+ */
91
+ export interface CreateActivityOptions {
92
+ type: AgentActivityType;
93
+ content: AgentActivityContent;
94
+ ephemeral?: boolean;
95
+ signals?: AgentSignals;
96
+ }
97
+ /**
98
+ * AgentPlan item states
99
+ */
100
+ export type AgentPlanItemState = 'pending' | 'inProgress' | 'completed' | 'canceled';
101
+ /**
102
+ * Linear's native plan item status values
103
+ * @see https://linear.app/developers/agents
104
+ */
105
+ export type LinearPlanStatus = 'pending' | 'inProgress' | 'completed' | 'canceled';
106
+ /**
107
+ * Linear's native plan item structure for agentSessionUpdate mutation
108
+ * @see https://linear.app/developers/agents
109
+ */
110
+ export interface LinearPlanItem {
111
+ /** The task description */
112
+ content: string;
113
+ /** Current status of the task */
114
+ status: LinearPlanStatus;
115
+ }
116
+ /**
117
+ * A single item in the agent's plan (internal representation)
118
+ * Supports nested children for more detailed task tracking
119
+ */
120
+ export interface AgentPlanItem {
121
+ id: string;
122
+ title: string;
123
+ state: AgentPlanItemState;
124
+ details?: string;
125
+ children?: AgentPlanItem[];
126
+ }
127
+ /**
128
+ * Full agent plan structure (internal representation)
129
+ */
130
+ export interface AgentPlan {
131
+ items: AgentPlanItem[];
132
+ }
133
+ /**
134
+ * Optional metadata for activity interpretation
135
+ */
136
+ export interface AgentSignals {
137
+ toolName?: string;
138
+ toolInput?: Record<string, unknown>;
139
+ toolOutput?: unknown;
140
+ error?: {
141
+ message: string;
142
+ code?: string;
143
+ stack?: string;
144
+ };
145
+ progress?: number;
146
+ [key: string]: unknown;
147
+ }
148
+ /**
149
+ * Pluggable rate limiter strategy.
150
+ *
151
+ * The default in-memory TokenBucket implements this. Consumers can provide
152
+ * a Redis-backed implementation for shared rate limiting across processes.
153
+ */
154
+ export interface RateLimiterStrategy {
155
+ acquire(): Promise<void>;
156
+ penalize(seconds: number): void | Promise<void>;
157
+ }
158
+ /**
159
+ * Pluggable circuit breaker strategy.
160
+ *
161
+ * The default in-memory CircuitBreaker implements this. Consumers can provide
162
+ * a Redis-backed implementation for shared circuit state across processes.
163
+ */
164
+ export interface CircuitBreakerStrategy {
165
+ canProceed(): boolean | Promise<boolean>;
166
+ recordSuccess(): void | Promise<void>;
167
+ recordAuthFailure(statusCode?: number): void | Promise<void>;
168
+ isAuthError(error: unknown): boolean;
169
+ reset(): void | Promise<void>;
170
+ }
171
+ /**
172
+ * Configuration for the circuit breaker
173
+ */
174
+ export interface CircuitBreakerConfig {
175
+ /** Consecutive auth failures before opening (default: 2) */
176
+ failureThreshold: number;
177
+ /** Milliseconds before half-open probe (default: 60_000) */
178
+ resetTimeoutMs: number;
179
+ /** Maximum reset timeout after exponential backoff (default: 300_000) */
180
+ maxResetTimeoutMs: number;
181
+ /** Backoff multiplier for reset timeout after probe failure (default: 2) */
182
+ backoffMultiplier: number;
183
+ /** HTTP status codes that count as auth failures (default: [400, 401, 403]) */
184
+ authErrorCodes: number[];
185
+ }
186
+ /**
187
+ * Configuration for the Linear Agent Client
188
+ */
189
+ /**
190
+ * Quota information extracted from Linear API response headers.
191
+ */
192
+ export interface LinearApiQuota {
193
+ /** Remaining requests in the current window */
194
+ requestsRemaining?: number;
195
+ /** Total request limit for the current window */
196
+ requestsLimit?: number;
197
+ /** Remaining complexity points in the current window */
198
+ complexityRemaining?: number;
199
+ /** Total complexity limit for the current window */
200
+ complexityLimit?: number;
201
+ /** Seconds until the rate limit window resets */
202
+ resetSeconds?: number;
203
+ }
204
+ export interface LinearAgentClientConfig {
205
+ apiKey: string;
206
+ baseUrl?: string;
207
+ retry?: RetryConfig;
208
+ /** Token bucket rate limiter configuration. Applied to all API calls. */
209
+ rateLimit?: Partial<import('./rate-limiter.js').TokenBucketConfig>;
210
+ /** Circuit breaker configuration. */
211
+ circuitBreaker?: Partial<CircuitBreakerConfig>;
212
+ /**
213
+ * Injectable rate limiter strategy (e.g., Redis-backed).
214
+ * When provided, replaces the default in-memory TokenBucket.
215
+ */
216
+ rateLimiterStrategy?: RateLimiterStrategy;
217
+ /**
218
+ * Injectable circuit breaker strategy (e.g., Redis-backed).
219
+ * When provided, replaces the default in-memory CircuitBreaker.
220
+ */
221
+ circuitBreakerStrategy?: CircuitBreakerStrategy;
222
+ /**
223
+ * Optional callback invoked after each successful API response.
224
+ * Receives quota information extracted from response headers.
225
+ * Use this to track API consumption across scans.
226
+ */
227
+ onApiResponse?: (quota: LinearApiQuota) => void;
228
+ }
229
+ /**
230
+ * Retry configuration with exponential backoff
231
+ */
232
+ export interface RetryConfig {
233
+ maxRetries?: number;
234
+ initialDelayMs?: number;
235
+ backoffMultiplier?: number;
236
+ maxDelayMs?: number;
237
+ retryableStatusCodes?: number[];
238
+ }
239
+ /**
240
+ * Standard Linear workflow states
241
+ */
242
+ export type LinearWorkflowStatus = 'Backlog' | 'Started' | 'Finished' | 'Delivered' | 'Accepted' | 'Rejected' | 'Canceled';
243
+ /**
244
+ * Type of agent work being performed based on issue status
245
+ *
246
+ * | Issue Status | Work Type | Agent Role |
247
+ * |--------------|------------------------|-----------------------------------------------|
248
+ * | Icebox | research | Research/story-writer |
249
+ * | Icebox | backlog-creation | Create backlog issues from research |
250
+ * | Backlog | development | Developer agents |
251
+ * | Backlog | coordination | Coordinate sub-issue execution |
252
+ * | Started | inflight | Developer (resume/continue) |
253
+ * | Finished | qa | QA agents |
254
+ * | Finished | qa-coordination | Coordinate QA across sub-issues |
255
+ * | Delivered | acceptance | Acceptance testing |
256
+ * | Delivered | acceptance-coordination| Coordinate acceptance across sub-issues |
257
+ * | Rejected | refinement | Refine and return to Backlog |
258
+ * | Rejected | refinement-coordination| Coordinate refinement across sub-issues |
259
+ */
260
+ export type AgentWorkType = 'research' | 'backlog-creation' | 'development' | 'inflight' | 'inflight-coordination' | 'qa' | 'acceptance' | 'refinement' | 'refinement-coordination' | 'coordination' | 'qa-coordination' | 'acceptance-coordination';
261
+ /**
262
+ * Mapping from Linear issue status to agent work type
263
+ */
264
+ export declare const STATUS_WORK_TYPE_MAP: Record<string, AgentWorkType>;
265
+ /**
266
+ * Terminal statuses where no agent work is needed
267
+ * Issues in these states are considered complete and should not be processed
268
+ */
269
+ export declare const TERMINAL_STATUSES: readonly ["Accepted", "Canceled", "Duplicate"];
270
+ export type TerminalStatus = typeof TERMINAL_STATUSES[number];
271
+ /**
272
+ * Status to transition to when agent session STARTS
273
+ * null means no transition on start
274
+ */
275
+ export declare const WORK_TYPE_START_STATUS: Record<AgentWorkType, LinearWorkflowStatus | null>;
276
+ /**
277
+ * Status to transition to when agent session COMPLETES successfully
278
+ * null means no auto-transition on completion
279
+ */
280
+ export declare const WORK_TYPE_COMPLETE_STATUS: Record<AgentWorkType, LinearWorkflowStatus | null>;
281
+ /**
282
+ * Status to transition to when agent work FAILS (e.g., QA rejected)
283
+ * null means no auto-transition on failure (stays in current status)
284
+ */
285
+ export declare const WORK_TYPE_FAIL_STATUS: Record<AgentWorkType, LinearWorkflowStatus | null>;
286
+ /**
287
+ * Work types that require an isolated git worktree.
288
+ * ALL work types now get worktrees to prevent agents from mutating the main
289
+ * checkout (e.g., running `git checkout` in the IDE's working tree).
290
+ */
291
+ export declare const WORK_TYPES_REQUIRING_WORKTREE: ReadonlySet<AgentWorkType>;
292
+ /**
293
+ * Allowed statuses for each work type
294
+ * Used to validate that an agent isn't assigned to an issue in the wrong status
295
+ */
296
+ export declare const WORK_TYPE_ALLOWED_STATUSES: Record<AgentWorkType, string[]>;
297
+ /**
298
+ * Valid work types for each status (reverse of WORK_TYPE_ALLOWED_STATUSES)
299
+ * Used to constrain keyword detection to only valid options for the current status
300
+ *
301
+ * For example:
302
+ * - Icebox issues can use keywords to choose between 'research' and 'backlog-creation'
303
+ * - Backlog issues only have 'development' as valid, so keywords won't change work type
304
+ * but could still provide agent specialization hints
305
+ */
306
+ export declare const STATUS_VALID_WORK_TYPES: Record<string, AgentWorkType[]>;
307
+ /**
308
+ * Get valid work types for a given status
309
+ * Returns empty array if status is unknown
310
+ */
311
+ export declare function getValidWorkTypesForStatus(status: string): AgentWorkType[];
312
+ /**
313
+ * Result of work type validation
314
+ */
315
+ export interface WorkTypeValidationResult {
316
+ valid: boolean;
317
+ error?: string;
318
+ }
319
+ /**
320
+ * Validate that a work type is appropriate for an issue's current status
321
+ *
322
+ * @param workType - The work type being assigned
323
+ * @param issueStatus - The current status of the issue
324
+ * @returns Validation result with error message if invalid
325
+ */
326
+ export declare function validateWorkTypeForStatus(workType: AgentWorkType, issueStatus: string): WorkTypeValidationResult;
327
+ /**
328
+ * Mapping of status names to their Linear state IDs
329
+ */
330
+ export interface StatusMapping {
331
+ [statusName: string]: string;
332
+ }
333
+ /**
334
+ * Configuration for creating/managing an agent session
335
+ */
336
+ export interface AgentSessionConfig {
337
+ client: LinearClient;
338
+ issueId: string;
339
+ sessionId?: string;
340
+ autoTransition?: boolean;
341
+ /**
342
+ * Type of work being performed.
343
+ * - 'development': Normal development work (transitions to Started on start)
344
+ * - 'qa': QA validation work (stays at Finished until QA passes, then Delivered)
345
+ * Defaults to 'development'.
346
+ */
347
+ workType?: AgentWorkType;
348
+ }
349
+ /**
350
+ * Result of session operations
351
+ */
352
+ export interface SessionOperationResult {
353
+ success: boolean;
354
+ sessionId?: string;
355
+ error?: Error;
356
+ }
357
+ /**
358
+ * External URL associated with an agent session
359
+ */
360
+ export interface AgentSessionExternalUrl {
361
+ /** Label for the URL (e.g., "Dashboard", "Logs") */
362
+ label: string;
363
+ /** The URL of the external resource */
364
+ url: string;
365
+ }
366
+ /**
367
+ * Input for updating an agent session via the Linear API
368
+ */
369
+ export interface AgentSessionUpdateInput {
370
+ /** The agent session ID to update */
371
+ sessionId: string;
372
+ /** External URLs linking to agent dashboard/logs */
373
+ externalUrls?: AgentSessionExternalUrl[];
374
+ /** External link URL (single, for backward compatibility) */
375
+ externalLink?: string;
376
+ /** Plan array showing agent execution strategy (Linear's native format) */
377
+ plan?: LinearPlanItem[];
378
+ }
379
+ /**
380
+ * Result of updating an agent session
381
+ */
382
+ export interface AgentSessionUpdateResult {
383
+ success: boolean;
384
+ sessionId?: string;
385
+ }
386
+ /**
387
+ * Input for creating an agent session on an issue via the Linear API
388
+ * @see https://linear.app/developers/agents
389
+ */
390
+ export interface AgentSessionCreateOnIssueInput {
391
+ /** The issue ID (UUID) or identifier (e.g., 'SUP-123') to create the session on */
392
+ issueId: string;
393
+ /** External URLs linking to agent dashboard/logs */
394
+ externalUrls?: AgentSessionExternalUrl[];
395
+ /** External link URL (single, for backward compatibility) */
396
+ externalLink?: string;
397
+ }
398
+ /**
399
+ * Result of creating an agent session on an issue
400
+ */
401
+ export interface AgentSessionCreateResult {
402
+ success: boolean;
403
+ /** The ID of the created agent session */
404
+ sessionId?: string;
405
+ }
406
+ /**
407
+ * Linear issue relationship types
408
+ * @see https://linear.app/developers/sdk
409
+ */
410
+ export type IssueRelationType = 'related' | 'blocks' | 'duplicate';
411
+ /**
412
+ * Input for creating an issue relation
413
+ */
414
+ export interface IssueRelationCreateInput {
415
+ issueId: string;
416
+ relatedIssueId: string;
417
+ type: IssueRelationType;
418
+ }
419
+ /**
420
+ * Result of creating/deleting an issue relation
421
+ */
422
+ export interface IssueRelationResult {
423
+ success: boolean;
424
+ relationId?: string;
425
+ }
426
+ /**
427
+ * Batch result for creating multiple relations
428
+ */
429
+ export interface IssueRelationBatchResult {
430
+ success: boolean;
431
+ relationIds: string[];
432
+ errors: Array<{
433
+ targetIssueId: string;
434
+ error: string;
435
+ }>;
436
+ }
437
+ /**
438
+ * Sub-issue with its blocking relations for dependency graph building
439
+ */
440
+ export interface SubIssueGraphNode {
441
+ issue: {
442
+ id: string;
443
+ identifier: string;
444
+ title: string;
445
+ description?: string;
446
+ status?: string;
447
+ priority: number;
448
+ labels: string[];
449
+ url: string;
450
+ };
451
+ /** Identifiers of issues that block this sub-issue */
452
+ blockedBy: string[];
453
+ /** Identifiers of issues that this sub-issue blocks */
454
+ blocks: string[];
455
+ }
456
+ /**
457
+ * Result of getSubIssueGraph - the complete dependency graph for a parent issue
458
+ */
459
+ export interface SubIssueGraph {
460
+ parentId: string;
461
+ parentIdentifier: string;
462
+ subIssues: SubIssueGraphNode[];
463
+ }
464
+ /**
465
+ * Lightweight sub-issue status info (no blocking relations)
466
+ * Used by QA and acceptance agents to validate sub-issue completion
467
+ */
468
+ export interface SubIssueStatus {
469
+ identifier: string;
470
+ title: string;
471
+ status: string;
472
+ }
473
+ /**
474
+ * Representation of an issue relation
475
+ */
476
+ export interface IssueRelationInfo {
477
+ id: string;
478
+ type: string;
479
+ issueId: string;
480
+ issueIdentifier?: string;
481
+ relatedIssueId: string;
482
+ relatedIssueIdentifier?: string;
483
+ createdAt: Date;
484
+ }
485
+ /**
486
+ * Result of querying issue relations
487
+ */
488
+ export interface IssueRelationsResult {
489
+ relations: IssueRelationInfo[];
490
+ inverseRelations: IssueRelationInfo[];
491
+ }
492
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,SAAS,GACT,QAAQ,GACR,OAAO,GACP,eAAe,GACf,UAAU,CAAA;AAEd;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,SAAS,GACT,QAAQ,GACR,UAAU,GACV,aAAa,GACb,OAAO,GACP,QAAQ,CAAA;AAEZ;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEzE;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,SAAS,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,QAAQ,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,aAAa,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,QAAQ,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;GAEG;AACH,MAAM,MAAM,2BAA2B,GACnC,sBAAsB,GACtB,qBAAqB,GACrB,uBAAuB,GACvB,0BAA0B,GAC1B,oBAAoB,GACpB,qBAAqB,CAAA;AAEzB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,2BAA2B,CAAA;IACpC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,mBAAmB,CAAA;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,iBAAiB,CAAA;IACvB,OAAO,EAAE,oBAAoB,CAAA;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,YAAY,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,YAAY,GACZ,WAAW,GACX,UAAU,CAAA;AAEd;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,UAAU,CAAA;AAElF;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,iCAAiC;IACjC,MAAM,EAAE,gBAAgB,CAAA;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,kBAAkB,CAAA;IACzB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAA;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,aAAa,EAAE,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACnC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,MAAM,CAAA;QACf,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;IACD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAChD;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,UAAU,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACxC,aAAa,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5D,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAA;IACpC,KAAK,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,CAAA;IACxB,4DAA4D;IAC5D,cAAc,EAAE,MAAM,CAAA;IACtB,yEAAyE;IACzE,iBAAiB,EAAE,MAAM,CAAA;IACzB,4EAA4E;IAC5E,iBAAiB,EAAE,MAAM,CAAA;IACzB,+EAA+E;IAC/E,cAAc,EAAE,MAAM,EAAE,CAAA;CACzB;AAED;;GAEG;AACH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,wDAAwD;IACxD,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,yEAAyE;IACzE,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,mBAAmB,EAAE,iBAAiB,CAAC,CAAA;IAClE,qCAAqC;IACrC,cAAc,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAA;IAC9C;;;OAGG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAA;IACzC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAA;IAC/C;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAA;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAA;CAChC;AAED;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAC5B,SAAS,GACT,SAAS,GACT,UAAU,GACV,WAAW,GACX,UAAU,GACV,UAAU,GACV,UAAU,CAAA;AAEd;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,kBAAkB,GAClB,aAAa,GACb,UAAU,GACV,uBAAuB,GACvB,IAAI,GACJ,YAAY,GACZ,YAAY,GACZ,yBAAyB,GACzB,cAAc,GACd,iBAAiB,GACjB,yBAAyB,CAAA;AAE7B;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAO9D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,gDAAiD,CAAA;AAC/E,MAAM,MAAM,cAAc,GAAG,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAA;AAE7D;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,aAAa,EAAE,oBAAoB,GAAG,IAAI,CAarF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,aAAa,EAAE,oBAAoB,GAAG,IAAI,CAaxF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,aAAa,EAAE,oBAAoB,GAAG,IAAI,CAapF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,EAAE,WAAW,CAAC,aAAa,CAanE,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,EAAE,CAatE,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,CAOnE,CAAA;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,EAAE,CAE1E;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,MAAM,GAClB,wBAAwB,CAW1B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,YAAY,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAA;IACb,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAA;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,oDAAoD;IACpD,YAAY,CAAC,EAAE,uBAAuB,EAAE,CAAA;IACxC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,cAAc,EAAE,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,8BAA8B;IAC7C,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAA;IACf,oDAAoD;IACpD,YAAY,CAAC,EAAE,uBAAuB,EAAE,CAAA;IACxC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAA;IAChB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAA;AAElE;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,iBAAiB,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,MAAM,EAAE,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACxD;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAA;QACV,UAAU,EAAE,MAAM,CAAA;QAClB,KAAK,EAAE,MAAM,CAAA;QACb,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,EAAE,MAAM,EAAE,CAAA;QAChB,GAAG,EAAE,MAAM,CAAA;KACZ,CAAA;IACD,sDAAsD;IACtD,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,uDAAuD;IACvD,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,iBAAiB,EAAE,CAAA;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,SAAS,EAAE,IAAI,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,iBAAiB,EAAE,CAAA;IAC9B,gBAAgB,EAAE,iBAAiB,EAAE,CAAA;CACtC"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Mapping from Linear issue status to agent work type
3
+ */
4
+ export const STATUS_WORK_TYPE_MAP = {
5
+ 'Icebox': 'research',
6
+ 'Backlog': 'development',
7
+ 'Started': 'inflight',
8
+ 'Finished': 'qa',
9
+ 'Delivered': 'acceptance',
10
+ 'Rejected': 'refinement',
11
+ };
12
+ /**
13
+ * Terminal statuses where no agent work is needed
14
+ * Issues in these states are considered complete and should not be processed
15
+ */
16
+ export const TERMINAL_STATUSES = ['Accepted', 'Canceled', 'Duplicate'];
17
+ /**
18
+ * Status to transition to when agent session STARTS
19
+ * null means no transition on start
20
+ */
21
+ export const WORK_TYPE_START_STATUS = {
22
+ 'research': null, // No transition from Icebox on start
23
+ 'backlog-creation': null, // No transition from Icebox on start
24
+ 'development': 'Started', // Backlog -> Started when agent begins
25
+ 'inflight': null, // Already Started, no change
26
+ 'inflight-coordination': null, // Already Started, no change
27
+ 'qa': null, // Already Finished
28
+ 'acceptance': null, // Already Delivered
29
+ 'refinement': null, // Already Rejected
30
+ 'refinement-coordination': null, // Already Rejected
31
+ 'coordination': 'Started', // Backlog -> Started when coordinator begins
32
+ 'qa-coordination': null, // Already Finished
33
+ 'acceptance-coordination': null, // Already Delivered
34
+ };
35
+ /**
36
+ * Status to transition to when agent session COMPLETES successfully
37
+ * null means no auto-transition on completion
38
+ */
39
+ export const WORK_TYPE_COMPLETE_STATUS = {
40
+ 'research': null, // No auto-transition, user moves to Backlog
41
+ 'backlog-creation': null, // Issues created in Backlog, source stays in Icebox
42
+ 'development': 'Finished', // Started -> Finished when work done
43
+ 'inflight': 'Finished', // Started -> Finished when work done
44
+ 'inflight-coordination': 'Finished', // Started -> Finished when all sub-issues done
45
+ 'qa': 'Delivered', // Finished -> Delivered on QA pass
46
+ 'acceptance': 'Accepted', // Delivered -> Accepted on acceptance pass
47
+ 'refinement': 'Backlog', // Rejected -> Backlog after refinement
48
+ 'refinement-coordination': 'Backlog', // Rejected -> Backlog after coordinated refinement (triggers coordination which re-runs failing sub-issues)
49
+ 'coordination': 'Finished', // Started -> Finished when all sub-issues done
50
+ 'qa-coordination': 'Delivered', // Finished -> Delivered when QA coordination passes
51
+ 'acceptance-coordination': 'Accepted', // Delivered -> Accepted when acceptance coordination passes
52
+ };
53
+ /**
54
+ * Status to transition to when agent work FAILS (e.g., QA rejected)
55
+ * null means no auto-transition on failure (stays in current status)
56
+ */
57
+ export const WORK_TYPE_FAIL_STATUS = {
58
+ 'research': null,
59
+ 'backlog-creation': null,
60
+ 'development': null,
61
+ 'inflight': null,
62
+ 'inflight-coordination': null,
63
+ 'qa': 'Backlog', // QA failure -> Backlog (developer/coordinator picks up with failure context)
64
+ 'acceptance': 'Rejected', // Acceptance failure -> Rejected (rejection handler diagnoses next steps)
65
+ 'refinement': null,
66
+ 'refinement-coordination': null,
67
+ 'coordination': null,
68
+ 'qa-coordination': 'Rejected', // QA coordination failure -> Rejected (refinement-coordination reads QA feedback and dispatches targeted fixes to failing sub-issues)
69
+ 'acceptance-coordination': 'Rejected', // Acceptance coordination failure -> Rejected
70
+ };
71
+ /**
72
+ * Work types that require an isolated git worktree.
73
+ * ALL work types now get worktrees to prevent agents from mutating the main
74
+ * checkout (e.g., running `git checkout` in the IDE's working tree).
75
+ */
76
+ export const WORK_TYPES_REQUIRING_WORKTREE = new Set([
77
+ 'development',
78
+ 'inflight',
79
+ 'inflight-coordination',
80
+ 'qa',
81
+ 'acceptance',
82
+ 'coordination',
83
+ 'qa-coordination',
84
+ 'acceptance-coordination',
85
+ 'research',
86
+ 'backlog-creation',
87
+ 'refinement',
88
+ 'refinement-coordination',
89
+ ]);
90
+ /**
91
+ * Allowed statuses for each work type
92
+ * Used to validate that an agent isn't assigned to an issue in the wrong status
93
+ */
94
+ export const WORK_TYPE_ALLOWED_STATUSES = {
95
+ 'research': ['Icebox'],
96
+ 'backlog-creation': ['Icebox'],
97
+ 'development': ['Backlog'],
98
+ 'inflight': ['Started'],
99
+ 'inflight-coordination': ['Started'],
100
+ 'qa': ['Finished'],
101
+ 'acceptance': ['Delivered'],
102
+ 'refinement': ['Rejected'],
103
+ 'refinement-coordination': ['Rejected'],
104
+ 'coordination': ['Backlog', 'Started'],
105
+ 'qa-coordination': ['Finished'],
106
+ 'acceptance-coordination': ['Delivered'],
107
+ };
108
+ /**
109
+ * Valid work types for each status (reverse of WORK_TYPE_ALLOWED_STATUSES)
110
+ * Used to constrain keyword detection to only valid options for the current status
111
+ *
112
+ * For example:
113
+ * - Icebox issues can use keywords to choose between 'research' and 'backlog-creation'
114
+ * - Backlog issues only have 'development' as valid, so keywords won't change work type
115
+ * but could still provide agent specialization hints
116
+ */
117
+ export const STATUS_VALID_WORK_TYPES = {
118
+ 'Icebox': ['research', 'backlog-creation'],
119
+ 'Backlog': ['development', 'coordination'],
120
+ 'Started': ['inflight', 'inflight-coordination'],
121
+ 'Finished': ['qa', 'qa-coordination'],
122
+ 'Delivered': ['acceptance', 'acceptance-coordination'],
123
+ 'Rejected': ['refinement', 'refinement-coordination'],
124
+ };
125
+ /**
126
+ * Get valid work types for a given status
127
+ * Returns empty array if status is unknown
128
+ */
129
+ export function getValidWorkTypesForStatus(status) {
130
+ return STATUS_VALID_WORK_TYPES[status] ?? [];
131
+ }
132
+ /**
133
+ * Validate that a work type is appropriate for an issue's current status
134
+ *
135
+ * @param workType - The work type being assigned
136
+ * @param issueStatus - The current status of the issue
137
+ * @returns Validation result with error message if invalid
138
+ */
139
+ export function validateWorkTypeForStatus(workType, issueStatus) {
140
+ const allowedStatuses = WORK_TYPE_ALLOWED_STATUSES[workType];
141
+ if (!allowedStatuses.includes(issueStatus)) {
142
+ return {
143
+ valid: false,
144
+ error: `Cannot assign ${workType} work to issue in ${issueStatus} status. Expected: ${allowedStatuses.join(', ')}`,
145
+ };
146
+ }
147
+ return { valid: true };
148
+ }