@matt82198/aesop 0.1.0-beta.3 → 0.1.0-beta.5

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 (234) hide show
  1. package/CHANGELOG.md +79 -95
  2. package/CLAUDE-TEMPLATE.md +115 -0
  3. package/README.md +126 -245
  4. package/aesop.config.example.json +34 -26
  5. package/bin/CLAUDE.md +67 -0
  6. package/bin/cli.js +593 -36
  7. package/daemons/CLAUDE.md +36 -0
  8. package/daemons/backup-fleet.sh +92 -21
  9. package/daemons/run-watchdog.sh +95 -12
  10. package/dash/CLAUDE.md +32 -0
  11. package/dash/dash-extra.mjs +194 -21
  12. package/dash/watchdog-gui.sh +23 -6
  13. package/docs/BEHAVIORAL-PR-REVIEW.md +86 -0
  14. package/docs/CHECKPOINTING.md +100 -0
  15. package/docs/DISPATCH-MODEL.md +11 -7
  16. package/docs/FORENSICS.md +204 -0
  17. package/docs/GOVERNANCE.md +4 -2
  18. package/docs/HOOK-INSTALL.md +307 -0
  19. package/docs/HOW-THE-LOOP-WORKS.md +175 -0
  20. package/docs/MEMORY-TEMPLATE.md +61 -0
  21. package/docs/README.md +44 -0
  22. package/docs/RELEASING.md +159 -0
  23. package/docs/RELIABILITY.md +61 -0
  24. package/docs/RESTORE.md +397 -0
  25. package/docs/SCRIPTS-POLICY.md +97 -0
  26. package/docs/archive/README.md +3 -0
  27. package/docs/archive/spikes/tiered-cognition/ACTIVATION.md +125 -0
  28. package/docs/archive/spikes/tiered-cognition/DESIGN.md +287 -0
  29. package/docs/archive/spikes/tiered-cognition/FINDINGS.md +113 -0
  30. package/docs/archive/spikes/tiered-cognition/README.md +27 -0
  31. package/docs/archive/spikes/tiered-cognition/aesop-cognition.example.md +32 -0
  32. package/docs/archive/spikes/tiered-cognition/force-model-policy.merged.mjs +673 -0
  33. package/docs/archive/spikes/tiered-cognition/strip-tools-hook.mjs +434 -0
  34. package/docs/case-study-portfolio.md +61 -0
  35. package/docs/self-stats-data.json +11 -0
  36. package/docs/templates/FLEET-OPS-ANALYSIS.example.md +27 -0
  37. package/docs/templates/FLEET-OPS-RECOMMENDATIONS.example.md +24 -0
  38. package/docs/templates/PROPOSALS-LOG.example.md +64 -0
  39. package/hooks/CLAUDE.md +61 -0
  40. package/hooks/claude/force-model-policy.mjs +159 -0
  41. package/hooks/pre-push-policy.sh +753 -0
  42. package/mcp/CLAUDE.md +213 -0
  43. package/mcp/package.json +26 -0
  44. package/mcp/server.mjs +543 -0
  45. package/monitor/.signal-state.json +3 -0
  46. package/monitor/ACTIONS.log +1 -0
  47. package/monitor/BRIEF.md +24 -0
  48. package/monitor/CHARTER.md +75 -88
  49. package/monitor/CLAUDE.md +40 -0
  50. package/monitor/SIGNALS.json +54 -0
  51. package/monitor/collect-signals.mjs +613 -61
  52. package/package.json +15 -3
  53. package/scan/fleet-scan.example.mjs +292 -0
  54. package/skills/CLAUDE.md +3 -0
  55. package/skills/healthcheck/SKILL.md +44 -0
  56. package/skills/power/SKILL.md +161 -0
  57. package/state_store/CLAUDE.md +39 -0
  58. package/state_store/__init__.py +24 -0
  59. package/state_store/__pycache__/__init__.cpython-314.pyc +0 -0
  60. package/state_store/__pycache__/api.cpython-314.pyc +0 -0
  61. package/state_store/__pycache__/export.cpython-314.pyc +0 -0
  62. package/state_store/__pycache__/ingest.cpython-314.pyc +0 -0
  63. package/state_store/__pycache__/projections.cpython-314.pyc +0 -0
  64. package/state_store/__pycache__/store.cpython-314.pyc +0 -0
  65. package/state_store/api.py +35 -0
  66. package/state_store/export.py +19 -0
  67. package/state_store/ingest.py +24 -0
  68. package/state_store/projections.py +52 -0
  69. package/state_store/store.py +102 -0
  70. package/tools/CLAUDE.md +72 -0
  71. package/tools/__pycache__/alert_bridge.cpython-314.pyc +0 -0
  72. package/tools/__pycache__/buildlog.cpython-314.pyc +0 -0
  73. package/tools/__pycache__/ci_merge_wait.cpython-314.pyc +0 -0
  74. package/tools/__pycache__/ensure_state.cpython-314.pyc +0 -0
  75. package/tools/__pycache__/eod_sweep.cpython-314.pyc +0 -0
  76. package/tools/__pycache__/fleet_ledger.cpython-314.pyc +0 -0
  77. package/tools/__pycache__/fleet_prompt_extractor.cpython-314.pyc +0 -0
  78. package/tools/__pycache__/healthcheck.cpython-314.pyc +0 -0
  79. package/tools/__pycache__/heartbeat.cpython-314.pyc +0 -0
  80. package/tools/__pycache__/inbox_drain.cpython-314.pyc +0 -0
  81. package/tools/__pycache__/launch_tui.cpython-314.pyc +0 -0
  82. package/tools/__pycache__/metrics_gate.cpython-314.pyc +0 -0
  83. package/tools/__pycache__/orchestrator_status.cpython-314.pyc +0 -0
  84. package/tools/__pycache__/power_selftest.cpython-314.pyc +0 -0
  85. package/tools/__pycache__/prepublish_scan.cpython-314.pyc +0 -0
  86. package/tools/__pycache__/rotate_logs.cpython-314.pyc +0 -0
  87. package/tools/__pycache__/scanner_selftest.cpython-314.pyc +0 -0
  88. package/tools/__pycache__/secret_scan.cpython-314.pyc +0 -0
  89. package/tools/__pycache__/self_stats.cpython-314.pyc +0 -0
  90. package/tools/__pycache__/session_usage_summary.cpython-314.pyc +0 -0
  91. package/tools/__pycache__/stall_check.cpython-314.pyc +0 -0
  92. package/tools/__pycache__/transcript_replay.cpython-314.pyc +0 -0
  93. package/tools/__pycache__/transcript_timeline.cpython-314.pyc +0 -0
  94. package/tools/__pycache__/verify_dash.cpython-314.pyc +0 -0
  95. package/tools/__pycache__/verify_submit_encoding.cpython-314.pyc +0 -0
  96. package/tools/agent-forensics.sh +186 -0
  97. package/tools/alert_bridge.py +449 -0
  98. package/tools/buildlog.py +182 -0
  99. package/tools/ci_merge_wait.py +317 -0
  100. package/tools/ensure_state.py +94 -0
  101. package/tools/eod_sweep.py +239 -0
  102. package/tools/fleet_ledger.py +272 -0
  103. package/tools/fleet_prompt_extractor.py +134 -0
  104. package/tools/healthcheck.py +296 -0
  105. package/tools/heartbeat.py +131 -0
  106. package/tools/inbox_drain.py +249 -0
  107. package/tools/launch_tui.py +51 -3
  108. package/tools/lock.mjs +211 -0
  109. package/tools/metrics_gate.py +205 -0
  110. package/tools/orchestrator_status.py +99 -0
  111. package/tools/power_selftest.py +386 -0
  112. package/tools/prepublish_scan.py +84 -0
  113. package/tools/proposals.mjs +248 -0
  114. package/tools/reconstitute.sh +467 -0
  115. package/tools/rotate_logs.py +228 -0
  116. package/tools/scanner_selftest.py +303 -0
  117. package/tools/secret_scan.py +138 -31
  118. package/tools/self_stats.py +509 -0
  119. package/tools/session_usage_summary.py +198 -0
  120. package/tools/stall_check.py +172 -0
  121. package/tools/svg_to_png.mjs +50 -0
  122. package/tools/transcript_replay.py +236 -0
  123. package/tools/transcript_timeline.py +184 -0
  124. package/tools/verify_dash.py +513 -0
  125. package/tools/verify_submit_encoding.py +202 -0
  126. package/ui/CLAUDE.md +125 -0
  127. package/ui/__pycache__/agents.cpython-314.pyc +0 -0
  128. package/ui/__pycache__/collectors.cpython-314.pyc +0 -0
  129. package/ui/__pycache__/config.cpython-314.pyc +0 -0
  130. package/ui/__pycache__/cost.cpython-314.pyc +0 -0
  131. package/ui/__pycache__/csrf.cpython-314.pyc +0 -0
  132. package/ui/__pycache__/handler.cpython-314.pyc +0 -0
  133. package/ui/__pycache__/render.cpython-314.pyc +0 -0
  134. package/ui/__pycache__/serve.cpython-314.pyc +0 -0
  135. package/ui/__pycache__/sse.cpython-314.pyc +0 -0
  136. package/ui/agents.py +183 -0
  137. package/ui/api/__init__.py +84 -0
  138. package/ui/api/__pycache__/__init__.cpython-314.pyc +0 -0
  139. package/ui/api/__pycache__/submit.cpython-314.pyc +0 -0
  140. package/ui/api/__pycache__/tracker.cpython-314.pyc +0 -0
  141. package/ui/api/submit.py +97 -0
  142. package/ui/api/tracker.py +116 -0
  143. package/ui/collectors.py +735 -0
  144. package/ui/config.py +123 -0
  145. package/ui/cost.py +260 -0
  146. package/ui/csrf.py +144 -0
  147. package/ui/handler.py +676 -0
  148. package/ui/render.py +49 -0
  149. package/ui/serve.py +68 -796
  150. package/ui/sse.py +183 -0
  151. package/ui/web/.gitattributes +13 -0
  152. package/ui/web/dist/assets/index-2LZDQirC.js +9 -0
  153. package/ui/web/dist/assets/index-D4M1qyOv.css +1 -0
  154. package/ui/web/dist/index.html +14 -0
  155. package/ui/web/index.html +13 -0
  156. package/ui/web/package-lock.json +2225 -0
  157. package/ui/web/package.json +26 -0
  158. package/ui/web/src/App.test.tsx +74 -0
  159. package/ui/web/src/App.tsx +142 -0
  160. package/ui/web/src/CONTRIBUTING-UI.md +49 -0
  161. package/ui/web/src/components/AgentRow.css +187 -0
  162. package/ui/web/src/components/AgentRow.test.tsx +209 -0
  163. package/ui/web/src/components/AgentRow.tsx +207 -0
  164. package/ui/web/src/components/AgentsPanel.css +108 -0
  165. package/ui/web/src/components/AgentsPanel.test.tsx +41 -0
  166. package/ui/web/src/components/AgentsPanel.tsx +58 -0
  167. package/ui/web/src/components/AlertsPanel.css +88 -0
  168. package/ui/web/src/components/AlertsPanel.test.tsx +51 -0
  169. package/ui/web/src/components/AlertsPanel.tsx +67 -0
  170. package/ui/web/src/components/BacklogPanel.test.tsx +126 -0
  171. package/ui/web/src/components/BacklogPanel.tsx +122 -0
  172. package/ui/web/src/components/CostChart.css +110 -0
  173. package/ui/web/src/components/CostChart.test.tsx +144 -0
  174. package/ui/web/src/components/CostChart.tsx +152 -0
  175. package/ui/web/src/components/CostTable.css +93 -0
  176. package/ui/web/src/components/CostTable.test.tsx +165 -0
  177. package/ui/web/src/components/CostTable.tsx +94 -0
  178. package/ui/web/src/components/EventsFeed.css +68 -0
  179. package/ui/web/src/components/EventsFeed.test.tsx +36 -0
  180. package/ui/web/src/components/EventsFeed.tsx +31 -0
  181. package/ui/web/src/components/HealthHeader.css +137 -0
  182. package/ui/web/src/components/HealthHeader.test.tsx +278 -0
  183. package/ui/web/src/components/HealthHeader.tsx +281 -0
  184. package/ui/web/src/components/InboxForm.css +135 -0
  185. package/ui/web/src/components/InboxForm.test.tsx +208 -0
  186. package/ui/web/src/components/InboxForm.tsx +116 -0
  187. package/ui/web/src/components/MessagesTail.module.css +144 -0
  188. package/ui/web/src/components/MessagesTail.test.tsx +176 -0
  189. package/ui/web/src/components/MessagesTail.tsx +94 -0
  190. package/ui/web/src/components/ReposPanel.css +90 -0
  191. package/ui/web/src/components/ReposPanel.test.tsx +45 -0
  192. package/ui/web/src/components/ReposPanel.tsx +67 -0
  193. package/ui/web/src/components/Scorecard.css +106 -0
  194. package/ui/web/src/components/Scorecard.test.tsx +117 -0
  195. package/ui/web/src/components/Scorecard.tsx +85 -0
  196. package/ui/web/src/components/Timeline.module.css +151 -0
  197. package/ui/web/src/components/Timeline.test.tsx +215 -0
  198. package/ui/web/src/components/Timeline.tsx +99 -0
  199. package/ui/web/src/components/TrackerBoard.test.tsx +121 -0
  200. package/ui/web/src/components/TrackerBoard.tsx +107 -0
  201. package/ui/web/src/components/TrackerCard.test.tsx +180 -0
  202. package/ui/web/src/components/TrackerCard.tsx +160 -0
  203. package/ui/web/src/components/TrackerForm.test.tsx +189 -0
  204. package/ui/web/src/components/TrackerForm.tsx +144 -0
  205. package/ui/web/src/lib/api.ts +218 -0
  206. package/ui/web/src/lib/format.test.ts +89 -0
  207. package/ui/web/src/lib/format.ts +103 -0
  208. package/ui/web/src/lib/sanitizeUrl.test.ts +84 -0
  209. package/ui/web/src/lib/sanitizeUrl.ts +38 -0
  210. package/ui/web/src/lib/types.ts +230 -0
  211. package/ui/web/src/lib/useHashRoute.test.ts +60 -0
  212. package/ui/web/src/lib/useHashRoute.ts +23 -0
  213. package/ui/web/src/lib/useSSE.ts +175 -0
  214. package/ui/web/src/main.tsx +10 -0
  215. package/ui/web/src/styles/global.css +179 -0
  216. package/ui/web/src/styles/theme.css +184 -0
  217. package/ui/web/src/styles/work.css +572 -0
  218. package/ui/web/src/test/fixtures.ts +385 -0
  219. package/ui/web/src/test/setup.ts +49 -0
  220. package/ui/web/src/views/Activity.module.css +43 -0
  221. package/ui/web/src/views/Activity.test.tsx +89 -0
  222. package/ui/web/src/views/Activity.tsx +31 -0
  223. package/ui/web/src/views/Cost.css +87 -0
  224. package/ui/web/src/views/Cost.test.tsx +142 -0
  225. package/ui/web/src/views/Cost.tsx +54 -0
  226. package/ui/web/src/views/Overview.css +51 -0
  227. package/ui/web/src/views/Overview.test.tsx +76 -0
  228. package/ui/web/src/views/Overview.tsx +46 -0
  229. package/ui/web/src/views/Work.test.tsx +82 -0
  230. package/ui/web/src/views/Work.tsx +79 -0
  231. package/ui/web/src/vite-env.d.ts +10 -0
  232. package/ui/web/tsconfig.json +22 -0
  233. package/ui/web/vite.config.ts +25 -0
  234. package/ui/web/vitest.config.ts +12 -0
package/README.md CHANGED
@@ -9,345 +9,226 @@
9
9
  <p align="center">
10
10
  <a href="https://www.npmjs.com/package/@matt82198/aesop"><img src="https://img.shields.io/npm/v/@matt82198/aesop/beta" alt="npm"></a>
11
11
  <a href="LICENSE"><img src="https://img.shields.io/npm/l/@matt82198/aesop" alt="license"></a>
12
+ <a href="https://github.com/matt82198/aesop/actions/workflows/ci.yml"><img src="https://github.com/matt82198/aesop/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
12
13
  </p>
13
14
 
14
- **Aesop** is an open-source orchestration harness for Claude Code, implementing a cost-optimized, self-healing multi-agent dispatch system. One orchestrator model (Opus/Sonnet) directs a fleet of cheap subagents (Haiku) across durable, observable machinery.
15
+ **Aesop** is an open-source orchestration harness for Claude Code that builds itself. It runs a `/buildsystem` wave cycle—ranking a backlog, fanning out parallel Haiku agents (1/3 the cost of Opus), watchdogging them, verifying merges, then feeding the next wave via audit + ideation + fleet-ops monitoring. **This repo's own PRs are built by Aesop's own loop.** Dogfooding, not doctrine.
15
16
 
16
- The naming is a conceit: Aesop directs the Fables (the AI models). Like the tortoise and the hare, Aesop favors the slow, deliberate orchestrator directing a fleet of fast, cheap agents toward reliable outcomes.
17
+ What you get: **cost-optimized multi-agent dispatch** (Haiku-first subagents, lean orchestrator), **durable state** (git-committed checkpoints survive wipes), **observable machinery** (every agent run logged, every cost tracked), **live dashboard** (real-time fleet health at http://localhost:8770), and **security gates** (secret-scan blocks pushes, CI validates each merge).
17
18
 
18
- ## Origin
19
+ ## What You Get
19
20
 
20
- Aesop began as damage control: an endpoint-security agent kept deleting work mid-session, so everything was forced into gitcommitted continuously, pushed constantly, reconstructable from nothing but the remotes. What started as a survival mechanism against a machine that wiped itself grew into a full multi-agent orchestration system—and one worth sharing.
21
+ - **Parallel Haiku fleets**Cheap, scoped subagents dispatch in parallel; orchestrator stays lean on main thread.
22
+ - **Durable state** — STATE.md + BUILDLOG.md checkpoints survive machine wipes; re-sync on resume, zero data loss.
23
+ - **Observable & auditable** — Every agent run logged, every cost tracked, every security event triaged.
24
+ - **Self-healing watchdog** — Runs every 150s: backs up work, scans for secrets, detects drift, restores on reboot.
25
+ - **Live web dashboard** — Real-time fleet health, security alerts, work-item kanban at `http://localhost:8770`.
26
+ - **Secret-scan gates** — Pre-push hook blocks leaks; audit trail logged. Pair with GitHub branch protection for enforcement.
21
27
 
22
- ## What it is
28
+ ## Get Started (3 steps, 5 min)
23
29
 
24
- A filesystem-first orchestration system that:
30
+ **Note:** Aesop is in beta. Install the `@beta` tag for the latest prerelease (0.1.0-beta.1+).
25
31
 
26
- - **Dispatch pattern**: Opus orchestrator on the main thread coordinates tiny scoped tasks to Haiku subagents (1/3 the token cost).
27
- - **Durable state**: git-committed checkpoints (STATE.md, BUILDLOG.md) survive machine wipes and interruptions.
28
- - **Observable machinery**: every agent run logged, every cost tracked, every security breach detected.
29
- - **Self-healing watchdog**: runs every 150s, backs up work, scans for secrets and drift, restores on reboot.
30
- - **Refinement monitor**: standing Haiku loop that watches orchestration health and auto-acts on rule friction.
31
- - **TUI dashboard**: real-time fleet status, security alerts, heartbeat liveness.
32
-
33
- ## Install & Quick Start
34
-
35
- ### Option 1: npm (Recommended for quick scaffolding)
36
-
37
- **Note:** Aesop is currently in beta. Install the prerelease version:
32
+ ### Quickest path: npx scaffold
38
33
 
39
34
  ```bash
40
- # Create a new aesop fleet directory
41
- # Using @beta tag to install the latest prerelease version (0.1.0-beta.1)
42
- npx @matt82198/aesop@beta my-fleet
35
+ npx @matt82198/aesop@beta my-fleet \
36
+ --name "my-api" \
37
+ --repos "/path/to/repo1,/path/to/repo2"
43
38
  cd my-fleet
44
39
 
45
- # Configure
46
- cp aesop.config.example.json aesop.config.json
47
- # Edit aesop.config.json with your paths and repos
48
-
49
40
  # Start the daemon
50
41
  bash daemons/run-watchdog.sh --once
51
42
 
52
- # Launch the dashboard
43
+ # Launch dashboard on localhost:8770
53
44
  python ui/serve.py
54
45
  ```
55
46
 
56
- Open `http://localhost:8770` to monitor your fleet.
47
+ Pre-push hook auto-installed. See [docs/HOOK-INSTALL.md](./docs/HOOK-INSTALL.md) for branch protection pairing.
57
48
 
58
- Alternatively, install globally:
59
- ```bash
60
- npm install -g @matt82198/aesop@beta
61
- aesop my-fleet
62
- ```
49
+ **State Store**: Aesop uses an event-sourced SQLite WAL backing store (`state_store/`) for durable state persistence. The `tracker.json` file is automatically re-rendered as an export for git-friendly checkpointing. Mutations follow a dual-path model: append new events via the StateAPI, then rendered exports for external consumption.
63
50
 
64
- ### Option 2: git clone (For development or full customization)
51
+ ### Or: git clone for hacking
65
52
 
66
53
  ```bash
67
54
  git clone https://github.com/matt82198/aesop ~/aesop
68
55
  cd ~/aesop
69
56
  cp aesop.config.example.json aesop.config.json
70
- # Edit aesop.config.json with your paths and repos
57
+ # Edit paths and repos
71
58
 
72
- # Start the daemon
73
59
  export AESOP_ROOT=$HOME/aesop
74
60
  bash $AESOP_ROOT/daemons/run-watchdog.sh --once
75
-
76
- # Launch the dashboard
77
61
  python ui/serve.py
78
62
  ```
79
63
 
80
- ## Architecture
81
-
82
- ### Directory layout
64
+ ## How It Works
83
65
 
84
66
  ```
85
- aesop/
86
- daemons/ # Watchdog daemon + backup scripts
87
- dash/ # TUI dashboard (watchdog-gui.sh)
88
- monitor/ # Orchestration monitor (collect-signals.mjs, CHARTER.md)
89
- tools/ # Build utilities (stubs for extend)
90
- docs/ # Migration guides, deep-dives
91
- state/ # Durable checkpoints (created at runtime)
92
- aesop.config.json # Your local configuration (git-ignored)
67
+ daemons/run-watchdog.sh Every 150s: backs up work, scans secrets, detects drift
68
+
69
+ orchestrator (via Claude Code) Reads backlog, dispatches Haiku subagents in parallel
70
+
71
+ parallel Haiku fleet Tiny, scoped domains (tests, build, review, docs, etc.)
72
+
73
+ watchdog verifies & merges GREEN push to main
74
+
75
+ monitor/collect-signals.mjs Audits orchestration health, feeds next wave's backlog
76
+
77
+ STATE.md + BUILDLOG.md Git-committed, survives machine wipes
93
78
  ```
94
79
 
95
- ### Operating the harness
80
+ See [docs/DISPATCH-MODEL.md](./docs/DISPATCH-MODEL.md) for cost analysis and parallel patterns.
96
81
 
97
- #### 1. Bootstrap
82
+ <!-- SELF-STATS:START -->
98
83
 
99
- ```bash
100
- git clone <aesop-repo> ~/aesop
101
- cd ~/aesop
102
- cp aesop.config.example.json aesop.config.json
103
- # Edit aesop.config.json with your paths and repos
104
- ```
84
+ ## Aesop builds itself
105
85
 
106
- #### 2. Start the watchdog daemon
86
+ Aesop is built entirely by its own `/buildsystem` wave cycle—running parallel Haiku fleets across ranked backlog items, verifying merges, auditing orchestration health. These stats are the receipts: all numbers computed LIVE from git, verified by anyone who clones.
107
87
 
108
- ```bash
109
- export AESOP_ROOT=$HOME/aesop
110
- bash $AESOP_ROOT/daemons/run-watchdog.sh &
111
- ```
88
+ | Metric | Value |
89
+ | --- | --- |
90
+ | Merged PRs | 141 <!-- metrics-verified: self_stats.py (git log) --> |
91
+ | Total Commits | 377 <!-- metrics-verified: self_stats.py (git log) --> |
92
+ | Project Age | 3 days <!-- metrics-verified: self_stats.py (git log) --> |
93
+ | Waves | 15 <!-- metrics-verified: self_stats.py (git log) --> |
94
+ | Insertions + Deletions | 70,439 <!-- metrics-verified: self_stats.py (git log) --> |
95
+ | Files Tracked | 257 <!-- metrics-verified: self_stats.py (git log) --> |
96
+ | Distinct Co-authors | 7 <!-- metrics-verified: self_stats.py (git log) --> |
112
97
 
113
- Runs every 150s: discovers changed repos, stashes uncommitted work, pushes backups to `backup/wip-*` branches, runs secret-scan gate.
98
+ <!-- SELF-STATS:END -->
114
99
 
115
- #### 3. Launch the Web Dashboard (Primary Interface)
100
+ ## Recommended Agents
116
101
 
117
- The web dashboard is the recommended way to monitor your fleet. It provides real-time observability, security alerts, and inbox integration in a modern, responsive interface.
102
+ Aesop pairs well with the open-source [Claude specialized-agent catalog](https://github.com/anthropics/claude-code/tree/main/agents) a library of ~130 domain-specific agents (TDD orchestrators, security reviewers, performance engineers, etc.). For optimal results, install agents from the upstream source and pair them with Aesop's cost-optimized Haiku dispatch. This is optional; Aesop works standalone with general-purpose Claude Code agents.
118
103
 
119
- ```bash
120
- python $AESOP_ROOT/ui/serve.py
121
- ```
122
-
123
- Opens `http://localhost:8770` with:
124
- - Real-time daemon heartbeats and liveness
125
- - Active subagent tracking
126
- - Security alerts panel
127
- - Recent events log
128
- - Inbox for orchestrator communication
129
- - Repository sync status
130
-
131
- See `ui/README.md` for configuration, environment variables, and troubleshooting.
104
+ ## Use with Claude Code
132
105
 
133
- #### (Optional) Legacy TUI Dashboard
134
-
135
- If you prefer a terminal-based interface:
106
+ If you're using **Claude Code**, invoke `/power` at the start of each session. It loads your orchestrator brain (cardinal rules, domain map, team memory, system state) and outputs a health brief. Setup once:
136
107
 
137
108
  ```bash
138
- # On Windows (in a dedicated terminal):
139
- Start-Process "C:\Program Files\Git\git-bash.exe" -ArgumentList '-c', 'bash /c/Users/you/aesop/dash/watchdog-gui.sh'
140
-
141
- # On Unix:
142
- bash ~/aesop/dash/watchdog-gui.sh &
109
+ # Copy the /power skill
110
+ cp -r skills/power/ ~/.claude/skills/power/
143
111
  ```
144
112
 
145
- Note: The TUI is maintained for backward compatibility but is not actively developed. The web dashboard is recommended for new deployments.
146
-
147
- #### 4. Arm the monitor loop
148
-
149
- ```bash
150
- # If using Claude Code, add to your CLAUDE.md or invoke via /power:
151
- # Runs collect-signals.mjs every cycle, emits BRIEF.md + SIGNALS.json,
152
- # then acts on AUTO-tier findings or stages PROPOSE-tier changes.
153
- ```
113
+ Then in Claude Code, type `/power` or `/buildsystem` to start a wave cycle. See [skills/power/SKILL.md](./skills/power/SKILL.md) for details.
154
114
 
155
- ## Cardinal Rules (abridged)
115
+ ## Core Principles
156
116
 
157
- Read `docs/CARDINAL-RULES.md` for the full text. Core principles:
117
+ 1. **Haiku-first dispatch** Subagents always cheap; orchestrator stays lean on main thread.
118
+ 2. **Durable state** — STATE.md + BUILDLOG.md survive wipes; re-sync on resume.
119
+ 3. **Observable** — Every agent run logged, every cost tracked, every security event triaged.
120
+ 4. **TDD-first** — Fail tests before implementation; one Haiku per scoped domain.
121
+ 5. **Never wait** — Dispatch work in parallel; connect with heartbeats, not polling.
122
+ 6. **Push discipline** — feature/* branches only; secret-scan gates every push.
158
123
 
159
- 1. **Dispatch**: Haiku subagents only (cost lever). Opus orchestrates main-thread only.
160
- 2. **TDD-first**: Fail tests before implementation. Tiny scoped domains; one Haiku per domain.
161
- 3. **Reliability**: Every input produces output (brief/log/heartbeat/FAILED). Never wait.
162
- 4. **Durable state**: STATE.md + BUILDLOG.md checkpoints survive wipes. Re-sync on resume.
163
- 5. **Push discipline**: feature/branch → PR (never main). Continuously push green work.
164
- 6. **Control files**: Single-writer discipline (STATE.md orchestrator, MEMORY.md keeper, BUILDLOG.md append-only).
165
- 7. **Local execution**: Python runs locally only (no cloud runners). Reusable scripts in ~/scripts.
166
- 8. **Secret gates**: `secret_scan.py` blocks every push. No credentials in repos.
167
- 9. **Observability**: Every agent run logged, every cost tracked, every security event triaged.
124
+ Read [docs/CARDINAL-RULES.md](./docs/CARDINAL-RULES.md) for the full text.
168
125
 
169
126
  ## Requirements
170
127
 
171
- - **Claude Code CLI** (v0.1+): the agent-spawning harness.
172
- - **Git** (v2.40+): version control for durable state.
173
- - **Bash** (v4+): scripting (Git Bash on Windows, bash on Unix).
174
- - **Node.js** (v18+): for monitor signal collection and dashboard extras.
175
- - **Python** (v3.10+): for log rotation, secret-scan, and custom tooling.
176
- - **jq** (optional): JSON parsing in TUI dashboard.
128
+ - Claude Code CLI (v0.1+)
129
+ - Git (v2.40+)
130
+ - Bash (v4+) or Git Bash on Windows
131
+ - Node.js (v18+) for dashboard and monitor
132
+ - Python (v3.10+) for log rotation and secret-scan
133
+ - jq (optional) for TUI dashboard
177
134
 
178
- ## Setup Walkthrough
135
+ ## Scaling Cheaply
179
136
 
180
- ### 1. Edit your configuration
137
+ The **dispatch model** fans work across parallel Haiku subagents (each 1/3 the cost of Opus). The orchestrator stays lean on the main thread, coordinating via durable STATE.md. Result: ~25% the cost of an all-Opus fleet.
181
138
 
182
- ```bash
183
- cp aesop.config.example.json aesop.config.json
184
- ```
139
+ **Action tiers**: AUTO (immediate, logged) for read-only checks and appends; PROPOSE (staged in `monitor/PROPOSALS.md`) for changes requiring approval. See [docs/GOVERNANCE.md](./docs/GOVERNANCE.md).
185
140
 
186
- Edit `aesop.config.json`:
187
- - Set `aesop_root`, `brain_root`, `scripts_root`, `temp_root` to your paths.
188
- - List your project repos under `repos[]`.
189
- - Tune watchdog and monitor cycle times.
190
- - Disable secret-scan if you don't have `tools/secret_scan.py` yet.
141
+ ## Security
191
142
 
192
- ### 2. Create required directories
143
+ The pre-push hook (`hooks/pre-push-policy.sh`) enforces branch discipline and secret scanning locally. It is bypassable (use `--no-verify` to skip), so **pair it with GitHub branch protection** for real enforcement:
193
144
 
194
- ```bash
195
- mkdir -p ~/aesop/state
196
- mkdir -p ~/.heartbeats
197
145
  ```
198
-
199
- ### 3. (Optional) Add your secret-scan script
200
-
201
- If you have a security scanner, drop it at `aesop/tools/secret_scan.py`. The watchdog will call it before pushing.
202
-
203
- Example stub:
204
- ```python
205
- #!/usr/bin/env python3
206
- import sys
207
- sys.exit(0) # TODO: implement secret scanning
146
+ Settings > Branches > main
147
+ Require pull request reviews
148
+ ✓ Require status checks to pass
149
+ Dismiss stale PR approvals
150
+ ✓ Restrict pushes to (Admins only)
208
151
  ```
209
152
 
210
- ### 4. Start the daemon
211
-
212
- ```bash
213
- export AESOP_ROOT=$HOME/aesop
214
- bash $AESOP_ROOT/daemons/run-watchdog.sh &
215
- ```
153
+ Private brain (`~/.claude`) is never committed to this repo. Keep `aesop.config.json` git-ignored. Implement `tools/secret_scan.py` with your security rules. See [docs/HOOK-INSTALL.md](./docs/HOOK-INSTALL.md) for setup.
216
154
 
217
- Test mode: `bash $AESOP_ROOT/daemons/run-watchdog.sh --once`
155
+ ## Dashboard (Wave-14 Rewrite)
218
156
 
219
- ### 5. Launch the dashboard
157
+ The dashboard is a **React 18 + Vite + TypeScript** single-page app with four hash-routed views:
220
158
 
159
+ ### Viewing the Dashboard
221
160
  ```bash
222
- bash ~/aesop/dash/watchdog-gui.sh
161
+ python ui/serve.py
223
162
  ```
163
+ Opens `http://localhost:8770` — live fleet health, security alerts, work-item kanban, cost analytics.
224
164
 
225
- ### 6. Arm the monitor (optional)
165
+ ### Architecture
166
+ - **Backend**: Python stdlib HTTP server (`ui/handler.py`) serves the built React app + JSON/SSE APIs (`/api/state`, `/api/cost`, `/events`).
167
+ - **Frontend**: `ui/web/` (React app) is built to `dist/` (committed to git) and served as static files by the Python server.
168
+ - **CSRF protection**: Token injected into `dist/index.html` via sentinel substitution; mutations gated by `/submit` and `/api/tracker` endpoints.
226
169
 
227
- If you're using Claude Code, add this to your orchestrator loop:
170
+ ### Development
228
171
  ```bash
229
- export AESOP_ROOT=$HOME/aesop
230
- node $AESOP_ROOT/monitor/collect-signals.mjs
231
- ```
232
-
233
- The monitor will read `BRIEF.md` and `SIGNALS.json` each cycle and act on findings.
234
-
235
- ## Usage Patterns
236
-
237
- ### Dispatch model (how to scale cheaply)
238
-
239
- ```plaintext
240
- Orchestrator (main thread)
241
- ├─ Haiku subagent 1 (domain A: tests)
242
- ├─ Haiku subagent 2 (domain B: build)
243
- ├─ Haiku subagent 3 (domain C: review)
244
- └─ Haiku subagent 4 (domain D: docs)
172
+ cd ui/web
173
+ npm install
174
+ npm run dev # Vite dev server with API proxy to http://localhost:8770
175
+ npm run build # Build to dist/ (commit the dist/)
245
176
  ```
246
177
 
247
- Each subagent is **tiny**, **scoped**, and **disposable**. Total cost: ~25% of all-Opus fleet.
248
-
249
- ### Action tiers (AUTO vs PROPOSE)
250
-
251
- - **AUTO**: immediate + logged (read-only checks, appends to logs, heartbeat updates).
252
- - **PROPOSE**: staged in `monitor/PROPOSALS.md`, requires user approval before execution.
253
-
254
- ### Heartbeat pattern
255
-
256
- Daemons write epoch-seconds to `.heartbeat` files. The dashboard reads these to detect stalls:
257
- - Watchdog: alert if >300s old.
258
- - Monitor: alert if >3600s old.
259
- - Custom loops: check before spawning (skip if <200s).
178
+ The dev server proxies `/data`, `/api`, `/events`, `/agent`, `/submit` to the Python backend on :8770, so the frontend can develop against live APIs.
260
179
 
261
- ## Security & Privacy
180
+ ### Views
181
+ - **Overview**: Fleet agents, security alerts, recent events.
182
+ - **Work** (`#/work`): Tracker kanban (4 lanes: proposed/ranked/in-progress/done), audit backlog progress.
183
+ - **Activity** (`#/activity`): Agent timeline, main-thread message tail (live reasoning).
184
+ - **Cost** (`#/cost`): Per-model spend/tokens, per-day bar chart, verdict scorecard (success/failure rates).
262
185
 
263
- **⚠️ Important**: This harness assumes a **private brain directory** (`~/.claude`) that is **NEVER committed** to this repo. Your cardinal rules, agent catalog, and memory belong in your private remote (e.g., `claude-config`).
186
+ ## Extending Aesop
264
187
 
265
- - `aesop.config.json` is git-ignored (keep your paths secret).
266
- - `state/` and `.log` files are git-ignored (keep runtime data local).
267
- - Implement `tools/secret_scan.py` with your own security rules.
268
- - Use `secret_scan.py` as a gate on every push (don't bypass).
188
+ **Custom signal collectors**: Edit `monitor/collect-signals.mjs` to add domain-specific health checks.
269
189
 
270
- ## Extension points
190
+ **Custom watchdog hooks**: Edit `daemons/backup-fleet.sh` to run linters, integrate with your CI, or customize secret-scan logic.
271
191
 
272
- ### Add a custom signal collector
273
-
274
- Edit `monitor/collect-signals.mjs`:
275
- ```javascript
276
- // Example: detect junk scripts
277
- function findJunkScripts() {
278
- const junk = fs.readdirSync('/tmp').filter(f => f.endsWith('.py'));
279
- return junk;
280
- }
281
-
282
- // Then add to signals:
283
- signals.junkScripts = findJunkScripts();
284
- ```
285
-
286
- ### Customize the watchdog
287
-
288
- Edit `daemons/backup-fleet.sh`:
289
- - Parse `aesop.config.json` to discover repos dynamically.
290
- - Add per-repo hooks (e.g., run linters before backup).
291
- - Implement your own secret-scan gate.
292
-
293
- ### Extend the dashboard
294
-
295
- Edit `dash/watchdog-gui.sh`:
296
- - Add panels for CPU/memory/disk usage.
297
- - Integrate with your monitoring system.
298
- - Color-code alerts by severity.
192
+ **Dashboard components**: Add React components in `ui/web/src/components/` or new views in `ui/web/src/views/`. Rebuild and commit `dist/`.
299
193
 
300
194
  ## Troubleshooting
301
195
 
302
- ### Watchdog doesn't start
303
-
304
- Check `state/FLEET-BACKUP.log` for errors. Verify `AESOP_ROOT` is set correctly.
196
+ | Issue | Check |
197
+ |-------|-------|
198
+ | Watchdog doesn't start | `state/FLEET-BACKUP.log` for errors; verify `AESOP_ROOT` is set |
199
+ | Dashboard shows "unavailable" | Install Node.js v18+; check `dash-extra.mjs` is in sync |
200
+ | Secret-scan blocks push | Add suppression to `tools/secret_scan.py`; no auto-bypass (by design) |
201
+ | Monitor doesn't start | Verify Node.js on PATH; check `monitor/BRIEF.md` for logs |
305
202
 
306
- ### Dashboard shows "unavailable"
203
+ For deeper docs, see `docs/`:
204
+ - `CARDINAL-RULES.md` — full 10 principles
205
+ - `DISPATCH-MODEL.md` — cost analysis and patterns
206
+ - `CHECKPOINTING.md` — how STATE.md + BUILDLOG.md survive wipes
207
+ - `GOVERNANCE.md` — AUTO/PROPOSE tiers
208
+ - `case-study-portfolio.md` — How Aesop built its own portfolio site; full audit trail and cost breakdown
307
209
 
308
- - If you see `(agents/processes panel unavailable)`, `node` is missing or `dash-extra.mjs` is not in sync.
309
- - Install Node.js v18+ and re-run.
210
+ See [CHANGELOG.md](./CHANGELOG.md) for release notes.
310
211
 
311
- ### Secret-scan blocks a legitimate push
312
-
313
- Add a suppression to your `tools/secret_scan.py`. Aesop never auto-bypasses gates (by design).
314
-
315
- ### Monitor doesn't start
212
+ ## Contributing
316
213
 
317
- Ensure Node.js is on PATH and `collect-signals.mjs` has execute permissions. Check `monitor/BRIEF.md` for the latest cycle log.
214
+ Aesop welcomes improvements. The repo uses its own `/buildsystem` loop for development—PRs from `feature/*` branches are built, tested, and merged by Aesop itself. To contribute:
318
215
 
319
- ## Architecture deep-dives
216
+ 1. Fork and create a `feature/*` branch.
217
+ 2. Write failing tests first (TDD).
218
+ 3. Open a PR; Aesop's wave cycle will verify and merge.
320
219
 
321
- See `docs/` for detailed guides:
322
- - `CARDINAL-RULES.md` — full text of the 10 cardinal rules.
323
- - `DISPATCH-MODEL.md` — cost analysis and parallel orchestration patterns.
324
- - `STATE-MACHINE.md` — how STATE.md and BUILDLOG.md survive wipes.
325
- - `MONITOR-GOVERNANCE.md` — monitor AUTO/PROPOSE tiers and approval flow.
220
+ Maintain the core principles: **Haiku-first** subagents, **lean** orchestrator, **durable** state, **observable** machinery.
326
221
 
327
222
  ## License
328
223
 
329
- MIT License. See `LICENSE` file.
330
-
331
- ## Contributing
332
-
333
- Aesop is open-source and welcomes improvements. To contribute:
334
-
335
- 1. Fork this repo.
336
- 2. Create a feature branch: `git checkout -b feature/your-idea`.
337
- 3. Add tests (TDD first).
338
- 4. Commit with clear messages.
339
- 5. Push to origin and open a PR.
340
-
341
- Maintain the cardinal rules: keep subagents cheap (Haiku), orchestrator lean, state durable, and machinery observable.
224
+ MIT. See `LICENSE`.
342
225
 
343
226
  ## References
344
227
 
345
- - [Anthropic Claude API](https://docs.anthropic.com)
228
+ - [Anthropic Claude API docs](https://docs.anthropic.com)
346
229
  - [Claude Code CLI](https://github.com/anthropics/claude-code)
347
- - [Git documentation](https://git-scm.com/doc)
348
- - Inspiration: "The Missing Memory Layer", "Agent Cost Trauma", "120 Words to Shipped" (publications on AI orchestration patterns).
230
+ - [Git docs](https://git-scm.com/doc)
349
231
 
350
232
  ---
351
233
 
352
- **Aesop Contributors**
353
- Built with the fable-fleet dispatch model in mind. May your orchestrator be wise and your subagents swift.
234
+ **Aesop**: Fable-fleet orchestration, built by Aesop itself. May your orchestrator be wise and your subagents swift.
@@ -1,47 +1,55 @@
1
1
  {
2
- "description": "Aesop configuration example. Copy to aesop.config.json and customize for your setup.",
3
- "aesop_root": "/path/to/aesop",
4
- "brain_root": "/path/to/your/brain",
5
- "scripts_root": "/path/to/your/scripts",
6
- "temp_root": "/path/to/temp/scratch",
2
+ "description": "Aesop configuration. Precedence: environment variables > config file > built-in defaults.",
3
+ "_paths": {
4
+ "aesop_root": "Set via AESOP_ROOT env var (no config key)",
5
+ "brain_root": "Override via BRAIN_ROOT env var or config; default: {aesop_root}/../.claude",
6
+ "scripts_root": "Override via SCRIPTS_ROOT env var or config; default: {aesop_root}/../scripts",
7
+ "temp_root": "Override via TEMP_ROOT env var or config; default: system temp + /claude",
8
+ "state_root": "Override via AESOP_STATE_ROOT env var or config; default: {aesop_root}/state",
9
+ "fleet_root": "Override via AESOP_FLEET_ROOT env var or config; default: $HOME. SECURITY: all repository clone targets must remain under fleet_root to prevent credential harvesting across account boundaries. The monitor validates clone targets on each cycle and surfaces violations as HIGH alerts.",
10
+ "transcripts_root": "Override via AESOP_TRANSCRIPTS_ROOT env var or config; default: ~/.claude/projects"
11
+ },
12
+ "brain_root": "~/.claude",
13
+ "scripts_root": "~/scripts",
14
+ "temp_root": "~/.aesop-temp",
15
+ "_temp_root_notes": "Portable path for temporary aesop files. ~ expands to home directory on both Windows and POSIX. Alternatively, on Windows set to %TEMP%/aesop, on POSIX set to /tmp/aesop. Config loaders expand ~ at runtime.",
16
+ "state_root": "./state",
17
+ "fleet_root": "/path/to/fleet",
18
+ "transcripts_root": "~/.claude/projects",
7
19
  "repos": [
8
20
  {
9
21
  "path": "/path/to/project1",
10
22
  "name": "project1",
23
+ "url": "https://github.com/user/project1.git",
11
24
  "primary_branch": "main",
12
25
  "backup_branch": "backup/wip"
13
26
  },
14
27
  {
15
28
  "path": "/path/to/project2",
16
29
  "name": "project2",
30
+ "url": "git@github.com:user/project2.git",
17
31
  "primary_branch": "main",
18
32
  "backup_branch": "backup/wip"
19
33
  }
20
34
  ],
21
- "watchdog": {
22
- "cycle_seconds": 150,
23
- "heartbeat_threshold_seconds": 200,
24
- "enable_secret_scan": true,
25
- "secret_scan_script": "tools/secret_scan.py"
26
- },
27
35
  "monitor": {
28
- "enable": true,
29
- "cycle_seconds": 3600,
30
- "heartbeat_threshold_seconds": 3600,
31
- "memory_staleness_days": 30,
32
36
  "log_max_lines": 500,
33
- "log_max_kb": 40
34
- },
35
- "dashboard": {
36
- "refresh_seconds": 1,
37
- "enable_jq_parsing": true,
38
- "theme": "dark"
37
+ "log_max_kb": 40,
38
+ "extended_signals": false,
39
+ "heartbeat_thresholds": {
40
+ "monitor": 3600,
41
+ "watchdog": 300,
42
+ "default": 1800
43
+ }
39
44
  },
40
45
  "cardinal_rules": {
41
- "subagent_model": "haiku",
42
- "orchestrator_model": "opus",
43
- "tdd_first": true,
44
- "never_push_main": true,
45
- "secret_scan_gates_push": true
46
+ "subagent_model": "haiku"
47
+ },
48
+ "alerts": {
49
+ "_comment": "Slack/Discord webhook integration for fleet alerts. webhook_url: null (default) disables alerts (feature opt-in). SETUP: (1) Slack: Create an app at https://api.slack.com/apps, enable 'Incoming Webhooks', add a new webhook to your channel, copy the Webhook URL. (2) Discord: In your Discord server, go to Server Settings > Integrations > Webhooks, create a webhook, copy its URL. SECURITY: NEVER commit a real webhook URL to version control — retrieve at runtime via environment variable AESOP_ALERTS_WEBHOOK_URL or load from a .env.local file. Provider: 'slack' (block-kit format) or 'discord' (embed format). min_severity: filter by HIGH/CRITICAL/etc. heartbeat_stall_s: alert if watchdog heartbeat older than N seconds (null = skip).",
50
+ "webhook_url": null,
51
+ "provider": "slack",
52
+ "min_severity": "HIGH",
53
+ "heartbeat_stall_s": 600
46
54
  }
47
55
  }
package/bin/CLAUDE.md ADDED
@@ -0,0 +1,67 @@
1
+ # bin/ — CLI scaffolder
2
+
3
+ **Purpose**: Node.js CLI entry point that clones the aesop orchestration template into a target directory with idempotent validation, plus an interactive onboarding wizard for new adopters.
4
+
5
+ ## Invocation
6
+
7
+ - **npm registry**: `npx @matt82198/aesop [target-dir]` (default: `aesop-fleet`)
8
+ - **Local dev**: `node bin/cli.js [target-dir]`
9
+ - **Help**: `npx @matt82198/aesop --help` or `-h`
10
+ - **Interactive wizard**: `npx @matt82198/aesop wizard` (on a TTY, prompts; with `--yes`, uses defaults)
11
+
12
+ ## What gets copied
13
+
14
+ Files in `filesToCopy` array (cli.js line 57–69):
15
+ - **Directories**: `daemons/`, `dash/`, `monitor/`, `tools/`, `ui/`, `docs/`
16
+ - **Files**: `aesop.config.example.json`, `README.md`, `LICENSE`, `CHANGELOG.md`, `CLAUDE-TEMPLATE.md`
17
+ - **Brain templates** (in docs/): `MEMORY-TEMPLATE.md` (via docs/ directory copy)
18
+
19
+ ## What does NOT get copied
20
+
21
+ - `aesop.config.json` (users must `cp aesop.config.example.json` and edit)
22
+ - `state/` (runtime durable state, git-ignored, created by daemons)
23
+ - `.git/`, `node_modules/`, build artifacts
24
+
25
+ ## Post-scaffold guidance
26
+
27
+ Scaffolder prints steps for users:
28
+ 1. `cd target-dir && cp aesop.config.example.json aesop.config.json`
29
+ 2. Edit config with paths and repos
30
+ 3. Initialize brain: `cp CLAUDE-TEMPLATE.md ~/.claude/CLAUDE.md` (edit)
31
+ 4. Initialize memory: `cp docs/MEMORY-TEMPLATE.md ~/.claude/MEMORY.md` (edit)
32
+ 5. Test daemon: `bash daemons/run-watchdog.sh --once`
33
+ 6. Launch dashboard: `python ui/serve.py`
34
+
35
+ ## Interactive wizard (`aesop wizard`)
36
+
37
+ The wizard mode provides an interactive onboarding flow for new adopters, guiding them through fleet setup in ~60 seconds:
38
+
39
+ 1. **Trigger**: `npx @matt82198/aesop wizard` on a TTY (interactive terminal)
40
+ 2. **Questions** (all have sensible defaults, press Enter-Enter-Enter to skip):
41
+ - Project name (default: "my-fleet")
42
+ - Repos to watch (auto-discovers git repos under `~`, offers choices)
43
+ - Dashboard port (default: 8770, validates 1–65535)
44
+ - Brain root directory (default: `~/.claude`)
45
+ 3. **Output**:
46
+ - Scaffolds template files
47
+ - Generates CLAUDE.md (substituted with project name)
48
+ - Generates aesop.config.json (with discovered repos)
49
+ - Prints "next 3 commands" epilogue
50
+ - Offers to run `watchdog --once` smoke test immediately
51
+ 4. **Non-interactive mode** (`--yes` flag or non-TTY stdin): Uses defaults, zero prompts (CI-safe)
52
+
53
+ ### Wizard implementation details
54
+
55
+ - **Repo discovery** (`discoverRepos`): Scans `~` for `.git` directories at first level (non-recursive)
56
+ - **Port validation** (`validatePort`): Rejects invalid ports, accepts 1–65535
57
+ - **Portable paths**: All config paths use `~` form (`~/.claude`, `~/scripts`, etc.) for cross-platform compatibility
58
+ - **Defaults**: Every prompt has a default so users can skip it (press Enter)
59
+ - **Non-destructive**: Never overwrites existing `aesop.config.json` without user confirmation
60
+
61
+ ## Invariants & gotchas
62
+
63
+ - **Idempotent on empty targets**: Fails if `targetDir` exists and is non-empty (non-destructive). Safe to retry.
64
+ - **Adding shipped files**: Any new file/dir added to `filesToCopy` array must also be added to `package.json` `files` array (lines 9–21 in package.json) so npm publish includes it.
65
+ - **No machine-specific paths**: Use relative paths only; `__dirname` and `path.join()` handle cross-platform resolution.
66
+ - **Wizard prompts are async**: Main execution is wrapped in async IIFE to support readline prompts
67
+ - **Help text accuracy**: If invocation steps or output paths change, update help text