@sayansr26/agent-os 0.5.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 +27 -0
- package/CHANGELOG.md +203 -0
- package/LICENSE +21 -0
- package/README.md +134 -0
- package/bin/agent-os.mjs +6 -0
- package/package.json +49 -0
- package/plugins/agent-os/.claude-plugin/plugin.json +18 -0
- package/plugins/agent-os/agents/architect.md +77 -0
- package/plugins/agent-os/agents/builder.md +90 -0
- package/plugins/agent-os/agents/documenter.md +87 -0
- package/plugins/agent-os/agents/feature-cartographer.md +142 -0
- package/plugins/agent-os/agents/orchestrator.md +96 -0
- package/plugins/agent-os/agents/reviewer.md +82 -0
- package/plugins/agent-os/agents/tester.md +83 -0
- package/plugins/agent-os/hooks/hooks.json +17 -0
- package/plugins/agent-os/hooks/session-resume.mjs +136 -0
- package/plugins/agent-os/skills/init/SKILL.md +134 -0
- package/plugins/agent-os/skills/init/references/changing-a-feature.md +104 -0
- package/plugins/agent-os/skills/init/references/establishing.md +128 -0
- package/plugins/agent-os/skills/init/references/git-permissions.md +118 -0
- package/plugins/agent-os/skills/init/references/migrating.md +43 -0
- package/plugins/agent-os/skills/init/references/writing-rules.md +50 -0
- package/plugins/agent-os/skills/init/scripts/audit.mjs +328 -0
- package/plugins/agent-os/skills/map/SKILL.md +67 -0
- package/plugins/agent-os/skills/memory/SKILL.md +82 -0
- package/plugins/agent-os/skills/memory/scripts/memory.mjs +97 -0
- package/src/cli.mjs +157 -0
- package/src/detect.mjs +54 -0
- package/src/selftest.mjs +71 -0
- package/src/source.mjs +102 -0
- package/src/targets.mjs +186 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: init
|
|
3
|
+
description: Set up or repair this project's Claude Code context layer. Audits what is already there — CLAUDE.md size, whether .claude/rules/ files are path-scoped, dangling hooks, legacy memory-bank or serena stores, auto-memory state, and machine-level problems like user-scope agents shadowing plugin ones — then creates or migrates what is missing. Use for "set up agent-os", "agent-os init", "initialise this project", "bootstrap my context setup", "migrate off memory-bank", "my CLAUDE.md is too big", or when starting work in a repo with no setup.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Memory bootstrap
|
|
7
|
+
|
|
8
|
+
Bring any repository up to the standard context layout, without inventing facts
|
|
9
|
+
and without ballooning what loads every session.
|
|
10
|
+
|
|
11
|
+
The layout this skill converges on:
|
|
12
|
+
|
|
13
|
+
| Tier | Lives in | Startup cost | Holds |
|
|
14
|
+
|---|---|---|---|
|
|
15
|
+
| Always-loaded | `CLAUDE.md`, ≤200 lines | small, fixed | Only what is true in *every* session |
|
|
16
|
+
| On-demand | `.claude/rules/*.md` with `paths:` frontmatter | **zero** | Durable facts scoped to some files |
|
|
17
|
+
| Self-writing | auto memory (`~/.claude/projects/<repo>/memory/`) | index only | Corrections, preferences, decisions |
|
|
18
|
+
| Explored | `.claude/agent-memory/feature-cartographer/` | **zero** (subagent context) | How each feature is actually built |
|
|
19
|
+
| Task state | the project's own vault / handoff file | zero (read selectively) | What is in flight right now |
|
|
20
|
+
|
|
21
|
+
The principle the whole layout serves: **storing a fact and loading a fact are
|
|
22
|
+
different acts.** Anything that makes them the same act — a handbook CLAUDE.md,
|
|
23
|
+
a memory-bank read at every startup, a rules file with no `paths:` — is the bug.
|
|
24
|
+
|
|
25
|
+
## `$ARGUMENTS`
|
|
26
|
+
|
|
27
|
+
| Argument | Do |
|
|
28
|
+
|---|---|
|
|
29
|
+
| *(none)* | The full pass: audit, then route by MODE |
|
|
30
|
+
| `audit` | Run the audit and report. Change nothing. |
|
|
31
|
+
| `settings` | The settings and permissions pass only — read `~/.claude/settings.json` and the project's, report what is set, and propose changes. See below. |
|
|
32
|
+
|
|
33
|
+
Related skills: `/agent-os:map` builds the architecture map, `/agent-os:memory`
|
|
34
|
+
inspects and repairs what the project remembers.
|
|
35
|
+
|
|
36
|
+
## Step 1 — Run the audit
|
|
37
|
+
|
|
38
|
+
One call. Do not rediscover this with a dozen Read and Grep round trips — the
|
|
39
|
+
checks are deterministic and the script does all of them at once:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
node "${CLAUDE_PLUGIN_ROOT}/skills/init/scripts/audit.mjs"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Pass a path as the first argument to audit a project other than the working
|
|
46
|
+
directory. It is read-only and exits 0 even when checks fail, so a partial audit
|
|
47
|
+
still reaches you.
|
|
48
|
+
|
|
49
|
+
It reports: always-loaded files and their line counts, whether every
|
|
50
|
+
`.claude/rules/` file is path-scoped, whether each hook's target exists, legacy
|
|
51
|
+
stores (`memory-bank/`, `.serena/memories/`, cursor and windsurf rules, memory-ish
|
|
52
|
+
MCP servers), per-agent memory health, the machine layer (`~/.claude` CLAUDE.md,
|
|
53
|
+
shadowing agents or skills, a duplicate session-resume hook, permissions
|
|
54
|
+
posture), the startup byte and token cost, and a ranked finding list.
|
|
55
|
+
|
|
56
|
+
**Show the output to the user before you change anything.** Do not restructure a
|
|
57
|
+
repo you have only just opened.
|
|
58
|
+
|
|
59
|
+
## Step 2 — Route by MODE
|
|
60
|
+
|
|
61
|
+
The audit ends with a `MODE` line. It decides what this run is for:
|
|
62
|
+
|
|
63
|
+
| MODE | What it means | Do |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| `TOO-EARLY` | Barely any source | **Build nothing.** Tell the user to write code, run Claude Code's `/init`, and come back. A layer over an empty project is invented conventions. |
|
|
66
|
+
| `ESTABLISH` | Real code, no context layer | `references/establishing.md` — build the layer *from the code* |
|
|
67
|
+
| `MAP` | Layer healthy, never mapped | `references/establishing.md`, "Map the architecture" |
|
|
68
|
+
| `MIGRATE` | Layer exists, has problems | fix the findings; `references/migrating.md` for legacy stores |
|
|
69
|
+
| `MAINTAIN` | Healthy and mapped | report and stop |
|
|
70
|
+
|
|
71
|
+
`ESTABLISH` and `MAP` are the modes that make a later request like *"change the
|
|
72
|
+
login flow from email to OTP"* execute from known structure instead of
|
|
73
|
+
rediscovering the codebase. `references/changing-a-feature.md` is that workflow —
|
|
74
|
+
point the user at it once the layer exists.
|
|
75
|
+
|
|
76
|
+
## Step 3 — Act on the findings
|
|
77
|
+
|
|
78
|
+
Each finding routes to one place. Load only what the audit actually surfaced:
|
|
79
|
+
|
|
80
|
+
| Finding | Read |
|
|
81
|
+
|---|---|
|
|
82
|
+
| `MODE ESTABLISH` or `MODE MAP` | `references/establishing.md` |
|
|
83
|
+
| user asks how to change an existing feature | `references/changing-a-feature.md` |
|
|
84
|
+
| legacy store found; CLAUDE.md over budget | `references/migrating.md` |
|
|
85
|
+
| rule without `paths:`; no rules layer yet; CLAUDE.md to trim | `references/writing-rules.md` |
|
|
86
|
+
| `defaultMode` auto-approves with an empty `deny` | `references/git-permissions.md` |
|
|
87
|
+
| LSP plugin recommended; checked-in generated dirs | `references/establishing.md`, "Stop Claude reading what it should not" |
|
|
88
|
+
| hook target missing | delete the hook entry, or restore the script — say which |
|
|
89
|
+
| shadowing agent or skill in `~/.claude` or `.claude/agents/` | the user removes the standalone copy; a plugin cannot |
|
|
90
|
+
| unindexed or near-duplicate agent memory topic files | merge into the best-named file, delete the rest, rebuild `MEMORY.md` as one line per file |
|
|
91
|
+
| project CLAUDE.md refers to a `~/.claude/CLAUDE.md` that is absent | the user creates it or drops the reference |
|
|
92
|
+
|
|
93
|
+
Findings on the machine layer are the user's to fix — a plugin cannot write
|
|
94
|
+
`~/.claude`. Hand over the exact change rather than attempting it.
|
|
95
|
+
|
|
96
|
+
## Step 4 — Verify by re-running
|
|
97
|
+
|
|
98
|
+
Run the audit again and show the before and after: finding count, startup bytes,
|
|
99
|
+
token estimate. Do not declare success on vibes — the script already produces the
|
|
100
|
+
numbers, so quote them.
|
|
101
|
+
|
|
102
|
+
## The settings pass
|
|
103
|
+
|
|
104
|
+
The audit already reads both settings files and reports `defaultMode`, the deny
|
|
105
|
+
list, hook registrations and shadowing. To act on it:
|
|
106
|
+
|
|
107
|
+
1. **Show what is set** — project `.claude/settings.json` and `~/.claude/settings.json`,
|
|
108
|
+
side by side, so the user can see which rules exist only in this project and
|
|
109
|
+
therefore vanish in every other one.
|
|
110
|
+
2. **Propose, do not apply.** Write out the exact JSON block and ask. This is the
|
|
111
|
+
one place where acting first is wrong: `permissions.deny` is the guardrail on
|
|
112
|
+
your own behaviour, and a skill that edits its own guardrails without being
|
|
113
|
+
asked is exactly the thing the setting exists to prevent. Apply only after an
|
|
114
|
+
explicit yes, and never widen an existing deny list without pointing out what
|
|
115
|
+
it would stop blocking.
|
|
116
|
+
3. **What to propose**, when the audit flagged it:
|
|
117
|
+
- git write protection — `references/git-permissions.md` has the rule set
|
|
118
|
+
- `Read` deny rules for checked-in generated or vendored paths
|
|
119
|
+
- a code intelligence plugin for the detected language
|
|
120
|
+
- `claudeMdExcludes` in a monorepo where other teams' files load
|
|
121
|
+
|
|
122
|
+
Anything under `~/.claude/` affects every project on the machine. Say so before
|
|
123
|
+
proposing it, and prefer the project's own settings file when the rule is really
|
|
124
|
+
about this project.
|
|
125
|
+
|
|
126
|
+
## What this skill will not do
|
|
127
|
+
|
|
128
|
+
- It will not write facts it has not verified in the repo. An invented rule is
|
|
129
|
+
worse than a missing one, because it will be trusted.
|
|
130
|
+
- It will not delete a legacy store before its content has landed.
|
|
131
|
+
- It will not add a memory MCP server. A knowledge graph solves retrieval over
|
|
132
|
+
unstructured memory; the common failure is that nothing was *written*, which a
|
|
133
|
+
graph does not fix and which the cartographer's memory does — with no database,
|
|
134
|
+
no embedding step, and no tokens in the main window.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Changing an existing feature
|
|
2
|
+
|
|
3
|
+
The workflow for a request like *"change the login flow from email to OTP"*, or
|
|
4
|
+
any change to code that already exists.
|
|
5
|
+
|
|
6
|
+
The point is that **no step re-reads the codebase from scratch**. Structure comes
|
|
7
|
+
from the map, conventions come from the rules, and only the files actually being
|
|
8
|
+
changed get opened.
|
|
9
|
+
|
|
10
|
+
## Do not start by reading code
|
|
11
|
+
|
|
12
|
+
The instinct is to grep for `login` and start opening files. That costs a lot of
|
|
13
|
+
context, finds the obvious call sites and misses the non-obvious ones, and
|
|
14
|
+
produces a change written in the model's default style rather than this
|
|
15
|
+
codebase's.
|
|
16
|
+
|
|
17
|
+
## Step 1 — Ask the cartographer how it is built
|
|
18
|
+
|
|
19
|
+
> use the feature-cartographer: how is the login flow currently implemented?
|
|
20
|
+
|
|
21
|
+
It reads `_architecture.md` and any existing map first, explores only what is
|
|
22
|
+
missing, and returns about forty lines in **its** context, not yours:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Entry: src/features/auth/LoginPage.tsx:24 (route /login)
|
|
26
|
+
Renders: LoginForm.tsx, OtpDialog.tsx (already exists — used by password reset)
|
|
27
|
+
State: authSlice — also read by the session provider
|
|
28
|
+
Network: services/auth.api.ts -> POST /auth/login, POST /auth/refresh
|
|
29
|
+
Gated by: nothing; /login is public
|
|
30
|
+
|
|
31
|
+
Blast radius
|
|
32
|
+
- useAuth() — imported by 14 files outside this feature
|
|
33
|
+
- authSlice.login — dispatched from 3 places
|
|
34
|
+
|
|
35
|
+
To change the login method, edit: services/auth.api.ts, LoginPage.tsx, authSlice.ts
|
|
36
|
+
Watch out
|
|
37
|
+
- OtpDialog already exists for password reset; reuse it rather than writing one
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
That last line is the whole argument for this step. A cold grep for `login` would
|
|
41
|
+
not have found the OTP dialog that already exists — and you would have built a
|
|
42
|
+
second one.
|
|
43
|
+
|
|
44
|
+
## Step 2 — Find the nearest precedent
|
|
45
|
+
|
|
46
|
+
Before designing anything, ask what this codebase already did that resembles the
|
|
47
|
+
change. An OTP flow somewhere else, a second auth method, a similar
|
|
48
|
+
service-and-slice pair. The cartographer's map will usually name it.
|
|
49
|
+
|
|
50
|
+
Matching an existing precedent is almost always better than a cleaner design that
|
|
51
|
+
matches nothing else in the repository.
|
|
52
|
+
|
|
53
|
+
## Step 3 — Let the rules load themselves
|
|
54
|
+
|
|
55
|
+
The path-scoped rules under `.claude/rules/` load when a matching file is
|
|
56
|
+
touched. Touching `src/features/auth/` brings in the feature rules; touching a
|
|
57
|
+
service brings in the service conventions. You do not need to fetch them, and you
|
|
58
|
+
should not paste them into the prompt.
|
|
59
|
+
|
|
60
|
+
If the rules layer does not exist yet, stop and read `establishing.md`. Making a
|
|
61
|
+
structural change to a codebase whose conventions are not written down means
|
|
62
|
+
inventing them in the diff.
|
|
63
|
+
|
|
64
|
+
## Step 4 — Build against the precedent
|
|
65
|
+
|
|
66
|
+
Dispatch `builder` with the cartographer's output, the precedent, and the files
|
|
67
|
+
to change — not with the original one-line request. An agent that receives
|
|
68
|
+
"change login to OTP" starts from nothing; one that receives the map, the
|
|
69
|
+
precedent and the file list starts where step 1 finished.
|
|
70
|
+
|
|
71
|
+
`builder` reads `CLAUDE.md` and the matching rules before writing, and matches the
|
|
72
|
+
nearest existing example for anything the rules do not cover.
|
|
73
|
+
|
|
74
|
+
## Step 5 — Review against the rules, not against taste
|
|
75
|
+
|
|
76
|
+
`reviewer` checks the diff against this project's documented rules first, then
|
|
77
|
+
correctness, security and the seams. A violation of a written project rule is the
|
|
78
|
+
highest-severity finding available, because the project already decided.
|
|
79
|
+
|
|
80
|
+
## Step 6 — Update the map, in the same turn
|
|
81
|
+
|
|
82
|
+
**The map is now stale.** The login flow no longer works the way its topic file
|
|
83
|
+
says it does.
|
|
84
|
+
|
|
85
|
+
Re-dispatch the cartographer to update the topic file for the area you changed,
|
|
86
|
+
or the change silently poisons the next question about it. A map that was right
|
|
87
|
+
last week and is wrong today is worse than no map, because it will be trusted.
|
|
88
|
+
|
|
89
|
+
This is the step that gets skipped. Treat it as part of the change, not as
|
|
90
|
+
follow-up work.
|
|
91
|
+
|
|
92
|
+
## What this costs
|
|
93
|
+
|
|
94
|
+
Roughly, for a feature change in a large codebase:
|
|
95
|
+
|
|
96
|
+
| | Cold | With the map |
|
|
97
|
+
|---|---|---|
|
|
98
|
+
| Finding how it works | 15–30 file reads in your context | ~40 lines returned from a subagent |
|
|
99
|
+
| Finding the conventions | re-derived, inconsistently | loaded automatically by path |
|
|
100
|
+
| Finding the precedent | usually missed | named in the map |
|
|
101
|
+
| Second change to the same area | the same cost again | near zero |
|
|
102
|
+
|
|
103
|
+
The first question about an area is cheaper. Every question after it is close to
|
|
104
|
+
free. That is the point of writing the map down.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Establishing a context layer from an existing codebase
|
|
2
|
+
|
|
3
|
+
Read this when the audit reports `MODE ESTABLISH` or `MODE MAP`: there is real
|
|
4
|
+
code but no context layer, or a layer but no architecture map.
|
|
5
|
+
|
|
6
|
+
The goal is not a smaller `CLAUDE.md`. The goal is that a request like *"change
|
|
7
|
+
the login flow from email to OTP"* can be executed from **known structure and
|
|
8
|
+
known conventions**, instead of rediscovering the codebase from scratch every
|
|
9
|
+
time. Smaller context is a consequence, not the objective.
|
|
10
|
+
|
|
11
|
+
## The one rule
|
|
12
|
+
|
|
13
|
+
**Everything you write must be something you observed in this repository.** Not
|
|
14
|
+
something you know about React, or Django, or how projects like this usually
|
|
15
|
+
work. If you did not open the file, it does not go in.
|
|
16
|
+
|
|
17
|
+
An invented convention is worse than a missing one, because the next agent will
|
|
18
|
+
follow it and the reviewer will enforce it.
|
|
19
|
+
|
|
20
|
+
## Step 1 — Let Claude Code write the first draft
|
|
21
|
+
|
|
22
|
+
Do not hand-write `CLAUDE.md` from nothing. Claude Code's own `/init` explores
|
|
23
|
+
the codebase and generates a starting file; `/doctor` trims a checked-in one and
|
|
24
|
+
migrates guidance out of it. Use those first, then build on the result.
|
|
25
|
+
|
|
26
|
+
Tell the user to run `/init` if no `CLAUDE.md` exists, and take what it produces
|
|
27
|
+
as the starting point. `agent-os` adds the layers `/init` does not: the
|
|
28
|
+
architecture map, conventions extracted from real code, and path-scoped rules.
|
|
29
|
+
|
|
30
|
+
## Step 2 — Map the architecture
|
|
31
|
+
|
|
32
|
+
Dispatch `feature-cartographer` with an explicit system-level brief, not a
|
|
33
|
+
feature question:
|
|
34
|
+
|
|
35
|
+
> Map this codebase at the system level. Produce `_architecture.md`: the stack
|
|
36
|
+
> and versions, the layers and what each owns, where a request enters and how it
|
|
37
|
+
> reaches data, the state management, the network edge, the auth and permission
|
|
38
|
+
> model, the build and run commands, and the three or four files a newcomer must
|
|
39
|
+
> read first. Name real files. Say what you could not determine.
|
|
40
|
+
|
|
41
|
+
It writes `_architecture.md` into its own memory and indexes it in `MEMORY.md`.
|
|
42
|
+
That file becomes the starting point for every later "how is X built" question —
|
|
43
|
+
the cartographer reads it before exploring, so the second question about any area
|
|
44
|
+
is cheap and the first is cheaper than cold.
|
|
45
|
+
|
|
46
|
+
Re-dispatch this when the architecture actually changes, not on a schedule.
|
|
47
|
+
|
|
48
|
+
## Step 3 — Extract conventions from real code
|
|
49
|
+
|
|
50
|
+
This is the part that makes a change follow the existing style rather than the
|
|
51
|
+
model's defaults. For each kind of thing the codebase contains — a service, a
|
|
52
|
+
component, a route, a migration, a test — do this:
|
|
53
|
+
|
|
54
|
+
1. **Find at least three independent examples.** Glob for the shape, pick three
|
|
55
|
+
written at different times if you can tell.
|
|
56
|
+
2. **Read them.** Not outlines. The convention lives in the details: how errors
|
|
57
|
+
are handled, where validation sits, what gets logged, how state is reached,
|
|
58
|
+
how the network is called, what the file is named and where it lives.
|
|
59
|
+
3. **Write down only what is consistent across all three.** One file is a sample.
|
|
60
|
+
Two is a coincidence. Three that agree is a convention.
|
|
61
|
+
4. **Note what varies.** If two services handle errors differently, that is not a
|
|
62
|
+
convention — it is drift. Say so; do not pick a winner on the codebase's
|
|
63
|
+
behalf.
|
|
64
|
+
5. **Record where you saw it.** Name the files the pattern came from. A future
|
|
65
|
+
reader can re-check a cited rule; an uncited one rots.
|
|
66
|
+
|
|
67
|
+
The highest-value things to capture are the ones a newcomer gets wrong:
|
|
68
|
+
|
|
69
|
+
- **Registration sites.** Where does a new route, nav item, feature flag or
|
|
70
|
+
migration have to be registered, and is that where the docs say? Check.
|
|
71
|
+
- **The seam.** How does this codebase talk to its backend, and what wraps it?
|
|
72
|
+
- **The gate.** How is a feature permitted — role, flag, config, middleware?
|
|
73
|
+
- **The thing that looks optional but is not.** A required call in every handler,
|
|
74
|
+
an index that must be added, a twin file that must be updated together.
|
|
75
|
+
|
|
76
|
+
## Step 4 — Write the rules
|
|
77
|
+
|
|
78
|
+
Group by **what the reader is touching**, not by topic. Each file gets `paths:`
|
|
79
|
+
frontmatter narrow enough that it is absent most of the time.
|
|
80
|
+
|
|
81
|
+
```markdown
|
|
82
|
+
---
|
|
83
|
+
paths:
|
|
84
|
+
- "src/features/**"
|
|
85
|
+
- "src/pages/**"
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
# Working inside a feature
|
|
89
|
+
|
|
90
|
+
Services export one function per endpoint and go through the shared client
|
|
91
|
+
wrapper, never a bare fetch. Errors surface as a typed result, not a throw.
|
|
92
|
+
Verified across three services; see the ones named in `_architecture.md`.
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Dense agent notes, not prose. Invariants and gotchas. Skip anything a `ls` or a
|
|
96
|
+
grep answers — that is rule 2 in the README and it applies hardest here.
|
|
97
|
+
|
|
98
|
+
## Step 5 — Stop Claude reading what it should not
|
|
99
|
+
|
|
100
|
+
Two settings with a large effect on how much gets read, both worth proposing:
|
|
101
|
+
|
|
102
|
+
- **Code intelligence.** If the audit named an LSP plugin, install it:
|
|
103
|
+
`/plugin install typescript-lsp@claude-plugins-official` (or the one for your
|
|
104
|
+
language). Claude then jumps to a definition and finds references through the
|
|
105
|
+
language server instead of scanning the tree. For "where is login handled and
|
|
106
|
+
what calls it", this is the single biggest win available.
|
|
107
|
+
- **`Read` deny rules** for checked-in generated or vendored code:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{ "permissions": { "deny": [
|
|
111
|
+
"Read(./**/dist/**/*)", "Read(./**/generated/**/*)", "Read(./**/vendor/**/*)"
|
|
112
|
+
] } }
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`.gitignore`d paths are already excluded from search; these cover the ones that
|
|
116
|
+
are committed.
|
|
117
|
+
|
|
118
|
+
In a monorepo, also consider per-directory `CLAUDE.md` files so each package's
|
|
119
|
+
conventions load only when Claude reads there.
|
|
120
|
+
|
|
121
|
+
## Step 6 — Verify
|
|
122
|
+
|
|
123
|
+
Re-run the audit. `MODE` should move to `MAINTAIN`. Show the user the before and
|
|
124
|
+
after: finding count, startup bytes, and what got mapped.
|
|
125
|
+
|
|
126
|
+
Then prove it works on a real question. Ask the cartographer something you
|
|
127
|
+
already know the answer to, and check it. A map that is confidently wrong is
|
|
128
|
+
worse than no map, and this is the cheapest moment to find out.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Git permission rules — block writes, keep reads
|
|
2
|
+
|
|
3
|
+
A `permissions.deny` set that blocks every git command which changes the
|
|
4
|
+
repository, while leaving read-only inspection (`status`, `log`, `diff`, `show`,
|
|
5
|
+
`blame`, `rev-parse`, `ls-files`, `describe`, `grep`, `shortlog`, …) available.
|
|
6
|
+
|
|
7
|
+
Paste into `~/.claude/settings.json` for every project, or a project's
|
|
8
|
+
`.claude/settings.json` for one.
|
|
9
|
+
|
|
10
|
+
```json
|
|
11
|
+
{
|
|
12
|
+
"permissions": {
|
|
13
|
+
"deny": [
|
|
14
|
+
"Bash(git -C*)",
|
|
15
|
+
"Bash(git -c*)",
|
|
16
|
+
"Bash(git --git-dir*)",
|
|
17
|
+
"Bash(git --work-tree*)",
|
|
18
|
+
"Bash(git --exec-path*)",
|
|
19
|
+
|
|
20
|
+
"Bash(git add *)",
|
|
21
|
+
"Bash(git am *)",
|
|
22
|
+
"Bash(git apply *)",
|
|
23
|
+
"Bash(git bisect *)",
|
|
24
|
+
"Bash(git branch *)",
|
|
25
|
+
"Bash(git checkout *)",
|
|
26
|
+
"Bash(git cherry-pick *)",
|
|
27
|
+
"Bash(git clean *)",
|
|
28
|
+
"Bash(git clone *)",
|
|
29
|
+
"Bash(git commit *)",
|
|
30
|
+
"Bash(git config *)",
|
|
31
|
+
"Bash(git fast-import *)",
|
|
32
|
+
"Bash(git filter-branch *)",
|
|
33
|
+
"Bash(git gc *)",
|
|
34
|
+
"Bash(git init *)",
|
|
35
|
+
"Bash(git merge *)",
|
|
36
|
+
"Bash(git mv *)",
|
|
37
|
+
"Bash(git notes *)",
|
|
38
|
+
"Bash(git prune *)",
|
|
39
|
+
"Bash(git pull *)",
|
|
40
|
+
"Bash(git push *)",
|
|
41
|
+
"Bash(git rebase *)",
|
|
42
|
+
"Bash(git reflog *)",
|
|
43
|
+
"Bash(git remote *)",
|
|
44
|
+
"Bash(git repack *)",
|
|
45
|
+
"Bash(git replace *)",
|
|
46
|
+
"Bash(git reset *)",
|
|
47
|
+
"Bash(git restore *)",
|
|
48
|
+
"Bash(git revert *)",
|
|
49
|
+
"Bash(git rm *)",
|
|
50
|
+
"Bash(git stash *)",
|
|
51
|
+
"Bash(git submodule *)",
|
|
52
|
+
"Bash(git switch *)",
|
|
53
|
+
"Bash(git symbolic-ref *)",
|
|
54
|
+
"Bash(git tag *)",
|
|
55
|
+
"Bash(git update-ref *)",
|
|
56
|
+
"Bash(git worktree *)"
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Why the first five entries matter
|
|
63
|
+
|
|
64
|
+
Without them the rest of the list is decorative. Claude Code matches a Bash rule
|
|
65
|
+
literally on the words before the first `*`, so `Bash(git commit *)` does **not**
|
|
66
|
+
match any of these:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
git -C . commit -m "..."
|
|
70
|
+
git -c user.email=x@y commit -m "..."
|
|
71
|
+
git --git-dir=.git --work-tree=. commit -m "..."
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`git -C` and `git -c` run any subcommand with a different directory or config,
|
|
75
|
+
which walks straight past a per-subcommand list. Denying the flag forms outright
|
|
76
|
+
closes that. The cost is that `git -C <path> status` is blocked too — `cd` there
|
|
77
|
+
instead.
|
|
78
|
+
|
|
79
|
+
## What this does not stop
|
|
80
|
+
|
|
81
|
+
**Quoting.** `git 'commit' -m "..."` does not match `Bash(git commit *)` either,
|
|
82
|
+
and there is no pattern that enumerates every quoting variant. Treat this list as
|
|
83
|
+
a strong guardrail against an agent doing the wrong thing by default, not as a
|
|
84
|
+
boundary against one determined to get around it.
|
|
85
|
+
|
|
86
|
+
If you need a hard boundary, there are two options, and both cost you read-only
|
|
87
|
+
git:
|
|
88
|
+
|
|
89
|
+
- `"deny": ["Bash(git:*)"]` — one rule, matches every invocation including the
|
|
90
|
+
flag and quoted forms.
|
|
91
|
+
- A `PreToolUse` hook that parses the command itself and exits non-zero.
|
|
92
|
+
|
|
93
|
+
Deny cannot carry allow exceptions — deny is evaluated first and always wins — so
|
|
94
|
+
you cannot pair a broad rule with `allow: ["Bash(git status *)"]` to get both.
|
|
95
|
+
|
|
96
|
+
## Judgment calls in this list
|
|
97
|
+
|
|
98
|
+
- **`git fetch` is allowed.** It writes remote-tracking refs but cannot touch the
|
|
99
|
+
working tree, index, HEAD, or a local branch, and blocking it breaks legitimate
|
|
100
|
+
inspection of remote state. Add `"Bash(git fetch *)"` if you disagree.
|
|
101
|
+
- **`git reflog` is denied** because `reflog expire` and `reflog delete` destroy
|
|
102
|
+
recovery history. That also blocks the read form; `git log -g` is an
|
|
103
|
+
unrestricted equivalent.
|
|
104
|
+
- **`git tag` is denied** wholesale, which also blocks listing tags. Use
|
|
105
|
+
`git for-each-ref refs/tags` to list them.
|
|
106
|
+
|
|
107
|
+
## How the rules behave
|
|
108
|
+
|
|
109
|
+
- A deny rule matches inside compound commands, subshells, command substitution
|
|
110
|
+
and control-flow bodies, so `cd /tmp && git clean -f` and `echo "$(git reset
|
|
111
|
+
--hard)"` are both blocked.
|
|
112
|
+
- A deny rule matches past a leading environment assignment, so
|
|
113
|
+
`GIT_AUTHOR_NAME=x git commit` is blocked.
|
|
114
|
+
- `Bash(git commit *)` and `Bash(git commit:*)` are equivalent; the `:*` suffix is
|
|
115
|
+
just another way to write a trailing wildcard. It only works at the end of a
|
|
116
|
+
pattern — `Bash(git:* push)` treats the colon as a literal character.
|
|
117
|
+
- A trailing `* ` with a space also matches the bare command, so
|
|
118
|
+
`Bash(git push *)` blocks `git push` on its own.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Migrating an existing setup
|
|
2
|
+
|
|
3
|
+
Read this when the audit reports a legacy store, or a CLAUDE.md over budget.
|
|
4
|
+
|
|
5
|
+
## Preserve before you delete
|
|
6
|
+
|
|
7
|
+
Content in a legacy store is usually real, hard-won knowledge. It is the
|
|
8
|
+
*loading* that was wrong, not the writing. Never delete a legacy store until its
|
|
9
|
+
content has landed somewhere. For each fact in it, ask:
|
|
10
|
+
|
|
11
|
+
- **True in every session, for every file?** → `CLAUDE.md`. Rare — build commands,
|
|
12
|
+
the hard rules, the definition of done, how to verify.
|
|
13
|
+
- **Durable but scoped to some files?** → a `.claude/rules/` file with `paths:`.
|
|
14
|
+
This is where most of it goes.
|
|
15
|
+
- **Derivable from the code?** → delete it. Directory tours, dependency lists,
|
|
16
|
+
architecture overviews, file inventories. The cartographer regenerates these on
|
|
17
|
+
demand and cannot go stale the way a written copy does.
|
|
18
|
+
- **About the user, or a correction, or a decision?** → leave it; auto memory takes it.
|
|
19
|
+
- **About work in flight?** → the task vault.
|
|
20
|
+
|
|
21
|
+
Back up what you replace (`CLAUDE.md.pre-migration.bak`) and tell the user where
|
|
22
|
+
the backup is.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## Confirm the shared pieces are active
|
|
26
|
+
|
|
27
|
+
These ship with the `agent-os` plugin, so normally there is nothing to install —
|
|
28
|
+
just confirm they are working and wire up anything project-specific:
|
|
29
|
+
|
|
30
|
+
- **`feature-cartographer`** answers "how is X built" and accumulates a per-repo
|
|
31
|
+
map under `.claude/agent-memory/feature-cartographer/`. Decide with the user
|
|
32
|
+
whether that map is committed (useful shared knowledge for a team) or ignored
|
|
33
|
+
(add `.claude/agent-memory/` to `.gitignore`). Check it appears in `/context`
|
|
34
|
+
under Custom Agents.
|
|
35
|
+
- **The session-resume hook** prints the where-you-left-off block at every
|
|
36
|
+
session start. If this project keeps a handoff note at a path the hook does not
|
|
37
|
+
already check, say so — the candidate paths are listed in the hook source, and
|
|
38
|
+
changing them is a plugin change, not a project one.
|
|
39
|
+
|
|
40
|
+
If an agent or the hook is missing, the plugin is not loaded. Say so and point
|
|
41
|
+
the user at `/plugin` rather than writing a project-local copy — a per-project
|
|
42
|
+
fork of a shared tool is how the two silently drift apart.
|
|
43
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Writing rules files and trimming CLAUDE.md
|
|
2
|
+
|
|
3
|
+
Read this when the audit reports an over-budget CLAUDE.md, a rule without
|
|
4
|
+
`paths:`, or when you are creating the rules layer from scratch.
|
|
5
|
+
|
|
6
|
+
## Write the rules files
|
|
7
|
+
|
|
8
|
+
Group by **what the reader is touching**, not by topic. A rule earns its keep
|
|
9
|
+
when its `paths:` are narrow enough that it is absent most of the time.
|
|
10
|
+
|
|
11
|
+
```markdown
|
|
12
|
+
---
|
|
13
|
+
paths:
|
|
14
|
+
- "src/features/**"
|
|
15
|
+
- "src/pages/**"
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Working inside a feature
|
|
19
|
+
...
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Rules of thumb:
|
|
23
|
+
|
|
24
|
+
- Every rule file gets `paths:`. No exceptions — an unscoped rule belongs in
|
|
25
|
+
CLAUDE.md or nowhere.
|
|
26
|
+
- If two rules would always match together, they are one rule.
|
|
27
|
+
- If a rule matches all of `src/**`, it had better be the single most important
|
|
28
|
+
convention in the repo. One such rule is defensible; three is a handbook.
|
|
29
|
+
- Dense agent notes, not prose docs: invariants, terse bullets, the non-obvious.
|
|
30
|
+
Skip rationale and examples unless they prevent a likely mistake.
|
|
31
|
+
- A gotcha is worth more than a description. "X is at Y" is derivable; "X looks
|
|
32
|
+
like it is at Y but is actually at Z, and the project's own docs say otherwise"
|
|
33
|
+
is not.
|
|
34
|
+
|
|
35
|
+
## Trim CLAUDE.md
|
|
36
|
+
|
|
37
|
+
Target ≤200 lines; aim for ~150. Keep:
|
|
38
|
+
|
|
39
|
+
- How to run, build and verify — and whatever the user does *not* want run
|
|
40
|
+
automatically.
|
|
41
|
+
- The hard rules, one line each, with a pointer to the rule file for detail.
|
|
42
|
+
- The definition of done.
|
|
43
|
+
- What automations exist (hooks, subagents, skills, MCP), briefly.
|
|
44
|
+
- A table of the rule files and what each covers, so the layout is discoverable.
|
|
45
|
+
|
|
46
|
+
Cut: directory tours, dependency lists, architecture narration, anything a
|
|
47
|
+
`ls`/`Grep` answers, anything a rule file now owns, and any instruction that is
|
|
48
|
+
really a personal preference (that belongs in `~/.claude/CLAUDE.md`, once,
|
|
49
|
+
globally — not re-typed per project).
|
|
50
|
+
|