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/cli.js
CHANGED
|
@@ -6689,7 +6689,7 @@ async function archiveRawSession(store, sessionId) {
|
|
|
6689
6689
|
return await store.putRawSession(sessionId, exp.tool, Math.floor(exp.mtime), gz, size);
|
|
6690
6690
|
}
|
|
6691
6691
|
function detectForkPredecessor(sessionPath) {
|
|
6692
|
-
const { readFileSync: readFileSync50, readdirSync:
|
|
6692
|
+
const { readFileSync: readFileSync50, readdirSync: readdirSync34 } = requireFs();
|
|
6693
6693
|
const { dirname: dirname30, join: join62, basename: basename28 } = requirePath();
|
|
6694
6694
|
let text;
|
|
6695
6695
|
try {
|
|
@@ -6719,7 +6719,7 @@ function detectForkPredecessor(sessionPath) {
|
|
|
6719
6719
|
const self = basename28(sessionPath);
|
|
6720
6720
|
let entries;
|
|
6721
6721
|
try {
|
|
6722
|
-
entries =
|
|
6722
|
+
entries = readdirSync34(dir);
|
|
6723
6723
|
} catch {
|
|
6724
6724
|
return null;
|
|
6725
6725
|
}
|
|
@@ -8350,8 +8350,35 @@ var init_codex2 = __esm({
|
|
|
8350
8350
|
configToml() {
|
|
8351
8351
|
return join9(this.homeDir(), "config.toml");
|
|
8352
8352
|
}
|
|
8353
|
-
|
|
8354
|
-
|
|
8353
|
+
/**
|
|
8354
|
+
* Plugins that are INSTALLED, one folder each:
|
|
8355
|
+
* `plugins/cache/<marketplace>/<plugin>/<version>/`, newest version.
|
|
8356
|
+
*
|
|
8357
|
+
* `.tmp/plugins/plugins/` is Codex's copy of the plugin catalog (62 plugins
|
|
8358
|
+
* and a README on one machine), not what is installed. Reading it reported
|
|
8359
|
+
* every catalog plugin's skills and MCP servers as the user's own, and a
|
|
8360
|
+
* pull then installed them into every tool: build-ios-apps' xcodebuildmcp
|
|
8361
|
+
* reached a Linux PC that never installed the plugin.
|
|
8362
|
+
*/
|
|
8363
|
+
installedPluginDirs() {
|
|
8364
|
+
const cache4 = join9(this.homeDir(), "plugins", "cache");
|
|
8365
|
+
const out = [];
|
|
8366
|
+
const dirs = (p) => {
|
|
8367
|
+
try {
|
|
8368
|
+
return readdirSync6(p, { withFileTypes: true }).filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name);
|
|
8369
|
+
} catch {
|
|
8370
|
+
return [];
|
|
8371
|
+
}
|
|
8372
|
+
};
|
|
8373
|
+
for (const market of dirs(cache4)) {
|
|
8374
|
+
for (const plugin of dirs(join9(cache4, market))) {
|
|
8375
|
+
const versions = dirs(join9(cache4, market, plugin)).sort((a, b) => a.localeCompare(b, void 0, { numeric: true }));
|
|
8376
|
+
const newest = versions[versions.length - 1];
|
|
8377
|
+
if (newest)
|
|
8378
|
+
out.push({ name: plugin, dir: join9(cache4, market, plugin, newest) });
|
|
8379
|
+
}
|
|
8380
|
+
}
|
|
8381
|
+
return out;
|
|
8355
8382
|
}
|
|
8356
8383
|
/** OpenAI-bundled, read-only system skills (imagegen, skill-creator, …). */
|
|
8357
8384
|
skillsSystemDir() {
|
|
@@ -17013,14 +17040,11 @@ var init_skills_source = __esm({
|
|
|
17013
17040
|
}
|
|
17014
17041
|
if (!isSourceEnabled("codex", "skills"))
|
|
17015
17042
|
return;
|
|
17016
|
-
const
|
|
17017
|
-
|
|
17018
|
-
|
|
17019
|
-
|
|
17020
|
-
|
|
17021
|
-
continue;
|
|
17022
|
-
yield* this.fromSkillRoot({ path: skillsDir, tool: "codex" }, pluginName);
|
|
17023
|
-
}
|
|
17043
|
+
for (const { name: pluginName, dir } of codexBackend.installedPluginDirs()) {
|
|
17044
|
+
const skillsDir = join32(dir, "skills");
|
|
17045
|
+
if (!existsSync33(skillsDir))
|
|
17046
|
+
continue;
|
|
17047
|
+
yield* this.fromSkillRoot({ path: skillsDir, tool: "codex" }, pluginName);
|
|
17024
17048
|
}
|
|
17025
17049
|
}
|
|
17026
17050
|
async *fromSkillRoot(root, pluginName) {
|
|
@@ -17133,7 +17157,7 @@ var init_skills_source = __esm({
|
|
|
17133
17157
|
});
|
|
17134
17158
|
|
|
17135
17159
|
// ../engine/dist/parsers/mcps-source.js
|
|
17136
|
-
import { existsSync as existsSync34,
|
|
17160
|
+
import { existsSync as existsSync34, readFileSync as readFileSync24, statSync as statSync30 } from "fs";
|
|
17137
17161
|
import { homedir as homedir13 } from "os";
|
|
17138
17162
|
import { join as join33 } from "path";
|
|
17139
17163
|
function readJson(path) {
|
|
@@ -17245,16 +17269,13 @@ var init_mcps_source = __esm({
|
|
|
17245
17269
|
scope: "user"
|
|
17246
17270
|
});
|
|
17247
17271
|
yield* this.fromCodexToml(codexBackend.configToml());
|
|
17248
|
-
const
|
|
17249
|
-
|
|
17250
|
-
|
|
17251
|
-
|
|
17252
|
-
|
|
17253
|
-
|
|
17254
|
-
|
|
17255
|
-
scope: "plugin"
|
|
17256
|
-
});
|
|
17257
|
-
}
|
|
17272
|
+
for (const { dir } of codexBackend.installedPluginDirs()) {
|
|
17273
|
+
const mcpPath = join33(dir, ".mcp.json");
|
|
17274
|
+
yield* this.fromObject(readJson(mcpPath)?.mcpServers, {
|
|
17275
|
+
tool: "codex",
|
|
17276
|
+
filePath: mcpPath,
|
|
17277
|
+
scope: "plugin"
|
|
17278
|
+
});
|
|
17258
17279
|
}
|
|
17259
17280
|
}
|
|
17260
17281
|
async *fromObject(obj, ctx) {
|
|
@@ -17292,7 +17313,12 @@ var init_mcps_source = __esm({
|
|
|
17292
17313
|
// MCP's url into a shell string, and `alwaysAllow` is truncated to
|
|
17293
17314
|
// 8 for the preview — rebuilding from either produces a broken or
|
|
17294
17315
|
// half-permissioned server, silently.
|
|
17295
|
-
spec
|
|
17316
|
+
spec,
|
|
17317
|
+
// Where this registration runs. A server that starts through npx
|
|
17318
|
+
// passes the command check on any machine, so this is what tells a
|
|
17319
|
+
// pull that it came from another platform (see toolkit-pull.ts).
|
|
17320
|
+
platform: process.platform,
|
|
17321
|
+
arch: process.arch
|
|
17296
17322
|
}
|
|
17297
17323
|
};
|
|
17298
17324
|
}
|
|
@@ -17471,7 +17497,7 @@ var init_toolkit_format = __esm({
|
|
|
17471
17497
|
});
|
|
17472
17498
|
|
|
17473
17499
|
// ../engine/dist/parsers/slash-commands-source.js
|
|
17474
|
-
import { existsSync as existsSync35, readdirSync as
|
|
17500
|
+
import { existsSync as existsSync35, readdirSync as readdirSync26, readFileSync as readFileSync25, statSync as statSync31 } from "fs";
|
|
17475
17501
|
import { join as join34, basename as basename18 } from "path";
|
|
17476
17502
|
function rebuildBody2(content) {
|
|
17477
17503
|
const { text, redacted } = redactInlineSecrets(content);
|
|
@@ -17526,7 +17552,7 @@ var init_slash_commands_source = __esm({
|
|
|
17526
17552
|
const projectsRoot = claudeBackend.projectsDir();
|
|
17527
17553
|
if (existsSync35(projectsRoot)) {
|
|
17528
17554
|
try {
|
|
17529
|
-
for (const entry of
|
|
17555
|
+
for (const entry of readdirSync26(projectsRoot, { withFileTypes: true })) {
|
|
17530
17556
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
17531
17557
|
continue;
|
|
17532
17558
|
const projectPath = resolveProjectDirName(entry.name);
|
|
@@ -17558,7 +17584,7 @@ var init_slash_commands_source = __esm({
|
|
|
17558
17584
|
const ext = root.format === "toml" ? ".toml" : ".md";
|
|
17559
17585
|
let files;
|
|
17560
17586
|
try {
|
|
17561
|
-
files =
|
|
17587
|
+
files = readdirSync26(root.path).filter((f) => f.endsWith(ext));
|
|
17562
17588
|
} catch {
|
|
17563
17589
|
continue;
|
|
17564
17590
|
}
|
|
@@ -17618,7 +17644,7 @@ var init_slash_commands_source = __esm({
|
|
|
17618
17644
|
});
|
|
17619
17645
|
|
|
17620
17646
|
// ../engine/dist/parsers/subagents-source.js
|
|
17621
|
-
import { existsSync as existsSync36, readdirSync as
|
|
17647
|
+
import { existsSync as existsSync36, readdirSync as readdirSync27, readFileSync as readFileSync26, statSync as statSync32 } from "fs";
|
|
17622
17648
|
import { join as join35, basename as basename19 } from "path";
|
|
17623
17649
|
function rebuildBody3(content) {
|
|
17624
17650
|
const { text, redacted } = redactInlineSecrets(content);
|
|
@@ -17675,7 +17701,7 @@ var init_subagents_source = __esm({
|
|
|
17675
17701
|
const projectsRoot = claudeBackend.projectsDir();
|
|
17676
17702
|
if (existsSync36(projectsRoot)) {
|
|
17677
17703
|
try {
|
|
17678
|
-
for (const entry of
|
|
17704
|
+
for (const entry of readdirSync27(projectsRoot, { withFileTypes: true })) {
|
|
17679
17705
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
17680
17706
|
continue;
|
|
17681
17707
|
const projectPath = resolveProjectDirName(entry.name);
|
|
@@ -17707,7 +17733,7 @@ var init_subagents_source = __esm({
|
|
|
17707
17733
|
const ext = root.format === "toml" ? ".toml" : ".md";
|
|
17708
17734
|
let files;
|
|
17709
17735
|
try {
|
|
17710
|
-
files =
|
|
17736
|
+
files = readdirSync27(root.path).filter((f) => f.endsWith(ext));
|
|
17711
17737
|
} catch {
|
|
17712
17738
|
continue;
|
|
17713
17739
|
}
|
|
@@ -17768,7 +17794,7 @@ var init_subagents_source = __esm({
|
|
|
17768
17794
|
});
|
|
17769
17795
|
|
|
17770
17796
|
// ../engine/dist/parsers/hooks-source.js
|
|
17771
|
-
import { existsSync as existsSync37, readFileSync as readFileSync27, readdirSync as
|
|
17797
|
+
import { existsSync as existsSync37, readFileSync as readFileSync27, readdirSync as readdirSync28, statSync as statSync33 } from "fs";
|
|
17772
17798
|
import { join as join36 } from "path";
|
|
17773
17799
|
function readJson2(path) {
|
|
17774
17800
|
if (!existsSync37(path))
|
|
@@ -17795,7 +17821,7 @@ var init_hooks_source = __esm({
|
|
|
17795
17821
|
const projectsRoot = claudeBackend.projectsDir();
|
|
17796
17822
|
if (existsSync37(projectsRoot)) {
|
|
17797
17823
|
try {
|
|
17798
|
-
for (const entry of
|
|
17824
|
+
for (const entry of readdirSync28(projectsRoot, { withFileTypes: true })) {
|
|
17799
17825
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
17800
17826
|
continue;
|
|
17801
17827
|
const projectPath = resolveProjectDirName(entry.name);
|
|
@@ -17891,7 +17917,7 @@ var init_hooks_source = __esm({
|
|
|
17891
17917
|
});
|
|
17892
17918
|
|
|
17893
17919
|
// ../engine/dist/parsers/plugins-source.js
|
|
17894
|
-
import { existsSync as existsSync38, readFileSync as readFileSync28, readdirSync as
|
|
17920
|
+
import { existsSync as existsSync38, readFileSync as readFileSync28, readdirSync as readdirSync29, statSync as statSync34 } from "fs";
|
|
17895
17921
|
import { homedir as homedir14 } from "os";
|
|
17896
17922
|
import { join as join37 } from "path";
|
|
17897
17923
|
function readJson3(path) {
|
|
@@ -17953,7 +17979,7 @@ var init_plugins_source = __esm({
|
|
|
17953
17979
|
if (isSourceEnabled("agy", "extensions") && existsSync38(gemRoot)) {
|
|
17954
17980
|
let entries;
|
|
17955
17981
|
try {
|
|
17956
|
-
entries =
|
|
17982
|
+
entries = readdirSync29(gemRoot);
|
|
17957
17983
|
} catch {
|
|
17958
17984
|
entries = [];
|
|
17959
17985
|
}
|
|
@@ -17997,16 +18023,8 @@ var init_plugins_source = __esm({
|
|
|
17997
18023
|
};
|
|
17998
18024
|
}
|
|
17999
18025
|
}
|
|
18000
|
-
|
|
18001
|
-
|
|
18002
|
-
let entries;
|
|
18003
|
-
try {
|
|
18004
|
-
entries = readdirSync30(codexPluginsRoot);
|
|
18005
|
-
} catch {
|
|
18006
|
-
entries = [];
|
|
18007
|
-
}
|
|
18008
|
-
for (const name of entries) {
|
|
18009
|
-
const pluginDir = join37(codexPluginsRoot, name);
|
|
18026
|
+
if (isSourceEnabled("codex", "plugins")) {
|
|
18027
|
+
for (const { name, dir: pluginDir } of codexBackend.installedPluginDirs()) {
|
|
18010
18028
|
let st;
|
|
18011
18029
|
try {
|
|
18012
18030
|
st = statSync34(pluginDir);
|
|
@@ -18120,7 +18138,8 @@ var init_all_sources = __esm({
|
|
|
18120
18138
|
|
|
18121
18139
|
// ../engine/dist/core/extractor-version.js
|
|
18122
18140
|
function extractorVersionForItem(id, sourceType) {
|
|
18123
|
-
|
|
18141
|
+
const tool = toolOfId(id);
|
|
18142
|
+
return extractorVersionForTool(tool) + (ITEM_SOURCE_BUMP[sourceType] ?? 0) + (ITEM_TOOL_SOURCE_BUMP[`${tool}:${sourceType}`] ?? 0);
|
|
18124
18143
|
}
|
|
18125
18144
|
function toolOfId(id) {
|
|
18126
18145
|
if (id.startsWith("agy_"))
|
|
@@ -18141,17 +18160,21 @@ function extractorVersionForTool(tool) {
|
|
|
18141
18160
|
function extractorVersionForId(id) {
|
|
18142
18161
|
return extractorVersionForTool(toolOfId(id));
|
|
18143
18162
|
}
|
|
18144
|
-
var BASE_EXTRACTOR_VERSION, ITEM_SOURCE_BUMP, TOOL_EXTRACTOR_BUMP, EXTRACTOR_VERSION;
|
|
18163
|
+
var BASE_EXTRACTOR_VERSION, ITEM_SOURCE_BUMP, ITEM_TOOL_SOURCE_BUMP, TOOL_EXTRACTOR_BUMP, EXTRACTOR_VERSION;
|
|
18145
18164
|
var init_extractor_version = __esm({
|
|
18146
18165
|
"../engine/dist/core/extractor-version.js"() {
|
|
18147
18166
|
"use strict";
|
|
18148
18167
|
BASE_EXTRACTOR_VERSION = 2;
|
|
18149
18168
|
ITEM_SOURCE_BUMP = {
|
|
18150
|
-
mcp:
|
|
18169
|
+
mcp: 2,
|
|
18151
18170
|
skill: 1,
|
|
18152
18171
|
agent: 1,
|
|
18153
18172
|
command: 1
|
|
18154
18173
|
};
|
|
18174
|
+
ITEM_TOOL_SOURCE_BUMP = {
|
|
18175
|
+
"codex:skill": 1,
|
|
18176
|
+
"codex:plugin": 1
|
|
18177
|
+
};
|
|
18155
18178
|
TOOL_EXTRACTOR_BUMP = {
|
|
18156
18179
|
agy: 3,
|
|
18157
18180
|
claude: 1,
|
|
@@ -18263,6 +18286,28 @@ function saveItemVersions(server, versions) {
|
|
|
18263
18286
|
writeFileSync5(tmp, JSON.stringify(all));
|
|
18264
18287
|
renameSync4(tmp, path);
|
|
18265
18288
|
}
|
|
18289
|
+
function loadInventoryHashes(server) {
|
|
18290
|
+
try {
|
|
18291
|
+
const parsed = JSON.parse(readFileSync29(inventoryPath(), "utf-8"));
|
|
18292
|
+
return { ...(parsed && typeof parsed === "object" ? parsed[server] : null) || {} };
|
|
18293
|
+
} catch {
|
|
18294
|
+
return {};
|
|
18295
|
+
}
|
|
18296
|
+
}
|
|
18297
|
+
function saveInventoryHashes(server, hashes) {
|
|
18298
|
+
let all = {};
|
|
18299
|
+
try {
|
|
18300
|
+
all = JSON.parse(readFileSync29(inventoryPath(), "utf-8"));
|
|
18301
|
+
} catch {
|
|
18302
|
+
}
|
|
18303
|
+
if (!all || typeof all !== "object") all = {};
|
|
18304
|
+
all[server] = { ...all[server] || {}, ...hashes };
|
|
18305
|
+
const path = inventoryPath();
|
|
18306
|
+
mkdirSync6(dirname15(path), { recursive: true });
|
|
18307
|
+
const tmp = `${path}.tmp`;
|
|
18308
|
+
writeFileSync5(tmp, JSON.stringify(all));
|
|
18309
|
+
renameSync4(tmp, path);
|
|
18310
|
+
}
|
|
18266
18311
|
function getSyncedRows(server) {
|
|
18267
18312
|
const data = load();
|
|
18268
18313
|
const out = /* @__PURE__ */ new Map();
|
|
@@ -18374,7 +18419,7 @@ function syncMode(row, mtime, fileSize, extractorVersion, isAppendOnly) {
|
|
|
18374
18419
|
if (row.m >= Math.floor(mtime)) return "skip";
|
|
18375
18420
|
return "full";
|
|
18376
18421
|
}
|
|
18377
|
-
var ledgerPath, cache3, LEDGER_FLUSH_MS, pendingWrite, flushTimer, itemVersionsPath, itemVersionsCache, unackedCursorAttempts, reconcilePath, reconcileCache;
|
|
18422
|
+
var ledgerPath, cache3, LEDGER_FLUSH_MS, pendingWrite, flushTimer, itemVersionsPath, itemVersionsCache, inventoryPath, unackedCursorAttempts, reconcilePath, reconcileCache;
|
|
18378
18423
|
var init_sync_ledger = __esm({
|
|
18379
18424
|
"src/sync-ledger.ts"() {
|
|
18380
18425
|
"use strict";
|
|
@@ -18387,6 +18432,7 @@ var init_sync_ledger = __esm({
|
|
|
18387
18432
|
flushTimer = null;
|
|
18388
18433
|
itemVersionsPath = () => join38(getDataDir(), "item-versions.json");
|
|
18389
18434
|
itemVersionsCache = null;
|
|
18435
|
+
inventoryPath = () => join38(getDataDir(), "toolkit-inventory.json");
|
|
18390
18436
|
unackedCursorAttempts = 0;
|
|
18391
18437
|
reconcilePath = () => join38(getDataDir(), "sync-field-reconcile.json");
|
|
18392
18438
|
reconcileCache = null;
|
|
@@ -18541,7 +18587,7 @@ var init_http = __esm({
|
|
|
18541
18587
|
CLI_VERSION = JSON.parse(readFileSync31(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
18542
18588
|
} catch {
|
|
18543
18589
|
try {
|
|
18544
|
-
if (true) CLI_VERSION = "0.7.
|
|
18590
|
+
if (true) CLI_VERSION = "0.7.5";
|
|
18545
18591
|
} catch {
|
|
18546
18592
|
}
|
|
18547
18593
|
}
|
|
@@ -19040,7 +19086,7 @@ var init_telemetry = __esm({
|
|
|
19040
19086
|
init_sync_client();
|
|
19041
19087
|
cliVersion2 = () => {
|
|
19042
19088
|
try {
|
|
19043
|
-
return true ? "0.7.
|
|
19089
|
+
return true ? "0.7.5" : "dev";
|
|
19044
19090
|
} catch {
|
|
19045
19091
|
return "dev";
|
|
19046
19092
|
}
|
|
@@ -19405,7 +19451,7 @@ __export(auto_update_exports, {
|
|
|
19405
19451
|
import { execSync as execSync2, execFileSync as execFileSync3 } from "node:child_process";
|
|
19406
19452
|
import { readFileSync as readFileSync34, existsSync as existsSync41 } from "node:fs";
|
|
19407
19453
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
19408
|
-
import { writeFileSync as writeFileSync8, mkdtempSync as mkdtempSync3, rmSync as rmSync5, readdirSync as
|
|
19454
|
+
import { writeFileSync as writeFileSync8, mkdtempSync as mkdtempSync3, rmSync as rmSync5, readdirSync as readdirSync30, statSync as statSync36, mkdirSync as mkdirSync9 } from "node:fs";
|
|
19409
19455
|
import { join as join41, dirname as dirname18, sep as sep2, posix as pathPosix, win32 as pathWin32 } from "node:path";
|
|
19410
19456
|
import { tmpdir as tmpdir2, homedir as homedir15 } from "node:os";
|
|
19411
19457
|
import { createHash as createHash8 } from "node:crypto";
|
|
@@ -19442,7 +19488,7 @@ function planAutoUpdate(base3, caps, ownVersion3, flag) {
|
|
|
19442
19488
|
if (!rel || !rel.version || !rel.sha256) return { update: false, reason: "server advertises no CLI release" };
|
|
19443
19489
|
if (!isAutoUpdateEnabled(caps.edition, flag)) return { update: false, reason: `auto-update disabled (edition ${caps.edition ?? "?"})` };
|
|
19444
19490
|
if (compareVersions(rel.version, ownVersion3) <= 0) return { update: false, reason: `already current (own ${ownVersion3} >= server ${rel.version})` };
|
|
19445
|
-
return { update: true, reason: `server ${rel.version} > own ${ownVersion3}`, url: tarballUrl(base3), sha256: rel.sha256, from: ownVersion3, to: rel.version };
|
|
19491
|
+
return { update: true, reason: `server ${rel.version} > own ${ownVersion3}`, url: tarballUrl(base3, rel.version), fallbackUrl: tarballUrl(base3), sha256: rel.sha256, from: ownVersion3, to: rel.version };
|
|
19446
19492
|
}
|
|
19447
19493
|
function sweepStaleStaging(root = tmpdir2(), now = Date.now()) {
|
|
19448
19494
|
const MKDTEMP_SUFFIX = /^cr-update-.{6}$/s;
|
|
@@ -19450,7 +19496,7 @@ function sweepStaleStaging(root = tmpdir2(), now = Date.now()) {
|
|
|
19450
19496
|
let removed = 0;
|
|
19451
19497
|
let entries;
|
|
19452
19498
|
try {
|
|
19453
|
-
entries =
|
|
19499
|
+
entries = readdirSync30(root);
|
|
19454
19500
|
} catch {
|
|
19455
19501
|
return 0;
|
|
19456
19502
|
}
|
|
@@ -19460,7 +19506,7 @@ function sweepStaleStaging(root = tmpdir2(), now = Date.now()) {
|
|
|
19460
19506
|
try {
|
|
19461
19507
|
const st = statSync36(dir);
|
|
19462
19508
|
if (!st.isDirectory() || now - st.mtimeMs < COLD_MS) continue;
|
|
19463
|
-
const inside =
|
|
19509
|
+
const inside = readdirSync30(dir);
|
|
19464
19510
|
if (inside.length > 1 || inside.length === 1 && inside[0] !== "chat-recall.tgz") continue;
|
|
19465
19511
|
rmSync5(dir, { recursive: true, force: true });
|
|
19466
19512
|
removed++;
|
|
@@ -19475,7 +19521,13 @@ async function executeAutoUpdate(plan, deps) {
|
|
|
19475
19521
|
try {
|
|
19476
19522
|
buf = await deps.download(plan.url);
|
|
19477
19523
|
} catch (e) {
|
|
19478
|
-
|
|
19524
|
+
const notFound = e instanceof Error && e.message === "HTTP 404";
|
|
19525
|
+
if (!notFound || !plan.fallbackUrl) return { updated: false, reason: `download failed: ${e instanceof Error ? e.message : e}` };
|
|
19526
|
+
try {
|
|
19527
|
+
buf = await deps.download(plan.fallbackUrl);
|
|
19528
|
+
} catch (e2) {
|
|
19529
|
+
return { updated: false, reason: `download failed: ${e2 instanceof Error ? e2.message : e2}` };
|
|
19530
|
+
}
|
|
19479
19531
|
}
|
|
19480
19532
|
const got = createHash8("sha256").update(buf).digest("hex");
|
|
19481
19533
|
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` };
|
|
@@ -19651,7 +19703,7 @@ var init_auto_update = __esm({
|
|
|
19651
19703
|
"src/auto-update.ts"() {
|
|
19652
19704
|
"use strict";
|
|
19653
19705
|
init_http();
|
|
19654
|
-
tarballUrl = (base3) => `${base3.replace(/\/+$/, "")}/install
|
|
19706
|
+
tarballUrl = (base3, version2) => `${base3.replace(/\/+$/, "")}/install/${version2 ? `chat-recall-${version2}.tgz` : "chat-recall.tgz"}`;
|
|
19655
19707
|
GIVE_UP_AFTER = 3;
|
|
19656
19708
|
reportedStandingSkip = /* @__PURE__ */ new Set();
|
|
19657
19709
|
}
|
|
@@ -19664,6 +19716,7 @@ __export(sync_client_exports, {
|
|
|
19664
19716
|
DERIVED_MAX_BYTES: () => DERIVED_MAX_BYTES,
|
|
19665
19717
|
FULL_BUILD_MAX_BYTES: () => FULL_BUILD_MAX_BYTES,
|
|
19666
19718
|
SYNC_CHUNK_BYTES: () => SYNC_CHUNK_BYTES,
|
|
19719
|
+
TOOLKIT_INVENTORY_TYPES: () => TOOLKIT_INVENTORY_TYPES,
|
|
19667
19720
|
_acceptedUploads: () => _acceptedUploads,
|
|
19668
19721
|
_fetchTenantSyncConfigForTests: () => _fetchTenantSyncConfigForTests,
|
|
19669
19722
|
_resetCapsCacheForTests: () => _resetCapsCacheForTests,
|
|
@@ -19692,7 +19745,7 @@ __export(sync_client_exports, {
|
|
|
19692
19745
|
syncSessions: () => syncSessions
|
|
19693
19746
|
});
|
|
19694
19747
|
import { join as join42, dirname as dirname19, basename as basename20 } from "node:path";
|
|
19695
|
-
import { readFileSync as readFileSync35, writeFileSync as writeFileSync9, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync4, rmSync as rmSync6, chmodSync as chmodSync3, unlinkSync as unlinkSync2, readdirSync as
|
|
19748
|
+
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";
|
|
19696
19749
|
import { tmpdir as tmpdir3, hostname as hostname2 } from "node:os";
|
|
19697
19750
|
import { createHash as createHash9 } from "node:crypto";
|
|
19698
19751
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
@@ -20095,7 +20148,7 @@ function reapStaleScanDirs(dir = tmpdir3(), maxAgeMs = 6 * 36e5, now = Date.now(
|
|
|
20095
20148
|
let reaped = 0;
|
|
20096
20149
|
let names;
|
|
20097
20150
|
try {
|
|
20098
|
-
names =
|
|
20151
|
+
names = readdirSync31(dir);
|
|
20099
20152
|
} catch {
|
|
20100
20153
|
return 0;
|
|
20101
20154
|
}
|
|
@@ -20736,17 +20789,24 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20736
20789
|
const seenTools = /* @__PURE__ */ new Set();
|
|
20737
20790
|
const seenItemKeys = /* @__PURE__ */ new Map();
|
|
20738
20791
|
const registry = buildSourceRegistry();
|
|
20792
|
+
const inventory = /* @__PURE__ */ new Map();
|
|
20793
|
+
const inventoryFailed = /* @__PURE__ */ new Set();
|
|
20739
20794
|
for (const sourceType of registry.getRegisteredTypes()) {
|
|
20740
20795
|
if (sourceType === "session") continue;
|
|
20796
|
+
if (TOOLKIT_INVENTORY_TYPES.has(sourceType)) inventory.set(sourceType, /* @__PURE__ */ new Set());
|
|
20741
20797
|
for (const source of registry.getAll(sourceType)) {
|
|
20742
20798
|
let discovered;
|
|
20743
20799
|
try {
|
|
20744
20800
|
discovered = source.discover();
|
|
20745
20801
|
} catch {
|
|
20802
|
+
inventoryFailed.add(sourceType);
|
|
20746
20803
|
continue;
|
|
20747
20804
|
}
|
|
20748
20805
|
try {
|
|
20749
20806
|
for await (const item of discovered) {
|
|
20807
|
+
if (inventory.has(item.sourceType) && !excluded(item.projectPath || "") && includedProject(item.projectPath || "")) {
|
|
20808
|
+
inventory.get(item.sourceType).add(item.id);
|
|
20809
|
+
}
|
|
20750
20810
|
const itemTool = toolOfId(item.id);
|
|
20751
20811
|
seenTools.add(itemTool);
|
|
20752
20812
|
const itemKey = `${itemTool}:${item.sourceType}`;
|
|
@@ -20804,6 +20864,7 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20804
20864
|
redactions += count.redactions;
|
|
20805
20865
|
}
|
|
20806
20866
|
} catch (err) {
|
|
20867
|
+
inventoryFailed.add(sourceType);
|
|
20807
20868
|
console.error(`[sync] source '${sourceType}' failed mid-walk (its items may be incomplete this run): ${err instanceof Error ? err.message : err}`);
|
|
20808
20869
|
}
|
|
20809
20870
|
}
|
|
@@ -20830,6 +20891,27 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20830
20891
|
await kgTripleBatch.drain();
|
|
20831
20892
|
await findingsBatch.drain();
|
|
20832
20893
|
await drainInflight();
|
|
20894
|
+
{
|
|
20895
|
+
const sentHashes = loadInventoryHashes(base3);
|
|
20896
|
+
const entries = [];
|
|
20897
|
+
const hashes = {};
|
|
20898
|
+
for (const [sourceType, ids] of inventory) {
|
|
20899
|
+
if (inventoryFailed.has(sourceType)) continue;
|
|
20900
|
+
const sorted = [...ids].sort();
|
|
20901
|
+
const hash = createHash9("sha256").update(sorted.join("\n")).digest("hex").slice(0, 32);
|
|
20902
|
+
if (sentHashes[sourceType] === hash) continue;
|
|
20903
|
+
entries.push({ source_type: sourceType, ids: sorted });
|
|
20904
|
+
hashes[sourceType] = hash;
|
|
20905
|
+
}
|
|
20906
|
+
if (entries.length > 0) {
|
|
20907
|
+
try {
|
|
20908
|
+
await post({ inventory: entries });
|
|
20909
|
+
saveInventoryHashes(base3, hashes);
|
|
20910
|
+
} catch (err) {
|
|
20911
|
+
console.error(`[sync] toolkit inventory not sent (it is retried next sync): ${err instanceof Error ? err.message : err}`);
|
|
20912
|
+
}
|
|
20913
|
+
}
|
|
20914
|
+
}
|
|
20833
20915
|
if (seenTools.size > 0) {
|
|
20834
20916
|
try {
|
|
20835
20917
|
const rec = {};
|
|
@@ -21275,7 +21357,7 @@ async function syncIncremental(opts = {}) {
|
|
|
21275
21357
|
lock.release();
|
|
21276
21358
|
}
|
|
21277
21359
|
}
|
|
21278
|
-
var ownVersion, ERROR_CLASS, STANDING_FAILURE, walkProgressForUpload, lastServerPackSpec, credPath, _securityConfigCache, SECURITY_CONFIG_TTL_MS, _syncConfigCache, EMPTY_SYNC_CONFIG, _fetchTenantSyncConfigForTests, 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;
|
|
21360
|
+
var ownVersion, ERROR_CLASS, STANDING_FAILURE, walkProgressForUpload, lastServerPackSpec, credPath, _securityConfigCache, SECURITY_CONFIG_TTL_MS, _syncConfigCache, EMPTY_SYNC_CONFIG, _fetchTenantSyncConfigForTests, 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;
|
|
21279
21361
|
var init_sync_client = __esm({
|
|
21280
21362
|
"src/sync-client.ts"() {
|
|
21281
21363
|
"use strict";
|
|
@@ -21320,7 +21402,7 @@ var init_sync_client = __esm({
|
|
|
21320
21402
|
ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
21321
21403
|
} catch {
|
|
21322
21404
|
try {
|
|
21323
|
-
if (true) ownVersion = "0.7.
|
|
21405
|
+
if (true) ownVersion = "0.7.5";
|
|
21324
21406
|
} catch {
|
|
21325
21407
|
}
|
|
21326
21408
|
}
|
|
@@ -21350,6 +21432,7 @@ var init_sync_client = __esm({
|
|
|
21350
21432
|
FULL_BUILD_MAX_BYTES = Math.max(8, parseInt(process.env.CHAT_RECALL_FULL_BUILD_MAX_MB || "24", 10)) * 1024 * 1024;
|
|
21351
21433
|
DERIVED_MAX_BYTES = Math.max(8, parseInt(process.env.CHAT_RECALL_DERIVED_MAX_MB || "64", 10)) * 1024 * 1024;
|
|
21352
21434
|
SYNC_CHUNK_BYTES = 8 * 1024 * 1024;
|
|
21435
|
+
TOOLKIT_INVENTORY_TYPES = /* @__PURE__ */ new Set(["skill", "mcp", "command", "agent", "plugin"]);
|
|
21353
21436
|
BATCH_SCAN_MAX_BYTES = Math.max(1, parseInt(process.env.CHAT_RECALL_BATCHSCAN_MAX_MB || "64", 10)) * 1024 * 1024;
|
|
21354
21437
|
}
|
|
21355
21438
|
});
|
|
@@ -22004,7 +22087,7 @@ __export(install_skills_exports, {
|
|
|
22004
22087
|
skillsSourceDir: () => skillsSourceDir,
|
|
22005
22088
|
uninstallSkills: () => uninstallSkills
|
|
22006
22089
|
});
|
|
22007
|
-
import { readdirSync as
|
|
22090
|
+
import { readdirSync as readdirSync32, existsSync as existsSync46, mkdirSync as mkdirSync14, rmSync as rmSync7, cpSync, writeFileSync as writeFileSync14, readFileSync as readFileSync39, statSync as statSync40, realpathSync as realpathSync4 } from "fs";
|
|
22008
22091
|
import { createHash as createHash11 } from "crypto";
|
|
22009
22092
|
import { join as join48, basename as basename21 } from "path";
|
|
22010
22093
|
function skillsSourceDir() {
|
|
@@ -22030,7 +22113,7 @@ function skillsFingerprint() {
|
|
|
22030
22113
|
}
|
|
22031
22114
|
function filesUnder(dir, prefix = "") {
|
|
22032
22115
|
const out = [];
|
|
22033
|
-
for (const e of
|
|
22116
|
+
for (const e of readdirSync32(dir, { withFileTypes: true })) {
|
|
22034
22117
|
if (e.name === MARKER) continue;
|
|
22035
22118
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
22036
22119
|
if (e.isDirectory()) out.push(...filesUnder(join48(dir, e.name), rel));
|
|
@@ -22044,7 +22127,7 @@ function skillStamp() {
|
|
|
22044
22127
|
function bundledSkillNames() {
|
|
22045
22128
|
const src = skillsSourceDir();
|
|
22046
22129
|
if (!existsSync46(src)) return [];
|
|
22047
|
-
return
|
|
22130
|
+
return readdirSync32(src, { withFileTypes: true }).filter((e) => e.isDirectory() && existsSync46(join48(src, e.name, "SKILL.md"))).map((e) => e.name).sort();
|
|
22048
22131
|
}
|
|
22049
22132
|
function realPathOrSelf(p) {
|
|
22050
22133
|
try {
|
|
@@ -22134,7 +22217,7 @@ function uninstallSkills() {
|
|
|
22134
22217
|
perTarget.push({ id: t.id, label: t.label, removed });
|
|
22135
22218
|
continue;
|
|
22136
22219
|
}
|
|
22137
|
-
for (const entry of
|
|
22220
|
+
for (const entry of readdirSync32(t.dir, { withFileTypes: true })) {
|
|
22138
22221
|
if (!entry.isDirectory()) continue;
|
|
22139
22222
|
const dir = join48(t.dir, entry.name);
|
|
22140
22223
|
if (isManaged(dir) && (names.has(entry.name) || entry.name.startsWith("chat-recall"))) {
|
|
@@ -22808,6 +22891,7 @@ __export(toolkit_pull_exports, {
|
|
|
22808
22891
|
entryFromSpec: () => entryFromSpec,
|
|
22809
22892
|
executePull: () => executePull,
|
|
22810
22893
|
planPull: () => planPull,
|
|
22894
|
+
platformRefusal: () => platformRefusal,
|
|
22811
22895
|
portableCommand: () => portableCommand
|
|
22812
22896
|
});
|
|
22813
22897
|
import { existsSync as existsSync48, mkdirSync as mkdirSync16, statSync as statSync41, writeFileSync as writeFileSync16 } from "node:fs";
|
|
@@ -22865,6 +22949,7 @@ function planPull(rows, opts = {}) {
|
|
|
22865
22949
|
const wanted = opts.types;
|
|
22866
22950
|
const seenUnsupported = /* @__PURE__ */ new Map();
|
|
22867
22951
|
const byName = /* @__PURE__ */ new Map();
|
|
22952
|
+
const platformsByName = /* @__PURE__ */ new Map();
|
|
22868
22953
|
const skillsByName = /* @__PURE__ */ new Map();
|
|
22869
22954
|
const agentsByName = /* @__PURE__ */ new Map();
|
|
22870
22955
|
const commandsByName = /* @__PURE__ */ new Map();
|
|
@@ -22928,6 +23013,9 @@ function planPull(rows, opts = {}) {
|
|
|
22928
23013
|
const name = extra.mcpName || row.title;
|
|
22929
23014
|
if (!name)
|
|
22930
23015
|
continue;
|
|
23016
|
+
if (typeof extra.platform === "string" && extra.platform) {
|
|
23017
|
+
(platformsByName.get(name) ?? platformsByName.set(name, /* @__PURE__ */ new Set()).get(name)).add(extra.platform);
|
|
23018
|
+
}
|
|
22931
23019
|
const spec = extra.spec || null;
|
|
22932
23020
|
if (!spec)
|
|
22933
23021
|
continue;
|
|
@@ -22937,7 +23025,12 @@ function planPull(rows, opts = {}) {
|
|
|
22937
23025
|
byName.set(name, spec);
|
|
22938
23026
|
}
|
|
22939
23027
|
const targets = SUPPORTED_TARGETS.mcp;
|
|
22940
|
-
const mcps = [...byName.entries()].map(([name, spec]) => ({
|
|
23028
|
+
const mcps = [...byName.entries()].map(([name, spec]) => ({
|
|
23029
|
+
name,
|
|
23030
|
+
spec,
|
|
23031
|
+
tools: targets,
|
|
23032
|
+
platforms: [...platformsByName.get(name) ?? []].sort()
|
|
23033
|
+
}));
|
|
22941
23034
|
const skills = [...skillsByName.entries()].map(([name, v]) => ({
|
|
22942
23035
|
name,
|
|
22943
23036
|
body: v.body,
|
|
@@ -22956,7 +23049,18 @@ function planPull(rows, opts = {}) {
|
|
|
22956
23049
|
];
|
|
22957
23050
|
return { mcps, skills, codecs, unsupported };
|
|
22958
23051
|
}
|
|
23052
|
+
function platformRefusal(name, platforms, here, explicit) {
|
|
23053
|
+
if (explicit.has(name) || platforms.includes(here))
|
|
23054
|
+
return null;
|
|
23055
|
+
const hint = `install it by name if it works on ${here}: chat-recall toolkit pull --mcp ${name}`;
|
|
23056
|
+
if (platforms.length === 0) {
|
|
23057
|
+
return `no device recorded its platform \u2014 re-sync from the device that has it, or ${hint}`;
|
|
23058
|
+
}
|
|
23059
|
+
return `registered only on ${platforms.join(", ")} \u2014 ${hint}`;
|
|
23060
|
+
}
|
|
22959
23061
|
function executePull(rows, opts = {}) {
|
|
23062
|
+
const here = opts.platform ?? process.platform;
|
|
23063
|
+
const explicit = new Set(opts.explicit ?? []);
|
|
22960
23064
|
const { mcps, skills, codecs, unsupported } = planPull(rows, opts);
|
|
22961
23065
|
const outcomes = [];
|
|
22962
23066
|
for (const { name, body, truncated, redacted, tools } of skills) {
|
|
@@ -23025,8 +23129,9 @@ function executePull(rows, opts = {}) {
|
|
|
23025
23129
|
}
|
|
23026
23130
|
}
|
|
23027
23131
|
}
|
|
23028
|
-
for (const { name, spec, tools } of mcps) {
|
|
23132
|
+
for (const { name, spec, tools, platforms } of mcps) {
|
|
23029
23133
|
const built = entryFromSpec(spec);
|
|
23134
|
+
const refusal = platformRefusal(name, platforms, here, explicit);
|
|
23030
23135
|
for (const tool of tools) {
|
|
23031
23136
|
if (!built) {
|
|
23032
23137
|
outcomes.push({ type: "mcp", name, tool, status: "skipped", reason: "stored row has no rebuildable spec (re-index on the source device)" });
|
|
@@ -23036,6 +23141,10 @@ function executePull(rows, opts = {}) {
|
|
|
23036
23141
|
outcomes.push({ type: "mcp", name, tool, status: "present" });
|
|
23037
23142
|
continue;
|
|
23038
23143
|
}
|
|
23144
|
+
if (refusal) {
|
|
23145
|
+
outcomes.push({ type: "mcp", name, tool, status: "skipped", reason: refusal });
|
|
23146
|
+
continue;
|
|
23147
|
+
}
|
|
23039
23148
|
if (spec.secretsRedacted) {
|
|
23040
23149
|
outcomes.push({
|
|
23041
23150
|
type: "mcp",
|
|
@@ -25320,7 +25429,7 @@ async function runPull(base3, opts) {
|
|
|
25320
25429
|
return r.title === opts.name;
|
|
25321
25430
|
}
|
|
25322
25431
|
}) : rows;
|
|
25323
|
-
const report = executePull2(filtered, { thisDeviceId: hostname3(), types: wanted });
|
|
25432
|
+
const report = executePull2(filtered, { thisDeviceId: hostname3(), types: wanted, explicit: opts.name ? [opts.name] : void 0 });
|
|
25324
25433
|
const written = report.outcomes.filter((o) => o.status === "written");
|
|
25325
25434
|
const failed = report.outcomes.filter((o) => o.status === "failed");
|
|
25326
25435
|
return {
|
|
@@ -25454,7 +25563,7 @@ var init_intent_drain = __esm({
|
|
|
25454
25563
|
ownVersion2 = JSON.parse(readFileSync45(join56(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
25455
25564
|
} catch {
|
|
25456
25565
|
try {
|
|
25457
|
-
if (true) ownVersion2 = "0.7.
|
|
25566
|
+
if (true) ownVersion2 = "0.7.5";
|
|
25458
25567
|
} catch {
|
|
25459
25568
|
}
|
|
25460
25569
|
}
|
|
@@ -25876,7 +25985,7 @@ var init_vault_crypto = __esm({
|
|
|
25876
25985
|
});
|
|
25877
25986
|
|
|
25878
25987
|
// ../engine/dist/core/vault-source.js
|
|
25879
|
-
import { existsSync as existsSync54, readdirSync as
|
|
25988
|
+
import { existsSync as existsSync54, readdirSync as readdirSync33, statSync as statSync44 } from "fs";
|
|
25880
25989
|
import { extname, join as join58 } from "path";
|
|
25881
25990
|
function* walkVaultSources() {
|
|
25882
25991
|
const t = loadSettings().team.vault;
|
|
@@ -25906,7 +26015,7 @@ function* walkClaude() {
|
|
|
25906
26015
|
return;
|
|
25907
26016
|
let projectDirs = [];
|
|
25908
26017
|
try {
|
|
25909
|
-
projectDirs =
|
|
26018
|
+
projectDirs = readdirSync33(root);
|
|
25910
26019
|
} catch {
|
|
25911
26020
|
return;
|
|
25912
26021
|
}
|
|
@@ -25917,7 +26026,7 @@ function* walkClaude() {
|
|
|
25917
26026
|
const projDir = join58(root, proj);
|
|
25918
26027
|
let entries = [];
|
|
25919
26028
|
try {
|
|
25920
|
-
entries =
|
|
26029
|
+
entries = readdirSync33(projDir);
|
|
25921
26030
|
} catch {
|
|
25922
26031
|
continue;
|
|
25923
26032
|
}
|
|
@@ -25962,7 +26071,7 @@ function* walkCodex() {
|
|
|
25962
26071
|
const dir = stack.pop();
|
|
25963
26072
|
let entries = [];
|
|
25964
26073
|
try {
|
|
25965
|
-
entries =
|
|
26074
|
+
entries = readdirSync33(dir, { withFileTypes: true });
|
|
25966
26075
|
} catch {
|
|
25967
26076
|
continue;
|
|
25968
26077
|
}
|
|
@@ -25988,7 +26097,7 @@ function* walkAgy() {
|
|
|
25988
26097
|
return;
|
|
25989
26098
|
let sessionDirs = [];
|
|
25990
26099
|
try {
|
|
25991
|
-
sessionDirs =
|
|
26100
|
+
sessionDirs = readdirSync33(brainDir);
|
|
25992
26101
|
} catch {
|
|
25993
26102
|
return;
|
|
25994
26103
|
}
|
|
@@ -29328,7 +29437,7 @@ toolkit.command("sync").description("Fan every artifact out to every tool that i
|
|
|
29328
29437
|
console.log(chalk2.bold(`Synced: ${r.copied.length} copied, ${r.skipped.length} already present, ${r.failed.length} failed.`));
|
|
29329
29438
|
if (r.copied.length > 0) await pushToolkitToServer();
|
|
29330
29439
|
});
|
|
29331
|
-
toolkit.command("pull").description("Install artifacts this device is missing, from the server (cross-device setup)").option("--types <list>", "comma-separated subset: mcp").option("--dry-run", "report what would change, write nothing").action(async (options) => {
|
|
29440
|
+
toolkit.command("pull").description("Install artifacts this device is missing, from the server (cross-device setup)").option("--types <list>", "comma-separated subset: mcp").option("--dry-run", "report what would change, write nothing").option("--mcp <names>", "comma-separated MCP servers to install even if only another platform registered them").action(async (options) => {
|
|
29332
29441
|
const { loadAllCredentials: loadAllCredentials2 } = await Promise.resolve().then(() => (init_sync_client(), sync_client_exports));
|
|
29333
29442
|
const { executePull: executePull2 } = await Promise.resolve().then(() => (init_toolkit_pull(), toolkit_pull_exports));
|
|
29334
29443
|
const { hostname: hostname3 } = await import("node:os");
|
|
@@ -29357,7 +29466,8 @@ toolkit.command("pull").description("Install artifacts this device is missing, f
|
|
|
29357
29466
|
return;
|
|
29358
29467
|
}
|
|
29359
29468
|
const types = options.types ? options.types.split(",").map((x) => x.trim()).filter(Boolean) : void 0;
|
|
29360
|
-
const
|
|
29469
|
+
const explicit = options.mcp ? options.mcp.split(",").map((x) => x.trim()).filter(Boolean) : void 0;
|
|
29470
|
+
const report = executePull2(rows, { thisDeviceId: hostname3(), types, dryRun: options.dryRun, explicit });
|
|
29361
29471
|
const written = report.outcomes.filter((o) => o.status === "written");
|
|
29362
29472
|
const present = report.outcomes.filter((o) => o.status === "present");
|
|
29363
29473
|
const failed = report.outcomes.filter((o) => o.status === "failed");
|