@p4code/cli 0.1.22 → 0.1.23
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/bin.mjs +587 -29
- package/dist/client/assets/Diagram-CP713Hf0.js +3 -0
- package/dist/client/assets/DiffPanel-D0McnRVJ.js +98 -0
- package/dist/client/assets/FilePreviewPanel-CBdYEmtx.js +1778 -0
- package/dist/client/assets/PreviewPanel-F4V0X333.js +2 -0
- package/dist/client/assets/abnfDiagram-N423BO3Z-BYQKJNsP.js +2 -0
- package/dist/client/assets/angular-html-BVBpGdXr.js +2 -0
- package/dist/client/assets/{angular-ts-CXoIeuGh.js → angular-ts-BfdufMKP.js} +2 -2
- package/dist/client/assets/{apl-C6oPUNZZ.js → apl-DWBSSoBH.js} +2 -2
- package/dist/client/assets/arc-BjSQqbzd.js +2 -0
- package/dist/client/assets/architecture-TIHT7OUA-DOwndo9a.js +1 -0
- package/dist/client/assets/architectureDiagram-T3A2C74G-Dkoxezw8.js +37 -0
- package/dist/client/assets/array-BifhSqXX.js +2 -0
- package/dist/client/assets/arrow-right-Fc_jCzG8.js +2 -0
- package/dist/client/assets/{astro-Bq_n5uKv.js → astro-3LtMP0Sq.js} +2 -2
- package/dist/client/assets/{blade-DYe65h_C.js → blade-llJRbbtR.js} +2 -2
- package/dist/client/assets/blockDiagram-VBNYF7ZC-sVeCAPAa.js +133 -0
- package/dist/client/assets/c-Wt1voDr2.js +2 -0
- package/dist/client/assets/c4Diagram-5PPSVZJV-CW_Wfxep.js +11 -0
- package/dist/client/assets/channel-Cc8SQh1U.js +2 -0
- package/dist/client/assets/chunk-2GRJ4B5K-ChihPphX.js +2 -0
- package/dist/client/assets/chunk-2Q5K7J3B-C1jixKkw.js +2 -0
- package/dist/client/assets/chunk-3NCLNEKW-lgePDcrq.js +2 -0
- package/dist/client/assets/chunk-4I5QYGJK-CYvb6li-.js +2 -0
- package/dist/client/assets/chunk-5RXB4S5H-BzE89W2t.js +232 -0
- package/dist/client/assets/chunk-5VM5RSS4-ZNzvKenW.js +16 -0
- package/dist/client/assets/chunk-6Q2QTUOP-CyDe-FPc.js +89 -0
- package/dist/client/assets/chunk-7BUUIJ7U-Bb538aSH.js +2 -0
- package/dist/client/assets/chunk-7Z6QIM7H-kaZRbPTV.js +11 -0
- package/dist/client/assets/chunk-GF5L2VYU-CHJWyX-t.js +207 -0
- package/dist/client/assets/chunk-I66GZJ75-CJWXi3bs.js +128 -0
- package/dist/client/assets/chunk-J7OUQ5F2-D19QWtqC.js +3 -0
- package/dist/client/assets/chunk-JQJVKLGR-oHxUxbQ4.js +157 -0
- package/dist/client/assets/chunk-JWPE2WC7-DVXcaiue.js +2 -0
- package/dist/client/assets/chunk-KBJHAD2P-D81b6htr.js +2 -0
- package/dist/client/assets/chunk-KEIR6QF5-BfrZ3jm6.js +162 -0
- package/dist/client/assets/chunk-NSK5VX7P-CoeZ_Lgi.js +3 -0
- package/dist/client/assets/chunk-QR6OTTB3-D0IyLhez.js +63 -0
- package/dist/client/assets/chunk-RYQCIY6F-CZ4ia6G4.js +2 -0
- package/dist/client/assets/chunk-UBXNYLIW-F4hmeeiG.js +2 -0
- package/dist/client/assets/chunk-W5SLKNZC-Bwmo9x3j.js +2 -0
- package/dist/client/assets/chunk-WRU74C26-C2Rb3ATV.js +71 -0
- package/dist/client/assets/chunk-XXDRQBXY-BuE3VzE_.js +2 -0
- package/dist/client/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +2 -0
- package/dist/client/assets/chunk-ZIRB5QZD-C6fEPe3t.js +33 -0
- package/dist/client/assets/classDiagram-JCYQIIEL-oYJOinll.js +2 -0
- package/dist/client/assets/classDiagram-v2-OCEON4UE-oYJOinll.js +2 -0
- package/dist/client/assets/{cobol-CoC31Rpg.js → cobol-x_HIyl2P.js} +2 -2
- package/dist/client/assets/{coffee-DU1_O9cH.js → coffee-CThvmt4R.js} +2 -2
- package/dist/client/assets/compiler-runtime-CLAvuQ-D.js +2 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-CU59zlcZ.js +2 -0
- package/dist/client/assets/cpp-NtAeskI3.js +2 -0
- package/dist/client/assets/{crystal-3iIyvfhL.js → crystal-DNu_sX0G.js} +2 -2
- package/dist/client/assets/css-DJp_X0uY.js +2 -0
- package/dist/client/assets/cynefin-VYW2F7L2-CjLioxN7.js +1 -0
- package/dist/client/assets/cynefinDiagram-MW4NZA55-DvNvdTNB.js +63 -0
- package/dist/client/assets/cytoscape.esm-B3I8pqwA.js +322 -0
- package/dist/client/assets/dagre-CXRCoUWR.js +2 -0
- package/dist/client/assets/dagre-VZM6K2ZE-bNpBL3bS.js +5 -0
- package/dist/client/assets/defaultLocale-C8Fc0cco.js +2 -0
- package/dist/client/assets/diagram-7IWD3JNH-DJveh2nY.js +31 -0
- package/dist/client/assets/diagram-B4RE2ZJO-CslhjucF.js +4 -0
- package/dist/client/assets/diagram-LBJQPF4R-DrVsyR2w.js +25 -0
- package/dist/client/assets/diagram-Q27KOJAE-Dp_H6G_V.js +25 -0
- package/dist/client/assets/diagram-UB23O5K3-ttWj4O6A.js +42 -0
- package/dist/client/assets/dist-D9sYb5Oa.js +2 -0
- package/dist/client/assets/ebnfDiagram-BXEA7PRR-DU7xTW-M.js +2 -0
- package/dist/client/assets/{edge--YoYp8s_.js → edge-ozw5tpLl.js} +2 -2
- package/dist/client/assets/{elixir-CZ1wqlQn.js → elixir-VhA6FeZt.js} +2 -2
- package/dist/client/assets/{elm-DKdyYY92.js → elm-dREJmIFz.js} +2 -2
- package/dist/client/assets/erDiagram-JOGREHBK-J8OGMeJ9.js +86 -0
- package/dist/client/assets/{erb-PeUqy_9N.js → erb-CIg6G69l.js} +2 -2
- package/dist/client/assets/eventmodeling-45OFAUF4-bPdt--LC.js +1 -0
- package/dist/client/assets/fileCommentAnnotations-BvEFhUAB.js +2 -0
- package/dist/client/assets/flowDiagram-UKHOOZJN-Xh4ZxM-b.js +1 -0
- package/dist/client/assets/ganttDiagram-PKOTCBZU-CTzbq3xg.js +293 -0
- package/dist/client/assets/{git-rebase-1Z5OxWid.js → git-rebase-B44mJPta.js} +2 -2
- package/dist/client/assets/gitGraph-TEB2WS4Q-D4WztIzM.js +1 -0
- package/dist/client/assets/gitGraphDiagram-DS77QQ5N-BYWChpgP.js +107 -0
- package/dist/client/assets/{glimmer-js-Br0y4u5b.js → glimmer-js-vH_gHG0-.js} +2 -2
- package/dist/client/assets/{glimmer-ts-Oh0AMNJv.js → glimmer-ts--abOzSAQ.js} +2 -2
- package/dist/client/assets/glsl-Dv5r7kPw.js +2 -0
- package/dist/client/assets/graphlib-B8gBHxth.js +2 -0
- package/dist/client/assets/graphql-CB4jsw2E.js +2 -0
- package/dist/client/assets/{hack-4xJQMtbZ.js → hack-DvEYX148.js} +2 -2
- package/dist/client/assets/haml-zE6W3STP.js +2 -0
- package/dist/client/assets/{handlebars-Znb8TzWA.js → handlebars-CzBR2SDs.js} +2 -2
- package/dist/client/assets/html-C8UlPnhE.js +2 -0
- package/dist/client/assets/{html-derivative-D6Fn1mLE.js → html-derivative-CY6NRz-J.js} +2 -2
- package/dist/client/assets/{http-CSdnm1Wh.js → http-Cyd7bS_S.js} +2 -2
- package/dist/client/assets/{hurl-DKOuNoWT.js → hurl-CWPsiEpf.js} +2 -2
- package/dist/client/assets/index-DN4UQwOg.js +853 -0
- package/dist/client/assets/index-jIQiqqGn.css +1 -0
- package/dist/client/assets/info-DKCQHKI2-a_IxCZlD.js +1 -0
- package/dist/client/assets/infoDiagram-6WML65LV-CNHt7MRQ.js +3 -0
- package/dist/client/assets/init-D6jRqBbL.js +2 -0
- package/dist/client/assets/ishikawaDiagram-WSZJBQD7-GfzwW5bv.js +71 -0
- package/dist/client/assets/java-CGc3VwQr.js +2 -0
- package/dist/client/assets/javascript-CUt1pgmJ.js +2 -0
- package/dist/client/assets/{jinja-CvJhR5Z5.js → jinja-CD-Z-FLd.js} +2 -2
- package/dist/client/assets/{jison-DSlj1sEU.js → jison-imPNup1l.js} +2 -2
- package/dist/client/assets/journeyDiagram-NVQOT4AX-BSwGpG7U.js +140 -0
- package/dist/client/assets/json-Bg9ijW3F.js +2 -0
- package/dist/client/assets/jsx-CY6oMTks.js +2 -0
- package/dist/client/assets/{julia-CmLSMgqX.js → julia-Dc3O-irA.js} +2 -2
- package/dist/client/assets/{just-D9KdTXpD.js → just-BhOq_Kbv.js} +2 -2
- package/dist/client/assets/kanban-definition-27J2QSJJ-D_T9V6VW.js +90 -0
- package/dist/client/assets/katex-CddkPoXu.js +258 -0
- package/dist/client/assets/{latex-BZoE-Z3X.js → latex-Cu4Y1d5w.js} +2 -2
- package/dist/client/assets/line-DSV8zekT.js +2 -0
- package/dist/client/assets/linear-B7l8qgEw.js +2 -0
- package/dist/client/assets/{liquid-DW5UrT3Q.js → liquid-CvXMrjlQ.js} +2 -2
- package/dist/client/assets/lua-BjLEUjKY.js +2 -0
- package/dist/client/assets/map-DsCK-0Cs.js +2 -0
- package/dist/client/assets/{marko-EN2dMS-t.js → marko-DvhNOisQ.js} +2 -2
- package/dist/client/assets/{mdc-DV5R0Zdp.js → mdc-Bm9TpL1X.js} +2 -2
- package/dist/client/assets/mdx-host-BSmJn2Ra.css +1 -0
- package/dist/client/assets/mdx-host-ykYobBl4.js +4 -0
- package/dist/client/assets/mermaid-parser.core-B5tsyPlM.js +8 -0
- package/dist/client/assets/mermaid.core-0eNWrEyK.js +12 -0
- package/dist/client/assets/mindmap-definition-FAOFIHXS-CCatf1G5.js +97 -0
- package/dist/client/assets/{nginx-BhF2pPjp.js → nginx-Bhc82uuv.js} +2 -2
- package/dist/client/assets/{nim-Ck0oR8VY.js → nim-DXTVBFnF.js} +2 -2
- package/dist/client/assets/ordinal-hYBb2elL.js +2 -0
- package/dist/client/assets/packet-7NZHBO7P-TVG5WLAg.js +1 -0
- package/dist/client/assets/path-BWPyau1x.js +2 -0
- package/dist/client/assets/pegDiagram-VL7TDLO6-cVET6VY2.js +2 -0
- package/dist/client/assets/{perl-B4V1RSOt.js → perl-C7veXV9z.js} +2 -2
- package/dist/client/assets/{php-BvwSzqRH.js → php-BRiuMnnr.js} +2 -2
- package/dist/client/assets/pie-RZYD4A2V-_HnCx0-n.js +1 -0
- package/dist/client/assets/pieDiagram-7S7Q4E2Y-my4weM7I.js +40 -0
- package/dist/client/assets/preload-helper-CEhsl8MR.js +10 -0
- package/dist/client/assets/{pug-DB3guzOM.js → pug-C5hz5LQ7.js} +2 -2
- package/dist/client/assets/{qml-CohVRZGq.js → qml-BdUV3aTS.js} +2 -2
- package/dist/client/assets/quadrantDiagram-CIZ2JOQS-DbbX4CCn.js +8 -0
- package/dist/client/assets/r-8R7vtdQc.js +2 -0
- package/dist/client/assets/radar-I7S5WNFK-CxNqBWNL.js +1 -0
- package/dist/client/assets/railroad-3IZDKUUU-x01a2S92.js +1 -0
- package/dist/client/assets/railroad-abnf-AHOZXSZD-CMSmMh88.js +1 -0
- package/dist/client/assets/railroad-ebnf-EBAXGLYW-BtYYxacN.js +1 -0
- package/dist/client/assets/railroad-peg-LSFZ7HO6-BlXAsNZI.js +1 -0
- package/dist/client/assets/railroadDiagram-AXF67PYL-CA2XP-eT.js +2 -0
- package/dist/client/assets/{razor-CtBV-RZa.js → razor-DRL52XO2.js} +2 -2
- package/dist/client/assets/regexp-Omp9DhTb.js +2 -0
- package/dist/client/assets/requirementDiagram-LRYGKXZP-DPky6FEM.js +85 -0
- package/dist/client/assets/rolldown-runtime-QTnfLwEv.js +1 -0
- package/dist/client/assets/rough.esm-CSKSodPl.js +2 -0
- package/dist/client/assets/{rst-1GlNPFb8.js → rst-BHX71KW9.js} +2 -2
- package/dist/client/assets/{ruby-C_Jg-W0j.js → ruby-B--HzjGU.js} +2 -2
- package/dist/client/assets/sankeyDiagram-W5VNT64P-Im_lfZl5.js +41 -0
- package/dist/client/assets/{sas-IRPqQRQC.js → sas-DrLaYOK_.js} +2 -2
- package/dist/client/assets/scss-DdSxiZKl.js +2 -0
- package/dist/client/assets/sequenceDiagram-SI44F4Z6-DaepaQXs.js +163 -0
- package/dist/client/assets/shellscript-DwcUjJBL.js +2 -0
- package/dist/client/assets/{shellsession-bEniUyPe.js → shellsession-CPZkydE6.js} +2 -2
- package/dist/client/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +2 -0
- package/dist/client/assets/{soy-D0Pcy9LW.js → soy-Br5FhD7c.js} +2 -2
- package/dist/client/assets/sql-DNssxck8.js +2 -0
- package/dist/client/assets/src-_wZywoZs.js +2 -0
- package/dist/client/assets/{stata-BLI2BTCU.js → stata-DXn1tqOr.js} +2 -2
- package/dist/client/assets/stateDiagram-OKZ733FA-CfYrJbpr.js +2 -0
- package/dist/client/assets/stateDiagram-v2-UEYNNEHI-Dj9TN_Qe.js +2 -0
- package/dist/client/assets/{surrealql-BjtO5tmi.js → surrealql-IeLNQw0f.js} +2 -2
- package/dist/client/assets/{svelte-IyvKNOcX.js → svelte-DOdLCIlh.js} +2 -2
- package/dist/client/assets/swimlanes-SLNWSIFB-DaoN2lsp.js +3 -0
- package/dist/client/assets/swimlanesDiagram-ULZ7WXOC-BKWIjosV.js +9 -0
- package/dist/client/assets/{templ-qRJlnfHP.js → templ-CIwIngms.js} +2 -2
- package/dist/client/assets/terminal-links-B96vwInV.js +46 -0
- package/dist/client/assets/{tex-CgYv5ALc.js → tex-D8QMumu5.js} +2 -2
- package/dist/client/assets/timeline-definition-Z64GVDOM-I6R4kaBM.js +121 -0
- package/dist/client/assets/treeView-QDETBFTQ-FHUGB9GE.js +1 -0
- package/dist/client/assets/treemap-6X3UGDF4-C2oSUZ4V.js +1 -0
- package/dist/client/assets/{ts-tags-YasuuPCT.js → ts-tags-BMVY4q-l.js} +2 -2
- package/dist/client/assets/tsx-5Eka4NBX.js +2 -0
- package/dist/client/assets/{twig-BF-FIMTp.js → twig-C8o_5mgw.js} +2 -2
- package/dist/client/assets/typescript-DOu2WMV5.js +2 -0
- package/dist/client/assets/vennDiagram-T6HMQDX7-uVbqilLL.js +35 -0
- package/dist/client/assets/{vue-BTbCYZab.js → vue-BU18DNDL.js} +2 -2
- package/dist/client/assets/{vue-html-1KQNz6IV.js → vue-html-BeluIYX0.js} +2 -2
- package/dist/client/assets/{vue-vine-BVHOJ5oI.js → vue-vine-DGUAbOCX.js} +2 -2
- package/dist/client/assets/wardley-OPB4EBWU-C8z79vwT.js +1 -0
- package/dist/client/assets/wardleyDiagram-T6FBY63Y-Bh4kXS4j.js +79 -0
- package/dist/client/assets/xml-DIqSwXR3.js +2 -0
- package/dist/client/assets/{xsl-DoQ9dHRM.js → xsl-Ct_-YIAy.js} +2 -2
- package/dist/client/assets/xychartDiagram-ELKLHX3M-aKLyYtge.js +8 -0
- package/dist/client/assets/yaml-DTtCYNlS.js +2 -0
- package/dist/client/index.html +6 -3
- package/dist/client/mdx-host.html +25 -0
- package/dist/client/mdx-jsx-runtime.js +23 -0
- package/package.json +4 -1
- package/dist/client/assets/DiffPanel-Cdf69_RS.js +0 -98
- package/dist/client/assets/FilePreviewPanel-CkKXCbcG.js +0 -1778
- package/dist/client/assets/PreviewPanel-BtqdQqtN.js +0 -2
- package/dist/client/assets/angular-html-BPHFZwgm.js +0 -2
- package/dist/client/assets/arrow-right-7YX6fLbL.js +0 -2
- package/dist/client/assets/c-BsDji_bt.js +0 -2
- package/dist/client/assets/cpp-D5_eYHZr.js +0 -2
- package/dist/client/assets/css-B4bpFXEv.js +0 -2
- package/dist/client/assets/fileCommentAnnotations-BTb-0nj3.js +0 -2
- package/dist/client/assets/glsl-DI6kM2gF.js +0 -2
- package/dist/client/assets/graphql-VCSJCQkl.js +0 -2
- package/dist/client/assets/haml-Bc0kPVkr.js +0 -2
- package/dist/client/assets/html-_Zw71zQT.js +0 -2
- package/dist/client/assets/index-CeztlSXj.js +0 -853
- package/dist/client/assets/index-eSuLivhH.css +0 -1
- package/dist/client/assets/java-Czo4Dn1f.js +0 -2
- package/dist/client/assets/javascript-fyReKHSS.js +0 -2
- package/dist/client/assets/json-fCB7n2pX.js +0 -2
- package/dist/client/assets/jsx-C1OJlXdb.js +0 -2
- package/dist/client/assets/lua-DMAjig-8.js +0 -2
- package/dist/client/assets/r-Doi-hRR2.js +0 -2
- package/dist/client/assets/regexp-DgF6jh6T.js +0 -2
- package/dist/client/assets/scss-BPKDbfld.js +0 -2
- package/dist/client/assets/shellscript-D5KbVhsx.js +0 -2
- package/dist/client/assets/sql-DF2TL966.js +0 -2
- package/dist/client/assets/textarea-B03Qe3NX.js +0 -46
- package/dist/client/assets/tsx-BF7eypTR.js +0 -2
- package/dist/client/assets/typescript-CtOBCMI7.js +0 -2
- package/dist/client/assets/xml-CftlzqvG.js +0 -2
- package/dist/client/assets/yaml-DMUX1MAF.js +0 -2
package/dist/bin.mjs
CHANGED
|
@@ -77,6 +77,10 @@ import * as HttpClientResponse$1 from "effect/unstable/http/HttpClientResponse";
|
|
|
77
77
|
import * as HttpApiBuilder from "effect/unstable/httpapi/HttpApiBuilder";
|
|
78
78
|
import * as Tracer from "effect/Tracer";
|
|
79
79
|
import "effect/unstable/observability";
|
|
80
|
+
import * as NodeFSP from "node:fs/promises";
|
|
81
|
+
import { compile } from "@mdx-js/mdx";
|
|
82
|
+
import remarkFrontmatter from "remark-frontmatter";
|
|
83
|
+
import remarkGfm from "remark-gfm";
|
|
80
84
|
import * as Cookies from "effect/unstable/http/Cookies";
|
|
81
85
|
import * as HttpEffect from "effect/unstable/http/HttpEffect";
|
|
82
86
|
import { RpcSerialization, RpcServer } from "effect/unstable/rpc";
|
|
@@ -86,7 +90,6 @@ import * as TxQueue from "effect/TxQueue";
|
|
|
86
90
|
import * as TxRef from "effect/TxRef";
|
|
87
91
|
import * as Fiber from "effect/Fiber";
|
|
88
92
|
import * as SynchronizedRef from "effect/SynchronizedRef";
|
|
89
|
-
import * as NodeFSP from "node:fs/promises";
|
|
90
93
|
import * as RcMap from "effect/RcMap";
|
|
91
94
|
import { FileFinder } from "@ff-labs/fff-node";
|
|
92
95
|
import * as LayerMap from "effect/LayerMap";
|
|
@@ -233,7 +236,7 @@ const make$76 = () => {
|
|
|
233
236
|
const layer$72 = Layer.sync(NetService, make$76);
|
|
234
237
|
//#endregion
|
|
235
238
|
//#region package.json
|
|
236
|
-
var version = "0.1.
|
|
239
|
+
var version = "0.1.23";
|
|
237
240
|
//#endregion
|
|
238
241
|
//#region src/config.ts
|
|
239
242
|
/**
|
|
@@ -261,6 +264,7 @@ const deriveServerPaths = Effect.fn(function* (baseDir, devUrl, options = {}) {
|
|
|
261
264
|
const stateDir = join(baseDir, devUrl !== void 0 && !options.baseDirIsExplicit ? "dev" : "userdata");
|
|
262
265
|
const dbPath = join(stateDir, "state.sqlite");
|
|
263
266
|
const attachmentsDir = join(stateDir, "attachments");
|
|
267
|
+
const mdxBuildsDir = join(stateDir, "mdx-builds");
|
|
264
268
|
const logsDir = join(stateDir, "logs");
|
|
265
269
|
const providerLogsDir = join(logsDir, "provider");
|
|
266
270
|
const providerStatusCacheDir = join(baseDir, "caches");
|
|
@@ -272,6 +276,7 @@ const deriveServerPaths = Effect.fn(function* (baseDir, devUrl, options = {}) {
|
|
|
272
276
|
providerStatusCacheDir,
|
|
273
277
|
worktreesDir: join(baseDir, "worktrees"),
|
|
274
278
|
attachmentsDir,
|
|
279
|
+
mdxBuildsDir,
|
|
275
280
|
logsDir,
|
|
276
281
|
serverLogPath: join(logsDir, "server.log"),
|
|
277
282
|
serverTracePath: join(logsDir, "server.trace.ndjson"),
|
|
@@ -293,6 +298,7 @@ const ensureServerDirectories = Effect.fn(function* (derivedPaths) {
|
|
|
293
298
|
fs.makeDirectory(derivedPaths.providerLogsDir, { recursive: true }),
|
|
294
299
|
fs.makeDirectory(derivedPaths.terminalLogsDir, { recursive: true }),
|
|
295
300
|
fs.makeDirectory(derivedPaths.attachmentsDir, { recursive: true }),
|
|
301
|
+
fs.makeDirectory(derivedPaths.mdxBuildsDir, { recursive: true }),
|
|
296
302
|
fs.makeDirectory(derivedPaths.worktreesDir, { recursive: true }),
|
|
297
303
|
fs.makeDirectory(path.dirname(derivedPaths.keybindingsConfigPath), { recursive: true }),
|
|
298
304
|
fs.makeDirectory(path.dirname(derivedPaths.settingsPath), { recursive: true }),
|
|
@@ -7773,13 +7779,18 @@ const ProjectReadFileResult = Schema$1.Struct({
|
|
|
7773
7779
|
relativePath: TrimmedNonEmptyString,
|
|
7774
7780
|
contents: Schema$1.String,
|
|
7775
7781
|
byteLength: NonNegativeInt,
|
|
7776
|
-
truncated: Schema$1.Boolean
|
|
7782
|
+
truncated: Schema$1.Boolean,
|
|
7783
|
+
/**
|
|
7784
|
+
* The file is not UTF-8 text, so `contents` is empty and only the metadata
|
|
7785
|
+
* is meaningful. Reported rather than raised because a `.docx` in a preview
|
|
7786
|
+
* panel is an ordinary file to describe, not a failed read to apologise for.
|
|
7787
|
+
*/
|
|
7788
|
+
binary: Schema$1.Boolean
|
|
7777
7789
|
});
|
|
7778
7790
|
const ProjectFileFailure = Schema$1.Literals([
|
|
7779
7791
|
"workspace_path_outside_root",
|
|
7780
7792
|
"resolved_path_outside_root",
|
|
7781
7793
|
"path_not_file",
|
|
7782
|
-
"binary_file",
|
|
7783
7794
|
"operation_failed"
|
|
7784
7795
|
]);
|
|
7785
7796
|
const ProjectFileOperation = Schema$1.Literals([
|
|
@@ -8913,6 +8924,8 @@ const AssetResource = Schema$1.Union([
|
|
|
8913
8924
|
threadId: ThreadId,
|
|
8914
8925
|
path: TrimmedNonEmptyString.check(Schema$1.isMaxLength(ASSET_PATH_MAX_LENGTH))
|
|
8915
8926
|
}),
|
|
8927
|
+
Schema$1.TaggedStruct("local-file", { path: TrimmedNonEmptyString.check(Schema$1.isMaxLength(ASSET_PATH_MAX_LENGTH)) }),
|
|
8928
|
+
Schema$1.TaggedStruct("mdx-preview", { path: TrimmedNonEmptyString.check(Schema$1.isMaxLength(ASSET_PATH_MAX_LENGTH)) }),
|
|
8916
8929
|
Schema$1.TaggedStruct("attachment", { attachmentId: TrimmedNonEmptyString.check(Schema$1.isMaxLength(256)) }),
|
|
8917
8930
|
Schema$1.TaggedStruct("project-favicon", { cwd: TrimmedNonEmptyString.check(Schema$1.isMaxLength(ASSET_PATH_MAX_LENGTH)) })
|
|
8918
8931
|
]);
|
|
@@ -9002,6 +9015,32 @@ var AssetProjectFaviconNotFoundError = class extends Schema$1.TaggedErrorClass()
|
|
|
9002
9015
|
return "Project favicon was not found.";
|
|
9003
9016
|
}
|
|
9004
9017
|
};
|
|
9018
|
+
var AssetLocalFileNotFoundError = class extends Schema$1.TaggedErrorClass()("AssetLocalFileNotFoundError", { resource: AssetResource }) {
|
|
9019
|
+
get message() {
|
|
9020
|
+
return "Local file was not found.";
|
|
9021
|
+
}
|
|
9022
|
+
};
|
|
9023
|
+
var AssetLocalFileInspectionError = class extends Schema$1.TaggedErrorClass()("AssetLocalFileInspectionError", {
|
|
9024
|
+
resource: AssetResource,
|
|
9025
|
+
cause: Schema$1.Defect()
|
|
9026
|
+
}) {
|
|
9027
|
+
get message() {
|
|
9028
|
+
return "Failed to inspect the local file.";
|
|
9029
|
+
}
|
|
9030
|
+
};
|
|
9031
|
+
var AssetLocalPathValidationError = class extends Schema$1.TaggedErrorClass()("AssetLocalPathValidationError", { resource: AssetResource }) {
|
|
9032
|
+
get message() {
|
|
9033
|
+
return "Local file path must be absolute.";
|
|
9034
|
+
}
|
|
9035
|
+
};
|
|
9036
|
+
var AssetMdxBuildError = class extends Schema$1.TaggedErrorClass()("AssetMdxBuildError", {
|
|
9037
|
+
resource: AssetResource,
|
|
9038
|
+
cause: Schema$1.Defect()
|
|
9039
|
+
}) {
|
|
9040
|
+
get message() {
|
|
9041
|
+
return "Failed to prepare the MDX preview build.";
|
|
9042
|
+
}
|
|
9043
|
+
};
|
|
9005
9044
|
var AssetSigningKeyLoadError = class extends Schema$1.TaggedErrorClass()("AssetSigningKeyLoadError", {
|
|
9006
9045
|
resource: AssetResource,
|
|
9007
9046
|
cause: Schema$1.Defect()
|
|
@@ -9023,6 +9062,10 @@ const AssetAccessError = Schema$1.Union([
|
|
|
9023
9062
|
AssetProjectFaviconResolutionError,
|
|
9024
9063
|
AssetProjectFaviconInspectionError,
|
|
9025
9064
|
AssetProjectFaviconNotFoundError,
|
|
9065
|
+
AssetLocalFileNotFoundError,
|
|
9066
|
+
AssetLocalFileInspectionError,
|
|
9067
|
+
AssetLocalPathValidationError,
|
|
9068
|
+
AssetMdxBuildError,
|
|
9026
9069
|
AssetSigningKeyLoadError
|
|
9027
9070
|
]);
|
|
9028
9071
|
//#endregion
|
|
@@ -16107,7 +16150,7 @@ function buildSkillOverrides(disabled, discovered) {
|
|
|
16107
16150
|
*
|
|
16108
16151
|
* @module provider/Drivers/ClaudeSkills
|
|
16109
16152
|
*/
|
|
16110
|
-
const FRONTMATTER_PATTERN = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/;
|
|
16153
|
+
const FRONTMATTER_PATTERN$1 = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/;
|
|
16111
16154
|
/**
|
|
16112
16155
|
* The `name`/`description` header a skill and a subagent definition both carry.
|
|
16113
16156
|
*
|
|
@@ -16117,7 +16160,7 @@ const FRONTMATTER_PATTERN = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/;
|
|
|
16117
16160
|
* one question both callers are asking.
|
|
16118
16161
|
*/
|
|
16119
16162
|
function parseMarkdownFrontmatter(contents) {
|
|
16120
|
-
const match = FRONTMATTER_PATTERN.exec(contents);
|
|
16163
|
+
const match = FRONTMATTER_PATTERN$1.exec(contents);
|
|
16121
16164
|
if (!match) return { kind: "missing" };
|
|
16122
16165
|
let parsed;
|
|
16123
16166
|
try {
|
|
@@ -30504,6 +30547,374 @@ function isWorkspacePreviewEntryPath(path) {
|
|
|
30504
30547
|
return isWorkspaceBrowserPreviewPath(path) || isWorkspaceImagePreviewPath(path);
|
|
30505
30548
|
}
|
|
30506
30549
|
//#endregion
|
|
30550
|
+
//#region src/assets/mdxCompile.ts
|
|
30551
|
+
/**
|
|
30552
|
+
* Pure MDX compilation for the preview renderer.
|
|
30553
|
+
*
|
|
30554
|
+
* Compilation only: nothing here touches the filesystem, resolves a module, or
|
|
30555
|
+
* runs a bundler. The output is a single ES module that imports only the host
|
|
30556
|
+
* page's runtime shim, so the build directory it lands in never needs a
|
|
30557
|
+
* `node_modules` beside it.
|
|
30558
|
+
*
|
|
30559
|
+
* @module mdxCompile
|
|
30560
|
+
*/
|
|
30561
|
+
/**
|
|
30562
|
+
* Stable, unhashed module the host page publishes its React JSX runtime and
|
|
30563
|
+
* component provider on. Compiled documents are cached across app versions, so
|
|
30564
|
+
* this specifier must not carry a build hash.
|
|
30565
|
+
*/
|
|
30566
|
+
const MDX_RUNTIME_SPECIFIER = "/mdx-jsx-runtime.js";
|
|
30567
|
+
/**
|
|
30568
|
+
* Scheme the compiler rewrites relative asset references to.
|
|
30569
|
+
*
|
|
30570
|
+
* The compiled module is served from the build directory, so `./diagram.png`
|
|
30571
|
+
* would resolve against the wrong origin path. Rather than copying referenced
|
|
30572
|
+
* files into the build directory, the reference is rewritten to a marker the
|
|
30573
|
+
* host page resolves against the source-directory grant carried by the same
|
|
30574
|
+
* asset token. Cached builds therefore stay valid when the token rotates.
|
|
30575
|
+
*/
|
|
30576
|
+
const MDX_ASSET_SCHEME = "p4-asset:";
|
|
30577
|
+
const FRONTMATTER_PATTERN = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/;
|
|
30578
|
+
const EMPTY_FRONTMATTER = {
|
|
30579
|
+
title: null,
|
|
30580
|
+
created: null,
|
|
30581
|
+
status: null,
|
|
30582
|
+
rest: {}
|
|
30583
|
+
};
|
|
30584
|
+
function scalarToString(value) {
|
|
30585
|
+
if (typeof value === "string") return value;
|
|
30586
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
30587
|
+
if (value instanceof Date) return value.toISOString().slice(0, 10);
|
|
30588
|
+
return null;
|
|
30589
|
+
}
|
|
30590
|
+
/**
|
|
30591
|
+
* Read the leading YAML block.
|
|
30592
|
+
*
|
|
30593
|
+
* Parsed here rather than through a remark plugin because the renderer needs
|
|
30594
|
+
* the values as data for the document header, while remark-frontmatter's job
|
|
30595
|
+
* is only to keep the block from reaching the body as literal text.
|
|
30596
|
+
*/
|
|
30597
|
+
function parseMdxFrontmatter(source) {
|
|
30598
|
+
const match = FRONTMATTER_PATTERN.exec(source);
|
|
30599
|
+
if (!match?.[1]) return EMPTY_FRONTMATTER;
|
|
30600
|
+
let parsed;
|
|
30601
|
+
try {
|
|
30602
|
+
parsed = parse(match[1]);
|
|
30603
|
+
} catch {
|
|
30604
|
+
return EMPTY_FRONTMATTER;
|
|
30605
|
+
}
|
|
30606
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return EMPTY_FRONTMATTER;
|
|
30607
|
+
const entries = Object.entries(parsed);
|
|
30608
|
+
const rest = {};
|
|
30609
|
+
for (const [key, value] of entries) {
|
|
30610
|
+
if (key === "title" || key === "created" || key === "status") continue;
|
|
30611
|
+
const scalar = scalarToString(value);
|
|
30612
|
+
if (scalar !== null) rest[key] = scalar;
|
|
30613
|
+
}
|
|
30614
|
+
return {
|
|
30615
|
+
title: scalarToString(parsed.title),
|
|
30616
|
+
created: scalarToString(parsed.created),
|
|
30617
|
+
status: scalarToString(parsed.status),
|
|
30618
|
+
rest
|
|
30619
|
+
};
|
|
30620
|
+
}
|
|
30621
|
+
function isRewritableAssetUrl(url) {
|
|
30622
|
+
if (url.length === 0) return false;
|
|
30623
|
+
if (url.startsWith("#") || url.startsWith("/")) return false;
|
|
30624
|
+
if (url.startsWith("data:") || url.startsWith("p4-asset:")) return false;
|
|
30625
|
+
return !/^[A-Za-z][A-Za-z\d+.-]*:/.test(url);
|
|
30626
|
+
}
|
|
30627
|
+
function walk(node, visit) {
|
|
30628
|
+
const stack = [{
|
|
30629
|
+
node,
|
|
30630
|
+
parent: null
|
|
30631
|
+
}];
|
|
30632
|
+
while (stack.length > 0) {
|
|
30633
|
+
const current = stack.pop();
|
|
30634
|
+
if (!current) break;
|
|
30635
|
+
if (!visit(current.node, current.parent)) continue;
|
|
30636
|
+
for (const child of current.node.children ?? []) stack.push({
|
|
30637
|
+
node: child,
|
|
30638
|
+
parent: current.node
|
|
30639
|
+
});
|
|
30640
|
+
}
|
|
30641
|
+
}
|
|
30642
|
+
/**
|
|
30643
|
+
* Drop `import`/`export` statements before compilation.
|
|
30644
|
+
*
|
|
30645
|
+
* Dropping rather than rejecting is deliberate: authored plans never contain
|
|
30646
|
+
* imports, third-party `.mdx` found on disk usually does, and a dropped import
|
|
30647
|
+
* is never resolved or executed either way. The component that would have come
|
|
30648
|
+
* from the import is then undefined, which the host page's fallback renders as
|
|
30649
|
+
* a labeled placeholder instead of blanking the document.
|
|
30650
|
+
*/
|
|
30651
|
+
function remarkDropEsm(state) {
|
|
30652
|
+
return (tree) => {
|
|
30653
|
+
walk(tree, (node) => {
|
|
30654
|
+
if (!node.children) return true;
|
|
30655
|
+
const kept = node.children.filter((child) => child.type !== "mdxjsEsm");
|
|
30656
|
+
if (kept.length !== node.children.length) {
|
|
30657
|
+
state.droppedImports = true;
|
|
30658
|
+
node.children = kept;
|
|
30659
|
+
}
|
|
30660
|
+
return true;
|
|
30661
|
+
});
|
|
30662
|
+
};
|
|
30663
|
+
}
|
|
30664
|
+
/**
|
|
30665
|
+
* Collect every capitalised element the document renders.
|
|
30666
|
+
*
|
|
30667
|
+
* MDX resolves components through `{...provideComponents(), ...props.components}`,
|
|
30668
|
+
* a plain object, and throws `Expected component X to be defined` for a name
|
|
30669
|
+
* neither supplies — which would blank the whole document over one unresolved
|
|
30670
|
+
* tag. A proxy cannot help, because the spread copies own keys only. Naming
|
|
30671
|
+
* the components at compile time lets the host page put a real placeholder in
|
|
30672
|
+
* the map for each one it does not provide.
|
|
30673
|
+
*/
|
|
30674
|
+
function remarkCollectComponentNames(state) {
|
|
30675
|
+
return (tree) => {
|
|
30676
|
+
walk(tree, (node) => {
|
|
30677
|
+
if (node.type !== "mdxJsxFlowElement" && node.type !== "mdxJsxTextElement") return true;
|
|
30678
|
+
const name = node.name;
|
|
30679
|
+
if (typeof name !== "string" || name.length === 0) return true;
|
|
30680
|
+
const base = name.split(".")[0] ?? name;
|
|
30681
|
+
if (base[0] === base[0]?.toUpperCase()) state.names.add(base);
|
|
30682
|
+
return true;
|
|
30683
|
+
});
|
|
30684
|
+
};
|
|
30685
|
+
}
|
|
30686
|
+
/** Rewrite relative image references to the host page's asset marker. */
|
|
30687
|
+
function remarkRewriteRelativeAssets() {
|
|
30688
|
+
return (tree) => {
|
|
30689
|
+
walk(tree, (node) => {
|
|
30690
|
+
if (node.type === "image" && typeof node.url === "string" && isRewritableAssetUrl(node.url)) {
|
|
30691
|
+
node.url = `${MDX_ASSET_SCHEME}${node.url}`;
|
|
30692
|
+
return true;
|
|
30693
|
+
}
|
|
30694
|
+
if (node.type === "mdxJsxFlowElement" || node.type === "mdxJsxTextElement") for (const attribute of node.attributes ?? []) {
|
|
30695
|
+
if (attribute.type !== "mdxJsxAttribute") continue;
|
|
30696
|
+
if (attribute.name !== "src" && attribute.name !== "poster") continue;
|
|
30697
|
+
if (typeof attribute.value !== "string" || !isRewritableAssetUrl(attribute.value)) continue;
|
|
30698
|
+
attribute.value = `${MDX_ASSET_SCHEME}${attribute.value}`;
|
|
30699
|
+
}
|
|
30700
|
+
return true;
|
|
30701
|
+
});
|
|
30702
|
+
};
|
|
30703
|
+
}
|
|
30704
|
+
/**
|
|
30705
|
+
* Point every surviving import at the host page's runtime shim.
|
|
30706
|
+
*
|
|
30707
|
+
* After the author's statements are dropped, the only imports left are the
|
|
30708
|
+
* ones MDX itself emits (the JSX runtime and the component provider). Both are
|
|
30709
|
+
* satisfied by one unhashed module, which is what lets the compiled output be
|
|
30710
|
+
* cached independently of the app build.
|
|
30711
|
+
*/
|
|
30712
|
+
function recmaPinRuntimeImports() {
|
|
30713
|
+
return (tree) => {
|
|
30714
|
+
for (const statement of tree.body) {
|
|
30715
|
+
if (statement.type !== "ImportDeclaration" || !statement.source) continue;
|
|
30716
|
+
statement.source.value = MDX_RUNTIME_SPECIFIER;
|
|
30717
|
+
statement.source.raw = JSON.stringify(MDX_RUNTIME_SPECIFIER);
|
|
30718
|
+
}
|
|
30719
|
+
};
|
|
30720
|
+
}
|
|
30721
|
+
function errorPosition(error) {
|
|
30722
|
+
const place = error?.place;
|
|
30723
|
+
const point = place?.start ?? place;
|
|
30724
|
+
const line = point?.line ?? error.line;
|
|
30725
|
+
const column = point?.column ?? error.column;
|
|
30726
|
+
return {
|
|
30727
|
+
line: typeof line === "number" ? line : null,
|
|
30728
|
+
column: typeof column === "number" ? column : null
|
|
30729
|
+
};
|
|
30730
|
+
}
|
|
30731
|
+
/** Compile MDX source into a single self-contained ES module. */
|
|
30732
|
+
async function compileMdxDocument(source) {
|
|
30733
|
+
const frontmatter = parseMdxFrontmatter(source);
|
|
30734
|
+
const state = { droppedImports: false };
|
|
30735
|
+
const collected = { names: /* @__PURE__ */ new Set() };
|
|
30736
|
+
try {
|
|
30737
|
+
const compiled = await compile(source, {
|
|
30738
|
+
development: false,
|
|
30739
|
+
jsx: false,
|
|
30740
|
+
outputFormat: "program",
|
|
30741
|
+
providerImportSource: MDX_RUNTIME_SPECIFIER,
|
|
30742
|
+
remarkPlugins: [
|
|
30743
|
+
remarkFrontmatter,
|
|
30744
|
+
remarkGfm,
|
|
30745
|
+
() => remarkDropEsm(state),
|
|
30746
|
+
() => remarkCollectComponentNames(collected),
|
|
30747
|
+
remarkRewriteRelativeAssets
|
|
30748
|
+
],
|
|
30749
|
+
recmaPlugins: [recmaPinRuntimeImports]
|
|
30750
|
+
});
|
|
30751
|
+
return {
|
|
30752
|
+
ok: true,
|
|
30753
|
+
code: String(compiled),
|
|
30754
|
+
droppedImports: state.droppedImports,
|
|
30755
|
+
componentNames: [...collected.names],
|
|
30756
|
+
frontmatter
|
|
30757
|
+
};
|
|
30758
|
+
} catch (cause) {
|
|
30759
|
+
const { line, column } = errorPosition(cause);
|
|
30760
|
+
return {
|
|
30761
|
+
ok: false,
|
|
30762
|
+
message: cause instanceof Error ? cause.message : "Failed to compile MDX.",
|
|
30763
|
+
line,
|
|
30764
|
+
column,
|
|
30765
|
+
frontmatter
|
|
30766
|
+
};
|
|
30767
|
+
}
|
|
30768
|
+
}
|
|
30769
|
+
//#endregion
|
|
30770
|
+
//#region src/assets/mdxPreviewStore.ts
|
|
30771
|
+
/**
|
|
30772
|
+
* On-disk cache of compiled MDX previews.
|
|
30773
|
+
*
|
|
30774
|
+
* A build is keyed by the source file's real path, mtime and size, so opening
|
|
30775
|
+
* the same unchanged document twice reuses the cached output and touching the
|
|
30776
|
+
* file invalidates it. Output lives under the server state directory, next to
|
|
30777
|
+
* `attachments`, because it is generated data that must never be written back
|
|
30778
|
+
* into the user's workspace.
|
|
30779
|
+
*
|
|
30780
|
+
* @module mdxPreviewStore
|
|
30781
|
+
*/
|
|
30782
|
+
/** Bumping this invalidates every cached build after a renderer change. */
|
|
30783
|
+
const BUILD_FORMAT_VERSION = 1;
|
|
30784
|
+
const MDX_BUILD_DOCUMENT_FILE = "document.js";
|
|
30785
|
+
const MDX_BUILD_META_FILE = "meta.json";
|
|
30786
|
+
/** Only these two names resolve inside a build directory. */
|
|
30787
|
+
const MDX_BUILD_FILES = /* @__PURE__ */ new Set([MDX_BUILD_DOCUMENT_FILE, MDX_BUILD_META_FILE]);
|
|
30788
|
+
const BUILD_ID_PATTERN = /^[0-9a-f]{32}$/;
|
|
30789
|
+
const CACHE_MAX_AGE_MS = 10080 * 60 * 1e3;
|
|
30790
|
+
const CACHE_MAX_TOTAL_BYTES = 64 * 1024 * 1024;
|
|
30791
|
+
function isMdxBuildId(value) {
|
|
30792
|
+
return BUILD_ID_PATTERN.test(value);
|
|
30793
|
+
}
|
|
30794
|
+
function buildIdFor(input) {
|
|
30795
|
+
return NodeCrypto.createHash("sha256").update(`${BUILD_FORMAT_VERSION}\0${input.realPath}\0${input.mtimeMs}\0${input.size}`).digest("hex").slice(0, 32);
|
|
30796
|
+
}
|
|
30797
|
+
function metaFor(input) {
|
|
30798
|
+
return {
|
|
30799
|
+
title: input.frontmatter.title,
|
|
30800
|
+
created: input.frontmatter.created,
|
|
30801
|
+
status: input.frontmatter.status,
|
|
30802
|
+
rest: input.frontmatter.rest,
|
|
30803
|
+
sourceName: input.sourceName,
|
|
30804
|
+
droppedImports: input.droppedImports,
|
|
30805
|
+
componentNames: input.componentNames,
|
|
30806
|
+
error: input.error,
|
|
30807
|
+
source: input.source
|
|
30808
|
+
};
|
|
30809
|
+
}
|
|
30810
|
+
async function directorySize(path) {
|
|
30811
|
+
const entries = await NodeFSP.readdir(path, { withFileTypes: true }).catch(() => []);
|
|
30812
|
+
let total = 0;
|
|
30813
|
+
for (const entry of entries) {
|
|
30814
|
+
if (!entry.isFile()) continue;
|
|
30815
|
+
const info = await NodeFSP.stat(NodePath.join(path, entry.name)).catch(() => null);
|
|
30816
|
+
total += info?.size ?? 0;
|
|
30817
|
+
}
|
|
30818
|
+
return total;
|
|
30819
|
+
}
|
|
30820
|
+
/**
|
|
30821
|
+
* Drop builds that aged out, then oldest-first until the directory fits.
|
|
30822
|
+
*
|
|
30823
|
+
* Both bounds exist because either alone leaks: a TTL lets a burst of large
|
|
30824
|
+
* documents blow past any disk budget within the window, and a size cap alone
|
|
30825
|
+
* keeps stale builds alive indefinitely on a quiet machine.
|
|
30826
|
+
*/
|
|
30827
|
+
async function evictStaleBuilds(buildsDir, keepBuildId, now) {
|
|
30828
|
+
const entries = await NodeFSP.readdir(buildsDir, { withFileTypes: true }).catch(() => []);
|
|
30829
|
+
const surviving = [];
|
|
30830
|
+
for (const entry of entries) {
|
|
30831
|
+
if (!entry.isDirectory() || entry.name === keepBuildId) continue;
|
|
30832
|
+
const path = NodePath.join(buildsDir, entry.name);
|
|
30833
|
+
if (!isMdxBuildId(entry.name)) {
|
|
30834
|
+
await NodeFSP.rm(path, {
|
|
30835
|
+
recursive: true,
|
|
30836
|
+
force: true
|
|
30837
|
+
}).catch(() => void 0);
|
|
30838
|
+
continue;
|
|
30839
|
+
}
|
|
30840
|
+
const info = await NodeFSP.stat(path).catch(() => null);
|
|
30841
|
+
if (!info) continue;
|
|
30842
|
+
if (now - info.mtimeMs > CACHE_MAX_AGE_MS) {
|
|
30843
|
+
await NodeFSP.rm(path, {
|
|
30844
|
+
recursive: true,
|
|
30845
|
+
force: true
|
|
30846
|
+
}).catch(() => void 0);
|
|
30847
|
+
continue;
|
|
30848
|
+
}
|
|
30849
|
+
surviving.push({
|
|
30850
|
+
path,
|
|
30851
|
+
mtimeMs: info.mtimeMs,
|
|
30852
|
+
size: await directorySize(path)
|
|
30853
|
+
});
|
|
30854
|
+
}
|
|
30855
|
+
let total = surviving.reduce((sum, entry) => sum + entry.size, 0);
|
|
30856
|
+
if (total <= CACHE_MAX_TOTAL_BYTES) return;
|
|
30857
|
+
for (const entry of surviving.toSorted((a, b) => a.mtimeMs - b.mtimeMs)) {
|
|
30858
|
+
if (total <= CACHE_MAX_TOTAL_BYTES) break;
|
|
30859
|
+
await NodeFSP.rm(entry.path, {
|
|
30860
|
+
recursive: true,
|
|
30861
|
+
force: true
|
|
30862
|
+
}).catch(() => void 0);
|
|
30863
|
+
total -= entry.size;
|
|
30864
|
+
}
|
|
30865
|
+
}
|
|
30866
|
+
/**
|
|
30867
|
+
* Compile `sourcePath` if needed and return the build that serves it.
|
|
30868
|
+
*
|
|
30869
|
+
* A compile failure is not an error here: it produces a build whose `meta.json`
|
|
30870
|
+
* carries the diagnostic, so the renderer can show an error card with the
|
|
30871
|
+
* source rather than a blank page.
|
|
30872
|
+
*/
|
|
30873
|
+
async function prepareMdxBuild(input) {
|
|
30874
|
+
const realPath = await NodeFSP.realpath(input.sourcePath);
|
|
30875
|
+
const stat = await NodeFSP.stat(realPath);
|
|
30876
|
+
if (!stat.isFile()) throw new Error(`MDX preview source is not a file: ${realPath}`);
|
|
30877
|
+
const buildId = buildIdFor({
|
|
30878
|
+
realPath,
|
|
30879
|
+
mtimeMs: stat.mtimeMs,
|
|
30880
|
+
size: stat.size
|
|
30881
|
+
});
|
|
30882
|
+
const buildDir = NodePath.join(input.buildsDir, buildId);
|
|
30883
|
+
const sourceDir = NodePath.dirname(realPath);
|
|
30884
|
+
const metaPath = NodePath.join(buildDir, MDX_BUILD_META_FILE);
|
|
30885
|
+
if ((await NodeFSP.stat(metaPath).catch(() => null))?.isFile()) {
|
|
30886
|
+
const touchedAtSeconds = input.now / 1e3;
|
|
30887
|
+
await NodeFSP.utimes(buildDir, touchedAtSeconds, touchedAtSeconds).catch(() => void 0);
|
|
30888
|
+
await evictStaleBuilds(input.buildsDir, buildId, input.now);
|
|
30889
|
+
return {
|
|
30890
|
+
buildId,
|
|
30891
|
+
sourceDir
|
|
30892
|
+
};
|
|
30893
|
+
}
|
|
30894
|
+
const source = await NodeFSP.readFile(realPath, "utf8");
|
|
30895
|
+
const outcome = await compileMdxDocument(source);
|
|
30896
|
+
const sourceName = NodePath.basename(realPath);
|
|
30897
|
+
await NodeFSP.mkdir(buildDir, { recursive: true });
|
|
30898
|
+
if (outcome.ok) await NodeFSP.writeFile(NodePath.join(buildDir, MDX_BUILD_DOCUMENT_FILE), outcome.code, "utf8");
|
|
30899
|
+
const meta = metaFor({
|
|
30900
|
+
frontmatter: outcome.frontmatter,
|
|
30901
|
+
sourceName,
|
|
30902
|
+
droppedImports: outcome.ok ? outcome.droppedImports : false,
|
|
30903
|
+
componentNames: outcome.ok ? outcome.componentNames : [],
|
|
30904
|
+
error: outcome.ok ? null : {
|
|
30905
|
+
message: outcome.message,
|
|
30906
|
+
line: outcome.line
|
|
30907
|
+
},
|
|
30908
|
+
source: outcome.ok ? null : source
|
|
30909
|
+
});
|
|
30910
|
+
await NodeFSP.writeFile(metaPath, JSON.stringify(meta), "utf8");
|
|
30911
|
+
await evictStaleBuilds(input.buildsDir, buildId, input.now);
|
|
30912
|
+
return {
|
|
30913
|
+
buildId,
|
|
30914
|
+
sourceDir
|
|
30915
|
+
};
|
|
30916
|
+
}
|
|
30917
|
+
//#endregion
|
|
30507
30918
|
//#region ../../packages/shared/src/projectFavicon.ts
|
|
30508
30919
|
const PROJECT_FAVICON_FALLBACK_MARKER = "project-favicon-missing";
|
|
30509
30920
|
//#endregion
|
|
@@ -30722,6 +31133,10 @@ const PREVIEW_ASSET_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
30722
31133
|
".woff",
|
|
30723
31134
|
".woff2"
|
|
30724
31135
|
]);
|
|
31136
|
+
/** Relative references inside a compiled MDX document resolve to images only. */
|
|
31137
|
+
const MDX_SOURCE_ASSET_EXTENSIONS = new Set(WORKSPACE_IMAGE_PREVIEW_EXTENSIONS);
|
|
31138
|
+
/** Path prefix under an MDX build token that maps to the source directory. */
|
|
31139
|
+
const MDX_SOURCE_ASSET_PREFIX = "assets/";
|
|
30725
31140
|
const AssetClaimsSchema = Schema$1.Union([
|
|
30726
31141
|
Schema$1.Struct({
|
|
30727
31142
|
version: Schema$1.Literal(1),
|
|
@@ -30737,6 +31152,25 @@ const AssetClaimsSchema = Schema$1.Union([
|
|
|
30737
31152
|
relativePath: Schema$1.String,
|
|
30738
31153
|
expiresAt: Schema$1.Number
|
|
30739
31154
|
}),
|
|
31155
|
+
Schema$1.Struct({
|
|
31156
|
+
version: Schema$1.Literal(1),
|
|
31157
|
+
kind: Schema$1.Literal("local-file"),
|
|
31158
|
+
baseDirectory: Schema$1.String,
|
|
31159
|
+
expiresAt: Schema$1.Number
|
|
31160
|
+
}),
|
|
31161
|
+
Schema$1.Struct({
|
|
31162
|
+
version: Schema$1.Literal(1),
|
|
31163
|
+
kind: Schema$1.Literal("local-file-exact"),
|
|
31164
|
+
filePath: Schema$1.String,
|
|
31165
|
+
expiresAt: Schema$1.Number
|
|
31166
|
+
}),
|
|
31167
|
+
Schema$1.Struct({
|
|
31168
|
+
version: Schema$1.Literal(1),
|
|
31169
|
+
kind: Schema$1.Literal("mdx-build"),
|
|
31170
|
+
buildId: Schema$1.String,
|
|
31171
|
+
sourceDirectory: Schema$1.String,
|
|
31172
|
+
expiresAt: Schema$1.Number
|
|
31173
|
+
}),
|
|
30740
31174
|
Schema$1.Struct({
|
|
30741
31175
|
version: Schema$1.Literal(1),
|
|
30742
31176
|
kind: Schema$1.Literal("attachment"),
|
|
@@ -30786,6 +31220,41 @@ const resolveCanonicalWorkspaceFileForRequest = (input) => resolveCanonicalWorks
|
|
|
30786
31220
|
relativePath: input.relativePath,
|
|
30787
31221
|
cause
|
|
30788
31222
|
})), Effect.orElseSucceed(() => null));
|
|
31223
|
+
/**
|
|
31224
|
+
* Reject anything that could walk out of a directory grant.
|
|
31225
|
+
*
|
|
31226
|
+
* Shared by every directory-scoped claim so the workspace grant and the two
|
|
31227
|
+
* new local grants cannot drift apart: a rule relaxed for one of them would
|
|
31228
|
+
* otherwise silently relax for none of the others, which is how the
|
|
31229
|
+
* out-of-workspace path becomes the weak one.
|
|
31230
|
+
*/
|
|
31231
|
+
function isSafeGrantRelativePath(decodedPath, allowedExtensions, extname) {
|
|
31232
|
+
if (decodedPath.length === 0 || decodedPath.includes("\0")) return false;
|
|
31233
|
+
if (decodedPath.split(/[\\/]/).some((segment) => segment === "." || segment === ".." || segment.startsWith("."))) return false;
|
|
31234
|
+
return allowedExtensions.has(extname(decodedPath).toLowerCase());
|
|
31235
|
+
}
|
|
31236
|
+
/**
|
|
31237
|
+
* Resolve a relative path inside a directory grant, following symlinks.
|
|
31238
|
+
*
|
|
31239
|
+
* The realpath comparison is the point: without it a symlink inside the
|
|
31240
|
+
* granted directory would hand out any file on disk while every textual check
|
|
31241
|
+
* above still passed.
|
|
31242
|
+
*/
|
|
31243
|
+
const resolveCanonicalFileWithinDirectory = Effect.fn("AssetAccess.resolveCanonicalFileWithinDirectory")(function* (input) {
|
|
31244
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
31245
|
+
const path = yield* Path.Path;
|
|
31246
|
+
const [canonicalBase, canonicalFile] = yield* Effect.all([optionOnNotFound(fileSystem.realPath(input.baseDirectory)), optionOnNotFound(fileSystem.realPath(path.join(input.baseDirectory, input.relativePath)))]);
|
|
31247
|
+
if (Option.isNone(canonicalBase) || Option.isNone(canonicalFile)) return null;
|
|
31248
|
+
const relative = path.relative(canonicalBase.value, canonicalFile.value);
|
|
31249
|
+
if (relative === "" || relative.startsWith("..") || path.isAbsolute(relative)) return null;
|
|
31250
|
+
const info = yield* optionOnNotFound(fileSystem.stat(canonicalFile.value));
|
|
31251
|
+
return Option.isSome(info) && info.value.type === "File" ? canonicalFile.value : null;
|
|
31252
|
+
});
|
|
31253
|
+
const resolveCanonicalFileWithinDirectoryForRequest = (input) => resolveCanonicalFileWithinDirectory(input).pipe(Effect.tapError((cause) => Effect.logError("Failed to resolve a granted asset path.", {
|
|
31254
|
+
baseDirectory: input.baseDirectory,
|
|
31255
|
+
relativePath: input.relativePath,
|
|
31256
|
+
cause
|
|
31257
|
+
})), Effect.orElseSucceed(() => null));
|
|
30789
31258
|
const issueAssetUrl = Effect.fn("AssetAccess.issueAssetUrl")(function* (input) {
|
|
30790
31259
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
30791
31260
|
const path = yield* Path.Path;
|
|
@@ -30836,6 +31305,59 @@ const issueAssetUrl = Effect.fn("AssetAccess.issueAssetUrl")(function* (input) {
|
|
|
30836
31305
|
fileName = path.basename(resolved.relativePath);
|
|
30837
31306
|
break;
|
|
30838
31307
|
}
|
|
31308
|
+
case "local-file": {
|
|
31309
|
+
if (!path.isAbsolute(input.resource.path)) return yield* new AssetLocalPathValidationError({ resource: input.resource });
|
|
31310
|
+
if (!isWorkspacePreviewEntryPath(input.resource.path)) return yield* new AssetPreviewTypeValidationError({ resource: input.resource });
|
|
31311
|
+
const canonicalFile = yield* optionOnNotFound(fileSystem.realPath(input.resource.path)).pipe(Effect.mapError((cause) => new AssetLocalFileInspectionError({
|
|
31312
|
+
resource: input.resource,
|
|
31313
|
+
cause
|
|
31314
|
+
})));
|
|
31315
|
+
if (Option.isNone(canonicalFile)) return yield* new AssetLocalFileNotFoundError({ resource: input.resource });
|
|
31316
|
+
const info = yield* optionOnNotFound(fileSystem.stat(canonicalFile.value)).pipe(Effect.mapError((cause) => new AssetLocalFileInspectionError({
|
|
31317
|
+
resource: input.resource,
|
|
31318
|
+
cause
|
|
31319
|
+
})));
|
|
31320
|
+
if (Option.isNone(info) || info.value.type !== "File") return yield* new AssetLocalFileNotFoundError({ resource: input.resource });
|
|
31321
|
+
claims = isWorkspaceImagePreviewPath(canonicalFile.value) ? {
|
|
31322
|
+
version: 1,
|
|
31323
|
+
kind: "local-file-exact",
|
|
31324
|
+
filePath: canonicalFile.value,
|
|
31325
|
+
expiresAt
|
|
31326
|
+
} : {
|
|
31327
|
+
version: 1,
|
|
31328
|
+
kind: "local-file",
|
|
31329
|
+
baseDirectory: path.dirname(canonicalFile.value),
|
|
31330
|
+
expiresAt
|
|
31331
|
+
};
|
|
31332
|
+
fileName = path.basename(canonicalFile.value);
|
|
31333
|
+
break;
|
|
31334
|
+
}
|
|
31335
|
+
case "mdx-preview": {
|
|
31336
|
+
if (!path.isAbsolute(input.resource.path)) return yield* new AssetLocalPathValidationError({ resource: input.resource });
|
|
31337
|
+
const config = yield* ServerConfig$1;
|
|
31338
|
+
const now = yield* Clock.currentTimeMillis;
|
|
31339
|
+
const sourcePath = input.resource.path;
|
|
31340
|
+
const build = yield* Effect.tryPromise({
|
|
31341
|
+
try: () => prepareMdxBuild({
|
|
31342
|
+
buildsDir: config.mdxBuildsDir,
|
|
31343
|
+
sourcePath,
|
|
31344
|
+
now
|
|
31345
|
+
}),
|
|
31346
|
+
catch: (cause) => new AssetMdxBuildError({
|
|
31347
|
+
resource: input.resource,
|
|
31348
|
+
cause
|
|
31349
|
+
})
|
|
31350
|
+
});
|
|
31351
|
+
claims = {
|
|
31352
|
+
version: 1,
|
|
31353
|
+
kind: "mdx-build",
|
|
31354
|
+
buildId: build.buildId,
|
|
31355
|
+
sourceDirectory: build.sourceDir,
|
|
31356
|
+
expiresAt
|
|
31357
|
+
};
|
|
31358
|
+
fileName = "meta.json";
|
|
31359
|
+
break;
|
|
31360
|
+
}
|
|
30839
31361
|
case "attachment": {
|
|
30840
31362
|
const attachmentPath = resolveAttachmentPathById({
|
|
30841
31363
|
attachmentsDir: (yield* ServerConfig$1).attachmentsDir,
|
|
@@ -30932,6 +31454,54 @@ const resolveAsset = Effect.fn("AssetAccess.resolveAsset")(function* (token, rel
|
|
|
30932
31454
|
const decodedPath = decodeRelativePath(relativePath);
|
|
30933
31455
|
if (decodedPath === null) return null;
|
|
30934
31456
|
const path = yield* Path.Path;
|
|
31457
|
+
if (claims.kind === "local-file-exact") {
|
|
31458
|
+
if (decodedPath !== path.basename(claims.filePath)) return null;
|
|
31459
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
31460
|
+
const info = yield* optionOnNotFound(fileSystem.stat(claims.filePath)).pipe(Effect.tapError((cause) => Effect.logError("Failed to inspect local asset.", {
|
|
31461
|
+
path: claims.filePath,
|
|
31462
|
+
cause
|
|
31463
|
+
})), Effect.orElseSucceed(() => Option.none()));
|
|
31464
|
+
return Option.isSome(info) && info.value.type === "File" ? {
|
|
31465
|
+
kind: "file",
|
|
31466
|
+
path: claims.filePath
|
|
31467
|
+
} : null;
|
|
31468
|
+
}
|
|
31469
|
+
if (claims.kind === "local-file") {
|
|
31470
|
+
if (!isSafeGrantRelativePath(decodedPath, PREVIEW_ASSET_EXTENSIONS, path.extname)) return null;
|
|
31471
|
+
const localFile = yield* resolveCanonicalFileWithinDirectoryForRequest({
|
|
31472
|
+
baseDirectory: claims.baseDirectory,
|
|
31473
|
+
relativePath: decodedPath
|
|
31474
|
+
});
|
|
31475
|
+
return localFile ? {
|
|
31476
|
+
kind: "file",
|
|
31477
|
+
path: localFile
|
|
31478
|
+
} : null;
|
|
31479
|
+
}
|
|
31480
|
+
if (claims.kind === "mdx-build") {
|
|
31481
|
+
if (!isMdxBuildId(claims.buildId)) return null;
|
|
31482
|
+
const config = yield* ServerConfig$1;
|
|
31483
|
+
if (MDX_BUILD_FILES.has(decodedPath)) {
|
|
31484
|
+
const buildFile = yield* resolveCanonicalFileWithinDirectoryForRequest({
|
|
31485
|
+
baseDirectory: path.join(config.mdxBuildsDir, claims.buildId),
|
|
31486
|
+
relativePath: decodedPath
|
|
31487
|
+
});
|
|
31488
|
+
return buildFile ? {
|
|
31489
|
+
kind: "file",
|
|
31490
|
+
path: buildFile
|
|
31491
|
+
} : null;
|
|
31492
|
+
}
|
|
31493
|
+
if (!decodedPath.startsWith(MDX_SOURCE_ASSET_PREFIX)) return null;
|
|
31494
|
+
const sourceRelativePath = decodedPath.slice(7);
|
|
31495
|
+
if (!isSafeGrantRelativePath(sourceRelativePath, MDX_SOURCE_ASSET_EXTENSIONS, path.extname)) return null;
|
|
31496
|
+
const sourceFile = yield* resolveCanonicalFileWithinDirectoryForRequest({
|
|
31497
|
+
baseDirectory: claims.sourceDirectory,
|
|
31498
|
+
relativePath: sourceRelativePath
|
|
31499
|
+
});
|
|
31500
|
+
return sourceFile ? {
|
|
31501
|
+
kind: "file",
|
|
31502
|
+
path: sourceFile
|
|
31503
|
+
} : null;
|
|
31504
|
+
}
|
|
30935
31505
|
if (claims.kind === "workspace-file-exact") {
|
|
30936
31506
|
if (decodedPath !== path.basename(claims.relativePath)) return null;
|
|
30937
31507
|
const exactWorkspaceFile = yield* resolveCanonicalWorkspaceFileForRequest({
|
|
@@ -30943,8 +31513,7 @@ const resolveAsset = Effect.fn("AssetAccess.resolveAsset")(function* (token, rel
|
|
|
30943
31513
|
path: exactWorkspaceFile
|
|
30944
31514
|
} : null;
|
|
30945
31515
|
}
|
|
30946
|
-
|
|
30947
|
-
if (decodedPath.length === 0 || decodedPath.includes("\0") || segments.some((segment) => segment === "." || segment === ".." || segment.startsWith(".")) || !PREVIEW_ASSET_EXTENSIONS.has(path.extname(decodedPath).toLowerCase())) return null;
|
|
31516
|
+
if (!isSafeGrantRelativePath(decodedPath, PREVIEW_ASSET_EXTENSIONS, path.extname)) return null;
|
|
30948
31517
|
const joinedRelativePath = claims.baseRelativePath === "." ? decodedPath : path.join(claims.baseRelativePath, decodedPath);
|
|
30949
31518
|
const workspaceFile = yield* resolveCanonicalWorkspaceFileForRequest({
|
|
30950
31519
|
workspaceRoot: claims.workspaceRoot,
|
|
@@ -39822,20 +40391,10 @@ var WorkspacePathNotFileError = class extends Schema$1.TaggedErrorClass()("Works
|
|
|
39822
40391
|
return `Workspace path '${this.relativePath}' in '${this.workspaceRoot}' is not a file: ${this.resolvedPath}`;
|
|
39823
40392
|
}
|
|
39824
40393
|
};
|
|
39825
|
-
var WorkspaceBinaryFileError = class extends Schema$1.TaggedErrorClass()("WorkspaceBinaryFileError", {
|
|
39826
|
-
workspaceRoot: Schema$1.String,
|
|
39827
|
-
relativePath: Schema$1.String,
|
|
39828
|
-
resolvedPath: Schema$1.String
|
|
39829
|
-
}) {
|
|
39830
|
-
get message() {
|
|
39831
|
-
return `Workspace file '${this.relativePath}' in '${this.workspaceRoot}' is binary and cannot be previewed as text.`;
|
|
39832
|
-
}
|
|
39833
|
-
};
|
|
39834
40394
|
Schema$1.Union([
|
|
39835
40395
|
WorkspaceFileSystemOperationError,
|
|
39836
40396
|
WorkspaceFilePathEscapeError,
|
|
39837
|
-
WorkspacePathNotFileError
|
|
39838
|
-
WorkspaceBinaryFileError
|
|
40397
|
+
WorkspacePathNotFileError
|
|
39839
40398
|
]);
|
|
39840
40399
|
/** Service tag for workspace file operations. */
|
|
39841
40400
|
var WorkspaceFileSystem = class extends Context.Service()("@p4code/cli/workspace/WorkspaceFileSystem") {};
|
|
@@ -39919,16 +40478,19 @@ const make$29 = Effect.gen(function* () {
|
|
|
39919
40478
|
})
|
|
39920
40479
|
});
|
|
39921
40480
|
const fileBytes = buffer.subarray(0, bytesRead);
|
|
39922
|
-
if (fileBytes.includes(0)) return
|
|
39923
|
-
|
|
39924
|
-
|
|
39925
|
-
|
|
39926
|
-
|
|
40481
|
+
if (fileBytes.includes(0)) return {
|
|
40482
|
+
relativePath: target.relativePath,
|
|
40483
|
+
contents: "",
|
|
40484
|
+
byteLength: stat.size,
|
|
40485
|
+
truncated: false,
|
|
40486
|
+
binary: true
|
|
40487
|
+
};
|
|
39927
40488
|
return {
|
|
39928
40489
|
relativePath: target.relativePath,
|
|
39929
40490
|
contents: new TextDecoder("utf-8").decode(fileBytes),
|
|
39930
40491
|
byteLength: stat.size,
|
|
39931
|
-
truncated: stat.size > PROJECT_READ_FILE_MAX_BYTES
|
|
40492
|
+
truncated: stat.size > PROJECT_READ_FILE_MAX_BYTES,
|
|
40493
|
+
binary: false
|
|
39932
40494
|
};
|
|
39933
40495
|
}), (handle) => Effect.tryPromise({
|
|
39934
40496
|
try: () => handle.close(),
|
|
@@ -45757,10 +46319,6 @@ function projectFileFailureContext(error) {
|
|
|
45757
46319
|
failure: "path_not_file",
|
|
45758
46320
|
resolvedPath: error.resolvedPath
|
|
45759
46321
|
};
|
|
45760
|
-
case "WorkspaceBinaryFileError": return {
|
|
45761
|
-
failure: "binary_file",
|
|
45762
|
-
resolvedPath: error.resolvedPath
|
|
45763
|
-
};
|
|
45764
46322
|
default: return unexpectedCompatibilityError(error);
|
|
45765
46323
|
}
|
|
45766
46324
|
}
|