chat-recall 0.6.4 → 0.6.6

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.
@@ -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"}
package/dist/watch.js CHANGED
@@ -13769,12 +13769,12 @@ function extractEntities(text, context = {}) {
13769
13769
  if (chosen && looksLikeStrictTool(chosen) && looksLikeStrictTool(rejected)) {
13770
13770
  const c = canonTool(chosen), r = canonTool(rejected);
13771
13771
  if (projectName)
13772
- addTriple(projectName, "chose", c, 0.8);
13773
- addTriple(projectName || "project", "rejected", r, 0.7);
13774
- addTriple(c, "chosen_over", r, 0.8);
13772
+ addTriple(projectName, "chose", c, DECISION_GUESS_CONFIDENCE);
13773
+ addTriple(projectName || "project", "rejected", r, DECISION_GUESS_CONFIDENCE);
13774
+ addTriple(c, "chosen_over", r, DECISION_GUESS_CONFIDENCE);
13775
13775
  }
13776
13776
  } else if (chosen && looksLikeDecisionObject(chosen) && projectName) {
13777
- addTriple(projectName, "chose", canonTool(chosen), 0.8);
13777
+ addTriple(projectName, "chose", canonTool(chosen), DECISION_GUESS_CONFIDENCE);
13778
13778
  }
13779
13779
  }
13780
13780
  }
@@ -13811,7 +13811,7 @@ function extractEntities(text, context = {}) {
13811
13811
  }
13812
13812
  return triples;
13813
13813
  }
13814
- var KNOWN_TOOLS, AMBIGUOUS_TOOLS, toolContextRe, TOOL_PATTERNS, DECISION_PATTERNS2, DECISION_OBJECT_STOPWORDS, KNOWN_TOOL_NAMES, CANONICAL_TOOL, canonTool, PROJECT_PATH_PATTERN, PEOPLE_PATTERNS, NOT_PEOPLE;
13814
+ var KNOWN_TOOLS, AMBIGUOUS_TOOLS, toolContextRe, TOOL_PATTERNS, DECISION_PATTERNS2, DECISION_OBJECT_STOPWORDS, KNOWN_TOOL_NAMES, CANONICAL_TOOL, canonTool, DECISION_GUESS_CONFIDENCE, PROJECT_PATH_PATTERN, PEOPLE_PATTERNS, NOT_PEOPLE;
13815
13815
  var init_entity_extractor = __esm({
13816
13816
  "../engine/dist/core/entity-extractor.js"() {
13817
13817
  "use strict";
@@ -14032,6 +14032,7 @@ var init_entity_extractor = __esm({
14032
14032
  "nextjs": "next.js"
14033
14033
  };
14034
14034
  canonTool = (n) => CANONICAL_TOOL[n.toLowerCase()] ?? n;
14035
+ DECISION_GUESS_CONFIDENCE = 0.6;
14035
14036
  PROJECT_PATH_PATTERN = /\/(?:home|Users)\/\w+\/(?:code|projects|work|dev|src)\/(?:\w+\/)?([a-zA-Z][a-zA-Z0-9_-]{1,40})/g;
14036
14037
  PEOPLE_PATTERNS = [
14037
14038
  /\b(?:my name is|I'm|I am)\s+([A-Z][a-z]{1,15}(?:\s+[A-Z][a-z]{1,15})?)/g,
@@ -18304,7 +18305,7 @@ var init_http = __esm({
18304
18305
  CLI_VERSION = JSON.parse(readFileSync31(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
18305
18306
  } catch {
18306
18307
  try {
18307
- if (true) CLI_VERSION = "0.6.4";
18308
+ if (true) CLI_VERSION = "0.6.6";
18308
18309
  } catch {
18309
18310
  }
18310
18311
  }
@@ -18820,7 +18821,7 @@ var init_telemetry = __esm({
18820
18821
  init_sync_client();
18821
18822
  cliVersion = () => {
18822
18823
  try {
18823
- return true ? "0.6.4" : "dev";
18824
+ return true ? "0.6.6" : "dev";
18824
18825
  } catch {
18825
18826
  return "dev";
18826
18827
  }
@@ -19089,12 +19090,16 @@ var init_client_events = __esm({
19089
19090
  // src/auto-update.ts
19090
19091
  var auto_update_exports = {};
19091
19092
  __export(auto_update_exports, {
19093
+ clearUpdateFailures: () => clearUpdateFailures,
19092
19094
  compareVersions: () => compareVersions,
19093
19095
  executeAutoUpdate: () => executeAutoUpdate,
19096
+ hasGivenUpOn: () => hasGivenUpOn,
19094
19097
  installedVersion: () => installedVersion,
19095
19098
  isAutoUpdateEnabled: () => isAutoUpdateEnabled,
19096
19099
  newerOf: () => newerOf,
19100
+ noteUpdateFailure: () => noteUpdateFailure,
19097
19101
  planAutoUpdate: () => planAutoUpdate,
19102
+ readUpdateState: () => readUpdateState,
19098
19103
  runAutoUpdate: () => runAutoUpdate,
19099
19104
  runningPrefix: () => runningPrefix,
19100
19105
  sweepStaleStaging: () => sweepStaleStaging,
@@ -19103,9 +19108,9 @@ __export(auto_update_exports, {
19103
19108
  import { execSync as execSync2 } from "node:child_process";
19104
19109
  import { readFileSync as readFileSync34 } from "node:fs";
19105
19110
  import { fileURLToPath as fileURLToPath2 } from "node:url";
19106
- import { writeFileSync as writeFileSync8, mkdtempSync as mkdtempSync3, rmSync as rmSync5, readdirSync as readdirSync31, statSync as statSync36 } from "node:fs";
19111
+ import { writeFileSync as writeFileSync8, mkdtempSync as mkdtempSync3, rmSync as rmSync5, readdirSync as readdirSync31, statSync as statSync36, mkdirSync as mkdirSync9 } from "node:fs";
19107
19112
  import { join as join41, dirname as dirname18, sep as sep2 } from "node:path";
19108
- import { tmpdir as tmpdir2 } from "node:os";
19113
+ import { tmpdir as tmpdir2, homedir as homedir15 } from "node:os";
19109
19114
  import { createHash as createHash7 } from "node:crypto";
19110
19115
  function compareVersions(a, b) {
19111
19116
  const pa = String(a).split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
@@ -19219,16 +19224,25 @@ function runningPrefix(moduleUrl = import.meta.url) {
19219
19224
  const beforeNodeModules = here.slice(0, at);
19220
19225
  return beforeNodeModules.endsWith(`${sep2}lib`) ? beforeNodeModules.slice(0, -4) : beforeNodeModules;
19221
19226
  }
19227
+ function npmInstall(cmd) {
19228
+ try {
19229
+ execSync2(cmd, { stdio: ["ignore", "ignore", "pipe"] });
19230
+ } catch (e) {
19231
+ const err = e;
19232
+ 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);
19233
+ throw new Error(detail ? `${err.message ?? "install failed"} \u2014 ${detail}` : err.message ?? "install failed");
19234
+ }
19235
+ }
19222
19236
  function realInstall(tgz) {
19223
19237
  const prefix = runningPrefix();
19224
19238
  if (prefix) {
19225
- execSync2(`npm install -g --prefix "${prefix}" "${tgz}"`, { stdio: "ignore" });
19239
+ npmInstall(`npm install -g --prefix "${prefix}" "${tgz}"`);
19226
19240
  return;
19227
19241
  }
19228
19242
  try {
19229
- execSync2(`npm install -g "${tgz}"`, { stdio: "ignore" });
19243
+ npmInstall(`npm install -g "${tgz}"`);
19230
19244
  } catch {
19231
- execSync2(`npm install -g --prefix "${process.env.HOME}/.local" "${tgz}"`, { stdio: "ignore" });
19245
+ npmInstall(`npm install -g --prefix "${process.env.HOME}/.local" "${tgz}"`);
19232
19246
  }
19233
19247
  }
19234
19248
  function realRestart(platform2) {
@@ -19236,6 +19250,37 @@ function realRestart(platform2) {
19236
19250
  else if (platform2 === "darwin") execSync2("launchctl kickstart -k gui/$(id -u)/com.chat-recall.watch", { stdio: "ignore", shell: "/bin/bash" });
19237
19251
  else if (platform2 === "win32") execSync2("schtasks /End /TN chat-recall-watch & schtasks /Run /TN chat-recall-watch", { stdio: "ignore" });
19238
19252
  }
19253
+ function updateStatePath() {
19254
+ const dir = process.env.CHAT_RECALL_DATA_DIR || join41(homedir15(), ".chat-recall");
19255
+ return join41(dir, "auto-update-state.json");
19256
+ }
19257
+ function readUpdateState() {
19258
+ try {
19259
+ return JSON.parse(readFileSync34(updateStatePath(), "utf8"));
19260
+ } catch {
19261
+ return {};
19262
+ }
19263
+ }
19264
+ function writeUpdateState(st) {
19265
+ try {
19266
+ const p = updateStatePath();
19267
+ mkdirSync9(dirname18(p), { recursive: true });
19268
+ writeFileSync8(p, JSON.stringify(st), "utf8");
19269
+ } catch {
19270
+ }
19271
+ }
19272
+ function hasGivenUpOn(target, st = readUpdateState()) {
19273
+ return st.target === target && (st.failures ?? 0) >= GIVE_UP_AFTER;
19274
+ }
19275
+ function noteUpdateFailure(target) {
19276
+ const st = readUpdateState();
19277
+ const failures = st.target === target ? (st.failures ?? 0) + 1 : 1;
19278
+ writeUpdateState({ target, failures });
19279
+ return failures;
19280
+ }
19281
+ function clearUpdateFailures() {
19282
+ writeUpdateState({});
19283
+ }
19239
19284
  async function runAutoUpdate(base2, authHeaders, ownVersion3, deps) {
19240
19285
  let caps;
19241
19286
  try {
@@ -19258,6 +19303,10 @@ async function runAutoUpdate(base2, authHeaders, ownVersion3, deps) {
19258
19303
  }
19259
19304
  return { updated: false, reason: plan.reason };
19260
19305
  }
19306
+ const target = plan.to ?? "";
19307
+ if (target && hasGivenUpOn(target)) {
19308
+ return { updated: false, reason: `gave up installing ${plan.to} after ${GIVE_UP_AFTER} failed attempts \u2014 run \`npm install -g chat-recall\` by hand` };
19309
+ }
19261
19310
  const result = await executeAutoUpdate(plan, {
19262
19311
  download: deps?.download ?? realDownload,
19263
19312
  install: deps?.install ?? realInstall,
@@ -19265,27 +19314,34 @@ async function runAutoUpdate(base2, authHeaders, ownVersion3, deps) {
19265
19314
  platform: deps?.platform
19266
19315
  });
19267
19316
  if (!result.updated) {
19268
- try {
19269
- const { reportClientEvent: reportClientEvent2 } = await Promise.resolve().then(() => (init_client_events(), client_events_exports));
19270
- reportClientEvent2("auto_update_failed", { message: `${plan.from} \u2192 ${plan.to}: ${result.reason}` });
19271
- } catch {
19317
+ const failures = target ? noteUpdateFailure(target) : 1;
19318
+ if (failures <= GIVE_UP_AFTER) {
19319
+ try {
19320
+ const { reportClientEvent: reportClientEvent2 } = await Promise.resolve().then(() => (init_client_events(), client_events_exports));
19321
+ 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})`;
19322
+ reportClientEvent2("auto_update_failed", { message: `${plan.from} \u2192 ${plan.to}: ${result.reason}${suffix}` });
19323
+ } catch {
19324
+ }
19272
19325
  }
19326
+ } else {
19327
+ clearUpdateFailures();
19273
19328
  }
19274
19329
  return result;
19275
19330
  }
19276
- var tarballUrl, reportedStandingSkip;
19331
+ var tarballUrl, GIVE_UP_AFTER, reportedStandingSkip;
19277
19332
  var init_auto_update = __esm({
19278
19333
  "src/auto-update.ts"() {
19279
19334
  "use strict";
19280
19335
  init_http();
19281
19336
  tarballUrl = (base2) => `${base2.replace(/\/+$/, "")}/install/chat-recall.tgz`;
19337
+ GIVE_UP_AFTER = 3;
19282
19338
  reportedStandingSkip = /* @__PURE__ */ new Set();
19283
19339
  }
19284
19340
  });
19285
19341
 
19286
19342
  // src/sync-client.ts
19287
19343
  import { join as join42, dirname as dirname19, basename as basename20 } from "node:path";
19288
- import { readFileSync as readFileSync35, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9, mkdtempSync as mkdtempSync4, rmSync as rmSync6, chmodSync as chmodSync3, unlinkSync as unlinkSync2, readdirSync as readdirSync32, statSync as statSync37 } from "node:fs";
19344
+ import { readFileSync as readFileSync35, writeFileSync as writeFileSync9, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync4, rmSync as rmSync6, chmodSync as chmodSync3, unlinkSync as unlinkSync2, readdirSync as readdirSync32, statSync as statSync37 } from "node:fs";
19289
19345
  import { tmpdir as tmpdir3, hostname as hostname2 } from "node:os";
19290
19346
  import { createHash as createHash8 } from "node:crypto";
19291
19347
  import { fileURLToPath as fileURLToPath3 } from "node:url";
@@ -19394,7 +19450,7 @@ function persistSyncConfig(base2, config) {
19394
19450
  try {
19395
19451
  const all = readPersistedSyncConfigs();
19396
19452
  all[base2] = { fetchedAt: Date.now(), config };
19397
- mkdirSync9(dirname19(syncConfigCachePath()), { recursive: true });
19453
+ mkdirSync10(dirname19(syncConfigCachePath()), { recursive: true });
19398
19454
  writeFileSync9(syncConfigCachePath(), JSON.stringify(all, null, 2));
19399
19455
  } catch {
19400
19456
  }
@@ -20763,7 +20819,7 @@ var init_sync_client = __esm({
20763
20819
  ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
20764
20820
  } catch {
20765
20821
  try {
20766
- if (true) ownVersion = "0.6.4";
20822
+ if (true) ownVersion = "0.6.6";
20767
20823
  } catch {
20768
20824
  }
20769
20825
  }
@@ -20797,7 +20853,7 @@ var init_sync_client = __esm({
20797
20853
  // ../engine/dist/core/artifact-codec.js
20798
20854
  import { readFileSync as readFileSync36 } from "fs";
20799
20855
  import { basename as basename21, join as join43 } from "path";
20800
- import { homedir as homedir15 } from "os";
20856
+ import { homedir as homedir16 } from "os";
20801
20857
  function parseCommandText(content, format, fallbackName) {
20802
20858
  if (format === "toml") {
20803
20859
  const t = parseScalarToml(content);
@@ -20887,7 +20943,7 @@ function instructionsPath(tool, projectPath) {
20887
20943
  case "codex":
20888
20944
  return join43(codexBackend.homeDir(), file);
20889
20945
  case "opencode":
20890
- return join43(homedir15(), ".config", "opencode", file);
20946
+ return join43(homedir16(), ".config", "opencode", file);
20891
20947
  // Cursor has no single user-scope instructions FILE — user-level guidance
20892
20948
  // is User Rules plus ~/.cursor/rules/*.mdc. AGENTS.md at the home root is
20893
20949
  // the closest equivalent and is what a mirror can actually write.
@@ -20938,9 +20994,9 @@ var init_artifact_codec = __esm({
20938
20994
  });
20939
20995
 
20940
20996
  // ../engine/dist/core/toolkit-sync.js
20941
- import { existsSync as existsSync41, mkdirSync as mkdirSync10, readFileSync as readFileSync37, writeFileSync as writeFileSync10, cpSync } from "fs";
20997
+ import { existsSync as existsSync41, mkdirSync as mkdirSync11, readFileSync as readFileSync37, writeFileSync as writeFileSync10, cpSync } from "fs";
20942
20998
  import { dirname as dirname20, join as join44, basename as basename22 } from "path";
20943
- import { homedir as homedir16 } from "os";
20999
+ import { homedir as homedir17 } from "os";
20944
21000
  function rowFromMemoryItem(type, item) {
20945
21001
  const extra = item.extra || {};
20946
21002
  return {
@@ -20979,7 +21035,7 @@ function copySkill(row, toTool) {
20979
21035
  if (existsSync41(targetDir))
20980
21036
  return { ok: false, status: 409, error: `Already exists: ${targetDir}` };
20981
21037
  try {
20982
- mkdirSync10(dirname20(targetDir), { recursive: true });
21038
+ mkdirSync11(dirname20(targetDir), { recursive: true });
20983
21039
  cpSync(skillDir, targetDir, { recursive: true });
20984
21040
  return { ok: true, targetPath: targetDir };
20985
21041
  } catch (e) {
@@ -20987,7 +21043,7 @@ function copySkill(row, toTool) {
20987
21043
  }
20988
21044
  }
20989
21045
  function readMcpEntry(tool, name) {
20990
- const home = homedir16();
21046
+ const home = homedir17();
20991
21047
  const tries = [];
20992
21048
  if (tool === "claude") {
20993
21049
  tries.push({ path: join44(home, ".mcp.json"), key: "mcpServers" });
@@ -21105,12 +21161,12 @@ function writeCodexMcpEntry(path, name, entry) {
21105
21161
  for (const [k, v] of Object.entries(entry.env))
21106
21162
  lines.push(`${k} = ${escape(String(v))}`);
21107
21163
  }
21108
- mkdirSync10(dirname20(path), { recursive: true });
21164
+ mkdirSync11(dirname20(path), { recursive: true });
21109
21165
  writeFileSync10(path, content + lines.join("\n") + "\n");
21110
21166
  return true;
21111
21167
  }
21112
21168
  function writeMcpEntry(toTool, name, entry) {
21113
- const home = homedir16();
21169
+ const home = homedir17();
21114
21170
  if (toTool === "codex") {
21115
21171
  const path2 = join44(home, ".codex", "config.toml");
21116
21172
  if (!writeCodexMcpEntry(path2, name, entry))
@@ -21140,7 +21196,7 @@ function writeMcpEntry(toTool, name, entry) {
21140
21196
  return { ok: false, status: 500, error: `Target config is malformed: ${path}` };
21141
21197
  }
21142
21198
  } else {
21143
- mkdirSync10(dirname20(path), { recursive: true });
21199
+ mkdirSync11(dirname20(path), { recursive: true });
21144
21200
  }
21145
21201
  cfg[key2] = cfg[key2] || {};
21146
21202
  if (cfg[key2][name])
@@ -21200,7 +21256,7 @@ function copyCommandOrAgent(type, row, toTool) {
21200
21256
  if (existsSync41(out.path))
21201
21257
  return { ok: false, status: 409, error: `Already exists: ${out.path}` };
21202
21258
  try {
21203
- mkdirSync10(dirname20(out.path), { recursive: true });
21259
+ mkdirSync11(dirname20(out.path), { recursive: true });
21204
21260
  writeFileSync10(out.path, out.content);
21205
21261
  return { ok: true, targetPath: out.path };
21206
21262
  } catch (e) {
@@ -21220,7 +21276,7 @@ function copyInstructions(row, toTool) {
21220
21276
  if (existsSync41(out.path))
21221
21277
  return { ok: false, status: 409, error: `Already exists: ${out.path}` };
21222
21278
  try {
21223
- mkdirSync10(dirname20(out.path), { recursive: true });
21279
+ mkdirSync11(dirname20(out.path), { recursive: true });
21224
21280
  writeFileSync10(out.path, out.content);
21225
21281
  return { ok: true, targetPath: out.path };
21226
21282
  } catch (e) {
@@ -21426,7 +21482,7 @@ __export(toolkit_pull_exports, {
21426
21482
  planPull: () => planPull,
21427
21483
  portableCommand: () => portableCommand
21428
21484
  });
21429
- import { existsSync as existsSync44, mkdirSync as mkdirSync12, statSync as statSync40, writeFileSync as writeFileSync12 } from "node:fs";
21485
+ import { existsSync as existsSync44, mkdirSync as mkdirSync13, statSync as statSync40, writeFileSync as writeFileSync12 } from "node:fs";
21430
21486
  import { dirname as dirname22, join as join47, basename as basename23, isAbsolute as isAbsolute3 } from "node:path";
21431
21487
  function isExecutableFile(p) {
21432
21488
  try {
@@ -21592,7 +21648,7 @@ function executePull(rows, opts = {}) {
21592
21648
  continue;
21593
21649
  }
21594
21650
  try {
21595
- mkdirSync12(dir, { recursive: true });
21651
+ mkdirSync13(dir, { recursive: true });
21596
21652
  writeFileSync12(file, body);
21597
21653
  outcomes.push({ type: "skill", name, tool, status: "written", path: file, redactedContent: redacted });
21598
21654
  } catch (e) {
@@ -21633,7 +21689,7 @@ function executePull(rows, opts = {}) {
21633
21689
  continue;
21634
21690
  }
21635
21691
  try {
21636
- mkdirSync12(dirname22(out.path), { recursive: true });
21692
+ mkdirSync13(dirname22(out.path), { recursive: true });
21637
21693
  writeFileSync12(out.path, out.content);
21638
21694
  outcomes.push({ type, name, tool, status: "written", path: out.path, redactedContent: redacted });
21639
21695
  } catch (e) {
@@ -22064,8 +22120,8 @@ var init_code_intel = __esm({
22064
22120
  });
22065
22121
 
22066
22122
  // ../engine/dist/core/companions.js
22067
- import { existsSync as existsSync47, mkdirSync as mkdirSync15, statSync as statSync43, chmodSync as chmodSync4, unlinkSync as unlinkSync4, renameSync as renameSync5, createWriteStream, readFileSync as readFileSync42, writeFileSync as writeFileSync15 } from "node:fs";
22068
- import { homedir as homedir18 } from "node:os";
22123
+ import { existsSync as existsSync47, mkdirSync as mkdirSync16, statSync as statSync43, chmodSync as chmodSync4, unlinkSync as unlinkSync4, renameSync as renameSync5, createWriteStream, readFileSync as readFileSync42, writeFileSync as writeFileSync15 } from "node:fs";
22124
+ import { homedir as homedir19 } from "node:os";
22069
22125
  import { join as join51 } from "node:path";
22070
22126
  import { execSync as execSync3 } from "node:child_process";
22071
22127
  import { createHash as createHash12 } from "node:crypto";
@@ -22168,7 +22224,7 @@ async function installCodeindex(opts = {}) {
22168
22224
  return status;
22169
22225
  if (!status.prebuiltAvailable)
22170
22226
  return status;
22171
- mkdirSync15(CODEINDEX_INSTALL_DIR, { recursive: true });
22227
+ mkdirSync16(CODEINDEX_INSTALL_DIR, { recursive: true });
22172
22228
  const tmpPath = `${CODEINDEX_BIN_PATH}.partial`;
22173
22229
  try {
22174
22230
  await downloadArtifact(status.artifactName, tmpPath);
@@ -22210,7 +22266,7 @@ var init_companions = __esm({
22210
22266
  "x86_64-windows": "a96fc8c8949bb399a44cc0615b12e458460a529c69f01e8829cc39a20f45ab29",
22211
22267
  "aarch64-windows": "42620d56272cd9ba9d785569d8d754d6b4a3e80f36f28db3e0c483fd600ed117"
22212
22268
  };
22213
- CODEINDEX_INSTALL_DIR = join51(homedir18(), ".local", "bin");
22269
+ CODEINDEX_INSTALL_DIR = join51(homedir19(), ".local", "bin");
22214
22270
  CODEINDEX_BIN_NAME = process.platform === "win32" ? "codeindex.exe" : "codeindex";
22215
22271
  CODEINDEX_BIN_PATH = join51(CODEINDEX_INSTALL_DIR, CODEINDEX_BIN_NAME);
22216
22272
  }
@@ -23271,14 +23327,14 @@ __export(service_installer_exports, {
23271
23327
  uninstallService: () => uninstallService
23272
23328
  });
23273
23329
  import { execSync as execSync5 } from "child_process";
23274
- import { existsSync as existsSync48, mkdirSync as mkdirSync16, readFileSync as readFileSync44, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "fs";
23275
- import { homedir as homedir19 } from "os";
23330
+ import { existsSync as existsSync48, mkdirSync as mkdirSync17, readFileSync as readFileSync44, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "fs";
23331
+ import { homedir as homedir20 } from "os";
23276
23332
  import { join as join53 } from "path";
23277
23333
  import { fileURLToPath as fileURLToPath5 } from "url";
23278
23334
  function resolveDaemonPaths() {
23279
23335
  const watchJs = fileURLToPath5(new URL("./watch.js", import.meta.url));
23280
23336
  const node = process.execPath;
23281
- const dataDir = join53(homedir19(), ".chat-recall");
23337
+ const dataDir = join53(homedir20(), ".chat-recall");
23282
23338
  const logFile = join53(dataDir, "watch.log");
23283
23339
  return { watchJs, node, logFile, dataDir };
23284
23340
  }
@@ -23306,7 +23362,7 @@ function refreshServiceDefinition() {
23306
23362
  if (process.platform !== "linux") return false;
23307
23363
  try {
23308
23364
  const { watchJs, node, logFile } = resolveDaemonPaths();
23309
- const unitPath = join53(homedir19(), ".config", "systemd", "user", "chat-recall-watch.service");
23365
+ const unitPath = join53(homedir20(), ".config", "systemd", "user", "chat-recall-watch.service");
23310
23366
  if (!existsSync48(unitPath)) return false;
23311
23367
  const current = readFileSync44(unitPath, "utf8");
23312
23368
  if (!current.includes(watchJs)) return false;
@@ -23321,7 +23377,7 @@ function refreshServiceDefinition() {
23321
23377
  }
23322
23378
  function installService() {
23323
23379
  const { watchJs, node, logFile, dataDir } = resolveDaemonPaths();
23324
- mkdirSync16(dataDir, { recursive: true });
23380
+ mkdirSync17(dataDir, { recursive: true });
23325
23381
  if (process.platform === "linux") {
23326
23382
  return installSystemd(watchJs, node, logFile);
23327
23383
  }
@@ -23337,10 +23393,10 @@ function installService() {
23337
23393
  );
23338
23394
  }
23339
23395
  function installSystemd(watchJs, node, logFile) {
23340
- const unitDir = join53(homedir19(), ".config", "systemd", "user");
23396
+ const unitDir = join53(homedir20(), ".config", "systemd", "user");
23341
23397
  const unitPath = join53(unitDir, "chat-recall-watch.service");
23342
23398
  const unit = renderSystemdUnit(watchJs, node, logFile);
23343
- mkdirSync16(unitDir, { recursive: true });
23399
+ mkdirSync17(unitDir, { recursive: true });
23344
23400
  writeFileSync16(unitPath, unit);
23345
23401
  try {
23346
23402
  execSync5("systemctl --user daemon-reload && systemctl --user enable chat-recall-watch.service && systemctl --user restart chat-recall-watch.service", { stdio: "inherit" });
@@ -23412,10 +23468,10 @@ function renderSystemdUnit(watchJs, node, logFile) {
23412
23468
  }
23413
23469
  function installLaunchd(watchJs, node, logFile) {
23414
23470
  const label = "com.chat-recall.watch";
23415
- const plistDir = join53(homedir19(), "Library", "LaunchAgents");
23471
+ const plistDir = join53(homedir20(), "Library", "LaunchAgents");
23416
23472
  const plistPath = join53(plistDir, `${label}.plist`);
23417
23473
  const plist = renderLaunchdPlist(watchJs, node, logFile, label);
23418
- mkdirSync16(plistDir, { recursive: true });
23474
+ mkdirSync17(plistDir, { recursive: true });
23419
23475
  writeFileSync16(plistPath, plist);
23420
23476
  try {
23421
23477
  try {
@@ -23469,7 +23525,7 @@ function uninstallService() {
23469
23525
  removed = true;
23470
23526
  } catch {
23471
23527
  }
23472
- const unitPath = join53(homedir19(), ".config", "systemd", "user", "chat-recall-watch.service");
23528
+ const unitPath = join53(homedir20(), ".config", "systemd", "user", "chat-recall-watch.service");
23473
23529
  if (existsSync48(unitPath)) {
23474
23530
  rmSync7(unitPath, { force: true });
23475
23531
  removed = true;
@@ -23481,7 +23537,7 @@ function uninstallService() {
23481
23537
  return removed;
23482
23538
  }
23483
23539
  if (process.platform === "darwin") {
23484
- const plistPath = join53(homedir19(), "Library", "LaunchAgents", "com.chat-recall.watch.plist");
23540
+ const plistPath = join53(homedir20(), "Library", "LaunchAgents", "com.chat-recall.watch.plist");
23485
23541
  try {
23486
23542
  execSync5(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore" });
23487
23543
  } catch {
@@ -23531,7 +23587,7 @@ init_sync_client();
23531
23587
  init_http();
23532
23588
  import chokidar from "chokidar";
23533
23589
  import { dirname as dirname25, basename as basename25, join as join54, resolve as resolve2, sep as sep4 } from "path";
23534
- import { homedir as homedir20 } from "os";
23590
+ import { homedir as homedir21 } from "os";
23535
23591
 
23536
23592
  // src/intent-drain.ts
23537
23593
  init_http();
@@ -23543,14 +23599,14 @@ init_codex2();
23543
23599
  init_cursor();
23544
23600
  init_opencode();
23545
23601
  init_agy();
23546
- import { existsSync as existsSync45, readFileSync as readFileSync39, writeFileSync as writeFileSync13, appendFileSync, mkdirSync as mkdirSync13 } from "node:fs";
23602
+ import { existsSync as existsSync45, readFileSync as readFileSync39, writeFileSync as writeFileSync13, appendFileSync, mkdirSync as mkdirSync14 } from "node:fs";
23547
23603
  import { join as join48 } from "node:path";
23548
23604
 
23549
23605
  // src/project-tasks.ts
23550
23606
  init_http();
23551
- import { existsSync as existsSync42, readFileSync as readFileSync38, writeFileSync as writeFileSync11, mkdirSync as mkdirSync11, statSync as statSync38 } from "node:fs";
23607
+ import { existsSync as existsSync42, readFileSync as readFileSync38, writeFileSync as writeFileSync11, mkdirSync as mkdirSync12, statSync as statSync38 } from "node:fs";
23552
23608
  import { join as join45, dirname as dirname21 } from "node:path";
23553
- import { homedir as homedir17 } from "node:os";
23609
+ import { homedir as homedir18 } from "node:os";
23554
23610
 
23555
23611
  // ../engine/dist/core/secret-task-status.js
23556
23612
  var SECRET_TASK_STATUSES = ["open", "rotated", "not-a-secret", "dismissed"];
@@ -23618,7 +23674,7 @@ function parseTaskFile(content) {
23618
23674
  return out;
23619
23675
  }
23620
23676
  function ledgerPath2() {
23621
- return join45(homedir17(), ".chat-recall", "project-tasks-ledger.json");
23677
+ return join45(homedir18(), ".chat-recall", "project-tasks-ledger.json");
23622
23678
  }
23623
23679
  function readLedger() {
23624
23680
  try {
@@ -23629,7 +23685,7 @@ function readLedger() {
23629
23685
  }
23630
23686
  function writeLedger(l) {
23631
23687
  try {
23632
- mkdirSync11(dirname21(ledgerPath2()), { recursive: true });
23688
+ mkdirSync12(dirname21(ledgerPath2()), { recursive: true });
23633
23689
  } catch {
23634
23690
  }
23635
23691
  try {
@@ -23742,7 +23798,7 @@ function applyCodeRecommendation(intent) {
23742
23798
  for (const file of targets) {
23743
23799
  const dir = file.slice(0, file.lastIndexOf("/"));
23744
23800
  try {
23745
- mkdirSync13(dir, { recursive: true });
23801
+ mkdirSync14(dir, { recursive: true });
23746
23802
  } catch {
23747
23803
  }
23748
23804
  const existing = existsSync45(file) ? readFileSync39(file, "utf8") : "";
@@ -23847,7 +23903,7 @@ try {
23847
23903
  ownVersion2 = JSON.parse(readFileSync39(join48(dir, "../package.json"), "utf-8")).version || ownVersion2;
23848
23904
  } catch {
23849
23905
  try {
23850
- if (true) ownVersion2 = "0.6.4";
23906
+ if (true) ownVersion2 = "0.6.6";
23851
23907
  } catch {
23852
23908
  }
23853
23909
  }
@@ -23912,7 +23968,7 @@ init_auto_update();
23912
23968
 
23913
23969
  // src/code-index-cursor.ts
23914
23970
  init_paths();
23915
- import { readFileSync as readFileSync40, writeFileSync as writeFileSync14, mkdirSync as mkdirSync14 } from "fs";
23971
+ import { readFileSync as readFileSync40, writeFileSync as writeFileSync14, mkdirSync as mkdirSync15 } from "fs";
23916
23972
  import { join as join49, dirname as dirname24 } from "path";
23917
23973
  var cursorPath = () => join49(getDataDir(), "code-index-cursor.json");
23918
23974
  function readCursor() {
@@ -23932,7 +23988,7 @@ function readCursor() {
23932
23988
  function writeCursor(c) {
23933
23989
  try {
23934
23990
  const p = cursorPath();
23935
- mkdirSync14(dirname24(p), { recursive: true });
23991
+ mkdirSync15(dirname24(p), { recursive: true });
23936
23992
  writeFileSync14(p, JSON.stringify(c));
23937
23993
  } catch {
23938
23994
  }
@@ -24195,7 +24251,7 @@ async function runCollectorMigration(opts) {
24195
24251
  init_sync_ledger();
24196
24252
  init_collector_health();
24197
24253
  import { existsSync as existsSync49, readFileSync as readFileSync45, statSync as statSync44 } from "fs";
24198
- var CLI_VERSION3 = true ? "0.6.4" : "0.0.0";
24254
+ var CLI_VERSION3 = true ? "0.6.6" : "0.0.0";
24199
24255
  var DEBOUNCE_MS = 5e3;
24200
24256
  var CLAUDE_DIR = claudeBackend.projectsDir();
24201
24257
  var PLANS_DIR = claudeBackend.plansDir();
@@ -24632,7 +24688,7 @@ var WORKSPACE_MARKERS = [
24632
24688
  function isCodeWorkspace(p) {
24633
24689
  try {
24634
24690
  const resolved = resolve2(p);
24635
- if (resolved === sep4 || resolved === homedir20() || dirname25(resolved) === resolved) return false;
24691
+ if (resolved === sep4 || resolved === homedir21() || dirname25(resolved) === resolved) return false;
24636
24692
  } catch {
24637
24693
  return false;
24638
24694
  }