feed-the-machine 1.0.0 → 1.2.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/bin/generate-manifest.mjs +253 -0
- package/bin/install.mjs +134 -4
- package/docs/HOOKS.md +243 -0
- package/docs/INBOX.md +233 -0
- package/ftm/SKILL.md +34 -0
- package/ftm-audit/SKILL.md +69 -0
- package/ftm-brainstorm/SKILL.md +51 -0
- package/ftm-browse/SKILL.md +39 -0
- package/ftm-capture/SKILL.md +370 -0
- package/ftm-capture.yml +4 -0
- package/ftm-codex-gate/SKILL.md +59 -0
- package/ftm-config/SKILL.md +35 -0
- package/ftm-council/SKILL.md +56 -0
- package/ftm-dashboard/SKILL.md +163 -0
- package/ftm-debug/SKILL.md +84 -0
- package/ftm-diagram/SKILL.md +44 -0
- package/ftm-executor/SKILL.md +97 -0
- package/ftm-git/SKILL.md +60 -0
- package/ftm-inbox/backend/__init__.py +0 -0
- package/ftm-inbox/backend/__pycache__/main.cpython-314.pyc +0 -0
- package/ftm-inbox/backend/adapters/__init__.py +0 -0
- package/ftm-inbox/backend/adapters/_retry.py +64 -0
- package/ftm-inbox/backend/adapters/base.py +230 -0
- package/ftm-inbox/backend/adapters/freshservice.py +104 -0
- package/ftm-inbox/backend/adapters/gmail.py +125 -0
- package/ftm-inbox/backend/adapters/jira.py +136 -0
- package/ftm-inbox/backend/adapters/registry.py +192 -0
- package/ftm-inbox/backend/adapters/slack.py +110 -0
- package/ftm-inbox/backend/db/__init__.py +0 -0
- package/ftm-inbox/backend/db/connection.py +54 -0
- package/ftm-inbox/backend/db/schema.py +78 -0
- package/ftm-inbox/backend/executor/__init__.py +7 -0
- package/ftm-inbox/backend/executor/engine.py +149 -0
- package/ftm-inbox/backend/executor/step_runner.py +98 -0
- package/ftm-inbox/backend/main.py +103 -0
- package/ftm-inbox/backend/models/__init__.py +1 -0
- package/ftm-inbox/backend/models/unified_task.py +36 -0
- package/ftm-inbox/backend/planner/__init__.py +6 -0
- package/ftm-inbox/backend/planner/__pycache__/__init__.cpython-314.pyc +0 -0
- package/ftm-inbox/backend/planner/__pycache__/generator.cpython-314.pyc +0 -0
- package/ftm-inbox/backend/planner/__pycache__/schema.cpython-314.pyc +0 -0
- package/ftm-inbox/backend/planner/generator.py +127 -0
- package/ftm-inbox/backend/planner/schema.py +34 -0
- package/ftm-inbox/backend/requirements.txt +5 -0
- package/ftm-inbox/backend/routes/__init__.py +0 -0
- package/ftm-inbox/backend/routes/__pycache__/plan.cpython-314.pyc +0 -0
- package/ftm-inbox/backend/routes/execute.py +186 -0
- package/ftm-inbox/backend/routes/health.py +52 -0
- package/ftm-inbox/backend/routes/inbox.py +68 -0
- package/ftm-inbox/backend/routes/plan.py +271 -0
- package/ftm-inbox/bin/launchagent.mjs +91 -0
- package/ftm-inbox/bin/setup.mjs +188 -0
- package/ftm-inbox/bin/start.sh +10 -0
- package/ftm-inbox/bin/status.sh +17 -0
- package/ftm-inbox/bin/stop.sh +8 -0
- package/ftm-inbox/config.example.yml +55 -0
- package/ftm-inbox/package-lock.json +2898 -0
- package/ftm-inbox/package.json +26 -0
- package/ftm-inbox/postcss.config.js +6 -0
- package/ftm-inbox/src/app.css +199 -0
- package/ftm-inbox/src/app.html +18 -0
- package/ftm-inbox/src/lib/api.ts +166 -0
- package/ftm-inbox/src/lib/components/ExecutionLog.svelte +81 -0
- package/ftm-inbox/src/lib/components/InboxFeed.svelte +143 -0
- package/ftm-inbox/src/lib/components/PlanStep.svelte +271 -0
- package/ftm-inbox/src/lib/components/PlanView.svelte +206 -0
- package/ftm-inbox/src/lib/components/StreamPanel.svelte +99 -0
- package/ftm-inbox/src/lib/components/TaskCard.svelte +190 -0
- package/ftm-inbox/src/lib/components/ui/EmptyState.svelte +63 -0
- package/ftm-inbox/src/lib/components/ui/KawaiiCard.svelte +86 -0
- package/ftm-inbox/src/lib/components/ui/PillButton.svelte +106 -0
- package/ftm-inbox/src/lib/components/ui/StatusBadge.svelte +67 -0
- package/ftm-inbox/src/lib/components/ui/StreamDrawer.svelte +149 -0
- package/ftm-inbox/src/lib/components/ui/ThemeToggle.svelte +80 -0
- package/ftm-inbox/src/lib/theme.ts +47 -0
- package/ftm-inbox/src/routes/+layout.svelte +76 -0
- package/ftm-inbox/src/routes/+page.svelte +401 -0
- package/ftm-inbox/static/favicon.png +0 -0
- package/ftm-inbox/svelte.config.js +12 -0
- package/ftm-inbox/tailwind.config.ts +63 -0
- package/ftm-inbox/tsconfig.json +13 -0
- package/ftm-inbox/vite.config.ts +6 -0
- package/ftm-intent/SKILL.md +44 -0
- package/ftm-manifest.json +3794 -0
- package/ftm-map/SKILL.md +259 -0
- package/ftm-map/scripts/db.py +391 -0
- package/ftm-map/scripts/index.py +341 -0
- package/ftm-map/scripts/parser.py +455 -0
- package/ftm-map/scripts/queries/.gitkeep +0 -0
- package/ftm-map/scripts/queries/javascript-tags.scm +23 -0
- package/ftm-map/scripts/queries/python-tags.scm +17 -0
- package/ftm-map/scripts/queries/typescript-tags.scm +29 -0
- package/ftm-map/scripts/query.py +149 -0
- package/ftm-map/scripts/requirements.txt +2 -0
- package/ftm-map/scripts/setup-hooks.sh +27 -0
- package/ftm-map/scripts/setup.sh +45 -0
- package/ftm-map/scripts/test_db.py +124 -0
- package/ftm-map/scripts/test_parser.py +106 -0
- package/ftm-map/scripts/test_query.py +66 -0
- package/ftm-map/scripts/tests/fixtures/__init__.py +0 -0
- package/ftm-map/scripts/tests/fixtures/sample_project/api.ts +16 -0
- package/ftm-map/scripts/tests/fixtures/sample_project/auth.py +15 -0
- package/ftm-map/scripts/tests/fixtures/sample_project/utils.js +16 -0
- package/ftm-map/scripts/views.py +545 -0
- package/ftm-mind/SKILL.md +173 -66
- package/ftm-pause/SKILL.md +43 -0
- package/ftm-researcher/SKILL.md +275 -0
- package/ftm-researcher/evals/agent-diversity.yaml +17 -0
- package/ftm-researcher/evals/synthesis-quality.yaml +12 -0
- package/ftm-researcher/evals/trigger-accuracy.yaml +39 -0
- package/ftm-researcher/references/adaptive-search.md +116 -0
- package/ftm-researcher/references/agent-prompts.md +193 -0
- package/ftm-researcher/references/council-integration.md +193 -0
- package/ftm-researcher/references/output-format.md +203 -0
- package/ftm-researcher/references/synthesis-pipeline.md +165 -0
- package/ftm-researcher/scripts/score_credibility.py +234 -0
- package/ftm-researcher/scripts/validate_research.py +92 -0
- package/ftm-resume/SKILL.md +47 -0
- package/ftm-retro/SKILL.md +54 -0
- package/ftm-routine/SKILL.md +170 -0
- package/ftm-state/blackboard/capabilities.json +5 -0
- package/ftm-state/blackboard/capabilities.schema.json +27 -0
- package/ftm-upgrade/SKILL.md +41 -0
- package/ftm-upgrade/scripts/check-version.sh +1 -1
- package/ftm-upgrade/scripts/upgrade.sh +1 -1
- package/hooks/ftm-blackboard-enforcer.sh +94 -0
- package/hooks/ftm-discovery-reminder.sh +90 -0
- package/hooks/ftm-drafts-gate.sh +61 -0
- package/hooks/ftm-event-logger.mjs +107 -0
- package/hooks/ftm-map-autodetect.sh +79 -0
- package/hooks/ftm-pending-sync-check.sh +22 -0
- package/hooks/ftm-plan-gate.sh +96 -0
- package/hooks/ftm-post-commit-trigger.sh +57 -0
- package/hooks/settings-template.json +81 -0
- package/install.sh +140 -11
- package/package.json +12 -2
package/docs/INBOX.md
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# ftm-inbox
|
|
2
|
+
|
|
3
|
+
ftm-inbox is an optional background service that polls your work tools (Jira, Freshservice, Slack, Gmail) and surfaces actionable items directly inside the FTM Operator Cockpit dashboard. It runs locally on your machine and never sends data to external services.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
Without ftm-inbox, the Operator Cockpit is a static interface. With it:
|
|
8
|
+
|
|
9
|
+
- Jira issues assigned to you appear as inbox items
|
|
10
|
+
- Freshservice tickets awaiting your response are surfaced
|
|
11
|
+
- Slack DMs and mentions are queued for triage
|
|
12
|
+
- Gmail threads that match configurable filters are included
|
|
13
|
+
|
|
14
|
+
Each item is stored in a local SQLite database. The FTM skills (`/ftm-mind`, `/ftm-executor`) can read from this inbox to generate plans and take action on your behalf.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx feed-the-machine --with-inbox
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This will:
|
|
23
|
+
|
|
24
|
+
1. Install core FTM skills (same as `npx feed-the-machine`)
|
|
25
|
+
2. Copy `ftm-inbox/` to `~/.claude/ftm-inbox/`
|
|
26
|
+
3. Run `npm install` for Node dependencies
|
|
27
|
+
4. Run `pip3 install -r requirements.txt` for Python dependencies
|
|
28
|
+
5. Launch the interactive setup wizard
|
|
29
|
+
6. Optionally install a macOS LaunchAgent for auto-start on login
|
|
30
|
+
|
|
31
|
+
The core `npx feed-the-machine` install (without `--with-inbox`) is completely unchanged.
|
|
32
|
+
|
|
33
|
+
### Requirements
|
|
34
|
+
|
|
35
|
+
- Node.js 18+
|
|
36
|
+
- Python 3.9+
|
|
37
|
+
- `pip3` in PATH
|
|
38
|
+
|
|
39
|
+
## Configuration
|
|
40
|
+
|
|
41
|
+
The setup wizard writes credentials to `~/.claude/ftm-inbox/config.yml`. This directory is outside any git repository and should never be committed.
|
|
42
|
+
|
|
43
|
+
### config.yml reference
|
|
44
|
+
|
|
45
|
+
```yaml
|
|
46
|
+
server:
|
|
47
|
+
port: 8042 # Port for the local API (default: 8042)
|
|
48
|
+
|
|
49
|
+
adapters:
|
|
50
|
+
jira:
|
|
51
|
+
enabled: true
|
|
52
|
+
base_url: "https://yourorg.atlassian.net"
|
|
53
|
+
email: "you@example.com"
|
|
54
|
+
api_token: "your-jira-api-token"
|
|
55
|
+
poll_interval_seconds: 60
|
|
56
|
+
|
|
57
|
+
freshservice:
|
|
58
|
+
enabled: true
|
|
59
|
+
domain: "yourorg.freshservice.com"
|
|
60
|
+
api_key: "your-freshservice-api-key"
|
|
61
|
+
poll_interval_seconds: 120
|
|
62
|
+
|
|
63
|
+
slack:
|
|
64
|
+
enabled: true
|
|
65
|
+
bot_token: "xoxb-your-slack-bot-token"
|
|
66
|
+
poll_interval_seconds: 30
|
|
67
|
+
|
|
68
|
+
gmail:
|
|
69
|
+
enabled: false
|
|
70
|
+
credentials_path: "~/credentials.json"
|
|
71
|
+
poll_interval_seconds: 120
|
|
72
|
+
|
|
73
|
+
database:
|
|
74
|
+
path: "~/.claude/ftm-inbox/inbox.db"
|
|
75
|
+
|
|
76
|
+
logging:
|
|
77
|
+
level: "INFO"
|
|
78
|
+
path: "~/.claude/ftm-inbox/logs"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
To re-run the wizard after initial setup:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
node ~/.claude/ftm-inbox/bin/setup.mjs
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
To edit manually:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
$EDITOR ~/.claude/ftm-inbox/config.yml
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Starting and Stopping
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Start the service
|
|
97
|
+
~/.claude/ftm-inbox/bin/start.sh
|
|
98
|
+
|
|
99
|
+
# Stop the service
|
|
100
|
+
~/.claude/ftm-inbox/bin/stop.sh
|
|
101
|
+
|
|
102
|
+
# Check status and last poll times
|
|
103
|
+
~/.claude/ftm-inbox/bin/status.sh
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The port can be overridden at runtime:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
FTM_INBOX_PORT=9000 ~/.claude/ftm-inbox/bin/start.sh
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Auto-start on Login (macOS)
|
|
113
|
+
|
|
114
|
+
To generate and load a LaunchAgent that starts ftm-inbox on login:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
node ~/.claude/ftm-inbox/bin/launchagent.mjs
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
This creates `~/Library/LaunchAgents/com.ftm.inbox.plist` and loads it immediately. Logs are written to `~/.claude/ftm-inbox/logs/`.
|
|
121
|
+
|
|
122
|
+
To remove the LaunchAgent:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
launchctl unload ~/Library/LaunchAgents/com.ftm.inbox.plist
|
|
126
|
+
rm ~/Library/LaunchAgents/com.ftm.inbox.plist
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Architecture
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
External Services ftm-inbox FTM Skills
|
|
133
|
+
────────────────── ───────────────────────── ──────────────────
|
|
134
|
+
Jira REST API ──────► Jira Adapter (poller) ─┐
|
|
135
|
+
Freshservice API ──────► Freshservice Adapter ─┤► SQLite DB ──► FastAPI ──► /ftm-mind
|
|
136
|
+
Slack API ──────► Slack Adapter ─┤ inbox.db 8042 /ftm-executor
|
|
137
|
+
Gmail API ──────► Gmail Adapter ─┘
|
|
138
|
+
▲
|
|
139
|
+
│
|
|
140
|
+
Svelte Dashboard
|
|
141
|
+
(Operator Cockpit)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
- **Adapters** poll their respective APIs on configurable intervals and write normalized `InboxItem` records to SQLite
|
|
145
|
+
- **FastAPI backend** (`backend/main.py`) exposes a REST API at `http://localhost:8042`
|
|
146
|
+
- **Svelte dashboard** reads from the API and renders the Operator Cockpit UI
|
|
147
|
+
- **FTM skills** use the API to read inbox items and generate or execute plans
|
|
148
|
+
|
|
149
|
+
## Adding a Custom Poller
|
|
150
|
+
|
|
151
|
+
1. Create a new file in `ftm-inbox/backend/adapters/`:
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
# ftm-inbox/backend/adapters/my_service.py
|
|
155
|
+
from .base import BaseAdapter, InboxItem
|
|
156
|
+
from typing import List
|
|
157
|
+
|
|
158
|
+
class MyServiceAdapter(BaseAdapter):
|
|
159
|
+
name = "my_service"
|
|
160
|
+
|
|
161
|
+
async def fetch(self) -> List[InboxItem]:
|
|
162
|
+
# Hit your API, return a list of InboxItem objects
|
|
163
|
+
items = []
|
|
164
|
+
# ... your logic here ...
|
|
165
|
+
return items
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
2. Add credentials to `~/.claude/ftm-inbox/config.yml`:
|
|
169
|
+
|
|
170
|
+
```yaml
|
|
171
|
+
adapters:
|
|
172
|
+
my_service:
|
|
173
|
+
enabled: true
|
|
174
|
+
api_key: "your-key"
|
|
175
|
+
poll_interval_seconds: 60
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
3. Register it in `ftm-inbox/backend/adapters/__init__.py`:
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
from .my_service import MyServiceAdapter
|
|
182
|
+
ADAPTERS = [..., MyServiceAdapter]
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
4. Restart the service: `~/.claude/ftm-inbox/bin/stop.sh && ~/.claude/ftm-inbox/bin/start.sh`
|
|
186
|
+
|
|
187
|
+
## Troubleshooting
|
|
188
|
+
|
|
189
|
+
### Service won't start
|
|
190
|
+
|
|
191
|
+
Check that Python 3 and uvicorn are installed:
|
|
192
|
+
```bash
|
|
193
|
+
python3 --version
|
|
194
|
+
python3 -c "import uvicorn; print(uvicorn.__version__)"
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
If uvicorn is missing:
|
|
198
|
+
```bash
|
|
199
|
+
pip3 install -r ~/.claude/ftm-inbox/requirements.txt
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### No items appearing in the dashboard
|
|
203
|
+
|
|
204
|
+
1. Check the service is running: `~/.claude/ftm-inbox/bin/status.sh`
|
|
205
|
+
2. Check logs: `tail -f ~/.claude/ftm-inbox/logs/*.log`
|
|
206
|
+
3. Verify credentials in `~/.claude/ftm-inbox/config.yml`
|
|
207
|
+
4. Confirm the adapter is set to `enabled: true`
|
|
208
|
+
|
|
209
|
+
### Port conflict
|
|
210
|
+
|
|
211
|
+
If port 8042 is already in use:
|
|
212
|
+
```bash
|
|
213
|
+
FTM_INBOX_PORT=9042 ~/.claude/ftm-inbox/bin/start.sh
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Update `config.yml` to match so the dashboard connects to the right port.
|
|
217
|
+
|
|
218
|
+
### Jira authentication errors
|
|
219
|
+
|
|
220
|
+
Jira Cloud requires an API token, not your password. Generate one at:
|
|
221
|
+
`https://id.atlassian.com/manage-profile/security/api-tokens`
|
|
222
|
+
|
|
223
|
+
### Freshservice 403 errors
|
|
224
|
+
|
|
225
|
+
Ensure the API key belongs to an agent with at least Viewer permissions on the relevant groups.
|
|
226
|
+
|
|
227
|
+
### Re-running setup
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
node ~/.claude/ftm-inbox/bin/setup.mjs
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
This overwrites `~/.claude/ftm-inbox/config.yml` but does not touch the database.
|
package/ftm/SKILL.md
CHANGED
|
@@ -33,6 +33,7 @@ If input starts with a recognized skill name, route directly to that skill:
|
|
|
33
33
|
| `upgrade` | ftm-upgrade |
|
|
34
34
|
| `retro` | ftm-retro |
|
|
35
35
|
| `config` | ftm-config |
|
|
36
|
+
| `capture`, `codify`, `save as routine` | ftm-capture |
|
|
36
37
|
| `mind` | ftm-mind |
|
|
37
38
|
|
|
38
39
|
When routing to a specific skill:
|
|
@@ -77,6 +78,7 @@ FTM Skills:
|
|
|
77
78
|
/ftm upgrade — Check for and install skill updates
|
|
78
79
|
/ftm retro — Post-execution retrospective
|
|
79
80
|
/ftm config — View and edit ftm configuration
|
|
81
|
+
/ftm capture [name] — Extract routine + playbook from current session
|
|
80
82
|
|
|
81
83
|
Or just describe what you need and ftm-mind will handle it.
|
|
82
84
|
```
|
|
@@ -86,3 +88,35 @@ Or just describe what you need and ftm-mind will handle it.
|
|
|
86
88
|
- Do not attempt to do the work yourself — route only.
|
|
87
89
|
- Be fast — decisive routing, not conversation.
|
|
88
90
|
- Case insensitive matching for all prefix detection.
|
|
91
|
+
|
|
92
|
+
## Requirements
|
|
93
|
+
|
|
94
|
+
- config: `~/.claude/ftm-config.yml` | optional | legacy_router_fallback setting
|
|
95
|
+
- reference: `~/.claude/ftm-state/blackboard/context.json` | optional | session state for blackboard update on routing
|
|
96
|
+
- tool: none beyond skill invocation mechanism
|
|
97
|
+
|
|
98
|
+
## Risk
|
|
99
|
+
|
|
100
|
+
- level: read_only
|
|
101
|
+
- scope: reads blackboard context.json and updates session_metadata.skills_invoked before routing; does not modify any project files
|
|
102
|
+
- rollback: no mutations to reverse; blackboard update is a metadata append
|
|
103
|
+
|
|
104
|
+
## Approval Gates
|
|
105
|
+
|
|
106
|
+
- trigger: ftm-mind failure AND legacy_router_fallback enabled | action: fall back to keyword routing automatically (no user gate needed)
|
|
107
|
+
- complexity_routing: micro → auto | small → auto | medium → auto | large → auto | xl → auto
|
|
108
|
+
|
|
109
|
+
## Fallbacks
|
|
110
|
+
|
|
111
|
+
- condition: ftm-mind fails or times out | action: check legacy_router_fallback in ftm-config.yml; if true, use keyword matching; if false, report failure
|
|
112
|
+
- condition: blackboard context.json missing | action: skip blackboard update, proceed with routing
|
|
113
|
+
- condition: skill tool unavailable for target skill | action: report routing failure to user with the target skill name
|
|
114
|
+
|
|
115
|
+
## Capabilities
|
|
116
|
+
|
|
117
|
+
- env: none required
|
|
118
|
+
|
|
119
|
+
## Event Payloads
|
|
120
|
+
|
|
121
|
+
### (none)
|
|
122
|
+
ftm is a pure router and does not emit events directly. Events are emitted by the target skill after routing.
|
package/ftm-audit/SKILL.md
CHANGED
|
@@ -144,3 +144,72 @@ After completing:
|
|
|
144
144
|
## Report Format
|
|
145
145
|
|
|
146
146
|
See `references/templates/REPORT-FORMAT.md` for the full report template (summary, changelog table, layer-by-layer finding format with examples).
|
|
147
|
+
|
|
148
|
+
## Requirements
|
|
149
|
+
|
|
150
|
+
- tool: `knip` | optional | static dead-code and unused-export analysis (Layer 1)
|
|
151
|
+
- tool: `node` | required | runtime for knip via npx
|
|
152
|
+
- config: `knip.config.ts` | optional | custom knip configuration at project root
|
|
153
|
+
- reference: `references/protocols/PROJECT-PATTERNS.md` | required | framework detection table and dimension activation matrix
|
|
154
|
+
- reference: `references/strategies/AUTO-FIX-STRATEGIES.md` | required | fix actions by finding type
|
|
155
|
+
- reference: `references/protocols/WIRING-CONTRACTS.md` | optional | wiring contract schema for plan-driven audits
|
|
156
|
+
- reference: `references/protocols/RUNTIME-WIRING.md` | optional | runtime verification protocol
|
|
157
|
+
- reference: `references/templates/REPORT-FORMAT.md` | required | structured report template
|
|
158
|
+
- tool: `$HOME/.claude/skills/ftm-browse/bin/ftm-browse` | optional | runtime wiring verification via browser (Phase 3)
|
|
159
|
+
|
|
160
|
+
## Risk
|
|
161
|
+
|
|
162
|
+
- level: medium_write
|
|
163
|
+
- scope: modifies source files to fix wiring issues (auto-fix layer); also adds/removes imports and route registrations; reads codebase broadly
|
|
164
|
+
- rollback: git checkout on auto-fixed files; all changes are tracked in the changelog report before being applied
|
|
165
|
+
|
|
166
|
+
## Approval Gates
|
|
167
|
+
|
|
168
|
+
- trigger: auto-fix proposed for a finding | action: report proposed change before applying (show "Proposed: ..." format)
|
|
169
|
+
- trigger: finding flagged MANUAL_INTERVENTION_NEEDED | action: surface to user with suggested action, do not auto-fix
|
|
170
|
+
- trigger: re-verification still fails after 3 iterations | action: stop and report remaining issues to user
|
|
171
|
+
- complexity_routing: micro → auto | small → auto | medium → plan_first | large → plan_first | xl → always_ask
|
|
172
|
+
|
|
173
|
+
## Fallbacks
|
|
174
|
+
|
|
175
|
+
- condition: knip not installed and npx unavailable | action: skip Layer 1, run Layer 2 adversarial audit only
|
|
176
|
+
- condition: no package.json found | action: skip knip entirely, run adversarial audit only
|
|
177
|
+
- condition: ftm-browse not installed | action: skip Phase 3 runtime wiring check, log reason and continue
|
|
178
|
+
- condition: dev server not running | action: skip Phase 3 runtime wiring check, log reason and continue
|
|
179
|
+
- condition: wiring contracts absent | action: run pure Layer 1 + Layer 2 analysis without contract checking
|
|
180
|
+
- condition: project has no identifiable entry point | action: skip knip, run adversarial audit only
|
|
181
|
+
|
|
182
|
+
## Capabilities
|
|
183
|
+
|
|
184
|
+
- cli: `knip` | optional | dead code detection via npx knip
|
|
185
|
+
- cli: `node` | required | JavaScript runtime for npx
|
|
186
|
+
- cli: `$HOME/.claude/skills/ftm-browse/bin/ftm-browse` | optional | headless browser for runtime wiring
|
|
187
|
+
- mcp: `git` | optional | diff scope for Layer 2 adversarial audit
|
|
188
|
+
|
|
189
|
+
## Event Payloads
|
|
190
|
+
|
|
191
|
+
### audit_complete
|
|
192
|
+
- skill: string — "ftm-audit"
|
|
193
|
+
- findings_count: number — total issues found across all layers
|
|
194
|
+
- auto_fixed_count: number — issues auto-remediated by Layer 3
|
|
195
|
+
- manual_count: number — issues requiring manual intervention
|
|
196
|
+
- scope: string[] — file paths audited
|
|
197
|
+
- duration_ms: number — total audit duration
|
|
198
|
+
- layers_run: string[] — which layers executed (e.g., ["layer1", "layer2", "layer3"])
|
|
199
|
+
|
|
200
|
+
### issue_found
|
|
201
|
+
- skill: string — "ftm-audit"
|
|
202
|
+
- layer: string — "layer1" | "layer2" | "layer3"
|
|
203
|
+
- dimension: string — D1 | D2 | D3 | D4 | D5 (for Layer 2 findings)
|
|
204
|
+
- finding_type: string — exports | types | duplicates | UNWIRED_COMPONENT | etc.
|
|
205
|
+
- file_path: string — affected file
|
|
206
|
+
- symbol: string — affected symbol name
|
|
207
|
+
- severity: string — CRITICAL | HIGH | MEDIUM | LOW
|
|
208
|
+
- auto_fixable: boolean — whether Layer 3 can fix this automatically
|
|
209
|
+
|
|
210
|
+
### task_completed
|
|
211
|
+
- skill: string — "ftm-audit"
|
|
212
|
+
- result: string — "pass" | "pass_with_fixes" | "fail"
|
|
213
|
+
- findings_count: number — total findings
|
|
214
|
+
- auto_fixed_count: number — auto-remediated count
|
|
215
|
+
- manual_count: number — manual intervention needed
|
package/ftm-brainstorm/SKILL.md
CHANGED
|
@@ -377,3 +377,54 @@ After completing, update:
|
|
|
377
377
|
3. Update `experiences/index.json` with the new entry
|
|
378
378
|
4. Emit `plan_generated` with `{ plan_path, plan_title, task_count, wave_count }` (if Phase 3 completed)
|
|
379
379
|
5. Emit `task_completed` with `{ task_title, plan_path, duration_ms }`
|
|
380
|
+
|
|
381
|
+
## Requirements
|
|
382
|
+
|
|
383
|
+
- config: `~/.claude/ftm-config.yml` | optional | model profile for planning agents
|
|
384
|
+
- reference: `references/agent-prompts.md` | required | research agent prompt templates
|
|
385
|
+
- reference: `references/plan-template.md` | required | plan document generation template
|
|
386
|
+
- reference: `~/.claude/ftm-state/blackboard/context.json` | optional | session state and active constraints
|
|
387
|
+
- reference: `~/.claude/ftm-state/blackboard/experiences/index.json` | optional | past brainstorm lessons
|
|
388
|
+
- reference: `~/.claude/ftm-state/blackboard/patterns.json` | optional | execution and user behavior patterns
|
|
389
|
+
|
|
390
|
+
## Risk
|
|
391
|
+
|
|
392
|
+
- level: low_write
|
|
393
|
+
- scope: writes plan documents to ~/.claude/plans/; writes blackboard context and experience files; does not modify project source code
|
|
394
|
+
- rollback: delete generated plan file; blackboard writes can be reverted by editing JSON files
|
|
395
|
+
|
|
396
|
+
## Approval Gates
|
|
397
|
+
|
|
398
|
+
- trigger: Phase 3 plan generation ready | action: present "Here's what I think we've landed on" summary and wait for explicit user approval before generating plan
|
|
399
|
+
- trigger: plan document generated | action: present plan incrementally (vision → tasks → agents/waves) and get approval at each step
|
|
400
|
+
- trigger: research returns thin results on all agents | action: note research gaps, present fewer suggestions, do not fabricate citations
|
|
401
|
+
- complexity_routing: micro → auto | small → auto | medium → plan_first | large → plan_first | xl → always_ask
|
|
402
|
+
|
|
403
|
+
## Fallbacks
|
|
404
|
+
|
|
405
|
+
- condition: ftm-researcher not available | action: dispatch 3 direct parallel research agents (web/github/competitive) using built-in prompts from references/agent-prompts.md
|
|
406
|
+
- condition: no git repo detected in Phase 0 | action: skip repo scan, ask about tech stack during intake
|
|
407
|
+
- condition: blackboard missing or empty | action: proceed without experience-informed shortcuts, rely on direct analysis
|
|
408
|
+
- condition: ftm-config.yml missing | action: use session default model for all agents
|
|
409
|
+
|
|
410
|
+
## Capabilities
|
|
411
|
+
|
|
412
|
+
- mcp: `WebSearch` | optional | web research agents use for blog posts and case studies
|
|
413
|
+
- mcp: `WebFetch` | optional | GitHub exploration and competitive analysis
|
|
414
|
+
- mcp: `sequential-thinking` | optional | complex trade-off analysis during synthesis
|
|
415
|
+
- env: none required
|
|
416
|
+
|
|
417
|
+
## Event Payloads
|
|
418
|
+
|
|
419
|
+
### plan_generated
|
|
420
|
+
- skill: string — "ftm-brainstorm"
|
|
421
|
+
- plan_path: string — absolute path to generated plan file
|
|
422
|
+
- plan_title: string — human-readable plan title
|
|
423
|
+
- task_count: number — total tasks in the plan
|
|
424
|
+
- wave_count: number — number of parallel execution waves
|
|
425
|
+
|
|
426
|
+
### task_completed
|
|
427
|
+
- skill: string — "ftm-brainstorm"
|
|
428
|
+
- task_title: string — title of the brainstorm topic
|
|
429
|
+
- plan_path: string | null — path to generated plan if Phase 3 completed
|
|
430
|
+
- duration_ms: number — total session duration
|
package/ftm-browse/SKILL.md
CHANGED
|
@@ -413,3 +413,42 @@ When ftm-browse is used directly (not within a plan), supervised mode is OFF by
|
|
|
413
413
|
- The daemon uses a 1280x800 headless Chromium viewport with a standard Mac Chrome user-agent, so most sites render predictably.
|
|
414
414
|
- To stop the daemon explicitly: `$PB stop`. It will auto-restart on next use.
|
|
415
415
|
- `$PB eval` is the escape hatch for anything the ARIA tree doesn't expose — hidden inputs, JS globals, localStorage, computed values.
|
|
416
|
+
|
|
417
|
+
## Requirements
|
|
418
|
+
|
|
419
|
+
- tool: `$HOME/.claude/skills/ftm-browse/bin/ftm-browse` | required | headless browser CLI binary
|
|
420
|
+
- tool: `npx playwright install chromium` | required | Chromium browser engine (first-time setup)
|
|
421
|
+
- reference: none required
|
|
422
|
+
|
|
423
|
+
## Risk
|
|
424
|
+
|
|
425
|
+
- level: low_write
|
|
426
|
+
- scope: navigates browser, takes screenshots saved to ~/.ftm-browse/screenshots/; does not modify project source files; form fills and clicks can have side effects on the target application
|
|
427
|
+
- rollback: no project file mutations; browser interactions on local dev servers are typically reversible by reloading
|
|
428
|
+
|
|
429
|
+
## Approval Gates
|
|
430
|
+
|
|
431
|
+
- trigger: auth redirect detected during supervised execution | action: STOP immediately, present options (retry/skip/abort/manual), wait for user choice
|
|
432
|
+
- trigger: unexpected browser state during plan step | action: STOP, take screenshot, present situation to user, wait for explicit choice
|
|
433
|
+
- trigger: supervised mode enabled AND state mismatch detected | action: halt and report before proceeding
|
|
434
|
+
- complexity_routing: micro → auto | small → auto | medium → auto | large → auto | xl → auto
|
|
435
|
+
|
|
436
|
+
## Fallbacks
|
|
437
|
+
|
|
438
|
+
- condition: daemon binary not found at expected path | action: report installation instructions and stop
|
|
439
|
+
- condition: Chromium not installed | action: instruct user to run "npx playwright install chromium" and stop
|
|
440
|
+
- condition: daemon fails to start within 10 seconds | action: check ~/.ftm-browse/ logs, report binary or Bun issue
|
|
441
|
+
- condition: dev server not running when navigating to localhost | action: report timeout error with the URL attempted
|
|
442
|
+
- condition: stale ref after navigation | action: re-run snapshot -i before retrying click/fill
|
|
443
|
+
|
|
444
|
+
## Capabilities
|
|
445
|
+
|
|
446
|
+
- cli: `$HOME/.claude/skills/ftm-browse/bin/ftm-browse` | required | headless Chromium control CLI
|
|
447
|
+
|
|
448
|
+
## Event Payloads
|
|
449
|
+
|
|
450
|
+
### task_completed
|
|
451
|
+
- skill: string — "ftm-browse"
|
|
452
|
+
- workflow: string — description of the visual verification or interaction performed
|
|
453
|
+
- screenshots: string[] — absolute paths to screenshots taken
|
|
454
|
+
- duration_ms: number — total workflow duration
|