Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -41,7 +41,7 @@ async function buildHooks() {
|
||||
|
||||
// Create scripts directory
|
||||
console.log('\n📦 Preparing scripts directory...');
|
||||
const scriptsDir = 'scripts/hooks';
|
||||
const scriptsDir = 'claude-mem/scripts';
|
||||
if (!fs.existsSync(scriptsDir)) {
|
||||
fs.mkdirSync(scriptsDir, { recursive: true });
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/usr/bin/env bun
|
||||
// @bun
|
||||
import{existsSync as O,unlinkSync as U}from"fs";import{Database as N}from"bun:sqlite";import{join as $,dirname as b,basename as g}from"path";import{homedir as J}from"os";import{existsSync as P,mkdirSync as L}from"fs";var W=process.env.CLAUDE_MEM_DATA_DIR||$(J(),".claude-mem"),V=process.env.CLAUDE_CONFIG_DIR||$(J(),".claude"),y=$(W,"archives"),S=$(W,"logs"),l=$(W,"trash"),R=$(W,"backups"),k=$(W,"chroma"),j=$(W,"settings.json"),M=$(W,"claude-mem.db"),A=$(V,"settings.json"),h=$(V,"commands"),I=$(V,"CLAUDE.md");function q(z){return $(W,`worker-${z}.sock`)}function F(z){L(z,{recursive:!0})}class v{db;constructor(){F(W),this.db=new N(M,{create:!0,readwrite:!0}),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON")}getRecentSummaries(z,Q=10){return this.db.query(`
|
||||
SELECT
|
||||
request, investigated, learned, completed, next_steps,
|
||||
files_read, files_edited, notes, created_at
|
||||
FROM session_summaries
|
||||
WHERE project = ?
|
||||
ORDER BY created_at_epoch DESC
|
||||
LIMIT ?
|
||||
`).all(z,Q)}findActiveSDKSession(z){return this.db.query(`
|
||||
SELECT id, sdk_session_id, project
|
||||
FROM sdk_sessions
|
||||
WHERE claude_session_id = ? AND status = 'active'
|
||||
LIMIT 1
|
||||
`).get(z)||null}createSDKSession(z,Q,X){let Z=new Date,Y=Z.getTime();return this.db.query(`
|
||||
INSERT INTO sdk_sessions
|
||||
(claude_session_id, project, user_prompt, started_at, started_at_epoch, status)
|
||||
VALUES (?, ?, ?, ?, ?, 'active')
|
||||
`).run(z,Q,X,Z.toISOString(),Y),this.db.query("SELECT last_insert_rowid() as id").get().id}updateSDKSessionId(z,Q){this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET sdk_session_id = ?
|
||||
WHERE id = ?
|
||||
`).run(Q,z)}storeObservation(z,Q,X,Z){let Y=new Date,K=Y.getTime();this.db.query(`
|
||||
INSERT INTO observations
|
||||
(sdk_session_id, project, text, type, created_at, created_at_epoch)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`).run(z,Q,Z,X,Y.toISOString(),K)}storeSummary(z,Q,X){let Z=new Date,Y=Z.getTime();this.db.query(`
|
||||
INSERT INTO session_summaries
|
||||
(sdk_session_id, project, request, investigated, learned, completed,
|
||||
next_steps, files_read, files_edited, notes, created_at, created_at_epoch)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`).run(z,Q,X.request||null,X.investigated||null,X.learned||null,X.completed||null,X.next_steps||null,X.files_read||null,X.files_edited||null,X.notes||null,Z.toISOString(),Y)}markSessionCompleted(z){let Q=new Date,X=Q.getTime();this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET status = 'completed', completed_at = ?, completed_at_epoch = ?
|
||||
WHERE id = ?
|
||||
`).run(Q.toISOString(),X,z)}markSessionFailed(z){let Q=new Date,X=Q.getTime();this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET status = 'failed', completed_at = ?, completed_at_epoch = ?
|
||||
WHERE id = ?
|
||||
`).run(Q.toISOString(),X,z)}close(){this.db.close()}}function G(z){try{if(console.error("[claude-mem cleanup] Hook fired",{input:z?{session_id:z.session_id,cwd:z.cwd,reason:z.reason}:null}),!z)console.log("No input provided - this script is designed to run as a Claude Code SessionEnd hook"),console.log(`
|
||||
Expected input format:`),console.log(JSON.stringify({session_id:"string",cwd:"string",transcript_path:"string",hook_event_name:"SessionEnd",reason:"exit"},null,2)),process.exit(0);let{session_id:Q,reason:X}=z;console.error("[claude-mem cleanup] Searching for active SDK session",{session_id:Q,reason:X});let Z=new v,Y=Z.findActiveSDKSession(Q);if(!Y)console.error("[claude-mem cleanup] No active SDK session found",{session_id:Q}),Z.close(),console.log('{"continue": true, "suppressOutput": true}'),process.exit(0);console.error("[claude-mem cleanup] Active SDK session found",{session_id:Y.id,sdk_session_id:Y.sdk_session_id,project:Y.project});let K=q(Y.id);try{if(O(K)){console.error("[claude-mem cleanup] Socket file exists, attempting cleanup",{socketPath:K});try{U(K),console.error("[claude-mem cleanup] Socket file removed successfully",{socketPath:K})}catch(B){console.error("[claude-mem cleanup] Failed to remove socket file",{error:B.message,socketPath:K})}}else console.error("[claude-mem cleanup] Socket file does not exist",{socketPath:K})}catch(B){console.error("[claude-mem cleanup] Error during cleanup",{error:B.message,stack:B.stack})}try{Z.markSessionFailed(Y.id),console.error("[claude-mem cleanup] Session marked as failed",{session_id:Y.id,reason:"SessionEnd hook - session terminated without completion"})}catch(B){console.error("[claude-mem cleanup] Failed to mark session as failed",{error:B.message,session_id:Y.id})}Z.close(),console.error("[claude-mem cleanup] Cleanup completed successfully"),console.log('{"continue": true, "suppressOutput": true}'),process.exit(0)}catch(Q){console.error("[claude-mem cleanup] Unexpected error in hook",{error:Q.message,stack:Q.stack,name:Q.name}),console.log('{"continue": true, "suppressOutput": true}'),process.exit(0)}}var x=await Bun.stdin.text();try{let z=x.trim()?JSON.parse(x):void 0;G(z)}catch(z){console.error(`[claude-mem cleanup-hook error: ${z.message}]`),console.log('{"continue": true, "suppressOutput": true}'),process.exit(0)}
|
||||
@@ -1,44 +0,0 @@
|
||||
#!/usr/bin/env bun
|
||||
// @bun
|
||||
import E from"path";import{Database as x}from"bun:sqlite";import{join as K,dirname as H,basename as P}from"path";import{homedir as L}from"os";import{existsSync as T,mkdirSync as U}from"fs";var B=process.env.CLAUDE_MEM_DATA_DIR||K(L(),".claude-mem"),J=process.env.CLAUDE_CONFIG_DIR||K(L(),".claude"),l=K(B,"archives"),A=K(B,"logs"),R=K(B,"trash"),j=K(B,"backups"),_=K(B,"chroma"),k=K(B,"settings.json"),N=K(B,"claude-mem.db"),I=K(J,"settings.json"),h=K(J,"commands"),y=K(J,"CLAUDE.md");function O(Q){U(Q,{recursive:!0})}class M{db;constructor(){O(B),this.db=new x(N,{create:!0,readwrite:!0}),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON")}getRecentSummaries(Q,Y=10){return this.db.query(`
|
||||
SELECT
|
||||
request, investigated, learned, completed, next_steps,
|
||||
files_read, files_edited, notes, created_at
|
||||
FROM session_summaries
|
||||
WHERE project = ?
|
||||
ORDER BY created_at_epoch DESC
|
||||
LIMIT ?
|
||||
`).all(Q,Y)}findActiveSDKSession(Q){return this.db.query(`
|
||||
SELECT id, sdk_session_id, project
|
||||
FROM sdk_sessions
|
||||
WHERE claude_session_id = ? AND status = 'active'
|
||||
LIMIT 1
|
||||
`).get(Q)||null}createSDKSession(Q,Y,X){let z=new Date,W=z.getTime();return this.db.query(`
|
||||
INSERT INTO sdk_sessions
|
||||
(claude_session_id, project, user_prompt, started_at, started_at_epoch, status)
|
||||
VALUES (?, ?, ?, ?, ?, 'active')
|
||||
`).run(Q,Y,X,z.toISOString(),W),this.db.query("SELECT last_insert_rowid() as id").get().id}updateSDKSessionId(Q,Y){this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET sdk_session_id = ?
|
||||
WHERE id = ?
|
||||
`).run(Y,Q)}storeObservation(Q,Y,X,z){let W=new Date,Z=W.getTime();this.db.query(`
|
||||
INSERT INTO observations
|
||||
(sdk_session_id, project, text, type, created_at, created_at_epoch)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`).run(Q,Y,z,X,W.toISOString(),Z)}storeSummary(Q,Y,X){let z=new Date,W=z.getTime();this.db.query(`
|
||||
INSERT INTO session_summaries
|
||||
(sdk_session_id, project, request, investigated, learned, completed,
|
||||
next_steps, files_read, files_edited, notes, created_at, created_at_epoch)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`).run(Q,Y,X.request||null,X.investigated||null,X.learned||null,X.completed||null,X.next_steps||null,X.files_read||null,X.files_edited||null,X.notes||null,z.toISOString(),W)}markSessionCompleted(Q){let Y=new Date,X=Y.getTime();this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET status = 'completed', completed_at = ?, completed_at_epoch = ?
|
||||
WHERE id = ?
|
||||
`).run(Y.toISOString(),X,Q)}markSessionFailed(Q){let Y=new Date,X=Y.getTime();this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET status = 'failed', completed_at = ?, completed_at_epoch = ?
|
||||
WHERE id = ?
|
||||
`).run(Y.toISOString(),X,Q)}close(){this.db.close()}}function b(Q,Y,X){if(Q==="PreCompact"){if(Y)return{continue:!0,suppressOutput:!0};return{continue:!1,stopReason:X.reason||"Pre-compact operation failed",suppressOutput:!0}}if(Q==="SessionStart"){if(Y&&X.context)return{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:X.context}};return{continue:!0,suppressOutput:!0}}if(Q==="UserPromptSubmit"||Q==="PostToolUse")return{continue:!0,suppressOutput:!0};if(Q==="Stop")return{continue:!0,suppressOutput:!0};return{continue:Y,suppressOutput:!0,...X.reason&&!Y?{stopReason:X.reason}:{}}}function q(Q,Y,X={}){let z=b(Q,Y,X);return JSON.stringify(z)}function F(Q){let Y=Q?.cwd??process.cwd(),X=Y?E.basename(Y):"unknown-project",z=new M;try{let W=z.getRecentSummaries(X,5);if(W.length===0){let $=q("SessionStart",!0,{context:`# Recent Session Context
|
||||
|
||||
No previous sessions found for this project yet.`});console.log($);return}let Z=[];Z.push("# Recent Session Context"),Z.push("");let v=W.length===1?"session":"sessions";Z.push(`Showing last ${W.length} ${v} for **${X}**:`),Z.push("");for(let $ of W){if(Z.push("---"),Z.push(""),$.request)Z.push(`**Request:** ${$.request}`);if($.completed)Z.push(`**Completed:** ${$.completed}`);if($.learned)Z.push(`**Learned:** ${$.learned}`);if($.next_steps)Z.push(`**Next Steps:** ${$.next_steps}`);if($.files_read)try{let V=JSON.parse($.files_read);if(Array.isArray(V)&&V.length>0)Z.push(`**Files Read:** ${V.join(", ")}`)}catch{if($.files_read.trim())Z.push(`**Files Read:** ${$.files_read}`)}if($.files_edited)try{let V=JSON.parse($.files_edited);if(Array.isArray(V)&&V.length>0)Z.push(`**Files Edited:** ${V.join(", ")}`)}catch{if($.files_edited.trim())Z.push(`**Files Edited:** ${$.files_edited}`)}Z.push(`**Date:** ${$.created_at.split("T")[0]}`),Z.push("")}let G=q("SessionStart",!0,{context:Z.join(`
|
||||
`)});console.log(G)}finally{z.close()}}try{if(process.stdin.isTTY)F();else{let Q=await Bun.stdin.text(),Y=Q.trim()?JSON.parse(Q):void 0;F(Y)}}catch(Q){console.error(`[claude-mem context-hook error: ${Q.message}]`),process.exit(0)}
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/usr/bin/env bun
|
||||
// @bun
|
||||
import{spawn as b}from"child_process";import L from"path";import{Database as E}from"bun:sqlite";import{join as Z,dirname as w,basename as S}from"path";import{homedir as F}from"os";import{existsSync as j,mkdirSync as f}from"fs";var $=process.env.CLAUDE_MEM_DATA_DIR||Z(F(),".claude-mem"),B=process.env.CLAUDE_CONFIG_DIR||Z(F(),".claude"),R=Z($,"archives"),y=Z($,"logs"),_=Z($,"trash"),k=Z($,"backups"),I=Z($,"chroma"),h=Z($,"settings.json"),G=Z($,"claude-mem.db"),d=Z(B,"settings.json"),D=Z(B,"commands"),m=Z(B,"CLAUDE.md");function x(Q){f(Q,{recursive:!0})}class V{db;constructor(){x($),this.db=new E(G,{create:!0,readwrite:!0}),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON")}getRecentSummaries(Q,X=10){return this.db.query(`
|
||||
SELECT
|
||||
request, investigated, learned, completed, next_steps,
|
||||
files_read, files_edited, notes, created_at
|
||||
FROM session_summaries
|
||||
WHERE project = ?
|
||||
ORDER BY created_at_epoch DESC
|
||||
LIMIT ?
|
||||
`).all(Q,X)}findActiveSDKSession(Q){return this.db.query(`
|
||||
SELECT id, sdk_session_id, project
|
||||
FROM sdk_sessions
|
||||
WHERE claude_session_id = ? AND status = 'active'
|
||||
LIMIT 1
|
||||
`).get(Q)||null}createSDKSession(Q,X,W){let Y=new Date,z=Y.getTime();return this.db.query(`
|
||||
INSERT INTO sdk_sessions
|
||||
(claude_session_id, project, user_prompt, started_at, started_at_epoch, status)
|
||||
VALUES (?, ?, ?, ?, ?, 'active')
|
||||
`).run(Q,X,W,Y.toISOString(),z),this.db.query("SELECT last_insert_rowid() as id").get().id}updateSDKSessionId(Q,X){this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET sdk_session_id = ?
|
||||
WHERE id = ?
|
||||
`).run(X,Q)}storeObservation(Q,X,W,Y){let z=new Date,K=z.getTime();this.db.query(`
|
||||
INSERT INTO observations
|
||||
(sdk_session_id, project, text, type, created_at, created_at_epoch)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`).run(Q,X,Y,W,z.toISOString(),K)}storeSummary(Q,X,W){let Y=new Date,z=Y.getTime();this.db.query(`
|
||||
INSERT INTO session_summaries
|
||||
(sdk_session_id, project, request, investigated, learned, completed,
|
||||
next_steps, files_read, files_edited, notes, created_at, created_at_epoch)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`).run(Q,X,W.request||null,W.investigated||null,W.learned||null,W.completed||null,W.next_steps||null,W.files_read||null,W.files_edited||null,W.notes||null,Y.toISOString(),z)}markSessionCompleted(Q){let X=new Date,W=X.getTime();this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET status = 'completed', completed_at = ?, completed_at_epoch = ?
|
||||
WHERE id = ?
|
||||
`).run(X.toISOString(),W,Q)}markSessionFailed(Q){let X=new Date,W=X.getTime();this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET status = 'failed', completed_at = ?, completed_at_epoch = ?
|
||||
WHERE id = ?
|
||||
`).run(X.toISOString(),W,Q)}close(){this.db.close()}}function H(Q,X,W){if(Q==="PreCompact"){if(X)return{continue:!0,suppressOutput:!0};return{continue:!1,stopReason:W.reason||"Pre-compact operation failed",suppressOutput:!0}}if(Q==="SessionStart"){if(X&&W.context)return{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:W.context}};return{continue:!0,suppressOutput:!0}}if(Q==="UserPromptSubmit"||Q==="PostToolUse")return{continue:!0,suppressOutput:!0};if(Q==="Stop")return{continue:!0,suppressOutput:!0};return{continue:X,suppressOutput:!0,...W.reason&&!X?{stopReason:W.reason}:{}}}function v(Q,X,W={}){let Y=H(Q,X,W);return JSON.stringify(Y)}function O(Q){if(!Q)throw new Error("newHook requires input");let{session_id:X,cwd:W,prompt:Y}=Q,z=L.basename(W),K=new V;try{if(K.findActiveSDKSession(X)){console.log(v("UserPromptSubmit",!0));return}let M=K.createSDKSession(X,z,Y),q=process.env.CLAUDE_PLUGIN_ROOT;if(!q)throw new Error("CLAUDE_PLUGIN_ROOT not set");let U=L.join(q,"scripts","hooks","worker.js");b("bun",[U,M.toString()],{detached:!0,stdio:"ignore"}).unref(),console.log(v("UserPromptSubmit",!0))}finally{K.close()}}var N=await Bun.stdin.text();try{let Q=N.trim()?JSON.parse(N):void 0;O(Q)}catch(Q){console.error(`[claude-mem new-hook error: ${Q.message}]`),console.log('{"continue": true, "suppressOutput": true}'),process.exit(0)}
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/usr/bin/env bun
|
||||
// @bun
|
||||
import w from"net";import{Database as H}from"bun:sqlite";import{join as $,dirname as T,basename as l}from"path";import{homedir as x}from"os";import{existsSync as y,mkdirSync as E}from"fs";var z=process.env.CLAUDE_MEM_DATA_DIR||$(x(),".claude-mem"),M=process.env.CLAUDE_CONFIG_DIR||$(x(),".claude"),I=$(z,"archives"),k=$(z,"logs"),_=$(z,"trash"),h=$(z,"backups"),D=$(z,"chroma"),d=$(z,"settings.json"),N=$(z,"claude-mem.db"),m=$(M,"settings.json"),u=$(M,"commands"),c=$(M,"CLAUDE.md");function L(Q){return $(z,`worker-${Q}.sock`)}function U(Q){E(Q,{recursive:!0})}class q{db;constructor(){U(z),this.db=new H(N,{create:!0,readwrite:!0}),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON")}getRecentSummaries(Q,Y=10){return this.db.query(`
|
||||
SELECT
|
||||
request, investigated, learned, completed, next_steps,
|
||||
files_read, files_edited, notes, created_at
|
||||
FROM session_summaries
|
||||
WHERE project = ?
|
||||
ORDER BY created_at_epoch DESC
|
||||
LIMIT ?
|
||||
`).all(Q,Y)}findActiveSDKSession(Q){return this.db.query(`
|
||||
SELECT id, sdk_session_id, project
|
||||
FROM sdk_sessions
|
||||
WHERE claude_session_id = ? AND status = 'active'
|
||||
LIMIT 1
|
||||
`).get(Q)||null}createSDKSession(Q,Y,X){let Z=new Date,W=Z.getTime();return this.db.query(`
|
||||
INSERT INTO sdk_sessions
|
||||
(claude_session_id, project, user_prompt, started_at, started_at_epoch, status)
|
||||
VALUES (?, ?, ?, ?, ?, 'active')
|
||||
`).run(Q,Y,X,Z.toISOString(),W),this.db.query("SELECT last_insert_rowid() as id").get().id}updateSDKSessionId(Q,Y){this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET sdk_session_id = ?
|
||||
WHERE id = ?
|
||||
`).run(Y,Q)}storeObservation(Q,Y,X,Z){let W=new Date,B=W.getTime();this.db.query(`
|
||||
INSERT INTO observations
|
||||
(sdk_session_id, project, text, type, created_at, created_at_epoch)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`).run(Q,Y,Z,X,W.toISOString(),B)}storeSummary(Q,Y,X){let Z=new Date,W=Z.getTime();this.db.query(`
|
||||
INSERT INTO session_summaries
|
||||
(sdk_session_id, project, request, investigated, learned, completed,
|
||||
next_steps, files_read, files_edited, notes, created_at, created_at_epoch)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`).run(Q,Y,X.request||null,X.investigated||null,X.learned||null,X.completed||null,X.next_steps||null,X.files_read||null,X.files_edited||null,X.notes||null,Z.toISOString(),W)}markSessionCompleted(Q){let Y=new Date,X=Y.getTime();this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET status = 'completed', completed_at = ?, completed_at_epoch = ?
|
||||
WHERE id = ?
|
||||
`).run(Y.toISOString(),X,Q)}markSessionFailed(Q){let Y=new Date,X=Y.getTime();this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET status = 'failed', completed_at = ?, completed_at_epoch = ?
|
||||
WHERE id = ?
|
||||
`).run(Y.toISOString(),X,Q)}close(){this.db.close()}}function g(Q,Y,X){if(Q==="PreCompact"){if(Y)return{continue:!0,suppressOutput:!0};return{continue:!1,stopReason:X.reason||"Pre-compact operation failed",suppressOutput:!0}}if(Q==="SessionStart"){if(Y&&X.context)return{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:X.context}};return{continue:!0,suppressOutput:!0}}if(Q==="UserPromptSubmit"||Q==="PostToolUse")return{continue:!0,suppressOutput:!0};if(Q==="Stop")return{continue:!0,suppressOutput:!0};return{continue:Y,suppressOutput:!0,...X.reason&&!Y?{stopReason:X.reason}:{}}}function J(Q,Y,X={}){let Z=g(Q,Y,X);return JSON.stringify(Z)}var C=new Set(["TodoWrite","ListMcpResourcesTool"]);function f(Q){if(!Q)throw new Error("saveHook requires input");let{session_id:Y,tool_name:X,tool_input:Z,tool_output:W}=Q;if(C.has(X)){console.log(J("PostToolUse",!0));return}let B=new q,K=B.findActiveSDKSession(Y);if(B.close(),!K){console.log(J("PostToolUse",!0));return}let F=L(K.id),b={type:"observation",tool_name:X,tool_input:JSON.stringify(Z),tool_output:JSON.stringify(W)},V=w.connect(F,()=>{V.write(JSON.stringify(b)+`
|
||||
`),V.end()}),G=!1,v=()=>{if(G)return;G=!0,console.log(J("PostToolUse",!0))};V.on("close",v),V.on("error",v)}var O=await Bun.stdin.text();try{let Q=O.trim()?JSON.parse(O):void 0;f(Q)}catch(Q){console.error(`[claude-mem save-hook error: ${Q.message}]`),console.log('{"continue": true, "suppressOutput": true}'),process.exit(0)}
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/usr/bin/env bun
|
||||
// @bun
|
||||
import E from"net";import{Database as f}from"bun:sqlite";import{join as $,dirname as w,basename as P}from"path";import{homedir as F}from"os";import{existsSync as T,mkdirSync as U}from"fs";var z=process.env.CLAUDE_MEM_DATA_DIR||$(F(),".claude-mem"),v=process.env.CLAUDE_CONFIG_DIR||$(F(),".claude"),A=$(z,"archives"),j=$(z,"logs"),R=$(z,"trash"),_=$(z,"backups"),y=$(z,"chroma"),I=$(z,"settings.json"),G=$(z,"claude-mem.db"),k=$(v,"settings.json"),h=$(v,"commands"),D=$(v,"CLAUDE.md");function x(Q){return $(z,`worker-${Q}.sock`)}function L(Q){U(Q,{recursive:!0})}class J{db;constructor(){L(z),this.db=new f(G,{create:!0,readwrite:!0}),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON")}getRecentSummaries(Q,Y=10){return this.db.query(`
|
||||
SELECT
|
||||
request, investigated, learned, completed, next_steps,
|
||||
files_read, files_edited, notes, created_at
|
||||
FROM session_summaries
|
||||
WHERE project = ?
|
||||
ORDER BY created_at_epoch DESC
|
||||
LIMIT ?
|
||||
`).all(Q,Y)}findActiveSDKSession(Q){return this.db.query(`
|
||||
SELECT id, sdk_session_id, project
|
||||
FROM sdk_sessions
|
||||
WHERE claude_session_id = ? AND status = 'active'
|
||||
LIMIT 1
|
||||
`).get(Q)||null}createSDKSession(Q,Y,X){let Z=new Date,K=Z.getTime();return this.db.query(`
|
||||
INSERT INTO sdk_sessions
|
||||
(claude_session_id, project, user_prompt, started_at, started_at_epoch, status)
|
||||
VALUES (?, ?, ?, ?, ?, 'active')
|
||||
`).run(Q,Y,X,Z.toISOString(),K),this.db.query("SELECT last_insert_rowid() as id").get().id}updateSDKSessionId(Q,Y){this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET sdk_session_id = ?
|
||||
WHERE id = ?
|
||||
`).run(Y,Q)}storeObservation(Q,Y,X,Z){let K=new Date,B=K.getTime();this.db.query(`
|
||||
INSERT INTO observations
|
||||
(sdk_session_id, project, text, type, created_at, created_at_epoch)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`).run(Q,Y,Z,X,K.toISOString(),B)}storeSummary(Q,Y,X){let Z=new Date,K=Z.getTime();this.db.query(`
|
||||
INSERT INTO session_summaries
|
||||
(sdk_session_id, project, request, investigated, learned, completed,
|
||||
next_steps, files_read, files_edited, notes, created_at, created_at_epoch)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`).run(Q,Y,X.request||null,X.investigated||null,X.learned||null,X.completed||null,X.next_steps||null,X.files_read||null,X.files_edited||null,X.notes||null,Z.toISOString(),K)}markSessionCompleted(Q){let Y=new Date,X=Y.getTime();this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET status = 'completed', completed_at = ?, completed_at_epoch = ?
|
||||
WHERE id = ?
|
||||
`).run(Y.toISOString(),X,Q)}markSessionFailed(Q){let Y=new Date,X=Y.getTime();this.db.query(`
|
||||
UPDATE sdk_sessions
|
||||
SET status = 'failed', completed_at = ?, completed_at_epoch = ?
|
||||
WHERE id = ?
|
||||
`).run(Y.toISOString(),X,Q)}close(){this.db.close()}}function b(Q,Y,X){if(Q==="PreCompact"){if(Y)return{continue:!0,suppressOutput:!0};return{continue:!1,stopReason:X.reason||"Pre-compact operation failed",suppressOutput:!0}}if(Q==="SessionStart"){if(Y&&X.context)return{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:X.context}};return{continue:!0,suppressOutput:!0}}if(Q==="UserPromptSubmit"||Q==="PostToolUse")return{continue:!0,suppressOutput:!0};if(Q==="Stop")return{continue:!0,suppressOutput:!0};return{continue:Y,suppressOutput:!0,...X.reason&&!Y?{stopReason:X.reason}:{}}}function M(Q,Y,X={}){let Z=b(Q,Y,X);return JSON.stringify(Z)}function N(Q){if(!Q)throw new Error("summaryHook requires input");let{session_id:Y}=Q,X=new J,Z=X.findActiveSDKSession(Y);if(X.close(),!Z){console.log(M("Stop",!0));return}let K=x(Z.id),B={type:"finalize"},W=E.connect(K,()=>{W.write(JSON.stringify(B)+`
|
||||
`),W.end()}),V=!1,q=()=>{if(V)return;V=!0,console.log(M("Stop",!0))};W.on("close",q),W.on("error",q)}var O=await Bun.stdin.text();try{let Q=O.trim()?JSON.parse(O):void 0;N(Q)}catch(Q){console.error(`[claude-mem summary-hook error: ${Q.message}]`),console.log('{"continue": true, "suppressOutput": true}'),process.exit(0)}
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user