@givolt/i3-composer-agent 2.3.7 → 3.1.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-sop.md +19 -0
- package/.claude/commands/i3-ui-demo.md +21 -0
- 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-sop.toml +19 -0
- package/.gemini/commands/i3-ui-demo.toml +21 -0
- package/README.md +42 -6
- package/bin/i3-composer-agent.cjs +38 -44
- package/bin/install.cjs +15 -3
- package/bin/native-layout.cjs +2 -1
- package/bin/native-migration.cjs +19 -2
- package/bin/retired-sop-fingerprints.json +213 -0
- package/bin/wizard.cjs +7 -18
- package/commands/i3-sop.toml +19 -0
- package/commands/i3-ui-demo.toml +21 -0
- package/docs/codebuddy-setup.md +20 -23
- package/docs/codex-setup.md +2 -2
- package/docs/comparison.md +131 -0
- package/docs/developer-onboarding.md +143 -0
- package/docs/opencode-setup.md +1 -1
- package/docs/other-hosts.md +2 -2
- package/docs/skill-anatomy.md +211 -0
- package/docs/upstream-repository/AGENTS.md +92 -0
- package/docs/upstream-repository/CLAUDE.md +60 -0
- package/docs/upstream-repository/CONTRIBUTING.md +137 -0
- package/docs/upstream-repository/README.md +8 -0
- package/docs/upstream-repository/gitattributes.txt +1 -0
- package/docs/upstream-repository/gitignore.txt +10 -0
- package/docs/upstream-repository/manifest.json +71 -0
- package/docs/upstream-repository/opencode-skills.link +1 -0
- package/docs/upstream-repository/skill-gap.yml +80 -0
- package/docs/upstream-repository/skills-contributing.md +15 -0
- package/docs/upstream-repository/test-plugin-install.yml +167 -0
- package/docs/workbuddy-setup.md +7 -10
- package/evals/cases/i3-enterprise-sop.json +64 -0
- package/evals/cases/i3-ui-demo.json +98 -0
- package/evals/fixtures/i3-enterprise-sop/brief.md +11 -0
- package/evals/fixtures/i3-ui-demo/asset-management.md +25 -0
- package/evals/zh-CN/cases/i3-enterprise-sop.json +61 -0
- package/evals/zh-CN/cases/i3-ui-demo.json +103 -0
- package/hooks/PROTOTYPE.md +16 -8
- package/hooks/i3-prototype.cjs +4 -10
- package/hooks/manage.cjs +30 -31
- package/package.json +48 -5
- package/plugin.json +1 -1
- package/scripts/ui-demo-dependencies-test.js +228 -0
- package/scripts/ui-demo-mcp-test.js +95 -0
- package/scripts/ui-demo-test.js +170 -0
- package/scripts/ui-prototype-execution-runtime-test.js +1 -1
- package/scripts/ui-prototype-native-test.js +25 -3
- package/skills/i3-enterprise-sop/SKILL.md +173 -0
- package/skills/i3-enterprise-sop/agents/openai.yaml +2 -0
- package/skills/i3-enterprise-sop/references/ad/assets-manifest.json +86 -0
- package/skills/i3-enterprise-sop/references/ad/prompts/01-generate.md +58 -0
- package/skills/i3-enterprise-sop/references/ad/prompts/02-review.md +54 -0
- package/skills/i3-enterprise-sop/references/ad/prompts/03-revise.md +54 -0
- package/skills/i3-enterprise-sop/references/ad/prompts/04-recheck.md +54 -0
- package/skills/i3-enterprise-sop/references/ad/readme.md +70 -0
- package/skills/i3-enterprise-sop/references/ad/templates/ad.md +337 -0
- package/skills/i3-enterprise-sop/references/assets-manifest.json +230 -0
- package/skills/i3-enterprise-sop/references/brd/assets-manifest.json +83 -0
- package/skills/i3-enterprise-sop/references/brd/prompts/01-generate.md +51 -0
- package/skills/i3-enterprise-sop/references/brd/prompts/02-review.md +47 -0
- package/skills/i3-enterprise-sop/references/brd/prompts/03-revise.md +47 -0
- package/skills/i3-enterprise-sop/references/brd/prompts/04-recheck.md +47 -0
- package/skills/i3-enterprise-sop/references/brd/readme.md +50 -0
- package/skills/i3-enterprise-sop/references/brd/templates/brd.md +169 -0
- package/skills/i3-enterprise-sop/references/codebuddy-project-guide.md +34 -0
- package/skills/i3-enterprise-sop/references/controlled-handoff.md +41 -0
- package/skills/i3-enterprise-sop/references/controlled_handoff.py +379 -0
- package/skills/i3-enterprise-sop/references/engineering-skeleton/adoption.md +200 -0
- package/skills/i3-enterprise-sop/references/engineering-skeleton/catalog.json +17 -0
- package/skills/i3-enterprise-sop/references/engineering-skeleton/directory-standard.md +119 -0
- package/skills/i3-enterprise-sop/references/engineering-skeleton/readme.md +52 -0
- package/skills/i3-enterprise-sop/references/handoff-contract.md +196 -0
- package/skills/i3-enterprise-sop/references/handoff.py +277 -0
- package/skills/i3-enterprise-sop/references/lifecycle-contract.md +91 -0
- package/skills/i3-enterprise-sop/references/plan-handoff.md +73 -0
- package/skills/i3-enterprise-sop/references/prd/assets-manifest.json +109 -0
- package/skills/i3-enterprise-sop/references/prd/prompts/01-generate.md +64 -0
- package/skills/i3-enterprise-sop/references/prd/prompts/02-review.md +49 -0
- package/skills/i3-enterprise-sop/references/prd/prompts/03-revise.md +48 -0
- package/skills/i3-enterprise-sop/references/prd/prompts/04-recheck.md +47 -0
- package/skills/i3-enterprise-sop/references/prd/readme.md +137 -0
- package/skills/i3-enterprise-sop/references/prd/template-contracts.md +39 -0
- package/skills/i3-enterprise-sop/references/prd/templates/ad.md +17 -0
- package/skills/i3-enterprise-sop/references/prd/templates/prd.md +257 -0
- package/skills/i3-enterprise-sop/references/readme.md +167 -0
- package/skills/i3-enterprise-sop/references/recovery-contract.md +65 -0
- package/skills/i3-enterprise-sop/references/review-handoff.md +105 -0
- package/skills/i3-enterprise-sop/references/selection-handoff.md +55 -0
- package/skills/i3-enterprise-sop/references/selection_handoff.py +225 -0
- package/skills/i3-enterprise-sop/references/stages.json +271 -0
- package/skills/i3-enterprise-sop/references/technical-baseline/assets-manifest.json +84 -0
- package/skills/i3-enterprise-sop/references/technical-baseline/baselines/enterprise-application-technical-baseline-v0-0-4.md +380 -0
- package/skills/i3-enterprise-sop/references/technical-baseline/readme.md +132 -0
- package/skills/i3-enterprise-sop/references/technical-baseline/templates/technical-baseline.md +133 -0
- package/skills/i3-enterprise-sop/references/template-contracts.md +142 -0
- package/skills/i3-enterprise-sop/references/testcase/assets-manifest.json +91 -0
- package/skills/i3-enterprise-sop/references/testcase/prompts/01-generate.md +53 -0
- package/skills/i3-enterprise-sop/references/testcase/prompts/02-review.md +51 -0
- package/skills/i3-enterprise-sop/references/testcase/prompts/03-revise.md +49 -0
- package/skills/i3-enterprise-sop/references/testcase/prompts/04-recheck.md +51 -0
- package/skills/i3-enterprise-sop/references/testcase/readme.md +61 -0
- package/skills/i3-enterprise-sop/references/testcase/templates/testcase.md +269 -0
- package/skills/i3-enterprise-sop/references/verification/check_execution.py +185 -0
- package/skills/i3-enterprise-sop/references/verification/check_native_execution.py +282 -0
- package/skills/i3-enterprise-sop/references/verification/check_reads.py +348 -0
- package/skills/i3-enterprise-sop/references/verification/readme.md +149 -0
- package/skills/i3-enterprise-sop/references/verification/review-output.schema.json +155 -0
- package/skills/i3-enterprise-sop/references/verification/review_handoff.py +329 -0
- package/skills/i3-ui-demo/SKILL.md +234 -0
- package/skills/i3-ui-demo/assets/antdv-build/package-lock.json +3363 -0
- package/skills/i3-ui-demo/assets/antdv-build/package.json +28 -0
- package/skills/i3-ui-demo/assets/design-source.json +11 -0
- package/skills/i3-ui-demo/assets/host-targets.json +739 -0
- package/skills/i3-ui-demo/assets/official-files.json +76 -0
- package/skills/i3-ui-demo/assets/starter/index.html +11 -0
- package/skills/i3-ui-demo/assets/starter/package-lock.json +2299 -0
- package/skills/i3-ui-demo/assets/starter/package.json +28 -0
- package/skills/i3-ui-demo/assets/starter/provenance.json +14 -0
- package/skills/i3-ui-demo/assets/starter/public/prototype-config.json +22 -0
- package/skills/i3-ui-demo/assets/starter/src/App.vue +64 -0
- package/skills/i3-ui-demo/assets/starter/src/PrototypeShell.vue +59 -0
- package/skills/i3-ui-demo/assets/starter/src/config.ts +23 -0
- package/skills/i3-ui-demo/assets/starter/src/domain/presentation.ts +30 -0
- package/skills/i3-ui-demo/assets/starter/src/domain/theme.ts +25 -0
- package/skills/i3-ui-demo/assets/starter/src/main.ts +18 -0
- package/skills/i3-ui-demo/assets/starter/src/style.css +26 -0
- package/skills/i3-ui-demo/assets/starter/tests/presentation.test.ts +23 -0
- package/skills/i3-ui-demo/assets/starter/tests/theme.test.ts +26 -0
- package/skills/i3-ui-demo/assets/starter/tsconfig.json +15 -0
- package/skills/i3-ui-demo/assets/starter/vite.config.ts +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/capability-definition.json +1395 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/component-inventory.json +707 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/design-system.md +26 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/generation.json +49 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/index.html +534 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/manifest.json +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/offline-build.json +265 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/offline.js +8888 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/origin.json +344 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/preset.json +928 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/app.js +22 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/empty.svg +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/reference-styles.json +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/result-403.svg +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/result-404.svg +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets-manifest.json +334 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/baseline.json +173 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/conversion.md +30 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/credits.md +17 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/design-tokens.json +881 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/index.html +28 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/licenses/@qin-ui-antdv-next-pro.txt +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/licenses/ant-design-icons.txt +22 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/licenses/antdv-next.txt +21 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/package.json +12 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/browser-routes.json +298 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/coverage.json +180 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/integrity.json +13 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/keyboard.json +11 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/responsive.json +125 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/review.md +51 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/rules.log +150 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-html.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-original.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-html.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-original.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/models-html.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/models-original.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-html.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-original.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/selection.json +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/visual-comparison.json +342 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/readme.md +73 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/reference.md +59 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/routes.json +178 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/controls.js +99 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/dialogs.js +54 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/dom.js +264 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/forms.js +47 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/icons.js +41 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/layout.js +47 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/router.js +63 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/state.js +90 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/table.js +41 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/widgets.js +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.js +36 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.js +51 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.js +48 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/CheckResults.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/CheckResults.js +6 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.js +13 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/data.js +24 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/domain.js +32 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/registry.js +25 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/store.js +85 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentClose.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentClose.js +17 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.js +66 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.js +38 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.js +66 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.js +5 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.js +12 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.js +11 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentList.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentList.js +116 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.js +32 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.js +49 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.js +10 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.js +77 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/data.js +60 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/domain.js +105 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/store.js +212 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/AuditPanel.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/AuditPanel.js +18 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelDetail.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelDetail.js +23 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelEditor.js +78 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelGrant.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelGrant.js +55 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelReferences.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelReferences.js +26 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelRelease.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelRelease.js +38 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelStatus.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelStatus.js +7 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTable.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTable.js +72 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTester.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTester.js +46 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelsPage.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelsPage.js +52 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/RowActions.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/RowActions.js +19 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/UsagePanel.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/UsagePanel.js +30 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/data.js +48 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/domain.js +39 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/store.js +129 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.html +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.js +21 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IntentSource.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IntentSource.js +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.js +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.js +10 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.js +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.js +49 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RunDetail.html +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RunDetail.js +22 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.js +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/commands.js +82 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/examples.js +47 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/model.js +61 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/repair.js +68 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/store.js +55 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/types.js +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/workbench.js +18 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.js +28 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.js +18 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.js +31 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.js +27 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.js +16 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.js +43 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.html +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.js +34 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.js +30 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.js +67 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.js +41 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.js +31 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.js +26 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.js +70 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/data.js +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/domain.js +62 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/management.js +36 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/managementStore.js +49 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/store.js +132 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/AdminList.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/AdminList.js +38 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.js +11 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.js +45 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.js +54 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.js +27 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.js +12 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.js +45 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.js +38 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/domain.js +61 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/state.js +51 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/store.js +116 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.js +45 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.html +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.js +30 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.js +67 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.js +5 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.html +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.js +60 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/commands.js +157 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/model.js +136 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/store.js +76 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.js +26 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.js +14 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.js +113 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.js +62 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/commands.js +97 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/model.js +147 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/store.js +13 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.js +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.js +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.js +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListMore.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListMore.js +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.js +17 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/columns.js +32 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/deliveryGuide.js +49 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/deliveryView.js +12 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/listBatch.js +15 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/listSelection.js +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/policy.js +68 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/session.js +44 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.js +25 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.js +53 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.html +10 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.js +30 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ScopePage.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ScopePage.js +10 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.js +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/confirmation.js +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/navigation.js +19 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.js +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.js +32 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.js +15 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.js +11 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecReview.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecReview.js +57 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.js +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/data.js +20 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/domain.js +55 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/store.js +151 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.js +18 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.js +40 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.js +51 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.js +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.html +5 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.js +48 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/domain.js +204 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/exampleSource.js +22 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/registry.js +135 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/store.js +137 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.js +36 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/model.js +56 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/store.js +15 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.js +27 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.html +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.js +31 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.js +68 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.html +5 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.js +55 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/data.js +16 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/domain.js +83 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/registry.js +18 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/store.js +61 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/admin.css +60 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/agents.css +46 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/antdv.css +295 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/app.css +102 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/delivery.css +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/intents.css +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/native.css +22 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/operations.css +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/pbc.css +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/permissions.css +22 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/pro.css +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/releases.css +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/reset.css +246 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/reviews.css +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/tasks.css +6 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/tokens.css +15 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/workbench.css +61 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/workflows.css +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/admin-rules.test.js +96 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/agents.test.js +14 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/intent-state.test.js +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/list-batch.test.js +44 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/operation-fixtures.js +19 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/operation-repair.test.js +14 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/operations.test.js +25 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/pbc-management.test.js +17 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/pbc-state.test.js +24 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/permission-config.test.js +23 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/permissions.test.js +24 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/releases.test.js +50 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/reviews.test.js +36 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/runtime-forms-router.test.js +28 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/runtime-state.test.js +42 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/runtime-stores.test.js +16 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/spec-state.test.js +11 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/tasks.test.js +27 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/workbench.test.js +34 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/workflows.test.js +16 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/convert.mjs +168 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/serve.mjs +7 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/styles.mjs +11 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/verify.mjs +24 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/serve.cjs +16 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/template-inventory.json +28791 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/template.json +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/usability.css +44 -0
- package/skills/i3-ui-demo/assets/templates.json +10 -0
- package/skills/i3-ui-demo/assets/versions.json +20 -0
- package/skills/i3-ui-demo/readme.md +350 -0
- package/skills/i3-ui-demo/references/browser.md +71 -0
- package/skills/i3-ui-demo/references/dependencies.md +67 -0
- package/skills/i3-ui-demo/references/resources.md +142 -0
- package/skills/i3-ui-demo/scripts/dependencies.cjs +364 -0
- package/skills/i3-ui-demo/scripts/design-install.cjs +105 -0
- package/skills/i3-ui-demo/scripts/design-provider.cjs +57 -0
- package/skills/i3-ui-demo/scripts/locations.cjs +52 -0
- package/skills/i3-ui-demo/scripts/mcp.cjs +112 -0
- package/skills/i3-ui-demo/scripts/provider-discovery.cjs +131 -0
- package/skills/i3-ui-demo/scripts/resources.cjs +283 -0
- package/skills/i3-ui-prototype/SKILL.md +1 -1
- package/skills/i3-ui-prototype/references/execution-evidence.md +12 -56
- package/skills/i3-ui-prototype/scripts/codebuddy-registration.cjs +1 -1
- package/skills/i3-ui-prototype/scripts/execution-runtime.cjs +5 -2
- package/skills/i3-ui-prototype/scripts/hosts/codebuddy.cjs +3 -2
- package/skills/i3-ui-prototype/scripts/native-delivery.cjs +2 -2
- package/skills/i3-ui-prototype/scripts/prototype-hooks.cjs +23 -20
- package/docs/ui-prototype-native/MAIN-SESSION-REPORT.md +0 -66
- package/docs/ui-prototype-native/USAGE.md +0 -93
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""CodeBuddy native-method evidence/report audit, v0.1.1; read-only stdout.
|
|
3
|
+
|
|
4
|
+
Separate from the direct-python helper profile in check_execution.py. A frozen
|
|
5
|
+
caller scope defines evidence obligations; neither the model nor this checker
|
|
6
|
+
creates business approval. Does not execute tools or modify project files.
|
|
7
|
+
"""
|
|
8
|
+
import argparse
|
|
9
|
+
import hashlib
|
|
10
|
+
import json
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
import re
|
|
13
|
+
import stat
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
START = '<!-- i3-sop-native-execution-report -->'
|
|
17
|
+
END = '<!-- /i3-sop-native-execution-report -->'
|
|
18
|
+
PROFILES = ('generation', 'status', 'plan', 'auto-preflight', 'standard')
|
|
19
|
+
GATE_STATES = ('not_applicable', 'not_checked', 'pending', 'blocked', 'satisfied')
|
|
20
|
+
INPUT_STATES = ('full', 'partial', 'not_read')
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def unique_object(pairs):
|
|
24
|
+
out = {}
|
|
25
|
+
for key, value in pairs:
|
|
26
|
+
if key in out:
|
|
27
|
+
raise ValueError('duplicate_json_key:' + key)
|
|
28
|
+
out[key] = value
|
|
29
|
+
return out
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def loads(text):
|
|
33
|
+
return json.loads(text, object_pairs_hook=unique_object,
|
|
34
|
+
parse_constant=lambda value: (_ for _ in ()).throw(ValueError('invalid_constant:' + value)))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def inventory(root):
|
|
38
|
+
files = {}
|
|
39
|
+
for p in Path(root).rglob('*'):
|
|
40
|
+
if '.git' in p.relative_to(root).parts:
|
|
41
|
+
continue
|
|
42
|
+
if p.is_symlink():
|
|
43
|
+
files[str(p.relative_to(root))] = {'symlink': str(p.readlink())}
|
|
44
|
+
elif p.is_file():
|
|
45
|
+
files[str(p.relative_to(root))] = {
|
|
46
|
+
'sha256': hashlib.sha256(p.read_bytes()).hexdigest(),
|
|
47
|
+
'mode': stat.S_IMODE(p.stat().st_mode)}
|
|
48
|
+
return files
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def content(block):
|
|
52
|
+
raw = block.get('content', '')
|
|
53
|
+
return raw if isinstance(raw, str) else '\n'.join(
|
|
54
|
+
row.get('text', '') for row in raw if isinstance(row, dict)) if isinstance(raw, list) else ''
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def outcome(result, tool):
|
|
58
|
+
if result is None:
|
|
59
|
+
return 'unconfirmed', 'missing_tool_result'
|
|
60
|
+
text = content(result)
|
|
61
|
+
error_carrier = result.get('is_error') or re.match(r'^\s*(?:Error:|Permission denied\b)', text)
|
|
62
|
+
if error_carrier and re.search(r'permission[^\n]*(denied|not allowed)|not (?:been )?granted permission', text, re.I):
|
|
63
|
+
return 'blocked', 'permission_denial'
|
|
64
|
+
if result.get('is_error') or re.match(r'^\s*Error:', text):
|
|
65
|
+
return 'failed', 'tool_flag_or_error_text'
|
|
66
|
+
if tool == 'Bash':
|
|
67
|
+
codes = re.findall(r'^Exit Code:\s*(-?\d+)\s*$', text, re.M | re.I)
|
|
68
|
+
if len(codes) != 1:
|
|
69
|
+
return 'unconfirmed', 'shell_exit_not_proven'
|
|
70
|
+
if int(codes[0]) != 0:
|
|
71
|
+
return 'failed', 'nonzero_process_exit'
|
|
72
|
+
return 'succeeded', 'tool_receipt'
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def trace_calls(events):
|
|
76
|
+
calls, results, issues = [], {}, []
|
|
77
|
+
ids = set()
|
|
78
|
+
for seq, event in enumerate(events):
|
|
79
|
+
blocks = (event.get('message') or {}).get('content', [])
|
|
80
|
+
if not isinstance(blocks, list):
|
|
81
|
+
continue
|
|
82
|
+
for block in blocks:
|
|
83
|
+
if not isinstance(block, dict):
|
|
84
|
+
continue
|
|
85
|
+
if event.get('type') == 'assistant' and block.get('type') == 'tool_use':
|
|
86
|
+
ident = block.get('id')
|
|
87
|
+
if not isinstance(ident, str) or ident in ids:
|
|
88
|
+
issues.append('missing_or_duplicate_tool_call_id')
|
|
89
|
+
ids.add(ident)
|
|
90
|
+
calls.append({**block, 'seq': seq})
|
|
91
|
+
elif event.get('type') == 'user' and block.get('type') == 'tool_result':
|
|
92
|
+
ident = block.get('tool_use_id')
|
|
93
|
+
if ident not in ids or ident in results:
|
|
94
|
+
issues.append('orphan_or_duplicate_tool_result')
|
|
95
|
+
results[ident] = (seq, block)
|
|
96
|
+
return calls, results, issues
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def report_block(text):
|
|
100
|
+
if text.count(START) != 1 or text.count(END) != 1:
|
|
101
|
+
raise ValueError('exactly_one_native_report_block_required')
|
|
102
|
+
block = text.split(START, 1)[1].split(END, 1)[0].strip()
|
|
103
|
+
match = re.fullmatch(r'```json\s*\n(.*?)\n```', block, re.S)
|
|
104
|
+
if not match:
|
|
105
|
+
raise ValueError('native_report_json_fence_required')
|
|
106
|
+
value = loads(match[1])
|
|
107
|
+
if not isinstance(value, dict) or set(value) != {'schemaVersion', 'failedAttempts', 'inputChecks', 'gates'}:
|
|
108
|
+
raise ValueError('native_report_root_contract_mismatch')
|
|
109
|
+
if type(value['schemaVersion']) is not int or value['schemaVersion'] != 1:
|
|
110
|
+
raise ValueError('native_report_version_mismatch')
|
|
111
|
+
for key, fields in [('failedAttempts', {'tool', 'subject', 'status'}),
|
|
112
|
+
('inputChecks', {'path', 'status'}), ('gates', {'id', 'status'})]:
|
|
113
|
+
if not isinstance(value[key], list) or any(not isinstance(row, dict) or set(row) != fields for row in value[key]):
|
|
114
|
+
raise ValueError('native_report_rows_invalid:' + key)
|
|
115
|
+
if any(not isinstance(item, str) for row in value[key] for item in row.values()):
|
|
116
|
+
raise ValueError('native_report_values_must_be_strings:' + key)
|
|
117
|
+
if any(row['status'] not in ('blocked', 'failed', 'unconfirmed') for row in value['failedAttempts']):
|
|
118
|
+
raise ValueError('native_attempt_state_invalid')
|
|
119
|
+
if any(row['status'] not in INPUT_STATES for row in value['inputChecks']):
|
|
120
|
+
raise ValueError('native_input_state_invalid')
|
|
121
|
+
if any(row['status'] not in GATE_STATES for row in value['gates']):
|
|
122
|
+
raise ValueError('native_gate_state_invalid')
|
|
123
|
+
return value
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def assess(root, scope, events, process, legacy_report=False):
|
|
127
|
+
root = Path(root).resolve()
|
|
128
|
+
if scope.get('profile') not in PROFILES:
|
|
129
|
+
raise ValueError('unknown_native_profile')
|
|
130
|
+
for key in ('requiredReads', 'reportInputs', 'allowedWrites', 'requiredSkills', 'files', 'gateExpectations'):
|
|
131
|
+
if key not in scope:
|
|
132
|
+
raise ValueError('frozen_scope_missing:' + key)
|
|
133
|
+
if any(path != '.codebuddy/.i3-composer-agent.json' for path in scope.get('requiredReadLines', {})):
|
|
134
|
+
raise ValueError('selected_line_exception_is_locator_metadata_only')
|
|
135
|
+
calls, results, trace_issues = trace_calls(events)
|
|
136
|
+
attempts, reads, writes, methods, forbidden = [], [], [], [], []
|
|
137
|
+
def relative(raw):
|
|
138
|
+
p = Path(raw)
|
|
139
|
+
p = (p if p.is_absolute() else root / p).resolve()
|
|
140
|
+
return str(p.relative_to(root)) if p.is_relative_to(root) else str(p)
|
|
141
|
+
for call in calls:
|
|
142
|
+
args = call.get('input') or {}
|
|
143
|
+
returned = results.get(call['id'])
|
|
144
|
+
receipt = returned[1] if returned else None
|
|
145
|
+
status, reason = outcome(receipt, call['name'])
|
|
146
|
+
text = content(receipt or {})
|
|
147
|
+
raw = args.get('file_path') or args.get('path')
|
|
148
|
+
path = relative(raw) if isinstance(raw, str) else None
|
|
149
|
+
tool = call['name']
|
|
150
|
+
subject = args.get('skill', '') if tool == 'Skill' else args.get('command', '') if tool == 'Bash' else path or ''
|
|
151
|
+
attempts.append({'ordinal': len(attempts) + 1, 'toolCallId': call['id'], 'traceLine': call['seq'] + 1,
|
|
152
|
+
'resultLine': returned[0] + 1 if returned else None, 'tool': tool, 'subject': subject,
|
|
153
|
+
'status': status, 'statusEvidence': reason})
|
|
154
|
+
if path and (Path(path).is_absolute() or path in scope.get('forbiddenReads', [])
|
|
155
|
+
or any(path == prefix or path.startswith(prefix.rstrip('/') + '/')
|
|
156
|
+
for prefix in scope.get('forbiddenAccessPrefixes', []))):
|
|
157
|
+
forbidden.append(path)
|
|
158
|
+
if tool == 'Read' and status == 'succeeded':
|
|
159
|
+
reads.append({'path': path, 'seq': returned[0], 'requestSeq': call['seq'],
|
|
160
|
+
'lines': {int(n): value for n, value in re.findall(r'^\s*(\d+)→(.*)$', text, re.M)}})
|
|
161
|
+
if tool == 'Grep' and path in scope.get('requiredReadLines', {}) and status == 'succeeded':
|
|
162
|
+
# This exception is only for locator metadata; caller explicitly freezes those lines.
|
|
163
|
+
try:
|
|
164
|
+
parts = loads(text)
|
|
165
|
+
except ValueError:
|
|
166
|
+
parts = text.splitlines()
|
|
167
|
+
selected = {}
|
|
168
|
+
for part in parts if isinstance(parts, list) else []:
|
|
169
|
+
match = re.match(re.escape(str(root / path)) + r':(\d+):(.*)$', str(part))
|
|
170
|
+
if match:
|
|
171
|
+
selected[int(match[1])] = match[2]
|
|
172
|
+
reads.append({'path': path, 'seq': returned[0], 'requestSeq': call['seq'], 'lines': selected})
|
|
173
|
+
if tool in ('Write', 'Edit'):
|
|
174
|
+
writes.append({'path': path, 'seq': call['seq'],
|
|
175
|
+
'receiptSeq': returned[0] if returned else float('inf'), 'status': status})
|
|
176
|
+
if tool == 'Skill':
|
|
177
|
+
local = root / '.codebuddy/skills' / str(subject) / 'SKILL.md'
|
|
178
|
+
valid_name = bool(re.fullmatch(r'[a-z][a-z0-9-]*', str(subject)))
|
|
179
|
+
body = local.read_text().split('---', 2)[-1].strip() if valid_name and local.is_file() else None
|
|
180
|
+
methods.append({'name': subject, 'seq': returned[0] if returned else float('inf'), 'success': status == 'succeeded',
|
|
181
|
+
'fullLocalBody': bool(body and body in text and str(local.parent) in text)})
|
|
182
|
+
first = min((row['seq'] for row in writes), default=float('inf'))
|
|
183
|
+
def coverage(path, before=float('inf'), after=-1, selected=None):
|
|
184
|
+
observed = {}
|
|
185
|
+
for read in reads:
|
|
186
|
+
if read['path'] == path and after < read['seq'] < before and (after < 0 or read['requestSeq'] > after):
|
|
187
|
+
observed.update(read['lines'])
|
|
188
|
+
p = root / path
|
|
189
|
+
lines = p.read_text().splitlines() if p.is_file() else []
|
|
190
|
+
wanted = list(selected) if selected is not None else list(range(1, len(lines) + 1))
|
|
191
|
+
correct = [n for n in wanted if 1 <= n <= len(lines) and observed.get(n) == lines[n - 1]]
|
|
192
|
+
state = 'full' if wanted and len(correct) == len(wanted) else 'partial' if observed else 'not_read'
|
|
193
|
+
return {'path': path, 'status': state, 'requiredLines': len(wanted), 'matchedLines': len(correct)}
|
|
194
|
+
required = [coverage(path, before=first, selected=scope.get('requiredReadLines', {}).get(path))
|
|
195
|
+
for path in scope['requiredReads']]
|
|
196
|
+
targets = []
|
|
197
|
+
for path in scope['allowedWrites']:
|
|
198
|
+
last = max((row['receiptSeq'] for row in writes if row['path'] == path and row['status'] == 'succeeded'), default=None)
|
|
199
|
+
targets.append(coverage(path, after=last if last is not None else float('inf')))
|
|
200
|
+
current = inventory(root)
|
|
201
|
+
changed = sorted(name for name in set(current) | set(scope['files']) if current.get(name) != scope['files'].get(name))
|
|
202
|
+
boundary_issues = ['unexpected_file_change:' + name for name in changed if name not in scope['allowedWrites']]
|
|
203
|
+
boundary_issues += ['write_attempt_outside_scope:' + str(row['path']) for row in writes if row['path'] not in scope['allowedWrites']]
|
|
204
|
+
boundary_issues += ['forbidden_or_outside_access:' + path for path in forbidden]
|
|
205
|
+
discipline = list(trace_issues)
|
|
206
|
+
allowed_tools = scope.get('tools', scope.get('allowedTools', []))
|
|
207
|
+
for row in attempts:
|
|
208
|
+
if row['tool'] not in allowed_tools:
|
|
209
|
+
discipline.append('tool_outside_scope:' + row['tool'])
|
|
210
|
+
if row['tool'] == 'Bash' and row['subject'] not in scope.get('allowedShellCommands', []):
|
|
211
|
+
discipline.append('shell_command_outside_exact_scope:' + row['subject'])
|
|
212
|
+
if row['status'] != 'succeeded':
|
|
213
|
+
discipline.append('tool_attempt_' + row['status'] + ':' + str(row['ordinal']))
|
|
214
|
+
method_issues = []
|
|
215
|
+
for skill in scope['requiredSkills']:
|
|
216
|
+
if not any(row['name'] == skill and row['success'] and row['fullLocalBody'] and row['seq'] < first for row in methods):
|
|
217
|
+
method_issues.append('required_native_skill_not_loaded:' + skill)
|
|
218
|
+
method_issues += ['forbidden_skill_loaded:' + row['name'] for row in methods if row['name'] in scope.get('forbiddenSkills', [])]
|
|
219
|
+
finals = [event for event in events if event.get('type') == 'result']
|
|
220
|
+
text = finals[-1].get('result', '') if finals else ''
|
|
221
|
+
report_issues, gate_issues = [], []
|
|
222
|
+
reporting_status = 'checked'
|
|
223
|
+
if legacy_report and START not in text:
|
|
224
|
+
reporting_status = 'not_checked_legacy'
|
|
225
|
+
report_issues.append('old_native_report_preserved_no_retroactive_format_claim')
|
|
226
|
+
else:
|
|
227
|
+
try:
|
|
228
|
+
report = report_block(text)
|
|
229
|
+
actual_failed = [{key: row[key] for key in ('tool', 'subject', 'status')}
|
|
230
|
+
for row in attempts if row['status'] != 'succeeded']
|
|
231
|
+
if report['failedAttempts'] != actual_failed:
|
|
232
|
+
report_issues.append('failed_attempts_do_not_match_trace')
|
|
233
|
+
expected_inputs = [{'path': path, 'status': coverage(path, selected=scope.get('requiredReadLines', {}).get(path))['status']}
|
|
234
|
+
for path in scope['reportInputs']]
|
|
235
|
+
if sorted(report['inputChecks'], key=lambda row: row['path']) != sorted(expected_inputs, key=lambda row: row['path']):
|
|
236
|
+
report_issues.append('input_claims_do_not_match_actual_reads')
|
|
237
|
+
expected_gates = [{'id': key, 'status': value} for key, value in scope['gateExpectations'].items()]
|
|
238
|
+
if sorted(report['gates'], key=lambda row: row['id']) != sorted(expected_gates, key=lambda row: row['id']):
|
|
239
|
+
gate_issues.append('gate_claims_differ_from_frozen_expectations')
|
|
240
|
+
except (ValueError, TypeError, KeyError) as exc:
|
|
241
|
+
report_issues.append(str(exc))
|
|
242
|
+
gate_issues.append('gate_report_not_validated')
|
|
243
|
+
if attempts and re.search(r'(?:^|[;;])\s*(?:无\s*(?:Bash\s*[//、和]\s*)?工具调用|未调用任何工具)\s*(?:[。;;]|$)', text, re.M):
|
|
244
|
+
report_issues.append('narrative_no_tools_claim_contradicts_trace')
|
|
245
|
+
if any(row['tool'] == 'Bash' for row in attempts) and re.search(r'(?:^|[;;])\s*无\s*Bash(?:\s*[,,。;;]|\s*$)', text, re.M):
|
|
246
|
+
report_issues.append('narrative_no_bash_claim_contradicts_trace')
|
|
247
|
+
completed = bool(process.get('exitCode') == 0 and not process.get('timedOut') and finals and not finals[-1].get('is_error'))
|
|
248
|
+
sections = {
|
|
249
|
+
'completion': {'passed': completed},
|
|
250
|
+
'inputs': {'passed': all(row['status'] == 'full' for row in required), 'checks': required},
|
|
251
|
+
'targets': {'passed': all(row['status'] == 'full' for row in targets), 'checks': targets},
|
|
252
|
+
'boundaries': {'passed': not boundary_issues, 'issues': boundary_issues, 'changedFiles': changed},
|
|
253
|
+
'nativeMethods': {'passed': not method_issues, 'issues': method_issues, 'loads': methods},
|
|
254
|
+
'toolDiscipline': {'passed': not discipline, 'issues': discipline},
|
|
255
|
+
'reportConsistency': {'passed': not report_issues, 'status': reporting_status, 'issues': report_issues},
|
|
256
|
+
'gateReport': {'passed': not gate_issues, 'issues': gate_issues,
|
|
257
|
+
'scope': 'matches caller test expectations; not human approval or semantic gate certification'}}
|
|
258
|
+
return {'checkerVersion': '0.1.1', 'profile': scope['profile'],
|
|
259
|
+
'passed': all(section['passed'] for section in sections.values()), **sections, 'attempts': attempts,
|
|
260
|
+
'proofScope': 'literal reads, local method load, file/tool boundary and structured report evidence; narrative semantics require human review',
|
|
261
|
+
'businessApproved': False, 'implementationApproved': False, 'published': False}
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def main():
|
|
265
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
266
|
+
for name in ('project-root', 'scope', 'trace', 'process'):
|
|
267
|
+
parser.add_argument('--' + name, required=True)
|
|
268
|
+
parser.add_argument('--legacy-report', action='store_true')
|
|
269
|
+
args = parser.parse_args()
|
|
270
|
+
try:
|
|
271
|
+
scope = loads(Path(args.scope).read_text())
|
|
272
|
+
events = [loads(line) for line in Path(args.trace).read_text().splitlines() if line.strip()]
|
|
273
|
+
result = assess(Path(args.project_root), scope, events, loads(Path(args.process).read_text()), args.legacy_report)
|
|
274
|
+
print(json.dumps(result, ensure_ascii=False, indent=2))
|
|
275
|
+
return 0 if result['passed'] else 1
|
|
276
|
+
except (OSError, ValueError, TypeError, KeyError) as exc:
|
|
277
|
+
print(json.dumps({'passed': False, 'error': str(exc), 'businessApproved': False}, ensure_ascii=False))
|
|
278
|
+
return 1
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
if __name__ == '__main__':
|
|
282
|
+
sys.exit(main())
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
"""Read-only checker for CodeBuddy stream-json evidence. No project or report writes."""
|
|
2
|
+
import json,re
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
def assess(project_root, scope, events):
|
|
6
|
+
root=Path(project_root).resolve()
|
|
7
|
+
def relative(raw):
|
|
8
|
+
p=Path(raw);p=(p if p.is_absolute() else root/p).resolve()
|
|
9
|
+
return str(p.relative_to(root)) if p.is_relative_to(root) else str(p)
|
|
10
|
+
calls=[];results={};finals=[]
|
|
11
|
+
for seq,event in enumerate(events):
|
|
12
|
+
if event.get('type')=='result':finals.append(event)
|
|
13
|
+
message=event.get('message',{})
|
|
14
|
+
if not isinstance(message,dict):continue
|
|
15
|
+
for block in message.get('content',[]):
|
|
16
|
+
if not isinstance(block,dict):continue
|
|
17
|
+
if event.get('type')=='assistant' and block.get('type')=='tool_use':
|
|
18
|
+
calls.append({**block,'event':seq})
|
|
19
|
+
if event.get('type')=='user' and block.get('type')=='tool_result':
|
|
20
|
+
results[block['tool_use_id']]={**block,'receiptEvent':seq}
|
|
21
|
+
reads=[];writes=[];errors=[]
|
|
22
|
+
for call in calls:
|
|
23
|
+
inp=call.get('input',{});result=results.get(call['id'])
|
|
24
|
+
raw=inp.get('file_path') or inp.get('path')
|
|
25
|
+
path=relative(raw) if raw else None
|
|
26
|
+
success=result is not None and not result.get('is_error',False)
|
|
27
|
+
item={'tool':call['name'],'path':path,'event':call['event'],
|
|
28
|
+
'receiptEvent':result['receiptEvent'] if result else float('inf'),'successful':success}
|
|
29
|
+
if call['name']=='Read':
|
|
30
|
+
data=result.get('content',[]) if result else []
|
|
31
|
+
text=data if isinstance(data,str) else '\n'.join(x.get('text','') for x in data if isinstance(x,dict))
|
|
32
|
+
reads.append({**item,'lines':[int(n) for n in re.findall(r'^\s*(\d+)→',text,re.M)]})
|
|
33
|
+
elif call['name'] in ['Write','Edit','Bash','PowerShell','NotebookEdit','Skill','Task','Agent']:
|
|
34
|
+
writes.append(item)
|
|
35
|
+
if result and result.get('is_error'):errors.append(item)
|
|
36
|
+
allowed={relative(p) for p in scope.get('allowedWrites',[])}
|
|
37
|
+
first_write=min((x['event'] for x in writes if x['successful']),default=float('inf'))
|
|
38
|
+
coverage=[]
|
|
39
|
+
for raw in scope['requiredReads']:
|
|
40
|
+
path=relative(raw);p=root/path
|
|
41
|
+
count=scope.get('beforeLineCounts',{}).get(raw)
|
|
42
|
+
if count is None:count=len(p.read_text().splitlines()) if p.is_file() else None
|
|
43
|
+
observed=[x for x in reads if x['path']==path and x['successful'] and x['receiptEvent']<first_write]
|
|
44
|
+
lines={n for x in observed for n in x['lines']}
|
|
45
|
+
full=count is not None and bool(observed) and all(n in lines for n in range(1,count+1))
|
|
46
|
+
coverage.append({'path':path,'exists':p.is_file(),'expectedLines':count,'successfulRead':bool(observed),'fullRead':full})
|
|
47
|
+
missing=[x['path'] for x in coverage if not x['successfulRead']]
|
|
48
|
+
partial=[x['path'] for x in coverage if x['successfulRead'] and not x['fullRead']]
|
|
49
|
+
explicit_external={relative(p) for p in scope['requiredReads'] if Path(relative(p)).is_absolute()}
|
|
50
|
+
forbidden=[]
|
|
51
|
+
for read in reads:
|
|
52
|
+
p=read['path']
|
|
53
|
+
if read['successful'] and ((Path(p).is_absolute() and p not in explicit_external) or any(p==relative(x) or p.startswith(relative(x).rstrip('/')+'/') for x in scope.get('forbiddenAccessPrefixes',[]))):forbidden.append(p)
|
|
54
|
+
targets=[]
|
|
55
|
+
for path in sorted(allowed):
|
|
56
|
+
p=root/path;changes=[x for x in writes if x['path']==path and x['successful'] and x['tool'] in ['Write','Edit']]
|
|
57
|
+
last=max((x['receiptEvent'] for x in changes),default=float('inf'))
|
|
58
|
+
final_reads=[x for x in reads if x['path']==path and x['successful'] and x['event']>last and x['receiptEvent']>last]
|
|
59
|
+
count=len(p.read_text().splitlines()) if p.is_file() else None
|
|
60
|
+
lines={n for x in final_reads for n in x['lines']}
|
|
61
|
+
full=bool(changes and final_reads) and count is not None and all(n in lines for n in range(1,count+1))
|
|
62
|
+
targets.append({'path':path,'lastWriteEvent':last if changes else None,'finalLines':count,'fullReadAfterLastEdit':full})
|
|
63
|
+
failures=[]
|
|
64
|
+
if not finals or finals[-1].get('is_error',False):failures.append('native_final_not_proven')
|
|
65
|
+
if missing:failures.append('required_read_missing')
|
|
66
|
+
if partial:failures.append('required_read_incomplete')
|
|
67
|
+
if forbidden:failures.append('forbidden_source_read')
|
|
68
|
+
if any(x['tool'] not in ['Write','Edit'] or x['path'] not in allowed for x in writes):failures.append('tool_or_write_boundary')
|
|
69
|
+
if any(not x['fullReadAfterLastEdit'] for x in targets):failures.append('final_full_read_incomplete')
|
|
70
|
+
return {'format':'i3-read-evidence/v1','passed':not failures,'failures':failures,'requiredReadCoverage':coverage,
|
|
71
|
+
'missingReads':missing,'partialReads':partial,'forbiddenReads':sorted(set(forbidden)),'targetChecks':targets,
|
|
72
|
+
'observedReads':reads,'observedWrites':writes,'toolErrors':errors,
|
|
73
|
+
'proofScope':'actual native reads and final read coverage only; not semantic correctness, approval or runtime interception'}
|
|
74
|
+
|
|
75
|
+
def _schema_errors(value, node, schema, location='$'):
|
|
76
|
+
"""Validate only the keywords used by our bundled contract, without dependencies.
|
|
77
|
+
|
|
78
|
+
This is not a general JSON Schema engine. Unknown keywords fail closed.
|
|
79
|
+
"""
|
|
80
|
+
supported = {'$schema', '$id', 'title', 'description', 'type', 'required', 'properties',
|
|
81
|
+
'additionalProperties', 'items', 'minItems', 'minimum', 'minLength',
|
|
82
|
+
'enum', '$ref', '$defs'}
|
|
83
|
+
if set(node) - supported:
|
|
84
|
+
raise ValueError('unsupported bundled schema keyword at ' + location)
|
|
85
|
+
if '$ref' in node:
|
|
86
|
+
prefix = '#/$defs/'
|
|
87
|
+
ref = node['$ref']
|
|
88
|
+
if not ref.startswith(prefix):
|
|
89
|
+
raise ValueError('only bundled local schema references are supported')
|
|
90
|
+
return _schema_errors(value, schema['$defs'][ref[len(prefix):]], schema, location)
|
|
91
|
+
types = {'object': lambda x: isinstance(x, dict), 'array': lambda x: isinstance(x, list),
|
|
92
|
+
'string': lambda x: isinstance(x, str), 'integer': lambda x: type(x) is int}
|
|
93
|
+
kind = node.get('type')
|
|
94
|
+
if kind and (kind not in types or not types[kind](value)):
|
|
95
|
+
return [location + ': expected ' + str(kind)]
|
|
96
|
+
errors = []
|
|
97
|
+
if 'enum' in node and value not in node['enum']:
|
|
98
|
+
errors.append(location + ': value outside enum')
|
|
99
|
+
if kind == 'object':
|
|
100
|
+
properties = node.get('properties', {})
|
|
101
|
+
errors += [location + '.' + key + ': missing' for key in node.get('required', []) if key not in value]
|
|
102
|
+
if node.get('additionalProperties') is False:
|
|
103
|
+
errors += [location + '.' + key + ': unknown field' for key in value if key not in properties]
|
|
104
|
+
for key in value.keys() & properties.keys():
|
|
105
|
+
errors += _schema_errors(value[key], properties[key], schema, location + '.' + key)
|
|
106
|
+
elif kind == 'array':
|
|
107
|
+
if len(value) < node.get('minItems', 0):
|
|
108
|
+
errors.append(location + ': too few items')
|
|
109
|
+
for index, item in enumerate(value):
|
|
110
|
+
errors += _schema_errors(item, node.get('items', {}), schema, f'{location}[{index}]')
|
|
111
|
+
elif kind == 'string' and len(value.strip()) < node.get('minLength', 0):
|
|
112
|
+
errors.append(location + ': empty string')
|
|
113
|
+
elif kind == 'integer' and value < node.get('minimum', value):
|
|
114
|
+
errors.append(location + ': below minimum')
|
|
115
|
+
return errors
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _source_role_bindings(scope):
|
|
119
|
+
"""One caller-owned role table for both schema generation and evidence checks."""
|
|
120
|
+
if not isinstance(scope, dict):
|
|
121
|
+
raise ValueError('review scope must be an object')
|
|
122
|
+
roles = scope.get('sourceRoles', {})
|
|
123
|
+
required = scope.get('requiredSourceRoles', [])
|
|
124
|
+
if (not isinstance(roles, dict)
|
|
125
|
+
or not all(isinstance(k, str) and isinstance(v, str) and k.strip() and v.strip() for k, v in roles.items())
|
|
126
|
+
or not isinstance(required, list)
|
|
127
|
+
or any(not isinstance(k, str) or k not in roles for k in required)):
|
|
128
|
+
raise ValueError('sourceRoles/requiredSourceRoles must be explicit caller bindings')
|
|
129
|
+
return dict(roles), list(required)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def build_review_schema(scope):
|
|
133
|
+
"""Build a fresh CLI-compatible job schema from the bundled schema and scope.
|
|
134
|
+
|
|
135
|
+
Role enums are bound before generation. No project, scope or report writes.
|
|
136
|
+
The evidence validator uses the same _source_role_bindings function.
|
|
137
|
+
"""
|
|
138
|
+
roles, _ = _source_role_bindings(scope)
|
|
139
|
+
schema = json.loads(Path(__file__).with_name('review-output.schema.json').read_text())
|
|
140
|
+
properties = schema['$defs']['reference']['properties']
|
|
141
|
+
if roles:
|
|
142
|
+
properties['role']['enum'] = sorted(roles)
|
|
143
|
+
else:
|
|
144
|
+
properties.pop('role', None)
|
|
145
|
+
|
|
146
|
+
def inline(node):
|
|
147
|
+
if isinstance(node, list):
|
|
148
|
+
return [inline(x) for x in node]
|
|
149
|
+
if not isinstance(node, dict):
|
|
150
|
+
return node
|
|
151
|
+
if '$ref' in node:
|
|
152
|
+
prefix = '#/$defs/'
|
|
153
|
+
if not node['$ref'].startswith(prefix):
|
|
154
|
+
raise ValueError('only bundled local schema references are supported')
|
|
155
|
+
return inline(schema['$defs'][node['$ref'][len(prefix):]])
|
|
156
|
+
return {k: inline(v) for k, v in node.items() if k not in ['$defs', '$schema', '$id']}
|
|
157
|
+
return inline(schema)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _unique_object(pairs):
|
|
161
|
+
result = {}
|
|
162
|
+
for key, value in pairs:
|
|
163
|
+
if key in result:
|
|
164
|
+
raise ValueError('duplicate JSON key: ' + key)
|
|
165
|
+
result[key] = value
|
|
166
|
+
return result
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _invalid_constant(value):
|
|
170
|
+
raise ValueError('nonstandard JSON constant: ' + value)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def check_review(project_root, events, assessment, scope=None):
|
|
174
|
+
scope = scope or {}
|
|
175
|
+
issues, checked = [], []
|
|
176
|
+
def fail(code, detail):
|
|
177
|
+
issues.append({'code': code, 'detail': detail})
|
|
178
|
+
def result(**extra):
|
|
179
|
+
return {'passed': not issues, 'errors': [x['detail'] for x in issues],
|
|
180
|
+
'errorCodes': sorted({x['code'] for x in issues}), 'issues': issues,
|
|
181
|
+
'quotes': checked, 'contract': 'i3-enterprise-sop-review-output/v1', **extra}
|
|
182
|
+
finals = [x for x in events if x.get('type') == 'result']
|
|
183
|
+
text = finals[-1].get('result', '') if finals else ''
|
|
184
|
+
carrier = scope.get('reviewCarrier', 'text')
|
|
185
|
+
if carrier not in ['text', 'structured_output']:
|
|
186
|
+
fail('review_carrier_invalid', 'unsupported explicitly selected review carrier')
|
|
187
|
+
return result()
|
|
188
|
+
if carrier == 'structured_output':
|
|
189
|
+
if not finals or 'structured_output' not in finals[-1]:
|
|
190
|
+
fail('review_output_missing', 'requested native structured_output missing; no text fallback')
|
|
191
|
+
return result()
|
|
192
|
+
payload = finals[-1]['structured_output']
|
|
193
|
+
calls, successful = {}, set()
|
|
194
|
+
for event in events:
|
|
195
|
+
message = event.get('message', {})
|
|
196
|
+
content = message.get('content', []) if isinstance(message, dict) else []
|
|
197
|
+
if not isinstance(content, list):
|
|
198
|
+
continue
|
|
199
|
+
for block in content:
|
|
200
|
+
if not isinstance(block, dict):
|
|
201
|
+
continue
|
|
202
|
+
if block.get('type') == 'tool_use' and block.get('name') == 'StructuredOutput':
|
|
203
|
+
calls[block.get('id')] = block.get('input')
|
|
204
|
+
elif block.get('type') == 'tool_result' and not block.get('is_error', False):
|
|
205
|
+
successful.add(block.get('tool_use_id'))
|
|
206
|
+
if not any(tool_id in successful and value == payload for tool_id, value in calls.items()):
|
|
207
|
+
fail('review_structured_output_unproven', 'no matching successful native StructuredOutput tool/result pair')
|
|
208
|
+
return result()
|
|
209
|
+
try:
|
|
210
|
+
raw = json.dumps(payload, ensure_ascii=False, allow_nan=False)
|
|
211
|
+
except (ValueError, TypeError) as error:
|
|
212
|
+
fail('review_json_invalid', str(error))
|
|
213
|
+
return result()
|
|
214
|
+
else:
|
|
215
|
+
if not isinstance(text, str) or not text.strip():
|
|
216
|
+
fail('review_output_missing', 'native final report text missing')
|
|
217
|
+
return result()
|
|
218
|
+
blocks = re.findall(r'```json[ \t]*\r?\n(.*?)\r?\n```', text, re.S)
|
|
219
|
+
if len(blocks) > 1:
|
|
220
|
+
fail('review_json_ambiguous', 'expected one JSON object, found multiple JSON blocks')
|
|
221
|
+
return result()
|
|
222
|
+
raw = blocks[0] if blocks else text.strip()
|
|
223
|
+
try:
|
|
224
|
+
report = json.loads(raw, object_pairs_hook=_unique_object, parse_constant=_invalid_constant)
|
|
225
|
+
except (ValueError, TypeError) as error:
|
|
226
|
+
fail('review_json_invalid', str(error))
|
|
227
|
+
return result(parseError={'message': str(error), 'line': getattr(error, 'lineno', None),
|
|
228
|
+
'column': getattr(error, 'colno', None), 'position': getattr(error, 'pos', None)})
|
|
229
|
+
checked_report = check_report(project_root, report, assessment, scope)
|
|
230
|
+
checked_report['carrier'] = carrier
|
|
231
|
+
checked_report['nativeCarrierProven'] = carrier == 'structured_output'
|
|
232
|
+
return checked_report
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def check_report(project_root, report, assessment, scope=None):
|
|
236
|
+
"""Check report content against source/read evidence; no native-origin claim.
|
|
237
|
+
|
|
238
|
+
The caller must record the origin of a separately corrected report. Calling
|
|
239
|
+
this function does not turn that report into a new native model result.
|
|
240
|
+
"""
|
|
241
|
+
root = Path(project_root).resolve()
|
|
242
|
+
scope = scope or {}
|
|
243
|
+
carrier = 'report-object'
|
|
244
|
+
issues, checked = [], []
|
|
245
|
+
def fail(code, detail):
|
|
246
|
+
issues.append({'code': code, 'detail': detail})
|
|
247
|
+
def result(**extra):
|
|
248
|
+
return {'passed': not issues, 'errors': [x['detail'] for x in issues],
|
|
249
|
+
'errorCodes': sorted({x['code'] for x in issues}), 'issues': issues,
|
|
250
|
+
'quotes': checked, 'contract': 'i3-enterprise-sop-review-output/v1', **extra}
|
|
251
|
+
try:
|
|
252
|
+
schema = json.loads(Path(__file__).with_name('review-output.schema.json').read_text())
|
|
253
|
+
schema_errors = _schema_errors(report, schema, schema)
|
|
254
|
+
except (ValueError, KeyError, OSError) as error:
|
|
255
|
+
fail('review_contract_invalid', str(error))
|
|
256
|
+
return result()
|
|
257
|
+
if not schema_errors:
|
|
258
|
+
for group in ['findings', 'checkedFacts']:
|
|
259
|
+
ids = [x['id'] for x in report[group]]
|
|
260
|
+
if len(ids) != len(set(ids)):
|
|
261
|
+
schema_errors.append(group + ': duplicate stable ID')
|
|
262
|
+
if schema_errors:
|
|
263
|
+
for error in schema_errors:
|
|
264
|
+
fail('review_schema_invalid', error)
|
|
265
|
+
return result()
|
|
266
|
+
|
|
267
|
+
def relative(raw_path):
|
|
268
|
+
p = Path(raw_path)
|
|
269
|
+
p = (p if p.is_absolute() else root / p).resolve()
|
|
270
|
+
return str(p.relative_to(root)) if p.is_relative_to(root) else str(p)
|
|
271
|
+
try:
|
|
272
|
+
roles, required_roles = _source_role_bindings(scope)
|
|
273
|
+
except ValueError as error:
|
|
274
|
+
fail('review_role_scope_invalid', str(error))
|
|
275
|
+
return result()
|
|
276
|
+
roles = {name: relative(path) for name, path in roles.items()}
|
|
277
|
+
read_lines = {}
|
|
278
|
+
for item in assessment['observedReads']:
|
|
279
|
+
if item['successful']:
|
|
280
|
+
read_lines.setdefault(item['path'], set()).update(item['lines'])
|
|
281
|
+
proven_roles = set()
|
|
282
|
+
for group in ['findings', 'checkedFacts']:
|
|
283
|
+
for index, item in enumerate(report[group]):
|
|
284
|
+
for side in ['target', 'source']:
|
|
285
|
+
ref = item[side]
|
|
286
|
+
label = f'{group}[{index}].{side}'
|
|
287
|
+
path = relative(ref['path'])
|
|
288
|
+
start, end = ref['startLine'], ref.get('endLine', ref['startLine'])
|
|
289
|
+
bound_role = ref.get('role')
|
|
290
|
+
role_matches = bound_role is None
|
|
291
|
+
if bound_role is not None:
|
|
292
|
+
if bound_role not in roles:
|
|
293
|
+
fail('review_source_role_unbound', label + ': unbound role ' + bound_role)
|
|
294
|
+
elif roles[bound_role] != path:
|
|
295
|
+
fail('review_source_role_mismatch', label + ': role does not match caller-bound path')
|
|
296
|
+
else:
|
|
297
|
+
role_matches = True
|
|
298
|
+
observed = start <= end and all(n in read_lines.get(path, set()) for n in range(start, end + 1))
|
|
299
|
+
quote_matches = False
|
|
300
|
+
if start > end:
|
|
301
|
+
fail('review_reference_range_invalid', label + ': endLine precedes startLine')
|
|
302
|
+
else:
|
|
303
|
+
# Do not open an arbitrary external path merely because the model cites it.
|
|
304
|
+
p = root / path
|
|
305
|
+
explicit_external = {relative(x) for x in scope.get('requiredReads', [])}
|
|
306
|
+
permitted = p.is_relative_to(root) or path in explicit_external
|
|
307
|
+
try:
|
|
308
|
+
lines = p.read_text().splitlines() if permitted and p.is_file() else []
|
|
309
|
+
quote_matches = end <= len(lines) and ref['quote'] in '\n'.join(lines[start-1:end])
|
|
310
|
+
except (OSError, UnicodeError):
|
|
311
|
+
pass
|
|
312
|
+
if not quote_matches:
|
|
313
|
+
fail('review_quote_mismatch', label + ': quote does not match referenced current file/lines')
|
|
314
|
+
if not observed:
|
|
315
|
+
fail('review_reference_not_read', label + ': cited lines lack successful native Read evidence')
|
|
316
|
+
if bound_role and role_matches and observed and quote_matches:
|
|
317
|
+
proven_roles.add(bound_role)
|
|
318
|
+
checked.append({'group': group, 'index': index, 'role': side, 'path': path,
|
|
319
|
+
'sourceRole': bound_role, 'quoteMatches': quote_matches,
|
|
320
|
+
'citedLinesActuallyRead': observed, 'sourceRoleMatches': role_matches})
|
|
321
|
+
for name in required_roles:
|
|
322
|
+
if name not in proven_roles:
|
|
323
|
+
fail('review_source_role_missing', 'required role lacks proven reference: ' + name)
|
|
324
|
+
return result(verdict=report['verdict'], carrier=carrier, sourceRoleEvidence=sorted(proven_roles),
|
|
325
|
+
scope='structure, exact quotes, actual Read ranges and caller-bound roles only; not semantic correctness or approval')
|
|
326
|
+
|
|
327
|
+
def main():
|
|
328
|
+
import argparse,sys
|
|
329
|
+
parser=argparse.ArgumentParser(description=__doc__)
|
|
330
|
+
parser.add_argument('--project-root',required=True)
|
|
331
|
+
parser.add_argument('--scope',required=True,help='Verification scope only; not business handoff.json')
|
|
332
|
+
parser.add_argument('--trace',required=True,help='CodeBuddy stream-json trace')
|
|
333
|
+
parser.add_argument('--review-quotes',action='store_true')
|
|
334
|
+
args=parser.parse_args()
|
|
335
|
+
try:
|
|
336
|
+
scope=json.loads(Path(args.scope).read_text())
|
|
337
|
+
events=[json.loads(line) for line in Path(args.trace).read_text().splitlines() if line.strip()]
|
|
338
|
+
if not isinstance(scope.get('requiredReads'),list):raise ValueError('scope.requiredReads must be a list')
|
|
339
|
+
result=assess(args.project_root,scope,events)
|
|
340
|
+
if args.review_quotes:
|
|
341
|
+
quote_check=check_review(args.project_root,events,result,scope);result['reviewQuoteCheck']=quote_check
|
|
342
|
+
if not quote_check['passed']:result['failures'].extend(quote_check['errorCodes']);result['passed']=False
|
|
343
|
+
except (ValueError,KeyError,TypeError,OSError,UnicodeError) as error:
|
|
344
|
+
result={'format':'i3-read-evidence/v1','passed':False,'failures':['invalid_or_unsupported_evidence'],'detail':str(error)}
|
|
345
|
+
print(json.dumps(result,ensure_ascii=False,indent=2))
|
|
346
|
+
return 0 if result['passed'] else 1
|
|
347
|
+
|
|
348
|
+
if __name__=='__main__':raise SystemExit(main())
|