fdeops 3.10.2 → 3.11.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/README.md +87 -81
- package/adapters/README.md +1 -1
- package/bin/check.js +25 -6
- package/bin/fde.js +341 -24
- package/bin/install.js +1 -1
- package/bin/lib/trust.js +11 -3
- package/bin/lib/vault.js +323 -0
- package/hooks/pre-compact +24 -1
- package/hooks/session-start +24 -1
- package/hooks/session-stop +24 -1
- package/mcp/fdeops-ingest/package.json +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/skills/fde/SKILL.md +3 -2
- package/templates/.fde/assumptions.md +2 -2
- package/templates/.fde/decisions.md +2 -10
- package/templates/.fde/delivery.md +6 -2
- package/templates/.fde/evals.md +0 -4
- package/templates/.fde/risks.md +3 -1
- package/templates/.fde/stakeholders.md +2 -1
- package/templates/.fde/terrain.md +0 -2
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# FDEOps
|
|
2
2
|
|
|
3
|
-
**Your AI coding agent forgets your client every morning.
|
|
3
|
+
**Your AI coding agent forgets your client every morning. FDEOps remembers.**
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/fdeops)
|
|
6
6
|
[](https://github.com/suboss87/fdeops/actions)
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
[](https://nodejs.org)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Skill packs teach your AI coding agent how to *build*. None of them remember who the client is, what you promised, or who agreed it was delivered. FDEOps adds that layer: a private fieldbook per engagement (`.fde/`), a field methodology from land to close, and one `@fde` skill that routes it.
|
|
11
11
|
|
|
12
|
-
Built for Forward Deployed Engineers
|
|
12
|
+
Built for Forward Deployed Engineers and anyone embedded in client work - consultants, agency developers, solutions architects, fractional CTOs. Feels like a second brain; behaves like a defensible record: dated, sourced, on your laptop.
|
|
13
13
|
|
|
14
14
|
```
|
|
15
15
|
land discover plan build ship close
|
|
@@ -19,46 +19,21 @@ Built for Forward Deployed Engineers, and anyone embedded in client work: consul
|
|
|
19
19
|
written as a side effect of the work
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Talk in plain language with `@fde`. The AI coding agent runs the plumbing. You confirm anything that enters the record.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## The week
|
|
27
|
-
|
|
28
|
-
`@fde` plus English. No cheat sheet.
|
|
29
|
-
|
|
30
|
-
| When | What you say | What you get |
|
|
31
|
-
|------|--------------|--------------|
|
|
32
|
-
| **Start of week** | `@fde` — or just open Claude Code | Fieldbook on disk either way. **Claude Code** injects trust, phase, next before you type. **Cursor / Codex / others:** say `@fde` or `resume` — nothing auto-loads. |
|
|
33
|
-
| **After a meeting** | `@fde` debrief these notes *(paste or attach)* | Proposed updates. You review, then confirm. |
|
|
34
|
-
| **Optional: pull** | `@fde` connect Granola *(once)* · `@fde` pull today's Acme transcript | You add that source MCP. We **pull** on request — no push, no sync. [mcp/recipes/](mcp/recipes/) |
|
|
35
|
-
| **Before a stakeholder meeting** | `@fde` prep me for tomorrow with the sponsor | Brief from what you already logged. |
|
|
36
|
-
| **Scope dispute** | `@fde` when did we agree to drop that? | Dated answers, or a clear gap. |
|
|
37
|
-
| **End of week** | `@fde` draft the sponsor update from the record | Status grounded in what happened. |
|
|
38
|
-
|
|
39
|
-
Same folder every time: `~/fde-engagements/<client>/.fde/`.
|
|
40
|
-
|
|
41
22
|
---
|
|
42
23
|
|
|
43
|
-
##
|
|
24
|
+
## A real session
|
|
44
25
|
|
|
45
|
-
|
|
46
|
-
npx fdeops demo
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Real commands on a fake client: messy notes → you confirm → cold reload → prep → receipts → fieldbook page. Nothing of yours is read. Lives in `~/fde-engagements/.demo/`. Remove with `npx fdeops demo --clean`.
|
|
50
|
-
|
|
51
|
-
One recorded session — kickoff notes, next morning, “when did we agree?” weeks later. CLI output; typing pace is staged. Re-record: [`media/record-session.sh`](media/record-session.sh).
|
|
26
|
+
Kickoff notes go in messy. You confirm what enters the record. A cold session the next morning already knows the client, the sponsor brief is grounded in dated facts, and the receipts survive the argument. Real CLI output - only the typing pace is staged, and you can [re-record it yourself](media/record-session.sh).
|
|
52
27
|
|
|
53
28
|
<p align="center"><img alt="A real fdeops session: messy kickoff notes routed into dated memory after you confirm, then a cold session that already knows the client, a grounded sponsor-meeting brief, and dated receipts" src="media/session.gif" width="900" /></p>
|
|
54
29
|
|
|
55
|
-
|
|
30
|
+
Nothing to install to see it on a fake client: `npx fdeops demo`.
|
|
56
31
|
|
|
57
32
|
---
|
|
58
33
|
|
|
59
34
|
## Quickstart
|
|
60
35
|
|
|
61
|
-
**1. Install
|
|
36
|
+
**1. Install** on your machine - never in the customer's repo.
|
|
62
37
|
|
|
63
38
|
```text
|
|
64
39
|
/plugin marketplace add suboss87/fdeops
|
|
@@ -66,9 +41,13 @@ Two things a chat window cannot do: **nothing is written until you confirm**, an
|
|
|
66
41
|
```
|
|
67
42
|
|
|
68
43
|
```bash
|
|
69
|
-
npx skills add suboss87/fdeops
|
|
44
|
+
npx skills add suboss87/fdeops --skill fde # Cursor, Codex, skills-compatible hosts
|
|
70
45
|
```
|
|
71
46
|
|
|
47
|
+
That is one skill, not a catalogue - `@fde` routes the whole method. The CLI needs no install either: the skill reaches for `npx fdeops` when `fde` is not on the PATH. (Drop `--skill fde` and you also get `testing-fieldbook`, which is for people contributing to this repo, not for field work.)
|
|
48
|
+
|
|
49
|
+
Claude Code additionally gets session hooks, so context arrives before you type. Everywhere else it is the same fieldbook, loaded when you ask.
|
|
50
|
+
|
|
72
51
|
**2. Bind once** in the client workspace:
|
|
73
52
|
|
|
74
53
|
```bash
|
|
@@ -76,46 +55,74 @@ npx fdeops resume --init garvey # ~/fde-engagements/garvey + bind this checkou
|
|
|
76
55
|
npx fdeops resume # where we are
|
|
77
56
|
```
|
|
78
57
|
|
|
79
|
-
**3. Work**
|
|
58
|
+
**3. Work** in plain language:
|
|
80
59
|
|
|
81
60
|
```text
|
|
82
61
|
@fde New client. Payments platform. They want it live before the Q3 audit.
|
|
83
62
|
```
|
|
84
63
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Working: `npx fdeops resume` prints this client's phase, trust, and next action. Tomorrow that file is still there. Auto-load at session start is Claude Code; elsewhere you invoke `@fde`.
|
|
64
|
+
**It is working if** `npx fdeops resume` prints this client's phase, trust signal, and next action - and prints the same thing tomorrow, from a new session, with no explaining. Full workflow: [docs/USAGE.md](docs/USAGE.md).
|
|
88
65
|
|
|
89
66
|
<details>
|
|
90
67
|
<summary>Other install paths · scan · env</summary>
|
|
91
68
|
|
|
92
|
-
- **Adapters:** `npx fdeops adapters .`
|
|
93
|
-
- **Local LLMs:** load `skills/fde/SKILL.md`
|
|
69
|
+
- **Adapters:** `npx fdeops adapters .` - [adapters/](adapters/README.md)
|
|
70
|
+
- **Local LLMs:** load `skills/fde/SKILL.md` - [guide](adapters/LOCAL-LLM.md)
|
|
94
71
|
- **Air-gapped:** `git clone https://github.com/suboss87/fdeops.git && cd fdeops && node bin/install.js`
|
|
95
72
|
- **No install:** `npx fdeops demo` · `npx fdeops scan` (heuristic recon, not findings)
|
|
96
73
|
- **Requires:** Node.js >= 18
|
|
97
|
-
- **Override:** `FDEOPS_ENGAGEMENT`
|
|
74
|
+
- **Override:** `FDEOPS_ENGAGEMENT` - [docs/install.md](docs/install.md)
|
|
98
75
|
|
|
99
76
|
</details>
|
|
100
77
|
|
|
101
78
|
---
|
|
102
79
|
|
|
80
|
+
## The week
|
|
81
|
+
|
|
82
|
+
`@fde` plus English. No cheat sheet.
|
|
83
|
+
|
|
84
|
+
| When | What you say | What you get |
|
|
85
|
+
|------|--------------|--------------|
|
|
86
|
+
| **Start of week** | `@fde` - or just open Claude Code | Fieldbook on disk either way. **Claude Code** injects trust, phase, next before you type. **Cursor / Codex / others:** say `@fde` or `resume` - nothing auto-loads. |
|
|
87
|
+
| **After a meeting** | `@fde` debrief these notes *(paste or attach)* | Proposed updates. You review, then confirm. |
|
|
88
|
+
| **Optional: pull** | `@fde` connect Granola *(once)* · `@fde` pull today's Acme transcript | You add that source MCP. We **pull** on request - no push, no sync. [mcp/recipes/](mcp/recipes/) |
|
|
89
|
+
| **Before a stakeholder meeting** | `@fde` prep me for tomorrow with the sponsor | Brief from what you already logged. |
|
|
90
|
+
| **Scope dispute** | `@fde` when did we agree to drop that? | Dated answers, or a clear gap. |
|
|
91
|
+
| **End of week** | `@fde` draft the sponsor update from the record | Status grounded in what happened. |
|
|
92
|
+
|
|
93
|
+
Same folder every time: `~/fde-engagements/<client>/.fde/`.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
103
97
|
## How it works
|
|
104
98
|
|
|
105
|
-
- **You** describe the situation with `@fde
|
|
106
|
-
- **
|
|
107
|
-
- **
|
|
108
|
-
- **
|
|
99
|
+
- **You** describe the situation with `@fde`, in plain language.
|
|
100
|
+
- **The AI coding agent** routes to a method, does the work, and drafts the memory.
|
|
101
|
+
- **The CLI** (`bin/fde.js`) does every write, receipt, and status check - git and file reads only, no network, no model tokens. You do not live in the CLI; your agent runs it. [docs/USAGE.md](docs/USAGE.md)
|
|
102
|
+
- **You confirm.** Nothing enters the record unreviewed; `fde debrief --dry-run` shows the routing first.
|
|
103
|
+
|
|
104
|
+
`CLAUDE.md` is how the *code* works. The fieldbook is how the *engagement* works. It lives at `~/fde-engagements/<client>/.fde/`, not inside any vendor - change hosts, install `@fde` on the new one, keep talking.
|
|
105
|
+
|
|
106
|
+
### What works where
|
|
109
107
|
|
|
110
|
-
|
|
108
|
+
Honest boundaries, so nothing here needs a footnote:
|
|
109
|
+
|
|
110
|
+
| | Claude Code | Cursor · Codex · Copilot · Gemini · local LLMs |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| Fieldbook, methods, CLI, dashboard | yes | yes |
|
|
113
|
+
| Context loaded before you type | session hooks | you say `@fde` / `resume` |
|
|
114
|
+
| Snapshot on session end | session hooks | `@fde` capture, or `fde capture` |
|
|
115
|
+
| Pull from Granola / Slack / Notion | you add that source MCP; FDEOps only ingests | same |
|
|
116
|
+
|
|
117
|
+
FDEOps is the sink, never the source: no push, no sync, no third-party tokens in `.fde/`. [mcp/recipes/](mcp/recipes/)
|
|
111
118
|
|
|
112
119
|
<details>
|
|
113
120
|
<summary>Phase verbs (land → close)</summary>
|
|
114
121
|
|
|
115
122
|
| Verb | When |
|
|
116
123
|
|------|------|
|
|
117
|
-
| **land** | First days
|
|
118
|
-
| **discover** | The brief is wrong
|
|
124
|
+
| **land** | First days - brief, stakeholders, success |
|
|
125
|
+
| **discover** | The brief is wrong - evidence from the repo |
|
|
119
126
|
| **plan** | Sequence backwards from done, PR-sized |
|
|
120
127
|
| **build** | Blast radius, log what shipped |
|
|
121
128
|
| **ship** | Pre-flight, canary, rollback |
|
|
@@ -127,9 +134,26 @@ Overlays (AI, fintech, healthcare, gov) fire on signal. [docs/skills.md](docs/sk
|
|
|
127
134
|
|
|
128
135
|
---
|
|
129
136
|
|
|
137
|
+
## Engagement memory (`.fde/`)
|
|
138
|
+
|
|
139
|
+
One folder per client. Plain markdown, so you can grep it, diff it, copy it into a readout, and defend it in a room.
|
|
140
|
+
|
|
141
|
+
| File | Holds |
|
|
142
|
+
|------|-------|
|
|
143
|
+
| `context.md` | Where you are |
|
|
144
|
+
| `brief.md` / `success.md` | What they asked; what "done" is and who signs |
|
|
145
|
+
| `reality.md` / `terrain.md` | The real problem; the map |
|
|
146
|
+
| `stakeholders.md` | `[signal:green\|amber\|red]` |
|
|
147
|
+
| `trust-profile.md` | Sacred data, AI policy, approval chain |
|
|
148
|
+
| `decisions.md` / `risks.md` / `delivery.md` | Dated choices; live risks; what shipped and how it rolls back |
|
|
149
|
+
|
|
150
|
+
A day-one fieldbook ships **empty** - headings and allowed values, no invented rows - so anything you read in it is something that actually happened. Schema: [docs/schema.md](docs/schema.md).
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
130
154
|
## The field methods
|
|
131
155
|
|
|
132
|
-
You never pick one. You describe the situation
|
|
156
|
+
You never pick one. You describe the situation and `@fde` routes. **37 methods** across six domains, each a method - thinking, artifact, checkpoint - not a tip sheet. [docs/skills.md](docs/skills.md) · [docs/skills-reference.md](docs/skills-reference.md)
|
|
133
157
|
|
|
134
158
|
<details>
|
|
135
159
|
<summary>All 37 methods</summary>
|
|
@@ -149,28 +173,11 @@ Overlays: [ai](skills/fde/references/ai.md) · [artifacts](skills/fde/references
|
|
|
149
173
|
|
|
150
174
|
---
|
|
151
175
|
|
|
152
|
-
## Engagement memory (`.fde/`)
|
|
153
|
-
|
|
154
|
-
One folder per client. Plain markdown. Grep it, copy it, defend it.
|
|
155
|
-
|
|
156
|
-
| File | Holds |
|
|
157
|
-
|------|-------|
|
|
158
|
-
| `context.md` | Where you are |
|
|
159
|
-
| `brief.md` / `success.md` | What they asked; what “done” is and who signs |
|
|
160
|
-
| `reality.md` / `terrain.md` | The real problem; the map |
|
|
161
|
-
| `stakeholders.md` | `[signal:green\|amber\|red]` |
|
|
162
|
-
| `trust-profile.md` | Sacred data, AI policy, approval chain |
|
|
163
|
-
| `decisions.md` / `risks.md` / `delivery.md` | Dated choices; live risks; what shipped and how it rolls back |
|
|
164
|
-
|
|
165
|
-
Schema: [docs/schema.md](docs/schema.md).
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
176
|
## Fieldbook UI
|
|
170
177
|
|
|
171
|
-
|
|
178
|
+
`@fde` dashboard, or `npx fdeops dashboard` (`--all` for the portfolio): one local HTML file - trust, phase, next action, and the record behind them. Generated on demand, no server.
|
|
172
179
|
|
|
173
|
-
<p align="center"><img width="1336" height="624" alt="fdeops Fieldbook
|
|
180
|
+
<p align="center"><img width="1336" height="624" alt="The fdeops Fieldbook dashboard: engagements with trust signal, phase and next action" src="https://github.com/user-attachments/assets/5683614c-7730-4a3a-860d-185053a377eb" /></p>
|
|
174
181
|
|
|
175
182
|
---
|
|
176
183
|
|
|
@@ -178,10 +185,10 @@ Local HTML: trust, phase, next, the record. `@fde` dashboard, or `npx fdeops das
|
|
|
178
185
|
|
|
179
186
|
| You are | What this is |
|
|
180
187
|
|---------|----------------|
|
|
181
|
-
| **Forward Deployed Engineer** | The job this was built for
|
|
188
|
+
| **Forward Deployed Engineer** | The job this was built for - first meeting through handoff |
|
|
182
189
|
| **Consultant / contractor on site** | The engagement stops resetting every morning |
|
|
183
190
|
| **Solutions architect** | Politics and architecture in the same record |
|
|
184
|
-
| **Agency, 3
|
|
191
|
+
| **Agency, 3-5 clients** | One `.fde/` each - they stop blurring |
|
|
185
192
|
| **Fractional CTO on client work** | System of record for the embed, and the billable trail |
|
|
186
193
|
|
|
187
194
|
---
|
|
@@ -189,22 +196,21 @@ Local HTML: trust, phase, next, the record. `@fde` dashboard, or `npx fdeops das
|
|
|
189
196
|
## Your data stays yours
|
|
190
197
|
|
|
191
198
|
- **Local only.** `git` + files. No network, no telemetry, no account. Air-gapped is fine.
|
|
192
|
-
- **Plain markdown.** No database.
|
|
193
|
-
- **No new data path.** The model sees client code only when you point the AI coding agent at it. `<private>`
|
|
194
|
-
- **
|
|
195
|
-
- **Know the sync surface.** `~/fde-engagements` is in `$HOME`. iCloud/Dropbox is an NDA incident waiting. `resume --init` warns. [PRIVACY.md](PRIVACY.md) before the first NDA.
|
|
199
|
+
- **Plain markdown.** No database, no lock-in, nothing to export.
|
|
200
|
+
- **No new data path.** The model sees client code only when you point the AI coding agent at it. `<private>` blocks are redacted from CLI, dashboard, and hook output - do not open raw private blocks with file tools.
|
|
201
|
+
- **Know the sync surface.** `~/fde-engagements` lives in `$HOME`. iCloud or Dropbox is an NDA incident waiting; `resume --init` warns you.
|
|
196
202
|
|
|
197
|
-
[PRIVACY.md](PRIVACY.md) · [SECURITY.md](SECURITY.md)
|
|
203
|
+
[PRIVACY.md](PRIVACY.md) before the first NDA · [SECURITY.md](SECURITY.md)
|
|
198
204
|
|
|
199
205
|
---
|
|
200
206
|
|
|
201
207
|
## Principles
|
|
202
208
|
|
|
203
|
-
- **The artifact is the memory**
|
|
204
|
-
- **Methods, not autonomy**
|
|
205
|
-
- **Brief is a hypothesis**
|
|
206
|
-
- **Evidence on every claim**
|
|
207
|
-
- **One customer, one folder**
|
|
209
|
+
- **The artifact is the memory** - producing the work and recording it are one action
|
|
210
|
+
- **Methods, not autonomy** - the kit says what to check; judgment stays yours
|
|
211
|
+
- **Brief is a hypothesis** - discover before building the wrong thing
|
|
212
|
+
- **Evidence on every claim** - these files get defended in the room
|
|
213
|
+
- **One customer, one folder** - context never bleeds
|
|
208
214
|
|
|
209
215
|
---
|
|
210
216
|
|
|
@@ -218,8 +224,8 @@ Re-run the Quickstart install, or from a clone: `git pull && node bin/install.js
|
|
|
218
224
|
|
|
219
225
|
**[Subash Natarajan](https://www.linkedin.com/in/subashn/)**. [Issues](https://github.com/suboss87/fdeops/issues) · [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
220
226
|
|
|
221
|
-
Thanks to builders whose craft sharpened the thinking, among them [Andrej Karpathy](https://karpathy.ai/)'s engineering guidelines and the [agentic engineering workflow](https://github.com/pawel-cell/micky-podcast-agentic-engineering) notes from David Ondrej / Michael Shimeles.
|
|
227
|
+
Thanks to builders whose craft sharpened the thinking, among them [Andrej Karpathy](https://karpathy.ai/)'s engineering guidelines and the [agentic engineering workflow](https://github.com/pawel-cell/micky-podcast-agentic-engineering) notes from David Ondrej / Michael Shimeles.
|
|
222
228
|
|
|
223
|
-
**What we won't build:** SaaS sync; Slack/Notion/Granola connectors or **push** inside the CLI; CRM as core; hardware capture; generic code-craft packs (TDD
|
|
229
|
+
**What we won't build:** SaaS sync; Slack/Notion/Granola connectors or **push** inside the CLI; CRM as core; hardware capture; generic code-craft packs (TDD and review live elsewhere). You may **pull** via *your* MCP. The `fde` CLI stays local-only.
|
|
224
230
|
|
|
225
231
|
[FDE Methodology](FDE-METHODOLOGY.md) · [SECURITY.md](SECURITY.md) · [PRIVACY.md](PRIVACY.md) · [Repo layout](docs/REPO_LAYOUT.md) · [Skills matrix](docs/skills.md) · MIT
|
package/adapters/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**One brain, thin adapters.** fdeops has a single source of truth - the `@fde` skill at `skills/fde/SKILL.md` and the `fde` CLI. Each AI coding tool discovers it through a small pointer file in the place that tool already looks. No forked logic, no five copies to maintain - every adapter says the same thing: *route via `@fde`, read/write `.fde/` memory, talk like a peer, never touch what isn't yours.*
|
|
4
4
|
|
|
5
|
-
**Switching tools:** the fieldbook does not live in the agent. It lives at `~/fde-engagements/<client>/.fde/`. Point a new tool at a bound workspace, drop adapters (or install the skill/plugin for that tool), and the same client record opens. Auto session hooks are Claude Code–first; elsewhere load via `@fde` / `fde resume`. See [README §
|
|
5
|
+
**Switching tools:** the fieldbook does not live in the agent. It lives at `~/fde-engagements/<client>/.fde/`. Point a new tool at a bound workspace, drop adapters (or install the skill/plugin for that tool), and the same client record opens. Auto session hooks are Claude Code–first; elsewhere load via `@fde` / `fde resume`. See [README § What works where](../README.md#what-works-where).
|
|
6
6
|
|
|
7
7
|
## What goes where
|
|
8
8
|
|
package/bin/check.js
CHANGED
|
@@ -221,17 +221,20 @@ const readme = read('README.md')
|
|
|
221
221
|
if (readme.includes('demo.gif')) fail('README must not embed media/demo.gif (staged mock, not real CLI output)')
|
|
222
222
|
else ok('README no staged demo gif')
|
|
223
223
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
224
|
+
// The recording may live on the front door or one click in (docs/USAGE.md), but
|
|
225
|
+
// it must stay reachable and reproducible - an orphaned gif rots silently.
|
|
226
|
+
const recordingHosts = ['README.md', 'docs/USAGE.md'].filter(f => read(f).includes('media/session.gif'))
|
|
227
|
+
if (!recordingHosts.length) {
|
|
228
|
+
fail('media/session.gif must be embedded in README.md or docs/USAGE.md (the recorded session is the proof)')
|
|
229
|
+
} else if (!recordingHosts.some(f => read(f).includes('media/record-session.sh'))) {
|
|
230
|
+
fail('link media/record-session.sh next to the recording, so it can be re-recorded')
|
|
228
231
|
} else {
|
|
229
232
|
const gifPath = path.join(root, 'media', 'session.gif')
|
|
230
233
|
const rec = path.join(root, 'media', 'record-session.sh')
|
|
231
234
|
if (!fs.existsSync(gifPath) || fs.statSync(gifPath).size < 50000) fail('media/session.gif missing or too small')
|
|
232
235
|
else if (!fs.existsSync(rec)) fail('media/record-session.sh missing - the recording must be reproducible')
|
|
233
236
|
else if (!fs.existsSync(path.join(root, 'media', 'session.cast'))) fail('media/session.cast missing - keep the source recording next to the gif')
|
|
234
|
-
else ok(
|
|
237
|
+
else ok(`recorded session in ${recordingHosts.join(' + ')} (gif + reproducible recorder + cast)`)
|
|
235
238
|
}
|
|
236
239
|
|
|
237
240
|
// Every repo-relative README link and image must resolve, or the front door 404s.
|
|
@@ -267,6 +270,22 @@ if (!readme.includes('fde-engagements') || !/fdeops.*init.*engagement/i.test(rea
|
|
|
267
270
|
fail('README must document fde-engagements + init flow')
|
|
268
271
|
} else ok('README engagement path')
|
|
269
272
|
|
|
273
|
+
// The contributor-only testing skill lives in .agents/skills/, so a bare
|
|
274
|
+
// `skills add` installs it too. The advertised command must name the one skill
|
|
275
|
+
// a field user wants.
|
|
276
|
+
for (const m of readme.match(/^.*npx skills add .*$/gm) || []) {
|
|
277
|
+
if (!m.includes('--skill fde')) {
|
|
278
|
+
fail(`README skills-add command must pin --skill fde: ${m.trim()}`)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
ok('README skills install is one skill')
|
|
282
|
+
|
|
283
|
+
// A skill-only install has no fde on the PATH; the router must reach npx before
|
|
284
|
+
// falling back to writing memory by hand.
|
|
285
|
+
if (!read('skills/fde/SKILL.md').includes('npx --yes fdeops')) {
|
|
286
|
+
fail('skills/fde/SKILL.md must fall back to npx --yes fdeops when the CLI is not installed')
|
|
287
|
+
} else ok('SKILL.md npx CLI fallback')
|
|
288
|
+
|
|
270
289
|
if (!fs.existsSync(path.join(root, 'docs', 'USAGE.md'))) {
|
|
271
290
|
fail('docs/USAGE.md missing')
|
|
272
291
|
} else ok('docs/USAGE.md')
|
|
@@ -461,7 +480,7 @@ if (!fs.existsSync(path.join(root, 'bin', 'fde.js'))) {
|
|
|
461
480
|
.map(name => path.join('bin', 'lib', name)),
|
|
462
481
|
]
|
|
463
482
|
const cliSource = cliFiles.map(read).join('\n')
|
|
464
|
-
for (const sub of ['cmdScan', 'cmdResume', 'cmdLog', 'cmdDebrief', 'cmdIngest', 'cmdReceipts', 'cmdCapture', 'cmdStatus', 'cmdDashboard']) {
|
|
483
|
+
for (const sub of ['cmdScan', 'cmdResume', 'cmdLog', 'cmdDebrief', 'cmdIngest', 'cmdReceipts', 'cmdCapture', 'cmdStatus', 'cmdDashboard', 'cmdVault']) {
|
|
465
484
|
if (!cliSource.includes(sub)) fail(`CLI sources missing ${sub}`)
|
|
466
485
|
}
|
|
467
486
|
if (!JSON.parse(read('package.json')).bin.fde) fail('package.json must expose the fde bin')
|