@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.
- package/agents/w1-recon.md +9 -4
- package/agents/w2-decide.md +51 -28
- package/agents/w3-edit.md +70 -78
- package/agents/w4-verify.md +164 -69
- package/commands/browser.md +98 -35
- package/commands/cc-connect.md +6 -0
- package/commands/chat.md +13 -1
- package/commands/close.md +45 -19
- package/commands/create.md +20 -10
- package/commands/db-sync.md +5 -1
- package/commands/deploy.md +174 -87
- package/commands/do-autonomous.md +31 -20
- package/commands/do-improve.md +4 -4
- package/commands/do-show.md +4 -3
- package/commands/do.md +53 -13
- package/commands/go.md +75 -0
- package/commands/improve.md +4 -2
- package/commands/kill.md +6 -8
- package/commands/notify.md +15 -2
- package/commands/oo-push.md +24 -9
- package/commands/rag.md +6 -0
- package/commands/release.md +46 -25
- package/commands/restart.md +5 -4
- package/commands/see.md +45 -35
- package/commands/skill-create.md +38 -5
- package/commands/sync.md +21 -11
- package/hooks/scripts/auto-continue.sh +70 -0
- package/hooks/scripts/branch-pin.sh +85 -0
- package/hooks/scripts/git-add-guard.sh +16 -5
- package/hooks/scripts/post-edit-check.sh +16 -0
- package/hooks/scripts/session-start.sh +13 -8
- package/hooks/scripts/sync-priority-todo.sh +5 -0
- package/package.json +1 -1
- package/rules/api.md +9 -0
- package/rules/design.md +13 -3
- package/rules/documentation.md +30 -71
- package/rules/engine.md +8 -1
- package/rules/ui.md +5 -1
- package/scripts/__pycache__/do-rank.cpython-313.pyc +0 -0
- package/scripts/browser-check.mjs +44 -103
- package/scripts/cc-events-proof.sh +13 -12
- package/scripts/chrome.mjs +381 -0
- package/scripts/do-analyze.sh +109 -4
- package/scripts/do-auto.sh +350 -43
- package/scripts/do-consumer-sweep.sh +72 -0
- package/scripts/do-derives-check.sh +88 -0
- package/scripts/do-fleet.sh +50 -1
- package/scripts/do-killswitch-audit.py +33 -14
- package/scripts/do-promise-lint.sh +150 -4
- package/scripts/do-promise-settle.sh +131 -9
- package/scripts/do-prove.sh +197 -17
- package/scripts/do-rank.py +606 -20
- package/scripts/do-rubric.py +21 -2
- package/scripts/do-signal.sh +157 -17
- package/scripts/do-smoke.sh +9 -0
- package/scripts/do-substrate-check.sh +49 -0
- package/scripts/do-tasks-wire-check.sh +81 -0
- package/scripts/do-tier.sh +90 -5
- package/scripts/do-ui-gate.sh +332 -0
- package/scripts/do-untracked-gate.sh +231 -0
- package/scripts/do-walk.sh +344 -0
- package/scripts/factory-check.sh +747 -0
- package/scripts/factory-repo.sh +1361 -0
- package/scripts/factory-tasks-check.sh +85 -0
- package/scripts/outcome-pull.ts +279 -0
- package/scripts/promise-manifest.mjs +167 -0
- package/scripts/reconcile-allow.txt +5 -0
- package/scripts/rubric-weights.json +64 -0
- package/scripts/spine-canary.sh +20 -0
- package/scripts/typedb-cluster-status.sh +128 -0
- package/scripts/typedb-env.sh +182 -0
- package/scripts/typedb-flap-recorder.sh +85 -0
- package/scripts/typedb-probes/containment-probe.py +88 -0
- package/scripts/typedb-probes/panic-probe-version.py +92 -0
- package/scripts/typedb-probes/panic-probe.py +77 -0
- package/scripts/typedb-scratch.sh +73 -0
- package/scripts/urls-lint.sh +58 -0
- package/scripts/w4-rubric.ts +96 -12
- package/scripts/wf-check.mjs +75 -0
- package/skills/ai-ui/SKILL.md +1 -1
- package/skills/astro/SKILL.md +177 -132
- package/skills/astro/add-content-collection.md +29 -13
- package/skills/astro/check-build.md +19 -13
- package/skills/astro/create-component.md +36 -9
- package/skills/astro/create-page.md +39 -10
- package/skills/astro/optimize-performance.md +36 -8
- package/skills/cli/SKILL.md +254 -220
- package/skills/dev/SKILL.md +1 -1
- package/skills/directory-autofill/SKILL.md +68 -0
- package/skills/docs/SKILL.md +4 -4
- package/skills/mcp/SKILL.md +186 -156
- package/skills/promise-make/SKILL.md +2 -2
- package/skills/puck/SKILL.md +465 -250
- package/skills/react19/SKILL.md +196 -296
- package/skills/reactflow/SKILL.md +387 -412
- package/skills/sdk/SKILL.md +167 -106
- package/skills/shadcn/SKILL.md +245 -201
- package/skills/signal/SKILL.md +5 -0
- package/skills/sui/SKILL.md +6 -1
- package/skills/tutorial/SKILL.md +15 -0
- package/skills/typedb/SKILL.md +427 -217
- package/skills/typedb/examples/python-patterns.py +11 -4
- package/skills/typedb/examples/query-patterns.tql +8 -3
- package/skills/typedb/examples/schema-patterns.tql +4 -2
- package/skills/typedb/reference/migration-2x-3x.md +19 -1
- package/skills/typedb/reference/python-driver.md +17 -1
- package/skills/voice/SKILL.md +117 -0
- package/skills/writer/SKILL.md +29 -12
- package/templates/template-feature.md +26 -1
- package/templates/template-tests.md +4 -0
- package/templates/template-todo.md +65 -10
package/skills/astro/SKILL.md
CHANGED
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: astro
|
|
3
|
-
description: Build Astro 6
|
|
3
|
+
description: Build pages, layouts and API routes in `one.ie/web` — Astro 6 + React 19 islands on Cloudflare Workers. Covers the real astro.config.mjs shape, adapter v13, SSR vs prerender, the `(await import('cloudflare:workers')).env` access pattern, and the LOCKED bundle-size rules. Use when editing `.astro` files, `astro.config.mjs`, or `src/pages/api/**`. For the `template/` tree use `template:astro` (Astro 7) instead.
|
|
4
4
|
user-invocable: true
|
|
5
5
|
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# Astro 6 on Cloudflare Workers
|
|
8
|
+
# Astro 6 on Cloudflare Workers — `one.ie/web`
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
**Which tree:** this skill describes `one.ie/web` only — Astro 6, single Cloudflare
|
|
11
|
+
adapter. `template/site` is a **different major** (Astro 7) with its own conventions;
|
|
12
|
+
use the `template:astro` skill there. Every claim below was checked against
|
|
13
|
+
`one.ie/web/astro.config.mjs` and `one.ie/web/package.json` on 2026-08-02.
|
|
14
|
+
|
|
15
|
+
Server-rendered pages with strategic React islands, on `@astrojs/cloudflare@13` +
|
|
16
|
+
Workers with Static Assets (the Pages era is retired).
|
|
11
17
|
|
|
12
18
|
## Stack
|
|
13
19
|
|
|
14
|
-
| Package |
|
|
20
|
+
| Package | Declared (2026-08-02) | Role |
|
|
15
21
|
|---|---|---|
|
|
16
|
-
| `astro` | `^6.
|
|
17
|
-
| `@astrojs/cloudflare` | `^13.1
|
|
18
|
-
| `@astrojs/react` | `^5.0.
|
|
19
|
-
| `@astrojs/node` | `^10.0.
|
|
20
|
-
| `wrangler` | `^4.
|
|
22
|
+
| `astro` | `^6.2.2` (6.3.7 installed) | Framework |
|
|
23
|
+
| `@astrojs/cloudflare` | `^13.3.1` | Workers adapter (no longer supports Pages) |
|
|
24
|
+
| `@astrojs/react` | `^5.0.4` | React 19 islands |
|
|
25
|
+
| `@astrojs/node` | `^10.0.6` | Declared but **unused** — not imported by `astro.config.mjs` |
|
|
26
|
+
| `wrangler` | `^4.14.0` | Workers CLI |
|
|
27
|
+
|
|
28
|
+
`@astrojs/node` is a leftover dependency. There is no dev/prod adapter swap in this
|
|
29
|
+
tree — don't add one back on the strength of the package being present.
|
|
21
30
|
|
|
22
31
|
## Works With
|
|
23
32
|
|
|
@@ -25,54 +34,51 @@ Server-rendered pages with strategic React islands, running on `@astrojs/cloudfl
|
|
|
25
34
|
|------------|---------------------------------------------------------------------------------------|
|
|
26
35
|
| `/react19` | React components inside islands — pick `client:load` / `client:visible` / `client:only`. |
|
|
27
36
|
| `/cloudflare` | `wrangler.toml`, `[assets]` binding, secrets, `wrangler tail`, Workers+Assets semantics. |
|
|
28
|
-
| `/deploy` | 8-step `bun run deploy` pipeline — Astro build is step 3; bundle-size rules live here. |
|
|
29
37
|
| `/signal` | `src/pages/api/*.ts` — every API route is the substrate's HTTP surface. |
|
|
30
38
|
| `/shadcn` | shadcn components live inside islands; dark-theme tokens + hydration strategy. |
|
|
31
|
-
| `/sui` | SSR pages reading on-chain data — use `client:only="react"` to keep worker
|
|
32
|
-
| `/typedb` | SSR data fetching —
|
|
39
|
+
| `/sui` | SSR pages reading on-chain data — use `client:only="react"` to keep the worker small. |
|
|
40
|
+
| `/typedb` | SSR data fetching — pages call `typedbQuery()` from `src/lib/substrate.ts`. |
|
|
33
41
|
|
|
34
|
-
Auto-loads on `*.astro`: `.claude/rules/astro.md`.
|
|
42
|
+
Auto-loads on `*.astro`: `.claude/rules/astro.md`. The deploy pipeline (8 steps,
|
|
43
|
+
Astro build is step 3) is the `/deploy` **command**, not a skill:
|
|
44
|
+
`.claude/commands/deploy.md`.
|
|
35
45
|
|
|
36
|
-
##
|
|
46
|
+
## The Config (the ONE shape)
|
|
37
47
|
|
|
38
|
-
`astro.config.mjs`
|
|
48
|
+
One adapter, always Cloudflare. `astro.config.mjs` is ~200 lines — three Vite plugins,
|
|
49
|
+
a large `optimizeDeps` block, and a Durable-Object export plugin. **Read the file for
|
|
50
|
+
the rest; the load-bearing shape is:**
|
|
39
51
|
|
|
40
52
|
```js
|
|
41
|
-
// astro.config.mjs — the
|
|
42
|
-
import react from "@astrojs/react";
|
|
43
|
-
import cloudflare from "@astrojs/cloudflare";
|
|
44
|
-
import node from "@astrojs/node";
|
|
45
|
-
import tailwindcss from "@tailwindcss/vite";
|
|
46
|
-
import { defineConfig } from "astro/config";
|
|
47
|
-
|
|
48
|
-
const isDev = process.env.NODE_ENV !== "production";
|
|
49
|
-
const adapter = isDev
|
|
50
|
-
? node({ mode: "standalone" })
|
|
51
|
-
: cloudflare({ platformProxy: { enabled: true } });
|
|
52
|
-
|
|
53
|
+
// astro.config.mjs — the parts this skill's rules depend on
|
|
53
54
|
export default defineConfig({
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// ...tailwind, aliases, chunks
|
|
71
|
-
},
|
|
72
|
-
});
|
|
55
|
+
output: 'server', // all routes SSR unless prerender=true
|
|
56
|
+
adapter: cloudflare({
|
|
57
|
+
prerenderEnvironment: 'node', // prerender under node, not workerd
|
|
58
|
+
imageService: 'passthrough',
|
|
59
|
+
sessions: false,
|
|
60
|
+
remoteBindings: false,
|
|
61
|
+
// NOT { enabled: true } — loading [env.production] during build sync
|
|
62
|
+
// makes Miniflare evaluate the DO before the export plugin runs
|
|
63
|
+
platformProxy: { environment: undefined },
|
|
64
|
+
}),
|
|
65
|
+
integrations: [react(), devWarmupIntegration()],
|
|
66
|
+
build: { inlineStylesheets: 'auto' }, // LOCKED — never 'always'
|
|
67
|
+
markdown: { syntaxHighlight: false }, // LOCKED — keeps Shiki out of the worker
|
|
68
|
+
security: { checkOrigin: false },
|
|
69
|
+
vite: { /* ssr.external, ssr.noExternal, optimizeDeps, plugins — see the file */ },
|
|
70
|
+
})
|
|
73
71
|
```
|
|
74
72
|
|
|
75
|
-
**
|
|
73
|
+
**Don't copy a `vite.ssr` list out of this skill.** `astro.config.mjs` §
|
|
74
|
+
`vite.ssr.external` is the authority (`.claude/commands/deploy.md` Rule 2 says so
|
|
75
|
+
explicitly: *never reconcile that file to a doc*). Note the direction — `recharts`,
|
|
76
|
+
Stripe, `@xyflow/react`, `motion`, `media-chrome` and the 100ms packages are
|
|
77
|
+
**external**; `react`, `react-dom`, `@astrojs/react`, `better-auth` and `kysely` are
|
|
78
|
+
**noExternal**. Getting that backwards breaks the build.
|
|
79
|
+
|
|
80
|
+
A companion `ssrExternalPlugin()` also swaps three packages for tiny SSR stubs
|
|
81
|
+
(`pusher-js`, `media-chrome/react`, `@mux/mux-player-react` → `src/lib/stubs/`).
|
|
76
82
|
|
|
77
83
|
## Adapter v13 — What Changed from Astro 5/v12
|
|
78
84
|
|
|
@@ -80,14 +86,16 @@ export default defineConfig({
|
|
|
80
86
|
|---|---|---|---|
|
|
81
87
|
| Pages support | ✓ | **removed** | Deploy target is Workers + Static Assets only |
|
|
82
88
|
| `output: "hybrid"` | ✓ | **removed** | Use `"server"` + `prerender = true` per-page, or `"static"` + `prerender = false` |
|
|
83
|
-
| `Astro.locals.runtime` | populated | **removed** | `
|
|
84
|
-
| `prerenderEnvironment` | n/a | `workerd` default |
|
|
85
|
-
| `imageService` default | `"compile"` | `"cloudflare-binding"` |
|
|
86
|
-
| `sessionKVBindingName` | n/a | default `"SESSION"` |
|
|
87
|
-
| `workerEntryPoint` | option | **removed** | Adapter emits `dist/
|
|
89
|
+
| `Astro.locals.runtime` | populated | **removed** | Use `cloudflare:workers` (see below) |
|
|
90
|
+
| `prerenderEnvironment` | n/a | `workerd` default | ONE sets `'node'` — prerender breaks under workerd here |
|
|
91
|
+
| `imageService` default | `"compile"` | `"cloudflare-binding"` | ONE overrides to `'passthrough'` — no IMAGES binding needed |
|
|
92
|
+
| `sessionKVBindingName` | n/a | default `"SESSION"` | ONE sets `sessions: false`; the `SESSION` KV is used directly |
|
|
93
|
+
| `workerEntryPoint` | option | **removed** | Adapter emits the bundled entry; `dist/server/wrangler.json` injects it |
|
|
88
94
|
| `cloudflareModules` | option | **removed** | Use Vite's built-in WASM/text imports |
|
|
89
95
|
|
|
90
|
-
**Migration memory
|
|
96
|
+
**Migration memory:** check adapter + deploy-target compatibility BEFORE bumping
|
|
97
|
+
Astro major. Astro 6's `@astrojs/cloudflare@13` dropped Pages in a single minor jump;
|
|
98
|
+
~8-commit cascade to fix.
|
|
91
99
|
|
|
92
100
|
## Output Modes (Astro 6)
|
|
93
101
|
|
|
@@ -103,39 +111,47 @@ export const prerender = false // force SSR — runs in worker
|
|
|
103
111
|
| `"server"` | SSR | ONE's choice — most routes are dynamic; static pages opt in |
|
|
104
112
|
| `"hybrid"` | — | **removed** in Astro 6; use `"server"` + per-page `prerender = true` |
|
|
105
113
|
|
|
106
|
-
**ONE's rule:** `output: "server"`. Static shell pages export `prerender = true` AND
|
|
114
|
+
**ONE's rule:** `output: "server"`. Static shell pages export `prerender = true` AND
|
|
115
|
+
load heavy islands with `client:only="react"`, so the worker ships no React for them.
|
|
116
|
+
Current split in `src/pages`: 53 files `prerender = true`, 601 `prerender = false`.
|
|
107
117
|
|
|
108
118
|
## cloudflare:workers — The Canonical Env Import
|
|
109
119
|
|
|
120
|
+
**Always the dynamic form.** A top-level `import { env } from "cloudflare:workers"`
|
|
121
|
+
is not used anywhere in this tree (0 files under `src/`); the dynamic import is (407 files). The
|
|
122
|
+
static import resolves at module-eval time, which breaks prerender and any non-worker
|
|
123
|
+
context that touches the module.
|
|
124
|
+
|
|
110
125
|
```ts
|
|
111
126
|
// src/pages/api/whatever.ts (SSR API route)
|
|
112
|
-
import {
|
|
127
|
+
import type { APIRoute } from "astro";
|
|
113
128
|
|
|
114
|
-
|
|
115
|
-
|
|
129
|
+
type Env = { DB?: D1Database; SESSION?: KVNamespace }
|
|
130
|
+
|
|
131
|
+
async function getEnv(): Promise<Env> {
|
|
132
|
+
return (await import('cloudflare:workers' as string)).env as Env
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export const GET: APIRoute = async () => {
|
|
136
|
+
const env = await getEnv()
|
|
137
|
+
if (!env.DB) return Response.json({ error: 'no_db' }, { status: 503 })
|
|
116
138
|
const { results } = await env.DB.prepare("SELECT * FROM signals LIMIT 10").all();
|
|
117
|
-
return Response.json({
|
|
139
|
+
return Response.json({ signals: results });
|
|
118
140
|
};
|
|
119
141
|
```
|
|
120
142
|
|
|
121
|
-
**Typing
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
```jsonc
|
|
129
|
-
// package.json scripts
|
|
130
|
-
{
|
|
131
|
-
"dev": "wrangler types && astro dev",
|
|
132
|
-
"build": "wrangler types && astro build"
|
|
133
|
-
}
|
|
134
|
-
```
|
|
143
|
+
**Typing.** There is no `worker-configuration.d.ts` in this tree and `wrangler types`
|
|
144
|
+
is not wired into any script. Bindings are typed by hand in `src/env.d.ts` — the
|
|
145
|
+
`Runtime` interface lists every binding (`DB`, `CONTENT`, `SESSION`, `CHAT_CACHE`,
|
|
146
|
+
`ANALYTICS_HUB`, `WORKFLOW_RUN`, …) alongside `App.Locals`. Add a new binding there
|
|
147
|
+
when you add it to `wrangler.toml`. Routes that declare a narrow local `Env` type (as
|
|
148
|
+
above) are the prevailing pattern.
|
|
135
149
|
|
|
136
150
|
### Legacy `Astro.locals.runtime.env` (compat shim)
|
|
137
151
|
|
|
138
|
-
|
|
152
|
+
`src/env.d.ts` still declares `runtime?: Runtime` on `App.Locals`, and 7 files read
|
|
153
|
+
`locals?.runtime?.env?.*` from the Astro 5 era. **New code uses the dynamic
|
|
154
|
+
`cloudflare:workers` import** — it survives the shim's removal.
|
|
139
155
|
|
|
140
156
|
## Hydration Directives (unchanged in Astro 6)
|
|
141
157
|
|
|
@@ -147,7 +163,11 @@ client:only="react" → Client-only, skip SSR entirely (heavy deps, keeps worker
|
|
|
147
163
|
client:media="(min-width: 768px)" → Hydrate on media query match
|
|
148
164
|
```
|
|
149
165
|
|
|
150
|
-
**Bundle rule (LOCKED
|
|
166
|
+
**Bundle rule (LOCKED):** heavy components (shiki, recharts, Stripe, 100ms, Puck)
|
|
167
|
+
MUST be `client:only="react"` OR listed in `vite.ssr.external`. Both together is the
|
|
168
|
+
common case — `ssr.external` is only safe when the package never executes on the
|
|
169
|
+
server path, and `client:only` is what guarantees that. 216 `client:only="react"`
|
|
170
|
+
uses across pages and components today.
|
|
151
171
|
|
|
152
172
|
## Page Patterns
|
|
153
173
|
|
|
@@ -172,9 +192,9 @@ export const prerender = true;
|
|
|
172
192
|
// src/pages/dashboard.astro
|
|
173
193
|
import Layout from "@/layouts/Layout.astro";
|
|
174
194
|
import Dashboard from "@/components/Dashboard";
|
|
175
|
-
import { env } from "cloudflare:workers";
|
|
176
195
|
|
|
177
|
-
const
|
|
196
|
+
const { env } = await import('cloudflare:workers' as string);
|
|
197
|
+
const paths = (await env.CHAT_CACHE?.get("paths.json", "json")) ?? [];
|
|
178
198
|
---
|
|
179
199
|
<Layout title="Dashboard">
|
|
180
200
|
<Dashboard client:load paths={paths} />
|
|
@@ -186,65 +206,78 @@ const paths = await env.KV.get("paths.json", "json") ?? [];
|
|
|
186
206
|
```ts
|
|
187
207
|
// src/pages/api/signal.ts
|
|
188
208
|
import type { APIRoute } from "astro";
|
|
189
|
-
|
|
209
|
+
|
|
210
|
+
export const prerender = false
|
|
190
211
|
|
|
191
212
|
export const POST: APIRoute = async ({ request }) => {
|
|
213
|
+
const { env } = await import('cloudflare:workers' as string);
|
|
192
214
|
const signal = await request.json();
|
|
193
|
-
await env.
|
|
215
|
+
await env.CHAT_CACHE.put(`signal:${Date.now()}`, JSON.stringify(signal));
|
|
194
216
|
return Response.json({ received: true });
|
|
195
217
|
};
|
|
196
218
|
```
|
|
197
219
|
|
|
198
220
|
## Bundle-Size Rules (LOCKED — do not revert)
|
|
199
221
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
222
|
+
Wrangler reports both `Total Upload` (uncompressed) and `gzip` — only gzip counts.
|
|
223
|
+
The documented ceiling is **3 MiB gzipped** free tier / 10 MiB paid, but this
|
|
224
|
+
account's real ceiling is **unconfirmed**: deploys at 3.22 MiB (2026-07-08) and
|
|
225
|
+
4.43 MiB (2026-07-19) both succeeded. Treat the current number as a floor to watch,
|
|
226
|
+
not a hard gate, and re-run the diagnosis if it keeps climbing.
|
|
227
|
+
`.claude/commands/deploy.md § Bundle Size Rules` + § Verified Bundle Numbers is the
|
|
228
|
+
authority — reconcile to it, not to this table.
|
|
203
229
|
|
|
204
230
|
| Rule | Where | Saves |
|
|
205
231
|
|---|---|---|
|
|
206
232
|
| `markdown: { syntaxHighlight: false }` | `astro.config.mjs` | ~5.8 MiB (Shiki grammars/WASM) |
|
|
207
|
-
| `ssr.external
|
|
208
|
-
| `prerender = true` + `client:only="react"` on shell pages | per-page |
|
|
209
|
-
| `build: { inlineStylesheets: 'auto' }` — **NEVER `'always'`** | `astro.config.mjs` | ~8 MiB at 100+ routes. `'always'` inlines the full Tailwind stylesheet into every route's manifest entry
|
|
233
|
+
| `vite.ssr.external` for heavy packages | `astro.config.mjs` | Bare imports — safe only if the package never runs server-side (shiki's callers are all `client:only`) |
|
|
234
|
+
| `prerender = true` + `client:only="react"` on shell pages | per-page | Page handler collapses to a stub; no React in the worker |
|
|
235
|
+
| `build: { inlineStylesheets: 'auto' }` — **NEVER `'always'`** | `astro.config.mjs` | ~8 MiB at 100+ routes. `'always'` inlines the full Tailwind stylesheet into every route's manifest entry. `'auto'` ships one external `<link>`. |
|
|
236
|
+
| `react-dom/server` → `react-dom/server.edge` alias, production only | `astro.config.mjs` `vite.resolve.alias` | Ships the edge build instead of the Node build |
|
|
210
237
|
|
|
211
238
|
Verified deltas:
|
|
212
239
|
- 2026-04-15: 21 MiB Pages → 9.5 MiB Worker (Rules 1-3). Pages deploy FAILED → Workers ✓.
|
|
213
|
-
- 2026-05-22: worker-entry 9.5 MiB → 672 KiB (Rule 4). gzip 3.3 MiB → 2.1 MiB.
|
|
240
|
+
- 2026-05-22: worker-entry 9.5 MiB → 672 KiB (Rule 4). gzip 3.3 MiB → 2.1 MiB.
|
|
214
241
|
|
|
215
242
|
## Dev Commands
|
|
216
243
|
|
|
217
244
|
```bash
|
|
218
|
-
bun run dev # localhost:4321
|
|
219
|
-
bun run build # astro build
|
|
220
|
-
bun run preview # wrangler dev
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
bun
|
|
224
|
-
bun
|
|
225
|
-
|
|
226
|
-
#
|
|
227
|
-
bun wrangler
|
|
228
|
-
astro check # tsc on .astro files + tsconfig
|
|
245
|
+
bun run dev # localhost:4321 — regenerates playbook meta + promises, then astro dev
|
|
246
|
+
bun run build # builds @oneie/sdk, astro build, patches dist/server/wrangler.json
|
|
247
|
+
bun run preview # astro preview (NOT wrangler — see dev:wrangler for production shape)
|
|
248
|
+
bun run dev:wrangler # build + wrangler dev against dist/server/wrangler.json on :8787
|
|
249
|
+
bun run check # astro check
|
|
250
|
+
bun run typecheck # tsc --noEmit
|
|
251
|
+
bun run verify # build SDK + typecheck + vitest — the gate
|
|
252
|
+
|
|
253
|
+
# Bindings against real CF resources
|
|
254
|
+
bun wrangler dev --remote # production KV/D1 — use with care
|
|
229
255
|
```
|
|
230
256
|
|
|
257
|
+
There is no `wrangler types` step. Bindings are hand-typed in `src/env.d.ts`.
|
|
258
|
+
|
|
231
259
|
## Dynamic Routes
|
|
232
260
|
|
|
261
|
+
Real routes in this tree:
|
|
262
|
+
|
|
233
263
|
```
|
|
234
264
|
src/pages/
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
265
|
+
p/[slug].astro → /p/my-landing-page
|
|
266
|
+
studio/[agent].astro → /studio/donal
|
|
267
|
+
u/[slug]/[...path].astro → catch-all under a workspace
|
|
268
|
+
go/[id].ts → a dynamic API-shaped route (.ts, not .astro)
|
|
269
|
+
tasks/[...view].astro → catch-all
|
|
238
270
|
```
|
|
239
271
|
|
|
240
272
|
```astro
|
|
241
273
|
---
|
|
242
|
-
// src/pages/
|
|
243
|
-
const
|
|
244
|
-
|
|
274
|
+
// src/pages/studio/[agent].astro
|
|
275
|
+
export const prerender = false
|
|
276
|
+
const { agent } = Astro.params;
|
|
277
|
+
if (!agent) return new Response(null, { status: 404 });
|
|
245
278
|
---
|
|
246
|
-
<Layout title={`
|
|
247
|
-
<AgentCard client:load agentId={
|
|
279
|
+
<Layout title={`Studio: ${agent}`}>
|
|
280
|
+
<AgentCard client:load agentId={agent} />
|
|
248
281
|
</Layout>
|
|
249
282
|
```
|
|
250
283
|
|
|
@@ -256,68 +289,80 @@ if (!id) return new Response(null, { status: 404 });
|
|
|
256
289
|
| API routes | `src/pages/api/**/*.ts` |
|
|
257
290
|
| Layouts | `src/layouts/*.astro` |
|
|
258
291
|
| React islands | `src/components/**/*.tsx` |
|
|
259
|
-
|
|
|
292
|
+
| Content collections | `src/content.config.ts` + `src/content/` |
|
|
260
293
|
| Astro config | `astro.config.mjs` |
|
|
261
|
-
| Worker config | `wrangler.toml` |
|
|
262
|
-
| Locals types | `src/env.d.ts` |
|
|
294
|
+
| Worker config | `wrangler.toml` (`main` intentionally omitted) |
|
|
295
|
+
| Binding + Locals types | `src/env.d.ts` |
|
|
263
296
|
|
|
264
297
|
## Performance Budgets (from `text/speed.md`)
|
|
265
298
|
|
|
266
|
-
| Metric |
|
|
299
|
+
| Metric | Measured |
|
|
267
300
|
|---|---|
|
|
268
|
-
| Routing (in-memory) | <0.005ms |
|
|
269
|
-
|
|
|
270
|
-
|
|
|
271
|
-
|
|
|
301
|
+
| Routing decision (in-memory) | <0.005ms (320 tests) |
|
|
302
|
+
| KV read / highway cache (edge) | <10ms |
|
|
303
|
+
| `ask()` round-trip (no LLM) | 50–200ms |
|
|
304
|
+
| Chat TTFB p50 (browser) | ~97ms — gate ≤100ms |
|
|
305
|
+
| Agent first SSE token (end-to-end) | ~500ms |
|
|
272
306
|
|
|
273
|
-
Static pages served from `[assets]` binding don't count against request quota —
|
|
307
|
+
Static pages served from the `[assets]` binding don't count against request quota —
|
|
308
|
+
pre-render anything that doesn't need SSR.
|
|
274
309
|
|
|
275
310
|
## Common Tasks
|
|
276
311
|
|
|
312
|
+
Five sub-workflows live beside this file: `create-page.md`, `create-component.md`,
|
|
313
|
+
`add-content-collection.md`, `check-build.md`, `optimize-performance.md`.
|
|
314
|
+
|
|
277
315
|
### Add a new page
|
|
278
316
|
|
|
279
|
-
1. Create `src/pages/<name>.astro` with Layout import
|
|
317
|
+
1. Create `src/pages/<name>.astro` with a Layout import
|
|
280
318
|
2. If mostly static → `export const prerender = true`
|
|
281
|
-
3. If needs CF bindings → `import
|
|
282
|
-
4. React islands: default to `client:visible`;
|
|
319
|
+
3. If it needs CF bindings → `await import('cloudflare:workers')` in frontmatter
|
|
320
|
+
4. React islands: default to `client:visible`; `client:load` only for above-fold critical UI
|
|
283
321
|
|
|
284
322
|
### Add an API route
|
|
285
323
|
|
|
286
|
-
1. Create `src/pages/api/<name>.ts`
|
|
324
|
+
1. Create `src/pages/api/<name>.ts`, `export const prerender = false`
|
|
287
325
|
2. Export `GET` / `POST` / `PUT` / `DELETE` as `APIRoute`
|
|
288
|
-
3. Read bindings via `import
|
|
289
|
-
4.
|
|
326
|
+
3. Read bindings via `(await import('cloudflare:workers')).env`
|
|
327
|
+
4. Authorize before touching workspace data (`authorizeWorkspace` from `@/lib/analytics/authz`)
|
|
328
|
+
5. Return `Response.json(...)` or `new Response(...)`
|
|
290
329
|
|
|
291
330
|
### Convert static component to interactive
|
|
292
331
|
|
|
293
332
|
1. Create `.tsx` in `src/components/`
|
|
294
|
-
2. Import into `.astro` page
|
|
333
|
+
2. Import into the `.astro` page
|
|
295
334
|
3. Pick directive: above-fold → `client:load`, below-fold → `client:visible`, heavy → `client:only="react"`
|
|
296
335
|
|
|
297
336
|
### Type a new binding
|
|
298
337
|
|
|
299
|
-
1. Add binding to `wrangler.toml` (`[[kv_namespaces]]`, `[[d1_databases]]`, etc.)
|
|
300
|
-
2.
|
|
301
|
-
3. `
|
|
338
|
+
1. Add the binding to `wrangler.toml` (`[[kv_namespaces]]`, `[[d1_databases]]`, etc.)
|
|
339
|
+
2. Add the field to the `Runtime.env` interface in `src/env.d.ts` (by hand — no codegen)
|
|
340
|
+
3. Narrow it in the route's local `Env` type where you read it
|
|
302
341
|
|
|
303
342
|
## Gotchas
|
|
304
343
|
|
|
305
|
-
- **Dev
|
|
306
|
-
|
|
344
|
+
- **Dev and prod both run the Cloudflare adapter**, but dev goes through Vite +
|
|
345
|
+
Miniflare. Behaviour still diverges — `bun run dev:wrangler` for a production-shape smoke.
|
|
346
|
+
- **A top-level `import { env } from "cloudflare:workers"` breaks prerender.** Always
|
|
347
|
+
the dynamic form. Zero files in this tree use the static one.
|
|
348
|
+
- **`import.meta.env.*`** is build-time only. Runtime secrets/bindings come from `env`.
|
|
307
349
|
- **Shiki will crash your deploy** if imported from SSR. All callers must be `client:only="react"`.
|
|
308
|
-
- **`output: "hybrid"`** throws in Astro 6.
|
|
309
|
-
-
|
|
310
|
-
|
|
350
|
+
- **`output: "hybrid"`** throws in Astro 6. Replace with `"server"` + per-page `prerender = true`.
|
|
351
|
+
- **Never delete a `vite.ssr.external` entry to match a doc snippet** — the config file is
|
|
352
|
+
the authority and the list is longer than any snippet.
|
|
353
|
+
- **`platformProxy: { enabled: true }`** is wrong here. This tree uses
|
|
354
|
+
`{ environment: undefined }` so `astro build` doesn't make Miniflare evaluate the
|
|
355
|
+
Durable Object before `durableObjectExportsPlugin` has run.
|
|
311
356
|
|
|
312
357
|
## References
|
|
313
358
|
|
|
314
359
|
- [Astro Cloudflare adapter](https://docs.astro.build/en/guides/integrations-guide/cloudflare/) — authoritative for v13
|
|
315
360
|
- [CF Workers framework guide — Astro](https://developers.cloudflare.com/workers/frameworks/framework-guides/astro/)
|
|
316
|
-
-
|
|
317
|
-
- `docs/deploy.md` — bundle-size diagnosis + LOCKED rules
|
|
361
|
+
- `.claude/commands/deploy.md` — 8-step pipeline, 5 LOCKED bundle rules, verified bundle numbers, rollback
|
|
318
362
|
- `.claude/rules/astro.md` — auto-loaded on `*.astro` edits
|
|
363
|
+
- `one.ie/web/astro.config.mjs` — the authority for adapter options and every `vite.ssr` list
|
|
319
364
|
|
|
320
365
|
---
|
|
321
366
|
|
|
322
|
-
**Version**:
|
|
323
|
-
**Previous**:
|
|
367
|
+
**Version**: 3.0.0 — reconciled against `one.ie/web` (2026-08-02)
|
|
368
|
+
**Previous**: 2.0.0 (2026-04-18, described a dual-adapter config this tree never had)
|
|
@@ -1,30 +1,46 @@
|
|
|
1
1
|
# Add Content Collection
|
|
2
2
|
|
|
3
3
|
**Category:** astro
|
|
4
|
-
**Version:**
|
|
5
|
-
**Used By:**
|
|
4
|
+
**Version:** 2.0.0
|
|
5
|
+
**Used By:** `astro` skill · `/do` W3 edit wave
|
|
6
6
|
|
|
7
7
|
## Purpose
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Adds a collection to `one.ie/web/src/content.config.ts`. This tree is on the Astro
|
|
10
|
+
Content Layer — every collection declares a **`loader`**; the legacy `type: 'content'`
|
|
11
|
+
shape is gone. Five collections exist today: `videos`, `playbook`, `moversPlaybook`,
|
|
12
|
+
`legal`, `blog`.
|
|
10
13
|
|
|
11
14
|
## Example
|
|
12
15
|
|
|
13
16
|
```typescript
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
// src/content.config.ts
|
|
18
|
+
import { defineCollection, z } from "astro:content";
|
|
19
|
+
import { glob } from "astro/loaders";
|
|
20
|
+
|
|
21
|
+
const GuideSchema = z.object({
|
|
22
|
+
title: z.string(),
|
|
23
|
+
order: z.number().default(0),
|
|
24
|
+
publishedAt: z.coerce.date(), // coerce — frontmatter dates arrive as strings
|
|
25
|
+
tags: z.array(z.string()).default([]),
|
|
26
|
+
draft: z.boolean().default(false),
|
|
23
27
|
});
|
|
24
28
|
|
|
25
|
-
|
|
29
|
+
const guides = defineCollection({
|
|
30
|
+
loader: glob({ pattern: "**/*.md", base: "./src/content/guides" }),
|
|
31
|
+
schema: GuideSchema,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Append to the single exported object — do not add a second export.
|
|
35
|
+
export const collections = { videos, playbook, moversPlaybook, legal, blog, guides };
|
|
26
36
|
```
|
|
27
37
|
|
|
38
|
+
Then create `src/content/guides/` and put the markdown in it. Read it with
|
|
39
|
+
`getCollection('guides')`; filter `draft` yourself — the schema defaults it, it
|
|
40
|
+
doesn't exclude it.
|
|
41
|
+
|
|
28
42
|
## Version History
|
|
29
43
|
|
|
44
|
+
- **2.0.0** (2026-08-02): Rewritten for the Content Layer `loader` API and the real
|
|
45
|
+
`content.config.ts`. The 1.0.0 example used the pre-Astro-5 shape with no loader.
|
|
30
46
|
- **1.0.0** (2025-10-18): Initial implementation
|
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
# Check Astro Build
|
|
2
2
|
|
|
3
3
|
**Category:** astro
|
|
4
|
-
**Version:**
|
|
5
|
-
**Used By:**
|
|
4
|
+
**Version:** 2.0.0
|
|
5
|
+
**Used By:** `astro` skill · `/do` W4 verify wave
|
|
6
6
|
|
|
7
7
|
## Purpose
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Verify `one.ie/web` compiles before shipping. `astro check` emits **human-readable
|
|
10
|
+
text, not JSON** — parse the exit code, not the stdout.
|
|
10
11
|
|
|
11
12
|
## Example
|
|
12
13
|
|
|
13
14
|
```bash
|
|
14
|
-
|
|
15
|
-
```
|
|
15
|
+
cd one.ie/web
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"errors": 0,
|
|
22
|
-
"warnings": 0,
|
|
23
|
-
"files": 252
|
|
24
|
-
}
|
|
17
|
+
bun run verify # THE gate: builds @oneie/sdk, then tsc --noEmit, then vitest run
|
|
18
|
+
bun run check # astro check — types inside .astro templates
|
|
19
|
+
bun run typecheck # tsc --noEmit only (fastest signal on .ts/.tsx)
|
|
20
|
+
bun run build # full production build; the only thing that catches bundler breaks
|
|
25
21
|
```
|
|
26
22
|
|
|
23
|
+
`astro check` prints a summary line of the form
|
|
24
|
+
`Result (N files): X errors, Y warnings, Z hints` and exits non-zero on errors.
|
|
25
|
+
|
|
26
|
+
**Build the SDK first.** `bun run typecheck` on its own reports phantom `TS2307`
|
|
27
|
+
module-not-found errors when `packages/sdk/dist` is stale or missing — `bun run verify`
|
|
28
|
+
already does the SDK build, which is why it is the gate. In a `/do` worktree also
|
|
29
|
+
confirm `node_modules` is present; a partial install fakes a ratchet violation.
|
|
30
|
+
|
|
27
31
|
## Version History
|
|
28
32
|
|
|
33
|
+
- **2.0.0** (2026-08-02): Replaced the invented JSON output with the real commands and
|
|
34
|
+
exit-code contract; added the build-SDK-first trap.
|
|
29
35
|
- **1.0.0** (2025-10-18): Initial implementation
|