@matt82198/aesop 0.1.0-beta.4 → 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 (174) hide show
  1. package/CHANGELOG.md +46 -5
  2. package/README.md +57 -1
  3. package/aesop.config.example.json +8 -1
  4. package/bin/CLAUDE.md +30 -2
  5. package/bin/cli.js +286 -73
  6. package/daemons/CLAUDE.md +4 -1
  7. package/daemons/run-watchdog.sh +5 -2
  8. package/docs/RELEASING.md +159 -0
  9. package/docs/archive/README.md +3 -0
  10. package/docs/{spikes → archive/spikes}/tiered-cognition/README.md +1 -3
  11. package/docs/case-study-portfolio.md +61 -0
  12. package/docs/self-stats-data.json +11 -0
  13. package/docs/templates/FLEET-OPS-ANALYSIS.example.md +27 -0
  14. package/docs/templates/FLEET-OPS-RECOMMENDATIONS.example.md +24 -0
  15. package/docs/templates/PROPOSALS-LOG.example.md +64 -0
  16. package/hooks/CLAUDE.md +23 -0
  17. package/mcp/CLAUDE.md +213 -0
  18. package/mcp/package.json +26 -0
  19. package/mcp/server.mjs +543 -0
  20. package/monitor/CHARTER.md +76 -110
  21. package/monitor/collect-signals.mjs +85 -0
  22. package/package.json +4 -1
  23. package/scan/fleet-scan.example.mjs +292 -0
  24. package/skills/healthcheck/SKILL.md +44 -0
  25. package/state_store/CLAUDE.md +39 -0
  26. package/state_store/__init__.py +24 -0
  27. package/state_store/__pycache__/__init__.cpython-314.pyc +0 -0
  28. package/state_store/__pycache__/api.cpython-314.pyc +0 -0
  29. package/state_store/__pycache__/export.cpython-314.pyc +0 -0
  30. package/state_store/__pycache__/ingest.cpython-314.pyc +0 -0
  31. package/state_store/__pycache__/projections.cpython-314.pyc +0 -0
  32. package/state_store/__pycache__/store.cpython-314.pyc +0 -0
  33. package/state_store/api.py +35 -0
  34. package/state_store/export.py +19 -0
  35. package/state_store/ingest.py +24 -0
  36. package/state_store/projections.py +52 -0
  37. package/state_store/store.py +102 -0
  38. package/tools/CLAUDE.md +30 -149
  39. package/tools/__pycache__/alert_bridge.cpython-314.pyc +0 -0
  40. package/tools/__pycache__/ci_merge_wait.cpython-314.pyc +0 -0
  41. package/tools/__pycache__/fleet_prompt_extractor.cpython-314.pyc +0 -0
  42. package/tools/__pycache__/healthcheck.cpython-314.pyc +0 -0
  43. package/tools/__pycache__/metrics_gate.cpython-314.pyc +0 -0
  44. package/tools/__pycache__/secret_scan.cpython-314.pyc +0 -0
  45. package/tools/__pycache__/self_stats.cpython-314.pyc +0 -0
  46. package/tools/__pycache__/session_usage_summary.cpython-314.pyc +0 -0
  47. package/tools/__pycache__/stall_check.cpython-314.pyc +0 -0
  48. package/tools/__pycache__/transcript_replay.cpython-314.pyc +0 -0
  49. package/tools/__pycache__/transcript_timeline.cpython-314.pyc +0 -0
  50. package/tools/__pycache__/verify_dash.cpython-314.pyc +0 -0
  51. package/tools/__pycache__/verify_submit_encoding.cpython-314.pyc +0 -0
  52. package/tools/alert_bridge.py +449 -0
  53. package/tools/ci_merge_wait.py +121 -8
  54. package/tools/fleet_prompt_extractor.py +134 -0
  55. package/tools/healthcheck.py +296 -0
  56. package/tools/secret_scan.py +8 -1
  57. package/tools/self_stats.py +509 -0
  58. package/tools/session_usage_summary.py +198 -0
  59. package/tools/svg_to_png.mjs +50 -0
  60. package/tools/transcript_replay.py +236 -0
  61. package/tools/transcript_timeline.py +184 -0
  62. package/tools/verify_dash.py +361 -542
  63. package/tools/verify_submit_encoding.py +12 -4
  64. package/ui/CLAUDE.md +57 -41
  65. package/ui/__pycache__/agents.cpython-314.pyc +0 -0
  66. package/ui/__pycache__/collectors.cpython-314.pyc +0 -0
  67. package/ui/__pycache__/config.cpython-314.pyc +0 -0
  68. package/ui/__pycache__/cost.cpython-314.pyc +0 -0
  69. package/ui/__pycache__/csrf.cpython-314.pyc +0 -0
  70. package/ui/__pycache__/handler.cpython-314.pyc +0 -0
  71. package/ui/__pycache__/render.cpython-314.pyc +0 -0
  72. package/ui/__pycache__/serve.cpython-314.pyc +0 -0
  73. package/ui/__pycache__/sse.cpython-314.pyc +0 -0
  74. package/ui/agents.py +9 -5
  75. package/ui/api/__pycache__/submit.cpython-314.pyc +0 -0
  76. package/ui/api/submit.py +44 -5
  77. package/ui/collectors.py +184 -35
  78. package/ui/config.py +9 -0
  79. package/ui/cost.py +260 -0
  80. package/ui/csrf.py +7 -3
  81. package/ui/handler.py +254 -4
  82. package/ui/render.py +26 -6
  83. package/ui/sse.py +16 -1
  84. package/ui/web/.gitattributes +13 -0
  85. package/ui/web/dist/assets/index-2LZDQirC.js +9 -0
  86. package/ui/web/dist/assets/index-D4M1qyOv.css +1 -0
  87. package/ui/web/dist/index.html +14 -0
  88. package/ui/web/index.html +13 -0
  89. package/ui/web/package-lock.json +2225 -0
  90. package/ui/web/package.json +26 -0
  91. package/ui/web/src/App.test.tsx +74 -0
  92. package/ui/web/src/App.tsx +142 -0
  93. package/ui/web/src/CONTRIBUTING-UI.md +49 -0
  94. package/ui/web/src/components/AgentRow.css +187 -0
  95. package/ui/web/src/components/AgentRow.test.tsx +209 -0
  96. package/ui/web/src/components/AgentRow.tsx +207 -0
  97. package/ui/web/src/components/AgentsPanel.css +108 -0
  98. package/ui/web/src/components/AgentsPanel.test.tsx +41 -0
  99. package/ui/web/src/components/AgentsPanel.tsx +58 -0
  100. package/ui/web/src/components/AlertsPanel.css +88 -0
  101. package/ui/web/src/components/AlertsPanel.test.tsx +51 -0
  102. package/ui/web/src/components/AlertsPanel.tsx +67 -0
  103. package/ui/web/src/components/BacklogPanel.test.tsx +126 -0
  104. package/ui/web/src/components/BacklogPanel.tsx +122 -0
  105. package/ui/web/src/components/CostChart.css +110 -0
  106. package/ui/web/src/components/CostChart.test.tsx +144 -0
  107. package/ui/web/src/components/CostChart.tsx +152 -0
  108. package/ui/web/src/components/CostTable.css +93 -0
  109. package/ui/web/src/components/CostTable.test.tsx +165 -0
  110. package/ui/web/src/components/CostTable.tsx +94 -0
  111. package/ui/web/src/components/EventsFeed.css +68 -0
  112. package/ui/web/src/components/EventsFeed.test.tsx +36 -0
  113. package/ui/web/src/components/EventsFeed.tsx +31 -0
  114. package/ui/web/src/components/HealthHeader.css +137 -0
  115. package/ui/web/src/components/HealthHeader.test.tsx +278 -0
  116. package/ui/web/src/components/HealthHeader.tsx +281 -0
  117. package/ui/web/src/components/InboxForm.css +135 -0
  118. package/ui/web/src/components/InboxForm.test.tsx +208 -0
  119. package/ui/web/src/components/InboxForm.tsx +116 -0
  120. package/ui/web/src/components/MessagesTail.module.css +144 -0
  121. package/ui/web/src/components/MessagesTail.test.tsx +176 -0
  122. package/ui/web/src/components/MessagesTail.tsx +94 -0
  123. package/ui/web/src/components/ReposPanel.css +90 -0
  124. package/ui/web/src/components/ReposPanel.test.tsx +45 -0
  125. package/ui/web/src/components/ReposPanel.tsx +67 -0
  126. package/ui/web/src/components/Scorecard.css +106 -0
  127. package/ui/web/src/components/Scorecard.test.tsx +117 -0
  128. package/ui/web/src/components/Scorecard.tsx +85 -0
  129. package/ui/web/src/components/Timeline.module.css +151 -0
  130. package/ui/web/src/components/Timeline.test.tsx +215 -0
  131. package/ui/web/src/components/Timeline.tsx +99 -0
  132. package/ui/web/src/components/TrackerBoard.test.tsx +121 -0
  133. package/ui/web/src/components/TrackerBoard.tsx +107 -0
  134. package/ui/web/src/components/TrackerCard.test.tsx +180 -0
  135. package/ui/web/src/components/TrackerCard.tsx +160 -0
  136. package/ui/web/src/components/TrackerForm.test.tsx +189 -0
  137. package/ui/web/src/components/TrackerForm.tsx +144 -0
  138. package/ui/web/src/lib/api.ts +218 -0
  139. package/ui/web/src/lib/format.test.ts +89 -0
  140. package/ui/web/src/lib/format.ts +103 -0
  141. package/ui/web/src/lib/sanitizeUrl.test.ts +84 -0
  142. package/ui/web/src/lib/sanitizeUrl.ts +38 -0
  143. package/ui/web/src/lib/types.ts +230 -0
  144. package/ui/web/src/lib/useHashRoute.test.ts +60 -0
  145. package/ui/web/src/lib/useHashRoute.ts +23 -0
  146. package/ui/web/src/lib/useSSE.ts +175 -0
  147. package/ui/web/src/main.tsx +10 -0
  148. package/ui/web/src/styles/global.css +179 -0
  149. package/ui/web/src/styles/theme.css +184 -0
  150. package/ui/web/src/styles/work.css +572 -0
  151. package/ui/web/src/test/fixtures.ts +385 -0
  152. package/ui/web/src/test/setup.ts +49 -0
  153. package/ui/web/src/views/Activity.module.css +43 -0
  154. package/ui/web/src/views/Activity.test.tsx +89 -0
  155. package/ui/web/src/views/Activity.tsx +31 -0
  156. package/ui/web/src/views/Cost.css +87 -0
  157. package/ui/web/src/views/Cost.test.tsx +142 -0
  158. package/ui/web/src/views/Cost.tsx +54 -0
  159. package/ui/web/src/views/Overview.css +51 -0
  160. package/ui/web/src/views/Overview.test.tsx +76 -0
  161. package/ui/web/src/views/Overview.tsx +46 -0
  162. package/ui/web/src/views/Work.test.tsx +82 -0
  163. package/ui/web/src/views/Work.tsx +79 -0
  164. package/ui/web/src/vite-env.d.ts +10 -0
  165. package/ui/web/tsconfig.json +22 -0
  166. package/ui/web/vite.config.ts +25 -0
  167. package/ui/web/vitest.config.ts +12 -0
  168. package/ui/templates/dashboard.html +0 -1202
  169. /package/docs/{spikes → archive/spikes}/tiered-cognition/ACTIVATION.md +0 -0
  170. /package/docs/{spikes → archive/spikes}/tiered-cognition/DESIGN.md +0 -0
  171. /package/docs/{spikes → archive/spikes}/tiered-cognition/FINDINGS.md +0 -0
  172. /package/docs/{spikes → archive/spikes}/tiered-cognition/aesop-cognition.example.md +0 -0
  173. /package/docs/{spikes → archive/spikes}/tiered-cognition/force-model-policy.merged.mjs +0 -0
  174. /package/docs/{spikes → archive/spikes}/tiered-cognition/strip-tools-hook.mjs +0 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,41 @@ All notable changes to Aesop are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ### Added (Wave-16/17 in-flight)
11
+ - CLAUDE.md minimization and domain map refinements (PR #151).
12
+ - Isolation detector and machinery/scripts port (PR #150).
13
+ - MCP server and scan/ directory shipping in npm package.
14
+ - README stats refresh and agent-catalog reference.
15
+
16
+ ## [0.1.0-beta.5] - 2026-07-15
17
+
18
+ ### Added (Wave-15)
19
+ - **State-Sourced State Layer** (#134, #135): Event-sourced SQLite WAL backing store with projections; tracker.json re-rendered as export for git integration; dual-path mutations via StateAPI.
20
+ - **Self-Building Stats** (#130): `tools/self_stats.py` computes verified repository metrics (merged PRs, commits, waves, files, coauthors) live from git; README stats block auto-populated via CI drift gate.
21
+ - **MCP Fleet Server** (#121): Read-only MCP server exposing fleet status, agents, tracker, costs for external Claude integrations.
22
+ - **Alert Webhook Bridge** (#120): Incoming HTTP webhook relay to monitor alerts; configurable signing + filtering.
23
+ - **Onboarding Wizard** (#127): Interactive CLI scaffolder with guided config, hook setup, repo discovery.
24
+ - **Healthcheck Skill** (#126): Liveness probe skill for orchestrator health; integrated into monitor signal collection.
25
+ - **Symlink/Junction Coverage** (#125): Test coverage for path-traversal guards; validates symlink/junction rejection in backup and UI handlers.
26
+
27
+ ### Changed (Wave-15)
28
+ - **Agent Detail Rendering** (#128): Transcript lookup fixed for parallel agent teams; handles multi-file agent logs.
29
+ - **CI Cascade** (#122, #131, #132, #133): Tools-index alert bridge integration; SSE transcript fixture isolation; favicon verification; node_modules secret-scan gate.
30
+
31
+ ### Fixed (Wave-15)
32
+ - **Socket Race** (#129): stderr noise from concurrent SSE keepalive; added locking around socket writes.
33
+ - **State Store Concurrency Seams** (#138): Inbox-drain deduplication, render-failure recovery, migration guard.
34
+ - **CSRF HTTPS Origins** (#137): Accept https loopback origins in CSRF validation.
35
+ - **CI/Daemon Machinery** (#136): Dist-freshness gate enforcement; watchdog script-relative path fix.
36
+ - **Dashboard UX Hardening** (#141): Stale-data timestamps, empty states, lane badges, a11y improvements.
37
+
38
+ ### Documentation (Wave-15)
39
+ - **RELEASING.md** (#140): Release process documentation; npm publish and CI merge procedures.
40
+ - **Currency Sweep** (#140): CHANGELOG #113–#135 documentation; README state_store and stats updates; CLAUDE.md drift correction; beta.5 preparation.
41
+ - **Portfolio Case Study** (#139): Matt Culliton personal portfolio documentation; agent-fleet-built showcase.
42
+
8
43
  ## [0.1.0-beta.4] - 2026-07-14
9
44
 
10
45
  ### Added (Wave-13)
@@ -15,13 +50,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
15
50
  - Test/CI wiring: doc-drift and domain-map test verification.
16
51
  - Machinery gates: secret-scan enforcement, pre-push hook gating.
17
52
 
18
- ## [Unreleased]
53
+ ### Added (Wave-14)
54
+ - **Dashboard Rewrite**: Complete React 18 + Vite + TypeScript redesign with 4 hash-routed views (Overview, Work, Activity, Cost), sticky health header, live SSE updates, light/dark theming with WCAG AA contrast, keyboard navigation, and `aria-live` regions.
55
+ - **Frontend Architecture**: Zero runtime dependencies beyond React/React-dom; Vite dev server with API proxy; committed `dist/` serves as authoritative build with content-hashed assets and immutable cache headers.
56
+ - **Backend Additions**: `/api/state` consolidated first-paint snapshot (one round trip), `/api/session` for Vite dev server CSRF fallback, `/api/cost` cost/scorecard collector from `OUTCOMES-LEDGER.md` with optional pricing map and per-model/per-day aggregates.
57
+ - **Cost Analytics**: Per-model token totals, per-day bar chart (pure SVG), verdict scorecard (success/failure/hung rates), configurable pricing estimates from `aesop.config.json`.
58
+ - **Testing Infrastructure**: Vitest + Testing Library component tests, rewritten `tools/verify_dash.py` (Playwright) with data-testid-based assertions, CI drift gate for committed dist, a11y/theme verification in CI.
19
59
 
20
- ### Added
21
- - **Stall Detection** (wave-12): `tools/stall_check.py` silent-hang detection for the agent watchdog.
22
- - **CI-Gated Merge Helper** (wave-12): `tools/ci_merge_wait.py` awaits CI success before merge.
60
+ ### Changed (Wave-14)
61
+ - **Dashboard Cutover**: `ui/templates/dashboard.html` deleted; `ui/handler.py` serve_html now returns hard 500 if dist missing (no fallback).
62
+ - **Render Module**: `render.py` requires `template_path` parameter (no legacy default); raises TypeError if called without it.
63
+ - **API Contract**: SSE emits 6 sections (added `cost`); `/api/state` returns consolidated snapshot for optimal first paint.
23
64
 
24
- ### Fixed
65
+ ### Fixed (Wave-14)
25
66
  - **Wave-12 Stability**: Swallowed failures now loud; `sse.reset_state()` locked for concurrent test isolation; tracker writes in tempdir; symlink/path-injection guards in rotate-logs.
26
67
  - **Wave-11 Security**: Dangling symlink inbox rejection; real handler exercise over HTTP; staged merge tier + model policy hook.
27
68
 
package/README.md CHANGED
@@ -46,6 +46,8 @@ python ui/serve.py
46
46
 
47
47
  Pre-push hook auto-installed. See [docs/HOOK-INSTALL.md](./docs/HOOK-INSTALL.md) for branch protection pairing.
48
48
 
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.
50
+
49
51
  ### Or: git clone for hacking
50
52
 
51
53
  ```bash
@@ -77,6 +79,28 @@ STATE.md + BUILDLOG.md Git-committed, survives machine wipes
77
79
 
78
80
  See [docs/DISPATCH-MODEL.md](./docs/DISPATCH-MODEL.md) for cost analysis and parallel patterns.
79
81
 
82
+ <!-- SELF-STATS:START -->
83
+
84
+ ## Aesop builds itself
85
+
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.
87
+
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) --> |
97
+
98
+ <!-- SELF-STATS:END -->
99
+
100
+ ## Recommended Agents
101
+
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.
103
+
80
104
  ## Use with Claude Code
81
105
 
82
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:
@@ -128,13 +152,44 @@ Settings > Branches > main
128
152
 
129
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.
130
154
 
155
+ ## Dashboard (Wave-14 Rewrite)
156
+
157
+ The dashboard is a **React 18 + Vite + TypeScript** single-page app with four hash-routed views:
158
+
159
+ ### Viewing the Dashboard
160
+ ```bash
161
+ python ui/serve.py
162
+ ```
163
+ Opens `http://localhost:8770` — live fleet health, security alerts, work-item kanban, cost analytics.
164
+
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.
169
+
170
+ ### Development
171
+ ```bash
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/)
176
+ ```
177
+
178
+ The dev server proxies `/data`, `/api`, `/events`, `/agent`, `/submit` to the Python backend on :8770, so the frontend can develop against live APIs.
179
+
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).
185
+
131
186
  ## Extending Aesop
132
187
 
133
188
  **Custom signal collectors**: Edit `monitor/collect-signals.mjs` to add domain-specific health checks.
134
189
 
135
190
  **Custom watchdog hooks**: Edit `daemons/backup-fleet.sh` to run linters, integrate with your CI, or customize secret-scan logic.
136
191
 
137
- **Dashboard panels**: Edit `ui/serve.py` or `dash/watchdog-gui.sh` to surface your metrics.
192
+ **Dashboard components**: Add React components in `ui/web/src/components/` or new views in `ui/web/src/views/`. Rebuild and commit `dist/`.
138
193
 
139
194
  ## Troubleshooting
140
195
 
@@ -150,6 +205,7 @@ For deeper docs, see `docs/`:
150
205
  - `DISPATCH-MODEL.md` — cost analysis and patterns
151
206
  - `CHECKPOINTING.md` — how STATE.md + BUILDLOG.md survive wipes
152
207
  - `GOVERNANCE.md` — AUTO/PROPOSE tiers
208
+ - `case-study-portfolio.md` — How Aesop built its own portfolio site; full audit trail and cost breakdown
153
209
 
154
210
  See [CHANGELOG.md](./CHANGELOG.md) for release notes.
155
211
 
@@ -6,7 +6,7 @@
6
6
  "scripts_root": "Override via SCRIPTS_ROOT env var or config; default: {aesop_root}/../scripts",
7
7
  "temp_root": "Override via TEMP_ROOT env var or config; default: system temp + /claude",
8
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: validate clone targets remain under this root)",
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
10
  "transcripts_root": "Override via AESOP_TRANSCRIPTS_ROOT env var or config; default: ~/.claude/projects"
11
11
  },
12
12
  "brain_root": "~/.claude",
@@ -44,5 +44,12 @@
44
44
  },
45
45
  "cardinal_rules": {
46
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
47
54
  }
48
55
  }
package/bin/CLAUDE.md CHANGED
@@ -1,12 +1,13 @@
1
1
  # bin/ — CLI scaffolder
2
2
 
3
- **Purpose**: Node.js CLI entry point that clones the aesop orchestration template into a target directory with idempotent validation.
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
4
 
5
5
  ## Invocation
6
6
 
7
7
  - **npm registry**: `npx @matt82198/aesop [target-dir]` (default: `aesop-fleet`)
8
8
  - **Local dev**: `node bin/cli.js [target-dir]`
9
9
  - **Help**: `npx @matt82198/aesop --help` or `-h`
10
+ - **Interactive wizard**: `npx @matt82198/aesop wizard` (on a TTY, prompts; with `--yes`, uses defaults)
10
11
 
11
12
  ## What gets copied
12
13
 
@@ -31,9 +32,36 @@ Scaffolder prints steps for users:
31
32
  5. Test daemon: `bash daemons/run-watchdog.sh --once`
32
33
  6. Launch dashboard: `python ui/serve.py`
33
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
+
34
61
  ## Invariants & gotchas
35
62
 
36
63
  - **Idempotent on empty targets**: Fails if `targetDir` exists and is non-empty (non-destructive). Safe to retry.
37
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.
38
65
  - **No machine-specific paths**: Use relative paths only; `__dirname` and `path.join()` handle cross-platform resolution.
39
- - **Help text accuracy**: If invocation steps or output paths change, update help text (lines 27–31).
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