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.
Files changed (27) hide show
  1. package/dist/{chunk-LTUUW3FN.js → chunk-5N7JBWAD.js} +24 -212
  2. package/dist/chunk-5N7JBWAD.js.map +1 -0
  3. package/dist/{chunk-CPPZCNAS.js → chunk-EEW7VFFF.js} +3 -3
  4. package/dist/{chunk-X3BU5MIG.js → chunk-FYAQBYHM.js} +2 -2
  5. package/dist/{chunk-VEF6DCQU.js → chunk-MV4R2ZIJ.js} +204 -4
  6. package/dist/chunk-MV4R2ZIJ.js.map +1 -0
  7. package/dist/{chunk-K446R3BC.js → chunk-NQRC7QQL.js} +17 -9
  8. package/dist/{chunk-K446R3BC.js.map → chunk-NQRC7QQL.js.map} +1 -1
  9. package/dist/{chunk-KGB67HII.js → chunk-QIDO6VPO.js} +5 -3
  10. package/dist/{chunk-KGB67HII.js.map → chunk-QIDO6VPO.js.map} +1 -1
  11. package/dist/cli.d.ts +2 -0
  12. package/dist/cli.js +26 -13
  13. package/dist/cli.js.map +1 -1
  14. package/dist/{consensus-vote-UR3JU7RI.js → consensus-vote-AWBFYF5S.js} +3 -3
  15. package/dist/{expert-bridge-DWBO2HXZ.js → expert-bridge-NX2MGOBQ.js} +2 -2
  16. package/dist/{factory-LXOVC44K.js → factory-JI6PSWGR.js} +2 -2
  17. package/dist/index.js +6 -6
  18. package/dist/{setup-command-XG7R4PR4.js → setup-command-4S7MPK4F.js} +4 -4
  19. package/package.json +1 -1
  20. package/dist/chunk-LTUUW3FN.js.map +0 -1
  21. package/dist/chunk-VEF6DCQU.js.map +0 -1
  22. /package/dist/{chunk-CPPZCNAS.js.map → chunk-EEW7VFFF.js.map} +0 -0
  23. /package/dist/{chunk-X3BU5MIG.js.map → chunk-FYAQBYHM.js.map} +0 -0
  24. /package/dist/{consensus-vote-UR3JU7RI.js.map → consensus-vote-AWBFYF5S.js.map} +0 -0
  25. /package/dist/{expert-bridge-DWBO2HXZ.js.map → expert-bridge-NX2MGOBQ.js.map} +0 -0
  26. /package/dist/{factory-LXOVC44K.js.map → factory-JI6PSWGR.js.map} +0 -0
  27. /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
- cache.set(cli, CliDetectionCache.fromHealthStatus(health));
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 health.healthy;
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-VEF6DCQU.js.map
3072
+ //# sourceMappingURL=chunk-MV4R2ZIJ.js.map