@chude/memory 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +294 -0
- package/dist/application/index.d.ts +6 -0
- package/dist/application/services/ambient-context-service.d.ts +90 -0
- package/dist/application/services/backfill-service.d.ts +71 -0
- package/dist/application/services/budget-allocator.d.ts +57 -0
- package/dist/application/services/embedding-service.d.ts +131 -0
- package/dist/application/services/export-service.d.ts +225 -0
- package/dist/application/services/extraction-pipeline.d.ts +50 -0
- package/dist/application/services/friction-service.d.ts +148 -0
- package/dist/application/services/fts-sanitizer.d.ts +25 -0
- package/dist/application/services/index.d.ts +34 -0
- package/dist/application/services/llm-extractor.d.ts +96 -0
- package/dist/application/services/memory-file-sync-service.d.ts +58 -0
- package/dist/application/services/pattern-extractor.d.ts +95 -0
- package/dist/application/services/recovery-service.d.ts +81 -0
- package/dist/application/services/rrf-fusion.d.ts +53 -0
- package/dist/application/services/smart-context-service.d.ts +126 -0
- package/dist/application/services/sync-service.d.ts +157 -0
- package/dist/application/services/temporal-decay.d.ts +62 -0
- package/dist/domain/entities/backfill-state.d.ts +56 -0
- package/dist/domain/entities/entity.d.ts +131 -0
- package/dist/domain/entities/extraction-state.d.ts +128 -0
- package/dist/domain/entities/fact.d.ts +59 -0
- package/dist/domain/entities/friction-entry.d.ts +84 -0
- package/dist/domain/entities/index.d.ts +15 -0
- package/dist/domain/entities/link.d.ts +74 -0
- package/dist/domain/entities/memory-file.d.ts +78 -0
- package/dist/domain/entities/message.d.ts +70 -0
- package/dist/domain/entities/session.d.ts +93 -0
- package/dist/domain/entities/tool-use.d.ts +85 -0
- package/dist/domain/errors/error-codes.d.ts +37 -0
- package/dist/domain/errors/index.d.ts +8 -0
- package/dist/domain/errors/memory-error.d.ts +52 -0
- package/dist/domain/errors/unknown-error.d.ts +9 -0
- package/dist/domain/index.d.ts +11 -0
- package/dist/domain/ports/embedding.d.ts +96 -0
- package/dist/domain/ports/extraction.d.ts +13 -0
- package/dist/domain/ports/index.d.ts +14 -0
- package/dist/domain/ports/redactor.d.ts +17 -0
- package/dist/domain/ports/repositories.d.ts +658 -0
- package/dist/domain/ports/services.d.ts +180 -0
- package/dist/domain/ports/signals.d.ts +82 -0
- package/dist/domain/ports/sources.d.ts +122 -0
- package/dist/domain/ports/types.d.ts +150 -0
- package/dist/domain/services/content-extractor.d.ts +61 -0
- package/dist/domain/services/index.d.ts +8 -0
- package/dist/domain/services/path-decoder.d.ts +56 -0
- package/dist/domain/services/query-parser.d.ts +47 -0
- package/dist/domain/value-objects/embedding-config.d.ts +56 -0
- package/dist/domain/value-objects/embedding-result.d.ts +46 -0
- package/dist/domain/value-objects/index.d.ts +10 -0
- package/dist/domain/value-objects/project-path.d.ts +92 -0
- package/dist/domain/value-objects/search-query.d.ts +30 -0
- package/dist/domain/value-objects/search-result.d.ts +92 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +1548 -0
- package/dist/infrastructure/database/connection.d.ts +161 -0
- package/dist/infrastructure/database/event-log.d.ts +22 -0
- package/dist/infrastructure/database/health-checker.d.ts +248 -0
- package/dist/infrastructure/database/index.d.ts +11 -0
- package/dist/infrastructure/database/repositories/backfill-state-repository.d.ts +19 -0
- package/dist/infrastructure/database/repositories/embedding-repository.d.ts +121 -0
- package/dist/infrastructure/database/repositories/entity-repository.d.ts +73 -0
- package/dist/infrastructure/database/repositories/extraction-log-repository.d.ts +17 -0
- package/dist/infrastructure/database/repositories/extraction-state-repository.d.ts +52 -0
- package/dist/infrastructure/database/repositories/fact-repository.d.ts +25 -0
- package/dist/infrastructure/database/repositories/friction-repository.d.ts +41 -0
- package/dist/infrastructure/database/repositories/index.d.ts +17 -0
- package/dist/infrastructure/database/repositories/link-repository.d.ts +64 -0
- package/dist/infrastructure/database/repositories/memory-file-repository.d.ts +28 -0
- package/dist/infrastructure/database/repositories/message-repository.d.ts +87 -0
- package/dist/infrastructure/database/repositories/session-repository.d.ts +125 -0
- package/dist/infrastructure/database/repositories/tool-use-repository.d.ts +72 -0
- package/dist/infrastructure/database/schema.d.ts +203 -0
- package/dist/infrastructure/database/services/context-service.d.ts +93 -0
- package/dist/infrastructure/database/services/hybrid-search-service.d.ts +156 -0
- package/dist/infrastructure/database/services/index.d.ts +10 -0
- package/dist/infrastructure/database/services/search-service.d.ts +57 -0
- package/dist/infrastructure/database/services/stats-service.d.ts +36 -0
- package/dist/infrastructure/embedding/background-embedder.d.ts +125 -0
- package/dist/infrastructure/embedding/embedding-provider-factory.d.ts +44 -0
- package/dist/infrastructure/embedding/index.d.ts +5 -0
- package/dist/infrastructure/embedding/ollama-provider.d.ts +41 -0
- package/dist/infrastructure/embedding/openai-provider.d.ts +38 -0
- package/dist/infrastructure/embedding/transformers-js-provider.d.ts +34 -0
- package/dist/infrastructure/external/index.d.ts +7 -0
- package/dist/infrastructure/external/qmd-runner.d.ts +36 -0
- package/dist/infrastructure/hooks/auto-memory-writer.d.ts +52 -0
- package/dist/infrastructure/hooks/config-manager.d.ts +237 -0
- package/dist/infrastructure/hooks/git-syncer.d.ts +44 -0
- package/dist/infrastructure/hooks/hook-runner.d.ts +126 -0
- package/dist/infrastructure/hooks/index.d.ts +12 -0
- package/dist/infrastructure/hooks/log-writer.d.ts +106 -0
- package/dist/infrastructure/hooks/settings-manager.d.ts +163 -0
- package/dist/infrastructure/hooks/sync-hook-script.d.ts +83 -0
- package/dist/infrastructure/hooks/sync-logger-adapter.d.ts +17 -0
- package/dist/infrastructure/index.d.ts +11 -0
- package/dist/infrastructure/llm/anthropic-extractor.d.ts +20 -0
- package/dist/infrastructure/llm/claude-cli-extractor.d.ts +14 -0
- package/dist/infrastructure/llm/claude-summary-generator.d.ts +14 -0
- package/dist/infrastructure/llm/extraction-helper.d.ts +16 -0
- package/dist/infrastructure/llm/ollama-extractor.d.ts +20 -0
- package/dist/infrastructure/llm/openai-extractor.d.ts +23 -0
- package/dist/infrastructure/migration.d.ts +103 -0
- package/dist/infrastructure/parsers/event-classifier.d.ts +111 -0
- package/dist/infrastructure/parsers/index.d.ts +8 -0
- package/dist/infrastructure/parsers/jsonl-parser.d.ts +25 -0
- package/dist/infrastructure/parsers/timestamp.d.ts +18 -0
- package/dist/infrastructure/paths.d.ts +129 -0
- package/dist/infrastructure/providers/provider-defaults.d.ts +11 -0
- package/dist/infrastructure/providers/provider-registry.d.ts +28 -0
- package/dist/infrastructure/security/pattern-redactor.d.ts +6 -0
- package/dist/infrastructure/signals/adapters.d.ts +27 -0
- package/dist/infrastructure/signals/checkpoint-manager.d.ts +83 -0
- package/dist/infrastructure/signals/index.d.ts +8 -0
- package/dist/infrastructure/signals/signal-handler.d.ts +113 -0
- package/dist/infrastructure/sources/index.d.ts +8 -0
- package/dist/infrastructure/sources/memory-file-scanner.d.ts +23 -0
- package/dist/infrastructure/sources/project-name-resolver.d.ts +67 -0
- package/dist/infrastructure/sources/session-source.d.ts +70 -0
- package/dist/presentation/cli/command-result.d.ts +10 -0
- package/dist/presentation/cli/commands/_helpers/capture-json.d.ts +36 -0
- package/dist/presentation/cli/commands/_helpers/deprecation-warning.d.ts +41 -0
- package/dist/presentation/cli/commands/backfill.d.ts +56 -0
- package/dist/presentation/cli/commands/browse.d.ts +55 -0
- package/dist/presentation/cli/commands/completion.d.ts +61 -0
- package/dist/presentation/cli/commands/context.d.ts +53 -0
- package/dist/presentation/cli/commands/doctor.d.ts +55 -0
- package/dist/presentation/cli/commands/export.d.ts +36 -0
- package/dist/presentation/cli/commands/extract.d.ts +40 -0
- package/dist/presentation/cli/commands/facts.d.ts +17 -0
- package/dist/presentation/cli/commands/friction/dashboard.d.ts +18 -0
- package/dist/presentation/cli/commands/friction/index.d.ts +12 -0
- package/dist/presentation/cli/commands/friction/list.d.ts +12 -0
- package/dist/presentation/cli/commands/friction/log.d.ts +12 -0
- package/dist/presentation/cli/commands/friction/purge.d.ts +12 -0
- package/dist/presentation/cli/commands/friction/resolve.d.ts +12 -0
- package/dist/presentation/cli/commands/friction/types.d.ts +86 -0
- package/dist/presentation/cli/commands/friction/wontfix.d.ts +12 -0
- package/dist/presentation/cli/commands/import.d.ts +38 -0
- package/dist/presentation/cli/commands/index.d.ts +51 -0
- package/dist/presentation/cli/commands/install.d.ts +67 -0
- package/dist/presentation/cli/commands/list.d.ts +61 -0
- package/dist/presentation/cli/commands/migrate.d.ts +36 -0
- package/dist/presentation/cli/commands/purge.d.ts +100 -0
- package/dist/presentation/cli/commands/query.d.ts +51 -0
- package/dist/presentation/cli/commands/related.d.ts +47 -0
- package/dist/presentation/cli/commands/remote.d.ts +36 -0
- package/dist/presentation/cli/commands/search.d.ts +100 -0
- package/dist/presentation/cli/commands/show.d.ts +51 -0
- package/dist/presentation/cli/commands/stats.d.ts +38 -0
- package/dist/presentation/cli/commands/status.d.ts +152 -0
- package/dist/presentation/cli/commands/sync/ambient.d.ts +22 -0
- package/dist/presentation/cli/commands/sync/background.d.ts +23 -0
- package/dist/presentation/cli/commands/sync/embedding-pass.d.ts +32 -0
- package/dist/presentation/cli/commands/sync/helpers.d.ts +25 -0
- package/dist/presentation/cli/commands/sync/index.d.ts +17 -0
- package/dist/presentation/cli/commands/sync/memory-files.d.ts +26 -0
- package/dist/presentation/cli/commands/sync/types.d.ts +163 -0
- package/dist/presentation/cli/commands/uninstall.d.ts +44 -0
- package/dist/presentation/cli/db-startup.d.ts +61 -0
- package/dist/presentation/cli/formatters/ai-formatter.d.ts +38 -0
- package/dist/presentation/cli/formatters/color.d.ts +82 -0
- package/dist/presentation/cli/formatters/context-formatter.d.ts +55 -0
- package/dist/presentation/cli/formatters/dto-helpers.d.ts +176 -0
- package/dist/presentation/cli/formatters/envelope.d.ts +136 -0
- package/dist/presentation/cli/formatters/error-formatter.d.ts +41 -0
- package/dist/presentation/cli/formatters/friction-dashboard.d.ts +46 -0
- package/dist/presentation/cli/formatters/index.d.ts +17 -0
- package/dist/presentation/cli/formatters/list-formatter.d.ts +48 -0
- package/dist/presentation/cli/formatters/output-formatter.d.ts +98 -0
- package/dist/presentation/cli/formatters/related-formatter.d.ts +57 -0
- package/dist/presentation/cli/formatters/show-formatter.d.ts +63 -0
- package/dist/presentation/cli/formatters/stats-formatter.d.ts +54 -0
- package/dist/presentation/cli/formatters/text-width.d.ts +37 -0
- package/dist/presentation/cli/formatters/timestamp-formatter.d.ts +38 -0
- package/dist/presentation/cli/index.d.ts +10 -0
- package/dist/presentation/cli/index.js +1664 -0
- package/dist/presentation/cli/parsers/date-parser.d.ts +28 -0
- package/dist/presentation/cli/parsers/index.d.ts +6 -0
- package/dist/presentation/cli/pickers/index.d.ts +6 -0
- package/dist/presentation/cli/pickers/session-picker.d.ts +59 -0
- package/dist/presentation/cli/progress-reporter.d.ts +199 -0
- package/package.json +94 -0
|
@@ -0,0 +1,1664 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
var D6=Object.create;var{getPrototypeOf:k6,defineProperty:h$,getOwnPropertyNames:S6}=Object;var v6=Object.prototype.hasOwnProperty;var h1=($,Z,K)=>{K=$!=null?D6(k6($)):{};let X=Z||!$||!$.__esModule?h$(K,"default",{value:$,enumerable:!0}):K;for(let Y of S6($))if(!v6.call(X,Y))h$(X,Y,{get:()=>$[Y],enumerable:!0});return X};var y=($,Z)=>{for(var K in Z)h$($,K,{get:Z[K],enumerable:!0,configurable:!0,set:(X)=>Z[K]=()=>X})};var L=($,Z)=>()=>($&&(Z=$($=0)),Z);var n0=import.meta.require;function A($){return $ instanceof Error?$.message:String($)}function g1($){return $ instanceof Error?$:Error(A($))}var N3={};y(N3,{getMemoryDir:()=>c1,getMachineLogPath:()=>g$,getLogDir:()=>X0,getLegacyDir:()=>m1,getHookDir:()=>d1,getEventsDir:()=>H1,getEventLogPath:()=>w6,getDbPath:()=>J1,getDataDir:()=>a,getConfigPath:()=>u1,getConfigDir:()=>S0,getCheckpointPath:()=>l1,getBackupDir:()=>p1,getAllLogFiles:()=>n1});import{existsSync as A3,readdirSync as y6}from"fs";import{homedir as M4}from"os";import{join as n}from"path";function S0(){let $=process.env.XDG_CONFIG_HOME;if($)return n($,F4);return n(M4(),".config",F4)}function a(){let $=process.env.XDG_DATA_HOME;if($)return n($,F4);return n(M4(),".local","share",F4)}function m1(){return n(M4(),".memory-nexus")}function c1(){let $=process.env.MEMORY_HOME;if($)return $;return n(M4(),".memory")}function u1(){return n(S0(),"config.json")}function J1(){return n(a(),"memory.db")}function X0(){return n(a(),"logs")}function d1(){return n(a(),"hooks")}function p1(){return n(a(),"backups")}function l1(){return n(a(),"sync-checkpoint.json")}function H1(){return n(a(),"events")}function w6(){return n(H1(),"events.jsonl")}function g$($){return n(H1(),`events-${$}.jsonl`)}function n1($){let Z=$??H1();if(!A3(Z))return[];let K=y6(Z),X=[],Y=n(Z,"events.jsonl");if(A3(Y))X.push(Y);for(let Q of K)if(Q.startsWith("events-")&&Q.endsWith(".jsonl"))X.push(n(Z,Q));return X}var F4="memory";var l=L(()=>{if(process.platform==="win32"&&!process.env.HOME)process.env.HOME=process.env.USERPROFILE});import{copyFileSync as q3,existsSync as a1,mkdirSync as m$,readFileSync as b6,writeFileSync as O3}from"fs";import{dirname as c$,join as u$}from"path";import{homedir as f6}from"os";function V1($){return $?.settingsPath??u$(f6(),".claude","settings.json")}function j4($){return $?.backupPath??u$(p1(),"settings.json.backup")}function a0($){return $?.hookScriptPath??u$(d1(),"sync-hook.js")}function W1($){let Z=V1($);if(!a1(Z))return{};try{let K=b6(Z,"utf-8");return JSON.parse(K)}catch{return{}}}function U3($){let Z=V1($),K=j4($);if(!a1(Z))return!1;return m$(c$(K),{recursive:!0}),q3(Z,K),!0}function d$($){let Z=V1($),K=j4($);if(!a1(K))return!1;return m$(c$(Z),{recursive:!0}),q3(K,Z),!0}function i0($){let Z=V1($),K=a0($);U3($);let X=W1($),Y=`bun run "${K.replace(/\\/g,"/")}"`;if(X.hooks=X.hooks??{},X.hooks.SessionEnd?.some((G)=>G.hooks.some((_)=>_.command.includes(i1)||_.command.includes(r1))))return{success:!0,message:"Hooks already installed"};return X.hooks.SessionEnd=X.hooks.SessionEnd??[],X.hooks.SessionEnd.push({hooks:[{type:"command",command:Y,timeout:5}]}),X.hooks.PreCompact=X.hooks.PreCompact??[],X.hooks.PreCompact.push({matcher:"auto",hooks:[{type:"command",command:Y,timeout:5}]}),m$(c$(Z),{recursive:!0}),O3(Z,JSON.stringify(X,null,2)+`
|
|
4
|
+
`),{success:!0,message:"Hooks installed successfully"}}function r0($){let Z=V1($),K=W1($);if(!K.hooks)return{success:!0,message:"No hooks to uninstall"};if(K.hooks.SessionEnd){if(K.hooks.SessionEnd=K.hooks.SessionEnd.filter((X)=>!X.hooks.some((Y)=>Y.command.includes(i1)||Y.command.includes(r1))),K.hooks.SessionEnd.length===0)delete K.hooks.SessionEnd}if(K.hooks.PreCompact){if(K.hooks.PreCompact=K.hooks.PreCompact.filter((X)=>!X.hooks.some((Y)=>Y.command.includes(i1)||Y.command.includes(r1))),K.hooks.PreCompact.length===0)delete K.hooks.PreCompact}if(Object.keys(K.hooks).length===0)delete K.hooks;return O3(Z,JSON.stringify(K,null,2)+`
|
|
5
|
+
`),{success:!0,message:"Hooks uninstalled successfully"}}function F0($){let Z=W1($),K=a0($),X=j4($);return{sessionEnd:Z.hooks?.SessionEnd?.some((Y)=>Y.hooks.some((Q)=>Q.command.includes(i1)||Q.command.includes(r1)))??!1,preCompact:Z.hooks?.PreCompact?.some((Y)=>Y.hooks.some((Q)=>Q.command.includes(i1)||Q.command.includes(r1)))??!1,hookScriptExists:a1(K),backupExists:a1(X)}}var i1="memory",r1="memory-nexus";var p$=L(()=>{l()});import{copyFileSync as h6,cpSync as g6,existsSync as Y0,mkdirSync as n$,readdirSync as m6,renameSync as c6,rmSync as a$,statSync as x4,unlinkSync as i$}from"fs";import{join as v0}from"path";function I3(){let $=Y0(m1()),Z=Y0(S0())||Y0(a()),K;if(!$&&!Z)K="not-needed";else if($&&!Z)K="pending";else if(!$&&Z)K="complete";else K="partial";return{legacyExists:$,newExists:Z,status:K}}function T3(){let $=m1();if(!Y0($))return!1;let Z=v0($,"memory.db");if(!Y0(Z))return!1;let K=J1();if(!Y0(K))return!0;let X=x4(Z).size,Y=x4(K).size;return X>Y}function l$($){for(let Z of["-wal","-shm"]){let K=$+Z;if(Y0(K))i$(K)}}function u6($,Z){for(let K of Z)if(K.isDir&&Y0(K.source)&&Y0(K.dest))try{a$(K.source,{recursive:!0})}catch{}try{if(m6($).length===0)a$($,{recursive:!0})}catch{}}function R3(){let $=m1();if(!Y0($))return{migrated:!1,itemsMoved:[],errors:[]};let Z=[{name:"memory.db",source:v0($,"memory.db"),dest:J1(),isDir:!1},{name:"config.json",source:v0($,"config.json"),dest:u1(),isDir:!1},{name:"sync-checkpoint.json",source:v0($,"sync-checkpoint.json"),dest:l1(),isDir:!1},{name:"logs",source:v0($,"logs"),dest:X0(),isDir:!0},{name:"hooks",source:v0($,"hooks"),dest:d1(),isDir:!0},{name:"backups",source:v0($,"backups"),dest:p1(),isDir:!0}];try{n$(S0(),{recursive:!0}),n$(a(),{recursive:!0})}catch(Q){let G=A(Q);return{migrated:!1,itemsMoved:[],errors:[`Failed to create target directories: ${G}`]}}let K=[],X=[];for(let Q of Z){if(!Y0(Q.source))continue;if(Y0(Q.dest)){if(Q.isDir)continue;let G=x4(Q.source).size;if(x4(Q.dest).size>=G){if(i$(Q.source),Q.source.endsWith(".db"))l$(Q.source);X.push(Q.name);continue}if(Q.dest.endsWith(".db"))l$(Q.dest)}try{if(L3(Q.source,Q.dest,Q.isDir),K.push({item:Q,rolledBack:!1}),X.push(Q.name),Q.source.endsWith(".db"))l$(Q.source)}catch(G){let _=A(G),J=[`Failed to move ${Q.name}: ${_}`];for(let H=K.length-1;H>=0;H--){let V=K[H];try{L3(V.item.dest,V.item.source,V.item.isDir),V.rolledBack=!0}catch(B){let z=A(B);J.push(`Rollback failed for ${V.item.name}: ${z}`)}}return{migrated:!1,itemsMoved:[],errors:J}}}if(X.length===0)return{migrated:!1,itemsMoved:[],errors:[]};let Y=[];try{r0(),i0()}catch(Q){let G=A(Q);Y.push(`hook re-install failed: ${G}`)}return u6($,Z),process.stderr.write(`Migrated data from ~/.memory-nexus to new paths
|
|
6
|
+
`),{migrated:!0,itemsMoved:X,errors:Y}}function L3($,Z,K){let X=v0(Z,"..");n$(X,{recursive:!0});try{c6($,Z)}catch(Y){if(Y.code==="EXDEV")if(K)g6($,Z,{recursive:!0}),a$($,{recursive:!0});else h6($,Z),i$($);else throw Y}}var r$=L(()=>{l();p$()});class O0{_id;_projectPath;_startTime;_endTime;_messages;_summary;_messageCount;constructor($){this._id=$.id,this._projectPath=$.projectPath,this._startTime=new Date($.startTime.getTime()),this._endTime=$.endTime?new Date($.endTime.getTime()):void 0,this._messages=Object.freeze([...$.messages??[]]),this._summary=$.summary,this._messageCount=$.messageCount}static create($){if(!$.id||$.id.trim()==="")throw Error("Session ID cannot be empty");if($.endTime&&$.endTime<$.startTime)throw Error("End time cannot be before start time");return new O0($)}get id(){return this._id}get projectPath(){return this._projectPath}get startTime(){return new Date(this._startTime.getTime())}get endTime(){return this._endTime?new Date(this._endTime.getTime()):void 0}get messages(){return[...this._messages]}get summary(){return this._summary}get messageCount(){return this._messageCount??this._messages.length}get durationMs(){if(!this._endTime)return;return this._endTime.getTime()-this._startTime.getTime()}equals($){return this._id===$._id}addMessage($){return new O0({id:this._id,projectPath:this._projectPath,startTime:this._startTime,endTime:this._endTime,messages:[...this._messages,$],summary:this._summary})}complete($){if($<this._startTime)throw Error("End time cannot be before start time");return new O0({id:this._id,projectPath:this._projectPath,startTime:this._startTime,endTime:$,messages:[...this._messages],summary:this._summary,messageCount:this._messageCount})}withSummary($){return new O0({id:this._id,projectPath:this._projectPath,startTime:this._startTime,endTime:this._endTime,messages:[...this._messages],summary:$,messageCount:this._messageCount})}}class J0{_id;_role;_content;_timestamp;_toolUseIds;constructor($){this._id=$.id,this._role=$.role,this._content=$.content,this._timestamp=new Date($.timestamp.getTime()),this._toolUseIds=Object.freeze([...$.toolUseIds??[]])}static create($){if(!$.id||$.id.trim()==="")throw Error("Message ID cannot be empty");if(!d6.includes($.role))throw Error("Invalid message role");return new J0($)}get id(){return this._id}get role(){return this._role}get content(){return this._content}get timestamp(){return new Date(this._timestamp.getTime())}get toolUses(){return[...this._toolUseIds]}get hasContent(){return this._content.length>0}get hasToolUses(){return this._toolUseIds.length>0}equals($){return this._id===$._id}addToolUse($){return new J0({id:this._id,role:this._role,content:this._content,timestamp:this._timestamp,toolUseIds:[...this._toolUseIds,$]})}}var d6;var o1=L(()=>{d6=["user","assistant"]});class U0{_id;_name;_input;_timestamp;_status;_result;constructor($){this._id=$.id,this._name=$.name,this._input=structuredClone($.input),this._timestamp=new Date($.timestamp.getTime()),this._status=$.status??"pending",this._result=$.result}static create($){if(!$.id||$.id.trim()==="")throw Error("Tool use ID cannot be empty");if(!$.name||$.name.trim()==="")throw Error("Tool name cannot be empty");if($.status&&!p6.includes($.status))throw Error("Invalid tool use status");return new U0($)}get id(){return this._id}get name(){return this._name}get input(){return structuredClone(this._input)}get timestamp(){return new Date(this._timestamp.getTime())}get status(){return this._status}get result(){return this._result}get isPending(){return this._status==="pending"}get isSuccess(){return this._status==="success"}get isError(){return this._status==="error"}equals($){return this._id===$._id}completeSuccess($){return new U0({id:this._id,name:this._name,input:this._input,timestamp:this._timestamp,status:"success",result:$})}completeError($){return new U0({id:this._id,name:this._name,input:this._input,timestamp:this._timestamp,status:"error",result:$})}}var p6;var E4=L(()=>{p6=["pending","success","error"]});class Q0{_id;_sessionPath;_startedAt;_status;_completedAt;_messagesExtracted;_errorMessage;_fileMtime;_fileSize;constructor($){this._id=$.id,this._sessionPath=$.sessionPath,this._startedAt=new Date($.startedAt.getTime()),this._status=$.status??"pending",this._completedAt=$.completedAt?new Date($.completedAt.getTime()):void 0,this._messagesExtracted=$.messagesExtracted??0,this._errorMessage=$.errorMessage,this._fileMtime=$.fileMtime?new Date($.fileMtime.getTime()):void 0,this._fileSize=$.fileSize}static create($){if(!$.id||$.id.trim()==="")throw Error("Extraction state ID cannot be empty");if(!$.sessionPath||$.sessionPath.trim()==="")throw Error("Session path cannot be empty");if($.status&&!l6.includes($.status))throw Error("Invalid extraction status");if($.messagesExtracted!==void 0&&$.messagesExtracted<0)throw Error("Messages extracted cannot be negative");if($.fileSize!==void 0&&$.fileSize<0)throw Error("File size cannot be negative");return new Q0($)}get id(){return this._id}get sessionPath(){return this._sessionPath}get startedAt(){return new Date(this._startedAt.getTime())}get status(){return this._status}get completedAt(){return this._completedAt?new Date(this._completedAt.getTime()):void 0}get messagesExtracted(){return this._messagesExtracted}get errorMessage(){return this._errorMessage}get fileMtime(){return this._fileMtime?new Date(this._fileMtime.getTime()):void 0}get fileSize(){return this._fileSize}get isPending(){return this._status==="pending"}get isInProgress(){return this._status==="in_progress"}get isComplete(){return this._status==="complete"}get isError(){return this._status==="error"}get durationMs(){if(!this._completedAt)return;return this._completedAt.getTime()-this._startedAt.getTime()}equals($){return this._id===$._id}startProcessing(){return new Q0({id:this._id,sessionPath:this._sessionPath,startedAt:this._startedAt,status:"in_progress",messagesExtracted:this._messagesExtracted,fileMtime:this._fileMtime,fileSize:this._fileSize})}complete($){return new Q0({id:this._id,sessionPath:this._sessionPath,startedAt:this._startedAt,status:"complete",completedAt:$,messagesExtracted:this._messagesExtracted,fileMtime:this._fileMtime,fileSize:this._fileSize})}fail($){return new Q0({id:this._id,sessionPath:this._sessionPath,startedAt:this._startedAt,status:"error",errorMessage:$,messagesExtracted:this._messagesExtracted,fileMtime:this._fileMtime,fileSize:this._fileSize})}incrementMessages($=1){return new Q0({id:this._id,sessionPath:this._sessionPath,startedAt:this._startedAt,status:this._status,completedAt:this._completedAt,messagesExtracted:this._messagesExtracted+$,errorMessage:this._errorMessage,fileMtime:this._fileMtime,fileSize:this._fileSize})}withFileMetadata($,Z){if(Z<0)throw Error("File size cannot be negative");return new Q0({id:this._id,sessionPath:this._sessionPath,startedAt:this._startedAt,status:this._status,completedAt:this._completedAt,messagesExtracted:this._messagesExtracted,errorMessage:this._errorMessage,fileMtime:$,fileSize:Z})}}var l6;var P4=L(()=>{l6=["pending","in_progress","complete","error"]});var F;var F3=L(()=>{F={DB_CONNECTION_FAILED:"DB_CONNECTION_FAILED",DB_CORRUPTED:"DB_CORRUPTED",DB_LOCKED:"DB_LOCKED",INVALID_SESSION_ID:"INVALID_SESSION_ID",SESSION_NOT_FOUND:"SESSION_NOT_FOUND",SOURCE_INACCESSIBLE:"SOURCE_INACCESSIBLE",DISK_FULL:"DISK_FULL",INVALID_JSON:"INVALID_JSON",UNKNOWN_FORMAT:"UNKNOWN_FORMAT",SYNC_INTERRUPTED:"SYNC_INTERRUPTED",SYNC_FAILED:"SYNC_FAILED",INVALID_ARGUMENT:"INVALID_ARGUMENT",MISSING_ARGUMENT:"MISSING_ARGUMENT",VECTOR_UNAVAILABLE:"VECTOR_UNAVAILABLE",PROVIDER_TIMEOUT:"PROVIDER_TIMEOUT",PROVIDER_CONFIG_INVALID:"PROVIDER_CONFIG_INVALID",EMBEDDING_DIMENSION_MISMATCH:"EMBEDDING_DIMENSION_MISMATCH",MODEL_CORRUPTED:"MODEL_CORRUPTED",NOT_FOUND:"NOT_FOUND",INVALID_STATE:"INVALID_STATE",UNKNOWN:"UNKNOWN"}});var j;var M3=L(()=>{j=class j extends Error{code;context;constructor($,Z,K){super(Z);if(this.name="MemoryError",this.code=$,this.context=K,Error.captureStackTrace)Error.captureStackTrace(this,j)}toJSON(){let $={error:{code:this.code,message:this.message}};if(this.context&&Object.keys(this.context).length>0)$.error.context=this.context;return $}}});var H0=L(()=>{F3();M3()});var t1=()=>{};var t$=L(()=>{t1()});var j3={};y(j3,{computeModelHash:()=>s$,EmbeddingService:()=>e$});import{createHash as a6}from"crypto";function s$($){let Z=`${$.provider}:${$.model}:${$.dimensions}`;return a6("sha256").update(Z).digest("hex").slice(0,16)}class e${repository;provider;batchSize;modelHash;modelName;redactor;constructor($){this.repository=$.repository,this.provider=$.provider,this.batchSize=$.config.batchSize,this.modelHash=s$($.config),this.modelName=$.config.model,this.redactor=$.redactor??i6}checkModelState(){let $=this.repository.getStoredModelHash(),Z=this.modelHash,K=this.modelName;if($===null)return{modelChanged:!1,needsReEmbed:!1,currentHash:Z,currentModelName:K};if($===Z)return{modelChanged:!1,needsReEmbed:!1,currentHash:Z,currentModelName:K};let X=this.repository.getStoredModelName()??$;return{modelChanged:!0,needsReEmbed:!0,storedHash:$,currentHash:Z,storedModelName:X,currentModelName:K,embeddedCount:this.repository.getEmbeddedCount()}}async embedUnembedded($={}){let Z=Date.now(),K=0,X=this.repository.getTotalMessageCount()-this.repository.getEmbeddedCount();if(X<=0)return{embedded:0,skipped:0,durationMs:0,rate:0};let Y=this.repository.findUnembedded(this.batchSize);while(Y.length>0){let _=Y.map((V)=>this.redactor.redactText(V.content).text),J=await this.provider.embedBatch(_),H=Y.map((V,B)=>({rowid:V.rowid,embedding:J[B].embedding}));this.repository.storeBatch(H,this.modelHash,this.modelName),K+=Y.length,$.onProgress?.({current:K,total:X}),Y=this.repository.findUnembedded(this.batchSize)}let Q=Date.now()-Z,G=Q>0?K/(Q/1000):0;return{embedded:K,skipped:0,durationMs:Q,rate:G}}async clearAndReembed($={}){return this.repository.clearAllEmbeddings(),this.embedUnembedded($)}}var i6;var $9=L(()=>{i6={redactText:($)=>({text:$,findings:[]}),redactJson:($)=>({value:$,findings:[]})}});function Y9($,Z,K){let X=new Map;for(let Q of $){let G=X.get(Q.rowid)??{rowid:Q.rowid,rrfScore:0,normalizedScore:0,sources:[]};G.rrfScore+=1/(60+Q.rank),G.sources.push({source:"fts",rank:Q.rank,rawScore:Q.rawScore}),X.set(Q.rowid,G)}for(let Q of Z){let G=X.get(Q.rowid)??{rowid:Q.rowid,rrfScore:0,normalizedScore:0,sources:[]};G.rrfScore+=1/(60+Q.rank),G.sources.push({source:"vector",rank:Q.rank,rawScore:Q.rawScore}),X.set(Q.rowid,G)}let Y=Array.from(X.values()).sort((Q,G)=>G.rrfScore-Q.rrfScore);if(Y=Y.filter((Q)=>Q.rrfScore>=0.001),Y=Y.slice(0,K),Y.length>0){let Q=Y[0].rrfScore;if(Q>0)for(let G of Y)G.normalizedScore=G.rrfScore/Q}return Y}function o0($){let Z=($.match(/"/g)||[]).length,K=Z>0&&Z%2===0,X;if(K)X=$.replace(/[.:\-()[\]{}^~@/\\]/gu," ").replace(/\s+/g," ").trim();else X=$.replace(/[.:\-()[\]{}^"~@/\\]/gu," ").replace(/\s+/g," ").trim();if(X)return X;let Y=($.match(/"/g)||[]).length,G=Y>0&&Y%2===0?/[.:\-()[\]{}^~@/\\]/gu:/[.:\-()[\]{}^"~@/\\]/gu;return $.replace(G," ").replace(/\s+/g," ").trim()}class t0{_id;_filePath;_fileType;_projectEncoded;_content;_contentHash;_lastIndexedAt;_createdAt;constructor($){this._id=$.id,this._filePath=$.filePath,this._fileType=$.fileType,this._projectEncoded=$.projectEncoded,this._content=$.content,this._contentHash=$.contentHash,this._lastIndexedAt=new Date($.lastIndexedAt.getTime()),this._createdAt=$.createdAt?new Date($.createdAt.getTime()):new Date}static create($){if(!$.filePath||$.filePath.trim()==="")throw Error("File path cannot be empty");if(!$.content||$.content.trim()==="")throw Error("Content cannot be empty");if(!t6.test($.contentHash))throw Error("Content hash must be 64 hexadecimal characters");if(!E3.includes($.fileType))throw Error(`Invalid file type: "${$.fileType}". Must be one of: ${E3.join(", ")}`);return new t0($)}get id(){return this._id}get filePath(){return this._filePath}get fileType(){return this._fileType}get projectEncoded(){return this._projectEncoded}get content(){return this._content}get contentHash(){return this._contentHash}get lastIndexedAt(){return new Date(this._lastIndexedAt.getTime())}get createdAt(){return new Date(this._createdAt.getTime())}}var E3,t6;var S4=L(()=>{E3=["daily_log","decisions","learnings","user_prefs"],t6=/^[a-f0-9]{64}$/});class C0{_id;_description;_severity;_category;_status;_tool;_tags;_lastReviewedAt;_context;_sourceProject;_loggedAt;_resolvedAt;_resolution;constructor($){this._id=$.id,this._description=$.description.trim(),this._severity=$.severity,this._category=$.category,this._status=$.status,this._tool=$.tool,this._tags=$.tags?[...$.tags]:void 0,this._lastReviewedAt=$.lastReviewedAt?new Date($.lastReviewedAt.getTime()):void 0,this._context=$.context,this._sourceProject=$.sourceProject,this._loggedAt=new Date($.loggedAt.getTime()),this._resolvedAt=$.resolvedAt?new Date($.resolvedAt.getTime()):void 0,this._resolution=$.resolution}static create($){if(!$.description||$.description.trim()==="")throw Error("Description cannot be empty");if(!P3.includes($.severity))throw Error(`Invalid severity: "${$.severity}". Must be one of: ${P3.join(", ")}`);if(!$.category||$.category.trim()==="")throw Error("Category cannot be empty");if(!D3.includes($.status))throw Error(`Invalid status: "${$.status}". Must be one of: ${D3.join(", ")}`);if(!$.tool||$.tool.trim()==="")throw Error("Tool cannot be empty");if($.status==="open"&&$.resolvedAt)throw Error("Open entries cannot have a resolvedAt date");return new C0($)}get id(){return this._id}get description(){return this._description}get severity(){return this._severity}get category(){return this._category}get status(){return this._status}get tool(){return this._tool}get tags(){return this._tags?[...this._tags]:void 0}get lastReviewedAt(){return this._lastReviewedAt?new Date(this._lastReviewedAt.getTime()):void 0}get context(){return this._context}get sourceProject(){return this._sourceProject}get loggedAt(){return new Date(this._loggedAt.getTime())}get resolvedAt(){return this._resolvedAt?new Date(this._resolvedAt.getTime()):void 0}get resolution(){return this._resolution}}var P3,D3;var C4=L(()=>{P3=["low","medium","high","critical"],D3=["open","resolved","wont-fix"]});class y0{_sessionId;_backfilledAt;_dailyLogPath;_success;_errorMessage;constructor($){this._sessionId=$.sessionId,this._backfilledAt=new Date($.backfilledAt.getTime()),this._dailyLogPath=$.dailyLogPath,this._success=$.success??!0,this._errorMessage=$.errorMessage}static create($){if(!$.sessionId||$.sessionId.trim()==="")throw Error("Session ID cannot be empty");if(!$.dailyLogPath||$.dailyLogPath.trim()==="")throw Error("Daily log path cannot be empty");return new y0($)}get sessionId(){return this._sessionId}get backfilledAt(){return new Date(this._backfilledAt.getTime())}get dailyLogPath(){return this._dailyLogPath}get success(){return this._success}get errorMessage(){return this._errorMessage}get isSuccess(){return this._success}}var k3={};y(k3,{BackfillService:()=>Q9});class Q9{sessionRepo;messageRepo;backfillStateRepo;summaryGenerator;dailyLogWriter;constructor($,Z,K,X,Y){this.sessionRepo=$;this.messageRepo=Z;this.backfillStateRepo=K;this.summaryGenerator=X;this.dailyLogWriter=Y}async dryRun($={}){let Z=await this.getUnprocessedSessions($.project);return{unprocessedCount:Z.length,estimatedCost:Z.length*Z7}}async backfill($={}){let{batch:Z=50,project:K,onProgress:X}=$,Q=(await this.getUnprocessedSessions(K)).slice(0,Z),G={sessionsProcessed:0,sessionsFailed:0,sessionsSkipped:0,dailyLogsCreated:0,dailyLogsUpdated:0,errors:[]};for(let _=0;_<Q.length;_++){let J=Q[_];if(!J)continue;if(await this.backfillStateRepo.findBySessionId(J.id)){G.sessionsSkipped++,X?.({current:_+1,total:Q.length,sessionId:J.id,action:"skipped"});continue}try{X?.({current:_+1,total:Q.length,sessionId:J.id,action:"processing"});let V=await this.extractContent(J.id),B=J.projectPath.decoded,z=B.split(/[/\\]/).filter(Boolean).pop()??B,W=await this.summaryGenerator.generateSummary(V,J.id,z,J.startTime.toISOString(),J.endTime?.toISOString()??J.startTime.toISOString()),q=`daily/${J.startTime.toISOString().slice(0,10)}.md`;if(await this.dailyLogWriter.writeOrAppend(q,W+`
|
|
7
|
+
|
|
8
|
+
`))G.dailyLogsCreated++;else G.dailyLogsUpdated++;await this.backfillStateRepo.save(y0.create({sessionId:J.id,backfilledAt:new Date,dailyLogPath:q,success:!0})),G.sessionsProcessed++}catch(V){let B=A(V);G.sessionsFailed++,G.errors.push({sessionId:J.id,error:B});let z=J.startTime.toISOString().slice(0,10);await this.backfillStateRepo.save(y0.create({sessionId:J.id,backfilledAt:new Date,dailyLogPath:`daily/${z}.md`,success:!1,errorMessage:B})),X?.({current:_+1,total:Q.length,sessionId:J.id,action:"error"})}}return G}async getUnprocessedSessions($){let Z=await this.sessionRepo.findFiltered({projectFilter:$,limit:1e4}),K=[];for(let X of Z)if(!await this.backfillStateRepo.findBySessionId(X.id))K.push(X);return K.sort((X,Y)=>X.startTime.getTime()-Y.startTime.getTime()),K}async extractContent($){let K=(await this.messageRepo.findBySession($)).filter((Y)=>Y.role==="user"||Y.role==="assistant"),X="";for(let Y of K){let G=`${Y.role==="user"?"User":"Assistant"}: ${Y.content}
|
|
9
|
+
|
|
10
|
+
`;if(X.length+G.length>K7){X+=`... [content truncated]
|
|
11
|
+
`;break}X+=G}return X}}var Z7=0.001,K7=16000;var G9=()=>{};function _9($,Z,K=4){if(Z<=0){let H=$.map((B)=>({...B,truncatedContent:B.content,allocated:B.content.length===0?0:Math.ceil(B.content.length/K),truncated:!1})),V=H.reduce((B,z)=>B+z.allocated,0);return{sections:H,totalTokensUsed:V,budgetExceeded:!1}}let X=Z*K,Y=[...$].sort((H,V)=>H.priority-V.priority),Q=X,G=[],_=!1;for(let H of Y){if(H.content.length===0){G.push({...H,truncatedContent:"",allocated:0,truncated:!1});continue}if(Q<=0){G.push({...H,truncatedContent:"",allocated:0,truncated:!0}),_=!0;continue}let V=H.content.length;if(V<=Q){let B=Math.ceil(V/K);G.push({...H,truncatedContent:H.content,allocated:B,truncated:!1}),Q-=V}else{let B=H.content.slice(0,Q),z=Math.ceil(Q/K);G.push({...H,truncatedContent:B,allocated:z,truncated:!0}),Q=0,_=!0}}let J=G.reduce((H,V)=>H+V.allocated,0);return{sections:G,totalTokensUsed:J,budgetExceeded:_}}var S3={};y(S3,{SmartContextService:()=>e1});function Y7($){if($.length===0)return 0;return Math.ceil($.length/X7)}function Q7($){return`#${$.id} (${$.severity}/${$.category}): ${$.description}`}class e1{projectResolver;factRepo;frictionRepo;getSessionSummary;constructor($){if(this.projectResolver=$.projectResolver,this.factRepo=$.factRepo,this.frictionRepo=$.frictionRepo,$.getSessionSummary)this.getSessionSummary=$.getSessionSummary}async getContext($){let Z=this.projectResolver.resolveProjectEncoded($.projectFilter),K=this.projectResolver.resolveProjectName($.projectFilter);if(!Z||!K)return null;let Y=(await this.factRepo.findByProject(K)).filter((W)=>W.supersededAt===null),Q=(W)=>{return W.map((N)=>`- ${N.content}`).join(`
|
|
12
|
+
`)},G=[],_=Y.filter((W)=>W.type==="decision");if(_.length>0)G.push(this.buildSection("decisions","Active Decisions",1,Q(_)));let J=Y.filter((W)=>W.type==="learning");if(J.length>0)G.push(this.buildSection("learnings","Recent Learnings",2,Q(J)));let H=Y.filter((W)=>W.type==="preference");if(H.length>0)G.push(this.buildSection("preferences","User Preferences",3,Q(H)));let V=Y.filter((W)=>W.type==="observation");if(V.length>0)G.push(this.buildSection("observations","Observations",4,Q(V)));if($.crossProject){let N=(await this.factRepo.findAll()).filter((U)=>U.supersededAt===null&&U.project!==K),q=N.filter((U)=>U.type==="preference");if(q.length>0)G.push(this.buildSection("cross_project_preferences","Global/Cross-Project User Preferences",5,Q(q)));let I=N.filter((U)=>U.type==="decision");if(I.length>0)G.push(this.buildSection("cross_project_decisions","Cross-Project Decisions",6,Q(I)));let T=N.filter((U)=>U.type==="learning");if(T.length>0)G.push(this.buildSection("cross_project_learnings","Cross-Project Learnings",7,Q(T)))}let B=await this.buildFrictionContent($.projectFilter);if(B)G.push(this.buildSection("friction","Open Friction",8,B));if(this.getSessionSummary){let W=await this.getSessionSummary($.projectFilter,$.days);if(W)G.push(this.buildSection("session_summary","Session Summary",9,W))}if($.budget&&$.budget>0)return this.applyBudget(K,Z,G,$.budget);let z=G.reduce((W,N)=>W+N.tokenEstimate,0);return{projectName:K,projectEncoded:Z,sections:G,totalTokensEstimate:z,truncated:!1}}buildSection($,Z,K,X){return{key:$,title:Z,priority:K,content:X,truncated:!1,tokenEstimate:Y7(X)}}async buildFrictionContent($){let Z=await this.frictionRepo.findOpen();if(Z.length===0)return null;let K=Z.filter((Y)=>Y.description.includes($)||Y.context&&Y.context.includes($));return(K.length>0?K:Z).map(Q7).join(`
|
|
13
|
+
`)}applyBudget($,Z,K,X){let Y=K.map((_)=>({key:_.key,priority:_.priority,content:_.content})),Q=_9(Y,X),G=Q.sections.map((_)=>{let J=K.find((H)=>H.key===_.key);return{key:_.key,title:J.title,priority:_.priority,content:_.truncatedContent,truncated:_.truncated,tokenEstimate:_.allocated}});return{projectName:$,projectEncoded:Z,sections:G,totalTokensEstimate:Q.totalTokensUsed,truncated:Q.budgetExceeded}}}var X7=4;var w4=()=>{};var v3={};y(v3,{AmbientContextService:()=>J9});class J9{smartContext;contextWriter;formatter;constructor($,Z,K){this.smartContext=$;this.contextWriter=Z;this.formatter=K}async generateAmbientContext($){let Z=await this.smartContext.getContext({projectFilter:$.projectName,budget:$.budget,crossProject:!0});if(Z===null)return{success:!1,reason:"project-not-found"};if(Z.sections.length===0)return{success:!1,reason:"no-context"};let K=this.formatter.formatSmartContext(Z),X=this.buildSummaryBlock(Z);return await this.contextWriter.writeContextFile($.autoMemoryDir,K),await this.contextWriter.updateMemoryBlock($.autoMemoryDir,X),{success:!0,contextTokens:Z.totalTokensEstimate}}buildSummaryBlock($){let Z=this.countSectionLines($.sections,"decisions"),K=this.countSectionLines($.sections,"learnings"),X=this.countSectionLines($.sections,"friction"),Y=new Date().toISOString().split("T")[0];return["## Cross-Project Context",`Run \`memory context ${$.projectName}\` for full briefing. See [context.md](context.md) for latest snapshot.`,`- ${Z} active decisions, ${K} learnings`,`- Open friction: ${X}`,`- Last synced: ${Y}`].join(`
|
|
14
|
+
`)}countSectionLines($,Z){let K=$.find((X)=>X.key===Z);if(!K||!K.content)return 0;return K.content.split(`
|
|
15
|
+
`).filter((X)=>X.trim().length>0).length}}var y3={};y(y3,{trackDownloadTotal:()=>V7,isUnicodeSupported:()=>C3,getBarCharacters:()=>b4,createProgressReporter:()=>z9,createModelDownloadHandler:()=>W7,createEmbeddingProgressReporter:()=>H7,TtyProgressReporter:()=>V9,TtyEmbeddingProgressReporter:()=>A9,QuietProgressReporter:()=>B9,QuietEmbeddingProgressReporter:()=>q9,PlainProgressReporter:()=>W9,PlainEmbeddingProgressReporter:()=>N9});import H9 from"cli-progress";function C3(){let{env:$}=process;if(process.platform!=="win32")return $.TERM!=="linux";return Boolean($.MSYSTEM)||Boolean($.WT_SESSION)||Boolean($.TERMINUS_SUBLIME)||$.ConEmuTask==="{cmd::Cmder}"||$.TERM_PROGRAM==="vscode"||$.TERM==="xterm-256color"||$.TERM==="alacritty"||$.TERMINAL_EMULATOR==="JetBrains-JediTerm"}function b4(){return C3()?_7:J7}class V9{bar;verbose;total=0;currentValue=0;constructor($=!1){this.verbose=$;let Z=b4();this.bar=new H9.SingleBar({format:"Syncing |{bar}| {percentage}% | {value}/{total} sessions",barCompleteChar:Z.complete,barIncompleteChar:Z.incomplete,hideCursor:!0})}start($){this.total=$,this.currentValue=0,this.bar.start($,0)}update($,Z){if(this.currentValue=$,this.bar.update($),this.verbose)this.bar.stop(),console.log(` Processing: ${Z}`),this.bar.start(this.total,$)}stop(){this.bar.stop()}log($){if(this.verbose)this.bar.stop(),console.log($),this.bar.start(this.total,this.currentValue)}}class W9{verbose;constructor($=!1){this.verbose=$}start($){console.log(`Processing ${$} sessions...`)}update($,Z){if(this.verbose)console.log(` [${$}] Processing: ${Z}`)}stop(){console.log("Done.")}log($){if(this.verbose)console.log($)}}class B9{start($){}update($,Z){}stop(){}log($){}}function z9($){if($.quiet)return new B9;if(!process.stdout.isTTY)return new W9($.verbose);return new V9($.verbose)}class A9{bar;constructor(){let $=b4();this.bar=new H9.SingleBar({format:"Embedding |{bar}| {percentage}% | {value}/{total} messages | ETA: {eta_formatted}",barCompleteChar:$.complete,barIncompleteChar:$.incomplete,hideCursor:!0,etaBuffer:20})}start($){this.bar.start($,0)}update($){this.bar.update($)}stop(){this.bar.stop()}}class N9{start($){console.log(`Embedding ${$} messages...`)}update($){}stop(){console.log("Done.")}}class q9{start($){}update($){}stop(){}}function H7($){if($.quiet)return new q9;if(!process.stdout.isTTY)return new N9;return new A9}function V7($,Z){let K=Math.round(Z/1048576);return K>$?K:$}function W7($){if($.quiet||!process.stdout.isTTY){let Q=!1;return(G)=>{if(!Q&&G.status==="downloading"&&!$.quiet)console.log("Downloading embedding model (one-time setup)..."),Q=!0}}let Z=b4(),K=new H9.SingleBar({format:"Downloading model |{bar}| {percentage}% | {value}/{total} MB",barCompleteChar:Z.complete,barIncompleteChar:Z.incomplete,hideCursor:!0}),X=!1,Y=0;return(Q)=>{if(Q.status==="downloading"){let G=Math.round(Q.loaded/1048576),_=Math.round(Q.total/1048576);if(_>Y)Y=_;if(!X&&Y>0)K.start(Y,G),X=!0;else if(X){if(_>0&&K.getTotal()!==Y)K.setTotal(Y);K.update(G)}}else if(Q.status==="ready"&&X)K.stop()}}var _7,J7;var O9=L(()=>{_7={complete:"\u2588",incomplete:"\u2591"},J7={complete:"#",incomplete:"-"}});function $4($){try{return $.exec("CREATE VIRTUAL TABLE _fts5_check USING fts5(test)"),$.exec("DROP TABLE _fts5_check"),!0}catch{return!1}}function f4($,Z){let{sqliteVecAvailable:K=!1}=Z??{};if(!$4($))throw Error("FTS5 extension is not available. Ensure you are using Bun with FTS5 support enabled.");try{let Q=$.prepare("PRAGMA table_info(friction_log)").all();if(!Q.some((_)=>_.name==="tool")&&Q.length>0)$.exec(`
|
|
16
|
+
CREATE TABLE friction_log_new (
|
|
17
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
18
|
+
description TEXT NOT NULL,
|
|
19
|
+
severity TEXT NOT NULL DEFAULT 'medium' CHECK (severity IN ('low', 'medium', 'high', 'critical')),
|
|
20
|
+
category TEXT NOT NULL DEFAULT 'cli',
|
|
21
|
+
tool TEXT NOT NULL DEFAULT 'memory',
|
|
22
|
+
tags TEXT,
|
|
23
|
+
status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'resolved', 'wont-fix')),
|
|
24
|
+
context TEXT,
|
|
25
|
+
source_project TEXT,
|
|
26
|
+
logged_at TEXT NOT NULL,
|
|
27
|
+
resolved_at TEXT,
|
|
28
|
+
resolution TEXT,
|
|
29
|
+
last_reviewed_at TEXT
|
|
30
|
+
);
|
|
31
|
+
INSERT INTO friction_log_new (id, description, severity, category, tool, tags, status, context, source_project, logged_at, resolved_at, resolution, last_reviewed_at)
|
|
32
|
+
SELECT id, description, severity, category, 'memory', NULL, status, context, source_project, logged_at, resolved_at, resolution, NULL
|
|
33
|
+
FROM friction_log;
|
|
34
|
+
DROP TABLE friction_log;
|
|
35
|
+
ALTER TABLE friction_log_new RENAME TO friction_log;
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_friction_status ON friction_log(status);
|
|
37
|
+
CREATE INDEX IF NOT EXISTS idx_friction_severity ON friction_log(severity);
|
|
38
|
+
CREATE INDEX IF NOT EXISTS idx_friction_category ON friction_log(category);
|
|
39
|
+
CREATE INDEX IF NOT EXISTS idx_friction_tool ON friction_log(tool);
|
|
40
|
+
`)}catch{}for(let Q of U9)$.exec(Q);if(!$.prepare("PRAGMA table_info(embedding_state)").all().some((Q)=>Q.name==="model_name"))$.exec(`
|
|
41
|
+
ALTER TABLE embedding_state ADD COLUMN model_name TEXT NOT NULL DEFAULT '';
|
|
42
|
+
`);if(K)$.exec(`
|
|
43
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS message_embeddings USING vec0(
|
|
44
|
+
embedding float[384]
|
|
45
|
+
);
|
|
46
|
+
`)}var w3=`
|
|
47
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
48
|
+
id TEXT PRIMARY KEY,
|
|
49
|
+
project_path_encoded TEXT NOT NULL,
|
|
50
|
+
project_path_decoded TEXT NOT NULL,
|
|
51
|
+
project_name TEXT NOT NULL,
|
|
52
|
+
start_time TEXT NOT NULL,
|
|
53
|
+
end_time TEXT,
|
|
54
|
+
message_count INTEGER DEFAULT 0,
|
|
55
|
+
summary TEXT,
|
|
56
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
57
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
58
|
+
);
|
|
59
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_path_encoded);
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_start_time ON sessions(start_time);
|
|
61
|
+
`,b3=`
|
|
62
|
+
CREATE TABLE IF NOT EXISTS messages_meta (
|
|
63
|
+
rowid INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
64
|
+
id TEXT UNIQUE NOT NULL,
|
|
65
|
+
session_id TEXT NOT NULL,
|
|
66
|
+
role TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
|
|
67
|
+
content TEXT NOT NULL,
|
|
68
|
+
timestamp TEXT NOT NULL,
|
|
69
|
+
tool_use_ids TEXT,
|
|
70
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
71
|
+
);
|
|
72
|
+
CREATE INDEX IF NOT EXISTS idx_messages_session ON messages_meta(session_id);
|
|
73
|
+
CREATE INDEX IF NOT EXISTS idx_messages_timestamp ON messages_meta(timestamp);
|
|
74
|
+
`,f3=`
|
|
75
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(
|
|
76
|
+
content,
|
|
77
|
+
content=messages_meta,
|
|
78
|
+
content_rowid=rowid,
|
|
79
|
+
tokenize='porter unicode61'
|
|
80
|
+
);
|
|
81
|
+
`,h3=`
|
|
82
|
+
CREATE TABLE IF NOT EXISTS tool_uses (
|
|
83
|
+
id TEXT PRIMARY KEY,
|
|
84
|
+
session_id TEXT NOT NULL,
|
|
85
|
+
name TEXT NOT NULL,
|
|
86
|
+
input TEXT NOT NULL,
|
|
87
|
+
timestamp TEXT NOT NULL,
|
|
88
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'success', 'error')),
|
|
89
|
+
result TEXT,
|
|
90
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
91
|
+
);
|
|
92
|
+
CREATE INDEX IF NOT EXISTS idx_tool_uses_session ON tool_uses(session_id);
|
|
93
|
+
CREATE INDEX IF NOT EXISTS idx_tool_uses_name ON tool_uses(name);
|
|
94
|
+
`,g3=`
|
|
95
|
+
CREATE TABLE IF NOT EXISTS links (
|
|
96
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
97
|
+
source_type TEXT NOT NULL CHECK (source_type IN ('session', 'message', 'topic')),
|
|
98
|
+
source_id TEXT NOT NULL,
|
|
99
|
+
target_type TEXT NOT NULL CHECK (target_type IN ('session', 'message', 'topic')),
|
|
100
|
+
target_id TEXT NOT NULL,
|
|
101
|
+
relationship TEXT NOT NULL CHECK (relationship IN ('mentions', 'related_to', 'continues')),
|
|
102
|
+
weight REAL DEFAULT 1.0 CHECK (weight >= 0 AND weight <= 1),
|
|
103
|
+
UNIQUE(source_type, source_id, target_type, target_id, relationship)
|
|
104
|
+
);
|
|
105
|
+
CREATE INDEX IF NOT EXISTS idx_links_source ON links(source_type, source_id);
|
|
106
|
+
CREATE INDEX IF NOT EXISTS idx_links_target ON links(target_type, target_id);
|
|
107
|
+
`,m3=`
|
|
108
|
+
CREATE TABLE IF NOT EXISTS topics (
|
|
109
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
110
|
+
name TEXT UNIQUE NOT NULL,
|
|
111
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
112
|
+
);
|
|
113
|
+
CREATE INDEX IF NOT EXISTS idx_topics_name ON topics(name);
|
|
114
|
+
`,c3=`
|
|
115
|
+
CREATE TABLE IF NOT EXISTS extraction_state (
|
|
116
|
+
id TEXT PRIMARY KEY,
|
|
117
|
+
session_path TEXT UNIQUE NOT NULL,
|
|
118
|
+
started_at TEXT NOT NULL,
|
|
119
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'in_progress', 'complete', 'error')),
|
|
120
|
+
completed_at TEXT,
|
|
121
|
+
messages_extracted INTEGER DEFAULT 0,
|
|
122
|
+
error_message TEXT,
|
|
123
|
+
file_mtime TEXT,
|
|
124
|
+
file_size INTEGER
|
|
125
|
+
);
|
|
126
|
+
CREATE INDEX IF NOT EXISTS idx_extraction_session_path ON extraction_state(session_path);
|
|
127
|
+
CREATE INDEX IF NOT EXISTS idx_extraction_status ON extraction_state(status);
|
|
128
|
+
`,u3=`
|
|
129
|
+
CREATE TABLE IF NOT EXISTS embedding_state (
|
|
130
|
+
message_id INTEGER PRIMARY KEY,
|
|
131
|
+
embedded_at TEXT NOT NULL,
|
|
132
|
+
model_hash TEXT NOT NULL,
|
|
133
|
+
FOREIGN KEY (message_id) REFERENCES messages_meta(rowid) ON DELETE CASCADE
|
|
134
|
+
);
|
|
135
|
+
CREATE INDEX IF NOT EXISTS idx_embedding_state_model ON embedding_state(model_hash);
|
|
136
|
+
`,d3=`
|
|
137
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS message_embeddings USING vec0(
|
|
138
|
+
embedding float[384]
|
|
139
|
+
);
|
|
140
|
+
`,p3=`
|
|
141
|
+
ALTER TABLE embedding_state ADD COLUMN model_name TEXT NOT NULL DEFAULT '';
|
|
142
|
+
`,l3=`
|
|
143
|
+
CREATE TABLE IF NOT EXISTS friction_log (
|
|
144
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
145
|
+
description TEXT NOT NULL,
|
|
146
|
+
severity TEXT NOT NULL DEFAULT 'medium' CHECK (severity IN ('low', 'medium', 'high', 'critical')),
|
|
147
|
+
category TEXT NOT NULL DEFAULT 'cli',
|
|
148
|
+
tool TEXT NOT NULL DEFAULT 'memory',
|
|
149
|
+
tags TEXT,
|
|
150
|
+
status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'resolved', 'wont-fix')),
|
|
151
|
+
context TEXT,
|
|
152
|
+
source_project TEXT,
|
|
153
|
+
logged_at TEXT NOT NULL,
|
|
154
|
+
resolved_at TEXT,
|
|
155
|
+
resolution TEXT,
|
|
156
|
+
last_reviewed_at TEXT
|
|
157
|
+
);
|
|
158
|
+
CREATE INDEX IF NOT EXISTS idx_friction_status ON friction_log(status);
|
|
159
|
+
CREATE INDEX IF NOT EXISTS idx_friction_severity ON friction_log(severity);
|
|
160
|
+
CREATE INDEX IF NOT EXISTS idx_friction_category ON friction_log(category);
|
|
161
|
+
CREATE INDEX IF NOT EXISTS idx_friction_tool ON friction_log(tool);
|
|
162
|
+
`,n3=`
|
|
163
|
+
CREATE TABLE IF NOT EXISTS backfill_state (
|
|
164
|
+
session_id TEXT PRIMARY KEY,
|
|
165
|
+
backfilled_at TEXT NOT NULL,
|
|
166
|
+
daily_log_path TEXT NOT NULL,
|
|
167
|
+
success INTEGER DEFAULT 1,
|
|
168
|
+
error_message TEXT
|
|
169
|
+
);
|
|
170
|
+
`,U9;var L9=L(()=>{U9=[`
|
|
171
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
172
|
+
id TEXT PRIMARY KEY,
|
|
173
|
+
project_path_encoded TEXT NOT NULL,
|
|
174
|
+
project_path_decoded TEXT NOT NULL,
|
|
175
|
+
project_name TEXT NOT NULL,
|
|
176
|
+
start_time TEXT NOT NULL,
|
|
177
|
+
end_time TEXT,
|
|
178
|
+
message_count INTEGER DEFAULT 0,
|
|
179
|
+
summary TEXT,
|
|
180
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
181
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
182
|
+
);
|
|
183
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_path_encoded);
|
|
184
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_start_time ON sessions(start_time);
|
|
185
|
+
`,`
|
|
186
|
+
CREATE TABLE IF NOT EXISTS messages_meta (
|
|
187
|
+
rowid INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
188
|
+
id TEXT UNIQUE NOT NULL,
|
|
189
|
+
session_id TEXT NOT NULL,
|
|
190
|
+
role TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
|
|
191
|
+
content TEXT NOT NULL,
|
|
192
|
+
timestamp TEXT NOT NULL,
|
|
193
|
+
tool_use_ids TEXT,
|
|
194
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
195
|
+
);
|
|
196
|
+
CREATE INDEX IF NOT EXISTS idx_messages_session ON messages_meta(session_id);
|
|
197
|
+
CREATE INDEX IF NOT EXISTS idx_messages_timestamp ON messages_meta(timestamp);
|
|
198
|
+
`,`
|
|
199
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(
|
|
200
|
+
content,
|
|
201
|
+
content=messages_meta,
|
|
202
|
+
content_rowid=rowid,
|
|
203
|
+
tokenize='porter unicode61'
|
|
204
|
+
);
|
|
205
|
+
`,`
|
|
206
|
+
CREATE TRIGGER IF NOT EXISTS messages_fts_insert AFTER INSERT ON messages_meta BEGIN
|
|
207
|
+
INSERT INTO messages_fts(rowid, content) VALUES (new.rowid, new.content);
|
|
208
|
+
END;
|
|
209
|
+
|
|
210
|
+
CREATE TRIGGER IF NOT EXISTS messages_fts_delete AFTER DELETE ON messages_meta BEGIN
|
|
211
|
+
INSERT INTO messages_fts(messages_fts, rowid, content) VALUES('delete', old.rowid, old.content);
|
|
212
|
+
END;
|
|
213
|
+
|
|
214
|
+
CREATE TRIGGER IF NOT EXISTS messages_fts_update AFTER UPDATE ON messages_meta BEGIN
|
|
215
|
+
INSERT INTO messages_fts(messages_fts, rowid, content) VALUES('delete', old.rowid, old.content);
|
|
216
|
+
INSERT INTO messages_fts(rowid, content) VALUES (new.rowid, new.content);
|
|
217
|
+
END;
|
|
218
|
+
`,`
|
|
219
|
+
CREATE TABLE IF NOT EXISTS tool_uses (
|
|
220
|
+
id TEXT PRIMARY KEY,
|
|
221
|
+
session_id TEXT NOT NULL,
|
|
222
|
+
name TEXT NOT NULL,
|
|
223
|
+
input TEXT NOT NULL,
|
|
224
|
+
timestamp TEXT NOT NULL,
|
|
225
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'success', 'error')),
|
|
226
|
+
result TEXT,
|
|
227
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
228
|
+
);
|
|
229
|
+
CREATE INDEX IF NOT EXISTS idx_tool_uses_session ON tool_uses(session_id);
|
|
230
|
+
CREATE INDEX IF NOT EXISTS idx_tool_uses_name ON tool_uses(name);
|
|
231
|
+
`,`
|
|
232
|
+
CREATE TABLE IF NOT EXISTS links (
|
|
233
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
234
|
+
source_type TEXT NOT NULL CHECK (source_type IN ('session', 'message', 'topic')),
|
|
235
|
+
source_id TEXT NOT NULL,
|
|
236
|
+
target_type TEXT NOT NULL CHECK (target_type IN ('session', 'message', 'topic')),
|
|
237
|
+
target_id TEXT NOT NULL,
|
|
238
|
+
relationship TEXT NOT NULL CHECK (relationship IN ('mentions', 'related_to', 'continues')),
|
|
239
|
+
weight REAL DEFAULT 1.0 CHECK (weight >= 0 AND weight <= 1),
|
|
240
|
+
UNIQUE(source_type, source_id, target_type, target_id, relationship)
|
|
241
|
+
);
|
|
242
|
+
CREATE INDEX IF NOT EXISTS idx_links_source ON links(source_type, source_id);
|
|
243
|
+
CREATE INDEX IF NOT EXISTS idx_links_target ON links(target_type, target_id);
|
|
244
|
+
`,`
|
|
245
|
+
CREATE TABLE IF NOT EXISTS topics (
|
|
246
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
247
|
+
name TEXT UNIQUE NOT NULL,
|
|
248
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
249
|
+
);
|
|
250
|
+
CREATE INDEX IF NOT EXISTS idx_topics_name ON topics(name);
|
|
251
|
+
`,`
|
|
252
|
+
CREATE TABLE IF NOT EXISTS extraction_state (
|
|
253
|
+
id TEXT PRIMARY KEY,
|
|
254
|
+
session_path TEXT UNIQUE NOT NULL,
|
|
255
|
+
started_at TEXT NOT NULL,
|
|
256
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'in_progress', 'complete', 'error')),
|
|
257
|
+
completed_at TEXT,
|
|
258
|
+
messages_extracted INTEGER DEFAULT 0,
|
|
259
|
+
error_message TEXT,
|
|
260
|
+
file_mtime TEXT,
|
|
261
|
+
file_size INTEGER
|
|
262
|
+
);
|
|
263
|
+
CREATE INDEX IF NOT EXISTS idx_extraction_session_path ON extraction_state(session_path);
|
|
264
|
+
CREATE INDEX IF NOT EXISTS idx_extraction_status ON extraction_state(status);
|
|
265
|
+
`,`
|
|
266
|
+
CREATE TABLE IF NOT EXISTS entities (
|
|
267
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
268
|
+
type TEXT NOT NULL CHECK (type IN ('concept', 'file', 'decision', 'term')),
|
|
269
|
+
name TEXT NOT NULL,
|
|
270
|
+
metadata TEXT,
|
|
271
|
+
confidence REAL DEFAULT 1.0 CHECK (confidence >= 0 AND confidence <= 1),
|
|
272
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
273
|
+
UNIQUE(type, name)
|
|
274
|
+
);
|
|
275
|
+
CREATE INDEX IF NOT EXISTS idx_entities_type ON entities(type);
|
|
276
|
+
CREATE INDEX IF NOT EXISTS idx_entities_name ON entities(name);
|
|
277
|
+
`,`
|
|
278
|
+
CREATE TABLE IF NOT EXISTS session_entities (
|
|
279
|
+
session_id TEXT NOT NULL,
|
|
280
|
+
entity_id INTEGER NOT NULL,
|
|
281
|
+
frequency INTEGER DEFAULT 1,
|
|
282
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE,
|
|
283
|
+
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE,
|
|
284
|
+
PRIMARY KEY (session_id, entity_id)
|
|
285
|
+
);
|
|
286
|
+
`,`
|
|
287
|
+
CREATE TABLE IF NOT EXISTS entity_links (
|
|
288
|
+
source_id INTEGER NOT NULL,
|
|
289
|
+
target_id INTEGER NOT NULL,
|
|
290
|
+
relationship TEXT NOT NULL CHECK (relationship IN ('related', 'implies', 'contradicts')),
|
|
291
|
+
weight REAL DEFAULT 1.0 CHECK (weight >= 0 AND weight <= 1),
|
|
292
|
+
FOREIGN KEY (source_id) REFERENCES entities(id) ON DELETE CASCADE,
|
|
293
|
+
FOREIGN KEY (target_id) REFERENCES entities(id) ON DELETE CASCADE,
|
|
294
|
+
PRIMARY KEY (source_id, target_id, relationship)
|
|
295
|
+
);
|
|
296
|
+
`,`
|
|
297
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS sessions_fts USING fts5(
|
|
298
|
+
session_id,
|
|
299
|
+
summary,
|
|
300
|
+
tokenize='porter unicode61'
|
|
301
|
+
);
|
|
302
|
+
`,`
|
|
303
|
+
CREATE TRIGGER IF NOT EXISTS sessions_fts_update AFTER UPDATE OF summary ON sessions
|
|
304
|
+
WHEN new.summary IS NOT NULL AND new.summary != ''
|
|
305
|
+
BEGIN
|
|
306
|
+
DELETE FROM sessions_fts WHERE session_id = old.id;
|
|
307
|
+
INSERT INTO sessions_fts(session_id, summary) VALUES (new.id, new.summary);
|
|
308
|
+
END;
|
|
309
|
+
|
|
310
|
+
CREATE TRIGGER IF NOT EXISTS sessions_fts_delete AFTER DELETE ON sessions BEGIN
|
|
311
|
+
DELETE FROM sessions_fts WHERE session_id = old.id;
|
|
312
|
+
END;
|
|
313
|
+
`,`
|
|
314
|
+
CREATE TABLE IF NOT EXISTS embedding_state (
|
|
315
|
+
message_id INTEGER PRIMARY KEY,
|
|
316
|
+
embedded_at TEXT NOT NULL,
|
|
317
|
+
model_hash TEXT NOT NULL,
|
|
318
|
+
FOREIGN KEY (message_id) REFERENCES messages_meta(rowid) ON DELETE CASCADE
|
|
319
|
+
);
|
|
320
|
+
CREATE INDEX IF NOT EXISTS idx_embedding_state_model ON embedding_state(model_hash);
|
|
321
|
+
`,`
|
|
322
|
+
CREATE TABLE IF NOT EXISTS memory_files (
|
|
323
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
324
|
+
file_path TEXT UNIQUE NOT NULL,
|
|
325
|
+
file_type TEXT NOT NULL CHECK (file_type IN ('daily_log', 'decisions', 'learnings', 'user_prefs')),
|
|
326
|
+
project_encoded TEXT,
|
|
327
|
+
content TEXT NOT NULL,
|
|
328
|
+
content_hash TEXT NOT NULL,
|
|
329
|
+
last_indexed_at TEXT NOT NULL,
|
|
330
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
331
|
+
);
|
|
332
|
+
CREATE INDEX IF NOT EXISTS idx_memory_files_type ON memory_files(file_type);
|
|
333
|
+
CREATE INDEX IF NOT EXISTS idx_memory_files_project ON memory_files(project_encoded);
|
|
334
|
+
`,`
|
|
335
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS memory_files_fts USING fts5(
|
|
336
|
+
content,
|
|
337
|
+
content=memory_files,
|
|
338
|
+
content_rowid=id,
|
|
339
|
+
tokenize='porter unicode61'
|
|
340
|
+
);
|
|
341
|
+
`,`
|
|
342
|
+
CREATE TRIGGER IF NOT EXISTS memory_files_fts_insert AFTER INSERT ON memory_files BEGIN
|
|
343
|
+
INSERT INTO memory_files_fts(rowid, content) VALUES (new.id, new.content);
|
|
344
|
+
END;
|
|
345
|
+
|
|
346
|
+
CREATE TRIGGER IF NOT EXISTS memory_files_fts_delete AFTER DELETE ON memory_files BEGIN
|
|
347
|
+
INSERT INTO memory_files_fts(memory_files_fts, rowid, content) VALUES('delete', old.id, old.content);
|
|
348
|
+
END;
|
|
349
|
+
|
|
350
|
+
CREATE TRIGGER IF NOT EXISTS memory_files_fts_update AFTER UPDATE ON memory_files BEGIN
|
|
351
|
+
INSERT INTO memory_files_fts(memory_files_fts, rowid, content) VALUES('delete', old.id, old.content);
|
|
352
|
+
INSERT INTO memory_files_fts(rowid, content) VALUES (new.id, new.content);
|
|
353
|
+
END;
|
|
354
|
+
`,`
|
|
355
|
+
CREATE TABLE IF NOT EXISTS friction_log (
|
|
356
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
357
|
+
description TEXT NOT NULL,
|
|
358
|
+
severity TEXT NOT NULL DEFAULT 'medium' CHECK (severity IN ('low', 'medium', 'high', 'critical')),
|
|
359
|
+
category TEXT NOT NULL DEFAULT 'cli',
|
|
360
|
+
tool TEXT NOT NULL DEFAULT 'memory',
|
|
361
|
+
tags TEXT,
|
|
362
|
+
status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'resolved', 'wont-fix')),
|
|
363
|
+
context TEXT,
|
|
364
|
+
source_project TEXT,
|
|
365
|
+
logged_at TEXT NOT NULL,
|
|
366
|
+
resolved_at TEXT,
|
|
367
|
+
resolution TEXT,
|
|
368
|
+
last_reviewed_at TEXT
|
|
369
|
+
);
|
|
370
|
+
CREATE INDEX IF NOT EXISTS idx_friction_status ON friction_log(status);
|
|
371
|
+
CREATE INDEX IF NOT EXISTS idx_friction_severity ON friction_log(severity);
|
|
372
|
+
CREATE INDEX IF NOT EXISTS idx_friction_category ON friction_log(category);
|
|
373
|
+
CREATE INDEX IF NOT EXISTS idx_friction_tool ON friction_log(tool);
|
|
374
|
+
`,`
|
|
375
|
+
CREATE TABLE IF NOT EXISTS backfill_state (
|
|
376
|
+
session_id TEXT PRIMARY KEY,
|
|
377
|
+
backfilled_at TEXT NOT NULL,
|
|
378
|
+
daily_log_path TEXT NOT NULL,
|
|
379
|
+
success INTEGER DEFAULT 1,
|
|
380
|
+
error_message TEXT
|
|
381
|
+
);
|
|
382
|
+
`,`
|
|
383
|
+
CREATE TABLE IF NOT EXISTS facts (
|
|
384
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
385
|
+
uuid TEXT UNIQUE NOT NULL,
|
|
386
|
+
type TEXT NOT NULL CHECK (type IN ('decision', 'learning', 'preference', 'friction', 'observation', 'supersedence')),
|
|
387
|
+
project TEXT NOT NULL,
|
|
388
|
+
content TEXT NOT NULL,
|
|
389
|
+
metadata TEXT,
|
|
390
|
+
observed_at TEXT NOT NULL,
|
|
391
|
+
superseded_at TEXT,
|
|
392
|
+
superseded_by TEXT,
|
|
393
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
394
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
395
|
+
);
|
|
396
|
+
CREATE INDEX IF NOT EXISTS idx_facts_uuid ON facts(uuid);
|
|
397
|
+
CREATE INDEX IF NOT EXISTS idx_facts_project ON facts(project);
|
|
398
|
+
CREATE INDEX IF NOT EXISTS idx_facts_type ON facts(type);
|
|
399
|
+
`,`
|
|
400
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS facts_fts USING fts5(
|
|
401
|
+
content,
|
|
402
|
+
content=facts,
|
|
403
|
+
content_rowid=id,
|
|
404
|
+
tokenize='porter unicode61'
|
|
405
|
+
);
|
|
406
|
+
`,`
|
|
407
|
+
CREATE TRIGGER IF NOT EXISTS facts_fts_insert AFTER INSERT ON facts BEGIN
|
|
408
|
+
INSERT INTO facts_fts(rowid, content) VALUES (new.id, new.content);
|
|
409
|
+
END;
|
|
410
|
+
|
|
411
|
+
CREATE TRIGGER IF NOT EXISTS facts_fts_delete AFTER DELETE ON facts BEGIN
|
|
412
|
+
INSERT INTO facts_fts(facts_fts, rowid, content) VALUES('delete', old.id, old.content);
|
|
413
|
+
END;
|
|
414
|
+
|
|
415
|
+
CREATE TRIGGER IF NOT EXISTS facts_fts_update AFTER UPDATE ON facts BEGIN
|
|
416
|
+
INSERT INTO facts_fts(facts_fts, rowid, content) VALUES('delete', old.id, old.content);
|
|
417
|
+
INSERT INTO facts_fts(rowid, content) VALUES (new.id, new.content);
|
|
418
|
+
END;
|
|
419
|
+
`,`
|
|
420
|
+
CREATE TABLE IF NOT EXISTS extraction_log (
|
|
421
|
+
session_id TEXT PRIMARY KEY,
|
|
422
|
+
mode TEXT NOT NULL,
|
|
423
|
+
facts_added INTEGER DEFAULT 0,
|
|
424
|
+
facts_updated INTEGER DEFAULT 0,
|
|
425
|
+
facts_superseded INTEGER DEFAULT 0,
|
|
426
|
+
facts_skipped INTEGER DEFAULT 0,
|
|
427
|
+
provider TEXT NOT NULL,
|
|
428
|
+
model TEXT NOT NULL,
|
|
429
|
+
tokens_consumed INTEGER DEFAULT 0,
|
|
430
|
+
extracted_at TEXT NOT NULL
|
|
431
|
+
);
|
|
432
|
+
`]});class z1{_sourceType;_sourceId;_targetType;_targetId;_relationship;_weight;constructor($){this._sourceType=$.sourceType,this._sourceId=$.sourceId,this._targetType=$.targetType,this._targetId=$.targetId,this._relationship=$.relationship,this._weight=$.weight??1}static create($){if(!$.sourceId||$.sourceId.trim()==="")throw Error("Source ID cannot be empty");if(!$.targetId||$.targetId.trim()==="")throw Error("Target ID cannot be empty");if(!a3.includes($.sourceType))throw Error("Invalid source type");if(!a3.includes($.targetType))throw Error("Invalid target type");if(!B7.includes($.relationship))throw Error("Invalid relationship type");if($.weight!==void 0&&($.weight<0||$.weight>1))throw Error("Weight must be between 0 and 1");return new z1($)}get id(){return`${this._sourceType}:${this._sourceId}->${this._targetType}:${this._targetId}:${this._relationship}`}get sourceType(){return this._sourceType}get sourceId(){return this._sourceId}get targetType(){return this._targetType}get targetId(){return this._targetId}get relationship(){return this._relationship}get weight(){return this._weight}equals($){return this.id===$.id}withWeight($){if($<0||$>1)throw Error("Weight must be between 0 and 1");return new z1({sourceType:this._sourceType,sourceId:this._sourceId,targetType:this._targetType,targetId:this._targetId,relationship:this._relationship,weight:$})}}var a3,B7;var I9=L(()=>{a3=["session","message","topic"],B7=["mentions","related_to","continues"]});import{randomUUID as z7}from"crypto";class Z0{_id;_uuid;_type;_project;_content;_metadata;_observedAt;_supersededAt;_supersededBy;constructor($){this._id=$.id,this._uuid=$.uuid??z7(),this._type=$.type,this._project=$.project,this._content=$.content,this._metadata=$.metadata?JSON.parse(JSON.stringify($.metadata)):void 0,this._observedAt=new Date($.observedAt.getTime()),this._supersededAt=$.supersededAt?new Date($.supersededAt.getTime()):null,this._supersededBy=$.supersededBy??null}static create($){if(!$.project||$.project.trim()==="")throw Error("Fact project cannot be empty");if(!$.content||$.content.trim()==="")throw Error("Fact content cannot be empty");if(!["decision","learning","preference","friction","observation","supersedence"].includes($.type))throw Error("Invalid fact type");return new Z0($)}get id(){return this._id}get uuid(){return this._uuid}get type(){return this._type}get project(){return this._project}get content(){return this._content}get metadata(){return this._metadata?JSON.parse(JSON.stringify(this._metadata)):void 0}get observedAt(){return new Date(this._observedAt.getTime())}get supersededAt(){return this._supersededAt?new Date(this._supersededAt.getTime()):null}get supersededBy(){return this._supersededBy}withId($){return new Z0({id:$,uuid:this._uuid,type:this._type,project:this._project,content:this._content,metadata:this._metadata,observedAt:this._observedAt,supersededAt:this._supersededAt,supersededBy:this._supersededBy})}withSuperseded($,Z){return new Z0({id:this._id,uuid:this._uuid,type:this._type,project:this._project,content:this._content,metadata:this._metadata,observedAt:this._observedAt,supersededAt:$,supersededBy:Z})}}var Z4=()=>{};var i3=L(()=>{t1();P4();I9();o1();E4();S4();C4();Z4()});class V0{_embedding;_model;_dimensions;constructor($){this._embedding=new Float32Array($.embedding),this._model=$.model,this._dimensions=$.dimensions}static create($){if($.embedding.length===0)throw Error("Embedding cannot be empty");let Z=$.model.trim();if(Z==="")throw Error("Model cannot be empty");if($.dimensions!==$.embedding.length)throw Error(`Dimensions (${$.dimensions}) must match embedding length (${$.embedding.length})`);return new V0({embedding:$.embedding,model:Z,dimensions:$.dimensions})}get embedding(){return new Float32Array(this._embedding)}get model(){return this._model}get dimensions(){return this._dimensions}equals($){if(this._model!==$._model)return!1;if(this._dimensions!==$._dimensions)return!1;for(let Z=0;Z<this._dimensions;Z++)if(this._embedding[Z]!==$._embedding[Z])return!1;return!0}}var r3={};y(r3,{ProjectPath:()=>t});class t{_decoded;_encoded;_projectName;constructor($,Z,K){this._decoded=$,this._encoded=Z,this._projectName=K??this.extractProjectName($)}static fromDecoded($){if(!$||$.trim()==="")throw Error("Path cannot be empty");let Z=t.encode($);return new t($,Z)}static fromEncoded($){if(!$||$.trim()==="")throw Error("Path cannot be empty");let Z=t.decode($);return new t(Z,$)}get decoded(){return this._decoded}get encoded(){return this._encoded}get projectName(){return this._projectName}withProjectName($){return new t(this._decoded,this._encoded,$)}equals($){return this._decoded===$._decoded}static encode($){return $.replace(/:\\/g,"--").replace(/\\/g,"-").replace(/\//g,"-").replace(/ /g,"-")}static decode($){if(/^([A-Za-z])--/.test($))return $.replace(/^([A-Za-z])--/,"$1:\\").replace(/-/g,"\\");else return $.replace(/-/g,"/")}extractProjectName($){let Z=$.replace(/[\\/]+$/,"");if(Z===""&&$.startsWith("/"))return"";if(/^[A-Za-z]:$/.test(Z))return Z;let K=Z.split(/[\\/]/);return K[K.length-1]||""}}class K4{_value;constructor($){this._value=$}static from($){let Z=$.trim();if(Z==="")throw Error("Query cannot be empty");return new K4(Z)}get value(){return this._value}equals($){return this._value===$._value}}class W0{_sessionId;_messageId;_snippet;_score;_timestamp;_role;_source;_rawScores;constructor($){this._sessionId=$.sessionId,this._messageId=$.messageId,this._snippet=$.snippet,this._score=$.score,this._timestamp=new Date($.timestamp.getTime()),this._role=$.role,this._source=$.source,this._rawScores=$.rawScores?{...$.rawScores}:void 0}static create($){if(!$.sessionId||$.sessionId.trim()==="")throw Error("Session ID cannot be empty");if(!$.messageId||$.messageId.trim()==="")throw Error("Message ID cannot be empty");if(!$.snippet||$.snippet.trim()==="")throw Error("Snippet cannot be empty");if($.score<0||$.score>1)throw Error("Score must be between 0 and 1");if(!$.role||$.role.trim()==="")throw Error("Role cannot be empty");return new W0($)}get sessionId(){return this._sessionId}get messageId(){return this._messageId}get snippet(){return this._snippet}get score(){return this._score}get timestamp(){return new Date(this._timestamp.getTime())}get role(){return this._role}get source(){return this._source}get rawScores(){return this._rawScores?{...this._rawScores}:void 0}equals($){return this._sessionId===$._sessionId&&this._messageId===$._messageId}compareByScore($){return $._score-this._score}}var T9=()=>{};class w0{static decodeProjectDirectory($){return t.fromEncoded($)}static isEncodedPath($){if(!$||$.length===0)return!1;if(A7.test($))return!0;if(N7.test($))return!0;return!1}static extractProjectName($){return t.fromEncoded($).projectName}static filterEncodedPaths($){return $.filter((Z)=>w0.isEncodedPath(Z))}static translatePath($,Z=process.platform){if(!$||$.trim()==="")return $;if(Z==="win32"){let K=$.match(/^\/mnt\/([a-zA-Z])([\/]?)(.*)$/);if(K){let X=K[1].toUpperCase(),Y=K[3].replace(/\//g,"\\");return`${X}:\\${Y}`}return $}else{let K=$.match(/^([a-zA-Z]):([\\/]?)(.*)$/);if(K){let X=K[1].toLowerCase(),Y=K[3].replace(/\\/g,"/");return`/mnt/${X}/${Y}`}return $}}static resolveExistingPath($,Z,K=process.platform){if(!$)return $;let X=Z??(()=>!1);if(X($))return $;let Y=w0.translatePath($,K);if(X(Y))return Y;return $}}var A7,N7;var h4=L(()=>{T9();A7=/^[A-Za-z]--/,N7=/^-[a-z]/i});var o3=()=>{};var t3=L(()=>{h4();o3()});var g4=L(()=>{i3();T9();t3();H0()});import{Database as q7}from"bun:sqlite";import{existsSync as O7,mkdirSync as U7}from"fs";import{dirname as s3}from"path";function L7($){try{return n0("sqlite-vec").load($),!0}catch{return!1}}function P(){return J1()}function S($){let{path:Z,create:K=!0,applySchema:X=!0,walMode:Y=!0,cacheSize:Q=-64000,busyTimeout:G=5000}=$,_=Z!==":memory:",J=_&&O7(Z),H=$.quickCheck??(_&&J);if(_)try{U7(s3(Z),{recursive:!0})}catch(z){let W=A(z);throw new j(F.DB_CONNECTION_FAILED,`Failed to create database directory: ${W}`,{path:s3(Z)})}let V;try{V=new q7(Z,{create:K})}catch(z){let W=A(z),N=z.code;throw new j(F.DB_CONNECTION_FAILED,`Failed to connect to database: ${W}`,{path:Z,...N?{errno:N}:{}})}let B=(z)=>{V.close();let W=A(z);if(W.includes("not a database")||W.includes("SQLITE_NOTADB"))throw new j(F.DB_CORRUPTED,"Database file is corrupted or not a valid SQLite database",{path:Z});throw new j(F.DB_CONNECTION_FAILED,`Failed to initialize database: ${W}`,{path:Z})};try{V.exec("PRAGMA foreign_keys = ON;");let z=!1;if(Y&&_){V.exec("PRAGMA journal_mode = WAL;");let q=V.query("PRAGMA journal_mode;").get();if(z=q.journal_mode==="wal",!z)console.warn(`Warning: WAL mode not enabled. Current mode: ${q.journal_mode}`)}V.exec(`PRAGMA busy_timeout = ${G};`),V.exec("PRAGMA synchronous = NORMAL;"),V.exec(`PRAGMA cache_size = ${Q};`),V.exec("PRAGMA temp_store = MEMORY;");let W=$4(V);if(!W){let q=V.query("SELECT sqlite_version() as version").get();throw V.close(),new j(F.DB_CONNECTION_FAILED,"FTS5 is not available. memory requires FTS5 for full-text search.",{sqliteVersion:q?.version??"unknown"})}if(H){let q=V.query("PRAGMA quick_check(1);").get();if(q?.quick_check!=="ok")throw V.close(),new j(F.DB_CORRUPTED,"Database integrity check failed",{path:Z,checkResult:q?.quick_check??"unknown"})}let N=L7(V);if(X)f4(V,{sqliteVecAvailable:N});return{db:V,walEnabled:z,fts5Available:W,sqliteVecAvailable:N}}catch(z){if(z instanceof j)throw z;throw B(z)}}function D($){try{$.exec("PRAGMA wal_checkpoint(TRUNCATE);")}catch{}try{$.exec("PRAGMA journal_mode = DELETE;")}catch{}$.close()}function e3($){$.exec("PRAGMA wal_checkpoint(PASSIVE);")}function m4($){return $.query("PRAGMA wal_checkpoint(TRUNCATE);").get()??{busy:0,log:0,checkpointed:0}}function $5($){try{return S($)}catch(Z){if(Z instanceof j)throw Z;let K=A(Z),X=Z.code;throw new j(F.DB_CONNECTION_FAILED,`Database initialization failed: ${K}`,{path:$.path,...X?{errno:X}:{}})}}var R9=L(()=>{L9();g4();l()});var Z5={};y(Z5,{SqliteSessionRepository:()=>g});class g{db;findByIdStmt;findByProjectStmt;findRecentStmt;insertStmt;deleteStmt;updateSummaryStmt;updateProjectNameStmt;findDistinctEncodedPathsStmt;constructor($){this.db=$,this.findByIdStmt=$.prepare(`
|
|
433
|
+
SELECT id, project_path_encoded, project_path_decoded, project_name,
|
|
434
|
+
start_time, end_time, message_count, summary
|
|
435
|
+
FROM sessions
|
|
436
|
+
WHERE id = $id
|
|
437
|
+
`),this.findByProjectStmt=$.prepare(`
|
|
438
|
+
SELECT id, project_path_encoded, project_path_decoded, project_name,
|
|
439
|
+
start_time, end_time, message_count, summary
|
|
440
|
+
FROM sessions
|
|
441
|
+
WHERE project_path_encoded = $projectPath
|
|
442
|
+
ORDER BY start_time DESC
|
|
443
|
+
`),this.findRecentStmt=$.prepare(`
|
|
444
|
+
SELECT id, project_path_encoded, project_path_decoded, project_name,
|
|
445
|
+
start_time, end_time, message_count, summary
|
|
446
|
+
FROM sessions
|
|
447
|
+
ORDER BY start_time DESC
|
|
448
|
+
LIMIT $limit
|
|
449
|
+
`),this.insertStmt=$.prepare(`
|
|
450
|
+
INSERT OR IGNORE INTO sessions
|
|
451
|
+
(id, project_path_encoded, project_path_decoded, project_name,
|
|
452
|
+
start_time, end_time, message_count)
|
|
453
|
+
VALUES
|
|
454
|
+
($id, $projectPathEncoded, $projectPathDecoded, $projectName,
|
|
455
|
+
$startTime, $endTime, $messageCount)
|
|
456
|
+
`),this.deleteStmt=$.prepare(`
|
|
457
|
+
DELETE FROM sessions WHERE id = $id
|
|
458
|
+
`),this.updateSummaryStmt=$.prepare(`
|
|
459
|
+
UPDATE sessions SET summary = $summary, updated_at = datetime('now')
|
|
460
|
+
WHERE id = $id
|
|
461
|
+
`),this.updateProjectNameStmt=$.prepare(`
|
|
462
|
+
UPDATE sessions SET project_name = $projectName, updated_at = datetime('now')
|
|
463
|
+
WHERE project_path_encoded = $encodedPath
|
|
464
|
+
`),this.findDistinctEncodedPathsStmt=$.prepare(`
|
|
465
|
+
SELECT DISTINCT project_path_encoded FROM sessions
|
|
466
|
+
ORDER BY project_path_encoded
|
|
467
|
+
`)}rowToSession($){let Z=t.fromDecoded($.project_path_decoded);return O0.create({id:$.id,projectPath:Z,startTime:new Date($.start_time),endTime:$.end_time?new Date($.end_time):void 0,summary:$.summary??void 0,messageCount:$.message_count})}async findById($){let Z=this.findByIdStmt.get({$id:$});if(!Z)return null;return this.rowToSession(Z)}async findByProject($){return this.findByProjectStmt.all({$projectPath:$.encoded}).map((K)=>this.rowToSession(K))}async findRecent($){return this.findRecentStmt.all({$limit:$}).map((K)=>this.rowToSession(K))}async save($){this.insertStmt.run({$id:$.id,$projectPathEncoded:$.projectPath.encoded,$projectPathDecoded:$.projectPath.decoded,$projectName:$.projectPath.projectName,$startTime:$.startTime.toISOString(),$endTime:$.endTime?.toISOString()??null,$messageCount:$.messages.length})}async saveMany($){this.db.transaction(()=>{for(let K of $)this.insertStmt.run({$id:K.id,$projectPathEncoded:K.projectPath.encoded,$projectPathDecoded:K.projectPath.decoded,$projectName:K.projectPath.projectName,$startTime:K.startTime.toISOString(),$endTime:K.endTime?.toISOString()??null,$messageCount:K.messages.length})}).immediate()}async delete($){this.deleteStmt.run({$id:$})}async updateSummary($,Z){this.updateSummaryStmt.run({$id:$,$summary:Z})}async findOlderThan($){return this.db.prepare(`
|
|
468
|
+
SELECT id, project_path_encoded, project_path_decoded, project_name,
|
|
469
|
+
start_time, end_time, message_count, summary
|
|
470
|
+
FROM sessions
|
|
471
|
+
WHERE updated_at < $cutoffDate
|
|
472
|
+
ORDER BY updated_at ASC
|
|
473
|
+
`).all({$cutoffDate:$.toISOString()}).map((Y)=>this.rowToSession(Y))}async countOlderThan($){return this.db.prepare(`
|
|
474
|
+
SELECT COUNT(*) as count
|
|
475
|
+
FROM sessions
|
|
476
|
+
WHERE updated_at < $cutoffDate
|
|
477
|
+
`).get({$cutoffDate:$.toISOString()}).count}async deleteOlderThan($){let Z=await this.countOlderThan($),K=`
|
|
478
|
+
DELETE FROM sessions
|
|
479
|
+
WHERE updated_at < $cutoffDate
|
|
480
|
+
`;return this.db.prepare(`
|
|
481
|
+
DELETE FROM sessions
|
|
482
|
+
WHERE updated_at < $cutoffDate
|
|
483
|
+
`).run({$cutoffDate:$.toISOString()}),Z}async updateProjectName($,Z){let X=this.db.prepare("SELECT COUNT(*) as count FROM sessions WHERE project_path_encoded = $encodedPath").get({$encodedPath:$}).count;if(X>0)this.updateProjectNameStmt.run({$encodedPath:$,$projectName:Z});return X}async findDistinctEncodedPaths(){return this.findDistinctEncodedPathsStmt.all().map((Z)=>Z.project_path_encoded)}async findFiltered($){let Z=[],K={};if($.projectFilter)Z.push("project_name LIKE $projectFilter"),K.$projectFilter=`%${$.projectFilter}%`;if($.sinceDate)Z.push("start_time >= $sinceDate"),K.$sinceDate=$.sinceDate.toISOString();if($.beforeDate)Z.push("start_time <= $beforeDate"),K.$beforeDate=$.beforeDate.toISOString();let X=Z.length>0?`WHERE ${Z.join(" AND ")}`:"",Y=$.limit??20;K.$limit=Y;let Q=`
|
|
484
|
+
SELECT id, project_path_encoded, project_path_decoded, project_name,
|
|
485
|
+
start_time, end_time, message_count, summary
|
|
486
|
+
FROM sessions
|
|
487
|
+
${X}
|
|
488
|
+
ORDER BY start_time DESC
|
|
489
|
+
LIMIT $limit
|
|
490
|
+
`;return this.db.prepare(Q).all(K).map((J)=>this.rowToSession(J))}async searchSummaries($,Z=20){let K=o0($);if(!K)return[];let X=`
|
|
491
|
+
SELECT s.id, s.project_path_encoded, s.project_path_decoded, s.project_name,
|
|
492
|
+
s.start_time, s.end_time, s.message_count, s.summary
|
|
493
|
+
FROM sessions s
|
|
494
|
+
JOIN sessions_fts f ON f.session_id = s.id
|
|
495
|
+
WHERE sessions_fts MATCH $query
|
|
496
|
+
ORDER BY rank
|
|
497
|
+
LIMIT $limit
|
|
498
|
+
`;return this.db.prepare(X).all({$query:K,$limit:Z}).map((G)=>this.rowToSession(G))}}var M0=()=>{};var K5={};y(K5,{SqliteMessageRepository:()=>G0});class G0{db;findByIdStmt;findBySessionStmt;existsStmt;insertStmt;constructor($){this.db=$,this.findByIdStmt=$.prepare(`SELECT id, session_id, role, content, timestamp, tool_use_ids
|
|
499
|
+
FROM messages_meta
|
|
500
|
+
WHERE id = ?`),this.findBySessionStmt=$.prepare(`SELECT id, session_id, role, content, timestamp, tool_use_ids
|
|
501
|
+
FROM messages_meta
|
|
502
|
+
WHERE session_id = ?
|
|
503
|
+
ORDER BY timestamp ASC`),this.existsStmt=$.prepare("SELECT id FROM messages_meta WHERE id = ?"),this.insertStmt=$.prepare(`INSERT OR IGNORE INTO messages_meta (id, session_id, role, content, timestamp, tool_use_ids)
|
|
504
|
+
VALUES ($id, $session_id, $role, $content, $timestamp, $tool_use_ids)`)}async findById($){let Z=this.findByIdStmt.get($);if(!Z)return null;return this.rowToMessage(Z)}async findBySession($){return this.findBySessionStmt.all($).map((K)=>this.rowToMessage(K))}async save($,Z){this.insertStmt.run({$id:$.id,$session_id:Z,$role:$.role,$content:$.content,$timestamp:$.timestamp.toISOString(),$tool_use_ids:$.toolUses.length>0?JSON.stringify($.toolUses):null})}async saveMany($,Z){let X={inserted:0,skipped:0,errors:[]};for(let Y=0;Y<$.length;Y+=100){let Q=$.slice(Y,Y+100);this.db.transaction((_)=>{for(let{message:J,sessionId:H}of _)try{if(this.existsStmt.get(J.id)){X.skipped++;continue}this.insertStmt.run({$id:J.id,$session_id:H,$role:J.role,$content:J.content,$timestamp:J.timestamp.toISOString(),$tool_use_ids:J.toolUses.length>0?JSON.stringify(J.toolUses):null}),X.inserted++}catch(V){X.skipped++,X.errors.push({id:J.id,reason:A(V)})}}).immediate(Q),Z?.onProgress?.({inserted:X.inserted,total:$.length})}return X}rowToMessage($){let Z=$.tool_use_ids?JSON.parse($.tool_use_ids):void 0;return J0.create({id:$.id,role:$.role,content:$.content,timestamp:new Date($.timestamp),toolUseIds:Z})}}var A1=L(()=>{o1()});class b0{findByIdStmt;findBySessionPathStmt;findPendingStmt;saveStmt;constructor($){this.findByIdStmt=$.prepare(`
|
|
505
|
+
SELECT id, session_path, started_at, status, completed_at,
|
|
506
|
+
messages_extracted, error_message, file_mtime, file_size
|
|
507
|
+
FROM extraction_state
|
|
508
|
+
WHERE id = $id
|
|
509
|
+
`),this.findBySessionPathStmt=$.prepare(`
|
|
510
|
+
SELECT id, session_path, started_at, status, completed_at,
|
|
511
|
+
messages_extracted, error_message, file_mtime, file_size
|
|
512
|
+
FROM extraction_state
|
|
513
|
+
WHERE session_path = $sessionPath
|
|
514
|
+
`),this.findPendingStmt=$.prepare(`
|
|
515
|
+
SELECT id, session_path, started_at, status, completed_at,
|
|
516
|
+
messages_extracted, error_message, file_mtime, file_size
|
|
517
|
+
FROM extraction_state
|
|
518
|
+
WHERE status IN ('pending', 'in_progress')
|
|
519
|
+
ORDER BY started_at ASC
|
|
520
|
+
`),this.saveStmt=$.prepare(`
|
|
521
|
+
INSERT OR REPLACE INTO extraction_state
|
|
522
|
+
(id, session_path, started_at, status, completed_at,
|
|
523
|
+
messages_extracted, error_message, file_mtime, file_size)
|
|
524
|
+
VALUES
|
|
525
|
+
($id, $sessionPath, $startedAt, $status, $completedAt,
|
|
526
|
+
$messagesExtracted, $errorMessage, $fileMtime, $fileSize)
|
|
527
|
+
`)}rowToExtractionState($){return Q0.create({id:$.id,sessionPath:$.session_path,startedAt:new Date($.started_at),status:$.status,completedAt:$.completed_at?new Date($.completed_at):void 0,messagesExtracted:$.messages_extracted,errorMessage:$.error_message??void 0,fileMtime:$.file_mtime?new Date($.file_mtime):void 0,fileSize:$.file_size??void 0})}async findById($){let Z=this.findByIdStmt.get({$id:$});if(!Z)return null;return this.rowToExtractionState(Z)}async findBySessionPath($){let Z=this.findBySessionPathStmt.get({$sessionPath:$});if(!Z)return null;return this.rowToExtractionState(Z)}async findPending(){return this.findPendingStmt.all().map((Z)=>this.rowToExtractionState(Z))}async save($){this.saveStmt.run({$id:$.id,$sessionPath:$.sessionPath,$startedAt:$.startedAt.toISOString(),$status:$.status,$completedAt:$.completedAt?.toISOString()??null,$messagesExtracted:$.messagesExtracted,$errorMessage:$.errorMessage??null,$fileMtime:$.fileMtime?.toISOString()??null,$fileSize:$.fileSize??null})}}var X5=L(()=>{P4()});class f0{db;findByIdStmt;findBySessionStmt;insertStmt;constructor($){this.db=$,this.findByIdStmt=$.prepare(`SELECT id, session_id, name, input, timestamp, status, result
|
|
528
|
+
FROM tool_uses
|
|
529
|
+
WHERE id = ?`),this.findBySessionStmt=$.prepare(`SELECT id, session_id, name, input, timestamp, status, result
|
|
530
|
+
FROM tool_uses
|
|
531
|
+
WHERE session_id = ?
|
|
532
|
+
ORDER BY timestamp ASC`),this.insertStmt=$.prepare(`INSERT OR IGNORE INTO tool_uses
|
|
533
|
+
(id, session_id, name, input, timestamp, status, result)
|
|
534
|
+
VALUES ($id, $session_id, $name, $input, $timestamp, $status, $result)`)}async findById($){let Z=this.findByIdStmt.get($);if(!Z)return null;return this.rowToEntity(Z)}async findBySession($){return this.findBySessionStmt.all($).map((K)=>this.rowToEntity(K))}async save($,Z){this.insertStmt.run({$id:$.id,$session_id:Z,$name:$.name,$input:JSON.stringify($.input),$timestamp:$.timestamp.toISOString(),$status:$.status,$result:$.result??null})}async saveMany($,Z){let X={inserted:0,skipped:0,errors:[]};for(let Y=0;Y<$.length;Y+=100){let Q=$.slice(Y,Y+100);this.db.transaction((_)=>{for(let{toolUse:J,sessionId:H}of _)try{if(this.insertStmt.run({$id:J.id,$session_id:H,$name:J.name,$input:JSON.stringify(J.input),$timestamp:J.timestamp.toISOString(),$status:J.status,$result:J.result??null}).changes>0)X.inserted++;else X.skipped++}catch(V){X.skipped++,X.errors.push({id:J.id,reason:A(V)})}}).immediate(Q),Z?.onProgress?.({inserted:X.inserted,total:$.length})}return X}rowToEntity($){return U0.create({id:$.id,name:$.name,input:JSON.parse($.input),timestamp:new Date($.timestamp),status:$.status,result:$.result??void 0})}}var F9=L(()=>{E4()});class N1{db;findBySourceStmt;findByTargetStmt;insertStmt;constructor($){this.db=$,this.findBySourceStmt=$.prepare(`
|
|
535
|
+
SELECT source_type, source_id, target_type, target_id, relationship, weight
|
|
536
|
+
FROM links
|
|
537
|
+
WHERE source_type = $sourceType AND source_id = $sourceId
|
|
538
|
+
`),this.findByTargetStmt=$.prepare(`
|
|
539
|
+
SELECT source_type, source_id, target_type, target_id, relationship, weight
|
|
540
|
+
FROM links
|
|
541
|
+
WHERE target_type = $targetType AND target_id = $targetId
|
|
542
|
+
`),this.insertStmt=$.prepare(`
|
|
543
|
+
INSERT OR REPLACE INTO links
|
|
544
|
+
(source_type, source_id, target_type, target_id, relationship, weight)
|
|
545
|
+
VALUES
|
|
546
|
+
($sourceType, $sourceId, $targetType, $targetId, $relationship, $weight)
|
|
547
|
+
`)}rowToLink($){return z1.create({sourceType:$.source_type,sourceId:$.source_id,targetType:$.target_type,targetId:$.target_id,relationship:$.relationship,weight:$.weight})}async findBySource($,Z){return this.findBySourceStmt.all({$sourceType:$,$sourceId:Z}).map((X)=>this.rowToLink(X))}async findByTarget($,Z){return this.findByTargetStmt.all({$targetType:$,$targetId:Z}).map((X)=>this.rowToLink(X))}async findRelated($,Z,K=2){return(await this.findRelatedWithHops($,Z,K)).map((Y)=>Y.link)}async findRelatedWithHops($,Z,K=2){return this.db.prepare(`
|
|
548
|
+
WITH RECURSIVE related(
|
|
549
|
+
source_type, source_id, target_type, target_id,
|
|
550
|
+
relationship, weight, hop, path
|
|
551
|
+
) AS (
|
|
552
|
+
-- Base case: direct connections (1-hop)
|
|
553
|
+
SELECT
|
|
554
|
+
source_type, source_id, target_type, target_id,
|
|
555
|
+
relationship, weight, 1 as hop,
|
|
556
|
+
source_type || ':' || source_id || '->' || target_type || ':' || target_id as path
|
|
557
|
+
FROM links
|
|
558
|
+
WHERE source_type = $entityType AND source_id = $entityId
|
|
559
|
+
|
|
560
|
+
UNION ALL
|
|
561
|
+
|
|
562
|
+
-- Recursive case: next level connections
|
|
563
|
+
SELECT
|
|
564
|
+
l.source_type, l.source_id, l.target_type, l.target_id,
|
|
565
|
+
l.relationship, l.weight * r.weight, r.hop + 1,
|
|
566
|
+
r.path || '->' || l.target_type || ':' || l.target_id
|
|
567
|
+
FROM links l
|
|
568
|
+
JOIN related r ON l.source_type = r.target_type AND l.source_id = r.target_id
|
|
569
|
+
WHERE r.hop < $maxHops
|
|
570
|
+
-- Prevent cycles: don't revisit nodes in current path
|
|
571
|
+
AND r.path NOT LIKE '%' || l.target_type || ':' || l.target_id || '%'
|
|
572
|
+
)
|
|
573
|
+
SELECT DISTINCT source_type, source_id, target_type, target_id, relationship, weight, hop
|
|
574
|
+
FROM related
|
|
575
|
+
ORDER BY hop ASC, weight DESC
|
|
576
|
+
`).all({$entityType:$,$entityId:Z,$maxHops:K}).map((G)=>({link:this.rowToLink(G),hop:G.hop}))}async save($){this.insertStmt.run({$sourceType:$.sourceType,$sourceId:$.sourceId,$targetType:$.targetType,$targetId:$.targetId,$relationship:$.relationship,$weight:$.weight})}async saveMany($){this.db.transaction(()=>{for(let K of $)this.insertStmt.run({$sourceType:K.sourceType,$sourceId:K.sourceId,$targetType:K.targetType,$targetId:K.targetId,$relationship:K.relationship,$weight:K.weight})}).immediate()}}var Y5=L(()=>{I9()});var M9=L(()=>{t1()});var Q5={};y(Q5,{EmbeddingRepository:()=>j0});class j0{db;constructor($){this.db=$}findUnembedded($){return this.db.prepare(`
|
|
577
|
+
SELECT m.rowid AS rowid, m.content AS content
|
|
578
|
+
FROM messages_meta m
|
|
579
|
+
LEFT JOIN embedding_state es ON m.rowid = es.message_id
|
|
580
|
+
WHERE es.message_id IS NULL
|
|
581
|
+
ORDER BY m.rowid ASC
|
|
582
|
+
LIMIT ?
|
|
583
|
+
`).all($)}storeBatch($,Z,K){let X=this.db.prepare("INSERT INTO message_embeddings(rowid, embedding) VALUES (?, vec_f32(?))"),Y=this.db.prepare("INSERT INTO embedding_state(message_id, embedded_at, model_hash, model_name) VALUES (?, ?, ?, ?)");this.db.transaction((G)=>{let _=new Date().toISOString();for(let J of G)X.run(J.rowid,J.embedding),Y.run(J.rowid,_,Z,K)})($)}getStoredModelHash(){return this.db.prepare("SELECT DISTINCT model_hash FROM embedding_state LIMIT 1").get()?.model_hash??null}getStoredModelName(){return this.db.prepare("SELECT DISTINCT model_name FROM embedding_state WHERE model_name != '' LIMIT 1").get()?.model_name??null}clearAllEmbeddings(){this.db.exec("DELETE FROM message_embeddings"),this.db.exec("DELETE FROM embedding_state")}getEmbeddedCount(){return this.db.prepare("SELECT COUNT(*) as count FROM embedding_state").get()?.count??0}getTotalMessageCount(){return this.db.prepare("SELECT COUNT(*) as count FROM messages_meta").get()?.count??0}vectorKnnSearch($,Z){if(Z<=0)return[];return this.db.prepare(`
|
|
584
|
+
SELECT rowid, distance
|
|
585
|
+
FROM message_embeddings
|
|
586
|
+
WHERE embedding MATCH ?
|
|
587
|
+
ORDER BY distance
|
|
588
|
+
LIMIT ?
|
|
589
|
+
`).all($,Z)}getStoredEmbeddingDimensions(){let $=this.db.prepare("SELECT COUNT(*) as count FROM message_embeddings").get();if(!$||$.count===0)return null;let Z=this.db.prepare("SELECT embedding FROM message_embeddings LIMIT 1").get();if(!Z||!Z.embedding)return null;return Z.embedding.byteLength/4}recreateVecTable($){this.db.exec("DROP TABLE IF EXISTS message_embeddings"),this.db.exec(`CREATE VIRTUAL TABLE message_embeddings USING vec0(
|
|
590
|
+
embedding float[${$}]
|
|
591
|
+
)`),this.db.exec("DELETE FROM embedding_state")}}class c4{db;constructor($){this.db=$}async findByPath($){let Z=this.db.prepare("SELECT * FROM memory_files WHERE file_path = ?").get($);return Z?this.toEntity(Z):null}async findByType($){return this.db.prepare("SELECT * FROM memory_files WHERE file_type = ? ORDER BY last_indexed_at DESC").all($).map((K)=>this.toEntity(K))}async findByProject($){return this.db.prepare("SELECT * FROM memory_files WHERE project_encoded = ? ORDER BY file_path").all($).map((K)=>this.toEntity(K))}async save($){this.db.prepare(G5).run($.filePath,$.fileType,$.projectEncoded??null,$.content,$.contentHash,$.lastIndexedAt.toISOString())}async saveMany($){let Z=this.db.prepare(G5);this.db.transaction(()=>{for(let X of $)Z.run(X.filePath,X.fileType,X.projectEncoded??null,X.content,X.contentHash,X.lastIndexedAt.toISOString())})()}async searchContent($,Z=20){let K=o0($);if(!K)return[];return this.db.prepare(`
|
|
592
|
+
SELECT m.* FROM memory_files m
|
|
593
|
+
JOIN memory_files_fts f ON f.rowid = m.id
|
|
594
|
+
WHERE memory_files_fts MATCH ?
|
|
595
|
+
ORDER BY rank
|
|
596
|
+
LIMIT ?
|
|
597
|
+
`).all(K,Z).map((Y)=>this.toEntity(Y))}async findCrossProjectLearnings($,Z=20){if($)return this.db.prepare(`SELECT * FROM memory_files
|
|
598
|
+
WHERE file_type = 'learnings'
|
|
599
|
+
AND content LIKE '%Applies to: cross-project%'
|
|
600
|
+
AND (project_encoded IS NULL OR project_encoded != ?)
|
|
601
|
+
ORDER BY last_indexed_at DESC
|
|
602
|
+
LIMIT ?`).all($,Z).map((Y)=>this.toEntity(Y));return this.db.prepare(`SELECT * FROM memory_files
|
|
603
|
+
WHERE file_type = 'learnings'
|
|
604
|
+
AND content LIKE '%Applies to: cross-project%'
|
|
605
|
+
ORDER BY last_indexed_at DESC
|
|
606
|
+
LIMIT ?`).all(Z).map((X)=>this.toEntity(X))}toEntity($){return t0.create({id:$.id,filePath:$.file_path,fileType:$.file_type,projectEncoded:$.project_encoded??void 0,content:$.content,contentHash:$.content_hash,lastIndexedAt:new Date($.last_indexed_at),createdAt:new Date($.created_at)})}}var G5=`
|
|
607
|
+
INSERT INTO memory_files (file_path, file_type, project_encoded, content, content_hash, last_indexed_at)
|
|
608
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
609
|
+
ON CONFLICT(file_path) DO UPDATE SET
|
|
610
|
+
file_type = excluded.file_type,
|
|
611
|
+
project_encoded = excluded.project_encoded,
|
|
612
|
+
content = excluded.content,
|
|
613
|
+
content_hash = excluded.content_hash,
|
|
614
|
+
last_indexed_at = excluded.last_indexed_at
|
|
615
|
+
`;var j9=L(()=>{S4()});var _5={};y(_5,{SqliteFrictionRepository:()=>x0});class x0{db;constructor($){this.db=$}async save($){let Z=this.db.prepare(`
|
|
616
|
+
INSERT INTO friction_log (description, severity, category, tool, tags, status, context, source_project, logged_at, resolved_at, resolution, last_reviewed_at)
|
|
617
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
618
|
+
`).run($.description,$.severity,$.category,$.tool,$.tags?JSON.stringify($.tags):null,$.status,$.context??null,$.sourceProject??null,$.loggedAt.toISOString(),$.resolvedAt?.toISOString()??null,$.resolution??null,$.lastReviewedAt?.toISOString()??null);return C0.create({id:Number(Z.lastInsertRowid),description:$.description,severity:$.severity,category:$.category,status:$.status,tool:$.tool,tags:$.tags,lastReviewedAt:$.lastReviewedAt,context:$.context,sourceProject:$.sourceProject,loggedAt:$.loggedAt,resolvedAt:$.resolvedAt,resolution:$.resolution})}async findById($){let Z=this.db.prepare("SELECT * FROM friction_log WHERE id = ?").get($);return Z?this.toEntity(Z):null}async findOpen(){return this.db.prepare("SELECT * FROM friction_log WHERE status = 'open' ORDER BY logged_at DESC").all().map((Z)=>this.toEntity(Z))}async findAll($){let Z=[],K=[];if($?.status)Z.push("status = ?"),K.push($.status);if($?.category)Z.push("category = ?"),K.push($.category);if($?.tool)Z.push("tool = ?"),K.push($.tool);if($?.sourceProject)Z.push("source_project = ?"),K.push($.sourceProject);let X=Z.length>0?`WHERE ${Z.join(" AND ")}`:"",Y=$?.limit??100;K.push(Y);let Q=`SELECT * FROM friction_log ${X} ORDER BY logged_at DESC LIMIT ?`;return this.db.prepare(Q).all(...K).map((_)=>this.toEntity(_))}async resolve($,Z){if(this.db.prepare("UPDATE friction_log SET status = 'resolved', resolution = ?, resolved_at = ? WHERE id = ?").run(Z,new Date().toISOString(),$).changes===0)throw Error(`Friction entry with id ${$} not found`)}async updateStatus($,Z){if(this.db.prepare("UPDATE friction_log SET status = ? WHERE id = ?").run(Z,$).changes===0)throw Error(`Friction entry with id ${$} not found`)}async getStats(){let $=this.db.prepare(`
|
|
619
|
+
SELECT
|
|
620
|
+
COUNT(*) as total,
|
|
621
|
+
COALESCE(SUM(CASE WHEN status = 'open' THEN 1 ELSE 0 END), 0) as open_count,
|
|
622
|
+
COALESCE(SUM(CASE WHEN status = 'resolved' THEN 1 ELSE 0 END), 0) as resolved_count,
|
|
623
|
+
COALESCE(SUM(CASE WHEN status = 'wont-fix' THEN 1 ELSE 0 END), 0) as wont_fix_count,
|
|
624
|
+
AVG(CASE WHEN resolved_at IS NOT NULL
|
|
625
|
+
THEN julianday(resolved_at) - julianday(logged_at) END) as avg_resolve_days
|
|
626
|
+
FROM friction_log
|
|
627
|
+
`).get(),Z=this.db.prepare("SELECT severity, COUNT(*) as count FROM friction_log GROUP BY severity").all(),K={low:0,medium:0,high:0,critical:0};for(let H of Z)K[H.severity]=H.count;let X=this.db.prepare("SELECT category, COUNT(*) as count FROM friction_log GROUP BY category").all(),Y={};for(let H of X)Y[H.category]=H.count;let Q=this.db.prepare("SELECT tool, COUNT(*) as count FROM friction_log GROUP BY tool").all(),G={};for(let H of Q)G[H.tool]=H.count;let _=this.db.prepare(`
|
|
628
|
+
SELECT id, description,
|
|
629
|
+
julianday('now') - julianday(logged_at) as days_open
|
|
630
|
+
FROM friction_log
|
|
631
|
+
WHERE status = 'open'
|
|
632
|
+
ORDER BY logged_at ASC
|
|
633
|
+
LIMIT 1
|
|
634
|
+
`).get(),J=_?{id:_.id,description:_.description,daysOpen:Math.floor(_.days_open)}:null;return{total:$.total,open:$.open_count,resolved:$.resolved_count,wontFix:$.wont_fix_count,bySeverity:K,byCategory:Y,byTool:G,meanTimeToResolve:$.avg_resolve_days??null,oldestOpen:J}}async getWeeklyTrends($){let Z=[],K=new Date;for(let _=$-1;_>=0;_--){let J=new Date(K);J.setDate(J.getDate()-_*7);let H=J.getFullYear(),V=new Date(H,0,1),B=Math.ceil((J.getTime()-V.getTime())/86400000),z=Math.ceil((B+V.getDay())/7),W=`${H}-W${String(z).padStart(2,"0")}`;Z.push(W)}let X=this.db.prepare(`
|
|
635
|
+
SELECT strftime('%Y-W', logged_at) || printf('%02d', CAST(strftime('%W', logged_at) AS INTEGER)) as week,
|
|
636
|
+
COUNT(*) as count
|
|
637
|
+
FROM friction_log
|
|
638
|
+
WHERE logged_at >= ?
|
|
639
|
+
GROUP BY week
|
|
640
|
+
`).all(new Date(K.getTime()-$*7*86400000).toISOString()),Y=new Map(X.map((_)=>[_.week,_.count])),Q=this.db.prepare(`
|
|
641
|
+
SELECT strftime('%Y-W', resolved_at) || printf('%02d', CAST(strftime('%W', resolved_at) AS INTEGER)) as week,
|
|
642
|
+
COUNT(*) as count
|
|
643
|
+
FROM friction_log
|
|
644
|
+
WHERE resolved_at IS NOT NULL AND resolved_at >= ?
|
|
645
|
+
GROUP BY week
|
|
646
|
+
`).all(new Date(K.getTime()-$*7*86400000).toISOString()),G=new Map(Q.map((_)=>[_.week,_.count]));return Z.map((_)=>({week:_,newCount:Y.get(_)??0,resolvedCount:G.get(_)??0}))}async markReviewed($,Z){this.db.prepare("UPDATE friction_log SET last_reviewed_at = ? WHERE tool = ? AND status = 'open'").run(Z.toISOString(),$)}async findPatterns($){let Z=this.db.prepare(`
|
|
647
|
+
SELECT tool, category, COUNT(*) as count
|
|
648
|
+
FROM friction_log
|
|
649
|
+
WHERE status = 'open'
|
|
650
|
+
GROUP BY tool, category
|
|
651
|
+
HAVING COUNT(*) >= ?
|
|
652
|
+
ORDER BY count DESC
|
|
653
|
+
`).all($),K=[];for(let X of Z){let Y=this.db.prepare("SELECT * FROM friction_log WHERE tool = ? AND category = ? AND status = 'open'").all(X.tool,X.category);K.push({tool:X.tool,category:X.category,count:X.count,entries:Y.map((Q)=>this.toEntity(Q))})}return K}async deleteByPattern($){return this.db.prepare("DELETE FROM friction_log WHERE description LIKE $pattern").run({$pattern:$}),this.db.query("SELECT changes() as count").get().count}toEntity($){return C0.create({id:$.id,description:$.description,severity:$.severity,category:$.category,status:$.status,tool:$.tool,tags:$.tags?JSON.parse($.tags):void 0,lastReviewedAt:$.last_reviewed_at?new Date($.last_reviewed_at):void 0,context:$.context??void 0,sourceProject:$.source_project??void 0,loggedAt:new Date($.logged_at),resolvedAt:$.resolved_at?new Date($.resolved_at):void 0,resolution:$.resolution??void 0})}}var u4=L(()=>{C4()});var J5={};y(J5,{SqliteBackfillStateRepository:()=>X4});class X4{db;constructor($){this.db=$}async findBySessionId($){let Z=this.db.prepare("SELECT * FROM backfill_state WHERE session_id = ?").get($);if(!Z)return null;return this.toEntity(Z)}async findAll(){return this.db.prepare("SELECT * FROM backfill_state ORDER BY backfilled_at DESC").all().map((Z)=>this.toEntity(Z))}async save($){this.db.prepare(`INSERT OR REPLACE INTO backfill_state
|
|
654
|
+
(session_id, backfilled_at, daily_log_path, success, error_message)
|
|
655
|
+
VALUES (?, ?, ?, ?, ?)`).run($.sessionId,$.backfilledAt.toISOString(),$.dailyLogPath,$.success?1:0,$.errorMessage??null)}async countByStatus(){let $=this.db.prepare(`SELECT
|
|
656
|
+
COUNT(*) as total,
|
|
657
|
+
SUM(CASE WHEN success = 1 THEN 1 ELSE 0 END) as succeeded,
|
|
658
|
+
SUM(CASE WHEN success = 0 THEN 1 ELSE 0 END) as failed
|
|
659
|
+
FROM backfill_state`).get();return{total:$.total,succeeded:$.succeeded??0,failed:$.failed??0}}toEntity($){return y0.create({sessionId:$.session_id,backfilledAt:new Date($.backfilled_at),dailyLogPath:$.daily_log_path,success:$.success===1,errorMessage:$.error_message??void 0})}}var x9=()=>{};var H5={};y(H5,{SqliteFactRepository:()=>E0});class E0{db;constructor($){this.db=$}async findById($){let Z=this.db.prepare("SELECT * FROM facts WHERE id = ?").get($);if(!Z)return null;return this.toEntity(Z)}async findByUuid($){let Z=this.db.prepare("SELECT * FROM facts WHERE uuid = ?").get($);if(!Z)return null;return this.toEntity(Z)}async findByProject($){return this.db.prepare("SELECT * FROM facts WHERE project = ? ORDER BY observed_at DESC").all($).map((K)=>this.toEntity(K))}async findRecent($){return this.db.prepare("SELECT * FROM facts ORDER BY observed_at DESC LIMIT ?").all($).map((K)=>this.toEntity(K))}async save($){let Z=$.metadata?JSON.stringify($.metadata):null,K=await this.findByUuid($.uuid);if(K)return this.db.prepare(`
|
|
660
|
+
UPDATE facts
|
|
661
|
+
SET type = ?, project = ?, content = ?, metadata = ?, observed_at = ?, superseded_at = ?, superseded_by = ?, updated_at = datetime('now')
|
|
662
|
+
WHERE uuid = ?
|
|
663
|
+
`).run($.type,$.project,$.content,Z,$.observedAt.toISOString(),$.supersededAt?$.supersededAt.toISOString():null,$.supersededBy,$.uuid),$.withId(K.id);else{let X=this.db.prepare(`
|
|
664
|
+
INSERT INTO facts (
|
|
665
|
+
uuid, type, project, content, metadata, observed_at, superseded_at, superseded_by
|
|
666
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
667
|
+
`).run($.uuid,$.type,$.project,$.content,Z,$.observedAt.toISOString(),$.supersededAt?$.supersededAt.toISOString():null,$.supersededBy);return $.withId(Number(X.lastInsertRowid))}}async saveMany($){let Z=[];return this.db.transaction(()=>{for(let X of $){let Y=X.metadata?JSON.stringify(X.metadata):null,Q=this.db.prepare("SELECT id FROM facts WHERE uuid = ?").get(X.uuid);if(Q)this.db.prepare(`
|
|
668
|
+
UPDATE facts
|
|
669
|
+
SET type = ?, project = ?, content = ?, metadata = ?, observed_at = ?, superseded_at = ?, superseded_by = ?, updated_at = datetime('now')
|
|
670
|
+
WHERE uuid = ?
|
|
671
|
+
`).run(X.type,X.project,X.content,Y,X.observedAt.toISOString(),X.supersededAt?X.supersededAt.toISOString():null,X.supersededBy,X.uuid),Z.push(X.withId(Q.id));else{let G=this.db.prepare(`
|
|
672
|
+
INSERT INTO facts (
|
|
673
|
+
uuid, type, project, content, metadata, observed_at, superseded_at, superseded_by
|
|
674
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
675
|
+
`).run(X.uuid,X.type,X.project,X.content,Y,X.observedAt.toISOString(),X.supersededAt?X.supersededAt.toISOString():null,X.supersededBy);Z.push(X.withId(Number(G.lastInsertRowid)))}}})(),Z}async search($,Z=20){return this.db.prepare(`
|
|
676
|
+
SELECT f.* FROM facts f
|
|
677
|
+
JOIN facts_fts fts ON f.id = fts.rowid
|
|
678
|
+
WHERE facts_fts MATCH ?
|
|
679
|
+
ORDER BY f.observed_at DESC
|
|
680
|
+
LIMIT ?
|
|
681
|
+
`).all($,Z).map((X)=>this.toEntity(X))}async superseded($,Z,K){this.db.prepare("UPDATE facts SET superseded_at = ?, superseded_by = ?, updated_at = datetime('now') WHERE uuid = ?").run(Z.toISOString(),K,$)}async supersede($,Z,K){await this.superseded($,Z,K)}async findAll(){return this.db.prepare("SELECT * FROM facts ORDER BY observed_at DESC").all().map((Z)=>this.toEntity(Z))}async clearAll(){this.db.exec("DELETE FROM facts;")}toEntity($){return Z0.create({id:$.id,uuid:$.uuid,type:$.type,project:$.project,content:$.content,metadata:$.metadata?JSON.parse($.metadata):void 0,observedAt:new Date($.observed_at),supersededAt:$.superseded_at?new Date($.superseded_at):null,supersededBy:$.superseded_by??null})}}var q1=L(()=>{Z4()});class d4{db;constructor($){this.db=$}async findById($){let Z=this.db.prepare("SELECT * FROM extraction_log WHERE session_id = ?").get($);if(!Z)return null;return this.toEntry(Z)}async save($){this.db.prepare(`
|
|
682
|
+
INSERT OR REPLACE INTO extraction_log (
|
|
683
|
+
session_id, mode, facts_added, facts_updated, facts_superseded,
|
|
684
|
+
facts_skipped, provider, model, tokens_consumed, extracted_at
|
|
685
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
686
|
+
`).run($.sessionId,$.mode,$.factsAdded,$.factsUpdated,$.factsSuperseded,$.factsSkipped,$.provider,$.model,$.tokensConsumed,$.extractedAt.toISOString())}async findAll(){return this.db.prepare("SELECT * FROM extraction_log ORDER BY extracted_at DESC").all().map((Z)=>this.toEntry(Z))}async clearAll(){this.db.exec("DELETE FROM extraction_log;")}toEntry($){return{sessionId:$.session_id,mode:$.mode,factsAdded:$.facts_added,factsUpdated:$.facts_updated,factsSuperseded:$.facts_superseded,factsSkipped:$.facts_skipped,provider:$.provider,model:$.model,tokensConsumed:$.tokens_consumed,extractedAt:new Date($.extracted_at)}}}var E9=L(()=>{M0();A1();X5();F9();Y5();M9();j9();u4();x9();q1()});class O1{db;constructor($){this.db=$}async search($,Z){let K=Z?.limit??20,X=o0($.value);if(!X)return[];let{sql:Y,params:Q}=this.buildSearchQuery(X,K,Z),_=this.db.prepare(Y).all(...Q);if(_.length===0)return[];return this.normalizeBm25Scores(_).map((H)=>W0.create({sessionId:H.session_id,messageId:H.id,snippet:H.snippet,score:H.normalizedScore,timestamp:new Date(H.timestamp),role:H.role}))}buildSearchQuery($,Z,K){let X=[$],Y=["messages_fts MATCH ?"],Q=`
|
|
687
|
+
FROM messages_fts f
|
|
688
|
+
JOIN messages_meta m ON f.rowid = m.rowid
|
|
689
|
+
`;if(K?.projectFilter)Q+=`
|
|
690
|
+
JOIN sessions s ON m.session_id = s.id
|
|
691
|
+
`,Y.push("LOWER(s.project_name) LIKE LOWER(?)"),X.push(`%${K.projectFilter}%`);if(K?.roleFilter)if(Array.isArray(K.roleFilter)){let _=K.roleFilter.map(()=>"?").join(", ");Y.push(`m.role IN (${_})`),X.push(...K.roleFilter)}else Y.push("m.role = ?"),X.push(K.roleFilter);if(K?.sessionFilter)Y.push("m.session_id = ?"),X.push(K.sessionFilter);if(K?.sinceDate)Y.push("m.timestamp >= ?"),X.push(K.sinceDate.toISOString());if(K?.beforeDate)Y.push("m.timestamp <= ?"),X.push(K.beforeDate.toISOString());return X.push(Z),{sql:`
|
|
692
|
+
SELECT
|
|
693
|
+
m.id,
|
|
694
|
+
m.session_id,
|
|
695
|
+
m.role,
|
|
696
|
+
m.content,
|
|
697
|
+
m.timestamp,
|
|
698
|
+
bm25(messages_fts) as score,
|
|
699
|
+
snippet(messages_fts, 0, '<mark>', '</mark>', '...', 64) as snippet
|
|
700
|
+
${Q}
|
|
701
|
+
WHERE ${Y.join(" AND ")}
|
|
702
|
+
ORDER BY score
|
|
703
|
+
LIMIT ?
|
|
704
|
+
`,params:X}}normalizeBm25Scores($){if($.length===0)return[];let Z=$[0];if($.length===1&&Z)return[{...Z,normalizedScore:1}];let K=$.map((G)=>G.score),X=Math.min(...K),Y=Math.max(...K);if(X===Y)return $.map((G)=>({...G,normalizedScore:1}));let Q=Y-X;return $.map((G)=>({...G,normalizedScore:(Y-G.score)/Q}))}}var V5=()=>{};class U1{db;fts5Service;embeddingRepo;providerFactory;config;sqliteVecAvailable;lastSearchMeta=null;constructor($){this.db=$.db,this.fts5Service=$.fts5Service,this.embeddingRepo=$.embeddingRepo,this.providerFactory=$.providerFactory,this.config=$.config,this.sqliteVecAvailable=$.sqliteVecAvailable}getLastSearchMeta(){return this.lastSearchMeta}async search($,Z){let K=performance.now(),X=this.embeddingRepo.getEmbeddedCount(),Y=this.embeddingRepo.getTotalMessageCount(),Q=Y>0?X/Y:0,G=this.sqliteVecAvailable&&X>0,_={fts:!0,vector:G,hybrid:G},J=this.resolveMode(Z?.mode,X),H=!1,V,B;try{switch(J.effectiveMode){case"fts":B=await this.ftsSearch($,Z);break;case"vector":B=await this.vectorSearch($,Z);break;case"hybrid":{let I=await this.hybridSearch($,Z);if(B=I.results,I.degraded)H=!0,V=I.degradationReason}break}}catch(I){if(J.effectiveMode!=="vector"&&!(I instanceof j))B=await this.ftsSearch($,Z),H=!0,V="provider_failure";else throw I}B=this.applyDecayToResults(B,Z);let z=J.degraded||H,W=V??(J.degraded?J.reason:void 0),N=z&&!J.degraded?"fts":J.effectiveMode,q=performance.now()-K;return this.lastSearchMeta={mode:N,modeReason:z?W??J.reason:J.reason,degraded:z,degradationReason:z?W:void 0,embeddingCoverage:Q,capabilities:_,timingMs:q},B}resolveMode($,Z=0){let K=this.config.search?.defaultMode??"auto",X=$??K;if(X==="fts")return{effectiveMode:"fts",degraded:!1,reason:"explicit"};if(X==="vector"){if(!this.sqliteVecAvailable)throw new j(F.VECTOR_UNAVAILABLE,"Vector search requires sqlite-vec extension",{suggestion:"Run 'memory doctor' to check extension status"});if(Z===0)throw new j(F.VECTOR_UNAVAILABLE,"No embeddings found in database",{suggestion:"Run 'memory sync --embed' to generate embeddings"});return{effectiveMode:"vector",degraded:!1,reason:"explicit"}}if(X==="hybrid"){if(!this.sqliteVecAvailable||Z===0)return{effectiveMode:"fts",degraded:!0,reason:!this.sqliteVecAvailable?"sqlite_vec_unavailable":"no_embeddings"};return{effectiveMode:"hybrid",degraded:!1,reason:"explicit"}}if(!this.sqliteVecAvailable||Z===0)return{effectiveMode:"fts",degraded:!1,reason:"no_embeddings"};return{effectiveMode:"hybrid",degraded:!1,reason:"auto_hybrid"}}applyDecayToResults($,Z){if(!(this.config.search?.temporalDecay?.enabled!==!1&&!Z?.noDecay)||$.length===0)return $;let X=this.config.search?.temporalDecay?.halfLifeDays??30,Q=new Date().getTime(),G=86400000,_=$.map((J)=>{let H=(Q-J.timestamp.getTime())/G,V=Math.pow(0.5,H/X),B=Math.max(0,Math.min(1,J.score*V));return{result:J,decayedScore:B}});return _.sort((J,H)=>H.decayedScore-J.decayedScore),_.map(({result:J,decayedScore:H})=>W0.create({sessionId:J.sessionId,messageId:J.messageId,snippet:J.snippet,score:H,timestamp:J.timestamp,role:J.role,source:J.source,rawScores:J.rawScores}))}async ftsSearch($,Z){return(await this.fts5Service.search($,Z)).map((X)=>W0.create({sessionId:X.sessionId,messageId:X.messageId,snippet:X.snippet,score:X.score,timestamp:X.timestamp,role:X.role,source:"fts",rawScores:{bm25:X.score}}))}async getProvider($){try{let Z=this.providerFactory.createFromConfig(this.config);if(!Z){if($)throw new j(F.VECTOR_UNAVAILABLE,"Embedding provider is disabled in configuration");return null}if(!Z.isReady())await Z.initialize();return Z}catch(Z){if($){if(Z instanceof j)throw Z;throw new j(F.VECTOR_UNAVAILABLE,`Embedding provider failed to initialize: ${A(Z)}`)}return null}}async embedQuery($,Z){return(await Z.embed($)).embedding}checkDimensionMismatch($){if(this.embeddingRepo.getEmbeddedCount()===0)return null;let K=this.getStoredEmbeddingDimensions();if(K===null)return null;let X=$.dimensions;if(X!==K)return`dimension_mismatch (stored: ${K}, provider: ${X})`;return null}getStoredEmbeddingDimensions(){try{let $=this.db.prepare("SELECT embedding FROM message_embeddings LIMIT 1").get();if(!$||!$.embedding)return null;let Z=$.embedding;if(Z instanceof Float32Array)return Z.length;if(Z instanceof ArrayBuffer||Z.byteLength!==void 0)return Z.byteLength/4;return null}catch{return null}}async vectorSearch($,Z){let K=await this.getProvider(!0);if(!K)throw new j(F.VECTOR_UNAVAILABLE,"Embedding provider unavailable");let X=this.checkDimensionMismatch(K);if(X)throw new j(F.EMBEDDING_DIMENSION_MISMATCH,`Cannot run vector search: ${X}`);let Y=await this.embedQuery($.value,K),Q=Z?.limit??20,G=Q*W5,_=this.embeddingRepo.vectorKnnSearch(Y,G);if(_.length===0)return[];let J=_.map((B)=>B.rowid),H=this.hydrateByRowids(J),V=[];for(let B=0;B<_.length&&V.length<Q;B++){let z=_[B];if(!z)continue;let W=H.get(z.rowid);if(!W)continue;if(!this.passesFilters(W,Z))continue;let N=this.vectorSnippet(W.content),q=Math.max(0,Math.min(1,1-z.distance/2));V.push(W0.create({sessionId:W.session_id,messageId:W.id,snippet:N,score:q,timestamp:new Date(W.timestamp),role:W.role,source:"vector",rawScores:{cosine:z.distance}}))}return V}async hybridSearch($,Z){let K=Z?.limit??20,X=K*W5,Y={...Z,limit:X},Q=await this.fts5Service.search($,Y),G=[],_=null,J=!1,H;try{if(_=await this.getProvider(!1),_){let O=this.checkDimensionMismatch(_);if(O)_=null,J=!0,H=O;else{let R=await this.embedQuery($.value,_);G=this.embeddingRepo.vectorKnnSearch(R,X)}}else J=!0,H="provider_unavailable"}catch(O){G=[],J=!0,H=`provider_failure: ${A(O)}`}if(G.length===0&&Q.length>0)return{results:Q.map((R)=>W0.create({sessionId:R.sessionId,messageId:R.messageId,snippet:R.snippet,score:R.score,timestamp:R.timestamp,role:R.role,source:"fts",rawScores:{bm25:R.score}})).slice(0,K),degraded:J,degradationReason:H};if(Q.length===0&&G.length===0)return{results:[],degraded:J,degradationReason:H};let V=this.buildFtsRowidMap(Q),B=Q.map((O,R)=>({rowid:V.get(O.messageId)??0,rank:R+1,source:"fts",rawScore:O.score})),z=G.map((O,R)=>({rowid:O.rowid,rank:R+1,source:"vector",rawScore:O.distance})),W=Y9(B,z,K);if(W.length===0)return{results:[],degraded:J,degradationReason:H};let N=W.map((O)=>O.rowid),q=this.hydrateByRowids(N),I=new Map;for(let O of W){let R=O.sources.some((x)=>x.source==="fts"),M=O.sources.some((x)=>x.source==="vector");if(R&&M)I.set(O.rowid,"both");else if(R)I.set(O.rowid,"fts");else I.set(O.rowid,"vector")}let T=W.map((O)=>({...O,score:O.normalizedScore})),U=[];for(let O of T){let R=q.get(O.rowid);if(!R)continue;if(!this.passesFilters(R,Z))continue;let M=I.get(O.rowid)??"fts",x=Q.find((q0)=>q0.messageId===R.id),o=x?x.snippet:this.vectorSnippet(R.content),A0=Math.max(0,Math.min(1,O.score)),N0={rrf:O.rrfScore};for(let q0 of O.sources){if(q0.source==="fts")N0.bm25=q0.rawScore;if(q0.source==="vector")N0.cosine=q0.rawScore}U.push(W0.create({sessionId:R.session_id,messageId:R.id,snippet:o,score:A0,timestamp:new Date(R.timestamp),role:R.role,source:M,rawScores:N0}))}return{results:U,degraded:J,degradationReason:H}}buildFtsRowidMap($){if($.length===0)return new Map;let Z=$.map((Y)=>Y.messageId),K=Z.map(()=>"?").join(","),X=this.db.prepare(`SELECT rowid, id FROM messages_meta WHERE id IN (${K})`).all(...Z);return new Map(X.map((Y)=>[Y.id,Y.rowid]))}hydrateByRowids($){if($.length===0)return new Map;let Z=$.map(()=>"?").join(","),K=this.db.prepare(`SELECT rowid, id, session_id, content, timestamp, role
|
|
705
|
+
FROM messages_meta
|
|
706
|
+
WHERE rowid IN (${Z})`).all(...$);return new Map(K.map((X)=>[X.rowid,X]))}vectorSnippet($){if($.length<=200)return $;return $.slice(0,200)+"..."}passesFilters($,Z){if(!Z)return!0;if(Z.projectFilter){let K=this.db.prepare("SELECT project_name FROM sessions WHERE id = ?").get($.session_id);if(!K||!K.project_name.toLowerCase().includes(Z.projectFilter.toLowerCase()))return!1}if(Z.roleFilter){if(Array.isArray(Z.roleFilter)){if(!Z.roleFilter.includes($.role))return!1}else if($.role!==Z.roleFilter)return!1}if(Z.sessionFilter&&$.session_id!==Z.sessionFilter)return!1;if(Z.sinceDate){if(new Date($.timestamp)<Z.sinceDate)return!1}if(Z.beforeDate){if(new Date($.timestamp)>Z.beforeDate)return!1}return!0}}var W5=4;var B5=L(()=>{g4()});class h0{db;constructor($){this.db=$}async getStats($=10){let Z=this.db.prepare(`
|
|
707
|
+
SELECT page_size * page_count as size
|
|
708
|
+
FROM pragma_page_count(), pragma_page_size()
|
|
709
|
+
`).get(),K=this.db.prepare(`
|
|
710
|
+
SELECT
|
|
711
|
+
s.project_name as projectName,
|
|
712
|
+
COUNT(DISTINCT s.id) as sessionCount,
|
|
713
|
+
COUNT(m.id) as messageCount
|
|
714
|
+
FROM sessions s
|
|
715
|
+
LEFT JOIN messages_meta m ON m.session_id = s.id
|
|
716
|
+
GROUP BY s.project_name
|
|
717
|
+
ORDER BY sessionCount DESC
|
|
718
|
+
LIMIT ?
|
|
719
|
+
`).all($),X=K.reduce((G,_)=>G+_.sessionCount,0),Y=K.reduce((G,_)=>G+_.messageCount,0),Q=this.db.prepare("SELECT COUNT(*) as totalToolUses FROM tool_uses").get();return{totalSessions:X,totalMessages:Y,totalToolUses:Q?.totalToolUses??0,databaseSizeBytes:Z?.size??0,projectBreakdown:K.map((G)=>({projectName:G.projectName,sessionCount:G.sessionCount,messageCount:G.messageCount}))}}}var z5={};y(z5,{SqliteProjectResolver:()=>e0,SqliteContextService:()=>s0});class s0{db;constructor($){this.db=$}async getProjectContext($,Z={}){let K=Z.topicsLimit??10,X=Z.toolsLimit??10,Y;if(Z.days){let I=new Date,T=new Date(I.getFullYear(),I.getMonth(),I.getDate());Y=new Date(T.getTime()-(Z.days-1)*24*60*60*1000)}let Q=this.db.prepare(`SELECT DISTINCT project_name, project_path_decoded, project_path_encoded
|
|
720
|
+
FROM sessions
|
|
721
|
+
WHERE LOWER(project_name) = LOWER(?)
|
|
722
|
+
LIMIT 1`).get($)??this.db.prepare(`SELECT project_name, project_path_decoded, project_path_encoded
|
|
723
|
+
FROM sessions
|
|
724
|
+
WHERE project_name LIKE '%' || ? || '%'
|
|
725
|
+
GROUP BY project_name
|
|
726
|
+
ORDER BY COUNT(*) DESC
|
|
727
|
+
LIMIT 1`).get($);if(!Q)return null;let G=Q.project_path_encoded,J=`
|
|
728
|
+
SELECT
|
|
729
|
+
COUNT(DISTINCT s.id) as sessionCount,
|
|
730
|
+
MAX(s.start_time) as lastActivity,
|
|
731
|
+
COUNT(CASE WHEN m.role = 'user' THEN 1 END) as userMessages,
|
|
732
|
+
COUNT(CASE WHEN m.role = 'assistant' THEN 1 END) as assistantMessages
|
|
733
|
+
FROM sessions s
|
|
734
|
+
LEFT JOIN messages_meta m ON m.session_id = s.id
|
|
735
|
+
WHERE s.project_path_encoded = ?
|
|
736
|
+
${Y?"AND s.start_time >= ?":""}
|
|
737
|
+
`,H=Y?this.db.prepare(J).get(G,Y.toISOString()):this.db.prepare(J).get(G);if(!H||H.sessionCount===0)return null;let B=`
|
|
738
|
+
SELECT t.name, COUNT(*) as count
|
|
739
|
+
FROM tool_uses t
|
|
740
|
+
JOIN sessions s ON t.session_id = s.id
|
|
741
|
+
WHERE s.project_path_encoded = ?
|
|
742
|
+
${Y?"AND t.timestamp >= ?":""}
|
|
743
|
+
GROUP BY t.name
|
|
744
|
+
ORDER BY count DESC
|
|
745
|
+
LIMIT ?
|
|
746
|
+
`,z=Y?this.db.prepare(B).all(G,Y.toISOString(),X):this.db.prepare(B).all(G,X),N=`
|
|
747
|
+
SELECT DISTINCT l.target_id as topic
|
|
748
|
+
FROM links l
|
|
749
|
+
${Y?`JOIN sessions s ON l.source_type = 'session' AND l.source_id = s.id
|
|
750
|
+
WHERE s.project_path_encoded = ?
|
|
751
|
+
AND l.target_type = 'topic'
|
|
752
|
+
AND s.start_time >= ?`:`JOIN sessions s ON l.source_type = 'session' AND l.source_id = s.id
|
|
753
|
+
WHERE s.project_path_encoded = ?
|
|
754
|
+
AND l.target_type = 'topic'`}
|
|
755
|
+
ORDER BY l.weight DESC
|
|
756
|
+
LIMIT ?
|
|
757
|
+
`,q=Y?this.db.prepare(N).all(G,Y.toISOString(),K):this.db.prepare(N).all(G,K);return{projectName:Q.project_name,projectPathDecoded:Q.project_path_decoded,sessionCount:H.sessionCount,totalMessages:H.userMessages+H.assistantMessages,userMessages:H.userMessages,assistantMessages:H.assistantMessages,recentTopics:q.map((I)=>I.topic),recentToolUses:z.map((I)=>({name:I.name,count:I.count})),lastActivity:H.lastActivity?new Date(H.lastActivity):null}}}class e0{db;constructor($){this.db=$}resolveProjectEncoded($){let Z=this.db.prepare(`SELECT DISTINCT project_path_encoded
|
|
758
|
+
FROM sessions
|
|
759
|
+
WHERE LOWER(project_name) = LOWER(?)
|
|
760
|
+
LIMIT 1`).get($);if(Z)return Z.project_path_encoded;return this.db.prepare(`SELECT project_path_encoded
|
|
761
|
+
FROM sessions
|
|
762
|
+
WHERE project_name LIKE '%' || ? || '%'
|
|
763
|
+
GROUP BY project_path_encoded
|
|
764
|
+
ORDER BY COUNT(*) DESC
|
|
765
|
+
LIMIT 1`).get($)?.project_path_encoded??null}resolveProjectName($){let Z=this.db.prepare(`SELECT DISTINCT project_name
|
|
766
|
+
FROM sessions
|
|
767
|
+
WHERE LOWER(project_name) = LOWER(?)
|
|
768
|
+
LIMIT 1`).get($);if(Z)return Z.project_name;return this.db.prepare(`SELECT project_name
|
|
769
|
+
FROM sessions
|
|
770
|
+
WHERE project_name LIKE '%' || ? || '%'
|
|
771
|
+
GROUP BY project_name
|
|
772
|
+
ORDER BY COUNT(*) DESC
|
|
773
|
+
LIMIT 1`).get($)?.project_name??null}}var A5=L(()=>{V5();B5()});var B0,L1;var P9=L(()=>{B0={local:{model:"Xenova/all-MiniLM-L6-v2",dimensions:384},openai:{model:"text-embedding-3-small",dimensions:1536},ollama:{model:"nomic-embed-text",dimensions:768},"openai-compatible":{model:"text-embedding-3-small",dimensions:1536}},L1={anthropic:"claude-3-5-sonnet-20241022",openai:"gpt-4o",ollama:"llama3","claude-cli":"claude-cli-print","openai-compatible":"gpt-4o"}});var n4={};y(n4,{saveConfig:()=>L0,resolveProviderDefaults:()=>L5,resolveEmbeddingApiKey:()=>Q4,loadConfig:()=>h,getConfigPath:()=>l4,getConfigDir:()=>$1,PROVIDER_DEFAULTS:()=>U5,DEFAULT_SEARCH_CONFIG:()=>p4,DEFAULT_REMOTE_SYNC_CONFIG:()=>S9,DEFAULT_LEGACY_MEMORY_FILES_CONFIG:()=>v9,DEFAULT_EMBEDDING_CONFIG:()=>I1,DEFAULT_CONFIG:()=>Y4,DEFAULT_AMBIENT_CONTEXT_CONFIG:()=>k9});import{randomUUID as D9}from"crypto";import{existsSync as N5,mkdirSync as T7,readFileSync as q5,writeFileSync as R7}from"fs";import{dirname as O5}from"path";function L5($,Z){let K=$.provider;if(K==="local"||!Z)return $;let X=U5[K],Y={...$};if(!("model"in Z))Y.model=X?.model??$.model;if(!("dimensions"in Z))Y.dimensions=X?.dimensions??$.dimensions;return Y}function Q4($,Z){let K=[$.apiKeyEnv,...Z].filter((Y)=>Boolean(Y));for(let Y of K){let Q=process.env[Y];if(Q){let G={apiKey:Q,source:"environment",envVar:Y,deprecatedPlaintext:!1};if($.apiKeyRef)G.ref=$.apiKeyRef;return G}}if($.apiKey){let Y={apiKey:$.apiKey,source:"plaintext-config",deprecatedPlaintext:!0};if($.apiKeyRef)Y.ref=$.apiKeyRef;return Y}let X={source:"missing",deprecatedPlaintext:!1};if($.apiKeyRef)X.ref=$.apiKeyRef;return X}function $1($){if($!==void 0)return O5($);return S0()}function l4($){if($!==void 0)return $;return u1()}function h($){let Z=l4($);if(!N5(Z)){let K=process.env.MEMORY_TEST_MACHINE_ID??D9(),X={...Y4,machineId:K};try{L0(X,$)}catch{}return X}try{let K=q5(Z,"utf-8"),X=JSON.parse(K),Y=X.machineId,Q=!1;if(!Y)Y=process.env.MEMORY_TEST_MACHINE_ID??D9(),Q=!0;let G=X.embedding,_={...I1,...G??{}},J={...S9,...X.remoteSync??{}},H={...v9,...X.legacyMemoryFiles??{}},V={...Y4,...X,machineId:Y,remoteSync:J,legacyMemoryFiles:H,embedding:L5(_,G),search:{...p4,...X.search??{},temporalDecay:{...p4.temporalDecay,...X.search?.temporalDecay??{}}},ambientContext:{...k9,...X.ambientContext??{}}};if(Q)try{L0(V,$)}catch{}return V}catch{console.warn("Invalid config.json, using defaults");let K=process.env.MEMORY_TEST_MACHINE_ID??D9();return{...Y4,machineId:K}}}function L0($,Z){let K=l4(Z),X=O5(K);T7(X,{recursive:!0});let Y={};if(N5(K))try{let G=q5(K,"utf-8");Y=JSON.parse(G)}catch{}let Q={...Y,...$};R7(K,JSON.stringify(Q,null,2)+`
|
|
774
|
+
`)}var p4,k9,S9,v9,U5,I1,Y4;var K0=L(()=>{l();P9();p4={defaultMode:"auto",temporalDecay:{enabled:!0,halfLifeDays:30}},k9={enabled:!0,budget:800},S9={enabled:!1,autoPush:!0,autoPull:!0},v9={enabled:!1},U5={...B0};I1={enabled:!0,provider:"local",model:"Xenova/all-MiniLM-L6-v2",dimensions:384,batchSize:100},Y4={autoSync:!0,recoveryOnStartup:!0,syncOnCompaction:!0,timeout:5000,logLevel:"info",logRetentionDays:7,showFailures:!1,embedding:I1,search:p4,ambientContext:k9,machineId:"",remoteSync:S9,legacyMemoryFiles:v9}});import{appendFileSync as OJ,existsSync as F7,mkdirSync as UJ,readFileSync as M7,renameSync as LJ,statSync as IJ}from"fs";import{dirname as j7,join as x7}from"path";function T1($){if($!==void 0)return j7($);return X0()}function I5($){if($!==void 0)return $;return x7(X0(),"sync.log")}function R1($=100,Z){let K=I5(Z);if(!F7(K))return[];try{let Y=M7(K,"utf-8").split(`
|
|
775
|
+
`).filter((G)=>G.trim()!==""),Q=[];for(let G of Y)try{let _=JSON.parse(G);Q.push(_)}catch{continue}return Q.slice(-$)}catch{return[]}}var a4=L(()=>{l()});var C9=L(()=>{l();t$();M9();A1()});var R5=L(()=>{K0();a4();C9()});var F5=L(()=>{a4()});var F1=L(()=>{K0();a4();C9();R5();F5();p$()});class y9{name="transformers-js";model;dimensions;_pipeline=null;constructor($){this.model=$?.model??"Xenova/all-MiniLM-L6-v2",this.dimensions=$?.dimensions??384}async initialize($){if(this._pipeline)return;let{pipeline:Z,env:K}=await import("@huggingface/transformers");K.allowLocalModels=!1;let X={dtype:"q8"};if($)X.progress_callback=(Y)=>{$({status:Y.status==="ready"?"ready":"downloading",file:Y.file??"",loaded:Y.loaded??0,total:Y.total??0})};try{this._pipeline=await Z("feature-extraction",this.model,X)}catch(Y){if(console.warn(`Native ONNX runtime failed: ${A(Y)}`),console.warn("Falling back to WASM backend (slower but universal)"),K.backends?.onnx?.wasm)K.backends.onnx.wasm.numThreads=1;try{this._pipeline=await Z("feature-extraction",this.model,{dtype:"q8",device:"wasm"})}catch(Q){throw Error(`Embedding initialization failed. Native: ${A(Y)}. WASM: ${A(Q)}`)}}}async embed($){if(!this._pipeline)throw Error("Provider not initialized. Call initialize() before embed().");let Z=await this._pipeline($,{pooling:"mean",normalize:!0}),K=new Float32Array(Z.tolist()[0]);return V0.create({embedding:K,model:this.model,dimensions:this.dimensions})}async embedBatch($){let Z=[];for(let K of $)Z.push(await this.embed(K));return Z}isReady(){return this._pipeline!==null}async dispose(){this._pipeline=null}}var M5=()=>{};class i4{name;model;dimensions;apiKey;baseUrl;_ready=!1;constructor($){this.apiKey=$.apiKey,this.name=$.providerId??"openai",this.model=$.model??"text-embedding-3-small",this.dimensions=$.dimensions??1536,this.baseUrl=$.baseUrl??"https://api.openai.com/v1"}async initialize($){this._ready=!0}async embed($){if(!this._ready)throw Error("Provider not initialized. Call initialize() before embed().");let Z=await fetch(`${this.baseUrl}/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify({model:this.model,input:$,dimensions:this.dimensions})});if(!Z.ok){let Q=await Z.text();throw Error(`OpenAI API error ${Z.status}: ${Q}`)}let X=(await Z.json()).data?.[0];if(!X)throw Error("OpenAI returned empty embeddings response");let Y=new Float32Array(X.embedding);return V0.create({embedding:Y,model:this.model,dimensions:this.dimensions})}async embedBatch($){if(!this._ready)throw Error("Provider not initialized. Call initialize() before embed().");let Z=await fetch(`${this.baseUrl}/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify({model:this.model,input:$,dimensions:this.dimensions})});if(!Z.ok){let Y=await Z.text();throw Error(`OpenAI API error ${Z.status}: ${Y}`)}return[...(await Z.json()).data].sort((Y,Q)=>Y.index-Q.index).map((Y)=>V0.create({embedding:new Float32Array(Y.embedding),model:this.model,dimensions:this.dimensions}))}isReady(){return this._ready}async dispose(){this._ready=!1}}var j5=()=>{};class w9{name="ollama";model;dimensions;baseUrl;_ready=!1;constructor($){this.model=$?.model??"nomic-embed-text",this.dimensions=$?.dimensions??768,this.baseUrl=$?.baseUrl??"http://localhost:11434"}async initialize($){let Z;try{Z=await fetch(`${this.baseUrl}/api/tags`,{method:"GET"})}catch(K){let X=A(K);throw Error(`Cannot reach Ollama server at ${this.baseUrl}. Ensure Ollama is running: ollama serve (${X})`)}if(!Z.ok)throw Error(`Ollama server returned ${Z.status} from ${this.baseUrl}/api/tags`);this._ready=!0}async embed($){if(!this._ready)throw Error("Provider not initialized. Call initialize() before embed().");let Z=await fetch(`${this.baseUrl}/api/embed`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:this.model,input:$})});if(!Z.ok){let Q=await Z.text();this.throwWithHint(Z.status,Q)}let X=(await Z.json()).embeddings?.[0];if(!X)throw Error("Ollama returned empty embeddings response");let Y=new Float32Array(X);return V0.create({embedding:Y,model:this.model,dimensions:this.dimensions})}async embedBatch($){if(!this._ready)throw Error("Provider not initialized. Call initialize() before embed().");let Z=await fetch(`${this.baseUrl}/api/embed`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:this.model,input:$})});if(!Z.ok){let X=await Z.text();this.throwWithHint(Z.status,X)}return(await Z.json()).embeddings.map((X)=>V0.create({embedding:new Float32Array(X),model:this.model,dimensions:this.dimensions}))}isReady(){return this._ready}async dispose(){this._ready=!1}throwWithHint($,Z){if($===404||Z.includes("not found"))throw Error(`Ollama error ${$}: ${Z}. Model '${this.model}' not found. Run: ollama pull ${this.model}`);throw Error(`Ollama error ${$}: ${Z}`)}}var x5=()=>{};function g0($){return["You are an expert developer assistant. Analyze the following conversation transcript between a user and an AI coding assistant.","Your task is to extract a structured JSON list of key facts that occurred during this conversation.","","Specifically, you should identify and classify facts into these categories:",'1. "decision": Key architectural choices, technology selections, conventions, or design decisions made.','2. "learning": Lessons learned, discoveries about tools, APIs, bugs found, environment specific issues, or workarounds.','3. "preference": User guidelines, rules, stylistic/operational preferences, or explicit constraints.','4. "friction": Pain points, slow processes, build issues, sync locks, file system access issues, command timeouts, or system bottlenecks.','5. "observation": Key metrics, observed state, runtime configurations, or general context findings.',"","For each fact, assign a confidence score between 0.0 and 1.0 based on how explicitly and clearly it was stated or agreed upon in the transcript.",'Provide optional structured "metadata" for additional context (e.g. rationale, severity, file path, system version, etc.).',"","CRITICAL: Your output MUST be a valid JSON array of objects. Do not include any explanation, markdown formatting outside of a JSON code block, or preambles. Output ONLY the JSON.","","Format:","["," {",' "type": "decision" | "learning" | "preference" | "friction" | "observation",',' "content": "Description of the fact",',' "metadata": { "key": "value" },',' "confidence": 0.95'," }","]","","Transcript:",$.map((K)=>`[${K.timestamp.toISOString()}] ${K.role.toUpperCase()}: ${K.content}`).join(`
|
|
776
|
+
|
|
777
|
+
`)].join(`
|
|
778
|
+
`)}function m0($){let Z=$.trim(),K=Z.match(/\[\s*\{[\s\S]*\}\s*\]/),X=K?K[0]:Z;try{let Y=JSON.parse(X);if(!Array.isArray(Y))return[];let Q=[];for(let G of Y){if(typeof G.content!=="string"||G.content.trim()==="")continue;let J=["decision","learning","preference","friction","observation"].includes(G.type)?G.type:"observation",H=typeof G.confidence==="number"?Math.max(0,Math.min(1,G.confidence)):0.8;Q.push({type:J,content:G.content.trim(),metadata:G.metadata&&typeof G.metadata==="object"?G.metadata:void 0,confidence:H})}return Q}catch(Y){return console.error("Failed to parse LLM facts JSON response:",Y),[]}}import P7 from"@anthropic-ai/sdk";class b9{providerId="anthropic";modelName;anthropic;constructor($){this.modelName=$.model??"claude-3-5-sonnet-20241022",this.anthropic=new P7({apiKey:$.apiKey})}async extract($){if($.length===0)return[];let Z=g0($);try{let X=(await this.anthropic.messages.create({model:this.modelName,max_tokens:4000,messages:[{role:"user",content:Z}]})).content[0],Y=X&&"text"in X?X.text:"";return m0(Y)}catch(K){throw console.error("Anthropic fact extraction API failed:",K),Error(`Anthropic API error: ${K.message}`)}}}var E5=()=>{};import{spawn as D7}from"child_process";class f9{providerId="claude-cli";modelName="claude-cli-print";async extract($){if($.length===0)return[];let Z=g0($);return new Promise((K,X)=>{let Y={...process.env};delete Y.CLAUDECODE;let Q=D7("claude",["-p","--output-format","text"],{env:Y,stdio:["pipe","pipe","pipe"]}),G="",_="";Q.stdout.on("data",(J)=>{G+=J.toString()}),Q.stderr.on("data",(J)=>{_+=J.toString()}),Q.on("error",(J)=>{X(Error(`Failed to spawn claude -p: ${J.message}`))}),Q.on("close",(J)=>{if(J===0)K(m0(G));else X(Error(`claude -p exited with code ${J}: ${_.trim()}`))}),Q.stdin.write(Z),Q.stdin.end()})}}var P5=()=>{};class h9{providerId="ollama";modelName;baseUrl;constructor($){this.baseUrl=$.baseUrl??"http://localhost:11434",this.modelName=$.model??"llama3"}async extract($){if($.length===0)return[];let Z=g0($);try{let K=`${this.baseUrl}/api/generate`,X=await fetch(K,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:this.modelName,prompt:Z,stream:!1,options:{temperature:0.1}})});if(!X.ok){let G=await X.text();throw Error(`HTTP ${X.status}: ${G}`)}let Q=(await X.json())?.response??"";return m0(Q)}catch(K){throw console.error("Ollama fact extraction API failed:",K),Error(`Ollama API error: ${K.message}`)}}}var D5=()=>{};class r4{providerId;modelName;apiKey;baseUrl;constructor($){this.apiKey=$.apiKey,this.providerId=$.providerId??"openai",this.modelName=$.model??"gpt-4o",this.baseUrl=$.baseUrl??"https://api.openai.com/v1"}async extract($){if($.length===0)return[];let Z=g0($);try{let K=await fetch(`${this.baseUrl}/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify({model:this.modelName,messages:[{role:"user",content:Z}],temperature:0.1})});if(!K.ok){let Q=await K.text();throw Error(`HTTP ${K.status}: ${Q}`)}let Y=(await K.json())?.choices?.[0]?.message?.content??"";return m0(Y)}catch(K){throw console.error("OpenAI fact extraction API failed:",K),Error(`OpenAI API error: ${K.message}`)}}}var k5=()=>{};function M1($){return{ready:!0,readyReason:$}}function J4($){return{ready:!1,readyReason:$}}function G4($,Z,K){let X=Q4($,Z);if(X.source==="missing")return J4(X.ref?"API key reference configured but not available at runtime; run through a secret injector or set embedding.apiKeyEnv":K);if(X.deprecatedPlaintext)return M1("Using deprecated plaintext config; prefer environment injection or embedding.apiKeyEnv");return M1()}function _4($,Z,K){let X=Q4($,Z);if(!X.apiKey)throw Error(`${K} API key is required. Set ${Z.join(" or ")} or configure embedding.apiKeyEnv for runtime injection. apiKeyRef is an opaque reference and is not resolved by memory-nexus.`);return X.apiKey}function S5($,Z){if(!$.baseUrl)throw Error(`openai-compatible ${Z} provider requires embedding.baseUrl`);return $.baseUrl}function k7(){return v5.map(($)=>$.id)}function S7(){return C5.map(($)=>$.id)}function w5($){return`Unsupported embedding provider: "${$}". Supported: ${k7().join(", ")}`}function b5($){return`Unsupported extraction provider: "${$}". Supported: ${S7().join(", ")}`}function f5($){let Z=y5.get($.provider);if(!Z)return J4(w5($.provider));return Z.checkReadiness($)}function h5($){let Z=y5.get($.provider);if(!Z)throw Error(w5($.provider));return Z.create($)}function o4($,Z=process.env){let K=Z.LLM_PROVIDER?.trim();if(K)return K;let X=$.embedding?.provider??"claude-cli";return X==="local"?"claude-cli":X}function m9($,Z,K=process.env){let X=g9.get(Z);if(!X)return"";return K.LLM_MODEL?.trim()||X.defaultModel}function g5($,Z=o4($)){let K=g9.get(Z);if(!K)return J4(b5(Z));return K.checkReadiness($.embedding)}function m5($){let Z=o4($),K=g9.get(Z);if(!K)throw Error(b5(Z));return K.create($.embedding,m9($,Z))}var v5,C5,y5,g9;var t4=L(()=>{K0();M5();j5();x5();E5();P5();D5();k5();P9();v5=[{id:"local",defaultModel:B0.local.model,defaultDimensions:B0.local.dimensions,checkReadiness:()=>M1(),create:($)=>new y9({model:$.model,dimensions:$.dimensions})},{id:"openai",defaultModel:B0.openai.model,defaultDimensions:B0.openai.dimensions,checkReadiness:($)=>G4($,["OPENAI_API_KEY"],"API key not available at runtime; set OPENAI_API_KEY or embedding.apiKeyEnv"),create:($)=>new i4({apiKey:_4($,["OPENAI_API_KEY"],"OpenAI embedding"),model:$.model,dimensions:$.dimensions,baseUrl:$.baseUrl})},{id:"ollama",defaultModel:B0.ollama.model,defaultDimensions:B0.ollama.dimensions,checkReadiness:()=>M1("Server reachability verified at sync time"),create:($)=>new w9({model:$.model,dimensions:$.dimensions,baseUrl:$.baseUrl})},{id:"openai-compatible",defaultModel:B0["openai-compatible"].model,defaultDimensions:B0["openai-compatible"].dimensions,checkReadiness:($)=>{if(!$.baseUrl)return J4("openai-compatible embedding provider requires embedding.baseUrl");return G4($,[],"API key not available at runtime; set embedding.apiKeyEnv for openai-compatible")},create:($)=>new i4({apiKey:_4($,[],"openai-compatible embedding"),model:$.model,dimensions:$.dimensions,baseUrl:S5($,"embedding"),providerId:"openai-compatible"})}],C5=[{id:"anthropic",defaultModel:L1.anthropic,checkReadiness:($)=>G4($,["ANTHROPIC_API_KEY"],"API key not available at runtime; set ANTHROPIC_API_KEY or embedding.apiKeyEnv"),create:($,Z)=>new b9({apiKey:_4($,["ANTHROPIC_API_KEY"],"Anthropic extraction"),model:Z})},{id:"openai",defaultModel:L1.openai,checkReadiness:($)=>G4($,["OPENAI_API_KEY"],"API key not available at runtime; set OPENAI_API_KEY or embedding.apiKeyEnv"),create:($,Z)=>new r4({apiKey:_4($,["OPENAI_API_KEY"],"OpenAI extraction"),model:Z})},{id:"ollama",defaultModel:L1.ollama,checkReadiness:()=>M1(),create:($,Z)=>new h9({baseUrl:$.baseUrl,model:Z})},{id:"claude-cli",defaultModel:L1["claude-cli"],checkReadiness:()=>M1(),create:()=>new f9},{id:"openai-compatible",defaultModel:L1["openai-compatible"],checkReadiness:($)=>{if(!$.baseUrl)return J4("openai-compatible extraction provider requires embedding.baseUrl");return G4($,[],"API key not available at runtime; set embedding.apiKeyEnv for openai-compatible")},create:($,Z)=>new r4({apiKey:_4($,[],"openai-compatible extraction"),model:Z,baseUrl:S5($,"extraction"),providerId:"openai-compatible"})}],y5=new Map(v5.map(($)=>[$.id,$])),g9=new Map(C5.map(($)=>[$.id,$]))});import{Database as u9}from"bun:sqlite";import{accessSync as c5,constants as u5,existsSync as d9,statSync as v7}from"fs";import{homedir as C7}from"os";import{join as c9}from"path";function p5($){try{return $.query("PRAGMA integrity_check(1);").get()?.integrity_check==="ok"?"ok":"corrupted"}catch{return"corrupted"}}function p9($){try{return $.query("PRAGMA quick_check(1);").get()?.quick_check==="ok"?"ok":"corrupted"}catch{return"corrupted"}}function j1($){if(!d9($))return{readable:!1,writable:!1};let Z=!1,K=!1;try{c5($,u5.R_OK),Z=!0}catch{}try{c5($,u5.W_OK),K=!0}catch{}return{readable:Z,writable:K}}function l9($,Z,K,X){let Y=X??F0(K),Q=h(Z),_=R1(1,$)[0];return{installed:Y.sessionEnd&&Y.preCompact,enabled:Q.autoSync,lastRun:_?new Date(_.timestamp):null}}function n9($){let Z=[];try{let K=h($);if(typeof K.autoSync!=="boolean")Z.push("autoSync is not a boolean");if(typeof K.recoveryOnStartup!=="boolean")Z.push("recoveryOnStartup is not a boolean");if(typeof K.syncOnCompaction!=="boolean")Z.push("syncOnCompaction is not a boolean");if(typeof K.timeout!=="number"||!Number.isFinite(K.timeout)||K.timeout<0)Z.push("timeout is not a valid positive number");if(!d5.includes(K.logLevel))Z.push(`logLevel "${K.logLevel}" is not valid (expected: ${d5.join(", ")})`);if(typeof K.logRetentionDays!=="number"||!Number.isFinite(K.logRetentionDays)||K.logRetentionDays<0)Z.push("logRetentionDays is not a valid positive number");if(typeof K.showFailures!=="boolean")Z.push("showFailures is not a boolean");return{valid:Z.length===0,issues:Z}}catch(K){let X=A(K);return Z.push(`Failed to load config: ${X}`),{valid:!1,issues:Z}}}function a9(){try{let $=n0("sqlite-vec"),Z=new u9(":memory:");try{return $.load(Z),{available:!0,version:Z.query("SELECT vec_version()").get()["vec_version()"]}}finally{Z.close()}}catch{return{available:!1,version:null}}}function i9($){let K=h($).embedding,X=f5(K);return{configured:!0,provider:K.provider,model:K.model,dimensions:K.dimensions,enabled:K.enabled,ready:X.ready,readyReason:X.readyReason}}function y7($){let Z=h($),K=o4(Z),X=g5(Z,K);return{provider:K,model:m9(Z,K),ready:X.ready,readyReason:X.readyReason}}function s4($){let Z=$?.dbPath??P(),K=b7(Z),X=$?.configDir??$1(),Y=$?.logsDir??T1(),Q=$?.sourceDir??c9(C7(),".claude","projects"),G=$?.logsDir?c9($.logsDir,"sync.log"):void 0,_=$?.configDir?c9($.configDir,"config.json"):void 0,J=j1(X),H=j1(Y),V=j1(Q),B={configDir:J.readable&&J.writable,logsDir:H.readable&&H.writable,sourceDir:V.readable},z=l9(G,_,$?.hookOverrides,$?.preCalculatedHookStatus),W=n9(_),N=h(_),q=i9(_),I=a9(),T=w7(Z,I,N),U=y7(_);return{database:K,permissions:B,hooks:z,config:W,embedding:q,sqliteVec:I,searchCapability:T,llmExtraction:U}}function w7($,Z,K){let X=0,Y=0;try{if(d9($)){let G=new u9($,{create:!1,readonly:!0});try{X=G.query("SELECT COUNT(*) as count FROM embedding_state").get()?.count??0,Y=G.query("SELECT COUNT(*) as count FROM messages_meta").get()?.count??0}finally{G.close()}}}catch{}let Q=Y>0?Math.round(X/Y*100):0;return{fts5:!0,sqliteVec:Z.available,embeddedCount:X,totalMessages:Y,coveragePercent:Q,defaultMode:K.search?.defaultMode??"auto",vectorReady:Z.available&&X>0}}function b7($){if(!d9($))return{exists:!1,readable:!1,writable:!1,integrity:"unknown",size:0};let K=j1($),X=0;try{X=v7($).size}catch{}let Y="unknown";if(K.readable)try{let Q=new u9($,{create:!1,readonly:!0});try{Y=p9(Q)}finally{Q.close()}}catch{Y="corrupted"}return{exists:!0,readable:K.readable,writable:K.writable,integrity:Y,size:X}}var d5;var l5=L(()=>{R9();F1();t4();d5=["debug","info","warn","error"]});var r9={};y(r9,{runHealthCheck:()=>s4,initializeDatabaseSafe:()=>$5,initializeDatabase:()=>S,getDefaultDbPath:()=>P,createSchema:()=>f4,closeDatabase:()=>D,checkpointDatabase:()=>e3,checkSqliteVecAvailability:()=>a9,checkQuickIntegrity:()=>p9,checkHookStatus:()=>l9,checkFts5Support:()=>$4,checkEmbeddingConfig:()=>i9,checkDirectoryPermissions:()=>j1,checkDatabaseIntegrity:()=>p5,checkConfigValidity:()=>n9,bulkOperationCheckpoint:()=>m4,TOPICS_TABLE:()=>m3,TOOL_USES_TABLE:()=>h3,SqliteToolUseRepository:()=>f0,SqliteStatsService:()=>h0,SqliteSessionRepository:()=>g,SqliteProjectResolver:()=>e0,SqliteMessageRepository:()=>G0,SqliteLinkRepository:()=>N1,SqliteFrictionRepository:()=>x0,SqliteExtractionStateRepository:()=>b0,SqliteContextService:()=>s0,SqliteBackfillStateRepository:()=>X4,SESSIONS_TABLE:()=>w3,SCHEMA_SQL:()=>U9,MESSAGE_EMBEDDINGS_TABLE:()=>d3,MESSAGES_META_TABLE:()=>b3,MESSAGES_FTS_TABLE:()=>f3,LINKS_TABLE:()=>g3,HybridSearchService:()=>U1,Fts5SearchService:()=>O1,FRICTION_LOG_TABLE:()=>l3,EmbeddingRepository:()=>j0,EXTRACTION_STATE_TABLE:()=>c3,EMBEDDING_STATE_TABLE:()=>u3,EMBEDDING_STATE_ADD_MODEL_NAME:()=>p3,BACKFILL_STATE_TABLE:()=>n3});var c=L(()=>{L9();R9();E9();A5();l5()});import{readdir as o9,stat as H4}from"fs/promises";import{join as V4}from"path";import{homedir as f7}from"os";class c0{claudeProjectsDir;resolver;constructor($){this.claudeProjectsDir=$?.claudeDir??V4(f7(),".claude","projects"),this.resolver=$?.projectNameResolver}async discoverSessions(){let $=[];try{await H4(this.claudeProjectsDir)}catch{return $}let Z;try{Z=await o9(this.claudeProjectsDir)}catch{return $}for(let K of Z){let X=V4(this.claudeProjectsDir,K);try{if(!(await H4(X)).isDirectory())continue}catch{continue}let Y;try{if(Y=t.fromEncoded(K),this.resolver){let Q=this.resolver.resolveFromEncodedPath(K);if(Q!==Y.projectName)Y=Y.withProjectName(Q)}}catch{continue}await this.scanProjectDirectory(X,Y,$)}return $}async getSessionFile($){return(await this.discoverSessions()).find((X)=>X.id===$)?.path??null}async scanProjectDirectory($,Z,K){let X;try{X=await o9($)}catch{return}for(let Y of X){let Q=V4($,Y);try{let G=await H4(Q);if(G.isFile()&&Y.endsWith(".jsonl")){let _=Y.slice(0,-6);K.push({id:_,path:Q,projectPath:Z,modifiedTime:G.mtime,size:G.size})}else if(G.isDirectory())await this.scanSubagentsDirectory(Q,Z,K)}catch{continue}}}async scanSubagentsDirectory($,Z,K){let X=V4($,"subagents");try{if(!(await H4(X)).isDirectory())return}catch{return}let Y;try{Y=await o9(X)}catch{return}for(let Q of Y){if(!Q.endsWith(".jsonl"))continue;let G=V4(X,Q);try{let _=await H4(G);if(_.isFile()){let J=Q.slice(0,-6);K.push({id:J,path:G,projectPath:Z,modifiedTime:_.mtime,size:_.size})}}catch{continue}}}}var n5=()=>{};import{readdirSync as h7,statSync as g7}from"fs";function m7($){return $.replace(/ /g,"-").replace(/-/g,"-")}class e4{rootDir;cache=new Map;dirCache=new Map;constructor($){this.rootDir=$}resolveFromEncodedPath($){let Z=/^[A-Za-z]--/,K=$;if(Z.test(K))K=K.slice(3);else if(K.startsWith("-"))K=K.slice(1);return this.resolveProjectName(K)}resolveProjectName($){let Z=this.cache.get($);if(Z!==void 0)return Z;let K=this.walkAndResolve(this.rootDir,$);return this.cache.set($,K),K}walkAndResolve($,Z){if(Z==="")return"";let K=this.listSubdirectories($),X=[];for(let Q of K){let G=m7(Q);X.push({name:Q,encoded:G})}X.sort((Q,G)=>G.encoded.length-Q.encoded.length);for(let Q of X){if(Z===Q.encoded)return Q.name;if(Z.startsWith(Q.encoded+"-")){let G=Z.slice(Q.encoded.length+1),_=`${$}/${Q.name}`,J=this.walkAndResolve(_,G);if(J!==this.fallbackLastSegment(G))return J;return J}}let Y=this.probeHiddenDirectories($,Z);if(Y!==void 0)return Y;return this.fallbackLastSegment(Z)}probeHiddenDirectories($,Z){let K=Z.split("-");for(let X=1;X<K.length;X++){let Y=K.slice(0,X).join("-"),Q=`${$}/${Y}`;if(this.isDirectory(Q)){let G=K.slice(X).join("-");if(G==="")return Y;let _=this.walkAndResolve(Q,G);if(_!==this.fallbackLastSegment(G))return _}}return}isDirectory($){try{return g7($).isDirectory()}catch{return!1}}listSubdirectories($){let Z=this.dirCache.get($);if(Z!==void 0)return Z;try{let X=h7($,{withFileTypes:!0}).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name);return this.dirCache.set($,X),X}catch{return this.dirCache.set($,[]),[]}}fallbackLastSegment($){let Z=$.split("-");return Z[Z.length-1]??""}}var a5=()=>{};import{readdir as c7,readFile as u7,stat as d7}from"fs/promises";import{join as p7,relative as l7}from"path";import{createHash as n7}from"crypto";class $${async discoverFiles(){let $=c1();try{await d7($)}catch{return[]}let Z=[];return await this.scanDirectory($,$,Z),Z}async scanDirectory($,Z,K){let X;try{X=await c7($,{withFileTypes:!0})}catch{return}for(let Y of X){let Q=p7($,Y.name);if(Y.isDirectory())await this.scanDirectory(Q,Z,K);else if(Y.isFile()&&Y.name.endsWith(".md")){let G=l7(Z,Q).split("\\").join("/"),_=this.classifyFileType(G);if(!_)continue;let J=await u7(Q,"utf8"),H=n7("sha256").update(J,"utf8").digest("hex"),V=this.extractProjectEncoded(G);K.push({filePath:G,absolutePath:Q,fileType:_,projectEncoded:V,contentHash:H,content:J})}}}classifyFileType($){if($.startsWith("daily/"))return"daily_log";if($.endsWith("DECISIONS.md"))return"decisions";if($.endsWith("LEARNINGS.md"))return"learnings";if($.endsWith("USER-PREFS.md"))return"user_prefs";return null}extractProjectEncoded($){return $.match(/^projects\/([^/]+)\//)?.[1]??void 0}}var i5=L(()=>{l()});var W4=L(()=>{n5();a5();i5()});function z0($,Z){let K=Z??new Date,X=$.getTime()-K.getTime(),Y=Math.abs(X);if(Y<3600000){let G=Math.round(X/60000);return B4.format(G,"minute")}if(Y<86400000){let G=Math.round(X/3600000);return B4.format(G,"hour")}if(Y<604800000){let G=Math.round(X/86400000);return B4.format(G,"day")}if(Y<2592000000){let G=Math.round(X/604800000);return B4.format(G,"week")}let Q=Math.round(X/2592000000);return B4.format(Q,"month")}function Z1($){let Z=$.getFullYear(),K=String($.getMonth()+1).padStart(2,"0"),X=String($.getDate()).padStart(2,"0"),Y=String($.getHours()).padStart(2,"0"),Q=String($.getMinutes()).padStart(2,"0");return`${Z}-${K}-${X} ${Y}:${Q}`}function I0($,Z){let K=z0($,Z),X=Z1($);return`${K} (${X})`}var B4;var u0=L(()=>{B4=new Intl.RelativeTimeFormat("en",{numeric:"auto",style:"long"})});function v($){let Z=$?.noColor??!!process.env.NO_COLOR,K=$?.forceColor??!!process.env.FORCE_COLOR,X=$?.isTTY??process.stdout.isTTY===!0;if(Z)return!1;if(K)return!0;return X}function P1($,Z,K){if(!K)return $;return`\x1B[${Z}m${$}\x1B[0m`}function s($,Z){return P1($,"1",Z??v())}function k($,Z){return P1($,"2",Z??v())}function w($,Z){return P1($,"32",Z??v())}function m($,Z){return P1($,"31",Z??v())}function u($,Z){return P1($,"33",Z??v())}function GZ($,Z){return P1($,"36",Z??v())}import _Z from"string-width";function e9($){return _Z($)}function $2($,Z){if(Z<=0)return"";if(e9($)<=Z)return $;let K="...",X=3;if(Z<=X)return".".repeat(Z);let Y=Z-X,Q="",G=0;for(let _ of $){let J=_Z(_);if(G+J>Y)break;Q+=_,G+=J}return Q+K}function G$($,Z){let K=e9($);if(K>=Z)return $;return $+" ".repeat(Z-K)}function Z2(){return process.stdout.columns||80}function K2($,Z,K=20){let X=Z2(),Y=e9(Z),Q=X-Y;return $2($,Q>K?Q:K)}var X2=()=>{};function _$($,Z={}){let K=BZ($.snippet),X=$.snippet.replace(/<\/?mark>/g,""),Y={sessionId:$.sessionId,messageId:$.messageId,role:$.role,score:$.score,timestamp:$.timestamp.toISOString(),snippet:X};if(Z.includeSearchMetaFields){if(Z.rank!==void 0)Y.rank=Z.rank;let Q=$.rawScores;if(Q)Y.raw_scores=Q;if($.source)Y.source=$.source;if(K.length>0)Y.highlights=K}return Y}function JZ($){let Z={score:$.score,file:$.file,title:$.title};if($.docid!==void 0)Z.docid=$.docid;if($.context!==void 0)Z.context=$.context;if($.snippet!==void 0)Z.snippet=$.snippet;return Z}function J$($){let Z={id:$.id,project:$.projectPath.projectName,projectPath:$.projectPath.decoded,startTime:$.startTime.toISOString()};if($.endTime)Z.endTime=$.endTime.toISOString();if($.messageCount!==void 0)Z.messageCount=$.messageCount;if($.summary!==void 0)Z.summary=$.summary;return Z}function HZ($){return{session:J$($.session),messages:$.messages.map(VK),toolUses:Array.from($.toolUses.values()).map(WK)}}function VK($){return{id:$.id,role:$.role,timestamp:$.timestamp.toISOString(),content:$.content}}function WK($){let Z={id:$.id,name:$.name,status:$.status,input:$.input};if($.result!==void 0)Z.result=$.result;return Z}function VZ($){return{session:J$($.session),weight:$.weight,hops:$.hops}}function Y2($){let Z={totalSessions:$.totalSessions,totalMessages:$.totalMessages,totalToolUses:$.totalToolUses,databaseSizeBytes:$.databaseSizeBytes,projectBreakdown:$.projectBreakdown.map((K)=>({projectName:K.projectName,sessionCount:K.sessionCount,messageCount:K.messageCount}))};if($.hooks)Z.hooks={installed:$.hooks.installed,autoSync:$.hooks.autoSync,pendingSessions:$.hooks.pendingSessions};return Z}function WZ($){return{projectName:$.projectName,projectPathDecoded:$.projectPathDecoded,sessionCount:$.sessionCount,totalMessages:$.totalMessages,userMessages:$.userMessages,assistantMessages:$.assistantMessages,recentTopics:[...$.recentTopics],recentToolUses:$.recentToolUses.map((Z)=>({name:Z.name,count:Z.count})),lastActivity:$.lastActivity?$.lastActivity.toISOString():null}}var d0=L(()=>{H$()});function Q2($,Z){switch($){case"json":return new qZ;case"quiet":return new OZ;case"verbose":return new UZ(Z);case"brief":return new NZ;default:return new AZ(Z)}}function BZ($){let Z=[],K=0,X=0;while(X<$.length)if($.startsWith("<mark>",X)){X+=6;let Y=$.indexOf("</mark>",X);if(Y===-1)break;Z.push({offset:K,length:Y-X}),K+=Y-X,X=Y+7}else K++,X++;return Z}function zZ($,Z){if(!Z)return $.replace(/<mark>/g,"*").replace(/<\/mark>/g,"*");return $.replace(/<mark>/g,"\x1B[1;36m").replace(/<\/mark>/g,"\x1B[0m")}class AZ{useColor;constructor($){this.useColor=$}formatResults($,Z){let K=Z?.contextBudget??D1;if($.length===0)return`No results found for: ${Z?.query??"query"}`;let X=`Found ${$.length} result(s):
|
|
779
|
+
|
|
780
|
+
`;for(let Y=0;Y<$.length;Y++){let Q=$[Y];if(!Q)continue;let G=this.formatResult(Q,Y+1);if(X.length+G.length>K){X+=`
|
|
781
|
+
(Output truncated - ${D1.toLocaleString()} char limit)
|
|
782
|
+
`;break}X+=G}return X}formatResult($,Z){let K=($.score*100).toFixed(0),X=$.sessionId.substring(0,16),Y=I0($.timestamp),Q=zZ($.snippet,this.useColor),G=$.role.charAt(0).toUpperCase()+$.role.slice(1),_=K2(Q," ");return`${Z}. [${K}%] [${G}] ${X}...
|
|
783
|
+
${Y}
|
|
784
|
+
${_}
|
|
785
|
+
|
|
786
|
+
`}formatError($){return`Error: ${A($)}`}formatSummary($){let Z=`Found ${$.found} results (showing ${$.shown})`;if($.truncated)Z+=" - truncated";return Z}}class NZ{formatResults($,Z){if($.length===0)return`No results for "${Z?.query??""}"`;return $.map((K)=>{let X=K.snippet.replace(/<\/?mark>/g,"").replace(/\s+/g," ").trim().slice(0,80),Y=Math.round(K.score*100);return`${K.sessionId} [${Y}%] ${X}`}).join(`
|
|
787
|
+
`)}formatError($){return`Error: ${A($)}`}formatSummary($){return""}}class qZ{formatResults($,Z){let K=Z?.contextBudget??D1,X=$.map((Q,G)=>_$(Q,{rank:G+1,includeSearchMetaFields:!!Z?.searchMeta}));if(Z?.searchMeta){let Q={query:Z.query??"",mode:Z.searchMeta.mode,mode_reason:Z.searchMeta.modeReason,total_results:$.length,embedding_coverage:Z.searchMeta.embeddingCoverage,degraded:Z.searchMeta.degraded,capabilities:Z.searchMeta.capabilities,timing_ms:Z.searchMeta.timingMs};if(Z.searchMeta.degradationReason)Q.degradation_reason=Z.searchMeta.degradationReason;return JSON.stringify({meta:Q,results:X},null,2)}let Y=JSON.stringify(X,null,2);if(Y.length>K){let Q=X.length;while(Q>0){let G=X.slice(0,Q);if(Y=JSON.stringify(G,null,2),Y.length<=K)break;Q--}}return Y}formatError($){let Z=A($);return JSON.stringify({error:Z})}formatSummary($){return""}}class OZ{formatResults($,Z){if($.length===0)return"";let K=Z2();return $.map((X)=>{let Y=X.sessionId.substring(0,16),Q=X.snippet.replace(/<mark>/g,"*").replace(/<\/mark>/g,"*"),G=`${Y} ${Q}`;return $2(G,K)}).join(`
|
|
788
|
+
`)}formatError($){return`Error: ${A($)}`}formatSummary($){return""}}class UZ{useColor;constructor($){this.useColor=$}formatResults($,Z){let K=Z?.contextBudget??D1;if($.length===0)return`No results found for: ${Z?.query??"query"}`;let X="";if(Z?.searchMeta){if(X+=`Mode: ${Z.searchMeta.mode}`,Z.searchMeta.degraded)X+=` (degraded: ${Z.searchMeta.degradationReason??"unknown"})`;X+=`
|
|
789
|
+
`}if(Z?.executionDetails){let Y=Z.executionDetails;if(X+=`=== Execution Details ===
|
|
790
|
+
`,Y.timeMs!==void 0)X+=`Time: ${Y.timeMs}ms
|
|
791
|
+
`;if(Y.ftsQuery)X+=`FTS5 Query: ${Y.ftsQuery}
|
|
792
|
+
`;if(Y.filtersApplied&&Y.filtersApplied.length>0)X+=`Filters: ${Y.filtersApplied.join(", ")}
|
|
793
|
+
`;X+=`
|
|
794
|
+
`}X+=`Found ${$.length} result(s):
|
|
795
|
+
|
|
796
|
+
`;for(let Y=0;Y<$.length;Y++){let Q=$[Y];if(!Q)continue;let G=this.formatResult(Q,Y+1,!!Z?.searchMeta);if(X.length+G.length>K){X+=`
|
|
797
|
+
(Output truncated - ${D1.toLocaleString()} char limit)
|
|
798
|
+
`;break}X+=G}return X}formatResult($,Z,K){let X=($.score*100).toFixed(0),Y=I0($.timestamp),Q=zZ($.snippet,this.useColor),G=$.role.charAt(0).toUpperCase()+$.role.slice(1),_=K2(Q," "),J=`${Z}. [${X}%] [${G}] ${$.sessionId}
|
|
799
|
+
${Y}
|
|
800
|
+
${_}
|
|
801
|
+
`;if(K&&$.rawScores){let H=[];if($.rawScores.bm25!==void 0)H.push(`bm25: ${$.rawScores.bm25}`);if($.rawScores.cosine!==void 0)H.push(`cosine: ${$.rawScores.cosine}`);if($.rawScores.rrf!==void 0)H.push(`rrf: ${$.rawScores.rrf}`);if(H.length>0)J+=` Scores: ${H.join(", ")}
|
|
802
|
+
`;if($.source)J+=` Source: ${$.source}
|
|
803
|
+
`}return J+=`
|
|
804
|
+
`,J}formatError($){let Z=A($),K=$ instanceof Error?$.stack:"";return`Error: ${Z}
|
|
805
|
+
${K??""}`}formatSummary($){let Z=`=== Summary ===
|
|
806
|
+
Found ${$.found} results (showing ${$.shown})`;if($.truncated)Z+=" - truncated due to context budget";return Z}}var D1=50000;var H$=L(()=>{u0();X2();d0()});function G2($,Z){switch($){case"json":return new TZ;case"quiet":return new RZ;case"verbose":return new FZ(Z);case"brief":return new IZ;default:return new LZ(Z)}}function V$($,Z,K){return $===1?Z:K}class LZ{useColor;constructor($){this.useColor=$}formatSessions($,Z){let K=$.length,X=`Sessions (${K} ${V$(K,"result","results")}):
|
|
807
|
+
|
|
808
|
+
`;for(let Y of $)X+=this.formatSession(Y);return X}formatSession($){let Z=$.id.substring(0,8),K=$.projectPath.projectName,X=z0($.startTime),Y=$.messageCount,Q=`${Y} ${V$(Y,"message","messages")}`,G=G$(Z,10),_=G$(K,20),J=G$(X,18);return` ${G}${_}${J}${k(Q,this.useColor)}
|
|
809
|
+
`}formatError($){return`Error: ${A($)}`}formatEmpty(){return"No sessions found. Run 'memory sync' to import sessions."}}class IZ{formatSessions($,Z){if($.length===0)return this.formatEmpty();return $.map((K)=>{let X=K.id.substring(0,8),Y=K.projectPath.projectName,Q=K.messageCount,G=z0(K.startTime);return`${X} ${Y} ${Q} ${G}`}).join(`
|
|
810
|
+
`)}formatError($){return`Error: ${A($)}`}formatEmpty(){return"No sessions found."}}class TZ{formatSessions($,Z){let K=$.map((X)=>({id:X.id,projectPath:X.projectPath.decoded,projectName:X.projectPath.projectName,startTime:X.startTime.toISOString(),endTime:X.endTime?.toISOString()??null,messageCount:X.messageCount}));return JSON.stringify(K,null,2)}formatError($){let Z=A($);return JSON.stringify({error:Z})}formatEmpty(){return"[]"}}class RZ{formatSessions($,Z){if($.length===0)return"";return $.map((K)=>K.id).join(`
|
|
811
|
+
`)}formatError($){return`Error: ${A($)}`}formatEmpty(){return""}}class FZ{useColor;constructor($){this.useColor=$}formatSessions($,Z){let K="";if(Z){if(K+=`=== Execution Details ===
|
|
812
|
+
`,Z.executionTimeMs!==void 0)K+=`Time: ${Z.executionTimeMs}ms
|
|
813
|
+
`;if(Z.filtersApplied&&Z.filtersApplied.length>0)K+=`Filters: ${Z.filtersApplied.join(", ")}
|
|
814
|
+
`;K+=`
|
|
815
|
+
`}let X=$.length;K+=`Sessions (${X} ${V$(X,"result","results")}):
|
|
816
|
+
|
|
817
|
+
`;for(let Y of $)K+=this.formatSession(Y);return K}formatSession($){let Z=$.projectPath.projectName,K=$.projectPath.decoded,X=I0($.startTime),Y=$.messageCount,Q=`${Y} ${V$(Y,"message","messages")}`,G=` ${$.id}
|
|
818
|
+
`;return G+=` Project: ${Z} (${K})
|
|
819
|
+
`,G+=` Started: ${X}
|
|
820
|
+
`,G+=` ${k(Q,this.useColor)}
|
|
821
|
+
|
|
822
|
+
`,G}formatError($){let Z=A($),K=$ instanceof Error?$.stack:"";return`Error: ${Z}
|
|
823
|
+
${K??""}`}formatEmpty(){return"No sessions found. Run 'memory sync' to import sessions."}}var _2=L(()=>{u0();X2()});function J2($){if($<1024)return`${$} B`;else if($<1048576)return`${($/1024).toFixed(1)} KB`;else if($<1073741824)return`${($/1048576).toFixed(1)} MB`;else return`${($/1073741824).toFixed(1)} GB`}function e($){return new Intl.NumberFormat("en-US").format($)}function H2($,Z){switch($){case"json":return new xZ;case"quiet":return new EZ;case"verbose":return new PZ(Z);case"brief":return new MZ;default:return new jZ(Z)}}class MZ{formatStats($,Z){return[`${e($.totalSessions)} sessions`,`${e($.totalMessages)} messages`,`${e($.totalToolUses)} tool uses`,`${e($.projectBreakdown.length)} projects`,`${J2($.databaseSizeBytes)}`].join(`
|
|
824
|
+
`)}formatError($){return`Error: ${A($)}`}formatEmpty(){return`0 sessions
|
|
825
|
+
0 messages
|
|
826
|
+
0 tool uses
|
|
827
|
+
0 projects
|
|
828
|
+
0 B`}}class jZ{constructor($){}formatStats($,Z){let K="";if(K+=`=== Database Statistics ===
|
|
829
|
+
|
|
830
|
+
`,K+=`Totals:
|
|
831
|
+
`,K+=` Sessions: ${e($.totalSessions)}
|
|
832
|
+
`,K+=` Messages: ${e($.totalMessages)}
|
|
833
|
+
`,K+=` Tool Uses: ${e($.totalToolUses)}
|
|
834
|
+
`,K+=` Size: ${J2($.databaseSizeBytes)}
|
|
835
|
+
`,$.projectBreakdown.length>0){K+=`
|
|
836
|
+
Projects:
|
|
837
|
+
`;for(let X of $.projectBreakdown)K+=` ${X.projectName}
|
|
838
|
+
`,K+=` Sessions: ${e(X.sessionCount)}`,K+=`, Messages: ${e(X.messageCount)}
|
|
839
|
+
`}if($.hooks){if(K+=`
|
|
840
|
+
Hooks:
|
|
841
|
+
`,K+=` Installed: ${$.hooks.installed?"yes":"no"}
|
|
842
|
+
`,K+=` Auto-sync: ${$.hooks.autoSync?"enabled":"disabled"}
|
|
843
|
+
`,K+=` Pending sessions: ${$.hooks.pendingSessions}
|
|
844
|
+
`,!$.hooks.installed)K+=`
|
|
845
|
+
Run 'aidev memory install' to enable automatic sync
|
|
846
|
+
`}return K}formatError($){return`Error: ${A($)}`}formatEmpty(){return"No sessions synced. Run 'memory sync' to import data."}}class xZ{formatStats($,Z){let K={totalSessions:$.totalSessions,totalMessages:$.totalMessages,totalToolUses:$.totalToolUses,databaseSizeBytes:$.databaseSizeBytes,projectBreakdown:$.projectBreakdown.map((X)=>({projectName:X.projectName,sessionCount:X.sessionCount,messageCount:X.messageCount}))};if(Z?.executionTimeMs!==void 0)K.executionTimeMs=Z.executionTimeMs;if($.hooks)K.hooks={installed:$.hooks.installed,autoSync:$.hooks.autoSync,pendingSessions:$.hooks.pendingSessions};return JSON.stringify(K,null,2)}formatError($){let Z=A($);return JSON.stringify({error:Z})}formatEmpty(){return JSON.stringify({totalSessions:0,totalMessages:0,totalToolUses:0,databaseSizeBytes:0,projectBreakdown:[],empty:!0,message:"No sessions synced. Run 'memory sync' to import data."})}}class EZ{formatStats($,Z){return[`Sessions: ${$.totalSessions}`,`Messages: ${$.totalMessages}`,`Tool uses: ${$.totalToolUses}`,`Size: ${$.databaseSizeBytes}`].join(`
|
|
847
|
+
`)}formatError($){return`Error: ${A($)}`}formatEmpty(){return`Sessions: 0
|
|
848
|
+
Messages: 0
|
|
849
|
+
Tool uses: 0
|
|
850
|
+
Size: 0`}}class PZ{constructor($){}formatStats($,Z){let K="";if(Z?.executionTimeMs!==void 0)K+=`=== Execution Details ===
|
|
851
|
+
`,K+=`Time: ${Z.executionTimeMs}ms
|
|
852
|
+
|
|
853
|
+
`;if(K+=`=== Database Statistics ===
|
|
854
|
+
|
|
855
|
+
`,K+=`Totals:
|
|
856
|
+
`,K+=` Sessions: ${e($.totalSessions)}
|
|
857
|
+
`,K+=` Messages: ${e($.totalMessages)}
|
|
858
|
+
`,K+=` Tool Uses: ${e($.totalToolUses)}
|
|
859
|
+
`,K+=` Size: ${J2($.databaseSizeBytes)} (${e($.databaseSizeBytes)} bytes)
|
|
860
|
+
`,$.projectBreakdown.length>0){K+=`
|
|
861
|
+
Projects (${$.projectBreakdown.length}):
|
|
862
|
+
`;for(let X of $.projectBreakdown){let Y=X.sessionCount>0?(X.messageCount/X.sessionCount).toFixed(1):"0";K+=` ${X.projectName}
|
|
863
|
+
`,K+=` Sessions: ${e(X.sessionCount)}`,K+=`, Messages: ${e(X.messageCount)}`,K+=` (avg ${Y}/session)
|
|
864
|
+
`}}if($.hooks){if(K+=`
|
|
865
|
+
Hooks:
|
|
866
|
+
`,K+=` Installed: ${$.hooks.installed?"yes":"no"}
|
|
867
|
+
`,K+=` Auto-sync: ${$.hooks.autoSync?"enabled":"disabled"}
|
|
868
|
+
`,K+=` Pending sessions: ${$.hooks.pendingSessions}
|
|
869
|
+
`,!$.hooks.installed)K+=`
|
|
870
|
+
Run 'aidev memory install' to enable automatic sync
|
|
871
|
+
`}return K}formatError($){let Z=A($),K=$ instanceof Error?$.stack:"";return`Error: ${Z}
|
|
872
|
+
${K??""}`}formatEmpty(){return"No sessions synced. Run 'memory sync' to import data."}}var V2=()=>{};function DZ($){return $.replace(BK,"")}function r($){return DZ($).replace(/\n{3,}/g,`
|
|
873
|
+
|
|
874
|
+
`).trim()}var BK;var P0=L(()=>{BK=/\x1b\[[0-9;]*[a-zA-Z]|\x1b\].*?\x07|\x1b\(B/g});var yZ={};y(yZ,{createContextFormatter:()=>W$});function W$($,Z){switch($){case"json":return new kZ;case"quiet":return new SZ;case"verbose":return new vZ(Z);case"detailed":return new B2(Z);case"ai":return new CZ;case"brief":case"default":default:return new W2(Z)}}function p0($){return new Intl.NumberFormat("en-US").format($)}function zK($,Z=3){if($.length===0)return"";let K=$.slice(0,Z),X=$.length-Z,Y=K.map((Q)=>`${Q.name} (${Q.count})`).join(", ");if(X>0)return`${Y} (+${X} more)`;return Y}function AK($,Z=3){if($.length===0)return"";let K=$.slice(0,Z),X=$.length-Z,Y=K.join(", ");if(X>0)return`${Y} (+${X} more)`;return Y}class W2{useColor;constructor($){this.useColor=$}formatContext($,Z){let K="";K+=s(`${$.projectName} Context`,this.useColor)+`
|
|
875
|
+
`;let X=$.lastActivity?z0($.lastActivity):"never";K+=`Sessions: ${p0($.sessionCount)} | `,K+=`Messages: ${p0($.totalMessages)} | `,K+=`Last active: ${X}
|
|
876
|
+
`;let Y=AK($.recentTopics);if(Y)K+=`Topics: ${Y}
|
|
877
|
+
`;let Q=zK($.recentToolUses);if(Q)K+=`Tools: ${Q}
|
|
878
|
+
`;return K}formatError($){return`Error: ${A($)}`}formatEmpty($){return`No sessions found for project matching '${$}'`}formatNoTopics(){return k("No topics extracted yet",this.useColor)}}class B2{useColor;constructor($){this.useColor=$}formatContext($,Z){let K="";if(K+=s(`${$.projectName} Context`,this.useColor)+`
|
|
879
|
+
`,K+="=".repeat(40)+`
|
|
880
|
+
|
|
881
|
+
`,K+=`Project: ${$.projectPathDecoded}
|
|
882
|
+
`,K+=`Sessions: ${p0($.sessionCount)}
|
|
883
|
+
`,K+=`Messages: ${p0($.totalMessages)}`,K+=` (user: ${p0($.userMessages)}, assistant: ${p0($.assistantMessages)})
|
|
884
|
+
`,$.lastActivity)K+=`Last active: ${I0($.lastActivity)}
|
|
885
|
+
`;else K+=`Last active: never
|
|
886
|
+
`;if(K+=`
|
|
887
|
+
Topics:
|
|
888
|
+
`,$.recentTopics.length>0)for(let X of $.recentTopics)K+=` - ${X}
|
|
889
|
+
`;else K+=k(` (no topics extracted yet)
|
|
890
|
+
`,this.useColor);if(K+=`
|
|
891
|
+
Tool Usage:
|
|
892
|
+
`,$.recentToolUses.length>0)for(let X of $.recentToolUses)K+=` - ${X.name}: ${p0(X.count)} times
|
|
893
|
+
`;else K+=k(` (no tool usage recorded)
|
|
894
|
+
`,this.useColor);return K}formatError($){return`Error: ${A($)}`}formatEmpty($){return`No sessions found for project matching '${$}'`}formatNoTopics(){return k("(no topics extracted yet)",this.useColor)}}class kZ{formatContext($,Z){let K={projectName:$.projectName,projectPath:$.projectPathDecoded,sessionCount:$.sessionCount,totalMessages:$.totalMessages,userMessages:$.userMessages,assistantMessages:$.assistantMessages,lastActivity:$.lastActivity?.toISOString()??null,topics:$.recentTopics,toolUsage:$.recentToolUses};return JSON.stringify(K,null,2)}formatError($){let Z=A($);return JSON.stringify({error:Z})}formatEmpty($){return JSON.stringify({error:`No sessions found for project matching '${$}'`})}formatNoTopics(){return JSON.stringify({topics:[]})}}class SZ{formatContext($,Z){return`${$.projectName}: ${$.sessionCount} sessions, ${p0($.totalMessages)} messages`}formatError($){return`Error: ${A($)}`}formatEmpty($){return""}formatNoTopics(){return""}}class vZ{detailed;constructor($){this.detailed=new B2($)}formatContext($,Z){let K="";if(Z){if(K+=`=== Execution Details ===
|
|
895
|
+
`,Z.executionTimeMs!==void 0)K+=`Time: ${Z.executionTimeMs}ms
|
|
896
|
+
`;if(Z.filtersApplied&&Z.filtersApplied.length>0)K+=`Filters: ${Z.filtersApplied.join(", ")}
|
|
897
|
+
`;K+=`
|
|
898
|
+
`}return K+=this.detailed.formatContext($,Z),K}formatError($){let Z=A($),K=$ instanceof Error?$.stack:"";return`Error: ${Z}
|
|
899
|
+
${K??""}`}formatEmpty($){return`No sessions found for project matching '${$}'`}formatNoTopics(){return this.detailed.formatNoTopics()}}class CZ{formatContext($,Z){let K=new W2(!1);return r(K.formatContext($,Z))}formatSmartContext($){let Z=[];for(let X of $.sections){if(X.content.trim()==="")continue;let Y=`### ${X.title}
|
|
900
|
+
${X.content}`;if(X.truncated)Y+=`
|
|
901
|
+
[truncated]`;Z.push(Y)}let K=`## ${$.projectName} context
|
|
902
|
+
|
|
903
|
+
`+Z.join(`
|
|
904
|
+
|
|
905
|
+
---
|
|
906
|
+
|
|
907
|
+
`);if($.truncated)K+=`
|
|
908
|
+
|
|
909
|
+
(budget: ~${$.totalTokensEstimate} tokens)`;return K.trim()}formatError($){return`Error: ${A($)}`}formatEmpty($){return`No sessions found for project matching '${$}'`}formatNoTopics(){return"No topics extracted yet"}}var B$=L(()=>{u0();P0()});function z2($,Z){switch($){case"json":return new fZ;case"quiet":return new hZ;case"verbose":return new gZ(Z);case"detailed":return new A2(Z);case"brief":case"default":default:return new bZ(Z)}}function wZ($,Z){let K=`${Math.round($*100)}%`;if(!Z)return K;if($>0.75)return w(K,Z);if($>=0.5)return u(K,Z);return K}function NK($){return $===1?"1 hop":`${$} hops`}function qK($){return`${$===1?"1":`${$}`} (${$===1?"direct":"indirect"})`}class bZ{useColor;constructor($){this.useColor=$}formatRelated($,Z){if($.length===0)return"";let X=`Related to session ${Z?.sourceId??"unknown"}...
|
|
910
|
+
`;return $.forEach((Y,Q)=>{let G=Y.session.projectPath.projectName,_=z0(Y.session.startTime),J=wZ(Y.weight,this.useColor),H=NK(Y.hops);X+=`${Q+1}. ${G} (${J}) - ${_} [${H}]
|
|
911
|
+
`}),X}formatError($){return`Error: ${A($)}`}formatEmpty($){return`No relationships found for '${$}'`}formatNoLinks(){return"No relationships extracted yet. Run 'memory sync' to extract session data."}}class A2{useColor;constructor($){this.useColor=$}formatRelated($,Z){if($.length===0)return"";let X=`Related to session ${Z?.sourceId??"unknown"}...
|
|
912
|
+
`;return X+="=".repeat(40)+`
|
|
913
|
+
|
|
914
|
+
`,$.forEach((Y,Q)=>{let G=Y.session,_=G.projectPath.projectName,J=G.projectPath.decoded,H=wZ(Y.weight,this.useColor),V=qK(Y.hops),B=I0(G.startTime),z=G.messages.length;X+=`${Q+1}. ${_}
|
|
915
|
+
`,X+=` Weight: ${H} | Hops: ${V}
|
|
916
|
+
`,X+=` Path: ${J}
|
|
917
|
+
`,X+=` Last active: ${B}
|
|
918
|
+
`,X+=` Messages: ${z}
|
|
919
|
+
|
|
920
|
+
`}),X}formatError($){return`Error: ${A($)}`}formatEmpty($){return`No relationships found for '${$}'`}formatNoLinks(){return"No relationships extracted yet. Run 'memory sync' to extract session data."}}class fZ{formatRelated($,Z){let X={sourceId:Z?.sourceId??"unknown",related:$.map((Y)=>({sessionId:Y.session.id,projectName:Y.session.projectPath.projectName,weight:Y.weight,hops:Y.hops,lastActivity:Y.session.startTime.toISOString(),messageCount:Y.session.messages.length}))};return JSON.stringify(X,null,2)}formatError($){let Z=A($);return JSON.stringify({error:Z})}formatEmpty($){return JSON.stringify({error:`No relationships found for '${$}'`})}formatNoLinks(){return JSON.stringify({error:"No relationships extracted yet"})}}class hZ{formatRelated($,Z){if($.length===0)return"";return $.map((K)=>K.session.id).join(`
|
|
921
|
+
`)}formatError($){return`Error: ${A($)}`}formatEmpty($){return""}formatNoLinks(){return""}}class gZ{detailed;constructor($){this.detailed=new A2($)}formatRelated($,Z){let K="";if(Z?.executionTimeMs!==void 0)K+=`=== Execution Details ===
|
|
922
|
+
`,K+=`Time: ${Z.executionTimeMs}ms
|
|
923
|
+
`,K+=`
|
|
924
|
+
`;return K+=this.detailed.formatRelated($,Z),K}formatError($){let Z=A($),K=$ instanceof Error?$.stack:"";return`Error: ${Z}
|
|
925
|
+
${K??""}`}formatEmpty($){return this.detailed.formatEmpty($)}formatNoLinks(){return this.detailed.formatNoLinks()}}var N2=L(()=>{u0()});function A$($,Z){switch($){case"json":return new dZ;case"quiet":return new pZ;case"verbose":return new lZ(Z);case"tools":return new z$(Z);case"brief":return new cZ;default:return new uZ(Z)}}function q2($){let Z=$.replace(/\\/g,"/").split("/");return Z[Z.length-1]||$}function mZ($){switch($.name){case"Read":{let Z=$.input.file_path,K=$.result?$.result.split(`
|
|
926
|
+
`).length:0;return`${q2(Z)} -> ${K} lines`}case"Write":{let Z=$.input.file_path;return q2(Z)}case"Edit":{let Z=$.input.file_path;return`${q2(Z)} edited`}case"Bash":{if(!$.isSuccess)return"FAILED";let Z=$.input.command.substring(0,20);return Z.length<$.input.command.length?`${Z}...`:Z}case"Glob":return`${$.result?.split(`
|
|
927
|
+
`).filter(Boolean).length??0} files`;case"Grep":return $.isSuccess?"matches":"no matches";default:return $.status}}function OK($){let Z=Math.floor($/3600000),K=Math.floor($%3600000/60000);if(Z>0)return`${Z}h ${K}m`;if(K>0)return`${K}m`;return"< 1m"}function O2($,Z){let{session:K,messages:X,toolUses:Y}=$,Q=[];Q.push(`Session: ${K.id}`),Q.push(`Project: ${K.projectPath.projectName}`);let G=Z1(K.startTime),_=K.endTime?Z1(K.endTime):"ongoing";if(Q.push(`Date: ${G} - ${_}`),K.durationMs!==void 0)Q.push(`Duration: ${OK(K.durationMs)}`);else Q.push("Duration: ongoing");let J=Y.size;return Q.push(`Messages: ${X.length} | Tools: ${J}`),Q.push("---"),Q.join(`
|
|
928
|
+
`)}function U2($,Z,K,X){let Y=$.role==="user"?s("[USER]",K):s("[ASSISTANT]",K),Q=Z1($.timestamp),G=`${Y} ${k(Q,K)}
|
|
929
|
+
`;if(G+=$.content,X&&$.role==="assistant"&&$.hasToolUses){let _=[];for(let J of $.toolUses){let H=Z.get(J);if(H)_.push(`[${H.name}: ${mZ(H)}]`)}if(_.length>0)G+=`
|
|
930
|
+
${_.join(" ")}`}return G}class cZ{formatSession($,Z){let{session:K,messages:X}=$,Y=Z1(K.startTime);return`${K.id} | ${K.projectPath.projectName} | ${X.length} messages | ${Y}`}formatError($){return`Error: ${A($)}`}formatNotFound($){return`Session not found: ${$}`}}class uZ{useColor;constructor($){this.useColor=$}formatSession($,Z){let K=[];K.push(O2($,this.useColor)),K.push("");for(let X of $.messages)K.push(U2(X,$.toolUses,this.useColor,!0)),K.push("");return K.join(`
|
|
931
|
+
`)}formatError($){return`Error: ${A($)}`}formatNotFound($){return`Session not found: ${$}`}}class dZ{formatSession($,Z){let{session:K,messages:X,toolUses:Y}=$,Q={session:{id:K.id,projectPath:K.projectPath.decoded,projectName:K.projectPath.projectName,startTime:K.startTime.toISOString(),endTime:K.endTime?.toISOString()??null,durationMs:K.durationMs??null},messages:X.map((G)=>({id:G.id,role:G.role,content:G.content,timestamp:G.timestamp.toISOString(),toolUseIds:G.toolUses})),toolUses:Object.fromEntries(Array.from(Y.entries()).map(([G,_])=>[G,{id:_.id,name:_.name,input:_.input,timestamp:_.timestamp.toISOString(),status:_.status,result:_.result??null}]))};return JSON.stringify(Q,null,2)}formatError($){let Z=A($);return JSON.stringify({error:Z})}formatNotFound($){return JSON.stringify({error:`Session not found: ${$}`})}}class pZ{formatSession($,Z){let K=[];for(let X of $.messages){let Y=X.role==="user"?"U:":"A:";K.push(`${Y} ${X.content}`)}return K.join(`
|
|
932
|
+
`)}formatError($){return`Error: ${A($)}`}formatNotFound($){return`Session not found: ${$}`}}class lZ{useColor;constructor($){this.useColor=$}formatSession($,Z){let K=[];if(Z?.executionTimeMs!==void 0)K.push("=== Execution Details ==="),K.push(`Time: ${Z.executionTimeMs}ms`),K.push("");K.push(O2($,this.useColor)),K.push("");for(let X of $.messages){if(K.push(U2(X,$.toolUses,this.useColor,!0)),X.role==="assistant"&&X.hasToolUses)for(let Y of X.toolUses){let Q=$.toolUses.get(Y);if(Q){if(K.push(""),K.push(` [TOOL: ${Q.name}]`),K.push(` Input: ${JSON.stringify(Q.input)}`),Q.result)K.push(` Result: ${Q.result}`);K.push(` Status: ${Q.status}`)}}K.push("")}return K.join(`
|
|
933
|
+
`)}formatError($){let Z=A($),K=$ instanceof Error?$.stack:"";return`Error: ${Z}
|
|
934
|
+
${K??""}`}formatNotFound($){return`Session not found: ${$}`}}class z${useColor;static RESULT_TRUNCATE_LENGTH=500;constructor($){this.useColor=$}formatSession($,Z){let K=[];K.push(O2($,this.useColor)),K.push("");for(let X of $.messages){if(K.push(U2(X,$.toolUses,this.useColor,!1)),X.role==="assistant"&&X.hasToolUses)for(let Y of X.toolUses){let Q=$.toolUses.get(Y);if(Q){if(K.push(""),K.push(` [TOOL: ${Q.name}]`),K.push(` Input: ${JSON.stringify(Q.input)}`),Q.result){let G=Q.result.length>z$.RESULT_TRUNCATE_LENGTH?Q.result.substring(0,z$.RESULT_TRUNCATE_LENGTH)+"...":Q.result;K.push(` Result: ${G}`)}K.push(` Status: ${Q.status}`)}}K.push("")}return K.join(`
|
|
935
|
+
`)}formatError($){return`Error: ${A($)}`}formatNotFound($){return`Session not found: ${$}`}}var L2=L(()=>{u0()});function nZ($){switch($){case F.DB_CONNECTION_FAILED:return"Check database file permissions";case F.DB_CORRUPTED:return"Run 'memory doctor' to diagnose or recreate database";case F.DB_LOCKED:return"Wait and retry, or check for other running processes";case F.INVALID_SESSION_ID:return"Check session ID format (expected UUID)";case F.SESSION_NOT_FOUND:return"Run 'memory list' to see available sessions";case F.SOURCE_INACCESSIBLE:return"Check that ~/.claude/projects exists and is readable";case F.DISK_FULL:return"Free up disk space and retry";case F.INVALID_JSON:return"Check file for JSON syntax errors";case F.UNKNOWN_FORMAT:return"File may be incompatible with current version";case F.SYNC_INTERRUPTED:return"Run 'memory sync' again to resume";case F.SYNC_FAILED:return`Check logs at ${X0()} for details`;case F.INVALID_ARGUMENT:return"Run command with --help to see valid options";case F.MISSING_ARGUMENT:return"Run command with --help to see required arguments";case F.VECTOR_UNAVAILABLE:return"Run 'memory sync --embed' to generate embeddings, or use '--mode fts' for keyword-only search";case F.PROVIDER_TIMEOUT:return"Check network connection or switch to local provider in config";case F.PROVIDER_CONFIG_INVALID:return"Check embedding config in ~/.config/memory/config.json";case F.EMBEDDING_DIMENSION_MISMATCH:return"Run 'memory sync --embed' to re-embed with the current model";case F.MODEL_CORRUPTED:return"Delete cached model files and run 'memory sync --embed' to re-download";case F.NOT_FOUND:return"Check the ID and try again";case F.INVALID_STATE:return"The entity is not in a valid state for this operation";case F.UNKNOWN:default:return null}}function UK($,Z){if(typeof Z==="string"||typeof Z==="number")return` ${$}: ${Z}`;return` ${$}: ${JSON.stringify(Z)}`}function p($,Z={}){let K=Z.useColor??v(),X=[];if($ instanceof j){let Y=m(`Error [${$.code}]:`,K);if(X.push(`${Y} ${$.message}`),$.context&&Object.keys($.context).length>0)for(let[G,_]of Object.entries($.context))X.push(UK(G,_));let Q=nZ($.code);if(Q)X.push(""),X.push(`Suggestion: ${Q}`)}else{let Y=m("Error:",K);X.push(`${Y} ${$.message}`)}if(Z.verbose&&$.stack)X.push(""),X.push("Stack trace:"),X.push($.stack);return X.join(`
|
|
936
|
+
`)}function K1($){if($ instanceof j)return JSON.stringify($.toJSON());let Z={error:{code:"UNKNOWN",message:$.message}};return JSON.stringify(Z)}var D0=L(()=>{g4();l()});function aZ($){return{schema_version:"1",command:$.command,kind:$.kind,...$.scope!==void 0?{scope:$.scope}:{},...$.meta!==void 0?{meta:$.meta}:{},data:$.data}}function iZ($){return{schema_version:"1",command:$.command,error:{code:$.code,message:$.message,...$.context!==void 0?{context:$.context}:{}}}}function $0($){let Z=process.env.MEMORY_JSON_COMMAND_OVERRIDE||$.command;console.log(JSON.stringify(aZ({...$,command:Z}),null,2))}function C($){let Z=process.env.MEMORY_JSON_COMMAND_OVERRIDE||$.command;console.log(JSON.stringify(iZ({...$,command:Z}),null,2))}var T0=()=>{};var q$={};y(q$,{writeLock:()=>sZ,spawnBackgroundEmbedding:()=>PK,removeLock:()=>N$,readLock:()=>M2,isProcessAlive:()=>j2,isBackgroundEmbedding:()=>kK,cleanupLock:()=>DK,acquireLock:()=>eZ});import{spawn as FK}from"child_process";import{existsSync as MK,readFileSync as jK,writeFileSync as xK,unlinkSync as EK,mkdirSync as oZ,openSync as rZ}from"fs";import{join as tZ}from"path";function F2($){return tZ($??a(),"embedding.lock")}function sZ($,Z){let K=F2(Z),X=Z??a();oZ(X,{recursive:!0}),xK(K,JSON.stringify($))}function M2($){let Z=F2($);if(!MK(Z))return null;try{return JSON.parse(jK(Z,"utf-8"))}catch{return null}}function N$($){let Z=F2($);try{EK(Z)}catch{}}function j2($){try{return process.kill($,0),!0}catch{return!1}}function eZ($,Z,K){let X=M2(K);if(X){if(j2(X.pid))return{acquired:!1,existingPid:X.pid,startedAt:X.startedAt};N$(K)}return sZ({pid:$,startedAt:new Date().toISOString(),totalMessages:Z},K),{acquired:!0,staleRemoved:X!==null}}function PK($){let{dataDir:Z,logDir:K,command:X=process.execPath}=$??{},Y=M2(Z);if(Y&&j2(Y.pid))return{started:!1,reason:"already_running",pid:Y.pid};if(Y)N$(Z);let Q=K??X0();oZ(Q,{recursive:!0});let G=tZ(Q,"sync.log"),_=rZ(G,"a"),J=rZ(G,"a"),V=[process.argv[1]??"","sync","--embed","--quiet"],B=FK(X,V,{detached:!0,stdio:["ignore",_,J],env:{...process.env,MEMORY_EMBED_BACKGROUND:"1"}});if(B.unref(),B.pid===void 0)return{started:!1,reason:"spawn_failed"};let z=eZ(B.pid,0,Z);if(!z.acquired)return{started:!1,reason:"already_running",pid:z.existingPid};return{started:!0,pid:B.pid}}function DK($){N$($)}function kK(){return process.env.MEMORY_EMBED_BACKGROUND==="1"}var O$=L(()=>{l()});var E2={};y(E2,{EmbeddingProviderFactory:()=>U$});import{createHash as vK}from"crypto";class U${cache=new Map;cacheKey($){let Z=$.apiKey?vK("sha256").update($.apiKey).digest("hex").slice(0,16):"";return[$.provider,$.model,String($.dimensions),$.baseUrl??"",$.apiKeyEnv??"",$.apiKeyRef??"",Z].join(":")}create($){let Z=this.cacheKey($),K=this.cache.get(Z);if(K)return K;let X=h5($);return this.cache.set(Z,X),X}createFromConfig($){let Z=$.embedding??I1;if(!Z.enabled)return null;return this.create(Z)}async dispose(){for(let $ of this.cache.values())await $.dispose();this.cache.clear()}}var L$=L(()=>{K0();t4()});var G8={};y(G8,{PatternRedactor:()=>l0});class l0{redactText($){let Z=$,K=[];for(let X of CK)Z=Z.replace(X.pattern,(Y)=>{let Q=`[REDACTED:${X.kind}]`;return K.push({kind:X.kind,placeholder:Q}),`${X.preservePrefix?.(Y)??""}${Q}`});return{text:Z,findings:K}}redactJson($){let Z=[];return{value:this.redactUnknown($,Z,new WeakSet),findings:Z}}redactUnknown($,Z,K){if(typeof $==="string"){let X=this.redactText($);return Z.push(...X.findings),X.text}if(Array.isArray($))return $.map((X)=>this.redactUnknown(X,Z,K));if($&&typeof $==="object"){if(K.has($))return"[REDACTED:circular]";K.add($);let X={};for(let[Y,Q]of Object.entries($))X[Y]=this.redactUnknown(Q,Z,K);return X}return $}}var CK;var z4=L(()=>{CK=[{kind:"private_key",pattern:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g},{kind:"api_key",pattern:/\bsk-ant-[A-Za-z0-9_-]{20,}\b/g},{kind:"api_key",pattern:/\bsk-[A-Za-z0-9_-]{20,}\b/g},{kind:"api_key",pattern:/\bgh[pousr]_[A-Za-z0-9_]{20,}\b/g},{kind:"aws_access_key",pattern:/\b(A3T[A-Z0-9]|AKIA|ASIA)[A-Z0-9]{16}\b/g},{kind:"jwt",pattern:/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g},{kind:"bearer_token",pattern:/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}/g,preservePrefix:()=>"Bearer "},{kind:"env_secret",pattern:/\b([A-Z][A-Z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|PASS|CREDENTIAL)[A-Z0-9_]*)\s*=\s*(?:"[^"]+"|'[^']+'|[^\s]+)/g,preservePrefix:($)=>`${$.split("=")[0].trim()}=`}]});var A8={};y(A8,{mergeMemoryBlock:()=>B8,AutoMemoryWriter:()=>z8});import{existsSync as yK,mkdirSync as V8,readFileSync as wK,writeFileSync as k2}from"fs";import{join as W8}from"path";function B8($,Z){let K=`${S2}
|
|
937
|
+
${Z}
|
|
938
|
+
${I$}
|
|
939
|
+
`;if($.length===0)return K;let X=$.indexOf(S2),Y=$.indexOf(I$);if(X!==-1&&Y!==-1){let G=$.substring(0,X),_=$.substring(Y+I$.length);return`${G}${K}${_}`}let Q=$.endsWith(`
|
|
940
|
+
`)?`
|
|
941
|
+
`:`
|
|
942
|
+
|
|
943
|
+
`;return`${$}${Q}${K}`}class z8{async writeContextFile($,Z){V8($,{recursive:!0}),k2(W8($,"context.md"),Z,"utf-8")}async updateMemoryBlock($,Z){V8($,{recursive:!0});let K=W8($,"MEMORY.md"),X=`${S2}
|
|
944
|
+
${Z}
|
|
945
|
+
${I$}
|
|
946
|
+
`;if(!yK(K)){k2(K,X,"utf-8");return}let Y=wK(K,"utf-8"),Q=B8(Y,Z);k2(K,Q,"utf-8")}}var S2="<!-- memory-cli:start -->",I$="<!-- memory-cli:end -->";var N8=()=>{};var L8={};y(L8,{runGit:()=>U8,GitSyncer:()=>k1});import{readFileSync as bK,existsSync as fK}from"fs";import{join as q8}from"path";var{spawn:hK}=globalThis.Bun;async function U8($,Z,K=process.env){let X=hK(["git",...$],{cwd:Z,stdout:"pipe",stderr:"pipe",env:K}),Y=await new Response(X.stdout).text(),Q=await new Response(X.stderr).text(),G=await X.exited;return{success:G===0,stdout:Y.trim(),stderr:Q.trim(),exitCode:G}}function O8($,Z){let K={};for(let X of $)if(Z.existsSync(X))try{let Y=Z.readFileSync(X,"utf-8");K[X]=Bun.hash(Y).toString()}catch{K[X]="error"}return K}class k1{eventsDir;deps;constructor($,Z={}){this.eventsDir=$??H1(),this.deps={runGit:U8,existsSync:fK,readFileSync:bK,getAllLogFiles:n1,now:()=>new Date,...Z}}async isGitRepo(){let $=q8(this.eventsDir,".git");return this.deps.existsSync($)}async initRepo(){if(!(await this.deps.runGit(["init"],this.eventsDir)).success)return!1;let Z=await this.deps.runGit(["config","user.name"],this.eventsDir);if(!Z.success||!Z.stdout)await this.deps.runGit(["config","user.name","Memory Nexus"],this.eventsDir),await this.deps.runGit(["config","user.email","sync@memory-nexus.local"],this.eventsDir);return await this.deps.runGit(["checkout","-b","main"],this.eventsDir),!0}async configureRemote($){if(!$.trim())return!1;return await this.deps.runGit(["remote","remove","origin"],this.eventsDir),(await this.deps.runGit(["remote","add","origin",$],this.eventsDir)).success}async removeRemote(){let $=await this.deps.runGit(["remote","remove","origin"],this.eventsDir);return $.success||$.stderr.includes("No such remote")}async getRemoteUrl(){let $=await this.deps.runGit(["remote","get-url","origin"],this.eventsDir);return $.success?$.stdout:null}async sync($,Z,K=!0,X=!0){try{if(!await this.isGitRepo()){if(!await this.initRepo())return{success:!1,rebuildNeeded:!1,error:"Failed to initialize Git repository in events directory"}}if(await this.getRemoteUrl()!==Z){if(!await this.configureRemote(Z))return{success:!1,rebuildNeeded:!1,error:"Failed to configure Git remote repository URL"}}let G=this.deps.getAllLogFiles(this.eventsDir),_=O8(G,this.deps),J=`events-${$}.jsonl`,H=q8(this.eventsDir,J);if(this.deps.existsSync(H))await this.deps.runGit(["add",J],this.eventsDir),await this.deps.runGit(["commit","-m",`sync: ${$} observed at ${this.deps.now().toISOString()}`],this.eventsDir);let V=!0;if(K){if(await this.deps.runGit(["fetch","origin"],this.eventsDir),(await this.deps.runGit(["rev-parse","--verify","origin/main"],this.eventsDir)).success){let q=await this.deps.runGit(["pull","--rebase","origin","main"],this.eventsDir);if(!q.success)return V=!1,await this.deps.runGit(["rebase","--abort"],this.eventsDir),{success:!1,rebuildNeeded:!1,error:`Git pull failed: ${q.stderr}`}}}if(X&&V){let N=await this.deps.runGit(["push","-u","origin","main"],this.eventsDir);if(!N.success)return{success:!1,rebuildNeeded:!1,error:`Git push failed: ${N.stderr}`}}let B=this.deps.getAllLogFiles(this.eventsDir),z=O8(B,this.deps),W=!1;if(G.length!==B.length)W=!0;else for(let N of B)if(_[N]!==z[N]){W=!0;break}return{success:!0,rebuildNeeded:W}}catch(Y){return{success:!1,rebuildNeeded:!1,error:A(Y)}}}}var C2=L(()=>{l()});var F8={};y(F8,{rebuildProjections:()=>y2,readEvents:()=>R8,appendEvent:()=>A4});import{appendFile as gK,mkdir as mK}from"fs/promises";import{dirname as cK}from"path";import{existsSync as uK,createReadStream as dK}from"fs";import*as T8 from"readline";async function A4($,Z){let K=Z;if(!K){let Q=h();K=g$(Q.machineId)}let X=cK(K);await mK(X,{recursive:!0});let Y={id:$.id,uuid:$.uuid,type:$.type,project:$.project,content:$.content,metadata:$.metadata,observedAt:$.observedAt.toISOString(),supersededAt:$.supersededAt?$.supersededAt.toISOString():null,supersededBy:$.supersededBy,version:1};await gK(K,JSON.stringify(Y)+`
|
|
947
|
+
`,"utf-8")}async function*R8($,Z){if($){yield*I8($);return}let K=n1(Z),X=[];for(let Y of K)for await(let Q of I8(Y))X.push(Q);X.sort((Y,Q)=>{let G=Y.observedAt.getTime()-Q.observedAt.getTime();if(G!==0)return G;return Y.uuid.localeCompare(Q.uuid)});for(let Y of X)yield Y}async function*I8($){if(!uK($))return;let Z=dK($,"utf-8"),K=T8.createInterface({input:Z,crlfDelay:1/0});for await(let X of K){if(!X.trim())continue;try{let Y=JSON.parse(X),Q=Z0.create({uuid:Y.uuid,type:Y.type,project:Y.project,content:Y.content,metadata:Y.metadata,observedAt:new Date(Y.observedAt),supersededAt:Y.supersededAt?new Date(Y.supersededAt):null,supersededBy:Y.supersededBy??null});yield Y.id!==void 0?Q.withId(Y.id):Q}catch(Y){console.error("Skipping malformed event log line:",Y)}}}async function y2($,Z,K){let X=[];for await(let Q of R8(Z,K))X.push(Q);$.transaction(()=>{$.run("DELETE FROM facts;");let Q=$.prepare(`
|
|
948
|
+
INSERT INTO facts (
|
|
949
|
+
uuid, type, project, content, metadata, observed_at, superseded_at, superseded_by
|
|
950
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
951
|
+
`);for(let G of X)if(Q.run(G.uuid,G.type,G.project,G.content,G.metadata?JSON.stringify(G.metadata):null,G.observedAt.toISOString(),G.supersededAt?G.supersededAt.toISOString():null,G.supersededBy),G.type==="supersedence"){let _=G.metadata?.superseded_uuid,J=G.metadata?.superseded_by_uuid;if(_&&J)$.prepare(`
|
|
952
|
+
UPDATE facts
|
|
953
|
+
SET superseded_at = ?, superseded_by = ?, updated_at = datetime('now')
|
|
954
|
+
WHERE uuid = ?
|
|
955
|
+
`).run(G.observedAt.toISOString(),J,_)}})()}var w2=L(()=>{Z4();l();K0()});import*as x8 from"chrono-node";function S1($,Z){if(!$||$.trim()==="")throw new R0("Invalid date format: ''. Examples: 'yesterday', '2 weeks ago', '2026-01-15'");let K=Z??new Date,X=x8.parseDate($,K);if(!X)throw new R0(`Invalid date format: '${$}'. Examples: 'yesterday', '2 weeks ago', '2026-01-15'`);let Y=new Date(X.getFullYear(),X.getMonth(),X.getDate()),Q=new Date(K.getFullYear(),K.getMonth(),K.getDate());if(Y>Q)throw new R0(`Future dates not allowed: '${$}'. Examples: 'yesterday', '2 weeks ago', '2026-01-15'`);return X}var R0;var f2=L(()=>{R0=class R0 extends Error{constructor($){super($);this.name="DateParseError"}}});function _0($){if($.json)return;let Z=`${$.command}:--format=${$.alias}`;if(E8.has(Z))return;E8.add(Z),console.error(`warning: --format ${$.alias} is deprecated and will be removed in the next minor release. ${$.replacement}`)}var E8;var X1=L(()=>{E8=new Set});import{spawn as oK,execSync as T$}from"child_process";class R${search($){return new Promise((Z,K)=>{let X=oK("qmd",["search",$,"--json"],{stdio:["pipe","pipe","pipe"]}),Y="",Q="";X.stdout.on("data",(G)=>{Y+=G.toString()}),X.stderr.on("data",(G)=>{Q+=G.toString()}),X.on("error",(G)=>{K(Error(`Failed to spawn qmd: ${G.message}`))}),X.on("close",(G)=>{if(G===0)try{let _=JSON.parse(Y);Z(_)}catch{K(Error(`Failed to parse qmd output: ${Y.slice(0,200)}`))}else K(Error(`qmd exited with code ${G}: ${Q.trim()}`))})})}isAvailable(){try{return T$("which qmd",{stdio:"ignore"}),!0}catch{return!1}}getHealthInfo(){try{return{available:!0,path:T$("which qmd",{encoding:"utf-8"}).trim()}}catch{return{available:!1,path:null}}}}function h2(){try{return T$("which qmd",{stdio:"ignore"}),!0}catch{return!1}}function F$(){try{return{available:!0,path:T$("which qmd",{encoding:"utf-8"}).trim()}}catch{return{available:!1,path:null}}}var P8=()=>{};var M$=L(()=>{P8()});var k8={};y(k8,{runShowInternal:()=>eK,executeShowCommand:()=>N4,createShowCommand:()=>j$});import{Command as tK,Option as g2}from"commander";function j$(){return new tK("show").description("Show session details").argument("<session-id>","Session ID to display").option("--json","Output as JSON").addOption(new g2("--format <type>","Output format: brief (single-line summary) or ai (AI-optimized text). 'default' accepted as deprecated alias.").choices(["brief","ai","default"])).addOption(new g2("-v, --verbose","Show detailed output").conflicts("quiet")).addOption(new g2("-q, --quiet","Minimal output (message content only)").conflicts("verbose")).option("--tools","Show detailed tool inputs and outputs").action(async($,Z)=>{let K=await N4($,Z);process.exitCode=K.exitCode})}function D8($){if($.json)return"json";if($.tools)return"tools";if($.quiet)return"quiet";if($.verbose)return"verbose";if($.format==="brief")return"brief";return"default"}async function sK($,Z,K){let X=await $.findById(Z);if(X)return X;let Q=K.prepare("SELECT id FROM sessions WHERE id LIKE ? ORDER BY start_time DESC LIMIT 1").get(`${Z}%`);if(Q)return $.findById(Q.id);return null}async function N4($,Z,K={}){let{executeQueryCommand:X}=await Promise.resolve().then(() => (Y1(),v1));process.env.MEMORY_JSON_COMMAND_OVERRIDE="show";try{return await X($,{...Z,kind:"session",dbPath:K.dbPath})}finally{delete process.env.MEMORY_JSON_COMMAND_OVERRIDE}}async function eK($,Z,K={}){let X=performance.now();if(Z.format==="default")_0({command:"show",alias:"default",replacement:"Omit --format for default behavior, or use --format brief / --format ai.",json:Z.json});let Y=K.dbPath??P(),{db:Q}=S({path:Y});try{let G=new g(Q),_=new G0(Q),J=new f0(Q),H=await sK(G,$,Q);if(!H){if(Z.json)C({command:"show",code:"NOT_FOUND",message:`Session not found: ${$}`,context:{session_id:$}});else{let U=D8(Z),O=A$(U,v());console.log(O.formatNotFound($))}return{exitCode:1}}let V=await _.findBySession(H.id),B=await J.findBySession(H.id),z=new Map;for(let U of B)z.set(U.id,U);let W={session:H,messages:V,toolUses:z};if(Z.json){let U=performance.now();return $0({command:"show",kind:"session",data:HZ(W),meta:{session_id:H.id,message_count:V.length,timing_ms:Math.round(U-X)}}),{exitCode:0}}let N=D8(Z),q=A$(N,v()),I=performance.now(),T=q.formatSession(W,{executionTimeMs:Math.round(I-X)});if(Z.format==="ai")T=r(T);return console.log(T),{exitCode:0}}catch(G){let _=G instanceof j?G:new j(F.DB_CONNECTION_FAILED,A(G));if(Z.json)C({command:"show",code:_.code,message:_.message,..._.context!==void 0?{context:_.context}:{}});else console.error(p(_));return{exitCode:1}}finally{D(Q)}}var x$=L(()=>{H0();M0();A1();F9();c();L2();P0();D0();T0();d0();X1()});var S8={};y(S8,{runListInternal:()=>ZX,executeListCommand:()=>m2,createListCommand:()=>E$});import{Command as $X,Option as C1}from"commander";function E$(){return new $X("list").description("List sessions").option("-l, --limit <count>","Maximum sessions to return","20").option("-p, --project <name>","Filter by project name").addOption(new C1("--since <date>","Sessions after date (e.g., 'yesterday', '2 weeks ago')").conflicts("days")).addOption(new C1("--before <date>","Sessions before date").conflicts("days")).addOption(new C1("--days <n>","Sessions from last N days (includes today)").argParser(($)=>{let Z=parseInt($,10);if(isNaN(Z)||Z<1)throw Error("Days must be a positive number");return Z}).conflicts(["since","before"])).option("--json","Output as JSON").addOption(new C1("--format <type>","Output format: brief (single-line per session) or ai (AI-optimized text). 'default' accepted as deprecated alias.").choices(["brief","ai","default"])).addOption(new C1("-v, --verbose","Show detailed output").conflicts("quiet")).addOption(new C1("-q, --quiet","Minimal output (session IDs only)").conflicts("verbose")).action(async($)=>{let Z=await m2($);process.exitCode=Z.exitCode})}async function m2($,Z={}){let{executeQueryCommand:K}=await Promise.resolve().then(() => (Y1(),v1)),X=$.project?"project":"global";process.env.MEMORY_JSON_COMMAND_OVERRIDE="list";try{return await K(void 0,{...$,kind:"session",scope:X,dbPath:Z.dbPath})}finally{delete process.env.MEMORY_JSON_COMMAND_OVERRIDE}}async function ZX($,Z={}){let K=performance.now();if($.format==="default")_0({command:"list",alias:"default",replacement:"Omit --format for default behavior, or use --format brief / --format ai.",json:$.json});let X=Z.dbPath??P(),Y=parseInt($.limit??"20",10);if(isNaN(Y)||Y<1){if($.json)C({command:"list",code:"INVALID_ARGUMENT",message:"Limit must be a positive number"});else console.error("Error: Limit must be a positive number");return{exitCode:1}}let Q,G;if($.days){let J=new Date,H=new Date(J.getFullYear(),J.getMonth(),J.getDate());Q=new Date(H.getTime()-($.days-1)*24*60*60*1000)}else{if($.since)try{Q=S1($.since)}catch(J){if(J instanceof R0){if($.json)C({command:"list",code:"INVALID_ARGUMENT",message:J.message,context:{flag:"since",value:$.since}});else console.error(`Error: ${J.message}`);return{exitCode:1}}throw J}if($.before)try{G=S1($.before)}catch(J){if(J instanceof R0){if($.json)C({command:"list",code:"INVALID_ARGUMENT",message:J.message,context:{flag:"before",value:$.before}});else console.error(`Error: ${J.message}`);return{exitCode:1}}throw J}}let{db:_}=S({path:X});try{let J=new g(_),H={limit:Y,projectFilter:$.project,sinceDate:Q,beforeDate:G},V=await J.findFiltered(H),B=KX($);if($.json){let U=performance.now(),O=V.map(J$);return $0({command:"list",kind:"session",data:O,meta:{filters_applied:B,count:O.length,timing_ms:Math.round(U-K)}}),{exitCode:0}}let z="default";if($.quiet)z="quiet";else if($.verbose)z="verbose";else if($.format==="brief")z="brief";let W=v(),N=G2(z,W);if(V.length===0)return console.log(N.formatEmpty()),{exitCode:0};let q=performance.now(),I={executionTimeMs:Math.round(q-K),filtersApplied:B},T=N.formatSessions(V,I);if($.format==="ai")T=r(T);return console.log(T),{exitCode:0}}catch(J){let H=J instanceof j?J:new j(F.DB_CONNECTION_FAILED,A(J));if($.json)C({command:"list",code:H.code,message:H.message,...H.context!==void 0?{context:H.context}:{}});else console.error(p(H));return{exitCode:1}}finally{D(_)}}function KX($){let Z=[];if($.limit)Z.push(`limit: ${$.limit}`);if($.project)Z.push(`project: ${$.project}`);if($.days)Z.push(`days: ${$.days}`);if($.since)Z.push(`since: ${$.since}`);if($.before)Z.push(`before: ${$.before}`);return Z}var c2=L(()=>{M0();H0();c();_2();P0();f2();D0();T0();d0();X1()});var u2={};y(u2,{gatherStatus:()=>y8,formatTimeAgo:()=>f8,formatStatusOutput:()=>b8,executeStatusCommand:()=>Q1,createStatusCommand:()=>P$,attemptFixes:()=>w8});import{Command as XX,Option as YX}from"commander";import{existsSync as QX,mkdirSync as v8}from"fs";import{dirname as C8}from"path";function P$(){return new XX("status").description("Show system status, health, and statistics").option("--db","Show database health and diagnostic info").option("--hooks","Show Git hook status").option("--embedding","Show background embedding process status").option("--config","Show config validation status").option("--stats","Show database statistics").option("--all","Show all status and health sections").option("--fix","Attempt to fix common issues automatically").option("--projects <count>","Number of projects to show in stats breakdown","10").addOption(new YX("--format <type>","Output format for stats: brief or ai").choices(["brief","ai","default"])).option("-v, --verbose","Show detailed output with timing").option("-q, --quiet","Minimal output").option("--json","Output as JSON").action(async($)=>{let Z=await Q1($);process.exitCode=Z.exitCode})}async function y8($={}){let Z=F0($.hookOverrides),K=h($.configPath),X=R1(1,$.logPath),Y=$.dbPath??P(),G=QX(Y)||$.stats,_=0,J,H=0,V=0,B=s4({dbPath:Y,configDir:$.configPath?C8($.configPath):void 0,logsDir:$.logPath?C8($.logPath):void 0,hookOverrides:$.hookOverrides,preCalculatedHookStatus:Z});if(G)try{let{db:T}=S({path:Y});try{let U=new c0,O=new b0(T),R=await U.discoverSessions();for(let A0 of R){let N0=await O.findBySessionPath(A0.path);if(!N0||N0.status!=="complete")_++}let M=new h0(T),x=$.projects??10;J=await M.getStats(x);let o=new j0(T);H=o.getEmbeddedCount(),V=o.getTotalMessageCount()}finally{D(T)}}catch{}let z={active:!1};try{let{readLock:T,isProcessAlive:U}=await Promise.resolve().then(() => (O$(),q$)),O=T();if(O&&U(O.pid))z={active:!0,pid:O.pid,startedAt:O.startedAt,embeddedCount:H,totalMessages:V}}catch{}let W=I3(),N=F$(),q;if(J)q={...J,hooks:{installed:Z.sessionEnd&&Z.preCompact,autoSync:K.autoSync,pendingSessions:_}};let I=[];if($.fix)I=w8(B,v());return{hooks:Z,config:GX(K),lastSync:X.length>0?X[0]?.timestamp??null:null,pendingSessions:_,recentLogs:R1(100,$.logPath).length,embedding:z,health:B,stats:q,migration:W,qmd:N,fixes:I}}function GX($){let Z={...$.embedding};if(Z.apiKey)Z.apiKey="[REDACTED:api_key]";return{...$,embedding:Z}}async function Q1($,Z={}){let K=performance.now();if($.format==="default")_0({command:"status",alias:"default",replacement:"Omit --format for default behavior, or use --format brief / --format ai.",json:$.json});let Y=$.stats&&!$.db&&!$.hooks&&!$.config&&!$.embedding&&!$.all?"stats":"status",Q=parseInt($.projects??"10",10);if(isNaN(Q)||Q<1){if($.json)C({command:Y,code:"INVALID_ARGUMENT",message:"Projects count must be a positive number"});else console.error("Error: Projects count must be a positive number");return{exitCode:1}}let _=await(Z.gatherStatus??y8)({dbPath:Z.dbPath,logPath:Z.logPath,configPath:Z.configPath,hookOverrides:Z.hookOverrides,fix:$.fix,projects:Q,stats:$.stats||$.all}),J=0;if($.db||$.all||$.fix)J=qX(_.health);else if($.stats)J=_.stats?0:1;else J=0;if($.json){if($.stats&&!$.db&&!$.hooks&&!$.config&&!$.embedding&&!$.all){if(!_.stats)return C({command:"stats",code:"DB_CONNECTION_FAILED",message:"Database stats could not be gathered"}),{exitCode:1};return $0({command:"stats",kind:"stats",data:Y2(_.stats),meta:{generated_at:new Date().toISOString(),timing_ms:Math.round(performance.now()-K)}}),{exitCode:0}}let W={hooks:_.hooks,config:_.config,lastSync:_.lastSync,pendingSessions:_.pendingSessions,recentLogs:_.recentLogs,embedding:_.embedding,health:{..._.health,hooks:{..._.health.hooks,lastRun:_.health.hooks.lastRun?.toISOString()??null}},stats:_.stats?Y2(_.stats):void 0,migration:_.migration,qmd:_.qmd,fixes:_.fixes};return console.log(JSON.stringify(W,null,2)),{exitCode:J}}let V=v();if(!($.db||$.hooks||$.embedding||$.config||$.stats||$.all)){if(b8(_),$.fix&&_.fixes.length>0){console.log(`
|
|
956
|
+
Applied fixes:`);for(let W of _.fixes)console.log(W)}return{exitCode:0}}let z=[];if($.hooks||$.all)z.push(JX(_,V));if($.config||$.all)z.push(HX(_,V));if($.db||$.all)z.push(VX(_,V));if($.embedding||$.all)z.push(WX(_,V)),z.push(BX(_,V));if($.stats||$.all)if(!_.stats)z.push(m("Database statistics are not available.",V));else{let W="default";if($.quiet)W="quiet";else if($.verbose)W="verbose";else if($.format==="brief")W="brief";let N=H2(W,V);if(_.stats.totalSessions===0)z.push(N.formatEmpty());else{let q=N.formatStats(_.stats,{executionTimeMs:Math.round(performance.now()-K)});if($.format==="ai")q=r(q);z.push(q)}}if(console.log(z.join(`
|
|
957
|
+
|
|
958
|
+
`)),$.all||$.db){if(_.migration.status==="pending")console.log(""),console.log(u("Legacy data found at ~/.memory-nexus/. Run any memory command to auto-migrate.",V));else if(_.migration.status==="partial")console.log(""),console.log(u("Partial migration detected. Some data in ~/.memory-nexus/ and some in new paths. Re-run migration or check manually.",V))}if($.fix)if(console.log(""),console.log("Attempting fixes..."),_.fixes.length===0)console.log(k("No automatic fixes available.",V));else for(let W of _.fixes)console.log(W);return{exitCode:J}}function _X($){let K=Date.now()-$.getTime(),X=Math.floor(K/1000),Y=Math.floor(X/60),Q=Math.floor(Y/60),G=Math.floor(Q/24);if(G>0)return`${G} day${G>1?"s":""} ago`;if(Q>0)return`${Q} hour${Q>1?"s":""} ago`;if(Y>0)return`${Y} minute${Y>1?"s":""} ago`;return"just now"}function JX($,Z){let K=[];if(K.push("Hooks"),K.push(` ${d($.health.hooks.installed,Z)} Installed: ${$.health.hooks.installed?"yes":"no"}`),K.push(` ${d($.health.hooks.enabled,Z)} Enabled (autoSync): ${$.health.hooks.enabled?"yes":"no"}`),$.health.hooks.lastRun)K.push(` ${k(`Last run: ${_X($.health.hooks.lastRun)}`,Z)}`);else K.push(` ${k("Last run: never",Z)}`);return K.join(`
|
|
959
|
+
`)}function HX($,Z){let K=[];if(K.push("Configuration"),$.health.config.valid)K.push(` ${d(!0,Z)} Valid`);else{K.push(` ${d(!1,Z)} Invalid`);for(let X of $.health.config.issues)K.push(` ${m("-",Z)} ${X}`)}return K.join(`
|
|
960
|
+
`)}function VX($,Z){let K=[];K.push("Database");let X=P();if($.health.database.exists)K.push(` ${d($.health.database.exists,Z)} Exists: ${X}`),K.push(` ${d($.health.database.readable,Z)} Readable`),K.push(` ${d($.health.database.writable,Z)} Writable`),K.push(` ${d($.health.database.integrity==="ok",Z)} Integrity: ${AX($.health.database.integrity,Z)}`),K.push(` ${k(`Size: ${zX($.health.database.size)}`,Z)}`);else K.push(` ${d(!1,Z)} Database not found: ${X}`),K.push(` ${k("Run 'memory sync' to create database",Z)}`);if($.health.sqliteVec.available)K.push(` ${d(!0,Z)} sqlite-vec: v${$.health.sqliteVec.version}`);else K.push(` ${d(!1,Z)} sqlite-vec: not available`);if(K.push(""),K.push("Permissions"),K.push(` ${d($.health.permissions.configDir,Z)} Config directory: ${$1()}`),K.push(` ${d($.health.permissions.logsDir,Z)} Logs directory: ${T1()}`),K.push(` ${d($.health.permissions.sourceDir,Z)} Source directory: ~/.claude/projects`),K.push(""),K.push("Search Capability"),K.push(` ${d($.health.searchCapability.fts5,Z)} FTS5: available`),K.push(` ${d($.health.searchCapability.sqliteVec,Z)} sqlite-vec: ${$.health.searchCapability.sqliteVec?"available":"not available"}`),K.push(` ${k(`Embeddings: ${$.health.searchCapability.embeddedCount}/${$.health.searchCapability.totalMessages} (${$.health.searchCapability.coveragePercent}%)`,Z)}`),K.push(` ${k(`Default mode: ${$.health.searchCapability.defaultMode}`,Z)}`),K.push(` ${d($.health.searchCapability.vectorReady,Z)} Vector search: ${$.health.searchCapability.vectorReady?"ready":"not ready"}`),K.push(""),K.push("Optional Tools"),$.qmd.available)K.push(` ${k("[INFO]",Z)} qmd: installed at ${$.qmd.path} (enables --files search)`);else K.push(` ${k("[INFO]",Z)} qmd: not found (optional -- install with: bun add -g @tobilu/qmd)`);return K.join(`
|
|
961
|
+
`)}function WX($,Z){let K=[];if(K.push("Embeddings"),K.push(` ${d($.health.embedding.enabled,Z)} Enabled: ${$.health.embedding.enabled?"yes":"no"}`),K.push(` ${k(`Provider: ${$.health.embedding.provider}`,Z)}`),K.push(` ${k(`Model: ${$.health.embedding.model}`,Z)}`),K.push(` ${k(`Dimensions: ${$.health.embedding.dimensions}`,Z)}`),K.push(` ${d($.health.embedding.ready,Z)} Ready: ${$.health.embedding.ready?"yes":"no"}`),$.health.embedding.readyReason)if($.health.embedding.ready)K.push(` ${k(`Note: ${$.health.embedding.readyReason}`,Z)}`);else K.push(` ${m(`Reason: ${$.health.embedding.readyReason}`,Z)}`);return K.join(`
|
|
962
|
+
`)}function BX($,Z){let K=[];if(K.push("LLM Fact Extraction"),K.push(` ${d($.health.llmExtraction.ready,Z)} Ready: ${$.health.llmExtraction.ready?"yes":"no"}`),K.push(` ${k(`Provider: ${$.health.llmExtraction.provider}`,Z)}`),K.push(` ${k(`Model: ${$.health.llmExtraction.model}`,Z)}`),$.health.llmExtraction.readyReason)if($.health.llmExtraction.ready)K.push(` ${k(`Note: ${$.health.llmExtraction.readyReason}`,Z)}`);else K.push(` ${m(`Reason: ${$.health.llmExtraction.readyReason}`,Z)}`);return K.join(`
|
|
963
|
+
`)}function d($,Z){if($)return w("[OK]",Z);return m("[FAIL]",Z)}function zX($){if($===0)return"0 B";let Z=["B","KB","MB","GB"],K=1024,X=Math.floor(Math.log($)/Math.log(K));return`${($/Math.pow(K,X)).toFixed(X>0?1:0)} ${Z[X]}`}function AX($,Z){switch($){case"ok":return w("ok",Z);case"corrupted":return m("CORRUPTED",Z);default:return u("unknown",Z)}}function NX($){let Z=0;if(!$.database.readable)Z++;if(!$.database.writable)Z++;if(!$.permissions.configDir)Z++;if(!$.permissions.logsDir)Z++;if(!$.permissions.sourceDir)Z++;return Z+=$.config.issues.length,Z}function qX($){if(!$.database.exists||$.database.integrity==="corrupted")return 2;if(NX($)>0||!$.searchCapability.vectorReady)return 1;return 0}function w8($,Z){let K=[];if(!$.permissions.configDir){let X=$1();try{v8(X,{recursive:!0}),K.push(w(`Created config directory: ${X}`,Z))}catch(Y){let Q=A(Y);K.push(m(`Failed to create config directory: ${Q}`,Z))}}if(!$.permissions.logsDir){let X=T1();try{v8(X,{recursive:!0}),K.push(w(`Created logs directory: ${X}`,Z))}catch(Y){let Q=A(Y);K.push(m(`Failed to create logs directory: ${Q}`,Z))}}if($.database.integrity==="corrupted")K.push(u("Database corruption detected. Consider:",Z)),K.push(" 1. Backup your database file"),K.push(` 2. Delete the database: rm ${P()}`),K.push(" 3. Re-sync: memory sync");if(!$.hooks.installed)K.push(u("Hooks not installed. Run 'memory install' to enable automatic sync.",Z));return K}function b8($){if(console.log("Memory Status"),console.log(`=============
|
|
964
|
+
`),console.log("Hooks:"),console.log(` SessionEnd: ${$.hooks.sessionEnd?"installed":"not installed"}`),console.log(` PreCompact: ${$.hooks.preCompact?"installed":"not installed"}`),console.log(` Hook script: ${$.hooks.hookScriptExists?"present":"missing"}`),console.log(` Backup: ${$.hooks.backupExists?"available":"none"}`),console.log(""),console.log("Configuration:"),console.log(` autoSync: ${$.config.autoSync}`),console.log(` syncOnCompaction: ${$.config.syncOnCompaction}`),console.log(` recoveryOnStartup: ${$.config.recoveryOnStartup}`),console.log(` timeout: ${$.config.timeout}ms`),console.log(` logLevel: ${$.config.logLevel}`),console.log(` showFailures: ${$.config.showFailures}`),console.log(""),console.log("Activity:"),console.log(` Last sync: ${$.lastSync??"never"}`),console.log(` Pending sessions: ${$.pendingSessions}`),console.log(` Recent log entries: ${$.recentLogs}`),console.log(""),console.log("Embedding:"),$.embedding.active){let Z=$.embedding.startedAt?f8($.embedding.startedAt):"unknown",K=$.embedding.embeddedCount!==void 0&&$.embedding.totalMessages!==void 0?`, ${$.embedding.embeddedCount}/${$.embedding.totalMessages} messages`:"";console.log(` Status: active (PID ${$.embedding.pid}${K}, started ${Z})`)}else console.log(" Status: idle");if(!$.hooks.sessionEnd||!$.hooks.preCompact)console.log(`
|
|
965
|
+
Recommendation: Run 'memory install' to enable automatic sync.`);if($.pendingSessions>0)console.log(`
|
|
966
|
+
Note: ${$.pendingSessions} session(s) pending sync. Run 'memory sync' to sync now.`)}function f8($){let Z=Date.now()-new Date($).getTime(),K=Math.floor(Z/60000);if(K<1)return"just now";if(K<60)return`${K} min ago`;let X=Math.floor(K/60);if(X<24)return`${X}h ago`;return`${Math.floor(X/24)}d ago`}var y1=L(()=>{F1();c();W4();r$();M$();V2();P0();X1();T0();d0()});var h8={};y(h8,{executeStatsCommand:()=>p2,createStatsCommand:()=>D$});import{Command as OX,Option as d2}from"commander";function D$(){return new OX("stats").description("Show database statistics").option("--json","Output as JSON").addOption(new d2("--format <type>","Output format: brief (top-line counters) or ai (AI-optimized text). 'default' accepted as deprecated alias.").choices(["brief","ai","default"])).addOption(new d2("-v, --verbose","Show detailed output with timing").conflicts("quiet")).addOption(new d2("-q, --quiet","Minimal output").conflicts("verbose")).option("--projects <count>","Number of projects to show in breakdown","10").action(async($)=>{let Z=await p2($);process.exitCode=Z.exitCode})}async function p2($,Z={}){return Q1({stats:!0,projects:$.projects,format:$.format,verbose:$.verbose,quiet:$.quiet,json:$.json},{dbPath:Z.dbPath})}var l2=L(()=>{y1()});var c8={};y(c8,{runContextInternal:()=>IX,executeContextCommand:()=>O4,createContextCommand:()=>k$});import*as g8 from"fs";import*as m8 from"os";import{join as UX}from"path";import{Command as LX,Option as q4}from"commander";function k$(){return new LX("context").description("Show aggregated context for a project").argument("<project>","Project name or substring to filter by").addOption(new q4("--days <n>","Sessions from last N days (includes today)").argParser(($)=>{let Z=parseInt($,10);if(isNaN(Z)||Z<1)throw Error("Days must be a positive number");return Z})).addOption(new q4("--format <type>","Output format: brief, ai. 'detailed' accepted as deprecated alias.").choices(["brief","ai","detailed"])).addOption(new q4("--budget <tokens>","Maximum token budget for context").argParser(($)=>{let Z=parseInt($,10);if(isNaN(Z)||Z<1)throw Error("Budget must be a positive number");return Z})).option("--cross-project","Include cross-project learnings and decisions").option("--json","Output as JSON").addOption(new q4("-v, --verbose","Show detailed output with timing").conflicts("quiet")).addOption(new q4("-q, --quiet","Minimal output").conflicts("verbose")).action(async($,Z)=>{let K=await O4($,Z);process.exitCode=K.exitCode})}async function O4($,Z){let{executeQueryCommand:K}=await Promise.resolve().then(() => (Y1(),v1));process.env.MEMORY_JSON_COMMAND_OVERRIDE="context";try{return await K($,{...Z,kind:"context",scope:"project"})}finally{delete process.env.MEMORY_JSON_COMMAND_OVERRIDE}}async function IX($,Z,K){if(Z.format==="detailed")_0({command:"context",alias:"detailed",replacement:"Use --format brief or --format ai.",json:Z.json});let X=UX(m8.homedir(),".memory");if(g8.existsSync(X)&&!Z.quiet&&!Z.json)console.error("[DEPRECATION WARNING] Legacy memory directory ~/.memory/ is deprecated. Your knowledge and decisions are now stored safely in the SQLite database.");let Y=K?.dbPath??Z.dbPath??P(),{db:Q}=S({path:Y});try{return await TX(Q,$,Z)}catch(G){let _=G instanceof j?G:new j(F.DB_CONNECTION_FAILED,A(G));if(Z.json)C({command:"context",code:_.code,message:_.message,..._.context!==void 0?{context:_.context}:{}});else console.error(p(_));return{exitCode:1}}finally{D(Q)}}async function TX($,Z,K){let X=new e0($),Y=new E0($),Q=new x0($),G=new s0($),J=await new e1({projectResolver:X,factRepo:Y,frictionRepo:Q,getSessionSummary:async(z,W)=>{let N=await G.getProjectContext(z,{days:W});if(!N)return null;return`Sessions: ${N.sessionCount} | Messages: ${N.totalMessages} | Last active: ${N.lastActivity?.toISOString()??"never"}`}}).getContext({projectFilter:Z,budget:K.budget,days:K.days,crossProject:K.crossProject});if(K.json){if(!J)return C({command:"context",code:"NOT_FOUND",message:`Project not found: ${Z}`,context:{project:Z}}),{exitCode:1};let z=await G.getProjectContext(Z,{days:K.days});return $0({command:"context",kind:"context",data:z?WZ(z):null,meta:{project:Z,days:K.days,budget:K.budget,cross_project:!!K.crossProject,mode:"smart",sections:J.sections.map((W)=>({key:W.key,title:W.title}))}}),{exitCode:0}}let H=K.format==="ai"?"ai":K.verbose?"verbose":K.quiet?"quiet":K.format==="detailed"?"detailed":"brief",V=v(),B=W$(H,V);if(!J){let z=B.formatEmpty(Z);if(H!=="quiet"||z)console.error(z);return{exitCode:1}}if(B.formatSmartContext){let z=B.formatSmartContext(J);console.log(z)}else{let z=J.sections.find((W)=>W.key==="session_summary");if(z)console.log(z.content);else{let W=J.sections.map((N)=>`${N.title}:
|
|
967
|
+
${N.content}`).join(`
|
|
968
|
+
|
|
969
|
+
`);console.log(W)}}return{exitCode:0}}var S$=L(()=>{H0();q1();u4();c();w4();B$();D0();T0();d0();X1()});var u8={};y(u8,{runRelatedInternal:()=>FX,executeRelatedCommand:()=>U4,createRelatedCommand:()=>v$});import{Command as RX,Option as w1}from"commander";function v$(){return new RX("related").description("Find sessions related through shared topics/entities").argument("<id>","Session ID, message ID, or topic name").addOption(new w1("--limit <n>","Maximum results").argParser(($)=>{let Z=parseInt($,10);if(isNaN(Z)||Z<1)throw Error("Limit must be a positive number");return Z}).default(10)).addOption(new w1("--hops <n>","Traversal depth (1-3)").argParser(($)=>{let Z=parseInt($,10);if(isNaN(Z)||Z<1||Z>3)throw Error("Hops must be 1, 2, or 3");return Z}).default(2)).addOption(new w1("--type <type>","Entity type of the ID").choices(["session","message","topic"]).default("session")).addOption(new w1("--format <type>","Output format: brief, ai. 'detailed' accepted as deprecated alias.").choices(["brief","ai","detailed"])).option("--json","Output as JSON").addOption(new w1("-v, --verbose","Show detailed output with timing").conflicts("quiet")).addOption(new w1("-q, --quiet","Minimal output (session IDs only)").conflicts("verbose")).action(async($,Z)=>{let K=await U4($,Z);process.exitCode=K.exitCode})}async function U4($,Z){let{executeQueryCommand:K}=await Promise.resolve().then(() => (Y1(),v1));process.env.MEMORY_JSON_COMMAND_OVERRIDE="related";try{return await K($,{...Z,kind:"related"})}finally{delete process.env.MEMORY_JSON_COMMAND_OVERRIDE}}async function FX($,Z,K){let X=performance.now();if(Z.format==="detailed")_0({command:"related",alias:"detailed",replacement:"Use --format brief or --format ai.",json:Z.json});let Y=K?.dbPath??Z.dbPath??P(),{db:Q}=S({path:Y});try{let G=new N1(Q),_=new g(Q),J=Z.type??"session",H=await G.findRelatedWithHops(J,$,Z.hops??2),V="brief";if(Z.json)V="json";else if(Z.verbose)V="verbose";else if(Z.quiet)V="quiet";else if(Z.format==="detailed")V="detailed";let B=v(),z=z2(V,B);if(H.length===0){let O=await G.findBySource(J,$),R=await G.findByTarget(J,$);if(O.length===0&&R.length===0){if(Z.json)C({command:"related",code:"NOT_FOUND",message:`No related items found for ${$}`,context:{source_id:$,source_type:J}});else{let M=z.formatEmpty($);if(V!=="quiet"||M)console.error(M)}return{exitCode:1}}}let W=new Map;for(let{link:O,hop:R}of H)if(O.targetType==="session"){let M=W.get(O.targetId);if(!M||O.weight>M.weight)W.set(O.targetId,{weight:O.weight,hops:R})}W.delete($);let N=Array.from(W.entries()).sort((O,R)=>R[1].weight-O[1].weight||O[1].hops-R[1].hops).slice(0,Z.limit??10),q=[];for(let[O,{weight:R,hops:M}]of N){let x=await _.findById(O);if(x)q.push({session:x,weight:R,hops:M})}if(q.length===0){if(Z.json)C({command:"related",code:"NOT_FOUND",message:`No related items found for ${$}`,context:{source_id:$,source_type:J}});else{let O=z.formatEmpty($);if(V!=="quiet"||O)console.error(O)}return{exitCode:1}}if(Z.json){let O=performance.now();return $0({command:"related",kind:"related",data:q.map(VZ),meta:{source_id:$,source_type:J,count:q.length,timing_ms:Math.round(O-X)}}),{exitCode:0}}let I=performance.now(),T={sourceId:$,executionTimeMs:Math.round(I-X)},U=z.formatRelated(q,T);if(Z.format==="ai")U=r(U);return console.log(U),{exitCode:0}}catch(G){let _=G instanceof j?G:new j(F.DB_CONNECTION_FAILED,A(G));if(Z.json)C({command:"related",code:_.code,message:_.message,..._.context!==void 0?{context:_.context}:{}});else console.error(p(_));return{exitCode:1}}finally{D(Q)}}var C$=L(()=>{H0();E9();c();N2();P0();D0();T0();d0();X1()});var v1={};y(v1,{executeQueryCommand:()=>a2,createQueryCommand:()=>y$});import{Command as MX,Option as b1}from"commander";function y$(){return new MX("query").argument("[argument]","Query argument (search query text, session ID, or project name depending on kind)").description("Execute unified query across sessions, files, stats, or context").addOption(new b1("--scope <scope>","Query scope: global or project").choices(["global","project"])).option("-p, --project <name>","Filter by project name").addOption(new b1("--kind <kind>","Resource kind to query").choices(["message","session","file","stats","context","related"]).default("message")).addOption(new b1("--mode <mode>","Search mode: auto, fts, vector, hybrid").choices(["auto","fts","vector","hybrid"])).option("-l, --limit <count>","Maximum results to return").addOption(new b1("--format <type>","Output format: brief or ai").choices(["brief","ai","default"])).option("--json","Output results as JSON envelope").option("--days <count>","Filter results from last N days",($)=>{let Z=parseInt($,10);if(isNaN(Z)||Z<1)throw Error("Days must be a positive number");return Z}).option("--projects <count>","Number of projects to show in stats breakdown","10").addOption(new b1("-v, --verbose","Show detailed output with execution info").conflicts("quiet")).addOption(new b1("-q, --quiet","Suppress headers and decorations").conflicts("verbose")).action(async($,Z)=>{let K=await a2($,Z);process.exitCode=K.exitCode})}async function a2($,Z){let K=Z.kind??"message",X=Z.project||(Z.scope==="project"?$:void 0),Y=!process.env.MEMORY_JSON_COMMAND_OVERRIDE;if(Y)process.env.MEMORY_JSON_COMMAND_OVERRIDE="query";try{let Q=Z;switch(K){case"message":{let{runSearchInternal:G}=await Promise.resolve().then(() => (L4(),n2));return await G($||"",{...Z,project:X,files:!1})}case"file":{let{runSearchInternal:G}=await Promise.resolve().then(() => (L4(),n2));return await G($||"",{...Z,project:X,files:!0})}case"session":if($){let{runShowInternal:G}=await Promise.resolve().then(() => (x$(),k8));return await G($,{json:Q.json,verbose:Q.verbose,quiet:Q.quiet,tools:Q.tools,format:Q.format},{dbPath:Z.dbPath})}else{let{runListInternal:G}=await Promise.resolve().then(() => (c2(),S8));return await G({limit:Z.limit,project:X,since:Q.since,before:Q.before,days:Z.days,json:Z.json,verbose:Z.verbose,quiet:Z.quiet,format:Z.format},{dbPath:Z.dbPath})}case"stats":{let{executeStatsCommand:G}=await Promise.resolve().then(() => (l2(),h8));return await G({json:Z.json,verbose:Z.verbose,quiet:Z.quiet,projects:Z.projects,format:Z.format},{dbPath:Z.dbPath})}case"context":{let G=X||$;if(!G){if(Z.json)C({command:"query",code:"INVALID_ARGUMENT",message:"Project name is required for context query"});else console.error("Error: Project name is required for context query");return{exitCode:1}}let{runContextInternal:_}=await Promise.resolve().then(() => (S$(),c8));return await _(G,{json:Z.json,verbose:Z.verbose,quiet:Z.quiet,days:Z.days,format:Q.format,budget:Q.budget,crossProject:Q.crossProject},{dbPath:Z.dbPath})}case"related":{if(!$){if(Z.json)C({command:"query",code:"INVALID_ARGUMENT",message:"Source session ID is required for related query"});else console.error("Error: Source session ID is required for related query");return{exitCode:1}}let{runRelatedInternal:G}=await Promise.resolve().then(() => (C$(),u8));return await G($,{limit:Q.limit,json:Z.json,verbose:Z.verbose,quiet:Z.quiet,format:Q.format,type:Q.type,hops:Q.hops,dbPath:Z.dbPath},{dbPath:Z.dbPath})}default:{if(Z.json)C({command:"query",code:"INVALID_ARGUMENT",message:`Unsupported kind: ${K}`});else console.error(`Error: Unsupported kind: ${K}`);return{exitCode:1}}}}finally{if(Y)delete process.env.MEMORY_JSON_COMMAND_OVERRIDE}}var Y1=L(()=>{T0()});var n2={};y(n2,{runSearchInternal:()=>xX,resolveSearchMode:()=>d8,filterCaseSensitive:()=>p8,executeSearchCommand:()=>I4,createSearchCommand:()=>w$});import{Command as jX,Option as k0}from"commander";function d8($){if($.vector===!1)return"fts";if(!$.mode||$.mode==="auto")return;return $.mode}function w$(){return new jX("search").argument("<query>","Search query text").description("Search across all sessions (keyword, semantic, or hybrid)").option("-l, --limit <count>","Maximum results to return","10").option("-p, --project <name>","Filter by project name").option("-s, --session <id>","Filter by session ID").option("--role <roles>","Filter by role: user, assistant, or both (comma-separated)").addOption(new k0("--since <date>","Results after date (e.g., 'yesterday', '2 weeks ago')").conflicts("days")).addOption(new k0("--before <date>","Results before date").conflicts("days")).addOption(new k0("--days <n>","Results from last N days (includes today)").argParser(($)=>{let Z=parseInt($,10);if(isNaN(Z)||Z<1)throw Error("Days must be a positive number");return Z}).conflicts(["since","before"])).option("--json","Output results as JSON").option("-i, --ignore-case","Case-insensitive search (default)").option("-c, --case-sensitive","Case-sensitive search").addOption(new k0("--mode <mode>","Search mode: auto, fts, vector, hybrid").choices(["auto","fts","vector","hybrid"]).default("auto")).addOption(new k0("--no-vector","Disable vector search (same as --mode fts)")).addOption(new k0("--no-decay","Disable temporal decay scoring")).option("--files","Search markdown files via qmd (requires qmd installed)").addOption(new k0("--format <type>","Output format: brief (single-line per record) or ai (AI-optimized text). 'default' accepted as deprecated alias.").choices(["brief","ai","default"])).addOption(new k0("-v, --verbose","Show detailed output with execution info").conflicts("quiet")).addOption(new k0("-q, --quiet","Suppress headers and decorations").conflicts("verbose")).action(async($,Z)=>{let K=await I4($,Z);process.exitCode=K.exitCode})}async function I4($,Z){let{executeQueryCommand:K}=await Promise.resolve().then(() => (Y1(),v1)),X=Z.files?"file":"message",Y=Z.project?"project":"global";process.env.MEMORY_JSON_COMMAND_OVERRIDE="search";try{return await K($,{...Z,kind:X,scope:Y})}finally{delete process.env.MEMORY_JSON_COMMAND_OVERRIDE}}async function xX($,Z){let K=performance.now();if(Z.format==="default")_0({command:"search",alias:"default",replacement:"Omit --format for default behavior, or use --format brief / --format ai.",json:Z.json});let X;try{X=K4.from($)}catch(J){if(Z.json)C({command:"search",code:"INVALID_QUERY",message:"Query cannot be empty"});else console.error("Error: Query cannot be empty");return{exitCode:1}}if(Z.files)return EX($,Z);let Y=Z.dbPath??P(),{db:Q,sqliteVecAvailable:G}=S({path:Y}),_=new U$;try{let J=h(),H=new O1(Q),V=new j0(Q),B=new U1({db:Q,fts5Service:H,embeddingRepo:V,providerFactory:_,config:J,sqliteVecAvailable:G}),z=parseInt(Z.limit??"10",10);if(isNaN(z)||z<1){if(Z.json)C({command:"search",code:"INVALID_ARGUMENT",message:"Limit must be a positive number"});else console.error("Error: Limit must be a positive number");return{exitCode:1}}let W;if(Z.role){let f=Z.role.split(",").map((f1)=>f1.trim().toLowerCase());if(f.length===1)W=f[0];else W=f}let N,q;if(Z.days){let f=new Date,f1=new Date(f.getFullYear(),f.getMonth(),f.getDate());N=new Date(f1.getTime()-(Z.days-1)*24*60*60*1000)}else{if(Z.since)try{N=S1(Z.since)}catch(f){if(f instanceof R0){if(Z.json)C({command:"search",code:"INVALID_ARGUMENT",message:f.message,context:{flag:"since",value:Z.since}});else console.error(`Error: ${f.message}`);return{exitCode:1}}throw f}if(Z.before)try{q=S1(Z.before)}catch(f){if(f instanceof R0){if(Z.json)C({command:"search",code:"INVALID_ARGUMENT",message:f.message,context:{flag:"before",value:Z.before}});else console.error(`Error: ${f.message}`);return{exitCode:1}}throw f}}let I=d8(Z),U={limit:Z.caseSensitive?z*2:z,projectFilter:Z.project,roleFilter:W,sinceDate:N,beforeDate:q,sessionFilter:Z.session,mode:I,noDecay:Z.decay===!1},O=await B.search(X,U),R=!1;if(Z.caseSensitive&&O.length>0){let f=O.length;O=p8(O,$,z),R=f>O.length||O.length<z}else O=O.slice(0,z);let M=B.getLastSearchMeta(),x="default";if(Z.json)x="json";else if(Z.quiet)x="quiet";else if(Z.verbose)x="verbose";else if(Z.format==="brief")x="brief";let o=v(),A0=Q2(x,o),N0=performance.now(),q0={query:$,executionDetails:{timeMs:Math.round(N0-K),ftsQuery:$,filtersApplied:DX(Z,R)},searchMeta:M??void 0},E6=Math.round(performance.now()-K),P6=()=>{let f={query:$,total_results:O.length,timing_ms:E6};if(M){if(f.mode=M.mode,f.mode_reason=M.modeReason,f.embedding_coverage=M.embeddingCoverage,f.degraded=M.degraded,M.degradationReason)f.degradation_reason=M.degradationReason}return f};if(Z.json){if($0({command:"search",kind:"message",data:O.map((f,f1)=>_$(f,{rank:f1+1,includeSearchMetaFields:!!M})),meta:P6()}),M&&M.embeddingCoverage===0&&!J.search?.hintShown)console.error("Tip: run 'memory sync --embed' to enable semantic search"),L0({search:{...J.search,hintShown:!0}});return{exitCode:0}}if(O.length===0&&M?.mode==="vector")return console.log(`No semantic matches for "${$}"`),{exitCode:0};let f$=A0.formatResults(O,q0);if(Z.format==="ai")f$=r(f$);if(console.log(f$),M&&M.embeddingCoverage===0&&!J.search?.hintShown)console.error("Tip: run 'memory sync --embed' to enable semantic search"),L0({search:{...J.search,hintShown:!0}});return{exitCode:0}}catch(J){let H=J instanceof j?J:new j(F.DB_CONNECTION_FAILED,A(J));if(Z.json)C({command:"search",code:H.code,message:H.message,...H.context!==void 0?{context:H.context}:{}});else console.error(p(H));return{exitCode:1}}finally{await _.dispose(),D(Q)}}async function EX($,Z){if(!h2()){if(Z.json)C({command:"search",code:"QMD_UNAVAILABLE",message:"qmd is required for --files search. Install: bun add -g @tobilu/qmd"});else console.error("Error: qmd is required for --files search. Install: bun add -g @tobilu/qmd");return{exitCode:1}}try{let X=await new R$().search($);if(Z.json)return $0({command:"search",kind:"file",data:X.map(JZ),meta:{query:$,files:!0,total_results:X.length}}),{exitCode:0};if(X.length===0){let G=`No file results for "${$}"`;return console.log(Z.format==="ai"?G:G),{exitCode:0}}let Y=v(),Q=PX(X,Y);if(Z.format==="ai")Q=r(Q);return console.log(Q),{exitCode:0}}catch(K){let X=A(K);if(Z.json)C({command:"search",code:"QMD_FAILED",message:`qmd search failed: ${X}`});else console.error(`Error: qmd search failed: ${X}`);return{exitCode:1}}}function PX($,Z){let K=[];K.push(`File results: ${$.length} match${$.length!==1?"es":""}`),K.push("");for(let X of $){let Y=X.file.replace(/^qmd:\/\//,"");K.push(` ${w(X.title,Z)}`),K.push(` ${k(`${Y} (score: ${X.score})`,Z)}`);let Q=X.snippet||X.context;if(Q)K.push(` ${Q}`);K.push("")}return K.join(`
|
|
970
|
+
`)}function DX($,Z){let K=[];if($.limit)K.push(`limit: ${$.limit}`);if($.project)K.push(`project: ${$.project}`);if($.session)K.push(`session: ${$.session}`);if($.role)K.push(`role: ${$.role}`);if($.days)K.push(`days: ${$.days}`);if($.since)K.push(`since: ${$.since}`);if($.before)K.push(`before: ${$.before}`);if($.caseSensitive)K.push("case-sensitive");if(Z)K.push("case-sensitive filter applied");if($.mode&&$.mode!=="auto")K.push(`mode: ${$.mode}`);if($.vector===!1)K.push("no-vector");if($.decay===!1)K.push("no-decay");return K}function p8($,Z,K){return $.filter((Y)=>{return Y.snippet.replace(/<\/?mark>/g,"").includes(Z)}).slice(0,K)}var L4=L(()=>{H0();c();L$();K0();H$();P0();f2();D0();T0();d0();X1();M$()});var I6={};y(I6,{ClaudeSummaryGenerator:()=>L6});import{spawn as PY}from"child_process";class L6{async generateSummary($,Z,K,X,Y){let Q=this.buildPrompt($,Z,K,X,Y);return new Promise((G,_)=>{let J={...process.env};delete J.CLAUDECODE;let H=PY("claude",["-p","--output-format","text"],{env:J,stdio:["pipe","pipe","pipe"]}),V="",B="";H.stdout.on("data",(z)=>{V+=z.toString()}),H.stderr.on("data",(z)=>{B+=z.toString()}),H.on("error",(z)=>{_(Error(`Failed to spawn claude -p: ${z.message}`))}),H.on("close",(z)=>{if(z===0)G(V.trim());else _(Error(`claude -p exited with code ${z}: ${B.trim()}`))}),H.stdin.write(Q),H.stdin.end()})}buildPrompt($,Z,K,X,Y){return["Summarize this Claude Code session into a structured daily log entry.","Output ONLY the markdown content below, no preamble or explanation.","","Format:",`## Session: ${Z} (${X} - ${Y})`,`**Project:** ${K}`,"","### Topic","[1-2 sentence summary of what the session was about]","","### Decisions","- [Key technical decisions made, one per bullet]","","### Outcomes","- [What was built, changed, or accomplished]","","### Unresolved",'- [Open questions or incomplete work, or "None" if all resolved]',"","### Learnings","- [Technical insights or patterns discovered]","","### Key Files","- [Important files created or modified]","","Session content:",$].join(`
|
|
971
|
+
`)}}var T6=()=>{};import{Command as uY}from"commander";var z3={name:"@chude/memory",version:"4.0.0",description:"Cross-project context persistence for Claude Code sessions",type:"module",main:"dist/index.js",types:"dist/index.d.ts",bin:{memory:"dist/presentation/cli/index.js"},files:["dist"],scripts:{"clean:dist":"bun run scripts/clean-dist.ts","build:types":"tsc --project tsconfig.lib.json","build:lib":"bun build src/index.ts --outdir dist --target bun --packages=external --minify --sourcemap=none","build:cli":"bun build src/presentation/cli/index.ts --outdir dist/presentation/cli --target bun --packages=external --minify --sourcemap=none",build:"bun run clean:dist && bun run build:types && bun run build:lib && bun run build:cli","build:hook":"bun build src/infrastructure/hooks/sync-hook-script.ts --outfile=dist/sync-hook.js --target=bun",test:"bun test","test:coverage":"bun run scripts/run-istanbul-bun-coverage.ts --coverage-dir coverage && bun run scripts/check-coverage-thresholds.ts --summary coverage/coverage-summary.json --threshold 95",quality:"bun run typecheck && bun run build && bun test --timeout 15000 && bun run test:isolation && bun run test:coverage && bun audit","test:smoke":"bun test tests/smoke","test:isolation":"bun run scripts/check-test-isolation.ts",typecheck:"tsc --noEmit && tsc --project tsconfig.scripts.json",lint:"bun run typecheck",mutation:"stryker run","mutation:domain":"stryker run --mutate 'src/domain/**/!(*.test).ts'"},author:"Chude <chude@emeke.org>",license:"MIT",devDependencies:{"@stryker-mutator/core":"9.6.1","@stryker-mutator/typescript-checker":"9.6.1","@stryker-mutator/vitest-runner":"9.6.1","@types/bun":"1.3.14","@types/cli-progress":"^3.11.6","@types/istanbul-lib-coverage":"^2.0.6","@types/istanbul-lib-instrument":"^1.7.8","@types/istanbul-lib-report":"^3.0.3","@types/istanbul-reports":"^3.0.4","istanbul-lib-coverage":"^3.2.2","istanbul-lib-instrument":"^6.0.3","istanbul-lib-report":"^3.0.1","istanbul-reports":"^3.2.0",typescript:"^5.5.0",vitest:"4.1.7"},engines:{bun:">=1.0.0"},keywords:["claude","claude-code","context","memory","session","search"],repository:{type:"git",url:"git+ssh://git@github.com/chudeemeke/memory-nexus.git"},dependencies:{"@anthropic-ai/claude-code":"2.1.152","@anthropic-ai/sdk":"0.98.1","@huggingface/transformers":"4.2.0","@inquirer/search":"4.2.0","@inquirer/select":"5.2.0","chart.js":"^4.5.1","chrono-node":"2.9.1","cli-progress":"^3.12.0",commander:"14.0.3",fuzzy:"^0.1.3","sqlite-vec":"0.1.9","string-width":"8.2.1"},overrides:{"@protobufjs/utf8":"1.1.1","fast-uri":"3.1.2",picomatch:"4.0.4",postcss:"8.5.15",protobufjs:"8.4.2",qs:"6.15.2",rollup:"4.60.4",vite:"8.0.14",yaml:"2.9.0"},trustedDependencies:["onnxruntime-node","protobufjs"]};r$();import{Command as pK,Option as M8}from"commander";o1();E4();P4();H0();var n6={redactText:($)=>({text:$,findings:[]}),redactJson:($)=>({value:$,findings:[]})};class D4{sessionSource;eventParser;sessionRepo;messageRepo;toolUseRepo;extractionStateRepo;db;abortSignal;checkpointManager;redactor;constructor($,Z,K,X,Y,Q,G,_,J,H=n6){this.sessionSource=$;this.eventParser=Z;this.sessionRepo=K;this.messageRepo=X;this.toolUseRepo=Y;this.extractionStateRepo=Q;this.db=G;this.abortSignal=_;this.checkpointManager=J;this.redactor=H}async sync($={}){let Z=Date.now(),K=$.checkpointEnabled!==!1,X={success:!0,sessionsDiscovered:0,sessionsProcessed:0,sessionsSkipped:0,messagesInserted:0,toolUsesInserted:0,errors:[],durationMs:0,aborted:!1},Y=null,Q=new Set;if(K){if(Y=this.checkpointManager.load(),Y){X.recoveredFromCheckpoint=Y.completedSessions;for(let V of Y.completedSessionIds)Q.add(V)}}$.onProgress?.({current:0,total:0,sessionId:"",phase:"discovering"});let G;try{G=await this.sessionSource.discoverSessions()}catch(V){throw new j(F.SOURCE_INACCESSIBLE,"Failed to discover sessions",{reason:A(V)})}X.sessionsDiscovered=G.length;let _=await this.filterSessions(G,$);if(Q.size>0){let V=_.length;_=_.filter((B)=>!Q.has(B.id)),X.sessionsSkipped+=V-_.length}if(X.sessionsSkipped=X.sessionsDiscovered-_.length-Q.size,X.sessionsSkipped<0)X.sessionsSkipped=X.sessionsDiscovered-_.length;let J=_.length+Q.size,H=Y??{startedAt:new Date().toISOString(),totalSessions:J,completedSessions:Q.size,completedSessionIds:[...Q],lastCompletedAt:null};for(let V=0;V<_.length;V++){if(this.abortSignal.shouldAbort()){if(X.aborted=!0,K)this.checkpointManager.save(H);break}let B=_[V];if(!B)continue;$.onProgress?.({current:V+1+Q.size,total:J,sessionId:B.id,phase:"extracting"});try{let z=await this.extractSession(B);if(X.sessionsProcessed++,X.messagesInserted+=z.messages,X.toolUsesInserted+=z.toolUses,K)H.completedSessions++,H.completedSessionIds.push(B.id),H.lastCompletedAt=new Date().toISOString(),this.checkpointManager.save(H);$.onSessionComplete?.(B.id)}catch(z){let W=this.wrapError(z,B.path);X.errors.push({sessionPath:B.path,error:W.message}),X.success=!1}}if(K&&!X.aborted&&X.success)this.checkpointManager.clear();return $.onProgress?.({current:J,total:J,sessionId:"",phase:"complete"}),X.durationMs=Date.now()-Z,X}async fixProjectNames($){let Z=await this.sessionRepo.findDistinctEncodedPaths(),K=0;for(let X of Z){let Y=$.resolveFromEncodedPath(X),Q=await this.sessionRepo.updateProjectName(X,Y);K+=Q}return K}wrapError($,Z){if($ instanceof j)return $;let K=A($);if(K.includes("ENOENT")||K.includes("no such file"))return new j(F.SOURCE_INACCESSIBLE,`Cannot access session file: ${K}`,{path:Z});if(K.includes("JSON")||K.includes("parse"))return new j(F.INVALID_JSON,`Failed to parse session file: ${K}`,{path:Z});if(K.includes("locked")||K.includes("SQLITE_BUSY"))return new j(F.DB_LOCKED,`Database is locked: ${K}`,{path:Z});if(K.includes("database")||K.includes("SQLITE"))return new j(F.DB_CONNECTION_FAILED,`Database error: ${K}`,{path:Z});return new j(F.SYNC_FAILED,K,{path:Z})}async filterSessions($,Z){let K=$;if(Z.projectFilter)K=K.filter((Y)=>Y.projectPath.decoded.includes(Z.projectFilter));if(Z.sessionFilter)K=K.filter((Y)=>Y.id===Z.sessionFilter);let X=[];for(let Y of K){let Q=await this.extractionStateRepo.findBySessionPath(Y.path);if(this.needsExtraction(Y,Q,Z.force??!1))X.push(Y)}return X}needsExtraction($,Z,K){if(K)return!0;if(!Z)return!0;if(Z.status!=="complete")return!0;let{fileMtime:X,fileSize:Y}=Z;if(!X||Y===void 0||Y===null)return!0;return $.modifiedTime.getTime()!==X.getTime()||$.size!==Y}async extractSession($){let Z=crypto.randomUUID(),K=Q0.create({id:Z,sessionPath:$.path,startedAt:new Date,status:"pending"}).withFileMetadata($.modifiedTime,$.size);try{let X=[];for await(let V of this.eventParser.parse($.path))X.push(V);let{messages:Y,toolUses:Q,firstTimestamp:G,lastTimestamp:_}=this.extractEntities(X),J=O0.create({id:$.id,projectPath:$.projectPath,startTime:G??new Date,endTime:_,messageCount:Y.length});return this.db.transaction(()=>{if(this.sessionRepo.save(J),Y.length>0)this.messageRepo.saveMany(Y.map((B)=>({message:B,sessionId:$.id})));if(Q.length>0)this.toolUseRepo.saveMany(Q.map((B)=>({toolUse:B,sessionId:$.id})));let V=K.startProcessing().incrementMessages(Y.length).complete(new Date);this.extractionStateRepo.save(V)}).immediate(),{messages:Y.length,toolUses:Q.length}}catch(X){let Y=K.fail(A(X));throw await this.extractionStateRepo.save(Y),X}}extractEntities($){let Z=[],K=[],X=new Map,Y,Q;for(let G of $){if(G.type==="skipped")continue;if("data"in G&&G.data.timestamp){let _=new Date(G.data.timestamp);if(!Y||_<Y)Y=_;if(!Q||_>Q)Q=_}switch(G.type){case"user":{let _=J0.create({id:G.data.uuid,role:"user",content:this.redactor.redactText(G.data.message.content).text,timestamp:new Date(G.data.timestamp)});Z.push(_);break}case"assistant":{let _=G.data.message.content.filter((B)=>B.type==="text").map((B)=>B.text).join(`
|
|
972
|
+
`),J=this.redactor.redactText(_).text,H=G.data.message.content.filter((B)=>B.type==="tool_use").map((B)=>B.id);for(let B of G.data.message.content)if(B.type==="tool_use"){let z=U0.create({id:B.id,name:B.name,input:this.redactor.redactJson(B.input).value,timestamp:new Date(G.data.timestamp),status:"pending"});X.set(B.id,z)}let V=J0.create({id:G.data.uuid,role:"assistant",content:J,timestamp:new Date(G.data.timestamp),toolUseIds:H});Z.push(V);break}case"tool_use":{let _=U0.create({id:G.data.uuid,name:G.data.name,input:this.redactor.redactJson(G.data.input).value,timestamp:new Date(G.data.timestamp),status:"pending"});X.set(G.data.uuid,_);break}case"tool_result":{let _=X.get(G.data.toolUseId);if(_){let J=G.data.isError?_.completeError(this.redactor.redactText(G.data.content).text):_.completeSuccess(this.redactor.redactText(G.data.content).text);X.set(G.data.toolUseId,J)}break}case"summary":case"system":break}}return K.push(...X.values()),{messages:Z,toolUses:K,firstTimestamp:Y,lastTimestamp:Q}}}t1();t$();$9();import{existsSync as r6}from"fs";var x3={redactText:($)=>({text:$,findings:[]}),redactJson:($)=>({value:$,findings:[]})};function B1($,Z){return $.redactText(Z).text}function s1($,Z){return Z===null?null:B1($,Z)}async function Z9($,Z,K={}){let X=K.includeSensitive?x3:K.redactor??x3,Y=$.query(`SELECT id, project_path_encoded as projectPathEncoded,
|
|
973
|
+
project_path_decoded as projectPathDecoded,
|
|
974
|
+
project_name as projectName,
|
|
975
|
+
start_time as startTime, end_time as endTime,
|
|
976
|
+
message_count as messageCount, summary
|
|
977
|
+
FROM sessions`).all().map((q)=>({...q,summary:s1(X,q.summary)})),Q=$.query(`SELECT id, session_id as sessionId, role, content, timestamp,
|
|
978
|
+
tool_use_ids as toolUseIds
|
|
979
|
+
FROM messages_meta`).all().map((q)=>({...q,content:B1(X,q.content)})),G=$.query(`SELECT id, session_id as sessionId, name, input, timestamp, status, result
|
|
980
|
+
FROM tool_uses`).all().map((q)=>({...q,input:B1(X,q.input),result:s1(X,q.result)})),_=$.query(`SELECT id, type, name, metadata, confidence
|
|
981
|
+
FROM entities`).all().map((q)=>({...q,name:B1(X,q.name),metadata:s1(X,q.metadata)})),J=$.query(`SELECT source_type as sourceType, source_id as sourceId,
|
|
982
|
+
target_type as targetType, target_id as targetId,
|
|
983
|
+
relationship, weight
|
|
984
|
+
FROM links`).all(),H=$.query(`SELECT session_id as sessionId, entity_id as entityId, frequency
|
|
985
|
+
FROM session_entities`).all(),V=$.query(`SELECT source_id as sourceId, target_id as targetId, relationship, weight
|
|
986
|
+
FROM entity_links`).all(),B=$.query(`SELECT id, session_path as sessionPath, started_at as startedAt,
|
|
987
|
+
status, completed_at as completedAt,
|
|
988
|
+
messages_extracted as messagesExtracted,
|
|
989
|
+
error_message as errorMessage,
|
|
990
|
+
file_mtime as fileMtime, file_size as fileSize
|
|
991
|
+
FROM extraction_state`).all().map((q)=>({...q,sessionPath:B1(X,q.sessionPath),errorMessage:s1(X,q.errorMessage)})),z=$.query(`SELECT uuid, type, project, content, metadata,
|
|
992
|
+
observed_at as observedAt, superseded_at as supersededAt,
|
|
993
|
+
superseded_by as supersededBy
|
|
994
|
+
FROM facts`).all().map((q)=>({...q,content:B1(X,q.content),metadata:s1(X,q.metadata)})),W={version:"1.0",exportedAt:new Date().toISOString(),stats:{sessions:Y.length,messages:Q.length,toolUses:G.length,entities:_.length,links:J.length,sessionEntities:H.length,entityLinks:V.length,extractionStates:B.length,facts:z.length},sessions:Y,messages:Q,toolUses:G,entities:_,links:J,sessionEntities:H,entityLinks:V,extractionStates:B,facts:z},N=JSON.stringify(W,null,2);return await Bun.write(Z,N),{sessions:Y.length,messages:Q.length,toolUses:G.length,entities:_.length,links:J.length,bytes:N.length,facts:z.length}}async function k4($){if(!r6($))return{valid:!1,error:"File does not exist"};try{let K=await Bun.file($).text(),X=JSON.parse(K);if(!X.version||typeof X.version!=="string")return{valid:!1,error:"Missing or invalid version field"};let Y=["sessions","messages","toolUses","entities","links"];for(let Q of Y)if(!Array.isArray(X[Q]))return{valid:!1,error:`Missing or invalid ${Q} array`};if(!X.stats||typeof X.stats!=="object")return{valid:!1,error:"Missing or invalid stats object"};return{valid:!0,version:X.version}}catch(Z){return{valid:!1,error:`Failed to parse file: ${A(Z)}`}}}async function K9($,Z,K={}){let X=await k4(Z);if(!X.valid)throw Error(`Invalid export file: ${X.error}`);let Q=await Bun.file(Z).text(),G=JSON.parse(Q);if(K.clearExisting)o6($);return $.transaction(()=>{let J=$.prepare(`
|
|
995
|
+
INSERT OR IGNORE INTO sessions
|
|
996
|
+
(id, project_path_encoded, project_path_decoded, project_name,
|
|
997
|
+
start_time, end_time, message_count, summary)
|
|
998
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
999
|
+
`);for(let W of G.sessions)J.run(W.id,W.projectPathEncoded,W.projectPathDecoded,W.projectName,W.startTime,W.endTime,W.messageCount,W.summary);let H=$.prepare(`
|
|
1000
|
+
INSERT OR IGNORE INTO messages_meta
|
|
1001
|
+
(id, session_id, role, content, timestamp, tool_use_ids)
|
|
1002
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
1003
|
+
`);for(let W of G.messages)H.run(W.id,W.sessionId,W.role,W.content,W.timestamp,W.toolUseIds);let V=$.prepare(`
|
|
1004
|
+
INSERT OR IGNORE INTO tool_uses
|
|
1005
|
+
(id, session_id, name, input, timestamp, status, result)
|
|
1006
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
1007
|
+
`);for(let W of G.toolUses)V.run(W.id,W.sessionId,W.name,W.input,W.timestamp,W.status,W.result);let B=$.prepare(`
|
|
1008
|
+
INSERT OR IGNORE INTO entities
|
|
1009
|
+
(id, type, name, metadata, confidence)
|
|
1010
|
+
VALUES (?, ?, ?, ?, ?)
|
|
1011
|
+
`);for(let W of G.entities)B.run(W.id,W.type,W.name,W.metadata,W.confidence);let z=$.prepare(`
|
|
1012
|
+
INSERT OR IGNORE INTO links
|
|
1013
|
+
(source_type, source_id, target_type, target_id, relationship, weight)
|
|
1014
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
1015
|
+
`);for(let W of G.links)z.run(W.sourceType,W.sourceId,W.targetType,W.targetId,W.relationship,W.weight);if(G.sessionEntities&&G.sessionEntities.length>0){let W=$.prepare(`
|
|
1016
|
+
INSERT OR IGNORE INTO session_entities
|
|
1017
|
+
(session_id, entity_id, frequency)
|
|
1018
|
+
VALUES (?, ?, ?)
|
|
1019
|
+
`);for(let N of G.sessionEntities)W.run(N.sessionId,N.entityId,N.frequency)}if(G.entityLinks&&G.entityLinks.length>0){let W=$.prepare(`
|
|
1020
|
+
INSERT OR IGNORE INTO entity_links
|
|
1021
|
+
(source_id, target_id, relationship, weight)
|
|
1022
|
+
VALUES (?, ?, ?, ?)
|
|
1023
|
+
`);for(let N of G.entityLinks)W.run(N.sourceId,N.targetId,N.relationship,N.weight)}if(G.extractionStates&&G.extractionStates.length>0){let W=$.prepare(`
|
|
1024
|
+
INSERT OR IGNORE INTO extraction_state
|
|
1025
|
+
(id, session_path, started_at, status, completed_at,
|
|
1026
|
+
messages_extracted, error_message, file_mtime, file_size)
|
|
1027
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1028
|
+
`);for(let N of G.extractionStates)W.run(N.id,N.sessionPath,N.startedAt,N.status,N.completedAt,N.messagesExtracted,N.errorMessage,N.fileMtime,N.fileSize)}if(G.facts&&G.facts.length>0){let W=$.prepare(`
|
|
1029
|
+
INSERT OR IGNORE INTO facts
|
|
1030
|
+
(uuid, type, project, content, metadata, observed_at, superseded_at, superseded_by)
|
|
1031
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
1032
|
+
`);for(let N of G.facts)W.run(N.uuid,N.type,N.project,N.content,N.metadata,N.observedAt,N.supersededAt,N.supersededBy)}return{sessions:G.sessions.length,messages:G.messages.length,toolUses:G.toolUses.length,entities:G.entities.length,links:G.links.length,facts:G.facts?G.facts.length:0}}).immediate()}function o6($){$.exec("PRAGMA foreign_keys = OFF;");try{$.exec("DELETE FROM session_entities;"),$.exec("DELETE FROM entity_links;"),$.exec("DELETE FROM links;"),$.exec("DELETE FROM messages_meta;"),$.exec("DELETE FROM sessions_fts;"),$.exec("DELETE FROM facts;"),$.exec("DELETE FROM tool_uses;"),$.exec("DELETE FROM sessions;"),$.exec("DELETE FROM entities;"),$.exec("DELETE FROM extraction_state;"),$.exec("DELETE FROM topics;")}finally{$.exec("PRAGMA foreign_keys = ON;")}}function X9($){return($.query(`SELECT (SELECT COUNT(*) FROM sessions) +
|
|
1033
|
+
(SELECT COUNT(*) FROM messages_meta) as count`).get()?.count??0)>0}S4();class v4{repository;scanner;constructor($,Z){this.repository=$;this.scanner=Z}async syncMemoryFiles($={}){let Z={filesIndexed:0,filesSkipped:0,errors:[]},K;try{K=await this.scanner.discoverFiles()}catch(X){return Z.errors.push({filePath:"~/.memory/",error:A(X)}),Z}for(let X=0;X<K.length;X++){let Y=K[X];if(!Y)continue;try{let Q=await this.repository.findByPath(Y.filePath);if(Q&&Q.contentHash===Y.contentHash){Z.filesSkipped++,$.onProgress?.({current:X+1,total:K.length,filePath:Y.filePath,action:"skipped"});continue}let G=t0.create({filePath:Y.filePath,fileType:Y.fileType,projectEncoded:Y.projectEncoded,content:Y.content,contentHash:Y.contentHash,lastIndexedAt:new Date});await this.repository.save(G),Z.filesIndexed++,$.onProgress?.({current:X+1,total:K.length,filePath:Y.filePath,action:"indexing"})}catch(Q){Z.errors.push({filePath:Y.filePath,error:A(Q)})}}return Z}}C4();H0();import{existsSync as s6,readFileSync as e6,unlinkSync as $7}from"fs";class y4{repository;constructor($){this.repository=$}async log($){let Z=C0.create({description:$.description,severity:$.severity??"medium",category:$.category??"cli",tool:$.tool??"memory",status:"open",context:$.context,sourceProject:$.sourceProject,loggedAt:$.loggedAt??new Date});return this.repository.save(Z)}async list($){if($?.all||$?.tool||$?.category||$?.sourceProject)return this.repository.findAll({status:$?.all?$.status:"open",category:$?.category,tool:$?.tool,sourceProject:$?.sourceProject,limit:$?.limit});return this.repository.findOpen()}async resolve($,Z){let K=await this.repository.findById($);if(!K)throw new j(F.NOT_FOUND,`Friction entry #${$} not found`,{id:$});if(K.status!=="open")throw new j(F.INVALID_STATE,`Friction entry #${$} is already ${K.status}`,{id:$,currentStatus:K.status});await this.repository.resolve($,Z)}async wontFix($,Z){let K=await this.repository.findById($);if(!K)throw new j(F.NOT_FOUND,`Friction entry #${$} not found`,{id:$});if(K.status!=="open")throw new j(F.INVALID_STATE,`Friction entry #${$} is already ${K.status}`,{id:$,currentStatus:K.status});await this.repository.resolve($,Z),await this.repository.updateStatus($,"wont-fix")}async getStats(){return this.repository.getStats()}async getWeeklyTrends($=4){return this.repository.getWeeklyTrends($)}async ingestFallbackFile($){if(!s6($))return 0;let K=e6($,"utf-8").split(`
|
|
1034
|
+
`).filter(Boolean),X=0;for(let Y of K)try{let Q=JSON.parse(Y);await this.log({description:Q.description,severity:Q.severity??"medium",category:Q.category??"cli",tool:Q.tool??"unknown",context:Q.context,sourceProject:Q.project,loggedAt:Q.date?new Date(Q.date+"T00:00:00Z"):new Date}),X++}catch{process.stderr.write(`Warning: skipping malformed friction entry in ${$}
|
|
1035
|
+
`)}try{$7($)}catch{process.stderr.write(`Warning: could not delete ${$} (entries already ingested)
|
|
1036
|
+
`)}return X}async detectPatterns($=3){return this.repository.findPatterns($)}async markReviewed($){await this.repository.markReviewed($,new Date)}async purge($){return this.repository.deleteByPattern($)}}G9();w4();O9();c();W4();import{createReadStream as $K}from"fs";import{createInterface as ZK}from"readline";function x1($){if(typeof $==="string"){if(/^\d{4}-\d{2}-\d{2}T/.test($))return $;let Z=new Date($);if(!isNaN(Z.getTime()))return Z.toISOString()}if(typeof $==="number"&&!isNaN($)){let Z=$>1000000000000?$:$*1000,K=new Date(Z);if(!isNaN(K.getTime()))return K.toISOString()}if($ instanceof Date&&!isNaN($.getTime()))return $.toISOString();return new Date().toISOString()}var a7=new Set(["progress","agent_progress","bash_progress","mcp_progress","hook_progress","base64","image","file-history-snapshot","waiting_for_task","create","update","queue-operation"]);function r5($){if(typeof $!=="object"||$===null)return!1;return typeof $.type==="string"}function t9($){if(!r5($))return{type:"skipped",reason:"Invalid event structure"};let Z=$.type;if(a7.has(Z))return{type:"skipped",reason:`Event type "${Z}" not extracted`};switch(Z){case"user":return i7($);case"assistant":return o7($);case"summary":return s7($);case"system":return e7($);default:return{type:"skipped",reason:`Event type "${Z}" not classified`}}}function i7($){if(!$.uuid||!$.timestamp||!$.message)return{type:"skipped",reason:"User event missing required fields"};let Z={uuid:$.uuid,message:{content:r7($.message.content)},timestamp:x1($.timestamp)};if($.cwd)Z.cwd=$.cwd;if($.gitBranch)Z.gitBranch=$.gitBranch;return{type:"user",data:Z}}function r7($){if(typeof $==="string")return $;if(Array.isArray($))return $.filter((K)=>K.type==="tool_result").map((K)=>{if(typeof K.content==="string")return K.content;return JSON.stringify(K.content)}).join(`
|
|
1037
|
+
`);return""}function o7($){if(!$.uuid||!$.timestamp||!$.message)return{type:"skipped",reason:"Assistant event missing required fields"};let Z=t7($.message.content||[]),K={uuid:$.uuid,message:{content:Z},timestamp:x1($.timestamp)};if($.message.model)K.message.model=$.message.model;if($.message.usage)K.usage={inputTokens:$.message.usage.input_tokens,outputTokens:$.message.usage.output_tokens};return{type:"assistant",data:K}}function t7($){if(!Array.isArray($))return[];return $.filter((Z)=>{return Z.type!=="thinking"}).map((Z)=>{if(Z.type==="text")return{type:"text",text:Z.text};if(Z.type==="tool_use")return{type:"tool_use",id:Z.id,name:Z.name,input:Z.input};return{type:"text",text:""}})}function s7($){if(!$.summary)return{type:"skipped",reason:"Summary event missing summary field"};let Z={content:$.summary,timestamp:x1($.timestamp)};if($.leafUuid)Z.leafUuid=$.leafUuid;return{type:"summary",data:Z}}function e7($){if(!$.subtype)return{type:"skipped",reason:"System event missing subtype field"};return{type:"system",data:{subtype:$.subtype,data:$.durationMs??$.data??null,timestamp:x1($.timestamp)}}}class Z${async*parse($){let Z=$K($,{encoding:"utf8"}),K=ZK({input:Z,crlfDelay:1/0}),X=0;for await(let Y of K){X++;let Q=Y.trim();if(Q===""){yield{type:"skipped",reason:`Empty line at ${X}`};continue}try{let G=JSON.parse(Q);yield t9(G)}catch(G){let _=A(G);yield{type:"skipped",reason:`Malformed JSON at line ${X}: ${_}`}}}}}l();import{existsSync as s9,mkdirSync as KK,readFileSync as XK,unlinkSync as YK,writeFileSync as QK}from"fs";import{dirname as GK}from"path";function K$($){return $??l1()}function o5($,Z){let K=K$(Z),X=GK(K);try{KK(X,{recursive:!0}),QK(K,JSON.stringify($,null,2)+`
|
|
1038
|
+
`)}catch(Y){console.warn("Failed to save checkpoint:",Y.message)}}function E1($){let Z=K$($);if(!s9(Z))return null;try{let K=XK(Z,"utf-8"),X=JSON.parse(K);if(typeof X.startedAt!=="string"||typeof X.totalSessions!=="number"||typeof X.completedSessions!=="number"||!Array.isArray(X.completedSessionIds))return console.warn("Invalid checkpoint format, ignoring"),null;return X}catch{return console.warn("Invalid checkpoint JSON, ignoring"),null}}function t5($){let Z=K$($);if(s9(Z))try{YK(Z)}catch(K){console.warn("Failed to clear checkpoint:",K.message)}}function s5($){return s9(K$($))}import*as $Z from"readline";var i={isShuttingDown:!1,interruptCount:0,cleanupFunctions:[],handlersRegistered:!1,ttyOverride:null,exitOverride:null};function _K(){if(i.ttyOverride!==null)return i.ttyOverride;return process.stdin.isTTY??!1}function X$($){if(i.exitOverride!==null){i.exitOverride($);return}process.exit($)}async function ZZ(){for(let $ of i.cleanupFunctions)try{await $()}catch(Z){console.warn("Cleanup error:",Z.message)}}async function JK(){let $=$Z.createInterface({input:process.stdin,output:process.stdout});return new Promise((Z)=>{let K=()=>{console.log(`
|
|
1039
|
+
Interrupt received. Choose action:`),console.log(" 1) Abort immediately"),console.log(" 2) Abort after current session (saves progress)"),console.log(" 3) Cancel abort (continue)"),$.question("> ",(X)=>{let Y=parseInt(X.trim(),10);if(Y===1||Y===2||Y===3)$.close(),Z(Y);else console.log("Invalid choice. Enter 1, 2, or 3."),K()})};K()})}async function HK($){switch($){case 1:console.log("Aborting immediately..."),await ZZ(),X$(130);break;case 2:console.log("Will abort after current session..."),i.isShuttingDown=!0;break;case 3:console.log("Continuing..."),i.interruptCount=0;break}}async function e5(){if(i.interruptCount++,i.interruptCount>=2){console.log(`
|
|
1040
|
+
Force exiting...`),await ZZ(),X$(130);return}if(_K()){let $=await JK();await HK($)}else console.log(`
|
|
1041
|
+
Interrupt received, shutting down after current operation...`),i.isShuttingDown=!0}function KZ(){if(i.handlersRegistered)return;process.on("SIGINT",()=>{e5().catch(($)=>{console.error("Signal handler error:",$),X$(1)})}),process.on("SIGTERM",()=>{e5().catch(($)=>{console.error("Signal handler error:",$),X$(1)})}),i.handlersRegistered=!0}function XZ(){return i.isShuttingDown}function YZ($){i.cleanupFunctions.push($)}function QZ($){let Z=i.cleanupFunctions.indexOf($);if(Z!==-1)i.cleanupFunctions.splice(Z,1)}class Y${shouldAbort(){return XZ()}}class Q${path;constructor($){this.path=$}load(){return E1(this.path)}save($){o5($,this.path)}clear(){t5(this.path)}}u0();H$();_2();V2();B$();N2();L2();D0();import{readFileSync as LK}from"fs";import{resolve as IK}from"path";function T2($,Z,K,X,Y){if($.total===0)return"No friction entries logged yet.";let Q=[];Q.push(s("Friction Dashboard",X)),Q.push("=================="),Q.push(""),Q.push(s(" Overview",X)),Q.push(" --------"),Q.push(` Total: ${$.total} Open: ${u(String($.open),X)} Resolved: ${w(String($.resolved),X)} Won't Fix: ${$.wontFix}`),Q.push("");let G=$.meanTimeToResolve!==null?`MTTR: ${$.meanTimeToResolve.toFixed(1)} days`:"MTTR: N/A";if($.oldestOpen)Q.push(` ${G} Oldest Open: #${$.oldestOpen.id} (${$.oldestOpen.daysOpen} days)`);else Q.push(` ${G}`);Q.push(""),Q.push(s(" By Severity",X)),Q.push(" -----------");let _=["critical","high","medium","low"],J=Math.max(..._.map((H)=>$.bySeverity[H]),1);for(let H of _){let V=$.bySeverity[H],B=Math.round(V/J*20),z="=".repeat(B)+" ".repeat(20-B),W=H.padEnd(10),N=H==="critical"||H==="high"?m(W,X):H==="medium"?u(W,X):w(W,X);Q.push(` ${N}[${z}] ${V}`)}Q.push(""),Q.push(s(" By Category",X)),Q.push(" -----------");for(let[H,V]of Object.entries($.byCategory))Q.push(` ${GZ(H.padEnd(14),X)}${V}`);if(Q.push(""),$.byTool&&Object.keys($.byTool).length>0){Q.push(s(" By Tool",X)),Q.push(" -------");for(let[H,V]of Object.entries($.byTool)){let B="=".repeat(Math.min(V,40));Q.push(` ${H.padEnd(15)} ${B} ${V}`)}Q.push("")}if(Y&&Y.length>0){Q.push(s(" Pattern Alerts",X)),Q.push(" --------------");for(let H of Y)Q.push(` [!] Pattern detected: ${H.count} open entries for ${H.tool}/${H.category}`);Q.push("")}if(Z.length===0)Q.push(" No trend data available.");else{Q.push(s(" Trends",X)),Q.push(" ------"),Q.push(` ${"Week".padEnd(12)}${"New".padEnd(6)}Resolved`);for(let H of Z)Q.push(` ${k(H.week.padEnd(12),X)}${String(H.newCount).padEnd(6)}${H.resolvedCount}`)}return Q.join(`
|
|
1042
|
+
`)}function TK(){let $=IK(import.meta.dirname,"../../../../node_modules/chart.js/dist/chart.umd.js");return LK($,"utf-8")}function RK($){return $.map((Z)=>({id:Z.id,severity:Z.severity,category:Z.category,description:Z.description,daysOpen:Math.floor((Date.now()-Z.loggedAt.getTime())/86400000)}))}function R2($,Z,K,X){let Y=TK(),Q=RK(K),G=$.meanTimeToResolve!==null?`${$.meanTimeToResolve.toFixed(1)} days`:"N/A",_=Q.map((J)=>`<tr>
|
|
1043
|
+
<td>${J.id??"-"}</td>
|
|
1044
|
+
<td class="severity-${J.severity}">${J.severity}</td>
|
|
1045
|
+
<td>${J.category}</td>
|
|
1046
|
+
<td>${I2(J.description)}</td>
|
|
1047
|
+
<td>${J.daysOpen}d</td>
|
|
1048
|
+
</tr>`).join(`
|
|
1049
|
+
`);return`<!DOCTYPE html>
|
|
1050
|
+
<html lang="en">
|
|
1051
|
+
<head>
|
|
1052
|
+
<meta charset="UTF-8">
|
|
1053
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1054
|
+
<title>Friction Dashboard</title>
|
|
1055
|
+
<style>
|
|
1056
|
+
body { background: #1a1a2e; color: #e0e0e0; font-family: system-ui, -apple-system, sans-serif; margin: 0; padding: 24px; }
|
|
1057
|
+
h1 { color: #e0e0e0; border-bottom: 1px solid #333; padding-bottom: 12px; }
|
|
1058
|
+
h2 { color: #e0e0e0; margin-top: 32px; }
|
|
1059
|
+
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; margin: 24px 0; }
|
|
1060
|
+
.stat-card { background: #16213e; border-radius: 8px; padding: 16px; text-align: center; }
|
|
1061
|
+
.stat-value { font-size: 2em; font-weight: bold; }
|
|
1062
|
+
.stat-label { color: #888; font-size: 0.9em; }
|
|
1063
|
+
.chart-container { background: #16213e; border-radius: 8px; padding: 16px; margin: 24px 0; }
|
|
1064
|
+
canvas { max-height: 300px; }
|
|
1065
|
+
table { width: 100%; border-collapse: collapse; margin: 24px 0; }
|
|
1066
|
+
th, td { text-align: left; padding: 8px 12px; border-bottom: 1px solid #333; }
|
|
1067
|
+
th { color: #888; font-weight: 600; }
|
|
1068
|
+
.severity-critical { color: #ff4444; }
|
|
1069
|
+
.severity-high { color: #ff8800; }
|
|
1070
|
+
.severity-medium { color: #ffcc00; }
|
|
1071
|
+
.severity-low { color: #44bb44; }
|
|
1072
|
+
.open { color: #ffcc00; }
|
|
1073
|
+
.resolved { color: #44bb44; }
|
|
1074
|
+
.generated { color: #666; font-size: 0.8em; margin-top: 48px; text-align: center; }
|
|
1075
|
+
</style>
|
|
1076
|
+
<script>${Y}</script>
|
|
1077
|
+
</head>
|
|
1078
|
+
<body>
|
|
1079
|
+
<h1>Friction Dashboard</h1>
|
|
1080
|
+
|
|
1081
|
+
<div class="stats-grid">
|
|
1082
|
+
<div class="stat-card">
|
|
1083
|
+
<div class="stat-value">${$.total}</div>
|
|
1084
|
+
<div class="stat-label">Total</div>
|
|
1085
|
+
</div>
|
|
1086
|
+
<div class="stat-card">
|
|
1087
|
+
<div class="stat-value open">${$.open}</div>
|
|
1088
|
+
<div class="stat-label">Open</div>
|
|
1089
|
+
</div>
|
|
1090
|
+
<div class="stat-card">
|
|
1091
|
+
<div class="stat-value resolved">${$.resolved}</div>
|
|
1092
|
+
<div class="stat-label">Resolved</div>
|
|
1093
|
+
</div>
|
|
1094
|
+
<div class="stat-card">
|
|
1095
|
+
<div class="stat-value">${$.wontFix}</div>
|
|
1096
|
+
<div class="stat-label">Won't Fix</div>
|
|
1097
|
+
</div>
|
|
1098
|
+
<div class="stat-card">
|
|
1099
|
+
<div class="stat-value">${G}</div>
|
|
1100
|
+
<div class="stat-label">MTTR</div>
|
|
1101
|
+
</div>
|
|
1102
|
+
</div>
|
|
1103
|
+
|
|
1104
|
+
<div class="chart-container">
|
|
1105
|
+
<canvas id="overTimeChart"></canvas>
|
|
1106
|
+
</div>
|
|
1107
|
+
|
|
1108
|
+
<div class="chart-container">
|
|
1109
|
+
<canvas id="byCategoryChart"></canvas>
|
|
1110
|
+
</div>
|
|
1111
|
+
|
|
1112
|
+
<div class="chart-container">
|
|
1113
|
+
<canvas id="bySeverityChart"></canvas>
|
|
1114
|
+
</div>
|
|
1115
|
+
|
|
1116
|
+
<div class="chart-container">
|
|
1117
|
+
<canvas id="resolutionTrendChart"></canvas>
|
|
1118
|
+
</div>
|
|
1119
|
+
|
|
1120
|
+
<div class="chart-container">
|
|
1121
|
+
<canvas id="byToolChart"></canvas>
|
|
1122
|
+
</div>
|
|
1123
|
+
|
|
1124
|
+
${X&&X.length>0?` <div class="alerts">
|
|
1125
|
+
<h2>Pattern Alerts</h2>
|
|
1126
|
+
<ul>
|
|
1127
|
+
${X.map((J)=>`<li>Pattern detected: ${J.count} open entries for ${I2(J.tool)}/${I2(J.category)}</li>`).join(`
|
|
1128
|
+
`)}
|
|
1129
|
+
</ul>
|
|
1130
|
+
</div>`:""}
|
|
1131
|
+
|
|
1132
|
+
<h2>Open Items</h2>
|
|
1133
|
+
<table id="openItemsTable">
|
|
1134
|
+
<thead>
|
|
1135
|
+
<tr><th>ID</th><th>Severity</th><th>Category</th><th>Description</th><th>Age</th></tr>
|
|
1136
|
+
</thead>
|
|
1137
|
+
<tbody>
|
|
1138
|
+
${_||'<tr><td colspan="5">No open items</td></tr>'}
|
|
1139
|
+
</tbody>
|
|
1140
|
+
</table>
|
|
1141
|
+
|
|
1142
|
+
<div class="generated">Generated ${new Date().toISOString().split("T")[0]}</div>
|
|
1143
|
+
|
|
1144
|
+
<script>
|
|
1145
|
+
const stats = ${JSON.stringify($)};
|
|
1146
|
+
const trends = ${JSON.stringify(Z)};
|
|
1147
|
+
const openItems = ${JSON.stringify(Q)};
|
|
1148
|
+
|
|
1149
|
+
const chartDefaults = {
|
|
1150
|
+
color: '#e0e0e0',
|
|
1151
|
+
borderColor: '#333',
|
|
1152
|
+
};
|
|
1153
|
+
Chart.defaults.color = '#e0e0e0';
|
|
1154
|
+
Chart.defaults.borderColor = '#333';
|
|
1155
|
+
|
|
1156
|
+
// Chart 1: Friction Over Time (line)
|
|
1157
|
+
if (trends.length > 0) {
|
|
1158
|
+
new Chart(document.getElementById('overTimeChart'), {
|
|
1159
|
+
type: 'line',
|
|
1160
|
+
data: {
|
|
1161
|
+
labels: trends.map(t => t.week),
|
|
1162
|
+
datasets: [
|
|
1163
|
+
{ label: 'New', data: trends.map(t => t.newCount), borderColor: '#ff4444', backgroundColor: 'rgba(255,68,68,0.1)', fill: true, tension: 0.3 },
|
|
1164
|
+
{ label: 'Resolved', data: trends.map(t => t.resolvedCount), borderColor: '#44bb44', backgroundColor: 'rgba(68,187,68,0.1)', fill: true, tension: 0.3 }
|
|
1165
|
+
]
|
|
1166
|
+
},
|
|
1167
|
+
options: { responsive: true, plugins: { title: { display: true, text: 'Friction Over Time', color: '#e0e0e0' } }, scales: { x: { ticks: { color: '#888' }, grid: { color: '#333' } }, y: { ticks: { color: '#888' }, grid: { color: '#333' }, beginAtZero: true } } }
|
|
1168
|
+
});
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
// Chart 2: By Category (doughnut)
|
|
1172
|
+
new Chart(document.getElementById('byCategoryChart'), {
|
|
1173
|
+
type: 'doughnut',
|
|
1174
|
+
data: {
|
|
1175
|
+
labels: Object.keys(stats.byCategory),
|
|
1176
|
+
datasets: [{
|
|
1177
|
+
data: Object.values(stats.byCategory),
|
|
1178
|
+
backgroundColor: ['#ff6384', '#36a2eb', '#ffce56', '#4bc0c0', '#9966ff', '#ff9f40']
|
|
1179
|
+
}]
|
|
1180
|
+
},
|
|
1181
|
+
options: { responsive: true, plugins: { title: { display: true, text: 'By Category', color: '#e0e0e0' }, legend: { labels: { color: '#e0e0e0' } } } }
|
|
1182
|
+
});
|
|
1183
|
+
|
|
1184
|
+
// Chart 3: By Severity (horizontal bar)
|
|
1185
|
+
new Chart(document.getElementById('bySeverityChart'), {
|
|
1186
|
+
type: 'bar',
|
|
1187
|
+
data: {
|
|
1188
|
+
labels: ['Critical', 'High', 'Medium', 'Low'],
|
|
1189
|
+
datasets: [{
|
|
1190
|
+
label: 'Count',
|
|
1191
|
+
data: [stats.bySeverity.critical, stats.bySeverity.high, stats.bySeverity.medium, stats.bySeverity.low],
|
|
1192
|
+
backgroundColor: ['#ff4444', '#ff8800', '#ffcc00', '#44bb44']
|
|
1193
|
+
}]
|
|
1194
|
+
},
|
|
1195
|
+
options: { indexAxis: 'y', responsive: true, plugins: { title: { display: true, text: 'By Severity', color: '#e0e0e0' }, legend: { display: false } }, scales: { x: { ticks: { color: '#888' }, grid: { color: '#333' }, beginAtZero: true }, y: { ticks: { color: '#888' }, grid: { color: '#333' } } } }
|
|
1196
|
+
});
|
|
1197
|
+
|
|
1198
|
+
// Chart 4: By Tool (doughnut)
|
|
1199
|
+
if (stats.byTool && Object.keys(stats.byTool).length > 0) {
|
|
1200
|
+
new Chart(document.getElementById('byToolChart'), {
|
|
1201
|
+
type: 'doughnut',
|
|
1202
|
+
data: {
|
|
1203
|
+
labels: Object.keys(stats.byTool),
|
|
1204
|
+
datasets: [{
|
|
1205
|
+
data: Object.values(stats.byTool),
|
|
1206
|
+
backgroundColor: ['#ff6384', '#36a2eb', '#ffce56', '#4bc0c0', '#9966ff', '#ff9f40', '#c9cbcf']
|
|
1207
|
+
}]
|
|
1208
|
+
},
|
|
1209
|
+
options: { responsive: true, plugins: { title: { display: true, text: 'By Tool', color: '#e0e0e0' }, legend: { labels: { color: '#e0e0e0' } } } }
|
|
1210
|
+
});
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
// Chart 5: Resolution Trend (grouped bar)
|
|
1214
|
+
if (trends.length > 0) {
|
|
1215
|
+
new Chart(document.getElementById('resolutionTrendChart'), {
|
|
1216
|
+
type: 'bar',
|
|
1217
|
+
data: {
|
|
1218
|
+
labels: trends.map(t => t.week),
|
|
1219
|
+
datasets: [
|
|
1220
|
+
{ label: 'New', data: trends.map(t => t.newCount), backgroundColor: '#ff4444' },
|
|
1221
|
+
{ label: 'Resolved', data: trends.map(t => t.resolvedCount), backgroundColor: '#44bb44' }
|
|
1222
|
+
]
|
|
1223
|
+
},
|
|
1224
|
+
options: { responsive: true, plugins: { title: { display: true, text: 'Resolution Trend', color: '#e0e0e0' }, legend: { labels: { color: '#e0e0e0' } } }, scales: { x: { ticks: { color: '#888' }, grid: { color: '#333' } }, y: { ticks: { color: '#888' }, grid: { color: '#333' }, beginAtZero: true } } }
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1227
|
+
</script>
|
|
1228
|
+
</body>
|
|
1229
|
+
</html>`}function I2($){return $.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}P0();T0();async function x2($,Z){if(!$.embed)return console.log("--background requires --embed flag"),console.log(" Usage: memory sync --embed --background"),{exitCode:0};let{spawnBackgroundEmbedding:K,readLock:X,isProcessAlive:Y}=Z??await SK(),Q=X();if(Q&&Y(Q.pid))return console.log(`Embedding already in progress (PID ${Q.pid}). Use 'memory status' to check progress.`),{exitCode:0};let G=K();if(G.started)console.log(`Background embedding started (PID ${G.pid}). Use 'memory status' to check progress.`);else return console.error(`Failed to start background embedding: ${G.reason}`),{exitCode:1};return{exitCode:0}}async function SK(){let $=await Promise.resolve().then(() => (O$(),q$));return{spawnBackgroundEmbedding:$.spawnBackgroundEmbedding,readLock:$.readLock,isProcessAlive:$.isProcessAlive}}W4();async function $8(){let{EmbeddingProviderFactory:$}=await Promise.resolve().then(() => (L$(),E2));return new $}async function Z8(){let{loadConfig:$}=await Promise.resolve().then(() => (K0(),n4));return $()}async function K8($){let{EmbeddingRepository:Z}=await Promise.resolve().then(() => Q5);return new Z($)}async function X8($){let Z=new c0;try{let K=await Z.discoverSessions(),X=K;if($.project)X=X.filter((_)=>_.projectPath.decoded.includes($.project));if($.session)X=X.filter((_)=>_.id===$.session);let Y=E1(),Q=new Set(Y?.completedSessionIds??[]),G=X.filter((_)=>!Q.has(_.id));if($.json){let _={dryRun:!0,discovered:K.length,filtered:X.length,toProcess:G.length,recoveredFromCheckpoint:Y?.completedSessions??0,sessions:G.map((J)=>({id:J.id,project:J.projectPath.decoded,size:J.size,modified:J.modifiedTime.toISOString()}))};console.log(JSON.stringify(_,null,2))}else{if(console.log(`Dry run - no changes will be made
|
|
1230
|
+
`),console.log(`Discovered: ${K.length} sessions`),console.log(`After filter: ${X.length} sessions`),Y)console.log(`Checkpoint: ${Y.completedSessions} already done`);if(console.log(`To process: ${G.length} sessions
|
|
1231
|
+
`),G.length>0){console.log("Sessions to sync:");for(let _ of G.slice(0,20)){let J=_.projectPath.decoded.split(/[/\\]/).pop()??"unknown";console.log(` ${_.id.slice(0,16)}... ${J}`)}if(G.length>20)console.log(` ... and ${G.length-20} more`)}}return{exitCode:0}}catch(K){return P2(K,$),{exitCode:1}}}function P2($,Z){let K=g1($);if(Z.json)console.error(K1(K));else console.error(p(K,{verbose:!!Z.verbose}))}function Y8($,Z,K){let X=Date.now()-Z;if(K.json){let Y={success:$.success,aborted:$.aborted??!1,duration:X,discovered:$.sessionsDiscovered,processed:$.sessionsProcessed,skipped:$.sessionsSkipped,messages:$.messagesInserted,toolUses:$.toolUsesInserted,recoveredFromCheckpoint:$.recoveredFromCheckpoint,errors:$.errors};console.log(JSON.stringify(Y,null,2));return}if(K.quiet)return;if($.aborted)console.log(`
|
|
1232
|
+
Sync aborted (progress saved)`);else console.log(`
|
|
1233
|
+
Sync complete in ${X}ms`);if(console.log(` Discovered: ${$.sessionsDiscovered}`),console.log(` Processed: ${$.sessionsProcessed}`),console.log(` Skipped: ${$.sessionsSkipped}`),console.log(` Messages: ${$.messagesInserted}`),console.log(` Tool uses: ${$.toolUsesInserted}`),$.recoveredFromCheckpoint)console.log(` Recovered: ${$.recoveredFromCheckpoint} from checkpoint`);if($.errors.length>0){console.log(`
|
|
1234
|
+
Errors (${$.errors.length}):`);for(let Y of $.errors)console.log(` ${Y.sessionPath}: ${Y.error}`)}}function Q8(){let $=process.platform==="win32"?"C:\\":"/";return new e4($)}async function D2($,Z,K={}){let X=K.factory??await $8(),Y=K.config??await Z8(),Q=X.createFromConfig(Y);if(!Q){if(!Z.quiet)console.error("Embedding is disabled in configuration. Enable it in ~/.config/memory/config.json");return}let G=K.repositoryOverride??await K8($),{EmbeddingService:_}=await Promise.resolve().then(() => ($9(),j3)),{PatternRedactor:J}=await Promise.resolve().then(() => (z4(),G8)),{createEmbeddingProgressReporter:H,createModelDownloadHandler:V}=await Promise.resolve().then(() => (O9(),y3)),B=new _({repository:G,provider:Q,config:Y.embedding,redactor:new J}),z=B.checkModelState();if(z.modelChanged&&z.needsReEmbed){if(!await _8(z,Z)){await X.dispose();return}let T=G.getStoredEmbeddingDimensions(),U=Y.embedding.dimensions;if(T!==null&&T!==U){if(!Z.quiet)console.log(`Recreating embedding table for ${U}-dimensional vectors...`);G.recreateVecTable(U)}if(!Z.quiet)console.log("Clearing existing embeddings for re-embedding...")}let W=V({quiet:!!Z.quiet});await Q.initialize(W);let N=G.getTotalMessageCount()-G.getEmbeddedCount();if(N===0){if(!Z.quiet)console.log(`
|
|
1235
|
+
All messages already embedded.`);await X.dispose();return}let q=H({quiet:!!Z.quiet});q.start(N);try{let I;if(z.modelChanged&&z.needsReEmbed)I=await B.clearAndReembed({onProgress:(T)=>q.update(T.current)});else I=await B.embedUnembedded({onProgress:(T)=>q.update(T.current)});if(q.stop(),!Z.quiet){let T=Math.max(1,Math.round(I.durationMs/1000)),U=I.rate.toFixed(1);console.log(`
|
|
1236
|
+
Embedded ${I.embedded} messages in ${T}s (${U} msg/s)`)}}catch(I){q.stop();let T=G.getEmbeddedCount(),U=G.getTotalMessageCount();if(!Z.quiet)console.error(`
|
|
1237
|
+
Embedding failed at ${T}/${U} messages. Run memory sync --embed to resume from where it stopped.`);throw I}finally{await X.dispose()}}async function _8($,Z){let K=$.embeddedCount??0,X=$.storedModelName??$.storedHash??"unknown",Y=$.currentModelName;if(Z.force)return!0;if(!process.stdin.isTTY||Z.quiet)return console.error(`Model changed from ${X} to ${Y}. Skipping re-embedding in non-interactive mode. Run 'memory sync --embed' interactively to re-embed.`),!1;let G=(await import("readline")).createInterface({input:process.stdin,output:process.stdout});return new Promise((_)=>{G.question(`Model changed from ${X} to ${Y}. Re-embed all ${K} messages? [y/N] `,(J)=>{G.close(),_(J.trim().toLowerCase()==="y")})})}j9();W4();async function J8($,Z){try{let K=new c4($),X=new $$,Q=await new v4(K,X).syncMemoryFiles();if(Q.filesIndexed>0||Q.filesSkipped>0||Q.errors.length>0)return Q;return null}catch(K){if(!Z.quiet)console.error(` Memory files: error (${A(K)})`);return null}}function H8($,Z){if(Z.json){let K={memoryFiles:{indexed:$.filesIndexed,skipped:$.filesSkipped,errors:$.errors}};console.log(JSON.stringify(K,null,2));return}if(Z.quiet)return;if(console.log(` Memory files: ${$.filesIndexed} indexed, ${$.filesSkipped} skipped`),$.errors.length>0)for(let K of $.errors)console.log(` Error: ${K.filePath}: ${K.error}`)}async function v2($,Z,K){try{let X,Y,Q,G;if(K){if(X=K.loadConfig(),!X.ambientContext.enabled)return;Y=K.resolveAutoMemoryDir(),Q=K.resolveProjectName(),G=K.createAmbientService()}else{let{loadConfig:J}=await Promise.resolve().then(() => (K0(),n4));if(X=J(),!X.ambientContext.enabled)return;let H=process.cwd(),{ProjectPath:V}=await Promise.resolve().then(() => r3),B=V.fromDecoded(H),z=B.encoded;Q=B.projectName;let{homedir:W}=await import("os"),{join:N}=await import("path");Y=N(W(),".claude","projects",z,"memory");let{SqliteProjectResolver:q}=await Promise.resolve().then(() => z5),{SqliteFactRepository:I}=await Promise.resolve().then(() => (q1(),H5)),{SqliteFrictionRepository:T}=await Promise.resolve().then(() => (u4(),_5)),{AutoMemoryWriter:U}=await Promise.resolve().then(() => (N8(),A8)),{SmartContextService:O}=await Promise.resolve().then(() => (w4(),S3)),{AmbientContextService:R}=await Promise.resolve().then(() => v3),{createContextFormatter:M}=await Promise.resolve().then(() => (B$(),yZ)),x=new q($),o=new I($),A0=new T($),N0=M("ai",!1),q0=new O({projectResolver:x,factRepo:o,frictionRepo:A0});G=new R(q0,new U,N0)}let _=await G.generateAmbientContext({projectName:Q,autoMemoryDir:Y,budget:X.ambientContext.budget});if(_.success&&!Z.quiet)console.log(` Ambient context: updated (~${_.contextTokens} tokens)`);else if(!_.success&&!Z.quiet)console.log(` Ambient context: skipped (${_.reason})`)}catch(X){if(!Z.quiet)console.error(` Ambient context: error (${A(X)})`)}}K0();z4();function lK({db:$,resolver:Z}){let K=new c0({projectNameResolver:Z}),X=new Z$,Y=new g($),Q=new G0($),G=new f0($),_=new b0($),J=new D4(K,X,Y,Q,G,_,$,new Y$,new Q$,new l0);return{fixProjectNames:(H)=>J.fixProjectNames(H),sync:(H)=>J.sync(H)}}async function nK($){await(await rK())($)}function aK($){return{handleBackgroundMode:x2,setupSignalHandlers:KZ,hasCheckpoint:s5,loadCheckpoint:E1,createProgressReporter:z9,getDefaultDbPath:P,executeDryRun:X8,handleError:P2,reportResults:Y8,createDriveResolver:Q8,initializeDatabase:S,closeDatabase:D,bulkOperationCheckpoint:m4,registerCleanup:YZ,unregisterCleanup:QZ,createSyncService:lK,loadConfig:h,createGitSyncer:iK,rebuildProjections:nK,experimentalRemoteSync:process.env.MEMORY_EXPERIMENTAL_REMOTE_SYNC==="1",runMemoryFileSync:J8,reportMemoryFileResults:H8,runAmbientContextGeneration:v2,runEmbeddingPass:D2,...$}}function b2(){return new pK("sync").description("Sync sessions from ~/.claude/projects/ to database").option("-f, --force","Re-extract all sessions regardless of state").option("-p, --project <path>","Sync only sessions from specific project").option("-s, --session <id>","Sync a specific session only").option("-n, --dry-run","Show what would be synced without syncing").option("--fix-names","Fix truncated project names in existing sessions").option("--embed","Generate embeddings for messages after sync").option("--background","Run embedding in background (use with --embed)").option("--include-memory-files","Index legacy ~/.memory / MEMORY_HOME markdown files").option("--json","Output results as JSON").addOption(new M8("-q, --quiet","Suppress progress output").conflicts("verbose")).addOption(new M8("-v, --verbose","Show detailed progress").conflicts("quiet")).action(async($)=>{let Z=await j8($);process.exitCode=Z.exitCode})}async function j8($,Z={}){let K=aK(Z);if($.background)return await K.handleBackgroundMode($);K.setupSignalHandlers();let X=Date.now(),Y=K.createProgressReporter($);if(!$.quiet&&K.hasCheckpoint()){let J=K.loadCheckpoint();if(J)console.log(`Resuming from previous interrupted sync (${J.completedSessions}/${J.totalSessions} sessions done)`)}let Q=K.getDefaultDbPath();if($.dryRun)return await K.executeDryRun($);let G;try{G=K.initializeDatabase({path:Q}).db}catch(J){return K.handleError(J,$),{exitCode:1}}let _=async()=>{K.closeDatabase(G)};K.registerCleanup(_);try{let J=K.createDriveResolver(),H=K.createSyncService({db:G,resolver:J});if($.fixNames){Y.log("Fixing project names...");let U=await H.fixProjectNames(J);if(!$.quiet)console.log(`Fixed project names: ${U} sessions updated`)}let V={force:$.force,projectFilter:$.project,sessionFilter:$.session,checkpointEnabled:!0,onProgress:(U)=>{if(U.phase==="discovering")Y.log("Discovering sessions...");else if(U.phase==="extracting"){if(U.current===1)Y.start(U.total);Y.update(U.current,U.sessionId)}}},B=await H.sync(V);K.bulkOperationCheckpoint(G),Y.stop(),K.reportResults(B,X,$);let z=K.loadConfig(),W=z.remoteSync?.repositoryUrl,N=z.remoteSync?.enabled===!0&&typeof W==="string"&&W.trim().length>0,q=K.experimentalRemoteSync;if(N&&q){if(!$.quiet)console.log("Synchronizing events with remote Git repository...");try{let O=await(await K.createGitSyncer()).sync(z.machineId,W,z.remoteSync.autoPull,z.remoteSync.autoPush);if(O.success){if(O.rebuildNeeded){if(!$.quiet)console.log("Remote events pulled. Rebuilding database projections...");await K.rebuildProjections(G)}else if(!$.quiet)console.log("Git events are already up to date.")}else console.error(`Warning: Remote synchronization failed: ${O.error}`)}catch(U){console.error(`Warning: Remote synchronization failed to execute: ${A(U)}`)}}else if(N&&!$.quiet)console.warn("Remote synchronization is configured but disabled until Phase 38 readiness. Set MEMORY_EXPERIMENTAL_REMOTE_SYNC=1 only for explicit prototype testing.");if($.includeMemoryFiles===!0||z.legacyMemoryFiles?.enabled===!0||process.env.MEMORY_LEGACY_MEMORY_FILES==="1"){let U=await K.runMemoryFileSync(G,$);if(U)K.reportMemoryFileResults(U,$)}else if($.verbose&&!$.quiet)console.log(" Memory files: skipped (legacy opt-in disabled)");if(!$.dryRun)await K.runAmbientContextGeneration(G,$);let T=B.errors.length>0||B.aborted?1:0;if($.embed&&!$.dryRun){let U=process.env.MEMORY_EMBED_BACKGROUND==="1";try{await K.runEmbeddingPass(G,$)}catch(O){if($.json)console.error(K1(g1(O)));else if(!$.quiet)console.error(p(g1(O),{verbose:$.verbose}));return{exitCode:1}}finally{if(U)if(K.removeBackgroundLock)K.removeBackgroundLock();else{let{removeLock:O}=await Promise.resolve().then(() => (O$(),q$));O()}}}return{exitCode:T}}catch(J){return Y.stop(),K.handleError(J,$),{exitCode:1}}finally{K.unregisterCleanup(_),K.closeDatabase(G)}}async function iK(){let{GitSyncer:$}=await Promise.resolve().then(() => (C2(),L8));return new $}async function rK(){let{rebuildProjections:$}=await Promise.resolve().then(() => (w2(),F8));return $}L4();c2();l2();S$();C$();x$();H0();import{Command as wX}from"commander";u0();import kX from"@inquirer/search";import SX from"@inquirer/select";import vX from"fuzzy";var l8=null,CX=null,yX=null;function n8(){if(l8!==null)return l8;return process.stdout.isTTY===!0}function a8(){return n8()}async function i8($){if(!n8())throw Error("Interactive picker requires TTY. Use --session <id> instead.");let{sessionRepo:Z,limit:K=100}=$,Y=(await Z.findFiltered({limit:K})).map((V)=>({value:V.id,name:`${V.projectPath.projectName} (${z0(V.startTime)})`,description:`${V.id.substring(0,8)}... | ${V.messages.length} messages`})),_=await(CX??kX)({message:"Search sessions (type to filter):",source:async(V,{signal:B})=>{if(B.aborted)return[];if(!V)return Y;return vX.filter(V,Y,{extract:(W)=>`${W.name} ${W.description}`}).map((W)=>W.original)},pageSize:10}),H=await(yX??SX)({message:"Action:",choices:[{value:"show",name:"Show session details"},{value:"search",name:"Search within session"},{value:"context",name:"Get project context"},{value:"related",name:"Find related sessions"},{value:"cancel",name:"Cancel"}]});if(H==="cancel")return null;return{sessionId:_,action:H}}M0();x$();L4();S$();C$();c();D0();function bX($){return{dbPath:P(),show:N4,search:I4,context:O4,related:U4,...$}}function i2(){return new wX("browse").description("Interactive session browser").option("-l, --limit <count>","Maximum sessions to show","100").action(async($)=>{let Z=await r8($);process.exitCode=Z.exitCode})}async function r8($,Z={}){if(!a8())return console.error("Error: Interactive mode requires a terminal."),console.error("Use specific commands instead:"),console.error(" memory list - List sessions"),console.error(" memory show <id> - Show session details"),console.error(" memory search <q> - Search sessions"),{exitCode:1};let K=bX(Z),X={limit:"100",...$},Y=parseInt(X.limit,10),Q=K.dbPath,{db:G}=S({path:Q});try{let _=new g(G),J=await i8({sessionRepo:_,limit:Y});if(!J)return D(G),{exitCode:0};switch(D(G),J.action){case"show":await K.show(J.sessionId,{});break;case"search":await K.search("*",{session:J.sessionId});break;case"context":{let{db:H}=S({path:Q}),B=await new g(H).findById(J.sessionId);if(D(H),B)await K.context(B.projectPath.projectName,{});break}case"related":await K.related(J.sessionId,{});break}return{exitCode:0}}catch(_){let J=_ instanceof j?_:new j(F.DB_CONNECTION_FAILED,A(_));console.error(p(J));try{D(G)}catch{}return{exitCode:1}}}Y1();K0();C2();import{Command as fX}from"commander";function r2($={}){let Z=new fX("remote").description("Manage multi-device Git transport synchronization configuration");return Z.command("set <repositoryUrl>").description("Set remote Git repository URL and initialize events log transport repository").action(async(K)=>{let X=await o8(K,$);process.exitCode=X.exitCode}),Z.command("remove").description("Remove remote Git synchronization URL and disable remote sync").action(async()=>{let K=await t8($);process.exitCode=K.exitCode}),Z.command("status").description("View remote Git synchronization status").action(async()=>{let K=await s8($);process.exitCode=K.exitCode}),Z}async function o8($,Z={}){try{let K=Z.loadConfig??h,X=Z.saveConfig??L0,Y=Z.createGitSyncer??((H)=>new k1(H)),Q=K(Z.configPathOverride),G=Y(Z.eventsDirOverride);if(!await G.isGitRepo()){if(console.log("Initializing local Git repository in events directory..."),!await G.initRepo())return console.error("Error: Failed to initialize Git repository locally."),{exitCode:1}}if(console.log(`Configuring remote origin repository URL: ${$}`),!await G.configureRemote($))return console.error("Error: Failed to configure Git remote repository origin."),{exitCode:1};return X({remoteSync:{enabled:!0,repositoryUrl:$,autoPush:Q.remoteSync?.autoPush??!0,autoPull:Q.remoteSync?.autoPull??!0}},Z.configPathOverride),console.log(`
|
|
1238
|
+
Success: Remote synchronization configured successfully!`),console.log("To synchronize your local facts with the remote repository, run: memory sync"),{exitCode:0}}catch(K){return console.error("Error setting remote:",A(K)),{exitCode:1}}}async function t8($={}){try{let Z=$.loadConfig??h,K=$.saveConfig??L0,X=$.createGitSyncer??((_)=>new k1(_)),Y=Z($.configPathOverride);K({remoteSync:{enabled:!1,autoPush:Y.remoteSync?.autoPush??!0,autoPull:Y.remoteSync?.autoPull??!0}},$.configPathOverride);let Q=X($.eventsDirOverride);if(await Q.isGitRepo())console.log("Removing Git remote origin URL..."),await Q.removeRemote();return console.log(`
|
|
1239
|
+
Success: Remote synchronization disabled and origin repository URL removed.`),{exitCode:0}}catch(Z){return console.error("Error removing remote:",A(Z)),{exitCode:1}}}async function s8($={}){try{let Z=$.loadConfig??h,K=$.createGitSyncer??((_)=>new k1(_)),X=Z($.configPathOverride),Y=X.remoteSync;console.log("Remote Sync Status"),console.log("=================="),console.log(`Machine ID: ${X.machineId}`),console.log(`Enabled: ${Y?.enabled?"yes":"no"}`),console.log(`Repository URL: ${Y?.repositoryUrl??"none configured"}`),console.log(`Auto-Pull: ${Y?.autoPull?"enabled":"disabled"}`),console.log(`Auto-Push: ${Y?.autoPush?"enabled":"disabled"}`);let Q=K($.eventsDirOverride),G=await Q.isGitRepo();if(console.log(`Git Repository: ${G?"initialized":"not initialized"}`),G){let _=await Q.getRemoteUrl();console.log(`Actual Git Remote: ${_??"none"}`)}return{exitCode:0}}catch(Z){return console.error("Error gathering remote status:",A(Z)),{exitCode:1}}}F1();import{Command as hX}from"commander";import{copyFileSync as gX,existsSync as e8,mkdirSync as mX}from"fs";import{dirname as cX,join as o2}from"path";function t2(){return new hX("install").description("Install Claude Code hooks for automatic session sync").option("-f, --force","Reinstall even if already installed").action(async($)=>{let Z=await $6($);process.exitCode=Z.exitCode})}async function $6($,Z={}){let K=F0(Z.hookOverrides);if(K.sessionEnd&&K.preCompact&&!$.force)return console.log("Hooks are already installed."),console.log("Use --force to reinstall."),{exitCode:0};let X=a0(Z.hookOverrides);mX(cX(X),{recursive:!0});let Y=dX(Z.hookScriptSourceOverride);if(!Y)return console.error("Error: Hook script not found. Run 'bun run build:hook' first."),{exitCode:1};gX(Y,X),console.log(`Copied hook script to ${X}`);let Q=i0(Z.hookOverrides);if(console.log(Q.message),Q.success)console.log(`
|
|
1240
|
+
Hook installation complete!`),console.log("Sessions will now sync automatically when they end."),console.log(`
|
|
1241
|
+
To check status: memory status`),console.log("To uninstall: memory uninstall"),uX(Z.hookOverrides);else return{exitCode:1};return{exitCode:0}}function uX($){let Z=W1($);if(!Z.hooks)return;let K="memory-nexus",X=!1;for(let Y of Object.values(Z.hooks)){if(!Array.isArray(Y))continue;for(let Q of Y){if(!Q?.hooks)continue;for(let G of Q.hooks)if(G.command?.includes(K)){X=!0;break}if(X)break}if(X)break}if(X)console.error(`
|
|
1242
|
+
Warning: Stale memory-nexus hook references detected in settings.json.`),console.error("Run 'memory uninstall' then 'memory install' to clean up.")}function dX($){if($!==void 0)return e8($)?$:null;let Z=o2(import.meta.dir,"../../../../dist/sync-hook.js"),K=o2(process.cwd(),"dist/sync-hook.js"),X=o2(process.cwd(),"dist","sync-hook.js");return[Z,K,X].find((Q)=>e8(Q))??null}F1();import{Command as pX}from"commander";import{existsSync as lX,unlinkSync as nX}from"fs";function s2(){return new pX("uninstall").description("Remove Claude Code hooks for automatic session sync").option("-r, --restore","Restore settings.json from backup").action(async($)=>{let Z=await Z6($);process.exitCode=Z.exitCode})}async function Z6($,Z={}){let K=F0(Z.hookOverrides);if(!K.sessionEnd&&!K.preCompact)return console.log("Hooks are not installed."),{exitCode:0};if($.restore&&K.backupExists){if(d$(Z.hookOverrides))console.log("Restored settings.json from backup.")}else{let Y=r0(Z.hookOverrides);console.log(Y.message)}let X=a0(Z.hookOverrides);if(lX(X))nX(X),console.log("Removed hook script.");return console.log(`
|
|
1243
|
+
Hooks uninstalled successfully.`),console.log("Sessions will no longer sync automatically."),console.log("Manual sync still available: memory sync"),{exitCode:0}}y1();import{Command as aX}from"commander";y1();l();c();h4();M0();c();l();M$();import{existsSync as e2,readFileSync as iX,unlinkSync as rX}from"fs";import{join as oX}from"path";function tX($){let Z=0;if(!$.database.exists)Z++;if($.database.exists&&!$.database.readable)Z++;if($.database.exists&&!$.database.writable)Z++;if($.database.integrity==="corrupted")Z++;if(!$.permissions.configDir)Z++;if(!$.permissions.logsDir)Z++;if(!$.permissions.sourceDir)Z++;if(Z+=$.config.issues.length,$.llmExtraction&&!$.llmExtraction.ready)Z++;return Z}function $3(){return new aX("doctor").description("Check system health and diagnose issues").option("--json","Output as JSON").option("--fix","Attempt to fix common issues").option("--portability","Perform portability and path-dialect migration checks").action(async($)=>{let Z=await K6($);process.exitCode=Z.exitCode})}async function K6($,Z={}){if($.portability)return eX($,Z);if($.json){let X=await(Z.gatherStatus??(await Promise.resolve().then(() => (y1(),u2))).gatherStatus)({dbPath:Z.healthOverrides?.dbPath,logPath:Z.healthOverrides?.logsDir?b$(Z.healthOverrides.logsDir,"sync.log"):void 0,configPath:Z.healthOverrides?.configDir?b$(Z.healthOverrides.configDir,"config.json"):void 0,hookOverrides:Z.healthOverrides?.hookOverrides,fix:$.fix,stats:!1}),Y={database:X.health.database,permissions:X.health.permissions,hooks:{...X.health.hooks,lastRun:X.health.hooks.lastRun?.toISOString()??null},config:X.health.config,embedding:X.health.embedding,sqliteVec:X.health.sqliteVec,searchCapability:X.health.searchCapability,llmExtraction:X.health.llmExtraction,migration:X.migration,qmd:X.qmd};console.log(JSON.stringify(Y,null,2));let Q=0;if(!X.health.database.exists||X.health.database.integrity==="corrupted")Q=2;else if(tX(X.health)>0||!X.health.searchCapability.vectorReady)Q=1;return{exitCode:Q}}return Q1({db:!0,hooks:!0,config:!0,embedding:!0,all:!0,fix:$.fix,json:$.json},{dbPath:Z.healthOverrides?.dbPath,logPath:Z.healthOverrides?.logsDir?b$(Z.healthOverrides.logsDir,"sync.log"):void 0,configPath:Z.healthOverrides?.configDir?b$(Z.healthOverrides.configDir,"config.json"):void 0,hookOverrides:Z.healthOverrides?.hookOverrides})}function sX($,Z=process.platform){if(Z==="win32")return $.includes("/")&&($.startsWith("/home")||$.startsWith("/mnt")||$.startsWith("/var")||$.startsWith("/usr")||$.startsWith("/"));return $.includes("\\")||/^[a-zA-Z]:/.test($)}async function eX($,Z={}){let K=e2,X=Z.healthOverrides?.dbPath??P(),Y=Z.healthOverrides?.sourceDir??a(),Q=$.json?!1:v(),G,_=[],J=[],H=[];if(!e2(X)){if($.json)console.log(JSON.stringify({error:"Database does not exist. Run 'memory sync' first."},null,2));else console.error(m("Error: Database does not exist. Run 'memory sync' first.",Q));return{exitCode:1}}try{G=S({path:X}).db;let R=await new g(G).findFiltered({limit:1e5});for(let M of R){let x=M.projectPath.decoded;if(sX(x)&&!_.includes(x))_.push(x);let o=w0.resolveExistingPath(x,K);if(!K(o)){if(!J.includes(x))J.push(x)}}}catch(U){let O=A(U);if($.json)console.log(JSON.stringify({error:`Portability scan failed: ${O}`},null,2));else console.error(m(`Portability scan failed: ${O}`,Q));return{exitCode:2}}finally{if(G)D(G)}let V=oX(Y,"embedding.lock"),B=!1,z=!1;if(e2(V)){B=!0;try{let U=iX(V,"utf-8"),O=JSON.parse(U);if(O.pid)process.kill(O.pid,0);else z=!0}catch(U){z=!0}}if(B&&z){if(H.push(V),$.fix)try{rX(V)}catch(U){}}let N=await(Z.gatherStatus??(await Promise.resolve().then(() => (y1(),u2))).gatherStatus)({dbPath:X,fix:!1,stats:!1}),q=N.health.sqliteVec.available,I=N.health.sqliteVec.version;if($.json)return console.log(JSON.stringify({portability:{mixedDialectPaths:_,orphanedPaths:J,staleLocks:H,sqliteVecAvailable:q,sqliteVecVersion:I,fixedStaleLocks:$.fix&&H.length>0}},null,2)),{exitCode:J.length>0||_.length>0||H.length>0&&!$.fix||!q?1:0};if(console.log("Portability & Migration Diagnostics"),console.log("=================================="),console.log(""),_.length===0)console.log(` ${w("[OK]",Q)} Path Dialects: No mixed path slashes/drive dialects detected.`);else{console.log(` ${u("[WARN]",Q)} Path Dialects: ${_.length} mixed slash/drive formats detected.`);for(let U of _)console.log(` - ${U}`)}if(J.length===0)console.log(` ${w("[OK]",Q)} Orphaned Workspaces: All session folders exist physically on disk.`);else{console.log(` ${u("[WARN]",Q)} Orphaned Workspaces: ${J.length} project folder(s) not found on active filesystem.`);for(let U of J)console.log(` - ${U}`)}if(H.length===0)console.log(` ${w("[OK]",Q)} Active Locks: No stale sync/embedding lock files detected.`);else if($.fix)console.log(` ${w("[FIXED]",Q)} Active Locks: Cleaned up ${H.length} stale lock file(s).`);else{console.log(` ${u("[WARN]",Q)} Active Locks: ${H.length} stale sync/embedding lock file(s) found.`);for(let U of H)console.log(` - ${U}`)}if(q)console.log(` ${w("[OK]",Q)} sqlite-vec: Loadable (v${I}) for active architecture.`);else console.log(` ${m("[FAIL]",Q)} sqlite-vec: Not loadable on this system architecture.`);if(console.log(""),J.length>0)console.log("\uD83D\uDCA1 [TIP] Orphaned project paths detected. You can safely prune these stale database records by running: memory purge --orphans"),console.log("");return{exitCode:J.length>0||_.length>0||H.length>0&&!$.fix||!q?1:0}}function b$(...$){if($.some((Z)=>Z===void 0))return;return $.join("/")}M0();c();h4();import{Command as $Y,Option as ZY}from"commander";import*as X6 from"readline";import{existsSync as KY}from"fs";function Z3($){let Z=$.match(/^(\d+)([dmy])$/i);if(!Z)throw Error(`Invalid duration format: "${$}". Use format like "30d" (days), "6m" (months), or "1y" (years).`);let K=parseInt(Z[1],10),X=Z[2].toLowerCase();if(K<=0)throw Error("Duration value must be a positive number.");let Y=new Date,Q;switch(X){case"d":Q=new Date(Y.getTime()-K*24*60*60*1000);break;case"m":Q=new Date(Y.getFullYear(),Y.getMonth()-K,Y.getDate());break;case"y":Q=new Date(Y.getFullYear()-K,Y.getMonth(),Y.getDate());break;default:throw Error(`Unknown duration unit: "${X}"`)}return Q}function T4($){return $.toISOString().split("T")[0]}async function XY($){let Z=X6.createInterface({input:process.stdin,output:process.stdout});return new Promise((K)=>{Z.question($,(X)=>{Z.close(),K(X.toLowerCase()==="y"||X.toLowerCase()==="yes")})})}function K3(){return new $Y("purge").description("Remove old sessions from database").option("--older-than <duration>",'Delete sessions older than duration (e.g., "90d", "6m", "1y")').option("--orphans","Delete orphaned sessions whose project workspaces no longer exist").option("-f, --force","Skip confirmation prompt").option("--dry-run","Show what would be deleted without deleting").option("--json","Output as JSON").addOption(new ZY("-q, --quiet","Minimal output").conflicts("json")).action(async($)=>{let Z=await Y6($);process.exitCode=Z.exitCode})}async function Y6($,Z={}){let K=Z.askConfirmation??XY,X=Z.existsSync??KY,Y=Z.getDefaultDbPath??P,Q=Z.initializeDatabase??S,G=Z.closeDatabase??D,_=Z.createSessionRepository??((B)=>new g(B));if(!$.olderThan&&!$.orphans){if($.json)console.log(JSON.stringify({error:"Please specify either --older-than <duration> or --orphans."},null,2));else console.error("Error: Please specify either --older-than <duration> or --orphans.");return{exitCode:1}}let J;if($.olderThan)try{J=Z3($.olderThan)}catch(B){let z=A(B);if($.json)console.log(JSON.stringify({error:z},null,2));else console.error(`Error: ${z}`);return{exitCode:1}}let H=Z.dbPath??Y(),V;try{V=Q({path:H}).db}catch(B){let z=A(B);if($.json)console.log(JSON.stringify({error:`Database error: ${z}`},null,2));else console.error("Error: Database not found or could not be opened.");return{exitCode:1}}try{let B=_(V),z=new Map;if(J){let q=await B.findOlderThan(J);for(let I of q)z.set(I.id,I)}if($.orphans){let q=await B.findFiltered({limit:1e5});for(let I of q){let T=I.projectPath.decoded,U=w0.resolveExistingPath(T,X);if(!X(U))z.set(I.id,I)}}let W=z.size;if(W===0){if($.json)console.log(JSON.stringify({sessionsDeleted:0,cutoffDate:J?.toISOString()??null,dryRun:$.dryRun??!1,message:J&&!$.orphans?`No sessions older than ${T4(J)}`:"No sessions matched the purge criteria."},null,2));else if(!$.quiet)if(J&&!$.orphans)console.log(`No sessions older than ${T4(J)}.`);else console.log("No sessions matched the purge criteria.");return{exitCode:0}}if($.dryRun){let q=Array.from(z.values());if($.json)console.log(JSON.stringify({sessionsToDelete:W,cutoffDate:J?.toISOString()??null,dryRun:!0,sessions:q.map((I)=>({id:I.id,project:I.projectPath.projectName,startTime:I.startTime.toISOString(),messageCount:I.messageCount}))},null,2));else if($.quiet)console.log(W.toString());else{if(J&&!$.orphans)console.log(`Would delete ${W} session(s) older than ${T4(J)}:
|
|
1244
|
+
`);else console.log(`Would delete ${W} session(s):
|
|
1245
|
+
`);let I=v();for(let T of q){let U=T.id.substring(0,16),O=T.projectPath.projectName,R=T.startTime.toISOString().split("T")[0],M=T.messageCount;if(I)console.log(` \x1B[33m${U}\x1B[0m ${O} ${R} (${M} messages)`);else console.log(` ${U} ${O} ${R} (${M} messages)`)}}return{exitCode:0}}if(!$.force){if(!await K(J&&!$.orphans?`Delete ${W} session(s) older than ${T4(J)}? This cannot be undone. (y/n) `:`Delete ${W} session(s)? This cannot be undone. (y/n) `)){if($.json)console.log(JSON.stringify({cancelled:!0},null,2));else if(!$.quiet)console.log("Purge cancelled.");return{exitCode:0}}}if(V.transaction(()=>{for(let q of z.keys())B.delete(q)}).immediate(),$.json)console.log(JSON.stringify({sessionsDeleted:W,cutoffDate:J?.toISOString()??null,dryRun:!1},null,2));else if($.quiet)console.log(W.toString());else if(J&&!$.orphans)console.log(`Deleted ${W} session(s) older than ${T4(J)}.`);else console.log(`Deleted ${W} session(s).`);return{exitCode:0}}catch(B){let z=A(B);if($.json)console.log(JSON.stringify({error:z},null,2));else console.error(`Error: ${z}`);return{exitCode:2}}finally{if(V)G(V)}}c();l();F1();import{Command as YY}from"commander";import{existsSync as Q6,unlinkSync as QY}from"fs";import{join as GY}from"path";function X3(){return new YY("migrate").description("Migrate database across platform environments").option("--from-windows","Migrate database from native Windows/desktop host").action(async($)=>{let Z=await G6($);process.exitCode=Z.exitCode})}async function G6($,Z={}){let K=v(),X=Z.dbPath??P(),Y=Z.dataDir??a(),Q=Z.uninstallHooks??r0,G=Z.installHooks??i0;if(!Q6(X))return console.error(m(`Error: Database not found at ${X}. Run 'memory sync' first.`,K)),{exitCode:1};let _;try{_=S({path:X}).db;let V=_.prepare("PRAGMA integrity_check").get();if(!V||V.integrity_check!=="ok"){let B=V?.integrity_check??"unknown";throw Error(`Database integrity check failed: ${B}`)}_.prepare("PRAGMA wal_checkpoint(TRUNCATE)").run()}catch(H){let V=A(H);if(console.error(m(`Error during migration: ${V}`,K)),_)D(_);return{exitCode:2}}let J=GY(Y,"embedding.lock");if(Q6(J))try{QY(J),console.log(w("Cleaned up stale embedding lock file.",K))}catch(H){}try{Q(),G(),console.log(w("Successfully re-installed Git hooks natively.",K))}catch(H){let V=A(H);console.log(u(`Warning: Failed to re-install Git hooks: ${V}`,K))}try{let V=await new h0(_).getStats();if(console.log(""),console.log(w("Database migration successful!",K)),console.log("================================="),console.log(`Total sessions: ${V.totalSessions}`),console.log(`Total messages: ${V.totalMessages}`),console.log(""),console.log("Project Breakdown:"),V.projectBreakdown.length===0)console.log(" No projects found.");else for(let B of V.projectBreakdown)console.log(` - ${B.projectName}: ${B.sessionCount} sessions, ${B.messageCount} messages`);console.log("")}catch(H){}finally{D(_)}return{exitCode:0}}c();import{Command as _Y,Option as Y3}from"commander";z4();import{existsSync as _6}from"fs";import{dirname as JY}from"path";function Q3(){return new _Y("export").description("Export database to JSON file for backup").argument("<output-file>","Path to write the JSON backup file").addOption(new Y3("-q, --quiet","Suppress output except the file path").conflicts("json")).addOption(new Y3("--json","Output stats as JSON").conflicts("quiet")).addOption(new Y3("--include-sensitive","Export raw sensitive values without redaction")).action(async($,Z)=>{let K=await J6($,Z);process.exitCode=K.exitCode})}async function J6($,Z={}){let K=JY($);if(K!=="."&&!_6(K))return console.error(`Error: Directory does not exist: ${K}`),{exitCode:1};let X=P();if(!_6(X))return console.error("Error: Database does not exist. Run 'memory sync' first."),{exitCode:1};let{db:Y}=S({path:X});try{let Q=await Z9(Y,$,{includeSensitive:Z.includeSensitive,redactor:new l0});if(Z.json)console.log(JSON.stringify({success:!0,path:$,stats:Q},null,2));else if(Z.quiet)console.log($);else console.log(HY(Q,$));return{exitCode:0}}catch(Q){let G=A(Q);if(Z.json)console.log(JSON.stringify({success:!1,error:G},null,2));else console.error(`Error: ${G}`);return{exitCode:1}}finally{D(Y)}}function HY($,Z){let K=[];return K.push(`Exported ${$.sessions} sessions, ${$.messages} messages to ${Z}`),K.push(""),K.push("Details:"),K.push(` Sessions: ${$.sessions}`),K.push(` Messages: ${$.messages}`),K.push(` Tool uses: ${$.toolUses}`),K.push(` Entities: ${$.entities}`),K.push(` Links: ${$.links}`),K.push(` File size: ${VY($.bytes)}`),K.join(`
|
|
1246
|
+
`)}function VY($){if($===0)return"0 B";let Z=["B","KB","MB","GB"],K=1024,X=Math.floor(Math.log($)/Math.log(K));return`${($/Math.pow(K,X)).toFixed(X>0?1:0)} ${Z[X]}`}c();import{Command as WY,Option as H6}from"commander";import{existsSync as BY}from"fs";function G3(){return new WY("import").description("Import database from JSON backup file").argument("<input-file>","Path to the JSON backup file").option("--clear","Clear existing data before import").option("--force","Skip confirmation when merging with existing data").addOption(new H6("-q, --quiet","Suppress output except errors").conflicts("json")).addOption(new H6("--json","Output stats as JSON").conflicts("quiet")).action(async($,Z)=>{let K=await V6($,Z);process.exitCode=K.exitCode})}async function V6($,Z={}){if(!BY($))return R4("File does not exist",$,Z),{exitCode:1};let K=await k4($);if(!K.valid)return R4(`Invalid backup file: ${K.error}`,$,Z),{exitCode:1};let X=P(),{db:Y}=S({path:X});try{if(X9(Y)&&!Z.clear&&!Z.force){if(!Z.json&&!Z.quiet)console.log("Warning: Database contains existing data."),console.log("Use --clear to replace all data, or --force to merge without prompt.");if(!process.stdout.isTTY)return R4("Cannot merge with existing data in non-interactive mode. Use --clear or --force.",$,Z),{exitCode:1};return R4("Use --clear to replace data or --force to merge",$,Z),{exitCode:1}}let G=await K9(Y,$,{clearExisting:Z.clear});if(Z.json){let _={success:!0,path:$,version:K.version,stats:G,cleared:Z.clear??!1};console.log(JSON.stringify(_,null,2))}else if(Z.quiet);else console.log(zY(G,$,Z.clear??!1));return{exitCode:0}}catch(Q){let G=A(Q);return R4(G,$,Z),{exitCode:1}}finally{D(Y)}}function R4($,Z,K){if(K.json)console.log(JSON.stringify({success:!1,path:Z,error:$},null,2));else console.error(`Error: ${$}`)}function zY($,Z,K){let X=[],Y=K?"Replaced":"Imported";return X.push(`${Y} ${$.sessions} sessions, ${$.messages} messages from ${Z}`),X.push(""),X.push("Details:"),X.push(` Sessions: ${$.sessions}`),X.push(` Messages: ${$.messages}`),X.push(` Tool uses: ${$.toolUses}`),X.push(` Entities: ${$.entities}`),X.push(` Links: ${$.links}`),X.join(`
|
|
1247
|
+
`)}import{Command as AY}from"commander";function NY($){return $==="bash"||$==="zsh"||$==="fish"}function qY(){return`# memory bash completion
|
|
1248
|
+
# Add to ~/.bashrc: eval "$(memory completion bash)"
|
|
1249
|
+
|
|
1250
|
+
_memory_completion() {
|
|
1251
|
+
local cur prev words cword
|
|
1252
|
+
_init_completion || return
|
|
1253
|
+
|
|
1254
|
+
local commands="sync search list stats context related show browse install uninstall status doctor purge export import completion"
|
|
1255
|
+
local search_opts="--limit --project --role --session --after --before --case-sensitive --json --verbose --quiet"
|
|
1256
|
+
local list_opts="--limit --project --after --before --sort --json --verbose --quiet"
|
|
1257
|
+
local stats_opts="--projects --json --verbose --quiet"
|
|
1258
|
+
local context_opts="--limit --json --verbose --quiet"
|
|
1259
|
+
local related_opts="--limit --depth --json --verbose --quiet"
|
|
1260
|
+
local show_opts="--json --verbose --quiet"
|
|
1261
|
+
local browse_opts="--project"
|
|
1262
|
+
local sync_opts="--force --dry-run --verbose --quiet"
|
|
1263
|
+
local install_opts="--force"
|
|
1264
|
+
local uninstall_opts="--restore"
|
|
1265
|
+
local doctor_opts="--json --fix"
|
|
1266
|
+
local purge_opts="--before --dry-run --force --json --verbose --quiet"
|
|
1267
|
+
local export_opts="--json --verbose --quiet --include-sensitive"
|
|
1268
|
+
local import_opts="--force --dry-run --json --verbose --quiet"
|
|
1269
|
+
local completion_opts=""
|
|
1270
|
+
|
|
1271
|
+
case "\${prev}" in
|
|
1272
|
+
memory)
|
|
1273
|
+
COMPREPLY=( $(compgen -W "\${commands}" -- "\${cur}") )
|
|
1274
|
+
return 0
|
|
1275
|
+
;;
|
|
1276
|
+
search)
|
|
1277
|
+
COMPREPLY=( $(compgen -W "\${search_opts}" -- "\${cur}") )
|
|
1278
|
+
return 0
|
|
1279
|
+
;;
|
|
1280
|
+
list)
|
|
1281
|
+
COMPREPLY=( $(compgen -W "\${list_opts}" -- "\${cur}") )
|
|
1282
|
+
return 0
|
|
1283
|
+
;;
|
|
1284
|
+
stats)
|
|
1285
|
+
COMPREPLY=( $(compgen -W "\${stats_opts}" -- "\${cur}") )
|
|
1286
|
+
return 0
|
|
1287
|
+
;;
|
|
1288
|
+
context)
|
|
1289
|
+
COMPREPLY=( $(compgen -W "\${context_opts}" -- "\${cur}") )
|
|
1290
|
+
return 0
|
|
1291
|
+
;;
|
|
1292
|
+
related)
|
|
1293
|
+
COMPREPLY=( $(compgen -W "\${related_opts}" -- "\${cur}") )
|
|
1294
|
+
return 0
|
|
1295
|
+
;;
|
|
1296
|
+
show)
|
|
1297
|
+
COMPREPLY=( $(compgen -W "\${show_opts}" -- "\${cur}") )
|
|
1298
|
+
return 0
|
|
1299
|
+
;;
|
|
1300
|
+
browse)
|
|
1301
|
+
COMPREPLY=( $(compgen -W "\${browse_opts}" -- "\${cur}") )
|
|
1302
|
+
return 0
|
|
1303
|
+
;;
|
|
1304
|
+
sync)
|
|
1305
|
+
COMPREPLY=( $(compgen -W "\${sync_opts}" -- "\${cur}") )
|
|
1306
|
+
return 0
|
|
1307
|
+
;;
|
|
1308
|
+
install)
|
|
1309
|
+
COMPREPLY=( $(compgen -W "\${install_opts}" -- "\${cur}") )
|
|
1310
|
+
return 0
|
|
1311
|
+
;;
|
|
1312
|
+
uninstall)
|
|
1313
|
+
COMPREPLY=( $(compgen -W "\${uninstall_opts}" -- "\${cur}") )
|
|
1314
|
+
return 0
|
|
1315
|
+
;;
|
|
1316
|
+
doctor)
|
|
1317
|
+
COMPREPLY=( $(compgen -W "\${doctor_opts}" -- "\${cur}") )
|
|
1318
|
+
return 0
|
|
1319
|
+
;;
|
|
1320
|
+
purge)
|
|
1321
|
+
COMPREPLY=( $(compgen -W "\${purge_opts}" -- "\${cur}") )
|
|
1322
|
+
return 0
|
|
1323
|
+
;;
|
|
1324
|
+
export)
|
|
1325
|
+
COMPREPLY=( $(compgen -W "\${export_opts}" -- "\${cur}") )
|
|
1326
|
+
return 0
|
|
1327
|
+
;;
|
|
1328
|
+
import)
|
|
1329
|
+
COMPREPLY=( $(compgen -W "\${import_opts}" -- "\${cur}") )
|
|
1330
|
+
return 0
|
|
1331
|
+
;;
|
|
1332
|
+
completion)
|
|
1333
|
+
COMPREPLY=( $(compgen -W "bash zsh fish" -- "\${cur}") )
|
|
1334
|
+
return 0
|
|
1335
|
+
;;
|
|
1336
|
+
--role)
|
|
1337
|
+
COMPREPLY=( $(compgen -W "user assistant" -- "\${cur}") )
|
|
1338
|
+
return 0
|
|
1339
|
+
;;
|
|
1340
|
+
--sort)
|
|
1341
|
+
COMPREPLY=( $(compgen -W "recent oldest largest" -- "\${cur}") )
|
|
1342
|
+
return 0
|
|
1343
|
+
;;
|
|
1344
|
+
esac
|
|
1345
|
+
|
|
1346
|
+
if [[ "\${cur}" == -* ]]; then
|
|
1347
|
+
case "\${words[1]}" in
|
|
1348
|
+
search) COMPREPLY=( $(compgen -W "\${search_opts}" -- "\${cur}") ) ;;
|
|
1349
|
+
list) COMPREPLY=( $(compgen -W "\${list_opts}" -- "\${cur}") ) ;;
|
|
1350
|
+
stats) COMPREPLY=( $(compgen -W "\${stats_opts}" -- "\${cur}") ) ;;
|
|
1351
|
+
context) COMPREPLY=( $(compgen -W "\${context_opts}" -- "\${cur}") ) ;;
|
|
1352
|
+
related) COMPREPLY=( $(compgen -W "\${related_opts}" -- "\${cur}") ) ;;
|
|
1353
|
+
show) COMPREPLY=( $(compgen -W "\${show_opts}" -- "\${cur}") ) ;;
|
|
1354
|
+
browse) COMPREPLY=( $(compgen -W "\${browse_opts}" -- "\${cur}") ) ;;
|
|
1355
|
+
sync) COMPREPLY=( $(compgen -W "\${sync_opts}" -- "\${cur}") ) ;;
|
|
1356
|
+
install) COMPREPLY=( $(compgen -W "\${install_opts}" -- "\${cur}") ) ;;
|
|
1357
|
+
uninstall) COMPREPLY=( $(compgen -W "\${uninstall_opts}" -- "\${cur}") ) ;;
|
|
1358
|
+
doctor) COMPREPLY=( $(compgen -W "\${doctor_opts}" -- "\${cur}") ) ;;
|
|
1359
|
+
purge) COMPREPLY=( $(compgen -W "\${purge_opts}" -- "\${cur}") ) ;;
|
|
1360
|
+
export) COMPREPLY=( $(compgen -W "\${export_opts}" -- "\${cur}") ) ;;
|
|
1361
|
+
import) COMPREPLY=( $(compgen -W "\${import_opts}" -- "\${cur}") ) ;;
|
|
1362
|
+
esac
|
|
1363
|
+
return 0
|
|
1364
|
+
fi
|
|
1365
|
+
|
|
1366
|
+
COMPREPLY=( $(compgen -W "\${commands}" -- "\${cur}") )
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
complete -F _memory_completion memory
|
|
1370
|
+
`}function OY(){return`#compdef memory
|
|
1371
|
+
# memory zsh completion
|
|
1372
|
+
# Add to ~/.zshrc: eval "$(memory completion zsh)"
|
|
1373
|
+
|
|
1374
|
+
_memory() {
|
|
1375
|
+
local -a commands
|
|
1376
|
+
commands=(
|
|
1377
|
+
'sync:Sync Claude Code sessions to database'
|
|
1378
|
+
'search:Search messages across all sessions'
|
|
1379
|
+
'list:List sessions with filtering'
|
|
1380
|
+
'stats:Show database statistics'
|
|
1381
|
+
'context:Get context for a project'
|
|
1382
|
+
'related:Find sessions related to a given session'
|
|
1383
|
+
'show:Show session details and conversation'
|
|
1384
|
+
'browse:Browse and select sessions interactively'
|
|
1385
|
+
'install:Install automatic sync hook'
|
|
1386
|
+
'uninstall:Remove automatic sync hook'
|
|
1387
|
+
'status:Show hook installation status'
|
|
1388
|
+
'doctor:Check system health and diagnose issues'
|
|
1389
|
+
'purge:Remove old sessions from database'
|
|
1390
|
+
'export:Export database to JSON file'
|
|
1391
|
+
'import:Import database from JSON file'
|
|
1392
|
+
'completion:Generate shell completion script'
|
|
1393
|
+
)
|
|
1394
|
+
|
|
1395
|
+
local -a search_opts list_opts stats_opts context_opts related_opts show_opts browse_opts
|
|
1396
|
+
local -a sync_opts install_opts uninstall_opts doctor_opts purge_opts export_opts import_opts completion_shells
|
|
1397
|
+
|
|
1398
|
+
search_opts=(
|
|
1399
|
+
'--limit[Maximum number of results]:number'
|
|
1400
|
+
'--project[Filter by project name]:project'
|
|
1401
|
+
'--role[Filter by message role]:role:(user assistant)'
|
|
1402
|
+
'--session[Filter by session ID]:session'
|
|
1403
|
+
'--after[Filter by start date]:date'
|
|
1404
|
+
'--before[Filter by end date]:date'
|
|
1405
|
+
'--case-sensitive[Enable case-sensitive search]'
|
|
1406
|
+
'--json[Output as JSON]'
|
|
1407
|
+
'--verbose[Show detailed output]'
|
|
1408
|
+
'--quiet[Minimal output]'
|
|
1409
|
+
)
|
|
1410
|
+
|
|
1411
|
+
list_opts=(
|
|
1412
|
+
'--limit[Maximum number of results]:number'
|
|
1413
|
+
'--project[Filter by project name]:project'
|
|
1414
|
+
'--after[Filter by start date]:date'
|
|
1415
|
+
'--before[Filter by end date]:date'
|
|
1416
|
+
'--sort[Sort order]:order:(recent oldest largest)'
|
|
1417
|
+
'--json[Output as JSON]'
|
|
1418
|
+
'--verbose[Show detailed output]'
|
|
1419
|
+
'--quiet[Minimal output]'
|
|
1420
|
+
)
|
|
1421
|
+
|
|
1422
|
+
stats_opts=(
|
|
1423
|
+
'--projects[Number of top projects to show]:number'
|
|
1424
|
+
'--json[Output as JSON]'
|
|
1425
|
+
'--verbose[Show detailed output]'
|
|
1426
|
+
'--quiet[Minimal output]'
|
|
1427
|
+
)
|
|
1428
|
+
|
|
1429
|
+
context_opts=(
|
|
1430
|
+
'--limit[Maximum number of results]:number'
|
|
1431
|
+
'--json[Output as JSON]'
|
|
1432
|
+
'--verbose[Show detailed output]'
|
|
1433
|
+
'--quiet[Minimal output]'
|
|
1434
|
+
)
|
|
1435
|
+
|
|
1436
|
+
related_opts=(
|
|
1437
|
+
'--limit[Maximum number of results]:number'
|
|
1438
|
+
'--depth[Maximum hop depth]:number'
|
|
1439
|
+
'--json[Output as JSON]'
|
|
1440
|
+
'--verbose[Show detailed output]'
|
|
1441
|
+
'--quiet[Minimal output]'
|
|
1442
|
+
)
|
|
1443
|
+
|
|
1444
|
+
show_opts=(
|
|
1445
|
+
'--json[Output as JSON]'
|
|
1446
|
+
'--verbose[Show detailed output]'
|
|
1447
|
+
'--quiet[Minimal output]'
|
|
1448
|
+
)
|
|
1449
|
+
|
|
1450
|
+
browse_opts=(
|
|
1451
|
+
'--project[Filter by project name]:project'
|
|
1452
|
+
)
|
|
1453
|
+
|
|
1454
|
+
sync_opts=(
|
|
1455
|
+
'--force[Force re-sync all sessions]'
|
|
1456
|
+
'--dry-run[Preview changes without syncing]'
|
|
1457
|
+
'--verbose[Show detailed output]'
|
|
1458
|
+
'--quiet[Minimal output]'
|
|
1459
|
+
)
|
|
1460
|
+
|
|
1461
|
+
install_opts=(
|
|
1462
|
+
'--force[Overwrite existing hook]'
|
|
1463
|
+
)
|
|
1464
|
+
|
|
1465
|
+
uninstall_opts=(
|
|
1466
|
+
'--restore[Restore original settings backup]'
|
|
1467
|
+
)
|
|
1468
|
+
|
|
1469
|
+
doctor_opts=(
|
|
1470
|
+
'--json[Output as JSON]'
|
|
1471
|
+
'--fix[Attempt to fix common issues]'
|
|
1472
|
+
)
|
|
1473
|
+
|
|
1474
|
+
purge_opts=(
|
|
1475
|
+
'--before[Delete sessions before date]:date'
|
|
1476
|
+
'--dry-run[Preview deletions without removing]'
|
|
1477
|
+
'--force[Skip confirmation prompt]'
|
|
1478
|
+
'--json[Output as JSON]'
|
|
1479
|
+
'--verbose[Show detailed output]'
|
|
1480
|
+
'--quiet[Minimal output]'
|
|
1481
|
+
)
|
|
1482
|
+
|
|
1483
|
+
export_opts=(
|
|
1484
|
+
'--json[Output as JSON]'
|
|
1485
|
+
'--verbose[Show detailed output]'
|
|
1486
|
+
'--quiet[Minimal output]'
|
|
1487
|
+
'--include-sensitive[Export raw sensitive values without redaction]'
|
|
1488
|
+
)
|
|
1489
|
+
|
|
1490
|
+
import_opts=(
|
|
1491
|
+
'--force[Overwrite existing data]'
|
|
1492
|
+
'--dry-run[Preview import without changes]'
|
|
1493
|
+
'--json[Output as JSON]'
|
|
1494
|
+
'--verbose[Show detailed output]'
|
|
1495
|
+
'--quiet[Minimal output]'
|
|
1496
|
+
)
|
|
1497
|
+
|
|
1498
|
+
completion_shells=(bash zsh fish)
|
|
1499
|
+
|
|
1500
|
+
_arguments -C \\
|
|
1501
|
+
'1:command:->command' \\
|
|
1502
|
+
'*::arg:->args'
|
|
1503
|
+
|
|
1504
|
+
case "$state" in
|
|
1505
|
+
command)
|
|
1506
|
+
_describe 'command' commands
|
|
1507
|
+
;;
|
|
1508
|
+
args)
|
|
1509
|
+
case "$words[1]" in
|
|
1510
|
+
search) _arguments "$search_opts[@]" ':query:' ;;
|
|
1511
|
+
list) _arguments "$list_opts[@]" ;;
|
|
1512
|
+
stats) _arguments "$stats_opts[@]" ;;
|
|
1513
|
+
context) _arguments "$context_opts[@]" ':project:' ;;
|
|
1514
|
+
related) _arguments "$related_opts[@]" ':session:' ;;
|
|
1515
|
+
show) _arguments "$show_opts[@]" ':session:' ;;
|
|
1516
|
+
browse) _arguments "$browse_opts[@]" ;;
|
|
1517
|
+
sync) _arguments "$sync_opts[@]" ;;
|
|
1518
|
+
install) _arguments "$install_opts[@]" ;;
|
|
1519
|
+
uninstall) _arguments "$uninstall_opts[@]" ;;
|
|
1520
|
+
doctor) _arguments "$doctor_opts[@]" ;;
|
|
1521
|
+
purge) _arguments "$purge_opts[@]" ;;
|
|
1522
|
+
export) _arguments "$export_opts[@]" ':output-file:_files' ;;
|
|
1523
|
+
import) _arguments "$import_opts[@]" ':input-file:_files' ;;
|
|
1524
|
+
completion) _arguments '1:shell:(bash zsh fish)' ;;
|
|
1525
|
+
esac
|
|
1526
|
+
;;
|
|
1527
|
+
esac
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
_memory "$@"
|
|
1531
|
+
`}function UY(){return`# memory fish completion
|
|
1532
|
+
# Save to ~/.config/fish/completions/memory.fish:
|
|
1533
|
+
# memory completion fish > ~/.config/fish/completions/memory.fish
|
|
1534
|
+
|
|
1535
|
+
# Disable file completion by default
|
|
1536
|
+
complete -c memory -f
|
|
1537
|
+
|
|
1538
|
+
# Commands
|
|
1539
|
+
complete -c memory -n "__fish_use_subcommand" -a sync -d "Sync Claude Code sessions to database"
|
|
1540
|
+
complete -c memory -n "__fish_use_subcommand" -a search -d "Search messages across all sessions"
|
|
1541
|
+
complete -c memory -n "__fish_use_subcommand" -a list -d "List sessions with filtering"
|
|
1542
|
+
complete -c memory -n "__fish_use_subcommand" -a stats -d "Show database statistics"
|
|
1543
|
+
complete -c memory -n "__fish_use_subcommand" -a context -d "Get context for a project"
|
|
1544
|
+
complete -c memory -n "__fish_use_subcommand" -a related -d "Find sessions related to a given session"
|
|
1545
|
+
complete -c memory -n "__fish_use_subcommand" -a show -d "Show session details and conversation"
|
|
1546
|
+
complete -c memory -n "__fish_use_subcommand" -a browse -d "Browse and select sessions interactively"
|
|
1547
|
+
complete -c memory -n "__fish_use_subcommand" -a install -d "Install automatic sync hook"
|
|
1548
|
+
complete -c memory -n "__fish_use_subcommand" -a uninstall -d "Remove automatic sync hook"
|
|
1549
|
+
complete -c memory -n "__fish_use_subcommand" -a status -d "Show hook installation status"
|
|
1550
|
+
complete -c memory -n "__fish_use_subcommand" -a doctor -d "Check system health and diagnose issues"
|
|
1551
|
+
complete -c memory -n "__fish_use_subcommand" -a purge -d "Remove old sessions from database"
|
|
1552
|
+
complete -c memory -n "__fish_use_subcommand" -a export -d "Export database to JSON file"
|
|
1553
|
+
complete -c memory -n "__fish_use_subcommand" -a import -d "Import database from JSON file"
|
|
1554
|
+
complete -c memory -n "__fish_use_subcommand" -a completion -d "Generate shell completion script"
|
|
1555
|
+
|
|
1556
|
+
# search options
|
|
1557
|
+
complete -c memory -n "__fish_seen_subcommand_from search" -l limit -d "Maximum number of results"
|
|
1558
|
+
complete -c memory -n "__fish_seen_subcommand_from search" -l project -d "Filter by project name"
|
|
1559
|
+
complete -c memory -n "__fish_seen_subcommand_from search" -l role -d "Filter by message role" -a "user assistant"
|
|
1560
|
+
complete -c memory -n "__fish_seen_subcommand_from search" -l session -d "Filter by session ID"
|
|
1561
|
+
complete -c memory -n "__fish_seen_subcommand_from search" -l after -d "Filter by start date"
|
|
1562
|
+
complete -c memory -n "__fish_seen_subcommand_from search" -l before -d "Filter by end date"
|
|
1563
|
+
complete -c memory -n "__fish_seen_subcommand_from search" -l case-sensitive -d "Enable case-sensitive search"
|
|
1564
|
+
complete -c memory -n "__fish_seen_subcommand_from search" -l json -d "Output as JSON"
|
|
1565
|
+
complete -c memory -n "__fish_seen_subcommand_from search" -l verbose -d "Show detailed output"
|
|
1566
|
+
complete -c memory -n "__fish_seen_subcommand_from search" -l quiet -d "Minimal output"
|
|
1567
|
+
|
|
1568
|
+
# list options
|
|
1569
|
+
complete -c memory -n "__fish_seen_subcommand_from list" -l limit -d "Maximum number of results"
|
|
1570
|
+
complete -c memory -n "__fish_seen_subcommand_from list" -l project -d "Filter by project name"
|
|
1571
|
+
complete -c memory -n "__fish_seen_subcommand_from list" -l after -d "Filter by start date"
|
|
1572
|
+
complete -c memory -n "__fish_seen_subcommand_from list" -l before -d "Filter by end date"
|
|
1573
|
+
complete -c memory -n "__fish_seen_subcommand_from list" -l sort -d "Sort order" -a "recent oldest largest"
|
|
1574
|
+
complete -c memory -n "__fish_seen_subcommand_from list" -l json -d "Output as JSON"
|
|
1575
|
+
complete -c memory -n "__fish_seen_subcommand_from list" -l verbose -d "Show detailed output"
|
|
1576
|
+
complete -c memory -n "__fish_seen_subcommand_from list" -l quiet -d "Minimal output"
|
|
1577
|
+
|
|
1578
|
+
# stats options
|
|
1579
|
+
complete -c memory -n "__fish_seen_subcommand_from stats" -l projects -d "Number of top projects to show"
|
|
1580
|
+
complete -c memory -n "__fish_seen_subcommand_from stats" -l json -d "Output as JSON"
|
|
1581
|
+
complete -c memory -n "__fish_seen_subcommand_from stats" -l verbose -d "Show detailed output"
|
|
1582
|
+
complete -c memory -n "__fish_seen_subcommand_from stats" -l quiet -d "Minimal output"
|
|
1583
|
+
|
|
1584
|
+
# context options
|
|
1585
|
+
complete -c memory -n "__fish_seen_subcommand_from context" -l limit -d "Maximum number of results"
|
|
1586
|
+
complete -c memory -n "__fish_seen_subcommand_from context" -l json -d "Output as JSON"
|
|
1587
|
+
complete -c memory -n "__fish_seen_subcommand_from context" -l verbose -d "Show detailed output"
|
|
1588
|
+
complete -c memory -n "__fish_seen_subcommand_from context" -l quiet -d "Minimal output"
|
|
1589
|
+
|
|
1590
|
+
# related options
|
|
1591
|
+
complete -c memory -n "__fish_seen_subcommand_from related" -l limit -d "Maximum number of results"
|
|
1592
|
+
complete -c memory -n "__fish_seen_subcommand_from related" -l depth -d "Maximum hop depth"
|
|
1593
|
+
complete -c memory -n "__fish_seen_subcommand_from related" -l json -d "Output as JSON"
|
|
1594
|
+
complete -c memory -n "__fish_seen_subcommand_from related" -l verbose -d "Show detailed output"
|
|
1595
|
+
complete -c memory -n "__fish_seen_subcommand_from related" -l quiet -d "Minimal output"
|
|
1596
|
+
|
|
1597
|
+
# show options
|
|
1598
|
+
complete -c memory -n "__fish_seen_subcommand_from show" -l json -d "Output as JSON"
|
|
1599
|
+
complete -c memory -n "__fish_seen_subcommand_from show" -l verbose -d "Show detailed output"
|
|
1600
|
+
complete -c memory -n "__fish_seen_subcommand_from show" -l quiet -d "Minimal output"
|
|
1601
|
+
|
|
1602
|
+
# browse options
|
|
1603
|
+
complete -c memory -n "__fish_seen_subcommand_from browse" -l project -d "Filter by project name"
|
|
1604
|
+
|
|
1605
|
+
# sync options
|
|
1606
|
+
complete -c memory -n "__fish_seen_subcommand_from sync" -l force -d "Force re-sync all sessions"
|
|
1607
|
+
complete -c memory -n "__fish_seen_subcommand_from sync" -l dry-run -d "Preview changes without syncing"
|
|
1608
|
+
complete -c memory -n "__fish_seen_subcommand_from sync" -l verbose -d "Show detailed output"
|
|
1609
|
+
complete -c memory -n "__fish_seen_subcommand_from sync" -l quiet -d "Minimal output"
|
|
1610
|
+
|
|
1611
|
+
# install options
|
|
1612
|
+
complete -c memory -n "__fish_seen_subcommand_from install" -l force -d "Overwrite existing hook"
|
|
1613
|
+
|
|
1614
|
+
# uninstall options
|
|
1615
|
+
complete -c memory -n "__fish_seen_subcommand_from uninstall" -l restore -d "Restore original settings backup"
|
|
1616
|
+
|
|
1617
|
+
# doctor options
|
|
1618
|
+
complete -c memory -n "__fish_seen_subcommand_from doctor" -l json -d "Output as JSON"
|
|
1619
|
+
complete -c memory -n "__fish_seen_subcommand_from doctor" -l fix -d "Attempt to fix common issues"
|
|
1620
|
+
|
|
1621
|
+
# purge options
|
|
1622
|
+
complete -c memory -n "__fish_seen_subcommand_from purge" -l before -d "Delete sessions before date"
|
|
1623
|
+
complete -c memory -n "__fish_seen_subcommand_from purge" -l dry-run -d "Preview deletions without removing"
|
|
1624
|
+
complete -c memory -n "__fish_seen_subcommand_from purge" -l force -d "Skip confirmation prompt"
|
|
1625
|
+
complete -c memory -n "__fish_seen_subcommand_from purge" -l json -d "Output as JSON"
|
|
1626
|
+
complete -c memory -n "__fish_seen_subcommand_from purge" -l verbose -d "Show detailed output"
|
|
1627
|
+
complete -c memory -n "__fish_seen_subcommand_from purge" -l quiet -d "Minimal output"
|
|
1628
|
+
|
|
1629
|
+
# export options
|
|
1630
|
+
complete -c memory -n "__fish_seen_subcommand_from export" -l json -d "Output as JSON"
|
|
1631
|
+
complete -c memory -n "__fish_seen_subcommand_from export" -l verbose -d "Show detailed output"
|
|
1632
|
+
complete -c memory -n "__fish_seen_subcommand_from export" -l quiet -d "Minimal output"
|
|
1633
|
+
complete -c memory -n "__fish_seen_subcommand_from export" -l include-sensitive -d "Export raw sensitive values without redaction"
|
|
1634
|
+
|
|
1635
|
+
# import options
|
|
1636
|
+
complete -c memory -n "__fish_seen_subcommand_from import" -l force -d "Overwrite existing data"
|
|
1637
|
+
complete -c memory -n "__fish_seen_subcommand_from import" -l dry-run -d "Preview import without changes"
|
|
1638
|
+
complete -c memory -n "__fish_seen_subcommand_from import" -l json -d "Output as JSON"
|
|
1639
|
+
complete -c memory -n "__fish_seen_subcommand_from import" -l verbose -d "Show detailed output"
|
|
1640
|
+
complete -c memory -n "__fish_seen_subcommand_from import" -l quiet -d "Minimal output"
|
|
1641
|
+
|
|
1642
|
+
# completion shells
|
|
1643
|
+
complete -c memory -n "__fish_seen_subcommand_from completion" -a "bash zsh fish"
|
|
1644
|
+
`}function LY($){switch($){case"bash":return qY();case"zsh":return OY();case"fish":return UY();default:throw Error(`Unknown shell type: ${$}`)}}function _3(){return new AY("completion").description("Generate shell completion script").argument("<shell>","Shell type (bash, zsh, or fish)").addHelpText("after",`
|
|
1645
|
+
Usage:
|
|
1646
|
+
# Bash (add to ~/.bashrc)
|
|
1647
|
+
eval "$(memory completion bash)"
|
|
1648
|
+
|
|
1649
|
+
# Zsh (add to ~/.zshrc)
|
|
1650
|
+
eval "$(memory completion zsh)"
|
|
1651
|
+
|
|
1652
|
+
# Fish (save to completions directory)
|
|
1653
|
+
memory completion fish > ~/.config/fish/completions/memory.fish
|
|
1654
|
+
`).action((Z)=>{let K=W6(Z);process.exitCode=K.exitCode})}function W6($){if(!NY($))return console.error(`Error: Invalid shell type '${$}'`),console.error("Valid shells: bash, zsh, fish"),{exitCode:1};let Z=LY($);return console.log(Z),{exitCode:0}}H0();c();import{Command as G1,Option as jY}from"commander";import{join as xY}from"path";import{homedir as EY}from"os";D0();async function B6($,Z){if(!Z.description)return console.error("Error: description is required for log action"),{exitCode:1};let K=await $.log({description:Z.description,severity:Z.severity,category:Z.category,tool:Z.tool,context:Z.context,sourceProject:Z.source});if(Z.json)console.log(JSON.stringify({id:K.id,description:K.description,severity:K.severity,category:K.category,tool:K.tool,status:K.status,loggedAt:K.loggedAt.toISOString(),context:K.context??null,sourceProject:K.sourceProject??null}));else console.log(`Logged friction #${K.id} (${K.severity}/${K.category})`);return{exitCode:0}}async function z6($,Z){let K=Z.limit?parseInt(Z.limit,10):void 0,X=await $.list({all:Z.all,status:Z.status,category:Z.category,tool:Z.tool,limit:K});if(Z.json)console.log(JSON.stringify(X.map((Y)=>({id:Y.id,description:Y.description,severity:Y.severity,category:Y.category,tool:Y.tool,status:Y.status,loggedAt:Y.loggedAt.toISOString(),resolvedAt:Y.resolvedAt?.toISOString()??null,resolution:Y.resolution??null,context:Y.context??null,sourceProject:Y.sourceProject??null,lastReviewedAt:Y.lastReviewedAt?.toISOString()??null}))));else if(X.length===0)console.log(Z.all?"No friction entries found.":"No open friction entries.");else{console.log(`${"".padEnd(5)}${"ID".padEnd(6)}${"Severity".padEnd(10)}${"Category".padEnd(14)}${"Description".padEnd(62)}Age`),console.log("-".repeat(101));let Y=0,Q={};for(let H of X){let V=!H.lastReviewedAt||H.lastReviewedAt<H.loggedAt;if(V)Y++;Q[H.severity]=(Q[H.severity]??0)+1;let B=V?"[NEW]":" ",z=H.description.length>60?H.description.slice(0,57)+"...":H.description,W=Date.now()-H.loggedAt.getTime(),N=Math.floor(W/86400000),q=N===0?"today":`${N}d`;console.log(`${B}${String(H.id).padEnd(6)}${H.severity.padEnd(10)}${H.category.padEnd(14)}${z.padEnd(62)}${q}`)}let G=Object.entries(Q).map(([H,V])=>`${V} ${H}`).join(", "),_=Z.tool?` for ${Z.tool}`:"",J=Y>0?` -- ${Y} new since last review`:"";console.log(`
|
|
1655
|
+
${X.length} ${Z.all?"total":"open"} entries${_} (${G})${J}`)}if(Z.tool)await $.markReviewed(Z.tool);return{exitCode:0}}async function A6($,Z){if(!Z.id||!Z.resolution)return console.error("Error: id and --resolution are required for resolve action"),{exitCode:1};let K=parseInt(Z.id,10);if(isNaN(K))return console.error("Error: id must be a number"),{exitCode:1};if(await $.resolve(K,Z.resolution),Z.json)console.log(JSON.stringify({id:K,status:"resolved",resolution:Z.resolution}));else console.log(`Resolved friction #${K}`);return{exitCode:0}}async function N6($,Z){if(!Z.id||!Z.resolution)return console.error("Error: id and --resolution are required for wont-fix action"),{exitCode:1};let K=parseInt(Z.id,10);if(isNaN(K))return console.error("Error: id must be a number"),{exitCode:1};if(await $.wontFix(K,Z.resolution),Z.json)console.log(JSON.stringify({id:K,status:"wont-fix",resolution:Z.resolution}));else console.log(`Marked friction #${K} as won't fix`);return{exitCode:0}}import{exec as IY}from"child_process";import{mkdirSync as TY,writeFileSync as RY}from"fs";import{join as FY}from"path";import{platform as q6}from"os";P0();l();async function O6($,Z,K=MY){let X=await $.getStats(),Y=await $.getWeeklyTrends(12),Q=await $.list({tool:Z.tool}),G=await $.detectPatterns();if(Z.html){let _=R2(X,Y,Q,G),J=c1();TY(J,{recursive:!0});let H=FY(J,"dashboard.html");if(RY(H,_,"utf-8"),!Z.json)console.log(`Dashboard written to ${H}`),K(H)}else if(Z.json)console.log(JSON.stringify({stats:X,trends:Y,patterns:G},null,2));else{let _=T2(X,Y,Q,v(),G);if(Z.format==="ai")_=r(_);console.log(_)}return{exitCode:0}}function MY($){let Z=q6()==="win32"?"start":q6()==="darwin"?"open":"xdg-open";IY(`${Z} "${$}"`)}async function U6($,Z){if(!Z.pattern)return console.error("Error: pattern is required for purge action"),{exitCode:1};if(Z.dryRun){let Y=(await $.list({all:!0})).filter((Q)=>{return new RegExp("^"+Z.pattern.replace(/%/g,".*").replace(/_/g,".")+"$").test(Q.description)});if(Y.length===0)if(Z.json)console.log(JSON.stringify({wouldDelete:0,pattern:Z.pattern}));else console.log(`No entries match pattern: "${Z.pattern}"`);else if(Z.json)console.log(JSON.stringify({wouldDelete:Y.length,pattern:Z.pattern}));else{console.log(`Would delete ${Y.length} entries matching "${Z.pattern}":`);for(let Q of Y.slice(0,10))console.log(` #${Q.id}: ${Q.description}`);if(Y.length>10)console.log(` ... and ${Y.length-10} more`)}return{exitCode:0}}if(!Z.force)return console.error(`Use --dry-run to preview or --force to delete entries matching "${Z.pattern}".`),{exitCode:1};let K=await $.purge(Z.pattern);if(K===0)if(Z.json)console.log(JSON.stringify({deleted:0,pattern:Z.pattern}));else console.log(`No entries match pattern: "${Z.pattern}"`);else if(Z.json)console.log(JSON.stringify({deleted:K,pattern:Z.pattern}));else console.log(`Purged ${K} friction entries matching "${Z.pattern}"`);return{exitCode:0}}function J3(){let $=new G1("friction").description("Log and track friction with memory tool").addOption(new jY("--format <type>","Output format").choices(["default","ai"]).default("default"));return $.addCommand(new G1("log").description("Log a friction entry").argument("<description>","What went wrong").option("--severity <level>","low|medium|high|critical","medium").option("--category <cat>","search|sync|cli|context|integration|ux","cli").option("--tool <name>","Tool that had friction (e.g., aidev, memory, gsd)").option("--source <project>","Source project name").option("--context <ctx>","Additional context").option("--json","Output as JSON").action(async(Z,K)=>{let X=await _1({action:"log",description:Z,...K});process.exitCode=X.exitCode})),$.addCommand(new G1("list").description("List friction entries").option("--all","Include resolved and won't-fix entries").option("--status <status>","Filter by status").option("--category <cat>","Filter by category").option("--tool <name>","Filter by tool name").option("--limit <n>","Maximum entries","50").option("--json","Output as JSON").action(async(Z)=>{let K=await _1({action:"list",...Z});process.exitCode=K.exitCode})),$.addCommand(new G1("resolve").description("Resolve a friction entry").argument("<id>","Friction entry ID").requiredOption("--resolution <text>","How it was resolved").option("--json","Output as JSON").action(async(Z,K)=>{let X=await _1({action:"resolve",id:Z,...K});process.exitCode=X.exitCode})),$.addCommand(new G1("wont-fix").description("Mark a friction entry as won't fix").argument("<id>","Friction entry ID").requiredOption("--resolution <text>","Why it won't be fixed").option("--json","Output as JSON").action(async(Z,K)=>{let X=await _1({action:"wont-fix",id:Z,...K});process.exitCode=X.exitCode})),$.addCommand(new G1("dashboard").description("Show friction dashboard").option("--html","Generate HTML report").option("--tool <name>","Filter by tool name").option("--json","Output as JSON").action(async(Z)=>{let K=await _1({action:"dashboard",...Z});process.exitCode=K.exitCode})),$.addCommand(new G1("purge").description("Delete friction entries by description pattern").argument("<pattern>","Description pattern (SQL LIKE: % for wildcard)").option("--dry-run","Preview matches without deleting").option("-f, --force","Skip confirmation").option("--json","Output as JSON").action(async(Z,K)=>{let X=await _1({action:"purge",pattern:Z,...K});process.exitCode=X.exitCode})),$}async function _1($,Z={}){let K;try{let X=Z.dbPath??P();K=S({path:X}).db;let Y=new x0(K),Q=new y4(Y),G=xY(EY(),".claude","friction.jsonl"),_=await Q.ingestFallbackFile(G);if(_>0)process.stderr.write(`Ingested ${_} friction entries from fallback file
|
|
1656
|
+
`);switch($.action){case"log":return await B6(Q,$);case"list":return await z6(Q,$);case"resolve":return await A6(Q,$);case"wont-fix":return await N6(Q,$);case"dashboard":return await O6(Q,$,Z.openInBrowser);case"purge":return await U6(Q,$);default:return console.error(`Unknown friction action: ${$.action}`),{exitCode:1}}}catch(X){let Y=X instanceof j?X:new j(F.UNKNOWN,A(X));if($.json)console.log(K1(Y));else console.error(p(Y));return{exitCode:1}}finally{if(K)D(K)}}import{Command as DY}from"commander";import{createInterface as kY}from"readline";import{existsSync as SY,mkdirSync as vY,appendFileSync as CY,writeFileSync as yY}from"fs";import{join as wY,dirname as bY}from"path";class R6{memoryDir;constructor($){this.memoryDir=$}async writeOrAppend($,Z){let K=wY(this.memoryDir,$),X=bY(K);vY(X,{recursive:!0});let Y=SY(K);if(Y)CY(K,`
|
|
1657
|
+
`+Z);else yY(K,Z);return!Y}}async function F6($,Z,K={}){let X=parseInt($.batch,10),Y=$.project;if($.dryRun){let H=await Z.dryRun({project:Y});if(H.unprocessedCount===0)return console.log("No sessions to backfill. All sessions have been processed."),{exitCode:0};return console.log(`${H.unprocessedCount} sessions to backfill. Estimated cost: ~$${H.estimatedCost.toFixed(2)}`),{exitCode:0}}let Q=await Z.dryRun({project:Y});if(Q.unprocessedCount===0)return console.log("No sessions to backfill. All sessions have been processed."),{exitCode:0};let G=Math.min(Q.unprocessedCount,X);if(!$.force){if(!await(K.confirm??fY)(`Process ${G} sessions? Estimated cost: ~$${(G*0.001).toFixed(2)} [y/N] `))return console.error("Cancelled."),{exitCode:0}}let _=null;try{if(K.createProgressBar)_=await K.createProgressBar(G);else if(process.stderr.isTTY){let H=await import("cli-progress"),V=new H.default.SingleBar({format:"Backfill |{bar}| {percentage}% | {value}/{total} sessions | {sessionId}",hideCursor:!0,stream:process.stderr},H.default.Presets.shades_classic);V.start(G,0,{sessionId:""}),_=V}}catch{}let J=await Z.backfill({batch:X,project:Y,onProgress:(H)=>{_?.update(H.current,{sessionId:H.sessionId.slice(0,8)})}});if(_?.stop(),console.log(`
|
|
1658
|
+
Backfill complete: ${J.sessionsProcessed} processed, ${J.sessionsFailed} failed, ${J.sessionsSkipped} skipped`),J.dailyLogsCreated>0||J.dailyLogsUpdated>0)console.log(`Daily logs: ${J.dailyLogsCreated} created, ${J.dailyLogsUpdated} updated`);if(J.errors.length>0){console.error(`
|
|
1659
|
+
Errors:`);for(let H of J.errors)console.error(` ${H.sessionId}: ${H.error}`)}return{exitCode:0}}function H3(){return new DY("backfill").description("Generate daily log entries from historical sessions via claude -p").option("--dry-run","Show session count and estimated cost without processing").option("--project <name>","Only backfill sessions for one project").option("--batch <n>","Process N sessions per run (default: 50)","50").option("-f, --force","Skip confirmation prompt").option("--write-memory-files","Write legacy ~/.memory / MEMORY_HOME daily log files").action(async($)=>{let{initializeDatabase:Z,closeDatabase:K}=await Promise.resolve().then(() => (c(),r9)),{SqliteSessionRepository:X}=await Promise.resolve().then(() => (M0(),Z5)),{SqliteMessageRepository:Y}=await Promise.resolve().then(() => (A1(),K5)),{SqliteBackfillStateRepository:Q}=await Promise.resolve().then(() => (x9(),J5)),{ClaudeSummaryGenerator:G}=await Promise.resolve().then(() => (T6(),I6)),{getMemoryDir:_}=await Promise.resolve().then(() => (l(),N3)),{BackfillService:J}=await Promise.resolve().then(() => (G9(),k3)),{getDefaultDbPath:H}=await Promise.resolve().then(() => (c(),r9)),{loadConfig:V}=await Promise.resolve().then(() => (K0(),n4)),B=V(),z=$.writeMemoryFiles===!0||B.legacyMemoryFiles?.enabled===!0||process.env.MEMORY_LEGACY_MEMORY_FILES==="1";if(!$.dryRun&&!z){console.error("Legacy memory-file backfill is disabled by default. Re-run with --write-memory-files or set legacyMemoryFiles.enabled=true to write ~/.memory / MEMORY_HOME daily logs."),process.exitCode=1;return}let W=H(),q=Z({path:W}).db;try{let I=new X(q),T=new Y(q),U=new Q(q),O=new G,R=_(),M=new R6(R),x=new J(I,T,U,O,M),o=await F6($,x);process.exitCode=o.exitCode}finally{K(q)}})}async function fY($){return new Promise((Z)=>{let K=kY({input:process.stdin,output:process.stderr});K.question($,(X)=>{K.close(),Z(X.toLowerCase()==="y"||X.toLowerCase()==="yes")})})}c();q1();M0();A1();K0();import{Command as gY}from"commander";Z4();w2();o1();var hY={redactText:($)=>({text:$,findings:[]}),redactJson:($)=>({value:$,findings:[]})};class V3{db;factRepo;logRepo;messageRepo;extractionProvider;embeddingProvider;eventLogPath;redactor;constructor($,Z,K,X,Y,Q,G,_=hY){this.db=$;this.factRepo=Z;this.logRepo=K;this.messageRepo=X;this.extractionProvider=Y;this.embeddingProvider=Q;this.eventLogPath=G;this.redactor=_}async extractFromSession($,Z,K){if(await this.logRepo.findById($)&&!K?.force)return{skippedSession:!0,added:0,updated:0,superseded:0,skipped:0};let Y=await this.messageRepo.findBySession($);if(Y.length===0)return{skippedSession:!1,added:0,updated:0,superseded:0,skipped:0};let Q=Y.map((I)=>J0.create({id:I.id,role:I.role,content:this.redactor.redactText(I.content).text,timestamp:I.timestamp,toolUseIds:I.toolUses})),G=(await this.extractionProvider.extract(Q)).map((I)=>({...I,content:this.redactor.redactText(I.content).text,metadata:this.redactor.redactJson(I.metadata).value}));if(G.length===0)return await this.logRepo.save({sessionId:$,mode:"manual",factsAdded:0,factsUpdated:0,factsSuperseded:0,factsSkipped:0,provider:this.extractionProvider.providerId,model:this.extractionProvider.modelName,tokensConsumed:0,extractedAt:new Date}),{skippedSession:!1,added:0,updated:0,superseded:0,skipped:0};let J=(await this.factRepo.findByProject(Z)).filter((I)=>I.supersededAt===null),H=Boolean(this.embeddingProvider&&this.embeddingProvider.isReady()),V=[],B=[];if(H&&this.embeddingProvider)try{V=(await this.embeddingProvider.embedBatch(J.map((U)=>U.content))).map((U)=>U.embedding),B=(await this.embeddingProvider.embedBatch(G.map((U)=>U.content))).map((U)=>U.embedding)}catch(I){console.warn("Failed to generate vector embeddings during extraction comparison, falling back to Jaccard:",I)}let z=0,W=0,N=0,q=0;for(let I=0;I<G.length;I++){let T=G[I];if(!T)continue;let U=0,O=null;for(let R=0;R<J.length;R++){let M=J[R];if(!M)continue;let x=0;if(T.content.trim().toLowerCase()===M.content.trim().toLowerCase())x=1;else{let o=B[I],A0=V[R];if(H&&o&&A0)x=this.cosineSimilarity(o,A0);else x=this.jaccardWordSimilarity(T.content,M.content)}if(x>U)U=x,O=M}if(U>=0.95||O&&T.content.trim().toLowerCase()===O.content.trim().toLowerCase())q++;else if(U>=0.85&&O){z++,W++,N++;let R=Z0.create({type:T.type,project:Z,content:T.content,metadata:{confidence:T.confidence,...T.metadata},observedAt:new Date});await A4(R,this.eventLogPath);let M=Z0.create({type:"supersedence",project:Z,content:`Superseded ${O.uuid} by ${R.uuid}`,metadata:{superseded_uuid:O.uuid,superseded_by_uuid:R.uuid},observedAt:new Date});await A4(M,this.eventLogPath)}else{z++;let R=Z0.create({type:T.type,project:Z,content:T.content,metadata:{confidence:T.confidence,...T.metadata},observedAt:new Date});await A4(R,this.eventLogPath)}}return await y2(this.db,this.eventLogPath),await this.logRepo.save({sessionId:$,mode:"manual",factsAdded:z,factsUpdated:W,factsSuperseded:N,factsSkipped:q,provider:this.extractionProvider.providerId,model:this.extractionProvider.modelName,tokensConsumed:0,extractedAt:new Date}),{skippedSession:!1,added:z,updated:W,superseded:N,skipped:q}}cosineSimilarity($,Z){let K=0,X=0,Y=0;for(let Q=0;Q<$.length;Q++){let G=$[Q]??0,_=Z[Q]??0;K+=G*_,X+=G*G,Y+=_*_}if(X===0||Y===0)return 0;return K/(Math.sqrt(X)*Math.sqrt(Y))}jaccardWordSimilarity($,Z){let K=(_)=>new Set(_.toLowerCase().replace(/[.,\/#!$%\^&\*;:{}=\-_`~()?"']/g,"").split(/\s+/).filter((J)=>J.length>0)),X=K($),Y=K(Z),Q=new Set([...X].filter((_)=>Y.has(_))),G=new Set([...X,...Y]);if(G.size===0)return 0;return Q.size/G.size}}T0();z4();t4();class M6{current=0;total=0;isTty=process.stdout.isTTY;quiet=!1;constructor($,Z=!1){if(this.total=$,this.quiet=Z,this.quiet)return;if(this.isTty)process.stdout.write(`\rExtracting facts... [0/${$}] \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 0%`);else console.log(`Extracting facts from ${$} sessions...`)}update($){if(this.quiet)return;this.current++;let Z=Math.round(this.current/this.total*100),K=Math.min(10,Math.max(0,Math.floor(Z/10))),X="\u2588".repeat(K)+"\u2591".repeat(10-K);if(this.isTty){let Y=$.length>25?$.substring(0,22)+"...":$;process.stdout.write(`\rExtracting facts... [${this.current}/${this.total}] [${X}] ${Z}% - Session: ${Y}`)}else console.log(`[${this.current}/${this.total}] Processed session: ${$}`)}stop(){if(this.quiet)return;if(this.isTty)process.stdout.write(`
|
|
1660
|
+
`)}}async function mY($){let{EmbeddingProviderFactory:Z}=await Promise.resolve().then(() => (L$(),E2)),X=new Z().create($.embedding);return await X.initialize(),X}function W3(){return new gY("extract").description("Extract facts from session messages using LLM").argument("<project>","Project name or path to process").option("--all","Process all sessions matching this project").option("--since <duration>","Filter sessions by age (e.g. '24h', '7d', '30d')").option("-f, --force","Force extraction even on previously processed sessions").option("--json","Output result as JSON").option("-q, --quiet","Minimal output").action(async($,Z)=>{let K=await j6({project:$,...Z});process.exitCode=K.exitCode})}async function j6($,Z={}){let K=performance.now(),X=Z.dbPath??P(),Y=h(),Q;if(Z.mockExtractor)Q=Z.mockExtractor;else try{Q=m5(Y)}catch(J){let H=A(J);if($.json)C({command:"extract",code:"PROVIDER_INIT_FAILED",message:H});else console.error(`Error: Provider initialization failed: ${H}`);return{exitCode:1}}let G=Z.mockEmbedder;if(!Z.mockEmbedder&&Y.embedding?.enabled)try{G=await(Z.createEmbedder??mY)(Y)}catch(J){}let _;try{_=S({path:X}).db}catch(J){if($.json)C({command:"extract",code:"DB_CONNECTION_FAILED",message:J.message});else console.error(`Error: Database connection failed: ${J.message}`);return{exitCode:1}}try{let J=new E0(_),H=new d4(_),V=new g(_),B=new G0(_),z=await V.findFiltered({projectFilter:$.project,limit:1e4}),W=z;if($.since&&!$.all)try{let M=Z3($.since);W=z.filter((x)=>x.startTime>=M)}catch(M){if($.json)C({command:"extract",code:"INVALID_ARGUMENT",message:M.message});else console.error(`Error: ${M.message}`);return{exitCode:1}}let N=new V3(_,J,H,B,Q,G,Z.eventLogPath,new l0),q=[];for(let M of W)if(!await H.findById(M.id)||$.force)q.push(M);if(q.length===0){if($.json)console.log(JSON.stringify({status:"success",data:{added:0,updated:0,superseded:0,skipped:0},meta:{timing_ms:Math.round(performance.now()-K),sessions_processed:0}},null,2));else if(!$.quiet)console.log("No new sessions to extract for project:",$.project);return{exitCode:0}}let I=new M6(q.length,!!$.quiet||!!$.json),T=0,U=0,O=0,R=0;for(let M of q){let x=await N.extractFromSession(M.id,$.project,$.force?{force:!0}:void 0);T+=x.added,U+=x.updated,O+=x.superseded,R+=x.skipped,I.update(M.id.substring(0,8))}if(I.stop(),$.json)console.log(JSON.stringify({status:"success",data:{added:T,updated:U,superseded:O,skipped:R},meta:{timing_ms:Math.round(performance.now()-K),sessions_processed:q.length}},null,2));else if($.quiet)console.log(`added: ${T}, updated: ${U}, superseded: ${O}, skipped: ${R}`);else{let M=v();console.log(`
|
|
1661
|
+
`+w("==================================================",M)),console.log(w(" Extraction Completed Successfully",M)),console.log(w("==================================================",M)),console.log(`Sessions Processed : ${q.length}`),console.log(`Added : ${T}`),console.log(`Updated : ${U}`),console.log(`Superseded : ${O}`),console.log(`Skipped (Duplicate): ${R}`),console.log(k(`Timing : ${Math.round(performance.now()-K)}ms`,M))}return{exitCode:0}}catch(J){if($.json)console.log(JSON.stringify({status:"error",error:{code:"UNEXPECTED_ERROR",message:J.message}},null,2));else console.error(`Error: Fact extraction pipeline execution failed: ${J.message}`);return{exitCode:2}}finally{D(_)}}c();q1();import{Command as cY}from"commander";function B3(){return new cY("facts").description("View active facts for a project").argument("<project>","Project name or path to view facts for").option("--superseded","Show superseded facts alongside active ones in a timeline").option("--json","Output results as JSON").action(async($,Z)=>{let K=await x6({project:$,...Z});process.exitCode=K.exitCode})}async function x6($,Z={}){let K=Z.dbPath??P(),X;try{X=S({path:K}).db}catch(Y){if($.json)console.log(JSON.stringify({status:"error",error:{code:"DB_CONNECTION_FAILED",message:Y.message}},null,2));else console.error(`Error: Database connection failed: ${Y.message}`);return{exitCode:1}}try{let Q=await new E0(X).findByProject($.project);if($.json){let _=Q;if(!$.superseded)_=Q.filter((J)=>J.supersededAt===null);return console.log(JSON.stringify({status:"success",data:_.map((J)=>({uuid:J.uuid,type:J.type,project:J.project,content:J.content,metadata:J.metadata,observed_at:J.observedAt.toISOString(),superseded_at:J.supersededAt?J.supersededAt.toISOString():null,superseded_by:J.supersededBy}))},null,2)),{exitCode:0}}let G=v();if(!$.superseded){let _=Q.filter((H)=>H.supersededAt===null);if(console.log(`
|
|
1662
|
+
Active Facts for Project: ${$.project}`),console.log("=".repeat(30+$.project.length)),_.length===0)return console.log(k("No active facts found for this project.",G)),{exitCode:0};let J=["decision","learning","preference","friction","observation"];for(let H of J){let V=_.filter((B)=>B.type===H);if(V.length===0)continue;console.log(`
|
|
1663
|
+
${H.toUpperCase()}`);for(let B of V)console.log(` - ${B.content}`)}}else{if(console.log(`
|
|
1664
|
+
Facts History Timeline for Project: ${$.project}`),console.log("=".repeat(35+$.project.length)),Q.length===0)return console.log(k("No facts history found for this project.",G)),{exitCode:0};let _=[...Q].sort((J,H)=>J.observedAt.getTime()-H.observedAt.getTime());for(let J of _){let H=J.observedAt.toISOString().split("T")[0],V=`[${J.type.toUpperCase()}]`;if(J.supersededAt)console.log(`[${H}] ${u(V,G)} (SUPERSEDED) ${J.content}`),console.log(` \u21B3 replaced by ${J.supersededBy} on ${J.supersededAt.toISOString().split("T")[0]}`);else console.log(`[${H}] ${w(V,G)} ${J.content}`)}}return{exitCode:0}}catch(Y){if($.json)console.log(JSON.stringify({status:"error",error:{code:"UNEXPECTED_ERROR",message:Y.message}},null,2));else console.error(`Error: Facts query execution failed: ${Y.message}`);return{exitCode:2}}finally{D(X)}}var b=new uY;b.name("memory").description("Cross-project context persistence for Claude Code sessions").version(z3.version);b.commandsGroup("Query Commands:");b.addCommand(y$());b.addCommand(w$());b.addCommand(k$());b.addCommand(j$());b.addCommand(E$());b.addCommand(v$());b.addCommand(D$());b.addCommand(B3());b.commandsGroup("Data Commands:");b.addCommand(b2());b.addCommand(H3());b.addCommand(Q3());b.addCommand(G3());b.addCommand(K3());b.addCommand(X3());b.addCommand(W3());if(process.env.MEMORY_EXPERIMENTAL_REMOTE_SYNC==="1")b.addCommand(r2());b.commandsGroup("System Commands:");b.addCommand(t2());b.addCommand(s2());b.addCommand(P$());b.addCommand($3());b.addCommand(_3());b.addCommand(i2());b.commandsGroup("Feedback Commands:");b.addCommand(J3());if(import.meta.main){if(T3())R3();b.parse()}export{b as program};
|