agent-state-machine 2.4.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +7 -7
- package/lib/llm.js +14 -3
- package/lib/remote/client.js +19 -6
- package/lib/runtime/agent.js +29 -2
- package/lib/runtime/prompt.js +1 -1
- package/lib/runtime/runtime.js +48 -4
- package/lib/runtime/track-changes.js +84 -0
- package/package.json +1 -1
- package/templates/project-builder/agents/{code-writer.md → code-write.md} +18 -12
- package/templates/project-builder/agents/{assumptions-clarifier.md → intake-assumptions.md} +1 -0
- package/templates/project-builder/agents/{requirements-clarifier.md → intake-requirements.md} +1 -0
- package/templates/project-builder/agents/{scope-clarifier.md → intake-scope.md} +1 -0
- package/templates/project-builder/agents/{security-clarifier.md → intake-security.md} +1 -0
- package/templates/project-builder/agents/{roadmap-generator.md → plan-roadmap.md} +1 -0
- package/templates/project-builder/agents/{task-planner.md → plan-tasks.md} +1 -0
- package/templates/project-builder/agents/post-code-fix.md +59 -0
- package/templates/project-builder/agents/{code-reviewer.md → post-code-review.md} +10 -0
- package/templates/project-builder/agents/post-code-security.md +55 -0
- package/templates/project-builder/agents/{security-reviewer.md → pre-code-security.md} +8 -11
- package/templates/project-builder/agents/{test-planner.md → pre-code-tests.md} +1 -0
- package/templates/project-builder/agents/response-interpreter.md +1 -0
- package/templates/project-builder/agents/verify-commit-msg.md +64 -0
- package/templates/project-builder/agents/{sanity-checker.md → verify-sanity.md} +1 -12
- package/templates/project-builder/config.js +15 -4
- package/templates/project-builder/scripts/safeguard-recovery.js +40 -0
- package/templates/project-builder/scripts/validate-changes.js +61 -0
- package/templates/project-builder/scripts/workflow-helpers.js +87 -35
- package/templates/project-builder/workflow.js +231 -93
- package/vercel-server/api/config/[token].js +76 -0
- package/vercel-server/api/history/[token].js +1 -0
- package/vercel-server/api/ws/cli.js +39 -20
- package/vercel-server/local-server.js +98 -11
- package/vercel-server/public/remote/assets/index-BHvHkNOe.css +1 -0
- package/vercel-server/public/remote/assets/index-BnuR91vD.js +188 -0
- package/vercel-server/public/remote/index.html +2 -2
- package/vercel-server/ui/src/App.jsx +35 -0
- package/vercel-server/ui/src/components/ContentCard.jsx +183 -5
- package/vercel-server/ui/src/components/Header.jsx +59 -11
- package/vercel-server/ui/src/components/SettingsModal.jsx +145 -0
- package/templates/project-builder/agents/code-fixer.md +0 -50
- package/vercel-server/public/remote/assets/index-Bnvi3AUu.js +0 -173
- package/vercel-server/public/remote/assets/index-DH2uv4Ll.css +0 -1
- /package/templates/project-builder/{agents → scripts}/sanity-runner.js +0 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
model: med
|
|
3
|
+
format: json
|
|
4
|
+
description: "Post-code phase: Audits implementation for security vulnerabilities"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Post-Code Security Auditor Agent
|
|
8
|
+
|
|
9
|
+
You are a security auditor. Review implemented code to identify security vulnerabilities and verify secure coding practices.
|
|
10
|
+
|
|
11
|
+
## How to Audit
|
|
12
|
+
|
|
13
|
+
**Use your file tools to read the files that need auditing.** You will receive a list of file paths. Read each file's contents directly from disk to perform your security audit.
|
|
14
|
+
|
|
15
|
+
## Instructions
|
|
16
|
+
|
|
17
|
+
Perform a post-implementation security audit:
|
|
18
|
+
|
|
19
|
+
- Review the implementation for security issues
|
|
20
|
+
- Check for common vulnerabilities (OWASP Top 10)
|
|
21
|
+
- Verify secure coding practices
|
|
22
|
+
- Identify any remaining security debt
|
|
23
|
+
- Verify pre-code security recommendations were followed
|
|
24
|
+
|
|
25
|
+
## Output Format
|
|
26
|
+
|
|
27
|
+
Return a valid JSON object:
|
|
28
|
+
|
|
29
|
+
{
|
|
30
|
+
"riskLevel": "low",
|
|
31
|
+
"findings": [
|
|
32
|
+
{
|
|
33
|
+
"type": "vulnerability",
|
|
34
|
+
"severity": "high",
|
|
35
|
+
"location": "src/auth.js:42",
|
|
36
|
+
"description": "User input not sanitized before database query",
|
|
37
|
+
"recommendation": "Use parameterized query instead"
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"checklistResults": [
|
|
41
|
+
{"item": "Input validation implemented", "status": "passed"},
|
|
42
|
+
{"item": "SQL injection prevented", "status": "passed"},
|
|
43
|
+
{"item": "Authentication tokens secured", "status": "failed"}
|
|
44
|
+
],
|
|
45
|
+
"securityDebt": [
|
|
46
|
+
"Consider adding rate limiting in future iteration"
|
|
47
|
+
],
|
|
48
|
+
"approved": true,
|
|
49
|
+
"blockers": []
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
**Severity levels:** critical, high, medium, low, info
|
|
53
|
+
**Status values:** passed, failed, na
|
|
54
|
+
|
|
55
|
+
Critical and high severity findings should set approved: false and be listed in blockers.
|
|
@@ -1,34 +1,27 @@
|
|
|
1
1
|
---
|
|
2
2
|
model: med
|
|
3
3
|
format: json
|
|
4
|
+
description: "Pre-code phase: Analyzes security risks before implementation starts"
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
# Security Reviewer Agent
|
|
7
|
+
# Pre-Code Security Reviewer Agent
|
|
7
8
|
|
|
8
|
-
You are a security
|
|
9
|
+
You are a security threat analyst. Analyze tasks BEFORE implementation to identify security risks and recommend secure patterns.
|
|
9
10
|
|
|
10
11
|
## Instructions
|
|
11
12
|
|
|
12
|
-
Perform a security
|
|
13
|
+
Perform a pre-implementation security analysis:
|
|
13
14
|
|
|
14
|
-
**Pre-Implementation Review (stage: pre-implementation):**
|
|
15
15
|
- Identify potential security concerns for the task
|
|
16
16
|
- Recommend secure implementation patterns
|
|
17
17
|
- Flag any high-risk areas requiring extra attention
|
|
18
18
|
- Suggest security tests to include
|
|
19
19
|
|
|
20
|
-
**Post-Implementation Review (stage: post-implementation):**
|
|
21
|
-
- Review the implementation for security issues
|
|
22
|
-
- Check for common vulnerabilities (OWASP Top 10)
|
|
23
|
-
- Verify secure coding practices
|
|
24
|
-
- Identify any remaining security debt
|
|
25
|
-
|
|
26
20
|
## Output Format
|
|
27
21
|
|
|
28
22
|
Return a valid JSON object:
|
|
29
23
|
|
|
30
24
|
{
|
|
31
|
-
"stage": "pre-implementation",
|
|
32
25
|
"riskLevel": "low",
|
|
33
26
|
"findings": [
|
|
34
27
|
{
|
|
@@ -43,6 +36,10 @@ Return a valid JSON object:
|
|
|
43
36
|
{"item": "Use parameterized queries", "status": "pending"},
|
|
44
37
|
{"item": "Implement rate limiting", "status": "na"}
|
|
45
38
|
],
|
|
39
|
+
"suggestedTests": [
|
|
40
|
+
"Test for SQL injection with malicious input",
|
|
41
|
+
"Verify authentication token validation"
|
|
42
|
+
],
|
|
46
43
|
"approved": true,
|
|
47
44
|
"blockers": []
|
|
48
45
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
model: fast
|
|
3
|
+
format: json
|
|
4
|
+
description: "Verify phase: Generates conventional commit message after task completion"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Commit Message Generator Agent
|
|
8
|
+
|
|
9
|
+
You generate conventional commit messages for completed tasks.
|
|
10
|
+
|
|
11
|
+
## Input
|
|
12
|
+
- task: { title, description }
|
|
13
|
+
- filesWritten: Array of { path, purpose } for files created/modified
|
|
14
|
+
|
|
15
|
+
## Output Format
|
|
16
|
+
|
|
17
|
+
Return a valid JSON object:
|
|
18
|
+
|
|
19
|
+
{
|
|
20
|
+
"type": "feat",
|
|
21
|
+
"scope": "auth",
|
|
22
|
+
"message": "add user login functionality",
|
|
23
|
+
"body": "Implements login form with email/password validation.\nAdds JWT token storage and refresh logic."
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
## Commit Type Guidelines
|
|
27
|
+
|
|
28
|
+
- **feat**: New feature for the user
|
|
29
|
+
- **fix**: Bug fix for the user
|
|
30
|
+
- **refactor**: Code change that neither fixes a bug nor adds a feature
|
|
31
|
+
- **test**: Adding or updating tests
|
|
32
|
+
- **docs**: Documentation only changes
|
|
33
|
+
- **style**: Formatting, missing semicolons, etc (no code change)
|
|
34
|
+
- **chore**: Updating build tasks, configs, etc
|
|
35
|
+
|
|
36
|
+
## Message Guidelines
|
|
37
|
+
|
|
38
|
+
- Use imperative mood ("add" not "added" or "adds")
|
|
39
|
+
- Keep first line under 72 characters
|
|
40
|
+
- Scope is optional but recommended (component/module name)
|
|
41
|
+
- Body should explain what and why, not how
|
|
42
|
+
- Reference file changes in body when helpful
|
|
43
|
+
|
|
44
|
+
## Examples
|
|
45
|
+
|
|
46
|
+
Task: "Implement user authentication"
|
|
47
|
+
Files: [{ path: "src/auth.js", purpose: "Auth module" }]
|
|
48
|
+
Output:
|
|
49
|
+
{
|
|
50
|
+
"type": "feat",
|
|
51
|
+
"scope": "auth",
|
|
52
|
+
"message": "implement user authentication",
|
|
53
|
+
"body": "Adds login/logout functionality with JWT tokens.\n\nFiles:\n- src/auth.js: Core auth module"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
Task: "Fix login validation bug"
|
|
57
|
+
Files: [{ path: "src/auth.js", purpose: "Fix validation" }]
|
|
58
|
+
Output:
|
|
59
|
+
{
|
|
60
|
+
"type": "fix",
|
|
61
|
+
"scope": "auth",
|
|
62
|
+
"message": "correct email validation regex",
|
|
63
|
+
"body": "Email validation was rejecting valid addresses with + symbols."
|
|
64
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model: fast
|
|
3
3
|
format: json
|
|
4
|
+
description: "Verify phase: Generates executable sanity checks to validate implementation"
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
You generate executable sanity checks for the implemented task.
|
|
@@ -37,15 +38,3 @@ Guidelines:
|
|
|
37
38
|
- Include at least one file_exists or file_contains check when files are created/modified.
|
|
38
39
|
- If tests exist (from testPlan or implementation), include a type "test_suite" check.
|
|
39
40
|
- Use testFramework.command for running tests (optionally target specific files when possible).
|
|
40
|
-
|
|
41
|
-
Task:
|
|
42
|
-
{{task}}
|
|
43
|
-
|
|
44
|
-
Implementation:
|
|
45
|
-
{{implementation}}
|
|
46
|
-
|
|
47
|
-
Test Plan:
|
|
48
|
-
{{testPlan}}
|
|
49
|
-
|
|
50
|
-
Test Framework:
|
|
51
|
-
{{testFramework}}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export const config = {
|
|
2
2
|
models: {
|
|
3
|
-
fast: "gemini
|
|
4
|
-
low: "gemini
|
|
5
|
-
med: "gemini
|
|
6
|
-
high: "gemini
|
|
3
|
+
fast: "gemini-2.5-flash",
|
|
4
|
+
low: "gemini-2.5-flash",
|
|
5
|
+
med: "gemini-2.5-flash",
|
|
6
|
+
high: "gemini-2.5-flash",
|
|
7
7
|
},
|
|
8
8
|
apiKeys: {
|
|
9
9
|
gemini: process.env.GEMINI_API_KEY,
|
|
@@ -11,6 +11,17 @@ export const config = {
|
|
|
11
11
|
openai: process.env.OPENAI_API_KEY,
|
|
12
12
|
},
|
|
13
13
|
|
|
14
|
+
// CLI permission modes - enables native file access for agents
|
|
15
|
+
cliPermissions: {
|
|
16
|
+
claude: 'bypassPermissions', // --permission-mode bypassPermissions
|
|
17
|
+
gemini: 'full', // --approval-mode full
|
|
18
|
+
codex: 'bypass' // --dangerously-bypass-approvals-and-sandbox
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
// Protected paths - prevents DELETION only (modifications allowed)
|
|
22
|
+
// Files matching these patterns cannot be deleted by agents
|
|
23
|
+
protectedPaths: ['.env', '.env.*', 'package.json'],
|
|
24
|
+
|
|
14
25
|
// File tracking (all optional - shown with defaults)
|
|
15
26
|
// projectRoot: process.env.PROJECT_ROOT, // Defaults to ../.. from workflow
|
|
16
27
|
// fileTracking: true, // Enable/disable file tracking
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Try to auto-fix common validation issues
|
|
5
|
+
* @param {string} projectRoot - Project root directory
|
|
6
|
+
* @param {string[]} violations - Array of violation messages
|
|
7
|
+
* @returns {string[]} Array of fixes applied
|
|
8
|
+
*/
|
|
9
|
+
export function autoFixValidationIssues(projectRoot, violations) {
|
|
10
|
+
const fixed = [];
|
|
11
|
+
|
|
12
|
+
for (const violation of violations) {
|
|
13
|
+
if (violation.includes('agent-state-machine')) {
|
|
14
|
+
// Re-install the dependency
|
|
15
|
+
try {
|
|
16
|
+
execSync('npm install agent-state-machine', { cwd: projectRoot, stdio: 'pipe' });
|
|
17
|
+
fixed.push('Reinstalled agent-state-machine');
|
|
18
|
+
} catch (e) {
|
|
19
|
+
// Will fall through to rollback
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return fixed;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Rollback a file using git checkout
|
|
29
|
+
* @param {string} projectRoot - Project root directory
|
|
30
|
+
* @param {string} filePath - File path to rollback (relative to projectRoot)
|
|
31
|
+
* @returns {{ success: boolean, error?: string }}
|
|
32
|
+
*/
|
|
33
|
+
export function rollbackFile(projectRoot, filePath) {
|
|
34
|
+
try {
|
|
35
|
+
execSync(`git checkout -- "${filePath}"`, { cwd: projectRoot, stdio: 'pipe' });
|
|
36
|
+
return { success: true };
|
|
37
|
+
} catch (e) {
|
|
38
|
+
return { success: false, error: e.message };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File: /templates/project-builder/scripts/validate-changes.js
|
|
3
|
+
*
|
|
4
|
+
* Project-builder specific validation for file changes.
|
|
5
|
+
* Checks constraints that are specific to this workflow template.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Validate project-builder specific constraints after file changes.
|
|
13
|
+
* - package.json: agent-state-machine dependency must not be removed
|
|
14
|
+
* - Additions and other modifications are allowed
|
|
15
|
+
*
|
|
16
|
+
* @param {string} projectRoot - The project root directory
|
|
17
|
+
* @param {Object} changes - Detected changes { created, modified, deleted, renamed }
|
|
18
|
+
* @returns {{ valid: boolean, violations: string[] }}
|
|
19
|
+
*/
|
|
20
|
+
export function validateProjectChanges(projectRoot, changes) {
|
|
21
|
+
const violations = [];
|
|
22
|
+
|
|
23
|
+
// Check package.json modifications (not deletions - that's handled by core protectedPaths)
|
|
24
|
+
if ((changes.modified || []).includes('package.json')) {
|
|
25
|
+
const pkgPath = path.resolve(projectRoot, 'package.json');
|
|
26
|
+
if (fs.existsSync(pkgPath)) {
|
|
27
|
+
try {
|
|
28
|
+
const content = fs.readFileSync(pkgPath, 'utf-8');
|
|
29
|
+
// Only flag if agent-state-machine was removed entirely
|
|
30
|
+
// This allows adding/updating other dependencies
|
|
31
|
+
if (!content.includes('agent-state-machine')) {
|
|
32
|
+
violations.push('package.json: agent-state-machine dependency was removed (not allowed)');
|
|
33
|
+
}
|
|
34
|
+
} catch (err) {
|
|
35
|
+
console.warn(`[validate-changes] Failed to read package.json: ${err.message}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return { valid: violations.length === 0, violations };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Check if package.json still has agent-state-machine dependency.
|
|
45
|
+
* Utility for checking after any file write operation.
|
|
46
|
+
*
|
|
47
|
+
* @param {string} projectRoot - The project root directory
|
|
48
|
+
* @returns {boolean} - True if dependency is present
|
|
49
|
+
*/
|
|
50
|
+
export function hasAgentStateMachine(projectRoot) {
|
|
51
|
+
const pkgPath = path.resolve(projectRoot, 'package.json');
|
|
52
|
+
if (!fs.existsSync(pkgPath)) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const content = fs.readFileSync(pkgPath, 'utf-8');
|
|
57
|
+
return content.includes('agent-state-machine');
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -1,40 +1,8 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
3
4
|
import { memory, getCurrentRuntime } from 'agent-state-machine';
|
|
4
5
|
|
|
5
|
-
// Write implementation files from code-writer agent output
|
|
6
|
-
function writeImplementationFiles(implementation) {
|
|
7
|
-
const runtime = getCurrentRuntime();
|
|
8
|
-
if (!runtime) {
|
|
9
|
-
throw new Error('writeImplementationFiles must be called within a workflow context');
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const projectRoot = runtime.workflowConfig.projectRoot;
|
|
13
|
-
const files = implementation?.implementation?.files || implementation?.files || [];
|
|
14
|
-
const written = [];
|
|
15
|
-
|
|
16
|
-
for (const file of files) {
|
|
17
|
-
if (!file.path || !file.code) {
|
|
18
|
-
console.warn(` [File] Skipping invalid file entry: ${JSON.stringify(file)}`);
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const fullPath = path.resolve(projectRoot, file.path);
|
|
23
|
-
|
|
24
|
-
// Ensure directory exists
|
|
25
|
-
const dir = path.dirname(fullPath);
|
|
26
|
-
if (!fs.existsSync(dir)) {
|
|
27
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
fs.writeFileSync(fullPath, file.code);
|
|
31
|
-
written.push(file.path);
|
|
32
|
-
console.log(` [File] Created: ${file.path}`);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return written;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
6
|
// Write markdown file to workflow state directory
|
|
39
7
|
function writeMarkdownFile(stateDir, filename, content) {
|
|
40
8
|
if (!fs.existsSync(stateDir)) fs.mkdirSync(stateDir, { recursive: true });
|
|
@@ -205,9 +173,90 @@ function detectTestFramework() {
|
|
|
205
173
|
return { framework: 'vitest', command: 'npx vitest run', isDefault: true };
|
|
206
174
|
}
|
|
207
175
|
|
|
176
|
+
// Git-based file awareness helpers
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Get list of all tracked files in the project
|
|
180
|
+
* @param {string} projectRoot - Project root directory
|
|
181
|
+
* @returns {string[]} Array of file paths
|
|
182
|
+
*/
|
|
183
|
+
function getProjectFiles(projectRoot) {
|
|
184
|
+
try {
|
|
185
|
+
const stdout = execSync('git ls-files', {
|
|
186
|
+
cwd: projectRoot,
|
|
187
|
+
encoding: 'utf-8'
|
|
188
|
+
});
|
|
189
|
+
return stdout.trim().split('\n').filter(Boolean);
|
|
190
|
+
} catch {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Create a git commit with the specified message
|
|
197
|
+
* @param {string} projectRoot - Project root directory
|
|
198
|
+
* @param {string} message - Commit message (can be multi-line)
|
|
199
|
+
* @param {string[]} files - Optional specific files to stage (stages all if empty)
|
|
200
|
+
* @returns {{ success: boolean, hash?: string, error?: string }}
|
|
201
|
+
*/
|
|
202
|
+
function createGitCommit(projectRoot, message, files = []) {
|
|
203
|
+
try {
|
|
204
|
+
// Stage files
|
|
205
|
+
if (files.length > 0) {
|
|
206
|
+
// Quote file paths to handle spaces
|
|
207
|
+
const quotedFiles = files.map(f => `"${f}"`).join(' ');
|
|
208
|
+
execSync(`git add ${quotedFiles}`, { cwd: projectRoot, stdio: 'pipe' });
|
|
209
|
+
} else {
|
|
210
|
+
execSync('git add -A', { cwd: projectRoot, stdio: 'pipe' });
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Check if there are staged changes
|
|
214
|
+
const status = execSync('git diff --cached --name-only', {
|
|
215
|
+
cwd: projectRoot,
|
|
216
|
+
encoding: 'utf-8'
|
|
217
|
+
}).trim();
|
|
218
|
+
|
|
219
|
+
if (!status) {
|
|
220
|
+
return { success: false, error: 'No changes to commit' };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Commit using stdin to avoid shell escaping issues
|
|
224
|
+
execSync('git commit -F -', {
|
|
225
|
+
cwd: projectRoot,
|
|
226
|
+
input: message,
|
|
227
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// Get commit hash
|
|
231
|
+
const hash = execSync('git rev-parse --short HEAD', {
|
|
232
|
+
cwd: projectRoot,
|
|
233
|
+
encoding: 'utf-8'
|
|
234
|
+
}).trim();
|
|
235
|
+
|
|
236
|
+
return { success: true, hash };
|
|
237
|
+
} catch (error) {
|
|
238
|
+
return { success: false, error: error.message };
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Ensure a git repository exists at the project root
|
|
244
|
+
* @param {string} projectRoot - Project root directory
|
|
245
|
+
* @returns {{ initialized: boolean, message: string }}
|
|
246
|
+
*/
|
|
247
|
+
function ensureGitRepo(projectRoot) {
|
|
248
|
+
try {
|
|
249
|
+
execSync('git rev-parse --git-dir', { cwd: projectRoot, stdio: 'pipe' });
|
|
250
|
+
return { initialized: false, message: 'Git repo already exists' };
|
|
251
|
+
} catch {
|
|
252
|
+
// Not a git repo, initialize it
|
|
253
|
+
execSync('git init', { cwd: projectRoot, stdio: 'pipe' });
|
|
254
|
+
return { initialized: true, message: 'Git repo initialized' };
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
208
258
|
export {
|
|
209
259
|
writeMarkdownFile,
|
|
210
|
-
writeImplementationFiles,
|
|
211
260
|
isApproval,
|
|
212
261
|
renderRoadmapMarkdown,
|
|
213
262
|
renderTasksMarkdown,
|
|
@@ -220,5 +269,8 @@ export {
|
|
|
220
269
|
getQuickFixAttempts,
|
|
221
270
|
incrementQuickFixAttempts,
|
|
222
271
|
resetQuickFixAttempts,
|
|
223
|
-
detectTestFramework
|
|
272
|
+
detectTestFramework,
|
|
273
|
+
getProjectFiles,
|
|
274
|
+
createGitCommit,
|
|
275
|
+
ensureGitRepo
|
|
224
276
|
};
|