@runneth/cli 0.0.0-sha.cf0e2f4e39c3.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 +8 -4
- package/dist/cli.js +68 -7
- package/dist/index.d.ts +17 -5
- package/dist/index.js +2 -2
- package/dist/src.js +387 -29
- package/package.json +1 -1
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,
|
|
76
|
-
|
|
77
|
-
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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",
|
package/dist/index.d.ts
CHANGED
|
@@ -7965,12 +7965,14 @@ type RunnethConversationOptions = Readonly<{
|
|
|
7965
7965
|
type RunnethConversationParsedOptions = Readonly<{
|
|
7966
7966
|
apiBaseUrl?: string;
|
|
7967
7967
|
authMode: RunnethConversationAuthMode;
|
|
7968
|
+
clientId?: string;
|
|
7968
7969
|
clientName: string;
|
|
7970
|
+
clientSecret?: string;
|
|
7969
7971
|
conversationId?: string;
|
|
7970
7972
|
openBrowser: boolean;
|
|
7971
7973
|
pollIntervalMs: number;
|
|
7972
7974
|
resourceUrl?: string;
|
|
7973
|
-
scope
|
|
7975
|
+
scope?: string;
|
|
7974
7976
|
tenanthId: string;
|
|
7975
7977
|
title?: string;
|
|
7976
7978
|
token?: string;
|
|
@@ -8042,18 +8044,20 @@ declare const runRunnethConversationMachineCommand: ({
|
|
|
8042
8044
|
//#endregion
|
|
8043
8045
|
//#region src/oauth.d.ts
|
|
8044
8046
|
type OAuthTokenEndpointAuthMethod = "client_secret_basic" | "client_secret_post" | "none";
|
|
8047
|
+
type OAuthGrantType = "authorization_code" | "client_credentials";
|
|
8045
8048
|
type OAuthClientRegistration = Readonly<{
|
|
8046
8049
|
clientId: string;
|
|
8047
8050
|
clientName: string;
|
|
8048
8051
|
clientSecret?: string;
|
|
8049
|
-
redirectUri
|
|
8052
|
+
redirectUri?: string;
|
|
8050
8053
|
tokenEndpointAuthMethod: OAuthTokenEndpointAuthMethod;
|
|
8051
8054
|
}>;
|
|
8052
8055
|
type OAuthServerMetadata = Readonly<{
|
|
8053
8056
|
authorizationEndpoint: string;
|
|
8054
8057
|
issuer: string;
|
|
8055
|
-
registrationEndpoint
|
|
8058
|
+
registrationEndpoint?: string;
|
|
8056
8059
|
tokenEndpoint: string;
|
|
8060
|
+
tokenEndpointAuthMethodsSupported?: readonly OAuthTokenEndpointAuthMethod[];
|
|
8057
8061
|
}>;
|
|
8058
8062
|
type OAuthStoredToken = Readonly<{
|
|
8059
8063
|
accessToken: string;
|
|
@@ -8067,9 +8071,10 @@ type OAuthStoredCredential = Readonly<{
|
|
|
8067
8071
|
authorizationServer: OAuthServerMetadata;
|
|
8068
8072
|
client: OAuthClientRegistration;
|
|
8069
8073
|
createdAt: string;
|
|
8074
|
+
grantType: OAuthGrantType;
|
|
8070
8075
|
requestedResourceUrl: string;
|
|
8071
8076
|
resource: string;
|
|
8072
|
-
scope
|
|
8077
|
+
scope?: string;
|
|
8073
8078
|
token: OAuthStoredToken;
|
|
8074
8079
|
updatedAt: string;
|
|
8075
8080
|
version: 1;
|
|
@@ -8086,7 +8091,9 @@ type OAuthCredentialStatus = Readonly<{
|
|
|
8086
8091
|
}>;
|
|
8087
8092
|
type OAuthLoginOptions = Readonly<{
|
|
8088
8093
|
authorizationUrlHandler?: (authorizationUrl: string) => Promise<void> | void;
|
|
8094
|
+
clientId?: string;
|
|
8089
8095
|
clientName?: string;
|
|
8096
|
+
clientSecret?: string;
|
|
8090
8097
|
homePath?: string;
|
|
8091
8098
|
openBrowser?: boolean;
|
|
8092
8099
|
resourceUrl: string;
|
|
@@ -8100,10 +8107,15 @@ type OAuthTokenResult = Readonly<{
|
|
|
8100
8107
|
expiresAt?: string;
|
|
8101
8108
|
tokenType: string;
|
|
8102
8109
|
}>;
|
|
8110
|
+
type OAuthClientCredentialOptions = Readonly<{
|
|
8111
|
+
clientId?: string;
|
|
8112
|
+
clientSecret?: string;
|
|
8113
|
+
}>;
|
|
8103
8114
|
declare const resolveOAuthCredentialPath: (input: {
|
|
8104
8115
|
readonly homePath?: string;
|
|
8105
8116
|
readonly resourceUrl: string;
|
|
8106
8117
|
}) => string;
|
|
8118
|
+
declare const resolveOAuthClientCredentialOptions: (input: OAuthClientCredentialOptions) => OAuthClientCredentialOptions;
|
|
8107
8119
|
declare const readOAuthCredential: (input: {
|
|
8108
8120
|
readonly homePath?: string;
|
|
8109
8121
|
readonly resourceUrl: string;
|
|
@@ -8403,4 +8415,4 @@ declare const ensureDaemon: (input: {
|
|
|
8403
8415
|
readonly socketPath: string;
|
|
8404
8416
|
}) => Promise<void>;
|
|
8405
8417
|
//#endregion
|
|
8406
|
-
export { type OAuthClientRegistration, type OAuthCredentialStatus, type OAuthLoginOptions, type OAuthServerMetadata, type OAuthStoredCredential, type OAuthStoredToken, type OAuthTokenEndpointAuthMethod, type OAuthTokenResult, type OpenSshOptions, RUNNETH_CONVERSATION_DEFAULT_POLL_INTERVAL_MS, type ResolvedRunnethSshTarget, RunnethCliDaemon, RunnethCliDaemonOptions, RunnethCliPublicSession, RunnethCliRequest, RunnethCliResponse, type RunnethConversationAuthMode, type RunnethConversationMachineCommandOptions, type RunnethConversationOptions, type RunnethConversationParsedOptions, type RunnethConversationState, type RunnethSkillAgent, type RunnethSkillInstallOptions, type RunnethSkillInstallResult, type RunnethSkillInstallTarget, type RunnethSshAppMetadata, type RunnethSshGeneratedKeyMode, type RunnethSshInstallResponse, type RunnethSshKeyMode, type RunnethSshKeyPaths, type RunnethSshProxyOptions, type RunnethSshProxyStreams, type RunnethSshSetupOptions, type RunnethSshSetupResult, type RunnethSshTarget, type RunnethSshTargetPaths, type RunnethSshTargetStore, type RunnethVmCopyOptions, type RunnethVmCopyResult, assertRunnethVmCopyTargetsUseSameResource, createCommandEnvelope, createConversation as createRunnethConversation, ensureDaemon, extractCommandResult, fetchConversationState as fetchRunnethConversationState, getOAuthAccessToken, installRunnethSkills, installRunnethSshAccess, loginWithOAuth, logoutOAuthCredential, normalizeRunnethApiBaseUrl, normalizeRunnethSshTargetName, normalizeSessionName, parseRunnethCliRequest, parseRunnethConversationArgs, parseRunnethConversationSessionRequest, readOAuthCredential, readOAuthCredentialStatus, readRunnethSshTargetStore, removeRunnethSshTarget, resolveBundledRunnethSkillPath, resolveOAuthCredentialPath, resolveRunnethCliHome, resolveRunnethConversationOptions, resolveRunnethSshAppUrl, resolveRunnethSshSharedKeyPaths, resolveRunnethSshTarget, resolveRunnethSshTargetPaths, resolveRunnethSshTargetsPath, resolveSocketPath, runOpenSsh, runRunnethConversation, runRunnethConversationMachineCommand, runRunnethSshProxy, runRunnethVmCopy, saveRunnethSshTarget, sendRunnethCliRequest, sendMessage as sendRunnethConversationMessage, setDefaultRunnethSshTarget, startDaemonProcess };
|
|
8418
|
+
export { type OAuthClientCredentialOptions, type OAuthClientRegistration, type OAuthCredentialStatus, type OAuthGrantType, type OAuthLoginOptions, type OAuthServerMetadata, type OAuthStoredCredential, type OAuthStoredToken, type OAuthTokenEndpointAuthMethod, type OAuthTokenResult, type OpenSshOptions, RUNNETH_CONVERSATION_DEFAULT_POLL_INTERVAL_MS, type ResolvedRunnethSshTarget, RunnethCliDaemon, RunnethCliDaemonOptions, RunnethCliPublicSession, RunnethCliRequest, RunnethCliResponse, type RunnethConversationAuthMode, type RunnethConversationMachineCommandOptions, type RunnethConversationOptions, type RunnethConversationParsedOptions, type RunnethConversationState, type RunnethSkillAgent, type RunnethSkillInstallOptions, type RunnethSkillInstallResult, type RunnethSkillInstallTarget, type RunnethSshAppMetadata, type RunnethSshGeneratedKeyMode, type RunnethSshInstallResponse, type RunnethSshKeyMode, type RunnethSshKeyPaths, type RunnethSshProxyOptions, type RunnethSshProxyStreams, type RunnethSshSetupOptions, type RunnethSshSetupResult, type RunnethSshTarget, type RunnethSshTargetPaths, type RunnethSshTargetStore, type RunnethVmCopyOptions, type RunnethVmCopyResult, assertRunnethVmCopyTargetsUseSameResource, createCommandEnvelope, createConversation as createRunnethConversation, ensureDaemon, extractCommandResult, fetchConversationState as fetchRunnethConversationState, getOAuthAccessToken, installRunnethSkills, installRunnethSshAccess, loginWithOAuth, logoutOAuthCredential, normalizeRunnethApiBaseUrl, normalizeRunnethSshTargetName, normalizeSessionName, parseRunnethCliRequest, parseRunnethConversationArgs, parseRunnethConversationSessionRequest, readOAuthCredential, readOAuthCredentialStatus, readRunnethSshTargetStore, removeRunnethSshTarget, resolveBundledRunnethSkillPath, resolveOAuthClientCredentialOptions, resolveOAuthCredentialPath, resolveRunnethCliHome, resolveRunnethConversationOptions, resolveRunnethSshAppUrl, resolveRunnethSshSharedKeyPaths, resolveRunnethSshTarget, resolveRunnethSshTargetPaths, resolveRunnethSshTargetsPath, resolveSocketPath, runOpenSsh, runRunnethConversation, runRunnethConversationMachineCommand, runRunnethSshProxy, runRunnethVmCopy, saveRunnethSshTarget, sendRunnethCliRequest, sendMessage as sendRunnethConversationMessage, setDefaultRunnethSshTarget, startDaemonProcess };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as fetchConversationState, B as readOAuthCredentialStatus, C as setDefaultRunnethSshTarget, D as runRunnethConversationMachineCommand, E as parseRunnethConversationSessionRequest, F as sendMessage, H as
|
|
2
|
-
export { RUNNETH_CONVERSATION_DEFAULT_POLL_INTERVAL_MS, RunnethCliDaemon, assertRunnethVmCopyTargetsUseSameResource, createCommandEnvelope, createConversation as createRunnethConversation, ensureDaemon, extractCommandResult, fetchConversationState as fetchRunnethConversationState, getOAuthAccessToken, installRunnethSkills, installRunnethSshAccess, loginWithOAuth, logoutOAuthCredential, normalizeRunnethApiBaseUrl, normalizeRunnethSshTargetName, normalizeSessionName, parseRunnethCliRequest, parseRunnethConversationArgs, parseRunnethConversationSessionRequest, readOAuthCredential, readOAuthCredentialStatus, readRunnethSshTargetStore, removeRunnethSshTarget, resolveBundledRunnethSkillPath, resolveOAuthCredentialPath, resolveRunnethCliHome, resolveRunnethConversationOptions, resolveRunnethSshAppUrl, resolveRunnethSshSharedKeyPaths, resolveRunnethSshTarget, resolveRunnethSshTargetPaths, resolveRunnethSshTargetsPath, resolveSocketPath, runOpenSsh, runRunnethConversation, runRunnethConversationMachineCommand, runRunnethSshProxy, runRunnethVmCopy, saveRunnethSshTarget, sendRunnethCliRequest, sendMessage as sendRunnethConversationMessage, setDefaultRunnethSshTarget, startDaemonProcess };
|
|
1
|
+
import { A as fetchConversationState, B as readOAuthCredentialStatus, C as setDefaultRunnethSshTarget, D as runRunnethConversationMachineCommand, E as parseRunnethConversationSessionRequest, F as sendMessage, G as resolveSocketPath, H as resolveOAuthCredentialPath, I as getOAuthAccessToken, L as loginWithOAuth, M as parseRunnethConversationArgs, N as resolveRunnethConversationOptions, O as RUNNETH_CONVERSATION_DEFAULT_POLL_INTERVAL_MS, P as runRunnethConversation, R as logoutOAuthCredential, S as saveRunnethSshTarget, T as runRunnethVmCopy, V as resolveOAuthClientCredentialOptions, W as resolveRunnethCliHome, _ as resolveRunnethSshTarget, a as normalizeSessionName, b as runOpenSsh, c as startDaemonProcess, d as installRunnethSshAccess, f as normalizeRunnethSshTargetName, g as resolveRunnethSshSharedKeyPaths, h as resolveRunnethSshAppUrl, i as extractCommandResult, j as normalizeRunnethApiBaseUrl, k as createConversation, l as installRunnethSkills, m as removeRunnethSshTarget, n as createCommandEnvelope, o as parseRunnethCliRequest, p as readRunnethSshTargetStore, r as ensureDaemon, s as sendRunnethCliRequest, t as RunnethCliDaemon, u as resolveBundledRunnethSkillPath, v as resolveRunnethSshTargetPaths, w as assertRunnethVmCopyTargetsUseSameResource, x as runRunnethSshProxy, y as resolveRunnethSshTargetsPath, z as readOAuthCredential } from "./src.js";
|
|
2
|
+
export { RUNNETH_CONVERSATION_DEFAULT_POLL_INTERVAL_MS, RunnethCliDaemon, assertRunnethVmCopyTargetsUseSameResource, createCommandEnvelope, createConversation as createRunnethConversation, ensureDaemon, extractCommandResult, fetchConversationState as fetchRunnethConversationState, getOAuthAccessToken, installRunnethSkills, installRunnethSshAccess, loginWithOAuth, logoutOAuthCredential, normalizeRunnethApiBaseUrl, normalizeRunnethSshTargetName, normalizeSessionName, parseRunnethCliRequest, parseRunnethConversationArgs, parseRunnethConversationSessionRequest, readOAuthCredential, readOAuthCredentialStatus, readRunnethSshTargetStore, removeRunnethSshTarget, resolveBundledRunnethSkillPath, resolveOAuthClientCredentialOptions, resolveOAuthCredentialPath, resolveRunnethCliHome, resolveRunnethConversationOptions, resolveRunnethSshAppUrl, resolveRunnethSshSharedKeyPaths, resolveRunnethSshTarget, resolveRunnethSshTargetPaths, resolveRunnethSshTargetsPath, resolveSocketPath, runOpenSsh, runRunnethConversation, runRunnethConversationMachineCommand, runRunnethSshProxy, runRunnethVmCopy, saveRunnethSshTarget, sendRunnethCliRequest, sendMessage as sendRunnethConversationMessage, setDefaultRunnethSshTarget, startDaemonProcess };
|
package/dist/src.js
CHANGED
|
@@ -4402,6 +4402,7 @@ const routineRunFailureReasonSchema = _enum([
|
|
|
4402
4402
|
"stopped"
|
|
4403
4403
|
]);
|
|
4404
4404
|
const routineRunSkipReasonSchema = _enum(["backlog_capped", "run_in_progress"]);
|
|
4405
|
+
const routineModeSchema = _enum(["agent", "script"]);
|
|
4405
4406
|
const isCanonicalUtcIso = (value) => {
|
|
4406
4407
|
const date = new Date(value);
|
|
4407
4408
|
return !Number.isNaN(date.getTime()) && date.toISOString() === value;
|
|
@@ -4472,7 +4473,9 @@ const routineBaseSchema = object({
|
|
|
4472
4473
|
owner: object({ id: string().uuid() }).strict().nullable(),
|
|
4473
4474
|
createdAt: utcDateTimeSchema,
|
|
4474
4475
|
delivery: routineDeliverySchema,
|
|
4476
|
+
failStreak: number$1().int().min(0).nullable().default(null),
|
|
4475
4477
|
lastRunAt: utcDateTimeSchema.nullable(),
|
|
4478
|
+
mode: routineModeSchema.default("agent"),
|
|
4476
4479
|
name: routineNameSchema,
|
|
4477
4480
|
nextRunAt: utcDateTimeSchema.nullable(),
|
|
4478
4481
|
occurrenceCount: number$1().int().min(0),
|
|
@@ -4494,11 +4497,27 @@ const validateRoutine = (routine, ctx) => {
|
|
|
4494
4497
|
message: "non-active routines must not have nextRunAt",
|
|
4495
4498
|
path: ["nextRunAt"]
|
|
4496
4499
|
});
|
|
4500
|
+
if (routine.mode === "script" !== (routine.failStreak !== null)) ctx.addIssue({
|
|
4501
|
+
code: "custom",
|
|
4502
|
+
message: "script mode requires a failStreak",
|
|
4503
|
+
path: ["failStreak"]
|
|
4504
|
+
});
|
|
4497
4505
|
};
|
|
4498
4506
|
routineBaseSchema.strict().superRefine(validateRoutine);
|
|
4499
4507
|
const routineResponseSchema = routineBaseSchema.strict().superRefine(validateRoutine);
|
|
4508
|
+
const routineV1ResponseSchema = routineBaseSchema.omit({
|
|
4509
|
+
failStreak: true,
|
|
4510
|
+
mode: true
|
|
4511
|
+
}).strict().superRefine((routine, ctx) => {
|
|
4512
|
+
validateRoutine({
|
|
4513
|
+
...routine,
|
|
4514
|
+
failStreak: null,
|
|
4515
|
+
mode: "agent"
|
|
4516
|
+
}, ctx);
|
|
4517
|
+
});
|
|
4500
4518
|
const routineRunBaseSchema = object({
|
|
4501
4519
|
createdAt: utcDateTimeSchema,
|
|
4520
|
+
executor: routineModeSchema.nullable().default(null),
|
|
4502
4521
|
failureReason: routineRunFailureReasonSchema.nullable(),
|
|
4503
4522
|
finishedAt: utcDateTimeSchema.nullable(),
|
|
4504
4523
|
missedOccurrenceCount: number$1().int().min(0),
|
|
@@ -4506,6 +4525,7 @@ const routineRunBaseSchema = object({
|
|
|
4506
4525
|
routineId: routineIdSchema,
|
|
4507
4526
|
runId: string().uuid(),
|
|
4508
4527
|
scheduledFor: utcDateTimeSchema,
|
|
4528
|
+
scriptError: string().trim().min(1).nullable().default(null),
|
|
4509
4529
|
skipReason: routineRunSkipReasonSchema.nullable(),
|
|
4510
4530
|
status: routineRunStatusSchema,
|
|
4511
4531
|
submittedAt: utcDateTimeSchema.nullable(),
|
|
@@ -4520,14 +4540,14 @@ const validateRoutineRun = (run, ctx) => {
|
|
|
4520
4540
|
message: "completed runs require submittedAt",
|
|
4521
4541
|
path: ["submittedAt"]
|
|
4522
4542
|
});
|
|
4523
|
-
if (run.outcome === null) ctx.addIssue({
|
|
4543
|
+
if (run.executor !== "script" && run.outcome === null) ctx.addIssue({
|
|
4524
4544
|
code: "custom",
|
|
4525
|
-
message: "completed runs require an outcome",
|
|
4545
|
+
message: "completed agent runs require an outcome",
|
|
4526
4546
|
path: ["outcome"]
|
|
4527
4547
|
});
|
|
4528
|
-
if (run.summary === null) ctx.addIssue({
|
|
4548
|
+
if (run.executor !== "script" && run.summary === null) ctx.addIssue({
|
|
4529
4549
|
code: "custom",
|
|
4530
|
-
message: "completed runs require a summary",
|
|
4550
|
+
message: "completed agent runs require a summary",
|
|
4531
4551
|
path: ["summary"]
|
|
4532
4552
|
});
|
|
4533
4553
|
if (run.failureReason !== null) ctx.addIssue({
|
|
@@ -4634,6 +4654,40 @@ const validateRoutineRun = (run, ctx) => {
|
|
|
4634
4654
|
path: ["skipReason"]
|
|
4635
4655
|
});
|
|
4636
4656
|
}
|
|
4657
|
+
if (run.executor === "script") {
|
|
4658
|
+
if (run.scriptError !== null) ctx.addIssue({
|
|
4659
|
+
code: "custom",
|
|
4660
|
+
message: "script-executed runs must not carry scriptError",
|
|
4661
|
+
path: ["scriptError"]
|
|
4662
|
+
});
|
|
4663
|
+
if (run.outcome !== null) ctx.addIssue({
|
|
4664
|
+
code: "custom",
|
|
4665
|
+
message: "script-executed runs must not have outcome",
|
|
4666
|
+
path: ["outcome"]
|
|
4667
|
+
});
|
|
4668
|
+
if (run.summary !== null) ctx.addIssue({
|
|
4669
|
+
code: "custom",
|
|
4670
|
+
message: "script-executed runs must not have summary",
|
|
4671
|
+
path: ["summary"]
|
|
4672
|
+
});
|
|
4673
|
+
}
|
|
4674
|
+
if (run.status === "scheduled" && run.executor !== null) ctx.addIssue({
|
|
4675
|
+
code: "custom",
|
|
4676
|
+
message: "scheduled runs must not have an executor",
|
|
4677
|
+
path: ["executor"]
|
|
4678
|
+
});
|
|
4679
|
+
if (run.status === "skipped") {
|
|
4680
|
+
if (run.executor !== null) ctx.addIssue({
|
|
4681
|
+
code: "custom",
|
|
4682
|
+
message: "skipped runs must not have an executor",
|
|
4683
|
+
path: ["executor"]
|
|
4684
|
+
});
|
|
4685
|
+
if (run.scriptError !== null) ctx.addIssue({
|
|
4686
|
+
code: "custom",
|
|
4687
|
+
message: "skipped runs must not have scriptError",
|
|
4688
|
+
path: ["scriptError"]
|
|
4689
|
+
});
|
|
4690
|
+
}
|
|
4637
4691
|
if ((run.status === "completed" || run.status === "failed" || run.status === "skipped" || run.status === "canceled") && run.finishedAt === null) ctx.addIssue({
|
|
4638
4692
|
code: "custom",
|
|
4639
4693
|
message: "terminal runs require finishedAt",
|
|
@@ -4647,14 +4701,41 @@ const validateRoutineRun = (run, ctx) => {
|
|
|
4647
4701
|
};
|
|
4648
4702
|
routineRunBaseSchema.strict().superRefine(validateRoutineRun);
|
|
4649
4703
|
const routineRunResponseSchema = routineRunBaseSchema.strict().superRefine(validateRoutineRun);
|
|
4704
|
+
const routineRunV1BaseSchema = routineRunBaseSchema.omit({
|
|
4705
|
+
executor: true,
|
|
4706
|
+
scriptError: true
|
|
4707
|
+
});
|
|
4708
|
+
const routineRunV1ResponseSchema = routineRunV1BaseSchema.strict().superRefine((run, ctx) => {
|
|
4709
|
+
validateRoutineRun({
|
|
4710
|
+
...run,
|
|
4711
|
+
executor: null,
|
|
4712
|
+
scriptError: null
|
|
4713
|
+
}, ctx);
|
|
4714
|
+
});
|
|
4650
4715
|
const routineManualRunResponseSchema = routineRunBaseSchema.extend({ trigger: literal("manual") }).strict().superRefine(validateRoutineRun);
|
|
4716
|
+
const routineManualRunV1ResponseSchema = routineRunV1BaseSchema.extend({ trigger: literal("manual") }).strict().superRefine((run, ctx) => {
|
|
4717
|
+
validateRoutineRun({
|
|
4718
|
+
...run,
|
|
4719
|
+
executor: null,
|
|
4720
|
+
scriptError: null
|
|
4721
|
+
}, ctx);
|
|
4722
|
+
});
|
|
4651
4723
|
object({ status: routineStatusSchema.optional() }).strict();
|
|
4652
4724
|
object({
|
|
4653
4725
|
cursor: string().trim().min(1).nullable().optional(),
|
|
4654
4726
|
pageSize: number().int().min(1).max(100).optional()
|
|
4655
4727
|
}).strict();
|
|
4656
4728
|
object({ routines: array(routineResponseSchema) }).strict();
|
|
4657
|
-
object({
|
|
4729
|
+
object({
|
|
4730
|
+
routine: routineResponseSchema,
|
|
4731
|
+
script: string().nullable().default(null)
|
|
4732
|
+
}).strict().superRefine((response, ctx) => {
|
|
4733
|
+
if (response.routine.mode === "script" !== (response.script !== null)) ctx.addIssue({
|
|
4734
|
+
code: "custom",
|
|
4735
|
+
message: "script content must be attached exactly for script-mode routines",
|
|
4736
|
+
path: ["script"]
|
|
4737
|
+
});
|
|
4738
|
+
});
|
|
4658
4739
|
object({
|
|
4659
4740
|
nextCursor: string().nullable(),
|
|
4660
4741
|
runs: array(routineRunResponseSchema)
|
|
@@ -4663,6 +4744,16 @@ object({
|
|
|
4663
4744
|
routine: routineResponseSchema,
|
|
4664
4745
|
run: routineManualRunResponseSchema
|
|
4665
4746
|
}).strict();
|
|
4747
|
+
object({ routines: array(routineV1ResponseSchema) }).strict();
|
|
4748
|
+
object({ routine: routineV1ResponseSchema }).strict();
|
|
4749
|
+
object({
|
|
4750
|
+
nextCursor: string().nullable(),
|
|
4751
|
+
runs: array(routineRunV1ResponseSchema)
|
|
4752
|
+
}).strict();
|
|
4753
|
+
object({
|
|
4754
|
+
routine: routineV1ResponseSchema,
|
|
4755
|
+
run: routineManualRunV1ResponseSchema
|
|
4756
|
+
}).strict();
|
|
4666
4757
|
//#endregion
|
|
4667
4758
|
//#region ../agent-protocol/dist/agent-events.js
|
|
4668
4759
|
const baseEventSchema = object({
|
|
@@ -4822,6 +4913,11 @@ const slackVisibilityEventSchema = object({
|
|
|
4822
4913
|
status: _enum(["preparing_output", "no_response"]),
|
|
4823
4914
|
toolUseId: string().min(1).optional()
|
|
4824
4915
|
}).merge(baseEventSchema);
|
|
4916
|
+
const slackSilenceRejectedEventSchema = object({
|
|
4917
|
+
type: literal("slack_silence_rejected"),
|
|
4918
|
+
toolUseId: string().min(1),
|
|
4919
|
+
reason: string().min(1).optional()
|
|
4920
|
+
}).merge(baseEventSchema);
|
|
4825
4921
|
const toolCallEventSchema = object({
|
|
4826
4922
|
type: literal("tool_call"),
|
|
4827
4923
|
toolUseId: string(),
|
|
@@ -4931,6 +5027,7 @@ const completeEventSchema = object({
|
|
|
4931
5027
|
outcome: routineRunOutcomeSchema,
|
|
4932
5028
|
summary: string().trim().min(1)
|
|
4933
5029
|
}).strict().optional(),
|
|
5030
|
+
nudged: boolean().optional(),
|
|
4934
5031
|
error: string().optional()
|
|
4935
5032
|
}).merge(baseEventSchema);
|
|
4936
5033
|
const stoppedEventSchema = object({
|
|
@@ -4963,6 +5060,7 @@ discriminatedUnion("type", [
|
|
|
4963
5060
|
harnessTraceEventSchema,
|
|
4964
5061
|
widgetEventSchema,
|
|
4965
5062
|
slackVisibilityEventSchema,
|
|
5063
|
+
slackSilenceRejectedEventSchema,
|
|
4966
5064
|
toolCallEventSchema,
|
|
4967
5065
|
toolResultEventSchema,
|
|
4968
5066
|
cliToolEventSchema,
|
|
@@ -4984,6 +5082,38 @@ discriminatedUnion("type", [
|
|
|
4984
5082
|
toolName: _undefined().optional()
|
|
4985
5083
|
}).strict()])
|
|
4986
5084
|
]);
|
|
5085
|
+
const runnethProtocolSchema = _enum([
|
|
5086
|
+
"chat",
|
|
5087
|
+
"relay",
|
|
5088
|
+
"events",
|
|
5089
|
+
"control",
|
|
5090
|
+
"stream"
|
|
5091
|
+
]);
|
|
5092
|
+
const protocolVersionsSchema = array(number$1().int().positive()).min(1);
|
|
5093
|
+
const runnethChatVersionSchema = union([
|
|
5094
|
+
literal(1),
|
|
5095
|
+
literal(2),
|
|
5096
|
+
literal(3),
|
|
5097
|
+
literal(4),
|
|
5098
|
+
literal(5),
|
|
5099
|
+
literal(6)
|
|
5100
|
+
]);
|
|
5101
|
+
object({
|
|
5102
|
+
chat: protocolVersionsSchema,
|
|
5103
|
+
relay: protocolVersionsSchema,
|
|
5104
|
+
events: protocolVersionsSchema,
|
|
5105
|
+
control: protocolVersionsSchema
|
|
5106
|
+
}).strict();
|
|
5107
|
+
object({
|
|
5108
|
+
protocol: runnethProtocolSchema,
|
|
5109
|
+
version: number$1().int().positive()
|
|
5110
|
+
}).strict();
|
|
5111
|
+
object({
|
|
5112
|
+
protocol: runnethProtocolSchema,
|
|
5113
|
+
version: string().trim().regex(/^[1-9]\d*$/u).transform((value) => {
|
|
5114
|
+
return Number.parseInt(value, 10);
|
|
5115
|
+
}).pipe(number$1().int().positive())
|
|
5116
|
+
}).strict();
|
|
4987
5117
|
//#endregion
|
|
4988
5118
|
//#region ../agent-protocol/dist/agent-chat-events.js
|
|
4989
5119
|
const uuidSchema$1 = string().uuid();
|
|
@@ -5276,6 +5406,7 @@ object({
|
|
|
5276
5406
|
]),
|
|
5277
5407
|
content: jsonValueSchema,
|
|
5278
5408
|
sequenceNumber: number$1().int().positive(),
|
|
5409
|
+
runnethChatVersion: runnethChatVersionSchema.optional(),
|
|
5279
5410
|
sourceSeq: number$1().int().positive().optional(),
|
|
5280
5411
|
toolUseId: string().nullable(),
|
|
5281
5412
|
createdDate: string(),
|
|
@@ -7514,7 +7645,7 @@ const CALLBACK_PATH = "/oauth/callback";
|
|
|
7514
7645
|
const DEFAULT_CLIENT_NAME = "Runneth MCP";
|
|
7515
7646
|
const DEFAULT_SCOPE = "openid profile email offline_access";
|
|
7516
7647
|
const DEFAULT_TIMEOUT_MS = 3e5;
|
|
7517
|
-
const LOOPBACK_HOST = "
|
|
7648
|
+
const LOOPBACK_HOST = "127.0.0.1";
|
|
7518
7649
|
const OAUTH_CREDENTIAL_PATH_SEGMENT_LENGTH = 120;
|
|
7519
7650
|
const TOKEN_REFRESH_BUFFER_MS = 6e4;
|
|
7520
7651
|
const isRecord$6 = (value) => {
|
|
@@ -7546,6 +7677,13 @@ const parseStringArrayField = (record, key) => {
|
|
|
7546
7677
|
for (const item of value) if (typeof item !== "string" || item.trim().length === 0) throw new Error(`${key} must contain non-empty strings`);
|
|
7547
7678
|
return value;
|
|
7548
7679
|
};
|
|
7680
|
+
const parseOptionalStringArrayField = (record, key) => {
|
|
7681
|
+
const value = record[key];
|
|
7682
|
+
if (value === void 0) return;
|
|
7683
|
+
if (!Array.isArray(value)) throw new Error(`${key} must be a string array`);
|
|
7684
|
+
for (const item of value) if (typeof item !== "string" || item.trim().length === 0) throw new Error(`${key} must contain non-empty strings`);
|
|
7685
|
+
return value;
|
|
7686
|
+
};
|
|
7549
7687
|
const parseTokenEndpointAuthMethod = (value) => {
|
|
7550
7688
|
switch (value) {
|
|
7551
7689
|
case "client_secret_basic":
|
|
@@ -7554,6 +7692,39 @@ const parseTokenEndpointAuthMethod = (value) => {
|
|
|
7554
7692
|
default: throw new Error(`Unsupported token_endpoint_auth_method: ${value}`);
|
|
7555
7693
|
}
|
|
7556
7694
|
};
|
|
7695
|
+
const parseOAuthGrantType = (value) => {
|
|
7696
|
+
switch (value) {
|
|
7697
|
+
case "authorization_code":
|
|
7698
|
+
case "client_credentials": return value;
|
|
7699
|
+
default: throw new Error(`Unsupported OAuth grant type: ${value}`);
|
|
7700
|
+
}
|
|
7701
|
+
};
|
|
7702
|
+
const parseOptionalOAuthGrantTypeField = (record, key) => {
|
|
7703
|
+
const value = parseOptionalStringField$1(record, key);
|
|
7704
|
+
return value === void 0 ? void 0 : parseOAuthGrantType(value);
|
|
7705
|
+
};
|
|
7706
|
+
const normalizeOptionalScope = (value) => {
|
|
7707
|
+
const scope = value?.trim();
|
|
7708
|
+
return scope === void 0 || scope.length === 0 ? void 0 : scope;
|
|
7709
|
+
};
|
|
7710
|
+
const parseKnownTokenEndpointAuthMethod = (value) => {
|
|
7711
|
+
switch (value) {
|
|
7712
|
+
case "client_secret_basic":
|
|
7713
|
+
case "client_secret_post":
|
|
7714
|
+
case "none": return value;
|
|
7715
|
+
default: return;
|
|
7716
|
+
}
|
|
7717
|
+
};
|
|
7718
|
+
const parseOptionalTokenEndpointAuthMethodsField = (record, key) => {
|
|
7719
|
+
const values = parseOptionalStringArrayField(record, key);
|
|
7720
|
+
if (values === void 0) return;
|
|
7721
|
+
const supportedValues = [];
|
|
7722
|
+
for (const value of values) {
|
|
7723
|
+
const supportedValue = parseKnownTokenEndpointAuthMethod(value);
|
|
7724
|
+
if (supportedValue !== void 0) supportedValues.push(supportedValue);
|
|
7725
|
+
}
|
|
7726
|
+
return supportedValues;
|
|
7727
|
+
};
|
|
7557
7728
|
const toBase64Url = (buffer) => {
|
|
7558
7729
|
return buffer.toString("base64url");
|
|
7559
7730
|
};
|
|
@@ -7613,8 +7784,9 @@ const discoverAuthorizationServer = async (issuerUrl) => {
|
|
|
7613
7784
|
return {
|
|
7614
7785
|
authorizationEndpoint: parseStringField$1(metadata, "authorization_endpoint"),
|
|
7615
7786
|
issuer: parseStringField$1(metadata, "issuer"),
|
|
7616
|
-
registrationEndpoint:
|
|
7617
|
-
tokenEndpoint: parseStringField$1(metadata, "token_endpoint")
|
|
7787
|
+
registrationEndpoint: parseOptionalStringField$1(metadata, "registration_endpoint"),
|
|
7788
|
+
tokenEndpoint: parseStringField$1(metadata, "token_endpoint"),
|
|
7789
|
+
tokenEndpointAuthMethodsSupported: parseOptionalTokenEndpointAuthMethodsField(metadata, "token_endpoint_auth_methods_supported")
|
|
7618
7790
|
};
|
|
7619
7791
|
};
|
|
7620
7792
|
const resolveOAuthCredentialPath = (input) => {
|
|
@@ -7622,6 +7794,17 @@ const resolveOAuthCredentialPath = (input) => {
|
|
|
7622
7794
|
const resourceUrl = normalizeOAuthResourceUrl$1(input.resourceUrl);
|
|
7623
7795
|
return path.join(homePath, "oauth", ...encodeOAuthCredentialPathSegments(resourceUrl));
|
|
7624
7796
|
};
|
|
7797
|
+
const resolveOAuthClientCredentialOptions = (input) => {
|
|
7798
|
+
const clientId = input.clientId?.trim();
|
|
7799
|
+
const clientSecret = input.clientSecret?.trim();
|
|
7800
|
+
if ((clientId === void 0 || clientId.length === 0) && (clientSecret === void 0 || clientSecret.length === 0)) return {};
|
|
7801
|
+
if (clientId === void 0 || clientId.length === 0) throw new Error("OAuth client secret requires a client id");
|
|
7802
|
+
if (clientSecret === void 0 || clientSecret.length === 0) throw new Error("OAuth client id requires a client secret");
|
|
7803
|
+
return {
|
|
7804
|
+
clientId,
|
|
7805
|
+
clientSecret
|
|
7806
|
+
};
|
|
7807
|
+
};
|
|
7625
7808
|
const writeOAuthCredential = async (input) => {
|
|
7626
7809
|
await mkdir(path.dirname(input.credentialPath), {
|
|
7627
7810
|
mode: 448,
|
|
@@ -7646,20 +7829,22 @@ const parseStoredCredential = (value) => {
|
|
|
7646
7829
|
authorizationServer: {
|
|
7647
7830
|
authorizationEndpoint: parseStringField$1(authorizationServerValue, "authorizationEndpoint"),
|
|
7648
7831
|
issuer: parseStringField$1(authorizationServerValue, "issuer"),
|
|
7649
|
-
registrationEndpoint:
|
|
7650
|
-
tokenEndpoint: parseStringField$1(authorizationServerValue, "tokenEndpoint")
|
|
7832
|
+
registrationEndpoint: parseOptionalStringField$1(authorizationServerValue, "registrationEndpoint"),
|
|
7833
|
+
tokenEndpoint: parseStringField$1(authorizationServerValue, "tokenEndpoint"),
|
|
7834
|
+
tokenEndpointAuthMethodsSupported: parseOptionalTokenEndpointAuthMethodsField(authorizationServerValue, "tokenEndpointAuthMethodsSupported")
|
|
7651
7835
|
},
|
|
7652
7836
|
client: {
|
|
7653
7837
|
clientId: parseStringField$1(clientValue, "clientId"),
|
|
7654
7838
|
clientName: parseStringField$1(clientValue, "clientName"),
|
|
7655
7839
|
clientSecret: parseOptionalStringField$1(clientValue, "clientSecret"),
|
|
7656
|
-
redirectUri:
|
|
7840
|
+
redirectUri: parseOptionalStringField$1(clientValue, "redirectUri"),
|
|
7657
7841
|
tokenEndpointAuthMethod: parseTokenEndpointAuthMethod(parseStringField$1(clientValue, "tokenEndpointAuthMethod"))
|
|
7658
7842
|
},
|
|
7659
7843
|
createdAt: parseStringField$1(value, "createdAt"),
|
|
7844
|
+
grantType: parseOptionalOAuthGrantTypeField(value, "grantType") ?? "authorization_code",
|
|
7660
7845
|
requestedResourceUrl: parseStringField$1(value, "requestedResourceUrl"),
|
|
7661
7846
|
resource: parseStringField$1(value, "resource"),
|
|
7662
|
-
scope:
|
|
7847
|
+
scope: parseOptionalStringField$1(value, "scope"),
|
|
7663
7848
|
token: {
|
|
7664
7849
|
accessToken: parseStringField$1(tokenValue, "accessToken"),
|
|
7665
7850
|
expiresAt: parseOptionalStringField$1(tokenValue, "expiresAt"),
|
|
@@ -7672,6 +7857,25 @@ const parseStoredCredential = (value) => {
|
|
|
7672
7857
|
version: 1
|
|
7673
7858
|
};
|
|
7674
7859
|
};
|
|
7860
|
+
const resolveOAuthToken = async (options) => {
|
|
7861
|
+
const clientCredentials = resolveOAuthClientCredentialOptions({
|
|
7862
|
+
clientId: options.clientId,
|
|
7863
|
+
clientSecret: options.clientSecret
|
|
7864
|
+
});
|
|
7865
|
+
if (clientCredentials.clientId !== void 0 && clientCredentials.clientSecret !== void 0) return await loginWithOAuth({
|
|
7866
|
+
...options,
|
|
7867
|
+
clientId: clientCredentials.clientId,
|
|
7868
|
+
clientSecret: clientCredentials.clientSecret
|
|
7869
|
+
});
|
|
7870
|
+
if ((await readOAuthCredentialStatus({
|
|
7871
|
+
homePath: options.homePath,
|
|
7872
|
+
resourceUrl: options.resourceUrl
|
|
7873
|
+
})).authenticated) return await getOAuthAccessToken({
|
|
7874
|
+
homePath: options.homePath,
|
|
7875
|
+
resourceUrl: options.resourceUrl
|
|
7876
|
+
});
|
|
7877
|
+
return await loginWithOAuth(options);
|
|
7878
|
+
};
|
|
7675
7879
|
const readOAuthCredential = async (input) => {
|
|
7676
7880
|
const credentialPath = resolveOAuthCredentialPath(input);
|
|
7677
7881
|
try {
|
|
@@ -7785,7 +7989,9 @@ const closeServer = async (server) => {
|
|
|
7785
7989
|
});
|
|
7786
7990
|
};
|
|
7787
7991
|
const registerOAuthClient = async (input) => {
|
|
7788
|
-
const
|
|
7992
|
+
const registrationEndpoint = input.metadata.registrationEndpoint;
|
|
7993
|
+
if (registrationEndpoint === void 0) throw new Error("OAuth authorization server does not support dynamic client registration; provide --client-id and --client-secret");
|
|
7994
|
+
const response = await fetchJsonObject(registrationEndpoint, {
|
|
7789
7995
|
body: JSON.stringify({
|
|
7790
7996
|
client_name: input.clientName,
|
|
7791
7997
|
grant_types: ["authorization_code", "refresh_token"],
|
|
@@ -7809,6 +8015,56 @@ const registerOAuthClient = async (input) => {
|
|
|
7809
8015
|
tokenEndpointAuthMethod: parseTokenEndpointAuthMethod(parseStringField$1(response, "token_endpoint_auth_method"))
|
|
7810
8016
|
};
|
|
7811
8017
|
};
|
|
8018
|
+
const requireOAuthClientSecret = (client) => {
|
|
8019
|
+
if (client.clientSecret === void 0) throw new Error(`OAuth client ${client.clientId} requires ${client.tokenEndpointAuthMethod} but has no client secret`);
|
|
8020
|
+
return client.clientSecret;
|
|
8021
|
+
};
|
|
8022
|
+
const requireOAuthClientRedirectUri = (client) => {
|
|
8023
|
+
if (client.redirectUri === void 0) throw new Error(`OAuth client ${client.clientId} requires authorization_code but has no redirect URI`);
|
|
8024
|
+
return client.redirectUri;
|
|
8025
|
+
};
|
|
8026
|
+
const buildOAuthClientAuthenticationHeaders = (input) => {
|
|
8027
|
+
switch (input.client.tokenEndpointAuthMethod) {
|
|
8028
|
+
case "none": return {};
|
|
8029
|
+
case "client_secret_post":
|
|
8030
|
+
input.body.set("client_secret", requireOAuthClientSecret(input.client));
|
|
8031
|
+
return {};
|
|
8032
|
+
case "client_secret_basic": {
|
|
8033
|
+
const encodedClientId = formUrlEncode(input.client.clientId);
|
|
8034
|
+
const encodedClientSecret = formUrlEncode(requireOAuthClientSecret(input.client));
|
|
8035
|
+
return { Authorization: `Basic ${Buffer.from(`${encodedClientId}:${encodedClientSecret}`, "utf8").toString("base64")}` };
|
|
8036
|
+
}
|
|
8037
|
+
default: {
|
|
8038
|
+
const exhaustive = input.client.tokenEndpointAuthMethod;
|
|
8039
|
+
throw new Error(`Unsupported OAuth client auth method: ${exhaustive}`);
|
|
8040
|
+
}
|
|
8041
|
+
}
|
|
8042
|
+
};
|
|
8043
|
+
const formUrlEncode = (value) => {
|
|
8044
|
+
const body = new URLSearchParams();
|
|
8045
|
+
body.set("value", value);
|
|
8046
|
+
return body.toString().slice(6);
|
|
8047
|
+
};
|
|
8048
|
+
const resolveClientSecretAuthMethod = (metadata) => {
|
|
8049
|
+
const supportedMethods = metadata.tokenEndpointAuthMethodsSupported;
|
|
8050
|
+
if (supportedMethods === void 0 || supportedMethods.includes("client_secret_basic")) return "client_secret_basic";
|
|
8051
|
+
if (supportedMethods.includes("client_secret_post")) return "client_secret_post";
|
|
8052
|
+
throw new Error("OAuth authorization server does not support client secret authentication");
|
|
8053
|
+
};
|
|
8054
|
+
const resolveProvidedOAuthClient = (input) => {
|
|
8055
|
+
const clientId = input.clientId?.trim();
|
|
8056
|
+
const clientSecret = input.clientSecret?.trim();
|
|
8057
|
+
if ((clientId === void 0 || clientId.length === 0) && (clientSecret === void 0 || clientSecret.length === 0)) return null;
|
|
8058
|
+
if (clientId === void 0 || clientId.length === 0) throw new Error("OAuth client secret requires a client id");
|
|
8059
|
+
if (clientSecret === void 0 || clientSecret.length === 0) throw new Error("OAuth client id requires a client secret");
|
|
8060
|
+
return {
|
|
8061
|
+
clientId,
|
|
8062
|
+
clientName: input.clientName,
|
|
8063
|
+
clientSecret,
|
|
8064
|
+
redirectUri: input.redirectUri,
|
|
8065
|
+
tokenEndpointAuthMethod: resolveClientSecretAuthMethod(input.metadata)
|
|
8066
|
+
};
|
|
8067
|
+
};
|
|
7812
8068
|
const openSystemBrowser = async (url) => {
|
|
7813
8069
|
const command = process$1.platform === "darwin" ? "open" : process$1.platform === "win32" ? "cmd" : "xdg-open";
|
|
7814
8070
|
const args = process$1.platform === "win32" ? [
|
|
@@ -7834,7 +8090,7 @@ const buildAuthorizationUrl = (input) => {
|
|
|
7834
8090
|
authorizationUrl.searchParams.set("client_id", input.client.clientId);
|
|
7835
8091
|
authorizationUrl.searchParams.set("code_challenge", input.pkceChallenge);
|
|
7836
8092
|
authorizationUrl.searchParams.set("code_challenge_method", "S256");
|
|
7837
|
-
authorizationUrl.searchParams.set("redirect_uri", input.client
|
|
8093
|
+
authorizationUrl.searchParams.set("redirect_uri", requireOAuthClientRedirectUri(input.client));
|
|
7838
8094
|
authorizationUrl.searchParams.set("response_type", "code");
|
|
7839
8095
|
authorizationUrl.searchParams.set("scope", input.scope);
|
|
7840
8096
|
authorizationUrl.searchParams.set("prompt", "consent");
|
|
@@ -7883,30 +8139,65 @@ const requestOAuthToken = async (input) => {
|
|
|
7883
8139
|
redirect_uri: input.redirectUri,
|
|
7884
8140
|
resource: input.resource
|
|
7885
8141
|
});
|
|
7886
|
-
|
|
8142
|
+
const clientAuthHeaders = buildOAuthClientAuthenticationHeaders({
|
|
8143
|
+
body,
|
|
8144
|
+
client: input.client
|
|
8145
|
+
});
|
|
7887
8146
|
return parseTokenResponse(await fetchJsonObject(input.metadata.tokenEndpoint, {
|
|
7888
8147
|
body,
|
|
7889
8148
|
headers: {
|
|
7890
8149
|
Accept: "application/json",
|
|
8150
|
+
...clientAuthHeaders,
|
|
7891
8151
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
7892
8152
|
},
|
|
7893
8153
|
method: "POST"
|
|
7894
8154
|
}, "OAuth token request"), Date.now());
|
|
7895
8155
|
};
|
|
8156
|
+
const requestOAuthClientCredentialsToken = async (input) => {
|
|
8157
|
+
const body = new URLSearchParams({
|
|
8158
|
+
client_id: input.client.clientId,
|
|
8159
|
+
grant_type: "client_credentials",
|
|
8160
|
+
resource: input.resource
|
|
8161
|
+
});
|
|
8162
|
+
if (input.scope !== void 0) body.set("scope", input.scope);
|
|
8163
|
+
const clientAuthHeaders = buildOAuthClientAuthenticationHeaders({
|
|
8164
|
+
body,
|
|
8165
|
+
client: input.client
|
|
8166
|
+
});
|
|
8167
|
+
return parseTokenResponse(await fetchJsonObject(input.metadata.tokenEndpoint, {
|
|
8168
|
+
body,
|
|
8169
|
+
headers: {
|
|
8170
|
+
Accept: "application/json",
|
|
8171
|
+
...clientAuthHeaders,
|
|
8172
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
8173
|
+
},
|
|
8174
|
+
method: "POST"
|
|
8175
|
+
}, "OAuth client credentials token request"), Date.now());
|
|
8176
|
+
};
|
|
7896
8177
|
const refreshOAuthToken = async (input) => {
|
|
8178
|
+
if (input.credential.grantType === "client_credentials") return await requestOAuthClientCredentialsToken({
|
|
8179
|
+
client: input.credential.client,
|
|
8180
|
+
metadata: input.credential.authorizationServer,
|
|
8181
|
+
resource: input.credential.resource,
|
|
8182
|
+
scope: input.credential.scope
|
|
8183
|
+
});
|
|
7897
8184
|
if (input.credential.token.refreshToken === void 0) throw new Error("Stored OAuth credential is expired and has no refresh token");
|
|
7898
8185
|
const body = new URLSearchParams({
|
|
7899
8186
|
client_id: input.credential.client.clientId,
|
|
7900
8187
|
grant_type: "refresh_token",
|
|
7901
8188
|
refresh_token: input.credential.token.refreshToken,
|
|
7902
|
-
resource: input.credential.resource
|
|
7903
|
-
|
|
8189
|
+
resource: input.credential.resource
|
|
8190
|
+
});
|
|
8191
|
+
if (input.credential.scope !== void 0) body.set("scope", input.credential.scope);
|
|
8192
|
+
const clientAuthHeaders = buildOAuthClientAuthenticationHeaders({
|
|
8193
|
+
body,
|
|
8194
|
+
client: input.credential.client
|
|
7904
8195
|
});
|
|
7905
|
-
if (input.credential.client.clientSecret !== void 0) body.set("client_secret", input.credential.client.clientSecret);
|
|
7906
8196
|
const refreshed = parseTokenResponse(await fetchJsonObject(input.credential.authorizationServer.tokenEndpoint, {
|
|
7907
8197
|
body,
|
|
7908
8198
|
headers: {
|
|
7909
8199
|
Accept: "application/json",
|
|
8200
|
+
...clientAuthHeaders,
|
|
7910
8201
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
7911
8202
|
},
|
|
7912
8203
|
method: "POST"
|
|
@@ -7922,22 +8213,62 @@ const tokenIsFresh = (token) => {
|
|
|
7922
8213
|
};
|
|
7923
8214
|
const loginWithOAuth = async (options) => {
|
|
7924
8215
|
const requestedResourceUrl = normalizeOAuthResourceUrl$1(options.resourceUrl);
|
|
7925
|
-
const
|
|
8216
|
+
const authorizationCodeScope = normalizeOptionalScope(options.scope) ?? DEFAULT_SCOPE;
|
|
8217
|
+
const clientCredentialsScope = normalizeOptionalScope(options.scope);
|
|
7926
8218
|
const clientName = options.clientName?.trim() || DEFAULT_CLIENT_NAME;
|
|
7927
8219
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
7928
|
-
const callbackServer = await startLoopbackCallbackServer();
|
|
7929
8220
|
const credentialPath = resolveOAuthCredentialPath({
|
|
7930
8221
|
homePath: options.homePath,
|
|
7931
8222
|
resourceUrl: requestedResourceUrl
|
|
7932
8223
|
});
|
|
8224
|
+
const protectedResource = await discoverProtectedResource(requestedResourceUrl);
|
|
8225
|
+
const authorizationServer = await discoverAuthorizationServer(protectedResource.authorizationServers[0]);
|
|
8226
|
+
const providedClient = resolveProvidedOAuthClient({
|
|
8227
|
+
clientId: options.clientId,
|
|
8228
|
+
clientName,
|
|
8229
|
+
clientSecret: options.clientSecret,
|
|
8230
|
+
metadata: authorizationServer,
|
|
8231
|
+
redirectUri: void 0
|
|
8232
|
+
});
|
|
8233
|
+
if (providedClient !== null) {
|
|
8234
|
+
const token = await requestOAuthClientCredentialsToken({
|
|
8235
|
+
client: providedClient,
|
|
8236
|
+
metadata: authorizationServer,
|
|
8237
|
+
resource: protectedResource.resource,
|
|
8238
|
+
scope: clientCredentialsScope
|
|
8239
|
+
});
|
|
8240
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
8241
|
+
const credential = {
|
|
8242
|
+
authorizationServer,
|
|
8243
|
+
client: providedClient,
|
|
8244
|
+
createdAt: now,
|
|
8245
|
+
grantType: "client_credentials",
|
|
8246
|
+
requestedResourceUrl,
|
|
8247
|
+
resource: protectedResource.resource,
|
|
8248
|
+
scope: clientCredentialsScope,
|
|
8249
|
+
token,
|
|
8250
|
+
updatedAt: now,
|
|
8251
|
+
version: 1
|
|
8252
|
+
};
|
|
8253
|
+
await writeOAuthCredential({
|
|
8254
|
+
credential,
|
|
8255
|
+
credentialPath
|
|
8256
|
+
});
|
|
8257
|
+
return {
|
|
8258
|
+
accessToken: token.accessToken,
|
|
8259
|
+
credential,
|
|
8260
|
+
credentialPath,
|
|
8261
|
+
expiresAt: token.expiresAt,
|
|
8262
|
+
tokenType: token.tokenType
|
|
8263
|
+
};
|
|
8264
|
+
}
|
|
8265
|
+
const callbackServer = await startLoopbackCallbackServer();
|
|
7933
8266
|
try {
|
|
7934
|
-
const protectedResource = await discoverProtectedResource(requestedResourceUrl);
|
|
7935
|
-
const authorizationServer = await discoverAuthorizationServer(protectedResource.authorizationServers[0]);
|
|
7936
8267
|
const client = await registerOAuthClient({
|
|
7937
8268
|
clientName,
|
|
7938
8269
|
metadata: authorizationServer,
|
|
7939
8270
|
redirectUri: callbackServer.redirectUri,
|
|
7940
|
-
scope
|
|
8271
|
+
scope: authorizationCodeScope
|
|
7941
8272
|
});
|
|
7942
8273
|
const state = toBase64Url(randomBytes(32));
|
|
7943
8274
|
const pkce = createPkcePair();
|
|
@@ -7945,7 +8276,7 @@ const loginWithOAuth = async (options) => {
|
|
|
7945
8276
|
client,
|
|
7946
8277
|
metadata: authorizationServer,
|
|
7947
8278
|
pkceChallenge: pkce.challenge,
|
|
7948
|
-
scope,
|
|
8279
|
+
scope: authorizationCodeScope,
|
|
7949
8280
|
state
|
|
7950
8281
|
});
|
|
7951
8282
|
await options.authorizationUrlHandler?.(authorizationUrl);
|
|
@@ -7966,9 +8297,10 @@ const loginWithOAuth = async (options) => {
|
|
|
7966
8297
|
authorizationServer,
|
|
7967
8298
|
client,
|
|
7968
8299
|
createdAt: now,
|
|
8300
|
+
grantType: "authorization_code",
|
|
7969
8301
|
requestedResourceUrl,
|
|
7970
8302
|
resource: protectedResource.resource,
|
|
7971
|
-
scope,
|
|
8303
|
+
scope: authorizationCodeScope,
|
|
7972
8304
|
token,
|
|
7973
8305
|
updatedAt: now,
|
|
7974
8306
|
version: 1
|
|
@@ -8021,9 +8353,10 @@ const getOAuthAccessToken = async (input) => {
|
|
|
8021
8353
|
//#region src/conversation.ts
|
|
8022
8354
|
const DEFAULT_POLL_INTERVAL_MS = 1e3;
|
|
8023
8355
|
const DEFAULT_OAUTH_CLIENT_NAME = "Runneth MCP";
|
|
8024
|
-
const DEFAULT_OAUTH_SCOPE = "openid profile email offline_access";
|
|
8025
8356
|
const DEFAULT_OAUTH_TIMEOUT_MS = 6e5;
|
|
8026
8357
|
const MIN_POLL_INTERVAL_MS = 250;
|
|
8358
|
+
const RUNNETH_OAUTH_CLIENT_ID_ENV = "RUNNETH_OAUTH_CLIENT_ID";
|
|
8359
|
+
const RUNNETH_OAUTH_CLIENT_SECRET_ENV = "RUNNETH_OAUTH_CLIENT_SECRET";
|
|
8027
8360
|
const SANDBOX_PREPARING_RETRY_TIMEOUT_MS = 18e4;
|
|
8028
8361
|
const TERMINAL_MESSAGE_STATUSES$1 = new Set([
|
|
8029
8362
|
"completed",
|
|
@@ -8138,16 +8471,24 @@ const apiFetch = async (options, input) => {
|
|
|
8138
8471
|
return parseApiDataEnvelope(body, input.schema).data;
|
|
8139
8472
|
}
|
|
8140
8473
|
};
|
|
8474
|
+
const resolveCliOAuthClientCredentialOptions = (parsed) => {
|
|
8475
|
+
return resolveOAuthClientCredentialOptions({
|
|
8476
|
+
clientId: parsed.clientId ?? process.env[RUNNETH_OAUTH_CLIENT_ID_ENV],
|
|
8477
|
+
clientSecret: parsed.clientSecret ?? process.env[RUNNETH_OAUTH_CLIENT_SECRET_ENV]
|
|
8478
|
+
});
|
|
8479
|
+
};
|
|
8141
8480
|
const parseRunnethConversationArgs = (argv, parseNumber) => {
|
|
8142
8481
|
const values = [];
|
|
8143
8482
|
let apiBaseUrl;
|
|
8144
8483
|
let authMode = "mondrian";
|
|
8484
|
+
let clientId;
|
|
8145
8485
|
let clientName = DEFAULT_OAUTH_CLIENT_NAME;
|
|
8486
|
+
let clientSecret;
|
|
8146
8487
|
let conversationId;
|
|
8147
8488
|
let openBrowser = true;
|
|
8148
8489
|
let pollIntervalMs = DEFAULT_POLL_INTERVAL_MS;
|
|
8149
8490
|
let resourceUrl;
|
|
8150
|
-
let scope
|
|
8491
|
+
let scope;
|
|
8151
8492
|
let tenanthId = "motion";
|
|
8152
8493
|
let title;
|
|
8153
8494
|
let token;
|
|
@@ -8180,9 +8521,17 @@ const parseRunnethConversationArgs = (argv, parseNumber) => {
|
|
|
8180
8521
|
authMode = value;
|
|
8181
8522
|
break;
|
|
8182
8523
|
}
|
|
8524
|
+
case "--client-id":
|
|
8525
|
+
case "--clientid":
|
|
8526
|
+
clientId = readValue(tokenValue);
|
|
8527
|
+
break;
|
|
8183
8528
|
case "--client-name":
|
|
8184
8529
|
clientName = readValue(tokenValue);
|
|
8185
8530
|
break;
|
|
8531
|
+
case "--client-secret":
|
|
8532
|
+
case "--secret":
|
|
8533
|
+
clientSecret = readValue(tokenValue);
|
|
8534
|
+
break;
|
|
8186
8535
|
case "--conversation":
|
|
8187
8536
|
conversationId = readValue(tokenValue);
|
|
8188
8537
|
break;
|
|
@@ -8220,7 +8569,9 @@ const parseRunnethConversationArgs = (argv, parseNumber) => {
|
|
|
8220
8569
|
return {
|
|
8221
8570
|
apiBaseUrl,
|
|
8222
8571
|
authMode,
|
|
8572
|
+
...clientId === void 0 ? {} : { clientId },
|
|
8223
8573
|
clientName,
|
|
8574
|
+
...clientSecret === void 0 ? {} : { clientSecret },
|
|
8224
8575
|
conversationId,
|
|
8225
8576
|
openBrowser,
|
|
8226
8577
|
pollIntervalMs,
|
|
@@ -8246,11 +8597,12 @@ const resolveRunnethConversationResourceUrl = (parsed) => {
|
|
|
8246
8597
|
return normalizeOAuthResourceUrl(resourceUrl);
|
|
8247
8598
|
};
|
|
8248
8599
|
const resolveOAuthAccessToken = async (parsed, resourceUrl) => {
|
|
8249
|
-
const token =
|
|
8600
|
+
const token = await resolveOAuthToken({
|
|
8250
8601
|
authorizationUrlHandler: (authorizationUrl) => {
|
|
8251
8602
|
process.stderr.write(`Authorize runneth-cli chat here:\n${authorizationUrl}\n`);
|
|
8252
8603
|
},
|
|
8253
8604
|
clientName: parsed.clientName,
|
|
8605
|
+
...resolveCliOAuthClientCredentialOptions(parsed),
|
|
8254
8606
|
openBrowser: parsed.openBrowser,
|
|
8255
8607
|
resourceUrl,
|
|
8256
8608
|
scope: parsed.scope,
|
|
@@ -9695,8 +10047,14 @@ const runRunnethConversationMachineCommand = async ({ argv, parseNumber, streams
|
|
|
9695
10047
|
" --workspace <id> Mondrian/Builder workspace id",
|
|
9696
10048
|
" --token <token> Bearer token override",
|
|
9697
10049
|
" --auth <mode> mondrian or builder. Defaults to mondrian",
|
|
10050
|
+
" --client-id, --clientid <id>",
|
|
10051
|
+
" OAuth client id; may use RUNNETH_OAUTH_CLIENT_ID",
|
|
10052
|
+
" --client-secret, --secret <value>",
|
|
10053
|
+
" OAuth client secret; prefer RUNNETH_OAUTH_CLIENT_SECRET",
|
|
9698
10054
|
" --conversation <id> Required for send and state",
|
|
10055
|
+
" --no-open Print the OAuth URL instead of opening a browser",
|
|
9699
10056
|
" --poll-interval-ms <ms> State refresh interval. Defaults to 1000",
|
|
10057
|
+
" --scope <scope> OAuth scope. Defaults to openid profile email offline_access",
|
|
9700
10058
|
" --tenanth <id> Tenant route id. Defaults to motion",
|
|
9701
10059
|
"",
|
|
9702
10060
|
"Machine options:",
|
|
@@ -11287,4 +11645,4 @@ const ensureDaemon = async (input) => {
|
|
|
11287
11645
|
throw new Error("Timed out waiting for runneth-cli daemon to start");
|
|
11288
11646
|
};
|
|
11289
11647
|
//#endregion
|
|
11290
|
-
export { fetchConversationState as A, readOAuthCredentialStatus as B, setDefaultRunnethSshTarget as C, runRunnethConversationMachineCommand as D, parseRunnethConversationSessionRequest as E, sendMessage as F,
|
|
11648
|
+
export { fetchConversationState as A, readOAuthCredentialStatus as B, setDefaultRunnethSshTarget as C, runRunnethConversationMachineCommand as D, parseRunnethConversationSessionRequest as E, sendMessage as F, resolveSocketPath as G, resolveOAuthCredentialPath as H, getOAuthAccessToken as I, loginWithOAuth as L, parseRunnethConversationArgs as M, resolveRunnethConversationOptions as N, RUNNETH_CONVERSATION_DEFAULT_POLL_INTERVAL_MS as O, runRunnethConversation as P, logoutOAuthCredential as R, saveRunnethSshTarget as S, runRunnethVmCopy as T, resolveOAuthToken as U, resolveOAuthClientCredentialOptions as V, resolveRunnethCliHome as W, resolveRunnethSshTarget as _, normalizeSessionName as a, runOpenSsh as b, startDaemonProcess as c, installRunnethSshAccess as d, normalizeRunnethSshTargetName as f, resolveRunnethSshSharedKeyPaths as g, resolveRunnethSshAppUrl as h, extractCommandResult as i, normalizeRunnethApiBaseUrl as j, createConversation as k, installRunnethSkills as l, removeRunnethSshTarget as m, createCommandEnvelope as n, parseRunnethCliRequest as o, readRunnethSshTargetStore as p, ensureDaemon as r, sendRunnethCliRequest as s, RunnethCliDaemon as t, resolveBundledRunnethSkillPath as u, resolveRunnethSshTargetPaths as v, assertRunnethVmCopyTargetsUseSameResource as w, runRunnethSshProxy as x, resolveRunnethSshTargetsPath as y, readOAuthCredential as z };
|
package/package.json
CHANGED