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.
- package/README.md +26 -8
- package/assets/packs/facult-operating-model/agents/evolution-planner/agent.toml +3 -0
- package/assets/packs/facult-operating-model/agents/integration-auditor/agent.toml +8 -1
- package/assets/packs/facult-operating-model/agents/scope-promoter/agent.toml +8 -1
- package/assets/packs/facult-operating-model/agents/writeback-curator/agent.toml +2 -0
- package/assets/packs/facult-operating-model/instructions/INTEGRATION.md +44 -0
- package/assets/packs/facult-operating-model/instructions/PROJECT_CAPABILITY.md +35 -0
- package/assets/packs/facult-operating-model/instructions/WORK_UNITS.md +48 -0
- package/assets/packs/facult-operating-model/skills/capability-evolution/SKILL.md +25 -6
- package/assets/packs/facult-operating-model/skills/project-operating-layer-design/SKILL.md +33 -0
- package/assets/packs/facult-operating-model/snippets/global/core/feedback-loops.md +1 -0
- package/assets/packs/facult-operating-model/snippets/global/core/work-units.md +2 -1
- package/assets/packs/facult-operating-model/{AGENTS.global.md → snippets/templates/agents-global.md} +6 -0
- package/docs/README.md +4 -0
- package/docs/assets/fclt-capability-loop.png +0 -0
- package/docs/built-in-pack.md +23 -2
- package/docs/codex-plugin.md +57 -0
- package/docs/concepts.md +4 -1
- package/docs/pack-upgrades.md +73 -0
- package/docs/reference.md +2 -2
- package/docs/roadmap.md +4 -3
- package/docs/work-units.md +96 -0
- package/package.json +5 -1
- package/plugins/fclt/.codex-plugin/plugin.json +31 -0
- package/plugins/fclt/.mcp.json +11 -0
- package/plugins/fclt/scripts/fclt-mcp.js +320 -0
- package/plugins/fclt/skills/fclt-capability-review/SKILL.md +51 -0
- package/plugins/fclt/skills/fclt-evolution/SKILL.md +65 -0
- package/plugins/fclt/skills/fclt-setup/SKILL.md +65 -0
- package/plugins/fclt/skills/fclt-writeback/SKILL.md +57 -0
- package/src/agents.ts +1 -0
- package/src/builtin-assets.ts +1 -1
- package/src/builtin.ts +22 -0
- package/src/doctor.ts +6 -2
- package/src/global-docs.ts +6 -2
- 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.
|
|
52
|
-
-
|
|
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
|
-
-
|
|
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.
|
|
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,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
|