@kitn.ai/ui 0.25.2 → 0.27.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/README.md +17 -6
- package/bin/mcp.js +16 -3
- package/bin/route.js +23 -0
- package/bin/route.test.js +58 -0
- package/dist/{elements/chunks/Icon-b5A8hlHs.js → Icon-BnFKqqtY.js} +1 -1
- package/dist/action-icons-CBskfBMz.js +1 -0
- package/dist/arrow-down-Br0qtpsz.js +1 -0
- package/dist/arrow-left-Dj7xgE12.js +1 -0
- package/dist/artifact-CvXEm1lS.js +1 -0
- package/dist/assets/dev-5XzXYR21.js +91 -0
- package/dist/attachments-C43ZegEq.js +1 -0
- package/dist/audio-visualizer-B-79y1Tj.js +1 -0
- package/dist/badge-BpUbq8c0.js +1 -0
- package/dist/bash-InADTalH.js +1 -6
- package/dist/bell-sn17Ip9v.js +1 -0
- package/dist/{elements/chunks/button-B9okqG73.js → button-BH6rN0U-.js} +1 -1
- package/dist/card-renderer-Cb1gQmth.js +1 -0
- package/dist/card-routing-DifQgS7n.js +1 -0
- package/dist/check-DPeeMUYx.js +1 -0
- package/dist/checkbox-Dc9Yov_B.js +1 -0
- package/dist/checkbox-group-B1kDLLYk.js +1 -0
- package/dist/chevron-down-CHSWk7ZT.js +1 -0
- package/dist/chevron-right-B7l_fMgx.js +1 -0
- package/dist/choice-card-BT3c1S8g.js +1 -0
- package/dist/circle-Bb0yOpqM.js +1 -0
- package/dist/circle-check-BGZpCiz7.js +1 -0
- package/dist/circle-x-wobWkoSx.js +1 -0
- package/dist/{elements/chunks/cn-CU7UAWzk.js → cn-DN5AWfiS.js} +1 -1
- package/dist/code-block-CUQ5mtv0.js +1 -0
- package/dist/collapsible-CPJbf6FM.js +1 -0
- package/dist/components/attachment-types.d.ts +53 -1
- package/dist/components/attachments.d.ts +31 -0
- package/dist/components/audio-visualizer/fit-scale.d.ts +50 -0
- package/dist/components/audio-visualizer/index.d.ts +15 -1
- package/dist/components/audio-visualizer/variant-bar.d.ts +24 -1
- package/dist/components/card-renderer.d.ts +13 -0
- package/dist/components/card.d.ts +4 -0
- package/dist/components/chat-thread.d.ts +49 -42
- package/dist/components/code-block.d.ts +22 -0
- package/dist/components/conversation-item.d.ts +66 -1
- package/dist/components/conversation-list.d.ts +77 -0
- package/dist/components/form-widgets.d.ts +67 -2
- package/dist/components/form.d.ts +89 -0
- package/dist/components/message.d.ts +29 -0
- package/dist/components/reasoning.d.ts +6 -0
- package/dist/components/scroll-button.d.ts +11 -0
- package/dist/components/thread.d.ts +5 -0
- package/dist/components/toast.d.ts +2 -1
- package/dist/components/tool-types.d.ts +9 -0
- package/dist/components/voice-input.d.ts +8 -0
- package/dist/components/voice-output.d.ts +12 -1
- package/dist/components/workspace-shell.d.ts +87 -0
- package/dist/composer-CjngLzal.js +106 -0
- package/dist/confirm-card-DCx_A4bU.js +1 -0
- package/dist/construct-cli.es.js +1169 -0
- package/dist/context-BY8V-Nlp.js +1 -0
- package/dist/controllable-D43BKmtX.js +1 -0
- package/dist/conversation-list-D4lLU_yS.js +1 -0
- package/dist/copy-B6DO4PqB.js +1 -0
- package/dist/core-AYMC6_lb.js +12 -5874
- package/dist/{create-tween-CUzOlaMS.js → create-tween-BPzaefTp.js} +1 -1
- package/dist/{create-tween-B5Y4Im8G.js → create-tween-CnMHviKB.js} +1 -1
- package/dist/{create-tween-4z1XYLkR.js → create-tween-D1aiGZZh.js} +1 -1
- package/dist/{elements/chunks/create-tween-CUrM6D_o.js → create-tween-DUSQUKpr.js} +2 -2
- package/dist/css-M7EaDHN_.js +1 -6
- package/dist/custom-elements.json +3468 -1927
- package/dist/default-input-CucQEOqH.js +1 -0
- package/dist/define-CGGX-7Vg.js +1 -0
- package/dist/define.d.ts +4 -0
- package/dist/define.js +510 -0
- package/dist/define.server.d.ts +5 -0
- package/dist/define.server.js +506 -0
- package/dist/diagnostics/hook.d.ts +81 -0
- package/dist/diagnostics/index.d.ts +7 -0
- package/dist/diagnostics/report-request.d.ts +61 -0
- package/dist/diagnostics.d.ts +5 -0
- package/dist/diagnostics.js +209 -0
- package/dist/disclosure-CbLtajUQ.js +1 -0
- package/dist/dropdown-BwhViJFd.js +1 -0
- package/dist/elements/agent-card.js +1 -1
- package/dist/elements/artifact.js +1 -1
- package/dist/elements/attachments.js +1 -1
- package/dist/elements/audio-visualizer.js +1 -1
- package/dist/elements/autoloader.js +1 -1
- package/dist/elements/avatar.js +1 -1
- package/dist/elements/badge.js +1 -1
- package/dist/elements/button.js +1 -1
- package/dist/elements/card.js +1 -1
- package/dist/elements/cards.js +1 -1
- package/dist/elements/chain-of-thought.js +1 -1
- package/dist/elements/chat-scope-picker.js +1 -1
- package/dist/elements/chat-workspace.js +1 -1
- package/dist/elements/chat.js +1 -1
- package/dist/elements/checkbox-group.d.ts +1 -0
- package/dist/elements/checkbox-group.js +1 -0
- package/dist/elements/checkbox.d.ts +1 -0
- package/dist/elements/checkbox.js +1 -0
- package/dist/elements/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/coachmark.js +1 -1
- package/dist/elements/code-block.js +1 -1
- package/dist/elements/command.js +1 -1
- package/dist/elements/compare.js +1 -1
- package/dist/elements/composer.js +1 -1
- package/dist/elements/confirm-card.js +1 -1
- package/dist/elements/context-meter.js +1 -1
- package/dist/elements/conversation-item.d.ts +1 -0
- package/dist/elements/conversation-item.js +1 -0
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/default-input.d.ts +3 -3
- package/dist/elements/define-entry.d.ts +12 -0
- package/dist/elements/define.d.ts +27 -0
- package/dist/elements/diagnostic-events.d.ts +74 -0
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/dock.d.ts +1 -0
- package/dist/elements/dock.js +243 -0
- package/dist/elements/dropdown.d.ts +1 -0
- package/dist/elements/dropdown.js +1 -0
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/element-data-types.d.ts +37 -0
- package/dist/elements/element-diagnostics.d.ts +81 -0
- package/dist/elements/embed.js +1 -1
- package/dist/elements/empty.js +1 -1
- package/dist/elements/feedback-bar.js +1 -1
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/form.js +1 -1
- package/dist/elements/hover-card.js +1 -1
- package/dist/elements/icon.js +1 -1
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.js +1 -1
- package/dist/elements/kbd.js +1 -1
- package/dist/elements/link-preview.js +1 -1
- package/dist/elements/loader.js +1 -1
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/menu.js +1 -1
- package/dist/elements/message-skills.js +1 -1
- package/dist/elements/message.js +1 -1
- package/dist/elements/model-switcher.js +1 -1
- package/dist/elements/nav.js +1 -1
- package/dist/elements/notice.js +1 -1
- package/dist/elements/pane-grid.d.ts +1 -0
- package/dist/elements/pane-grid.js +1 -0
- package/dist/elements/pane-group.js +1 -1
- package/dist/elements/pane.js +1 -1
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.js +1 -1
- package/dist/elements/prompt-dock.js +1 -1
- package/dist/elements/prompt-input.js +1 -1
- package/dist/elements/prompt-suggestions.js +1 -1
- package/dist/elements/radio-group.d.ts +1 -0
- package/dist/elements/radio-group.js +1 -0
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/register.d.ts +2 -0
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +3 -3
- package/dist/elements/screen.js +1 -1
- package/dist/elements/scroll-area.js +1 -1
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.js +1 -1
- package/dist/elements/segmented.js +1 -1
- package/dist/elements/select.d.ts +1 -0
- package/dist/elements/select.js +1 -0
- package/dist/elements/separator.js +1 -1
- package/dist/elements/setting-item.js +1 -1
- package/dist/elements/settings-group.js +1 -1
- package/dist/elements/skeleton.js +1 -1
- package/dist/elements/slider.d.ts +1 -0
- package/dist/elements/slider.js +1 -0
- package/dist/elements/slots.d.ts +36 -4
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.js +1 -1
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.js +1 -1
- package/dist/elements/tasks.js +1 -1
- package/dist/elements/text-shimmer.js +1 -1
- package/dist/elements/thinking-bar.js +1 -1
- package/dist/elements/thread.js +1 -1
- package/dist/elements/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.js +1 -1
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.js +1 -1
- package/dist/elements.d.ts +589 -167
- package/dist/{elements/chunks/ellipsis-CVxqfsDZ.js → ellipsis-DFr4Vqr3.js} +1 -1
- package/dist/embed-5s_vU4J0.js +1 -0
- package/dist/engine-javascript-vq0WuIJl.js +14 -2516
- package/dist/{elements/chunks/external-link-DG2sRdQL.js → external-link-u9d85ORQ.js} +1 -1
- package/dist/file-text-CX7_x42o.js +1 -0
- package/dist/{elements/chunks/file-tree-yGWNK0Js.js → file-tree-D3kBjXI5.js} +1 -1
- package/dist/folder-V-YdIL8f.js +1 -0
- package/dist/form-BRNUMCN2.js +1 -0
- package/dist/github-dark-dimmed-DUshB20C.js +1 -4
- package/dist/github-light-JYsPkUQd.js +1 -4
- package/dist/hover-card-DaeiYrTA.js +1 -0
- package/dist/html-CPZ3oZQ7.js +1 -10
- package/dist/icon-BpixdZNq.js +1 -0
- package/dist/{elements/chunks/index-BCRhi84a.js → index-xu_pdcPi.js} +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +8473 -6470
- package/dist/index.server.js +6495 -4958
- package/dist/info-8mFsIjS3.js +1 -0
- package/dist/input-d1Yuu-hz.js +1 -0
- package/dist/javascript-C25yR2R2.js +1 -6
- package/dist/json-DxJze_jm.js +1 -6
- package/dist/kai-provider.es.js +40 -40
- package/dist/kai.es.js +1 -1
- package/dist/kbd-961zMPFB.js +1 -0
- package/dist/link-DlZZBGaR.js +1 -0
- package/dist/{elements/chunks/link-preview-Cf5KOP-i.js → link-preview-DIIbV2Sd.js} +1 -1
- package/dist/loader-YQszHFaW.js +1 -0
- package/dist/{elements/chunks/markdown-DbozyYqa.js → markdown-CVk1MPsj.js} +1 -1
- package/dist/mcp.es.js +3873 -544
- package/dist/message-CwKVEdZg.js +1 -0
- package/dist/message-DS8lzHc1.js +1 -0
- package/dist/message-circle-Xf8Q-vZp.js +1 -0
- package/dist/message-square-Cxnwgkns.js +1 -0
- package/dist/{elements/chunks/minimize-2-SegJ_oku.js → minimize-2-UEZmP2QT.js} +1 -1
- package/dist/{elements/chunks/model-switcher-D7JrFFHp.js → model-switcher-Kk1jEQ5t.js} +1 -1
- package/dist/{elements/chunks/overlay-CV7z2YuX.js → overlay-C1od6LOz.js} +1 -1
- package/dist/panel-right-ryET0yyn.js +1 -0
- package/dist/paperclip-BDNoZFJP.js +1 -0
- package/dist/play-OFIvYXUQ.js +1 -0
- package/dist/primitives/card-data-types.d.ts +49 -0
- package/dist/primitives/card-routing.d.ts +1 -33
- package/dist/primitives/card-validate.d.ts +2 -2
- package/dist/primitives/chat-config.d.ts +29 -2
- package/dist/primitives/field-mask.d.ts +96 -0
- package/dist/primitives/field-semantics.d.ts +36 -0
- package/dist/primitives/input-mask.d.ts +46 -0
- package/dist/primitives/url-scheme-policy.d.ts +34 -0
- package/dist/primitives/use-resize-observer.d.ts +23 -0
- package/dist/primitives/use-speech-recognition.d.ts +8 -0
- package/dist/primitives/use-text-stream.d.ts +5 -0
- package/dist/progress-bar-BvYX0aoy.js +1 -0
- package/dist/prompt-suggestion-BRFu2lcu.js +1 -0
- package/dist/radio-DcL23cNJ.js +1 -0
- package/dist/react/index.d.ts +306 -283
- package/dist/react.js +309 -247
- package/dist/reasoning-Cackq4Rh.js +1 -0
- package/dist/register-impl-C7rENvPK.js +424 -0
- package/dist/{elements/chunks/resizable-Dpzjlvp4.js → resizable-Cp9HUYih.js} +1 -1
- package/dist/rotate-ccw-0DLRDHH5.js +1 -0
- package/dist/rotate-cw-DOB9IGcU.js +1 -0
- package/dist/schemas/form.schema.json +21 -1
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/tool-defs.d.ts +45 -0
- package/dist/schemas.js +398 -305
- package/dist/scroll-area-emVmWP4K.js +1 -0
- package/dist/scroll-button-CeP_gv1x.js +1 -0
- package/dist/select-CWmu00tS.js +1 -0
- package/dist/{elements/chunks/separator-DH2r_ZSZ.js → separator-CE6vly6z.js} +1 -1
- package/dist/{elements/chunks/settings-BFMOd6yB.js → settings-CE-78SvZ.js} +1 -1
- package/dist/{elements/chunks/settings-group-B3VZKIcz.js → settings-group-ZFWNxFQR.js} +1 -1
- package/dist/{elements/chunks/skeleton-N8BuWYmf.js → skeleton-BebdP4mf.js} +1 -1
- package/dist/slider-BAKRYUlz.js +1 -0
- package/dist/slots-DaNjX0rc.js +1 -0
- package/dist/{solid-BMuDmFo_.js → solid-BE5ui6sy.js} +10672 -8116
- package/dist/{solid-CGYNdLRR.js → solid-DFhsce3O.js} +8137 -6056
- package/dist/solid.d.ts +15 -0
- package/dist/solid.js +248 -235
- package/dist/solid.server.js +248 -235
- package/dist/source-B0FlguSx.js +1 -0
- package/dist/star-CBMZvLuN.js +1 -0
- package/dist/state/index.d.ts +5 -1
- package/dist/state/mock.d.ts +32 -2
- package/dist/state/persistence.d.ts +51 -0
- package/dist/state/stream.d.ts +50 -0
- package/dist/state/threads.d.ts +71 -0
- package/dist/state.js +297 -172
- package/dist/store-7eoadydQ.js +1 -0
- package/dist/svelte--5p79yCD.js +1 -15
- package/dist/switch-CViARZCy.js +1 -0
- package/dist/tasks-card-MjCcOhR_.js +1 -0
- package/dist/text-shimmer-DKlwRF2G.js +1 -0
- package/dist/textarea-3ay2Me2-.js +1 -0
- package/dist/theme.tokens.css +82 -13
- package/dist/{elements/chunks/thumbs-up-DQe0hvkZ.js → thumbs-up-DQcu2HMO.js} +1 -1
- package/dist/toast-store-C6yKOhbk.js +1 -0
- package/dist/{elements/chunks/tool-C1YtxwPu.js → tool-BCYNlfKy.js} +1 -1
- package/dist/{elements/chunks/tooltip-BqwnFWhn.js → tooltip-05zI4hjs.js} +1 -1
- package/dist/trash-2-BR1RxGky.js +1 -0
- package/dist/{elements/chunks/triangle-alert-B6or7F5u.js → triangle-alert-DHohDOCy.js} +1 -1
- package/dist/tsx-B8rCNbgL.js +1 -6
- package/dist/types.d.ts +4 -2
- package/dist/typescript-RycA9KXf.js +1 -6
- package/dist/ui/checkbox-group.d.ts +83 -0
- package/dist/ui/checkbox.d.ts +40 -0
- package/dist/ui/dock.d.ts +131 -0
- package/dist/ui/hover-card.d.ts +44 -0
- package/dist/ui/icon.d.ts +3 -0
- package/dist/ui/input.d.ts +48 -2
- package/dist/ui/radio.d.ts +85 -0
- package/dist/ui/select.d.ts +71 -0
- package/dist/ui/slider.d.ts +65 -0
- package/dist/ui/switch.d.ts +9 -2
- package/dist/upload-BbGW6A_u.js +1 -0
- package/dist/url-scheme-policy-DHpoTJwB.js +1 -0
- package/dist/use-card-resolution-CJW4grFa.js +1 -0
- package/dist/{variant-aurora-DwSOfraQ.js → variant-aurora-BUOVgPOB.js} +27 -27
- package/dist/{variant-aurora-wKvAQ5wp.js → variant-aurora-CUsUJvFI.js} +28 -28
- package/dist/{variant-aurora-XEkPT0_z.js → variant-aurora-CW2i4bfr.js} +2 -2
- package/dist/{elements/chunks/variant-aurora-QXTZPyST.js → variant-aurora-xiMPty8f.js} +2 -2
- package/dist/variant-custom-BQtOnmeO.js +1 -0
- package/dist/{variant-custom-BhS9wIpU.js → variant-custom-CAm9L-E5.js} +65 -65
- package/dist/{variant-custom-eFIg2XWQ.js → variant-custom-CAnzzppW.js} +40 -40
- package/dist/variant-custom-D91HjAKz.js +1 -0
- package/dist/{variant-wave-CUWGx9Bn.js → variant-wave-Ca1Ls4_y.js} +21 -21
- package/dist/{variant-wave-CbVsmgwT.js → variant-wave-CxX39DKd.js} +25 -25
- package/dist/{variant-wave-BwzrHD1s.js → variant-wave-DYyzIIZv.js} +2 -2
- package/dist/{elements/chunks/variant-wave-DDCwhLas.js → variant-wave-uY5crU_K.js} +2 -2
- package/dist/vue-BmIZj4XD.js +1 -33
- package/dist/wire/chunk.d.ts +47 -0
- package/dist/wire/diagnostics.d.ts +575 -0
- package/dist/wire/encode-probe.d.ts +70 -0
- package/dist/wire/encode.d.ts +24 -0
- package/dist/wire/index.d.ts +2 -0
- package/dist/wire/sse.d.ts +10 -2
- package/dist/wire.js +917 -480
- package/dist/x-C5m1JFgi.js +1 -0
- package/frameworks/react/index.tsx +325 -108
- package/llms-full.txt +1354 -82
- package/llms.txt +6 -3
- package/package.json +39 -6
- package/src/agent-tooling/archetypes.ts +41 -9
- package/src/agent-tooling/catalog/README.md +676 -0
- package/src/agent-tooling/catalog/catalog-types.ts +231 -0
- package/src/agent-tooling/catalog/fabrications.ts +96 -0
- package/src/agent-tooling/catalog/invariants.ts +284 -0
- package/src/agent-tooling/catalog/labs-titles.ts +114 -0
- package/src/agent-tooling/catalog/scenarios.ts +87 -0
- package/src/agent-tooling/catalog/surfaces.ts +347 -0
- package/src/agent-tooling/construct/cli-entry.ts +8 -0
- package/src/agent-tooling/construct/cli.ts +131 -0
- package/src/agent-tooling/construct/codegen.ts +1353 -0
- package/src/agent-tooling/construct/construct.v1.schema.json +250 -0
- package/src/agent-tooling/construct/dev.ts +148 -0
- package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +7 -0
- package/src/agent-tooling/construct/fixtures/ops-console.construct.json +44 -0
- package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +23 -0
- package/src/agent-tooling/construct/schema.ts +371 -0
- package/src/agent-tooling/integrations/anthropic.ts +7 -1
- package/src/agent-tooling/integrations/cloudflare.ts +43 -2
- package/src/agent-tooling/integrations/langgraph.ts +7 -1
- package/src/agent-tooling/integrations/mastra.ts +7 -1
- package/src/agent-tooling/integrations/mock.ts +92 -17
- package/src/agent-tooling/integrations/ollama.ts +7 -1
- package/src/agent-tooling/integrations/openai.ts +7 -1
- package/src/agent-tooling/integrations/openrouter.ts +7 -1
- package/src/agent-tooling/integrations/pi.ts +56 -1
- package/src/agent-tooling/integrations/vercel-ai-sdk.ts +7 -1
- package/src/agent-tooling/mcp/css-raw.d.ts +12 -0
- package/src/agent-tooling/mcp/manifest.ts +100 -1
- package/src/agent-tooling/mcp/server.ts +63 -6
- package/src/agent-tooling/mcp/tools/construct.ts +130 -0
- package/src/agent-tooling/mcp/tools/debug.ts +126 -4
- package/src/agent-tooling/mcp/tools/reference.ts +542 -5
- package/src/agent-tooling/mcp/tools/scaffold.ts +1834 -307
- package/src/agent-tooling/mcp/tools/theme.ts +146 -30
- package/src/agent-tooling/mcp/validate-args.ts +141 -0
- package/src/agent-tooling/recipes/composed-thread.ts +714 -0
- package/src/agent-tooling/recipes/index.ts +22 -0
- package/src/agent-tooling/recipes/types.ts +32 -0
- package/src/agent-tooling/registry.ts +24 -7
- package/src/agent-tooling/route-emit.ts +26 -2
- package/src/components/attachment-types.ts +54 -1
- package/src/components/attachments.tsx +169 -22
- package/src/components/audio-visualizer/fit-scale.ts +112 -0
- package/src/components/audio-visualizer/index.tsx +80 -3
- package/src/components/audio-visualizer/variant-aurora.tsx +10 -4
- package/src/components/audio-visualizer/variant-bar.tsx +38 -6
- package/src/components/audio-visualizer/variant-custom.tsx +8 -2
- package/src/components/audio-visualizer/variant-grid.tsx +16 -11
- package/src/components/audio-visualizer/variant-radial.tsx +15 -10
- package/src/components/audio-visualizer/variant-wave.tsx +7 -2
- package/src/components/card-renderer.tsx +39 -8
- package/src/components/card.tsx +10 -2
- package/src/components/chat-container.tsx +4 -1
- package/src/components/chat-scope-picker.tsx +2 -2
- package/src/components/chat-thread.tsx +105 -13
- package/src/components/choice-card.tsx +102 -37
- package/src/components/coachmark.tsx +1 -1
- package/src/components/code-block.tsx +81 -5
- package/src/components/composer.tsx +89 -8
- package/src/components/confirm-card.tsx +20 -4
- package/src/components/conversation-item.tsx +138 -4
- package/src/components/conversation-list.tsx +230 -15
- package/src/components/embed.tsx +4 -0
- package/src/components/empty.tsx +14 -3
- package/src/components/file-tree.tsx +5 -1
- package/src/components/form-widgets.tsx +257 -195
- package/src/components/form.tsx +336 -21
- package/src/components/loader.tsx +12 -5
- package/src/components/message-skills.tsx +1 -1
- package/src/components/message.tsx +142 -12
- package/src/components/prompt-input.tsx +7 -1
- package/src/components/prompt-suggestion.tsx +4 -1
- package/src/components/reasoning.tsx +30 -3
- package/src/components/response-compare.tsx +2 -2
- package/src/components/response-stream.tsx +13 -7
- package/src/components/screen.tsx +5 -0
- package/src/components/scroll-button.tsx +63 -4
- package/src/components/source.tsx +6 -1
- package/src/components/tasks-card.tsx +58 -16
- package/src/components/thread.tsx +10 -1
- package/src/components/toast.tsx +11 -5
- package/src/components/tool-types.ts +9 -0
- package/src/components/voice-input.tsx +35 -3
- package/src/components/voice-output.tsx +46 -6
- package/src/components/workspace-shell.tsx +285 -0
- package/src/diagnostics/hook.ts +352 -0
- package/src/diagnostics/index.ts +82 -0
- package/src/diagnostics/report-request.ts +296 -0
- package/src/elements/attachments.tsx +9 -8
- package/src/elements/audio-visualizer.tsx +48 -4
- package/src/elements/chat-workspace.tsx +159 -287
- package/src/elements/chat.tsx +31 -10
- package/src/elements/checkbox-group.tsx +164 -0
- package/src/elements/checkbox.tsx +134 -0
- package/src/elements/code-block.tsx +19 -1
- package/src/elements/command.tsx +4 -1
- package/src/elements/compiled.css +1 -1
- package/src/elements/composer.tsx +12 -1
- package/src/elements/conversation-item.tsx +120 -0
- package/src/elements/conversation-list.tsx +60 -11
- package/src/elements/default-input.tsx +5 -5
- package/src/elements/define-entry.ts +12 -0
- package/src/elements/define.tsx +168 -8
- package/src/elements/diagnostic-events.ts +114 -0
- package/src/elements/dialog.tsx +47 -0
- package/src/elements/disclosure.ts +34 -12
- package/src/elements/dock.tsx +215 -0
- package/src/elements/dropdown.tsx +123 -0
- package/src/elements/element-data-types.ts +40 -0
- package/src/elements/element-diagnostics.ts +392 -0
- package/src/elements/element-manifest.json +36 -0
- package/src/elements/element-meta.json +1483 -560
- package/src/elements/element-nonscalar.json +185 -0
- package/src/elements/element-types.d.ts +589 -167
- package/src/elements/feedback-bar.tsx +5 -0
- package/src/elements/icon-names.json +29 -0
- package/src/elements/input.tsx +312 -23
- package/src/elements/menu.tsx +13 -0
- package/src/elements/message.tsx +2 -0
- package/src/elements/pane-grid.tsx +111 -0
- package/src/elements/prompt-dock.tsx +2 -1
- package/src/elements/prompt-input.tsx +16 -10
- package/src/elements/radio-group.tsx +129 -0
- package/src/elements/register-impl.ts +52 -0
- package/src/elements/register.ts +28 -0
- package/src/elements/resizable.tsx +52 -25
- package/src/elements/scroll-button.tsx +59 -6
- package/src/elements/select.tsx +165 -0
- package/src/elements/slider.tsx +171 -0
- package/src/elements/slots.ts +108 -13
- package/src/elements/styles.css +119 -9
- package/src/elements/thinking-bar.tsx +16 -7
- package/src/elements/thread.tsx +2 -0
- package/src/elements/toast.tsx +17 -1
- package/src/elements/tool.tsx +26 -5
- package/src/elements/voice-input.tsx +11 -2
- package/src/elements/voice-output.tsx +16 -3
- package/src/index.ts +4 -1
- package/src/primitives/card-data-types.ts +49 -0
- package/src/primitives/card-host.tsx +4 -2
- package/src/primitives/card-routing.ts +7 -56
- package/src/primitives/card-schemas/form.schema.json +21 -1
- package/src/primitives/card-validate.ts +10 -2
- package/src/primitives/chat-config.tsx +33 -6
- package/src/primitives/field-mask.ts +256 -0
- package/src/primitives/field-semantics.ts +115 -0
- package/src/primitives/input-mask.ts +853 -0
- package/src/primitives/toast-store.ts +66 -4
- package/src/primitives/url-scheme-policy.ts +70 -0
- package/src/primitives/use-resize-observer.ts +33 -0
- package/src/primitives/use-speech-recognition.ts +12 -1
- package/src/primitives/use-stick-to-bottom.ts +34 -2
- package/src/primitives/use-text-stream.ts +33 -2
- package/src/remote/provider-runtime.ts +6 -3
- package/src/schemas/index.ts +1 -0
- package/src/schemas/tool-defs.ts +307 -6
- package/src/solid.ts +15 -0
- package/src/state/index.ts +13 -1
- package/src/state/mock.ts +92 -6
- package/src/state/persistence.ts +180 -0
- package/src/state/stream.ts +71 -4
- package/src/state/threads.ts +142 -0
- package/src/types.ts +4 -2
- package/src/ui/agent-card.tsx +2 -2
- package/src/ui/avatar.tsx +1 -1
- package/src/ui/checkbox-group.tsx +153 -0
- package/src/ui/checkbox.tsx +63 -0
- package/src/ui/dialog.tsx +6 -0
- package/src/ui/dock.tsx +584 -0
- package/src/ui/dropdown.tsx +67 -23
- package/src/ui/hover-card.tsx +156 -6
- package/src/ui/icon.tsx +53 -0
- package/src/ui/input.tsx +275 -16
- package/src/ui/kbd.tsx +1 -1
- package/src/ui/nav.tsx +1 -1
- package/src/ui/pane-group.tsx +2 -2
- package/src/ui/radio.tsx +150 -0
- package/src/ui/resizable.tsx +11 -0
- package/src/ui/select.tsx +168 -0
- package/src/ui/slider.tsx +178 -0
- package/src/ui/switch.tsx +49 -18
- package/src/utils/cn.ts +11 -5
- package/src/wire/chunk.ts +47 -0
- package/src/wire/consume.ts +185 -26
- package/src/wire/diagnostics.ts +727 -0
- package/src/wire/encode-probe.ts +214 -0
- package/src/wire/encode.ts +267 -14
- package/src/wire/formats/anthropic.ts +8 -1
- package/src/wire/formats/openai.ts +5 -0
- package/src/wire/index.ts +22 -0
- package/src/wire/read.ts +250 -6
- package/src/wire/sse.ts +16 -3
- package/theme.css +84 -13
- package/dist/elements/chunks/action-icons-DW9muWrY.js +0 -1
- package/dist/elements/chunks/arrow-left-iJVnQmxA.js +0 -1
- package/dist/elements/chunks/artifact-BSuPYFHY.js +0 -1
- package/dist/elements/chunks/attachments-CL6TaqIb.js +0 -1
- package/dist/elements/chunks/audio-visualizer-BuUqQmaO.js +0 -1
- package/dist/elements/chunks/badge-TIMiJFKc.js +0 -1
- package/dist/elements/chunks/bash-InADTalH.js +0 -1
- package/dist/elements/chunks/card-renderer-CSoTL_e1.js +0 -1
- package/dist/elements/chunks/card-routing-BK09BdmL.js +0 -1
- package/dist/elements/chunks/chat-thread-DxoKaStk.js +0 -1
- package/dist/elements/chunks/check-MdLzbxrm.js +0 -1
- package/dist/elements/chunks/chevron-down-MK7IzDqe.js +0 -1
- package/dist/elements/chunks/chevron-right-C5jXhmtV.js +0 -1
- package/dist/elements/chunks/choice-card-CGMc3kek.js +0 -1
- package/dist/elements/chunks/circle-BG7VkPep.js +0 -1
- package/dist/elements/chunks/circle-check-GqvO2UBs.js +0 -1
- package/dist/elements/chunks/circle-x-mhH7pOK2.js +0 -1
- package/dist/elements/chunks/code-block-ClhQO9RW.js +0 -1
- package/dist/elements/chunks/collapsible-DBcBkFPh.js +0 -1
- package/dist/elements/chunks/composer-CZZmtYOT.js +0 -69
- package/dist/elements/chunks/confirm-card-BWjf2-xo.js +0 -1
- package/dist/elements/chunks/context-hKjNqiyQ.js +0 -1
- package/dist/elements/chunks/conversation-list-CsGJjSKG.js +0 -1
- package/dist/elements/chunks/core-AYMC6_lb.js +0 -12
- package/dist/elements/chunks/css-M7EaDHN_.js +0 -1
- package/dist/elements/chunks/default-input-B1Mem5wu.js +0 -1
- package/dist/elements/chunks/define-B_tXMYRm.js +0 -1
- package/dist/elements/chunks/disclosure-DAoYOKew.js +0 -1
- package/dist/elements/chunks/download-DnCyWFJE.js +0 -1
- package/dist/elements/chunks/dropdown-CmNna5lT.js +0 -1
- package/dist/elements/chunks/embed-CjAD2jSi.js +0 -1
- package/dist/elements/chunks/engine-javascript-vq0WuIJl.js +0 -141
- package/dist/elements/chunks/file-text-D0J9F6M7.js +0 -1
- package/dist/elements/chunks/folder-NV1pi_ud.js +0 -1
- package/dist/elements/chunks/form-Cp8Y00Wn.js +0 -1
- package/dist/elements/chunks/github-dark-dimmed-DUshB20C.js +0 -1
- package/dist/elements/chunks/github-light-JYsPkUQd.js +0 -1
- package/dist/elements/chunks/hover-card-6KtXpLwT.js +0 -1
- package/dist/elements/chunks/html-CPZ3oZQ7.js +0 -1
- package/dist/elements/chunks/icon-97R8SR2p.js +0 -1
- package/dist/elements/chunks/info-C8r5Q6cc.js +0 -1
- package/dist/elements/chunks/input-DrseEjhp.js +0 -1
- package/dist/elements/chunks/javascript-C25yR2R2.js +0 -1
- package/dist/elements/chunks/json-DxJze_jm.js +0 -1
- package/dist/elements/chunks/kbd-OGJDUT-O.js +0 -1
- package/dist/elements/chunks/link-BdsfLB7b.js +0 -1
- package/dist/elements/chunks/loader-B5QzK_8_.js +0 -1
- package/dist/elements/chunks/message-CE4k-qaj.js +0 -1
- package/dist/elements/chunks/message-DtXKPqiR.js +0 -1
- package/dist/elements/chunks/message-square-C9ovmtOo.js +0 -1
- package/dist/elements/chunks/paperclip-Bg0ITU3b.js +0 -1
- package/dist/elements/chunks/progress-bar-D1_rzt6N.js +0 -1
- package/dist/elements/chunks/prompt-suggestion-D5Sm8xF1.js +0 -1
- package/dist/elements/chunks/reasoning-BrxQfpfI.js +0 -1
- package/dist/elements/chunks/rotate-cw-DzVDJOA1.js +0 -1
- package/dist/elements/chunks/scroll-area-93A1bbeG.js +0 -1
- package/dist/elements/chunks/scroll-button-CrTo7wm4.js +0 -1
- package/dist/elements/chunks/share-DgNbkJKY.js +0 -1
- package/dist/elements/chunks/slots-CIw9RlAe.js +0 -1
- package/dist/elements/chunks/source-w9V0NnBn.js +0 -1
- package/dist/elements/chunks/star-DHvACxtm.js +0 -1
- package/dist/elements/chunks/store-HIPGhNz9.js +0 -1
- package/dist/elements/chunks/svelte--5p79yCD.js +0 -1
- package/dist/elements/chunks/tasks-card-lPxoodlA.js +0 -1
- package/dist/elements/chunks/text-shimmer-BY_rI3s5.js +0 -1
- package/dist/elements/chunks/textarea-DPfuhswM.js +0 -1
- package/dist/elements/chunks/toast-store-VUZZBhzH.js +0 -1
- package/dist/elements/chunks/tsx-B8rCNbgL.js +0 -1
- package/dist/elements/chunks/typescript-RycA9KXf.js +0 -1
- package/dist/elements/chunks/use-card-resolution-DJg32jGH.js +0 -1
- package/dist/elements/chunks/variant-custom-D5ZlmziF.js +0 -1
- package/dist/elements/chunks/video-Bb86fVYI.js +0 -1
- package/dist/elements/chunks/vue-BmIZj4XD.js +0 -1
- package/dist/elements/chunks/x-BOhjBeOd.js +0 -1
- package/dist/llms/llms-full.txt +0 -2834
- package/dist/llms/llms.txt +0 -156
- package/dist/primitives/card-validate-generator.testlib.d.ts +0 -20
- package/dist/register-impl-DGmGzrEM.js +0 -145
- package/dist/ui/stat.d.ts +0 -16
- package/dist/variant-custom-MkTNTycd.js +0 -1
- package/src/primitives/card-validate-generator.testlib.ts +0 -38
- package/src/ui/stat.tsx +0 -41
- /package/dist/{elements/chunks/card-tags-D8lZ-C_U.js → card-tags-D8lZ-C_U.js} +0 -0
- /package/dist/{elements/chunks/link-preview-DNILK391.js → link-preview-DNILK391.js} +0 -0
|
@@ -0,0 +1,676 @@
|
|
|
1
|
+
# The composition catalog
|
|
2
|
+
|
|
3
|
+
A machine-readable description of what can be composed from this kit: the parts,
|
|
4
|
+
what each one requires, and the invariants that must hold. It exists so a coding
|
|
5
|
+
agent building `kai-*` into someone else's app has the **contracts** — which
|
|
6
|
+
event carries which detail, which prop must be a JS property, what breaks if you
|
|
7
|
+
set the same array back — and not just a prop list it can already read off
|
|
8
|
+
`element-meta.json`.
|
|
9
|
+
|
|
10
|
+
The measurement is the point. An acceptance deck of seven scenarios hands an
|
|
11
|
+
agent the catalog and **no kit source**; whatever it cannot build names what the
|
|
12
|
+
catalog is missing. The evaluator attributes every failure to the catalog record
|
|
13
|
+
that should have prevented it and ranks the fixes. That ranked list, not the
|
|
14
|
+
score, is the output.
|
|
15
|
+
|
|
16
|
+
Every command below was run from the repo root and its output pasted verbatim.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Generated vs authored
|
|
21
|
+
|
|
22
|
+
Half the confusion here is which files you may edit. `derived.json` is read out
|
|
23
|
+
of the tree by a generator; everything else is written by hand.
|
|
24
|
+
|
|
25
|
+
### `src/agent-tooling/catalog/`
|
|
26
|
+
|
|
27
|
+
| file | what it is | who writes it | edit by hand? |
|
|
28
|
+
| --- | --- | --- | --- |
|
|
29
|
+
| `derived.json` | Every element's props/events/methods/parts, the `MessagePart` variants, integrations, capability groups, theme tokens, event exceptions | `scripts/gen-catalog.mjs`, via `build:api` | **Never.** Change the source it reads (`src/elements/element-meta.json`, `src/elements/chat-types.ts`, `src/agent-tooling/registry.ts`, `archetypes.ts`, `theme.css`) and regenerate |
|
|
30
|
+
| `catalog-types.ts` | The Zod schemas every authored record is parsed against | you | yes |
|
|
31
|
+
| `invariants.ts` | The rules that break real consumers, each with a statement, `diagnosis` symptom/cause pairs, wrong/right code examples, and an honest `enforcedBy` | you | yes |
|
|
32
|
+
| `surfaces.ts` | `inventory` (what is a surface vs an ingredient vs corpus), `surfaceRecipes` (proven compositions with their host wiring written out), `partConsumption` | you | yes |
|
|
33
|
+
| `scenarios.ts` | The seven acceptance scenarios: prompt, what it needs, scoring lines | you | yes |
|
|
34
|
+
| `fabrications.ts` | Tags agents invented that do not exist. Empty until a run fills it | you, from a run's report | yes |
|
|
35
|
+
| `labs-titles.ts` | TypeScript parser that reads the `title` off a story's default-exported meta. Used by the drift lint to resolve inventory rows | you | rarely |
|
|
36
|
+
| `*.test.ts` | The tests that pin all of the above | you | yes |
|
|
37
|
+
|
|
38
|
+
### Scripts
|
|
39
|
+
|
|
40
|
+
| script | what it does |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `scripts/gen-catalog.mjs` | Writes `derived.json`. Runs inside `build:api` |
|
|
43
|
+
| `scripts/lint-catalog-drift.mjs` | Required CI. Every authored claim — element tags, events, properties, invariant ids, corpus paths, inventory titles, scenario invariant refs — must resolve against `derived.json` and the tree |
|
|
44
|
+
| `scripts/acceptance-pack.mjs` | Builds one scenario's pack: `agent/` and `judge/` |
|
|
45
|
+
| `scripts/acceptance-run.mjs` | Records what is about to be measured, and isolates the handover. Invokes no model |
|
|
46
|
+
| `scripts/acceptance-eval.mjs` | Scores a run and produces the catalog-improvement analysis |
|
|
47
|
+
| `scripts/acceptance-gate-compiles.mjs` | The `compiles` gate. Runs `tsc --strict` over the output under the real consumer projects and writes `gates.json` |
|
|
48
|
+
|
|
49
|
+
`scripts/lib/` holds the pieces those four share: `rubric.mjs` (weighted
|
|
50
|
+
dimensions, 0–10 anchors, the severity ladder), `catalog-attribution.mjs` (the
|
|
51
|
+
improvement analysis), `invariant-floor.mjs` (executes every `examples[].right`),
|
|
52
|
+
`audit-needles.mjs` (the self-audit search strings and their recall tier),
|
|
53
|
+
`output-scan.mjs` (the two gates the evaluator runs itself), `run-routing.mjs`
|
|
54
|
+
(which model may take which execution path), `handover.mjs` (the judge-leak
|
|
55
|
+
scan), `import-catalog.mjs` (esbuild-bundles the authored TS for plain Node),
|
|
56
|
+
`consumer-tsc-projects.mjs` (the throwaway consumer tree and the six tsc
|
|
57
|
+
projects — shared with `verify:scaffold`, never copied), `compile-plan.mjs`
|
|
58
|
+
(which scanned units tsc can actually check, and what the rest are reported as).
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## It already runs without you
|
|
63
|
+
|
|
64
|
+
Three things fire on their own. You do not have to do anything for these.
|
|
65
|
+
|
|
66
|
+
**`build:api` regenerates `derived.json`.** `gen-catalog.mjs` is chained onto the
|
|
67
|
+
end of it, so a normal build keeps the derived layer current:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
"build:api": "node scripts/gen-elements-manifest.mjs && node scripts/gen-element-api.mjs && node scripts/gen-catalog.mjs"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**`verify:generated` fails CI if a checked-in generated artifact is stale.**
|
|
74
|
+
`derived.json` is one of the nine it re-derives and diffs, and it seeds each with
|
|
75
|
+
a single-use sentinel first so a dead generator cannot pass as "in sync":
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
$ pnpm --filter @kitn.ai/ui run verify:generated
|
|
79
|
+
verify-generated-sync: regenerating 9 artifacts via `npm run build:api`
|
|
80
|
+
|
|
81
|
+
· model parsed: 80 kai-* elements
|
|
82
|
+
|
|
83
|
+
✓ packages/ui/src/elements/element-meta.json
|
|
84
|
+
...
|
|
85
|
+
✓ packages/ui/src/agent-tooling/catalog/derived.json
|
|
86
|
+
✓ docs/web-components.md
|
|
87
|
+
|
|
88
|
+
✓ verify-generated-sync: all 9 generated artifacts match their source (each one proven rewritten this run).
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**`lint:catalog-drift` fails CI if an authored claim stopped resolving.** Needs
|
|
92
|
+
no build, about a second:
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
$ pnpm --filter @kitn.ai/ui run lint:catalog-drift
|
|
96
|
+
...
|
|
97
|
+
lint-catalog-drift --self-test: all 71 cases behaved.
|
|
98
|
+
⚠ coverage gap: invariant props-not-attributes: enforced by nothing.
|
|
99
|
+
⚠ coverage gap: invariant host-coordinates: enforced by nothing.
|
|
100
|
+
⚠ coverage gap: invariant untrusted-model-output: PARTIAL — ... covers part of it; the statement says which half is uncovered.
|
|
101
|
+
⚠ coverage gap: invariant kit-parses-consumer-fetches: PARTIAL — lint:silent-drops covers part of it; the statement says which half is uncovered.
|
|
102
|
+
⚠ coverage gap: invariant upgrade-race: enforced by nothing (until issue #99 option B lands in defineWebComponent).
|
|
103
|
+
lint-catalog-drift: 2 recipes, 7 invariants, 26 inventory rows resolved clean (5 reported gaps).
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The `⚠ coverage gap` lines are reports, not failures — an invariant that nothing
|
|
107
|
+
in the repo enforces is a fact the catalog states out loud rather than hides.
|
|
108
|
+
|
|
109
|
+
The MCP consumes the catalog too. `component_reference` for a tag now serves the
|
|
110
|
+
invariants that apply to it and the recipes it appears in, with the enforcement
|
|
111
|
+
line attached:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
### Invariants
|
|
115
|
+
Rules that have already broken real consumers of this kit. Each block says what
|
|
116
|
+
enforces it — read that line rather than assuming CI catches a violation, because
|
|
117
|
+
nothing here reads YOUR code. 3 of the 7 below are enforced by NOTHING at all,
|
|
118
|
+
and 2 more by only half of what they say.
|
|
119
|
+
|
|
120
|
+
#### reactivity-two-halves (only kai-chat, kai-conversations) — enforced by the kit's own tests (packages/ui/src/components/reactivity-contract.test.tsx)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Running it against a model
|
|
126
|
+
|
|
127
|
+
**Nothing here calls a model.** There is no API key, no socket and no network in
|
|
128
|
+
any of these scripts. The model invocation is a seam you cross by hand (or with a
|
|
129
|
+
transport module you supply). Everything on either side of the seam is offline
|
|
130
|
+
and tested; only the part that costs money needs you.
|
|
131
|
+
|
|
132
|
+
### 1. See the deck
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
$ pnpm --filter @kitn.ai/ui exec node scripts/acceptance-pack.mjs --list
|
|
136
|
+
S1 surface recipe applied to an existing tree
|
|
137
|
+
S2 greenfield, contract
|
|
138
|
+
S3 capability
|
|
139
|
+
S4 whole surface; expected to fail hardest first
|
|
140
|
+
S5 platform embed
|
|
141
|
+
S6 refusal
|
|
142
|
+
S7 debugging
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The prompts and scoring lines are in `scenarios.ts`. S6 is the strongest signal
|
|
146
|
+
in the deck: a model with no catalog cannot refuse honestly, because it does not
|
|
147
|
+
know what does not exist.
|
|
148
|
+
|
|
149
|
+
### 2. Pack a scenario
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
$ pnpm --filter @kitn.ai/ui exec node scripts/acceptance-pack.mjs \
|
|
153
|
+
--scenario S6 --out /tmp/pack-S6
|
|
154
|
+
acceptance-pack: packed S6 into /tmp/pack-S6 (agent/: 80 element pages + 13 guides; judge/: 2 reports + catalog.json)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`--out` must be new or empty; the packer refuses to merge into a directory it
|
|
158
|
+
does not own. Use absolute paths — `pnpm exec` runs from `packages/ui`, so a
|
|
159
|
+
relative path lands there.
|
|
160
|
+
|
|
161
|
+
Before it writes anything the packer runs the **floor stage**: every
|
|
162
|
+
`examples[].right` in `invariants.ts` is executed. You can run it alone:
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
$ pnpm --filter @kitn.ai/ui exec node scripts/acceptance-pack.mjs --floor
|
|
166
|
+
PASS reactivity-two-halves#0 [stand-ins: `chat` is a plain object, not a registered element]
|
|
167
|
+
· appending a turn produces a NEW array reference
|
|
168
|
+
...
|
|
169
|
+
✓ acceptance-pack: floor clean — 15 examples executed.
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
A pack built on advice that does not run measures the wrong thing, so a red floor
|
|
173
|
+
means no pack.
|
|
174
|
+
|
|
175
|
+
### 3. Prepare the run
|
|
176
|
+
|
|
177
|
+
`acceptance-pack` gives you a pack. `acceptance-run` gives you a **ledger** — a
|
|
178
|
+
timestamped record of what is about to be measured — plus a handover directory
|
|
179
|
+
holding `agent/` and nothing else.
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
$ pnpm --filter @kitn.ai/ui exec node scripts/acceptance-run.mjs \
|
|
183
|
+
--scenario S6 --model claude-opus-5 --tier frontier --runs-dir /tmp/runs
|
|
184
|
+
acceptance-run: no --path was given; "claude-opus-5" admits exactly one (claude-code, rule anthropic-via-subscription). Recorded as inferred.
|
|
185
|
+
acceptance-pack: packed S6 into /tmp/runs/20260818-110728-S6-claude-opus-5/pack (agent/: 80 element pages + 13 guides; judge/: 2 reports + catalog.json)
|
|
186
|
+
acceptance-run: prepared 20260818-110728-S6-claude-opus-5
|
|
187
|
+
scenario S6
|
|
188
|
+
model claude-opus-5 (tier frontier)
|
|
189
|
+
path claude-code [inferred, anthropic-via-subscription]
|
|
190
|
+
kit version 0.25.2
|
|
191
|
+
HAND THIS TO THE AGENT, and nothing else:
|
|
192
|
+
/var/folders/.../T/kai-handover-20260818-110728-S6-claude-opus-5-AVqU8s (93 files, sha256:894f68b5638d…)
|
|
193
|
+
collect its output into:
|
|
194
|
+
/tmp/runs/20260818-110728-S6-claude-opus-5/output
|
|
195
|
+
then: node scripts/acceptance-eval.mjs --run /tmp/runs/20260818-110728-S6-claude-opus-5
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Flags: `--scenario` `--model` `--tier` `--runs-dir` are required; `--path`
|
|
199
|
+
`--effort` `--handover` `--note` `--exec` are optional. Every one of them is
|
|
200
|
+
recorded in the ledger and compared across runs, so a flag given no value is
|
|
201
|
+
refused rather than guessed.
|
|
202
|
+
|
|
203
|
+
The handover defaults to the OS temp directory. Pass `--handover <dir>` to put it
|
|
204
|
+
somewhere durable — on this machine the temp copies vanished between commands.
|
|
205
|
+
`--prune-handovers <runs-dir>` deletes every handover no ledger still references.
|
|
206
|
+
|
|
207
|
+
The ledger (`run-info.json`) records the third thing everyone forgets — **which
|
|
208
|
+
execution path ran** — alongside the scenario and the model:
|
|
209
|
+
|
|
210
|
+
```json
|
|
211
|
+
{
|
|
212
|
+
"runId": "20260818-110728-S6-claude-opus-5",
|
|
213
|
+
"scenarioId": "S6",
|
|
214
|
+
"model": "claude-opus-5",
|
|
215
|
+
"modelCanonical": "claude-opus-5",
|
|
216
|
+
"tier": "frontier",
|
|
217
|
+
"executionPath": "claude-code",
|
|
218
|
+
"pathSource": "inferred",
|
|
219
|
+
"routingRule": "anthropic-via-subscription",
|
|
220
|
+
"kitVersion": "0.25.2",
|
|
221
|
+
"handoverFiles": 93,
|
|
222
|
+
"handoverDigest": "sha256:894f68b5638d811b809c1a1606f2a917088c120f74af1d11a78dcd2eadf509a1",
|
|
223
|
+
"status": "prepared",
|
|
224
|
+
"transport": null
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Without the path, a later cost or quality comparison is guesswork: the same model
|
|
229
|
+
identifier can mean a subscription seat or a metered invoice.
|
|
230
|
+
|
|
231
|
+
### 4. Cross the seam
|
|
232
|
+
|
|
233
|
+
The handover directory is a flat set of markdown files:
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
$ ls /var/folders/.../T/kai-handover-20260818-111237-S7-claude-opus-5-V3vZSo
|
|
237
|
+
DELIVERY.md FABRICATED.md INVARIANTS.md PARTS.md README.md SELF-AUDIT.md THEME.md
|
|
238
|
+
ELEMENTS.md INTEGRATIONS.md INVENTORY.md PROMPT.md RECIPES.md SHARED-PROPS.md elements
|
|
239
|
+
$ ls .../judge
|
|
240
|
+
ls: .../judge: No such file or directory
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Anthropic models — your Claude Code subscription.** Start a session with the
|
|
244
|
+
handover directory as its working directory, give it the contents of `PROMPT.md`,
|
|
245
|
+
and tell it that directory is all the documentation there is. Save whatever it
|
|
246
|
+
produces into the run's `output/`. Do not let it read your repo: the whole
|
|
247
|
+
measurement is "what can it build from the catalog alone".
|
|
248
|
+
|
|
249
|
+
**OpenRouter — the models you name.** Same shape, different transport: POST the
|
|
250
|
+
handover's markdown plus `PROMPT.md` to OpenRouter with your own key, write the
|
|
251
|
+
reply into `output/`. Only `~deepseek/deepseek-v4-flash-latest` is allowed today;
|
|
252
|
+
the list lives in `OPENROUTER_ALLOWED` in `scripts/lib/run-routing.mjs`.
|
|
253
|
+
|
|
254
|
+
**The router refuses, it never reroutes.** The two paths bill to different
|
|
255
|
+
places, and quietly moving a run would also make the `executionPath` in the
|
|
256
|
+
ledger untrue:
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
$ ... --model claude-opus-5 --path openrouter
|
|
260
|
+
✗ acceptance-run: routing refused [anthropic-never-openrouter]: "claude-opus-5" is an Anthropic model and the openrouter path was selected. ... This is REFUSED rather than rerouted: the two paths bill to different places, and quietly moving the run would also make the executionPath recorded in the ledger untrue.
|
|
261
|
+
|
|
262
|
+
$ ... --model '~deepseek/deepseek-v4-flash-latest' --path claude-code
|
|
263
|
+
✗ acceptance-run: routing refused [non-anthropic-never-claude-code]: "~deepseek/deepseek-v4-flash-latest" is not an Anthropic model, so it cannot run through the Claude Code subscription. Re-run with --path openrouter.
|
|
264
|
+
|
|
265
|
+
$ ... --model meta/llama-4
|
|
266
|
+
✗ acceptance-run: routing refused [no-path-for-model]: "meta/llama-4" is neither an Anthropic model nor one of the owner-named OpenRouter models (~deepseek/deepseek-v4-flash-latest), so there is no path it may take. Neither "charge the card" nor "use the subscription" is this script's decision to make.
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**Automating the seam.** `--exec <module>` imports a module you write and calls
|
|
270
|
+
its `runAgent(request)`:
|
|
271
|
+
|
|
272
|
+
```js
|
|
273
|
+
export async function runAgent(request) {
|
|
274
|
+
// request = { runId, scenarioId, model, executionPath, effort, handoverDir, outputDir }
|
|
275
|
+
return {
|
|
276
|
+
files: [{ name: 'ANSWER.md', text }], // written into outputDir
|
|
277
|
+
transcript, // written as output/TRANSCRIPT.md
|
|
278
|
+
meta, // recorded in run-info.transport
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
`request` carries no pack directory and no run directory, so a transport cannot
|
|
284
|
+
hand an agent the answer key by accident — it is never told where the answer key
|
|
285
|
+
is. CI never passes `--exec`.
|
|
286
|
+
|
|
287
|
+
### 5. Run the external gates
|
|
288
|
+
|
|
289
|
+
`compiles` is implemented; `registers` and `streams` are not (see *What is not
|
|
290
|
+
built*). It compiles the run's output under the same tsc projects
|
|
291
|
+
`verify:scaffold` uses — the real `@kitn.ai/ui` exports map, `--strict`,
|
|
292
|
+
`noUnusedLocals` — and writes its verdict into the run's `gates.json`. It needs
|
|
293
|
+
a built tree, and it will not guess which framework was asked for:
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
$ pnpm --filter @kitn.ai/ui exec node scripts/acceptance-gate-compiles.mjs \
|
|
297
|
+
--run /tmp/runs/20260818-181634-S1-claude-opus-5 --framework react
|
|
298
|
+
acceptance-gate-compiles: 20260818-181634-S1-claude-opus-5 — S1, framework react → default project
|
|
299
|
+
✓ self-test [default]: types resolve for real (TS2322) and noUnusedLocals is live (TS6133)
|
|
300
|
+
✓ 1 unit(s) compile clean under the default project (framework react)
|
|
301
|
+
acceptance-gate-compiles: wrote compiles = PASSED into .../gates.json
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
A failure names the file and the diagnostic, with the harness's own path prefix
|
|
305
|
+
stripped off:
|
|
306
|
+
|
|
307
|
+
```
|
|
308
|
+
✗ 1 error(s) under the default project (framework react):
|
|
309
|
+
src/main.ts(30,26): error TS2345: Argument of type 'ReadableStream<Uint8Array<ArrayBuffer>> | null' is not assignable to parameter of type 'StreamSource'.
|
|
310
|
+
acceptance-gate-compiles: wrote compiles = FAILED into .../gates.json
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**And an answer with no code in it FAILS**, with the reason recorded — this gate
|
|
314
|
+
only applies to scenarios that asked for code, so an answer without any did not
|
|
315
|
+
do the thing:
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
acceptance-gate-compiles: wrote compiles = FAILED into .../gates.json
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
It refuses a scenario the dimension does not apply to, rather than compiling
|
|
322
|
+
something whose result the evaluator would then throw away:
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
✗ acceptance-gate-compiles: "compiles" does not apply to S6 — no scoring line in that scenario claims it, so acceptance-eval would refuse a gates file that answered it. Scenarios that need it: S1, S2, S4.
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
`--self-test` plants a fault per outcome and watches each one fire, including
|
|
329
|
+
the ones only `--strict` produces and a sandbox whose tsconfig has been gutted:
|
|
330
|
+
|
|
331
|
+
```
|
|
332
|
+
$ pnpm --filter @kitn.ai/ui run gate:compiles:self-test
|
|
333
|
+
...
|
|
334
|
+
✓ OUTCOME 2 — an implicit `any` (TS7006) — the error ONLY --strict produces
|
|
335
|
+
✓ OUTCOME 2 — a possibly-null value used without a check (TS18047/TS2531) — strictNullChecks is live
|
|
336
|
+
✓ OUTCOME 2 — an unused import (TS6133) — noUnusedLocals is live, which is what fails a stock `npm run build`
|
|
337
|
+
✓ OUTCOME 2 — a WRONG-TYPE use of the kit (TS2322) — @kitn.ai/ui did not resolve to `any`
|
|
338
|
+
✓ OUTCOME 2 — a broken fence inside a markdown answer — a prose-shaped answer is measured too
|
|
339
|
+
✓ the sandbox control PASSES on the real tsconfig (positive control)
|
|
340
|
+
✓ a sandbox whose tsconfig lost its strict flags is DETECTED, so a green cannot come from a dead harness
|
|
341
|
+
✓ acceptance-gate-compiles: 16 controls, every planted fault detected.
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### 6. Score it
|
|
345
|
+
|
|
346
|
+
Generate the findings template, fill it, then evaluate:
|
|
347
|
+
|
|
348
|
+
```
|
|
349
|
+
$ pnpm --filter @kitn.ai/ui exec node scripts/acceptance-eval.mjs --template /tmp/runs/20260818-111308-S1-claude-opus-5
|
|
350
|
+
acceptance-eval: wrote .../findings.template.json — fill judgedScores and findings, then --run ...
|
|
351
|
+
external gates still needed: compiles, registers (supply via --gates; absent is an ERROR, never "skipped" and never a pass)
|
|
352
|
+
· compiles: node scripts/acceptance-gate-compiles.mjs --run /tmp/runs/20260818-111308-S1-claude-opus-5 --framework <react|vue|…>
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
The template carries the full rubric, the severity ladder and the attribution
|
|
356
|
+
kinds inline, so you are not guessing at the vocabulary. Rename it to
|
|
357
|
+
`findings.json` (the default `--findings` path) and fill `judgedScores` plus a
|
|
358
|
+
`findings` array. Then:
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
$ pnpm --filter @kitn.ai/ui exec node scripts/acceptance-eval.mjs --run /tmp/runs/20260818-110728-S6-claude-opus-5
|
|
362
|
+
acceptance-eval: S6 gated-fail — 2.84/10 via claude-code. 2 catalog change(s) proposed. Wrote .../REPORT.md.
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Flags: `--run <dir>` `[--findings f] [--gates g]`, `--template <dir> [--out f]`,
|
|
366
|
+
`--compare --strong <dir> --weak <dir>`, `--self-test`.
|
|
367
|
+
|
|
368
|
+
The evaluator refuses more than it accepts, and every refusal is a real one you
|
|
369
|
+
will hit:
|
|
370
|
+
|
|
371
|
+
```
|
|
372
|
+
✗ acceptance-eval: no findings file at .../findings.json. Generate one with --template ...; a run with no judgement is not an evaluation.
|
|
373
|
+
|
|
374
|
+
✗ acceptance-eval: findings could not be attributed to the catalog, so no improvement analysis was produced:
|
|
375
|
+
- finding "F1": fabricated-element with no `useInstead` must carry `noReplacementReason` — "there is no replacement" is a real and useful answer, but it has to be said rather than left blank.
|
|
376
|
+
|
|
377
|
+
✗ acceptance-eval: ... is a gated-fail (registers) with ZERO findings recorded. That is not an evaluation: the premise of the deck is that whatever the agent could not build names what the catalog is missing, so a failing run must say what went wrong and what would have prevented it.
|
|
378
|
+
|
|
379
|
+
- mechanical dimension "compiles" has no gate result. That is an ERROR, not a skip and not a pass: an unrun gate and a clean gate produce the same silence, and only one of them means anything.
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## What the pack contains
|
|
385
|
+
|
|
386
|
+
```
|
|
387
|
+
$ find /tmp/pack-S6 -maxdepth 2 -not -path '*/agent/elements/*' | sort
|
|
388
|
+
./PACK.md
|
|
389
|
+
./agent
|
|
390
|
+
./agent/DELIVERY.md
|
|
391
|
+
./agent/ELEMENTS.md
|
|
392
|
+
./agent/FABRICATED.md
|
|
393
|
+
./agent/INTEGRATIONS.md
|
|
394
|
+
./agent/INVARIANTS.md
|
|
395
|
+
./agent/INVENTORY.md
|
|
396
|
+
./agent/PARTS.md
|
|
397
|
+
./agent/PROMPT.md
|
|
398
|
+
./agent/README.md
|
|
399
|
+
./agent/RECIPES.md
|
|
400
|
+
./agent/SELF-AUDIT.md
|
|
401
|
+
./agent/SHARED-PROPS.md
|
|
402
|
+
./agent/THEME.md
|
|
403
|
+
./agent/elements
|
|
404
|
+
./judge
|
|
405
|
+
./judge/FLOOR.md
|
|
406
|
+
./judge/JUDGE.md
|
|
407
|
+
./judge/catalog.json
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
`agent/` is the whole catalog and no kit source: the task, how to install and
|
|
411
|
+
register, an exhaustive element index with one page per tag, the shared props,
|
|
412
|
+
the invariants with wrong/right pairs, the recipes with host wiring, and a
|
|
413
|
+
self-audit the agent runs over its own output before delivering.
|
|
414
|
+
|
|
415
|
+
`judge/` is the answer key. `JUDGE.md` carries the scoring checklist, the
|
|
416
|
+
`enforcedBy` table for triage, and the recipe corpus paths — repo paths pointing
|
|
417
|
+
at files the agent is deliberately not given. Handing any of it to the agent
|
|
418
|
+
invalidates the run, which is why `acceptance-run` copies `agent/` alone into an
|
|
419
|
+
isolated handover and verifies afterwards that no judge material leaked in.
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## Reading a result
|
|
424
|
+
|
|
425
|
+
`REPORT.md`, from a real S6 run where the agent invented `<kai-datagrid>`:
|
|
426
|
+
|
|
427
|
+
```md
|
|
428
|
+
## Verdict: gated-fail — 2.84 / 10
|
|
429
|
+
|
|
430
|
+
**Gated failure.** elements-exist did not pass. A gated failure outranks the
|
|
431
|
+
score: "it scored 2.84" and "it does not compile" are different facts.
|
|
432
|
+
|
|
433
|
+
| dimension | gate | weight | score | source | detail |
|
|
434
|
+
| --- | --- | --- | --- | --- | --- |
|
|
435
|
+
| elements-exist | mechanical | 3 | 0.0 | gate | 1 fabricated tag(s) in 2 place(s): kai-datagrid |
|
|
436
|
+
| audit-clean | mechanical | 3 | 10.0 | gate | no wrong-form needle fired across 15 needles — a floor, not a proof |
|
|
437
|
+
| contract-correctness | judged | 3 | 2.0 | judged | |
|
|
438
|
+
| invariant-compliance | judged | 3 | 3.0 | judged | |
|
|
439
|
+
| honesty-bound | judged | 4 | 0.0 | judged | |
|
|
440
|
+
| completeness | judged | 3 | 3.0 | judged | |
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**The weighted score** is a renormalised 0–10 over the dimensions that applied.
|
|
444
|
+
It is for comparing two runs, not for reporting a verdict.
|
|
445
|
+
|
|
446
|
+
**Gates fail closed.** A gate that did not run scores 0 — never "skipped" —
|
|
447
|
+
because an unrun gate and a clean gate produce the same silence and only one of
|
|
448
|
+
them means anything. `elements-exist` and `audit-clean` the evaluator computes
|
|
449
|
+
itself from the output text and the catalog; supplying either through `--gates`
|
|
450
|
+
is refused. `compiles`, `registers` and `streams` need real tooling and come in
|
|
451
|
+
through `--gates`. There is no exception: an output with no code in it is a
|
|
452
|
+
FAILED `compiles`, not an absent one — see below.
|
|
453
|
+
|
|
454
|
+
**Severity caps the dimension.** From an S1 run: a `does-not-render` finding
|
|
455
|
+
filed against `completeness` produced `0.0 (capped from 7.0)`. The ladder is
|
|
456
|
+
`does-not-render` (cap 0) · `does-not-function` (3) · `does-not-wire` (5) ·
|
|
457
|
+
`cosmetic-or-practice` (8, never blocking).
|
|
458
|
+
|
|
459
|
+
**Not-applicable belongs to the evaluator's OWN gates, and to no other.** A
|
|
460
|
+
prose answer — a refusal, a diagnosis — gives `elements-exist` and `audit-clean`
|
|
461
|
+
nothing to read, and those two leave the score entirely rather than scoring 0.
|
|
462
|
+
They are the gates the evaluator runs itself, over the output it holds.
|
|
463
|
+
|
|
464
|
+
**An external gate never leaves the score.** That was tried and removed. The
|
|
465
|
+
evaluator ran the same `codeUnits()` scan for the external dimensions too and,
|
|
466
|
+
finding nothing, marked them not-applicable with an `adjudicated: 'evaluator'`
|
|
467
|
+
stamp. The scan cannot support that verdict: it reads recognised code files and
|
|
468
|
+
LABELLED fences, so an unlabelled fence — how models most often emit code — is
|
|
469
|
+
indistinguishable from prose, and "no code my scanner recognises" was being read
|
|
470
|
+
as "no code". Measured: an S1 run producing **zero output files** scored 8.93/10
|
|
471
|
+
and exit 0 where it had previously hard-failed, and a mixed answer that
|
|
472
|
+
fabricated `<kai-datagrid>` and failed typecheck scored every mechanical gate
|
|
473
|
+
10/10.
|
|
474
|
+
|
|
475
|
+
Deleting it cost nothing, because the benefit was unreachable. The
|
|
476
|
+
prose-by-design case it was argued for is S6's refusal and S7's diagnosis, and
|
|
477
|
+
neither scenario carries an external mechanical dimension at all —
|
|
478
|
+
`compiles`/`registers`/`streams` exist only on S1/S2/S4/S5, where an answer with
|
|
479
|
+
no code is a failure and not an absence. So:
|
|
480
|
+
|
|
481
|
+
- a self-declared `vacuous: true` from a runner is refused, as it always was;
|
|
482
|
+
- so is one that claims the evaluator adjudicated it;
|
|
483
|
+
- an external gate with no result at all is an ERROR, never a skip and never a
|
|
484
|
+
pass;
|
|
485
|
+
- `compiles` reports `passed: false` when it finds nothing to compile.
|
|
486
|
+
|
|
487
|
+
`tests/scripts/acceptance-gate-compiles.test.ts` pins each of those.
|
|
488
|
+
|
|
489
|
+
**The tier delta** is the point of running two models. `--compare` puts them side
|
|
490
|
+
by side, and warns when the denominators differ:
|
|
491
|
+
|
|
492
|
+
```
|
|
493
|
+
$ ... --compare --strong <dir> --weak <dir>
|
|
494
|
+
> **⚠ Different denominators.** The strong run was scored over 19 weight and the
|
|
495
|
+
> weak run over 13 ... They are not directly comparable; read the per-dimension
|
|
496
|
+
> rows instead of the headline.
|
|
497
|
+
|
|
498
|
+
**The headline is not "did it pass".** It is how far down the model tier the
|
|
499
|
+
catalog keeps working. Anything the strong model gets right and the weak one gets
|
|
500
|
+
wrong names a contract the catalog leaves IMPLICIT and is currently relying on
|
|
501
|
+
the model to supply from its own priors.
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
**The catalog-improvement analysis is the actual output.** Every finding is
|
|
505
|
+
attributed to the record that should have prevented it, and the changes are
|
|
506
|
+
ranked by how many findings each would close:
|
|
507
|
+
|
|
508
|
+
```md
|
|
509
|
+
| # | change | kind | closes | severity weight | tier-revealed |
|
|
510
|
+
| --- | --- | --- | --- | --- | --- |
|
|
511
|
+
| 1 | `fabricated:kai-datagrid` | fabricated-element | 1 | 16 | |
|
|
512
|
+
| 2 | `invariant:strengthen:props-not-attributes` | invariant-ineffective | 1 | 9 | |
|
|
513
|
+
|
|
514
|
+
Addressable share: 1 — all 2 finding(s) name a catalog change.
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
Attribution kinds: `missing-invariant` · `invariant-ineffective` ·
|
|
518
|
+
`missing-recipe` · `recipe-ineffective` · `underived-contract` ·
|
|
519
|
+
`missing-element-description` · `fabricated-element` · `pack-defect` ·
|
|
520
|
+
`not-a-catalog-gap`. The last is the escape hatch and it costs something: it must
|
|
521
|
+
quote the page and the line that said it plainly, because an uncosted escape
|
|
522
|
+
hatch swallows the analysis.
|
|
523
|
+
|
|
524
|
+
Fabrications are proposed, never written:
|
|
525
|
+
|
|
526
|
+
```md
|
|
527
|
+
## Proposed FABRICATED.md rows
|
|
528
|
+
|
|
529
|
+
Paste into `src/agent-tooling/catalog/fabrications.ts` after checking each tag.
|
|
530
|
+
**Not written automatically:** a mis-scored run editing the catalog would teach
|
|
531
|
+
every later agent that a real element is imaginary.
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
536
|
+
## Making improvements
|
|
537
|
+
|
|
538
|
+
The loop: **run → read the improvement list → edit the authored records → the
|
|
539
|
+
lints keep you honest → re-run.** Only `derived.json` is off limits.
|
|
540
|
+
|
|
541
|
+
### Worked example: adding an invariant
|
|
542
|
+
|
|
543
|
+
Add a record to `invariants.ts` and nothing complains yet — the drift lint only
|
|
544
|
+
resolves references, and a new id refers to nothing:
|
|
545
|
+
|
|
546
|
+
```
|
|
547
|
+
$ pnpm --filter @kitn.ai/ui exec node scripts/lint-catalog-drift.mjs
|
|
548
|
+
lint-catalog-drift: 2 recipes, 8 invariants, 26 inventory rows resolved clean (6 reported gaps).
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
The packer is where it bites. The floor stage refuses to pack advice it cannot
|
|
552
|
+
execute:
|
|
553
|
+
|
|
554
|
+
```
|
|
555
|
+
$ ... acceptance-pack.mjs --scenario S6 --out /tmp/pack-bad
|
|
556
|
+
ERROR no harness for theme-attribute-scalar#0 (wrong: chat.theme = { mode: 'dark' };). Every examples[].right must be executed; add a harness in scripts/lib/invariant-floor.mjs binding its free variables, or the example stops being measured.
|
|
557
|
+
✗ acceptance-pack: the floor stage failed, so nothing was packed. 1 problem(s) in the catalog's own examples[].right forms — fix those first; a pack built on broken advice measures the wrong thing.
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
Add the harness, and the next gate fires:
|
|
561
|
+
|
|
562
|
+
```
|
|
563
|
+
✗ acceptance-pack: the self-audit needles are unsound, so nothing was packed:
|
|
564
|
+
- no search needle for theme-attribute-scalar#0. Every wrong/right pair needs one, or that mistake is unsearchable.
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
So a new invariant is three edits, in this order:
|
|
568
|
+
|
|
569
|
+
1. the record in `invariants.ts` — statement, `appliesTo`, an honest
|
|
570
|
+
`enforcedBy` (`kind: 'none'` is fine and preferred over a fake pointer),
|
|
571
|
+
`diagnosis` pairs, and wrong/right examples;
|
|
572
|
+
2. a harness in `scripts/lib/invariant-floor.mjs` binding the example's free
|
|
573
|
+
variables, so the `right` form is executed and its behavioural claim asserted;
|
|
574
|
+
3. a needle in `NEEDLE_TABLE` in `scripts/lib/audit-needles.mjs`, with its tier.
|
|
575
|
+
The needle is checked to appear in its own `wrong` form, in **zero** `right`
|
|
576
|
+
forms across all invariants in either quote style, and to hold its claimed
|
|
577
|
+
tier against rename and quote transforms.
|
|
578
|
+
|
|
579
|
+
### Worked example: a recipe or an inventory row
|
|
580
|
+
|
|
581
|
+
Every authored claim is resolved against the tree. Misspell an ingredient:
|
|
582
|
+
|
|
583
|
+
```
|
|
584
|
+
$ pnpm --filter @kitn.ai/ui exec node scripts/lint-catalog-drift.mjs
|
|
585
|
+
✗ lint-catalog-drift: recipe workspace-chat: ingredient kai-datagrid is not a derived element.
|
|
586
|
+
$ echo $?
|
|
587
|
+
1
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
Inventory titles resolve the same way, against real `Labs/` story titles parsed
|
|
591
|
+
out of each story's default-exported meta. What resolution does **not** cover is
|
|
592
|
+
deletion, for most rows: the check runs row → tree, and a deleted row asks
|
|
593
|
+
nothing of the tree. The exceptions are documented at the top of `surfaces.ts`.
|
|
594
|
+
|
|
595
|
+
### Before you push
|
|
596
|
+
|
|
597
|
+
```
|
|
598
|
+
pnpm --filter @kitn.ai/ui run lint:catalog-drift
|
|
599
|
+
pnpm --filter @kitn.ai/ui run verify:generated
|
|
600
|
+
pnpm --filter @kitn.ai/ui exec node scripts/acceptance-pack.mjs --floor
|
|
601
|
+
pnpm --filter @kitn.ai/ui exec vitest run --project=unit src/agent-tooling/catalog tests/scripts
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
And, if you touched the `compiles` gate or the tsc projects it shares with
|
|
605
|
+
`verify:scaffold` (both need a build):
|
|
606
|
+
|
|
607
|
+
```
|
|
608
|
+
pnpm --filter @kitn.ai/ui run gate:compiles:self-test
|
|
609
|
+
pnpm --filter @kitn.ai/ui run verify:scaffold
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
The vitest line above, on this tree:
|
|
613
|
+
|
|
614
|
+
```
|
|
615
|
+
Test Files 32 passed (32)
|
|
616
|
+
Tests 448 passed (448)
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
Each script also takes `--self-test`, which watches every refusal fire rather
|
|
620
|
+
than asserting it works.
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
624
|
+
## What is not built
|
|
625
|
+
|
|
626
|
+
Say this plainly, because the machinery looks more finished than it is.
|
|
627
|
+
|
|
628
|
+
**No acceptance run has ever happened.** Everything above was exercised with
|
|
629
|
+
hand-written stand-in output. No model has been given a pack.
|
|
630
|
+
|
|
631
|
+
**Two of the three external gates are still unimplemented.** `compiles` now runs
|
|
632
|
+
(step 5 above). `registers` and `streams` have weights, anchors and a refusal if
|
|
633
|
+
they are missing — and nothing runs them. Supplying one by hand means writing
|
|
634
|
+
`gates.json` in the run directory:
|
|
635
|
+
|
|
636
|
+
```json
|
|
637
|
+
{
|
|
638
|
+
"registers": { "passed": false, "detail": "kai-artifact never upgraded" },
|
|
639
|
+
"streams": { "passed": true, "detail": "tokens appended; final turn matched the fixture" }
|
|
640
|
+
}
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
You get those verdicts by doing the work yourself: mount the output in a browser
|
|
644
|
+
and check `customElements.get`, drive it with a mock provider-SSE fixture. What
|
|
645
|
+
you may NOT write is `vacuous: true` — a runner that never read the output cannot
|
|
646
|
+
discover that there was nothing in it. And do not leave the gate out: an absent
|
|
647
|
+
external verdict is a hard error, not a skip. If the answer really contains no
|
|
648
|
+
code, that is `passed: false` on a scenario that asked for some.
|
|
649
|
+
|
|
650
|
+
The shape to copy when implementing them is `acceptance-gate-compiles.mjs`, and
|
|
651
|
+
the part worth copying is not the tsc plumbing — it is that the script always
|
|
652
|
+
returns a verdict, and says in `detail` exactly what it did and did not read.
|
|
653
|
+
|
|
654
|
+
**`FABRICATED.md` is empty by construction.** `fabrications.ts` holds no rows,
|
|
655
|
+
and the page in every pack says so in those words. Read the emptiness as "nobody
|
|
656
|
+
has looked yet", not "agents get this right".
|
|
657
|
+
|
|
658
|
+
**There are almost no element descriptions in the tree.** The index's "what it
|
|
659
|
+
is" column is blank for nearly every row:
|
|
660
|
+
|
|
661
|
+
```
|
|
662
|
+
$ grep -c '^- `<kai-' packages/ui/llms.txt
|
|
663
|
+
3
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
Three curated one-liners, and `llms.txt` is the only place they live. This is why
|
|
667
|
+
`missing-element-description` is an attribution kind: an agent choosing between
|
|
668
|
+
two elements has counts and a capability group and nothing else.
|
|
669
|
+
|
|
670
|
+
---
|
|
671
|
+
|
|
672
|
+
## Reference
|
|
673
|
+
|
|
674
|
+
- Design: `docs/superpowers/specs/2026-08-17-composition-catalog-design.md`
|
|
675
|
+
- Brief: `docs/superpowers/specs/2026-08-16-composition-catalog-brief.md`
|
|
676
|
+
- Plan: `docs/superpowers/plans/2026-08-17-composition-catalog.md`
|