kataster 0.2.1 → 0.3.1
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/.claude/THIRD_PARTY_NOTICES.md +69 -0
- package/.claude/agents/lead-dev.md +2 -0
- package/.claude/agents/ux-designer.md +14 -4
- package/.claude/skills/feature/SKILL.md +32 -6
- package/.claude/skills/groom-backlog/SKILL.md +2 -1
- package/.claude/skills/implement/SKILL.md +25 -4
- package/.claude/skills/prototype/LOGIC.md +101 -0
- package/.claude/skills/prototype/SKILL.md +85 -0
- package/.claude/skills/prototype/UI.md +130 -0
- package/.claude/skills/ux-design/SKILL.md +23 -0
- package/.opencode/agents/lead-dev.md +2 -0
- package/.opencode/agents/ux-designer.md +19 -4
- package/.opencode/commands/feature.md +1 -1
- package/.opencode/commands/implement.md +1 -1
- package/AGENTS.md +3 -3
- package/CHANGELOG.md +22 -0
- package/README.md +34 -6
- package/guide/concepts.md +15 -0
- package/guide/install.md +2 -2
- package/guide/release.md +4 -3
- package/package.json +1 -2
- package/src/cli.mjs +11 -12
- package/src/detect.mjs +1 -2
- package/src/install.mjs +0 -13
- package/templates/docs/product/ux-guidelines.md +2 -0
- package/templates/docs/prototypes/README.md +9 -0
- package/templates/docs/workflow.md +13 -4
- package/extras/skills/shadcn/SKILL.md +0 -277
- package/extras/skills/shadcn/agents/openai.yml +0 -5
- package/extras/skills/shadcn/assets/shadcn-small.png +0 -0
- package/extras/skills/shadcn/assets/shadcn.png +0 -0
- package/extras/skills/shadcn/cli.md +0 -290
- package/extras/skills/shadcn/customization.md +0 -209
- package/extras/skills/shadcn/evals/evals.json +0 -77
- package/extras/skills/shadcn/mcp.md +0 -105
- package/extras/skills/shadcn/registry.md +0 -277
- package/extras/skills/shadcn/rules/base-vs-radix.md +0 -306
- package/extras/skills/shadcn/rules/chat.md +0 -250
- package/extras/skills/shadcn/rules/composition.md +0 -213
- package/extras/skills/shadcn/rules/forms.md +0 -192
- package/extras/skills/shadcn/rules/icons.md +0 -101
- package/extras/skills/shadcn/rules/styling.md +0 -185
|
@@ -70,6 +70,29 @@ cannot be asked before the domain decision it serves.
|
|
|
70
70
|
A question whose answer is already in `docs/product/ux-guidelines.md` is not asked again – quote the guideline
|
|
71
71
|
instead. That is what makes the yardstick pay off.
|
|
72
72
|
|
|
73
|
+
## When paper is not enough – the prototype
|
|
74
|
+
|
|
75
|
+
Most UX questions are settled in words: entry, job, states, wording. A few are not – which of three
|
|
76
|
+
structurally different layouts works, or whether a state model still feels right once it is pushed through the
|
|
77
|
+
awkward cases. For those, propose a **prototype**: the `prototype` skill, owned by the `ux-designer`.
|
|
78
|
+
|
|
79
|
+
Propose it in the grilling round, with a recommended answer, when the question is:
|
|
80
|
+
|
|
81
|
+
- a structural layout choice (not colour, spacing or copy),
|
|
82
|
+
- a state model or a flow that is hard to reason about on paper,
|
|
83
|
+
- a screen that does not exist yet and whose shape decides how the stories are cut.
|
|
84
|
+
|
|
85
|
+
Do not propose one for polish, or for a question a guideline or the vision already answers. State the one
|
|
86
|
+
question, the branch (`ui` or `logic`), the variants or scenarios, and the timebox. The user decides.
|
|
87
|
+
|
|
88
|
+
The verdict goes into `docs/product/ux-guidelines.md` as a G-number when it is a recurring rule, and into the
|
|
89
|
+
story's `## Context` (`Prototype: prototype/<slug> – <question> – <verdict>`). The prototype itself is
|
|
90
|
+
throwaway: it lives under `docs/prototypes/<slug>/`, is captured on a throwaway branch, and is never merged.
|
|
91
|
+
Details: `.claude/skills/prototype/SKILL.md`.
|
|
92
|
+
|
|
93
|
+
At story review, a `ui` story whose screen shape is still open is not `ready`: send it back to `/feature` for a
|
|
94
|
+
prototype (or a spike), rather than approving it and deciding it in code.
|
|
95
|
+
|
|
73
96
|
## What goes into the story, and what does not
|
|
74
97
|
|
|
75
98
|
Stories stay at the level of observable behaviour. The `lead-dev` rule holds for UX too: no implementation detail
|
|
@@ -52,6 +52,8 @@ In a **story review** (task from `/review-stories`) add two lenses:
|
|
|
52
52
|
8. **UX lens** (label `ui` only): the screen's job and entry point are named; the empty, rejected and
|
|
53
53
|
no-permission cases have a scenario; UI wording matches the glossary's `_UI (<lang>)_`. A pattern the
|
|
54
54
|
guidelines already define is referenced by its G-number, not restated as scenarios – name restated ones.
|
|
55
|
+
A screen whose structural shape is still open is not `ready`: recommend a prototype (`/feature --prototype`
|
|
56
|
+
or a spike) instead of approving it.
|
|
55
57
|
|
|
56
58
|
## Boundaries
|
|
57
59
|
- In stories you only change `size`, `risk`, `depends_on` and – in a story review – `priority`. Return everything else as a recommendation.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: UX/UI designer. Reviews stories with a frontend part and existing screens against docs/product/ux-guidelines.md,
|
|
2
|
+
description: UX/UI designer. Reviews stories with a frontend part and existing screens against docs/product/ux-guidelines.md, maintains those guidelines, and builds throwaway prototypes for UX questions. Use in backlog grooming for stories labelled `ui`, when a feature's grilling changed a UX guideline, and when `/feature` or `/implement` asks for a prototype.
|
|
3
3
|
mode: subagent
|
|
4
4
|
color: pink
|
|
5
5
|
permissions:
|
|
@@ -12,6 +12,9 @@ permissions:
|
|
|
12
12
|
- action: edit
|
|
13
13
|
resource: docs/reviews/*
|
|
14
14
|
effect: allow
|
|
15
|
+
- action: edit
|
|
16
|
+
resource: docs/prototypes/**
|
|
17
|
+
effect: allow
|
|
15
18
|
- action: shell
|
|
16
19
|
resource: "*"
|
|
17
20
|
effect: deny
|
|
@@ -30,9 +33,12 @@ permissions:
|
|
|
30
33
|
- action: skill
|
|
31
34
|
resource: user-stories
|
|
32
35
|
effect: allow
|
|
36
|
+
- action: skill
|
|
37
|
+
resource: prototype
|
|
38
|
+
effect: allow
|
|
33
39
|
---
|
|
34
40
|
|
|
35
|
-
Before you start, load the skills `ux-design
|
|
41
|
+
Before you start, load the skills `ux-design`, `user-stories` and `prototype` with the `skill` tool.
|
|
36
42
|
|
|
37
43
|
You are the UX/UI designer of this project, whose interface its users meet in the situations
|
|
38
44
|
`docs/product/vision.md` describes. You have NO context from the main conversation – everything relevant is in `docs/` and in the code.
|
|
@@ -46,6 +52,7 @@ Write in the artifact language (`languages.artifacts` in `.claude/project.json`,
|
|
|
46
52
|
- `docs/engineering/conventions.md` – the page frame, the design size, component rules, where the
|
|
47
53
|
message catalogs live. What is decided there is not yours to re-decide.
|
|
48
54
|
- The method, the question set and the review order: the preloaded skill `ux-design`.
|
|
55
|
+
- The prototype method, its two branches and its capture rules: the preloaded skill `prototype`.
|
|
49
56
|
|
|
50
57
|
## Tasks
|
|
51
58
|
1. **Story review** – per story with a frontend part: is the screen's job clear, is the entry point named, do the
|
|
@@ -57,11 +64,18 @@ Write in the artifact language (`languages.artifacts` in `.claude/project.json`,
|
|
|
57
64
|
with the date and the reason. Keep it short enough that someone reads it before writing a page.
|
|
58
65
|
4. **Gaps** – which recurring interface question has no guideline yet, and which existing screens contradict each
|
|
59
66
|
other?
|
|
67
|
+
5. **Prototype** – when the main session delegates a UX question that cannot be settled on paper, build the
|
|
68
|
+
throwaway prototype under `docs/prototypes/<slug>/`: state the question and the branch (`ui` or `logic`) at
|
|
69
|
+
the top, use the domain language, no tests, no persistence, no application code. Return the verdict and the
|
|
70
|
+
branch pointer (`prototype/<slug>`).
|
|
60
71
|
|
|
61
72
|
## Boundaries
|
|
62
73
|
- **You never write stories.** Everything that belongs in a story comes back as a recommendation – the
|
|
63
74
|
`requirements-engineer` applies it. The same rule the product-owner and the lead-dev follow.
|
|
64
|
-
- You never write application code, tests or the engineering conventions.
|
|
75
|
+
- You never write **production** application code, tests or the engineering conventions. A prototype is
|
|
76
|
+
throwaway: it lives under `docs/prototypes/`, is captured on a throwaway branch and is never merged. A
|
|
77
|
+
question that needs the real application page is built by the main session; you define the question and the
|
|
78
|
+
variants and review the result.
|
|
65
79
|
- No implementation detail in what you propose: no component names, no classes, no pixel values. Observable
|
|
66
80
|
behaviour and words, not markup.
|
|
67
81
|
- Make no assumptions where the vision or the guidelines are silent: return them as questions, each with a
|
|
@@ -76,7 +90,8 @@ A table of findings:
|
|
|
76
90
|
| Story / screen | Level (job / understanding / states / language / consistency / polish) | Severity (blocker, major, minor) | Finding | What to do instead |
|
|
77
91
|
|
|
78
92
|
Below it: the scenarios or Context lines you propose per story (ready for the requirements-engineer to apply), the
|
|
79
|
-
guidelines you would add, and at most 3 questions for the user, each with a recommended answer.
|
|
93
|
+
guidelines you would add, and at most 3 questions for the user, each with a recommended answer. When you built a
|
|
94
|
+
prototype, add its question, branch, verdict and pointer (`prototype/<slug>`) so the main session can pass it on.
|
|
80
95
|
|
|
81
96
|
Severity means: **blocker** – the person cannot do the job, or cannot on a phone; **major** – they can, but will
|
|
82
97
|
get it wrong, misread it or not find it; **minor** – it works and is understood, but is inconsistent or clumsy.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Entry point for a new feature or change once the initial discovery is done – accepts a free-text idea, an existing story (`ST-NNN`) or a ticket (`#123`, `PROJ-123`, URL); grills the idea, runs a focused event storming, updates domain model and ADRs, derives stories into the backlog (local, or the tracker mirror) and runs the story review; bug tickets go to a regression story.
|
|
2
|
+
description: Entry point for a new feature or change once the initial discovery is done – accepts a free-text idea, an existing story (`ST-NNN`) or a ticket (`#123`, `PROJ-123`, URL); grills the idea, runs a focused event storming, updates domain model and ADRs, derives stories into the backlog (local, or the tracker mirror) and runs the story review; bug tickets go to a regression story; `--prototype` adds a throwaway prototype before the stories.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
Load the `feature` skill with the `skill` tool and follow it exactly. Do not restate it.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Engineering workflow – implements one story from docs/stories/ test-first on its own branch, verifies, has it reviewed by code-reviewer and acceptance-tester, refactors, and sets it done on the acceptance tester's verdict and hands the pull request to the user to merge.
|
|
2
|
+
description: Engineering workflow – implements one story from docs/stories/ test-first on its own branch, verifies, has it reviewed by code-reviewer and acceptance-tester, refactors, and sets it done on the acceptance tester's verdict and hands the pull request to the user to merge; `--prototype` prototypes an open UI question first.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
Load the `implement` skill with the `skill` tool and follow it exactly. Do not restate it.
|
package/AGENTS.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Kataster – development entry point
|
|
2
2
|
|
|
3
|
-
This repository is the **toolkit**, not an installation of it. `.claude/`, `.opencode
|
|
4
|
-
|
|
3
|
+
This repository is the **toolkit**, not an installation of it. `.claude/`, `.opencode/` and `templates/` are the
|
|
4
|
+
payload that `npx kataster init` copies into a target repository.
|
|
5
5
|
|
|
6
6
|
- **Installer:** `src/cli.mjs` (commands, prompts), `src/install.mjs` (copy, merge, manifest, upgrade),
|
|
7
7
|
`src/detect.mjs` (stack detection), `src/repo.mjs` (monorepo tooling and workspaces), `src/util.mjs`.
|
|
8
8
|
- **Payload:** `.claude/` (skills, agents, hooks, lib, settings), `.opencode/` (commands, agents, plugin),
|
|
9
|
-
`templates/` (docs skeleton, project profile defaults, conventions template)
|
|
9
|
+
`templates/` (docs skeleton, project profile defaults, conventions template).
|
|
10
10
|
- **Tests:** `npm test` (installs into temp directories and asserts the result).
|
|
11
11
|
- **Docs for users:** `README.md` and `guide/`.
|
|
12
12
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.1 – 2026-11-02
|
|
4
|
+
|
|
5
|
+
- **Optional prototyping, owned by the UX designer.** New `prototype` skill (adapted from Matt Pocock's, MIT) builds
|
|
6
|
+
a throwaway self-contained HTML prototype for one design question: several structurally different UI variants
|
|
7
|
+
(`ui`) or a clickable state model (`logic`). `/feature --prototype[=ui|logic]` – or a proposal from the UX frontier
|
|
8
|
+
during grilling – runs it between grilling and the stories; `/implement --prototype` settles an open UI question
|
|
9
|
+
before the test plan. The verdict goes into the story (`Prototype: …`) and, when it is a recurring rule, into
|
|
10
|
+
`docs/product/ux-guidelines.md` as a G-number. The prototype lives under `docs/prototypes/<slug>/`, is captured on
|
|
11
|
+
a throwaway branch `prototype/<slug>` and is never merged.
|
|
12
|
+
- **Credit where the workflow comes from.** `.claude/THIRD_PARTY_NOTICES.md` lists which skills are derived from
|
|
13
|
+
[Matt Pocock's skills](https://github.com/mattpocock/skills) – some adapted, some copied verbatim – and carries his
|
|
14
|
+
MIT license text. The file ships with the payload and lands in every installation; the README has a Credits
|
|
15
|
+
section.
|
|
16
|
+
|
|
17
|
+
## 0.3.0 – 2026-10-31
|
|
18
|
+
|
|
19
|
+
- **Removed the optional extras and the vendored `shadcn` skill.** `--with` is gone; the CLI fails with a clear
|
|
20
|
+
message instead of reading the value as a directory. The payload no longer ships third-party content: install a
|
|
21
|
+
UI skill such as shadcn/ui in the project that needs it. An installation made with `--with shadcn` keeps the files
|
|
22
|
+
under `.claude/skills/shadcn/`; `upgrade` leaves them alone and drops the stale `workflow.extras` field from
|
|
23
|
+
`.claude/project.json`.
|
|
24
|
+
|
|
3
25
|
## 0.2.1 – 2026-10-31
|
|
4
26
|
|
|
5
27
|
- Releases are published from CI with npm trusted publishing (OIDC): pushing a `v*` tag runs the type check and the
|
package/README.md
CHANGED
|
@@ -92,6 +92,8 @@ docs/
|
|
|
92
92
|
workflow.md the map: sources of truth, commands, phases, rules
|
|
93
93
|
product/vision.md the vision, grilled with you
|
|
94
94
|
product/initiatives/ proposals for large ideas from /shape (no stories)
|
|
95
|
+
product/ux-guidelines.md the interface yardstick
|
|
96
|
+
prototypes/ throwaway prototypes on their own branch; the default branch keeps the README
|
|
95
97
|
domain/events.yaml the event storming model (empty is valid)
|
|
96
98
|
domain/context-map.md
|
|
97
99
|
architecture/data-model.md
|
|
@@ -114,12 +116,12 @@ Existing `CONTEXT.md` and `docs/` are never touched.
|
|
|
114
116
|
| `/grill-me` | Relentless interview on a plan, decision or idea |
|
|
115
117
|
| `/grill-with-docs` | The same, writing glossary and ADRs as you go |
|
|
116
118
|
| `/event-storming [process]` | Big-picture or single-process event storming |
|
|
117
|
-
| `/feature <idea \| ST-NNN \| #123 \| PROJ-123>` | New feature from an idea, an existing story or a ticket: intake and routing, grilling, focused storming, model, stories, review; bugs become a regression story |
|
|
119
|
+
| `/feature <idea \| ST-NNN \| #123 \| PROJ-123>` | New feature from an idea, an existing story or a ticket: intake and routing, grilling, focused storming, model, stories, review; bugs become a regression story; `--prototype` adds a throwaway prototype before the stories |
|
|
118
120
|
| `/shape <idea \| ticket> [--dry-run]` | Before a large feature: frame, place (existing/new context, shared library), impact, slices, rough cost range, recommendation; creates no stories |
|
|
119
121
|
| `/review-stories [ST-…]` | One lead-dev pass (value, build, UX) before a story is `ready` |
|
|
120
122
|
| `/backlog-sync [status\|pull\|push]` | Keep `docs/stories/` in sync with GitHub Issues or Jira |
|
|
121
123
|
| `/groom-backlog [scope]` | Periodic challenge: is this backlog still worth building? |
|
|
122
|
-
| `/implement [ST-NNN]` | Test-first implementation of one story, review, refactor, PR |
|
|
124
|
+
| `/implement [ST-NNN]` | Test-first implementation of one story, review, refactor, PR; `--prototype` prototypes an open UI question first |
|
|
123
125
|
| `/improve-codebase-architecture` | Scan for deepening opportunities, present them, grill one |
|
|
124
126
|
| `/retro` | Retrospective on a session, proposing rule changes |
|
|
125
127
|
|
|
@@ -149,6 +151,21 @@ The brief lands in `docs/product/initiatives/<slug>.md` (`proposed` until you ac
|
|
|
149
151
|
existing monorepo is treated as a new context in an existing landscape, not as a greenfield project; a similar
|
|
150
152
|
service is used as evidence and as the cost anchor, never as a template.
|
|
151
153
|
|
|
154
|
+
### Prototyping an open question
|
|
155
|
+
|
|
156
|
+
When a UI, flow or state question cannot be settled on paper, `/feature --prototype` (or a proposal from the UX
|
|
157
|
+
lens during grilling) runs a throwaway prototype before the stories are written. The `ux-designer` builds one
|
|
158
|
+
self-contained HTML file under `docs/prototypes/<slug>/` – several structurally different UI variants or a
|
|
159
|
+
clickable state model. The verdict goes into the story and, when it is a recurring rule, into the UX guidelines;
|
|
160
|
+
the prototype is captured on a throwaway branch and never merged. `/implement --prototype` does the same for an
|
|
161
|
+
open UI question during engineering; if the prototype changes the story, the story goes back to `review`.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
/feature "checkout with saved cards" --prototype=ui
|
|
165
|
+
/feature PROJ-123 --prototype=logic
|
|
166
|
+
/implement ST-042 --prototype
|
|
167
|
+
```
|
|
168
|
+
|
|
152
169
|
## Greenfield, end to end
|
|
153
170
|
|
|
154
171
|
1. `npx kataster init --greenfield` → review `.claude/project.json`.
|
|
@@ -301,10 +318,6 @@ npx kataster doctor
|
|
|
301
318
|
overwrite files you changed locally – it lists them instead. `--force` overwrites and writes a backup to
|
|
302
319
|
`.kataster/backup/`.
|
|
303
320
|
|
|
304
|
-
## Optional extras
|
|
305
|
-
|
|
306
|
-
- `--with shadcn` installs the shadcn/ui skill for projects that use it.
|
|
307
|
-
|
|
308
321
|
## Design notes
|
|
309
322
|
|
|
310
323
|
- **`.claude/` is the source of truth.** OpenCode and Claude Code share skills, agents and hooks; `.opencode/` is an
|
|
@@ -327,6 +340,21 @@ The toolkit is maintained in the open: bug reports, a skill that fills a real ga
|
|
|
327
340
|
[SECURITY.md](SECURITY.md) is the way to report a vulnerability privately. Participation is covered by the
|
|
328
341
|
[Code of Conduct](CODE_OF_CONDUCT.md).
|
|
329
342
|
|
|
343
|
+
## Credits
|
|
344
|
+
|
|
345
|
+
Kataster stands on other people's work:
|
|
346
|
+
|
|
347
|
+
- **Matt Pocock** – [skills](https://github.com/mattpocock/skills), [aihero.dev](https://www.aihero.dev). The grilling
|
|
348
|
+
interview (`grilling`, `grill-me`, `grill-with-docs`), test-driven development (`tdd`), the deep-module vocabulary
|
|
349
|
+
(`codebase-design`), the architecture survey (`improve-codebase-architecture`), the throwaway prototype
|
|
350
|
+
(`prototype`), the retro, the domain-modeling discipline and `writing-for-agents` come from his skill repository –
|
|
351
|
+
partly adapted, partly copied verbatim under MIT. The per-file mapping and the license text are in
|
|
352
|
+
[.claude/THIRD_PARTY_NOTICES.md](.claude/THIRD_PARTY_NOTICES.md).
|
|
353
|
+
- **John Ousterhout**, *A Philosophy of Software Design* – "Design It Twice" and the depth, seam and deletion-test
|
|
354
|
+
vocabulary.
|
|
355
|
+
- **Eric Evans**, *Domain-Driven Design* – ubiquitous language, bounded contexts, aggregates.
|
|
356
|
+
- **Martin Fowler** – the smell baseline the review agents work from.
|
|
357
|
+
|
|
330
358
|
## License
|
|
331
359
|
|
|
332
360
|
MIT
|
package/guide/concepts.md
CHANGED
|
@@ -29,6 +29,7 @@ Two rules make it work:
|
|
|
29
29
|
| `docs/stories/` | The backlog. One Markdown file per story; `BACKLOG.md` is generated. With a tracker, this is the local mirror | requirements-engineer, PO, lead-dev; `/backlog-sync` with a tracker |
|
|
30
30
|
| `docs/product/vision.md` | Problem, user groups, goals, non-goals, success criteria | user |
|
|
31
31
|
| `docs/product/ux-guidelines.md` | The interface yardstick, as numbered rules with date and reason | ux-designer, approved by user |
|
|
32
|
+
| `docs/prototypes/<slug>/` | Throwaway prototypes on their own branch; only the README stays on the default branch | ux-designer; verdict in the story and the guidelines |
|
|
32
33
|
|
|
33
34
|
## Events, commands, aggregates
|
|
34
35
|
|
|
@@ -75,6 +76,20 @@ An initiative is **not** a work item: no `ready`/`done`, no stories, no second b
|
|
|
75
76
|
with a basis and a confidence – an analogue service is evidence, not a template. Each accepted slice then goes
|
|
76
77
|
through `/feature`, which creates the stories and runs the review.
|
|
77
78
|
|
|
79
|
+
## Prototypes
|
|
80
|
+
|
|
81
|
+
A **prototype** is throwaway code that answers one design question. It is not a first draft: no tests, no
|
|
82
|
+
persistence, no production path. The question decides the branch – `ui` (what should it look like) or `logic`
|
|
83
|
+
(does the state model feel right). In discovery it is one self-contained HTML file under
|
|
84
|
+
`docs/prototypes/<slug>/`, built by the `ux-designer`; a question that needs the real application page is built
|
|
85
|
+
by the main session during `/implement`.
|
|
86
|
+
|
|
87
|
+
`/feature --prototype` (or a proposal from the UX frontier during grilling) adds the phase between grilling and
|
|
88
|
+
the stories. The verdict goes into the story (`Prototype: prototype/<slug> – <question> – <verdict>`) and, when
|
|
89
|
+
it is a recurring rule, into `ux-guidelines.md` as a G-number. The code is captured on a throwaway branch
|
|
90
|
+
`prototype/<slug>` and never merged. `/implement --prototype` does the same for an open UI question during
|
|
91
|
+
engineering; if it changes the story, the story goes back to `review`.
|
|
92
|
+
|
|
78
93
|
## The seam catalog
|
|
79
94
|
|
|
80
95
|
A **seam** is where a test attaches. Testing everything everywhere is not affordable, so the project agrees up front
|
package/guide/install.md
CHANGED
|
@@ -15,7 +15,6 @@ npx kataster init [dir]
|
|
|
15
15
|
| `--backlog <provider>` | Where stories live: `local` (default), `github`, `jira` |
|
|
16
16
|
| `--jira-project <key>` | Jira project key (with `--backlog jira`) |
|
|
17
17
|
| `--github-repo <repo>` | `owner/name` for a GitHub backlog (default: the current repository) |
|
|
18
|
-
| `--with <list>` | Optional extras, comma-separated (`shadcn`) |
|
|
19
18
|
| `--yes`, `-y` | Non-interactive: accept the detected defaults |
|
|
20
19
|
| `--no-install` | Skip `npm install --prefix .claude` |
|
|
21
20
|
| `--dry-run` | Show what would happen, write nothing |
|
|
@@ -57,7 +56,8 @@ npx kataster upgrade
|
|
|
57
56
|
rewritten. `backlog.labelPrefix` in `project.json` is kept, so labels already in GitHub or Jira stay valid.
|
|
58
57
|
- An existing `project.json` keeps its content. If it predates the backlog backend, add the `backlog` section by hand
|
|
59
58
|
(see the README) – without it the provider stays `local`.
|
|
60
|
-
- `--with
|
|
59
|
+
- An extra installed by an older version (`--with shadcn`, up to 0.2.1) stays on disk as a project file; upgrade no
|
|
60
|
+
longer touches it. Delete `.claude/skills/shadcn/` if you do not want it.
|
|
61
61
|
|
|
62
62
|
## Harness setup
|
|
63
63
|
|
package/guide/release.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
npm install --prefix .claude --no-audit --no-fund
|
|
12
12
|
npm run typecheck --prefix .claude
|
|
13
13
|
npm test
|
|
14
|
-
npm pack --dry-run #
|
|
14
|
+
npm pack --dry-run # 148 files, 218 kB – no examples/, no node_modules, no state/
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
4. Install the tarball once and start a throwaway project with it – a tarball that installs is not the same as a
|
|
@@ -77,7 +77,8 @@ npx kataster@latest --version
|
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
The package page shows a provenance badge (`built and signed on GitHub Actions`) and the workflow run is linked to
|
|
80
|
-
the tag. A missing badge means the publish did not go through trusted publishing.
|
|
80
|
+
the tag. A missing badge means the publish did not go through trusted publishing. The registry can take a minute or
|
|
81
|
+
two before a new version appears; `npm view kataster version` is the source of truth, not the cache in `npx`.
|
|
81
82
|
|
|
82
83
|
## What ships
|
|
83
84
|
|
|
@@ -85,7 +86,7 @@ the tag. A missing badge means the publish did not go through trusted publishing
|
|
|
85
86
|
|
|
86
87
|
- `bin/`, `src/` – the CLI and installer
|
|
87
88
|
- `.claude/`, `.opencode/` – the payload the installer copies
|
|
88
|
-
- `templates
|
|
89
|
+
- `templates/` – docs skeleton
|
|
89
90
|
- `guide/`, `README.md`, `AGENTS.md`, `CHANGELOG.md`, `LICENSE`
|
|
90
91
|
|
|
91
92
|
Not shipped: `test/`, `examples/`, `.github/`. `examples/` contains project-specific facts and is reference material
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kataster",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Agent workflow for domain-driven discovery and delivery – drop it into a greenfield or brownfield repository and build the domain by grilling.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -40,7 +40,6 @@
|
|
|
40
40
|
"bin",
|
|
41
41
|
"src",
|
|
42
42
|
"templates",
|
|
43
|
-
"extras",
|
|
44
43
|
"guide",
|
|
45
44
|
".claude",
|
|
46
45
|
".opencode",
|
package/src/cli.mjs
CHANGED
|
@@ -25,7 +25,6 @@ Options:
|
|
|
25
25
|
--backlog <provider> Where stories live: local (default), github, jira
|
|
26
26
|
--jira-project <key> Jira project key (with --backlog jira)
|
|
27
27
|
--github-repo <repo> GitHub repository owner/name (with --backlog github; default: this repo)
|
|
28
|
-
--with <list> Optional extras, comma-separated (available: shadcn)
|
|
29
28
|
--force Overwrite locally modified workflow files (backup is kept)
|
|
30
29
|
--no-install Do not run "npm install --prefix .claude"
|
|
31
30
|
--yes, -y Non-interactive: accept the detected defaults
|
|
@@ -34,7 +33,7 @@ Options:
|
|
|
34
33
|
|
|
35
34
|
function parse(argv) {
|
|
36
35
|
const options = { _: [] };
|
|
37
|
-
const takesValue = new Set(["name", "ui-language", "artifacts", "
|
|
36
|
+
const takesValue = new Set(["name", "ui-language", "artifacts", "backlog", "jira-project", "github-repo"]);
|
|
38
37
|
for (let i = 0; i < argv.length; i += 1) {
|
|
39
38
|
const arg = argv[i];
|
|
40
39
|
if (!arg.startsWith("-")) {
|
|
@@ -49,6 +48,9 @@ function parse(argv) {
|
|
|
49
48
|
else if (arg === "--no-install") options.noInstall = true;
|
|
50
49
|
else if (arg === "--yes" || arg === "-y") options.yes = true;
|
|
51
50
|
else if (arg === "--dry-run") options.dryRun = true;
|
|
51
|
+
else if (arg === "--with" || arg.startsWith("--with=")) {
|
|
52
|
+
throw new Error("--with was removed in 0.3.0 – install an extra such as shadcn/ui directly in your project.");
|
|
53
|
+
}
|
|
52
54
|
else if (arg.startsWith("--") && arg.includes("=")) {
|
|
53
55
|
const [key, ...rest] = arg.slice(2).split("=");
|
|
54
56
|
options[camel(key)] = rest.join("=");
|
|
@@ -104,9 +106,9 @@ Useful commands afterwards:
|
|
|
104
106
|
`);
|
|
105
107
|
}
|
|
106
108
|
|
|
107
|
-
function printSummary(installer
|
|
109
|
+
function printSummary(installer) {
|
|
108
110
|
const { created, updated, conflicts } = installer.summary();
|
|
109
|
-
console.log(`\nDone: ${created} created, ${updated} updated
|
|
111
|
+
console.log(`\nDone: ${created} created, ${updated} updated.`);
|
|
110
112
|
if (conflicts.length) {
|
|
111
113
|
console.log(`\n${conflicts.length} file(s) kept because they were modified locally:`);
|
|
112
114
|
for (const c of conflicts) console.log(` - ${c}`);
|
|
@@ -117,7 +119,6 @@ function printSummary(installer, extras) {
|
|
|
117
119
|
async function init(options) {
|
|
118
120
|
const root = resolve(options._[1] ?? ".");
|
|
119
121
|
const detection = detectProject(root);
|
|
120
|
-
const extras = String(options.with ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
121
122
|
|
|
122
123
|
banner();
|
|
123
124
|
if (existsSync(join(root, ".claude", "install.json"))) {
|
|
@@ -147,7 +148,7 @@ async function init(options) {
|
|
|
147
148
|
: "";
|
|
148
149
|
|
|
149
150
|
const profile = buildProfile(root, {
|
|
150
|
-
name, kind, uiLanguage, artifactLanguage, detection,
|
|
151
|
+
name, kind, uiLanguage, artifactLanguage, detection,
|
|
151
152
|
backlog, jiraProject, githubRepo,
|
|
152
153
|
});
|
|
153
154
|
profile.workflow.version = VERSION;
|
|
@@ -163,7 +164,6 @@ async function init(options) {
|
|
|
163
164
|
installer.putClaudeMd(profile);
|
|
164
165
|
installer.putProfile(profile);
|
|
165
166
|
installer.putConventions(profile);
|
|
166
|
-
installer.installExtras(extras);
|
|
167
167
|
installer.updateGitignore();
|
|
168
168
|
installer.writeManifest();
|
|
169
169
|
|
|
@@ -177,7 +177,7 @@ async function init(options) {
|
|
|
177
177
|
if (!result.ok) console.log("\nTooling dependencies could not be installed – run: npm install --prefix .claude");
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
printSummary(installer
|
|
180
|
+
printSummary(installer);
|
|
181
181
|
nextSteps(root, profile);
|
|
182
182
|
}
|
|
183
183
|
|
|
@@ -190,7 +190,6 @@ async function upgrade(options) {
|
|
|
190
190
|
return init({ ...options, _: ["init", root] });
|
|
191
191
|
}
|
|
192
192
|
const profile = readJson(join(root, ".claude", "project.json")) ?? {};
|
|
193
|
-
const extras = options.with ? String(options.with).split(",").map((s) => s.trim()).filter(Boolean) : profile.workflow?.extras ?? [];
|
|
194
193
|
|
|
195
194
|
console.log(`Upgrading ${root} from ${installer.manifest.version ?? "?"} to ${VERSION}\n`);
|
|
196
195
|
installer.migrateLegacy();
|
|
@@ -202,12 +201,12 @@ async function upgrade(options) {
|
|
|
202
201
|
installer.putContext(profile);
|
|
203
202
|
installer.putClaudeMd(profile);
|
|
204
203
|
installer.putConventions(profile);
|
|
205
|
-
installer.installExtras(extras);
|
|
206
204
|
installer.updateGitignore();
|
|
207
205
|
installer.writeManifest();
|
|
208
206
|
|
|
209
207
|
if (profile.name && !options.dryRun) {
|
|
210
|
-
profile.workflow = { ...(profile.workflow ?? {}), version: VERSION
|
|
208
|
+
profile.workflow = { ...(profile.workflow ?? {}), version: VERSION };
|
|
209
|
+
delete profile.workflow.extras;
|
|
211
210
|
write(join(root, ".claude", "project.json"), `${JSON.stringify(profile, null, 2)}\n`);
|
|
212
211
|
}
|
|
213
212
|
|
|
@@ -216,7 +215,7 @@ async function upgrade(options) {
|
|
|
216
215
|
return;
|
|
217
216
|
}
|
|
218
217
|
if (!options.noInstall) installer.installToolingDependencies();
|
|
219
|
-
printSummary(installer
|
|
218
|
+
printSummary(installer);
|
|
220
219
|
console.log("\nUpgrade complete. Project content (CONTEXT.md, docs/domain, docs/stories, ADRs) was not touched.");
|
|
221
220
|
}
|
|
222
221
|
|
package/src/detect.mjs
CHANGED
|
@@ -157,7 +157,7 @@ export function detectProject(root) {
|
|
|
157
157
|
};
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
export function buildProfile(root, { name, kind, uiLanguage, artifactLanguage, detection,
|
|
160
|
+
export function buildProfile(root, { name, kind, uiLanguage, artifactLanguage, detection, backlog = "local", jiraProject = "", githubRepo = "" }) {
|
|
161
161
|
const stackSummary = [
|
|
162
162
|
...detection.languages,
|
|
163
163
|
...detection.frameworks,
|
|
@@ -230,7 +230,6 @@ export function buildProfile(root, { name, kind, uiLanguage, artifactLanguage, d
|
|
|
230
230
|
},
|
|
231
231
|
workflow: {
|
|
232
232
|
version: "0.1.0",
|
|
233
|
-
extras,
|
|
234
233
|
installedAt: new Date().toISOString(),
|
|
235
234
|
},
|
|
236
235
|
};
|
package/src/install.mjs
CHANGED
|
@@ -341,19 +341,6 @@ export class Installer {
|
|
|
341
341
|
});
|
|
342
342
|
}
|
|
343
343
|
|
|
344
|
-
installExtras(names = []) {
|
|
345
|
-
for (const name of names) {
|
|
346
|
-
const source = join(PKG, "extras", "skills", name);
|
|
347
|
-
if (!existsSync(source)) {
|
|
348
|
-
this.record("skip", source, `unknown extra '${name}'`);
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
for (const file of walk(source)) {
|
|
352
|
-
this.put(join(this.root, ".claude", "skills", name, relative(source, file)), read(file));
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
344
|
installToolingDependencies() {
|
|
358
345
|
if (this.dryRun) return { ok: true, skipped: true };
|
|
359
346
|
if (!existsSync(join(this.root, ".claude", "package.json"))) return { ok: true, skipped: true };
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
The yardstick, not the method. The method is `.claude/skills/ux-design/SKILL.md`.
|
|
5
5
|
Every guideline is a rule someone can point at, with the date and the reason it was decided.
|
|
6
6
|
`ux-designer` maintains this file; the user approves a guideline before it is written here.
|
|
7
|
+
A prototype verdict that becomes a recurring rule lands here as a G-number; the prototype itself stays on
|
|
8
|
+
its throwaway branch (`docs/prototypes/<slug>/`).
|
|
7
9
|
|
|
8
10
|
Format:
|
|
9
11
|
## G1 – <short rule>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Prototypes
|
|
2
|
+
|
|
3
|
+
Throwaway code that answers one design question. The method is `.claude/skills/prototype/SKILL.md`.
|
|
4
|
+
|
|
5
|
+
- A prototype lives in `docs/prototypes/<slug>/` on a throwaway branch `prototype/<slug>`; it is never merged.
|
|
6
|
+
- The default branch keeps this README only. The prototype itself is a primary source on its branch.
|
|
7
|
+
- The decision it settled goes into the story (`Prototype: prototype/<slug> – <question> – <verdict>` in
|
|
8
|
+
`## Context`) and, when it is a recurring rule, into `docs/product/ux-guidelines.md` as a G-number.
|
|
9
|
+
- One question, one self-contained HTML file, one timebox. No tests, no persistence, no production code.
|
|
@@ -17,6 +17,7 @@ is what to read when you are unsure where something belongs.
|
|
|
17
17
|
| Vision, user groups, scope | `docs/product/vision.md` | user + `product-owner` |
|
|
18
18
|
| Initiative briefs (proposals, no stories) | `docs/product/initiatives/<slug>.md` | `/shape`; user accepts |
|
|
19
19
|
| UI/UX decisions (yardstick) | `docs/product/ux-guidelines.md` | `ux-designer` (user approves) |
|
|
20
|
+
| Prototypes (throwaway, on branch `prototype/<slug>`) | `docs/prototypes/<slug>/` | `ux-designer`; verdict in the story and `ux-guidelines.md` |
|
|
20
21
|
| Glossary (ubiquitous language) | `CONTEXT.md` | `domain-model` skill |
|
|
21
22
|
| Event storming model | `docs/domain/events.yaml` | event storming / `domain-architect` |
|
|
22
23
|
| Visualization (generated!) | `docs/domain/event-storming.md` | hook – never edit manually |
|
|
@@ -49,12 +50,13 @@ is what to read when you are unsure where something belongs.
|
|
|
49
50
|
| `affected.ts` | monorepo fast loop: changed files or `--base` → affected packages + native test command |
|
|
50
51
|
| `grilling` (`/grill-me`) | relentless interview in rounds with recommended answers – how we ask questions |
|
|
51
52
|
| `/grill-with-docs` | grilling + `domain-model` + `architect`: writes glossary and ADRs as it goes |
|
|
52
|
-
| `/event-storming [process]`, `/feature <idea \| ST-NNN \| ticket>` | discovery entry points; both start by grilling. `/feature` resolves a story or ticket read-only and routes bugs to a regression story |
|
|
53
|
+
| `/event-storming [process]`, `/feature <idea \| ST-NNN \| ticket>` | discovery entry points; both start by grilling. `/feature` resolves a story or ticket read-only and routes bugs to a regression story; `--prototype` adds a throwaway prototype before the stories |
|
|
53
54
|
| `user-stories`, `/review-stories` | story format, validation, review |
|
|
54
55
|
| `backlog`, `/backlog-sync` | local / GitHub Issues / Jira mirror, sync and conflict rules |
|
|
55
56
|
| `ux-design` | how we decide the interface: the UX frontier, what a story says about a screen, review order |
|
|
57
|
+
| `prototype` | throwaway HTML prototype for a UI or logic question; the verdict goes into the story and the guidelines |
|
|
56
58
|
| `/groom-backlog` | periodic challenge of the open backlog |
|
|
57
|
-
| `/implement [ST-NNN]` | one story test-first, verify, review, refactor, acceptance, pull request |
|
|
59
|
+
| `/implement [ST-NNN]` | one story test-first, verify, review, refactor, acceptance, pull request; `--prototype` prototypes an open UI question first |
|
|
58
60
|
| `tdd` | red → green loop, good tests, seams |
|
|
59
61
|
| `codebase-design` | vocabulary for deep modules |
|
|
60
62
|
| `/improve-codebase-architecture` | periodic scan for deepening opportunities, then grilling |
|
|
@@ -100,6 +102,10 @@ is what to read when you are unsure where something belongs.
|
|
|
100
102
|
source is recorded in the story (`Source: …`), its acceptance criteria are grilled like any other claim, and
|
|
101
103
|
`external` is still written only by the backlog sync. A bug is a story with the label `bug`, not a separate type; a
|
|
102
104
|
change to a documented rule is a feature, because the rule changes.
|
|
105
|
+
- **Prototypes are throwaway.** One question, one self-contained HTML file under `docs/prototypes/<slug>/`,
|
|
106
|
+
captured on a throwaway branch `prototype/<slug>` and never merged. The decision lands in the story
|
|
107
|
+
(`Prototype: …`) and, when it is a recurring rule, in `ux-guidelines.md` as a G-number. No tests, no
|
|
108
|
+
persistence, no production code.
|
|
103
109
|
- **Initiatives are not a backlog.** `docs/product/initiatives/` holds proposals from `/shape`; they have no
|
|
104
110
|
`ready`/`done` and create no stories. Only `docs/stories/` is work. Cost is a range with a basis and a
|
|
105
111
|
confidence – never a single number, never a commitment.
|
|
@@ -110,11 +116,14 @@ is what to read when you are unsure where something belongs.
|
|
|
110
116
|
Discovery, first time: `/bootstrap` (greenfield) or `/adopt` (existing code), then `/review-stories` until stories
|
|
111
117
|
are `ready`. A monorepo is adopted slice by slice: finish one domain plus its shared library, then run
|
|
112
118
|
`/adopt <next path>` – the map keeps track of what is adopted. Later features: `/feature <idea | ticket>`; an idea
|
|
113
|
-
larger than one feature goes through `/shape` first and then `/feature` per slice.
|
|
119
|
+
larger than one feature goes through `/shape` first and then `/feature` per slice. When a UI, flow or state
|
|
120
|
+
question cannot be settled on paper, `/feature --prototype` adds a throwaway prototype between grilling and the
|
|
121
|
+
stories; the verdict goes into the story and the UX guidelines.
|
|
114
122
|
|
|
115
123
|
Engineering, story by story: `/implement [ST-NNN]` (empty = next ready story whose dependencies are done):
|
|
116
124
|
prepare → test plan → red/green per scenario → `verify.ts` → review lane scaled to risk → refactor → acceptance
|
|
117
|
-
tester's verdict → `done` + pull request; **the user only merges**.
|
|
125
|
+
tester's verdict → `done` + pull request; **the user only merges**. `--prototype` settles an open UI question
|
|
126
|
+
first; if it changes the story, the story goes back to `review`. Start the next story in a fresh session.
|
|
118
127
|
|
|
119
128
|
With a tracker: pull before `/review-stories`, `/groom-backlog` and `/implement`; push after changing or approving
|
|
120
129
|
stories and after `done`. The tracker leads on conflict; `docs/stories/` is the mirror and `BACKLOG.md` stays
|