@ghostwater/soulforge 0.6.0 → 0.8.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.
Files changed (46) hide show
  1. package/dist/cli/cli.js +323 -117
  2. package/dist/cli/cli.js.map +1 -1
  3. package/dist/daemon/daemon.js +112 -6
  4. package/dist/daemon/daemon.js.map +1 -1
  5. package/dist/daemon/runner.js +634 -64
  6. package/dist/daemon/runner.js.map +1 -1
  7. package/dist/db/database.d.ts +20 -10
  8. package/dist/db/database.js +182 -44
  9. package/dist/db/database.js.map +1 -1
  10. package/dist/executors/claude-code.d.ts +2 -0
  11. package/dist/executors/claude-code.js +38 -2
  12. package/dist/executors/claude-code.js.map +1 -1
  13. package/dist/executors/codex-cli.d.ts +2 -0
  14. package/dist/executors/codex-cli.js +37 -2
  15. package/dist/executors/codex-cli.js.map +1 -1
  16. package/dist/executors/codex.d.ts +1 -0
  17. package/dist/executors/codex.js +53 -0
  18. package/dist/executors/codex.js.map +1 -1
  19. package/dist/executors/openclaw.d.ts +1 -0
  20. package/dist/executors/openclaw.js +11 -0
  21. package/dist/executors/openclaw.js.map +1 -1
  22. package/dist/executors/self.d.ts +1 -0
  23. package/dist/executors/self.js +11 -0
  24. package/dist/executors/self.js.map +1 -1
  25. package/dist/executors/types.d.ts +4 -0
  26. package/dist/lib/worktree.d.ts +1 -1
  27. package/dist/lib/worktree.js +2 -1
  28. package/dist/lib/worktree.js.map +1 -1
  29. package/dist/workflow/discovery.d.ts +24 -0
  30. package/dist/workflow/discovery.js +120 -0
  31. package/dist/workflow/discovery.js.map +1 -0
  32. package/dist/workflow/gate-routing.d.ts +5 -0
  33. package/dist/workflow/gate-routing.js +44 -0
  34. package/dist/workflow/gate-routing.js.map +1 -0
  35. package/dist/workflow/parser.js +117 -5
  36. package/dist/workflow/parser.js.map +1 -1
  37. package/dist/workflow/schema-validator.d.ts +6 -0
  38. package/dist/workflow/schema-validator.js +120 -0
  39. package/dist/workflow/schema-validator.js.map +1 -0
  40. package/dist/workflow/template.d.ts +2 -1
  41. package/dist/workflow/template.js +13 -21
  42. package/dist/workflow/template.js.map +1 -1
  43. package/dist/workflow/types.d.ts +22 -2
  44. package/package.json +1 -1
  45. package/workflows/bugfix/workflow.yml +248 -40
  46. package/workflows/feature-dev/workflow.yml +252 -48
@@ -1,12 +1,18 @@
1
1
  export type ExecutorType = "openclaw" | "claude-code" | "codex" | "codex-cli" | "self";
2
2
  export type NotifyEvent = "on_complete" | "on_waiting" | "on_fail";
3
3
  export type LoopConfig = {
4
- over: "stories";
4
+ over: string;
5
5
  completion: "all_done";
6
6
  freshSession?: boolean;
7
7
  verifyEach?: boolean;
8
8
  verifyStep?: string;
9
9
  };
10
+ export type GateConfig = {
11
+ decision_var: string;
12
+ routes: Record<string, string>;
13
+ default: string;
14
+ max_loops: number;
15
+ };
10
16
  export type StepFailure = {
11
17
  retry_step?: string;
12
18
  max_retries?: number;
@@ -18,14 +24,27 @@ export type StepFailure = {
18
24
  export type OnRejectConfig = {
19
25
  reset_to: string;
20
26
  };
27
+ export type OutputFieldType = "string" | "number" | "boolean" | "array" | "object";
28
+ export type OutputField = {
29
+ name: string;
30
+ type: OutputFieldType;
31
+ required: boolean;
32
+ description?: string;
33
+ items?: OutputField[];
34
+ };
35
+ export type OutputSchema = {
36
+ fields: OutputField[];
37
+ };
21
38
  export type WorkflowStep = {
22
39
  id: string;
23
40
  executor?: ExecutorType;
24
41
  agent?: string;
25
42
  model?: string;
26
43
  workdir?: string;
27
- type?: "single" | "loop";
44
+ type?: "single" | "loop" | "gate";
28
45
  loop?: LoopConfig;
46
+ gate?: GateConfig;
47
+ next?: string;
29
48
  input: string;
30
49
  expects?: string;
31
50
  timeout?: number;
@@ -33,6 +52,7 @@ export type WorkflowStep = {
33
52
  on_fail?: StepFailure;
34
53
  on_reject?: OnRejectConfig;
35
54
  notify?: NotifyEvent | NotifyEvent[];
55
+ output_schema?: OutputSchema;
36
56
  };
37
57
  export type AgentRole = "analysis" | "coding" | "verification" | "testing" | "pr" | "scanning";
38
58
  export type WorkflowAgent = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghostwater/soulforge",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Pluggable executor workflow engine for AI coding agents. Dispatch workflow steps to Claude Code, Codex CLI, or human review checkpoints.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -9,17 +9,43 @@ description: |
9
9
  Keeps scope tight — no "while I'm here" improvements.
10
10
 
11
11
  defaults:
12
- executor: claude-code
13
- model: opus
12
+ executor: "{{executor:codex-cli}}"
13
+ model: "{{model:gpt-5.3-codex}}"
14
14
  timeout: 600
15
15
  max_retries: 2
16
16
  notify: [on_complete, on_fail]
17
17
 
18
18
  steps:
19
19
  - id: diagnose
20
- executor: claude-code
21
- model: opus
20
+ executor: "{{executor:codex-cli}}"
21
+ model: "{{model:gpt-5.3-codex}}"
22
22
  workdir: "{{workdir}}"
23
+ output_schema:
24
+ fields:
25
+ - name: status
26
+ type: string
27
+ required: true
28
+ description: Must be "done"
29
+ - name: affected_files
30
+ type: string
31
+ required: true
32
+ description: Files and components involved in the bug
33
+ - name: root_cause
34
+ type: string
35
+ required: true
36
+ description: Exact defect and why it fails
37
+ - name: failing_test
38
+ type: string
39
+ required: true
40
+ description: Failing reproduction test details
41
+ - name: fix_proposal
42
+ type: string
43
+ required: true
44
+ description: Minimal approved change plan
45
+ - name: scope
46
+ type: string
47
+ required: true
48
+ description: Maximum file scope for the fix
23
49
  input: |
24
50
  You are working in {{workdir}}. Diagnose the following bug.
25
51
 
@@ -39,18 +65,20 @@ steps:
39
65
  - Keep the fix proposal minimal — bugfixes should be surgical
40
66
  - Commit the failing test: test: failing test for {{task}}
41
67
 
42
- Reply with:
43
- STATUS: done
44
- AFFECTED_FILES: which files are involved
45
- ROOT_CAUSE: exactly what's wrong and why
46
- FAILING_TEST: what test you wrote and how it demonstrates the bug
47
- FIX_PROPOSAL: what needs to change (be specific — file, function, what changes)
48
- SCOPE: list of files that will be modified in the fix (max)
49
- expects: "STATUS: done"
50
68
 
51
69
  - id: review-diagnosis
52
70
  executor: self
53
71
  notify: on_waiting
72
+ output_schema:
73
+ fields:
74
+ - name: status
75
+ type: string
76
+ required: true
77
+ description: Review outcome (approved or retry)
78
+ - name: notes
79
+ type: string
80
+ required: false
81
+ description: Optional feedback for revised diagnosis
54
82
  on_reject:
55
83
  reset_to: diagnose
56
84
  input: |
@@ -69,9 +97,23 @@ steps:
69
97
  - Is the scope reasonable?
70
98
 
71
99
  - id: fix
72
- executor: claude-code
73
- model: opus
100
+ executor: "{{executor:codex-cli}}"
101
+ model: "{{model:gpt-5.3-codex}}"
74
102
  workdir: "{{workdir}}"
103
+ output_schema:
104
+ fields:
105
+ - name: status
106
+ type: string
107
+ required: true
108
+ description: Must be "done"
109
+ - name: changes
110
+ type: string
111
+ required: true
112
+ description: Exact implementation changes made for the fix
113
+ - name: tests
114
+ type: string
115
+ required: true
116
+ description: Test execution summary after applying the fix
75
117
  input: |
76
118
  Implement the approved fix for this bug.
77
119
 
@@ -98,16 +140,33 @@ steps:
98
140
  - Change files outside SCOPE unless absolutely necessary
99
141
  - "Improve" things while you're in there
100
142
 
101
- Reply with:
102
- STATUS: done
103
- CHANGES: exactly what you changed and why
104
- TEST_RESULTS: full test suite results
105
- expects: "STATUS: done"
106
143
 
107
144
  - id: verify
108
- executor: claude-code
109
- model: opus
145
+ executor: "{{executor:codex-cli}}"
146
+ model: "{{model:gpt-5.3-codex}}"
110
147
  workdir: "{{workdir}}"
148
+ output_schema:
149
+ fields:
150
+ - name: status
151
+ type: string
152
+ required: true
153
+ description: Verification decision ("done" or "retry")
154
+ - name: verified
155
+ type: string
156
+ required: true
157
+ description: Confirmed verification results
158
+ - name: issues
159
+ type: string
160
+ required: true
161
+ description: Problems found when retry is required
162
+ - name: diff_review
163
+ type: string
164
+ required: true
165
+ description: Diff scope review against approved plan
166
+ - name: verify_feedback
167
+ type: string
168
+ required: false
169
+ description: Retry feedback passed back to the fix step
111
170
  input: |
112
171
  Verify the bugfix independently.
113
172
 
@@ -127,46 +186,195 @@ steps:
127
186
  4. Does the fix actually address the root cause (not just mask symptoms)?
128
187
  5. Are there any edge cases the fix misses?
129
188
 
130
- Reply with:
131
- STATUS: done
132
- VERIFIED: what you confirmed
133
- DIFF_REVIEW: summary of actual changes vs approved scope
134
-
135
- Or if issues found:
136
- STATUS: retry
137
- ISSUES:
138
- - What's wrong
139
- expects: "STATUS: done"
140
189
 
141
190
  - id: pr
142
- executor: claude-code
143
- model: opus
191
+ executor: "{{executor:codex-cli}}"
192
+ model: "{{model:gpt-5.3-codex}}"
144
193
  workdir: "{{workdir}}"
145
194
  notify: on_complete
195
+ output_schema:
196
+ fields:
197
+ - name: status
198
+ type: string
199
+ required: true
200
+ description: Must be "done"
201
+ - name: pr
202
+ type: string
203
+ required: true
204
+ description: Pull request URL
205
+ - name: pr_number
206
+ type: number
207
+ required: true
208
+ description: Pull request number
146
209
  input: |
147
- Create a pull request for this bugfix.
210
+ Create or resolve a pull request for this bugfix.
148
211
 
149
212
  WORKDIR: {{workdir}}
150
213
  BUG: {{task}}
151
214
  ROOT_CAUSE: {{root_cause}}
152
215
  CHANGES: {{changes}}
153
216
 
154
- Create a PR with gh pr create. The PR body should include:
217
+ IMPORTANT: this step is idempotent.
218
+
219
+ 1) First check whether a PR already exists for the current branch.
220
+ - Use gh pr view --json number,url,state
221
+ - If that fails, search by head branch in this repo.
222
+
223
+ 2) If an existing PR is found, DO NOT create a new one.
224
+ Immediately complete the step with that existing PR's URL and number.
225
+
226
+ 3) Only run gh pr create when no PR exists.
227
+
228
+ PR body should include:
155
229
  - What the bug was
156
230
  - Root cause
157
231
  - What the fix does
158
232
  - Link to the issue if one exists
159
233
 
160
- Reply with:
161
- STATUS: done
162
- PR: URL to the pull request
163
- expects: "STATUS: done"
234
+
235
+ # ── Automated Review Loop ──────────────────────────────────────────
236
+ - id: code-review
237
+ executor: "{{executor:codex-cli}}"
238
+ model: "{{model:gpt-5.3-codex}}"
239
+ workdir: "{{workdir}}"
240
+ output_schema:
241
+ fields:
242
+ - name: status
243
+ type: string
244
+ required: true
245
+ description: Must be "done"
246
+ - name: review_decision
247
+ type: string
248
+ required: true
249
+ description: Gate decision ("pass" or "fix")
250
+ - name: findings
251
+ type: string
252
+ required: false
253
+ description: Review summary posted to the PR
254
+ input: |
255
+ Thorough code review of PR #{{pr_number}}.
256
+
257
+ WORKDIR: {{workdir}}
258
+ BUG: {{task}}
259
+ ROOT CAUSE: {{root_cause}}
260
+ SCOPE: {{scope}}
261
+ BUILD_CMD: {{build_cmd}}
262
+ TEST_CMD: {{test_cmd}}
263
+
264
+ Instructions:
265
+ 1. Read ALL changed files in the PR
266
+ 2. Check: does the fix address the root cause (not just mask symptoms)?
267
+ 3. Check: are changes limited to the approved SCOPE?
268
+ 4. Check: edge cases, regressions, test quality
269
+ 5. Run build: {{build_cmd}}
270
+ 6. Run tests: {{test_cmd}}
271
+ 7. Post ALL findings as a single comment on the PR:
272
+ gh pr comment {{pr_number}} --body "<your review>"
273
+ 8. Flag severity for each finding (High/Medium/Low)
274
+
275
+ Do NOT decide what should or shouldn't be fixed — just flag everything.
276
+
277
+ Reply with exactly one of:
278
+ REVIEW_DECISION: pass
279
+ REVIEW_DECISION: fix
280
+
281
+ - id: review-gate
282
+ type: gate
283
+ executor: self
284
+ notify: on_waiting
285
+ output_schema:
286
+ fields:
287
+ - name: status
288
+ type: string
289
+ required: true
290
+ description: Triage checkpoint status
291
+ - name: review_decision
292
+ type: string
293
+ required: true
294
+ description: Final triage decision ("pass" or "fix")
295
+ - name: triage_summary
296
+ type: string
297
+ required: false
298
+ description: Summary of triage decisions and issue filing
299
+ input: |
300
+ Triage the code review findings on PR #{{pr_number}}.
301
+
302
+ Read the latest review comment on the PR. For each finding, decide:
303
+ - FIX: any issue related to the task, introduced by this PR, or that
304
+ affects correctness of the changes. ALL task-related items get fixed.
305
+ - SEPARATE: only for genuine scope creep — pre-existing issues unrelated
306
+ to the task that were not introduced or affected by this PR.
307
+
308
+ Then:
309
+ 1. Post a triage comment on the PR summarizing your decisions
310
+ 2. File separate issues (if any) via: gh issue create --title "..." --body "..."
311
+ 3. Approve with the appropriate routing decision
312
+ gate:
313
+ decision_var: REVIEW_DECISION
314
+ routes:
315
+ fix: review-fix
316
+ pass: final-review
317
+ default: final-review
318
+ max_loops: 5
319
+
320
+ - id: review-fix
321
+ executor: "{{executor:codex-cli}}"
322
+ model: "{{model:gpt-5.3-codex}}"
323
+ workdir: "{{workdir}}"
324
+ output_schema:
325
+ fields:
326
+ - name: status
327
+ type: string
328
+ required: true
329
+ description: Must be "done"
330
+ - name: changes
331
+ type: string
332
+ required: true
333
+ description: What was fixed from review findings
334
+ - name: tests
335
+ type: string
336
+ required: false
337
+ description: Build and test confirmation after fixes
338
+ input: |
339
+ Read the latest triage comment on PR #{{pr_number}} for the list of
340
+ items to fix. You can fetch it with:
341
+ gh pr view {{pr_number}} --comments --json comments --jq '.comments[-1].body'
342
+
343
+ WORKDIR: {{workdir}}
344
+ BUILD_CMD: {{build_cmd}}
345
+ TEST_CMD: {{test_cmd}}
346
+
347
+ Fix ONLY the items marked for fixing. Do not touch anything else.
348
+
349
+ After fixing:
350
+ 1. Run build: {{build_cmd}}
351
+ 2. Run tests: {{test_cmd}}
352
+ 3. Commit and push
353
+
354
+ DO NOT:
355
+ - Refactor unrelated code
356
+ - Add features or improvements
357
+ - Touch files not related to the review findings
358
+
359
+ next: code-review
164
360
 
165
361
  - id: final-review
166
362
  executor: self
167
363
  notify: on_waiting
364
+ output_schema:
365
+ fields:
366
+ - name: status
367
+ type: string
368
+ required: true
369
+ description: Human sign-off decision
370
+ - name: notes
371
+ type: string
372
+ required: false
373
+ description: Optional final approval notes
168
374
  input: |
169
- Final review of the bugfix PR.
375
+ PR #{{pr_number}} has passed automated code review.
376
+ Ready for human sign-off before merge.
377
+
170
378
  PR: {{pr}}
171
379
  BUG: {{task}}
172
380
  ROOT CAUSE: {{root_cause}}