Add UpdateFeatureStatus custom MCP tool for safe feature status updates

- Created createFeatureToolsServer() method that creates an MCP server with
  the UpdateFeatureStatus tool
- Tool accepts featureId and status parameters to safely update feature status
- Updated all prompts to instruct agents to use the custom tool instead of
  directly modifying feature_list.json
- Added mcpServers configuration to all query options
- This prevents race conditions and accidental state restoration when
  Claude Code updates feature status

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Cody Seibert
2025-12-09 08:47:13 -05:00
parent da5960c340
commit 436625648c
2 changed files with 122 additions and 14 deletions

View File

@@ -25,7 +25,7 @@
"category": "Kanban", "category": "Kanban",
"description": "When adding a new feature inside the modal there's an add feature button. Can you add a shortcut of shift? Enter which if you click shift enter I'll automatically add it in", "description": "When adding a new feature inside the modal there's an add feature button. Can you add a shortcut of shift? Enter which if you click shift enter I'll automatically add it in",
"steps": [], "steps": [],
"status": "in_progress" "status": "verified"
}, },
{ {
"id": "feature-1765287141131-dz489etgj", "id": "feature-1765287141131-dz489etgj",
@@ -39,7 +39,7 @@
"category": "Core", "category": "Core",
"description": "I'm noticing that when cards finish running, sometimes Cloud Code will update the featureless JSON and restore old state. I think instead of actually modifying the featureless JSON manually, it should call an custom tool, and that tool should update a card directly into the JSON so that Cloud Code isn't potentially messing with other things. All it needs to do is just pass in an ID and a status, and that's going to update in the JSON list.", "description": "I'm noticing that when cards finish running, sometimes Cloud Code will update the featureless JSON and restore old state. I think instead of actually modifying the featureless JSON manually, it should call an custom tool, and that tool should update a card directly into the JSON so that Cloud Code isn't potentially messing with other things. All it needs to do is just pass in an ID and a status, and that's going to update in the JSON list.",
"steps": [], "steps": [],
"status": "in_progress" "status": "verified"
}, },
{ {
"id": "feature-1765287638726-rtxxdpobi", "id": "feature-1765287638726-rtxxdpobi",

View File

@@ -1,6 +1,7 @@
const { query, AbortError } = require("@anthropic-ai/claude-agent-sdk"); const { query, AbortError, createSdkMcpServer, tool } = require("@anthropic-ai/claude-agent-sdk");
const path = require("path"); const path = require("path");
const fs = require("fs/promises"); const fs = require("fs/promises");
const { z } = require("zod");
/** /**
* Auto Mode Service - Autonomous feature implementation * Auto Mode Service - Autonomous feature implementation
@@ -14,6 +15,54 @@ class AutoModeService {
this.autoLoopAbortController = null; this.autoLoopAbortController = null;
} }
/**
* Create a custom MCP server with the UpdateFeatureStatus tool
* This tool allows Claude Code to safely update feature status without
* directly modifying the feature_list.json file, preventing race conditions
* and accidental state restoration.
*/
createFeatureToolsServer(projectPath) {
const service = this; // Reference to AutoModeService instance
return createSdkMcpServer({
name: "automaker-tools",
version: "1.0.0",
tools: [
tool(
"UpdateFeatureStatus",
"Update the status of a feature in the feature list. Use this tool instead of directly modifying feature_list.json to safely update feature status.",
{
featureId: z.string().describe("The ID of the feature to update"),
status: z.enum(["backlog", "in_progress", "verified"]).describe("The new status for the feature")
},
async (args) => {
try {
console.log(`[AutoMode] UpdateFeatureStatus tool called: featureId=${args.featureId}, status=${args.status}`);
// Use the service's updateFeatureStatus method
await service.updateFeatureStatus(args.featureId, args.status, projectPath);
return {
content: [{
type: "text",
text: `Successfully updated feature ${args.featureId} to status "${args.status}"`
}]
};
} catch (error) {
console.error("[AutoMode] UpdateFeatureStatus tool error:", error);
return {
content: [{
type: "text",
text: `Failed to update feature status: ${error.message}`
}]
};
}
}
)
]
});
}
/** /**
* Start auto mode - continuously implement features * Start auto mode - continuously implement features
*/ */
@@ -359,12 +408,18 @@ class AutoModeService {
const abortController = new AbortController(); const abortController = new AbortController();
execution.abortController = abortController; execution.abortController = abortController;
// Create custom MCP server with UpdateFeatureStatus tool
const featureToolsServer = this.createFeatureToolsServer(projectPath);
const options = { const options = {
model: "claude-opus-4-5-20251101", model: "claude-opus-4-5-20251101",
systemPrompt: this.getVerificationPrompt(), systemPrompt: this.getVerificationPrompt(),
maxTurns: 1000, maxTurns: 1000,
cwd: projectPath, cwd: projectPath,
allowedTools: ["Read", "Write", "Edit", "Glob", "Grep", "Bash", "WebSearch", "WebFetch"], mcpServers: {
"automaker-tools": featureToolsServer
},
allowedTools: ["Read", "Write", "Edit", "Glob", "Grep", "Bash", "WebSearch", "WebFetch", "mcp__automaker-tools__UpdateFeatureStatus"],
permissionMode: "acceptEdits", permissionMode: "acceptEdits",
sandbox: { sandbox: {
enabled: true, enabled: true,
@@ -465,6 +520,7 @@ class AutoModeService {
**Current Feature:** **Current Feature:**
ID: ${feature.id}
Category: ${feature.category} Category: ${feature.category}
Description: ${feature.description} Description: ${feature.description}
@@ -484,9 +540,16 @@ Continue where you left off and complete the feature implementation:
3. Write Playwright tests to verify the feature works correctly (if not already done) 3. Write Playwright tests to verify the feature works correctly (if not already done)
4. Run the tests and ensure they pass 4. Run the tests and ensure they pass
5. **DELETE the test file(s) you created** - tests are only for immediate verification 5. **DELETE the test file(s) you created** - tests are only for immediate verification
6. Update .automaker/feature_list.json to mark this feature as "status": "verified" 6. **CRITICAL: Use the UpdateFeatureStatus tool to mark this feature as verified** - DO NOT manually edit .automaker/feature_list.json
7. Commit your changes with git 7. Commit your changes with git
**IMPORTANT - Updating Feature Status:**
When all tests pass, you MUST use the \`mcp__automaker-tools__UpdateFeatureStatus\` tool to update the feature status:
- Call the tool with: featureId="${feature.id}" and status="verified"
- **DO NOT manually edit the .automaker/feature_list.json file** - this can cause race conditions
- The UpdateFeatureStatus tool safely updates the feature status without risk of corrupting other data
**Important Guidelines:** **Important Guidelines:**
- Review what was already done in the previous context - Review what was already done in the previous context
@@ -495,6 +558,7 @@ Continue where you left off and complete the feature implementation:
- Write comprehensive Playwright tests if not already done - Write comprehensive Playwright tests if not already done
- Ensure all tests pass before marking as verified - Ensure all tests pass before marking as verified
- **CRITICAL: Delete test files after verification** - **CRITICAL: Delete test files after verification**
- **CRITICAL: Use UpdateFeatureStatus tool instead of editing feature_list.json directly**
- Make a git commit when complete - Make a git commit when complete
Begin by assessing what's been done and what remains to be completed.`; Begin by assessing what's been done and what remains to be completed.`;
@@ -704,12 +768,18 @@ Begin by assessing what's been done and what remains to be completed.`;
const abortController = new AbortController(); const abortController = new AbortController();
execution.abortController = abortController; execution.abortController = abortController;
// Create custom MCP server with UpdateFeatureStatus tool
const featureToolsServer = this.createFeatureToolsServer(projectPath);
// Configure options for the SDK query // Configure options for the SDK query
const options = { const options = {
model: "claude-opus-4-5-20251101", model: "claude-opus-4-5-20251101",
systemPrompt: this.getCodingPrompt(), systemPrompt: this.getCodingPrompt(),
maxTurns: 1000, maxTurns: 1000,
cwd: projectPath, cwd: projectPath,
mcpServers: {
"automaker-tools": featureToolsServer
},
allowedTools: [ allowedTools: [
"Read", "Read",
"Write", "Write",
@@ -719,6 +789,7 @@ Begin by assessing what's been done and what remains to be completed.`;
"Bash", "Bash",
"WebSearch", "WebSearch",
"WebFetch", "WebFetch",
"mcp__automaker-tools__UpdateFeatureStatus",
], ],
permissionMode: "acceptEdits", permissionMode: "acceptEdits",
sandbox: { sandbox: {
@@ -946,12 +1017,18 @@ Begin by assessing what's been done and what remains to be completed.`;
const abortController = new AbortController(); const abortController = new AbortController();
execution.abortController = abortController; execution.abortController = abortController;
// Create custom MCP server with UpdateFeatureStatus tool
const featureToolsServer = this.createFeatureToolsServer(projectPath);
const options = { const options = {
model: "claude-opus-4-5-20251101", model: "claude-opus-4-5-20251101",
systemPrompt: this.getVerificationPrompt(), systemPrompt: this.getVerificationPrompt(),
maxTurns: 1000, maxTurns: 1000,
cwd: projectPath, cwd: projectPath,
allowedTools: ["Read", "Write", "Edit", "Glob", "Grep", "Bash"], mcpServers: {
"automaker-tools": featureToolsServer
},
allowedTools: ["Read", "Write", "Edit", "Glob", "Grep", "Bash", "mcp__automaker-tools__UpdateFeatureStatus"],
permissionMode: "acceptEdits", permissionMode: "acceptEdits",
sandbox: { sandbox: {
enabled: true, enabled: true,
@@ -1061,6 +1138,7 @@ Begin by assessing what's been done and what remains to be completed.`;
**Current Feature to Implement:** **Current Feature to Implement:**
ID: ${feature.id}
Category: ${feature.category} Category: ${feature.category}
Description: ${feature.description} Description: ${feature.description}
@@ -1074,9 +1152,16 @@ ${feature.steps.map((step, i) => `${i + 1}. ${step}`).join("\n")}
3. Write Playwright tests to verify the feature works correctly 3. Write Playwright tests to verify the feature works correctly
4. Run the tests and ensure they pass 4. Run the tests and ensure they pass
5. **DELETE the test file(s) you created** - tests are only for immediate verification 5. **DELETE the test file(s) you created** - tests are only for immediate verification
6. Update .automaker/feature_list.json to mark this feature as "status": "verified" 6. **CRITICAL: Use the UpdateFeatureStatus tool to mark this feature as verified** - DO NOT manually edit .automaker/feature_list.json
7. Commit your changes with git 7. Commit your changes with git
**IMPORTANT - Updating Feature Status:**
When you have completed the feature and all tests pass, you MUST use the \`mcp__automaker-tools__UpdateFeatureStatus\` tool to update the feature status:
- Call the tool with: featureId="${feature.id}" and status="verified"
- **DO NOT manually edit the .automaker/feature_list.json file** - this can cause race conditions
- The UpdateFeatureStatus tool safely updates the feature status without risk of corrupting other data
**Important Guidelines:** **Important Guidelines:**
- Focus ONLY on implementing this specific feature - Focus ONLY on implementing this specific feature
@@ -1086,6 +1171,7 @@ ${feature.steps.map((step, i) => `${i + 1}. ${step}`).join("\n")}
- Ensure all existing tests still pass - Ensure all existing tests still pass
- Mark the feature as passing only when all tests are green - Mark the feature as passing only when all tests are green
- **CRITICAL: Delete test files after verification** - tests accumulate and become brittle - **CRITICAL: Delete test files after verification** - tests accumulate and become brittle
- **CRITICAL: Use UpdateFeatureStatus tool instead of editing feature_list.json directly**
- Make a git commit when complete - Make a git commit when complete
**Testing Utilities (CRITICAL):** **Testing Utilities (CRITICAL):**
@@ -1142,13 +1228,19 @@ ${feature.steps.map((step, i) => `${i + 1}. ${step}`).join("\n")}
- Update test utilities in tests/utils.ts if needed - Update test utilities in tests/utils.ts if needed
- Re-run the tests to verify the fixes - Re-run the tests to verify the fixes
- **REPEAT this process until ALL tests pass** - **REPEAT this process until ALL tests pass**
- Keep the feature "status" as "in_progress" in .automaker/feature_list.json
7. **If ALL tests pass:** 7. **If ALL tests pass:**
- **DELETE the test file(s) for this feature** - tests are only for immediate verification - **DELETE the test file(s) for this feature** - tests are only for immediate verification
- Update .automaker/feature_list.json to set this feature's "status" to "verified" - **CRITICAL: Use the UpdateFeatureStatus tool to mark this feature as verified** - DO NOT manually edit .automaker/feature_list.json
- Explain what was implemented/fixed and that all tests passed - Explain what was implemented/fixed and that all tests passed
- Commit your changes with git - Commit your changes with git
**IMPORTANT - Updating Feature Status:**
When all tests pass, you MUST use the \`mcp__automaker-tools__UpdateFeatureStatus\` tool to update the feature status:
- Call the tool with: featureId="${feature.id}" and status="verified"
- **DO NOT manually edit the .automaker/feature_list.json file** - this can cause race conditions
- The UpdateFeatureStatus tool safely updates the feature status without risk of corrupting other data
**Testing Utilities:** **Testing Utilities:**
- Check if tests/utils.ts exists and is being used - Check if tests/utils.ts exists and is being used
- If utilities are outdated due to functionality changes, update them - If utilities are outdated due to functionality changes, update them
@@ -1165,6 +1257,7 @@ rm tests/[feature-name].spec.ts
- **CONTINUE IMPLEMENTING until all tests pass** - don't stop at the first failure - **CONTINUE IMPLEMENTING until all tests pass** - don't stop at the first failure
- Only mark as "verified" if Playwright tests pass - Only mark as "verified" if Playwright tests pass
- **CRITICAL: Delete test files after they pass** - tests should not accumulate - **CRITICAL: Delete test files after they pass** - tests should not accumulate
- **CRITICAL: Use UpdateFeatureStatus tool instead of editing feature_list.json directly**
- Update test utilities if functionality changed - Update test utilities if functionality changed
- Make a git commit when the feature is complete - Make a git commit when the feature is complete
- Be thorough and persistent in fixing issues - Be thorough and persistent in fixing issues
@@ -1186,10 +1279,16 @@ Your role is to:
- If other tests fail, verify if those tests are still accurate or should be updated or deleted - If other tests fail, verify if those tests are still accurate or should be updated or deleted
- Continue rerunning tests and fixing issues until ALL tests pass - Continue rerunning tests and fixing issues until ALL tests pass
- **DELETE test files after successful verification** - tests are only for immediate feature verification - **DELETE test files after successful verification** - tests are only for immediate feature verification
- Update feature status to verified in .automaker/feature_list.json after all tests pass - **Use the UpdateFeatureStatus tool to mark features as verified** - NEVER manually edit feature_list.json
- **Update test utilities (tests/utils.ts) if functionality changed** - keep helpers in sync with code - **Update test utilities (tests/utils.ts) if functionality changed** - keep helpers in sync with code
- Commit working code to git - Commit working code to git
**IMPORTANT - UpdateFeatureStatus Tool:**
You have access to the \`mcp__automaker-tools__UpdateFeatureStatus\` tool. When all tests pass, use this tool to update the feature status:
- Call with featureId and status="verified"
- **DO NOT manually edit .automaker/feature_list.json** - this can cause race conditions and restore old state
- The tool safely updates the status without corrupting other feature data
**Testing Utilities:** **Testing Utilities:**
- Check if tests/utils.ts needs updates based on code changes - Check if tests/utils.ts needs updates based on code changes
- If a component's selectors or behavior changed, update the corresponding utility functions - If a component's selectors or behavior changed, update the corresponding utility functions
@@ -1199,7 +1298,7 @@ Your role is to:
**Test Deletion Policy:** **Test Deletion Policy:**
Tests should NOT accumulate. After a feature is verified: Tests should NOT accumulate. After a feature is verified:
1. Delete the test file for that feature 1. Delete the test file for that feature
2. Mark the feature as "verified" in feature_list.json 2. Use UpdateFeatureStatus tool to mark the feature as "verified"
This prevents test brittleness as the app changes rapidly. This prevents test brittleness as the app changes rapidly.
@@ -1210,8 +1309,9 @@ You have access to:
- Delete files (rm command) - Delete files (rm command)
- Analyze test output - Analyze test output
- Make git commits - Make git commits
- **UpdateFeatureStatus tool** (mcp__automaker-tools__UpdateFeatureStatus) - Use this to update feature status
**CRITICAL:** Be persistent and thorough - keep iterating on the implementation until all tests pass. Don't give up after the first failure. Always delete tests after they pass and commit your work.`; **CRITICAL:** Be persistent and thorough - keep iterating on the implementation until all tests pass. Don't give up after the first failure. Always delete tests after they pass, use the UpdateFeatureStatus tool, and commit your work.`;
} }
/** /**
@@ -1226,9 +1326,16 @@ Your role is to:
- Create comprehensive Playwright tests using testing utilities - Create comprehensive Playwright tests using testing utilities
- Ensure all tests pass before marking features complete - Ensure all tests pass before marking features complete
- **DELETE test files after successful verification** - tests are only for immediate feature verification - **DELETE test files after successful verification** - tests are only for immediate feature verification
- **Use the UpdateFeatureStatus tool to mark features as verified** - NEVER manually edit feature_list.json
- Commit working code to git - Commit working code to git
- Be thorough and detail-oriented - Be thorough and detail-oriented
**IMPORTANT - UpdateFeatureStatus Tool:**
You have access to the \`mcp__automaker-tools__UpdateFeatureStatus\` tool. When all tests pass, use this tool to update the feature status:
- Call with featureId and status="verified"
- **DO NOT manually edit .automaker/feature_list.json** - this can cause race conditions and restore old state
- The tool safely updates the status without corrupting other feature data
**Testing Utilities (CRITICAL):** **Testing Utilities (CRITICAL):**
- **Create and maintain tests/utils.ts** with helper functions for finding elements and common operations - **Create and maintain tests/utils.ts** with helper functions for finding elements and common operations
- **Always use utilities in tests** instead of repeating selectors - **Always use utilities in tests** instead of repeating selectors
@@ -1241,7 +1348,7 @@ This makes future tests easier to write and more maintainable!
Tests should NOT accumulate. After a feature is verified: Tests should NOT accumulate. After a feature is verified:
1. Run the tests to ensure they pass 1. Run the tests to ensure they pass
2. Delete the test file for that feature 2. Delete the test file for that feature
3. Mark the feature as "verified" in .automaker/feature_list.json 3. Use UpdateFeatureStatus tool to mark the feature as "verified"
This prevents test brittleness as the app changes rapidly. This prevents test brittleness as the app changes rapidly.
@@ -1252,8 +1359,9 @@ You have full access to:
- Delete files (rm command) - Delete files (rm command)
- Make git commits - Make git commits
- Search and analyze the codebase - Search and analyze the codebase
- **UpdateFeatureStatus tool** (mcp__automaker-tools__UpdateFeatureStatus) - Use this to update feature status
Focus on one feature at a time and complete it fully before finishing. Always delete tests after they pass.`; Focus on one feature at a time and complete it fully before finishing. Always delete tests after they pass and use the UpdateFeatureStatus tool.`;
} }
/** /**