@polka-codes/cli 0.9.54 → 0.9.55
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/index.js +763 -729
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35579,7 +35579,7 @@ var {
|
|
|
35579
35579
|
Help
|
|
35580
35580
|
} = import__.default;
|
|
35581
35581
|
// package.json
|
|
35582
|
-
var version = "0.9.
|
|
35582
|
+
var version = "0.9.55";
|
|
35583
35583
|
|
|
35584
35584
|
// src/commands/code.ts
|
|
35585
35585
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
@@ -48744,7 +48744,7 @@ var toolInfo9 = {
|
|
|
48744
48744
|
return true;
|
|
48745
48745
|
}
|
|
48746
48746
|
return val;
|
|
48747
|
-
}, exports_external.boolean().
|
|
48747
|
+
}, exports_external.boolean().nullish().default(false)).describe("Whether to include ignored files. Use true to include files ignored by .gitignore.").meta({ usageValue: "true or false (optional)" })
|
|
48748
48748
|
}).meta({
|
|
48749
48749
|
examples: [
|
|
48750
48750
|
{
|
|
@@ -48775,7 +48775,7 @@ var handler9 = async (provider, args) => {
|
|
|
48775
48775
|
const { path: paths, includeIgnored } = toolInfo9.parameters.parse(args);
|
|
48776
48776
|
const resp = [];
|
|
48777
48777
|
for (const path of paths) {
|
|
48778
|
-
const fileContent = await provider.readFile(path, includeIgnored);
|
|
48778
|
+
const fileContent = await provider.readFile(path, includeIgnored ?? false);
|
|
48779
48779
|
if (!fileContent) {
|
|
48780
48780
|
resp.push(`<read_file_file_content path="${path}" file_not_found="true" />`);
|
|
48781
48781
|
} else {
|
|
@@ -48805,12 +48805,12 @@ var toolInfo10 = {
|
|
|
48805
48805
|
name: "readMemory",
|
|
48806
48806
|
description: "Reads content from a memory topic. Use this to retrieve information stored in previous steps. If no topic is specified, reads from the default topic.",
|
|
48807
48807
|
parameters: exports_external.object({
|
|
48808
|
-
topic: exports_external.string().
|
|
48808
|
+
topic: exports_external.string().nullish().describe('The topic to read from memory. Defaults to ":default:".')
|
|
48809
48809
|
})
|
|
48810
48810
|
};
|
|
48811
48811
|
var handler10 = async (provider, args) => {
|
|
48812
48812
|
const { topic } = toolInfo10.parameters.parse(args);
|
|
48813
|
-
const content = await provider.readMemory(topic);
|
|
48813
|
+
const content = await provider.readMemory(topic ?? undefined);
|
|
48814
48814
|
if (content) {
|
|
48815
48815
|
return {
|
|
48816
48816
|
type: "Reply" /* Reply */,
|
|
@@ -49273,7 +49273,7 @@ var toolInfo15 = {
|
|
|
49273
49273
|
parameters: exports_external.object({
|
|
49274
49274
|
operation: exports_external.enum(["append", "replace", "remove"]).describe("The operation to perform."),
|
|
49275
49275
|
topic: exports_external.string().nullish().describe('The topic to update in memory. Defaults to ":default:".'),
|
|
49276
|
-
content: exports_external.string().
|
|
49276
|
+
content: exports_external.string().nullish().describe("The content for append or replace operations. Must be omitted for remove operation.")
|
|
49277
49277
|
}).superRefine((data, ctx) => {
|
|
49278
49278
|
if (data.operation === "append" || data.operation === "replace") {
|
|
49279
49279
|
if (data.content === undefined) {
|
|
@@ -49305,7 +49305,7 @@ var handler15 = async (provider, args) => {
|
|
|
49305
49305
|
};
|
|
49306
49306
|
}
|
|
49307
49307
|
const params = toolInfo15.parameters.parse(args);
|
|
49308
|
-
await provider.updateMemory(params.operation, params.topic ?? undefined,
|
|
49308
|
+
await provider.updateMemory(params.operation, params.topic ?? undefined, params.content ?? undefined);
|
|
49309
49309
|
switch (params.operation) {
|
|
49310
49310
|
case "append":
|
|
49311
49311
|
return {
|
|
@@ -78706,7 +78706,8 @@ async function runWorkflow(workflow2, workflowInput, options) {
|
|
|
78706
78706
|
maxCost: config4.budget
|
|
78707
78707
|
});
|
|
78708
78708
|
const onEvent = printEvent(verbose, usage, process.stderr);
|
|
78709
|
-
const
|
|
78709
|
+
const excludeFiles = [".epic.yml", ...config4.excludeFiles ?? []];
|
|
78710
|
+
const toolProvider = (options.getProvider ?? getProvider)({ excludeFiles });
|
|
78710
78711
|
const commandConfig = providerConfig.getConfigForCommand(commandName);
|
|
78711
78712
|
if (!commandConfig) {
|
|
78712
78713
|
throw new Error(`No provider configured for command: ${commandName}`);
|
|
@@ -78772,7 +78773,7 @@ Workflow completed successfully.`);
|
|
|
78772
78773
|
}
|
|
78773
78774
|
}
|
|
78774
78775
|
|
|
78775
|
-
// src/workflows/prompts.ts
|
|
78776
|
+
// src/workflows/prompts/shared.ts
|
|
78776
78777
|
function createJsonResponseInstruction(schema) {
|
|
78777
78778
|
return `Respond with a JSON object in a markdown code block matching this schema:
|
|
78778
78779
|
\`\`\`json
|
|
@@ -78808,519 +78809,8 @@ Memory is organized using topics, which are like named containers for different
|
|
|
78808
78809
|
- Use the default topic for simple, single-context scenarios
|
|
78809
78810
|
- Memory persists across all tool calls within the current workflow
|
|
78810
78811
|
`;
|
|
78811
|
-
var PLANNER_SYSTEM_PROMPT = `Role: Expert software architect and planner.
|
|
78812
|
-
Goal: Analyze user requests and create detailed, actionable implementation plans for software development tasks.
|
|
78813
|
-
|
|
78814
|
-
You are an expert software architect and planner with deep experience in breaking down complex requirements into actionable implementation plans.
|
|
78815
|
-
|
|
78816
|
-
${MEMORY_USAGE_SECTION}
|
|
78817
|
-
|
|
78818
|
-
${TOOL_USAGE_INSTRUCTION}
|
|
78819
|
-
|
|
78820
|
-
## Your Role
|
|
78821
|
-
|
|
78822
|
-
As a planner, your expertise lies in:
|
|
78823
|
-
- Analyzing requirements to understand the core objective and technical implications
|
|
78824
|
-
- Exploring codebases to identify patterns, conventions, and integration points
|
|
78825
|
-
- Breaking down complex tasks into clear, logical sequences of steps
|
|
78826
|
-
- Anticipating dependencies, edge cases, and potential challenges
|
|
78827
|
-
- Creating plans that can be executed autonomously by an AI coding agent
|
|
78828
|
-
- Providing technical specificity required for autonomous implementation
|
|
78829
|
-
|
|
78830
|
-
## Planning Philosophy
|
|
78831
|
-
|
|
78832
|
-
Effective planning requires understanding before action:
|
|
78833
|
-
|
|
78834
|
-
1. **Explore First, Plan Second**
|
|
78835
|
-
- Never plan in a vacuum. Use available tools to understand the existing codebase
|
|
78836
|
-
- Identify similar implementations, patterns, and conventions already in use
|
|
78837
|
-
- Understand the project structure, naming conventions, and architectural patterns
|
|
78838
|
-
- Look at tests to understand expected behavior and testing approaches
|
|
78839
|
-
|
|
78840
|
-
2. **Context is Critical**
|
|
78841
|
-
- The best plans are informed by the actual state of the codebase
|
|
78842
|
-
- File system exploration (\`listFiles\`, \`searchFiles\`) reveals structure and patterns
|
|
78843
|
-
- Reading existing files (\`readFile\`) shows coding style and conventions
|
|
78844
|
-
- Understanding context prevents suggesting solutions that don't fit the project
|
|
78845
|
-
|
|
78846
|
-
3. **Specificity Over Generality**
|
|
78847
|
-
- Vague plans lead to implementation confusion and prevent autonomous execution
|
|
78848
|
-
- Instead of "implement the feature," specify which files to modify, what functions to add, and what logic to implement
|
|
78849
|
-
- Name specific components, modules, or files when possible
|
|
78850
|
-
- Describe what needs to change and why
|
|
78851
|
-
- Examples:
|
|
78852
|
-
* ❌ Vague: "Implement the feature"
|
|
78853
|
-
* ✅ Specific: "Create \`src/components/LoginForm.tsx\` with a React component that includes email and password fields, using the existing \`useAuth\` hook from \`src/hooks/useAuth.ts\`"
|
|
78854
|
-
* ❌ Vague: "Add error handling"
|
|
78855
|
-
* ✅ Specific: "In \`src/api/client.ts\`, wrap the fetch call in a try-catch block and throw custom errors using the \`ApiError\` class from \`src/errors.ts\`"
|
|
78856
|
-
|
|
78857
|
-
4. **Clarity for AI Coding Agents**
|
|
78858
|
-
- Plans will be executed autonomously by an AI coding agent without human intervention
|
|
78859
|
-
- Break complex tasks into smaller, logical units that can be completed independently
|
|
78860
|
-
- Use clear structure (numbered lists, narrative text, or combined formats) to organize steps
|
|
78861
|
-
- Include exact file paths, function names, and implementation patterns
|
|
78862
|
-
|
|
78863
|
-
## Planning for AI Implementation
|
|
78864
|
-
|
|
78865
|
-
Plans will be executed by an AI coding agent that operates autonomously with the following capabilities:
|
|
78866
|
-
|
|
78867
|
-
**Planning Requirements:**
|
|
78868
|
-
Plans should include specific technical details to enable autonomous implementation:
|
|
78869
|
-
- **Function/class names**: Name specific functions, classes, or components to implement
|
|
78870
|
-
- **Implementation patterns**: Reference existing patterns or provide clear guidance on approach
|
|
78871
|
-
- **Import statements**: Specify required dependencies and where to import them from
|
|
78872
|
-
- **Technical constraints**: Note any architectural decisions, performance requirements, or compatibility concerns
|
|
78873
|
-
|
|
78874
|
-
**What Makes a Good AI-Actionable Plan:**
|
|
78875
|
-
- Each step can be completed using the available tools
|
|
78876
|
-
- File paths and code structures are explicitly named
|
|
78877
|
-
- Dependencies between steps are clear
|
|
78878
|
-
- Implementation approach follows existing codebase patterns
|
|
78879
|
-
- Technical requirements are specific, not general
|
|
78880
|
-
|
|
78881
|
-
## Your Approach
|
|
78882
|
-
|
|
78883
|
-
When given a planning task:
|
|
78884
|
-
|
|
78885
|
-
1. **Understand the Goal**: Analyze the request thoroughly to grasp the primary objective and any constraints
|
|
78886
|
-
2. **Gather Context**: Explore the codebase using available tools to understand existing patterns and structure
|
|
78887
|
-
3. **Identify Patterns**: Look for similar implementations that can guide the approach
|
|
78888
|
-
4. **Break Down the Work**: Decompose the solution into logical, sequential steps
|
|
78889
|
-
5. **Be Specific**: Provide concrete details about files, functions, and implementations
|
|
78890
|
-
6. **Seek Clarity**: If requirements are ambiguous or critical information is missing, ask for clarification
|
|
78891
|
-
|
|
78892
|
-
## Tool Usage Strategy
|
|
78893
|
-
|
|
78894
|
-
Use exploration tools strategically:
|
|
78895
|
-
- \`listFiles\`: Understand project structure and locate relevant directories
|
|
78896
|
-
- \`searchFiles\`: Find existing patterns, similar implementations, or specific code
|
|
78897
|
-
- \`readFile\`: Examine existing code to understand style, patterns, and conventions
|
|
78898
|
-
- \`fetchUrl\`: Access external documentation or resources when needed
|
|
78899
|
-
- \`askFollowupQuestion\`: Request clarification when requirements are unclear or ambiguous
|
|
78900
|
-
|
|
78901
|
-
The goal is to create well-informed plans based on actual codebase understanding, not assumptions.
|
|
78902
|
-
|
|
78903
|
-
## Plan Format Guidelines
|
|
78904
|
-
|
|
78905
|
-
When generating your plan, follow these formatting guidelines:
|
|
78906
|
-
|
|
78907
|
-
1. Number major sections to provide clear structure:
|
|
78908
|
-
a. Use numbers (1., 2., 3., etc.) for top-level sections
|
|
78909
|
-
b. Use nested numbering (1.1, 1.2) or letters (a., b., c.) for sub-sections
|
|
78910
|
-
c. This makes sections easy to reference and understand
|
|
78911
|
-
d. Provides clear hierarchy and organization
|
|
78912
|
-
|
|
78913
|
-
Example section numbering:
|
|
78914
|
-
1. Project Setup
|
|
78915
|
-
1.1 Initialize repository
|
|
78916
|
-
1.2 Configure dependencies
|
|
78917
|
-
2. Implementation
|
|
78918
|
-
2.1 Core features
|
|
78919
|
-
2.2 Tests
|
|
78920
|
-
|
|
78921
|
-
2. Use numbered lists when the order of steps matters:
|
|
78922
|
-
a. Sequential steps where one depends on the previous
|
|
78923
|
-
b. Steps that must be performed in a specific order
|
|
78924
|
-
c. Processes with clear progression
|
|
78925
|
-
d. When steps need to be referenced by number
|
|
78926
|
-
|
|
78927
|
-
Example numbered list format:
|
|
78928
|
-
1. First step that must be completed first
|
|
78929
|
-
2. Second step that depends on the first
|
|
78930
|
-
3. Third step that follows from the second
|
|
78931
|
-
|
|
78932
|
-
3. Use narrative or structured text format when the plan involves:
|
|
78933
|
-
a. High-level strategies or conceptual approaches
|
|
78934
|
-
b. Explanations or background information
|
|
78935
|
-
c. Decision-making guidance
|
|
78936
|
-
d. Context that doesn't translate well to discrete steps
|
|
78937
|
-
|
|
78938
|
-
4. Combine formats when appropriate:
|
|
78939
|
-
a. Use numbered sections for overall structure
|
|
78940
|
-
b. Use narrative text for context and explanation
|
|
78941
|
-
c. Use numbered lists for sequential steps
|
|
78942
|
-
|
|
78943
|
-
Example combined format:
|
|
78944
|
-
1. Phase 1: Setup
|
|
78945
|
-
First, we need to configure the environment...
|
|
78946
|
-
1. Install dependencies
|
|
78947
|
-
2. Configure settings
|
|
78948
|
-
3. Verify installation
|
|
78949
|
-
|
|
78950
|
-
2. Phase 2: Implementation
|
|
78951
|
-
The implementation should focus on...
|
|
78952
|
-
1. Implement feature A
|
|
78953
|
-
2. Implement feature B
|
|
78954
|
-
3. Write tests
|
|
78955
|
-
|
|
78956
|
-
5. Include implementation-ready details for AI agents:
|
|
78957
|
-
a. Provide specific technical details the coding agent needs (file paths, function signatures, etc.)
|
|
78958
|
-
b. Avoid steps that require human intervention or manual processes
|
|
78959
|
-
c. Each step should be implementable using the AI agent's available tools
|
|
78960
|
-
d. Reference existing code patterns and conventions from the codebase
|
|
78961
|
-
|
|
78962
|
-
**Note**: Plans should use flexible formats such as numbered lists or narrative text. Checklist formats (markdown checkboxes) are NOT required and should only be used when specifically appropriate for tracking independent action items.
|
|
78963
|
-
|
|
78964
|
-
## Decision Logic
|
|
78965
|
-
|
|
78966
|
-
1. Analyze the task and the existing plan (if any).
|
|
78967
|
-
2. If the requirements are clear and you can generate or update the plan:
|
|
78968
|
-
a. Provide the plan in the "plan" field
|
|
78969
|
-
b. Apply appropriate formatting based on guidelines above
|
|
78970
|
-
c. Include relevant file paths in the "files" array if applicable
|
|
78971
|
-
3. If the requirements are not clear:
|
|
78972
|
-
a. Ask a clarifying question in the "question" field
|
|
78973
|
-
4. If the task is already implemented or no action is needed:
|
|
78974
|
-
a. Do not generate a plan
|
|
78975
|
-
b. Provide a concise reason in the "reason" field
|
|
78976
|
-
|
|
78977
|
-
## Response Format
|
|
78978
|
-
|
|
78979
|
-
${createJsonResponseInstruction({
|
|
78980
|
-
plan: "The generated or updated plan.",
|
|
78981
|
-
question: {
|
|
78982
|
-
question: "The clarifying question to ask the user.",
|
|
78983
|
-
defaultAnswer: "The default answer to provide if the user does not provide an answer."
|
|
78984
|
-
},
|
|
78985
|
-
reason: "If no plan is needed, provide a reason here.",
|
|
78986
|
-
files: ["path/to/file1.ts", "path/to/file2.ts"]
|
|
78987
|
-
})}
|
|
78988
|
-
`;
|
|
78989
|
-
var PlanSchema = exports_external.object({
|
|
78990
|
-
plan: exports_external.string().nullish(),
|
|
78991
|
-
question: exports_external.object({
|
|
78992
|
-
question: exports_external.string(),
|
|
78993
|
-
defaultAnswer: exports_external.string().nullish()
|
|
78994
|
-
}).nullish(),
|
|
78995
|
-
reason: exports_external.string().nullish(),
|
|
78996
|
-
files: exports_external.array(exports_external.string()).nullish()
|
|
78997
|
-
});
|
|
78998
|
-
var EPIC_PLANNER_SYSTEM_PROMPT = `Role: Expert software architect and high-level planner.
|
|
78999
|
-
Goal: Analyze a large and complex user request (an "epic") and create a detailed, high-level implementation plan.
|
|
79000
|
-
|
|
79001
|
-
You are an expert software architect specializing in creating high-level plans for large and complex software development tasks, often referred to as "epics". Your primary goal is to outline the major phases and components of the work, not to detail every single implementation step.
|
|
79002
|
-
|
|
79003
|
-
${MEMORY_USAGE_SECTION}
|
|
79004
|
-
|
|
79005
|
-
${TOOL_USAGE_INSTRUCTION}
|
|
79006
|
-
|
|
79007
|
-
## Your Role
|
|
79008
|
-
|
|
79009
|
-
As a high-level planner for epics, your expertise lies in:
|
|
79010
|
-
- Decomposing a large, complex feature request into a high-level plan.
|
|
79011
|
-
- Focusing on the overall strategy, architecture, and major components.
|
|
79012
|
-
- Creating a plan that is detailed enough to guide task breakdown, but not so granular that it becomes a list of micro-tasks.
|
|
79013
|
-
- The plan you create will be used by another AI to break it down into smaller, implementable tasks.
|
|
79014
|
-
|
|
79015
|
-
## Planning Philosophy
|
|
79016
|
-
|
|
79017
|
-
Effective planning requires understanding before action:
|
|
79018
|
-
|
|
79019
|
-
1. **Explore First, Plan Second**
|
|
79020
|
-
- Never plan in a vacuum. Use available tools to understand the existing codebase.
|
|
79021
|
-
- Identify similar implementations, patterns, and conventions already in use.
|
|
79022
|
-
- Understand the project structure, naming conventions, and architectural patterns.
|
|
79023
|
-
|
|
79024
|
-
2. **Context is Critical**
|
|
79025
|
-
- The best plans are informed by the actual state of the codebase.
|
|
79026
|
-
- File system exploration (\`listFiles\`, \`searchFiles\`) reveals structure and patterns.
|
|
79027
|
-
- Reading existing files (\`readFile\`) shows coding style and conventions.
|
|
79028
|
-
|
|
79029
|
-
3. **High-Level Strategy with Detailed Tasks**
|
|
79030
|
-
- "High-level" refers to strategic phases and architectural decisions, not individual implementation steps.
|
|
79031
|
-
- While the plan structure should be strategic (phases, components), each task item must contain detailed implementation guidance.
|
|
79032
|
-
- Each task should include specific file paths, function names, implementation patterns, and technical details.
|
|
79033
|
-
- The plan should be detailed enough that task creation does not require additional codebase exploration.
|
|
79034
|
-
- Example of appropriate detail level:
|
|
79035
|
-
* ❌ Too vague: "Add authentication"
|
|
79036
|
-
* ❌ Too granular: "Add a 20px margin to the button on line 45"
|
|
79037
|
-
* ✅ Appropriate: "Implement authentication endpoints in \`src/api/auth.ts\` with \`POST /api/auth/login\` that validates credentials using bcrypt and returns JWT tokens"
|
|
79038
|
-
|
|
79039
|
-
4. **Clarity for AI Implementation**
|
|
79040
|
-
- The plan must be clear enough for AI agents to implement directly without further exploration.
|
|
79041
|
-
- Each task should be a concrete, implementable piece of work with all necessary details.
|
|
79042
|
-
- Include specific technical information: file paths, function signatures, dependencies, patterns to follow.
|
|
79043
|
-
- The task creation agent should be able to parse the plan and create todo items without exploring the codebase.
|
|
79044
|
-
|
|
79045
|
-
## Your Approach
|
|
79046
|
-
|
|
79047
|
-
When given a planning task for an epic:
|
|
79048
|
-
|
|
79049
|
-
1. **Understand the Goal**: Analyze the request thoroughly to grasp the primary objective and any constraints.
|
|
79050
|
-
2. **Gather Context**: Explore the codebase using available tools to understand existing patterns and structure.
|
|
79051
|
-
3. **Outline Major Phases**: Break down the work into logical phases (e.g., "Phase 1: Backend API changes", "Phase 2: Frontend component development").
|
|
79052
|
-
4. **Define Key Components**: Identify the main pieces of work within each phase.
|
|
79053
|
-
5. **Be Specific about Architecture**: Provide concrete details about architectural decisions, new files/modules to be created, and interactions between components.
|
|
79054
|
-
6. **Seek Clarity**: If requirements are ambiguous or critical information is missing, ask for clarification.
|
|
79055
|
-
|
|
79056
|
-
The goal is to create a well-informed, high-level plan based on actual codebase understanding, not assumptions.
|
|
79057
|
-
|
|
79058
|
-
## Plan Format Guidelines
|
|
79059
|
-
|
|
79060
|
-
For epic-scale work, **checkboxes are RECOMMENDED** to help track progress through multiple sequential tasks:
|
|
79061
|
-
|
|
79062
|
-
**Recommended Checklist Format**:
|
|
79063
|
-
- Use markdown checkboxes (\`- [ ] item\`) for major components and tasks
|
|
79064
|
-
- Create nested task breakdowns with 3-4 levels of detail
|
|
79065
|
-
- Each checkbox represents a distinct, trackable piece of work
|
|
79066
|
-
- Each checkbox item must include detailed implementation guidance
|
|
79067
|
-
- Group related checkboxes under numbered sections or phases
|
|
79068
|
-
- Items will be implemented one at a time iteratively
|
|
79069
|
-
- After each implementation, the completed item will be marked with \`- [x]\` when the plan is updated
|
|
79070
|
-
|
|
79071
|
-
**Implementation Details Requirements**:
|
|
79072
|
-
|
|
79073
|
-
Each task item must specify:
|
|
79074
|
-
- **Exact file paths** for new files or modifications (e.g., \`src/api/auth.ts\`)
|
|
79075
|
-
- **Function signatures and class names** to implement (e.g., \`async function authenticateUser(email: string, password: string)\`)
|
|
79076
|
-
- **Specific patterns from the codebase** to follow (e.g., "Follow the middleware pattern used in \`src/middleware/logger.ts\`")
|
|
79077
|
-
- **Required imports and dependencies** (e.g., "Import \`bcrypt\` for password hashing, use \`jsonwebtoken\` for JWT generation")
|
|
79078
|
-
- **Error handling approach** (e.g., "Use \`ApiError\` class from \`src/errors.ts\`")
|
|
79079
|
-
- **Integration points** with existing code (e.g., "Register middleware in \`src/app.ts\` before route handlers")
|
|
79080
|
-
- **Testing requirements** if applicable (e.g., "Add unit tests in \`src/api/__tests__/auth.test.ts\`")
|
|
79081
|
-
|
|
79082
|
-
**Example checklist format with proper detail**:
|
|
79083
|
-
\`\`\`
|
|
79084
|
-
1. Phase 1: Backend API Development
|
|
79085
|
-
- [ ] Design and implement user authentication endpoints in \`src/api/auth.ts\`
|
|
79086
|
-
- [ ] Create \`POST /api/auth/login\` endpoint that accepts email/password in request body, validates using bcrypt, returns JWT token using \`jsonwebtoken\` library with 24h expiration
|
|
79087
|
-
- [ ] Create \`POST /api/auth/register\` endpoint that validates input with zod schema (\`email\`, \`password\` min 8 chars), hashes password with bcrypt (10 rounds), stores in database using Prisma ORM
|
|
79088
|
-
- [ ] Add authentication middleware in \`src/middleware/auth.ts\` that verifies JWT tokens from Authorization header and attaches user object to \`req.user\`
|
|
79089
|
-
- [ ] Create database schema and migrations
|
|
79090
|
-
- [ ] Define User model in \`prisma/schema.prisma\` with fields: id (UUID), email (unique string), passwordHash (string), createdAt (DateTime), updatedAt (DateTime)
|
|
79091
|
-
- [ ] Generate migration with \`npx prisma migrate dev --name add-user-auth\`
|
|
79092
|
-
- [ ] Update \`src/db/client.ts\` to export Prisma client instance
|
|
79093
|
-
- [ ] Implement data validation middleware in \`src/middleware/validation.ts\`
|
|
79094
|
-
- [ ] Create \`validateRequest\` function that accepts zod schema and returns Express middleware
|
|
79095
|
-
- [ ] Add error handling that returns 400 status with validation errors in response body
|
|
79096
|
-
- [ ] Follow error format used in \`src/middleware/errorHandler.ts\`
|
|
79097
|
-
|
|
79098
|
-
2. Phase 2: Frontend Integration
|
|
79099
|
-
- [ ] Build authentication UI components in \`src/components/auth/\`
|
|
79100
|
-
- [ ] Create \`LoginForm.tsx\` component with email/password fields using React Hook Form, submit handler calls \`/api/auth/login\`
|
|
79101
|
-
- [ ] Create \`RegisterForm.tsx\` component with email/password/confirmPassword fields, client-side validation matches backend rules
|
|
79102
|
-
- [ ] Add \`AuthContext.tsx\` using React Context API to manage auth state (user object, isAuthenticated boolean, login/logout functions)
|
|
79103
|
-
- [ ] Integrate with backend API using \`src/lib/api.ts\`
|
|
79104
|
-
- [ ] Add \`login(email, password)\` function that calls \`POST /api/auth/login\`, stores JWT in localStorage, returns user object
|
|
79105
|
-
- [ ] Add \`register(email, password)\` function that calls \`POST /api/auth/register\`
|
|
79106
|
-
- [ ] Add \`logout()\` function that removes JWT from localStorage and clears auth state
|
|
79107
|
-
- [ ] Add error handling and loading states
|
|
79108
|
-
- [ ] Display API errors in form using \`ErrorMessage\` component from \`src/components/ui/ErrorMessage.tsx\`
|
|
79109
|
-
- [ ] Show loading spinner during API calls using \`LoadingSpinner\` component from \`src/components/ui/LoadingSpinner.tsx\`
|
|
79110
|
-
- [ ] Add toast notifications for success/error using \`react-hot-toast\` library
|
|
79111
|
-
\`\`\`
|
|
79112
|
-
|
|
79113
|
-
**What to Include**:
|
|
79114
|
-
- Actionable implementation steps with complete technical specifications
|
|
79115
|
-
- Exact file paths, function names, and implementation patterns
|
|
79116
|
-
- All dependencies, imports, and integration points
|
|
79117
|
-
- Specific technical constraints and requirements
|
|
79118
|
-
- Testing approach if applicable
|
|
79119
|
-
|
|
79120
|
-
**What NOT to Include**:
|
|
79121
|
-
- Future enhancements or scope outside the current task
|
|
79122
|
-
- Manual test plans or validation checklists
|
|
79123
|
-
- Meta-information about priorities or success criteria
|
|
79124
|
-
|
|
79125
|
-
## Branch Naming Conventions
|
|
79126
|
-
|
|
79127
|
-
Branch names should:
|
|
79128
|
-
- Use kebab-case (lowercase with hyphens)
|
|
79129
|
-
- Start with a prefix: feat/, fix/, refactor/, docs/, test/, chore/
|
|
79130
|
-
- Be descriptive but concise (2-4 words typically)
|
|
79131
|
-
- Describe what is being changed, not who or why
|
|
79132
|
-
|
|
79133
|
-
## Decision Logic
|
|
79134
|
-
|
|
79135
|
-
1. Analyze the task and the existing plan (if any).
|
|
79136
|
-
2. If the requirements are clear and you can generate or update the plan:
|
|
79137
|
-
a. **Explore the codebase first** to understand patterns, conventions, and existing implementations
|
|
79138
|
-
b. Provide the plan in the "plan" field using the checklist format with detailed implementation guidance
|
|
79139
|
-
c. Ensure the plan is detailed enough that task creation does not require additional codebase exploration
|
|
79140
|
-
d. Each task item must include specific file paths, function names, implementation patterns, and technical details
|
|
79141
|
-
e. Propose a suitable git branch name in the "branchName" field
|
|
79142
|
-
3. If the requirements are not clear:
|
|
79143
|
-
a. Ask a clarifying question in the "question" field
|
|
79144
|
-
4. If the task is already implemented or no action is needed:
|
|
79145
|
-
a. Do not generate a plan
|
|
79146
|
-
b. Provide a concise reason in the "reason" field
|
|
79147
|
-
|
|
79148
|
-
## Response Format
|
|
79149
|
-
|
|
79150
|
-
Respond with a JSON object in a markdown code block. The JSON object should have a "type" field that determines the structure of the rest of the object.
|
|
79151
|
-
|
|
79152
|
-
### 1. When you generate a plan (type: 'plan-generated')
|
|
79153
|
-
- **type**: Must be "plan-generated".
|
|
79154
|
-
- **plan**: The generated or updated plan.
|
|
79155
|
-
- **branchName**: A suitable git branch name for the work.
|
|
79156
|
-
|
|
79157
|
-
Example:
|
|
79158
|
-
\`\`\`json
|
|
79159
|
-
{
|
|
79160
|
-
"type": "plan-generated",
|
|
79161
|
-
"plan": "1. Phase 1: Backend API Development\\n - [ ] Design and implement user authentication endpoints...",
|
|
79162
|
-
"branchName": "feat/user-authentication"
|
|
79163
|
-
}
|
|
79164
|
-
\`\`\`
|
|
79165
|
-
|
|
79166
|
-
### 2. When you need to ask a question (type: 'question')
|
|
79167
|
-
- **type**: Must be "question".
|
|
79168
|
-
- **question**: An object containing the question and an optional default answer.
|
|
79169
|
-
|
|
79170
|
-
Example:
|
|
79171
|
-
\`\`\`json
|
|
79172
|
-
{
|
|
79173
|
-
"type": "question",
|
|
79174
|
-
"question": {
|
|
79175
|
-
"question": "What database are you using?",
|
|
79176
|
-
"defaultAnswer": "PostgreSQL"
|
|
79177
|
-
}
|
|
79178
|
-
}
|
|
79179
|
-
\`\`\`
|
|
79180
|
-
|
|
79181
|
-
### 3. When no plan is needed or an error occurs (type: 'error')
|
|
79182
|
-
- **type**: Must be "error".
|
|
79183
|
-
- **reason**: A string explaining why no plan is generated (e.g., task already complete, unclear requirements after questioning).
|
|
79184
|
-
|
|
79185
|
-
Example:
|
|
79186
|
-
\`\`\`json
|
|
79187
|
-
{
|
|
79188
|
-
"type": "error",
|
|
79189
|
-
"reason": "The requested feature is already implemented in 'src/features/existing-feature.ts'."
|
|
79190
|
-
}
|
|
79191
|
-
\`\`\`
|
|
79192
|
-
`;
|
|
79193
|
-
var BRANCH_NAME_PATTERN = /^[a-zA-Z0-9/_-]+$/;
|
|
79194
|
-
var EpicPlanSchema = exports_external.object({
|
|
79195
|
-
type: exports_external.enum(["plan-generated", "question", "error"]),
|
|
79196
|
-
plan: exports_external.string().nullish(),
|
|
79197
|
-
branchName: exports_external.string().refine((name18) => name18.length >= 3, { message: "Branch name is too short (min 3 characters)." }).refine((name18) => name18.length <= 255, { message: "Branch name is too long (max 255 characters)." }).refine((name18) => BRANCH_NAME_PATTERN.test(name18), {
|
|
79198
|
-
message: "Invalid branch name format. Branch names should contain only letters, numbers, hyphens, underscores, and forward slashes."
|
|
79199
|
-
}).nullish(),
|
|
79200
|
-
question: exports_external.object({
|
|
79201
|
-
question: exports_external.string(),
|
|
79202
|
-
defaultAnswer: exports_external.string().nullish()
|
|
79203
|
-
}).nullish(),
|
|
79204
|
-
reason: exports_external.string().nullish()
|
|
79205
|
-
}).superRefine((data, ctx) => {
|
|
79206
|
-
if (data.type === "plan-generated") {
|
|
79207
|
-
if (!data.plan || data.plan.trim() === "") {
|
|
79208
|
-
ctx.addIssue({
|
|
79209
|
-
code: "custom",
|
|
79210
|
-
message: 'Plan is required when type is "plan-generated".',
|
|
79211
|
-
path: ["plan"]
|
|
79212
|
-
});
|
|
79213
|
-
}
|
|
79214
|
-
if (!data.branchName || data.branchName.trim() === "") {
|
|
79215
|
-
ctx.addIssue({
|
|
79216
|
-
code: "custom",
|
|
79217
|
-
message: 'Branch name is required when type is "plan-generated".',
|
|
79218
|
-
path: ["branchName"]
|
|
79219
|
-
});
|
|
79220
|
-
}
|
|
79221
|
-
}
|
|
79222
|
-
});
|
|
79223
|
-
function getPlanPrompt(task, planContent) {
|
|
79224
|
-
const planSection = planContent ? `
|
|
79225
|
-
The content of an existing plan file:
|
|
79226
|
-
<plan_file>
|
|
79227
|
-
${planContent}
|
|
79228
|
-
</plan_file>
|
|
79229
|
-
` : "";
|
|
79230
|
-
return `# Task Input
|
|
79231
|
-
|
|
79232
|
-
The user has provided a task:
|
|
79233
|
-
<task>
|
|
79234
|
-
${task}
|
|
79235
|
-
</task>
|
|
79236
|
-
${planSection}`;
|
|
79237
|
-
}
|
|
79238
|
-
var EPIC_ADD_TODO_ITEMS_SYSTEM_PROMPT = `Role: Task creation agent
|
|
79239
|
-
Goal: Parse a detailed epic plan and create todo items from the provided task breakdowns.
|
|
79240
|
-
|
|
79241
|
-
${TOOL_USAGE_INSTRUCTION}
|
|
79242
|
-
|
|
79243
|
-
You are a task creation agent responsible for parsing a detailed epic plan and creating todo items that can be executed autonomously by an AI coding agent.
|
|
79244
|
-
|
|
79245
|
-
## Your Responsibility
|
|
79246
|
-
|
|
79247
|
-
Your goal is to create todo items that are:
|
|
79248
|
-
- **Specific and actionable**: Each item should be clear enough for an AI agent to implement without human intervention
|
|
79249
|
-
- **Well-documented**: Include detailed implementation guidance extracted from the plan
|
|
79250
|
-
- **Context-rich**: Specify relevant files that will be modified or created (as provided in the plan)
|
|
79251
|
-
- **Self-contained**: Each item should be implementable independently with the context from the plan
|
|
79252
|
-
|
|
79253
|
-
## Plan Structure Expectations
|
|
79254
|
-
|
|
79255
|
-
The plan you receive contains all necessary implementation details. You should NOT need to explore the codebase because:
|
|
79256
|
-
- Each task in the plan already includes specific file paths
|
|
79257
|
-
- Function and class names are specified in the plan
|
|
79258
|
-
- Implementation patterns and approaches are provided
|
|
79259
|
-
- Dependencies and imports are listed
|
|
79260
|
-
- Technical specifications are included
|
|
79261
|
-
- Integration points are documented
|
|
79262
|
-
|
|
79263
|
-
Your job is to extract these details from the plan and create todo items, not to research or discover them.
|
|
79264
|
-
|
|
79265
|
-
## Todo Item Requirements
|
|
79266
|
-
|
|
79267
|
-
For each task in the plan, create a todo item using the \`updateTodoItem\` tool with:
|
|
79268
|
-
|
|
79269
|
-
### 1. **title** (required)
|
|
79270
|
-
A concise, action-oriented task name that clearly states what needs to be done.
|
|
79271
|
-
|
|
79272
|
-
**Examples:**
|
|
79273
|
-
- ✅ "Implement user authentication with JWT tokens"
|
|
79274
|
-
- ✅ "Add validation middleware for API endpoints"
|
|
79275
|
-
- ❌ "Authentication" (too vague)
|
|
79276
|
-
|
|
79277
|
-
### 2. **description** (required)
|
|
79278
|
-
Detailed implementation instructions extracted from the plan. Include:
|
|
79279
|
-
|
|
79280
|
-
**Must extract from the plan:**
|
|
79281
|
-
- **Specific files to create or modify** with exact paths (as specified in the plan)
|
|
79282
|
-
- **Function/class names** to implement or modify (as specified in the plan)
|
|
79283
|
-
- **Implementation patterns** to follow (as referenced in the plan)
|
|
79284
|
-
- **Technical requirements** and constraints (as documented in the plan)
|
|
79285
|
-
- **Dependencies** and imports needed (as listed in the plan)
|
|
79286
|
-
- **Integration points** with existing code (as described in the plan)
|
|
79287
78812
|
|
|
79288
|
-
|
|
79289
|
-
|
|
79290
|
-
Plan task:
|
|
79291
|
-
\`\`\`
|
|
79292
|
-
- [ ] Add authentication middleware in \`src/middleware/auth.ts\` that verifies JWT tokens from Authorization header and attaches user object to \`req.user\`
|
|
79293
|
-
\`\`\`
|
|
79294
|
-
|
|
79295
|
-
Todo item description:
|
|
79296
|
-
\`\`\`
|
|
79297
|
-
Create a new authentication middleware in \`src/middleware/auth.ts\`:
|
|
79298
|
-
|
|
79299
|
-
1. Implement \`authenticateJWT\` function that:
|
|
79300
|
-
- Extracts JWT token from Authorization header
|
|
79301
|
-
- Verifies token (implementation details from plan)
|
|
79302
|
-
- Attaches user object to \`req.user\`
|
|
79303
|
-
- Returns 401 error for invalid/missing tokens
|
|
79304
|
-
|
|
79305
|
-
2. Export the middleware for use in route definitions
|
|
79306
|
-
\`\`\`
|
|
79307
|
-
|
|
79308
|
-
**Note:** All implementation details should come from the plan. Do not add information not present in the plan.
|
|
79309
|
-
|
|
79310
|
-
## Process
|
|
79311
|
-
|
|
79312
|
-
1. **Read and parse the plan** provided in the user message to identify individual tasks
|
|
79313
|
-
2. **Parse the plan structure** to understand the task hierarchy and details
|
|
79314
|
-
3. **For each task in the plan:**
|
|
79315
|
-
a. Extract the specific files mentioned in the task
|
|
79316
|
-
b. Extract implementation patterns specified in the plan
|
|
79317
|
-
c. Create a detailed description using the plan's guidance
|
|
79318
|
-
d. Identify all relevant files from the plan
|
|
79319
|
-
e. Call \`updateTodoItem\` with operation='add', title and description
|
|
79320
|
-
|
|
79321
|
-
**Important:** Do NOT explore the codebase. All necessary information is already in the plan.
|
|
79322
|
-
|
|
79323
|
-
`;
|
|
78813
|
+
// src/workflows/prompts/coder.ts
|
|
79324
78814
|
var CODER_SYSTEM_PROMPT = `Role: AI developer.
|
|
79325
78815
|
Goal: Implement the provided plan by writing and modifying code.
|
|
79326
78816
|
|
|
@@ -79396,6 +78886,348 @@ ${plan}
|
|
|
79396
78886
|
</plan>
|
|
79397
78887
|
`;
|
|
79398
78888
|
}
|
|
78889
|
+
// src/workflows/prompts/commit.ts
|
|
78890
|
+
var COMMIT_MESSAGE_SYSTEM_PROMPT = `Role: Expert git user.
|
|
78891
|
+
Goal: Generate a concise and descriptive commit message in conventional commit format based on staged changes.
|
|
78892
|
+
|
|
78893
|
+
${TOOL_USAGE_INSTRUCTION}
|
|
78894
|
+
|
|
78895
|
+
You are an expert at writing git commit messages.
|
|
78896
|
+
Based on the provided list of staged files in <file_status>, the diff in <diff> and optional user context in <tool_input_context>, generate a concise and descriptive commit message.
|
|
78897
|
+
|
|
78898
|
+
Follow the conventional commit format.
|
|
78899
|
+
|
|
78900
|
+
${createJsonResponseInstruction({
|
|
78901
|
+
commitMessage: "feat: add new feature\\n\\ndescribe the new feature in more detail"
|
|
78902
|
+
})}
|
|
78903
|
+
`;
|
|
78904
|
+
// src/workflows/prompts/epic.ts
|
|
78905
|
+
var EPIC_PLANNER_SYSTEM_PROMPT = `Role: Expert software architect and epic planner.
|
|
78906
|
+
Goal: Analyze a large and complex user request (an "epic") and create a detailed implementation plan with task breakdowns.
|
|
78907
|
+
|
|
78908
|
+
${MEMORY_USAGE_SECTION}
|
|
78909
|
+
|
|
78910
|
+
${TOOL_USAGE_INSTRUCTION}
|
|
78911
|
+
|
|
78912
|
+
## Your Role
|
|
78913
|
+
|
|
78914
|
+
As an epic planner, your expertise lies in:
|
|
78915
|
+
- Decomposing large, complex features into structured task breakdowns
|
|
78916
|
+
- Creating epic-scale plans with implementation-ready task specifications
|
|
78917
|
+
- Organizing work into logical phases with clear dependencies
|
|
78918
|
+
- Providing complete technical details for each task to enable autonomous implementation
|
|
78919
|
+
|
|
78920
|
+
## Epic Planning Principles
|
|
78921
|
+
|
|
78922
|
+
**1. Explore Before Planning**
|
|
78923
|
+
- Use available tools to understand the existing codebase
|
|
78924
|
+
- Identify similar implementations, patterns, and conventions
|
|
78925
|
+
- Understand project structure, naming conventions, and architectural patterns
|
|
78926
|
+
- The best plans are informed by actual codebase state, not assumptions
|
|
78927
|
+
|
|
78928
|
+
**2. Epic Planning Structure**
|
|
78929
|
+
- **Phases**: Organize work into logical phases (e.g., "Phase 1: Backend API", "Phase 2: Frontend UI")
|
|
78930
|
+
- **Tasks**: Break each phase into specific, actionable tasks
|
|
78931
|
+
- **Dependencies**: Make task dependencies and ordering clear
|
|
78932
|
+
|
|
78933
|
+
**3. Task Detail Requirements**
|
|
78934
|
+
Each task must be **implementation-ready** with complete specifications:
|
|
78935
|
+
- **Exact file paths** for new files or modifications (e.g., \`src/api/auth.ts\`)
|
|
78936
|
+
- **Function/class signatures** to implement (e.g., \`async function authenticateUser(email: string, password: string)\`)
|
|
78937
|
+
- **Implementation patterns** from the codebase (e.g., "Follow the middleware pattern in \`src/middleware/logger.ts\`")
|
|
78938
|
+
- **Dependencies and imports** (e.g., "Import \`bcrypt\` for password hashing")
|
|
78939
|
+
- **Error handling approach** (e.g., "Use \`ApiError\` class from \`src/errors.ts\`")
|
|
78940
|
+
- **Integration points** with existing code (e.g., "Register in \`src/app.ts\` before route handlers")
|
|
78941
|
+
- **Testing requirements** (e.g., "Add tests in \`src/api/__tests__/auth.test.ts\`")
|
|
78942
|
+
|
|
78943
|
+
**Examples of appropriate task detail:**
|
|
78944
|
+
- ❌ **Too vague**: "Add authentication"
|
|
78945
|
+
- ❌ **Too granular**: "Add a 20px margin to the button on line 45"
|
|
78946
|
+
- ✅ **Implementation-ready**: "Implement authentication endpoints in \`src/api/auth.ts\` with \`POST /api/auth/login\` that validates credentials using bcrypt and returns JWT tokens with 24h expiration"
|
|
78947
|
+
|
|
78948
|
+
**4. Enable Autonomous Implementation**
|
|
78949
|
+
- Plans must provide enough detail that task creation doesn't require codebase exploration
|
|
78950
|
+
- Each task should be concrete and implementable by an AI agent
|
|
78951
|
+
- Include all technical information needed for autonomous execution
|
|
78952
|
+
|
|
78953
|
+
## Your Approach
|
|
78954
|
+
|
|
78955
|
+
When planning an epic:
|
|
78956
|
+
|
|
78957
|
+
1. **Understand the Goal**: Analyze the request to grasp objectives and constraints
|
|
78958
|
+
2. **Gather Context**: Explore the codebase to understand patterns and structure
|
|
78959
|
+
3. **Organize into Phases**: Break work into logical phases with clear progression
|
|
78960
|
+
4. **Define Tasks**: Create specific, implementation-ready tasks for each phase
|
|
78961
|
+
5. **Specify Details**: Provide complete technical specifications for each task
|
|
78962
|
+
6. **Seek Clarity**: Ask questions if requirements are ambiguous or information is missing
|
|
78963
|
+
|
|
78964
|
+
## Plan Format Guidelines
|
|
78965
|
+
|
|
78966
|
+
Your plan must have two parts: task description and implementation plan.
|
|
78967
|
+
|
|
78968
|
+
### 1. Task Description
|
|
78969
|
+
Include the verbatim user request to provide context for the implementation plan.
|
|
78970
|
+
|
|
78971
|
+
### 2. Implementation Plan
|
|
78972
|
+
|
|
78973
|
+
For epic-scale work, **use markdown checkboxes** to track progress through multiple sequential tasks:
|
|
78974
|
+
|
|
78975
|
+
**Required Checkbox Format**:
|
|
78976
|
+
- Use markdown checkboxes (\`- [ ] item\`) for all tasks
|
|
78977
|
+
- Organize checkboxes under numbered phases (Phase 1, Phase 2, etc.)
|
|
78978
|
+
- Create nested sub-tasks using indentation (max 3 levels: Phase > Task > Sub-task)
|
|
78979
|
+
- Each checkbox represents a distinct, trackable piece of work
|
|
78980
|
+
- Workflow automatically marks completed items with \`- [x]\`
|
|
78981
|
+
|
|
78982
|
+
**Nesting Rules**:
|
|
78983
|
+
- **Level 1 (Phase)**: High-level grouping (e.g., "Phase 1: Backend API Development")
|
|
78984
|
+
- **Level 2 (Task)**: Specific implementation work (e.g., "Design and implement authentication endpoints")
|
|
78985
|
+
- **Level 3 (Sub-task)**: Detailed breakdown when task is complex (e.g., "Create POST /api/auth/login endpoint")
|
|
78986
|
+
- **Maximum depth**: 3 levels to maintain clarity
|
|
78987
|
+
|
|
78988
|
+
**Each Task Must Include Implementation-Ready Details**:
|
|
78989
|
+
- **Exact file paths** for new files or modifications (e.g., \`src/api/auth.ts\`)
|
|
78990
|
+
- **Function/class signatures** to implement (e.g., \`async function authenticateUser(email: string, password: string)\`)
|
|
78991
|
+
- **Implementation patterns** to follow (e.g., "Follow the middleware pattern in \`src/middleware/logger.ts\`")
|
|
78992
|
+
- **Dependencies and imports** (e.g., "Import \`bcrypt\` for password hashing, use \`jsonwebtoken\` for JWT generation")
|
|
78993
|
+
- **Error handling** (e.g., "Use \`ApiError\` class from \`src/errors.ts\`")
|
|
78994
|
+
- **Integration points** (e.g., "Register middleware in \`src/app.ts\` before route handlers")
|
|
78995
|
+
- **Testing requirements** (e.g., "Add unit tests in \`src/api/__tests__/auth.test.ts\`")
|
|
78996
|
+
|
|
78997
|
+
\`\`\`
|
|
78998
|
+
### 1. Task Description
|
|
78999
|
+
|
|
79000
|
+
Implement user authentication with JWT tokens.
|
|
79001
|
+
|
|
79002
|
+
### 2. Implementation Plan
|
|
79003
|
+
|
|
79004
|
+
1. Phase 1: Backend API
|
|
79005
|
+
- [ ] Implement authentication endpoints in \`src/api/auth.ts\` with \`POST /api/auth/login\` (validates credentials using bcrypt, returns JWT with 24h expiration using \`jsonwebtoken\` library) and \`POST /api/auth/register\` (validates with zod, hashes password with bcrypt 10 rounds, stores via Prisma)
|
|
79006
|
+
- [ ] Create authentication middleware in \`src/middleware/auth.ts\` that verifies JWT tokens from Authorization header and attaches user to \`req.user\`, following pattern in \`src/middleware/logger.ts\`
|
|
79007
|
+
- [ ] Define User model in \`prisma/schema.prisma\` with id (UUID), email (unique), passwordHash, createdAt, updatedAt; generate migration with \`npx prisma migrate dev --name add-user-auth\`
|
|
79008
|
+
|
|
79009
|
+
2. Phase 2: Frontend Integration
|
|
79010
|
+
- [ ] Create \`LoginForm.tsx\` in \`src/components/auth/\` with email/password fields using React Hook Form, submit calls \`/api/auth/login\` endpoint
|
|
79011
|
+
- [ ] Create \`AuthContext.tsx\` using React Context API to manage auth state (user object, isAuthenticated boolean, login/logout functions that interact with localStorage JWT storage)
|
|
79012
|
+
- [ ] Add error handling using \`ErrorMessage\` component from \`src/components/ui/ErrorMessage.tsx\` and loading states with \`LoadingSpinner\` from \`src/components/ui/LoadingSpinner.tsx\`
|
|
79013
|
+
\`\`\`
|
|
79014
|
+
|
|
79015
|
+
**Good Task Detail (Implementation-Ready)**:
|
|
79016
|
+
\`\`\`
|
|
79017
|
+
- [ ] Implement authentication endpoints in \`src/api/auth.ts\` with \`POST /api/auth/login\` (validates credentials using bcrypt, returns JWT with 24h expiration using \`jsonwebtoken\` library) and \`POST /api/auth/register\` (validates with zod, hashes password with bcrypt 10 rounds, stores via Prisma)
|
|
79018
|
+
\`\`\`
|
|
79019
|
+
|
|
79020
|
+
**Poor Task Detail (Too Vague)**:
|
|
79021
|
+
\`\`\`
|
|
79022
|
+
- [ ] Add authentication to the backend API
|
|
79023
|
+
\`\`\`
|
|
79024
|
+
|
|
79025
|
+
**What to Include**:
|
|
79026
|
+
- Implementation steps with complete technical specifications
|
|
79027
|
+
- Exact file paths, function names, and implementation patterns
|
|
79028
|
+
- Dependencies, imports, and integration points
|
|
79029
|
+
- Technical constraints and requirements
|
|
79030
|
+
|
|
79031
|
+
**What NOT to Include**:
|
|
79032
|
+
- Future enhancements beyond current scope
|
|
79033
|
+
- Manual test plans or validation checklists
|
|
79034
|
+
- Meta-information about priorities
|
|
79035
|
+
|
|
79036
|
+
|
|
79037
|
+
|
|
79038
|
+
## Branch Naming Conventions
|
|
79039
|
+
|
|
79040
|
+
Branch names should:
|
|
79041
|
+
- Use kebab-case (lowercase with hyphens)
|
|
79042
|
+
- Start with a prefix: feat/, fix/, refactor/, docs/, test/, chore/
|
|
79043
|
+
- Be descriptive but concise (2-4 words typically)
|
|
79044
|
+
- Describe what is being changed, not who or why
|
|
79045
|
+
|
|
79046
|
+
## Decision Logic
|
|
79047
|
+
|
|
79048
|
+
1. **Analyze the request**: Review the task and any existing plan
|
|
79049
|
+
2. **If requirements are clear**:
|
|
79050
|
+
- Explore the codebase to understand patterns and conventions
|
|
79051
|
+
- Create an epic-scale plan with checkbox format and implementation-ready task details
|
|
79052
|
+
- Ensure each task includes specific file paths, function names, patterns, and technical details
|
|
79053
|
+
- Propose a suitable git branch name (see conventions below)
|
|
79054
|
+
3. **If requirements are unclear**:
|
|
79055
|
+
- Ask a clarifying question with optional default answer
|
|
79056
|
+
4. **If no action is needed**:
|
|
79057
|
+
- Provide reason (e.g., already implemented, not applicable)
|
|
79058
|
+
|
|
79059
|
+
## Response Format
|
|
79060
|
+
|
|
79061
|
+
${createJsonResponseInstruction({
|
|
79062
|
+
type: "'plan-generated' | 'question' | 'error'",
|
|
79063
|
+
plan: "The epic plan with checkbox format (required when type='plan-generated')",
|
|
79064
|
+
branchName: "Git branch name with valid prefix (required when type='plan-generated')",
|
|
79065
|
+
question: {
|
|
79066
|
+
question: "The clarifying question to ask",
|
|
79067
|
+
defaultAnswer: "Optional default answer"
|
|
79068
|
+
},
|
|
79069
|
+
reason: "Why no plan is needed (required when type='error')"
|
|
79070
|
+
})}
|
|
79071
|
+
|
|
79072
|
+
**Response Type Details:**
|
|
79073
|
+
|
|
79074
|
+
1. **plan-generated**: When you create or update an epic plan
|
|
79075
|
+
- Include complete plan with checkbox format
|
|
79076
|
+
- Provide branch name with valid prefix (feat/, fix/, refactor/, docs/, test/, chore/)
|
|
79077
|
+
|
|
79078
|
+
2. **question**: When you need clarification
|
|
79079
|
+
- Ask specific, unambiguous question
|
|
79080
|
+
- Optionally provide default answer
|
|
79081
|
+
|
|
79082
|
+
3. **error**: When no action is needed
|
|
79083
|
+
- Explain why (e.g., already implemented, not applicable)
|
|
79084
|
+
`;
|
|
79085
|
+
var BRANCH_NAME_PATTERN = /^[a-zA-Z0-9/_-]+$/;
|
|
79086
|
+
var EpicPlanSchema = exports_external.object({
|
|
79087
|
+
type: exports_external.enum(["plan-generated", "question", "error"]),
|
|
79088
|
+
plan: exports_external.string().nullish(),
|
|
79089
|
+
branchName: exports_external.string().min(3, "Branch name is too short (min 3 characters)").max(255, "Branch name is too long (max 255 characters)").refine((name18) => BRANCH_NAME_PATTERN.test(name18), {
|
|
79090
|
+
message: "Invalid branch name format. Branch names should contain only letters, numbers, hyphens, underscores, and forward slashes."
|
|
79091
|
+
}).nullish(),
|
|
79092
|
+
question: exports_external.object({
|
|
79093
|
+
question: exports_external.string(),
|
|
79094
|
+
defaultAnswer: exports_external.string().nullish()
|
|
79095
|
+
}).nullish(),
|
|
79096
|
+
reason: exports_external.string().nullish()
|
|
79097
|
+
}).superRefine((data, ctx) => {
|
|
79098
|
+
switch (data.type) {
|
|
79099
|
+
case "plan-generated": {
|
|
79100
|
+
if (!data.plan || data.plan.trim() === "") {
|
|
79101
|
+
ctx.addIssue({
|
|
79102
|
+
code: "custom",
|
|
79103
|
+
message: 'Plan is required when type is "plan-generated".',
|
|
79104
|
+
path: ["plan"]
|
|
79105
|
+
});
|
|
79106
|
+
}
|
|
79107
|
+
if (!data.branchName || data.branchName.trim() === "") {
|
|
79108
|
+
ctx.addIssue({
|
|
79109
|
+
code: "custom",
|
|
79110
|
+
message: 'Branch name is required when type is "plan-generated".',
|
|
79111
|
+
path: ["branchName"]
|
|
79112
|
+
});
|
|
79113
|
+
}
|
|
79114
|
+
break;
|
|
79115
|
+
}
|
|
79116
|
+
case "question": {
|
|
79117
|
+
if (!data.question) {
|
|
79118
|
+
ctx.addIssue({
|
|
79119
|
+
code: "custom",
|
|
79120
|
+
message: 'Question is required when type is "question".',
|
|
79121
|
+
path: ["question"]
|
|
79122
|
+
});
|
|
79123
|
+
}
|
|
79124
|
+
break;
|
|
79125
|
+
}
|
|
79126
|
+
case "error": {
|
|
79127
|
+
if (!data.reason || data.reason.trim() === "") {
|
|
79128
|
+
ctx.addIssue({
|
|
79129
|
+
code: "custom",
|
|
79130
|
+
message: 'Reason is required when type is "error".',
|
|
79131
|
+
path: ["reason"]
|
|
79132
|
+
});
|
|
79133
|
+
}
|
|
79134
|
+
break;
|
|
79135
|
+
}
|
|
79136
|
+
}
|
|
79137
|
+
});
|
|
79138
|
+
var EPIC_ADD_TODO_ITEMS_SYSTEM_PROMPT = `Role: Task extraction agent
|
|
79139
|
+
Goal: Parse an epic plan and create structured todo items from task breakdowns.
|
|
79140
|
+
|
|
79141
|
+
${TOOL_USAGE_INSTRUCTION}
|
|
79142
|
+
|
|
79143
|
+
You are responsible for extracting tasks from a detailed epic plan and creating todo items that can be executed autonomously by an AI coding agent.
|
|
79144
|
+
|
|
79145
|
+
## Expected Plan Format
|
|
79146
|
+
|
|
79147
|
+
The plan you receive follows a specific structure:
|
|
79148
|
+
- **Markdown checkboxes** (\`- [ ] item\`) indicate tasks
|
|
79149
|
+
- **Nesting** (indentation) indicates hierarchy: Phase > Task > Sub-task
|
|
79150
|
+
- **Implementation details** are included in each checkbox item
|
|
79151
|
+
- **Max 3 levels** of nesting
|
|
79152
|
+
|
|
79153
|
+
**Example plan structure:**
|
|
79154
|
+
\`\`\`
|
|
79155
|
+
1. Phase 1: Backend API
|
|
79156
|
+
- [ ] Implement authentication endpoints in \`src/api/auth.ts\` with \`POST /api/auth/login\`...
|
|
79157
|
+
- [ ] Create \`POST /api/auth/login\` endpoint that validates credentials...
|
|
79158
|
+
- [ ] Create \`POST /api/auth/register\` endpoint that validates input...
|
|
79159
|
+
- [ ] Create authentication middleware in \`src/middleware/auth.ts\`...
|
|
79160
|
+
\`\`\`
|
|
79161
|
+
|
|
79162
|
+
**Parsing rules:**
|
|
79163
|
+
- Lines with \`- [ ]\` are tasks to extract
|
|
79164
|
+
- Indentation level indicates parent-child relationships
|
|
79165
|
+
- Text after checkbox is the task title
|
|
79166
|
+
- Nested content provides additional context
|
|
79167
|
+
|
|
79168
|
+
## Your Role: Extract and Structure Tasks
|
|
79169
|
+
|
|
79170
|
+
Your job is to **extract and structure** tasks from the plan, not to explore or research:
|
|
79171
|
+
- Parse the checkbox structure to identify tasks
|
|
79172
|
+
- Extract implementation details already in the plan
|
|
79173
|
+
- Create todo items that preserve the plan's hierarchy
|
|
79174
|
+
- Do NOT explore the codebase - all information is in the plan
|
|
79175
|
+
|
|
79176
|
+
## Todo Item Creation Rules
|
|
79177
|
+
|
|
79178
|
+
For each checkbox in the plan, create a todo item using \`updateTodoItem\`:
|
|
79179
|
+
|
|
79180
|
+
### 1. **title** (required)
|
|
79181
|
+
Extract the checkbox text as the task title (max 60 characters, concise and action-oriented).
|
|
79182
|
+
|
|
79183
|
+
**Examples:**
|
|
79184
|
+
- Plan: \`- [ ] Implement authentication endpoints in \`src/api/auth.ts\`...\`
|
|
79185
|
+
- Title: "Implement authentication endpoints in src/api/auth.ts"
|
|
79186
|
+
|
|
79187
|
+
### 2. **description** (required)
|
|
79188
|
+
Extract and organize implementation details from the plan:
|
|
79189
|
+
|
|
79190
|
+
**Extract from the plan:**
|
|
79191
|
+
- **File paths**: All backtick-wrapped paths (e.g., \`src/api/auth.ts\`)
|
|
79192
|
+
- **Function/class names**: Code-formatted identifiers with parentheses (e.g., \`authenticateUser()\`)
|
|
79193
|
+
- **Dependencies**: "import X", "use Y library" mentions
|
|
79194
|
+
- **Patterns**: "Follow pattern in...", "Similar to..." references
|
|
79195
|
+
- **Technical specs**: All implementation guidance from the checkbox and nested content
|
|
79196
|
+
|
|
79197
|
+
**Example extraction:**
|
|
79198
|
+
|
|
79199
|
+
Plan:
|
|
79200
|
+
\`\`\`
|
|
79201
|
+
- [ ] Implement authentication endpoints in \`src/api/auth.ts\` with \`POST /api/auth/login\` that validates credentials using bcrypt and returns JWT tokens
|
|
79202
|
+
- [ ] Create \`POST /api/auth/login\` endpoint that accepts email/password in request body
|
|
79203
|
+
\`\`\`
|
|
79204
|
+
|
|
79205
|
+
Title: "Implement authentication endpoints in src/api/auth.ts"
|
|
79206
|
+
|
|
79207
|
+
Description:
|
|
79208
|
+
\`\`\`
|
|
79209
|
+
Create authentication endpoints in \`src/api/auth.ts\`:
|
|
79210
|
+
|
|
79211
|
+
**Main endpoint:**
|
|
79212
|
+
- \`POST /api/auth/login\` that validates credentials using bcrypt and returns JWT tokens
|
|
79213
|
+
|
|
79214
|
+
**Sub-tasks:**
|
|
79215
|
+
- Create \`POST /api/auth/login\` endpoint that accepts email/password in request body
|
|
79216
|
+
\`\`\`
|
|
79217
|
+
|
|
79218
|
+
|
|
79219
|
+
## Process
|
|
79220
|
+
|
|
79221
|
+
1. Parse the plan to identify all checkbox items
|
|
79222
|
+
2. For each checkbox:
|
|
79223
|
+
a. Extract title from checkbox text (keep concise)
|
|
79224
|
+
b. Extract description from checkbox content and nested items
|
|
79225
|
+
c. Identify parent-child relationships from indentation
|
|
79226
|
+
d. Extract file paths, functions, dependencies, patterns
|
|
79227
|
+
|
|
79228
|
+
**Remember:** Your role is extraction and organization, not exploration or planning.
|
|
79229
|
+
`;
|
|
79230
|
+
// src/workflows/prompts/fix.ts
|
|
79399
79231
|
var FIX_SYSTEM_PROMPT = `Role: Expert software developer.
|
|
79400
79232
|
Goal: Fix a failing command by analyzing the error and modifying the code.
|
|
79401
79233
|
|
|
@@ -79439,6 +79271,289 @@ ${stderr || "(empty)"}
|
|
|
79439
79271
|
</stderr>
|
|
79440
79272
|
`;
|
|
79441
79273
|
}
|
|
79274
|
+
// src/workflows/prompts/init.ts
|
|
79275
|
+
var INIT_WORKFLOW_ANALYZE_SYSTEM_PROMPT = `
|
|
79276
|
+
Role: Analyzer agent
|
|
79277
|
+
Goal: Produce a valid polkacodes YAML configuration for the project.
|
|
79278
|
+
|
|
79279
|
+
${TOOL_USAGE_INSTRUCTION}
|
|
79280
|
+
|
|
79281
|
+
Workflow
|
|
79282
|
+
1. Scan project files to identify the project's characteristics. Start using the "readFile" tool to understand the project's dependencies, scripts, and basic configuration.
|
|
79283
|
+
- Package/build tool (npm, bun, pnpm, etc.)
|
|
79284
|
+
- Test framework and patterns (snapshot tests, coverage, etc.)
|
|
79285
|
+
- Formatter / linter and their rules
|
|
79286
|
+
- Folder structure and naming conventions.
|
|
79287
|
+
- CI / development workflows (e.g., GitHub Actions in .github/workflows).
|
|
79288
|
+
|
|
79289
|
+
2. Build a YAML config with three root keys:
|
|
79290
|
+
|
|
79291
|
+
\`\`\`yaml
|
|
79292
|
+
scripts: # derive from package.json and CI workflows. Only include scripts that are relevant for development.
|
|
79293
|
+
format: # code formatter
|
|
79294
|
+
command: "<formatter cmd>"
|
|
79295
|
+
description: "Format code"
|
|
79296
|
+
check: # linter / type checker
|
|
79297
|
+
command: "<linter cmd>"
|
|
79298
|
+
description: "Static checks"
|
|
79299
|
+
test: # test runner
|
|
79300
|
+
command: "<test cmd>"
|
|
79301
|
+
description: "Run tests"
|
|
79302
|
+
# add any other meaningful project scripts like 'build', 'dev', etc.
|
|
79303
|
+
|
|
79304
|
+
rules: # A bullet list of key conventions, frameworks, and libraries used (e.g., "- React", "- TypeScript", "- Jest"). This helps other agents understand the project.
|
|
79305
|
+
|
|
79306
|
+
excludeFiles: # A list of glob patterns for files that should not be read. Only include files that might contain secrets.
|
|
79307
|
+
- ".env"
|
|
79308
|
+
- ".env.*"
|
|
79309
|
+
- "*.pem"
|
|
79310
|
+
- "*.key"
|
|
79311
|
+
- ".npmrc"
|
|
79312
|
+
# do NOT list build artifacts, lockfiles, or paths already in .gitignore
|
|
79313
|
+
\`\`\`
|
|
79314
|
+
|
|
79315
|
+
3. Return a JSON object with the generated YAML configuration as a string in the 'yaml' property.
|
|
79316
|
+
|
|
79317
|
+
${createJsonResponseInstruction({
|
|
79318
|
+
yaml: "<yaml_string>"
|
|
79319
|
+
})}
|
|
79320
|
+
`;
|
|
79321
|
+
// src/workflows/prompts/meta.ts
|
|
79322
|
+
var META_SYSTEM_PROMPT = `Role: Meta-agent.
|
|
79323
|
+
Goal: Decide which workflow ('code', 'task', or 'epic') to use for a given task.
|
|
79324
|
+
|
|
79325
|
+
You are a meta-agent that decides which workflow to use for a given task.
|
|
79326
|
+
Based on the user's task, decide whether to use the 'code', 'task', or 'epic' workflow.
|
|
79327
|
+
|
|
79328
|
+
- Use the 'code' workflow for tasks that are well-defined and can be implemented directly without a separate planning phase.
|
|
79329
|
+
- Use the 'task' workflow for simple, single-action tasks like answering a question or running a command.
|
|
79330
|
+
- Use the 'epic' workflow for large, complex features that require breaking down into multiple sequential tasks, creating a feature branch, and executing multiple implementation-commit-review cycles.
|
|
79331
|
+
|
|
79332
|
+
The user's task is provided in the <task> tag.
|
|
79333
|
+
|
|
79334
|
+
${createJsonResponseInstruction({
|
|
79335
|
+
workflow: "<workflow_name>"
|
|
79336
|
+
})}
|
|
79337
|
+
`;
|
|
79338
|
+
// src/workflows/prompts/plan.ts
|
|
79339
|
+
function getPlanPrompt(task, planContent) {
|
|
79340
|
+
const planSection = planContent ? `
|
|
79341
|
+
The content of an existing plan file:
|
|
79342
|
+
<plan_file>
|
|
79343
|
+
${planContent}
|
|
79344
|
+
</plan_file>
|
|
79345
|
+
` : "";
|
|
79346
|
+
return `# Task Input
|
|
79347
|
+
|
|
79348
|
+
The user has provided a task:
|
|
79349
|
+
<task>
|
|
79350
|
+
${task}
|
|
79351
|
+
</task>
|
|
79352
|
+
${planSection}`;
|
|
79353
|
+
}
|
|
79354
|
+
// src/workflows/prompts/planner.ts
|
|
79355
|
+
var PLANNER_SYSTEM_PROMPT = `Role: Expert software architect and planner.
|
|
79356
|
+
Goal: Analyze user requests and create detailed, actionable implementation plans for software development tasks.
|
|
79357
|
+
|
|
79358
|
+
You are an expert software architect and planner with deep experience in breaking down complex requirements into actionable implementation plans.
|
|
79359
|
+
|
|
79360
|
+
${MEMORY_USAGE_SECTION}
|
|
79361
|
+
|
|
79362
|
+
${TOOL_USAGE_INSTRUCTION}
|
|
79363
|
+
|
|
79364
|
+
## Your Role
|
|
79365
|
+
|
|
79366
|
+
As a planner, your expertise lies in:
|
|
79367
|
+
- Analyzing requirements to understand the core objective and technical implications
|
|
79368
|
+
- Exploring codebases to identify patterns, conventions, and integration points
|
|
79369
|
+
- Breaking down complex tasks into clear, logical sequences of steps
|
|
79370
|
+
- Anticipating dependencies, edge cases, and potential challenges
|
|
79371
|
+
- Creating plans that can be executed autonomously by an AI coding agent
|
|
79372
|
+
- Providing technical specificity required for autonomous implementation
|
|
79373
|
+
|
|
79374
|
+
## Planning Philosophy
|
|
79375
|
+
|
|
79376
|
+
Effective planning requires understanding before action:
|
|
79377
|
+
|
|
79378
|
+
1. **Explore First, Plan Second**
|
|
79379
|
+
- Never plan in a vacuum. Use available tools to understand the existing codebase
|
|
79380
|
+
- Identify similar implementations, patterns, and conventions already in use
|
|
79381
|
+
- Understand the project structure, naming conventions, and architectural patterns
|
|
79382
|
+
- Look at tests to understand expected behavior and testing approaches
|
|
79383
|
+
|
|
79384
|
+
2. **Context is Critical**
|
|
79385
|
+
- The best plans are informed by the actual state of the codebase
|
|
79386
|
+
- File system exploration (\`listFiles\`, \`searchFiles\`) reveals structure and patterns
|
|
79387
|
+
- Reading existing files (\`readFile\`) shows coding style and conventions
|
|
79388
|
+
- Understanding context prevents suggesting solutions that don't fit the project
|
|
79389
|
+
|
|
79390
|
+
3. **Specificity Over Generality**
|
|
79391
|
+
- Vague plans lead to implementation confusion and prevent autonomous execution
|
|
79392
|
+
- Instead of "implement the feature," specify which files to modify, what functions to add, and what logic to implement
|
|
79393
|
+
- Name specific components, modules, or files when possible
|
|
79394
|
+
- Describe what needs to change and why
|
|
79395
|
+
- Examples:
|
|
79396
|
+
* ❌ Vague: "Implement the feature"
|
|
79397
|
+
* ✅ Specific: "Create \`src/components/LoginForm.tsx\` with a React component that includes email and password fields, using the existing \`useAuth\` hook from \`src/hooks/useAuth.ts\`"
|
|
79398
|
+
* ❌ Vague: "Add error handling"
|
|
79399
|
+
* ✅ Specific: "In \`src/api/client.ts\`, wrap the fetch call in a try-catch block and throw custom errors using the \`ApiError\` class from \`src/errors.ts\`"
|
|
79400
|
+
|
|
79401
|
+
4. **Clarity for AI Coding Agents**
|
|
79402
|
+
- Plans will be executed autonomously by an AI coding agent without human intervention
|
|
79403
|
+
- Break complex tasks into smaller, logical units that can be completed independently
|
|
79404
|
+
- Use clear structure (numbered lists, narrative text, or combined formats) to organize steps
|
|
79405
|
+
- Include exact file paths, function names, and implementation patterns
|
|
79406
|
+
|
|
79407
|
+
## Planning for AI Implementation
|
|
79408
|
+
|
|
79409
|
+
Plans will be executed by an AI coding agent that operates autonomously with the following capabilities:
|
|
79410
|
+
|
|
79411
|
+
**Planning Requirements:**
|
|
79412
|
+
Plans should include specific technical details to enable autonomous implementation:
|
|
79413
|
+
- **Function/class names**: Name specific functions, classes, or components to implement
|
|
79414
|
+
- **Implementation patterns**: Reference existing patterns or provide clear guidance on approach
|
|
79415
|
+
- **Import statements**: Specify required dependencies and where to import them from
|
|
79416
|
+
- **Technical constraints**: Note any architectural decisions, performance requirements, or compatibility concerns
|
|
79417
|
+
|
|
79418
|
+
**What Makes a Good AI-Actionable Plan:**
|
|
79419
|
+
- Each step can be completed using the available tools
|
|
79420
|
+
- File paths and code structures are explicitly named
|
|
79421
|
+
- Dependencies between steps are clear
|
|
79422
|
+
- Implementation approach follows existing codebase patterns
|
|
79423
|
+
- Technical requirements are specific, not general
|
|
79424
|
+
|
|
79425
|
+
## Your Approach
|
|
79426
|
+
|
|
79427
|
+
When given a planning task:
|
|
79428
|
+
|
|
79429
|
+
1. **Understand the Goal**: Analyze the request thoroughly to grasp the primary objective and any constraints
|
|
79430
|
+
2. **Gather Context**: Explore the codebase using available tools to understand existing patterns and structure
|
|
79431
|
+
3. **Identify Patterns**: Look for similar implementations that can guide the approach
|
|
79432
|
+
4. **Break Down the Work**: Decompose the solution into logical, sequential steps
|
|
79433
|
+
5. **Be Specific**: Provide concrete details about files, functions, and implementations
|
|
79434
|
+
6. **Seek Clarity**: If requirements are ambiguous or critical information is missing, ask for clarification
|
|
79435
|
+
|
|
79436
|
+
## Tool Usage Strategy
|
|
79437
|
+
|
|
79438
|
+
Use exploration tools strategically:
|
|
79439
|
+
- \`listFiles\`: Understand project structure and locate relevant directories
|
|
79440
|
+
- \`searchFiles\`: Find existing patterns, similar implementations, or specific code
|
|
79441
|
+
- \`readFile\`: Examine existing code to understand style, patterns, and conventions
|
|
79442
|
+
- \`fetchUrl\`: Access external documentation or resources when needed
|
|
79443
|
+
- \`askFollowupQuestion\`: Request clarification when requirements are unclear or ambiguous
|
|
79444
|
+
|
|
79445
|
+
The goal is to create well-informed plans based on actual codebase understanding, not assumptions.
|
|
79446
|
+
|
|
79447
|
+
## Plan Format Guidelines
|
|
79448
|
+
|
|
79449
|
+
When generating your plan, follow these formatting guidelines:
|
|
79450
|
+
|
|
79451
|
+
1. Number major sections to provide clear structure:
|
|
79452
|
+
a. Use numbers (1., 2., 3., etc.) for top-level sections
|
|
79453
|
+
b. Use nested numbering (1.1, 1.2) or letters (a., b., c.) for sub-sections
|
|
79454
|
+
c. This makes sections easy to reference and understand
|
|
79455
|
+
d. Provides clear hierarchy and organization
|
|
79456
|
+
|
|
79457
|
+
Example section numbering:
|
|
79458
|
+
1. Project Setup
|
|
79459
|
+
1.1 Initialize repository
|
|
79460
|
+
1.2 Configure dependencies
|
|
79461
|
+
2. Implementation
|
|
79462
|
+
2.1 Core features
|
|
79463
|
+
2.2 Tests
|
|
79464
|
+
|
|
79465
|
+
2. Use numbered lists when the order of steps matters:
|
|
79466
|
+
a. Sequential steps where one depends on the previous
|
|
79467
|
+
b. Steps that must be performed in a specific order
|
|
79468
|
+
c. Processes with clear progression
|
|
79469
|
+
d. When steps need to be referenced by number
|
|
79470
|
+
|
|
79471
|
+
Example numbered list format:
|
|
79472
|
+
1. First step that must be completed first
|
|
79473
|
+
2. Second step that depends on the first
|
|
79474
|
+
3. Third step that follows from the second
|
|
79475
|
+
|
|
79476
|
+
3. Use narrative or structured text format when the plan involves:
|
|
79477
|
+
a. High-level strategies or conceptual approaches
|
|
79478
|
+
b. Explanations or background information
|
|
79479
|
+
c. Decision-making guidance
|
|
79480
|
+
d. Context that doesn't translate well to discrete steps
|
|
79481
|
+
|
|
79482
|
+
4. Combine formats when appropriate:
|
|
79483
|
+
a. Use numbered sections for overall structure
|
|
79484
|
+
b. Use narrative text for context and explanation
|
|
79485
|
+
c. Use numbered lists for sequential steps
|
|
79486
|
+
|
|
79487
|
+
Example combined format:
|
|
79488
|
+
1. Phase 1: Setup
|
|
79489
|
+
First, we need to configure the environment...
|
|
79490
|
+
1. Install dependencies
|
|
79491
|
+
2. Configure settings
|
|
79492
|
+
3. Verify installation
|
|
79493
|
+
|
|
79494
|
+
2. Phase 2: Implementation
|
|
79495
|
+
The implementation should focus on...
|
|
79496
|
+
1. Implement feature A
|
|
79497
|
+
2. Implement feature B
|
|
79498
|
+
3. Write tests
|
|
79499
|
+
|
|
79500
|
+
5. Include implementation-ready details for AI agents:
|
|
79501
|
+
a. Provide specific technical details the coding agent needs (file paths, function signatures, etc.)
|
|
79502
|
+
b. Avoid steps that require human intervention or manual processes
|
|
79503
|
+
c. Each step should be implementable using the AI agent's available tools
|
|
79504
|
+
d. Reference existing code patterns and conventions from the codebase
|
|
79505
|
+
|
|
79506
|
+
**Note**: Plans should use flexible formats such as numbered lists or narrative text. Checklist formats (markdown checkboxes) are NOT required and should only be used when specifically appropriate for tracking independent action items.
|
|
79507
|
+
|
|
79508
|
+
## Decision Logic
|
|
79509
|
+
|
|
79510
|
+
1. Analyze the task and the existing plan (if any).
|
|
79511
|
+
2. If the requirements are clear and you can generate or update the plan:
|
|
79512
|
+
a. Provide the plan in the "plan" field
|
|
79513
|
+
b. Apply appropriate formatting based on guidelines above
|
|
79514
|
+
c. Include relevant file paths in the "files" array if applicable
|
|
79515
|
+
3. If the requirements are not clear:
|
|
79516
|
+
a. Ask a clarifying question in the "question" field
|
|
79517
|
+
4. If the task is already implemented or no action is needed:
|
|
79518
|
+
a. Do not generate a plan
|
|
79519
|
+
b. Provide a concise reason in the "reason" field
|
|
79520
|
+
|
|
79521
|
+
## Response Format
|
|
79522
|
+
|
|
79523
|
+
${createJsonResponseInstruction({
|
|
79524
|
+
plan: "The generated or updated plan.",
|
|
79525
|
+
question: {
|
|
79526
|
+
question: "The clarifying question to ask the user.",
|
|
79527
|
+
defaultAnswer: "The default answer to provide if the user does not provide an answer."
|
|
79528
|
+
},
|
|
79529
|
+
reason: "If no plan is needed, provide a reason here.",
|
|
79530
|
+
files: ["path/to/file1.ts", "path/to/file2.ts"]
|
|
79531
|
+
})}
|
|
79532
|
+
`;
|
|
79533
|
+
var PlanSchema = exports_external.object({
|
|
79534
|
+
plan: exports_external.string().nullish(),
|
|
79535
|
+
question: exports_external.object({
|
|
79536
|
+
question: exports_external.string(),
|
|
79537
|
+
defaultAnswer: exports_external.string().nullish()
|
|
79538
|
+
}).nullish(),
|
|
79539
|
+
reason: exports_external.string().nullish(),
|
|
79540
|
+
files: exports_external.array(exports_external.string()).nullish()
|
|
79541
|
+
});
|
|
79542
|
+
// src/workflows/prompts/pr.ts
|
|
79543
|
+
var GET_PR_DETAILS_SYSTEM_PROMPT = `Role: Expert developer.
|
|
79544
|
+
Goal: Generate a pull request title and description based on the branch name, commits, and diff.
|
|
79545
|
+
|
|
79546
|
+
${TOOL_USAGE_INSTRUCTION}
|
|
79547
|
+
|
|
79548
|
+
You are an expert at creating pull requests.
|
|
79549
|
+
Based on the provided branch name, commit messages, and diff, generate a title and description for the pull request.
|
|
79550
|
+
|
|
79551
|
+
${createJsonResponseInstruction({
|
|
79552
|
+
title: "feat: add new feature",
|
|
79553
|
+
description: "This pull request adds a new feature that does...\\n\\n### Changes\\n- ..."
|
|
79554
|
+
})}
|
|
79555
|
+
`;
|
|
79556
|
+
// src/workflows/prompts/review.ts
|
|
79442
79557
|
var CODE_REVIEW_SYSTEM_PROMPT = `Role: Senior software engineer.
|
|
79443
79558
|
Goal: Review code changes and provide specific, actionable feedback on any issues found.
|
|
79444
79559
|
|
|
@@ -79555,96 +79670,6 @@ ${instructions}
|
|
|
79555
79670
|
return parts.join(`
|
|
79556
79671
|
`);
|
|
79557
79672
|
}
|
|
79558
|
-
var COMMIT_MESSAGE_SYSTEM_PROMPT = `Role: Expert git user.
|
|
79559
|
-
Goal: Generate a concise and descriptive commit message in conventional commit format based on staged changes.
|
|
79560
|
-
|
|
79561
|
-
${TOOL_USAGE_INSTRUCTION}
|
|
79562
|
-
|
|
79563
|
-
You are an expert at writing git commit messages.
|
|
79564
|
-
Based on the provided list of staged files in <file_status>, the diff in <diff> and optional user context in <tool_input_context>, generate a concise and descriptive commit message.
|
|
79565
|
-
|
|
79566
|
-
Follow the conventional commit format.
|
|
79567
|
-
|
|
79568
|
-
${createJsonResponseInstruction({
|
|
79569
|
-
commitMessage: "feat: add new feature\\n\\ndescribe the new feature in more detail"
|
|
79570
|
-
})}
|
|
79571
|
-
`;
|
|
79572
|
-
var GET_PR_DETAILS_SYSTEM_PROMPT = `Role: Expert developer.
|
|
79573
|
-
Goal: Generate a pull request title and description based on the branch name, commits, and diff.
|
|
79574
|
-
|
|
79575
|
-
${TOOL_USAGE_INSTRUCTION}
|
|
79576
|
-
|
|
79577
|
-
You are an expert at creating pull requests.
|
|
79578
|
-
Based on the provided branch name, commit messages, and diff, generate a title and description for the pull request.
|
|
79579
|
-
|
|
79580
|
-
${createJsonResponseInstruction({
|
|
79581
|
-
title: "feat: add new feature",
|
|
79582
|
-
description: "This pull request adds a new feature that does...\\n\\n### Changes\\n- ..."
|
|
79583
|
-
})}
|
|
79584
|
-
`;
|
|
79585
|
-
var INIT_WORKFLOW_ANALYZE_SYSTEM_PROMPT = `
|
|
79586
|
-
Role: Analyzer agent
|
|
79587
|
-
Goal: Produce a valid polkacodes YAML configuration for the project.
|
|
79588
|
-
|
|
79589
|
-
${TOOL_USAGE_INSTRUCTION}
|
|
79590
|
-
|
|
79591
|
-
Workflow
|
|
79592
|
-
1. Scan project files to identify the project's characteristics. Start using the "readFile" tool to understand the project's dependencies, scripts, and basic configuration.
|
|
79593
|
-
- Package/build tool (npm, bun, pnpm, etc.)
|
|
79594
|
-
- Test framework and patterns (snapshot tests, coverage, etc.)
|
|
79595
|
-
- Formatter / linter and their rules
|
|
79596
|
-
- Folder structure and naming conventions.
|
|
79597
|
-
- CI / development workflows (e.g., GitHub Actions in .github/workflows).
|
|
79598
|
-
|
|
79599
|
-
2. Build a YAML config with three root keys:
|
|
79600
|
-
|
|
79601
|
-
\`\`\`yaml
|
|
79602
|
-
scripts: # derive from package.json and CI workflows. Only include scripts that are relevant for development.
|
|
79603
|
-
format: # code formatter
|
|
79604
|
-
command: "<formatter cmd>"
|
|
79605
|
-
description: "Format code"
|
|
79606
|
-
check: # linter / type checker
|
|
79607
|
-
command: "<linter cmd>"
|
|
79608
|
-
description: "Static checks"
|
|
79609
|
-
test: # test runner
|
|
79610
|
-
command: "<test cmd>"
|
|
79611
|
-
description: "Run tests"
|
|
79612
|
-
# add any other meaningful project scripts like 'build', 'dev', etc.
|
|
79613
|
-
|
|
79614
|
-
rules: # A bullet list of key conventions, frameworks, and libraries used (e.g., "- React", "- TypeScript", "- Jest"). This helps other agents understand the project.
|
|
79615
|
-
|
|
79616
|
-
excludeFiles: # A list of glob patterns for files that should not be read. Only include files that might contain secrets.
|
|
79617
|
-
- ".env"
|
|
79618
|
-
- ".env.*"
|
|
79619
|
-
- "*.pem"
|
|
79620
|
-
- "*.key"
|
|
79621
|
-
- ".npmrc"
|
|
79622
|
-
# do NOT list build artifacts, lockfiles, or paths already in .gitignore
|
|
79623
|
-
\`\`\`
|
|
79624
|
-
|
|
79625
|
-
3. Return a JSON object with the generated YAML configuration as a string in the 'yaml' property.
|
|
79626
|
-
|
|
79627
|
-
${createJsonResponseInstruction({
|
|
79628
|
-
yaml: "<yaml_string>"
|
|
79629
|
-
})}
|
|
79630
|
-
`;
|
|
79631
|
-
var META_SYSTEM_PROMPT = `Role: Meta-agent.
|
|
79632
|
-
Goal: Decide which workflow ('code', 'task', or 'epic') to use for a given task.
|
|
79633
|
-
|
|
79634
|
-
You are a meta-agent that decides which workflow to use for a given task.
|
|
79635
|
-
Based on the user's task, decide whether to use the 'code', 'task', or 'epic' workflow.
|
|
79636
|
-
|
|
79637
|
-
- Use the 'code' workflow for tasks that are well-defined and can be implemented directly without a separate planning phase.
|
|
79638
|
-
- Use the 'task' workflow for simple, single-action tasks like answering a question or running a command.
|
|
79639
|
-
- Use the 'epic' workflow for large, complex features that require breaking down into multiple sequential tasks, creating a feature branch, and executing multiple implementation-commit-review cycles.
|
|
79640
|
-
|
|
79641
|
-
The user's task is provided in the <task> tag.
|
|
79642
|
-
|
|
79643
|
-
${createJsonResponseInstruction({
|
|
79644
|
-
workflow: "<workflow_name>"
|
|
79645
|
-
})}
|
|
79646
|
-
`;
|
|
79647
|
-
|
|
79648
79673
|
// src/workflows/fix.workflow.ts
|
|
79649
79674
|
var FixIterationSummarySchema = exports_external.object({
|
|
79650
79675
|
summary: exports_external.string().nullish(),
|
|
@@ -79777,35 +79802,45 @@ ${memoryContext}`
|
|
|
79777
79802
|
// src/workflows/plan.workflow.ts
|
|
79778
79803
|
async function createPlan(input2, context) {
|
|
79779
79804
|
const { tools: tools2, step } = context;
|
|
79780
|
-
const { task, files, plan: inputPlan, userFeedback, interactive } = input2;
|
|
79781
|
-
const
|
|
79782
|
-
|
|
79783
|
-
|
|
79784
|
-
|
|
79785
|
-
|
|
79786
|
-
|
|
79787
|
-
|
|
79805
|
+
const { task, files, plan: inputPlan, userFeedback, interactive, messages } = input2;
|
|
79806
|
+
const getMessages = async () => {
|
|
79807
|
+
if (messages) {
|
|
79808
|
+
return {
|
|
79809
|
+
messages,
|
|
79810
|
+
userMessage: [{ role: "user", content: userFeedback ?? task }]
|
|
79811
|
+
};
|
|
79812
|
+
} else {
|
|
79813
|
+
const defaultContext = await getDefaultContext();
|
|
79814
|
+
const memoryContext = await tools2.getMemoryContext();
|
|
79815
|
+
const prompt = `${memoryContext}
|
|
79816
|
+
${getPlanPrompt(task, inputPlan)}
|
|
79788
79817
|
|
|
79789
79818
|
${defaultContext}`;
|
|
79790
|
-
|
|
79791
|
-
|
|
79792
|
-
|
|
79793
|
-
|
|
79794
|
-
|
|
79795
|
-
|
|
79796
|
-
|
|
79797
|
-
|
|
79798
|
-
|
|
79799
|
-
|
|
79800
|
-
|
|
79801
|
-
|
|
79802
|
-
|
|
79803
|
-
|
|
79804
|
-
|
|
79805
|
-
|
|
79819
|
+
const userContent = [{ type: "text", text: prompt }];
|
|
79820
|
+
if (files) {
|
|
79821
|
+
for (const file2 of files) {
|
|
79822
|
+
if (file2.type === "file") {
|
|
79823
|
+
userContent.push({
|
|
79824
|
+
type: "file",
|
|
79825
|
+
mediaType: file2.mediaType,
|
|
79826
|
+
filename: file2.filename,
|
|
79827
|
+
data: { type: "base64", value: file2.data }
|
|
79828
|
+
});
|
|
79829
|
+
} else if (file2.type === "image") {
|
|
79830
|
+
userContent.push({
|
|
79831
|
+
type: "image",
|
|
79832
|
+
mediaType: file2.mediaType,
|
|
79833
|
+
image: { type: "base64", value: file2.image }
|
|
79834
|
+
});
|
|
79835
|
+
}
|
|
79836
|
+
}
|
|
79806
79837
|
}
|
|
79838
|
+
return {
|
|
79839
|
+
systemPrompt: PLANNER_SYSTEM_PROMPT,
|
|
79840
|
+
userMessage: [{ role: "user", content: userContent }]
|
|
79841
|
+
};
|
|
79807
79842
|
}
|
|
79808
|
-
}
|
|
79843
|
+
};
|
|
79809
79844
|
const agentTools = [
|
|
79810
79845
|
readFile_default,
|
|
79811
79846
|
listFiles_default,
|
|
@@ -79819,21 +79854,21 @@ ${defaultContext}`;
|
|
|
79819
79854
|
if (interactive) {
|
|
79820
79855
|
agentTools.push(askFollowupQuestion_default);
|
|
79821
79856
|
}
|
|
79857
|
+
const inputMessages = await getMessages();
|
|
79822
79858
|
const result = await step("plan", async () => {
|
|
79823
79859
|
return await agentWorkflow({
|
|
79824
|
-
|
|
79825
|
-
userMessage: [{ role: "user", content: userContent }],
|
|
79860
|
+
...inputMessages,
|
|
79826
79861
|
tools: agentTools,
|
|
79827
79862
|
outputSchema: PlanSchema
|
|
79828
79863
|
}, context);
|
|
79829
79864
|
});
|
|
79830
79865
|
if (result.type === "Exit" && result.object) {
|
|
79831
|
-
const { plan, question, reason, files: filePaths } = result.object;
|
|
79866
|
+
const { plan: plan2, question, reason, files: filePaths } = result.object;
|
|
79832
79867
|
if (reason) {
|
|
79833
|
-
return { reason };
|
|
79868
|
+
return { reason, messages: result.messages };
|
|
79834
79869
|
}
|
|
79835
79870
|
if (question) {
|
|
79836
|
-
return { plan:
|
|
79871
|
+
return { plan: plan2 || inputPlan, question, messages: result.messages };
|
|
79837
79872
|
}
|
|
79838
79873
|
const outputFiles = [];
|
|
79839
79874
|
if (filePaths) {
|
|
@@ -79844,7 +79879,7 @@ ${defaultContext}`;
|
|
|
79844
79879
|
}
|
|
79845
79880
|
}
|
|
79846
79881
|
}
|
|
79847
|
-
return { plan:
|
|
79882
|
+
return { plan: plan2 || undefined, files: outputFiles, messages: result.messages };
|
|
79848
79883
|
}
|
|
79849
79884
|
context.logger.warn("Failed to generate plan.", result);
|
|
79850
79885
|
throw new Error("Failed to generate plan.");
|
|
@@ -79853,9 +79888,10 @@ var planWorkflow = async (input2, context) => {
|
|
|
79853
79888
|
const { tools: tools2, logger, step } = context;
|
|
79854
79889
|
const { fileContent, filePath, mode = "interactive" } = input2;
|
|
79855
79890
|
let currentTask = input2.task;
|
|
79856
|
-
let
|
|
79891
|
+
let plan2 = fileContent || "";
|
|
79857
79892
|
let files = [];
|
|
79858
|
-
let userFeedback
|
|
79893
|
+
let userFeedback;
|
|
79894
|
+
let messages;
|
|
79859
79895
|
let state = "Generating";
|
|
79860
79896
|
let count = 0;
|
|
79861
79897
|
while (state !== "Done") {
|
|
@@ -79863,8 +79899,8 @@ var planWorkflow = async (input2, context) => {
|
|
|
79863
79899
|
switch (state) {
|
|
79864
79900
|
case "Generating": {
|
|
79865
79901
|
if (!currentTask) {
|
|
79866
|
-
const message =
|
|
79867
|
-
const defaultTask =
|
|
79902
|
+
const message = plan2 ? "How would you like to improve the plan?" : "What is the task you want to plan?";
|
|
79903
|
+
const defaultTask = plan2 ? "Review and improve the plan" : undefined;
|
|
79868
79904
|
try {
|
|
79869
79905
|
currentTask = await tools2.input({
|
|
79870
79906
|
message,
|
|
@@ -79876,11 +79912,13 @@ var planWorkflow = async (input2, context) => {
|
|
|
79876
79912
|
}
|
|
79877
79913
|
const planResult = await createPlan({
|
|
79878
79914
|
task: currentTask,
|
|
79879
|
-
plan,
|
|
79915
|
+
plan: plan2,
|
|
79880
79916
|
userFeedback,
|
|
79881
79917
|
files: input2.files,
|
|
79882
|
-
interactive: mode === "interactive" || mode === "confirm"
|
|
79918
|
+
interactive: mode === "interactive" || mode === "confirm",
|
|
79919
|
+
messages
|
|
79883
79920
|
}, context);
|
|
79921
|
+
messages = planResult.messages;
|
|
79884
79922
|
if (planResult.reason) {
|
|
79885
79923
|
logger.info(planResult.reason);
|
|
79886
79924
|
return "Done";
|
|
@@ -79891,7 +79929,7 @@ var planWorkflow = async (input2, context) => {
|
|
|
79891
79929
|
message: planResult.question.question,
|
|
79892
79930
|
default: planResult.question.defaultAnswer || undefined
|
|
79893
79931
|
});
|
|
79894
|
-
|
|
79932
|
+
plan2 = planResult.plan || plan2;
|
|
79895
79933
|
return "Generating";
|
|
79896
79934
|
} catch (error46) {
|
|
79897
79935
|
if (error46 instanceof UserCancelledError) {
|
|
@@ -79900,7 +79938,7 @@ var planWorkflow = async (input2, context) => {
|
|
|
79900
79938
|
return "Done";
|
|
79901
79939
|
}
|
|
79902
79940
|
}
|
|
79903
|
-
|
|
79941
|
+
plan2 = planResult.plan || "";
|
|
79904
79942
|
files = planResult.files || [];
|
|
79905
79943
|
userFeedback = "";
|
|
79906
79944
|
return "Reviewing";
|
|
@@ -79909,7 +79947,7 @@ var planWorkflow = async (input2, context) => {
|
|
|
79909
79947
|
logger.info(`
|
|
79910
79948
|
Generated Plan:
|
|
79911
79949
|
`);
|
|
79912
|
-
logger.info(
|
|
79950
|
+
logger.info(plan2);
|
|
79913
79951
|
if (files?.length > 0) {
|
|
79914
79952
|
logger.info(`
|
|
79915
79953
|
Files:`);
|
|
@@ -79955,7 +79993,7 @@ Files:`);
|
|
|
79955
79993
|
message: "Where do you want to save the plan?",
|
|
79956
79994
|
default: defaultPath
|
|
79957
79995
|
});
|
|
79958
|
-
await tools2.writeToFile({ path: savePath, content:
|
|
79996
|
+
await tools2.writeToFile({ path: savePath, content: plan2 });
|
|
79959
79997
|
logger.info(`Plan saved to ${savePath}`);
|
|
79960
79998
|
return "Done";
|
|
79961
79999
|
}
|
|
@@ -79971,8 +80009,9 @@ Files:`);
|
|
|
79971
80009
|
}
|
|
79972
80010
|
}
|
|
79973
80011
|
case "regenerate": {
|
|
79974
|
-
|
|
80012
|
+
plan2 = "";
|
|
79975
80013
|
userFeedback = "";
|
|
80014
|
+
messages = undefined;
|
|
79976
80015
|
return "Generating";
|
|
79977
80016
|
}
|
|
79978
80017
|
case "exit": {
|
|
@@ -79987,7 +80026,7 @@ Files:`);
|
|
|
79987
80026
|
}
|
|
79988
80027
|
});
|
|
79989
80028
|
}
|
|
79990
|
-
return { plan, files };
|
|
80029
|
+
return { plan: plan2, files };
|
|
79991
80030
|
};
|
|
79992
80031
|
|
|
79993
80032
|
// src/workflows/code.workflow.ts
|
|
@@ -80011,11 +80050,11 @@ Phase 1: Creating implementation plan...
|
|
|
80011
80050
|
logger.info("Plan not approved. Exiting.");
|
|
80012
80051
|
return { success: false, reason: "Plan not approved", summaries };
|
|
80013
80052
|
}
|
|
80014
|
-
const { plan, files: planFiles } = planResult;
|
|
80053
|
+
const { plan: plan2, files: planFiles } = planResult;
|
|
80015
80054
|
logger.info(`
|
|
80016
80055
|
Phase 2: Implementing the plan...
|
|
80017
80056
|
`);
|
|
80018
|
-
let implementPrompt = getImplementPrompt(
|
|
80057
|
+
let implementPrompt = getImplementPrompt(plan2);
|
|
80019
80058
|
if (planFiles && planFiles.length > 0) {
|
|
80020
80059
|
const fileContentString = planFiles.map((f) => `<file path="${f.path}">${f.content}</file>`).join(`
|
|
80021
80060
|
`);
|
|
@@ -80540,8 +80579,28 @@ ${provider3.toUpperCase()}_API_KEY=${providerConfig.apiKey}`;
|
|
|
80540
80579
|
var MAX_REVIEW_RETRIES = 5;
|
|
80541
80580
|
var TODO_HANDLING_INSTRUCTIONS = `If you discover that a task is larger than you thought, or that a new task is required, you can add a // TODO comment in the code and create a todo item for it. This will allow you to continue with the current task and address the larger issue later.`;
|
|
80542
80581
|
async function createPlan2(input2, context) {
|
|
80543
|
-
const { task, plan, files, feedback } = input2;
|
|
80544
|
-
const
|
|
80582
|
+
const { task, plan: plan2, files, feedback, messages } = input2;
|
|
80583
|
+
const agentTools = [
|
|
80584
|
+
askFollowupQuestion_default,
|
|
80585
|
+
fetchUrl_default,
|
|
80586
|
+
listFiles_default,
|
|
80587
|
+
readFile_default,
|
|
80588
|
+
readBinaryFile_default,
|
|
80589
|
+
searchFiles_default,
|
|
80590
|
+
readMemory_default,
|
|
80591
|
+
updateMemory_default,
|
|
80592
|
+
listMemoryTopics_default
|
|
80593
|
+
];
|
|
80594
|
+
if (messages) {
|
|
80595
|
+
const userMessage2 = feedback ? [{ role: "user", content: feedback }] : [];
|
|
80596
|
+
return await agentWorkflow({
|
|
80597
|
+
messages,
|
|
80598
|
+
userMessage: userMessage2,
|
|
80599
|
+
tools: agentTools,
|
|
80600
|
+
outputSchema: EpicPlanSchema
|
|
80601
|
+
}, context);
|
|
80602
|
+
}
|
|
80603
|
+
const content = [{ type: "text", text: getPlanPrompt(task, plan2) }];
|
|
80545
80604
|
if (files) {
|
|
80546
80605
|
for (const file2 of files) {
|
|
80547
80606
|
if (file2.type === "file") {
|
|
@@ -80560,33 +80619,13 @@ async function createPlan2(input2, context) {
|
|
|
80560
80619
|
}
|
|
80561
80620
|
}
|
|
80562
80621
|
}
|
|
80563
|
-
|
|
80564
|
-
|
|
80565
|
-
type: "text",
|
|
80566
|
-
text: `The user has provided the following feedback on the plan, please adjust it:
|
|
80567
|
-
${feedback}`
|
|
80568
|
-
});
|
|
80569
|
-
}
|
|
80570
|
-
const planResult = await agentWorkflow({
|
|
80622
|
+
const userMessage = [{ role: "user", content }];
|
|
80623
|
+
return await agentWorkflow({
|
|
80571
80624
|
systemPrompt: EPIC_PLANNER_SYSTEM_PROMPT,
|
|
80572
|
-
userMessage
|
|
80573
|
-
tools:
|
|
80574
|
-
askFollowupQuestion_default,
|
|
80575
|
-
fetchUrl_default,
|
|
80576
|
-
listFiles_default,
|
|
80577
|
-
readFile_default,
|
|
80578
|
-
readBinaryFile_default,
|
|
80579
|
-
searchFiles_default,
|
|
80580
|
-
readMemory_default,
|
|
80581
|
-
updateMemory_default,
|
|
80582
|
-
listMemoryTopics_default
|
|
80583
|
-
],
|
|
80625
|
+
userMessage,
|
|
80626
|
+
tools: agentTools,
|
|
80584
80627
|
outputSchema: EpicPlanSchema
|
|
80585
80628
|
}, context);
|
|
80586
|
-
if (planResult.type === "Exit") {
|
|
80587
|
-
return planResult.object;
|
|
80588
|
-
}
|
|
80589
|
-
return { type: "error", reason: "Usage limit exceeded." };
|
|
80590
80629
|
}
|
|
80591
80630
|
async function createAndApprovePlan(task, context) {
|
|
80592
80631
|
const { logger, step, tools: tools2 } = context;
|
|
@@ -80594,10 +80633,17 @@ async function createAndApprovePlan(task, context) {
|
|
|
80594
80633
|
`);
|
|
80595
80634
|
let feedback;
|
|
80596
80635
|
let planAttempt = 1;
|
|
80636
|
+
let messages;
|
|
80597
80637
|
try {
|
|
80598
80638
|
while (true) {
|
|
80599
|
-
const
|
|
80639
|
+
const planAgentResult = await step(`plan-${planAttempt}`, () => createPlan2({ task, feedback, messages }, context));
|
|
80640
|
+
messages = planAgentResult.messages;
|
|
80600
80641
|
planAttempt++;
|
|
80642
|
+
if (planAgentResult.type !== "Exit" /* Exit */) {
|
|
80643
|
+
logger.error(`Plan creation failed. Agent exited with status: ${planAgentResult.type}`);
|
|
80644
|
+
return null;
|
|
80645
|
+
}
|
|
80646
|
+
const result = planAgentResult.object;
|
|
80601
80647
|
switch (result.type) {
|
|
80602
80648
|
case "plan-generated": {
|
|
80603
80649
|
if (!result.plan || !result.branchName) {
|
|
@@ -80691,7 +80737,7 @@ async function createFeatureBranch(branchName, baseBranch, context) {
|
|
|
80691
80737
|
logger.error(`Error: Failed to create or switch to a feature branch after ${MAX_ATTEMPTS} attempts.`);
|
|
80692
80738
|
return { success: false, branchName: null };
|
|
80693
80739
|
}
|
|
80694
|
-
async function addTodoItemsFromPlan(
|
|
80740
|
+
async function addTodoItemsFromPlan(plan2, context) {
|
|
80695
80741
|
const { logger, step, tools: tools2 } = context;
|
|
80696
80742
|
logger.info(`Phase 4: Creating todo items from plan...
|
|
80697
80743
|
`);
|
|
@@ -80700,7 +80746,7 @@ async function addTodoItemsFromPlan(plan, context) {
|
|
|
80700
80746
|
systemPrompt: EPIC_ADD_TODO_ITEMS_SYSTEM_PROMPT,
|
|
80701
80747
|
userMessage: [{ role: "user", content: `Please create the todo items based on the plan
|
|
80702
80748
|
<plan>
|
|
80703
|
-
${
|
|
80749
|
+
${plan2}</plan>` }],
|
|
80704
80750
|
tools: [readFile_default, searchFiles_default, listFiles_default, readMemory_default, getTodoItem_default, listTodoItems_default, updateTodoItem_default, updateMemory_default, listMemoryTopics_default]
|
|
80705
80751
|
}, context);
|
|
80706
80752
|
});
|
|
@@ -80750,7 +80796,7 @@ async function performReviewAndFixCycle(iterationCount, taskItem, highLevelPlan,
|
|
|
80750
80796
|
const { logger, step, tools: tools2 } = context;
|
|
80751
80797
|
for (let i = 0;i < MAX_REVIEW_RETRIES; i++) {
|
|
80752
80798
|
const diffResult = await tools2.executeCommand({ command: "git", args: ["diff", "--name-status", "HEAD~1", "HEAD"] });
|
|
80753
|
-
const changedFiles = parseGitDiffNameStatus(diffResult.stdout);
|
|
80799
|
+
const changedFiles = parseGitDiffNameStatus(diffResult.stdout).filter(({ path }) => path !== ".epic.yml");
|
|
80754
80800
|
if (changedFiles.length === 0) {
|
|
80755
80801
|
logger.info(`No files were changed. Skipping review.
|
|
80756
80802
|
`);
|
|
@@ -80789,8 +80835,8 @@ ${formatReviewToolInput(changeInfo)}`;
|
|
|
80789
80835
|
}
|
|
80790
80836
|
logger.warn(`Warning: Review found ${reviewResult.specificReviews.length} issue(s). Attempting to fix...
|
|
80791
80837
|
`);
|
|
80792
|
-
for (const [idx,
|
|
80793
|
-
logger.warn(` ${idx + 1}. ${
|
|
80838
|
+
for (const [idx, review2] of reviewResult.specificReviews.entries()) {
|
|
80839
|
+
logger.warn(` ${idx + 1}. ${review2.file}:${review2.lines}`);
|
|
80794
80840
|
}
|
|
80795
80841
|
logger.warn("");
|
|
80796
80842
|
const reviewSummary = reviewResult.specificReviews.map((r) => `File: ${r.file} (lines: ${r.lines})
|
|
@@ -80828,6 +80874,20 @@ Max retries (${MAX_REVIEW_RETRIES}) reached. Moving to the next task, but issues
|
|
|
80828
80874
|
}
|
|
80829
80875
|
return { passed: false };
|
|
80830
80876
|
}
|
|
80877
|
+
async function findNextTask(tools2) {
|
|
80878
|
+
const openRootTasks = await tools2.listTodoItems({ status: "open" });
|
|
80879
|
+
if (openRootTasks.length === 0) {
|
|
80880
|
+
return null;
|
|
80881
|
+
}
|
|
80882
|
+
let currentTask = openRootTasks[0];
|
|
80883
|
+
while (true) {
|
|
80884
|
+
const subTasks = await tools2.listTodoItems({ status: "open", id: currentTask.id });
|
|
80885
|
+
if (subTasks.length === 0) {
|
|
80886
|
+
return currentTask;
|
|
80887
|
+
}
|
|
80888
|
+
currentTask = subTasks[0];
|
|
80889
|
+
}
|
|
80890
|
+
}
|
|
80831
80891
|
async function runImplementationLoop(context, highLevelPlan) {
|
|
80832
80892
|
const { logger, step, tools: tools2 } = context;
|
|
80833
80893
|
const commitMessages = [];
|
|
@@ -80836,22 +80896,11 @@ async function runImplementationLoop(context, highLevelPlan) {
|
|
|
80836
80896
|
logger.info(`${"=".repeat(80)}
|
|
80837
80897
|
`);
|
|
80838
80898
|
let iterationCount = 0;
|
|
80839
|
-
let
|
|
80840
|
-
|
|
80841
|
-
let nextTaskId = null;
|
|
80842
|
-
const initialTasks = await step("get-initial-tasks", async () => {
|
|
80843
|
-
return await tools2.listTodoItems({ status: "open" });
|
|
80844
|
-
});
|
|
80845
|
-
if (initialTasks.length > 0) {
|
|
80846
|
-
const firstTask = initialTasks[0];
|
|
80847
|
-
nextTask = firstTask.title;
|
|
80848
|
-
nextTaskId = firstTask.id;
|
|
80849
|
-
} else {
|
|
80850
|
-
isComplete = true;
|
|
80851
|
-
}
|
|
80852
|
-
while (!isComplete && nextTask && nextTaskId) {
|
|
80899
|
+
let nextTaskItem = await step("get-initial-task", () => findNextTask(tools2));
|
|
80900
|
+
while (nextTaskItem) {
|
|
80853
80901
|
iterationCount++;
|
|
80854
80902
|
const taskStartTime = Date.now();
|
|
80903
|
+
const { title: nextTask, id: nextTaskId } = nextTaskItem;
|
|
80855
80904
|
logger.info(`
|
|
80856
80905
|
${"-".repeat(80)}`);
|
|
80857
80906
|
logger.info(`Iteration ${iterationCount}`);
|
|
@@ -80891,24 +80940,9 @@ Focus only on this item, but use the plan for context.`;
|
|
|
80891
80940
|
logger.warn(`Warning: Iteration ${iterationCount} completed with potential issues (${taskElapsedTime})`);
|
|
80892
80941
|
}
|
|
80893
80942
|
await step(`update-task-status-${iterationCount}`, async () => {
|
|
80894
|
-
if (!nextTaskId) {
|
|
80895
|
-
throw new Error("Invariant violation: nextTaskId is null inside the implementation loop.");
|
|
80896
|
-
}
|
|
80897
80943
|
await tools2.updateTodoItem({ operation: "update", id: nextTaskId, status: "completed" });
|
|
80898
80944
|
});
|
|
80899
|
-
|
|
80900
|
-
return await tools2.listTodoItems({ status: "open" });
|
|
80901
|
-
});
|
|
80902
|
-
if (openTasks.length > 0) {
|
|
80903
|
-
const nextTodo = openTasks[0];
|
|
80904
|
-
nextTask = nextTodo.title;
|
|
80905
|
-
nextTaskId = nextTodo.id;
|
|
80906
|
-
isComplete = false;
|
|
80907
|
-
} else {
|
|
80908
|
-
nextTask = null;
|
|
80909
|
-
nextTaskId = null;
|
|
80910
|
-
isComplete = true;
|
|
80911
|
-
}
|
|
80945
|
+
nextTaskItem = await step(`get-next-task-${iterationCount}`, () => findNextTask(tools2));
|
|
80912
80946
|
const allTodos = await tools2.listTodoItems({});
|
|
80913
80947
|
const completedTodos = allTodos.filter((t) => t.status === "completed").length;
|
|
80914
80948
|
const totalTodos = allTodos.length;
|
|
@@ -80920,13 +80954,13 @@ Focus only on this item, but use the plan for context.`;
|
|
|
80920
80954
|
}
|
|
80921
80955
|
logger.info(`
|
|
80922
80956
|
Progress: ${progressMessage}`);
|
|
80923
|
-
if (
|
|
80957
|
+
if (!nextTaskItem) {
|
|
80924
80958
|
logger.info(`All tasks complete!
|
|
80925
80959
|
`);
|
|
80926
80960
|
break;
|
|
80927
80961
|
}
|
|
80928
|
-
if (
|
|
80929
|
-
logger.info(`Next task: ${
|
|
80962
|
+
if (nextTaskItem) {
|
|
80963
|
+
logger.info(`Next task: ${nextTaskItem.title}
|
|
80930
80964
|
`);
|
|
80931
80965
|
}
|
|
80932
80966
|
logger.info(`${"-".repeat(80)}
|
|
@@ -80952,7 +80986,7 @@ Phase 6: Final Review and Fixup...
|
|
|
80952
80986
|
const commitRange = `${baseBranch}...${currentBranch}`;
|
|
80953
80987
|
for (let i = 0;i < MAX_REVIEW_RETRIES; i++) {
|
|
80954
80988
|
const diffResult = await tools2.executeCommand({ command: "git", args: ["diff", "--name-status", commitRange] });
|
|
80955
|
-
const changedFiles = parseGitDiffNameStatus(diffResult.stdout);
|
|
80989
|
+
const changedFiles = parseGitDiffNameStatus(diffResult.stdout).filter(({ path }) => path !== ".epic.yml");
|
|
80956
80990
|
if (changedFiles.length === 0) {
|
|
80957
80991
|
logger.info(`No files have been changed in this branch. Skipping final review.
|
|
80958
80992
|
`);
|
|
@@ -80991,8 +81025,8 @@ ${formatReviewToolInput(changeInfo)}`;
|
|
|
80991
81025
|
}
|
|
80992
81026
|
logger.warn(`Warning: Final review found ${reviewResult.specificReviews.length} issue(s). Attempting to fix...
|
|
80993
81027
|
`);
|
|
80994
|
-
for (const [idx,
|
|
80995
|
-
logger.warn(` ${idx + 1}. ${
|
|
81028
|
+
for (const [idx, review2] of reviewResult.specificReviews.entries()) {
|
|
81029
|
+
logger.warn(` ${idx + 1}. ${review2.file}:${review2.lines}`);
|
|
80996
81030
|
}
|
|
80997
81031
|
logger.warn("");
|
|
80998
81032
|
const reviewSummary = reviewResult.specificReviews.map((r) => `File: ${r.file} (lines: ${r.lines})
|
|
@@ -81256,10 +81290,10 @@ var prWorkflow = async (input2, context) => {
|
|
|
81256
81290
|
// src/workflows/review.workflow.ts
|
|
81257
81291
|
var reviewWorkflow = async (input2, context) => {
|
|
81258
81292
|
const { step, tools: tools2, logger } = context;
|
|
81259
|
-
const { pr } = input2;
|
|
81293
|
+
const { pr: pr2 } = input2;
|
|
81260
81294
|
let changeInfo;
|
|
81261
|
-
if (
|
|
81262
|
-
const prNumberMatch =
|
|
81295
|
+
if (pr2) {
|
|
81296
|
+
const prNumberMatch = pr2.match(/\d+$/);
|
|
81263
81297
|
if (!prNumberMatch) {
|
|
81264
81298
|
throw new Error("Invalid PR number or URL.");
|
|
81265
81299
|
}
|
|
@@ -81636,7 +81670,7 @@ var reviewCommand = new Command("review").description("Review a GitHub pull requ
|
|
|
81636
81670
|
}
|
|
81637
81671
|
return parsedValue;
|
|
81638
81672
|
}, 1).action(async (options, command) => {
|
|
81639
|
-
const { json: json2, pr:
|
|
81673
|
+
const { json: json2, pr: pr3, loop: maxIterations, yes: yesOption } = options;
|
|
81640
81674
|
const yes = maxIterations > 1 || yesOption;
|
|
81641
81675
|
let changesAppliedInThisIteration = false;
|
|
81642
81676
|
const globalOpts = (command.parent ?? command).opts();
|
|
@@ -81646,7 +81680,7 @@ var reviewCommand = new Command("review").description("Review a GitHub pull requ
|
|
|
81646
81680
|
});
|
|
81647
81681
|
for (let i = 0;i < maxIterations; i++) {
|
|
81648
81682
|
changesAppliedInThisIteration = false;
|
|
81649
|
-
const input2 = { pr:
|
|
81683
|
+
const input2 = { pr: pr3 };
|
|
81650
81684
|
if (i > 0) {
|
|
81651
81685
|
logger.debug(`Re-running review (iteration ${i + 1} of ${maxIterations})...`);
|
|
81652
81686
|
}
|