@givolt/i3-composer-agent 2.2.2 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +1 -1
- package/.claude/commands/i3-prototype.md +23 -0
- package/.claude/commands/i3-review.md +1 -1
- package/.claude/commands/i3-ship.md +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -2
- package/.gemini/commands/i3-prototype.toml +23 -0
- package/.gemini/commands/i3-review.toml +1 -1
- package/.gemini/commands/i3-ship.toml +1 -1
- package/README.md +42 -25
- package/agents/code-reviewer.md +1 -1
- package/agents/test-engineer.md +1 -1
- package/bin/i3-composer-agent.cjs +5 -4
- package/bin/install.cjs +22 -10
- package/bin/native-command-validation.cjs +8 -13
- package/bin/native-layout.cjs +64 -28
- package/bin/native-migration.cjs +13 -7
- package/bin/native-runtime.cjs +10 -5
- package/commands/i3-prototype.toml +23 -0
- package/commands/i3-review.toml +1 -1
- package/commands/i3-ship.toml +1 -1
- package/docs/advanced-per-agent-configuration.md +78 -0
- package/docs/agents.md +2 -2
- package/docs/codebuddy-setup.md +5 -5
- package/docs/codex-setup.md +3 -3
- package/docs/copilot-setup.md +4 -0
- package/docs/cursor-setup.md +3 -0
- package/docs/other-hosts.md +44 -9
- package/docs/workbuddy-setup.md +9 -9
- package/evals/README.md +28 -16
- package/evals/cases/i3-documentation-and-adrs.json +18 -0
- package/evals/cases/i3-test-driven-development.json +8 -0
- package/evals/cases/i3-ui-prototype.json +49 -0
- package/evals/fixtures/i3-documentation-and-adrs/prose-review/README.md +19 -0
- package/evals/fixtures/i3-documentation-and-adrs/prose-review/queue.js +32 -0
- package/evals/fixtures/i3-ui-prototype/business-brief.md +7 -0
- package/evals/plugin/tdd-fires-on-pasted-bug/graders/failing-test-first.md +7 -0
- package/evals/plugin/tdd-fires-on-pasted-bug/graders/skill-fired.md +5 -0
- package/evals/plugin/tdd-fires-on-pasted-bug/prompt.md +15 -0
- package/evals/plugin/tdd-stays-quiet-on-debug/graders/not-fired.md +8 -0
- package/evals/plugin/tdd-stays-quiet-on-debug/prompt.md +25 -0
- package/evals/zh-CN/cases/i3-documentation-and-adrs.json +19 -0
- package/evals/zh-CN/cases/i3-test-driven-development.json +4 -0
- package/evals/zh-CN/cases/i3-ui-prototype.json +50 -0
- package/hooks/SIMPLIFY-IGNORE.md +3 -2
- package/hooks/simplify-ignore-test.sh +93 -1
- package/hooks/simplify-ignore.sh +94 -11
- package/package.json +63 -18
- package/plugin.json +1 -1
- package/references/performance-checklist.md +4 -2
- package/scripts/enterprise-template-test.js +139 -0
- package/scripts/floor-guard-reference-test.js +291 -0
- package/scripts/lib/skill-lint-test.js +762 -0
- package/scripts/lib/skill-lint.js +62 -8
- package/scripts/run-evals-test.js +830 -0
- package/scripts/run-evals.js +47 -9
- package/scripts/run-regressions.js +19 -0
- package/scripts/template-adapter-test.js +155 -0
- package/scripts/ui-prototype-test.js +114 -0
- package/scripts/validate-artifact-paths-test.js +179 -0
- package/scripts/validate-commands-test.js +246 -0
- package/scripts/validate-commands.js +6 -16
- package/scripts/validate-reference-links-test.js +513 -0
- package/scripts/validate-reference-links.js +4 -2
- package/scripts/validate-skills.js +26 -3
- package/scripts/validate-versions-test.js +32 -0
- package/skills/i3-documentation-and-adrs/SKILL.md +9 -0
- package/skills/i3-frontend-ui-engineering/SKILL.md +5 -1
- package/skills/i3-idea-refine/SKILL.md +20 -5
- package/skills/i3-incremental-implementation/SKILL.md +4 -0
- package/skills/i3-performance-optimization/SKILL.md +10 -10
- package/skills/i3-security-and-hardening/references/hardening-patterns.md +1 -1
- package/skills/i3-shipping-and-launch/SKILL.md +6 -0
- package/skills/i3-test-driven-development/SKILL.md +3 -3
- package/skills/i3-ui-prototype/SKILL.md +119 -0
- package/skills/i3-ui-prototype/assets/templates/catalog.json +147 -0
- package/skills/i3-ui-prototype/assets/templates/classic-admin/manifest.json +9 -0
- package/skills/i3-ui-prototype/assets/templates/classic-admin/preset.json +6 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/app.mjs +89 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/config.json +1 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/domain.mjs +20 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/index.html +17 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/serve.cjs +16 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/styles.css +670 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/tokens.css +19 -0
- package/skills/i3-ui-prototype/assets/templates/common/design-system/master.md +20 -0
- package/skills/i3-ui-prototype/assets/templates/common/gallery.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/common/mocks/applications.json +5 -0
- package/skills/i3-ui-prototype/assets/templates/common/requirements-map.json +8 -0
- package/skills/i3-ui-prototype/assets/templates/common/serve-gallery.cjs +16 -0
- package/skills/i3-ui-prototype/assets/templates/credits.md +17 -0
- package/skills/i3-ui-prototype/assets/templates/data-operations/manifest.json +9 -0
- package/skills/i3-ui-prototype/assets/templates/data-operations/preset.json +6 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/design-system.md +32 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/index.html +29 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/manifest.json +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/origin.json +344 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/preset.json +928 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/app.js +22 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/empty.svg +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/reference-styles.json +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/result-403.svg +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/result-404.svg +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets-manifest.json +334 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/baseline.json +173 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/conversion.md +30 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/credits.md +17 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/design-tokens.json +881 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/index.html +28 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/@qin-ui-antdv-next-pro.txt +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/ant-design-icons.txt +22 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/antdv-next.txt +21 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/package.json +12 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/browser-routes.json +298 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/coverage.json +180 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/integrity.json +13 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/keyboard.json +11 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/responsive.json +125 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/review.md +51 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/rules.log +150 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-html.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-original.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-html.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-original.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/models-html.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/models-original.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-html.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-original.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/selection.json +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/visual-comparison.json +342 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/readme.md +73 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/reference.md +59 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/routes.json +178 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/controls.js +99 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/dialogs.js +54 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/dom.js +264 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/forms.js +47 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/icons.js +41 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/layout.js +47 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/router.js +63 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/state.js +90 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/table.js +41 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/widgets.js +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.js +36 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.js +51 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.js +48 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/CheckResults.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/CheckResults.js +6 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.js +13 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/data.js +24 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/domain.js +32 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/registry.js +25 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/store.js +85 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentClose.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentClose.js +17 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.js +66 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.js +38 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.js +66 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.js +5 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.js +12 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.js +11 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentList.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentList.js +116 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.js +32 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.js +49 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.js +10 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.js +77 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/data.js +60 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/domain.js +105 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/store.js +212 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/AuditPanel.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/AuditPanel.js +18 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.js +23 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.js +78 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.js +55 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelReferences.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelReferences.js +26 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelRelease.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelRelease.js +38 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.js +7 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.js +72 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.js +46 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.js +52 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.js +19 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.js +30 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/data.js +48 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/domain.js +39 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/store.js +129 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.html +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.js +21 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IntentSource.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IntentSource.js +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.js +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.js +10 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.js +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.js +49 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RunDetail.html +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RunDetail.js +22 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.js +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/commands.js +82 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/examples.js +47 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/model.js +61 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/repair.js +68 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/store.js +55 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/types.js +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/workbench.js +18 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.js +28 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.js +18 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.js +31 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.js +27 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.js +16 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.js +43 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.html +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.js +34 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.js +30 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.js +67 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.js +41 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.js +31 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.js +26 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.js +70 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/data.js +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/domain.js +62 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/management.js +36 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/managementStore.js +49 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/store.js +132 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/AdminList.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/AdminList.js +38 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.js +11 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.js +45 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.js +54 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.js +27 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.js +12 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.js +45 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.js +38 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/domain.js +61 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/state.js +51 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/store.js +116 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.js +45 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.html +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.js +30 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.js +67 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.js +5 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.html +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.js +60 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/commands.js +157 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/model.js +136 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/store.js +76 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.js +26 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.js +14 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.js +113 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.js +62 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/commands.js +97 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/model.js +147 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/store.js +13 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.js +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.js +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.js +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListMore.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListMore.js +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.js +17 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/columns.js +32 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/deliveryGuide.js +49 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/deliveryView.js +12 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/listBatch.js +15 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/listSelection.js +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/policy.js +68 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/session.js +44 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.js +25 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.js +53 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.html +10 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.js +30 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ScopePage.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ScopePage.js +10 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.js +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/confirmation.js +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/navigation.js +19 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.js +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.js +32 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.js +15 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.js +11 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecReview.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecReview.js +57 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.js +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/data.js +20 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/domain.js +55 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/store.js +151 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.js +18 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.js +40 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.js +51 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.js +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.html +5 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.js +48 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/domain.js +204 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/exampleSource.js +22 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/registry.js +135 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/store.js +137 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.js +36 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/model.js +56 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/store.js +15 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.js +27 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.html +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.js +31 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.js +68 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.html +5 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.js +55 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/data.js +16 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/domain.js +83 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/registry.js +18 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/store.js +61 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/admin.css +60 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/agents.css +46 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/antdv.css +295 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/app.css +102 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/delivery.css +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/intents.css +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/native.css +22 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/operations.css +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/pbc.css +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/permissions.css +22 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/pro.css +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/releases.css +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/reset.css +246 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/reviews.css +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/tasks.css +6 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/tokens.css +15 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/workbench.css +61 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/workflows.css +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/admin-rules.test.js +96 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/agents.test.js +14 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/intent-state.test.js +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/list-batch.test.js +44 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operation-fixtures.js +19 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operation-repair.test.js +14 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operations.test.js +25 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/pbc-management.test.js +17 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/pbc-state.test.js +24 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/permission-config.test.js +23 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/permissions.test.js +24 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/releases.test.js +50 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/reviews.test.js +36 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-forms-router.test.js +28 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-state.test.js +42 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-stores.test.js +16 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/spec-state.test.js +11 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/tasks.test.js +27 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/workbench.test.js +34 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/workflows.test.js +16 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/convert.mjs +168 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/serve.mjs +7 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/styles.mjs +11 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/verify.mjs +24 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/serve.cjs +16 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/usability.css +44 -0
- package/skills/i3-ui-prototype/assets/templates/gallery/index.html +40 -0
- package/skills/i3-ui-prototype/assets/templates/modern-workspace/manifest.json +9 -0
- package/skills/i3-ui-prototype/assets/templates/modern-workspace/preset.json +6 -0
- package/skills/i3-ui-prototype/assets/templates/serve-gallery.cjs +16 -0
- package/skills/i3-ui-prototype/references/artifact-contract.md +41 -0
- package/skills/i3-ui-prototype/references/enterprise-admin.md +38 -0
- package/skills/i3-ui-prototype/references/expert-adapter.md +42 -0
- package/skills/i3-ui-prototype/references/template-adapters.md +57 -0
- package/skills/i3-ui-prototype/references/workflow-contract.md +19 -0
- package/skills/i3-ui-prototype/scripts/adapters/easel-html.cjs +30 -0
- package/skills/i3-ui-prototype/scripts/adapters/legacy-html.cjs +28 -0
- package/skills/i3-ui-prototype/scripts/check-design-provider.cjs +9 -0
- package/skills/i3-ui-prototype/scripts/check-prototype.cjs +14 -0
- package/skills/i3-ui-prototype/scripts/enterprise-template.cjs +88 -0
- package/skills/i3-ui-prototype/scripts/init-prototype.cjs +8 -0
- package/skills/i3-ui-prototype/scripts/manage-baseline.cjs +11 -0
- package/skills/i3-ui-prototype/scripts/prototype-lib.cjs +255 -0
- package/skills/i3-ui-prototype/scripts/template-adapters.cjs +89 -0
- package/skills/i3-using-agent-skills/SKILL.md +5 -0
- package/bin/native-version-validation.cjs +0 -8
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
const assert = require('node:assert/strict');
|
|
6
|
+
const fs = require('node:fs');
|
|
7
|
+
const os = require('node:os');
|
|
8
|
+
const path = require('node:path');
|
|
9
|
+
const { spawnSync } = require('node:child_process');
|
|
10
|
+
const { afterEach, test } = require('node:test');
|
|
11
|
+
|
|
12
|
+
const VALIDATOR = path.join(__dirname, 'validate-reference-links.js');
|
|
13
|
+
const sandboxes = [];
|
|
14
|
+
|
|
15
|
+
function makeSandbox() {
|
|
16
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-skills-validate-reference-links-test-'));
|
|
17
|
+
const scriptsDir = path.join(root, 'scripts');
|
|
18
|
+
fs.mkdirSync(scriptsDir, { recursive: true });
|
|
19
|
+
fs.copyFileSync(VALIDATOR, path.join(scriptsDir, 'validate-reference-links.js'));
|
|
20
|
+
fs.mkdirSync(path.join(scriptsDir, 'lib'));
|
|
21
|
+
fs.copyFileSync(path.join(__dirname, 'lib', 'skill-lint.js'), path.join(scriptsDir, 'lib', 'skill-lint.js'));
|
|
22
|
+
sandboxes.push(root);
|
|
23
|
+
return root;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function writeFile(root, relativePath, content) {
|
|
27
|
+
const file = path.join(root, relativePath);
|
|
28
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
29
|
+
fs.writeFileSync(file, content);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function run(root) {
|
|
33
|
+
return spawnSync(process.execPath, [path.join(root, 'scripts', 'validate-reference-links.js')], {
|
|
34
|
+
cwd: root,
|
|
35
|
+
encoding: 'utf8',
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
afterEach(() => {
|
|
40
|
+
for (const root of sandboxes.splice(0)) {
|
|
41
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('passes when a skill reaches the shared checklist two levels up', () => {
|
|
46
|
+
const root = makeSandbox();
|
|
47
|
+
writeFile(root, 'references/definition-of-done.md', '# Definition of Done\n');
|
|
48
|
+
writeFile(
|
|
49
|
+
root,
|
|
50
|
+
'skills/i3-using-agent-skills/SKILL.md',
|
|
51
|
+
'See `../../references/definition-of-done.md`.\n'
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const result = run(root);
|
|
55
|
+
|
|
56
|
+
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
57
|
+
assert.match(result.stdout, /1 skills checked — 0 error\(s\) — PASSED/);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('fails when a skill links the shared checklist as if it were colocated', () => {
|
|
61
|
+
// The regression: references/ lives at the repo root, but the link is
|
|
62
|
+
// resolved from skills/<name>/, so it points two levels too deep.
|
|
63
|
+
const root = makeSandbox();
|
|
64
|
+
writeFile(root, 'references/definition-of-done.md', '# Definition of Done\n');
|
|
65
|
+
writeFile(
|
|
66
|
+
root,
|
|
67
|
+
'skills/i3-using-agent-skills/SKILL.md',
|
|
68
|
+
'See `references/definition-of-done.md`.\n'
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const result = run(root);
|
|
72
|
+
|
|
73
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
74
|
+
assert.match(result.stdout, /1 skills checked — 1 error\(s\) — FAILED/);
|
|
75
|
+
assert.match(
|
|
76
|
+
result.stdout,
|
|
77
|
+
/L1: references\/definition-of-done\.md — resolves to skills\/i3-using-agent-skills\/references\/definition-of-done\.md/
|
|
78
|
+
);
|
|
79
|
+
assert.match(result.stdout, /use `\.\.\/\.\.\/references\/<file>\.md`/);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('checks markdown link syntax, not just backtick mentions', () => {
|
|
83
|
+
const root = makeSandbox();
|
|
84
|
+
writeFile(root, 'references/definition-of-done.md', '# Definition of Done\n');
|
|
85
|
+
writeFile(root, 'skills/i3-using-agent-skills/SKILL.md', 'See [DoD](references/definition-of-done.md).\n');
|
|
86
|
+
|
|
87
|
+
const result = run(root);
|
|
88
|
+
|
|
89
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
90
|
+
assert.match(result.stdout, /L1: references\/definition-of-done\.md/);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('passes when a skill colocates its own references directory', () => {
|
|
94
|
+
// CLAUDE.md allows self-contained skills to keep references under
|
|
95
|
+
// skills/<name>/references/. Those links are correct as written.
|
|
96
|
+
const root = makeSandbox();
|
|
97
|
+
writeFile(root, 'skills/dataviz/references/palette.md', '# Palette\n');
|
|
98
|
+
writeFile(root, 'skills/dataviz/SKILL.md', 'See `references/palette.md`.\n');
|
|
99
|
+
|
|
100
|
+
const result = run(root);
|
|
101
|
+
|
|
102
|
+
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
103
|
+
assert.match(result.stdout, /1 skills checked — 0 error\(s\) — PASSED/);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('passes when a skill reference file reaches the shared checklist three levels up', () => {
|
|
107
|
+
// A file under skills/<name>/references/ sits one directory deeper than
|
|
108
|
+
// SKILL.md, so the shared checklists are three levels up from it, not two.
|
|
109
|
+
const root = makeSandbox();
|
|
110
|
+
writeFile(root, 'references/security-checklist.md', '# Security\n');
|
|
111
|
+
writeFile(root, 'skills/hardening/SKILL.md', 'See [patterns](references/patterns.md).\n');
|
|
112
|
+
writeFile(
|
|
113
|
+
root,
|
|
114
|
+
'skills/hardening/references/patterns.md',
|
|
115
|
+
'Shared checklists live in `../../../references/security-checklist.md`.\n'
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const result = run(root);
|
|
119
|
+
|
|
120
|
+
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
121
|
+
assert.match(result.stdout, /✓ {2}skills\/hardening\/references\/patterns\.md/);
|
|
122
|
+
assert.match(result.stdout, /1 skills checked — 0 error\(s\) — PASSED/);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('fails when a skill reference file links the shared checklist with the SKILL.md prefix', () => {
|
|
126
|
+
// The same off-by-a-level mistake this validator exists to catch, made from
|
|
127
|
+
// inside the skill's references/ directory: the link is resolved from the
|
|
128
|
+
// file that contains it, so `../../` stops at skills/.
|
|
129
|
+
const root = makeSandbox();
|
|
130
|
+
writeFile(root, 'references/security-checklist.md', '# Security\n');
|
|
131
|
+
writeFile(root, 'skills/hardening/SKILL.md', 'See [patterns](references/patterns.md).\n');
|
|
132
|
+
writeFile(
|
|
133
|
+
root,
|
|
134
|
+
'skills/hardening/references/patterns.md',
|
|
135
|
+
['# Patterns', '', 'See `../../references/security-checklist.md`.', ''].join('\n')
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const result = run(root);
|
|
139
|
+
|
|
140
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
141
|
+
assert.match(result.stdout, /✓ {2}skills\/hardening\/SKILL\.md/);
|
|
142
|
+
assert.match(result.stdout, /✗ {2}skills\/hardening\/references\/patterns\.md/);
|
|
143
|
+
assert.match(
|
|
144
|
+
result.stdout,
|
|
145
|
+
/L3: \.\.\/\.\.\/references\/security-checklist\.md — resolves to skills\/references\/security-checklist\.md/
|
|
146
|
+
);
|
|
147
|
+
assert.match(result.stdout, /1 skills checked — 1 error\(s\) — FAILED/);
|
|
148
|
+
assert.match(result.stdout, /use `\.\.\/\.\.\/\.\.\/references\/<file>\.md`/);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('keeps the same narrow rule inside a skill reference file', () => {
|
|
152
|
+
// Same exemptions as SKILL.md: fenced examples, sibling files named without
|
|
153
|
+
// a references/ prefix, and artifacts that do not exist yet.
|
|
154
|
+
const root = makeSandbox();
|
|
155
|
+
writeFile(root, 'references/security-checklist.md', '# Security\n');
|
|
156
|
+
writeFile(root, 'skills/hardening/SKILL.md', 'See [patterns](references/patterns.md).\n');
|
|
157
|
+
writeFile(
|
|
158
|
+
root,
|
|
159
|
+
'skills/hardening/references/patterns.md',
|
|
160
|
+
[
|
|
161
|
+
'Record findings in `SECURITY.md` or `docs/threat-model.md`. See also `other-patterns.md`.',
|
|
162
|
+
'',
|
|
163
|
+
'```markdown',
|
|
164
|
+
'[wrong on purpose](../../references/security-checklist.md)',
|
|
165
|
+
'```',
|
|
166
|
+
'',
|
|
167
|
+
].join('\n')
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
const result = run(root);
|
|
171
|
+
|
|
172
|
+
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
173
|
+
assert.match(result.stdout, /1 skills checked — 0 error\(s\) — PASSED/);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('counts errors from SKILL.md and its reference files together', () => {
|
|
177
|
+
const root = makeSandbox();
|
|
178
|
+
writeFile(root, 'references/security-checklist.md', '# Security\n');
|
|
179
|
+
writeFile(root, 'skills/hardening/SKILL.md', 'See `references/security-checklist.md`.\n');
|
|
180
|
+
writeFile(root, 'skills/hardening/references/a.md', 'See `../../references/security-checklist.md`.\n');
|
|
181
|
+
writeFile(root, 'skills/hardening/references/b.md', 'See `../../../references/security-checklist.md`.\n');
|
|
182
|
+
writeFile(root, 'skills/hardening/references/notes.txt', 'See ../../references/security-checklist.md\n');
|
|
183
|
+
|
|
184
|
+
const result = run(root);
|
|
185
|
+
|
|
186
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
187
|
+
assert.match(result.stdout, /✗ {2}skills\/hardening\/references\/a\.md/);
|
|
188
|
+
assert.match(result.stdout, /✓ {2}skills\/hardening\/references\/b\.md/);
|
|
189
|
+
assert.doesNotMatch(result.stdout, /notes\.txt/);
|
|
190
|
+
assert.match(result.stdout, /1 skills checked — 2 error\(s\) — FAILED/);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test('fails when a link points at a checklist that no longer exists', () => {
|
|
194
|
+
const root = makeSandbox();
|
|
195
|
+
writeFile(root, 'references/definition-of-done.md', '# Definition of Done\n');
|
|
196
|
+
writeFile(root, 'skills/i3-shipping-and-launch/SKILL.md', 'See `../../references/renamed.md`.\n');
|
|
197
|
+
|
|
198
|
+
const result = run(root);
|
|
199
|
+
|
|
200
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
201
|
+
assert.match(result.stdout, /L1: \.\.\/\.\.\/references\/renamed\.md/);
|
|
202
|
+
assert.match(result.stdout, /1 skills checked — 1 error\(s\) — FAILED/);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test('ignores paths that are not references/ links', () => {
|
|
206
|
+
// Skills legitimately name artifacts the user has yet to create. Widening
|
|
207
|
+
// this validator into a general markdown linter would fail the build on them.
|
|
208
|
+
const root = makeSandbox();
|
|
209
|
+
writeFile(root, 'references/definition-of-done.md', '# Definition of Done\n');
|
|
210
|
+
writeFile(
|
|
211
|
+
root,
|
|
212
|
+
'skills/i3-planning-and-task-breakdown/SKILL.md',
|
|
213
|
+
[
|
|
214
|
+
'Save the task list to `tasks/todo.md` and the plan to `tasks/plan.md`.',
|
|
215
|
+
'Record findings in `PERF.md` or `docs/ideas/[idea-name].md`.',
|
|
216
|
+
'Related: `skills/i3-incremental-implementation/SKILL.md`.',
|
|
217
|
+
'See `../../references/definition-of-done.md`.',
|
|
218
|
+
'',
|
|
219
|
+
].join('\n')
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
const result = run(root);
|
|
223
|
+
|
|
224
|
+
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
225
|
+
assert.match(result.stdout, /1 skills checked — 0 error\(s\) — PASSED/);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test('reports every unresolvable link, not just the first per skill', () => {
|
|
229
|
+
const root = makeSandbox();
|
|
230
|
+
writeFile(root, 'references/security-checklist.md', '# Security\n');
|
|
231
|
+
writeFile(root, 'references/performance-checklist.md', '# Performance\n');
|
|
232
|
+
writeFile(
|
|
233
|
+
root,
|
|
234
|
+
'skills/i3-code-review-and-quality/SKILL.md',
|
|
235
|
+
['See `references/security-checklist.md`.', 'And `references/performance-checklist.md`.', ''].join('\n')
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
const result = run(root);
|
|
239
|
+
|
|
240
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
241
|
+
assert.match(result.stdout, /1 skills checked — 2 error\(s\) — FAILED/);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test('a link inside a fenced block is an example, not a link to resolve', () => {
|
|
245
|
+
const root = makeSandbox();
|
|
246
|
+
writeFile(root, 'references/definition-of-done.md', '# DoD\n');
|
|
247
|
+
writeFile(
|
|
248
|
+
root,
|
|
249
|
+
'skills/i3-using-agent-skills/SKILL.md',
|
|
250
|
+
[
|
|
251
|
+
'Shared checklists live two levels up:',
|
|
252
|
+
'',
|
|
253
|
+
'See `../../references/definition-of-done.md`.',
|
|
254
|
+
'',
|
|
255
|
+
'Do not write it this way:',
|
|
256
|
+
'',
|
|
257
|
+
'```markdown',
|
|
258
|
+
'[Definition of Done](references/definition-of-done.md)',
|
|
259
|
+
'```',
|
|
260
|
+
'',
|
|
261
|
+
].join('\n')
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
const result = run(root);
|
|
265
|
+
|
|
266
|
+
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
267
|
+
assert.match(result.stdout, /1 skills checked — 0 error\(s\) — PASSED/);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
test('fence exemption follows CommonMark rather than a bare ``` match', () => {
|
|
271
|
+
const root = makeSandbox();
|
|
272
|
+
writeFile(
|
|
273
|
+
root,
|
|
274
|
+
'skills/i3-using-agent-skills/SKILL.md',
|
|
275
|
+
[
|
|
276
|
+
'~~~markdown',
|
|
277
|
+
'[a](references/missing-a.md)',
|
|
278
|
+
'```', // wrong marker: must not close the ~~~ block
|
|
279
|
+
'[b](references/missing-b.md)',
|
|
280
|
+
'~~~',
|
|
281
|
+
'',
|
|
282
|
+
' ```markdown', // three-space indent is still a fence
|
|
283
|
+
'[c](references/missing-c.md)',
|
|
284
|
+
' `````', // a longer closer is legal
|
|
285
|
+
'',
|
|
286
|
+
].join('\n')
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
const result = run(root);
|
|
290
|
+
|
|
291
|
+
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
292
|
+
assert.match(result.stdout, /0 error\(s\) — PASSED/);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
test('a real broken link outside any fence is still reported', () => {
|
|
296
|
+
const root = makeSandbox();
|
|
297
|
+
writeFile(
|
|
298
|
+
root,
|
|
299
|
+
'skills/i3-using-agent-skills/SKILL.md',
|
|
300
|
+
[
|
|
301
|
+
'```markdown',
|
|
302
|
+
'[shown as an example](references/example-only.md)',
|
|
303
|
+
'```',
|
|
304
|
+
'',
|
|
305
|
+
'See `references/definition-of-done.md`.', // genuinely wrong, outside the fence
|
|
306
|
+
'',
|
|
307
|
+
].join('\n')
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
const result = run(root);
|
|
311
|
+
|
|
312
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
313
|
+
assert.match(result.stdout, /1 skills checked — 1 error\(s\) — FAILED/);
|
|
314
|
+
assert.match(result.stdout, /L5: references\/definition-of-done\.md/);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
for (const [ending, newline] of [['LF', '\n'], ['CRLF', '\r\n']]) {
|
|
318
|
+
test(`inline backticks do not hide subsequent broken links (${ending})`, () => {
|
|
319
|
+
const root = makeSandbox();
|
|
320
|
+
writeFile(root, 'skills/example/SKILL.md', [
|
|
321
|
+
'```js``` is inline code, not a fence opener.',
|
|
322
|
+
'See [missing](references/missing.md).',
|
|
323
|
+
'',
|
|
324
|
+
].join(newline));
|
|
325
|
+
|
|
326
|
+
const result = run(root);
|
|
327
|
+
|
|
328
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
329
|
+
assert.match(result.stdout, /L2: references\/missing\.md/);
|
|
330
|
+
assert.match(result.stdout, /1 skills checked — 1 error\(s\) — FAILED/);
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
for (const marker of ['```', '~~~']) {
|
|
334
|
+
test(`trailing text does not close a ${marker} fence (${ending})`, () => {
|
|
335
|
+
const root = makeSandbox();
|
|
336
|
+
writeFile(root, 'skills/example/SKILL.md', [
|
|
337
|
+
marker + 'markdown',
|
|
338
|
+
marker + ' still part of the example',
|
|
339
|
+
'[example](references/example-only.md)',
|
|
340
|
+
marker + ' \t',
|
|
341
|
+
'[real link](references/missing.md)',
|
|
342
|
+
'',
|
|
343
|
+
].join(newline));
|
|
344
|
+
|
|
345
|
+
const result = run(root);
|
|
346
|
+
|
|
347
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
348
|
+
assert.match(result.stdout, /L5: references\/missing\.md/);
|
|
349
|
+
assert.match(result.stdout, /1 skills checked — 1 error\(s\) — FAILED/);
|
|
350
|
+
assert.doesNotMatch(result.stdout, /example-only\.md/);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
test('tilde fence info strings may contain backticks', () => {
|
|
356
|
+
const root = makeSandbox();
|
|
357
|
+
writeFile(root, 'skills/example/SKILL.md', [
|
|
358
|
+
'~~~example `code`',
|
|
359
|
+
'[example](references/example-only.md)',
|
|
360
|
+
'~~~',
|
|
361
|
+
'',
|
|
362
|
+
].join('\n'));
|
|
363
|
+
|
|
364
|
+
const result = run(root);
|
|
365
|
+
|
|
366
|
+
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
367
|
+
assert.match(result.stdout, /1 skills checked — 0 error\(s\) — PASSED/);
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
// Anchors. A `#fragment` after a references/ link must match a heading in the
|
|
371
|
+
// target file, slugged the way GitHub does it. Without this, renaming a heading
|
|
372
|
+
// silently breaks every link to it while the file itself still exists.
|
|
373
|
+
|
|
374
|
+
function hardeningSkill(root, link) {
|
|
375
|
+
writeFile(root, 'skills/hardening/SKILL.md', `See [patterns](${link}).\n`);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
test('passes when an anchor matches a heading in the target file', () => {
|
|
379
|
+
const root = makeSandbox();
|
|
380
|
+
hardeningSkill(root, 'references/patterns.md#cross-site-scripting-xss');
|
|
381
|
+
writeFile(root, 'skills/hardening/references/patterns.md', '# Patterns\n\n## Cross-Site Scripting (XSS)\n');
|
|
382
|
+
|
|
383
|
+
const result = run(root);
|
|
384
|
+
|
|
385
|
+
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
386
|
+
assert.match(result.stdout, /1 skills checked — 0 error\(s\) — PASSED/);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
test('fails when an anchor matches no heading in the target file', () => {
|
|
390
|
+
// The file exists, so the existing check is satisfied; only the fragment is stale.
|
|
391
|
+
const root = makeSandbox();
|
|
392
|
+
hardeningSkill(root, 'references/patterns.md#injection');
|
|
393
|
+
writeFile(root, 'skills/hardening/references/patterns.md', '# Patterns\n\n## Injection attacks\n');
|
|
394
|
+
|
|
395
|
+
const result = run(root);
|
|
396
|
+
|
|
397
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
398
|
+
assert.match(
|
|
399
|
+
result.stdout,
|
|
400
|
+
/L1: references\/patterns\.md#injection — no heading in skills\/hardening\/references\/patterns\.md produces #injection/
|
|
401
|
+
);
|
|
402
|
+
assert.match(result.stdout, /1 skills checked — 1 error\(s\) — FAILED/);
|
|
403
|
+
assert.match(result.stdout, /GitHub's heading slugs/);
|
|
404
|
+
// The path was right, so the path hint would only mislead.
|
|
405
|
+
assert.doesNotMatch(result.stdout, /use `\.\.\/\.\.\/references/);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
test('a repeated heading gets a -1 suffix, as on GitHub', () => {
|
|
409
|
+
const root = makeSandbox();
|
|
410
|
+
writeFile(root, 'skills/hardening/SKILL.md', [
|
|
411
|
+
'See [first](references/patterns.md#example).',
|
|
412
|
+
'See [second](references/patterns.md#example-1).',
|
|
413
|
+
'See [third](references/patterns.md#example-2).',
|
|
414
|
+
'',
|
|
415
|
+
].join('\n'));
|
|
416
|
+
writeFile(root, 'skills/hardening/references/patterns.md', '## Example\n\n## Example\n');
|
|
417
|
+
|
|
418
|
+
const result = run(root);
|
|
419
|
+
|
|
420
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
421
|
+
assert.match(result.stdout, /L3: references\/patterns\.md#example-2 — no heading/);
|
|
422
|
+
assert.doesNotMatch(result.stdout, /L[12]:/);
|
|
423
|
+
assert.match(result.stdout, /1 skills checked — 1 error\(s\) — FAILED/);
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
test('slugs come from the rendered heading text, not its markdown', () => {
|
|
427
|
+
// Real headings in the pack carry emphasis, code spans and links.
|
|
428
|
+
const root = makeSandbox();
|
|
429
|
+
writeFile(root, 'skills/hardening/SKILL.md', [
|
|
430
|
+
'See [a](references/patterns.md#why-this-is-not-a-ship-job).',
|
|
431
|
+
'See [b](references/patterns.md#owasp-top-10).',
|
|
432
|
+
'See [c](references/patterns.md#snake_case-names-stay).',
|
|
433
|
+
'See [d](references/patterns.md#closing-hashes).',
|
|
434
|
+
'',
|
|
435
|
+
].join('\n'));
|
|
436
|
+
writeFile(root, 'skills/hardening/references/patterns.md', [
|
|
437
|
+
'### Why this is *not* a `/ship` job',
|
|
438
|
+
'## [OWASP](https://owasp.org/Top10/) Top 10',
|
|
439
|
+
'## snake_case names stay',
|
|
440
|
+
'## Closing hashes ##',
|
|
441
|
+
'',
|
|
442
|
+
].join('\n'));
|
|
443
|
+
|
|
444
|
+
const result = run(root);
|
|
445
|
+
|
|
446
|
+
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
test('a heading-like line inside a fenced block is not an anchor', () => {
|
|
450
|
+
// Bash comments in a fenced example look like H1s.
|
|
451
|
+
const root = makeSandbox();
|
|
452
|
+
hardeningSkill(root, 'references/patterns.md#chrome-devtools');
|
|
453
|
+
writeFile(root, 'skills/hardening/references/patterns.md', [
|
|
454
|
+
'# Patterns',
|
|
455
|
+
'',
|
|
456
|
+
'```bash',
|
|
457
|
+
'# Chrome DevTools',
|
|
458
|
+
'```',
|
|
459
|
+
'',
|
|
460
|
+
].join('\n'));
|
|
461
|
+
|
|
462
|
+
const result = run(root);
|
|
463
|
+
|
|
464
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
465
|
+
assert.match(result.stdout, /#chrome-devtools — no heading/);
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
test('anchors resolve from a reference file to a shared checklist', () => {
|
|
469
|
+
const root = makeSandbox();
|
|
470
|
+
writeFile(root, 'references/security-checklist.md', '# Security\n\n## OWASP Top 10 Quick Reference\n');
|
|
471
|
+
hardeningSkill(root, 'references/patterns.md');
|
|
472
|
+
writeFile(root, 'skills/hardening/references/patterns.md', [
|
|
473
|
+
'See `../../../references/security-checklist.md#owasp-top-10-quick-reference`.',
|
|
474
|
+
'See `../../../references/security-checklist.md#destructive-path-operations`.',
|
|
475
|
+
'',
|
|
476
|
+
].join('\n'));
|
|
477
|
+
|
|
478
|
+
const result = run(root);
|
|
479
|
+
|
|
480
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
481
|
+
assert.match(result.stdout, /✗ {2}skills\/hardening\/references\/patterns\.md/);
|
|
482
|
+
assert.match(result.stdout, /L2: \.\.\/\.\.\/\.\.\/references\/security-checklist\.md#destructive-path-operations — no heading in references\/security-checklist\.md/);
|
|
483
|
+
assert.doesNotMatch(result.stdout, /L1:/);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
test('a missing file is reported once, not again for its anchor', () => {
|
|
487
|
+
const root = makeSandbox();
|
|
488
|
+
hardeningSkill(root, 'references/renamed.md#injection');
|
|
489
|
+
|
|
490
|
+
const result = run(root);
|
|
491
|
+
|
|
492
|
+
assert.equal(result.status, 1, result.stdout + result.stderr);
|
|
493
|
+
assert.match(result.stdout, /L1: references\/renamed\.md — resolves to skills\/hardening\/references\/renamed\.md, which does not exist/);
|
|
494
|
+
assert.match(result.stdout, /1 skills checked — 1 error\(s\) — FAILED/);
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
test('heading slugs remain unique when a literal suffix collides with an allocated slug', () => {
|
|
499
|
+
const root = makeSandbox();
|
|
500
|
+
hardeningSkill(root, 'references/patterns.md#example-1-1');
|
|
501
|
+
// A hyphen in the literal heading makes its base slug collide with Example's suffix.
|
|
502
|
+
writeFile(root, 'skills/hardening/references/patterns.md', '## Example\n\n## Example\n\n## Example-1\n');
|
|
503
|
+
const result = run(root);
|
|
504
|
+
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
test('a duplicate skips a slug occupied by an earlier literal heading', () => {
|
|
508
|
+
const root = makeSandbox();
|
|
509
|
+
hardeningSkill(root, 'references/patterns.md#example-2');
|
|
510
|
+
writeFile(root, 'skills/hardening/references/patterns.md', '## Example\n\n## Example-1\n\n## Example\n');
|
|
511
|
+
const result = run(root);
|
|
512
|
+
assert.equal(result.status, 0, result.stdout + result.stderr);
|
|
513
|
+
});
|
|
@@ -77,8 +77,10 @@ function headingAnchors(file) {
|
|
|
77
77
|
const match = line.match(/^ {0,3}#{1,6}[ \t]+(.*?)(?:[ \t]+#+)?[ \t]*$/);
|
|
78
78
|
if (!match) continue;
|
|
79
79
|
const slug = slugify(match[1]);
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
let count = seen.get(slug) || 0;
|
|
81
|
+
let anchor = count === 0 ? slug : `${slug}-${count}`;
|
|
82
|
+
while (anchors.has(anchor)) anchor = `${slug}-${++count}`;
|
|
83
|
+
anchors.add(anchor);
|
|
82
84
|
seen.set(slug, count + 1);
|
|
83
85
|
}
|
|
84
86
|
return anchors;
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* validate-skills.js
|
|
4
4
|
*
|
|
5
5
|
* CLI that validates every skill in skills/ against the rules in
|
|
6
|
-
* docs/skill-anatomy.md
|
|
6
|
+
* docs/skill-anatomy.md, and every persona in agents/ against the three rules
|
|
7
|
+
* in docs/agents.md. The rules themselves live in scripts/lib/skill-lint.js
|
|
7
8
|
* (a single source of truth, importable and unit-testable); this file is a thin
|
|
8
9
|
* wrapper that walks the skills directory, runs the linter, prints the report,
|
|
9
10
|
* and sets the exit code.
|
|
@@ -16,9 +17,10 @@
|
|
|
16
17
|
const fs = require('fs');
|
|
17
18
|
const path = require('path');
|
|
18
19
|
|
|
19
|
-
const { lintSkill } = require('./lib/skill-lint');
|
|
20
|
+
const { lintSkill, lintPersona } = require('./lib/skill-lint');
|
|
20
21
|
|
|
21
22
|
const SKILLS_DIR = path.resolve(__dirname, '..', 'skills');
|
|
23
|
+
const AGENTS_DIR = path.resolve(__dirname, '..', 'agents');
|
|
22
24
|
|
|
23
25
|
// ─── Main ────────────────────────────────────────────────────────────────────
|
|
24
26
|
|
|
@@ -54,8 +56,29 @@ function main() {
|
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
|
|
59
|
+
// ── Personas ─────────────────────────────────────────────────────────────
|
|
60
|
+
// agents/<name>.md files are consumed as subagents and spawned by name from
|
|
61
|
+
// commands, so they get the same frontmatter contract plus a closing
|
|
62
|
+
// Composition section (docs/agents.md). An index file such as README.md is
|
|
63
|
+
// not a persona and is skipped.
|
|
64
|
+
const personaFiles = fs.existsSync(AGENTS_DIR)
|
|
65
|
+
? fs.readdirSync(AGENTS_DIR).filter(f => f.endsWith('.md') && !/^readme\.md$/i.test(f)).sort()
|
|
66
|
+
: [];
|
|
67
|
+
|
|
68
|
+
if (personaFiles.length > 0) console.log('');
|
|
69
|
+
for (const fileName of personaFiles) {
|
|
70
|
+
const { errors } = lintPersona(fileName, AGENTS_DIR);
|
|
71
|
+
totalErrors += errors.length;
|
|
72
|
+
if (errors.length === 0) {
|
|
73
|
+
console.log(` ✓ agents/${fileName}`);
|
|
74
|
+
} else {
|
|
75
|
+
console.log(` ✗ agents/${fileName}`);
|
|
76
|
+
for (const msg of errors) console.log(` ERROR: ${msg}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
57
80
|
const status = totalErrors > 0 ? 'FAILED' : totalWarnings > 0 ? 'PASSED WITH WARNINGS' : 'PASSED';
|
|
58
|
-
console.log(`\n${skillDirs.length} skills checked — ${totalErrors} error(s), ${totalWarnings} warning(s) — ${status}`);
|
|
81
|
+
console.log(`\n${skillDirs.length} skills and ${personaFiles.length} personas checked — ${totalErrors} error(s), ${totalWarnings} warning(s) — ${status}`);
|
|
59
82
|
|
|
60
83
|
if (totalErrors > 0) process.exit(1);
|
|
61
84
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const assert = require("node:assert/strict");
|
|
4
|
+
const { readFileSync } = require("node:fs");
|
|
5
|
+
const test = require("node:test");
|
|
6
|
+
|
|
7
|
+
const manifestPaths = [
|
|
8
|
+
"package.json",
|
|
9
|
+
"plugin.json",
|
|
10
|
+
".codex-plugin/plugin.json",
|
|
11
|
+
".claude-plugin/plugin.json",
|
|
12
|
+
".claude-plugin/marketplace.json",
|
|
13
|
+
".agents/plugins/marketplace.json",
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
function readManifestVersion(manifestPath) {
|
|
17
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
18
|
+
return manifest.version ?? manifest.plugins?.[0]?.version;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
test("all plugin manifests use the root plugin.json version", () => {
|
|
22
|
+
const expectedVersion = readManifestVersion("plugin.json");
|
|
23
|
+
assert.ok(expectedVersion, "plugin.json must define a version");
|
|
24
|
+
|
|
25
|
+
for (const manifestPath of manifestPaths) {
|
|
26
|
+
assert.equal(
|
|
27
|
+
readManifestVersion(manifestPath),
|
|
28
|
+
expectedVersion,
|
|
29
|
+
`${manifestPath} must use version ${expectedVersion}`,
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
@@ -268,6 +268,14 @@ Special consideration for AI agent context:
|
|
|
268
268
|
- **ADRs** — Help agents understand why past decisions were made (prevents re-deciding)
|
|
269
269
|
- **Inline gotchas** — Prevent agents from falling into known traps
|
|
270
270
|
|
|
271
|
+
## Prose Review
|
|
272
|
+
|
|
273
|
+
After checking the technical content, review the prose for the people who will use it. Clearer wording must not change the decision or its limits.
|
|
274
|
+
|
|
275
|
+
1. Mark the details that must survive the edit: names, numbers and units, commands, paths, links, conditions, trade-offs, and uncertainty. Check them against the available code and decision context; flag anything you cannot substantiate.
|
|
276
|
+
2. Replace stock introductions, promotional adjectives, and repeated summaries with the concrete information the reader needs. Do not replace an unsupported claim with an invented example or a stronger guarantee. Keep necessary technical repetition and the project's established terminology.
|
|
277
|
+
3. Compare the edited document with the original and its sources. Restore any lost qualifier or caveat, verify command and code examples still work as documented, and explain any unresolved factual question rather than polishing it away.
|
|
278
|
+
|
|
271
279
|
## Common Rationalizations
|
|
272
280
|
|
|
273
281
|
| Rationalization | Reality |
|
|
@@ -298,3 +306,4 @@ After documenting:
|
|
|
298
306
|
- [ ] Known gotchas are documented inline where they matter
|
|
299
307
|
- [ ] No commented-out code remains
|
|
300
308
|
- [ ] Rules files (CLAUDE.md etc.) are current and accurate
|
|
309
|
+
- [ ] Prose edits preserve source details, decision trade-offs, and qualifiers without adding unsupported guarantees
|
|
@@ -29,6 +29,10 @@ Build production-quality user interfaces that are accessible, performant, and vi
|
|
|
29
29
|
- Adding interactivity or state management
|
|
30
30
|
- Fixing visual or UX issues
|
|
31
31
|
|
|
32
|
+
## Applicable Prototype Baselines
|
|
33
|
+
|
|
34
|
+
When the project has `.i3-ui-prototypes.json`, read the prototype entry applicable to the UI module being changed, then its `baseline.json`, `design-system/MASTER.md`, tokens and page rules. Preserve approved design and interaction decisions; explain conflicts with new requirements instead of silently changing them. New pages reuse the selected template and component conventions. Changes to global tokens, navigation, component behavior or business states go through the `i3-ui-prototype` workflow and corresponding review. HTML review prototypes need explicit component mapping when implemented in another framework. Verify affected production pages in the browser; a prototype manifest check alone does not prove production fidelity. Projects without an applicable baseline retain this skill's existing workflow.
|
|
35
|
+
|
|
32
36
|
## Component Architecture
|
|
33
37
|
|
|
34
38
|
### File Structure
|
|
@@ -91,7 +95,7 @@ export function TaskItem({ task, onToggle, onDelete }: TaskItemProps) {
|
|
|
91
95
|
```tsx
|
|
92
96
|
// Container: handles data
|
|
93
97
|
export function TaskListContainer() {
|
|
94
|
-
const { tasks, isLoading, error } = useTasks();
|
|
98
|
+
const { tasks, isLoading, error, refetch } = useTasks();
|
|
95
99
|
|
|
96
100
|
if (isLoading) return <TaskListSkeleton />;
|
|
97
101
|
if (error) return <ErrorState message="Failed to load tasks" retry={refetch} />;
|