facult 2.13.9 → 2.15.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.
Files changed (36) hide show
  1. package/README.md +26 -8
  2. package/assets/packs/facult-operating-model/agents/evolution-planner/agent.toml +3 -0
  3. package/assets/packs/facult-operating-model/agents/integration-auditor/agent.toml +8 -1
  4. package/assets/packs/facult-operating-model/agents/scope-promoter/agent.toml +8 -1
  5. package/assets/packs/facult-operating-model/agents/writeback-curator/agent.toml +2 -0
  6. package/assets/packs/facult-operating-model/instructions/INTEGRATION.md +44 -0
  7. package/assets/packs/facult-operating-model/instructions/PROJECT_CAPABILITY.md +35 -0
  8. package/assets/packs/facult-operating-model/instructions/WORK_UNITS.md +48 -0
  9. package/assets/packs/facult-operating-model/skills/capability-evolution/SKILL.md +25 -6
  10. package/assets/packs/facult-operating-model/skills/project-operating-layer-design/SKILL.md +33 -0
  11. package/assets/packs/facult-operating-model/snippets/global/core/feedback-loops.md +1 -0
  12. package/assets/packs/facult-operating-model/snippets/global/core/work-units.md +2 -1
  13. package/assets/packs/facult-operating-model/{AGENTS.global.md → snippets/templates/agents-global.md} +6 -0
  14. package/docs/README.md +4 -0
  15. package/docs/assets/fclt-capability-loop.png +0 -0
  16. package/docs/built-in-pack.md +23 -2
  17. package/docs/codex-plugin.md +57 -0
  18. package/docs/concepts.md +4 -1
  19. package/docs/pack-upgrades.md +73 -0
  20. package/docs/reference.md +2 -2
  21. package/docs/roadmap.md +4 -3
  22. package/docs/work-units.md +96 -0
  23. package/package.json +5 -1
  24. package/plugins/fclt/.codex-plugin/plugin.json +31 -0
  25. package/plugins/fclt/.mcp.json +11 -0
  26. package/plugins/fclt/scripts/fclt-mcp.js +320 -0
  27. package/plugins/fclt/skills/fclt-capability-review/SKILL.md +51 -0
  28. package/plugins/fclt/skills/fclt-evolution/SKILL.md +65 -0
  29. package/plugins/fclt/skills/fclt-setup/SKILL.md +65 -0
  30. package/plugins/fclt/skills/fclt-writeback/SKILL.md +57 -0
  31. package/src/agents.ts +1 -0
  32. package/src/builtin-assets.ts +1 -1
  33. package/src/builtin.ts +22 -0
  34. package/src/doctor.ts +6 -2
  35. package/src/global-docs.ts +6 -2
  36. package/src/remote.ts +252 -10
@@ -0,0 +1,73 @@
1
+ # Built-in Pack Upgrades
2
+
3
+ The built-in operating-model pack is a starting point, not a source of destructive ownership over your `.ai` root.
4
+
5
+ Use normal install for a new root:
6
+
7
+ ```bash
8
+ fclt templates init operating-model --global
9
+ fclt templates init operating-model --project
10
+ fclt templates init operating-model --root /path/to/.ai
11
+ ```
12
+
13
+ By default, existing files are skipped. This is safe for first install and for adding newly introduced pack files.
14
+
15
+ ## Non-Destructive Update
16
+
17
+ Use `--update` to refresh only files that still match the previously installed pack copy:
18
+
19
+ ```bash
20
+ fclt templates init operating-model --global --update --dry-run
21
+ fclt templates init operating-model --global --update
22
+ ```
23
+
24
+ `fclt` records a pack manifest under:
25
+
26
+ ```text
27
+ .ai/.facult/packs/facult-operating-model.json
28
+ ```
29
+
30
+ During `--update`, files are overwritten only when their current hash matches the last installed pack hash. If a user or agent edited a file locally, `fclt` skips it and reports it as a local edit.
31
+
32
+ Use `--force` only when you intentionally want to replace the selected root's pack files:
33
+
34
+ ```bash
35
+ fclt templates init operating-model --global --force
36
+ ```
37
+
38
+ ## Legacy Installs
39
+
40
+ Older installs may not have a pack manifest. In that case, `--update` stays conservative:
41
+
42
+ - files that already match the current pack are recorded in the manifest
43
+ - missing files are added
44
+ - edited or unknown existing files are skipped
45
+
46
+ For a legacy root with many local changes, use an agent-assisted review:
47
+
48
+ ```bash
49
+ fclt templates init operating-model --global --update --dry-run --json
50
+ fclt doctor --json --global
51
+ ```
52
+
53
+ Review skipped files before deciding whether to merge changes manually, keep the local version, or replace with `--force`.
54
+
55
+ ## AGENTS.global.md
56
+
57
+ The pack source stores the composed entry template at `snippets/templates/agents-global.md`. During install or update, `fclt` materializes that template as `AGENTS.global.md` in the target `.ai` root.
58
+
59
+ That installed `AGENTS.global.md` is not meant to hold every rule.
60
+
61
+ If first install finds existing agent guidance, `fclt` seeds `AGENTS.global.md` from it and appends the Facult operating-model frame. Global installs look for existing global tool docs such as `~/.codex/AGENTS.md` and `~/.claude/CLAUDE.md`; project installs look for repo-local `AGENTS.md` or `CLAUDE.md`.
62
+
63
+ Seeded files are user-owned. They are intentionally excluded from the pack manifest so `--update` skips them unless you explicitly replace them with `--force` or edit them manually.
64
+
65
+ Use:
66
+
67
+ - snippets for injected baseline blocks
68
+ - instructions for detailed doctrine
69
+ - skills for workflow execution
70
+ - agents for delegated review roles
71
+ - local/global config for private user-owned refs
72
+
73
+ This keeps global agent guidance small while still making the full operating model discoverable.
package/docs/reference.md CHANGED
@@ -48,8 +48,8 @@ The graph explains how instructions, snippets, config refs, and rendered targets
48
48
 
49
49
  ```bash
50
50
  fclt templates list
51
- fclt templates init operating-model [--global|--project|--root PATH]
52
- fclt templates init project-ai
51
+ fclt templates init operating-model [--global|--project|--root PATH] [--update] [--force]
52
+ fclt templates init project-ai [--update] [--force]
53
53
  fclt templates init instruction <name>
54
54
  fclt templates init snippet <marker>
55
55
  fclt templates init skill <name>
package/docs/roadmap.md CHANGED
@@ -16,6 +16,7 @@ This roadmap tracks remaining product direction for `fclt`.
16
16
  - JSON-first `inventory`.
17
17
  - `sync --adopt-live` for explicit promotion of live tool edits.
18
18
  - Managed sync local-edit protection for rendered docs, config, MCP, and skills.
19
+ - Initial first-party Codex plugin with setup/writeback/evolution/capability-review skills and a CLI-backed MCP wrapper.
19
20
 
20
21
  ## Current Priorities
21
22
 
@@ -48,11 +49,11 @@ This roadmap tracks remaining product direction for `fclt`.
48
49
  - Add graph visibility.
49
50
  - Include them in status and sync plans.
50
51
 
51
- 7. Add a first-party Codex plugin and MCP surface.
52
- - Expose safe read/write operations over existing `fclt` behavior.
52
+ 7. Expand the first-party Codex plugin and MCP surface.
53
+ - Add richer setup planning tools beyond the initial CLI wrapper.
53
54
  - Keep the CLI and canonical `.ai` roots as the source of truth.
54
55
  - Gate high-risk global changes behind explicit review.
55
- - Bundle agent-facing skills for work units, writeback, evolution, capability search, and automation setup.
56
+ - Add more focused agent-facing skills for automation setup, capability search, and upgrade flows.
56
57
 
57
58
  8. Tighten selector consistency.
58
59
  - Use one selector grammar across `list`, `show`, `graph`, `enable`, `disable`, `trust`, `audit`, writeback, and evolution.
@@ -0,0 +1,96 @@
1
+ # Work Units
2
+
3
+ A work unit is a governed unit of agent work. It gives a task enough shape to be executed, checked, integrated, and learned from.
4
+
5
+ This is broader than capability evolution. Use work-unit framing for coding, research, docs, operations, setup, debugging, product work, and AI capability updates whenever the task has meaningful ambiguity or risk.
6
+
7
+ ## Minimum Shape
8
+
9
+ A useful work unit names:
10
+
11
+ - goal: the outcome needed
12
+ - acceptance criteria: what must be true at the end
13
+ - context: source files, systems, docs, messages, or decisions needed for correctness
14
+ - constraints: privacy, permissions, compatibility, deadlines, ownership, and scope limits
15
+ - evidence: checks that confirm progress or falsify assumptions
16
+ - artifact: code, docs, issue, note, draft, proposal, report, or rendered output
17
+ - verification: command, review surface, manual check, or source-of-truth read
18
+ - writeback target: where durable learning belongs if the work teaches something reusable
19
+
20
+ Keep this implicit for trivial work. Make it explicit when the task is ambiguous, stateful, high-impact, cross-tool, or likely to create reusable learning.
21
+
22
+ ## Why It Matters
23
+
24
+ Machine execution makes output cheaper. That does not remove the governance problem. It moves pressure into intent, context, review, integration, memory, and feedback.
25
+
26
+ Work units are the object that keeps those pieces attached. Without them, agents can produce more output while leaving humans to reconstruct what changed, why it changed, what evidence exists, and what should improve next time.
27
+
28
+ With them:
29
+
30
+ - the agent knows what done means
31
+ - verification is chosen before the final claim
32
+ - integration risk is visible
33
+ - writeback has evidence and a target
34
+ - repeated friction can become evolution instead of folklore
35
+
36
+ ## How It Connects To fclt
37
+
38
+ `fclt` ships work-unit guidance in the built-in operating-model pack:
39
+
40
+ ```text
41
+ @builtin/facult-operating-model/instructions/WORK_UNITS.md
42
+ @builtin/facult-operating-model/snippets/global/core/work-units.md
43
+ ```
44
+
45
+ Install it into a canonical root:
46
+
47
+ ```bash
48
+ fclt templates init operating-model --global
49
+ ```
50
+
51
+ Then agents can read the same guidance from `~/.ai/instructions/WORK_UNITS.md`, and rendered global agent files can include the work-unit snippet.
52
+
53
+ ## Examples
54
+
55
+ Coding work:
56
+
57
+ ```text
58
+ Goal: fix a failing checkout test
59
+ Acceptance: the focused test and relevant integration path pass
60
+ Context: failing output, checkout code, recent commits
61
+ Constraints: preserve public API and user data behavior
62
+ Evidence: test output plus inspected changed path
63
+ Artifact: code diff and summary
64
+ Verification: command output and integration check
65
+ Writeback: only if the failure exposes reusable stale guidance
66
+ ```
67
+
68
+ Research work:
69
+
70
+ ```text
71
+ Goal: answer a product or technical question
72
+ Acceptance: answer is current, source-backed, and separates facts from inference
73
+ Context: user question, relevant docs, date sensitivity
74
+ Constraints: use primary sources when accuracy depends on them
75
+ Evidence: source links and consistency check
76
+ Artifact: concise answer or research note
77
+ Verification: source freshness and source agreement
78
+ Writeback: durable note if the answer will recur
79
+ ```
80
+
81
+ Capability evolution:
82
+
83
+ ```text
84
+ Goal: decide whether writebacks justify changing capability
85
+ Acceptance: proposal exists only when repeated evidence or a clear gap supports it
86
+ Context: grouped writebacks, current target asset, project/global scope
87
+ Constraints: avoid proposal noise and private leakage
88
+ Evidence: writeback ids and affected work units
89
+ Artifact: proposal, applied change, rejection, or no-op note
90
+ Verification: target, scope, proposal kind, and rendered/review artifact
91
+ Writeback: only for new meta-learning about the evolution loop
92
+ ```
93
+
94
+ ## Background
95
+
96
+ The framing is related to the production-model argument in [Governing the Machine](https://www.hack.dance/writing/governing-the-machine): as more work becomes machine-mediated, the hard problem shifts from producing output to governing work, evidence, memory, and improvement.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "facult",
3
- "version": "2.13.9",
3
+ "version": "2.15.0",
4
4
  "description": "Manage canonical AI capabilities, sync surfaces, and evolution state.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -33,6 +33,10 @@
33
33
  "bin/facult.cjs",
34
34
  "docs/**/*.md",
35
35
  "docs/**/*.png",
36
+ "plugins/fclt/.codex-plugin/*.json",
37
+ "plugins/fclt/.mcp.json",
38
+ "plugins/fclt/**/*.js",
39
+ "plugins/fclt/**/*.md",
36
40
  "src/**/*.ts",
37
41
  "!src/**/*.test.ts",
38
42
  "README.md",
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "fclt",
3
+ "version": "0.1.0",
4
+ "description": "Codex workflows and MCP tools for fclt setup, writeback, evolution, and capability review.",
5
+ "license": "MIT",
6
+ "keywords": [
7
+ "fclt",
8
+ "facult",
9
+ "codex",
10
+ "skills",
11
+ "mcp",
12
+ "writeback",
13
+ "evolution"
14
+ ],
15
+ "skills": "./skills/",
16
+ "mcpServers": "./.mcp.json",
17
+ "interface": {
18
+ "displayName": "fclt",
19
+ "shortDescription": "Capability loops for Codex",
20
+ "longDescription": "Install and operate fclt from Codex: initialize AI capability roots, inspect setup health, record writebacks, review evolution proposals, and keep skills, snippets, instructions, automations, and MCP surfaces improving over time.",
21
+ "developerName": "Hack Dance",
22
+ "category": "Productivity",
23
+ "capabilities": ["Read", "Write", "MCP"],
24
+ "defaultPrompt": [
25
+ "Use fclt to check this repo's AI capability setup.",
26
+ "Record useful fclt writeback from this work.",
27
+ "Review fclt evolution proposals and next actions."
28
+ ],
29
+ "brandColor": "#166534"
30
+ }
31
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "fclt": {
4
+ "command": "node",
5
+ "args": ["./scripts/fclt-mcp.js"],
6
+ "env": {
7
+ "FCLT_BIN": "fclt"
8
+ }
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,320 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn } from "node:child_process";
4
+
5
+ const FCLT_BIN = process.env.FCLT_BIN || "fclt";
6
+ const DEFAULT_TIMEOUT_MS = Number(process.env.FCLT_MCP_TIMEOUT_MS || 60_000);
7
+ const CONTENT_LENGTH_RE = /Content-Length:\s*(\d+)/i;
8
+
9
+ const tools = [
10
+ {
11
+ name: "fclt_status",
12
+ description:
13
+ "Return fclt status for the current, global, or project scope.",
14
+ inputSchema: {
15
+ type: "object",
16
+ properties: {
17
+ scope: { type: "string", enum: ["auto", "global", "project"] },
18
+ cwd: { type: "string" },
19
+ },
20
+ },
21
+ },
22
+ {
23
+ name: "fclt_doctor",
24
+ description: "Run read-only fclt doctor checks and return JSON output.",
25
+ inputSchema: {
26
+ type: "object",
27
+ properties: {
28
+ scope: { type: "string", enum: ["auto", "global", "project"] },
29
+ cwd: { type: "string" },
30
+ },
31
+ },
32
+ },
33
+ {
34
+ name: "fclt_paths",
35
+ description: "Return canonical, generated, review, and runtime fclt paths.",
36
+ inputSchema: {
37
+ type: "object",
38
+ properties: {
39
+ scope: { type: "string", enum: ["auto", "global", "project"] },
40
+ cwd: { type: "string" },
41
+ },
42
+ },
43
+ },
44
+ {
45
+ name: "fclt_init_operating_model",
46
+ description: "Install or update the built-in operating-model pack.",
47
+ inputSchema: {
48
+ type: "object",
49
+ properties: {
50
+ scope: { type: "string", enum: ["global", "project"] },
51
+ cwd: { type: "string" },
52
+ update: { type: "boolean" },
53
+ dryRun: { type: "boolean" },
54
+ force: { type: "boolean" },
55
+ },
56
+ required: ["scope"],
57
+ },
58
+ },
59
+ {
60
+ name: "fclt_writeback_add",
61
+ description: "Record a durable fclt writeback with evidence.",
62
+ inputSchema: {
63
+ type: "object",
64
+ properties: {
65
+ scope: { type: "string", enum: ["auto", "global", "project"] },
66
+ cwd: { type: "string" },
67
+ kind: { type: "string" },
68
+ summary: { type: "string" },
69
+ asset: { type: "string" },
70
+ evidence: { type: "string" },
71
+ confidence: {
72
+ type: "string",
73
+ enum: ["low", "medium", "high"],
74
+ },
75
+ },
76
+ required: ["kind", "summary"],
77
+ },
78
+ },
79
+ {
80
+ name: "fclt_writeback_review",
81
+ description: "List, group, or summarize current fclt writebacks.",
82
+ inputSchema: {
83
+ type: "object",
84
+ properties: {
85
+ scope: { type: "string", enum: ["auto", "global", "project"] },
86
+ cwd: { type: "string" },
87
+ mode: { type: "string", enum: ["list", "group", "summarize"] },
88
+ by: { type: "string" },
89
+ },
90
+ },
91
+ },
92
+ {
93
+ name: "fclt_evolve",
94
+ description: "List, propose, draft, or review fclt evolution proposals.",
95
+ inputSchema: {
96
+ type: "object",
97
+ properties: {
98
+ scope: { type: "string", enum: ["auto", "global", "project"] },
99
+ cwd: { type: "string" },
100
+ action: {
101
+ type: "string",
102
+ enum: ["list", "propose", "draft", "review", "show"],
103
+ },
104
+ id: { type: "string" },
105
+ },
106
+ },
107
+ },
108
+ ];
109
+
110
+ function scopeArgs(scope) {
111
+ if (scope === "global") {
112
+ return ["--global"];
113
+ }
114
+ if (scope === "project") {
115
+ return ["--project"];
116
+ }
117
+ return [];
118
+ }
119
+
120
+ function boolFlag(name, value) {
121
+ return value ? [name] : [];
122
+ }
123
+
124
+ function stringFlag(name, value) {
125
+ return typeof value === "string" && value.trim() ? [name, value] : [];
126
+ }
127
+
128
+ function commandForTool(name, args = {}) {
129
+ switch (name) {
130
+ case "fclt_status":
131
+ return ["status", ...scopeArgs(args.scope), "--json"];
132
+ case "fclt_doctor":
133
+ return ["doctor", ...scopeArgs(args.scope), "--json"];
134
+ case "fclt_paths":
135
+ return ["paths", ...scopeArgs(args.scope), "--json"];
136
+ case "fclt_init_operating_model":
137
+ return [
138
+ "templates",
139
+ "init",
140
+ "operating-model",
141
+ ...scopeArgs(args.scope),
142
+ ...boolFlag("--update", args.update),
143
+ ...boolFlag("--dry-run", args.dryRun),
144
+ ...boolFlag("--force", args.force),
145
+ "--json",
146
+ ];
147
+ case "fclt_writeback_add":
148
+ return [
149
+ "ai",
150
+ "writeback",
151
+ ...scopeArgs(args.scope),
152
+ "add",
153
+ "--kind",
154
+ args.kind,
155
+ "--summary",
156
+ args.summary,
157
+ ...stringFlag("--asset", args.asset),
158
+ ...stringFlag("--evidence", args.evidence),
159
+ ...stringFlag("--confidence", args.confidence),
160
+ ];
161
+ case "fclt_writeback_review": {
162
+ const mode = args.mode || "list";
163
+ return [
164
+ "ai",
165
+ "writeback",
166
+ ...scopeArgs(args.scope),
167
+ mode,
168
+ ...stringFlag("--by", args.by),
169
+ ];
170
+ }
171
+ case "fclt_evolve": {
172
+ const action = args.action || "list";
173
+ return [
174
+ "ai",
175
+ "evolve",
176
+ ...scopeArgs(args.scope),
177
+ action,
178
+ ...(args.id ? [args.id] : []),
179
+ ];
180
+ }
181
+ default:
182
+ throw new Error(`Unknown tool: ${name}`);
183
+ }
184
+ }
185
+
186
+ function runFclt(args, cwd) {
187
+ return new Promise((resolve) => {
188
+ const child = spawn(FCLT_BIN, args, {
189
+ cwd: cwd || process.cwd(),
190
+ env: process.env,
191
+ stdio: ["ignore", "pipe", "pipe"],
192
+ });
193
+ let stdout = "";
194
+ let stderr = "";
195
+ const timer = setTimeout(() => {
196
+ child.kill("SIGTERM");
197
+ }, DEFAULT_TIMEOUT_MS);
198
+ child.stdout.on("data", (chunk) => {
199
+ stdout += chunk.toString();
200
+ });
201
+ child.stderr.on("data", (chunk) => {
202
+ stderr += chunk.toString();
203
+ });
204
+ child.on("close", (code) => {
205
+ clearTimeout(timer);
206
+ resolve({
207
+ code,
208
+ text: [
209
+ `$ ${FCLT_BIN} ${args.join(" ")}`,
210
+ stdout.trim(),
211
+ stderr.trim() ? `stderr:\n${stderr.trim()}` : "",
212
+ ]
213
+ .filter(Boolean)
214
+ .join("\n\n"),
215
+ });
216
+ });
217
+ });
218
+ }
219
+
220
+ function send(message) {
221
+ const body = JSON.stringify(message);
222
+ process.stdout.write(
223
+ `Content-Length: ${Buffer.byteLength(body)}\r\n\r\n${body}`
224
+ );
225
+ }
226
+
227
+ async function handle(message) {
228
+ if (!message || message.id == null) {
229
+ return;
230
+ }
231
+
232
+ try {
233
+ if (message.method === "initialize") {
234
+ send({
235
+ jsonrpc: "2.0",
236
+ id: message.id,
237
+ result: {
238
+ protocolVersion: "2025-06-18",
239
+ capabilities: { tools: {} },
240
+ serverInfo: { name: "fclt", version: "0.1.0" },
241
+ },
242
+ });
243
+ return;
244
+ }
245
+ if (message.method === "tools/list") {
246
+ send({ jsonrpc: "2.0", id: message.id, result: { tools } });
247
+ return;
248
+ }
249
+ if (message.method === "tools/call") {
250
+ const { name, arguments: args = {} } = message.params || {};
251
+ const command = commandForTool(name, args);
252
+ const result = await runFclt(command, args.cwd);
253
+ send({
254
+ jsonrpc: "2.0",
255
+ id: message.id,
256
+ result: {
257
+ isError: result.code !== 0,
258
+ content: [{ type: "text", text: result.text }],
259
+ },
260
+ });
261
+ return;
262
+ }
263
+ send({
264
+ jsonrpc: "2.0",
265
+ id: message.id,
266
+ error: { code: -32_601, message: `Method not found: ${message.method}` },
267
+ });
268
+ } catch (error) {
269
+ send({
270
+ jsonrpc: "2.0",
271
+ id: message.id,
272
+ error: {
273
+ code: -32_000,
274
+ message: error instanceof Error ? error.message : String(error),
275
+ },
276
+ });
277
+ }
278
+ }
279
+
280
+ let buffer = Buffer.alloc(0);
281
+
282
+ process.stdin.on("data", (chunk) => {
283
+ buffer = Buffer.concat([buffer, chunk]);
284
+ while (true) {
285
+ const headerEnd = buffer.indexOf("\r\n\r\n");
286
+ if (headerEnd === -1) {
287
+ return;
288
+ }
289
+ const header = buffer.slice(0, headerEnd).toString("utf8");
290
+ const match = CONTENT_LENGTH_RE.exec(header);
291
+ if (!match) {
292
+ buffer = Buffer.alloc(0);
293
+ return;
294
+ }
295
+ const length = Number(match[1]);
296
+ const frameEnd = headerEnd + 4 + length;
297
+ if (buffer.length < frameEnd) {
298
+ return;
299
+ }
300
+ const body = buffer.slice(headerEnd + 4, frameEnd).toString("utf8");
301
+ buffer = buffer.slice(frameEnd);
302
+ handle(JSON.parse(body)).catch((error) => {
303
+ send({
304
+ jsonrpc: "2.0",
305
+ id: null,
306
+ error: {
307
+ code: -32_000,
308
+ message: error instanceof Error ? error.message : String(error),
309
+ },
310
+ });
311
+ });
312
+ }
313
+ });
314
+
315
+ if (process.argv.includes("--self-test")) {
316
+ console.log(
317
+ JSON.stringify({ tools: tools.map((tool) => tool.name) }, null, 2)
318
+ );
319
+ process.exit(0);
320
+ }
@@ -0,0 +1,51 @@
1
+ ---
2
+ description: Inspect fclt capability roots, docs, snippets, skills, agents, MCP, and automations.
3
+ tags: [fclt, capability, review, inventory]
4
+ ---
5
+
6
+ # fclt-capability-review
7
+
8
+ ## When To Use
9
+ Use this skill when Codex needs to understand what capability exists before changing it.
10
+
11
+ Use it for:
12
+
13
+ - checking global and project `.ai` roots
14
+ - finding relevant skills, snippets, instructions, agents, MCP servers, or automations
15
+ - deciding whether a change belongs in global or project scope
16
+ - checking whether managed rendering is enabled or needed
17
+ - reviewing public/private boundaries before publishing docs or pack assets
18
+
19
+ ## Workflow
20
+
21
+ ```bash
22
+ fclt status --json
23
+ fclt inventory --json
24
+ fclt list skills
25
+ fclt list instructions
26
+ fclt list snippets
27
+ fclt graph AGENTS.global.md
28
+ ```
29
+
30
+ For project work:
31
+
32
+ ```bash
33
+ fclt status --project --json
34
+ fclt inventory --project --json
35
+ ```
36
+
37
+ ## Rules
38
+
39
+ - Read existing repo guidance before proposing project capability.
40
+ - Use project scope for repo-specific commands, tests, architecture, or team workflow.
41
+ - Use global scope only for broadly reusable behavior.
42
+ - Keep generated state and review artifacts out of repo-local `.ai`.
43
+ - Prefer adding or updating the smallest unit: instruction, snippet, skill, agent, MCP config, or automation.
44
+
45
+ ## Output
46
+
47
+ - capability roots found
48
+ - relevant assets
49
+ - scope recommendation
50
+ - missing or stale capability
51
+ - safe next command