@adia-ai/adia-ui-forge 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/.claude-plugin/plugin.json +23 -0
  2. package/CHANGELOG.md +26 -0
  3. package/README.md +54 -0
  4. package/bin/forge-lint +263 -0
  5. package/bin/lib/audit-axes.mjs +555 -0
  6. package/bin/lib/dry-run-irreversible.mjs +236 -0
  7. package/bin/lib/run-skill-evals.mjs +487 -0
  8. package/bin/lib/teach-router.mjs +250 -0
  9. package/commands/adia-forge-a2ui.md +10 -0
  10. package/commands/adia-forge-author.md +10 -0
  11. package/commands/adia-forge-dogfood.md +8 -0
  12. package/commands/adia-forge-llm.md +8 -0
  13. package/commands/adia-forge-orient.md +10 -0
  14. package/commands/adia-forge-release.md +8 -0
  15. package/commands/adia-forge-review.md +10 -0
  16. package/hooks/hooks.json +15 -0
  17. package/package.json +41 -0
  18. package/references/shared/content-trust.md +76 -0
  19. package/references/shared/pev-rationale.md +64 -0
  20. package/references/shared/skill-conventions.md +133 -0
  21. package/skills/adia-ui-a2ui/CHANGELOG.md +32 -0
  22. package/skills/adia-ui-a2ui/SKILL.md +243 -0
  23. package/skills/adia-ui-a2ui/evals/adversarial-corpus.json +75 -0
  24. package/skills/adia-ui-a2ui/evals/routing-corpus.json +31 -0
  25. package/skills/adia-ui-a2ui/evals/teach-routing-cases.json +100 -0
  26. package/skills/adia-ui-a2ui/references/anti-patterns.md +24 -0
  27. package/skills/adia-ui-a2ui/references/chunk-authoring.md +88 -0
  28. package/skills/adia-ui-a2ui/references/corpus-discipline.md +56 -0
  29. package/skills/adia-ui-a2ui/references/eval-diagnostics.md +127 -0
  30. package/skills/adia-ui-a2ui/references/fragment-graph.md +91 -0
  31. package/skills/adia-ui-a2ui/references/mcp-pipeline-ops.md +106 -0
  32. package/skills/adia-ui-a2ui/references/mcp-tool-reference.md +398 -0
  33. package/skills/adia-ui-a2ui/references/pipeline-overview.md +175 -0
  34. package/skills/adia-ui-a2ui/references/semantic-fail-lifting.md +120 -0
  35. package/skills/adia-ui-a2ui/references/strategy-engines.md +111 -0
  36. package/skills/adia-ui-a2ui/references/teach-protocol.md +220 -0
  37. package/skills/adia-ui-a2ui/references/zettel-calibration.md +93 -0
  38. package/skills/adia-ui-a2ui/scripts/audit-a2ui-roster.mjs +96 -0
  39. package/skills/adia-ui-a2ui/scripts/teach-route.mjs +157 -0
  40. package/skills/adia-ui-a2ui/skill.json +38 -0
  41. package/skills/adia-ui-authoring/CHANGELOG.md +32 -0
  42. package/skills/adia-ui-authoring/SKILL.md +256 -0
  43. package/skills/adia-ui-authoring/assets/case-studies/admin-shell-decomposition.md +101 -0
  44. package/skills/adia-ui-authoring/assets/case-studies/maxtokens-32768-discovery.md +109 -0
  45. package/skills/adia-ui-authoring/assets/case-studies/theme-panel-promotion.md +113 -0
  46. package/skills/adia-ui-authoring/evals/adversarial-design-plan-gates.json +138 -0
  47. package/skills/adia-ui-authoring/evals/routing-corpus.json +245 -0
  48. package/skills/adia-ui-authoring/references/anti-patterns.md +606 -0
  49. package/skills/adia-ui-authoring/references/api-contract.md +205 -0
  50. package/skills/adia-ui-authoring/references/authoring-cycle.md +211 -0
  51. package/skills/adia-ui-authoring/references/canonical-pattern-index.md +179 -0
  52. package/skills/adia-ui-authoring/references/code-style.md +329 -0
  53. package/skills/adia-ui-authoring/references/common-gotchas.md +93 -0
  54. package/skills/adia-ui-authoring/references/composite-demo-protocol.md +1084 -0
  55. package/skills/adia-ui-authoring/references/css-patterns.md +364 -0
  56. package/skills/adia-ui-authoring/references/lifecycle-patterns.md +302 -0
  57. package/skills/adia-ui-authoring/references/llm-bridge.md +254 -0
  58. package/skills/adia-ui-authoring/references/module-promotion.md +289 -0
  59. package/skills/adia-ui-authoring/references/primitive-audit.md +123 -0
  60. package/skills/adia-ui-authoring/references/shell-patterns.md +561 -0
  61. package/skills/adia-ui-authoring/references/teach-protocol.md +428 -0
  62. package/skills/adia-ui-authoring/references/token-contract.md +120 -0
  63. package/skills/adia-ui-authoring/references/worked-example.md +351 -0
  64. package/skills/adia-ui-authoring/references/yaml-contract.md +224 -0
  65. package/skills/adia-ui-authoring/scripts/audit-authoring-roster.mjs +148 -0
  66. package/skills/adia-ui-authoring/scripts/build-canonical-pattern-index.mjs +199 -0
  67. package/skills/adia-ui-authoring/skill.json +45 -0
  68. package/skills/adia-ui-dogfood/CHANGELOG.md +17 -0
  69. package/skills/adia-ui-dogfood/README.md +62 -0
  70. package/skills/adia-ui-dogfood/SKILL.md +866 -0
  71. package/skills/adia-ui-dogfood/scripts/analyze.mjs +603 -0
  72. package/skills/adia-ui-dogfood/skill.json +40 -0
  73. package/skills/adia-ui-forge/SKILL.md +88 -0
  74. package/skills/adia-ui-forge/evals/routing-corpus.json +30 -0
  75. package/skills/adia-ui-gen-review/CHANGELOG.md +108 -0
  76. package/skills/adia-ui-gen-review/SKILL.md +266 -0
  77. package/skills/adia-ui-gen-review/references/loop-protocol.md +712 -0
  78. package/skills/adia-ui-gen-review/references/rubric-cosmetic.md +144 -0
  79. package/skills/adia-ui-gen-review/references/rubric-decompose.md +117 -0
  80. package/skills/adia-ui-gen-review/references/rubric-score.md +249 -0
  81. package/skills/adia-ui-gen-review/references/scores.schema.json +125 -0
  82. package/skills/adia-ui-gen-review/references/teach-protocol.md +214 -0
  83. package/skills/adia-ui-gen-review/scripts/gen-review-coverage-audit.mjs +127 -0
  84. package/skills/adia-ui-gen-review/scripts/gen-review-decompose.mjs +569 -0
  85. package/skills/adia-ui-gen-review/scripts/gen-review-status.mjs +176 -0
  86. package/skills/adia-ui-gen-review/scripts/validate-cycle-scores.mjs +198 -0
  87. package/skills/adia-ui-gen-review/skill.json +22 -0
  88. package/skills/adia-ui-llm/CHANGELOG.md +25 -0
  89. package/skills/adia-ui-llm/SKILL.md +165 -0
  90. package/skills/adia-ui-llm/evals/adversarial-corpus.json +75 -0
  91. package/skills/adia-ui-llm/evals/routing-corpus.json +30 -0
  92. package/skills/adia-ui-llm/evals/teach-routing-cases.json +73 -0
  93. package/skills/adia-ui-llm/references/adapter-contract.md +99 -0
  94. package/skills/adia-ui-llm/references/add-a-provider.md +90 -0
  95. package/skills/adia-ui-llm/references/bridge-facade.md +94 -0
  96. package/skills/adia-ui-llm/references/browser-proxy-boundary.md +89 -0
  97. package/skills/adia-ui-llm/references/model-registry.md +75 -0
  98. package/skills/adia-ui-llm/references/streaming-sse.md +95 -0
  99. package/skills/adia-ui-llm/references/teach-protocol.md +78 -0
  100. package/skills/adia-ui-llm/scripts/audit-llm-roster.mjs +93 -0
  101. package/skills/adia-ui-llm/scripts/teach-route.mjs +119 -0
  102. package/skills/adia-ui-llm/skill.json +33 -0
  103. package/skills/adia-ui-release/CHANGELOG.md +23 -0
  104. package/skills/adia-ui-release/SKILL.md +295 -0
  105. package/skills/adia-ui-release/assets/case-studies/2026-05-20-batch-push-v0.6.14-v0.6.15.md +144 -0
  106. package/skills/adia-ui-release/assets/case-studies/2026-05-20-corpus-drift-remediation-v0.6.15.md +155 -0
  107. package/skills/adia-ui-release/assets/case-studies/2026-05-20-version-skip-correction-v0.6.12.md +114 -0
  108. package/skills/adia-ui-release/assets/case-studies/2026-05-21-author-from-scratch-v0.6.18.md +139 -0
  109. package/skills/adia-ui-release/assets/case-studies/2026-05-21-feedback37-retraction-v0.6.21.md +124 -0
  110. package/skills/adia-ui-release/assets/case-studies/2026-05-21-fn1-enrichment-pass-v0.6.19.md +125 -0
  111. package/skills/adia-ui-release/assets/case-studies/2026-05-21-stale-test-detection-v0.6.20.md +142 -0
  112. package/skills/adia-ui-release/assets/case-studies/2026-05-23-freshness-gate-recovery-v0.6.32.md +97 -0
  113. package/skills/adia-ui-release/assets/case-studies/2026-05-26-catalog-drift-recurring-v0.6.40.md +147 -0
  114. package/skills/adia-ui-release/assets/templates/stub-changelog.template.md +22 -0
  115. package/skills/adia-ui-release/evals/evals.json +164 -0
  116. package/skills/adia-ui-release/references/changelog-discipline.md +250 -0
  117. package/skills/adia-ui-release/references/cycle-happy-path.md +520 -0
  118. package/skills/adia-ui-release/references/exe-deploy.md +149 -0
  119. package/skills/adia-ui-release/references/gates-catalog.md +778 -0
  120. package/skills/adia-ui-release/references/ledger-discipline.md +232 -0
  121. package/skills/adia-ui-release/references/migration-guide-authoring.md +174 -0
  122. package/skills/adia-ui-release/references/multi-agent-baseline.md +207 -0
  123. package/skills/adia-ui-release/references/notes-authoring.md +212 -0
  124. package/skills/adia-ui-release/references/recovery-paths.md +215 -0
  125. package/skills/adia-ui-release/references/rollup-notes.md +208 -0
  126. package/skills/adia-ui-release/references/teach-protocol.md +468 -0
  127. package/skills/adia-ui-release/scripts/assert-monorepo-root.mjs +49 -0
  128. package/skills/adia-ui-release/scripts/audit-gate-roster.mjs +196 -0
  129. package/skills/adia-ui-release/scripts/bump.mjs +118 -0
  130. package/skills/adia-ui-release/scripts/dispatch-publish.mjs +151 -0
  131. package/skills/adia-ui-release/scripts/insert-stub.mjs +127 -0
  132. package/skills/adia-ui-release/scripts/make-ledger.mjs +179 -0
  133. package/skills/adia-ui-release/scripts/promote-unreleased.mjs +88 -0
  134. package/skills/adia-ui-release/scripts/release-pack.mjs +350 -0
  135. package/skills/adia-ui-release/scripts/tag-lockstep.mjs +110 -0
  136. package/skills/adia-ui-release/skill.json +75 -0
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env node
2
+ // audit-authoring-roster.mjs — §SelfAudit enforcement for adia-ui-authoring.
3
+ // Universal axes via the shared audit-axes lib; plus a skill-specific
4
+ // absorbed-skill roster-currency axis.
5
+ //
6
+ // Usage (from anywhere):
7
+ // node scripts/audit-authoring-roster.mjs
8
+ // node scripts/audit-authoring-roster.mjs --json
9
+ // node scripts/audit-authoring-roster.mjs --strict
10
+ //
11
+ // Resolves the shared lib via ${CLAUDE_PLUGIN_ROOT}/bin/lib/audit-axes.mjs,
12
+ // with a fallback relative to this script (skills/<name>/scripts → bin/lib).
13
+
14
+ import fs from 'node:fs';
15
+ import path from 'node:path';
16
+ import process from 'node:process';
17
+ import { fileURLToPath, pathToFileURL } from 'node:url';
18
+
19
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
20
+ const SKILL_DIR = path.resolve(__dirname, '..'); // skills/adia-ui-authoring
21
+ const SKILLS_ROOT = path.resolve(SKILL_DIR, '..'); // skills/
22
+ const PLUGIN_ROOT = process.env.CLAUDE_PLUGIN_ROOT
23
+ ? path.resolve(process.env.CLAUDE_PLUGIN_ROOT)
24
+ : path.resolve(SKILL_DIR, '..', '..'); // plugin root
25
+
26
+ const SKILL_MD = path.join(SKILL_DIR, 'SKILL.md');
27
+ const SKILL_JSON = path.join(SKILL_DIR, 'skill.json');
28
+
29
+ // Resolve the shared audit-axes library from the plugin root, falling back
30
+ // to the script-relative location if the env var isn't set.
31
+ const auditAxesPath = (() => {
32
+ const fromEnv = path.join(PLUGIN_ROOT, 'bin', 'lib', 'audit-axes.mjs');
33
+ if (fs.existsSync(fromEnv)) return fromEnv;
34
+ return path.resolve(__dirname, '..', '..', '..', 'bin', 'lib', 'audit-axes.mjs');
35
+ })();
36
+
37
+ const { runUniversalAxes, formatResults } = await import(pathToFileURL(auditAxesPath).href);
38
+
39
+ // [name, expected-redirect-path or null if already-gone]. The legacy
40
+ // skills these absorbed were never carried into this plugin, so every
41
+ // entry is expected to be absorbed-clean (no directory present).
42
+ const ABSORBED = [
43
+ ['primitive-audit', null],
44
+ ['component-token-audit', null],
45
+ ['llm-bridge-extension', null],
46
+ ['adia-ui-code-bestpractices', null],
47
+ ['bespoke-shell-children', null],
48
+ ['promote-inline-to-module', null],
49
+ ];
50
+
51
+ const CLEAN_STATUSES = ['absorbed-clean', 'absorbed-clean-deleted', 'redirect-ok'];
52
+
53
+ function parseArgs(argv) {
54
+ if (argv.includes('--help') || argv.includes('-h')) {
55
+ console.log(`audit-authoring-roster.mjs — adia-ui-authoring §SelfAudit.
56
+
57
+ USAGE
58
+ node scripts/audit-authoring-roster.mjs [--json] [--strict]
59
+
60
+ FLAGS
61
+ --json Emit findings as JSON instead of human text
62
+ --strict Exit 1 on any drifting axis
63
+ --help Show this help
64
+
65
+ AXES (universal axes from \${CLAUDE_PLUGIN_ROOT}/bin/lib/audit-axes.mjs)
66
+ 1 Manifest enforcement — skill.json files[] matches disk (recursive)
67
+ 2 Reference graph — every markdown link inside SKILL.md resolves
68
+ 3 Capability-menu drift — every §ColdStartTriage row's entry reference exists
69
+ 4 Version-literal parity — SKILL.md frontmatter version matches skill.json
70
+ 5 Phase-label absence — no stale Phase N annotations in skill prose
71
+ 6 Fence-leak detection — no orphan fence markers
72
+ 7 Content currency — references cited by skill.json exist on disk
73
+ 8 CLI helper currency — npm scripts cited by SKILL.md (skips substrate-only)
74
+
75
+ 9 Authoring-roster currency (skill-specific) — every absorbed skill has a
76
+ redirect SKILL.md at the expected path or is absorbed-clean (no directory).
77
+
78
+ EXIT CODES
79
+ 0 All axes clean
80
+ 1 At least one axis drifting (with --strict)
81
+ `);
82
+ process.exit(0);
83
+ }
84
+ return { json: argv.includes('--json'), strict: argv.includes('--strict') };
85
+ }
86
+
87
+ function axis9_authoringRosterCurrency() {
88
+ const findings = [];
89
+ for (const [name, redirectPath] of ABSORBED) {
90
+ if (redirectPath === null) {
91
+ const dir = path.join(SKILLS_ROOT, name);
92
+ if (fs.existsSync(dir)) {
93
+ findings.push({ type: 'unexpected-directory', message: `${name}/ exists but was claimed absorbed-and-gone`, name });
94
+ } else {
95
+ findings.push({ type: 'absorbed-clean', message: `${name}: no directory — correct`, name });
96
+ }
97
+ } else {
98
+ const full = path.join(PLUGIN_ROOT, redirectPath);
99
+ if (!fs.existsSync(full)) {
100
+ const dir = path.dirname(full);
101
+ findings.push({
102
+ type: fs.existsSync(dir) ? 'redirect-missing' : 'absorbed-clean-deleted',
103
+ message: fs.existsSync(dir)
104
+ ? `${name}: expected redirect at ${redirectPath} — not found`
105
+ : `${name}: fully deleted post-soak`,
106
+ name,
107
+ });
108
+ } else {
109
+ const txt = fs.readFileSync(full, 'utf8');
110
+ findings.push(
111
+ /status:\s*redirect/m.test(txt)
112
+ ? { type: 'redirect-ok', message: `${name}: redirect ok`, name }
113
+ : { type: 'redirect-not-tagged', message: `${name}: ${redirectPath} lacks 'status: redirect'`, name }
114
+ );
115
+ }
116
+ }
117
+ }
118
+ const driftCount = findings.filter(f => !CLEAN_STATUSES.includes(f.type)).length;
119
+ return {
120
+ axis: 'authoringRosterCurrency',
121
+ axis_num: 9,
122
+ status: driftCount > 0 ? 'drift' : 'ok',
123
+ findings,
124
+ summary: driftCount > 0 ? `${driftCount} absorbed-skill issue(s)` : 'all absorbed-skill entries clean',
125
+ };
126
+ }
127
+
128
+ function main() {
129
+ const args = parseArgs(process.argv.slice(2));
130
+ const ctx = { skillDir: SKILL_DIR, skillMd: SKILL_MD, skillJson: SKILL_JSON, repoRoot: PLUGIN_ROOT };
131
+ const { results: universal } = runUniversalAxes(ctx);
132
+ const axis9 = axis9_authoringRosterCurrency();
133
+ const allResults = [...universal, axis9];
134
+ const driftCount = allResults.filter(r => r.status === 'drift').length;
135
+
136
+ if (args.json) {
137
+ console.log(JSON.stringify({ results: allResults, driftCount }, null, 2));
138
+ if (args.strict && driftCount > 0) process.exit(1);
139
+ return;
140
+ }
141
+
142
+ console.log(`[audit-authoring-roster] adia-ui-authoring §SelfAudit — ${driftCount} drifting axis/axes`);
143
+ console.log(formatResults(allResults));
144
+ if (driftCount === 0) console.log('\n✓ All clean.');
145
+ if (args.strict && driftCount > 0) process.exit(1);
146
+ }
147
+
148
+ main();
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * build-canonical-pattern-index.mjs — Auto-build canonical-pattern-index.md
4
+ *
5
+ * Walks apps/, catalog/, and playgrounds/ for `.contents.html` files and
6
+ * emits a grouped markdown index used by Mode 8 (composite-demo-protocol.md)
7
+ * Phase 2 (Canonical Survey).
8
+ *
9
+ * Run from the framework monorepo root (the dirs it scans — apps/, catalog/,
10
+ * playgrounds/ — are monorepo roots):
11
+ *
12
+ * node scripts/build-canonical-pattern-index.mjs
13
+ *
14
+ * The output `references/canonical-pattern-index.md` is checked in so agents
15
+ * reading the skill always see the current state without running the script
16
+ * first. REPO_ROOT defaults to the current working directory; OUTPUT is
17
+ * resolved relative to this script (into the skill's own references/).
18
+ */
19
+
20
+ import fs from 'node:fs';
21
+ import path from 'node:path';
22
+ import process from 'node:process';
23
+ import { fileURLToPath } from 'node:url';
24
+
25
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
26
+ const REPO_ROOT = process.env.REPO_ROOT
27
+ ? path.resolve(process.env.REPO_ROOT)
28
+ : process.cwd();
29
+ const OUTPUT = path.join(__dirname, '..', 'references', 'canonical-pattern-index.md');
30
+
31
+ const ROOTS = [
32
+ { path: 'apps/saas/app', label: 'SaaS app dashboards' },
33
+ { path: 'apps/genui/app', label: 'GenUI app routes' },
34
+ { path: 'apps/user-flow/app', label: 'User-flow templates' },
35
+ { path: 'catalog/ui-patterns/app', label: 'UI-pattern atomics (catalog)' },
36
+ { path: 'catalog/page-shells/app', label: 'Page-shell templates (catalog)' },
37
+ { path: 'playgrounds', label: 'Playgrounds' },
38
+ ];
39
+
40
+ function walkContentsHtml(root) {
41
+ const results = [];
42
+ const abs = path.join(REPO_ROOT, root);
43
+ if (!fs.existsSync(abs)) return results;
44
+ function recurse(dir) {
45
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
46
+ const full = path.join(dir, entry.name);
47
+ if (entry.isDirectory()) {
48
+ recurse(full);
49
+ } else if (entry.name.endsWith('.contents.html')) {
50
+ results.push(path.relative(REPO_ROOT, full));
51
+ }
52
+ }
53
+ }
54
+ recurse(abs);
55
+ return results.sort();
56
+ }
57
+
58
+ function lineCount(rel) {
59
+ try {
60
+ return fs.readFileSync(path.join(REPO_ROOT, rel), 'utf8').split('\n').length;
61
+ } catch {
62
+ return 0;
63
+ }
64
+ }
65
+
66
+ function inferUiType(rel) {
67
+ const segments = rel.split('/');
68
+ const slug = segments[segments.length - 2] ?? '';
69
+
70
+ // Heuristics — categorize by slug fragments
71
+ if (/billing|invoice|payment|plan-picker|subscription/i.test(slug)) return 'billing';
72
+ if (/dashboard|kpi|metrics|admin-dashboard/i.test(slug)) return 'dashboard';
73
+ if (/settings|preferences|notification/i.test(slug)) return 'settings';
74
+ if (/onboarding|welcome|first-action/i.test(slug)) return 'onboarding-wizard';
75
+ if (/registration|sign-up|profile/i.test(slug)) return 'registration-wizard';
76
+ if (/sign-in|password|mfa|otp|oauth|forgot|reset/i.test(slug)) return 'auth-flow';
77
+ if (/error|404|500|forbidden|locked|expired|deleted/i.test(slug)) return 'error-page';
78
+ if (/email-change|verify|callback/i.test(slug)) return 'auth-flow';
79
+ if (/integration|connector|api/i.test(slug)) return 'integrations-list';
80
+ if (/members|users|team/i.test(slug)) return 'list-with-detail';
81
+ if (/security|privacy/i.test(slug)) return 'settings';
82
+ if (/marketing|hero|cta|landing/i.test(slug)) return 'marketing';
83
+ if (/agent|reasoning|trace/i.test(slug)) return 'agent-activity';
84
+ if (/chat|conversation|message/i.test(slug)) return 'chat';
85
+ if (/editor|code|preview/i.test(slug)) return 'editor';
86
+ if (/kanban|board/i.test(slug)) return 'kanban';
87
+ if (/table|grid|data/i.test(slug)) return 'data-table';
88
+ if (/command|palette|search/i.test(slug)) return 'command';
89
+ if (/funnel|conversion|step/i.test(slug)) return 'multi-step-funnel';
90
+ if (/modal|confirm|destructive/i.test(slug)) return 'overlay';
91
+ if (/profile-card|user-card/i.test(slug)) return 'list-with-detail';
92
+ if (/feed|activity|timeline/i.test(slug)) return 'feed';
93
+ if (/render|stream|css-channel|a2ui/i.test(slug)) return 'demo-playground';
94
+ return 'other';
95
+ }
96
+
97
+ const UI_TYPE_ORDER = [
98
+ 'billing', 'dashboard', 'settings', 'auth-flow', 'onboarding-wizard',
99
+ 'registration-wizard', 'list-with-detail', 'integrations-list', 'agent-activity',
100
+ 'chat', 'editor', 'kanban', 'data-table', 'command', 'overlay',
101
+ 'multi-step-funnel', 'feed', 'marketing', 'error-page', 'demo-playground', 'other',
102
+ ];
103
+
104
+ const UI_TYPE_GUIDANCE = {
105
+ billing: 'Billing dashboards (current plan, invoices, payment methods, usage). Lift card-ui + section + col-ui + field-ui chain from billing.contents.html.',
106
+ dashboard: 'Admin dashboards (KPI grids, overview cards). Lift grid-ui responsive columns from admin-dashboard.contents.html.',
107
+ settings: 'Settings pages (preferences, security, appearance). Lift card-ui per setting group + col-ui spacing.',
108
+ 'auth-flow': 'Authentication flows (sign-in, MFA, OAuth, password reset). Lift single-column form layout from sign-in.contents.html siblings.',
109
+ 'onboarding-wizard': 'Onboarding multi-step wizards. Lift step-progress + section + cta-row pattern.',
110
+ 'registration-wizard': 'Registration multi-step flows. Lift wizard step + form composition.',
111
+ 'list-with-detail': 'List + detail compositions (entity rows + drawer/modal detail). Lift entity-item + drawer pattern.',
112
+ 'integrations-list': 'Searchable integration/connector grids. Lift grid-ui + card-ui + empty-state-inside-card pattern.',
113
+ 'agent-activity': 'Agent activity / reasoning feeds. Lift activity-feed scroll + collapsed-reasoning pattern.',
114
+ chat: 'Chat surfaces (thread, composer, sidebar). Lift chat-streaming-surface composition.',
115
+ editor: 'Editor panes (code, preview, toolbar). Lift editor-shell composition.',
116
+ kanban: 'Kanban / column-based boards. Lift kanban-board-3col pattern.',
117
+ 'data-table': 'Data tables with badges/inline actions. Lift users-table-badge composition.',
118
+ command: 'Command palette / global search. Lift command-palette overlay pattern.',
119
+ overlay: 'Modals, drawers, popovers. Lift destructive-confirm-modal pattern for confirmations.',
120
+ 'multi-step-funnel': 'Multi-step conversion funnels. Lift conversion-funnel-6step composition.',
121
+ feed: 'Activity / event feeds. Lift activity-feed composition.',
122
+ marketing: 'Marketing pages, hero CTAs. Lift marketing-hero-cta composition.',
123
+ 'error-page': 'Error states (404, 500, forbidden, expired). Lift centered single-card error pattern.',
124
+ 'demo-playground': 'Internal demo + playground surfaces. Use these as reference for composition style; not always production-grade.',
125
+ other: 'Misc canonicals. Inspect contents.html to determine UI type.',
126
+ };
127
+
128
+ function buildMarkdown(grouped) {
129
+ const lines = [
130
+ '# Canonical Pattern Index — survey targets for Mode 8 (composite-demo-protocol.md)',
131
+ '',
132
+ '**Auto-generated** by `scripts/build-canonical-pattern-index.mjs`. Do not edit by hand — re-run the build script after adding new canonicals to `apps/`, `catalog/`, or `playgrounds/`.',
133
+ '',
134
+ `**Total canonical \`.contents.html\` files**: ${grouped.totalFiles}`,
135
+ '',
136
+ '## How to use this index',
137
+ '',
138
+ '1. From Phase 1 of [composite-demo-protocol.md](composite-demo-protocol.md), name the UI type.',
139
+ '2. Find the matching section below.',
140
+ '3. Read every `.contents.html` listed (or the closest 2-3 if the section has many).',
141
+ '4. Extract primitive composition per Phase 3 of the protocol.',
142
+ '5. Cite the path in your demo\'s `<!-- Pattern source: ... -->` comment.',
143
+ '',
144
+ '---',
145
+ '',
146
+ ];
147
+
148
+ for (const uiType of UI_TYPE_ORDER) {
149
+ const files = grouped.byType[uiType];
150
+ if (!files || files.length === 0) continue;
151
+ lines.push(`## ${uiType} (${files.length})`);
152
+ lines.push('');
153
+ lines.push(`> ${UI_TYPE_GUIDANCE[uiType]}`);
154
+ lines.push('');
155
+ for (const f of files) {
156
+ const lc = lineCount(f.path);
157
+ lines.push(`- \`${f.path}\` — ${lc} lines (from ${f.root})`);
158
+ }
159
+ lines.push('');
160
+ }
161
+
162
+ lines.push('---');
163
+ lines.push('');
164
+ lines.push('## Maintenance');
165
+ lines.push('');
166
+ lines.push('Re-build this index:');
167
+ lines.push('');
168
+ lines.push('```bash');
169
+ lines.push('node scripts/build-canonical-pattern-index.mjs');
170
+ lines.push('```');
171
+ lines.push('');
172
+ lines.push('If a heuristic misclassifies a path (the file lands in `other` or the wrong UI type), update the `inferUiType()` regex in `scripts/build-canonical-pattern-index.mjs`.');
173
+ lines.push('');
174
+ return lines.join('\n');
175
+ }
176
+
177
+ function main() {
178
+ const grouped = { byType: {}, totalFiles: 0 };
179
+
180
+ for (const { path: rootPath, label } of ROOTS) {
181
+ const files = walkContentsHtml(rootPath);
182
+ for (const f of files) {
183
+ const uiType = inferUiType(f);
184
+ (grouped.byType[uiType] ??= []).push({ path: f, root: label });
185
+ grouped.totalFiles++;
186
+ }
187
+ }
188
+
189
+ const md = buildMarkdown(grouped);
190
+ fs.writeFileSync(OUTPUT, md);
191
+ console.log(`Wrote ${OUTPUT}`);
192
+ console.log(` ${grouped.totalFiles} canonical .contents.html files indexed`);
193
+ for (const uiType of UI_TYPE_ORDER) {
194
+ const count = (grouped.byType[uiType] || []).length;
195
+ if (count > 0) console.log(` ${uiType}: ${count}`);
196
+ }
197
+ }
198
+
199
+ main();
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "adia-ui-authoring",
3
+ "version": "1.9.2",
4
+ "description": "Author or modify code INSIDE the adia-ui (@adia-ai) monorepo — primitives in packages/web-components/, composite shells in packages/web-modules/, inline page content promoted to reusable modules, composite/module demos (.examples.html, .contents.html), the @adia-ai/llm bridge, the trait catalog, .a2ui.json sidecars, yaml SoTs — clearing the four-axis contract before review and VERIFYING against the built/rendered artifact (build:components --verify, the primitive's demo page, the rendered-DOM probe), never 'looks done'. Use whenever the user wants to ADD A NEW PRIMITIVE / MODIFY A COMPONENT / FIX A YAML / PROMOTE INLINE TO MODULE / UPDATE A SHELL / AUTHOR A DEMO FOR A COMPOSITE OR MODULE / COMPOSE EXAMPLES.HTML / EXTEND THE LLM BRIDGE — the work happens on packages/* source, not on consumer code. Triggers on 'add a primitive', 'modify table-ui yaml', 'author a new web-module shell', 'trait catalog regenerated wrong', 'promote inline CSS to a module', 'audit the four-axis contract', '.a2ui.json sidecar is stale', 'set up LLM-bridge surface', 'author a demo for X', 'compose examples.html for Y', any edit under packages/web-modules/**/*.examples.html or **/*.contents.html. Does NOT trigger for: composing screens FROM existing primitives in consumer/app code (the adia-ui-factory plugin), cutting a release (adia-ui-release), generation-pipeline internals (adia-ui-a2ui), scoring generated UI quality (adia-ui-gen-review), broad cross-surface QA (adia-ui-dogfood). Absorbs primitive-audit + component-token-audit + code-bestpractices + bespoke-shell-children + promote-inline-to-module + llm-bridge-extension.",
5
+ "status": "stable",
6
+ "authors": ["kim.granlund"],
7
+ "codeowners": [],
8
+ "tags": ["adia-ui", "web-components", "web-modules", "design-system", "component-authoring", "tokens", "light-dom", "scope-css", "lifecycle", "form-associated", "shell-patterns", "inline-to-module", "llm-bridge", "composite-demo"],
9
+ "depends_on": [],
10
+ "peer_skills": ["adia-ui-release", "adia-ui-a2ui", "adia-ui-llm", "adia-ui-gen-review", "adia-ui-dogfood", "ui-audit-coherence", "analyze-css", "ui-build-components"],
11
+ "environment": {
12
+ "portable": false,
13
+ "requires": ["the adia-ui (@adia-ai) framework monorepo with packages/web-components/, packages/web-modules/, packages/llm/, packages/a2ui/, and the component-token-contract spec"],
14
+ "rationale": "Every mode operates on monorepo-specific source layout, build scripts, and the four-axis contract; it does not apply to consumer repos."
15
+ },
16
+ "files": [
17
+ "SKILL.md",
18
+ "CHANGELOG.md",
19
+ "skill.json",
20
+ "references/primitive-audit.md",
21
+ "references/authoring-cycle.md",
22
+ "references/code-style.md",
23
+ "references/api-contract.md",
24
+ "references/yaml-contract.md",
25
+ "references/css-patterns.md",
26
+ "references/lifecycle-patterns.md",
27
+ "references/shell-patterns.md",
28
+ "references/module-promotion.md",
29
+ "references/token-contract.md",
30
+ "references/llm-bridge.md",
31
+ "references/teach-protocol.md",
32
+ "references/composite-demo-protocol.md",
33
+ "references/canonical-pattern-index.md",
34
+ "references/common-gotchas.md",
35
+ "references/anti-patterns.md",
36
+ "references/worked-example.md",
37
+ "scripts/audit-authoring-roster.mjs",
38
+ "scripts/build-canonical-pattern-index.mjs",
39
+ "evals/routing-corpus.json",
40
+ "evals/adversarial-design-plan-gates.json",
41
+ "assets/case-studies/maxtokens-32768-discovery.md",
42
+ "assets/case-studies/admin-shell-decomposition.md",
43
+ "assets/case-studies/theme-panel-promotion.md"
44
+ ]
45
+ }
@@ -0,0 +1,17 @@
1
+ # Changelog — adia-ui-dogfood
2
+
3
+ ## [0.1.0] stable — 2026-06-03
4
+
5
+ **MINOR** — first cut as a plugin skill. Ported from the framework monorepo's maintainer skill `dogfood-sweep`, renamed and de-repo'd: absolute paths stripped, shared-infra references rewritten to `${CLAUDE_PLUGIN_ROOT}/...`, the component visual probe bundled at `scripts/analyze.mjs` (repo-root resolved from `$ADIA_REPO_ROOT` / cwd, not a path relative to the install), instance data dropped. No procedural changes to the 6 modes.
6
+
7
+ SKILL.md carries all 6 modes inline (component visual probe / app-shell QA / HTML typo sweep / native-primitive leak / admin-shell composition / component anatomy + card header), with a cold-start triage menu, §Plan-Execute-Verify, §SelfAudit, §Teach, and §FileMap added to match the rollup-family conventions. Modes 2 / 4 / 5 drive **repo-local** audit scripts that ship in the monorepo (`scripts/dev/audit-app-shells.mjs`, `audit-native-primitive-leak.mjs`, `audit-shell-composition.mjs`); modes 3 / 6 use inline shell snippets.
8
+
9
+ ### Reconstructed history (pre-port)
10
+
11
+ - Added probe #6 (missing component CSS detection) to mode 1 after the swap-to-primitive-but-forget-the-link class slipped past a real PR. The bug class: an agent uses `<button-ui>` markup but forgets the `<link rel="stylesheet">` for the button component CSS; the element registers, the markup looks right, and the control renders unstyled.
12
+
13
+ - Native-primitive-leak audit (mode 4) intent-marker detection window widened from 80 → 200 chars after a peer agent found that realistic preceding-line comments (indent + comment prefix + reason text + closing `-->` + newline) sat at exactly the 80-char boundary and were not detected.
14
+
15
+ - Mode 6 (Component Anatomy + Card Header Sweep) added: card-ui `<header><div>` wrapper anti-pattern + missing anatomy sections per the anatomy-sweep gate's expectations.
16
+
17
+ - Mode 1 (component visual probe via Chromium) was the initial skill. Modes 2–5 were absorbed from the substrate-side `scripts/dev/audit-*.mjs` work over multiple cycles. The skill grew its 6-mode catalog organically.
@@ -0,0 +1,62 @@
1
+ # adia-ui-dogfood
2
+
3
+ Six-mode static + visual QA sweep for the adia-ui framework substrate. The agent-facing skill body — all six modes, triage rules, fix recipes, and verify targets — is in `SKILL.md`. This README covers the one bundled script.
4
+
5
+ ## The component visual probe (`scripts/analyze.mjs`)
6
+
7
+ Walks every `site/components/*` demo page in headless Chromium and runs visual-correctness probes that type-checks and tests don't catch:
8
+
9
+ | # | Probe | Bug class it detects |
10
+ | --- | --- | --- |
11
+ | 1 | Zero-area | Element collapsed (parent `display:none`, toolbar overflow spilled it, layout glitch) |
12
+ | 2 | Transparent fill | `[data-swatch]` / variant pill / button / chart indicator whose computed bg is `rgba(0,0,0,0)` — fallback token doesn't resolve (the chart-legend `--chart-N` class) |
13
+ | 3 | Empty control | `input-ui` / `search-ui` whose `connected()` should have stamped internals but didn't |
14
+ | 4 | Synonym-attr / synonym-slot drift | Markers from the attribute-api-migration convention (`avatar-ui[name]`, `grid-ui[cols]`, `card-ui [slot=meta]`, etc.) |
15
+ | 5 | Alert flex-row | `alert-ui` with multiple bare `<text-ui>` children (need `<col-ui slot="content">` wrap) |
16
+ | 6 | Missing component CSS / unstyled popover | a `*-ui` tag on the page with no matching stylesheet loaded; an open popover with transparent bg + zero padding |
17
+ | 7 | Console | Every `console.error` + `console.warn` during page load + 800ms settling |
18
+
19
+ Output: a severity-ranked markdown report at `docs/reports/dogfooding-YYYY-MM-DD.md` under the repo root.
20
+
21
+ ## Run locally
22
+
23
+ Run from the framework monorepo checkout (the script resolves the repo root from `$ADIA_REPO_ROOT` if set, else the current working directory):
24
+
25
+ ```bash
26
+ # Terminal 1
27
+ npm run dev
28
+
29
+ # Terminal 2 (S = ${CLAUDE_PLUGIN_ROOT}/skills/adia-ui-dogfood/scripts/analyze.mjs)
30
+ node "$S" # full sweep
31
+ node "$S" --filter chart-legend # one page
32
+ node "$S" --port 5174 # custom port
33
+ node "$S" --out /tmp/r.md # custom path
34
+ ```
35
+
36
+ Exit code: **1** if any **critical** finding, **0** otherwise. CI-friendly.
37
+
38
+ ## Schedule as a remote agent
39
+
40
+ The script is the data gatherer. A scheduled agent wraps it with git orchestration: check out the repo, start the dev server, run the script, triage findings, commit/PR. The full agent procedure — env setup, the 3-question triage gate, the ≤5-fix-per-PR blast-radius cap, the verify gate, and the PR shape — is documented in `SKILL.md` (§ Component Dogfood + §Plan-Execute-Verify). Weekly cadence is a reasonable default; pages drift slowly.
41
+
42
+ Hard rules carried from the source skill:
43
+
44
+ - Never touch a component's deprecation-handler string when sweeping the attribute it deprecates.
45
+ - Never edit historic MIGRATION GUIDE sections; only the active version section.
46
+ - Don't fix more than 5 critical findings in one PR — leave the rest for follow-up so humans can review fix shape before scaling.
47
+
48
+ ## False positives + tuning
49
+
50
+ The probes are intentionally narrow. Known places where "transparent fill" is by design (and shouldn't be added to `COLORED_SELECTORS`):
51
+
52
+ - `tag-ui` without a variant (`muted` / default) — bg is correctly `--a-bg-muted`, not transparent.
53
+ - `button-ui[variant=ghost]` — transparent by design.
54
+ - `[data-swatch]` for `chart-legend-ui[shape=dashed]` — intentionally transparent bg + colored `border-top`. The probe handles this case.
55
+
56
+ If a finding is a known false positive, add the parent component or selector to the skip-list rather than removing it from `COLORED_SELECTORS` (preserves coverage on the canonical case).
57
+
58
+ ## When to revisit the probe set
59
+
60
+ - New component ships → add to `STAMP_CONTRACTS` if it has internal stamping logic.
61
+ - New synonym-attribute drift class documented in the attribute-api-migration convention → add to `DRIFT_MARKERS`.
62
+ - A class of bugs slips past the analyzer in a real PR → add a probe for that bug class first, _then_ fix it. Test for the test.