@haus-tech/haus-workflow 4.3.0 → 4.5.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 CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.5.0](https://github.com/WeAreHausTech/haus-workflow/compare/v4.4.0...v4.5.0) (2026-08-25)
4
+
5
+ ### Features
6
+
7
+ - **skill:** consolidate /haus-workflow to 7 scope-aware tasks ([#352](https://github.com/WeAreHausTech/haus-workflow/issues/352)) ([5f31286](https://github.com/WeAreHausTech/haus-workflow/commit/5f3128656366360ba68efb10e5ee1152247f2288))
8
+ - **skills:** dela poster som inte går att ringa in, prissätt saknad testtäckning ([#351](https://github.com/WeAreHausTech/haus-workflow/issues/351)) ([ef4fe36](https://github.com/WeAreHausTech/haus-workflow/commit/ef4fe36fc8dc03dbd04914668401e96ce2a5c2b6))
9
+ - **skills:** price the simplest option that solves the problem, offer the rest ([#349](https://github.com/WeAreHausTech/haus-workflow/issues/349)) ([ad557ef](https://github.com/WeAreHausTech/haus-workflow/commit/ad557efc492ae001d0b69751526a7643a87948c6))
10
+ - **skills:** request-sync writes a score instead of a class ([#348](https://github.com/WeAreHausTech/haus-workflow/issues/348)) ([f0ba914](https://github.com/WeAreHausTech/haus-workflow/commit/f0ba91463c414cc67cd23aad8f888d113252d26f))
11
+
12
+ ### Bug Fixes
13
+
14
+ - **doctor:** stop reading inline code spans as skill references ([#354](https://github.com/WeAreHausTech/haus-workflow/issues/354)) ([5f264bd](https://github.com/WeAreHausTech/haus-workflow/commit/5f264bddeb3aacb87bcace2fdce1cc0b8c8c52bb)), closes [#259](https://github.com/WeAreHausTech/haus-workflow/issues/259) [#350](https://github.com/WeAreHausTech/haus-workflow/issues/350)
15
+ - **skill:** close review gaps from [#352](https://github.com/WeAreHausTech/haus-workflow/issues/352) in haus-workflow scope detection ([#353](https://github.com/WeAreHausTech/haus-workflow/issues/353)) ([f02ff1f](https://github.com/WeAreHausTech/haus-workflow/commit/f02ff1ff58616eca0cba4bbc9f34aa714370a751))
16
+
17
+ ## [4.4.0](https://github.com/WeAreHausTech/haus-workflow/compare/v4.3.0...v4.4.0) (2026-08-24)
18
+
19
+ ### Features
20
+
21
+ - **skills:** add request-score and let assess describe open outcome choices ([#347](https://github.com/WeAreHausTech/haus-workflow/issues/347)) ([09bd070](https://github.com/WeAreHausTech/haus-workflow/commit/09bd0709c5123fb9d82a0410fa995020beb384a6))
22
+
3
23
  ## [4.3.0](https://github.com/WeAreHausTech/haus-workflow/compare/v4.2.0...v4.3.0) (2026-08-24)
4
24
 
5
25
  ### Features
package/README.md CHANGED
@@ -32,22 +32,20 @@ re-run or repair any time with `haus install`. Undo with `haus uninstall`.
32
32
 
33
33
  Once installed, Claude Code gains a `/haus-workflow` slash command.
34
34
 
35
- The `project:*` tasks act on the current repo. The unprefixed verbs (`update`,
36
- `install`, `uninstall`) manage the haus tool itself on your machine
37
- (`~/.claude` + npm), like `npm install -g`. The short legacy names still work.
35
+ Task names are plain verbs; each detects its own scope (a single haus-set-up repo, a
36
+ multi-repo workspace, or neither) before acting. `refresh` also updates this machine's
37
+ haus install (`~/.claude`, npm) first; `uninstall` acts ONLY on the machine, never on a
38
+ repo. Every old `project:`-prefixed name (and other legacy aliases like `setup`, `fix`,
39
+ `add-skills`) still works as an alias into the task it merged into.
38
40
 
39
41
  ```
40
- /haus-workflow # interactive menu — pick a task
41
- /haus-workflow project:init # [project] add haus to an EXISTING repo — AI skills, commands, workflow + docs
42
- /haus-workflow project:reinit # [project] full re-setup from scratch (removes haus-managed files first, backed up)
43
- /haus-workflow project:clone [name] # [project] clone a workspace's repos (repos.manifest.json), or find & clone one repo by name from GitHub
44
- /haus-workflow project:cloneandsetup [name] # [project] like project:clone, then set up each repo locally (node version, deps, .env)
45
- /haus-workflow project:add-skills # [project] add optional skills/agents/config to an already-set-up project
46
- /haus-workflow project:refresh # [project] refresh .claude/ and regenerate CLAUDE.md imports
47
- /haus-workflow project:doctor # [project] health check for drift
48
- /haus-workflow project:fix # [project] diagnose drift and apply the suggested fixes
49
- /haus-workflow update # [global] update npm package + catalog + ~/.claude/
50
- /haus-workflow install / uninstall # [global] seed or remove haus-owned files under ~/.claude/
42
+ /haus-workflow # interactive menu — pick a task
43
+ /haus-workflow init # set up this project (or workspace) with haus; offers refresh/clean-slate when already set up
44
+ /haus-workflow clone [name] # clone one repo by name, or a whole workspace (repos.manifest.json); offers local-dev setup after
45
+ /haus-workflow new [description] # create a brand-new project from a plain-language request
46
+ /haus-workflow doctor # health check for this project or workspace; offers to apply suggested fixes
47
+ /haus-workflow refresh # update haus itself (package + catalog + ~/.claude), then fully sync this project or just add optional helpers
48
+ /haus-workflow uninstall # remove haus global files from ~/.claude — never touches this project
51
49
  ```
52
50
 
53
51
  Without an argument, the skill presents a menu so you can pick the task. With an argument, it runs immediately.
@@ -59,7 +57,7 @@ Without an argument, the skill presents a menu so you can pick the task. With an
59
57
  ```bash
60
58
  haus init # full setup: scan → recommend → apply (safe to re-run)
61
59
  haus init --dry-run # preview the .claude/ write only; scan artifacts are still written
62
- haus clone <url> [dir] # clone a single git repo by URL (the primitive project:clone / project:cloneandsetup loop over)
60
+ haus clone <url> [dir] # clone a single git repo by URL (the primitive the clone/cloneandsetup tasks loop over)
63
61
  haus scan # scan repo and write context-map
64
62
  haus recommend # recommend catalog items (binary eligibility)
65
63
  haus apply --dry-run # preview what would be written
package/dist/cli.js CHANGED
@@ -6499,6 +6499,14 @@ var REFERENCE_PATTERN = /\b([a-z][a-z0-9]*(?:-[a-z0-9]+)+):([a-z][a-z0-9]*(?:-[a
6499
6499
  function stripFencedCodeBlocks(text) {
6500
6500
  return text.replace(/```[\s\S]*?```/g, (block) => block.replace(/[^\n]/g, " "));
6501
6501
  }
6502
+ var INLINE_CODE_SPAN = /(`+)(?!`)[\s\S]*?\1/g;
6503
+ function inlineCodeSpanRanges(line2) {
6504
+ const ranges = [];
6505
+ for (const match of line2.matchAll(INLINE_CODE_SPAN)) {
6506
+ ranges.push([match.index, match.index + match[0].length]);
6507
+ }
6508
+ return ranges;
6509
+ }
6502
6510
  async function findUnresolvedSkillReferences(root, options = {}) {
6503
6511
  const resolvableNamespaces = new Set(options.pluginNamespaces ?? []);
6504
6512
  const skillsRoot = claudePath(root, "skills");
@@ -6513,10 +6521,15 @@ async function findUnresolvedSkillReferences(root, options = {}) {
6513
6521
  const raw = await fs30.readFile(abs, "utf8");
6514
6522
  const lines = stripFencedCodeBlocks(raw).split("\n");
6515
6523
  lines.forEach((line2, idx) => {
6524
+ const codeSpans = inlineCodeSpanRanges(line2);
6516
6525
  for (const match of line2.matchAll(REFERENCE_PATTERN)) {
6517
6526
  const [reference, namespace, bareName] = match;
6518
6527
  if (!reference || !bareName) continue;
6519
6528
  if (namespace && resolvableNamespaces.has(namespace)) continue;
6529
+ const inCodeSpan = codeSpans.some(
6530
+ ([start, end]) => match.index >= start && match.index < end
6531
+ );
6532
+ if (inCodeSpan && !installedSkillNames.has(bareName)) continue;
6520
6533
  issues.push({
6521
6534
  file: path32.join(".claude/skills", rel),
6522
6535
  line: idx + 1,
@@ -9063,7 +9076,7 @@ async function runFromHookCheck(root) {
9063
9076
  JSON.stringify({
9064
9077
  hookSpecificOutput: {
9065
9078
  hookEventName: "SessionStart",
9066
- additionalContext: `This project's haus setup is behind: ${reasons.join("; ")}. Suggest running \`/haus-workflow project:refresh\` to bring it up to date.`
9079
+ additionalContext: `This project's haus setup is behind: ${reasons.join("; ")}. Suggest running \`/haus-workflow refresh\` to bring it up to date.`
9067
9080
  }
9068
9081
  })
9069
9082
  );
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: haus-workflow
3
- description: Haus all-in-one workflow skill. Handles project setup, re-init, update, catalog refresh, health checks, and CLAUDE.md regeneration. Invoke with a task name or without to get a menu.
3
+ description: Haus all-in-one workflow skill. Scope-aware tasks: init, clone, new, doctor, refresh (update + add helpers), uninstall, help. Invoke with a task name or without to get a menu.
4
4
  ---
5
5
 
6
6
  # haus-workflow
@@ -17,34 +17,30 @@ this skill — there are no separate `/haus-setup`, `/haus-clone`, `/haus-clonea
17
17
 
18
18
  ## Task aliases → commands
19
19
 
20
- Task names use an asymmetric scope convention. The **project:** namespace marks tasks that
21
- act on **this repo** (`./.claude`, `./.haus-workflow`) — type `project:` to see them all.
22
- The unprefixed verbs (`update`, `install`, `uninstall`, `help`) act on **this machine's
23
- haus install** (`~/.claude`, npm) or are purely informational — they don't act on this
24
- repo's files. The short legacy aliases still work but the names below are canonical.
25
-
26
- | Task name (legacy aliases) | Command | Scope | What it does |
27
- | ----------------------------------------------------------------- | ------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
28
- | `project:init` (`setup`, `init`) | _Setup procedure below_ | project | First-time setup of an **existing** repo: adds AI skills, commands, workflow + project docs |
29
- | `project:reinit` (`reinit`, `re-init`) | _Reinit procedure below_ | project | **Full re-setup.** Removes all haus-managed project files (backed up first, user content preserved), then re-runs `project:init` from scratch |
30
- | `project:clone [name]` (`clone`) | _Clone procedure below_ | project | With a `name`: find & clone one repo by name from GitHub. No name: asks single-repo-vs-workspace first, then either mode — workspace mode clones from `repos.manifest.json` |
31
- | `project:cloneandsetup [name]` (`cloneandsetup`) | _Clone & setup procedure below_ | project | Run `project:clone`, then set up each repo for local dev — deps, databases, cross-repo links, and env — via each repo's `.haus-workflow/localdev.yml` (+ the workspace's order/links/env) |
32
- | `project:new [description]` (`new`, `create`) | _New-project procedure below_ | project | Create a **brand-new** project from a plain-language request: elicit features, pick the stack (any — registry stacks use the haus new rails), scaffold, git + GitHub repo, full init, then build a walking skeleton — all in one session |
33
- | `project:add-skills` (`add-skills`, `opt-in`) | _Add-skills procedure below_ | project | Add optional skills, agents, or config (ESLint/Prettier) to an already-set-up project without re-running full setup |
34
- | `project:refresh` (`apply`, `refresh`, `claude-md`, `regenerate`) | _Refresh procedure below_ | project | **Full non-destructive sync.** Updates the haus package + catalog first, then re-runs `project:init`'s pipeline in place — nothing is removed up front; new catalog items get added, changed ones updated, and anything removed upstream gets pruned by `apply`'s existing orphan-pruning |
35
- | `project:doctor` (`doctor`, `check`) | `haus doctor` | project | Check for install drift |
36
- | `project:fix` (`fix`) | _Fix procedure below_ | project | Diagnose and fix install drift: run doctor, apply the suggested fixes, confirm green |
37
- | `update` (`upgrade`) | `haus update` | global | Update npm package + catalog + `~/.claude/`; if run inside an already-set-up project, fully refreshes it too (same pipeline as `project:refresh`) |
38
- | `install` (`global`) | `haus install` | global | Seed `~/.claude/` with haus-owned files |
39
- | `uninstall` | `haus uninstall` | global | Remove all haus global files from `~/.claude/` |
40
- | `help` (`?`) | _Answer directly below_ | — | Explain what haus-workflow is, list available tasks, point to deeper docs — touches no files |
20
+ Task names are plain verbs. Every task detects its own scope first (see Step 1.5):
21
+ a single haus-set-up repo, a multi-repo workspace, or neither. `refresh` additionally
22
+ acts on this machine's haus install (`~/.claude`, npm) before touching any repo;
23
+ `uninstall` acts ONLY on the machine, never on a repo. The old `project:`-prefixed
24
+ names and all other legacy aliases still work — an alias that named a merged
25
+ sub-flow (e.g. `fix`, `add-skills`, `reinit`, `cloneandsetup`) jumps straight into
26
+ that branch of the merged task.
27
+
28
+ | Task name (aliases) | Command | What it does |
29
+ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
30
+ | `init` (`setup`, `project:init`, `reinit`, `re-init`, `project:reinit`) | _Init procedure below_ | State-aware setup. Not set up → first-time init (skills, commands, workflow + project docs). Already set up → asks: non-destructive refresh, or clean slate (confirmed wipe via `haus undo --yes` / `haus workspace undo`, then re-init). `reinit` aliases jump straight to the clean-slate branch (still confirmed). |
31
+ | `clone [name]` (`project:clone`, `cloneandsetup`, `project:cloneandsetup`) | _Clone procedure below_ | Clone one repo by name, or a whole workspace from `repos.manifest.json`. Afterwards asks "set up for local dev too?" (deps, databases, links, env via `localdev.yml`). `cloneandsetup` aliases pre-answer that question with yes. |
32
+ | `new [description]` (`create`, `project:new`) | _New-project procedure below_ | Create a brand-new project from a plain-language request — unchanged seven-phase flow. |
33
+ | `doctor` (`check`, `fix`, `project:doctor`, `project:fix`) | _Doctor procedure below_ | Health check for the detected scope; relays the verdict, then offers to apply the doctor's own suggested fixes and re-checks until green. `fix` aliases pre-answer "fix now?" with yes. |
34
+ | `refresh` (`update`, `upgrade`, `apply`, `regenerate`, `claude-md`, `project:refresh`, `add-skills`, `opt-in`, `project:add-skills`, `install`, `global`) | _Refresh procedure below_ | Bring haus current. Always: update npm package + catalog + `~/.claude` (seeding it first if never installed). Inside a set-up project/workspace, asks: **Full sync** (re-run the whole setup pipeline in place) or **Just add helpers** (offer opt-in skills/agents + configs only). `add-skills`/`opt-in` aliases jump to the helpers branch; outside any project it stops after the global update. |
35
+ | `uninstall` | `haus uninstall` | Remove all haus global files from `~/.claude/`. Machine scope only — confirm gate states this does NOT touch the current project (that's `init` → clean slate). |
36
+ | `help` (`?`) | _Answer directly_ | Explain what haus-workflow is, list tasks, point to deeper docs — touches no files. |
41
37
 
42
38
  ## Step 1 — Determine the task
43
39
 
44
- **If a task argument was passed:** look it up in the alias table above. If no match, tell the user and list valid options. If matched, skip to Step 2.
40
+ **If a task argument was passed:** look it up in the alias table above. If no match, tell the user and list valid options. If matched, skip to Step 1.5.
45
41
 
46
42
  **If no task was passed:** the menu has more options than one `AskUserQuestion` question can
47
- hold (max 4 options per question). Page through all 13 tasks in batches: each page shows the
43
+ hold (max 4 options per question). Page through all 7 tasks in batches: each page shows the
48
44
  next 3 tasks plus a 4th "More options" choice, except the last page, which shows whatever
49
45
  tasks remain (≤4) with no continuation choice — nothing is dropped, and this pattern
50
46
  generalizes automatically if a task is ever added to or removed from the alias table above
@@ -55,192 +51,173 @@ into a single `AskUserQuestion` call:
55
51
  ```
56
52
  Question 1: "What would you like to do?"
57
53
  Options:
58
- 1. [project] project:init — add haus to an existing project for the first time
59
- (AI skills + commands + workflow into a repo you already have, then a deep read to write the CLAUDE.md docs body + docs/)
60
- 2. [project] project:new [description] — create a brand-new project from a plain-language request
61
- (elicit features, pick any stack, scaffold, git + GitHub repo, full init, then build a walking skeleton)
62
- 3. [project] project:refresh — full non-destructive sync with the latest haus
63
- (updates the haus package + catalog, then re-runs setup in place — nothing removed first)
64
- 4. [—] More options — see: project:clone, project:cloneandsetup, project:add-skills, and 7 more
65
-
66
- Question 2: "What would you like to do?" (only shown if "More options" was picked)
67
- Options:
68
- 1. [project] project:clone [name] — clone repos
69
- (picked from here with no name yet — clone.md will ask whether it's a single repo or a whole workspace next)
70
- 2. [project] project:cloneandsetup [name] — clone repos, then set them up for local dev
71
- (project:clone — asking single-repo-vs-workspace since no name is known yet — then per-repo deps + databases + cross-repo links + env from localdev.yml)
72
- 3. [project] project:add-skills — add optional skills, agents, or config to this project
73
- (offers opt-in helpers matching your stack that aren't installed yet — no full re-setup)
74
- 4. [—] More options — see: project:reinit, update, project:doctor, and 4 more
75
-
76
- Question 3: "What would you like to do?" (only shown if "More options" was picked again)
77
- Options:
78
- 1. [project] project:reinit — full re-setup from scratch
79
- (removes all haus-managed project files, backed up first, then re-runs project:init)
80
- 2. [global] update — update haus package + catalog + global files
81
- (haus update — checks npm for new version, fetches catalog, refreshes ~/.claude/)
82
- 3. [project] project:doctor — check for install drift
83
- (haus doctor — a one-line plain-language verdict, healthy or a list of what needs attention)
84
- 4. [—] More options — see: project:fix, install, uninstall, help
85
-
86
- Question 4: "What would you like to do?" (only shown if "More options" was picked a third time — last page, no further continuation)
54
+ 1. init — set up this project (or workspace) with haus; offers refresh/clean-slate when already set up
55
+ 2. new [description] — create a brand-new project from a plain-language request
56
+ 3. refresh — update haus itself, then fully sync this project (or just add optional helpers)
57
+ 4. More options — see: clone, doctor, uninstall, help
58
+
59
+ Question 2 (only if "More options"):
87
60
  Options:
88
- 1. [project] project:fix — diagnose and fix install drift
89
- (runs doctor, applies the suggested fixes, confirms green)
90
- 2. [global] install — seed ~/.claude/ with haus-owned files
91
- (haus install)
92
- 3. [global] uninstall — remove all haus global files from ~/.claude/
93
- (haus uninstall)
94
- 4. [—] help — explain what haus-workflow is and list all available tasks
95
- (touches no files — points to docs/cli.md and docs/runbook.md for depth)
61
+ 1. clone [name] — clone one repo or a whole workspace; offers local-dev setup after
62
+ 2. doctor — health check for this project or workspace; offers to fix what it finds
63
+ 3. uninstall — remove haus global files from ~/.claude (never touches this project)
64
+ 4. help — explain haus-workflow and list all tasks; touches no files
96
65
  ```
97
66
 
98
- Map the user's selection to the command from the alias table, then continue to Step 2.
67
+ Map the user's selection to the command from the alias table, then continue to Step 1.5.
99
68
 
100
- ## Step 2 — Run the command
69
+ ## Step 1.5 — Detect scope
101
70
 
102
- Run the mapped command via Bash. Quote the exact command you are running before executing it.
71
+ Before running anything, determine what the current directory is. Check in order:
103
72
 
104
- **Exception — `project:init` (`setup` / `init`):** this maps to a multi-step procedure that drives `haus init --json --dry-run` plus follow-up commands, not a single command. Skip to **Setup (`project:init`)** under Step 3 and follow it.
73
+ 1. **Workspace** — `haus.workspace.yaml` or `repos.manifest.json` exists at the git
74
+ root (`git rev-parse --show-toplevel`, falling back to cwd outside a repo).
75
+ 2. **Member repo of a workspace** — the git root has `.haus-workflow/` (or is simply
76
+ a repo) AND a parent directory holds `haus.workspace.yaml`/`repos.manifest.json`.
77
+ Ambiguous — ask via `AskUserQuestion`: "Run this for this repo only, or the whole
78
+ workspace?" (options: This repo / Whole workspace). Never guess.
79
+ 3. **Project** — the git root has `.haus-workflow/` and `haus.lock.json`.
80
+ 4. **Not set up** — none of the above. `init`, `new`, and `clone` proceed in project
81
+ scope; `doctor` says the project isn't set up yet and suggests `init`; `refresh`
82
+ runs its global half only.
105
83
 
106
- **Exception — `project:reinit` (`reinit` / `re-init`):** removes files before re-running setup. Skip to **Reinit (`project:reinit`)** under Step 3 and follow it.
84
+ Workspace scope routes to the `haus workspace` subcommands named in each procedure;
85
+ project scope routes to the plain commands. `help` and `uninstall` skip this step.
107
86
 
108
- **Exception — `project:clone` (`clone`):** this asks the user a question before running, so it is a short procedure too. Skip to **Clone (`project:clone`)** under Step 3 and follow it.
87
+ ## Step 2 — Run the command
88
+
89
+ Run the mapped command via Bash. Quote the exact command you are running before executing it.
109
90
 
110
- **Exception — `project:cloneandsetup` (`cloneandsetup`):** clone followed by a per-repo setup pass, with confirmations. Skip to **Clone & setup (`project:cloneandsetup`)** under Step 3 and follow it.
91
+ **Exception — `init` (`setup` / `reinit` / `re-init` / `project:init` / `project:reinit`):** this maps to a multi-step procedure, not a single command. Skip to **Init (`init`)** under Step 3 and follow it. `reinit` aliases jump to the clean-slate branch of step 0 (still confirmed).
111
92
 
112
- **Exception — `project:new` (`new` / `create`):** a multi-phase AI-driven procedure — elicits the request via `AskUserQuestion`, picks the stack itself, scaffolds (registry rails or a user-confirmed official scaffolder), then builds a walking skeleton. Skip to **New project (`project:new`)** under Step 3 and follow it.
93
+ **Exception — `clone` (`project:clone` / `cloneandsetup` / `project:cloneandsetup`):** this asks the user a question before running, so it is a short procedure too. Skip to **Clone (`clone`)** under Step 3 and follow it. `cloneandsetup` aliases pre-answer the local-dev setup question with yes.
113
94
 
114
- **Exception — `project:add-skills` (`add-skills` / `opt-in`):** a short scan → recommend → choose → apply procedure. Skip to **Add optional skills (`project:add-skills`)** under Step 3 and follow it.
95
+ **Exception — `new` (`create` / `project:new`):** a multi-phase AI-driven procedure — elicits the request via `AskUserQuestion`, picks the stack itself, scaffolds (registry rails or a user-confirmed official scaffolder), then builds a walking skeleton. Skip to **New project (`new`)** under Step 3 and follow it.
115
96
 
116
- **Exception — `project:refresh` (`apply` / `refresh` / `claude-md` / `regenerate`):** updates the haus package first, then re-runs the setup pipeline — not a single command. Skip to **Refresh (`project:refresh`)** under Step 3 and follow it.
97
+ **Exception — `refresh` (`update` / `upgrade` / `apply` / `regenerate` / `claude-md` / `project:refresh` / `add-skills` / `opt-in` / `project:add-skills` / `install` / `global`):** updates haus itself first, then optionally syncs the project — not a single command. Skip to **Refresh (`refresh`)** under Step 3 and follow it. `add-skills`/`opt-in` aliases jump to the helpers branch.
117
98
 
118
- **Exception — `project:fix` (`fix`):** diagnose-then-fix loop, not a single command. Skip to **Fix (`project:fix`)** under Step 3 and follow it.
99
+ **Exception — `doctor` (`check` / `fix` / `project:doctor` / `project:fix`):** diagnose-then-fix loop, not a single command. Skip to **Doctor (`doctor`)** under Step 3 and follow it. `fix` aliases pre-answer "fix now?" with yes.
119
100
 
120
101
  **Exception — `help` (`?`):** no command runs at all. Skip Step 2 and Step 3 — answer directly from the task alias table above, plus `docs/cli.md` and `docs/runbook.md` for deeper detail on any specific task.
121
102
 
103
+ **Exception — `uninstall`:** run `haus uninstall` after an `AskUserQuestion` confirm gate that states this removes haus's global files from `~/.claude/`, not anything in the current project. Then skip to **After `haus uninstall`**.
104
+
122
105
  ## Step 3 — Post-run steps
123
106
 
124
107
  After the command completes, follow the relevant post-run steps below.
125
108
 
126
- ### Setup (`project:init`)
127
-
128
- 1. Open and follow `references/init.md` in this skill's directory. Run every step in order. It detects the stack, runs `haus apply --write` (scaffolding, skills, commands, rules, docs skill), writes the **project docs** (`CLAUDE.md` body + `docs/`) and `.haus-workflow/deep-context.json`, runs `haus recommend`, applies the newly-matched helpers, and confirms.
129
- 2. Then fill `.haus-workflow/workflow-config.md` — replace every placeholder (`TODO`, `n/a`, empty): test/lint/typecheck/build commands (check `package.json`), docs paths, validation library, pre-commit tool, highest-stakes logic (ask if unclear). Leave none.
130
-
131
- ### Reinit (`project:reinit`)
132
-
133
- Full re-setup — removes everything haus manages in this project and starts over. Use when
134
- the project's haus setup is badly out of sync and a plain `project:fix`/`project:refresh`
135
- isn't enough, or the user explicitly wants a clean slate.
136
-
137
- 1. **Confirm first, always** — via `AskUserQuestion`. Explain plainly: this removes all
138
- haus-managed files in this project (commands, skills, rules, workflow docs; `haus undo`
139
- backs them up first and never touches user-owned `.claude/` content or `.haus-workflow`
140
- docs you've edited), then re-runs setup from scratch. Offer **Cancel**.
141
- 2. On confirm, run `haus undo --yes` (already backs up + preserves user content — no need
142
- to ask a second time).
143
- 3. Immediately follow **Setup (`project:init`)** above, end to end.
144
- 4. Report what was removed, backed up (path), and re-added, in plain language.
145
-
146
- ### Refresh (`project:refresh`)
147
-
148
- Full non-destructive sync — nothing is removed up front (contrast with `project:reinit`,
149
- which wipes first). Use for routine "bring this project up to date with the latest haus"
150
- maintenance: new catalog items get added, changed ones updated, and anything removed
151
- upstream gets pruned automatically by `apply`'s existing orphan-pruning.
152
-
153
- 1. Run `haus update`. This bumps the npm package (or reports one's available), syncs the
154
- catalog cache, refreshes `~/.claude/`, and does a light re-apply of this project's
155
- already-tracked files. Apply the same reactions as **After `haus update`** below
156
- (version-bump command, `WORKFLOW.md` update nudge, catalog-changes summary).
157
- 2. Immediately follow **Setup (`project:init`)** above, end to end. Re-running it is safe
158
- on an already-set-up project — it re-scans, re-applies, redoes the deep docs read (so
159
- `CLAUDE.md`/`docs/` catch up with any code drift), and re-recommends against the
160
- now-current catalog.
161
- 3. Report what changed in plain language — package/catalog version bumps, docs
162
- refreshed, helpers added/updated/removed.
163
-
164
- ### Clone (`project:clone`)
165
-
166
- 1. Open and follow `references/clone.md` in this skill's directory. With a `name` argument it finds and clones one matching repo from GitHub; with no argument (e.g. reached via the no-arg menu) it starts with clone.md's Step 0, which asks whether this is a single repo or a whole workspace before picking a mode. This task only clones — to also install dependencies, use `project:cloneandsetup`.
167
-
168
- ### Clone & setup (`project:cloneandsetup`)
169
-
170
- 1. Open and follow `references/cloneandsetup.md` in this skill's directory — it runs the full `project:clone` flow (including clone.md's Step 0 when no name is already known), then sets up each cloned repo locally: selects the node version (`nvm install` from `.nvmrc`), enables corepack, installs JS/PHP dependencies, and seeds `.env`, confirming before each phase. It does not start servers.
171
-
172
- ### New project (`project:new`)
173
-
174
- 1. Open and follow `references/new.md` in this skill's directory. It is a seven-phase AI-driven flow: elicit the request and propose features, gate on user intent, scaffold (registry stacks via `haus new --json --yes` with a `--dry-run` preview; any other stack via a user-confirmed official scaffolder plus manual rails), install context via `haus init`, seed `docs/SPEC.md` + `docs/plans/walking-skeleton.md`, build the walking skeleton with one subagent per feature (against a structure recorded in `docs/DESIGN.md`), verify (build + lint + tests + smoke boot), then write the project docs by following `references/init.md` from step 3 (deep read, `CLAUDE.md` body + `docs/`, recommend re-check, opt-ins). Repos are only ever created private. Failure `detail` is relayed verbatim and nothing is ever auto-deleted. Never run bare interactive `haus new`.
175
-
176
- ### Add optional skills (`project:add-skills`)
177
-
178
- For a project that's already set up but where the user wants more helpers later —
179
- without re-running the full `project:init` flow. Never show raw JSON; offer plain
180
- choices.
181
-
182
- 1. Refresh the picture: run `haus scan --json` then `haus recommend` (it re-reads
183
- `.haus-workflow/deep-context.json` if present).
184
- 2. Read `.haus-workflow/recommendation.json` and `.haus-workflow/haus.lock.json`
185
- yourself. Build the choices from items **not already installed** (lock ids):
186
- - **Optional skills & agents** — `optInEligible[]`, grouped by `optInGroup`
187
- (each carries `purpose` + `tokenEstimate` for a plain-language label).
188
- - **Project config** — `recommended[]` entries with `install: false` (Haus
189
- ESLint / Prettier) whose files aren't already present.
190
- 3. If nothing is eligible, say so plainly and stop — e.g. "Everything matching
191
- your stack is already installed" or "No optional helpers for this stack."
192
- 4. Otherwise present a single `AskUserQuestion` (multi-select, all unchecked)
193
- with one option per group / config item. Then:
194
- - Skills/agents → `haus recommend --include <id> <id> …`, then
195
- `haus apply --write`.
196
- - Config → `haus configs <id>` (add `--force` only if the user chose to
197
- replace an existing file; configs preserves files by default).
198
- 5. Confirm with the names added and their combined token estimate, e.g.
199
- "Added 2 optional helpers: Code review workflow, TDD workflow (~3k tokens)."
200
-
201
- ### Fix (`project:fix`)
202
-
203
- 1. Run `haus doctor` and read the verdict.
204
- 2. If the project is already healthy, say so in one line and stop.
205
- 3. Otherwise, for each item that needs attention, run the exact fix command the
206
- doctor named (commonly `haus apply --write` or `haus apply --refill-config`).
109
+ ### Init (`init`)
110
+
111
+ 0. **State check.** Scope was detected in Step 1.5. If `haus.lock.json` already
112
+ exists (or, workspace scope, `.haus-workflow/workspace.manifest.json` records a
113
+ prior setup), this project is already set up — ask via `AskUserQuestion`:
114
+ - **Refresh instead** (recommended) — non-destructive; jump to the Refresh
115
+ procedure's full-sync branch.
116
+ - **Clean slate** — explain plainly: removes all haus-managed files (backed up
117
+ first; user content preserved), then re-runs setup from scratch. On confirm run
118
+ `haus undo --yes` (project) or `haus workspace undo --yes` (workspace), then
119
+ continue by the scope already detected in Step 1.5 — workspace: step 1 below
120
+ (deep-docs ask, `haus workspace setup --write`, per-member documentation pass,
121
+ stop); project: step 2 (`references/init.md`). Reached directly by the
122
+ `reinit` aliases — still always confirmed, never silent.
123
+ - **Cancel.**
124
+ 1. **Workspace scope.** Ask once via `AskUserQuestion` whether to run the deep docs
125
+ pass (writing-documentation) or the standard documentation pass per member repo;
126
+ deep docs are thorough but slow, with one deep read per member. Then run
127
+ `haus workspace setup --write`, run the chosen per-member documentation pass,
128
+ and stop. Do not follow `references/init.md`; it contains project commands.
129
+ 2. **Project scope.** Open and follow `references/init.md` in this skill's directory.
130
+ Run every step in order. It detects the stack, runs `haus apply --write`
131
+ (scaffolding, skills, commands, rules, docs skill), writes the **project docs**
132
+ (`CLAUDE.md` body + `docs/`) and `.haus-workflow/deep-context.json`, runs
133
+ `haus recommend`, applies the newly-matched helpers, and confirms. Then fill
134
+ `.haus-workflow/workflow-config.md` — replace every placeholder (`TODO`, `n/a`,
135
+ empty): test/lint/typecheck/build commands (check `package.json`), docs paths,
136
+ validation library, pre-commit tool, highest-stakes logic (ask if unclear).
137
+ Leave none.
138
+
139
+ ### Refresh (`refresh`)
140
+
141
+ Bring haus current. Global half always runs; the project half depends on scope.
142
+
143
+ 1. **Global half.** If `~/.claude` was never seeded by haus (`haus install --check`
144
+ reports it missing), run `haus install` first. Then run `haus update`. React to
145
+ its output: if a new version is available run `npm i -g @haus-tech/haus-workflow`
146
+ and confirm the bump; if `WORKFLOW.md` changed, remind the user to review
147
+ `workflow-config.md` for new sections; if the catalog changed, summarise which
148
+ templates changed.
149
+ 2. **No project/workspace detected** (scope step said "not set up") → report the
150
+ global result and stop.
151
+ 3. **Project or workspace detected** → ask via `AskUserQuestion` (skip the question
152
+ when an alias pre-answered it):
153
+ - **Full sync** — re-run the Init procedure's pipeline in place, end to end
154
+ (re-scan, deep docs read, re-recommend, apply; workspace scope:
155
+ `haus workspace setup --write`, asking the deep-docs question first). Nothing
156
+ is removed up front; anything removed upstream is pruned by `apply`'s existing
157
+ orphan-pruning.
158
+ - **Just add helpers** — no package pipeline re-run, no docs regeneration:
159
+ run `haus rescan` — does the same scan + recommend as `haus scan --json` then
160
+ `haus recommend`, in one call, and additionally ensures the catalog-pinned
161
+ global plugin(s), which a manual scan+recommend pair would skip; read
162
+ `.haus-workflow/recommendation.json` and `.haus-workflow/haus.lock.json`
163
+ yourself; offer items not already installed — `optInEligible[]` grouped by
164
+ `optInGroup` (purpose + tokenEstimate as plain language) and `recommended[]`
165
+ config entries with `install: false` whose files aren't present. One
166
+ multi-select `AskUserQuestion`, all unchecked. Then one single
167
+ `haus recommend --include <id> <id> …` with every chosen id followed by
168
+ `haus apply --write`; configs via `haus configs <id>` (`--force` only if the
169
+ user chose to replace an existing file). Nothing eligible → say so and stop.
170
+ Reached directly by the `add-skills`/`opt-in` aliases. In workspace scope, ask
171
+ which member repo(s) first and run the branch per chosen repo.
172
+ 4. Report what changed in plain language — package/catalog bumps, docs refreshed,
173
+ helpers added/updated/removed.
174
+
175
+ ### Doctor (`doctor`)
176
+
177
+ 0. **Not set up.** If Step 1.5 detected the not-set-up case, report that the project
178
+ is not set up, suggest `init`, and stop before running any doctor command.
179
+ 1. Run `haus doctor` (project scope) or `haus workspace doctor` plus
180
+ `haus workspace worktree doctor` (workspace scope) and read the verdict.
181
+ 2. Relay the verdict in one or two plain sentences. Healthy → stop.
182
+ 3. Otherwise list each item as a short sentence plus its fix, and ask via
183
+ `AskUserQuestion` whether to apply the fixes now — **the `fix` aliases pre-answer
184
+ yes: skip this `AskUserQuestion` call entirely and apply the fixes directly.**
185
+ On a manual yes, run the exact fix command the doctor named (commonly
186
+ `haus apply --write` or `haus apply --refill-config`).
207
187
  One suggestion is not a shell command: if the doctor suggests running the
208
188
  writing-documentation skill (`/docs`) because the project docs were never
209
189
  generated, invoke that skill directly (it's installed in this project at
210
190
  `.claude/skills/writing-documentation/`) instead of running anything in
211
191
  the terminal.
212
- 4. Re-run `haus doctor` to confirm the verdict is now green.
213
- 5. Report what you changed in plain language — what was wrong, what you ran, and
214
- that it's now resolved.
215
-
216
- Only run haus commands and the fixes the doctor suggests. If a fix needs a
217
- decision you can't make safely, stop and ask in plain language.
218
-
219
- ### After `haus update`
220
-
221
- 1. If CLI output says a new version is available, run `npm i -g @haus-tech/haus-workflow` and confirm the version bump.
222
- 2. If `WORKFLOW.md` was updated, remind the user: "WORKFLOW.md updated — review `workflow-config.md` for any new sections that need project-specific values."
223
- 3. If CLI output shows catalog changes, summarise which templates changed.
224
- 4. **If the current directory has a `.haus-workflow/` folder** (this project was already
225
- set up by haus), don't stop at the global update — continue immediately into
226
- **Setup (`project:init`)** above to fully sync this project too (rescan, redo the deep
227
- docs read, re-recommend, apply). This is what makes `update`'s scope note ("also
228
- refreshes this project") literally true, not just a light lock-replay. No `.haus-workflow/`
229
- folder → nothing more to do here, `update` only touched global files.
230
-
231
- ### After `haus doctor` (`project:doctor`)
232
-
233
- 1. Read the output. The first line is a plain-language verdict (green = healthy,
234
- amber = things need attention).
235
- 2. Relay that verdict to the person in one or two sentences. If anything needs
236
- attention, list each item as a short sentence plus the exact command that
237
- fixes it — and offer to run the fix for them (or suggest `project:fix`).
238
-
239
- Don't show raw command output unless they ask for detail.
240
-
241
- ### After `haus install` / `haus uninstall`
242
-
243
- Confirm which files were written to or removed from `~/.claude/`. No further steps.
192
+ 4. Re-run the doctor to confirm green, and report what was wrong, what you ran,
193
+ and that it's resolved. Only run haus commands and the fixes the doctor
194
+ suggests; if a fix needs a decision you can't make safely, stop and ask.
195
+
196
+ ### Clone (`clone`)
197
+
198
+ 1. Open and follow `references/clone.md` in this skill's directory. With a `name`
199
+ argument it finds and clones one matching repo from GitHub; with no argument,
200
+ and only when Step 1.5 didn't already resolve Workspace scope, it starts with
201
+ clone.md's Step 0 (single repo vs whole workspace) — when Step 1.5 already found
202
+ Workspace scope, clone.md skips Step 0 and goes straight to Mode B. Its final
203
+ step asks whether to also set the cloned repo(s) up for local dev — the
204
+ `cloneandsetup` aliases pre-answer yes: skip that `AskUserQuestion` call
205
+ entirely and proceed straight into local-dev setup.
206
+
207
+ ### New project (`new`)
208
+
209
+ 1. If Step 1.5 found **Workspace** scope, or **Member repo of a workspace** with the
210
+ user's answer being "Whole workspace," open `references/new.md`'s Phase 0 knowing
211
+ it must ask the workspace-membership question there before eliciting anything
212
+ else. Otherwise (Project or Not-set-up scope) open it knowing that question is
213
+ skipped.
214
+ 2. Open and follow `references/new.md` in this skill's directory. It is a seven-phase AI-driven flow: elicit the request and propose features, gate on user intent, scaffold (registry stacks via `haus new --json --yes` with a `--dry-run` preview; any other stack via a user-confirmed official scaffolder plus manual rails), install context via `haus init`, seed `docs/SPEC.md` + `docs/plans/walking-skeleton.md`, build the walking skeleton with one subagent per feature (against a structure recorded in `docs/DESIGN.md`), verify (build + lint + tests + smoke boot), then write the project docs by following `references/init.md` from step 3 (deep read, `CLAUDE.md` body + `docs/`, recommend re-check, opt-ins). Repos are only ever created private. Failure `detail` is relayed verbatim and nothing is ever auto-deleted. Never run bare interactive `haus new`.
215
+
216
+ ### After `haus uninstall`
217
+
218
+ Confirm which files were removed from `~/.claude/`.
219
+ The confirm gate before running must state this removes haus's global files, not
220
+ anything in the current project.
244
221
 
245
222
  ## Do not use when
246
223