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 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
+ ![](docs/architecture-diagram.png)
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
- // Prompt for requirement if not provided
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
- if (!config.requirement) {
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "software-engineer",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "CLI that automates the full dev workflow with Claude AI - implement, review, test, and commit code with a single command",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",