chat-recall 0.7.3 → 0.7.5
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/auto-update.d.ts +9 -1
- package/dist/auto-update.d.ts.map +1 -1
- package/dist/auto-update.js +20 -3
- package/dist/auto-update.js.map +1 -1
- package/dist/cli.js +185 -75
- package/dist/cli.js.map +1 -1
- package/dist/intent-drain.d.ts.map +1 -1
- package/dist/intent-drain.js +3 -1
- package/dist/intent-drain.js.map +1 -1
- package/dist/mcp-relay.js +1 -1
- package/dist/mcp.js +223 -79
- package/dist/mcp.js.map +1 -1
- package/dist/scan-worker.js +29 -2
- package/dist/sync-client.d.ts +4 -0
- package/dist/sync-client.d.ts.map +1 -1
- package/dist/sync-client.js +45 -1
- package/dist/sync-client.js.map +1 -1
- package/dist/sync-delegate.d.ts +8 -0
- package/dist/sync-delegate.d.ts.map +1 -0
- package/dist/sync-delegate.js +52 -0
- package/dist/sync-delegate.js.map +1 -0
- package/dist/sync-ledger.d.ts +2 -0
- package/dist/sync-ledger.d.ts.map +1 -1
- package/dist/sync-ledger.js +25 -0
- package/dist/sync-ledger.js.map +1 -1
- package/dist/watch.js +178 -68
- package/package.json +1 -1
package/dist/watch.js
CHANGED
|
@@ -6520,7 +6520,7 @@ async function archiveRawSession(store, sessionId) {
|
|
|
6520
6520
|
return await store.putRawSession(sessionId, exp.tool, Math.floor(exp.mtime), gz, size);
|
|
6521
6521
|
}
|
|
6522
6522
|
function detectForkPredecessor(sessionPath) {
|
|
6523
|
-
const { readFileSync: readFileSync46, readdirSync:
|
|
6523
|
+
const { readFileSync: readFileSync46, readdirSync: readdirSync33 } = requireFs();
|
|
6524
6524
|
const { dirname: dirname26, join: join55, basename: basename26 } = requirePath();
|
|
6525
6525
|
let text;
|
|
6526
6526
|
try {
|
|
@@ -6550,7 +6550,7 @@ function detectForkPredecessor(sessionPath) {
|
|
|
6550
6550
|
const self = basename26(sessionPath);
|
|
6551
6551
|
let entries;
|
|
6552
6552
|
try {
|
|
6553
|
-
entries =
|
|
6553
|
+
entries = readdirSync33(dir);
|
|
6554
6554
|
} catch {
|
|
6555
6555
|
return null;
|
|
6556
6556
|
}
|
|
@@ -9404,8 +9404,35 @@ var init_codex2 = __esm({
|
|
|
9404
9404
|
configToml() {
|
|
9405
9405
|
return join12(this.homeDir(), "config.toml");
|
|
9406
9406
|
}
|
|
9407
|
-
|
|
9408
|
-
|
|
9407
|
+
/**
|
|
9408
|
+
* Plugins that are INSTALLED, one folder each:
|
|
9409
|
+
* `plugins/cache/<marketplace>/<plugin>/<version>/`, newest version.
|
|
9410
|
+
*
|
|
9411
|
+
* `.tmp/plugins/plugins/` is Codex's copy of the plugin catalog (62 plugins
|
|
9412
|
+
* and a README on one machine), not what is installed. Reading it reported
|
|
9413
|
+
* every catalog plugin's skills and MCP servers as the user's own, and a
|
|
9414
|
+
* pull then installed them into every tool: build-ios-apps' xcodebuildmcp
|
|
9415
|
+
* reached a Linux PC that never installed the plugin.
|
|
9416
|
+
*/
|
|
9417
|
+
installedPluginDirs() {
|
|
9418
|
+
const cache4 = join12(this.homeDir(), "plugins", "cache");
|
|
9419
|
+
const out = [];
|
|
9420
|
+
const dirs = (p) => {
|
|
9421
|
+
try {
|
|
9422
|
+
return readdirSync8(p, { withFileTypes: true }).filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name);
|
|
9423
|
+
} catch {
|
|
9424
|
+
return [];
|
|
9425
|
+
}
|
|
9426
|
+
};
|
|
9427
|
+
for (const market of dirs(cache4)) {
|
|
9428
|
+
for (const plugin of dirs(join12(cache4, market))) {
|
|
9429
|
+
const versions = dirs(join12(cache4, market, plugin)).sort((a, b) => a.localeCompare(b, void 0, { numeric: true }));
|
|
9430
|
+
const newest = versions[versions.length - 1];
|
|
9431
|
+
if (newest)
|
|
9432
|
+
out.push({ name: plugin, dir: join12(cache4, market, plugin, newest) });
|
|
9433
|
+
}
|
|
9434
|
+
}
|
|
9435
|
+
return out;
|
|
9409
9436
|
}
|
|
9410
9437
|
/** OpenAI-bundled, read-only system skills (imagegen, skill-creator, …). */
|
|
9411
9438
|
skillsSystemDir() {
|
|
@@ -16502,14 +16529,11 @@ var init_skills_source = __esm({
|
|
|
16502
16529
|
}
|
|
16503
16530
|
if (!isSourceEnabled("codex", "skills"))
|
|
16504
16531
|
return;
|
|
16505
|
-
const
|
|
16506
|
-
|
|
16507
|
-
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
continue;
|
|
16511
|
-
yield* this.fromSkillRoot({ path: skillsDir, tool: "codex" }, pluginName);
|
|
16512
|
-
}
|
|
16532
|
+
for (const { name: pluginName, dir } of codexBackend.installedPluginDirs()) {
|
|
16533
|
+
const skillsDir = join33(dir, "skills");
|
|
16534
|
+
if (!existsSync33(skillsDir))
|
|
16535
|
+
continue;
|
|
16536
|
+
yield* this.fromSkillRoot({ path: skillsDir, tool: "codex" }, pluginName);
|
|
16513
16537
|
}
|
|
16514
16538
|
}
|
|
16515
16539
|
async *fromSkillRoot(root, pluginName) {
|
|
@@ -16622,7 +16646,7 @@ var init_skills_source = __esm({
|
|
|
16622
16646
|
});
|
|
16623
16647
|
|
|
16624
16648
|
// ../engine/dist/parsers/mcps-source.js
|
|
16625
|
-
import { existsSync as existsSync34,
|
|
16649
|
+
import { existsSync as existsSync34, readFileSync as readFileSync25, statSync as statSync30 } from "fs";
|
|
16626
16650
|
import { homedir as homedir13 } from "os";
|
|
16627
16651
|
import { join as join34 } from "path";
|
|
16628
16652
|
function readJson(path) {
|
|
@@ -16734,16 +16758,13 @@ var init_mcps_source = __esm({
|
|
|
16734
16758
|
scope: "user"
|
|
16735
16759
|
});
|
|
16736
16760
|
yield* this.fromCodexToml(codexBackend.configToml());
|
|
16737
|
-
const
|
|
16738
|
-
|
|
16739
|
-
|
|
16740
|
-
|
|
16741
|
-
|
|
16742
|
-
|
|
16743
|
-
|
|
16744
|
-
scope: "plugin"
|
|
16745
|
-
});
|
|
16746
|
-
}
|
|
16761
|
+
for (const { dir } of codexBackend.installedPluginDirs()) {
|
|
16762
|
+
const mcpPath = join34(dir, ".mcp.json");
|
|
16763
|
+
yield* this.fromObject(readJson(mcpPath)?.mcpServers, {
|
|
16764
|
+
tool: "codex",
|
|
16765
|
+
filePath: mcpPath,
|
|
16766
|
+
scope: "plugin"
|
|
16767
|
+
});
|
|
16747
16768
|
}
|
|
16748
16769
|
}
|
|
16749
16770
|
async *fromObject(obj, ctx) {
|
|
@@ -16781,7 +16802,12 @@ var init_mcps_source = __esm({
|
|
|
16781
16802
|
// MCP's url into a shell string, and `alwaysAllow` is truncated to
|
|
16782
16803
|
// 8 for the preview — rebuilding from either produces a broken or
|
|
16783
16804
|
// half-permissioned server, silently.
|
|
16784
|
-
spec
|
|
16805
|
+
spec,
|
|
16806
|
+
// Where this registration runs. A server that starts through npx
|
|
16807
|
+
// passes the command check on any machine, so this is what tells a
|
|
16808
|
+
// pull that it came from another platform (see toolkit-pull.ts).
|
|
16809
|
+
platform: process.platform,
|
|
16810
|
+
arch: process.arch
|
|
16785
16811
|
}
|
|
16786
16812
|
};
|
|
16787
16813
|
}
|
|
@@ -16960,7 +16986,7 @@ var init_toolkit_format = __esm({
|
|
|
16960
16986
|
});
|
|
16961
16987
|
|
|
16962
16988
|
// ../engine/dist/parsers/slash-commands-source.js
|
|
16963
|
-
import { existsSync as existsSync35, readdirSync as
|
|
16989
|
+
import { existsSync as existsSync35, readdirSync as readdirSync26, readFileSync as readFileSync26, statSync as statSync31 } from "fs";
|
|
16964
16990
|
import { join as join35, basename as basename18 } from "path";
|
|
16965
16991
|
function rebuildBody2(content) {
|
|
16966
16992
|
const { text, redacted } = redactInlineSecrets(content);
|
|
@@ -17015,7 +17041,7 @@ var init_slash_commands_source = __esm({
|
|
|
17015
17041
|
const projectsRoot = claudeBackend.projectsDir();
|
|
17016
17042
|
if (existsSync35(projectsRoot)) {
|
|
17017
17043
|
try {
|
|
17018
|
-
for (const entry of
|
|
17044
|
+
for (const entry of readdirSync26(projectsRoot, { withFileTypes: true })) {
|
|
17019
17045
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
17020
17046
|
continue;
|
|
17021
17047
|
const projectPath = resolveProjectDirName(entry.name);
|
|
@@ -17047,7 +17073,7 @@ var init_slash_commands_source = __esm({
|
|
|
17047
17073
|
const ext = root.format === "toml" ? ".toml" : ".md";
|
|
17048
17074
|
let files;
|
|
17049
17075
|
try {
|
|
17050
|
-
files =
|
|
17076
|
+
files = readdirSync26(root.path).filter((f) => f.endsWith(ext));
|
|
17051
17077
|
} catch {
|
|
17052
17078
|
continue;
|
|
17053
17079
|
}
|
|
@@ -17107,7 +17133,7 @@ var init_slash_commands_source = __esm({
|
|
|
17107
17133
|
});
|
|
17108
17134
|
|
|
17109
17135
|
// ../engine/dist/parsers/subagents-source.js
|
|
17110
|
-
import { existsSync as existsSync36, readdirSync as
|
|
17136
|
+
import { existsSync as existsSync36, readdirSync as readdirSync27, readFileSync as readFileSync27, statSync as statSync32 } from "fs";
|
|
17111
17137
|
import { join as join36, basename as basename19 } from "path";
|
|
17112
17138
|
function rebuildBody3(content) {
|
|
17113
17139
|
const { text, redacted } = redactInlineSecrets(content);
|
|
@@ -17164,7 +17190,7 @@ var init_subagents_source = __esm({
|
|
|
17164
17190
|
const projectsRoot = claudeBackend.projectsDir();
|
|
17165
17191
|
if (existsSync36(projectsRoot)) {
|
|
17166
17192
|
try {
|
|
17167
|
-
for (const entry of
|
|
17193
|
+
for (const entry of readdirSync27(projectsRoot, { withFileTypes: true })) {
|
|
17168
17194
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
17169
17195
|
continue;
|
|
17170
17196
|
const projectPath = resolveProjectDirName(entry.name);
|
|
@@ -17196,7 +17222,7 @@ var init_subagents_source = __esm({
|
|
|
17196
17222
|
const ext = root.format === "toml" ? ".toml" : ".md";
|
|
17197
17223
|
let files;
|
|
17198
17224
|
try {
|
|
17199
|
-
files =
|
|
17225
|
+
files = readdirSync27(root.path).filter((f) => f.endsWith(ext));
|
|
17200
17226
|
} catch {
|
|
17201
17227
|
continue;
|
|
17202
17228
|
}
|
|
@@ -17257,7 +17283,7 @@ var init_subagents_source = __esm({
|
|
|
17257
17283
|
});
|
|
17258
17284
|
|
|
17259
17285
|
// ../engine/dist/parsers/hooks-source.js
|
|
17260
|
-
import { existsSync as existsSync37, readFileSync as readFileSync28, readdirSync as
|
|
17286
|
+
import { existsSync as existsSync37, readFileSync as readFileSync28, readdirSync as readdirSync28, statSync as statSync33 } from "fs";
|
|
17261
17287
|
import { join as join37 } from "path";
|
|
17262
17288
|
function readJson2(path) {
|
|
17263
17289
|
if (!existsSync37(path))
|
|
@@ -17284,7 +17310,7 @@ var init_hooks_source = __esm({
|
|
|
17284
17310
|
const projectsRoot = claudeBackend.projectsDir();
|
|
17285
17311
|
if (existsSync37(projectsRoot)) {
|
|
17286
17312
|
try {
|
|
17287
|
-
for (const entry of
|
|
17313
|
+
for (const entry of readdirSync28(projectsRoot, { withFileTypes: true })) {
|
|
17288
17314
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
17289
17315
|
continue;
|
|
17290
17316
|
const projectPath = resolveProjectDirName(entry.name);
|
|
@@ -17380,7 +17406,7 @@ var init_hooks_source = __esm({
|
|
|
17380
17406
|
});
|
|
17381
17407
|
|
|
17382
17408
|
// ../engine/dist/parsers/plugins-source.js
|
|
17383
|
-
import { existsSync as existsSync38, readFileSync as readFileSync29, readdirSync as
|
|
17409
|
+
import { existsSync as existsSync38, readFileSync as readFileSync29, readdirSync as readdirSync29, statSync as statSync34 } from "fs";
|
|
17384
17410
|
import { homedir as homedir14 } from "os";
|
|
17385
17411
|
import { join as join38 } from "path";
|
|
17386
17412
|
function readJson3(path) {
|
|
@@ -17442,7 +17468,7 @@ var init_plugins_source = __esm({
|
|
|
17442
17468
|
if (isSourceEnabled("agy", "extensions") && existsSync38(gemRoot)) {
|
|
17443
17469
|
let entries;
|
|
17444
17470
|
try {
|
|
17445
|
-
entries =
|
|
17471
|
+
entries = readdirSync29(gemRoot);
|
|
17446
17472
|
} catch {
|
|
17447
17473
|
entries = [];
|
|
17448
17474
|
}
|
|
@@ -17486,16 +17512,8 @@ var init_plugins_source = __esm({
|
|
|
17486
17512
|
};
|
|
17487
17513
|
}
|
|
17488
17514
|
}
|
|
17489
|
-
|
|
17490
|
-
|
|
17491
|
-
let entries;
|
|
17492
|
-
try {
|
|
17493
|
-
entries = readdirSync30(codexPluginsRoot);
|
|
17494
|
-
} catch {
|
|
17495
|
-
entries = [];
|
|
17496
|
-
}
|
|
17497
|
-
for (const name of entries) {
|
|
17498
|
-
const pluginDir = join38(codexPluginsRoot, name);
|
|
17515
|
+
if (isSourceEnabled("codex", "plugins")) {
|
|
17516
|
+
for (const { name, dir: pluginDir } of codexBackend.installedPluginDirs()) {
|
|
17499
17517
|
let st;
|
|
17500
17518
|
try {
|
|
17501
17519
|
st = statSync34(pluginDir);
|
|
@@ -17609,7 +17627,8 @@ var init_all_sources = __esm({
|
|
|
17609
17627
|
|
|
17610
17628
|
// ../engine/dist/core/extractor-version.js
|
|
17611
17629
|
function extractorVersionForItem(id, sourceType) {
|
|
17612
|
-
|
|
17630
|
+
const tool = toolOfId(id);
|
|
17631
|
+
return extractorVersionForTool(tool) + (ITEM_SOURCE_BUMP[sourceType] ?? 0) + (ITEM_TOOL_SOURCE_BUMP[`${tool}:${sourceType}`] ?? 0);
|
|
17613
17632
|
}
|
|
17614
17633
|
function toolOfId(id) {
|
|
17615
17634
|
if (id.startsWith("agy_"))
|
|
@@ -17630,17 +17649,21 @@ function extractorVersionForTool(tool) {
|
|
|
17630
17649
|
function extractorVersionForId(id) {
|
|
17631
17650
|
return extractorVersionForTool(toolOfId(id));
|
|
17632
17651
|
}
|
|
17633
|
-
var BASE_EXTRACTOR_VERSION, ITEM_SOURCE_BUMP, TOOL_EXTRACTOR_BUMP, EXTRACTOR_VERSION;
|
|
17652
|
+
var BASE_EXTRACTOR_VERSION, ITEM_SOURCE_BUMP, ITEM_TOOL_SOURCE_BUMP, TOOL_EXTRACTOR_BUMP, EXTRACTOR_VERSION;
|
|
17634
17653
|
var init_extractor_version = __esm({
|
|
17635
17654
|
"../engine/dist/core/extractor-version.js"() {
|
|
17636
17655
|
"use strict";
|
|
17637
17656
|
BASE_EXTRACTOR_VERSION = 2;
|
|
17638
17657
|
ITEM_SOURCE_BUMP = {
|
|
17639
|
-
mcp:
|
|
17658
|
+
mcp: 2,
|
|
17640
17659
|
skill: 1,
|
|
17641
17660
|
agent: 1,
|
|
17642
17661
|
command: 1
|
|
17643
17662
|
};
|
|
17663
|
+
ITEM_TOOL_SOURCE_BUMP = {
|
|
17664
|
+
"codex:skill": 1,
|
|
17665
|
+
"codex:plugin": 1
|
|
17666
|
+
};
|
|
17644
17667
|
TOOL_EXTRACTOR_BUMP = {
|
|
17645
17668
|
agy: 3,
|
|
17646
17669
|
claude: 1,
|
|
@@ -17663,6 +17686,7 @@ __export(sync_ledger_exports, {
|
|
|
17663
17686
|
getSyncedMtimes: () => getSyncedMtimes,
|
|
17664
17687
|
getSyncedRows: () => getSyncedRows,
|
|
17665
17688
|
ledgerFilePath: () => ledgerFilePath,
|
|
17689
|
+
loadInventoryHashes: () => loadInventoryHashes,
|
|
17666
17690
|
loadItemVersions: () => loadItemVersions,
|
|
17667
17691
|
markFieldCoverage: () => markFieldCoverage,
|
|
17668
17692
|
markFieldFullPassDone: () => markFieldFullPassDone,
|
|
@@ -17670,6 +17694,7 @@ __export(sync_ledger_exports, {
|
|
|
17670
17694
|
markSynced: () => markSynced,
|
|
17671
17695
|
persistLedgerData: () => persistLedgerData,
|
|
17672
17696
|
pruneLedgerTargets: () => pruneLedgerTargets,
|
|
17697
|
+
saveInventoryHashes: () => saveInventoryHashes,
|
|
17673
17698
|
saveItemVersions: () => saveItemVersions,
|
|
17674
17699
|
syncMode: () => syncMode,
|
|
17675
17700
|
unackedCursorAttemptCount: () => unackedCursorAttemptCount
|
|
@@ -17775,6 +17800,28 @@ function saveItemVersions(server, versions) {
|
|
|
17775
17800
|
writeFileSync6(tmp, JSON.stringify(all));
|
|
17776
17801
|
renameSync4(tmp, path);
|
|
17777
17802
|
}
|
|
17803
|
+
function loadInventoryHashes(server) {
|
|
17804
|
+
try {
|
|
17805
|
+
const parsed = JSON.parse(readFileSync30(inventoryPath(), "utf-8"));
|
|
17806
|
+
return { ...(parsed && typeof parsed === "object" ? parsed[server] : null) || {} };
|
|
17807
|
+
} catch {
|
|
17808
|
+
return {};
|
|
17809
|
+
}
|
|
17810
|
+
}
|
|
17811
|
+
function saveInventoryHashes(server, hashes) {
|
|
17812
|
+
let all = {};
|
|
17813
|
+
try {
|
|
17814
|
+
all = JSON.parse(readFileSync30(inventoryPath(), "utf-8"));
|
|
17815
|
+
} catch {
|
|
17816
|
+
}
|
|
17817
|
+
if (!all || typeof all !== "object") all = {};
|
|
17818
|
+
all[server] = { ...all[server] || {}, ...hashes };
|
|
17819
|
+
const path = inventoryPath();
|
|
17820
|
+
mkdirSync7(dirname16(path), { recursive: true });
|
|
17821
|
+
const tmp = `${path}.tmp`;
|
|
17822
|
+
writeFileSync6(tmp, JSON.stringify(all));
|
|
17823
|
+
renameSync4(tmp, path);
|
|
17824
|
+
}
|
|
17778
17825
|
function getSyncedMtimes(server) {
|
|
17779
17826
|
const data = load();
|
|
17780
17827
|
const out = /* @__PURE__ */ new Map();
|
|
@@ -17913,7 +17960,7 @@ function syncMode(row, mtime, fileSize, extractorVersion, isAppendOnly) {
|
|
|
17913
17960
|
if (row.m >= Math.floor(mtime)) return "skip";
|
|
17914
17961
|
return "full";
|
|
17915
17962
|
}
|
|
17916
|
-
var ledgerPath, cache3, LEDGER_FLUSH_MS, pendingWrite, flushTimer, itemVersionsPath, itemVersionsCache, unackedCursorAttempts, reconcilePath, reconcileCache;
|
|
17963
|
+
var ledgerPath, cache3, LEDGER_FLUSH_MS, pendingWrite, flushTimer, itemVersionsPath, itemVersionsCache, inventoryPath, unackedCursorAttempts, reconcilePath, reconcileCache;
|
|
17917
17964
|
var init_sync_ledger = __esm({
|
|
17918
17965
|
"src/sync-ledger.ts"() {
|
|
17919
17966
|
"use strict";
|
|
@@ -17926,6 +17973,7 @@ var init_sync_ledger = __esm({
|
|
|
17926
17973
|
flushTimer = null;
|
|
17927
17974
|
itemVersionsPath = () => join39(getDataDir(), "item-versions.json");
|
|
17928
17975
|
itemVersionsCache = null;
|
|
17976
|
+
inventoryPath = () => join39(getDataDir(), "toolkit-inventory.json");
|
|
17929
17977
|
unackedCursorAttempts = 0;
|
|
17930
17978
|
reconcilePath = () => join39(getDataDir(), "sync-field-reconcile.json");
|
|
17931
17979
|
reconcileCache = null;
|
|
@@ -18071,7 +18119,7 @@ var init_http = __esm({
|
|
|
18071
18119
|
CLI_VERSION = JSON.parse(readFileSync32(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
18072
18120
|
} catch {
|
|
18073
18121
|
try {
|
|
18074
|
-
if (true) CLI_VERSION = "0.7.
|
|
18122
|
+
if (true) CLI_VERSION = "0.7.5";
|
|
18075
18123
|
} catch {
|
|
18076
18124
|
}
|
|
18077
18125
|
}
|
|
@@ -18566,7 +18614,7 @@ var init_telemetry = __esm({
|
|
|
18566
18614
|
init_sync_client();
|
|
18567
18615
|
cliVersion = () => {
|
|
18568
18616
|
try {
|
|
18569
|
-
return true ? "0.7.
|
|
18617
|
+
return true ? "0.7.5" : "dev";
|
|
18570
18618
|
} catch {
|
|
18571
18619
|
return "dev";
|
|
18572
18620
|
}
|
|
@@ -18800,7 +18848,7 @@ __export(auto_update_exports, {
|
|
|
18800
18848
|
import { execSync as execSync2, execFileSync as execFileSync3 } from "node:child_process";
|
|
18801
18849
|
import { readFileSync as readFileSync34, existsSync as existsSync41 } from "node:fs";
|
|
18802
18850
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
18803
|
-
import { writeFileSync as writeFileSync8, mkdtempSync as mkdtempSync3, rmSync as rmSync5, readdirSync as
|
|
18851
|
+
import { writeFileSync as writeFileSync8, mkdtempSync as mkdtempSync3, rmSync as rmSync5, readdirSync as readdirSync30, statSync as statSync36, mkdirSync as mkdirSync9 } from "node:fs";
|
|
18804
18852
|
import { join as join41, dirname as dirname18, sep as sep2, posix as pathPosix, win32 as pathWin32 } from "node:path";
|
|
18805
18853
|
import { tmpdir as tmpdir2, homedir as homedir15 } from "node:os";
|
|
18806
18854
|
import { createHash as createHash7 } from "node:crypto";
|
|
@@ -18837,7 +18885,7 @@ function planAutoUpdate(base2, caps, ownVersion3, flag) {
|
|
|
18837
18885
|
if (!rel || !rel.version || !rel.sha256) return { update: false, reason: "server advertises no CLI release" };
|
|
18838
18886
|
if (!isAutoUpdateEnabled(caps.edition, flag)) return { update: false, reason: `auto-update disabled (edition ${caps.edition ?? "?"})` };
|
|
18839
18887
|
if (compareVersions(rel.version, ownVersion3) <= 0) return { update: false, reason: `already current (own ${ownVersion3} >= server ${rel.version})` };
|
|
18840
|
-
return { update: true, reason: `server ${rel.version} > own ${ownVersion3}`, url: tarballUrl(base2), sha256: rel.sha256, from: ownVersion3, to: rel.version };
|
|
18888
|
+
return { update: true, reason: `server ${rel.version} > own ${ownVersion3}`, url: tarballUrl(base2, rel.version), fallbackUrl: tarballUrl(base2), sha256: rel.sha256, from: ownVersion3, to: rel.version };
|
|
18841
18889
|
}
|
|
18842
18890
|
function sweepStaleStaging(root = tmpdir2(), now = Date.now()) {
|
|
18843
18891
|
const MKDTEMP_SUFFIX = /^cr-update-.{6}$/s;
|
|
@@ -18845,7 +18893,7 @@ function sweepStaleStaging(root = tmpdir2(), now = Date.now()) {
|
|
|
18845
18893
|
let removed = 0;
|
|
18846
18894
|
let entries;
|
|
18847
18895
|
try {
|
|
18848
|
-
entries =
|
|
18896
|
+
entries = readdirSync30(root);
|
|
18849
18897
|
} catch {
|
|
18850
18898
|
return 0;
|
|
18851
18899
|
}
|
|
@@ -18855,7 +18903,7 @@ function sweepStaleStaging(root = tmpdir2(), now = Date.now()) {
|
|
|
18855
18903
|
try {
|
|
18856
18904
|
const st = statSync36(dir);
|
|
18857
18905
|
if (!st.isDirectory() || now - st.mtimeMs < COLD_MS) continue;
|
|
18858
|
-
const inside =
|
|
18906
|
+
const inside = readdirSync30(dir);
|
|
18859
18907
|
if (inside.length > 1 || inside.length === 1 && inside[0] !== "chat-recall.tgz") continue;
|
|
18860
18908
|
rmSync5(dir, { recursive: true, force: true });
|
|
18861
18909
|
removed++;
|
|
@@ -18870,7 +18918,13 @@ async function executeAutoUpdate(plan, deps) {
|
|
|
18870
18918
|
try {
|
|
18871
18919
|
buf = await deps.download(plan.url);
|
|
18872
18920
|
} catch (e) {
|
|
18873
|
-
|
|
18921
|
+
const notFound = e instanceof Error && e.message === "HTTP 404";
|
|
18922
|
+
if (!notFound || !plan.fallbackUrl) return { updated: false, reason: `download failed: ${e instanceof Error ? e.message : e}` };
|
|
18923
|
+
try {
|
|
18924
|
+
buf = await deps.download(plan.fallbackUrl);
|
|
18925
|
+
} catch (e2) {
|
|
18926
|
+
return { updated: false, reason: `download failed: ${e2 instanceof Error ? e2.message : e2}` };
|
|
18927
|
+
}
|
|
18874
18928
|
}
|
|
18875
18929
|
const got = createHash7("sha256").update(buf).digest("hex");
|
|
18876
18930
|
if (got !== plan.sha256) return { updated: false, reason: `checksum mismatch (expected ${plan.sha256.slice(0, 12)}\u2026, got ${got.slice(0, 12)}\u2026) \u2014 NOT installing` };
|
|
@@ -19046,7 +19100,7 @@ var init_auto_update = __esm({
|
|
|
19046
19100
|
"src/auto-update.ts"() {
|
|
19047
19101
|
"use strict";
|
|
19048
19102
|
init_http();
|
|
19049
|
-
tarballUrl = (base2) => `${base2.replace(/\/+$/, "")}/install
|
|
19103
|
+
tarballUrl = (base2, version) => `${base2.replace(/\/+$/, "")}/install/${version ? `chat-recall-${version}.tgz` : "chat-recall.tgz"}`;
|
|
19050
19104
|
GIVE_UP_AFTER = 3;
|
|
19051
19105
|
reportedStandingSkip = /* @__PURE__ */ new Set();
|
|
19052
19106
|
}
|
|
@@ -19054,7 +19108,7 @@ var init_auto_update = __esm({
|
|
|
19054
19108
|
|
|
19055
19109
|
// src/sync-client.ts
|
|
19056
19110
|
import { join as join42, dirname as dirname19, basename as basename20 } from "node:path";
|
|
19057
|
-
import { readFileSync as readFileSync35, writeFileSync as writeFileSync9, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync4, rmSync as rmSync6, chmodSync as chmodSync3, unlinkSync as unlinkSync2, readdirSync as
|
|
19111
|
+
import { readFileSync as readFileSync35, writeFileSync as writeFileSync9, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync4, rmSync as rmSync6, chmodSync as chmodSync3, unlinkSync as unlinkSync2, readdirSync as readdirSync31, statSync as statSync37 } from "node:fs";
|
|
19058
19112
|
import { tmpdir as tmpdir3, hostname as hostname2 } from "node:os";
|
|
19059
19113
|
import { createHash as createHash8 } from "node:crypto";
|
|
19060
19114
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
@@ -19401,7 +19455,7 @@ function reapStaleScanDirs(dir = tmpdir3(), maxAgeMs = 6 * 36e5, now = Date.now(
|
|
|
19401
19455
|
let reaped = 0;
|
|
19402
19456
|
let names;
|
|
19403
19457
|
try {
|
|
19404
|
-
names =
|
|
19458
|
+
names = readdirSync31(dir);
|
|
19405
19459
|
} catch {
|
|
19406
19460
|
return 0;
|
|
19407
19461
|
}
|
|
@@ -20037,17 +20091,24 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20037
20091
|
const seenTools = /* @__PURE__ */ new Set();
|
|
20038
20092
|
const seenItemKeys = /* @__PURE__ */ new Map();
|
|
20039
20093
|
const registry = buildSourceRegistry();
|
|
20094
|
+
const inventory = /* @__PURE__ */ new Map();
|
|
20095
|
+
const inventoryFailed = /* @__PURE__ */ new Set();
|
|
20040
20096
|
for (const sourceType of registry.getRegisteredTypes()) {
|
|
20041
20097
|
if (sourceType === "session") continue;
|
|
20098
|
+
if (TOOLKIT_INVENTORY_TYPES.has(sourceType)) inventory.set(sourceType, /* @__PURE__ */ new Set());
|
|
20042
20099
|
for (const source of registry.getAll(sourceType)) {
|
|
20043
20100
|
let discovered;
|
|
20044
20101
|
try {
|
|
20045
20102
|
discovered = source.discover();
|
|
20046
20103
|
} catch {
|
|
20104
|
+
inventoryFailed.add(sourceType);
|
|
20047
20105
|
continue;
|
|
20048
20106
|
}
|
|
20049
20107
|
try {
|
|
20050
20108
|
for await (const item of discovered) {
|
|
20109
|
+
if (inventory.has(item.sourceType) && !excluded(item.projectPath || "") && includedProject(item.projectPath || "")) {
|
|
20110
|
+
inventory.get(item.sourceType).add(item.id);
|
|
20111
|
+
}
|
|
20051
20112
|
const itemTool = toolOfId(item.id);
|
|
20052
20113
|
seenTools.add(itemTool);
|
|
20053
20114
|
const itemKey = `${itemTool}:${item.sourceType}`;
|
|
@@ -20105,6 +20166,7 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20105
20166
|
redactions += count.redactions;
|
|
20106
20167
|
}
|
|
20107
20168
|
} catch (err) {
|
|
20169
|
+
inventoryFailed.add(sourceType);
|
|
20108
20170
|
console.error(`[sync] source '${sourceType}' failed mid-walk (its items may be incomplete this run): ${err instanceof Error ? err.message : err}`);
|
|
20109
20171
|
}
|
|
20110
20172
|
}
|
|
@@ -20131,6 +20193,27 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20131
20193
|
await kgTripleBatch.drain();
|
|
20132
20194
|
await findingsBatch.drain();
|
|
20133
20195
|
await drainInflight();
|
|
20196
|
+
{
|
|
20197
|
+
const sentHashes = loadInventoryHashes(base2);
|
|
20198
|
+
const entries = [];
|
|
20199
|
+
const hashes = {};
|
|
20200
|
+
for (const [sourceType, ids] of inventory) {
|
|
20201
|
+
if (inventoryFailed.has(sourceType)) continue;
|
|
20202
|
+
const sorted = [...ids].sort();
|
|
20203
|
+
const hash = createHash8("sha256").update(sorted.join("\n")).digest("hex").slice(0, 32);
|
|
20204
|
+
if (sentHashes[sourceType] === hash) continue;
|
|
20205
|
+
entries.push({ source_type: sourceType, ids: sorted });
|
|
20206
|
+
hashes[sourceType] = hash;
|
|
20207
|
+
}
|
|
20208
|
+
if (entries.length > 0) {
|
|
20209
|
+
try {
|
|
20210
|
+
await post({ inventory: entries });
|
|
20211
|
+
saveInventoryHashes(base2, hashes);
|
|
20212
|
+
} catch (err) {
|
|
20213
|
+
console.error(`[sync] toolkit inventory not sent (it is retried next sync): ${err instanceof Error ? err.message : err}`);
|
|
20214
|
+
}
|
|
20215
|
+
}
|
|
20216
|
+
}
|
|
20134
20217
|
if (seenTools.size > 0) {
|
|
20135
20218
|
try {
|
|
20136
20219
|
const rec = {};
|
|
@@ -20576,7 +20659,7 @@ async function syncIncremental(opts = {}) {
|
|
|
20576
20659
|
lock.release();
|
|
20577
20660
|
}
|
|
20578
20661
|
}
|
|
20579
|
-
var ownVersion, ERROR_CLASS, STANDING_FAILURE, walkProgressForUpload, lastServerPackSpec, credPath, _securityConfigCache, SECURITY_CONFIG_TTL_MS, _syncConfigCache, EMPTY_SYNC_CONFIG, SYNC_RULES_REFUSAL, hashPath, acceptedUploads, MAX_DERIVED_ROW_BYTES, isLocalHost, CAPS_TTL_MS, capsOk, advertisedIngestConc, advertisedGzipBody, FULL_BUILD_MAX_BYTES, DERIVED_MAX_BYTES, SYNC_CHUNK_BYTES, BATCH_SCAN_MAX_BYTES;
|
|
20662
|
+
var ownVersion, ERROR_CLASS, STANDING_FAILURE, walkProgressForUpload, lastServerPackSpec, credPath, _securityConfigCache, SECURITY_CONFIG_TTL_MS, _syncConfigCache, EMPTY_SYNC_CONFIG, SYNC_RULES_REFUSAL, hashPath, acceptedUploads, MAX_DERIVED_ROW_BYTES, isLocalHost, CAPS_TTL_MS, capsOk, advertisedIngestConc, advertisedGzipBody, FULL_BUILD_MAX_BYTES, DERIVED_MAX_BYTES, SYNC_CHUNK_BYTES, TOOLKIT_INVENTORY_TYPES, BATCH_SCAN_MAX_BYTES;
|
|
20580
20663
|
var init_sync_client = __esm({
|
|
20581
20664
|
"src/sync-client.ts"() {
|
|
20582
20665
|
"use strict";
|
|
@@ -20621,7 +20704,7 @@ var init_sync_client = __esm({
|
|
|
20621
20704
|
ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
20622
20705
|
} catch {
|
|
20623
20706
|
try {
|
|
20624
|
-
if (true) ownVersion = "0.7.
|
|
20707
|
+
if (true) ownVersion = "0.7.5";
|
|
20625
20708
|
} catch {
|
|
20626
20709
|
}
|
|
20627
20710
|
}
|
|
@@ -20650,6 +20733,7 @@ var init_sync_client = __esm({
|
|
|
20650
20733
|
FULL_BUILD_MAX_BYTES = Math.max(8, parseInt(process.env.CHAT_RECALL_FULL_BUILD_MAX_MB || "24", 10)) * 1024 * 1024;
|
|
20651
20734
|
DERIVED_MAX_BYTES = Math.max(8, parseInt(process.env.CHAT_RECALL_DERIVED_MAX_MB || "64", 10)) * 1024 * 1024;
|
|
20652
20735
|
SYNC_CHUNK_BYTES = 8 * 1024 * 1024;
|
|
20736
|
+
TOOLKIT_INVENTORY_TYPES = /* @__PURE__ */ new Set(["skill", "mcp", "command", "agent", "plugin"]);
|
|
20653
20737
|
BATCH_SCAN_MAX_BYTES = Math.max(1, parseInt(process.env.CHAT_RECALL_BATCHSCAN_MAX_MB || "64", 10)) * 1024 * 1024;
|
|
20654
20738
|
}
|
|
20655
20739
|
});
|
|
@@ -21284,6 +21368,7 @@ __export(toolkit_pull_exports, {
|
|
|
21284
21368
|
entryFromSpec: () => entryFromSpec,
|
|
21285
21369
|
executePull: () => executePull,
|
|
21286
21370
|
planPull: () => planPull,
|
|
21371
|
+
platformRefusal: () => platformRefusal,
|
|
21287
21372
|
portableCommand: () => portableCommand
|
|
21288
21373
|
});
|
|
21289
21374
|
import { existsSync as existsSync45, mkdirSync as mkdirSync13, statSync as statSync40, writeFileSync as writeFileSync12 } from "node:fs";
|
|
@@ -21341,6 +21426,7 @@ function planPull(rows, opts = {}) {
|
|
|
21341
21426
|
const wanted = opts.types;
|
|
21342
21427
|
const seenUnsupported = /* @__PURE__ */ new Map();
|
|
21343
21428
|
const byName = /* @__PURE__ */ new Map();
|
|
21429
|
+
const platformsByName = /* @__PURE__ */ new Map();
|
|
21344
21430
|
const skillsByName = /* @__PURE__ */ new Map();
|
|
21345
21431
|
const agentsByName = /* @__PURE__ */ new Map();
|
|
21346
21432
|
const commandsByName = /* @__PURE__ */ new Map();
|
|
@@ -21404,6 +21490,9 @@ function planPull(rows, opts = {}) {
|
|
|
21404
21490
|
const name = extra.mcpName || row.title;
|
|
21405
21491
|
if (!name)
|
|
21406
21492
|
continue;
|
|
21493
|
+
if (typeof extra.platform === "string" && extra.platform) {
|
|
21494
|
+
(platformsByName.get(name) ?? platformsByName.set(name, /* @__PURE__ */ new Set()).get(name)).add(extra.platform);
|
|
21495
|
+
}
|
|
21407
21496
|
const spec = extra.spec || null;
|
|
21408
21497
|
if (!spec)
|
|
21409
21498
|
continue;
|
|
@@ -21413,7 +21502,12 @@ function planPull(rows, opts = {}) {
|
|
|
21413
21502
|
byName.set(name, spec);
|
|
21414
21503
|
}
|
|
21415
21504
|
const targets = SUPPORTED_TARGETS.mcp;
|
|
21416
|
-
const mcps = [...byName.entries()].map(([name, spec]) => ({
|
|
21505
|
+
const mcps = [...byName.entries()].map(([name, spec]) => ({
|
|
21506
|
+
name,
|
|
21507
|
+
spec,
|
|
21508
|
+
tools: targets,
|
|
21509
|
+
platforms: [...platformsByName.get(name) ?? []].sort()
|
|
21510
|
+
}));
|
|
21417
21511
|
const skills = [...skillsByName.entries()].map(([name, v]) => ({
|
|
21418
21512
|
name,
|
|
21419
21513
|
body: v.body,
|
|
@@ -21432,7 +21526,18 @@ function planPull(rows, opts = {}) {
|
|
|
21432
21526
|
];
|
|
21433
21527
|
return { mcps, skills, codecs, unsupported };
|
|
21434
21528
|
}
|
|
21529
|
+
function platformRefusal(name, platforms, here, explicit) {
|
|
21530
|
+
if (explicit.has(name) || platforms.includes(here))
|
|
21531
|
+
return null;
|
|
21532
|
+
const hint = `install it by name if it works on ${here}: chat-recall toolkit pull --mcp ${name}`;
|
|
21533
|
+
if (platforms.length === 0) {
|
|
21534
|
+
return `no device recorded its platform \u2014 re-sync from the device that has it, or ${hint}`;
|
|
21535
|
+
}
|
|
21536
|
+
return `registered only on ${platforms.join(", ")} \u2014 ${hint}`;
|
|
21537
|
+
}
|
|
21435
21538
|
function executePull(rows, opts = {}) {
|
|
21539
|
+
const here = opts.platform ?? process.platform;
|
|
21540
|
+
const explicit = new Set(opts.explicit ?? []);
|
|
21436
21541
|
const { mcps, skills, codecs, unsupported } = planPull(rows, opts);
|
|
21437
21542
|
const outcomes = [];
|
|
21438
21543
|
for (const { name, body, truncated, redacted, tools } of skills) {
|
|
@@ -21501,8 +21606,9 @@ function executePull(rows, opts = {}) {
|
|
|
21501
21606
|
}
|
|
21502
21607
|
}
|
|
21503
21608
|
}
|
|
21504
|
-
for (const { name, spec, tools } of mcps) {
|
|
21609
|
+
for (const { name, spec, tools, platforms } of mcps) {
|
|
21505
21610
|
const built = entryFromSpec(spec);
|
|
21611
|
+
const refusal = platformRefusal(name, platforms, here, explicit);
|
|
21506
21612
|
for (const tool of tools) {
|
|
21507
21613
|
if (!built) {
|
|
21508
21614
|
outcomes.push({ type: "mcp", name, tool, status: "skipped", reason: "stored row has no rebuildable spec (re-index on the source device)" });
|
|
@@ -21512,6 +21618,10 @@ function executePull(rows, opts = {}) {
|
|
|
21512
21618
|
outcomes.push({ type: "mcp", name, tool, status: "present" });
|
|
21513
21619
|
continue;
|
|
21514
21620
|
}
|
|
21621
|
+
if (refusal) {
|
|
21622
|
+
outcomes.push({ type: "mcp", name, tool, status: "skipped", reason: refusal });
|
|
21623
|
+
continue;
|
|
21624
|
+
}
|
|
21515
21625
|
if (spec.secretsRedacted) {
|
|
21516
21626
|
outcomes.push({
|
|
21517
21627
|
type: "mcp",
|
|
@@ -21798,14 +21908,14 @@ __export(shadow_prune_exports, {
|
|
|
21798
21908
|
DEFAULT_MAX_TOTAL_BYTES: () => DEFAULT_MAX_TOTAL_BYTES,
|
|
21799
21909
|
pruneShadow: () => pruneShadow
|
|
21800
21910
|
});
|
|
21801
|
-
import { readdirSync as
|
|
21911
|
+
import { readdirSync as readdirSync32, statSync as statSync43, unlinkSync as unlinkSync3 } from "fs";
|
|
21802
21912
|
import { join as join50 } from "path";
|
|
21803
21913
|
function listShadows(isFullyAcked) {
|
|
21804
21914
|
const out = [];
|
|
21805
21915
|
const root = shadowRoot();
|
|
21806
21916
|
let tools;
|
|
21807
21917
|
try {
|
|
21808
|
-
tools =
|
|
21918
|
+
tools = readdirSync32(root);
|
|
21809
21919
|
} catch {
|
|
21810
21920
|
return out;
|
|
21811
21921
|
}
|
|
@@ -21813,7 +21923,7 @@ function listShadows(isFullyAcked) {
|
|
|
21813
21923
|
const dir = join50(root, tool);
|
|
21814
21924
|
let names;
|
|
21815
21925
|
try {
|
|
21816
|
-
names =
|
|
21926
|
+
names = readdirSync32(dir);
|
|
21817
21927
|
} catch {
|
|
21818
21928
|
continue;
|
|
21819
21929
|
}
|
|
@@ -23672,7 +23782,7 @@ async function runPull(base2, opts) {
|
|
|
23672
23782
|
return r.title === opts.name;
|
|
23673
23783
|
}
|
|
23674
23784
|
}) : rows;
|
|
23675
|
-
const report = executePull2(filtered, { thisDeviceId: hostname3(), types: wanted });
|
|
23785
|
+
const report = executePull2(filtered, { thisDeviceId: hostname3(), types: wanted, explicit: opts.name ? [opts.name] : void 0 });
|
|
23676
23786
|
const written = report.outcomes.filter((o) => o.status === "written");
|
|
23677
23787
|
const failed = report.outcomes.filter((o) => o.status === "failed");
|
|
23678
23788
|
return {
|
|
@@ -23730,7 +23840,7 @@ try {
|
|
|
23730
23840
|
ownVersion2 = JSON.parse(readFileSync39(join48(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
23731
23841
|
} catch {
|
|
23732
23842
|
try {
|
|
23733
|
-
if (true) ownVersion2 = "0.7.
|
|
23843
|
+
if (true) ownVersion2 = "0.7.5";
|
|
23734
23844
|
} catch {
|
|
23735
23845
|
}
|
|
23736
23846
|
}
|
|
@@ -24115,7 +24225,7 @@ async function runCollectorMigration(opts) {
|
|
|
24115
24225
|
init_sync_ledger();
|
|
24116
24226
|
init_collector_health();
|
|
24117
24227
|
import { existsSync as existsSync50, readFileSync as readFileSync45, statSync as statSync45 } from "fs";
|
|
24118
|
-
var CLI_VERSION3 = true ? "0.7.
|
|
24228
|
+
var CLI_VERSION3 = true ? "0.7.5" : "0.0.0";
|
|
24119
24229
|
var DEBOUNCE_MS = 5e3;
|
|
24120
24230
|
var CLAUDE_DIR = claudeBackend.projectsDir();
|
|
24121
24231
|
var PLANS_DIR = claudeBackend.plansDir();
|