@g3nomaly/g3n-skills 0.0.0-stage → 0.1.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-plugin/marketplace.json +92 -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/analyze/SKILL.md +32 -0
- package/skills/coding/analyze/agents/openai.yaml +5 -0
- package/skills/coding/analyze/references/api.md +27 -0
- package/skills/coding/analyze/references/commands.md +54 -0
- package/skills/coding/analyze/references/repository.md +13 -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 +56 -0
- package/skills/coding/document/agents/openai.yaml +5 -0
- package/skills/coding/document/references/typescript.md +131 -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 +25 -0
- package/skills/task-manager/decisions/src/read.ts +70 -0
- package/skills/task-manager/decisions/src/write.ts +88 -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 +49 -0
- package/skills/task-manager/task-manager/hooks/get-entry.ts +29 -0
- package/skills/task-manager/task-manager/hooks/guard-tree.ts +114 -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 +51 -0
- package/skills/task-manager/task-manager/src/filetree/entries.ts +77 -0
- package/skills/task-manager/task-manager/src/filetree/frontmatter.ts +74 -0
- package/skills/task-manager/task-manager/src/filetree/generate.ts +101 -0
- package/skills/task-manager/task-manager/src/filetree/index.ts +36 -0
- package/skills/task-manager/task-manager/src/filetree/levels.ts +55 -0
- package/skills/task-manager/task-manager/src/filetree/locate.ts +150 -0
- package/skills/task-manager/task-manager/src/filetree/paths.ts +70 -0
- package/skills/task-manager/task-manager/src/filetree/read.ts +62 -0
- package/skills/task-manager/task-manager/src/filetree/remove.ts +22 -0
- package/skills/task-manager/task-manager/src/filetree/root.ts +29 -0
- package/skills/task-manager/task-manager/src/filetree/status.ts +98 -0
- package/skills/task-manager/task-manager/src/hooks/cli.ts +115 -0
- package/skills/task-manager/task-manager/src/hooks/index.ts +3 -0
- package/skills/task-manager/task-manager/src/schemas/config.ts +23 -0
- package/skills/task-manager/task-manager/src/schemas/decision.ts +39 -0
- package/skills/task-manager/task-manager/src/schemas/index.ts +42 -0
- package/skills/task-manager/task-manager/src/schemas/phase.ts +27 -0
- package/skills/task-manager/task-manager/src/schemas/plan.ts +26 -0
- package/skills/task-manager/task-manager/src/schemas/primitives.ts +44 -0
- package/skills/task-manager/task-manager/src/schemas/task.ts +31 -0
- package/skills/task-manager/task-manager/src/schemas/term.ts +38 -0
- package/skills/task-manager/task-manager/src/schemas/validation.ts +78 -0
- package/skills/task-manager/task-manager/src/vocabulary/file.ts +131 -0
- package/skills/task-manager/task-manager/src/vocabulary/index.ts +5 -0
- package/skills/task-manager/task-manager/src/vocabulary/match.ts +74 -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 +72 -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 +66 -0
- package/skills/workflow/run/src/phase.ts +50 -0
- package/skills/workflow/run/src/steps.ts +43 -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,92 @@
|
|
|
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, and query a repository with analyze.",
|
|
20
|
+
"skills": [
|
|
21
|
+
"./code",
|
|
22
|
+
"./document",
|
|
23
|
+
"./analyze"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "grilling",
|
|
28
|
+
"source": "./skills/grilling",
|
|
29
|
+
"description": "Relentless interviews that stress-test a plan, plus the domain model they feed.",
|
|
30
|
+
"skills": [
|
|
31
|
+
"./grilling",
|
|
32
|
+
"./grill-me",
|
|
33
|
+
"./grill-with-docs",
|
|
34
|
+
"./domain-modeling"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "speech",
|
|
39
|
+
"source": "./skills/speech",
|
|
40
|
+
"description": "Conventions for how an agent writes — emphasis markup and cutting AI tells.",
|
|
41
|
+
"skills": [
|
|
42
|
+
"./emphasise",
|
|
43
|
+
"./unslop"
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "task-manager",
|
|
48
|
+
"source": "./skills/task-manager",
|
|
49
|
+
"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.",
|
|
50
|
+
"skills": [
|
|
51
|
+
"./task-manager",
|
|
52
|
+
"./vocabulary",
|
|
53
|
+
"./decisions"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "using-hooks",
|
|
58
|
+
"source": "./skills/using-hooks",
|
|
59
|
+
"description": "How to write each Claude Code lifecycle hook.",
|
|
60
|
+
"skills": [
|
|
61
|
+
"./hook-pre-tool-use",
|
|
62
|
+
"./hook-post-tool-use",
|
|
63
|
+
"./hook-stop",
|
|
64
|
+
"./hook-user-prompt-submit"
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "workflow",
|
|
69
|
+
"source": "./skills/workflow",
|
|
70
|
+
"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.",
|
|
71
|
+
"skills": [
|
|
72
|
+
"./run",
|
|
73
|
+
"./plan",
|
|
74
|
+
"./execute",
|
|
75
|
+
"./review",
|
|
76
|
+
"./sync",
|
|
77
|
+
"./orchestrator",
|
|
78
|
+
"./worktree"
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "writing",
|
|
83
|
+
"source": "./skills/writing",
|
|
84
|
+
"description": "How to write skills, hooks and tasks that an agent can follow.",
|
|
85
|
+
"skills": [
|
|
86
|
+
"./writing-great-hooks",
|
|
87
|
+
"./writing-great-skills",
|
|
88
|
+
"./writing-great-tasks"
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|
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.1",
|
|
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,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: analyze
|
|
3
|
+
description: Query and update the linked model of a repository with g3n-analyze: find code, docs, skills, decisions and tasks, see what uses or links to what, and rebuild the documentation site in analyze_out/. Use when asked where something is, what uses a type or function, what a decision affects, or to run g3n-analyze or regenerate the docs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`g3n-analyze` scans a repository into one model of **nodes** and **edges**, and answers queries on it. Run it from the repository root as `bunx @g3nomaly/analyze <command>`; in the g3n monorepo, `bun packages/analyze/dist/cli.js <command>` after `bun run build` in `packages/analyze`.
|
|
7
|
+
|
|
8
|
+
## Query
|
|
9
|
+
|
|
10
|
+
1. **Find** the node: `search <words>`. It matches names first, then meaning. Done when a hit's `id` names what you want.
|
|
11
|
+
2. **Read** it: `show <id>`. Text, signature, parameters, fields and every edge.
|
|
12
|
+
3. **Follow** its edges: `refs <id>`. Add `--incoming` for what uses it, `--outgoing` for what it uses, `--edge <kind>` to keep one kind, such as `type` or `affects`.
|
|
13
|
+
4. **Narrow** any of these with `--kind`, `--section` and `-n`. `list --kind <kind>` lists every node of a kind.
|
|
14
|
+
|
|
15
|
+
Add `--json` when a script reads the output. A `<node>` may be an `id`, a file path or a name; a name that fits several nodes prints the candidates.
|
|
16
|
+
|
|
17
|
+
A _member_, a parameter, field, operation or definition, is found by search but returns its _owner_: the function, the type or the file. Its exact `id` opens the member itself.
|
|
18
|
+
|
|
19
|
+
Flags, kinds and edge kinds: [`references/commands.md`](references/commands.md).
|
|
20
|
+
|
|
21
|
+
## Update
|
|
22
|
+
|
|
23
|
+
- **Queries rescan by themselves.** The scan is cached in `analyze_out/cache/` and redone when a file changes. `--no-cache` forces it.
|
|
24
|
+
- **Rebuild the site** with `create_docs`. It writes `analyze_out/index.html` and nothing else.
|
|
25
|
+
- **Change what is scanned** in `.analyzeignore` at the root, written with the defaults on the first run. `--exclude <glob>` skips more for one run.
|
|
26
|
+
- **Never edit `analyze_out/`.** It is output.
|
|
27
|
+
|
|
28
|
+
What makes a repository show more, such as glossaries, decisions and doc tags: [`references/repository.md`](references/repository.md).
|
|
29
|
+
|
|
30
|
+
## From code
|
|
31
|
+
|
|
32
|
+
Hooks and scripts call the same queries as a typed library, without the CLI: [`references/api.md`](references/api.md).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Library
|
|
2
|
+
|
|
3
|
+
`@g3nomaly/analyze` exports the queries as functions. They take the CLI options as fields, never print, and throw `OptionsError`, `QueryError` or `SourceError`.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { createDocs, list, refs, search, show } from '@g3nomaly/analyze';
|
|
7
|
+
|
|
8
|
+
const repo = '/home/me/app';
|
|
9
|
+
const { hits } = await search({ repo, query: 'route price', limit: 5 });
|
|
10
|
+
const node = await show({ repo, target: hits[0].id });
|
|
11
|
+
const users = await refs({ repo, target: 'choose_route', incoming: true, edges: ['type'] });
|
|
12
|
+
const tasks = await list({ repo, kinds: ['task'] });
|
|
13
|
+
await createDocs({ repo });
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
| Field | Functions | CLI flag |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `repo`, `skillDirs`, `docDirs`, `excludes`, `embeddings` | all | `--repo`, `--skills`, `--docs`, `--exclude`, `--no-embeddings` |
|
|
19
|
+
| `from`, `cache` | queries | `--from`, `--no-cache` |
|
|
20
|
+
| `kinds`, `section` | queries | `--kind`, `--section` |
|
|
21
|
+
| `query`, `by`, `limit` | `search` | `<query>`, `--by`, `-n` |
|
|
22
|
+
| `target` | `show`, `refs` | `<node>` |
|
|
23
|
+
| `incoming`, `outgoing`, `edges` | `refs` | `--incoming`, `--outgoing`, `--edge` |
|
|
24
|
+
| `title` | `createDocs` | `--title` |
|
|
25
|
+
| `onWarning` | all | — |
|
|
26
|
+
|
|
27
|
+
Warnings go to `onWarning` and are dropped without it.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Commands
|
|
2
|
+
|
|
3
|
+
| Command | Does |
|
|
4
|
+
|---|---|
|
|
5
|
+
| `create_docs` | Writes `analyze_out/index.html`, one offline HTML file |
|
|
6
|
+
| `search <query>` | Finds nodes by words and by meaning |
|
|
7
|
+
| `show <node>` | Prints one node in full |
|
|
8
|
+
| `refs <node>` | Lists its edges, both ways |
|
|
9
|
+
| `list` | Lists nodes in display order |
|
|
10
|
+
|
|
11
|
+
## Flags
|
|
12
|
+
|
|
13
|
+
| Flag | Commands | Does |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| `--repo <dir>` | all | Repository to read. Default: the working directory |
|
|
16
|
+
| `--skills <dir>`, `--docs <dir>` | all | Read skills or docs from this directory only. Repeatable |
|
|
17
|
+
| `--exclude <glob>` | all | Skip matching paths. Repeatable |
|
|
18
|
+
| `--no-embeddings` | all | No search by meaning |
|
|
19
|
+
| `--title <text>` | `create_docs` | Site title |
|
|
20
|
+
| `--from <file>` | queries | Query a built `index.html` instead of scanning |
|
|
21
|
+
| `--no-cache` | queries | Scan again even when nothing changed |
|
|
22
|
+
| `--json` | queries | JSON instead of text |
|
|
23
|
+
| `--kind <kind>` | queries | Only this kind. Repeatable |
|
|
24
|
+
| `--section <name>` | queries | `skills`, `docs`, `code`, `database` or `tasks` |
|
|
25
|
+
| `-n, --limit <n>` | `search`, `list` | Most results |
|
|
26
|
+
| `--by <way>` | `search` | `name`, `meaning` or `both` |
|
|
27
|
+
| `--incoming`, `--outgoing` | `refs` | One direction only |
|
|
28
|
+
| `--edge <kind>` | `refs` | Only this edge kind. Repeatable |
|
|
29
|
+
|
|
30
|
+
Each flag has an `ANALYZE_*` variable, such as `ANALYZE_REPO`. A flag wins over its variable.
|
|
31
|
+
|
|
32
|
+
## Kinds
|
|
33
|
+
|
|
34
|
+
- **Structure**: `folder`, `package`, `file`
|
|
35
|
+
- **Code**: `namespace`, `class`, `interface`, `struct`, `enum`, `trait`, `type`, `function` (methods included)
|
|
36
|
+
- **Docs and data**: `term`, `decision`, `table`, `query`
|
|
37
|
+
- **Tasks**: `plan`, `phase`, `task`
|
|
38
|
+
- **Members**, returned as their owner: `operation`, `definition`, `parameter`, `field`
|
|
39
|
+
|
|
40
|
+
The JSON of a node has its `kind` and its `type`, the finer sort, such as `method` or `api`.
|
|
41
|
+
|
|
42
|
+
## Edge kinds
|
|
43
|
+
|
|
44
|
+
| Edge | From → to |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `type` | parameter or field → its type |
|
|
47
|
+
| `returns`, `throws` | function → type it returns or throws |
|
|
48
|
+
| `extends` | type → type it extends or implements |
|
|
49
|
+
| `mentions` | page or description → node it links to |
|
|
50
|
+
| `uses` | text → glossary term |
|
|
51
|
+
| `affects` | decision → node it is about |
|
|
52
|
+
| `references` | table → table of its foreign key |
|
|
53
|
+
| `reads`, `writes` | query → table |
|
|
54
|
+
| `names`, `depends` | plan, phase or task → node it names, task it waits for |
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# What analyze reads
|
|
2
|
+
|
|
3
|
+
| Shows as | Write |
|
|
4
|
+
|---|---|
|
|
5
|
+
| **Skill** | A `SKILL.md` inside an AI directory: `.claude`, `.codex`, `.cursor`, `.gemini`, `.agents`, `.windsurf`, `.opencode`. Elsewhere it is a doc |
|
|
6
|
+
| **Package** | A directory with a manifest: `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `pom.xml`, `build.gradle`, `composer.json`, `.csproj`, `.gemspec`, `Gemfile`. A declared executable makes it an app |
|
|
7
|
+
| **Glossary** | A `glossary.md`. Each term is a node, and its first use in any text links to it |
|
|
8
|
+
| **Decisions** | A `decisions.md`. Each decision is a node; a link or inline code in it that names a node becomes an `affects` edge |
|
|
9
|
+
| **Code docs** | Doc comments. `@param`, `@returns`, `@throws` and `@property` attach to the parameter, return value, error and field |
|
|
10
|
+
| **Database** | `.sql` files. One with `CREATE TABLE` is a schema, any other a query |
|
|
11
|
+
| **Tasks** | The task-manager tree in `docs/task-manager`, or the directory `.g3n.config.json` names |
|
|
12
|
+
|
|
13
|
+
Inline code that names a type or function, such as `` `choose_route` ``, links to it from any text.
|
|
@@ -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,56 @@
|
|
|
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 _what_ code does and _how_. The _why_ goes in `decisions.md`.
|
|
8
|
+
|
|
9
|
+
These rules apply to existing docstrings too. **Rewrite docstrings that breaks them when applicable**, and never copy the style of one that does.
|
|
10
|
+
|
|
11
|
+
## Files
|
|
12
|
+
|
|
13
|
+
Line 1 of every file is a comment with its relative path. No file-level docstring.
|
|
14
|
+
|
|
15
|
+
## Docstrings
|
|
16
|
+
|
|
17
|
+
Functions, classes and other type declarations get a docstring; the language reference lists which. **A property, field or enum member is a tag in the docstring of its owner**, not a docstring of its own.
|
|
18
|
+
|
|
19
|
+
A _tag_ is a marked line in a docstring that documents one thing, such as `@param` in TypeScript.
|
|
20
|
+
|
|
21
|
+
**What a tag can say goes in the docstring, never in a code comment.** Any tag the language has is fine.
|
|
22
|
+
|
|
23
|
+
## Functions
|
|
24
|
+
|
|
25
|
+
The function its docstring is declarative of _what_ / _how_ it works. Use @brief to summarize the function in one line or two lines.
|
|
26
|
+
|
|
27
|
+
Tag a parameter or the return value when its name and type hide the meaning. Custom types are always tagged.
|
|
28
|
+
|
|
29
|
+
## Classes
|
|
30
|
+
|
|
31
|
+
A class docstring says:
|
|
32
|
+
|
|
33
|
+
- what it does and holds,
|
|
34
|
+
- which modules create and consume it,
|
|
35
|
+
- how to create one.
|
|
36
|
+
|
|
37
|
+
## Other types
|
|
38
|
+
|
|
39
|
+
The summary says what the type _holds_. Tag its properties under the same rule as function parameters.
|
|
40
|
+
|
|
41
|
+
## Comments
|
|
42
|
+
|
|
43
|
+
An inline comment explains how code works when neither the code nor a tag shows it. Use sparingly!
|
|
44
|
+
|
|
45
|
+
## Decisions
|
|
46
|
+
|
|
47
|
+
A decision is a choice **the user** made, with its _why_, never the _how_. A choice made while implementing is not one.
|
|
48
|
+
|
|
49
|
+
- **Never add an entry without the user's explicit approval.**
|
|
50
|
+
- Decisions are never written in the code.
|
|
51
|
+
|
|
52
|
+
## Languages
|
|
53
|
+
|
|
54
|
+
The syntax for each language:
|
|
55
|
+
|
|
56
|
+
- TypeScript: [`references/typescript.md`](references/typescript.md)
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# TypeScript
|
|
2
|
+
|
|
3
|
+
TSDoc: a `/** */` block directly above the declaration.
|
|
4
|
+
|
|
5
|
+
- **Declarations with a docstring**: functions, classes, interfaces, type aliases and enums.
|
|
6
|
+
- **Summary**: `/** Adds two numbers. */` on one line. A longer block opens with `@brief` and the summary.
|
|
7
|
+
- **Tags**: `@param name - text`, `@returns text`, and for the members of a class, interface, type or enum `@param name - text` or `@property name - text`. Any other TSDoc tag that fits is fine: `@throws {Type} When ...`, `@example`, `@see`, `@deprecated`.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
/** Adds two numbers. */
|
|
11
|
+
export function add(a: number, b: number): number {
|
|
12
|
+
return a + b;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @brief Retrieves a user by id.
|
|
17
|
+
*
|
|
18
|
+
* @param userId - Surrogate key from the `users` table, not the auth provider's id.
|
|
19
|
+
* @returns Custom User class used by the authentication service, or `undefined` when no row matches.
|
|
20
|
+
*/
|
|
21
|
+
export async function getUser(userId: number): Promise<User | undefined> {
|
|
22
|
+
// ...
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @brief Error for a file on disk that does not match its schema.
|
|
27
|
+
*
|
|
28
|
+
* Holds the path of the file and one issue per rejected field, and its message
|
|
29
|
+
* lists them all. Thrown by `parseFile` and by the readers in `filetree/`,
|
|
30
|
+
* `decisions/` and `vocabulary/` that check a file's layout by hand. Callers
|
|
31
|
+
* tell it apart from other errors with `instanceof FileValidationError`.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* throw new FileValidationError("/home/me/app/docs/task-manager/auth/auth.md", [
|
|
35
|
+
* { field: "status", message: 'is "done"' },
|
|
36
|
+
* ]);
|
|
37
|
+
*/
|
|
38
|
+
export class FileValidationError extends Error {
|
|
39
|
+
readonly file: string;
|
|
40
|
+
readonly issues: FileValidationIssue[];
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @brief Builds the message from the file path and every issue.
|
|
44
|
+
*
|
|
45
|
+
* @param file - Absolute path of the file that failed, e.g. `/home/me/app/docs/task-manager/auth/auth.md`.
|
|
46
|
+
* @param issues - Rejected fields, e.g. `{ field: "phases.0.status", message: "is required" }`.
|
|
47
|
+
*/
|
|
48
|
+
constructor(file: string, issues: FileValidationIssue[]) {
|
|
49
|
+
// ...
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @brief Entries a set of requests resolved to, and the requests that did not resolve.
|
|
55
|
+
*
|
|
56
|
+
* @property entries - Resolved entries by key, e.g. `emphasise`.
|
|
57
|
+
* @property unknown - Requests no source offers, e.g. `ghost@mine`.
|
|
58
|
+
* @property notes - Why an entry nobody named is in the set, e.g. `{ vocabulary: "dep of plan" }`.
|
|
59
|
+
*/
|
|
60
|
+
export interface Resolution {
|
|
61
|
+
entries: Map<string, SourceOffer>;
|
|
62
|
+
unknown: string[];
|
|
63
|
+
notes: Record<string, string>;
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Bad
|
|
68
|
+
|
|
69
|
+
Each one next to what is wrong with it. The examples above show the fix.
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
/** Holds the installed skills read from `skills.json`. */
|
|
73
|
+
export class SkillRegistry {}
|
|
74
|
+
```
|
|
75
|
+
Too thin. It leaves out what the class holds, who creates and consumes it, and how to make one.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
/** @param file - Path of the file that was read. */
|
|
79
|
+
constructor(file: string, issues: FileValidationIssue[])
|
|
80
|
+
```
|
|
81
|
+
`file` doesn't say absolute or relative. `issues` is missing, while its type hides what goes in it.
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
/**
|
|
85
|
+
* @param issues - One entry per rejected field. `field` is the dotted path
|
|
86
|
+
* as it reads in the file, such as `phases.0.status`, or `(whole file)`.
|
|
87
|
+
*/
|
|
88
|
+
```
|
|
89
|
+
Prose about the type. One example value shows it faster: `` e.g. `{ field: "phases.0.status", message: "is required" }` ``.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
/**
|
|
93
|
+
* Adds two numbers.
|
|
94
|
+
* @param a - The first number.
|
|
95
|
+
* @param b - The second number.
|
|
96
|
+
* @returns The sum.
|
|
97
|
+
*/
|
|
98
|
+
export function add(a: number, b: number): number
|
|
99
|
+
```
|
|
100
|
+
The tags repeat the signature. The summary line is enough.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
/** Entries one request names. */
|
|
104
|
+
function matchRequest(request: EntryRequest, offers: readonly SourceOffer[]): Match
|
|
105
|
+
```
|
|
106
|
+
A noun phrase that names the result, and no tags. The summary says what the function does: _Finds the entries one request names_. `EntryRequest`, `SourceOffer` and `Match` are custom types, so `request`, `offers` and the return value each need a tag.
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
/** Entries a set of requests resolved to. */
|
|
110
|
+
export interface Resolution {
|
|
111
|
+
/** Resolved entries by key. */
|
|
112
|
+
entries: Map<string, SourceOffer>;
|
|
113
|
+
/** Requests no source offers. */
|
|
114
|
+
unknown: string[];
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
A docstring on each property. Properties go in the interface's docstring as `@property` tags, as in `Resolution` above.
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
/**
|
|
121
|
+
* Resolves the dependencies of one entry against every offer.
|
|
122
|
+
*
|
|
123
|
+
* @param preferred - Source to take a key from when several offer it.
|
|
124
|
+
*/
|
|
125
|
+
```
|
|
126
|
+
More than one line without `@brief`. It opens with `@brief Resolves the dependencies...`.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
/** Loads a user by id. Uses a surrogate key because auth ids changed format in 2024. */
|
|
130
|
+
```
|
|
131
|
+
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.
|