@codemem/server 0.22.3 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +311 -90
- package/dist/index.js.map +1 -1
- package/dist/routes/memory.d.ts.map +1 -1
- package/dist/routes/sync.d.ts.map +1 -1
- package/package.json +12 -9
- package/static/app.js +81 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/routes/memory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/routes/memory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAWjD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,KAAK,YAAY,GAAG,MAAM,WAAW,CAAC;AA6ItC,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,8EAwQlD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/routes/sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/routes/sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAEX,WAAW,EAEX,MAAM,eAAe,CAAC;AA+BvB,OAAO,EAAgB,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAE3E,KAAK,YAAY,GAAG,MAAM,WAAW,CAAC;AACtC,KAAK,iBAAiB,GAAG;IACxB,KAAK,EACF,UAAU,GACV,SAAS,GACT,UAAU,GACV,OAAO,GACP,UAAU,GACV,iBAAiB,GACjB,iBAAiB,GACjB,IAAI,CAAC;IACR,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,UAAU,wBAAwB;IACjC,cAAc,CAAC,EAAE;QAChB,OAAO,EAAE,0BAA0B,CAAC;QACpC,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,wBAAwB,EAAE,MAAM,CAAC;QACjC,4BAA4B,EAAE,MAAM,CAAC;KACrC,CAAC;CACF;AA6vBD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,GAAE,wBAA6B,8EA4R7F;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACzB,QAAQ,EAAE,YAAY,EACtB,oBAAoB,CAAC,EAAE,MAAM,iBAAiB,GAAG,IAAI,8EA+4BrD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codemem/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -15,33 +15,36 @@
|
|
|
15
15
|
"static/"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@hono/node-server": "^1.
|
|
19
|
-
"drizzle-orm": "^0.45.
|
|
20
|
-
"hono": "^4.
|
|
18
|
+
"@hono/node-server": "^1.19.12",
|
|
19
|
+
"drizzle-orm": "^0.45.2",
|
|
20
|
+
"hono": "^4.12.11",
|
|
21
21
|
"limiter": "^3.0.0",
|
|
22
|
-
"@codemem/core": "^0.
|
|
22
|
+
"@codemem/core": "^0.23.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/better-sqlite3": "^7.6.13",
|
|
26
26
|
"@types/node": "^22.15.21",
|
|
27
27
|
"better-sqlite3": "^12.8.0",
|
|
28
28
|
"sqlite-vec": "0.1.7-alpha.2",
|
|
29
|
-
"typescript": "^5.
|
|
30
|
-
"vite": "8.0.
|
|
31
|
-
"vitest": "4.
|
|
29
|
+
"typescript": "^5.9.3",
|
|
30
|
+
"vite": "^8.0.5",
|
|
31
|
+
"vitest": "^4.1.2"
|
|
32
32
|
},
|
|
33
33
|
"repository": {
|
|
34
34
|
"type": "git",
|
|
35
35
|
"url": "git+https://github.com/kunickiaj/codemem.git",
|
|
36
36
|
"directory": "packages/viewer-server"
|
|
37
37
|
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=24"
|
|
40
|
+
},
|
|
38
41
|
"license": "MIT",
|
|
39
42
|
"publishConfig": {
|
|
40
43
|
"access": "public"
|
|
41
44
|
},
|
|
42
45
|
"scripts": {
|
|
43
46
|
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
44
|
-
"build": "pnpm exec vite build --ssr src/index.ts --outDir dist && pnpm exec tsc --build
|
|
47
|
+
"build": "pnpm exec vite build --ssr src/index.ts --outDir dist && pnpm exec tsc --build",
|
|
45
48
|
"typecheck": "pnpm exec tsc --noEmit"
|
|
46
49
|
}
|
|
47
50
|
}
|
package/static/app.js
CHANGED
|
@@ -481,6 +481,16 @@
|
|
|
481
481
|
if (!resp.ok) throw new Error(payloadError(payload) || text || "request failed");
|
|
482
482
|
return payload;
|
|
483
483
|
}
|
|
484
|
+
async function deactivateActor(actorId) {
|
|
485
|
+
const resp = await fetch("/api/sync/actors/deactivate", {
|
|
486
|
+
method: "POST",
|
|
487
|
+
headers: { "Content-Type": "application/json" },
|
|
488
|
+
body: JSON.stringify({ actor_id: actorId })
|
|
489
|
+
});
|
|
490
|
+
const { text, payload } = await readJsonPayload(resp);
|
|
491
|
+
if (!resp.ok) throw new Error(payloadError(payload) || text || "request failed");
|
|
492
|
+
return payload;
|
|
493
|
+
}
|
|
484
494
|
async function claimLegacyDeviceIdentity(originDeviceId) {
|
|
485
495
|
const resp = await fetch("/api/sync/legacy-devices/claim", {
|
|
486
496
|
method: "POST",
|
|
@@ -1313,6 +1323,10 @@
|
|
|
1313
1323
|
if (metadata?.is_summary === true) return true;
|
|
1314
1324
|
return String(metadata?.source || "").trim().toLowerCase() === "observer_summary";
|
|
1315
1325
|
}
|
|
1326
|
+
function canonicalKind(item, metadata) {
|
|
1327
|
+
const kindValue = String(item?.kind || "").trim().toLowerCase();
|
|
1328
|
+
return isSummaryLikeItem(item, metadata) ? "session_summary" : kindValue || "change";
|
|
1329
|
+
}
|
|
1316
1330
|
function observationViewData(item) {
|
|
1317
1331
|
const metadata = mergeMetadata(item?.metadata_json);
|
|
1318
1332
|
const summary = String(item?.subtitle || item?.body_text || "").trim();
|
|
@@ -1494,10 +1508,9 @@
|
|
|
1494
1508
|
}, display);
|
|
1495
1509
|
}
|
|
1496
1510
|
function FeedItemCard({ item }) {
|
|
1497
|
-
const kindValue = String(item.kind || "session_summary").toLowerCase();
|
|
1498
1511
|
const metadata = mergeMetadata(item?.metadata_json);
|
|
1499
1512
|
const isSessionSummary = isSummaryLikeItem(item, metadata);
|
|
1500
|
-
const displayKindValue =
|
|
1513
|
+
const displayKindValue = canonicalKind(item, metadata);
|
|
1501
1514
|
const rowKey = itemKey(item);
|
|
1502
1515
|
const defaultTitle = item.title || "(untitled)";
|
|
1503
1516
|
const displayTitle = isSessionSummary && metadata?.request ? metadata.request : defaultTitle;
|
|
@@ -4052,15 +4065,19 @@
|
|
|
4052
4065
|
class: "diag-line",
|
|
4053
4066
|
children: [/* @__PURE__ */ u("div", {
|
|
4054
4067
|
class: "left",
|
|
4055
|
-
children: [/* @__PURE__ */ u("div", { children:
|
|
4068
|
+
children: [/* @__PURE__ */ u("div", { children: [
|
|
4069
|
+
attempt.peerLabel,
|
|
4070
|
+
" — ",
|
|
4071
|
+
attempt.status
|
|
4072
|
+
] }), attempt.detail ? /* @__PURE__ */ u("div", {
|
|
4056
4073
|
class: "small",
|
|
4057
|
-
children: attempt.
|
|
4058
|
-
})]
|
|
4074
|
+
children: attempt.detail
|
|
4075
|
+
}) : null]
|
|
4059
4076
|
}), /* @__PURE__ */ u("div", {
|
|
4060
4077
|
class: "right",
|
|
4061
4078
|
children: attempt.startedAt
|
|
4062
4079
|
})]
|
|
4063
|
-
}, `${attempt.startedAt}-${attempt.
|
|
4080
|
+
}, `${attempt.startedAt}-${attempt.peerLabel}-${index}`)) });
|
|
4064
4081
|
}
|
|
4065
4082
|
function PairingText({ text }) {
|
|
4066
4083
|
return /* @__PURE__ */ u(k$2, { children: text });
|
|
@@ -4532,9 +4549,18 @@
|
|
|
4532
4549
|
}
|
|
4533
4550
|
renderAttemptsList(syncAttempts, attempts.slice(0, 5).map((attempt) => {
|
|
4534
4551
|
const time = attempt.started_at || attempt.started_at_utc || "";
|
|
4552
|
+
const peerId = String(attempt.peer_device_id || "").trim();
|
|
4553
|
+
const matchedPeer = Array.isArray(state.lastSyncPeers) ? state.lastSyncPeers.find((p) => String(p?.peer_device_id || "") === peerId) : null;
|
|
4554
|
+
const peerLabel = String(matchedPeer?.name || "").trim() || (peerId ? peerId.slice(0, 8) : "unknown");
|
|
4555
|
+
const isError = attempt.status === "error";
|
|
4556
|
+
const detailParts = [];
|
|
4557
|
+
if (isError && attempt.error) detailParts.push(String(attempt.error));
|
|
4558
|
+
if (!isError && (attempt.ops_in || attempt.ops_out)) detailParts.push(`${attempt.ops_in ?? 0} in · ${attempt.ops_out ?? 0} out`);
|
|
4559
|
+
if (!isSyncRedactionEnabled() && attempt.address) detailParts.push(attempt.address);
|
|
4535
4560
|
return {
|
|
4536
4561
|
status: attempt.status || "unknown",
|
|
4537
|
-
|
|
4562
|
+
peerLabel,
|
|
4563
|
+
detail: detailParts.join(" · "),
|
|
4538
4564
|
startedAt: time ? formatTimestamp(time) : ""
|
|
4539
4565
|
};
|
|
4540
4566
|
}));
|
|
@@ -10337,18 +10363,33 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10337
10363
|
displayName: String(request.display_name || request.device_id || "Pending device"),
|
|
10338
10364
|
requestId: String(request.request_id || "")
|
|
10339
10365
|
}));
|
|
10366
|
+
const visibleDiscoveredRows = discoveredRows.filter((row) => row.mode !== "paired" && row.mode !== "none" && row.mode !== "scope-pending");
|
|
10340
10367
|
const discoveredActionableCount = discoveredRows.filter((row) => row.mode === "accept" || row.mode === "scope-pending").length;
|
|
10341
10368
|
const actionableCount = attentionItems.length + pendingJoinRequests.length + discoveredActionableCount;
|
|
10369
|
+
const attentionParts = [];
|
|
10370
|
+
if (attentionItems.length > 0) {
|
|
10371
|
+
const repairItems = attentionItems.filter((item) => item.kind === "device-needs-repair");
|
|
10372
|
+
const nameItems = attentionItems.filter((item) => item.kind === "name-device");
|
|
10373
|
+
const reviewItems = attentionItems.filter((item) => item.kind === "review-team-device");
|
|
10374
|
+
const duplicateItems = attentionItems.filter((item) => item.kind === "possible-duplicate-person");
|
|
10375
|
+
if (repairItems.length > 0) attentionParts.push(`${repairItems.length} device${repairItems.length === 1 ? "" : "s"} to repair`);
|
|
10376
|
+
if (nameItems.length > 0) attentionParts.push(`${nameItems.length} device${nameItems.length === 1 ? "" : "s"} to name`);
|
|
10377
|
+
if (reviewItems.length > 0) attentionParts.push(`${reviewItems.length} device${reviewItems.length === 1 ? "" : "s"} to review`);
|
|
10378
|
+
if (duplicateItems.length > 0) attentionParts.push(`${duplicateItems.length} possible duplicate${duplicateItems.length === 1 ? "" : "s"}`);
|
|
10379
|
+
}
|
|
10380
|
+
if (pendingJoinRequests.length > 0) attentionParts.push(`${pendingJoinRequests.length} join request${pendingJoinRequests.length === 1 ? "" : "s"} to review`);
|
|
10381
|
+
if (discoveredActionableCount > 0) attentionParts.push(`${discoveredActionableCount} discovered device${discoveredActionableCount === 1 ? "" : "s"}`);
|
|
10382
|
+
const attentionDetail = attentionParts.join(", ");
|
|
10342
10383
|
const teamLabel = (coordinator.groups || []).join(", ") || "none";
|
|
10343
10384
|
const statusSummary = {
|
|
10344
10385
|
badgeClassName: `pill ${presenceStatus === "posted" ? "pill-success" : presenceStatus === "not_enrolled" ? "pill-warning" : "pill-error"}`,
|
|
10345
|
-
headline: presenceStatus === "posted" ? actionableCount > 0 ?
|
|
10386
|
+
headline: presenceStatus === "posted" ? actionableCount > 0 ? attentionDetail : "Everything is healthy" : presenceStatus === "not_enrolled" ? "This device is not enrolled in the team yet" : "Sync needs attention",
|
|
10346
10387
|
metricsText: metricParts.join(" · "),
|
|
10347
10388
|
presenceLabel
|
|
10348
10389
|
};
|
|
10349
10390
|
meta.textContent = presenceStatus === "posted" ? actionableCount > 0 ? `Team: ${teamLabel}. Start with the next step below, then scan the current team status.` : `Team: ${teamLabel}. Team status and device details are below.` : presenceStatus === "not_enrolled" ? `Team: ${teamLabel}. Enroll this device first, then return here to review the rest of the team.` : `Team: ${teamLabel}. Fix the current sync issue first, then use the rest of this card to verify the team state.`;
|
|
10350
|
-
if (discoveredPanel) discoveredPanel.hidden =
|
|
10351
|
-
if (discoveredMeta) discoveredMeta.textContent =
|
|
10391
|
+
if (discoveredPanel) discoveredPanel.hidden = visibleDiscoveredRows.length === 0 && !state.syncDiscoveredFeedback;
|
|
10392
|
+
if (discoveredMeta) discoveredMeta.textContent = visibleDiscoveredRows.length ? "Review anything here that still needs trust, repair, or approval." : "";
|
|
10352
10393
|
if (joinRequests) joinRequests.hidden = pendingJoinRequests.length === 0 && !state.syncJoinRequestsFeedback;
|
|
10353
10394
|
teardownTeamSyncRender(actions, [
|
|
10354
10395
|
list,
|
|
@@ -10376,7 +10417,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10376
10417
|
presenceStatus
|
|
10377
10418
|
}),
|
|
10378
10419
|
discoveredListMount: discoveredList,
|
|
10379
|
-
discoveredRows,
|
|
10420
|
+
discoveredRows: visibleDiscoveredRows,
|
|
10380
10421
|
joinRequestsMount: joinRequests,
|
|
10381
10422
|
listMount: list,
|
|
10382
10423
|
onApproveJoinRequest: async (request) => {
|
|
@@ -10642,7 +10683,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10642
10683
|
if (hiddenLocalDuplicateCount <= 0) return "Represents you across your devices.";
|
|
10643
10684
|
return `Represents you across your devices. ${hiddenLocalDuplicateCount} unresolved duplicate ${hiddenLocalDuplicateCount === 1 ? "entry is" : "entries are"} hidden until reviewed in Needs attention.`;
|
|
10644
10685
|
}
|
|
10645
|
-
function SyncActorRow({ actor, hiddenLocalDuplicateCount, onRename, onMerge }) {
|
|
10686
|
+
function SyncActorRow({ actor, hiddenLocalDuplicateCount, onRename, onMerge, onDeactivate }) {
|
|
10646
10687
|
const actorId = String(actor.actor_id || "");
|
|
10647
10688
|
const label = actorLabel(actor);
|
|
10648
10689
|
const count = assignedActorCount(actorId);
|
|
@@ -10775,12 +10816,26 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10775
10816
|
/* @__PURE__ */ u("div", {
|
|
10776
10817
|
className: "peer-meta actor-merge-note",
|
|
10777
10818
|
children: mergeNote
|
|
10819
|
+
}),
|
|
10820
|
+
/* @__PURE__ */ u("button", {
|
|
10821
|
+
className: "settings-button",
|
|
10822
|
+
disabled: renameBusy || mergeBusy,
|
|
10823
|
+
onClick: async () => {
|
|
10824
|
+
if (await openSyncConfirmDialog({
|
|
10825
|
+
title: `Remove ${label}?`,
|
|
10826
|
+
description: "This deactivates the person and unassigns their devices. Existing memories keep their current attribution.",
|
|
10827
|
+
confirmLabel: "Remove person",
|
|
10828
|
+
cancelLabel: "Keep",
|
|
10829
|
+
tone: "danger"
|
|
10830
|
+
})) await onDeactivate(actorId);
|
|
10831
|
+
},
|
|
10832
|
+
children: "Remove person"
|
|
10778
10833
|
})
|
|
10779
10834
|
] })
|
|
10780
10835
|
})]
|
|
10781
10836
|
});
|
|
10782
10837
|
}
|
|
10783
|
-
function SyncActorsList({ actors, hiddenLocalDuplicateCount, onRename, onMerge }) {
|
|
10838
|
+
function SyncActorsList({ actors, hiddenLocalDuplicateCount, onRename, onMerge, onDeactivate }) {
|
|
10784
10839
|
if (!actors.length) return /* @__PURE__ */ u("div", {
|
|
10785
10840
|
className: "sync-empty-state",
|
|
10786
10841
|
children: [/* @__PURE__ */ u("strong", { children: "No people yet." }), /* @__PURE__ */ u("span", { children: "Create a named person here, then assign each device below to keep sync ownership readable." })]
|
|
@@ -10791,7 +10846,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10791
10846
|
actor,
|
|
10792
10847
|
hiddenLocalDuplicateCount,
|
|
10793
10848
|
onRename,
|
|
10794
|
-
onMerge
|
|
10849
|
+
onMerge,
|
|
10850
|
+
onDeactivate
|
|
10795
10851
|
}, actorId);
|
|
10796
10852
|
}) });
|
|
10797
10853
|
}
|
|
@@ -11286,6 +11342,16 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
11286
11342
|
showGlobalNotice(friendlyError(error, "Failed to combine people."), "warning");
|
|
11287
11343
|
throw error;
|
|
11288
11344
|
}
|
|
11345
|
+
},
|
|
11346
|
+
onDeactivate: async (actorId) => {
|
|
11347
|
+
try {
|
|
11348
|
+
await deactivateActor(actorId);
|
|
11349
|
+
showGlobalNotice("Person removed. Assigned devices have been unassigned.");
|
|
11350
|
+
await _loadSyncData();
|
|
11351
|
+
} catch (error) {
|
|
11352
|
+
showGlobalNotice(friendlyError(error, "Failed to remove person."), "warning");
|
|
11353
|
+
throw error;
|
|
11354
|
+
}
|
|
11289
11355
|
}
|
|
11290
11356
|
});
|
|
11291
11357
|
}
|
|
@@ -13294,7 +13360,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
13294
13360
|
try {
|
|
13295
13361
|
const runtime = await loadRuntimeInfo();
|
|
13296
13362
|
if (!runtime?.version) return;
|
|
13297
|
-
setRuntimeLabel(runtime.version, "
|
|
13363
|
+
setRuntimeLabel(runtime.version, "8d28296");
|
|
13298
13364
|
} catch {}
|
|
13299
13365
|
}
|
|
13300
13366
|
var lastAnnouncedRefreshState = null;
|