nogrep 1.0.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/README.md +91 -0
- package/commands/init.md +241 -0
- package/commands/off.md +11 -0
- package/commands/on.md +21 -0
- package/commands/query.md +13 -0
- package/commands/status.md +15 -0
- package/commands/update.md +89 -0
- package/dist/chunk-SMUAF6SM.js +12 -0
- package/dist/chunk-SMUAF6SM.js.map +1 -0
- package/dist/query.d.ts +12 -0
- package/dist/query.js +272 -0
- package/dist/query.js.map +1 -0
- package/dist/settings.d.ts +6 -0
- package/dist/settings.js +75 -0
- package/dist/settings.js.map +1 -0
- package/dist/signals.d.ts +9 -0
- package/dist/signals.js +174 -0
- package/dist/signals.js.map +1 -0
- package/dist/trim.d.ts +3 -0
- package/dist/trim.js +266 -0
- package/dist/trim.js.map +1 -0
- package/dist/types.d.ts +141 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +10 -0
- package/dist/validate.js +143 -0
- package/dist/validate.js.map +1 -0
- package/dist/write.d.ts +8 -0
- package/dist/write.js +267 -0
- package/dist/write.js.map +1 -0
- package/docs/ARCHITECTURE.md +239 -0
- package/docs/CLAUDE.md +161 -0
- package/docs/CONVENTIONS.md +162 -0
- package/docs/SPEC.md +803 -0
- package/docs/TASKS.md +216 -0
- package/hooks/hooks.json +35 -0
- package/hooks/pre-tool-use.sh +37 -0
- package/hooks/prompt-submit.sh +26 -0
- package/hooks/session-start.sh +21 -0
- package/package.json +24 -0
- package/scripts/query.ts +290 -0
- package/scripts/settings.ts +98 -0
- package/scripts/signals.ts +237 -0
- package/scripts/trim.ts +379 -0
- package/scripts/types.ts +186 -0
- package/scripts/validate.ts +181 -0
- package/scripts/write.ts +346 -0
- package/templates/claude-md-patch.md +8 -0
package/docs/CLAUDE.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# nogrep — Implementation Guide for Claude Code
|
|
2
|
+
|
|
3
|
+
## What You Are Building
|
|
4
|
+
|
|
5
|
+
`nogrep` is a Claude Code plugin that gives AI agents a navigable index of any codebase, so they stop doing blind grep/find exploration.
|
|
6
|
+
|
|
7
|
+
**The one thing it does:** Generate and maintain a structured `.nogrep/` directory with a reverse index (`_index.json`) and thin context nodes (markdown files), so CC can find the right files in 2 reads instead of 20.
|
|
8
|
+
|
|
9
|
+
**What it is NOT:** A documentation generator, a code search engine, a standalone CLI, or a replacement for GSD or Compodoc. It is a navigation layer — intentionally minimal, fully scoped to Claude Code.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Before You Start
|
|
14
|
+
|
|
15
|
+
Read these files in order before writing any code:
|
|
16
|
+
|
|
17
|
+
1. `docs/SPEC.md` — full technical specification, schemas, pipeline details
|
|
18
|
+
2. `docs/ARCHITECTURE.md` — project structure and module boundaries
|
|
19
|
+
3. `docs/CONVENTIONS.md` — code style, naming, patterns to follow
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Project Stack
|
|
24
|
+
|
|
25
|
+
- **Language:** TypeScript (strict mode)
|
|
26
|
+
- **Runtime:** Node.js 20+
|
|
27
|
+
- **Package manager:** npm
|
|
28
|
+
- **Testing:** Vitest
|
|
29
|
+
- **Build:** `tsup`
|
|
30
|
+
- **Distribution:** CC plugin (npm package)
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Repository Structure to Create
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
nogrep/
|
|
38
|
+
├── scripts/
|
|
39
|
+
│ ├── signals.ts # Phase 1: universal signal collection
|
|
40
|
+
│ ├── query.ts # index lookup (called by hooks)
|
|
41
|
+
│ ├── validate.ts # staleness check (called by hooks)
|
|
42
|
+
│ ├── write.ts # structured file writer (context nodes, index, registry)
|
|
43
|
+
│ ├── settings.ts # read/write .claude/settings.json
|
|
44
|
+
│ ├── trim.ts # language-agnostic source trimming
|
|
45
|
+
│ └── types.ts # all shared TypeScript types
|
|
46
|
+
├── commands/
|
|
47
|
+
│ ├── init.md # orchestrates full init pipeline
|
|
48
|
+
│ ├── update.md # diff-based update of stale nodes
|
|
49
|
+
│ ├── query.md # manual index lookup
|
|
50
|
+
│ ├── status.md # coverage + freshness summary
|
|
51
|
+
│ ├── on.md # enable nogrep
|
|
52
|
+
│ └── off.md # disable nogrep
|
|
53
|
+
├── hooks/
|
|
54
|
+
│ ├── pre-tool-use.sh # intercepts grep/find/rg
|
|
55
|
+
│ ├── session-start.sh # checks index freshness on session start
|
|
56
|
+
│ └── prompt-submit.sh # injects context on every user prompt
|
|
57
|
+
├── templates/
|
|
58
|
+
│ └── claude-md-patch.md # snippet appended to target project CLAUDE.md
|
|
59
|
+
├── tests/
|
|
60
|
+
│ ├── fixtures/ # sample mini-projects for testing
|
|
61
|
+
│ │ ├── nestjs-project/
|
|
62
|
+
│ │ ├── django-project/
|
|
63
|
+
│ │ └── react-project/
|
|
64
|
+
│ ├── signals.test.ts
|
|
65
|
+
│ ├── query.test.ts
|
|
66
|
+
│ └── writer.test.ts
|
|
67
|
+
├── docs/
|
|
68
|
+
│ ├── CLAUDE.md # this file
|
|
69
|
+
│ ├── SPEC.md # full technical spec
|
|
70
|
+
│ ├── ARCHITECTURE.md # internal architecture doc
|
|
71
|
+
│ ├── CONVENTIONS.md # coding conventions
|
|
72
|
+
│ └── TASKS.md # implementation tasks
|
|
73
|
+
├── plugin.json
|
|
74
|
+
├── package.json
|
|
75
|
+
├── tsconfig.json
|
|
76
|
+
└── README.md
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Implementation Order
|
|
82
|
+
|
|
83
|
+
Implement in this exact order — each step is testable before moving on:
|
|
84
|
+
|
|
85
|
+
### Step 1 — Scaffold
|
|
86
|
+
- `package.json`, `tsconfig.json`, `tsup.config.ts`
|
|
87
|
+
- `scripts/types.ts` — all types first
|
|
88
|
+
- `plugin.json` — CC plugin manifest
|
|
89
|
+
|
|
90
|
+
### Step 2 — Settings
|
|
91
|
+
- `scripts/settings.ts` — read/write `.claude/settings.json` and `.claude/settings.local.json`
|
|
92
|
+
- `commands/on.md` and `commands/off.md` slash commands
|
|
93
|
+
|
|
94
|
+
### Step 3 — Phase 1: Signals (no AI)
|
|
95
|
+
- `scripts/signals.ts` — universal signal collection
|
|
96
|
+
- Test against the fixtures in `tests/fixtures/`
|
|
97
|
+
|
|
98
|
+
### Step 4 — Source Trimming
|
|
99
|
+
- `scripts/trim.ts` — language-agnostic source trimming
|
|
100
|
+
- Test against TypeScript, Python, Java snippet fixtures
|
|
101
|
+
|
|
102
|
+
### Step 5 — Writers
|
|
103
|
+
- `scripts/write.ts` — context files, index builder, registry, CLAUDE.md patcher
|
|
104
|
+
- `templates/claude-md-patch.md`
|
|
105
|
+
- Test: write to temp dirs, verify file contents
|
|
106
|
+
|
|
107
|
+
### Step 6 — Init Slash Command
|
|
108
|
+
- `commands/init.md` — orchestrates the full pipeline
|
|
109
|
+
- Embeds Phase 2 + Phase 3 prompts (Claude does the AI work)
|
|
110
|
+
- Calls `dist/signals.js` for data, `dist/write.js` for output via `${CLAUDE_PLUGIN_ROOT}`
|
|
111
|
+
|
|
112
|
+
### Step 7 — Query System
|
|
113
|
+
- `scripts/query.ts` — extractor + resolver
|
|
114
|
+
- `commands/query.md` slash command
|
|
115
|
+
|
|
116
|
+
### Step 8 — Validate + Update + Status
|
|
117
|
+
- `scripts/validate.ts` — staleness detection
|
|
118
|
+
- `commands/update.md` — guided incremental update
|
|
119
|
+
- `commands/status.md` — index health summary
|
|
120
|
+
|
|
121
|
+
### Step 9 — Hooks
|
|
122
|
+
- `hooks/pre-tool-use.sh` — intercepts grep/find
|
|
123
|
+
- `hooks/session-start.sh` — freshness check
|
|
124
|
+
- `hooks/prompt-submit.sh` — context injection
|
|
125
|
+
|
|
126
|
+
### Step 10 — README + Distribution
|
|
127
|
+
- `README.md`
|
|
128
|
+
- Verify `npm pack` ships correct files
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Key Decisions Already Made
|
|
133
|
+
|
|
134
|
+
- **No standalone CLI.** Everything runs inside CC via slash commands and hooks.
|
|
135
|
+
- **No AI client / SDK.** Claude IS the AI — slash commands contain the analysis prompts, Claude executes them directly.
|
|
136
|
+
- **No database.** Everything is files. `.nogrep/` lives in the repo.
|
|
137
|
+
- **Scripts are mechanical.** They collect data, write files, query indexes — no AI work.
|
|
138
|
+
- **Nodes are intentionally thin** — 3 sentences of purpose, public surface, does-not-own, gotchas. Not comprehensive docs.
|
|
139
|
+
- **Manual Notes section** in each node is never overwritten by update.
|
|
140
|
+
- **Hooks intercept at tool-call level** — not just CLAUDE.md instructions, so CC cannot bypass.
|
|
141
|
+
- **Per-project settings** — `.claude/settings.json` (team, committed) or `.claude/settings.local.json` (personal, gitignored).
|
|
142
|
+
- **CI is out of scope for v1** — index maintained via `/nogrep:update` during CC sessions.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Environment Variables
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
NOGREP_DEBUG # optional, set to 1 for verbose script output
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
No `ANTHROPIC_API_KEY` needed — Claude does the AI work directly.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Testing Approach
|
|
157
|
+
|
|
158
|
+
- Use **Vitest** for all tests
|
|
159
|
+
- Fixture projects in `tests/fixtures/` are minimal — 5-10 files each, enough to test detection
|
|
160
|
+
- No AI mocking needed — scripts are pure data/IO
|
|
161
|
+
- Run: `npm test`
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# nogrep — Coding Conventions
|
|
2
|
+
|
|
3
|
+
## Language & Runtime
|
|
4
|
+
|
|
5
|
+
- TypeScript strict mode — `"strict": true` in tsconfig
|
|
6
|
+
- Node.js 20+
|
|
7
|
+
- ESM modules (`"type": "module"` in package.json)
|
|
8
|
+
- No `any` — use `unknown` and narrow
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Naming
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
// Files: kebab-case
|
|
16
|
+
signals.ts
|
|
17
|
+
index-builder.ts
|
|
18
|
+
pre-tool-use.sh
|
|
19
|
+
|
|
20
|
+
// Types/Interfaces: PascalCase
|
|
21
|
+
interface StackResult { ... }
|
|
22
|
+
interface NodeResult { ... }
|
|
23
|
+
|
|
24
|
+
// Functions: camelCase, verb-first
|
|
25
|
+
collectSignals()
|
|
26
|
+
buildIndex()
|
|
27
|
+
resolveQuery()
|
|
28
|
+
extractTerms()
|
|
29
|
+
checkFreshness()
|
|
30
|
+
|
|
31
|
+
// Constants: UPPER_SNAKE_CASE
|
|
32
|
+
const MAX_CLUSTER_LINES = 300
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Functions
|
|
38
|
+
|
|
39
|
+
- Small and focused — one responsibility
|
|
40
|
+
- Pure functions where possible (especially in scripts)
|
|
41
|
+
- Prefer named parameters for 3+ args:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// ✅
|
|
45
|
+
writeContextFiles({ nodes, outputDir, preserveManualNotes })
|
|
46
|
+
|
|
47
|
+
// ❌
|
|
48
|
+
writeContextFiles(nodes, outputDir, true)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
- Always type return values explicitly on exported functions
|
|
52
|
+
- Async/await everywhere — no raw Promise chains
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Error Handling
|
|
57
|
+
|
|
58
|
+
Always use `NogrepError` with a code for expected failures:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// ✅
|
|
62
|
+
throw new NogrepError('No .nogrep/_index.json found. Run /nogrep:init first.', 'NO_INDEX')
|
|
63
|
+
|
|
64
|
+
// ❌
|
|
65
|
+
throw new Error('not found')
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Scripts catch `NogrepError` and output JSON errors to stderr.
|
|
69
|
+
Hooks fail silently (exit 0) — never block the CC session.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## File I/O
|
|
74
|
+
|
|
75
|
+
- All file paths are absolute — resolve early, pass around as absolute
|
|
76
|
+
- Use `fs/promises` — no sync fs calls
|
|
77
|
+
- Writer functions take `outputDir` as explicit parameter — never hardcode `.nogrep/`
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Script Output
|
|
82
|
+
|
|
83
|
+
Scripts communicate via stdout (JSON for data, plain text for human-readable).
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
# ✅ Good
|
|
87
|
+
{ "nodes": 17, "stale": 1 }
|
|
88
|
+
|
|
89
|
+
# ❌ Too chatty
|
|
90
|
+
🚀 Starting signal collection...
|
|
91
|
+
📁 Found 42 files...
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Verbose output only when `NOGREP_DEBUG=1`, and goes to stderr.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Package Structure
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"type": "module",
|
|
103
|
+
"files": ["dist/", "commands/", "hooks/", "templates/", "plugin.json"]
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Dependencies
|
|
110
|
+
|
|
111
|
+
Keep dependencies minimal. Approved list:
|
|
112
|
+
|
|
113
|
+
| Package | Purpose |
|
|
114
|
+
|---------|---------|
|
|
115
|
+
| `glob` | file glob matching |
|
|
116
|
+
| `gray-matter` | frontmatter parsing |
|
|
117
|
+
| `js-yaml` | YAML serialization |
|
|
118
|
+
| `vitest` | testing (dev) |
|
|
119
|
+
| `tsup` | build (dev) |
|
|
120
|
+
| `typescript` | type checking (dev) |
|
|
121
|
+
| `@types/node` | Node type defs (dev) |
|
|
122
|
+
|
|
123
|
+
Do not add new dependencies without a strong reason.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## tsconfig.json
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"compilerOptions": {
|
|
132
|
+
"target": "ES2022",
|
|
133
|
+
"module": "ESNext",
|
|
134
|
+
"moduleResolution": "bundler",
|
|
135
|
+
"strict": true,
|
|
136
|
+
"noUncheckedIndexedAccess": true,
|
|
137
|
+
"outDir": "./dist",
|
|
138
|
+
"rootDir": "./scripts",
|
|
139
|
+
"declaration": true,
|
|
140
|
+
"sourceMap": true
|
|
141
|
+
},
|
|
142
|
+
"include": ["scripts/**/*"],
|
|
143
|
+
"exclude": ["node_modules", "dist", "tests"]
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Tests
|
|
150
|
+
|
|
151
|
+
- Test files in `tests/` directory
|
|
152
|
+
- Use `describe` + `it` — not `test`
|
|
153
|
+
- Each test file is independent — no shared state between files
|
|
154
|
+
- Use `vitest`'s `vi.mock` sparingly — prefer dependency injection
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
// ✅ injectable
|
|
158
|
+
const result = collectSignals('/path/to/fixture', { exclude: [] })
|
|
159
|
+
|
|
160
|
+
// ❌ global mock
|
|
161
|
+
vi.mock('fs/promises')
|
|
162
|
+
```
|