software-engineer 0.1.13 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/claude.js +6 -20
- package/dist/pipeline.js +21 -9
- package/dist/steps/branchManagement.js +1 -1
- package/dist/steps/changelog.js +1 -1
- package/dist/steps/commit.js +1 -1
- package/dist/steps/implement.js +3 -4
- package/dist/steps/index.d.ts +1 -0
- package/dist/steps/index.js +1 -0
- package/dist/steps/review.js +1 -1
- package/dist/steps/simplify.js +1 -1
- package/dist/steps/solid.js +1 -1
- package/dist/steps/test.js +1 -1
- package/dist/steps/understand.d.ts +2 -0
- package/dist/steps/understand.js +100 -0
- package/package.json +1 -1
package/dist/claude.js
CHANGED
|
@@ -21,29 +21,15 @@ export async function runClaude(options, config) {
|
|
|
21
21
|
}
|
|
22
22
|
logInfo('Calling Claude...');
|
|
23
23
|
return new Promise((resolve) => {
|
|
24
|
-
let capturedOutput = '';
|
|
25
24
|
// Spawn Claude using child_process
|
|
26
|
-
// Use 'inherit' for
|
|
27
|
-
//
|
|
25
|
+
// Use 'inherit' for all stdio to allow Claude's interactive UI to work properly
|
|
26
|
+
// Claude CLI requires a TTY for its rich terminal features (spinners, progress, etc.)
|
|
27
|
+
// Piping stdout/stderr causes Claude to detect non-TTY and buffer/disable output
|
|
28
28
|
const child = spawn('claude', args, {
|
|
29
29
|
cwd: process.cwd(),
|
|
30
30
|
env: process.env,
|
|
31
|
-
stdio:
|
|
31
|
+
stdio: 'inherit',
|
|
32
32
|
});
|
|
33
|
-
// Capture and pass through stdout
|
|
34
|
-
if (child.stdout) {
|
|
35
|
-
child.stdout.on('data', (data) => {
|
|
36
|
-
const text = data.toString();
|
|
37
|
-
process.stdout.write(text);
|
|
38
|
-
capturedOutput += text;
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
// Capture and pass through stderr
|
|
42
|
-
if (child.stderr) {
|
|
43
|
-
child.stderr.on('data', (data) => {
|
|
44
|
-
process.stderr.write(data.toString());
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
33
|
// Handle process exit
|
|
48
34
|
child.on('close', (exitCode) => {
|
|
49
35
|
if (exitCode === EXIT_INTERRUPTED || exitCode === 2) {
|
|
@@ -52,11 +38,11 @@ export async function runClaude(options, config) {
|
|
|
52
38
|
}
|
|
53
39
|
else if (exitCode === EXIT_SUCCESS) {
|
|
54
40
|
logSuccess('Claude completed');
|
|
55
|
-
resolve({ success: true, output:
|
|
41
|
+
resolve({ success: true, output: '' });
|
|
56
42
|
}
|
|
57
43
|
else {
|
|
58
44
|
logError(`Claude exited with code ${exitCode}`);
|
|
59
|
-
resolve({ success: false, output:
|
|
45
|
+
resolve({ success: false, output: '' });
|
|
60
46
|
}
|
|
61
47
|
});
|
|
62
48
|
// Handle spawn errors
|
package/dist/pipeline.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { log, logHeader, setLogFile, logInfo } from './logger.js';
|
|
3
|
-
import { stepBranchManagement, stepImplement, stepSimplify, stepReview, stepSolidCleanCode, stepTest, stepCommit, stepChangelog, } from './steps/index.js';
|
|
3
|
+
import { stepBranchManagement, stepUnderstandCodebase, stepImplement, stepSimplify, stepReview, stepSolidCleanCode, stepTest, stepCommit, stepChangelog, } from './steps/index.js';
|
|
4
4
|
let signalHandlersRegistered = false;
|
|
5
5
|
export async function runPipeline(config) {
|
|
6
6
|
// Setup logging
|
|
@@ -31,13 +31,19 @@ export async function runPipeline(config) {
|
|
|
31
31
|
// Extract adaptive analysis for step decisions
|
|
32
32
|
const adaptive = branchResult.adaptiveAnalysis;
|
|
33
33
|
const rec = adaptive?.stepRecommendation;
|
|
34
|
-
// Step 2:
|
|
34
|
+
// Step 2: Understand Codebase
|
|
35
|
+
const understandSuccess = await stepUnderstandCodebase(config);
|
|
36
|
+
if (!understandSuccess) {
|
|
37
|
+
console.log(chalk.red('\nUnderstand codebase step failed. Exiting.'));
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
// Step 3: Implement
|
|
35
41
|
const implSuccess = await stepImplement(config);
|
|
36
42
|
if (!implSuccess) {
|
|
37
43
|
console.log(chalk.red('\nImplementation step failed. Exiting.'));
|
|
38
44
|
process.exit(1);
|
|
39
45
|
}
|
|
40
|
-
// Step
|
|
46
|
+
// Step 4: Simplify (can be skipped by adaptive execution)
|
|
41
47
|
if (rec?.skipSimplify) {
|
|
42
48
|
logInfo('Simplify step skipped (adaptive execution)');
|
|
43
49
|
}
|
|
@@ -48,7 +54,7 @@ export async function runPipeline(config) {
|
|
|
48
54
|
process.exit(1);
|
|
49
55
|
}
|
|
50
56
|
}
|
|
51
|
-
// Step
|
|
57
|
+
// Step 5: Review loop (can be skipped or adjusted by adaptive execution)
|
|
52
58
|
if (rec?.skipReview) {
|
|
53
59
|
logInfo('Review step skipped (adaptive execution)');
|
|
54
60
|
}
|
|
@@ -67,7 +73,7 @@ export async function runPipeline(config) {
|
|
|
67
73
|
}
|
|
68
74
|
}
|
|
69
75
|
}
|
|
70
|
-
// Step
|
|
76
|
+
// Step 6: SOLID & Clean Code (can be skipped by adaptive execution)
|
|
71
77
|
if (rec?.skipSolid) {
|
|
72
78
|
logInfo('SOLID review step skipped (adaptive execution)');
|
|
73
79
|
}
|
|
@@ -78,8 +84,14 @@ export async function runPipeline(config) {
|
|
|
78
84
|
process.exit(1);
|
|
79
85
|
}
|
|
80
86
|
}
|
|
81
|
-
// Step
|
|
82
|
-
|
|
87
|
+
// Step 7: Test (can be skipped by adaptive execution or CLI flag)
|
|
88
|
+
let skipTestsReason = null;
|
|
89
|
+
if (rec?.skipTests) {
|
|
90
|
+
skipTestsReason = 'adaptive execution';
|
|
91
|
+
}
|
|
92
|
+
else if (config.skipTests) {
|
|
93
|
+
skipTestsReason = '--skip-tests';
|
|
94
|
+
}
|
|
83
95
|
if (skipTestsReason) {
|
|
84
96
|
logInfo(`Test step skipped (${skipTestsReason})`);
|
|
85
97
|
}
|
|
@@ -90,13 +102,13 @@ export async function runPipeline(config) {
|
|
|
90
102
|
process.exit(1);
|
|
91
103
|
}
|
|
92
104
|
}
|
|
93
|
-
// Step
|
|
105
|
+
// Step 8: Commit
|
|
94
106
|
const commitSuccess = await stepCommit(config);
|
|
95
107
|
if (!commitSuccess) {
|
|
96
108
|
console.log(chalk.red('\nCommit step failed. Exiting.'));
|
|
97
109
|
process.exit(1);
|
|
98
110
|
}
|
|
99
|
-
// Step
|
|
111
|
+
// Step 9: Changelog (can be skipped by adaptive execution)
|
|
100
112
|
if (rec?.skipChangelog) {
|
|
101
113
|
logInfo('Changelog step skipped (adaptive execution)');
|
|
102
114
|
}
|
|
@@ -46,7 +46,7 @@ function branchMatchesRequirement(currentBranch, analysis) {
|
|
|
46
46
|
return overlap || (prefixMatches && suggestedKeywords.length === 0);
|
|
47
47
|
}
|
|
48
48
|
export async function stepBranchManagement(config) {
|
|
49
|
-
logStep('1/
|
|
49
|
+
logStep('1/9', 'SMART BRANCH MANAGEMENT');
|
|
50
50
|
const adaptiveAnalysis = config.adaptiveExecution ? await performAdaptiveAnalysis(config) : null;
|
|
51
51
|
if (config.skipBranchManagement) {
|
|
52
52
|
logInfo('Branch management skipped (--skip-branch-management)');
|
package/dist/steps/changelog.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { logStep } from '../logger.js';
|
|
2
2
|
import { runClaude } from '../claude.js';
|
|
3
3
|
export async function stepChangelog(config) {
|
|
4
|
-
logStep('
|
|
4
|
+
logStep('9/9', 'UPDATE CHANGELOG');
|
|
5
5
|
const prompt = `Update CHANGELOG.md:
|
|
6
6
|
|
|
7
7
|
## Format (Keep a Changelog):
|
package/dist/steps/commit.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { logStep } from '../logger.js';
|
|
2
2
|
import { runClaude } from '../claude.js';
|
|
3
3
|
export async function stepCommit(config) {
|
|
4
|
-
logStep('
|
|
4
|
+
logStep('8/9', 'COMMIT CHANGES');
|
|
5
5
|
const pushInstruction = config.skipPush ? '' : 'Then push to remote.';
|
|
6
6
|
const prompt = `Commit the changes:
|
|
7
7
|
|
package/dist/steps/implement.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { logStep } from '../logger.js';
|
|
2
2
|
import { runClaude } from '../claude.js';
|
|
3
3
|
export async function stepImplement(config) {
|
|
4
|
-
logStep('
|
|
4
|
+
logStep('3/9', 'IMPLEMENT REQUIREMENT');
|
|
5
5
|
const prompt = `${config.requirement}
|
|
6
6
|
|
|
7
7
|
## Implementation Guidelines:
|
|
8
|
-
- Understand the existing codebase structure first
|
|
9
8
|
- Write clean, idiomatic code following project conventions
|
|
10
9
|
- Handle edge cases and errors appropriately
|
|
11
10
|
- Add necessary comments for complex logic
|
|
12
|
-
- Keep changes focused and minimal
|
|
13
|
-
const result = await runClaude({ prompt }, config);
|
|
11
|
+
- Keep changes focused and minimal. Once the work is completed, exit.`;
|
|
12
|
+
const result = await runClaude({ prompt, continueConversation: true }, config);
|
|
14
13
|
return result.success;
|
|
15
14
|
}
|
package/dist/steps/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { stepBranchManagement, type BranchResult } from './branchManagement.js';
|
|
2
|
+
export { stepUnderstandCodebase } from './understand.js';
|
|
2
3
|
export { stepImplement } from './implement.js';
|
|
3
4
|
export { stepSimplify } from './simplify.js';
|
|
4
5
|
export { stepReview, type ReviewResult, type ReviewDepth } from './review.js';
|
package/dist/steps/index.js
CHANGED
package/dist/steps/review.js
CHANGED
|
@@ -60,7 +60,7 @@ function getPromptForDepth(depth) {
|
|
|
60
60
|
}
|
|
61
61
|
export async function stepReview(iteration, config, depth = 'standard') {
|
|
62
62
|
const depthLabel = depth !== 'standard' ? ` [${depth}]` : '';
|
|
63
|
-
logStep('
|
|
63
|
+
logStep('5/9', `CODE REVIEW (Round ${iteration}/${config.reviewIterations})${depthLabel}`);
|
|
64
64
|
const prompt = getPromptForDepth(depth);
|
|
65
65
|
const result = await runClaude({ prompt, continueConversation: true }, config);
|
|
66
66
|
const noIssuesFound = result.success && detectNoIssues(result.output);
|
package/dist/steps/simplify.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { logStep } from '../logger.js';
|
|
2
2
|
import { runClaude } from '../claude.js';
|
|
3
3
|
export async function stepSimplify(config) {
|
|
4
|
-
logStep('
|
|
4
|
+
logStep('4/9', 'CODE SIMPLIFICATION');
|
|
5
5
|
const prompt = `Refine the recently modified code for clarity, consistency, and maintainability while preserving all functionality.
|
|
6
6
|
|
|
7
7
|
## Core Principles:
|
package/dist/steps/solid.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { logStep } from '../logger.js';
|
|
2
2
|
import { runClaude } from '../claude.js';
|
|
3
3
|
export async function stepSolidCleanCode(config) {
|
|
4
|
-
logStep('
|
|
4
|
+
logStep('6/9', 'SOLID PRINCIPLES & CLEAN CODE');
|
|
5
5
|
const prompt = `Review the code for SOLID principles and Clean Code compliance:
|
|
6
6
|
|
|
7
7
|
## SOLID Principles:
|
package/dist/steps/test.js
CHANGED
|
@@ -2,7 +2,7 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { logStep } from '../logger.js';
|
|
3
3
|
import { runClaude } from '../claude.js';
|
|
4
4
|
export async function stepTest(config) {
|
|
5
|
-
logStep('
|
|
5
|
+
logStep('7/9', 'TESTING');
|
|
6
6
|
if (config.skipTests) {
|
|
7
7
|
console.log(chalk.yellow('[SKIPPED]') + ' Testing step skipped via configuration');
|
|
8
8
|
return true;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { logStep } from '../logger.js';
|
|
2
|
+
import { runClaude } from '../claude.js';
|
|
3
|
+
const UNDERSTAND_CODEBASE_PROMPT = `Goal
|
|
4
|
+
Build an internal map of the codebase. Do not change code. Do not refactor. Do not optimize.
|
|
5
|
+
|
|
6
|
+
Operating mode
|
|
7
|
+
Static analysis first. Minimal assumptions. Prefer certainty over completeness.
|
|
8
|
+
|
|
9
|
+
Required steps
|
|
10
|
+
|
|
11
|
+
1. Detect codebase type
|
|
12
|
+
|
|
13
|
+
* Language(s)
|
|
14
|
+
* Runtime
|
|
15
|
+
* Frameworks
|
|
16
|
+
* Monorepo or single service
|
|
17
|
+
|
|
18
|
+
2. Identify execution roots
|
|
19
|
+
|
|
20
|
+
* Primary entry files
|
|
21
|
+
* CLI commands
|
|
22
|
+
* Server startup paths
|
|
23
|
+
* Test runners
|
|
24
|
+
|
|
25
|
+
3. Build directory graph
|
|
26
|
+
|
|
27
|
+
* Top level folders
|
|
28
|
+
* Purpose of each folder
|
|
29
|
+
* Ownership boundaries if visible
|
|
30
|
+
|
|
31
|
+
4. Dependency flow analysis
|
|
32
|
+
|
|
33
|
+
* Module import graph
|
|
34
|
+
* Direction of dependencies
|
|
35
|
+
* Shared utilities vs feature code
|
|
36
|
+
|
|
37
|
+
5. Architecture inference
|
|
38
|
+
|
|
39
|
+
* Architectural style if evident
|
|
40
|
+
* Layer boundaries
|
|
41
|
+
* Cross layer violations
|
|
42
|
+
|
|
43
|
+
6. State and data flow
|
|
44
|
+
|
|
45
|
+
* Where state lives
|
|
46
|
+
* How data moves between modules
|
|
47
|
+
* Persistence boundaries
|
|
48
|
+
|
|
49
|
+
7. External interfaces
|
|
50
|
+
|
|
51
|
+
* APIs exposed
|
|
52
|
+
* APIs consumed
|
|
53
|
+
* Databases, queues, filesystems
|
|
54
|
+
|
|
55
|
+
8. Configuration and environment
|
|
56
|
+
|
|
57
|
+
* Config files
|
|
58
|
+
* Environment variables
|
|
59
|
+
* Feature flags
|
|
60
|
+
|
|
61
|
+
9. Change impact map
|
|
62
|
+
|
|
63
|
+
* High blast radius files
|
|
64
|
+
* Core abstractions
|
|
65
|
+
* Unsafe modification zones
|
|
66
|
+
|
|
67
|
+
10. Gaps and unknowns
|
|
68
|
+
|
|
69
|
+
* Missing docs
|
|
70
|
+
* Ambiguous responsibilities
|
|
71
|
+
* Implicit behavior
|
|
72
|
+
|
|
73
|
+
Output format
|
|
74
|
+
|
|
75
|
+
* Use structured bullet points
|
|
76
|
+
* Use short phrases, not prose
|
|
77
|
+
* Use file paths when referencing code
|
|
78
|
+
* Flag assumptions explicitly
|
|
79
|
+
* End with a one page mental model of the system
|
|
80
|
+
|
|
81
|
+
Constraints
|
|
82
|
+
|
|
83
|
+
* No code edits
|
|
84
|
+
* No speculative refactors
|
|
85
|
+
* No style commentary
|
|
86
|
+
* No opinions unless clearly labeled as inference
|
|
87
|
+
|
|
88
|
+
Primary objective
|
|
89
|
+
Enable safe future modifications by maximizing structural understanding.`;
|
|
90
|
+
export async function stepUnderstandCodebase(config) {
|
|
91
|
+
logStep('2/9', 'UNDERSTAND CODEBASE');
|
|
92
|
+
const prompt = `${UNDERSTAND_CODEBASE_PROMPT}
|
|
93
|
+
|
|
94
|
+
Context: I need to understand this codebase to implement the following requirement:
|
|
95
|
+
${config.requirement}
|
|
96
|
+
|
|
97
|
+
Focus your analysis on areas most relevant to this requirement while still building a complete mental model.`;
|
|
98
|
+
const result = await runClaude({ prompt }, config);
|
|
99
|
+
return result.success;
|
|
100
|
+
}
|
package/package.json
CHANGED