@agent-native/core 0.38.0 → 0.39.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/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +8 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/skills.d.ts +5 -4
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +450 -125
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/blocks/BlockView.d.ts +13 -4
- package/dist/client/blocks/BlockView.d.ts.map +1 -1
- package/dist/client/blocks/BlockView.js +34 -13
- package/dist/client/blocks/BlockView.js.map +1 -1
- package/dist/client/blocks/SchemaBlockEditor.d.ts.map +1 -1
- package/dist/client/blocks/SchemaBlockEditor.js +96 -3
- package/dist/client/blocks/SchemaBlockEditor.js.map +1 -1
- package/dist/client/blocks/index.d.ts +18 -1
- package/dist/client/blocks/index.d.ts.map +1 -1
- package/dist/client/blocks/index.js +26 -1
- package/dist/client/blocks/index.js.map +1 -1
- package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts +6 -0
- package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -0
- package/dist/client/blocks/library/AnnotatedCodeBlock.js +135 -0
- package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -0
- package/dist/client/blocks/library/ApiEndpointBlock.d.ts +20 -0
- package/dist/client/blocks/library/ApiEndpointBlock.d.ts.map +1 -0
- package/dist/client/blocks/library/ApiEndpointBlock.js +131 -0
- package/dist/client/blocks/library/ApiEndpointBlock.js.map +1 -0
- package/dist/client/blocks/library/DataModelBlock.d.ts +28 -0
- package/dist/client/blocks/library/DataModelBlock.d.ts.map +1 -0
- package/dist/client/blocks/library/DataModelBlock.js +222 -0
- package/dist/client/blocks/library/DataModelBlock.js.map +1 -0
- package/dist/client/blocks/library/DiffBlock.d.ts +6 -0
- package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -0
- package/dist/client/blocks/library/DiffBlock.js +293 -0
- package/dist/client/blocks/library/DiffBlock.js.map +1 -0
- package/dist/client/blocks/library/FileTreeBlock.d.ts +23 -0
- package/dist/client/blocks/library/FileTreeBlock.d.ts.map +1 -0
- package/dist/client/blocks/library/FileTreeBlock.js +225 -0
- package/dist/client/blocks/library/FileTreeBlock.js.map +1 -0
- package/dist/client/blocks/library/JsonExplorerBlock.d.ts +19 -0
- package/dist/client/blocks/library/JsonExplorerBlock.d.ts.map +1 -0
- package/dist/client/blocks/library/JsonExplorerBlock.js +171 -0
- package/dist/client/blocks/library/JsonExplorerBlock.js.map +1 -0
- package/dist/client/blocks/library/MermaidBlock.d.ts +17 -0
- package/dist/client/blocks/library/MermaidBlock.d.ts.map +1 -0
- package/dist/client/blocks/library/MermaidBlock.js +131 -0
- package/dist/client/blocks/library/MermaidBlock.js.map +1 -0
- package/dist/client/blocks/library/OpenApiSpecBlock.d.ts +19 -0
- package/dist/client/blocks/library/OpenApiSpecBlock.d.ts.map +1 -0
- package/dist/client/blocks/library/OpenApiSpecBlock.js +494 -0
- package/dist/client/blocks/library/OpenApiSpecBlock.js.map +1 -0
- package/dist/client/blocks/library/annotated-code.config.d.ts +58 -0
- package/dist/client/blocks/library/annotated-code.config.d.ts.map +1 -0
- package/dist/client/blocks/library/annotated-code.config.js +53 -0
- package/dist/client/blocks/library/annotated-code.config.js.map +1 -0
- package/dist/client/blocks/library/api-endpoint.config.d.ts +71 -0
- package/dist/client/blocks/library/api-endpoint.config.d.ts.map +1 -0
- package/dist/client/blocks/library/api-endpoint.config.js +91 -0
- package/dist/client/blocks/library/api-endpoint.config.js.map +1 -0
- package/dist/client/blocks/library/checklist.d.ts.map +1 -1
- package/dist/client/blocks/library/checklist.js +3 -1
- package/dist/client/blocks/library/checklist.js.map +1 -1
- package/dist/client/blocks/library/code-tabs.js +1 -1
- package/dist/client/blocks/library/code-tabs.js.map +1 -1
- package/dist/client/blocks/library/data-model.config.d.ts +72 -0
- package/dist/client/blocks/library/data-model.config.d.ts.map +1 -0
- package/dist/client/blocks/library/data-model.config.js +59 -0
- package/dist/client/blocks/library/data-model.config.js.map +1 -0
- package/dist/client/blocks/library/dev-doc-ui.d.ts +49 -0
- package/dist/client/blocks/library/dev-doc-ui.d.ts.map +1 -0
- package/dist/client/blocks/library/dev-doc-ui.js +50 -0
- package/dist/client/blocks/library/dev-doc-ui.js.map +1 -0
- package/dist/client/blocks/library/diff.config.d.ts +41 -0
- package/dist/client/blocks/library/diff.config.d.ts.map +1 -0
- package/dist/client/blocks/library/diff.config.js +34 -0
- package/dist/client/blocks/library/diff.config.js.map +1 -0
- package/dist/client/blocks/library/file-tree.config.d.ts +59 -0
- package/dist/client/blocks/library/file-tree.config.d.ts.map +1 -0
- package/dist/client/blocks/library/file-tree.config.js +45 -0
- package/dist/client/blocks/library/file-tree.config.js.map +1 -0
- package/dist/client/blocks/library/html.d.ts.map +1 -1
- package/dist/client/blocks/library/html.js +4 -1
- package/dist/client/blocks/library/html.js.map +1 -1
- package/dist/client/blocks/library/json-explorer.config.d.ts +46 -0
- package/dist/client/blocks/library/json-explorer.config.d.ts.map +1 -0
- package/dist/client/blocks/library/json-explorer.config.js +28 -0
- package/dist/client/blocks/library/json-explorer.config.js.map +1 -0
- package/dist/client/blocks/library/mermaid.config.d.ts +32 -0
- package/dist/client/blocks/library/mermaid.config.d.ts.map +1 -0
- package/dist/client/blocks/library/mermaid.config.js +24 -0
- package/dist/client/blocks/library/mermaid.config.js.map +1 -0
- package/dist/client/blocks/library/openapi-spec.config.d.ts +49 -0
- package/dist/client/blocks/library/openapi-spec.config.d.ts.map +1 -0
- package/dist/client/blocks/library/openapi-spec.config.js +24 -0
- package/dist/client/blocks/library/openapi-spec.config.js.map +1 -0
- package/dist/client/blocks/library/server-specs.d.ts +35 -0
- package/dist/client/blocks/library/server-specs.d.ts.map +1 -0
- package/dist/client/blocks/library/server-specs.js +171 -0
- package/dist/client/blocks/library/server-specs.js.map +1 -0
- package/dist/client/blocks/library/specs.d.ts +29 -0
- package/dist/client/blocks/library/specs.d.ts.map +1 -0
- package/dist/client/blocks/library/specs.js +229 -0
- package/dist/client/blocks/library/specs.js.map +1 -0
- package/dist/client/blocks/library/table.d.ts.map +1 -1
- package/dist/client/blocks/library/table.js +3 -1
- package/dist/client/blocks/library/table.js.map +1 -1
- package/dist/client/blocks/library/tabs.js +1 -1
- package/dist/client/blocks/library/tabs.js.map +1 -1
- package/dist/client/blocks/registry.d.ts +8 -0
- package/dist/client/blocks/registry.d.ts.map +1 -1
- package/dist/client/blocks/registry.js +15 -0
- package/dist/client/blocks/registry.js.map +1 -1
- package/dist/client/blocks/server.d.ts +9 -0
- package/dist/client/blocks/server.d.ts.map +1 -1
- package/dist/client/blocks/server.js +16 -0
- package/dist/client/blocks/server.js.map +1 -1
- package/dist/client/blocks/types.d.ts +40 -0
- package/dist/client/blocks/types.d.ts.map +1 -1
- package/dist/client/blocks/types.js.map +1 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +10 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/rich-markdown-editor/DragHandle.d.ts +52 -0
- package/dist/client/rich-markdown-editor/DragHandle.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/DragHandle.js +403 -0
- package/dist/client/rich-markdown-editor/DragHandle.js.map +1 -0
- package/dist/client/rich-markdown-editor/RegistryBlockNode.d.ts +97 -0
- package/dist/client/rich-markdown-editor/RegistryBlockNode.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js +214 -0
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -0
- package/dist/client/rich-markdown-editor/RunId.d.ts +28 -0
- package/dist/client/rich-markdown-editor/RunId.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/RunId.js +60 -0
- package/dist/client/rich-markdown-editor/RunId.js.map +1 -0
- package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts +25 -1
- package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/SharedRichEditor.js +14 -5
- package/dist/client/rich-markdown-editor/SharedRichEditor.js.map +1 -1
- package/dist/client/rich-markdown-editor/gfmDoc.d.ts +24 -0
- package/dist/client/rich-markdown-editor/gfmDoc.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/gfmDoc.js +83 -0
- package/dist/client/rich-markdown-editor/gfmDoc.js.map +1 -0
- package/dist/client/rich-markdown-editor/index.d.ts +5 -0
- package/dist/client/rich-markdown-editor/index.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/index.js +5 -0
- package/dist/client/rich-markdown-editor/index.js.map +1 -1
- package/dist/client/rich-markdown-editor/registrySlashCommands.d.ts +46 -0
- package/dist/client/rich-markdown-editor/registrySlashCommands.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/registrySlashCommands.js +13 -0
- package/dist/client/rich-markdown-editor/registrySlashCommands.js.map +1 -0
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.js +33 -0
- package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
- package/docs/content/template-plan.md +19 -4
- package/docs/content/visual-plans.md +3 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-tabs.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/code-tabs.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EACL,cAAc,EACd,WAAW,GAGZ,MAAM,uBAAuB,CAAC;AAE/B;;;;;;;;;;;GAWG;AAEH,kFAAkF;AAElF,SAAS,YAAY,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAgC;IAC1E,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5E,OAAO,CACL,mBAAS,SAAS,EAAC,YAAY,mBAAgB,OAAO,aACnD,KAAK,IAAI,uBAAK,KAAK,GAAM,EAC1B,eAAK,SAAS,EAAC,mFAAmF,aAChG,cAAK,SAAS,EAAC,8BAA8B,YAC1C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACtB,kBAEE,IAAI,EAAC,QAAQ,iCAEb,SAAS,EAAE,EAAE,CACX,6EAA6E,EAC7E,GAAG,CAAC,EAAE,KAAK,MAAM,EAAE,EAAE;gCACnB,CAAC,CAAC,sEAAsE;gCACxE,CAAC,CAAC,oCAAoC,CACzC,EACD,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,aAElC,KAAC,QAAQ,IAAC,SAAS,EAAC,wBAAwB,GAAG,EAC/C,gBAAM,SAAS,EAAC,SAAS,aACvB,eAAM,SAAS,EAAC,gDAAgD,YAC7D,GAAG,CAAC,KAAK,GACL,EACN,GAAG,CAAC,OAAO,IAAI,CACd,eAAM,SAAS,EAAC,8BAA8B,YAC3C,GAAG,CAAC,OAAO,GACP,CACR,IACI,KArBF,GAAG,CAAC,EAAE,CAsBJ,CACV,CAAC,GACE,EACN,cAAK,SAAS,EAAC,aAAa,YACzB,MAAM,IAAI,CACT,8BACE,aAAI,SAAS,EAAC,uCAAuC,YAClD,MAAM,CAAC,KAAK,GACV,EACJ,MAAM,CAAC,OAAO,IAAI,CACjB,YAAG,SAAS,EAAC,sBAAsB,YAAE,MAAM,CAAC,OAAO,GAAK,CACzD,EACD,KAAC,WAAW,IAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAI,IAC5D,CACJ,GACG,IACF,IACE,CACX,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,EACnB,IAAI,EACJ,QAAQ,EACR,SAAS,GAKV;IACC,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,mBAAmB,EAAE,SAAS,IAAI,MAAM,CAAC,YAC1D,KAAC,eAAe,IAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,GAAI,GAC/C,CACP,CAAC;AACJ,CAAC;AAED,kFAAkF;AAElF,MAAM,UAAU,GACd,uQAAuQ,CAAC;AAE1Q,MAAM,aAAa,GACjB,mRAAmR,CAAC;AAEtR,4EAA4E;AAC5E,SAAS,YAAY;IACnB,OAAO,YAAY,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AAC/D,CAAC;AAED;;;;;GAKG;AACH,SAAS,YAAY,CAAC,EACpB,IAAI,EACJ,QAAQ,EACR,QAAQ,GACqB;IAC7B,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE5E,MAAM,MAAM,GAAG,CAAC,IAAmB,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3D,MAAM,SAAS,GAAG,CAAC,EAAU,EAAE,KAA2B,EAAE,EAAE,CAC5D,MAAM,CACJ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CACrE,CAAC;IAEJ,MAAM,SAAS,GAAG,CAAC,EAAU,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,6CAA6C;QAC5E,MAAM,CAAC,IAAI,CAAC,CAAC;QACb,IAAI,QAAQ,KAAK,EAAE;YAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE;YAAE,OAAO,CAAC,aAAa;QACjD,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;QAC1B,MAAM,CAAC;YACL,GAAG,IAAI,CAAC,IAAI;YACZ,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;SAC3D,CAAC,CAAC;QACH,WAAW,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,yCAAyC,aACtD,eACE,SAAS,EAAC,8DAA8D,EACxE,IAAI,EAAC,SAAS,4CAGb,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;wBACrB,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,KAAK,MAAM,EAAE,EAAE,CAAC;wBACvC,OAAO,CACL,eAEE,SAAS,EAAE,EAAE,CACX,iEAAiE,EACjE,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,wBAAwB,CAChE,aAED,kBACE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,mBACK,QAAQ,EACvB,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAClC,SAAS,EAAE,EAAE,CACX,gGAAgG,EAChG,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAChD,aAED,KAAC,QAAQ,IAAC,SAAS,EAAC,iBAAiB,GAAG,EACvC,GAAG,CAAC,KAAK,IACH,EACR,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CACnC,iBACE,IAAI,EAAC,QAAQ,+CAED,UAAU,GAAG,CAAC,KAAK,EAAE,EACjC,SAAS,EAAE,EAAE,CACX,6FAA6F,EAC7F,kEAAkE,EAClE,sCAAsC,CACvC,EACD,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,YAEhC,KAAC,KAAK,IAAC,SAAS,EAAC,mBAAmB,GAAG,GAChC,CACV,KAjCI,GAAG,CAAC,EAAE,CAkCP,CACP,CAAC;oBACJ,CAAC,CAAC,EACD,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,CACpC,kBACE,IAAI,EAAC,QAAQ,+CAEF,SAAS,EACpB,SAAS,EAAC,oHAAoH,EAC9H,OAAO,EAAE,MAAM,aAEf,KAAC,QAAQ,IAAC,SAAS,EAAC,QAAQ,GAAG,eAExB,CACV,IACG,EACL,MAAM,IAAI,CACT,eAAK,SAAS,EAAC,qBAAqB,aAClC,eAAK,SAAS,EAAC,2BAA2B,aACxC,iBAAO,SAAS,EAAC,uBAAuB,aACtC,eAAM,SAAS,EAAC,2CAA2C,sBAEpD,EACP,gBACE,IAAI,EAAC,MAAM,iCAEX,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,CAAC,KAAK,EACnB,QAAQ,EAAE,CAAC,QAAQ,EACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,GAErD,IACI,EACR,iBAAO,SAAS,EAAC,uBAAuB,aACtC,eAAM,SAAS,EAAC,2CAA2C,yBAEpD,EACP,gBACE,IAAI,EAAC,MAAM,iCAEX,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE,EAC5B,QAAQ,EAAE,CAAC,QAAQ,EACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE;4CACnB,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,SAAS;yCAC1C,CAAC,GAEJ,IACI,IACJ,EACN,iBAAO,SAAS,EAAC,uBAAuB,aACtC,eAAM,SAAS,EAAC,2CAA2C,wBAEpD,EACP,gBACE,IAAI,EAAC,MAAM,iCAEX,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE,EAC3B,QAAQ,EAAE,CAAC,QAAQ,EACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE;oCACnB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,SAAS;iCACzC,CAAC,GAEJ,IACI,EACR,iBAAO,SAAS,EAAC,uBAAuB,aACtC,eAAM,SAAS,EAAC,2CAA2C,qBAEpD,EACP,kDAEE,UAAU,EAAE,KAAK,EACjB,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,MAAM,CAAC,IAAI,EAClB,QAAQ,EAAE,CAAC,QAAQ,EACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,GAEpD,IACI,IACJ,CACP,IACG,CACP,CAAC;AACJ,CAAC;AAWD,IAAI,iBAAiB,GAAqC,IAAI,CAAC;AAC/D,SAAS,eAAe;IACtB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,iBAAiB,GAAG,CAAC,KAAK,IAAI,EAAE;YAC9B,MAAM,CAAC,EAAE,qBAAqB,EAAE,EAAE,EAAE,qBAAqB,EAAE,CAAC,GAC1D,MAAM,OAAO,CAAC,GAAG,CAAC;gBAChB,MAAM,CAAC,YAAY,CAAC;gBACpB,MAAM,CAAC,wBAAwB,CAAC;aACjC,CAAC,CAAC;YACL,OAAO,qBAAqB,CAAC;gBAC3B,MAAM,EAAE,CAAC,MAAM,CAAC,sCAAsC,CAAC,CAAC;gBACxD,KAAK,EAAE;oBACL,MAAM,CAAC,4BAA4B,CAAC;oBACpC,MAAM,CAAC,4BAA4B,CAAC;oBACpC,MAAM,CAAC,qBAAqB,CAAC;oBAC7B,MAAM,CAAC,qBAAqB,CAAC;oBAC7B,MAAM,CAAC,sBAAsB,CAAC;oBAC9B,MAAM,CAAC,qBAAqB,CAAC;oBAC7B,MAAM,CAAC,sBAAsB,CAAC;oBAC9B,MAAM,CAAC,0BAA0B,CAAC;oBAClC,MAAM,CAAC,sBAAsB,CAAC;oBAC9B,MAAM,CAAC,6BAA6B,CAAC;oBACrC,MAAM,CAAC,wBAAwB,CAAC;oBAChC,MAAM,CAAC,sBAAsB,CAAC;oBAC9B,MAAM,CAAC,qBAAqB,CAAC;iBAC9B;gBACD,MAAM,EAAE,qBAAqB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;aACpD,CAAyC,CAAC;QAC7C,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACnB,iBAAiB,GAAG,IAAI,CAAC;YACzB,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,YAAY,GAA2B;IAC3C,EAAE,EAAE,YAAY;IAChB,EAAE,EAAE,YAAY;IAChB,EAAE,EAAE,MAAM;IACV,KAAK,EAAE,MAAM;IACb,GAAG,EAAE,MAAM;IACX,EAAE,EAAE,QAAQ;IACZ,GAAG,EAAE,MAAM;IACX,EAAE,EAAE,UAAU;CACf,CAAC;AAEF,SAAS,eAAe,CAAC,EACvB,IAAI,EACJ,QAAQ,GAIT;IACC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAEtD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,eAAe,EAAE;aACd,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE;YACpB,MAAM,SAAS,GAAG,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YACrD,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;YACtD,MAAM,MAAM,GAAG,WAAW,CAAC,kBAAkB,EAAE,CAAC;YAChD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;YAC3D,OAAO,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE;gBAClC,IAAI;gBACJ,KAAK,EAAE,qBAAqB;aAC7B,CAAC,CAAC;QACL,CAAC,CAAC;aACD,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;YACZ,IAAI,CAAC,SAAS;gBAAE,OAAO,CAAC,GAAa,CAAC,CAAC;QACzC,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE;YACV,IAAI,CAAC,SAAS;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QACL,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAErB,IAAI,IAAI,EAAE,CAAC;QACT,wEAAwE;QACxE,sEAAsE;QACtE,OAAO,CACL,cAAK,SAAS,EAAC,YAAY,EAAC,uBAAuB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAI,CAC1E,CAAC;IACJ,CAAC;IACD,OAAO,CACL,wBACE,eAAM,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,YAC3D,IAAI,GACA,GACH,CACP,CAAC;AACJ,CAAC;AAED,kFAAkF;AAElF,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAe;IACrD,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,cAAc;IACtB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;IAClB,SAAS,EAAE,CAAC,OAAO,CAAC;IACpB,KAAK,EAAE,WAAW;IAClB,IAAI,EAAE,QAAQ;IACd,WAAW,EACT,uHAAuH;CAC1H,CAAC,CAAC","sourcesContent":["import { useEffect, useState } from \"react\";\nimport { IconCode, IconPlus, IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type { BlockReadProps, BlockEditProps } from \"../types.js\";\nimport {\n codeTabsSchema,\n codeTabsMdx,\n type CodeTabsData,\n type CodeTabsTab,\n} from \"./code-tabs.config.js\";\n\n/**\n * Standard `code-tabs` block (STANDARD core library): a vertical file tab rail\n * with Shiki-highlighted code panes. Moved verbatim from the plan\n * `CodeTabsBlock` (`DocumentArea.tsx`) so its rendered output is unchanged, then\n * generalized to the registry `Read`/`Edit` contract. Shareable by any app that\n * registers the core block library.\n *\n * `Edit` is schema-driven in spirit: each tab's `code` field renders as a\n * code-style monospace text area (the plain auto-editor can't descend into the\n * `tabs` array), plus label/language/caption inputs. The component owns no app\n * services, so it stays portable across apps.\n */\n\n/* ── Read (vertical tab rail + Shiki) ──────────────────────────────────────── */\n\nfunction CodeTabsRead({ data, blockId, title }: BlockReadProps<CodeTabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n return (\n <section className=\"plan-block\" data-block-id={blockId}>\n {title && <h2>{title}</h2>}\n <div className=\"grid overflow-hidden border-y border-plan-line md:grid-cols-[300px_minmax(0,1fr)]\">\n <div className=\"border-plan-line md:border-r\">\n {data.tabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n data-plan-interactive\n className={cn(\n \"flex w-full items-start gap-3 border-b border-plan-line px-4 py-4 text-left\",\n tab.id === active?.id\n ? \"bg-plan-block text-plan-text shadow-[inset_3px_0_0_hsl(var(--ring))]\"\n : \"text-plan-muted hover:bg-accent/30\",\n )}\n onClick={() => setActiveId(tab.id)}\n >\n <IconCode className=\"mt-0.5 size-4 shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block truncate font-mono text-sm font-semibold\">\n {tab.label}\n </span>\n {tab.caption && (\n <span className=\"mt-1 block text-xs leading-5\">\n {tab.caption}\n </span>\n )}\n </span>\n </button>\n ))}\n </div>\n <div className=\"min-w-0 p-5\">\n {active && (\n <>\n <h3 className=\"text-2xl font-semibold tracking-tight\">\n {active.label}\n </h3>\n {active.caption && (\n <p className=\"mt-2 text-plan-muted\">{active.caption}</p>\n )}\n <CodeSurface code={active.code} language={active.language} />\n </>\n )}\n </div>\n </div>\n </section>\n );\n}\n\nfunction CodeSurface({\n code,\n language,\n className,\n}: {\n code: string;\n language?: string;\n className?: string;\n}) {\n return (\n <div className={cn(\"plan-code-surface\", className ?? \"mt-5\")}>\n <HighlightedCode code={code} language={language} />\n </div>\n );\n}\n\n/* ── Edit (code text areas per tab) ────────────────────────────────────────── */\n\nconst inputClass =\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nconst codeAreaClass =\n \"flex min-h-[140px] w-full rounded-md border border-input bg-transparent px-3 py-2 font-mono text-xs leading-5 shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\n/** Mint a reasonably-unique code-tab id without pulling a dep into core. */\nfunction newCodeTabId(): string {\n return `code-tab-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/**\n * Editor: a file-tab strip (one tab active at a time) whose active tab exposes\n * label/language/caption/code fields — mirroring the read renderer's tabbed\n * layout and the standard `tabs` block editor instead of stacking every tab's\n * full form vertically. Add/remove/rename keep the schema's 1..12 bounds.\n */\nfunction CodeTabsEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<CodeTabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n\n const commit = (tabs: CodeTabsTab[]) => onChange({ tabs });\n\n const updateTab = (id: string, patch: Partial<CodeTabsTab>) =>\n commit(\n data.tabs.map((tab) => (tab.id === id ? { ...tab, ...patch } : tab)),\n );\n\n const removeTab = (id: string) => {\n const next = data.tabs.filter((tab) => tab.id !== id);\n if (next.length === 0) return; // tabs must keep at least one (schema min 1)\n commit(next);\n if (activeId === id) setActiveId(next[0]?.id ?? \"\");\n };\n\n const addTab = () => {\n if (data.tabs.length >= 12) return; // schema max\n const id = newCodeTabId();\n commit([\n ...data.tabs,\n { id, label: `file-${data.tabs.length + 1}.ts`, code: \"\" },\n ]);\n setActiveId(id);\n };\n\n return (\n <div className=\"an-code-tabs-editor flex flex-col gap-4\">\n <div\n className=\"flex max-w-full flex-wrap items-center gap-1 overflow-x-auto\"\n role=\"tablist\"\n data-plan-interactive\n >\n {data.tabs.map((tab) => {\n const selected = tab.id === active?.id;\n return (\n <div\n key={tab.id}\n className={cn(\n \"group flex items-center gap-1 rounded-lg pr-1 transition-colors\",\n selected ? \"bg-plan-block shadow-sm\" : \"hover:bg-plan-block/60\",\n )}\n >\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => setActiveId(tab.id)}\n className={cn(\n \"flex items-center gap-2 rounded-lg px-3 py-2 font-mono text-sm font-semibold transition-colors\",\n selected ? \"text-plan-text\" : \"text-plan-muted\",\n )}\n >\n <IconCode className=\"size-4 shrink-0\" />\n {tab.label}\n </button>\n {editable && data.tabs.length > 1 && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove ${tab.label}`}\n className={cn(\n \"flex size-6 shrink-0 items-center justify-center rounded text-plan-muted transition-opacity\",\n \"opacity-0 group-hover:opacity-100 group-focus-within:opacity-100\",\n \"hover:bg-muted hover:text-foreground\",\n )}\n onClick={() => removeTab(tab.id)}\n >\n <IconX className=\"size-3.5 shrink-0\" />\n </button>\n )}\n </div>\n );\n })}\n {editable && data.tabs.length < 12 && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Add tab\"\n className=\"flex items-center gap-1.5 rounded-md px-2 py-2 text-sm text-plan-muted hover:bg-plan-block/60 hover:text-plan-text\"\n onClick={addTab}\n >\n <IconPlus className=\"size-4\" />\n Add tab\n </button>\n )}\n </div>\n {active && (\n <div className=\"flex flex-col gap-2\">\n <div className=\"grid gap-2 md:grid-cols-2\">\n <label className=\"flex flex-col gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Label\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={active.label}\n disabled={!editable}\n onChange={(event) =>\n updateTab(active.id, { label: event.target.value })\n }\n />\n </label>\n <label className=\"flex flex-col gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Language\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={active.language ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateTab(active.id, {\n language: event.target.value || undefined,\n })\n }\n />\n </label>\n </div>\n <label className=\"flex flex-col gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Caption\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={active.caption ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateTab(active.id, {\n caption: event.target.value || undefined,\n })\n }\n />\n </label>\n <label className=\"flex flex-col gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Code\n </span>\n <textarea\n data-plan-interactive\n spellCheck={false}\n className={codeAreaClass}\n value={active.code}\n disabled={!editable}\n onChange={(event) =>\n updateTab(active.id, { code: event.target.value })\n }\n />\n </label>\n </div>\n )}\n </div>\n );\n}\n\n/* ── Shiki syntax highlighting (lazy-loaded, single dark theme) ────────────── */\ntype ShikiHighlighter = {\n codeToHtml: (\n code: string,\n options: { lang: string; theme: string },\n ) => string | Promise<string>;\n getLoadedLanguages: () => string[];\n};\n\nlet highlighterLoader: Promise<ShikiHighlighter> | null = null;\nfunction loadHighlighter(): Promise<ShikiHighlighter> {\n if (!highlighterLoader) {\n highlighterLoader = (async () => {\n const [{ createHighlighterCore }, { createOnigurumaEngine }] =\n await Promise.all([\n import(\"shiki/core\"),\n import(\"shiki/engine/oniguruma\"),\n ]);\n return createHighlighterCore({\n themes: [import(\"shiki/themes/github-dark-default.mjs\")],\n langs: [\n import(\"shiki/langs/javascript.mjs\"),\n import(\"shiki/langs/typescript.mjs\"),\n import(\"shiki/langs/jsx.mjs\"),\n import(\"shiki/langs/tsx.mjs\"),\n import(\"shiki/langs/json.mjs\"),\n import(\"shiki/langs/css.mjs\"),\n import(\"shiki/langs/html.mjs\"),\n import(\"shiki/langs/markdown.mjs\"),\n import(\"shiki/langs/bash.mjs\"),\n import(\"shiki/langs/shellscript.mjs\"),\n import(\"shiki/langs/python.mjs\"),\n import(\"shiki/langs/yaml.mjs\"),\n import(\"shiki/langs/sql.mjs\"),\n ],\n engine: createOnigurumaEngine(import(\"shiki/wasm\")),\n }) as unknown as Promise<ShikiHighlighter>;\n })().catch((error) => {\n highlighterLoader = null;\n throw error;\n });\n }\n return highlighterLoader;\n}\n\nconst LANG_ALIASES: Record<string, string> = {\n js: \"javascript\",\n ts: \"typescript\",\n sh: \"bash\",\n shell: \"bash\",\n zsh: \"bash\",\n py: \"python\",\n yml: \"yaml\",\n md: \"markdown\",\n};\n\nfunction HighlightedCode({\n code,\n language,\n}: {\n code: string;\n language?: string;\n}) {\n const [html, setHtml] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n loadHighlighter()\n .then((highlighter) => {\n const requested = (language || \"text\").toLowerCase();\n const resolved = LANG_ALIASES[requested] ?? requested;\n const loaded = highlighter.getLoadedLanguages();\n const lang = loaded.includes(resolved) ? resolved : \"text\";\n return highlighter.codeToHtml(code, {\n lang,\n theme: \"github-dark-default\",\n });\n })\n .then((out) => {\n if (!cancelled) setHtml(out as string);\n })\n .catch(() => {\n if (!cancelled) setHtml(null);\n });\n return () => {\n cancelled = true;\n };\n }, [code, language]);\n\n if (html) {\n // Shiki output is generated from plain text by the highlighter itself —\n // it is NOT agent-authored HTML, so this is safe (mirrors core chat).\n return (\n <div className=\"plan-shiki\" dangerouslySetInnerHTML={{ __html: html }} />\n );\n }\n return (\n <pre>\n <code className={language ? `language-${language}` : undefined}>\n {code}\n </code>\n </pre>\n );\n}\n\n/* ── Spec ──────────────────────────────────────────────────────────────────── */\n\nexport const codeTabsBlock = defineBlock<CodeTabsData>({\n type: \"code-tabs\",\n schema: codeTabsSchema,\n mdx: codeTabsMdx,\n Read: CodeTabsRead,\n Edit: CodeTabsEdit,\n placement: [\"block\"],\n label: \"Code tabs\",\n icon: IconCode,\n description:\n \"A vertical file tab rail of syntax-highlighted code snippets, one tab per file with an optional language and caption.\",\n});\n"]}
|
|
1
|
+
{"version":3,"file":"code-tabs.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/code-tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from \"react\";\nimport { IconCode, IconPlus, IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type { BlockReadProps, BlockEditProps } from \"../types.js\";\nimport {\n codeTabsSchema,\n codeTabsMdx,\n type CodeTabsData,\n type CodeTabsTab,\n} from \"./code-tabs.config.js\";\n\n/**\n * Standard `code-tabs` block (STANDARD core library): a vertical file tab rail\n * with Shiki-highlighted code panes. Moved verbatim from the plan\n * `CodeTabsBlock` (`DocumentArea.tsx`) so its rendered output is unchanged, then\n * generalized to the registry `Read`/`Edit` contract. Shareable by any app that\n * registers the core block library.\n *\n * `Edit` is schema-driven in spirit: each tab's `code` field renders as a\n * code-style monospace text area (the plain auto-editor can't descend into the\n * `tabs` array), plus label/language/caption inputs. The component owns no app\n * services, so it stays portable across apps.\n */\n\n/* ── Read (vertical tab rail + Shiki) ──────────────────────────────────────── */\n\nfunction CodeTabsRead({ data, blockId, title }: BlockReadProps<CodeTabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n return (\n <section className=\"plan-block\" data-block-id={blockId}>\n {title && <div className=\"plan-block-label\">{title}</div>}\n <div className=\"grid overflow-hidden border-y border-plan-line md:grid-cols-[300px_minmax(0,1fr)]\">\n <div className=\"border-plan-line md:border-r\">\n {data.tabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n data-plan-interactive\n className={cn(\n \"flex w-full items-start gap-3 border-b border-plan-line px-4 py-4 text-left\",\n tab.id === active?.id\n ? \"bg-plan-block text-plan-text shadow-[inset_3px_0_0_hsl(var(--ring))]\"\n : \"text-plan-muted hover:bg-accent/30\",\n )}\n onClick={() => setActiveId(tab.id)}\n >\n <IconCode className=\"mt-0.5 size-4 shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block truncate font-mono text-sm font-semibold\">\n {tab.label}\n </span>\n {tab.caption && (\n <span className=\"mt-1 block text-xs leading-5\">\n {tab.caption}\n </span>\n )}\n </span>\n </button>\n ))}\n </div>\n <div className=\"min-w-0 p-5\">\n {active && (\n <>\n <h3 className=\"text-2xl font-semibold tracking-tight\">\n {active.label}\n </h3>\n {active.caption && (\n <p className=\"mt-2 text-plan-muted\">{active.caption}</p>\n )}\n <CodeSurface code={active.code} language={active.language} />\n </>\n )}\n </div>\n </div>\n </section>\n );\n}\n\nfunction CodeSurface({\n code,\n language,\n className,\n}: {\n code: string;\n language?: string;\n className?: string;\n}) {\n return (\n <div className={cn(\"plan-code-surface\", className ?? \"mt-5\")}>\n <HighlightedCode code={code} language={language} />\n </div>\n );\n}\n\n/* ── Edit (code text areas per tab) ────────────────────────────────────────── */\n\nconst inputClass =\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nconst codeAreaClass =\n \"flex min-h-[140px] w-full rounded-md border border-input bg-transparent px-3 py-2 font-mono text-xs leading-5 shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\n/** Mint a reasonably-unique code-tab id without pulling a dep into core. */\nfunction newCodeTabId(): string {\n return `code-tab-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/**\n * Editor: a file-tab strip (one tab active at a time) whose active tab exposes\n * label/language/caption/code fields — mirroring the read renderer's tabbed\n * layout and the standard `tabs` block editor instead of stacking every tab's\n * full form vertically. Add/remove/rename keep the schema's 1..12 bounds.\n */\nfunction CodeTabsEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<CodeTabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n\n const commit = (tabs: CodeTabsTab[]) => onChange({ tabs });\n\n const updateTab = (id: string, patch: Partial<CodeTabsTab>) =>\n commit(\n data.tabs.map((tab) => (tab.id === id ? { ...tab, ...patch } : tab)),\n );\n\n const removeTab = (id: string) => {\n const next = data.tabs.filter((tab) => tab.id !== id);\n if (next.length === 0) return; // tabs must keep at least one (schema min 1)\n commit(next);\n if (activeId === id) setActiveId(next[0]?.id ?? \"\");\n };\n\n const addTab = () => {\n if (data.tabs.length >= 12) return; // schema max\n const id = newCodeTabId();\n commit([\n ...data.tabs,\n { id, label: `file-${data.tabs.length + 1}.ts`, code: \"\" },\n ]);\n setActiveId(id);\n };\n\n return (\n <div className=\"an-code-tabs-editor flex flex-col gap-4\">\n <div\n className=\"flex max-w-full flex-wrap items-center gap-1 overflow-x-auto\"\n role=\"tablist\"\n data-plan-interactive\n >\n {data.tabs.map((tab) => {\n const selected = tab.id === active?.id;\n return (\n <div\n key={tab.id}\n className={cn(\n \"group flex items-center gap-1 rounded-lg pr-1 transition-colors\",\n selected ? \"bg-plan-block shadow-sm\" : \"hover:bg-plan-block/60\",\n )}\n >\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => setActiveId(tab.id)}\n className={cn(\n \"flex items-center gap-2 rounded-lg px-3 py-2 font-mono text-sm font-semibold transition-colors\",\n selected ? \"text-plan-text\" : \"text-plan-muted\",\n )}\n >\n <IconCode className=\"size-4 shrink-0\" />\n {tab.label}\n </button>\n {editable && data.tabs.length > 1 && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={`Remove ${tab.label}`}\n className={cn(\n \"flex size-6 shrink-0 items-center justify-center rounded text-plan-muted transition-opacity\",\n \"opacity-0 group-hover:opacity-100 group-focus-within:opacity-100\",\n \"hover:bg-muted hover:text-foreground\",\n )}\n onClick={() => removeTab(tab.id)}\n >\n <IconX className=\"size-3.5 shrink-0\" />\n </button>\n )}\n </div>\n );\n })}\n {editable && data.tabs.length < 12 && (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Add tab\"\n className=\"flex items-center gap-1.5 rounded-md px-2 py-2 text-sm text-plan-muted hover:bg-plan-block/60 hover:text-plan-text\"\n onClick={addTab}\n >\n <IconPlus className=\"size-4\" />\n Add tab\n </button>\n )}\n </div>\n {active && (\n <div className=\"flex flex-col gap-2\">\n <div className=\"grid gap-2 md:grid-cols-2\">\n <label className=\"flex flex-col gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Label\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={active.label}\n disabled={!editable}\n onChange={(event) =>\n updateTab(active.id, { label: event.target.value })\n }\n />\n </label>\n <label className=\"flex flex-col gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Language\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={active.language ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateTab(active.id, {\n language: event.target.value || undefined,\n })\n }\n />\n </label>\n </div>\n <label className=\"flex flex-col gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Caption\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={active.caption ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateTab(active.id, {\n caption: event.target.value || undefined,\n })\n }\n />\n </label>\n <label className=\"flex flex-col gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Code\n </span>\n <textarea\n data-plan-interactive\n spellCheck={false}\n className={codeAreaClass}\n value={active.code}\n disabled={!editable}\n onChange={(event) =>\n updateTab(active.id, { code: event.target.value })\n }\n />\n </label>\n </div>\n )}\n </div>\n );\n}\n\n/* ── Shiki syntax highlighting (lazy-loaded, single dark theme) ────────────── */\ntype ShikiHighlighter = {\n codeToHtml: (\n code: string,\n options: { lang: string; theme: string },\n ) => string | Promise<string>;\n getLoadedLanguages: () => string[];\n};\n\nlet highlighterLoader: Promise<ShikiHighlighter> | null = null;\nfunction loadHighlighter(): Promise<ShikiHighlighter> {\n if (!highlighterLoader) {\n highlighterLoader = (async () => {\n const [{ createHighlighterCore }, { createOnigurumaEngine }] =\n await Promise.all([\n import(\"shiki/core\"),\n import(\"shiki/engine/oniguruma\"),\n ]);\n return createHighlighterCore({\n themes: [import(\"shiki/themes/github-dark-default.mjs\")],\n langs: [\n import(\"shiki/langs/javascript.mjs\"),\n import(\"shiki/langs/typescript.mjs\"),\n import(\"shiki/langs/jsx.mjs\"),\n import(\"shiki/langs/tsx.mjs\"),\n import(\"shiki/langs/json.mjs\"),\n import(\"shiki/langs/css.mjs\"),\n import(\"shiki/langs/html.mjs\"),\n import(\"shiki/langs/markdown.mjs\"),\n import(\"shiki/langs/bash.mjs\"),\n import(\"shiki/langs/shellscript.mjs\"),\n import(\"shiki/langs/python.mjs\"),\n import(\"shiki/langs/yaml.mjs\"),\n import(\"shiki/langs/sql.mjs\"),\n ],\n engine: createOnigurumaEngine(import(\"shiki/wasm\")),\n }) as unknown as Promise<ShikiHighlighter>;\n })().catch((error) => {\n highlighterLoader = null;\n throw error;\n });\n }\n return highlighterLoader;\n}\n\nconst LANG_ALIASES: Record<string, string> = {\n js: \"javascript\",\n ts: \"typescript\",\n sh: \"bash\",\n shell: \"bash\",\n zsh: \"bash\",\n py: \"python\",\n yml: \"yaml\",\n md: \"markdown\",\n};\n\nfunction HighlightedCode({\n code,\n language,\n}: {\n code: string;\n language?: string;\n}) {\n const [html, setHtml] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n loadHighlighter()\n .then((highlighter) => {\n const requested = (language || \"text\").toLowerCase();\n const resolved = LANG_ALIASES[requested] ?? requested;\n const loaded = highlighter.getLoadedLanguages();\n const lang = loaded.includes(resolved) ? resolved : \"text\";\n return highlighter.codeToHtml(code, {\n lang,\n theme: \"github-dark-default\",\n });\n })\n .then((out) => {\n if (!cancelled) setHtml(out as string);\n })\n .catch(() => {\n if (!cancelled) setHtml(null);\n });\n return () => {\n cancelled = true;\n };\n }, [code, language]);\n\n if (html) {\n // Shiki output is generated from plain text by the highlighter itself —\n // it is NOT agent-authored HTML, so this is safe (mirrors core chat).\n return (\n <div className=\"plan-shiki\" dangerouslySetInnerHTML={{ __html: html }} />\n );\n }\n return (\n <pre>\n <code className={language ? `language-${language}` : undefined}>\n {code}\n </code>\n </pre>\n );\n}\n\n/* ── Spec ──────────────────────────────────────────────────────────────────── */\n\nexport const codeTabsBlock = defineBlock<CodeTabsData>({\n type: \"code-tabs\",\n schema: codeTabsSchema,\n mdx: codeTabsMdx,\n Read: CodeTabsRead,\n Edit: CodeTabsEdit,\n placement: [\"block\"],\n label: \"Code tabs\",\n icon: IconCode,\n description:\n \"A vertical file tab rail of syntax-highlighted code snippets, one tab per file with an optional language and caption.\",\n});\n"]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { BlockMdxConfig } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Pure (React-free) part of the PLAN-SPECIFIC `data-model` block: its data schema
|
|
5
|
+
* and MDX round-trip config. Shared by the server MDX adapter (`plan-mdx.ts` via
|
|
6
|
+
* `plan-block-registry.ts`) and the client spec (`planBlocks.tsx`). Keeping this
|
|
7
|
+
* React-free means importing it into a server module never pulls React into the
|
|
8
|
+
* Nitro/SSR bundle.
|
|
9
|
+
*
|
|
10
|
+
* The block renders a dbdiagram / Prisma-style entity-relationship diagram: a set
|
|
11
|
+
* of entity cards (each a small table of fields with PK / FK / nullable flags)
|
|
12
|
+
* plus optional explicit relations. The Read renderer makes foreign keys
|
|
13
|
+
* interactive — hovering / clicking an FK highlights and scrolls to the
|
|
14
|
+
* referenced entity — which is why this is a custom block, not a plain table.
|
|
15
|
+
*
|
|
16
|
+
* The schema MUST stay data-compatible with the `data-model` branch of
|
|
17
|
+
* `planBlockSchema` (`plan-content.ts`), and the MDX `tag` (`DataModel`) +
|
|
18
|
+
* attribute shape MUST match the inline planBlockSchema member so stored `.mdx`
|
|
19
|
+
* round-trips: the whole `entities` and `relations` arrays are JSON props
|
|
20
|
+
* (`<DataModel id … entities={…} relations={…} />`).
|
|
21
|
+
*/
|
|
22
|
+
/** Cardinality of a relation between two entities. */
|
|
23
|
+
export type DataModelRelationKind = "1-1" | "1-n" | "n-n";
|
|
24
|
+
export declare const DATA_MODEL_RELATION_KINDS: DataModelRelationKind[];
|
|
25
|
+
/** One column of an entity. `fk` is a string like `"User.id"`. */
|
|
26
|
+
export interface DataModelField {
|
|
27
|
+
name: string;
|
|
28
|
+
type?: string;
|
|
29
|
+
pk?: boolean;
|
|
30
|
+
/** Foreign-key target, e.g. `"User.id"` (entity name/id + optional field). */
|
|
31
|
+
fk?: string;
|
|
32
|
+
nullable?: boolean;
|
|
33
|
+
default?: string;
|
|
34
|
+
note?: string;
|
|
35
|
+
}
|
|
36
|
+
/** One table / model. `id` is referenced by relations (`from`/`to`). */
|
|
37
|
+
export interface DataModelEntity {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
note?: string;
|
|
41
|
+
fields: DataModelField[];
|
|
42
|
+
}
|
|
43
|
+
/** An explicit relation between two entities, by `id` (or `name`). */
|
|
44
|
+
export interface DataModelRelation {
|
|
45
|
+
from: string;
|
|
46
|
+
to: string;
|
|
47
|
+
kind?: DataModelRelationKind;
|
|
48
|
+
label?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface DataModelData {
|
|
51
|
+
entities: DataModelEntity[];
|
|
52
|
+
relations?: DataModelRelation[];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Data-compatible with the inline `data-model` member of `planBlockSchema`
|
|
56
|
+
* (`plan-content.ts`). At least one entity is required; `relations` is optional
|
|
57
|
+
* (the Read renderer can infer simple `1-n` relations from `fk` fields when it is
|
|
58
|
+
* omitted) so a fresh model validates from a single entity with a couple fields.
|
|
59
|
+
*/
|
|
60
|
+
export declare const dataModelSchema: z.ZodType<DataModelData>;
|
|
61
|
+
/**
|
|
62
|
+
* MDX config: the whole `entities` and `relations` arrays are serialized as JSON
|
|
63
|
+
* props on a self-closing element — the `<DataModel id … entities={…}
|
|
64
|
+
* relations={…} />` form. `toAttrs` emits `entities` then `relations` in a STABLE
|
|
65
|
+
* order (the shared `prop()` encoder drops `relations` when it is undefined).
|
|
66
|
+
*
|
|
67
|
+
* `fromAttrs` tolerates missing/partial attributes for backward-compat: a missing
|
|
68
|
+
* `entities` decodes to `[]` and a missing `relations` decodes to `undefined` so
|
|
69
|
+
* a plan written before this block existed still parses.
|
|
70
|
+
*/
|
|
71
|
+
export declare const dataModelMdx: BlockMdxConfig<DataModelData>;
|
|
72
|
+
//# sourceMappingURL=data-model.config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-model.config.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/data-model.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,sDAAsD;AACtD,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAE1D,eAAO,MAAM,yBAAyB,EAAE,qBAAqB,EAI5D,CAAC;AAEF,kEAAkE;AAClE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,8EAA8E;IAC9E,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED,sEAAsE;AACtE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,qBAAqB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACjC;AA0BD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAGX,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;AAE1C;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,aAAa,CAUtD,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const DATA_MODEL_RELATION_KINDS = [
|
|
3
|
+
"1-1",
|
|
4
|
+
"1-n",
|
|
5
|
+
"n-n",
|
|
6
|
+
];
|
|
7
|
+
const fieldSchema = z.object({
|
|
8
|
+
name: z.string().trim().min(1).max(160),
|
|
9
|
+
type: z.string().trim().max(120).optional(),
|
|
10
|
+
pk: z.boolean().optional(),
|
|
11
|
+
fk: z.string().trim().max(200).optional(),
|
|
12
|
+
nullable: z.boolean().optional(),
|
|
13
|
+
default: z.string().trim().max(400).optional(),
|
|
14
|
+
note: z.string().trim().max(600).optional(),
|
|
15
|
+
});
|
|
16
|
+
const entitySchema = z.object({
|
|
17
|
+
id: z.string().trim().min(1).max(120),
|
|
18
|
+
name: z.string().trim().min(1).max(160),
|
|
19
|
+
note: z.string().trim().max(600).optional(),
|
|
20
|
+
fields: z.array(fieldSchema).max(80),
|
|
21
|
+
});
|
|
22
|
+
const relationSchema = z.object({
|
|
23
|
+
from: z.string().trim().min(1).max(120),
|
|
24
|
+
to: z.string().trim().min(1).max(120),
|
|
25
|
+
kind: z.enum(["1-1", "1-n", "n-n"]).optional(),
|
|
26
|
+
label: z.string().trim().max(160).optional(),
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Data-compatible with the inline `data-model` member of `planBlockSchema`
|
|
30
|
+
* (`plan-content.ts`). At least one entity is required; `relations` is optional
|
|
31
|
+
* (the Read renderer can infer simple `1-n` relations from `fk` fields when it is
|
|
32
|
+
* omitted) so a fresh model validates from a single entity with a couple fields.
|
|
33
|
+
*/
|
|
34
|
+
export const dataModelSchema = z.object({
|
|
35
|
+
entities: z.array(entitySchema).min(1).max(60),
|
|
36
|
+
relations: z.array(relationSchema).max(200).optional(),
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* MDX config: the whole `entities` and `relations` arrays are serialized as JSON
|
|
40
|
+
* props on a self-closing element — the `<DataModel id … entities={…}
|
|
41
|
+
* relations={…} />` form. `toAttrs` emits `entities` then `relations` in a STABLE
|
|
42
|
+
* order (the shared `prop()` encoder drops `relations` when it is undefined).
|
|
43
|
+
*
|
|
44
|
+
* `fromAttrs` tolerates missing/partial attributes for backward-compat: a missing
|
|
45
|
+
* `entities` decodes to `[]` and a missing `relations` decodes to `undefined` so
|
|
46
|
+
* a plan written before this block existed still parses.
|
|
47
|
+
*/
|
|
48
|
+
export const dataModelMdx = {
|
|
49
|
+
tag: "DataModel",
|
|
50
|
+
toAttrs: (data) => ({
|
|
51
|
+
entities: data.entities,
|
|
52
|
+
relations: data.relations,
|
|
53
|
+
}),
|
|
54
|
+
fromAttrs: (attrs) => ({
|
|
55
|
+
entities: attrs.array("entities") ?? [],
|
|
56
|
+
relations: attrs.array("relations"),
|
|
57
|
+
}),
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=data-model.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-model.config.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/data-model.config.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport type { BlockMdxConfig } from \"../types.js\";\n\n/**\n * Pure (React-free) part of the PLAN-SPECIFIC `data-model` block: its data schema\n * and MDX round-trip config. Shared by the server MDX adapter (`plan-mdx.ts` via\n * `plan-block-registry.ts`) and the client spec (`planBlocks.tsx`). Keeping this\n * React-free means importing it into a server module never pulls React into the\n * Nitro/SSR bundle.\n *\n * The block renders a dbdiagram / Prisma-style entity-relationship diagram: a set\n * of entity cards (each a small table of fields with PK / FK / nullable flags)\n * plus optional explicit relations. The Read renderer makes foreign keys\n * interactive — hovering / clicking an FK highlights and scrolls to the\n * referenced entity — which is why this is a custom block, not a plain table.\n *\n * The schema MUST stay data-compatible with the `data-model` branch of\n * `planBlockSchema` (`plan-content.ts`), and the MDX `tag` (`DataModel`) +\n * attribute shape MUST match the inline planBlockSchema member so stored `.mdx`\n * round-trips: the whole `entities` and `relations` arrays are JSON props\n * (`<DataModel id … entities={…} relations={…} />`).\n */\n\n/** Cardinality of a relation between two entities. */\nexport type DataModelRelationKind = \"1-1\" | \"1-n\" | \"n-n\";\n\nexport const DATA_MODEL_RELATION_KINDS: DataModelRelationKind[] = [\n \"1-1\",\n \"1-n\",\n \"n-n\",\n];\n\n/** One column of an entity. `fk` is a string like `\"User.id\"`. */\nexport interface DataModelField {\n name: string;\n type?: string;\n pk?: boolean;\n /** Foreign-key target, e.g. `\"User.id\"` (entity name/id + optional field). */\n fk?: string;\n nullable?: boolean;\n default?: string;\n note?: string;\n}\n\n/** One table / model. `id` is referenced by relations (`from`/`to`). */\nexport interface DataModelEntity {\n id: string;\n name: string;\n note?: string;\n fields: DataModelField[];\n}\n\n/** An explicit relation between two entities, by `id` (or `name`). */\nexport interface DataModelRelation {\n from: string;\n to: string;\n kind?: DataModelRelationKind;\n label?: string;\n}\n\nexport interface DataModelData {\n entities: DataModelEntity[];\n relations?: DataModelRelation[];\n}\n\nconst fieldSchema = z.object({\n name: z.string().trim().min(1).max(160),\n type: z.string().trim().max(120).optional(),\n pk: z.boolean().optional(),\n fk: z.string().trim().max(200).optional(),\n nullable: z.boolean().optional(),\n default: z.string().trim().max(400).optional(),\n note: z.string().trim().max(600).optional(),\n}) as z.ZodType<DataModelField>;\n\nconst entitySchema = z.object({\n id: z.string().trim().min(1).max(120),\n name: z.string().trim().min(1).max(160),\n note: z.string().trim().max(600).optional(),\n fields: z.array(fieldSchema).max(80),\n}) as z.ZodType<DataModelEntity>;\n\nconst relationSchema = z.object({\n from: z.string().trim().min(1).max(120),\n to: z.string().trim().min(1).max(120),\n kind: z.enum([\"1-1\", \"1-n\", \"n-n\"]).optional(),\n label: z.string().trim().max(160).optional(),\n}) as z.ZodType<DataModelRelation>;\n\n/**\n * Data-compatible with the inline `data-model` member of `planBlockSchema`\n * (`plan-content.ts`). At least one entity is required; `relations` is optional\n * (the Read renderer can infer simple `1-n` relations from `fk` fields when it is\n * omitted) so a fresh model validates from a single entity with a couple fields.\n */\nexport const dataModelSchema = z.object({\n entities: z.array(entitySchema).min(1).max(60),\n relations: z.array(relationSchema).max(200).optional(),\n}) as unknown as z.ZodType<DataModelData>;\n\n/**\n * MDX config: the whole `entities` and `relations` arrays are serialized as JSON\n * props on a self-closing element — the `<DataModel id … entities={…}\n * relations={…} />` form. `toAttrs` emits `entities` then `relations` in a STABLE\n * order (the shared `prop()` encoder drops `relations` when it is undefined).\n *\n * `fromAttrs` tolerates missing/partial attributes for backward-compat: a missing\n * `entities` decodes to `[]` and a missing `relations` decodes to `undefined` so\n * a plan written before this block existed still parses.\n */\nexport const dataModelMdx: BlockMdxConfig<DataModelData> = {\n tag: \"DataModel\",\n toAttrs: (data) => ({\n entities: data.entities,\n relations: data.relations,\n }),\n fromAttrs: (attrs) => ({\n entities: attrs.array<DataModelEntity>(\"entities\") ?? [],\n relations: attrs.array<DataModelRelation>(\"relations\"),\n }),\n};\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ComponentProps, InputHTMLAttributes, LabelHTMLAttributes, ReactNode, TextareaHTMLAttributes } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal, app-agnostic form primitives for the core "dev-doc" block library
|
|
4
|
+
* (mermaid / api-endpoint / data-model / diff / file-tree / json-explorer /
|
|
5
|
+
* annotated-code). These blocks previously imported the plan app's shadcn/ui
|
|
6
|
+
* components (`@/components/ui/*`); core blocks must stay portable, so these are
|
|
7
|
+
* plain styled elements that reproduce the SAME shadcn Tailwind classes byte-for
|
|
8
|
+
* -byte. They resolve against whatever shadcn token theme (`border-input`,
|
|
9
|
+
* `bg-background`, `ring-ring`, …) the host app ships, so the rendered look is
|
|
10
|
+
* unchanged across apps.
|
|
11
|
+
*
|
|
12
|
+
* The Select is intentionally a NATIVE `<select>` styled to match the shadcn
|
|
13
|
+
* trigger rather than a Radix popover: it keeps core dependency-free and behaves
|
|
14
|
+
* identically for the simple enum pickers these editors use (method, change,
|
|
15
|
+
* param location, diff mode).
|
|
16
|
+
*/
|
|
17
|
+
export declare const DevInput: import("react").ForwardRefExoticComponent<InputHTMLAttributes<HTMLInputElement> & import("react").RefAttributes<HTMLInputElement>>;
|
|
18
|
+
export declare const DevLabel: import("react").ForwardRefExoticComponent<LabelHTMLAttributes<HTMLLabelElement> & import("react").RefAttributes<HTMLLabelElement>>;
|
|
19
|
+
export declare const DevTextarea: import("react").ForwardRefExoticComponent<TextareaHTMLAttributes<HTMLTextAreaElement> & import("react").RefAttributes<HTMLTextAreaElement>>;
|
|
20
|
+
/** Only the `outline` badge variant is used by these blocks. */
|
|
21
|
+
export declare function DevBadge({ className, ...props }: ComponentProps<"span">): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
/**
|
|
23
|
+
* A native-checkbox toggle styled to read like the shadcn Switch. `onCheckedChange`
|
|
24
|
+
* mirrors the shadcn/Radix API so call sites stay identical.
|
|
25
|
+
*/
|
|
26
|
+
export declare function DevSwitch({ checked, onCheckedChange, disabled, className, ...props }: {
|
|
27
|
+
checked: boolean;
|
|
28
|
+
onCheckedChange: (checked: boolean) => void;
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
className?: string;
|
|
31
|
+
} & Omit<InputHTMLAttributes<HTMLButtonElement>, "onChange" | "checked" | "type">): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export interface DevSelectOption {
|
|
33
|
+
value: string;
|
|
34
|
+
label: ReactNode;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A native `<select>` styled to match the shadcn SelectTrigger. Drop-in for the
|
|
38
|
+
* simple enum pickers the dev-doc editors use. `onValueChange` mirrors the shadcn
|
|
39
|
+
* API. The chevron is positioned over the native control.
|
|
40
|
+
*/
|
|
41
|
+
export declare function DevSelect({ value, onValueChange, options, disabled, className, "aria-label": ariaLabel, }: {
|
|
42
|
+
value: string;
|
|
43
|
+
onValueChange: (value: string) => void;
|
|
44
|
+
options: DevSelectOption[];
|
|
45
|
+
disabled?: boolean;
|
|
46
|
+
className?: string;
|
|
47
|
+
"aria-label"?: string;
|
|
48
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
49
|
+
//# sourceMappingURL=dev-doc-ui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-doc-ui.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/dev-doc-ui.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,SAAS,EACT,sBAAsB,EACvB,MAAM,OAAO,CAAC;AAIf;;;;;;;;;;;;;;GAcG;AAIH,eAAO,MAAM,QAAQ,oIAanB,CAAC;AAKH,eAAO,MAAM,QAAQ,oIAYnB,CAAC;AAKH,eAAO,MAAM,WAAW,6IAYtB,CAAC;AAKH,gEAAgE;AAChE,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,CAAC,MAAM,CAAC,2CAUvE;AAID;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EACxB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CACN,mBAAmB,CAAC,iBAAiB,CAAC,EACtC,UAAU,GAAG,SAAS,GAAG,MAAM,CAChC,2CAwBA;AAID,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,aAAa,EACb,OAAO,EACP,QAAQ,EACR,SAAS,EACT,YAAY,EAAE,SAAS,GACxB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,2CAsBA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { IconChevronDown } from "@tabler/icons-react";
|
|
4
|
+
import { cn } from "../../utils.js";
|
|
5
|
+
/**
|
|
6
|
+
* Minimal, app-agnostic form primitives for the core "dev-doc" block library
|
|
7
|
+
* (mermaid / api-endpoint / data-model / diff / file-tree / json-explorer /
|
|
8
|
+
* annotated-code). These blocks previously imported the plan app's shadcn/ui
|
|
9
|
+
* components (`@/components/ui/*`); core blocks must stay portable, so these are
|
|
10
|
+
* plain styled elements that reproduce the SAME shadcn Tailwind classes byte-for
|
|
11
|
+
* -byte. They resolve against whatever shadcn token theme (`border-input`,
|
|
12
|
+
* `bg-background`, `ring-ring`, …) the host app ships, so the rendered look is
|
|
13
|
+
* unchanged across apps.
|
|
14
|
+
*
|
|
15
|
+
* The Select is intentionally a NATIVE `<select>` styled to match the shadcn
|
|
16
|
+
* trigger rather than a Radix popover: it keeps core dependency-free and behaves
|
|
17
|
+
* identically for the simple enum pickers these editors use (method, change,
|
|
18
|
+
* param location, diff mode).
|
|
19
|
+
*/
|
|
20
|
+
/* ── Input ─────────────────────────────────────────────────────────────────── */
|
|
21
|
+
export const DevInput = forwardRef(({ className, type, ...props }, ref) => (_jsx("input", { ref: ref, type: type, className: cn("flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", className), ...props })));
|
|
22
|
+
DevInput.displayName = "DevInput";
|
|
23
|
+
/* ── Label ─────────────────────────────────────────────────────────────────── */
|
|
24
|
+
export const DevLabel = forwardRef(({ className, ...props }, ref) => (_jsx("label", { ref: ref, className: cn("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", className), ...props })));
|
|
25
|
+
DevLabel.displayName = "DevLabel";
|
|
26
|
+
/* ── Textarea ──────────────────────────────────────────────────────────────── */
|
|
27
|
+
export const DevTextarea = forwardRef(({ className, ...props }, ref) => (_jsx("textarea", { ref: ref, className: cn("flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", className), ...props })));
|
|
28
|
+
DevTextarea.displayName = "DevTextarea";
|
|
29
|
+
/* ── Badge ─────────────────────────────────────────────────────────────────── */
|
|
30
|
+
/** Only the `outline` badge variant is used by these blocks. */
|
|
31
|
+
export function DevBadge({ className, ...props }) {
|
|
32
|
+
return (_jsx("span", { className: cn("inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-foreground", className), ...props }));
|
|
33
|
+
}
|
|
34
|
+
/* ── Switch ────────────────────────────────────────────────────────────────── */
|
|
35
|
+
/**
|
|
36
|
+
* A native-checkbox toggle styled to read like the shadcn Switch. `onCheckedChange`
|
|
37
|
+
* mirrors the shadcn/Radix API so call sites stay identical.
|
|
38
|
+
*/
|
|
39
|
+
export function DevSwitch({ checked, onCheckedChange, disabled, className, ...props }) {
|
|
40
|
+
return (_jsx("button", { type: "button", role: "switch", "aria-checked": checked, disabled: disabled, "data-plan-interactive": true, onClick: () => onCheckedChange(!checked), className: cn("peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50", checked ? "bg-primary" : "bg-input", className), ...props, children: _jsx("span", { className: cn("pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform", checked ? "translate-x-5" : "translate-x-0") }) }));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A native `<select>` styled to match the shadcn SelectTrigger. Drop-in for the
|
|
44
|
+
* simple enum pickers the dev-doc editors use. `onValueChange` mirrors the shadcn
|
|
45
|
+
* API. The chevron is positioned over the native control.
|
|
46
|
+
*/
|
|
47
|
+
export function DevSelect({ value, onValueChange, options, disabled, className, "aria-label": ariaLabel, }) {
|
|
48
|
+
return (_jsxs("div", { className: cn("relative", className), children: [_jsx("select", { value: value, disabled: disabled, "aria-label": ariaLabel, "data-plan-interactive": true, onChange: (event) => onValueChange(event.target.value), className: cn("flex h-10 w-full appearance-none items-center justify-between rounded-md border border-input bg-background px-3 py-2 pr-8 text-sm ring-offset-background focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"), children: options.map((option) => (_jsx("option", { value: option.value, children: typeof option.label === "string" ? option.label : option.value }, option.value))) }), _jsx(IconChevronDown, { className: "pointer-events-none absolute right-2.5 top-1/2 size-4 -translate-y-1/2 opacity-50" })] }));
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=dev-doc-ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-doc-ui.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/dev-doc-ui.tsx"],"names":[],"mappings":"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","sourcesContent":["import { forwardRef } from \"react\";\nimport type {\n ComponentProps,\n InputHTMLAttributes,\n LabelHTMLAttributes,\n ReactNode,\n TextareaHTMLAttributes,\n} from \"react\";\nimport { IconChevronDown } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\n\n/**\n * Minimal, app-agnostic form primitives for the core \"dev-doc\" block library\n * (mermaid / api-endpoint / data-model / diff / file-tree / json-explorer /\n * annotated-code). These blocks previously imported the plan app's shadcn/ui\n * components (`@/components/ui/*`); core blocks must stay portable, so these are\n * plain styled elements that reproduce the SAME shadcn Tailwind classes byte-for\n * -byte. They resolve against whatever shadcn token theme (`border-input`,\n * `bg-background`, `ring-ring`, …) the host app ships, so the rendered look is\n * unchanged across apps.\n *\n * The Select is intentionally a NATIVE `<select>` styled to match the shadcn\n * trigger rather than a Radix popover: it keeps core dependency-free and behaves\n * identically for the simple enum pickers these editors use (method, change,\n * param location, diff mode).\n */\n\n/* ── Input ─────────────────────────────────────────────────────────────────── */\n\nexport const DevInput = forwardRef<\n HTMLInputElement,\n InputHTMLAttributes<HTMLInputElement>\n>(({ className, type, ...props }, ref) => (\n <input\n ref={ref}\n type={type}\n className={cn(\n \"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className,\n )}\n {...props}\n />\n));\nDevInput.displayName = \"DevInput\";\n\n/* ── Label ─────────────────────────────────────────────────────────────────── */\n\nexport const DevLabel = forwardRef<\n HTMLLabelElement,\n LabelHTMLAttributes<HTMLLabelElement>\n>(({ className, ...props }, ref) => (\n <label\n ref={ref}\n className={cn(\n \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n className,\n )}\n {...props}\n />\n));\nDevLabel.displayName = \"DevLabel\";\n\n/* ── Textarea ──────────────────────────────────────────────────────────────── */\n\nexport const DevTextarea = forwardRef<\n HTMLTextAreaElement,\n TextareaHTMLAttributes<HTMLTextAreaElement>\n>(({ className, ...props }, ref) => (\n <textarea\n ref={ref}\n className={cn(\n \"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n {...props}\n />\n));\nDevTextarea.displayName = \"DevTextarea\";\n\n/* ── Badge ─────────────────────────────────────────────────────────────────── */\n\n/** Only the `outline` badge variant is used by these blocks. */\nexport function DevBadge({ className, ...props }: ComponentProps<\"span\">) {\n return (\n <span\n className={cn(\n \"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-foreground\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/* ── Switch ────────────────────────────────────────────────────────────────── */\n\n/**\n * A native-checkbox toggle styled to read like the shadcn Switch. `onCheckedChange`\n * mirrors the shadcn/Radix API so call sites stay identical.\n */\nexport function DevSwitch({\n checked,\n onCheckedChange,\n disabled,\n className,\n ...props\n}: {\n checked: boolean;\n onCheckedChange: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n} & Omit<\n InputHTMLAttributes<HTMLButtonElement>,\n \"onChange\" | \"checked\" | \"type\"\n>) {\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n disabled={disabled}\n data-plan-interactive\n onClick={() => onCheckedChange(!checked)}\n className={cn(\n \"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50\",\n checked ? \"bg-primary\" : \"bg-input\",\n className,\n )}\n {...(props as Record<string, unknown>)}\n >\n <span\n className={cn(\n \"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform\",\n checked ? \"translate-x-5\" : \"translate-x-0\",\n )}\n />\n </button>\n );\n}\n\n/* ── Select (native, shadcn-trigger styled) ────────────────────────────────── */\n\nexport interface DevSelectOption {\n value: string;\n label: ReactNode;\n}\n\n/**\n * A native `<select>` styled to match the shadcn SelectTrigger. Drop-in for the\n * simple enum pickers the dev-doc editors use. `onValueChange` mirrors the shadcn\n * API. The chevron is positioned over the native control.\n */\nexport function DevSelect({\n value,\n onValueChange,\n options,\n disabled,\n className,\n \"aria-label\": ariaLabel,\n}: {\n value: string;\n onValueChange: (value: string) => void;\n options: DevSelectOption[];\n disabled?: boolean;\n className?: string;\n \"aria-label\"?: string;\n}) {\n return (\n <div className={cn(\"relative\", className)}>\n <select\n value={value}\n disabled={disabled}\n aria-label={ariaLabel}\n data-plan-interactive\n onChange={(event) => onValueChange(event.target.value)}\n className={cn(\n \"flex h-10 w-full appearance-none items-center justify-between rounded-md border border-input bg-background px-3 py-2 pr-8 text-sm ring-offset-background focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n )}\n >\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {typeof option.label === \"string\" ? option.label : option.value}\n </option>\n ))}\n </select>\n <IconChevronDown className=\"pointer-events-none absolute right-2.5 top-1/2 size-4 -translate-y-1/2 opacity-50\" />\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { BlockMdxConfig } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Pure (React-free) part of the PLAN-SPECIFIC diff block: its data schema and MDX
|
|
5
|
+
* round-trip config. Shared by the server MDX adapter (`plan-mdx.ts` via
|
|
6
|
+
* `plan-block-registry.ts`) and the client spec (`planBlocks.tsx`). Keeping this
|
|
7
|
+
* React-free means importing it into a server module never pulls React (or the
|
|
8
|
+
* `diff` line-differ used only by the renderer) into the Nitro/SSR bundle.
|
|
9
|
+
*
|
|
10
|
+
* The schema MUST stay data-compatible with the `diff` branch of `planBlockSchema`
|
|
11
|
+
* (`plan-content.ts`), and the MDX `tag` + flat attribute shape MUST match the
|
|
12
|
+
* `<Diff filename language mode before after />` self-closing encoding so stored
|
|
13
|
+
* `.mdx` round-trips. The `before`/`after` source lives in ATTRIBUTES (not MDX
|
|
14
|
+
* children) — the shared `prop()` encoder round-trips multiline strings cleanly,
|
|
15
|
+
* and keeping them attributes avoids the code being reflowed as prose.
|
|
16
|
+
*/
|
|
17
|
+
/** Rendering layout for the diff body. */
|
|
18
|
+
export type DiffMode = "unified" | "split";
|
|
19
|
+
export interface DiffData {
|
|
20
|
+
/** Optional file path shown in the header (e.g. `src/add.ts`). */
|
|
21
|
+
filename?: string;
|
|
22
|
+
/** Optional language label rendered as a chip (e.g. `ts`). Purely cosmetic. */
|
|
23
|
+
language?: string;
|
|
24
|
+
/** Original ("before") source. */
|
|
25
|
+
before: string;
|
|
26
|
+
/** New ("after") source. */
|
|
27
|
+
after: string;
|
|
28
|
+
/** Layout: unified (default, one column) or split (side-by-side). */
|
|
29
|
+
mode?: DiffMode;
|
|
30
|
+
}
|
|
31
|
+
export declare const diffSchema: z.ZodType<DiffData>;
|
|
32
|
+
/**
|
|
33
|
+
* MDX config: `filename`, `language`, `mode`, `before`, and `after` are flat
|
|
34
|
+
* attributes — the `<Diff id … filename language mode before after />`
|
|
35
|
+
* self-closing form. Insertion order of `toAttrs` is the on-disk attribute order.
|
|
36
|
+
* `fromAttrs` mirrors a forgiving parse (`before ?? ""`, `after ?? ""`, optional
|
|
37
|
+
* `filename`/`language`/`mode` undefined when absent) so a plan missing an
|
|
38
|
+
* attribute still parses.
|
|
39
|
+
*/
|
|
40
|
+
export declare const diffMdx: BlockMdxConfig<DiffData>;
|
|
41
|
+
//# sourceMappingURL=diff.config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.config.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/diff.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;;;;;GAaG;AAEH,0CAA0C;AAC1C,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAE3C,MAAM,WAAW,QAAQ;IACvB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,eAAO,MAAM,UAAU,EAMN,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAErC;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,EAAE,cAAc,CAAC,QAAQ,CAgB5C,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const diffSchema = z.object({
|
|
3
|
+
filename: z.string().trim().max(400).optional(),
|
|
4
|
+
language: z.string().trim().max(40).optional(),
|
|
5
|
+
before: z.string().max(100_000),
|
|
6
|
+
after: z.string().max(100_000),
|
|
7
|
+
mode: z.enum(["unified", "split"]).optional(),
|
|
8
|
+
});
|
|
9
|
+
/**
|
|
10
|
+
* MDX config: `filename`, `language`, `mode`, `before`, and `after` are flat
|
|
11
|
+
* attributes — the `<Diff id … filename language mode before after />`
|
|
12
|
+
* self-closing form. Insertion order of `toAttrs` is the on-disk attribute order.
|
|
13
|
+
* `fromAttrs` mirrors a forgiving parse (`before ?? ""`, `after ?? ""`, optional
|
|
14
|
+
* `filename`/`language`/`mode` undefined when absent) so a plan missing an
|
|
15
|
+
* attribute still parses.
|
|
16
|
+
*/
|
|
17
|
+
export const diffMdx = {
|
|
18
|
+
tag: "Diff",
|
|
19
|
+
toAttrs: (data) => ({
|
|
20
|
+
filename: data.filename,
|
|
21
|
+
language: data.language,
|
|
22
|
+
mode: data.mode,
|
|
23
|
+
before: data.before,
|
|
24
|
+
after: data.after,
|
|
25
|
+
}),
|
|
26
|
+
fromAttrs: (attrs) => ({
|
|
27
|
+
filename: attrs.string("filename"),
|
|
28
|
+
language: attrs.string("language"),
|
|
29
|
+
mode: attrs.string("mode"),
|
|
30
|
+
before: attrs.string("before") ?? "",
|
|
31
|
+
after: attrs.string("after") ?? "",
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=diff.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.config.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/diff.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkCxB,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC/C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC9C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;IAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;IAC9B,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC9C,CAAmC,CAAC;AAErC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,OAAO,GAA6B;IAC/C,GAAG,EAAE,MAAM;IACX,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC;IACF,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACrB,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;QAClC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;QAClC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAyB;QAClD,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;QACpC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE;KACnC,CAAC;CACH,CAAC","sourcesContent":["import { z } from \"zod\";\nimport type { BlockMdxConfig } from \"../types.js\";\n\n/**\n * Pure (React-free) part of the PLAN-SPECIFIC diff block: its data schema and MDX\n * round-trip config. Shared by the server MDX adapter (`plan-mdx.ts` via\n * `plan-block-registry.ts`) and the client spec (`planBlocks.tsx`). Keeping this\n * React-free means importing it into a server module never pulls React (or the\n * `diff` line-differ used only by the renderer) into the Nitro/SSR bundle.\n *\n * The schema MUST stay data-compatible with the `diff` branch of `planBlockSchema`\n * (`plan-content.ts`), and the MDX `tag` + flat attribute shape MUST match the\n * `<Diff filename language mode before after />` self-closing encoding so stored\n * `.mdx` round-trips. The `before`/`after` source lives in ATTRIBUTES (not MDX\n * children) — the shared `prop()` encoder round-trips multiline strings cleanly,\n * and keeping them attributes avoids the code being reflowed as prose.\n */\n\n/** Rendering layout for the diff body. */\nexport type DiffMode = \"unified\" | \"split\";\n\nexport interface DiffData {\n /** Optional file path shown in the header (e.g. `src/add.ts`). */\n filename?: string;\n /** Optional language label rendered as a chip (e.g. `ts`). Purely cosmetic. */\n language?: string;\n /** Original (\"before\") source. */\n before: string;\n /** New (\"after\") source. */\n after: string;\n /** Layout: unified (default, one column) or split (side-by-side). */\n mode?: DiffMode;\n}\n\nexport const diffSchema = z.object({\n filename: z.string().trim().max(400).optional(),\n language: z.string().trim().max(40).optional(),\n before: z.string().max(100_000),\n after: z.string().max(100_000),\n mode: z.enum([\"unified\", \"split\"]).optional(),\n}) as unknown as z.ZodType<DiffData>;\n\n/**\n * MDX config: `filename`, `language`, `mode`, `before`, and `after` are flat\n * attributes — the `<Diff id … filename language mode before after />`\n * self-closing form. Insertion order of `toAttrs` is the on-disk attribute order.\n * `fromAttrs` mirrors a forgiving parse (`before ?? \"\"`, `after ?? \"\"`, optional\n * `filename`/`language`/`mode` undefined when absent) so a plan missing an\n * attribute still parses.\n */\nexport const diffMdx: BlockMdxConfig<DiffData> = {\n tag: \"Diff\",\n toAttrs: (data) => ({\n filename: data.filename,\n language: data.language,\n mode: data.mode,\n before: data.before,\n after: data.after,\n }),\n fromAttrs: (attrs) => ({\n filename: attrs.string(\"filename\"),\n language: attrs.string(\"language\"),\n mode: attrs.string(\"mode\") as DiffMode | undefined,\n before: attrs.string(\"before\") ?? \"\",\n after: attrs.string(\"after\") ?? \"\",\n }),\n};\n"]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { BlockMdxConfig } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Pure (React-free) part of the PLAN-SPECIFIC `file-tree` block: its data schema
|
|
5
|
+
* and MDX round-trip config. Shared by the server MDX adapter (`plan-mdx.ts` via
|
|
6
|
+
* `plan-block-registry.ts`) and the client spec (`planBlocks.tsx`). Keeping this
|
|
7
|
+
* React-free means importing it into a server module never pulls React into the
|
|
8
|
+
* Nitro/SSR bundle.
|
|
9
|
+
*
|
|
10
|
+
* The block renders a VS Code / GitHub-explorer style file/change tree: a flat
|
|
11
|
+
* list of `entries` (each a slash-delimited `path` with an optional change kind,
|
|
12
|
+
* note, and code snippet) from which the RENDERER derives the nested folder tree
|
|
13
|
+
* — the model never carries the folder structure, only the leaf paths. This keeps
|
|
14
|
+
* the data lean and the tree always consistent with the paths.
|
|
15
|
+
*
|
|
16
|
+
* The schema MUST stay data-compatible with the `file-tree` member of
|
|
17
|
+
* `planBlockSchema` (`plan-content.ts`), and the MDX `tag` (`FileTree`) +
|
|
18
|
+
* attribute shape MUST match it so stored `.mdx` round-trips: the whole `entries`
|
|
19
|
+
* array is one JSON prop (`<FileTree id … title entries={…} />`).
|
|
20
|
+
*/
|
|
21
|
+
/** The kind of change applied to a file, driving its change badge. */
|
|
22
|
+
export type FileTreeChange = "added" | "modified" | "removed" | "renamed";
|
|
23
|
+
export declare const FILE_TREE_CHANGES: FileTreeChange[];
|
|
24
|
+
/**
|
|
25
|
+
* One file in the tree. `path` is slash-delimited (`src/routes/git.ts`); the
|
|
26
|
+
* renderer derives the folder structure from its segments. `change` drives the
|
|
27
|
+
* change badge (A/M/D/R); `note` + `snippet` (with optional `language`) make the
|
|
28
|
+
* file row expandable to show why it changes and a code preview.
|
|
29
|
+
*/
|
|
30
|
+
export interface FileTreeEntry {
|
|
31
|
+
path: string;
|
|
32
|
+
change?: FileTreeChange;
|
|
33
|
+
note?: string;
|
|
34
|
+
snippet?: string;
|
|
35
|
+
language?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface FileTreeData {
|
|
38
|
+
/** Optional heading shown above the tree (e.g. "Files touched"). */
|
|
39
|
+
title?: string;
|
|
40
|
+
entries: FileTreeEntry[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Data-compatible with the inline `file-tree` member of `planBlockSchema`
|
|
44
|
+
* (`plan-content.ts`). `entries` is required (at least one file); `title` is
|
|
45
|
+
* optional so a fresh tree validates from a couple of files.
|
|
46
|
+
*/
|
|
47
|
+
export declare const fileTreeSchema: z.ZodType<FileTreeData>;
|
|
48
|
+
/**
|
|
49
|
+
* MDX config: `title` is a flat string attribute and the whole `entries` array is
|
|
50
|
+
* serialized as one JSON prop on a self-closing element — the `<FileTree id …
|
|
51
|
+
* title entries={…} />` form. `toAttrs` emits `title` then `entries` in a STABLE
|
|
52
|
+
* order (the shared `prop()` encoder drops `title` when it is undefined).
|
|
53
|
+
*
|
|
54
|
+
* `fromAttrs` tolerates missing/partial attributes for backward-compat: a missing
|
|
55
|
+
* `title` decodes to `undefined` and a missing `entries` decodes to `[]` so a
|
|
56
|
+
* plan written before this block existed still parses.
|
|
57
|
+
*/
|
|
58
|
+
export declare const fileTreeMdx: BlockMdxConfig<FileTreeData>;
|
|
59
|
+
//# sourceMappingURL=file-tree.config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-tree.config.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/file-tree.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;;;;;;;;;GAiBG;AAEH,sEAAsE;AACtE,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAE1E,eAAO,MAAM,iBAAiB,EAAE,cAAc,EAK7C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAUD;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAGV,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;AAEzC;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,EAAE,cAAc,CAAC,YAAY,CAUpD,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const FILE_TREE_CHANGES = [
|
|
3
|
+
"added",
|
|
4
|
+
"modified",
|
|
5
|
+
"removed",
|
|
6
|
+
"renamed",
|
|
7
|
+
];
|
|
8
|
+
const entrySchema = z.object({
|
|
9
|
+
path: z.string().trim().min(1).max(500),
|
|
10
|
+
change: z.enum(["added", "modified", "removed", "renamed"]).optional(),
|
|
11
|
+
note: z.string().trim().max(2_000).optional(),
|
|
12
|
+
snippet: z.string().max(50_000).optional(),
|
|
13
|
+
language: z.string().trim().max(40).optional(),
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* Data-compatible with the inline `file-tree` member of `planBlockSchema`
|
|
17
|
+
* (`plan-content.ts`). `entries` is required (at least one file); `title` is
|
|
18
|
+
* optional so a fresh tree validates from a couple of files.
|
|
19
|
+
*/
|
|
20
|
+
export const fileTreeSchema = z.object({
|
|
21
|
+
title: z.string().trim().max(180).optional(),
|
|
22
|
+
entries: z.array(entrySchema).min(1).max(200),
|
|
23
|
+
});
|
|
24
|
+
/**
|
|
25
|
+
* MDX config: `title` is a flat string attribute and the whole `entries` array is
|
|
26
|
+
* serialized as one JSON prop on a self-closing element — the `<FileTree id …
|
|
27
|
+
* title entries={…} />` form. `toAttrs` emits `title` then `entries` in a STABLE
|
|
28
|
+
* order (the shared `prop()` encoder drops `title` when it is undefined).
|
|
29
|
+
*
|
|
30
|
+
* `fromAttrs` tolerates missing/partial attributes for backward-compat: a missing
|
|
31
|
+
* `title` decodes to `undefined` and a missing `entries` decodes to `[]` so a
|
|
32
|
+
* plan written before this block existed still parses.
|
|
33
|
+
*/
|
|
34
|
+
export const fileTreeMdx = {
|
|
35
|
+
tag: "FileTree",
|
|
36
|
+
toAttrs: (data) => ({
|
|
37
|
+
title: data.title,
|
|
38
|
+
entries: data.entries,
|
|
39
|
+
}),
|
|
40
|
+
fromAttrs: (attrs) => ({
|
|
41
|
+
title: attrs.string("title"),
|
|
42
|
+
entries: attrs.array("entries") ?? [],
|
|
43
|
+
}),
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=file-tree.config.js.map
|