@event4u/agent-config 9.11.0 → 9.13.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +80 -204
- package/README.md +8 -1
- package/dist/agent-src/commands/fix/ci.md +29 -0
- package/dist/agent-src/commands/pr/create.md +60 -0
- package/dist/agent-src/contexts/authority/kernel-rule-edits.md +18 -2
- package/dist/agent-src/rules/active-remediation.md +0 -2
- package/dist/agent-src/rules/architecture.md +0 -1
- package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -4
- package/dist/agent-src/rules/autonomous-execution.md +1 -2
- package/dist/agent-src/rules/broken-access-control.md +0 -2
- package/dist/agent-src/rules/code-comment-discipline.md +0 -3
- package/dist/agent-src/rules/code-provenance.md +0 -3
- package/dist/agent-src/rules/communication-through-line.md +2 -3
- package/dist/agent-src/rules/content-quoting-floor.md +0 -2
- package/dist/agent-src/rules/context-hygiene.md +1 -3
- package/dist/agent-src/rules/decision-revisit-gate.md +0 -2
- package/dist/agent-src/rules/design-fidelity.md +30 -1
- package/dist/agent-src/rules/domain-adoption-policy.md +0 -3
- package/dist/agent-src/rules/downstream-changes.md +10 -1
- package/dist/agent-src/rules/external-reference-deep-dive.md +0 -7
- package/dist/agent-src/rules/fast-path-marker-visibility.md +0 -1
- package/dist/agent-src/rules/git-history-discipline.md +0 -7
- package/dist/agent-src/rules/guidelines.md +0 -2
- package/dist/agent-src/rules/improve-before-implement.md +4 -2
- package/dist/agent-src/rules/invite-challenge.md +0 -4
- package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -2
- package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
- package/dist/agent-src/rules/minimal-safe-diff.md +2 -2
- package/dist/agent-src/rules/missing-tool-handling.md +0 -1
- package/dist/agent-src/rules/no-attribution-footers.md +0 -3
- package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +8 -5
- package/dist/agent-src/rules/no-pr-progress-comments.md +1 -3
- package/dist/agent-src/rules/no-roadmap-references.md +0 -2
- package/dist/agent-src/rules/output-discipline.md +0 -1
- package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -2
- package/dist/agent-src/rules/preservation-guard.md +0 -3
- package/dist/agent-src/rules/role-mode-adherence.md +0 -1
- package/dist/agent-src/rules/secret-vcs-guard.md +0 -2
- package/dist/agent-src/rules/senior-engineering-discipline.md +0 -2
- package/dist/agent-src/rules/session-canary.md +0 -2
- package/dist/agent-src/rules/size-enforcement.md +0 -5
- package/dist/agent-src/rules/source-confidentiality.md +0 -3
- package/dist/agent-src/rules/source-discovery-gate.md +0 -2
- package/dist/agent-src/rules/think-before-action.md +3 -3
- package/dist/agent-src/rules/token-budget-discipline.md +0 -1
- package/dist/agent-src/rules/token-efficiency.md +1 -2
- package/dist/agent-src/rules/tool-safety.md +0 -1
- package/dist/agent-src/rules/user-interaction.md +0 -3
- package/dist/agent-src/rules/user-interrupt-priority.md +0 -1
- package/dist/agent-src/skills/agent-docs-writing/SKILL.md +8 -0
- package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +1 -0
- package/dist/agent-src/skills/analysis-skill-router/SKILL.md +55 -86
- package/dist/agent-src/skills/character-consistency/SKILL.md +7 -4
- package/dist/agent-src/skills/decision-record/SKILL.md +8 -0
- package/dist/agent-src/skills/design-intelligence/SKILL.md +27 -1
- package/dist/agent-src/skills/design-intelligence/data/font-pairings-reference.csv +74 -74
- package/dist/agent-src/skills/design-intelligence/data/manifest.json +2 -0
- package/dist/agent-src/skills/design-review/SKILL.md +11 -0
- package/dist/agent-src/skills/design-system-capture/reference/design-system-json.md +8 -0
- package/dist/agent-src/skills/design-tokens/scripts/tokens.ts +0 -7
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +34 -3
- package/dist/agent-src/skills/fe-design/SKILL.md +10 -0
- package/dist/agent-src/skills/motion-choreographer/SKILL.md +7 -4
- package/dist/agent-src/skills/overbuild-review-lens/SKILL.md +201 -0
- package/dist/agent-src/skills/performance/SKILL.md +14 -0
- package/dist/agent-src/skills/pixar-storyteller/SKILL.md +8 -5
- package/dist/agent-src/skills/scene-expander/SKILL.md +9 -6
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +10 -0
- package/dist/agent-src/skills/typography-system/SKILL.md +55 -11
- package/dist/agent-src/skills/ui-apply-generic/SKILL.md +180 -0
- package/dist/agent-src/skills/universal-project-analysis/SKILL.md +14 -37
- package/dist/agent-src/skills/video-director/SKILL.md +9 -6
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +162 -17
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +118 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +49 -6
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +9 -5
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +182 -29
- package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +311 -24
- package/dist/agent-src/templates/scripts/work_engine/state.ts +55 -0
- package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
- package/dist/cli-delegate/{chunk-IR7P7JWA.js → chunk-A3HJ6NTI.js} +271 -59
- package/dist/cli-delegate/chunk-EJYIGZ3T.js +125 -0
- package/dist/cli-delegate/{chunk-RDGRHAAB.js → chunk-HYWSRNUX.js} +6 -86
- package/dist/cli-delegate/{chunk-YMFO6FDN.js → chunk-QFKQLQ7X.js} +313 -81
- package/dist/cli-delegate/{chunk-4SV3XGFA.js → chunk-TEGJU2JX.js} +7 -9
- package/dist/cli-delegate/chunk-TJIAM5FW.js +133 -0
- package/dist/cli-delegate/cmd_conformance.js +4 -7
- package/dist/cli-delegate/cmd_doctor.js +3 -5
- package/dist/cli-delegate/cmd_explain.js +153 -85
- package/dist/cli-delegate/cmd_export.js +5 -3
- package/dist/cli-delegate/cmd_fleet.js +2 -1
- package/dist/cli-delegate/cmd_preflight.js +6 -123
- package/dist/cli-delegate/cmd_prune.js +5 -3
- package/dist/cli-delegate/cmd_settings_migrate.js +5 -3
- package/dist/cli-delegate/cmd_sync.js +5 -3
- package/dist/cli-delegate/cmd_uninstall.js +6 -5
- package/dist/cli-delegate/cmd_validate.js +5 -3
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +116 -72
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +7 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +6 -4
- package/dist/hooks/dispatch.js +174 -13
- package/dist/install/install.mjs +605 -412
- package/dist/install/ruleInScope.js +123 -0
- package/dist/install/ruleInScope.js.map +1 -0
- package/dist/install/rule_scope.js +2 -2
- package/dist/install/rule_scope.js.map +1 -1
- package/dist/install/wizard-plan.js +10 -1
- package/dist/install/wizard-plan.js.map +1 -1
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +710 -2491
- package/dist/router.json +1 -1
- package/dist/scripts/condense.js +8 -24
- package/dist/scripts/condense.js.map +1 -1
- package/docs/MIGRATION.md +1 -1
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +71 -0
- package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +24 -1
- package/docs/guidelines/code-clarity.md +9 -2
- package/docs/guidelines/design-fidelity-mechanics.md +58 -0
- package/llms.txt +63 -27
- package/package.json +4 -4
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +162 -17
- package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +118 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +49 -6
- package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +9 -5
- package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +182 -29
- package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +311 -24
- package/src/agent-src/templates/scripts/work_engine/state.ts +55 -0
- package/src/config/agent-settings.template.yml +8 -0
- package/src/install/ruleInScope.ts +133 -0
- package/src/install/rule_scope.ts +2 -2
- package/src/install/wizard-plan.ts +11 -1
- package/src/scripts/_lib/counted_probe.ts +142 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +38 -2
- package/src/scripts/_lib/overbuild_lens_contract.ts +196 -0
- package/src/scripts/_lib/release_scope.ts +207 -0
- package/src/scripts/ai_council/stance_tally.ts +37 -2
- package/src/scripts/audit_auto_rules.ts +9 -9
- package/src/scripts/audit_likelihood.ts +3 -3
- package/src/scripts/audit_overlap.ts +2 -2
- package/src/scripts/audit_skill_overlap.ts +233 -95
- package/src/scripts/audit_skill_overlap_allowlist.json +4 -0
- package/src/scripts/build_proof.ts +15 -1
- package/src/scripts/check_dependency_floors.ts +16 -6
- package/src/scripts/check_gate_coverage.ts +6 -6
- package/src/scripts/check_installer_import_purity.ts +295 -0
- package/src/scripts/check_kernel_rule_bundle.ts +5 -4
- package/src/scripts/check_token_quality_golden.ts +0 -18
- package/src/scripts/code_graph/loader.ts +35 -6
- package/src/scripts/compile_router.ts +3 -8
- package/src/scripts/condense.ts +9 -30
- package/src/scripts/explain_run.ts +0 -1
- package/src/scripts/generate_pack_manifests.ts +3 -20
- package/src/scripts/hooks/block_kernel_rule_writes.ts +145 -10
- package/src/scripts/hooks/block_no_verify.ts +101 -0
- package/src/scripts/install-hooks.sh +36 -4
- package/src/scripts/install.ts +210 -5
- package/src/scripts/lint_agent_security.ts +5 -4
- package/src/scripts/lint_framework_leakage_allowlist.json +2 -2
- package/src/scripts/lint_regression.ts +92 -1
- package/src/scripts/lint_skill_descriptions.ts +93 -5
- package/src/scripts/lint_ui_stack_bundles.ts +31 -0
- package/src/scripts/project_thin_rules.ts +2 -2
- package/src/scripts/release.ts +107 -3
- package/src/scripts/resolve_lint_scope.ts +53 -0
- package/src/scripts/router_telemetry.ts +0 -5
- package/src/scripts/runtime_dispatcher.ts +40 -0
- package/src/scripts/schemas/pack.schema.json +1 -5
- package/src/scripts/schemas/rule.schema.json +1 -2
- package/src/scripts/self_review_gate.ts +15 -73
- package/src/scripts/skill_linter.ts +93 -11
- package/src/scripts/sweep_dead_scan_roots.ts +550 -0
- package/src/scripts/trigger_coverage.ts +11 -37
- package/dist/cli-delegate/chunk-7DSAMZFU.js +0 -356
- package/dist/cli-delegate/chunk-BJGXZNPM.js +0 -266
- package/dist/cli-delegate/chunk-TFG57JJM.js +0 -1969
|
@@ -39,14 +39,24 @@ export interface StackBundle {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
|
-
* The
|
|
43
|
-
* in every install
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
42
|
+
* The stack-neutral build bundle. All three live in `engineering-base`, so they
|
|
43
|
+
* are present in every install.
|
|
44
|
+
*
|
|
45
|
+
* `ui-apply-generic` leads: it carries the implementation contract that used to
|
|
46
|
+
* exist only inside the framework executors, and it pulls framework idiom from
|
|
47
|
+
* the 16-stack corpus rather than from prose. That is what turns this lane from
|
|
48
|
+
* an honest refusal into actual coverage for Svelte, Astro, Angular and
|
|
49
|
+
* anything future — without minting a skill per framework.
|
|
50
|
+
*
|
|
51
|
+
* The other two are the companions it composes with: `ui-component-architect`
|
|
52
|
+
* ("the same lens applies to Blade, Livewire, React, or Vue trees") and
|
|
53
|
+
* `tailwind-engineer` ("the **how** for any Tailwind-stack screen").
|
|
48
54
|
*/
|
|
49
|
-
const GENERIC_BUILD: ReadonlyArray<string> = [
|
|
55
|
+
const GENERIC_BUILD: ReadonlyArray<string> = [
|
|
56
|
+
'ui-apply-generic',
|
|
57
|
+
'ui-component-architect',
|
|
58
|
+
'tailwind-engineer',
|
|
59
|
+
];
|
|
50
60
|
|
|
51
61
|
/** `design-review` is stack-neutral and ships in `engineering-base`. */
|
|
52
62
|
const GENERIC_REVIEW: ReadonlyArray<string> = ['design-review'];
|
|
@@ -57,6 +67,16 @@ const GENERIC_REVIEW: ReadonlyArray<string> = ['design-review'];
|
|
|
57
67
|
* contract) and consume this map only to name the skills in the halt body.
|
|
58
68
|
*/
|
|
59
69
|
export const STACK_BUNDLES: Readonly<Record<string, StackBundle>> = {
|
|
70
|
+
// An unmodelled framework routes to the generic lane rather than refusing:
|
|
71
|
+
// `ui-apply-generic` queries the stack corpus, which covers svelte, astro,
|
|
72
|
+
// angular, nuxt and eleven more. Refusing while holding that corpus is the
|
|
73
|
+
// "an honest refusal is not coverage" defect. A genuine ambiguity still
|
|
74
|
+
// refuses — see `is_ambiguous_stack`.
|
|
75
|
+
unknown: {
|
|
76
|
+
build: GENERIC_BUILD,
|
|
77
|
+
review: GENERIC_REVIEW,
|
|
78
|
+
pack_agnostic: true,
|
|
79
|
+
},
|
|
60
80
|
'blade-livewire-flux': {
|
|
61
81
|
build: ['flux', 'livewire', 'blade-ui'],
|
|
62
82
|
review: GENERIC_REVIEW,
|
|
@@ -113,7 +133,7 @@ export const STACK_BUNDLES: Readonly<Record<string, StackBundle>> = {
|
|
|
113
133
|
* definite idiom and the package has no executor for it, so the result must not
|
|
114
134
|
* read as Vue support.
|
|
115
135
|
*/
|
|
116
|
-
export const GENERIC_LANES: ReadonlySet<string> = new Set(['vue', 'plain']);
|
|
136
|
+
export const GENERIC_LANES: ReadonlySet<string> = new Set(['vue', 'plain', 'unknown']);
|
|
117
137
|
|
|
118
138
|
/** Lanes where the stack-neutral pair is the correct answer, not a shortfall. */
|
|
119
139
|
const NATIVELY_GENERIC_LANES: ReadonlySet<string> = new Set(['plain']);
|
|
@@ -126,31 +146,81 @@ const NATIVELY_GENERIC_LANES: ReadonlySet<string> = new Set(['plain']);
|
|
|
126
146
|
*/
|
|
127
147
|
export const UNSUPPORTED_LANE = 'unknown';
|
|
128
148
|
|
|
129
|
-
/**
|
|
130
|
-
|
|
131
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Return the bundle for a stack state.
|
|
151
|
+
*
|
|
152
|
+
* Composition wins when the state carries axes; the hand-written map is the
|
|
153
|
+
* fallback for a legacy `state.stack` persisted before Detection v2. Keeping
|
|
154
|
+
* both is not indecision — a state file written by an older run must still
|
|
155
|
+
* dispatch, and the map is exactly what it expects.
|
|
156
|
+
*/
|
|
157
|
+
export function bundle_for(stack_state: unknown): StackBundle {
|
|
158
|
+
if (typeof stack_state === 'object' && stack_state !== null) {
|
|
159
|
+
const raw = (stack_state as Record<string, unknown>)['axes'];
|
|
160
|
+
if (typeof raw === 'object' && raw !== null) {
|
|
161
|
+
return compose_bundle(raw as Record<string, string>);
|
|
162
|
+
}
|
|
163
|
+
const label = (stack_state as Record<string, unknown>)['frontend'];
|
|
164
|
+
if (typeof label === 'string' && label in STACK_BUNDLES) {
|
|
165
|
+
return STACK_BUNDLES[label] as StackBundle;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (typeof stack_state === 'string' && stack_state in STACK_BUNDLES) {
|
|
169
|
+
return STACK_BUNDLES[stack_state] as StackBundle;
|
|
170
|
+
}
|
|
171
|
+
return STACK_BUNDLES['plain'] as StackBundle;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* True when the `unknown` label came from a question, not from a coverage gap.
|
|
176
|
+
*
|
|
177
|
+
* `unknown` carries two different situations and they need opposite handling:
|
|
178
|
+
*
|
|
179
|
+
* - **An unmodelled framework** (svelte, astro, angular …). Since
|
|
180
|
+
* `ui-apply-generic` exists and queries the stack corpus, refusing here would
|
|
181
|
+
* be the "an honest refusal is not coverage" defect — the corpus almost
|
|
182
|
+
* certainly HAS the stack. Route to the generic lane, naming the framework.
|
|
183
|
+
* - **A genuine ambiguity** — two SPA frameworks in one manifest, or several
|
|
184
|
+
* workspace roots. No executor can fix that: the open question is *which
|
|
185
|
+
* project is this*, and only the caller can answer. Refuse.
|
|
186
|
+
*
|
|
187
|
+
* `StackResult.ambiguity` is what distinguishes them, so the check is on the
|
|
188
|
+
* ambiguity list rather than on the label.
|
|
189
|
+
*/
|
|
190
|
+
export function is_ambiguous_stack(stack_state: unknown): boolean {
|
|
191
|
+
if (typeof stack_state !== 'object' || stack_state === null) return false;
|
|
192
|
+
const raw = (stack_state as Record<string, unknown>)['ambiguity'];
|
|
193
|
+
return Array.isArray(raw) && raw.length > 0;
|
|
132
194
|
}
|
|
133
195
|
|
|
134
196
|
/**
|
|
135
|
-
* Questions for the refusal halt
|
|
197
|
+
* Questions for the refusal halt when detection cannot say what the project is.
|
|
136
198
|
*
|
|
137
|
-
* Not a directive — there is nothing honest to dispatch to
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
* between the stack-neutral floor and stopping.
|
|
199
|
+
* Not a directive — there is nothing honest to dispatch to, because the missing
|
|
200
|
+
* input is a decision rather than a skill. `conflicts` are echoed verbatim from
|
|
201
|
+
* `StackResult.ambiguity` so the user sees the actual collision.
|
|
141
202
|
*/
|
|
142
|
-
export function unsupported_stack_questions(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
'
|
|
150
|
-
'framework; say so in the result.',
|
|
151
|
-
'> 2. Abort — drop this UI request and add a lane first ' +
|
|
152
|
-
'(`docs/contracts/ui-stack-extension.md`).',
|
|
203
|
+
export function unsupported_stack_questions(
|
|
204
|
+
step: string,
|
|
205
|
+
conflicts: ReadonlyArray<string> = [],
|
|
206
|
+
): string[] {
|
|
207
|
+
const lines = [
|
|
208
|
+
'> Detection found conflicting signals, so it will not pick a stack for ' +
|
|
209
|
+
`you at \`${step}\`. Guessing here is the failure this halt exists ` +
|
|
210
|
+
'to prevent.',
|
|
153
211
|
];
|
|
212
|
+
for (const c of conflicts) {
|
|
213
|
+
lines.push(`> - \`${c}\``);
|
|
214
|
+
}
|
|
215
|
+
lines.push(
|
|
216
|
+
'> 1. Name the project to build for — the workspace path, or which ' +
|
|
217
|
+
'framework owns this surface. Detection re-runs against that scope.',
|
|
218
|
+
'> 2. Continue on the stack-neutral floor anyway — `ui-apply-generic` ' +
|
|
219
|
+
'plus its companions. Output will not be idiomatic for either ' +
|
|
220
|
+
'framework; say so in the result.',
|
|
221
|
+
'> 3. Abort — drop this UI request.',
|
|
222
|
+
);
|
|
223
|
+
return lines;
|
|
154
224
|
}
|
|
155
225
|
|
|
156
226
|
/**
|
|
@@ -161,8 +231,19 @@ export function unsupported_stack_questions(step: string): string[] {
|
|
|
161
231
|
* framework-specific executor says that outright rather than presenting the
|
|
162
232
|
* generic pair as if it were stack support.
|
|
163
233
|
*/
|
|
164
|
-
export function bundle_line(
|
|
165
|
-
|
|
234
|
+
export function bundle_line(
|
|
235
|
+
stack_state: unknown,
|
|
236
|
+
role: 'build' | 'review',
|
|
237
|
+
stack_label?: string,
|
|
238
|
+
): string {
|
|
239
|
+
const bundle = bundle_for(stack_state);
|
|
240
|
+
const stack =
|
|
241
|
+
stack_label ??
|
|
242
|
+
(typeof stack_state === 'string'
|
|
243
|
+
? stack_state
|
|
244
|
+
: String(
|
|
245
|
+
(stack_state as Record<string, unknown> | null)?.['frontend'] ?? 'plain',
|
|
246
|
+
));
|
|
166
247
|
const skills = role === 'review' ? bundle.review : bundle.build;
|
|
167
248
|
const rendered = skills.map((name) => `\`${name}\``).join(' + ');
|
|
168
249
|
if (NATIVELY_GENERIC_LANES.has(stack)) {
|
|
@@ -177,3 +258,75 @@ export function bundle_line(stack: string, role: 'build' | 'review'): string {
|
|
|
177
258
|
}
|
|
178
259
|
return `> Skills: ${rendered}.`;
|
|
179
260
|
}
|
|
261
|
+
|
|
262
|
+
// ── Axis-driven composition ─────────────────────────────────────────────────
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Overlay table: one axis value → the skills that add its idiom.
|
|
266
|
+
*
|
|
267
|
+
* This is what replaces lane enumeration. A lane is no longer a hand-written
|
|
268
|
+
* bundle but the base plus whatever the axes turn on, so a stack the package has
|
|
269
|
+
* never named still composes: `reactivity: livewire` pulls Livewire **with or
|
|
270
|
+
* without** Flux, and `component_lib: flux` layers Flux on top. The two
|
|
271
|
+
* full-match lanes fall out as a special case — that identity is the regression
|
|
272
|
+
* witness, asserted in `ui_lane_matrix.test.ts`.
|
|
273
|
+
*
|
|
274
|
+
* Only axis values with a real overlay skill appear. Everything else is served
|
|
275
|
+
* by the base plus its corpus query, which is the point: coverage without a
|
|
276
|
+
* skill per framework.
|
|
277
|
+
*/
|
|
278
|
+
const _AXIS_OVERLAYS: Readonly<Record<string, ReadonlyArray<string>>> = {
|
|
279
|
+
'reactivity:livewire': ['livewire'],
|
|
280
|
+
'reactivity:react': ['react-shadcn-ui'],
|
|
281
|
+
'component_lib:flux': ['flux'],
|
|
282
|
+
'component_lib:shadcn': ['react-shadcn-ui'],
|
|
283
|
+
'component_lib:radix': ['react-shadcn-ui'],
|
|
284
|
+
'view:blade': ['blade-ui'],
|
|
285
|
+
'meta:filament': ['livewire', 'blade-ui'],
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
/** Axes consulted for overlays, most-specific first. */
|
|
289
|
+
const _OVERLAY_AXES: ReadonlyArray<string> = [
|
|
290
|
+
'component_lib',
|
|
291
|
+
'meta',
|
|
292
|
+
'reactivity',
|
|
293
|
+
'view',
|
|
294
|
+
];
|
|
295
|
+
|
|
296
|
+
/** Skill → the pack it ships in, for the pack-agnostic determination. */
|
|
297
|
+
const _FRAMEWORK_PACK_SKILLS: ReadonlySet<string> = new Set([
|
|
298
|
+
'livewire',
|
|
299
|
+
'flux',
|
|
300
|
+
'blade-ui',
|
|
301
|
+
'react-shadcn-ui',
|
|
302
|
+
]);
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Derive a bundle from detected axes.
|
|
306
|
+
*
|
|
307
|
+
* Order is deliberate and matches the hand-written lanes: overlays first
|
|
308
|
+
* (most-specific axis first), base last. An overlay carries framework idiom the
|
|
309
|
+
* base cannot, so it must be read before the generic contract's fallbacks.
|
|
310
|
+
*
|
|
311
|
+
* `pack_agnostic` is computed, not declared: a composition that pulled in any
|
|
312
|
+
* framework-pack skill is not safe as a fallback, and computing it removes the
|
|
313
|
+
* chance of a hand-written `true` outliving the bundle it described.
|
|
314
|
+
*/
|
|
315
|
+
export function compose_bundle(axes: Readonly<Record<string, string>>): StackBundle {
|
|
316
|
+
const build: string[] = [];
|
|
317
|
+
for (const axis of _OVERLAY_AXES) {
|
|
318
|
+
const value = axes[axis];
|
|
319
|
+
if (value === undefined || value === 'none' || value === 'unknown') continue;
|
|
320
|
+
for (const skill of _AXIS_OVERLAYS[`${axis}:${value}`] ?? []) {
|
|
321
|
+
if (!build.includes(skill)) build.push(skill);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
for (const skill of GENERIC_BUILD) {
|
|
325
|
+
if (!build.includes(skill)) build.push(skill);
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
build,
|
|
329
|
+
review: GENERIC_REVIEW,
|
|
330
|
+
pack_agnostic: !build.some((s) => _FRAMEWORK_PACK_SKILLS.has(s)),
|
|
331
|
+
};
|
|
332
|
+
}
|