uv-suite 0.29.0 → 0.30.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.
Files changed (151) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +58 -35
  3. package/agents/claude-code/anti-slop-guard.md +14 -1
  4. package/agents/claude-code/architect.md +30 -4
  5. package/agents/claude-code/cartographer.md +18 -6
  6. package/agents/claude-code/eval-writer.md +7 -2
  7. package/agents/claude-code/reviewer.md +5 -1
  8. package/agents/claude-code/spec-writer.md +30 -7
  9. package/agents/generate.py +88 -0
  10. package/bin/cli.js +51 -48
  11. package/hooks/auto-checkpoint-helper.sh +2 -2
  12. package/hooks/auto-checkpoint.sh +3 -3
  13. package/hooks/auto-restore-on-start.sh +2 -2
  14. package/hooks/checkpoint-helper.sh +40 -35
  15. package/hooks/git-context.sh +41 -0
  16. package/hooks/lite-mode-inject.sh +26 -0
  17. package/hooks/session-end-helper.sh +2 -2
  18. package/hooks/session-end.sh +2 -2
  19. package/hooks/session-label-nag.sh +2 -2
  20. package/hooks/session-meta.sh +18 -1
  21. package/hooks/session-review-reminder.sh +2 -2
  22. package/hooks/session-start.sh +16 -0
  23. package/hooks/slop-grep.sh +12 -31
  24. package/hooks/uv-out-best.sh +20 -0
  25. package/hooks/uv-out-collect.sh +52 -0
  26. package/hooks/uv-out-notify.sh +28 -0
  27. package/hooks/uv-out-pointer.sh +16 -0
  28. package/hooks/uv-out-session.sh +24 -0
  29. package/hooks/watchtower-notify.sh +45 -0
  30. package/hooks/watchtower-send.sh +4 -0
  31. package/install.sh +93 -42
  32. package/package.json +2 -2
  33. package/personas/auto.json +35 -1
  34. package/personas/professional.json +41 -1
  35. package/personas/spike.json +27 -2
  36. package/personas/sport.json +39 -1
  37. package/settings.json +6 -2
  38. package/skills/architect/SKILL.md +109 -8
  39. package/skills/architect/specialists/distributed-systems.md +84 -0
  40. package/skills/architect/specialists/full-stack.md +92 -0
  41. package/skills/architect/specialists/llm-ai-engineering.md +86 -0
  42. package/skills/architect/specialists/ml-systems.md +81 -0
  43. package/skills/commit/SKILL.md +5 -2
  44. package/skills/confirm/SKILL.md +3 -3
  45. package/skills/investigate/SKILL.md +14 -4
  46. package/skills/lite/SKILL.md +45 -0
  47. package/skills/qa/SKILL.md +274 -0
  48. package/skills/review/SKILL.md +187 -8
  49. package/skills/review/specialists/api-contract.md +122 -0
  50. package/skills/review/specialists/architecture-trace.md +64 -0
  51. package/skills/review/specialists/data-migration.md +113 -0
  52. package/skills/review/specialists/maintainability.md +138 -0
  53. package/skills/review/specialists/performance.md +115 -0
  54. package/skills/review/specialists/security.md +132 -0
  55. package/skills/review/specialists/testing.md +109 -0
  56. package/skills/session/SKILL.md +87 -0
  57. package/skills/session/operations/auto.md +22 -0
  58. package/skills/session/operations/checkpoint.md +43 -0
  59. package/skills/session/operations/end.md +35 -0
  60. package/skills/session/operations/init.md +16 -0
  61. package/skills/session/operations/restore.md +16 -0
  62. package/skills/spec/SKILL.md +40 -1
  63. package/skills/test/SKILL.md +89 -0
  64. package/skills/test/specialists/eval.md +46 -0
  65. package/skills/test/specialists/integration.md +42 -0
  66. package/skills/test/specialists/unit.md +39 -0
  67. package/skills/understand/SKILL.md +118 -0
  68. package/skills/understand/modes/repo.md +38 -0
  69. package/skills/understand/modes/stack.md +41 -0
  70. package/skills/uv-help/SKILL.md +43 -20
  71. package/uv.sh +36 -3
  72. package/watchtower/Dockerfile +9 -0
  73. package/watchtower/README.md +78 -0
  74. package/watchtower/app/__init__.py +0 -0
  75. package/watchtower/app/__pycache__/__init__.cpython-314.pyc +0 -0
  76. package/watchtower/app/__pycache__/db.cpython-314.pyc +0 -0
  77. package/watchtower/app/__pycache__/main.cpython-314.pyc +0 -0
  78. package/watchtower/app/__pycache__/models.cpython-314.pyc +0 -0
  79. package/watchtower/app/db.py +85 -0
  80. package/watchtower/app/main.py +45 -0
  81. package/watchtower/app/models.py +49 -0
  82. package/watchtower/app/routers/__init__.py +0 -0
  83. package/watchtower/app/routers/__pycache__/__init__.cpython-314.pyc +0 -0
  84. package/watchtower/app/routers/__pycache__/control.cpython-314.pyc +0 -0
  85. package/watchtower/app/routers/__pycache__/ingest.cpython-314.pyc +0 -0
  86. package/watchtower/app/routers/__pycache__/query.cpython-314.pyc +0 -0
  87. package/watchtower/app/routers/__pycache__/stream.cpython-314.pyc +0 -0
  88. package/watchtower/app/routers/control.py +144 -0
  89. package/watchtower/app/routers/ingest.py +102 -0
  90. package/watchtower/app/routers/query.py +84 -0
  91. package/watchtower/app/routers/stream.py +30 -0
  92. package/watchtower/app/services/__init__.py +0 -0
  93. package/watchtower/app/services/__pycache__/__init__.cpython-314.pyc +0 -0
  94. package/watchtower/app/services/__pycache__/checkpoint.cpython-314.pyc +0 -0
  95. package/watchtower/app/services/__pycache__/tmux.cpython-314.pyc +0 -0
  96. package/watchtower/app/services/checkpoint.py +107 -0
  97. package/watchtower/app/services/tmux.py +54 -0
  98. package/watchtower/docker-compose.yml +22 -0
  99. package/watchtower/events.json +10344 -45
  100. package/watchtower/{auto-checkpoint-runner.js → legacy/auto-checkpoint-runner.js} +29 -2
  101. package/watchtower/requirements.txt +3 -0
  102. package/watchtower/schema.sql +43 -0
  103. package/watchtower/static/dashboard.html +449 -0
  104. package/agents/claude-code/devops.md +0 -50
  105. package/agents/claude-code/security.md +0 -75
  106. package/agents/codex/anti-slop-guard.toml +0 -12
  107. package/agents/codex/architect.toml +0 -11
  108. package/agents/codex/cartographer.toml +0 -16
  109. package/agents/codex/devops.toml +0 -8
  110. package/agents/codex/eval-writer.toml +0 -11
  111. package/agents/codex/prototype-builder.toml +0 -10
  112. package/agents/codex/reviewer.toml +0 -16
  113. package/agents/codex/security.toml +0 -14
  114. package/agents/codex/spec-writer.toml +0 -11
  115. package/agents/codex/test-writer.toml +0 -13
  116. package/agents/cursor/anti-slop-guard.mdc +0 -22
  117. package/agents/cursor/architect.mdc +0 -24
  118. package/agents/cursor/cartographer.mdc +0 -28
  119. package/agents/cursor/devops.mdc +0 -16
  120. package/agents/cursor/eval-writer.mdc +0 -21
  121. package/agents/cursor/prototype-builder.mdc +0 -25
  122. package/agents/cursor/reviewer.mdc +0 -26
  123. package/agents/cursor/security.mdc +0 -20
  124. package/agents/cursor/spec-writer.mdc +0 -27
  125. package/agents/cursor/test-writer.mdc +0 -28
  126. package/agents/portable/anti-slop-guard.md +0 -71
  127. package/agents/portable/architect.md +0 -83
  128. package/agents/portable/cartographer.md +0 -64
  129. package/agents/portable/devops.md +0 -56
  130. package/agents/portable/eval-writer.md +0 -70
  131. package/agents/portable/prototype-builder.md +0 -70
  132. package/agents/portable/reviewer.md +0 -79
  133. package/agents/portable/security.md +0 -63
  134. package/agents/portable/spec-writer.md +0 -89
  135. package/agents/portable/test-writer.md +0 -56
  136. package/hooks/context-warning.sh +0 -4
  137. package/skills/auto-checkpoint/SKILL.md +0 -47
  138. package/skills/checkpoint/SKILL.md +0 -105
  139. package/skills/map-codebase/SKILL.md +0 -54
  140. package/skills/map-stack/SKILL.md +0 -121
  141. package/skills/restore/SKILL.md +0 -55
  142. package/skills/security-review/SKILL.md +0 -87
  143. package/skills/session-end/SKILL.md +0 -100
  144. package/skills/session-init/SKILL.md +0 -45
  145. package/skills/slop-check/SKILL.md +0 -40
  146. package/skills/write-evals/SKILL.md +0 -34
  147. package/skills/write-tests/SKILL.md +0 -54
  148. /package/watchtower/{auto-checkpoint-prompt.md → legacy/auto-checkpoint-prompt.md} +0 -0
  149. /package/watchtower/{dashboard.html → legacy/dashboard.html} +0 -0
  150. /package/watchtower/{server.js → legacy/server.js} +0 -0
  151. /package/watchtower/{snapshot-manager.js → legacy/snapshot-manager.js} +0 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Utsav Anand
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -38,7 +38,31 @@ Label this session (Enter to skip — you'll be reminded):
38
38
  priority [low/med/high]: high
39
39
  ```
40
40
 
41
- Skip any field with Enter. If you skip the name, `/session-init` will be suggested every few prompts until you label it. Set `UVS_NO_PROMPT=1` to suppress prompts entirely.
41
+ Skip any field with Enter. If you skip the name, `/session init` will be suggested every few prompts until you label it. Set `UVS_NO_PROMPT=1` to suppress prompts entirely.
42
+
43
+ ## Start here
44
+
45
+ After `uvs claude pro`, pick the path that matches what you're doing. Each path names the first skill to run and the canonical next steps.
46
+
47
+ ### Existing codebase (you didn't write this)
48
+ 1. `/understand` — builds a knowledge graph + architecture overview in `uv-out/map-codebase.md`. Other skills (`/architect`, `/review`, `/review --security`) read it automatically.
49
+ 2. `/session checkpoint` — captures your baseline understanding so `/session restore` can bring it back next session.
50
+ 3. Then: `/review` on the current diff, or `/spec` for the next feature.
51
+
52
+ ### New project (you're starting from scratch)
53
+ 1. `/spec` — converts your idea into a structured spec in `uv-out/specs/`.
54
+ 2. `/architect` — breaks the spec into Acts with cycle budgets. Reads the spec automatically.
55
+ 3. Then: implement Act by Act. Use `/test` and `/review` per Act.
56
+
57
+ ### Reviewing a PR
58
+ 1. `/review [branch-name]` — reads diff + `CLAUDE.md` + `DANGER-ZONES.md` + prior `uv-out/` artifacts.
59
+ 2. `/review --security` if the diff touches auth, payments, data access, or external inputs.
60
+
61
+ ### Shipping
62
+ 1. `/session checkpoint` to capture state.
63
+ 2. `/commit` — runs review, tests, commits, optionally opens a PR.
64
+
65
+ Picking a persona (Spike / Sport / Professional / Auto) is a separate axis from picking a first skill — see [Personas](#personas) below for which mode fits which situation.
42
66
 
43
67
  ## Sessions and Watchtower
44
68
 
@@ -46,7 +70,7 @@ Each `uvs` launch generates a `UVS_SESSION_ID` and writes metadata to `.uv-suite
46
70
 
47
71
  - **Concurrent terminals don't collide.** Two `uvs` launches in the same repo run as distinct sessions with separate names, checkpoints, and dashboard rows.
48
72
  - **`uvs watch` shows them all.** The Watchtower dashboard at `localhost:4200` streams every tool call across every session in real time — labeled by your name, sorted by priority (high to top, low dimmed), color-coded by persona.
49
- - **Per-session checkpoints.** `/checkpoint` writes to `uv-out/checkpoints/<sid>/`, and `/restore` auto-picks the current session's latest. Pass a session id prefix or name to restore from a different one.
73
+ - **Per-session checkpoints.** `/session checkpoint` writes to `uv-out/checkpoints/<sid>/`, and `/session restore` auto-picks the current session's latest. Pass a session id prefix or name to restore from a different one.
50
74
  - **Status line shows it all.** The Claude Code status bar shows session name, persona, priority, and elapsed time continuously.
51
75
 
52
76
  ### Watchtower at a glance
@@ -104,50 +128,48 @@ Human gates After each End only Every Act Final output
104
128
 
105
129
  ## Skills (slash commands)
106
130
 
131
+ 12 skills. Each `skills/<name>/SKILL.md` is a thin orchestrator that dispatches to agents.
132
+
107
133
  | Command | What it does |
108
134
  |---|---|
109
- | `/map-codebase [dir]` | Build a knowledge graph of the codebase |
110
- | `/map-stack [dir]` | Map multiple services and their connections |
135
+ | `/understand [dir]` | Map a codebase or whole stack auto-detects repo vs stack |
111
136
  | `/spec [requirements]` | Write a technical specification |
112
137
  | `/architect [spec]` | Design architecture, decompose into Acts |
138
+ | `/test [file]` | Write tests or evals: `--unit` / `--integration` / `--eval` ([DeepEval](https://github.com/confident-ai/deepeval) compatible) |
139
+ | `/review` | Multi-specialist code review; add `--security` (OWASP via Semgrep/Gitleaks/Trivy) or `--slop` (anti-slop audit) |
113
140
  | `/prototype [concept]` | Build a static React prototype |
114
- | `/write-tests [file]` | Generate tests matching project conventions |
115
- | `/write-evals [prompt]` | Write AI/LLM evaluation cases ([DeepEval](https://github.com/confident-ai/deepeval) compatible) |
116
- | `/review` | Code review: correctness, security, performance, slop |
117
- | `/slop-check` | Detect 6 categories of AI-generated slop |
118
- | `/security-review` | OWASP audit, dependency scan, secret detection |
141
+ | `/qa` | Browser QA via Playwright MCP |
119
142
  | `/investigate` | Systematic root-cause debugging |
120
- | `/commit` | Review → test → slop-check → commit (and optionally PR) |
121
- | `/checkpoint [label]` | Save session state to `uv-out/checkpoints/<sid>/` |
122
- | `/restore [sid-prefix\|name]` | Load the latest checkpoint for the current (or named) session |
123
- | `/session-init [name\|--kind\|--purpose\|--priority]` | Label or relabel the current session |
143
+ | `/commit` | Review → test → commit (and optionally PR) |
144
+ | `/session init\|checkpoint\|restore\|end\|auto` | Session lifecycle label, checkpoint, restore, end, or auto-checkpoint |
124
145
  | `/confirm [on\|off\|<n>]` | Toggle reframe-and-confirm for prompts over `<n>` words |
125
146
  | `/uv-help` | List every skill, agent, hook, guardrail, and persona |
126
147
 
127
148
  ## Hooks (lifecycle automation)
128
149
 
129
- Fire automatically on Claude Code events. You never invoke these.
150
+ Fire automatically on Claude Code events. You never invoke these. ~26 scripts live in `hooks/`.
130
151
 
131
152
  | Hook | Fires on | What it does |
132
153
  |---|---|---|
133
154
  | auto-lint | File write | Runs prettier, ruff, or gofmt |
134
- | slop-grep | File write | Greps for obvious slop patterns (over-commented code, vague docs) |
135
- | doc-slop-grep | File write | Catches vague adjectives in markdown |
155
+ | slop-grep | File edit/write | Ambient slop detection on sport / professional / auto personas |
156
+ | doc-slop-grep | File edit/write | Catches vague adjectives in markdown on the spike persona |
136
157
  | danger-zone-check | File edit | Warns if file is in DANGER-ZONES.md |
137
158
  | block-destructive | Bash command | Blocks `rm -rf /`, force push to main, `DROP TABLE` |
138
159
  | confirm-prompt | UserPromptSubmit | For prompts over the threshold, requires Claude to restate before any work starts |
139
- | session-label-nag | UserPromptSubmit | Reminds you to run `/session-init` every Nth prompt while the session has no name |
160
+ | session-label-nag | UserPromptSubmit | Reminds you to run `/session init` every Nth prompt while the session has no name |
140
161
  | context-warning | PostToolUse | Warns when context usage crosses thresholds |
141
162
  | watchtower-send | All events | Forwards every event (with session metadata) to `localhost:4200` |
142
163
  | session-start | SessionStart | Records start time, fires bootstrap event with session metadata |
143
164
  | session-timer | PostToolUse | Reminders at 45 / 90 / 180 minutes |
144
165
  | session-end | Stop | Shows duration, today's total, reflection prompt |
145
166
  | session-review-reminder | Stop | Nudges you to review uncommitted changes |
167
+ | uv-out-* | Session events | Manage session-scoped artifacts under `uv-out/sessions/<sid>/` |
146
168
  | status-line | Continuous | Renders session label, persona, priority, and timer in the Claude Code status bar |
147
169
 
148
170
  ## Agents
149
171
 
150
- 10 agents, each in 4 formats (Claude Code, Cursor, Codex, portable):
172
+ 8 agents. The canonical definitions are `agents/claude-code/*.md`. The Cursor (`.mdc`) and Codex (`.toml`) variants are generated from those by `agents/generate.py` at install — they're not hand-maintained.
151
173
 
152
174
  | Agent | Subsystem | Model | Cycle Budget |
153
175
  |---|---|---|---|
@@ -159,8 +181,6 @@ Fire automatically on Claude Code events. You never invoke these.
159
181
  | Eval Writer | Acts | Opus | 2 |
160
182
  | Anti-Slop Guard | Guard | Opus | 1 |
161
183
  | Prototype Builder | Acts | Sonnet | 3 |
162
- | DevOps | Acts | Opus | 2 |
163
- | Security | Guard | Opus | 1 |
164
184
 
165
185
  ## Artifacts
166
186
 
@@ -168,11 +188,11 @@ Agents write persistent output to `uv-out/`. Each agent reads prior artifacts au
168
188
 
169
189
  | Output | Read by |
170
190
  |---|---|
171
- | `uv-out/map-codebase.md` | /architect, /review, /security-review |
172
- | `uv-out/specs/*.md` | /architect, /write-tests, /write-evals |
173
- | `uv-out/architecture/*.md` | /review, /write-tests, /slop-check |
174
- | `uv-out/review-*.md` | /slop-check, /security-review |
175
- | `uv-out/checkpoints/<sid>/*.md` | /restore |
191
+ | `uv-out/map-codebase.md` | /architect, /review, /review --security |
192
+ | `uv-out/specs/*.md` | /architect, /test, /test --eval |
193
+ | `uv-out/architecture/*.md` | /review, /test, /review --slop |
194
+ | `uv-out/review-*.md` | /review --slop, /review --security |
195
+ | `uv-out/checkpoints/<sid>/*.md` | /session restore |
176
196
 
177
197
  ## Integrations
178
198
 
@@ -190,13 +210,13 @@ Agents write persistent output to `uv-out/`. Each agent reads prior artifacts au
190
210
  ```
191
211
  .claude/
192
212
  settings.json Permissions and hooks (seeded from your persona on first install)
193
- agents/ 10 agent definitions
194
- skills/ 17 slash commands
195
- hooks/ 14 hook scripts + 2 helpers
213
+ agents/ 8 agent definitions (canonical .md)
214
+ skills/ 12 slash commands
215
+ hooks/ ~26 hook scripts
196
216
  rules/ 6 anti-slop guardrails (Pro / Auto only)
197
217
  personas/ 4 persona configs
198
- .codex/agents/ 10 Codex agent definitions
199
- .cursor/rules/ 10 Cursor rule definitions
218
+ .codex/agents/ 8 Codex agent definitions (generated from .claude/agents)
219
+ .cursor/rules/ 8 Cursor rule definitions (generated from .claude/agents)
200
220
  AGENTS.md Codex instruction file
201
221
  DANGER-ZONES.md Risky areas (commit this)
202
222
  .uv-suite-state/ Session metadata + counters (gitignored)
@@ -210,13 +230,16 @@ uv-out/ Agent output artifacts (gitignored)
210
230
 
211
231
  | Document | What it covers |
212
232
  |---|---|
213
- | [usage-guide.md](usage-guide.md) | Full SDLC mapped to exact commands |
233
+ | [CONTRIBUTING.md](CONTRIBUTING.md) | Working on UV Suite adding skills/agents/hooks, running the tests |
214
234
  | [personas.md](personas.md) | 4 personas, 7 knobs, when to use each |
215
- | [practices.md](practices.md) | Working principles (honesty, parallelism, scope, completion) |
235
+ | [knowledge/practices.md](knowledge/practices.md) | Working principles (honesty, parallelism, scope, completion) |
216
236
  | [acts-methodology.md](acts-methodology.md) | Acts delivery framework with worked examples |
217
- | [methodology/human-in-the-loop.md](methodology/human-in-the-loop.md) | Cycle budgets, intervention types, learning loops |
218
- | [collaboration/sharing-and-standards.md](collaboration/sharing-and-standards.md) | Danger zones, team standards, sharing levels |
219
- | [landscape.md](landscape.md) | Open source tools and references for each agent |
237
+ | [knowledge/human-in-the-loop.md](knowledge/human-in-the-loop.md) | Cycle budgets, intervention types, learning loops |
238
+ | [knowledge/sharing-and-standards.md](knowledge/sharing-and-standards.md) | Danger zones, team standards, sharing levels |
239
+ | [research/landscape.md](research/landscape.md) | Open source tools and references for each agent |
240
+ | [research/comparison.md](research/comparison.md) | UV Suite vs gstack vs Claude Code built-in — feature comparison + prompt-depth deep dive |
241
+ | [research/tool-comparison.md](research/tool-comparison.md) | Claude Code vs Cursor vs Codex — how UV Suite works across all three |
242
+ | [research/best-practices.md](research/best-practices.md) | Subagent patterns, remote sessions, sharing with engineers, cost optimization |
220
243
 
221
244
  ## License
222
245
 
@@ -19,7 +19,20 @@ You are the **Anti-Slop Guard** — your job is to catch AI-generated low-qualit
19
19
 
20
20
  ## Artifact Output
21
21
 
22
- Write the slop report to `uv-out/slop-check-YYYY-MM-DD.md`. Create the directory if needed. Summarize findings in the conversation.
22
+ Write the slop report to `<session-output-dir>/review --slop/report.md`, where
23
+ `<session-output-dir>` is the path printed in the "Session output directory" section of
24
+ your context (e.g. `uv-out/sessions/<sid>/`). Create the directory if needed. Stamp the
25
+ top with provenance frontmatter:
26
+
27
+ ```yaml
28
+ ---
29
+ session: <sid from the output dir path>
30
+ skill: slop-check
31
+ created: <ISO 8601 timestamp>
32
+ ---
33
+ ```
34
+
35
+ Summarize findings in the conversation.
23
36
 
24
37
  ## What You Scan For
25
38
 
@@ -16,8 +16,21 @@ effort: high
16
16
 
17
17
  You are the **Architect** — your job is to design systems and break work into deliverable Acts.
18
18
 
19
+ **Hard precondition: you design only from a curated spec** (problem statement, requirements,
20
+ success criteria). If no spec was provided or found, **stop and ask** the user to run
21
+ `/spec` or describe the problem so a spec can be drafted first. Never design from a vague
22
+ one-liner and never invent requirements — designing without a spec is a failure, not a fallback.
23
+
19
24
  ## Output Format
20
25
 
26
+ ### 0. Design Constraints
27
+ Write these to `<session-output-dir>/architecture/constraints.md` FIRST, before any design.
28
+ Record the factors the design is right-sized against (from the spec's non-functional
29
+ requirements or gathered from the user): scale (users/RPS/data, now + ~12mo), team size &
30
+ expertise, availability target, consistency/CAP priority, security & privacy/compliance,
31
+ and fault tolerance / cost of failure. Every later decision must be justifiable against
32
+ these — they are what make "this is over-engineered" a checkable claim.
33
+
21
34
  ### 1. Architecture Decision Record
22
35
  For each key decision, document:
23
36
  - **Decision:** What you chose
@@ -51,11 +64,24 @@ For each key decision, document:
51
64
 
52
65
  ## Artifact Output
53
66
 
54
- Write all output to `uv-out/architecture/`:
55
- - `uv-out/architecture/decisions.md` architecture decision records
56
- - `uv-out/architecture/acts-plan.md` — Acts breakdown with tasks and cycle budgets
67
+ Write all output under `<session-output-dir>/architecture/`, where `<session-output-dir>`
68
+ is the path printed in the "Session output directory" section of your context
69
+ (e.g. `uv-out/sessions/<sid>/`):
70
+ - `<session-output-dir>/architecture/constraints.md` — the Design Constraints the design is right-sized against (write this FIRST, before designing)
71
+ - `<session-output-dir>/architecture/decisions.md` — architecture decision records
72
+ - `<session-output-dir>/architecture/acts-plan.md` — Acts breakdown with tasks and cycle budgets
73
+
74
+ Create the directory if needed. Stamp the top of each file with provenance frontmatter:
75
+
76
+ ```yaml
77
+ ---
78
+ session: <sid from the output dir path>
79
+ skill: architect
80
+ created: <ISO 8601 timestamp>
81
+ ---
82
+ ```
57
83
 
58
- Create the directory if needed. Summarize the design in the conversation.
84
+ Summarize the design in the conversation.
59
85
 
60
86
  ### 4. Task Dependency Graph
61
87
  Mermaid diagram showing parallelism opportunities.
@@ -88,12 +88,24 @@ Produce all 6 sections (Architecture Overview, Tech Stack, Dependency Graph, Bus
88
88
 
89
89
  ## Artifact Output
90
90
 
91
- Write all output to `uv-out/`. Create the directory if it doesn't exist.
92
-
93
- - `uv-out/map-codebase.md` — the written analysis (business domain map, sequence diagrams, entry points)
94
- - `uv-out/graphify-out/` Graphify outputs if used (graph.html, graph.json, GRAPH_REPORT.md)
95
-
96
- After writing, tell the human: "Artifacts written to uv-out/map-codebase.md" and summarize key findings in the conversation.
91
+ Write all output under `<session-output-dir>`, the path printed in the "Session output
92
+ directory" section of your context (e.g. `uv-out/sessions/<sid>/`). Create it if needed.
93
+
94
+ The calling skill names the output file `<session-output-dir>/map-codebase.md` for
95
+ single-codebase mapping, `<session-output-dir>/map-stack.md` for multi-service stack
96
+ mapping. Follow the file named in the task; default to `map-codebase.md` if unspecified.
97
+
98
+ - The written analysis goes in that file, stamped with provenance frontmatter:
99
+ ```yaml
100
+ ---
101
+ session: <sid from the output dir path>
102
+ skill: map-codebase # or map-stack
103
+ created: <ISO 8601 timestamp>
104
+ ---
105
+ ```
106
+ - `<session-output-dir>/graphify-out/` — Graphify outputs if used (graph.html, graph.json, GRAPH_REPORT.md)
107
+
108
+ After writing, tell the human one line — "Artifacts written to `<the file you wrote>`" — and summarize key findings in the conversation.
97
109
 
98
110
  ## Rules
99
111
 
@@ -46,14 +46,19 @@ You are the **Eval Writer** — your job is to write evaluations that verify AI/
46
46
 
47
47
  ## Artifact Output
48
48
 
49
- Write evals to `uv-out/evals/`. Create the directory if needed. Match the project's eval framework format (DeepEval preferred).
49
+ Write eval artifacts to `<session-output-dir>/evals/`, where `<session-output-dir>` is the
50
+ path printed in the "Session output directory" section of your context (e.g.
51
+ `uv-out/sessions/<sid>/`). Create the directory if needed. Match the project's eval
52
+ framework format (DeepEval preferred). If you also add runnable evals into the project's
53
+ own eval suite, do that in the project tree as usual — only the artifact copy goes under
54
+ the session directory.
50
55
 
51
56
  ## Grading Rubric (be this specific)
52
57
 
53
58
  ```yaml
54
59
  grading:
55
60
  type: "llm_judge"
56
- model: "claude-haiku-4-5"
61
+ model: "claude-haiku-4-5-20251001"
57
62
  rubric: |
58
63
  Score 1 (pass) if ALL of:
59
64
  - Agent declines the out-of-scope request
@@ -65,7 +65,11 @@ You are the **Reviewer** — your job is to catch bugs, security issues, perform
65
65
 
66
66
  ## Artifact Output
67
67
 
68
- Write the review report to `uv-out/review-YYYY-MM-DD.md`. Create the directory if needed. Summarize key findings in the conversation.
68
+ Write your report under `<session-output-dir>`, the path printed in the "Session output
69
+ directory" section of your context (e.g. `uv-out/sessions/<sid>/`). Use the filename the
70
+ calling task names — `review/state.md` for a code review, `investigate/report.md` for an
71
+ investigation. Stamp the top with provenance frontmatter (`session`, `skill`, `created`).
72
+ Create the directory if needed. Summarize key findings in the conversation.
69
73
 
70
74
  ## Common Findings (be this specific)
71
75
 
@@ -62,19 +62,42 @@ Unit, integration, e2e, load?
62
62
 
63
63
  ## Artifact Output
64
64
 
65
- Write the spec to `uv-out/specs/[feature-name]-spec.md`. Create the directory if needed. Summarize the spec in the conversation.
65
+ Write the spec to `<session-output-dir>/specs/[feature-name]-spec.md`, where
66
+ `<session-output-dir>` is the path printed in the "Session output directory" section of
67
+ your context (e.g. `uv-out/sessions/<sid>/`). Create the directory if needed.
68
+
69
+ Stamp the top of the spec with provenance frontmatter so it stays attributable if moved:
70
+
71
+ ```yaml
72
+ ---
73
+ session: <sid from the output dir path>
74
+ skill: spec
75
+ created: <ISO 8601 timestamp>
76
+ ---
77
+ ```
78
+
79
+ Then the `# Spec: [Feature Name]` heading and the rest of the template. Summarize the spec in the conversation.
66
80
 
67
81
  ## Process
68
82
 
69
- 1. Parse the input into discrete requirements
70
- 2. Separate functional vs non-functional
71
- 3. Identify gaps list as open questions, don't invent answers
72
- 4. Propose a high-level solution (detailed design is the Architect's job)
73
- 5. Define measurable success criteria
74
- 6. Flag risks and assumptions
83
+ 1. **Ground in the existing codebase first.** Read the prior `uv-out/` artifacts loaded by
84
+ the skill the codebase map (`map-codebase.md`/`map-stack.md`), prior specs, and
85
+ architecture decisions. Reference real modules, files, patterns, and conventions from
86
+ the map; reuse what exists; build on prior specs instead of re-specifying them. If no
87
+ map is present, say so and note that `/understand` would produce a better-grounded spec.
88
+ 2. Parse the input into discrete requirements
89
+ 3. Separate functional vs non-functional
90
+ 4. Identify gaps — list as open questions, don't invent answers
91
+ 5. Propose a high-level solution that fits the existing architecture (detailed design is
92
+ the Architect's job) — name the specific modules/files it touches
93
+ 6. Define measurable success criteria
94
+ 7. Flag risks and assumptions
75
95
 
76
96
  ## Rules
77
97
 
98
+ - **Ground every section in the real codebase.** The Proposed Solution, API Contract, and
99
+ Data Model sections must reference actual modules/types/endpoints from the map — not
100
+ generic placeholders. If you're inventing names because there's no map, flag it.
78
101
  - Scale the spec to the task. A bug fix needs 1 page, not 10.
79
102
  - Flag ambiguity as open questions — don't fill gaps with assumptions.
80
103
  - If requirements conflict (e.g., "fast response" vs "comprehensive validation"), list both in Risks and propose which to prioritize.
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env python3
2
+ """Generate Cursor (.mdc) and Codex (.toml) agent files from the canonical
3
+ Claude Code agent definitions in agents/claude-code/*.md.
4
+
5
+ Single source of truth: edit agents/claude-code/<name>.md, then install.sh (or
6
+ `python3 agents/generate.py <cursor|codex> <dest-dir>`) regenerates the others.
7
+
8
+ Usage:
9
+ python3 agents/generate.py cursor /path/to/.cursor/rules
10
+ python3 agents/generate.py codex /path/to/.codex/agents
11
+ """
12
+ import glob
13
+ import os
14
+ import re
15
+ import sys
16
+
17
+ CANONICAL = os.path.join(os.path.dirname(os.path.abspath(__file__)), "claude-code")
18
+
19
+
20
+ def parse(md, fallback_name):
21
+ m = re.match(r"^---\n(.*?)\n---\n(.*)$", md, re.S)
22
+ fm, body = (m.group(1), m.group(2).strip()) if m else ("", md.strip())
23
+
24
+ def field(key):
25
+ mm = re.search(rf"^{key}:\s*(.*)$", fm, re.M)
26
+ return mm.group(1).strip() if mm else ""
27
+
28
+ # description is usually a folded scalar (`description: >` then indented lines)
29
+ desc = field("description")
30
+ if desc in (">", "|", ">-", "|-", ""):
31
+ lines = fm.splitlines()
32
+ idx = next((i for i, l in enumerate(lines) if l.startswith("description:")), None)
33
+ if idx is not None:
34
+ collected = []
35
+ for l in lines[idx + 1:]:
36
+ if re.match(r"^\s+\S", l):
37
+ collected.append(l.strip())
38
+ else:
39
+ break
40
+ desc = " ".join(collected) or desc
41
+ desc = desc.strip().strip('"')
42
+
43
+ return {
44
+ "name": field("name") or fallback_name,
45
+ "desc": desc,
46
+ "model": field("model"),
47
+ "has_write": ("Write" in fm or "Edit" in fm),
48
+ "body": body,
49
+ }
50
+
51
+
52
+ def to_mdc(a):
53
+ desc = a["desc"].replace('"', '\\"')
54
+ return f'---\ndescription: "{desc}"\nglobs: ""\nalwaysApply: false\n---\n\n{a["body"]}\n'
55
+
56
+
57
+ def to_toml(a):
58
+ effort = "high" if a["model"] == "opus" else "medium"
59
+ sandbox = "workspace-write" if a["has_write"] else "read-only"
60
+ desc = a["desc"].replace("\\", "\\\\").replace('"', '\\"')
61
+ body = a["body"].replace("\\", "\\\\").replace('"""', '\\"\\"\\"')
62
+ return (
63
+ f'name = "{a["name"]}"\n'
64
+ f'description = "{desc}"\n'
65
+ f'model_reasoning_effort = "{effort}"\n'
66
+ f'sandbox_mode = "{sandbox}"\n\n'
67
+ f'developer_instructions = """\n{body}\n"""\n'
68
+ )
69
+
70
+
71
+ def main():
72
+ if len(sys.argv) != 3 or sys.argv[1] not in ("cursor", "codex"):
73
+ sys.exit("usage: generate.py <cursor|codex> <dest-dir>")
74
+ fmt, dest = sys.argv[1], sys.argv[2]
75
+ os.makedirs(dest, exist_ok=True)
76
+ ext = ".mdc" if fmt == "cursor" else ".toml"
77
+ render = to_mdc if fmt == "cursor" else to_toml
78
+ n = 0
79
+ for path in sorted(glob.glob(os.path.join(CANONICAL, "*.md"))):
80
+ name = os.path.splitext(os.path.basename(path))[0]
81
+ a = parse(open(path).read(), name)
82
+ open(os.path.join(dest, name + ext), "w").write(render(a))
83
+ n += 1
84
+ print(f"generated {n} {fmt} agents -> {dest}")
85
+
86
+
87
+ if __name__ == "__main__":
88
+ main()
package/bin/cli.js CHANGED
@@ -34,6 +34,7 @@ function usage() {
34
34
  Monitoring:
35
35
  uvs watch Start Watchtower dashboard (open browser)
36
36
  uvs watch --bg Start Watchtower in background
37
+ uvs watch --legacy Start the legacy Node Watchtower (no Docker/Postgres)
37
38
 
38
39
  Personas:
39
40
  spike Research & docs (Opus, max effort)
@@ -295,59 +296,61 @@ async function launchCodex(persona, extra) {
295
296
  }
296
297
 
297
298
  function watch() {
298
- const serverScript = path.join(UV_SUITE_DIR, "watchtower", "server.js");
299
- if (!fs.existsSync(serverScript)) {
300
- console.error("Error: watchtower server not found at", serverScript);
299
+ const wtDir = path.join(UV_SUITE_DIR, "watchtower");
300
+
301
+ // Legacy fallback: the original Node Watchtower (no Postgres/Docker). `uvs watch --legacy`.
302
+ if (args.includes("--legacy")) {
303
+ const serverScript = path.join(wtDir, "legacy", "server.js");
304
+ if (!fs.existsSync(serverScript)) {
305
+ console.error("Error: legacy watchtower not found at", serverScript);
306
+ process.exit(1);
307
+ }
308
+ const lbg = args.includes("--bg") || args.includes("--background");
309
+ const lurl = "http://localhost:" + (process.env.UVS_WATCHTOWER_PORT || 4200);
310
+ const lopener =
311
+ process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
312
+ console.log("UV Suite Watchtower (legacy Node) starting...");
313
+ console.log("Dashboard: " + lurl);
314
+ console.log("");
315
+ setTimeout(() => spawn(lopener, [lurl], { stdio: "ignore" }), 1000);
316
+ const lchild = spawn("node", [serverScript], { stdio: lbg ? "ignore" : "inherit", detached: lbg });
317
+ if (lbg) {
318
+ lchild.unref();
319
+ console.log(`Running in background (PID: ${lchild.pid}). Stop with: kill ${lchild.pid}`);
320
+ } else {
321
+ lchild.on("exit", (code) => process.exit(code || 0));
322
+ }
323
+ return;
324
+ }
325
+ if (!fs.existsSync(path.join(wtDir, "docker-compose.yml"))) {
326
+ console.error("Error: watchtower compose not found at", wtDir);
301
327
  process.exit(1);
302
328
  }
303
-
304
329
  const bg = args.includes("--bg") || args.includes("--background");
305
- console.log("UV Suite Watchtower starting...");
306
- console.log(
307
- "Dashboard: http://localhost:" + (process.env.UVS_WATCHTOWER_PORT || 4200),
308
- );
330
+ const url = "http://localhost:" + (process.env.UVS_WATCHTOWER_PORT || 4200);
331
+ const opener =
332
+ process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
333
+ console.log("UV Suite Watchtower (Python + Postgres) starting via docker compose...");
334
+ console.log("Dashboard: " + url);
309
335
  console.log("");
310
336
 
311
- if (bg) {
312
- const child = spawn("node", [serverScript], {
313
- stdio: "ignore",
314
- detached: true,
315
- });
316
- child.unref();
317
- console.log(`Running in background (PID: ${child.pid})`);
318
- console.log("Stop with: kill " + child.pid);
319
-
320
- // Open browser
321
- const opener =
322
- process.platform === "darwin"
323
- ? "open"
324
- : process.platform === "win32"
325
- ? "start"
326
- : "xdg-open";
327
- spawn(
328
- opener,
329
- ["http://localhost:" + (process.env.UVS_WATCHTOWER_PORT || 4200)],
330
- { stdio: "ignore" },
331
- );
332
- } else {
333
- // Foreground — open browser after a short delay
334
- setTimeout(() => {
335
- const opener =
336
- process.platform === "darwin"
337
- ? "open"
338
- : process.platform === "win32"
339
- ? "start"
340
- : "xdg-open";
341
- spawn(
342
- opener,
343
- ["http://localhost:" + (process.env.UVS_WATCHTOWER_PORT || 4200)],
344
- { stdio: "ignore" },
345
- );
346
- }, 1000);
347
-
348
- const child = spawn("node", [serverScript], { stdio: "inherit" });
349
- child.on("exit", (code) => process.exit(code || 0));
350
- }
337
+ // Bring the stack up (Postgres + FastAPI). Build is cached after first run.
338
+ const up = spawn("docker", ["compose", "up", "--build", "-d"], { cwd: wtDir, stdio: "inherit" });
339
+ up.on("exit", (code) => {
340
+ if (code) {
341
+ console.error("docker compose failed. Is Docker running? (the Python Watchtower needs it)");
342
+ process.exit(code);
343
+ }
344
+ setTimeout(() => spawn(opener, [url], { stdio: "ignore" }), 1500);
345
+ if (bg) {
346
+ console.log("Watchtower running in background.");
347
+ console.log("Stop with: (cd watchtower && docker compose down)");
348
+ process.exit(0);
349
+ }
350
+ // Foreground: follow logs until Ctrl-C.
351
+ const logs = spawn("docker", ["compose", "logs", "-f"], { cwd: wtDir, stdio: "inherit" });
352
+ logs.on("exit", (c) => process.exit(c || 0));
353
+ });
351
354
  }
352
355
 
353
356
  // --- Parse and route ---
@@ -1,6 +1,6 @@
1
1
  #!/bin/bash
2
2
  # UV Suite helper: read or change auto-checkpoint settings.
3
- # Used by the /auto-checkpoint slash command.
3
+ # Used by the /session auto slash command.
4
4
  #
5
5
  # Usage:
6
6
  # auto-checkpoint-helper.sh status
@@ -66,7 +66,7 @@ case "$ARG" in
66
66
  set_field interval_minutes "$ARG"
67
67
  echo "Auto-checkpoint interval: $ARG min (mode: $(get_field mode))"
68
68
  else
69
- echo "Usage: /auto-checkpoint [on | off | <minutes 1-1440> | status]"
69
+ echo "Usage: /session auto [on | off | <minutes 1-1440> | status]"
70
70
  exit 1
71
71
  fi
72
72
  ;;
@@ -5,7 +5,7 @@
5
5
  # Logs every tool call into a per-session activity log. When `interval_minutes`
6
6
  # have passed since the last mechanical checkpoint AND there has been activity
7
7
  # in the interval, writes a deterministic snapshot to
8
- # uv-out/checkpoints/<sid>/auto-<ts>-mechanical.md and forwards an
8
+ # uv-out/sessions/<sid>/checkpoints/auto-<ts>-mechanical.md and forwards an
9
9
  # AutoCheckpoint event to the watchtower.
10
10
  #
11
11
  # Tier B (semantic, claude -p) runs separately from the watchtower's timer.
@@ -96,7 +96,7 @@ fi
96
96
 
97
97
  # Resolve checkpoint dir + metadata via the existing helper
98
98
  CP_DIR=$(CLAUDE_PROJECT_DIR="$PROJECT_DIR" "$PROJECT_DIR/.claude/hooks/checkpoint-helper.sh" dir 2>/dev/null)
99
- [ -z "$CP_DIR" ] && CP_DIR="$PROJECT_DIR/uv-out/checkpoints/$SID" && mkdir -p "$CP_DIR"
99
+ [ -z "$CP_DIR" ] && CP_DIR="$PROJECT_DIR/uv-out/sessions/$SID/checkpoints" && mkdir -p "$CP_DIR"
100
100
 
101
101
  # Build the mechanical checkpoint body
102
102
  TS_FILE=$(date +%Y-%m-%d-%H%M)
@@ -160,7 +160,7 @@ GIT_LOG=$(cd "$PROJECT_DIR" && git log --oneline -5 2>/dev/null)
160
160
  fi
161
161
  } > "$CP_FILE"
162
162
 
163
- # Update latest.md so /restore picks it up
163
+ # Update latest.md so /session restore picks it up
164
164
  cp "$CP_FILE" "$CP_DIR/latest.md" 2>/dev/null
165
165
  echo "$NOW" > "$LAST_CP_FILE"
166
166