superlocalmemory 3.6.13 → 3.6.15
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/marketplace.json +17 -0
- package/CHANGELOG.md +28 -0
- package/README.md +189 -740
- package/package.json +12 -5
- package/plugin/.claude-plugin/plugin.json +20 -0
- package/plugin/.mcp.json +12 -0
- package/plugin/CLAUDE.md +44 -0
- package/plugin/_GENERATED.md +6 -0
- package/plugin/agents/slm-memory-advisor.md +44 -0
- package/plugin/agents/slm-optimize-advisor.md +38 -0
- package/plugin/hooks/hooks.json +14 -0
- package/plugin/requirements.txt +1 -0
- package/plugin/scripts/ensure-venv.bat +122 -0
- package/plugin/scripts/ensure-venv.sh +105 -0
- package/plugin/scripts/slm-launch +15 -0
- package/plugin/scripts/slm-launch.bat +17 -0
- package/plugin/settings.json +16 -0
- package/plugin/skills/slm-cache/SKILL.md +140 -0
- package/plugin/skills/slm-compress/SKILL.md +143 -0
- package/plugin/skills/slm-graph/SKILL.md +300 -0
- package/plugin/skills/slm-recall/SKILL.md +204 -0
- package/plugin/skills/slm-remember/SKILL.md +194 -0
- package/plugin/skills/slm-session/SKILL.md +207 -0
- package/plugin/skills/slm-status/SKILL.md +149 -0
- package/plugin-src/.mcp.json +12 -0
- package/plugin-src/agents/slm-memory-advisor.md +44 -0
- package/plugin-src/agents/slm-optimize-advisor.md +38 -0
- package/plugin-src/commands/slm-optimize.md +22 -0
- package/plugin-src/commands/slm-recall.md +16 -0
- package/plugin-src/commands/slm-remember.md +16 -0
- package/plugin-src/commands/slm-status.md +15 -0
- package/plugin-src/hooks/.gitkeep +0 -0
- package/plugin-src/hooks/hooks.json +14 -0
- package/plugin-src/manifest.json +25 -0
- package/plugin-src/requirements.txt +1 -0
- package/plugin-src/rules/AGENTS.md +91 -0
- package/plugin-src/rules/CLAUDE.md.fragment +44 -0
- package/plugin-src/scripts/ensure-venv.bat +122 -0
- package/plugin-src/scripts/ensure-venv.sh +105 -0
- package/plugin-src/scripts/slm-launch +15 -0
- package/plugin-src/scripts/slm-launch.bat +17 -0
- package/plugin-src/settings.json +16 -0
- package/plugin-src/skills/slm-cache/SKILL.md +140 -0
- package/plugin-src/skills/slm-compress/SKILL.md +143 -0
- package/plugin-src/skills/slm-graph/SKILL.md +300 -0
- package/plugin-src/skills/slm-recall/SKILL.md +204 -0
- package/plugin-src/skills/slm-remember/SKILL.md +194 -0
- package/plugin-src/skills/slm-session/SKILL.md +207 -0
- package/plugin-src/skills/slm-status/SKILL.md +149 -0
- package/pyproject.toml +6 -2
- package/scripts/__tests__/build-plugin.test.mjs +613 -0
- package/scripts/_savings_math.py +270 -0
- package/scripts/build-plugin.js +742 -0
- package/scripts/dogfood_savings.py +490 -0
- package/scripts/install-skills.ps1 +4 -334
- package/scripts/install-skills.sh +4 -435
- package/scripts/postinstall-interactive.js +0 -27
- package/scripts/postinstall.js +21 -2
- package/src/superlocalmemory/__init__.py +1 -1
- package/src/superlocalmemory/cli/_lazy_init.py +115 -0
- package/src/superlocalmemory/cli/commands.py +439 -41
- package/src/superlocalmemory/cli/main.py +92 -4
- package/src/superlocalmemory/cli/setup_wizard.py +47 -6
- package/src/superlocalmemory/core/backend_orchestrator.py +12 -8
- package/src/superlocalmemory/core/config.py +194 -9
- package/src/superlocalmemory/core/embeddings.py +10 -5
- package/src/superlocalmemory/core/engine.py +76 -5
- package/src/superlocalmemory/core/fact_consolidator.py +20 -3
- package/src/superlocalmemory/core/platform_utils.py +8 -0
- package/src/superlocalmemory/core/recall_pipeline.py +7 -0
- package/src/superlocalmemory/core/recall_worker.py +7 -0
- package/src/superlocalmemory/core/store_pipeline.py +23 -1
- package/src/superlocalmemory/core/worker_pool.py +14 -2
- package/src/superlocalmemory/hooks/claude_code_hooks.py +27 -3
- package/src/superlocalmemory/hooks/portable_kit.py +506 -0
- package/src/superlocalmemory/hooks/session_registry.py +8 -4
- package/src/superlocalmemory/infra/cloud_backup.py +99 -23
- package/src/superlocalmemory/mcp/_daemon_proxy.py +12 -2
- package/src/superlocalmemory/mcp/_pool_adapter.py +15 -6
- package/src/superlocalmemory/mcp/cli_fallback.py +602 -0
- package/src/superlocalmemory/mcp/server.py +75 -4
- package/src/superlocalmemory/mcp/tools_code_graph.py +3 -3
- package/src/superlocalmemory/mcp/tools_core.py +37 -4
- package/src/superlocalmemory/mcp/tools_v3.py +6 -1
- package/src/superlocalmemory/mcp/tools_v33.py +8 -4
- package/src/superlocalmemory/optimize/cache/boundary_store.py +25 -6
- package/src/superlocalmemory/optimize/cache/centroid_store.py +27 -4
- package/src/superlocalmemory/optimize/cache/manager.py +92 -6
- package/src/superlocalmemory/optimize/cache/semantic.py +20 -1
- package/src/superlocalmemory/optimize/compress/ccr.py +12 -0
- package/src/superlocalmemory/optimize/compress/router.py +46 -13
- package/src/superlocalmemory/optimize/config/schema.py +6 -0
- package/src/superlocalmemory/optimize/proxy/_helpers.py +111 -8
- package/src/superlocalmemory/optimize/proxy/anthropic_surface.py +14 -4
- package/src/superlocalmemory/optimize/proxy/gemini_surface.py +23 -6
- package/src/superlocalmemory/optimize/proxy/openai_surface.py +10 -4
- package/src/superlocalmemory/optimize/proxy/server.py +11 -0
- package/src/superlocalmemory/optimize/proxy/vertex_surface.py +246 -0
- package/src/superlocalmemory/optimize/storage/db.py +30 -0
- package/src/superlocalmemory/retrieval/bm25_channel.py +12 -2
- package/src/superlocalmemory/retrieval/engine.py +36 -3
- package/src/superlocalmemory/retrieval/entity_channel.py +5 -5
- package/src/superlocalmemory/retrieval/hopfield_channel.py +10 -2
- package/src/superlocalmemory/retrieval/semantic_channel.py +10 -2
- package/src/superlocalmemory/server/recall_serializer.py +3 -1
- package/src/superlocalmemory/server/unified_daemon.py +156 -16
- package/src/superlocalmemory/storage/database.py +215 -43
- package/src/superlocalmemory/storage/migration_runner.py +17 -1
- package/src/superlocalmemory/storage/migrations/M016_add_scope_support.py +120 -0
- package/src/superlocalmemory/storage/models.py +10 -0
- package/src/superlocalmemory/storage/schema.py +15 -10
- package/src/superlocalmemory/ui/css/legacy-dashboard.css +18 -0
- package/src/superlocalmemory/ui/css/neural-glass.css +5 -0
- package/src/superlocalmemory/ui/index.html +2 -2
- package/src/superlocalmemory/ui/js/core.js +98 -0
- package/src/superlocalmemory/ui/js/dashboard.js +8 -1
- package/src/superlocalmemory/ui/js/ide-status.js +16 -3
- package/src/superlocalmemory/ui/js/math-health.js +15 -3
- package/src/superlocalmemory/ui/js/optimize.js +18 -2
- package/src/superlocalmemory/ui/js/trust-dashboard.js +10 -1
- package/src/superlocalmemory.egg-info/PKG-INFO +191 -741
- package/src/superlocalmemory.egg-info/SOURCES.txt +7 -9
- package/src/superlocalmemory.egg-info/requires.txt +1 -0
- package/ide/skills/slm-build-graph/SKILL.md +0 -423
- package/ide/skills/slm-list-recent/SKILL.md +0 -348
- package/ide/skills/slm-recall/SKILL.md +0 -326
- package/ide/skills/slm-remember/SKILL.md +0 -194
- package/ide/skills/slm-show-patterns/SKILL.md +0 -224
- package/ide/skills/slm-status/SKILL.md +0 -363
- package/ide/skills/slm-switch-profile/SKILL.md +0 -442
- package/skills/slm-build-graph/SKILL.md +0 -423
- package/skills/slm-list-recent/SKILL.md +0 -348
- package/skills/slm-optimize/README.md +0 -55
- package/skills/slm-optimize/SKILL.md +0 -139
- package/skills/slm-recall/SKILL.md +0 -343
- package/skills/slm-remember/SKILL.md +0 -194
- package/skills/slm-show-patterns/SKILL.md +0 -224
- package/skills/slm-status/SKILL.md +0 -363
- package/skills/slm-switch-profile/SKILL.md +0 -442
- package/src/superlocalmemory/cli/doctor_cmd.py +0 -152
- package/src/superlocalmemory/skills/slm-build-graph/SKILL.md +0 -423
- package/src/superlocalmemory/skills/slm-list-recent/SKILL.md +0 -348
- package/src/superlocalmemory/skills/slm-recall/SKILL.md +0 -343
- package/src/superlocalmemory/skills/slm-remember/SKILL.md +0 -194
- package/src/superlocalmemory/skills/slm-show-patterns/SKILL.md +0 -224
- package/src/superlocalmemory/skills/slm-status/SKILL.md +0 -363
- package/src/superlocalmemory/skills/slm-switch-profile/SKILL.md +0 -442
|
@@ -110,6 +110,8 @@ _SQL_MEMORIES: Final[str] = """
|
|
|
110
110
|
CREATE TABLE IF NOT EXISTS memories (
|
|
111
111
|
memory_id TEXT PRIMARY KEY,
|
|
112
112
|
profile_id TEXT NOT NULL DEFAULT 'default',
|
|
113
|
+
scope TEXT NOT NULL DEFAULT 'personal',
|
|
114
|
+
shared_with TEXT,
|
|
113
115
|
content TEXT NOT NULL,
|
|
114
116
|
session_id TEXT NOT NULL DEFAULT '',
|
|
115
117
|
speaker TEXT NOT NULL DEFAULT '',
|
|
@@ -127,8 +129,7 @@ CREATE INDEX IF NOT EXISTS idx_memories_profile
|
|
|
127
129
|
CREATE INDEX IF NOT EXISTS idx_memories_session
|
|
128
130
|
ON memories (profile_id, session_id);
|
|
129
131
|
CREATE INDEX IF NOT EXISTS idx_memories_created
|
|
130
|
-
ON memories (created_at);
|
|
131
|
-
"""
|
|
132
|
+
ON memories (created_at);"""
|
|
132
133
|
|
|
133
134
|
|
|
134
135
|
# ---------------------------------------------------------------------------
|
|
@@ -140,6 +141,8 @@ CREATE TABLE IF NOT EXISTS atomic_facts (
|
|
|
140
141
|
fact_id TEXT PRIMARY KEY,
|
|
141
142
|
memory_id TEXT NOT NULL,
|
|
142
143
|
profile_id TEXT NOT NULL DEFAULT 'default',
|
|
144
|
+
scope TEXT NOT NULL DEFAULT 'personal',
|
|
145
|
+
shared_with TEXT,
|
|
143
146
|
content TEXT NOT NULL,
|
|
144
147
|
fact_type TEXT NOT NULL DEFAULT 'semantic'
|
|
145
148
|
CHECK (fact_type IN (
|
|
@@ -208,8 +211,7 @@ CREATE INDEX IF NOT EXISTS idx_facts_referenced_date
|
|
|
208
211
|
WHERE referenced_date IS NOT NULL;
|
|
209
212
|
CREATE INDEX IF NOT EXISTS idx_facts_interval
|
|
210
213
|
ON atomic_facts (profile_id, interval_start, interval_end)
|
|
211
|
-
WHERE interval_start IS NOT NULL;
|
|
212
|
-
"""
|
|
214
|
+
WHERE interval_start IS NOT NULL;"""
|
|
213
215
|
|
|
214
216
|
|
|
215
217
|
# ---------------------------------------------------------------------------
|
|
@@ -287,6 +289,8 @@ _SQL_CANONICAL_ENTITIES: Final[str] = """
|
|
|
287
289
|
CREATE TABLE IF NOT EXISTS canonical_entities (
|
|
288
290
|
entity_id TEXT PRIMARY KEY,
|
|
289
291
|
profile_id TEXT NOT NULL DEFAULT 'default',
|
|
292
|
+
scope TEXT NOT NULL DEFAULT 'personal',
|
|
293
|
+
shared_with TEXT,
|
|
290
294
|
canonical_name TEXT NOT NULL,
|
|
291
295
|
entity_type TEXT NOT NULL DEFAULT '',
|
|
292
296
|
first_seen TEXT NOT NULL DEFAULT (datetime('now')),
|
|
@@ -302,8 +306,7 @@ CREATE INDEX IF NOT EXISTS idx_entities_profile
|
|
|
302
306
|
CREATE INDEX IF NOT EXISTS idx_entities_name_lower
|
|
303
307
|
ON canonical_entities (profile_id, canonical_name COLLATE NOCASE);
|
|
304
308
|
CREATE INDEX IF NOT EXISTS idx_entities_type
|
|
305
|
-
ON canonical_entities (profile_id, entity_type);
|
|
306
|
-
"""
|
|
309
|
+
ON canonical_entities (profile_id, entity_type);"""
|
|
307
310
|
|
|
308
311
|
|
|
309
312
|
# ---------------------------------------------------------------------------
|
|
@@ -386,6 +389,8 @@ _SQL_TEMPORAL_EVENTS: Final[str] = """
|
|
|
386
389
|
CREATE TABLE IF NOT EXISTS temporal_events (
|
|
387
390
|
event_id TEXT PRIMARY KEY,
|
|
388
391
|
profile_id TEXT NOT NULL DEFAULT 'default',
|
|
392
|
+
scope TEXT NOT NULL DEFAULT 'personal',
|
|
393
|
+
shared_with TEXT,
|
|
389
394
|
entity_id TEXT NOT NULL,
|
|
390
395
|
fact_id TEXT NOT NULL,
|
|
391
396
|
observation_date TEXT,
|
|
@@ -408,8 +413,7 @@ CREATE INDEX IF NOT EXISTS idx_tevents_entity
|
|
|
408
413
|
ON temporal_events (profile_id, entity_id);
|
|
409
414
|
CREATE INDEX IF NOT EXISTS idx_tevents_date_range
|
|
410
415
|
ON temporal_events (profile_id, referenced_date)
|
|
411
|
-
WHERE referenced_date IS NOT NULL;
|
|
412
|
-
"""
|
|
416
|
+
WHERE referenced_date IS NOT NULL;"""
|
|
413
417
|
|
|
414
418
|
|
|
415
419
|
# ---------------------------------------------------------------------------
|
|
@@ -420,6 +424,8 @@ _SQL_GRAPH_EDGES: Final[str] = """
|
|
|
420
424
|
CREATE TABLE IF NOT EXISTS graph_edges (
|
|
421
425
|
edge_id TEXT PRIMARY KEY,
|
|
422
426
|
profile_id TEXT NOT NULL DEFAULT 'default',
|
|
427
|
+
scope TEXT NOT NULL DEFAULT 'personal',
|
|
428
|
+
shared_with TEXT,
|
|
423
429
|
source_id TEXT NOT NULL,
|
|
424
430
|
target_id TEXT NOT NULL,
|
|
425
431
|
edge_type TEXT NOT NULL DEFAULT 'entity'
|
|
@@ -443,8 +449,7 @@ CREATE INDEX IF NOT EXISTS idx_edges_target
|
|
|
443
449
|
CREATE INDEX IF NOT EXISTS idx_edges_type
|
|
444
450
|
ON graph_edges (profile_id, edge_type);
|
|
445
451
|
CREATE INDEX IF NOT EXISTS idx_edges_exists_check
|
|
446
|
-
ON graph_edges (profile_id, source_id, target_id, edge_type);
|
|
447
|
-
"""
|
|
452
|
+
ON graph_edges (profile_id, source_id, target_id, edge_type);"""
|
|
448
453
|
|
|
449
454
|
|
|
450
455
|
# ---------------------------------------------------------------------------
|
|
@@ -202,6 +202,24 @@
|
|
|
202
202
|
margin-bottom: 12px;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
/* Pane error state — WP-12 */
|
|
206
|
+
.pane-error {
|
|
207
|
+
text-align: center;
|
|
208
|
+
padding: 40px;
|
|
209
|
+
color: var(--bs-danger, #dc3545);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.pane-error i {
|
|
213
|
+
font-size: 2rem;
|
|
214
|
+
display: block;
|
|
215
|
+
margin-bottom: 8px;
|
|
216
|
+
opacity: 0.7;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.pane-error p {
|
|
220
|
+
margin-bottom: 12px;
|
|
221
|
+
}
|
|
222
|
+
|
|
205
223
|
.tooltip-custom {
|
|
206
224
|
position: absolute;
|
|
207
225
|
padding: 10px;
|
|
@@ -1242,7 +1242,7 @@
|
|
|
1242
1242
|
</div>
|
|
1243
1243
|
<div class="card-body">
|
|
1244
1244
|
<div class="row g-3">
|
|
1245
|
-
<div class="col-md-6">
|
|
1245
|
+
<div class="col-md-6" id="optimize-config-card">
|
|
1246
1246
|
<h6>Controls</h6>
|
|
1247
1247
|
<div class="form-check form-switch mb-2">
|
|
1248
1248
|
<input class="form-check-input" type="checkbox" id="opt-enabled">
|
|
@@ -1282,7 +1282,7 @@
|
|
|
1282
1282
|
<label class="form-check-label" for="opt-compress-prose">Prose Compression</label>
|
|
1283
1283
|
</div>
|
|
1284
1284
|
</div>
|
|
1285
|
-
<div class="col-md-6">
|
|
1285
|
+
<div class="col-md-6" id="optimize-savings-card">
|
|
1286
1286
|
<h6>Savings</h6>
|
|
1287
1287
|
<table class="table table-sm">
|
|
1288
1288
|
<tr><td>Tokens Saved</td><td id="opt-tokens-saved">-</td></tr>
|
|
@@ -199,6 +199,104 @@ function showEmpty(containerId, icon, message) {
|
|
|
199
199
|
el.appendChild(wrapper);
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
+
// ============================================================================
|
|
203
|
+
// Pane error state — WP-12
|
|
204
|
+
// showPaneError / clearPaneError / paneErrorMessage
|
|
205
|
+
// ============================================================================
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Map an HTTP status (or 0 for network failure) to a user-readable message.
|
|
209
|
+
* @param {number} status 0 = network/abort, ≥400 = HTTP error
|
|
210
|
+
* @returns {string}
|
|
211
|
+
*/
|
|
212
|
+
function paneErrorMessage(status) {
|
|
213
|
+
if (!status || status === 0) {
|
|
214
|
+
return 'Service unavailable — check network connection';
|
|
215
|
+
}
|
|
216
|
+
if (status >= 500) {
|
|
217
|
+
return 'Server error ' + status + ' — daemon may be down';
|
|
218
|
+
}
|
|
219
|
+
return 'Request failed ' + status;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Render an inline error banner inside a pane container.
|
|
224
|
+
*
|
|
225
|
+
* slotMode=false (container panes — math-health, ide-status):
|
|
226
|
+
* Clears the container and appends the error div directly.
|
|
227
|
+
*
|
|
228
|
+
* slotMode=true (field-scatter panes — dashboard, trust, optimize):
|
|
229
|
+
* Inserts/replaces a #<containerId>-error-slot div at the top of the
|
|
230
|
+
* container, leaving existing field values visible.
|
|
231
|
+
*
|
|
232
|
+
* @param {string} containerId - getElementById target
|
|
233
|
+
* @param {string} message - user-facing message (set via textContent — XSS-safe)
|
|
234
|
+
* @param {Function|null} onRetry - callback for Retry button; null = no button
|
|
235
|
+
* @param {boolean} slotMode - true for field-scatter panes
|
|
236
|
+
*/
|
|
237
|
+
function showPaneError(containerId, message, onRetry, slotMode) {
|
|
238
|
+
var el = document.getElementById(containerId);
|
|
239
|
+
if (!el) return;
|
|
240
|
+
|
|
241
|
+
// Build the error div
|
|
242
|
+
var errDiv = document.createElement('div');
|
|
243
|
+
errDiv.className = 'pane-error';
|
|
244
|
+
errDiv.setAttribute('role', 'alert');
|
|
245
|
+
|
|
246
|
+
var icon = document.createElement('i');
|
|
247
|
+
icon.className = 'bi bi-exclamation-triangle';
|
|
248
|
+
errDiv.appendChild(icon);
|
|
249
|
+
|
|
250
|
+
var p = document.createElement('p');
|
|
251
|
+
p.textContent = message; // textContent — no XSS risk
|
|
252
|
+
errDiv.appendChild(p);
|
|
253
|
+
|
|
254
|
+
if (typeof onRetry === 'function') {
|
|
255
|
+
var btn = document.createElement('button');
|
|
256
|
+
btn.className = 'btn btn-sm btn-outline-danger pane-error-retry';
|
|
257
|
+
btn.textContent = 'Retry';
|
|
258
|
+
// Capture onRetry lexically to avoid closure issues in IIFEs (CRIT-1)
|
|
259
|
+
(function(cb) {
|
|
260
|
+
btn.addEventListener('click', function() { cb(); });
|
|
261
|
+
}(onRetry));
|
|
262
|
+
errDiv.appendChild(btn);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (slotMode) {
|
|
266
|
+
// Insert/replace error slot at top of container
|
|
267
|
+
var slotId = containerId + '-error-slot';
|
|
268
|
+
errDiv.id = slotId;
|
|
269
|
+
var existing = document.getElementById(slotId);
|
|
270
|
+
if (existing) {
|
|
271
|
+
existing.parentNode.replaceChild(errDiv, existing);
|
|
272
|
+
} else {
|
|
273
|
+
el.insertBefore(errDiv, el.firstChild);
|
|
274
|
+
}
|
|
275
|
+
} else {
|
|
276
|
+
// Replace container contents
|
|
277
|
+
el.textContent = '';
|
|
278
|
+
el.appendChild(errDiv);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Remove the error state previously set by showPaneError.
|
|
284
|
+
*
|
|
285
|
+
* @param {string} containerId - getElementById target
|
|
286
|
+
* @param {boolean} slotMode - must match the slotMode used in showPaneError
|
|
287
|
+
*/
|
|
288
|
+
function clearPaneError(containerId, slotMode) {
|
|
289
|
+
if (slotMode) {
|
|
290
|
+
var slot = document.getElementById(containerId + '-error-slot');
|
|
291
|
+
if (slot && slot.parentNode) slot.parentNode.removeChild(slot);
|
|
292
|
+
} else {
|
|
293
|
+
var el = document.getElementById(containerId);
|
|
294
|
+
if (!el) return;
|
|
295
|
+
var err = el.querySelector('.pane-error');
|
|
296
|
+
if (err) el.removeChild(err);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
202
300
|
// ============================================================================
|
|
203
301
|
// Safe HTML builder — tagged template for escaped interpolation
|
|
204
302
|
// ============================================================================
|
|
@@ -17,11 +17,17 @@ window.addEventListener('hashchange', function() {
|
|
|
17
17
|
window.addEventListener('focus', function() { loadDashboard(); });
|
|
18
18
|
|
|
19
19
|
async function loadDashboard() {
|
|
20
|
+
var PANE_ID = 'dashboard-pane';
|
|
20
21
|
try {
|
|
21
22
|
var response = await fetch('/api/v3/dashboard');
|
|
22
|
-
if (!response.ok)
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
showPaneError(PANE_ID, paneErrorMessage(response.status), loadDashboard, true);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
23
27
|
var data = await response.json();
|
|
24
28
|
|
|
29
|
+
clearPaneError(PANE_ID, true);
|
|
30
|
+
|
|
25
31
|
document.getElementById('dashboard-mode').textContent = 'Mode ' + data.mode.toUpperCase();
|
|
26
32
|
document.getElementById('dashboard-mode-desc').textContent = data.mode_name + (data.provider !== 'none' ? ' — ' + data.provider : '');
|
|
27
33
|
document.getElementById('dashboard-memory-count').textContent = data.fact_count || data.memory_count || '0';
|
|
@@ -44,6 +50,7 @@ async function loadDashboard() {
|
|
|
44
50
|
btn.classList.toggle('active', btn.dataset.mode === data.mode);
|
|
45
51
|
});
|
|
46
52
|
} catch (e) {
|
|
53
|
+
showPaneError(PANE_ID, paneErrorMessage(0), loadDashboard, true);
|
|
47
54
|
console.log('Dashboard load error:', e);
|
|
48
55
|
}
|
|
49
56
|
}
|
|
@@ -2,14 +2,26 @@
|
|
|
2
2
|
// Displays detected IDEs and allows connecting them to SLM.
|
|
3
3
|
|
|
4
4
|
async function loadIDEStatus() {
|
|
5
|
+
var CID = 'ide-list-body';
|
|
5
6
|
try {
|
|
6
7
|
var response = await fetch('/api/v3/ide/status');
|
|
7
|
-
if (!response.ok)
|
|
8
|
+
if (!response.ok) {
|
|
9
|
+
showPaneError(CID, paneErrorMessage(response.status), loadIDEStatus, false);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
8
12
|
var data = await response.json();
|
|
9
13
|
|
|
10
|
-
var
|
|
14
|
+
var ides = data.ides || [];
|
|
15
|
+
|
|
16
|
+
// AC5: empty array → empty state
|
|
17
|
+
if (ides.length === 0) {
|
|
18
|
+
showEmpty(CID, 'laptop', 'No IDEs detected');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
var tbody = document.getElementById(CID);
|
|
11
23
|
tbody.textContent = '';
|
|
12
|
-
|
|
24
|
+
ides.forEach(function(ide) {
|
|
13
25
|
var tr = document.createElement('tr');
|
|
14
26
|
|
|
15
27
|
// IDE name cell
|
|
@@ -52,6 +64,7 @@ async function loadIDEStatus() {
|
|
|
52
64
|
tbody.appendChild(tr);
|
|
53
65
|
});
|
|
54
66
|
} catch (e) {
|
|
67
|
+
showPaneError('ide-list-body', paneErrorMessage(0), loadIDEStatus, false);
|
|
55
68
|
console.log('IDE status error:', e);
|
|
56
69
|
}
|
|
57
70
|
}
|
|
@@ -2,15 +2,26 @@
|
|
|
2
2
|
// Displays status of Fisher-Rao, sheaf cohomology, and Langevin dynamics layers.
|
|
3
3
|
|
|
4
4
|
async function loadMathHealth() {
|
|
5
|
+
var CID = 'math-health-cards';
|
|
5
6
|
try {
|
|
6
7
|
var response = await fetch('/api/v3/math/health');
|
|
7
|
-
if (!response.ok)
|
|
8
|
+
if (!response.ok) {
|
|
9
|
+
showPaneError(CID, paneErrorMessage(response.status), loadMathHealth, false);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
8
12
|
var data = await response.json();
|
|
9
13
|
|
|
10
|
-
var
|
|
14
|
+
var layers = data.health || {};
|
|
15
|
+
|
|
16
|
+
// AC5: empty object → empty state
|
|
17
|
+
if (!layers || Object.keys(layers).length === 0) {
|
|
18
|
+
showEmpty(CID, 'calculator', 'No math health data available');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
var container = document.getElementById(CID);
|
|
11
23
|
container.textContent = '';
|
|
12
24
|
|
|
13
|
-
var layers = data.health || {};
|
|
14
25
|
var colors = { fisher: 'primary', sheaf: 'success', langevin: 'info' };
|
|
15
26
|
var icons = { fisher: 'bi-graph-up', sheaf: 'bi-diagram-3', langevin: 'bi-activity' };
|
|
16
27
|
|
|
@@ -91,6 +102,7 @@ async function loadMathHealth() {
|
|
|
91
102
|
container.appendChild(col);
|
|
92
103
|
});
|
|
93
104
|
} catch (e) {
|
|
105
|
+
showPaneError('math-health-cards', paneErrorMessage(0), loadMathHealth, false);
|
|
94
106
|
console.log('Math health error:', e);
|
|
95
107
|
}
|
|
96
108
|
}
|
|
@@ -17,11 +17,17 @@
|
|
|
17
17
|
_pollTimer = setInterval(_loadSavings, 10000);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
var CFG_CARD = 'optimize-config-card';
|
|
21
|
+
|
|
20
22
|
async function _loadOptimizeConfig() {
|
|
21
23
|
try {
|
|
22
24
|
var resp = await fetch('/api/optimize/config');
|
|
23
|
-
if (!resp.ok)
|
|
25
|
+
if (!resp.ok) {
|
|
26
|
+
showPaneError(CFG_CARD, paneErrorMessage(resp.status), _loadOptimizeConfig, true);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
24
29
|
var cfg = await resp.json();
|
|
30
|
+
clearPaneError(CFG_CARD, true);
|
|
25
31
|
_setToggle('opt-enabled', cfg.enabled);
|
|
26
32
|
_setToggle('opt-proxy-enabled', cfg.proxy_enabled);
|
|
27
33
|
_setToggle('opt-cache-enabled', cfg.cache_enabled);
|
|
@@ -32,15 +38,23 @@
|
|
|
32
38
|
var verEl = document.getElementById('opt-config-version');
|
|
33
39
|
if (verEl) verEl.textContent = cfg.config_version || '-';
|
|
34
40
|
} catch (e) {
|
|
41
|
+
showPaneError(CFG_CARD, paneErrorMessage(0), _loadOptimizeConfig, true);
|
|
35
42
|
console.log('Optimize config load error:', e);
|
|
36
43
|
}
|
|
37
44
|
}
|
|
38
45
|
|
|
46
|
+
var SAV_CARD = 'optimize-savings-card';
|
|
47
|
+
|
|
39
48
|
async function _loadSavings() {
|
|
40
49
|
try {
|
|
41
50
|
var resp = await fetch('/api/optimize/savings');
|
|
42
|
-
if (!resp.ok)
|
|
51
|
+
if (!resp.ok) {
|
|
52
|
+
// D-3: no Retry on polling loader \u2014 auto-heals on next poll
|
|
53
|
+
showPaneError(SAV_CARD, paneErrorMessage(resp.status), null, true);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
43
56
|
var data = await resp.json();
|
|
57
|
+
clearPaneError(SAV_CARD, true);
|
|
44
58
|
var tokensSaved = (data.tokens_saved_input || 0) + (data.tokens_saved_output || 0) + (data.tokens_saved_compress || 0);
|
|
45
59
|
_setText('opt-tokens-saved', tokensSaved.toLocaleString());
|
|
46
60
|
var costSaved = data.cost_saved || {};
|
|
@@ -57,6 +71,8 @@
|
|
|
57
71
|
_setText('opt-stale-warning', 'Pricing data may be outdated');
|
|
58
72
|
}
|
|
59
73
|
} catch (e) {
|
|
74
|
+
// D-3: no Retry on polling loader
|
|
75
|
+
showPaneError(SAV_CARD, paneErrorMessage(0), null, true);
|
|
60
76
|
console.log('Savings load error:', e);
|
|
61
77
|
}
|
|
62
78
|
}
|
|
@@ -127,12 +127,20 @@
|
|
|
127
127
|
if (next) next.disabled = STATE.page >= maxPage;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
var TRUST_PANE_ID = 'operations-pane';
|
|
131
|
+
|
|
130
132
|
async function loadTrustDashboard() {
|
|
131
133
|
try {
|
|
132
134
|
var resp = await fetch('/api/v3/trust/dashboard');
|
|
133
|
-
if (!resp.ok)
|
|
135
|
+
if (!resp.ok) {
|
|
136
|
+
// CRIT-1: pass lexically-scoped loadTrustDashboard (inside IIFE)
|
|
137
|
+
showPaneError(TRUST_PANE_ID, paneErrorMessage(resp.status), loadTrustDashboard, true);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
134
140
|
var data = await resp.json();
|
|
135
141
|
|
|
142
|
+
clearPaneError(TRUST_PANE_ID, true);
|
|
143
|
+
|
|
136
144
|
var agents = data.agents || [];
|
|
137
145
|
STATE.agents = agents;
|
|
138
146
|
STATE.page = 0;
|
|
@@ -154,6 +162,7 @@
|
|
|
154
162
|
|
|
155
163
|
_renderPage();
|
|
156
164
|
} catch (e) {
|
|
165
|
+
showPaneError(TRUST_PANE_ID, paneErrorMessage(0), loadTrustDashboard, true);
|
|
157
166
|
if (window.console && window.console.debug) {
|
|
158
167
|
window.console.debug('Trust dashboard error:', e);
|
|
159
168
|
}
|