@agentmemory/agentmemory 0.8.11 → 0.9.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/AGENTS.md +2 -2
- package/README.md +80 -9
- package/dist/cli.mjs +47 -5
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +866 -33
- package/dist/index.mjs.map +1 -1
- package/dist/{src-M6V9yZW5.mjs → src-B3pEsBSb.mjs} +838 -29
- package/dist/src-B3pEsBSb.mjs.map +1 -0
- package/dist/standalone-DXc-BEqr.mjs +457 -0
- package/dist/standalone-DXc-BEqr.mjs.map +1 -0
- package/dist/standalone.d.mts.map +1 -1
- package/dist/standalone.mjs +230 -66
- package/dist/standalone.mjs.map +1 -1
- package/dist/{tools-registry-DmTkd0if.mjs → tools-registry-DXIK5CxQ.mjs} +31 -7
- package/dist/tools-registry-DXIK5CxQ.mjs.map +1 -0
- package/dist/viewer/index.html +264 -0
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +2 -2
- package/dist/src-M6V9yZW5.mjs.map +0 -1
- package/dist/standalone-XB9gPYmo.mjs +0 -313
- package/dist/standalone-XB9gPYmo.mjs.map +0 -1
- package/dist/tools-registry-DmTkd0if.mjs.map +0 -1
package/dist/viewer/index.html
CHANGED
|
@@ -578,6 +578,35 @@
|
|
|
578
578
|
.empty-state p { font-size: 14px; font-family: var(--font-body); font-style: italic; }
|
|
579
579
|
|
|
580
580
|
.loading { color: var(--ink-faint); padding: 20px; text-align: center; font-style: italic; font-family: var(--font-body); }
|
|
581
|
+
.empty { color: var(--ink-muted); padding: 24px; text-align: center; font-family: var(--font-body); font-style: italic; border: 1px dashed var(--border); }
|
|
582
|
+
|
|
583
|
+
.replay-controls { display: flex; align-items: center; gap: 6px; padding: 10px 0; flex-wrap: wrap; font-family: var(--font-ui); font-size: 12px; }
|
|
584
|
+
.replay-controls button { padding: 4px 10px; border: 1px solid var(--border); background: var(--bg); color: var(--ink); cursor: pointer; font-family: var(--font-ui); font-size: 12px; }
|
|
585
|
+
.replay-controls button:hover { background: var(--bg-alt); }
|
|
586
|
+
.replay-controls button.active { background: var(--ink); color: var(--bg); }
|
|
587
|
+
.replay-controls .sep { width: 12px; }
|
|
588
|
+
.replay-progress { height: 3px; background: var(--border-light); margin: 4px 0 12px 0; }
|
|
589
|
+
.replay-progress-bar { height: 100%; background: var(--ink); transition: width 100ms linear; }
|
|
590
|
+
.replay-grid { display: grid; grid-template-columns: 340px 1fr; gap: 16px; align-items: start; }
|
|
591
|
+
.replay-list { max-height: 60vh; overflow-y: auto; border: 1px solid var(--border); }
|
|
592
|
+
.replay-event { display: grid; grid-template-columns: 90px 1fr 60px; gap: 8px; padding: 6px 10px; border-bottom: 1px solid var(--border-light); font-family: var(--font-ui); font-size: 11px; cursor: default; }
|
|
593
|
+
.replay-event:hover { background: var(--bg-alt); }
|
|
594
|
+
.replay-event-active { background: var(--bg-alt); border-left: 2px solid var(--ink); }
|
|
595
|
+
.replay-event-kind { font-size: 9px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-muted); align-self: center; }
|
|
596
|
+
.replay-event-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
597
|
+
.replay-event-time { text-align: right; font-family: var(--font-mono); color: var(--ink-muted); }
|
|
598
|
+
.replay-event-prompt .replay-event-kind { color: var(--blue, #0366d6); }
|
|
599
|
+
.replay-event-response .replay-event-kind { color: var(--green, #2ea043); }
|
|
600
|
+
.replay-event-tool_call .replay-event-kind { color: var(--orange, #bf8700); }
|
|
601
|
+
.replay-event-tool_result .replay-event-kind { color: var(--ink-muted); }
|
|
602
|
+
.replay-event-tool_error .replay-event-kind { color: var(--red, #cf222e); }
|
|
603
|
+
.replay-detail { border: 1px solid var(--border); padding: 14px; max-height: 60vh; overflow-y: auto; font-family: var(--font-body); font-size: 13px; }
|
|
604
|
+
.replay-detail-header { margin-bottom: 6px; }
|
|
605
|
+
.replay-body { background: var(--bg-alt); padding: 10px; white-space: pre-wrap; word-break: break-word; font-family: var(--font-mono); font-size: 12px; }
|
|
606
|
+
.replay-tool { margin-top: 10px; font-family: var(--font-ui); font-size: 12px; }
|
|
607
|
+
.replay-tool-block { margin-top: 8px; }
|
|
608
|
+
.replay-tool-block pre { background: var(--bg-alt); padding: 10px; max-height: 240px; overflow: auto; font-family: var(--font-mono); font-size: 11px; white-space: pre-wrap; word-break: break-word; }
|
|
609
|
+
.muted { color: var(--ink-muted); font-size: 11px; }
|
|
581
610
|
|
|
582
611
|
.metric-table { width: 100%; border-collapse: collapse; font-size: 12px; }
|
|
583
612
|
.metric-table th { padding: 6px 8px; font-size: 9px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-muted); border-bottom: 2px solid var(--border); text-align: left; font-family: var(--font-ui); font-weight: 600; }
|
|
@@ -782,6 +811,7 @@
|
|
|
782
811
|
<button data-tab="audit">Audit</button>
|
|
783
812
|
<button data-tab="activity">Activity</button>
|
|
784
813
|
<button data-tab="profile">Profile</button>
|
|
814
|
+
<button data-tab="replay">Replay</button>
|
|
785
815
|
</div>
|
|
786
816
|
|
|
787
817
|
<div id="view-dashboard" class="view active"></div>
|
|
@@ -795,6 +825,7 @@
|
|
|
795
825
|
<div id="view-audit" class="view"></div>
|
|
796
826
|
<div id="view-activity" class="view"></div>
|
|
797
827
|
<div id="view-profile" class="view"></div>
|
|
828
|
+
<div id="view-replay" class="view"></div>
|
|
798
829
|
|
|
799
830
|
<div id="modal-overlay" class="modal-overlay">
|
|
800
831
|
<div class="modal" id="modal"></div>
|
|
@@ -871,6 +902,7 @@
|
|
|
871
902
|
actions: { loaded: false, items: [], frontier: [], statusFilter: '', search: '' },
|
|
872
903
|
crystals: { loaded: false, items: [], search: '' },
|
|
873
904
|
profile: { loaded: false, projects: [], selectedProject: '', data: null },
|
|
905
|
+
replay: { loaded: false, sessions: [], selectedId: '', timeline: null, cursor: 0, playing: false, speed: 1, timer: null, startAt: 0, offsetAt: 0 },
|
|
874
906
|
ws: null
|
|
875
907
|
};
|
|
876
908
|
|
|
@@ -934,6 +966,9 @@
|
|
|
934
966
|
}
|
|
935
967
|
|
|
936
968
|
function switchTab(tab) {
|
|
969
|
+
if (state.activeTab === 'replay' && tab !== 'replay' && typeof stopReplayTimer === 'function') {
|
|
970
|
+
stopReplayTimer();
|
|
971
|
+
}
|
|
937
972
|
state.activeTab = tab;
|
|
938
973
|
document.querySelectorAll('.tab-bar button').forEach(function(b) {
|
|
939
974
|
b.classList.toggle('active', b.dataset.tab === tab);
|
|
@@ -957,6 +992,7 @@
|
|
|
957
992
|
case 'audit': if (!state.audit.loaded) await loadAudit(); break;
|
|
958
993
|
case 'activity': if (!state.activity.loaded) await loadActivity(); break;
|
|
959
994
|
case 'profile': if (!state.profile.loaded) await loadProfile(); break;
|
|
995
|
+
case 'replay': if (!state.replay.loaded) await loadReplay(); break;
|
|
960
996
|
}
|
|
961
997
|
}
|
|
962
998
|
|
|
@@ -3006,11 +3042,239 @@
|
|
|
3006
3042
|
var auditIndex = parseInt(target.getAttribute('data-audit-index') || '', 10);
|
|
3007
3043
|
if (!Number.isNaN(auditIndex)) toggleAuditDetail(auditIndex);
|
|
3008
3044
|
}
|
|
3045
|
+
if (action === 'replay-select') {
|
|
3046
|
+
var rSid = target.getAttribute('data-session-id');
|
|
3047
|
+
if (rSid) selectReplaySession(rSid);
|
|
3048
|
+
return;
|
|
3049
|
+
}
|
|
3050
|
+
if (action === 'replay-toggle-play') { toggleReplayPlay(); return; }
|
|
3051
|
+
if (action === 'replay-step') {
|
|
3052
|
+
var d = parseInt(target.getAttribute('data-dir') || '1', 10);
|
|
3053
|
+
stepReplay(d);
|
|
3054
|
+
return;
|
|
3055
|
+
}
|
|
3056
|
+
if (action === 'replay-speed') {
|
|
3057
|
+
var sp = parseFloat(target.getAttribute('data-speed') || '1');
|
|
3058
|
+
setReplaySpeed(sp);
|
|
3059
|
+
return;
|
|
3060
|
+
}
|
|
3061
|
+
if (action === 'replay-reset') { resetReplay(); return; }
|
|
3062
|
+
if (action === 'replay-import') { runReplayImport(); return; }
|
|
3063
|
+
if (action === 'replay-refresh') { refreshReplaySessions(); return; }
|
|
3009
3064
|
});
|
|
3010
3065
|
document.getElementById('modal-overlay').addEventListener('click', function(e) {
|
|
3011
3066
|
if (e.target === this) closeModal();
|
|
3012
3067
|
});
|
|
3013
3068
|
|
|
3069
|
+
async function loadReplay() {
|
|
3070
|
+
var el = document.getElementById('view-replay');
|
|
3071
|
+
el.innerHTML = '<div class="loading">Loading sessions…</div>';
|
|
3072
|
+
var res = await apiGet('replay/sessions');
|
|
3073
|
+
state.replay.sessions = (res && res.sessions) || [];
|
|
3074
|
+
state.replay.loaded = true;
|
|
3075
|
+
renderReplay();
|
|
3076
|
+
}
|
|
3077
|
+
|
|
3078
|
+
async function refreshReplaySessions() {
|
|
3079
|
+
state.replay.loaded = false;
|
|
3080
|
+
await loadReplay();
|
|
3081
|
+
}
|
|
3082
|
+
|
|
3083
|
+
function renderReplay() {
|
|
3084
|
+
var el = document.getElementById('view-replay');
|
|
3085
|
+
var sessions = state.replay.sessions || [];
|
|
3086
|
+
var options = '<option value="">— pick a session —</option>' + sessions.map(function(s) {
|
|
3087
|
+
var label = (s.project || 'unknown') + ' · ' + (s.id || '').slice(0, 8) + ' · ' + (s.observationCount || 0) + ' obs';
|
|
3088
|
+
return '<option value="' + esc(s.id) + '"' + (s.id === state.replay.selectedId ? ' selected' : '') + '>' + esc(label) + '</option>';
|
|
3089
|
+
}).join('');
|
|
3090
|
+
|
|
3091
|
+
var tl = state.replay.timeline;
|
|
3092
|
+
var hasTl = tl && tl.events && tl.events.length > 0;
|
|
3093
|
+
var cursorEvent = hasTl ? tl.events[Math.min(state.replay.cursor, tl.events.length - 1)] : null;
|
|
3094
|
+
var progress = hasTl && tl.totalDurationMs > 0 ? Math.min(100, (state.replay.offsetAt / tl.totalDurationMs) * 100) : 0;
|
|
3095
|
+
|
|
3096
|
+
el.innerHTML =
|
|
3097
|
+
'<div class="toolbar">' +
|
|
3098
|
+
'<select id="replay-session-select">' + options + '</select>' +
|
|
3099
|
+
'<button data-action="replay-refresh">Refresh</button>' +
|
|
3100
|
+
'<span class="sep"></span>' +
|
|
3101
|
+
'<input type="text" id="replay-import-path" placeholder="~/.claude/projects or file.jsonl" style="width:280px">' +
|
|
3102
|
+
'<button data-action="replay-import">Import JSONL</button>' +
|
|
3103
|
+
'</div>' +
|
|
3104
|
+
(hasTl
|
|
3105
|
+
? '<div class="replay-controls">' +
|
|
3106
|
+
'<button data-action="replay-step" data-dir="-1" title="Previous (←)">◀</button>' +
|
|
3107
|
+
'<button data-action="replay-toggle-play" title="Play/Pause (Space)">' + (state.replay.playing ? '❚❚ Pause' : '▶ Play') + '</button>' +
|
|
3108
|
+
'<button data-action="replay-step" data-dir="1" title="Next (→)">▶</button>' +
|
|
3109
|
+
'<button data-action="replay-reset" title="Reset">⟲</button>' +
|
|
3110
|
+
'<span class="sep"></span>' +
|
|
3111
|
+
'<span>Speed</span>' +
|
|
3112
|
+
['0.5', '1', '2', '4'].map(function(sp) {
|
|
3113
|
+
var active = Math.abs(state.replay.speed - parseFloat(sp)) < 0.01;
|
|
3114
|
+
return '<button data-action="replay-speed" data-speed="' + sp + '"' + (active ? ' class="active"' : '') + '>' + sp + '×</button>';
|
|
3115
|
+
}).join('') +
|
|
3116
|
+
'<span class="sep"></span>' +
|
|
3117
|
+
'<span>' + (state.replay.cursor + 1) + ' / ' + tl.eventCount + '</span>' +
|
|
3118
|
+
'</div>' +
|
|
3119
|
+
'<div class="replay-progress"><div class="replay-progress-bar" style="width:' + progress.toFixed(1) + '%"></div></div>' +
|
|
3120
|
+
'<div class="replay-grid">' +
|
|
3121
|
+
'<div class="replay-list" id="replay-list">' +
|
|
3122
|
+
tl.events.map(function(ev, i) {
|
|
3123
|
+
var active = i === state.replay.cursor ? ' replay-event-active' : '';
|
|
3124
|
+
return '<div class="replay-event replay-event-' + esc(ev.kind) + active + '" data-replay-idx="' + i + '">' +
|
|
3125
|
+
'<span class="replay-event-kind">' + esc(ev.kind) + '</span>' +
|
|
3126
|
+
'<span class="replay-event-label">' + esc(ev.label) + '</span>' +
|
|
3127
|
+
'<span class="replay-event-time">' + (ev.offsetMs / 1000).toFixed(1) + 's</span>' +
|
|
3128
|
+
'</div>';
|
|
3129
|
+
}).join('') +
|
|
3130
|
+
'</div>' +
|
|
3131
|
+
'<div class="replay-detail">' + renderReplayDetail(cursorEvent) + '</div>' +
|
|
3132
|
+
'</div>'
|
|
3133
|
+
: '<div class="empty">Pick a session to replay, or import Claude Code JSONL transcripts from ~/.claude/projects.</div>');
|
|
3134
|
+
|
|
3135
|
+
var sel = document.getElementById('replay-session-select');
|
|
3136
|
+
if (sel) sel.addEventListener('change', function() { selectReplaySession(sel.value); });
|
|
3137
|
+
}
|
|
3138
|
+
|
|
3139
|
+
function renderReplayDetail(ev) {
|
|
3140
|
+
if (!ev) return '<div class="empty">No event selected.</div>';
|
|
3141
|
+
var blocks = [];
|
|
3142
|
+
blocks.push('<div class="replay-detail-header"><b>' + esc(ev.label) + '</b> <span class="muted">' + esc(ev.kind) + '</span></div>');
|
|
3143
|
+
if (ev.ts) blocks.push('<div class="muted">' + esc(formatTime(ev.ts)) + '</div>');
|
|
3144
|
+
if (ev.body) {
|
|
3145
|
+
blocks.push('<pre class="replay-body">' + esc(ev.body) + '</pre>');
|
|
3146
|
+
}
|
|
3147
|
+
if (ev.toolName) {
|
|
3148
|
+
blocks.push('<div class="replay-tool"><b>Tool:</b> ' + esc(ev.toolName) + '</div>');
|
|
3149
|
+
}
|
|
3150
|
+
if (ev.toolInput !== undefined && ev.toolInput !== null) {
|
|
3151
|
+
var inp = typeof ev.toolInput === 'string' ? ev.toolInput : JSON.stringify(ev.toolInput, null, 2);
|
|
3152
|
+
blocks.push('<div class="replay-tool-block"><b>Input</b><pre>' + esc(truncate(inp, 4000)) + '</pre></div>');
|
|
3153
|
+
}
|
|
3154
|
+
if (ev.toolOutput !== undefined && ev.toolOutput !== null) {
|
|
3155
|
+
var out = typeof ev.toolOutput === 'string' ? ev.toolOutput : JSON.stringify(ev.toolOutput, null, 2);
|
|
3156
|
+
blocks.push('<div class="replay-tool-block"><b>Output</b><pre>' + esc(truncate(out, 4000)) + '</pre></div>');
|
|
3157
|
+
}
|
|
3158
|
+
return blocks.join('');
|
|
3159
|
+
}
|
|
3160
|
+
|
|
3161
|
+
async function selectReplaySession(sessionId) {
|
|
3162
|
+
stopReplayTimer();
|
|
3163
|
+
state.replay.selectedId = sessionId;
|
|
3164
|
+
state.replay.timeline = null;
|
|
3165
|
+
state.replay.cursor = 0;
|
|
3166
|
+
state.replay.offsetAt = 0;
|
|
3167
|
+
state.replay.playing = false;
|
|
3168
|
+
if (!sessionId) { renderReplay(); return; }
|
|
3169
|
+
var el = document.getElementById('view-replay');
|
|
3170
|
+
el.innerHTML = '<div class="loading">Loading replay…</div>';
|
|
3171
|
+
var res = await apiGet('replay/load?sessionId=' + encodeURIComponent(sessionId));
|
|
3172
|
+
if (res && res.success && res.timeline) {
|
|
3173
|
+
state.replay.timeline = res.timeline;
|
|
3174
|
+
} else {
|
|
3175
|
+
state.replay.timeline = { events: [], eventCount: 0, totalDurationMs: 0 };
|
|
3176
|
+
}
|
|
3177
|
+
renderReplay();
|
|
3178
|
+
}
|
|
3179
|
+
|
|
3180
|
+
function toggleReplayPlay() {
|
|
3181
|
+
if (!state.replay.timeline || state.replay.timeline.eventCount === 0) return;
|
|
3182
|
+
if (state.replay.playing) {
|
|
3183
|
+
stopReplayTimer();
|
|
3184
|
+
} else {
|
|
3185
|
+
startReplayTimer();
|
|
3186
|
+
}
|
|
3187
|
+
renderReplay();
|
|
3188
|
+
}
|
|
3189
|
+
|
|
3190
|
+
function startReplayTimer() {
|
|
3191
|
+
state.replay.playing = true;
|
|
3192
|
+
state.replay.startAt = Date.now();
|
|
3193
|
+
var baseOffset = state.replay.offsetAt;
|
|
3194
|
+
if (state.replay.timer) clearInterval(state.replay.timer);
|
|
3195
|
+
state.replay.timer = setInterval(function() {
|
|
3196
|
+
if (!state.replay.timeline) return;
|
|
3197
|
+
var elapsed = (Date.now() - state.replay.startAt) * state.replay.speed;
|
|
3198
|
+
state.replay.offsetAt = baseOffset + elapsed;
|
|
3199
|
+
var events = state.replay.timeline.events;
|
|
3200
|
+
var newCursor = state.replay.cursor;
|
|
3201
|
+
for (var i = newCursor; i < events.length; i++) {
|
|
3202
|
+
if (events[i].offsetMs <= state.replay.offsetAt) newCursor = i;
|
|
3203
|
+
else break;
|
|
3204
|
+
}
|
|
3205
|
+
var changed = newCursor !== state.replay.cursor;
|
|
3206
|
+
state.replay.cursor = newCursor;
|
|
3207
|
+
if (state.replay.offsetAt >= state.replay.timeline.totalDurationMs) {
|
|
3208
|
+
state.replay.offsetAt = state.replay.timeline.totalDurationMs;
|
|
3209
|
+
stopReplayTimer();
|
|
3210
|
+
renderReplay();
|
|
3211
|
+
return;
|
|
3212
|
+
}
|
|
3213
|
+
if (changed) renderReplay();
|
|
3214
|
+
}, 100);
|
|
3215
|
+
}
|
|
3216
|
+
|
|
3217
|
+
function stopReplayTimer() {
|
|
3218
|
+
state.replay.playing = false;
|
|
3219
|
+
if (state.replay.timer) {
|
|
3220
|
+
clearInterval(state.replay.timer);
|
|
3221
|
+
state.replay.timer = null;
|
|
3222
|
+
}
|
|
3223
|
+
}
|
|
3224
|
+
|
|
3225
|
+
function stepReplay(dir) {
|
|
3226
|
+
if (!state.replay.timeline) return;
|
|
3227
|
+
stopReplayTimer();
|
|
3228
|
+
var next = state.replay.cursor + dir;
|
|
3229
|
+
if (next < 0) next = 0;
|
|
3230
|
+
if (next >= state.replay.timeline.eventCount) next = state.replay.timeline.eventCount - 1;
|
|
3231
|
+
state.replay.cursor = next;
|
|
3232
|
+
state.replay.offsetAt = state.replay.timeline.events[next].offsetMs;
|
|
3233
|
+
renderReplay();
|
|
3234
|
+
}
|
|
3235
|
+
|
|
3236
|
+
function setReplaySpeed(sp) {
|
|
3237
|
+
if (!sp || sp <= 0) return;
|
|
3238
|
+
var wasPlaying = state.replay.playing;
|
|
3239
|
+
stopReplayTimer();
|
|
3240
|
+
state.replay.speed = sp;
|
|
3241
|
+
if (wasPlaying) startReplayTimer();
|
|
3242
|
+
renderReplay();
|
|
3243
|
+
}
|
|
3244
|
+
|
|
3245
|
+
function resetReplay() {
|
|
3246
|
+
stopReplayTimer();
|
|
3247
|
+
state.replay.cursor = 0;
|
|
3248
|
+
state.replay.offsetAt = 0;
|
|
3249
|
+
renderReplay();
|
|
3250
|
+
}
|
|
3251
|
+
|
|
3252
|
+
async function runReplayImport() {
|
|
3253
|
+
var input = document.getElementById('replay-import-path');
|
|
3254
|
+
var pathVal = input ? input.value.trim() : '';
|
|
3255
|
+
var body = {};
|
|
3256
|
+
if (pathVal) body.path = pathVal;
|
|
3257
|
+
var el = document.getElementById('view-replay');
|
|
3258
|
+
var prior = el.innerHTML;
|
|
3259
|
+
el.innerHTML = '<div class="loading">Importing JSONL…</div>';
|
|
3260
|
+
var res = await apiPost('replay/import-jsonl', body);
|
|
3261
|
+
if (!res || res.success === false) {
|
|
3262
|
+
el.innerHTML = prior;
|
|
3263
|
+
alert((res && res.error) || 'Import failed');
|
|
3264
|
+
return;
|
|
3265
|
+
}
|
|
3266
|
+
alert('Imported ' + (res.imported || 0) + ' file(s), ' + (res.observations || 0) + ' observation(s)');
|
|
3267
|
+
await refreshReplaySessions();
|
|
3268
|
+
}
|
|
3269
|
+
|
|
3270
|
+
document.addEventListener('keydown', function(e) {
|
|
3271
|
+
if (state.activeTab !== 'replay') return;
|
|
3272
|
+
if (e.target && (e.target.tagName === 'INPUT' || e.target.tagName === 'SELECT' || e.target.tagName === 'TEXTAREA')) return;
|
|
3273
|
+
if (e.key === ' ') { e.preventDefault(); toggleReplayPlay(); }
|
|
3274
|
+
else if (e.key === 'ArrowLeft') { e.preventDefault(); stepReplay(-1); }
|
|
3275
|
+
else if (e.key === 'ArrowRight') { e.preventDefault(); stepReplay(1); }
|
|
3276
|
+
});
|
|
3277
|
+
|
|
3014
3278
|
loadTab('dashboard');
|
|
3015
3279
|
connectWs();
|
|
3016
3280
|
startDashboardAutoRefresh();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentmemory",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Persistent memory for AI coding agents -- captures tool usage, compresses via LLM, injects context into future sessions. 12 hooks,
|
|
3
|
+
"version": "0.9.0",
|
|
4
|
+
"description": "Persistent memory for AI coding agents -- captures tool usage, compresses via LLM, injects context into future sessions. 12 hooks, 44 MCP tools, 4 skills, real-time viewer.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Rohit Ghumare",
|
|
7
7
|
"url": "https://github.com/rohitg00"
|