@prismer/runtime 2.0.7 → 2.2.55
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/CHANGELOG.md +3631 -0
- package/README.md +34 -12
- package/apc/skills/FIELD-DICTIONARY.md +111 -0
- package/apc/skills/bug-reproduce/SKILL.md +150 -0
- package/apc/skills/bug-reproduce/skill.json +96 -0
- package/apc/skills/code-review/SKILL.md +198 -0
- package/apc/skills/code-review/skill.json +124 -0
- package/apc/skills/design-review/SKILL.md +122 -0
- package/apc/skills/design-review/skill.json +88 -0
- package/apc/skills/doc-sync/SKILL.md +168 -0
- package/apc/skills/doc-sync/skill.json +81 -0
- package/apc/skills/env-doctor/SKILL.md +194 -0
- package/apc/skills/env-doctor/skill.json +209 -0
- package/apc/skills/git-ops/SKILL.md +189 -0
- package/apc/skills/git-ops/skill.json +94 -0
- package/apc/skills/impact-trace/SKILL.md +168 -0
- package/apc/skills/impact-trace/skill.json +104 -0
- package/apc/skills/observability/SKILL.md +195 -0
- package/apc/skills/observability/skill.json +116 -0
- package/apc/skills/release-db-config-sync/SKILL.md +186 -0
- package/apc/skills/release-db-config-sync/skill.json +109 -0
- package/apc/skills/release-ota-promote/SKILL.md +195 -0
- package/apc/skills/release-ota-promote/skill.json +176 -0
- package/apc/skills/release-preflight/SKILL.md +174 -0
- package/apc/skills/release-preflight/skill.json +175 -0
- package/apc/skills/release-rollback/SKILL.md +214 -0
- package/apc/skills/release-rollback/skill.json +230 -0
- package/apc/skills/release-tag/SKILL.md +194 -0
- package/apc/skills/release-tag/skill.json +94 -0
- package/apc/skills/releasing-prod/SKILL.md +49 -0
- package/apc/skills/releasing-test/SKILL.md +135 -0
- package/apc/skills/sdk-release/SKILL.md +200 -0
- package/apc/skills/spec-intake/SKILL.md +169 -0
- package/apc/skills/spec-intake/skill.json +93 -0
- package/apc/skills/test-result-feedback/SKILL.md +239 -0
- package/apc/skills/test-result-feedback/skill.json +193 -0
- package/apc/skills/test-runner/SKILL.md +169 -0
- package/apc/skills/test-runner/skill.json +103 -0
- package/apc/skills/ui-align/SKILL.md +209 -0
- package/apc/skills/ui-align/skill.json +114 -0
- package/apc/skills/ui-canvas/SKILL.md +148 -0
- package/apc/skills/ui-canvas/skill.json +127 -0
- package/built-in-skills/agent-coordination/SKILL.md +257 -0
- package/built-in-skills/agent-meta/SKILL.md +53 -0
- package/built-in-skills/assets/SKILL.md +133 -0
- package/built-in-skills/browser-use/SKILL.md +93 -0
- package/built-in-skills/canvas-design/LICENSE.txt +202 -0
- package/built-in-skills/canvas-design/SKILL.md +157 -0
- package/built-in-skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/built-in-skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/built-in-skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/built-in-skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/built-in-skills/claim-agent-ownership/SKILL.md +255 -0
- package/built-in-skills/claude-api/LICENSE.txt +202 -0
- package/built-in-skills/claude-api/SKILL.md +325 -0
- package/built-in-skills/claude-api/csharp/claude-api.md +402 -0
- package/built-in-skills/claude-api/curl/examples.md +216 -0
- package/built-in-skills/claude-api/curl/managed-agents.md +336 -0
- package/built-in-skills/claude-api/go/claude-api.md +421 -0
- package/built-in-skills/claude-api/go/managed-agents/README.md +561 -0
- package/built-in-skills/claude-api/java/claude-api.md +432 -0
- package/built-in-skills/claude-api/java/managed-agents/README.md +442 -0
- package/built-in-skills/claude-api/php/claude-api.md +375 -0
- package/built-in-skills/claude-api/php/managed-agents/README.md +435 -0
- package/built-in-skills/claude-api/python/claude-api/README.md +420 -0
- package/built-in-skills/claude-api/python/claude-api/batches.md +185 -0
- package/built-in-skills/claude-api/python/claude-api/files-api.md +165 -0
- package/built-in-skills/claude-api/python/claude-api/streaming.md +162 -0
- package/built-in-skills/claude-api/python/claude-api/tool-use.md +590 -0
- package/built-in-skills/claude-api/python/managed-agents/README.md +332 -0
- package/built-in-skills/claude-api/ruby/claude-api.md +113 -0
- package/built-in-skills/claude-api/ruby/managed-agents/README.md +389 -0
- package/built-in-skills/claude-api/shared/agent-design.md +101 -0
- package/built-in-skills/claude-api/shared/error-codes.md +213 -0
- package/built-in-skills/claude-api/shared/live-sources.md +135 -0
- package/built-in-skills/claude-api/shared/managed-agents-api-reference.md +378 -0
- package/built-in-skills/claude-api/shared/managed-agents-client-patterns.md +209 -0
- package/built-in-skills/claude-api/shared/managed-agents-core.md +238 -0
- package/built-in-skills/claude-api/shared/managed-agents-environments.md +215 -0
- package/built-in-skills/claude-api/shared/managed-agents-events.md +195 -0
- package/built-in-skills/claude-api/shared/managed-agents-memory.md +197 -0
- package/built-in-skills/claude-api/shared/managed-agents-multiagent.md +99 -0
- package/built-in-skills/claude-api/shared/managed-agents-onboarding.md +114 -0
- package/built-in-skills/claude-api/shared/managed-agents-outcomes.md +106 -0
- package/built-in-skills/claude-api/shared/managed-agents-overview.md +68 -0
- package/built-in-skills/claude-api/shared/managed-agents-self-hosted-sandboxes.md +173 -0
- package/built-in-skills/claude-api/shared/managed-agents-tools.md +321 -0
- package/built-in-skills/claude-api/shared/managed-agents-webhooks.md +110 -0
- package/built-in-skills/claude-api/shared/model-migration.md +779 -0
- package/built-in-skills/claude-api/shared/models.md +121 -0
- package/built-in-skills/claude-api/shared/prompt-caching.md +171 -0
- package/built-in-skills/claude-api/shared/tool-use-concepts.md +327 -0
- package/built-in-skills/claude-api/typescript/claude-api/README.md +333 -0
- package/built-in-skills/claude-api/typescript/claude-api/batches.md +106 -0
- package/built-in-skills/claude-api/typescript/claude-api/files-api.md +98 -0
- package/built-in-skills/claude-api/typescript/claude-api/streaming.md +178 -0
- package/built-in-skills/claude-api/typescript/claude-api/tool-use.md +527 -0
- package/built-in-skills/claude-api/typescript/managed-agents/README.md +359 -0
- package/built-in-skills/codebase-design/DEEPENING.md +37 -0
- package/built-in-skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/built-in-skills/codebase-design/LICENSE +21 -0
- package/built-in-skills/codebase-design/SKILL.md +116 -0
- package/built-in-skills/conversation-compaction/SKILL.md +114 -0
- package/built-in-skills/council-creator/SKILL.md +426 -0
- package/built-in-skills/diagnosing-bugs/LICENSE +21 -0
- package/built-in-skills/diagnosing-bugs/SKILL.md +136 -0
- package/built-in-skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
- package/built-in-skills/doc-coauthoring/SKILL.md +376 -0
- package/built-in-skills/document-generation/SKILL.md +105 -0
- package/built-in-skills/domain-modeling/ADR-FORMAT.md +47 -0
- package/built-in-skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
- package/built-in-skills/domain-modeling/LICENSE +21 -0
- package/built-in-skills/domain-modeling/SKILL.md +76 -0
- package/built-in-skills/frontend-design/LICENSE.txt +177 -0
- package/built-in-skills/frontend-design/SKILL.md +43 -0
- package/built-in-skills/human-approval/SKILL.md +129 -0
- package/built-in-skills/image-generate/SKILL.md +128 -0
- package/built-in-skills/image-generate/scripts/generate-and-deliver.mjs +289 -0
- package/built-in-skills/ingest/SKILL.md +73 -0
- package/built-in-skills/internal-comms/LICENSE.txt +202 -0
- package/built-in-skills/internal-comms/SKILL.md +33 -0
- package/built-in-skills/internal-comms/examples/3p-updates.md +47 -0
- package/built-in-skills/internal-comms/examples/company-newsletter.md +65 -0
- package/built-in-skills/internal-comms/examples/faq-answers.md +30 -0
- package/built-in-skills/internal-comms/examples/general-comms.md +16 -0
- package/built-in-skills/liteparse/SKILL.md +176 -0
- package/built-in-skills/mcp-builder/LICENSE.txt +202 -0
- package/built-in-skills/mcp-builder/SKILL.md +237 -0
- package/built-in-skills/mcp-builder/reference/evaluation.md +602 -0
- package/built-in-skills/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/built-in-skills/mcp-builder/reference/node_mcp_server.md +970 -0
- package/built-in-skills/mcp-builder/reference/python_mcp_server.md +719 -0
- package/built-in-skills/mcp-builder/scripts/connections.py +151 -0
- package/built-in-skills/mcp-builder/scripts/evaluation.py +373 -0
- package/built-in-skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/built-in-skills/mcp-builder/scripts/requirements.txt +2 -0
- package/built-in-skills/memory/SKILL.md +471 -0
- package/built-in-skills/memory-dream/SKILL.md +339 -0
- package/built-in-skills/office-artifacts/SKILL.md +211 -0
- package/built-in-skills/okr/SKILL.md +154 -0
- package/built-in-skills/persona/SKILL.md +81 -0
- package/built-in-skills/persona-generator/SKILL.md +296 -0
- package/built-in-skills/pkf-svg/SKILL.md +253 -0
- package/built-in-skills/pkf-writing/SKILL.md +236 -0
- package/built-in-skills/prismer-im-collab/SKILL.md +168 -0
- package/built-in-skills/proactivity/SKILL.md +84 -0
- package/built-in-skills/remotion/SKILL.md +431 -0
- package/built-in-skills/role-builder/SKILL.md +203 -0
- package/built-in-skills/role-builder/scripts/author-role.mjs +334 -0
- package/built-in-skills/role-builder/scripts/ingest-role.mjs +223 -0
- package/built-in-skills/role-builder/scripts/instantiate-and-run.mjs +290 -0
- package/built-in-skills/role-builder/scripts/operation-harness.mjs +267 -0
- package/built-in-skills/skill-authoring/SKILL.md +134 -0
- package/built-in-skills/skill-authoring/skill.json +74 -0
- package/built-in-skills/skill-builder/SKILL.md +171 -0
- package/built-in-skills/skill-builder/scripts/ingest.mjs +265 -0
- package/built-in-skills/skill-creator/LICENSE.txt +202 -0
- package/built-in-skills/skill-creator/SKILL.md +227 -0
- package/built-in-skills/skill-creator/agents/analyzer.md +274 -0
- package/built-in-skills/skill-creator/agents/comparator.md +202 -0
- package/built-in-skills/skill-creator/agents/grader.md +223 -0
- package/built-in-skills/skill-creator/assets/eval_review.html +146 -0
- package/built-in-skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/built-in-skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/built-in-skills/skill-creator/references/external-library-import.md +110 -0
- package/built-in-skills/skill-creator/references/schemas.md +430 -0
- package/built-in-skills/skill-creator/scripts/__init__.py +0 -0
- package/built-in-skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/built-in-skills/skill-creator/scripts/generate_report.py +326 -0
- package/built-in-skills/skill-creator/scripts/import-library.mjs +475 -0
- package/built-in-skills/skill-creator/scripts/improve_description.py +247 -0
- package/built-in-skills/skill-creator/scripts/package_skill.py +136 -0
- package/built-in-skills/skill-creator/scripts/quick_validate.py +103 -0
- package/built-in-skills/skill-creator/scripts/run_eval.py +310 -0
- package/built-in-skills/skill-creator/scripts/run_loop.py +328 -0
- package/built-in-skills/skill-creator/scripts/utils.py +47 -0
- package/built-in-skills/slack-gif-creator/LICENSE.txt +202 -0
- package/built-in-skills/slack-gif-creator/SKILL.md +291 -0
- package/built-in-skills/slack-gif-creator/core/easing.py +234 -0
- package/built-in-skills/slack-gif-creator/core/frame_composer.py +176 -0
- package/built-in-skills/slack-gif-creator/core/gif_builder.py +269 -0
- package/built-in-skills/slack-gif-creator/core/validators.py +136 -0
- package/built-in-skills/slack-gif-creator/requirements.txt +4 -0
- package/built-in-skills/tasks/SKILL.md +413 -0
- package/built-in-skills/tdd/LICENSE +21 -0
- package/built-in-skills/tdd/SKILL.md +110 -0
- package/built-in-skills/tdd/mocking.md +59 -0
- package/built-in-skills/tdd/refactoring.md +10 -0
- package/built-in-skills/tdd/tests.md +61 -0
- package/built-in-skills/team/SKILL.md +77 -0
- package/built-in-skills/web-artifacts-builder/LICENSE.txt +202 -0
- package/built-in-skills/web-artifacts-builder/SKILL.md +105 -0
- package/built-in-skills/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/built-in-skills/web-artifacts-builder/scripts/init-artifact.sh +334 -0
- package/built-in-skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/built-in-skills/webapp-testing/LICENSE.txt +202 -0
- package/built-in-skills/webapp-testing/SKILL.md +97 -0
- package/built-in-skills/webapp-testing/examples/console_logging.py +35 -0
- package/built-in-skills/webapp-testing/examples/element_discovery.py +40 -0
- package/built-in-skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/built-in-skills/webapp-testing/scripts/with_server.py +106 -0
- package/built-in-skills/wechat-pay/SKILL.md +59 -0
- package/dist/cli.cjs +72577 -16101
- package/dist/cli.js +72752 -16232
- package/dist/index.cjs +72632 -16024
- package/dist/index.d.cts +4956 -640
- package/dist/index.d.ts +4956 -640
- package/dist/index.js +72564 -15963
- package/package.json +39 -6
- package/plugins/memory/prismer/__init__.py +1211 -0
- package/plugins/memory/prismer/plugin.yaml +8 -0
- package/plugins/memory/prismer/tool-schemas.generated.json +249 -0
- package/plugins/tools/prismer-recall/__init__.py +282 -0
- package/plugins/tools/prismer-recall/plugin.yaml +15 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ui-align
|
|
3
|
+
description: Visual-alignment workflow for a new UI need or a UI改进. Index-first (consult the ui-kit registry to avoid re-building an existing primitive), then implement, then run the screenshot harness to capture the component in light/dark against the live /ui-kit, then produce a ReportCard (screenshot assets side by side + a written conclusion) the requester reviews VISUALLY without reading code. The harness computes NO image diff — it verifies side effects (screenshots really have pixels, assets uploaded, ReportCard persisted); both "the visual looks good" and any deviation number are human judgments the machine never produces.
|
|
4
|
+
license: MIT
|
|
5
|
+
scope: common
|
|
6
|
+
compatibility:
|
|
7
|
+
- claude-code
|
|
8
|
+
allowed-tools:
|
|
9
|
+
- Bash
|
|
10
|
+
metadata:
|
|
11
|
+
category: design
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# ui-align
|
|
15
|
+
|
|
16
|
+
把「新 UI 需求 / UI 改进对比」跑成 **索引 → 实现 → 截图 → 报告** 的闭环(docs/apc/07 Part A §A4)。
|
|
17
|
+
产出是一张 **ReportCard**:把同一组件的 **light / dark 两态截图** + 对比结论落成一张可寻址的富报告页,
|
|
18
|
+
需求方**从视觉验收,不读代码**。
|
|
19
|
+
|
|
20
|
+
**什么时候用**:一个 UI 组件要新增 / 改样式 / 做前后对比时。**第一步永远是查索引**——ui-kit 已经把
|
|
21
|
+
现有原语拆成 `registry.ts` 索引,先看有没有现成的,别重复造第 N 个 Dialog / Button / Card。
|
|
22
|
+
|
|
23
|
+
## Why(这条 skill 存在的理由)
|
|
24
|
+
|
|
25
|
+
- **避免重复造**:ui-kit 是全状态画廊 + 机器可读索引(`src/app/ui-kit/registry.ts` 的 `ENTRIES`)。
|
|
26
|
+
新需求先对索引,命中就复用,不命中才新增一片。索引是唯一真源——**不 grep 源码猜有没有**。
|
|
27
|
+
- **视觉验收可寻址**:截图落 task-bound asset,ReportCard 用 `prismer://asset/<id>` 引它 + 结论段。
|
|
28
|
+
需求方点开卡就看到 before/after,不必读 diff。
|
|
29
|
+
- **两态都截**:light / dark 是同一个主题机制的两个投影(`.dark` on `<html>`)。只截一态会漏掉暗色下
|
|
30
|
+
的对比度 / 边框 / 玻璃态塌缩——两态并排是对齐评审最有用的形态。
|
|
31
|
+
|
|
32
|
+
## Anti-pattern(这条 skill 要防的)
|
|
33
|
+
|
|
34
|
+
- **不查索引就动手**:直接新写一个组件,结果 ui-kit 里早有同款 → 又一个分叉。**先 `--list`。**
|
|
35
|
+
- **只截一态**:只发 light 截图,dark 下的问题溜过评审。
|
|
36
|
+
- **把"视觉通过"当机器结论**:本 skill 的 oracle 断的是**副作用**(截图产出了、ReportCard 落库了、
|
|
37
|
+
对比表结构对),**不是**"好不好看"。**别在报告里声称"视觉已验证正确"**——那是人的判断(同
|
|
38
|
+
design-review 固有局限)。
|
|
39
|
+
- **贴原始 JSON 冒充报告**:harness 的 stdout 是结构化 JSON,读它、汇报关键字段(scope / themes /
|
|
40
|
+
reportCard pageId / shots assetId / exit 码),不是把整坨 JSON 甩回去。
|
|
41
|
+
|
|
42
|
+
## Workflow(真命令,`apc` 不在 PATH → 一律 `npx tsx`)
|
|
43
|
+
|
|
44
|
+
从仓库根跑。harness 的 stdout 是纯 JSON。
|
|
45
|
+
|
|
46
|
+
### 1. 索引优先——查有没有现成的 scope
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx tsx sdk/apc/harness/ui-screenshot.ts --list # 合法 scope 清单
|
|
50
|
+
npx tsx sdk/apc/harness/ui-screenshot.ts --help # 全部旗标 + 退出码语义
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
打印 registry 里所有合法 scope(`{ ok:true, scopes:[...] }`)。**命中就复用那个 scope;不命中**
|
|
54
|
+
说明是新需求 → 在 `src/app/ui-kit/registry.ts` 的 `ENTRIES` 加一行(`status:'draft'` + 挂 task/doc)
|
|
55
|
+
并在 `sections/<scope>.tsx` 加稿件(07 §A4 步骤 1-2;本 skill 不替你写实现,只教流程 + 产报告)。
|
|
56
|
+
|
|
57
|
+
### 2. 跑截图 harness——两态截图 + 上云 + 产 ReportCard
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx tsx sdk/apc/harness/ui-screenshot.ts \
|
|
61
|
+
--scope <scope> --themes light,dark \
|
|
62
|
+
--workspace "$APC_WORKSPACE_ID" --task "$PRISMER_TASK_ID"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
harness 会:读 registry 校验 scope(非法 scope → 结构化错误、**不产废卡**)→ 用 Playwright 打
|
|
66
|
+
`http://127.0.0.1:3000/ui-kit?scope=<scope>` 对 light/dark 各截一张 → **过像素闸**(单张 0 字节 /
|
|
67
|
+
< 1 KiB / 不是 PNG / 两态字节完全相同 ⇒ 直接判红,**在上传之前**,不产废 asset 不产废卡)→ 上云成
|
|
68
|
+
task-bound asset → **复用 `report-card.ts` 产一张 ReportCard**(截图 + 结论 + TierResult 表)。
|
|
69
|
+
|
|
70
|
+
卡里两张图的槽位:**before = `--themes` 的第一个态(light),after = 第二个态(dark)**,与卡正文
|
|
71
|
+
结论段的措辞逐字一致。
|
|
72
|
+
|
|
73
|
+
**并排引用一张已有的基线图**(改进现有组件时):
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npx tsx sdk/apc/harness/ui-screenshot.ts --scope <scope> --themes light,dark \
|
|
77
|
+
--workspace "$APC_WORKSPACE_ID" --task "$PRISMER_TASK_ID" \
|
|
78
|
+
--baseline-light <旧light assetId> --baseline-dark <旧dark assetId>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
此时 before 槽 = 你传进来的旧图,after 槽 = 本次新截的图,`mode` 变成 `baseline-reference`。
|
|
82
|
+
|
|
83
|
+
> ⚠️ **这不是"比对"**。本 harness **不计算任何像素/结构差异**——它只是把两张图并排放进同一张卡,
|
|
84
|
+
> 差异由**人看图**判定(输出 JSON 里的 `"comparison": "none"` 就是在结构化地说这件事)。
|
|
85
|
+
> **报告里不许出现任何偏差百分比 / diff 数值 / "像素级通过"**:harness 没算过,写出来就是编造。
|
|
86
|
+
> 像素级阈值 diff(`toHaveScreenshot`)属 Playwright spec 层,本 skill 不含。
|
|
87
|
+
>
|
|
88
|
+
> 传进来的 baseline id 会在起 chromium **之前**回读校验(真存在 · 同 workspace · 是图片)。
|
|
89
|
+
> 解析不开 ⇒ `ui-screenshot-baseline-unresolvable`、exit 1、不截图不上传不产卡(以前这里只是往卡里
|
|
90
|
+
> 填一个字符串,传个根本不存在的 id 也 exit 0,卡里就多一条永远打不开的悬空引用)。
|
|
91
|
+
|
|
92
|
+
### 3. 读结构化输出 → 汇报
|
|
93
|
+
|
|
94
|
+
harness stdout(成功):
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{ "ok": true, "scope": "basics", "themes": ["light","dark"], "mode": "new-baseline",
|
|
98
|
+
"comparison": "none",
|
|
99
|
+
"shots": [ {"theme":"light","assetId":"cmr...","bytes":204601},
|
|
100
|
+
{"theme":"dark","assetId":"cmr...","bytes":202065} ],
|
|
101
|
+
"reportCard": { "pageId":"cmr...", "uri":"prismer://workspace/.../memory/cards/ui-align-<scope>", "version":1 } }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
(`baseline-reference` 模式下每个带基线的 shot 还会多一个 `baselineRefAssetId`。)
|
|
105
|
+
|
|
106
|
+
汇报:**scope、截了哪两态、每态 assetId 与 bytes、ReportCard 的 pageId/uri、退出码**。需求方经
|
|
107
|
+
ReportCard 视觉验收。`comparison` 恒为 `"none"` —— 照抄,别把它写成任何形式的"差异结论"。
|
|
108
|
+
|
|
109
|
+
## Decision table
|
|
110
|
+
|
|
111
|
+
| 情况 | 怎么做 |
|
|
112
|
+
| --- | --- |
|
|
113
|
+
| 需求匹配 `--list` 里的某个 scope | 复用该 scope,直接跑步骤 2 |
|
|
114
|
+
| 新 UI 需求,索引里没有 | 先加 registry 行 + section 稿件(07 §A4),再跑步骤 2 |
|
|
115
|
+
| 改进现有组件、要把旧图并排放进卡 | 传 `--baseline-light/--baseline-dark`(并排引用,**不算差异**) |
|
|
116
|
+
| harness 报 `ui-screenshot-unknown-scope` | scope 拼错或没进索引——对 `--list` 核对,别硬跑 |
|
|
117
|
+
| harness 报 `ui-screenshot-degenerate-shot` | 截图退化(0 字节 / 过小 / 非 PNG / 两态同字节)——这是**真失败**:cloud 页面没渲染出来、或主题没切成。查 `$APC_CLOUD_BASE_URL` 那个 `/ui-kit?scope=` 页面本身,别重试骗绿 |
|
|
118
|
+
| harness 报 `ui-screenshot-baseline-unresolvable` | `--baseline-*` 给的 asset 不存在/已删/不同 workspace/不是图片——核对 id,别把它当成"基线库还没建" |
|
|
119
|
+
| harness 报 `ui-screenshot-upload-*` / `write-*` | cloud 不可达或 token 无效——查 `$APC_CLOUD_BASE_URL` / `$APC_API_KEY`,别谎报已产卡 |
|
|
120
|
+
|
|
121
|
+
## Failure(怎么算失败,别骗绿)
|
|
122
|
+
|
|
123
|
+
- harness 退出码 **非 0** = 失败。unknown-scope(exit 2)说明 scope 不在索引——这是**发现**(拼错/漏建索引),
|
|
124
|
+
如实报,别把 scope 名改成能过的。
|
|
125
|
+
- 拿不到 `reportCard.pageId` = ReportCard 没落库 = 没产出,**不许声称已产报告**。
|
|
126
|
+
- **exit 0 但零输出 = 没跑**。harness 成功时 stdout 一定是一坨 JSON;失败时 stderr 一定是一坨 JSON。
|
|
127
|
+
两边都空 = 它压根没执行,**不许当成功**(历史上入口守卫在含软链的调用路径下就是这样 fail-open 的)。
|
|
128
|
+
- **视觉不对齐不是本 skill 的失败**——那是评审发现,写进结论让人判。本 skill 失败 = 截图/报告的**副作用**没产出。
|
|
129
|
+
- **不许报任何 diff 数值**(偏差百分比 / 变化像素数 / "像素级 PASS")。harness 没有比对这个计算,
|
|
130
|
+
写出来的每一个这类数字都是编造 —— 这是本 skill 最容易犯的那种"引用真、结论假"。
|
|
131
|
+
|
|
132
|
+
## 输出契约(索引那一段是机器复验的,别自由发挥格式)
|
|
133
|
+
|
|
134
|
+
「索引优先」是本 skill 的头号反 pattern(不查索引就动手),但旧判据只找 `(--?list|registry|scopes?|索引|清单)` ——**报告里写一句「已查清单」就绿**,零检索也过。现在这一段找的是**两条固定 key 的行**,并把行上的引用**读回磁盘复核**(`structured-criteria.ts` 的 `dimension-coverage`):
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
- [1] index-first: scope=basics 在索引里命中(--list)→ 复用,不新造原语 | src/app/ui-kit/registry.ts:69
|
|
138
|
+
- [2] scope-source: 渲染 ?scope=basics 的稿件源 | src/app/ui-kit/sections/basics.tsx:1
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
- 行号用 `rg -n "scope: 'basics'" src/app/ui-kit/registry.ts` 取,**别猜**——文件不存在 / 行号越界 / 该行是空行都判红。
|
|
142
|
+
- 引用**必须 repo-root-relative**(`src/app/ui-kit/registry.ts:69`,不要简写、不要绝对路径);`rg -c` 的 `path:12` 是命中计数不是行号,要写就写 `count=12`。
|
|
143
|
+
- **新需求(索引未命中)**:仍然作答这两行——`index-first` 引你新加的 `ENTRIES` 那一行,`scope-source` 引你新建的 `sections/<scope>.tsx`(07 §A4 步骤 1-2)。别写 `N/A`:本 skill 任何一次真跑都有索引落点。
|
|
144
|
+
|
|
145
|
+
**判据管不到的部分(诚实边界)**:截图 assetId / ReportCard pageId / harness 退出码是**运行时 id,不是文件引用**——现有 checker 只会把 `path:line` 读回磁盘,没有能复核这类 id 的 checker,所以那几条仍是文本判据(`assetId` / `report-card` / `exit 0` 的正则)。**别为了讨好判据把 id 伪装成 `path:line`**——照 harness JSON 原样贴。这一段的真验收仍靠 harness 的真副作用(截图上云 + 卡落库)。
|
|
146
|
+
|
|
147
|
+
## Output(副作用 oracle,报告里必须给)
|
|
148
|
+
|
|
149
|
+
1. **索引已查**:报告说明查了 `--list` 且命中/未命中哪个 scope。
|
|
150
|
+
2. **两态截图产出**:light + dark 各一张,每态有 assetId **和 bytes**(bytes 是"图里真有像素"的证据;
|
|
151
|
+
两态的 assetId 必须**不同**,相同说明主题没切成)。
|
|
152
|
+
3. **ReportCard 落库**:有 `reportCard.pageId` + uri(`pageType='report-card'`,`visibility='task:<id>'`)。
|
|
153
|
+
4. **退出码 0**(或 unknown-scope 时 exit 2 + 如实报 scope 不在索引)。
|
|
154
|
+
5. **`comparison` 原样照抄**(恒 `"none"`)——它就是"本次没有任何比对结论"的证据。
|
|
155
|
+
|
|
156
|
+
**不许**:只截一态;声称"视觉通过/正确"(机器不断视觉);报任何偏差数值;没 pageId 却说已产报告;
|
|
157
|
+
把整坨 JSON 甩回不提炼。
|
|
158
|
+
|
|
159
|
+
## 诚实边界
|
|
160
|
+
|
|
161
|
+
- **视觉"好不好看"是人的判断,非机器断言**(同 design-review 固有局限)。本 skill 保证的是"两态截图产出
|
|
162
|
+
+ ReportCard 落库 + 对比表结构对",**不保证**"视觉正确"。别拿本 skill 的绿宣称视觉验收通过。
|
|
163
|
+
- **本 skill 不做任何图像比对。** `--baseline-*` 是**并排引用**(把一张已有的图放进卡的 before 槽),
|
|
164
|
+
不是 diff 输入;harness 从不计算像素/结构差异,`comparison` 恒为 `"none"`。**任何偏差百分比、
|
|
165
|
+
"像素级通过/不通过"都是编造**。像素级阈值 diff(`toHaveScreenshot`)属 Playwright spec 层,本 skill 不含。
|
|
166
|
+
(harness 只保证 baseline id **解析得开**:存在 · 同 workspace · 是图片;解析不开就红。)
|
|
167
|
+
- **像素闸只挡退化,不挡丑**:0 字节 / < 1 KiB / 非 PNG / 两态字节完全相同 ⇒ 红。它证明"图里有像素、
|
|
168
|
+
两态确实是两张图",**不证明**"这张图是对的"。
|
|
169
|
+
- harness 需要活 cloud(`$APC_CLOUD_BASE_URL`,默认 `127.0.0.1:3000`)+ 有效 token(`$APC_API_KEY`)+
|
|
170
|
+
真 chromium(Playwright)。缺任一 → harness 结构化报错,别谎报。
|
|
171
|
+
|
|
172
|
+
## PKF 直写(研发回环 · doc07 §B2 写入点②)
|
|
173
|
+
|
|
174
|
+
**产出时机**:上面步骤 2 产出的 **ReportCard 就是一张 PKF 记忆页**(doc07 §B2 写入点②:截图对比报告直写 PKF)。**直写已由 harness 完成**——`sdk/apc/harness/report-card.ts` 构造 PKF → `parsePkf`/`validatePkf` 校验 → 仅合法时经**既有写入 seam**(`POST /api/im/memory/resolve`,唯一能带 `visibility` 的写入面)落库并**回读校验**;你**不必**再手跑 `prismer memory write`,那会重复写。**不新造写入面**(B3:骑既有面)。页面形状(`pageType='report-card'`、`visibility='task:<id>'`、截图走 `prismer://asset/<id>`)见 `pkf-writing` skill 的 media 引用。
|
|
175
|
+
|
|
176
|
+
**声明**(doc10 §2.5 格式,报告末尾一行):
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
PKF: prismer://workspace/<ws>/memory/<path>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
值取 harness 的返回值(`GeneratedReportCard.uri`);harness 写入失败(写入面不可达)时如实声明 `PKF: none — 写入面不可达(<哪一条>)`,绝不许假装写了。
|
|
183
|
+
|
|
184
|
+
**回读**:harness 的 strict readback 已校验「落库页与产出字节一致」;你**只声称**「ReportCard 已落库 + INDEX 可达」,不得声称比这更多。**诚实边界**:harness 写入 body 只带 `uri/content/pageType/visibility`,**未**传 `parent_hub_path`,即 `apc/ui` hub 归属尚未接线——报告里别声称"已挂 apc/ui hub"(doc07 §B5:hub 归属走 memory skill 正常 PLACE 流程,不手工造 hub)。
|
|
185
|
+
|
|
186
|
+
<!-- APC-ACK:v1 -->
|
|
187
|
+
|
|
188
|
+
## 调用回执(APC 平台方运营纪律 · 自动注入,勿手改)
|
|
189
|
+
|
|
190
|
+
执行本 skill 的**第一步**,先落一条调用回执:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
cloud skill ack ui-align --task "$PRISMER_TASK_ID"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**按退出码分流**(这条命令的退出码是承重信息,禁止用 `||` 兜底、`; true`、
|
|
197
|
+
`set +e` 或重定向把它抹掉):
|
|
198
|
+
|
|
199
|
+
| exit | 含义 | 你要做的 |
|
|
200
|
+
| --- | --- | --- |
|
|
201
|
+
| `0` | 回执已落库(`im_task_logs.action='skill_ack'`) | 继续执行本 skill |
|
|
202
|
+
| `3` | **无 task 上下文**——本次运行没有 task,产不出回执 | 继续执行本 skill;但本次运行**没有回执**,任何报告里都不得声称已 ack |
|
|
203
|
+
| `4` | 你不是该 task 的 assignee,服务端拒绝 | 停下并上报:回执只能由执行该 task 的 agent 产生 |
|
|
204
|
+
| `1` | 其它失败(网络 / 服务端) | 重试一次;仍失败则继续执行,并在结果里显式标注「回执缺失」 |
|
|
205
|
+
|
|
206
|
+
回执只证明本 skill **被调度**,不证明**执行正确**——效果证明由本 skill 自己的
|
|
207
|
+
acceptanceCriteria 副作用断言承担(apc/04 §2 层 1 诚实标注)。
|
|
208
|
+
|
|
209
|
+
<!-- /APC-ACK:v1 -->
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"slug": "ui-align",
|
|
4
|
+
"name": "UI Align",
|
|
5
|
+
"description": "Visual-alignment workflow for a new UI need or a UI change: index-first (consult the ui-kit registry to avoid re-building an existing primitive), implement, run the screenshot harness to capture the component in light/dark against the live /ui-kit, then produce a ReportCard (screenshot assets side by side + a written conclusion) the requester reviews visually. The harness computes NO image diff (`comparison` is always \"none\"; --baseline-* is a side-by-side reference, not a diff input). It verifies side effects — screenshots really have pixels, assets uploaded, ReportCard persisted — NOT whether the visual looks good, and never a deviation number; both are human judgments.",
|
|
6
|
+
"category": "design",
|
|
7
|
+
"version": "1.2.0",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"compatibility": [
|
|
10
|
+
"claude-code"
|
|
11
|
+
],
|
|
12
|
+
"runtime": {
|
|
13
|
+
"kind": "text-workflow",
|
|
14
|
+
"requires": {
|
|
15
|
+
"env": [],
|
|
16
|
+
"bins": [
|
|
17
|
+
"node",
|
|
18
|
+
"npx"
|
|
19
|
+
],
|
|
20
|
+
"capabilities": []
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"sampleTasks": [
|
|
24
|
+
{
|
|
25
|
+
"title": "Index-first, then screenshot a ui-kit scope in light/dark and produce a ReportCard",
|
|
26
|
+
"prompt": "Run the ui-align workflow for a UI-alignment need. The `apc`/harness CLIs are NOT on PATH — invoke via `npx tsx <path>` from the repo root; the harness stdout is pure JSON. Steps: (1) INDEX-FIRST — run `npx tsx sdk/apc/harness/ui-screenshot.ts --list` to read the ui-kit registry index (its stdout is `{ok:true, scopes:[...]}`); state which existing scope your need matches so you do NOT re-build an existing primitive. For this task use the existing scope `basics`. (2) SCREENSHOT + REPORT — run `npx tsx sdk/apc/harness/ui-screenshot.ts --scope basics --themes light,dark --workspace \"$APC_WORKSPACE_ID\" --task \"$PRISMER_TASK_ID\"`. The harness reads the registry to validate the scope (an unknown scope is a STRUCTURED ERROR that produces NO waste card), uses Playwright to open http://127.0.0.1:3000/ui-kit?scope=basics in BOTH light and dark, uploads each screenshot as a task-bound asset, and REUSES the report-card generator to persist ONE ReportCard (pageType=report-card, visibility=task:<id>) embedding both screenshots + a comparison conclusion + a TierResult table. (3) Read the harness JSON and report: the scope, that BOTH light AND dark themes were captured, each theme's screenshot assetId, the ReportCard pageId + uri, and the harness exit code (0 on success). Your report MUST: (a) show you consulted the registry index (the --list scopes) before running; (b) confirm BOTH light and dark screenshots were produced, each with an assetId; (c) give the ReportCard pageId (the persisted evidence card). DO NOT claim the visual 'looks correct' or 'passed visual review' — the harness verifies SIDE EFFECTS (screenshots produced, ReportCard persisted), not visual correctness, which is a human judgment. Report exit code 0 and the reportCard pageId. ALSO: this harness computes NO image diff — its JSON carries `\"comparison\": \"none\"`, and `--baseline-*` is a SIDE-BY-SIDE REFERENCE, not a diff input. Copy `comparison` verbatim and DO NOT report any deviation percentage, changed-pixel count, or 'pixel-level PASS/FAIL' — no such number exists, so writing one is fabrication. Report each theme's `bytes` alongside its assetId, and note that the two assetIds differ (identical bytes would mean the theme never switched; the harness now fails that case instead of producing a card whose two slots point at one blob).\n\n--- THE INDEX-FIRST PART OF YOUR REPORT IS MACHINE-CHECKED AGAINST THE FILESYSTEM. Two lines, each with its exact key, each carrying a repo-root-relative `path:line` that is re-read off disk (a real file, a line in range, non-blank — so an invented citation is caught):\n```\n- [1] index-first: scope=basics matched in the registry index (--list) — reusing it, not re-building a primitive | src/app/ui-kit/registry.ts:69\n- [2] scope-source: the section source that renders ?scope=basics | src/app/ui-kit/sections/basics.tsx:1\n```\nGet those line numbers with `rg -n \"scope: 'basics'\" src/app/ui-kit/registry.ts` — do NOT guess. 'I consulted the index' with no verifiable line is no longer an answer. Do not open either value with `无`/`N/A`; a `rg -c` HIT COUNT is not a line number (write counts as `count=N`). The harness-side evidence (both themes' assetIds, the ReportCard pageId, the exit code) still goes in the report as usual — those are runtime ids, not filesystem citations, so keep them verbatim from the harness JSON and do not dress them up as path:line.",
|
|
27
|
+
"expectedArtifacts": [
|
|
28
|
+
"two keyed index-first lines (index-first / scope-source), each citing a path:line in the ui-kit registry / section source that resolves on disk",
|
|
29
|
+
"the ui-kit registry scopes from --list (index consulted before building)",
|
|
30
|
+
"both light and dark screenshots, each with a task-bound asset id AND a byte count (the two asset ids must differ)",
|
|
31
|
+
"a ReportCard pageId (pageType=report-card, visibility=task:<id>) embedding both screenshots side by side + a written conclusion",
|
|
32
|
+
"the harness's comparison field verbatim (always \"none\" — no image diff is computed, so no deviation number may appear anywhere in the report)",
|
|
33
|
+
"harness exit code (0 on success); an unknown scope reported as a structured error with no waste card"
|
|
34
|
+
],
|
|
35
|
+
"acceptanceCriteria": [
|
|
36
|
+
{
|
|
37
|
+
"label": "index-first is PROVEN, not asserted — the matched scope and its section source each answered on their own keyed line with a path:line re-verified on disk (the #1 anti-pattern of this skill is 不查索引就动手)",
|
|
38
|
+
"type": "structured",
|
|
39
|
+
"checker": "dimension-coverage",
|
|
40
|
+
"args": {
|
|
41
|
+
"dimensions": ["index-first", "scope-source"],
|
|
42
|
+
"minReasonChars": 20
|
|
43
|
+
},
|
|
44
|
+
"match": "<structured:dimension-coverage:index-first>",
|
|
45
|
+
"required": true
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"label": "consulted the ui-kit registry index (--list / scopes) before building",
|
|
49
|
+
"match": "(--?list|registry|scopes?|索引|清单)",
|
|
50
|
+
"type": "regex",
|
|
51
|
+
"flags": "is",
|
|
52
|
+
"required": true
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"label": "captured the light theme",
|
|
56
|
+
"match": "\\b(light|亮色|浅色|亮态)\\b",
|
|
57
|
+
"type": "regex",
|
|
58
|
+
"flags": "is",
|
|
59
|
+
"required": true
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"label": "captured the dark theme",
|
|
63
|
+
"match": "\\b(dark|暗色|深色|暗态)\\b",
|
|
64
|
+
"type": "regex",
|
|
65
|
+
"flags": "is",
|
|
66
|
+
"required": true
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"label": "reports a persisted ReportCard (pageId / report-card / ui-align card uri)",
|
|
70
|
+
"match": "(report[- ]?card|pageid|page\\s*id|prismer://[^\\s]*cards/ui-align|cards/ui-align)",
|
|
71
|
+
"type": "regex",
|
|
72
|
+
"flags": "is",
|
|
73
|
+
"required": true
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"label": "reports a screenshot asset id (task-bound asset produced)",
|
|
77
|
+
"match": "(assetid|asset\\s*id|asset[_-]|prismer://asset/|截图\\s*asset)",
|
|
78
|
+
"type": "regex",
|
|
79
|
+
"flags": "is",
|
|
80
|
+
"required": true
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"label": "reports harness success (exit 0 / ok:true)",
|
|
84
|
+
"match": "(exit(\\s*code)?[^0-9]{0,6}0\\b|ok\\s*[:=]\\s*true|\\bok:true\\b|成功|通过)",
|
|
85
|
+
"type": "regex",
|
|
86
|
+
"flags": "is",
|
|
87
|
+
"required": true
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
"security": {
|
|
93
|
+
"dataAccess": [
|
|
94
|
+
"local-filesystem",
|
|
95
|
+
"network"
|
|
96
|
+
],
|
|
97
|
+
"humanApprovalRequiredFor": []
|
|
98
|
+
},
|
|
99
|
+
"provenance": {
|
|
100
|
+
"sourceKind": "inline-spec",
|
|
101
|
+
"sourceRefs": [
|
|
102
|
+
"docs/apc/07-ui-kit-index-and-pkf-loop.md",
|
|
103
|
+
"docs/apc/05-devchain-gaps-and-skills.md",
|
|
104
|
+
"docs/apc/11-impl-tracker.md#0.23",
|
|
105
|
+
"sdk/apc/harness/ui-screenshot.ts",
|
|
106
|
+
"sdk/apc/harness/report-card.ts",
|
|
107
|
+
"sdk/apc/skills/design-review/skill.json",
|
|
108
|
+
"src/app/ui-kit/registry.ts",
|
|
109
|
+
"sdk/prismer-cloud/runtime/src/bundle/structured-criteria.ts"
|
|
110
|
+
],
|
|
111
|
+
"authoredBy": "prismer-platform",
|
|
112
|
+
"authoredAt": "2026-07-24T00:00:00Z"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ui-canvas
|
|
3
|
+
description: Use when a product journey, production component path, UI/UX operation sequence, visual regression, or alignment review must be represented or audited in /ui-canvas with implementation-spec references, immutable versions, task-bound screenshots, and a persisted ReportCard.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Bash
|
|
7
|
+
metadata:
|
|
8
|
+
category: design
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# UI Canvas
|
|
12
|
+
|
|
13
|
+
用一个代码定义的展开画布完成 **spec ↔ 真实生产组件 ↔ 用户操作 ↔ 可寻址视觉证据** 对齐。Production checkpoint 必须在 Frame 内直接渲染真实 UI;不能安全渲染就保留同尺寸 `gap` contract。最终证据来自真实 `/ui-canvas` deep link,不来自 `/ui-kit` 仿制稿。
|
|
14
|
+
|
|
15
|
+
## 承重规则
|
|
16
|
+
|
|
17
|
+
1. 先读 implementation spec 的 `UI Canvas index` 和 Canvas registry,建立双向索引。
|
|
18
|
+
2. 禁止从 `src/app/ui-kit/sections/**` 取节点实现;`/ui-kit` 仅是历史参考。
|
|
19
|
+
3. Canvas callback 只能改变本地 fixture、选中节点和 edge 高亮,不得发业务请求。
|
|
20
|
+
4. `aligned` 版本不可原地修改;需求变化时新增版本并用 `previousVersion` 回指。
|
|
21
|
+
5. Production Frame 直接 import 生产组件;不能复用就写 `gap`,不复制 JSX 冒充闭合。
|
|
22
|
+
6. 测试和截图只证明 Canvas route/registry/render;不能证明 service、DB、daemon 或业务副作用。
|
|
23
|
+
7. 截图 asset 与 ReportCard 证明“证据已产出”,不能自动判定“视觉正确”。
|
|
24
|
+
|
|
25
|
+
## Workflow
|
|
26
|
+
|
|
27
|
+
### 1. 建立双向索引
|
|
28
|
+
|
|
29
|
+
从 spec 找出 set、journey、checkpoint 与 user/system oracle。每个 `CanvasSet`、version、journey、node 都持有真实 `SpecRef`;spec 反向列出 Overview、journey deep link 与 registry source。
|
|
30
|
+
|
|
31
|
+
### 2. 盘生产 source
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
rg -n "export (function|const|class)" src/app src/components
|
|
35
|
+
rg -n "ui-kit/sections|fetch\\(|imFetch\\(|/api/" src/app/ui-canvas
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
| 判定 | 条件 | 动作 |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| `production` | props 可确定性渲染,callback 可留在本地 | 在 `component-registry.tsx` 直接 import |
|
|
41
|
+
| `gap` | 没有生产组件,或 wrapper 挂载即请求/轮询 | 写清 `reason`、`driftRef`、双 oracle |
|
|
42
|
+
|
|
43
|
+
生产 wrapper 只因数据编排不能复用时,可抽纯 `*View` 让生产 wrapper 与 Canvas 共用;不得借机修改 endpoint、model、daemon 或 SDK。
|
|
44
|
+
|
|
45
|
+
### 3. 写不可变版本
|
|
46
|
+
|
|
47
|
+
- draft 可编辑;`aligned` 后冻结。
|
|
48
|
+
- 需求变化新增版本文件,不覆盖历史文件。
|
|
49
|
+
- checkpoint 总数、唯一性、edge 完整性和 production source 由 registry test 锁定。
|
|
50
|
+
- Overview 从 journey registry 派生,不复制 checkpoint。
|
|
51
|
+
|
|
52
|
+
### 4. 展开 Frame 与操作边
|
|
53
|
+
|
|
54
|
+
- Production checkpoint 使用约 `960×680` 的 Frame,body 直接挂 renderer。
|
|
55
|
+
- Gap 使用同尺寸 contract,显示 reason、driftRef、双 oracle 和 SpecRef。
|
|
56
|
+
- 默认相机聚焦 deep-link Frame;整条路径缩略图只能通过显式 `Fit journey`。
|
|
57
|
+
- Inspector 使用浮层,不永久挤压真实组件。
|
|
58
|
+
- Edge label 写用户动作或条件;用 `action / condition / error / recovery / handoff` 区分语义。
|
|
59
|
+
- 生产 callback 选择对应 outgoing edge;没有真实 target 时只记录 local action。
|
|
60
|
+
|
|
61
|
+
### 5. 验证结构与真实渲染
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx vitest run src/app/ui-canvas/__tests__
|
|
65
|
+
npx tsc --noEmit
|
|
66
|
+
PRISMER_BASE_URL=http://127.0.0.1:3000 \
|
|
67
|
+
npx playwright test e2e-playwright/specs/ui-canvas.spec.ts --project=chromium
|
|
68
|
+
rg -n "ui-kit/sections|fetch\\(|imFetch\\(|/api/" src/app/ui-canvas
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Playwright 只能打本地 `127.0.0.1:3000`。截图前先断言目标可见,不得用 `.first()` 掩盖稳定态重复节点。
|
|
72
|
+
|
|
73
|
+
### 6. 发布 task-bound 视觉证据
|
|
74
|
+
|
|
75
|
+
先从代码 registry 读取合法 set/version/journey:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx tsx scripts/ui-canvas-evidence.ts --list
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
再对需要验收的真实 Frame deep link 产 light/dark 截图、task asset 和一张 ReportCard:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npx tsx scripts/ui-canvas-evidence.ts \
|
|
85
|
+
--set <set> --version <version> --journey <journey> --node <node> \
|
|
86
|
+
--themes light,dark \
|
|
87
|
+
--workspace "$APC_WORKSPACE_ID" --task "$PRISMER_TASK_ID"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Runner 的顺序是:registry target 校验 → 可选 baseline asset 回读 → Playwright 打真实 `/ui-canvas` deep link → PNG 像素闸 → 上传 task-bound assets → 写 `visibility=task:<id>` 的 ReportCard。非法 set/version/journey/node 在任何副作用前失败。默认 ReportCard path 同时包含 task 与本次 evidence id,因此同一节点重复运行不会撞已有 page;显式 `--path` 时调用方必须提供未占用路径。
|
|
91
|
+
|
|
92
|
+
需要旧图/新图并排时只传一个 `--baseline-light` **或** `--baseline-dark`;一张 ReportCard 只承载所选 theme 的一组 old/new。它只是 reference,不是 diff;结构化输出的 `comparison` 恒为 `"none"`。禁止编造偏差百分比、changed pixels 或视觉 PASS。
|
|
93
|
+
|
|
94
|
+
凭据只从已设置的 `APC_API_KEY` / `PRISMER_API_KEY` 环境读取,禁止把 token 放进命令参数或报告。
|
|
95
|
+
|
|
96
|
+
没有 task/workspace/live local cloud 时可以完成代码审计,但证据步骤必须写 `not-run + 原因`,不能声称已产 asset 或 ReportCard。
|
|
97
|
+
|
|
98
|
+
## 输出契约
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
CANVAS: <set>@<version> | route: </ui-canvas?...>
|
|
102
|
+
PRODUCTION: <count> | source: <repo-relative-path:line>
|
|
103
|
+
GAPS: <count> | refs: <drift refs>
|
|
104
|
+
REGISTRY-TEST: <command> | exit: <code>
|
|
105
|
+
PLAYWRIGHT: <local command> | exit: <code> | passed: <count>
|
|
106
|
+
EVIDENCE: route=<exact deep link> | themes=light,dark | comparison=none
|
|
107
|
+
ASSETS: light=<assetId>(bytes=<n>) | dark=<assetId>(bytes=<n>)
|
|
108
|
+
REPORTCARD: pageId=<id> | uri=<prismer uri> | visibility=task:<taskId>
|
|
109
|
+
HARNESS: <command> | exit: <code>
|
|
110
|
+
BOUNDARY: canvas interaction and evidence are not service verification
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
只汇报真跑结果。任何 `not-run` 都必须带原因;没有 pageId 就没有持久化 ReportCard。
|
|
114
|
+
|
|
115
|
+
## Red flags
|
|
116
|
+
|
|
117
|
+
- 在 `/ui-kit` 画一个相似稿再当 production
|
|
118
|
+
- 用摘要卡代表真实 UI,或把真实组件藏进 detached Focus
|
|
119
|
+
- 默认 Fit 整条路径,导致 Frame 变成不可读缩略图
|
|
120
|
+
- 复制生产 JSX 到 Canvas
|
|
121
|
+
- 用 mock 隐藏缺失 checkpoint
|
|
122
|
+
- 为截图在 Canvas 调业务 API
|
|
123
|
+
- 原地修改 `aligned` 版本
|
|
124
|
+
- 用 asset/ReportCard 的存在声称视觉已经通过
|
|
125
|
+
- 把 Canvas local callback 说成系统副作用已验证
|
|
126
|
+
|
|
127
|
+
出现任一项就停止,把节点改回 `gap`、建立共享生产 `*View`,或如实降低证据结论。
|
|
128
|
+
|
|
129
|
+
<!-- APC-ACK:v1 -->
|
|
130
|
+
|
|
131
|
+
## 调用回执
|
|
132
|
+
|
|
133
|
+
执行本 Skill 的第一步:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
cloud skill ack ui-canvas --task "$PRISMER_TASK_ID"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
| exit | 含义 | 动作 |
|
|
140
|
+
| --- | --- | --- |
|
|
141
|
+
| `0` | 回执已落库 | 继续 |
|
|
142
|
+
| `3` | 无 task 上下文 | 继续,但不得声称已 ack 或已发布 task evidence |
|
|
143
|
+
| `4` | 不是 task assignee | 停止并上报 |
|
|
144
|
+
| `1` | 网络或服务端失败 | 重试一次,仍失败则标注回执缺失 |
|
|
145
|
+
|
|
146
|
+
回执只证明 Skill 被调度,不证明执行正确。
|
|
147
|
+
|
|
148
|
+
<!-- /APC-ACK:v1 -->
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"slug": "ui-canvas",
|
|
4
|
+
"name": "UI Canvas",
|
|
5
|
+
"description": "Align product journeys and UI/UX actions to directly imported production React components, explicit gaps, bidirectional implementation-spec references, immutable code-defined versions, and task-bound screenshot plus ReportCard evidence.",
|
|
6
|
+
"category": "design",
|
|
7
|
+
"version": "2.0.0",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"compatibility": ["claude-code", "codex"],
|
|
10
|
+
"runtime": {
|
|
11
|
+
"kind": "text-workflow",
|
|
12
|
+
"requires": {
|
|
13
|
+
"env": [],
|
|
14
|
+
"bins": ["git", "rg", "node", "npx"],
|
|
15
|
+
"capabilities": []
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"sampleTasks": [
|
|
19
|
+
{
|
|
20
|
+
"title": "Audit and publish task-bound evidence for a Product207 production Frame",
|
|
21
|
+
"prompt": "Use the ui-canvas skill to audit Product207 v1 and publish visual evidence for S1-01. Read `docs/product207/01-ui-mvp-seven-step-journey-contract.md`, `src/app/ui-canvas/registry/sets/product207/v1.ts`, and `src/app/ui-canvas/registry/component-registry.tsx`. Confirm the spec↔canvas reverse index, count checkpoints exactly once, classify every node as direct production or explicit gap, and verify no source comes from `src/app/ui-kit/sections/**`. Do not mutate aligned v1. Run `npx vitest run src/app/ui-canvas/__tests__`, `npx tsc --noEmit`, and only against local Next run `PRISMER_BASE_URL=http://127.0.0.1:3000 npx playwright test e2e-playwright/specs/ui-canvas.spec.ts --project=chromium`. Then run `npx tsx scripts/ui-canvas-evidence.ts --list`, followed by `npx tsx scripts/ui-canvas-evidence.ts --set product207 --version v1 --journey s1 --node s1-01 --themes light,dark --workspace \"$APC_WORKSPACE_ID\" --task \"$PRISMER_TASK_ID\"`. Read the harness JSON and report exactly these keyed lines with real values:\n\nCANVAS: product207@v1 | route: /ui-canvas?set=product207&version=v1&journey=s1&node=s1-01\nPRODUCTION: <count> | source: <repo-relative production import path:line>\nGAPS: <count> | refs: <drift refs>\nREGISTRY-TEST: npx vitest run src/app/ui-canvas/__tests__ | exit: <code>\nPLAYWRIGHT: <local command> | exit: <code> | passed: <count>\nEVIDENCE: route=/ui-canvas?set=product207&version=v1&journey=s1&node=s1-01 | themes=light,dark | comparison=none\nASSETS: light=<assetId>(bytes=<n>) | dark=<assetId>(bytes=<n>)\nREPORTCARD: pageId=<id> | uri=<prismer uri> | visibility=task:<taskId>\nHARNESS: npx tsx scripts/ui-canvas-evidence.ts ... | exit: <code>\nBOUNDARY: canvas interaction and evidence are not service verification\n\nDo not claim visual correctness or service verification. This sample requires live local cloud, workspace, and task context. If any is unavailable, report `BLOCKED` with the exact reason and state that the sample does not satisfy acceptance; never invent runtime ids.",
|
|
22
|
+
"expectedArtifacts": [
|
|
23
|
+
"the exact immutable UI Canvas Frame deep link",
|
|
24
|
+
"production and gap counts derived from the Canvas registry",
|
|
25
|
+
"a real production source path:line",
|
|
26
|
+
"real registry-test and local Playwright results",
|
|
27
|
+
"light and dark task-bound screenshot asset ids with byte counts",
|
|
28
|
+
"a persisted task-visible ReportCard pageId and uri",
|
|
29
|
+
"the harness comparison field verbatim as none",
|
|
30
|
+
"an explicit boundary that Canvas evidence is not service verification"
|
|
31
|
+
],
|
|
32
|
+
"acceptanceCriteria": [
|
|
33
|
+
{
|
|
34
|
+
"label": "declares the audited Canvas set, version, and exact Frame route",
|
|
35
|
+
"match": "CANVAS\\s*:\\s*product207@v1\\s*\\|\\s*route\\s*:\\s*/ui-canvas\\?set=product207&version=v1&journey=s1&node=s1-01",
|
|
36
|
+
"type": "regex",
|
|
37
|
+
"flags": "is",
|
|
38
|
+
"required": true
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"label": "reports production coverage with a real repo-relative source line",
|
|
42
|
+
"match": "PRODUCTION\\s*:\\s*\\d+\\s*\\|\\s*source\\s*:\\s*src/app/workspace/components/[^\\n:]+(?:/[^\\n:]+)*\\.tsx:\\d+",
|
|
43
|
+
"type": "regex",
|
|
44
|
+
"flags": "is",
|
|
45
|
+
"required": true
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"label": "reports explicit gaps with drift references",
|
|
49
|
+
"match": "GAPS\\s*:\\s*[1-9]\\d*\\s*\\|\\s*refs\\s*:\\s*[^\\n]{3,}",
|
|
50
|
+
"type": "regex",
|
|
51
|
+
"flags": "is",
|
|
52
|
+
"required": true
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"label": "reports a successful focused registry test",
|
|
56
|
+
"match": "REGISTRY-TEST\\s*:[^\\n]*vitest[^\\n]*ui-canvas/__tests__[^\\n]*exit\\s*:\\s*0",
|
|
57
|
+
"type": "regex",
|
|
58
|
+
"flags": "is",
|
|
59
|
+
"required": true
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"label": "reports successful local Playwright evidence with at least one passing test",
|
|
63
|
+
"match": "PLAYWRIGHT\\s*:[^\\n]*127\\.0\\.0\\.1[^\\n]*\\|\\s*exit\\s*:\\s*0[^\\n]*\\|\\s*passed\\s*:\\s*[1-9]\\d*",
|
|
64
|
+
"type": "regex",
|
|
65
|
+
"flags": "is",
|
|
66
|
+
"required": true
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"label": "identifies the exact Canvas evidence route, both themes, and no computed diff",
|
|
70
|
+
"match": "EVIDENCE\\s*:\\s*route=/ui-canvas\\?set=product207&version=v1&journey=s1&node=s1-01\\s*\\|\\s*themes=light,dark\\s*\\|\\s*comparison=none",
|
|
71
|
+
"type": "regex",
|
|
72
|
+
"flags": "is",
|
|
73
|
+
"required": true
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"label": "reports different light and dark screenshot asset ids with non-zero byte counts",
|
|
77
|
+
"match": "ASSETS\\s*:\\s*light=[A-Za-z0-9_-]+\\(bytes=[1-9]\\d*\\)\\s*\\|\\s*dark=[A-Za-z0-9_-]+\\(bytes=[1-9]\\d*\\)",
|
|
78
|
+
"type": "regex",
|
|
79
|
+
"flags": "is",
|
|
80
|
+
"required": true
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"label": "reports a persisted task-visible ReportCard",
|
|
84
|
+
"match": "REPORTCARD\\s*:\\s*pageId=[A-Za-z0-9_-]+\\s*\\|\\s*uri=prismer://[^\\s]+\\s*\\|\\s*visibility=task:[A-Za-z0-9_-]+",
|
|
85
|
+
"type": "regex",
|
|
86
|
+
"flags": "is",
|
|
87
|
+
"required": true
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"label": "reports the UI Canvas evidence harness success",
|
|
91
|
+
"match": "HARNESS\\s*:[^\\n]*ui-canvas-evidence\\.ts[^\\n]*\\|\\s*exit\\s*:\\s*0",
|
|
92
|
+
"type": "regex",
|
|
93
|
+
"flags": "is",
|
|
94
|
+
"required": true
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"label": "does not confuse Canvas evidence with service verification",
|
|
98
|
+
"match": "BOUNDARY\\s*:\\s*canvas interaction and evidence are not service verification",
|
|
99
|
+
"type": "regex",
|
|
100
|
+
"flags": "is",
|
|
101
|
+
"required": true
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"security": {
|
|
107
|
+
"dataAccess": ["local-filesystem", "network"],
|
|
108
|
+
"humanApprovalRequiredFor": []
|
|
109
|
+
},
|
|
110
|
+
"provenance": {
|
|
111
|
+
"sourceKind": "inline-spec",
|
|
112
|
+
"sourceRefs": [
|
|
113
|
+
"docs/product207/15-ui-canvas-design.md",
|
|
114
|
+
"docs/product207/17-ui-canvas-expanded-frames-design.md",
|
|
115
|
+
"docs/product207/16-ui-canvas-implementation-plan.md",
|
|
116
|
+
"docs/product207/18-ui-canvas-expanded-frames-implementation-plan.md",
|
|
117
|
+
"docs/product207/01-ui-mvp-seven-step-journey-contract.md",
|
|
118
|
+
"src/app/ui-canvas/registry/sets/product207/v1.ts",
|
|
119
|
+
"src/app/ui-canvas/registry/component-registry.tsx",
|
|
120
|
+
"scripts/ui-canvas-evidence.ts",
|
|
121
|
+
"sdk/apc/harness/report-card.ts",
|
|
122
|
+
"e2e-playwright/specs/ui-canvas.spec.ts"
|
|
123
|
+
],
|
|
124
|
+
"authoredBy": "prismer-platform",
|
|
125
|
+
"authoredAt": "2026-07-29T00:00:00Z"
|
|
126
|
+
}
|
|
127
|
+
}
|