worclaude 2.10.1 → 2.10.3

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 CHANGED
@@ -4,6 +4,42 @@ All notable changes to worclaude are documented in this file. Format loosely fol
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [2.10.3] — 2026-04-30
8
+
9
+ Fixes a user-reported breakage where every arrow-selectable prompt across `worclaude init` / `upgrade` / `restore` / `delete` accepted typed text instead of arrow-key navigation. Root cause: PR #169 (v2.10.0) bumped `inquirer` 12 → 13 with no code changes, but inquirer 13 renamed its legacy `list` prompt type to `select` and ships a runner that silently falls back to `type: 'input'` (free-text) for unknown types — so every `type: 'list'` site degraded silently. The "Everything look right?" prompt looped because typed `y`/`yes` did not strictly equal the choice value `'yes'`. Renames all 20 sites, migrates 4 index-based defaults to value-based (inquirer 13's `select` matches by value, not index), aligns the CLAUDE.md tech-stack metadata that had drifted behind `package.json` for three deps (Inquirer / Ora / Commander), and closes the test-suite blind spot — the prior `vi.mock('inquirer')` setup never inspected `spec.type`.
10
+
11
+ ### Fixed
12
+
13
+ - **Arrow-selectable prompts work again across init / upgrade / restore / delete** (PR #177) — renamed all 20 `type: 'list'` sites to `type: 'select'` across `src/commands/{init,upgrade,restore,delete}.js` and `src/prompts/{claude-md-merge,conflict-resolution,project-type,tech-stack}.js`. Migrated 4 index-based `default:` values to value-based: `init.js:93,111`, `restore.js:51`, `delete.js:113,156`. Without this, "Generate plugin.json?", "Scaffold memory files?", "Install GitHub Action?", "Everything look right?", "Which step do you want to adjust?", restore and delete confirmations, and the standalone hook-conflict / project-type / claude-md-merge prompts all rendered as silent free-text inputs.
14
+
15
+ ### Tests
16
+
17
+ - **Structural regression coverage for prompt types** (PR #177) — new `tests/utils/prompt-types.js` exposes `VALID_INQUIRER_TYPES` (the 10 v13 built-in prompt names) plus `expectAllValidPromptTypes(inquirer, label)` which inspects every captured `inquirer.prompt.mock.calls` spec and fails when any `type` is not a v13 built-in. New `tests/prompts/prompt-types.test.js` exercises the four standalone prompt modules + agent-selection. Single-line assertions added to `tests/commands/{init,upgrade,restore,delete}.test.js` so the ~30 sites in command files are also covered. Three stale `expect(spec.type).toBe('list')` assertions in `init.test.js` updated to `'select'`. Test counts: 992 → 999.
18
+
19
+ ### Docs
20
+
21
+ - **CLAUDE.md tech-stack metadata aligned with package.json** (PR #177) — Inquirer ^12.5.0 → ^13.4.2, Ora ^8.2.0 → ^9.4.0, Commander ^13.1.0 → ^14.0.3 (all three were drifted; CLAUDE.md's own "watch for breaking changes between majors" warning had not been acted on at the time of PR #169's bump). Two new Gotchas added: (1) the silent `type` → `input` fallback in inquirer 13's legacy runner (`node_modules/inquirer/dist/ui/prompt.js`), and (2) inquirer 13 `select` defaults take the choice value, not its index — `default: 1` (second choice) becomes `default: <that-choice's-value>`.
22
+
23
+ Release group: 1 PR (patch). v2.10.2 → v2.10.3. No missing declarations.
24
+
25
+ ## [2.10.2] — 2026-04-30
26
+
27
+ Bundles a dogfood catch-up of this repo's own `.claude/` (skipping from v2.8.0 to v2.10.1 in one upgrade run) with a real scaffold bug fix surfaced during that upgrade — `.claude/workflow-ref/` (transient upgrade-time conflict references) was missing from the scaffolder's `updateGitignore` entries, so every user running `worclaude upgrade` had those files pollute their git status. Also closes the BACKLOG "claude --worktree command visibility" item via a docs-only fix: investigation confirmed Claude Code does not create a "minimal `.claude/`" (the worktree's `.claude/` is a normal git checkout from `origin/HEAD`); the perceived missing-commands symptom was caused by main lagging develop, and the existing `subagent-usage` skill already documented the mechanism. The gap was direct `claude --worktree` users with no agent-mediated freshness preamble — filled with a one-paragraph copy-paste reset block.
28
+
29
+ ### Fixed
30
+
31
+ - **`.claude/workflow-ref/` now scaffolded into `.gitignore`** (PR #174) — `src/core/scaffolder.js` `updateGitignore` entries list now includes `.claude/workflow-ref/`. Existing users pick up the fix on the next scaffold or upgrade pass that runs `updateGitignore`. Two existing tests updated (`is idempotent` seed input + `writes exactly N entries` count 10 → 11 + expected array).
32
+
33
+ ### Docs
34
+
35
+ - **Manual freshness reset for direct `claude --worktree`** (PR #175) — added a copy-paste workaround block (`cd .claude/worktrees/<name> && git fetch origin && git reset --hard origin/<your-branch>`) to the existing "Base-branch gotcha" section of the `subagent-usage` skill, in both `templates/skills/universal/subagent-usage.md` and the dogfood mirror. Closes BACKLOG "claude --worktree command visibility" (the entry's "minimal `.claude/`" framing was wrong; investigation captured in the session summary).
36
+
37
+ ### Internal
38
+
39
+ - **Dogfood catch-up v2.8.0 → v2.10.1** (PR #174) — applied 3 release groups' worth of template evolution to this repo's own `.claude/`: sandbox.network block in settings.json (self-testing the v2.10.1 feature), observability hooks for UserPromptSubmit / InstructionsLoaded / SubagentStart / SubagentStop, 3 obs-\*.cjs hook scripts, 3 helper scripts under `.claude/scripts/`, and template-current versions of 5 slash commands plus the git-conventions skill that had drifted behind their templates.
40
+
41
+ Release group: 2 PRs (1 patch, 1 none). v2.10.1 → v2.10.2.
42
+
7
43
  ## [2.10.1] — 2026-04-29
8
44
 
9
45
  Adds opt-in scaffolding for Claude Code 2.1.113's `sandbox.network` deny/allow lists. Worclaude is a scaffolder, so the new `templates/settings/base.json` ships empty `deniedDomains` and `allowedDomains` stubs rather than an opinionated default list — project owners decide their own network policy. The merge paths for both fresh init (Scenario A) and existing-project init/upgrade (Scenarios B/C) union-merge the new arrays preserving any user-added domains, and a new `worclaude doctor` check warns when the block is missing or malformed (with `worclaude upgrade` as the remediation hint). Also bundles a Dependabot major bump to `commander` 14, which is now Node-20+-only and was unblocked by the v2.10.0 Node 18 drop.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "worclaude",
3
- "version": "2.10.1",
3
+ "version": "2.10.3",
4
4
  "description": "The Workflow Layer for Claude Code — scaffold agents, commands, skills, hooks, and memory into any project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -32,7 +32,7 @@ export async function deleteCommand() {
32
32
  // Step 1: Mode selection
33
33
  const { mode } = await inquirer.prompt([
34
34
  {
35
- type: 'list',
35
+ type: 'select',
36
36
  name: 'mode',
37
37
  message: 'What would you like to do?',
38
38
  choices: [
@@ -82,7 +82,7 @@ export async function deleteCommand() {
82
82
  display.newline();
83
83
  const { modifiedAction } = await inquirer.prompt([
84
84
  {
85
- type: 'list',
85
+ type: 'select',
86
86
  name: 'modifiedAction',
87
87
  message: `${classification.modified.length} file(s) have been customized. What should we do?`,
88
88
  choices: [
@@ -110,7 +110,7 @@ export async function deleteCommand() {
110
110
 
111
111
  const { rootAction } = await inquirer.prompt([
112
112
  {
113
- type: 'list',
113
+ type: 'select',
114
114
  name: 'rootAction',
115
115
  message: 'What would you like to do with these files?',
116
116
  choices: [
@@ -118,7 +118,7 @@ export async function deleteCommand() {
118
118
  { name: 'Let me choose which to remove', value: 'choose' },
119
119
  { name: 'Remove all', value: 'remove' },
120
120
  ],
121
- default: 0,
121
+ default: 'keep',
122
122
  },
123
123
  ]);
124
124
 
@@ -153,14 +153,14 @@ export async function deleteCommand() {
153
153
 
154
154
  const { confirm } = await inquirer.prompt([
155
155
  {
156
- type: 'list',
156
+ type: 'select',
157
157
  name: 'confirm',
158
158
  message: 'Confirm deletion?',
159
159
  choices: [
160
160
  { name: 'Yes, delete', value: true },
161
161
  { name: 'No, cancel', value: false },
162
162
  ],
163
- default: 1,
163
+ default: false,
164
164
  },
165
165
  ]);
166
166
 
@@ -83,14 +83,14 @@ async function runAgents(selections) {
83
83
  async function runOptionalExtras(selections) {
84
84
  const previouslySelected = new Set(selections.optionalFeatures || []);
85
85
  const questions = OPTIONAL_FEATURES.map((feature) => ({
86
- type: 'list',
86
+ type: 'select',
87
87
  name: feature.id,
88
88
  message: feature.label,
89
89
  choices: [
90
90
  { name: 'Yes', value: true },
91
91
  { name: 'No', value: false },
92
92
  ],
93
- default: previouslySelected.has(feature.id) ? 0 : 1,
93
+ default: previouslySelected.has(feature.id),
94
94
  }));
95
95
  const answers = await inquirer.prompt(questions);
96
96
  const optionalFeatures = OPTIONAL_FEATURES.filter((f) => answers[f.id]).map((f) => f.id);
@@ -100,7 +100,7 @@ async function runOptionalExtras(selections) {
100
100
  // at it. Phase 7 T7.3.
101
101
  const { installGithubAction } = await inquirer.prompt([
102
102
  {
103
- type: 'list',
103
+ type: 'select',
104
104
  name: 'installGithubAction',
105
105
  message:
106
106
  'Install Claude Code\'s GitHub Action for the @claude "compounding engineering" workflow?',
@@ -108,7 +108,7 @@ async function runOptionalExtras(selections) {
108
108
  { name: 'Yes — show me the install instructions now', value: true },
109
109
  { name: "No — I'll do it later", value: false },
110
110
  ],
111
- default: 1,
111
+ default: false,
112
112
  },
113
113
  ]);
114
114
 
@@ -179,7 +179,7 @@ async function showConfirmation(selections) {
179
179
 
180
180
  const { confirmation } = await inquirer.prompt([
181
181
  {
182
- type: 'list',
182
+ type: 'select',
183
183
  name: 'confirmation',
184
184
  message: 'Everything look right?',
185
185
  choices: [
@@ -241,7 +241,7 @@ async function runInteractivePrompts(projectRoot) {
241
241
  } else if (confirmation === 'adjust') {
242
242
  const { step } = await inquirer.prompt([
243
243
  {
244
- type: 'list',
244
+ type: 'select',
245
245
  name: 'step',
246
246
  message: 'Which step do you want to adjust?',
247
247
  choices: CONFIRMATION_STEPS,
@@ -772,7 +772,7 @@ export async function initCommand() {
772
772
 
773
773
  const { proceed } = await inquirer.prompt([
774
774
  {
775
- type: 'list',
775
+ type: 'select',
776
776
  name: 'proceed',
777
777
  message: 'Proceed with workflow installation?',
778
778
  choices: [
@@ -27,7 +27,7 @@ export async function restoreCommand() {
27
27
 
28
28
  const { selected } = await inquirer.prompt([
29
29
  {
30
- type: 'list',
30
+ type: 'select',
31
31
  name: 'selected',
32
32
  message: 'Select backup to restore:',
33
33
  choices,
@@ -48,14 +48,14 @@ export async function restoreCommand() {
48
48
 
49
49
  const { confirm } = await inquirer.prompt([
50
50
  {
51
- type: 'list',
51
+ type: 'select',
52
52
  name: 'confirm',
53
53
  message: 'Confirm restore?',
54
54
  choices: [
55
55
  { name: 'Yes', value: true },
56
56
  { name: 'No', value: false },
57
57
  ],
58
- default: 1,
58
+ default: false,
59
59
  },
60
60
  ]);
61
61
 
@@ -233,7 +233,7 @@ async function applyRepairPass(projectRoot, plan, variables) {
233
233
  async function promptProceed(message) {
234
234
  const { proceed } = await inquirer.prompt([
235
235
  {
236
- type: 'list',
236
+ type: 'select',
237
237
  name: 'proceed',
238
238
  message,
239
239
  choices: [
@@ -357,7 +357,7 @@ async function promptAndScaffoldOptionalFeatures(projectRoot, meta, { yes, dryRu
357
357
  for (const feature of available) {
358
358
  const { accept } = await inquirer.prompt([
359
359
  {
360
- type: 'list',
360
+ type: 'select',
361
361
  name: 'accept',
362
362
  message: feature.label,
363
363
  choices: [
@@ -397,7 +397,7 @@ export async function upgradeCommand(options = {}) {
397
397
  );
398
398
  const { doUpdate } = await inquirer.prompt([
399
399
  {
400
- type: 'list',
400
+ type: 'select',
401
401
  name: 'doUpdate',
402
402
  message: 'Update worclaude CLI?',
403
403
  choices: [
@@ -533,7 +533,7 @@ export async function upgradeCommand(options = {}) {
533
533
  agentReport = await patchAgentDescriptions(projectRoot, meta, async (agentName) => {
534
534
  const { patch } = await inquirer.prompt([
535
535
  {
536
- type: 'list',
536
+ type: 'select',
537
537
  name: 'patch',
538
538
  message: `Agent "${agentName}" has been customized. Add missing description field?`,
539
539
  choices: [
@@ -78,6 +78,7 @@ export async function updateGitignore(projectDir) {
78
78
  '.claude/cache/',
79
79
  '.claude/scratch/',
80
80
  '.claude/observability/',
81
+ '.claude/workflow-ref/',
81
82
  ];
82
83
  const header = '# Worclaude (generated workflow files)';
83
84
 
@@ -107,7 +107,7 @@ export async function promptClaudeMdMerge(existingContent, missingSections) {
107
107
 
108
108
  const { choice } = await inquirer.prompt([
109
109
  {
110
- type: 'list',
110
+ type: 'select',
111
111
  name: 'choice',
112
112
  message: 'How would you like to handle CLAUDE.md?',
113
113
  choices: [
@@ -139,7 +139,7 @@ export async function interactiveSectionMerge(existingContent, renderedTemplate,
139
139
 
140
140
  const { addSection } = await inquirer.prompt([
141
141
  {
142
- type: 'list',
142
+ type: 'select',
143
143
  name: 'addSection',
144
144
  message: `Add "${sectionName}" to your CLAUDE.md?`,
145
145
  choices: [
@@ -16,7 +16,7 @@ export async function promptHookConflict(hookCategory, existingHook, workflowHoo
16
16
 
17
17
  const { resolution } = await inquirer.prompt([
18
18
  {
19
- type: 'list',
19
+ type: 'select',
20
20
  name: 'resolution',
21
21
  message: 'How would you like to resolve this?',
22
22
  choices: [
@@ -37,7 +37,7 @@ export async function promptProjectType() {
37
37
  display.dim('You may not need both.');
38
38
  const { continueAnyway } = await inquirer.prompt([
39
39
  {
40
- type: 'list',
40
+ type: 'select',
41
41
  name: 'continueAnyway',
42
42
  message: 'Continue anyway?',
43
43
  choices: [
@@ -20,7 +20,7 @@ export async function promptTechStack(_projectTypes) {
20
20
 
21
21
  const { useDocker } = await inquirer.prompt([
22
22
  {
23
- type: 'list',
23
+ type: 'select',
24
24
  name: 'useDocker',
25
25
  message: 'Do you use Docker currently?',
26
26
  choices: [
@@ -88,6 +88,14 @@ Run `worclaude doctor` to diagnose. Fix locally with `git remote set-head origin
88
88
  their worktree to match the parent's current branch automatically; other worktree
89
89
  agents do not.
90
90
 
91
+ If you invoke `claude --worktree` directly (not via an agent), no preamble runs
92
+ — sync the worktree manually before doing real work:
93
+
94
+ ```bash
95
+ cd .claude/worktrees/<name>
96
+ git fetch origin && git reset --hard origin/<your-working-branch>
97
+ ```
98
+
91
99
  Benefits:
92
100
  - Agent's changes don't conflict with your uncommitted work
93
101
  - You can review agent changes before merging