nexus-agents 2.77.3 → 2.77.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/{chunk-LTUUW3FN.js → chunk-5N7JBWAD.js} +24 -212
- package/dist/chunk-5N7JBWAD.js.map +1 -0
- package/dist/{chunk-CPPZCNAS.js → chunk-EEW7VFFF.js} +3 -3
- package/dist/{chunk-X3BU5MIG.js → chunk-FYAQBYHM.js} +2 -2
- package/dist/{chunk-VEF6DCQU.js → chunk-MV4R2ZIJ.js} +204 -4
- package/dist/chunk-MV4R2ZIJ.js.map +1 -0
- package/dist/{chunk-K446R3BC.js → chunk-NQRC7QQL.js} +17 -9
- package/dist/{chunk-K446R3BC.js.map → chunk-NQRC7QQL.js.map} +1 -1
- package/dist/{chunk-KGB67HII.js → chunk-QIDO6VPO.js} +5 -3
- package/dist/{chunk-KGB67HII.js.map → chunk-QIDO6VPO.js.map} +1 -1
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +26 -13
- package/dist/cli.js.map +1 -1
- package/dist/{consensus-vote-UR3JU7RI.js → consensus-vote-AWBFYF5S.js} +3 -3
- package/dist/{expert-bridge-DWBO2HXZ.js → expert-bridge-NX2MGOBQ.js} +2 -2
- package/dist/{factory-LXOVC44K.js → factory-JI6PSWGR.js} +2 -2
- package/dist/index.js +6 -6
- package/dist/{setup-command-XG7R4PR4.js → setup-command-4S7MPK4F.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-LTUUW3FN.js.map +0 -1
- package/dist/chunk-VEF6DCQU.js.map +0 -1
- /package/dist/{chunk-CPPZCNAS.js.map → chunk-EEW7VFFF.js.map} +0 -0
- /package/dist/{chunk-X3BU5MIG.js.map → chunk-FYAQBYHM.js.map} +0 -0
- /package/dist/{consensus-vote-UR3JU7RI.js.map → consensus-vote-AWBFYF5S.js.map} +0 -0
- /package/dist/{expert-bridge-DWBO2HXZ.js.map → expert-bridge-NX2MGOBQ.js.map} +0 -0
- /package/dist/{factory-LXOVC44K.js.map → factory-JI6PSWGR.js.map} +0 -0
- /package/dist/{setup-command-XG7R4PR4.js.map → setup-command-4S7MPK4F.js.map} +0 -0
|
@@ -2762,6 +2762,193 @@ function createCliDetectionCache(config) {
|
|
|
2762
2762
|
return new CliDetectionCache(config);
|
|
2763
2763
|
}
|
|
2764
2764
|
|
|
2765
|
+
// src/cli/cli-auth-probe.ts
|
|
2766
|
+
import { execFile as execFile2 } from "child_process";
|
|
2767
|
+
import { promisify as promisify2 } from "util";
|
|
2768
|
+
import { existsSync, readFileSync } from "fs";
|
|
2769
|
+
import { homedir } from "os";
|
|
2770
|
+
import { join as join3 } from "path";
|
|
2771
|
+
var execFileAsync = promisify2(execFile2);
|
|
2772
|
+
var HOME = homedir();
|
|
2773
|
+
function claudeNeedsLogin(reason) {
|
|
2774
|
+
return {
|
|
2775
|
+
cli: "claude",
|
|
2776
|
+
state: "needs-login",
|
|
2777
|
+
reason,
|
|
2778
|
+
fixCommand: "claude /login",
|
|
2779
|
+
envFallback: "ANTHROPIC_API_KEY",
|
|
2780
|
+
fixUrl: "https://console.anthropic.com/account/keys"
|
|
2781
|
+
};
|
|
2782
|
+
}
|
|
2783
|
+
function probeClaude() {
|
|
2784
|
+
if (process.env["ANTHROPIC_API_KEY"] !== void 0 && process.env["ANTHROPIC_API_KEY"] !== "") {
|
|
2785
|
+
return { cli: "claude", state: "authenticated", via: "env-var" };
|
|
2786
|
+
}
|
|
2787
|
+
const credPath = join3(HOME, ".claude", ".credentials.json");
|
|
2788
|
+
if (!existsSync(credPath)) {
|
|
2789
|
+
return claudeNeedsLogin(
|
|
2790
|
+
"No credentials at ~/.claude/.credentials.json and ANTHROPIC_API_KEY is not set"
|
|
2791
|
+
);
|
|
2792
|
+
}
|
|
2793
|
+
try {
|
|
2794
|
+
const parsed = JSON.parse(readFileSync(credPath, "utf-8"));
|
|
2795
|
+
if (!isClaudeCredsShape(parsed)) {
|
|
2796
|
+
return claudeNeedsLogin(
|
|
2797
|
+
"Credentials file present but not in expected shape (missing claudeAiOauth.accessToken)"
|
|
2798
|
+
);
|
|
2799
|
+
}
|
|
2800
|
+
const expiresAt = parsed.claudeAiOauth.expiresAt;
|
|
2801
|
+
if (typeof expiresAt === "number" && expiresAt < Date.now()) {
|
|
2802
|
+
return claudeNeedsLogin(`OAuth token expired ${new Date(expiresAt).toISOString()}`);
|
|
2803
|
+
}
|
|
2804
|
+
return {
|
|
2805
|
+
cli: "claude",
|
|
2806
|
+
state: "authenticated",
|
|
2807
|
+
via: "cli-credentials",
|
|
2808
|
+
...typeof expiresAt === "number" ? { meta: { expiresAt } } : {}
|
|
2809
|
+
};
|
|
2810
|
+
} catch (e) {
|
|
2811
|
+
return {
|
|
2812
|
+
cli: "claude",
|
|
2813
|
+
state: "error",
|
|
2814
|
+
reason: `Failed to read claude credentials: ${e instanceof Error ? e.message : String(e)}`
|
|
2815
|
+
};
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
function codexNeedsLogin(reason) {
|
|
2819
|
+
return {
|
|
2820
|
+
cli: "codex",
|
|
2821
|
+
state: "needs-login",
|
|
2822
|
+
reason,
|
|
2823
|
+
fixCommand: "codex login",
|
|
2824
|
+
envFallback: "OPENAI_API_KEY",
|
|
2825
|
+
fixUrl: "https://platform.openai.com/api-keys"
|
|
2826
|
+
};
|
|
2827
|
+
}
|
|
2828
|
+
function classifyCodexStdout(stdout) {
|
|
2829
|
+
if (/not logged/i.test(stdout) || /no.*token/i.test(stdout)) {
|
|
2830
|
+
return codexNeedsLogin(stdout.trim().split("\n")[0] ?? "Not logged in");
|
|
2831
|
+
}
|
|
2832
|
+
return { cli: "codex", state: "authenticated", via: "cli-credentials" };
|
|
2833
|
+
}
|
|
2834
|
+
async function probeCodex() {
|
|
2835
|
+
if (process.env["OPENAI_API_KEY"] !== void 0 && process.env["OPENAI_API_KEY"] !== "") {
|
|
2836
|
+
return { cli: "codex", state: "authenticated", via: "env-var" };
|
|
2837
|
+
}
|
|
2838
|
+
try {
|
|
2839
|
+
const { stdout } = await execFileAsync("codex", ["login", "status"], {
|
|
2840
|
+
timeout: CLI_SUBPROCESS_TIMEOUTS.spawnMs
|
|
2841
|
+
});
|
|
2842
|
+
return classifyCodexStdout(stdout);
|
|
2843
|
+
} catch (e) {
|
|
2844
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
2845
|
+
if (/ENOENT|not found/i.test(msg)) {
|
|
2846
|
+
return { cli: "codex", state: "not-installed", reason: "codex binary not on PATH" };
|
|
2847
|
+
}
|
|
2848
|
+
return codexNeedsLogin("Not logged in (codex login status returned non-zero)");
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2851
|
+
function geminiNeedsLogin(reason) {
|
|
2852
|
+
return {
|
|
2853
|
+
cli: "gemini",
|
|
2854
|
+
state: "needs-login",
|
|
2855
|
+
reason,
|
|
2856
|
+
fixCommand: "gemini",
|
|
2857
|
+
envFallback: "GOOGLE_AI_API_KEY",
|
|
2858
|
+
fixUrl: "https://aistudio.google.com/apikey"
|
|
2859
|
+
};
|
|
2860
|
+
}
|
|
2861
|
+
function classifyGeminiCreds(parsed) {
|
|
2862
|
+
if (!isGeminiCredsShape(parsed)) {
|
|
2863
|
+
return geminiNeedsLogin("OAuth credentials file present but not in expected shape");
|
|
2864
|
+
}
|
|
2865
|
+
if (typeof parsed.expiry_date === "number" && parsed.expiry_date < Date.now()) {
|
|
2866
|
+
return geminiNeedsLogin(
|
|
2867
|
+
`OAuth access token expired ${new Date(parsed.expiry_date).toISOString()} (refresh may still work)`
|
|
2868
|
+
);
|
|
2869
|
+
}
|
|
2870
|
+
return {
|
|
2871
|
+
cli: "gemini",
|
|
2872
|
+
state: "authenticated",
|
|
2873
|
+
via: "cli-credentials",
|
|
2874
|
+
...typeof parsed.expiry_date === "number" ? { meta: { expiresAt: parsed.expiry_date } } : {}
|
|
2875
|
+
};
|
|
2876
|
+
}
|
|
2877
|
+
function probeGemini() {
|
|
2878
|
+
const env = process.env["GOOGLE_AI_API_KEY"] ?? process.env["GEMINI_API_KEY"];
|
|
2879
|
+
if (env !== void 0 && env !== "") {
|
|
2880
|
+
return { cli: "gemini", state: "authenticated", via: "env-var" };
|
|
2881
|
+
}
|
|
2882
|
+
const credPath = join3(HOME, ".gemini", "oauth_creds.json");
|
|
2883
|
+
if (!existsSync(credPath)) {
|
|
2884
|
+
return geminiNeedsLogin(
|
|
2885
|
+
"No OAuth credentials at ~/.gemini/oauth_creds.json and GOOGLE_AI_API_KEY/GEMINI_API_KEY are not set"
|
|
2886
|
+
);
|
|
2887
|
+
}
|
|
2888
|
+
try {
|
|
2889
|
+
return classifyGeminiCreds(JSON.parse(readFileSync(credPath, "utf-8")));
|
|
2890
|
+
} catch (e) {
|
|
2891
|
+
return {
|
|
2892
|
+
cli: "gemini",
|
|
2893
|
+
state: "error",
|
|
2894
|
+
reason: `Failed to read gemini credentials: ${e instanceof Error ? e.message : String(e)}`
|
|
2895
|
+
};
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
async function probeOpencode() {
|
|
2899
|
+
try {
|
|
2900
|
+
const { stdout } = await execFileAsync("opencode", ["auth", "list"], {
|
|
2901
|
+
timeout: CLI_SUBPROCESS_TIMEOUTS.spawnMs
|
|
2902
|
+
});
|
|
2903
|
+
if (/0 credentials/i.test(stdout)) {
|
|
2904
|
+
return {
|
|
2905
|
+
cli: "opencode",
|
|
2906
|
+
state: "needs-login",
|
|
2907
|
+
reason: "No providers configured in opencode",
|
|
2908
|
+
fixCommand: "opencode auth login",
|
|
2909
|
+
fixUrl: "https://opencode.ai/docs/config"
|
|
2910
|
+
};
|
|
2911
|
+
}
|
|
2912
|
+
return { cli: "opencode", state: "authenticated", via: "cli-credentials" };
|
|
2913
|
+
} catch (e) {
|
|
2914
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
2915
|
+
if (/ENOENT|not found/i.test(msg)) {
|
|
2916
|
+
return { cli: "opencode", state: "not-installed", reason: "opencode binary not on PATH" };
|
|
2917
|
+
}
|
|
2918
|
+
return {
|
|
2919
|
+
cli: "opencode",
|
|
2920
|
+
state: "error",
|
|
2921
|
+
reason: msg.split("\n")[0] ?? "opencode auth list failed"
|
|
2922
|
+
};
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
function isClaudeCredsShape(v) {
|
|
2926
|
+
if (typeof v !== "object" || v === null) return false;
|
|
2927
|
+
const oauth = v.claudeAiOauth;
|
|
2928
|
+
if (typeof oauth !== "object" || oauth === null) return false;
|
|
2929
|
+
return typeof oauth.accessToken === "string";
|
|
2930
|
+
}
|
|
2931
|
+
function isGeminiCredsShape(v) {
|
|
2932
|
+
if (typeof v !== "object" || v === null) return false;
|
|
2933
|
+
return typeof v.access_token === "string";
|
|
2934
|
+
}
|
|
2935
|
+
async function probeCli(cli) {
|
|
2936
|
+
switch (cli) {
|
|
2937
|
+
case "claude":
|
|
2938
|
+
return Promise.resolve(probeClaude());
|
|
2939
|
+
case "codex":
|
|
2940
|
+
return probeCodex();
|
|
2941
|
+
case "gemini":
|
|
2942
|
+
return Promise.resolve(probeGemini());
|
|
2943
|
+
case "opencode":
|
|
2944
|
+
return probeOpencode();
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
async function probeAllClis() {
|
|
2948
|
+
const clis = ["claude", "gemini", "codex", "opencode"];
|
|
2949
|
+
return Promise.all(clis.map((c) => probeCli(c)));
|
|
2950
|
+
}
|
|
2951
|
+
|
|
2765
2952
|
// src/cli-adapters/factory.ts
|
|
2766
2953
|
function createCliAdapter(config) {
|
|
2767
2954
|
const options = {
|
|
@@ -2807,11 +2994,22 @@ async function isCliAvailable(cli, cache) {
|
|
|
2807
2994
|
}
|
|
2808
2995
|
try {
|
|
2809
2996
|
const adapter = createCliAdapter({ cli });
|
|
2810
|
-
const health = await adapter.healthCheck();
|
|
2997
|
+
const [health, auth] = await Promise.all([adapter.healthCheck(), probeCli(cli)]);
|
|
2998
|
+
const available = health.healthy && auth.state === "authenticated";
|
|
2811
2999
|
if (cache !== void 0) {
|
|
2812
|
-
|
|
3000
|
+
if (available) {
|
|
3001
|
+
cache.set(cli, CliDetectionCache.fromHealthStatus(health));
|
|
3002
|
+
} else {
|
|
3003
|
+
cache.set(cli, {
|
|
3004
|
+
healthy: false,
|
|
3005
|
+
version: health.version,
|
|
3006
|
+
versionStatus: health.versionStatus,
|
|
3007
|
+
checkedAt: /* @__PURE__ */ new Date(),
|
|
3008
|
+
message: auth.state === "authenticated" ? health.message : `auth: ${auth.state}` + ("reason" in auth ? ` (${auth.reason})` : "")
|
|
3009
|
+
});
|
|
3010
|
+
}
|
|
2813
3011
|
}
|
|
2814
|
-
return
|
|
3012
|
+
return available;
|
|
2815
3013
|
} catch {
|
|
2816
3014
|
if (cache !== void 0) {
|
|
2817
3015
|
cache.set(cli, {
|
|
@@ -2864,9 +3062,11 @@ export {
|
|
|
2864
3062
|
DEFAULT_CACHE_CONFIG,
|
|
2865
3063
|
CliDetectionCache,
|
|
2866
3064
|
createCliDetectionCache,
|
|
3065
|
+
probeCli,
|
|
3066
|
+
probeAllClis,
|
|
2867
3067
|
createCliAdapter,
|
|
2868
3068
|
createAllAdapters,
|
|
2869
3069
|
isCliAvailable,
|
|
2870
3070
|
getAvailableClis
|
|
2871
3071
|
};
|
|
2872
|
-
//# sourceMappingURL=chunk-
|
|
3072
|
+
//# sourceMappingURL=chunk-MV4R2ZIJ.js.map
|