create-ailk 0.9.0 → 0.11.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 +10 -5
- package/dist/cli.js +17 -2
- package/dist/content-payloads.d.ts +37 -0
- package/dist/content-payloads.js +64 -0
- package/dist/lib/fetch-module.d.ts +3 -3
- package/dist/lib/fetch-module.js +11 -5
- package/dist/lib/fetch-template.d.ts +1 -1
- package/dist/lib/fetch-template.js +7 -4
- package/dist/lib/module-license-gate.d.ts +29 -23
- package/dist/lib/module-license-gate.js +98 -0
- package/dist/module-architecture.d.ts +9 -0
- package/dist/module-architecture.js +46 -14
- package/dist/parse-args.d.ts +2 -0
- package/dist/parse-args.js +7 -0
- package/dist/programmatic.js +12 -4
- package/dist/starter-grid.d.ts +4 -67
- package/dist/starter-grid.js +6 -84
- package/dist/surfaces.js +2 -3
- package/dist/template-manifest.d.ts +1 -1
- package/dist/template-manifest.js +5 -5
- package/package.json +6 -4
- package/release-scope.json +25 -0
- package/site-templates/designs/minimalism/sample/README.md +2 -2
- package/site-templates/designs/minimalism/sample/content/en/HomePage/home.mdx +1 -1
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +4 -3
- package/templates/.claude/agents/web.md +10 -8
- package/templates/.claude/rules/architecture.md +10 -7
- package/templates/.claude/settings.json +12 -0
- package/templates/.env.example +24 -3
- package/templates/CLAUDE.md +38 -22
- package/templates/README.md +12 -12
- package/templates/apps/api/jest.config.cjs +1 -0
- package/templates/apps/api/package.json +1 -0
- package/templates/apps/mcp/CLAUDE.md +23 -10
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +160 -17
- package/templates/apps/mcp/__tests__/index.test.ts +118 -1
- package/templates/apps/mcp/__tests__/lib/commerce-claim.test.ts +425 -5
- package/templates/apps/mcp/__tests__/module-exclusion.test.ts +67 -3
- package/templates/apps/mcp/__tests__/server.test.ts +162 -1
- package/templates/apps/mcp/src/index.ts +35 -3
- package/templates/apps/mcp/src/lib/commerce-claim.ts +193 -24
- package/templates/apps/mcp/src/server.ts +77 -5
- package/templates/apps/mcp/src/tools/purchase.ts +1 -1
- package/templates/apps/web/app/.well-known/mcp.json/build-manifest.ts +15 -0
- package/templates/apps/web/app/.well-known/mcp.json/route.ts +10 -3
- package/templates/apps/web/src/lib/commerce-claim.ts +15 -6
- package/templates/content/_site.mdx +23 -4
- package/templates/database/CHANGELOG.md +7 -0
- package/templates/database/package.json +1 -1
- package/templates/package.json +2 -0
- package/versions.json +34 -33
- package/dist/modules/commerce/0.6.0.tar.gz +0 -0
- package/dist/modules/commerce/0.6.1.tar.gz +0 -0
- package/dist/modules/docs-blog/0.6.0.tar.gz +0 -0
- package/dist/modules/docs-blog/0.6.1.tar.gz +0 -0
- package/dist/modules/marketing-site/0.6.1.tar.gz +0 -0
- package/dist/modules/minimalism-site/0.6.1.tar.gz +0 -0
- package/dist/modules/multi-tenant/0.6.0.tar.gz +0 -0
- package/dist/modules/multi-tenant/0.6.1.tar.gz +0 -0
- package/dist/modules/saas-product/0.6.1.tar.gz +0 -0
- package/dist/modules/scheduling/0.6.0.tar.gz +0 -0
- package/dist/modules/scheduling/0.6.1.tar.gz +0 -0
- package/dist/modules/signal-collectors/0.6.0.tar.gz +0 -0
- package/dist/modules/signal-collectors/0.6.1.tar.gz +0 -0
- package/dist/modules/simple-service/0.6.1.tar.gz +0 -0
- package/dist/modules/workspace/0.6.0.tar.gz +0 -0
- package/dist/modules/workspace/0.6.1.tar.gz +0 -0
- package/site-templates/aliases/minimalism-site.TEMPLATE-MANIFEST.json +0 -538
- package/templates/.claude/skills/README.md +0 -37
- package/templates/.claude/skills/add-auth/SKILL.md +0 -261
- package/templates/.claude/skills/add-auth/references/env-vars.md +0 -98
- package/templates/.claude/skills/add-auth/references/oauth-app-setup.md +0 -172
- package/templates/.claude/skills/add-page/SKILL.md +0 -260
- package/templates/.claude/skills/add-page/references/page-types.md +0 -124
- package/templates/.claude/skills/add-page/scripts/site-pages.mjs +0 -87
- package/templates/.claude/skills/add-page/templates/comparison-page.mdx.tmpl +0 -99
- package/templates/.claude/skills/add-page/templates/content.mdx.tmpl +0 -18
- package/templates/.claude/skills/add-page/templates/flow-landing-page.mdx.tmpl +0 -43
- package/templates/.claude/skills/add-page/templates/report-page.mdx.tmpl +0 -52
- package/templates/.claude/skills/add-page/templates/reports-list.mdx.tmpl +0 -38
- package/templates/.claude/skills/check-site/SKILL.md +0 -235
- package/templates/.claude/skills/check-site/references/common-errors.md +0 -113
- package/templates/.claude/skills/check-site/references/findings-glossary.md +0 -140
- package/templates/.claude/skills/check-site/references/severity-levels.md +0 -114
- package/templates/.claude/skills/fill-page/SKILL.md +0 -199
- package/templates/.claude/skills/fill-page/profiles/plumbing.yaml +0 -80
- package/templates/.claude/skills/fill-page/references/section-sources.md +0 -41
- package/templates/.claude/skills/setup-database/SKILL.md +0 -156
- package/templates/.claude/skills/setup-database/scripts/verify-inbox.ts +0 -154
- package/templates/.claude/skills/setup-deploy/SKILL.md +0 -275
- package/templates/.claude/skills/setup-deploy/references/env-vars-template.md +0 -192
- package/templates/.claude/skills/setup-deploy/references/runbook-template.md +0 -204
- package/templates/.claude/skills/setup-deploy/references/vercel-json-template.md +0 -98
- package/templates/.claude/skills/update-page/SKILL.md +0 -117
- package/templates/.claude/skills/update-page/scripts/update-page.ts +0 -640
- package/templates/.claude/skills/update-page/templates/redirects.mjs.tmpl +0 -31
- package/templates/.claude/skills/upgrade-plan/SKILL.md +0 -121
- package/templates/.claude/skills/upgrade-plan/references/options.md +0 -24
- package/templates/.claude/skills/upgrade-plan/scripts/upgrade-plan.ts +0 -527
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-31.552Z-fallback-1789916251590-037e9005.json +0 -8
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.840Z-fallback-1789916253842-b52659e9.json +0 -12
- package/templates/apps/api/.ailk/inbox/2026-09-20T14-57-33.844Z-fallback-1789916253845-6b266f8c.json +0 -12
- package/templates/apps/mcp/__tests__/lib/require-paid-tier.test.ts +0 -75
- package/templates/apps/mcp/src/lib/require-paid-tier.ts +0 -44
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: ReportPage
|
|
3
|
-
slug: {{SLUG}}
|
|
4
|
-
placeholder: true
|
|
5
|
-
title: {{TITLE}}
|
|
6
|
-
description: {{DESCRIPTION}}
|
|
7
|
-
schema:
|
|
8
|
-
datePublished: "{{DATE_PUBLISHED}}"
|
|
9
|
-
author:
|
|
10
|
-
"@type": Organization
|
|
11
|
-
name: "{Your Company}"
|
|
12
|
-
sections:
|
|
13
|
-
[
|
|
14
|
-
{
|
|
15
|
-
"id": "header",
|
|
16
|
-
"type": "report-header",
|
|
17
|
-
"data":
|
|
18
|
-
{
|
|
19
|
-
"title": "{{TITLE}}",
|
|
20
|
-
"eyebrow": "{{DATE_LABEL}}",
|
|
21
|
-
"backHref": "/reports",
|
|
22
|
-
"backLabel": "All reports",
|
|
23
|
-
"tone": "on-dark",
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"id": "document",
|
|
28
|
-
"type": "document-viewer",
|
|
29
|
-
"data":
|
|
30
|
-
{
|
|
31
|
-
"src": "/reports/sample-report.pdf",
|
|
32
|
-
"geometry": "16:9",
|
|
33
|
-
"pages": 8,
|
|
34
|
-
"downloadFilename": "{{SLUG}}.pdf",
|
|
35
|
-
"outline":
|
|
36
|
-
[
|
|
37
|
-
{ "id": "opening", "label": "Opening", "startPage": 1 },
|
|
38
|
-
{ "id": "findings", "label": "Findings", "startPage": 3 },
|
|
39
|
-
{ "id": "outlook", "label": "Outlook", "startPage": 6 },
|
|
40
|
-
],
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
]
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
{/* A PLACEHOLDER report. Its bytes are the signal-collectors module's own
|
|
47
|
-
sample PDF (apps/web/public/reports/sample-report.pdf), shared by every
|
|
48
|
-
sample report so the site ships no binary of its own. Point `src` at your
|
|
49
|
-
real document and set `pages` to its real page count. Rendered by the
|
|
50
|
-
signal-collectors module's own /reports/<slug> route (`app/[locale]/reports/[slug]/page.tsx`)
|
|
51
|
-
and listed automatically by the /reports hub (ReportsList) — never
|
|
52
|
-
hand-list a report there. */}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: ReportsList
|
|
3
|
-
slug: reports
|
|
4
|
-
placeholder: true
|
|
5
|
-
title: {{TITLE}}
|
|
6
|
-
description: {{DESCRIPTION}}
|
|
7
|
-
sections:
|
|
8
|
-
[
|
|
9
|
-
{
|
|
10
|
-
"id": "hero",
|
|
11
|
-
"type": "hero",
|
|
12
|
-
"data":
|
|
13
|
-
{
|
|
14
|
-
"variant": "centered",
|
|
15
|
-
"eyebrow": "Reports",
|
|
16
|
-
"headline": "{{TITLE}}",
|
|
17
|
-
"subheadline": "{{DESCRIPTION}}",
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"id": "closing",
|
|
22
|
-
"type": "cta",
|
|
23
|
-
"data":
|
|
24
|
-
{
|
|
25
|
-
"variant": "minimal",
|
|
26
|
-
"headline": "{Want the next one as it lands?}",
|
|
27
|
-
"primaryCta": { "label": "{Contact me →}", "href": "/contact" },
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
]
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
{/* Rendered from frontmatter `sections[]` by the /reports route
|
|
34
|
-
(`app/[locale]/reports/page.tsx`). Its card list is GENERATED, not
|
|
35
|
-
authored here (spec 6892 D2): the route appends one `reports-list`
|
|
36
|
-
section listing every ReportPage seed, so this seed carries only its own
|
|
37
|
-
hero and closing cta. Placeholder copy — replace every {brace} with your
|
|
38
|
-
own words before you launch. */}
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: check-site
|
|
3
|
-
description: Run `ailk-audit --json` on the consumer's AILK site, parse the JSON report, and explain the score and findings in plain language. Use when the user asks "how is my site doing?", "audit my site", "what's my score?", "is my JSON-LD valid?", "do I have all the schema I need?", or otherwise wants a citation-readiness check on their AILK content. The skill never edits files — it reports and points at fix tools.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# check-site
|
|
7
|
-
|
|
8
|
-
Shell out to `ailk-audit --json`, parse the JSON, and turn it into a
|
|
9
|
-
conversational summary the consumer can act on. Pure explain-only —
|
|
10
|
-
the skill names fix tools (like the `schema:` frontmatter override)
|
|
11
|
-
but does not invoke them.
|
|
12
|
-
|
|
13
|
-
## When to use
|
|
14
|
-
|
|
15
|
-
The user wants to know how their AILK site is doing on the
|
|
16
|
-
citation-readiness audit (AEO Layer 1). Triggers:
|
|
17
|
-
|
|
18
|
-
- "audit my site" / "run the audit"
|
|
19
|
-
- "what's my score?" / "how is my site doing?"
|
|
20
|
-
- "is my JSON-LD valid?" / "do I have schema on every page?"
|
|
21
|
-
- "what would I fix to bump my AEO score?"
|
|
22
|
-
- "re-run the audit, I just edited /pricing"
|
|
23
|
-
|
|
24
|
-
Skip this skill when:
|
|
25
|
-
|
|
26
|
-
- The consumer wants to _fix_ a finding — point them at the fix
|
|
27
|
-
tool (usually `add-page`'s `schema:` frontmatter override) and stop. This skill reports;
|
|
28
|
-
fix tools fix.
|
|
29
|
-
- The consumer is asking about deploy-time monitoring or continuous
|
|
30
|
-
audits — those are Pro features (`ailk pro` for details). Mention
|
|
31
|
-
briefly and stop.
|
|
32
|
-
- The audit CLI isn't installed (`ailk-audit` not on PATH or as a
|
|
33
|
-
workspace bin) — translate the error per "Common errors" below.
|
|
34
|
-
|
|
35
|
-
## The mechanic
|
|
36
|
-
|
|
37
|
-
### Step 0 — Read what this site can render
|
|
38
|
-
|
|
39
|
-
Read `.ailk-site-manifest.json` at the site root, the site's roster of
|
|
40
|
-
record:
|
|
41
|
-
|
|
42
|
-
- `modules` — the modules this site has. Add any module the
|
|
43
|
-
`# Modules:` line of `architecture.yaml` names that `modules` does not:
|
|
44
|
-
`create-ailk add-module` records a module it adds there. With no
|
|
45
|
-
manifest, or none carrying `modules`, that line is the set.
|
|
46
|
-
- `rows` — every route the site carries and the page type each renders.
|
|
47
|
-
- `level` — present only when the scaffold derived it from the licence
|
|
48
|
-
key. It never decides what to suggest; `modules` does.
|
|
49
|
-
|
|
50
|
-
A page type renders on this site only when its **Module** in
|
|
51
|
-
`.claude/skills/add-page/references/page-types.md` is in that set.
|
|
52
|
-
Step 7 suggests a page only of such a type.
|
|
53
|
-
|
|
54
|
-
### Step 1 — Invoke the CLI
|
|
55
|
-
|
|
56
|
-
Run `ailk-audit --json` from the consumer's project root. Use
|
|
57
|
-
whichever of these is appropriate to the consumer's setup:
|
|
58
|
-
|
|
59
|
-
- `pnpm exec ailk-audit --json`
|
|
60
|
-
- `npx ailk-audit --json`
|
|
61
|
-
- A package.json script if the consumer has one (`pnpm audit:run`,
|
|
62
|
-
etc.) — only if it's a thin wrapper over the same CLI.
|
|
63
|
-
|
|
64
|
-
Capture both stdout (the JSON report) and stderr (errors). Do not
|
|
65
|
-
cache. Each invocation runs the CLI fresh.
|
|
66
|
-
|
|
67
|
-
### Step 2 — Detect errors first
|
|
68
|
-
|
|
69
|
-
If the CLI exited non-zero, treat as an error condition:
|
|
70
|
-
|
|
71
|
-
- If stderr matches one of the three common-error signatures, emit
|
|
72
|
-
the translated explanation from `references/common-errors.md`.
|
|
73
|
-
- Otherwise, surface the verbatim CLI stderr prefixed with one
|
|
74
|
-
line: `` `ailk-audit` failed — `` followed by the verbatim message.
|
|
75
|
-
Do not invent fix suggestions for unknown errors.
|
|
76
|
-
|
|
77
|
-
Stop here on errors. Do not continue to Step 3.
|
|
78
|
-
|
|
79
|
-
### Step 3 — Parse the JSON report
|
|
80
|
-
|
|
81
|
-
The report shape (from `packages/aeo/src/types.ts`):
|
|
82
|
-
|
|
83
|
-
```ts
|
|
84
|
-
interface AuditReport {
|
|
85
|
-
score: number; // 0–100
|
|
86
|
-
perRule: PerRuleResult[]; // one entry per rule, with id + pass + weight
|
|
87
|
-
perPage: PerPageResult[]; // one entry per audited page
|
|
88
|
-
meta: { schemaVersion; registryVersion; auditedAt };
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
`perRule` entries each have `{ id, weight, pass, evidence?, perPage? }`.
|
|
93
|
-
|
|
94
|
-
### Step 4 — Render the headline
|
|
95
|
-
|
|
96
|
-
The first line of output should be the score, in a compact form:
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
AEO score: 87 / 100
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
If the score is the same as the consumer's previous run (and you
|
|
103
|
-
can tell — but you usually can't, since this is always-fresh), do
|
|
104
|
-
not annotate with deltas. The audit doesn't track history.
|
|
105
|
-
|
|
106
|
-
### Step 5 — Group findings by severity
|
|
107
|
-
|
|
108
|
-
Severity is **derived from rule weight + pass/fail** per
|
|
109
|
-
`references/severity-levels.md`. The mapping at v1:
|
|
110
|
-
|
|
111
|
-
| Severity | Source |
|
|
112
|
-
| -------- | ------------------------------------------------------------------------------------------ |
|
|
113
|
-
| Critical | `pass: false` on a rule with `weight >= 10` (e.g., schema-coverage, jsonld-validity) |
|
|
114
|
-
| Warning | `pass: false` on a rule with `weight` in `[1, 9]` (e.g., entity-markup) |
|
|
115
|
-
| Info | `pass: true` on incentive rules (`weight: 0`) — these are positive signals; never failures |
|
|
116
|
-
|
|
117
|
-
After the score line, emit a one-line severity summary:
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
2 critical · 1 warning · 0 info
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
If the count for a tier is 0, omit it from the summary (e.g.,
|
|
124
|
-
"2 critical" if warnings and info are both empty).
|
|
125
|
-
|
|
126
|
-
### Step 6 — Drill-down on demand
|
|
127
|
-
|
|
128
|
-
Wait for the consumer's next message. Common follow-ups:
|
|
129
|
-
|
|
130
|
-
- "tell me about the critical findings" → emit each critical
|
|
131
|
-
finding's plain-language explanation (from
|
|
132
|
-
`references/findings-glossary.md`) plus, if applicable, a
|
|
133
|
-
pointer to the fix tool (see Step 7).
|
|
134
|
-
- "what about the warnings?" → same, for warnings.
|
|
135
|
-
- "show me the per-page scores" → emit the `perPage` list,
|
|
136
|
-
formatted as a table or bullet list.
|
|
137
|
-
- "re-run it" / "audit again" → go back to Step 1.
|
|
138
|
-
|
|
139
|
-
If the consumer doesn't ask anything specific, ask them which
|
|
140
|
-
severity tier they'd like to see first, and offer to point at the
|
|
141
|
-
likely fix-tool path.
|
|
142
|
-
|
|
143
|
-
### Step 7 — Map findings to fix tools (no auto-dispatch)
|
|
144
|
-
|
|
145
|
-
When you describe a finding, name the fix tool by name. Do not
|
|
146
|
-
invoke it. The consumer must explicitly invoke the fix tool
|
|
147
|
-
themselves on a subsequent turn.
|
|
148
|
-
|
|
149
|
-
| Rule | Fix tool |
|
|
150
|
-
| --------------------- | ---------------------------------------------------------------------------------------- |
|
|
151
|
-
| `schema-coverage` | `add-page`'s `schema:` frontmatter override — add the missing schema type to the named page |
|
|
152
|
-
| `jsonld-validity` | `add-page`'s `schema:` frontmatter override — replace the invalid block; or hand-fix the MDX |
|
|
153
|
-
| `entity-markup` | Manual edit — ensure `Organization` (or `Person`) JSON-LD is emitted somewhere site-wide |
|
|
154
|
-
| `faq-howto-incentive` | `add-page`'s `schema:` frontmatter override — add an `FAQPage` or `HowTo` block to a relevant page |
|
|
155
|
-
|
|
156
|
-
When a fix means adding a page, name only a page type this site can
|
|
157
|
-
render (Step 0) — for `faq-howto-incentive`, a `FAQPage` or `HowTo`
|
|
158
|
-
page, never one the site's modules do not render. When only a type the
|
|
159
|
-
site cannot render would fix a finding, say which module renders it and
|
|
160
|
-
which level carries it, and point at the `upgrade-plan` skill.
|
|
161
|
-
|
|
162
|
-
Phrase the pointer as a single sentence:
|
|
163
|
-
|
|
164
|
-
> "Missing `Product` schema on `/pricing` — add it via `add-page`'s
|
|
165
|
-
> `schema:` frontmatter override."
|
|
166
|
-
|
|
167
|
-
Never write to the consumer's repo from inside this skill.
|
|
168
|
-
|
|
169
|
-
### Step 8 — Soft Pro mention
|
|
170
|
-
|
|
171
|
-
If a finding maps to a Pro auto-fix capability, surface a
|
|
172
|
-
single-line mention tied to that finding:
|
|
173
|
-
|
|
174
|
-
- **Schema-pack drift** (a finding indicating a registry version
|
|
175
|
-
mismatch or stale schema-type usage):
|
|
176
|
-
|
|
177
|
-
> "Pro auto-applies schema-pack updates as schema.org evolves —
|
|
178
|
-
> `ailk pro` for details."
|
|
179
|
-
|
|
180
|
-
- **Continuous-deploy audit** (the consumer is asking how to keep
|
|
181
|
-
the score from regressing, not about a specific finding):
|
|
182
|
-
> "Pro can run this audit on every deploy and gate releases on
|
|
183
|
-
> the score — `ailk pro` for details."
|
|
184
|
-
|
|
185
|
-
Never produce a multi-line Pro recommendation, feature
|
|
186
|
-
comparison, or upgrade prompt. The mention is informational, not
|
|
187
|
-
salesy.
|
|
188
|
-
|
|
189
|
-
### Step 9 — Cadence guidance
|
|
190
|
-
|
|
191
|
-
If the consumer asks "how often should I run this?", answer:
|
|
192
|
-
|
|
193
|
-
> "Re-run after content changes — adding pages, editing schema,
|
|
194
|
-
> changing your identity entity. There's no calendar cadence — the
|
|
195
|
-
> audit reports current state, not trends."
|
|
196
|
-
|
|
197
|
-
Never recommend "weekly" / "monthly" / a date.
|
|
198
|
-
|
|
199
|
-
## Output style
|
|
200
|
-
|
|
201
|
-
- **Score line first.** No preamble before the number.
|
|
202
|
-
- **Plain language for findings.** Don't paste raw rule IDs at the
|
|
203
|
-
consumer; translate via `references/findings-glossary.md`.
|
|
204
|
-
- **Pointers, not pitches.** A finding becomes a sentence; a fix
|
|
205
|
-
tool becomes a sentence. The consumer drives the next turn.
|
|
206
|
-
- **Verbatim for unknown errors.** If something fails in a way
|
|
207
|
-
this skill doesn't recognize, surface the raw stderr and stop.
|
|
208
|
-
|
|
209
|
-
## What this skill does NOT do
|
|
210
|
-
|
|
211
|
-
- Edit any file in the consumer's repo.
|
|
212
|
-
- Add JSON-LD to pages (that's the `schema:` frontmatter override, documented in `add-page`).
|
|
213
|
-
- Create new pages (that's `add-page`).
|
|
214
|
-
- Cache results between runs.
|
|
215
|
-
- Track score history or trends.
|
|
216
|
-
- Auto-invoke fix tools.
|
|
217
|
-
- Pitch Pro hard.
|
|
218
|
-
|
|
219
|
-
## References
|
|
220
|
-
|
|
221
|
-
- `references/findings-glossary.md` — plain-language explanation per rule.
|
|
222
|
-
- `references/common-errors.md` — translations for the three most common CLI failures.
|
|
223
|
-
- `references/severity-levels.md` — how rule weight + pass/fail maps to severity.
|
|
224
|
-
|
|
225
|
-
## Coordination
|
|
226
|
-
|
|
227
|
-
- **`add-page`'s `schema:` frontmatter override** — primary fix
|
|
228
|
-
mechanism the skill points at. Never auto-invoked.
|
|
229
|
-
- **`add-page`** — new-page creation; not a fix-tool
|
|
230
|
-
for audit findings (audit reports on existing pages).
|
|
231
|
-
- **`packages/aeo`** — owner of the `ailk-audit` CLI and rule set.
|
|
232
|
-
This skill depends only on the CLI's `--json` output schema, not
|
|
233
|
-
the package's internal types. New rules added upstream surface
|
|
234
|
-
automatically as new findings; the glossary may lag and that's
|
|
235
|
-
acceptable (unrecognized rule IDs render as the raw ID).
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
# Common Errors — Plain-Language Translations
|
|
2
|
-
|
|
3
|
-
The three most common ways `ailk-audit` fails on a real consumer
|
|
4
|
-
setup, with translations the `check-site` skill emits instead of
|
|
5
|
-
the raw stderr. Errors not matching any of these signatures pass
|
|
6
|
-
through verbatim with a one-line `` `ailk-audit` failed — `` prefix
|
|
7
|
-
(see SKILL.md Step 2).
|
|
8
|
-
|
|
9
|
-
The signature matching is intentionally narrow — partial matches
|
|
10
|
-
on substrings the user could reasonably encounter, so we don't
|
|
11
|
-
mis-translate an unfamiliar error into a familiar fix path.
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## 1. `ailk.config.ts` is missing
|
|
16
|
-
|
|
17
|
-
**Stderr signature (any of):**
|
|
18
|
-
|
|
19
|
-
- `ailk.config.ts not found`
|
|
20
|
-
- `Cannot resolve ailk.config.ts`
|
|
21
|
-
- `[aeo] config file ailk.config.ts is missing`
|
|
22
|
-
|
|
23
|
-
**Translation:**
|
|
24
|
-
|
|
25
|
-
> Your project is missing `ailk.config.ts`. The audit reads this
|
|
26
|
-
> file to know what `identityMode` (`organization` vs `person`)
|
|
27
|
-
> your site uses, plus any custom registry overrides.
|
|
28
|
-
>
|
|
29
|
-
> Create one at the project root with at minimum:
|
|
30
|
-
>
|
|
31
|
-
> ```ts
|
|
32
|
-
> import type { AilkConfig } from "@working-theory/config";
|
|
33
|
-
>
|
|
34
|
-
> export default {
|
|
35
|
-
> identityMode: "organization",
|
|
36
|
-
> } satisfies AilkConfig;
|
|
37
|
-
> ```
|
|
38
|
-
>
|
|
39
|
-
> …then re-run the audit. If you don't have `@working-theory/config`
|
|
40
|
-
> installed, your scaffold is incomplete — `pnpm install` should
|
|
41
|
-
> have pulled it as part of `@working-theory/*`.
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## 2. No MDX content found
|
|
46
|
-
|
|
47
|
-
**Stderr signature (any of):**
|
|
48
|
-
|
|
49
|
-
- `No pages found in content`
|
|
50
|
-
- `[aeo] content directory is empty`
|
|
51
|
-
- `Cannot read directory: content/`
|
|
52
|
-
|
|
53
|
-
**Translation:**
|
|
54
|
-
|
|
55
|
-
> The audit didn't find any MDX content in `content/`. Either:
|
|
56
|
-
>
|
|
57
|
-
> - Your content lives elsewhere — pass `--content-root <path>`
|
|
58
|
-
> to point at the right directory.
|
|
59
|
-
> - You haven't authored any pages yet — run `add-page` to generate
|
|
60
|
-
> them.
|
|
61
|
-
> - The MDX files exist but aren't in the format the AILK content
|
|
62
|
-
> adapter expects — make sure each page has frontmatter with at
|
|
63
|
-
> least `title` and `type`.
|
|
64
|
-
>
|
|
65
|
-
> The audit needs at least one MDX file to score; an empty site
|
|
66
|
-
> can't be audited.
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## 3. `@working-theory/aeo` is not installed
|
|
71
|
-
|
|
72
|
-
**Stderr signature (any of):**
|
|
73
|
-
|
|
74
|
-
- `command not found: ailk-audit`
|
|
75
|
-
- `ailk-audit: command not found`
|
|
76
|
-
- The skill itself can't find the binary on PATH or in
|
|
77
|
-
`node_modules/.bin`.
|
|
78
|
-
|
|
79
|
-
**Translation:**
|
|
80
|
-
|
|
81
|
-
> The `ailk-audit` CLI isn't installed in this project. It ships
|
|
82
|
-
> with `@working-theory/aeo`, which is normally part of the AILK consumer
|
|
83
|
-
> scaffold.
|
|
84
|
-
>
|
|
85
|
-
> Add it: `pnpm add -D @working-theory/aeo` (dev dep is fine — audits run
|
|
86
|
-
> at content time, not at build time). Then `pnpm install` and
|
|
87
|
-
> re-run.
|
|
88
|
-
>
|
|
89
|
-
> If `@working-theory/aeo` is in `package.json` but the binary still isn't
|
|
90
|
-
> found, run `pnpm install` once to refresh `node_modules/.bin`.
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## Anything else
|
|
95
|
-
|
|
96
|
-
If the stderr doesn't match one of the three signatures above:
|
|
97
|
-
|
|
98
|
-
1. Don't translate — the cost of a wrong translation is high
|
|
99
|
-
(consumer follows incorrect fix advice).
|
|
100
|
-
2. Surface the verbatim stderr.
|
|
101
|
-
3. Prefix with one line: `` `ailk-audit` failed — `` then the raw
|
|
102
|
-
message on subsequent lines.
|
|
103
|
-
4. Stop. Don't invent fix steps for an error you don't recognize.
|
|
104
|
-
|
|
105
|
-
Example output for an unrecognized error:
|
|
106
|
-
|
|
107
|
-
```
|
|
108
|
-
`ailk-audit` failed —
|
|
109
|
-
[aeo] failed to parse JSON-LD on page /blog/post-1: SyntaxError: Unexpected token } in JSON at position 482
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
This gives the consumer exactly what the CLI said, branded with
|
|
113
|
-
which CLI emitted it, without pretending to know how to fix it.
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# Findings Glossary — Per-Rule Plain-Language Explanations
|
|
2
|
-
|
|
3
|
-
What each AEO rule means in plain language, what its `pass: false`
|
|
4
|
-
result indicates, and what the consumer can do about it. Used by the
|
|
5
|
-
`check-site` skill in Step 6 (drill-down) and Step 7 (fix-tool
|
|
6
|
-
pointer).
|
|
7
|
-
|
|
8
|
-
The structure deliberately matches `perRule[].id` from the audit
|
|
9
|
-
JSON so the skill can grep this file for `## <rule-id>` to find the
|
|
10
|
-
explanation. New rules added to `packages/aeo` will not appear here
|
|
11
|
-
until this file is updated; render unrecognized rule IDs as the raw
|
|
12
|
-
ID (no synthesis).
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## schema-coverage
|
|
17
|
-
|
|
18
|
-
**Plain language:** every page on your site should emit at least
|
|
19
|
-
one JSON-LD object whose `@type` matches what the page is _about_.
|
|
20
|
-
A `/pricing` page should have `Product` (or `Service`, or
|
|
21
|
-
`OfferCatalog`) schema; a `/about` page should have `AboutPage`;
|
|
22
|
-
and so on.
|
|
23
|
-
|
|
24
|
-
**`pass: false` means:** one or more pages emit no JSON-LD whose
|
|
25
|
-
`@type` matches the registry's expected `pageType` for that page's
|
|
26
|
-
content type. The `evidence` field names which pages.
|
|
27
|
-
|
|
28
|
-
**Why it matters:** structured data is what answer engines (Google
|
|
29
|
-
SGE, Perplexity, ChatGPT search) read to understand your pages. A
|
|
30
|
-
page with no schema is invisible to citation; a page with the
|
|
31
|
-
wrong schema gets miscategorized.
|
|
32
|
-
|
|
33
|
-
**Fix tool:** `add-page`'s `schema:` frontmatter override — set the
|
|
34
|
-
schema type the registry expects (the audit names it) on the page's
|
|
35
|
-
frontmatter. The typed builder emits a `<JsonLd>` block matching the
|
|
36
|
-
page's content.
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## jsonld-validity
|
|
41
|
-
|
|
42
|
-
**Plain language:** every JSON-LD block on the site should be
|
|
43
|
-
well-formed schema.org markup with all required fields present
|
|
44
|
-
and non-empty for its `@type`. Missing the `name` on an
|
|
45
|
-
`Organization`, missing `headline` on an `Article`, etc., breaks
|
|
46
|
-
schema validity.
|
|
47
|
-
|
|
48
|
-
**`pass: false` means:** at least one JSON-LD block has missing or
|
|
49
|
-
empty schema.org-required fields for its declared `@type`.
|
|
50
|
-
|
|
51
|
-
**Why it matters:** answer engines and crawlers may silently drop
|
|
52
|
-
invalid blocks. The page exists, the JSON-LD exists, but the
|
|
53
|
-
citation surface is broken because the block doesn't parse as
|
|
54
|
-
valid schema.org.
|
|
55
|
-
|
|
56
|
-
**Fix tool:** `add-page`'s `schema:` frontmatter override — replace
|
|
57
|
-
the malformed block. For one-off edits to MDX, the consumer can also
|
|
58
|
-
hand-edit the JSON-LD inline; the frontmatter override is the safer
|
|
59
|
-
path because it uses typed builders.
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
## entity-markup
|
|
64
|
-
|
|
65
|
-
**Plain language:** somewhere on your site (typically the home
|
|
66
|
-
page or layout root), there should be exactly one identity entity
|
|
67
|
-
JSON-LD — `Organization` if the site represents a business, or
|
|
68
|
-
`Person` if the site represents an individual (a solo lawyer,
|
|
69
|
-
realtor, consultant, author, etc.). The audit picks up on
|
|
70
|
-
`identityMode` (configured in `ailk.config.ts`).
|
|
71
|
-
|
|
72
|
-
**`pass: false` means:** no `Organization` block (when
|
|
73
|
-
`identityMode: organization`) or no `Person` block (when
|
|
74
|
-
`identityMode: person`) was emitted by any audited page.
|
|
75
|
-
|
|
76
|
-
**Why it matters:** the identity entity is what ties every other
|
|
77
|
-
piece of structured data together. Without it, schema.org
|
|
78
|
-
relationships (`isPartOf`, `author`, `provider`, `mainEntity`)
|
|
79
|
-
have nothing to anchor to.
|
|
80
|
-
|
|
81
|
-
**Fix:** Manual MDX or layout edit — ensure your home page (or a
|
|
82
|
-
layout component rendered on every page) emits an
|
|
83
|
-
`Organization` (or `Person`) JSON-LD block. The `<JsonLd
|
|
84
|
-
schema={OrganizationSchema(...)} />` pattern from `@working-theory/schema`
|
|
85
|
-
is the one this is going to ship as. `add-page`'s `schema:`
|
|
86
|
-
frontmatter override can land the block on a specific page if you'd
|
|
87
|
-
rather; but typically
|
|
88
|
-
identity goes in a layout, not a leaf page.
|
|
89
|
-
|
|
90
|
-
---
|
|
91
|
-
|
|
92
|
-
## faq-howto-incentive
|
|
93
|
-
|
|
94
|
-
**Plain language:** pages that emit `FAQPage` or `HowTo` schema
|
|
95
|
-
get a small bonus signal. This rule **never fails a page** — it's
|
|
96
|
-
purely incentivizing. Absence of FAQ/HowTo blocks is neutral, not
|
|
97
|
-
a failure.
|
|
98
|
-
|
|
99
|
-
**`pass: true` and `bonus: true` per page means:** that page
|
|
100
|
-
earned the incentive (has FAQ or HowTo schema).
|
|
101
|
-
|
|
102
|
-
**`pass: true` and `bonus: false` per page means:** that page is
|
|
103
|
-
fine, just didn't earn the bonus.
|
|
104
|
-
|
|
105
|
-
**Why it matters:** answer engines preferentially cite pages with
|
|
106
|
-
explicit Q&A or step-by-step content because those are easier to
|
|
107
|
-
quote directly into a generated response. Adding an FAQ or HowTo
|
|
108
|
-
block to relevant pages is a low-effort score boost.
|
|
109
|
-
|
|
110
|
-
**Fix tool:** `add-page`'s `schema:` frontmatter override — add an
|
|
111
|
-
`FAQPage` block to your `/pricing` or `/contact` page (anywhere your
|
|
112
|
-
customers ask predictable questions), or a `HowTo` block to any
|
|
113
|
-
process/instructions content. `check-site` will surface this as
|
|
114
|
-
an _incentive_ in drill-down, not a finding to "fix."
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## always-passes / always-fails
|
|
119
|
-
|
|
120
|
-
These are **test rules** that exist for the audit's own test suite
|
|
121
|
-
in `packages/aeo`. They should not appear on a real consumer site
|
|
122
|
-
unless the rule list has been customized. If you see one of these
|
|
123
|
-
IDs in your audit output, the consumer's `ailk-audit` CLI may have
|
|
124
|
-
a non-standard rule list — that's a setup question, not a content
|
|
125
|
-
finding.
|
|
126
|
-
|
|
127
|
-
---
|
|
128
|
-
|
|
129
|
-
## Unrecognized rule IDs
|
|
130
|
-
|
|
131
|
-
If the audit JSON includes a rule ID not listed above, the rule is
|
|
132
|
-
new (added to `packages/aeo` after this glossary was last updated).
|
|
133
|
-
Render it as:
|
|
134
|
-
|
|
135
|
-
> Rule `<id>` — `<evidence text from the audit JSON>` — not in
|
|
136
|
-
> the local glossary; consult `packages/aeo` upstream docs.
|
|
137
|
-
|
|
138
|
-
Do not invent a plain-language explanation for an unrecognized
|
|
139
|
-
rule. The consumer can read the rule's `description` field from
|
|
140
|
-
the JSON if they want the formal definition.
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
# Severity Levels — Score Banding + Severity Mapping
|
|
2
|
-
|
|
3
|
-
The AEO audit JSON does **not** include explicit severity fields.
|
|
4
|
-
Severity is **derived** by the `check-site` skill from each rule's
|
|
5
|
-
`weight` and `pass`. This file is the source of truth for that
|
|
6
|
-
mapping.
|
|
7
|
-
|
|
8
|
-
The skill applies these rules in `SKILL.md` Step 5.
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Severity tiers
|
|
13
|
-
|
|
14
|
-
| Tier | Source signal | Meaning |
|
|
15
|
-
| -------- | ----------------------------------------------- | ----------------------------------------------------------------------- |
|
|
16
|
-
| Critical | `pass: false` AND `weight >= 10` | Rule that materially affects citation readiness; failure is blocking. |
|
|
17
|
-
| Warning | `pass: false` AND `weight` in `[1, 9]` | Rule that nudges citation quality; failure is fixable, not blocking. |
|
|
18
|
-
| Info | `pass: true` AND `weight: 0` (incentive rules) | Positive signal earned. Bonus, not a finding. |
|
|
19
|
-
| Neutral | `pass: true` AND `weight: 0` AND `bonus: false` | Page is fine but didn't earn the incentive. Don't surface unless asked. |
|
|
20
|
-
|
|
21
|
-
A rule with `pass: false` AND `weight: 0` is **not possible** today
|
|
22
|
-
(incentive rules are designed to never fail — see
|
|
23
|
-
`faq-howto-incentive` in `packages/aeo`). If one ever appears,
|
|
24
|
-
treat it as Info (the rule's own design says failures are neutral).
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## Why weight thresholds, not explicit severity
|
|
29
|
-
|
|
30
|
-
The AEO type system intentionally keeps rules weight-based, not
|
|
31
|
-
severity-based. Reasons:
|
|
32
|
-
|
|
33
|
-
- **Score arithmetic stays simple.** `passing-weight / total-weight`
|
|
34
|
-
is the score; introducing severity as a separate axis would force
|
|
35
|
-
every rule to choose two attributes (weight AND severity) when
|
|
36
|
-
one is enough.
|
|
37
|
-
- **The skill is the right place for the translation.** Consumers
|
|
38
|
-
don't care about weights — they care about "should I fix this?".
|
|
39
|
-
The skill turns "weight 10 fail" into "Critical" because that's
|
|
40
|
-
the language consumers can act on.
|
|
41
|
-
- **Rule authors don't have to think about severity.** A new rule
|
|
42
|
-
added to `packages/aeo` gets a weight (its impact on the score)
|
|
43
|
-
and the skill maps that to a severity tier automatically. No
|
|
44
|
-
coupling between rule authoring and consumer-facing UX.
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## Score banding (optional)
|
|
49
|
-
|
|
50
|
-
When the consumer asks "is this a good score?", you can map the
|
|
51
|
-
numeric score to a band. This is optional — Step 4 always emits
|
|
52
|
-
the raw score first.
|
|
53
|
-
|
|
54
|
-
| Score | Band | Hint |
|
|
55
|
-
| ------ | ----------------- | ---------------------------------------------------------------- |
|
|
56
|
-
| 90–100 | Excellent | All critical rules pass; site is well-instrumented for citation. |
|
|
57
|
-
| 75–89 | Good | Probably a critical or warning fixable on a couple of pages. |
|
|
58
|
-
| 50–74 | Needs work | Multiple critical rules failing; address those first. |
|
|
59
|
-
| 0–49 | Foundational gaps | Site likely has no schema or invalid schema across most pages. |
|
|
60
|
-
|
|
61
|
-
Hint sentences are suggestions; adapt phrasing to the consumer's
|
|
62
|
-
context. Don't quote the band tag verbatim if a more natural
|
|
63
|
-
phrasing fits the conversation ("you're at 87 — couple of fixes
|
|
64
|
-
away from clean").
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## Severity counting for the summary line
|
|
69
|
-
|
|
70
|
-
Step 5 of SKILL.md asks for a summary like:
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
2 critical · 1 warning · 0 info
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Counts are computed as:
|
|
77
|
-
|
|
78
|
-
- **Critical count** = count of `perRule[]` entries where
|
|
79
|
-
`pass === false && weight >= 10`.
|
|
80
|
-
- **Warning count** = count of `perRule[]` entries where
|
|
81
|
-
`pass === false && weight >= 1 && weight < 10`.
|
|
82
|
-
- **Info count** = count of `perRule[]` entries where
|
|
83
|
-
`pass === true && weight === 0` (i.e., earned incentives).
|
|
84
|
-
|
|
85
|
-
Some rules surface per-page failures (`perRule[].perPage[]`).
|
|
86
|
-
Those are deeper-level findings the skill can drill into in Step 6;
|
|
87
|
-
they don't change the rule-level severity counts. A `schema-coverage`
|
|
88
|
-
rule with `pass: false` and 5 failing pages is **one** critical
|
|
89
|
-
finding (the rule failed), with 5 page-specific evidence entries
|
|
90
|
-
for drill-down.
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## What this skill does NOT classify as severity
|
|
95
|
-
|
|
96
|
-
- **`bonus: true` per page** is not a finding; it's a positive
|
|
97
|
-
signal. Surface it on drill-down ("These pages earned the FAQ
|
|
98
|
-
bonus: …") but don't include it in the severity summary.
|
|
99
|
-
- **Schema-version mismatch** (a `meta.schemaVersion` from the
|
|
100
|
-
audit that doesn't match the consumer's `@working-theory/schema`) is not a
|
|
101
|
-
rule failure — it's a setup-drift signal. Surface only if the
|
|
102
|
-
consumer asks why the score might be inconsistent across runs.
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
## Future rules
|
|
107
|
-
|
|
108
|
-
When `packages/aeo` adds a new rule, this glossary may not name
|
|
109
|
-
it. The severity mapping still works because it keys off `weight`
|
|
110
|
-
and `pass` only — both fields are guaranteed by the
|
|
111
|
-
`PerRuleResult` type. New critical-tier rules will surface as
|
|
112
|
-
`Critical` automatically; new warnings as `Warning`. The findings
|
|
113
|
-
glossary may lag in offering plain-language explanations until
|
|
114
|
-
this template is updated.
|