@polka-codes/cli 0.9.54 → 0.9.56
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 +842 -733
- 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.56";
|
|
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 {
|
|
@@ -78705,8 +78705,10 @@ async function runWorkflow(workflow2, workflowInput, options) {
|
|
|
78705
78705
|
maxMessages: config4.maxMessageCount,
|
|
78706
78706
|
maxCost: config4.budget
|
|
78707
78707
|
});
|
|
78708
|
+
options.onUsageMeterCreated?.(usage);
|
|
78708
78709
|
const onEvent = printEvent(verbose, usage, process.stderr);
|
|
78709
|
-
const
|
|
78710
|
+
const excludeFiles = [".epic.yml", ...config4.excludeFiles ?? []];
|
|
78711
|
+
const toolProvider = (options.getProvider ?? getProvider)({ excludeFiles });
|
|
78710
78712
|
const commandConfig = providerConfig.getConfigForCommand(commandName);
|
|
78711
78713
|
if (!commandConfig) {
|
|
78712
78714
|
throw new Error(`No provider configured for command: ${commandName}`);
|
|
@@ -78772,7 +78774,7 @@ Workflow completed successfully.`);
|
|
|
78772
78774
|
}
|
|
78773
78775
|
}
|
|
78774
78776
|
|
|
78775
|
-
// src/workflows/prompts.ts
|
|
78777
|
+
// src/workflows/prompts/shared.ts
|
|
78776
78778
|
function createJsonResponseInstruction(schema) {
|
|
78777
78779
|
return `Respond with a JSON object in a markdown code block matching this schema:
|
|
78778
78780
|
\`\`\`json
|
|
@@ -78808,519 +78810,8 @@ Memory is organized using topics, which are like named containers for different
|
|
|
78808
78810
|
- Use the default topic for simple, single-context scenarios
|
|
78809
78811
|
- Memory persists across all tool calls within the current workflow
|
|
78810
78812
|
`;
|
|
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
78813
|
|
|
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
|
-
`;
|
|
78814
|
+
// src/workflows/prompts/coder.ts
|
|
79324
78815
|
var CODER_SYSTEM_PROMPT = `Role: AI developer.
|
|
79325
78816
|
Goal: Implement the provided plan by writing and modifying code.
|
|
79326
78817
|
|
|
@@ -79396,6 +78887,355 @@ ${plan}
|
|
|
79396
78887
|
</plan>
|
|
79397
78888
|
`;
|
|
79398
78889
|
}
|
|
78890
|
+
// src/workflows/prompts/commit.ts
|
|
78891
|
+
var COMMIT_MESSAGE_SYSTEM_PROMPT = `Role: Expert git user.
|
|
78892
|
+
Goal: Generate a concise and descriptive commit message in conventional commit format based on staged changes.
|
|
78893
|
+
|
|
78894
|
+
${TOOL_USAGE_INSTRUCTION}
|
|
78895
|
+
|
|
78896
|
+
You are an expert at writing git commit messages.
|
|
78897
|
+
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.
|
|
78898
|
+
|
|
78899
|
+
Follow the conventional commit format.
|
|
78900
|
+
|
|
78901
|
+
${createJsonResponseInstruction({
|
|
78902
|
+
commitMessage: "feat: add new feature\\n\\ndescribe the new feature in more detail"
|
|
78903
|
+
})}
|
|
78904
|
+
`;
|
|
78905
|
+
// src/workflows/prompts/epic.ts
|
|
78906
|
+
var EPIC_PLANNER_SYSTEM_PROMPT = `Role: Expert software architect and epic planner.
|
|
78907
|
+
Goal: Analyze a large and complex user request (an "epic") and create a detailed implementation plan with task breakdowns.
|
|
78908
|
+
|
|
78909
|
+
${MEMORY_USAGE_SECTION}
|
|
78910
|
+
|
|
78911
|
+
${TOOL_USAGE_INSTRUCTION}
|
|
78912
|
+
|
|
78913
|
+
## Your Role
|
|
78914
|
+
|
|
78915
|
+
As an epic planner, your expertise lies in:
|
|
78916
|
+
- Decomposing large, complex features into structured task breakdowns
|
|
78917
|
+
- Creating epic-scale plans with implementation-ready task specifications
|
|
78918
|
+
- Organizing work into logical phases with clear dependencies
|
|
78919
|
+
- Providing complete technical details for each task to enable autonomous implementation
|
|
78920
|
+
|
|
78921
|
+
## Epic Planning Principles
|
|
78922
|
+
|
|
78923
|
+
**1. Explore Before Planning**
|
|
78924
|
+
- Use available tools to understand the existing codebase
|
|
78925
|
+
- Identify similar implementations, patterns, and conventions
|
|
78926
|
+
- Understand project structure, naming conventions, and architectural patterns
|
|
78927
|
+
- The best plans are informed by actual codebase state, not assumptions
|
|
78928
|
+
|
|
78929
|
+
**2. Epic Planning Structure**
|
|
78930
|
+
- **Phases**: Organize work into logical phases (e.g., "Phase 1: Backend API", "Phase 2: Frontend UI")
|
|
78931
|
+
- **Tasks**: Break each phase into specific, actionable tasks
|
|
78932
|
+
- **Dependencies**: Make task dependencies and ordering clear
|
|
78933
|
+
|
|
78934
|
+
**3. Task Detail Requirements**
|
|
78935
|
+
Each task must be **implementation-ready** with complete specifications:
|
|
78936
|
+
- **Exact file paths** for new files or modifications (e.g., \`src/api/auth.ts\`)
|
|
78937
|
+
- **Function/class signatures** to implement (e.g., \`async function authenticateUser(email: string, password: string)\`)
|
|
78938
|
+
- **Implementation patterns** from the codebase (e.g., "Follow the middleware pattern in \`src/middleware/logger.ts\`")
|
|
78939
|
+
- **Dependencies and imports** (e.g., "Import \`bcrypt\` for password hashing")
|
|
78940
|
+
- **Error handling approach** (e.g., "Use \`ApiError\` class from \`src/errors.ts\`")
|
|
78941
|
+
- **Integration points** with existing code (e.g., "Register in \`src/app.ts\` before route handlers")
|
|
78942
|
+
- **Testing requirements** (e.g., "Add tests in \`src/api/__tests__/auth.test.ts\`")
|
|
78943
|
+
|
|
78944
|
+
**Examples of appropriate task detail:**
|
|
78945
|
+
- ❌ **Too vague**: "Add authentication"
|
|
78946
|
+
- ❌ **Too granular**: "Add a 20px margin to the button on line 45"
|
|
78947
|
+
- ✅ **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"
|
|
78948
|
+
|
|
78949
|
+
**4. Enable Autonomous Implementation**
|
|
78950
|
+
- Plans must provide enough detail that task creation doesn't require codebase exploration
|
|
78951
|
+
- Each task should be concrete and implementable by an AI agent
|
|
78952
|
+
- Include all technical information needed for autonomous execution
|
|
78953
|
+
|
|
78954
|
+
## Your Approach
|
|
78955
|
+
|
|
78956
|
+
When planning an epic:
|
|
78957
|
+
|
|
78958
|
+
1. **Understand the Goal**: Analyze the request to grasp objectives and constraints
|
|
78959
|
+
2. **Gather Context**: Explore the codebase to understand patterns and structure
|
|
78960
|
+
3. **Organize into Phases**: Break work into logical phases with clear progression
|
|
78961
|
+
4. **Define Tasks**: Create specific, implementation-ready tasks for each phase
|
|
78962
|
+
5. **Specify Details**: Provide complete technical specifications for each task
|
|
78963
|
+
6. **Seek Clarity**: Ask questions if requirements are ambiguous or information is missing
|
|
78964
|
+
|
|
78965
|
+
## Plan Format Guidelines
|
|
78966
|
+
|
|
78967
|
+
Your plan must have two parts: task description and implementation plan.
|
|
78968
|
+
|
|
78969
|
+
### 1. Task Description
|
|
78970
|
+
Start by providing a detailed description of the task and its expected outcome. This description should be a comprehensive summary based on the user's request, setting the stage for the detailed implementation plan that follows. It should clearly articulate the "what" and "why" of the epic before breaking it down into "how".
|
|
78971
|
+
|
|
78972
|
+
### 2. Implementation Plan
|
|
78973
|
+
|
|
78974
|
+
For epic-scale work, **use markdown checkboxes** to track progress through multiple sequential tasks:
|
|
78975
|
+
|
|
78976
|
+
**Required Checkbox Format**:
|
|
78977
|
+
- Use markdown checkboxes (\`- [ ] item\`) for all tasks
|
|
78978
|
+
- Organize checkboxes under numbered phases (Phase 1, Phase 2, etc.)
|
|
78979
|
+
- Create nested sub-tasks using indentation (max 3 levels: Phase > Task > Sub-task)
|
|
78980
|
+
- Each checkbox represents a distinct, trackable piece of work
|
|
78981
|
+
- Workflow automatically marks completed items with \`- [x]\`
|
|
78982
|
+
|
|
78983
|
+
**Nesting Rules**:
|
|
78984
|
+
- **Level 1 (Phase)**: High-level grouping (e.g., "Phase 1: Backend API Development")
|
|
78985
|
+
- **Level 2 (Task)**: Specific implementation work (e.g., "Design and implement authentication endpoints")
|
|
78986
|
+
- **Level 3 (Sub-task)**: Detailed breakdown when task is complex (e.g., "Create POST /api/auth/login endpoint")
|
|
78987
|
+
- **Maximum depth**: 3 levels to maintain clarity
|
|
78988
|
+
|
|
78989
|
+
**Each Task Must Include Implementation-Ready Details**:
|
|
78990
|
+
- **Exact file paths** for new files or modifications (e.g., \`src/api/auth.ts\`)
|
|
78991
|
+
- **Function/class signatures** to implement (e.g., \`async function authenticateUser(email: string, password: string)\`)
|
|
78992
|
+
- **Implementation patterns** to follow (e.g., "Follow the middleware pattern in \`src/middleware/logger.ts\`")
|
|
78993
|
+
- **Dependencies and imports** (e.g., "Import \`bcrypt\` for password hashing, use \`jsonwebtoken\` for JWT generation")
|
|
78994
|
+
- **Error handling** (e.g., "Use \`ApiError\` class from \`src/errors.ts\`")
|
|
78995
|
+
- **Integration points** (e.g., "Register middleware in \`src/app.ts\` before route handlers")
|
|
78996
|
+
- **Testing requirements** (e.g., "Add unit tests in \`src/api/__tests__/auth.test.ts\`")
|
|
78997
|
+
|
|
78998
|
+
\`\`\`
|
|
78999
|
+
### 1. Task Description
|
|
79000
|
+
|
|
79001
|
+
This epic is to implement a complete user authentication system using JSON Web Tokens (JWT). The primary goal is to allow users to register for a new account and log in to receive a token that can be used to access protected resources. The system should handle password hashing for security and provide a way to manage user sessions on the frontend.
|
|
79002
|
+
|
|
79003
|
+
**Expected Outcome:**
|
|
79004
|
+
- A backend with registration and login endpoints.
|
|
79005
|
+
- Secure password storage using bcrypt.
|
|
79006
|
+
- JWT generation upon successful login.
|
|
79007
|
+
- Middleware to protect specific routes.
|
|
79008
|
+
- A frontend with a login form, registration form, and context for managing authentication state.
|
|
79009
|
+
|
|
79010
|
+
### 2. Implementation Plan
|
|
79011
|
+
|
|
79012
|
+
1. Phase 1: Backend API
|
|
79013
|
+
- [ ] 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)
|
|
79014
|
+
- [ ] 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\`
|
|
79015
|
+
- [ ] 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\`
|
|
79016
|
+
|
|
79017
|
+
2. Phase 2: Frontend Integration
|
|
79018
|
+
- [ ] Create \`LoginForm.tsx\` in \`src/components/auth/\` with email/password fields using React Hook Form, submit calls \`/api/auth/login\` endpoint
|
|
79019
|
+
- [ ] Create \`AuthContext.tsx\` using React Context API to manage auth state (user object, isAuthenticated boolean, login/logout functions that interact with localStorage JWT storage)
|
|
79020
|
+
- [ ] Add error handling using \`ErrorMessage\` component from \`src/components/ui/ErrorMessage.tsx\` and loading states with \`LoadingSpinner\` from \`src/components/ui/LoadingSpinner.tsx\`
|
|
79021
|
+
\`\`\`
|
|
79022
|
+
|
|
79023
|
+
**Good Task Detail (Implementation-Ready)**:
|
|
79024
|
+
\`\`\`
|
|
79025
|
+
- [ ] 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)
|
|
79026
|
+
\`\`\`
|
|
79027
|
+
|
|
79028
|
+
**Poor Task Detail (Too Vague)**:
|
|
79029
|
+
\`\`\`
|
|
79030
|
+
- [ ] Add authentication to the backend API
|
|
79031
|
+
\`\`\`
|
|
79032
|
+
|
|
79033
|
+
**What to Include**:
|
|
79034
|
+
- Implementation steps with complete technical specifications
|
|
79035
|
+
- Exact file paths, function names, and implementation patterns
|
|
79036
|
+
- Dependencies, imports, and integration points
|
|
79037
|
+
- Technical constraints and requirements
|
|
79038
|
+
|
|
79039
|
+
**What NOT to Include**:
|
|
79040
|
+
- Future enhancements beyond current scope
|
|
79041
|
+
- Manual test plans or validation checklists
|
|
79042
|
+
- Meta-information about priorities
|
|
79043
|
+
|
|
79044
|
+
|
|
79045
|
+
|
|
79046
|
+
## Branch Naming Conventions
|
|
79047
|
+
|
|
79048
|
+
Branch names should:
|
|
79049
|
+
- Use kebab-case (lowercase with hyphens)
|
|
79050
|
+
- Start with a prefix: feat/, fix/, refactor/, docs/, test/, chore/
|
|
79051
|
+
- Be descriptive but concise (2-4 words typically)
|
|
79052
|
+
- Describe what is being changed, not who or why
|
|
79053
|
+
|
|
79054
|
+
## Decision Logic
|
|
79055
|
+
|
|
79056
|
+
1. **Analyze the request**: Review the task and any existing plan
|
|
79057
|
+
2. **If requirements are clear**:
|
|
79058
|
+
- Explore the codebase to understand patterns and conventions
|
|
79059
|
+
- Create an epic-scale plan with checkbox format and implementation-ready task details
|
|
79060
|
+
- Ensure each task includes specific file paths, function names, patterns, and technical details
|
|
79061
|
+
- Propose a suitable git branch name (see conventions below)
|
|
79062
|
+
3. **If requirements are unclear**:
|
|
79063
|
+
- Ask a clarifying question with optional default answer
|
|
79064
|
+
4. **If no action is needed**:
|
|
79065
|
+
- Provide reason (e.g., already implemented, not applicable)
|
|
79066
|
+
|
|
79067
|
+
## Response Format
|
|
79068
|
+
|
|
79069
|
+
${createJsonResponseInstruction({
|
|
79070
|
+
type: "'plan-generated' | 'question' | 'error'",
|
|
79071
|
+
plan: "The epic plan with checkbox format (required when type='plan-generated')",
|
|
79072
|
+
branchName: "Git branch name with valid prefix (required when type='plan-generated')",
|
|
79073
|
+
question: {
|
|
79074
|
+
question: "The clarifying question to ask",
|
|
79075
|
+
defaultAnswer: "Optional default answer"
|
|
79076
|
+
},
|
|
79077
|
+
reason: "Why no plan is needed (required when type='error')"
|
|
79078
|
+
})}
|
|
79079
|
+
|
|
79080
|
+
**Response Type Details:**
|
|
79081
|
+
|
|
79082
|
+
1. **plan-generated**: When you create or update an epic plan
|
|
79083
|
+
- Include complete plan with checkbox format
|
|
79084
|
+
- Provide branch name with valid prefix (feat/, fix/, refactor/, docs/, test/, chore/)
|
|
79085
|
+
|
|
79086
|
+
2. **question**: When you need clarification
|
|
79087
|
+
- Ask specific, unambiguous question
|
|
79088
|
+
- Optionally provide default answer
|
|
79089
|
+
|
|
79090
|
+
3. **error**: When no action is needed
|
|
79091
|
+
- Explain why (e.g., already implemented, not applicable)
|
|
79092
|
+
`;
|
|
79093
|
+
var BRANCH_NAME_PATTERN = /^[a-zA-Z0-9/_-]+$/;
|
|
79094
|
+
var EpicPlanSchema = exports_external.object({
|
|
79095
|
+
type: exports_external.enum(["plan-generated", "question", "error"]),
|
|
79096
|
+
plan: exports_external.string().nullish(),
|
|
79097
|
+
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), {
|
|
79098
|
+
message: "Invalid branch name format. Branch names should contain only letters, numbers, hyphens, underscores, and forward slashes."
|
|
79099
|
+
}).nullish(),
|
|
79100
|
+
question: exports_external.object({
|
|
79101
|
+
question: exports_external.string(),
|
|
79102
|
+
defaultAnswer: exports_external.string().nullish()
|
|
79103
|
+
}).nullish(),
|
|
79104
|
+
reason: exports_external.string().nullish()
|
|
79105
|
+
}).superRefine((data, ctx) => {
|
|
79106
|
+
switch (data.type) {
|
|
79107
|
+
case "plan-generated": {
|
|
79108
|
+
if (!data.plan || data.plan.trim() === "") {
|
|
79109
|
+
ctx.addIssue({
|
|
79110
|
+
code: "custom",
|
|
79111
|
+
message: 'Plan is required when type is "plan-generated".',
|
|
79112
|
+
path: ["plan"]
|
|
79113
|
+
});
|
|
79114
|
+
}
|
|
79115
|
+
if (!data.branchName || data.branchName.trim() === "") {
|
|
79116
|
+
ctx.addIssue({
|
|
79117
|
+
code: "custom",
|
|
79118
|
+
message: 'Branch name is required when type is "plan-generated".',
|
|
79119
|
+
path: ["branchName"]
|
|
79120
|
+
});
|
|
79121
|
+
}
|
|
79122
|
+
break;
|
|
79123
|
+
}
|
|
79124
|
+
case "question": {
|
|
79125
|
+
if (!data.question) {
|
|
79126
|
+
ctx.addIssue({
|
|
79127
|
+
code: "custom",
|
|
79128
|
+
message: 'Question is required when type is "question".',
|
|
79129
|
+
path: ["question"]
|
|
79130
|
+
});
|
|
79131
|
+
}
|
|
79132
|
+
break;
|
|
79133
|
+
}
|
|
79134
|
+
case "error": {
|
|
79135
|
+
if (!data.reason || data.reason.trim() === "") {
|
|
79136
|
+
ctx.addIssue({
|
|
79137
|
+
code: "custom",
|
|
79138
|
+
message: 'Reason is required when type is "error".',
|
|
79139
|
+
path: ["reason"]
|
|
79140
|
+
});
|
|
79141
|
+
}
|
|
79142
|
+
break;
|
|
79143
|
+
}
|
|
79144
|
+
}
|
|
79145
|
+
});
|
|
79146
|
+
var EPIC_ADD_TODO_ITEMS_SYSTEM_PROMPT = `Role: Task extraction agent
|
|
79147
|
+
Goal: Parse an epic plan and create structured todo items from task breakdowns.
|
|
79148
|
+
|
|
79149
|
+
${TOOL_USAGE_INSTRUCTION}
|
|
79150
|
+
|
|
79151
|
+
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.
|
|
79152
|
+
|
|
79153
|
+
## Expected Plan Format
|
|
79154
|
+
|
|
79155
|
+
The plan you receive follows a specific structure:
|
|
79156
|
+
- **Markdown checkboxes** (\`- [ ] item\`) indicate tasks
|
|
79157
|
+
- **Nesting** (indentation) indicates hierarchy: Phase > Task > Sub-task
|
|
79158
|
+
- **Implementation details** are included in each checkbox item
|
|
79159
|
+
- **Max 3 levels** of nesting
|
|
79160
|
+
|
|
79161
|
+
**Example plan structure:**
|
|
79162
|
+
\`\`\`
|
|
79163
|
+
1. Phase 1: Backend API
|
|
79164
|
+
- [ ] Implement authentication endpoints in \`src/api/auth.ts\` with \`POST /api/auth/login\`...
|
|
79165
|
+
- [ ] Create \`POST /api/auth/login\` endpoint that validates credentials...
|
|
79166
|
+
- [ ] Create \`POST /api/auth/register\` endpoint that validates input...
|
|
79167
|
+
- [ ] Create authentication middleware in \`src/middleware/auth.ts\`...
|
|
79168
|
+
\`\`\`
|
|
79169
|
+
|
|
79170
|
+
**Parsing rules:**
|
|
79171
|
+
- Lines with \`- [ ]\` are tasks to extract
|
|
79172
|
+
- Indentation level indicates parent-child relationships
|
|
79173
|
+
- Text after checkbox is the task title
|
|
79174
|
+
- Nested content provides additional context
|
|
79175
|
+
|
|
79176
|
+
## Your Role: Extract and Structure Tasks
|
|
79177
|
+
|
|
79178
|
+
Your job is to **extract and structure** tasks from the plan, not to explore or research:
|
|
79179
|
+
- Parse the checkbox structure to identify tasks
|
|
79180
|
+
- Extract implementation details already in the plan
|
|
79181
|
+
- Create todo items that preserve the plan's hierarchy
|
|
79182
|
+
- Do NOT explore the codebase - all information is in the plan
|
|
79183
|
+
|
|
79184
|
+
## Todo Item Creation Rules
|
|
79185
|
+
|
|
79186
|
+
For each checkbox in the plan, create a todo item using \`updateTodoItem\`:
|
|
79187
|
+
|
|
79188
|
+
### 1. **title** (required)
|
|
79189
|
+
Extract the checkbox text as the task title (max 60 characters, concise and action-oriented).
|
|
79190
|
+
|
|
79191
|
+
**Examples:**
|
|
79192
|
+
- Plan: \`- [ ] Implement authentication endpoints in \`src/api/auth.ts\`...\`
|
|
79193
|
+
- Title: "Implement authentication endpoints in src/api/auth.ts"
|
|
79194
|
+
|
|
79195
|
+
### 2. **description** (required)
|
|
79196
|
+
Extract and organize implementation details from the plan:
|
|
79197
|
+
|
|
79198
|
+
**Extract from the plan:**
|
|
79199
|
+
- **File paths**: All backtick-wrapped paths (e.g., \`src/api/auth.ts\`)
|
|
79200
|
+
- **Function/class names**: Code-formatted identifiers with parentheses (e.g., \`authenticateUser()\`)
|
|
79201
|
+
- **Dependencies**: "import X", "use Y library" mentions
|
|
79202
|
+
- **Patterns**: "Follow pattern in...", "Similar to..." references
|
|
79203
|
+
- **Technical specs**: All implementation guidance from the checkbox and nested content
|
|
79204
|
+
|
|
79205
|
+
**Example extraction:**
|
|
79206
|
+
|
|
79207
|
+
Plan:
|
|
79208
|
+
\`\`\`
|
|
79209
|
+
- [ ] Implement authentication endpoints in \`src/api/auth.ts\` with \`POST /api/auth/login\` that validates credentials using bcrypt and returns JWT tokens
|
|
79210
|
+
- [ ] Create \`POST /api/auth/login\` endpoint that accepts email/password in request body
|
|
79211
|
+
\`\`\`
|
|
79212
|
+
|
|
79213
|
+
Title: "Implement authentication endpoints in src/api/auth.ts"
|
|
79214
|
+
|
|
79215
|
+
Description:
|
|
79216
|
+
\`\`\`
|
|
79217
|
+
Create authentication endpoints in \`src/api/auth.ts\`:
|
|
79218
|
+
|
|
79219
|
+
**Main endpoint:**
|
|
79220
|
+
- \`POST /api/auth/login\` that validates credentials using bcrypt and returns JWT tokens
|
|
79221
|
+
|
|
79222
|
+
**Sub-tasks:**
|
|
79223
|
+
- Create \`POST /api/auth/login\` endpoint that accepts email/password in request body
|
|
79224
|
+
\`\`\`
|
|
79225
|
+
|
|
79226
|
+
|
|
79227
|
+
## Process
|
|
79228
|
+
|
|
79229
|
+
1. Parse the plan to identify all checkbox items
|
|
79230
|
+
2. For each checkbox:
|
|
79231
|
+
a. Extract title from checkbox text (keep concise)
|
|
79232
|
+
b. Extract description from checkbox content and nested items
|
|
79233
|
+
c. Identify parent-child relationships from indentation
|
|
79234
|
+
d. Extract file paths, functions, dependencies, patterns
|
|
79235
|
+
|
|
79236
|
+
**Remember:** Your role is extraction and organization, not exploration or planning.
|
|
79237
|
+
`;
|
|
79238
|
+
// src/workflows/prompts/fix.ts
|
|
79399
79239
|
var FIX_SYSTEM_PROMPT = `Role: Expert software developer.
|
|
79400
79240
|
Goal: Fix a failing command by analyzing the error and modifying the code.
|
|
79401
79241
|
|
|
@@ -79439,6 +79279,289 @@ ${stderr || "(empty)"}
|
|
|
79439
79279
|
</stderr>
|
|
79440
79280
|
`;
|
|
79441
79281
|
}
|
|
79282
|
+
// src/workflows/prompts/init.ts
|
|
79283
|
+
var INIT_WORKFLOW_ANALYZE_SYSTEM_PROMPT = `
|
|
79284
|
+
Role: Analyzer agent
|
|
79285
|
+
Goal: Produce a valid polkacodes YAML configuration for the project.
|
|
79286
|
+
|
|
79287
|
+
${TOOL_USAGE_INSTRUCTION}
|
|
79288
|
+
|
|
79289
|
+
Workflow
|
|
79290
|
+
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.
|
|
79291
|
+
- Package/build tool (npm, bun, pnpm, etc.)
|
|
79292
|
+
- Test framework and patterns (snapshot tests, coverage, etc.)
|
|
79293
|
+
- Formatter / linter and their rules
|
|
79294
|
+
- Folder structure and naming conventions.
|
|
79295
|
+
- CI / development workflows (e.g., GitHub Actions in .github/workflows).
|
|
79296
|
+
|
|
79297
|
+
2. Build a YAML config with three root keys:
|
|
79298
|
+
|
|
79299
|
+
\`\`\`yaml
|
|
79300
|
+
scripts: # derive from package.json and CI workflows. Only include scripts that are relevant for development.
|
|
79301
|
+
format: # code formatter
|
|
79302
|
+
command: "<formatter cmd>"
|
|
79303
|
+
description: "Format code"
|
|
79304
|
+
check: # linter / type checker
|
|
79305
|
+
command: "<linter cmd>"
|
|
79306
|
+
description: "Static checks"
|
|
79307
|
+
test: # test runner
|
|
79308
|
+
command: "<test cmd>"
|
|
79309
|
+
description: "Run tests"
|
|
79310
|
+
# add any other meaningful project scripts like 'build', 'dev', etc.
|
|
79311
|
+
|
|
79312
|
+
rules: # A bullet list of key conventions, frameworks, and libraries used (e.g., "- React", "- TypeScript", "- Jest"). This helps other agents understand the project.
|
|
79313
|
+
|
|
79314
|
+
excludeFiles: # A list of glob patterns for files that should not be read. Only include files that might contain secrets.
|
|
79315
|
+
- ".env"
|
|
79316
|
+
- ".env.*"
|
|
79317
|
+
- "*.pem"
|
|
79318
|
+
- "*.key"
|
|
79319
|
+
- ".npmrc"
|
|
79320
|
+
# do NOT list build artifacts, lockfiles, or paths already in .gitignore
|
|
79321
|
+
\`\`\`
|
|
79322
|
+
|
|
79323
|
+
3. Return a JSON object with the generated YAML configuration as a string in the 'yaml' property.
|
|
79324
|
+
|
|
79325
|
+
${createJsonResponseInstruction({
|
|
79326
|
+
yaml: "<yaml_string>"
|
|
79327
|
+
})}
|
|
79328
|
+
`;
|
|
79329
|
+
// src/workflows/prompts/meta.ts
|
|
79330
|
+
var META_SYSTEM_PROMPT = `Role: Meta-agent.
|
|
79331
|
+
Goal: Decide which workflow ('code', 'task', or 'epic') to use for a given task.
|
|
79332
|
+
|
|
79333
|
+
You are a meta-agent that decides which workflow to use for a given task.
|
|
79334
|
+
Based on the user's task, decide whether to use the 'code', 'task', or 'epic' workflow.
|
|
79335
|
+
|
|
79336
|
+
- Use the 'code' workflow for tasks that are well-defined and can be implemented directly without a separate planning phase.
|
|
79337
|
+
- Use the 'task' workflow for simple, single-action tasks like answering a question or running a command.
|
|
79338
|
+
- 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.
|
|
79339
|
+
|
|
79340
|
+
The user's task is provided in the <task> tag.
|
|
79341
|
+
|
|
79342
|
+
${createJsonResponseInstruction({
|
|
79343
|
+
workflow: "<workflow_name>"
|
|
79344
|
+
})}
|
|
79345
|
+
`;
|
|
79346
|
+
// src/workflows/prompts/plan.ts
|
|
79347
|
+
function getPlanPrompt(task, planContent) {
|
|
79348
|
+
const planSection = planContent ? `
|
|
79349
|
+
The content of an existing plan file:
|
|
79350
|
+
<plan_file>
|
|
79351
|
+
${planContent}
|
|
79352
|
+
</plan_file>
|
|
79353
|
+
` : "";
|
|
79354
|
+
return `# Task Input
|
|
79355
|
+
|
|
79356
|
+
The user has provided a task:
|
|
79357
|
+
<task>
|
|
79358
|
+
${task}
|
|
79359
|
+
</task>
|
|
79360
|
+
${planSection}`;
|
|
79361
|
+
}
|
|
79362
|
+
// src/workflows/prompts/planner.ts
|
|
79363
|
+
var PLANNER_SYSTEM_PROMPT = `Role: Expert software architect and planner.
|
|
79364
|
+
Goal: Analyze user requests and create detailed, actionable implementation plans for software development tasks.
|
|
79365
|
+
|
|
79366
|
+
You are an expert software architect and planner with deep experience in breaking down complex requirements into actionable implementation plans.
|
|
79367
|
+
|
|
79368
|
+
${MEMORY_USAGE_SECTION}
|
|
79369
|
+
|
|
79370
|
+
${TOOL_USAGE_INSTRUCTION}
|
|
79371
|
+
|
|
79372
|
+
## Your Role
|
|
79373
|
+
|
|
79374
|
+
As a planner, your expertise lies in:
|
|
79375
|
+
- Analyzing requirements to understand the core objective and technical implications
|
|
79376
|
+
- Exploring codebases to identify patterns, conventions, and integration points
|
|
79377
|
+
- Breaking down complex tasks into clear, logical sequences of steps
|
|
79378
|
+
- Anticipating dependencies, edge cases, and potential challenges
|
|
79379
|
+
- Creating plans that can be executed autonomously by an AI coding agent
|
|
79380
|
+
- Providing technical specificity required for autonomous implementation
|
|
79381
|
+
|
|
79382
|
+
## Planning Philosophy
|
|
79383
|
+
|
|
79384
|
+
Effective planning requires understanding before action:
|
|
79385
|
+
|
|
79386
|
+
1. **Explore First, Plan Second**
|
|
79387
|
+
- Never plan in a vacuum. Use available tools to understand the existing codebase
|
|
79388
|
+
- Identify similar implementations, patterns, and conventions already in use
|
|
79389
|
+
- Understand the project structure, naming conventions, and architectural patterns
|
|
79390
|
+
- Look at tests to understand expected behavior and testing approaches
|
|
79391
|
+
|
|
79392
|
+
2. **Context is Critical**
|
|
79393
|
+
- The best plans are informed by the actual state of the codebase
|
|
79394
|
+
- File system exploration (\`listFiles\`, \`searchFiles\`) reveals structure and patterns
|
|
79395
|
+
- Reading existing files (\`readFile\`) shows coding style and conventions
|
|
79396
|
+
- Understanding context prevents suggesting solutions that don't fit the project
|
|
79397
|
+
|
|
79398
|
+
3. **Specificity Over Generality**
|
|
79399
|
+
- Vague plans lead to implementation confusion and prevent autonomous execution
|
|
79400
|
+
- Instead of "implement the feature," specify which files to modify, what functions to add, and what logic to implement
|
|
79401
|
+
- Name specific components, modules, or files when possible
|
|
79402
|
+
- Describe what needs to change and why
|
|
79403
|
+
- Examples:
|
|
79404
|
+
* ❌ Vague: "Implement the feature"
|
|
79405
|
+
* ✅ 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\`"
|
|
79406
|
+
* ❌ Vague: "Add error handling"
|
|
79407
|
+
* ✅ 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\`"
|
|
79408
|
+
|
|
79409
|
+
4. **Clarity for AI Coding Agents**
|
|
79410
|
+
- Plans will be executed autonomously by an AI coding agent without human intervention
|
|
79411
|
+
- Break complex tasks into smaller, logical units that can be completed independently
|
|
79412
|
+
- Use clear structure (numbered lists, narrative text, or combined formats) to organize steps
|
|
79413
|
+
- Include exact file paths, function names, and implementation patterns
|
|
79414
|
+
|
|
79415
|
+
## Planning for AI Implementation
|
|
79416
|
+
|
|
79417
|
+
Plans will be executed by an AI coding agent that operates autonomously with the following capabilities:
|
|
79418
|
+
|
|
79419
|
+
**Planning Requirements:**
|
|
79420
|
+
Plans should include specific technical details to enable autonomous implementation:
|
|
79421
|
+
- **Function/class names**: Name specific functions, classes, or components to implement
|
|
79422
|
+
- **Implementation patterns**: Reference existing patterns or provide clear guidance on approach
|
|
79423
|
+
- **Import statements**: Specify required dependencies and where to import them from
|
|
79424
|
+
- **Technical constraints**: Note any architectural decisions, performance requirements, or compatibility concerns
|
|
79425
|
+
|
|
79426
|
+
**What Makes a Good AI-Actionable Plan:**
|
|
79427
|
+
- Each step can be completed using the available tools
|
|
79428
|
+
- File paths and code structures are explicitly named
|
|
79429
|
+
- Dependencies between steps are clear
|
|
79430
|
+
- Implementation approach follows existing codebase patterns
|
|
79431
|
+
- Technical requirements are specific, not general
|
|
79432
|
+
|
|
79433
|
+
## Your Approach
|
|
79434
|
+
|
|
79435
|
+
When given a planning task:
|
|
79436
|
+
|
|
79437
|
+
1. **Understand the Goal**: Analyze the request thoroughly to grasp the primary objective and any constraints
|
|
79438
|
+
2. **Gather Context**: Explore the codebase using available tools to understand existing patterns and structure
|
|
79439
|
+
3. **Identify Patterns**: Look for similar implementations that can guide the approach
|
|
79440
|
+
4. **Break Down the Work**: Decompose the solution into logical, sequential steps
|
|
79441
|
+
5. **Be Specific**: Provide concrete details about files, functions, and implementations
|
|
79442
|
+
6. **Seek Clarity**: If requirements are ambiguous or critical information is missing, ask for clarification
|
|
79443
|
+
|
|
79444
|
+
## Tool Usage Strategy
|
|
79445
|
+
|
|
79446
|
+
Use exploration tools strategically:
|
|
79447
|
+
- \`listFiles\`: Understand project structure and locate relevant directories
|
|
79448
|
+
- \`searchFiles\`: Find existing patterns, similar implementations, or specific code
|
|
79449
|
+
- \`readFile\`: Examine existing code to understand style, patterns, and conventions
|
|
79450
|
+
- \`fetchUrl\`: Access external documentation or resources when needed
|
|
79451
|
+
- \`askFollowupQuestion\`: Request clarification when requirements are unclear or ambiguous
|
|
79452
|
+
|
|
79453
|
+
The goal is to create well-informed plans based on actual codebase understanding, not assumptions.
|
|
79454
|
+
|
|
79455
|
+
## Plan Format Guidelines
|
|
79456
|
+
|
|
79457
|
+
When generating your plan, follow these formatting guidelines:
|
|
79458
|
+
|
|
79459
|
+
1. Number major sections to provide clear structure:
|
|
79460
|
+
a. Use numbers (1., 2., 3., etc.) for top-level sections
|
|
79461
|
+
b. Use nested numbering (1.1, 1.2) or letters (a., b., c.) for sub-sections
|
|
79462
|
+
c. This makes sections easy to reference and understand
|
|
79463
|
+
d. Provides clear hierarchy and organization
|
|
79464
|
+
|
|
79465
|
+
Example section numbering:
|
|
79466
|
+
1. Project Setup
|
|
79467
|
+
1.1 Initialize repository
|
|
79468
|
+
1.2 Configure dependencies
|
|
79469
|
+
2. Implementation
|
|
79470
|
+
2.1 Core features
|
|
79471
|
+
2.2 Tests
|
|
79472
|
+
|
|
79473
|
+
2. Use numbered lists when the order of steps matters:
|
|
79474
|
+
a. Sequential steps where one depends on the previous
|
|
79475
|
+
b. Steps that must be performed in a specific order
|
|
79476
|
+
c. Processes with clear progression
|
|
79477
|
+
d. When steps need to be referenced by number
|
|
79478
|
+
|
|
79479
|
+
Example numbered list format:
|
|
79480
|
+
1. First step that must be completed first
|
|
79481
|
+
2. Second step that depends on the first
|
|
79482
|
+
3. Third step that follows from the second
|
|
79483
|
+
|
|
79484
|
+
3. Use narrative or structured text format when the plan involves:
|
|
79485
|
+
a. High-level strategies or conceptual approaches
|
|
79486
|
+
b. Explanations or background information
|
|
79487
|
+
c. Decision-making guidance
|
|
79488
|
+
d. Context that doesn't translate well to discrete steps
|
|
79489
|
+
|
|
79490
|
+
4. Combine formats when appropriate:
|
|
79491
|
+
a. Use numbered sections for overall structure
|
|
79492
|
+
b. Use narrative text for context and explanation
|
|
79493
|
+
c. Use numbered lists for sequential steps
|
|
79494
|
+
|
|
79495
|
+
Example combined format:
|
|
79496
|
+
1. Phase 1: Setup
|
|
79497
|
+
First, we need to configure the environment...
|
|
79498
|
+
1. Install dependencies
|
|
79499
|
+
2. Configure settings
|
|
79500
|
+
3. Verify installation
|
|
79501
|
+
|
|
79502
|
+
2. Phase 2: Implementation
|
|
79503
|
+
The implementation should focus on...
|
|
79504
|
+
1. Implement feature A
|
|
79505
|
+
2. Implement feature B
|
|
79506
|
+
3. Write tests
|
|
79507
|
+
|
|
79508
|
+
5. Include implementation-ready details for AI agents:
|
|
79509
|
+
a. Provide specific technical details the coding agent needs (file paths, function signatures, etc.)
|
|
79510
|
+
b. Avoid steps that require human intervention or manual processes
|
|
79511
|
+
c. Each step should be implementable using the AI agent's available tools
|
|
79512
|
+
d. Reference existing code patterns and conventions from the codebase
|
|
79513
|
+
|
|
79514
|
+
**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.
|
|
79515
|
+
|
|
79516
|
+
## Decision Logic
|
|
79517
|
+
|
|
79518
|
+
1. Analyze the task and the existing plan (if any).
|
|
79519
|
+
2. If the requirements are clear and you can generate or update the plan:
|
|
79520
|
+
a. Provide the plan in the "plan" field
|
|
79521
|
+
b. Apply appropriate formatting based on guidelines above
|
|
79522
|
+
c. Include relevant file paths in the "files" array if applicable
|
|
79523
|
+
3. If the requirements are not clear:
|
|
79524
|
+
a. Ask a clarifying question in the "question" field
|
|
79525
|
+
4. If the task is already implemented or no action is needed:
|
|
79526
|
+
a. Do not generate a plan
|
|
79527
|
+
b. Provide a concise reason in the "reason" field
|
|
79528
|
+
|
|
79529
|
+
## Response Format
|
|
79530
|
+
|
|
79531
|
+
${createJsonResponseInstruction({
|
|
79532
|
+
plan: "The generated or updated plan.",
|
|
79533
|
+
question: {
|
|
79534
|
+
question: "The clarifying question to ask the user.",
|
|
79535
|
+
defaultAnswer: "The default answer to provide if the user does not provide an answer."
|
|
79536
|
+
},
|
|
79537
|
+
reason: "If no plan is needed, provide a reason here.",
|
|
79538
|
+
files: ["path/to/file1.ts", "path/to/file2.ts"]
|
|
79539
|
+
})}
|
|
79540
|
+
`;
|
|
79541
|
+
var PlanSchema = exports_external.object({
|
|
79542
|
+
plan: exports_external.string().nullish(),
|
|
79543
|
+
question: exports_external.object({
|
|
79544
|
+
question: exports_external.string(),
|
|
79545
|
+
defaultAnswer: exports_external.string().nullish()
|
|
79546
|
+
}).nullish(),
|
|
79547
|
+
reason: exports_external.string().nullish(),
|
|
79548
|
+
files: exports_external.array(exports_external.string()).nullish()
|
|
79549
|
+
});
|
|
79550
|
+
// src/workflows/prompts/pr.ts
|
|
79551
|
+
var GET_PR_DETAILS_SYSTEM_PROMPT = `Role: Expert developer.
|
|
79552
|
+
Goal: Generate a pull request title and description based on the branch name, commits, and diff.
|
|
79553
|
+
|
|
79554
|
+
${TOOL_USAGE_INSTRUCTION}
|
|
79555
|
+
|
|
79556
|
+
You are an expert at creating pull requests.
|
|
79557
|
+
Based on the provided branch name, commit messages, and diff, generate a title and description for the pull request.
|
|
79558
|
+
|
|
79559
|
+
${createJsonResponseInstruction({
|
|
79560
|
+
title: "feat: add new feature",
|
|
79561
|
+
description: "This pull request adds a new feature that does...\\n\\n### Changes\\n- ..."
|
|
79562
|
+
})}
|
|
79563
|
+
`;
|
|
79564
|
+
// src/workflows/prompts/review.ts
|
|
79442
79565
|
var CODE_REVIEW_SYSTEM_PROMPT = `Role: Senior software engineer.
|
|
79443
79566
|
Goal: Review code changes and provide specific, actionable feedback on any issues found.
|
|
79444
79567
|
|
|
@@ -79555,96 +79678,6 @@ ${instructions}
|
|
|
79555
79678
|
return parts.join(`
|
|
79556
79679
|
`);
|
|
79557
79680
|
}
|
|
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
79681
|
// src/workflows/fix.workflow.ts
|
|
79649
79682
|
var FixIterationSummarySchema = exports_external.object({
|
|
79650
79683
|
summary: exports_external.string().nullish(),
|
|
@@ -79777,35 +79810,45 @@ ${memoryContext}`
|
|
|
79777
79810
|
// src/workflows/plan.workflow.ts
|
|
79778
79811
|
async function createPlan(input2, context) {
|
|
79779
79812
|
const { tools: tools2, step } = context;
|
|
79780
|
-
const { task, files, plan: inputPlan, userFeedback, interactive } = input2;
|
|
79781
|
-
const
|
|
79782
|
-
|
|
79783
|
-
|
|
79784
|
-
|
|
79785
|
-
|
|
79786
|
-
|
|
79787
|
-
|
|
79813
|
+
const { task, files, plan: inputPlan, userFeedback, interactive, messages } = input2;
|
|
79814
|
+
const getMessages = async () => {
|
|
79815
|
+
if (messages) {
|
|
79816
|
+
return {
|
|
79817
|
+
messages,
|
|
79818
|
+
userMessage: [{ role: "user", content: userFeedback ?? task }]
|
|
79819
|
+
};
|
|
79820
|
+
} else {
|
|
79821
|
+
const defaultContext = await getDefaultContext();
|
|
79822
|
+
const memoryContext = await tools2.getMemoryContext();
|
|
79823
|
+
const prompt = `${memoryContext}
|
|
79824
|
+
${getPlanPrompt(task, inputPlan)}
|
|
79788
79825
|
|
|
79789
79826
|
${defaultContext}`;
|
|
79790
|
-
|
|
79791
|
-
|
|
79792
|
-
|
|
79793
|
-
|
|
79794
|
-
|
|
79795
|
-
|
|
79796
|
-
|
|
79797
|
-
|
|
79798
|
-
|
|
79799
|
-
|
|
79800
|
-
|
|
79801
|
-
|
|
79802
|
-
|
|
79803
|
-
|
|
79804
|
-
|
|
79805
|
-
|
|
79827
|
+
const userContent = [{ type: "text", text: prompt }];
|
|
79828
|
+
if (files) {
|
|
79829
|
+
for (const file2 of files) {
|
|
79830
|
+
if (file2.type === "file") {
|
|
79831
|
+
userContent.push({
|
|
79832
|
+
type: "file",
|
|
79833
|
+
mediaType: file2.mediaType,
|
|
79834
|
+
filename: file2.filename,
|
|
79835
|
+
data: { type: "base64", value: file2.data }
|
|
79836
|
+
});
|
|
79837
|
+
} else if (file2.type === "image") {
|
|
79838
|
+
userContent.push({
|
|
79839
|
+
type: "image",
|
|
79840
|
+
mediaType: file2.mediaType,
|
|
79841
|
+
image: { type: "base64", value: file2.image }
|
|
79842
|
+
});
|
|
79843
|
+
}
|
|
79844
|
+
}
|
|
79806
79845
|
}
|
|
79846
|
+
return {
|
|
79847
|
+
systemPrompt: PLANNER_SYSTEM_PROMPT,
|
|
79848
|
+
userMessage: [{ role: "user", content: userContent }]
|
|
79849
|
+
};
|
|
79807
79850
|
}
|
|
79808
|
-
}
|
|
79851
|
+
};
|
|
79809
79852
|
const agentTools = [
|
|
79810
79853
|
readFile_default,
|
|
79811
79854
|
listFiles_default,
|
|
@@ -79819,21 +79862,21 @@ ${defaultContext}`;
|
|
|
79819
79862
|
if (interactive) {
|
|
79820
79863
|
agentTools.push(askFollowupQuestion_default);
|
|
79821
79864
|
}
|
|
79865
|
+
const inputMessages = await getMessages();
|
|
79822
79866
|
const result = await step("plan", async () => {
|
|
79823
79867
|
return await agentWorkflow({
|
|
79824
|
-
|
|
79825
|
-
userMessage: [{ role: "user", content: userContent }],
|
|
79868
|
+
...inputMessages,
|
|
79826
79869
|
tools: agentTools,
|
|
79827
79870
|
outputSchema: PlanSchema
|
|
79828
79871
|
}, context);
|
|
79829
79872
|
});
|
|
79830
79873
|
if (result.type === "Exit" && result.object) {
|
|
79831
|
-
const { plan, question, reason, files: filePaths } = result.object;
|
|
79874
|
+
const { plan: plan2, question, reason, files: filePaths } = result.object;
|
|
79832
79875
|
if (reason) {
|
|
79833
|
-
return { reason };
|
|
79876
|
+
return { reason, messages: result.messages };
|
|
79834
79877
|
}
|
|
79835
79878
|
if (question) {
|
|
79836
|
-
return { plan:
|
|
79879
|
+
return { plan: plan2 || inputPlan, question, messages: result.messages };
|
|
79837
79880
|
}
|
|
79838
79881
|
const outputFiles = [];
|
|
79839
79882
|
if (filePaths) {
|
|
@@ -79844,7 +79887,7 @@ ${defaultContext}`;
|
|
|
79844
79887
|
}
|
|
79845
79888
|
}
|
|
79846
79889
|
}
|
|
79847
|
-
return { plan:
|
|
79890
|
+
return { plan: plan2 || undefined, files: outputFiles, messages: result.messages };
|
|
79848
79891
|
}
|
|
79849
79892
|
context.logger.warn("Failed to generate plan.", result);
|
|
79850
79893
|
throw new Error("Failed to generate plan.");
|
|
@@ -79853,9 +79896,10 @@ var planWorkflow = async (input2, context) => {
|
|
|
79853
79896
|
const { tools: tools2, logger, step } = context;
|
|
79854
79897
|
const { fileContent, filePath, mode = "interactive" } = input2;
|
|
79855
79898
|
let currentTask = input2.task;
|
|
79856
|
-
let
|
|
79899
|
+
let plan2 = fileContent || "";
|
|
79857
79900
|
let files = [];
|
|
79858
|
-
let userFeedback
|
|
79901
|
+
let userFeedback;
|
|
79902
|
+
let messages;
|
|
79859
79903
|
let state = "Generating";
|
|
79860
79904
|
let count = 0;
|
|
79861
79905
|
while (state !== "Done") {
|
|
@@ -79863,8 +79907,8 @@ var planWorkflow = async (input2, context) => {
|
|
|
79863
79907
|
switch (state) {
|
|
79864
79908
|
case "Generating": {
|
|
79865
79909
|
if (!currentTask) {
|
|
79866
|
-
const message =
|
|
79867
|
-
const defaultTask =
|
|
79910
|
+
const message = plan2 ? "How would you like to improve the plan?" : "What is the task you want to plan?";
|
|
79911
|
+
const defaultTask = plan2 ? "Review and improve the plan" : undefined;
|
|
79868
79912
|
try {
|
|
79869
79913
|
currentTask = await tools2.input({
|
|
79870
79914
|
message,
|
|
@@ -79876,11 +79920,13 @@ var planWorkflow = async (input2, context) => {
|
|
|
79876
79920
|
}
|
|
79877
79921
|
const planResult = await createPlan({
|
|
79878
79922
|
task: currentTask,
|
|
79879
|
-
plan,
|
|
79923
|
+
plan: plan2,
|
|
79880
79924
|
userFeedback,
|
|
79881
79925
|
files: input2.files,
|
|
79882
|
-
interactive: mode === "interactive" || mode === "confirm"
|
|
79926
|
+
interactive: mode === "interactive" || mode === "confirm",
|
|
79927
|
+
messages
|
|
79883
79928
|
}, context);
|
|
79929
|
+
messages = planResult.messages;
|
|
79884
79930
|
if (planResult.reason) {
|
|
79885
79931
|
logger.info(planResult.reason);
|
|
79886
79932
|
return "Done";
|
|
@@ -79891,7 +79937,7 @@ var planWorkflow = async (input2, context) => {
|
|
|
79891
79937
|
message: planResult.question.question,
|
|
79892
79938
|
default: planResult.question.defaultAnswer || undefined
|
|
79893
79939
|
});
|
|
79894
|
-
|
|
79940
|
+
plan2 = planResult.plan || plan2;
|
|
79895
79941
|
return "Generating";
|
|
79896
79942
|
} catch (error46) {
|
|
79897
79943
|
if (error46 instanceof UserCancelledError) {
|
|
@@ -79900,7 +79946,7 @@ var planWorkflow = async (input2, context) => {
|
|
|
79900
79946
|
return "Done";
|
|
79901
79947
|
}
|
|
79902
79948
|
}
|
|
79903
|
-
|
|
79949
|
+
plan2 = planResult.plan || "";
|
|
79904
79950
|
files = planResult.files || [];
|
|
79905
79951
|
userFeedback = "";
|
|
79906
79952
|
return "Reviewing";
|
|
@@ -79909,7 +79955,7 @@ var planWorkflow = async (input2, context) => {
|
|
|
79909
79955
|
logger.info(`
|
|
79910
79956
|
Generated Plan:
|
|
79911
79957
|
`);
|
|
79912
|
-
logger.info(
|
|
79958
|
+
logger.info(plan2);
|
|
79913
79959
|
if (files?.length > 0) {
|
|
79914
79960
|
logger.info(`
|
|
79915
79961
|
Files:`);
|
|
@@ -79955,7 +80001,7 @@ Files:`);
|
|
|
79955
80001
|
message: "Where do you want to save the plan?",
|
|
79956
80002
|
default: defaultPath
|
|
79957
80003
|
});
|
|
79958
|
-
await tools2.writeToFile({ path: savePath, content:
|
|
80004
|
+
await tools2.writeToFile({ path: savePath, content: plan2 });
|
|
79959
80005
|
logger.info(`Plan saved to ${savePath}`);
|
|
79960
80006
|
return "Done";
|
|
79961
80007
|
}
|
|
@@ -79971,8 +80017,9 @@ Files:`);
|
|
|
79971
80017
|
}
|
|
79972
80018
|
}
|
|
79973
80019
|
case "regenerate": {
|
|
79974
|
-
|
|
80020
|
+
plan2 = "";
|
|
79975
80021
|
userFeedback = "";
|
|
80022
|
+
messages = undefined;
|
|
79976
80023
|
return "Generating";
|
|
79977
80024
|
}
|
|
79978
80025
|
case "exit": {
|
|
@@ -79987,7 +80034,7 @@ Files:`);
|
|
|
79987
80034
|
}
|
|
79988
80035
|
});
|
|
79989
80036
|
}
|
|
79990
|
-
return { plan, files };
|
|
80037
|
+
return { plan: plan2, files };
|
|
79991
80038
|
};
|
|
79992
80039
|
|
|
79993
80040
|
// src/workflows/code.workflow.ts
|
|
@@ -80011,11 +80058,11 @@ Phase 1: Creating implementation plan...
|
|
|
80011
80058
|
logger.info("Plan not approved. Exiting.");
|
|
80012
80059
|
return { success: false, reason: "Plan not approved", summaries };
|
|
80013
80060
|
}
|
|
80014
|
-
const { plan, files: planFiles } = planResult;
|
|
80061
|
+
const { plan: plan2, files: planFiles } = planResult;
|
|
80015
80062
|
logger.info(`
|
|
80016
80063
|
Phase 2: Implementing the plan...
|
|
80017
80064
|
`);
|
|
80018
|
-
let implementPrompt = getImplementPrompt(
|
|
80065
|
+
let implementPrompt = getImplementPrompt(plan2);
|
|
80019
80066
|
if (planFiles && planFiles.length > 0) {
|
|
80020
80067
|
const fileContentString = planFiles.map((f) => `<file path="${f.path}">${f.content}</file>`).join(`
|
|
80021
80068
|
`);
|
|
@@ -80540,8 +80587,35 @@ ${provider3.toUpperCase()}_API_KEY=${providerConfig.apiKey}`;
|
|
|
80540
80587
|
var MAX_REVIEW_RETRIES = 5;
|
|
80541
80588
|
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
80589
|
async function createPlan2(input2, context) {
|
|
80543
|
-
const { task, plan, files, feedback } = input2;
|
|
80544
|
-
const
|
|
80590
|
+
const { task, plan: plan2, files, feedback, messages } = input2;
|
|
80591
|
+
const { tools: tools2 } = context;
|
|
80592
|
+
const agentTools = [
|
|
80593
|
+
askFollowupQuestion_default,
|
|
80594
|
+
fetchUrl_default,
|
|
80595
|
+
listFiles_default,
|
|
80596
|
+
readFile_default,
|
|
80597
|
+
readBinaryFile_default,
|
|
80598
|
+
searchFiles_default,
|
|
80599
|
+
readMemory_default,
|
|
80600
|
+
updateMemory_default,
|
|
80601
|
+
listMemoryTopics_default
|
|
80602
|
+
];
|
|
80603
|
+
if (messages) {
|
|
80604
|
+
const userMessage2 = feedback ? [{ role: "user", content: feedback }] : [];
|
|
80605
|
+
return await agentWorkflow({
|
|
80606
|
+
messages,
|
|
80607
|
+
userMessage: userMessage2,
|
|
80608
|
+
tools: agentTools,
|
|
80609
|
+
outputSchema: EpicPlanSchema
|
|
80610
|
+
}, context);
|
|
80611
|
+
}
|
|
80612
|
+
const defaultContext = await getDefaultContext();
|
|
80613
|
+
const memoryContext = await tools2.getMemoryContext();
|
|
80614
|
+
const prompt = `${memoryContext}
|
|
80615
|
+
${getPlanPrompt(task, plan2)}
|
|
80616
|
+
|
|
80617
|
+
${defaultContext}`;
|
|
80618
|
+
const content = [{ type: "text", text: prompt }];
|
|
80545
80619
|
if (files) {
|
|
80546
80620
|
for (const file2 of files) {
|
|
80547
80621
|
if (file2.type === "file") {
|
|
@@ -80560,33 +80634,13 @@ async function createPlan2(input2, context) {
|
|
|
80560
80634
|
}
|
|
80561
80635
|
}
|
|
80562
80636
|
}
|
|
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({
|
|
80637
|
+
const userMessage = [{ role: "user", content }];
|
|
80638
|
+
return await agentWorkflow({
|
|
80571
80639
|
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
|
-
],
|
|
80640
|
+
userMessage,
|
|
80641
|
+
tools: agentTools,
|
|
80584
80642
|
outputSchema: EpicPlanSchema
|
|
80585
80643
|
}, context);
|
|
80586
|
-
if (planResult.type === "Exit") {
|
|
80587
|
-
return planResult.object;
|
|
80588
|
-
}
|
|
80589
|
-
return { type: "error", reason: "Usage limit exceeded." };
|
|
80590
80644
|
}
|
|
80591
80645
|
async function createAndApprovePlan(task, context) {
|
|
80592
80646
|
const { logger, step, tools: tools2 } = context;
|
|
@@ -80594,10 +80648,17 @@ async function createAndApprovePlan(task, context) {
|
|
|
80594
80648
|
`);
|
|
80595
80649
|
let feedback;
|
|
80596
80650
|
let planAttempt = 1;
|
|
80651
|
+
let messages;
|
|
80597
80652
|
try {
|
|
80598
80653
|
while (true) {
|
|
80599
|
-
const
|
|
80654
|
+
const planAgentResult = await step(`plan-${planAttempt}`, () => createPlan2({ task, feedback, messages }, context));
|
|
80655
|
+
messages = planAgentResult.messages;
|
|
80600
80656
|
planAttempt++;
|
|
80657
|
+
if (planAgentResult.type !== "Exit" /* Exit */) {
|
|
80658
|
+
logger.error(`Plan creation failed. Agent exited with status: ${planAgentResult.type}`);
|
|
80659
|
+
return null;
|
|
80660
|
+
}
|
|
80661
|
+
const result = planAgentResult.object;
|
|
80601
80662
|
switch (result.type) {
|
|
80602
80663
|
case "plan-generated": {
|
|
80603
80664
|
if (!result.plan || !result.branchName) {
|
|
@@ -80691,7 +80752,7 @@ async function createFeatureBranch(branchName, baseBranch, context) {
|
|
|
80691
80752
|
logger.error(`Error: Failed to create or switch to a feature branch after ${MAX_ATTEMPTS} attempts.`);
|
|
80692
80753
|
return { success: false, branchName: null };
|
|
80693
80754
|
}
|
|
80694
|
-
async function addTodoItemsFromPlan(
|
|
80755
|
+
async function addTodoItemsFromPlan(plan2, context) {
|
|
80695
80756
|
const { logger, step, tools: tools2 } = context;
|
|
80696
80757
|
logger.info(`Phase 4: Creating todo items from plan...
|
|
80697
80758
|
`);
|
|
@@ -80700,7 +80761,7 @@ async function addTodoItemsFromPlan(plan, context) {
|
|
|
80700
80761
|
systemPrompt: EPIC_ADD_TODO_ITEMS_SYSTEM_PROMPT,
|
|
80701
80762
|
userMessage: [{ role: "user", content: `Please create the todo items based on the plan
|
|
80702
80763
|
<plan>
|
|
80703
|
-
${
|
|
80764
|
+
${plan2}</plan>` }],
|
|
80704
80765
|
tools: [readFile_default, searchFiles_default, listFiles_default, readMemory_default, getTodoItem_default, listTodoItems_default, updateTodoItem_default, updateMemory_default, listMemoryTopics_default]
|
|
80705
80766
|
}, context);
|
|
80706
80767
|
});
|
|
@@ -80750,7 +80811,7 @@ async function performReviewAndFixCycle(iterationCount, taskItem, highLevelPlan,
|
|
|
80750
80811
|
const { logger, step, tools: tools2 } = context;
|
|
80751
80812
|
for (let i = 0;i < MAX_REVIEW_RETRIES; i++) {
|
|
80752
80813
|
const diffResult = await tools2.executeCommand({ command: "git", args: ["diff", "--name-status", "HEAD~1", "HEAD"] });
|
|
80753
|
-
const changedFiles = parseGitDiffNameStatus(diffResult.stdout);
|
|
80814
|
+
const changedFiles = parseGitDiffNameStatus(diffResult.stdout).filter(({ path }) => path !== ".epic.yml");
|
|
80754
80815
|
if (changedFiles.length === 0) {
|
|
80755
80816
|
logger.info(`No files were changed. Skipping review.
|
|
80756
80817
|
`);
|
|
@@ -80789,8 +80850,8 @@ ${formatReviewToolInput(changeInfo)}`;
|
|
|
80789
80850
|
}
|
|
80790
80851
|
logger.warn(`Warning: Review found ${reviewResult.specificReviews.length} issue(s). Attempting to fix...
|
|
80791
80852
|
`);
|
|
80792
|
-
for (const [idx,
|
|
80793
|
-
logger.warn(` ${idx + 1}. ${
|
|
80853
|
+
for (const [idx, review2] of reviewResult.specificReviews.entries()) {
|
|
80854
|
+
logger.warn(` ${idx + 1}. ${review2.file}:${review2.lines}`);
|
|
80794
80855
|
}
|
|
80795
80856
|
logger.warn("");
|
|
80796
80857
|
const reviewSummary = reviewResult.specificReviews.map((r) => `File: ${r.file} (lines: ${r.lines})
|
|
@@ -80828,6 +80889,20 @@ Max retries (${MAX_REVIEW_RETRIES}) reached. Moving to the next task, but issues
|
|
|
80828
80889
|
}
|
|
80829
80890
|
return { passed: false };
|
|
80830
80891
|
}
|
|
80892
|
+
async function findNextTask(tools2) {
|
|
80893
|
+
const openRootTasks = await tools2.listTodoItems({ status: "open" });
|
|
80894
|
+
if (openRootTasks.length === 0) {
|
|
80895
|
+
return null;
|
|
80896
|
+
}
|
|
80897
|
+
let currentTask = openRootTasks[0];
|
|
80898
|
+
while (true) {
|
|
80899
|
+
const subTasks = await tools2.listTodoItems({ status: "open", id: currentTask.id });
|
|
80900
|
+
if (subTasks.length === 0) {
|
|
80901
|
+
return currentTask;
|
|
80902
|
+
}
|
|
80903
|
+
currentTask = subTasks[0];
|
|
80904
|
+
}
|
|
80905
|
+
}
|
|
80831
80906
|
async function runImplementationLoop(context, highLevelPlan) {
|
|
80832
80907
|
const { logger, step, tools: tools2 } = context;
|
|
80833
80908
|
const commitMessages = [];
|
|
@@ -80836,22 +80911,11 @@ async function runImplementationLoop(context, highLevelPlan) {
|
|
|
80836
80911
|
logger.info(`${"=".repeat(80)}
|
|
80837
80912
|
`);
|
|
80838
80913
|
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) {
|
|
80914
|
+
let nextTaskItem = await step("get-initial-task", () => findNextTask(tools2));
|
|
80915
|
+
while (nextTaskItem) {
|
|
80853
80916
|
iterationCount++;
|
|
80854
80917
|
const taskStartTime = Date.now();
|
|
80918
|
+
const { title: nextTask, id: nextTaskId } = nextTaskItem;
|
|
80855
80919
|
logger.info(`
|
|
80856
80920
|
${"-".repeat(80)}`);
|
|
80857
80921
|
logger.info(`Iteration ${iterationCount}`);
|
|
@@ -80891,24 +80955,9 @@ Focus only on this item, but use the plan for context.`;
|
|
|
80891
80955
|
logger.warn(`Warning: Iteration ${iterationCount} completed with potential issues (${taskElapsedTime})`);
|
|
80892
80956
|
}
|
|
80893
80957
|
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
80958
|
await tools2.updateTodoItem({ operation: "update", id: nextTaskId, status: "completed" });
|
|
80898
80959
|
});
|
|
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
|
-
}
|
|
80960
|
+
nextTaskItem = await step(`get-next-task-${iterationCount}`, () => findNextTask(tools2));
|
|
80912
80961
|
const allTodos = await tools2.listTodoItems({});
|
|
80913
80962
|
const completedTodos = allTodos.filter((t) => t.status === "completed").length;
|
|
80914
80963
|
const totalTodos = allTodos.length;
|
|
@@ -80920,13 +80969,13 @@ Focus only on this item, but use the plan for context.`;
|
|
|
80920
80969
|
}
|
|
80921
80970
|
logger.info(`
|
|
80922
80971
|
Progress: ${progressMessage}`);
|
|
80923
|
-
if (
|
|
80972
|
+
if (!nextTaskItem) {
|
|
80924
80973
|
logger.info(`All tasks complete!
|
|
80925
80974
|
`);
|
|
80926
80975
|
break;
|
|
80927
80976
|
}
|
|
80928
|
-
if (
|
|
80929
|
-
logger.info(`Next task: ${
|
|
80977
|
+
if (nextTaskItem) {
|
|
80978
|
+
logger.info(`Next task: ${nextTaskItem.title}
|
|
80930
80979
|
`);
|
|
80931
80980
|
}
|
|
80932
80981
|
logger.info(`${"-".repeat(80)}
|
|
@@ -80952,7 +81001,7 @@ Phase 6: Final Review and Fixup...
|
|
|
80952
81001
|
const commitRange = `${baseBranch}...${currentBranch}`;
|
|
80953
81002
|
for (let i = 0;i < MAX_REVIEW_RETRIES; i++) {
|
|
80954
81003
|
const diffResult = await tools2.executeCommand({ command: "git", args: ["diff", "--name-status", commitRange] });
|
|
80955
|
-
const changedFiles = parseGitDiffNameStatus(diffResult.stdout);
|
|
81004
|
+
const changedFiles = parseGitDiffNameStatus(diffResult.stdout).filter(({ path }) => path !== ".epic.yml");
|
|
80956
81005
|
if (changedFiles.length === 0) {
|
|
80957
81006
|
logger.info(`No files have been changed in this branch. Skipping final review.
|
|
80958
81007
|
`);
|
|
@@ -80991,8 +81040,8 @@ ${formatReviewToolInput(changeInfo)}`;
|
|
|
80991
81040
|
}
|
|
80992
81041
|
logger.warn(`Warning: Final review found ${reviewResult.specificReviews.length} issue(s). Attempting to fix...
|
|
80993
81042
|
`);
|
|
80994
|
-
for (const [idx,
|
|
80995
|
-
logger.warn(` ${idx + 1}. ${
|
|
81043
|
+
for (const [idx, review2] of reviewResult.specificReviews.entries()) {
|
|
81044
|
+
logger.warn(` ${idx + 1}. ${review2.file}:${review2.lines}`);
|
|
80996
81045
|
}
|
|
80997
81046
|
logger.warn("");
|
|
80998
81047
|
const reviewSummary = reviewResult.specificReviews.map((r) => `File: ${r.file} (lines: ${r.lines})
|
|
@@ -81102,6 +81151,37 @@ Summary:`);
|
|
|
81102
81151
|
for (const [idx, msg] of commitMessages.entries()) {
|
|
81103
81152
|
logger.info(` ${idx + 1}. ${msg}`);
|
|
81104
81153
|
}
|
|
81154
|
+
if (input2.usages && input2.usages.length > 0) {
|
|
81155
|
+
const sortedUsages = [...input2.usages].sort((a, b) => a.timestamp - b.timestamp);
|
|
81156
|
+
let lastUsage = {
|
|
81157
|
+
input: 0,
|
|
81158
|
+
output: 0,
|
|
81159
|
+
cachedRead: 0,
|
|
81160
|
+
cost: 0,
|
|
81161
|
+
messageCount: 0
|
|
81162
|
+
};
|
|
81163
|
+
logger.info(`
|
|
81164
|
+
Usage Breakdown:`);
|
|
81165
|
+
sortedUsages.forEach((usage, index) => {
|
|
81166
|
+
const delta = {
|
|
81167
|
+
input: usage.input - lastUsage.input,
|
|
81168
|
+
output: usage.output - lastUsage.output,
|
|
81169
|
+
cachedRead: usage.cachedRead - lastUsage.cachedRead,
|
|
81170
|
+
cost: usage.cost - lastUsage.cost,
|
|
81171
|
+
messageCount: usage.messageCount - lastUsage.messageCount
|
|
81172
|
+
};
|
|
81173
|
+
const tempMeter = new UsageMeter;
|
|
81174
|
+
tempMeter.setUsage(delta);
|
|
81175
|
+
logger.info(` Step ${index + 1}: ${tempMeter.getUsageText()}`);
|
|
81176
|
+
lastUsage = usage;
|
|
81177
|
+
});
|
|
81178
|
+
const last = sortedUsages.at(-1);
|
|
81179
|
+
if (last) {
|
|
81180
|
+
const totalMeter = new UsageMeter;
|
|
81181
|
+
totalMeter.setUsage(last);
|
|
81182
|
+
logger.info(` Total: ${totalMeter.getUsageText()}`);
|
|
81183
|
+
}
|
|
81184
|
+
}
|
|
81105
81185
|
} catch (error46) {
|
|
81106
81186
|
logger.error(`
|
|
81107
81187
|
Epic workflow failed: ${error46 instanceof Error ? error46.message : String(error46)}`);
|
|
@@ -81256,10 +81336,10 @@ var prWorkflow = async (input2, context) => {
|
|
|
81256
81336
|
// src/workflows/review.workflow.ts
|
|
81257
81337
|
var reviewWorkflow = async (input2, context) => {
|
|
81258
81338
|
const { step, tools: tools2, logger } = context;
|
|
81259
|
-
const { pr } = input2;
|
|
81339
|
+
const { pr: pr2 } = input2;
|
|
81260
81340
|
let changeInfo;
|
|
81261
|
-
if (
|
|
81262
|
-
const prNumberMatch =
|
|
81341
|
+
if (pr2) {
|
|
81342
|
+
const prNumberMatch = pr2.match(/\d+$/);
|
|
81263
81343
|
if (!prNumberMatch) {
|
|
81264
81344
|
throw new Error("Invalid PR number or URL.");
|
|
81265
81345
|
}
|
|
@@ -81403,13 +81483,22 @@ var commitCommand = new Command("commit").description("Create a commit with AI-g
|
|
|
81403
81483
|
// src/workflows/epic-context.ts
|
|
81404
81484
|
import { promises as fs3 } from "node:fs";
|
|
81405
81485
|
var EPIC_CONTEXT_FILE = ".epic.yml";
|
|
81486
|
+
var EpicUsageSchema = exports_external.object({
|
|
81487
|
+
timestamp: exports_external.number(),
|
|
81488
|
+
input: exports_external.number(),
|
|
81489
|
+
output: exports_external.number(),
|
|
81490
|
+
cachedRead: exports_external.number(),
|
|
81491
|
+
cost: exports_external.number(),
|
|
81492
|
+
messageCount: exports_external.number()
|
|
81493
|
+
});
|
|
81406
81494
|
var EpicContextSchema = exports_external.object({
|
|
81407
81495
|
task: exports_external.string().nullish(),
|
|
81408
81496
|
plan: exports_external.string().nullish(),
|
|
81409
81497
|
branchName: exports_external.string().nullish(),
|
|
81410
81498
|
baseBranch: exports_external.string().nullish(),
|
|
81411
81499
|
todos: exports_external.array(TodoItemSchema).nullish(),
|
|
81412
|
-
memory: exports_external.record(exports_external.string(), exports_external.string()).nullish()
|
|
81500
|
+
memory: exports_external.record(exports_external.string(), exports_external.string()).nullish(),
|
|
81501
|
+
usages: exports_external.array(EpicUsageSchema).nullish()
|
|
81413
81502
|
});
|
|
81414
81503
|
var saveEpicContext = async (context) => {
|
|
81415
81504
|
const yamlString = $stringify({
|
|
@@ -81418,7 +81507,8 @@ var saveEpicContext = async (context) => {
|
|
|
81418
81507
|
branchName: context.branchName,
|
|
81419
81508
|
baseBranch: context.baseBranch,
|
|
81420
81509
|
todos: context.todos,
|
|
81421
|
-
memory: context.memory
|
|
81510
|
+
memory: context.memory,
|
|
81511
|
+
usages: context.usages
|
|
81422
81512
|
});
|
|
81423
81513
|
await fs3.writeFile(EPIC_CONTEXT_FILE, yamlString, "utf-8");
|
|
81424
81514
|
};
|
|
@@ -81492,10 +81582,26 @@ async function runEpic(task2, _options, command) {
|
|
|
81492
81582
|
}
|
|
81493
81583
|
epicContext.task = taskInput;
|
|
81494
81584
|
}
|
|
81585
|
+
let usageAppended = false;
|
|
81495
81586
|
const workflowInput = {
|
|
81496
81587
|
...epicContext,
|
|
81497
|
-
saveEpicContext
|
|
81588
|
+
async saveEpicContext(context) {
|
|
81589
|
+
if (usageMeter) {
|
|
81590
|
+
const currentUsage = usageMeter.usage;
|
|
81591
|
+
if (!context.usages) {
|
|
81592
|
+
context.usages = [];
|
|
81593
|
+
}
|
|
81594
|
+
if (!usageAppended) {
|
|
81595
|
+
context.usages.push({ ...currentUsage, timestamp: Date.now() });
|
|
81596
|
+
usageAppended = true;
|
|
81597
|
+
} else {
|
|
81598
|
+
context.usages[context.usages.length - 1] = { ...currentUsage, timestamp: Date.now() };
|
|
81599
|
+
}
|
|
81600
|
+
}
|
|
81601
|
+
await saveEpicContext(context);
|
|
81602
|
+
}
|
|
81498
81603
|
};
|
|
81604
|
+
let usageMeter;
|
|
81499
81605
|
await runWorkflow(epicWorkflow, workflowInput, {
|
|
81500
81606
|
commandName: "epic",
|
|
81501
81607
|
command,
|
|
@@ -81505,7 +81611,10 @@ async function runEpic(task2, _options, command) {
|
|
|
81505
81611
|
...opt,
|
|
81506
81612
|
todoItemStore: new EpicTodoItemStore(workflowInput),
|
|
81507
81613
|
memoryStore: new EpicMemoryStore(workflowInput)
|
|
81508
|
-
})
|
|
81614
|
+
}),
|
|
81615
|
+
onUsageMeterCreated: (meter) => {
|
|
81616
|
+
usageMeter = meter;
|
|
81617
|
+
}
|
|
81509
81618
|
});
|
|
81510
81619
|
}
|
|
81511
81620
|
var epicCommand = new Command("epic").description("Orchestrates a large feature or epic, breaking it down into smaller tasks.").argument("[task]", "The epic to plan and implement.").action(runEpic);
|
|
@@ -81636,7 +81745,7 @@ var reviewCommand = new Command("review").description("Review a GitHub pull requ
|
|
|
81636
81745
|
}
|
|
81637
81746
|
return parsedValue;
|
|
81638
81747
|
}, 1).action(async (options, command) => {
|
|
81639
|
-
const { json: json2, pr:
|
|
81748
|
+
const { json: json2, pr: pr3, loop: maxIterations, yes: yesOption } = options;
|
|
81640
81749
|
const yes = maxIterations > 1 || yesOption;
|
|
81641
81750
|
let changesAppliedInThisIteration = false;
|
|
81642
81751
|
const globalOpts = (command.parent ?? command).opts();
|
|
@@ -81646,7 +81755,7 @@ var reviewCommand = new Command("review").description("Review a GitHub pull requ
|
|
|
81646
81755
|
});
|
|
81647
81756
|
for (let i = 0;i < maxIterations; i++) {
|
|
81648
81757
|
changesAppliedInThisIteration = false;
|
|
81649
|
-
const input2 = { pr:
|
|
81758
|
+
const input2 = { pr: pr3 };
|
|
81650
81759
|
if (i > 0) {
|
|
81651
81760
|
logger.debug(`Re-running review (iteration ${i + 1} of ${maxIterations})...`);
|
|
81652
81761
|
}
|