@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
@@ -8,6 +8,25 @@ Apply to all TODOs and `/do` workflows.
8
8
 
9
9
  Within a build cycle this still maps to three phases: **W2** declares which docs this cycle touches (the spec already exists; W2 lists the deltas), **W3** edits docs alongside code in the same wave, **W4** verifies consistency *and truth* against the shipped behaviour. The difference from before: the full doc set is not seeded-then-refined — it is written for real up front, and the cycle keeps it in sync and proves it true.
10
10
 
11
+ ## Promises grow with delivery (always update the promise with what shipped)
12
+
13
+ **When you ship a feature that extends an already-kept promise — a new view, capability, or surface under the same banner — you MUST append it to that promise as a new `deliverable:` with its own `accept:` check, and extend the `proof:` `&&`-join to include that check.** This is not optional polish; it is what keeps the promise a record the system can depend on. A promise that silently omits shipped work is a promise that lies about the delivery, and the router that sells the next signal to the proven path is reading a stale contract.
14
+
15
+ The covenant's freeze (clause 4, `text/promises.md`) permits this because it is a **monotonic ratchet** — the same "can't regress" DNA `/do` runs on:
16
+
17
+ - **Allowed (do it every time):** append a deliverable whose `accept:` is **already green**, and add that exact `accept:` string to `proof:`. The join stays exit-0; the record only rises. No new `terms_hash` needed — nothing that was promised changed.
18
+ - **Forbidden (needs a *new* promise):** anything that would make the existing proof go **red** — weakening a check, removing a line, reversing a decision, or a broken `assumes:`. That's a regression, not growth.
19
+
20
+ Checklist when extending a kept promise `text/<slug>.md`:
21
+
22
+ 1. Add the `- item:` + `accept:` row under `deliverables:` (group fulfilled follow-ons under a dated comment).
23
+ 2. Append the identical `accept:` body to `proof:` (the schedule ⊆ proof law — `do-promise-lint.sh` enforces verbatim inclusion).
24
+ 3. Add any new `world:` entries (a new view → `views:`, a new workflow step → `workflow:`).
25
+ 4. Add the human-readable row to the deliverables table in the prose, and reconcile any now-stale status claim (e.g. an "X is still red / not shipped" line for the thing you just shipped).
26
+ 5. Run `bash .claude/scripts/do-promise-lint.sh <slug>` — it must report `schedule ⊆ proof, contract well-formed` **and** every `assumes:` green. Fix any stale `assumes:` path while you're there (a moved file makes the whole contract un-signable).
27
+
28
+ The same discipline applies to the propagate matrix below: the promise is the first row every close reconciles, before its derived docs.
29
+
11
30
  **Format:** any ASCII diagram written into a doc follows `text/CLAUDE.md § ASCII diagrams` — max ~60 chars wide, vertical flow over multi-column tables. A diagram that's fine in a wide terminal wraps into garbage in the narrow panels these docs actually get read in.
12
31
 
13
32
  ---
@@ -106,79 +125,12 @@ These six docs are the **source of truth** and must stay in sync with code:
106
125
  | **one-ontology.md** | 6 dimensions, actor/group/thing/path/signal/hypothesis | Type system changes |
107
126
  | **routing.md** | L1-L7 loops, signal flow, priority formula | Loop/routing changes |
108
127
  | **lifecycle.md** | Agent journey stages, revenue flow | Lifecycle/economic changes |
109
- | **rubrics.md** | Code rubric (security/stability/simplicity/integration/speed) + agent rubric (fit/form/truth/taste) | Rubric changes or new dimensions |
128
+ | **rubrics.md** | Code rubric (the design target — eight dims) + agent rubric (fit/form/truth/taste). Live weights are data at `.claude/scripts/rubric-weights.json`; the gap between the two is `text/rubric-migration-plan.md` | Rubric changes or new dimensions |
110
129
 
111
130
  **Feature-specific docs** (rich-messages.md, webhooks.md, etc.) are updated per feature. Always link back to the six core docs.
112
131
 
113
132
  ---
114
133
 
115
- ## The Workflow Integration
116
-
117
- ### Hook: Pre-W2 — Load Source Docs
118
-
119
- When a TODO is created, auto-load relevant source docs:
120
-
121
- ```
122
- /do {name}-todo.md
123
- ├─ [Hook] Load: dictionary.md, DSL.md, rubrics.md
124
- ├─ [W1] Recon code (reads files)
125
- ├─ [W2] Decide code + **document changes needed in docs**
126
- │ (explicit list: what terms change, what loops change, what's new)
127
- ├─ [W3] Edit code (spawns Sonnet agents)
128
- │ + [Hook] Suggest: "Also edit X doc for {Y change}"
129
- └─ [W4] Verify code + **verify docs match** (cross-check task)
130
- ```
131
-
132
- ### Hook: Post-W4 — Validate Doc Consistency
133
-
134
- After W4 completes, auto-run consistency checks:
135
-
136
- ```bash
137
- # Terminology consistency
138
- grep -r "old-term" text/ | flag if > 0 (not on deadname list)
139
-
140
- # Cross-references
141
- markdown-link-check text/*.md
142
-
143
- # Metaphor alignment (if touching signal/path semantics)
144
- grep -l "signal\|strength\|resistance" src/changed-files.txt | xargs -I {} \
145
- check if metaphors.md still applies
146
-
147
- # Rubric scoring (if W4 added dimensions)
148
- grep "rubric\|dimension" src/changed-files.txt | flag for rubrics.md review
149
- ```
150
-
151
- ---
152
-
153
- ## Example: rich-messages-todo (Retrospective)
154
-
155
- **What should have happened (W2):**
156
-
157
- ```markdown
158
- ### Documentation Updates (W2)
159
-
160
- **New docs:**
161
- - None (extends existing types)
162
-
163
- **Docs modified:**
164
- - `text/dictionary.md` — add "Rich Messages" section, explain `data.rich` convention
165
- - `text/rich-messages.md` — add PaymentMetadata type, Payment flow section
166
- - `text/template-todo.md` — add "Documentation Updates (W2 + W4)" section
167
-
168
- **Schema changes:**
169
- - `nanoclaw/src/types.ts` — RichMessage.thread, RichMessage.payment added (Cycle 1 & 3)
170
- - `migrations/0010_payment_columns.sql` — new D1 columns for payment tracking
171
- ```
172
-
173
- **What actually happened:**
174
-
175
- - ✅ Docs updated (rich-messages.md, dictionary.md, template-todo.md) — **AFTER W4**
176
- - ⚠️ Should have been planned in W2, preventing surprises in W3
177
-
178
- **Lesson:** Next TODO follows: document in W2, edit in W3, verify in W4. No surprises.
179
-
180
- ---
181
-
182
134
  ## Rules for `/do` (The Command)
183
135
 
184
136
  When running `/do {name}-todo.md`, the workflow enforces:
@@ -186,7 +138,7 @@ When running `/do {name}-todo.md`, the workflow enforces:
186
138
  1. **W2 must explicitly call out doc changes** — no surprise doc edits in W3
187
139
  2. **W3 spawns edit agents for both code AND docs** — parallel edits
188
140
  3. **W4 includes doc consistency check** — not just code tests
189
- 4. **The code rubric (security/stability/simplicity/integration/speed) applies to docs too** — simplicity means fewer words; stability means no broken links; security means no sensitive data exposed; integration means every doc is linked from its family and lies about nothing shipped; speed means lean docs = fewer tokens to read
141
+ 4. **The code rubric applies to docs too**, reading each axis for prose — simplicity means fewer words; stability means no broken links and accurate references; security means no sensitive data exposed; integration means every doc is linked from its family and lies about nothing shipped; speed means lean docs = fewer tokens to read. (Axis names and weights: `.claude/scripts/rubric-weights.json`. Note the doc reading of *stability* — links and references — is not the code reading — error handling and closed loops; same name, two criteria, which is exactly why the eight-dim migration splits it.)
190
142
 
191
143
  ---
192
144
 
@@ -200,6 +152,8 @@ When running `/do {name}-todo.md`, the workflow enforces:
200
152
 
201
153
  | Trigger (detected from W3 diff) | Target doc | Edit |
202
154
  |---|---|---|
155
+ | feature extends an already-kept promise | that `text/<slug>.md` promise | **first row, always** — append the fulfilled deliverable + its green `accept:`, extend `proof:`, add `world:` entries, then `do-promise-lint.sh <slug>` must pass (see § Promises grow with delivery) |
156
+ | slug has `text/<slug>-agents.md` (a verification walk exists) | `.claude/scripts/do-walk.sh <slug> --agents` | run it — must exit 0; a promise extension that added a deliverable but no matching walk stop is an incomplete close, append the stop to both `-humans.md` and `-agents.md` before the cycle closes |
203
157
  | any change | source-of-truth doc(s) from plan frontmatter | always — even if only touch-verified |
204
158
  | 6-dim, L1-L8, or locked-rule change | root `CLAUDE.md` | edit the relevant section |
205
159
  | directory contract change (new component family, new pattern) | nearest `CLAUDE.md` (e.g., `one.ie/web/src/components/CLAUDE.md`) | append / edit section |
@@ -212,7 +166,12 @@ Anchor mismatch → log to `text/improvements.md` for manual W2 next cycle (no h
212
166
  **Learnings entry** (append to `text/learnings.md` on each close):
213
167
 
214
168
  ```
215
- - YYYY-MM-DD · cycle N · wave N|gate · {one sentence} · rubric=0.NN · source=w1|w2|w3|w4|cycle
169
+ - YYYY-MM-DD · cycle N · wave N|gate · {one sentence} · rubric=0.NN [sec.NN simp.NN struct.NN speed.NN integ.NN reuse.NN test.NN ux.NN] · source=w1|w2|w3|w4|cycle
170
+
171
+ The `[...]` eight-field vector is self-labeling and appended, never replacing the
172
+ composite — see `text/rubrics.md` § Code Rubric for the eight dimensions and the
173
+ per-field scoring rules. A close with no per-dimension breakdown to hand may omit
174
+ the vector (old form still parses; counts toward the composite trend only).
216
175
  ```
217
176
 
218
177
  W4 code rubric applies to docs too: security (no sensitive data), stability (no broken links, accurate references), simplicity (fewer words, no bloat), speed (lean = fewer tokens to read).
@@ -222,7 +181,7 @@ W4 code rubric applies to docs too: security (no sensitive data), stability (no
222
181
  W4 must pass four bash checks before the rubric runs. Detail in `.claude/commands/do.md` W4 section. Summary:
223
182
 
224
183
  1. **stale-name check** — every old identifier in W3's rename list has 0 hits in `**/*.md`
225
- 2. **broken-link check** — `markdown-link-check` on every touched doc returns 0 broken
184
+ 2. **broken-link check** — `markdown-link-check` on every touched doc returns 0 broken. **It is not installed** (`command -v markdown-link-check` → nothing), so this check cannot pass today. Report it `n/a`, never `ok` — an absent tool is an unrun check, not a green one. Install it or replace it with a resolve-every-relative-link grep; do not let it silently vanish.
226
185
  3. **contract-staleness check** — every dir whose code was touched has `CLAUDE.md` mtime ≥ newest code mtime
227
186
  4. **shipped-status check** — the just-built slug's own `text/<slug>-plan.md` / `-docs.md` must not still claim the feature is unbuilt:
228
187
  ```bash
package/rules/engine.md CHANGED
@@ -120,7 +120,14 @@ world.restore(snapshot) // rehydrate
120
120
  ```
121
121
 
122
122
  Over HTTP the same verbs are `SubstrateClient` methods (`packages/sdk/src/client.ts`).
123
- `harden` is exposed via `signal("learning:know")`.
123
+
124
+ `harden` is the one verb with **no general wire**. `learning:know` is in no
125
+ registry (`grep -c "learning:" packages/sdk/src/receivers.ts` → 0) and has no
126
+ resolver; `client.know()` is `@deprecated` and returns `{}`. The only shipped
127
+ harden receiver is **`chat:harden`** (`one.ie/web/src/lib/resolvers/entity.ts:566`),
128
+ which crystallises a resolved chat thread into a dim-6 learning and requires an
129
+ `entityId` — so it does not cover free-standing claims. Do not write
130
+ `signal("learning:know")` into new code or docs; it fails silently.
124
131
 
125
132
  **Promise paths.** `promise:<slug>→proof` is a first-class weighted path
126
133
  family. At close, `.claude/scripts/do-promise-settle.sh` re-runs the
package/rules/ui.md CHANGED
@@ -35,8 +35,12 @@ Receiver naming: `ui:<surface>:<action>` where surface is the component or page
35
35
  | `settings` | close, save, reset | `ui:settings:close`, `ui:settings:save` |
36
36
  | `memory` | reveal, forget, expand | `ui:memory:reveal`, `ui:memory:forget` |
37
37
  | `demo` | run, reset, next | `ui:demo:run`, `ui:demo:reset` |
38
+ | `in:space` / `in:view` | the inbox axes — select, open | `ui:in:space:select`, `ui:in:view:open` |
39
+ | `switcher` | group switching | `ui:switcher:open`, `ui:switcher:select` |
40
+ | `members` | add, remove, delegate | `ui:members:add`, `ui:members:delegate` |
38
41
 
39
- Format: `ui:<surface>:<action>` — all lowercase, colon-delimited.
42
+ Format: `ui:<surface>:<action>` — all lowercase, colon-delimited. A surface may
43
+ nest (`in:space`), but the action is always the last segment.
40
44
 
41
45
  ---
42
46
 
@@ -1,122 +1,63 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * browser-check.mjs — Playwright browser diagnostic tool.
3
+ * browser-check.mjs — DEPRECATED SHIM. Kept so existing callers keep working.
4
4
  *
5
- * Usage:
6
- * node .claude/scripts/browser-check.mjs [url] [--send "message"] [--screenshot] [--network]
5
+ * The engine is now `.claude/scripts/chrome.mjs` (chrome-headless-shell via
6
+ * Playwright). This file maps the old flag set onto it and renames the report
7
+ * fields back to the shape `do-prove.sh` and `/browser` already parse.
7
8
  *
8
- * Requires: playwright in /tmp/node_modules (installed once, persists across sessions)
9
- * Install: cd /tmp && npm install playwright && npx playwright install chromium
9
+ * New work calls chrome.mjs directly — it has steps, network, eval, selectors,
10
+ * cookies and headers this shim does not expose.
10
11
  *
11
- * What it checks:
12
- * - Page load (status, title, console errors)
13
- * - Chat rail text before/after sending a message (--send)
14
- * - API request/response monitoring (--network)
15
- * - Screenshot saved to /tmp/browser-check.png (--screenshot)
16
- * - JS errors, React hydration errors
12
+ * Old usage (unchanged):
13
+ * node .claude/scripts/browser-check.mjs [url] [--send "msg"] [--screenshot] [--network]
14
+ *
15
+ * Old prerequisite (`npm install playwright` into /tmp) is GONE. chrome.mjs
16
+ * finds Playwright wherever this tree installed it, including from a linked
17
+ * worktree. The /tmp copy had already evaporated, which silently degraded every
18
+ * browser PROVE to a curl fallback.
17
19
  */
18
20
 
19
- import pkg from '/tmp/node_modules/playwright/index.js'
20
- const { chromium } = pkg
21
- import { writeFileSync } from 'fs'
21
+ import { spawnSync } from 'node:child_process'
22
+ import { dirname, join } from 'node:path'
23
+ import { fileURLToPath } from 'node:url'
22
24
 
25
+ const HERE = dirname(fileURLToPath(import.meta.url))
23
26
  const args = process.argv.slice(2)
24
- const urlArg = args.find(a => a.startsWith('http')) ?? 'http://localhost:4321'
27
+
28
+ const url = args.find((a) => a.startsWith('http')) ?? 'http://localhost:4321'
25
29
  const sendMsg = args.find((_, i) => args[i - 1] === '--send') ?? null
26
30
  const doScreenshot = args.includes('--screenshot')
27
31
  const doNetwork = args.includes('--network')
28
32
 
29
- const browser = await chromium.launch({ headless: true })
30
- const page = await browser.newPage()
31
-
32
- // Capture console output
33
- const consoleLogs = []
34
- const jsErrors = []
35
- page.on('console', m => consoleLogs.push({ type: m.type(), text: m.text() }))
36
- page.on('pageerror', e => jsErrors.push(String(e)))
37
-
38
- // Network monitoring
39
- const apiRequests = []
40
- const apiResponses = []
41
- if (doNetwork) {
42
- page.on('request', req => {
43
- if (req.url().includes('/api/')) {
44
- apiRequests.push({ method: req.method(), url: req.url().split('?')[0] })
45
- }
46
- })
47
- }
48
-
49
- // Patch fetch to capture chat API body + stream
50
- await page.addInitScript(() => {
51
- const orig = window.fetch
52
- window.__chatCapture = []
53
- window.fetch = async (...args) => {
54
- const url = args[0]?.toString() || ''
55
- if (url.includes('/api/chat') && !url.includes('warmup') && !url.includes('tts')) {
56
- const method = args[1]?.method || 'GET'
57
- const body = typeof args[1]?.body === 'string' ? args[1].body : ''
58
- if (method === 'POST') {
59
- window.__chatCapture.push({ type: 'request', body: body.substring(0, 200) })
60
- const resp = await orig(...args)
61
- const clone = resp.clone()
62
- const reader = clone.body?.getReader()
63
- if (reader) {
64
- let chunks = ''
65
- while (true) {
66
- const { done, value } = await reader.read()
67
- if (done) break
68
- chunks += new TextDecoder().decode(value)
69
- }
70
- window.__chatCapture.push({ type: 'stream', status: resp.status, body: chunks.substring(0, 800) })
71
- }
72
- return resp
73
- }
74
- }
75
- return orig(...args)
76
- }
77
- })
33
+ const argv = [join(HERE, 'chrome.mjs'), url]
34
+ if (sendMsg) argv.push('--send', sendMsg)
35
+ if (doScreenshot) argv.push('--screenshot', '/tmp/browser-check.png')
36
+ if (doNetwork) argv.push('--network')
78
37
 
79
- // Load page
80
- const res = await page.goto(urlArg, { waitUntil: 'load', timeout: 15000 }).catch(e => ({ status: () => 0, error: e.message }))
81
- const httpStatus = typeof res?.status === 'function' ? res.status() : 0
82
- await page.waitForTimeout(2500)
83
-
84
- const title = await page.title().catch(() => '(no title)')
85
- const chatRailBefore = await page.evaluate(() => document.querySelector('.chat-rail')?.innerText?.substring(0, 200) || null)
86
-
87
- // Send message if requested
88
- let chatRailAfter = null
89
- if (sendMsg) {
90
- const ta = await page.$('textarea')
91
- if (ta) {
92
- await ta.fill(sendMsg)
93
- await ta.press('Enter')
94
- await page.waitForTimeout(12000)
95
- chatRailAfter = await page.evaluate(() => document.querySelector('.chat-rail')?.innerText?.substring(0, 400) || null)
96
- }
38
+ const run = spawnSync(process.execPath, argv, { encoding: 'utf8', maxBuffer: 32 * 1024 * 1024 })
39
+ if (run.status !== 0) {
40
+ process.stderr.write(run.stderr || 'chrome.mjs failed\n')
41
+ process.exit(run.status ?? 1)
97
42
  }
98
43
 
99
- // Screenshot
100
- if (doScreenshot) {
101
- await page.screenshot({ path: '/tmp/browser-check.png', fullPage: false })
44
+ let r
45
+ try {
46
+ r = JSON.parse(run.stdout)
47
+ } catch {
48
+ process.stdout.write(run.stdout)
49
+ process.exit(0)
102
50
  }
103
51
 
104
- const chatCapture = await page.evaluate(() => window.__chatCapture || [])
105
-
106
- await browser.close()
107
-
108
- // Report
109
- const report = {
110
- url: urlArg,
111
- httpStatus,
112
- title,
113
- jsErrors,
114
- consoleErrors: consoleLogs.filter(l => l.type === 'error').map(l => l.text),
115
- chatRailBefore,
116
- chatRailAfter: sendMsg ? chatRailAfter : undefined,
117
- chatCapture: sendMsg ? chatCapture : undefined,
118
- apiRequests: doNetwork ? apiRequests : undefined,
52
+ console.log(JSON.stringify({
53
+ url: r.url,
54
+ httpStatus: r.httpStatus,
55
+ title: r.title ?? '(no title)',
56
+ jsErrors: r.jsErrors,
57
+ consoleErrors: r.consoleErrors,
58
+ chatRailBefore: r.chatRailBefore ?? null,
59
+ chatRailAfter: sendMsg ? (r.chatRailAfter ?? null) : undefined,
60
+ chatCapture: sendMsg ? (r.chatCapture ?? []) : undefined,
61
+ apiRequests: doNetwork ? (r.network ?? []).map((n) => ({ method: n.method, url: n.url })) : undefined,
119
62
  screenshot: doScreenshot ? '/tmp/browser-check.png' : undefined,
120
- }
121
-
122
- console.log(JSON.stringify(report, null, 2))
63
+ }, null, 2))
@@ -56,8 +56,6 @@ if ! _is_one_web "$API_URL"; then
56
56
  kill "$SELF_STARTED_PID" 2>/dev/null
57
57
  exit 2
58
58
  fi
59
- # do-tasks-bridge.py (wire 3, invoked below) reads this same env var independently —
60
- # without exporting it here it would still default to the wrong :4321.
61
59
  export ONE_API_URL="$API_URL"
62
60
  fi
63
61
 
@@ -124,18 +122,21 @@ if [ "$neg_ok" = "true" ]; then
124
122
  fi
125
123
  echo "[cc-events-proof] wire1 negative control ok — wrong key correctly rejected ($neg_resp)"
126
124
 
127
- # ── wire 3 — the tasks bridge sends ──────────────────────────────────────────
128
- send_out="$(python3 "$ROOT/.claude/scripts/do-tasks-bridge.py" --send 2>/dev/null)"
129
- send_count="$(printf '%s' "$send_out" | jq 'length' 2>/dev/null || echo 0)"
130
- send_matched_total="$(printf '%s' "$send_out" | jq '[.[] | .result.matched // 0] | add // 0' 2>/dev/null)"
131
- if [ "${send_count:-0}" -eq 0 ]; then
132
- echo "[cc-events-proof] wire3 tasks skipped local build queue is empty (not a failure)"
133
- wire3_ok=skip
134
- elif [ "${send_matched_total:-0}" -ge 1 ]; then
135
- echo "[cc-events-proof] wire3 tasks ok $send_count sent, matched_total=$send_matched_total"
125
+ # ── wire 3 — tasks:announce direct (shared-atom wire, text/tasks-do-plan.md C1/C8:
126
+ # tasks:create already fires tasks:announce in-process, so this proof calls the same
127
+ # receiver the create path calls instead of going through the deleted reconciler
128
+ # script) ───────────────────────────────────────────────────────────────────
129
+ tasks_payload="$(jq -nc --arg tid "task:${PROOF_SLUG}-$$" '{taskId:$tid,tags:["cc","session"],board:"marketplace"}')"
130
+ tasks_resp="$(curl -sS --max-time 5 -X POST "$API_URL/api/ask/tasks:announce" \
131
+ -H 'Content-Type: application/json' --config "$AUTHCFG" \
132
+ -H 'Cookie: signed_out=1' -d "{\"data\":$tasks_payload}")"
133
+ tasks_ok="$(printf '%s' "$tasks_resp" | jq -r '.result.ok // false' 2>/dev/null)"
134
+ tasks_matched="$(printf '%s' "$tasks_resp" | jq -r '.result.matched // 0' 2>/dev/null)"
135
+ echo "[cc-events-proof] wire3 tasks:announce ok=$tasks_ok matched=$tasks_matched"
136
+ if [ "$tasks_ok" = "true" ] && [ "${tasks_matched:-0}" -ge 1 ]; then
136
137
  wire3_ok=true
137
138
  else
138
- echo "[cc-events-proof] wire3 tasks FAIL — $send_count sent, matched_total=$send_matched_total"
139
+ echo "[cc-events-proof] wire3 tasks FAIL — $tasks_resp"
139
140
  wire3_ok=false
140
141
  fi
141
142