@runneth/cli 0.0.0-sha.d9e3d484bac2.production → 0.0.0-sha.e9a1bd80922c.production

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/README.md CHANGED
@@ -40,7 +40,7 @@ runneth send [--name default] [--timeout-ms 600000] [--stdin] -- <command...>
40
40
  runneth status [--name default]
41
41
  runneth list
42
42
  runneth close [--name default]
43
- runneth oauth login [--resource <url>] [--client-name "Runneth MCP"] [--scope <scope>] [--no-open]
43
+ runneth oauth login [--resource <url>] [--client-id|--clientid <id>] [--client-secret|--secret <value>] [--client-name "Runneth MCP"] [--scope <scope>] [--no-open]
44
44
  runneth oauth status [--resource <url>]
45
45
  runneth oauth logout [--resource <url>]
46
46
  runneth chat --workspace <workspace-id> [--api <builder-url>] [--resource <url>] [--auth mondrian|builder] [--conversation <id>]
@@ -72,12 +72,16 @@ use a different state directory.
72
72
 
73
73
  ## OAuth
74
74
 
75
- `runneth-cli oauth login` performs OAuth protected-resource discovery, dynamic
76
- client registration as a public MCP-style client, PKCE authorization, and token
77
- exchange through a local loopback callback.
75
+ `runneth-cli oauth login` performs OAuth protected-resource discovery, PKCE
76
+ authorization, and token exchange through a local loopback callback. By default
77
+ it uses dynamic client registration as a public MCP-style client. Provide
78
+ `--client-id`/`--clientid` and `--client-secret`/`--secret`, or set
79
+ `RUNNETH_OAUTH_CLIENT_ID` and `RUNNETH_OAUTH_CLIENT_SECRET`, to use a
80
+ pre-registered confidential client instead.
78
81
 
79
82
  ```bash
80
83
  runneth oauth login --resource http://localhost:4100/mcp
84
+ RUNNETH_OAUTH_CLIENT_ID=client-id RUNNETH_OAUTH_CLIENT_SECRET=client-secret runneth oauth login --resource http://localhost:4100/mcp
81
85
  runneth oauth status --resource http://localhost:4100/mcp
82
86
  ```
83
87
 
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { resolveBuildDefaultMcpResourceUrl } from "./build-defaults.js";
3
- import { B as readOAuthCredentialStatus, C as setDefaultRunnethSshTarget, D as runRunnethConversationMachineCommand, I as getOAuthAccessToken, L as loginWithOAuth, M as parseRunnethConversationArgs, N as resolveRunnethConversationOptions, P as runRunnethConversation, R as logoutOAuthCredential, S as saveRunnethSshTarget, T as runRunnethVmCopy, U as resolveSocketPath, _ as resolveRunnethSshTarget, a as normalizeSessionName, b as runOpenSsh, d as installRunnethSshAccess, f as normalizeRunnethSshTargetName, l as installRunnethSkills, m as removeRunnethSshTarget, p as readRunnethSshTargetStore, r as ensureDaemon, s as sendRunnethCliRequest, t as RunnethCliDaemon, w as assertRunnethVmCopyTargetsUseSameResource, x as runRunnethSshProxy } from "./src.js";
3
+ import { B as readOAuthCredentialStatus, C as setDefaultRunnethSshTarget, D as runRunnethConversationMachineCommand, G as resolveSocketPath, L as loginWithOAuth, M as parseRunnethConversationArgs, N as resolveRunnethConversationOptions, P as runRunnethConversation, R as logoutOAuthCredential, S as saveRunnethSshTarget, T as runRunnethVmCopy, U as resolveOAuthToken, V as resolveOAuthClientCredentialOptions, _ as resolveRunnethSshTarget, a as normalizeSessionName, b as runOpenSsh, d as installRunnethSshAccess, f as normalizeRunnethSshTargetName, l as installRunnethSkills, m as removeRunnethSshTarget, p as readRunnethSshTargetStore, r as ensureDaemon, s as sendRunnethCliRequest, t as RunnethCliDaemon, w as assertRunnethVmCopyTargetsUseSameResource, x as runRunnethSshProxy } from "./src.js";
4
4
  import { readFile, rm } from "node:fs/promises";
5
5
  import path from "node:path";
6
6
  import process$1 from "node:process";
@@ -547,8 +547,9 @@ const runRunnethSshStdio = async (options) => {
547
547
  //#region src/cli.ts
548
548
  const DEFAULT_TIMEOUT_MS = 6e5;
549
549
  const DEFAULT_OAUTH_CLIENT_NAME = "Runneth MCP";
550
- const DEFAULT_OAUTH_SCOPE = "openid profile email offline_access";
551
550
  const MAX_STDIN_BYTES = 1048576;
551
+ const RUNNETH_OAUTH_CLIENT_ID_ENV = "RUNNETH_OAUTH_CLIENT_ID";
552
+ const RUNNETH_OAUTH_CLIENT_SECRET_ENV = "RUNNETH_OAUTH_CLIENT_SECRET";
552
553
  const isRecord = (value) => {
553
554
  return typeof value === "object" && value !== null && !Array.isArray(value);
554
555
  };
@@ -620,6 +621,12 @@ const parseNumber = (rawValue, label) => {
620
621
  if (!Number.isInteger(value) || value <= 0) throw new Error(`${label} must be a positive integer`);
621
622
  return value;
622
623
  };
624
+ const resolveCliOAuthClientCredentialOptions = (parsed) => {
625
+ return resolveOAuthClientCredentialOptions({
626
+ clientId: parsed.clientId ?? process$1.env[RUNNETH_OAUTH_CLIENT_ID_ENV],
627
+ clientSecret: parsed.clientSecret ?? process$1.env[RUNNETH_OAUTH_CLIENT_SECRET_ENV]
628
+ });
629
+ };
623
630
  const parseArgs = (argv) => {
624
631
  const values = [];
625
632
  let cwd;
@@ -696,10 +703,12 @@ const parseSkillsArgs = (argv) => {
696
703
  };
697
704
  const parseOAuthArgs = (argv) => {
698
705
  const values = [];
706
+ let clientId;
699
707
  let clientName = DEFAULT_OAUTH_CLIENT_NAME;
708
+ let clientSecret;
700
709
  let openBrowser = true;
701
710
  let resourceUrl;
702
- let scope = DEFAULT_OAUTH_SCOPE;
711
+ let scope;
703
712
  let timeoutMs = DEFAULT_TIMEOUT_MS;
704
713
  let parseOptions = true;
705
714
  for (let index = 0; index < argv.length; index += 1) {
@@ -719,9 +728,17 @@ const parseOAuthArgs = (argv) => {
719
728
  return value;
720
729
  };
721
730
  switch (token) {
731
+ case "--client-id":
732
+ case "--clientid":
733
+ clientId = readValue(token);
734
+ break;
722
735
  case "--client-name":
723
736
  clientName = readValue(token);
724
737
  break;
738
+ case "--client-secret":
739
+ case "--secret":
740
+ clientSecret = readValue(token);
741
+ break;
725
742
  case "--no-open":
726
743
  openBrowser = false;
727
744
  break;
@@ -738,7 +755,9 @@ const parseOAuthArgs = (argv) => {
738
755
  }
739
756
  }
740
757
  return {
758
+ ...clientId === void 0 ? {} : { clientId },
741
759
  clientName,
760
+ ...clientSecret === void 0 ? {} : { clientSecret },
742
761
  openBrowser,
743
762
  resourceUrl,
744
763
  scope,
@@ -748,12 +767,14 @@ const parseOAuthArgs = (argv) => {
748
767
  };
749
768
  const parseSshArgs = (argv) => {
750
769
  const values = [];
770
+ let clientId;
751
771
  let clientName = DEFAULT_OAUTH_CLIENT_NAME;
772
+ let clientSecret;
752
773
  let identityFilePath;
753
774
  let makeDefault = false;
754
775
  let openBrowser = true;
755
776
  let resourceUrl;
756
- let scope = DEFAULT_OAUTH_SCOPE;
777
+ let scope;
757
778
  let sshHost;
758
779
  let sshUrl;
759
780
  let targetName;
@@ -779,9 +800,17 @@ const parseSshArgs = (argv) => {
779
800
  return value;
780
801
  };
781
802
  switch (token) {
803
+ case "--client-id":
804
+ case "--clientid":
805
+ clientId = readValue(token);
806
+ break;
782
807
  case "--client-name":
783
808
  clientName = readValue(token);
784
809
  break;
810
+ case "--client-secret":
811
+ case "--secret":
812
+ clientSecret = readValue(token);
813
+ break;
785
814
  case "--default":
786
815
  makeDefault = true;
787
816
  break;
@@ -817,7 +846,9 @@ const parseSshArgs = (argv) => {
817
846
  }
818
847
  return {
819
848
  argumentSeparatorSeen,
849
+ ...clientId === void 0 ? {} : { clientId },
820
850
  clientName,
851
+ ...clientSecret === void 0 ? {} : { clientSecret },
821
852
  ...identityFilePath === void 0 ? {} : { identityFilePath },
822
853
  makeDefault,
823
854
  openBrowser,
@@ -833,11 +864,13 @@ const parseSshArgs = (argv) => {
833
864
  };
834
865
  const parseCopyArgs = (argv) => {
835
866
  const values = [];
867
+ let clientId;
836
868
  let clientName = DEFAULT_OAUTH_CLIENT_NAME;
869
+ let clientSecret;
837
870
  let destinationTargetName;
838
871
  const ignoredPaths = [];
839
872
  let openBrowser = true;
840
- let scope = DEFAULT_OAUTH_SCOPE;
873
+ let scope;
841
874
  let sourceTargetName;
842
875
  let timeoutMs = DEFAULT_TIMEOUT_MS;
843
876
  let parseOptions = true;
@@ -858,9 +891,17 @@ const parseCopyArgs = (argv) => {
858
891
  return value;
859
892
  };
860
893
  switch (token) {
894
+ case "--client-id":
895
+ case "--clientid":
896
+ clientId = readValue(token);
897
+ break;
861
898
  case "--client-name":
862
899
  clientName = readValue(token);
863
900
  break;
901
+ case "--client-secret":
902
+ case "--secret":
903
+ clientSecret = readValue(token);
904
+ break;
864
905
  case "--from":
865
906
  sourceTargetName = normalizeRunnethSshTargetName(readValue(token));
866
907
  break;
@@ -885,7 +926,9 @@ const parseCopyArgs = (argv) => {
885
926
  if (sourceTargetName === void 0) throw new Error("runneth-cli copy requires --from <target>");
886
927
  if (destinationTargetName === void 0) throw new Error("runneth-cli copy requires --to <target>");
887
928
  return {
929
+ ...clientId === void 0 ? {} : { clientId },
888
930
  clientName,
931
+ ...clientSecret === void 0 ? {} : { clientSecret },
889
932
  destinationTargetName,
890
933
  ignoredPaths,
891
934
  openBrowser,
@@ -1001,12 +1044,12 @@ const resolveSshTargetImportEntries = (input) => {
1001
1044
  });
1002
1045
  };
1003
1046
  const resolveSshOAuthToken = async (parsed, resourceUrl) => {
1004
- if ((await readOAuthCredentialStatus({ resourceUrl })).authenticated) return await getOAuthAccessToken({ resourceUrl });
1005
- return await loginWithOAuth({
1047
+ return await resolveOAuthToken({
1006
1048
  authorizationUrlHandler: (authorizationUrl) => {
1007
1049
  process$1.stderr.write(`Authorize runneth-cli here:\n${authorizationUrl}\n`);
1008
1050
  },
1009
1051
  clientName: parsed.clientName,
1052
+ ...resolveCliOAuthClientCredentialOptions(parsed),
1010
1053
  openBrowser: parsed.openBrowser,
1011
1054
  resourceUrl,
1012
1055
  scope: parsed.scope,
@@ -1091,7 +1134,11 @@ const run = async (argv) => {
1091
1134
  " --workspace <id> Mondrian/Builder workspace id; may also use RUNNETH_WORKSPACE_ID",
1092
1135
  " --token <token> Bearer token override; omitted uses stored OAuth or starts login",
1093
1136
  " --auth <mode> mondrian or builder. Defaults to mondrian",
1137
+ " --client-id, --clientid <id>",
1138
+ " OAuth client id; may use RUNNETH_OAUTH_CLIENT_ID",
1094
1139
  " --client-name <name> OAuth dynamic client name. Defaults to Runneth MCP",
1140
+ " --client-secret, --secret <value>",
1141
+ " OAuth client secret; prefer RUNNETH_OAUTH_CLIENT_SECRET",
1095
1142
  " --conversation <id> Resume an existing conversation",
1096
1143
  " --no-open Print the OAuth URL instead of opening a browser",
1097
1144
  " --scope <scope> OAuth scope. Defaults to openid profile email offline_access",
@@ -1102,6 +1149,7 @@ const run = async (argv) => {
1102
1149
  "",
1103
1150
  "Environment:",
1104
1151
  " RUNNETH_API_URL, RUNNETH_RESOURCE_URL, RUNNETH_WORKSPACE_ID",
1152
+ " RUNNETH_OAUTH_CLIENT_ID, RUNNETH_OAUTH_CLIENT_SECRET",
1105
1153
  " RUNNETH_TOKEN, MONDRIAN_TOKEN, BUILDER_AGENT_CHAT_TOKEN",
1106
1154
  "",
1107
1155
  "Commands inside chat:",
@@ -1128,7 +1176,11 @@ const run = async (argv) => {
1128
1176
  "Usage: runneth-cli oauth <login|status|logout> [--resource <url>] [options]",
1129
1177
  "",
1130
1178
  "Options:",
1179
+ " --client-id, --clientid <id>",
1180
+ " OAuth client id; may use RUNNETH_OAUTH_CLIENT_ID",
1131
1181
  " --client-name <name> Dynamic OAuth client name",
1182
+ " --client-secret, --secret <val>",
1183
+ " OAuth client secret; prefer RUNNETH_OAUTH_CLIENT_SECRET",
1132
1184
  " --no-open Print the authorization URL without opening a browser",
1133
1185
  " --resource <url> OAuth-protected MCP resource URL, defaults to build MONDRIAN_API_URL/mcp",
1134
1186
  " --scope <scope> OAuth scopes",
@@ -1145,6 +1197,7 @@ const run = async (argv) => {
1145
1197
  process$1.stderr.write(`Authorize runneth-cli here:\n${authorizationUrl}\n`);
1146
1198
  },
1147
1199
  clientName: parsed.clientName,
1200
+ ...resolveCliOAuthClientCredentialOptions(parsed),
1148
1201
  openBrowser: parsed.openBrowser,
1149
1202
  resourceUrl,
1150
1203
  scope: parsed.scope,
@@ -1191,7 +1244,11 @@ const run = async (argv) => {
1191
1244
  " --from <target> Source SSH target name",
1192
1245
  " --to <target> Destination SSH target name",
1193
1246
  " --ignore <path> Additional relative folder/path to skip; node_modules is skipped by default",
1247
+ " --client-id, --clientid <id>",
1248
+ " OAuth client id; may use RUNNETH_OAUTH_CLIENT_ID",
1194
1249
  " --client-name <name> Dynamic OAuth client name",
1250
+ " --client-secret, --secret <val>",
1251
+ " OAuth client secret; prefer RUNNETH_OAUTH_CLIENT_SECRET",
1195
1252
  " --no-open Print the authorization URL without opening a browser",
1196
1253
  " --scope <scope> OAuth scopes",
1197
1254
  " --timeout-ms <ms> Copy command timeout",
@@ -1270,7 +1327,11 @@ const run = async (argv) => {
1270
1327
  " target Manage named Runneth SSH VM targets",
1271
1328
  "",
1272
1329
  "Options:",
1330
+ " --client-id, --clientid <id>",
1331
+ " OAuth client id; may use RUNNETH_OAUTH_CLIENT_ID",
1273
1332
  " --client-name <name> Dynamic OAuth client name",
1333
+ " --client-secret, --secret <val>",
1334
+ " OAuth client secret; prefer RUNNETH_OAUTH_CLIENT_SECRET",
1274
1335
  " --no-open Print the authorization URL without opening a browser",
1275
1336
  " --resource <url> OAuth-protected MCP resource URL, defaults to build MONDRIAN_API_URL/mcp when using --host or --ssh-url",
1276
1337
  " --scope <scope> OAuth scopes",