chat-recall 0.7.12 → 0.7.13

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/cli.js CHANGED
@@ -7118,7 +7118,7 @@ function markersFromTurns(sessionId, turns) {
7118
7118
  const prompts = turns.filter((t) => t.kind === "user" && t.text).map((t) => ({ line: t.line, ts: t.ts, tsIso: t.tsIso, ...markPrompt(t.text) }));
7119
7119
  return { v: MARKERS_VERSION, sessionId, prompts, summary: summarizeMarkers(prompts) };
7120
7120
  }
7121
- var PROFANITY, PROFANITY_LOOSE, APPROVAL_HEAD, NEG_HEAD, QUESTION_HEAD, DIRECTIVE_HEAD, CLARIFY_PHRASES, FRUSTRATED_PHRASES, MARKERS_VERSION;
7121
+ var PROFANITY, PROFANITY_LOOSE, APPROVAL_HEAD, NEG_HEAD, QUESTION_HEAD, DIRECTIVE_HEAD, CLARIFY_PHRASES, FRUSTRATED_PHRASES, MARKERS_VERSION, MARKERS_TURN_OPTS;
7122
7122
  var init_session_sentiment = __esm({
7123
7123
  "../engine/dist/core/session-sentiment.js"() {
7124
7124
  "use strict";
@@ -7132,6 +7132,7 @@ var init_session_sentiment = __esm({
7132
7132
  CLARIFY_PHRASES = /\b(?:wdym|what do you mean|explain|clarify|what is|what's|huh\??|i don'?t understand)\b/i;
7133
7133
  FRUSTRATED_PHRASES = /\b(?:why (?:the )?(?:fuck|hell)|wtf|are you (?:kidding|serious)|stop slacking|stop making|why did you|why didn'?t you|i (?:fucking )?(?:asked|told you)|are you (?:listening|even)|come\s*on|just\s+do)\b/i;
7134
7134
  MARKERS_VERSION = 3;
7135
+ MARKERS_TURN_OPTS = { maxTurns: 5e4, userMax: Number.POSITIVE_INFINITY };
7135
7136
  }
7136
7137
  });
7137
7138
 
@@ -7307,7 +7308,7 @@ function extractTurnsAny(sessionId, opts = {}) {
7307
7308
  const backend = getBackendForId(sessionId);
7308
7309
  if (!backend)
7309
7310
  return { sessionId, found: false, turns: [], startMs: 0, endMs: 0 };
7310
- return memoInSessionScope(`turns:${sessionId}:${opts.maxTurns ?? ""}:${opts.assistantMax ?? ""}`, () => backend.extractTurns(sessionId, opts));
7311
+ return memoInSessionScope(`turns:${sessionId}:${opts.maxTurns ?? ""}:${opts.assistantMax ?? ""}:${opts.userMax ?? ""}`, () => backend.extractTurns(sessionId, opts));
7311
7312
  }
7312
7313
  function replaySessionAny(sessionId) {
7313
7314
  const backend = getBackendForId(sessionId);
@@ -7519,6 +7520,7 @@ function shorten(text, max) {
7519
7520
  function extractTurnsFromEvents(sessionId, events, opts = {}) {
7520
7521
  const maxTurns = opts.maxTurns ?? DEFAULT_MAX_TURNS;
7521
7522
  const assistantMax = opts.assistantMax ?? DEFAULT_ASSISTANT_MAX;
7523
+ const userMax = opts.userMax ?? DEFAULT_USER_MAX;
7522
7524
  const turns = [];
7523
7525
  let startMs = 0, endMs = 0;
7524
7526
  let found = false;
@@ -7536,7 +7538,7 @@ function extractTurnsFromEvents(sessionId, events, opts = {}) {
7536
7538
  ts: e.ts,
7537
7539
  tsIso: e.tsIso,
7538
7540
  line: e.line,
7539
- text: shorten(e.text, DEFAULT_USER_MAX)
7541
+ text: shorten(e.text, userMax)
7540
7542
  });
7541
7543
  } else if (e.kind === "assistant_text" && e.text) {
7542
7544
  turns.push({
@@ -18936,7 +18938,7 @@ var init_http = __esm({
18936
18938
  CLI_VERSION = JSON.parse(readFileSync31(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
18937
18939
  } catch {
18938
18940
  try {
18939
- if (true) CLI_VERSION = "0.7.12";
18941
+ if (true) CLI_VERSION = "0.7.13";
18940
18942
  } catch {
18941
18943
  }
18942
18944
  }
@@ -18980,7 +18982,7 @@ function collectDerivedRows(ref, mtime, count, maxRowBytes) {
18980
18982
  if (!fullOutcome) fullOutcome = computeOutcome(id);
18981
18983
  if (fullOutcome.found) data = fullOutcome.commits;
18982
18984
  } else if (kind === "markers") {
18983
- const turns = extractTurnsAny(id, { maxTurns: 5e4 });
18985
+ const turns = extractTurnsAny(id, MARKERS_TURN_OPTS);
18984
18986
  data = markersFromTurns(id, turns.turns);
18985
18987
  }
18986
18988
  } catch {
@@ -19434,7 +19436,7 @@ var init_telemetry = __esm({
19434
19436
  init_sync_client();
19435
19437
  cliVersion2 = () => {
19436
19438
  try {
19437
- return true ? "0.7.12" : "dev";
19439
+ return true ? "0.7.13" : "dev";
19438
19440
  } catch {
19439
19441
  return "dev";
19440
19442
  }
@@ -21815,7 +21817,7 @@ var init_sync_client = __esm({
21815
21817
  ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
21816
21818
  } catch {
21817
21819
  try {
21818
- if (true) ownVersion = "0.7.12";
21820
+ if (true) ownVersion = "0.7.13";
21819
21821
  } catch {
21820
21822
  }
21821
21823
  }
@@ -25977,7 +25979,7 @@ var init_intent_drain = __esm({
25977
25979
  ownVersion2 = JSON.parse(readFileSync45(join56(dir, "../package.json"), "utf-8")).version || ownVersion2;
25978
25980
  } catch {
25979
25981
  try {
25980
- if (true) ownVersion2 = "0.7.12";
25982
+ if (true) ownVersion2 = "0.7.13";
25981
25983
  } catch {
25982
25984
  }
25983
25985
  }
@@ -28044,17 +28046,21 @@ function safeSlice(s, start, end) {
28044
28046
  const hi = end < s.length && /[\uD800-\uDBFF]/.test(s[end - 1] ?? "") ? end + 1 : end;
28045
28047
  return s.slice(lo, hi);
28046
28048
  }
28047
- function body(text, line, opts) {
28048
- if (opts.full || text.length <= BODY_LIMIT)
28049
- return indent(text);
28049
+ function headTail(text, how) {
28050
+ if (text.length <= BODY_LIMIT)
28051
+ return [text];
28050
28052
  const lines = text.split("\n").length;
28051
28053
  const cut = text.length - 2 * EDGE;
28052
- const how = opts.expandHint ? ` ${opts.expandHint(line)}` : "";
28053
28054
  return [
28054
- indent(safeSlice(text, 0, EDGE)),
28055
- `${INDENT}\u2026 ${cut} characters cut (${text.length} in all, ${lines} lines).${how} \u2026`,
28056
- indent(safeSlice(text, text.length - EDGE, text.length))
28057
- ].join("\n");
28055
+ safeSlice(text, 0, EDGE),
28056
+ `\u2026 ${cut} characters cut (${text.length} in all, ${lines} lines).${how ? ` ${how}` : ""} \u2026`,
28057
+ safeSlice(text, text.length - EDGE, text.length)
28058
+ ];
28059
+ }
28060
+ function body(text, line, opts) {
28061
+ if (opts.full)
28062
+ return indent(text);
28063
+ return headTail(text, opts.expandHint?.(line)).map(indent).join("\n");
28058
28064
  }
28059
28065
  function resultText(result) {
28060
28066
  if (typeof result === "string")
package/dist/derived.js CHANGED
@@ -22,7 +22,7 @@
22
22
  import { withSessionReadCache } from '@chat-recall/engine/core/live-session-scan.js';
23
23
  import { replaySessionAny, extractTurnsAny } from '@chat-recall/engine/core/session-multi-tool.js';
24
24
  import { computeOutcome } from '@chat-recall/engine/core/session-outcome.js';
25
- import { markersFromTurns } from '@chat-recall/engine/core/session-sentiment.js';
25
+ import { markersFromTurns, MARKERS_TURN_OPTS } from '@chat-recall/engine/core/session-sentiment.js';
26
26
  import { redactDeep } from './redact-deep.js';
27
27
  /** Which compute rows a session ships. */
28
28
  export const COMPUTE_KINDS = ['diff', 'outcome', 'commits', 'markers'];
@@ -57,7 +57,7 @@ export function collectDerivedRows(ref, mtime, count, maxRowBytes) {
57
57
  else if (kind === 'markers') {
58
58
  // Analysis-only use of the turns extractor (R4) — markers need
59
59
  // per-prompt line/ts, not render fidelity.
60
- const turns = extractTurnsAny(id, { maxTurns: 50_000 });
60
+ const turns = extractTurnsAny(id, MARKERS_TURN_OPTS);
61
61
  data = markersFromTurns(id, turns.turns);
62
62
  }
63
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"derived.js","sourceRoot":"","sources":["../src/derived.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"derived.js","sourceRoot":"","sources":["../src/derived.ts"],"names":[],"mappings":"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"}
package/dist/mcp-relay.js CHANGED
@@ -192,7 +192,7 @@ function bridge(input, output, sock, exit, opts = {}) {
192
192
  }
193
193
 
194
194
  // src/mcp-relay.ts
195
- var VERSION = true ? "0.7.12" : "0.0.0";
195
+ var VERSION = true ? "0.7.13" : "0.0.0";
196
196
  var SERVER_URL = new URL("./mcp.js", import.meta.url);
197
197
  var SERVER_PATH = fileURLToPath(SERVER_URL);
198
198
  var START_TIMEOUT_MS = 15e3;
package/dist/mcp.js CHANGED
@@ -6035,7 +6035,7 @@ function markersFromTurns(sessionId, turns) {
6035
6035
  const prompts = turns.filter((t) => t.kind === "user" && t.text).map((t) => ({ line: t.line, ts: t.ts, tsIso: t.tsIso, ...markPrompt(t.text) }));
6036
6036
  return { v: MARKERS_VERSION, sessionId, prompts, summary: summarizeMarkers(prompts) };
6037
6037
  }
6038
- var PROFANITY, PROFANITY_LOOSE, APPROVAL_HEAD, NEG_HEAD, QUESTION_HEAD, DIRECTIVE_HEAD, CLARIFY_PHRASES, FRUSTRATED_PHRASES, MARKERS_VERSION;
6038
+ var PROFANITY, PROFANITY_LOOSE, APPROVAL_HEAD, NEG_HEAD, QUESTION_HEAD, DIRECTIVE_HEAD, CLARIFY_PHRASES, FRUSTRATED_PHRASES, MARKERS_VERSION, MARKERS_TURN_OPTS;
6039
6039
  var init_session_sentiment = __esm({
6040
6040
  "../engine/dist/core/session-sentiment.js"() {
6041
6041
  "use strict";
@@ -6049,6 +6049,7 @@ var init_session_sentiment = __esm({
6049
6049
  CLARIFY_PHRASES = /\b(?:wdym|what do you mean|explain|clarify|what is|what's|huh\??|i don'?t understand)\b/i;
6050
6050
  FRUSTRATED_PHRASES = /\b(?:why (?:the )?(?:fuck|hell)|wtf|are you (?:kidding|serious)|stop slacking|stop making|why did you|why didn'?t you|i (?:fucking )?(?:asked|told you)|are you (?:listening|even)|come\s*on|just\s+do)\b/i;
6051
6051
  MARKERS_VERSION = 3;
6052
+ MARKERS_TURN_OPTS = { maxTurns: 5e4, userMax: Number.POSITIVE_INFINITY };
6052
6053
  }
6053
6054
  });
6054
6055
 
@@ -6274,6 +6275,7 @@ function shorten(text, max) {
6274
6275
  function extractTurnsFromEvents(sessionId, events, opts = {}) {
6275
6276
  const maxTurns = opts.maxTurns ?? DEFAULT_MAX_TURNS;
6276
6277
  const assistantMax = opts.assistantMax ?? DEFAULT_ASSISTANT_MAX;
6278
+ const userMax = opts.userMax ?? DEFAULT_USER_MAX;
6277
6279
  const turns = [];
6278
6280
  let startMs = 0, endMs = 0;
6279
6281
  let found = false;
@@ -6291,7 +6293,7 @@ function extractTurnsFromEvents(sessionId, events, opts = {}) {
6291
6293
  ts: e.ts,
6292
6294
  tsIso: e.tsIso,
6293
6295
  line: e.line,
6294
- text: shorten(e.text, DEFAULT_USER_MAX)
6296
+ text: shorten(e.text, userMax)
6295
6297
  });
6296
6298
  } else if (e.kind === "assistant_text" && e.text) {
6297
6299
  turns.push({
@@ -9655,7 +9657,7 @@ function extractTurnsAny(sessionId, opts = {}) {
9655
9657
  const backend = getBackendForId(sessionId);
9656
9658
  if (!backend)
9657
9659
  return { sessionId, found: false, turns: [], startMs: 0, endMs: 0 };
9658
- return memoInSessionScope(`turns:${sessionId}:${opts.maxTurns ?? ""}:${opts.assistantMax ?? ""}`, () => backend.extractTurns(sessionId, opts));
9660
+ return memoInSessionScope(`turns:${sessionId}:${opts.maxTurns ?? ""}:${opts.assistantMax ?? ""}:${opts.userMax ?? ""}`, () => backend.extractTurns(sessionId, opts));
9659
9661
  }
9660
9662
  function replaySessionAny(sessionId) {
9661
9663
  const backend = getBackendForId(sessionId);
@@ -12938,9 +12940,9 @@ function judgeHealth(h, now = Date.now()) {
12938
12940
  return (a.t.lastOkAt ?? 0) - (b.t.lastOkAt ?? 0);
12939
12941
  });
12940
12942
  const worst = ranked[0];
12941
- const when = worst.t.lastOkAt ? `${ago(now - worst.t.lastOkAt)} ago` : "never";
12943
+ const when2 = worst.t.lastOkAt ? `${ago(now - worst.t.lastOkAt)} ago` : "never";
12942
12944
  const why = worst.t.lastError ? ` (${worst.t.lastError})` : "";
12943
- reasons.push(`nothing has synced since ${when}${why}`);
12945
+ reasons.push(`nothing has synced since ${when2}${why}`);
12944
12946
  }
12945
12947
  if (reasons.length === 0)
12946
12948
  return { ok: true, summary: null, reasons: [] };
@@ -19844,7 +19846,7 @@ var init_http = __esm({
19844
19846
  CLI_VERSION = JSON.parse(readFileSync36(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
19845
19847
  } catch {
19846
19848
  try {
19847
- if (true) CLI_VERSION = "0.7.12";
19849
+ if (true) CLI_VERSION = "0.7.13";
19848
19850
  } catch {
19849
19851
  }
19850
19852
  }
@@ -19888,7 +19890,7 @@ function collectDerivedRows(ref, mtime, count, maxRowBytes) {
19888
19890
  if (!fullOutcome) fullOutcome = computeOutcome(id);
19889
19891
  if (fullOutcome.found) data = fullOutcome.commits;
19890
19892
  } else if (kind === "markers") {
19891
- const turns = extractTurnsAny(id, { maxTurns: 5e4 });
19893
+ const turns = extractTurnsAny(id, MARKERS_TURN_OPTS);
19892
19894
  data = markersFromTurns(id, turns.turns);
19893
19895
  }
19894
19896
  } catch {
@@ -20342,7 +20344,7 @@ var init_telemetry = __esm({
20342
20344
  init_sync_client();
20343
20345
  cliVersion2 = () => {
20344
20346
  try {
20345
- return true ? "0.7.12" : "dev";
20347
+ return true ? "0.7.13" : "dev";
20346
20348
  } catch {
20347
20349
  return "dev";
20348
20350
  }
@@ -22505,7 +22507,7 @@ var init_sync_client = __esm({
22505
22507
  ownVersion = JSON.parse(readFileSync38(join49(dir, "../package.json"), "utf-8")).version || ownVersion;
22506
22508
  } catch {
22507
22509
  try {
22508
- if (true) ownVersion = "0.7.12";
22510
+ if (true) ownVersion = "0.7.13";
22509
22511
  } catch {
22510
22512
  }
22511
22513
  }
@@ -23982,8 +23984,8 @@ function formatDigest(input, summaryChars = 400) {
23982
23984
  const { row, outcome, related, resumeCmd } = input;
23983
23985
  const lines = [];
23984
23986
  lines.push(`### ${digestTitle(row)}`);
23985
- const when = (row.modified || "").slice(0, 16).replace("T", " ");
23986
- lines.push(`**Project:** ${projectName(row.projectPath) || "(unknown)"} \xB7 **Tool:** ${row.tool || "claude"}` + (when ? ` \xB7 **Modified:** ${when}` : "") + ` \xB7 \`${row.sessionId}\``);
23987
+ const when2 = (row.modified || "").slice(0, 16).replace("T", " ");
23988
+ lines.push(`**Project:** ${projectName(row.projectPath) || "(unknown)"} \xB7 **Tool:** ${row.tool || "claude"}` + (when2 ? ` \xB7 **Modified:** ${when2}` : "") + ` \xB7 \`${row.sessionId}\``);
23987
23989
  if (outcome) {
23988
23990
  const edits = outcome.fileCount > 0 ? ` \xB7 ${outcome.fileCount} file(s) +${outcome.totalLinesAdded}/\u2212${outcome.totalLinesRemoved}` : "";
23989
23991
  const commits = outcome.commits && outcome.commits.totalCommits > 0 ? ` \xB7 ${outcome.commits.totalCommits} commit(s)` : "";
@@ -24043,17 +24045,21 @@ function safeSlice(s, start, end) {
24043
24045
  const hi = end < s.length && /[\uD800-\uDBFF]/.test(s[end - 1] ?? "") ? end + 1 : end;
24044
24046
  return s.slice(lo, hi);
24045
24047
  }
24046
- function body(text, line, opts) {
24047
- if (opts.full || text.length <= BODY_LIMIT)
24048
- return indent(text);
24048
+ function headTail(text, how) {
24049
+ if (text.length <= BODY_LIMIT)
24050
+ return [text];
24049
24051
  const lines = text.split("\n").length;
24050
24052
  const cut = text.length - 2 * EDGE;
24051
- const how = opts.expandHint ? ` ${opts.expandHint(line)}` : "";
24052
24053
  return [
24053
- indent(safeSlice(text, 0, EDGE)),
24054
- `${INDENT}\u2026 ${cut} characters cut (${text.length} in all, ${lines} lines).${how} \u2026`,
24055
- indent(safeSlice(text, text.length - EDGE, text.length))
24056
- ].join("\n");
24054
+ safeSlice(text, 0, EDGE),
24055
+ `\u2026 ${cut} characters cut (${text.length} in all, ${lines} lines).${how ? ` ${how}` : ""} \u2026`,
24056
+ safeSlice(text, text.length - EDGE, text.length)
24057
+ ];
24058
+ }
24059
+ function body(text, line, opts) {
24060
+ if (opts.full)
24061
+ return indent(text);
24062
+ return headTail(text, opts.expandHint?.(line)).map(indent).join("\n");
24057
24063
  }
24058
24064
  function resultText(result) {
24059
24065
  if (typeof result === "string")
@@ -24175,6 +24181,59 @@ function findShowMessages(messages, query) {
24175
24181
  return messages.filter((m) => searchableText(m).toLowerCase().includes(needle));
24176
24182
  }
24177
24183
 
24184
+ // ../engine/dist/mcp/prompts-render.js
24185
+ var fold = (s) => s.toLowerCase().replace(/\s+/g, " ");
24186
+ function when(p, sessionMs) {
24187
+ if (p.ts && p.ts > 0)
24188
+ return p.ts;
24189
+ const parsed = p.tsIso ? Date.parse(p.tsIso) : NaN;
24190
+ return Number.isFinite(parsed) ? parsed : sessionMs;
24191
+ }
24192
+ function newestFirst(a, b) {
24193
+ if (b.at !== a.at)
24194
+ return b.at - a.at;
24195
+ if (a.row.sessionId === b.row.sessionId)
24196
+ return b.row.line - a.row.line;
24197
+ return 0;
24198
+ }
24199
+ function matching(rows, query) {
24200
+ const q = query ? fold(query.trim()) : "";
24201
+ return rows.filter((p) => p.text && p.text.trim() && (!q || fold(p.text).includes(q)));
24202
+ }
24203
+ function selectPrompts(rows, opts) {
24204
+ return matching(rows, opts.query).map((row) => ({ row, at: when(row, 0) })).sort(newestFirst).slice(0, Math.max(0, opts.limit)).map((x) => x.row);
24205
+ }
24206
+ async function collectAcrossSessions(feed, fetchPrompts, opts) {
24207
+ const limit = Math.max(0, opts.limit);
24208
+ let kept = [];
24209
+ for (const s of feed) {
24210
+ if (kept.length >= limit && s.modifiedMs < kept[kept.length - 1].at)
24211
+ break;
24212
+ const rows = await fetchPrompts(s.sessionId);
24213
+ if (!rows)
24214
+ continue;
24215
+ for (const row of matching(rows, opts.query))
24216
+ kept.push({ row, at: when(row, s.modifiedMs) });
24217
+ kept = kept.sort(newestFirst).slice(0, limit);
24218
+ }
24219
+ return kept.map((x) => x.row);
24220
+ }
24221
+ function renderPrompts(rows, opts) {
24222
+ const what = opts.query ? `, containing "${opts.query.trim()}"` : "";
24223
+ const lines = [`# User prompts (${rows.length}${what}, newest first)
24224
+ `];
24225
+ for (const p of rows) {
24226
+ const t = p.tsIso?.slice(0, 16).replace("T", " ") || "";
24227
+ const markerSuffix = opts.withMarkers && p.markers.length ? ` _[${p.markers.join(", ")}]_` : "";
24228
+ lines.push(`- **${p.sessionId}** L${p.line}${t ? ` \xB7 ${t}` : ""}${markerSuffix}`);
24229
+ const how = `Call recall_show with session_id "${p.sessionId}" and expand_line ${p.line} for the whole text.`;
24230
+ for (const part of headTail(p.text, how)) {
24231
+ lines.push(part.split("\n").map((l) => ` ${l}`).join("\n"));
24232
+ }
24233
+ }
24234
+ return lines.join("\n");
24235
+ }
24236
+
24178
24237
  // ../engine/dist/mcp/show-freshness.js
24179
24238
  init_tool_backend();
24180
24239
  init_transcript();
@@ -24411,14 +24470,14 @@ function trialEndingBanner(state2, serverBase) {
24411
24470
  const days = state2.trialDaysLeft;
24412
24471
  if (typeof days !== "number" || days > TRIAL_WARN_DAYS)
24413
24472
  return null;
24414
- const when = days <= 0 ? "today" : days === 1 ? "tomorrow" : `in ${days} days`;
24473
+ const when2 = days <= 0 ? "today" : days === 1 ? "tomorrow" : `in ${days} days`;
24415
24474
  const account = `${serverBase.replace(/\/+$/, "")}/app?view=account`;
24416
24475
  return [
24417
24476
  // No trial LENGTH here. It is FREE_TRIAL_DAYS on the server, so a "7-day
24418
24477
  // trial" written into the CLI is a number that drifts the first time that is
24419
24478
  // tuned — and this file already carries two sentences that went stale that
24420
24479
  // exact way. Days REMAINING comes from the server and is always right.
24421
- `\u23F3 TRIAL ENDS ${when.toUpperCase()} \u2014 this chat-recall account is on the free trial.`,
24480
+ `\u23F3 TRIAL ENDS ${when2.toUpperCase()} \u2014 this chat-recall account is on the free trial.`,
24422
24481
  "When it ends, recall switches off: searches and session reads stop, and new sessions stop syncing.",
24423
24482
  "Nothing is deleted \u2014 the history is kept and export keeps working.",
24424
24483
  `Tell the user now, and give them this link to subscribe or see the account: ${account}`
@@ -25200,7 +25259,8 @@ var RecallImprovementsSchema = z.object({
25200
25259
  var RecallUserPromptsSchema = z.object({
25201
25260
  session_id: z.string().optional().describe("If set, only that session's prompts"),
25202
25261
  since_days: z.number().optional().default(7).describe("When session_id is omitted, look back this many days"),
25203
- limit: z.number().optional().default(50).describe("Maximum prompts to return"),
25262
+ limit: z.number().optional().default(50).describe("Maximum prompts to return, newest first"),
25263
+ query: z.string().optional().describe("Keep only the prompts that contain this text (no case)"),
25204
25264
  with_markers: z.boolean().optional().default(true).describe("Tag each prompt with sentiment / corrective markers (interrupt, frustrated, correction, approval, \u2026). Set false to revert to legacy text-only output.")
25205
25265
  });
25206
25266
  function resolveRecordScope(params) {
@@ -26299,15 +26359,18 @@ write.`,
26299
26359
  // ── User-prompts / decision-record ──
26300
26360
  {
26301
26361
  name: "recall_user_prompts",
26302
- description: `List the human-typed prompts from a session (or recent sessions). Tool results
26303
- and system banners are stripped \u2014 you get only what the user actually wrote. Useful for "what was
26304
- I asking yesterday?" or "what did I tell the agent in this session?".`,
26362
+ description: `List the human-typed prompts from a session (or recent sessions), newest first.
26363
+ Tool results and system banners are stripped \u2014 you get only what the user actually wrote. Useful for
26364
+ "what was I asking yesterday?" or "what did I tell the agent in this session?". Pass \`query\` for
26365
+ "did I say X?": it keeps only the prompts that contain that text. Each prompt prints whole up to 2000
26366
+ characters; a longer one prints its start and end and the recall_show expand_line call for the rest.`,
26305
26367
  inputSchema: {
26306
26368
  type: "object",
26307
26369
  properties: {
26308
26370
  session_id: { type: "string", description: "If set, only that session's prompts" },
26309
26371
  since_days: { type: "number", default: 7, description: "How far back to look, in days." },
26310
- limit: { type: "number", default: 50, description: "Maximum prompts to return, newest first." }
26372
+ limit: { type: "number", default: 50, description: "Maximum prompts to return, newest first." },
26373
+ query: { type: "string", description: "Keep only the prompts that contain this text. Case and runs of whitespace are ignored." }
26311
26374
  }
26312
26375
  }
26313
26376
  },
@@ -27472,9 +27535,9 @@ _Edits stayed local or window was off \u2014 try increasing buffer_minutes._` }]
27472
27535
  const r = remote.results[i];
27473
27536
  const kind = r.chunkType?.match(/:(\w+):imp([0-9])/);
27474
27537
  const tag = kind ? ` \xB7 ${kind[1]} (imp${kind[2]})` : "";
27475
- const when = r.mtime ? ` \xB7 ${new Date(r.mtime).toISOString().slice(0, 10)}` : "";
27538
+ const when2 = r.mtime ? ` \xB7 ${new Date(r.mtime).toISOString().slice(0, 10)}` : "";
27476
27539
  lines.push(`## #${i + 1} [${r.sourceType}${tag}] ${(r.title || r.itemId).slice(0, 90)}`);
27477
- lines.push(`**id:** \`${r.itemId}\`${when}${r.projectPath ? ` \xB7 ${r.projectPath}` : ""}`);
27540
+ lines.push(`**id:** \`${r.itemId}\`${when2}${r.projectPath ? ` \xB7 ${r.projectPath}` : ""}`);
27478
27541
  if (r.sourceType === "session")
27479
27542
  lines.push(`_fetch: recall_context / recall_show "${r.itemId}"_`);
27480
27543
  const snippets = (r.matchedChunks?.length ? r.matchedChunks.map((c) => c.text) : [r.text]).filter(Boolean).slice(0, 3);
@@ -27766,8 +27829,8 @@ _Edits stayed local or window was off \u2014 try increasing buffer_minutes._` }]
27766
27829
  const total = rows.reduce((n, r) => n + r.sessions, 0);
27767
27830
  lines.push(`## ${member} \u2014 ${total} session(s)`);
27768
27831
  for (const r of [...rows].sort((x, y) => y.lastMtime - x.lastMtime)) {
27769
- const when = r.lastMtime ? new Date(r.lastMtime).toISOString().slice(0, 10) : "????";
27770
- lines.push(`- ${r.projectId} \xB7 ${r.sessions} session(s) \xB7 last active ${when}`);
27832
+ const when2 = r.lastMtime ? new Date(r.lastMtime).toISOString().slice(0, 10) : "????";
27833
+ lines.push(`- ${r.projectId} \xB7 ${r.sessions} session(s) \xB7 last active ${when2}`);
27771
27834
  }
27772
27835
  lines.push("");
27773
27836
  }
@@ -28448,54 +28511,35 @@ ${JSON.stringify(r, null, 2)}
28448
28511
  case "recall_user_prompts": {
28449
28512
  const params = RecallUserPromptsSchema.parse(args);
28450
28513
  requireRemote();
28451
- const renderPrompts = (rows) => {
28452
- const lines = [`# User prompts (${rows.length})
28453
- `];
28454
- for (const p of rows) {
28455
- const t = p.tsIso?.slice(0, 16).replace("T", " ") || "";
28456
- const snippet = p.text.length > 240 ? p.text.slice(0, 240) + "\u2026" : p.text;
28457
- const markerSuffix = params.with_markers && p.markers.length ? ` _[${p.markers.join(", ")}]_` : "";
28458
- lines.push(`- **${p.sessionId}** L${p.line}${t ? ` \xB7 ${t}` : ""}${markerSuffix}`);
28459
- lines.push(` ${snippet.replace(/\n/g, " ")}`);
28460
- }
28461
- return lines.join("\n");
28462
- };
28514
+ const toRows = (sessionId, prompts) => prompts.map((p) => ({ sessionId, line: p.line, ts: p.ts, tsIso: p.tsIso, markers: p.markers || [], text: p.text }));
28515
+ const select = { limit: params.limit, query: params.query };
28516
+ const render = (rows) => renderPrompts(rows, { withMarkers: params.with_markers, query: params.query });
28517
+ const none = params.query ? `No user prompts contain "${params.query.trim()}".` : "No user prompts found.";
28463
28518
  if (params.session_id) {
28464
28519
  const soft = await remoteGetSoft(`/api/conversations/${encodeURIComponent(params.session_id)}/markers`);
28465
28520
  if (!soft.data) {
28466
28521
  return { content: [{ type: "text", text: soft.message || (soft.status === 404 ? `Session ${params.session_id} not found.` : `Prompts not synced yet for ${params.session_id}.`) }] };
28467
28522
  }
28468
- const rows = soft.data.prompts.filter((p) => p.text && p.text.trim()).slice(0, params.limit).map((p) => ({ sessionId: params.session_id, line: p.line, tsIso: p.tsIso, markers: p.markers || [], text: p.text }));
28469
- if (rows.length === 0) {
28470
- return { content: [{ type: "text", text: "No user prompts found." }] };
28471
- }
28472
- return { content: [{ type: "text", text: renderPrompts(rows) }] };
28523
+ const rows = selectPrompts(toRows(params.session_id, soft.data.prompts), select);
28524
+ return { content: [{ type: "text", text: rows.length ? render(rows) : none }] };
28473
28525
  }
28474
28526
  const sinceHours = params.since_days * 24;
28475
28527
  const recent = await remoteGetQS("/api/conversations/recent", { limit: 200, since_hours: sinceHours });
28476
- const sessionIds = (recent.sessions || []).map((s) => s.sessionId);
28477
- if (sessionIds.length === 0) {
28478
- return { content: [{ type: "text", text: "No user prompts found." }] };
28479
- }
28480
- const collected = [];
28481
- for (const sid of sessionIds) {
28482
- if (collected.length >= params.limit)
28483
- break;
28528
+ const feed = (recent.sessions || []).map((s) => ({
28529
+ sessionId: s.sessionId,
28530
+ modifiedMs: s.fileMtime || (s.modified ? Date.parse(s.modified) : 0) || 0
28531
+ }));
28532
+ if (feed.length === 0) {
28533
+ return { content: [{ type: "text", text: none }] };
28534
+ }
28535
+ const collected = await collectAcrossSessions(feed, async (sid) => {
28484
28536
  const soft = await remoteGetSoft(`/api/conversations/${encodeURIComponent(sid)}/markers`);
28485
- if (!soft.data)
28486
- continue;
28487
- for (const p of soft.data.prompts) {
28488
- if (!p.text || !p.text.trim())
28489
- continue;
28490
- collected.push({ sessionId: sid, line: p.line, tsIso: p.tsIso, markers: p.markers || [], text: p.text });
28491
- if (collected.length >= params.limit)
28492
- break;
28493
- }
28494
- }
28537
+ return soft.data ? toRows(sid, soft.data.prompts) : null;
28538
+ }, select);
28495
28539
  if (collected.length === 0) {
28496
- return { content: [{ type: "text", text: "No user prompts found (none of the recent sessions have synced markers yet)." }] };
28540
+ return { content: [{ type: "text", text: params.query ? none : "No user prompts found (none of the recent sessions have synced markers yet)." }] };
28497
28541
  }
28498
- return { content: [{ type: "text", text: renderPrompts(collected) }] };
28542
+ return { content: [{ type: "text", text: render(collected) }] };
28499
28543
  }
28500
28544
  // ── Decision recording ────────────────────────────────────
28501
28545
  case "recall_decision_record": {
@@ -29091,9 +29135,9 @@ _Tell the user \u2014 this changes how future sessions treat their repo._` }] };
29091
29135
  }
29092
29136
  const lines = [`# Files resembling \`${params.filename}\` (${data.hits.length})`, "_You may have built this before._\n"];
29093
29137
  for (const h of data.hits) {
29094
- const when = h.mtime ? new Date(h.mtime).toISOString().slice(0, 10) : "";
29138
+ const when2 = h.mtime ? new Date(h.mtime).toISOString().slice(0, 10) : "";
29095
29139
  lines.push(`- \`${h.file}\` \u2014 ${h.reason} (score ${h.score})`);
29096
- lines.push(` ${h.project || "(no project)"} \xB7 ${h.sessionId}${when ? ` \xB7 ${when}` : ""}`);
29140
+ lines.push(` ${h.project || "(no project)"} \xB7 ${h.sessionId}${when2 ? ` \xB7 ${when2}` : ""}`);
29097
29141
  }
29098
29142
  return { content: [{ type: "text", text: lines.join("\n") }] };
29099
29143
  }
@@ -29135,8 +29179,8 @@ _Tell the user \u2014 this changes how future sessions treat their repo._` }] };
29135
29179
  const lines = [`# ${params.source_type} items (${data.items.length})
29136
29180
  `];
29137
29181
  for (const it of data.items) {
29138
- const when = it.mtime ? new Date(it.mtime).toISOString().slice(0, 10) : "";
29139
- lines.push(`- **${it.id}**${it.title ? ` \u2014 ${it.title}` : ""}${when ? ` \xB7 ${when}` : ""}`);
29182
+ const when2 = it.mtime ? new Date(it.mtime).toISOString().slice(0, 10) : "";
29183
+ lines.push(`- **${it.id}**${it.title ? ` \u2014 ${it.title}` : ""}${when2 ? ` \xB7 ${when2}` : ""}`);
29140
29184
  }
29141
29185
  return { content: [{ type: "text", text: lines.join("\n") }] };
29142
29186
  }
@@ -29454,7 +29498,7 @@ function installCrashGuards() {
29454
29498
  reportClientEvent2("mcp_crash", { message: err.stack || err.message });
29455
29499
  });
29456
29500
  }
29457
- var RELAY_VERSION = true ? "0.7.12" : "0.0.0";
29501
+ var RELAY_VERSION = true ? "0.7.13" : "0.0.0";
29458
29502
  function daemonIdleSecs() {
29459
29503
  const raw = process.env.CHAT_RECALL_DAEMON_IDLE_SECS;
29460
29504
  if (raw === void 0) return 900;
@@ -5829,7 +5829,7 @@ function markersFromTurns(sessionId, turns) {
5829
5829
  const prompts = turns.filter((t) => t.kind === "user" && t.text).map((t) => ({ line: t.line, ts: t.ts, tsIso: t.tsIso, ...markPrompt(t.text) }));
5830
5830
  return { v: MARKERS_VERSION, sessionId, prompts, summary: summarizeMarkers(prompts) };
5831
5831
  }
5832
- var PROFANITY, PROFANITY_LOOSE, APPROVAL_HEAD, NEG_HEAD, QUESTION_HEAD, DIRECTIVE_HEAD, CLARIFY_PHRASES, FRUSTRATED_PHRASES, MARKERS_VERSION;
5832
+ var PROFANITY, PROFANITY_LOOSE, APPROVAL_HEAD, NEG_HEAD, QUESTION_HEAD, DIRECTIVE_HEAD, CLARIFY_PHRASES, FRUSTRATED_PHRASES, MARKERS_VERSION, MARKERS_TURN_OPTS;
5833
5833
  var init_session_sentiment = __esm({
5834
5834
  "../engine/dist/core/session-sentiment.js"() {
5835
5835
  "use strict";
@@ -5843,6 +5843,7 @@ var init_session_sentiment = __esm({
5843
5843
  CLARIFY_PHRASES = /\b(?:wdym|what do you mean|explain|clarify|what is|what's|huh\??|i don'?t understand)\b/i;
5844
5844
  FRUSTRATED_PHRASES = /\b(?:why (?:the )?(?:fuck|hell)|wtf|are you (?:kidding|serious)|stop slacking|stop making|why did you|why didn'?t you|i (?:fucking )?(?:asked|told you)|are you (?:listening|even)|come\s*on|just\s+do)\b/i;
5845
5845
  MARKERS_VERSION = 3;
5846
+ MARKERS_TURN_OPTS = { maxTurns: 5e4, userMax: Number.POSITIVE_INFINITY };
5846
5847
  }
5847
5848
  });
5848
5849
 
@@ -6068,6 +6069,7 @@ function shorten(text, max) {
6068
6069
  function extractTurnsFromEvents(sessionId, events, opts = {}) {
6069
6070
  const maxTurns = opts.maxTurns ?? DEFAULT_MAX_TURNS;
6070
6071
  const assistantMax = opts.assistantMax ?? DEFAULT_ASSISTANT_MAX;
6072
+ const userMax = opts.userMax ?? DEFAULT_USER_MAX;
6071
6073
  const turns = [];
6072
6074
  let startMs = 0, endMs = 0;
6073
6075
  let found = false;
@@ -6085,7 +6087,7 @@ function extractTurnsFromEvents(sessionId, events, opts = {}) {
6085
6087
  ts: e.ts,
6086
6088
  tsIso: e.tsIso,
6087
6089
  line: e.line,
6088
- text: shorten(e.text, DEFAULT_USER_MAX)
6090
+ text: shorten(e.text, userMax)
6089
6091
  });
6090
6092
  } else if (e.kind === "assistant_text" && e.text) {
6091
6093
  turns.push({
@@ -9444,7 +9446,7 @@ function extractTurnsAny(sessionId, opts = {}) {
9444
9446
  const backend = getBackendForId(sessionId);
9445
9447
  if (!backend)
9446
9448
  return { sessionId, found: false, turns: [], startMs: 0, endMs: 0 };
9447
- return memoInSessionScope(`turns:${sessionId}:${opts.maxTurns ?? ""}:${opts.assistantMax ?? ""}`, () => backend.extractTurns(sessionId, opts));
9449
+ return memoInSessionScope(`turns:${sessionId}:${opts.maxTurns ?? ""}:${opts.assistantMax ?? ""}:${opts.userMax ?? ""}`, () => backend.extractTurns(sessionId, opts));
9448
9450
  }
9449
9451
  function replaySessionAny(sessionId) {
9450
9452
  const backend = getBackendForId(sessionId);
@@ -11114,7 +11116,7 @@ function collectDerivedRows(ref, mtime, count, maxRowBytes) {
11114
11116
  if (!fullOutcome) fullOutcome = computeOutcome(id);
11115
11117
  if (fullOutcome.found) data = fullOutcome.commits;
11116
11118
  } else if (kind === "markers") {
11117
- const turns = extractTurnsAny(id, { maxTurns: 5e4 });
11119
+ const turns = extractTurnsAny(id, MARKERS_TURN_OPTS);
11118
11120
  data = markersFromTurns(id, turns.turns);
11119
11121
  }
11120
11122
  } catch {
package/dist/watch.js CHANGED
@@ -7457,7 +7457,7 @@ function markersFromTurns(sessionId, turns) {
7457
7457
  const prompts = turns.filter((t) => t.kind === "user" && t.text).map((t) => ({ line: t.line, ts: t.ts, tsIso: t.tsIso, ...markPrompt(t.text) }));
7458
7458
  return { v: MARKERS_VERSION, sessionId, prompts, summary: summarizeMarkers(prompts) };
7459
7459
  }
7460
- var PROFANITY, PROFANITY_LOOSE, APPROVAL_HEAD, NEG_HEAD, QUESTION_HEAD, DIRECTIVE_HEAD, CLARIFY_PHRASES, FRUSTRATED_PHRASES, MARKERS_VERSION;
7460
+ var PROFANITY, PROFANITY_LOOSE, APPROVAL_HEAD, NEG_HEAD, QUESTION_HEAD, DIRECTIVE_HEAD, CLARIFY_PHRASES, FRUSTRATED_PHRASES, MARKERS_VERSION, MARKERS_TURN_OPTS;
7461
7461
  var init_session_sentiment = __esm({
7462
7462
  "../engine/dist/core/session-sentiment.js"() {
7463
7463
  "use strict";
@@ -7471,6 +7471,7 @@ var init_session_sentiment = __esm({
7471
7471
  CLARIFY_PHRASES = /\b(?:wdym|what do you mean|explain|clarify|what is|what's|huh\??|i don'?t understand)\b/i;
7472
7472
  FRUSTRATED_PHRASES = /\b(?:why (?:the )?(?:fuck|hell)|wtf|are you (?:kidding|serious)|stop slacking|stop making|why did you|why didn'?t you|i (?:fucking )?(?:asked|told you)|are you (?:listening|even)|come\s*on|just\s+do)\b/i;
7473
7473
  MARKERS_VERSION = 3;
7474
+ MARKERS_TURN_OPTS = { maxTurns: 5e4, userMax: Number.POSITIVE_INFINITY };
7474
7475
  }
7475
7476
  });
7476
7477
 
@@ -7646,7 +7647,7 @@ function extractTurnsAny(sessionId, opts = {}) {
7646
7647
  const backend = getBackendForId(sessionId);
7647
7648
  if (!backend)
7648
7649
  return { sessionId, found: false, turns: [], startMs: 0, endMs: 0 };
7649
- return memoInSessionScope(`turns:${sessionId}:${opts.maxTurns ?? ""}:${opts.assistantMax ?? ""}`, () => backend.extractTurns(sessionId, opts));
7650
+ return memoInSessionScope(`turns:${sessionId}:${opts.maxTurns ?? ""}:${opts.assistantMax ?? ""}:${opts.userMax ?? ""}`, () => backend.extractTurns(sessionId, opts));
7650
7651
  }
7651
7652
  function replaySessionAny(sessionId) {
7652
7653
  const backend = getBackendForId(sessionId);
@@ -8054,6 +8055,7 @@ function shorten(text, max) {
8054
8055
  function extractTurnsFromEvents(sessionId, events, opts = {}) {
8055
8056
  const maxTurns = opts.maxTurns ?? DEFAULT_MAX_TURNS;
8056
8057
  const assistantMax = opts.assistantMax ?? DEFAULT_ASSISTANT_MAX;
8058
+ const userMax = opts.userMax ?? DEFAULT_USER_MAX;
8057
8059
  const turns = [];
8058
8060
  let startMs = 0, endMs = 0;
8059
8061
  let found = false;
@@ -8071,7 +8073,7 @@ function extractTurnsFromEvents(sessionId, events, opts = {}) {
8071
8073
  ts: e.ts,
8072
8074
  tsIso: e.tsIso,
8073
8075
  line: e.line,
8074
- text: shorten(e.text, DEFAULT_USER_MAX)
8076
+ text: shorten(e.text, userMax)
8075
8077
  });
8076
8078
  } else if (e.kind === "assistant_text" && e.text) {
8077
8079
  turns.push({
@@ -18483,7 +18485,7 @@ var init_http = __esm({
18483
18485
  CLI_VERSION = JSON.parse(readFileSync32(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
18484
18486
  } catch {
18485
18487
  try {
18486
- if (true) CLI_VERSION = "0.7.12";
18488
+ if (true) CLI_VERSION = "0.7.13";
18487
18489
  } catch {
18488
18490
  }
18489
18491
  }
@@ -18527,7 +18529,7 @@ function collectDerivedRows(ref, mtime, count, maxRowBytes) {
18527
18529
  if (!fullOutcome) fullOutcome = computeOutcome(id);
18528
18530
  if (fullOutcome.found) data = fullOutcome.commits;
18529
18531
  } else if (kind === "markers") {
18530
- const turns = extractTurnsAny(id, { maxTurns: 5e4 });
18532
+ const turns = extractTurnsAny(id, MARKERS_TURN_OPTS);
18531
18533
  data = markersFromTurns(id, turns.turns);
18532
18534
  }
18533
18535
  } catch {
@@ -18977,7 +18979,7 @@ var init_telemetry = __esm({
18977
18979
  init_sync_client();
18978
18980
  cliVersion = () => {
18979
18981
  try {
18980
- return true ? "0.7.12" : "dev";
18982
+ return true ? "0.7.13" : "dev";
18981
18983
  } catch {
18982
18984
  return "dev";
18983
18985
  }
@@ -21110,7 +21112,7 @@ var init_sync_client = __esm({
21110
21112
  ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
21111
21113
  } catch {
21112
21114
  try {
21113
- if (true) ownVersion = "0.7.12";
21115
+ if (true) ownVersion = "0.7.13";
21114
21116
  } catch {
21115
21117
  }
21116
21118
  }
@@ -24247,7 +24249,7 @@ try {
24247
24249
  ownVersion2 = JSON.parse(readFileSync39(join48(dir, "../package.json"), "utf-8")).version || ownVersion2;
24248
24250
  } catch {
24249
24251
  try {
24250
- if (true) ownVersion2 = "0.7.12";
24252
+ if (true) ownVersion2 = "0.7.13";
24251
24253
  } catch {
24252
24254
  }
24253
24255
  }
@@ -24632,7 +24634,7 @@ async function runCollectorMigration(opts) {
24632
24634
  init_sync_ledger();
24633
24635
  init_collector_health();
24634
24636
  import { existsSync as existsSync50, readFileSync as readFileSync45, statSync as statSync45 } from "fs";
24635
- var CLI_VERSION3 = true ? "0.7.12" : "0.0.0";
24637
+ var CLI_VERSION3 = true ? "0.7.13" : "0.0.0";
24636
24638
  var DEBOUNCE_MS = 5e3;
24637
24639
  var PLANS_DIR = claudeBackend.plansDir();
24638
24640
  var TASKS_DIR = claudeBackend.tasksDir();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chat-recall",
3
- "version": "0.7.12",
3
+ "version": "0.7.13",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/munhq/chat-recall.git"