@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.
Files changed (2) hide show
  1. package/dist/index.js +842 -733
  2. 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.54";
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().optional().default(false)).describe("Whether to include ignored files. Use true to include files ignored by .gitignore.").meta({ usageValue: "true or false (optional)" })
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().optional().describe('The topic to read from memory. Defaults to ":default:".')
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().optional().describe("The content for append or replace operations. Must be omitted for remove operation.")
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, "content" in params ? params.content : 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 toolProvider = (options.getProvider ?? getProvider)({ excludeFiles: config4.excludeFiles });
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
- **Example of extracting from a detailed plan task:**
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 currentTask = userFeedback ? `${task}
79782
-
79783
- User feedback: ${userFeedback}` : task;
79784
- const defaultContext = await getDefaultContext();
79785
- const memoryContext = await tools2.getMemoryContext();
79786
- const prompt = `${memoryContext}
79787
- ${getPlanPrompt(currentTask, inputPlan)}
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
- const userContent = [{ type: "text", text: prompt }];
79791
- if (files) {
79792
- for (const file2 of files) {
79793
- if (file2.type === "file") {
79794
- userContent.push({
79795
- type: "file",
79796
- mediaType: file2.mediaType,
79797
- filename: file2.filename,
79798
- data: { type: "base64", value: file2.data }
79799
- });
79800
- } else if (file2.type === "image") {
79801
- userContent.push({
79802
- type: "image",
79803
- mediaType: file2.mediaType,
79804
- image: { type: "base64", value: file2.image }
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
- systemPrompt: PLANNER_SYSTEM_PROMPT,
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: plan || inputPlan, question };
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: plan || undefined, files: outputFiles };
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 plan = fileContent || "";
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 = plan ? "How would you like to improve the plan?" : "What is the task you want to plan?";
79867
- const defaultTask = plan ? "Review and improve the plan" : undefined;
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
- plan = planResult.plan || plan;
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
- plan = planResult.plan || "";
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(plan);
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: plan });
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
- plan = "";
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(plan);
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 content = [{ type: "text", text: getPlanPrompt(task, plan) }];
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
- if (feedback) {
80564
- content.push({
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: [{ role: "user", content }],
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 result = await step(`plan-${planAttempt}`, () => createPlan2({ task, feedback }, context));
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(plan, context) {
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
- ${plan}</plan>` }],
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, review] of reviewResult.specificReviews.entries()) {
80793
- logger.warn(` ${idx + 1}. ${review.file}:${review.lines}`);
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 isComplete = false;
80840
- let nextTask = null;
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
- const openTasks = await step(`get-next-task-${iterationCount}`, async () => {
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 (isComplete) {
80972
+ if (!nextTaskItem) {
80924
80973
  logger.info(`All tasks complete!
80925
80974
  `);
80926
80975
  break;
80927
80976
  }
80928
- if (nextTask) {
80929
- logger.info(`Next task: ${nextTask}
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, review] of reviewResult.specificReviews.entries()) {
80995
- logger.warn(` ${idx + 1}. ${review.file}:${review.lines}`);
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 (pr) {
81262
- const prNumberMatch = pr.match(/\d+$/);
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: pr2, loop: maxIterations, yes: yesOption } = options;
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: pr2 };
81758
+ const input2 = { pr: pr3 };
81650
81759
  if (i > 0) {
81651
81760
  logger.debug(`Re-running review (iteration ${i + 1} of ${maxIterations})...`);
81652
81761
  }