create-ailk 0.19.1 → 0.21.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/README.md +84 -7
- package/component-catalog.json +184 -6
- package/component-catalog.md +20 -9
- package/dist/apply-design.d.ts +9 -0
- package/dist/apply-design.js +78 -31
- package/dist/cli.js +35 -0
- package/dist/copy.d.ts +41 -0
- package/dist/copy.js +87 -21
- package/dist/design-home.d.ts +54 -11
- package/dist/design-home.js +160 -22
- package/dist/lib/design-checks.d.ts +6 -1
- package/dist/lib/design-checks.js +23 -2
- package/dist/lib/fetch-template-snapshot.d.ts +21 -0
- package/dist/lib/fetch-template-snapshot.js +205 -0
- package/dist/lib/merge-three-way.d.ts +31 -0
- package/dist/lib/merge-three-way.js +65 -0
- package/dist/module-architecture.js +55 -2
- package/dist/programmatic.d.ts +7 -1
- package/dist/programmatic.js +76 -22
- package/dist/site-roster.d.ts +4 -2
- package/dist/site-roster.js +7 -5
- package/dist/spoke-checkout.d.ts +7 -0
- package/dist/spoke-checkout.js +8 -1
- package/dist/starter-grid.js +16 -0
- package/dist/surfaces.js +78 -2
- package/dist/sync-routes.d.ts +28 -0
- package/dist/sync-routes.js +123 -1
- package/dist/template-record.d.ts +59 -0
- package/dist/template-record.js +183 -0
- package/dist/update.d.ts +53 -0
- package/dist/update.js +606 -0
- package/package.json +3 -3
- package/site-templates/_base/ailk-template.json +2 -2
- package/site-templates/_base/content/en/WorkingAgreementPage/working-agreement.mdx +78 -0
- package/site-templates/designs/minimalism/DESIGN.md +1 -1
- package/site-templates/designs/minimalism/contact/local-business-service.mdx +23 -0
- package/site-templates/designs/minimalism/contact/organization-product.mdx +23 -0
- package/site-templates/designs/minimalism/contact/organization-service.mdx +23 -0
- package/site-templates/designs/minimalism/contact/person-service.mdx +23 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +11 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +34 -23
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +33 -23
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +33 -23
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +18 -1
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +31 -21
- package/templates/.claude/cloudparity-repo-hooks.json +9 -0
- package/templates/.claude/hooks/architecture-check.sh +8 -0
- package/templates/.claude/rules/loop-contract.md +129 -0
- package/templates/.claude/settings.json +3 -2
- package/templates/.env.example +13 -0
- package/templates/CLAUDE.md +1 -1
- package/templates/CONVENTIONS.md +3 -2
- package/templates/README.md +26 -25
- package/templates/_gitignore +162 -0
- package/templates/apps/api/CLAUDE.md +18 -10
- package/templates/apps/api/jest.config.cjs +1 -0
- package/templates/apps/api/package.json +2 -1
- package/templates/apps/api/src/__tests__/factories/in-memory-prisma.ts +22 -2
- package/templates/apps/api/src/__tests__/setup.ts +7 -0
- package/templates/apps/api/src/bin/__tests__/rate-limit-probe.test.ts +184 -0
- package/templates/apps/api/src/bin/rate-limit-probe.ts +53 -0
- package/templates/apps/api/src/lib/proposal-paid-store.ts +49 -0
- package/templates/apps/api/src/lib/rate-limit-probe.ts +165 -0
- package/templates/apps/api/src/lib/rate-limit-store.ts +142 -0
- package/templates/apps/api/src/middleware/__tests__/auth.hub-session-path.test.ts +5 -2
- package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +2 -0
- package/templates/apps/api/src/middleware/__tests__/rate-limit-cross-isolate.db.test.ts +220 -0
- package/templates/apps/api/src/middleware/__tests__/rate-limit-store.test.ts +430 -0
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +21 -14
- package/templates/apps/api/src/middleware/auth.ts +8 -4
- package/templates/apps/api/src/middleware/default-tenant.ts +9 -0
- package/templates/apps/api/src/middleware/rate-limit.ts +290 -82
- package/templates/apps/api/src/routes/project-listings/__tests__/drafts.test.ts +26 -0
- package/templates/apps/api/src/routes/webhooks/README.md +33 -5
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-proposal-paid.test.ts +369 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-site-filter.test.ts +442 -0
- package/templates/apps/api/src/routes/webhooks/stripe.ts +184 -6
- package/templates/apps/api/src/server.ts +14 -2
- package/templates/apps/api/src/services/__tests__/audit-log.test.ts +91 -0
- package/templates/apps/api/src/services/audit-log.ts +72 -10
- package/templates/apps/api/src/services/default-tenant.ts +12 -3
- package/templates/apps/api/src/services/hub-sign-in.ts +2 -1
- package/templates/apps/api/src/services/project-listings.ts +6 -1
- package/templates/apps/api/src/services/public-site-resolver.ts +21 -2
- package/templates/apps/api/vercel.json +1 -1
- package/templates/apps/mcp/CLAUDE.md +19 -7
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +139 -44
- package/templates/apps/mcp/jest.config.cjs +1 -0
- package/templates/apps/mcp/src/tools/person_notes.ts +25 -0
- package/templates/apps/mcp/src/tools/proposals.ts +27 -0
- package/templates/apps/mcp/src/workspace-server.ts +16 -0
- package/templates/apps/web/CLAUDE.md +26 -1
- package/templates/apps/web/_gitignore +6 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/sign-up-card.test.tsx +165 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +19 -0
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +106 -23
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up.actions.ts +125 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/agreements-prompt.test.tsx +281 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/general.test.tsx +28 -83
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/hub-mode.test.tsx +27 -13
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/item.test.tsx +57 -2
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/layout.test.tsx +2 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/notifications.test.tsx +102 -18
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/onboarding.test.tsx +323 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/privacy.test.tsx +365 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/settings.test.tsx +3 -2
- package/templates/apps/web/app/[locale]/(authed)/account/actions.ts +8 -0
- package/templates/apps/web/app/[locale]/(authed)/account/agreements-actions.ts +170 -0
- package/templates/apps/web/app/[locale]/(authed)/account/agreements-prompt.tsx +181 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/[pieceId]/page.tsx +88 -3
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/[pieceId]/pay-form.tsx +65 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/[pieceId]/review-form.tsx +27 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/__tests__/page.test.tsx +176 -3
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/__tests__/pay.test.tsx +193 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/__tests__/review.test.tsx +188 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/artifact-actions.ts +65 -4
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/artifact-data.ts +17 -0
- package/templates/apps/web/app/[locale]/(authed)/account/artifacts/page.tsx +11 -2
- package/templates/apps/web/app/[locale]/(authed)/account/general/page.tsx +5 -24
- package/templates/apps/web/app/[locale]/(authed)/account/notifications/page.tsx +64 -18
- package/templates/apps/web/app/[locale]/(authed)/account/onboarding/actions.ts +120 -0
- package/templates/apps/web/app/[locale]/(authed)/account/onboarding/onboarding-form.tsx +322 -0
- package/templates/apps/web/app/[locale]/(authed)/account/onboarding/page.tsx +126 -0
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +43 -1
- package/templates/apps/web/app/[locale]/(authed)/account/privacy/actions.ts +65 -0
- package/templates/apps/web/app/[locale]/(authed)/account/privacy/page.tsx +226 -0
- package/templates/apps/web/app/[locale]/(authed)/account/settings-frame.tsx +5 -3
- package/templates/apps/web/app/[locale]/about/[slug]/page.tsx +46 -0
- package/templates/apps/web/app/[locale]/about/__tests__/about-routes.test.tsx +350 -0
- package/templates/apps/web/app/[locale]/about/page.tsx +83 -1
- package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/consent-banner.tsx +32 -0
- package/templates/apps/web/app/[locale]/consent.actions.ts +71 -0
- package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +7 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-form-magnet.test.ts +138 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-form-text.test.ts +17 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-magnet-page.test.tsx +347 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +73 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +5 -3
- package/templates/apps/web/app/[locale]/contact/contact-form-magnet.ts +77 -0
- package/templates/apps/web/app/[locale]/contact/contact-form-text.ts +2 -0
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +48 -4
- package/templates/apps/web/app/[locale]/contact/page.tsx +81 -9
- package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/flows/[slug]/flow.actions.ts +25 -3
- package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/layout.tsx +46 -4
- package/templates/apps/web/app/[locale]/newsletter/newsletter.actions.ts +12 -1
- package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/unsubscribe/__tests__/unsubscribe-rsc-boundary.test.tsx +209 -0
- package/templates/apps/web/app/[locale]/unsubscribe/__tests__/unsubscribe.test.tsx +158 -0
- package/templates/apps/web/app/[locale]/unsubscribe/page.tsx +54 -0
- package/templates/apps/web/app/[locale]/unsubscribe/unsubscribe-button.tsx +73 -0
- package/templates/apps/web/app/[locale]/unsubscribe/unsubscribe.actions.ts +55 -0
- package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/working-agreement/__tests__/page.test.tsx +63 -0
- package/templates/apps/web/app/[locale]/working-agreement/page.tsx +41 -0
- package/templates/apps/web/app/robots.txt/route.ts +13 -10
- package/templates/apps/web/jest.config.cjs +4 -0
- package/templates/apps/web/lib/__tests__/consent-visitor.test.ts +163 -0
- package/templates/apps/web/lib/__tests__/deck-page.test.ts +244 -0
- package/templates/apps/web/lib/__tests__/relay.test.ts +49 -0
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +100 -9
- package/templates/apps/web/lib/account-config.ts +31 -16
- package/templates/apps/web/lib/consent-visitor.ts +103 -0
- package/templates/apps/web/lib/deck-page.ts +186 -0
- package/templates/apps/web/lib/relay.ts +20 -0
- package/templates/apps/web/messages/en.json +83 -9
- package/templates/apps/web/next.config.mjs +8 -2
- package/templates/database/CHANGELOG.md +48 -0
- package/templates/database/__tests__/outbound-message-action.db.test.ts +80 -0
- package/templates/database/__tests__/person-notes.db.test.ts +249 -0
- package/templates/database/__tests__/piece-kind-migration.test.ts +67 -0
- package/templates/database/__tests__/piece-kind.db.test.ts +208 -0
- package/templates/database/__tests__/seed.test.ts +39 -2
- package/templates/database/_gitignore +8 -0
- package/templates/database/inbox/schema.prisma +38 -12
- package/templates/database/jest.config.cjs +1 -0
- package/templates/database/migrations/20261015120000_person_notes/migration.sql +77 -0
- package/templates/database/migrations/20261015120000_rate_limit_counters/migration.sql +43 -0
- package/templates/database/migrations/20261016120000_piece_kind/migration.sql +95 -0
- package/templates/database/migrations/20261017120000_outbound_message_action/migration.sql +30 -0
- package/templates/database/ops/schema.prisma +16 -0
- package/templates/database/package.json +1 -1
- package/templates/database/seed.ts +29 -0
- package/templates/project.yaml +6 -3
- package/templates/tools/jest/pin-timezone.cjs +34 -0
- package/versions.json +35 -35
- package/templates/.claude/rules/preserve-existing-style.md +0 -51
|
@@ -232,6 +232,14 @@ _Code route — no content, no sections._
|
|
|
232
232
|
|
|
233
233
|
<!-- generated:end -->
|
|
234
234
|
|
|
235
|
+
<!-- generated:begin page=/working-agreement -->
|
|
236
|
+
|
|
237
|
+
| # | Section | Component | Copy (first line) |
|
|
238
|
+
| --- | ----------------------------------- | ----------------- | ----------------- |
|
|
239
|
+
| 1 | `document-chassis` (layout=article) | `DocumentChassis` | Working Agreement |
|
|
240
|
+
|
|
241
|
+
<!-- generated:end -->
|
|
242
|
+
|
|
235
243
|
`/blog` (the Free teaser row, § 1.9 — served by the generic `[slug]` route over the always-copied overlay's `BlogList/blog.mdx`):
|
|
236
244
|
|
|
237
245
|
<!-- generated:begin page=/blog -->
|
|
@@ -287,8 +295,9 @@ The standard page set for this shape (`derive-roster.py --shape person-service -
|
|
|
287
295
|
| `PortfolioList` · `PortfolioItem` | the portfolio pair belongs to every shape's standard roster (operator, 2026-09-25; roadmap § 4) |
|
|
288
296
|
| `BlogList` | every Free scaffold's nav links `/blog` unconditionally (`renderNavConfig`, operator ruling 2026-09-23); the Free teaser serves it, as on organization-product (#6753 D3) |
|
|
289
297
|
| `LandingPage` | the Free `/meet` meeting-types hub is a LandingPage seed, the same generic `[slug]` route serves it through (#6897 D3); the four `/meet/[slug]` BookCall detail seeds ride the `BookCall` type already in the standard roster |
|
|
298
|
+
| `WorkingAgreementPage` | the Contact form's terms checkbox links `/working-agreement` beside `/terms` and `/privacy`, so every starter ships the page from `_base` (#8661 D10) |
|
|
290
299
|
|
|
291
|
-
`|S − D| = 13` and `|R| =
|
|
300
|
+
`|S − D| = 13` and `|R| = 19`.
|
|
292
301
|
|
|
293
302
|
`/sign-in` and `/sign-up` are also rostered (#6797) — code routes (`kind: route`) with no page type, so they sit outside this set equation: the locale layout's header links both, and the roster of record lists every page the scaffold serves.
|
|
294
303
|
|
|
@@ -305,26 +314,27 @@ person-service:
|
|
|
305
314
|
shape: person-service
|
|
306
315
|
design: standard
|
|
307
316
|
roster:
|
|
308
|
-
- { route: "/",
|
|
309
|
-
- { route: "/services",
|
|
310
|
-
- { route: "/services/[slug]",
|
|
311
|
-
- { route: "/for",
|
|
312
|
-
- { route: "/for/[slug]",
|
|
313
|
-
- { route: "/about",
|
|
314
|
-
- { route: "/contact",
|
|
315
|
-
- { route: "/faq",
|
|
316
|
-
- { route: "/glossary",
|
|
317
|
-
- { route: "/newsletter",
|
|
318
|
-
- { route: "/sign-in",
|
|
319
|
-
- { route: "/sign-up",
|
|
320
|
-
- { route: "/purchase-policy",
|
|
321
|
-
- { route: "/privacy",
|
|
322
|
-
- { route: "/terms",
|
|
323
|
-
- { route: "/
|
|
324
|
-
- { route: "/
|
|
325
|
-
- { route: "/meet
|
|
326
|
-
- { route: "/
|
|
327
|
-
- { route: "/portfolio
|
|
317
|
+
- { route: "/", kind: page, content: ["content/en/HomePage/home.mdx"] }
|
|
318
|
+
- { route: "/services", kind: page, content: ["content/en/ServicesList/services.mdx"] }
|
|
319
|
+
- { route: "/services/[slug]", kind: page, contentDir: "content/en/Service" }
|
|
320
|
+
- { route: "/for", kind: page, content: ["content/en/UseCasesList/for.mdx"] }
|
|
321
|
+
- { route: "/for/[slug]", kind: page, contentDir: "content/en/UseCase" }
|
|
322
|
+
- { route: "/about", kind: page, content: ["content/en/AboutPage/about.mdx"] }
|
|
323
|
+
- { route: "/contact", kind: page, content: ["content/en/ContactPage/contact.mdx"] }
|
|
324
|
+
- { route: "/faq", kind: page, content: ["content/en/FAQPage/faq.mdx"] }
|
|
325
|
+
- { route: "/glossary", kind: page, content: ["content/en/GlossaryList/glossary.mdx"] }
|
|
326
|
+
- { route: "/newsletter", kind: page, content: ["content/en/NewsletterSignup/newsletter.mdx"] }
|
|
327
|
+
- { route: "/sign-in", kind: route }
|
|
328
|
+
- { route: "/sign-up", kind: route }
|
|
329
|
+
- { route: "/purchase-policy", kind: page, content: ["content/en/PurchasePolicyPage/purchase-policy.mdx"] }
|
|
330
|
+
- { route: "/privacy", kind: page, content: ["content/en/PrivacyPage/privacy.mdx"] }
|
|
331
|
+
- { route: "/terms", kind: page, content: ["content/en/TermsPage/terms.mdx"] }
|
|
332
|
+
- { route: "/working-agreement", kind: page, content: ["content/en/WorkingAgreementPage/working-agreement.mdx"] }
|
|
333
|
+
- { route: "/blog", kind: page, content: ["content/en/BlogList/blog.mdx"] }
|
|
334
|
+
- { route: "/meet", kind: page, content: ["content/en/LandingPage/meet.mdx"] }
|
|
335
|
+
- { route: "/meet/[slug]", kind: page, content: ["content/en/BookCall/book-a-call.mdx", "content/en/BookCall/onsite-estimate.mdx", "content/en/BookCall/start-project.mdx", "content/en/BookCall/onsite-service.mdx"] }
|
|
336
|
+
- { route: "/portfolio", kind: page, content: ["content/en/PortfolioList/portfolio.mdx"] }
|
|
337
|
+
- { route: "/portfolio/[slug]", kind: page, contentDir: "content/en/PortfolioItem" }
|
|
328
338
|
```
|
|
329
339
|
|
|
330
340
|
<!-- generated:end -->
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PostToolUse (Edit|Write): run the architecture boundary lint after an edit.
|
|
3
|
+
# Exits 0 until dependencies are installed, and 2 on a violation so Claude
|
|
4
|
+
# reads the finding. Registered in .claude/settings.json and declared in
|
|
5
|
+
# .claude/cloudparity-repo-hooks.json; keep the two in step.
|
|
6
|
+
cd "$CLAUDE_PROJECT_DIR" || exit 0
|
|
7
|
+
[ -x node_modules/.bin/tsx ] || exit 0
|
|
8
|
+
pnpm --silent architecture >&2 || exit 2
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Per-Issue Workflow
|
|
2
|
+
|
|
3
|
+
The contract every change goes through. One issue in, one PR out, no
|
|
4
|
+
scope creep.
|
|
5
|
+
|
|
6
|
+
This is the single-developer flow. If you're working solo on this
|
|
7
|
+
project, this is what every meaningful change looks like.
|
|
8
|
+
|
|
9
|
+
## Pick
|
|
10
|
+
|
|
11
|
+
Open an issue or claim one from your backlog. The issue must have:
|
|
12
|
+
|
|
13
|
+
- A `## Acceptance Criteria` section listing observable, verifiable
|
|
14
|
+
outcomes.
|
|
15
|
+
- A `## Scope` section listing the files or path globs you intend
|
|
16
|
+
to touch.
|
|
17
|
+
|
|
18
|
+
If either is missing, write them before you start — not as a
|
|
19
|
+
formality but because the rest of the workflow depends on them.
|
|
20
|
+
|
|
21
|
+
## Read
|
|
22
|
+
|
|
23
|
+
Before any edits:
|
|
24
|
+
|
|
25
|
+
1. The issue body in full — every acceptance bullet, scope path,
|
|
26
|
+
and dependency note.
|
|
27
|
+
2. `CLAUDE.md` — the operating manual you're already reading.
|
|
28
|
+
3. The files inside `## Scope` — confirm they exist and your mental
|
|
29
|
+
model matches what's actually there.
|
|
30
|
+
|
|
31
|
+
If anything is missing or the issue is infeasible as written, stop
|
|
32
|
+
and refine the issue before coding.
|
|
33
|
+
|
|
34
|
+
## Branch
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git checkout main
|
|
38
|
+
git pull --ff-only origin main
|
|
39
|
+
git checkout -b issue-<N>-<kebab-slug>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Use a 3–6 word slug from the issue title. Branch names show up in
|
|
43
|
+
your PR list — make them scannable.
|
|
44
|
+
|
|
45
|
+
## TDD: RED → GREEN
|
|
46
|
+
|
|
47
|
+
For functional acceptance criteria:
|
|
48
|
+
|
|
49
|
+
1. Write tests from the criteria first. They should fail (RED) —
|
|
50
|
+
your implementation doesn't exist yet.
|
|
51
|
+
2. Implement the smallest change that makes the tests pass (GREEN).
|
|
52
|
+
3. Refactor if the implementation is messy. Tests stay green
|
|
53
|
+
throughout.
|
|
54
|
+
|
|
55
|
+
Skip TDD only for: pure documentation, prompt-only changes, or
|
|
56
|
+
single-line fixes already covered by an existing test.
|
|
57
|
+
|
|
58
|
+
## Verify
|
|
59
|
+
|
|
60
|
+
Before commit AND before push:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pnpm preflight
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
This runs `architecture` + `claude-md:check` + `type-check` + `lint` +
|
|
67
|
+
`build`. It runs no tests, so it is not a stand-in for CI: run
|
|
68
|
+
`pnpm test` as well whenever your change has tests, and read CI's own
|
|
69
|
+
result on the PR.
|
|
70
|
+
|
|
71
|
+
For PRs touching specific surfaces:
|
|
72
|
+
|
|
73
|
+
- `database/` schema changes — also run `pnpm db:migrate` locally if
|
|
74
|
+
you added a migration.
|
|
75
|
+
|
|
76
|
+
## Commit + PR
|
|
77
|
+
|
|
78
|
+
- Commit message format: `feat(area): description (#N)`. Include
|
|
79
|
+
the issue number when one exists.
|
|
80
|
+
- Multiple commits on the branch are fine; squash-merge collapses
|
|
81
|
+
them.
|
|
82
|
+
- PR title: same as the commit message format.
|
|
83
|
+
- PR body must include:
|
|
84
|
+
- **Summary** — what the PR does, in plain language.
|
|
85
|
+
- **Scope** — paths actually touched (a subset of the issue's
|
|
86
|
+
scope).
|
|
87
|
+
- **Verification** — checklist of what you ran, with
|
|
88
|
+
`[x] pnpm preflight` ticked.
|
|
89
|
+
- `Closes #N` line — required for issue PRs; triggers GitHub's
|
|
90
|
+
auto-close on merge.
|
|
91
|
+
|
|
92
|
+
## After PR open
|
|
93
|
+
|
|
94
|
+
1. Wait for CI. If it goes red, diagnose and fix; do not merge red.
|
|
95
|
+
2. Wait for any automated reviewers (Bugbot, code review bots) to
|
|
96
|
+
return. Address every finding — either fix it or write a short
|
|
97
|
+
reply explaining why it's not actionable.
|
|
98
|
+
3. Merge once CI is green and reviews are reconciled.
|
|
99
|
+
|
|
100
|
+
## After merge
|
|
101
|
+
|
|
102
|
+
1. Close the issue if the PR didn't auto-close it.
|
|
103
|
+
2. Delete the local and remote branch.
|
|
104
|
+
3. Pick the next issue.
|
|
105
|
+
|
|
106
|
+
## Mid-task scope expansion
|
|
107
|
+
|
|
108
|
+
If you realize mid-task that the issue's `## Scope` was insufficient:
|
|
109
|
+
|
|
110
|
+
1. Stop before writing outside scope.
|
|
111
|
+
2. Update the PR description to add the new path with a one-line
|
|
112
|
+
reason.
|
|
113
|
+
3. Continue.
|
|
114
|
+
|
|
115
|
+
That short pause is the entire point — it forces you to acknowledge
|
|
116
|
+
that the work has grown, instead of letting it grow silently.
|
|
117
|
+
|
|
118
|
+
## When to escalate
|
|
119
|
+
|
|
120
|
+
Stop and surface the question rather than make the call alone if:
|
|
121
|
+
|
|
122
|
+
- An architecture invariant in `.claude/rules/architecture.md` would
|
|
123
|
+
have to bend.
|
|
124
|
+
- A change to a published `@working-theory/*` package is needed (file the
|
|
125
|
+
issue upstream; don't fork locally).
|
|
126
|
+
- The acceptance criteria contradict each other or the existing code.
|
|
127
|
+
- You'd be deleting or moving more than five files at once.
|
|
128
|
+
|
|
129
|
+
A short clarifying question beats a long detour down the wrong path.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"hooks": [
|
|
7
7
|
{
|
|
8
8
|
"type": "command",
|
|
9
|
-
"command": "
|
|
9
|
+
"command": "bash .claude/hooks/architecture-check.sh"
|
|
10
10
|
}
|
|
11
11
|
]
|
|
12
12
|
}
|
|
@@ -23,5 +23,6 @@
|
|
|
23
23
|
},
|
|
24
24
|
"enabledPlugins": {
|
|
25
25
|
"ailk@working-theory": true
|
|
26
|
-
}
|
|
26
|
+
},
|
|
27
|
+
"x-cloudparity-managed-keys": ["hooks"]
|
|
27
28
|
}
|
package/templates/.env.example
CHANGED
|
@@ -14,6 +14,7 @@ AILK_PUBLIC_DOMAIN=ailaunchkit.ai
|
|
|
14
14
|
# 3. <meta name="robots" content="noindex,nofollow"> tag (apps/web/app/[locale]/layout.tsx)
|
|
15
15
|
# At launch, set STEALTH=false on the hosting platform's env vars and redeploy.
|
|
16
16
|
# See README.md § "Going live" for the full flip checklist.
|
|
17
|
+
# Accepted (any case): true, 1, yes, on hide the site; false, 0, no, off or empty allow indexing. Any other value fails the build.
|
|
17
18
|
STEALTH=true
|
|
18
19
|
|
|
19
20
|
# Blog-OFF launch gate (#3413) — SITE-ARCHITECTURE §4.1 parks the blog at
|
|
@@ -520,6 +521,18 @@ CONTENT_ADAPTER=mdx
|
|
|
520
521
|
# it from one egress address. A whole number from 1 to 999999. Default: 120.
|
|
521
522
|
# AILK_RATE_LIMIT_DIRECTORY_PER_MINUTE=120
|
|
522
523
|
#
|
|
524
|
+
# apps/api. Which store rateLimitMiddleware's per-IP/per-key counters use
|
|
525
|
+
# (#5040). `database` counts in the deployment's own Postgres (DATABASE_URL),
|
|
526
|
+
# so the limit holds across every concurrent isolate; `memory` keeps the
|
|
527
|
+
# pre-#5040 in-process Map, which does not. Default: `database` when
|
|
528
|
+
# DATABASE_URL is set, else `memory`. A database failure or a 1s-slow call
|
|
529
|
+
# falls back to the in-process Map for that request rather than letting it
|
|
530
|
+
# through uncounted. Run `pnpm --filter @working-theory/api rate-limit:probe
|
|
531
|
+
# --origin <https origin>` against a live deployment to check which store it
|
|
532
|
+
# selected and whether a burst holds — see
|
|
533
|
+
# docs/runbooks/site-configuration.md.
|
|
534
|
+
# AILK_RATE_LIMIT_STORE=
|
|
535
|
+
#
|
|
523
536
|
# SPOKE (apps/web, server-only — never NEXT_PUBLIC_). This spoke's key: one
|
|
524
537
|
# entry of the hub's AILK_VISITOR_FORWARD_KEYS. Sent only when AILK_API_URL
|
|
525
538
|
# is https (or loopback). Issue a key only to a spoke whose platform
|
package/templates/CLAUDE.md
CHANGED
|
@@ -64,7 +64,7 @@ your module set; `pnpm architecture` enforces it, and a hook in
|
|
|
64
64
|
| Change the look | `create-ailk apply-design <name\|path>` (keeps `brand:`); at scaffold, `--design <folder>` |
|
|
65
65
|
| Logos, photos, brand reference | `brand_assets/` |
|
|
66
66
|
| Repo identity, labels, hard floors | `project.yaml` |
|
|
67
|
-
| Diff hygiene when editing existing files |
|
|
67
|
+
| Diff hygiene when editing existing files | `CONVENTIONS.md` § Commit + diff hygiene |
|
|
68
68
|
| Code style, testing, security | `CONVENTIONS.md` |
|
|
69
69
|
| Environment variables and what they unlock | `.env.example` |
|
|
70
70
|
| Deploy configuration | `apps/api/vercel.json`; the `/ailk:setup-deploy` skill |
|
package/templates/CONVENTIONS.md
CHANGED
|
@@ -196,8 +196,9 @@ move.
|
|
|
196
196
|
cleanup goes in its own follow-up PR.
|
|
197
197
|
- **Diff is the contract.** A 20-line behavioral change should produce
|
|
198
198
|
a ~20-line diff. If your editor reformatted unrelated lines, revert
|
|
199
|
-
the formatting before committing.
|
|
200
|
-
|
|
199
|
+
the formatting before committing. Match the file's existing quotes,
|
|
200
|
+
indentation and import order, and check `git diff --stat` before you
|
|
201
|
+
commit.
|
|
201
202
|
- **Commit message format:** `feat(area): description (#N)`. Include
|
|
202
203
|
the issue number when one exists.
|
|
203
204
|
- **Squash merge only.** Multiple commits on the branch are fine; the
|
package/templates/README.md
CHANGED
|
@@ -43,31 +43,32 @@ The pages of the Free `organization-product` shape, and where each one's copy li
|
|
|
43
43
|
|
|
44
44
|
<!-- generated:begin content -->
|
|
45
45
|
|
|
46
|
-
| Page
|
|
47
|
-
|
|
|
48
|
-
| `/`
|
|
49
|
-
| `/features`
|
|
50
|
-
| `/features/[slug]`
|
|
51
|
-
| `/for`
|
|
52
|
-
| `/for/[slug]`
|
|
53
|
-
| `/pricing`
|
|
54
|
-
| `/about`
|
|
55
|
-
| `/faq`
|
|
56
|
-
| `/contact`
|
|
57
|
-
| `/glossary`
|
|
58
|
-
| `/newsletter`
|
|
59
|
-
| `/sign-in`
|
|
60
|
-
| `/sign-up`
|
|
61
|
-
| `/privacy`
|
|
62
|
-
| `/terms`
|
|
63
|
-
| `/
|
|
64
|
-
| `/
|
|
65
|
-
| `/
|
|
66
|
-
| `/meet
|
|
67
|
-
| `/
|
|
68
|
-
| `/portfolio
|
|
69
|
-
| `/
|
|
70
|
-
| `/team
|
|
46
|
+
| Page | Content file | Ships in |
|
|
47
|
+
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
|
|
48
|
+
| `/` | `content/en/HomePage/home.mdx` | every scaffold |
|
|
49
|
+
| `/features` | `content/en/FeaturesList/features.mdx` | `--shape organization-product` |
|
|
50
|
+
| `/features/[slug]` | — (a code route) | `--shape organization-product` |
|
|
51
|
+
| `/for` | `content/en/UseCasesList/for.mdx` | `--shape organization-product` |
|
|
52
|
+
| `/for/[slug]` | — (a code route) | `--shape organization-product` |
|
|
53
|
+
| `/pricing` | `content/en/Pricing/pricing.mdx` | `--shape organization-product` |
|
|
54
|
+
| `/about` | `content/en/AboutPage/about.mdx` | every scaffold |
|
|
55
|
+
| `/faq` | `content/en/FAQPage/faq.mdx` | every scaffold |
|
|
56
|
+
| `/contact` | `content/en/ContactPage/contact.mdx` | every scaffold |
|
|
57
|
+
| `/glossary` | `content/en/GlossaryList/glossary.mdx` | `--shape organization-product` |
|
|
58
|
+
| `/newsletter` | `content/en/NewsletterSignup/newsletter.mdx` | `--shape organization-product` |
|
|
59
|
+
| `/sign-in` | — (a code route) | every scaffold |
|
|
60
|
+
| `/sign-up` | — (a code route) | every scaffold |
|
|
61
|
+
| `/privacy` | `content/en/PrivacyPage/privacy.mdx` | `--shape organization-product` |
|
|
62
|
+
| `/terms` | `content/en/TermsPage/terms.mdx` | `--shape organization-product` |
|
|
63
|
+
| `/working-agreement` | `content/en/WorkingAgreementPage/working-agreement.mdx` | `--shape organization-product` |
|
|
64
|
+
| `/purchase-policy` | `content/en/PurchasePolicyPage/purchase-policy.mdx` | every scaffold |
|
|
65
|
+
| `/blog` | `content/en/BlogList/blog.mdx` | every scaffold |
|
|
66
|
+
| `/meet` | `content/en/LandingPage/meet.mdx` | every scaffold |
|
|
67
|
+
| `/meet/[slug]` | `content/en/BookCall/book-a-call.mdx`, `content/en/BookCall/onsite-estimate.mdx`, `content/en/BookCall/start-project.mdx`, `content/en/BookCall/onsite-service.mdx` | every scaffold |
|
|
68
|
+
| `/portfolio` | `content/en/PortfolioList/portfolio.mdx` | `--shape organization-product` |
|
|
69
|
+
| `/portfolio/[slug]` | — (a code route) | `--shape organization-product` |
|
|
70
|
+
| `/team` | `content/en/TeamList/team.mdx` | `--shape organization-product` |
|
|
71
|
+
| `/team/[slug]` | — (a code route) | `--shape organization-product` |
|
|
71
72
|
|
|
72
73
|
<!-- generated:end -->
|
|
73
74
|
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules/
|
|
3
|
+
|
|
4
|
+
# Build output
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
.next/
|
|
8
|
+
*.tsbuildinfo
|
|
9
|
+
|
|
10
|
+
# Turborepo local task cache
|
|
11
|
+
.turbo/
|
|
12
|
+
|
|
13
|
+
# Fumadocs MDX codegen output (generated by fumadocs-mdx/next at build time)
|
|
14
|
+
apps/web/.source/
|
|
15
|
+
apps-paid/marketing-web/.source/
|
|
16
|
+
|
|
17
|
+
# Prisma generated client (regenerated via `pnpm db:generate`)
|
|
18
|
+
database/generated/
|
|
19
|
+
apps-paid/license-issuer/src/generated/
|
|
20
|
+
|
|
21
|
+
# api-client generated types (regenerated via `pnpm codegen`, run at build time)
|
|
22
|
+
packages/api-client/src/generated/
|
|
23
|
+
|
|
24
|
+
# Environment files
|
|
25
|
+
.env
|
|
26
|
+
.env.local
|
|
27
|
+
.env.*.local
|
|
28
|
+
|
|
29
|
+
# Logs
|
|
30
|
+
*.log
|
|
31
|
+
npm-debug.log*
|
|
32
|
+
pnpm-debug.log*
|
|
33
|
+
|
|
34
|
+
# Editor / OS
|
|
35
|
+
.DS_Store
|
|
36
|
+
.vscode/
|
|
37
|
+
.idea/
|
|
38
|
+
|
|
39
|
+
# Test coverage
|
|
40
|
+
coverage/
|
|
41
|
+
|
|
42
|
+
# Coverage audit baseline output (tools/audit-coverage.ts; on-demand only)
|
|
43
|
+
coverage-baseline-*.json
|
|
44
|
+
|
|
45
|
+
# Stryker mutation testing — temp sandbox + per-run report output
|
|
46
|
+
.stryker-tmp/
|
|
47
|
+
**/reports/mutation/
|
|
48
|
+
|
|
49
|
+
# Caches
|
|
50
|
+
.eslintcache
|
|
51
|
+
.cache/
|
|
52
|
+
|
|
53
|
+
# Claude Code session state (worktree manager)
|
|
54
|
+
.claude/worktrees/
|
|
55
|
+
|
|
56
|
+
# AILK file-fallback inbox (OSS standalone mode; leads written here when DB unavailable)
|
|
57
|
+
.ailk/
|
|
58
|
+
|
|
59
|
+
# AILK license refresh-cached JWT (default storage path for @working-theory/license)
|
|
60
|
+
.ailk-license.jwt
|
|
61
|
+
|
|
62
|
+
# Lead capture JSONL store (contains customer contact data — never commit)
|
|
63
|
+
apps/api/leads.jsonl
|
|
64
|
+
apps/api/leads.jsonl.*
|
|
65
|
+
|
|
66
|
+
# Build-time content manifest (generated by pnpm content:compile; not committed)
|
|
67
|
+
content/.compiled/
|
|
68
|
+
|
|
69
|
+
# Preflight success marker (written by pnpm preflight; read by require-preflight-on-push hook)
|
|
70
|
+
.claude/.preflight-ok
|
|
71
|
+
|
|
72
|
+
# Maintainer-only orchestration (Sam's /loop, dispatch, autonomy, babysit/cron skills).
|
|
73
|
+
# These live on the maintainer's filesystem and are not part of the public template.
|
|
74
|
+
.claude/rules/dispatch-defaults.md
|
|
75
|
+
.claude/rules/parallel-agent-discipline.md
|
|
76
|
+
.claude/rules/autonomy-ailk.md
|
|
77
|
+
.claude/skills/babysit/
|
|
78
|
+
.claude/skills/post-merge-sweeper/
|
|
79
|
+
.claude/skills/pr-pruner/
|
|
80
|
+
|
|
81
|
+
# Other ephemeral Claude Code state
|
|
82
|
+
.claude/.continue-after-simplify-attempts
|
|
83
|
+
.claude/.simplify-last-run
|
|
84
|
+
.claude/.enforce-checkpoint-before-stop-attempts
|
|
85
|
+
.claude/.worktree-root
|
|
86
|
+
.claude/scheduled_tasks.lock
|
|
87
|
+
.claude/logs/
|
|
88
|
+
.claude/settings.local.json
|
|
89
|
+
.claude/review-findings/
|
|
90
|
+
|
|
91
|
+
# db:generate advisory lock dir (runtime-only; created/removed by database/scripts/db-generate-locked.sh)
|
|
92
|
+
.claude/.db-generate.lock
|
|
93
|
+
|
|
94
|
+
# Playwright MCP session artifacts (accessibility snapshots auto-created during browser_* runs)
|
|
95
|
+
.playwright-mcp/
|
|
96
|
+
|
|
97
|
+
# Saved Playwright login sessions the extract-*-from-reference skills write
|
|
98
|
+
# (cookies for an auth-gated reference site). This file is also every
|
|
99
|
+
# scaffold's .gitignore (build-templates.mjs SNAPSHOT_FILES), so a customer
|
|
100
|
+
# never commits one either.
|
|
101
|
+
brand_assets/.playwright-auth/
|
|
102
|
+
|
|
103
|
+
# Visual-iteration scratch — directory tracked via .gitkeep, contents ignored
|
|
104
|
+
screenshots/*
|
|
105
|
+
!screenshots/.gitkeep
|
|
106
|
+
|
|
107
|
+
# Content pipeline per-repo scratch (PAGE-COPY, site architecture files, etc.)
|
|
108
|
+
# Collocated with repo for /copywriting and /compile-page skills. See claude-setup#423.
|
|
109
|
+
strategy/
|
|
110
|
+
# Allow versioned strategy docs in docs/internal/strategy/ (claude-setup#486)
|
|
111
|
+
!docs/internal/strategy/
|
|
112
|
+
# Allow the flat versioned strategy docs in docs/strategy/ (claude-setup#3424).
|
|
113
|
+
# Kept out of the public OSS repo via project.yaml strip_for_oss.exclude_dirs.
|
|
114
|
+
!docs/strategy/
|
|
115
|
+
|
|
116
|
+
# Storybook build output
|
|
117
|
+
storybook-static/
|
|
118
|
+
|
|
119
|
+
# Playwright test-run bookkeeping (per-run status + failure artifacts) — never
|
|
120
|
+
# committed; a local `pnpm visual:test` run previously left `.last-run.json`
|
|
121
|
+
# and a per-failure `error-context.md` tracked in the repo (#6577).
|
|
122
|
+
test-results/
|
|
123
|
+
|
|
124
|
+
# Static export output — @working-theory/design-reference-gallery's build
|
|
125
|
+
# artifact (the ailk-storybook hosting shape: a static tree served from a
|
|
126
|
+
# protected origin). Rebuilt by `pnpm --filter @working-theory/design-reference-gallery build`.
|
|
127
|
+
apps-paid/design-reference-gallery/out/
|
|
128
|
+
|
|
129
|
+
# Vercel CLI local state — `vercel pull` writes project settings + a pulled
|
|
130
|
+
# .env.<env>.local here, and `vercel build` writes the Build Output API tree.
|
|
131
|
+
# The deploy workflow creates all of it at the repo root at run time (#4482).
|
|
132
|
+
.vercel/
|
|
133
|
+
|
|
134
|
+
# impeccable detect CLI pilot (epic #4501, issue #4511) — per-developer
|
|
135
|
+
# override + ephemeral working state. .impeccable/config.json itself IS
|
|
136
|
+
# committed (e.g. packages/ui/.impeccable/config.json) — only these are not.
|
|
137
|
+
# Patterns are `**/`-prefixed since .impeccable/ lives under packages/ui, not
|
|
138
|
+
# the repo root.
|
|
139
|
+
**/.impeccable/config.local.json
|
|
140
|
+
**/.impeccable/*.ndjson
|
|
141
|
+
**/.impeccable/cache/
|
|
142
|
+
**/.impeccable/hook.cache.json
|
|
143
|
+
|
|
144
|
+
# Root-anchored scratch-artifact guard (#5179 / PUB-902, PUB-903, PUB-910).
|
|
145
|
+
# Design-iteration screenshots and profiling dumps have no directory to live
|
|
146
|
+
# under at the repository root, so nothing else stops them from recurring
|
|
147
|
+
# there. The leading `/` anchors each pattern to the repo root only — images
|
|
148
|
+
# tracked elsewhere (brand_assets/**, package public/ assets, visual-regression
|
|
149
|
+
# baselines) are untouched. Bytecode caches are unwanted anywhere, so those two
|
|
150
|
+
# patterns are unanchored.
|
|
151
|
+
/*.png
|
|
152
|
+
/*.jpeg
|
|
153
|
+
/*.jpg
|
|
154
|
+
__pycache__/
|
|
155
|
+
*.pyc
|
|
156
|
+
|
|
157
|
+
# e2e journey tests (.claude/skills/e2e): the running stack's state, logs and secrets, and each run's raw results
|
|
158
|
+
tests/e2e/.stack/
|
|
159
|
+
tests/e2e/.results/
|
|
160
|
+
|
|
161
|
+
# create-ailk licence key file (`--license`, `ailk license set`) — owner-only, never committed
|
|
162
|
+
ailk.key
|