@agentmemory/agentmemory 0.8.1 → 0.8.5

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/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { getContext, init } from "iii-sdk";
3
3
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
4
- import { dirname, join, resolve } from "node:path";
4
+ import { dirname, join, resolve, sep } from "node:path";
5
5
  import { homedir } from "node:os";
6
6
  import Anthropic from "@anthropic-ai/sdk";
7
7
  import { createHash, createHmac, randomBytes, timingSafeEqual } from "node:crypto";
@@ -902,7 +902,8 @@ const KV = {
902
902
  graphEdgeHistory: "mem:graph:edge-history",
903
903
  enrichedChunks: (sessionId) => `mem:enriched:${sessionId}`,
904
904
  latentEmbeddings: (obsId) => `mem:latent:${obsId}`,
905
- retentionScores: "mem:retention"
905
+ retentionScores: "mem:retention",
906
+ accessLog: "mem:access"
906
907
  };
907
908
  const STREAM = {
908
909
  name: "mem-live",
@@ -1951,9 +1952,11 @@ var IndexPersistence = class {
1951
1952
  const PRIVATE_TAG_RE = /<private>[\s\S]*?<\/private>/gi;
1952
1953
  const SECRET_PATTERN_SOURCES = [
1953
1954
  /(?:api[_-]?key|secret|token|password|credential|auth)[\s]*[=:]\s*["']?[A-Za-z0-9_\-/.+]{20,}["']?/gi,
1954
- /(?:sk|pk|rk|ak)-[A-Za-z0-9]{20,}/g,
1955
+ /Bearer\s+[A-Za-z0-9._\-+/=]{20,}/gi,
1956
+ /sk-proj-[A-Za-z0-9\-_]{20,}/g,
1957
+ /(?:sk|pk|rk|ak)-[A-Za-z0-9][A-Za-z0-9\-_]{19,}/g,
1955
1958
  /sk-ant-[A-Za-z0-9\-_]{20,}/g,
1956
- /ghp_[A-Za-z0-9]{36}/g,
1959
+ /gh[pus]_[A-Za-z0-9]{36,}/g,
1957
1960
  /github_pat_[A-Za-z0-9_]{22,}/g,
1958
1961
  /xoxb-[A-Za-z0-9\-]+/g,
1959
1962
  /AKIA[0-9A-Z]{16}/g,
@@ -2154,6 +2157,77 @@ function getXmlChildren(xml, parentTag, childTag) {
2154
2157
  return items;
2155
2158
  }
2156
2159
 
2160
+ //#endregion
2161
+ //#region src/functions/access-tracker.ts
2162
+ const RECENT_CAP = 20;
2163
+ function emptyAccessLog(memoryId) {
2164
+ return {
2165
+ memoryId,
2166
+ count: 0,
2167
+ lastAt: "",
2168
+ recent: []
2169
+ };
2170
+ }
2171
+ function normalizeAccessLog(raw) {
2172
+ const r = raw ?? {};
2173
+ const rawCount = typeof r.count === "number" && Number.isFinite(r.count) ? r.count : 0;
2174
+ const count = Math.max(0, Math.floor(rawCount));
2175
+ const rawRecent = Array.isArray(r.recent) ? r.recent.filter((x) => typeof x === "number" && Number.isFinite(x)) : [];
2176
+ const recent = rawRecent.length > RECENT_CAP ? rawRecent.slice(-RECENT_CAP) : rawRecent;
2177
+ return {
2178
+ memoryId: typeof r.memoryId === "string" ? r.memoryId : "",
2179
+ count: Math.max(count, recent.length),
2180
+ lastAt: typeof r.lastAt === "string" ? r.lastAt : "",
2181
+ recent
2182
+ };
2183
+ }
2184
+ async function getAccessLog(kv, memoryId) {
2185
+ try {
2186
+ const raw = await kv.get(KV.accessLog, memoryId);
2187
+ if (!raw) return emptyAccessLog(memoryId);
2188
+ const normalized = normalizeAccessLog(raw);
2189
+ if (!normalized.memoryId) normalized.memoryId = memoryId;
2190
+ return normalized;
2191
+ } catch {
2192
+ return emptyAccessLog(memoryId);
2193
+ }
2194
+ }
2195
+ async function recordAccess(kv, memoryId, timestampMs) {
2196
+ if (!memoryId) return;
2197
+ const ts = timestampMs ?? Date.now();
2198
+ try {
2199
+ await withKeyedLock(`mem:access:${memoryId}`, async () => {
2200
+ const existing = await getAccessLog(kv, memoryId);
2201
+ existing.count += 1;
2202
+ existing.lastAt = new Date(ts).toISOString();
2203
+ existing.recent.push(ts);
2204
+ if (existing.recent.length > RECENT_CAP) existing.recent = existing.recent.slice(-RECENT_CAP);
2205
+ await kv.set(KV.accessLog, memoryId, existing);
2206
+ });
2207
+ } catch (err) {
2208
+ try {
2209
+ getContext().logger.warn("recordAccess failed", {
2210
+ memoryId,
2211
+ error: err instanceof Error ? err.message : String(err)
2212
+ });
2213
+ } catch {}
2214
+ }
2215
+ }
2216
+ async function recordAccessBatch(kv, memoryIds, timestampMs) {
2217
+ if (!memoryIds || memoryIds.length === 0) return;
2218
+ const ts = timestampMs ?? Date.now();
2219
+ const unique = Array.from(new Set(memoryIds.filter(Boolean)));
2220
+ await Promise.allSettled(unique.map((id) => recordAccess(kv, id, ts)));
2221
+ }
2222
+ async function deleteAccessLog(kv, memoryId) {
2223
+ if (!memoryId) return;
2224
+ try {
2225
+ await withKeyedLock(`mem:access:${memoryId}`, async () => {
2226
+ await kv.delete(KV.accessLog, memoryId);
2227
+ });
2228
+ } catch {}
2229
+ }
2230
+
2157
2231
  //#endregion
2158
2232
  //#region src/functions/search.ts
2159
2233
  let index = null;
@@ -2240,6 +2314,7 @@ function registerSearchFunction(sdk, kv) {
2240
2314
  sessionId: candidates[i].sessionId
2241
2315
  });
2242
2316
  }
2317
+ recordAccessBatch(kv, enriched.map((r) => r.observation.id));
2243
2318
  ctx.logger.info("Search completed", {
2244
2319
  query,
2245
2320
  results: enriched.length,
@@ -2635,19 +2710,22 @@ function registerContextFunction(sdk, kv, tokenBudget) {
2635
2710
  const i = sessionsNeedingObs[j];
2636
2711
  const important = obsResults[j].filter((o) => o.title && o.importance >= 5);
2637
2712
  if (important.length > 0) {
2638
- const items = important.sort((a, b) => b.importance - a.importance).slice(0, 5).map((o) => `- [${o.type}] ${o.title}: ${o.narrative}`).join("\n");
2713
+ const top = important.sort((a, b) => b.importance - a.importance).slice(0, 5);
2714
+ const items = top.map((o) => `- [${o.type}] ${o.title}: ${o.narrative}`).join("\n");
2639
2715
  const content = `## Session ${sessions[i].id.slice(0, 8)} (${sessions[i].startedAt})\n${items}`;
2640
2716
  blocks.push({
2641
2717
  type: "observation",
2642
2718
  content,
2643
2719
  tokens: estimateTokens$1(content),
2644
- recency: new Date(sessions[i].startedAt).getTime()
2720
+ recency: new Date(sessions[i].startedAt).getTime(),
2721
+ sourceIds: top.map((o) => o.id)
2645
2722
  });
2646
2723
  }
2647
2724
  }
2648
2725
  blocks.sort((a, b) => b.recency - a.recency);
2649
2726
  let usedTokens = 0;
2650
2727
  const selected = [];
2728
+ const accessedIds = [];
2651
2729
  const header = `<agentmemory-context project="${escapeXmlAttr(data.project)}">`;
2652
2730
  const footer = `</agentmemory-context>`;
2653
2731
  usedTokens += estimateTokens$1(header) + estimateTokens$1(footer);
@@ -2655,7 +2733,9 @@ function registerContextFunction(sdk, kv, tokenBudget) {
2655
2733
  if (usedTokens + block.tokens > budget) break;
2656
2734
  selected.push(block.content);
2657
2735
  usedTokens += block.tokens;
2736
+ if (block.sourceIds && block.sourceIds.length > 0) accessedIds.push(...block.sourceIds);
2658
2737
  }
2738
+ if (accessedIds.length > 0) recordAccessBatch(kv, accessedIds);
2659
2739
  if (selected.length === 0) {
2660
2740
  ctx.logger.info("No context available", { project: data.project });
2661
2741
  return {
@@ -2988,6 +3068,9 @@ function registerFileIndexFunction(sdk, kv) {
2988
3068
  for (const obs of fh.observations) lines.push(`- [${obs.type}] ${obs.title}: ${obs.narrative}`);
2989
3069
  }
2990
3070
  lines.push("</agentmemory-file-context>");
3071
+ const accessedIds = [];
3072
+ for (const fh of results) for (const obs of fh.observations) accessedIds.push(obs.obsId);
3073
+ recordAccessBatch(kv, accessedIds);
2991
3074
  const context = lines.join("\n");
2992
3075
  ctx.logger.info("File context generated", {
2993
3076
  files: data.files.length,
@@ -3300,6 +3383,7 @@ function registerRememberFunction(sdk, kv) {
3300
3383
  let deleted = 0;
3301
3384
  if (data.memoryId) {
3302
3385
  await kv.delete(KV.memories, data.memoryId);
3386
+ await deleteAccessLog(kv, data.memoryId);
3303
3387
  deleted++;
3304
3388
  }
3305
3389
  if (data.sessionId && data.observationIds && data.observationIds.length > 0) for (const obsId of data.observationIds) {
@@ -3391,13 +3475,19 @@ function registerEvictFunction(sdk, kv) {
3391
3475
  if (now > new Date(mem.forgetAfter).getTime()) {
3392
3476
  stats.expiredMemories++;
3393
3477
  evictedMemIds.add(mem.id);
3394
- if (!dryRun) await kv.delete(KV.memories, mem.id).catch(() => {});
3478
+ if (!dryRun) {
3479
+ await kv.delete(KV.memories, mem.id).catch(() => {});
3480
+ await deleteAccessLog(kv, mem.id);
3481
+ }
3395
3482
  }
3396
3483
  }
3397
3484
  if (!evictedMemIds.has(mem.id) && mem.isLatest === false && mem.createdAt) {
3398
3485
  if (now - new Date(mem.createdAt).getTime() > cfg.lowImportanceMaxDays * MS_PER_DAY$1) {
3399
3486
  stats.nonLatestMemories++;
3400
- if (!dryRun) await kv.delete(KV.memories, mem.id).catch(() => {});
3487
+ if (!dryRun) {
3488
+ await kv.delete(KV.memories, mem.id).catch(() => {});
3489
+ await deleteAccessLog(kv, mem.id);
3490
+ }
3401
3491
  }
3402
3492
  }
3403
3493
  }
@@ -3562,6 +3652,7 @@ function registerRelationsFunction(sdk, kv) {
3562
3652
  });
3563
3653
  }
3564
3654
  result.sort((a, b) => b.confidence - a.confidence);
3655
+ recordAccessBatch(kv, result.map((r) => r.memory.id));
3565
3656
  ctx.logger.info("Related memories retrieved", {
3566
3657
  memoryId: data.memoryId,
3567
3658
  found: result.length
@@ -3633,6 +3724,7 @@ function registerTimelineFunction(sdk, kv) {
3633
3724
  relativePosition: i - anchorIdx
3634
3725
  });
3635
3726
  }
3727
+ recordAccessBatch(kv, entries.map((e) => e.observation.id));
3636
3728
  ctx.logger.info("Timeline retrieved", {
3637
3729
  anchor: data.anchor,
3638
3730
  entries: entries.length
@@ -3683,6 +3775,7 @@ function registerSmartSearchFunction(sdk, kv, searchFn) {
3683
3775
  observation: obs
3684
3776
  } : null)));
3685
3777
  for (const r of results) if (r) expanded.push(r);
3778
+ recordAccessBatch(kv, expanded.map((e) => e.observation.id));
3686
3779
  const truncated = data.expandIds.length > raw.length;
3687
3780
  ctx.logger.info("Smart search expanded", {
3688
3781
  requested: data.expandIds.length,
@@ -3710,6 +3803,7 @@ function registerSmartSearchFunction(sdk, kv, searchFn) {
3710
3803
  score: r.combinedScore,
3711
3804
  timestamp: r.observation.timestamp
3712
3805
  }));
3806
+ recordAccessBatch(kv, compact.map((r) => r.obsId));
3713
3807
  ctx.logger.info("Smart search compact", {
3714
3808
  query: data.query,
3715
3809
  results: compact.length
@@ -3841,7 +3935,10 @@ function registerAutoForgetFunction(sdk, kv) {
3841
3935
  if (now > new Date(mem.forgetAfter).getTime()) {
3842
3936
  result.ttlExpired.push(mem.id);
3843
3937
  deletedIds.add(mem.id);
3844
- if (!dryRun) await kv.delete(KV.memories, mem.id);
3938
+ if (!dryRun) {
3939
+ await kv.delete(KV.memories, mem.id);
3940
+ await deleteAccessLog(kv, mem.id);
3941
+ }
3845
3942
  }
3846
3943
  }
3847
3944
  const latestMemories = memories.filter((m) => m.isLatest !== false && !deletedIds.has(m.id)).sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()).slice(0, 1e3);
@@ -3910,7 +4007,7 @@ function registerAutoForgetFunction(sdk, kv) {
3910
4007
 
3911
4008
  //#endregion
3912
4009
  //#region src/version.ts
3913
- const VERSION = "0.8.1";
4010
+ const VERSION = "0.8.5";
3914
4011
 
3915
4012
  //#endregion
3916
4013
  //#region src/functions/export-import.ts
@@ -3938,7 +4035,7 @@ function registerExportImportFunction(sdk, kv) {
3938
4035
  const uniqueProjects = [...new Set(paginatedSessions.map((s) => s.project))];
3939
4036
  const profileResults = await Promise.all(uniqueProjects.map((project) => kv.get(KV.profiles, project).catch(() => null)));
3940
4037
  for (const profile of profileResults) if (profile) profiles.push(profile);
3941
- const [graphNodes, graphEdges, semanticMemories, proceduralMemories, actions, actionEdges, sentinels, sketches, crystals, facets, lessons, insights, routines, signals, checkpoints] = await Promise.all([
4038
+ const [graphNodes, graphEdges, semanticMemories, proceduralMemories, actions, actionEdges, sentinels, sketches, crystals, facets, lessons, insights, routines, signals, checkpoints, accessLogs] = await Promise.all([
3942
4039
  kv.list(KV.graphNodes).catch(() => []),
3943
4040
  kv.list(KV.graphEdges).catch(() => []),
3944
4041
  kv.list(KV.semantic).catch(() => []),
@@ -3953,7 +4050,8 @@ function registerExportImportFunction(sdk, kv) {
3953
4050
  kv.list(KV.insights).catch(() => []),
3954
4051
  kv.list(KV.routines).catch(() => []),
3955
4052
  kv.list(KV.signals).catch(() => []),
3956
- kv.list(KV.checkpoints).catch(() => [])
4053
+ kv.list(KV.checkpoints).catch(() => []),
4054
+ kv.list(KV.accessLog).catch(() => [])
3957
4055
  ]);
3958
4056
  const exportData = {
3959
4057
  version: VERSION,
@@ -3977,7 +4075,8 @@ function registerExportImportFunction(sdk, kv) {
3977
4075
  insights: insights.length > 0 ? insights : void 0,
3978
4076
  routines: routines.length > 0 ? routines : void 0,
3979
4077
  signals: signals.length > 0 ? signals : void 0,
3980
- checkpoints: checkpoints.length > 0 ? checkpoints : void 0
4078
+ checkpoints: checkpoints.length > 0 ? checkpoints : void 0,
4079
+ accessLogs: accessLogs.length > 0 ? accessLogs : void 0
3981
4080
  };
3982
4081
  if (maxSessions !== void 0) exportData.pagination = {
3983
4082
  offset,
@@ -4017,7 +4116,11 @@ function registerExportImportFunction(sdk, kv) {
4017
4116
  "0.7.7",
4018
4117
  "0.7.9",
4019
4118
  "0.8.0",
4020
- "0.8.1"
4119
+ "0.8.1",
4120
+ "0.8.2",
4121
+ "0.8.3",
4122
+ "0.8.4",
4123
+ "0.8.5"
4021
4124
  ]).has(importData.version)) return {
4022
4125
  success: false,
4023
4126
  error: `Unsupported export version: ${importData.version}`
@@ -4027,6 +4130,7 @@ function registerExportImportFunction(sdk, kv) {
4027
4130
  const MAX_SUMMARIES = 1e4;
4028
4131
  const MAX_OBS_PER_SESSION = 5e3;
4029
4132
  const MAX_TOTAL_OBSERVATIONS = 5e5;
4133
+ const MAX_ACCESS_LOGS = 5e4;
4030
4134
  if (!Array.isArray(importData.sessions)) return {
4031
4135
  success: false,
4032
4136
  error: "sessions must be an array"
@@ -4109,6 +4213,7 @@ function registerExportImportFunction(sdk, kv) {
4109
4213
  for (const e of await kv.list(KV.graphEdges).catch(() => [])) await kv.delete(KV.graphEdges, e.id);
4110
4214
  for (const s of await kv.list(KV.semantic).catch(() => [])) await kv.delete(KV.semantic, s.id);
4111
4215
  for (const p of await kv.list(KV.procedural).catch(() => [])) await kv.delete(KV.procedural, p.id);
4216
+ for (const a of await kv.list(KV.accessLog).catch(() => [])) await kv.delete(KV.accessLog, a.memoryId);
4112
4217
  }
4113
4218
  for (const session of importData.sessions) {
4114
4219
  if (strategy === "skip") {
@@ -4285,6 +4390,28 @@ function registerExportImportFunction(sdk, kv) {
4285
4390
  }
4286
4391
  await kv.set(KV.insights, insight.id, insight);
4287
4392
  }
4393
+ if (importData.accessLogs) {
4394
+ if (!Array.isArray(importData.accessLogs)) return {
4395
+ success: false,
4396
+ error: "accessLogs must be an array"
4397
+ };
4398
+ if (importData.accessLogs.length > MAX_ACCESS_LOGS) return {
4399
+ success: false,
4400
+ error: `Too many access logs (max ${MAX_ACCESS_LOGS})`
4401
+ };
4402
+ const memoryIds = new Set(importData.memories.map((m) => m.id));
4403
+ for (const raw of importData.accessLogs) {
4404
+ const log = normalizeAccessLog(raw);
4405
+ if (!log.memoryId || !memoryIds.has(log.memoryId)) continue;
4406
+ if (strategy === "skip") {
4407
+ if (await kv.get(KV.accessLog, log.memoryId).catch(() => null)) {
4408
+ stats.skipped++;
4409
+ continue;
4410
+ }
4411
+ }
4412
+ await kv.set(KV.accessLog, log.memoryId, log);
4413
+ }
4414
+ }
4288
4415
  ctx.logger.info("Import complete", {
4289
4416
  strategy,
4290
4417
  ...stats
@@ -5053,6 +5180,7 @@ function registerGovernanceFunction(sdk, kv) {
5053
5180
  let deleted = 0;
5054
5181
  for (const id of data.memoryIds) if (await kv.get(KV.memories, id)) {
5055
5182
  await kv.delete(KV.memories, id);
5183
+ await deleteAccessLog(kv, id);
5056
5184
  deleted++;
5057
5185
  }
5058
5186
  await recordAudit(kv, "delete", "mem::governance-delete", data.memoryIds, {
@@ -5100,7 +5228,10 @@ function registerGovernanceFunction(sdk, kv) {
5100
5228
  wouldDelete: candidates.length,
5101
5229
  ids: candidates.map((m) => m.id)
5102
5230
  };
5103
- for (const mem of candidates) await kv.delete(KV.memories, mem.id);
5231
+ for (const mem of candidates) {
5232
+ await kv.delete(KV.memories, mem.id);
5233
+ await deleteAccessLog(kv, mem.id);
5234
+ }
5104
5235
  await recordAudit(kv, "delete", "mem::governance-bulk", candidates.map((m) => m.id), {
5105
5236
  filter: data,
5106
5237
  deleted: candidates.length
@@ -5148,6 +5279,7 @@ function registerSnapshotFunction(sdk, kv, snapshotDir) {
5148
5279
  const sessions = await kv.list(KV.sessions);
5149
5280
  const memories = await kv.list(KV.memories);
5150
5281
  const graphNodes = await kv.list(KV.graphNodes);
5282
+ const accessLogs = await kv.list(KV.accessLog).catch(() => []);
5151
5283
  const observations = {};
5152
5284
  for (const session of sessions) {
5153
5285
  const obs = await kv.list(KV.observations(session.id)).catch(() => []);
@@ -5159,7 +5291,8 @@ function registerSnapshotFunction(sdk, kv, snapshotDir) {
5159
5291
  sessions,
5160
5292
  memories,
5161
5293
  graphNodes,
5162
- observations
5294
+ observations,
5295
+ accessLogs
5163
5296
  };
5164
5297
  writeFileSync(join(snapshotDir, "state.json"), JSON.stringify(state, null, 2), "utf-8");
5165
5298
  await gitExec(snapshotDir, ["add", "."]);
@@ -5251,6 +5384,7 @@ function registerSnapshotFunction(sdk, kv, snapshotDir) {
5251
5384
  if (state.memories) for (const memory of state.memories) await kv.set(KV.memories, memory.id, memory);
5252
5385
  if (state.graphNodes) for (const node of state.graphNodes) await kv.set(KV.graphNodes, node.id, node);
5253
5386
  if (state.observations) for (const [sessionId, obs] of Object.entries(state.observations)) for (const o of obs) await kv.set(KV.observations(sessionId), o.id, o);
5387
+ if (state.accessLogs) for (const log of state.accessLogs) await kv.set(KV.accessLog, log.memoryId, log);
5254
5388
  await gitExec(snapshotDir, [
5255
5389
  "checkout",
5256
5390
  "HEAD",
@@ -6418,7 +6552,7 @@ async function lwwMergeGraphNodes(kv, items) {
6418
6552
  }
6419
6553
  return count;
6420
6554
  }
6421
- function registerMeshFunction(sdk, kv) {
6555
+ function registerMeshFunction(sdk, kv, meshAuthToken) {
6422
6556
  sdk.registerFunction({ id: "mem::mesh-register" }, async (data) => {
6423
6557
  if (!data.url || !data.name) return {
6424
6558
  success: false,
@@ -6455,6 +6589,10 @@ function registerMeshFunction(sdk, kv) {
6455
6589
  };
6456
6590
  });
6457
6591
  sdk.registerFunction({ id: "mem::mesh-sync" }, async (data) => {
6592
+ if (!meshAuthToken) return {
6593
+ success: false,
6594
+ error: "mesh sync requires AGENTMEMORY_SECRET"
6595
+ };
6458
6596
  const direction = data.direction || "both";
6459
6597
  let peers;
6460
6598
  if (data.peerId) {
@@ -6490,7 +6628,10 @@ function registerMeshFunction(sdk, kv) {
6490
6628
  try {
6491
6629
  const response = await fetch(`${peer.url}/agentmemory/mesh/receive`, {
6492
6630
  method: "POST",
6493
- headers: { "Content-Type": "application/json" },
6631
+ headers: {
6632
+ "Content-Type": "application/json",
6633
+ Authorization: `Bearer ${meshAuthToken}`
6634
+ },
6494
6635
  body: JSON.stringify(pushData),
6495
6636
  signal: AbortSignal.timeout(3e4),
6496
6637
  redirect: "error"
@@ -6503,6 +6644,7 @@ function registerMeshFunction(sdk, kv) {
6503
6644
  }
6504
6645
  if (direction === "pull" || direction === "both") try {
6505
6646
  const response = await fetch(`${peer.url}/agentmemory/mesh/export?since=${peer.lastSyncAt || ""}`, {
6647
+ headers: { Authorization: `Bearer ${meshAuthToken}` },
6506
6648
  signal: AbortSignal.timeout(3e4),
6507
6649
  redirect: "error"
6508
6650
  });
@@ -8363,7 +8505,16 @@ function registerLessonsFunctions(sdk, kv) {
8363
8505
 
8364
8506
  //#endregion
8365
8507
  //#region src/functions/obsidian-export.ts
8366
- const DEFAULT_VAULT = join(homedir(), ".agentmemory", "vault");
8508
+ const DEFAULT_EXPORT_ROOT = join(homedir(), ".agentmemory");
8509
+ function getExportRoot() {
8510
+ return resolve(process.env["AGENTMEMORY_EXPORT_ROOT"] || DEFAULT_EXPORT_ROOT);
8511
+ }
8512
+ function resolveVaultDir(vaultDir) {
8513
+ const root = getExportRoot();
8514
+ const resolved = resolve(vaultDir || join(root, "vault"));
8515
+ if (resolved === root || resolved.startsWith(root + sep)) return resolved;
8516
+ return null;
8517
+ }
8367
8518
  function sanitize(name) {
8368
8519
  return name.replace(/[<>:"/\\|?*\x00-\x1f]/g, "_").slice(0, 100);
8369
8520
  }
@@ -8476,7 +8627,11 @@ function sessionToMd(s) {
8476
8627
  }
8477
8628
  function registerObsidianExportFunction(sdk, kv) {
8478
8629
  sdk.registerFunction({ id: "mem::obsidian-export" }, async (data) => {
8479
- const vaultDir = data.vaultDir || DEFAULT_VAULT;
8630
+ const vaultDir = resolveVaultDir(data.vaultDir);
8631
+ if (!vaultDir) return {
8632
+ success: false,
8633
+ error: `vaultDir must be inside ${getExportRoot()}`
8634
+ };
8480
8635
  const exportTypes = new Set(data.types || [
8481
8636
  "memories",
8482
8637
  "lessons",
@@ -9022,12 +9177,15 @@ function registerWorkingMemoryFunctions(sdk, kv, tokenBudget) {
9022
9177
  if (Math.abs(strengthDiff) > .2) return strengthDiff;
9023
9178
  return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
9024
9179
  });
9180
+ const archivalIds = [];
9025
9181
  for (const mem of active) {
9026
9182
  const tokens = estimateTokens(mem.content);
9027
9183
  if (usedTokens + tokens > budget) continue;
9028
9184
  archivalLines.push(`- [${mem.type}] ${mem.title}: ${mem.content}`);
9185
+ archivalIds.push(mem.id);
9029
9186
  usedTokens += tokens;
9030
9187
  }
9188
+ recordAccessBatch(kv, archivalIds);
9031
9189
  const pagedOut = active.length - archivalLines.length;
9032
9190
  const sections = [];
9033
9191
  if (coreLines.length > 0) sections.push(`## Core Memory\n${coreLines.join("\n")}`);
@@ -9781,17 +9939,15 @@ const DEFAULT_DECAY = {
9781
9939
  cold: .15
9782
9940
  }
9783
9941
  };
9784
- function computeRetention(salience, createdAt, accessTimestamps, config) {
9942
+ function computeReinforcementBoost(accessTimestamps, sigma) {
9785
9943
  const now = Date.now();
9786
- const deltaT = (now - new Date(createdAt).getTime()) / (1e3 * 60 * 60 * 24);
9787
- const temporalDecay = Math.exp(-config.lambda * deltaT);
9788
- let reinforcementBoost = 0;
9944
+ let boost = 0;
9789
9945
  for (const tAccess of accessTimestamps) {
9946
+ if (!Number.isFinite(tAccess)) continue;
9790
9947
  const daysSinceAccess = (now - tAccess) / (1e3 * 60 * 60 * 24);
9791
- if (daysSinceAccess > 0) reinforcementBoost += 1 / daysSinceAccess;
9948
+ if (daysSinceAccess > 0) boost += 1 / daysSinceAccess;
9792
9949
  }
9793
- reinforcementBoost *= config.sigma;
9794
- return Math.min(1, salience * temporalDecay + reinforcementBoost);
9950
+ return boost * sigma;
9795
9951
  }
9796
9952
  function computeSalience(memory, accessCount) {
9797
9953
  let baseSalience = .5;
@@ -9817,37 +9973,64 @@ function registerRetentionFunctions(sdk, kv) {
9817
9973
  ...DEFAULT_DECAY,
9818
9974
  ...data.config
9819
9975
  };
9820
- const memories = await kv.list(KV.memories);
9821
- const semanticMems = await kv.list(KV.semantic);
9976
+ const [memories, semanticMems, allLogs] = await Promise.all([
9977
+ kv.list(KV.memories),
9978
+ kv.list(KV.semantic),
9979
+ kv.list(KV.accessLog).catch(() => [])
9980
+ ]);
9981
+ const logsById = /* @__PURE__ */ new Map();
9982
+ for (const raw of allLogs) {
9983
+ const log = normalizeAccessLog(raw);
9984
+ if (log.memoryId) logsById.set(log.memoryId, log);
9985
+ }
9822
9986
  const scores = [];
9987
+ const computeDecay = (createdAt) => Math.exp(-config.lambda * ((Date.now() - new Date(createdAt).getTime()) / (1e3 * 60 * 60 * 24)));
9823
9988
  for (const mem of memories) {
9824
9989
  if (!mem.isLatest) continue;
9825
- const salience = computeSalience(mem, 0);
9826
- const score = computeRetention(salience, mem.createdAt, [], config);
9990
+ const log = logsById.get(mem.id) ?? emptyAccessLog(mem.id);
9991
+ const salience = computeSalience(mem, log.count);
9992
+ const temporalDecay = computeDecay(mem.createdAt);
9993
+ const reinforcementBoost = computeReinforcementBoost(log.recent, config.sigma);
9994
+ const score = Math.min(1, salience * temporalDecay + reinforcementBoost);
9827
9995
  const entry = {
9828
9996
  memoryId: mem.id,
9829
9997
  score,
9830
9998
  salience,
9831
- temporalDecay: Math.exp(-config.lambda * ((Date.now() - new Date(mem.createdAt).getTime()) / (1e3 * 60 * 60 * 24))),
9832
- reinforcementBoost: 0,
9833
- lastAccessed: mem.updatedAt,
9834
- accessCount: 0
9999
+ temporalDecay,
10000
+ reinforcementBoost,
10001
+ lastAccessed: log.lastAt || mem.updatedAt,
10002
+ accessCount: log.count
9835
10003
  };
9836
10004
  scores.push(entry);
9837
10005
  await kv.set(KV.retentionScores, mem.id, entry);
9838
10006
  }
9839
10007
  for (const sem of semanticMems) {
9840
- const accessTimestamps = sem.lastAccessedAt ? [new Date(sem.lastAccessedAt).getTime()] : [];
9841
- const salience = computeSalience(sem, sem.accessCount);
9842
- const score = computeRetention(salience, sem.createdAt, accessTimestamps, config);
10008
+ const log = logsById.get(sem.id) ?? emptyAccessLog(sem.id);
10009
+ let accessTimestamps;
10010
+ let effectiveCount;
10011
+ if (log.recent.length > 0 || log.count > 0) {
10012
+ accessTimestamps = log.recent;
10013
+ effectiveCount = log.count;
10014
+ } else if (sem.lastAccessedAt) {
10015
+ const legacyTs = Date.parse(sem.lastAccessedAt);
10016
+ accessTimestamps = Number.isFinite(legacyTs) ? [legacyTs] : [];
10017
+ effectiveCount = sem.accessCount;
10018
+ } else {
10019
+ accessTimestamps = [];
10020
+ effectiveCount = sem.accessCount;
10021
+ }
10022
+ const salience = computeSalience(sem, effectiveCount);
10023
+ const temporalDecay = computeDecay(sem.createdAt);
10024
+ const reinforcementBoost = computeReinforcementBoost(accessTimestamps, config.sigma);
10025
+ const score = Math.min(1, salience * temporalDecay + reinforcementBoost);
9843
10026
  const entry = {
9844
10027
  memoryId: sem.id,
9845
10028
  score,
9846
10029
  salience,
9847
- temporalDecay: Math.exp(-config.lambda * ((Date.now() - new Date(sem.createdAt).getTime()) / (1e3 * 60 * 60 * 24))),
9848
- reinforcementBoost: score - salience * Math.exp(-config.lambda * ((Date.now() - new Date(sem.createdAt).getTime()) / (1e3 * 60 * 60 * 24))),
9849
- lastAccessed: sem.lastAccessedAt,
9850
- accessCount: sem.accessCount
10030
+ temporalDecay,
10031
+ reinforcementBoost,
10032
+ lastAccessed: log.lastAt || sem.lastAccessedAt,
10033
+ accessCount: effectiveCount
9851
10034
  };
9852
10035
  scores.push(entry);
9853
10036
  await kv.set(KV.retentionScores, sem.id, entry);
@@ -9891,6 +10074,7 @@ function registerRetentionFunctions(sdk, kv) {
9891
10074
  for (const candidate of candidates) try {
9892
10075
  await kv.delete(KV.memories, candidate.memoryId);
9893
10076
  await kv.delete(KV.retentionScores, candidate.memoryId);
10077
+ await deleteAccessLog(kv, candidate.memoryId);
9894
10078
  evicted++;
9895
10079
  } catch {
9896
10080
  continue;
@@ -10046,14 +10230,57 @@ async function getLatestHealth(kv) {
10046
10230
  //#endregion
10047
10231
  //#region src/auth.ts
10048
10232
  const hmacKey = randomBytes(32);
10233
+ const VIEWER_NONCE_PLACEHOLDER = "__AGENTMEMORY_VIEWER_NONCE__";
10049
10234
  function timingSafeCompare(a, b) {
10050
10235
  return timingSafeEqual(createHmac("sha256", hmacKey).update(a).digest(), createHmac("sha256", hmacKey).update(b).digest());
10051
10236
  }
10052
- const VIEWER_CSP = "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src 'self' ws://localhost:* wss://localhost:*; img-src 'self'; font-src 'self'";
10237
+ function createViewerNonce() {
10238
+ return randomBytes(16).toString("base64url");
10239
+ }
10240
+ function buildViewerCsp(nonce) {
10241
+ return [
10242
+ "default-src 'none'",
10243
+ "base-uri 'none'",
10244
+ "frame-ancestors 'none'",
10245
+ "object-src 'none'",
10246
+ "form-action 'none'",
10247
+ `script-src 'nonce-${nonce}'`,
10248
+ "script-src-attr 'none'",
10249
+ "style-src 'unsafe-inline'",
10250
+ "connect-src 'self' http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:* wss://localhost:* wss://127.0.0.1:*",
10251
+ "img-src 'self'",
10252
+ "font-src 'self'"
10253
+ ].join("; ");
10254
+ }
10255
+
10256
+ //#endregion
10257
+ //#region src/viewer/document.ts
10258
+ function loadViewerTemplate() {
10259
+ const base = dirname(fileURLToPath(import.meta.url));
10260
+ const candidates = [
10261
+ join(base, "..", "src", "viewer", "index.html"),
10262
+ join(base, "..", "viewer", "index.html"),
10263
+ join(base, "viewer", "index.html")
10264
+ ];
10265
+ for (const path of candidates) try {
10266
+ return readFileSync(path, "utf-8");
10267
+ } catch {}
10268
+ return null;
10269
+ }
10270
+ function renderViewerDocument() {
10271
+ const template = loadViewerTemplate();
10272
+ if (!template) return { found: false };
10273
+ const nonce = createViewerNonce();
10274
+ return {
10275
+ found: true,
10276
+ html: template.replaceAll(VIEWER_NONCE_PLACEHOLDER, nonce),
10277
+ csp: buildViewerCsp(nonce)
10278
+ };
10279
+ }
10053
10280
 
10054
10281
  //#endregion
10055
10282
  //#region src/triggers/api.ts
10056
- function checkAuth$1(req, secret) {
10283
+ function checkAuth(req, secret) {
10057
10284
  if (!secret) return null;
10058
10285
  const auth = req.headers?.["authorization"] || req.headers?.["Authorization"];
10059
10286
  if (typeof auth !== "string" || !timingSafeCompare(auth, `Bearer ${secret}`)) return {
@@ -10062,6 +10289,13 @@ function checkAuth$1(req, secret) {
10062
10289
  };
10063
10290
  return null;
10064
10291
  }
10292
+ function requireConfiguredSecret(secret, feature) {
10293
+ if (secret) return null;
10294
+ return {
10295
+ status_code: 503,
10296
+ body: { error: `${feature} requires AGENTMEMORY_SECRET` }
10297
+ };
10298
+ }
10065
10299
  function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10066
10300
  sdk.registerFunction({ id: "api::liveness" }, async () => ({
10067
10301
  status_code: 200,
@@ -10079,7 +10313,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10079
10313
  }
10080
10314
  });
10081
10315
  sdk.registerFunction({ id: "api::health" }, async (req) => {
10082
- const authErr = checkAuth$1(req, secret);
10316
+ const authErr = checkAuth(req, secret);
10083
10317
  if (authErr) return authErr;
10084
10318
  const health = await getLatestHealth(kv);
10085
10319
  const functionMetrics = metricsStore ? await metricsStore.getAll() : [];
@@ -10106,7 +10340,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10106
10340
  }
10107
10341
  });
10108
10342
  sdk.registerFunction({ id: "api::observe" }, async (req) => {
10109
- const authErr = checkAuth$1(req, secret);
10343
+ const authErr = checkAuth(req, secret);
10110
10344
  if (authErr) return authErr;
10111
10345
  return {
10112
10346
  status_code: 201,
@@ -10122,7 +10356,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10122
10356
  }
10123
10357
  });
10124
10358
  sdk.registerFunction({ id: "api::context" }, async (req) => {
10125
- const authErr = checkAuth$1(req, secret);
10359
+ const authErr = checkAuth(req, secret);
10126
10360
  if (authErr) return authErr;
10127
10361
  return {
10128
10362
  status_code: 200,
@@ -10138,7 +10372,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10138
10372
  }
10139
10373
  });
10140
10374
  sdk.registerFunction({ id: "api::search" }, async (req) => {
10141
- const authErr = checkAuth$1(req, secret);
10375
+ const authErr = checkAuth(req, secret);
10142
10376
  if (authErr) return authErr;
10143
10377
  const body = req.body ?? {};
10144
10378
  if (typeof body.query !== "string" || !body.query.trim()) return {
@@ -10177,7 +10411,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10177
10411
  }
10178
10412
  });
10179
10413
  sdk.registerFunction({ id: "api::session::start" }, async (req) => {
10180
- const authErr = checkAuth$1(req, secret);
10414
+ const authErr = checkAuth(req, secret);
10181
10415
  if (authErr) return authErr;
10182
10416
  const { sessionId, project, cwd } = req.body;
10183
10417
  const session = {
@@ -10209,7 +10443,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10209
10443
  }
10210
10444
  });
10211
10445
  sdk.registerFunction({ id: "api::session::end" }, async (req) => {
10212
- const authErr = checkAuth$1(req, secret);
10446
+ const authErr = checkAuth(req, secret);
10213
10447
  if (authErr) return authErr;
10214
10448
  const session = await kv.get(KV.sessions, req.body.sessionId);
10215
10449
  if (session) await kv.set(KV.sessions, req.body.sessionId, {
@@ -10231,7 +10465,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10231
10465
  }
10232
10466
  });
10233
10467
  sdk.registerFunction({ id: "api::summarize" }, async (req) => {
10234
- const authErr = checkAuth$1(req, secret);
10468
+ const authErr = checkAuth(req, secret);
10235
10469
  if (authErr) return authErr;
10236
10470
  return {
10237
10471
  status_code: 200,
@@ -10247,7 +10481,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10247
10481
  }
10248
10482
  });
10249
10483
  sdk.registerFunction({ id: "api::sessions" }, async (req) => {
10250
- const authErr = checkAuth$1(req, secret);
10484
+ const authErr = checkAuth(req, secret);
10251
10485
  if (authErr) return authErr;
10252
10486
  return {
10253
10487
  status_code: 200,
@@ -10263,7 +10497,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10263
10497
  }
10264
10498
  });
10265
10499
  sdk.registerFunction({ id: "api::observations" }, async (req) => {
10266
- const authErr = checkAuth$1(req, secret);
10500
+ const authErr = checkAuth(req, secret);
10267
10501
  if (authErr) return authErr;
10268
10502
  const sessionId = req.query_params["sessionId"];
10269
10503
  if (!sessionId) return {
@@ -10284,7 +10518,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10284
10518
  }
10285
10519
  });
10286
10520
  sdk.registerFunction({ id: "api::file-context" }, async (req) => {
10287
- const authErr = checkAuth$1(req, secret);
10521
+ const authErr = checkAuth(req, secret);
10288
10522
  if (authErr) return authErr;
10289
10523
  return {
10290
10524
  status_code: 200,
@@ -10300,7 +10534,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10300
10534
  }
10301
10535
  });
10302
10536
  sdk.registerFunction({ id: "api::enrich" }, async (req) => {
10303
- const authErr = checkAuth$1(req, secret);
10537
+ const authErr = checkAuth(req, secret);
10304
10538
  if (authErr) return authErr;
10305
10539
  if (!req.body?.sessionId || typeof req.body.sessionId !== "string" || !Array.isArray(req.body?.files) || req.body.files.length === 0 || !req.body.files.every((f) => typeof f === "string")) return {
10306
10540
  status_code: 400,
@@ -10324,7 +10558,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10324
10558
  }
10325
10559
  });
10326
10560
  sdk.registerFunction({ id: "api::remember" }, async (req) => {
10327
- const authErr = checkAuth$1(req, secret);
10561
+ const authErr = checkAuth(req, secret);
10328
10562
  if (authErr) return authErr;
10329
10563
  if (!req.body?.content || typeof req.body.content !== "string" || !req.body.content.trim()) return {
10330
10564
  status_code: 400,
@@ -10344,7 +10578,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10344
10578
  }
10345
10579
  });
10346
10580
  sdk.registerFunction({ id: "api::forget" }, async (req) => {
10347
- const authErr = checkAuth$1(req, secret);
10581
+ const authErr = checkAuth(req, secret);
10348
10582
  if (authErr) return authErr;
10349
10583
  if (!req.body?.sessionId && !req.body?.memoryId) return {
10350
10584
  status_code: 400,
@@ -10364,7 +10598,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10364
10598
  }
10365
10599
  });
10366
10600
  sdk.registerFunction({ id: "api::consolidate" }, async (req) => {
10367
- const authErr = checkAuth$1(req, secret);
10601
+ const authErr = checkAuth(req, secret);
10368
10602
  if (authErr) return authErr;
10369
10603
  return {
10370
10604
  status_code: 200,
@@ -10380,7 +10614,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10380
10614
  }
10381
10615
  });
10382
10616
  sdk.registerFunction({ id: "api::patterns" }, async (req) => {
10383
- const authErr = checkAuth$1(req, secret);
10617
+ const authErr = checkAuth(req, secret);
10384
10618
  if (authErr) return authErr;
10385
10619
  return {
10386
10620
  status_code: 200,
@@ -10396,7 +10630,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10396
10630
  }
10397
10631
  });
10398
10632
  sdk.registerFunction({ id: "api::generate-rules" }, async (req) => {
10399
- const authErr = checkAuth$1(req, secret);
10633
+ const authErr = checkAuth(req, secret);
10400
10634
  if (authErr) return authErr;
10401
10635
  return {
10402
10636
  status_code: 200,
@@ -10412,7 +10646,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10412
10646
  }
10413
10647
  });
10414
10648
  sdk.registerFunction({ id: "api::migrate" }, async (req) => {
10415
- const authErr = checkAuth$1(req, secret);
10649
+ const authErr = checkAuth(req, secret);
10416
10650
  if (authErr) return authErr;
10417
10651
  if (!req.body?.dbPath || typeof req.body.dbPath !== "string") return {
10418
10652
  status_code: 400,
@@ -10432,7 +10666,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10432
10666
  }
10433
10667
  });
10434
10668
  sdk.registerFunction({ id: "api::evict" }, async (req) => {
10435
- const authErr = checkAuth$1(req, secret);
10669
+ const authErr = checkAuth(req, secret);
10436
10670
  if (authErr) return authErr;
10437
10671
  const dryRun = req.query_params?.["dryRun"] === "true" || req.body?.dryRun === true;
10438
10672
  return {
@@ -10449,7 +10683,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10449
10683
  }
10450
10684
  });
10451
10685
  sdk.registerFunction({ id: "api::smart-search" }, async (req) => {
10452
- const authErr = checkAuth$1(req, secret);
10686
+ const authErr = checkAuth(req, secret);
10453
10687
  if (authErr) return authErr;
10454
10688
  if (!req.body?.query && (!req.body?.expandIds || req.body.expandIds.length === 0)) return {
10455
10689
  status_code: 400,
@@ -10469,7 +10703,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10469
10703
  }
10470
10704
  });
10471
10705
  sdk.registerFunction({ id: "api::timeline" }, async (req) => {
10472
- const authErr = checkAuth$1(req, secret);
10706
+ const authErr = checkAuth(req, secret);
10473
10707
  if (authErr) return authErr;
10474
10708
  if (!req.body?.anchor) return {
10475
10709
  status_code: 400,
@@ -10489,7 +10723,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10489
10723
  }
10490
10724
  });
10491
10725
  sdk.registerFunction({ id: "api::profile" }, async (req) => {
10492
- const authErr = checkAuth$1(req, secret);
10726
+ const authErr = checkAuth(req, secret);
10493
10727
  if (authErr) return authErr;
10494
10728
  const project = req.query_params["project"];
10495
10729
  if (!project) return {
@@ -10510,7 +10744,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10510
10744
  }
10511
10745
  });
10512
10746
  sdk.registerFunction({ id: "api::export" }, async (req) => {
10513
- const authErr = checkAuth$1(req, secret);
10747
+ const authErr = checkAuth(req, secret);
10514
10748
  if (authErr) return authErr;
10515
10749
  return {
10516
10750
  status_code: 200,
@@ -10526,7 +10760,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10526
10760
  }
10527
10761
  });
10528
10762
  sdk.registerFunction({ id: "api::import" }, async (req) => {
10529
- const authErr = checkAuth$1(req, secret);
10763
+ const authErr = checkAuth(req, secret);
10530
10764
  if (authErr) return authErr;
10531
10765
  if (!req.body?.exportData) return {
10532
10766
  status_code: 400,
@@ -10546,7 +10780,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10546
10780
  }
10547
10781
  });
10548
10782
  sdk.registerFunction({ id: "api::relations" }, async (req) => {
10549
- const authErr = checkAuth$1(req, secret);
10783
+ const authErr = checkAuth(req, secret);
10550
10784
  if (authErr) return authErr;
10551
10785
  if (!req.body?.sourceId || !req.body?.targetId || !req.body?.type) return {
10552
10786
  status_code: 400,
@@ -10566,7 +10800,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10566
10800
  }
10567
10801
  });
10568
10802
  sdk.registerFunction({ id: "api::evolve" }, async (req) => {
10569
- const authErr = checkAuth$1(req, secret);
10803
+ const authErr = checkAuth(req, secret);
10570
10804
  if (authErr) return authErr;
10571
10805
  if (!req.body?.memoryId || !req.body?.newContent) return {
10572
10806
  status_code: 400,
@@ -10586,7 +10820,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10586
10820
  }
10587
10821
  });
10588
10822
  sdk.registerFunction({ id: "api::auto-forget" }, async (req) => {
10589
- const authErr = checkAuth$1(req, secret);
10823
+ const authErr = checkAuth(req, secret);
10590
10824
  if (authErr) return authErr;
10591
10825
  const dryRun = req.query_params?.["dryRun"] === "true" || req.body?.dryRun === true;
10592
10826
  return {
@@ -10603,7 +10837,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10603
10837
  }
10604
10838
  });
10605
10839
  sdk.registerFunction({ id: "api::claude-bridge-read" }, async (req) => {
10606
- const authErr = checkAuth$1(req, secret);
10840
+ const authErr = checkAuth(req, secret);
10607
10841
  if (authErr) return authErr;
10608
10842
  try {
10609
10843
  return {
@@ -10626,7 +10860,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10626
10860
  }
10627
10861
  });
10628
10862
  sdk.registerFunction({ id: "api::claude-bridge-sync" }, async (req) => {
10629
- const authErr = checkAuth$1(req, secret);
10863
+ const authErr = checkAuth(req, secret);
10630
10864
  if (authErr) return authErr;
10631
10865
  try {
10632
10866
  return {
@@ -10649,7 +10883,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10649
10883
  }
10650
10884
  });
10651
10885
  sdk.registerFunction({ id: "api::graph-query" }, async (req) => {
10652
- const authErr = checkAuth$1(req, secret);
10886
+ const authErr = checkAuth(req, secret);
10653
10887
  if (authErr) return authErr;
10654
10888
  try {
10655
10889
  return {
@@ -10672,7 +10906,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10672
10906
  }
10673
10907
  });
10674
10908
  sdk.registerFunction({ id: "api::graph-stats" }, async (req) => {
10675
- const authErr = checkAuth$1(req, secret);
10909
+ const authErr = checkAuth(req, secret);
10676
10910
  if (authErr) return authErr;
10677
10911
  try {
10678
10912
  return {
@@ -10695,7 +10929,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10695
10929
  }
10696
10930
  });
10697
10931
  sdk.registerFunction({ id: "api::graph-extract" }, async (req) => {
10698
- const authErr = checkAuth$1(req, secret);
10932
+ const authErr = checkAuth(req, secret);
10699
10933
  if (authErr) return authErr;
10700
10934
  if (!Array.isArray(req.body?.observations) || req.body.observations.length === 0) return {
10701
10935
  status_code: 400,
@@ -10722,7 +10956,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10722
10956
  }
10723
10957
  });
10724
10958
  sdk.registerFunction({ id: "api::consolidate-pipeline" }, async (req) => {
10725
- const authErr = checkAuth$1(req, secret);
10959
+ const authErr = checkAuth(req, secret);
10726
10960
  if (authErr) return authErr;
10727
10961
  try {
10728
10962
  return {
@@ -10745,7 +10979,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10745
10979
  }
10746
10980
  });
10747
10981
  sdk.registerFunction({ id: "api::team-share" }, async (req) => {
10748
- const authErr = checkAuth$1(req, secret);
10982
+ const authErr = checkAuth(req, secret);
10749
10983
  if (authErr) return authErr;
10750
10984
  if (!req.body?.itemId || !req.body?.itemType) return {
10751
10985
  status_code: 400,
@@ -10772,7 +11006,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10772
11006
  }
10773
11007
  });
10774
11008
  sdk.registerFunction({ id: "api::team-feed" }, async (req) => {
10775
- const authErr = checkAuth$1(req, secret);
11009
+ const authErr = checkAuth(req, secret);
10776
11010
  if (authErr) return authErr;
10777
11011
  try {
10778
11012
  const limit = parseInt(req.query_params?.["limit"]) || 20;
@@ -10796,7 +11030,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10796
11030
  }
10797
11031
  });
10798
11032
  sdk.registerFunction({ id: "api::team-profile" }, async (req) => {
10799
- const authErr = checkAuth$1(req, secret);
11033
+ const authErr = checkAuth(req, secret);
10800
11034
  if (authErr) return authErr;
10801
11035
  try {
10802
11036
  return {
@@ -10819,7 +11053,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10819
11053
  }
10820
11054
  });
10821
11055
  sdk.registerFunction({ id: "api::audit" }, async (req) => {
10822
- const authErr = checkAuth$1(req, secret);
11056
+ const authErr = checkAuth(req, secret);
10823
11057
  if (authErr) return authErr;
10824
11058
  return {
10825
11059
  status_code: 200,
@@ -10838,7 +11072,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10838
11072
  }
10839
11073
  });
10840
11074
  sdk.registerFunction({ id: "api::governance-delete" }, async (req) => {
10841
- const authErr = checkAuth$1(req, secret);
11075
+ const authErr = checkAuth(req, secret);
10842
11076
  if (authErr) return authErr;
10843
11077
  if (!req.body?.memoryIds || !Array.isArray(req.body.memoryIds)) return {
10844
11078
  status_code: 400,
@@ -10858,7 +11092,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10858
11092
  }
10859
11093
  });
10860
11094
  sdk.registerFunction({ id: "api::governance-bulk" }, async (req) => {
10861
- const authErr = checkAuth$1(req, secret);
11095
+ const authErr = checkAuth(req, secret);
10862
11096
  if (authErr) return authErr;
10863
11097
  return {
10864
11098
  status_code: 200,
@@ -10874,7 +11108,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10874
11108
  }
10875
11109
  });
10876
11110
  sdk.registerFunction({ id: "api::snapshots" }, async (req) => {
10877
- const authErr = checkAuth$1(req, secret);
11111
+ const authErr = checkAuth(req, secret);
10878
11112
  if (authErr) return authErr;
10879
11113
  try {
10880
11114
  return {
@@ -10897,7 +11131,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10897
11131
  }
10898
11132
  });
10899
11133
  sdk.registerFunction({ id: "api::snapshot-create" }, async (req) => {
10900
- const authErr = checkAuth$1(req, secret);
11134
+ const authErr = checkAuth(req, secret);
10901
11135
  if (authErr) return authErr;
10902
11136
  try {
10903
11137
  return {
@@ -10920,7 +11154,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10920
11154
  }
10921
11155
  });
10922
11156
  sdk.registerFunction({ id: "api::snapshot-restore" }, async (req) => {
10923
- const authErr = checkAuth$1(req, secret);
11157
+ const authErr = checkAuth(req, secret);
10924
11158
  if (authErr) return authErr;
10925
11159
  if (!req.body?.commitHash) return {
10926
11160
  status_code: 400,
@@ -10947,7 +11181,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10947
11181
  }
10948
11182
  });
10949
11183
  sdk.registerFunction({ id: "api::memories" }, async (req) => {
10950
- const authErr = checkAuth$1(req, secret);
11184
+ const authErr = checkAuth(req, secret);
10951
11185
  if (authErr) return authErr;
10952
11186
  const memories = await kv.list(KV.memories);
10953
11187
  return {
@@ -10964,7 +11198,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10964
11198
  }
10965
11199
  });
10966
11200
  sdk.registerFunction({ id: "api::action-create" }, async (req) => {
10967
- const authErr = checkAuth$1(req, secret);
11201
+ const authErr = checkAuth(req, secret);
10968
11202
  if (authErr) return authErr;
10969
11203
  if (!req.body?.title) return {
10970
11204
  status_code: 400,
@@ -10984,7 +11218,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
10984
11218
  }
10985
11219
  });
10986
11220
  sdk.registerFunction({ id: "api::action-update" }, async (req) => {
10987
- const authErr = checkAuth$1(req, secret);
11221
+ const authErr = checkAuth(req, secret);
10988
11222
  if (authErr) return authErr;
10989
11223
  if (!req.body?.actionId) return {
10990
11224
  status_code: 400,
@@ -11004,7 +11238,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11004
11238
  }
11005
11239
  });
11006
11240
  sdk.registerFunction({ id: "api::action-list" }, async (req) => {
11007
- const authErr = checkAuth$1(req, secret);
11241
+ const authErr = checkAuth(req, secret);
11008
11242
  if (authErr) return authErr;
11009
11243
  return {
11010
11244
  status_code: 200,
@@ -11024,7 +11258,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11024
11258
  }
11025
11259
  });
11026
11260
  sdk.registerFunction({ id: "api::action-get" }, async (req) => {
11027
- const authErr = checkAuth$1(req, secret);
11261
+ const authErr = checkAuth(req, secret);
11028
11262
  if (authErr) return authErr;
11029
11263
  const actionId = req.query_params?.["actionId"];
11030
11264
  if (!actionId) return {
@@ -11045,7 +11279,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11045
11279
  }
11046
11280
  });
11047
11281
  sdk.registerFunction({ id: "api::action-edge" }, async (req) => {
11048
- const authErr = checkAuth$1(req, secret);
11282
+ const authErr = checkAuth(req, secret);
11049
11283
  if (authErr) return authErr;
11050
11284
  if (!req.body?.sourceActionId || !req.body?.targetActionId || !req.body?.type) return {
11051
11285
  status_code: 400,
@@ -11065,7 +11299,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11065
11299
  }
11066
11300
  });
11067
11301
  sdk.registerFunction({ id: "api::frontier" }, async (req) => {
11068
- const authErr = checkAuth$1(req, secret);
11302
+ const authErr = checkAuth(req, secret);
11069
11303
  if (authErr) return authErr;
11070
11304
  return {
11071
11305
  status_code: 200,
@@ -11085,7 +11319,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11085
11319
  }
11086
11320
  });
11087
11321
  sdk.registerFunction({ id: "api::next" }, async (req) => {
11088
- const authErr = checkAuth$1(req, secret);
11322
+ const authErr = checkAuth(req, secret);
11089
11323
  if (authErr) return authErr;
11090
11324
  return {
11091
11325
  status_code: 200,
@@ -11104,7 +11338,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11104
11338
  }
11105
11339
  });
11106
11340
  sdk.registerFunction({ id: "api::lease-acquire" }, async (req) => {
11107
- const authErr = checkAuth$1(req, secret);
11341
+ const authErr = checkAuth(req, secret);
11108
11342
  if (authErr) return authErr;
11109
11343
  if (!req.body?.actionId || !req.body?.agentId) return {
11110
11344
  status_code: 400,
@@ -11124,7 +11358,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11124
11358
  }
11125
11359
  });
11126
11360
  sdk.registerFunction({ id: "api::lease-release" }, async (req) => {
11127
- const authErr = checkAuth$1(req, secret);
11361
+ const authErr = checkAuth(req, secret);
11128
11362
  if (authErr) return authErr;
11129
11363
  if (!req.body?.actionId || !req.body?.agentId) return {
11130
11364
  status_code: 400,
@@ -11144,7 +11378,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11144
11378
  }
11145
11379
  });
11146
11380
  sdk.registerFunction({ id: "api::lease-renew" }, async (req) => {
11147
- const authErr = checkAuth$1(req, secret);
11381
+ const authErr = checkAuth(req, secret);
11148
11382
  if (authErr) return authErr;
11149
11383
  if (!req.body?.actionId || !req.body?.agentId) return {
11150
11384
  status_code: 400,
@@ -11164,7 +11398,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11164
11398
  }
11165
11399
  });
11166
11400
  sdk.registerFunction({ id: "api::routine-create" }, async (req) => {
11167
- const authErr = checkAuth$1(req, secret);
11401
+ const authErr = checkAuth(req, secret);
11168
11402
  if (authErr) return authErr;
11169
11403
  if (!req.body?.name) return {
11170
11404
  status_code: 400,
@@ -11184,7 +11418,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11184
11418
  }
11185
11419
  });
11186
11420
  sdk.registerFunction({ id: "api::routine-list" }, async (req) => {
11187
- const authErr = checkAuth$1(req, secret);
11421
+ const authErr = checkAuth(req, secret);
11188
11422
  if (authErr) return authErr;
11189
11423
  return {
11190
11424
  status_code: 200,
@@ -11200,7 +11434,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11200
11434
  }
11201
11435
  });
11202
11436
  sdk.registerFunction({ id: "api::routine-run" }, async (req) => {
11203
- const authErr = checkAuth$1(req, secret);
11437
+ const authErr = checkAuth(req, secret);
11204
11438
  if (authErr) return authErr;
11205
11439
  if (!req.body?.routineId) return {
11206
11440
  status_code: 400,
@@ -11220,7 +11454,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11220
11454
  }
11221
11455
  });
11222
11456
  sdk.registerFunction({ id: "api::routine-status" }, async (req) => {
11223
- const authErr = checkAuth$1(req, secret);
11457
+ const authErr = checkAuth(req, secret);
11224
11458
  if (authErr) return authErr;
11225
11459
  const runId = req.query_params?.["runId"];
11226
11460
  if (!runId) return {
@@ -11241,7 +11475,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11241
11475
  }
11242
11476
  });
11243
11477
  sdk.registerFunction({ id: "api::signal-send" }, async (req) => {
11244
- const authErr = checkAuth$1(req, secret);
11478
+ const authErr = checkAuth(req, secret);
11245
11479
  if (authErr) return authErr;
11246
11480
  if (!req.body?.from || !req.body?.content) return {
11247
11481
  status_code: 400,
@@ -11261,7 +11495,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11261
11495
  }
11262
11496
  });
11263
11497
  sdk.registerFunction({ id: "api::signal-read" }, async (req) => {
11264
- const authErr = checkAuth$1(req, secret);
11498
+ const authErr = checkAuth(req, secret);
11265
11499
  if (authErr) return authErr;
11266
11500
  const agentId = req.query_params?.["agentId"];
11267
11501
  if (!agentId) return {
@@ -11287,7 +11521,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11287
11521
  }
11288
11522
  });
11289
11523
  sdk.registerFunction({ id: "api::checkpoint-create" }, async (req) => {
11290
- const authErr = checkAuth$1(req, secret);
11524
+ const authErr = checkAuth(req, secret);
11291
11525
  if (authErr) return authErr;
11292
11526
  if (!req.body?.name) return {
11293
11527
  status_code: 400,
@@ -11307,7 +11541,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11307
11541
  }
11308
11542
  });
11309
11543
  sdk.registerFunction({ id: "api::checkpoint-resolve" }, async (req) => {
11310
- const authErr = checkAuth$1(req, secret);
11544
+ const authErr = checkAuth(req, secret);
11311
11545
  if (authErr) return authErr;
11312
11546
  if (!req.body?.checkpointId || !req.body?.status) return {
11313
11547
  status_code: 400,
@@ -11327,7 +11561,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11327
11561
  }
11328
11562
  });
11329
11563
  sdk.registerFunction({ id: "api::checkpoint-list" }, async (req) => {
11330
- const authErr = checkAuth$1(req, secret);
11564
+ const authErr = checkAuth(req, secret);
11331
11565
  if (authErr) return authErr;
11332
11566
  return {
11333
11567
  status_code: 200,
@@ -11346,7 +11580,9 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11346
11580
  }
11347
11581
  });
11348
11582
  sdk.registerFunction({ id: "api::mesh-register" }, async (req) => {
11349
- const authErr = checkAuth$1(req, secret);
11583
+ const secretErr = requireConfiguredSecret(secret, "mesh");
11584
+ if (secretErr) return secretErr;
11585
+ const authErr = checkAuth(req, secret);
11350
11586
  if (authErr) return authErr;
11351
11587
  if (!req.body?.url || !req.body?.name) return {
11352
11588
  status_code: 400,
@@ -11366,7 +11602,9 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11366
11602
  }
11367
11603
  });
11368
11604
  sdk.registerFunction({ id: "api::mesh-list" }, async (req) => {
11369
- const authErr = checkAuth$1(req, secret);
11605
+ const secretErr = requireConfiguredSecret(secret, "mesh");
11606
+ if (secretErr) return secretErr;
11607
+ const authErr = checkAuth(req, secret);
11370
11608
  if (authErr) return authErr;
11371
11609
  return {
11372
11610
  status_code: 200,
@@ -11382,7 +11620,9 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11382
11620
  }
11383
11621
  });
11384
11622
  sdk.registerFunction({ id: "api::mesh-sync" }, async (req) => {
11385
- const authErr = checkAuth$1(req, secret);
11623
+ const secretErr = requireConfiguredSecret(secret, "mesh");
11624
+ if (secretErr) return secretErr;
11625
+ const authErr = checkAuth(req, secret);
11386
11626
  if (authErr) return authErr;
11387
11627
  return {
11388
11628
  status_code: 200,
@@ -11398,7 +11638,9 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11398
11638
  }
11399
11639
  });
11400
11640
  sdk.registerFunction({ id: "api::mesh-receive" }, async (req) => {
11401
- const authErr = checkAuth$1(req, secret);
11641
+ const secretErr = requireConfiguredSecret(secret, "mesh");
11642
+ if (secretErr) return secretErr;
11643
+ const authErr = checkAuth(req, secret);
11402
11644
  if (authErr) return authErr;
11403
11645
  return {
11404
11646
  status_code: 200,
@@ -11414,7 +11656,9 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11414
11656
  }
11415
11657
  });
11416
11658
  sdk.registerFunction({ id: "api::mesh-export" }, async (req) => {
11417
- const authErr = checkAuth$1(req, secret);
11659
+ const secretErr = requireConfiguredSecret(secret, "mesh");
11660
+ if (secretErr) return secretErr;
11661
+ const authErr = checkAuth(req, secret);
11418
11662
  if (authErr) return authErr;
11419
11663
  const since = req.query_params?.["since"];
11420
11664
  if (since) {
@@ -11460,7 +11704,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11460
11704
  }
11461
11705
  });
11462
11706
  sdk.registerFunction({ id: "api::flow-compress" }, async (req) => {
11463
- const authErr = checkAuth$1(req, secret);
11707
+ const authErr = checkAuth(req, secret);
11464
11708
  if (authErr) return authErr;
11465
11709
  try {
11466
11710
  return {
@@ -11483,7 +11727,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11483
11727
  }
11484
11728
  });
11485
11729
  sdk.registerFunction({ id: "api::branch-detect" }, async (req) => {
11486
- const authErr = checkAuth$1(req, secret);
11730
+ const authErr = checkAuth(req, secret);
11487
11731
  if (authErr) return authErr;
11488
11732
  const cwd = req.query_params?.["cwd"] || process.cwd();
11489
11733
  return {
@@ -11500,7 +11744,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11500
11744
  }
11501
11745
  });
11502
11746
  sdk.registerFunction({ id: "api::branch-worktrees" }, async (req) => {
11503
- const authErr = checkAuth$1(req, secret);
11747
+ const authErr = checkAuth(req, secret);
11504
11748
  if (authErr) return authErr;
11505
11749
  const cwd = req.query_params?.["cwd"] || process.cwd();
11506
11750
  return {
@@ -11517,7 +11761,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11517
11761
  }
11518
11762
  });
11519
11763
  sdk.registerFunction({ id: "api::branch-sessions" }, async (req) => {
11520
- const authErr = checkAuth$1(req, secret);
11764
+ const authErr = checkAuth(req, secret);
11521
11765
  if (authErr) return authErr;
11522
11766
  const cwd = req.query_params?.["cwd"] || process.cwd();
11523
11767
  return {
@@ -11533,27 +11777,21 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11533
11777
  http_method: "GET"
11534
11778
  }
11535
11779
  });
11536
- sdk.registerFunction({ id: "api::viewer" }, async () => {
11537
- const headers = {
11538
- "Content-Type": "text/html",
11539
- "Content-Security-Policy": VIEWER_CSP
11780
+ sdk.registerFunction({ id: "api::viewer" }, async (req) => {
11781
+ const denied = checkAuth(req, secret);
11782
+ if (denied) return denied;
11783
+ const rendered = renderViewerDocument();
11784
+ if (rendered.found) return {
11785
+ status_code: 200,
11786
+ headers: {
11787
+ "Content-Type": "text/html",
11788
+ "Content-Security-Policy": rendered.csp
11789
+ },
11790
+ body: rendered.html
11540
11791
  };
11541
- const base = dirname(fileURLToPath(import.meta.url));
11542
- const candidates = [
11543
- join(base, "..", "viewer", "index.html"),
11544
- join(base, "..", "src", "viewer", "index.html"),
11545
- join(base, "viewer", "index.html")
11546
- ];
11547
- for (const p of candidates) try {
11548
- return {
11549
- status_code: 200,
11550
- headers,
11551
- body: readFileSync(p, "utf-8")
11552
- };
11553
- } catch {}
11554
11792
  return {
11555
11793
  status_code: 404,
11556
- headers,
11794
+ headers: { "Content-Type": "text/html" },
11557
11795
  body: "<!DOCTYPE html><html><body><h1>agentmemory</h1><p>viewer not found</p></body></html>"
11558
11796
  };
11559
11797
  });
@@ -11566,7 +11804,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11566
11804
  }
11567
11805
  });
11568
11806
  sdk.registerFunction({ id: "api::sentinel-create" }, async (req) => {
11569
- const denied = checkAuth$1(req, secret);
11807
+ const denied = checkAuth(req, secret);
11570
11808
  if (denied) return denied;
11571
11809
  const body = req.body;
11572
11810
  if (!body?.name) return {
@@ -11587,7 +11825,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11587
11825
  }
11588
11826
  });
11589
11827
  sdk.registerFunction({ id: "api::sentinel-trigger" }, async (req) => {
11590
- const denied = checkAuth$1(req, secret);
11828
+ const denied = checkAuth(req, secret);
11591
11829
  if (denied) return denied;
11592
11830
  const body = req.body;
11593
11831
  if (!body?.sentinelId) return {
@@ -11608,7 +11846,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11608
11846
  }
11609
11847
  });
11610
11848
  sdk.registerFunction({ id: "api::sentinel-check" }, async (req) => {
11611
- const denied = checkAuth$1(req, secret);
11849
+ const denied = checkAuth(req, secret);
11612
11850
  if (denied) return denied;
11613
11851
  return {
11614
11852
  status_code: 200,
@@ -11624,7 +11862,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11624
11862
  }
11625
11863
  });
11626
11864
  sdk.registerFunction({ id: "api::sentinel-cancel" }, async (req) => {
11627
- const denied = checkAuth$1(req, secret);
11865
+ const denied = checkAuth(req, secret);
11628
11866
  if (denied) return denied;
11629
11867
  const body = req.body;
11630
11868
  if (!body?.sentinelId) return {
@@ -11645,7 +11883,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11645
11883
  }
11646
11884
  });
11647
11885
  sdk.registerFunction({ id: "api::sentinel-list" }, async (req) => {
11648
- const denied = checkAuth$1(req, secret);
11886
+ const denied = checkAuth(req, secret);
11649
11887
  if (denied) return denied;
11650
11888
  const params = req.query_params || {};
11651
11889
  return {
@@ -11665,7 +11903,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11665
11903
  }
11666
11904
  });
11667
11905
  sdk.registerFunction({ id: "api::sketch-create" }, async (req) => {
11668
- const denied = checkAuth$1(req, secret);
11906
+ const denied = checkAuth(req, secret);
11669
11907
  if (denied) return denied;
11670
11908
  const body = req.body;
11671
11909
  if (!body?.title) return {
@@ -11686,7 +11924,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11686
11924
  }
11687
11925
  });
11688
11926
  sdk.registerFunction({ id: "api::sketch-add" }, async (req) => {
11689
- const denied = checkAuth$1(req, secret);
11927
+ const denied = checkAuth(req, secret);
11690
11928
  if (denied) return denied;
11691
11929
  const body = req.body;
11692
11930
  if (!body?.sketchId || !body?.title) return {
@@ -11707,7 +11945,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11707
11945
  }
11708
11946
  });
11709
11947
  sdk.registerFunction({ id: "api::sketch-promote" }, async (req) => {
11710
- const denied = checkAuth$1(req, secret);
11948
+ const denied = checkAuth(req, secret);
11711
11949
  if (denied) return denied;
11712
11950
  const body = req.body;
11713
11951
  if (!body?.sketchId) return {
@@ -11728,7 +11966,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11728
11966
  }
11729
11967
  });
11730
11968
  sdk.registerFunction({ id: "api::sketch-discard" }, async (req) => {
11731
- const denied = checkAuth$1(req, secret);
11969
+ const denied = checkAuth(req, secret);
11732
11970
  if (denied) return denied;
11733
11971
  const body = req.body;
11734
11972
  if (!body?.sketchId) return {
@@ -11749,7 +11987,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11749
11987
  }
11750
11988
  });
11751
11989
  sdk.registerFunction({ id: "api::sketch-list" }, async (req) => {
11752
- const denied = checkAuth$1(req, secret);
11990
+ const denied = checkAuth(req, secret);
11753
11991
  if (denied) return denied;
11754
11992
  const params = req.query_params || {};
11755
11993
  return {
@@ -11769,7 +12007,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11769
12007
  }
11770
12008
  });
11771
12009
  sdk.registerFunction({ id: "api::sketch-gc" }, async (req) => {
11772
- const denied = checkAuth$1(req, secret);
12010
+ const denied = checkAuth(req, secret);
11773
12011
  if (denied) return denied;
11774
12012
  return {
11775
12013
  status_code: 200,
@@ -11785,7 +12023,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11785
12023
  }
11786
12024
  });
11787
12025
  sdk.registerFunction({ id: "api::crystallize" }, async (req) => {
11788
- const denied = checkAuth$1(req, secret);
12026
+ const denied = checkAuth(req, secret);
11789
12027
  if (denied) return denied;
11790
12028
  const body = req.body;
11791
12029
  if (!body?.actionIds) return {
@@ -11806,7 +12044,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11806
12044
  }
11807
12045
  });
11808
12046
  sdk.registerFunction({ id: "api::crystal-list" }, async (req) => {
11809
- const denied = checkAuth$1(req, secret);
12047
+ const denied = checkAuth(req, secret);
11810
12048
  if (denied) return denied;
11811
12049
  const params = req.query_params || {};
11812
12050
  return {
@@ -11827,7 +12065,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11827
12065
  }
11828
12066
  });
11829
12067
  sdk.registerFunction({ id: "api::auto-crystallize" }, async (req) => {
11830
- const denied = checkAuth$1(req, secret);
12068
+ const denied = checkAuth(req, secret);
11831
12069
  if (denied) return denied;
11832
12070
  const body = req.body;
11833
12071
  return {
@@ -11844,7 +12082,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11844
12082
  }
11845
12083
  });
11846
12084
  sdk.registerFunction({ id: "api::diagnose" }, async (req) => {
11847
- const denied = checkAuth$1(req, secret);
12085
+ const denied = checkAuth(req, secret);
11848
12086
  if (denied) return denied;
11849
12087
  const body = req.body;
11850
12088
  return {
@@ -11861,7 +12099,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11861
12099
  }
11862
12100
  });
11863
12101
  sdk.registerFunction({ id: "api::heal" }, async (req) => {
11864
- const denied = checkAuth$1(req, secret);
12102
+ const denied = checkAuth(req, secret);
11865
12103
  if (denied) return denied;
11866
12104
  const body = req.body;
11867
12105
  return {
@@ -11878,7 +12116,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11878
12116
  }
11879
12117
  });
11880
12118
  sdk.registerFunction({ id: "api::facet-tag" }, async (req) => {
11881
- const denied = checkAuth$1(req, secret);
12119
+ const denied = checkAuth(req, secret);
11882
12120
  if (denied) return denied;
11883
12121
  const body = req.body;
11884
12122
  if (!body?.targetId || !body?.dimension || !body?.value) return {
@@ -11899,7 +12137,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11899
12137
  }
11900
12138
  });
11901
12139
  sdk.registerFunction({ id: "api::facet-untag" }, async (req) => {
11902
- const denied = checkAuth$1(req, secret);
12140
+ const denied = checkAuth(req, secret);
11903
12141
  if (denied) return denied;
11904
12142
  const body = req.body;
11905
12143
  if (!body?.targetId || !body?.dimension) return {
@@ -11920,7 +12158,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11920
12158
  }
11921
12159
  });
11922
12160
  sdk.registerFunction({ id: "api::facet-query" }, async (req) => {
11923
- const denied = checkAuth$1(req, secret);
12161
+ const denied = checkAuth(req, secret);
11924
12162
  if (denied) return denied;
11925
12163
  const body = req.body;
11926
12164
  return {
@@ -11937,7 +12175,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11937
12175
  }
11938
12176
  });
11939
12177
  sdk.registerFunction({ id: "api::facet-get" }, async (req) => {
11940
- const denied = checkAuth$1(req, secret);
12178
+ const denied = checkAuth(req, secret);
11941
12179
  if (denied) return denied;
11942
12180
  const params = req.query_params || {};
11943
12181
  if (!params.targetId) return {
@@ -11958,7 +12196,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11958
12196
  }
11959
12197
  });
11960
12198
  sdk.registerFunction({ id: "api::facet-stats" }, async (req) => {
11961
- const denied = checkAuth$1(req, secret);
12199
+ const denied = checkAuth(req, secret);
11962
12200
  if (denied) return denied;
11963
12201
  const params = req.query_params || {};
11964
12202
  return {
@@ -11975,7 +12213,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11975
12213
  }
11976
12214
  });
11977
12215
  sdk.registerFunction({ id: "api::verify" }, async (req) => {
11978
- const denied = checkAuth$1(req, secret);
12216
+ const denied = checkAuth(req, secret);
11979
12217
  if (denied) return denied;
11980
12218
  const body = req.body;
11981
12219
  if (!body?.id || typeof body.id !== "string") return {
@@ -11996,7 +12234,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
11996
12234
  }
11997
12235
  });
11998
12236
  sdk.registerFunction({ id: "api::cascade-update" }, async (req) => {
11999
- const denied = checkAuth$1(req, secret);
12237
+ const denied = checkAuth(req, secret);
12000
12238
  if (denied) return denied;
12001
12239
  const body = req.body;
12002
12240
  if (!body?.supersededMemoryId || typeof body.supersededMemoryId !== "string") return {
@@ -12017,7 +12255,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
12017
12255
  }
12018
12256
  });
12019
12257
  sdk.registerFunction({ id: "api::lesson-save" }, async (req) => {
12020
- const denied = checkAuth$1(req, secret);
12258
+ const denied = checkAuth(req, secret);
12021
12259
  if (denied) return denied;
12022
12260
  const body = req.body;
12023
12261
  if (!body?.content || typeof body.content !== "string") return {
@@ -12047,7 +12285,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
12047
12285
  }
12048
12286
  });
12049
12287
  sdk.registerFunction({ id: "api::lesson-list" }, async (req) => {
12050
- const denied = checkAuth$1(req, secret);
12288
+ const denied = checkAuth(req, secret);
12051
12289
  if (denied) return denied;
12052
12290
  const params = req.query_params || {};
12053
12291
  return {
@@ -12069,7 +12307,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
12069
12307
  }
12070
12308
  });
12071
12309
  sdk.registerFunction({ id: "api::lesson-search" }, async (req) => {
12072
- const denied = checkAuth$1(req, secret);
12310
+ const denied = checkAuth(req, secret);
12073
12311
  if (denied) return denied;
12074
12312
  const body = req.body;
12075
12313
  if (!body?.query || typeof body.query !== "string") return {
@@ -12090,7 +12328,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
12090
12328
  }
12091
12329
  });
12092
12330
  sdk.registerFunction({ id: "api::lesson-strengthen" }, async (req) => {
12093
- const denied = checkAuth$1(req, secret);
12331
+ const denied = checkAuth(req, secret);
12094
12332
  if (denied) return denied;
12095
12333
  const body = req.body;
12096
12334
  if (!body?.lessonId || typeof body.lessonId !== "string") return {
@@ -12111,7 +12349,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
12111
12349
  }
12112
12350
  });
12113
12351
  sdk.registerFunction({ id: "api::obsidian-export" }, async (req) => {
12114
- const denied = checkAuth$1(req, secret);
12352
+ const denied = checkAuth(req, secret);
12115
12353
  if (denied) return denied;
12116
12354
  const body = req.body || {};
12117
12355
  const types = typeof body.types === "string" ? body.types.split(",").map((t) => t.trim()).filter(Boolean) : void 0;
@@ -12132,7 +12370,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
12132
12370
  }
12133
12371
  });
12134
12372
  sdk.registerFunction({ id: "api::reflect" }, async (req) => {
12135
- const denied = checkAuth$1(req, secret);
12373
+ const denied = checkAuth(req, secret);
12136
12374
  if (denied) return denied;
12137
12375
  const body = req.body || {};
12138
12376
  return {
@@ -12152,7 +12390,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
12152
12390
  }
12153
12391
  });
12154
12392
  sdk.registerFunction({ id: "api::insight-list" }, async (req) => {
12155
- const denied = checkAuth$1(req, secret);
12393
+ const denied = checkAuth(req, secret);
12156
12394
  if (denied) return denied;
12157
12395
  const params = req.query_params || {};
12158
12396
  return {
@@ -12173,7 +12411,7 @@ function registerApiTriggers(sdk, kv, secret, metricsStore, provider) {
12173
12411
  }
12174
12412
  });
12175
12413
  sdk.registerFunction({ id: "api::insight-search" }, async (req) => {
12176
- const denied = checkAuth$1(req, secret);
12414
+ const denied = checkAuth(req, secret);
12177
12415
  if (denied) return denied;
12178
12416
  const body = req.body;
12179
12417
  if (!body?.query || typeof body.query !== "string") return {
@@ -14442,11 +14680,6 @@ function readBody(req) {
14442
14680
  req.on("error", reject);
14443
14681
  });
14444
14682
  }
14445
- function checkAuth(req, secret) {
14446
- if (!secret) return true;
14447
- const auth = req.headers["authorization"] || "";
14448
- return typeof auth === "string" && timingSafeCompare(auth, `Bearer ${secret}`);
14449
- }
14450
14683
  function startViewerServer(port, _kv, _sdk, secret, restPort) {
14451
14684
  const resolvedRestPort = restPort ?? port - 2;
14452
14685
  const server = createServer(async (req, res) => {
@@ -14464,32 +14697,20 @@ function startViewerServer(port, _kv, _sdk, secret, restPort) {
14464
14697
  return;
14465
14698
  }
14466
14699
  if (method === "GET" && (pathname === "/" || pathname === "/viewer" || pathname === "/agentmemory/viewer")) {
14467
- const base = dirname(fileURLToPath(import.meta.url));
14468
- const candidates = [
14469
- join(base, "index.html"),
14470
- join(base, "viewer", "index.html"),
14471
- join(base, "..", "viewer", "index.html"),
14472
- join(base, "..", "src", "viewer", "index.html"),
14473
- join(base, "..", "dist", "viewer", "index.html")
14474
- ];
14475
- for (const p of candidates) try {
14476
- const html = readFileSync(p, "utf-8");
14700
+ const rendered = renderViewerDocument();
14701
+ if (rendered.found) {
14477
14702
  res.writeHead(200, {
14478
14703
  "Content-Type": "text/html; charset=utf-8",
14479
- "Content-Security-Policy": VIEWER_CSP,
14704
+ "Content-Security-Policy": rendered.csp,
14480
14705
  "Cache-Control": "no-cache"
14481
14706
  });
14482
- res.end(html);
14707
+ res.end(rendered.html);
14483
14708
  return;
14484
- } catch {}
14709
+ }
14485
14710
  res.writeHead(404, { "Content-Type": "text/plain" });
14486
14711
  res.end("viewer not found");
14487
14712
  return;
14488
14713
  }
14489
- if (!checkAuth(req, secret)) {
14490
- json(res, 401, { error: "unauthorized" }, req);
14491
- return;
14492
- }
14493
14714
  try {
14494
14715
  await proxyToRestApi(resolvedRestPort, pathname, qs, method, req, res, secret);
14495
14716
  } catch (err) {
@@ -14747,7 +14968,7 @@ async function main() {
14747
14968
  registerRoutinesFunction(sdk, kv);
14748
14969
  registerSignalsFunction(sdk, kv);
14749
14970
  registerCheckpointsFunction(sdk, kv);
14750
- registerMeshFunction(sdk, kv);
14971
+ registerMeshFunction(sdk, kv, secret);
14751
14972
  registerBranchAwareFunction(sdk, kv);
14752
14973
  registerFlowCompressFunction(sdk, kv, provider);
14753
14974
  registerSentinelsFunction(sdk, kv);