nexus-agents 2.62.0 → 2.63.0
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/{chunk-X5WDX7L3.js → chunk-4G7MSCIK.js} +2 -2
- package/dist/{chunk-OJBW4II4.js → chunk-7C32M23X.js} +2 -2
- package/dist/{chunk-V7AFOKWC.js → chunk-FMFQJLMR.js} +3 -3
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +287 -50
- package/dist/cli.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/{setup-command-FC67SJSP.js → setup-command-QKAVRVLV.js} +3 -3
- package/package.json +1 -1
- /package/dist/{chunk-X5WDX7L3.js.map → chunk-4G7MSCIK.js.map} +0 -0
- /package/dist/{chunk-OJBW4II4.js.map → chunk-7C32M23X.js.map} +0 -0
- /package/dist/{chunk-V7AFOKWC.js.map → chunk-FMFQJLMR.js.map} +0 -0
- /package/dist/{setup-command-FC67SJSP.js.map → setup-command-QKAVRVLV.js.map} +0 -0
|
@@ -68,7 +68,7 @@ import {
|
|
|
68
68
|
clampTaskTtl,
|
|
69
69
|
getAvailabilityCache,
|
|
70
70
|
resolveFallback
|
|
71
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-FMFQJLMR.js";
|
|
72
72
|
import {
|
|
73
73
|
DEFAULTS
|
|
74
74
|
} from "./chunk-H43PABG4.js";
|
|
@@ -53661,4 +53661,4 @@ export {
|
|
|
53661
53661
|
detectBackend,
|
|
53662
53662
|
createTaskTracker
|
|
53663
53663
|
};
|
|
53664
|
-
//# sourceMappingURL=chunk-
|
|
53664
|
+
//# sourceMappingURL=chunk-4G7MSCIK.js.map
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
checkSqlite,
|
|
9
9
|
defaultConfig,
|
|
10
10
|
initDataDirectories
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-FMFQJLMR.js";
|
|
12
12
|
import {
|
|
13
13
|
BUILT_IN_EXPERTS
|
|
14
14
|
} from "./chunk-GJVHRJO2.js";
|
|
@@ -1933,4 +1933,4 @@ export {
|
|
|
1933
1933
|
setupCommand,
|
|
1934
1934
|
setupCommandAsync
|
|
1935
1935
|
};
|
|
1936
|
-
//# sourceMappingURL=chunk-
|
|
1936
|
+
//# sourceMappingURL=chunk-7C32M23X.js.map
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
} from "./chunk-CLYZ7FWP.js";
|
|
39
39
|
|
|
40
40
|
// src/version.ts
|
|
41
|
-
var VERSION = true ? "2.
|
|
41
|
+
var VERSION = true ? "2.63.0" : "dev";
|
|
42
42
|
|
|
43
43
|
// src/config/schemas-core.ts
|
|
44
44
|
import { z } from "zod";
|
|
@@ -2025,7 +2025,7 @@ async function runDoctorFix(result) {
|
|
|
2025
2025
|
writeLine2("\u2500".repeat(40));
|
|
2026
2026
|
let fixCount = 0;
|
|
2027
2027
|
if (!result.dataDirectory.rootExists || result.dataDirectory.subdirectories.some((d) => !d.exists || !d.writable)) {
|
|
2028
|
-
const { runSetup } = await import("./setup-command-
|
|
2028
|
+
const { runSetup } = await import("./setup-command-QKAVRVLV.js");
|
|
2029
2029
|
const setupResult = runSetup({
|
|
2030
2030
|
skipMcp: true,
|
|
2031
2031
|
skipRules: true,
|
|
@@ -2135,4 +2135,4 @@ export {
|
|
|
2135
2135
|
startStdioServer,
|
|
2136
2136
|
closeServer
|
|
2137
2137
|
};
|
|
2138
|
-
//# sourceMappingURL=chunk-
|
|
2138
|
+
//# sourceMappingURL=chunk-FMFQJLMR.js.map
|
package/dist/cli.d.ts
CHANGED
package/dist/cli.js
CHANGED
|
@@ -16,7 +16,7 @@ import "./chunk-6QU4DJYW.js";
|
|
|
16
16
|
import {
|
|
17
17
|
setupCommandAsync,
|
|
18
18
|
verifyCommand
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-7C32M23X.js";
|
|
20
20
|
import "./chunk-QGZBCD2A.js";
|
|
21
21
|
import {
|
|
22
22
|
AuthHandler,
|
|
@@ -142,7 +142,7 @@ import {
|
|
|
142
142
|
validateCommand,
|
|
143
143
|
validateWorkflow,
|
|
144
144
|
wrapInMarkdownFence
|
|
145
|
-
} from "./chunk-
|
|
145
|
+
} from "./chunk-4G7MSCIK.js";
|
|
146
146
|
import "./chunk-ED6VQWNG.js";
|
|
147
147
|
import {
|
|
148
148
|
resolveToken
|
|
@@ -201,7 +201,7 @@ import {
|
|
|
201
201
|
loadConfig,
|
|
202
202
|
runDoctor,
|
|
203
203
|
validateNexusEnv
|
|
204
|
-
} from "./chunk-
|
|
204
|
+
} from "./chunk-FMFQJLMR.js";
|
|
205
205
|
import {
|
|
206
206
|
DEFAULTS
|
|
207
207
|
} from "./chunk-H43PABG4.js";
|
|
@@ -17668,6 +17668,15 @@ var PARSE_ARGS_CONFIG = {
|
|
|
17668
17668
|
"mcp-config": {
|
|
17669
17669
|
type: "boolean",
|
|
17670
17670
|
default: false
|
|
17671
|
+
},
|
|
17672
|
+
// init --portable --install / --uninstall flags (#2311)
|
|
17673
|
+
install: {
|
|
17674
|
+
type: "boolean",
|
|
17675
|
+
default: false
|
|
17676
|
+
},
|
|
17677
|
+
uninstall: {
|
|
17678
|
+
type: "boolean",
|
|
17679
|
+
default: false
|
|
17671
17680
|
}
|
|
17672
17681
|
},
|
|
17673
17682
|
allowPositionals: true,
|
|
@@ -17726,27 +17735,27 @@ function isValidCommand(value) {
|
|
|
17726
17735
|
}
|
|
17727
17736
|
|
|
17728
17737
|
// src/cli-commands-handlers.ts
|
|
17729
|
-
import { existsSync as
|
|
17738
|
+
import { existsSync as existsSync22 } from "fs";
|
|
17730
17739
|
|
|
17731
17740
|
// src/cli/init-portable.ts
|
|
17732
17741
|
import {
|
|
17733
|
-
existsSync as
|
|
17734
|
-
mkdirSync as
|
|
17742
|
+
existsSync as existsSync20,
|
|
17743
|
+
mkdirSync as mkdirSync5,
|
|
17735
17744
|
readdirSync as readdirSync2,
|
|
17736
17745
|
statSync as statSync3,
|
|
17737
17746
|
appendFileSync as appendFileSync2,
|
|
17738
|
-
readFileSync as
|
|
17747
|
+
readFileSync as readFileSync12
|
|
17739
17748
|
} from "fs";
|
|
17740
|
-
import { resolve as resolve11, join as
|
|
17749
|
+
import { resolve as resolve11, join as join16, isAbsolute as isAbsolute2 } from "path";
|
|
17741
17750
|
|
|
17742
17751
|
// src/cli/mcp-config-emitter.ts
|
|
17743
17752
|
import { existsSync as existsSync17, readFileSync as readFileSync10, writeFileSync as writeFileSync5, appendFileSync } from "fs";
|
|
17744
17753
|
import { join as join13 } from "path";
|
|
17745
17754
|
var MCP_CONFIG_FILENAME = ".mcp.json";
|
|
17746
17755
|
var NEXUS_SERVER_KEY = "nexus-agents";
|
|
17747
|
-
function buildNexusServerEntry(dataDir) {
|
|
17756
|
+
function buildNexusServerEntry(dataDir, commandPath) {
|
|
17748
17757
|
return {
|
|
17749
|
-
command: "nexus-agents",
|
|
17758
|
+
command: commandPath ?? "nexus-agents",
|
|
17750
17759
|
args: ["--mode=server"],
|
|
17751
17760
|
env: { NEXUS_DATA_DIR: dataDir }
|
|
17752
17761
|
};
|
|
@@ -17821,7 +17830,7 @@ function emitMcpConfig(options) {
|
|
|
17821
17830
|
const mcpConfigPath = join13(options.workspaceDir, MCP_CONFIG_FILENAME);
|
|
17822
17831
|
const dryRun = options.dryRun === true;
|
|
17823
17832
|
const force = options.force === true;
|
|
17824
|
-
const desired = buildNexusServerEntry(options.dataDir);
|
|
17833
|
+
const desired = buildNexusServerEntry(options.dataDir, options.commandPath);
|
|
17825
17834
|
const loaded = loadExistingConfig(mcpConfigPath);
|
|
17826
17835
|
if (!loaded.ok) return makeFailure(mcpConfigPath, loaded.error);
|
|
17827
17836
|
const decision = decideEmission(loaded.value, desired, force);
|
|
@@ -17854,6 +17863,165 @@ function makeFailure(mcpConfigPath, error) {
|
|
|
17854
17863
|
};
|
|
17855
17864
|
}
|
|
17856
17865
|
|
|
17866
|
+
// src/cli/portable-installer.ts
|
|
17867
|
+
import { execFile } from "child_process";
|
|
17868
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync4, rmSync, writeFileSync as writeFileSync7 } from "fs";
|
|
17869
|
+
import { join as join15 } from "path";
|
|
17870
|
+
import { promisify } from "util";
|
|
17871
|
+
|
|
17872
|
+
// src/cli/bin-shim.ts
|
|
17873
|
+
import { existsSync as existsSync18, readFileSync as readFileSync11, writeFileSync as writeFileSync6, chmodSync as chmodSync2, mkdirSync as mkdirSync3 } from "fs";
|
|
17874
|
+
import { join as join14 } from "path";
|
|
17875
|
+
var SHIM_BASENAME = "nexus-agents";
|
|
17876
|
+
var SHIM_MODE = 493;
|
|
17877
|
+
function buildShimContents(cliEntryPath) {
|
|
17878
|
+
const lines = [
|
|
17879
|
+
"#!/usr/bin/env node",
|
|
17880
|
+
"// Generated by `nexus-agents init --portable --install` (#3a).",
|
|
17881
|
+
"// Do not edit by hand \u2014 re-run `init --portable --install` to refresh.",
|
|
17882
|
+
`import('${cliEntryPath}').catch((e) => { console.error(e); process.exit(1); });`,
|
|
17883
|
+
""
|
|
17884
|
+
];
|
|
17885
|
+
return lines.join("\n");
|
|
17886
|
+
}
|
|
17887
|
+
function writeBinShim(options) {
|
|
17888
|
+
const shimPath = join14(options.binDir, SHIM_BASENAME);
|
|
17889
|
+
const desired = buildShimContents(options.cliEntryPath);
|
|
17890
|
+
const dryRun = options.dryRun === true;
|
|
17891
|
+
try {
|
|
17892
|
+
if (existsSync18(shimPath)) {
|
|
17893
|
+
const current = readFileSync11(shimPath, "utf-8");
|
|
17894
|
+
if (current === desired) {
|
|
17895
|
+
return { success: true, shimPath, written: false, alreadyMatched: true, error: null };
|
|
17896
|
+
}
|
|
17897
|
+
}
|
|
17898
|
+
if (!dryRun) {
|
|
17899
|
+
if (!existsSync18(options.binDir)) mkdirSync3(options.binDir, { recursive: true });
|
|
17900
|
+
writeFileSync6(shimPath, desired, "utf-8");
|
|
17901
|
+
chmodSync2(shimPath, SHIM_MODE);
|
|
17902
|
+
}
|
|
17903
|
+
return { success: true, shimPath, written: true, alreadyMatched: false, error: null };
|
|
17904
|
+
} catch (error) {
|
|
17905
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
17906
|
+
return { success: false, shimPath, written: false, alreadyMatched: false, error: msg };
|
|
17907
|
+
}
|
|
17908
|
+
}
|
|
17909
|
+
|
|
17910
|
+
// src/cli/portable-installer.ts
|
|
17911
|
+
var execFileAsync = promisify(execFile);
|
|
17912
|
+
var CLI_SUBDIR = "cli";
|
|
17913
|
+
var BIN_SUBDIR = "bin";
|
|
17914
|
+
var CLI_ENTRY_RELATIVE = "node_modules/nexus-agents/dist/cli.js";
|
|
17915
|
+
var NPM_INSTALL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
17916
|
+
function resolveInstallVersion(override) {
|
|
17917
|
+
const v = override ?? VERSION;
|
|
17918
|
+
if (v === "dev" || v === "" || v.includes(" ")) {
|
|
17919
|
+
return {
|
|
17920
|
+
ok: false,
|
|
17921
|
+
error: `cannot resolve install version: got '${v}'. Portable install requires a published nexus-agents version (build the CLI from a release).`
|
|
17922
|
+
};
|
|
17923
|
+
}
|
|
17924
|
+
return { ok: true, value: v };
|
|
17925
|
+
}
|
|
17926
|
+
function writeInstallManifest(cliDir, version) {
|
|
17927
|
+
const manifest = {
|
|
17928
|
+
name: "nexus-agents-portable-shim",
|
|
17929
|
+
private: true,
|
|
17930
|
+
version: "0.0.0",
|
|
17931
|
+
description: "Local install root for portable nexus-agents (generated; do not commit)",
|
|
17932
|
+
dependencies: { "nexus-agents": version }
|
|
17933
|
+
};
|
|
17934
|
+
writeFileSync7(join15(cliDir, "package.json"), JSON.stringify(manifest, null, 2) + "\n", "utf-8");
|
|
17935
|
+
}
|
|
17936
|
+
function isAlreadyInstalled(cliDir) {
|
|
17937
|
+
return existsSync19(join15(cliDir, "node_modules", "nexus-agents", "package.json"));
|
|
17938
|
+
}
|
|
17939
|
+
async function spawnNpmInstall(cliDir) {
|
|
17940
|
+
await execFileAsync("npm", ["install", "--no-audit", "--no-fund", "--silent"], {
|
|
17941
|
+
cwd: cliDir,
|
|
17942
|
+
timeout: NPM_INSTALL_TIMEOUT_MS
|
|
17943
|
+
});
|
|
17944
|
+
}
|
|
17945
|
+
function cleanupOnFailure(cliDir) {
|
|
17946
|
+
try {
|
|
17947
|
+
rmSync(cliDir, { recursive: true, force: true });
|
|
17948
|
+
} catch {
|
|
17949
|
+
}
|
|
17950
|
+
}
|
|
17951
|
+
async function runNpmStep(ctx) {
|
|
17952
|
+
try {
|
|
17953
|
+
if (!existsSync19(ctx.cliDir)) mkdirSync4(ctx.cliDir, { recursive: true });
|
|
17954
|
+
writeInstallManifest(ctx.cliDir, ctx.version);
|
|
17955
|
+
await spawnNpmInstall(ctx.cliDir);
|
|
17956
|
+
return void 0;
|
|
17957
|
+
} catch (error) {
|
|
17958
|
+
cleanupOnFailure(ctx.cliDir);
|
|
17959
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
17960
|
+
return { success: false, ...ctx, skipped: false, error: `npm install failed: ${msg}` };
|
|
17961
|
+
}
|
|
17962
|
+
}
|
|
17963
|
+
async function installPortable(options) {
|
|
17964
|
+
const cliDir = join15(options.dataDir, CLI_SUBDIR);
|
|
17965
|
+
const binDir = join15(options.dataDir, BIN_SUBDIR);
|
|
17966
|
+
const versionResolution = resolveInstallVersion(options.version);
|
|
17967
|
+
if (!versionResolution.ok) {
|
|
17968
|
+
return {
|
|
17969
|
+
success: false,
|
|
17970
|
+
version: "",
|
|
17971
|
+
cliDir,
|
|
17972
|
+
binDir,
|
|
17973
|
+
skipped: false,
|
|
17974
|
+
error: versionResolution.error
|
|
17975
|
+
};
|
|
17976
|
+
}
|
|
17977
|
+
const ctx = { cliDir, binDir, version: versionResolution.value };
|
|
17978
|
+
if (isAlreadyInstalled(cliDir) && options.force !== true) {
|
|
17979
|
+
return { success: true, ...ctx, skipped: true, error: null };
|
|
17980
|
+
}
|
|
17981
|
+
if (options.dryRun === true) {
|
|
17982
|
+
return { success: true, ...ctx, skipped: false, error: null };
|
|
17983
|
+
}
|
|
17984
|
+
const npmFailure = await runNpmStep(ctx);
|
|
17985
|
+
if (npmFailure !== void 0) return npmFailure;
|
|
17986
|
+
const shim = writeBinShim({ binDir, cliEntryPath: join15(cliDir, CLI_ENTRY_RELATIVE) });
|
|
17987
|
+
if (!shim.success) {
|
|
17988
|
+
cleanupOnFailure(cliDir);
|
|
17989
|
+
return {
|
|
17990
|
+
success: false,
|
|
17991
|
+
...ctx,
|
|
17992
|
+
shim,
|
|
17993
|
+
skipped: false,
|
|
17994
|
+
error: `bin shim emission failed: ${shim.error ?? "unknown"}`
|
|
17995
|
+
};
|
|
17996
|
+
}
|
|
17997
|
+
return { success: true, ...ctx, shim, skipped: false, error: null };
|
|
17998
|
+
}
|
|
17999
|
+
function uninstallPortable(options) {
|
|
18000
|
+
const cliDir = join15(options.dataDir, CLI_SUBDIR);
|
|
18001
|
+
const binDir = join15(options.dataDir, BIN_SUBDIR);
|
|
18002
|
+
const removed = [];
|
|
18003
|
+
const notPresent = [];
|
|
18004
|
+
const dryRun = options.dryRun === true;
|
|
18005
|
+
try {
|
|
18006
|
+
for (const dir of [cliDir, binDir]) {
|
|
18007
|
+
if (!existsSync19(dir)) {
|
|
18008
|
+
notPresent.push(dir);
|
|
18009
|
+
continue;
|
|
18010
|
+
}
|
|
18011
|
+
if (!dryRun) rmSync(dir, { recursive: true, force: true });
|
|
18012
|
+
removed.push(dir);
|
|
18013
|
+
}
|
|
18014
|
+
return { success: true, removed, notPresent, error: null };
|
|
18015
|
+
} catch (error) {
|
|
18016
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
18017
|
+
return { success: false, removed, notPresent, error: msg };
|
|
18018
|
+
}
|
|
18019
|
+
}
|
|
18020
|
+
function findBinShim(dataDir) {
|
|
18021
|
+
const shimPath = join15(dataDir, BIN_SUBDIR, "nexus-agents");
|
|
18022
|
+
return existsSync19(shimPath) ? shimPath : void 0;
|
|
18023
|
+
}
|
|
18024
|
+
|
|
17857
18025
|
// src/cli/init-portable.ts
|
|
17858
18026
|
var DEFAULT_PORTABLE_DIRNAME = ".nexus-agents";
|
|
17859
18027
|
var RESTRICTED_SUBDIRS = /* @__PURE__ */ new Set(["auth"]);
|
|
@@ -17864,29 +18032,29 @@ function resolveTargetPath(rawPath) {
|
|
|
17864
18032
|
return isAbsolute2(rawPath) ? rawPath : resolve11(process.cwd(), rawPath);
|
|
17865
18033
|
}
|
|
17866
18034
|
function isNonEmpty(dir) {
|
|
17867
|
-
if (!
|
|
18035
|
+
if (!existsSync20(dir)) return false;
|
|
17868
18036
|
const stat2 = statSync3(dir);
|
|
17869
18037
|
if (!stat2.isDirectory()) return true;
|
|
17870
18038
|
return readdirSync2(dir).length > 0;
|
|
17871
18039
|
}
|
|
17872
18040
|
function ensureDir(path23, dryRun, created, alreadyExisted, mode) {
|
|
17873
|
-
if (
|
|
18041
|
+
if (existsSync20(path23)) {
|
|
17874
18042
|
alreadyExisted.push(path23);
|
|
17875
18043
|
return;
|
|
17876
18044
|
}
|
|
17877
18045
|
if (!dryRun) {
|
|
17878
|
-
|
|
18046
|
+
mkdirSync5(path23, { recursive: true, ...mode !== void 0 ? { mode } : {} });
|
|
17879
18047
|
}
|
|
17880
18048
|
created.push(path23);
|
|
17881
18049
|
}
|
|
17882
18050
|
function maybeUpdateGitignore(workspaceDir, portableDirName, dryRun) {
|
|
17883
|
-
const gitDir =
|
|
17884
|
-
if (!
|
|
17885
|
-
const gitignorePath =
|
|
18051
|
+
const gitDir = join16(workspaceDir, ".git");
|
|
18052
|
+
if (!existsSync20(gitDir)) return false;
|
|
18053
|
+
const gitignorePath = join16(workspaceDir, ".gitignore");
|
|
17886
18054
|
const entry = `${portableDirName}/`;
|
|
17887
18055
|
let existing = "";
|
|
17888
|
-
if (
|
|
17889
|
-
existing =
|
|
18056
|
+
if (existsSync20(gitignorePath)) {
|
|
18057
|
+
existing = readFileSync12(gitignorePath, "utf-8");
|
|
17890
18058
|
if (existing.split("\n").some((l) => l.trim() === entry || l.trim() === portableDirName)) {
|
|
17891
18059
|
return false;
|
|
17892
18060
|
}
|
|
@@ -17899,18 +18067,18 @@ function maybeUpdateGitignore(workspaceDir, portableDirName, dryRun) {
|
|
|
17899
18067
|
return true;
|
|
17900
18068
|
}
|
|
17901
18069
|
function inspectTarget(target) {
|
|
17902
|
-
const exists =
|
|
18070
|
+
const exists = existsSync20(target);
|
|
17903
18071
|
if (!exists) return { exists: false, nonEmpty: false, isExistingNexusDir: false };
|
|
17904
18072
|
const nonEmpty = isNonEmpty(target);
|
|
17905
18073
|
const stat2 = statSync3(target);
|
|
17906
|
-
const isExistingNexusDir = stat2.isDirectory() &&
|
|
18074
|
+
const isExistingNexusDir = stat2.isDirectory() && existsSync20(join16(target, "audit"));
|
|
17907
18075
|
return { exists, nonEmpty, isExistingNexusDir };
|
|
17908
18076
|
}
|
|
17909
18077
|
function createDataLayout(target, dryRun, created, alreadyExisted) {
|
|
17910
18078
|
ensureDir(target, dryRun, created, alreadyExisted);
|
|
17911
18079
|
for (const subdir of DATA_SUBDIRECTORIES) {
|
|
17912
18080
|
const mode = RESTRICTED_SUBDIRS.has(subdir) ? 448 : void 0;
|
|
17913
|
-
ensureDir(
|
|
18081
|
+
ensureDir(join16(target, subdir), dryRun, created, alreadyExisted, mode);
|
|
17914
18082
|
}
|
|
17915
18083
|
}
|
|
17916
18084
|
function makeResult(opts) {
|
|
@@ -17922,6 +18090,8 @@ function makeResult(opts) {
|
|
|
17922
18090
|
skipped: opts.skipped ?? false,
|
|
17923
18091
|
gitignoreUpdated: opts.gitignoreUpdated ?? false,
|
|
17924
18092
|
...opts.mcpConfig !== void 0 ? { mcpConfig: opts.mcpConfig } : {},
|
|
18093
|
+
...opts.install !== void 0 ? { install: opts.install } : {},
|
|
18094
|
+
...opts.uninstall !== void 0 ? { uninstall: opts.uninstall } : {},
|
|
17925
18095
|
error: opts.error ?? null
|
|
17926
18096
|
};
|
|
17927
18097
|
}
|
|
@@ -17934,23 +18104,60 @@ function applyGitignoreOption(target, options, dryRun) {
|
|
|
17934
18104
|
function applyMcpConfigOption(target, options, dryRun) {
|
|
17935
18105
|
if (options.mcpConfig !== true) return void 0;
|
|
17936
18106
|
const workspaceDir = resolve11(target, "..");
|
|
18107
|
+
const shimPath = findBinShim(target);
|
|
17937
18108
|
return emitMcpConfig({
|
|
17938
18109
|
workspaceDir,
|
|
17939
18110
|
dataDir: target,
|
|
18111
|
+
...shimPath !== void 0 && { commandPath: shimPath },
|
|
17940
18112
|
force: options.force === true,
|
|
17941
18113
|
dryRun
|
|
17942
18114
|
});
|
|
17943
18115
|
}
|
|
17944
|
-
function
|
|
17945
|
-
if (
|
|
17946
|
-
|
|
18116
|
+
async function applyInstallOption(target, options, dryRun) {
|
|
18117
|
+
if (options.install !== true) return void 0;
|
|
18118
|
+
return installPortable({ dataDir: target, force: options.force === true, dryRun });
|
|
18119
|
+
}
|
|
18120
|
+
function buildSuccessResult(base, flags, extras) {
|
|
18121
|
+
const installFailed = extras.install !== void 0 && !extras.install.success;
|
|
18122
|
+
const mcpFailed = extras.mcpConfig !== void 0 && !extras.mcpConfig.success;
|
|
18123
|
+
if (installFailed) {
|
|
18124
|
+
return makeResult({
|
|
18125
|
+
...base,
|
|
18126
|
+
...flags,
|
|
18127
|
+
success: false,
|
|
18128
|
+
...extras,
|
|
18129
|
+
error: extras.install?.error ?? "install failed"
|
|
18130
|
+
});
|
|
17947
18131
|
}
|
|
17948
|
-
if (
|
|
17949
|
-
return makeResult({
|
|
18132
|
+
if (mcpFailed) {
|
|
18133
|
+
return makeResult({
|
|
18134
|
+
...base,
|
|
18135
|
+
...flags,
|
|
18136
|
+
success: false,
|
|
18137
|
+
...extras,
|
|
18138
|
+
error: extras.mcpConfig?.error ?? "mcp-config emission failed"
|
|
18139
|
+
});
|
|
17950
18140
|
}
|
|
17951
|
-
return makeResult({ ...base, ...flags, success:
|
|
18141
|
+
return makeResult({ ...base, ...flags, success: true, ...extras });
|
|
18142
|
+
}
|
|
18143
|
+
async function collectExtras(target, options, dryRun) {
|
|
18144
|
+
const extras = {};
|
|
18145
|
+
const install = await applyInstallOption(target, options, dryRun);
|
|
18146
|
+
if (install !== void 0) extras.install = install;
|
|
18147
|
+
const mcpConfig = applyMcpConfigOption(target, options, dryRun);
|
|
18148
|
+
if (mcpConfig !== void 0) extras.mcpConfig = mcpConfig;
|
|
18149
|
+
return extras;
|
|
18150
|
+
}
|
|
18151
|
+
function handleUninstall(target, base, dryRun) {
|
|
18152
|
+
const uninstall = uninstallPortable({ dataDir: target, dryRun });
|
|
18153
|
+
return makeResult({
|
|
18154
|
+
...base,
|
|
18155
|
+
success: uninstall.success,
|
|
18156
|
+
uninstall,
|
|
18157
|
+
error: uninstall.error
|
|
18158
|
+
});
|
|
17952
18159
|
}
|
|
17953
|
-
function initPortable(options = {}) {
|
|
18160
|
+
async function initPortable(options = {}) {
|
|
17954
18161
|
const created = [];
|
|
17955
18162
|
const alreadyExisted = [];
|
|
17956
18163
|
const dryRun = options.dryRun === true;
|
|
@@ -17958,14 +18165,12 @@ function initPortable(options = {}) {
|
|
|
17958
18165
|
const target = resolveTargetPath(options.path);
|
|
17959
18166
|
const base = { absolutePath: target, created, alreadyExisted };
|
|
17960
18167
|
try {
|
|
18168
|
+
if (options.uninstall === true) return handleUninstall(target, base, dryRun);
|
|
17961
18169
|
const state = inspectTarget(target);
|
|
17962
18170
|
if (state.isExistingNexusDir && !force) {
|
|
17963
18171
|
createDataLayout(target, dryRun, created, alreadyExisted);
|
|
17964
|
-
|
|
17965
|
-
|
|
17966
|
-
{ skipped: true },
|
|
17967
|
-
applyMcpConfigOption(target, options, dryRun)
|
|
17968
|
-
);
|
|
18172
|
+
const extras2 = await collectExtras(target, options, dryRun);
|
|
18173
|
+
return buildSuccessResult(base, { skipped: true }, extras2);
|
|
17969
18174
|
}
|
|
17970
18175
|
if (state.nonEmpty && !state.isExistingNexusDir && !force) {
|
|
17971
18176
|
const error = `target ${target} already exists and is not empty; pass --force to use anyway`;
|
|
@@ -17973,11 +18178,8 @@ function initPortable(options = {}) {
|
|
|
17973
18178
|
}
|
|
17974
18179
|
createDataLayout(target, dryRun, created, alreadyExisted);
|
|
17975
18180
|
const gitignoreUpdated = applyGitignoreOption(target, options, dryRun);
|
|
17976
|
-
|
|
17977
|
-
|
|
17978
|
-
{ gitignoreUpdated },
|
|
17979
|
-
applyMcpConfigOption(target, options, dryRun)
|
|
17980
|
-
);
|
|
18181
|
+
const extras = await collectExtras(target, options, dryRun);
|
|
18182
|
+
return buildSuccessResult(base, { gitignoreUpdated }, extras);
|
|
17981
18183
|
} catch (error) {
|
|
17982
18184
|
const msg = error instanceof Error ? error.message : String(error);
|
|
17983
18185
|
return makeResult({ ...base, success: false, error: msg });
|
|
@@ -18004,11 +18206,34 @@ function renderMcpConfigCaveat(mcpConfig) {
|
|
|
18004
18206
|
"run `nexus-agents init --portable --mcp-config` themselves."
|
|
18005
18207
|
];
|
|
18006
18208
|
}
|
|
18209
|
+
function renderInstallLines(install) {
|
|
18210
|
+
if (install.skipped) return [`\u2713 Portable install already present (${install.version})`];
|
|
18211
|
+
return [
|
|
18212
|
+
`\u2713 Installed nexus-agents@${install.version} \u2192 ${install.cliDir}`,
|
|
18213
|
+
`\u2713 Wrote bin shim \u2192 ${install.shim?.shimPath ?? install.binDir + "/nexus-agents"}`
|
|
18214
|
+
];
|
|
18215
|
+
}
|
|
18216
|
+
function renderUninstallLines(uninstall) {
|
|
18217
|
+
const lines = [];
|
|
18218
|
+
if (uninstall.removed.length === 0 && uninstall.notPresent.length > 0) {
|
|
18219
|
+
lines.push("Nothing to uninstall \u2014 cli/ and bin/ were not present.");
|
|
18220
|
+
}
|
|
18221
|
+
for (const r of uninstall.removed) lines.push(`\u2713 Removed: ${r}`);
|
|
18222
|
+
if (uninstall.removed.length > 0) {
|
|
18223
|
+
lines.push("");
|
|
18224
|
+
lines.push("Note: data subdirs (memory, audit, voting, sessions, \u2026) preserved.");
|
|
18225
|
+
lines.push("To purge data too, remove the parent dir manually.");
|
|
18226
|
+
}
|
|
18227
|
+
return lines;
|
|
18228
|
+
}
|
|
18007
18229
|
function formatInitPortableMessage(result, dryRun) {
|
|
18008
18230
|
if (!result.success) {
|
|
18009
18231
|
return `init --portable failed: ${result.error ?? "unknown error"}
|
|
18010
18232
|
`;
|
|
18011
18233
|
}
|
|
18234
|
+
if (result.uninstall !== void 0) {
|
|
18235
|
+
return renderUninstallLines(result.uninstall).join("\n") + "\n";
|
|
18236
|
+
}
|
|
18012
18237
|
if (dryRun) {
|
|
18013
18238
|
const lines2 = [
|
|
18014
18239
|
`(dry-run) would create ${String(result.created.length)} entries under:`,
|
|
@@ -18021,6 +18246,7 @@ function formatInitPortableMessage(result, dryRun) {
|
|
|
18021
18246
|
result.skipped ? `\u2713 Already initialized: ${result.absolutePath}` : `\u2713 Created: ${result.absolutePath}`
|
|
18022
18247
|
);
|
|
18023
18248
|
if (result.gitignoreUpdated) lines.push(`\u2713 Added entry to .gitignore`);
|
|
18249
|
+
if (result.install !== void 0) lines.push(...renderInstallLines(result.install));
|
|
18024
18250
|
if (result.mcpConfig !== void 0) lines.push(...renderMcpConfigLines(result.mcpConfig));
|
|
18025
18251
|
lines.push("");
|
|
18026
18252
|
lines.push("Activate by exporting:");
|
|
@@ -20843,8 +21069,8 @@ function printFirstRunHint() {
|
|
|
20843
21069
|
const isTTY = process.stderr.isTTY;
|
|
20844
21070
|
if (!isTTY) return;
|
|
20845
21071
|
const dataDir = getNexusDataDir();
|
|
20846
|
-
const hasConfig =
|
|
20847
|
-
if (
|
|
21072
|
+
const hasConfig = existsSync22("./nexus-agents.yaml") || existsSync22("./nexus-agents.yml");
|
|
21073
|
+
if (existsSync22(dataDir) || hasConfig) return;
|
|
20848
21074
|
process.stderr.write(
|
|
20849
21075
|
"\n\x1B[36mnexus-agents\x1B[0m: First time? Run \x1B[1mnexus-agents setup\x1B[0m to configure.\n\n"
|
|
20850
21076
|
);
|
|
@@ -21010,20 +21236,29 @@ async function handleDoctorCommand(args) {
|
|
|
21010
21236
|
}
|
|
21011
21237
|
process.exit(exitCode === 0 ? EXIT_CODES.SUCCESS : EXIT_CODES.SERVER_START_FAILED);
|
|
21012
21238
|
}
|
|
21013
|
-
function
|
|
21239
|
+
function validateInitFlags(args) {
|
|
21014
21240
|
if (args.options.portable !== true) {
|
|
21015
21241
|
process.stderr.write(
|
|
21016
|
-
"Usage: nexus-agents init --portable [path] [--force] [--dry-run]
|
|
21242
|
+
"Usage: nexus-agents init --portable [path] [--force] [--dry-run]\n [--gitignore] [--mcp-config]\n [--install | --uninstall]\nBootstraps a workspace-local nexus-agents data directory.\n"
|
|
21017
21243
|
);
|
|
21018
21244
|
process.exit(EXIT_CODES.INVALID_ARGS);
|
|
21019
21245
|
}
|
|
21246
|
+
if (args.options.install === true && args.options.uninstall === true) {
|
|
21247
|
+
process.stderr.write("Error: --install and --uninstall are mutually exclusive.\n");
|
|
21248
|
+
process.exit(EXIT_CODES.INVALID_ARGS);
|
|
21249
|
+
}
|
|
21250
|
+
}
|
|
21251
|
+
async function handleInitCommand(args) {
|
|
21252
|
+
validateInitFlags(args);
|
|
21020
21253
|
const targetPath = args.positionals[1];
|
|
21021
|
-
const result = initPortable({
|
|
21254
|
+
const result = await initPortable({
|
|
21022
21255
|
...targetPath !== void 0 && targetPath !== "" ? { path: targetPath } : {},
|
|
21023
21256
|
force: args.options.force,
|
|
21024
21257
|
dryRun: args.options.dryRun,
|
|
21025
21258
|
gitignore: args.options.gitignore ?? false,
|
|
21026
|
-
mcpConfig: args.options.mcpConfig ?? false
|
|
21259
|
+
mcpConfig: args.options.mcpConfig ?? false,
|
|
21260
|
+
install: args.options.install ?? false,
|
|
21261
|
+
uninstall: args.options.uninstall ?? false
|
|
21027
21262
|
});
|
|
21028
21263
|
process.stdout.write(formatInitPortableMessage(result, args.options.dryRun));
|
|
21029
21264
|
process.exit(result.success ? EXIT_CODES.SUCCESS : EXIT_CODES.SERVER_START_FAILED);
|
|
@@ -22501,7 +22736,7 @@ function handleStatusCommand2(args) {
|
|
|
22501
22736
|
|
|
22502
22737
|
// src/cli/scenario-command.ts
|
|
22503
22738
|
import { readdir as readdir4 } from "fs/promises";
|
|
22504
|
-
import { join as
|
|
22739
|
+
import { join as join18, resolve as resolve14 } from "path";
|
|
22505
22740
|
|
|
22506
22741
|
// src/testing/e2e/scenario-runner.ts
|
|
22507
22742
|
import { readFile as readFile7 } from "fs/promises";
|
|
@@ -22871,7 +23106,7 @@ async function handleRun(args) {
|
|
|
22871
23106
|
process.exit(EXIT_CODES.SERVER_START_FAILED);
|
|
22872
23107
|
}
|
|
22873
23108
|
const runner = createScenarioRunner();
|
|
22874
|
-
const fixturePath =
|
|
23109
|
+
const fixturePath = join18(FIXTURES_DIR, `${name}${SCENARIO_SUFFIX}`);
|
|
22875
23110
|
try {
|
|
22876
23111
|
const fixture = await runner.loadFixture(fixturePath);
|
|
22877
23112
|
const result = await runner.run(fixture);
|
|
@@ -23134,8 +23369,6 @@ var SYNC_COMMAND_HANDLERS = {
|
|
|
23134
23369
|
status: handleStatusCommand2,
|
|
23135
23370
|
// Issue #1023: Warm-Up Command
|
|
23136
23371
|
"warm-up": handleWarmUpCommand,
|
|
23137
|
-
// #2305: Init Portable Command
|
|
23138
|
-
init: handleInitCommand,
|
|
23139
23372
|
"e2e-eval": handleE2EEvalCommand,
|
|
23140
23373
|
"routing-ab": handleRoutingABCommand,
|
|
23141
23374
|
"memory-eval": handleMemoryEvalCommand,
|
|
@@ -23175,6 +23408,8 @@ var ASYNC_COMMAND_HANDLERS = {
|
|
|
23175
23408
|
hooks: handleHooksCommand,
|
|
23176
23409
|
setup: handleSetupCommandAsync,
|
|
23177
23410
|
// Uses async for interactive wizard support (Issue #425)
|
|
23411
|
+
// #2305 / #2308 / #2311: Init Portable Command (async because --install spawns npm)
|
|
23412
|
+
init: handleInitCommand,
|
|
23178
23413
|
demo: handleDemoCommand,
|
|
23179
23414
|
// Made async for live CLI execution
|
|
23180
23415
|
// Issue #526: Newly wired async commands
|
|
@@ -23590,7 +23825,9 @@ function buildInitOptions(values) {
|
|
|
23590
23825
|
return {
|
|
23591
23826
|
portable: values.portable,
|
|
23592
23827
|
gitignore: values.gitignore,
|
|
23593
|
-
mcpConfig: values["mcp-config"]
|
|
23828
|
+
mcpConfig: values["mcp-config"],
|
|
23829
|
+
install: values.install,
|
|
23830
|
+
uninstall: values.uninstall
|
|
23594
23831
|
};
|
|
23595
23832
|
}
|
|
23596
23833
|
function parseCliArgs(args = process.argv.slice(2)) {
|