@albinocrabs/feynman 0.2.0 → 0.2.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/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +12 -0
- package/CONTRIBUTING.md +126 -0
- package/README.md +22 -4
- package/SECURITY.md +31 -0
- package/bin/feynman.js +5 -5
- package/docs/architecture.md +190 -0
- package/docs/launch.md +67 -0
- package/docs/lint-rules.md +317 -0
- package/docs/self-improvement.md +281 -0
- package/docs/visual-patterns.md +253 -0
- package/examples/algorithm-explain.md +70 -0
- package/examples/api-flow.md +55 -0
- package/examples/architecture-review.md +50 -0
- package/examples/code-review.md +55 -0
- package/examples/db-schema.md +48 -0
- package/examples/deploy-pipeline.md +58 -0
- package/package.json +13 -3
package/CHANGELOG.md
ADDED
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Contributing to feynman
|
|
2
|
+
|
|
3
|
+
Contributions welcome. This guide covers setup, what to work on, and
|
|
4
|
+
how to get a PR merged.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Quick Start
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
git clone https://github.com/apolenkov/feynman
|
|
12
|
+
cd feynman
|
|
13
|
+
npm install
|
|
14
|
+
npm test
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Tests use Node's built-in `node:test` runner — no external test framework
|
|
18
|
+
needed.
|
|
19
|
+
|
|
20
|
+
Lint the codebase: `node bin/feynman-lint.js README.md docs/*.md examples/*.md`
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## What Makes a Good First PR
|
|
25
|
+
|
|
26
|
+
These are well-scoped and require no architectural decisions:
|
|
27
|
+
|
|
28
|
+
- **Add a lint-rule test case** — add a row to `tests/lint-cases.json` for
|
|
29
|
+
an edge case that's currently untested.
|
|
30
|
+
- **Improve an example** — add or improve a file in `examples/` following
|
|
31
|
+
the schema in `docs/architecture.md` and `06-CONTEXT.md`.
|
|
32
|
+
- **Expand `feynman doctor`** — add a new health check to `bin/feynman.js`
|
|
33
|
+
`cmdDoctor()`.
|
|
34
|
+
- **Fix a typo or improve prose** — in `README.md`, `docs/`, or `CONTRIBUTING.md`.
|
|
35
|
+
- **Add a rule to `rules/feynman-activate.md`** — follow the rules-authoring
|
|
36
|
+
guidelines below.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## PR Checklist
|
|
41
|
+
|
|
42
|
+
Before opening a pull request:
|
|
43
|
+
|
|
44
|
+
- [ ] `npm test` passes (all existing tests green)
|
|
45
|
+
- [ ] New behavior has a test in `tests/` covering the change
|
|
46
|
+
- [ ] No new lint warnings: `node bin/feynman-lint.js <changed files>`
|
|
47
|
+
- [ ] `README.md` updated if a user-facing feature changed
|
|
48
|
+
- [ ] Commit message follows the format: `type(scope): description`
|
|
49
|
+
(types: `feat`, `fix`, `test`, `docs`, `refactor`, `chore`)
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Rules Authoring Guidelines
|
|
54
|
+
|
|
55
|
+
The hook injects `rules/feynman-activate.md` into every Claude prompt.
|
|
56
|
+
The rules must be declarative facts, not commands.
|
|
57
|
+
|
|
58
|
+
**Good (declarative):**
|
|
59
|
+
> "A response describing a sequence of steps includes an ASCII flow diagram."
|
|
60
|
+
|
|
61
|
+
**Bad (imperative):**
|
|
62
|
+
> "Always draw a flow diagram when you see steps."
|
|
63
|
+
|
|
64
|
+
Imperative phrasing triggers Claude's prompt-injection defense
|
|
65
|
+
([bug #17804](https://github.com/anthropics/claude-code/issues/17804)) and
|
|
66
|
+
may be filtered or reinterpreted.
|
|
67
|
+
|
|
68
|
+
Each intensity variant must stay under 8,000 characters. Measure with:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
node -e "
|
|
72
|
+
const f = require('fs').readFileSync('rules/feynman-activate.md', 'utf8');
|
|
73
|
+
['lite','full','ultra'].forEach(v => {
|
|
74
|
+
const s = f.indexOf('<!-- ' + v + ' -->');
|
|
75
|
+
const e = f.indexOf('<!-- /' + v + ' -->', s);
|
|
76
|
+
console.log(v, f.slice(s, e + ('<!-- /' + v + ' -->').length).length, 'chars');
|
|
77
|
+
});
|
|
78
|
+
"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Issue Triage
|
|
84
|
+
|
|
85
|
+
**Labels:**
|
|
86
|
+
|
|
87
|
+
| label | when to use |
|
|
88
|
+
|------------------|--------------------------------------------------|
|
|
89
|
+
| `bug` | something works differently than documented |
|
|
90
|
+
| `feature` | new capability request |
|
|
91
|
+
| `docs` | documentation gap or error |
|
|
92
|
+
| `good-first-issue` | well-scoped, no architecture decisions needed |
|
|
93
|
+
|
|
94
|
+
**Expected response time:** best-effort, typically within a week for bugs.
|
|
95
|
+
Feature requests may be deferred to a milestone.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Governance
|
|
100
|
+
|
|
101
|
+
- Single maintainer: [apolenkov](https://github.com/apolenkov)
|
|
102
|
+
- License: MIT — see `LICENSE`
|
|
103
|
+
- Public roadmap: `.planning/ROADMAP.md` (check before proposing big features)
|
|
104
|
+
- No DCO or CLA sign-off required — low barrier to contribution is intentional
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Testing
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npm test # run all tests
|
|
112
|
+
npm test -- --grep L01 # filter by test name pattern
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Coverage report: `npm run coverage` (writes to `coverage/`)
|
|
116
|
+
|
|
117
|
+
Tests are in `tests/` using `node:test` and `node:assert`. Lint golden
|
|
118
|
+
cases are in `tests/lint-cases.json`.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Architecture
|
|
123
|
+
|
|
124
|
+
See [`docs/architecture.md`](docs/architecture.md) for the hook lifecycle,
|
|
125
|
+
lint pipeline, and state schema before making changes to `hooks/`,
|
|
126
|
+
`lib/lint/`, or `bin/`.
|
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
<a href="#intensity-levels">Levels</a> •
|
|
25
25
|
<a href="#lint">Lint</a> •
|
|
26
26
|
<a href="#examples">Examples</a> •
|
|
27
|
+
<a href="docs/launch.md">Launch</a> •
|
|
27
28
|
<a href="CONTRIBUTING.md">Contributing</a>
|
|
28
29
|
</p>
|
|
29
30
|
|
|
@@ -33,7 +34,10 @@ A [Claude Code](https://docs.anthropic.com/en/docs/claude-code) and Codex
|
|
|
33
34
|
plugin that automatically injects ASCII diagram rules into every prompt via the
|
|
34
35
|
`UserPromptSubmit` hook.
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
```bash
|
|
38
|
+
npx -y @albinocrabs/feynman@latest install --target both
|
|
39
|
+
npx -y @albinocrabs/feynman@latest doctor --target codex
|
|
40
|
+
```
|
|
37
41
|
|
|
38
42
|
## Why feynman
|
|
39
43
|
|
|
@@ -262,10 +266,11 @@ Domain-specific examples showing feynman in practice:
|
|
|
262
266
|
|
|
263
267
|
## How it works
|
|
264
268
|
|
|
265
|
-
The `UserPromptSubmit` hook fires on every Claude prompt. The
|
|
266
|
-
`~/.claude/.feynman/state.json
|
|
269
|
+
The `UserPromptSubmit` hook fires on every Claude Code or Codex prompt. The
|
|
270
|
+
hook reads the target-local state file (`~/.claude/.feynman/state.json` or
|
|
271
|
+
`~/.codex/.feynman/state.json`), extracts the rules for the active intensity
|
|
267
272
|
level, and injects them as `additionalContext` — invisible to you, visible to
|
|
268
|
-
|
|
273
|
+
the model on every message.
|
|
269
274
|
|
|
270
275
|
```
|
|
271
276
|
[your prompt]
|
|
@@ -279,6 +284,19 @@ Claude on every message.
|
|
|
279
284
|
[structured response with ASCII diagrams]
|
|
280
285
|
```
|
|
281
286
|
|
|
287
|
+
## Release process
|
|
288
|
+
|
|
289
|
+
Every push runs tests on Node 18 and 20 across Ubuntu and macOS. The release
|
|
290
|
+
lane also lints public docs, smoke-tests the packed npm tarball, builds a
|
|
291
|
+
`dist/*.tgz` artifact, and can publish to npm from a GitHub Release when
|
|
292
|
+
`NPM_TOKEN` is configured.
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
npm run ci
|
|
296
|
+
npm run changelog
|
|
297
|
+
npm run build
|
|
298
|
+
```
|
|
299
|
+
|
|
282
300
|
State is stored at `~/.claude/.feynman/state.json`. First run bootstraps
|
|
283
301
|
automatically. See [docs/architecture.md](docs/architecture.md) for internals.
|
|
284
302
|
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
Security fixes are shipped for the latest published npm version.
|
|
6
|
+
|
|
7
|
+
## Reporting a Vulnerability
|
|
8
|
+
|
|
9
|
+
Please report security issues privately by opening a GitHub security advisory:
|
|
10
|
+
|
|
11
|
+
https://github.com/apolenkov/feynman/security/advisories/new
|
|
12
|
+
|
|
13
|
+
Do not file public issues for vulnerabilities. Include:
|
|
14
|
+
|
|
15
|
+
- affected version
|
|
16
|
+
- reproduction steps
|
|
17
|
+
- expected impact
|
|
18
|
+
- suggested fix, if known
|
|
19
|
+
|
|
20
|
+
We aim to acknowledge reports within 72 hours.
|
|
21
|
+
|
|
22
|
+
## Scope
|
|
23
|
+
|
|
24
|
+
feynman is a local hook package. The main security-sensitive surfaces are:
|
|
25
|
+
|
|
26
|
+
- hook command registration in `~/.claude/settings.json`
|
|
27
|
+
- hook command registration in `~/.codex/hooks.json`
|
|
28
|
+
- file reads from the installed package directory
|
|
29
|
+
- state files under `~/.claude/.feynman/` and `~/.codex/.feynman/`
|
|
30
|
+
|
|
31
|
+
The package has zero runtime npm dependencies.
|
package/bin/feynman.js
CHANGED
|
@@ -98,10 +98,10 @@ ${c.bold('Options:')}
|
|
|
98
98
|
--force (install) Re-register even if already installed
|
|
99
99
|
|
|
100
100
|
${c.bold('Examples:')}
|
|
101
|
-
npx feynman install
|
|
102
|
-
npx feynman install --target codex
|
|
103
|
-
npx feynman install --target both
|
|
104
|
-
npx feynman doctor
|
|
101
|
+
npx @albinocrabs/feynman install
|
|
102
|
+
npx @albinocrabs/feynman install --target codex
|
|
103
|
+
npx @albinocrabs/feynman install --target both
|
|
104
|
+
npx @albinocrabs/feynman doctor
|
|
105
105
|
feynman lint response.md
|
|
106
106
|
feynman uninstall
|
|
107
107
|
`;
|
|
@@ -351,7 +351,7 @@ function cmdUninstall(opts) {
|
|
|
351
351
|
if (results.every(r => r.missing || !r.hadHook)) {
|
|
352
352
|
console.log(`feynman: no hook found for ${labels} — nothing to uninstall.`);
|
|
353
353
|
} else {
|
|
354
|
-
console.log(`feynman disabled for ${labels}. State preserved. Re-enable: npx feynman install --target ${opts.target}`);
|
|
354
|
+
console.log(`feynman disabled for ${labels}. State preserved. Re-enable: npx @albinocrabs/feynman install --target ${opts.target}`);
|
|
355
355
|
}
|
|
356
356
|
process.exit(0);
|
|
357
357
|
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# feynman Architecture
|
|
2
|
+
|
|
3
|
+
Three independent layers: hook lifecycle, lint pipeline, and state schema.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Layer 1: Hook Lifecycle
|
|
8
|
+
|
|
9
|
+
The `UserPromptSubmit` hook fires before every Claude Code or Codex prompt.
|
|
10
|
+
feynman intercepts the event, reads the active rules, and injects them as
|
|
11
|
+
`additionalContext`.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
~/.claude/settings.json ~/.codex/hooks.json
|
|
15
|
+
│
|
|
16
|
+
│ hooks.UserPromptSubmit fires on every prompt
|
|
17
|
+
▼
|
|
18
|
+
hooks/feynman-activate.js
|
|
19
|
+
│
|
|
20
|
+
├─ [0] FEYNMAN_HOME selects client state root
|
|
21
|
+
│ unset → ~/.claude (backward compatible)
|
|
22
|
+
│ ~/.claude → Claude Code install
|
|
23
|
+
│ ~/.codex → Codex install
|
|
24
|
+
│
|
|
25
|
+
├─ [1] validate session_id (path-traversal guard)
|
|
26
|
+
│
|
|
27
|
+
├─ [2] $FEYNMAN_HOME/.feynman-active ← flag file
|
|
28
|
+
│ absent + no state.json → bootstrap first run
|
|
29
|
+
│ absent + state.json → exit 0 (user disabled)
|
|
30
|
+
│ present → continue
|
|
31
|
+
│
|
|
32
|
+
├─ [3] $FEYNMAN_HOME/.feynman/state.json
|
|
33
|
+
│ enabled: false → exit 0
|
|
34
|
+
│ corrupt JSON → exit 0 (fail safe)
|
|
35
|
+
│
|
|
36
|
+
├─ [4] rules/feynman-activate.md
|
|
37
|
+
│ extract section for state.intensity
|
|
38
|
+
│ (lite | full | ultra)
|
|
39
|
+
│
|
|
40
|
+
├─ [5] state.injections++ (write back)
|
|
41
|
+
│
|
|
42
|
+
└─ [6] stdout: JSON additionalContext → injected into prompt
|
|
43
|
+
{hookSpecificOutput: {hookEventName: 'UserPromptSubmit',
|
|
44
|
+
additionalContext: <rules text>}}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Key constraints:**
|
|
48
|
+
|
|
49
|
+
- Output must be JSON with no trailing newline — plain stdout triggers
|
|
50
|
+
Claude Code's red error banner (bug #13912).
|
|
51
|
+
- Paths use `os.homedir()`, never tilde literals (bug #8810).
|
|
52
|
+
- Production install writes user hook config directly:
|
|
53
|
+
`~/.claude/settings.json` for Claude Code and `~/.codex/hooks.json` for
|
|
54
|
+
Codex. Plugin manifests are shipped for discoverability, but direct hook
|
|
55
|
+
registration remains the reliable fallback.
|
|
56
|
+
- Flag file checked before state file to detect intentional disabling
|
|
57
|
+
vs. first run (bug #35713).
|
|
58
|
+
|
|
59
|
+
**File:** `hooks/feynman-activate.js`
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Layer 2: Lint Pipeline
|
|
64
|
+
|
|
65
|
+
The lint pipeline validates ASCII diagram correctness in markdown files.
|
|
66
|
+
It runs as a CLI tool and as an optional `Stop` hook.
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
<file.md> or stdin
|
|
70
|
+
│
|
|
71
|
+
▼
|
|
72
|
+
lib/lint/parser.js
|
|
73
|
+
│ parseMarkdown(text) → ASTNode[]
|
|
74
|
+
│ each node: {type, content, startLine, endLine}
|
|
75
|
+
│ types: fenced_code, ascii_art (freestanding)
|
|
76
|
+
│
|
|
77
|
+
▼
|
|
78
|
+
lib/lint/rules.js
|
|
79
|
+
│ runs each rule against each AST node:
|
|
80
|
+
│
|
|
81
|
+
├─ L01_box_closure(ast)
|
|
82
|
+
├─ L02_tree_chars(ast)
|
|
83
|
+
├─ L03_arrow_style(ast)
|
|
84
|
+
├─ L04_column_widths(ast)
|
|
85
|
+
├─ L05_flow_integrity(ast)
|
|
86
|
+
├─ L06_priority_scale(ast)
|
|
87
|
+
├─ L07_no_mermaid_mix(ast, fullText)
|
|
88
|
+
└─ L08_frame_width(ast)
|
|
89
|
+
│
|
|
90
|
+
│ each rule returns Issue[]:
|
|
91
|
+
│ {rule, severity, line, column, message, suggestion?}
|
|
92
|
+
│
|
|
93
|
+
▼
|
|
94
|
+
reporter (inline in CLI + Stop hook)
|
|
95
|
+
│
|
|
96
|
+
├─ bin/feynman-lint.js ← standalone CLI
|
|
97
|
+
│ feynman lint <file>
|
|
98
|
+
│ exit 0: no errors
|
|
99
|
+
│ exit 1: errors found
|
|
100
|
+
│ exit 2: usage error
|
|
101
|
+
│ --json: machine-readable output
|
|
102
|
+
│ --strict: warnings treated as errors
|
|
103
|
+
│
|
|
104
|
+
└─ hooks/feynman-lint.js ← Stop hook (optional)
|
|
105
|
+
fires after Claude's response
|
|
106
|
+
if issues found: injects correction context
|
|
107
|
+
into next UserPromptSubmit cycle
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**File:** `lib/lint/parser.js`, `lib/lint/rules.js`, `bin/feynman-lint.js`,
|
|
111
|
+
`hooks/feynman-lint.js`
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Layer 3: State Schema
|
|
116
|
+
|
|
117
|
+
All runtime state lives in two files under the selected client root:
|
|
118
|
+
`~/.claude/` for Claude Code, `~/.codex/` for Codex.
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
~/.claude/ or ~/.codex/
|
|
122
|
+
├── .feynman-active ← presence flag
|
|
123
|
+
│ present = feynman active
|
|
124
|
+
│ absent = user disabled (state.json preserved)
|
|
125
|
+
│ content = current intensity string (informational)
|
|
126
|
+
│
|
|
127
|
+
└── .feynman/
|
|
128
|
+
└── state.json ← runtime state
|
|
129
|
+
{
|
|
130
|
+
"enabled": boolean, // true = inject rules on each prompt
|
|
131
|
+
"intensity": string, // "lite" | "full" | "ultra"
|
|
132
|
+
"injections": number // cumulative hook fire count
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**State transitions:**
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
[first run]
|
|
140
|
+
both files absent → bootstrap
|
|
141
|
+
writes state.json {enabled:true, intensity:'full', injections:0}
|
|
142
|
+
writes .feynman-active with intensity string
|
|
143
|
+
|
|
144
|
+
[/feynman off]
|
|
145
|
+
state.enabled = false
|
|
146
|
+
.feynman-active deleted
|
|
147
|
+
|
|
148
|
+
[/feynman on]
|
|
149
|
+
state.enabled = true
|
|
150
|
+
.feynman-active created
|
|
151
|
+
|
|
152
|
+
[/feynman lite | full | ultra]
|
|
153
|
+
state.intensity = <value>
|
|
154
|
+
.feynman-active content updated
|
|
155
|
+
|
|
156
|
+
[npx @albinocrabs/feynman uninstall --target claude|codex|both]
|
|
157
|
+
hook removed from target hook config
|
|
158
|
+
.feynman-active deleted
|
|
159
|
+
state.json preserved (user data)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Schema is frozen** — field names are used by `hooks/feynman-activate.js`,
|
|
163
|
+
`bin/feynman.js`, and `skills/feynman/SKILL.md`. Any rename requires
|
|
164
|
+
coordinated update across all three files.
|
|
165
|
+
|
|
166
|
+
**File:** read/written by `hooks/feynman-activate.js` and `bin/feynman.js`;
|
|
167
|
+
managed by skill commands in `skills/feynman/SKILL.md`.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## CLI Subcommand Map
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
bin/feynman.js
|
|
175
|
+
├── install → writes target hook config + state.json + flag
|
|
176
|
+
├── uninstall → removes target hook entries + flag (keeps state)
|
|
177
|
+
├── doctor → checks target health criteria, prints frame
|
|
178
|
+
├── lint → delegates to bin/feynman-lint.js
|
|
179
|
+
└── version → prints package.json version
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Targets:
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
claude → ~/.claude/settings.json + ~/.claude/.feynman/
|
|
186
|
+
codex → ~/.codex/hooks.json + ~/.codex/.feynman/
|
|
187
|
+
both → runs claude and codex installers idempotently
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**File:** `bin/feynman.js`
|
package/docs/launch.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Launch Notes
|
|
2
|
+
|
|
3
|
+
## Positioning
|
|
4
|
+
|
|
5
|
+
feynman is a Claude Code and Codex plugin that makes structured answers
|
|
6
|
+
visible by default. Flows become arrows, hierarchies become trees, comparisons
|
|
7
|
+
become columns, priorities become scales, and status summaries become frames.
|
|
8
|
+
|
|
9
|
+
## One-liner
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx -y @albinocrabs/feynman@latest install --target both
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Short Description
|
|
16
|
+
|
|
17
|
+
feynman automatically injects ASCII diagram rules into Claude Code and Codex
|
|
18
|
+
prompts, so structured answers render as readable terminal-native diagrams
|
|
19
|
+
without asking every time.
|
|
20
|
+
|
|
21
|
+
## Benefits
|
|
22
|
+
|
|
23
|
+
- No runtime dependencies
|
|
24
|
+
- Works with Claude Code and Codex
|
|
25
|
+
- Installs with `npx`
|
|
26
|
+
- Keeps state local under `~/.claude` or `~/.codex`
|
|
27
|
+
- Ships a diagram linter for public docs and generated responses
|
|
28
|
+
- Uses plain ASCII/Unicode text, not external renderers
|
|
29
|
+
|
|
30
|
+
## Demo Script
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx -y @albinocrabs/feynman@latest install --target both
|
|
34
|
+
npx -y @albinocrabs/feynman@latest doctor --target claude
|
|
35
|
+
npx -y @albinocrabs/feynman@latest doctor --target codex
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Prompt:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
Compare SQLite, Postgres, and Redis for a local-first prototype.
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Expected shape:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
SQLite | Postgres | Redis
|
|
48
|
+
-----------------|------------------|----------------
|
|
49
|
+
single-file | server database | memory-first
|
|
50
|
+
easy local setup | richer SQL | fast cache
|
|
51
|
+
limited writes | production-ready | persistence opt
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Release Checklist
|
|
55
|
+
|
|
56
|
+
- `npm run ci`
|
|
57
|
+
- GitHub Actions CI green
|
|
58
|
+
- `npm run changelog`
|
|
59
|
+
- `npm run build`
|
|
60
|
+
- `npm publish --dry-run --access public`
|
|
61
|
+
- GitHub Release created from changelog notes
|
|
62
|
+
- npm package visible at `@albinocrabs/feynman@latest`
|
|
63
|
+
- Smoke test from clean directory:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npx -y @albinocrabs/feynman@latest version
|
|
67
|
+
```
|