@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
@@ -1,4 +1,4 @@
1
- export { f as CodexHome, e as CodingSessionsAgentsOptions, c as CodingSessionsEngine, d as CodingSessionsEngineOptions, D as DEFAULT_SERVER_URL, g as DEFAULT_SUPABASE_URL, E as EFFORT_LEVELS, P as PreferenceStore, h as ProviderHomes, R as RAW_TRANSCRIPT_MAX_BYTES, i as RawBackupPolicy, j as RawBackupSink, k as RunStatus, T as TitleHint, l as TitleHints, m as buildCleanEnv, n as claudeDefaults, o as codexDefaults, p as codexHome, q as createAiMatrxRawBackupSink, r as createCodingSessionsEngine, s as createRawBackupScheduler, t as createTitleHintsStore, u as defaultProviderHomes, v as describeActivity, w as describeProviderStatus, x as discoverLocalSessions, y as endsWithOpenToolCall, z as findDrivingProcess, A as findSessionFile, B as isAllowedEnvName, F as listProcesses, G as readSessionFile, H as searchLocalChats, I as sessionActivity, J as snippetAround, K as titleHintKey } from '../index-29t7n472.cjs';
1
+ export { f as CodexHome, e as CodingSessionsAgentsOptions, c as CodingSessionsEngine, d as CodingSessionsEngineOptions, D as DEFAULT_SERVER_URL, g as DEFAULT_SUPABASE_URL, E as EFFORT_LEVELS, P as PreferenceStore, h as ProviderHomes, R as RAW_TRANSCRIPT_MAX_BYTES, i as RawBackupPolicy, j as RawBackupSink, k as RunStatus, T as TitleHint, l as TitleHints, m as buildCleanEnv, n as claudeDefaults, o as codexDefaults, p as codexHome, q as createAiMatrxRawBackupSink, r as createCodingSessionsEngine, s as createRawBackupScheduler, t as createTitleHintsStore, u as defaultProviderHomes, v as describeActivity, w as describeProviderStatus, x as discoverLocalSessions, y as endsWithOpenToolCall, z as findDrivingProcess, A as findSessionFile, B as isAllowedEnvName, F as listProcesses, G as readSessionFile, H as searchLocalChats, I as sessionActivity, J as snippetAround, K as titleHintKey } from '../index-Bbe11HoB.cjs';
2
2
  import '@ai-matrx/agents/portable/mcp';
3
3
  import '@ai-matrx/agents/portable';
4
4
  import '@ai-matrx/data';
@@ -1,4 +1,4 @@
1
- export { f as CodexHome, e as CodingSessionsAgentsOptions, c as CodingSessionsEngine, d as CodingSessionsEngineOptions, D as DEFAULT_SERVER_URL, g as DEFAULT_SUPABASE_URL, E as EFFORT_LEVELS, P as PreferenceStore, h as ProviderHomes, R as RAW_TRANSCRIPT_MAX_BYTES, i as RawBackupPolicy, j as RawBackupSink, k as RunStatus, T as TitleHint, l as TitleHints, m as buildCleanEnv, n as claudeDefaults, o as codexDefaults, p as codexHome, q as createAiMatrxRawBackupSink, r as createCodingSessionsEngine, s as createRawBackupScheduler, t as createTitleHintsStore, u as defaultProviderHomes, v as describeActivity, w as describeProviderStatus, x as discoverLocalSessions, y as endsWithOpenToolCall, z as findDrivingProcess, A as findSessionFile, B as isAllowedEnvName, F as listProcesses, G as readSessionFile, H as searchLocalChats, I as sessionActivity, J as snippetAround, K as titleHintKey } from '../index-29t7n472.js';
1
+ export { f as CodexHome, e as CodingSessionsAgentsOptions, c as CodingSessionsEngine, d as CodingSessionsEngineOptions, D as DEFAULT_SERVER_URL, g as DEFAULT_SUPABASE_URL, E as EFFORT_LEVELS, P as PreferenceStore, h as ProviderHomes, R as RAW_TRANSCRIPT_MAX_BYTES, i as RawBackupPolicy, j as RawBackupSink, k as RunStatus, T as TitleHint, l as TitleHints, m as buildCleanEnv, n as claudeDefaults, o as codexDefaults, p as codexHome, q as createAiMatrxRawBackupSink, r as createCodingSessionsEngine, s as createRawBackupScheduler, t as createTitleHintsStore, u as defaultProviderHomes, v as describeActivity, w as describeProviderStatus, x as discoverLocalSessions, y as endsWithOpenToolCall, z as findDrivingProcess, A as findSessionFile, B as isAllowedEnvName, F as listProcesses, G as readSessionFile, H as searchLocalChats, I as sessionActivity, J as snippetAround, K as titleHintKey } from '../index-Bbe11HoB.js';
2
2
  import '@ai-matrx/agents/portable/mcp';
3
3
  import '@ai-matrx/agents/portable';
4
4
  import '@ai-matrx/data';
@@ -1597,6 +1597,7 @@ function codexHome(dir) {
1597
1597
  function defaultProviderHomes(home = os3.homedir()) {
1598
1598
  return {
1599
1599
  claudeProjects: path5.join(home, ".claude", "projects"),
1600
+ claudeVault: path5.join(home, ".claude", "claude-app-vault"),
1600
1601
  codex: [codexHome(path5.join(home, ".codex"))]
1601
1602
  };
1602
1603
  }
@@ -1768,6 +1769,12 @@ async function describeCodex(candidate, names) {
1768
1769
  activeElsewhere: null
1769
1770
  };
1770
1771
  }
1772
+ async function codexNames(homes, appTitles) {
1773
+ if (!appTitles) return readCodexIndex(homes.codex.map((h) => h.index));
1774
+ const out = /* @__PURE__ */ new Map();
1775
+ for (const [key, title] of appTitles) if (key.startsWith("codex:")) out.set(key.slice(6), title);
1776
+ return out;
1777
+ }
1771
1778
  async function readTail(file, size) {
1772
1779
  const start = Math.max(0, size - TAIL_BYTES);
1773
1780
  return parseJsonl(completeLines(await readSlice(file, start, Math.min(size, TAIL_BYTES)), start > 0));
@@ -1808,7 +1815,7 @@ async function discoverLocalSessions(options = {}) {
1808
1815
  const [claude, codex, names] = await Promise.all([
1809
1816
  claudeCandidates(homes.claudeProjects),
1810
1817
  codexCandidates(homes.codex),
1811
- readCodexIndex(homes.codex.map((h) => h.index))
1818
+ codexNames(homes, options.appTitles)
1812
1819
  ]);
1813
1820
  const candidates = [...claude, ...codex].sort((a, b) => b.mtimeMs - a.mtimeMs);
1814
1821
  const processes = await listProcesses();
@@ -1830,7 +1837,12 @@ async function findSessionFile(provider, providerSessionId, homes = defaultProvi
1830
1837
  if (!/^[0-9a-f-]{36}$/i.test(providerSessionId)) return null;
1831
1838
  const candidates = provider === "claude" ? await claudeCandidates(homes.claudeProjects) : await codexCandidates(homes.codex);
1832
1839
  const hits = candidates.filter((c) => c.id === providerSessionId).sort((a, b) => b.mtimeMs - a.mtimeMs);
1833
- return hits[0]?.file ?? null;
1840
+ if (hits[0]) return hits[0].file;
1841
+ if (provider === "claude" && homes.claudeVault) {
1842
+ const copy = path5.join(homes.claudeVault, providerSessionId, "transcript.jsonl");
1843
+ if ((await fs4.stat(copy).catch(() => null))?.isFile()) return copy;
1844
+ }
1845
+ return null;
1834
1846
  }
1835
1847
  var HISTORY_BUDGET = 24 * 1024 * 1024;
1836
1848
  var MAX_HISTORY_BUDGET = 256 * 1024 * 1024;
@@ -1884,8 +1896,8 @@ async function listSessionFiles(homes = defaultProviderHomes()) {
1884
1896
  ]);
1885
1897
  return [...claude, ...codex].sort((a, b) => b.mtimeMs - a.mtimeMs);
1886
1898
  }
1887
- async function describeSessionFile(candidate, codexNames) {
1888
- return (candidate.provider === "claude" ? describeClaude(candidate) : describeCodex(candidate, codexNames)).catch(
1899
+ async function describeSessionFile(candidate, codexNames2) {
1900
+ return (candidate.provider === "claude" ? describeClaude(candidate) : describeCodex(candidate, codexNames2)).catch(
1889
1901
  () => null
1890
1902
  );
1891
1903
  }
@@ -2080,12 +2092,12 @@ async function searchLocalChats(query, options = {}) {
2080
2092
  const raw = JSON.stringify(needle).slice(1, -1);
2081
2093
  const limit = Math.max(1, Math.min(options.limit ?? 30, 100));
2082
2094
  const deadline = Date.now() + (options.budgetMs ?? 3500);
2083
- const names = await readCodexIndex(homes.codex.map((h) => h.index));
2095
+ const names = await codexNames(homes, options.appTitles);
2084
2096
  const hits = [];
2085
2097
  let i = cursor;
2086
2098
  for (; i < files.length && hits.length < limit && Date.now() < deadline; i += 1) {
2087
2099
  const candidate = files[i];
2088
- const named = candidate.provider === "codex" ? names.get(candidate.id) : void 0;
2100
+ const named = options.appTitles?.get(`${candidate.provider}:${candidate.id}`) ?? (candidate.provider === "codex" ? names.get(candidate.id) : void 0);
2089
2101
  const nameHit = named !== void 0 && named.toLowerCase().includes(needle);
2090
2102
  const scanned = nameHit ? null : await scanFile(candidate.provider, candidate.file, needle, raw, deadline);
2091
2103
  if (scanned === TIMED_OUT) {
@@ -2121,19 +2133,35 @@ function titleHintKey(provider, sessionId) {
2121
2133
  }
2122
2134
  function createTitleHintsStore() {
2123
2135
  let hints = null;
2136
+ let problem = null;
2124
2137
  const listeners = /* @__PURE__ */ new Set();
2138
+ const tell = () => {
2139
+ for (const l of listeners) l();
2140
+ };
2125
2141
  return {
2126
2142
  current: () => hints,
2143
+ problem: () => problem,
2127
2144
  subscribe(listener) {
2128
2145
  listeners.add(listener);
2129
2146
  return () => listeners.delete(listener);
2130
2147
  },
2131
2148
  set(next) {
2132
2149
  hints = next;
2133
- for (const l of listeners) l();
2150
+ problem = null;
2151
+ tell();
2152
+ },
2153
+ setProblem(next) {
2154
+ if (next === problem) return;
2155
+ problem = next;
2156
+ tell();
2134
2157
  }
2135
2158
  };
2136
2159
  }
2160
+ function appTitlesOf(hints) {
2161
+ const out = /* @__PURE__ */ new Map();
2162
+ for (const [key, hint] of hints) out.set(key, hint.title);
2163
+ return out;
2164
+ }
2137
2165
 
2138
2166
  // src/engine/title-hints.ts
2139
2167
  function overlayHint(chat, hints, expected) {
@@ -2444,7 +2472,7 @@ function describeAuthStatus(provider, probe) {
2444
2472
  async function createCodingSessionsEngine(options = {}) {
2445
2473
  const dataDir = options.dataDir ?? path9.join(os5.homedir(), ".matrx", "coding-sessions");
2446
2474
  const stateDir = path9.join(dataDir, "paperclip-state");
2447
- const homes = options.homes ?? defaultProviderHomes();
2475
+ let homes = options.homes ?? defaultProviderHomes();
2448
2476
  const index = new RunIndex(dataDir);
2449
2477
  await index.load();
2450
2478
  const preferences = new PreferenceStore(dataDir);
@@ -2526,6 +2554,11 @@ async function createCodingSessionsEngine(options = {}) {
2526
2554
  }
2527
2555
  const titleHints = options.titleHints;
2528
2556
  const hintsNow = () => titleHints?.current() ?? null;
2557
+ const appTitles = () => {
2558
+ if (!titleHints) return void 0;
2559
+ const hints = hintsNow();
2560
+ return hints ? appTitlesOf(hints) : /* @__PURE__ */ new Map();
2561
+ };
2529
2562
  const unsubscribeHints = titleHints?.subscribe(() => emit({ type: "titles" })) ?? null;
2530
2563
  const withHintTitle = (session) => {
2531
2564
  const hint = session.providerSessionId ? hintsNow()?.get(titleHintKey(session.provider, session.providerSessionId)) : void 0;
@@ -3000,7 +3033,7 @@ async function createCodingSessionsEngine(options = {}) {
3000
3033
  );
3001
3034
  },
3002
3035
  async discoverSessions(opts) {
3003
- const read = await discoverLocalSessions({ limit: opts?.limit, homes, excludePids: ourPids() });
3036
+ const read = await discoverLocalSessions({ limit: opts?.limit, homes, excludePids: ourPids(), appTitles: appTitles() });
3004
3037
  const hints = hintsNow();
3005
3038
  const found = read.map((chat) => overlayHint(chat, hints, titleHints !== void 0));
3006
3039
  if (backups) {
@@ -3038,6 +3071,17 @@ async function createCodingSessionsEngine(options = {}) {
3038
3071
  }))
3039
3072
  );
3040
3073
  },
3074
+ async titleStatus() {
3075
+ if (!titleHints) return { owner: false, pending: false, problem: null };
3076
+ const problem = titleHints.problem?.() ?? null;
3077
+ return { owner: true, pending: hintsNow() === null && problem === null, problem };
3078
+ },
3079
+ async retryTitles() {
3080
+ titleHints?.retry?.();
3081
+ },
3082
+ setHomes(next) {
3083
+ homes = next;
3084
+ },
3041
3085
  async listSessions() {
3042
3086
  return index.sessions().map(withHintTitle);
3043
3087
  },
@@ -3214,7 +3258,7 @@ async function createCodingSessionsEngine(options = {}) {
3214
3258
  return all;
3215
3259
  },
3216
3260
  async searchChats(query, opts) {
3217
- const result = await searchLocalChats(String(query ?? ""), { homes, cursor: opts?.cursor, limit: opts?.limit });
3261
+ const result = await searchLocalChats(String(query ?? ""), { homes, cursor: opts?.cursor, limit: opts?.limit, appTitles: appTitles() });
3218
3262
  const hints = hintsNow();
3219
3263
  return { ...result, hits: result.hits.map((hit) => ({ ...hit, title: hints?.get(titleHintKey(hit.provider, hit.providerSessionId))?.title ?? hit.title })) };
3220
3264
  },