cli-jaw 1.4.11 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +56 -26
- package/README.md +30 -24
- package/README.zh-CN.md +56 -26
- package/dist/bin/commands/browser.js +3 -1
- package/dist/bin/commands/browser.js.map +1 -1
- package/dist/bin/commands/chat.js +358 -9
- package/dist/bin/commands/chat.js.map +1 -1
- package/dist/bin/commands/doctor.js +80 -2
- package/dist/bin/commands/doctor.js.map +1 -1
- package/dist/bin/commands/init.js +88 -6
- package/dist/bin/commands/init.js.map +1 -1
- package/dist/bin/commands/serve.js +1 -0
- package/dist/bin/commands/serve.js.map +1 -1
- package/dist/lib/mcp-sync.js +101 -51
- package/dist/lib/mcp-sync.js.map +1 -1
- package/dist/lib/quota-copilot.js +4 -0
- package/dist/lib/quota-copilot.js.map +1 -1
- package/dist/server.js +131 -35
- package/dist/server.js.map +1 -1
- package/dist/src/agent/events.js +198 -29
- package/dist/src/agent/events.js.map +1 -1
- package/dist/src/agent/smoke-detector.js +111 -0
- package/dist/src/agent/smoke-detector.js.map +1 -0
- package/dist/src/agent/spawn.js +157 -26
- package/dist/src/agent/spawn.js.map +1 -1
- package/dist/src/browser/connection.js +9 -1
- package/dist/src/browser/connection.js.map +1 -1
- package/dist/src/browser/launch-policy.js +32 -0
- package/dist/src/browser/launch-policy.js.map +1 -0
- package/dist/src/cli/claude-models.js +46 -0
- package/dist/src/cli/claude-models.js.map +1 -0
- package/dist/src/cli/command-context.js +19 -8
- package/dist/src/cli/command-context.js.map +1 -1
- package/dist/src/cli/commands.js +16 -13
- package/dist/src/cli/commands.js.map +1 -1
- package/dist/src/cli/compact.js +93 -0
- package/dist/src/cli/compact.js.map +1 -0
- package/dist/src/cli/handlers.js +94 -32
- package/dist/src/cli/handlers.js.map +1 -1
- package/dist/src/cli/readiness.js +69 -0
- package/dist/src/cli/readiness.js.map +1 -0
- package/dist/src/cli/registry.js +3 -2
- package/dist/src/cli/registry.js.map +1 -1
- package/dist/src/cli/tui/composer.js +6 -4
- package/dist/src/cli/tui/composer.js.map +1 -1
- package/dist/src/cli/tui/keymap.js +2 -0
- package/dist/src/cli/tui/keymap.js.map +1 -1
- package/dist/src/cli/tui/overlay.js +170 -0
- package/dist/src/cli/tui/overlay.js.map +1 -1
- package/dist/src/cli/tui/store.js +25 -0
- package/dist/src/cli/tui/store.js.map +1 -1
- package/dist/src/cli/tui/transcript.js +46 -0
- package/dist/src/cli/tui/transcript.js.map +1 -0
- package/dist/src/command-contract/catalog.js +8 -4
- package/dist/src/command-contract/catalog.js.map +1 -1
- package/dist/src/core/bus.js +1 -0
- package/dist/src/core/bus.js.map +1 -1
- package/dist/src/core/compact.js +70 -0
- package/dist/src/core/compact.js.map +1 -0
- package/dist/src/core/config.js +109 -3
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/db.js +13 -4
- package/dist/src/core/db.js.map +1 -1
- package/dist/src/core/main-session.js +15 -0
- package/dist/src/core/main-session.js.map +1 -1
- package/dist/src/core/runtime-settings.js +19 -4
- package/dist/src/core/runtime-settings.js.map +1 -1
- package/dist/src/core/settings-merge.js +1 -1
- package/dist/src/core/settings-merge.js.map +1 -1
- package/dist/src/discord/bot.js +274 -0
- package/dist/src/discord/bot.js.map +1 -0
- package/dist/src/discord/commands.js +103 -0
- package/dist/src/discord/commands.js.map +1 -0
- package/dist/src/discord/discord-file.js +43 -0
- package/dist/src/discord/discord-file.js.map +1 -0
- package/dist/src/discord/forwarder.js +45 -0
- package/dist/src/discord/forwarder.js.map +1 -0
- package/dist/src/memory/bootstrap.js +341 -0
- package/dist/src/memory/bootstrap.js.map +1 -0
- package/dist/src/memory/heartbeat.js +11 -22
- package/dist/src/memory/heartbeat.js.map +1 -1
- package/dist/src/memory/indexing.js +329 -0
- package/dist/src/memory/indexing.js.map +1 -0
- package/dist/src/memory/keyword-expand.js +247 -0
- package/dist/src/memory/keyword-expand.js.map +1 -0
- package/dist/src/memory/runtime.js +56 -1090
- package/dist/src/memory/runtime.js.map +1 -1
- package/dist/src/memory/shared.js +167 -0
- package/dist/src/memory/shared.js.map +1 -0
- package/dist/src/messaging/runtime.js +122 -0
- package/dist/src/messaging/runtime.js.map +1 -0
- package/dist/src/messaging/send.js +120 -0
- package/dist/src/messaging/send.js.map +1 -0
- package/dist/src/messaging/session-key.js +25 -0
- package/dist/src/messaging/session-key.js.map +1 -0
- package/dist/src/messaging/types.js +6 -0
- package/dist/src/messaging/types.js.map +1 -0
- package/dist/src/orchestrator/collect.js +5 -0
- package/dist/src/orchestrator/collect.js.map +1 -1
- package/dist/src/orchestrator/distribute.js +34 -8
- package/dist/src/orchestrator/distribute.js.map +1 -1
- package/dist/src/orchestrator/gateway.js +18 -12
- package/dist/src/orchestrator/gateway.js.map +1 -1
- package/dist/src/orchestrator/parser.js +0 -28
- package/dist/src/orchestrator/parser.js.map +1 -1
- package/dist/src/orchestrator/pipeline.js +94 -75
- package/dist/src/orchestrator/pipeline.js.map +1 -1
- package/dist/src/orchestrator/state-machine.js +23 -20
- package/dist/src/orchestrator/state-machine.js.map +1 -1
- package/dist/src/orchestrator/worker-monitor.js +50 -0
- package/dist/src/orchestrator/worker-monitor.js.map +1 -0
- package/dist/src/orchestrator/worker-registry.js +107 -0
- package/dist/src/orchestrator/worker-registry.js.map +1 -0
- package/dist/src/prompt/builder.js +78 -6
- package/dist/src/prompt/builder.js.map +1 -1
- package/dist/src/prompt/templates/a1-system.md +52 -10
- package/dist/src/prompt/templates/employee.md +17 -5
- package/dist/src/prompt/templates/orchestration.md +11 -10
- package/dist/src/prompt/templates/research-worker.md +1 -1
- package/dist/src/prompt/templates/worker-context.md +4 -4
- package/dist/src/routes/browser.js +14 -3
- package/dist/src/routes/browser.js.map +1 -1
- package/dist/src/telegram/bot.js +92 -8
- package/dist/src/telegram/bot.js.map +1 -1
- package/dist/src/types/agent.js +4 -0
- package/dist/src/types/agent.js.map +1 -0
- package/package.json +27 -15
- package/public/css/chat.css +365 -127
- package/public/css/layout.css +67 -10
- package/public/css/markdown.css +219 -54
- package/public/css/modals.css +35 -15
- package/public/css/orc-state.css +16 -16
- package/public/css/sidebar.css +12 -12
- package/public/css/tool-ui.css +483 -0
- package/public/css/variables.css +334 -6
- package/public/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/public/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/public/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/public/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/public/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/public/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/public/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/public/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/public/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/public/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/public/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/public/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/public/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/public/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/public/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/public/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/public/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/public/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/public/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/public/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/public/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/public/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/public/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/public/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/public/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/public/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/public/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/public/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/public/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/public/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/public/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/public/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/public/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/public/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/public/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/public/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/public/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/public/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/public/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/public/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/public/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/public/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/public/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/public/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/public/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/public/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/public/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/public/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/public/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/public/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/public/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/public/dist/assets/api-B8XKQ4OT.js +1 -0
- package/public/dist/assets/api-BlPw3bUI.js +1 -0
- package/public/dist/assets/architecture-YZFGNWBL-BkS7SZQi.js +1 -0
- package/public/dist/assets/architectureDiagram-Q4EWVU46-Dl3iBKeR.js +1 -0
- package/public/dist/assets/blockDiagram-DXYQGD6D-DPr4D17p.js +1 -0
- package/public/dist/assets/c4Diagram-AHTNJAMY-CfoxJtDk.js +1 -0
- package/public/dist/assets/classDiagram-6PBFFD2Q-BOAdHnnB.js +1 -0
- package/public/dist/assets/classDiagram-v2-HSJHXN6E-B2QCJXWC.js +1 -0
- package/public/dist/assets/constants-DshMUJbo.js +1 -0
- package/public/dist/assets/cose-bilkent-S5V4N54A-CA14jk7w.js +1 -0
- package/public/dist/assets/dagre-KV5264BT-BVwNaSwC.js +1 -0
- package/public/dist/assets/diagram-5BDNPKRD-CHqIAvdc.js +1 -0
- package/public/dist/assets/diagram-G4DWMVQ6-DxvsCvTP.js +1 -0
- package/public/dist/assets/diagram-MMDJMWI5-DqOPO7dl.js +1 -0
- package/public/dist/assets/diagram-TYMM5635-C9xMWPQn.js +1 -0
- package/public/dist/assets/employees-CFRlsbHm.js +39 -0
- package/public/dist/assets/erDiagram-SMLLAGMA-BTmpfRkm.js +1 -0
- package/public/dist/assets/flowDiagram-DWJPFMVM-DZBSQAKA.js +1 -0
- package/public/dist/assets/ganttDiagram-T4ZO3ILL-TAEMCRbT.js +1 -0
- package/public/dist/assets/gitGraph-7Q5UKJZL-bbxndRNA.js +1 -0
- package/public/dist/assets/gitGraphDiagram-UUTBAWPF-CBxtx0MB.js +1 -0
- package/public/dist/assets/icon-192-CwXPIYF5.png +0 -0
- package/public/dist/assets/index-1Gg-6jeC.css +1 -0
- package/public/dist/assets/index-CQHqXjrK.js +49 -0
- package/public/dist/assets/info-OMHHGYJF-DRXq_Ywr.js +1 -0
- package/public/dist/assets/infoDiagram-42DDH7IO-C7FFwX4m.js +1 -0
- package/public/dist/assets/ishikawaDiagram-UXIWVN3A-DEZJE79j.js +1 -0
- package/public/dist/assets/journeyDiagram-VCZTEJTY-ZHLiY6GV.js +1 -0
- package/public/dist/assets/kanban-definition-6JOO6SKY-NP7pY7ML.js +1 -0
- package/public/dist/assets/katex-DZLS_HFU.js +1 -0
- package/public/dist/assets/locale-BjoAcbis.js +1 -0
- package/public/dist/assets/manifest-Bw-LRm-c.json +20 -0
- package/public/dist/assets/mermaid.core-CHuluSlD.js +1 -0
- package/public/dist/assets/mindmap-definition-QFDTVHPH-Bd1OgfN_.js +1 -0
- package/public/dist/assets/packet-4T2RLAQJ-CGu8ST97.js +1 -0
- package/public/dist/assets/pie-ZZUOXDRM-CDG65mhS.js +1 -0
- package/public/dist/assets/pieDiagram-DEJITSTG-BbMBHLDM.js +1 -0
- package/public/dist/assets/quadrantDiagram-34T5L4WZ-CDCDgI1e.js +1 -0
- package/public/dist/assets/radar-PYXPWWZC-1gS-6ylu.js +1 -0
- package/public/dist/assets/render-YHvL5VM_.js +6 -0
- package/public/dist/assets/requirementDiagram-MS252O5E-DkmvOtYz.js +1 -0
- package/public/dist/assets/rolldown-runtime-FhOqtrmT.js +1 -0
- package/public/dist/assets/sankeyDiagram-XADWPNL6-GNcXIYsL.js +1 -0
- package/public/dist/assets/sequenceDiagram-FGHM5R23-BFrw2n6x.js +1 -0
- package/public/dist/assets/settings-BQF_u5px.js +37 -0
- package/public/dist/assets/settings-C5Q9IPjJ.js +1 -0
- package/public/dist/assets/shark-sprite-B3AAuERd.png +0 -0
- package/public/dist/assets/skills-9Pd2rOw-.js +1 -0
- package/public/dist/assets/skills-BI7sQAdk.js +12 -0
- package/public/dist/assets/slash-commands-DMsE88bu.js +14 -0
- package/public/dist/assets/slash-commands-FMpJzlDB.js +1 -0
- package/public/dist/assets/state-O6NVkWcL.js +1 -0
- package/public/dist/assets/stateDiagram-FHFEXIEX-BLgKnllT.js +1 -0
- package/public/dist/assets/stateDiagram-v2-QKLJ7IA2-CbzuWsSa.js +1 -0
- package/public/dist/assets/timeline-definition-GMOUNBTQ-CcZTJ3gL.js +1 -0
- package/public/dist/assets/treeView-SZITEDCU-BDqBsaH1.js +1 -0
- package/public/dist/assets/treemap-W4RFUUIX-BaWHA3Di.js +1 -0
- package/public/dist/assets/ui-BukgLHuh.js +29 -0
- package/public/dist/assets/ui-Bvz1JfTE.js +1 -0
- package/public/dist/assets/vendor-mermaid-COidH9HB.js +2934 -0
- package/public/dist/assets/vendor-render-Bjnw0wQ6.css +1 -0
- package/public/dist/assets/vendor-render-D2YP6GiF.js +322 -0
- package/public/dist/assets/vennDiagram-DHZGUBPP-BWV_j1bh.js +1 -0
- package/public/dist/assets/wardley-RL74JXVD-C7gKA3d7.js +1 -0
- package/public/dist/assets/wardleyDiagram-NUSXRM2D-BUoq_wug.js +1 -0
- package/public/dist/assets/ws-S_AZgx7L.js +2 -0
- package/public/dist/assets/xychartDiagram-5P7HB3ND-PvT5Ec82.js +1 -0
- package/public/dist/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/public/dist/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/public/dist/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/public/dist/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/public/dist/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/public/dist/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/public/dist/dist/assets/api-B8XKQ4OT.js +1 -0
- package/public/dist/dist/assets/api-BlPw3bUI.js +1 -0
- package/public/dist/dist/assets/architecture-YZFGNWBL-BkS7SZQi.js +1 -0
- package/public/dist/dist/assets/architectureDiagram-Q4EWVU46-Dl3iBKeR.js +1 -0
- package/public/dist/dist/assets/blockDiagram-DXYQGD6D-DPr4D17p.js +1 -0
- package/public/dist/dist/assets/c4Diagram-AHTNJAMY-CfoxJtDk.js +1 -0
- package/public/dist/dist/assets/classDiagram-6PBFFD2Q-BOAdHnnB.js +1 -0
- package/public/dist/dist/assets/classDiagram-v2-HSJHXN6E-B2QCJXWC.js +1 -0
- package/public/dist/dist/assets/constants-DshMUJbo.js +1 -0
- package/public/dist/dist/assets/cose-bilkent-S5V4N54A-CA14jk7w.js +1 -0
- package/public/dist/dist/assets/dagre-KV5264BT-BVwNaSwC.js +1 -0
- package/public/dist/dist/assets/diagram-5BDNPKRD-CHqIAvdc.js +1 -0
- package/public/dist/dist/assets/diagram-G4DWMVQ6-DxvsCvTP.js +1 -0
- package/public/dist/dist/assets/diagram-MMDJMWI5-DqOPO7dl.js +1 -0
- package/public/dist/dist/assets/diagram-TYMM5635-C9xMWPQn.js +1 -0
- package/public/dist/dist/assets/employees-CFRlsbHm.js +39 -0
- package/public/dist/dist/assets/erDiagram-SMLLAGMA-BTmpfRkm.js +1 -0
- package/public/dist/dist/assets/flowDiagram-DWJPFMVM-DZBSQAKA.js +1 -0
- package/public/dist/dist/assets/ganttDiagram-T4ZO3ILL-TAEMCRbT.js +1 -0
- package/public/dist/dist/assets/gitGraph-7Q5UKJZL-bbxndRNA.js +1 -0
- package/public/dist/dist/assets/gitGraphDiagram-UUTBAWPF-CBxtx0MB.js +1 -0
- package/public/dist/dist/assets/icon-192-CwXPIYF5.png +0 -0
- package/public/dist/dist/assets/index-1Gg-6jeC.css +1 -0
- package/public/dist/dist/assets/index-CQHqXjrK.js +49 -0
- package/public/dist/dist/assets/info-OMHHGYJF-DRXq_Ywr.js +1 -0
- package/public/dist/dist/assets/infoDiagram-42DDH7IO-C7FFwX4m.js +1 -0
- package/public/dist/dist/assets/ishikawaDiagram-UXIWVN3A-DEZJE79j.js +1 -0
- package/public/dist/dist/assets/journeyDiagram-VCZTEJTY-ZHLiY6GV.js +1 -0
- package/public/dist/dist/assets/kanban-definition-6JOO6SKY-NP7pY7ML.js +1 -0
- package/public/dist/dist/assets/katex-DZLS_HFU.js +1 -0
- package/public/dist/dist/assets/locale-BjoAcbis.js +1 -0
- package/public/dist/dist/assets/manifest-Bw-LRm-c.json +20 -0
- package/public/dist/dist/assets/mermaid.core-CHuluSlD.js +1 -0
- package/public/dist/dist/assets/mindmap-definition-QFDTVHPH-Bd1OgfN_.js +1 -0
- package/public/dist/dist/assets/packet-4T2RLAQJ-CGu8ST97.js +1 -0
- package/public/dist/dist/assets/pie-ZZUOXDRM-CDG65mhS.js +1 -0
- package/public/dist/dist/assets/pieDiagram-DEJITSTG-BbMBHLDM.js +1 -0
- package/public/dist/dist/assets/quadrantDiagram-34T5L4WZ-CDCDgI1e.js +1 -0
- package/public/dist/dist/assets/radar-PYXPWWZC-1gS-6ylu.js +1 -0
- package/public/dist/dist/assets/render-YHvL5VM_.js +6 -0
- package/public/dist/dist/assets/requirementDiagram-MS252O5E-DkmvOtYz.js +1 -0
- package/public/dist/dist/assets/rolldown-runtime-FhOqtrmT.js +1 -0
- package/public/dist/dist/assets/sankeyDiagram-XADWPNL6-GNcXIYsL.js +1 -0
- package/public/dist/dist/assets/sequenceDiagram-FGHM5R23-BFrw2n6x.js +1 -0
- package/public/dist/dist/assets/settings-BQF_u5px.js +37 -0
- package/public/dist/dist/assets/settings-C5Q9IPjJ.js +1 -0
- package/public/dist/dist/assets/shark-sprite-B3AAuERd.png +0 -0
- package/public/dist/dist/assets/skills-9Pd2rOw-.js +1 -0
- package/public/dist/dist/assets/skills-BI7sQAdk.js +12 -0
- package/public/dist/dist/assets/slash-commands-DMsE88bu.js +14 -0
- package/public/dist/dist/assets/slash-commands-FMpJzlDB.js +1 -0
- package/public/dist/dist/assets/state-O6NVkWcL.js +1 -0
- package/public/dist/dist/assets/stateDiagram-FHFEXIEX-BLgKnllT.js +1 -0
- package/public/dist/dist/assets/stateDiagram-v2-QKLJ7IA2-CbzuWsSa.js +1 -0
- package/public/dist/dist/assets/timeline-definition-GMOUNBTQ-CcZTJ3gL.js +1 -0
- package/public/dist/dist/assets/treeView-SZITEDCU-BDqBsaH1.js +1 -0
- package/public/dist/dist/assets/treemap-W4RFUUIX-BaWHA3Di.js +1 -0
- package/public/dist/dist/assets/ui-BukgLHuh.js +29 -0
- package/public/dist/dist/assets/ui-Bvz1JfTE.js +1 -0
- package/public/dist/dist/assets/vendor-mermaid-COidH9HB.js +2934 -0
- package/public/dist/dist/assets/vendor-render-Bjnw0wQ6.css +1 -0
- package/public/dist/dist/assets/vendor-render-D2YP6GiF.js +322 -0
- package/public/dist/dist/assets/vennDiagram-DHZGUBPP-BWV_j1bh.js +1 -0
- package/public/dist/dist/assets/wardley-RL74JXVD-C7gKA3d7.js +1 -0
- package/public/dist/dist/assets/wardleyDiagram-NUSXRM2D-BUoq_wug.js +1 -0
- package/public/dist/dist/assets/ws-S_AZgx7L.js +2 -0
- package/public/dist/dist/assets/xychartDiagram-5P7HB3ND-PvT5Ec82.js +1 -0
- package/public/dist/dist/index.html +708 -0
- package/public/dist/index.html +708 -0
- package/public/icons/icon-192.png +0 -0
- package/public/icons/icon-512-maskable.png +0 -0
- package/public/icons/icon-512.png +0 -0
- package/public/index.html +178 -125
- package/public/js/constants.ts +6 -6
- package/public/js/features/chat.ts +23 -3
- package/public/js/features/employees.ts +12 -12
- package/public/js/features/gesture.ts +61 -0
- package/public/js/features/heartbeat.ts +1 -1
- package/public/js/features/idb-cache.ts +89 -0
- package/public/js/features/memory.ts +4 -1
- package/public/js/features/process-block.ts +236 -0
- package/public/js/features/settings-channel.ts +53 -0
- package/public/js/features/settings-cli-status.ts +164 -0
- package/public/js/features/settings-core.ts +357 -0
- package/public/js/features/settings-discord.ts +52 -0
- package/public/js/features/settings-mcp.ts +54 -0
- package/public/js/features/settings-stt.ts +78 -0
- package/public/js/features/settings-telegram.ts +40 -0
- package/public/js/features/settings-templates.ts +129 -0
- package/public/js/features/settings-types.ts +24 -0
- package/public/js/features/settings.ts +9 -815
- package/public/js/features/sidebar.ts +4 -2
- package/public/js/features/skills.ts +5 -4
- package/public/js/features/slash-commands.ts +1 -8
- package/public/js/features/theme.ts +16 -10
- package/public/js/features/tool-ui.ts +113 -0
- package/public/js/main.ts +67 -8
- package/public/js/render.ts +128 -90
- package/public/js/state.ts +4 -0
- package/public/js/streaming-render.ts +55 -0
- package/public/js/ui.ts +289 -46
- package/public/js/virtual-scroll.ts +189 -0
- package/public/js/ws.ts +175 -112
- package/public/locales/en.json +6 -1
- package/public/locales/ko.json +6 -1
- package/public/manifest.json +20 -0
- package/public/public/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/public/public/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/public/public/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/public/public/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/public/public/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/public/public/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/public/public/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/public/public/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/public/public/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/public/public/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/public/public/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/public/public/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/public/public/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/public/public/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/public/public/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/public/public/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/public/public/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/public/public/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/public/public/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/public/public/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/public/public/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/public/public/dist/assets/api-B8XKQ4OT.js +1 -0
- package/public/public/dist/assets/api-BlPw3bUI.js +1 -0
- package/public/public/dist/assets/architecture-YZFGNWBL-BkS7SZQi.js +1 -0
- package/public/public/dist/assets/architectureDiagram-Q4EWVU46-Dl3iBKeR.js +1 -0
- package/public/public/dist/assets/blockDiagram-DXYQGD6D-DPr4D17p.js +1 -0
- package/public/public/dist/assets/c4Diagram-AHTNJAMY-CfoxJtDk.js +1 -0
- package/public/public/dist/assets/classDiagram-6PBFFD2Q-BOAdHnnB.js +1 -0
- package/public/public/dist/assets/classDiagram-v2-HSJHXN6E-B2QCJXWC.js +1 -0
- package/public/public/dist/assets/constants-DshMUJbo.js +1 -0
- package/public/public/dist/assets/cose-bilkent-S5V4N54A-CA14jk7w.js +1 -0
- package/public/public/dist/assets/dagre-KV5264BT-BVwNaSwC.js +1 -0
- package/public/public/dist/assets/diagram-5BDNPKRD-CHqIAvdc.js +1 -0
- package/public/public/dist/assets/diagram-G4DWMVQ6-DxvsCvTP.js +1 -0
- package/public/public/dist/assets/diagram-MMDJMWI5-DqOPO7dl.js +1 -0
- package/public/public/dist/assets/diagram-TYMM5635-C9xMWPQn.js +1 -0
- package/public/public/dist/assets/employees-CFRlsbHm.js +39 -0
- package/public/public/dist/assets/erDiagram-SMLLAGMA-BTmpfRkm.js +1 -0
- package/public/public/dist/assets/flowDiagram-DWJPFMVM-DZBSQAKA.js +1 -0
- package/public/public/dist/assets/ganttDiagram-T4ZO3ILL-TAEMCRbT.js +1 -0
- package/public/public/dist/assets/gitGraph-7Q5UKJZL-bbxndRNA.js +1 -0
- package/public/public/dist/assets/gitGraphDiagram-UUTBAWPF-CBxtx0MB.js +1 -0
- package/public/public/dist/assets/icon-192-CwXPIYF5.png +0 -0
- package/public/public/dist/assets/index-1Gg-6jeC.css +1 -0
- package/public/public/dist/assets/index-CQHqXjrK.js +49 -0
- package/public/public/dist/assets/info-OMHHGYJF-DRXq_Ywr.js +1 -0
- package/public/public/dist/assets/infoDiagram-42DDH7IO-C7FFwX4m.js +1 -0
- package/public/public/dist/assets/ishikawaDiagram-UXIWVN3A-DEZJE79j.js +1 -0
- package/public/public/dist/assets/journeyDiagram-VCZTEJTY-ZHLiY6GV.js +1 -0
- package/public/public/dist/assets/kanban-definition-6JOO6SKY-NP7pY7ML.js +1 -0
- package/public/public/dist/assets/katex-DZLS_HFU.js +1 -0
- package/public/public/dist/assets/locale-BjoAcbis.js +1 -0
- package/public/public/dist/assets/manifest-Bw-LRm-c.json +20 -0
- package/public/public/dist/assets/mermaid.core-CHuluSlD.js +1 -0
- package/public/public/dist/assets/mindmap-definition-QFDTVHPH-Bd1OgfN_.js +1 -0
- package/public/public/dist/assets/packet-4T2RLAQJ-CGu8ST97.js +1 -0
- package/public/public/dist/assets/pie-ZZUOXDRM-CDG65mhS.js +1 -0
- package/public/public/dist/assets/pieDiagram-DEJITSTG-BbMBHLDM.js +1 -0
- package/public/public/dist/assets/quadrantDiagram-34T5L4WZ-CDCDgI1e.js +1 -0
- package/public/public/dist/assets/radar-PYXPWWZC-1gS-6ylu.js +1 -0
- package/public/public/dist/assets/render-YHvL5VM_.js +6 -0
- package/public/public/dist/assets/requirementDiagram-MS252O5E-DkmvOtYz.js +1 -0
- package/public/public/dist/assets/rolldown-runtime-FhOqtrmT.js +1 -0
- package/public/public/dist/assets/sankeyDiagram-XADWPNL6-GNcXIYsL.js +1 -0
- package/public/public/dist/assets/sequenceDiagram-FGHM5R23-BFrw2n6x.js +1 -0
- package/public/public/dist/assets/settings-BQF_u5px.js +37 -0
- package/public/public/dist/assets/settings-C5Q9IPjJ.js +1 -0
- package/public/public/dist/assets/shark-sprite-B3AAuERd.png +0 -0
- package/public/public/dist/assets/skills-9Pd2rOw-.js +1 -0
- package/public/public/dist/assets/skills-BI7sQAdk.js +12 -0
- package/public/public/dist/assets/slash-commands-DMsE88bu.js +14 -0
- package/public/public/dist/assets/slash-commands-FMpJzlDB.js +1 -0
- package/public/public/dist/assets/state-O6NVkWcL.js +1 -0
- package/public/public/dist/assets/stateDiagram-FHFEXIEX-BLgKnllT.js +1 -0
- package/public/public/dist/assets/stateDiagram-v2-QKLJ7IA2-CbzuWsSa.js +1 -0
- package/public/public/dist/assets/timeline-definition-GMOUNBTQ-CcZTJ3gL.js +1 -0
- package/public/public/dist/assets/treeView-SZITEDCU-BDqBsaH1.js +1 -0
- package/public/public/dist/assets/treemap-W4RFUUIX-BaWHA3Di.js +1 -0
- package/public/public/dist/assets/ui-BukgLHuh.js +29 -0
- package/public/public/dist/assets/ui-Bvz1JfTE.js +1 -0
- package/public/public/dist/assets/vendor-mermaid-COidH9HB.js +2934 -0
- package/public/public/dist/assets/vendor-render-Bjnw0wQ6.css +1 -0
- package/public/public/dist/assets/vendor-render-D2YP6GiF.js +322 -0
- package/public/public/dist/assets/vennDiagram-DHZGUBPP-BWV_j1bh.js +1 -0
- package/public/public/dist/assets/wardley-RL74JXVD-C7gKA3d7.js +1 -0
- package/public/public/dist/assets/wardleyDiagram-NUSXRM2D-BUoq_wug.js +1 -0
- package/public/public/dist/assets/ws-S_AZgx7L.js +2 -0
- package/public/public/dist/assets/xychartDiagram-5P7HB3ND-PvT5Ec82.js +1 -0
- package/public/public/dist/index.html +708 -0
- package/public/sw.js +104 -0
- package/scripts/install-officecli.sh +145 -0
- package/scripts/release-preview.sh +18 -10
- package/scripts/release.sh +3 -3
- package/public/dist/bundle.js +0 -151
- package/public/dist/bundle.js.map +0 -7
|
@@ -1,1084 +1,18 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import os from 'os';
|
|
3
|
-
import
|
|
4
|
-
import { join, relative, dirname } from 'path';
|
|
5
|
-
import { createHash, createSign } from 'crypto';
|
|
3
|
+
import { join, relative } from 'path';
|
|
6
4
|
import { JAW_HOME, settings } from '../core/config.js';
|
|
7
|
-
import { instanceId } from '../core/instance.js';
|
|
8
5
|
import { getMemory } from '../core/db.js';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
export function getAdvancedFlushFilePath(date = new Date().toISOString().slice(0, 10)) {
|
|
21
|
-
return join(getAdvancedMemoryDir(), 'episodes', 'live', `${date}.md`);
|
|
22
|
-
}
|
|
23
|
-
function getAdvancedIndexDbPath() {
|
|
24
|
-
return join(getAdvancedMemoryDir(), 'index.sqlite');
|
|
25
|
-
}
|
|
26
|
-
function getMigrationLockPath() {
|
|
27
|
-
return join(getAdvancedMemoryDir(), '.migration.lock');
|
|
28
|
-
}
|
|
29
|
-
export function normalizeOpenAiCompatibleBaseUrl(raw) {
|
|
30
|
-
const value = String(raw || '').trim();
|
|
31
|
-
if (!value)
|
|
32
|
-
return '';
|
|
33
|
-
const trimmed = value.replace(/\/+$/, '');
|
|
34
|
-
return /\/v1$/i.test(trimmed) ? trimmed : `${trimmed}/v1`;
|
|
35
|
-
}
|
|
36
|
-
function getAdvancedConfig(override = {}) {
|
|
37
|
-
return {
|
|
38
|
-
enabled: true,
|
|
39
|
-
provider: override.provider ?? 'integrated',
|
|
40
|
-
model: override.model ?? '',
|
|
41
|
-
apiKey: override.apiKey ?? '',
|
|
42
|
-
baseUrl: normalizeOpenAiCompatibleBaseUrl(override.baseUrl ?? ''),
|
|
43
|
-
vertexConfig: override.vertexConfig ?? '',
|
|
44
|
-
bootstrap: {
|
|
45
|
-
enabled: override.bootstrap?.enabled ?? true,
|
|
46
|
-
useActiveCli: override.bootstrap?.useActiveCli ?? true,
|
|
47
|
-
cli: override.bootstrap?.cli ?? '',
|
|
48
|
-
model: override.bootstrap?.model ?? '',
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
function ensureDir(path) {
|
|
53
|
-
fs.mkdirSync(path, { recursive: true });
|
|
54
|
-
}
|
|
55
|
-
function safeReadFile(path) {
|
|
56
|
-
try {
|
|
57
|
-
return fs.readFileSync(path, 'utf8');
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
return '';
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
function writeText(path, content) {
|
|
64
|
-
ensureDir(dirname(path));
|
|
65
|
-
fs.writeFileSync(path, content);
|
|
66
|
-
}
|
|
67
|
-
function frontmatter(meta) {
|
|
68
|
-
const lines = ['---'];
|
|
69
|
-
for (const [k, v] of Object.entries(meta)) {
|
|
70
|
-
lines.push(`${k}: ${v}`);
|
|
71
|
-
}
|
|
72
|
-
lines.push('---', '');
|
|
73
|
-
return lines.join('\n');
|
|
74
|
-
}
|
|
75
|
-
function hashText(text) {
|
|
76
|
-
return createHash('sha1').update(text).digest('hex').slice(0, 12);
|
|
77
|
-
}
|
|
78
|
-
function heuristicKeywords(query) {
|
|
79
|
-
const q = String(query || '').trim();
|
|
80
|
-
if (!q)
|
|
81
|
-
return [];
|
|
82
|
-
const tokens = q.split(/[\s,]+/).map(t => t.trim()).filter(Boolean);
|
|
83
|
-
const out = new Set([q, ...tokens]);
|
|
84
|
-
const lower = q.toLowerCase();
|
|
85
|
-
if (/login|로그인|auth|인증/.test(lower)) {
|
|
86
|
-
out.add('login');
|
|
87
|
-
out.add('auth');
|
|
88
|
-
out.add('인증');
|
|
89
|
-
out.add('401');
|
|
90
|
-
}
|
|
91
|
-
if (/launchd|service|plist|시작 안됨/.test(lower)) {
|
|
92
|
-
out.add('launchd');
|
|
93
|
-
out.add('plist');
|
|
94
|
-
out.add('service');
|
|
95
|
-
}
|
|
96
|
-
return [...out].slice(0, 5);
|
|
97
|
-
}
|
|
98
|
-
function sanitizeKeywords(input) {
|
|
99
|
-
const raw = Array.isArray(input) ? input : [];
|
|
100
|
-
const out = [];
|
|
101
|
-
const seen = new Set();
|
|
102
|
-
for (const item of raw) {
|
|
103
|
-
const value = String(item || '')
|
|
104
|
-
.replace(/[;&|`$><]/g, ' ')
|
|
105
|
-
.replace(/\s+/g, ' ')
|
|
106
|
-
.trim()
|
|
107
|
-
.slice(0, 48);
|
|
108
|
-
if (!value)
|
|
109
|
-
continue;
|
|
110
|
-
const key = value.toLowerCase();
|
|
111
|
-
if (seen.has(key))
|
|
112
|
-
continue;
|
|
113
|
-
seen.add(key);
|
|
114
|
-
out.push(value);
|
|
115
|
-
if (out.length >= 5)
|
|
116
|
-
break;
|
|
117
|
-
}
|
|
118
|
-
return out;
|
|
119
|
-
}
|
|
120
|
-
function extractJsonArray(text) {
|
|
121
|
-
const trimmed = String(text || '').trim();
|
|
122
|
-
if (!trimmed)
|
|
123
|
-
return [];
|
|
124
|
-
try {
|
|
125
|
-
const parsed = JSON.parse(trimmed);
|
|
126
|
-
return sanitizeKeywords(parsed);
|
|
127
|
-
}
|
|
128
|
-
catch {
|
|
129
|
-
const match = trimmed.match(/\[[\s\S]*\]/);
|
|
130
|
-
if (match) {
|
|
131
|
-
try {
|
|
132
|
-
return sanitizeKeywords(JSON.parse(match[0]));
|
|
133
|
-
}
|
|
134
|
-
catch {
|
|
135
|
-
return [];
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return [];
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
async function expandViaGemini(query, override = {}) {
|
|
142
|
-
const cfg = getAdvancedConfig(override);
|
|
143
|
-
const apiKey = cfg.apiKey || process.env.GEMINI_API_KEY || '';
|
|
144
|
-
const model = cfg.model || 'gemini-3.1-flash-lite-preview';
|
|
145
|
-
if (!apiKey)
|
|
146
|
-
return [];
|
|
147
|
-
const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;
|
|
148
|
-
const body = {
|
|
149
|
-
contents: [{
|
|
150
|
-
parts: [{
|
|
151
|
-
text: `사용자 질문을 바탕으로 로컬 마크다운 기억을 뒤질 검색 키워드 5개를 JSON 배열로만 출력해라.
|
|
152
|
-
- 한국어, 영어, 동의어, 에러코드, 모듈명 포함 가능
|
|
153
|
-
- 예: ["로그인","login","auth","401","인증"]
|
|
154
|
-
|
|
155
|
-
질문: ${query}`,
|
|
156
|
-
}],
|
|
157
|
-
}],
|
|
158
|
-
};
|
|
159
|
-
const res = await fetch(url, {
|
|
160
|
-
method: 'POST',
|
|
161
|
-
headers: { 'Content-Type': 'application/json' },
|
|
162
|
-
body: JSON.stringify(body),
|
|
163
|
-
});
|
|
164
|
-
if (!res.ok)
|
|
165
|
-
return [];
|
|
166
|
-
const json = await res.json();
|
|
167
|
-
const text = json?.candidates?.[0]?.content?.parts?.map((p) => p?.text || '').join('\n') || '';
|
|
168
|
-
return extractJsonArray(text);
|
|
169
|
-
}
|
|
170
|
-
async function expandViaOpenAiCompatible(query, override = {}) {
|
|
171
|
-
const cfg = getAdvancedConfig(override);
|
|
172
|
-
const apiKey = cfg.apiKey || '';
|
|
173
|
-
const baseUrl = cfg.baseUrl || '';
|
|
174
|
-
const model = cfg.model || 'gpt-4o-mini';
|
|
175
|
-
if (!apiKey || !baseUrl)
|
|
176
|
-
return [];
|
|
177
|
-
const res = await fetch(`${baseUrl}/chat/completions`, {
|
|
178
|
-
method: 'POST',
|
|
179
|
-
headers: {
|
|
180
|
-
'Content-Type': 'application/json',
|
|
181
|
-
Authorization: `Bearer ${apiKey}`,
|
|
182
|
-
},
|
|
183
|
-
body: JSON.stringify({
|
|
184
|
-
model,
|
|
185
|
-
temperature: 0,
|
|
186
|
-
response_format: { type: 'json_object' },
|
|
187
|
-
messages: [
|
|
188
|
-
{
|
|
189
|
-
role: 'system',
|
|
190
|
-
content: 'Return only valid JSON: {"keywords":["k1","k2","k3"]}',
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
role: 'user',
|
|
194
|
-
content: `Expand this user query into up to 5 search keywords for local markdown search. Include Korean, English, synonyms, error codes, module names when helpful.\nQuery: ${query}`,
|
|
195
|
-
},
|
|
196
|
-
],
|
|
197
|
-
}),
|
|
198
|
-
});
|
|
199
|
-
if (!res.ok)
|
|
200
|
-
return [];
|
|
201
|
-
const json = await res.json();
|
|
202
|
-
const text = json?.choices?.[0]?.message?.content || '';
|
|
203
|
-
try {
|
|
204
|
-
const parsed = JSON.parse(text);
|
|
205
|
-
return sanitizeKeywords(parsed.keywords);
|
|
206
|
-
}
|
|
207
|
-
catch {
|
|
208
|
-
return extractJsonArray(text);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
function loadServiceAccount(config) {
|
|
212
|
-
if (config.credentials_json || config.credentialsJson)
|
|
213
|
-
return config.credentials_json || config.credentialsJson;
|
|
214
|
-
const path = config.credentials_path || config.credentialsPath || '';
|
|
215
|
-
if (!path)
|
|
216
|
-
return null;
|
|
217
|
-
try {
|
|
218
|
-
return JSON.parse(fs.readFileSync(path, 'utf8'));
|
|
219
|
-
}
|
|
220
|
-
catch {
|
|
221
|
-
return null;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
async function getGoogleAccessToken(sa) {
|
|
225
|
-
const iat = Math.floor(Date.now() / 1000);
|
|
226
|
-
const exp = iat + 3600;
|
|
227
|
-
const header = Buffer.from(JSON.stringify({ alg: 'RS256', typ: 'JWT' })).toString('base64url');
|
|
228
|
-
const claim = Buffer.from(JSON.stringify({
|
|
229
|
-
iss: sa.client_email,
|
|
230
|
-
scope: 'https://www.googleapis.com/auth/cloud-platform',
|
|
231
|
-
aud: sa.token_uri,
|
|
232
|
-
exp,
|
|
233
|
-
iat,
|
|
234
|
-
})).toString('base64url');
|
|
235
|
-
const unsigned = `${header}.${claim}`;
|
|
236
|
-
const signer = createSign('RSA-SHA256');
|
|
237
|
-
signer.update(unsigned);
|
|
238
|
-
signer.end();
|
|
239
|
-
const signature = signer.sign(sa.private_key).toString('base64url');
|
|
240
|
-
const assertion = `${unsigned}.${signature}`;
|
|
241
|
-
const body = new URLSearchParams({
|
|
242
|
-
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
243
|
-
assertion,
|
|
244
|
-
});
|
|
245
|
-
const res = await fetch(sa.token_uri, {
|
|
246
|
-
method: 'POST',
|
|
247
|
-
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
248
|
-
body,
|
|
249
|
-
});
|
|
250
|
-
if (!res.ok)
|
|
251
|
-
return '';
|
|
252
|
-
const json = await res.json();
|
|
253
|
-
return json?.access_token || '';
|
|
254
|
-
}
|
|
255
|
-
async function expandViaVertex(query, override = {}) {
|
|
256
|
-
const cfgSetting = getAdvancedConfig(override);
|
|
257
|
-
const cfgRaw = cfgSetting.vertexConfig || '';
|
|
258
|
-
if (!cfgRaw)
|
|
259
|
-
return [];
|
|
260
|
-
let cfg;
|
|
261
|
-
try {
|
|
262
|
-
cfg = JSON.parse(cfgRaw);
|
|
263
|
-
}
|
|
264
|
-
catch {
|
|
265
|
-
return [];
|
|
266
|
-
}
|
|
267
|
-
let endpoint = cfg.endpoint || '';
|
|
268
|
-
let token = cfg.token || '';
|
|
269
|
-
const model = cfgSetting.model || cfg.model || 'gemini-3.1-flash-lite-preview';
|
|
270
|
-
if (!endpoint) {
|
|
271
|
-
const sa = loadServiceAccount(cfg);
|
|
272
|
-
const project = cfg.project_id || cfg.projectId || sa?.project_id;
|
|
273
|
-
const location = cfg.location || 'us-central1';
|
|
274
|
-
if (sa && !token)
|
|
275
|
-
token = await getGoogleAccessToken(sa);
|
|
276
|
-
if (project) {
|
|
277
|
-
endpoint = `https://${location}-aiplatform.googleapis.com/v1/projects/${project}/locations/${location}/publishers/google/models/${model}:generateContent`;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
if (!endpoint || !token)
|
|
281
|
-
return [];
|
|
282
|
-
const body = {
|
|
283
|
-
contents: [{
|
|
284
|
-
role: 'user',
|
|
285
|
-
parts: [{
|
|
286
|
-
text: `Return only a JSON array of up to 5 search keywords for local markdown search. Include Korean, English, synonyms, error codes, module names when useful.\nQuery: ${query}`,
|
|
287
|
-
}],
|
|
288
|
-
}],
|
|
289
|
-
};
|
|
290
|
-
const res = await fetch(endpoint, {
|
|
291
|
-
method: 'POST',
|
|
292
|
-
headers: {
|
|
293
|
-
'Content-Type': 'application/json',
|
|
294
|
-
Authorization: `Bearer ${token}`,
|
|
295
|
-
},
|
|
296
|
-
body: JSON.stringify(body),
|
|
297
|
-
});
|
|
298
|
-
if (!res.ok)
|
|
299
|
-
return [];
|
|
300
|
-
const json = await res.json();
|
|
301
|
-
const text = json?.candidates?.[0]?.content?.parts?.map((p) => p?.text || '').join('\n') || '';
|
|
302
|
-
return extractJsonArray(text);
|
|
303
|
-
}
|
|
304
|
-
export async function expandSearchKeywords(query) {
|
|
305
|
-
const q = String(query || '').trim();
|
|
306
|
-
if (!q)
|
|
307
|
-
return [];
|
|
308
|
-
const merged = sanitizeKeywords(heuristicKeywords(q));
|
|
309
|
-
lastExpansionTerms = merged;
|
|
310
|
-
return merged;
|
|
311
|
-
}
|
|
312
|
-
export async function validateAdvancedMemoryConfig(override = {}) {
|
|
313
|
-
const cfg = getAdvancedConfig(override);
|
|
314
|
-
return { ok: true, provider: cfg.provider || 'integrated', error: '' };
|
|
315
|
-
}
|
|
316
|
-
function slug(value) {
|
|
317
|
-
return value
|
|
318
|
-
.replace(/\\/g, '/')
|
|
319
|
-
.replace(/[^a-zA-Z0-9._/-]+/g, '-')
|
|
320
|
-
.replace(/-+/g, '-')
|
|
321
|
-
.replace(/^-|-$/g, '');
|
|
322
|
-
}
|
|
323
|
-
function listMarkdownFiles(dir) {
|
|
324
|
-
if (!fs.existsSync(dir))
|
|
325
|
-
return [];
|
|
326
|
-
const out = [];
|
|
327
|
-
const walk = (current) => {
|
|
328
|
-
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
|
329
|
-
if (entry.name.startsWith('.'))
|
|
330
|
-
continue;
|
|
331
|
-
const full = join(current, entry.name);
|
|
332
|
-
if (entry.isDirectory())
|
|
333
|
-
walk(full);
|
|
334
|
-
else if (entry.name.endsWith('.md'))
|
|
335
|
-
out.push(full);
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
walk(dir);
|
|
339
|
-
return out.sort();
|
|
340
|
-
}
|
|
341
|
-
function countMarkdownFiles(dir) {
|
|
342
|
-
return listMarkdownFiles(dir).length;
|
|
343
|
-
}
|
|
344
|
-
function countFiles(dir) {
|
|
345
|
-
if (!fs.existsSync(dir))
|
|
346
|
-
return 0;
|
|
347
|
-
let count = 0;
|
|
348
|
-
const walk = (current) => {
|
|
349
|
-
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
|
350
|
-
if (entry.name.startsWith('.'))
|
|
351
|
-
continue;
|
|
352
|
-
const full = join(current, entry.name);
|
|
353
|
-
if (entry.isDirectory())
|
|
354
|
-
walk(full);
|
|
355
|
-
else
|
|
356
|
-
count++;
|
|
357
|
-
}
|
|
358
|
-
};
|
|
359
|
-
walk(dir);
|
|
360
|
-
return count;
|
|
361
|
-
}
|
|
362
|
-
function getMetaPath() {
|
|
363
|
-
return join(getAdvancedMemoryDir(), 'meta.json');
|
|
364
|
-
}
|
|
365
|
-
function readMeta() {
|
|
366
|
-
const metaPath = getMetaPath();
|
|
367
|
-
if (!fs.existsSync(metaPath))
|
|
368
|
-
return null;
|
|
369
|
-
try {
|
|
370
|
-
return JSON.parse(fs.readFileSync(metaPath, 'utf8'));
|
|
371
|
-
}
|
|
372
|
-
catch {
|
|
373
|
-
return null;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
function writeMeta(patch) {
|
|
377
|
-
const base = readMeta() || {
|
|
378
|
-
schemaVersion: 1,
|
|
379
|
-
phase: '1',
|
|
380
|
-
homeId: instanceId(),
|
|
381
|
-
jawHome: JAW_HOME,
|
|
382
|
-
initializedAt: new Date().toISOString(),
|
|
383
|
-
migrationVersion: 1,
|
|
384
|
-
migrationState: 'pending',
|
|
385
|
-
migratedAt: null,
|
|
386
|
-
sourceLayout: 'legacy',
|
|
387
|
-
bootstrapStatus: 'idle',
|
|
388
|
-
importedCounts: { ...DEFAULT_IMPORTED_COUNTS },
|
|
389
|
-
};
|
|
390
|
-
const next = {
|
|
391
|
-
...base,
|
|
392
|
-
...patch,
|
|
393
|
-
importedCounts: {
|
|
394
|
-
...(base.importedCounts || DEFAULT_IMPORTED_COUNTS),
|
|
395
|
-
...(patch.importedCounts || {}),
|
|
396
|
-
},
|
|
397
|
-
};
|
|
398
|
-
writeText(getMetaPath(), JSON.stringify(next, null, 2));
|
|
399
|
-
return next;
|
|
400
|
-
}
|
|
401
|
-
function withMigrationLock(fn) {
|
|
402
|
-
const lockPath = getMigrationLockPath();
|
|
403
|
-
ensureDir(dirname(lockPath));
|
|
404
|
-
if (fs.existsSync(lockPath))
|
|
405
|
-
return fn();
|
|
406
|
-
fs.writeFileSync(lockPath, String(process.pid));
|
|
407
|
-
try {
|
|
408
|
-
return fn();
|
|
409
|
-
}
|
|
410
|
-
finally {
|
|
411
|
-
try {
|
|
412
|
-
fs.unlinkSync(lockPath);
|
|
413
|
-
}
|
|
414
|
-
catch { /* ignore */ }
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
function migrateLegacyAdvancedRoot(root) {
|
|
418
|
-
const oldRoot = getLegacyAdvancedMemoryDir();
|
|
419
|
-
if (!fs.existsSync(oldRoot) || oldRoot === root)
|
|
420
|
-
return false;
|
|
421
|
-
const newExists = fs.existsSync(root) && fs.readdirSync(root).length > 0;
|
|
422
|
-
if (newExists)
|
|
423
|
-
return false;
|
|
424
|
-
ensureDir(dirname(root));
|
|
425
|
-
fs.cpSync(oldRoot, root, { recursive: true });
|
|
426
|
-
writeMeta({
|
|
427
|
-
migrationVersion: 1,
|
|
428
|
-
migrationState: 'done',
|
|
429
|
-
migratedAt: new Date().toISOString(),
|
|
430
|
-
sourceLayout: 'advanced',
|
|
431
|
-
});
|
|
432
|
-
return true;
|
|
433
|
-
}
|
|
434
|
-
function parseLegacyMemorySections(content) {
|
|
435
|
-
const sections = {
|
|
436
|
-
userPreferences: '',
|
|
437
|
-
keyDecisions: '',
|
|
438
|
-
activeProjects: '',
|
|
439
|
-
};
|
|
440
|
-
const patterns = [
|
|
441
|
-
{ key: 'userPreferences', re: /## User Preferences([\s\S]*?)(?=\n## |\s*$)/i },
|
|
442
|
-
{ key: 'keyDecisions', re: /## Key Decisions([\s\S]*?)(?=\n## |\s*$)/i },
|
|
443
|
-
{ key: 'activeProjects', re: /## Active Projects([\s\S]*?)(?=\n## |\s*$)/i },
|
|
444
|
-
];
|
|
445
|
-
for (const p of patterns) {
|
|
446
|
-
const match = p.re.exec(content);
|
|
447
|
-
if (match?.[1])
|
|
448
|
-
sections[p.key] = match[1].trim();
|
|
449
|
-
}
|
|
450
|
-
return sections;
|
|
451
|
-
}
|
|
452
|
-
function getLegacyClaudeMemoryDir() {
|
|
453
|
-
const wd = (settings.workingDir || os.homedir()).replace(/^~/, os.homedir());
|
|
454
|
-
const hash = wd.replace(/\//g, '-');
|
|
455
|
-
return join(os.homedir(), '.claude', 'projects', hash, 'memory');
|
|
456
|
-
}
|
|
457
|
-
function importCoreMemory(root) {
|
|
458
|
-
const corePath = join(JAW_HOME, 'memory', 'MEMORY.md');
|
|
459
|
-
if (!fs.existsSync(corePath))
|
|
460
|
-
return 0;
|
|
461
|
-
const profilePath = join(root, 'profile.md');
|
|
462
|
-
if (fs.existsSync(profilePath)) {
|
|
463
|
-
// Profile already exists — preserve user edits, skip overwrite
|
|
464
|
-
return 0;
|
|
465
|
-
}
|
|
466
|
-
const content = safeReadFile(corePath);
|
|
467
|
-
const parsed = parseLegacyMemorySections(content);
|
|
468
|
-
const body = `# Profile
|
|
469
|
-
|
|
470
|
-
## User Preferences
|
|
471
|
-
${parsed.userPreferences || ''}
|
|
472
|
-
|
|
473
|
-
## Key Decisions
|
|
474
|
-
${parsed.keyDecisions || ''}
|
|
475
|
-
|
|
476
|
-
## Active Projects
|
|
477
|
-
${parsed.activeProjects || ''}
|
|
478
|
-
`;
|
|
479
|
-
const fm = frontmatter({
|
|
480
|
-
id: `profile-${instanceId()}`,
|
|
481
|
-
home_id: instanceId(),
|
|
482
|
-
kind: 'profile',
|
|
483
|
-
source: 'legacy-memory-md',
|
|
484
|
-
trust_level: 'high',
|
|
485
|
-
created_at: new Date().toISOString(),
|
|
486
|
-
updated_at: new Date().toISOString(),
|
|
487
|
-
});
|
|
488
|
-
writeText(profilePath, fm + body);
|
|
489
|
-
return 1;
|
|
490
|
-
}
|
|
491
|
-
function importMarkdownMemory(root) {
|
|
492
|
-
const legacyDir = join(JAW_HOME, 'memory');
|
|
493
|
-
if (!fs.existsSync(legacyDir))
|
|
494
|
-
return 0;
|
|
495
|
-
const files = listMarkdownFiles(legacyDir).filter(f => f !== join(legacyDir, 'MEMORY.md'));
|
|
496
|
-
let imported = 0;
|
|
497
|
-
for (const file of files) {
|
|
498
|
-
const rel = relative(legacyDir, file).replace(/\\/g, '/');
|
|
499
|
-
const body = safeReadFile(file);
|
|
500
|
-
const sourceHash = hashText(body);
|
|
501
|
-
const baseName = rel.split('/').pop() || 'memory.md';
|
|
502
|
-
const isDated = /^\d{4}-\d{2}-\d{2}\.md$/.test(baseName);
|
|
503
|
-
const sectionDir = isDated ? 'episodes/imported' : 'semantic/imported';
|
|
504
|
-
const dest = join(root, sectionDir, rel);
|
|
505
|
-
const fm = frontmatter({
|
|
506
|
-
id: `import-${sourceHash}`,
|
|
507
|
-
home_id: instanceId(),
|
|
508
|
-
kind: isDated ? 'episode' : 'semantic',
|
|
509
|
-
source: 'legacy-markdown',
|
|
510
|
-
trust_level: 'high',
|
|
511
|
-
source_relpath: rel,
|
|
512
|
-
source_hash: sourceHash,
|
|
513
|
-
created_at: new Date().toISOString(),
|
|
514
|
-
updated_at: new Date().toISOString(),
|
|
515
|
-
});
|
|
516
|
-
writeText(dest, fm + body.trim() + '\n');
|
|
517
|
-
imported += 1;
|
|
518
|
-
}
|
|
519
|
-
return imported;
|
|
520
|
-
}
|
|
521
|
-
function importKvMemory(root) {
|
|
522
|
-
const rows = getMemory.all();
|
|
523
|
-
if (!rows.length)
|
|
524
|
-
return 0;
|
|
525
|
-
const lines = rows.map(r => `- \`${r.key}\`: ${r.value} ${r.source ? `(source: ${r.source})` : ''}`);
|
|
526
|
-
const fm = frontmatter({
|
|
527
|
-
id: `kv-${instanceId()}`,
|
|
528
|
-
home_id: instanceId(),
|
|
529
|
-
kind: 'semantic',
|
|
530
|
-
source: 'legacy-kv-table',
|
|
531
|
-
trust_level: 'high',
|
|
532
|
-
created_at: new Date().toISOString(),
|
|
533
|
-
updated_at: new Date().toISOString(),
|
|
534
|
-
});
|
|
535
|
-
writeText(join(root, 'semantic', 'kv-imported.md'), fm + '# Imported KV Memory\n\n' + lines.join('\n') + '\n');
|
|
536
|
-
return rows.length;
|
|
537
|
-
}
|
|
538
|
-
function importClaudeSessionMemory(root) {
|
|
539
|
-
const claudeDir = getLegacyClaudeMemoryDir();
|
|
540
|
-
if (!fs.existsSync(claudeDir))
|
|
541
|
-
return 0;
|
|
542
|
-
const files = listMarkdownFiles(claudeDir);
|
|
543
|
-
let imported = 0;
|
|
544
|
-
for (const file of files) {
|
|
545
|
-
const real = fs.realpathSync(file);
|
|
546
|
-
const body = safeReadFile(file);
|
|
547
|
-
const sourceHash = hashText(body);
|
|
548
|
-
const base = slug(relative(claudeDir, real).replace(/\\/g, '/')) || slug(file.split('/').pop() || 'legacy');
|
|
549
|
-
const dest = join(root, 'episodes', 'legacy', `${base}-${sourceHash}.md`);
|
|
550
|
-
const fm = frontmatter({
|
|
551
|
-
id: `claude-${sourceHash}`,
|
|
552
|
-
home_id: instanceId(),
|
|
553
|
-
kind: 'episode',
|
|
554
|
-
source: 'external-claude-memory',
|
|
555
|
-
trust_level: 'medium',
|
|
556
|
-
source_realpath: real.replace(/\\/g, '/'),
|
|
557
|
-
source_hash: sourceHash,
|
|
558
|
-
created_at: new Date().toISOString(),
|
|
559
|
-
updated_at: new Date().toISOString(),
|
|
560
|
-
});
|
|
561
|
-
writeText(dest, fm + body.trim() + '\n');
|
|
562
|
-
imported += 1;
|
|
563
|
-
}
|
|
564
|
-
return imported;
|
|
565
|
-
}
|
|
566
|
-
function backupLegacyMemory() {
|
|
567
|
-
const backupRoot = getAdvancedMemoryBackupDir();
|
|
568
|
-
ensureDir(backupRoot);
|
|
569
|
-
const legacyMemoryDir = join(JAW_HOME, 'memory');
|
|
570
|
-
const backupMemoryDir = join(backupRoot, 'memory');
|
|
571
|
-
if (fs.existsSync(legacyMemoryDir)) {
|
|
572
|
-
fs.rmSync(backupMemoryDir, { recursive: true, force: true });
|
|
573
|
-
fs.cpSync(legacyMemoryDir, backupMemoryDir, { recursive: true });
|
|
574
|
-
}
|
|
575
|
-
const kvRows = getMemory.all();
|
|
576
|
-
writeText(join(backupRoot, 'memory-kv.json'), JSON.stringify(kvRows, null, 2));
|
|
577
|
-
return backupRoot;
|
|
578
|
-
}
|
|
579
|
-
function parseMarkdownFile(raw) {
|
|
580
|
-
const lines = raw.replace(/\r\n/g, '\n').split('\n');
|
|
581
|
-
if (lines[0] !== '---') {
|
|
582
|
-
return { meta: {}, body: raw, bodyStartLine: 1 };
|
|
583
|
-
}
|
|
584
|
-
const closing = lines.findIndex((line, idx) => idx > 0 && line === '---');
|
|
585
|
-
if (closing === -1) {
|
|
586
|
-
return { meta: {}, body: raw, bodyStartLine: 1 };
|
|
587
|
-
}
|
|
588
|
-
const meta = {};
|
|
589
|
-
for (const line of lines.slice(1, closing)) {
|
|
590
|
-
const idx = line.indexOf(':');
|
|
591
|
-
if (idx === -1)
|
|
592
|
-
continue;
|
|
593
|
-
const key = line.slice(0, idx).trim();
|
|
594
|
-
const value = line.slice(idx + 1).trim();
|
|
595
|
-
if (key)
|
|
596
|
-
meta[key] = value;
|
|
597
|
-
}
|
|
598
|
-
return {
|
|
599
|
-
meta,
|
|
600
|
-
body: lines.slice(closing + 1).join('\n'),
|
|
601
|
-
bodyStartLine: closing + 2,
|
|
602
|
-
};
|
|
603
|
-
}
|
|
604
|
-
function buildHeaderPath(stack) {
|
|
605
|
-
return stack.filter(Boolean).join(' > ');
|
|
606
|
-
}
|
|
607
|
-
function chunkMarkdown(absPath, relpath, kind) {
|
|
608
|
-
const raw = safeReadFile(absPath);
|
|
609
|
-
const parsed = parseMarkdownFile(raw);
|
|
610
|
-
const lines = parsed.body.split('\n');
|
|
611
|
-
const chunks = [];
|
|
612
|
-
const headings = [];
|
|
613
|
-
let currentStart = parsed.bodyStartLine;
|
|
614
|
-
let currentBody = [];
|
|
615
|
-
let currentHeader = '';
|
|
616
|
-
const flush = (endLine) => {
|
|
617
|
-
const body = currentBody.join('\n').trim();
|
|
618
|
-
if (!body)
|
|
619
|
-
return;
|
|
620
|
-
const headerPath = buildHeaderPath(headings);
|
|
621
|
-
const prefix = [
|
|
622
|
-
`Source: ${relpath}`,
|
|
623
|
-
`Kind: ${kind}`,
|
|
624
|
-
headerPath ? `Header: ${headerPath}` : '',
|
|
625
|
-
].filter(Boolean).join('\n');
|
|
626
|
-
const content = `${prefix}\n\n${body}`.trim();
|
|
627
|
-
chunks.push({
|
|
628
|
-
relpath,
|
|
629
|
-
path: absPath,
|
|
630
|
-
kind,
|
|
631
|
-
source_start_line: currentStart,
|
|
632
|
-
source_end_line: endLine,
|
|
633
|
-
source_hash: hashText(`${relpath}:${currentStart}:${body}`),
|
|
634
|
-
content,
|
|
635
|
-
});
|
|
636
|
-
};
|
|
637
|
-
for (let idx = 0; idx < lines.length; idx++) {
|
|
638
|
-
const line = lines[idx] ?? '';
|
|
639
|
-
const actualLine = parsed.bodyStartLine + idx;
|
|
640
|
-
const headerMatch = /^(#{1,3})\s+(.+)$/.exec(line.trim());
|
|
641
|
-
if (headerMatch) {
|
|
642
|
-
flush(actualLine - 1);
|
|
643
|
-
const level = headerMatch[1]?.length || 1;
|
|
644
|
-
headings[level - 1] = headerMatch[2]?.trim() || '';
|
|
645
|
-
headings.length = level;
|
|
646
|
-
currentHeader = headerMatch[2]?.trim() || '';
|
|
647
|
-
currentStart = actualLine;
|
|
648
|
-
currentBody = [line];
|
|
649
|
-
continue;
|
|
650
|
-
}
|
|
651
|
-
if (!currentBody.length) {
|
|
652
|
-
currentStart = actualLine;
|
|
653
|
-
currentBody = currentHeader ? [currentHeader, line] : [line];
|
|
654
|
-
}
|
|
655
|
-
else {
|
|
656
|
-
currentBody.push(line);
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
flush(parsed.bodyStartLine + lines.length - 1);
|
|
660
|
-
if (chunks.length === 0 && parsed.body.trim()) {
|
|
661
|
-
chunks.push({
|
|
662
|
-
relpath,
|
|
663
|
-
path: absPath,
|
|
664
|
-
kind,
|
|
665
|
-
source_start_line: parsed.bodyStartLine,
|
|
666
|
-
source_end_line: parsed.bodyStartLine + lines.length - 1,
|
|
667
|
-
source_hash: hashText(`${relpath}:${parsed.body}`),
|
|
668
|
-
content: parsed.body.trim(),
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
|
-
return chunks;
|
|
672
|
-
}
|
|
673
|
-
function getIndexDb() {
|
|
674
|
-
ensureDir(getAdvancedMemoryDir());
|
|
675
|
-
const db = new Database(getAdvancedIndexDbPath());
|
|
676
|
-
db.pragma('journal_mode = WAL');
|
|
677
|
-
db.exec(`
|
|
678
|
-
CREATE TABLE IF NOT EXISTS chunks (
|
|
679
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
680
|
-
path TEXT NOT NULL,
|
|
681
|
-
relpath TEXT NOT NULL,
|
|
682
|
-
kind TEXT NOT NULL,
|
|
683
|
-
home_id TEXT NOT NULL DEFAULT '',
|
|
684
|
-
source_start_line INTEGER NOT NULL,
|
|
685
|
-
source_end_line INTEGER NOT NULL,
|
|
686
|
-
source_hash TEXT NOT NULL,
|
|
687
|
-
content TEXT NOT NULL,
|
|
688
|
-
content_hash TEXT NOT NULL DEFAULT '',
|
|
689
|
-
created_at TEXT NOT NULL DEFAULT ''
|
|
690
|
-
);
|
|
691
|
-
CREATE INDEX IF NOT EXISTS idx_chunks_relpath ON chunks(relpath);
|
|
692
|
-
CREATE INDEX IF NOT EXISTS idx_chunks_path ON chunks(path);
|
|
693
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS chunks_fts USING fts5(
|
|
694
|
-
content,
|
|
695
|
-
relpath UNINDEXED,
|
|
696
|
-
kind UNINDEXED,
|
|
697
|
-
tokenize = 'unicode61'
|
|
698
|
-
);
|
|
699
|
-
`);
|
|
700
|
-
return db;
|
|
701
|
-
}
|
|
702
|
-
function clearIndex(db) {
|
|
703
|
-
db.exec('DELETE FROM chunks;');
|
|
704
|
-
db.exec(`DELETE FROM chunks_fts;`);
|
|
705
|
-
}
|
|
706
|
-
function indexedFiles(root) {
|
|
707
|
-
const buckets = [
|
|
708
|
-
join(root, 'profile.md'),
|
|
709
|
-
...listMarkdownFiles(join(root, 'shared')),
|
|
710
|
-
...listMarkdownFiles(join(root, 'episodes')),
|
|
711
|
-
...listMarkdownFiles(join(root, 'semantic')),
|
|
712
|
-
...listMarkdownFiles(join(root, 'procedures')),
|
|
713
|
-
];
|
|
714
|
-
return buckets.filter((value, idx, arr) => value && arr.indexOf(value) === idx && fs.existsSync(value));
|
|
715
|
-
}
|
|
716
|
-
function kindForFile(root, file) {
|
|
717
|
-
const rel = relative(root, file).replace(/\\/g, '/');
|
|
718
|
-
if (rel === 'profile.md')
|
|
719
|
-
return 'profile';
|
|
720
|
-
if (rel.startsWith('shared/'))
|
|
721
|
-
return 'shared';
|
|
722
|
-
if (rel.startsWith('episodes/'))
|
|
723
|
-
return 'episode';
|
|
724
|
-
if (rel.startsWith('semantic/'))
|
|
725
|
-
return 'semantic';
|
|
726
|
-
if (rel.startsWith('procedures/'))
|
|
727
|
-
return 'procedure';
|
|
728
|
-
return 'memory';
|
|
729
|
-
}
|
|
730
|
-
function reindexAll(root) {
|
|
731
|
-
const db = getIndexDb();
|
|
732
|
-
clearIndex(db);
|
|
733
|
-
const now = new Date().toISOString();
|
|
734
|
-
const homeId = instanceId();
|
|
735
|
-
const insertChunk = db.prepare(`
|
|
736
|
-
INSERT INTO chunks (path, relpath, kind, home_id, source_start_line, source_end_line, source_hash, content, content_hash, created_at)
|
|
737
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
738
|
-
`);
|
|
739
|
-
const insertFts = db.prepare(`
|
|
740
|
-
INSERT INTO chunks_fts (rowid, content, relpath, kind)
|
|
741
|
-
VALUES (?, ?, ?, ?)
|
|
742
|
-
`);
|
|
743
|
-
let totalFiles = 0;
|
|
744
|
-
let totalChunks = 0;
|
|
745
|
-
const tx = db.transaction(() => {
|
|
746
|
-
for (const file of indexedFiles(root)) {
|
|
747
|
-
totalFiles += 1;
|
|
748
|
-
const rel = relative(root, file).replace(/\\/g, '/');
|
|
749
|
-
const kind = kindForFile(root, file);
|
|
750
|
-
for (const chunk of chunkMarkdown(file, rel, kind)) {
|
|
751
|
-
const contentHash = hashText(chunk.content);
|
|
752
|
-
const info = insertChunk.run(chunk.path, chunk.relpath, chunk.kind, homeId, chunk.source_start_line, chunk.source_end_line, chunk.source_hash, chunk.content, contentHash, now);
|
|
753
|
-
insertFts.run(Number(info.lastInsertRowid), chunk.content, chunk.relpath, chunk.kind);
|
|
754
|
-
totalChunks += 1;
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
});
|
|
758
|
-
tx();
|
|
759
|
-
db.close();
|
|
760
|
-
return { totalFiles, totalChunks };
|
|
761
|
-
}
|
|
762
|
-
function reindexSingleFile(root, file) {
|
|
763
|
-
if (!fs.existsSync(file))
|
|
764
|
-
return 0;
|
|
765
|
-
const db = getIndexDb();
|
|
766
|
-
const rel = relative(root, file).replace(/\\/g, '/');
|
|
767
|
-
const kind = kindForFile(root, file);
|
|
768
|
-
const now = new Date().toISOString();
|
|
769
|
-
const homeId = instanceId();
|
|
770
|
-
// Delete existing chunks for this file
|
|
771
|
-
db.prepare('DELETE FROM chunks_fts WHERE rowid IN (SELECT id FROM chunks WHERE relpath = ?)').run(rel);
|
|
772
|
-
db.prepare('DELETE FROM chunks WHERE relpath = ?').run(rel);
|
|
773
|
-
// Re-chunk and insert
|
|
774
|
-
const insertChunk = db.prepare('INSERT INTO chunks (path, relpath, kind, home_id, source_start_line, source_end_line, source_hash, content, content_hash, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
775
|
-
const insertFts = db.prepare('INSERT INTO chunks_fts (rowid, content, relpath, kind) VALUES (?, ?, ?, ?)');
|
|
776
|
-
let count = 0;
|
|
777
|
-
const tx = db.transaction(() => {
|
|
778
|
-
for (const chunk of chunkMarkdown(file, rel, kind)) {
|
|
779
|
-
const contentHash = hashText(chunk.content);
|
|
780
|
-
const info = insertChunk.run(chunk.path, chunk.relpath, chunk.kind, homeId, chunk.source_start_line, chunk.source_end_line, chunk.source_hash, chunk.content, contentHash, now);
|
|
781
|
-
insertFts.run(Number(info.lastInsertRowid), chunk.content, chunk.relpath, chunk.kind);
|
|
782
|
-
count++;
|
|
783
|
-
}
|
|
784
|
-
});
|
|
785
|
-
tx();
|
|
786
|
-
db.close();
|
|
787
|
-
return count;
|
|
788
|
-
}
|
|
789
|
-
export function reindexIntegratedMemoryFile(file) {
|
|
790
|
-
const root = getAdvancedMemoryDir();
|
|
791
|
-
if (!fs.existsSync(file))
|
|
792
|
-
return 0;
|
|
793
|
-
if (!file.startsWith(root))
|
|
794
|
-
return 0;
|
|
795
|
-
return reindexSingleFile(root, file);
|
|
796
|
-
}
|
|
797
|
-
function buildLikeTerm(term) {
|
|
798
|
-
return `%${term.replace(/[%_]/g, (m) => `\\${m}`)}%`;
|
|
799
|
-
}
|
|
800
|
-
function tokenizeQuery(query) {
|
|
801
|
-
const trimmed = String(query || '').trim();
|
|
802
|
-
if (!trimmed)
|
|
803
|
-
return [];
|
|
804
|
-
const tokens = trimmed
|
|
805
|
-
.split(/[\s,]+/)
|
|
806
|
-
.map(t => t.trim())
|
|
807
|
-
.filter(Boolean);
|
|
808
|
-
return Array.from(new Set([trimmed, ...tokens])).slice(0, 8);
|
|
809
|
-
}
|
|
810
|
-
function tokenizeExpandedQuery(query, expanded) {
|
|
811
|
-
if (expanded?.length)
|
|
812
|
-
return sanitizeKeywords([query, ...expanded]).slice(0, 8);
|
|
813
|
-
return tokenizeQuery(query);
|
|
814
|
-
}
|
|
815
|
-
function formatHits(hits) {
|
|
816
|
-
if (!hits.length)
|
|
817
|
-
return '(no results)';
|
|
818
|
-
return hits.map(hit => {
|
|
819
|
-
const loc = `${hit.relpath}:${hit.source_start_line}-${hit.source_end_line}`;
|
|
820
|
-
return `${loc}\n${hit.snippet}`;
|
|
821
|
-
}).join('\n\n---\n\n');
|
|
822
|
-
}
|
|
823
|
-
function searchIndex(query, expanded) {
|
|
824
|
-
const db = getIndexDb();
|
|
825
|
-
const searchTerms = tokenizeExpandedQuery(query, expanded);
|
|
826
|
-
if (!searchTerms.length) {
|
|
827
|
-
db.close();
|
|
828
|
-
return { hits: [] };
|
|
829
|
-
}
|
|
830
|
-
const byPathLine = new Map();
|
|
831
|
-
const ftsStmt = db.prepare(`
|
|
832
|
-
SELECT
|
|
833
|
-
c.path,
|
|
834
|
-
c.relpath,
|
|
835
|
-
c.kind,
|
|
836
|
-
c.source_start_line,
|
|
837
|
-
c.source_end_line,
|
|
838
|
-
c.content,
|
|
839
|
-
bm25(chunks_fts) AS score
|
|
840
|
-
FROM chunks_fts
|
|
841
|
-
JOIN chunks c ON c.id = chunks_fts.rowid
|
|
842
|
-
WHERE chunks_fts MATCH ?
|
|
843
|
-
ORDER BY score
|
|
844
|
-
LIMIT 16
|
|
845
|
-
`);
|
|
846
|
-
const likeStmt = db.prepare(`
|
|
847
|
-
SELECT path, relpath, kind, source_start_line, source_end_line, content
|
|
848
|
-
FROM chunks
|
|
849
|
-
WHERE content LIKE ? ESCAPE '\\'
|
|
850
|
-
ORDER BY relpath ASC, source_start_line ASC
|
|
851
|
-
LIMIT 16
|
|
852
|
-
`);
|
|
853
|
-
for (const term of searchTerms) {
|
|
854
|
-
const ftsQuery = term.split(/\s+/).map(t => `"${t.replace(/"/g, '')}"`).join(' OR ');
|
|
855
|
-
try {
|
|
856
|
-
const rows = ftsStmt.all(ftsQuery);
|
|
857
|
-
for (const row of rows) {
|
|
858
|
-
const key = `${row.relpath}:${row.source_start_line}:${row.source_end_line}`;
|
|
859
|
-
if (!byPathLine.has(key)) {
|
|
860
|
-
byPathLine.set(key, {
|
|
861
|
-
path: row.path,
|
|
862
|
-
relpath: row.relpath,
|
|
863
|
-
kind: row.kind,
|
|
864
|
-
source_start_line: row.source_start_line,
|
|
865
|
-
source_end_line: row.source_end_line,
|
|
866
|
-
snippet: String(row.content || '').slice(0, 700),
|
|
867
|
-
score: Number(row.score || 0),
|
|
868
|
-
});
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
catch {
|
|
873
|
-
// ignore FTS parse issues, fallback to LIKE below
|
|
874
|
-
}
|
|
875
|
-
const likeRows = likeStmt.all(buildLikeTerm(term));
|
|
876
|
-
for (const row of likeRows) {
|
|
877
|
-
const key = `${row.relpath}:${row.source_start_line}:${row.source_end_line}`;
|
|
878
|
-
if (!byPathLine.has(key)) {
|
|
879
|
-
byPathLine.set(key, {
|
|
880
|
-
path: row.path,
|
|
881
|
-
relpath: row.relpath,
|
|
882
|
-
kind: row.kind,
|
|
883
|
-
source_start_line: row.source_start_line,
|
|
884
|
-
source_end_line: row.source_end_line,
|
|
885
|
-
snippet: String(row.content || '').slice(0, 700),
|
|
886
|
-
score: 999,
|
|
887
|
-
});
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
db.close();
|
|
892
|
-
const hits = [...byPathLine.values()]
|
|
893
|
-
.sort((a, b) => a.score - b.score)
|
|
894
|
-
.slice(0, 8);
|
|
895
|
-
return { hits };
|
|
896
|
-
}
|
|
897
|
-
function updateImportedCount(kind, value) {
|
|
898
|
-
const meta = readMeta();
|
|
899
|
-
writeMeta({
|
|
900
|
-
importedCounts: {
|
|
901
|
-
...(meta?.importedCounts || DEFAULT_IMPORTED_COUNTS),
|
|
902
|
-
[kind]: value,
|
|
903
|
-
},
|
|
904
|
-
});
|
|
905
|
-
}
|
|
906
|
-
function isAdvancedShadowEnabled() {
|
|
907
|
-
return fs.existsSync(getMetaPath());
|
|
908
|
-
}
|
|
909
|
-
function importSingleMarkdownFile(root, file) {
|
|
910
|
-
const legacyDir = join(JAW_HOME, 'memory');
|
|
911
|
-
if (!file.startsWith(legacyDir))
|
|
912
|
-
return null;
|
|
913
|
-
const rel = relative(legacyDir, file).replace(/\\/g, '/');
|
|
914
|
-
if (!rel || rel === 'MEMORY.md')
|
|
915
|
-
return null;
|
|
916
|
-
const body = safeReadFile(file);
|
|
917
|
-
const sourceHash = hashText(body);
|
|
918
|
-
const baseName = rel.split('/').pop() || 'memory.md';
|
|
919
|
-
const isDated = /^\d{4}-\d{2}-\d{2}\.md$/.test(baseName);
|
|
920
|
-
const sectionDir = isDated ? 'episodes/imported' : 'semantic/imported';
|
|
921
|
-
const dest = join(root, sectionDir, rel);
|
|
922
|
-
const fm = frontmatter({
|
|
923
|
-
id: `import-${sourceHash}`,
|
|
924
|
-
home_id: instanceId(),
|
|
925
|
-
kind: isDated ? 'episode' : 'semantic',
|
|
926
|
-
source: 'legacy-markdown',
|
|
927
|
-
trust_level: 'high',
|
|
928
|
-
source_relpath: rel,
|
|
929
|
-
source_hash: sourceHash,
|
|
930
|
-
created_at: new Date().toISOString(),
|
|
931
|
-
updated_at: new Date().toISOString(),
|
|
932
|
-
});
|
|
933
|
-
writeText(dest, fm + body.trim() + '\n');
|
|
934
|
-
reindexSingleFile(root, dest);
|
|
935
|
-
return dest;
|
|
936
|
-
}
|
|
937
|
-
export function syncLegacyMarkdownShadowImport(file) {
|
|
938
|
-
if (!isAdvancedShadowEnabled())
|
|
939
|
-
return { ok: false, reason: 'advanced_not_ready' };
|
|
940
|
-
const root = getAdvancedMemoryDir();
|
|
941
|
-
if (file === join(JAW_HOME, 'memory', 'MEMORY.md')) {
|
|
942
|
-
const count = importCoreMemory(root);
|
|
943
|
-
updateImportedCount('core', count);
|
|
944
|
-
if (count > 0)
|
|
945
|
-
reindexSingleFile(root, join(root, 'profile.md'));
|
|
946
|
-
return { ok: true, target: join(root, 'profile.md'), count };
|
|
947
|
-
}
|
|
948
|
-
const target = importSingleMarkdownFile(root, file);
|
|
949
|
-
if (!target)
|
|
950
|
-
return { ok: false, reason: 'not_importable' };
|
|
951
|
-
updateImportedCount('markdown', countMarkdownFiles(join(root, 'semantic')) + countMarkdownFiles(join(root, 'episodes')));
|
|
952
|
-
return { ok: true, target, count: 1 };
|
|
953
|
-
}
|
|
954
|
-
export function syncKvShadowImport() {
|
|
955
|
-
if (!isAdvancedShadowEnabled())
|
|
956
|
-
return { ok: false, reason: 'advanced_not_ready' };
|
|
957
|
-
const root = getAdvancedMemoryDir();
|
|
958
|
-
const count = importKvMemory(root);
|
|
959
|
-
updateImportedCount('kv', count);
|
|
960
|
-
reindexSingleFile(root, join(root, 'semantic', 'kv-imported.md'));
|
|
961
|
-
return { ok: true, target: join(root, 'semantic', 'kv-imported.md'), count };
|
|
962
|
-
}
|
|
963
|
-
export function ensureAdvancedMemoryStructure() {
|
|
964
|
-
const root = getAdvancedMemoryDir();
|
|
965
|
-
return withMigrationLock(() => {
|
|
966
|
-
const sharedDir = join(root, 'shared');
|
|
967
|
-
const episodesDir = join(root, 'episodes');
|
|
968
|
-
const semanticDir = join(root, 'semantic');
|
|
969
|
-
const proceduresDir = join(root, 'procedures');
|
|
970
|
-
const sessionsDir = join(root, 'sessions');
|
|
971
|
-
const corruptedDir = join(root, 'corrupted');
|
|
972
|
-
const unmappedDir = join(root, 'legacy-unmapped');
|
|
973
|
-
migrateLegacyAdvancedRoot(root);
|
|
974
|
-
ensureDir(root);
|
|
975
|
-
ensureDir(sharedDir);
|
|
976
|
-
ensureDir(episodesDir);
|
|
977
|
-
ensureDir(semanticDir);
|
|
978
|
-
ensureDir(proceduresDir);
|
|
979
|
-
ensureDir(sessionsDir);
|
|
980
|
-
ensureDir(corruptedDir);
|
|
981
|
-
ensureDir(unmappedDir);
|
|
982
|
-
writeMeta({
|
|
983
|
-
schemaVersion: 1,
|
|
984
|
-
phase: '10',
|
|
985
|
-
homeId: instanceId(),
|
|
986
|
-
jawHome: JAW_HOME,
|
|
987
|
-
initializedAt: readMeta()?.initializedAt || new Date().toISOString(),
|
|
988
|
-
migrationVersion: 1,
|
|
989
|
-
migrationState: 'done',
|
|
990
|
-
migratedAt: readMeta()?.migratedAt || new Date().toISOString(),
|
|
991
|
-
sourceLayout: fs.existsSync(getLegacyAdvancedMemoryDir()) ? 'advanced' : 'legacy',
|
|
992
|
-
});
|
|
993
|
-
const profilePath = join(root, 'profile.md');
|
|
994
|
-
if (!fs.existsSync(profilePath)) {
|
|
995
|
-
const fm = frontmatter({
|
|
996
|
-
id: `profile-${instanceId()}`,
|
|
997
|
-
home_id: instanceId(),
|
|
998
|
-
kind: 'profile',
|
|
999
|
-
source: 'generated',
|
|
1000
|
-
trust_level: 'high',
|
|
1001
|
-
created_at: new Date().toISOString(),
|
|
1002
|
-
updated_at: new Date().toISOString(),
|
|
1003
|
-
});
|
|
1004
|
-
writeText(profilePath, fm + `# Profile
|
|
1005
|
-
|
|
1006
|
-
## User Preferences
|
|
1007
|
-
|
|
1008
|
-
## Key Decisions
|
|
1009
|
-
|
|
1010
|
-
## Active Projects
|
|
1011
|
-
`);
|
|
1012
|
-
}
|
|
1013
|
-
return { root, metaPath: getMetaPath(), profilePath };
|
|
1014
|
-
});
|
|
1015
|
-
}
|
|
1016
|
-
export function bootstrapAdvancedMemory(options = {}) {
|
|
1017
|
-
const root = getAdvancedMemoryDir();
|
|
1018
|
-
ensureAdvancedMemoryStructure();
|
|
1019
|
-
writeMeta({
|
|
1020
|
-
phase: '10',
|
|
1021
|
-
bootstrapStatus: 'running',
|
|
1022
|
-
lastBootstrapAt: new Date().toISOString(),
|
|
1023
|
-
lastError: '',
|
|
1024
|
-
});
|
|
1025
|
-
const resolved = {
|
|
1026
|
-
importCore: options.importCore !== false,
|
|
1027
|
-
importMarkdown: options.importMarkdown !== false,
|
|
1028
|
-
importKv: options.importKv !== false,
|
|
1029
|
-
importClaudeSession: options.importClaudeSession !== false,
|
|
1030
|
-
};
|
|
1031
|
-
try {
|
|
1032
|
-
const backupRoot = backupLegacyMemory();
|
|
1033
|
-
const counts = {
|
|
1034
|
-
core: resolved.importCore ? importCoreMemory(root) : 0,
|
|
1035
|
-
markdown: resolved.importMarkdown ? importMarkdownMemory(root) : 0,
|
|
1036
|
-
kv: resolved.importKv ? importKvMemory(root) : 0,
|
|
1037
|
-
claude: resolved.importClaudeSession ? importClaudeSessionMemory(root) : 0,
|
|
1038
|
-
};
|
|
1039
|
-
const { totalFiles, totalChunks } = reindexAll(root);
|
|
1040
|
-
const meta = writeMeta({
|
|
1041
|
-
phase: '10',
|
|
1042
|
-
bootstrapStatus: 'done',
|
|
1043
|
-
importedCounts: counts,
|
|
1044
|
-
lastBootstrapAt: new Date().toISOString(),
|
|
1045
|
-
lastError: '',
|
|
1046
|
-
});
|
|
1047
|
-
return { root, backupRoot, counts, indexed: { totalFiles, totalChunks }, meta };
|
|
1048
|
-
}
|
|
1049
|
-
catch (err) {
|
|
1050
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1051
|
-
writeMeta({
|
|
1052
|
-
phase: '10',
|
|
1053
|
-
bootstrapStatus: 'failed',
|
|
1054
|
-
lastBootstrapAt: new Date().toISOString(),
|
|
1055
|
-
lastError: message,
|
|
1056
|
-
});
|
|
1057
|
-
throw err;
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
export function ensureIntegratedMemoryReady() {
|
|
1061
|
-
const created = ensureAdvancedMemoryStructure();
|
|
1062
|
-
const status = getAdvancedMemoryStatus();
|
|
1063
|
-
if (status.indexState === 'ready')
|
|
1064
|
-
return { created, bootstrapped: false, status };
|
|
1065
|
-
const hasLegacy = fs.existsSync(join(JAW_HOME, 'memory', 'MEMORY.md'))
|
|
1066
|
-
|| fs.existsSync(join(JAW_HOME, 'memory', 'daily'))
|
|
1067
|
-
|| fs.existsSync(getLegacyClaudeMemoryDir())
|
|
1068
|
-
|| getMemory.all().length > 0
|
|
1069
|
-
|| fs.existsSync(getLegacyAdvancedMemoryDir());
|
|
1070
|
-
if (!hasLegacy) {
|
|
1071
|
-
const result = reindexAdvancedMemory();
|
|
1072
|
-
return { created, bootstrapped: false, status: getAdvancedMemoryStatus(), result };
|
|
1073
|
-
}
|
|
1074
|
-
const result = bootstrapAdvancedMemory({
|
|
1075
|
-
importCore: true,
|
|
1076
|
-
importMarkdown: true,
|
|
1077
|
-
importKv: true,
|
|
1078
|
-
importClaudeSession: true,
|
|
1079
|
-
});
|
|
1080
|
-
return { created, bootstrapped: true, status: getAdvancedMemoryStatus(), result };
|
|
1081
|
-
}
|
|
6
|
+
// Re-export everything from sub-modules for backward compatibility
|
|
7
|
+
export { DEFAULT_IMPORTED_COUNTS, getAdvancedMemoryDir, getAdvancedMemoryBackupDir, getAdvancedFlushFilePath, getAdvancedIndexDbPath, getLegacyAdvancedMemoryDir, ensureDir, safeReadFile, writeText, frontmatter, hashText, sanitizeKeywords, listMarkdownFiles, countMarkdownFiles, countFiles, readMeta, writeMeta, } from './shared.js';
|
|
8
|
+
export { normalizeOpenAiCompatibleBaseUrl, expandSearchKeywords, validateAdvancedMemoryConfig, getLastExpansionTerms, } from './keyword-expand.js';
|
|
9
|
+
export { reindexAll, reindexSingleFile, reindexIntegratedMemoryFile, searchIndex, formatHits, reindexIndexCounts, getIndexDb, indexedFiles, } from './indexing.js';
|
|
10
|
+
export { syncLegacyMarkdownShadowImport, syncKvShadowImport, ensureAdvancedMemoryStructure, bootstrapAdvancedMemory, } from './bootstrap.js';
|
|
11
|
+
import { getAdvancedMemoryDir, getAdvancedMemoryBackupDir, getAdvancedIndexDbPath, getLegacyAdvancedMemoryDir, safeReadFile, listMarkdownFiles, countFiles, readMeta, } from './shared.js';
|
|
12
|
+
import { getLastExpansionTerms } from './keyword-expand.js';
|
|
13
|
+
import { reindexAll, searchIndex, formatHits, reindexIndexCounts } from './indexing.js';
|
|
14
|
+
import { ensureAdvancedMemoryStructure, bootstrapAdvancedMemory } from './bootstrap.js';
|
|
15
|
+
// ---------- Public API ----------
|
|
1082
16
|
export function reindexAdvancedMemory() {
|
|
1083
17
|
const root = getAdvancedMemoryDir();
|
|
1084
18
|
ensureAdvancedMemoryStructure();
|
|
@@ -1109,15 +43,24 @@ export function searchAdvancedMemory(query) {
|
|
|
1109
43
|
const { hits } = searchIndex(baseQuery, expanded);
|
|
1110
44
|
return formatHits(hits);
|
|
1111
45
|
}
|
|
46
|
+
function parseMarkdownFileLight(raw) {
|
|
47
|
+
const lines = raw.replace(/\r\n/g, '\n').split('\n');
|
|
48
|
+
if (lines[0] !== '---')
|
|
49
|
+
return { body: raw };
|
|
50
|
+
const closing = lines.findIndex((line, idx) => idx > 0 && line === '---');
|
|
51
|
+
if (closing === -1)
|
|
52
|
+
return { body: raw };
|
|
53
|
+
return { body: lines.slice(closing + 1).join('\n') };
|
|
54
|
+
}
|
|
1112
55
|
export function loadAdvancedProfileSummary(maxChars = 800) {
|
|
1113
56
|
const file = join(getAdvancedMemoryDir(), 'profile.md');
|
|
1114
57
|
if (!fs.existsSync(file))
|
|
1115
58
|
return '';
|
|
1116
|
-
const
|
|
1117
|
-
const
|
|
1118
|
-
if (!
|
|
59
|
+
const { body } = parseMarkdownFileLight(safeReadFile(file));
|
|
60
|
+
const trimmed = body.trim();
|
|
61
|
+
if (!trimmed)
|
|
1119
62
|
return '';
|
|
1120
|
-
return
|
|
63
|
+
return trimmed.length > maxChars ? trimmed.slice(0, maxChars) + '\n...(truncated)' : trimmed;
|
|
1121
64
|
}
|
|
1122
65
|
export function buildTaskSnapshot(query, budget = 2800, expanded) {
|
|
1123
66
|
const terms = Array.isArray(query)
|
|
@@ -1194,18 +137,41 @@ export function getAdvancedMemoryStatus() {
|
|
|
1194
137
|
lastIndexedAt: fs.existsSync(dbPath) ? fs.statSync(dbPath).mtime.toISOString() : null,
|
|
1195
138
|
importStatus: meta?.bootstrapStatus || (initialized ? 'idle' : 'not_started'),
|
|
1196
139
|
corruptedCount: countFiles(corruptedDir),
|
|
1197
|
-
lastExpansion:
|
|
140
|
+
lastExpansion: getLastExpansionTerms(),
|
|
1198
141
|
lastError: meta?.lastError || '',
|
|
1199
|
-
importedCounts: meta?.importedCounts || {
|
|
142
|
+
importedCounts: meta?.importedCounts || { core: 0, markdown: 0, kv: 0, claude: 0 },
|
|
1200
143
|
backupRoot: getAdvancedMemoryBackupDir(),
|
|
1201
144
|
};
|
|
1202
145
|
}
|
|
1203
|
-
function
|
|
1204
|
-
const
|
|
1205
|
-
const
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
146
|
+
function getLegacyClaudeMemoryDir() {
|
|
147
|
+
const wd = (settings.workingDir || os.homedir()).replace(/^~/, os.homedir());
|
|
148
|
+
const hash = wd.replace(/\//g, '-');
|
|
149
|
+
return join(os.homedir(), '.claude', 'projects', hash, 'memory');
|
|
150
|
+
}
|
|
151
|
+
export function ensureIntegratedMemoryReady() {
|
|
152
|
+
const created = ensureAdvancedMemoryStructure();
|
|
153
|
+
const status = getAdvancedMemoryStatus();
|
|
154
|
+
if (status.indexState === 'ready')
|
|
155
|
+
return { created, bootstrapped: false, status };
|
|
156
|
+
const hasLegacy = fs.existsSync(join(JAW_HOME, 'memory', 'MEMORY.md'))
|
|
157
|
+
|| fs.existsSync(join(JAW_HOME, 'memory', 'daily'))
|
|
158
|
+
|| fs.existsSync(getLegacyClaudeMemoryDir())
|
|
159
|
+
|| getMemory.all().length > 0
|
|
160
|
+
|| fs.existsSync(getLegacyAdvancedMemoryDir());
|
|
161
|
+
if (!hasLegacy) {
|
|
162
|
+
const result = reindexAll(getAdvancedMemoryDir());
|
|
163
|
+
return { created, bootstrapped: false, status: getAdvancedMemoryStatus(), result };
|
|
164
|
+
}
|
|
165
|
+
const result = bootstrapAdvancedMemory({
|
|
166
|
+
importCore: true,
|
|
167
|
+
importMarkdown: true,
|
|
168
|
+
importKv: true,
|
|
169
|
+
importClaudeSession: true,
|
|
170
|
+
});
|
|
171
|
+
return { created, bootstrapped: true, status: getAdvancedMemoryStatus(), result };
|
|
1209
172
|
}
|
|
1210
|
-
|
|
173
|
+
// ---------- Backward-compat aliases ----------
|
|
174
|
+
export { getAdvancedMemoryDir as getStructuredMemoryDir, getAdvancedMemoryBackupDir as getMemoryBackupDir, getAdvancedFlushFilePath as getMemoryFlushFilePath, } from './shared.js';
|
|
175
|
+
export { ensureAdvancedMemoryStructure as ensureMemoryStructure, bootstrapAdvancedMemory as bootstrapMemory, } from './bootstrap.js';
|
|
176
|
+
export { ensureIntegratedMemoryReady as ensureMemoryRuntimeReady, reindexAdvancedMemory as reindexMemory, listAdvancedMemoryFiles as listMemoryFiles, searchAdvancedMemory as searchIndexedMemory, readAdvancedMemorySnippet as readIndexedMemorySnippet, getAdvancedMemoryStatus as getMemoryStatus, loadAdvancedProfileSummary as loadProfileSummary, };
|
|
1211
177
|
//# sourceMappingURL=runtime.js.map
|