@haus-tech/haus-workflow 0.23.1 → 0.24.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,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.24.0](https://github.com/WeAreHausTech/haus-workflow/compare/v0.23.1...v0.24.0) (2026-06-12)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- **cloneandsetup:** local-dev orchestration via localdev.yml ([#97](https://github.com/WeAreHausTech/haus-workflow/issues/97)) ([8a2b5d3](https://github.com/WeAreHausTech/haus-workflow/commit/8a2b5d3e9a767bfe92152189b37921d58878818b))
|
|
8
|
+
|
|
3
9
|
## [0.23.1](https://github.com/WeAreHausTech/haus-workflow/compare/v0.23.0...v0.23.1) (2026-06-12)
|
|
4
10
|
|
|
5
11
|
## [0.23.0](https://github.com/WeAreHausTech/haus-workflow/compare/v0.22.1...v0.23.0) (2026-06-12)
|
|
@@ -1,51 +1,100 @@
|
|
|
1
|
-
Clone a project's repos **and** set each one up
|
|
1
|
+
Clone a project's repos **and** set each one up for local development — node version, dependencies, databases, cross-repo links, and env. This is `project:clone` followed by a per-repo setup pass and a localdev orchestration pass.
|
|
2
2
|
|
|
3
|
-
**Always ask before doing work — never assume.** Cloning and setup
|
|
3
|
+
**Always ask before doing work — never assume.** Cloning and setup hit the network, need auth, and can touch databases; confirm before each phase, and respect repos the user already has.
|
|
4
4
|
|
|
5
5
|
## Step 1 — Clone
|
|
6
6
|
|
|
7
|
-
Run the full `project:clone` flow
|
|
7
|
+
Run the full `project:clone` flow by following `~/.claude/commands/haus-clone.md` end to end (name → one repo; no name → workspace repos from `repos.manifest.json`). Carry the resulting repo list into Step 2.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- **No name** → it clones the workspace's repos from `repos.manifest.json` (asking clean-clone vs reuse-local first).
|
|
9
|
+
## Step 2 — Confirm the setup pass
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
1. List the repos and what each will run (node, deps, localdev steps). Get a go-ahead. For **reused** local clones, ask whether to re-run setup.
|
|
12
|
+
2. Check `NODE_AUTH_TOKEN` is exported if any repo needs private `@`-scoped packages; if missing, tell the user — those installs fail without it.
|
|
13
13
|
|
|
14
|
-
## Step
|
|
14
|
+
## Step 3 — Per-repo dependency pass
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
For each repo, in its own directory, detect and install from the repo's own files (read its `docs/setup.md` / `CLAUDE.md` / `README.md` first — they win). Select node from `.nvmrc`/`engines.node` (`nvm install`), enable the pinned package manager (`corepack enable`), install JS deps (`yarn`/`pnpm`/`npm` by lockfile), composer deps if `composer.json` + `composer` present. Run each repo's steps in one login shell so the node version stays active. Per-repo failure is reported and skipped, not fatal.
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
2. Check `NODE_AUTH_TOKEN` is exported if any repo depends on private `@`-scoped packages (e.g. `@haus-storefront-*`, `@haus-tech/*`). If it's missing, tell the user to set it first — those installs will fail without it. Let them decide whether to continue or stop.
|
|
18
|
+
**Scaffold `.env`** so the env-wiring in Step 4 has a file to write to: if `.env.example` exists and `.env` does not, copy it; otherwise create an empty `.env`. Per decision D5, write `.env`; if the write is blocked, print the values for the user to add. Tell the user real secrets still need filling.
|
|
20
19
|
|
|
21
|
-
## Step
|
|
20
|
+
## Step 4 — Local-dev orchestration
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
This is the phase that takes the workspace from "installed" to "ready to run." It is driven by `localdev.yml` files; a repo with none is set up by Step 3 only.
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
### House conventions (the "how", so repos specify only the "what")
|
|
25
|
+
|
|
26
|
+
Specify the least. Infer the rest from the repo's stack + these conventions, and work out the concrete commands at run time:
|
|
27
|
+
|
|
28
|
+
- **IMPORTANT — never install anything without asking first; global/system tools especially** (Homebrew, Docker, Laravel Herd, global `npm`/`composer` packages). Detect what's already present; if something required is missing, name it, say why it's needed, and get an explicit **yes** before installing. Prefer the least-invasive option, and don't switch or override tools the dev already has.
|
|
29
|
+
- **PHP / WordPress sites are served by the developer's own PHP environment.** If they already have one — detect `valet`, `herd`, `ddev`, or `php` on PATH — **use it**: just satisfy the env contract (docroot → the repo's `web/`, HTTPS) and report the URL; never override what they already run. **Only when no local PHP environment exists** (a completely fresh machine) suggest installing **[Laravel Herd](https://herd.laravel.com)** as the default (asking first) and point its docroot at `web/` + `herd secure`.
|
|
30
|
+
- **Databases and other services (a repo's `needs:`) run in Docker.** **If Docker isn't installed**, it's a prerequisite for these — tell the user and **ask before installing it** (it's a global install). Once Docker is available, provision services the simplest way (a one-off `docker run`, or the repo's own compose if it ships one), then wire the matching env vars to point at them. Confirm before creating/overwriting data.
|
|
31
|
+
- **Dependencies** install from the lockfile (Step 3).
|
|
32
|
+
- A repo's `localdev.yml` carries **only what can't be inferred** — its `needs`, repo-specific `build`/`seed` commands, env keys, and URL. Detect the stack (e.g. Bedrock = `composer.json` + `web/` docroot + `wp-cli.yml`; Vendure/Node = `docker-compose.yml` + `@vendure/*`) and apply the matching convention.
|
|
33
|
+
|
|
34
|
+
### The `localdev.yml` format
|
|
35
|
+
|
|
36
|
+
**Per-repo — `<repo>/.haus-workflow/localdev.yml`** (how to set up THAT repo alone; sibling-agnostic):
|
|
37
|
+
|
|
38
|
+
All fields optional. **Prefer intent (`needs`/`build`/`seed`/`serve`) over explicit `steps`** —
|
|
39
|
+
the conventions above turn intent into commands.
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
needs: [mysql] # services this repo requires; provisioned in Docker, env wired to them
|
|
43
|
+
needsEnv: [WP_HOME, DB_NAME] # env keys that must be present to run/serve
|
|
44
|
+
build: 'yarn build' # optional: the build command (run after deps)
|
|
45
|
+
seed: 'dep db:pull staging-oderland' # optional: how to load data; remote/destructive → confirm first
|
|
46
|
+
serve: # optional: how it runs (printed as a next-step, never auto-started)
|
|
47
|
+
via: herd # herd | valet | docker | command — for PHP envs, bring-your-own (don't install)
|
|
48
|
+
url: 'https://example.test'
|
|
49
|
+
start: 'yarn dev'
|
|
50
|
+
steps: # optional escape hatch: explicit ordered shell steps when intent isn't enough
|
|
51
|
+
- run: 'composer install'
|
|
52
|
+
node: 10 # nvm version for THIS step
|
|
53
|
+
remote: true # SSH → confirm first
|
|
54
|
+
destructive: true # overwrites data → confirm first
|
|
55
|
+
optional: true # failure is non-fatal, continue
|
|
27
56
|
```
|
|
28
57
|
|
|
29
|
-
**
|
|
58
|
+
**Workspace — `<workspace>/.haus-workflow/localdev.yml`** (the glue BETWEEN repos):
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
order: [repo-a, repo-b] # setup/startup order, by manifest id
|
|
62
|
+
links:
|
|
63
|
+
- { type: symlink, from: <repo-folder>, to: <repo-folder>/path/to/link }
|
|
64
|
+
- { type: composer-path, in: <repo>, dep: <sibling-repo> }
|
|
65
|
+
- { type: yarn-link, in: [<repo>, ...], dep: <sibling-package-repo> }
|
|
66
|
+
env:
|
|
67
|
+
- source: { repo: <repo>, provides: '<value>' }
|
|
68
|
+
sinks:
|
|
69
|
+
- { repo: <repo>, key: ENV_KEY }
|
|
70
|
+
```
|
|
30
71
|
|
|
31
|
-
|
|
72
|
+
### Run order
|
|
32
73
|
|
|
33
|
-
1. **
|
|
34
|
-
2. **
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
|
|
74
|
+
1. **Discover** `.haus-workflow/localdev.yml` in the workspace root and each repo.
|
|
75
|
+
2. **Resolve order** from the workspace `order` (repos not listed run last, in manifest order). No workspace file → manifest order.
|
|
76
|
+
3. **Per repo, in order**, apply intent via the conventions:
|
|
77
|
+
- **`needs`** → provision each service in Docker if not already running, and wire its env vars. Confirm before creating/overwriting data.
|
|
78
|
+
- **`build`** → run it (honor any node version the repo's docs note).
|
|
79
|
+
- **`serve`** → for `via: herd` / PHP envs, install nothing — verify the dev's environment serves `web/`, and report the URL.
|
|
80
|
+
- **`seed`** → run it; **confirm first** if it's remote (SSH) or destructive (overwrites data).
|
|
81
|
+
- **`steps`** (escape hatch) → run in order, selecting `node:` per step, `optional:` failures continue, **confirming before any `remote:`/`destructive:` step** — every run, even on re-run.
|
|
82
|
+
4. **Links** (workspace-owned, performed generically — do NOT call a repo's own `setup-dev-mode.sh`, which is deprecated):
|
|
83
|
+
- `symlink` → `ln -s <from> <to>`; replace an existing symlink, but never clobber a real directory without confirmation.
|
|
84
|
+
- `composer-path` → in `in`'s `composer.json`, set the `dep`'s require to `{ "type": "path", "url": "../<dep-folder>", "options": { "symlink": true } }`, then `composer update <vendor/dep>`.
|
|
85
|
+
- `yarn-link` → `yarn link` in the `dep` repo, then `yarn link <pkg-name>` in each `in` repo (read `<pkg-name>` from the dep's `package.json`).
|
|
86
|
+
5. **Env:** for each workspace `env` entry, confirm the `source` is satisfiable, then upsert the value into each sink repo's `.env` under its `key` — **creating `.env` if it does not exist** (Step 3 scaffolds it, but don't assume). **If the write is blocked or fails, print the exact `KEY=value` lines for the user to paste** (decision D5). Real secrets (DB passwords, tokens) remain the user's to fill.
|
|
87
|
+
6. **Report, then offer to start.** Give the per-repo summary, then **ask the user whether to start everything now.**
|
|
88
|
+
- **Yes** → start each repo in the workspace `order` (its `serve.start`, e.g. `yarn dev`; bring up any remaining foreground services), run any follow-ups (e.g. `wp sync-products sync`), then **print the live URLs** (each repo's `serve.url`).
|
|
89
|
+
- **No** → just print the ordered start commands + follow-ups as next steps; start nothing.
|
|
41
90
|
|
|
42
|
-
|
|
91
|
+
**Default is "ready to run" (D2):** the preparation — datastores up (`docker compose up -d`), DBs pulled, links, builds, env wired — always happens. Starting the **foreground** dev servers and the initial product sync happens **only if the user says yes** to the start prompt above; otherwise they're printed, not run.
|
|
43
92
|
|
|
44
|
-
## Step
|
|
93
|
+
## Step 5 — Report
|
|
45
94
|
|
|
46
|
-
Summarise per repo
|
|
95
|
+
Summarise per repo (node, deps, localdev steps, links, env). Then **ask whether to start everything now**:
|
|
47
96
|
|
|
48
|
-
-
|
|
49
|
-
-
|
|
97
|
+
- **Yes** → start the dev servers in workspace `order`, run any follow-ups, and **print the live URLs** so the user can open the running app.
|
|
98
|
+
- **No** → print the ordered start commands + follow-ups instead, and start nothing.
|
|
50
99
|
|
|
51
|
-
|
|
100
|
+
Never start the app without that explicit yes.
|
|
@@ -21,17 +21,17 @@ The unprefixed verbs (`update`, `catalog`, `install`, `uninstall`) act on **this
|
|
|
21
21
|
haus install** (`~/.claude`, npm) — they manage the haus tool itself, like `npm install -g`.
|
|
22
22
|
The short legacy aliases still work but the names below are canonical.
|
|
23
23
|
|
|
24
|
-
| Task name (legacy aliases) | Command | Scope | What it does
|
|
25
|
-
| ----------------------------------------------------------------- | ------------------------------- | ------- |
|
|
26
|
-
| `project:init` (`setup`, `init`) | _Setup procedure below_ | project | First-time setup of an **existing** repo: adds AI skills, commands, workflow + project docs
|
|
27
|
-
| `project:clone [name]` (`clone`) | _Clone procedure below_ | project | No name: clone a **workspace**'s repos from `repos.manifest.json`. With a `name`: find & clone one repo by name from GitHub
|
|
28
|
-
| `project:cloneandsetup [name]` (`cloneandsetup`) | _Clone & setup procedure below_ | project | Run `project:clone`, then set up each repo
|
|
29
|
-
| `project:refresh` (`apply`, `refresh`, `claude-md`, `regenerate`) | `haus apply --write` | project | Re-run setup / refresh `.claude/` context + regenerate root `CLAUDE.md` import block
|
|
30
|
-
| `project:doctor` (`doctor`, `check`) | `haus doctor` | project | Check for install drift
|
|
31
|
-
| `update` (`upgrade`) | `haus update` | global | Update npm package + catalog + `~/.claude/` (also refreshes this project)
|
|
32
|
-
| `catalog` | `haus update` | global | Fetch latest catalog (same command as update)
|
|
33
|
-
| `install` (`global`) | `haus install` | global | Seed `~/.claude/` with haus-owned files
|
|
34
|
-
| `uninstall` | `haus uninstall` | global | Remove all haus global files from `~/.claude/`
|
|
24
|
+
| Task name (legacy aliases) | Command | Scope | What it does |
|
|
25
|
+
| ----------------------------------------------------------------- | ------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
26
|
+
| `project:init` (`setup`, `init`) | _Setup procedure below_ | project | First-time setup of an **existing** repo: adds AI skills, commands, workflow + project docs |
|
|
27
|
+
| `project:clone [name]` (`clone`) | _Clone procedure below_ | project | No name: clone a **workspace**'s repos from `repos.manifest.json`. With a `name`: find & clone one repo by name from GitHub |
|
|
28
|
+
| `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) |
|
|
29
|
+
| `project:refresh` (`apply`, `refresh`, `claude-md`, `regenerate`) | `haus apply --write` | project | Re-run setup / refresh `.claude/` context + regenerate root `CLAUDE.md` import block |
|
|
30
|
+
| `project:doctor` (`doctor`, `check`) | `haus doctor` | project | Check for install drift |
|
|
31
|
+
| `update` (`upgrade`) | `haus update` | global | Update npm package + catalog + `~/.claude/` (also refreshes this project) |
|
|
32
|
+
| `catalog` | `haus update` | global | Fetch latest catalog (same command as update) |
|
|
33
|
+
| `install` (`global`) | `haus install` | global | Seed `~/.claude/` with haus-owned files |
|
|
34
|
+
| `uninstall` | `haus uninstall` | global | Remove all haus global files from `~/.claude/` |
|
|
35
35
|
|
|
36
36
|
## Step 1 — Determine the task
|
|
37
37
|
|
|
@@ -52,8 +52,8 @@ Options:
|
|
|
52
52
|
(haus update — same command; pulls latest workflow templates and lockfile)
|
|
53
53
|
5. [project] project:clone [name] — clone repos
|
|
54
54
|
(no name: clone a workspace from repos.manifest.json; with a name: find & clone one repo by name from GitHub)
|
|
55
|
-
6. [project] project:cloneandsetup [name] — clone repos, then set them up
|
|
56
|
-
(project:clone, then per-repo
|
|
55
|
+
6. [project] project:cloneandsetup [name] — clone repos, then set them up for local dev
|
|
56
|
+
(project:clone, then per-repo deps + databases + cross-repo links + env from localdev.yml)
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
Map the user's selection to the command from the alias table, then continue to Step 2.
|