@g3nomaly/g3n-skills 0.0.0-stage → 0.1.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/.claude-plugin/marketplace.json +91 -0
- package/package.json +25 -4
- package/skills/agent/.claude-plugin/plugin.json +7 -0
- package/skills/agent/bootstrap/SKILL.md +21 -0
- package/skills/agent/bootstrap/agents/openai.yaml +5 -0
- package/skills/agent/worktrees/SKILL.md +21 -0
- package/skills/agent/worktrees/agents/openai.yaml +5 -0
- package/skills/coding/.claude-plugin/plugin.json +7 -0
- package/skills/coding/code/SKILL.md +28 -0
- package/skills/coding/code/agents/openai.yaml +5 -0
- package/skills/coding/code/references/typescript.md +26 -0
- package/skills/coding/document/SKILL.md +39 -0
- package/skills/coding/document/agents/openai.yaml +5 -0
- package/skills/coding/document/references/typescript.md +90 -0
- package/skills/grilling/.claude-plugin/plugin.json +7 -0
- package/skills/grilling/domain-modeling/ADR-FORMAT.md +47 -0
- package/skills/grilling/domain-modeling/CONTEXT-FORMAT.md +60 -0
- package/skills/grilling/domain-modeling/SKILL.md +74 -0
- package/skills/grilling/domain-modeling/agents/openai.yaml +3 -0
- package/skills/grilling/grill-me/SKILL.md +7 -0
- package/skills/grilling/grill-me/agents/openai.yaml +5 -0
- package/skills/grilling/grill-with-docs/SKILL.md +7 -0
- package/skills/grilling/grill-with-docs/agents/openai.yaml +5 -0
- package/skills/grilling/grilling/SKILL.md +12 -0
- package/skills/grilling/grilling/agents/openai.yaml +3 -0
- package/skills/speech/.claude-plugin/plugin.json +7 -0
- package/skills/speech/emphasise/SKILL.md +49 -0
- package/skills/speech/emphasise/agents/openai.yaml +5 -0
- package/skills/speech/unslop/SKILL.md +80 -0
- package/skills/task-manager/.claude-plugin/plugin.json +12 -0
- package/skills/task-manager/decisions/SKILL.md +39 -0
- package/skills/task-manager/decisions/agents/openai.yaml +5 -0
- package/skills/task-manager/decisions/hooks/add-decision.ts +26 -0
- package/skills/task-manager/decisions/hooks/get-decision.ts +16 -0
- package/skills/task-manager/decisions/hooks/list-decisions.ts +25 -0
- package/skills/task-manager/decisions/references/usage.md +26 -0
- package/skills/task-manager/decisions/src/index.ts +8 -0
- package/skills/task-manager/decisions/src/paths.ts +13 -0
- package/skills/task-manager/decisions/src/read.ts +56 -0
- package/skills/task-manager/decisions/src/write.ts +65 -0
- package/skills/task-manager/decisions/tsconfig.json +7 -0
- package/skills/task-manager/hooks.json +27 -0
- package/skills/task-manager/task-manager/SKILL.md +36 -0
- package/skills/task-manager/task-manager/bun.lock +15 -0
- package/skills/task-manager/task-manager/hooks/cleanup.ts +43 -0
- package/skills/task-manager/task-manager/hooks/get-entry.ts +29 -0
- package/skills/task-manager/task-manager/hooks/guard-tree.ts +87 -0
- package/skills/task-manager/task-manager/hooks/list-entries.ts +27 -0
- package/skills/task-manager/task-manager/hooks/next-entry.ts +33 -0
- package/skills/task-manager/task-manager/hooks/set-state.ts +27 -0
- package/skills/task-manager/task-manager/hooks/sync-tree.ts +36 -0
- package/skills/task-manager/task-manager/package.json +8 -0
- package/skills/task-manager/task-manager/references/hooks.md +34 -0
- package/skills/task-manager/task-manager/references/task-file.md +26 -0
- package/skills/task-manager/task-manager/references/tree.md +39 -0
- package/skills/task-manager/task-manager/src/filetree/ensure.ts +39 -0
- package/skills/task-manager/task-manager/src/filetree/entries.ts +56 -0
- package/skills/task-manager/task-manager/src/filetree/frontmatter.ts +58 -0
- package/skills/task-manager/task-manager/src/filetree/generate.ts +76 -0
- package/skills/task-manager/task-manager/src/filetree/index.ts +36 -0
- package/skills/task-manager/task-manager/src/filetree/levels.ts +54 -0
- package/skills/task-manager/task-manager/src/filetree/locate.ts +118 -0
- package/skills/task-manager/task-manager/src/filetree/paths.ts +46 -0
- package/skills/task-manager/task-manager/src/filetree/read.ts +54 -0
- package/skills/task-manager/task-manager/src/filetree/remove.ts +19 -0
- package/skills/task-manager/task-manager/src/filetree/root.ts +28 -0
- package/skills/task-manager/task-manager/src/filetree/status.ts +76 -0
- package/skills/task-manager/task-manager/src/hooks/cli.ts +77 -0
- package/skills/task-manager/task-manager/src/hooks/index.ts +3 -0
- package/skills/task-manager/task-manager/src/schemas/config.ts +22 -0
- package/skills/task-manager/task-manager/src/schemas/decision.ts +33 -0
- package/skills/task-manager/task-manager/src/schemas/index.ts +42 -0
- package/skills/task-manager/task-manager/src/schemas/phase.ts +21 -0
- package/skills/task-manager/task-manager/src/schemas/plan.ts +20 -0
- package/skills/task-manager/task-manager/src/schemas/primitives.ts +41 -0
- package/skills/task-manager/task-manager/src/schemas/task.ts +24 -0
- package/skills/task-manager/task-manager/src/schemas/term.ts +31 -0
- package/skills/task-manager/task-manager/src/schemas/validation.ts +54 -0
- package/skills/task-manager/task-manager/src/vocabulary/file.ts +98 -0
- package/skills/task-manager/task-manager/src/vocabulary/index.ts +5 -0
- package/skills/task-manager/task-manager/src/vocabulary/match.ts +52 -0
- package/skills/task-manager/vocabulary/SKILL.md +42 -0
- package/skills/task-manager/vocabulary/agents/openai.yaml +5 -0
- package/skills/task-manager/vocabulary/hooks/get-term.ts +18 -0
- package/skills/task-manager/vocabulary/hooks/list-terms.ts +12 -0
- package/skills/task-manager/vocabulary/hooks/remove-term.ts +22 -0
- package/skills/task-manager/vocabulary/hooks/set-term.ts +37 -0
- package/skills/task-manager/vocabulary/references/usage.md +26 -0
- package/skills/task-manager/vocabulary/tsconfig.json +7 -0
- package/skills/using-hooks/.claude-plugin/plugin.json +7 -0
- package/skills/using-hooks/hook-post-tool-use/SKILL.md +79 -0
- package/skills/using-hooks/hook-post-tool-use/agents/openai.yaml +5 -0
- package/skills/using-hooks/hook-pre-tool-use/SKILL.md +84 -0
- package/skills/using-hooks/hook-pre-tool-use/agents/openai.yaml +5 -0
- package/skills/using-hooks/hook-stop/SKILL.md +69 -0
- package/skills/using-hooks/hook-stop/agents/openai.yaml +5 -0
- package/skills/using-hooks/hook-user-prompt-submit/SKILL.md +64 -0
- package/skills/using-hooks/hook-user-prompt-submit/agents/openai.yaml +5 -0
- package/skills/workflow/.claude-plugin/plugin.json +17 -0
- package/skills/workflow/execute/SKILL.md +21 -0
- package/skills/workflow/execute/agents/openai.yaml +5 -0
- package/skills/workflow/orchestrator/SKILL.md +27 -0
- package/skills/workflow/orchestrator/agents/openai.yaml +5 -0
- package/skills/workflow/orchestrator/hooks/ready-phases.ts +21 -0
- package/skills/workflow/orchestrator/tsconfig.json +8 -0
- package/skills/workflow/plan/SKILL.md +18 -0
- package/skills/workflow/plan/agents/openai.yaml +5 -0
- package/skills/workflow/review/SKILL.md +25 -0
- package/skills/workflow/review/agents/openai.yaml +5 -0
- package/skills/workflow/review/agents/reviewer.md +9 -0
- package/skills/workflow/run/SKILL.md +33 -0
- package/skills/workflow/run/agents/openai.yaml +5 -0
- package/skills/workflow/run/hooks/advance-step.ts +60 -0
- package/skills/workflow/run/hooks/current-step.ts +35 -0
- package/skills/workflow/run/references/sub-agents.md +46 -0
- package/skills/workflow/run/src/gates.ts +53 -0
- package/skills/workflow/run/src/phase.ts +36 -0
- package/skills/workflow/run/src/steps.ts +37 -0
- package/skills/workflow/run/tsconfig.json +7 -0
- package/skills/workflow/sync/SKILL.md +18 -0
- package/skills/workflow/sync/agents/openai.yaml +5 -0
- package/skills/workflow/worktree/SKILL.md +38 -0
- package/skills/workflow/worktree/agents/openai.yaml +5 -0
- package/skills/workflow/worktree/references/git-commands.md +27 -0
- package/skills/writing/.claude-plugin/plugin.json +7 -0
- package/skills/writing/writing-great-hooks/SKILL.md +24 -0
- package/skills/writing/writing-great-hooks/agents/openai.yaml +5 -0
- package/skills/writing/writing-great-hooks/references/lifecycle-hook.md +46 -0
- package/skills/writing/writing-great-hooks/references/skill-hook.md +46 -0
- package/skills/writing/writing-great-skills/SKILL.md +36 -0
- package/skills/writing/writing-great-skills/agents/openai.yaml +5 -0
- package/skills/writing/writing-great-tasks/SKILL.md +31 -0
- package/skills/writing/writing-great-tasks/agents/openai.yaml +5 -0
- package/skills/writing/writing-great-tasks/references/template.md +45 -0
- package/README.md +0 -3
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "g3n",
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "g3ntrovert"
|
|
5
|
+
},
|
|
6
|
+
"plugins": [
|
|
7
|
+
{
|
|
8
|
+
"name": "agent",
|
|
9
|
+
"source": "./skills/agent",
|
|
10
|
+
"description": "Rules every agent session follows: the session bootstrap, its boundaries, and working in worktrees.",
|
|
11
|
+
"skills": [
|
|
12
|
+
"./bootstrap",
|
|
13
|
+
"./worktrees"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "coding",
|
|
18
|
+
"source": "./skills/coding",
|
|
19
|
+
"description": "How to write, check and document code, per language.",
|
|
20
|
+
"skills": [
|
|
21
|
+
"./code",
|
|
22
|
+
"./document"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "grilling",
|
|
27
|
+
"source": "./skills/grilling",
|
|
28
|
+
"description": "Relentless interviews that stress-test a plan, plus the domain model they feed.",
|
|
29
|
+
"skills": [
|
|
30
|
+
"./grilling",
|
|
31
|
+
"./grill-me",
|
|
32
|
+
"./grill-with-docs",
|
|
33
|
+
"./domain-modeling"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "speech",
|
|
38
|
+
"source": "./skills/speech",
|
|
39
|
+
"description": "Conventions for how an agent writes — emphasis markup and cutting AI tells.",
|
|
40
|
+
"skills": [
|
|
41
|
+
"./emphasise",
|
|
42
|
+
"./unslop"
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"name": "task-manager",
|
|
47
|
+
"source": "./skills/task-manager",
|
|
48
|
+
"description": "Query and drive a tree of plans, phases and tasks through hooks, with the plan's decisions and the project vocabulary kept beside them.",
|
|
49
|
+
"skills": [
|
|
50
|
+
"./task-manager",
|
|
51
|
+
"./vocabulary",
|
|
52
|
+
"./decisions"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "using-hooks",
|
|
57
|
+
"source": "./skills/using-hooks",
|
|
58
|
+
"description": "How to write each Claude Code lifecycle hook.",
|
|
59
|
+
"skills": [
|
|
60
|
+
"./hook-pre-tool-use",
|
|
61
|
+
"./hook-post-tool-use",
|
|
62
|
+
"./hook-stop",
|
|
63
|
+
"./hook-user-prompt-submit"
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"name": "workflow",
|
|
68
|
+
"source": "./skills/workflow",
|
|
69
|
+
"description": "Work a phase of a plan through plan, execute, review and sync, one agent per step, with hooks deciding when a step is finished.",
|
|
70
|
+
"skills": [
|
|
71
|
+
"./run",
|
|
72
|
+
"./plan",
|
|
73
|
+
"./execute",
|
|
74
|
+
"./review",
|
|
75
|
+
"./sync",
|
|
76
|
+
"./orchestrator",
|
|
77
|
+
"./worktree"
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"name": "writing",
|
|
82
|
+
"source": "./skills/writing",
|
|
83
|
+
"description": "How to write skills, hooks and tasks that an agent can follow.",
|
|
84
|
+
"skills": [
|
|
85
|
+
"./writing-great-hooks",
|
|
86
|
+
"./writing-great-skills",
|
|
87
|
+
"./writing-great-tasks"
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@g3nomaly/g3n-skills",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The g3n skills, each with its own hooks: a skill source for @g3nomaly/skills and a Claude Code plugin marketplace.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
".claude-plugin",
|
|
8
|
+
"skills"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "bun run build:marketplace",
|
|
12
|
+
"build:marketplace": "bun scripts/build-marketplace.ts",
|
|
13
|
+
"typecheck": "tsc --noEmit",
|
|
14
|
+
"test": "bun test",
|
|
15
|
+
"test:clean": "CLEAN_TMP=1 bun test"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@g3nomaly/core": "^0.3.1",
|
|
19
|
+
"@types/bun": "^1.4.0",
|
|
20
|
+
"typescript": "~7.0.2",
|
|
21
|
+
"zod": "^4.4.3"
|
|
22
|
+
},
|
|
23
|
+
"license": "Elastic-2.0",
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bootstrap
|
|
3
|
+
description: Session start checks and agent boundaries. Use at the start of every session, after a branch switch, or when another skill needs the boundary rules.
|
|
4
|
+
disable-model-invocation: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Steps
|
|
8
|
+
|
|
9
|
+
Run every session before any work, and after a branch switch.
|
|
10
|
+
|
|
11
|
+
1. **Read** `CLAUDE.md` in full.
|
|
12
|
+
2. **Get the file tree**: run `git ls-files --cached --others --exclude-standard`.
|
|
13
|
+
3. **Compare** it against the tree you expect. On mismatch, output exactly `FILE TREE MISMATCH`, stop and ask. Do not guess.
|
|
14
|
+
4. **State the branch**: output exactly `BRANCH: <name>`, from `git branch --show-current`. It must be `main` in the main checkout, unless the user asked you to work in a worktree (see the `/worktrees` skill). Otherwise stop and ask.
|
|
15
|
+
|
|
16
|
+
Done when `BRANCH: <name>` is printed and no step stopped you.
|
|
17
|
+
|
|
18
|
+
## Boundaries
|
|
19
|
+
|
|
20
|
+
- **Air-gapped**: everything stays on disk. Never publish, push, upload or share anything to an external service.
|
|
21
|
+
- **No workarounds**: when a tool call or permission is blocked, stop and report it.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: worktrees
|
|
3
|
+
description: Work in a git worktree on its home branch and land the work there with a local squash merge. Use only when the user asks you to work in a worktree.
|
|
4
|
+
disable-model-invocation: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
A worktree at `~/worktrees/<repo>/<x>` has the **home branch** `worktree/<x>`, which tracks local `main`. Work ends on the home branch. The user merges it into `main`.
|
|
8
|
+
|
|
9
|
+
## Steps
|
|
10
|
+
|
|
11
|
+
1. `git switch worktree/<x> && git pull --no-rebase --no-edit`
|
|
12
|
+
2. `git switch -c <type>/<name>`, do the work, commit, and run the package's checks (see the `/code` skill)
|
|
13
|
+
3. `git switch worktree/<x> && git pull --no-rebase --no-edit`
|
|
14
|
+
4. `git merge --squash <type>/<name>`, then `git commit` with a subject and body covering the whole change
|
|
15
|
+
5. Stop and report. Leave the feature branch in place.
|
|
16
|
+
|
|
17
|
+
On conflict: `git merge --abort` (after a squash: `git reset --merge`), stop and report.
|
|
18
|
+
|
|
19
|
+
## Branch types
|
|
20
|
+
|
|
21
|
+
`feature`, `fix`, `refactor`, `chore`, `docs`, `snapshot` (backup before destructive operations), `demo` (not meant to merge), `experiment` (may never merge).
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code
|
|
3
|
+
description: Standard code skill for writing and checking code. Includes toolchain references for each language.
|
|
4
|
+
disable-model-invocation: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Rules
|
|
8
|
+
|
|
9
|
+
Apply SOLID principles, DRY, and KISS. Use descriptive names for variables, functions, and classes.
|
|
10
|
+
|
|
11
|
+
- **One domain per file**: schemas, selectors and business logic live in separate files. Split god objects.
|
|
12
|
+
- **Strict typing**: per the language reference. Python passes `mypy` or `pyright`.
|
|
13
|
+
- **Production grade**: handle errors explicitly, validate external input at the boundary, leave no dead code.
|
|
14
|
+
- **No shims**: on a rename or refactor, update every call site. Leave no aliases.
|
|
15
|
+
- **Config from the environment**: read configuration from environment variables through a schema.
|
|
16
|
+
|
|
17
|
+
## Testing
|
|
18
|
+
|
|
19
|
+
- Features in active development get no tests. The type checker and linters carry the structural checks.
|
|
20
|
+
- Tests go in `tests/`, once a feature's API is stable.
|
|
21
|
+
|
|
22
|
+
## code references
|
|
23
|
+
|
|
24
|
+
Each language has a reference that names its toolchain, its commands and its rules.
|
|
25
|
+
|
|
26
|
+
| Language | Reference | Files |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| TypeScript | [`references/typescript.md`](references/typescript.md) | `.ts` `.tsx` |
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# TypeScript
|
|
2
|
+
|
|
3
|
+
Bun handles install, run, test and build. Run commands from inside the package directory.
|
|
4
|
+
|
|
5
|
+
| Task | Command |
|
|
6
|
+
|---|---|
|
|
7
|
+
| Install | `bun install` |
|
|
8
|
+
| Add a dependency | `bun add <pkg>`, or `bun add -d <pkg>` for dev |
|
|
9
|
+
| Run a file | `bun <file>` |
|
|
10
|
+
| Run a script | `bun run <script>` |
|
|
11
|
+
| Run a tool once | `bunx <pkg>` |
|
|
12
|
+
| Build | `bun run build` |
|
|
13
|
+
|
|
14
|
+
## Checks
|
|
15
|
+
|
|
16
|
+
| Check | Command | When |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| Typecheck | `bun run typecheck` | always |
|
|
19
|
+
| Lint | `bun run lint` | when the package defines it |
|
|
20
|
+
| Test | `bun test` | when the package has tests |
|
|
21
|
+
|
|
22
|
+
## Rules
|
|
23
|
+
|
|
24
|
+
- `strict: true` in `tsconfig.json`.
|
|
25
|
+
- `unknown` and narrowing in place of `any`.
|
|
26
|
+
- External input is parsed with zod at the boundary.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: document
|
|
3
|
+
description: Docstrings and comments for functions and classes, and where the reasons behind code go. Use when writing or changing a function or class, or when another skill needs the documentation rules.
|
|
4
|
+
disable-model-invocation: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Documentation describes the code as it is now: _what_ it does and _how_. The _why_ goes in `decisions.md`.
|
|
8
|
+
|
|
9
|
+
## Files
|
|
10
|
+
|
|
11
|
+
Line 1 of every file is a comment with its relative path, such as `// path/to/file.ts`. No file-level docstring.
|
|
12
|
+
|
|
13
|
+
## Functions
|
|
14
|
+
|
|
15
|
+
Every function gets a docstring that says what it does in one or two sentences.
|
|
16
|
+
|
|
17
|
+
`@param` and `@returns` important. Add one when the type alone hides the meaning, such as the form of an id, whether a path is absolute or relative to what, the unit of a number, or when the result can be empty. Leave them out when the name and the types already make it clear.
|
|
18
|
+
|
|
19
|
+
## Classes
|
|
20
|
+
|
|
21
|
+
A class docstring says:
|
|
22
|
+
|
|
23
|
+
- what the class does and what it holds,
|
|
24
|
+
- where it is used: the modules that create it and the ones that consume it,
|
|
25
|
+
- how to create one, as an `@example`, when the constructor takes more than the obvious.
|
|
26
|
+
|
|
27
|
+
## Comments
|
|
28
|
+
|
|
29
|
+
An inline comment explains how a piece of code works when the code itself does not show it. Use sparingly!
|
|
30
|
+
|
|
31
|
+
## Decisions
|
|
32
|
+
|
|
33
|
+
The reason code is the way it is goes in `decisions.md` as an entry. Decisions are never written directly in the code.
|
|
34
|
+
|
|
35
|
+
## Languages
|
|
36
|
+
|
|
37
|
+
The syntax for each language:
|
|
38
|
+
|
|
39
|
+
- TypeScript: [`references/typescript.md`](references/typescript.md)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# TypeScript
|
|
2
|
+
|
|
3
|
+
TSDoc: a `/** */` block directly above the declaration. The first sentence is the summary. Tags are `@param name - text` and `@returns text`.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
/** Adds two numbers. */
|
|
7
|
+
export function add(a: number, b: number): number {
|
|
8
|
+
return a + b;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @brief Retrieves a user by id.
|
|
13
|
+
*
|
|
14
|
+
* @param userId - Surrogate key from the `users` table, not the auth provider's id.
|
|
15
|
+
* @returns Custom User class used by the authentication service, or `undefined` when no row matches.
|
|
16
|
+
*/
|
|
17
|
+
export async function getUser(userId: number): Promise<User | undefined> {
|
|
18
|
+
// ...
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @brief Error for a file on disk that does not match its schema.
|
|
23
|
+
*
|
|
24
|
+
* Holds the path of the file and one issue per rejected field, and its message
|
|
25
|
+
* lists them all. Thrown by `parseFile` and by the readers in `filetree/`,
|
|
26
|
+
* `decisions/` and `vocabulary/` that check a file's layout by hand. Callers
|
|
27
|
+
* tell it apart from other errors with `instanceof FileValidationError`.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* throw new FileValidationError("/home/me/app/docs/task-manager/auth/auth.md", [
|
|
31
|
+
* { field: "status", message: 'is "done"' },
|
|
32
|
+
* ]);
|
|
33
|
+
*/
|
|
34
|
+
export class FileValidationError extends Error {
|
|
35
|
+
readonly file: string;
|
|
36
|
+
readonly issues: FileValidationIssue[];
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @brief Builds the message from the file path and every issue.
|
|
40
|
+
*
|
|
41
|
+
* @param file - Absolute path of the file that failed, e.g. `/home/me/app/docs/task-manager/auth/auth.md`.
|
|
42
|
+
* @param issues - Rejected fields, e.g. `{ field: "phases.0.status", message: "is required" }`.
|
|
43
|
+
*/
|
|
44
|
+
constructor(file: string, issues: FileValidationIssue[]) {
|
|
45
|
+
// ...
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Exported types and interfaces get a one-line docstring. A field gets its own `/** */` line only when its name and type leave its meaning open.
|
|
51
|
+
|
|
52
|
+
## Bad
|
|
53
|
+
|
|
54
|
+
Each one next to what is wrong with it. The examples above show the fix.
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
/** Holds the installed skills read from `skills.json`. */
|
|
58
|
+
export class SkillRegistry {}
|
|
59
|
+
```
|
|
60
|
+
Too thin. It leaves out what the class holds, who creates and consumes it, and how to make one.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
/** @param file - Path of the file that was read. */
|
|
64
|
+
constructor(file: string, issues: FileValidationIssue[])
|
|
65
|
+
```
|
|
66
|
+
`file` doesn't say absolute or relative. `issues` is missing, while its type hides what goes in it.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
/**
|
|
70
|
+
* @param issues - One entry per rejected field. `field` is the dotted path
|
|
71
|
+
* as it reads in the file, such as `phases.0.status`, or `(whole file)`.
|
|
72
|
+
*/
|
|
73
|
+
```
|
|
74
|
+
Prose about the type. One example value shows it faster: `` e.g. `{ field: "phases.0.status", message: "is required" }` ``.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
/**
|
|
78
|
+
* Adds two numbers.
|
|
79
|
+
* @param a - The first number.
|
|
80
|
+
* @param b - The second number.
|
|
81
|
+
* @returns The sum.
|
|
82
|
+
*/
|
|
83
|
+
export function add(a: number, b: number): number
|
|
84
|
+
```
|
|
85
|
+
The tags repeat the signature. The summary line is enough.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
/** Loads a user by id. Uses a surrogate key because auth ids changed format in 2024. */
|
|
89
|
+
```
|
|
90
|
+
The _why_ belongs in `decisions.md`. The docstring says what and how.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# ADR Format
|
|
2
|
+
|
|
3
|
+
ADRs live in `docs/adr/` and use sequential numbering: `0001-slug.md`, `0002-slug.md`, etc.
|
|
4
|
+
|
|
5
|
+
Create the `docs/adr/` directory lazily — only when the first ADR is needed.
|
|
6
|
+
|
|
7
|
+
## Template
|
|
8
|
+
|
|
9
|
+
```md
|
|
10
|
+
# {Short title of the decision}
|
|
11
|
+
|
|
12
|
+
{1-3 sentences: what's the context, what did we decide, and why.}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
That's it. An ADR can be a single paragraph. The value is in recording *that* a decision was made and *why* — not in filling out sections.
|
|
16
|
+
|
|
17
|
+
## Optional sections
|
|
18
|
+
|
|
19
|
+
Only include these when they add genuine value. Most ADRs won't need them.
|
|
20
|
+
|
|
21
|
+
- **Status** frontmatter (`proposed | accepted | deprecated | superseded by ADR-NNNN`) — useful when decisions are revisited
|
|
22
|
+
- **Considered Options** — only when the rejected alternatives are worth remembering
|
|
23
|
+
- **Consequences** — only when non-obvious downstream effects need to be called out
|
|
24
|
+
|
|
25
|
+
## Numbering
|
|
26
|
+
|
|
27
|
+
Scan `docs/adr/` for the highest existing number and increment by one.
|
|
28
|
+
|
|
29
|
+
## When to offer an ADR
|
|
30
|
+
|
|
31
|
+
All three of these must be true:
|
|
32
|
+
|
|
33
|
+
1. **Hard to reverse** — the cost of changing your mind later is meaningful
|
|
34
|
+
2. **Surprising without context** — a future reader will look at the code and wonder "why on earth did they do it this way?"
|
|
35
|
+
3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons
|
|
36
|
+
|
|
37
|
+
If a decision is easy to reverse, skip it — you'll just reverse it. If it's not surprising, nobody will wonder why. If there was no real alternative, there's nothing to record beyond "we did the obvious thing."
|
|
38
|
+
|
|
39
|
+
### What qualifies
|
|
40
|
+
|
|
41
|
+
- **Architectural shape.** "We're using a monorepo." "The write model is event-sourced, the read model is projected into Postgres."
|
|
42
|
+
- **Integration patterns between contexts.** "Ordering and Billing communicate via domain events, not synchronous HTTP."
|
|
43
|
+
- **Technology choices that carry lock-in.** Database, message bus, auth provider, deployment target. Not every library — just the ones that would take a quarter to swap out.
|
|
44
|
+
- **Boundary and scope decisions.** "Customer data is owned by the Customer context; other contexts reference it by ID only." The explicit no-s are as valuable as the yes-s.
|
|
45
|
+
- **Deliberate deviations from the obvious path.** "We're using manual SQL instead of an ORM because X." Anything where a reasonable reader would assume the opposite. These stop the next engineer from "fixing" something that was deliberate.
|
|
46
|
+
- **Constraints not visible in the code.** "We can't use AWS because of compliance requirements." "Response times must be under 200ms because of the partner API contract."
|
|
47
|
+
- **Rejected alternatives when the rejection is non-obvious.** If you considered GraphQL and picked REST for subtle reasons, record it — otherwise someone will suggest GraphQL again in six months.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# CONTEXT.md Format
|
|
2
|
+
|
|
3
|
+
## Structure
|
|
4
|
+
|
|
5
|
+
```md
|
|
6
|
+
# {Context Name}
|
|
7
|
+
|
|
8
|
+
{One or two sentence description of what this context is and why it exists.}
|
|
9
|
+
|
|
10
|
+
## Language
|
|
11
|
+
|
|
12
|
+
**Order**:
|
|
13
|
+
{A one or two sentence description of the term}
|
|
14
|
+
_Avoid_: Purchase, transaction
|
|
15
|
+
|
|
16
|
+
**Invoice**:
|
|
17
|
+
A request for payment sent to a customer after delivery.
|
|
18
|
+
_Avoid_: Bill, payment request
|
|
19
|
+
|
|
20
|
+
**Customer**:
|
|
21
|
+
A person or organization that places orders.
|
|
22
|
+
_Avoid_: Client, buyer, account
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Rules
|
|
26
|
+
|
|
27
|
+
- **Be opinionated.** When multiple words exist for the same concept, pick the best one and list the others under `_Avoid_`.
|
|
28
|
+
- **Keep definitions tight.** One or two sentences max. Define what it IS, not what it does.
|
|
29
|
+
- **Only include terms specific to this project's context.** General programming concepts (timeouts, error types, utility patterns) don't belong even if the project uses them extensively. Before adding a term, ask: is this a concept unique to this context, or a general programming concept? Only the former belongs.
|
|
30
|
+
- **Group terms under subheadings** when natural clusters emerge. If all terms belong to a single cohesive area, a flat list is fine.
|
|
31
|
+
|
|
32
|
+
## Single vs multi-context repos
|
|
33
|
+
|
|
34
|
+
**Single context (most repos):** One `CONTEXT.md` at the repo root.
|
|
35
|
+
|
|
36
|
+
**Multiple contexts:** A `CONTEXT-MAP.md` at the repo root lists the contexts, where they live, and how they relate to each other:
|
|
37
|
+
|
|
38
|
+
```md
|
|
39
|
+
# Context Map
|
|
40
|
+
|
|
41
|
+
## Contexts
|
|
42
|
+
|
|
43
|
+
- [Ordering](./src/ordering/CONTEXT.md) — receives and tracks customer orders
|
|
44
|
+
- [Billing](./src/billing/CONTEXT.md) — generates invoices and processes payments
|
|
45
|
+
- [Fulfillment](./src/fulfillment/CONTEXT.md) — manages warehouse picking and shipping
|
|
46
|
+
|
|
47
|
+
## Relationships
|
|
48
|
+
|
|
49
|
+
- **Ordering → Fulfillment**: Ordering emits `OrderPlaced` events; Fulfillment consumes them to start picking
|
|
50
|
+
- **Fulfillment → Billing**: Fulfillment emits `ShipmentDispatched` events; Billing consumes them to generate invoices
|
|
51
|
+
- **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money`
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The skill infers which structure applies:
|
|
55
|
+
|
|
56
|
+
- If `CONTEXT-MAP.md` exists, read it to find contexts
|
|
57
|
+
- If only a root `CONTEXT.md` exists, single context
|
|
58
|
+
- If neither exists, create a root `CONTEXT.md` lazily when the first term is resolved
|
|
59
|
+
|
|
60
|
+
When multiple contexts exist, infer which one the current topic relates to. If unclear, ask.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: domain-modeling
|
|
3
|
+
description: Build and sharpen a project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to maintain the domain model.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Domain Modeling
|
|
7
|
+
|
|
8
|
+
Actively build and sharpen the project's domain model as you design. This is the *active* discipline — challenging terms, inventing edge-case scenarios, and writing the glossary and decisions down the moment they crystallise. (Merely *reading* `CONTEXT.md` for vocabulary is not this skill — that's a one-line habit any skill can do. This skill is for when you're changing the model, not just consuming it.)
|
|
9
|
+
|
|
10
|
+
## File structure
|
|
11
|
+
|
|
12
|
+
Most repos have a single context:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
/
|
|
16
|
+
├── CONTEXT.md
|
|
17
|
+
├── docs/
|
|
18
|
+
│ └── adr/
|
|
19
|
+
│ ├── 0001-event-sourced-orders.md
|
|
20
|
+
│ └── 0002-postgres-for-write-model.md
|
|
21
|
+
└── src/
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If a `CONTEXT-MAP.md` exists at the root, the repo has multiple contexts. The map points to where each one lives:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
/
|
|
28
|
+
├── CONTEXT-MAP.md
|
|
29
|
+
├── docs/
|
|
30
|
+
│ └── adr/ ← system-wide decisions
|
|
31
|
+
├── src/
|
|
32
|
+
│ ├── ordering/
|
|
33
|
+
│ │ ├── CONTEXT.md
|
|
34
|
+
│ │ └── docs/adr/ ← context-specific decisions
|
|
35
|
+
│ └── billing/
|
|
36
|
+
│ ├── CONTEXT.md
|
|
37
|
+
│ └── docs/adr/
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Create files lazily — only when you have something to write. If no `CONTEXT.md` exists, create one when the first term is resolved. If no `docs/adr/` exists, create it when the first ADR is needed.
|
|
41
|
+
|
|
42
|
+
## During the session
|
|
43
|
+
|
|
44
|
+
### Challenge against the glossary
|
|
45
|
+
|
|
46
|
+
When the user uses a term that conflicts with the existing language in `CONTEXT.md`, call it out immediately. "Your glossary defines 'cancellation' as X, but you seem to mean Y — which is it?"
|
|
47
|
+
|
|
48
|
+
### Sharpen fuzzy language
|
|
49
|
+
|
|
50
|
+
When the user uses vague or overloaded terms, propose a precise canonical term. "You're saying 'account' — do you mean the Customer or the User? Those are different things."
|
|
51
|
+
|
|
52
|
+
### Discuss concrete scenarios
|
|
53
|
+
|
|
54
|
+
When domain relationships are being discussed, stress-test them with specific scenarios. Invent scenarios that probe edge cases and force the user to be precise about the boundaries between concepts.
|
|
55
|
+
|
|
56
|
+
### Cross-reference with code
|
|
57
|
+
|
|
58
|
+
When the user states how something works, check whether the code agrees. If you find a contradiction, surface it: "Your code cancels entire Orders, but you just said partial cancellation is possible — which is right?"
|
|
59
|
+
|
|
60
|
+
### Update CONTEXT.md inline
|
|
61
|
+
|
|
62
|
+
When a term is resolved, update `CONTEXT.md` right there. Don't batch these up — capture them as they happen. Use the format in [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md).
|
|
63
|
+
|
|
64
|
+
`CONTEXT.md` should be totally devoid of implementation details. Do not treat `CONTEXT.md` as a spec, a scratch pad, or a repository for implementation decisions. It is a glossary and nothing else.
|
|
65
|
+
|
|
66
|
+
### Offer ADRs sparingly
|
|
67
|
+
|
|
68
|
+
Only offer to create an ADR when all three are true:
|
|
69
|
+
|
|
70
|
+
1. **Hard to reverse** — the cost of changing your mind later is meaningful
|
|
71
|
+
2. **Surprising without context** — a future reader will wonder "why did they do it this way?"
|
|
72
|
+
3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons
|
|
73
|
+
|
|
74
|
+
If any of the three is missing, skip the ADR. Use the format in [ADR-FORMAT.md](./ADR-FORMAT.md).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grilling
|
|
3
|
+
description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Interview me relentlessly about every aspect of this until we reach a shared understanding. Walk down each branch of the decision tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.
|
|
7
|
+
|
|
8
|
+
Ask the questions one at a time, waiting for feedback on each question before continuing. Asking multiple questions at once is bewildering.
|
|
9
|
+
|
|
10
|
+
If a *fact* can be found by exploring the environment (filesystem, tools, etc.), look it up rather than asking me. The *decisions*, though, are mine — put each one to me and wait for my answer.
|
|
11
|
+
|
|
12
|
+
Do not act on it until I confirm we have reached a shared understanding.
|