@mquan/mochi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +154 -0
- package/dist/bin/mochi.d.ts +3 -0
- package/dist/bin/mochi.d.ts.map +1 -0
- package/dist/bin/mochi.js +74 -0
- package/dist/bin/mochi.js.map +1 -0
- package/dist/bin/tsconfig.tsbuildinfo +1 -0
- package/dist/server/analysis/git-context.d.ts +12 -0
- package/dist/server/analysis/git-context.d.ts.map +1 -0
- package/dist/server/analysis/git-context.js +151 -0
- package/dist/server/analysis/git-context.js.map +1 -0
- package/dist/server/analysis/grammars.d.ts +3 -0
- package/dist/server/analysis/grammars.d.ts.map +1 -0
- package/dist/server/analysis/grammars.js +32 -0
- package/dist/server/analysis/grammars.js.map +1 -0
- package/dist/server/analysis/index.d.ts +8 -0
- package/dist/server/analysis/index.d.ts.map +1 -0
- package/dist/server/analysis/index.js +86 -0
- package/dist/server/analysis/index.js.map +1 -0
- package/dist/server/analysis/tree-sitter.d.ts +20 -0
- package/dist/server/analysis/tree-sitter.d.ts.map +1 -0
- package/dist/server/analysis/tree-sitter.js +126 -0
- package/dist/server/analysis/tree-sitter.js.map +1 -0
- package/dist/server/analysis/ts-morph.d.ts +17 -0
- package/dist/server/analysis/ts-morph.d.ts.map +1 -0
- package/dist/server/analysis/ts-morph.js +143 -0
- package/dist/server/analysis/ts-morph.js.map +1 -0
- package/dist/server/analysis/types.d.ts +7 -0
- package/dist/server/analysis/types.d.ts.map +1 -0
- package/dist/server/analysis/types.js +9 -0
- package/dist/server/analysis/types.js.map +1 -0
- package/dist/server/api.d.ts +14 -0
- package/dist/server/api.d.ts.map +1 -0
- package/dist/server/api.js +121 -0
- package/dist/server/api.js.map +1 -0
- package/dist/server/diagram/cache.d.ts +23 -0
- package/dist/server/diagram/cache.d.ts.map +1 -0
- package/dist/server/diagram/cache.js +158 -0
- package/dist/server/diagram/cache.js.map +1 -0
- package/dist/server/diagram/endpoint.d.ts +21 -0
- package/dist/server/diagram/endpoint.d.ts.map +1 -0
- package/dist/server/diagram/endpoint.js +426 -0
- package/dist/server/diagram/endpoint.js.map +1 -0
- package/dist/server/diagram/generate.d.ts +220 -0
- package/dist/server/diagram/generate.d.ts.map +1 -0
- package/dist/server/diagram/generate.js +605 -0
- package/dist/server/diagram/generate.js.map +1 -0
- package/dist/server/diagram/prompt-version.d.ts +2 -0
- package/dist/server/diagram/prompt-version.d.ts.map +1 -0
- package/dist/server/diagram/prompt-version.js +47 -0
- package/dist/server/diagram/prompt-version.js.map +1 -0
- package/dist/server/diagram/prompts/diagram-spec.md +315 -0
- package/dist/server/diagram/scope-resolver.d.ts +44 -0
- package/dist/server/diagram/scope-resolver.d.ts.map +1 -0
- package/dist/server/diagram/scope-resolver.js +198 -0
- package/dist/server/diagram/scope-resolver.js.map +1 -0
- package/dist/server/diagram/spawn.d.ts +18 -0
- package/dist/server/diagram/spawn.d.ts.map +1 -0
- package/dist/server/diagram/spawn.js +103 -0
- package/dist/server/diagram/spawn.js.map +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/input/path-selector.d.ts +8 -0
- package/dist/server/input/path-selector.d.ts.map +1 -0
- package/dist/server/input/path-selector.js +45 -0
- package/dist/server/input/path-selector.js.map +1 -0
- package/dist/server/server.d.ts +14 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +79 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/tsconfig.tsbuildinfo +1 -0
- package/dist/shared/analysis-schema.d.ts +120 -0
- package/dist/shared/analysis-schema.d.ts.map +1 -0
- package/dist/shared/analysis-schema.js +43 -0
- package/dist/shared/analysis-schema.js.map +1 -0
- package/dist/shared/design/index.d.ts +6 -0
- package/dist/shared/design/index.d.ts.map +1 -0
- package/dist/shared/design/index.js +7 -0
- package/dist/shared/design/index.js.map +1 -0
- package/dist/shared/design/kinds.d.ts +26 -0
- package/dist/shared/design/kinds.d.ts.map +1 -0
- package/dist/shared/design/kinds.js +141 -0
- package/dist/shared/design/kinds.js.map +1 -0
- package/dist/shared/design/lenses.d.ts +11 -0
- package/dist/shared/design/lenses.d.ts.map +1 -0
- package/dist/shared/design/lenses.js +36 -0
- package/dist/shared/design/lenses.js.map +1 -0
- package/dist/shared/design/node-styles.d.ts +24 -0
- package/dist/shared/design/node-styles.d.ts.map +1 -0
- package/dist/shared/design/node-styles.js +150 -0
- package/dist/shared/design/node-styles.js.map +1 -0
- package/dist/shared/design/prompt-fragments.d.ts +4 -0
- package/dist/shared/design/prompt-fragments.d.ts.map +1 -0
- package/dist/shared/design/prompt-fragments.js +45 -0
- package/dist/shared/design/prompt-fragments.js.map +1 -0
- package/dist/shared/design/tokens.d.ts +102 -0
- package/dist/shared/design/tokens.d.ts.map +1 -0
- package/dist/shared/design/tokens.js +110 -0
- package/dist/shared/design/tokens.js.map +1 -0
- package/dist/shared/diagram-spec.d.ts +914 -0
- package/dist/shared/diagram-spec.d.ts.map +1 -0
- package/dist/shared/diagram-spec.js +173 -0
- package/dist/shared/diagram-spec.js.map +1 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +2 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/tsconfig.tsbuildinfo +1 -0
- package/dist/web/assets/abap-BdImnpbu.js +1 -0
- package/dist/web/assets/actionscript-3-CoDkCxhg.js +1 -0
- package/dist/web/assets/ada-bCR0ucgS.js +1 -0
- package/dist/web/assets/andromeeda-C4gqWexZ.js +1 -0
- package/dist/web/assets/angular-html-DMxchsRu.js +1 -0
- package/dist/web/assets/angular-ts-DzOHUlBM.js +1 -0
- package/dist/web/assets/apache-Pmp26Uib.js +1 -0
- package/dist/web/assets/apex-D8_7TLub.js +1 -0
- package/dist/web/assets/apl-dKokRX4l.js +1 -0
- package/dist/web/assets/applescript-Co6uUVPk.js +1 -0
- package/dist/web/assets/ara-BRHolxvo.js +1 -0
- package/dist/web/assets/asciidoc-Ve4PFQV2.js +1 -0
- package/dist/web/assets/asm-D_Q5rh1f.js +1 -0
- package/dist/web/assets/astro-CbQHKStN.js +1 -0
- package/dist/web/assets/aurora-x-D-2ljcwZ.js +1 -0
- package/dist/web/assets/awk-DMzUqQB5.js +1 -0
- package/dist/web/assets/ayu-dark-DYE7WIF3.js +1 -0
- package/dist/web/assets/ayu-light-BA47KaF1.js +1 -0
- package/dist/web/assets/ayu-mirage-32ctXXKs.js +1 -0
- package/dist/web/assets/ballerina-BFfxhgS-.js +1 -0
- package/dist/web/assets/bat-BkioyH1T.js +1 -0
- package/dist/web/assets/beancount-k_qm7-4y.js +1 -0
- package/dist/web/assets/berry-uYugtg8r.js +1 -0
- package/dist/web/assets/bibtex-CHM0blh-.js +1 -0
- package/dist/web/assets/bicep-Bmn6On1c.js +1 -0
- package/dist/web/assets/bird2-DPOp833l.js +1 -0
- package/dist/web/assets/blade-D4QpJJKB.js +1 -0
- package/dist/web/assets/bsl-BO_Y6i37.js +1 -0
- package/dist/web/assets/c-BIGW1oBm.js +1 -0
- package/dist/web/assets/c3-eo99z4R2.js +1 -0
- package/dist/web/assets/cadence-Bv_4Rxtq.js +1 -0
- package/dist/web/assets/cairo-KRGpt6FW.js +1 -0
- package/dist/web/assets/catppuccin-frappe-DFWUc33u.js +1 -0
- package/dist/web/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
- package/dist/web/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
- package/dist/web/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
- package/dist/web/assets/clarity-D53aC0YG.js +1 -0
- package/dist/web/assets/clojure-P80f7IUj.js +1 -0
- package/dist/web/assets/cmake-D1j8_8rp.js +1 -0
- package/dist/web/assets/cobol-nwyudZeR.js +1 -0
- package/dist/web/assets/codeowners-Bp6g37R7.js +1 -0
- package/dist/web/assets/codeql-DsOJ9woJ.js +1 -0
- package/dist/web/assets/coffee-Ch7k5sss.js +1 -0
- package/dist/web/assets/common-lisp-Cg-RD9OK.js +1 -0
- package/dist/web/assets/coq-DkFqJrB1.js +1 -0
- package/dist/web/assets/cpp-CofmeUqb.js +1 -0
- package/dist/web/assets/crystal-tKQVLTB8.js +1 -0
- package/dist/web/assets/csharp-COcwbKMJ.js +1 -0
- package/dist/web/assets/css-DPfMkruS.js +1 -0
- package/dist/web/assets/csv-fuZLfV_i.js +1 -0
- package/dist/web/assets/cue-D82EKSYY.js +1 -0
- package/dist/web/assets/cypher-COkxafJQ.js +1 -0
- package/dist/web/assets/d-85-TOEBH.js +1 -0
- package/dist/web/assets/dark-plus-C3mMm8J8.js +1 -0
- package/dist/web/assets/dart-CF10PKvl.js +1 -0
- package/dist/web/assets/dax-CEL-wOlO.js +1 -0
- package/dist/web/assets/desktop-BmXAJ9_W.js +1 -0
- package/dist/web/assets/diff-D97Zzqfu.js +1 -0
- package/dist/web/assets/docker-BcOcwvcX.js +1 -0
- package/dist/web/assets/dotenv-Da5cRb03.js +1 -0
- package/dist/web/assets/dracula-BzJJZx-M.js +1 -0
- package/dist/web/assets/dracula-soft-BXkSAIEj.js +1 -0
- package/dist/web/assets/dream-maker-BtqSS_iP.js +1 -0
- package/dist/web/assets/edge-BkV0erSs.js +1 -0
- package/dist/web/assets/elixir-CDX3lj18.js +1 -0
- package/dist/web/assets/elm-DbKCFpqz.js +1 -0
- package/dist/web/assets/emacs-lisp-C9XAeP06.js +1 -0
- package/dist/web/assets/erb-B12qg9BL.js +1 -0
- package/dist/web/assets/erlang-DsQrWhSR.js +1 -0
- package/dist/web/assets/everforest-dark-BgDCqdQA.js +1 -0
- package/dist/web/assets/everforest-light-C8M2exoo.js +1 -0
- package/dist/web/assets/fennel-BYunw83y.js +1 -0
- package/dist/web/assets/fish-BvzEVeQv.js +1 -0
- package/dist/web/assets/fluent-C4IJs8-o.js +1 -0
- package/dist/web/assets/fortran-fixed-form-CkoXwp7k.js +1 -0
- package/dist/web/assets/fortran-free-form-BxgE0vQu.js +1 -0
- package/dist/web/assets/fsharp-CXgrBDvD.js +1 -0
- package/dist/web/assets/gdresource-BOOCDP_w.js +1 -0
- package/dist/web/assets/gdscript-C5YyOfLZ.js +1 -0
- package/dist/web/assets/gdshader-DkwncUOv.js +1 -0
- package/dist/web/assets/genie-D0YGMca9.js +1 -0
- package/dist/web/assets/gherkin-DyxjwDmM.js +1 -0
- package/dist/web/assets/git-commit-F4YmCXRG.js +1 -0
- package/dist/web/assets/git-rebase-r7XF79zn.js +1 -0
- package/dist/web/assets/github-dark-DHJKELXO.js +1 -0
- package/dist/web/assets/github-dark-default-Cuk6v7N8.js +1 -0
- package/dist/web/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
- package/dist/web/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
- package/dist/web/assets/github-light-DAi9KRSo.js +1 -0
- package/dist/web/assets/github-light-default-D7oLnXFd.js +1 -0
- package/dist/web/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
- package/dist/web/assets/gleam-BspZqrRM.js +1 -0
- package/dist/web/assets/glimmer-js-Rg0-pVw9.js +1 -0
- package/dist/web/assets/glimmer-ts-U6CK756n.js +1 -0
- package/dist/web/assets/glsl-DplSGwfg.js +1 -0
- package/dist/web/assets/gn-n2N0HUVH.js +1 -0
- package/dist/web/assets/gnuplot-DdkO51Og.js +1 -0
- package/dist/web/assets/go-CxLEBnE3.js +1 -0
- package/dist/web/assets/graphql-ChdNCCLP.js +1 -0
- package/dist/web/assets/groovy-gcz8RCvz.js +1 -0
- package/dist/web/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
- package/dist/web/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
- package/dist/web/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
- package/dist/web/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
- package/dist/web/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
- package/dist/web/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
- package/dist/web/assets/hack-CaT9iCJl.js +1 -0
- package/dist/web/assets/haml-B8DHNrY2.js +1 -0
- package/dist/web/assets/handlebars-BL8al0AC.js +1 -0
- package/dist/web/assets/haskell-Df6bDoY_.js +1 -0
- package/dist/web/assets/haxe-CzTSHFRz.js +1 -0
- package/dist/web/assets/hcl-BWvSN4gD.js +1 -0
- package/dist/web/assets/hjson-D5-asLiD.js +1 -0
- package/dist/web/assets/hlsl-D3lLCCz7.js +1 -0
- package/dist/web/assets/horizon-BUw7H-hv.js +1 -0
- package/dist/web/assets/horizon-bright-Cn-bp-IR.js +1 -0
- package/dist/web/assets/houston-DnULxvSX.js +1 -0
- package/dist/web/assets/html-GMplVEZG.js +1 -0
- package/dist/web/assets/html-derivative-BFtXZ54Q.js +1 -0
- package/dist/web/assets/http-jrhK8wxY.js +1 -0
- package/dist/web/assets/hurl-irOxFIW8.js +1 -0
- package/dist/web/assets/hxml-Bvhsp5Yf.js +1 -0
- package/dist/web/assets/hy-DFXneXwc.js +1 -0
- package/dist/web/assets/imba-DGztddWO.js +1 -0
- package/dist/web/assets/index-B4-Q-CcM.js +88 -0
- package/dist/web/assets/index-DtQV41FL.css +1 -0
- package/dist/web/assets/ini-BEwlwnbL.js +1 -0
- package/dist/web/assets/java-CylS5w8V.js +1 -0
- package/dist/web/assets/javascript-wDzz0qaB.js +1 -0
- package/dist/web/assets/jinja-4LBKfQ-Z.js +1 -0
- package/dist/web/assets/jison-wvAkD_A8.js +1 -0
- package/dist/web/assets/json-Cp-IABpG.js +1 -0
- package/dist/web/assets/json5-C9tS-k6U.js +1 -0
- package/dist/web/assets/jsonc-Des-eS-w.js +1 -0
- package/dist/web/assets/jsonl-DcaNXYhu.js +1 -0
- package/dist/web/assets/jsonnet-DFQXde-d.js +1 -0
- package/dist/web/assets/jssm-C2t-YnRu.js +1 -0
- package/dist/web/assets/jsx-g9-lgVsj.js +1 -0
- package/dist/web/assets/julia-CxzCAyBv.js +1 -0
- package/dist/web/assets/just-Cw27pwNe.js +1 -0
- package/dist/web/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
- package/dist/web/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
- package/dist/web/assets/kanagawa-wave-DWedfzmr.js +1 -0
- package/dist/web/assets/kdl-DV7GczEv.js +1 -0
- package/dist/web/assets/kotlin-BdnUsdx6.js +1 -0
- package/dist/web/assets/kusto-DZf3V79B.js +1 -0
- package/dist/web/assets/laserwave-DUszq2jm.js +1 -0
- package/dist/web/assets/latex-CWtU0Tv5.js +1 -0
- package/dist/web/assets/lean-BZvkOJ9d.js +1 -0
- package/dist/web/assets/less-B1dDrJ26.js +1 -0
- package/dist/web/assets/light-plus-B7mTdjB0.js +1 -0
- package/dist/web/assets/liquid-DYVedYrR.js +1 -0
- package/dist/web/assets/llvm-DjAJT7YJ.js +1 -0
- package/dist/web/assets/log-2UxHyX5q.js +1 -0
- package/dist/web/assets/logo-BtOb2qkB.js +1 -0
- package/dist/web/assets/lua-BaeVxFsk.js +1 -0
- package/dist/web/assets/luau-C-HG3fhB.js +1 -0
- package/dist/web/assets/make-CHLpvVh8.js +1 -0
- package/dist/web/assets/markdown-Cvjx9yec.js +1 -0
- package/dist/web/assets/marko-CnJfTvn9.js +1 -0
- package/dist/web/assets/material-theme-D5KoaKCx.js +1 -0
- package/dist/web/assets/material-theme-darker-BfHTSMKl.js +1 -0
- package/dist/web/assets/material-theme-lighter-B0m2ddpp.js +1 -0
- package/dist/web/assets/material-theme-ocean-CyktbL80.js +1 -0
- package/dist/web/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
- package/dist/web/assets/matlab-D7o27uSR.js +1 -0
- package/dist/web/assets/mdc-BMNejdWA.js +1 -0
- package/dist/web/assets/mdx-Cmh6b_Ma.js +1 -0
- package/dist/web/assets/mermaid-mWjccvbQ.js +1 -0
- package/dist/web/assets/min-dark-CafNBF8u.js +1 -0
- package/dist/web/assets/min-light-CTRr51gU.js +1 -0
- package/dist/web/assets/mipsasm-CKIfxQSi.js +1 -0
- package/dist/web/assets/mojo-rZm6bMo-.js +1 -0
- package/dist/web/assets/monokai-D4h5O-jR.js +1 -0
- package/dist/web/assets/moonbit-_H4v1dQx.js +1 -0
- package/dist/web/assets/move-IF9eRakj.js +1 -0
- package/dist/web/assets/narrat-DRg8JJMk.js +1 -0
- package/dist/web/assets/nextflow-Zz6hmt5N.js +1 -0
- package/dist/web/assets/nextflow-groovy-BeH2EWoN.js +1 -0
- package/dist/web/assets/nginx-BpAMiNFr.js +1 -0
- package/dist/web/assets/night-owl-C39BiMTA.js +1 -0
- package/dist/web/assets/night-owl-light-CMTm3GFP.js +1 -0
- package/dist/web/assets/nim-CVrawwO9.js +1 -0
- package/dist/web/assets/nix-CwoSXNpI.js +1 -0
- package/dist/web/assets/nord-Ddv68eIx.js +1 -0
- package/dist/web/assets/nushell-Cz2AlsmD.js +1 -0
- package/dist/web/assets/objective-c-DXmwc3jG.js +1 -0
- package/dist/web/assets/objective-cpp-CLxacb5B.js +1 -0
- package/dist/web/assets/ocaml-C0hk2d4L.js +1 -0
- package/dist/web/assets/odin-BBf5iR-q.js +1 -0
- package/dist/web/assets/one-dark-pro-DVMEJ2y_.js +1 -0
- package/dist/web/assets/one-light-C3Wv6jpd.js +1 -0
- package/dist/web/assets/openscad-C4EeE6gA.js +1 -0
- package/dist/web/assets/pascal-D93ZcfNL.js +1 -0
- package/dist/web/assets/perl-C0TMdlhV.js +1 -0
- package/dist/web/assets/php-Dhbhpdrm.js +1 -0
- package/dist/web/assets/pkl-u5AG7uiY.js +1 -0
- package/dist/web/assets/plastic-3e1v2bzS.js +1 -0
- package/dist/web/assets/plsql-ChMvpjG-.js +1 -0
- package/dist/web/assets/po-BTJTHyun.js +1 -0
- package/dist/web/assets/poimandres-CS3Unz2-.js +1 -0
- package/dist/web/assets/polar-C0HS_06l.js +1 -0
- package/dist/web/assets/postcss-CXtECtnM.js +1 -0
- package/dist/web/assets/powerquery-CEu0bR-o.js +1 -0
- package/dist/web/assets/powershell-Dpen1YoG.js +1 -0
- package/dist/web/assets/prisma-Dd19v3D-.js +1 -0
- package/dist/web/assets/prolog-CbFg5uaA.js +1 -0
- package/dist/web/assets/proto-C7zT0LnQ.js +1 -0
- package/dist/web/assets/pug-CGlum2m_.js +1 -0
- package/dist/web/assets/puppet-BMWR74SV.js +1 -0
- package/dist/web/assets/purescript-CklMAg4u.js +1 -0
- package/dist/web/assets/python-B6aJPvgy.js +1 -0
- package/dist/web/assets/qml-3beO22l8.js +1 -0
- package/dist/web/assets/qmldir-C8lEn-DE.js +1 -0
- package/dist/web/assets/qss-IeuSbFQv.js +1 -0
- package/dist/web/assets/r-Dspwwk_N.js +1 -0
- package/dist/web/assets/racket-BqYA7rlc.js +1 -0
- package/dist/web/assets/raku-DXvB9xmW.js +1 -0
- package/dist/web/assets/razor-Uh8Bk_45.js +1 -0
- package/dist/web/assets/red-bN70gL4F.js +1 -0
- package/dist/web/assets/reg-C-SQnVFl.js +1 -0
- package/dist/web/assets/regexp-CDVJQ6XC.js +1 -0
- package/dist/web/assets/rel-C3B-1QV4.js +1 -0
- package/dist/web/assets/riscv-BM1_JUlF.js +1 -0
- package/dist/web/assets/ron-D8l8udqQ.js +1 -0
- package/dist/web/assets/rose-pine-dawn-DHQR4-dF.js +1 -0
- package/dist/web/assets/rose-pine-moon-D4_iv3hh.js +1 -0
- package/dist/web/assets/rose-pine-qdsjHGoJ.js +1 -0
- package/dist/web/assets/rosmsg-BJDFO7_C.js +1 -0
- package/dist/web/assets/rst-BrH8l1NY.js +1 -0
- package/dist/web/assets/ruby-Dw2BHqvy.js +1 -0
- package/dist/web/assets/rust-B1yitclQ.js +1 -0
- package/dist/web/assets/sas-cz2c8ADy.js +1 -0
- package/dist/web/assets/sass-Cj5Yp3dK.js +1 -0
- package/dist/web/assets/scala-C151Ov-r.js +1 -0
- package/dist/web/assets/scheme-C98Dy4si.js +1 -0
- package/dist/web/assets/scss-OYdSNvt2.js +1 -0
- package/dist/web/assets/sdbl-DVxCFoDh.js +1 -0
- package/dist/web/assets/shaderlab-Dg9Lc6iA.js +1 -0
- package/dist/web/assets/shellscript-Yzrsuije.js +1 -0
- package/dist/web/assets/shellsession-BADoaaVG.js +1 -0
- package/dist/web/assets/slack-dark-BthQWCQV.js +1 -0
- package/dist/web/assets/slack-ochin-DqwNpetd.js +1 -0
- package/dist/web/assets/smalltalk-BERRCDM3.js +1 -0
- package/dist/web/assets/snazzy-light-Bw305WKR.js +1 -0
- package/dist/web/assets/solarized-dark-DXbdFlpD.js +1 -0
- package/dist/web/assets/solarized-light-L9t79GZl.js +1 -0
- package/dist/web/assets/solidity-rGO070M0.js +1 -0
- package/dist/web/assets/soy-Brmx7dQM.js +1 -0
- package/dist/web/assets/sparql-rVzFXLq3.js +1 -0
- package/dist/web/assets/splunk-BtCnVYZw.js +1 -0
- package/dist/web/assets/sql-BLtJtn59.js +1 -0
- package/dist/web/assets/ssh-config-_ykCGR6B.js +1 -0
- package/dist/web/assets/stata-BH5u7GGu.js +1 -0
- package/dist/web/assets/stylus-BEDo0Tqx.js +1 -0
- package/dist/web/assets/surrealql-Bq5Q-fJD.js +1 -0
- package/dist/web/assets/svelte-C_ipcX3V.js +1 -0
- package/dist/web/assets/swift-D82vCrfD.js +1 -0
- package/dist/web/assets/synthwave-84-CbfX1IO0.js +1 -0
- package/dist/web/assets/system-verilog-CnnmHF94.js +1 -0
- package/dist/web/assets/systemd-4A_iFExJ.js +1 -0
- package/dist/web/assets/talonscript-CkByrt1z.js +1 -0
- package/dist/web/assets/tasl-QIJgUcNo.js +1 -0
- package/dist/web/assets/tcl-dwOrl1Do.js +1 -0
- package/dist/web/assets/templ-P3uqSqPl.js +1 -0
- package/dist/web/assets/terraform-BETggiCN.js +1 -0
- package/dist/web/assets/tex-idrVyKtj.js +1 -0
- package/dist/web/assets/tokyo-night-hegEt444.js +1 -0
- package/dist/web/assets/toml-vGWfd6FD.js +1 -0
- package/dist/web/assets/ts-tags-zn1MmPIZ.js +1 -0
- package/dist/web/assets/tsv-B_m7g4N7.js +1 -0
- package/dist/web/assets/tsx-COt5Ahok.js +1 -0
- package/dist/web/assets/turtle-BsS91CYL.js +1 -0
- package/dist/web/assets/twig-DNn4PbVi.js +1 -0
- package/dist/web/assets/typescript-BPQ3VLAy.js +1 -0
- package/dist/web/assets/typespec-BGHnOYBU.js +1 -0
- package/dist/web/assets/typst-DHCkPAjA.js +1 -0
- package/dist/web/assets/v-BcVCzyr7.js +1 -0
- package/dist/web/assets/vala-CsfeWuGM.js +1 -0
- package/dist/web/assets/vb-D17OF-Vu.js +1 -0
- package/dist/web/assets/verilog-BQ8w6xss.js +1 -0
- package/dist/web/assets/vesper-DU1UobuO.js +1 -0
- package/dist/web/assets/vhdl-CeAyd5Ju.js +1 -0
- package/dist/web/assets/viml-CJc9bBzg.js +1 -0
- package/dist/web/assets/vitesse-black-Bkuqu6BP.js +1 -0
- package/dist/web/assets/vitesse-dark-D0r3Knsf.js +1 -0
- package/dist/web/assets/vitesse-light-CVO1_9PV.js +1 -0
- package/dist/web/assets/vue-DN_0RTcg.js +1 -0
- package/dist/web/assets/vue-html-AaS7Mt5G.js +1 -0
- package/dist/web/assets/vue-vine-CQOfvN7w.js +1 -0
- package/dist/web/assets/vyper-CDx5xZoG.js +1 -0
- package/dist/web/assets/wasm-CG6Dc4jp.js +1 -0
- package/dist/web/assets/wasm-MzD3tlZU.js +1 -0
- package/dist/web/assets/wenyan-BV7otONQ.js +1 -0
- package/dist/web/assets/wgsl-Dx-B1_4e.js +1 -0
- package/dist/web/assets/wikitext-BhOHFoWU.js +1 -0
- package/dist/web/assets/wit-5i3qLPDT.js +1 -0
- package/dist/web/assets/wolfram-lXgVvXCa.js +1 -0
- package/dist/web/assets/xml-sdJ4AIDG.js +1 -0
- package/dist/web/assets/xsl-CtQFsRM5.js +1 -0
- package/dist/web/assets/yaml-Buea-lGh.js +1 -0
- package/dist/web/assets/zenscript-DVFEvuxE.js +1 -0
- package/dist/web/assets/zig-VOosw3JB.js +1 -0
- package/dist/web/index.html +13 -0
- package/package.json +56 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// Disk-backed content-hash cache for DiagramSpec.
|
|
2
|
+
//
|
|
3
|
+
// Cache key: SHA-256 of canonical JSON over
|
|
4
|
+
// { files: sortedByPath([{path, sha256(content)}]),
|
|
5
|
+
// intent: intent ?? null,
|
|
6
|
+
// model,
|
|
7
|
+
// prompt_version }
|
|
8
|
+
//
|
|
9
|
+
// File layout: <dir>/<key>.json (one file per entry; no index file).
|
|
10
|
+
//
|
|
11
|
+
// Reliability rules (see `## Architecture` in the task file):
|
|
12
|
+
// 1. cache.put never throws — on disk error, log a warning and resolve.
|
|
13
|
+
// 2. cache.get returns null on missing/corrupt/invalid — never throws.
|
|
14
|
+
// 3. Writes are atomic via tmp-file + rename (POSIX atomic on same FS).
|
|
15
|
+
// 4. The cache directory is created eagerly in createDiagramCache() so an
|
|
16
|
+
// unwritable cache surfaces at boot, not after we've burned an LLM call.
|
|
17
|
+
// If creation fails, the cache is silently disabled (get always returns
|
|
18
|
+
// null, put is a no-op + warn-once).
|
|
19
|
+
import { mkdir, readFile, rename, unlink, writeFile, } from "node:fs/promises";
|
|
20
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
21
|
+
import os from "node:os";
|
|
22
|
+
import path from "node:path";
|
|
23
|
+
import { DiagramSpecValidationError, parseDiagramSpec, } from "../../shared/diagram-spec.js";
|
|
24
|
+
// Where to put cache files when the caller doesn't override the directory.
|
|
25
|
+
// Honors XDG on Linux/macOS, LOCALAPPDATA on Windows.
|
|
26
|
+
export function defaultCacheDir() {
|
|
27
|
+
const platform = os.platform();
|
|
28
|
+
if (platform === "win32") {
|
|
29
|
+
const localAppData = process.env.LOCALAPPDATA ??
|
|
30
|
+
path.join(os.homedir(), "AppData", "Local");
|
|
31
|
+
return path.join(localAppData, "mochi", "Cache", "specs");
|
|
32
|
+
}
|
|
33
|
+
const xdg = process.env.XDG_CACHE_HOME;
|
|
34
|
+
const base = xdg && xdg.length > 0 ? xdg : path.join(os.homedir(), ".cache");
|
|
35
|
+
return path.join(base, "mochi", "specs");
|
|
36
|
+
}
|
|
37
|
+
function sha256Hex(input) {
|
|
38
|
+
return createHash("sha256").update(input).digest("hex");
|
|
39
|
+
}
|
|
40
|
+
export function makeCacheKey(args) {
|
|
41
|
+
// Hash file content first → keeps the canonical input compact and
|
|
42
|
+
// makes the operation O(file_count) rather than O(total_bytes^2).
|
|
43
|
+
const hashedFiles = args.files
|
|
44
|
+
.map((f) => ({ path: f.path, sha: sha256Hex(f.content) }))
|
|
45
|
+
.slice()
|
|
46
|
+
.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
|
|
47
|
+
// Insertion order matters for JSON.stringify — we control it explicitly.
|
|
48
|
+
const canonical = JSON.stringify({
|
|
49
|
+
files: hashedFiles,
|
|
50
|
+
intent: args.intent ?? null,
|
|
51
|
+
model: args.model,
|
|
52
|
+
prompt_version: args.prompt_version,
|
|
53
|
+
});
|
|
54
|
+
return sha256Hex(canonical);
|
|
55
|
+
}
|
|
56
|
+
function pathFor(dir, key) {
|
|
57
|
+
return path.join(dir, `${key}.json`);
|
|
58
|
+
}
|
|
59
|
+
function tmpPathFor(dir, key) {
|
|
60
|
+
// Random suffix avoids collisions between concurrent writers for the same key.
|
|
61
|
+
const random = randomBytes(8).toString("hex");
|
|
62
|
+
return path.join(dir, `${key}.json.tmp.${process.pid}.${random}`);
|
|
63
|
+
}
|
|
64
|
+
export function createDiagramCache(opts = {}) {
|
|
65
|
+
const dir = opts.dir ?? defaultCacheDir();
|
|
66
|
+
const state = {
|
|
67
|
+
disabled: false,
|
|
68
|
+
warnedDisabled: false,
|
|
69
|
+
};
|
|
70
|
+
// Eager mkdir: surface unwritable-cache as a boot-time warning instead of
|
|
71
|
+
// failing on the first put after we've already paid for generation.
|
|
72
|
+
const initPromise = (async () => {
|
|
73
|
+
try {
|
|
74
|
+
await mkdir(dir, { recursive: true });
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
state.disabled = true;
|
|
78
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
79
|
+
console.warn(`mochi cache: directory ${dir} is unwritable (${reason}) — cache disabled for this session`);
|
|
80
|
+
}
|
|
81
|
+
})();
|
|
82
|
+
async function get(key) {
|
|
83
|
+
await initPromise;
|
|
84
|
+
if (state.disabled)
|
|
85
|
+
return null;
|
|
86
|
+
let raw;
|
|
87
|
+
try {
|
|
88
|
+
raw = await readFile(pathFor(dir, key), "utf8");
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
const code = err?.code;
|
|
92
|
+
if (code === "ENOENT")
|
|
93
|
+
return null;
|
|
94
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
95
|
+
console.warn(`mochi cache: read failed for ${key}: ${reason}`);
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
let parsed;
|
|
99
|
+
try {
|
|
100
|
+
parsed = JSON.parse(raw);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
104
|
+
console.warn(`mochi cache: corrupt entry ${key}: invalid JSON (${reason}) — treating as miss`);
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
return parseDiagramSpec(parsed);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
const reason = err instanceof DiagramSpecValidationError
|
|
112
|
+
? err.message
|
|
113
|
+
: err instanceof Error
|
|
114
|
+
? err.message
|
|
115
|
+
: String(err);
|
|
116
|
+
console.warn(`mochi cache: corrupt entry ${key}: schema-invalid (${reason}) — treating as miss`);
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async function put(key, spec) {
|
|
121
|
+
await initPromise;
|
|
122
|
+
if (state.disabled) {
|
|
123
|
+
if (!state.warnedDisabled) {
|
|
124
|
+
state.warnedDisabled = true;
|
|
125
|
+
console.warn(`mochi cache: put(${key}) skipped — cache is disabled for this session`);
|
|
126
|
+
}
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const target = pathFor(dir, key);
|
|
130
|
+
const tmp = tmpPathFor(dir, key);
|
|
131
|
+
try {
|
|
132
|
+
await writeFile(tmp, JSON.stringify(spec), "utf8");
|
|
133
|
+
await rename(tmp, target);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
137
|
+
console.warn(`mochi cache: write failed for ${key}: ${reason}`);
|
|
138
|
+
// Clean up tmp file if rename never happened. Best-effort; ignore errors.
|
|
139
|
+
try {
|
|
140
|
+
await unlink(tmp);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
/* tmp may not exist; nothing to do */
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
get,
|
|
149
|
+
put,
|
|
150
|
+
get dir() {
|
|
151
|
+
return dir;
|
|
152
|
+
},
|
|
153
|
+
get disabled() {
|
|
154
|
+
return state.disabled;
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../server/diagram/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { RequestHandler } from "express";
|
|
2
|
+
import { generateDiagram as defaultGenerate } from "./generate.js";
|
|
3
|
+
import { resolveScope } from "./scope-resolver.js";
|
|
4
|
+
import type { DiagramCache } from "./cache.js";
|
|
5
|
+
export type SseErrorType = "llm_auth" | "llm_rate_limit" | "llm_timeout" | "network" | "validation" | "scope_too_large" | "scope_outside_root" | "file_resolution" | "empty_scope" | "forbidden_origin" | "internal";
|
|
6
|
+
export interface SseErrorPayload {
|
|
7
|
+
type: SseErrorType;
|
|
8
|
+
message: string;
|
|
9
|
+
details?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export declare function mapErrorToSse(err: unknown): SseErrorPayload;
|
|
12
|
+
export interface DiagramHandlerDeps {
|
|
13
|
+
rootDir: string;
|
|
14
|
+
cache: DiagramCache;
|
|
15
|
+
generate?: typeof defaultGenerate;
|
|
16
|
+
promptVersion?: string;
|
|
17
|
+
defaultModel?: string;
|
|
18
|
+
resolve?: typeof resolveScope;
|
|
19
|
+
}
|
|
20
|
+
export declare function createDiagramHandler(deps: DiagramHandlerDeps): RequestHandler;
|
|
21
|
+
//# sourceMappingURL=endpoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint.d.ts","sourceRoot":"","sources":["../../../server/diagram/endpoint.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAW,cAAc,EAAY,MAAM,SAAS,CAAC;AAEjE,OAAO,EAOL,eAAe,IAAI,eAAe,EACnC,MAAM,eAAe,CAAC;AAEvB,OAAO,EAKL,YAAY,EAEb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAa/C,MAAM,MAAM,YAAY,GACpB,UAAU,GACV,gBAAgB,GAChB,aAAa,GACb,SAAS,GACT,YAAY,GACZ,iBAAiB,GACjB,oBAAoB,GACpB,iBAAiB,GACjB,aAAa,GACb,kBAAkB,GAClB,UAAU,CAAC;AAEf,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,CAwD3D;AA4KD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,YAAY,CAAC;IAEpB,QAAQ,CAAC,EAAE,OAAO,eAAe,CAAC;IAElC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,OAAO,CAAC,EAAE,OAAO,YAAY,CAAC;CAC/B;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CAgB7E"}
|
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
// /api/diagram — Server-Sent Events handler.
|
|
2
|
+
//
|
|
3
|
+
// Wire format:
|
|
4
|
+
// event: partial data: <PartialDiagramSpec> (one per generator yield)
|
|
5
|
+
// event: complete data: <DiagramSpec> (final, after cache.put)
|
|
6
|
+
// event: error data: { type, message, details? }
|
|
7
|
+
//
|
|
8
|
+
// Wire-format contract for clients:
|
|
9
|
+
// - The browser EventSource API auto-reconnects on connection close.
|
|
10
|
+
// Clients MUST close the EventSource on receipt of `event: complete` or
|
|
11
|
+
// `event: error` to avoid re-triggering generation. The client side of
|
|
12
|
+
// this contract lives in t10 (streaming-client) — this handler does not
|
|
13
|
+
// attempt to suppress reconnect server-side because there is no
|
|
14
|
+
// standardized mechanism that does so reliably.
|
|
15
|
+
//
|
|
16
|
+
// Status surface: once we've flushed `200 + text/event-stream`, the HTTP
|
|
17
|
+
// status cannot change. All errors flow through `event: error`. The error
|
|
18
|
+
// `type` IS the status surface for the caller.
|
|
19
|
+
//
|
|
20
|
+
// Security: localhost-only server (HOST=127.0.0.1). The same-origin guard
|
|
21
|
+
// rejects browser-triggered cross-origin requests so a rogue tab cannot
|
|
22
|
+
// drain the user's Anthropic budget while mochi is running.
|
|
23
|
+
import { LlmAuthError, LlmNetworkError, LlmRateLimitError, LlmTimeoutError, DiagramSpecValidationError, StreamAbortedError, generateDiagram as defaultGenerate, } from "./generate.js";
|
|
24
|
+
import { PROMPT_VERSION as DEFAULT_PROMPT_VERSION } from "./prompt-version.js";
|
|
25
|
+
import { EmptyScopeError, FileResolutionError, ScopeOutsideRootError, ScopeTooLargeError, resolveScope, } from "./scope-resolver.js";
|
|
26
|
+
import { makeCacheKey } from "./cache.js";
|
|
27
|
+
const DEFAULT_MODEL = "claude-opus-4-7";
|
|
28
|
+
export function mapErrorToSse(err) {
|
|
29
|
+
if (err instanceof LlmAuthError) {
|
|
30
|
+
return {
|
|
31
|
+
type: "llm_auth",
|
|
32
|
+
message: "claude CLI authentication failed. Run `claude /login` and make sure the `claude` CLI is on PATH.",
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (err instanceof LlmRateLimitError) {
|
|
36
|
+
return { type: "llm_rate_limit", message: err.message };
|
|
37
|
+
}
|
|
38
|
+
if (err instanceof LlmTimeoutError) {
|
|
39
|
+
return { type: "llm_timeout", message: err.message };
|
|
40
|
+
}
|
|
41
|
+
if (err instanceof LlmNetworkError) {
|
|
42
|
+
return { type: "network", message: err.message };
|
|
43
|
+
}
|
|
44
|
+
if (err instanceof DiagramSpecValidationError) {
|
|
45
|
+
return {
|
|
46
|
+
type: "validation",
|
|
47
|
+
message: err.message,
|
|
48
|
+
details: { path: err.path },
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (err instanceof ScopeTooLargeError) {
|
|
52
|
+
return {
|
|
53
|
+
type: "scope_too_large",
|
|
54
|
+
message: err.message,
|
|
55
|
+
details: {
|
|
56
|
+
estimated_tokens: err.estimated_tokens,
|
|
57
|
+
max: err.max,
|
|
58
|
+
suggestion: err.suggestion,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (err instanceof ScopeOutsideRootError) {
|
|
63
|
+
return {
|
|
64
|
+
type: "scope_outside_root",
|
|
65
|
+
message: err.message,
|
|
66
|
+
details: { path: err.path },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (err instanceof FileResolutionError) {
|
|
70
|
+
return {
|
|
71
|
+
type: "file_resolution",
|
|
72
|
+
message: err.message,
|
|
73
|
+
details: { path: err.path, reason: err.reason },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (err instanceof EmptyScopeError) {
|
|
77
|
+
return { type: "empty_scope", message: err.message };
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
type: "internal",
|
|
81
|
+
message: err instanceof Error ? err.message : String(err),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// Body / query parsing
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
class BadRequestError extends Error {
|
|
88
|
+
constructor(message) {
|
|
89
|
+
super(message);
|
|
90
|
+
this.name = "BadRequestError";
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function isString(x) {
|
|
94
|
+
return typeof x === "string";
|
|
95
|
+
}
|
|
96
|
+
function isStringArray(x) {
|
|
97
|
+
return Array.isArray(x) && x.every(isString);
|
|
98
|
+
}
|
|
99
|
+
function parseScope(raw) {
|
|
100
|
+
if (raw === null || typeof raw !== "object") {
|
|
101
|
+
throw new BadRequestError("scope must be an object");
|
|
102
|
+
}
|
|
103
|
+
const s = raw;
|
|
104
|
+
const kind = s.kind;
|
|
105
|
+
if (kind === "file") {
|
|
106
|
+
if (!isString(s.path) || s.path.length === 0) {
|
|
107
|
+
throw new BadRequestError("scope.path must be a non-empty string");
|
|
108
|
+
}
|
|
109
|
+
return { kind: "file", path: s.path };
|
|
110
|
+
}
|
|
111
|
+
if (kind === "directory") {
|
|
112
|
+
if (!isString(s.path) || s.path.length === 0) {
|
|
113
|
+
throw new BadRequestError("scope.path must be a non-empty string");
|
|
114
|
+
}
|
|
115
|
+
return { kind: "directory", path: s.path };
|
|
116
|
+
}
|
|
117
|
+
if (kind === "multi") {
|
|
118
|
+
if (!isStringArray(s.paths) || s.paths.length === 0) {
|
|
119
|
+
throw new BadRequestError("scope.paths must be a non-empty array of strings");
|
|
120
|
+
}
|
|
121
|
+
return { kind: "multi", paths: s.paths };
|
|
122
|
+
}
|
|
123
|
+
throw new BadRequestError("scope.kind must be 'file', 'directory', or 'multi'");
|
|
124
|
+
}
|
|
125
|
+
function parseRequest(req) {
|
|
126
|
+
// Prefer body (POST). Fall back to query (GET).
|
|
127
|
+
const body = req.body && typeof req.body === "object" && !Array.isArray(req.body)
|
|
128
|
+
? req.body
|
|
129
|
+
: undefined;
|
|
130
|
+
let scopeRaw;
|
|
131
|
+
let intentRaw;
|
|
132
|
+
let modelRaw;
|
|
133
|
+
if (body && body.scope !== undefined) {
|
|
134
|
+
scopeRaw = body.scope;
|
|
135
|
+
intentRaw = body.intent;
|
|
136
|
+
modelRaw = body.model;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
const q = req.query;
|
|
140
|
+
if (q.scope === undefined) {
|
|
141
|
+
throw new BadRequestError("missing scope (provide JSON body { scope } for POST, or ?scope=<json> for GET)");
|
|
142
|
+
}
|
|
143
|
+
if (typeof q.scope !== "string") {
|
|
144
|
+
throw new BadRequestError("query 'scope' must be a JSON string");
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
scopeRaw = JSON.parse(q.scope);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
throw new BadRequestError("query 'scope' is not valid JSON");
|
|
151
|
+
}
|
|
152
|
+
intentRaw = typeof q.intent === "string" ? q.intent : undefined;
|
|
153
|
+
modelRaw = typeof q.model === "string" ? q.model : undefined;
|
|
154
|
+
}
|
|
155
|
+
const scope = parseScope(scopeRaw);
|
|
156
|
+
const intent = intentRaw === undefined ? undefined : isString(intentRaw)
|
|
157
|
+
? intentRaw
|
|
158
|
+
: (() => {
|
|
159
|
+
throw new BadRequestError("intent must be a string");
|
|
160
|
+
})();
|
|
161
|
+
const model = modelRaw === undefined ? undefined : isString(modelRaw)
|
|
162
|
+
? modelRaw
|
|
163
|
+
: (() => {
|
|
164
|
+
throw new BadRequestError("model must be a string");
|
|
165
|
+
})();
|
|
166
|
+
return { scope, intent, model };
|
|
167
|
+
}
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
// SSE writing
|
|
170
|
+
// ---------------------------------------------------------------------------
|
|
171
|
+
function flushSseHeaders(res) {
|
|
172
|
+
res.status(200);
|
|
173
|
+
res.setHeader("Content-Type", "text/event-stream");
|
|
174
|
+
res.setHeader("Cache-Control", "no-cache, no-transform");
|
|
175
|
+
res.setHeader("Connection", "keep-alive");
|
|
176
|
+
// Defeat proxy buffering (Nginx-style). Localhost path doesn't need this in
|
|
177
|
+
// mochi v1, but it's free insurance against future deployments.
|
|
178
|
+
res.setHeader("X-Accel-Buffering", "no");
|
|
179
|
+
res.flushHeaders();
|
|
180
|
+
}
|
|
181
|
+
function writeSse(res, event, data) {
|
|
182
|
+
// `writable` flips false once the underlying socket is destroyed (typically
|
|
183
|
+
// after the client disconnects). Writing past that point fires an 'error'
|
|
184
|
+
// event on the response stream which Express does not handle by default,
|
|
185
|
+
// so we guard explicitly.
|
|
186
|
+
if (!res.writable)
|
|
187
|
+
return;
|
|
188
|
+
const json = JSON.stringify(data);
|
|
189
|
+
res.write(`event: ${event}\ndata: ${json}\n\n`);
|
|
190
|
+
}
|
|
191
|
+
// Short human-readable scope description for the `resolving_scope` progress
|
|
192
|
+
// event. Examples: "Reading server/api.ts", "Reading 12 files in src/",
|
|
193
|
+
// "Reading 3 selected files". Keep terse — the UI shows this inline.
|
|
194
|
+
function describeScopeShort(scope) {
|
|
195
|
+
if (scope.kind === "file")
|
|
196
|
+
return `Reading ${scope.path}`;
|
|
197
|
+
if (scope.kind === "directory")
|
|
198
|
+
return `Reading directory ${scope.path}/`;
|
|
199
|
+
return `Reading ${scope.paths.length} selected file${scope.paths.length === 1 ? "" : "s"}`;
|
|
200
|
+
}
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
// Origin guard (D1)
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
// Returns true when the request's Origin header is acceptable. We accept:
|
|
205
|
+
// - no Origin header (curl, server-to-server)
|
|
206
|
+
// - Origin matching http://127.0.0.1:<port> or http://localhost:<port>
|
|
207
|
+
// for the port the request is hitting
|
|
208
|
+
function isOriginAllowed(req) {
|
|
209
|
+
const origin = req.headers.origin;
|
|
210
|
+
if (origin === undefined || origin === "null")
|
|
211
|
+
return true;
|
|
212
|
+
if (typeof origin !== "string")
|
|
213
|
+
return false;
|
|
214
|
+
const host = req.get("host"); // includes port; e.g. "127.0.0.1:54321"
|
|
215
|
+
if (!host)
|
|
216
|
+
return false;
|
|
217
|
+
// Build the two acceptable origins for this listener's port. We do not
|
|
218
|
+
// accept https — mochi binds plain HTTP on localhost.
|
|
219
|
+
const port = host.includes(":") ? host.split(":").pop() : "";
|
|
220
|
+
const candidates = port
|
|
221
|
+
? [`http://127.0.0.1:${port}`, `http://localhost:${port}`]
|
|
222
|
+
: ["http://127.0.0.1", "http://localhost"];
|
|
223
|
+
return candidates.includes(origin);
|
|
224
|
+
}
|
|
225
|
+
export function createDiagramHandler(deps) {
|
|
226
|
+
const generate = deps.generate ?? defaultGenerate;
|
|
227
|
+
const resolve = deps.resolve ?? resolveScope;
|
|
228
|
+
const promptVersion = deps.promptVersion ?? DEFAULT_PROMPT_VERSION;
|
|
229
|
+
const defaultModel = deps.defaultModel ?? DEFAULT_MODEL;
|
|
230
|
+
return (req, res) => {
|
|
231
|
+
void handleDiagram(req, res, {
|
|
232
|
+
rootDir: deps.rootDir,
|
|
233
|
+
cache: deps.cache,
|
|
234
|
+
generate,
|
|
235
|
+
resolve,
|
|
236
|
+
promptVersion,
|
|
237
|
+
defaultModel,
|
|
238
|
+
});
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
async function handleDiagram(req, res, deps) {
|
|
242
|
+
const startedAt = Date.now();
|
|
243
|
+
const elapsed = () => Date.now() - startedAt;
|
|
244
|
+
// --- Origin guard (before any side effects, before we open the SSE stream)
|
|
245
|
+
if (!isOriginAllowed(req)) {
|
|
246
|
+
flushSseHeaders(res);
|
|
247
|
+
writeSse(res, "error", {
|
|
248
|
+
type: "forbidden_origin",
|
|
249
|
+
message: "request origin is not allowed (mochi only accepts same-origin requests)",
|
|
250
|
+
});
|
|
251
|
+
res.end();
|
|
252
|
+
console.warn(`mochi: /api/diagram forbidden_origin origin=${String(req.headers.origin)}`);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
// --- Parse request (before opening the SSE stream so a 400 can still go via
|
|
256
|
+
// SSE for client uniformity, but parse failures are fast and we can also
|
|
257
|
+
// tolerate emitting them through the stream).
|
|
258
|
+
let parsed;
|
|
259
|
+
try {
|
|
260
|
+
parsed = parseRequest(req);
|
|
261
|
+
}
|
|
262
|
+
catch (err) {
|
|
263
|
+
flushSseHeaders(res);
|
|
264
|
+
writeSse(res, "error", {
|
|
265
|
+
type: "validation",
|
|
266
|
+
message: err instanceof Error ? err.message : String(err),
|
|
267
|
+
});
|
|
268
|
+
res.end();
|
|
269
|
+
console.warn(`mochi: /api/diagram validation error: ${err instanceof Error ? err.message : String(err)}`);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
console.log(`mochi: /api/diagram start scope_kind=${parsed.scope.kind} intent_present=${parsed.intent !== undefined}`);
|
|
273
|
+
flushSseHeaders(res);
|
|
274
|
+
// --- Resolve scope
|
|
275
|
+
// Progress: emitting phase events alongside partials so the UI can show
|
|
276
|
+
// granular "what's happening now" copy during the multi-step generate flow.
|
|
277
|
+
// LLM calls are seconds-to-minutes; a single spinner is insufficient. The
|
|
278
|
+
// ordering mirrors the actual server-side timeline:
|
|
279
|
+
// resolving_scope → indexed → cache_check → (cache_hit | calling_claude →
|
|
280
|
+
// awaiting_first → streaming → validating) → complete | error
|
|
281
|
+
writeSse(res, "progress", {
|
|
282
|
+
phase: "resolving_scope",
|
|
283
|
+
message: describeScopeShort(parsed.scope),
|
|
284
|
+
});
|
|
285
|
+
let resolved;
|
|
286
|
+
try {
|
|
287
|
+
resolved = await deps.resolve(parsed.scope, deps.rootDir);
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
const payload = mapErrorToSse(err);
|
|
291
|
+
writeSse(res, "error", payload);
|
|
292
|
+
res.end();
|
|
293
|
+
console.warn(`mochi: /api/diagram error type=${payload.type} message=${payload.message}`);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
writeSse(res, "progress", {
|
|
297
|
+
phase: "indexed",
|
|
298
|
+
message: `Indexed ${resolved.files.length} file${resolved.files.length === 1 ? "" : "s"} · ~${resolved.estimated_tokens.toLocaleString()} tokens`,
|
|
299
|
+
data: {
|
|
300
|
+
file_count: resolved.files.length,
|
|
301
|
+
estimated_tokens: resolved.estimated_tokens,
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
// --- Build cache key
|
|
305
|
+
const model = parsed.model ?? deps.defaultModel;
|
|
306
|
+
const key = makeCacheKey({
|
|
307
|
+
files: resolved.files.map((f) => ({ path: f.path, content: f.content })),
|
|
308
|
+
intent: parsed.intent,
|
|
309
|
+
model,
|
|
310
|
+
prompt_version: deps.promptVersion,
|
|
311
|
+
});
|
|
312
|
+
const keyShort = key.slice(0, 12);
|
|
313
|
+
writeSse(res, "progress", {
|
|
314
|
+
phase: "cache_check",
|
|
315
|
+
message: "Checking cache…",
|
|
316
|
+
});
|
|
317
|
+
// --- Cache hit?
|
|
318
|
+
const hit = await deps.cache.get(key);
|
|
319
|
+
if (hit !== null) {
|
|
320
|
+
console.log(`mochi: /api/diagram cache=hit key=${keyShort}... file_count=${resolved.files.length}`);
|
|
321
|
+
writeSse(res, "progress", {
|
|
322
|
+
phase: "cache_hit",
|
|
323
|
+
message: "Cache hit · loading saved diagram",
|
|
324
|
+
});
|
|
325
|
+
writeSse(res, "partial", hit);
|
|
326
|
+
writeSse(res, "complete", hit);
|
|
327
|
+
res.end();
|
|
328
|
+
console.log(`mochi: /api/diagram complete duration_ms=${elapsed()} cache=hit`);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
console.log(`mochi: /api/diagram cache=miss key=${keyShort}... model=${model} file_count=${resolved.files.length}`);
|
|
332
|
+
writeSse(res, "progress", {
|
|
333
|
+
phase: "calling_claude",
|
|
334
|
+
message: "Calling claude CLI…",
|
|
335
|
+
});
|
|
336
|
+
writeSse(res, "progress", {
|
|
337
|
+
phase: "awaiting_first",
|
|
338
|
+
message: "Waiting for Claude's first token…",
|
|
339
|
+
});
|
|
340
|
+
// --- Generate (with abort propagation)
|
|
341
|
+
const ctrl = new AbortController();
|
|
342
|
+
let completed = false;
|
|
343
|
+
let aborted = false;
|
|
344
|
+
const onClose = () => {
|
|
345
|
+
if (completed || aborted)
|
|
346
|
+
return;
|
|
347
|
+
aborted = true;
|
|
348
|
+
ctrl.abort();
|
|
349
|
+
};
|
|
350
|
+
// Listen on both req and res — in modern Node (>=15) the response stream's
|
|
351
|
+
// 'close' event is the reliable signal for connection termination, while
|
|
352
|
+
// older guidance points at req.on('close'). Registering both is harmless.
|
|
353
|
+
req.on("close", onClose);
|
|
354
|
+
res.on("close", onClose);
|
|
355
|
+
try {
|
|
356
|
+
// Buffer-then-emit: the generator yields N PartialDiagramSpec values then
|
|
357
|
+
// exactly one DiagramSpec at the end. We don't know which yield is final
|
|
358
|
+
// until the loop ends, so we hold the previous yield and emit it as
|
|
359
|
+
// 'partial' on the next iteration.
|
|
360
|
+
let prev;
|
|
361
|
+
let emittedStreamingPhase = false;
|
|
362
|
+
for await (const out of deps.generate({
|
|
363
|
+
scope: resolved,
|
|
364
|
+
intent: parsed.intent,
|
|
365
|
+
model,
|
|
366
|
+
signal: ctrl.signal,
|
|
367
|
+
})) {
|
|
368
|
+
if (aborted)
|
|
369
|
+
break;
|
|
370
|
+
// First iteration: tokens started arriving. Transition the UI phase from
|
|
371
|
+
// "awaiting_first" → "streaming". Subsequent partials drive a count
|
|
372
|
+
// overlay client-side (no extra progress events needed during streaming).
|
|
373
|
+
if (!emittedStreamingPhase) {
|
|
374
|
+
writeSse(res, "progress", {
|
|
375
|
+
phase: "streaming",
|
|
376
|
+
message: "Receiving response…",
|
|
377
|
+
});
|
|
378
|
+
emittedStreamingPhase = true;
|
|
379
|
+
}
|
|
380
|
+
if (prev !== undefined) {
|
|
381
|
+
writeSse(res, "partial", prev);
|
|
382
|
+
}
|
|
383
|
+
prev = out;
|
|
384
|
+
}
|
|
385
|
+
if (aborted) {
|
|
386
|
+
// Re-enter the abort branch so we log + end uniformly.
|
|
387
|
+
throw new StreamAbortedError();
|
|
388
|
+
}
|
|
389
|
+
if (prev === undefined) {
|
|
390
|
+
throw new Error("generator yielded no values");
|
|
391
|
+
}
|
|
392
|
+
writeSse(res, "progress", {
|
|
393
|
+
phase: "validating",
|
|
394
|
+
message: "Validating diagram structure…",
|
|
395
|
+
});
|
|
396
|
+
const final = prev;
|
|
397
|
+
await deps.cache.put(key, final);
|
|
398
|
+
writeSse(res, "complete", final);
|
|
399
|
+
completed = true;
|
|
400
|
+
res.end();
|
|
401
|
+
console.log(`mochi: /api/diagram complete duration_ms=${elapsed()} cache=miss`);
|
|
402
|
+
}
|
|
403
|
+
catch (err) {
|
|
404
|
+
if (err instanceof StreamAbortedError || aborted) {
|
|
405
|
+
// Client went away — don't try to emit; the socket is gone (write would
|
|
406
|
+
// EPIPE). Just log.
|
|
407
|
+
console.log(`mochi: /api/diagram aborted_by_client duration_ms=${elapsed()}`);
|
|
408
|
+
try {
|
|
409
|
+
res.end();
|
|
410
|
+
}
|
|
411
|
+
catch {
|
|
412
|
+
/* socket already closed */
|
|
413
|
+
}
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
const payload = mapErrorToSse(err);
|
|
417
|
+
writeSse(res, "error", payload);
|
|
418
|
+
res.end();
|
|
419
|
+
console.warn(`mochi: /api/diagram error type=${payload.type} message=${payload.message} duration_ms=${elapsed()}`);
|
|
420
|
+
}
|
|
421
|
+
finally {
|
|
422
|
+
req.off("close", onClose);
|
|
423
|
+
res.off("close", onClose);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
//# sourceMappingURL=endpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../../../server/diagram/endpoint.ts"],"names":[],"mappings":"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"}
|