hammoc 1.0.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/LICENSE +661 -0
- package/README.md +272 -0
- package/bin/hammoc.js +59 -0
- package/package.json +86 -0
- package/packages/client/dist/assets/abap-DsBKuouk.js +1 -0
- package/packages/client/dist/assets/actionscript-3-D_z4Izcz.js +1 -0
- package/packages/client/dist/assets/ada-727ZlQH0.js +1 -0
- package/packages/client/dist/assets/andromeeda-C3khCPGq.js +1 -0
- package/packages/client/dist/assets/angular-html-LfdN0zeE.js +1 -0
- package/packages/client/dist/assets/angular-ts-CKsD7JZE.js +1 -0
- package/packages/client/dist/assets/apache-Dn00JSTd.js +1 -0
- package/packages/client/dist/assets/apex-COJ4H7py.js +1 -0
- package/packages/client/dist/assets/apl-BBq3IX1j.js +1 -0
- package/packages/client/dist/assets/applescript-Bu5BbsvL.js +1 -0
- package/packages/client/dist/assets/ara-7O62HKoU.js +1 -0
- package/packages/client/dist/assets/asciidoc-BPT9niGB.js +1 -0
- package/packages/client/dist/assets/asm-Dhn9LcZ4.js +1 -0
- package/packages/client/dist/assets/astro-CqkE3fuf.js +1 -0
- package/packages/client/dist/assets/aurora-x-D-2ljcwZ.js +1 -0
- package/packages/client/dist/assets/awk-eg146-Ew.js +1 -0
- package/packages/client/dist/assets/ayu-dark-Cv9koXgw.js +1 -0
- package/packages/client/dist/assets/ballerina-Du268qiB.js +1 -0
- package/packages/client/dist/assets/bat-fje9CFhw.js +1 -0
- package/packages/client/dist/assets/beancount-BwXTMy5W.js +1 -0
- package/packages/client/dist/assets/berry-3xVqZejG.js +1 -0
- package/packages/client/dist/assets/bibtex-xW4inM5L.js +1 -0
- package/packages/client/dist/assets/bicep-DHo0CJ0O.js +1 -0
- package/packages/client/dist/assets/blade-a8OxSdnT.js +1 -0
- package/packages/client/dist/assets/bsl-Dgyn0ogV.js +1 -0
- package/packages/client/dist/assets/c-C3t2pwGQ.js +1 -0
- package/packages/client/dist/assets/cadence-DNquZEk8.js +1 -0
- package/packages/client/dist/assets/cairo--RitsXJZ.js +1 -0
- package/packages/client/dist/assets/catppuccin-frappe-CD_QflpE.js +1 -0
- package/packages/client/dist/assets/catppuccin-latte-DRW-0cLl.js +1 -0
- package/packages/client/dist/assets/catppuccin-macchiato-C-_shW-Y.js +1 -0
- package/packages/client/dist/assets/catppuccin-mocha-LGGdnPYs.js +1 -0
- package/packages/client/dist/assets/clarity-BHOwM8T6.js +1 -0
- package/packages/client/dist/assets/clojure-DxSadP1t.js +1 -0
- package/packages/client/dist/assets/cmake-DbXoA79R.js +1 -0
- package/packages/client/dist/assets/cobol-PTqiYgYu.js +1 -0
- package/packages/client/dist/assets/codeowners-Bp6g37R7.js +1 -0
- package/packages/client/dist/assets/codeql-sacFqUAJ.js +1 -0
- package/packages/client/dist/assets/coffee-dyiR41kL.js +1 -0
- package/packages/client/dist/assets/common-lisp-C7gG9l05.js +1 -0
- package/packages/client/dist/assets/coq-Dsg_Bt_b.js +1 -0
- package/packages/client/dist/assets/cpp-BksuvNSY.js +1 -0
- package/packages/client/dist/assets/crystal-DtDmRg-F.js +1 -0
- package/packages/client/dist/assets/csharp-D9R-vmeu.js +1 -0
- package/packages/client/dist/assets/css-BPhBrDlE.js +1 -0
- package/packages/client/dist/assets/csv-B0qRVHPH.js +1 -0
- package/packages/client/dist/assets/cue-DtFQj3wx.js +1 -0
- package/packages/client/dist/assets/cypher-m2LEI-9-.js +1 -0
- package/packages/client/dist/assets/d-BoXegm-a.js +1 -0
- package/packages/client/dist/assets/dark-plus-C3mMm8J8.js +1 -0
- package/packages/client/dist/assets/dart-B9wLZaAG.js +1 -0
- package/packages/client/dist/assets/dax-ClGRhx96.js +1 -0
- package/packages/client/dist/assets/desktop-DEIpsLCJ.js +1 -0
- package/packages/client/dist/assets/diff-BgYniUM_.js +1 -0
- package/packages/client/dist/assets/docker-COcR7UxN.js +1 -0
- package/packages/client/dist/assets/dotenv-BjQB5zDj.js +1 -0
- package/packages/client/dist/assets/dracula-BzJJZx-M.js +1 -0
- package/packages/client/dist/assets/dracula-soft-BXkSAIEj.js +1 -0
- package/packages/client/dist/assets/dream-maker-C-nORZOA.js +1 -0
- package/packages/client/dist/assets/edge-D5gP-w-T.js +1 -0
- package/packages/client/dist/assets/elixir-CLiX3zqd.js +1 -0
- package/packages/client/dist/assets/elm-CmHSxxaM.js +1 -0
- package/packages/client/dist/assets/emacs-lisp-BX77sIaO.js +1 -0
- package/packages/client/dist/assets/erb-BYTLMnw6.js +1 -0
- package/packages/client/dist/assets/erlang-B-DoSBHF.js +1 -0
- package/packages/client/dist/assets/everforest-dark-BgDCqdQA.js +1 -0
- package/packages/client/dist/assets/everforest-light-C8M2exoo.js +1 -0
- package/packages/client/dist/assets/fennel-bCA53EVm.js +1 -0
- package/packages/client/dist/assets/fish-w-ucz2PV.js +1 -0
- package/packages/client/dist/assets/fluent-Dayu4EKP.js +1 -0
- package/packages/client/dist/assets/fortran-fixed-form-TqA4NnZg.js +1 -0
- package/packages/client/dist/assets/fortran-free-form-DKXYxT9g.js +1 -0
- package/packages/client/dist/assets/fsharp-XplgxFYe.js +1 -0
- package/packages/client/dist/assets/gdresource-BHYsBjWJ.js +1 -0
- package/packages/client/dist/assets/gdscript-DfxzS6Rs.js +1 -0
- package/packages/client/dist/assets/gdshader-SKMF96pI.js +1 -0
- package/packages/client/dist/assets/genie-ajMbGru0.js +1 -0
- package/packages/client/dist/assets/gherkin--30QC5Em.js +1 -0
- package/packages/client/dist/assets/git-commit-i4q6IMui.js +1 -0
- package/packages/client/dist/assets/git-rebase-B-v9cOL2.js +1 -0
- package/packages/client/dist/assets/github-dark-DHJKELXO.js +1 -0
- package/packages/client/dist/assets/github-dark-default-Cuk6v7N8.js +1 -0
- package/packages/client/dist/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
- package/packages/client/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
- package/packages/client/dist/assets/github-light-DAi9KRSo.js +1 -0
- package/packages/client/dist/assets/github-light-default-D7oLnXFd.js +1 -0
- package/packages/client/dist/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
- package/packages/client/dist/assets/gleam-B430Bg39.js +1 -0
- package/packages/client/dist/assets/glimmer-js-D-cwc0-E.js +1 -0
- package/packages/client/dist/assets/glimmer-ts-pgjy16dm.js +1 -0
- package/packages/client/dist/assets/glsl-DBO2IWDn.js +1 -0
- package/packages/client/dist/assets/gnuplot-CM8KxXT1.js +1 -0
- package/packages/client/dist/assets/go-B1SYOhNW.js +1 -0
- package/packages/client/dist/assets/graphql-cDcHW_If.js +1 -0
- package/packages/client/dist/assets/groovy-DkBy-JyN.js +1 -0
- package/packages/client/dist/assets/hack-D1yCygmZ.js +1 -0
- package/packages/client/dist/assets/haml-B2EZWmdv.js +1 -0
- package/packages/client/dist/assets/handlebars-BQGss363.js +1 -0
- package/packages/client/dist/assets/haskell-BILxekzW.js +1 -0
- package/packages/client/dist/assets/haxe-C5wWYbrZ.js +1 -0
- package/packages/client/dist/assets/hcl-HzYwdGDm.js +1 -0
- package/packages/client/dist/assets/hjson-T-Tgc4AT.js +1 -0
- package/packages/client/dist/assets/hlsl-ifBTmRxC.js +1 -0
- package/packages/client/dist/assets/houston-DnULxvSX.js +1 -0
- package/packages/client/dist/assets/html-C2L_23MC.js +1 -0
- package/packages/client/dist/assets/html-derivative-CSfWNPLT.js +1 -0
- package/packages/client/dist/assets/http-FRrOvY1W.js +1 -0
- package/packages/client/dist/assets/hxml-TIA70rKU.js +1 -0
- package/packages/client/dist/assets/hy-BMj5Y0dO.js +1 -0
- package/packages/client/dist/assets/imba-bv_oIlVt.js +1 -0
- package/packages/client/dist/assets/index-Bzql1gnR.js +2 -0
- package/packages/client/dist/assets/index-DjQDxRju.css +32 -0
- package/packages/client/dist/assets/index-q3VZc6RP.js +1297 -0
- package/packages/client/dist/assets/ini-BjABl1g7.js +1 -0
- package/packages/client/dist/assets/java-xI-RfyKK.js +1 -0
- package/packages/client/dist/assets/javascript-ySlJ1b_l.js +1 -0
- package/packages/client/dist/assets/jinja-DGy0s7-h.js +1 -0
- package/packages/client/dist/assets/jison-BqZprYcd.js +1 -0
- package/packages/client/dist/assets/json-BQoSv7ci.js +1 -0
- package/packages/client/dist/assets/json5-w8dY5SsB.js +1 -0
- package/packages/client/dist/assets/jsonc-TU54ms6u.js +1 -0
- package/packages/client/dist/assets/jsonl-DREVFZK8.js +1 -0
- package/packages/client/dist/assets/jsonnet-BfivnA6A.js +1 -0
- package/packages/client/dist/assets/jssm-P4WzXJd0.js +1 -0
- package/packages/client/dist/assets/jsx-BAng5TT0.js +1 -0
- package/packages/client/dist/assets/julia-BBuGR-5E.js +1 -0
- package/packages/client/dist/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
- package/packages/client/dist/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
- package/packages/client/dist/assets/kanagawa-wave-DWedfzmr.js +1 -0
- package/packages/client/dist/assets/kotlin-B5lbUyaz.js +1 -0
- package/packages/client/dist/assets/kusto-mebxcVVE.js +1 -0
- package/packages/client/dist/assets/laserwave-DUszq2jm.js +1 -0
- package/packages/client/dist/assets/latex-C-cWTeAZ.js +1 -0
- package/packages/client/dist/assets/lean-XBlWyCtg.js +1 -0
- package/packages/client/dist/assets/less-BfCpw3nA.js +1 -0
- package/packages/client/dist/assets/light-plus-B7mTdjB0.js +1 -0
- package/packages/client/dist/assets/liquid-D3W5UaiH.js +1 -0
- package/packages/client/dist/assets/log-Cc5clBb7.js +1 -0
- package/packages/client/dist/assets/logo-IuBKFhSY.js +1 -0
- package/packages/client/dist/assets/lua-CvWAzNxB.js +1 -0
- package/packages/client/dist/assets/luau-Du5NY7AG.js +1 -0
- package/packages/client/dist/assets/make-Bvotw-X0.js +1 -0
- package/packages/client/dist/assets/markdown-UIAJJxZW.js +1 -0
- package/packages/client/dist/assets/marko-z0MBrx5-.js +1 -0
- package/packages/client/dist/assets/material-theme-D5KoaKCx.js +1 -0
- package/packages/client/dist/assets/material-theme-darker-BfHTSMKl.js +1 -0
- package/packages/client/dist/assets/material-theme-lighter-B0m2ddpp.js +1 -0
- package/packages/client/dist/assets/material-theme-ocean-CyktbL80.js +1 -0
- package/packages/client/dist/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
- package/packages/client/dist/assets/matlab-D9-PGadD.js +1 -0
- package/packages/client/dist/assets/mdc-DB_EDNY_.js +1 -0
- package/packages/client/dist/assets/mdx-sdHcTMYB.js +1 -0
- package/packages/client/dist/assets/mermaid-Ci6OQyBP.js +1 -0
- package/packages/client/dist/assets/min-dark-CafNBF8u.js +1 -0
- package/packages/client/dist/assets/min-light-CTRr51gU.js +1 -0
- package/packages/client/dist/assets/mipsasm-BC5c_5Pe.js +1 -0
- package/packages/client/dist/assets/mojo-Tz6hzZYG.js +1 -0
- package/packages/client/dist/assets/monokai-D4h5O-jR.js +1 -0
- package/packages/client/dist/assets/move-DB_GagMm.js +1 -0
- package/packages/client/dist/assets/narrat-DLbgOhZU.js +1 -0
- package/packages/client/dist/assets/nextflow-B0XVJmRM.js +1 -0
- package/packages/client/dist/assets/nginx-D_VnBJ67.js +1 -0
- package/packages/client/dist/assets/night-owl-C39BiMTA.js +1 -0
- package/packages/client/dist/assets/nim-ZlGxZxc3.js +1 -0
- package/packages/client/dist/assets/nix-shcSOmrb.js +1 -0
- package/packages/client/dist/assets/nord-Ddv68eIx.js +1 -0
- package/packages/client/dist/assets/nushell-D4Tzg5kh.js +1 -0
- package/packages/client/dist/assets/objective-c-Deuh7S70.js +1 -0
- package/packages/client/dist/assets/objective-cpp-BUEGK8hf.js +1 -0
- package/packages/client/dist/assets/ocaml-BNioltXt.js +1 -0
- package/packages/client/dist/assets/one-dark-pro-GBQ2dnAY.js +1 -0
- package/packages/client/dist/assets/one-light-PoHY5YXO.js +1 -0
- package/packages/client/dist/assets/pascal-JqZropPD.js +1 -0
- package/packages/client/dist/assets/perl-CHQXSrWU.js +1 -0
- package/packages/client/dist/assets/php-B5ebYQev.js +1 -0
- package/packages/client/dist/assets/plastic-3e1v2bzS.js +1 -0
- package/packages/client/dist/assets/plsql-LKU2TuZ1.js +1 -0
- package/packages/client/dist/assets/po-BFLt1xDp.js +1 -0
- package/packages/client/dist/assets/poimandres-CS3Unz2-.js +1 -0
- package/packages/client/dist/assets/polar-DKykz6zU.js +1 -0
- package/packages/client/dist/assets/postcss-B3ZDOciz.js +1 -0
- package/packages/client/dist/assets/powerquery-CSHBycmS.js +1 -0
- package/packages/client/dist/assets/powershell-BIEUsx6d.js +1 -0
- package/packages/client/dist/assets/prisma-B48N-Iqd.js +1 -0
- package/packages/client/dist/assets/prolog-BY-TUvya.js +1 -0
- package/packages/client/dist/assets/proto-zocC4JxJ.js +1 -0
- package/packages/client/dist/assets/pug-CM9l7STV.js +1 -0
- package/packages/client/dist/assets/puppet-Cza_XSSt.js +1 -0
- package/packages/client/dist/assets/purescript-Bg-kzb6g.js +1 -0
- package/packages/client/dist/assets/python-DhUJRlN_.js +1 -0
- package/packages/client/dist/assets/qml-D8XfuvdV.js +1 -0
- package/packages/client/dist/assets/qmldir-C8lEn-DE.js +1 -0
- package/packages/client/dist/assets/qss-DhMKtDLN.js +1 -0
- package/packages/client/dist/assets/r-CwjWoCRV.js +1 -0
- package/packages/client/dist/assets/racket-CzouJOBO.js +1 -0
- package/packages/client/dist/assets/raku-B1bQXN8T.js +1 -0
- package/packages/client/dist/assets/razor-CNLDkMZG.js +1 -0
- package/packages/client/dist/assets/red-bN70gL4F.js +1 -0
- package/packages/client/dist/assets/reg-5LuOXUq_.js +1 -0
- package/packages/client/dist/assets/regexp-DWJ3fJO_.js +1 -0
- package/packages/client/dist/assets/rel-DJlmqQ1C.js +1 -0
- package/packages/client/dist/assets/riscv-QhoSD0DR.js +1 -0
- package/packages/client/dist/assets/rose-pine-CmCqftbK.js +1 -0
- package/packages/client/dist/assets/rose-pine-dawn-Ds-gbosJ.js +1 -0
- package/packages/client/dist/assets/rose-pine-moon-CjDtw9vr.js +1 -0
- package/packages/client/dist/assets/rst-4NLicBqY.js +1 -0
- package/packages/client/dist/assets/ruby-DeZ3UC14.js +1 -0
- package/packages/client/dist/assets/rust-Be6lgOlo.js +1 -0
- package/packages/client/dist/assets/sas-BmTFh92c.js +1 -0
- package/packages/client/dist/assets/sass-BJ4Li9vH.js +1 -0
- package/packages/client/dist/assets/scala-DQVVAn-B.js +1 -0
- package/packages/client/dist/assets/scheme-BJGe-b2p.js +1 -0
- package/packages/client/dist/assets/scss-C31hgJw-.js +1 -0
- package/packages/client/dist/assets/sdbl-BLhTXw86.js +1 -0
- package/packages/client/dist/assets/shaderlab-B7qAK45m.js +1 -0
- package/packages/client/dist/assets/shellscript-atvbtKCR.js +1 -0
- package/packages/client/dist/assets/shellsession-C_rIy8kc.js +1 -0
- package/packages/client/dist/assets/slack-dark-BthQWCQV.js +1 -0
- package/packages/client/dist/assets/slack-ochin-DqwNpetd.js +1 -0
- package/packages/client/dist/assets/smalltalk-DkLiglaE.js +1 -0
- package/packages/client/dist/assets/snazzy-light-Bw305WKR.js +1 -0
- package/packages/client/dist/assets/solarized-dark-DXbdFlpD.js +1 -0
- package/packages/client/dist/assets/solarized-light-L9t79GZl.js +1 -0
- package/packages/client/dist/assets/solidity-C1w2a3ep.js +1 -0
- package/packages/client/dist/assets/soy-C-lX7w71.js +1 -0
- package/packages/client/dist/assets/sparql-bYkjHRlG.js +1 -0
- package/packages/client/dist/assets/splunk-Cf8iN4DR.js +1 -0
- package/packages/client/dist/assets/sql-COK4E0Yg.js +1 -0
- package/packages/client/dist/assets/ssh-config-BknIz3MU.js +1 -0
- package/packages/client/dist/assets/stata-DorPZHa4.js +1 -0
- package/packages/client/dist/assets/stylus-BeQkCIfX.js +1 -0
- package/packages/client/dist/assets/svelte-MSaWC3Je.js +1 -0
- package/packages/client/dist/assets/swift-BSxZ-RaX.js +1 -0
- package/packages/client/dist/assets/synthwave-84-CbfX1IO0.js +1 -0
- package/packages/client/dist/assets/system-verilog-C7L56vO4.js +1 -0
- package/packages/client/dist/assets/systemd-CUnW07Te.js +1 -0
- package/packages/client/dist/assets/talonscript-C1XDQQGZ.js +1 -0
- package/packages/client/dist/assets/tasl-CQjiPCtT.js +1 -0
- package/packages/client/dist/assets/tcl-DQ1-QYvQ.js +1 -0
- package/packages/client/dist/assets/templ-dwX3ZSMB.js +1 -0
- package/packages/client/dist/assets/terraform-BbSNqyBO.js +1 -0
- package/packages/client/dist/assets/tex-rYs2v40G.js +1 -0
- package/packages/client/dist/assets/tokyo-night-DBQeEorK.js +1 -0
- package/packages/client/dist/assets/toml-CB2ApiWb.js +1 -0
- package/packages/client/dist/assets/ts-tags-CipyTH0X.js +1 -0
- package/packages/client/dist/assets/tsv-B_m7g4N7.js +1 -0
- package/packages/client/dist/assets/tsx-B6W0miNI.js +1 -0
- package/packages/client/dist/assets/turtle-BMR_PYu6.js +1 -0
- package/packages/client/dist/assets/twig-NC5TFiHP.js +1 -0
- package/packages/client/dist/assets/typescript-Dj6nwHGl.js +1 -0
- package/packages/client/dist/assets/typespec-BpWG_bgh.js +1 -0
- package/packages/client/dist/assets/typst-BVUVsWT6.js +1 -0
- package/packages/client/dist/assets/v-CAQ2eGtk.js +1 -0
- package/packages/client/dist/assets/vala-BFOHcciG.js +1 -0
- package/packages/client/dist/assets/vb-CdO5JTpU.js +1 -0
- package/packages/client/dist/assets/verilog-CJaU5se_.js +1 -0
- package/packages/client/dist/assets/vesper-BEBZ7ncR.js +1 -0
- package/packages/client/dist/assets/vhdl-DYoNaHQp.js +1 -0
- package/packages/client/dist/assets/viml-m4uW47V2.js +1 -0
- package/packages/client/dist/assets/vitesse-black-Bkuqu6BP.js +1 -0
- package/packages/client/dist/assets/vitesse-dark-D0r3Knsf.js +1 -0
- package/packages/client/dist/assets/vitesse-light-CVO1_9PV.js +1 -0
- package/packages/client/dist/assets/vue-BuYVFjOK.js +1 -0
- package/packages/client/dist/assets/vue-html-xdeiXROB.js +1 -0
- package/packages/client/dist/assets/vyper-nyqBNV6O.js +1 -0
- package/packages/client/dist/assets/wasm-C6j12Q_x.js +1 -0
- package/packages/client/dist/assets/wasm-CG6Dc4jp.js +1 -0
- package/packages/client/dist/assets/wenyan-7A4Fjokl.js +1 -0
- package/packages/client/dist/assets/wgsl-CB0Krxn9.js +1 -0
- package/packages/client/dist/assets/wikitext-DCE3LsBG.js +1 -0
- package/packages/client/dist/assets/wolfram-C3FkfJm5.js +1 -0
- package/packages/client/dist/assets/xml-e3z08dGr.js +1 -0
- package/packages/client/dist/assets/xsl-Dd0NUgwM.js +1 -0
- package/packages/client/dist/assets/yaml-CVw76BM1.js +1 -0
- package/packages/client/dist/assets/zenscript-HnGAYVZD.js +1 -0
- package/packages/client/dist/assets/zig-BVz_zdnA.js +1 -0
- package/packages/client/dist/index.html +13 -0
- package/packages/server/dist/__tests__/i18n.test.d.ts +5 -0
- package/packages/server/dist/__tests__/i18n.test.d.ts.map +1 -0
- package/packages/server/dist/__tests__/i18n.test.js +31 -0
- package/packages/server/dist/__tests__/i18n.test.js.map +1 -0
- package/packages/server/dist/app.d.ts +15 -0
- package/packages/server/dist/app.d.ts.map +1 -0
- package/packages/server/dist/app.js +120 -0
- package/packages/server/dist/app.js.map +1 -0
- package/packages/server/dist/cli/passwordSetup.d.ts +5 -0
- package/packages/server/dist/cli/passwordSetup.d.ts.map +1 -0
- package/packages/server/dist/cli/passwordSetup.js +74 -0
- package/packages/server/dist/cli/passwordSetup.js.map +1 -0
- package/packages/server/dist/config/index.d.ts +81 -0
- package/packages/server/dist/config/index.d.ts.map +1 -0
- package/packages/server/dist/config/index.js +107 -0
- package/packages/server/dist/config/index.js.map +1 -0
- package/packages/server/dist/controllers/__tests__/authController.test.d.ts +6 -0
- package/packages/server/dist/controllers/__tests__/authController.test.d.ts.map +1 -0
- package/packages/server/dist/controllers/__tests__/authController.test.js +198 -0
- package/packages/server/dist/controllers/__tests__/authController.test.js.map +1 -0
- package/packages/server/dist/controllers/__tests__/bmadStatusController.test.d.ts +6 -0
- package/packages/server/dist/controllers/__tests__/bmadStatusController.test.d.ts.map +1 -0
- package/packages/server/dist/controllers/__tests__/bmadStatusController.test.js +121 -0
- package/packages/server/dist/controllers/__tests__/bmadStatusController.test.js.map +1 -0
- package/packages/server/dist/controllers/__tests__/commandController.test.d.ts +6 -0
- package/packages/server/dist/controllers/__tests__/commandController.test.d.ts.map +1 -0
- package/packages/server/dist/controllers/__tests__/commandController.test.js +73 -0
- package/packages/server/dist/controllers/__tests__/commandController.test.js.map +1 -0
- package/packages/server/dist/controllers/__tests__/dashboardController.test.d.ts +6 -0
- package/packages/server/dist/controllers/__tests__/dashboardController.test.d.ts.map +1 -0
- package/packages/server/dist/controllers/__tests__/dashboardController.test.js +63 -0
- package/packages/server/dist/controllers/__tests__/dashboardController.test.js.map +1 -0
- package/packages/server/dist/controllers/__tests__/gitController.test.d.ts +6 -0
- package/packages/server/dist/controllers/__tests__/gitController.test.d.ts.map +1 -0
- package/packages/server/dist/controllers/__tests__/gitController.test.js +585 -0
- package/packages/server/dist/controllers/__tests__/gitController.test.js.map +1 -0
- package/packages/server/dist/controllers/__tests__/projectController.test.d.ts +6 -0
- package/packages/server/dist/controllers/__tests__/projectController.test.d.ts.map +1 -0
- package/packages/server/dist/controllers/__tests__/projectController.test.js +175 -0
- package/packages/server/dist/controllers/__tests__/projectController.test.js.map +1 -0
- package/packages/server/dist/controllers/__tests__/queueController.test.d.ts +6 -0
- package/packages/server/dist/controllers/__tests__/queueController.test.d.ts.map +1 -0
- package/packages/server/dist/controllers/__tests__/queueController.test.js +115 -0
- package/packages/server/dist/controllers/__tests__/queueController.test.js.map +1 -0
- package/packages/server/dist/controllers/__tests__/queueTemplateController.test.d.ts +6 -0
- package/packages/server/dist/controllers/__tests__/queueTemplateController.test.d.ts.map +1 -0
- package/packages/server/dist/controllers/__tests__/queueTemplateController.test.js +167 -0
- package/packages/server/dist/controllers/__tests__/queueTemplateController.test.js.map +1 -0
- package/packages/server/dist/controllers/__tests__/sessionController.test.d.ts +6 -0
- package/packages/server/dist/controllers/__tests__/sessionController.test.d.ts.map +1 -0
- package/packages/server/dist/controllers/__tests__/sessionController.test.js +113 -0
- package/packages/server/dist/controllers/__tests__/sessionController.test.js.map +1 -0
- package/packages/server/dist/controllers/authController.d.ts +30 -0
- package/packages/server/dist/controllers/authController.d.ts.map +1 -0
- package/packages/server/dist/controllers/authController.js +209 -0
- package/packages/server/dist/controllers/authController.js.map +1 -0
- package/packages/server/dist/controllers/bmadStatusController.d.ts +5 -0
- package/packages/server/dist/controllers/bmadStatusController.d.ts.map +1 -0
- package/packages/server/dist/controllers/bmadStatusController.js +53 -0
- package/packages/server/dist/controllers/bmadStatusController.js.map +1 -0
- package/packages/server/dist/controllers/boardController.d.ts +16 -0
- package/packages/server/dist/controllers/boardController.d.ts.map +1 -0
- package/packages/server/dist/controllers/boardController.js +295 -0
- package/packages/server/dist/controllers/boardController.js.map +1 -0
- package/packages/server/dist/controllers/cliController.d.ts +7 -0
- package/packages/server/dist/controllers/cliController.d.ts.map +1 -0
- package/packages/server/dist/controllers/cliController.js +27 -0
- package/packages/server/dist/controllers/cliController.js.map +1 -0
- package/packages/server/dist/controllers/commandController.d.ts +14 -0
- package/packages/server/dist/controllers/commandController.d.ts.map +1 -0
- package/packages/server/dist/controllers/commandController.js +31 -0
- package/packages/server/dist/controllers/commandController.js.map +1 -0
- package/packages/server/dist/controllers/dashboardController.d.ts +10 -0
- package/packages/server/dist/controllers/dashboardController.d.ts.map +1 -0
- package/packages/server/dist/controllers/dashboardController.js +23 -0
- package/packages/server/dist/controllers/dashboardController.js.map +1 -0
- package/packages/server/dist/controllers/fileSystemController.d.ts +54 -0
- package/packages/server/dist/controllers/fileSystemController.d.ts.map +1 -0
- package/packages/server/dist/controllers/fileSystemController.js +435 -0
- package/packages/server/dist/controllers/fileSystemController.js.map +1 -0
- package/packages/server/dist/controllers/gitController.d.ts +57 -0
- package/packages/server/dist/controllers/gitController.d.ts.map +1 -0
- package/packages/server/dist/controllers/gitController.js +494 -0
- package/packages/server/dist/controllers/gitController.js.map +1 -0
- package/packages/server/dist/controllers/projectController.d.ts +57 -0
- package/packages/server/dist/controllers/projectController.d.ts.map +1 -0
- package/packages/server/dist/controllers/projectController.js +358 -0
- package/packages/server/dist/controllers/projectController.js.map +1 -0
- package/packages/server/dist/controllers/queueController.d.ts +15 -0
- package/packages/server/dist/controllers/queueController.d.ts.map +1 -0
- package/packages/server/dist/controllers/queueController.js +131 -0
- package/packages/server/dist/controllers/queueController.js.map +1 -0
- package/packages/server/dist/controllers/queueTemplateController.d.ts +15 -0
- package/packages/server/dist/controllers/queueTemplateController.d.ts.map +1 -0
- package/packages/server/dist/controllers/queueTemplateController.js +187 -0
- package/packages/server/dist/controllers/queueTemplateController.js.map +1 -0
- package/packages/server/dist/controllers/serverController.d.ts +14 -0
- package/packages/server/dist/controllers/serverController.d.ts.map +1 -0
- package/packages/server/dist/controllers/serverController.js +164 -0
- package/packages/server/dist/controllers/serverController.js.map +1 -0
- package/packages/server/dist/controllers/sessionController.d.ts +39 -0
- package/packages/server/dist/controllers/sessionController.d.ts.map +1 -0
- package/packages/server/dist/controllers/sessionController.js +230 -0
- package/packages/server/dist/controllers/sessionController.js.map +1 -0
- package/packages/server/dist/dev.d.ts +2 -0
- package/packages/server/dist/dev.d.ts.map +1 -0
- package/packages/server/dist/dev.js +8 -0
- package/packages/server/dist/dev.js.map +1 -0
- package/packages/server/dist/handlers/__tests__/websocket.auth.test.d.ts +7 -0
- package/packages/server/dist/handlers/__tests__/websocket.auth.test.d.ts.map +1 -0
- package/packages/server/dist/handlers/__tests__/websocket.auth.test.js +125 -0
- package/packages/server/dist/handlers/__tests__/websocket.auth.test.js.map +1 -0
- package/packages/server/dist/handlers/__tests__/websocket.test.d.ts +2 -0
- package/packages/server/dist/handlers/__tests__/websocket.test.d.ts.map +1 -0
- package/packages/server/dist/handlers/__tests__/websocket.test.js +1316 -0
- package/packages/server/dist/handlers/__tests__/websocket.test.js.map +1 -0
- package/packages/server/dist/handlers/streamCallbacks.d.ts +52 -0
- package/packages/server/dist/handlers/streamCallbacks.d.ts.map +1 -0
- package/packages/server/dist/handlers/streamCallbacks.js +107 -0
- package/packages/server/dist/handlers/streamCallbacks.js.map +1 -0
- package/packages/server/dist/handlers/websocket.d.ts +82 -0
- package/packages/server/dist/handlers/websocket.d.ts.map +1 -0
- package/packages/server/dist/handlers/websocket.js +1041 -0
- package/packages/server/dist/handlers/websocket.js.map +1 -0
- package/packages/server/dist/i18n.d.ts +7 -0
- package/packages/server/dist/i18n.d.ts.map +1 -0
- package/packages/server/dist/i18n.js +32 -0
- package/packages/server/dist/i18n.js.map +1 -0
- package/packages/server/dist/index.d.ts +2 -0
- package/packages/server/dist/index.d.ts.map +1 -0
- package/packages/server/dist/index.js +114 -0
- package/packages/server/dist/index.js.map +1 -0
- package/packages/server/dist/locales/en/server.json +303 -0
- package/packages/server/dist/locales/es/server.json +303 -0
- package/packages/server/dist/locales/ja/server.json +303 -0
- package/packages/server/dist/locales/ko/server.json +303 -0
- package/packages/server/dist/locales/pt/server.json +303 -0
- package/packages/server/dist/locales/zh-CN/server.json +303 -0
- package/packages/server/dist/middleware/__tests__/auth.test.d.ts +6 -0
- package/packages/server/dist/middleware/__tests__/auth.test.d.ts.map +1 -0
- package/packages/server/dist/middleware/__tests__/auth.test.js +146 -0
- package/packages/server/dist/middleware/__tests__/auth.test.js.map +1 -0
- package/packages/server/dist/middleware/__tests__/i18n.test.d.ts +5 -0
- package/packages/server/dist/middleware/__tests__/i18n.test.d.ts.map +1 -0
- package/packages/server/dist/middleware/__tests__/i18n.test.js +96 -0
- package/packages/server/dist/middleware/__tests__/i18n.test.js.map +1 -0
- package/packages/server/dist/middleware/__tests__/pathGuard.test.d.ts +6 -0
- package/packages/server/dist/middleware/__tests__/pathGuard.test.d.ts.map +1 -0
- package/packages/server/dist/middleware/__tests__/pathGuard.test.js +73 -0
- package/packages/server/dist/middleware/__tests__/pathGuard.test.js.map +1 -0
- package/packages/server/dist/middleware/__tests__/session.test.d.ts +6 -0
- package/packages/server/dist/middleware/__tests__/session.test.d.ts.map +1 -0
- package/packages/server/dist/middleware/__tests__/session.test.js +33 -0
- package/packages/server/dist/middleware/__tests__/session.test.js.map +1 -0
- package/packages/server/dist/middleware/auth.d.ts +18 -0
- package/packages/server/dist/middleware/auth.d.ts.map +1 -0
- package/packages/server/dist/middleware/auth.js +52 -0
- package/packages/server/dist/middleware/auth.js.map +1 -0
- package/packages/server/dist/middleware/i18n.d.ts +17 -0
- package/packages/server/dist/middleware/i18n.d.ts.map +1 -0
- package/packages/server/dist/middleware/i18n.js +42 -0
- package/packages/server/dist/middleware/i18n.js.map +1 -0
- package/packages/server/dist/middleware/pathGuard.d.ts +15 -0
- package/packages/server/dist/middleware/pathGuard.d.ts.map +1 -0
- package/packages/server/dist/middleware/pathGuard.js +41 -0
- package/packages/server/dist/middleware/pathGuard.js.map +1 -0
- package/packages/server/dist/middleware/session.d.ts +18 -0
- package/packages/server/dist/middleware/session.d.ts.map +1 -0
- package/packages/server/dist/middleware/session.js +35 -0
- package/packages/server/dist/middleware/session.js.map +1 -0
- package/packages/server/dist/routes/__tests__/auth.integration.test.d.ts +6 -0
- package/packages/server/dist/routes/__tests__/auth.integration.test.d.ts.map +1 -0
- package/packages/server/dist/routes/__tests__/auth.integration.test.js +111 -0
- package/packages/server/dist/routes/__tests__/auth.integration.test.js.map +1 -0
- package/packages/server/dist/routes/__tests__/auth.test.d.ts +6 -0
- package/packages/server/dist/routes/__tests__/auth.test.d.ts.map +1 -0
- package/packages/server/dist/routes/__tests__/auth.test.js +155 -0
- package/packages/server/dist/routes/__tests__/auth.test.js.map +1 -0
- package/packages/server/dist/routes/__tests__/board.test.d.ts +2 -0
- package/packages/server/dist/routes/__tests__/board.test.d.ts.map +1 -0
- package/packages/server/dist/routes/__tests__/board.test.js +201 -0
- package/packages/server/dist/routes/__tests__/board.test.js.map +1 -0
- package/packages/server/dist/routes/__tests__/cli.test.d.ts +2 -0
- package/packages/server/dist/routes/__tests__/cli.test.d.ts.map +1 -0
- package/packages/server/dist/routes/__tests__/cli.test.js +121 -0
- package/packages/server/dist/routes/__tests__/cli.test.js.map +1 -0
- package/packages/server/dist/routes/__tests__/commands.test.d.ts +6 -0
- package/packages/server/dist/routes/__tests__/commands.test.d.ts.map +1 -0
- package/packages/server/dist/routes/__tests__/commands.test.js +74 -0
- package/packages/server/dist/routes/__tests__/commands.test.js.map +1 -0
- package/packages/server/dist/routes/__tests__/projects.integration.test.d.ts +9 -0
- package/packages/server/dist/routes/__tests__/projects.integration.test.d.ts.map +1 -0
- package/packages/server/dist/routes/__tests__/projects.integration.test.js +517 -0
- package/packages/server/dist/routes/__tests__/projects.integration.test.js.map +1 -0
- package/packages/server/dist/routes/__tests__/projects.test.d.ts +7 -0
- package/packages/server/dist/routes/__tests__/projects.test.d.ts.map +1 -0
- package/packages/server/dist/routes/__tests__/projects.test.js +361 -0
- package/packages/server/dist/routes/__tests__/projects.test.js.map +1 -0
- package/packages/server/dist/routes/__tests__/sessions.integration.test.d.ts +8 -0
- package/packages/server/dist/routes/__tests__/sessions.integration.test.d.ts.map +1 -0
- package/packages/server/dist/routes/__tests__/sessions.integration.test.js +287 -0
- package/packages/server/dist/routes/__tests__/sessions.integration.test.js.map +1 -0
- package/packages/server/dist/routes/__tests__/sessions.test.d.ts +6 -0
- package/packages/server/dist/routes/__tests__/sessions.test.d.ts.map +1 -0
- package/packages/server/dist/routes/__tests__/sessions.test.js +261 -0
- package/packages/server/dist/routes/__tests__/sessions.test.js.map +1 -0
- package/packages/server/dist/routes/auth.d.ts +8 -0
- package/packages/server/dist/routes/auth.d.ts.map +1 -0
- package/packages/server/dist/routes/auth.js +18 -0
- package/packages/server/dist/routes/auth.js.map +1 -0
- package/packages/server/dist/routes/bmadStatus.d.ts +3 -0
- package/packages/server/dist/routes/bmadStatus.d.ts.map +1 -0
- package/packages/server/dist/routes/bmadStatus.js +7 -0
- package/packages/server/dist/routes/bmadStatus.js.map +1 -0
- package/packages/server/dist/routes/board.d.ts +3 -0
- package/packages/server/dist/routes/board.d.ts.map +1 -0
- package/packages/server/dist/routes/board.js +16 -0
- package/packages/server/dist/routes/board.js.map +1 -0
- package/packages/server/dist/routes/cli.d.ts +3 -0
- package/packages/server/dist/routes/cli.d.ts.map +1 -0
- package/packages/server/dist/routes/cli.js +10 -0
- package/packages/server/dist/routes/cli.js.map +1 -0
- package/packages/server/dist/routes/commands.d.ts +8 -0
- package/packages/server/dist/routes/commands.d.ts.map +1 -0
- package/packages/server/dist/routes/commands.js +12 -0
- package/packages/server/dist/routes/commands.js.map +1 -0
- package/packages/server/dist/routes/dashboard.d.ts +3 -0
- package/packages/server/dist/routes/dashboard.d.ts.map +1 -0
- package/packages/server/dist/routes/dashboard.js +7 -0
- package/packages/server/dist/routes/dashboard.js.map +1 -0
- package/packages/server/dist/routes/debug.d.ts +6 -0
- package/packages/server/dist/routes/debug.d.ts.map +1 -0
- package/packages/server/dist/routes/debug.js +59 -0
- package/packages/server/dist/routes/debug.js.map +1 -0
- package/packages/server/dist/routes/fileSystem.d.ts +8 -0
- package/packages/server/dist/routes/fileSystem.d.ts.map +1 -0
- package/packages/server/dist/routes/fileSystem.js +24 -0
- package/packages/server/dist/routes/fileSystem.js.map +1 -0
- package/packages/server/dist/routes/git.d.ts +8 -0
- package/packages/server/dist/routes/git.d.ts.map +1 -0
- package/packages/server/dist/routes/git.js +24 -0
- package/packages/server/dist/routes/git.js.map +1 -0
- package/packages/server/dist/routes/preferences.d.ts +7 -0
- package/packages/server/dist/routes/preferences.d.ts.map +1 -0
- package/packages/server/dist/routes/preferences.js +112 -0
- package/packages/server/dist/routes/preferences.js.map +1 -0
- package/packages/server/dist/routes/projects.d.ts +9 -0
- package/packages/server/dist/routes/projects.d.ts.map +1 -0
- package/packages/server/dist/routes/projects.js +84 -0
- package/packages/server/dist/routes/projects.js.map +1 -0
- package/packages/server/dist/routes/queue.d.ts +7 -0
- package/packages/server/dist/routes/queue.d.ts.map +1 -0
- package/packages/server/dist/routes/queue.js +22 -0
- package/packages/server/dist/routes/queue.js.map +1 -0
- package/packages/server/dist/routes/server.d.ts +3 -0
- package/packages/server/dist/routes/server.d.ts.map +1 -0
- package/packages/server/dist/routes/server.js +10 -0
- package/packages/server/dist/routes/server.js.map +1 -0
- package/packages/server/dist/routes/sessions.d.ts +8 -0
- package/packages/server/dist/routes/sessions.d.ts.map +1 -0
- package/packages/server/dist/routes/sessions.js +47 -0
- package/packages/server/dist/routes/sessions.js.map +1 -0
- package/packages/server/dist/services/__tests__/authConfigService.test.d.ts +2 -0
- package/packages/server/dist/services/__tests__/authConfigService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/authConfigService.test.js +274 -0
- package/packages/server/dist/services/__tests__/authConfigService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/bmadStatusService.test.d.ts +6 -0
- package/packages/server/dist/services/__tests__/bmadStatusService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/bmadStatusService.test.js +456 -0
- package/packages/server/dist/services/__tests__/bmadStatusService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/chatService.integration.test.d.ts +32 -0
- package/packages/server/dist/services/__tests__/chatService.integration.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/chatService.integration.test.js +97 -0
- package/packages/server/dist/services/__tests__/chatService.integration.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/chatService.test.d.ts +2 -0
- package/packages/server/dist/services/__tests__/chatService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/chatService.test.js +517 -0
- package/packages/server/dist/services/__tests__/chatService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/cliService.test.d.ts +2 -0
- package/packages/server/dist/services/__tests__/cliService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/cliService.test.js +172 -0
- package/packages/server/dist/services/__tests__/cliService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/commandService.test.d.ts +6 -0
- package/packages/server/dist/services/__tests__/commandService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/commandService.test.js +525 -0
- package/packages/server/dist/services/__tests__/commandService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/dashboardService.test.d.ts +6 -0
- package/packages/server/dist/services/__tests__/dashboardService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/dashboardService.test.js +248 -0
- package/packages/server/dist/services/__tests__/dashboardService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/fileSystemService.test.d.ts +7 -0
- package/packages/server/dist/services/__tests__/fileSystemService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/fileSystemService.test.js +348 -0
- package/packages/server/dist/services/__tests__/fileSystemService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/gitService.test.d.ts +6 -0
- package/packages/server/dist/services/__tests__/gitService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/gitService.test.js +340 -0
- package/packages/server/dist/services/__tests__/gitService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/historyParser.test.d.ts +2 -0
- package/packages/server/dist/services/__tests__/historyParser.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/historyParser.test.js +471 -0
- package/packages/server/dist/services/__tests__/historyParser.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/issueService.test.d.ts +2 -0
- package/packages/server/dist/services/__tests__/issueService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/issueService.test.js +382 -0
- package/packages/server/dist/services/__tests__/issueService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/notificationService.test.d.ts +6 -0
- package/packages/server/dist/services/__tests__/notificationService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/notificationService.test.js +131 -0
- package/packages/server/dist/services/__tests__/notificationService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/preferencesService.telegram.test.d.ts +6 -0
- package/packages/server/dist/services/__tests__/preferencesService.telegram.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/preferencesService.telegram.test.js +101 -0
- package/packages/server/dist/services/__tests__/preferencesService.telegram.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/preferencesService.test.d.ts +6 -0
- package/packages/server/dist/services/__tests__/preferencesService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/preferencesService.test.js +68 -0
- package/packages/server/dist/services/__tests__/preferencesService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/projectService.settings.test.d.ts +6 -0
- package/packages/server/dist/services/__tests__/projectService.settings.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/projectService.settings.test.js +101 -0
- package/packages/server/dist/services/__tests__/projectService.settings.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/projectService.test.d.ts +7 -0
- package/packages/server/dist/services/__tests__/projectService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/projectService.test.js +618 -0
- package/packages/server/dist/services/__tests__/projectService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/ptyService.test.d.ts +6 -0
- package/packages/server/dist/services/__tests__/ptyService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/ptyService.test.js +289 -0
- package/packages/server/dist/services/__tests__/ptyService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/queueService.test.d.ts +6 -0
- package/packages/server/dist/services/__tests__/queueService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/queueService.test.js +477 -0
- package/packages/server/dist/services/__tests__/queueService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/queueTemplateService.test.d.ts +6 -0
- package/packages/server/dist/services/__tests__/queueTemplateService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/queueTemplateService.test.js +129 -0
- package/packages/server/dist/services/__tests__/queueTemplateService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/rateLimiter.test.d.ts +6 -0
- package/packages/server/dist/services/__tests__/rateLimiter.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/rateLimiter.test.js +123 -0
- package/packages/server/dist/services/__tests__/rateLimiter.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/sessionService.test.d.ts +2 -0
- package/packages/server/dist/services/__tests__/sessionService.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/sessionService.test.js +349 -0
- package/packages/server/dist/services/__tests__/sessionService.test.js.map +1 -0
- package/packages/server/dist/services/__tests__/streamHandler.test.d.ts +2 -0
- package/packages/server/dist/services/__tests__/streamHandler.test.d.ts.map +1 -0
- package/packages/server/dist/services/__tests__/streamHandler.test.js +654 -0
- package/packages/server/dist/services/__tests__/streamHandler.test.js.map +1 -0
- package/packages/server/dist/services/authConfigService.d.ts +56 -0
- package/packages/server/dist/services/authConfigService.d.ts.map +1 -0
- package/packages/server/dist/services/authConfigService.js +186 -0
- package/packages/server/dist/services/authConfigService.js.map +1 -0
- package/packages/server/dist/services/bmadStatusService.d.ts +56 -0
- package/packages/server/dist/services/bmadStatusService.d.ts.map +1 -0
- package/packages/server/dist/services/bmadStatusService.js +438 -0
- package/packages/server/dist/services/bmadStatusService.js.map +1 -0
- package/packages/server/dist/services/chatService.d.ts +78 -0
- package/packages/server/dist/services/chatService.d.ts.map +1 -0
- package/packages/server/dist/services/chatService.js +335 -0
- package/packages/server/dist/services/chatService.js.map +1 -0
- package/packages/server/dist/services/cliService.d.ts +29 -0
- package/packages/server/dist/services/cliService.d.ts.map +1 -0
- package/packages/server/dist/services/cliService.js +101 -0
- package/packages/server/dist/services/cliService.js.map +1 -0
- package/packages/server/dist/services/commandService.d.ts +84 -0
- package/packages/server/dist/services/commandService.d.ts.map +1 -0
- package/packages/server/dist/services/commandService.js +322 -0
- package/packages/server/dist/services/commandService.js.map +1 -0
- package/packages/server/dist/services/dashboardService.d.ts +23 -0
- package/packages/server/dist/services/dashboardService.d.ts.map +1 -0
- package/packages/server/dist/services/dashboardService.js +81 -0
- package/packages/server/dist/services/dashboardService.js.map +1 -0
- package/packages/server/dist/services/fileSystemService.d.ts +105 -0
- package/packages/server/dist/services/fileSystemService.d.ts.map +1 -0
- package/packages/server/dist/services/fileSystemService.js +498 -0
- package/packages/server/dist/services/fileSystemService.js.map +1 -0
- package/packages/server/dist/services/gitService.d.ts +25 -0
- package/packages/server/dist/services/gitService.d.ts.map +1 -0
- package/packages/server/dist/services/gitService.js +230 -0
- package/packages/server/dist/services/gitService.js.map +1 -0
- package/packages/server/dist/services/historyParser.d.ts +45 -0
- package/packages/server/dist/services/historyParser.d.ts.map +1 -0
- package/packages/server/dist/services/historyParser.js +315 -0
- package/packages/server/dist/services/historyParser.js.map +1 -0
- package/packages/server/dist/services/issueService.d.ts +79 -0
- package/packages/server/dist/services/issueService.d.ts.map +1 -0
- package/packages/server/dist/services/issueService.js +708 -0
- package/packages/server/dist/services/issueService.js.map +1 -0
- package/packages/server/dist/services/notificationService.d.ts +78 -0
- package/packages/server/dist/services/notificationService.d.ts.map +1 -0
- package/packages/server/dist/services/notificationService.js +246 -0
- package/packages/server/dist/services/notificationService.js.map +1 -0
- package/packages/server/dist/services/preferencesService.d.ts +35 -0
- package/packages/server/dist/services/preferencesService.d.ts.map +1 -0
- package/packages/server/dist/services/preferencesService.js +121 -0
- package/packages/server/dist/services/preferencesService.js.map +1 -0
- package/packages/server/dist/services/projectService.d.ts +210 -0
- package/packages/server/dist/services/projectService.d.ts.map +1 -0
- package/packages/server/dist/services/projectService.js +892 -0
- package/packages/server/dist/services/projectService.js.map +1 -0
- package/packages/server/dist/services/ptyService.d.ts +83 -0
- package/packages/server/dist/services/ptyService.d.ts.map +1 -0
- package/packages/server/dist/services/ptyService.js +214 -0
- package/packages/server/dist/services/ptyService.js.map +1 -0
- package/packages/server/dist/services/queueService.d.ts +93 -0
- package/packages/server/dist/services/queueService.d.ts.map +1 -0
- package/packages/server/dist/services/queueService.js +598 -0
- package/packages/server/dist/services/queueService.js.map +1 -0
- package/packages/server/dist/services/queueTemplateService.d.ts +12 -0
- package/packages/server/dist/services/queueTemplateService.d.ts.map +1 -0
- package/packages/server/dist/services/queueTemplateService.js +73 -0
- package/packages/server/dist/services/queueTemplateService.js.map +1 -0
- package/packages/server/dist/services/rateLimitProbeService.d.ts +56 -0
- package/packages/server/dist/services/rateLimitProbeService.d.ts.map +1 -0
- package/packages/server/dist/services/rateLimitProbeService.js +227 -0
- package/packages/server/dist/services/rateLimitProbeService.js.map +1 -0
- package/packages/server/dist/services/rateLimiter.d.ts +32 -0
- package/packages/server/dist/services/rateLimiter.d.ts.map +1 -0
- package/packages/server/dist/services/rateLimiter.js +60 -0
- package/packages/server/dist/services/rateLimiter.js.map +1 -0
- package/packages/server/dist/services/sessionService.d.ts +152 -0
- package/packages/server/dist/services/sessionService.d.ts.map +1 -0
- package/packages/server/dist/services/sessionService.js +672 -0
- package/packages/server/dist/services/sessionService.js.map +1 -0
- package/packages/server/dist/services/streamHandler.d.ts +145 -0
- package/packages/server/dist/services/streamHandler.d.ts.map +1 -0
- package/packages/server/dist/services/streamHandler.js +753 -0
- package/packages/server/dist/services/streamHandler.js.map +1 -0
- package/packages/server/dist/utils/__tests__/networkUtils.test.d.ts +6 -0
- package/packages/server/dist/utils/__tests__/networkUtils.test.d.ts.map +1 -0
- package/packages/server/dist/utils/__tests__/networkUtils.test.js +106 -0
- package/packages/server/dist/utils/__tests__/networkUtils.test.js.map +1 -0
- package/packages/server/dist/utils/__tests__/pathUtils.test.d.ts +6 -0
- package/packages/server/dist/utils/__tests__/pathUtils.test.d.ts.map +1 -0
- package/packages/server/dist/utils/__tests__/pathUtils.test.js +111 -0
- package/packages/server/dist/utils/__tests__/pathUtils.test.js.map +1 -0
- package/packages/server/dist/utils/errors.d.ts +79 -0
- package/packages/server/dist/utils/errors.d.ts.map +1 -0
- package/packages/server/dist/utils/errors.js +167 -0
- package/packages/server/dist/utils/errors.js.map +1 -0
- package/packages/server/dist/utils/logger.d.ts +28 -0
- package/packages/server/dist/utils/logger.d.ts.map +1 -0
- package/packages/server/dist/utils/logger.js +87 -0
- package/packages/server/dist/utils/logger.js.map +1 -0
- package/packages/server/dist/utils/networkUtils.d.ts +26 -0
- package/packages/server/dist/utils/networkUtils.d.ts.map +1 -0
- package/packages/server/dist/utils/networkUtils.js +70 -0
- package/packages/server/dist/utils/networkUtils.js.map +1 -0
- package/packages/server/dist/utils/pathUtils.d.ts +30 -0
- package/packages/server/dist/utils/pathUtils.d.ts.map +1 -0
- package/packages/server/dist/utils/pathUtils.js +81 -0
- package/packages/server/dist/utils/pathUtils.js.map +1 -0
- package/packages/server/package.json +48 -0
- package/packages/shared/dist/constants/errorCodes.d.ts +31 -0
- package/packages/shared/dist/constants/errorCodes.d.ts.map +1 -0
- package/packages/shared/dist/constants/errorCodes.js +33 -0
- package/packages/shared/dist/constants/errorCodes.js.map +1 -0
- package/packages/shared/dist/index.d.ts +26 -0
- package/packages/shared/dist/index.d.ts.map +1 -0
- package/packages/shared/dist/index.js +48 -0
- package/packages/shared/dist/index.js.map +1 -0
- package/packages/shared/dist/types/auth.d.ts +159 -0
- package/packages/shared/dist/types/auth.d.ts.map +1 -0
- package/packages/shared/dist/types/auth.js +74 -0
- package/packages/shared/dist/types/auth.js.map +1 -0
- package/packages/shared/dist/types/bmadStatus.d.ts +97 -0
- package/packages/shared/dist/types/bmadStatus.d.ts.map +1 -0
- package/packages/shared/dist/types/bmadStatus.js +18 -0
- package/packages/shared/dist/types/bmadStatus.js.map +1 -0
- package/packages/shared/dist/types/board.d.ts +68 -0
- package/packages/shared/dist/types/board.d.ts.map +1 -0
- package/packages/shared/dist/types/board.js +108 -0
- package/packages/shared/dist/types/board.js.map +1 -0
- package/packages/shared/dist/types/cli.d.ts +34 -0
- package/packages/shared/dist/types/cli.d.ts.map +1 -0
- package/packages/shared/dist/types/cli.js +10 -0
- package/packages/shared/dist/types/cli.js.map +1 -0
- package/packages/shared/dist/types/command.d.ts +39 -0
- package/packages/shared/dist/types/command.d.ts.map +1 -0
- package/packages/shared/dist/types/command.js +6 -0
- package/packages/shared/dist/types/command.js.map +1 -0
- package/packages/shared/dist/types/dashboard.d.ts +15 -0
- package/packages/shared/dist/types/dashboard.d.ts.map +1 -0
- package/packages/shared/dist/types/dashboard.js +3 -0
- package/packages/shared/dist/types/dashboard.js.map +1 -0
- package/packages/shared/dist/types/fileSystem.d.ts +175 -0
- package/packages/shared/dist/types/fileSystem.d.ts.map +1 -0
- package/packages/shared/dist/types/fileSystem.js +62 -0
- package/packages/shared/dist/types/fileSystem.js.map +1 -0
- package/packages/shared/dist/types/git.d.ts +81 -0
- package/packages/shared/dist/types/git.d.ts.map +1 -0
- package/packages/shared/dist/types/git.js +34 -0
- package/packages/shared/dist/types/git.js.map +1 -0
- package/packages/shared/dist/types/history.d.ts +103 -0
- package/packages/shared/dist/types/history.d.ts.map +1 -0
- package/packages/shared/dist/types/history.js +6 -0
- package/packages/shared/dist/types/history.js.map +1 -0
- package/packages/shared/dist/types/logger.d.ts +18 -0
- package/packages/shared/dist/types/logger.d.ts.map +1 -0
- package/packages/shared/dist/types/logger.js +29 -0
- package/packages/shared/dist/types/logger.js.map +1 -0
- package/packages/shared/dist/types/message.d.ts +34 -0
- package/packages/shared/dist/types/message.d.ts.map +1 -0
- package/packages/shared/dist/types/message.js +14 -0
- package/packages/shared/dist/types/message.js.map +1 -0
- package/packages/shared/dist/types/preferences.d.ts +95 -0
- package/packages/shared/dist/types/preferences.d.ts.map +1 -0
- package/packages/shared/dist/types/preferences.js +15 -0
- package/packages/shared/dist/types/preferences.js.map +1 -0
- package/packages/shared/dist/types/project.d.ts +205 -0
- package/packages/shared/dist/types/project.d.ts.map +1 -0
- package/packages/shared/dist/types/project.js +64 -0
- package/packages/shared/dist/types/project.js.map +1 -0
- package/packages/shared/dist/types/queue.d.ts +94 -0
- package/packages/shared/dist/types/queue.d.ts.map +1 -0
- package/packages/shared/dist/types/queue.js +2 -0
- package/packages/shared/dist/types/queue.js.map +1 -0
- package/packages/shared/dist/types/sdk.d.ts +156 -0
- package/packages/shared/dist/types/sdk.d.ts.map +1 -0
- package/packages/shared/dist/types/sdk.js +13 -0
- package/packages/shared/dist/types/sdk.js.map +1 -0
- package/packages/shared/dist/types/session.d.ts +149 -0
- package/packages/shared/dist/types/session.d.ts.map +1 -0
- package/packages/shared/dist/types/session.js +51 -0
- package/packages/shared/dist/types/session.js.map +1 -0
- package/packages/shared/dist/types/streaming.d.ts +269 -0
- package/packages/shared/dist/types/streaming.d.ts.map +1 -0
- package/packages/shared/dist/types/streaming.js +43 -0
- package/packages/shared/dist/types/streaming.js.map +1 -0
- package/packages/shared/dist/types/terminal.d.ts +93 -0
- package/packages/shared/dist/types/terminal.d.ts.map +1 -0
- package/packages/shared/dist/types/terminal.js +38 -0
- package/packages/shared/dist/types/terminal.js.map +1 -0
- package/packages/shared/dist/types/websocket.d.ts +196 -0
- package/packages/shared/dist/types/websocket.d.ts.map +1 -0
- package/packages/shared/dist/types/websocket.js +7 -0
- package/packages/shared/dist/types/websocket.js.map +1 -0
- package/packages/shared/dist/utils/__tests__/queueParser.test.d.ts +2 -0
- package/packages/shared/dist/utils/__tests__/queueParser.test.d.ts.map +1 -0
- package/packages/shared/dist/utils/__tests__/queueParser.test.js +246 -0
- package/packages/shared/dist/utils/__tests__/queueParser.test.js.map +1 -0
- package/packages/shared/dist/utils/__tests__/queueTemplateUtils.test.d.ts +6 -0
- package/packages/shared/dist/utils/__tests__/queueTemplateUtils.test.d.ts.map +1 -0
- package/packages/shared/dist/utils/__tests__/queueTemplateUtils.test.js +138 -0
- package/packages/shared/dist/utils/__tests__/queueTemplateUtils.test.js.map +1 -0
- package/packages/shared/dist/utils/queueParser.d.ts +3 -0
- package/packages/shared/dist/utils/queueParser.d.ts.map +1 -0
- package/packages/shared/dist/utils/queueParser.js +165 -0
- package/packages/shared/dist/utils/queueParser.js.map +1 -0
- package/packages/shared/dist/utils/queueTemplateUtils.d.ts +17 -0
- package/packages/shared/dist/utils/queueTemplateUtils.d.ts.map +1 -0
- package/packages/shared/dist/utils/queueTemplateUtils.js +65 -0
- package/packages/shared/dist/utils/queueTemplateUtils.js.map +1 -0
- package/packages/shared/package.json +23 -0
- package/scripts/postinstall.cjs +23 -0
|
@@ -0,0 +1,892 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Service
|
|
3
|
+
* Scans ~/.claude/projects/ directory for project list
|
|
4
|
+
* [Source: Story 3.1 - Task 2]
|
|
5
|
+
* [Extended: Story 3.6 - Task 2: Project creation service]
|
|
6
|
+
*/
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import os from 'os';
|
|
9
|
+
import fs from 'fs/promises';
|
|
10
|
+
import { existsSync } from 'fs';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
import { preferencesService } from './preferencesService.js';
|
|
13
|
+
import { createLogger } from '../utils/logger.js';
|
|
14
|
+
const log = createLogger('projectService');
|
|
15
|
+
// Resolve the server package root for locating bundled resources
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
+
const __dirname = path.dirname(__filename);
|
|
18
|
+
const SERVER_PACKAGE_ROOT = path.resolve(__dirname, '..', '..');
|
|
19
|
+
const BMAD_RESOURCES_DIR = path.join(SERVER_PACKAGE_ROOT, 'resources', 'bmad-method');
|
|
20
|
+
/**
|
|
21
|
+
* Validate path for security (path traversal prevention)
|
|
22
|
+
* Cross-platform compatible (Windows, macOS, Linux)
|
|
23
|
+
* [Source: Story 3.6 - Task 2]
|
|
24
|
+
*/
|
|
25
|
+
function isValidPathFormat(inputPath) {
|
|
26
|
+
// Normalize path first for cross-platform compatibility
|
|
27
|
+
const normalizedPath = path.normalize(inputPath);
|
|
28
|
+
// Reject relative paths (works for both Windows and Unix)
|
|
29
|
+
if (!path.isAbsolute(normalizedPath)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
// Reject path traversal sequences (check both normalized and original)
|
|
33
|
+
// Windows: ..\, Unix: ../
|
|
34
|
+
if (inputPath.includes('..') || normalizedPath.includes('..')) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
// Reject null bytes (security)
|
|
38
|
+
if (inputPath.includes('\0')) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
// Additional Windows-specific checks
|
|
42
|
+
// Reject reserved device names (CON, PRN, AUX, NUL, COM1-9, LPT1-9)
|
|
43
|
+
if (process.platform === 'win32') {
|
|
44
|
+
const basename = path.basename(normalizedPath).toUpperCase();
|
|
45
|
+
const reservedNames = /^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.|$)/i;
|
|
46
|
+
if (reservedNames.test(basename)) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* ProjectService - Scans and lists Claude Code projects
|
|
54
|
+
*/
|
|
55
|
+
class ProjectService {
|
|
56
|
+
/**
|
|
57
|
+
* Get the Claude projects directory path
|
|
58
|
+
* @returns Path to ~/.claude/projects/
|
|
59
|
+
*/
|
|
60
|
+
getClaudeProjectsDir() {
|
|
61
|
+
return path.join(os.homedir(), '.claude', 'projects');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Scan the projects directory and return project list
|
|
65
|
+
* @returns Array of ProjectInfo sorted by lastModified (descending)
|
|
66
|
+
*/
|
|
67
|
+
async scanProjects() {
|
|
68
|
+
const projectsDir = this.getClaudeProjectsDir();
|
|
69
|
+
// Check if directory exists (AC 6: return empty array if not)
|
|
70
|
+
try {
|
|
71
|
+
await fs.access(projectsDir);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
// Read all entries in the projects directory
|
|
77
|
+
let entries;
|
|
78
|
+
try {
|
|
79
|
+
entries = await fs.readdir(projectsDir);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
// Permission denied or other error
|
|
83
|
+
if (error.code === 'EACCES') {
|
|
84
|
+
const err = new Error('디렉토리 접근 권한이 없습니다.');
|
|
85
|
+
err.code = 'PERMISSION_DENIED';
|
|
86
|
+
throw err;
|
|
87
|
+
}
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
// Filter to only directories and process each
|
|
91
|
+
const projects = [];
|
|
92
|
+
for (const entry of entries) {
|
|
93
|
+
const projectPath = path.join(projectsDir, entry);
|
|
94
|
+
// Check if it's a directory
|
|
95
|
+
try {
|
|
96
|
+
const stat = await fs.stat(projectPath);
|
|
97
|
+
if (!stat.isDirectory()) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// Try sessions-index.json first, fall back to JSONL-based discovery
|
|
105
|
+
let projectInfo = await this.parseSessionsIndex(projectPath, entry);
|
|
106
|
+
if (!projectInfo) {
|
|
107
|
+
projectInfo = await this.buildProjectFromDirectory(projectPath, entry);
|
|
108
|
+
}
|
|
109
|
+
if (projectInfo) {
|
|
110
|
+
// Filter out projects whose originalPath no longer exists
|
|
111
|
+
const pathExists = await this.checkPathExists(projectInfo.originalPath);
|
|
112
|
+
if (pathExists) {
|
|
113
|
+
projects.push(projectInfo);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Sort by lastModified descending (AC 5)
|
|
118
|
+
projects.sort((a, b) => {
|
|
119
|
+
const dateA = new Date(a.lastModified).getTime();
|
|
120
|
+
const dateB = new Date(b.lastModified).getTime();
|
|
121
|
+
return dateB - dateA;
|
|
122
|
+
});
|
|
123
|
+
return projects;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Parse sessions-index.json file from a project directory
|
|
127
|
+
* @param projectPath Full path to the project directory in ~/.claude/projects/
|
|
128
|
+
* @param projectSlug The folder name (hash/slug)
|
|
129
|
+
* @returns ProjectInfo or null if parsing fails
|
|
130
|
+
*/
|
|
131
|
+
async parseSessionsIndex(projectPath, projectSlug) {
|
|
132
|
+
const indexPath = path.join(projectPath, 'sessions-index.json');
|
|
133
|
+
try {
|
|
134
|
+
const content = await fs.readFile(indexPath, 'utf-8');
|
|
135
|
+
const index = JSON.parse(content);
|
|
136
|
+
const entries = index.entries || [];
|
|
137
|
+
// Determine originalPath from either format:
|
|
138
|
+
// 1. Legacy format: index.originalPath at root level
|
|
139
|
+
// 2. Current format (v1): entries[0].projectPath from first entry
|
|
140
|
+
let originalPath = index.originalPath;
|
|
141
|
+
if (!originalPath && entries.length > 0) {
|
|
142
|
+
// Try to get projectPath from the first entry (current Claude Code format)
|
|
143
|
+
originalPath = entries[0].projectPath;
|
|
144
|
+
}
|
|
145
|
+
// If still no originalPath, skip this project (invalid format)
|
|
146
|
+
if (!originalPath || typeof originalPath !== 'string') {
|
|
147
|
+
// Don't throw error, just skip - this might be a corrupted or empty project
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
// Count sessions from index entries + unindexed .jsonl files
|
|
151
|
+
const indexedSessionIds = new Set(entries.map((e) => e.sessionId));
|
|
152
|
+
let sessionCount = entries.length;
|
|
153
|
+
// Collect modification timestamps from index entries
|
|
154
|
+
const modifiedTimestamps = entries
|
|
155
|
+
.filter((e) => e.modified)
|
|
156
|
+
.map((e) => new Date(e.modified).getTime());
|
|
157
|
+
// Scan for .jsonl files not in index (Hammoc sessions, SDK not yet synced)
|
|
158
|
+
// and collect their mtimes for lastModified calculation
|
|
159
|
+
try {
|
|
160
|
+
const files = await fs.readdir(projectPath);
|
|
161
|
+
for (const f of files) {
|
|
162
|
+
if (!f.endsWith('.jsonl') || indexedSessionIds.has(f.replace('.jsonl', '')))
|
|
163
|
+
continue;
|
|
164
|
+
sessionCount++;
|
|
165
|
+
const fileStat = await fs.stat(path.join(projectPath, f));
|
|
166
|
+
modifiedTimestamps.push(fileStat.mtime.getTime());
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// Failed to read directory - use index data only
|
|
171
|
+
}
|
|
172
|
+
// Calculate lastModified
|
|
173
|
+
let lastModified;
|
|
174
|
+
if (modifiedTimestamps.length > 0) {
|
|
175
|
+
lastModified = new Date(Math.max(...modifiedTimestamps)).toISOString();
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
// Fallback to index file mtime
|
|
179
|
+
const stat = await fs.stat(indexPath);
|
|
180
|
+
lastModified = stat.mtime.toISOString();
|
|
181
|
+
}
|
|
182
|
+
// Check if it's a BMad project (AC 4)
|
|
183
|
+
const isBmadProject = await this.checkBmadProject(originalPath);
|
|
184
|
+
// Read project settings from .hammoc/settings.json
|
|
185
|
+
const settings = await this.readProjectSettings(originalPath);
|
|
186
|
+
return {
|
|
187
|
+
originalPath,
|
|
188
|
+
projectSlug,
|
|
189
|
+
sessionCount,
|
|
190
|
+
lastModified,
|
|
191
|
+
isBmadProject,
|
|
192
|
+
...(settings.hidden !== undefined && { hidden: settings.hidden }),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
// Re-throw specific errors
|
|
197
|
+
if (error.code === 'INVALID_SESSION_INDEX') {
|
|
198
|
+
throw error;
|
|
199
|
+
}
|
|
200
|
+
// File doesn't exist or is invalid JSON - skip this project
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Read project settings from <originalPath>/.hammoc/settings.json
|
|
206
|
+
* Returns default values if file doesn't exist
|
|
207
|
+
*/
|
|
208
|
+
async readProjectSettings(originalPath) {
|
|
209
|
+
const settingsPath = path.join(originalPath, '.hammoc', 'settings.json');
|
|
210
|
+
try {
|
|
211
|
+
const content = await fs.readFile(settingsPath, 'utf-8');
|
|
212
|
+
return JSON.parse(content);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return {};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Write project settings to <originalPath>/.hammoc/settings.json
|
|
220
|
+
* Creates .hammoc directory if it doesn't exist
|
|
221
|
+
* Supports null values to delete overrides (null = remove field, undefined = no change)
|
|
222
|
+
*/
|
|
223
|
+
async writeProjectSettings(originalPath, settings) {
|
|
224
|
+
const hammocDir = path.join(originalPath, '.hammoc');
|
|
225
|
+
await fs.mkdir(hammocDir, { recursive: true });
|
|
226
|
+
const settingsPath = path.join(hammocDir, 'settings.json');
|
|
227
|
+
const existing = await this.readProjectSettings(originalPath);
|
|
228
|
+
const merged = { ...existing };
|
|
229
|
+
// Apply updates: null = delete override, undefined = no change, value = set
|
|
230
|
+
for (const [key, value] of Object.entries(settings)) {
|
|
231
|
+
if (value === null) {
|
|
232
|
+
delete merged[key];
|
|
233
|
+
}
|
|
234
|
+
else if (value !== undefined) {
|
|
235
|
+
merged[key] = value;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
await fs.writeFile(settingsPath, JSON.stringify(merged, null, 2), 'utf-8');
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Internal helper: builds ProjectSettingsApiResponse from an already-resolved originalPath.
|
|
242
|
+
* Used by both getProjectSettingsWithEffective() and updateProjectSettings() to avoid
|
|
243
|
+
* redundant parseSessionsIndex() calls.
|
|
244
|
+
*/
|
|
245
|
+
async _buildEffectiveResponse(originalPath) {
|
|
246
|
+
const projectSettings = await this.readProjectSettings(originalPath);
|
|
247
|
+
const globalPrefs = await preferencesService.getEffectivePreferences();
|
|
248
|
+
const _overrides = [];
|
|
249
|
+
if (projectSettings.modelOverride !== undefined)
|
|
250
|
+
_overrides.push('modelOverride');
|
|
251
|
+
if (projectSettings.permissionModeOverride !== undefined)
|
|
252
|
+
_overrides.push('permissionModeOverride');
|
|
253
|
+
return {
|
|
254
|
+
...projectSettings,
|
|
255
|
+
effectiveModel: projectSettings.modelOverride ?? globalPrefs.defaultModel ?? '',
|
|
256
|
+
effectivePermissionMode: projectSettings.permissionModeOverride
|
|
257
|
+
?? (globalPrefs.permissionMode === 'latest' ? (globalPrefs.lastPermissionMode ?? 'default') : (globalPrefs.permissionMode ?? 'default')),
|
|
258
|
+
_overrides,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Returns project settings merged with global preferences.
|
|
263
|
+
* Calculates effective values and identifies which fields are overridden.
|
|
264
|
+
*/
|
|
265
|
+
async getProjectSettingsWithEffective(projectSlug) {
|
|
266
|
+
const projectDir = path.join(this.getClaudeProjectsDir(), projectSlug);
|
|
267
|
+
const info = await this.parseSessionsIndex(projectDir, projectSlug);
|
|
268
|
+
if (!info) {
|
|
269
|
+
const err = new Error('프로젝트를 찾을 수 없습니다.');
|
|
270
|
+
err.code = 'PROJECT_NOT_FOUND';
|
|
271
|
+
throw err;
|
|
272
|
+
}
|
|
273
|
+
return this._buildEffectiveResponse(info.originalPath);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Update settings for a project identified by its slug
|
|
277
|
+
* @returns Updated ProjectSettingsApiResponse with effective values
|
|
278
|
+
*/
|
|
279
|
+
async updateProjectSettings(projectSlug, settings) {
|
|
280
|
+
const projectDir = path.join(this.getClaudeProjectsDir(), projectSlug);
|
|
281
|
+
const info = await this.parseSessionsIndex(projectDir, projectSlug);
|
|
282
|
+
if (!info) {
|
|
283
|
+
const err = new Error('프로젝트를 찾을 수 없습니다.');
|
|
284
|
+
err.code = 'PROJECT_NOT_FOUND';
|
|
285
|
+
throw err;
|
|
286
|
+
}
|
|
287
|
+
await this.writeProjectSettings(info.originalPath, settings);
|
|
288
|
+
return this._buildEffectiveResponse(info.originalPath);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Read session names from <originalPath>/.hammoc/session-names.json
|
|
292
|
+
* Returns empty object if file doesn't exist
|
|
293
|
+
*/
|
|
294
|
+
async readSessionNames(originalPath) {
|
|
295
|
+
const namesPath = path.join(originalPath, '.hammoc', 'session-names.json');
|
|
296
|
+
try {
|
|
297
|
+
const content = await fs.readFile(namesPath, 'utf-8');
|
|
298
|
+
return JSON.parse(content);
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
return {};
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Write session names to <originalPath>/.hammoc/session-names.json
|
|
306
|
+
*/
|
|
307
|
+
async writeSessionNames(originalPath, names) {
|
|
308
|
+
const hammocDir = path.join(originalPath, '.hammoc');
|
|
309
|
+
await fs.mkdir(hammocDir, { recursive: true });
|
|
310
|
+
const namesPath = path.join(hammocDir, 'session-names.json');
|
|
311
|
+
await fs.writeFile(namesPath, JSON.stringify(names, null, 2), 'utf-8');
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Update a session name for a project identified by slug
|
|
315
|
+
* @param name null to remove the name
|
|
316
|
+
*/
|
|
317
|
+
async updateSessionName(projectSlug, sessionId, name) {
|
|
318
|
+
const projectDir = path.join(this.getClaudeProjectsDir(), projectSlug);
|
|
319
|
+
const info = await this.parseSessionsIndex(projectDir, projectSlug);
|
|
320
|
+
if (!info) {
|
|
321
|
+
const err = new Error('프로젝트를 찾을 수 없습니다.');
|
|
322
|
+
err.code = 'PROJECT_NOT_FOUND';
|
|
323
|
+
throw err;
|
|
324
|
+
}
|
|
325
|
+
const names = await this.readSessionNames(info.originalPath);
|
|
326
|
+
if (name) {
|
|
327
|
+
names[sessionId] = name;
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
delete names[sessionId];
|
|
331
|
+
}
|
|
332
|
+
await this.writeSessionNames(info.originalPath, names);
|
|
333
|
+
return name;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Resolve a project slug to its original filesystem path.
|
|
337
|
+
* Returns null if the project does not exist.
|
|
338
|
+
*/
|
|
339
|
+
async resolveProjectPath(projectSlug) {
|
|
340
|
+
const projectDir = path.join(this.getClaudeProjectsDir(), projectSlug);
|
|
341
|
+
const info = await this.parseSessionsIndex(projectDir, projectSlug);
|
|
342
|
+
return info?.originalPath ?? null;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Read session names for a project identified by slug
|
|
346
|
+
*/
|
|
347
|
+
async readSessionNamesBySlug(projectSlug) {
|
|
348
|
+
const projectDir = path.join(this.getClaudeProjectsDir(), projectSlug);
|
|
349
|
+
const info = await this.parseSessionsIndex(projectDir, projectSlug);
|
|
350
|
+
if (!info)
|
|
351
|
+
return {};
|
|
352
|
+
return this.readSessionNames(info.originalPath);
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Read prompt history for a session within a project
|
|
356
|
+
*/
|
|
357
|
+
async readPromptHistory(originalPath, sessionId) {
|
|
358
|
+
const historyPath = path.join(originalPath, '.hammoc', 'prompt-history', `${sessionId}.json`);
|
|
359
|
+
try {
|
|
360
|
+
const content = await fs.readFile(historyPath, 'utf-8');
|
|
361
|
+
return JSON.parse(content);
|
|
362
|
+
}
|
|
363
|
+
catch {
|
|
364
|
+
return { history: [] };
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Write prompt history for a session within a project
|
|
369
|
+
*/
|
|
370
|
+
async writePromptHistory(originalPath, sessionId, data) {
|
|
371
|
+
const historyDir = path.join(originalPath, '.hammoc', 'prompt-history');
|
|
372
|
+
await fs.mkdir(historyDir, { recursive: true });
|
|
373
|
+
const historyPath = path.join(historyDir, `${sessionId}.json`);
|
|
374
|
+
await fs.writeFile(historyPath, JSON.stringify(data, null, 2), 'utf-8');
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Read prompt history for a session identified by project slug
|
|
378
|
+
*/
|
|
379
|
+
async readPromptHistoryBySlug(projectSlug, sessionId) {
|
|
380
|
+
const projectDir = path.join(this.getClaudeProjectsDir(), projectSlug);
|
|
381
|
+
const info = await this.parseSessionsIndex(projectDir, projectSlug);
|
|
382
|
+
if (!info)
|
|
383
|
+
return { history: [] };
|
|
384
|
+
return this.readPromptHistory(info.originalPath, sessionId);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Write prompt history for a session identified by project slug
|
|
388
|
+
*/
|
|
389
|
+
async writePromptHistoryBySlug(projectSlug, sessionId, data) {
|
|
390
|
+
const projectDir = path.join(this.getClaudeProjectsDir(), projectSlug);
|
|
391
|
+
const info = await this.parseSessionsIndex(projectDir, projectSlug);
|
|
392
|
+
if (!info) {
|
|
393
|
+
const err = new Error('프로젝트를 찾을 수 없습니다.');
|
|
394
|
+
err.code = 'PROJECT_NOT_FOUND';
|
|
395
|
+
throw err;
|
|
396
|
+
}
|
|
397
|
+
await this.writePromptHistory(info.originalPath, sessionId, data);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Extract originalPath (cwd) from a .jsonl session file's first few lines.
|
|
401
|
+
* Used as fallback when sessions-index.json doesn't exist (e.g., VS Code extension projects).
|
|
402
|
+
* Only reads the first 4KB to avoid loading large conversation logs.
|
|
403
|
+
*/
|
|
404
|
+
async extractCwdFromSessionFiles(projectDir) {
|
|
405
|
+
try {
|
|
406
|
+
const files = await fs.readdir(projectDir);
|
|
407
|
+
const jsonlFiles = files.filter((f) => f.endsWith('.jsonl'));
|
|
408
|
+
if (jsonlFiles.length === 0)
|
|
409
|
+
return null;
|
|
410
|
+
const filePath = path.join(projectDir, jsonlFiles[0]);
|
|
411
|
+
const handle = await fs.open(filePath, 'r');
|
|
412
|
+
try {
|
|
413
|
+
const buffer = Buffer.alloc(4096);
|
|
414
|
+
const { bytesRead } = await handle.read(buffer, 0, 4096, 0);
|
|
415
|
+
const chunk = buffer.toString('utf-8', 0, bytesRead);
|
|
416
|
+
const lines = chunk.split('\n');
|
|
417
|
+
for (const line of lines) {
|
|
418
|
+
if (!line.trim())
|
|
419
|
+
continue;
|
|
420
|
+
try {
|
|
421
|
+
const entry = JSON.parse(line);
|
|
422
|
+
if (entry.cwd && typeof entry.cwd === 'string') {
|
|
423
|
+
return entry.cwd;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
catch {
|
|
427
|
+
continue; // incomplete JSON line at buffer boundary
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
finally {
|
|
432
|
+
await handle.close();
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
catch {
|
|
436
|
+
// Failed to read directory or file
|
|
437
|
+
}
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Build ProjectInfo from a project directory without sessions-index.json.
|
|
442
|
+
* Scans .jsonl files for session count, timestamps, and originalPath.
|
|
443
|
+
*/
|
|
444
|
+
async buildProjectFromDirectory(projectDir, projectSlug) {
|
|
445
|
+
const originalPath = await this.extractCwdFromSessionFiles(projectDir);
|
|
446
|
+
if (!originalPath)
|
|
447
|
+
return null;
|
|
448
|
+
let sessionCount = 0;
|
|
449
|
+
const mtimes = [];
|
|
450
|
+
try {
|
|
451
|
+
const files = await fs.readdir(projectDir);
|
|
452
|
+
for (const f of files) {
|
|
453
|
+
if (!f.endsWith('.jsonl'))
|
|
454
|
+
continue;
|
|
455
|
+
sessionCount++;
|
|
456
|
+
const fileStat = await fs.stat(path.join(projectDir, f));
|
|
457
|
+
mtimes.push(fileStat.mtime.getTime());
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
catch {
|
|
461
|
+
// Failed to read directory
|
|
462
|
+
}
|
|
463
|
+
let lastModified;
|
|
464
|
+
if (mtimes.length > 0) {
|
|
465
|
+
lastModified = new Date(Math.max(...mtimes)).toISOString();
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
const stat = await fs.stat(projectDir);
|
|
469
|
+
lastModified = stat.mtime.toISOString();
|
|
470
|
+
}
|
|
471
|
+
const isBmadProject = await this.checkBmadProject(originalPath);
|
|
472
|
+
const settings = await this.readProjectSettings(originalPath);
|
|
473
|
+
return {
|
|
474
|
+
originalPath,
|
|
475
|
+
projectSlug,
|
|
476
|
+
sessionCount,
|
|
477
|
+
lastModified,
|
|
478
|
+
isBmadProject,
|
|
479
|
+
...(settings.hidden !== undefined && { hidden: settings.hidden }),
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Resolve a project slug to its originalPath.
|
|
484
|
+
* Tries sessions-index.json first, falls back to JSONL-based discovery.
|
|
485
|
+
* @throws Error with code 'PROJECT_NOT_FOUND' if project cannot be resolved
|
|
486
|
+
*/
|
|
487
|
+
async resolveOriginalPath(projectSlug) {
|
|
488
|
+
const projectDir = path.join(this.getClaudeProjectsDir(), projectSlug);
|
|
489
|
+
let info = await this.parseSessionsIndex(projectDir, projectSlug);
|
|
490
|
+
if (!info) {
|
|
491
|
+
info = await this.buildProjectFromDirectory(projectDir, projectSlug);
|
|
492
|
+
}
|
|
493
|
+
if (!info) {
|
|
494
|
+
const err = new Error('프로젝트를 찾을 수 없습니다.');
|
|
495
|
+
err.code = 'PROJECT_NOT_FOUND';
|
|
496
|
+
throw err;
|
|
497
|
+
}
|
|
498
|
+
return info.originalPath;
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Get session count for a single project (lightweight, no full scan).
|
|
502
|
+
* Used by dashboard to avoid expensive scanProjects() calls.
|
|
503
|
+
*/
|
|
504
|
+
async getProjectSessionCount(projectSlug) {
|
|
505
|
+
const projectDir = path.join(this.getClaudeProjectsDir(), projectSlug);
|
|
506
|
+
const info = await this.parseSessionsIndex(projectDir, projectSlug);
|
|
507
|
+
if (info)
|
|
508
|
+
return info.sessionCount;
|
|
509
|
+
const fallback = await this.buildProjectFromDirectory(projectDir, projectSlug);
|
|
510
|
+
return fallback?.sessionCount ?? 0;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Check if a path exists on the filesystem
|
|
514
|
+
* @param targetPath Path to check
|
|
515
|
+
* @returns true if path exists
|
|
516
|
+
*/
|
|
517
|
+
async checkPathExists(targetPath) {
|
|
518
|
+
try {
|
|
519
|
+
await fs.access(targetPath);
|
|
520
|
+
return true;
|
|
521
|
+
}
|
|
522
|
+
catch {
|
|
523
|
+
return false;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Check if a project has .bmad-core folder
|
|
528
|
+
* @param originalPath The original project path from sessions-index.json
|
|
529
|
+
* @returns true if .bmad-core folder exists
|
|
530
|
+
*/
|
|
531
|
+
async checkBmadProject(originalPath) {
|
|
532
|
+
const bmadCorePath = path.join(originalPath, '.bmad-core');
|
|
533
|
+
try {
|
|
534
|
+
const stat = await fs.stat(bmadCorePath);
|
|
535
|
+
return stat.isDirectory();
|
|
536
|
+
}
|
|
537
|
+
catch {
|
|
538
|
+
return false;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Validate a directory path
|
|
543
|
+
* [Source: Story 3.6 - Task 2]
|
|
544
|
+
* @param inputPath Path to validate
|
|
545
|
+
* @returns Validation result
|
|
546
|
+
*/
|
|
547
|
+
async validatePath(inputPath) {
|
|
548
|
+
// Security check
|
|
549
|
+
if (!isValidPathFormat(inputPath)) {
|
|
550
|
+
return {
|
|
551
|
+
valid: false,
|
|
552
|
+
exists: false,
|
|
553
|
+
isProject: false,
|
|
554
|
+
error: '경로 형식이 올바르지 않습니다. 절대 경로를 사용해 주세요.',
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
// Check if path exists
|
|
558
|
+
try {
|
|
559
|
+
const stat = await fs.stat(inputPath);
|
|
560
|
+
if (!stat.isDirectory()) {
|
|
561
|
+
return {
|
|
562
|
+
valid: false,
|
|
563
|
+
exists: true,
|
|
564
|
+
isProject: false,
|
|
565
|
+
error: '지정한 경로가 파일입니다. 디렉토리 경로를 입력해 주세요.',
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
catch (error) {
|
|
570
|
+
if (error.code === 'ENOENT') {
|
|
571
|
+
// Path doesn't exist yet - valid for project creation (will be created)
|
|
572
|
+
return {
|
|
573
|
+
valid: true,
|
|
574
|
+
exists: false,
|
|
575
|
+
isProject: false,
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
throw error;
|
|
579
|
+
}
|
|
580
|
+
// Check if already a project
|
|
581
|
+
const existingProject = await this.findProjectByPath(inputPath);
|
|
582
|
+
if (existingProject) {
|
|
583
|
+
return {
|
|
584
|
+
valid: true,
|
|
585
|
+
exists: true,
|
|
586
|
+
isProject: true,
|
|
587
|
+
projectSlug: existingProject.projectSlug,
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
return {
|
|
591
|
+
valid: true,
|
|
592
|
+
exists: true,
|
|
593
|
+
isProject: false,
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Find project by original path
|
|
598
|
+
* [Source: Story 3.6 - Task 2]
|
|
599
|
+
* @param originalPath Original project path
|
|
600
|
+
* @returns ProjectInfo or null
|
|
601
|
+
*/
|
|
602
|
+
async findProjectByPath(originalPath) {
|
|
603
|
+
const projects = await this.scanProjects();
|
|
604
|
+
// Normalize both paths for comparison (handle case sensitivity on Windows)
|
|
605
|
+
const normalizedInput = path.normalize(originalPath);
|
|
606
|
+
return (projects.find((p) => {
|
|
607
|
+
const normalizedProject = path.normalize(p.originalPath);
|
|
608
|
+
// Case-insensitive comparison on Windows, case-sensitive on Unix
|
|
609
|
+
if (process.platform === 'win32') {
|
|
610
|
+
return normalizedProject.toLowerCase() === normalizedInput.toLowerCase();
|
|
611
|
+
}
|
|
612
|
+
return normalizedProject === normalizedInput;
|
|
613
|
+
}) || null);
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Create a new project
|
|
617
|
+
* [Source: Story 3.6 - Task 2]
|
|
618
|
+
* @param request Create project request
|
|
619
|
+
* @returns Created project info
|
|
620
|
+
*/
|
|
621
|
+
async createProject(request) {
|
|
622
|
+
const { path: projectPath, setupBmad = true, bmadVersion } = request;
|
|
623
|
+
// Validate path first
|
|
624
|
+
const validation = await this.validatePath(projectPath);
|
|
625
|
+
if (!validation.valid) {
|
|
626
|
+
const error = new Error(validation.error || '경로 검증 실패');
|
|
627
|
+
error.code = 'INVALID_PATH';
|
|
628
|
+
throw error;
|
|
629
|
+
}
|
|
630
|
+
// Check if already exists
|
|
631
|
+
if (validation.isProject && validation.projectSlug) {
|
|
632
|
+
const existingProject = await this.findProjectByPath(projectPath);
|
|
633
|
+
if (existingProject) {
|
|
634
|
+
return {
|
|
635
|
+
project: existingProject,
|
|
636
|
+
isExisting: true,
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
// Create project directory if it doesn't exist
|
|
641
|
+
if (!validation.exists) {
|
|
642
|
+
await fs.mkdir(projectPath, { recursive: true });
|
|
643
|
+
}
|
|
644
|
+
// Initialize Claude project (creates sessions-index.json)
|
|
645
|
+
await this.initializeClaudeProject(projectPath);
|
|
646
|
+
// Setup BMad if requested (graceful handling: project creation succeeds even if BMad setup fails)
|
|
647
|
+
let bmadSetupError;
|
|
648
|
+
if (setupBmad) {
|
|
649
|
+
try {
|
|
650
|
+
const version = bmadVersion || (await this.getLatestBmadVersion());
|
|
651
|
+
if (!version) {
|
|
652
|
+
throw new Error('사용 가능한 BMad 버전이 없습니다.');
|
|
653
|
+
}
|
|
654
|
+
await this.setupBmadCore(projectPath, version);
|
|
655
|
+
}
|
|
656
|
+
catch (err) {
|
|
657
|
+
bmadSetupError = err instanceof Error ? err.message : 'BMad 설정 중 오류가 발생했습니다.';
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
// Scan to get the created project info
|
|
661
|
+
const project = await this.findProjectByPath(projectPath);
|
|
662
|
+
if (!project) {
|
|
663
|
+
throw new Error('프로젝트 생성 후 조회에 실패했습니다.');
|
|
664
|
+
}
|
|
665
|
+
return {
|
|
666
|
+
project,
|
|
667
|
+
isExisting: false,
|
|
668
|
+
bmadSetupError,
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* Initialize a Claude project directory
|
|
673
|
+
* Creates the necessary structure in ~/.claude/projects/
|
|
674
|
+
* [Source: Story 3.6 - Task 2]
|
|
675
|
+
*
|
|
676
|
+
* Strategy:
|
|
677
|
+
* 1. Check if project already exists with this path
|
|
678
|
+
* 2. Try to use Claude Code CLI for initialization
|
|
679
|
+
* 3. Fallback: use same path-encoding as Claude Code
|
|
680
|
+
*
|
|
681
|
+
* @param projectPath Original project path
|
|
682
|
+
* @returns Project slug (path-encoded or existing)
|
|
683
|
+
*/
|
|
684
|
+
async initializeClaudeProject(projectPath) {
|
|
685
|
+
// Strategy 1: Check if project already exists with this path
|
|
686
|
+
const existingProject = await this.findProjectByPath(projectPath);
|
|
687
|
+
if (existingProject) {
|
|
688
|
+
return existingProject.projectSlug;
|
|
689
|
+
}
|
|
690
|
+
// Strategy 2: Try to use Claude Code CLI for initialization
|
|
691
|
+
try {
|
|
692
|
+
const { execSync } = await import('child_process');
|
|
693
|
+
// Run a minimal Claude command in the project directory to trigger project creation
|
|
694
|
+
execSync('claude --version', {
|
|
695
|
+
cwd: projectPath,
|
|
696
|
+
stdio: 'pipe',
|
|
697
|
+
timeout: 5000,
|
|
698
|
+
});
|
|
699
|
+
// After CLI execution, scan again to find the newly created project
|
|
700
|
+
// Wait briefly for filesystem sync
|
|
701
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
702
|
+
const newProject = await this.findProjectByPath(projectPath);
|
|
703
|
+
if (newProject) {
|
|
704
|
+
return newProject.projectSlug;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
catch {
|
|
708
|
+
// CLI not available or failed - fall back to self-generation
|
|
709
|
+
log.warn('Claude CLI not available, using fallback path-encoding');
|
|
710
|
+
}
|
|
711
|
+
// Strategy 3: Fallback - use same path-encoding as Claude Code
|
|
712
|
+
// Claude Code encodes project paths by replacing path separators with hyphens
|
|
713
|
+
const projectSlug = projectPath.replace(/[/\\:]/g, '-').replace(/^-/, '');
|
|
714
|
+
const claudeProjectDir = path.join(this.getClaudeProjectsDir(), projectSlug);
|
|
715
|
+
// Create directory if not exists
|
|
716
|
+
await fs.mkdir(claudeProjectDir, { recursive: true });
|
|
717
|
+
// Create sessions-index.json
|
|
718
|
+
const sessionsIndexPath = path.join(claudeProjectDir, 'sessions-index.json');
|
|
719
|
+
if (!existsSync(sessionsIndexPath)) {
|
|
720
|
+
const sessionsIndex = {
|
|
721
|
+
originalPath: projectPath,
|
|
722
|
+
entries: [],
|
|
723
|
+
_generatedBy: 'hammoc',
|
|
724
|
+
_warning: 'This project was created without Claude CLI and may not be fully compatible',
|
|
725
|
+
};
|
|
726
|
+
await fs.writeFile(sessionsIndexPath, JSON.stringify(sessionsIndex, null, 2));
|
|
727
|
+
}
|
|
728
|
+
// Note: Claude Code stores session JSONL files directly in the project folder,
|
|
729
|
+
// not in a sessions subdirectory, so we don't create one here.
|
|
730
|
+
return projectSlug;
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Get list of available BMad method versions from bundled resources
|
|
734
|
+
* @returns Array of version strings sorted descending (latest first)
|
|
735
|
+
*/
|
|
736
|
+
async getBmadVersions() {
|
|
737
|
+
try {
|
|
738
|
+
const entries = await fs.readdir(BMAD_RESOURCES_DIR);
|
|
739
|
+
const versions = [];
|
|
740
|
+
for (const entry of entries) {
|
|
741
|
+
const stat = await fs.stat(path.join(BMAD_RESOURCES_DIR, entry));
|
|
742
|
+
if (stat.isDirectory()) {
|
|
743
|
+
versions.push(entry);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
// Sort by semver descending (latest first)
|
|
747
|
+
versions.sort((a, b) => {
|
|
748
|
+
const partsA = a.split('.').map(Number);
|
|
749
|
+
const partsB = b.split('.').map(Number);
|
|
750
|
+
for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
|
|
751
|
+
const diff = (partsB[i] || 0) - (partsA[i] || 0);
|
|
752
|
+
if (diff !== 0)
|
|
753
|
+
return diff;
|
|
754
|
+
}
|
|
755
|
+
return 0;
|
|
756
|
+
});
|
|
757
|
+
return versions;
|
|
758
|
+
}
|
|
759
|
+
catch {
|
|
760
|
+
return [];
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Get the latest available BMad method version
|
|
765
|
+
* @returns Latest version string or null if none available
|
|
766
|
+
*/
|
|
767
|
+
async getLatestBmadVersion() {
|
|
768
|
+
const versions = await this.getBmadVersions();
|
|
769
|
+
return versions[0] || null;
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* Setup .bmad-core folder in project by copying from bundled template
|
|
773
|
+
* Copies the full BMad method content (agents, tasks, templates, workflows, etc.)
|
|
774
|
+
* @param projectPath Project directory path
|
|
775
|
+
* @param version BMad method version to install
|
|
776
|
+
*/
|
|
777
|
+
async setupBmadCore(projectPath, version) {
|
|
778
|
+
const templateDir = path.join(BMAD_RESOURCES_DIR, version);
|
|
779
|
+
// Validate the version exists
|
|
780
|
+
try {
|
|
781
|
+
await fs.access(templateDir);
|
|
782
|
+
}
|
|
783
|
+
catch {
|
|
784
|
+
throw new Error(`BMad 버전 ${version}을 찾을 수 없습니다.`);
|
|
785
|
+
}
|
|
786
|
+
// Recursively copy template to project
|
|
787
|
+
await this.copyDirRecursive(templateDir, projectPath);
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Setup BMad for an existing project by slug
|
|
791
|
+
* @param projectSlug Project slug (folder name in ~/.claude/projects/)
|
|
792
|
+
* @param version BMad version to install (defaults to latest)
|
|
793
|
+
* @param force Force setup even if project already has .bmad-core
|
|
794
|
+
* @returns Object with updated ProjectInfo and installed version
|
|
795
|
+
*/
|
|
796
|
+
async setupBmadForProject(projectSlug, version, force) {
|
|
797
|
+
const projectDir = path.join(this.getClaudeProjectsDir(), projectSlug);
|
|
798
|
+
const info = await this.parseSessionsIndex(projectDir, projectSlug);
|
|
799
|
+
if (!info) {
|
|
800
|
+
const err = new Error('프로젝트를 찾을 수 없습니다.');
|
|
801
|
+
err.code = 'PROJECT_NOT_FOUND';
|
|
802
|
+
throw err;
|
|
803
|
+
}
|
|
804
|
+
if (info.isBmadProject && !force) {
|
|
805
|
+
const err = new Error('이미 BMad가 설정된 프로젝트입니다.');
|
|
806
|
+
err.code = 'ALREADY_BMAD';
|
|
807
|
+
throw err;
|
|
808
|
+
}
|
|
809
|
+
const resolvedVersion = version || await this.getLatestBmadVersion();
|
|
810
|
+
if (!resolvedVersion) {
|
|
811
|
+
const err = new Error('사용 가능한 BMad 버전이 없습니다.');
|
|
812
|
+
err.code = 'NO_BMAD_VERSION';
|
|
813
|
+
throw err;
|
|
814
|
+
}
|
|
815
|
+
await this.setupBmadCore(info.originalPath, resolvedVersion);
|
|
816
|
+
return { project: { ...info, isBmadProject: true }, installedVersion: resolvedVersion };
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Delete a project's session data from ~/.claude/projects/
|
|
820
|
+
* Optionally also deletes the actual project files on disk.
|
|
821
|
+
* @param projectSlug Project slug (folder name in ~/.claude/projects/)
|
|
822
|
+
* @param deleteFiles If true, also delete the project directory on disk
|
|
823
|
+
* @returns true if deleted successfully
|
|
824
|
+
*/
|
|
825
|
+
async deleteProject(projectSlug, deleteFiles = false) {
|
|
826
|
+
if (!projectSlug || projectSlug.includes('..') || projectSlug.includes('/') || projectSlug.includes('\\')) {
|
|
827
|
+
return false;
|
|
828
|
+
}
|
|
829
|
+
const projectDir = path.join(this.getClaudeProjectsDir(), projectSlug);
|
|
830
|
+
// Read originalPath before deleting session data (needed for file deletion)
|
|
831
|
+
let originalPath;
|
|
832
|
+
if (deleteFiles) {
|
|
833
|
+
const indexPath = path.join(projectDir, 'sessions-index.json');
|
|
834
|
+
try {
|
|
835
|
+
const content = await fs.readFile(indexPath, 'utf-8');
|
|
836
|
+
const index = JSON.parse(content);
|
|
837
|
+
originalPath = index.originalPath || index.entries?.[0]?.projectPath;
|
|
838
|
+
}
|
|
839
|
+
catch {
|
|
840
|
+
// Can't read originalPath — skip file deletion
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
try {
|
|
844
|
+
const stat = await fs.stat(projectDir);
|
|
845
|
+
if (!stat.isDirectory()) {
|
|
846
|
+
return false;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
catch {
|
|
850
|
+
return false;
|
|
851
|
+
}
|
|
852
|
+
// Delete session data
|
|
853
|
+
await fs.rm(projectDir, { recursive: true, force: true });
|
|
854
|
+
// Delete project files on disk if requested
|
|
855
|
+
if (deleteFiles && originalPath) {
|
|
856
|
+
try {
|
|
857
|
+
await fs.rm(originalPath, { recursive: true, force: true });
|
|
858
|
+
}
|
|
859
|
+
catch {
|
|
860
|
+
// Session data already deleted, log but don't fail
|
|
861
|
+
log.warn(`Failed to delete project files at: ${originalPath}`);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
return true;
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Recursively copy directory contents from source to destination
|
|
868
|
+
* Preserves directory structure. Does not overwrite existing files.
|
|
869
|
+
* @param src Source directory path
|
|
870
|
+
* @param dest Destination directory path
|
|
871
|
+
*/
|
|
872
|
+
async copyDirRecursive(src, dest) {
|
|
873
|
+
await fs.mkdir(dest, { recursive: true });
|
|
874
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
875
|
+
for (const entry of entries) {
|
|
876
|
+
const srcPath = path.join(src, entry.name);
|
|
877
|
+
const destPath = path.join(dest, entry.name);
|
|
878
|
+
if (entry.isDirectory()) {
|
|
879
|
+
await this.copyDirRecursive(srcPath, destPath);
|
|
880
|
+
}
|
|
881
|
+
else {
|
|
882
|
+
// Do not overwrite existing files
|
|
883
|
+
if (!existsSync(destPath)) {
|
|
884
|
+
await fs.copyFile(srcPath, destPath);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
// Singleton export - consistent with authService pattern
|
|
891
|
+
export const projectService = new ProjectService();
|
|
892
|
+
//# sourceMappingURL=projectService.js.map
|