@renseiai/agentfactory-linear 0.8.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/LICENSE +21 -0
- package/README.md +91 -0
- package/dist/src/agent-client-project-repo.test.d.ts +2 -0
- package/dist/src/agent-client-project-repo.test.d.ts.map +1 -0
- package/dist/src/agent-client-project-repo.test.js +153 -0
- package/dist/src/agent-client.d.ts +261 -0
- package/dist/src/agent-client.d.ts.map +1 -0
- package/dist/src/agent-client.js +902 -0
- package/dist/src/agent-session.d.ts +303 -0
- package/dist/src/agent-session.d.ts.map +1 -0
- package/dist/src/agent-session.js +969 -0
- package/dist/src/checkbox-utils.d.ts +88 -0
- package/dist/src/checkbox-utils.d.ts.map +1 -0
- package/dist/src/checkbox-utils.js +120 -0
- package/dist/src/circuit-breaker.d.ts +76 -0
- package/dist/src/circuit-breaker.d.ts.map +1 -0
- package/dist/src/circuit-breaker.js +229 -0
- package/dist/src/circuit-breaker.test.d.ts +2 -0
- package/dist/src/circuit-breaker.test.d.ts.map +1 -0
- package/dist/src/circuit-breaker.test.js +292 -0
- package/dist/src/constants.d.ts +87 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +101 -0
- package/dist/src/defaults/auto-trigger.d.ts +35 -0
- package/dist/src/defaults/auto-trigger.d.ts.map +1 -0
- package/dist/src/defaults/auto-trigger.js +36 -0
- package/dist/src/defaults/index.d.ts +12 -0
- package/dist/src/defaults/index.d.ts.map +1 -0
- package/dist/src/defaults/index.js +11 -0
- package/dist/src/defaults/priority.d.ts +20 -0
- package/dist/src/defaults/priority.d.ts.map +1 -0
- package/dist/src/defaults/priority.js +37 -0
- package/dist/src/defaults/prompts.d.ts +42 -0
- package/dist/src/defaults/prompts.d.ts.map +1 -0
- package/dist/src/defaults/prompts.js +310 -0
- package/dist/src/defaults/prompts.test.d.ts +2 -0
- package/dist/src/defaults/prompts.test.d.ts.map +1 -0
- package/dist/src/defaults/prompts.test.js +263 -0
- package/dist/src/defaults/work-type-detection.d.ts +19 -0
- package/dist/src/defaults/work-type-detection.d.ts.map +1 -0
- package/dist/src/defaults/work-type-detection.js +93 -0
- package/dist/src/errors.d.ts +91 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +173 -0
- package/dist/src/frontend-adapter.d.ts +168 -0
- package/dist/src/frontend-adapter.d.ts.map +1 -0
- package/dist/src/frontend-adapter.js +314 -0
- package/dist/src/frontend-adapter.test.d.ts +2 -0
- package/dist/src/frontend-adapter.test.d.ts.map +1 -0
- package/dist/src/frontend-adapter.test.js +545 -0
- package/dist/src/index.d.ts +28 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +30 -0
- package/dist/src/issue-tracker-proxy.d.ts +140 -0
- package/dist/src/issue-tracker-proxy.d.ts.map +1 -0
- package/dist/src/issue-tracker-proxy.js +10 -0
- package/dist/src/platform-adapter.d.ts +132 -0
- package/dist/src/platform-adapter.d.ts.map +1 -0
- package/dist/src/platform-adapter.js +260 -0
- package/dist/src/platform-adapter.test.d.ts +2 -0
- package/dist/src/platform-adapter.test.d.ts.map +1 -0
- package/dist/src/platform-adapter.test.js +468 -0
- package/dist/src/proxy-client.d.ts +103 -0
- package/dist/src/proxy-client.d.ts.map +1 -0
- package/dist/src/proxy-client.js +191 -0
- package/dist/src/rate-limiter.d.ts +64 -0
- package/dist/src/rate-limiter.d.ts.map +1 -0
- package/dist/src/rate-limiter.js +163 -0
- package/dist/src/rate-limiter.test.d.ts +2 -0
- package/dist/src/rate-limiter.test.d.ts.map +1 -0
- package/dist/src/rate-limiter.test.js +217 -0
- package/dist/src/retry.d.ts +59 -0
- package/dist/src/retry.d.ts.map +1 -0
- package/dist/src/retry.js +82 -0
- package/dist/src/types.d.ts +492 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +143 -0
- package/dist/src/utils.d.ts +52 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/utils.js +277 -0
- package/dist/src/webhook-types.d.ts +308 -0
- package/dist/src/webhook-types.d.ts.map +1 -0
- package/dist/src/webhook-types.js +46 -0
- package/package.json +70 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default prompt templates for each work type.
|
|
3
|
+
*
|
|
4
|
+
* These provide sensible defaults that can be overridden by consumers.
|
|
5
|
+
* The Rensei project overrides these with its own prompts.ts.
|
|
6
|
+
*/
|
|
7
|
+
import type { AgentWorkType, SubIssueStatus } from '../types.js';
|
|
8
|
+
export declare const WORK_RESULT_MARKER_INSTRUCTION = "\n\nMANDATORY \u2014 Structured Result Marker:\nYou MUST include exactly one of these HTML comment markers in your final output:\n- On pass: <!-- WORK_RESULT:passed -->\n- On fail: <!-- WORK_RESULT:failed -->\nWithout this marker, the orchestrator CANNOT detect your result and the issue status will NOT be updated. Even if you encounter errors, always emit <!-- WORK_RESULT:failed -->.";
|
|
9
|
+
export declare const READ_ONLY_CONSTRAINT = "\n\nCRITICAL CONSTRAINT \u2014 READ-ONLY ROLE:\nYou are a VALIDATION agent, NOT a development agent. You MUST NOT modify any source code, configuration files, migration files, or project files. Your role is strictly to READ, VALIDATE, and REPORT.\nFORBIDDEN actions: creating files, editing files, writing code, committing changes, patching snapshots, fixing bugs, resolving errors in code.\nALLOWED actions: reading files, running tests, running builds, checking CI status, posting comments, merging PRs (acceptance only), updating Linear status.\nIf you discover issues (missing files, broken builds, failing tests), REPORT them in your result comment and emit WORK_RESULT:failed. Do NOT attempt to fix them.";
|
|
10
|
+
export declare const PR_SELECTION_GUIDANCE = "\n\nPR Selection (Multi-PR Handling):\nIssues may have multiple PRs. Select the correct one:\n1. Check linked PRs in the issue attachments/links for GitHub PR URLs\n2. Filter by state \u2014 prefer OPEN over MERGED over CLOSED: gh pr view NNN --json state\n3. If multiple OPEN PRs, pick the most recently created one\n4. Fallback search by branch: gh pr list --head \"$(git branch --show-current)\" --state open\n5. Last resort search by issue ID: gh pr list --state open --search \"[issue-id]\"\n6. If no PR found, emit WORK_RESULT:failed with explanation";
|
|
11
|
+
/**
|
|
12
|
+
* Context from the workflow state machine for retry enrichment.
|
|
13
|
+
* Injected when an issue has been through previous dev-QA-rejected cycles.
|
|
14
|
+
*/
|
|
15
|
+
export interface WorkflowContext {
|
|
16
|
+
cycleCount: number;
|
|
17
|
+
strategy: string;
|
|
18
|
+
failureSummary: string | null;
|
|
19
|
+
qaAttemptCount?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Build the failure context block to append to prompts for retries.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildFailureContextBlock(workType: AgentWorkType, context: WorkflowContext): string;
|
|
25
|
+
/**
|
|
26
|
+
* Generate a default prompt for a given work type and issue identifier.
|
|
27
|
+
*
|
|
28
|
+
* @param identifier - The issue identifier (e.g., "PROJ-123")
|
|
29
|
+
* @param workType - The type of work to perform
|
|
30
|
+
* @param mentionContext - Optional additional context from a user mention
|
|
31
|
+
* @param workflowContext - Optional workflow state context for retry enrichment
|
|
32
|
+
*/
|
|
33
|
+
export declare function defaultGeneratePrompt(identifier: string, workType: AgentWorkType, mentionContext?: string, workflowContext?: WorkflowContext): string;
|
|
34
|
+
/**
|
|
35
|
+
* Build default QA context for parent issues with sub-issues.
|
|
36
|
+
*/
|
|
37
|
+
export declare function defaultBuildParentQAContext(issueIdentifier: string, subIssueStatuses: SubIssueStatus[]): string;
|
|
38
|
+
/**
|
|
39
|
+
* Build default acceptance context for parent issues with sub-issues.
|
|
40
|
+
*/
|
|
41
|
+
export declare function defaultBuildParentAcceptanceContext(issueIdentifier: string, subIssueStatuses: SubIssueStatus[]): string;
|
|
42
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/defaults/prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAahE,eAAO,MAAM,8BAA8B,uYAMsI,CAAA;AAEjL,eAAO,MAAM,oBAAoB,2sBAMiI,CAAA;AAElK,eAAO,MAAM,qBAAqB,ijBAS0B,CAAA;AAE5D;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,eAAe,GACvB,MAAM,CA0DR;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,aAAa,EACvB,cAAc,CAAC,EAAE,MAAM,EACvB,eAAe,CAAC,EAAE,eAAe,GAChC,MAAM,CAgKR;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,eAAe,EAAE,MAAM,EACvB,gBAAgB,EAAE,cAAc,EAAE,GACjC,MAAM,CAoBR;AAED;;GAEG;AACH,wBAAgB,mCAAmC,CACjD,eAAe,EAAE,MAAM,EACvB,gBAAgB,EAAE,cAAc,EAAE,GACjC,MAAM,CAmBR"}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default prompt templates for each work type.
|
|
3
|
+
*
|
|
4
|
+
* These provide sensible defaults that can be overridden by consumers.
|
|
5
|
+
* The Rensei project overrides these with its own prompts.ts.
|
|
6
|
+
*/
|
|
7
|
+
const HUMAN_BLOCKER_INSTRUCTION = `
|
|
8
|
+
|
|
9
|
+
HUMAN-NEEDED BLOCKERS:
|
|
10
|
+
If you encounter work that requires human action and cannot be resolved autonomously
|
|
11
|
+
(e.g., missing API keys/credentials, infrastructure not provisioned, third-party onboarding,
|
|
12
|
+
manual setup steps, policy decisions, access permissions), create a blocker issue:
|
|
13
|
+
pnpm af-linear create-blocker <SOURCE-ISSUE-ID> --title "What human needs to do" --description "Detailed steps"
|
|
14
|
+
This creates a tracked issue in Icebox with 'Needs Human' label, linked as blocking the source issue.
|
|
15
|
+
Do NOT silently skip human-needed work or bury it in comments.
|
|
16
|
+
Only create blockers for things that genuinely require a human — not for things you can retry or work around.`;
|
|
17
|
+
export const WORK_RESULT_MARKER_INSTRUCTION = `
|
|
18
|
+
|
|
19
|
+
MANDATORY — Structured Result Marker:
|
|
20
|
+
You MUST include exactly one of these HTML comment markers in your final output:
|
|
21
|
+
- On pass: <!-- WORK_RESULT:passed -->
|
|
22
|
+
- On fail: <!-- WORK_RESULT:failed -->
|
|
23
|
+
Without this marker, the orchestrator CANNOT detect your result and the issue status will NOT be updated. Even if you encounter errors, always emit <!-- WORK_RESULT:failed -->.`;
|
|
24
|
+
export const READ_ONLY_CONSTRAINT = `
|
|
25
|
+
|
|
26
|
+
CRITICAL CONSTRAINT — READ-ONLY ROLE:
|
|
27
|
+
You are a VALIDATION agent, NOT a development agent. You MUST NOT modify any source code, configuration files, migration files, or project files. Your role is strictly to READ, VALIDATE, and REPORT.
|
|
28
|
+
FORBIDDEN actions: creating files, editing files, writing code, committing changes, patching snapshots, fixing bugs, resolving errors in code.
|
|
29
|
+
ALLOWED actions: reading files, running tests, running builds, checking CI status, posting comments, merging PRs (acceptance only), updating Linear status.
|
|
30
|
+
If you discover issues (missing files, broken builds, failing tests), REPORT them in your result comment and emit WORK_RESULT:failed. Do NOT attempt to fix them.`;
|
|
31
|
+
export const PR_SELECTION_GUIDANCE = `
|
|
32
|
+
|
|
33
|
+
PR Selection (Multi-PR Handling):
|
|
34
|
+
Issues may have multiple PRs. Select the correct one:
|
|
35
|
+
1. Check linked PRs in the issue attachments/links for GitHub PR URLs
|
|
36
|
+
2. Filter by state — prefer OPEN over MERGED over CLOSED: gh pr view NNN --json state
|
|
37
|
+
3. If multiple OPEN PRs, pick the most recently created one
|
|
38
|
+
4. Fallback search by branch: gh pr list --head "$(git branch --show-current)" --state open
|
|
39
|
+
5. Last resort search by issue ID: gh pr list --state open --search "[issue-id]"
|
|
40
|
+
6. If no PR found, emit WORK_RESULT:failed with explanation`;
|
|
41
|
+
/**
|
|
42
|
+
* Build the failure context block to append to prompts for retries.
|
|
43
|
+
*/
|
|
44
|
+
export function buildFailureContextBlock(workType, context) {
|
|
45
|
+
if (context.cycleCount <= 0)
|
|
46
|
+
return '';
|
|
47
|
+
switch (workType) {
|
|
48
|
+
case 'refinement': {
|
|
49
|
+
if (context.strategy === 'decompose') {
|
|
50
|
+
return `\n\n## Decomposition Required (Cycle ${context.cycleCount})
|
|
51
|
+
|
|
52
|
+
This issue has been through ${context.cycleCount} development-QA cycle(s) and keeps failing.
|
|
53
|
+
Instead of refining, DECOMPOSE this issue into smaller, independently testable pieces.
|
|
54
|
+
|
|
55
|
+
### Failure History
|
|
56
|
+
${context.failureSummary ?? 'No details recorded.'}
|
|
57
|
+
|
|
58
|
+
### Decomposition Instructions
|
|
59
|
+
- Break this issue into smaller sub-issues (use --parentId to make them children)
|
|
60
|
+
- Each sub-issue must have clear, unambiguous acceptance criteria
|
|
61
|
+
- Each sub-issue must be testable in isolation
|
|
62
|
+
- Address one specific concern that previous attempts failed on
|
|
63
|
+
- After creating sub-issues, keep the PARENT issue in Icebox for human review`;
|
|
64
|
+
}
|
|
65
|
+
return `\n\n## Previous Failure Context
|
|
66
|
+
|
|
67
|
+
This issue has been through ${context.cycleCount} development-QA cycle(s).
|
|
68
|
+
|
|
69
|
+
### Failure History
|
|
70
|
+
${context.failureSummary ?? 'No details recorded.'}
|
|
71
|
+
|
|
72
|
+
### Instructions
|
|
73
|
+
- Read the failure history carefully before making changes
|
|
74
|
+
- Do NOT repeat approaches that already failed
|
|
75
|
+
- If the acceptance criteria are ambiguous, update them to be testable before fixing code
|
|
76
|
+
- Focus on the ROOT CAUSE, not symptoms`;
|
|
77
|
+
}
|
|
78
|
+
case 'development':
|
|
79
|
+
case 'coordination': {
|
|
80
|
+
return `\n\n## Retry Context
|
|
81
|
+
|
|
82
|
+
This is retry #${context.cycleCount} for this issue. Previous QA failures:
|
|
83
|
+
${context.failureSummary ?? 'No details recorded.'}
|
|
84
|
+
|
|
85
|
+
Pay special attention to the areas that failed QA previously.`;
|
|
86
|
+
}
|
|
87
|
+
case 'qa':
|
|
88
|
+
case 'qa-coordination': {
|
|
89
|
+
if (!context.failureSummary)
|
|
90
|
+
return '';
|
|
91
|
+
return `\n\n## Previous QA Results
|
|
92
|
+
This issue has been QA'd ${context.qaAttemptCount ?? context.cycleCount} times previously.
|
|
93
|
+
${context.failureSummary}
|
|
94
|
+
Focus validation on these previously failing areas.`;
|
|
95
|
+
}
|
|
96
|
+
default:
|
|
97
|
+
return '';
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Generate a default prompt for a given work type and issue identifier.
|
|
102
|
+
*
|
|
103
|
+
* @param identifier - The issue identifier (e.g., "PROJ-123")
|
|
104
|
+
* @param workType - The type of work to perform
|
|
105
|
+
* @param mentionContext - Optional additional context from a user mention
|
|
106
|
+
* @param workflowContext - Optional workflow state context for retry enrichment
|
|
107
|
+
*/
|
|
108
|
+
export function defaultGeneratePrompt(identifier, workType, mentionContext, workflowContext) {
|
|
109
|
+
let basePrompt;
|
|
110
|
+
switch (workType) {
|
|
111
|
+
case 'research':
|
|
112
|
+
basePrompt = `Research and flesh out story ${identifier}. Analyze requirements, identify technical approach, estimate complexity, and update the story description with detailed acceptance criteria. Do NOT implement code.`;
|
|
113
|
+
break;
|
|
114
|
+
case 'backlog-creation':
|
|
115
|
+
basePrompt = `Create backlog issues from the researched story ${identifier}.
|
|
116
|
+
Read the issue description, identify distinct work items, classify each as bug/feature/chore,
|
|
117
|
+
and create appropriately scoped issues in Icebox status (so a human can review before moving to Backlog).
|
|
118
|
+
Choose the correct issue structure based on the work:
|
|
119
|
+
- Sub-issues (--parentId): When work is a single concern with sequential/parallel phases sharing context and dependencies.
|
|
120
|
+
- Independent issues (--type related): When items are unrelated work in different codebase areas with no shared context.
|
|
121
|
+
- Single issue rewrite: When scope is atomic (single concern, few files, no phases). Rewrite source in-place, keep in Icebox.
|
|
122
|
+
When creating multiple issues, always add "related" links between them AND blocking relations where one step depends on another.
|
|
123
|
+
Do NOT wait for user approval - create issues automatically.`;
|
|
124
|
+
break;
|
|
125
|
+
case 'development':
|
|
126
|
+
basePrompt = `Start work on ${identifier}. Implement the feature/fix as specified.`;
|
|
127
|
+
break;
|
|
128
|
+
case 'inflight':
|
|
129
|
+
basePrompt = `Continue work on ${identifier}. Resume where you left off.`;
|
|
130
|
+
break;
|
|
131
|
+
case 'qa':
|
|
132
|
+
basePrompt = `QA ${identifier}. Validate the implementation against acceptance criteria.
|
|
133
|
+
${READ_ONLY_CONSTRAINT}
|
|
134
|
+
${WORK_RESULT_MARKER_INSTRUCTION}
|
|
135
|
+
${PR_SELECTION_GUIDANCE}
|
|
136
|
+
|
|
137
|
+
Validation Steps:
|
|
138
|
+
1. Find and validate the correct PR (see PR selection above)
|
|
139
|
+
2. Run tests scoped to the affected packages
|
|
140
|
+
3. Verify the build passes
|
|
141
|
+
4. Check deployment status (CI checks on the PR)
|
|
142
|
+
5. Review changes against issue requirements
|
|
143
|
+
6. Post result comment with the structured marker`;
|
|
144
|
+
break;
|
|
145
|
+
case 'acceptance':
|
|
146
|
+
basePrompt = `Process acceptance for ${identifier}. Validate development and QA work is complete, verify PR is ready to merge (CI passing, no conflicts), merge the PR, and clean up local resources.
|
|
147
|
+
${READ_ONLY_CONSTRAINT}
|
|
148
|
+
${WORK_RESULT_MARKER_INSTRUCTION}
|
|
149
|
+
${PR_SELECTION_GUIDANCE}
|
|
150
|
+
|
|
151
|
+
Acceptance Steps:
|
|
152
|
+
1. Find and validate the correct PR (see PR selection above)
|
|
153
|
+
2. Verify CI is passing and there are no merge conflicts
|
|
154
|
+
3. Confirm QA has passed (check issue status or QA comments)
|
|
155
|
+
4. Merge the PR
|
|
156
|
+
5. Delete the remote branch after successful merge
|
|
157
|
+
6. Post result comment with the structured marker`;
|
|
158
|
+
break;
|
|
159
|
+
case 'refinement':
|
|
160
|
+
basePrompt = `Refine ${identifier} based on rejection feedback. Read comments, update requirements, then return to Backlog.`;
|
|
161
|
+
break;
|
|
162
|
+
case 'coordination': {
|
|
163
|
+
const isRetry = workflowContext && workflowContext.cycleCount > 0;
|
|
164
|
+
if (isRetry) {
|
|
165
|
+
basePrompt = `Fix issues found during QA for parent issue ${identifier}.
|
|
166
|
+
|
|
167
|
+
REWORK MODE — DO NOT re-coordinate sub-issues from scratch.
|
|
168
|
+
All sub-issues are already Finished and a PR already exists. QA failed and specific fixes are needed.
|
|
169
|
+
|
|
170
|
+
MANDATORY FIRST STEPS:
|
|
171
|
+
1. Read the most recent QA failure comments: pnpm af-linear list-comments ${identifier}
|
|
172
|
+
2. Identify the SPECIFIC fixes needed from the QA failure details below
|
|
173
|
+
3. Apply fixes directly — do NOT re-spawn sub-agents for already-complete work
|
|
174
|
+
4. Commit fixes, push to the existing PR branch
|
|
175
|
+
5. Run full validation: pnpm typecheck && pnpm build && pnpm test
|
|
176
|
+
6. Update parent issue status to Finished
|
|
177
|
+
|
|
178
|
+
COMMON REWORK FIXES:
|
|
179
|
+
- Missing migration .json snapshots: Find .ts migrations without .json, patch the latest snapshot
|
|
180
|
+
- TypeScript errors: Read the error details, fix the type issues
|
|
181
|
+
- Missing API fields: Update route handlers to include missing fields
|
|
182
|
+
- Build failures: Run pnpm build, diagnose, fix
|
|
183
|
+
|
|
184
|
+
If the existing PR branch is checked out, work directly on it. Do not create a new branch or PR.`;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
basePrompt = `Coordinate sub-issue execution for parent issue ${identifier}. Fetch sub-issues with dependency graph, create tasks mapping to each sub-issue, spawn sub-agents for unblocked sub-issues in parallel, monitor completion, and create a single PR with all changes when done.
|
|
188
|
+
|
|
189
|
+
SUB-ISSUE STATUS MANAGEMENT:
|
|
190
|
+
Update sub-issue statuses in Linear as work progresses:
|
|
191
|
+
- When starting work on a sub-issue: update status to Started
|
|
192
|
+
- When a sub-agent completes a sub-issue: update status to Finished
|
|
193
|
+
- If a sub-agent fails: add a comment explaining the failure
|
|
194
|
+
|
|
195
|
+
COMPLETION VERIFICATION:
|
|
196
|
+
Before marking the parent issue as complete, verify ALL sub-issues are in Finished status.
|
|
197
|
+
If any sub-issue is not Finished, report the failure and do not mark the parent as complete.`;
|
|
198
|
+
}
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
case 'qa-coordination':
|
|
202
|
+
basePrompt = `Coordinate QA across sub-issues for parent issue ${identifier}. Fetch sub-issues, validate each against acceptance criteria, collect pass/fail results, and roll up to parent.
|
|
203
|
+
${READ_ONLY_CONSTRAINT}
|
|
204
|
+
${WORK_RESULT_MARKER_INSTRUCTION}
|
|
205
|
+
${PR_SELECTION_GUIDANCE}
|
|
206
|
+
|
|
207
|
+
QA Coordination Steps:
|
|
208
|
+
1. Find and validate the correct PR (see PR selection above)
|
|
209
|
+
2. Fetch all sub-issues and verify each is in Finished or later status
|
|
210
|
+
3. Run tests scoped to the affected packages
|
|
211
|
+
4. Verify the build passes (pnpm typecheck && pnpm build)
|
|
212
|
+
5. Review changes against each sub-issue's acceptance criteria
|
|
213
|
+
6. Verify cross-cutting concerns: shared types, API contracts, data flow between sub-issues
|
|
214
|
+
7. Check deployment status (CI checks on the PR)
|
|
215
|
+
|
|
216
|
+
Pass/Fail:
|
|
217
|
+
- PASS (emit <!-- WORK_RESULT:passed -->): ALL tests pass, build succeeds, all sub-issues implemented, deployment healthy
|
|
218
|
+
- FAIL (emit <!-- WORK_RESULT:failed -->): ANY test failure, build error, missing implementation, deployment failure
|
|
219
|
+
Post a result comment listing per-sub-issue findings, then emit the marker.`;
|
|
220
|
+
break;
|
|
221
|
+
case 'acceptance-coordination':
|
|
222
|
+
basePrompt = `Coordinate acceptance across sub-issues for parent issue ${identifier}. Verify all sub-issues are Delivered, validate the PR, merge it, and bulk-update sub-issues to Accepted.
|
|
223
|
+
${READ_ONLY_CONSTRAINT}
|
|
224
|
+
${WORK_RESULT_MARKER_INSTRUCTION}
|
|
225
|
+
${PR_SELECTION_GUIDANCE}
|
|
226
|
+
|
|
227
|
+
Acceptance Coordination Steps:
|
|
228
|
+
1. Find and validate the correct PR (see PR selection above)
|
|
229
|
+
2. Verify ALL sub-issues are in Delivered or Accepted status
|
|
230
|
+
3. Verify CI is passing and there are no merge conflicts
|
|
231
|
+
4. Merge the PR
|
|
232
|
+
5. Delete the remote branch after successful merge
|
|
233
|
+
6. Post result comment with per-sub-issue status, then emit the marker
|
|
234
|
+
|
|
235
|
+
Pass/Fail:
|
|
236
|
+
- PASS (emit <!-- WORK_RESULT:passed -->): All sub-issues Delivered, CI passing, PR merged successfully
|
|
237
|
+
- FAIL (emit <!-- WORK_RESULT:failed -->): Incomplete sub-issues, CI failure, merge conflicts, merge failed
|
|
238
|
+
If ANY issue prevents merging, do NOT attempt to fix it — emit WORK_RESULT:failed with details.`;
|
|
239
|
+
break;
|
|
240
|
+
case 'refinement-coordination':
|
|
241
|
+
basePrompt = `Coordinate refinement across sub-issues for parent issue ${identifier}.
|
|
242
|
+
Read the QA/acceptance failure comments to identify which sub-issues failed and why.
|
|
243
|
+
For each failing sub-issue, update its description with the specific failure feedback and move it back to Backlog.
|
|
244
|
+
Leave passing sub-issues in their current state — do not re-run them.
|
|
245
|
+
Once failing sub-issues are triaged, the orchestrator will move the parent to Backlog for re-coordination.
|
|
246
|
+
|
|
247
|
+
Refinement Coordination Steps:
|
|
248
|
+
1. Read comments on ${identifier} to find the QA/acceptance failure report
|
|
249
|
+
2. Fetch sub-issues: pnpm af-linear list-sub-issues ${identifier}
|
|
250
|
+
3. For each failing sub-issue: update description with failure details, move to Backlog
|
|
251
|
+
4. Leave passing sub-issues unchanged
|
|
252
|
+
|
|
253
|
+
IMPORTANT: Do NOT implement fixes yourself — only triage and route feedback to the correct sub-issues.`;
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
basePrompt += HUMAN_BLOCKER_INSTRUCTION;
|
|
257
|
+
// Inject workflow failure context for retries
|
|
258
|
+
if (workflowContext) {
|
|
259
|
+
basePrompt += buildFailureContextBlock(workType, workflowContext);
|
|
260
|
+
}
|
|
261
|
+
if (mentionContext) {
|
|
262
|
+
return `${basePrompt}\n\nAdditional context from the user's mention:\n${mentionContext}`;
|
|
263
|
+
}
|
|
264
|
+
return basePrompt;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Build default QA context for parent issues with sub-issues.
|
|
268
|
+
*/
|
|
269
|
+
export function defaultBuildParentQAContext(issueIdentifier, subIssueStatuses) {
|
|
270
|
+
const subIssueList = subIssueStatuses
|
|
271
|
+
.map(s => `- ${s.identifier}: ${s.title} (Status: ${s.status})`)
|
|
272
|
+
.join('\n');
|
|
273
|
+
return `QA ${issueIdentifier} (parent issue with ${subIssueStatuses.length} sub-issues).
|
|
274
|
+
|
|
275
|
+
## Sub-Issues
|
|
276
|
+
${subIssueList}
|
|
277
|
+
|
|
278
|
+
## Holistic QA Instructions
|
|
279
|
+
This is a parent issue whose work was coordinated across multiple sub-issues.
|
|
280
|
+
Perform holistic validation beyond individual sub-issue checks:
|
|
281
|
+
|
|
282
|
+
1. **Scope Coverage**: Read each sub-issue description and verify the PR includes implementation for ALL sub-issues.
|
|
283
|
+
2. **Integration Validation**: Check that shared types, API contracts, and data flow between sub-issue implementations are consistent and correct.
|
|
284
|
+
3. **Cross-Cutting Concerns**: Verify consistent error handling, auth patterns, naming conventions, and no orphaned/dead code across all sub-issue changes.
|
|
285
|
+
4. **Sub-Issue Status**: All sub-issues must be in Finished, Delivered, or Accepted status.
|
|
286
|
+
|
|
287
|
+
Validate the implementation against the parent issue's acceptance criteria as a whole, not just each sub-issue in isolation.`;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Build default acceptance context for parent issues with sub-issues.
|
|
291
|
+
*/
|
|
292
|
+
export function defaultBuildParentAcceptanceContext(issueIdentifier, subIssueStatuses) {
|
|
293
|
+
const subIssueList = subIssueStatuses
|
|
294
|
+
.map(s => `- ${s.identifier}: ${s.title} (Status: ${s.status})`)
|
|
295
|
+
.join('\n');
|
|
296
|
+
return `Process acceptance for ${issueIdentifier} (parent issue with ${subIssueStatuses.length} sub-issues).
|
|
297
|
+
|
|
298
|
+
## Sub-Issues
|
|
299
|
+
${subIssueList}
|
|
300
|
+
|
|
301
|
+
## Parent Issue Acceptance Requirements
|
|
302
|
+
This is a parent issue with coordinated sub-issues. Before merging:
|
|
303
|
+
|
|
304
|
+
1. **Sub-Issue Status**: ALL sub-issues must be in **Delivered** or **Accepted** status.
|
|
305
|
+
2. **PR Completeness**: The single PR should contain changes for all sub-issues.
|
|
306
|
+
3. **CI/Deployment**: Verify the combined PR passes CI and deploys successfully.
|
|
307
|
+
|
|
308
|
+
Validate development and QA work is complete, verify PR is ready to merge (CI passing, no conflicts), merge the PR.
|
|
309
|
+
After merge succeeds, delete the remote branch.`;
|
|
310
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.test.d.ts","sourceRoot":"","sources":["../../../src/defaults/prompts.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { buildFailureContextBlock, defaultGeneratePrompt } from './prompts.js';
|
|
3
|
+
describe('buildFailureContextBlock', () => {
|
|
4
|
+
const baseContext = {
|
|
5
|
+
cycleCount: 2,
|
|
6
|
+
strategy: 'context-enriched',
|
|
7
|
+
failureSummary: '--- Cycle 1, qa (2024-01-01) ---\nTests failed: TypeError in UserService',
|
|
8
|
+
};
|
|
9
|
+
describe('refinement work type', () => {
|
|
10
|
+
it('returns empty string for cycleCount 0', () => {
|
|
11
|
+
expect(buildFailureContextBlock('refinement', { ...baseContext, cycleCount: 0 })).toBe('');
|
|
12
|
+
});
|
|
13
|
+
it('includes failure history for cycle 1+', () => {
|
|
14
|
+
const result = buildFailureContextBlock('refinement', baseContext);
|
|
15
|
+
expect(result).toContain('Previous Failure Context');
|
|
16
|
+
expect(result).toContain('2 development-QA cycle(s)');
|
|
17
|
+
expect(result).toContain('TypeError in UserService');
|
|
18
|
+
expect(result).toContain('Do NOT repeat approaches that already failed');
|
|
19
|
+
});
|
|
20
|
+
it('includes decomposition instructions for decompose strategy', () => {
|
|
21
|
+
const decomposeCtx = {
|
|
22
|
+
...baseContext,
|
|
23
|
+
cycleCount: 3,
|
|
24
|
+
strategy: 'decompose',
|
|
25
|
+
};
|
|
26
|
+
const result = buildFailureContextBlock('refinement', decomposeCtx);
|
|
27
|
+
expect(result).toContain('Decomposition Required');
|
|
28
|
+
expect(result).toContain('DECOMPOSE this issue');
|
|
29
|
+
expect(result).toContain('smaller sub-issues');
|
|
30
|
+
expect(result).not.toContain('Previous Failure Context');
|
|
31
|
+
});
|
|
32
|
+
it('handles null failure summary gracefully', () => {
|
|
33
|
+
const result = buildFailureContextBlock('refinement', { ...baseContext, failureSummary: null });
|
|
34
|
+
expect(result).toContain('No details recorded');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe('development work type', () => {
|
|
38
|
+
it('returns empty string for cycleCount 0', () => {
|
|
39
|
+
expect(buildFailureContextBlock('development', { ...baseContext, cycleCount: 0 })).toBe('');
|
|
40
|
+
});
|
|
41
|
+
it('includes retry context for cycle 1+', () => {
|
|
42
|
+
const result = buildFailureContextBlock('development', baseContext);
|
|
43
|
+
expect(result).toContain('Retry Context');
|
|
44
|
+
expect(result).toContain('retry #2');
|
|
45
|
+
expect(result).toContain('TypeError in UserService');
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
describe('coordination work type', () => {
|
|
49
|
+
it('includes retry context same as development', () => {
|
|
50
|
+
const result = buildFailureContextBlock('coordination', baseContext);
|
|
51
|
+
expect(result).toContain('Retry Context');
|
|
52
|
+
expect(result).toContain('retry #2');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe('qa-coordination work type', () => {
|
|
56
|
+
it('returns empty string when no failure summary', () => {
|
|
57
|
+
expect(buildFailureContextBlock('qa-coordination', { ...baseContext, failureSummary: null })).toBe('');
|
|
58
|
+
});
|
|
59
|
+
it('includes previous QA results when failure summary exists', () => {
|
|
60
|
+
const result = buildFailureContextBlock('qa-coordination', baseContext);
|
|
61
|
+
expect(result).toContain('Previous QA Results');
|
|
62
|
+
expect(result).toContain('TypeError in UserService');
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
describe('qa work type', () => {
|
|
66
|
+
it('returns empty string when no failure summary', () => {
|
|
67
|
+
expect(buildFailureContextBlock('qa', { ...baseContext, failureSummary: null })).toBe('');
|
|
68
|
+
});
|
|
69
|
+
it('includes previous QA results when failure summary exists', () => {
|
|
70
|
+
const qaCtx = {
|
|
71
|
+
...baseContext,
|
|
72
|
+
qaAttemptCount: 2,
|
|
73
|
+
};
|
|
74
|
+
const result = buildFailureContextBlock('qa', qaCtx);
|
|
75
|
+
expect(result).toContain('Previous QA Results');
|
|
76
|
+
expect(result).toContain('QA\'d 2 times previously');
|
|
77
|
+
expect(result).toContain('TypeError in UserService');
|
|
78
|
+
});
|
|
79
|
+
it('falls back to cycleCount when qaAttemptCount not provided', () => {
|
|
80
|
+
const result = buildFailureContextBlock('qa', baseContext);
|
|
81
|
+
expect(result).toContain('QA\'d 2 times previously');
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
describe('other work types', () => {
|
|
85
|
+
it('returns empty string for acceptance', () => {
|
|
86
|
+
expect(buildFailureContextBlock('acceptance', baseContext)).toBe('');
|
|
87
|
+
});
|
|
88
|
+
it('returns empty string for research', () => {
|
|
89
|
+
expect(buildFailureContextBlock('research', baseContext)).toBe('');
|
|
90
|
+
});
|
|
91
|
+
it('returns empty string for backlog-creation', () => {
|
|
92
|
+
expect(buildFailureContextBlock('backlog-creation', baseContext)).toBe('');
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
describe('defaultGeneratePrompt with workflowContext', () => {
|
|
97
|
+
it('does not modify prompt when workflowContext is undefined', () => {
|
|
98
|
+
const withoutCtx = defaultGeneratePrompt('PROJ-123', 'development');
|
|
99
|
+
const withUndefined = defaultGeneratePrompt('PROJ-123', 'development', undefined, undefined);
|
|
100
|
+
expect(withoutCtx).toBe(withUndefined);
|
|
101
|
+
});
|
|
102
|
+
it('does not modify prompt when cycleCount is 0', () => {
|
|
103
|
+
const withoutCtx = defaultGeneratePrompt('PROJ-123', 'development');
|
|
104
|
+
const withZero = defaultGeneratePrompt('PROJ-123', 'development', undefined, {
|
|
105
|
+
cycleCount: 0,
|
|
106
|
+
strategy: 'normal',
|
|
107
|
+
failureSummary: null,
|
|
108
|
+
});
|
|
109
|
+
expect(withoutCtx).toBe(withZero);
|
|
110
|
+
});
|
|
111
|
+
it('enriches refinement prompt with failure context', () => {
|
|
112
|
+
const result = defaultGeneratePrompt('PROJ-123', 'refinement', undefined, {
|
|
113
|
+
cycleCount: 2,
|
|
114
|
+
strategy: 'context-enriched',
|
|
115
|
+
failureSummary: 'Tests failed in UserService',
|
|
116
|
+
});
|
|
117
|
+
expect(result).toContain('Refine PROJ-123');
|
|
118
|
+
expect(result).toContain('Previous Failure Context');
|
|
119
|
+
expect(result).toContain('Tests failed in UserService');
|
|
120
|
+
});
|
|
121
|
+
it('enriches development prompt with retry context', () => {
|
|
122
|
+
const result = defaultGeneratePrompt('PROJ-123', 'development', undefined, {
|
|
123
|
+
cycleCount: 1,
|
|
124
|
+
strategy: 'normal',
|
|
125
|
+
failureSummary: 'Build error in core package',
|
|
126
|
+
});
|
|
127
|
+
expect(result).toContain('Start work on PROJ-123');
|
|
128
|
+
expect(result).toContain('Retry Context');
|
|
129
|
+
expect(result).toContain('Build error in core package');
|
|
130
|
+
});
|
|
131
|
+
it('preserves mentionContext alongside workflowContext', () => {
|
|
132
|
+
const result = defaultGeneratePrompt('PROJ-123', 'development', 'Please focus on the API layer', {
|
|
133
|
+
cycleCount: 1,
|
|
134
|
+
strategy: 'normal',
|
|
135
|
+
failureSummary: 'API tests failing',
|
|
136
|
+
});
|
|
137
|
+
expect(result).toContain('Retry Context');
|
|
138
|
+
expect(result).toContain('Please focus on the API layer');
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe('defaultGeneratePrompt read-only constraint', () => {
|
|
142
|
+
const readOnlyWorkTypes = ['qa', 'acceptance', 'qa-coordination', 'acceptance-coordination'];
|
|
143
|
+
for (const workType of readOnlyWorkTypes) {
|
|
144
|
+
it(`includes READ-ONLY constraint for ${workType}`, () => {
|
|
145
|
+
const result = defaultGeneratePrompt('PROJ-123', workType);
|
|
146
|
+
expect(result).toContain('READ-ONLY ROLE');
|
|
147
|
+
expect(result).toContain('MUST NOT modify any source code');
|
|
148
|
+
expect(result).toContain('WORK_RESULT:failed');
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
const writableWorkTypes = ['development', 'coordination', 'refinement', 'research', 'backlog-creation', 'inflight'];
|
|
152
|
+
for (const workType of writableWorkTypes) {
|
|
153
|
+
it(`does NOT include READ-ONLY constraint for ${workType}`, () => {
|
|
154
|
+
const result = defaultGeneratePrompt('PROJ-123', workType);
|
|
155
|
+
expect(result).not.toContain('READ-ONLY ROLE');
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
describe('defaultGeneratePrompt coordination prompts have steps', () => {
|
|
160
|
+
it('qa-coordination includes numbered steps and pass/fail criteria', () => {
|
|
161
|
+
const result = defaultGeneratePrompt('PROJ-100', 'qa-coordination');
|
|
162
|
+
expect(result).toContain('QA Coordination Steps:');
|
|
163
|
+
expect(result).toContain('1. Find and validate the correct PR');
|
|
164
|
+
expect(result).toContain('Pass/Fail:');
|
|
165
|
+
expect(result).toContain('WORK_RESULT:passed');
|
|
166
|
+
expect(result).toContain('WORK_RESULT:failed');
|
|
167
|
+
expect(result).toContain('PR Selection');
|
|
168
|
+
});
|
|
169
|
+
it('acceptance-coordination includes numbered steps and pass/fail criteria', () => {
|
|
170
|
+
const result = defaultGeneratePrompt('PROJ-100', 'acceptance-coordination');
|
|
171
|
+
expect(result).toContain('Acceptance Coordination Steps:');
|
|
172
|
+
expect(result).toContain('1. Find and validate the correct PR');
|
|
173
|
+
expect(result).toContain('Merge the PR');
|
|
174
|
+
expect(result).toContain('Pass/Fail:');
|
|
175
|
+
expect(result).toContain('WORK_RESULT:passed');
|
|
176
|
+
expect(result).toContain('WORK_RESULT:failed');
|
|
177
|
+
expect(result).toContain('do NOT attempt to fix it');
|
|
178
|
+
expect(result).toContain('PR Selection');
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
describe('defaultGeneratePrompt coordination retry', () => {
|
|
182
|
+
it('uses fresh coordination prompt when no workflowContext', () => {
|
|
183
|
+
const result = defaultGeneratePrompt('PROJ-100', 'coordination');
|
|
184
|
+
expect(result).toContain('Coordinate sub-issue execution for parent issue PROJ-100');
|
|
185
|
+
expect(result).toContain('Fetch sub-issues with dependency graph');
|
|
186
|
+
expect(result).not.toContain('REWORK MODE');
|
|
187
|
+
});
|
|
188
|
+
it('uses fresh coordination prompt when cycleCount is 0', () => {
|
|
189
|
+
const result = defaultGeneratePrompt('PROJ-100', 'coordination', undefined, {
|
|
190
|
+
cycleCount: 0,
|
|
191
|
+
strategy: 'normal',
|
|
192
|
+
failureSummary: null,
|
|
193
|
+
});
|
|
194
|
+
expect(result).toContain('Coordinate sub-issue execution for parent issue PROJ-100');
|
|
195
|
+
expect(result).not.toContain('REWORK MODE');
|
|
196
|
+
});
|
|
197
|
+
it('switches to rework mode when cycleCount > 0', () => {
|
|
198
|
+
const result = defaultGeneratePrompt('PROJ-100', 'coordination', undefined, {
|
|
199
|
+
cycleCount: 1,
|
|
200
|
+
strategy: 'context-enriched',
|
|
201
|
+
failureSummary: '2 migrations missing .json snapshots',
|
|
202
|
+
});
|
|
203
|
+
expect(result).toContain('REWORK MODE');
|
|
204
|
+
expect(result).toContain('Fix issues found during QA for parent issue PROJ-100');
|
|
205
|
+
expect(result).toContain('DO NOT re-coordinate sub-issues from scratch');
|
|
206
|
+
expect(result).toContain('pnpm af-linear list-comments PROJ-100');
|
|
207
|
+
expect(result).not.toContain('Fetch sub-issues with dependency graph');
|
|
208
|
+
});
|
|
209
|
+
it('includes common rework fixes in rework mode', () => {
|
|
210
|
+
const result = defaultGeneratePrompt('PROJ-100', 'coordination', undefined, {
|
|
211
|
+
cycleCount: 2,
|
|
212
|
+
strategy: 'context-enriched',
|
|
213
|
+
failureSummary: 'Build failed',
|
|
214
|
+
});
|
|
215
|
+
expect(result).toContain('Missing migration .json snapshots');
|
|
216
|
+
expect(result).toContain('TypeScript errors');
|
|
217
|
+
expect(result).toContain('Missing API fields');
|
|
218
|
+
expect(result).toContain('Build failures');
|
|
219
|
+
});
|
|
220
|
+
it('appends failure context block in rework mode', () => {
|
|
221
|
+
const result = defaultGeneratePrompt('PROJ-100', 'coordination', undefined, {
|
|
222
|
+
cycleCount: 2,
|
|
223
|
+
strategy: 'context-enriched',
|
|
224
|
+
failureSummary: 'Tests failed: missing snapshot for 20260308_migration.ts',
|
|
225
|
+
});
|
|
226
|
+
expect(result).toContain('REWORK MODE');
|
|
227
|
+
expect(result).toContain('Retry Context');
|
|
228
|
+
expect(result).toContain('retry #2');
|
|
229
|
+
expect(result).toContain('missing snapshot for 20260308_migration.ts');
|
|
230
|
+
});
|
|
231
|
+
it('includes mention context alongside rework mode', () => {
|
|
232
|
+
const result = defaultGeneratePrompt('PROJ-100', 'coordination', 'Focus on the migration snapshots', {
|
|
233
|
+
cycleCount: 1,
|
|
234
|
+
strategy: 'normal',
|
|
235
|
+
failureSummary: 'Missing .json snapshots',
|
|
236
|
+
});
|
|
237
|
+
expect(result).toContain('REWORK MODE');
|
|
238
|
+
expect(result).toContain('Focus on the migration snapshots');
|
|
239
|
+
});
|
|
240
|
+
it('instructs agent to use existing PR branch', () => {
|
|
241
|
+
const result = defaultGeneratePrompt('PROJ-100', 'coordination', undefined, {
|
|
242
|
+
cycleCount: 1,
|
|
243
|
+
strategy: 'normal',
|
|
244
|
+
failureSummary: null,
|
|
245
|
+
});
|
|
246
|
+
expect(result).toContain('Do not create a new branch or PR');
|
|
247
|
+
expect(result).toContain('push to the existing PR branch');
|
|
248
|
+
});
|
|
249
|
+
it('includes sub-issue status management in fresh coordination', () => {
|
|
250
|
+
const result = defaultGeneratePrompt('PROJ-100', 'coordination');
|
|
251
|
+
expect(result).toContain('SUB-ISSUE STATUS MANAGEMENT');
|
|
252
|
+
expect(result).toContain('COMPLETION VERIFICATION');
|
|
253
|
+
});
|
|
254
|
+
it('does not include sub-issue status management in rework mode', () => {
|
|
255
|
+
const result = defaultGeneratePrompt('PROJ-100', 'coordination', undefined, {
|
|
256
|
+
cycleCount: 1,
|
|
257
|
+
strategy: 'normal',
|
|
258
|
+
failureSummary: 'QA failed',
|
|
259
|
+
});
|
|
260
|
+
expect(result).not.toContain('SUB-ISSUE STATUS MANAGEMENT');
|
|
261
|
+
expect(result).not.toContain('COMPLETION VERIFICATION');
|
|
262
|
+
});
|
|
263
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default work type detection from prompt keywords.
|
|
3
|
+
*
|
|
4
|
+
* Scans prompt text for keywords that map to specific work types,
|
|
5
|
+
* constrained to the set of valid work types for the current issue status.
|
|
6
|
+
*/
|
|
7
|
+
import type { AgentWorkType } from '../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Detect work type from prompt text, constrained to valid options.
|
|
10
|
+
*
|
|
11
|
+
* Scans the prompt for keywords and returns the first matching work type
|
|
12
|
+
* that is also in the set of valid work types for the current issue status.
|
|
13
|
+
*
|
|
14
|
+
* @param prompt - The prompt text to scan
|
|
15
|
+
* @param validWorkTypes - Work types valid for the current issue status
|
|
16
|
+
* @returns The detected work type, or undefined if no match
|
|
17
|
+
*/
|
|
18
|
+
export declare function defaultDetectWorkTypeFromPrompt(prompt: string, validWorkTypes: AgentWorkType[]): AgentWorkType | undefined;
|
|
19
|
+
//# sourceMappingURL=work-type-detection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-type-detection.d.ts","sourceRoot":"","sources":["../../../src/defaults/work-type-detection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAmEhD;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,aAAa,EAAE,GAC9B,aAAa,GAAG,SAAS,CAe3B"}
|