worclaude 2.7.1 → 2.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.
- package/CHANGELOG.md +18 -0
- package/package.json +1 -1
- package/src/commands/doctor.js +68 -0
- package/templates/agents/optional/quality/bug-fixer.md +12 -0
- package/templates/agents/universal/test-writer.md +12 -0
- package/templates/agents/universal/verify-app.md +12 -0
- package/templates/skills/universal/subagent-usage.md +14 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@ All notable changes to worclaude are documented in this file. Format loosely fol
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [2.8.0] — 2026-04-24
|
|
8
|
+
|
|
9
|
+
Fixes a long-standing agent worktree correctness bug. Both `claude --worktree` and the `Agent` tool's `isolation: "worktree"` option create their isolated checkout from `origin/HEAD` — which on most worclaude-convention repos resolves to `origin/main`. When the working branch (typically `develop`) is ahead of main (the normal state mid-release-cycle), agent worktrees get a stale checkout that misses recent commits, producing "missing develop files" symptoms easy to misattribute to tooling flakiness. This release ships two complementary fixes: a new `worclaude doctor` check that detects and warns on the at-risk configuration with a local, reversible remedy (`git remote set-head origin <branch>`), and a freshness preamble on the three bundled worktree agents (`bug-fixer`, `verify-app`, `test-writer`) that resets the worktree to match the parent's current branch regardless of `origin/HEAD`. Documentation in `subagent-usage` now correctly describes the harness behavior instead of the previous "creates a worktree from your current branch" claim.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **`worclaude doctor` Git Integration / `origin/HEAD` divergence check** (PR #121) — warns when the current branch is ahead of `origin/HEAD`'s target, naming the branch and commit count. Suggests `git remote set-head origin <branch>` (local-only, reversible via `--auto` or `main`) as the fix. Skips silently outside a git repo or when `origin/HEAD` is unset. Shared `runGit(cwd, args)` helper added alongside for future checks to reuse the same spawn pattern.
|
|
14
|
+
- **Worktree freshness preamble on `bug-fixer`, `verify-app`, `test-writer` agent templates** (PR #121) — on worktree start the agent runs `git fetch origin`, identifies the parent's current branch from `git worktree list --porcelain` (filtering out auto-named `worktree-agent-*` branches), then `git reset --hard "origin/${PARENT_BRANCH}"`. Protects correctness even when the user hasn't run `set-head`. LLM-driven parsing (no `awk`/`sed` pipelines) for cross-platform portability.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **`subagent-usage` skill (both `.claude/skills/subagent-usage/SKILL.md` and `templates/skills/universal/subagent-usage.md`)** (PR #121) — "How it works" item 1 corrected from "creates a worktree from your current branch" to "creates a worktree based on `origin/HEAD` (see gotcha below)". New "Base-branch gotcha" subsection cross-links to `worclaude doctor` and the `git remote set-head` remedy, and notes that the three bundled agents include a freshness preamble while other worktree agents do not.
|
|
19
|
+
|
|
20
|
+
### Docs
|
|
21
|
+
|
|
22
|
+
- **`docs/spec/SPEC.md` doctor section** (this /sync) — adds a `### Git Integration` subsection documenting both the gitignore coverage check and the new origin/HEAD divergence check.
|
|
23
|
+
- **`docs/spec/PROGRESS.md`** (this /sync) — new v2.8.0 release entry; Stats refreshed (788 → 804 tests, 57 → 58 files).
|
|
24
|
+
|
|
7
25
|
## [2.7.1] — 2026-04-24
|
|
8
26
|
|
|
9
27
|
Three `/setup` UX follow-ups from v2.7.0 confirmation testing, shipped as a single patch PR. The `?` / `help` trigger introduced in v2.7.0 turned out to collide with Claude Code's built-in keyboard-shortcut overlay (pressing `?` opens the shortcut panel before /setup's parser sees the keystroke); switched to the `help` keyword only. `worclaude init`'s `runOptionalExtras` was the only place in the init flow still using `inquirer type: 'confirm'` (rendered as `(y/N)`) — converted to `type: 'list'` arrow-key menus so every yes/no in init behaves consistently. CONFIRM_MEDIUM now invokes `AskUserQuestion` directly when the per-item option count fits the tool's `maxItems: 4` schema cap, with the consequence info ("Will be saved as") carried inside each option's `description` field; falls back to the verbatim text prompt (using `help` instead of `?`) when the count exceeds 4. CONFIRM_HIGH stays text-parse — detection lists routinely exceed 4 items. No consumer-visible schema or CLI surface additions.
|
package/package.json
CHANGED
package/src/commands/doctor.js
CHANGED
|
@@ -838,6 +838,73 @@ async function checkGitignore(projectRoot) {
|
|
|
838
838
|
return results;
|
|
839
839
|
}
|
|
840
840
|
|
|
841
|
+
function runGit(projectRoot, args) {
|
|
842
|
+
try {
|
|
843
|
+
const r = spawnSync('git', args, { cwd: projectRoot, encoding: 'utf8' });
|
|
844
|
+
if (r.error) return { status: -1, stdout: '', stderr: String(r.error) };
|
|
845
|
+
return {
|
|
846
|
+
status: r.status,
|
|
847
|
+
stdout: (r.stdout || '').trim(),
|
|
848
|
+
stderr: (r.stderr || '').trim(),
|
|
849
|
+
};
|
|
850
|
+
} catch (err) {
|
|
851
|
+
return { status: -1, stdout: '', stderr: String(err) };
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
async function checkOriginHead(projectRoot) {
|
|
856
|
+
const skipped = result(PASS, 'origin/HEAD check skipped', null);
|
|
857
|
+
|
|
858
|
+
const headRef = runGit(projectRoot, ['symbolic-ref', 'refs/remotes/origin/HEAD']);
|
|
859
|
+
if (headRef.status === 128) return skipped;
|
|
860
|
+
if (headRef.status !== 0) {
|
|
861
|
+
return result(
|
|
862
|
+
WARN,
|
|
863
|
+
'origin/HEAD not set',
|
|
864
|
+
'Run `git remote set-head origin --auto` (or `git remote set-head origin <branch>`) so worktree agents have a defined base'
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
const defaultBranch = headRef.stdout.replace(/^refs\/remotes\/origin\//, '');
|
|
869
|
+
if (!defaultBranch) {
|
|
870
|
+
return result(WARN, 'origin/HEAD malformed', `Unexpected ref: ${headRef.stdout}`);
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
const currentRef = runGit(projectRoot, ['branch', '--show-current']);
|
|
874
|
+
if (currentRef.status !== 0) return skipped;
|
|
875
|
+
|
|
876
|
+
const currentBranch = currentRef.stdout;
|
|
877
|
+
if (!currentBranch) {
|
|
878
|
+
return result(PASS, `origin/HEAD → ${defaultBranch} (detached HEAD, skipped)`, null);
|
|
879
|
+
}
|
|
880
|
+
if (currentBranch === defaultBranch) {
|
|
881
|
+
return result(PASS, `origin/HEAD → ${defaultBranch} (matches current branch)`, null);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
const ahead = runGit(projectRoot, [
|
|
885
|
+
'rev-list',
|
|
886
|
+
'--count',
|
|
887
|
+
`origin/${defaultBranch}..${currentBranch}`,
|
|
888
|
+
]);
|
|
889
|
+
if (ahead.status !== 0) {
|
|
890
|
+
return result(PASS, `origin/HEAD → ${defaultBranch}`, null);
|
|
891
|
+
}
|
|
892
|
+
const aheadCount = Number.parseInt(ahead.stdout, 10) || 0;
|
|
893
|
+
if (aheadCount === 0) {
|
|
894
|
+
return result(
|
|
895
|
+
PASS,
|
|
896
|
+
`origin/HEAD → ${defaultBranch}, current '${currentBranch}' not ahead`,
|
|
897
|
+
null
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
return result(
|
|
902
|
+
WARN,
|
|
903
|
+
`Current branch '${currentBranch}' is ${aheadCount} commit(s) ahead of origin/${defaultBranch}`,
|
|
904
|
+
`Worktree agents (claude --worktree, Agent isolation:worktree) base off origin/${defaultBranch} and will miss those commits. Fix: \`git remote set-head origin ${currentBranch}\` (local-only, reversible with \`--auto\` or \`main\`)`
|
|
905
|
+
);
|
|
906
|
+
}
|
|
907
|
+
|
|
841
908
|
async function checkPendingReviewFiles(projectRoot) {
|
|
842
909
|
const pending = [];
|
|
843
910
|
try {
|
|
@@ -943,6 +1010,7 @@ export async function doctorCommand(options = {}) {
|
|
|
943
1010
|
// Git Integration
|
|
944
1011
|
section('Git Integration');
|
|
945
1012
|
record('git', await checkGitignore(projectRoot));
|
|
1013
|
+
record('git', await checkOriginHead(projectRoot));
|
|
946
1014
|
spacer();
|
|
947
1015
|
|
|
948
1016
|
// Integrity
|
|
@@ -6,6 +6,18 @@ isolation: worktree
|
|
|
6
6
|
maxTurns: 50
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## Worktree freshness preamble
|
|
10
|
+
|
|
11
|
+
Before making any code changes, synchronize this worktree to the parent checkout's committed state. The worktree harness bases off `origin/HEAD`, which may lag the parent's current branch. Follow these steps and report the result:
|
|
12
|
+
|
|
13
|
+
1. Run `git fetch origin`.
|
|
14
|
+
2. Run `git worktree list --porcelain`. Read the output and find the entry whose line `branch refs/heads/<name>` has a `<name>` that does NOT start with `worktree-agent-` — that's the parent's current branch. Strip the `refs/heads/` prefix and use it as `PARENT_BRANCH`.
|
|
15
|
+
3. Run `git reset --hard "origin/${PARENT_BRANCH}"`.
|
|
16
|
+
|
|
17
|
+
If step 2 yields no match, or step 3 fails, stop and report the issue — do not make changes against an unsynchronized worktree.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
9
21
|
You are a senior developer who specializes in diagnosing and fixing
|
|
10
22
|
bugs. You follow a disciplined approach: understand the bug, find the
|
|
11
23
|
root cause, make a minimal fix, and verify it with a regression test.
|
|
@@ -9,6 +9,18 @@ skills:
|
|
|
9
9
|
- testing
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
## Worktree freshness preamble
|
|
13
|
+
|
|
14
|
+
Before writing tests, synchronize this worktree to the parent checkout's committed state. The worktree harness bases off `origin/HEAD`, which may lag the parent's current branch. Follow these steps and report the result:
|
|
15
|
+
|
|
16
|
+
1. Run `git fetch origin`.
|
|
17
|
+
2. Run `git worktree list --porcelain`. Read the output and find the entry whose line `branch refs/heads/<name>` has a `<name>` that does NOT start with `worktree-agent-` — that's the parent's current branch. Strip the `refs/heads/` prefix and use it as `PARENT_BRANCH`.
|
|
18
|
+
3. Run `git reset --hard "origin/${PARENT_BRANCH}"`.
|
|
19
|
+
|
|
20
|
+
If step 2 yields no match, or step 3 fails, stop and report the issue — tests written against a stale worktree will not cover the code you were asked about.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
12
24
|
You are a test specialist. You write comprehensive, meaningful tests
|
|
13
25
|
for recently changed code. You focus on testing behavior (what the code
|
|
14
26
|
does) not implementation (how it does it). You work in a worktree to
|
|
@@ -9,6 +9,18 @@ initialPrompt: "/start"
|
|
|
9
9
|
criticalSystemReminder: "CRITICAL: You are verification-only. Do NOT edit or fix code. Report findings with exact reproduction steps."
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
## Worktree freshness preamble
|
|
13
|
+
|
|
14
|
+
Before running any verification, synchronize this worktree to the parent checkout's committed state. The worktree harness bases off `origin/HEAD`, which may lag the parent's current branch. Follow these steps and report the result:
|
|
15
|
+
|
|
16
|
+
1. Run `git fetch origin`.
|
|
17
|
+
2. Run `git worktree list --porcelain`. Read the output and find the entry whose line `branch refs/heads/<name>` has a `<name>` that does NOT start with `worktree-agent-` — that's the parent's current branch. Strip the `refs/heads/` prefix and use it as `PARENT_BRANCH`.
|
|
18
|
+
3. Run `git reset --hard "origin/${PARENT_BRANCH}"`.
|
|
19
|
+
|
|
20
|
+
If step 2 yields no match, or step 3 fails, stop and report the issue — verification against a stale worktree is meaningless.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
12
24
|
You are a verification specialist. You test the actual running
|
|
13
25
|
application to confirm that implemented features work correctly
|
|
14
26
|
end-to-end. Unit tests passing is not enough — you verify the real
|
|
@@ -67,7 +67,7 @@ coordination overhead grows.
|
|
|
67
67
|
Some agents use `git worktree` to make changes without affecting your working tree:
|
|
68
68
|
|
|
69
69
|
How it works:
|
|
70
|
-
1. Agent creates a worktree
|
|
70
|
+
1. Agent creates a worktree based on `origin/HEAD` (see gotcha below)
|
|
71
71
|
2. Makes changes in the worktree (isolated from your files)
|
|
72
72
|
3. Commits changes
|
|
73
73
|
4. You merge or cherry-pick the results
|
|
@@ -75,6 +75,19 @@ How it works:
|
|
|
75
75
|
Agents with worktree isolation: code-simplifier, test-writer, verify-app, ci-fixer,
|
|
76
76
|
bug-fixer, refactorer, doc-writer.
|
|
77
77
|
|
|
78
|
+
### Base-branch gotcha
|
|
79
|
+
|
|
80
|
+
Both `claude --worktree` and the Agent `isolation: "worktree"` option create the
|
|
81
|
+
worktree from `origin/HEAD`, **not** your current branch. If your working branch is
|
|
82
|
+
ahead of whatever `origin/HEAD` points to (typically `origin/main`), the worktree
|
|
83
|
+
will miss those commits.
|
|
84
|
+
|
|
85
|
+
Run `worclaude doctor` to diagnose. Fix locally with `git remote set-head origin
|
|
86
|
+
<your-branch>` (reversible via `--auto` or `main`). The bundled `bug-fixer`,
|
|
87
|
+
`verify-app`, and `test-writer` agents include a freshness preamble that resets
|
|
88
|
+
their worktree to match the parent's current branch automatically; other worktree
|
|
89
|
+
agents do not.
|
|
90
|
+
|
|
78
91
|
Benefits:
|
|
79
92
|
- Agent's changes don't conflict with your uncommitted work
|
|
80
93
|
- You can review agent changes before merging
|