software-engineer 0.1.23 → 0.1.24
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/README.md +46 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +10 -0
- package/dist/index.js +24 -4
- package/dist/pipeline.js +72 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,11 @@ A CLI tool that automates the software development workflow using Claude AI. It
|
|
|
4
4
|
|
|
5
5
|
By default, Claude is automatically granted permission to **Edit, Read, and Bash** tools, allowing seamless autonomous operation without constant permission prompts.
|
|
6
6
|
|
|
7
|
+
|
|
8
|
+
## The Brain
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
7
12
|
## Installation
|
|
8
13
|
|
|
9
14
|
```bash
|
|
@@ -104,6 +109,39 @@ sf --dangerously-skip-permissions "implement feature"
|
|
|
104
109
|
|
|
105
110
|
**Note**: When `--dangerously-skip-permissions` is used, the `allowedTools` setting is ignored.
|
|
106
111
|
|
|
112
|
+
## Run Individual Stages
|
|
113
|
+
|
|
114
|
+
You can run specific pipeline stages directly without executing the full pipeline. This is useful for running a quick review or cleanup on code you've already written.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Run only the code simplification step
|
|
118
|
+
sf --simplify
|
|
119
|
+
|
|
120
|
+
# Run only the code review step
|
|
121
|
+
sf --review
|
|
122
|
+
|
|
123
|
+
# Run only the SOLID & clean code check
|
|
124
|
+
sf --clean-code
|
|
125
|
+
|
|
126
|
+
# Run only the testing step
|
|
127
|
+
sf --test
|
|
128
|
+
|
|
129
|
+
# Run only the commit step
|
|
130
|
+
sf --commit
|
|
131
|
+
|
|
132
|
+
# Run only the implementation step (requires a requirement)
|
|
133
|
+
sf --implement "add error handling to the API"
|
|
134
|
+
|
|
135
|
+
# Combine multiple stages (executed in pipeline order)
|
|
136
|
+
sf --simplify --review --clean-code
|
|
137
|
+
|
|
138
|
+
# Works with other options
|
|
139
|
+
sf --review -r 3 # 3 review iterations
|
|
140
|
+
sf --review --dry-run # Preview without executing
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Note**: All stages except `--implement` work without a requirement — they operate on the current state of your code. You can combine multiple stage flags and they will run in pipeline order.
|
|
144
|
+
|
|
107
145
|
## Options
|
|
108
146
|
|
|
109
147
|
| Option | Description |
|
|
@@ -114,6 +152,14 @@ sf --dangerously-skip-permissions "implement feature"
|
|
|
114
152
|
| `--skip-tests` | Skip the testing step |
|
|
115
153
|
| `--skip-push` | Commit but don't push to remote |
|
|
116
154
|
| `--skip-branch-management` | Skip smart branch management |
|
|
155
|
+
| `--implementation-only` | Run only: Implement → Review → SOLID |
|
|
156
|
+
| `--implement` | Run only the implementation step |
|
|
157
|
+
| `--simplify` | Run only the code simplification step |
|
|
158
|
+
| `--review` | Run only the code review step |
|
|
159
|
+
| `--clean-code` | Run only the SOLID & clean code step |
|
|
160
|
+
| `--test` | Run only the testing step |
|
|
161
|
+
| `--commit` | Run only the commit step |
|
|
162
|
+
| `--changelog` | Run only the changelog step |
|
|
117
163
|
| `--log <file>` | Log output to file |
|
|
118
164
|
| `--allowedTools <tools>` | Comma-separated list of allowed tools (default: "Edit,Read,Bash") |
|
|
119
165
|
| `--dangerously-skip-permissions` | Skip Claude permission prompts (overrides allowedTools) |
|
package/dist/config.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export declare const VALID_STAGES: readonly ["implement", "simplify", "review", "clean-code", "test", "commit", "changelog"];
|
|
2
|
+
export type StageName = typeof VALID_STAGES[number];
|
|
1
3
|
export interface Config {
|
|
2
4
|
reviewIterations: number;
|
|
3
5
|
dryRun: boolean;
|
|
@@ -10,6 +12,7 @@ export interface Config {
|
|
|
10
12
|
requirement: string;
|
|
11
13
|
adaptiveExecution: boolean;
|
|
12
14
|
implementationOnly: boolean;
|
|
15
|
+
runStages?: StageName[];
|
|
13
16
|
}
|
|
14
17
|
export declare function loadConfigFromEnv(): Partial<Config>;
|
|
15
18
|
export declare function mergeConfig(envConfig: Partial<Config>, cliConfig: Partial<Config>): Config;
|
package/dist/config.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
const DEFAULT_REVIEW_ITERATIONS = 2;
|
|
2
|
+
export const VALID_STAGES = [
|
|
3
|
+
'implement',
|
|
4
|
+
'simplify',
|
|
5
|
+
'review',
|
|
6
|
+
'clean-code',
|
|
7
|
+
'test',
|
|
8
|
+
'commit',
|
|
9
|
+
'changelog',
|
|
10
|
+
];
|
|
2
11
|
function parseBoolEnv(value, defaultValue) {
|
|
3
12
|
if (value === undefined)
|
|
4
13
|
return defaultValue;
|
|
@@ -42,5 +51,6 @@ export function mergeConfig(envConfig, cliConfig) {
|
|
|
42
51
|
requirement: cliConfig.requirement ?? '',
|
|
43
52
|
adaptiveExecution: cliConfig.adaptiveExecution ?? envConfig.adaptiveExecution ?? false,
|
|
44
53
|
implementationOnly: cliConfig.implementationOnly ?? envConfig.implementationOnly ?? false,
|
|
54
|
+
runStages: cliConfig.runStages,
|
|
45
55
|
};
|
|
46
56
|
}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { readFileSync } from 'fs';
|
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { dirname, join } from 'path';
|
|
7
7
|
import { createInterface } from 'readline';
|
|
8
|
-
import { loadConfigFromEnv, mergeConfig } from './config.js';
|
|
8
|
+
import { loadConfigFromEnv, mergeConfig, VALID_STAGES } from './config.js';
|
|
9
9
|
import { runPipeline } from './pipeline.js';
|
|
10
10
|
import { checkForUpdates } from './utils/updateNotifier.js';
|
|
11
11
|
async function promptForRequirement() {
|
|
@@ -48,15 +48,28 @@ program
|
|
|
48
48
|
.option('--skip-push', 'Commit but do not push')
|
|
49
49
|
.option('--skip-branch-management', 'Skip smart branch management')
|
|
50
50
|
.option('--implementation-only', 'Run only: Implement → Review → SOLID (skips branch, tests, commit)')
|
|
51
|
+
.option('--implement', 'Run only the implementation step')
|
|
52
|
+
.option('--simplify', 'Run only the code simplification step')
|
|
53
|
+
.option('--review', 'Run only the code review step')
|
|
54
|
+
.option('--clean-code', 'Run only the SOLID & clean code step')
|
|
55
|
+
.option('--test', 'Run only the testing step')
|
|
56
|
+
.option('--commit', 'Run only the commit step')
|
|
57
|
+
.option('--changelog', 'Run only the changelog step')
|
|
51
58
|
.option('--log <file>', 'Log output to file')
|
|
52
59
|
.option('--dangerously-skip-permissions', 'Pass flag to claude to skip permission prompts')
|
|
53
60
|
.option('--allowedTools <tools>', 'Comma-separated list of allowed tools (default: "Edit,Read,Bash")')
|
|
54
61
|
.action(async (requirement, options) => {
|
|
55
62
|
// Check for updates (non-blocking, fails silently)
|
|
56
63
|
await checkForUpdates(pkg.name, pkg.version).catch(() => { });
|
|
57
|
-
//
|
|
64
|
+
// Collect stage flags
|
|
65
|
+
const selectedStages = VALID_STAGES.filter((stage) => {
|
|
66
|
+
const camelCase = stage.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
67
|
+
return !!options[camelCase];
|
|
68
|
+
});
|
|
69
|
+
// Prompt for requirement if not provided (skip for stages that don't need one)
|
|
70
|
+
const stageNeedsRequirement = selectedStages.length === 0 || selectedStages.includes('implement');
|
|
58
71
|
let finalRequirement = requirement;
|
|
59
|
-
if (!finalRequirement) {
|
|
72
|
+
if (!finalRequirement && stageNeedsRequirement) {
|
|
60
73
|
finalRequirement = await promptForRequirement();
|
|
61
74
|
}
|
|
62
75
|
const envConfig = loadConfigFromEnv();
|
|
@@ -72,10 +85,15 @@ program
|
|
|
72
85
|
allowedTools: options.allowedTools ?? undefined,
|
|
73
86
|
adaptiveExecution: options.adaptive ?? undefined,
|
|
74
87
|
implementationOnly: options.implementationOnly ?? undefined,
|
|
88
|
+
runStages: selectedStages.length > 0 ? selectedStages : undefined,
|
|
75
89
|
};
|
|
76
90
|
const config = mergeConfig(envConfig, cliConfig);
|
|
77
91
|
// Handle implementation-only mode
|
|
78
92
|
if (config.implementationOnly) {
|
|
93
|
+
if (config.runStages) {
|
|
94
|
+
console.error(chalk.red('Error:') + ' Cannot use --implementation-only with individual stage flags');
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
79
97
|
// Implementation-only mode automatically skips branch management and tests
|
|
80
98
|
config.skipBranchManagement = true;
|
|
81
99
|
config.skipTests = true;
|
|
@@ -86,7 +104,9 @@ program
|
|
|
86
104
|
}
|
|
87
105
|
config.adaptiveExecution = false;
|
|
88
106
|
}
|
|
89
|
-
|
|
107
|
+
// Require a requirement for full pipeline or implement stage; optional for other stages
|
|
108
|
+
const needsRequirement = !config.runStages || config.runStages.includes('implement');
|
|
109
|
+
if (!config.requirement && needsRequirement) {
|
|
90
110
|
console.error(chalk.red('Error:') + ' No requirement provided');
|
|
91
111
|
program.help();
|
|
92
112
|
return; // Ensure we don't continue if help() doesn't exit
|
package/dist/pipeline.js
CHANGED
|
@@ -34,6 +34,74 @@ function displayCompletionMessage(implementationOnly) {
|
|
|
34
34
|
console.log(chalk.green('\n✓ Pipeline completed successfully\n'));
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
const STAGE_LABELS = {
|
|
38
|
+
'implement': 'Implement',
|
|
39
|
+
'simplify': 'Simplify',
|
|
40
|
+
'review': 'Code Review',
|
|
41
|
+
'clean-code': 'SOLID & Clean Code',
|
|
42
|
+
'test': 'Testing',
|
|
43
|
+
'commit': 'Commit',
|
|
44
|
+
'changelog': 'Changelog',
|
|
45
|
+
};
|
|
46
|
+
async function runSelectedStages(config) {
|
|
47
|
+
const stages = config.runStages;
|
|
48
|
+
const stageLabels = stages.map((s) => STAGE_LABELS[s]).join(' → ');
|
|
49
|
+
console.log(chalk.cyan(`▶ Running selected stage(s): ${stageLabels}\n`));
|
|
50
|
+
for (const stage of stages) {
|
|
51
|
+
switch (stage) {
|
|
52
|
+
case 'implement': {
|
|
53
|
+
const success = await stepImplement(config);
|
|
54
|
+
if (!success)
|
|
55
|
+
exitWithError('Implementation step failed. Exiting.');
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
case 'simplify': {
|
|
59
|
+
const success = await stepSimplify(config);
|
|
60
|
+
if (!success)
|
|
61
|
+
exitWithError('Simplification step failed. Exiting.');
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
case 'review': {
|
|
65
|
+
const reviewIterations = config.reviewIterations;
|
|
66
|
+
for (let i = 1; i <= reviewIterations; i++) {
|
|
67
|
+
const reviewResult = await stepReview(i, config);
|
|
68
|
+
if (!reviewResult.success)
|
|
69
|
+
exitWithError('Review step failed. Exiting.');
|
|
70
|
+
if (reviewResult.noIssuesFound) {
|
|
71
|
+
console.log(chalk.green('\n✓ Code review passed - no issues found, skipping remaining reviews'));
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case 'clean-code': {
|
|
78
|
+
const success = await stepSolidCleanCode(config);
|
|
79
|
+
if (!success)
|
|
80
|
+
exitWithError('SOLID review step failed. Exiting.');
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
case 'test': {
|
|
84
|
+
const success = await stepTest(config);
|
|
85
|
+
if (!success)
|
|
86
|
+
exitWithError('Test step failed. Exiting.');
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
case 'commit': {
|
|
90
|
+
const success = await stepCommit(config);
|
|
91
|
+
if (!success)
|
|
92
|
+
exitWithError('Commit step failed. Exiting.');
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case 'changelog': {
|
|
96
|
+
const success = await stepChangelog(config);
|
|
97
|
+
if (!success)
|
|
98
|
+
exitWithError('Changelog step failed. Exiting.');
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
console.log(chalk.green('\n✓ Selected stage(s) completed successfully\n'));
|
|
104
|
+
}
|
|
37
105
|
export async function runPipeline(config) {
|
|
38
106
|
// Setup logging
|
|
39
107
|
if (config.logFile) {
|
|
@@ -53,6 +121,10 @@ export async function runPipeline(config) {
|
|
|
53
121
|
}
|
|
54
122
|
// Display header
|
|
55
123
|
logHeader(config);
|
|
124
|
+
// Run specific stages if requested
|
|
125
|
+
if (config.runStages && config.runStages.length > 0) {
|
|
126
|
+
return runSelectedStages(config);
|
|
127
|
+
}
|
|
56
128
|
if (config.implementationOnly) {
|
|
57
129
|
displayImplementationOnlyBanner();
|
|
58
130
|
}
|
package/package.json
CHANGED