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.
- package/README.md +48 -3
- 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 +1508 -358
- package/dist/cli.js.map +1 -1
- package/dist/mcp-relay.js +1 -1
- package/dist/mcp.js +295 -42
- 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 +117 -61
- package/hooks/chat_recall_guard_hook.sh +54 -0
- package/package.json +1 -1
- package/skills/chat-recall/SKILL.md +2 -1
- package/skills/chat-recall-memory/SKILL.md +18 -2
|
@@ -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,
|
|
13773
|
-
addTriple(projectName || "project", "rejected", r,
|
|
13774
|
-
addTriple(c, "chosen_over", r,
|
|
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),
|
|
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.
|
|
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.
|
|
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
|
-
|
|
19239
|
+
npmInstall(`npm install -g --prefix "${prefix}" "${tgz}"`);
|
|
19226
19240
|
return;
|
|
19227
19241
|
}
|
|
19228
19242
|
try {
|
|
19229
|
-
|
|
19243
|
+
npmInstall(`npm install -g "${tgz}"`);
|
|
19230
19244
|
} catch {
|
|
19231
|
-
|
|
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
|
-
|
|
19269
|
-
|
|
19270
|
-
|
|
19271
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
22068
|
-
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";
|
|
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
|
-
|
|
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(
|
|
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
|
|
23275
|
-
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";
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
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.
|
|
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 ===
|
|
24691
|
+
if (resolved === sep4 || resolved === homedir21() || dirname25(resolved) === resolved) return false;
|
|
24636
24692
|
} catch {
|
|
24637
24693
|
return false;
|
|
24638
24694
|
}
|