chat-recall 0.5.22 → 0.5.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +347 -197
- package/dist/cli.js.map +1 -1
- package/dist/conformant-server.d.ts +17 -0
- package/dist/conformant-server.d.ts.map +1 -0
- package/dist/conformant-server.js +116 -0
- package/dist/conformant-server.js.map +1 -0
- package/dist/device-auth.d.ts +0 -4
- package/dist/device-auth.d.ts.map +1 -1
- package/dist/device-auth.js +43 -2
- package/dist/device-auth.js.map +1 -1
- package/dist/hostile-server.d.ts +47 -0
- package/dist/hostile-server.d.ts.map +1 -0
- package/dist/hostile-server.js +95 -0
- package/dist/hostile-server.js.map +1 -0
- package/dist/mcp.js +160 -8
- package/dist/server-probe.d.ts +16 -2
- package/dist/server-probe.d.ts.map +1 -1
- package/dist/server-probe.js +59 -4
- package/dist/server-probe.js.map +1 -1
- package/dist/sync-client.d.ts.map +1 -1
- package/dist/sync-client.js +47 -2
- package/dist/sync-client.js.map +1 -1
- package/dist/watch.js +263 -117
- package/package.json +2 -2
package/dist/watch.js
CHANGED
|
@@ -7266,7 +7266,7 @@ async function archiveRawSession(store, sessionId) {
|
|
|
7266
7266
|
}
|
|
7267
7267
|
function detectForkPredecessor(sessionPath) {
|
|
7268
7268
|
const { readFileSync: readFileSync47, readdirSync: readdirSync34 } = requireFs();
|
|
7269
|
-
const { dirname: dirname26, join: join56, basename:
|
|
7269
|
+
const { dirname: dirname26, join: join56, basename: basename28 } = requirePath();
|
|
7270
7270
|
let text;
|
|
7271
7271
|
try {
|
|
7272
7272
|
text = readFileSync47(sessionPath, "utf-8");
|
|
@@ -7292,7 +7292,7 @@ function detectForkPredecessor(sessionPath) {
|
|
|
7292
7292
|
if (text.includes(`"uuid":"${headParent}"`))
|
|
7293
7293
|
return null;
|
|
7294
7294
|
const dir = dirname26(sessionPath);
|
|
7295
|
-
const self =
|
|
7295
|
+
const self = basename28(sessionPath);
|
|
7296
7296
|
let entries;
|
|
7297
7297
|
try {
|
|
7298
7298
|
entries = readdirSync34(dir);
|
|
@@ -7304,7 +7304,7 @@ function detectForkPredecessor(sessionPath) {
|
|
|
7304
7304
|
continue;
|
|
7305
7305
|
try {
|
|
7306
7306
|
if (readFileSync47(join56(dir, f), "utf-8").includes(`"uuid":"${headParent}"`)) {
|
|
7307
|
-
return
|
|
7307
|
+
return basename28(f, ".jsonl");
|
|
7308
7308
|
}
|
|
7309
7309
|
} catch {
|
|
7310
7310
|
}
|
|
@@ -14306,8 +14306,11 @@ function isInside(child, parent) {
|
|
|
14306
14306
|
return c.startsWith(p);
|
|
14307
14307
|
}
|
|
14308
14308
|
function globMatch(pattern, path) {
|
|
14309
|
-
const re = new RegExp("^" + globToRegex(pattern) + "$");
|
|
14310
|
-
return re.test(path);
|
|
14309
|
+
const re = new RegExp("^" + globToRegex(toPosix(pattern)) + "$");
|
|
14310
|
+
return re.test(toPosix(path));
|
|
14311
|
+
}
|
|
14312
|
+
function toPosix(p) {
|
|
14313
|
+
return p.replace(/\\/g, "/");
|
|
14311
14314
|
}
|
|
14312
14315
|
function globToRegex(glob) {
|
|
14313
14316
|
let out = "";
|
|
@@ -19210,7 +19213,7 @@ var init_http = __esm({
|
|
|
19210
19213
|
CLI_VERSION = JSON.parse(readFileSync33(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
19211
19214
|
} catch {
|
|
19212
19215
|
try {
|
|
19213
|
-
if (true) CLI_VERSION = "0.5.
|
|
19216
|
+
if (true) CLI_VERSION = "0.5.24";
|
|
19214
19217
|
} catch {
|
|
19215
19218
|
}
|
|
19216
19219
|
}
|
|
@@ -19718,7 +19721,7 @@ var init_telemetry = __esm({
|
|
|
19718
19721
|
init_sync_client();
|
|
19719
19722
|
cliVersion = () => {
|
|
19720
19723
|
try {
|
|
19721
|
-
return true ? "0.5.
|
|
19724
|
+
return true ? "0.5.24" : "dev";
|
|
19722
19725
|
} catch {
|
|
19723
19726
|
return "dev";
|
|
19724
19727
|
}
|
|
@@ -19782,6 +19785,143 @@ var init_collector_health = __esm({
|
|
|
19782
19785
|
}
|
|
19783
19786
|
});
|
|
19784
19787
|
|
|
19788
|
+
// src/server-probe.ts
|
|
19789
|
+
var server_probe_exports = {};
|
|
19790
|
+
__export(server_probe_exports, {
|
|
19791
|
+
classifyUnreachable: () => classifyUnreachable,
|
|
19792
|
+
describeCause: () => describeCause,
|
|
19793
|
+
describeUnreachable: () => describeUnreachable,
|
|
19794
|
+
probeAdvice: () => probeAdvice,
|
|
19795
|
+
probeOk: () => probeOk,
|
|
19796
|
+
probeServer: () => probeServer
|
|
19797
|
+
});
|
|
19798
|
+
function probeOk(r) {
|
|
19799
|
+
return r.kind === "ok" && r.apiVersion >= 2;
|
|
19800
|
+
}
|
|
19801
|
+
async function probeServer(base2, opts = {}) {
|
|
19802
|
+
const f = opts.fetchImpl || fetch;
|
|
19803
|
+
let res;
|
|
19804
|
+
try {
|
|
19805
|
+
res = await f(`${base2.replace(/\/+$/, "")}/api/capabilities`, {
|
|
19806
|
+
signal: AbortSignal.timeout(opts.timeoutMs ?? 1e4)
|
|
19807
|
+
});
|
|
19808
|
+
} catch (err) {
|
|
19809
|
+
return {
|
|
19810
|
+
kind: "unreachable",
|
|
19811
|
+
error: describeCause(err),
|
|
19812
|
+
reason: classifyUnreachable(err)
|
|
19813
|
+
};
|
|
19814
|
+
}
|
|
19815
|
+
if (res.status === 401 || res.status === 403) return { kind: "unauthorized", status: res.status };
|
|
19816
|
+
if (res.status === 404 || res.status === 410) return { kind: "moved", status: res.status };
|
|
19817
|
+
if (res.status >= 500) return { kind: "server_error", status: res.status };
|
|
19818
|
+
if (!res.ok) return { kind: "moved", status: res.status };
|
|
19819
|
+
let body;
|
|
19820
|
+
try {
|
|
19821
|
+
body = await res.text();
|
|
19822
|
+
} catch (err) {
|
|
19823
|
+
return { kind: "unreachable", error: describeCause(err), reason: classifyUnreachable(err) };
|
|
19824
|
+
}
|
|
19825
|
+
let parsed;
|
|
19826
|
+
try {
|
|
19827
|
+
parsed = JSON.parse(body);
|
|
19828
|
+
} catch {
|
|
19829
|
+
return { kind: "not_api", status: res.status, snippet: body.trim().slice(0, 60) };
|
|
19830
|
+
}
|
|
19831
|
+
if (typeof parsed?.apiVersion !== "number") {
|
|
19832
|
+
return { kind: "not_api", status: res.status, snippet: body.trim().slice(0, 60) };
|
|
19833
|
+
}
|
|
19834
|
+
return {
|
|
19835
|
+
kind: "ok",
|
|
19836
|
+
apiVersion: parsed.apiVersion,
|
|
19837
|
+
edition: parsed.edition,
|
|
19838
|
+
cliVersion: parsed.cli?.version,
|
|
19839
|
+
raw: parsed
|
|
19840
|
+
};
|
|
19841
|
+
}
|
|
19842
|
+
function probeAdvice(r, base2) {
|
|
19843
|
+
switch (r.kind) {
|
|
19844
|
+
case "ok":
|
|
19845
|
+
return r.apiVersion >= 2 ? `apiVersion ${r.apiVersion}${r.edition ? `, edition ${r.edition}` : ""}` : `apiVersion ${r.apiVersion} is too old for this CLI \u2014 upgrade the server`;
|
|
19846
|
+
case "moved":
|
|
19847
|
+
return `HTTP ${r.status} \u2014 nothing is served at ${base2}. If the host moved, re-point it: \`chat-recall login <new-server-url>\``;
|
|
19848
|
+
case "unauthorized":
|
|
19849
|
+
return `HTTP ${r.status} \u2014 ${base2} rejected the credential. Re-login: \`chat-recall login ` + base2 + "`";
|
|
19850
|
+
case "server_error":
|
|
19851
|
+
return `HTTP ${r.status} \u2014 ${base2} is up but failing. Nothing to fix locally; check the server.`;
|
|
19852
|
+
case "not_api":
|
|
19853
|
+
return `${base2} answered ${r.status} with something that is not the chat-recall API (${JSON.stringify(r.snippet)}) \u2014 check the URL, a proxy or a captive portal`;
|
|
19854
|
+
case "unreachable":
|
|
19855
|
+
switch (r.reason) {
|
|
19856
|
+
case "dns":
|
|
19857
|
+
return `cannot resolve the host in ${base2} (${r.error}) \u2014 check the URL for a typo, and your DNS or VPN`;
|
|
19858
|
+
case "refused":
|
|
19859
|
+
return `${base2} resolves but refused the connection (${r.error}) \u2014 the server is not running, or the port is wrong`;
|
|
19860
|
+
case "tls":
|
|
19861
|
+
return `the TLS certificate at ${base2} was rejected (${r.error}) \u2014 expired, self-signed, or issued for another host. A corporate proxy that re-signs traffic does this.`;
|
|
19862
|
+
case "timeout":
|
|
19863
|
+
return `${base2} did not answer in time (${r.error}) \u2014 a firewall or proxy that drops traffic silently looks exactly like this`;
|
|
19864
|
+
case "reset":
|
|
19865
|
+
return `the connection to ${base2} was cut (${r.error}) \u2014 often a proxy or a captive portal`;
|
|
19866
|
+
case "bad_port":
|
|
19867
|
+
return `${base2} names a port that Node and every browser refuse to open (the WHATWG bad-port list) \u2014 use the server's real port`;
|
|
19868
|
+
default:
|
|
19869
|
+
return `no HTTP response from ${base2} (${r.error}) \u2014 check the URL, DNS, or that the server is running`;
|
|
19870
|
+
}
|
|
19871
|
+
}
|
|
19872
|
+
}
|
|
19873
|
+
function classifyUnreachable(err) {
|
|
19874
|
+
if (err instanceof Error && (err.name === "TimeoutError" || err.name === "AbortError")) return "timeout";
|
|
19875
|
+
for (const e of walkErrorChain(err)) {
|
|
19876
|
+
const code = String(e.code ?? "");
|
|
19877
|
+
const msg = String(e.message ?? "");
|
|
19878
|
+
if (code === "ENOTFOUND" || code === "EAI_AGAIN") return "dns";
|
|
19879
|
+
if (code === "ECONNREFUSED") return "refused";
|
|
19880
|
+
if (code === "ECONNRESET" || code === "EPIPE") return "reset";
|
|
19881
|
+
if (code === "ETIMEDOUT" || code === "UND_ERR_CONNECT_TIMEOUT" || code === "UND_ERR_HEADERS_TIMEOUT") return "timeout";
|
|
19882
|
+
if (code.startsWith("CERT_") || code.startsWith("ERR_TLS") || code === "DEPTH_ZERO_SELF_SIGNED_CERT" || code === "SELF_SIGNED_CERT_IN_CHAIN" || code === "UNABLE_TO_VERIFY_LEAF_SIGNATURE" || /certificate/i.test(msg)) return "tls";
|
|
19883
|
+
if (/^bad port$/i.test(msg)) return "bad_port";
|
|
19884
|
+
}
|
|
19885
|
+
return "unknown";
|
|
19886
|
+
}
|
|
19887
|
+
function* walkErrorChain(err, depth = 0) {
|
|
19888
|
+
if (!err || typeof err !== "object" || depth > 5) return;
|
|
19889
|
+
yield err;
|
|
19890
|
+
const members = err.errors;
|
|
19891
|
+
if (Array.isArray(members)) {
|
|
19892
|
+
for (const m of members) yield* walkErrorChain(m, depth + 1);
|
|
19893
|
+
}
|
|
19894
|
+
yield* walkErrorChain(err.cause, depth + 1);
|
|
19895
|
+
}
|
|
19896
|
+
function describeCause(err) {
|
|
19897
|
+
const parts = [];
|
|
19898
|
+
for (const e of walkErrorChain(err)) {
|
|
19899
|
+
const code = e.code;
|
|
19900
|
+
if (typeof code === "string" && code && !parts.includes(code)) parts.push(code);
|
|
19901
|
+
}
|
|
19902
|
+
const base2 = err instanceof Error ? err.message : String(err);
|
|
19903
|
+
return parts.length ? `${base2}: ${parts.join(" \u2192 ")}` : base2;
|
|
19904
|
+
}
|
|
19905
|
+
function describeUnreachable(err) {
|
|
19906
|
+
const reason = classifyUnreachable(err);
|
|
19907
|
+
const detail = describeCause(err);
|
|
19908
|
+
const phrase = {
|
|
19909
|
+
dns: "the host name does not resolve",
|
|
19910
|
+
refused: "the connection was refused \u2014 nothing is listening there",
|
|
19911
|
+
tls: "the TLS certificate was rejected",
|
|
19912
|
+
timeout: "no answer before the timeout",
|
|
19913
|
+
reset: "the connection was cut mid-request",
|
|
19914
|
+
bad_port: "that port is one Node and every browser refuse to open",
|
|
19915
|
+
unknown: "no HTTP response"
|
|
19916
|
+
};
|
|
19917
|
+
return `${phrase[reason]} (${detail})`;
|
|
19918
|
+
}
|
|
19919
|
+
var init_server_probe = __esm({
|
|
19920
|
+
"src/server-probe.ts"() {
|
|
19921
|
+
"use strict";
|
|
19922
|
+
}
|
|
19923
|
+
});
|
|
19924
|
+
|
|
19785
19925
|
// src/client-events.ts
|
|
19786
19926
|
var client_events_exports = {};
|
|
19787
19927
|
__export(client_events_exports, {
|
|
@@ -20143,6 +20283,7 @@ async function fetchTenantSyncConfig(cred) {
|
|
|
20143
20283
|
persistSyncConfig(base2, config);
|
|
20144
20284
|
return config;
|
|
20145
20285
|
} catch (err) {
|
|
20286
|
+
if (isSyncRulesRefusal(err)) throw err;
|
|
20146
20287
|
return lastKnownSyncConfig(base2, err instanceof Error ? err.message : "request failed");
|
|
20147
20288
|
}
|
|
20148
20289
|
}
|
|
@@ -20152,9 +20293,14 @@ function lastKnownSyncConfig(base2, reason) {
|
|
|
20152
20293
|
console.error(`[sync] could not read server-side sync rules (${reason}) \u2014 applying the last known set from ${new Date(remembered.fetchedAt).toISOString()}`);
|
|
20153
20294
|
return remembered.config;
|
|
20154
20295
|
}
|
|
20155
|
-
|
|
20296
|
+
const refusal = new Error(
|
|
20156
20297
|
`Cannot read the server-side sync rules from ${base2} (${reason}), and this machine has never successfully read them. Refusing to sync: uploading without knowing your exclusions could ship a project you told the dashboard to hold back. Fix the server or retry.`
|
|
20157
20298
|
);
|
|
20299
|
+
refusal[SYNC_RULES_REFUSAL] = true;
|
|
20300
|
+
throw refusal;
|
|
20301
|
+
}
|
|
20302
|
+
function isSyncRulesRefusal(err) {
|
|
20303
|
+
return !!err && typeof err === "object" && err[SYNC_RULES_REFUSAL] === true;
|
|
20158
20304
|
}
|
|
20159
20305
|
function deviceLabel() {
|
|
20160
20306
|
try {
|
|
@@ -20378,7 +20524,12 @@ async function verifyServerApi(serverUrl, minApi) {
|
|
|
20378
20524
|
const base2 = serverUrl.replace(/\/$/, "");
|
|
20379
20525
|
const seen = capsOk.get(base2);
|
|
20380
20526
|
if (seen !== void 0 && Date.now() - seen < CAPS_TTL_MS) return true;
|
|
20381
|
-
const
|
|
20527
|
+
const { probeServer: probeServer2, probeAdvice: probeAdvice2 } = await Promise.resolve().then(() => (init_server_probe(), server_probe_exports));
|
|
20528
|
+
const probe = await probeServer2(base2, {
|
|
20529
|
+
fetchImpl: ((url, init) => fetchWithTimeout(String(url), init ?? {}))
|
|
20530
|
+
});
|
|
20531
|
+
if (probe.kind !== "ok") throw new Error(probeAdvice2(probe, base2));
|
|
20532
|
+
const caps = probe.raw;
|
|
20382
20533
|
if ((caps.apiVersion ?? 0) < minApi) {
|
|
20383
20534
|
throw new Error(`server too old: apiVersion ${caps.apiVersion ?? "none"} < required ${minApi} \u2014 update the server image before syncing`);
|
|
20384
20535
|
}
|
|
@@ -21368,7 +21519,7 @@ async function syncIncremental(opts = {}) {
|
|
|
21368
21519
|
lock.release();
|
|
21369
21520
|
}
|
|
21370
21521
|
}
|
|
21371
|
-
var ownVersion, walkProgressForUpload, lastServerPackSpec, credPath, _securityConfigCache, SECURITY_CONFIG_TTL_MS, _syncConfigCache, EMPTY_SYNC_CONFIG, hashPath, MAX_DERIVED_ROW_BYTES, isLocalHost, CAPS_TTL_MS, capsOk, advertisedIngestConc, advertisedGzipBody, FULL_BUILD_MAX_BYTES, FULL_BUILD_TAIL_BYTES, BATCH_SCAN_MAX_BYTES;
|
|
21522
|
+
var ownVersion, walkProgressForUpload, lastServerPackSpec, credPath, _securityConfigCache, SECURITY_CONFIG_TTL_MS, _syncConfigCache, EMPTY_SYNC_CONFIG, SYNC_RULES_REFUSAL, hashPath, MAX_DERIVED_ROW_BYTES, isLocalHost, CAPS_TTL_MS, capsOk, advertisedIngestConc, advertisedGzipBody, FULL_BUILD_MAX_BYTES, FULL_BUILD_TAIL_BYTES, BATCH_SCAN_MAX_BYTES;
|
|
21372
21523
|
var init_sync_client = __esm({
|
|
21373
21524
|
"src/sync-client.ts"() {
|
|
21374
21525
|
"use strict";
|
|
@@ -21414,7 +21565,7 @@ var init_sync_client = __esm({
|
|
|
21414
21565
|
ownVersion = JSON.parse(readFileSync37(join44(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
21415
21566
|
} catch {
|
|
21416
21567
|
try {
|
|
21417
|
-
if (true) ownVersion = "0.5.
|
|
21568
|
+
if (true) ownVersion = "0.5.24";
|
|
21418
21569
|
} catch {
|
|
21419
21570
|
}
|
|
21420
21571
|
}
|
|
@@ -21425,6 +21576,7 @@ var init_sync_client = __esm({
|
|
|
21425
21576
|
SECURITY_CONFIG_TTL_MS = 5 * 60 * 1e3;
|
|
21426
21577
|
_syncConfigCache = /* @__PURE__ */ new Map();
|
|
21427
21578
|
EMPTY_SYNC_CONFIG = { excludeTools: [], excludeProjects: [], excludeSources: [], approveSources: [] };
|
|
21579
|
+
SYNC_RULES_REFUSAL = /* @__PURE__ */ Symbol.for("chat-recall.syncRulesRefusal");
|
|
21428
21580
|
hashPath = (p) => p ? "p_" + createHash12("sha256").update(p).digest("hex").slice(0, 12) : "";
|
|
21429
21581
|
MAX_DERIVED_ROW_BYTES = 2 * 1024 * 1024;
|
|
21430
21582
|
isLocalHost = isPrivateHost;
|
|
@@ -21440,7 +21592,7 @@ var init_sync_client = __esm({
|
|
|
21440
21592
|
|
|
21441
21593
|
// ../engine/dist/core/artifact-codec.js
|
|
21442
21594
|
import { readFileSync as readFileSync38 } from "fs";
|
|
21443
|
-
import { join as join45 } from "path";
|
|
21595
|
+
import { basename as basename23, join as join45 } from "path";
|
|
21444
21596
|
import { homedir as homedir15 } from "os";
|
|
21445
21597
|
function parseCommandText(content, format, fallbackName) {
|
|
21446
21598
|
if (format === "toml") {
|
|
@@ -21568,8 +21720,7 @@ function emit(type, art, toTool, projectPath) {
|
|
|
21568
21720
|
};
|
|
21569
21721
|
}
|
|
21570
21722
|
function base(filePath) {
|
|
21571
|
-
|
|
21572
|
-
return b.replace(/\.(md|toml)$/, "");
|
|
21723
|
+
return basename23(filePath).replace(/\.(md|toml)$/, "");
|
|
21573
21724
|
}
|
|
21574
21725
|
var init_artifact_codec = __esm({
|
|
21575
21726
|
"../engine/dist/core/artifact-codec.js"() {
|
|
@@ -21586,7 +21737,7 @@ var init_artifact_codec = __esm({
|
|
|
21586
21737
|
|
|
21587
21738
|
// ../engine/dist/core/toolkit-sync.js
|
|
21588
21739
|
import { existsSync as existsSync43, mkdirSync as mkdirSync10, readFileSync as readFileSync39, writeFileSync as writeFileSync10, cpSync } from "fs";
|
|
21589
|
-
import { dirname as dirname20, join as join46, basename as
|
|
21740
|
+
import { dirname as dirname20, join as join46, basename as basename24 } from "path";
|
|
21590
21741
|
import { homedir as homedir16 } from "os";
|
|
21591
21742
|
function rowFromMemoryItem(type, item) {
|
|
21592
21743
|
const extra = item.extra || {};
|
|
@@ -21623,7 +21774,7 @@ function copySkill(row, toTool) {
|
|
|
21623
21774
|
const skillDir = row.extra.skillDir || dirname20(row.filePath);
|
|
21624
21775
|
if (!existsSync43(skillDir))
|
|
21625
21776
|
return { ok: false, status: 404, error: `Source dir missing: ${skillDir}` };
|
|
21626
|
-
const name = row.extra.skillName ||
|
|
21777
|
+
const name = row.extra.skillName || basename24(skillDir);
|
|
21627
21778
|
const targetDir = join46(skillsDirFor(toTool), name);
|
|
21628
21779
|
if (existsSync43(targetDir))
|
|
21629
21780
|
return { ok: false, status: 409, error: `Already exists: ${targetDir}` };
|
|
@@ -22012,6 +22163,65 @@ var init_toolkit_sync = __esm({
|
|
|
22012
22163
|
}
|
|
22013
22164
|
});
|
|
22014
22165
|
|
|
22166
|
+
// ../engine/dist/core/which.js
|
|
22167
|
+
import { existsSync as existsSync45, statSync as statSync40, accessSync, constants } from "node:fs";
|
|
22168
|
+
import { join as join48, isAbsolute as isAbsolute2, delimiter as delimiter2, sep as sep2 } from "node:path";
|
|
22169
|
+
function executable(p) {
|
|
22170
|
+
try {
|
|
22171
|
+
if (!statSync40(p).isFile())
|
|
22172
|
+
return false;
|
|
22173
|
+
} catch {
|
|
22174
|
+
return false;
|
|
22175
|
+
}
|
|
22176
|
+
if (isWindows)
|
|
22177
|
+
return true;
|
|
22178
|
+
try {
|
|
22179
|
+
accessSync(p, constants.X_OK);
|
|
22180
|
+
return true;
|
|
22181
|
+
} catch {
|
|
22182
|
+
return false;
|
|
22183
|
+
}
|
|
22184
|
+
}
|
|
22185
|
+
function candidates(name) {
|
|
22186
|
+
if (!isWindows)
|
|
22187
|
+
return [name];
|
|
22188
|
+
const exts = (process.env.PATHEXT || ".COM;.EXE;.BAT;.CMD").split(";").map((e) => e.trim()).filter(Boolean);
|
|
22189
|
+
if (exts.some((e) => name.toLowerCase().endsWith(e.toLowerCase())))
|
|
22190
|
+
return [name];
|
|
22191
|
+
return exts.map((e) => name + e);
|
|
22192
|
+
}
|
|
22193
|
+
function resolveOnPath(name) {
|
|
22194
|
+
if (!name)
|
|
22195
|
+
return null;
|
|
22196
|
+
if (name.includes("/") || isWindows && name.includes(sep2) || isAbsolute2(name)) {
|
|
22197
|
+
for (const c of candidates(name))
|
|
22198
|
+
if (executable(c))
|
|
22199
|
+
return c;
|
|
22200
|
+
return null;
|
|
22201
|
+
}
|
|
22202
|
+
for (const raw of (process.env.PATH || "").split(delimiter2)) {
|
|
22203
|
+
const dir = raw.replace(/^"(.*)"$/, "$1");
|
|
22204
|
+
if (!dir)
|
|
22205
|
+
continue;
|
|
22206
|
+
for (const c of candidates(name)) {
|
|
22207
|
+
const full = join48(dir, c);
|
|
22208
|
+
if (existsSync45(full) && executable(full))
|
|
22209
|
+
return full;
|
|
22210
|
+
}
|
|
22211
|
+
}
|
|
22212
|
+
return null;
|
|
22213
|
+
}
|
|
22214
|
+
function isOnPath(name) {
|
|
22215
|
+
return resolveOnPath(name) !== null;
|
|
22216
|
+
}
|
|
22217
|
+
var isWindows;
|
|
22218
|
+
var init_which = __esm({
|
|
22219
|
+
"../engine/dist/core/which.js"() {
|
|
22220
|
+
"use strict";
|
|
22221
|
+
isWindows = process.platform === "win32";
|
|
22222
|
+
}
|
|
22223
|
+
});
|
|
22224
|
+
|
|
22015
22225
|
// ../engine/dist/core/toolkit-pull.js
|
|
22016
22226
|
var toolkit_pull_exports = {};
|
|
22017
22227
|
__export(toolkit_pull_exports, {
|
|
@@ -22020,31 +22230,25 @@ __export(toolkit_pull_exports, {
|
|
|
22020
22230
|
planPull: () => planPull,
|
|
22021
22231
|
portableCommand: () => portableCommand
|
|
22022
22232
|
});
|
|
22023
|
-
import { existsSync as
|
|
22024
|
-
import {
|
|
22233
|
+
import { existsSync as existsSync46, mkdirSync as mkdirSync12, statSync as statSync41, writeFileSync as writeFileSync12 } from "node:fs";
|
|
22234
|
+
import { dirname as dirname22, join as join49, basename as basename25, isAbsolute as isAbsolute3 } from "node:path";
|
|
22025
22235
|
function isExecutableFile(p) {
|
|
22026
22236
|
try {
|
|
22027
|
-
return
|
|
22237
|
+
return statSync41(p).isFile();
|
|
22028
22238
|
} catch {
|
|
22029
22239
|
return false;
|
|
22030
22240
|
}
|
|
22031
22241
|
}
|
|
22032
22242
|
function onPath(name) {
|
|
22033
|
-
|
|
22034
|
-
for (const d of dirs) {
|
|
22035
|
-
const candidate = join48(d, name);
|
|
22036
|
-
if (isExecutableFile(candidate))
|
|
22037
|
-
return candidate;
|
|
22038
|
-
}
|
|
22039
|
-
return null;
|
|
22243
|
+
return resolveOnPath(name);
|
|
22040
22244
|
}
|
|
22041
22245
|
function portableCommand(cmd) {
|
|
22042
|
-
if (!
|
|
22246
|
+
if (!isAbsolute3(cmd)) {
|
|
22043
22247
|
return onPath(cmd) ? { command: cmd, rewritten: false } : { missing: cmd };
|
|
22044
22248
|
}
|
|
22045
22249
|
if (isExecutableFile(cmd))
|
|
22046
22250
|
return { command: cmd, rewritten: false };
|
|
22047
|
-
const base2 =
|
|
22251
|
+
const base2 = basename25(cmd);
|
|
22048
22252
|
if (onPath(base2))
|
|
22049
22253
|
return { command: base2, rewritten: true };
|
|
22050
22254
|
return { missing: cmd };
|
|
@@ -22177,9 +22381,9 @@ function executePull(rows, opts = {}) {
|
|
|
22177
22381
|
const outcomes = [];
|
|
22178
22382
|
for (const { name, body, truncated, redacted, tools } of skills) {
|
|
22179
22383
|
for (const tool of tools) {
|
|
22180
|
-
const dir =
|
|
22181
|
-
const file =
|
|
22182
|
-
if (
|
|
22384
|
+
const dir = join49(skillsDirFor(tool), name);
|
|
22385
|
+
const file = join49(dir, "SKILL.md");
|
|
22386
|
+
if (existsSync46(file)) {
|
|
22183
22387
|
outcomes.push({ type: "skill", name, tool, status: "present" });
|
|
22184
22388
|
continue;
|
|
22185
22389
|
}
|
|
@@ -22224,7 +22428,7 @@ function executePull(rows, opts = {}) {
|
|
|
22224
22428
|
outcomes.push({ type, name, tool, status: "failed", reason: e instanceof Error ? e.message : "emit failed" });
|
|
22225
22429
|
continue;
|
|
22226
22430
|
}
|
|
22227
|
-
if (
|
|
22431
|
+
if (existsSync46(out.path)) {
|
|
22228
22432
|
outcomes.push({ type, name, tool, status: "present" });
|
|
22229
22433
|
continue;
|
|
22230
22434
|
}
|
|
@@ -22298,6 +22502,7 @@ var NOT_REBUILDABLE;
|
|
|
22298
22502
|
var init_toolkit_pull = __esm({
|
|
22299
22503
|
"../engine/dist/core/toolkit-pull.js"() {
|
|
22300
22504
|
"use strict";
|
|
22505
|
+
init_which();
|
|
22301
22506
|
init_toolkit_sync();
|
|
22302
22507
|
init_artifact_codec();
|
|
22303
22508
|
NOT_REBUILDABLE = {
|
|
@@ -22523,8 +22728,8 @@ __export(shadow_prune_exports, {
|
|
|
22523
22728
|
DEFAULT_MAX_TOTAL_BYTES: () => DEFAULT_MAX_TOTAL_BYTES,
|
|
22524
22729
|
pruneShadow: () => pruneShadow
|
|
22525
22730
|
});
|
|
22526
|
-
import { readdirSync as readdirSync33, statSync as
|
|
22527
|
-
import { join as
|
|
22731
|
+
import { readdirSync as readdirSync33, statSync as statSync43, unlinkSync as unlinkSync3 } from "fs";
|
|
22732
|
+
import { join as join52 } from "path";
|
|
22528
22733
|
function listShadows(isFullyAcked) {
|
|
22529
22734
|
const out = [];
|
|
22530
22735
|
const root = shadowRoot();
|
|
@@ -22535,7 +22740,7 @@ function listShadows(isFullyAcked) {
|
|
|
22535
22740
|
return out;
|
|
22536
22741
|
}
|
|
22537
22742
|
for (const tool of tools) {
|
|
22538
|
-
const dir =
|
|
22743
|
+
const dir = join52(root, tool);
|
|
22539
22744
|
let names;
|
|
22540
22745
|
try {
|
|
22541
22746
|
names = readdirSync33(dir);
|
|
@@ -22545,10 +22750,10 @@ function listShadows(isFullyAcked) {
|
|
|
22545
22750
|
for (const name of names) {
|
|
22546
22751
|
if (!name.endsWith(".gz"))
|
|
22547
22752
|
continue;
|
|
22548
|
-
const path =
|
|
22753
|
+
const path = join52(dir, name);
|
|
22549
22754
|
let st;
|
|
22550
22755
|
try {
|
|
22551
|
-
st =
|
|
22756
|
+
st = statSync43(path);
|
|
22552
22757
|
} catch {
|
|
22553
22758
|
continue;
|
|
22554
22759
|
}
|
|
@@ -22662,65 +22867,6 @@ var init_code_intel = __esm({
|
|
|
22662
22867
|
}
|
|
22663
22868
|
});
|
|
22664
22869
|
|
|
22665
|
-
// ../engine/dist/core/which.js
|
|
22666
|
-
import { existsSync as existsSync48, statSync as statSync43, accessSync, constants } from "node:fs";
|
|
22667
|
-
import { join as join52, isAbsolute as isAbsolute3, delimiter as delimiter3, sep as sep2 } from "node:path";
|
|
22668
|
-
function executable(p) {
|
|
22669
|
-
try {
|
|
22670
|
-
if (!statSync43(p).isFile())
|
|
22671
|
-
return false;
|
|
22672
|
-
} catch {
|
|
22673
|
-
return false;
|
|
22674
|
-
}
|
|
22675
|
-
if (isWindows)
|
|
22676
|
-
return true;
|
|
22677
|
-
try {
|
|
22678
|
-
accessSync(p, constants.X_OK);
|
|
22679
|
-
return true;
|
|
22680
|
-
} catch {
|
|
22681
|
-
return false;
|
|
22682
|
-
}
|
|
22683
|
-
}
|
|
22684
|
-
function candidates(name) {
|
|
22685
|
-
if (!isWindows)
|
|
22686
|
-
return [name];
|
|
22687
|
-
const exts = (process.env.PATHEXT || ".COM;.EXE;.BAT;.CMD").split(";").map((e) => e.trim()).filter(Boolean);
|
|
22688
|
-
if (exts.some((e) => name.toLowerCase().endsWith(e.toLowerCase())))
|
|
22689
|
-
return [name];
|
|
22690
|
-
return exts.map((e) => name + e);
|
|
22691
|
-
}
|
|
22692
|
-
function resolveOnPath(name) {
|
|
22693
|
-
if (!name)
|
|
22694
|
-
return null;
|
|
22695
|
-
if (name.includes("/") || isWindows && name.includes(sep2) || isAbsolute3(name)) {
|
|
22696
|
-
for (const c of candidates(name))
|
|
22697
|
-
if (executable(c))
|
|
22698
|
-
return c;
|
|
22699
|
-
return null;
|
|
22700
|
-
}
|
|
22701
|
-
for (const raw of (process.env.PATH || "").split(delimiter3)) {
|
|
22702
|
-
const dir = raw.replace(/^"(.*)"$/, "$1");
|
|
22703
|
-
if (!dir)
|
|
22704
|
-
continue;
|
|
22705
|
-
for (const c of candidates(name)) {
|
|
22706
|
-
const full = join52(dir, c);
|
|
22707
|
-
if (existsSync48(full) && executable(full))
|
|
22708
|
-
return full;
|
|
22709
|
-
}
|
|
22710
|
-
}
|
|
22711
|
-
return null;
|
|
22712
|
-
}
|
|
22713
|
-
function isOnPath(name) {
|
|
22714
|
-
return resolveOnPath(name) !== null;
|
|
22715
|
-
}
|
|
22716
|
-
var isWindows;
|
|
22717
|
-
var init_which = __esm({
|
|
22718
|
-
"../engine/dist/core/which.js"() {
|
|
22719
|
-
"use strict";
|
|
22720
|
-
isWindows = process.platform === "win32";
|
|
22721
|
-
}
|
|
22722
|
-
});
|
|
22723
|
-
|
|
22724
22870
|
// ../engine/dist/core/companions.js
|
|
22725
22871
|
import { existsSync as existsSync49, mkdirSync as mkdirSync15, statSync as statSync44, chmodSync as chmodSync4, unlinkSync as unlinkSync4, renameSync as renameSync5, createWriteStream, readFileSync as readFileSync44, writeFileSync as writeFileSync15 } from "node:fs";
|
|
22726
22872
|
import { homedir as homedir19 } from "node:os";
|
|
@@ -22986,7 +23132,7 @@ __export(collector_exports, {
|
|
|
22986
23132
|
import { spawn as spawn2 } from "node:child_process";
|
|
22987
23133
|
import { execSync as execSync4 } from "node:child_process";
|
|
22988
23134
|
import { readFileSync as readFileSync45 } from "node:fs";
|
|
22989
|
-
import { join as join54, basename as
|
|
23135
|
+
import { join as join54, basename as basename26 } from "node:path";
|
|
22990
23136
|
async function resolveCodeindexBin(autoInstall = true) {
|
|
22991
23137
|
let st = checkCodeindexStatus();
|
|
22992
23138
|
if (!st.installed && autoInstall)
|
|
@@ -23364,7 +23510,7 @@ async function collectCode(opts) {
|
|
|
23364
23510
|
file,
|
|
23365
23511
|
line: null,
|
|
23366
23512
|
rule: "god_module",
|
|
23367
|
-
title: `God module ${
|
|
23513
|
+
title: `God module ${basename26(file)}`,
|
|
23368
23514
|
snippet: `fan-in ${m.fan_in}, fan-out ${m.fan_out}`,
|
|
23369
23515
|
why: FINDING_WHY.coupling,
|
|
23370
23516
|
agentPrompt: couplingPrompt(file, m.fan_in ?? 0, m.fan_out ?? 0, Math.round((m.instability ?? 0) * 100) / 100)
|
|
@@ -23532,7 +23678,7 @@ async function collectCode(opts) {
|
|
|
23532
23678
|
file,
|
|
23533
23679
|
line: v.line ?? null,
|
|
23534
23680
|
rule: v.violation_type ?? "manifest_violation",
|
|
23535
|
-
title: `${v.violation_type} in ${
|
|
23681
|
+
title: `${v.violation_type} in ${basename26(file)}`,
|
|
23536
23682
|
snippet: v.description ?? "",
|
|
23537
23683
|
why: FINDING_WHY.manifest,
|
|
23538
23684
|
agentPrompt: manifestPrompt(v.violation_type ?? "", file, v.line ?? null, v.description ?? "")
|
|
@@ -23922,15 +24068,15 @@ init_settings();
|
|
|
23922
24068
|
init_sync_client();
|
|
23923
24069
|
init_http();
|
|
23924
24070
|
import chokidar from "chokidar";
|
|
23925
|
-
import { dirname as dirname25, basename as
|
|
24071
|
+
import { dirname as dirname25, basename as basename27, join as join55, resolve as resolve2, sep as sep3 } from "path";
|
|
23926
24072
|
import { homedir as homedir20 } from "os";
|
|
23927
24073
|
|
|
23928
24074
|
// src/intent-drain.ts
|
|
23929
24075
|
init_http();
|
|
23930
24076
|
init_sync_client();
|
|
23931
24077
|
init_toolkit_sync();
|
|
23932
|
-
import { existsSync as
|
|
23933
|
-
import { join as
|
|
24078
|
+
import { existsSync as existsSync47, readFileSync as readFileSync41, writeFileSync as writeFileSync13, appendFileSync, mkdirSync as mkdirSync13 } from "node:fs";
|
|
24079
|
+
import { join as join50 } from "node:path";
|
|
23934
24080
|
import { homedir as homedir18 } from "node:os";
|
|
23935
24081
|
|
|
23936
24082
|
// src/project-tasks.ts
|
|
@@ -24090,7 +24236,7 @@ function applyCodeRecommendation(intent) {
|
|
|
24090
24236
|
const meta = JSON.parse(intent.name || "{}");
|
|
24091
24237
|
if (intent.artifact_type === "write_tasks_file") {
|
|
24092
24238
|
if (!meta.rootPath || !meta.content) return { status: "error", result: JSON.stringify({ error: "missing rootPath or content" }) };
|
|
24093
|
-
const file =
|
|
24239
|
+
const file = join50(meta.rootPath, meta.filename || "CODE_TASKS.md");
|
|
24094
24240
|
writeFileSync13(file, meta.content);
|
|
24095
24241
|
return { status: "done", result: JSON.stringify({ wrote: file }) };
|
|
24096
24242
|
}
|
|
@@ -24100,17 +24246,17 @@ function applyCodeRecommendation(intent) {
|
|
|
24100
24246
|
if (!text) return { status: "error", result: JSON.stringify({ error: "missing text" }) };
|
|
24101
24247
|
let file;
|
|
24102
24248
|
if (isGlobal) {
|
|
24103
|
-
const dir =
|
|
24249
|
+
const dir = join50(homedir18(), ".claude");
|
|
24104
24250
|
try {
|
|
24105
24251
|
mkdirSync13(dir, { recursive: true });
|
|
24106
24252
|
} catch {
|
|
24107
24253
|
}
|
|
24108
|
-
file =
|
|
24254
|
+
file = join50(dir, "CLAUDE.md");
|
|
24109
24255
|
} else {
|
|
24110
24256
|
if (!meta.rootPath) return { status: "error", result: JSON.stringify({ error: "missing rootPath" }) };
|
|
24111
|
-
file =
|
|
24257
|
+
file = join50(meta.rootPath, "CLAUDE.md");
|
|
24112
24258
|
}
|
|
24113
|
-
const existing =
|
|
24259
|
+
const existing = existsSync47(file) ? readFileSync41(file, "utf8") : "";
|
|
24114
24260
|
if (existing.includes(text)) return { status: "done", result: JSON.stringify({ skipped: "rule already present", file }) };
|
|
24115
24261
|
const block = `${existing && !existing.endsWith("\n") ? "\n" : ""}
|
|
24116
24262
|
## Rule (added by chat-recall recommendation)
|
|
@@ -24204,10 +24350,10 @@ async function runIntent(intent, ctx) {
|
|
|
24204
24350
|
var ownVersion2 = "0.0.0";
|
|
24205
24351
|
try {
|
|
24206
24352
|
const dir = dirname23(fileURLToPath4(import.meta.url));
|
|
24207
|
-
ownVersion2 = JSON.parse(readFileSync41(
|
|
24353
|
+
ownVersion2 = JSON.parse(readFileSync41(join50(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
24208
24354
|
} catch {
|
|
24209
24355
|
try {
|
|
24210
|
-
if (true) ownVersion2 = "0.5.
|
|
24356
|
+
if (true) ownVersion2 = "0.5.24";
|
|
24211
24357
|
} catch {
|
|
24212
24358
|
}
|
|
24213
24359
|
}
|
|
@@ -24272,8 +24418,8 @@ init_auto_update();
|
|
|
24272
24418
|
// src/code-index-cursor.ts
|
|
24273
24419
|
init_paths();
|
|
24274
24420
|
import { readFileSync as readFileSync42, writeFileSync as writeFileSync14, mkdirSync as mkdirSync14 } from "fs";
|
|
24275
|
-
import { join as
|
|
24276
|
-
var cursorPath = () =>
|
|
24421
|
+
import { join as join51, dirname as dirname24 } from "path";
|
|
24422
|
+
var cursorPath = () => join51(getDataDir(), "code-index-cursor.json");
|
|
24277
24423
|
function readCursor() {
|
|
24278
24424
|
try {
|
|
24279
24425
|
const raw = JSON.parse(readFileSync42(cursorPath(), "utf-8"));
|
|
@@ -24491,11 +24637,11 @@ function checkSelfRestart(opts) {
|
|
|
24491
24637
|
}
|
|
24492
24638
|
|
|
24493
24639
|
// src/log-rotate.ts
|
|
24494
|
-
import { statSync as
|
|
24640
|
+
import { statSync as statSync42, copyFileSync as copyFileSync3, truncateSync } from "fs";
|
|
24495
24641
|
var LOG_MAX_BYTES = 32 * 1024 * 1024;
|
|
24496
24642
|
function rotateLogIfLarge(logPath, maxBytes = LOG_MAX_BYTES) {
|
|
24497
24643
|
try {
|
|
24498
|
-
const size =
|
|
24644
|
+
const size = statSync42(logPath).size;
|
|
24499
24645
|
if (size < maxBytes) return { rotated: false, sizeBefore: 0 };
|
|
24500
24646
|
copyFileSync3(logPath, `${logPath}.1`);
|
|
24501
24647
|
truncateSync(logPath, 0);
|
|
@@ -24507,8 +24653,8 @@ function rotateLogIfLarge(logPath, maxBytes = LOG_MAX_BYTES) {
|
|
|
24507
24653
|
|
|
24508
24654
|
// src/collector-migrate.ts
|
|
24509
24655
|
init_http();
|
|
24510
|
-
import { existsSync as
|
|
24511
|
-
function selectProjectsToReindex(projects, current, existsFn =
|
|
24656
|
+
import { existsSync as existsSync48 } from "node:fs";
|
|
24657
|
+
function selectProjectsToReindex(projects, current, existsFn = existsSync48) {
|
|
24512
24658
|
const reindex = [];
|
|
24513
24659
|
const missing = [];
|
|
24514
24660
|
for (const p of projects) {
|
|
@@ -24551,7 +24697,7 @@ async function runCollectorMigration(opts) {
|
|
|
24551
24697
|
init_sync_ledger();
|
|
24552
24698
|
init_collector_health();
|
|
24553
24699
|
import { existsSync as existsSync50, readFileSync as readFileSync46 } from "fs";
|
|
24554
|
-
var CLI_VERSION3 = true ? "0.5.
|
|
24700
|
+
var CLI_VERSION3 = true ? "0.5.24" : "0.0.0";
|
|
24555
24701
|
var DEBOUNCE_MS = 5e3;
|
|
24556
24702
|
var CLAUDE_DIR = claudeBackend.projectsDir();
|
|
24557
24703
|
var PLANS_DIR = claudeBackend.plansDir();
|
|
@@ -24652,7 +24798,7 @@ function watchWithFallback(name, pattern, t) {
|
|
|
24652
24798
|
return w;
|
|
24653
24799
|
}
|
|
24654
24800
|
var sessionWatcher = watchWithFallback("sessions", `${CLAUDE_DIR}/**/*.jsonl`, {
|
|
24655
|
-
ignored: (p) => /agent-/.test(p) || /^\./.test(
|
|
24801
|
+
ignored: (p) => /agent-/.test(p) || /^\./.test(basename27(p)),
|
|
24656
24802
|
interval: 5e3
|
|
24657
24803
|
});
|
|
24658
24804
|
var plansWatcher = chokidar.watch(`${PLANS_DIR}/*.md`, {
|