create-claude-workspace 2.3.37 → 2.3.39
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/scheduler/loop.mjs
CHANGED
|
@@ -419,10 +419,7 @@ async function runTaskPipeline(task, workerId, agents, deps) {
|
|
|
419
419
|
const skipTo = resumeStep ?? 'triage';
|
|
420
420
|
const stepOrder = ['triage', 'plan', 'implement', 'test', 'review', 'rework', 'commit', 'pr-create', 'pr-watch', 'merge'];
|
|
421
421
|
const skipToIndex = stepOrder.indexOf(skipTo);
|
|
422
|
-
|
|
423
|
-
const interactiveSkip = new Set(['triage', 'test', 'review', 'rework', 're-review']);
|
|
424
|
-
const shouldSkip = (step) => stepOrder.indexOf(step) < skipToIndex ||
|
|
425
|
-
(state.taskMode === 'interactive' && interactiveSkip.has(step));
|
|
422
|
+
const shouldSkip = (step) => stepOrder.indexOf(step) < skipToIndex;
|
|
426
423
|
try {
|
|
427
424
|
// STEP 0: Triage (platform issues only — features go through PO, bugs go to IT analyst)
|
|
428
425
|
if (!shouldSkip('triage')) {
|
|
@@ -603,10 +600,13 @@ async function runTaskPipeline(task, workerId, agents, deps) {
|
|
|
603
600
|
model: getAgentModel(pipeline.assignedAgent, agents, task),
|
|
604
601
|
}, state, task.id, logger, onMessage, onSpawnStart, onSpawnEnd, mcpServers);
|
|
605
602
|
}
|
|
603
|
+
// Check if changes contain actual code (affects QA + review decisions)
|
|
604
|
+
const postImplFiles = getChangedFiles(worktreePath);
|
|
605
|
+
const codeChanged = hasCodeChanges(postImplFiles);
|
|
606
606
|
// STEP 3: QA (E2E tests, integration tests, acceptance criteria verification)
|
|
607
|
-
//
|
|
607
|
+
// Skip for non-code changes (docs, config, assets) and pure refactoring tasks.
|
|
608
608
|
if (!shouldSkip('test')) {
|
|
609
|
-
const needsQA = task.type !== 'fullstack' || !isRefactoringTask(task);
|
|
609
|
+
const needsQA = codeChanged && (task.type !== 'fullstack' || !isRefactoringTask(task));
|
|
610
610
|
if (needsQA) {
|
|
611
611
|
pipeline.step = 'test';
|
|
612
612
|
appendEvent(projectDir, createEvent('step_changed', { taskId: task.id, step: 'test' }));
|
|
@@ -633,11 +633,11 @@ async function runTaskPipeline(task, workerId, agents, deps) {
|
|
|
633
633
|
}
|
|
634
634
|
}
|
|
635
635
|
else {
|
|
636
|
-
logger.info(`[${task.id}] Skipping QA step (refactoring/config task)`);
|
|
636
|
+
logger.info(`[${task.id}] Skipping QA step (${codeChanged ? 'refactoring/config task' : 'no code changes'})`);
|
|
637
637
|
}
|
|
638
638
|
} // end if !shouldSkip('test')
|
|
639
|
-
// STEP 4: Review
|
|
640
|
-
if (!shouldSkip('review')) {
|
|
639
|
+
// STEP 4: Review (skip for non-code changes — nothing to review)
|
|
640
|
+
if (!shouldSkip('review') && codeChanged) {
|
|
641
641
|
pipeline.step = 'review';
|
|
642
642
|
appendEvent(projectDir, createEvent('step_changed', { taskId: task.id, step: 'review' }));
|
|
643
643
|
const reviewRouting = await orchestrator.routeTask(task, 'review', agents);
|
|
@@ -680,7 +680,10 @@ async function runTaskPipeline(task, workerId, agents, deps) {
|
|
|
680
680
|
}
|
|
681
681
|
}
|
|
682
682
|
}
|
|
683
|
-
}
|
|
683
|
+
}
|
|
684
|
+
else if (!shouldSkip('review') && !codeChanged) {
|
|
685
|
+
logger.info(`[${task.id}] Skipping review (no code changes)`);
|
|
686
|
+
} // end review
|
|
684
687
|
// STEP 5: Commit
|
|
685
688
|
if (!shouldSkip('commit')) {
|
|
686
689
|
pipeline.step = 'commit';
|
|
@@ -882,6 +885,21 @@ function isRefactoringTask(task) {
|
|
|
882
885
|
return lower.includes('refactor') || lower.includes('config') || lower.includes('cleanup')
|
|
883
886
|
|| lower.includes('rename') || lower.includes('migrate') || lower.includes('upgrade');
|
|
884
887
|
}
|
|
888
|
+
/** Code file extensions that warrant QA and review. */
|
|
889
|
+
const CODE_EXTENSIONS = new Set([
|
|
890
|
+
'.ts', '.tsx', '.js', '.jsx', '.mts', '.mjs', '.cts', '.cjs',
|
|
891
|
+
'.vue', '.svelte', '.py', '.rs', '.go', '.java', '.kt',
|
|
892
|
+
'.css', '.scss', '.sass', '.less',
|
|
893
|
+
'.html', '.htm',
|
|
894
|
+
'.sql',
|
|
895
|
+
]);
|
|
896
|
+
/** Check if changed files contain actual code (not just docs/config/assets). */
|
|
897
|
+
function hasCodeChanges(changedFiles) {
|
|
898
|
+
return changedFiles.some(f => {
|
|
899
|
+
const ext = f.slice(f.lastIndexOf('.')).toLowerCase();
|
|
900
|
+
return CODE_EXTENSIONS.has(ext);
|
|
901
|
+
});
|
|
902
|
+
}
|
|
885
903
|
// ─── Orphaned worktree recovery ───
|
|
886
904
|
/** Mark issue as done on the platform after a successful recovery merge */
|
|
887
905
|
export function closeRecoveredIssue(projectDir, branch, logger) {
|
|
@@ -195,8 +195,8 @@ Before doing anything, check for unexpected state from user intervention or prev
|
|
|
195
195
|
- If pipeline failed → resume STEP 9b fix loop.
|
|
196
196
|
- If no pipeline found → proceed to STEP 10 (pipeline may have been cancelled or platform is unreachable).
|
|
197
197
|
- **Crash recovery for STEP 10**: If `currentStep` in `state.json` is `10`:
|
|
198
|
-
- Check if the feature branch has commits ahead of main. If yes, proceed to STEP 10 (
|
|
199
|
-
- If already merged: clean up worktree
|
|
198
|
+
- Check if the feature branch has commits ahead of main. If yes, proceed to STEP 10 (push + cleanup).
|
|
199
|
+
- If already merged or MR/PR exists: clean up worktree.
|
|
200
200
|
- **Crash recovery for hotfix**: If `currentStep` starts with `hotfix`, resume in hotfix workflow mode (shortened cycle). Re-delegate to architect (same as STEPs 1-10 recovery above), then continue from the hotfix step.
|
|
201
201
|
- `currentWorktree` is set in `state.json` but directory doesn't exist → orphaned reference. Check if the branch was merged (in `git log main`). If merged: task is done, move to next. If not merged but branch exists: recreate worktree `git worktree add {path} {branch}` and resume. If branch is gone: move to next task.
|
|
202
202
|
- **Orphaned worktrees**: `git worktree list` — if there are worktrees not referenced by `state.json`:
|
|
@@ -371,8 +371,8 @@ If `PLAN.md` exists in the project root, check whether it changed since the last
|
|
|
371
371
|
### 13. One task per invocation — FULL CYCLE required
|
|
372
372
|
- Complete exactly ONE task per invocation, then end the session cleanly.
|
|
373
373
|
- The external loop (`autonomous.mjs` or ralph-loop) handles iteration control — you do NOT need to manage capacity, iteration counters, or session bounds.
|
|
374
|
-
- **CRITICAL: You MUST execute the FULL cycle: STEP 9 → STEP 9b → STEP 10 → EXIT.** Do NOT exit after STEP 9. Creating an MR/PR is NOT the end — you must watch the CI pipeline (9b),
|
|
375
|
-
- After
|
|
374
|
+
- **CRITICAL: You MUST execute the FULL cycle: STEP 9 → STEP 9b → STEP 10 → EXIT.** Do NOT exit after STEP 9. Creating an MR/PR is NOT the end — you must watch the CI pipeline (9b), fix failures, then clean up (10). Only EXIT after STEP 10 is complete (worktree cleaned up, MR/PR left open for review).
|
|
375
|
+
- After STEP 10, EXIT. Do NOT ask whether to continue, do NOT wait for confirmation, do NOT start another task. Do NOT create any commits after cleanup.
|
|
376
376
|
- Complexity tracking (S=1, M=2, L=4) is handled by the scheduler in `state.json`.
|
|
377
377
|
|
|
378
378
|
### 14. User input during autonomous operation
|
|
@@ -755,67 +755,56 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
|
|
|
755
755
|
- If architect confirms environment issue → proceed to STEP 10 with local merge fallback, log blocker
|
|
756
756
|
- If still failing → proceed to STEP 10 with local merge fallback
|
|
757
757
|
- **Note**: `--force-with-lease` is safe here because we own the branch and just pushed it. The MR/PR stays open and updates automatically.
|
|
758
|
-
- **→ PROCEED TO STEP 10**
|
|
758
|
+
- **→ PROCEED TO STEP 10**
|
|
759
759
|
|
|
760
|
-
**STEP 10: POST-
|
|
760
|
+
**STEP 10: POST-TASK CLEANUP & NEXT ITEM**
|
|
761
761
|
- Everything was committed in STEP 9 inside the worktree.
|
|
762
|
-
- **ZERO commits in this step** — all tracking was already committed in STEP 9. This step only performs git operations (
|
|
763
|
-
|
|
762
|
+
- **ZERO commits in this step** — all tracking was already committed in STEP 9. This step only performs git operations (cleanup, push) and delegates issue status updates.
|
|
763
|
+
|
|
764
|
+
- **When running via scheduler** (`state.json` exists): The scheduler handles merge, worktree cleanup, and branch deletion. Orchestrator only ensures final push and exits.
|
|
765
|
+
|
|
766
|
+
- **When running directly** (`claude --agent orchestrator` or ralph-loop):
|
|
767
|
+
|
|
764
768
|
- **If git integration active** (MR/PR was created in STEP 9):
|
|
765
769
|
- Ensure latest commit is pushed from worktree:
|
|
766
770
|
```bash
|
|
767
771
|
git -C {worktree-path} push origin HEAD
|
|
768
772
|
```
|
|
769
|
-
-
|
|
770
|
-
|
|
771
|
-
# GitHub
|
|
772
|
-
gh pr merge --merge --delete-branch
|
|
773
|
-
# GitLab
|
|
774
|
-
glab mr merge --remove-source-branch
|
|
775
|
-
```
|
|
776
|
-
- Then sync local main:
|
|
777
|
-
```bash
|
|
778
|
-
git pull --rebase origin HEAD
|
|
779
|
-
```
|
|
780
|
-
- Clean up worktree and branch:
|
|
773
|
+
- **Do NOT merge the MR/PR.** Leave it open for CI to pass and (optionally) human review. The MR/PR will be merged externally (by the user, by CI auto-merge, or by the scheduler in a future run).
|
|
774
|
+
- Clean up worktree only (branch stays for MR/PR):
|
|
781
775
|
```bash
|
|
782
776
|
git worktree remove .worktrees/feat/{slug}
|
|
783
|
-
git branch -d feat/{slug} 2>/dev/null || true
|
|
784
777
|
```
|
|
785
|
-
-
|
|
786
|
-
|
|
787
|
-
-
|
|
778
|
+
- Sync main: `git pull --rebase origin HEAD`
|
|
779
|
+
- If git integration active: delegate to `devops-integrator`: "Update issue #N status to in-review. Do NOT perform any git operations."
|
|
780
|
+
- **Track the open MR/PR branch** — remember `feat/{slug}` for branch stacking (see below).
|
|
781
|
+
|
|
782
|
+
- **If no git integration** (no MR/PR, no remote):
|
|
788
783
|
- Merge locally (from project root, which is on main):
|
|
789
784
|
```bash
|
|
790
785
|
git merge feat/{slug} --no-ff
|
|
791
786
|
```
|
|
792
787
|
- If merge fails due to conflicts: follow the "Merge Conflicts" section below, then retry
|
|
793
|
-
- If remote exists: `git push origin HEAD` after merge. If push fails (branch protection, auth): log blocker, leave commit local.
|
|
794
|
-
- If no remote: skip pull/push (local-only mode)
|
|
795
788
|
- Clean up worktree and branch:
|
|
796
789
|
```bash
|
|
797
790
|
git worktree remove .worktrees/feat/{slug}
|
|
798
791
|
git branch -d feat/{slug}
|
|
799
792
|
```
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
- **Team workflow** (CLAUDE.md `Workflow: team`):
|
|
804
|
-
- If remote exists: push from worktree: `git -C {worktree-path} push origin HEAD`
|
|
805
|
-
- Clean up worktree (branch stays for MR/PR review):
|
|
793
|
+
|
|
794
|
+
- **Branch stacking for dependent tasks**:
|
|
795
|
+
- If the next task depends on changes from a previous unmerged MR/PR, create worktree from the previous branch (not from main):
|
|
806
796
|
```bash
|
|
807
|
-
git worktree
|
|
797
|
+
git worktree add .worktrees/feat/{next} -b feat/{next} feat/{previous}
|
|
808
798
|
```
|
|
809
|
-
-
|
|
810
|
-
-
|
|
811
|
-
- Next task: if the next task depends on the previous (unmerged) MR/PR, create worktree from previous branch:
|
|
799
|
+
- This is "branch stacking" — the new branch builds on top of the unmerged one.
|
|
800
|
+
- When the previous MR/PR is eventually merged into main, rebase the stacked branch:
|
|
812
801
|
```bash
|
|
813
|
-
git
|
|
802
|
+
git -C .worktrees/feat/{next} rebase --onto main feat/{previous}
|
|
814
803
|
```
|
|
815
|
-
|
|
804
|
+
- If the next task does NOT depend on the previous MR/PR, create worktree from main as usual.
|
|
816
805
|
- **If no `[ ]` tasks remain in current phase AND at least one `[~]` exists** (all remaining were skipped): do NOT auto-advance. Delegate to `product-owner`: "All tasks in Phase [N] are blocked/skipped. The autonomous loop cannot proceed. Options: (1) ADD replacement tasks that unblock progress, (2) REPRIORITIZE to skip this phase entirely and move to next, (3) declare a BLOCKER requiring human intervention." If product-owner returns only CONFIRM with no actionable changes, STOP the autonomous loop and log: "Phase [N] fully blocked — requires human intervention. Run orchestrator manually after resolving blockers."
|
|
817
806
|
- **→ EXIT NOW.** One task per invocation — STEP 10 is complete, end session. The external loop will start the next invocation.
|
|
818
|
-
- **CRITICAL: ZERO commits after
|
|
807
|
+
- **CRITICAL: ZERO commits after STEP 10.** Do NOT `git add`, do NOT `git commit`, do NOT create `chore:` commits after cleanup.
|
|
819
808
|
- **If no `[ ]` tasks remain in current phase AND zero `[~]` exist** (all completed) -> phase transition (handled at start of STEP 1)
|
|
820
809
|
- **If no `[ ]` tasks remain in ALL phases AND zero `[~]` exist** (everything completed):
|
|
821
810
|
- **Pre-completion check**: Run `git status --short` — if there are uncommitted/untracked source files (excluding `.env`, `node_modules/`, `.claude/autonomous-state.json`), do NOT enter completion sequence. These files represent unfinished work. Create a task to review and commit them, then continue STEP 1.
|
|
@@ -844,7 +833,7 @@ For critical production bugs (outside normal TODO.md flow):
|
|
|
844
833
|
5. If reviewer finds CRITICAL or WARN issues: fix them and re-review (max 2 cycles for hotfixes). If still failing, commit anyway — hotfix urgency takes priority.
|
|
845
834
|
6. Commit & push from worktree (STEP 9) — include in the SAME commit:
|
|
846
835
|
- Do NOT update TODO.md checkboxes unless the fix corresponds to an existing task
|
|
847
|
-
7. Post-
|
|
836
|
+
7. Post-task: follow STEP 10 logic (push, create MR/PR if git integration active, clean up worktree). No additional commits.
|
|
848
837
|
8. **Patch release**: if git integration active, delegate to `devops-integrator`: "Hotfix merged. Create a patch release with changelog." If CLAUDE.md has `Distribution: npm`, follow the same publish verification logic as phase transition (watch CI pipeline, verify `npm view`, fall back to direct publish on failure).
|
|
849
838
|
|
|
850
839
|
**Skipped steps:** STEP 4 (tests — unless the bug reveals missing test coverage), STEP 5 (visual verification).
|
|
@@ -863,13 +852,17 @@ If a merge conflict occurs:
|
|
|
863
852
|
5. If rebase is too complex: `cd {worktree-path} && git merge origin/main` instead (creates merge commit but is safer)
|
|
864
853
|
6. Log the conflict resolution
|
|
865
854
|
|
|
866
|
-
**During `git merge feat/branch` on main** (STEP 10,
|
|
855
|
+
**During `git merge feat/branch` on main** (STEP 10, local merge only — no git integration):
|
|
867
856
|
1. Resolve the conflict in the merge commit (do NOT rebase here — you are on main)
|
|
868
857
|
2. `git add [resolved files]` (only resolved files — do NOT use `git add .`), then `git merge --continue`
|
|
869
858
|
3. Verify the merged result: build, lint, test from project root
|
|
870
859
|
4. Push: `git push origin HEAD`
|
|
871
860
|
5. Then clean up: `git worktree remove .worktrees/feat/{slug} && git branch -d feat/{slug}`
|
|
872
861
|
|
|
862
|
+
**During rebase in worktree** (branch stacking or MR/PR conflict):
|
|
863
|
+
1. Resolve conflicts in the worktree: `git -C {worktree-path} add [resolved files]`, then `git -C {worktree-path} rebase --continue`
|
|
864
|
+
2. Force-push the rebased branch: `git -C {worktree-path} push --force-with-lease`
|
|
865
|
+
|
|
873
866
|
## Proactive Problem Resolution
|
|
874
867
|
|
|
875
868
|
All agents have access to a `report_issue` tool provided by the scheduler. When an agent encounters a problem outside its current task scope, it calls this tool to create a tracked issue. The scheduler picks it up on the next iteration and routes it through the normal pipeline.
|
|
@@ -914,6 +907,15 @@ Examples:
|
|
|
914
907
|
- CI unfixable: `status: completed, action: ci_needs_config, message: "CI pipeline failed — missing NODE_AUTH_TOKEN secret. Task merged locally (fallback).", task_completed: "#42 User auth", next_task: "#43 Dashboard"`
|
|
915
908
|
- Blocked: `status: blocked, action: needs_user_decision, message: "Task #15 requires API design decision — REST vs GraphQL. Cannot proceed without guidance."`
|
|
916
909
|
|
|
910
|
+
## Research First — Then Implement (STRICT)
|
|
911
|
+
|
|
912
|
+
Before solving any problem, agents MUST research whether a correct/proper solution exists:
|
|
913
|
+
1. **Read documentation** — check official docs, existing code patterns, API references
|
|
914
|
+
2. **Verify assumptions** — grep for existing implementations, check library APIs, read types
|
|
915
|
+
3. **Only then implement** — using the verified correct approach
|
|
916
|
+
|
|
917
|
+
Never guess or implement a workaround when a proper solution might exist. If unsure, delegate research to the relevant specialist agent before proceeding.
|
|
918
|
+
|
|
917
919
|
## No Workarounds — Fix the Root Cause (STRICT)
|
|
918
920
|
|
|
919
921
|
When a tool, library, or process fails (e.g., `nx release`, `nx build`, a @cibule/* package, a generator), **fix the underlying issue** instead of bypassing it with a workaround. For example:
|
|
@@ -972,7 +974,7 @@ After handling the user's message, resume the development cycle from where you l
|
|
|
972
974
|
- NEVER implement without architect plan (STEP 2) or skip code review (STEP 6)
|
|
973
975
|
- Each commit = 1 logical unit
|
|
974
976
|
- Conventional commits: feat/fix/refactor/chore/docs
|
|
975
|
-
- **ABSOLUTE BAN: NEVER create commits that only change tracking files.** TODO.md changes (local mode) are committed WITH implementation code in STEP 9. After
|
|
977
|
+
- **ABSOLUTE BAN: NEVER create commits that only change tracking files.** TODO.md changes (local mode) are committed WITH implementation code in STEP 9. After STEP 10, ZERO commits. Forbidden patterns: `chore: update progress tracking`, `chore: update TODO.md`. If TODO.md shows as modified after cleanup, something went wrong in STEP 9 — investigate and fix, do NOT create a band-aid commit.
|
|
976
978
|
- All files in ENGLISH
|
|
977
979
|
- TODO.md is your task tracking system (local mode) — keep it PRECISE and CURRENT
|
|
978
980
|
- **NEVER add `eslint-disable` comments** (inline, next-line, or block). Fix the actual code instead. If a lint rule cannot be satisfied, restructure the code — do not suppress the warning.
|