@ai-matrx/coding-sessions 0.2.0 → 0.3.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/engine/index.cjs +54 -10
  3. package/dist/engine/index.cjs.map +1 -1
  4. package/dist/engine/index.d.cts +1 -1
  5. package/dist/engine/index.d.ts +1 -1
  6. package/dist/engine/index.js +54 -10
  7. package/dist/engine/index.js.map +1 -1
  8. package/dist/{index-29t7n472.d.cts → index-Bbe11HoB.d.cts} +30 -3
  9. package/dist/{index-29t7n472.d.ts → index-Bbe11HoB.d.ts} +30 -3
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +12 -3
  12. package/dist/index.d.ts +12 -3
  13. package/dist/index.js.map +1 -1
  14. package/dist/react/index.cjs +34 -5
  15. package/dist/react/index.cjs.map +1 -1
  16. package/dist/react/index.d.cts +15 -1
  17. package/dist/react/index.d.ts +15 -1
  18. package/dist/react/index.js +34 -5
  19. package/dist/react/index.js.map +1 -1
  20. package/dist/server/index.cjs +44 -9
  21. package/dist/server/index.cjs.map +1 -1
  22. package/dist/server/index.d.cts +2 -2
  23. package/dist/server/index.d.ts +2 -2
  24. package/dist/server/index.js +44 -9
  25. package/dist/server/index.js.map +1 -1
  26. package/dist/sessions/index.cjs +26 -1
  27. package/dist/sessions/index.cjs.map +1 -1
  28. package/dist/sessions/index.d.cts +13 -5
  29. package/dist/sessions/index.d.ts +13 -5
  30. package/dist/sessions/index.js +26 -1
  31. package/dist/sessions/index.js.map +1 -1
  32. package/dist/{titles-eCnA5sY7.d.cts → titles-DjxUb0ji.d.cts} +8 -1
  33. package/dist/{titles-eCnA5sY7.d.ts → titles-DjxUb0ji.d.ts} +8 -1
  34. package/dist/ui/assets/index-BqzTnRFe.css +2 -0
  35. package/dist/ui/assets/{index-SuRr0-D2.js → index-U98AY8r-.js} +17 -17
  36. package/dist/ui/index.html +2 -2
  37. package/package.json +3 -3
  38. package/dist/ui/assets/index-BqpVx_My.css +0 -2
@@ -1613,6 +1613,7 @@ function codexHome(dir) {
1613
1613
  function defaultProviderHomes(home = import_node_os3.default.homedir()) {
1614
1614
  return {
1615
1615
  claudeProjects: import_node_path5.default.join(home, ".claude", "projects"),
1616
+ claudeVault: import_node_path5.default.join(home, ".claude", "claude-app-vault"),
1616
1617
  codex: [codexHome(import_node_path5.default.join(home, ".codex"))]
1617
1618
  };
1618
1619
  }
@@ -1784,6 +1785,12 @@ async function describeCodex(candidate, names) {
1784
1785
  activeElsewhere: null
1785
1786
  };
1786
1787
  }
1788
+ async function codexNames(homes, appTitles) {
1789
+ if (!appTitles) return readCodexIndex(homes.codex.map((h) => h.index));
1790
+ const out = /* @__PURE__ */ new Map();
1791
+ for (const [key, title] of appTitles) if (key.startsWith("codex:")) out.set(key.slice(6), title);
1792
+ return out;
1793
+ }
1787
1794
  async function readTail(file, size) {
1788
1795
  const start = Math.max(0, size - TAIL_BYTES);
1789
1796
  return parseJsonl(completeLines(await readSlice(file, start, Math.min(size, TAIL_BYTES)), start > 0));
@@ -1824,7 +1831,7 @@ async function discoverLocalSessions(options = {}) {
1824
1831
  const [claude, codex, names] = await Promise.all([
1825
1832
  claudeCandidates(homes.claudeProjects),
1826
1833
  codexCandidates(homes.codex),
1827
- readCodexIndex(homes.codex.map((h) => h.index))
1834
+ codexNames(homes, options.appTitles)
1828
1835
  ]);
1829
1836
  const candidates = [...claude, ...codex].sort((a, b) => b.mtimeMs - a.mtimeMs);
1830
1837
  const processes = await listProcesses();
@@ -1846,7 +1853,12 @@ async function findSessionFile(provider, providerSessionId, homes = defaultProvi
1846
1853
  if (!/^[0-9a-f-]{36}$/i.test(providerSessionId)) return null;
1847
1854
  const candidates = provider === "claude" ? await claudeCandidates(homes.claudeProjects) : await codexCandidates(homes.codex);
1848
1855
  const hits = candidates.filter((c) => c.id === providerSessionId).sort((a, b) => b.mtimeMs - a.mtimeMs);
1849
- return hits[0]?.file ?? null;
1856
+ if (hits[0]) return hits[0].file;
1857
+ if (provider === "claude" && homes.claudeVault) {
1858
+ const copy = import_node_path5.default.join(homes.claudeVault, providerSessionId, "transcript.jsonl");
1859
+ if ((await import_promises4.default.stat(copy).catch(() => null))?.isFile()) return copy;
1860
+ }
1861
+ return null;
1850
1862
  }
1851
1863
  var HISTORY_BUDGET = 24 * 1024 * 1024;
1852
1864
  var MAX_HISTORY_BUDGET = 256 * 1024 * 1024;
@@ -1900,8 +1912,8 @@ async function listSessionFiles(homes = defaultProviderHomes()) {
1900
1912
  ]);
1901
1913
  return [...claude, ...codex].sort((a, b) => b.mtimeMs - a.mtimeMs);
1902
1914
  }
1903
- async function describeSessionFile(candidate, codexNames) {
1904
- return (candidate.provider === "claude" ? describeClaude(candidate) : describeCodex(candidate, codexNames)).catch(
1915
+ async function describeSessionFile(candidate, codexNames2) {
1916
+ return (candidate.provider === "claude" ? describeClaude(candidate) : describeCodex(candidate, codexNames2)).catch(
1905
1917
  () => null
1906
1918
  );
1907
1919
  }
@@ -2096,12 +2108,12 @@ async function searchLocalChats(query, options = {}) {
2096
2108
  const raw = JSON.stringify(needle).slice(1, -1);
2097
2109
  const limit = Math.max(1, Math.min(options.limit ?? 30, 100));
2098
2110
  const deadline = Date.now() + (options.budgetMs ?? 3500);
2099
- const names = await readCodexIndex(homes.codex.map((h) => h.index));
2111
+ const names = await codexNames(homes, options.appTitles);
2100
2112
  const hits = [];
2101
2113
  let i = cursor;
2102
2114
  for (; i < files.length && hits.length < limit && Date.now() < deadline; i += 1) {
2103
2115
  const candidate = files[i];
2104
- const named = candidate.provider === "codex" ? names.get(candidate.id) : void 0;
2116
+ const named = options.appTitles?.get(`${candidate.provider}:${candidate.id}`) ?? (candidate.provider === "codex" ? names.get(candidate.id) : void 0);
2105
2117
  const nameHit = named !== void 0 && named.toLowerCase().includes(needle);
2106
2118
  const scanned = nameHit ? null : await scanFile(candidate.provider, candidate.file, needle, raw, deadline);
2107
2119
  if (scanned === TIMED_OUT) {
@@ -2135,6 +2147,11 @@ async function searchLocalChats(query, options = {}) {
2135
2147
  function titleHintKey(provider, sessionId) {
2136
2148
  return `${provider}:${sessionId}`;
2137
2149
  }
2150
+ function appTitlesOf(hints) {
2151
+ const out = /* @__PURE__ */ new Map();
2152
+ for (const [key, hint] of hints) out.set(key, hint.title);
2153
+ return out;
2154
+ }
2138
2155
 
2139
2156
  // src/engine/title-hints.ts
2140
2157
  function overlayHint(chat, hints, expected) {
@@ -2445,7 +2462,7 @@ function describeAuthStatus(provider, probe) {
2445
2462
  async function createCodingSessionsEngine(options = {}) {
2446
2463
  const dataDir = options.dataDir ?? import_node_path9.default.join(import_node_os5.default.homedir(), ".matrx", "coding-sessions");
2447
2464
  const stateDir = import_node_path9.default.join(dataDir, "paperclip-state");
2448
- const homes = options.homes ?? defaultProviderHomes();
2465
+ let homes = options.homes ?? defaultProviderHomes();
2449
2466
  const index = new RunIndex(dataDir);
2450
2467
  await index.load();
2451
2468
  const preferences = new PreferenceStore(dataDir);
@@ -2527,6 +2544,11 @@ async function createCodingSessionsEngine(options = {}) {
2527
2544
  }
2528
2545
  const titleHints = options.titleHints;
2529
2546
  const hintsNow = () => titleHints?.current() ?? null;
2547
+ const appTitles = () => {
2548
+ if (!titleHints) return void 0;
2549
+ const hints = hintsNow();
2550
+ return hints ? appTitlesOf(hints) : /* @__PURE__ */ new Map();
2551
+ };
2530
2552
  const unsubscribeHints = titleHints?.subscribe(() => emit({ type: "titles" })) ?? null;
2531
2553
  const withHintTitle = (session) => {
2532
2554
  const hint = session.providerSessionId ? hintsNow()?.get(titleHintKey(session.provider, session.providerSessionId)) : void 0;
@@ -3001,7 +3023,7 @@ async function createCodingSessionsEngine(options = {}) {
3001
3023
  );
3002
3024
  },
3003
3025
  async discoverSessions(opts) {
3004
- const read = await discoverLocalSessions({ limit: opts?.limit, homes, excludePids: ourPids() });
3026
+ const read = await discoverLocalSessions({ limit: opts?.limit, homes, excludePids: ourPids(), appTitles: appTitles() });
3005
3027
  const hints = hintsNow();
3006
3028
  const found = read.map((chat) => overlayHint(chat, hints, titleHints !== void 0));
3007
3029
  if (backups) {
@@ -3039,6 +3061,17 @@ async function createCodingSessionsEngine(options = {}) {
3039
3061
  }))
3040
3062
  );
3041
3063
  },
3064
+ async titleStatus() {
3065
+ if (!titleHints) return { owner: false, pending: false, problem: null };
3066
+ const problem = titleHints.problem?.() ?? null;
3067
+ return { owner: true, pending: hintsNow() === null && problem === null, problem };
3068
+ },
3069
+ async retryTitles() {
3070
+ titleHints?.retry?.();
3071
+ },
3072
+ setHomes(next) {
3073
+ homes = next;
3074
+ },
3042
3075
  async listSessions() {
3043
3076
  return index.sessions().map(withHintTitle);
3044
3077
  },
@@ -3215,7 +3248,7 @@ async function createCodingSessionsEngine(options = {}) {
3215
3248
  return all;
3216
3249
  },
3217
3250
  async searchChats(query, opts) {
3218
- const result = await searchLocalChats(String(query ?? ""), { homes, cursor: opts?.cursor, limit: opts?.limit });
3251
+ const result = await searchLocalChats(String(query ?? ""), { homes, cursor: opts?.cursor, limit: opts?.limit, appTitles: appTitles() });
3219
3252
  const hints = hintsNow();
3220
3253
  return { ...result, hits: result.hits.map((hit) => ({ ...hit, title: hints?.get(titleHintKey(hit.provider, hit.providerSessionId))?.title ?? hit.title })) };
3221
3254
  },
@@ -3299,6 +3332,8 @@ function openFolderIn(folder, target) {
3299
3332
  var BRIDGE_METHODS = [
3300
3333
  "providers",
3301
3334
  "discoverSessions",
3335
+ "titleStatus",
3336
+ "retryTitles",
3302
3337
  "recentFolders",
3303
3338
  "listSessions",
3304
3339
  "listRuns",