chat-recall 0.6.5 → 0.6.7

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/mcp-relay.js CHANGED
@@ -118,7 +118,7 @@ function daemonEnabled() {
118
118
  }
119
119
 
120
120
  // src/mcp-relay.ts
121
- var VERSION = true ? "0.6.5" : "0.0.0";
121
+ var VERSION = true ? "0.6.7" : "0.0.0";
122
122
  var SERVER_URL = new URL("./mcp.js", import.meta.url);
123
123
  var SERVER_PATH = fileURLToPath(SERVER_URL);
124
124
  var START_TIMEOUT_MS = 15e3;
package/dist/mcp.js CHANGED
@@ -19728,7 +19728,7 @@ var init_http = __esm({
19728
19728
  CLI_VERSION = JSON.parse(readFileSync35(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
19729
19729
  } catch {
19730
19730
  try {
19731
- if (true) CLI_VERSION = "0.6.5";
19731
+ if (true) CLI_VERSION = "0.6.7";
19732
19732
  } catch {
19733
19733
  }
19734
19734
  }
@@ -20248,7 +20248,7 @@ var init_telemetry = __esm({
20248
20248
  init_sync_client();
20249
20249
  cliVersion2 = () => {
20250
20250
  try {
20251
- return true ? "0.6.5" : "dev";
20251
+ return true ? "0.6.7" : "dev";
20252
20252
  } catch {
20253
20253
  return "dev";
20254
20254
  }
@@ -20398,12 +20398,16 @@ var init_server_probe = __esm({
20398
20398
  // src/auto-update.ts
20399
20399
  var auto_update_exports = {};
20400
20400
  __export(auto_update_exports, {
20401
+ clearUpdateFailures: () => clearUpdateFailures,
20401
20402
  compareVersions: () => compareVersions,
20402
20403
  executeAutoUpdate: () => executeAutoUpdate,
20404
+ hasGivenUpOn: () => hasGivenUpOn,
20403
20405
  installedVersion: () => installedVersion,
20404
20406
  isAutoUpdateEnabled: () => isAutoUpdateEnabled,
20405
20407
  newerOf: () => newerOf,
20408
+ noteUpdateFailure: () => noteUpdateFailure,
20406
20409
  planAutoUpdate: () => planAutoUpdate,
20410
+ readUpdateState: () => readUpdateState,
20407
20411
  runAutoUpdate: () => runAutoUpdate,
20408
20412
  runningPrefix: () => runningPrefix,
20409
20413
  sweepStaleStaging: () => sweepStaleStaging,
@@ -20412,9 +20416,9 @@ __export(auto_update_exports, {
20412
20416
  import { execSync as execSync4 } from "node:child_process";
20413
20417
  import { readFileSync as readFileSync36 } from "node:fs";
20414
20418
  import { fileURLToPath as fileURLToPath2 } from "node:url";
20415
- import { writeFileSync as writeFileSync9, mkdtempSync as mkdtempSync3, rmSync as rmSync5, readdirSync as readdirSync31, statSync as statSync40 } from "node:fs";
20419
+ import { writeFileSync as writeFileSync9, mkdtempSync as mkdtempSync3, rmSync as rmSync5, readdirSync as readdirSync31, statSync as statSync40, mkdirSync as mkdirSync12 } from "node:fs";
20416
20420
  import { join as join47, dirname as dirname19, sep as sep3 } from "node:path";
20417
- import { tmpdir as tmpdir3 } from "node:os";
20421
+ import { tmpdir as tmpdir3, homedir as homedir17 } from "node:os";
20418
20422
  import { createHash as createHash10 } from "node:crypto";
20419
20423
  function compareVersions(a, b) {
20420
20424
  const pa = String(a).split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
@@ -20528,16 +20532,25 @@ function runningPrefix(moduleUrl = import.meta.url) {
20528
20532
  const beforeNodeModules = here.slice(0, at);
20529
20533
  return beforeNodeModules.endsWith(`${sep3}lib`) ? beforeNodeModules.slice(0, -4) : beforeNodeModules;
20530
20534
  }
20535
+ function npmInstall(cmd) {
20536
+ try {
20537
+ execSync4(cmd, { stdio: ["ignore", "ignore", "pipe"] });
20538
+ } catch (e) {
20539
+ const err = e;
20540
+ const detail = String(err.stderr ?? "").trim().split("\n").filter((l) => l.trim() && !/^npm (notice|warn)\b/i.test(l)).slice(-4).join(" | ").slice(0, 400);
20541
+ throw new Error(detail ? `${err.message ?? "install failed"} \u2014 ${detail}` : err.message ?? "install failed");
20542
+ }
20543
+ }
20531
20544
  function realInstall(tgz) {
20532
20545
  const prefix = runningPrefix();
20533
20546
  if (prefix) {
20534
- execSync4(`npm install -g --prefix "${prefix}" "${tgz}"`, { stdio: "ignore" });
20547
+ npmInstall(`npm install -g --prefix "${prefix}" "${tgz}"`);
20535
20548
  return;
20536
20549
  }
20537
20550
  try {
20538
- execSync4(`npm install -g "${tgz}"`, { stdio: "ignore" });
20551
+ npmInstall(`npm install -g "${tgz}"`);
20539
20552
  } catch {
20540
- execSync4(`npm install -g --prefix "${process.env.HOME}/.local" "${tgz}"`, { stdio: "ignore" });
20553
+ npmInstall(`npm install -g --prefix "${process.env.HOME}/.local" "${tgz}"`);
20541
20554
  }
20542
20555
  }
20543
20556
  function realRestart(platform2) {
@@ -20545,6 +20558,37 @@ function realRestart(platform2) {
20545
20558
  else if (platform2 === "darwin") execSync4("launchctl kickstart -k gui/$(id -u)/com.chat-recall.watch", { stdio: "ignore", shell: "/bin/bash" });
20546
20559
  else if (platform2 === "win32") execSync4("schtasks /End /TN chat-recall-watch & schtasks /Run /TN chat-recall-watch", { stdio: "ignore" });
20547
20560
  }
20561
+ function updateStatePath() {
20562
+ const dir = process.env.CHAT_RECALL_DATA_DIR || join47(homedir17(), ".chat-recall");
20563
+ return join47(dir, "auto-update-state.json");
20564
+ }
20565
+ function readUpdateState() {
20566
+ try {
20567
+ return JSON.parse(readFileSync36(updateStatePath(), "utf8"));
20568
+ } catch {
20569
+ return {};
20570
+ }
20571
+ }
20572
+ function writeUpdateState(st) {
20573
+ try {
20574
+ const p = updateStatePath();
20575
+ mkdirSync12(dirname19(p), { recursive: true });
20576
+ writeFileSync9(p, JSON.stringify(st), "utf8");
20577
+ } catch {
20578
+ }
20579
+ }
20580
+ function hasGivenUpOn(target, st = readUpdateState()) {
20581
+ return st.target === target && (st.failures ?? 0) >= GIVE_UP_AFTER;
20582
+ }
20583
+ function noteUpdateFailure(target) {
20584
+ const st = readUpdateState();
20585
+ const failures = st.target === target ? (st.failures ?? 0) + 1 : 1;
20586
+ writeUpdateState({ target, failures });
20587
+ return failures;
20588
+ }
20589
+ function clearUpdateFailures() {
20590
+ writeUpdateState({});
20591
+ }
20548
20592
  async function runAutoUpdate(base, authHeaders, ownVersion2, deps) {
20549
20593
  let caps;
20550
20594
  try {
@@ -20567,6 +20611,10 @@ async function runAutoUpdate(base, authHeaders, ownVersion2, deps) {
20567
20611
  }
20568
20612
  return { updated: false, reason: plan.reason };
20569
20613
  }
20614
+ const target = plan.to ?? "";
20615
+ if (target && hasGivenUpOn(target)) {
20616
+ return { updated: false, reason: `gave up installing ${plan.to} after ${GIVE_UP_AFTER} failed attempts \u2014 run \`npm install -g chat-recall\` by hand` };
20617
+ }
20570
20618
  const result = await executeAutoUpdate(plan, {
20571
20619
  download: deps?.download ?? realDownload,
20572
20620
  install: deps?.install ?? realInstall,
@@ -20574,20 +20622,27 @@ async function runAutoUpdate(base, authHeaders, ownVersion2, deps) {
20574
20622
  platform: deps?.platform
20575
20623
  });
20576
20624
  if (!result.updated) {
20577
- try {
20578
- const { reportClientEvent: reportClientEvent3 } = await Promise.resolve().then(() => (init_client_events(), client_events_exports));
20579
- reportClientEvent3("auto_update_failed", { message: `${plan.from} \u2192 ${plan.to}: ${result.reason}` });
20580
- } catch {
20625
+ const failures = target ? noteUpdateFailure(target) : 1;
20626
+ if (failures <= GIVE_UP_AFTER) {
20627
+ try {
20628
+ const { reportClientEvent: reportClientEvent3 } = await Promise.resolve().then(() => (init_client_events(), client_events_exports));
20629
+ const suffix = failures >= GIVE_UP_AFTER ? ` \u2014 giving up after ${failures} attempts, needs a manual \`npm install -g chat-recall\`` : ` (attempt ${failures} of ${GIVE_UP_AFTER})`;
20630
+ reportClientEvent3("auto_update_failed", { message: `${plan.from} \u2192 ${plan.to}: ${result.reason}${suffix}` });
20631
+ } catch {
20632
+ }
20581
20633
  }
20634
+ } else {
20635
+ clearUpdateFailures();
20582
20636
  }
20583
20637
  return result;
20584
20638
  }
20585
- var tarballUrl, reportedStandingSkip;
20639
+ var tarballUrl, GIVE_UP_AFTER, reportedStandingSkip;
20586
20640
  var init_auto_update = __esm({
20587
20641
  "src/auto-update.ts"() {
20588
20642
  "use strict";
20589
20643
  init_http();
20590
20644
  tarballUrl = (base) => `${base.replace(/\/+$/, "")}/install/chat-recall.tgz`;
20645
+ GIVE_UP_AFTER = 3;
20591
20646
  reportedStandingSkip = /* @__PURE__ */ new Set();
20592
20647
  }
20593
20648
  });
@@ -20622,7 +20677,7 @@ __export(sync_client_exports, {
20622
20677
  syncSessions: () => syncSessions
20623
20678
  });
20624
20679
  import { join as join48, dirname as dirname20, basename as basename21 } from "node:path";
20625
- import { readFileSync as readFileSync37, writeFileSync as writeFileSync10, mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync4, rmSync as rmSync6, chmodSync as chmodSync6, unlinkSync as unlinkSync3, readdirSync as readdirSync32, statSync as statSync41 } from "node:fs";
20680
+ import { readFileSync as readFileSync37, writeFileSync as writeFileSync10, mkdirSync as mkdirSync13, mkdtempSync as mkdtempSync4, rmSync as rmSync6, chmodSync as chmodSync6, unlinkSync as unlinkSync3, readdirSync as readdirSync32, statSync as statSync41 } from "node:fs";
20626
20681
  import { tmpdir as tmpdir4, hostname as hostname2 } from "node:os";
20627
20682
  import { createHash as createHash11 } from "node:crypto";
20628
20683
  import { fileURLToPath as fileURLToPath3 } from "node:url";
@@ -20657,7 +20712,7 @@ function classifyError(msg, err) {
20657
20712
  }
20658
20713
  function saveCredentials(c) {
20659
20714
  assertTransportSafe(c.serverUrl);
20660
- mkdirSync12(dirname20(credPath()), { recursive: true });
20715
+ mkdirSync13(dirname20(credPath()), { recursive: true });
20661
20716
  const targets = loadAllCredentials().filter((t) => t.serverUrl !== c.serverUrl);
20662
20717
  targets.unshift(c);
20663
20718
  writeFileSync10(credPath(), JSON.stringify({ targets }, null, 2));
@@ -20752,7 +20807,7 @@ function persistSyncConfig(base, config2) {
20752
20807
  try {
20753
20808
  const all = readPersistedSyncConfigs();
20754
20809
  all[base] = { fetchedAt: Date.now(), config: config2 };
20755
- mkdirSync12(dirname20(syncConfigCachePath()), { recursive: true });
20810
+ mkdirSync13(dirname20(syncConfigCachePath()), { recursive: true });
20756
20811
  writeFileSync10(syncConfigCachePath(), JSON.stringify(all, null, 2));
20757
20812
  } catch {
20758
20813
  }
@@ -22158,7 +22213,7 @@ var init_sync_client = __esm({
22158
22213
  ownVersion = JSON.parse(readFileSync37(join48(dir, "../package.json"), "utf-8")).version || ownVersion;
22159
22214
  } catch {
22160
22215
  try {
22161
- if (true) ownVersion = "0.6.5";
22216
+ if (true) ownVersion = "0.6.7";
22162
22217
  } catch {
22163
22218
  }
22164
22219
  }
@@ -22381,7 +22436,7 @@ __export(install_skills_exports, {
22381
22436
  skillsSourceDir: () => skillsSourceDir,
22382
22437
  uninstallSkills: () => uninstallSkills
22383
22438
  });
22384
- import { readdirSync as readdirSync33, existsSync as existsSync45, mkdirSync as mkdirSync13, rmSync as rmSync7, cpSync, writeFileSync as writeFileSync12, readFileSync as readFileSync40, statSync as statSync42, realpathSync as realpathSync4 } from "fs";
22439
+ import { readdirSync as readdirSync33, existsSync as existsSync45, mkdirSync as mkdirSync14, rmSync as rmSync7, cpSync, writeFileSync as writeFileSync12, readFileSync as readFileSync40, statSync as statSync42, realpathSync as realpathSync4 } from "fs";
22385
22440
  import { createHash as createHash12 } from "crypto";
22386
22441
  import { join as join50, basename as basename22 } from "path";
22387
22442
  function skillsSourceDir() {
@@ -22491,7 +22546,7 @@ function installSkills(opts = {}) {
22491
22546
  skippedUserOwned.push(name);
22492
22547
  continue;
22493
22548
  }
22494
- mkdirSync13(t.dir, { recursive: true });
22549
+ mkdirSync14(t.dir, { recursive: true });
22495
22550
  rmSync7(dest, { recursive: true, force: true });
22496
22551
  cpSync(join50(src, name), dest, { recursive: true });
22497
22552
  writeFileSync12(join50(dest, MARKER), `${stamp}
@@ -22589,14 +22644,14 @@ __export(service_installer_exports, {
22589
22644
  uninstallService: () => uninstallService
22590
22645
  });
22591
22646
  import { execSync as execSync5 } from "child_process";
22592
- import { existsSync as existsSync46, mkdirSync as mkdirSync14, readFileSync as readFileSync41, rmSync as rmSync8, writeFileSync as writeFileSync13 } from "fs";
22593
- import { homedir as homedir17 } from "os";
22647
+ import { existsSync as existsSync46, mkdirSync as mkdirSync15, readFileSync as readFileSync41, rmSync as rmSync8, writeFileSync as writeFileSync13 } from "fs";
22648
+ import { homedir as homedir18 } from "os";
22594
22649
  import { join as join51 } from "path";
22595
22650
  import { fileURLToPath as fileURLToPath4 } from "url";
22596
22651
  function resolveDaemonPaths() {
22597
22652
  const watchJs = fileURLToPath4(new URL("./watch.js", import.meta.url));
22598
22653
  const node = process.execPath;
22599
- const dataDir = join51(homedir17(), ".chat-recall");
22654
+ const dataDir = join51(homedir18(), ".chat-recall");
22600
22655
  const logFile = join51(dataDir, "watch.log");
22601
22656
  return { watchJs, node, logFile, dataDir };
22602
22657
  }
@@ -22624,7 +22679,7 @@ function refreshServiceDefinition() {
22624
22679
  if (process.platform !== "linux") return false;
22625
22680
  try {
22626
22681
  const { watchJs, node, logFile } = resolveDaemonPaths();
22627
- const unitPath = join51(homedir17(), ".config", "systemd", "user", "chat-recall-watch.service");
22682
+ const unitPath = join51(homedir18(), ".config", "systemd", "user", "chat-recall-watch.service");
22628
22683
  if (!existsSync46(unitPath)) return false;
22629
22684
  const current = readFileSync41(unitPath, "utf8");
22630
22685
  if (!current.includes(watchJs)) return false;
@@ -22639,7 +22694,7 @@ function refreshServiceDefinition() {
22639
22694
  }
22640
22695
  function installService() {
22641
22696
  const { watchJs, node, logFile, dataDir } = resolveDaemonPaths();
22642
- mkdirSync14(dataDir, { recursive: true });
22697
+ mkdirSync15(dataDir, { recursive: true });
22643
22698
  if (process.platform === "linux") {
22644
22699
  return installSystemd(watchJs, node, logFile);
22645
22700
  }
@@ -22655,10 +22710,10 @@ function installService() {
22655
22710
  );
22656
22711
  }
22657
22712
  function installSystemd(watchJs, node, logFile) {
22658
- const unitDir = join51(homedir17(), ".config", "systemd", "user");
22713
+ const unitDir = join51(homedir18(), ".config", "systemd", "user");
22659
22714
  const unitPath = join51(unitDir, "chat-recall-watch.service");
22660
22715
  const unit = renderSystemdUnit(watchJs, node, logFile);
22661
- mkdirSync14(unitDir, { recursive: true });
22716
+ mkdirSync15(unitDir, { recursive: true });
22662
22717
  writeFileSync13(unitPath, unit);
22663
22718
  try {
22664
22719
  execSync5("systemctl --user daemon-reload && systemctl --user enable chat-recall-watch.service && systemctl --user restart chat-recall-watch.service", { stdio: "inherit" });
@@ -22730,10 +22785,10 @@ function renderSystemdUnit(watchJs, node, logFile) {
22730
22785
  }
22731
22786
  function installLaunchd(watchJs, node, logFile) {
22732
22787
  const label = "com.chat-recall.watch";
22733
- const plistDir = join51(homedir17(), "Library", "LaunchAgents");
22788
+ const plistDir = join51(homedir18(), "Library", "LaunchAgents");
22734
22789
  const plistPath = join51(plistDir, `${label}.plist`);
22735
22790
  const plist = renderLaunchdPlist(watchJs, node, logFile, label);
22736
- mkdirSync14(plistDir, { recursive: true });
22791
+ mkdirSync15(plistDir, { recursive: true });
22737
22792
  writeFileSync13(plistPath, plist);
22738
22793
  try {
22739
22794
  try {
@@ -22787,7 +22842,7 @@ function uninstallService() {
22787
22842
  removed = true;
22788
22843
  } catch {
22789
22844
  }
22790
- const unitPath = join51(homedir17(), ".config", "systemd", "user", "chat-recall-watch.service");
22845
+ const unitPath = join51(homedir18(), ".config", "systemd", "user", "chat-recall-watch.service");
22791
22846
  if (existsSync46(unitPath)) {
22792
22847
  rmSync8(unitPath, { force: true });
22793
22848
  removed = true;
@@ -22799,7 +22854,7 @@ function uninstallService() {
22799
22854
  return removed;
22800
22855
  }
22801
22856
  if (process.platform === "darwin") {
22802
- const plistPath = join51(homedir17(), "Library", "LaunchAgents", "com.chat-recall.watch.plist");
22857
+ const plistPath = join51(homedir18(), "Library", "LaunchAgents", "com.chat-recall.watch.plist");
22803
22858
  try {
22804
22859
  execSync5(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore" });
22805
22860
  } catch {
@@ -28006,7 +28061,7 @@ function installCrashGuards() {
28006
28061
  reportClientEvent2("mcp_crash", { message: err.stack || err.message });
28007
28062
  });
28008
28063
  }
28009
- var RELAY_VERSION = true ? "0.6.5" : "0.0.0";
28064
+ var RELAY_VERSION = true ? "0.6.7" : "0.0.0";
28010
28065
  function daemonIdleSecs() {
28011
28066
  const raw = process.env.CHAT_RECALL_DAEMON_IDLE_SECS;
28012
28067
  if (raw === void 0) return 900;
@@ -0,0 +1,13 @@
1
+ export declare function shouldAskForStar(resultCount: number): boolean;
2
+ /** Record that it has been shown. A failure here means it may be shown once
3
+ * more on the next run, which is the harmless direction to fail in. */
4
+ export declare function markStarAsked(): void;
5
+ /**
6
+ * Print the ask and record it. Writes to stderr so a piped stdout carries only
7
+ * search results.
8
+ *
9
+ * `dim` is passed in rather than imported so this module pulls in no colour
10
+ * dependency of its own and a caller can hand it a no-op.
11
+ */
12
+ export declare function askForStar(resultCount: number, dim: (s: string) => string): void;
13
+ //# sourceMappingURL=star-nudge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"star-nudge.d.ts","sourceRoot":"","sources":["../src/star-nudge.ts"],"names":[],"mappings":"AA6CA,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAO7D;AAED;wEACwE;AACxE,wBAAgB,aAAa,IAAI,IAAI,CAMpC;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAKhF"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Ask, once per machine, for a GitHub star — after a search that worked.
3
+ *
4
+ * WHY IT EXISTS. Measured 2026-09-13: npm reported 6,973 downloads in the last
5
+ * month and 440 in the last week, while github.com/munhq/chat-recall had 2
6
+ * stars, 0 forks and 0 watchers. People install this, use it, and leave no
7
+ * public trace, and a star count is the signal both recommendation paths read —
8
+ * the corpus a model is trained on, and the "best MCP servers" articles that
9
+ * rank for the queries buyers actually type.
10
+ *
11
+ * WHERE IT IS SAFE TO PRINT. Here, and nowhere else. The MCP server is a
12
+ * different entry point (mcp.ts, reached through mcp-relay.js) and speaks
13
+ * JSON-RPC over stdio, where one stray line of text corrupts the stream. This
14
+ * module is imported by cli.ts only. Keep it that way.
15
+ *
16
+ * Four conditions, all required:
17
+ * - the search returned results, so the ask follows something that worked
18
+ * - stderr is a TTY, so a piped or redirected run is untouched
19
+ * - no CI marker in the environment
20
+ * - the marker file is absent, so it has never been shown on this machine
21
+ */
22
+ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
23
+ import { dirname, join } from 'node:path';
24
+ import { getDataDir } from '@chat-recall/engine/core/paths.js';
25
+ const REPO = 'https://github.com/munhq/chat-recall';
26
+ /** One file, written once. Deliberately not a settings field: AppSettings is a
27
+ * versioned schema merged field by field, and a cosmetic one-shot marker is
28
+ * not worth a migration or a chance to corrupt a user's real settings. */
29
+ function markerPath() {
30
+ return join(getDataDir(), '.star-asked');
31
+ }
32
+ /**
33
+ * Environments that must never see it: CI, and anyone who has opted out.
34
+ * CI=true is set by GitHub Actions, GitLab, CircleCI and Travis; the others are
35
+ * belt and braces for runners that set only their own name.
36
+ */
37
+ function suppressed() {
38
+ const env = process.env;
39
+ if (env.CHAT_RECALL_NO_STAR_PROMPT)
40
+ return true;
41
+ return Boolean(env.CI || env.GITHUB_ACTIONS || env.GITLAB_CI || env.BUILDKITE || env.TEAMCITY_VERSION);
42
+ }
43
+ export function shouldAskForStar(resultCount) {
44
+ if (resultCount <= 0)
45
+ return false;
46
+ if (suppressed())
47
+ return false;
48
+ // stderr, because that is where the line goes. A run whose stdout is a pipe
49
+ // but whose stderr is still the terminal is a person watching, so it shows.
50
+ if (!process.stderr.isTTY)
51
+ return false;
52
+ try {
53
+ return !existsSync(markerPath());
54
+ }
55
+ catch {
56
+ return false;
57
+ }
58
+ }
59
+ /** Record that it has been shown. A failure here means it may be shown once
60
+ * more on the next run, which is the harmless direction to fail in. */
61
+ export function markStarAsked() {
62
+ try {
63
+ const p = markerPath();
64
+ mkdirSync(dirname(p), { recursive: true });
65
+ writeFileSync(p, `${new Date().toISOString()}\n`);
66
+ }
67
+ catch { /* read-only home, or no disk — never worth failing a search over */ }
68
+ }
69
+ /**
70
+ * Print the ask and record it. Writes to stderr so a piped stdout carries only
71
+ * search results.
72
+ *
73
+ * `dim` is passed in rather than imported so this module pulls in no colour
74
+ * dependency of its own and a caller can hand it a no-op.
75
+ */
76
+ export function askForStar(resultCount, dim) {
77
+ if (!shouldAskForStar(resultCount))
78
+ return;
79
+ markStarAsked();
80
+ process.stderr.write(`${dim(`If this saved you time, a star helps other people find it: ${REPO}`)}\n`);
81
+ process.stderr.write(`${dim('You will not be asked again. CHAT_RECALL_NO_STAR_PROMPT=1 disables it everywhere.')}\n`);
82
+ }
83
+ //# sourceMappingURL=star-nudge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"star-nudge.js","sourceRoot":"","sources":["../src/star-nudge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAE/D,MAAM,IAAI,GAAG,sCAAsC,CAAC;AAEpD;;2EAE2E;AAC3E,SAAS,UAAU;IACjB,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,aAAa,CAAC,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU;IACjB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACxB,IAAI,GAAG,CAAC,0BAA0B;QAAE,OAAO,IAAI,CAAC;IAChD,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,gBAAgB,CAAC,CAAC;AACzG,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,IAAI,WAAW,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,IAAI,UAAU,EAAE;QAAE,OAAO,KAAK,CAAC;IAC/B,4EAA4E;IAC5E,4EAA4E;IAC5E,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,CAAC;QAAC,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AACnE,CAAC;AAED;wEACwE;AACxE,MAAM,UAAU,aAAa;IAC3B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;QACvB,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,aAAa,CAAC,CAAC,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC,CAAC,oEAAoE,CAAC,CAAC;AAClF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,WAAmB,EAAE,GAA0B;IACxE,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC;QAAE,OAAO;IAC3C,aAAa,EAAE,CAAC;IAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,8DAA8D,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;IACvG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,mFAAmF,CAAC,IAAI,CAAC,CAAC;AACxH,CAAC"}