fdeops 3.9.4 → 3.9.5

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 CHANGED
@@ -7,7 +7,7 @@
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
8
8
  [![Node](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
9
9
 
10
- The **second brain for Forward Deployed Engineers** - engineers embedded at a client, from first meeting to final handoff. Works the same for consultants, agency developers, solutions architects, and fractional CTOs.
10
+ CLI + one `@fde` skill + hooks over a local `.fde/` fieldbook - one folder per client. The **second brain for Forward Deployed Engineers** - engineers embedded at a client, from first meeting to final handoff. Works the same for consultants, agency developers, solutions architects, and fractional CTOs.
11
11
 
12
12
  ```
13
13
  land discover plan build ship close
@@ -17,48 +17,52 @@ The **second brain for Forward Deployed Engineers** - engineers embedded at a cl
17
17
  written as a side effect of the work
18
18
  ```
19
19
 
20
- Describe your situation - `@fde` routes to the right method and writes the matching `.fde/` artifact. Phase methods (land close) live in the skill; the CLI owns scan, memory, and receipts. You still confirm judgment the fieldbook does not maintain itself without you.
20
+ **Glossary:** **fieldbook** = the `.fde/` folder · **TRIAGE** = trust + phase + next from memory · **receipts** = dated search of what you logged · **hooks** = auto load/capture at session start/end.
21
21
 
22
- ---
23
-
24
- ## The problem
22
+ Describe your situation - `@fde` routes to the right method and writes the matching `.fde/` artifact. Phase methods (land → close) live in the skill; the CLI owns scan, memory, and receipts. You still confirm judgment - the fieldbook does not maintain itself without you.
25
23
 
26
- Your AI agent's memory is scoped to a **repo**. Client work isn't: one engagement spans several repos, a dozen stakeholders, and decisions made in meetings your agent never saw. That context lives in rooms, chats, and hallway conversations - nothing writes it down where your tools can use it.
24
+ ---
27
25
 
28
- fdeops adds the missing layer: memory scoped to the **client** - plain markdown at `~/fde-engagements/<client>/.fde/`, written as a side effect of doing the work. Local only, zero dependencies, no network, no telemetry.
26
+ ## The week
29
27
 
30
- A notes app stores what you type. fdeops loads the right client into your AI agent's context automatically and turns meetings into dated receipts you can defend - the difference is what happens without you opening it.
28
+ What you actually run most days - the habit that compounds the fieldbook:
31
29
 
32
- ## Without fdeops vs with fdeops
30
+ | When | What you do | Why it matters |
31
+ |------|-------------|----------------|
32
+ | **Monday** | Open your AI coding agent → TRIAGE loads (trust, phase, next) | Start where last week left off - no re-paste |
33
+ | **After a meeting** | `fde debrief --smart notes.txt` → review → `--apply` | Messy notes become dated decisions, risks, contacts |
34
+ | **Before a walk-in** | `fde prep "Denise sync"` | Walk in with memory, not a blank chat |
35
+ | **Scope fight** | `fde receipts descope` (+ memory git hash) | Answer "when did we agree?" from the record |
36
+ | **Friday** | `fde status` → sponsor update from the real record | Status from evidence, not memory theater |
33
37
 
34
- | Moment | Without fdeops | With fdeops |
35
- |---|---|---|
36
- | **Monday morning** | Re-paste last week's context, re-explain the stakeholders | A hook loads the engagement at session start - the agent opens knowing the deadline and the open thread |
37
- | **After a meeting** | Notes rot in a scratch file | `fde debrief` routes decisions, risks, deliveries, and contacts into the record, dated |
38
- | **Scope dispute** | "Small" additions absorbed silently; no record when the sponsor asks | `fde receipts <term>` answers "when did we agree to that?" with dates |
39
- | **Quiet stakeholder** | Noticed three weeks too late | `fde log contact --signal amber` the day it happens; `fde status` surfaces it |
40
- | **Multiple clients** | Details blur across engagements | One folder per client; bind the workspace so writes cannot land on a name-alike checkout |
38
+ Same engagement folder every time (`~/fde-engagements/<client>/.fde/`). Git versions it. Your AI coding agent reads it on every session.
41
39
 
42
40
  ---
43
41
 
44
42
  ## Quickstart
45
43
 
46
- **1. Install** (Claude Code)
44
+ **1. Install** (pick one)
45
+
46
+ ```bash
47
+ npx skills add suboss87/fdeops # Cursor, Codex, and skills-compatible agents
48
+ ```
47
49
 
48
50
  ```text
49
- /plugin marketplace add suboss87/fdeops
51
+ /plugin marketplace add suboss87/fdeops # Claude Code
50
52
  /plugin install fdeops@fdeops
51
53
  ```
52
54
 
53
- **2. Bind your client workspace** - run once, inside the workspace:
55
+ **2. Bind** - once, inside the client workspace:
54
56
 
55
57
  ```bash
56
- npx fdeops resume --init garvey
58
+ npx fdeops resume --init garvey # creates ~/fde-engagements/garvey engagement + binds workspace
57
59
  ```
58
60
 
59
- (`npx` needs nothing pre-installed. Want the bare `fde` command the rest of this README uses? `npm i -g fdeops` - the plugin install alone does not put `fde` on your PATH.)
61
+ **Verify:**
60
62
 
61
- fdeops' `--init` creates the engagement memory at `~/fde-engagements/garvey/.fde/` (plain markdown, private to your machine) and binds this workspace to it. The hooks read that binding - context auto-loads at session start, auto-captures at session end. That is the whole setup.
63
+ ```bash
64
+ npx fdeops resume # should print TRIAGE (trust, phase, next) for garvey
65
+ ```
62
66
 
63
67
  **3. Work**
64
68
 
@@ -66,43 +70,37 @@ fdeops' `--init` creates the engagement memory at `~/fde-engagements/garvey/.fde
66
70
  @fde I just got the brief. New client, payments platform, they want it live before their Q3 audit.
67
71
  ```
68
72
 
69
- `@fde` is the one skill fdeops installs. Describe what's happening; it routes to the right field method and writes matching `.fde/` artifacts you still confirm judgment. Full workflow: [docs/USAGE.md](docs/USAGE.md).
70
-
71
- Not ready to install? `npx fdeops scan` runs on any repo you can read - day-1 recon (pure `git` + file reads, no config, no account) that maps hotspots, test gaps, and reverted attempts, and ends with the ASK ON DAY 1 questions the brief never mentions. The scan is heuristic by design - treat its output as leads to verify on day one, not findings.
73
+ `@fde` routes and writes `.fde/` artifacts - you confirm judgment. Use `npx fdeops …` until you want a short command: `npm i -g fdeops` (optional). Full workflow: [docs/USAGE.md](docs/USAGE.md).
72
74
 
73
75
  <details>
74
- <summary><strong>Other install paths</strong> - Cursor, Codex, Copilot, Gemini CLI, local LLMs, air-gapped</summary>
76
+ <summary><strong>Other install paths</strong> · scan · env</summary>
75
77
 
76
- - **Cursor / Codex / Copilot / Gemini CLI:** `npx fdeops adapters .` drops a thin pointer to the same `@fde` skill - [adapters/](adapters/README.md)
78
+ - **Cursor / Codex / Copilot / Gemini CLI:** `npx fdeops adapters .` - [adapters/](adapters/README.md)
77
79
  - **Local LLMs (Ollama, LM Studio, llama.cpp):** load `skills/fde/SKILL.md` as the system prompt - [guide](adapters/LOCAL-LLM.md)
78
- - **Skills CLI:** `npx skills add suboss87/fdeops`
79
80
  - **Manual / air-gapped:** `git clone https://github.com/suboss87/fdeops.git && cd fdeops && node bin/install.js`
80
- - **Requires:** [Node.js](https://nodejs.org) >= 18 for the CLI and adapters; the Claude Code plugin install does not need Node separately.
81
- - **Advanced:** the `FDEOPS_ENGAGEMENT` env var overrides the workspace registry - only for unusual setups. Full matrix: [docs/install.md](docs/install.md)
81
+ - **Try without install:** `npx fdeops scan` - day-1 recon (heuristic leads, not findings)
82
+ - **Requires:** [Node.js](https://nodejs.org) >= 18 for the CLI and adapters
83
+ - **Advanced:** `FDEOPS_ENGAGEMENT` overrides the workspace registry. Full matrix: [docs/install.md](docs/install.md)
82
84
 
83
85
  </details>
84
86
 
85
87
  ---
86
88
 
87
- ## The week
88
-
89
- This is the actual habit — the high-frequency loop, not the full skill matrix:
90
-
91
- - **Monday morning** - open your agent, context loads, you're not re-explaining anything
92
- - **After a meeting** - `fde debrief` turns raw notes into dated decisions, risks, and signals
93
- - **Mid-scope-fight** - `fde receipts <term>` answers "when did we agree to that?"
94
- - **Friday** - `fde status` gives you the sponsor update from the week's actual record
95
-
96
- ---
97
-
98
89
  ## How it works
99
90
 
100
- Two hooks and one router, on top of the fieldbook:
91
+ Three pieces on top of the fieldbook:
101
92
 
102
93
  - **Session start** - a hook loads where you left off into your AI coding agent's context
103
94
  - **Session end** - a hook captures what happened back into the fieldbook
104
- - **After meetings** - `fde debrief notes.md` routes lines prefixed `decision:` / `risk:` / `delivery:` / `contact:` to the matching file, dated; everything else lands as a dated block in `context.md`
105
- - **On top of the memory** - the `@fde` skill routes six phase verbs:
95
+ - **`@fde`** - routes your situation to a field method; you confirm before memory sticks
96
+ - **CLI** - deterministic, offline (`scan`, `debrief`, `prep`, `receipts`, `status`)
97
+
98
+ fdeops complements repo memory: CLAUDE.md holds how the *code* works; the fieldbook holds how the *engagement* works.
99
+
100
+ Works with **Claude Code** · **Cursor** · **Copilot** · **Gemini CLI** · **Ollama** · **LM Studio** - any model that reads markdown.
101
+
102
+ <details>
103
+ <summary><strong>Phase verbs</strong> (land → close)</summary>
106
104
 
107
105
  | Verb | When |
108
106
  |------|------|
@@ -113,9 +111,9 @@ Two hooks and one router, on top of the fieldbook:
113
111
  | **ship** | Going to production - pre-flight, canary, tested rollback |
114
112
  | **close** | Engagement ending - handoff doc, retrospective, receipts that survive you |
115
113
 
116
- Overlays for regulated domains (AI, fintech, healthcare, government) activate on signal. fdeops complements your agent's native repo memory: CLAUDE.md holds how the *code* works; the fieldbook holds how the *engagement* works. Full matrix: [docs/skills.md](docs/skills.md).
114
+ Overlays for regulated domains (AI, fintech, healthcare, government) activate on signal. Full matrix: [docs/skills.md](docs/skills.md).
117
115
 
118
- Works with **Claude Code** - **Cursor** - **Copilot** - **Gemini CLI** - **Ollama** - **LM Studio** - any model that reads a markdown file.
116
+ </details>
119
117
 
120
118
  ---
121
119
 
@@ -138,33 +136,41 @@ Every entry is dated and sourced, so you can defend it in front of skeptical sta
138
136
 
139
137
  ## The CLI
140
138
 
141
- Deterministic, offline, zero tokens - the skill adds judgment on top:
139
+ Commands that match **The week** (skill adds judgment on top):
142
140
 
143
141
  ```bash
144
- fde scan # day-1 recon + ASK ON DAY 1 questions (works via npx)
145
142
  fde resume # TRIAGE + load this workspace's engagement
146
- fde resume --init <client> # THE setup step: create + bind + git-version .fde/
147
- fde triage # TRIAGE only (session hooks / Cursor entry)
148
- fde debrief notes.md # route prefixed meeting notes (also reads stdin)
149
- fde debrief --smart notes.md # propose routing from messy notes --apply to confirm
150
- fde prep "Denise sync" # grounded walk-in brief from existing memory
143
+ fde resume --init <client> # create + bind + git-version .fde/
144
+ fde debrief --smart notes.md # propose routing --apply to confirm
145
+ fde prep "Denise sync" # walk-in brief from existing memory
146
+ fde receipts <term> # dated search (gap proof of absence)
147
+ fde status # sponsor-ready triage (--all for portfolio)
148
+ fde scan # day-1 recon + ASK ON DAY 1 (works via npx)
149
+ ```
150
+
151
+ <details>
152
+ <summary><strong>More commands</strong></summary>
153
+
154
+ ```bash
155
+ fde triage # TRIAGE only (hooks / Cursor entry)
156
+ fde debrief notes.md # prefix router: decision: / risk: / delivery: / contact:
151
157
  fde doctor # lint: stale signals, unset phase, gaps
152
- fde log decision "descope agreed with Kowalczyk"
153
- fde log contact "Denise gone quiet" --signal amber
154
- fde receipts <term> # dated search; no hit = a gap in the record, not proof of absence
155
- fde status # current engagement triage (add --all for every client)
156
- fde dashboard # current engagement fieldbook (add --all for every client)
158
+ fde log decision ""
159
+ fde log contact "" --signal amber
160
+ fde dashboard # FieldBook HTML (--all for every client)
157
161
  ```
158
162
 
159
- Optional: `export FDEOPS_ENGAGEMENTS_ROOT=~/path/to/engagements` to isolate init/status/dashboard from the default `~/fde-engagements`.
163
+ Optional: `export FDEOPS_ENGAGEMENTS_ROOT=~/path/to/engagements` to isolate from `~/fde-engagements`.
164
+
165
+ Each `.fde/` is a local git repo (no remote, no telemetry) - dated entries carry an author tag; every write commits so receipts are tamper-evident. Worst-of `[signal:...]` per stakeholder drives trust; signals older than 21 days show as stale.
160
166
 
161
- Each `.fde/` is a local git repo (no remote, no telemetry) — dated entries carry an author tag; every write commits so receipts are tamper-evident. Worst-of `[signal:...]` per stakeholder drives trust; signals older than 21 days show as stale.
167
+ </details>
162
168
 
163
169
  <p align="center"><img src="media/terminal-demo.svg" alt="fde CLI - status, scan, dashboard" width="720"/></p>
164
170
 
165
171
  `fde dashboard` (FieldBook) renders the **current** engagement by default. Pass `--all` for every client sorted by trust:
166
172
 
167
- <p align="center"><img width="1336" height="624" alt="Screenshot 2026-07-08 at 12 45 07" src="https://github.com/user-attachments/assets/5683614c-7730-4a3a-860d-185053a377eb" /></p>
173
+ <p align="center"><img width="1336" height="624" alt="fde dashboard FieldBook" src="https://github.com/user-attachments/assets/5683614c-7730-4a3a-860d-185053a377eb" /></p>
168
174
 
169
175
  ---
170
176
 
@@ -196,10 +202,8 @@ Details: [PRIVACY.md](PRIVACY.md) · [SECURITY.md](SECURITY.md)
196
202
 
197
203
  - **The artifact is the memory** - producing work and recording it are one action
198
204
  - **Methods, not autonomy** - each skill tells you what to check; the judgment, the trust, and the consequences stay yours
199
- - **Trust before production** - earn the right to touch their systems
200
205
  - **Brief is a hypothesis** - discover before building the wrong thing
201
206
  - **Evidence on every claim** - these files get defended in front of skeptical clients
202
- - **Thin slices** - ship learning, not theatre
203
207
  - **One customer, one folder** - context never bleeds
204
208
 
205
209
  ---
@@ -207,6 +211,8 @@ Details: [PRIVACY.md](PRIVACY.md) · [SECURITY.md](SECURITY.md)
207
211
  ## Updating
208
212
 
209
213
  ```bash
214
+ # Plugin / skills install: re-run the install command from Quickstart
215
+ # From a git clone:
210
216
  cd fdeops && git pull && node bin/install.js
211
217
  ```
212
218
 
package/bin/check.js CHANGED
@@ -111,7 +111,7 @@ for (const section of [
111
111
  'Quickstart',
112
112
  'Engagement memory',
113
113
  'Who this is for',
114
- 'Without fdeops vs with fdeops',
114
+ 'The week',
115
115
  'Principles',
116
116
  ]) {
117
117
  if (!readme.includes(section)) fail(`README missing section: ${section}`)
@@ -205,6 +205,22 @@ const hook = read('hooks/session-start')
205
205
  if (!hook.includes('FDEOPS_ENGAGEMENT')) {
206
206
  fail('session-start hook must read FDEOPS_ENGAGEMENT env var')
207
207
  } else ok('hook FDEOPS_ENGAGEMENT')
208
+ // Token discipline: SessionStart must not dump the full skill (L1 progressive disclosure).
209
+ // Strip comments before scanning for a real `cat …SKILL.md` / BOOTSTRAP inject.
210
+ const hookCode = hook.replace(/^[ \t]*#.*$/gm, '')
211
+ if (/\$\(cat\s+"\$BOOTSTRAP"\)|cat\s+"\$BOOTSTRAP"|cat\s+[^\n]*SKILL\.md/.test(hookCode)) {
212
+ fail('session-start must not cat SKILL.md - inject TRIAGE + bounded context + pointer only')
213
+ }
214
+ if (hookCode.includes('BOOTSTRAP=')) {
215
+ fail('session-start must not resolve BOOTSTRAP skill path for inject')
216
+ }
217
+ if (!hook.includes('invoke @fde')) {
218
+ fail('session-start must include a lean @fde pointer (not full skill)')
219
+ }
220
+ if (!/\btriage\b/.test(hook)) {
221
+ fail('session-start must still inject TRIAGE')
222
+ }
223
+ ok('session-start lean inject (no SKILL dump)')
208
224
 
209
225
  // v3: write-side memory backstop
210
226
  if (!fs.existsSync(path.join(root, 'hooks', 'session-stop'))) {
@@ -1,18 +1,10 @@
1
1
  #!/bin/bash
2
- # fdeops SessionStart - load @fde + engagement context from FDE laptop path.
2
+ # fdeops SessionStart - inject TRIAGE + bounded engagement context (not the full skill).
3
+ # Token discipline (L1 progressive disclosure): Claude/Cursor already discover @fde via
4
+ # skill metadata. Dumping skills/fde/SKILL.md here paid ~6-8k tokens every session even
5
+ # when the FDE was not doing field work. Load the skill body only when @fde triggers.
3
6
 
4
7
  CONTEXT_FILE=""
5
- BOOTSTRAP=""
6
-
7
- for candidate in \
8
- "${CLAUDE_PLUGIN_ROOT:+$CLAUDE_PLUGIN_ROOT/skills/fde/SKILL.md}" \
9
- "$(dirname "$0")/../skills/fde/SKILL.md" \
10
- "$HOME/.claude/skills/fde/SKILL.md"; do
11
- if [ -n "$candidate" ] && [ -f "$candidate" ]; then
12
- BOOTSTRAP="$candidate"
13
- break
14
- fi
15
- done
16
8
 
17
9
  resolve_engagement_dir() {
18
10
  local raw="$1"
@@ -143,9 +135,8 @@ bounded_context() {
143
135
 
144
136
  CONTENT=""
145
137
 
146
- if [ -n "$BOOTSTRAP" ]; then
147
- CONTENT="$CONTENT$(cat "$BOOTSTRAP")\n\n"
148
- fi
138
+ # Lean pointer only - never cat SKILL.md. Methods load on @fde / skill trigger.
139
+ CONTENT="${CONTENT}fdeops: engagement fieldbook active. For field methods, invoke @fde (loads skills/fde/SKILL.md + one references/*.md). Plumbing is zero-token CLI: fde triage | resume | debrief | prep | receipts | status.\n\n"
149
140
 
150
141
  # Same TRIAGE block as `fde resume` / `fde triage` - Monday morning must not
151
142
  # depend on the model remembering to run a CLI command. Prefer the installed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fdeops",
3
- "version": "3.9.4",
3
+ "version": "3.9.5",
4
4
  "description": "Field kit for engineers embedded in client work - a real CLI (recon, memory, portfolio), one @fde skill with field judgment on top, and hooks that make it automatic. Claude Code plugin and any agent that loads skills.",
5
5
  "bin": {
6
6
  "fdeops": "bin/install.js",
@@ -70,7 +70,7 @@ When NOT to interrogate or challenge: unambiguous one-liners, mechanical ops, FD
70
70
 
71
71
  CLI missing → use the manual fallback commands inside each reference.
72
72
 
73
- **Token model - where the cost goes.** Deterministic work is the CLI's job and costs **zero model tokens**: memory writes, recon, receipts, status, dashboard, and the bounded `fde resume`. Spend tokens only on judgment - reading the situation, routing, running the phase method, writing the artifact. Three rules keep a full day of FDE work cheap: load the router first and pull **one** reference only when you route to it; never dump a whole `.fde/` file into context - read the bounded resume, or `fde receipts <term>` for a targeted slice; don't re-read files you already have. The expensive model should fire for real decisions, not for plumbing the CLI already does.
73
+ **Token model - where the cost goes.** Deterministic work is the CLI's job and costs **zero model tokens**: memory writes, recon, receipts, status, dashboard, and the bounded `fde resume`. Session-start hooks inject **TRIAGE + bounded `context.md` + a one-line pointer** - never this full skill body (that loads only when `@fde` triggers). Spend tokens only on judgment - reading the situation, routing, running the phase method, writing the artifact. Three rules keep a full day of FDE work cheap: load the router first and pull **one** reference only when you route to it; never dump a whole `.fde/` file into context - read the bounded resume, or `fde receipts <term>` for a targeted slice; don't re-read files you already have. The expensive model should fire for real decisions, not for plumbing the CLI already does.
74
74
 
75
75
  ## Proactive intelligence (run on every session start)
76
76