chat-recall 0.6.5 → 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.
- package/README.md +45 -0
- package/dist/auto-update.d.ts +12 -0
- package/dist/auto-update.d.ts.map +1 -1
- package/dist/auto-update.js +115 -9
- package/dist/auto-update.js.map +1 -1
- package/dist/board-hooks.d.ts +56 -0
- package/dist/board-hooks.d.ts.map +1 -0
- package/dist/board-hooks.js +144 -0
- package/dist/board-hooks.js.map +1 -0
- package/dist/cli.js +1501 -353
- package/dist/cli.js.map +1 -1
- package/dist/mcp-relay.js +1 -1
- package/dist/mcp.js +85 -30
- package/dist/star-nudge.d.ts +13 -0
- package/dist/star-nudge.d.ts.map +1 -0
- package/dist/star-nudge.js +83 -0
- package/dist/star-nudge.js.map +1 -0
- package/dist/watch.js +111 -56
- package/hooks/chat_recall_guard_hook.sh +54 -0
- package/package.json +1 -1
package/dist/watch.js
CHANGED
|
@@ -18305,7 +18305,7 @@ var init_http = __esm({
|
|
|
18305
18305
|
CLI_VERSION = JSON.parse(readFileSync31(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
18306
18306
|
} catch {
|
|
18307
18307
|
try {
|
|
18308
|
-
if (true) CLI_VERSION = "0.6.
|
|
18308
|
+
if (true) CLI_VERSION = "0.6.6";
|
|
18309
18309
|
} catch {
|
|
18310
18310
|
}
|
|
18311
18311
|
}
|
|
@@ -18821,7 +18821,7 @@ var init_telemetry = __esm({
|
|
|
18821
18821
|
init_sync_client();
|
|
18822
18822
|
cliVersion = () => {
|
|
18823
18823
|
try {
|
|
18824
|
-
return true ? "0.6.
|
|
18824
|
+
return true ? "0.6.6" : "dev";
|
|
18825
18825
|
} catch {
|
|
18826
18826
|
return "dev";
|
|
18827
18827
|
}
|
|
@@ -19090,12 +19090,16 @@ var init_client_events = __esm({
|
|
|
19090
19090
|
// src/auto-update.ts
|
|
19091
19091
|
var auto_update_exports = {};
|
|
19092
19092
|
__export(auto_update_exports, {
|
|
19093
|
+
clearUpdateFailures: () => clearUpdateFailures,
|
|
19093
19094
|
compareVersions: () => compareVersions,
|
|
19094
19095
|
executeAutoUpdate: () => executeAutoUpdate,
|
|
19096
|
+
hasGivenUpOn: () => hasGivenUpOn,
|
|
19095
19097
|
installedVersion: () => installedVersion,
|
|
19096
19098
|
isAutoUpdateEnabled: () => isAutoUpdateEnabled,
|
|
19097
19099
|
newerOf: () => newerOf,
|
|
19100
|
+
noteUpdateFailure: () => noteUpdateFailure,
|
|
19098
19101
|
planAutoUpdate: () => planAutoUpdate,
|
|
19102
|
+
readUpdateState: () => readUpdateState,
|
|
19099
19103
|
runAutoUpdate: () => runAutoUpdate,
|
|
19100
19104
|
runningPrefix: () => runningPrefix,
|
|
19101
19105
|
sweepStaleStaging: () => sweepStaleStaging,
|
|
@@ -19104,9 +19108,9 @@ __export(auto_update_exports, {
|
|
|
19104
19108
|
import { execSync as execSync2 } from "node:child_process";
|
|
19105
19109
|
import { readFileSync as readFileSync34 } from "node:fs";
|
|
19106
19110
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
19107
|
-
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";
|
|
19108
19112
|
import { join as join41, dirname as dirname18, sep as sep2 } from "node:path";
|
|
19109
|
-
import { tmpdir as tmpdir2 } from "node:os";
|
|
19113
|
+
import { tmpdir as tmpdir2, homedir as homedir15 } from "node:os";
|
|
19110
19114
|
import { createHash as createHash7 } from "node:crypto";
|
|
19111
19115
|
function compareVersions(a, b) {
|
|
19112
19116
|
const pa = String(a).split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
|
|
@@ -19220,16 +19224,25 @@ function runningPrefix(moduleUrl = import.meta.url) {
|
|
|
19220
19224
|
const beforeNodeModules = here.slice(0, at);
|
|
19221
19225
|
return beforeNodeModules.endsWith(`${sep2}lib`) ? beforeNodeModules.slice(0, -4) : beforeNodeModules;
|
|
19222
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
|
+
}
|
|
19223
19236
|
function realInstall(tgz) {
|
|
19224
19237
|
const prefix = runningPrefix();
|
|
19225
19238
|
if (prefix) {
|
|
19226
|
-
|
|
19239
|
+
npmInstall(`npm install -g --prefix "${prefix}" "${tgz}"`);
|
|
19227
19240
|
return;
|
|
19228
19241
|
}
|
|
19229
19242
|
try {
|
|
19230
|
-
|
|
19243
|
+
npmInstall(`npm install -g "${tgz}"`);
|
|
19231
19244
|
} catch {
|
|
19232
|
-
|
|
19245
|
+
npmInstall(`npm install -g --prefix "${process.env.HOME}/.local" "${tgz}"`);
|
|
19233
19246
|
}
|
|
19234
19247
|
}
|
|
19235
19248
|
function realRestart(platform2) {
|
|
@@ -19237,6 +19250,37 @@ function realRestart(platform2) {
|
|
|
19237
19250
|
else if (platform2 === "darwin") execSync2("launchctl kickstart -k gui/$(id -u)/com.chat-recall.watch", { stdio: "ignore", shell: "/bin/bash" });
|
|
19238
19251
|
else if (platform2 === "win32") execSync2("schtasks /End /TN chat-recall-watch & schtasks /Run /TN chat-recall-watch", { stdio: "ignore" });
|
|
19239
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
|
+
}
|
|
19240
19284
|
async function runAutoUpdate(base2, authHeaders, ownVersion3, deps) {
|
|
19241
19285
|
let caps;
|
|
19242
19286
|
try {
|
|
@@ -19259,6 +19303,10 @@ async function runAutoUpdate(base2, authHeaders, ownVersion3, deps) {
|
|
|
19259
19303
|
}
|
|
19260
19304
|
return { updated: false, reason: plan.reason };
|
|
19261
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
|
+
}
|
|
19262
19310
|
const result = await executeAutoUpdate(plan, {
|
|
19263
19311
|
download: deps?.download ?? realDownload,
|
|
19264
19312
|
install: deps?.install ?? realInstall,
|
|
@@ -19266,27 +19314,34 @@ async function runAutoUpdate(base2, authHeaders, ownVersion3, deps) {
|
|
|
19266
19314
|
platform: deps?.platform
|
|
19267
19315
|
});
|
|
19268
19316
|
if (!result.updated) {
|
|
19269
|
-
|
|
19270
|
-
|
|
19271
|
-
|
|
19272
|
-
|
|
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
|
+
}
|
|
19273
19325
|
}
|
|
19326
|
+
} else {
|
|
19327
|
+
clearUpdateFailures();
|
|
19274
19328
|
}
|
|
19275
19329
|
return result;
|
|
19276
19330
|
}
|
|
19277
|
-
var tarballUrl, reportedStandingSkip;
|
|
19331
|
+
var tarballUrl, GIVE_UP_AFTER, reportedStandingSkip;
|
|
19278
19332
|
var init_auto_update = __esm({
|
|
19279
19333
|
"src/auto-update.ts"() {
|
|
19280
19334
|
"use strict";
|
|
19281
19335
|
init_http();
|
|
19282
19336
|
tarballUrl = (base2) => `${base2.replace(/\/+$/, "")}/install/chat-recall.tgz`;
|
|
19337
|
+
GIVE_UP_AFTER = 3;
|
|
19283
19338
|
reportedStandingSkip = /* @__PURE__ */ new Set();
|
|
19284
19339
|
}
|
|
19285
19340
|
});
|
|
19286
19341
|
|
|
19287
19342
|
// src/sync-client.ts
|
|
19288
19343
|
import { join as join42, dirname as dirname19, basename as basename20 } from "node:path";
|
|
19289
|
-
import { readFileSync as readFileSync35, writeFileSync as writeFileSync9, mkdirSync as
|
|
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";
|
|
19290
19345
|
import { tmpdir as tmpdir3, hostname as hostname2 } from "node:os";
|
|
19291
19346
|
import { createHash as createHash8 } from "node:crypto";
|
|
19292
19347
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
@@ -19395,7 +19450,7 @@ function persistSyncConfig(base2, config) {
|
|
|
19395
19450
|
try {
|
|
19396
19451
|
const all = readPersistedSyncConfigs();
|
|
19397
19452
|
all[base2] = { fetchedAt: Date.now(), config };
|
|
19398
|
-
|
|
19453
|
+
mkdirSync10(dirname19(syncConfigCachePath()), { recursive: true });
|
|
19399
19454
|
writeFileSync9(syncConfigCachePath(), JSON.stringify(all, null, 2));
|
|
19400
19455
|
} catch {
|
|
19401
19456
|
}
|
|
@@ -20764,7 +20819,7 @@ var init_sync_client = __esm({
|
|
|
20764
20819
|
ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
20765
20820
|
} catch {
|
|
20766
20821
|
try {
|
|
20767
|
-
if (true) ownVersion = "0.6.
|
|
20822
|
+
if (true) ownVersion = "0.6.6";
|
|
20768
20823
|
} catch {
|
|
20769
20824
|
}
|
|
20770
20825
|
}
|
|
@@ -20798,7 +20853,7 @@ var init_sync_client = __esm({
|
|
|
20798
20853
|
// ../engine/dist/core/artifact-codec.js
|
|
20799
20854
|
import { readFileSync as readFileSync36 } from "fs";
|
|
20800
20855
|
import { basename as basename21, join as join43 } from "path";
|
|
20801
|
-
import { homedir as
|
|
20856
|
+
import { homedir as homedir16 } from "os";
|
|
20802
20857
|
function parseCommandText(content, format, fallbackName) {
|
|
20803
20858
|
if (format === "toml") {
|
|
20804
20859
|
const t = parseScalarToml(content);
|
|
@@ -20888,7 +20943,7 @@ function instructionsPath(tool, projectPath) {
|
|
|
20888
20943
|
case "codex":
|
|
20889
20944
|
return join43(codexBackend.homeDir(), file);
|
|
20890
20945
|
case "opencode":
|
|
20891
|
-
return join43(
|
|
20946
|
+
return join43(homedir16(), ".config", "opencode", file);
|
|
20892
20947
|
// Cursor has no single user-scope instructions FILE — user-level guidance
|
|
20893
20948
|
// is User Rules plus ~/.cursor/rules/*.mdc. AGENTS.md at the home root is
|
|
20894
20949
|
// the closest equivalent and is what a mirror can actually write.
|
|
@@ -20939,9 +20994,9 @@ var init_artifact_codec = __esm({
|
|
|
20939
20994
|
});
|
|
20940
20995
|
|
|
20941
20996
|
// ../engine/dist/core/toolkit-sync.js
|
|
20942
|
-
import { existsSync as existsSync41, mkdirSync as
|
|
20997
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync11, readFileSync as readFileSync37, writeFileSync as writeFileSync10, cpSync } from "fs";
|
|
20943
20998
|
import { dirname as dirname20, join as join44, basename as basename22 } from "path";
|
|
20944
|
-
import { homedir as
|
|
20999
|
+
import { homedir as homedir17 } from "os";
|
|
20945
21000
|
function rowFromMemoryItem(type, item) {
|
|
20946
21001
|
const extra = item.extra || {};
|
|
20947
21002
|
return {
|
|
@@ -20980,7 +21035,7 @@ function copySkill(row, toTool) {
|
|
|
20980
21035
|
if (existsSync41(targetDir))
|
|
20981
21036
|
return { ok: false, status: 409, error: `Already exists: ${targetDir}` };
|
|
20982
21037
|
try {
|
|
20983
|
-
|
|
21038
|
+
mkdirSync11(dirname20(targetDir), { recursive: true });
|
|
20984
21039
|
cpSync(skillDir, targetDir, { recursive: true });
|
|
20985
21040
|
return { ok: true, targetPath: targetDir };
|
|
20986
21041
|
} catch (e) {
|
|
@@ -20988,7 +21043,7 @@ function copySkill(row, toTool) {
|
|
|
20988
21043
|
}
|
|
20989
21044
|
}
|
|
20990
21045
|
function readMcpEntry(tool, name) {
|
|
20991
|
-
const home =
|
|
21046
|
+
const home = homedir17();
|
|
20992
21047
|
const tries = [];
|
|
20993
21048
|
if (tool === "claude") {
|
|
20994
21049
|
tries.push({ path: join44(home, ".mcp.json"), key: "mcpServers" });
|
|
@@ -21106,12 +21161,12 @@ function writeCodexMcpEntry(path, name, entry) {
|
|
|
21106
21161
|
for (const [k, v] of Object.entries(entry.env))
|
|
21107
21162
|
lines.push(`${k} = ${escape(String(v))}`);
|
|
21108
21163
|
}
|
|
21109
|
-
|
|
21164
|
+
mkdirSync11(dirname20(path), { recursive: true });
|
|
21110
21165
|
writeFileSync10(path, content + lines.join("\n") + "\n");
|
|
21111
21166
|
return true;
|
|
21112
21167
|
}
|
|
21113
21168
|
function writeMcpEntry(toTool, name, entry) {
|
|
21114
|
-
const home =
|
|
21169
|
+
const home = homedir17();
|
|
21115
21170
|
if (toTool === "codex") {
|
|
21116
21171
|
const path2 = join44(home, ".codex", "config.toml");
|
|
21117
21172
|
if (!writeCodexMcpEntry(path2, name, entry))
|
|
@@ -21141,7 +21196,7 @@ function writeMcpEntry(toTool, name, entry) {
|
|
|
21141
21196
|
return { ok: false, status: 500, error: `Target config is malformed: ${path}` };
|
|
21142
21197
|
}
|
|
21143
21198
|
} else {
|
|
21144
|
-
|
|
21199
|
+
mkdirSync11(dirname20(path), { recursive: true });
|
|
21145
21200
|
}
|
|
21146
21201
|
cfg[key2] = cfg[key2] || {};
|
|
21147
21202
|
if (cfg[key2][name])
|
|
@@ -21201,7 +21256,7 @@ function copyCommandOrAgent(type, row, toTool) {
|
|
|
21201
21256
|
if (existsSync41(out.path))
|
|
21202
21257
|
return { ok: false, status: 409, error: `Already exists: ${out.path}` };
|
|
21203
21258
|
try {
|
|
21204
|
-
|
|
21259
|
+
mkdirSync11(dirname20(out.path), { recursive: true });
|
|
21205
21260
|
writeFileSync10(out.path, out.content);
|
|
21206
21261
|
return { ok: true, targetPath: out.path };
|
|
21207
21262
|
} catch (e) {
|
|
@@ -21221,7 +21276,7 @@ function copyInstructions(row, toTool) {
|
|
|
21221
21276
|
if (existsSync41(out.path))
|
|
21222
21277
|
return { ok: false, status: 409, error: `Already exists: ${out.path}` };
|
|
21223
21278
|
try {
|
|
21224
|
-
|
|
21279
|
+
mkdirSync11(dirname20(out.path), { recursive: true });
|
|
21225
21280
|
writeFileSync10(out.path, out.content);
|
|
21226
21281
|
return { ok: true, targetPath: out.path };
|
|
21227
21282
|
} catch (e) {
|
|
@@ -21427,7 +21482,7 @@ __export(toolkit_pull_exports, {
|
|
|
21427
21482
|
planPull: () => planPull,
|
|
21428
21483
|
portableCommand: () => portableCommand
|
|
21429
21484
|
});
|
|
21430
|
-
import { existsSync as existsSync44, mkdirSync as
|
|
21485
|
+
import { existsSync as existsSync44, mkdirSync as mkdirSync13, statSync as statSync40, writeFileSync as writeFileSync12 } from "node:fs";
|
|
21431
21486
|
import { dirname as dirname22, join as join47, basename as basename23, isAbsolute as isAbsolute3 } from "node:path";
|
|
21432
21487
|
function isExecutableFile(p) {
|
|
21433
21488
|
try {
|
|
@@ -21593,7 +21648,7 @@ function executePull(rows, opts = {}) {
|
|
|
21593
21648
|
continue;
|
|
21594
21649
|
}
|
|
21595
21650
|
try {
|
|
21596
|
-
|
|
21651
|
+
mkdirSync13(dir, { recursive: true });
|
|
21597
21652
|
writeFileSync12(file, body);
|
|
21598
21653
|
outcomes.push({ type: "skill", name, tool, status: "written", path: file, redactedContent: redacted });
|
|
21599
21654
|
} catch (e) {
|
|
@@ -21634,7 +21689,7 @@ function executePull(rows, opts = {}) {
|
|
|
21634
21689
|
continue;
|
|
21635
21690
|
}
|
|
21636
21691
|
try {
|
|
21637
|
-
|
|
21692
|
+
mkdirSync13(dirname22(out.path), { recursive: true });
|
|
21638
21693
|
writeFileSync12(out.path, out.content);
|
|
21639
21694
|
outcomes.push({ type, name, tool, status: "written", path: out.path, redactedContent: redacted });
|
|
21640
21695
|
} catch (e) {
|
|
@@ -22065,8 +22120,8 @@ var init_code_intel = __esm({
|
|
|
22065
22120
|
});
|
|
22066
22121
|
|
|
22067
22122
|
// ../engine/dist/core/companions.js
|
|
22068
|
-
import { existsSync as existsSync47, mkdirSync as
|
|
22069
|
-
import { homedir as
|
|
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";
|
|
22070
22125
|
import { join as join51 } from "node:path";
|
|
22071
22126
|
import { execSync as execSync3 } from "node:child_process";
|
|
22072
22127
|
import { createHash as createHash12 } from "node:crypto";
|
|
@@ -22169,7 +22224,7 @@ async function installCodeindex(opts = {}) {
|
|
|
22169
22224
|
return status;
|
|
22170
22225
|
if (!status.prebuiltAvailable)
|
|
22171
22226
|
return status;
|
|
22172
|
-
|
|
22227
|
+
mkdirSync16(CODEINDEX_INSTALL_DIR, { recursive: true });
|
|
22173
22228
|
const tmpPath = `${CODEINDEX_BIN_PATH}.partial`;
|
|
22174
22229
|
try {
|
|
22175
22230
|
await downloadArtifact(status.artifactName, tmpPath);
|
|
@@ -22211,7 +22266,7 @@ var init_companions = __esm({
|
|
|
22211
22266
|
"x86_64-windows": "a96fc8c8949bb399a44cc0615b12e458460a529c69f01e8829cc39a20f45ab29",
|
|
22212
22267
|
"aarch64-windows": "42620d56272cd9ba9d785569d8d754d6b4a3e80f36f28db3e0c483fd600ed117"
|
|
22213
22268
|
};
|
|
22214
|
-
CODEINDEX_INSTALL_DIR = join51(
|
|
22269
|
+
CODEINDEX_INSTALL_DIR = join51(homedir19(), ".local", "bin");
|
|
22215
22270
|
CODEINDEX_BIN_NAME = process.platform === "win32" ? "codeindex.exe" : "codeindex";
|
|
22216
22271
|
CODEINDEX_BIN_PATH = join51(CODEINDEX_INSTALL_DIR, CODEINDEX_BIN_NAME);
|
|
22217
22272
|
}
|
|
@@ -23272,14 +23327,14 @@ __export(service_installer_exports, {
|
|
|
23272
23327
|
uninstallService: () => uninstallService
|
|
23273
23328
|
});
|
|
23274
23329
|
import { execSync as execSync5 } from "child_process";
|
|
23275
|
-
import { existsSync as existsSync48, mkdirSync as
|
|
23276
|
-
import { homedir as
|
|
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";
|
|
23277
23332
|
import { join as join53 } from "path";
|
|
23278
23333
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
23279
23334
|
function resolveDaemonPaths() {
|
|
23280
23335
|
const watchJs = fileURLToPath5(new URL("./watch.js", import.meta.url));
|
|
23281
23336
|
const node = process.execPath;
|
|
23282
|
-
const dataDir = join53(
|
|
23337
|
+
const dataDir = join53(homedir20(), ".chat-recall");
|
|
23283
23338
|
const logFile = join53(dataDir, "watch.log");
|
|
23284
23339
|
return { watchJs, node, logFile, dataDir };
|
|
23285
23340
|
}
|
|
@@ -23307,7 +23362,7 @@ function refreshServiceDefinition() {
|
|
|
23307
23362
|
if (process.platform !== "linux") return false;
|
|
23308
23363
|
try {
|
|
23309
23364
|
const { watchJs, node, logFile } = resolveDaemonPaths();
|
|
23310
|
-
const unitPath = join53(
|
|
23365
|
+
const unitPath = join53(homedir20(), ".config", "systemd", "user", "chat-recall-watch.service");
|
|
23311
23366
|
if (!existsSync48(unitPath)) return false;
|
|
23312
23367
|
const current = readFileSync44(unitPath, "utf8");
|
|
23313
23368
|
if (!current.includes(watchJs)) return false;
|
|
@@ -23322,7 +23377,7 @@ function refreshServiceDefinition() {
|
|
|
23322
23377
|
}
|
|
23323
23378
|
function installService() {
|
|
23324
23379
|
const { watchJs, node, logFile, dataDir } = resolveDaemonPaths();
|
|
23325
|
-
|
|
23380
|
+
mkdirSync17(dataDir, { recursive: true });
|
|
23326
23381
|
if (process.platform === "linux") {
|
|
23327
23382
|
return installSystemd(watchJs, node, logFile);
|
|
23328
23383
|
}
|
|
@@ -23338,10 +23393,10 @@ function installService() {
|
|
|
23338
23393
|
);
|
|
23339
23394
|
}
|
|
23340
23395
|
function installSystemd(watchJs, node, logFile) {
|
|
23341
|
-
const unitDir = join53(
|
|
23396
|
+
const unitDir = join53(homedir20(), ".config", "systemd", "user");
|
|
23342
23397
|
const unitPath = join53(unitDir, "chat-recall-watch.service");
|
|
23343
23398
|
const unit = renderSystemdUnit(watchJs, node, logFile);
|
|
23344
|
-
|
|
23399
|
+
mkdirSync17(unitDir, { recursive: true });
|
|
23345
23400
|
writeFileSync16(unitPath, unit);
|
|
23346
23401
|
try {
|
|
23347
23402
|
execSync5("systemctl --user daemon-reload && systemctl --user enable chat-recall-watch.service && systemctl --user restart chat-recall-watch.service", { stdio: "inherit" });
|
|
@@ -23413,10 +23468,10 @@ function renderSystemdUnit(watchJs, node, logFile) {
|
|
|
23413
23468
|
}
|
|
23414
23469
|
function installLaunchd(watchJs, node, logFile) {
|
|
23415
23470
|
const label = "com.chat-recall.watch";
|
|
23416
|
-
const plistDir = join53(
|
|
23471
|
+
const plistDir = join53(homedir20(), "Library", "LaunchAgents");
|
|
23417
23472
|
const plistPath = join53(plistDir, `${label}.plist`);
|
|
23418
23473
|
const plist = renderLaunchdPlist(watchJs, node, logFile, label);
|
|
23419
|
-
|
|
23474
|
+
mkdirSync17(plistDir, { recursive: true });
|
|
23420
23475
|
writeFileSync16(plistPath, plist);
|
|
23421
23476
|
try {
|
|
23422
23477
|
try {
|
|
@@ -23470,7 +23525,7 @@ function uninstallService() {
|
|
|
23470
23525
|
removed = true;
|
|
23471
23526
|
} catch {
|
|
23472
23527
|
}
|
|
23473
|
-
const unitPath = join53(
|
|
23528
|
+
const unitPath = join53(homedir20(), ".config", "systemd", "user", "chat-recall-watch.service");
|
|
23474
23529
|
if (existsSync48(unitPath)) {
|
|
23475
23530
|
rmSync7(unitPath, { force: true });
|
|
23476
23531
|
removed = true;
|
|
@@ -23482,7 +23537,7 @@ function uninstallService() {
|
|
|
23482
23537
|
return removed;
|
|
23483
23538
|
}
|
|
23484
23539
|
if (process.platform === "darwin") {
|
|
23485
|
-
const plistPath = join53(
|
|
23540
|
+
const plistPath = join53(homedir20(), "Library", "LaunchAgents", "com.chat-recall.watch.plist");
|
|
23486
23541
|
try {
|
|
23487
23542
|
execSync5(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore" });
|
|
23488
23543
|
} catch {
|
|
@@ -23532,7 +23587,7 @@ init_sync_client();
|
|
|
23532
23587
|
init_http();
|
|
23533
23588
|
import chokidar from "chokidar";
|
|
23534
23589
|
import { dirname as dirname25, basename as basename25, join as join54, resolve as resolve2, sep as sep4 } from "path";
|
|
23535
|
-
import { homedir as
|
|
23590
|
+
import { homedir as homedir21 } from "os";
|
|
23536
23591
|
|
|
23537
23592
|
// src/intent-drain.ts
|
|
23538
23593
|
init_http();
|
|
@@ -23544,14 +23599,14 @@ init_codex2();
|
|
|
23544
23599
|
init_cursor();
|
|
23545
23600
|
init_opencode();
|
|
23546
23601
|
init_agy();
|
|
23547
|
-
import { existsSync as existsSync45, readFileSync as readFileSync39, writeFileSync as writeFileSync13, appendFileSync, mkdirSync as
|
|
23602
|
+
import { existsSync as existsSync45, readFileSync as readFileSync39, writeFileSync as writeFileSync13, appendFileSync, mkdirSync as mkdirSync14 } from "node:fs";
|
|
23548
23603
|
import { join as join48 } from "node:path";
|
|
23549
23604
|
|
|
23550
23605
|
// src/project-tasks.ts
|
|
23551
23606
|
init_http();
|
|
23552
|
-
import { existsSync as existsSync42, readFileSync as readFileSync38, writeFileSync as writeFileSync11, mkdirSync as
|
|
23607
|
+
import { existsSync as existsSync42, readFileSync as readFileSync38, writeFileSync as writeFileSync11, mkdirSync as mkdirSync12, statSync as statSync38 } from "node:fs";
|
|
23553
23608
|
import { join as join45, dirname as dirname21 } from "node:path";
|
|
23554
|
-
import { homedir as
|
|
23609
|
+
import { homedir as homedir18 } from "node:os";
|
|
23555
23610
|
|
|
23556
23611
|
// ../engine/dist/core/secret-task-status.js
|
|
23557
23612
|
var SECRET_TASK_STATUSES = ["open", "rotated", "not-a-secret", "dismissed"];
|
|
@@ -23619,7 +23674,7 @@ function parseTaskFile(content) {
|
|
|
23619
23674
|
return out;
|
|
23620
23675
|
}
|
|
23621
23676
|
function ledgerPath2() {
|
|
23622
|
-
return join45(
|
|
23677
|
+
return join45(homedir18(), ".chat-recall", "project-tasks-ledger.json");
|
|
23623
23678
|
}
|
|
23624
23679
|
function readLedger() {
|
|
23625
23680
|
try {
|
|
@@ -23630,7 +23685,7 @@ function readLedger() {
|
|
|
23630
23685
|
}
|
|
23631
23686
|
function writeLedger(l) {
|
|
23632
23687
|
try {
|
|
23633
|
-
|
|
23688
|
+
mkdirSync12(dirname21(ledgerPath2()), { recursive: true });
|
|
23634
23689
|
} catch {
|
|
23635
23690
|
}
|
|
23636
23691
|
try {
|
|
@@ -23743,7 +23798,7 @@ function applyCodeRecommendation(intent) {
|
|
|
23743
23798
|
for (const file of targets) {
|
|
23744
23799
|
const dir = file.slice(0, file.lastIndexOf("/"));
|
|
23745
23800
|
try {
|
|
23746
|
-
|
|
23801
|
+
mkdirSync14(dir, { recursive: true });
|
|
23747
23802
|
} catch {
|
|
23748
23803
|
}
|
|
23749
23804
|
const existing = existsSync45(file) ? readFileSync39(file, "utf8") : "";
|
|
@@ -23848,7 +23903,7 @@ try {
|
|
|
23848
23903
|
ownVersion2 = JSON.parse(readFileSync39(join48(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
23849
23904
|
} catch {
|
|
23850
23905
|
try {
|
|
23851
|
-
if (true) ownVersion2 = "0.6.
|
|
23906
|
+
if (true) ownVersion2 = "0.6.6";
|
|
23852
23907
|
} catch {
|
|
23853
23908
|
}
|
|
23854
23909
|
}
|
|
@@ -23913,7 +23968,7 @@ init_auto_update();
|
|
|
23913
23968
|
|
|
23914
23969
|
// src/code-index-cursor.ts
|
|
23915
23970
|
init_paths();
|
|
23916
|
-
import { readFileSync as readFileSync40, writeFileSync as writeFileSync14, mkdirSync as
|
|
23971
|
+
import { readFileSync as readFileSync40, writeFileSync as writeFileSync14, mkdirSync as mkdirSync15 } from "fs";
|
|
23917
23972
|
import { join as join49, dirname as dirname24 } from "path";
|
|
23918
23973
|
var cursorPath = () => join49(getDataDir(), "code-index-cursor.json");
|
|
23919
23974
|
function readCursor() {
|
|
@@ -23933,7 +23988,7 @@ function readCursor() {
|
|
|
23933
23988
|
function writeCursor(c) {
|
|
23934
23989
|
try {
|
|
23935
23990
|
const p = cursorPath();
|
|
23936
|
-
|
|
23991
|
+
mkdirSync15(dirname24(p), { recursive: true });
|
|
23937
23992
|
writeFileSync14(p, JSON.stringify(c));
|
|
23938
23993
|
} catch {
|
|
23939
23994
|
}
|
|
@@ -24196,7 +24251,7 @@ async function runCollectorMigration(opts) {
|
|
|
24196
24251
|
init_sync_ledger();
|
|
24197
24252
|
init_collector_health();
|
|
24198
24253
|
import { existsSync as existsSync49, readFileSync as readFileSync45, statSync as statSync44 } from "fs";
|
|
24199
|
-
var CLI_VERSION3 = true ? "0.6.
|
|
24254
|
+
var CLI_VERSION3 = true ? "0.6.6" : "0.0.0";
|
|
24200
24255
|
var DEBOUNCE_MS = 5e3;
|
|
24201
24256
|
var CLAUDE_DIR = claudeBackend.projectsDir();
|
|
24202
24257
|
var PLANS_DIR = claudeBackend.plansDir();
|
|
@@ -24633,7 +24688,7 @@ var WORKSPACE_MARKERS = [
|
|
|
24633
24688
|
function isCodeWorkspace(p) {
|
|
24634
24689
|
try {
|
|
24635
24690
|
const resolved = resolve2(p);
|
|
24636
|
-
if (resolved === sep4 || resolved ===
|
|
24691
|
+
if (resolved === sep4 || resolved === homedir21() || dirname25(resolved) === resolved) return false;
|
|
24637
24692
|
} catch {
|
|
24638
24693
|
return false;
|
|
24639
24694
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# chat-recall decision guard — fires before a tool call runs.
|
|
3
|
+
#
|
|
4
|
+
# Reads the harness's pre-execution payload on stdin, asks the decision register
|
|
5
|
+
# whether this call reaches for something already ruled out, and prints the
|
|
6
|
+
# answer in that harness's own dialect. Registered as:
|
|
7
|
+
#
|
|
8
|
+
# Claude Code PreToolUse settings.json hooks
|
|
9
|
+
# Codex PreToolUse hooks.json / [hooks] in config.toml
|
|
10
|
+
# Antigravity PreToolUse .agents/hooks.json
|
|
11
|
+
# Cursor beforeShellExecution .cursor/hooks.json
|
|
12
|
+
#
|
|
13
|
+
# OpenCode uses a TypeScript plugin rather than a script; `chat-recall guard`
|
|
14
|
+
# is the same entry point there.
|
|
15
|
+
#
|
|
16
|
+
# ── Silence is the correct failure mode ─────────────────────────────────────
|
|
17
|
+
#
|
|
18
|
+
# Every failure path exits 0 with no output, and this file never blocks. A guard
|
|
19
|
+
# that errors is a guard that stops work it was never asked to judge, and the
|
|
20
|
+
# first time it does that somebody removes it — after which it protects nothing.
|
|
21
|
+
# The binary itself is written the same way.
|
|
22
|
+
#
|
|
23
|
+
# Env:
|
|
24
|
+
# CHAT_RECALL_BIN path to the binary (default: from PATH)
|
|
25
|
+
# CHAT_RECALL_GUARD_HARNESS claude | codex | agy | cursor | opencode
|
|
26
|
+
# CHAT_RECALL_GUARD=0 turn the guard off entirely
|
|
27
|
+
# CHAT_RECALL_GUARD_ENFORCE=1 block instead of warning (opt in; see below)
|
|
28
|
+
|
|
29
|
+
set -uo pipefail
|
|
30
|
+
|
|
31
|
+
# Off by request. Checked first so disabling costs nothing.
|
|
32
|
+
if [[ "${CHAT_RECALL_GUARD:-1}" == "0" ]]; then exit 0; fi
|
|
33
|
+
|
|
34
|
+
# stdin is the payload. Read it even when we are about to bail, or the harness
|
|
35
|
+
# can see a broken pipe on a hook that was only meant to be quiet.
|
|
36
|
+
INPUT="$(cat 2>/dev/null || true)"
|
|
37
|
+
[[ -z "$INPUT" ]] && exit 0
|
|
38
|
+
|
|
39
|
+
BIN="${CHAT_RECALL_BIN:-$(command -v chat-recall 2>/dev/null || true)}"
|
|
40
|
+
if [[ -z "$BIN" ]] || [[ ! -x "$BIN" ]]; then exit 0; fi
|
|
41
|
+
|
|
42
|
+
HARNESS="${CHAT_RECALL_GUARD_HARNESS:-claude}"
|
|
43
|
+
|
|
44
|
+
ARGS=(guard --harness "$HARNESS")
|
|
45
|
+
# Enforcement is opt-in and per machine. The default is a warning on every
|
|
46
|
+
# harness, because a wrong block burns the user's turn while a wrong warning
|
|
47
|
+
# costs a line of context — and only one of those gets the guard uninstalled.
|
|
48
|
+
if [[ "${CHAT_RECALL_GUARD_ENFORCE:-0}" == "1" ]]; then ARGS+=(--enforce); fi
|
|
49
|
+
|
|
50
|
+
# A hard ceiling on top of the binary's own timeout. This runs in front of every
|
|
51
|
+
# tool call, so the worst case has to be bounded by something the harness can
|
|
52
|
+
# rely on rather than by a network.
|
|
53
|
+
printf '%s' "$INPUT" | timeout 8 "$BIN" "${ARGS[@]}" 2>/dev/null || true
|
|
54
|
+
exit 0
|