@codemem/server 0.24.0 → 0.25.1

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.
@@ -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;AAWjD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,KAAK,YAAY,GAAG,MAAM,WAAW,CAAC;AA6ItC,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,8EAwQlD"}
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,8EA+TlD"}
@@ -1 +1 @@
1
- {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/routes/stats.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,WAAW,EAAW,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,WAAW,8EA2HtD"}
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/routes/stats.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAuB,KAAK,WAAW,EAAW,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAqB5B;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,WAAW,8EAyItD"}
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/routes/sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAGX,WAAW,EAEX,MAAM,eAAe,CAAC;AAgCvB,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;AA6xBD;;;;;;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,8EAg5BrD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemem/server",
3
- "version": "0.24.0",
3
+ "version": "0.25.1",
4
4
  "type": "module",
5
5
  "types": "./dist/index.d.ts",
6
6
  "exports": {
@@ -19,7 +19,7 @@
19
19
  "drizzle-orm": "^0.45.2",
20
20
  "hono": "^4.12.11",
21
21
  "limiter": "^3.0.0",
22
- "@codemem/core": "^0.24.0"
22
+ "@codemem/core": "^0.25.1"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/better-sqlite3": "^7.6.13",
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "scripts": {
46
46
  "clean": "rm -rf dist tsconfig.tsbuildinfo",
47
- "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 --force",
48
48
  "typecheck": "pnpm exec tsc --noEmit"
49
49
  }
50
50
  }
package/static/app.js CHANGED
@@ -309,6 +309,16 @@
309
309
  async function loadSummariesPage(project, options) {
310
310
  return fetchJson(`/api/summaries?${buildProjectParams(project, options?.limit, options?.offset, options?.scope)}`);
311
311
  }
312
+ async function tracePack(payload) {
313
+ const resp = await fetch("/api/pack/trace", {
314
+ method: "POST",
315
+ headers: { "Content-Type": "application/json" },
316
+ body: JSON.stringify(payload)
317
+ });
318
+ const { text, payload: data } = await readJsonPayload(resp);
319
+ if (!resp.ok) throw new Error(payloadError(data) || text || "request failed");
320
+ return data;
321
+ }
312
322
  async function loadObserverStatus() {
313
323
  return fetchJson("/api/observer-status");
314
324
  }
@@ -1329,14 +1339,14 @@
1329
1339
  }
1330
1340
  function observationViewData(item) {
1331
1341
  const metadata = mergeMetadata(item?.metadata_json);
1332
- const summary = String(item?.subtitle || item?.body_text || "").trim();
1333
- const narrative = String(item?.narrative || metadata?.narrative || "").trim();
1342
+ const summary = String(item?.subtitle || metadata?.subtitle || "").trim();
1343
+ const narrative = String(item?.narrative || metadata?.narrative || item?.body_text || "").trim();
1334
1344
  const normSummary = normalize(summary);
1335
1345
  const normNarrative = normalize(narrative);
1336
1346
  const narrativeDistinct = Boolean(narrative) && normNarrative !== normSummary;
1337
1347
  const explicitFacts = parseJsonArray(item?.facts || metadata?.facts || []);
1338
- const fallbackFacts = explicitFacts.length ? explicitFacts : extractFactsFromBody(summary || narrative);
1339
- const derivedFacts = fallbackFacts.length ? fallbackFacts : sentenceFacts(summary);
1348
+ const fallbackFacts = explicitFacts.length ? explicitFacts : extractFactsFromBody(narrative || summary);
1349
+ const derivedFacts = fallbackFacts.length ? fallbackFacts : sentenceFacts(narrative || summary);
1340
1350
  return {
1341
1351
  summary,
1342
1352
  narrative,
@@ -1766,6 +1776,138 @@
1766
1776
  }, label);
1767
1777
  }));
1768
1778
  }
1779
+ function TraceCandidateGroup({ label, candidates }) {
1780
+ if (candidates.length === 0) return null;
1781
+ return _$1("div", { className: "trace-group" }, _$1("div", { className: "section-meta" }, label), _$1("div", { className: "feed-list" }, candidates.map((candidate) => _$1("div", {
1782
+ className: "feed-card",
1783
+ key: `${label}:${candidate.id}`
1784
+ }, _$1("div", { className: "feed-card-header" }, [_$1("div", { className: "feed-card-title" }, `${candidate.rank}. ${candidate.title}`), _$1("div", { className: "feed-card-meta" }, `#${candidate.id} · ${candidate.kind}${candidate.section ? ` · ${candidate.section}` : ""}`)]), _$1("div", { className: "feed-card-body" }, [_$1("div", null, candidate.preview || "No preview available."), candidate.reasons.length ? _$1("div", { className: "section-meta" }, `Reasons: ${candidate.reasons.join(", ")}`) : null])))));
1785
+ }
1786
+ function ContextInspectorPanel() {
1787
+ const [open, setOpen] = d(false);
1788
+ const [workingSetText, setWorkingSetText] = d("");
1789
+ const [loading, setLoading] = d(false);
1790
+ const [error, setError] = d("");
1791
+ const [errorContextKey, setErrorContextKey] = d("");
1792
+ const [trace, setTrace] = d(null);
1793
+ const currentQuery = String(state.feedQuery || "").trim();
1794
+ const currentProject = state.currentProject || null;
1795
+ const currentContextKey = JSON.stringify([currentProject, currentQuery]);
1796
+ const visibleTrace = trace && trace.inputs.query === currentQuery && trace.inputs.project === currentProject ? trace : null;
1797
+ const visibleError = error && errorContextKey === currentContextKey ? error : "";
1798
+ y(() => {
1799
+ setError("");
1800
+ setErrorContextKey("");
1801
+ setTrace((currentTrace) => {
1802
+ if (!currentTrace) return null;
1803
+ if (currentTrace.inputs.query !== currentQuery || currentTrace.inputs.project !== currentProject) return null;
1804
+ return currentTrace;
1805
+ });
1806
+ }, [currentProject, currentQuery]);
1807
+ const runTrace = async () => {
1808
+ const context = currentQuery;
1809
+ const project = currentProject;
1810
+ const contextKey = JSON.stringify([project, context]);
1811
+ if (!context) {
1812
+ setError("Enter a query to inspect.");
1813
+ setErrorContextKey(contextKey);
1814
+ setTrace(null);
1815
+ return;
1816
+ }
1817
+ setLoading(true);
1818
+ setError("");
1819
+ setErrorContextKey("");
1820
+ try {
1821
+ const nextTrace = await tracePack({
1822
+ context,
1823
+ project,
1824
+ working_set_files: workingSetText.split(/\n|,/).map((value) => value.trim()).filter(Boolean)
1825
+ });
1826
+ if (String(state.feedQuery || "").trim() !== context || (state.currentProject || null) !== project) return;
1827
+ setTrace(nextTrace);
1828
+ } catch (err) {
1829
+ if (String(state.feedQuery || "").trim() !== context || (state.currentProject || null) !== project) return;
1830
+ setError(err instanceof Error ? err.message : String(err));
1831
+ setErrorContextKey(contextKey);
1832
+ setTrace(null);
1833
+ } finally {
1834
+ setLoading(false);
1835
+ }
1836
+ };
1837
+ const selected = visibleTrace?.retrieval.candidates.filter((candidate) => candidate.disposition === "selected") || [];
1838
+ const dropped = visibleTrace?.retrieval.candidates.filter((candidate) => candidate.disposition === "dropped") || [];
1839
+ const deduped = visibleTrace?.retrieval.candidates.filter((candidate) => candidate.disposition === "deduped") || [];
1840
+ const trimmed = visibleTrace?.retrieval.candidates.filter((candidate) => candidate.disposition === "trimmed") || [];
1841
+ return _$1("div", { className: "feed-inspector" }, _$1("button", {
1842
+ className: "toggle-button",
1843
+ onClick: () => setOpen(!open),
1844
+ type: "button"
1845
+ }, open ? "Hide Context Inspector" : "Open Context Inspector"), open ? _$1("div", {
1846
+ className: "feed-card",
1847
+ style: "margin-top:12px;"
1848
+ }, [
1849
+ _$1("div", { className: "feed-card-header" }, [_$1("div", { className: "feed-card-title" }, "Context Inspector"), _$1("div", { className: "feed-card-meta" }, "Tracing the current Search query")]),
1850
+ _$1("div", { className: "feed-card-body" }, [
1851
+ _$1("input", {
1852
+ className: "feed-search",
1853
+ onInput: (event) => {
1854
+ state.feedQuery = String(event.currentTarget.value || "");
1855
+ setTrace(null);
1856
+ setError("");
1857
+ setErrorContextKey("");
1858
+ updateFeedView();
1859
+ },
1860
+ placeholder: "Trace a pack query…",
1861
+ value: state.feedQuery
1862
+ }),
1863
+ _$1("textarea", {
1864
+ onInput: (event) => setWorkingSetText(String(event.currentTarget.value || "")),
1865
+ placeholder: "Optional working-set files, one per line",
1866
+ rows: 3,
1867
+ style: "margin-top:8px; width:100%;",
1868
+ value: workingSetText
1869
+ }),
1870
+ _$1("div", { style: "display:flex; gap:8px; margin-top:8px; align-items:center;" }, _$1("button", {
1871
+ className: "toggle-button active",
1872
+ disabled: loading,
1873
+ onClick: () => void runTrace(),
1874
+ type: "button"
1875
+ }, loading ? "Tracing…" : "Run trace"), visibleTrace ? _$1("span", { className: "section-meta" }, `mode=${visibleTrace.mode.selected} · candidates=${visibleTrace.retrieval.candidate_count} · tokens=${visibleTrace.output.estimated_tokens}`) : null),
1876
+ trace && !visibleTrace ? _$1("div", {
1877
+ className: "section-meta",
1878
+ style: "margin-top:8px;"
1879
+ }, "Search context changed. Run trace again for the current query and project.") : null,
1880
+ visibleError ? _$1("div", {
1881
+ className: "section-meta",
1882
+ style: "margin-top:8px; color:#d96c6c;"
1883
+ }, visibleError) : null
1884
+ ]),
1885
+ visibleTrace ? _$1(k$2, null, [
1886
+ _$1(TraceCandidateGroup, {
1887
+ label: "Selected",
1888
+ candidates: selected
1889
+ }),
1890
+ _$1(TraceCandidateGroup, {
1891
+ label: "Dropped",
1892
+ candidates: dropped
1893
+ }),
1894
+ _$1(TraceCandidateGroup, {
1895
+ label: "Deduped",
1896
+ candidates: deduped
1897
+ }),
1898
+ _$1(TraceCandidateGroup, {
1899
+ label: "Trimmed",
1900
+ candidates: trimmed
1901
+ }),
1902
+ _$1("div", { className: "feed-card-body" }, [
1903
+ visibleTrace.assembly.collapsed_groups.length ? _$1("div", { className: "section-meta" }, `Collapsed duplicates: ${visibleTrace.assembly.collapsed_groups.map((group) => `kept #${group.kept} from [${group.dropped.join(", ")}]`).join(" · ")}`) : null,
1904
+ visibleTrace.assembly.trim_reasons.length ? _$1("div", { className: "section-meta" }, `Trim reasons: ${visibleTrace.assembly.trim_reasons.join(", ")}`) : null,
1905
+ _$1("div", { className: "section-meta" }, "Final pack"),
1906
+ _$1("pre", { style: "white-space:pre-wrap; overflow:auto;" }, visibleTrace.output.pack_text)
1907
+ ])
1908
+ ]) : null
1909
+ ]) : null);
1910
+ }
1769
1911
  function FeedTabView({ items, loadingText }) {
1770
1912
  return _$1(k$2, null, _$1("div", { className: "feed-controls" }, _$1("div", {
1771
1913
  className: "section-meta",
@@ -1779,7 +1921,7 @@
1779
1921
  },
1780
1922
  placeholder: "Search title, body, tags…",
1781
1923
  value: state.feedQuery
1782
- }), _$1(FeedToggle, {
1924
+ }), _$1(ContextInspectorPanel, {}), _$1(FeedToggle, {
1783
1925
  active: state.feedScopeFilter,
1784
1926
  id: "feedScopeToggle",
1785
1927
  onSelect: (value) => {
@@ -2016,6 +2158,7 @@
2016
2158
  const usagePayload = state.lastUsagePayload || {};
2017
2159
  const raw = state.lastRawEventsPayload && typeof state.lastRawEventsPayload === "object" ? state.lastRawEventsPayload : {};
2018
2160
  const syncStatus = state.lastSyncStatus || {};
2161
+ const maintenanceJobs = Array.isArray(stats.maintenance_jobs) ? stats.maintenance_jobs : [];
2019
2162
  const reliability = stats.reliability || {};
2020
2163
  const counts = reliability.counts || {};
2021
2164
  const rates = reliability.rates || {};
@@ -2121,6 +2264,23 @@
2121
2264
  const pipelineDetail = rawPending > 0 ? "Queue is actively draining" : "Queue is clear";
2122
2265
  const syncDetail = syncDisabled ? "Sync disabled" : syncNoPeers ? "No peers configured" : syncOfflinePeers ? `${peerCount} peers offline · last sync ${formatAgeShort(syncAgeSeconds)} ago` : `${peerCount} peers · last sync ${formatAgeShort(syncAgeSeconds)} ago`;
2123
2266
  const freshnessDetail = `last pack ${formatAgeShort(packAgeSeconds)} ago`;
2267
+ const maintenanceCards = maintenanceJobs.map((job) => {
2268
+ const current = Number(job.progress?.current || 0);
2269
+ const total = typeof job.progress?.total === "number" ? job.progress.total : null;
2270
+ const unit = String(job.progress?.unit || "items");
2271
+ const pct = total && total > 0 ? ` (${Math.round(100 * current / total)}%)` : "";
2272
+ const progress = total && total > 0 ? `${current.toLocaleString()}/${total.toLocaleString()} ${unit}${pct}` : `${current.toLocaleString()} ${unit}`;
2273
+ const isFailed = job.status === "failed";
2274
+ const detail = isFailed ? String(job.error || "unknown error").trim() : void 0;
2275
+ return buildHealthCard({
2276
+ label: String(job.title || job.kind || "Background maintenance"),
2277
+ value: isFailed ? "Failed" : progress,
2278
+ detail,
2279
+ icon: isFailed ? "alert-triangle" : "loader",
2280
+ className: isFailed ? "status-attention" : void 0,
2281
+ title: isFailed ? `Error: ${job.error || "unknown"}` : `${String(job.title || "Maintenance")} in progress`
2282
+ });
2283
+ });
2124
2284
  renderHealthCards(healthGrid, [
2125
2285
  buildHealthCard({
2126
2286
  label: "Overall health",
@@ -2130,6 +2290,7 @@
2130
2290
  className: `health-primary ${statusClass}`,
2131
2291
  title: drivers.length ? `Main signals: ${drivers.join(", ")}` : "No major risk signals detected"
2132
2292
  }),
2293
+ ...maintenanceCards,
2133
2294
  buildHealthCard({
2134
2295
  label: "Pipeline health",
2135
2296
  value: `${rawPending.toLocaleString()} pending`,
@@ -13620,7 +13781,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
13620
13781
  try {
13621
13782
  const runtime = await loadRuntimeInfo();
13622
13783
  if (!runtime?.version) return;
13623
- setRuntimeLabel(runtime.version, "dfc218f");
13784
+ setRuntimeLabel(runtime.version, "840f9e8");
13624
13785
  } catch {}
13625
13786
  }
13626
13787
  var lastAnnouncedRefreshState = null;
@@ -13773,6 +13934,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
13773
13934
  }
13774
13935
  $select("projectFilter")?.addEventListener("change", () => {
13775
13936
  state.currentProject = $select("projectFilter")?.value || "";
13937
+ updateFeedView(true);
13776
13938
  refresh();
13777
13939
  });
13778
13940
  var refreshDebounceTimer = null;