@hir4ta/mneme 0.20.0 → 0.20.2
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/.claude-plugin/plugin.json +1 -1
- package/dist/lib/incremental-save.js +16 -3
- package/dist/public/assets/{index-CFkxnncE.js → index-CeHiZXwl.js} +2 -2
- package/dist/public/assets/{react-force-graph-2d-D3wGjFqA.js → react-force-graph-2d-CGnpkwRw.js} +1 -1
- package/dist/public/index.html +1 -1
- package/dist/servers/db-server.js +33 -1
- package/hooks/session-end.sh +15 -1
- package/package.json +1 -1
- package/servers/db-server.ts +44 -1
package/dist/public/assets/{react-force-graph-2d-D3wGjFqA.js → react-force-graph-2d-CGnpkwRw.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{i as zt,r as ot,R as Di,c as On,a as En,b as $i,o as ji,m as zn,d as Rn,g as Fi}from"./index-
|
|
1
|
+
import{i as zt,r as ot,R as Di,c as On,a as En,b as $i,o as ji,m as zn,d as Rn,g as Fi}from"./index-CeHiZXwl.js";function Ui(e,n){let r=0;for(let i of e)(i=+i)&&(r+=i);return r}var In=180/Math.PI,Xe={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function Pr(e,n,r,i,o,a){var s,u,f;return(s=Math.sqrt(e*e+n*n))&&(e/=s,n/=s),(f=e*r+n*i)&&(r-=e*f,i-=n*f),(u=Math.sqrt(r*r+i*i))&&(r/=u,i/=u,f/=u),e*i<n*r&&(e=-e,n=-n,f=-f,s=-s),{translateX:o,translateY:a,rotate:Math.atan2(n,e)*In,skewX:Math.atan(f)*In,scaleX:s,scaleY:u}}var fe;function Li(e){const n=new(typeof DOMMatrix=="function"?DOMMatrix:WebKitCSSMatrix)(e+"");return n.isIdentity?Xe:Pr(n.a,n.b,n.c,n.d,n.e,n.f)}function qi(e){return e==null||(fe||(fe=document.createElementNS("http://www.w3.org/2000/svg","g")),fe.setAttribute("transform",e),!(e=fe.transform.baseVal.consolidate()))?Xe:(e=e.matrix,Pr(e.a,e.b,e.c,e.d,e.e,e.f))}function Or(e,n,r,i){function o(l){return l.length?l.pop()+" ":""}function a(l,h,c,d,p,y){if(l!==c||h!==d){var m=p.push("translate(",null,n,null,r);y.push({i:m-4,x:zt(l,c)},{i:m-2,x:zt(h,d)})}else(c||d)&&p.push("translate("+c+n+d+r)}function s(l,h,c,d){l!==h?(l-h>180?h+=360:h-l>180&&(l+=360),d.push({i:c.push(o(c)+"rotate(",null,i)-2,x:zt(l,h)})):h&&c.push(o(c)+"rotate("+h+i)}function u(l,h,c,d){l!==h?d.push({i:c.push(o(c)+"skewX(",null,i)-2,x:zt(l,h)}):h&&c.push(o(c)+"skewX("+h+i)}function f(l,h,c,d,p,y){if(l!==c||h!==d){var m=p.push(o(p)+"scale(",null,",",null,")");y.push({i:m-4,x:zt(l,c)},{i:m-2,x:zt(h,d)})}else(c!==1||d!==1)&&p.push(o(p)+"scale("+c+","+d+")")}return function(l,h){var c=[],d=[];return l=e(l),h=e(h),a(l.translateX,l.translateY,h.translateX,h.translateY,c,d),s(l.rotate,h.rotate,c,d),u(l.skewX,h.skewX,c,d),f(l.scaleX,l.scaleY,h.scaleX,h.scaleY,c,d),l=h=null,function(p){for(var y=-1,m=d.length,_;++y<m;)c[(_=d[y]).i]=_.x(p);return c.join("")}}}var Hi=Or(Li,"px, ","px)","deg)"),Vi=Or(qi,", ",")",")"),Gi=1e-12;function Nn(e){return((e=Math.exp(e))+1/e)/2}function Wi(e){return((e=Math.exp(e))-1/e)/2}function Bi(e){return((e=Math.exp(2*e))-1)/(e+1)}const Xi=(function e(n,r,i){function o(a,s){var u=a[0],f=a[1],l=a[2],h=s[0],c=s[1],d=s[2],p=h-u,y=c-f,m=p*p+y*y,_,g;if(m<Gi)g=Math.log(d/l)/n,_=function(S){return[u+S*p,f+S*y,l*Math.exp(n*S*g)]};else{var w=Math.sqrt(m),C=(d*d-l*l+i*m)/(2*l*r*w),b=(d*d-l*l-i*m)/(2*d*r*w),x=Math.log(Math.sqrt(C*C+1)-C),A=Math.log(Math.sqrt(b*b+1)-b);g=(A-x)/n,_=function(S){var T=S*g,R=Nn(x),O=l/(r*w)*(R*Bi(n*T+x)-Wi(x));return[u+O*p,f+O*y,l*R/Nn(n*T+x)]}}return _.duration=g*1e3*n/Math.SQRT2,_}return o.rho=function(a){var s=Math.max(.001,+a),u=s*s,f=u*u;return e(s,u,f)},o})(Math.SQRT2,2,4);function Yi(e,n){var r=e==null?null:typeof Symbol<"u"&&e[Symbol.iterator]||e["@@iterator"];if(r!=null){var i,o,a,s,u=[],f=!0,l=!1;try{if(a=(r=r.call(e)).next,n===0){if(Object(r)!==r)return;f=!1}else for(;!(f=(i=a.call(r)).done)&&(u.push(i.value),u.length!==n);f=!0);}catch(h){l=!0,o=h}finally{try{if(!f&&r.return!=null&&(s=r.return(),Object(s)!==s))return}finally{if(l)throw o}}return u}}function Zi(e,n,r){return n=io(n),n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function Dn(e,n){return Ji(e)||Yi(e,n)||Er(e,n)||no()}function Ki(e){return Qi(e)||to(e)||Er(e)||eo()}function Qi(e){if(Array.isArray(e))return Ye(e)}function Ji(e){if(Array.isArray(e))return e}function to(e){if(typeof Symbol<"u"&&e[Symbol.iterator]!=null||e["@@iterator"]!=null)return Array.from(e)}function Er(e,n){if(e){if(typeof e=="string")return Ye(e,n);var r=Object.prototype.toString.call(e).slice(8,-1);if(r==="Object"&&e.constructor&&(r=e.constructor.name),r==="Map"||r==="Set")return Array.from(e);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return Ye(e,n)}}function Ye(e,n){(n==null||n>e.length)&&(n=e.length);for(var r=0,i=new Array(n);r<n;r++)i[r]=e[r];return i}function eo(){throw new TypeError(`Invalid attempt to spread non-iterable instance.
|
|
2
2
|
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function no(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
3
3
|
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function ro(e,n){if(typeof e!="object"||e===null)return e;var r=e[Symbol.toPrimitive];if(r!==void 0){var i=r.call(e,n);if(typeof i!="object")return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return(n==="string"?String:Number)(e)}function io(e){var n=ro(e,"string");return typeof n=="symbol"?n:String(n)}var oo=function(n,r){var i=new Set(r);return Object.assign.apply(Object,[{}].concat(Ki(Object.entries(n).filter(function(o){var a=Dn(o,1),s=a[0];return!i.has(s)}).map(function(o){var a=Dn(o,2),s=a[0],u=a[1];return Zi({},s,u)}))))};function Ze(e,n){(n==null||n>e.length)&&(n=e.length);for(var r=0,i=Array(n);r<n;r++)i[r]=e[r];return i}function ao(e){if(Array.isArray(e))return e}function so(e){if(Array.isArray(e))return Ze(e)}function uo(e){if(typeof Symbol<"u"&&e[Symbol.iterator]!=null||e["@@iterator"]!=null)return Array.from(e)}function lo(e,n){var r=e==null?null:typeof Symbol<"u"&&e[Symbol.iterator]||e["@@iterator"];if(r!=null){var i,o,a,s,u=[],f=!0,l=!1;try{if(a=(r=r.call(e)).next,n!==0)for(;!(f=(i=a.call(r)).done)&&(u.push(i.value),u.length!==n);f=!0);}catch(h){l=!0,o=h}finally{try{if(!f&&r.return!=null&&(s=r.return(),Object(s)!==s))return}finally{if(l)throw o}}return u}}function fo(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
4
4
|
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function co(){throw new TypeError(`Invalid attempt to spread non-iterable instance.
|
package/dist/public/index.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>mneme - Dashboard</title>
|
|
7
7
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32-max.png" />
|
|
8
8
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-CeHiZXwl.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/assets/index-t_srr1OD.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
@@ -30200,7 +30200,9 @@ async function parseTranscript(transcriptPath) {
|
|
|
30200
30200
|
crlfDelay: Number.POSITIVE_INFINITY
|
|
30201
30201
|
});
|
|
30202
30202
|
const entries = [];
|
|
30203
|
+
let totalLines = 0;
|
|
30203
30204
|
for await (const line of rl) {
|
|
30205
|
+
totalLines++;
|
|
30204
30206
|
if (line.trim()) {
|
|
30205
30207
|
try {
|
|
30206
30208
|
entries.push(JSON.parse(line));
|
|
@@ -30210,6 +30212,7 @@ async function parseTranscript(transcriptPath) {
|
|
|
30210
30212
|
}
|
|
30211
30213
|
const userMessages = entries.filter((e) => {
|
|
30212
30214
|
if (e.type !== "user" || e.message?.role !== "user") return false;
|
|
30215
|
+
if (e.isMeta === true) return false;
|
|
30213
30216
|
const content = e.message?.content;
|
|
30214
30217
|
if (typeof content !== "string") return false;
|
|
30215
30218
|
if (content.startsWith("<local-command-stdout>")) return false;
|
|
@@ -30286,7 +30289,8 @@ async function parseTranscript(transcriptPath) {
|
|
|
30286
30289
|
userMessages: userMessages.length,
|
|
30287
30290
|
assistantResponses: assistantMessages.length,
|
|
30288
30291
|
thinkingBlocks: assistantMessages.filter((a) => a.thinking).length
|
|
30289
|
-
}
|
|
30292
|
+
},
|
|
30293
|
+
totalLines
|
|
30290
30294
|
};
|
|
30291
30295
|
}
|
|
30292
30296
|
async function saveInteractions(claudeSessionId, mnemeSessionId) {
|
|
@@ -30424,6 +30428,34 @@ async function saveInteractions(claudeSessionId, mnemeSessionId) {
|
|
|
30424
30428
|
clearBackupStmt.run(sessionId);
|
|
30425
30429
|
} catch {
|
|
30426
30430
|
}
|
|
30431
|
+
try {
|
|
30432
|
+
const lastTimestamp = finalInteractions.length > 0 ? finalInteractions[finalInteractions.length - 1].timestamp : null;
|
|
30433
|
+
const checkStmt = database.prepare(
|
|
30434
|
+
"SELECT 1 FROM session_save_state WHERE claude_session_id = ?"
|
|
30435
|
+
);
|
|
30436
|
+
const exists = checkStmt.get(claudeSessionId);
|
|
30437
|
+
if (exists) {
|
|
30438
|
+
const updateStmt = database.prepare(`
|
|
30439
|
+
UPDATE session_save_state
|
|
30440
|
+
SET last_saved_line = ?, last_saved_timestamp = ?, updated_at = datetime('now')
|
|
30441
|
+
WHERE claude_session_id = ?
|
|
30442
|
+
`);
|
|
30443
|
+
updateStmt.run(parsed.totalLines, lastTimestamp, claudeSessionId);
|
|
30444
|
+
} else {
|
|
30445
|
+
const insertStmt2 = database.prepare(`
|
|
30446
|
+
INSERT INTO session_save_state (claude_session_id, mneme_session_id, project_path, last_saved_line, last_saved_timestamp)
|
|
30447
|
+
VALUES (?, ?, ?, ?, ?)
|
|
30448
|
+
`);
|
|
30449
|
+
insertStmt2.run(
|
|
30450
|
+
claudeSessionId,
|
|
30451
|
+
sessionId,
|
|
30452
|
+
projectPath,
|
|
30453
|
+
parsed.totalLines,
|
|
30454
|
+
lastTimestamp
|
|
30455
|
+
);
|
|
30456
|
+
}
|
|
30457
|
+
} catch {
|
|
30458
|
+
}
|
|
30427
30459
|
return {
|
|
30428
30460
|
success: true,
|
|
30429
30461
|
savedCount: insertedCount,
|
package/hooks/session-end.sh
CHANGED
|
@@ -130,7 +130,21 @@ if [ -n "$session_file" ] && [ -f "$session_file" ]; then
|
|
|
130
130
|
echo "[mneme] Session ended without /mneme:save - cleaned up ${deleted_count} interactions" >&2
|
|
131
131
|
fi
|
|
132
132
|
fi
|
|
133
|
-
|
|
133
|
+
|
|
134
|
+
# Also delete the empty session JSON file (no summary = not saved)
|
|
135
|
+
if [ -f "$session_file" ]; then
|
|
136
|
+
rm -f "$session_file"
|
|
137
|
+
echo "[mneme] Deleted empty session file: ${session_file}" >&2
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# Delete session-link file if exists
|
|
141
|
+
link_file="${session_links_dir}/${session_short_id}.json"
|
|
142
|
+
if [ -f "$link_file" ]; then
|
|
143
|
+
rm -f "$link_file"
|
|
144
|
+
echo "[mneme] Deleted session-link file: ${link_file}" >&2
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
echo "[mneme] Session completed (not saved, cleaned up)" >&2
|
|
134
148
|
else
|
|
135
149
|
echo "[mneme] Session completed: ${session_file}" >&2
|
|
136
150
|
fi
|
package/package.json
CHANGED
package/servers/db-server.ts
CHANGED
|
@@ -479,6 +479,7 @@ interface ParsedTranscript {
|
|
|
479
479
|
assistantResponses: number;
|
|
480
480
|
thinkingBlocks: number;
|
|
481
481
|
};
|
|
482
|
+
totalLines: number;
|
|
482
483
|
}
|
|
483
484
|
|
|
484
485
|
async function parseTranscript(
|
|
@@ -509,8 +510,10 @@ async function parseTranscript(
|
|
|
509
510
|
}
|
|
510
511
|
|
|
511
512
|
const entries: TranscriptEntry[] = [];
|
|
513
|
+
let totalLines = 0;
|
|
512
514
|
|
|
513
515
|
for await (const line of rl) {
|
|
516
|
+
totalLines++;
|
|
514
517
|
if (line.trim()) {
|
|
515
518
|
try {
|
|
516
519
|
entries.push(JSON.parse(line));
|
|
@@ -520,10 +523,12 @@ async function parseTranscript(
|
|
|
520
523
|
}
|
|
521
524
|
}
|
|
522
525
|
|
|
523
|
-
// Extract user messages (text only, exclude tool results
|
|
526
|
+
// Extract user messages (text only, exclude tool results, local command outputs, and skill expansions)
|
|
524
527
|
const userMessages = entries
|
|
525
528
|
.filter((e) => {
|
|
526
529
|
if (e.type !== "user" || e.message?.role !== "user") return false;
|
|
530
|
+
// Skip skill expansions (isMeta: true) to avoid duplicates
|
|
531
|
+
if ((e as { isMeta?: boolean }).isMeta === true) return false;
|
|
527
532
|
const content = e.message?.content;
|
|
528
533
|
if (typeof content !== "string") return false;
|
|
529
534
|
if (content.startsWith("<local-command-stdout>")) return false;
|
|
@@ -641,6 +646,7 @@ async function parseTranscript(
|
|
|
641
646
|
assistantResponses: assistantMessages.length,
|
|
642
647
|
thinkingBlocks: assistantMessages.filter((a) => a.thinking).length,
|
|
643
648
|
},
|
|
649
|
+
totalLines,
|
|
644
650
|
};
|
|
645
651
|
}
|
|
646
652
|
|
|
@@ -827,6 +833,43 @@ async function saveInteractions(
|
|
|
827
833
|
// Ignore
|
|
828
834
|
}
|
|
829
835
|
|
|
836
|
+
// Update session_save_state to prevent incremental-save from re-inserting
|
|
837
|
+
// This is critical to avoid duplicate interactions
|
|
838
|
+
try {
|
|
839
|
+
const lastTimestamp =
|
|
840
|
+
finalInteractions.length > 0
|
|
841
|
+
? finalInteractions[finalInteractions.length - 1].timestamp
|
|
842
|
+
: null;
|
|
843
|
+
|
|
844
|
+
const checkStmt = database.prepare(
|
|
845
|
+
"SELECT 1 FROM session_save_state WHERE claude_session_id = ?",
|
|
846
|
+
);
|
|
847
|
+
const exists = checkStmt.get(claudeSessionId);
|
|
848
|
+
|
|
849
|
+
if (exists) {
|
|
850
|
+
const updateStmt = database.prepare(`
|
|
851
|
+
UPDATE session_save_state
|
|
852
|
+
SET last_saved_line = ?, last_saved_timestamp = ?, updated_at = datetime('now')
|
|
853
|
+
WHERE claude_session_id = ?
|
|
854
|
+
`);
|
|
855
|
+
updateStmt.run(parsed.totalLines, lastTimestamp, claudeSessionId);
|
|
856
|
+
} else {
|
|
857
|
+
const insertStmt = database.prepare(`
|
|
858
|
+
INSERT INTO session_save_state (claude_session_id, mneme_session_id, project_path, last_saved_line, last_saved_timestamp)
|
|
859
|
+
VALUES (?, ?, ?, ?, ?)
|
|
860
|
+
`);
|
|
861
|
+
insertStmt.run(
|
|
862
|
+
claudeSessionId,
|
|
863
|
+
sessionId,
|
|
864
|
+
projectPath,
|
|
865
|
+
parsed.totalLines,
|
|
866
|
+
lastTimestamp,
|
|
867
|
+
);
|
|
868
|
+
}
|
|
869
|
+
} catch {
|
|
870
|
+
// Ignore session_save_state errors
|
|
871
|
+
}
|
|
872
|
+
|
|
830
873
|
return {
|
|
831
874
|
success: true,
|
|
832
875
|
savedCount: insertedCount,
|