@haus-tech/haus-workflow 0.11.1 → 0.12.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 +29 -8
- package/README.md +40 -9
- package/dist/cli.js +1446 -836
- package/library/catalog/manifest.json +90 -74
- package/library/catalog/{allowed-stacks.json → validation-rules.json} +42 -2
- package/library/global/commands/haus-doctor.md +10 -0
- package/library/global/commands/haus-fix.md +12 -0
- package/library/global/commands/haus-setup.md +28 -0
- package/library/global/settings-fragments/hooks.json +0 -6
- package/library/global/skills/haus-workflow/SKILL.md +81 -41
- package/package.json +10 -10
- package/scripts/postinstall.mjs +62 -0
- package/tests/README.md +5 -21
- package/tests/fixtures/catalog/manifest.json +0 -19
- package/library/catalog/sources.yaml +0 -411
- package/library/global/agents/haus-code-reviewer.md +0 -28
- package/library/global/agents/haus-docs-researcher.md +0 -27
- package/library/global/agents/haus-planner.md +0 -27
- package/library/global/agents/haus-security-reviewer.md +0 -27
- package/library/global/agents/haus-test-reviewer.md +0 -27
- package/library/global/templates/agentic-workflow-standard.md +0 -279
|
@@ -1,63 +1,103 @@
|
|
|
1
|
-
## <!-- HAUS-MANAGED id=skill.haus-workflow v=
|
|
1
|
+
## <!-- HAUS-MANAGED id=skill.haus-workflow v=2 source=@haus-tech/haus-workflow@0.1.0 -->
|
|
2
2
|
|
|
3
3
|
name: haus-workflow
|
|
4
|
-
description: Haus all-in-one workflow skill. Handles project setup, update, catalog refresh, and CLAUDE.md regeneration.
|
|
4
|
+
description: Haus all-in-one workflow skill. Handles project setup, update, catalog refresh, and CLAUDE.md regeneration. Invoke with a task name or without to get a menu.
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# haus-workflow
|
|
9
9
|
|
|
10
|
-
All-in-one entry point for the Haus AI workflow.
|
|
10
|
+
All-in-one entry point for the Haus AI workflow.
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## Invocation
|
|
13
13
|
|
|
14
|
-
-
|
|
15
|
-
- Updating an existing project setup (`.claude/` + `.haus-workflow/`).
|
|
16
|
-
- Checking for a newer `@haus-tech/haus-workflow` package and refreshing `~/.claude/` accordingly.
|
|
17
|
-
- Fetching catalog updates (`haus update`).
|
|
18
|
-
- Regenerating the root `CLAUDE.md` import block.
|
|
14
|
+
`/haus-workflow [task]`
|
|
19
15
|
|
|
20
|
-
|
|
16
|
+
`task` is optional. If omitted, present a task menu (see below). If provided, map it to a command and run immediately.
|
|
21
17
|
|
|
22
|
-
|
|
18
|
+
## Task aliases → commands
|
|
19
|
+
|
|
20
|
+
| Alias(es) | Command | What it does |
|
|
21
|
+
| ------------------------------------ | -------------------- | ---------------------------------------------- |
|
|
22
|
+
| `init`, `setup` | `haus init` | First-time project setup |
|
|
23
|
+
| `apply`, `refresh`, `update-project` | `haus apply --write` | Re-run setup / refresh `.claude/` context |
|
|
24
|
+
| `update`, `upgrade` | `haus update` | Update npm package + catalog + `~/.claude/` |
|
|
25
|
+
| `catalog` | `haus update` | Fetch latest catalog (same command as update) |
|
|
26
|
+
| `doctor`, `check` | `haus doctor` | Check for install drift |
|
|
27
|
+
| `install`, `global` | `haus install` | Seed `~/.claude/` with haus-owned files |
|
|
28
|
+
| `uninstall` | `haus uninstall` | Remove all haus global files from `~/.claude/` |
|
|
29
|
+
| `claude-md`, `regenerate` | `haus apply --write` | Regenerate root `CLAUDE.md` import block |
|
|
30
|
+
|
|
31
|
+
## Step 1 — Determine the task
|
|
32
|
+
|
|
33
|
+
**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.
|
|
34
|
+
|
|
35
|
+
**If no task was passed:** use `AskUserQuestion` to present this menu:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
Question: "What would you like to do?"
|
|
39
|
+
Options:
|
|
40
|
+
1. Set up this project for the first time
|
|
41
|
+
(haus init — scans repo, writes .haus-workflow/, updates CLAUDE.md)
|
|
42
|
+
2. Refresh project setup
|
|
43
|
+
(haus apply --write — re-runs setup, regenerates CLAUDE.md imports)
|
|
44
|
+
3. Update haus package + catalog + global files
|
|
45
|
+
(haus update — checks npm for new version, fetches catalog, refreshes ~/.claude/)
|
|
46
|
+
4. Fetch catalog updates only
|
|
47
|
+
(haus update — same command; pulls latest workflow templates and lockfile)
|
|
48
|
+
5. Regenerate CLAUDE.md import block
|
|
49
|
+
(haus apply --write — rewrites the @-import block at the root CLAUDE.md)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Map the user's selection to the command from the alias table, then continue to Step 2.
|
|
53
|
+
|
|
54
|
+
## Step 2 — Run the command
|
|
23
55
|
|
|
24
|
-
|
|
56
|
+
Run the mapped command via Bash. Quote the exact command you are running before executing it.
|
|
25
57
|
|
|
26
|
-
|
|
58
|
+
## Step 3 — Post-run steps
|
|
27
59
|
|
|
28
|
-
|
|
29
|
-
| ------------------------------------------- | -------------------- |
|
|
30
|
-
| First-time project setup | `haus init` |
|
|
31
|
-
| Re-run setup / refresh context | `haus apply --write` |
|
|
32
|
-
| Update package + catalog + `~/.claude/` | `haus update` |
|
|
33
|
-
| Check install drift | `haus doctor` |
|
|
34
|
-
| Install global haus files into `~/.claude/` | `haus install` |
|
|
35
|
-
| Remove all haus global files | `haus uninstall` |
|
|
60
|
+
After the command completes, follow the relevant post-run steps below.
|
|
36
61
|
|
|
37
|
-
|
|
62
|
+
### After `haus init`
|
|
38
63
|
|
|
39
|
-
1.
|
|
40
|
-
2.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
- `package.json`
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
6. Prints a summary; user confirms before writes.
|
|
64
|
+
1. Open `.haus-workflow/workflow-config.md`.
|
|
65
|
+
2. Check for unfilled placeholders (`TODO`, `n/a`, empty values) in:
|
|
66
|
+
- Test, lint, typecheck, build commands — confirm against `package.json` scripts.
|
|
67
|
+
- Docs paths — check whether `docs/SPEC.md`, `docs/DESIGN.md`, `docs/UX.md` exist.
|
|
68
|
+
- Validation library — check `package.json` dependencies for `zod`, `yup`, `joi`, `valibot`.
|
|
69
|
+
- Pre-commit tool — check for `.husky/`, `lefthook.yml`, `.pre-commit-config.yaml`.
|
|
70
|
+
- Highest-stakes logic — ask the user if unclear.
|
|
71
|
+
3. Fill in every unfilled field. Do not leave placeholders.
|
|
72
|
+
4. Confirm with the user that `workflow-config.md` is complete before proceeding.
|
|
49
73
|
|
|
50
|
-
|
|
74
|
+
### After `haus apply --write`
|
|
51
75
|
|
|
52
|
-
|
|
76
|
+
Verify that the root `CLAUDE.md` imports all three haus files:
|
|
53
77
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
78
|
+
```
|
|
79
|
+
@.haus-workflow/WORKFLOW.md
|
|
80
|
+
@.haus-workflow/workflow-config.md
|
|
81
|
+
@.haus-workflow/project.md
|
|
82
|
+
```
|
|
58
83
|
|
|
59
|
-
|
|
84
|
+
If any import is missing, add it.
|
|
60
85
|
|
|
61
|
-
|
|
86
|
+
### After `haus update`
|
|
62
87
|
|
|
63
|
-
|
|
88
|
+
1. If CLI output says a new version is available, run `npm i -g @haus-tech/haus-workflow` and confirm the version bump.
|
|
89
|
+
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."
|
|
90
|
+
3. If CLI output shows catalog changes, summarise which templates changed.
|
|
91
|
+
|
|
92
|
+
### After `haus doctor`
|
|
93
|
+
|
|
94
|
+
Report findings clearly. For each drift item, suggest the exact fix command.
|
|
95
|
+
|
|
96
|
+
### After `haus install` / `haus uninstall`
|
|
97
|
+
|
|
98
|
+
Confirm which files were written to or removed from `~/.claude/`. No further steps.
|
|
99
|
+
|
|
100
|
+
## Do not use when
|
|
101
|
+
|
|
102
|
+
- User needs a security, code, or test review — use the dedicated reviewer agents instead.
|
|
103
|
+
- User asks about workflow concepts or wants to understand the WORKFLOW.md standard — answer directly from the loaded context.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haus-tech/haus-workflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Haus AI workflow CLI for Claude Code.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"homepage": "https://github.com/WeAreHausTech/haus-workflow",
|
|
14
14
|
"files": [
|
|
15
15
|
"dist",
|
|
16
|
+
"scripts/postinstall.mjs",
|
|
16
17
|
"library/global",
|
|
17
18
|
"library/catalog",
|
|
18
19
|
"tests/fixtures/catalog",
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
"scripts": {
|
|
25
26
|
"build": "tsup src/cli.ts --format esm --dts --clean --out-dir dist --external @inquirer/checkbox",
|
|
26
27
|
"dev": "tsx src/cli.ts",
|
|
27
|
-
"test": "node --test tests/**/*.test.js",
|
|
28
|
+
"test": "node --import tsx --test tests/**/*.test.js",
|
|
28
29
|
"lint": "eslint src scripts",
|
|
29
30
|
"format:check": "prettier --check .",
|
|
30
31
|
"format": "prettier --write .",
|
|
@@ -37,7 +38,8 @@
|
|
|
37
38
|
"release:dry": "GITHUB_TOKEN=$(gh auth token) release-it --dry-run",
|
|
38
39
|
"prepack": "yarn build",
|
|
39
40
|
"verify": "yarn typecheck && yarn typecheck:scripts && yarn lint && yarn build && yarn test",
|
|
40
|
-
"
|
|
41
|
+
"postinstall": "node ./scripts/postinstall.mjs || true",
|
|
42
|
+
"prepare": "lefthook install || true",
|
|
41
43
|
"security:audit": "yarn npm audit -A -R --severity high --environment production"
|
|
42
44
|
},
|
|
43
45
|
"dependencies": {
|
|
@@ -62,8 +64,7 @@
|
|
|
62
64
|
"@typescript-eslint/parser": "8.59.3",
|
|
63
65
|
"eslint": "9.39.4",
|
|
64
66
|
"eslint-plugin-import": "2.32.0",
|
|
65
|
-
"
|
|
66
|
-
"lint-staged": "17.0.4",
|
|
67
|
+
"lefthook": "1.13.6",
|
|
67
68
|
"prettier": "3.8.3",
|
|
68
69
|
"release-it": "20.0.1",
|
|
69
70
|
"tsup": "8.5.1",
|
|
@@ -77,10 +78,9 @@
|
|
|
77
78
|
"access": "public"
|
|
78
79
|
},
|
|
79
80
|
"packageManager": "yarn@4.15.0",
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
|
|
84
|
-
]
|
|
81
|
+
"dependenciesMeta": {
|
|
82
|
+
"lefthook": {
|
|
83
|
+
"built": true
|
|
84
|
+
}
|
|
85
85
|
}
|
|
86
86
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* npm postinstall hook. On a GLOBAL install of @haus-tech/haus-workflow, runs
|
|
4
|
+
* `haus install --postinstall` automatically so a non-developer gets a working
|
|
5
|
+
* Claude Code setup with zero manual steps — then the CLI prints exactly what it
|
|
6
|
+
* changed in ~/.claude and how to undo it.
|
|
7
|
+
*
|
|
8
|
+
* Fail-open by design: this must NEVER break `npm install`. Every gate that isn't
|
|
9
|
+
* satisfied is a silent no-op, and the whole body is wrapped so any error still
|
|
10
|
+
* exits 0. Plain Node ESM (no tsx) because consumers don't have the dev toolchain.
|
|
11
|
+
*/
|
|
12
|
+
import { spawnSync } from 'node:child_process'
|
|
13
|
+
import fs from 'node:fs'
|
|
14
|
+
import path from 'node:path'
|
|
15
|
+
import { fileURLToPath } from 'node:url'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Pure gate: decides whether the postinstall should run. Kept side-effect-free and
|
|
19
|
+
* exported so it can be unit-tested across the full env/fs matrix without spawning npm.
|
|
20
|
+
*
|
|
21
|
+
* @param {{ env: Record<string, string | undefined>, distExists: boolean, srcExists: boolean }} input
|
|
22
|
+
* @returns {{ run: boolean, reason: string }}
|
|
23
|
+
*/
|
|
24
|
+
export function shouldRunPostinstall({ env, distExists, srcExists }) {
|
|
25
|
+
if (env.npm_config_global !== 'true') return { run: false, reason: 'not a global install' }
|
|
26
|
+
if (env.CI) return { run: false, reason: 'CI environment' }
|
|
27
|
+
if (env.HAUS_NO_POSTINSTALL === '1') return { run: false, reason: 'HAUS_NO_POSTINSTALL=1' }
|
|
28
|
+
if (!distExists) return { run: false, reason: 'dist/cli.js missing' }
|
|
29
|
+
// Published tarballs omit src/; its presence means we're in the package's own
|
|
30
|
+
// dev checkout, where a local `yarn install` must not self-trigger.
|
|
31
|
+
if (srcExists) return { run: false, reason: 'running inside the package dev checkout' }
|
|
32
|
+
return { run: true, reason: 'global install' }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Entry point: runs only when this file is invoked directly (not when imported by a test). */
|
|
36
|
+
function main() {
|
|
37
|
+
try {
|
|
38
|
+
const pkgRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
|
39
|
+
const cliPath = path.join(pkgRoot, 'dist', 'cli.js')
|
|
40
|
+
const decision = shouldRunPostinstall({
|
|
41
|
+
env: process.env,
|
|
42
|
+
distExists: fs.existsSync(cliPath),
|
|
43
|
+
srcExists: fs.existsSync(path.join(pkgRoot, 'src')),
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
if (!decision.run) {
|
|
47
|
+
if (process.env.HAUS_DEBUG) console.error(`[haus postinstall] skipped: ${decision.reason}`)
|
|
48
|
+
process.exit(0)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Non-fatal: a nonzero CLI exit must not fail `npm install`.
|
|
52
|
+
spawnSync(process.execPath, [cliPath, 'install', '--postinstall'], { stdio: 'inherit' })
|
|
53
|
+
} catch (err) {
|
|
54
|
+
if (process.env.HAUS_DEBUG) console.error(`[haus postinstall] error (ignored): ${err}`)
|
|
55
|
+
}
|
|
56
|
+
process.exit(0)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Run only as a script, never when imported.
|
|
60
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1])) {
|
|
61
|
+
main()
|
|
62
|
+
}
|
package/tests/README.md
CHANGED
|
@@ -8,12 +8,11 @@ yarn test
|
|
|
8
8
|
|
|
9
9
|
## Structure
|
|
10
10
|
|
|
11
|
-
| Path | Contents
|
|
12
|
-
| ----------------- |
|
|
13
|
-
| `tests/*.test.js` | Unit and integration tests
|
|
14
|
-
| `tests/helpers/` | Shared test utilities
|
|
15
|
-
| `tests/fixtures/` | Static fixture repos used by tests
|
|
16
|
-
| `tests/golden/` | Golden output snapshots for scan/recommend/context |
|
|
11
|
+
| Path | Contents |
|
|
12
|
+
| ----------------- | ----------------------------------- |
|
|
13
|
+
| `tests/*.test.js` | Unit and integration tests |
|
|
14
|
+
| `tests/helpers/` | Shared test utilities |
|
|
15
|
+
| `tests/fixtures/` | Static fixture repos used by tests |
|
|
17
16
|
|
|
18
17
|
## helpers/fixture-runner.js
|
|
19
18
|
|
|
@@ -22,8 +21,6 @@ Utilities for running the compiled CLI against fixture repos in a temp directory
|
|
|
22
21
|
- `cloneFixtureToTemp(fixtureName)` — copies `tests/fixtures/repos/<name>` to a temp dir, returns the path
|
|
23
22
|
- `runHaus(cwd, command)` — runs `node dist/cli.js <command>` in `cwd`, returns stdout
|
|
24
23
|
- `readHausJson(cwd, fileName)` — reads `.haus-workflow/<fileName>` as parsed JSON
|
|
25
|
-
- `normalizeRecommendationForGolden(rec)` — stable sort for golden snapshot comparison
|
|
26
|
-
- `normalizeContextForGolden(ctx)` — stable sort for golden snapshot comparison
|
|
27
24
|
|
|
28
25
|
Tests that use `fixture-runner.js` require a built `dist/` — run `yarn build && yarn test`, or use `yarn verify` which builds before running tests.
|
|
29
26
|
|
|
@@ -47,10 +44,6 @@ Full fixture repos scanned by integration tests and golden tests. Each subdirect
|
|
|
47
44
|
| `wordpress-bedrock-site` | WordPress Bedrock (Composer) |
|
|
48
45
|
| `wordpress-with-node-tooling` | WordPress + Node tooling (pnpm) |
|
|
49
46
|
|
|
50
|
-
### fixtures/findings/
|
|
51
|
-
|
|
52
|
-
QA findings records (see `fixtures/findings/README.md`). Observational only — not gated by any test.
|
|
53
|
-
|
|
54
47
|
### Other fixture dirs
|
|
55
48
|
|
|
56
49
|
- `fixtures/dotnet-service/` — unsupported stack (C#/.NET), used to verify unsupported-stack handling
|
|
@@ -59,12 +52,3 @@ QA findings records (see `fixtures/findings/README.md`). Observational only —
|
|
|
59
52
|
- `fixtures/vendure-plugin/` — minimal Vendure plugin package
|
|
60
53
|
- `fixtures/laravel-app/`, `fixtures/next-react-app/`, `fixtures/wordpress-bedrock/` — legacy shallow fixtures; prefer `fixtures/repos/` equivalents for new tests
|
|
61
54
|
|
|
62
|
-
## golden/
|
|
63
|
-
|
|
64
|
-
Snapshot files for `context-goldens.test.js` and `recommender.test.js`. Keyed by fixture name.
|
|
65
|
-
|
|
66
|
-
- `golden/scans/` — `scanProject` output
|
|
67
|
-
- `golden/recommendations/` — `runRecommend` output (normalized)
|
|
68
|
-
- `golden/context/` — `runContext` output (normalized)
|
|
69
|
-
|
|
70
|
-
To regenerate goldens after intentional recommender changes, delete the relevant `.json` file and re-run `yarn test` — the test will write the new snapshot and pass on the next run.
|
|
@@ -2,25 +2,6 @@
|
|
|
2
2
|
"version": "0.1.0",
|
|
3
3
|
"_note": "Stable fixture for CLI tests. Decoupled from production catalog repo. Update manually when catalog schema changes.",
|
|
4
4
|
"items": [
|
|
5
|
-
{
|
|
6
|
-
"id": "haus.global-engineering-rules",
|
|
7
|
-
"source": "haus",
|
|
8
|
-
"type": "skill",
|
|
9
|
-
"path": "skills/global-engineering-rules",
|
|
10
|
-
"title": "Haus global engineering rules",
|
|
11
|
-
"purpose": "Provide baseline deterministic engineering, validation, and security guardrails.",
|
|
12
|
-
"whenToUse": "Use as default baseline in supported Haus workflows.",
|
|
13
|
-
"whenNotToUse": "Do not use for unsupported stacks or non-development workflows.",
|
|
14
|
-
"references": [],
|
|
15
|
-
"safetyNotes": ["Never read secrets or customer exports."],
|
|
16
|
-
"tokenBudget": 1800,
|
|
17
|
-
"tags": ["haus", "quality", "security"],
|
|
18
|
-
"repoRoles": [],
|
|
19
|
-
"requiresAny": [],
|
|
20
|
-
"tokenEstimate": 1800,
|
|
21
|
-
"installMode": "copy-selected",
|
|
22
|
-
"default": true
|
|
23
|
-
},
|
|
24
5
|
{
|
|
25
6
|
"id": "haus.nextjs-patterns",
|
|
26
7
|
"source": "haus",
|