@oneie/claude 0.6.0 → 0.7.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 (111) hide show
  1. package/agents/w1-recon.md +9 -4
  2. package/agents/w2-decide.md +51 -28
  3. package/agents/w3-edit.md +70 -78
  4. package/agents/w4-verify.md +164 -69
  5. package/commands/browser.md +98 -35
  6. package/commands/cc-connect.md +6 -0
  7. package/commands/chat.md +13 -1
  8. package/commands/close.md +45 -19
  9. package/commands/create.md +20 -10
  10. package/commands/db-sync.md +5 -1
  11. package/commands/deploy.md +174 -87
  12. package/commands/do-autonomous.md +31 -20
  13. package/commands/do-improve.md +4 -4
  14. package/commands/do-show.md +4 -3
  15. package/commands/do.md +53 -13
  16. package/commands/go.md +75 -0
  17. package/commands/improve.md +4 -2
  18. package/commands/kill.md +6 -8
  19. package/commands/notify.md +15 -2
  20. package/commands/oo-push.md +24 -9
  21. package/commands/rag.md +6 -0
  22. package/commands/release.md +46 -25
  23. package/commands/restart.md +5 -4
  24. package/commands/see.md +45 -35
  25. package/commands/skill-create.md +38 -5
  26. package/commands/sync.md +21 -11
  27. package/hooks/scripts/auto-continue.sh +70 -0
  28. package/hooks/scripts/branch-pin.sh +85 -0
  29. package/hooks/scripts/git-add-guard.sh +16 -5
  30. package/hooks/scripts/post-edit-check.sh +16 -0
  31. package/hooks/scripts/session-start.sh +13 -8
  32. package/hooks/scripts/sync-priority-todo.sh +5 -0
  33. package/package.json +1 -1
  34. package/rules/api.md +9 -0
  35. package/rules/design.md +13 -3
  36. package/rules/documentation.md +30 -71
  37. package/rules/engine.md +8 -1
  38. package/rules/ui.md +5 -1
  39. package/scripts/__pycache__/do-rank.cpython-313.pyc +0 -0
  40. package/scripts/browser-check.mjs +44 -103
  41. package/scripts/cc-events-proof.sh +13 -12
  42. package/scripts/chrome.mjs +381 -0
  43. package/scripts/do-analyze.sh +109 -4
  44. package/scripts/do-auto.sh +350 -43
  45. package/scripts/do-consumer-sweep.sh +72 -0
  46. package/scripts/do-derives-check.sh +88 -0
  47. package/scripts/do-fleet.sh +50 -1
  48. package/scripts/do-killswitch-audit.py +33 -14
  49. package/scripts/do-promise-lint.sh +150 -4
  50. package/scripts/do-promise-settle.sh +131 -9
  51. package/scripts/do-prove.sh +197 -17
  52. package/scripts/do-rank.py +606 -20
  53. package/scripts/do-rubric.py +21 -2
  54. package/scripts/do-signal.sh +157 -17
  55. package/scripts/do-smoke.sh +9 -0
  56. package/scripts/do-substrate-check.sh +49 -0
  57. package/scripts/do-tasks-wire-check.sh +81 -0
  58. package/scripts/do-tier.sh +90 -5
  59. package/scripts/do-ui-gate.sh +332 -0
  60. package/scripts/do-untracked-gate.sh +231 -0
  61. package/scripts/do-walk.sh +344 -0
  62. package/scripts/factory-check.sh +747 -0
  63. package/scripts/factory-repo.sh +1361 -0
  64. package/scripts/factory-tasks-check.sh +85 -0
  65. package/scripts/outcome-pull.ts +279 -0
  66. package/scripts/promise-manifest.mjs +167 -0
  67. package/scripts/reconcile-allow.txt +5 -0
  68. package/scripts/rubric-weights.json +64 -0
  69. package/scripts/spine-canary.sh +20 -0
  70. package/scripts/typedb-cluster-status.sh +128 -0
  71. package/scripts/typedb-env.sh +182 -0
  72. package/scripts/typedb-flap-recorder.sh +85 -0
  73. package/scripts/typedb-probes/containment-probe.py +88 -0
  74. package/scripts/typedb-probes/panic-probe-version.py +92 -0
  75. package/scripts/typedb-probes/panic-probe.py +77 -0
  76. package/scripts/typedb-scratch.sh +73 -0
  77. package/scripts/urls-lint.sh +58 -0
  78. package/scripts/w4-rubric.ts +96 -12
  79. package/scripts/wf-check.mjs +75 -0
  80. package/skills/ai-ui/SKILL.md +1 -1
  81. package/skills/astro/SKILL.md +177 -132
  82. package/skills/astro/add-content-collection.md +29 -13
  83. package/skills/astro/check-build.md +19 -13
  84. package/skills/astro/create-component.md +36 -9
  85. package/skills/astro/create-page.md +39 -10
  86. package/skills/astro/optimize-performance.md +36 -8
  87. package/skills/cli/SKILL.md +254 -220
  88. package/skills/dev/SKILL.md +1 -1
  89. package/skills/directory-autofill/SKILL.md +68 -0
  90. package/skills/docs/SKILL.md +4 -4
  91. package/skills/mcp/SKILL.md +186 -156
  92. package/skills/promise-make/SKILL.md +2 -2
  93. package/skills/puck/SKILL.md +465 -250
  94. package/skills/react19/SKILL.md +196 -296
  95. package/skills/reactflow/SKILL.md +387 -412
  96. package/skills/sdk/SKILL.md +167 -106
  97. package/skills/shadcn/SKILL.md +245 -201
  98. package/skills/signal/SKILL.md +5 -0
  99. package/skills/sui/SKILL.md +6 -1
  100. package/skills/tutorial/SKILL.md +15 -0
  101. package/skills/typedb/SKILL.md +427 -217
  102. package/skills/typedb/examples/python-patterns.py +11 -4
  103. package/skills/typedb/examples/query-patterns.tql +8 -3
  104. package/skills/typedb/examples/schema-patterns.tql +4 -2
  105. package/skills/typedb/reference/migration-2x-3x.md +19 -1
  106. package/skills/typedb/reference/python-driver.md +17 -1
  107. package/skills/voice/SKILL.md +117 -0
  108. package/skills/writer/SKILL.md +29 -12
  109. package/templates/template-feature.md +26 -1
  110. package/templates/template-tests.md +4 -0
  111. package/templates/template-todo.md +65 -10
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: w4-verify
3
- description: "Wave 4 verify agent for /do cycles. Runs deterministic checks (biome + tsc + vitest), then reconcile-per-canon and coherence-ratchet checks, then scores the code rubric (security/stability/simplicity/integration/speed) per one/rubrics.md. Returns pass/fail with numeric receipts. Use after W3 edits land. Gates the cycle at rubric >= 0.65 AND goal-fit >= 0.50 (hard gate)."
3
+ description: "Wave 4 verify agent for /do cycles. Runs deterministic checks (bun run verify — tsc + vitest), then reconcile-per-canon over the 7 canons and the coherence ratchet, then scores the code rubric (goal-fit/security/stability/simplicity/integration/speed) per text/rubrics.md. Returns pass/fail with numeric receipts and a per-dimension improvement instruction that seeds the next cycle's W1. Use after W3 edits land, and for each W3.5 reloop. Gates the cycle at composite >= 0.65 AND goal-fit >= 0.50 (hard gate)."
4
4
  tools: "Read, Grep, Glob, Bash, Edit"
5
5
  model: sonnet
6
6
  skills: "signal, typedb, typecheck"
@@ -20,7 +20,10 @@ The rubric is not a verdict; it is a map forward.
20
20
  ## W4 Verify
21
21
 
22
22
  ### Deterministic checks
23
- - biome: <pass|fail> errors=<N> warnings=<N>
23
+ - biome: <pass|fail|n/a> errors=<N> warnings=<N>
24
+ (`n/a — no biome config in this folder` is the honest answer in this
25
+ monorepo: `one.ie/web` has none. Never render a `pass` for a linter
26
+ that did not run.)
24
27
  - tsc: <pass|fail> errors=<N>
25
28
  - vitest: <pass|fail> passed=<N>/<total> failed=<N> flaky=<N>
26
29
  - buildMs: <N>ms (bun run build; compare to W0 baseline)
@@ -32,7 +35,7 @@ The rubric is not a verdict; it is a map forward.
32
35
  ### Coherence ratchet
33
36
  <see below>
34
37
 
35
- ### Code Rubric (one/rubrics.md — Code Rubric section)
38
+ ### Code Rubric (text/rubrics.md — Code Rubric section)
36
39
  - goal-fit: <0.00–1.00> <why — did this move the plan outcome closer? one line>
37
40
  → improve: <what the diff does NOT yet deliver toward the goal> | "clean" if 1.00
38
41
  - security: <0.00–1.00> <why — one line>
@@ -41,7 +44,7 @@ The rubric is not a verdict; it is a map forward.
41
44
  → improve: <test name + error, or type gap> | "clean" if 1.00
42
45
  - simplicity: <0.00–1.00> <why — one line>
43
46
  → improve: <function or import that can shrink, with line ref> | "clean" if 1.00
44
- - integration: <0.00–1.00> <deterministic — fraction of .w2-surface-checklist.json surfaces verified (nav entry · inbound links · SDK/MCP/CLI exports · docs synced); no checklist → score wired-vs-orphaned from the diff>
47
+ - integration: <0.00–1.00> <deterministic — fraction of .w2-surface-checklist.json surfaces verified (nav entry · inbound links · SDK/MCP/CLI exports · docs synced); checklist with surface:"none"+reason → score wired-vs-orphaned from the diff; checklist file absent → integration gate FAILS the cycle>
45
48
  → improve: <surface or export left unwired, with checklist key> | "clean" if 1.00
46
49
  - speed: <0.00–1.00> <why — one line>
47
50
  → improve: <Lighthouse audit + component, or bundle culprit> | "clean" if 1.00
@@ -49,6 +52,11 @@ The rubric is not a verdict; it is a map forward.
49
52
 
50
53
  ### Gate
51
54
  - threshold: composite ≥ 0.65 AND goal-fit ≥ 0.50 (hard)
55
+ AND no adversarial finding > 0.5 AND delta_tsc ≤ 0
56
+ (all four conjuncts — `.claude/commands/do.md` § W4. `delta_tsc` is the
57
+ ratchet `types` dim; the adversarial score comes from the reviewers the
58
+ parent runs alongside you — if the parent supplied none, report
59
+ `adversarial: not run` and do NOT treat it as satisfied.)
52
60
  - outcome: <pass ✓ | fail ✗>
53
61
 
54
62
  ### Cross-consistency
@@ -64,8 +72,21 @@ The rubric is not a verdict; it is a map forward.
64
72
 
65
73
  ## Workflow
66
74
 
67
- 1. Run `bun run verify` (biome + tsc + vitest). Capture exit code and counts. If the command fails because `bun` isn't available, fall back to `npm run verify`.
75
+ 1. Run verify **inside the package folder** there is no repo-root `package.json`, so a
76
+ bare `bun run verify` at the root fails with "script not found", which is not a code
77
+ failure and must never be reported as one:
78
+ ```bash
79
+ FOLDER="${FOLDER:-one.ie/web}" # bind it — an unset FOLDER means cd "" = repo root
80
+ ( cd "$FOLDER" && bun run verify ) # one.ie/web = sdk build + tsc + vitest
81
+ ```
82
+ Bind `FOLDER` to the cycle's folder before running (`do-folder.sh` resolves it;
83
+ `one.ie/web` is the default for web work). Capture exit code and counts. If `bun` is
84
+ unavailable, fall back to `( cd "$FOLDER" && npm run verify )`. If the folder has no `verify` script,
85
+ run its `typecheck` and `test` scripts directly and say which ones ran — never
86
+ report a check that did not execute as `pass`.
68
87
  2. If biome/tsc/vitest fail on files touched in W3 → route failure back to W3 (the parent handles the W3.5 reloop; you emit `w4:verify:fail` with the failure list). Max 3 loops per cycle.
88
+
89
+ **in-wave-race exception.** Parallel W3a agents editing disjoint files can race the type checker: a TS2307 (`Cannot find module`) whose missing specifier resolves to a file listed in another SAME-WAVE diff spec is classified `in-wave-race`, not a real failure — re-run `tsc` once after all wave agents have settled; only a TS2307 that persists on the second run fails the cycle. A TS2307 pointing at a file no diff spec in this wave creates is a genuine missing-file error and is never waived.
69
90
  2.5. **Contract gate** — for any verb touched in W3 (`signal`, `mark`, `warn`, `fade`, `follow`, `harden`), read `text/contracts.md` and verify the diff against the verb's pre/post/inv. Until a property-test suite exists, this is a manual check; emit `contracts: reviewed` or `contracts: violated <verb> <clause>` in receipts. A violation is **non-bypassable** — cycle does not close regardless of rubric. If no verb touched → `contracts: n/a`.
70
91
 
71
92
  3. **Reconcile per canon** — run after deterministic checks pass, before rubric scoring.
@@ -82,24 +103,32 @@ The rubric is not a verdict; it is a map forward.
82
103
 
83
104
  Run the canons that apply to each touched file:
84
105
 
106
+ The 7 canons are `substrate | dictionary | authority | sdk | design | navigation |
107
+ types`. Always invoke by explicit path — `.claude/scripts/` is not on `PATH`, and a
108
+ bare call exits 127, which is not one of the script's own codes (0 reconciles,
109
+ 1 fails, 2 unknown canon). A 127 read as a FAIL is a false red; a 127 swallowed is
110
+ a false green. Neither is acceptable — fix the invocation and re-run.
111
+
85
112
  ```bash
113
+ R=".claude/scripts/do-reconcile.sh"
114
+
86
115
  # DATA
87
- do-reconcile.sh substrate <file>
88
- do-reconcile.sh dictionary <file>
89
- do-reconcile.sh types
116
+ bash $R substrate <file>
117
+ bash $R dictionary <file>
118
+ bash $R types
90
119
 
91
120
  # SURFACE
92
- do-reconcile.sh design <file>
93
- do-reconcile.sh navigation <file>
121
+ bash $R design <file>
122
+ bash $R navigation <file>
94
123
 
95
124
  # GATEWAY
96
- do-reconcile.sh sdk <file>
97
- do-reconcile.sh authority <file>
125
+ bash $R sdk <file>
126
+ bash $R authority <file>
98
127
 
99
128
  # PROOF — no canon check; exit code IS the check (vitest already ran above)
100
129
 
101
130
  # TEACH
102
- do-reconcile.sh dictionary <file>
131
+ bash $R dictionary <file>
103
132
  ```
104
133
 
105
134
  Report each result as `canon/<name>: ok | warn | FAIL`. Any FAIL → cycle does not close, same as a tsc failure. Emit the FAIL stdout in the report so W2 can target the exact gap.
@@ -119,13 +148,15 @@ The rubric is not a verdict; it is a map forward.
119
148
  | Dim | Check | Command | Gate |
120
149
  |-----|-------|---------|------|
121
150
  | types | delta_tsc ≤ 0 | already in deterministic checks (step 1) | tsc errors this cycle ≤ tsc errors at W0 |
122
- | names | 0 dead names in touched docs | `do-reconcile.sh dictionary <touched_docs>` | exit 0 |
151
+ | names | 0 dead names in touched docs | `bash .claude/scripts/do-reconcile.sh dictionary <touched_docs>` | exit 0 |
123
152
  | primitives | net new ≤ 0 | `git diff --name-status HEAD \| grep -c '^A'` minus `git diff --name-status HEAD \| grep -c '^D'` | new_files − deleted_files ≤ 0 |
124
- | schema | no fork | `do-reconcile.sh substrate <touched_schema_files>` | exit 0 |
125
- | surfaces | registered + linked | `do-reconcile.sh navigation <touched_pages>` | exit 0 |
153
+ | schema | no fork | `bash .claude/scripts/do-reconcile.sh substrate <touched_schema_files>` | exit 0 |
154
+ | surfaces | registered + linked | `bash .claude/scripts/do-reconcile.sh navigation <touched_pages>` | exit 0 |
126
155
  | docs | no broken link | `markdown-link-check <touched_docs>` | exit 0 |
127
156
 
128
157
  ```bash
158
+ R=".claude/scripts/do-reconcile.sh"
159
+
129
160
  # primitives net check
130
161
  NEW_FILES=$(git diff --name-status HEAD | grep -c '^A')
131
162
  DEL_FILES=$(git diff --name-status HEAD | grep -c '^D')
@@ -133,25 +164,41 @@ The rubric is not a verdict; it is a map forward.
133
164
  # pass if NET_PRIMITIVES <= 0; warn if > 0 and justify with PRIMITIVE verdict from W2
134
165
 
135
166
  # names ratchet
136
- do-reconcile.sh dictionary $(git diff --name-only HEAD | grep '\.md$' | tr '\n' ' ')
167
+ bash $R dictionary $(git diff --name-only HEAD | grep '\.md$' | tr '\n' ' ')
137
168
 
138
169
  # schema fork check
139
170
  SCHEMA_TOUCHED=$(git diff --name-only HEAD | grep '\.tql$' | tr '\n' ' ')
140
- [ -n "$SCHEMA_TOUCHED" ] && do-reconcile.sh substrate $SCHEMA_TOUCHED
171
+ [ -n "$SCHEMA_TOUCHED" ] && bash $R substrate $SCHEMA_TOUCHED
141
172
 
142
173
  # surfaces ratchet
143
174
  PAGES_TOUCHED=$(git diff --name-only HEAD | grep -E 'src/pages/' | tr '\n' ' ')
144
- [ -n "$PAGES_TOUCHED" ] && do-reconcile.sh navigation $PAGES_TOUCHED
175
+ [ -n "$PAGES_TOUCHED" ] && bash $R navigation $PAGES_TOUCHED
145
176
 
146
- # broken links
177
+ # broken links — the checker is NOT installed by default in this repo
147
178
  DOCS_TOUCHED=$(git diff --name-only HEAD | grep '\.md$' | tr '\n' ' ')
148
- [ -n "$DOCS_TOUCHED" ] && markdown-link-check $DOCS_TOUCHED
179
+ if [ -n "$DOCS_TOUCHED" ]; then
180
+ if command -v markdown-link-check >/dev/null || npx --no-install markdown-link-check --version >/dev/null 2>&1; then
181
+ markdown-link-check $DOCS_TOUCHED
182
+ else
183
+ echo "ratchet/docs: n/a — markdown-link-check not installed"
184
+ fi
185
+ fi
149
186
  ```
150
187
 
151
188
  Any ratchet regression → cycle does not close. Report each dim: `ratchet/<dim>: ok | FAIL — <reason>`.
152
189
 
190
+ **An absent tool is `n/a`, never `ok`.** `markdown-link-check` is not on `PATH` in
191
+ this repo, so the `docs` dim usually cannot run. Report `ratchet/docs: n/a — <tool>
192
+ not installed` and carry it as an open improvement item — an unrunnable gate that
193
+ prints `ok` is the false green this whole wave exists to prevent. The same rule
194
+ applies to Lighthouse (§9) and Playwright below.
195
+
153
196
  5. If deterministic checks, reconcile-per-canon, and coherence ratchet all pass → score the code rubric. Target is 1.0 on every dim.
154
- Full KPIs, scoring bands, and improvement format are in `one/rubrics.md` — Code Rubric.
197
+ Full KPIs, scoring bands, and improvement format are in `text/rubrics.md` — Code Rubric.
198
+ Note: `text/rubrics.md` also documents an eight-dimension repo-level variant
199
+ (`structure` replacing `stability`, plus `code-reuse` / `test-coverage` / `ux`).
200
+ The in-cycle W4 gate you run is the six-dimension form below, which is what
201
+ `.claude/commands/do.md` § W4 specifies. Score the six; do not silently substitute.
155
202
 
156
203
  5.5. **Goal-fit (0.30 — the heaviest dim, hard gate ≥ 0.50):** re-read the cycle's
157
204
  `Goal delta:` / plan `outcome:` and verify the shipped diff actually moves it. Confirm the
@@ -170,7 +217,7 @@ The rubric is not a verdict; it is a map forward.
170
217
  at the boundary. CF Worker env via `context.env` only. No wildcard CORS headers.
171
218
  **IDOR:** any new/changed API route reading `searchParams.get('slug'|'workspace')` or
172
219
  `body.slug`/`body.workspace` MUST call `authorizeWorkspace()` (or anchor to `locals.slug`) —
173
- `do-reconcile.sh authority` now gates this per GATEWAY file; verify it ran on EVERY touched route.
220
+ `bash .claude/scripts/do-reconcile.sh authority` gates this per GATEWAY file; verify it ran on EVERY touched route.
174
221
  **Same-pattern sweep (mandatory):** when ANY security gap is found or fixed in one file,
175
222
  extract the pattern and grep it across the ENTIRE cycle diff (`git diff HEAD --name-only`),
176
223
  not just the flagged file — fix every instance in the same wave or the cycle does not close.
@@ -182,7 +229,7 @@ The rubric is not a verdict; it is a map forward.
182
229
  7. **Stability (0.18):** biome + tsc + vitest already ran. Now check: no new `any`, no
183
230
  `@ts-ignore` without WHY comment, no silent returns (Rule 1), no wall-clock units in new
184
231
  code or docs (Rule 2), no retired dead-names (the locked list in root `CLAUDE.md` —
185
- `do-reconcile.sh dictionary` is the oracle). Score 1.0 = all zero. For each gap, emit
232
+ `bash .claude/scripts/do-reconcile.sh dictionary` is the oracle). Score 1.0 = all zero. For each gap, emit
186
233
  `→ improve: exact location`.
187
234
 
188
235
  8. **Simplicity (0.12):** the philosophy is small, focused files. The substrate — the
@@ -214,15 +261,23 @@ The rubric is not a verdict; it is a map forward.
214
261
  Score 1.0 = all files feel focused and single-purpose; functions tight; zero ceremony.
215
262
  For each gap, name what to split or delete.
216
263
 
217
- 8.5. **Integration (0.12 — deterministic first):** wired, never orphaned. If
218
- `.w2-surface-checklist.json` exists, the score IS the fraction of declared surfaces
219
- verified — nav entry registered in `navigation.ts`, every inbound link present, every
220
- declared SDK/MCP/CLI export wired, docs from `.w2-doc-plan.json` synced (the same greps
221
- the W4 surface-layer gate runs; score = verified/declared, no judgment involved). No
222
- checklist score wired-vs-orphaned from the diff: new exports have a caller or a barrel
223
- re-export, new files have an importer, no dangling route/component. The surface hard
224
- gates still block independently this score is what makes the axis compound
225
- (`mark` amount + `s:integration` signal). For each gap, emit
264
+ 8.5. **Integration (0.12 — deterministic first):** wired, never orphaned. The checklist
265
+ is mandatory — W2 always writes `.w2-surface-checklist.json`, either the surface layers
266
+ or `{"surface":"none","reason":"..."}`. Three cases:
267
+ - **File absent the integration gate FAILS the cycle.** Do not fall back to diff
268
+ heuristics a missing checklist is exactly the cycle where W2 forgot the UI, and
269
+ the gate must not vanish there. Report `integration: FAIL .w2-surface-checklist.json
270
+ missing` and fail the gate.
271
+ - **Checklist with `surface:"none"` + a `reason` string** (explicit, auditable "no
272
+ user-visible surface, because X") score wired-vs-orphaned from the diff: new exports
273
+ have a caller or a barrel re-export, new files have an importer, no dangling
274
+ route/component. `surface:"none"` without a reason is also a FAIL.
275
+ - **Checklist with layers** → the score IS the fraction of declared surfaces
276
+ verified — nav entry registered in `navigation.ts`, every inbound link present, every
277
+ declared SDK/MCP/CLI export wired, docs from `.w2-doc-plan.json` synced (the same greps
278
+ the W4 surface-layer gate runs; score = verified/declared, no judgment involved).
279
+ The surface hard gates still block independently — this score is what makes the axis
280
+ compound (`mark` amount + `s:integration` signal). For each gap, emit
226
281
  `→ improve: <checklist key or file> — left unwired`.
227
282
 
228
283
  9. **Speed (0.10):** Three sub-checks, all must pass for 1.0.
@@ -235,13 +290,19 @@ The rubric is not a verdict; it is a map forward.
235
290
 
236
291
  **Token efficiency:**
237
292
  ```bash
238
- # Agent/skill body line delta vs baseline
239
- AGENT_LINES_NOW=$(find agents -name '*.md' 2>/dev/null | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}')
240
- AGENT_LINES_W0=$(jq '.agentLines' .w0-baseline.json)
241
- AGENT_DELTA=$((AGENT_LINES_NOW - AGENT_LINES_W0))
293
+ # Agent/skill body line delta vs baseline. The agents live at .claude/agents/ —
294
+ # there is no `agents/` at repo root, and a bare `find agents` errors, leaving
295
+ # AGENT_LINES_NOW empty and the arithmetic below broken.
296
+ AGENT_LINES_NOW=$(find .claude/agents .claude/skills -name '*.md' 2>/dev/null | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}')
297
+ AGENT_LINES_W0=$(jq -r '.agentLines // empty' .w0-baseline.json 2>/dev/null)
298
+ if [ -n "$AGENT_LINES_NOW" ] && [ -n "$AGENT_LINES_W0" ]; then
299
+ AGENT_DELTA=$((AGENT_LINES_NOW - AGENT_LINES_W0))
300
+ else
301
+ echo "agent-lines: n/a — no .w0-baseline.json agentLines to compare"
302
+ fi
242
303
 
243
304
  # Flag any single .md file over 300 lines (token bloat per activation)
244
- find agents one.ie/web/src -name '*.md' 2>/dev/null | xargs wc -l | sort -rn | head -10
305
+ find .claude/agents .claude/skills one.ie/web/src -name '*.md' 2>/dev/null | xargs wc -l | sort -rn | head -10
245
306
 
246
307
  # Check for context stuffing in chat.ts — full file trees injected per request?
247
308
  git diff HEAD | grep -E '^\+.*listFiles|readdir|readdirSync' | grep -i 'prompt\|system\|context'
@@ -256,7 +317,9 @@ The rubric is not a verdict; it is a map forward.
256
317
  10. **W0 rubric delta** — read the pre-cycle baseline if present. Report the delta for each axis so the cycle shows measurable improvement, not just an absolute score.
257
318
 
258
319
  ```bash
259
- # Load W0 rubric baseline (written by do-rubric.py before the first cycle)
320
+ # Load W0 rubric baseline. do-rubric.py writes text/<slug>-w0-rubric.json before the
321
+ # first cycle; do-auto.sh copies it into the worktree as .w0-rubric.json. Read the
322
+ # worktree copy — and if it is absent, that is `velocity: null`, not a zero delta.
260
323
  if [ -f .w0-rubric.json ]; then
261
324
  W0_SEC=$(jq -r '.scores.security' .w0-rubric.json 2>/dev/null)
262
325
  W0_STA=$(jq -r '.scores.stability' .w0-rubric.json 2>/dev/null)
@@ -274,7 +337,7 @@ If `.w0-rubric.json` is absent, set `velocity: null` and omit deltas.
274
337
 
275
338
  11. Composite = `0.30·goal-fit + 0.18·security + 0.18·stability + 0.12·simplicity + 0.12·integration + 0.10·speed`. Gate: composite ≥ 0.65 AND goal-fit ≥ 0.50 (hard).
276
339
 
277
- 11. Must-not checks (bypass composite — immediate warn):
340
+ 11.5. Must-not checks (bypass composite — immediate warn):
278
341
  - Hardcoded secret or API key → `warn(1)` on security, cycle fails.
279
342
  - `eval()` or unsanitized `dangerouslySetInnerHTML` → `warn(1)`, cycle fails.
280
343
  - Test failure on W3-touched files → `warn(1)` on stability, route to W3.5.
@@ -377,16 +440,24 @@ Do NOT score 1.0 for speed without a real Lighthouse number.
377
440
 
378
441
  ### Playwright (functional + a11y verification)
379
442
 
380
- ```bash
381
- # If playwright tests exist
382
- npx playwright test --reporter=line 2>&1 | tail -20
443
+ Playwright runs only when the cycle declares `requires_playwright: true` (testing policy,
444
+ `.claude/commands/do.md`). Vitest is the default; do not add a Playwright gate to a cycle
445
+ that did not ask for one.
383
446
 
384
- # Quick a11y scan (axe-playwright) on touched pages — if configured
385
- npx playwright test tests/a11y --reporter=line
447
+ ```bash
448
+ # Only if the cycle declares requires_playwright AND a config exists
449
+ if [ -f playwright.config.ts ] || [ -f playwright.config.js ]; then
450
+ npx playwright test --reporter=line 2>&1 | tail -20
451
+ # a11y scan (axe-playwright) on touched pages — if that suite exists
452
+ [ -d tests/a11y ] && npx playwright test tests/a11y --reporter=line
453
+ else
454
+ echo "playwright: n/a — no config in this folder"
455
+ fi
386
456
  ```
387
457
 
388
458
  Playwright failures are stability failures — they join the vitest gate.
389
459
  A11y failures from playwright count against the Accessibility Lighthouse category.
460
+ Absent config → `playwright: n/a`, never a silent pass.
390
461
 
391
462
  ### Bundle size (Speed dim)
392
463
 
@@ -394,8 +465,9 @@ A11y failures from playwright count against the Accessibility Lighthouse categor
394
465
  # Check CF Worker bundle size
395
466
  npx wrangler deploy --dry-run --outdir=.wrangler/output 2>&1 | grep -E 'Total|gzip'
396
467
 
397
- # Or check Astro build output
398
- bun run build 2>&1 | grep -E 'dist/|\.js|\.css|kB'
468
+ # Or check Astro build output (in the package folder — no root package.json)
469
+ FOLDER="${FOLDER:-one.ie/web}"
470
+ ( cd "$FOLDER" && bun run build ) 2>&1 | grep -E 'dist/|\.js|\.css|kB'
399
471
 
400
472
  # Delta vs W0: compare to the buildMs + sizes recorded in W0
401
473
  ```
@@ -444,24 +516,34 @@ cat > .w4-improvements.json <<EOF
444
516
  "w0_composite": W0_CMP_OR_NULL,
445
517
  "velocity": COMPOSITE_MINUS_W0_COMPOSITE_OR_NULL,
446
518
  "open": [
447
- { "dim": "security", "score": SEC, "file": "...", "line": N, "action": "..." },
448
- { "dim": "stability", "score": STA, "file": "...", "line": N, "action": "..." },
449
- { "dim": "simplicity", "score": SIM, "file": "...", "line": N, "action": "..." },
450
- { "dim": "speed", "score": SPD, "audit": "...", "component": "...", "action": "..." }
519
+ { "dim": "goal-fit", "score": GOA, "action": "<what the goal still needs>" },
520
+ { "dim": "security", "score": SEC, "file": "...", "line": N, "action": "..." },
521
+ { "dim": "stability", "score": STA, "file": "...", "line": N, "action": "..." },
522
+ { "dim": "simplicity", "score": SIM, "file": "...", "line": N, "action": "..." },
523
+ { "dim": "integration", "score": INT, "checklist_key": "...", "action": "..." },
524
+ { "dim": "speed", "score": SPD, "audit": "...", "component": "...", "action": "..." }
451
525
  ]
452
526
  }
453
527
  EOF
454
- # Omit any dim with score 1.00 from "open" — those are clean.
528
+ # All six scored dims appear here. Omit any dim with score 1.00 from "open" — those are
529
+ # clean. Never omit a dim because you did not score it; an unscored dim is a fail on
530
+ # that dim (Rule 3).
455
531
 
456
532
  # b) Human-readable history: feeds pattern detection and learning
457
533
  cat >> docs/improvements.md <<EOF
458
534
 
459
535
  ## $(date -u +%Y-%m-%d) · cycle N · composite=COMPOSITE (Δ VELOCITY)
460
- - security/SEC: IMPROVE_LINE_OR_clean
461
- - stability/STA: IMPROVE_LINE_OR_clean
462
- - simplicity/SIM: IMPROVE_LINE_OR_clean
463
- - speed/SPD: IMPROVE_LINE_OR_clean
536
+ - goal-fit/GOA: IMPROVE_LINE_OR_clean
537
+ - security/SEC: IMPROVE_LINE_OR_clean
538
+ - stability/STA: IMPROVE_LINE_OR_clean
539
+ - simplicity/SIM: IMPROVE_LINE_OR_clean
540
+ - integration/INT: IMPROVE_LINE_OR_clean
541
+ - speed/SPD: IMPROVE_LINE_OR_clean
464
542
  EOF
543
+
544
+ # c) Shrink the improvements queue: delete every line this cycle actually resolved.
545
+ # The queue shrinks or the loop is hoarding (.claude/commands/do.md § W1).
546
+ # Delete only what you verified fixed — never a line you merely read.
465
547
  ```
466
548
 
467
549
  **Systemic gap detection** — after writing, check for patterns:
@@ -490,11 +572,19 @@ the substrate — this file is structurally weak and should be prioritized in fu
490
572
 
491
573
  ## Known-flaky allowlist
492
574
 
493
- Tests matching patterns in `scripts/deploy.ts` `KNOWN_FLAKY` are stochastic (timing, network). They do NOT fail the gate — report them as `flaky=N` in the receipt and continue. See memory `feedback_timing_tests.md`.
575
+ A test that is stochastic by construction hardware-timing benchmarks, network reachability,
576
+ sampling/distribution tests — does NOT fail the gate. Report it as `flaky=N` in the receipt,
577
+ name each one, and continue. Judge stochasticity from the test itself; there is no
578
+ `KNOWN_FLAKY` allowlist in this repo (the one the older prompt cited, in `scripts/deploy.ts`,
579
+ no longer exists — do not cite a file you have not read). A test that fails deterministically
580
+ on re-run is not flaky: it is a stability failure and routes to W3.5.
494
581
 
495
582
  ## TypeScript crash handling
496
583
 
497
- `tsc` 5.9 has a known stack-overflow bug see memory `feedback_typecheck_crash.md`. If `tsc` crashes WITHOUT a real `TS####` error line, treat as pass. Fall through to `scripts/typecheck.sh` if it exists.
584
+ If `tsc` crashes (stack overflow, internal error) WITHOUT emitting a real `TS####` error
585
+ line, treat it as pass and report `tsc: crashed — no TS#### emitted, treated as pass`.
586
+ A crash that DOES emit `TS####` lines is a normal failure. Re-run once before either
587
+ verdict.
498
588
 
499
589
  ## Completion signal
500
590
 
@@ -508,11 +598,12 @@ Success:
508
598
  "content": {
509
599
  "passed": N, "failed": 0,
510
600
  "rubric": {
511
- "goal-fit": { "score": 0.90, "improve": "clean" },
512
- "security": { "score": 0.95, "improve": "src/pages/api/provision.ts:31 — missing Zod parse on slug" },
513
- "stability": { "score": 1.00, "improve": "clean" },
514
- "simplicity": { "score": 0.85, "improve": "inline formatDate() at src/lib/slug.ts:12, saves 9 lines" },
515
- "speed": { "score": 0.80, "improve": "EvalCard client:load → client:visible; Lighthouse Perf 97" }
601
+ "goal-fit": { "score": 0.90, "improve": "clean" },
602
+ "security": { "score": 0.95, "improve": "src/pages/api/provision.ts:31 — missing Zod parse on slug" },
603
+ "stability": { "score": 1.00, "improve": "clean" },
604
+ "simplicity": { "score": 0.85, "improve": "inline formatDate() at src/lib/slug.ts:12, saves 9 lines" },
605
+ "integration": { "score": 1.00, "improve": "clean" },
606
+ "speed": { "score": 0.80, "improve": "EvalCard client:load → client:visible; Lighthouse Perf 97" }
516
607
  },
517
608
  "composite": 0.91,
518
609
  "velocity": +0.06,
@@ -537,11 +628,12 @@ Failure:
537
628
  "passed": N, "failed": M,
538
629
  "failures": ["<test name or tsc error>"],
539
630
  "rubric": {
540
- "goal-fit": { "score": 0.40, "improve": "diff does not advance plan outcome — goal still needs <X>" },
541
- "security": { "score": 0.50, "improve": "src/pages/api/chat.ts:23 — missing Zod parse on body.slug" },
542
- "stability": { "score": 0.00, "improve": "vitest: chat renders message FAILED — type mismatch line 14" },
543
- "simplicity": { "score": 0.60, "improve": "parseMarkdown() 18 lines, one caller — inline and delete" },
544
- "speed": { "score": 0.50, "improve": "Lighthouse Perf 94 unused JS from lodash import in slug.ts" }
631
+ "goal-fit": { "score": 0.40, "improve": "diff does not advance plan outcome — goal still needs <X>" },
632
+ "security": { "score": 0.50, "improve": "src/pages/api/chat.ts:23 — missing Zod parse on body.slug" },
633
+ "stability": { "score": 0.00, "improve": "vitest: chat renders message FAILED — type mismatch line 14" },
634
+ "simplicity": { "score": 0.60, "improve": "parseMarkdown() 18 lines, one caller — inline and delete" },
635
+ "integration": { "score": 0.50, "improve": "surfaces[0].nav_entry/u/[slug]/new left unwired" },
636
+ "speed": { "score": 0.50, "improve": "Lighthouse Perf 94 — unused JS from lodash import in slug.ts" }
545
637
  },
546
638
  "composite": 0.34,
547
639
  "velocity": -0.12,
@@ -553,7 +645,10 @@ Failure:
553
645
  }
554
646
  ```
555
647
 
556
- `velocity` = this cycle's composite minus the previous cycle's composite (read from `docs/improvements.md`).
648
+ `velocity` = this cycle's composite minus the **W0 baseline** composite from
649
+ `.w0-rubric.json` (step 10) — one definition, used everywhere. If `.w0-rubric.json` is
650
+ absent, `velocity` is `null` — report the prior cycle's composite from
651
+ `docs/improvements.md` as prose context if it helps, never as the `velocity` field.
557
652
  Positive velocity = the system is improving. Negative = something regressed.
558
653
  Pheromone compounds the velocity signal: `mark(edge, composite)` every cycle → paths that
559
654
  consistently score high get strong; paths that keep failing accumulate resistance.
@@ -1,55 +1,118 @@
1
- # /browser — Playwright browser diagnostic
1
+ # /browser — headless-shell browser driver
2
2
 
3
- Runs a headless Chrome check against a URL and reports page health, JS errors, and chat behaviour.
3
+ Drives **chrome-headless-shell** against a URL and reports page health, JS errors, network, and anything you tell it to click, fill, or evaluate.
4
+
5
+ This replaced the `claude-in-chrome` MCP tools. No extension, no Chrome profile, no desktop browser, no human in the loop — one process per invocation, one JSON report on stdout.
4
6
 
5
7
  ## Usage
6
8
 
9
+ ```bash
10
+ node .claude/scripts/chrome.mjs <url> [flags]
7
11
  ```
8
- /browser [url] [--send "message"] [--screenshot] [--network]
12
+
13
+ Default url: `http://localhost:4321`.
14
+
15
+ ## Flags
16
+
17
+ | Flag | Does |
18
+ |---|---|
19
+ | `--text` | page `innerText` (truncate at `--max`, default 4000) |
20
+ | `--html` | page HTML |
21
+ | `--sel <css>` | scope `--text`/`--html` to a selector |
22
+ | `--screenshot [path]` | PNG, default `/tmp/chrome-shot.png`; add `--full-page` for the whole document |
23
+ | `--console` | every console line (errors are always reported) |
24
+ | `--network` | responses to `/api/*`; `--network-all` widens it to everything |
25
+ | `--eval <js>` | evaluate an expression in the page, return its value |
26
+ | `--do <json>` | run a step list — see below |
27
+ | `--send <msg>` | chat drill: fill the first textarea, press Enter, capture the SSE stream |
28
+ | `--send-wait <ms>` | how long to hold open after `--send` (default 12000) |
29
+ | `--wait <ms>` | settle time after load (default 2500) |
30
+ | `--timeout <ms>` | navigation timeout (default 20000) |
31
+ | `--state <path>` | persist cookies + localStorage to `<path>` and reuse them next run |
32
+ | `--cookie <n=v>` | cookie for the target host (repeatable) |
33
+ | `--header <k: v>` | extra HTTP header (repeatable) |
34
+ | `--ua <string>` · `--viewport <WxH>` | user agent · viewport (default 1280x800) |
35
+ | `--headed` | full Chromium with a visible window instead of the shell |
36
+ | `--max <n>` | truncation ceiling for text/html/eval |
37
+
38
+ `PROVE_SESSION_COOKIE="name=value"` is honoured the same way as before, so an auth-gated `/u/[slug]/*` route can be proven signed-in.
39
+
40
+ ## Steps (`--do`)
41
+
42
+ A JSON array executed in order. Each entry is one object; every step reports `{step, kind, ok, error?, result?}` and a failed step does **not** abort the run.
43
+
44
+ ```json
45
+ [
46
+ {"goto": "http://localhost:4321/login"},
47
+ {"fill": "input[type=email]", "value": "tony@one.ie"},
48
+ {"click": "button[type=submit]"},
49
+ {"waitFor": ".dashboard"},
50
+ {"eval": "document.querySelectorAll('[data-row]').length"},
51
+ {"screenshot": "/tmp/after-login.png"}
52
+ ]
9
53
  ```
10
54
 
11
- **Arguments (all optional):**
12
- - `url` — page to check (default: `http://localhost:4321`)
13
- - `--send "text"` — type and submit a chat message, then compare rail before/after
14
- - `--screenshot` — save `/tmp/browser-check.png`
15
- - `--network` — capture API request list
55
+ Kinds: `goto` · `click` · `dblclick` · `hover` · `fill`+`value` · `press`(+`sel`) · `select`+`value` · `check`(+`value:false` to uncheck) · `upload`+`files` · `scroll` (px, or a selector to bring into view) · `wait` (ms) · `waitFor` (selector) · `eval` · `screenshot`.
56
+
57
+ ## Sessions
16
58
 
17
- ## How to invoke
59
+ Each invocation is a fresh browser — that is the trade for having no extension. `--state` is how a session survives it:
18
60
 
19
61
  ```bash
20
- node .claude/scripts/browser-check.mjs http://localhost:4321/studio/boq-empire?agent=boq-empire --send "hello" --screenshot
21
- ```
62
+ # sign in once, keep the session
63
+ node .claude/scripts/chrome.mjs http://localhost:4321/login --state /tmp/one.json \
64
+ --do '[{"fill":"#email","value":"tony@one.ie"},{"click":"button[type=submit]"},{"waitFor":".dashboard"}]'
22
65
 
23
- Or directly in conversation Claude runs the script via Bash.
66
+ # every later run reuses it
67
+ node .claude/scripts/chrome.mjs http://localhost:4321/u/one/in --state /tmp/one.json --text
68
+ ```
24
69
 
25
- ## What it checks
70
+ The report carries `stateLoaded` (was the file read) and `stateSaved` (where it was written). Without `--state`, cookies and localStorage die with the process — put the whole flow in one `--do` list instead.
26
71
 
27
- | Check | How |
28
- |---|---|
29
- | HTTP status | `page.goto` response code |
30
- | Title | `page.title()` |
31
- | JS errors | `pageerror` events |
32
- | Console errors | `console.error` events |
33
- | Chat rail (before send) | `.chat-rail` innerText |
34
- | Chat POST body | fetch monkey-patch captures `agentId`, `slug`, messages |
35
- | Stream content | Reads cloned SSE stream; shows first 800 chars |
36
- | Chat rail (after send) | After 12s wait post-submit |
72
+ `file://` URLs work, so a local fixture is a valid target.
37
73
 
38
- ## Prerequisites
74
+ ## Examples
39
75
 
40
- Playwright installed once:
41
76
  ```bash
42
- cd /tmp && npm install playwright && npx playwright install chromium
77
+ # health check one route
78
+ node .claude/scripts/chrome.mjs http://localhost:4321/pricing --console --network
79
+
80
+ # read a page
81
+ node .claude/scripts/chrome.mjs https://one.ie --text --sel main --max 8000
82
+
83
+ # drill a form and shoot the result
84
+ node .claude/scripts/chrome.mjs http://localhost:4321/contact \
85
+ --do '[{"fill":"#email","value":"a@b.c"},{"click":"button[type=submit]"},{"wait":2000}]' \
86
+ --screenshot /tmp/contact.png
87
+
88
+ # chat diagnostic (the old browser-check job)
89
+ node .claude/scripts/chrome.mjs "http://localhost:4321/studio/boq-empire?agent=boq-empire" --send "hello"
43
90
  ```
44
91
 
45
- Check with: `node -e "require('/tmp/node_modules/playwright'); console.log('ok')"`
92
+ ## Report fields
93
+
94
+ `url` · `finalUrl` · `engine` · `playwrightFrom` · `httpStatus` · `navError` · `title` · `jsErrors` · `consoleErrors` · `console?` · `network?` · `steps?` · `chatCapture?` · `chatRailBefore?` · `chatRailAfter?` · `text?` · `html?` · `eval?` · `screenshot?`
95
+
96
+ Exit **0** = the run completed (read `httpStatus` and `jsErrors` for the verdict). Exit **1** = the browser could not run at all, and stderr carries `{"error": …, "fix": …}`.
97
+
98
+ ## Prerequisites
99
+
100
+ None to install by hand. chrome-headless-shell ships with the repo's Playwright and the script finds it:
101
+
102
+ 1. `ONE_PLAYWRIGHT_DIR` if set
103
+ 2. `one.ie/web/node_modules` then `node_modules`, in this tree **and** in the main worktree (via `git rev-parse --git-common-dir`) — a linked worktree has no `node_modules` of its own
104
+ 3. `/tmp/node_modules` (legacy)
105
+
106
+ If none resolve it exits 1 with the fix: `cd one.ie/web && bun install && bunx playwright install chromium-headless-shell`. If the shell channel is missing it falls back to plain headless Chromium.
107
+
108
+ ## Who calls it
109
+
110
+ | Caller | How |
111
+ |---|---|
112
+ | `do-prove.sh` | every `--route` check — reads `httpStatus`, `jsErrors`, `consoleErrors`; curl is the fallback when the browser can't run. A route fails on 404, ≥500, an uncaught JS error, or a console error; subresource **401/403 are tolerated** (PROVE runs signed-out, so gated is not broken) — the same policy the curl leg already applied |
113
+ | `browser-check.mjs` | deprecated shim, maps old flags onto `chrome.mjs` and renames fields back |
114
+ | you | directly, via Bash |
46
115
 
47
- ## Output
116
+ ## What it is not
48
117
 
49
- JSON report to stdout. Key fields:
50
- - `httpStatus` — 200/404/500
51
- - `jsErrors` — uncaught JS exceptions
52
- - `consoleErrors` — console.error calls
53
- - `chatRailBefore` / `chatRailAfter` — visible text
54
- - `chatCapture[].body` — POST body (check `agentId` present)
55
- - `chatCapture[].stream` — SSE response (check for error vs real tokens)
118
+ Not a hand on the operator's own logged-in Chrome. It has no profile, no session, and no visible surface for a human to approve an action on. Jobs that need those — `.claude/skills/directory-autofill` is the one in this repo — are **not** served by this script.
@@ -20,11 +20,17 @@ Three spaces wired by default:
20
20
  /cc-connect broadcast "text" # fan out — all space:* groups at once
21
21
  /cc-connect listen # start SSE listeners for all subscribed spaces
22
22
  /cc-connect stop # kill all listeners
23
+ /cc-connect stop space:vespio # kill just one listener
23
24
  /cc-connect status # listener PIDs + unread counts per space
25
+ /cc-connect listeners # list every running listener PID
26
+ /cc-connect groups # ask channels which groups exist (discovery)
24
27
  /cc-connect join space:X # subscribe + start listener for a new space
25
28
  /cc-connect leave space:X # unsubscribe + stop listener
26
29
  ```
27
30
 
31
+ `read` with no group reads your default space; `read <group>` reads one named
32
+ space. Requires `bash`, `curl`, and `jq` on PATH.
33
+
28
34
  **→ Use `/chat` for the simple two-key interface: read = fan in, send = fan out.**
29
35
 
30
36
  ## How to invoke
package/commands/chat.md CHANGED
@@ -32,4 +32,16 @@ Want a desktop popup when something lands? `brew install terminal-notifier` (one
32
32
 
33
33
  ## Advanced (raw commands, rarely needed)
34
34
 
35
- `/chat` is a shortcut for `.claude/scripts/cc-connect.sh`. Reach for the raw form only when you need something `/chat` doesn't expose — joining a new space, checking listener status, reading offline history. See `/cc-connect` for the full surface.
35
+ `/chat` is a shortcut for `.claude/scripts/cc-connect.sh`. The three moves map exactly:
36
+
37
+ | `/chat` form | runs |
38
+ |---|---|
39
+ | `/chat` | `.claude/scripts/cc-connect.sh read --all` |
40
+ | `/chat "text"` | `.claude/scripts/cc-connect.sh broadcast "text"` |
41
+ | `/chat @vespio "text"` | `.claude/scripts/cc-connect.sh send --to space:vespio "text"` |
42
+
43
+ `@name` is `/chat` sugar — cc-connect itself wants the full `space:name`.
44
+ Send fans out via `broadcast`, not `send`: `send` with no `--to` hits only your
45
+ default space, which is not what `/chat "text"` promises.
46
+
47
+ Reach for the raw form only when you need something `/chat` doesn't expose — joining a new space, checking listener status, reading offline history. See `/cc-connect` for the full surface.