feed-the-machine 1.1.0 → 1.3.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 +372 -26
- 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 +34 -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/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/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/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 +50 -0
- package/ftm-mind/SKILL.md +173 -66
- package/ftm-pause/SKILL.md +43 -0
- package/ftm-researcher/SKILL.md +55 -0
- package/ftm-resume/SKILL.md +47 -0
- package/ftm-retro/SKILL.md +54 -0
- package/ftm-routine/SKILL.md +36 -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/hooks/ftm-blackboard-enforcer.sh +28 -27
- package/hooks/ftm-plan-gate.sh +21 -25
- package/install.sh +238 -111
- package/package.json +6 -2
package/install.sh
CHANGED
|
@@ -3,11 +3,13 @@ set -euo pipefail
|
|
|
3
3
|
|
|
4
4
|
# FTM Skills Installer
|
|
5
5
|
# Creates symlinks from this repo into ~/.claude/skills/ so slash commands work.
|
|
6
|
-
#
|
|
6
|
+
# Installs hooks, merges them into settings.json, and verifies the result.
|
|
7
|
+
# Safe to re-run — idempotent.
|
|
7
8
|
#
|
|
8
9
|
# Usage:
|
|
9
|
-
# ./install.sh #
|
|
10
|
-
# ./install.sh --
|
|
10
|
+
# ./install.sh # Full install (skills + hooks + settings merge)
|
|
11
|
+
# ./install.sh --no-hooks # Skills and state only, skip hooks entirely
|
|
12
|
+
# ./install.sh --skip-merge # Install hook files but don't touch settings.json
|
|
11
13
|
|
|
12
14
|
REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
13
15
|
SKILLS_DIR="$HOME/.claude/skills"
|
|
@@ -16,13 +18,64 @@ CONFIG_DIR="$HOME/.claude"
|
|
|
16
18
|
HOOKS_DIR="$HOME/.claude/hooks"
|
|
17
19
|
SETTINGS_FILE="$CONFIG_DIR/settings.json"
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
NO_HOOKS=false
|
|
22
|
+
SKIP_MERGE=false
|
|
20
23
|
for arg in "$@"; do
|
|
21
24
|
case "$arg" in
|
|
22
|
-
--
|
|
25
|
+
--no-hooks) NO_HOOKS=true ;;
|
|
26
|
+
--skip-merge) SKIP_MERGE=true ;;
|
|
27
|
+
# Keep --setup-hooks for backwards compat (now a no-op since merge is default)
|
|
28
|
+
--setup-hooks) ;;
|
|
23
29
|
esac
|
|
24
30
|
done
|
|
25
31
|
|
|
32
|
+
WARN_COUNT=0
|
|
33
|
+
warn() {
|
|
34
|
+
echo " WARN: $1"
|
|
35
|
+
WARN_COUNT=$((WARN_COUNT + 1))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# --- Preflight Checks ---
|
|
39
|
+
|
|
40
|
+
echo "Preflight checks..."
|
|
41
|
+
|
|
42
|
+
# Check jq (required for hooks and settings merge)
|
|
43
|
+
if ! command -v jq &>/dev/null; then
|
|
44
|
+
if [ "$NO_HOOKS" = true ]; then
|
|
45
|
+
echo " jq not found (ok — hooks skipped)"
|
|
46
|
+
else
|
|
47
|
+
echo ""
|
|
48
|
+
echo " ERROR: jq is required for FTM hooks."
|
|
49
|
+
echo ""
|
|
50
|
+
echo " Install it:"
|
|
51
|
+
echo " macOS: brew install jq"
|
|
52
|
+
echo " Ubuntu: sudo apt-get install jq"
|
|
53
|
+
echo " Alpine: apk add jq"
|
|
54
|
+
echo ""
|
|
55
|
+
echo " Or skip hooks: ./install.sh --no-hooks"
|
|
56
|
+
exit 1
|
|
57
|
+
fi
|
|
58
|
+
else
|
|
59
|
+
echo " jq: $(jq --version)"
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Check node (required for event logger hook)
|
|
63
|
+
if ! command -v node &>/dev/null; then
|
|
64
|
+
if [ "$NO_HOOKS" = true ]; then
|
|
65
|
+
echo " node not found (ok — hooks skipped)"
|
|
66
|
+
else
|
|
67
|
+
echo ""
|
|
68
|
+
echo " ERROR: Node.js is required for the FTM event logger hook."
|
|
69
|
+
echo ""
|
|
70
|
+
echo " Install it: https://nodejs.org/"
|
|
71
|
+
echo " Or skip hooks: ./install.sh --no-hooks"
|
|
72
|
+
exit 1
|
|
73
|
+
fi
|
|
74
|
+
else
|
|
75
|
+
echo " node: $(node --version)"
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
echo ""
|
|
26
79
|
echo "Installing FTM skills from: $REPO_DIR"
|
|
27
80
|
echo "Linking into: $SKILLS_DIR"
|
|
28
81
|
echo ""
|
|
@@ -98,134 +151,208 @@ fi
|
|
|
98
151
|
|
|
99
152
|
# --- Hooks ---
|
|
100
153
|
|
|
101
|
-
|
|
102
|
-
echo "Installing hooks..."
|
|
103
|
-
|
|
104
|
-
if [ -d "$REPO_DIR/hooks" ]; then
|
|
105
|
-
mkdir -p "$HOOKS_DIR"
|
|
106
|
-
HOOK_COUNT=0
|
|
107
|
-
|
|
108
|
-
# Install shell hooks
|
|
109
|
-
for hook in "$REPO_DIR/hooks"/ftm-*.sh; do
|
|
110
|
-
[ -f "$hook" ] || continue
|
|
111
|
-
name=$(basename "$hook")
|
|
112
|
-
target="$HOOKS_DIR/$name"
|
|
113
|
-
if [ -f "$target" ]; then
|
|
114
|
-
cp "$hook" "$target"
|
|
115
|
-
chmod +x "$target"
|
|
116
|
-
echo " UPDATE $name"
|
|
117
|
-
else
|
|
118
|
-
cp "$hook" "$target"
|
|
119
|
-
chmod +x "$target"
|
|
120
|
-
echo " INSTALL $name"
|
|
121
|
-
fi
|
|
122
|
-
HOOK_COUNT=$((HOOK_COUNT + 1))
|
|
123
|
-
done
|
|
124
|
-
|
|
125
|
-
# Install Node.js hooks
|
|
126
|
-
for hook in "$REPO_DIR/hooks"/ftm-*.mjs; do
|
|
127
|
-
[ -f "$hook" ] || continue
|
|
128
|
-
name=$(basename "$hook")
|
|
129
|
-
target="$HOOKS_DIR/$name"
|
|
130
|
-
if [ -f "$target" ]; then
|
|
131
|
-
cp "$hook" "$target"
|
|
132
|
-
echo " UPDATE $name"
|
|
133
|
-
else
|
|
134
|
-
cp "$hook" "$target"
|
|
135
|
-
echo " INSTALL $name"
|
|
136
|
-
fi
|
|
137
|
-
HOOK_COUNT=$((HOOK_COUNT + 1))
|
|
138
|
-
done
|
|
154
|
+
HOOK_COUNT=0
|
|
139
155
|
|
|
156
|
+
if [ "$NO_HOOKS" = true ]; then
|
|
140
157
|
echo ""
|
|
141
|
-
echo "
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
# --- Hook Config Merge (--setup-hooks) ---
|
|
145
|
-
|
|
146
|
-
if [ "$SETUP_HOOKS" = true ]; then
|
|
158
|
+
echo "Skipping hooks (--no-hooks)."
|
|
159
|
+
else
|
|
147
160
|
echo ""
|
|
148
|
-
echo "
|
|
161
|
+
echo "Installing hooks..."
|
|
162
|
+
|
|
163
|
+
if [ -d "$REPO_DIR/hooks" ]; then
|
|
164
|
+
mkdir -p "$HOOKS_DIR"
|
|
165
|
+
|
|
166
|
+
# Install shell hooks
|
|
167
|
+
for hook in "$REPO_DIR/hooks"/ftm-*.sh; do
|
|
168
|
+
[ -f "$hook" ] || continue
|
|
169
|
+
name=$(basename "$hook")
|
|
170
|
+
target="$HOOKS_DIR/$name"
|
|
171
|
+
if [ -f "$target" ]; then
|
|
172
|
+
cp "$hook" "$target"
|
|
173
|
+
chmod +x "$target"
|
|
174
|
+
echo " UPDATE $name"
|
|
175
|
+
else
|
|
176
|
+
cp "$hook" "$target"
|
|
177
|
+
chmod +x "$target"
|
|
178
|
+
echo " INSTALL $name"
|
|
179
|
+
fi
|
|
180
|
+
HOOK_COUNT=$((HOOK_COUNT + 1))
|
|
181
|
+
done
|
|
149
182
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
183
|
+
# Install Node.js hooks
|
|
184
|
+
for hook in "$REPO_DIR/hooks"/ftm-*.mjs; do
|
|
185
|
+
[ -f "$hook" ] || continue
|
|
186
|
+
name=$(basename "$hook")
|
|
187
|
+
target="$HOOKS_DIR/$name"
|
|
188
|
+
if [ -f "$target" ]; then
|
|
189
|
+
cp "$hook" "$target"
|
|
190
|
+
echo " UPDATE $name"
|
|
191
|
+
else
|
|
192
|
+
cp "$hook" "$target"
|
|
193
|
+
echo " INSTALL $name"
|
|
194
|
+
fi
|
|
195
|
+
HOOK_COUNT=$((HOOK_COUNT + 1))
|
|
196
|
+
done
|
|
155
197
|
|
|
156
|
-
|
|
157
|
-
echo "
|
|
158
|
-
exit 1
|
|
198
|
+
echo ""
|
|
199
|
+
echo " $HOOK_COUNT hooks installed to $HOOKS_DIR"
|
|
159
200
|
fi
|
|
160
201
|
|
|
161
|
-
#
|
|
162
|
-
EXPANDED_TEMPLATE=$(sed "s|~/.claude|$HOME/.claude|g" "$TEMPLATE")
|
|
202
|
+
# --- Hook Config Merge (default behavior now) ---
|
|
163
203
|
|
|
164
|
-
if [
|
|
165
|
-
|
|
166
|
-
echo "
|
|
167
|
-
echo "
|
|
204
|
+
if [ "$SKIP_MERGE" = true ]; then
|
|
205
|
+
echo ""
|
|
206
|
+
echo " Skipping settings.json merge (--skip-merge)."
|
|
207
|
+
echo " Add entries from hooks/settings-template.json to ~/.claude/settings.json manually."
|
|
168
208
|
else
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
BACKUP="$SETTINGS_FILE.ftm-backup-$(date +%Y%m%d%H%M%S)"
|
|
172
|
-
cp "$SETTINGS_FILE" "$BACKUP"
|
|
173
|
-
echo " BACKUP $BACKUP"
|
|
209
|
+
echo ""
|
|
210
|
+
echo "Registering hooks in settings.json..."
|
|
174
211
|
|
|
175
|
-
|
|
176
|
-
|
|
212
|
+
TEMPLATE="$REPO_DIR/hooks/settings-template.json"
|
|
213
|
+
if [ ! -f "$TEMPLATE" ]; then
|
|
214
|
+
warn "hooks/settings-template.json not found — hooks installed but not registered"
|
|
215
|
+
else
|
|
216
|
+
# Expand ~ to $HOME in the template (jq doesn't expand shell paths)
|
|
217
|
+
EXPANDED_TEMPLATE=$(sed "s|~/.claude|$HOME/.claude|g" "$TEMPLATE")
|
|
218
|
+
|
|
219
|
+
if [ ! -f "$SETTINGS_FILE" ]; then
|
|
220
|
+
# No settings.json — create one from the template hooks section
|
|
221
|
+
echo "$EXPANDED_TEMPLATE" | jq '{hooks: .hooks}' > "$SETTINGS_FILE"
|
|
222
|
+
echo " CREATED $SETTINGS_FILE with FTM hooks"
|
|
223
|
+
else
|
|
224
|
+
# Merge FTM hooks into existing settings.json
|
|
225
|
+
BACKUP="$SETTINGS_FILE.ftm-backup-$(date +%Y%m%d%H%M%S)"
|
|
226
|
+
cp "$SETTINGS_FILE" "$BACKUP"
|
|
227
|
+
echo " BACKUP $BACKUP"
|
|
228
|
+
|
|
229
|
+
# Extract the hooks section from the template
|
|
230
|
+
TEMPLATE_HOOKS=$(echo "$EXPANDED_TEMPLATE" | jq '.hooks')
|
|
231
|
+
|
|
232
|
+
# Read existing settings
|
|
233
|
+
EXISTING=$(cat "$SETTINGS_FILE")
|
|
234
|
+
|
|
235
|
+
# Ensure hooks key exists
|
|
236
|
+
if echo "$EXISTING" | jq -e '.hooks' >/dev/null 2>&1; then
|
|
237
|
+
: # hooks key exists
|
|
238
|
+
else
|
|
239
|
+
EXISTING=$(echo "$EXISTING" | jq '. + {hooks: {}}')
|
|
240
|
+
fi
|
|
177
241
|
|
|
178
|
-
|
|
179
|
-
|
|
242
|
+
# Merge each hook event type
|
|
243
|
+
for EVENT in PreToolUse UserPromptSubmit PostToolUse Stop; do
|
|
244
|
+
TEMPLATE_ENTRIES=$(echo "$TEMPLATE_HOOKS" | jq --arg e "$EVENT" '.[$e] // []')
|
|
245
|
+
EXISTING_ENTRIES=$(echo "$EXISTING" | jq --arg e "$EVENT" '.hooks[$e] // []')
|
|
246
|
+
|
|
247
|
+
# Check if any FTM hooks are already present (by checking command paths)
|
|
248
|
+
FTM_COMMANDS=$(echo "$TEMPLATE_ENTRIES" | jq -r '.[].hooks[]?.command // empty' 2>/dev/null)
|
|
249
|
+
ALREADY_PRESENT=false
|
|
250
|
+
|
|
251
|
+
for cmd in $FTM_COMMANDS; do
|
|
252
|
+
cmd_basename=$(basename "$cmd")
|
|
253
|
+
if echo "$EXISTING_ENTRIES" | jq -r '.[].hooks[]?.command // empty' 2>/dev/null | grep -q "$cmd_basename"; then
|
|
254
|
+
ALREADY_PRESENT=true
|
|
255
|
+
break
|
|
256
|
+
fi
|
|
257
|
+
done
|
|
258
|
+
|
|
259
|
+
if [ "$ALREADY_PRESENT" = true ]; then
|
|
260
|
+
echo " SKIP $EVENT hooks (already configured)"
|
|
261
|
+
continue
|
|
262
|
+
fi
|
|
263
|
+
|
|
264
|
+
# Append template entries to existing
|
|
265
|
+
MERGED=$(jq -n --argjson existing "$EXISTING_ENTRIES" --argjson template "$TEMPLATE_ENTRIES" '$existing + $template')
|
|
266
|
+
EXISTING=$(echo "$EXISTING" | jq --arg e "$EVENT" --argjson m "$MERGED" '.hooks[$e] = $m')
|
|
267
|
+
echo " MERGE $EVENT hooks"
|
|
268
|
+
done
|
|
269
|
+
|
|
270
|
+
echo "$EXISTING" | jq '.' > "$SETTINGS_FILE"
|
|
271
|
+
echo " UPDATED $SETTINGS_FILE"
|
|
272
|
+
fi
|
|
180
273
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
: # hooks key exists
|
|
184
|
-
else
|
|
185
|
-
EXISTING=$(echo "$EXISTING" | jq '. + {hooks: {}}')
|
|
274
|
+
echo ""
|
|
275
|
+
echo " Hooks are active."
|
|
186
276
|
fi
|
|
277
|
+
fi
|
|
278
|
+
fi
|
|
187
279
|
|
|
188
|
-
|
|
189
|
-
for EVENT in PreToolUse UserPromptSubmit PostToolUse Stop; do
|
|
190
|
-
TEMPLATE_ENTRIES=$(echo "$TEMPLATE_HOOKS" | jq --arg e "$EVENT" '.[$e] // []')
|
|
191
|
-
EXISTING_ENTRIES=$(echo "$EXISTING" | jq --arg e "$EVENT" '.hooks[$e] // []')
|
|
280
|
+
# --- Verification ---
|
|
192
281
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
ALREADY_PRESENT=false
|
|
282
|
+
echo ""
|
|
283
|
+
echo "Verifying installation..."
|
|
196
284
|
|
|
197
|
-
|
|
198
|
-
cmd_basename=$(basename "$cmd")
|
|
199
|
-
if echo "$EXISTING_ENTRIES" | jq -r '.[].hooks[]?.command // empty' 2>/dev/null | grep -q "$cmd_basename"; then
|
|
200
|
-
ALREADY_PRESENT=true
|
|
201
|
-
break
|
|
202
|
-
fi
|
|
203
|
-
done
|
|
285
|
+
ERRORS=0
|
|
204
286
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
287
|
+
# Check skill symlinks resolve
|
|
288
|
+
BROKEN_LINKS=0
|
|
289
|
+
for link in "$SKILLS_DIR"/ftm*; do
|
|
290
|
+
[ -L "$link" ] || continue
|
|
291
|
+
if [ ! -e "$link" ]; then
|
|
292
|
+
warn "broken symlink: $link"
|
|
293
|
+
BROKEN_LINKS=$((BROKEN_LINKS + 1))
|
|
294
|
+
fi
|
|
295
|
+
done
|
|
296
|
+
if [ "$BROKEN_LINKS" -eq 0 ]; then
|
|
297
|
+
echo " Skills: $SKILL_COUNT linked, all symlinks valid"
|
|
298
|
+
else
|
|
299
|
+
ERRORS=$((ERRORS + 1))
|
|
300
|
+
fi
|
|
209
301
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
302
|
+
# Check blackboard state
|
|
303
|
+
if [ -f "$STATE_DIR/blackboard/context.json" ] && [ -f "$STATE_DIR/blackboard/patterns.json" ]; then
|
|
304
|
+
echo " Blackboard: initialized"
|
|
305
|
+
else
|
|
306
|
+
warn "blackboard state incomplete"
|
|
307
|
+
ERRORS=$((ERRORS + 1))
|
|
308
|
+
fi
|
|
215
309
|
|
|
216
|
-
|
|
217
|
-
|
|
310
|
+
# Check config
|
|
311
|
+
if [ -f "$CONFIG_DIR/ftm-config.yml" ]; then
|
|
312
|
+
echo " Config: present"
|
|
313
|
+
else
|
|
314
|
+
warn "ftm-config.yml missing"
|
|
315
|
+
ERRORS=$((ERRORS + 1))
|
|
316
|
+
fi
|
|
317
|
+
|
|
318
|
+
# Check hooks (if installed)
|
|
319
|
+
if [ "$NO_HOOKS" = false ] && [ "$HOOK_COUNT" -gt 0 ]; then
|
|
320
|
+
# Verify hook files exist and are executable
|
|
321
|
+
HOOK_OK=true
|
|
322
|
+
for hook in "$HOOKS_DIR"/ftm-*.sh; do
|
|
323
|
+
[ -f "$hook" ] || continue
|
|
324
|
+
if [ ! -x "$hook" ]; then
|
|
325
|
+
warn "$(basename "$hook") not executable"
|
|
326
|
+
HOOK_OK=false
|
|
327
|
+
fi
|
|
328
|
+
done
|
|
329
|
+
|
|
330
|
+
if [ "$HOOK_OK" = true ]; then
|
|
331
|
+
echo " Hooks: $HOOK_COUNT installed, all executable"
|
|
332
|
+
else
|
|
333
|
+
ERRORS=$((ERRORS + 1))
|
|
218
334
|
fi
|
|
219
335
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
336
|
+
# Verify settings.json has FTM hooks registered
|
|
337
|
+
if [ "$SKIP_MERGE" = false ] && [ -f "$SETTINGS_FILE" ]; then
|
|
338
|
+
FTM_REGISTERED=$(grep -c 'ftm-' "$SETTINGS_FILE" 2>/dev/null || echo "0")
|
|
339
|
+
if [ "$FTM_REGISTERED" -gt 0 ]; then
|
|
340
|
+
echo " Settings: $FTM_REGISTERED FTM entries in settings.json"
|
|
341
|
+
else
|
|
342
|
+
warn "no FTM hooks found in settings.json"
|
|
343
|
+
ERRORS=$((ERRORS + 1))
|
|
344
|
+
fi
|
|
345
|
+
fi
|
|
227
346
|
fi
|
|
228
347
|
|
|
348
|
+
# --- Summary ---
|
|
349
|
+
|
|
350
|
+
echo ""
|
|
351
|
+
if [ "$ERRORS" -eq 0 ] && [ "$WARN_COUNT" -eq 0 ]; then
|
|
352
|
+
echo "Done. $SKILL_COUNT skills, $HOOK_COUNT hooks. Everything checks out."
|
|
353
|
+
else
|
|
354
|
+
echo "Done. $SKILL_COUNT skills, $HOOK_COUNT hooks. $WARN_COUNT warning(s)."
|
|
355
|
+
fi
|
|
229
356
|
echo ""
|
|
230
|
-
echo "
|
|
357
|
+
echo "Restart Claude Code (or start a new session) to pick up the skills."
|
|
231
358
|
echo "Try: /ftm help"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "feed-the-machine",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "A unified intelligence layer for Claude Code —
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "A unified intelligence layer for Claude Code — 22 skills with OODA-based reasoning, persistent memory, multi-model deliberation, and optional operator cockpit inbox",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "kkudumu",
|
|
7
7
|
"type": "module",
|
|
@@ -51,8 +51,12 @@
|
|
|
51
51
|
"ftm-map/",
|
|
52
52
|
"ftm-dashboard/",
|
|
53
53
|
"ftm-routine/",
|
|
54
|
+
"ftm-capture/",
|
|
54
55
|
"ftm-state/",
|
|
56
|
+
"ftm-inbox/",
|
|
55
57
|
"ftm-config.default.yml",
|
|
58
|
+
"ftm-manifest.json",
|
|
59
|
+
"docs/INBOX.md",
|
|
56
60
|
"README.md",
|
|
57
61
|
"LICENSE"
|
|
58
62
|
],
|