@deepseek-insight/dsi 0.5.5
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 +204 -0
- package/README.md +98 -0
- package/bin/dsi.mjs +147 -0
- package/build/client/_app/immutable/assets/0.DqFt8jIM.css +2 -0
- package/build/client/_app/immutable/assets/2.YlW45hiM.css +1 -0
- package/build/client/_app/immutable/assets/codicon.Brq4_Ui5.ttf +0 -0
- package/build/client/_app/immutable/assets/editor.jjEx9u7D.css +1 -0
- package/build/client/_app/immutable/assets/settings-monaco.C1CMdMvw.css +1 -0
- package/build/client/_app/immutable/chunks/-g7BcI22.js +4 -0
- package/build/client/_app/immutable/chunks/08VXUWAP.js +1 -0
- package/build/client/_app/immutable/chunks/2irkVCIh.js +10 -0
- package/build/client/_app/immutable/chunks/43DmfD33.js +1 -0
- package/build/client/_app/immutable/chunks/6GKQw8m6.js +99 -0
- package/build/client/_app/immutable/chunks/6RTg0lbw.js +1 -0
- package/build/client/_app/immutable/chunks/9TvT6fta.js +120 -0
- package/build/client/_app/immutable/chunks/B1YSaoU7.js +96 -0
- package/build/client/_app/immutable/chunks/B2J2w5EN.js +1 -0
- package/build/client/_app/immutable/chunks/B5-_aFwp.js +2 -0
- package/build/client/_app/immutable/chunks/B8-Q2PIv.js +1 -0
- package/build/client/_app/immutable/chunks/B8J7ngcE.js +1 -0
- package/build/client/_app/immutable/chunks/B9JPFI3C.js +2 -0
- package/build/client/_app/immutable/chunks/BAZKJuQw.js +1 -0
- package/build/client/_app/immutable/chunks/BBKpNcUe.js +1 -0
- package/build/client/_app/immutable/chunks/BEEn4gHE.js +1 -0
- package/build/client/_app/immutable/chunks/BEtHBSE6.js +1 -0
- package/build/client/_app/immutable/chunks/BFoDCU3G.js +1 -0
- package/build/client/_app/immutable/chunks/BHtPwB2y.js +847 -0
- package/build/client/_app/immutable/chunks/BI-MrBd-.js +1 -0
- package/build/client/_app/immutable/chunks/BI4pMaIG.js +1 -0
- package/build/client/_app/immutable/chunks/BJL7RCQE.js +4 -0
- package/build/client/_app/immutable/chunks/BKxtCVv1.js +1 -0
- package/build/client/_app/immutable/chunks/BOfSXrr7.js +1 -0
- package/build/client/_app/immutable/chunks/BOotOW0E.js +1 -0
- package/build/client/_app/immutable/chunks/BTzV9O1M.js +3 -0
- package/build/client/_app/immutable/chunks/BW-FRVGs.js +1 -0
- package/build/client/_app/immutable/chunks/BWPQTe0t.js +1 -0
- package/build/client/_app/immutable/chunks/BYgofb2h.js +1 -0
- package/build/client/_app/immutable/chunks/Ba7i2nA0.js +1 -0
- package/build/client/_app/immutable/chunks/Bb19NAkg.js +1 -0
- package/build/client/_app/immutable/chunks/Bc_sGQ0U.js +1 -0
- package/build/client/_app/immutable/chunks/BeGwcela.js +1 -0
- package/build/client/_app/immutable/chunks/BeZqd5lB.js +1 -0
- package/build/client/_app/immutable/chunks/Beo7Z46k.js +7 -0
- package/build/client/_app/immutable/chunks/BhNEBkk_.js +39 -0
- package/build/client/_app/immutable/chunks/BifhSqXX.js +1 -0
- package/build/client/_app/immutable/chunks/Bjy-W4x2.js +81 -0
- package/build/client/_app/immutable/chunks/BlltJnm0.js +1 -0
- package/build/client/_app/immutable/chunks/Bn9NRi0R.js +168 -0
- package/build/client/_app/immutable/chunks/BnF5Jm-h.js +1 -0
- package/build/client/_app/immutable/chunks/Bp4uuUjI.js +3 -0
- package/build/client/_app/immutable/chunks/BrTsmS-o.js +57 -0
- package/build/client/_app/immutable/chunks/Bri6UV-V.js +1 -0
- package/build/client/_app/immutable/chunks/Btk-1DaX.js +1 -0
- package/build/client/_app/immutable/chunks/BwWrilGY.js +1 -0
- package/build/client/_app/immutable/chunks/Bxkupp3x.js +1 -0
- package/build/client/_app/immutable/chunks/Bz4Y3fRF.js +1 -0
- package/build/client/_app/immutable/chunks/C-OQMol4.js +1 -0
- package/build/client/_app/immutable/chunks/C-y9NEjX.js +1 -0
- package/build/client/_app/immutable/chunks/C1JXY9b5.js +30 -0
- package/build/client/_app/immutable/chunks/C2x7inlt.js +321 -0
- package/build/client/_app/immutable/chunks/C531GsRP.js +2 -0
- package/build/client/_app/immutable/chunks/C5TAQhFO.js +1 -0
- package/build/client/_app/immutable/chunks/C5_-GSwl.js +1 -0
- package/build/client/_app/immutable/chunks/C6lv30UQ.js +1 -0
- package/build/client/_app/immutable/chunks/C7h46wYY.js +1 -0
- package/build/client/_app/immutable/chunks/C8Ef5oNN.js +1 -0
- package/build/client/_app/immutable/chunks/CA_WNCsl.js +41 -0
- package/build/client/_app/immutable/chunks/CC2rA5mh.js +1 -0
- package/build/client/_app/immutable/chunks/CHdTS7qa.js +15 -0
- package/build/client/_app/immutable/chunks/CIPQ_RoX.js +1 -0
- package/build/client/_app/immutable/chunks/CJ_zvTBg.js +72 -0
- package/build/client/_app/immutable/chunks/CPEyWost.js +1 -0
- package/build/client/_app/immutable/chunks/CPgSxomx.js +1 -0
- package/build/client/_app/immutable/chunks/CRfGWb83.js +1 -0
- package/build/client/_app/immutable/chunks/CTgm3pse.js +1 -0
- package/build/client/_app/immutable/chunks/CVaqCwHa.js +1 -0
- package/build/client/_app/immutable/chunks/CWKM3f5q.js +1 -0
- package/build/client/_app/immutable/chunks/CWVpRRWx.js +162 -0
- package/build/client/_app/immutable/chunks/CXMH3UgJ.js +257 -0
- package/build/client/_app/immutable/chunks/CZ-RNlot.js +1 -0
- package/build/client/_app/immutable/chunks/CZXl7qUb.js +70 -0
- package/build/client/_app/immutable/chunks/C_N-eONP.js +1 -0
- package/build/client/_app/immutable/chunks/Cb1pwoev.js +1 -0
- package/build/client/_app/immutable/chunks/CcL1k2On.js +11 -0
- package/build/client/_app/immutable/chunks/CcWV7GYH.js +1 -0
- package/build/client/_app/immutable/chunks/CcwsVR0C.js +1 -0
- package/build/client/_app/immutable/chunks/Cd6K7Y8m.js +1 -0
- package/build/client/_app/immutable/chunks/CfSJPG6W.js +1 -0
- package/build/client/_app/immutable/chunks/CfZ7uSQe.js +38 -0
- package/build/client/_app/immutable/chunks/Cimd5fb3.js +1 -0
- package/build/client/_app/immutable/chunks/Cj-Zm41R.js +36 -0
- package/build/client/_app/immutable/chunks/CjZ_QSbm.js +1 -0
- package/build/client/_app/immutable/chunks/CkrcOjFY.js +1 -0
- package/build/client/_app/immutable/chunks/ClamHrr6.js +1 -0
- package/build/client/_app/immutable/chunks/Cm7r79vr.js +1 -0
- package/build/client/_app/immutable/chunks/CmbEK4CY.js +84 -0
- package/build/client/_app/immutable/chunks/CmvnEPtD.js +7 -0
- package/build/client/_app/immutable/chunks/CopQ2nXW.js +1 -0
- package/build/client/_app/immutable/chunks/CpzslTdj.js +1 -0
- package/build/client/_app/immutable/chunks/CsHVnZCH.js +1 -0
- package/build/client/_app/immutable/chunks/CsQS60Ue.js +1 -0
- package/build/client/_app/immutable/chunks/CuRJVwEq.js +1 -0
- package/build/client/_app/immutable/chunks/D-oSqn_W.js +1 -0
- package/build/client/_app/immutable/chunks/D-ptJ9y-.js +1 -0
- package/build/client/_app/immutable/chunks/D05T4iGw.js +1 -0
- package/build/client/_app/immutable/chunks/D0I62FkS.js +1 -0
- package/build/client/_app/immutable/chunks/D16vkywU.js +1 -0
- package/build/client/_app/immutable/chunks/D1qzYj9m.js +1 -0
- package/build/client/_app/immutable/chunks/D3hlyOfw.js +1 -0
- package/build/client/_app/immutable/chunks/D4gq_dik.js +1 -0
- package/build/client/_app/immutable/chunks/D7fX-3xy.js +1 -0
- package/build/client/_app/immutable/chunks/D8-5qLJg.js +231 -0
- package/build/client/_app/immutable/chunks/D8hlhfM3.js +1 -0
- package/build/client/_app/immutable/chunks/DAS1CLuE.js +24 -0
- package/build/client/_app/immutable/chunks/DGarjVZC.js +1 -0
- package/build/client/_app/immutable/chunks/DGd2pJF5.js +1 -0
- package/build/client/_app/immutable/chunks/DHpiXF5c.js +1 -0
- package/build/client/_app/immutable/chunks/DHwB1DNv.js +161 -0
- package/build/client/_app/immutable/chunks/DIMkf-bt.js +3 -0
- package/build/client/_app/immutable/chunks/DISqw1ZD.js +1 -0
- package/build/client/_app/immutable/chunks/DITEY8D_.js +62 -0
- package/build/client/_app/immutable/chunks/DL0yNkAA.js +1 -0
- package/build/client/_app/immutable/chunks/DL1Hc2zs.js +1 -0
- package/build/client/_app/immutable/chunks/DLOOos_8.js +292 -0
- package/build/client/_app/immutable/chunks/DMUM7wLl.js +1 -0
- package/build/client/_app/immutable/chunks/DPKol_4Z.js +139 -0
- package/build/client/_app/immutable/chunks/DS17s2tU.js +1 -0
- package/build/client/_app/immutable/chunks/DT7zqm-g.js +1 -0
- package/build/client/_app/immutable/chunks/DTj74zXo.js +1 -0
- package/build/client/_app/immutable/chunks/DV3o63ZY.js +1 -0
- package/build/client/_app/immutable/chunks/DVXVVWkX.js +129 -0
- package/build/client/_app/immutable/chunks/DWDfcLfy.js +206 -0
- package/build/client/_app/immutable/chunks/DXeGLmed.js +8 -0
- package/build/client/_app/immutable/chunks/DYqsupvX.js +1 -0
- package/build/client/_app/immutable/chunks/DZ6u0Z-K.js +1 -0
- package/build/client/_app/immutable/chunks/DZFCIeNp.js +1 -0
- package/build/client/_app/immutable/chunks/D_Lu-MrJ.js +1 -0
- package/build/client/_app/immutable/chunks/DauUninz.js +1 -0
- package/build/client/_app/immutable/chunks/DbInun42.js +1 -0
- package/build/client/_app/immutable/chunks/DbcKN35_.js +3 -0
- package/build/client/_app/immutable/chunks/DcZe4Woe.js +1 -0
- package/build/client/_app/immutable/chunks/DdL9SqIa.js +1 -0
- package/build/client/_app/immutable/chunks/De2hgUGE.js +1 -0
- package/build/client/_app/immutable/chunks/DezsRK8O.js +1 -0
- package/build/client/_app/immutable/chunks/Dg_UWGX7.js +24 -0
- package/build/client/_app/immutable/chunks/Dj2t5yNg.js +1 -0
- package/build/client/_app/immutable/chunks/DkqhCAOL.js +1 -0
- package/build/client/_app/immutable/chunks/DlQrSOw4.js +7 -0
- package/build/client/_app/immutable/chunks/DmHpPYUd.js +1 -0
- package/build/client/_app/immutable/chunks/Dmn-tsie.js +1 -0
- package/build/client/_app/immutable/chunks/DpFanUEy.js +298 -0
- package/build/client/_app/immutable/chunks/DqwfDHZH.js +89 -0
- package/build/client/_app/immutable/chunks/Dr0pcX_F.js +1 -0
- package/build/client/_app/immutable/chunks/DrH0SRf2.js +1 -0
- package/build/client/_app/immutable/chunks/DsF7k-Jl.js +1 -0
- package/build/client/_app/immutable/chunks/DtBGId5S.js +2 -0
- package/build/client/_app/immutable/chunks/DuM1hSCa.js +1 -0
- package/build/client/_app/immutable/chunks/Du_ODUAO.js +1 -0
- package/build/client/_app/immutable/chunks/DvCMcJ3P.js +1 -0
- package/build/client/_app/immutable/chunks/Dy-Kn_BL.js +1 -0
- package/build/client/_app/immutable/chunks/DzVMo6mB.js +62 -0
- package/build/client/_app/immutable/chunks/ESmLJICu.js +1 -0
- package/build/client/_app/immutable/chunks/FvmIjYaQ.js +1 -0
- package/build/client/_app/immutable/chunks/GBaNblmo.js +1 -0
- package/build/client/_app/immutable/chunks/HclGiUj8.js +1 -0
- package/build/client/_app/immutable/chunks/Ju5jF6hy.js +1 -0
- package/build/client/_app/immutable/chunks/KythIMN8.js +1 -0
- package/build/client/_app/immutable/chunks/LWre5GKl.js +40 -0
- package/build/client/_app/immutable/chunks/NEE52Syq.js +1 -0
- package/build/client/_app/immutable/chunks/No6lfiAw.js +1 -0
- package/build/client/_app/immutable/chunks/OmE6SGvs.js +106 -0
- package/build/client/_app/immutable/chunks/P_ok0Z_j.js +2 -0
- package/build/client/_app/immutable/chunks/PaZBB01u.js +1 -0
- package/build/client/_app/immutable/chunks/Rh9cy7xg.js +2 -0
- package/build/client/_app/immutable/chunks/SOo6toE5.js +1 -0
- package/build/client/_app/immutable/chunks/TNLUqJaC.js +1 -0
- package/build/client/_app/immutable/chunks/UNxFjlik.js +1 -0
- package/build/client/_app/immutable/chunks/UmdltqoE.js +1 -0
- package/build/client/_app/immutable/chunks/Z5eAx3Zn.js +1 -0
- package/build/client/_app/immutable/chunks/bTuwJoIa.js +1 -0
- package/build/client/_app/immutable/chunks/fmXr3nnJ.js +1 -0
- package/build/client/_app/immutable/chunks/fybaL0A-.js +1 -0
- package/build/client/_app/immutable/chunks/gp-XZpBa.js +3 -0
- package/build/client/_app/immutable/chunks/h-p5ZdY8.js +1 -0
- package/build/client/_app/immutable/chunks/hxYEUgOo.js +1 -0
- package/build/client/_app/immutable/chunks/i0VQdJtv.js +1 -0
- package/build/client/_app/immutable/chunks/i0X4ZdIN.js +1 -0
- package/build/client/_app/immutable/chunks/mVHw7KEX.js +7 -0
- package/build/client/_app/immutable/chunks/nDMCpPkF.js +1 -0
- package/build/client/_app/immutable/chunks/nr791fC2.js +1 -0
- package/build/client/_app/immutable/chunks/onAF5SnQ.js +1 -0
- package/build/client/_app/immutable/chunks/oz_6vUea.js +1 -0
- package/build/client/_app/immutable/chunks/qEGLx2Wc.js +78 -0
- package/build/client/_app/immutable/chunks/raVGrKQy.js +44 -0
- package/build/client/_app/immutable/chunks/sBoK_t0W.js +1 -0
- package/build/client/_app/immutable/chunks/sIEmSkn6.js +34 -0
- package/build/client/_app/immutable/chunks/wFIeY1Cf.js +88 -0
- package/build/client/_app/immutable/chunks/xihTtKlq.js +1 -0
- package/build/client/_app/immutable/chunks/zpcgJjUg.js +127 -0
- package/build/client/_app/immutable/entry/app.B2QxMn0t.js +2 -0
- package/build/client/_app/immutable/entry/start.BR3A4iFi.js +1 -0
- package/build/client/_app/immutable/nodes/0.B_ZEZy7b.js +1 -0
- package/build/client/_app/immutable/nodes/1.By3Gd2cs.js +1 -0
- package/build/client/_app/immutable/nodes/2.1TAwiWw1.js +69 -0
- package/build/client/_app/immutable/workers/css.worker-DRH2OcAG.js +93 -0
- package/build/client/_app/immutable/workers/html.worker-DQLddT9h.js +506 -0
- package/build/client/_app/immutable/workers/json.worker-D_Dqrls5.js +62 -0
- package/build/client/_app/immutable/workers/settings-editor-worker-D9zwrD0f.js +30 -0
- package/build/client/_app/immutable/workers/ts.worker-DkYoA6bF.js +67738 -0
- package/build/client/_app/immutable/workers/yaml.worker-BTGFEDOA.js +449 -0
- package/build/client/_app/version.json +1 -0
- package/build/client/favicon.svg +7 -0
- package/build/env.js +70 -0
- package/build/handler.js +23 -0
- package/build/index.js +146 -0
- package/build/server/chunks/chunks/a2a-protocol.js-C77mVg2Q.js +52 -0
- package/build/server/chunks/chunks/app-config.svelte.js-Co9jacqT.js +52 -0
- package/build/server/chunks/chunks/config.js-BBYogCe7.js +123 -0
- package/build/server/chunks/chunks/db.js-DcmO3JAx.js +120 -0
- package/build/server/chunks/chunks/db2.js-DBltVUGg.js +717 -0
- package/build/server/chunks/chunks/dsh-connection.js-DwihVtk_.js +1957 -0
- package/build/server/chunks/chunks/dsh-events.js-BtDxaV6Q.js +706 -0
- package/build/server/chunks/chunks/env.js-l0sNRNKZ.js +2 -0
- package/build/server/chunks/chunks/exports.js-DMiPee3x.js +263 -0
- package/build/server/chunks/chunks/goal-projection.js-0_34t60K.js +44 -0
- package/build/server/chunks/chunks/image-limits.js-BMPZ55kJ.js +186 -0
- package/build/server/chunks/chunks/insight-config.js-CfMPTA6Z.js +352 -0
- package/build/server/chunks/chunks/internal.js-CQzEjdyk.js +747 -0
- package/build/server/chunks/chunks/internal2.js-D-DAuSVh.js +22 -0
- package/build/server/chunks/chunks/server.js-DoCd0fEo.js +4104 -0
- package/build/server/chunks/chunks/shared.js-C4-Py8s_.js +775 -0
- package/build/server/chunks/chunks/state.js-CpmOS0a2.js +114 -0
- package/build/server/chunks/chunks/uneval.js-BJ9Qq2SF.js +488 -0
- package/build/server/chunks/chunks/utils.js-tOWCe9Wk.js +933 -0
- package/build/server/chunks/chunks/watcher.js-BelxjMOP.js +473 -0
- package/build/server/chunks/entries/endpoints/api/a2a/_id_/_server.ts.js-B4HUNFZv.js +37 -0
- package/build/server/chunks/entries/endpoints/api/a2a/_server.ts.js-JDV_oqbX.js +61 -0
- package/build/server/chunks/entries/endpoints/api/a2a/register/_server.ts.js-Dxwc-7-5.js +99 -0
- package/build/server/chunks/entries/endpoints/api/config/_server.ts.js-D8i35bGH.js +35 -0
- package/build/server/chunks/entries/endpoints/api/dsh/directory/_server.ts.js-CeBU1G85.js +43 -0
- package/build/server/chunks/entries/endpoints/api/dsh/pick-directory/_server.ts.js-CyrVUxv3.js +36 -0
- package/build/server/chunks/entries/endpoints/api/dsh/presets/_server.ts.js-qeO_1htT.js +33 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/attachment/_server.ts.js-DnHffohz.js +44 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/cancel/_server.ts.js-fm6MFyjP.js +33 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/catalog/_server.ts.js-wJ9V_Ue7.js +42 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/command/_server.ts.js-o83L4GUY.js +85 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/events/_server.ts.js-DLCHSC1M.js +212 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/fork/_server.ts.js-Ca6NU9HO.js +58 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/goal/_server.ts.js-RteR85vn.js +138 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/history/_server.ts.js-CEKDkK7v.js +55 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/models/_server.ts.js-D7ziyW3d.js +35 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/permission/_server.ts.js-DbkD4JZb.js +92 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/prompt/_server.ts.js-eOLNlf1-.js +94 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/rename/_server.ts.js-txQRocK9.js +57 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/respond/_server.ts.js-D3WGYzkE.js +69 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/select-model/_server.ts.js-g2GtvLTs.js +69 -0
- package/build/server/chunks/entries/endpoints/api/dsh/sessions/_server.ts.js-17yKojU_.js +85 -0
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-file/_server.ts.js-D16pEhvd.js +99 -0
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-file/save/_server.ts.js-BXpZNLK8.js +110 -0
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-file-bytes/_server.ts.js-hBlyjq-x.js +113 -0
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-tree/_server.ts.js-KWRnsAkm.js +59 -0
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_server.ts.js-DzNvvCxK.js +55 -0
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/delete/_server.ts.js-MK5925CY.js +45 -0
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/rename/_server.ts.js-w3Mo0nf7.js +63 -0
- package/build/server/chunks/entries/endpoints/api/prompts/_id_/_server.ts.js-CInfjM-i.js +64 -0
- package/build/server/chunks/entries/endpoints/api/prompts/_server.ts.js-C1lqP1OV.js +87 -0
- package/build/server/chunks/entries/endpoints/api/prompts/use/_server.ts.js-B36YMKMt.js +54 -0
- package/build/server/chunks/entries/endpoints/api/settings/_server.ts.js-CHvHNzeB.js +101 -0
- package/build/server/chunks/entries/pages/_error.svelte.js-BE3-BWDd.js +41 -0
- package/build/server/chunks/entries/pages/_layout.svelte.js-EFiihTdF.js +18 -0
- package/build/server/chunks/entries/pages/_layout.ts.js-CNSo-Z1U.js +22 -0
- package/build/server/chunks/entries/pages/_page.server.ts.js-Bk8UuUXA.js +85 -0
- package/build/server/chunks/entries/pages/_page.svelte.js-CfmKQYLK.js +13883 -0
- package/build/server/chunks/handler-BshnD4Y4.js +1735 -0
- package/build/server/chunks/index.js-I_pMeIwQ.js +3864 -0
- package/build/server/chunks/manifest.js-DwhpAk_y.js +273 -0
- package/build/server/chunks/nodes/0.js-DCyDo8-C.js +12 -0
- package/build/server/chunks/nodes/1.js-Dx7z_VWN.js +9 -0
- package/build/server/chunks/nodes/2.js-CLw9pxho.js +24 -0
- package/build/shims.js +33 -0
- package/package.json +65 -0
- package/template/.dsi/a2a.sqlite +0 -0
- package/template/.dsi/config.json +42 -0
- package/template/.dsi/prompts.sqlite +0 -0
- package/template/.dsi/settings.yaml +33 -0
|
@@ -0,0 +1,717 @@
|
|
|
1
|
+
import { D as DSI_CONFIG_PATH } from './insight-config.js-CfMPTA6Z.js';
|
|
2
|
+
import { mkdirSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the library path: explicit argument → `DSI_PROMPTS_DB` env →
|
|
8
|
+
* sibling of DSI_CONFIG_PATH (`~/.dsi/prompts.sqlite`).
|
|
9
|
+
*/
|
|
10
|
+
function resolvePromptsDbPath(path) {
|
|
11
|
+
return process.env["DSI_PROMPTS_DB"] ?? join(dirname(DSI_CONFIG_PATH), "prompts.sqlite");
|
|
12
|
+
}
|
|
13
|
+
/** Degrade-contract logger — server has no logger module (a2a precedent
|
|
14
|
+
* swallows silently); this feature's contract says failures LOG and
|
|
15
|
+
* return empty/false, so a prefixed console.warn is the honest floor. */
|
|
16
|
+
function warn(msg, e) {
|
|
17
|
+
console.warn(`[prompts-db] ${msg}`, e instanceof Error ? e.message : e);
|
|
18
|
+
}
|
|
19
|
+
var SCHEMA = `
|
|
20
|
+
CREATE TABLE IF NOT EXISTS prompts (
|
|
21
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
22
|
+
label TEXT,
|
|
23
|
+
text TEXT NOT NULL,
|
|
24
|
+
use_count INTEGER NOT NULL DEFAULT 1,
|
|
25
|
+
macro INTEGER NOT NULL DEFAULT 0,
|
|
26
|
+
last_used_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
27
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
28
|
+
UNIQUE(text)
|
|
29
|
+
);
|
|
30
|
+
CREATE INDEX IF NOT EXISTS idx_prompts_text ON prompts(text);
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_prompts_prune
|
|
32
|
+
ON prompts(use_count, last_used_at);
|
|
33
|
+
`;
|
|
34
|
+
/** Hard row cap — overflow prunes oldest one-use rows (ADR D13). */
|
|
35
|
+
var MAX_ROWS = 5e3;
|
|
36
|
+
/** FTS5 external-content trigram index + sync triggers (schema v2, ADR v1.2
|
|
37
|
+
* F3). Applied by migrate(), NOT in SCHEMA: `CREATE VIRTUAL TABLE` has no
|
|
38
|
+
* IF NOT EXISTS and SCHEMA is exec'd on every open — migrate re-enters via
|
|
39
|
+
* DROP IF EXISTS, safe because external content makes the index disposable
|
|
40
|
+
* (rebuildable at any time from the source-of-truth table). */
|
|
41
|
+
var FTS_SCHEMA = `
|
|
42
|
+
CREATE VIRTUAL TABLE prompts_fts USING fts5(
|
|
43
|
+
label, text,
|
|
44
|
+
content='prompts', content_rowid='id',
|
|
45
|
+
tokenize='trigram'
|
|
46
|
+
);
|
|
47
|
+
CREATE TRIGGER prompts_ai AFTER INSERT ON prompts BEGIN
|
|
48
|
+
INSERT INTO prompts_fts(rowid, label, text) VALUES (new.id, new.label, new.text);
|
|
49
|
+
END;
|
|
50
|
+
CREATE TRIGGER prompts_ad AFTER DELETE ON prompts BEGIN
|
|
51
|
+
INSERT INTO prompts_fts(prompts_fts, rowid, label, text)
|
|
52
|
+
VALUES ('delete', old.id, old.label, old.text);
|
|
53
|
+
END;
|
|
54
|
+
CREATE TRIGGER prompts_au AFTER UPDATE OF label, text ON prompts BEGIN
|
|
55
|
+
INSERT INTO prompts_fts(prompts_fts, rowid, label, text)
|
|
56
|
+
VALUES ('delete', old.id, old.label, old.text);
|
|
57
|
+
INSERT INTO prompts_fts(rowid, label, text) VALUES (new.id, new.label, new.text);
|
|
58
|
+
END;
|
|
59
|
+
`;
|
|
60
|
+
/** Schema version tracked via PRAGMA user_version (ADR D11).
|
|
61
|
+
* v0: original table — text/use_count/last_used_at only (label-less).
|
|
62
|
+
* v1: adds label, created_at, prune index, UNIQUE(text) upsert semantics.
|
|
63
|
+
* v2: adds prompts_fts trigram index + sync triggers (ADR v1.2 F3).
|
|
64
|
+
* v3: adds the macro flag column (0 = ordinary, 1 = macro). */
|
|
65
|
+
var SCHEMA_VERSION = 3;
|
|
66
|
+
var defaultDb = null;
|
|
67
|
+
/**
|
|
68
|
+
* Open (creating if needed) the library DB and ensure schema. Idempotent:
|
|
69
|
+
* DDL re-runs safely, migrate is version-gated. An explicit `path` always
|
|
70
|
+
* returns a FRESH handle (test/tmp isolation); the no-arg form memoizes
|
|
71
|
+
* one default handle per process — routes and the finder share it.
|
|
72
|
+
* Never throws: on failure logs and returns null — the feature degrades
|
|
73
|
+
* silently (no strip, no recording; the app is otherwise fine).
|
|
74
|
+
*/
|
|
75
|
+
function openPromptsDb(path) {
|
|
76
|
+
if (defaultDb !== null) try {
|
|
77
|
+
defaultDb.prepare("SELECT 1").get();
|
|
78
|
+
return defaultDb;
|
|
79
|
+
} catch {
|
|
80
|
+
try {
|
|
81
|
+
defaultDb.close();
|
|
82
|
+
} catch {}
|
|
83
|
+
defaultDb = null;
|
|
84
|
+
}
|
|
85
|
+
const file = resolvePromptsDbPath();
|
|
86
|
+
try {
|
|
87
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
88
|
+
const db = new DatabaseSync(file);
|
|
89
|
+
db.exec(SCHEMA);
|
|
90
|
+
migrate(db);
|
|
91
|
+
if (path === void 0) defaultDb = db;
|
|
92
|
+
return db;
|
|
93
|
+
} catch (e) {
|
|
94
|
+
warn(`Failed to open ${file}:`, e);
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Idempotent in-place migration (ADR D11). CREATE TABLE IF NOT EXISTS does
|
|
100
|
+
* not evolve an existing table — a prompts.sqlite created by the pre-label
|
|
101
|
+
* build lacks the label/created_at columns, and every query against them
|
|
102
|
+
* fails. Bump-then-alter: read PRAGMA user_version, add missing columns +
|
|
103
|
+
* indexes, set new version. Failure logs and leaves user_version where it
|
|
104
|
+
* is — the DB still opens, prefix/contains LIKE search keeps working, and
|
|
105
|
+
* the next open retries.
|
|
106
|
+
*/
|
|
107
|
+
function migrate(db) {
|
|
108
|
+
const current = db.prepare("PRAGMA user_version").get().user_version;
|
|
109
|
+
if (current >= SCHEMA_VERSION) return;
|
|
110
|
+
try {
|
|
111
|
+
if (current < 1) {
|
|
112
|
+
const cols = db.prepare("PRAGMA table_info(prompts)").all().map((c) => c.name);
|
|
113
|
+
if (!cols.includes("label")) db.exec("ALTER TABLE prompts ADD COLUMN label TEXT");
|
|
114
|
+
if (!cols.includes("created_at")) {
|
|
115
|
+
db.exec("ALTER TABLE prompts ADD COLUMN created_at TEXT");
|
|
116
|
+
db.exec("UPDATE prompts SET created_at = datetime('now') WHERE created_at IS NULL");
|
|
117
|
+
}
|
|
118
|
+
db.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_prompts_text_unique ON prompts(text)");
|
|
119
|
+
db.exec("UPDATE prompts SET use_count = MAX(use_count, 1) WHERE use_count < 1");
|
|
120
|
+
}
|
|
121
|
+
if (current < 2) {
|
|
122
|
+
db.exec("DROP TABLE IF EXISTS prompts_fts");
|
|
123
|
+
db.exec("DROP TRIGGER IF EXISTS prompts_ai");
|
|
124
|
+
db.exec("DROP TRIGGER IF EXISTS prompts_ad");
|
|
125
|
+
db.exec("DROP TRIGGER IF EXISTS prompts_au");
|
|
126
|
+
db.exec(FTS_SCHEMA);
|
|
127
|
+
db.exec("INSERT INTO prompts_fts(rowid, label, text) SELECT id, label, text FROM prompts");
|
|
128
|
+
}
|
|
129
|
+
if (current < 3) {
|
|
130
|
+
const want = [
|
|
131
|
+
"id",
|
|
132
|
+
"label",
|
|
133
|
+
"text",
|
|
134
|
+
"use_count",
|
|
135
|
+
"macro",
|
|
136
|
+
"last_used_at",
|
|
137
|
+
"created_at"
|
|
138
|
+
];
|
|
139
|
+
let cols = db.prepare("PRAGMA table_info(prompts)").all().map((c) => c.name);
|
|
140
|
+
if (!cols.includes("macro")) {
|
|
141
|
+
db.exec("ALTER TABLE prompts ADD COLUMN macro INTEGER NOT NULL DEFAULT 0");
|
|
142
|
+
cols = db.prepare("PRAGMA table_info(prompts)").all().map((c) => c.name);
|
|
143
|
+
}
|
|
144
|
+
if (JSON.stringify(cols) !== JSON.stringify(want)) {
|
|
145
|
+
db.exec("DROP TABLE IF EXISTS prompts_fts");
|
|
146
|
+
db.exec("DROP TRIGGER IF EXISTS prompts_ai");
|
|
147
|
+
db.exec("DROP TRIGGER IF EXISTS prompts_ad");
|
|
148
|
+
db.exec("DROP TRIGGER IF EXISTS prompts_au");
|
|
149
|
+
db.exec("DROP INDEX IF EXISTS idx_prompts_text");
|
|
150
|
+
db.exec("DROP INDEX IF EXISTS idx_prompts_text_unique");
|
|
151
|
+
db.exec("DROP INDEX IF EXISTS idx_prompts_prune");
|
|
152
|
+
db.exec("DROP INDEX IF EXISTS idx_prompts_label");
|
|
153
|
+
db.exec(`CREATE TABLE prompts_new (
|
|
154
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
155
|
+
label TEXT,
|
|
156
|
+
text TEXT NOT NULL,
|
|
157
|
+
use_count INTEGER NOT NULL DEFAULT 1,
|
|
158
|
+
macro INTEGER NOT NULL DEFAULT 0,
|
|
159
|
+
last_used_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
160
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
161
|
+
UNIQUE(text)
|
|
162
|
+
)`);
|
|
163
|
+
db.exec(`INSERT INTO prompts_new (id, label, text, use_count, macro, last_used_at, created_at)
|
|
164
|
+
SELECT id, label, text, use_count, COALESCE(macro, 0), last_used_at,
|
|
165
|
+
COALESCE(created_at, datetime('now'))
|
|
166
|
+
FROM prompts`);
|
|
167
|
+
db.exec("DROP TABLE prompts");
|
|
168
|
+
db.exec("ALTER TABLE prompts_new RENAME TO prompts");
|
|
169
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_prompts_text ON prompts(text)");
|
|
170
|
+
db.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_prompts_text_unique ON prompts(text)");
|
|
171
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_prompts_prune ON prompts(use_count, last_used_at)");
|
|
172
|
+
db.exec(FTS_SCHEMA);
|
|
173
|
+
db.exec("INSERT INTO prompts_fts(rowid, label, text) SELECT id, label, text FROM prompts");
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
db.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_prompts_label ON prompts(label) WHERE label IS NOT NULL");
|
|
177
|
+
db.exec(`PRAGMA user_version = ${SCHEMA_VERSION}`);
|
|
178
|
+
} catch (e) {
|
|
179
|
+
warn("migration failed:", e);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
var SELECT_COLS = "id, label, text, use_count, macro, last_used_at, created_at";
|
|
183
|
+
/** Find a prompt by exact (trimmed) text. Null on miss/failure. */
|
|
184
|
+
function findPromptByText(text) {
|
|
185
|
+
const trimmed = text.trim();
|
|
186
|
+
if (!trimmed) return null;
|
|
187
|
+
const db = openPromptsDb();
|
|
188
|
+
if (!db) return null;
|
|
189
|
+
try {
|
|
190
|
+
return db.prepare(`SELECT ${SELECT_COLS} FROM prompts WHERE text = ?`).get(trimmed) ?? null;
|
|
191
|
+
} catch (e) {
|
|
192
|
+
warn("findPromptByText failed:", e);
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Record a sent prompt (ADR D5/D15): insert on first send, increment
|
|
198
|
+
* use_count + refresh last_used_at afterwards. Enforces the row cap.
|
|
199
|
+
* Returns the updated record, or null on failure (DB unavailable/empty text).
|
|
200
|
+
*/
|
|
201
|
+
function recordPromptUse(text) {
|
|
202
|
+
const trimmed = text.trim();
|
|
203
|
+
if (!trimmed) return null;
|
|
204
|
+
const db = openPromptsDb();
|
|
205
|
+
if (!db) return null;
|
|
206
|
+
try {
|
|
207
|
+
db.prepare(`INSERT INTO prompts (label, text, use_count, last_used_at, created_at)
|
|
208
|
+
VALUES (NULL, ?, 1, datetime('now'), datetime('now'))
|
|
209
|
+
ON CONFLICT(text) DO UPDATE SET
|
|
210
|
+
use_count = use_count + 1,
|
|
211
|
+
last_used_at = datetime('now')`).run(trimmed);
|
|
212
|
+
pruneIfNeeded(db);
|
|
213
|
+
return db.prepare(`SELECT ${SELECT_COLS} FROM prompts WHERE text = ?`).get(trimmed) ?? null;
|
|
214
|
+
} catch (e) {
|
|
215
|
+
warn("recordPromptUse failed:", e);
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Cap enforcement (ADR D13): if rows > MAX_ROWS, delete the oldest
|
|
221
|
+
* use_count=1 rows until at cap. Multi-use prompts are never pruned.
|
|
222
|
+
*/
|
|
223
|
+
function pruneIfNeeded(db) {
|
|
224
|
+
try {
|
|
225
|
+
const overflow = db.prepare("SELECT COUNT(*) AS n FROM prompts").get().n - MAX_ROWS;
|
|
226
|
+
if (overflow <= 0) return;
|
|
227
|
+
db.prepare(`DELETE FROM prompts
|
|
228
|
+
WHERE id IN (
|
|
229
|
+
SELECT id FROM prompts
|
|
230
|
+
WHERE use_count <= 1
|
|
231
|
+
ORDER BY last_used_at ASC, id ASC
|
|
232
|
+
LIMIT ?
|
|
233
|
+
)`).run(overflow);
|
|
234
|
+
} catch (e) {
|
|
235
|
+
warn("prune failed:", e);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Search prompts. Ranked by use_count DESC, last_used_at DESC.
|
|
240
|
+
*
|
|
241
|
+
* `?` contains/fuzzy mode (ADR v1.2 F2, schema v2): opts.mode ===
|
|
242
|
+
* 'contains' dispatches tiered search —
|
|
243
|
+
* tier 0: key < 3 chars → LIKE '%q%' table scan (trigram index unusable)
|
|
244
|
+
* tier 1: ≥ 3 chars → FTS MATCH '"key"' (index-accelerated contains)
|
|
245
|
+
* tier 2: tier-1 empty AND key ≥ FUZZY_MIN_LEN(4) → per-term best-line
|
|
246
|
+
* Dice, min-combine (Semicolon Search S3): union of per-term
|
|
247
|
+
* trigram pools (bm25 cap 50, union cap 100) re-ranked by
|
|
248
|
+
* min-over-terms of max-over-lines score (label = first line;
|
|
249
|
+
* word-aware — a term scores against each word of a line as
|
|
250
|
+
* well as the whole line), floored at 0.3 per term.
|
|
251
|
+
* Tier 1 always fully outranks tier 2 — tiers never mix in one response.
|
|
252
|
+
* Default (no mode) keeps the OCI prefix contract: label OR text prefix,
|
|
253
|
+
* case-insensitive — DSI drops the ghost-only single-line filter (the
|
|
254
|
+
* ghost is out, ADR §6).
|
|
255
|
+
*/
|
|
256
|
+
function searchPrompts(prefix, limit = 5, opts) {
|
|
257
|
+
const db = openPromptsDb();
|
|
258
|
+
if (!db) return [];
|
|
259
|
+
const trimmed = prefix.trim();
|
|
260
|
+
if (!trimmed) return [];
|
|
261
|
+
try {
|
|
262
|
+
if (opts?.mode === "contains") return searchContains(db, trimmed, limit, opts.macro);
|
|
263
|
+
return db.prepare(`SELECT ${SELECT_COLS} FROM prompts
|
|
264
|
+
WHERE (label LIKE ? ESCAPE '\\' OR text LIKE ? ESCAPE '\\')${macroCond(opts?.macro)}
|
|
265
|
+
ORDER BY use_count DESC, last_used_at DESC
|
|
266
|
+
LIMIT ?`).all(`${escLike(trimmed)}%`, `${escLike(trimmed)}%`, limit);
|
|
267
|
+
} catch (e) {
|
|
268
|
+
warn("searchPrompts failed:", e);
|
|
269
|
+
return [];
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/** SQL fragment filtering the macro flag — empty when unfiltered (the
|
|
273
|
+
* value is a server-internal 0|1, never user text, so inlining is safe). */
|
|
274
|
+
function macroCond(macro) {
|
|
275
|
+
return macro === void 0 ? "" : ` AND macro = ${macro}`;
|
|
276
|
+
}
|
|
277
|
+
/** Escape LIKE wildcards in user input so the prefix matches literally. */
|
|
278
|
+
function escLike(s) {
|
|
279
|
+
return s.replace(/[\\%_]/g, (c) => `\\${c}`);
|
|
280
|
+
}
|
|
281
|
+
/** Trigram index needs ≥3-char keys; below this tier 0 falls back to LIKE. */
|
|
282
|
+
var CONTAINS_MIN_FTS = 3;
|
|
283
|
+
/** Candidate-pool caps: per-term pool (bm25) and the union budget (S3). */
|
|
284
|
+
var FUZZY_CANDIDATE_LIMIT = 50;
|
|
285
|
+
var FUZZY_UNION_LIMIT = 100;
|
|
286
|
+
/** Dice similarity floor for tier-2 inclusion — PER TERM (min-combine,
|
|
287
|
+
* S3): a row is only as strong as its weakest keyword. Below = noise; the
|
|
288
|
+
* ADR word-share decoy scores 0.174 — excluded. */
|
|
289
|
+
var FUZZY_DICE_FLOOR = .3;
|
|
290
|
+
/**
|
|
291
|
+
* Split a `?`-search key into keyword terms (ADR S1): split on `;` and
|
|
292
|
+
* whitespace, trim, drop empties, dedupe (case-insensitive, first spelling
|
|
293
|
+
* wins). `load;skill;feature-spec` → [load, skill, feature-spec];
|
|
294
|
+
* `load;;skill;` → [load, skill]; single term → array of one — the caller
|
|
295
|
+
* decides which path runs. Empty/blank key → []. Pure; exported for tests.
|
|
296
|
+
*/
|
|
297
|
+
function splitQueryTerms(key) {
|
|
298
|
+
const seen = /* @__PURE__ */ new Set();
|
|
299
|
+
const terms = [];
|
|
300
|
+
for (const frag of key.split(/[;\s]+/)) {
|
|
301
|
+
const raw = frag.trim();
|
|
302
|
+
if (!raw) continue;
|
|
303
|
+
const lower = raw.toLowerCase();
|
|
304
|
+
if (seen.has(lower)) continue;
|
|
305
|
+
seen.add(lower);
|
|
306
|
+
terms.push({
|
|
307
|
+
raw,
|
|
308
|
+
lower
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
return terms;
|
|
312
|
+
}
|
|
313
|
+
/** Build an FTS5 phrase string from one term: `"` doubled per FTS5
|
|
314
|
+
* phrase quoting. */
|
|
315
|
+
function ftsPhrase(term) {
|
|
316
|
+
return `"${term.replace(/"/g, "\"\"")}"`;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Tier dispatch for `?` queries: tier 0 LIKE / tier 1 FTS contains /
|
|
320
|
+
* tier 2 fuzzy. Any FTS failure degrades to tier-0 LIKE — search never
|
|
321
|
+
* throws (callers get an empty array or LIKE results, per ADR F3).
|
|
322
|
+
*
|
|
323
|
+
* Multi-keyword (S1+S2): a `;`/whitespace-split key with ≥2 terms takes
|
|
324
|
+
* the AND path — every keyword must appear somewhere in the row (each
|
|
325
|
+
* anywhere, order-free); more keywords narrow the result. Tier 1 runs an
|
|
326
|
+
* AND-of-phrases FTS MATCH on indexable (≥3 char) terms with sub-3-char
|
|
327
|
+
* terms re-verified by LIKE post-filter over the FTS row set; the
|
|
328
|
+
* self-echo row (a previously recorded query whose text starts with the
|
|
329
|
+
* key as sent) is suppressed when it is the ONLY hit; tier 2 is per-term
|
|
330
|
+
* best-line Dice, min-combine (S3). FTS failure degrades to LIKE-AND
|
|
331
|
+
* across ALL terms (AND is absolute in both tiers). A single term keeps
|
|
332
|
+
* the exact v1.2 path.
|
|
333
|
+
*/
|
|
334
|
+
function searchContains(db, key, limit, macro) {
|
|
335
|
+
const terms = splitQueryTerms(key);
|
|
336
|
+
if (terms.length > 1) return searchContainsMulti(db, key, terms, limit, macro);
|
|
337
|
+
const single = terms.length === 1 ? terms[0].raw : key;
|
|
338
|
+
if (single.length < CONTAINS_MIN_FTS) return containsLike(db, single, limit, macro);
|
|
339
|
+
try {
|
|
340
|
+
const contains = ftsContains(db, single, limit, macro);
|
|
341
|
+
if (contains.length > 0) return contains;
|
|
342
|
+
if (single.length < 4) return [];
|
|
343
|
+
return fuzzyReRank(db, terms, limit, macro);
|
|
344
|
+
} catch {
|
|
345
|
+
return containsLike(db, single, limit, macro);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
/** Echo guard: the query row itself — text starts with the `?`-key as the
|
|
349
|
+
* operator sent it (queries ARE recorded when sent, so the query's own
|
|
350
|
+
* row can be the only tier-1 hit; G3). Case-insensitive: LIKE matching
|
|
351
|
+
* is case-insensitive for ASCII, and trigram FTS is ASCII case-folding —
|
|
352
|
+
* the echo row can reach tier 1 through a case variant too. */
|
|
353
|
+
function isQueryEcho(text, keyAsSent) {
|
|
354
|
+
return text.toLowerCase().startsWith(keyAsSent.toLowerCase());
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Multi-keyword `?` search (S1+S2): AND semantics.
|
|
358
|
+
* Tier 1: FTS MATCH '"t1" AND "t2" AND …' over indexable terms (≥3 chars);
|
|
359
|
+
* sub-3-char terms can't use the trigram index, so they're enforced via
|
|
360
|
+
* post-filter LIKE over the FTS row set (AND preserved). The self-echo
|
|
361
|
+
* row is dropped when it's the only tier-1 hit. Tier 2 is per-term
|
|
362
|
+
* best-line Dice, min-combine (S3) — unified with the single-term path.
|
|
363
|
+
* Any FTS failure degrades to LIKE-AND across all terms — never throws.
|
|
364
|
+
*/
|
|
365
|
+
function searchContainsMulti(db, key, terms, limit, macro) {
|
|
366
|
+
const indexable = terms.filter((t) => t.lower.length >= CONTAINS_MIN_FTS);
|
|
367
|
+
try {
|
|
368
|
+
let rows;
|
|
369
|
+
if (indexable.length > 0) {
|
|
370
|
+
rows = ftsAndContains(db, indexable, limit, macro);
|
|
371
|
+
const shortTerms = terms.filter((t) => t.lower.length < CONTAINS_MIN_FTS);
|
|
372
|
+
if (shortTerms.length > 0) rows = rows.filter((row) => shortTerms.every((t) => `${row.label ?? ""}\n${row.text}`.toLowerCase().includes(t.lower)));
|
|
373
|
+
} else rows = likeAndContains(db, terms, limit, macro);
|
|
374
|
+
if (rows.length === 1 && isQueryEcho(rows[0].text, key)) rows = [];
|
|
375
|
+
if (rows.length > 0) return rows;
|
|
376
|
+
if (key.length < 4) return [];
|
|
377
|
+
const fuzzy = fuzzyReRank(db, terms, limit, macro);
|
|
378
|
+
if (fuzzy.length === 1 && isQueryEcho(fuzzy[0].text, key)) return [];
|
|
379
|
+
return fuzzy;
|
|
380
|
+
} catch {
|
|
381
|
+
return likeAndContains(db, terms, limit, macro);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
/** Tier 1 (multi-term) — AND-of-phrases MATCH: every keyword somewhere,
|
|
385
|
+
* order-free, index-accelerated. Phrases quote-escaped via ftsPhrase. */
|
|
386
|
+
function ftsAndContains(db, terms, limit, macro) {
|
|
387
|
+
const expr = terms.map((t) => ftsPhrase(t.lower)).join(" AND ");
|
|
388
|
+
return db.prepare(`SELECT ${SELECT_COLS} FROM prompts
|
|
389
|
+
WHERE id IN (SELECT rowid FROM prompts_fts WHERE prompts_fts MATCH ?)${macroCond(macro)}
|
|
390
|
+
ORDER BY use_count DESC, last_used_at DESC
|
|
391
|
+
LIMIT ?`).all(expr, limit);
|
|
392
|
+
}
|
|
393
|
+
/** LIKE-AND across all terms (multi-term tier-0 and FTS degrade path):
|
|
394
|
+
* case-insensitive contains for EVERY term in label-or-text. Trigram
|
|
395
|
+
* FTS is ASCII case-folding — toLowerCase() keeps LIKE equivalent. */
|
|
396
|
+
function likeAndContains(db, terms, limit, macro) {
|
|
397
|
+
const conds = terms.map(() => "(label LIKE ? ESCAPE '\\' OR text LIKE ? ESCAPE '\\')");
|
|
398
|
+
const params = [];
|
|
399
|
+
for (const t of terms) {
|
|
400
|
+
const like = `%${escLike(t.lower)}%`;
|
|
401
|
+
params.push(like, like);
|
|
402
|
+
}
|
|
403
|
+
return db.prepare(`SELECT ${SELECT_COLS} FROM prompts
|
|
404
|
+
WHERE ${conds.join(" AND ")}${macroCond(macro)}
|
|
405
|
+
ORDER BY use_count DESC, last_used_at DESC
|
|
406
|
+
LIMIT ?`).all(...params, limit);
|
|
407
|
+
}
|
|
408
|
+
/** Tier 1 — index-accelerated contains via trigram phrase MATCH. */
|
|
409
|
+
function ftsContains(db, key, limit, macro) {
|
|
410
|
+
const expr = ftsPhrase(key.toLowerCase());
|
|
411
|
+
if (!key) return containsLike(db, key, limit, macro);
|
|
412
|
+
return db.prepare(`SELECT ${SELECT_COLS} FROM prompts
|
|
413
|
+
WHERE id IN (SELECT rowid FROM prompts_fts WHERE prompts_fts MATCH ?)${macroCond(macro)}
|
|
414
|
+
ORDER BY use_count DESC, last_used_at DESC
|
|
415
|
+
LIMIT ?`).all(expr, limit);
|
|
416
|
+
}
|
|
417
|
+
/** Tier 0 — LIKE table scan (short keys; FTS degrade path shares it). */
|
|
418
|
+
function containsLike(db, key, limit, macro) {
|
|
419
|
+
const like = `%${escLike(key)}%`;
|
|
420
|
+
return db.prepare(`SELECT ${SELECT_COLS} FROM prompts
|
|
421
|
+
WHERE (label LIKE ? ESCAPE '\\' OR text LIKE ? ESCAPE '\\')${macroCond(macro)}
|
|
422
|
+
ORDER BY use_count DESC, last_used_at DESC
|
|
423
|
+
LIMIT ?`).all(like, like, limit);
|
|
424
|
+
}
|
|
425
|
+
/** Dice coefficient over character trigrams (case handled by callers). */
|
|
426
|
+
function diceSimilarity(a, b) {
|
|
427
|
+
const grams = /* @__PURE__ */ new Map();
|
|
428
|
+
for (let i = 0; i + 3 <= a.length; i++) {
|
|
429
|
+
const g = a.slice(i, 3 + i);
|
|
430
|
+
grams.set(g, (grams.get(g) ?? 0) + 1);
|
|
431
|
+
}
|
|
432
|
+
if (grams.size === 0) return 0;
|
|
433
|
+
let bCount = 0;
|
|
434
|
+
let shared = 0;
|
|
435
|
+
for (let i = 0; i + 3 <= b.length; i++) {
|
|
436
|
+
bCount++;
|
|
437
|
+
const g = b.slice(i, 3 + i);
|
|
438
|
+
const have = grams.get(g) ?? 0;
|
|
439
|
+
if (have > 0) {
|
|
440
|
+
shared++;
|
|
441
|
+
if (have === 1) grams.delete(g);
|
|
442
|
+
else grams.set(g, have - 1);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
if (bCount === 0) return 0;
|
|
446
|
+
const aCount = a.length - 2;
|
|
447
|
+
return 2 * shared / (aCount + bCount);
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Word-level similarity: max of Dice and normalized edit distance — Dice is
|
|
451
|
+
* meaningless for words shorter than 3 trigrams/chars, edit covers them
|
|
452
|
+
* ("lod" vs "load": Dice 0, edit 0.75 → 0.75). Exported for tests.
|
|
453
|
+
*/
|
|
454
|
+
function wordSimilarity(a, b) {
|
|
455
|
+
const edit = 1 - levenshtein(a, b) / Math.max(a.length, b.length);
|
|
456
|
+
return Math.max(diceSimilarity(a, b), edit);
|
|
457
|
+
}
|
|
458
|
+
/** Wagner–Fischer edit distance (two-row DP), case handled by callers. */
|
|
459
|
+
function levenshtein(a, b) {
|
|
460
|
+
if (a === b) return 0;
|
|
461
|
+
if (!a.length) return b.length;
|
|
462
|
+
if (!b.length) return a.length;
|
|
463
|
+
let prev = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
464
|
+
for (let i = 1; i <= a.length; i++) {
|
|
465
|
+
const cur = [i];
|
|
466
|
+
for (let j = 1; j <= b.length; j++) cur[j] = Math.min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
467
|
+
prev = cur;
|
|
468
|
+
}
|
|
469
|
+
return prev[b.length];
|
|
470
|
+
}
|
|
471
|
+
/** Lines a row offers to line-level Dice (S3): label counts as the FIRST
|
|
472
|
+
* line — the user-chosen handle deserves line parity with text lines. */
|
|
473
|
+
function rowLines(row) {
|
|
474
|
+
return row.label !== null ? [row.label, ...row.text.split("\n")] : row.text.split("\n");
|
|
475
|
+
}
|
|
476
|
+
/** Best-line score for ONE term (S3): max over the row's lines, where a
|
|
477
|
+
* line's score is the best of whole-line Dice and word-level similarity
|
|
478
|
+
* over the line's words (max of Dice and normalized edit distance — Dice
|
|
479
|
+
* is meaningless for words shorter than 3 trigrams, edit covers them:
|
|
480
|
+
* typo'd "lod" vs "load" clears the floor at word level while line-level
|
|
481
|
+
* trigram dilution would sink it). The word-aware allowance is what keeps
|
|
482
|
+
* typo'd short terms reachable under min-combine as part of a multi-term
|
|
483
|
+
* key. Localizing to the best line kills the body tax: a 400-char body
|
|
484
|
+
* diluting full-text Dice can no longer sink a term that matches its own
|
|
485
|
+
* line cleanly. */
|
|
486
|
+
function termLineScore(term, row) {
|
|
487
|
+
let best = 0;
|
|
488
|
+
for (const line of rowLines(row)) {
|
|
489
|
+
const l = line.toLowerCase();
|
|
490
|
+
if (l.includes(term)) {
|
|
491
|
+
best = 1;
|
|
492
|
+
break;
|
|
493
|
+
}
|
|
494
|
+
let lineScore = diceSimilarity(term, l);
|
|
495
|
+
for (const word of l.split(/\s+/)) {
|
|
496
|
+
if (!word) continue;
|
|
497
|
+
lineScore = Math.max(lineScore, wordSimilarity(term, word));
|
|
498
|
+
}
|
|
499
|
+
best = Math.max(best, lineScore);
|
|
500
|
+
}
|
|
501
|
+
return best;
|
|
502
|
+
}
|
|
503
|
+
/** FTS5 trigram set for a single term (S3): grams of the lowercased term
|
|
504
|
+
* only — never extracted across separators, so no junk grams bridge
|
|
505
|
+
* `;`-split keywords. Deduped; null for <3-char terms (no grams). */
|
|
506
|
+
function termTrigramExpr(term) {
|
|
507
|
+
const k = term.toLowerCase();
|
|
508
|
+
const grams = [];
|
|
509
|
+
for (let i = 0; i + 3 <= k.length && grams.length < 64; i++) {
|
|
510
|
+
const g = k.slice(i, 3 + i);
|
|
511
|
+
if (!grams.includes(g)) grams.push(g);
|
|
512
|
+
}
|
|
513
|
+
return grams.length ? grams.map((g) => `"${g}"`).join(" OR ") : null;
|
|
514
|
+
}
|
|
515
|
+
/** Tier 2 — per-term best-line Dice, min-combine (S3, Semicolon Search).
|
|
516
|
+
* Candidate pool: per-term trigram OR + bm25 cap 50, UNION of per-term
|
|
517
|
+
* pools capped 100 — a row matching ANY term fuzzily enters the pool;
|
|
518
|
+
* per-term scoring then enforces the AND. Row score = MIN over terms of
|
|
519
|
+
* (max Dice over the row's lines, label counts as first line); any term
|
|
520
|
+
* under the 0.3 floor excludes the row entirely. Ordering: score DESC,
|
|
521
|
+
* use_count DESC, last_used_at DESC. Never mixes with tier 1 (only runs
|
|
522
|
+
* when tier 1 returned empty). */
|
|
523
|
+
function fuzzyReRank(db, terms, limit, macro) {
|
|
524
|
+
const pool = /* @__PURE__ */ new Map();
|
|
525
|
+
for (const term of terms) {
|
|
526
|
+
if (term.lower.length < CONTAINS_MIN_FTS) continue;
|
|
527
|
+
const expr = termTrigramExpr(term.lower);
|
|
528
|
+
if (!expr) continue;
|
|
529
|
+
try {
|
|
530
|
+
const rows = db.prepare(`SELECT ${SELECT_COLS} FROM prompts
|
|
531
|
+
WHERE id IN (
|
|
532
|
+
SELECT rowid FROM prompts_fts WHERE prompts_fts MATCH ?
|
|
533
|
+
ORDER BY bm25(prompts_fts) LIMIT ${FUZZY_CANDIDATE_LIMIT}
|
|
534
|
+
)${macroCond(macro)}`).all(expr);
|
|
535
|
+
for (const r of rows) {
|
|
536
|
+
if (pool.size >= FUZZY_UNION_LIMIT) break;
|
|
537
|
+
if (!pool.has(r.id)) pool.set(r.id, r);
|
|
538
|
+
}
|
|
539
|
+
} catch {}
|
|
540
|
+
}
|
|
541
|
+
if (pool.size === 0) return [];
|
|
542
|
+
return [...pool.values()].map((row) => {
|
|
543
|
+
return {
|
|
544
|
+
row,
|
|
545
|
+
score: terms.reduce((min, t) => Math.min(min, termLineScore(t.lower, row)), 1)
|
|
546
|
+
};
|
|
547
|
+
}).filter((s) => s.score >= FUZZY_DICE_FLOOR).sort((a, b) => b.score - a.score || b.row.use_count - a.row.use_count || (b.row.last_used_at < a.row.last_used_at ? 1 : b.row.last_used_at > a.row.last_used_at ? -1 : 0)).slice(0, limit).map((s) => s.row);
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Rename a prompt's label (ADR D3). Label is the one-line handle used for
|
|
551
|
+
* matching and display; passing null clears it. Fails (returns false) if
|
|
552
|
+
* another prompt already claims the label (unique partial index).
|
|
553
|
+
*/
|
|
554
|
+
function renamePromptLabel(id, label) {
|
|
555
|
+
const db = openPromptsDb();
|
|
556
|
+
if (!db) return false;
|
|
557
|
+
try {
|
|
558
|
+
const clean = label === null ? null : label.trim().slice(0, 60) || null;
|
|
559
|
+
return db.prepare("UPDATE prompts SET label = ? WHERE id = ?").run(clean, id).changes > 0;
|
|
560
|
+
} catch (e) {
|
|
561
|
+
warn("renamePromptLabel failed:", e);
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
/** Delete a prompt row. Returns true when a row was removed. */
|
|
566
|
+
function deletePrompt(id) {
|
|
567
|
+
const db = openPromptsDb();
|
|
568
|
+
if (!db) return false;
|
|
569
|
+
try {
|
|
570
|
+
return db.prepare("DELETE FROM prompts WHERE id = ?").run(id).changes > 0;
|
|
571
|
+
} catch (e) {
|
|
572
|
+
warn("deletePrompt failed:", e);
|
|
573
|
+
return false;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
/** Sort param → ORDER BY clause (col + direction). */
|
|
577
|
+
var SORT_MAP = {
|
|
578
|
+
uses: {
|
|
579
|
+
col: "use_count",
|
|
580
|
+
asc: "use_count ASC",
|
|
581
|
+
desc: "use_count DESC"
|
|
582
|
+
},
|
|
583
|
+
last_used: {
|
|
584
|
+
col: "last_used_at",
|
|
585
|
+
asc: "last_used_at ASC",
|
|
586
|
+
desc: "last_used_at DESC"
|
|
587
|
+
},
|
|
588
|
+
created: {
|
|
589
|
+
col: "created_at",
|
|
590
|
+
asc: "created_at ASC",
|
|
591
|
+
desc: "created_at DESC"
|
|
592
|
+
},
|
|
593
|
+
display: {
|
|
594
|
+
col: "COALESCE(label, text)",
|
|
595
|
+
asc: "COALESCE(label, text) ASC",
|
|
596
|
+
desc: "COALESCE(label, text) DESC"
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
/**
|
|
600
|
+
* List prompts for the manager (ADR E4). Supports optional prefix filter,
|
|
601
|
+
* sort, and offset paging. Returns rows + total count (for cap-footer UX).
|
|
602
|
+
*/
|
|
603
|
+
function listPrompts(opts) {
|
|
604
|
+
const db = openPromptsDb();
|
|
605
|
+
if (!db) return {
|
|
606
|
+
rows: [],
|
|
607
|
+
total: 0
|
|
608
|
+
};
|
|
609
|
+
const limit = Math.min(Math.max(opts.limit ?? 200, 1), 500);
|
|
610
|
+
const offset = Math.max(opts.offset ?? 0, 0);
|
|
611
|
+
const sortKey = opts.sort && SORT_MAP[opts.sort] ? opts.sort : "last_used";
|
|
612
|
+
const dir = opts.dir === "asc" ? "asc" : "desc";
|
|
613
|
+
const orderBy = SORT_MAP[sortKey][dir];
|
|
614
|
+
const q = opts.q?.trim();
|
|
615
|
+
try {
|
|
616
|
+
if (q) {
|
|
617
|
+
const like = `${escLike(q)}%`;
|
|
618
|
+
return {
|
|
619
|
+
rows: db.prepare(`SELECT ${SELECT_COLS} FROM prompts
|
|
620
|
+
WHERE label LIKE ? ESCAPE '\\' OR text LIKE ? ESCAPE '\\'
|
|
621
|
+
ORDER BY ${orderBy}
|
|
622
|
+
LIMIT ? OFFSET ?`).all(like, like, limit, offset),
|
|
623
|
+
total: db.prepare(`SELECT COUNT(*) AS n FROM prompts
|
|
624
|
+
WHERE label LIKE ? ESCAPE '\\' OR text LIKE ? ESCAPE '\\'`).get(like, like).n
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
return {
|
|
628
|
+
rows: db.prepare(`SELECT ${SELECT_COLS} FROM prompts ORDER BY ${orderBy} LIMIT ? OFFSET ?`).all(limit, offset),
|
|
629
|
+
total: db.prepare("SELECT COUNT(*) AS n FROM prompts").get().n
|
|
630
|
+
};
|
|
631
|
+
} catch (e) {
|
|
632
|
+
warn("listPrompts failed:", e);
|
|
633
|
+
return {
|
|
634
|
+
rows: [],
|
|
635
|
+
total: 0
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Create a prompt manually (ADR E4). If text already exists, returns the
|
|
641
|
+
* existing row as a 409-info object instead of inserting. Manual create ≠
|
|
642
|
+
* upsert — never silently bumps use_count.
|
|
643
|
+
*/
|
|
644
|
+
function createPrompt(text, label) {
|
|
645
|
+
const trimmed = text.trim();
|
|
646
|
+
if (!trimmed) return {
|
|
647
|
+
ok: false,
|
|
648
|
+
existing: null
|
|
649
|
+
};
|
|
650
|
+
const db = openPromptsDb();
|
|
651
|
+
if (!db) return {
|
|
652
|
+
ok: false,
|
|
653
|
+
existing: null
|
|
654
|
+
};
|
|
655
|
+
try {
|
|
656
|
+
const existing = db.prepare(`SELECT ${SELECT_COLS} FROM prompts WHERE text = ?`).get(trimmed);
|
|
657
|
+
if (existing) return {
|
|
658
|
+
ok: false,
|
|
659
|
+
existing
|
|
660
|
+
};
|
|
661
|
+
const cleanLabel = label ? label.trim().slice(0, 60) || null : null;
|
|
662
|
+
db.prepare(`INSERT INTO prompts (label, text, use_count, last_used_at, created_at)
|
|
663
|
+
VALUES (?, ?, 1, datetime('now'), datetime('now'))`).run(cleanLabel, trimmed);
|
|
664
|
+
pruneIfNeeded(db);
|
|
665
|
+
return {
|
|
666
|
+
ok: true,
|
|
667
|
+
record: db.prepare(`SELECT ${SELECT_COLS} FROM prompts WHERE text = ?`).get(trimmed)
|
|
668
|
+
};
|
|
669
|
+
} catch (e) {
|
|
670
|
+
warn("createPrompt failed:", e);
|
|
671
|
+
return {
|
|
672
|
+
ok: false,
|
|
673
|
+
existing: null
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Update a prompt's text, label, and/or use_count (ADR E4 PATCH extend).
|
|
679
|
+
* `use_count` is floored at 1 (reset). Returns the updated row or null.
|
|
680
|
+
*/
|
|
681
|
+
function updatePrompt(id, fields) {
|
|
682
|
+
const db = openPromptsDb();
|
|
683
|
+
if (!db) return null;
|
|
684
|
+
try {
|
|
685
|
+
const sets = [];
|
|
686
|
+
const args = [];
|
|
687
|
+
if (fields.text !== void 0) {
|
|
688
|
+
const trimmed = fields.text.trim();
|
|
689
|
+
if (!trimmed) return null;
|
|
690
|
+
sets.push("text = ?");
|
|
691
|
+
args.push(trimmed);
|
|
692
|
+
}
|
|
693
|
+
if (fields.label !== void 0) {
|
|
694
|
+
const clean = fields.label === null ? null : fields.label.trim().slice(0, 60) || null;
|
|
695
|
+
sets.push("label = ?");
|
|
696
|
+
args.push(clean);
|
|
697
|
+
}
|
|
698
|
+
if (fields.use_count !== void 0) {
|
|
699
|
+
sets.push("use_count = ?");
|
|
700
|
+
args.push(Math.max(1, Math.floor(fields.use_count)));
|
|
701
|
+
}
|
|
702
|
+
if (fields.macro !== void 0) {
|
|
703
|
+
sets.push("macro = ?");
|
|
704
|
+
args.push(fields.macro ? 1 : 0);
|
|
705
|
+
}
|
|
706
|
+
if (sets.length === 0) return null;
|
|
707
|
+
args.push(id);
|
|
708
|
+
if (db.prepare(`UPDATE prompts SET ${sets.join(", ")} WHERE id = ?`).run(...args).changes === 0) return null;
|
|
709
|
+
return db.prepare(`SELECT ${SELECT_COLS} FROM prompts WHERE id = ?`).get(id);
|
|
710
|
+
} catch (e) {
|
|
711
|
+
warn("updatePrompt failed:", e);
|
|
712
|
+
return null;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
export { renamePromptLabel as a, createPrompt as c, deletePrompt as d, findPromptByText as f, listPrompts as l, recordPromptUse as r, searchPrompts as s, updatePrompt as u };
|
|
717
|
+
//# sourceMappingURL=db2.js-DBltVUGg.js.map
|