omnara 1.0.0-beta.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/dist/bin.js +380 -232
- package/package.json +12 -3
package/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Omnara CLI
|
|
2
|
+
|
|
3
|
+
Command-line interface for [Omnara](https://omnara.com): launch and manage agents, organizations, integrations, and MCP servers.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npx omnara
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
omnara login
|
|
15
|
+
omnara --help
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Requires Node.js 22 or later.
|
|
19
|
+
|
|
20
|
+
## Documentation
|
|
21
|
+
|
|
22
|
+
See the [Omnara docs](https://docs.omnara.com) and the [GitHub repository](https://github.com/omnara-ai/omnara).
|
|
23
|
+
|
|
24
|
+
## License
|
|
25
|
+
|
|
26
|
+
Apache-2.0
|
package/dist/bin.js
CHANGED
|
@@ -210,7 +210,7 @@ function createSseClient({
|
|
|
210
210
|
...options
|
|
211
211
|
}) {
|
|
212
212
|
let lastEventId;
|
|
213
|
-
const
|
|
213
|
+
const sleep2 = sseSleepFn ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
|
|
214
214
|
const createStream = async function* () {
|
|
215
215
|
let retryDelay = sseDefaultRetryDelay ?? 3e3;
|
|
216
216
|
let attempt = 0;
|
|
@@ -314,7 +314,7 @@ function createSseClient({
|
|
|
314
314
|
break;
|
|
315
315
|
}
|
|
316
316
|
const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 3e4);
|
|
317
|
-
await
|
|
317
|
+
await sleep2(backoff);
|
|
318
318
|
}
|
|
319
319
|
}
|
|
320
320
|
};
|
|
@@ -1012,6 +1012,10 @@ var zError = z.object({
|
|
|
1012
1012
|
"authentication_unavailable"
|
|
1013
1013
|
])
|
|
1014
1014
|
});
|
|
1015
|
+
var zWarning = z.object({
|
|
1016
|
+
message: z.string(),
|
|
1017
|
+
code: z.enum(["missing_recommended_machine_tools"])
|
|
1018
|
+
});
|
|
1015
1019
|
var zClientErrorCode = z.enum([
|
|
1016
1020
|
"invalid_request",
|
|
1017
1021
|
"validation_failed",
|
|
@@ -1043,6 +1047,8 @@ var zOrgInvitationId = z.string().regex(/^oinv_[a-z2-7]{26}$/);
|
|
|
1043
1047
|
var zPersonalAccessTokenId = z.string().regex(/^pat_[a-z2-7]{26}$/);
|
|
1044
1048
|
var zOrgApiKeyId = z.string().regex(/^oak_[a-z2-7]{26}$/);
|
|
1045
1049
|
var zProjectId = z.string().regex(/^proj_[a-z2-7]{26}$/);
|
|
1050
|
+
var zMcpoAuthFlowId = z.string().regex(/^moaf_[a-z2-7]{26}$/);
|
|
1051
|
+
var zIntegrationOAuthFlowId = z.string().regex(/^ioaf_[a-z2-7]{26}$/);
|
|
1046
1052
|
var zActorId = z.string().regex(/^actr_[a-z2-7]{26}$/);
|
|
1047
1053
|
var zAgentId = z.string().regex(/^agt_[a-z2-7]{26}$/);
|
|
1048
1054
|
var zAgentConfigId = z.string().regex(/^acfg_[a-z2-7]{26}$/);
|
|
@@ -1220,6 +1226,7 @@ var zConfiguredModel = z.object({
|
|
|
1220
1226
|
id: zConfiguredModelId,
|
|
1221
1227
|
org_id: zOrganizationId,
|
|
1222
1228
|
model_provider_config_id: zModelProviderConfigId,
|
|
1229
|
+
management_kind: zManagementKind,
|
|
1223
1230
|
name: z.string(),
|
|
1224
1231
|
current_revision_id: zConfiguredModelRevisionId,
|
|
1225
1232
|
provider_model_slug: z.string(),
|
|
@@ -1363,6 +1370,7 @@ var zSkillGrant = z.object({
|
|
|
1363
1370
|
});
|
|
1364
1371
|
var zMcpoAuthStartMetadata = z.record(z.string(), z.string().max(512));
|
|
1365
1372
|
var zMcpoAuthStartResponse = z.object({
|
|
1373
|
+
flow_id: zMcpoAuthFlowId,
|
|
1366
1374
|
authorization_url: z.url(),
|
|
1367
1375
|
expires_at: zTimestamp
|
|
1368
1376
|
});
|
|
@@ -1395,6 +1403,7 @@ var zListIntegrationInstallsResponse = z.object({
|
|
|
1395
1403
|
});
|
|
1396
1404
|
var zIntegrationOAuthSetup = z.object({
|
|
1397
1405
|
provider: z.string(),
|
|
1406
|
+
flow_id: zIntegrationOAuthFlowId,
|
|
1398
1407
|
oauth_url: z.url(),
|
|
1399
1408
|
redirect_uri: z.url(),
|
|
1400
1409
|
events_url: z.url(),
|
|
@@ -1413,6 +1422,7 @@ var zCreateSlackSetupRequest = z.object({
|
|
|
1413
1422
|
});
|
|
1414
1423
|
var zSlackSetup = z.object({
|
|
1415
1424
|
provider: z.string(),
|
|
1425
|
+
flow_id: zIntegrationOAuthFlowId,
|
|
1416
1426
|
slack_app_id: z.string(),
|
|
1417
1427
|
oauth_url: z.url(),
|
|
1418
1428
|
redirect_uri: z.url(),
|
|
@@ -1483,6 +1493,7 @@ var zAgentConfig = z.object({
|
|
|
1483
1493
|
effective_definition_hash: z.string(),
|
|
1484
1494
|
model: zAgentConfigModel,
|
|
1485
1495
|
instruction_hash: z.string().optional(),
|
|
1496
|
+
warnings: z.array(zWarning).min(1).optional(),
|
|
1486
1497
|
created_at: zTimestamp
|
|
1487
1498
|
});
|
|
1488
1499
|
var zCreateAgentProfileRequest = z.object({
|
|
@@ -2441,6 +2452,11 @@ var zUpdateMachinePoolRequest = z.object({
|
|
|
2441
2452
|
max_machine_memory_mb: z.int().gte(1).lte(2147483647).nullish(),
|
|
2442
2453
|
metadata: zMachineMetadata.optional()
|
|
2443
2454
|
});
|
|
2455
|
+
var zMachinePoolUsage = z.object({
|
|
2456
|
+
machines: z.int().gte(0).max(2147483647, { error: "Invalid value: Expected int32 to be <= 2147483647" }),
|
|
2457
|
+
cpu: z.coerce.bigint().gte(BigInt(0)).max(BigInt("9223372036854775807"), { error: "Invalid value: Expected int64 to be <= 9223372036854775807" }),
|
|
2458
|
+
memory_mb: z.coerce.bigint().gte(BigInt(0)).max(BigInt("9223372036854775807"), { error: "Invalid value: Expected int64 to be <= 9223372036854775807" })
|
|
2459
|
+
});
|
|
2444
2460
|
var zMachinePool = z.object({
|
|
2445
2461
|
id: zMachinePoolId,
|
|
2446
2462
|
org_id: zOrganizationId,
|
|
@@ -2466,7 +2482,8 @@ var zMachinePool = z.object({
|
|
|
2466
2482
|
max_machine_memory_mb: z.int().gte(1).lte(2147483647).nullable(),
|
|
2467
2483
|
metadata: zMetadata,
|
|
2468
2484
|
created_at: zTimestamp,
|
|
2469
|
-
updated_at: zTimestamp
|
|
2485
|
+
updated_at: zTimestamp,
|
|
2486
|
+
usage: zMachinePoolUsage.optional()
|
|
2470
2487
|
});
|
|
2471
2488
|
var zListMachinePoolsResponse = z.object({
|
|
2472
2489
|
data: z.array(zMachinePool),
|
|
@@ -3114,6 +3131,7 @@ var zListSkillGrantsQuery = z.object({
|
|
|
3114
3131
|
cursor: z.string().max(1024).optional()
|
|
3115
3132
|
});
|
|
3116
3133
|
var zListSkillGrantsResponse2 = zListSkillGrantsResponse;
|
|
3134
|
+
var zCreateSkillGrantBody = zSkillGrantCreateRequest;
|
|
3117
3135
|
var zCreateSkillGrantPath = z.object({
|
|
3118
3136
|
orgID: z.string().regex(/^org_[a-z2-7]{26}$/),
|
|
3119
3137
|
skillID: zSkillId
|
|
@@ -3154,6 +3172,7 @@ var zListSecretsQuery = z.object({
|
|
|
3154
3172
|
"user"
|
|
3155
3173
|
]).optional(),
|
|
3156
3174
|
owner_project_id: zProjectId.optional(),
|
|
3175
|
+
mcp_oauth_flow_id: zMcpoAuthFlowId.optional(),
|
|
3157
3176
|
metadata: z.record(z.string(), z.string()).optional(),
|
|
3158
3177
|
sort: zResourceListSort.optional(),
|
|
3159
3178
|
limit: z.int().gte(1).lte(100).optional().default(50),
|
|
@@ -3201,6 +3220,7 @@ var zListSecretGrantsQuery = z.object({
|
|
|
3201
3220
|
cursor: z.string().max(1024).optional()
|
|
3202
3221
|
});
|
|
3203
3222
|
var zListSecretGrantsResponse2 = zListSecretGrantsResponse;
|
|
3223
|
+
var zCreateSecretGrantBody = zSecretGrantCreateRequest;
|
|
3204
3224
|
var zCreateSecretGrantPath = z.object({
|
|
3205
3225
|
orgID: z.string().regex(/^org_[a-z2-7]{26}$/),
|
|
3206
3226
|
secretID: z.string().regex(/^sec_[a-z2-7]{26}$/)
|
|
@@ -3219,6 +3239,7 @@ var zListIntegrationInstallsPath = z.object({
|
|
|
3219
3239
|
var zListIntegrationInstallsQuery = z.object({
|
|
3220
3240
|
name: z.string().min(1).max(200).optional(),
|
|
3221
3241
|
agent_profile_id: zAgentProfileId.optional(),
|
|
3242
|
+
oauth_flow_id: zIntegrationOAuthFlowId.optional(),
|
|
3222
3243
|
sort: zResourceListSort.optional(),
|
|
3223
3244
|
limit: z.int().gte(1).lte(100).optional().default(50),
|
|
3224
3245
|
cursor: z.string().max(1024).optional()
|
|
@@ -3561,6 +3582,7 @@ var zListProjectMachineGrantsQuery = z.object({
|
|
|
3561
3582
|
cursor: z.string().max(1024).optional()
|
|
3562
3583
|
});
|
|
3563
3584
|
var zListProjectMachineGrantsResponse2 = zListProjectMachineGrantsResponse;
|
|
3585
|
+
var zCreateProjectMachineGrantBody = zCreateProjectMachineGrantRequest;
|
|
3564
3586
|
var zCreateProjectMachineGrantHeaders = z.object({
|
|
3565
3587
|
"Idempotency-Key": z.string().min(1).max(255).optional()
|
|
3566
3588
|
});
|
|
@@ -3737,6 +3759,7 @@ var zListProjectModelGrantsQuery = z.object({
|
|
|
3737
3759
|
cursor: z.string().max(1024).optional()
|
|
3738
3760
|
});
|
|
3739
3761
|
var zListProjectModelGrantsResponse2 = zListProjectModelGrantsResponse;
|
|
3762
|
+
var zCreateProjectModelGrantBody = zCreateProjectModelGrantRequest;
|
|
3740
3763
|
var zCreateProjectModelGrantPath = z.object({
|
|
3741
3764
|
orgID: z.string().regex(/^org_[a-z2-7]{26}$/),
|
|
3742
3765
|
projectID: z.string().regex(/^proj_[a-z2-7]{26}$/)
|
|
@@ -3748,6 +3771,7 @@ var zDeleteProjectModelGrantPath = z.object({
|
|
|
3748
3771
|
modelGrantID: z.string().regex(/^pmog_[a-z2-7]{26}$/)
|
|
3749
3772
|
});
|
|
3750
3773
|
var zDeleteProjectModelGrantResponse = z.void();
|
|
3774
|
+
var zUpdateProjectModelGrantBody = zUpdateProjectModelGrantRequest;
|
|
3751
3775
|
var zUpdateProjectModelGrantPath = z.object({
|
|
3752
3776
|
orgID: z.string().regex(/^org_[a-z2-7]{26}$/),
|
|
3753
3777
|
projectID: z.string().regex(/^proj_[a-z2-7]{26}$/),
|
|
@@ -3796,6 +3820,7 @@ var zListProjectMachinePoolGrantsQuery = z.object({
|
|
|
3796
3820
|
cursor: z.string().max(1024).optional()
|
|
3797
3821
|
});
|
|
3798
3822
|
var zListProjectMachinePoolGrantsResponse2 = zListProjectMachinePoolGrantsResponse;
|
|
3823
|
+
var zCreateProjectMachinePoolGrantBody = zCreateProjectMachinePoolGrantRequest;
|
|
3799
3824
|
var zCreateProjectMachinePoolGrantHeaders = z.object({
|
|
3800
3825
|
"Idempotency-Key": z.string().min(1).max(255).optional()
|
|
3801
3826
|
});
|
|
@@ -3816,6 +3841,7 @@ var zGetProjectMachinePoolGrantPath = z.object({
|
|
|
3816
3841
|
poolGrantID: z.string().regex(/^pmpg_[a-z2-7]{26}$/)
|
|
3817
3842
|
});
|
|
3818
3843
|
var zGetProjectMachinePoolGrantResponse = zProjectMachinePoolGrant;
|
|
3844
|
+
var zUpdateProjectMachinePoolGrantBody = zUpdateProjectMachinePoolGrantRequest;
|
|
3819
3845
|
var zUpdateProjectMachinePoolGrantPath = z.object({
|
|
3820
3846
|
orgID: z.string().regex(/^org_[a-z2-7]{26}$/),
|
|
3821
3847
|
projectID: z.string().regex(/^proj_[a-z2-7]{26}$/),
|
|
@@ -6312,7 +6338,8 @@ function createOmnaraClient(options = {}) {
|
|
|
6312
6338
|
);
|
|
6313
6339
|
client2.setConfig({
|
|
6314
6340
|
baseUrl: options.baseUrl ?? "",
|
|
6315
|
-
credentials: options.credentials
|
|
6341
|
+
credentials: options.credentials,
|
|
6342
|
+
headers: options.headers
|
|
6316
6343
|
});
|
|
6317
6344
|
const { auth } = options;
|
|
6318
6345
|
if (auth) {
|
|
@@ -6390,10 +6417,10 @@ function defaultSleep(seconds) {
|
|
|
6390
6417
|
}
|
|
6391
6418
|
async function pollDeviceAuthToken(options) {
|
|
6392
6419
|
const fetchImpl = options.fetch ?? fetch;
|
|
6393
|
-
const
|
|
6420
|
+
const sleep2 = options.sleep ?? defaultSleep;
|
|
6394
6421
|
let interval = options.intervalSeconds;
|
|
6395
6422
|
while (true) {
|
|
6396
|
-
await
|
|
6423
|
+
await sleep2(interval);
|
|
6397
6424
|
const response = await postDeviceAuthJSON(
|
|
6398
6425
|
fetchImpl,
|
|
6399
6426
|
options.baseUrl,
|
|
@@ -6725,7 +6752,8 @@ function loadConfig() {
|
|
|
6725
6752
|
const token = process.env.OMNARA_API_KEY ?? file.token;
|
|
6726
6753
|
const client2 = createOmnaraClient({
|
|
6727
6754
|
baseUrl,
|
|
6728
|
-
auth: token ? bearerToken(token) : void 0
|
|
6755
|
+
auth: token ? bearerToken(token) : void 0,
|
|
6756
|
+
headers: { "User-Agent": "omnara-cli" }
|
|
6729
6757
|
});
|
|
6730
6758
|
return {
|
|
6731
6759
|
client: client2,
|
|
@@ -6952,7 +6980,8 @@ function plainReporter() {
|
|
|
6952
6980
|
stop(message) {
|
|
6953
6981
|
console.log(`${message}.`);
|
|
6954
6982
|
},
|
|
6955
|
-
fail() {
|
|
6983
|
+
fail(message) {
|
|
6984
|
+
console.error(message);
|
|
6956
6985
|
},
|
|
6957
6986
|
warn(message) {
|
|
6958
6987
|
console.error(`warning: ${message}`);
|
|
@@ -6961,6 +6990,7 @@ function plainReporter() {
|
|
|
6961
6990
|
console.log(message);
|
|
6962
6991
|
},
|
|
6963
6992
|
done() {
|
|
6993
|
+
console.log("Done");
|
|
6964
6994
|
}
|
|
6965
6995
|
};
|
|
6966
6996
|
}
|
|
@@ -6981,7 +7011,7 @@ function flowOp(spec) {
|
|
|
6981
7011
|
client: input.client,
|
|
6982
7012
|
path: parseWithSchema(spec.path, input.path, "arguments"),
|
|
6983
7013
|
body: parseWithSchema(spec.body, input.body, "flags"),
|
|
6984
|
-
report:
|
|
7014
|
+
report: createFlowReporter(spec.summary)
|
|
6985
7015
|
})
|
|
6986
7016
|
};
|
|
6987
7017
|
}
|
|
@@ -7113,7 +7143,9 @@ function planPathParams(path, positional) {
|
|
|
7113
7143
|
(param) => pathParams.includes(param.key) && !positional.includes(param.key)
|
|
7114
7144
|
);
|
|
7115
7145
|
return {
|
|
7116
|
-
positionalParams: pathParams.filter(
|
|
7146
|
+
positionalParams: pathParams.filter(
|
|
7147
|
+
(name) => !configParams.some((param) => param.key === name)
|
|
7148
|
+
),
|
|
7117
7149
|
configParams
|
|
7118
7150
|
};
|
|
7119
7151
|
}
|
|
@@ -7200,8 +7232,7 @@ function registerFlow(parent, config2, spec) {
|
|
|
7200
7232
|
await spec.execute({
|
|
7201
7233
|
client: config2.client,
|
|
7202
7234
|
path: await resolvePathValues(plan, args, options, config2),
|
|
7203
|
-
body: collectFlagValues(bodyFlags, options)
|
|
7204
|
-
report: createFlowReporter(spec.summary)
|
|
7235
|
+
body: collectFlagValues(bodyFlags, options)
|
|
7205
7236
|
});
|
|
7206
7237
|
});
|
|
7207
7238
|
});
|
|
@@ -7222,13 +7253,21 @@ import { intro as intro2, log as log2, note as note2, outro as outro2, spinner a
|
|
|
7222
7253
|
// src/browser.ts
|
|
7223
7254
|
import { spawn } from "node:child_process";
|
|
7224
7255
|
function browserCommand(url3) {
|
|
7225
|
-
if (process.platform === "darwin")
|
|
7226
|
-
|
|
7227
|
-
|
|
7256
|
+
if (process.platform === "darwin") {
|
|
7257
|
+
return { command: "open", args: [url3], windowsVerbatimArguments: false };
|
|
7258
|
+
}
|
|
7259
|
+
if (process.platform === "win32") {
|
|
7260
|
+
return {
|
|
7261
|
+
command: "cmd",
|
|
7262
|
+
args: ["/c", "start", '""', `"${url3}"`],
|
|
7263
|
+
windowsVerbatimArguments: true
|
|
7264
|
+
};
|
|
7265
|
+
}
|
|
7266
|
+
return { command: "xdg-open", args: [url3], windowsVerbatimArguments: false };
|
|
7228
7267
|
}
|
|
7229
7268
|
function openInBrowser(url3, onError) {
|
|
7230
|
-
const { command, args } = browserCommand(url3);
|
|
7231
|
-
const child = spawn(command, args, { stdio: "ignore", detached: true });
|
|
7269
|
+
const { command, args, windowsVerbatimArguments } = browserCommand(url3);
|
|
7270
|
+
const child = spawn(command, args, { stdio: "ignore", detached: true, windowsVerbatimArguments });
|
|
7232
7271
|
child.once("error", () => {
|
|
7233
7272
|
onError("could not open a browser; use the URL above");
|
|
7234
7273
|
});
|
|
@@ -7413,84 +7452,56 @@ function formatVoid(message = "ok") {
|
|
|
7413
7452
|
}
|
|
7414
7453
|
|
|
7415
7454
|
// src/mcp-add.ts
|
|
7455
|
+
import { isMap, isScalar as isScalar2, parseDocument } from "yaml";
|
|
7416
7456
|
import * as z8 from "zod";
|
|
7417
7457
|
|
|
7418
7458
|
// src/mcp-oauth.ts
|
|
7419
7459
|
import * as z7 from "zod";
|
|
7460
|
+
|
|
7461
|
+
// src/poll.ts
|
|
7420
7462
|
var POLL_INTERVAL_SECONDS = 2;
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
}
|
|
7424
|
-
function sameOwner(secret, owner) {
|
|
7425
|
-
if (secret.owner.kind !== owner.kind) return false;
|
|
7426
|
-
if (owner.kind !== "project") return true;
|
|
7427
|
-
return secret.owner.kind === "project" && secret.owner.project_id === owner.project_id;
|
|
7428
|
-
}
|
|
7429
|
-
async function matchingSecrets(client2, orgId, owner, name) {
|
|
7430
|
-
const { data } = await sdk_gen_exports.listSecrets({
|
|
7431
|
-
client: client2,
|
|
7432
|
-
path: { orgID: orgId },
|
|
7433
|
-
query: {
|
|
7434
|
-
name: exactGlob(name),
|
|
7435
|
-
kind: "oauth_token_set",
|
|
7436
|
-
owner_kind: owner.kind,
|
|
7437
|
-
...owner.kind === "project" ? { owner_project_id: owner.project_id } : {},
|
|
7438
|
-
limit: 100
|
|
7439
|
-
}
|
|
7440
|
-
});
|
|
7441
|
-
return data.data.filter((secret) => secret.name === name && sameOwner(secret, owner));
|
|
7442
|
-
}
|
|
7443
|
-
async function snapshotSecrets(client2, orgId, owner, name) {
|
|
7444
|
-
return new Map(
|
|
7445
|
-
(await matchingSecrets(client2, orgId, owner, name)).map((secret) => [
|
|
7446
|
-
secret.id,
|
|
7447
|
-
{ version: secret.current_version_number, updatedAt: secret.updated_at }
|
|
7448
|
-
])
|
|
7449
|
-
);
|
|
7450
|
-
}
|
|
7451
|
-
function changedSecret(secrets, before) {
|
|
7452
|
-
return secrets.find((secret) => {
|
|
7453
|
-
const previous = before.get(secret.id);
|
|
7454
|
-
return previous === void 0 || secret.current_version_number > previous.version || secret.updated_at !== previous.updatedAt;
|
|
7455
|
-
});
|
|
7456
|
-
}
|
|
7457
|
-
function defaultSleep2(seconds) {
|
|
7463
|
+
var MAX_CONSECUTIVE_POLL_FAILURES = 3;
|
|
7464
|
+
function sleep(seconds) {
|
|
7458
7465
|
return new Promise((resolve2) => setTimeout(resolve2, seconds * 1e3));
|
|
7459
7466
|
}
|
|
7460
|
-
async function
|
|
7461
|
-
const sleep = options.sleep ?? defaultSleep2;
|
|
7462
|
-
const now = options.now ?? Date.now;
|
|
7467
|
+
async function pollUntilDeadline(options) {
|
|
7463
7468
|
const deadline = Date.parse(options.expiresAt);
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
options.
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
7469
|
+
let consecutiveFailures = 0;
|
|
7470
|
+
while (true) {
|
|
7471
|
+
try {
|
|
7472
|
+
const found = await options.fetchOnce();
|
|
7473
|
+
consecutiveFailures = 0;
|
|
7474
|
+
if (found !== void 0) return found;
|
|
7475
|
+
} catch (error) {
|
|
7476
|
+
consecutiveFailures += 1;
|
|
7477
|
+
if (consecutiveFailures >= MAX_CONSECUTIVE_POLL_FAILURES) throw error;
|
|
7478
|
+
}
|
|
7479
|
+
const remainingSeconds = (deadline - Date.now()) / 1e3;
|
|
7480
|
+
if (remainingSeconds <= 0) break;
|
|
7481
|
+
await sleep(Math.min(POLL_INTERVAL_SECONDS, remainingSeconds));
|
|
7471
7482
|
}
|
|
7472
|
-
throw new CliInputError(
|
|
7483
|
+
throw new CliInputError(options.expiredMessage);
|
|
7473
7484
|
}
|
|
7485
|
+
|
|
7486
|
+
// src/mcp-oauth.ts
|
|
7474
7487
|
async function authorizeMcpOAuthSecret(options) {
|
|
7475
|
-
const before = await snapshotSecrets(
|
|
7476
|
-
options.client,
|
|
7477
|
-
options.orgId,
|
|
7478
|
-
options.request.owner,
|
|
7479
|
-
options.request.name
|
|
7480
|
-
);
|
|
7481
7488
|
const { data: start } = await sdk_gen_exports.startSecretMcpoAuth({
|
|
7482
7489
|
client: options.client,
|
|
7483
7490
|
path: { orgID: options.orgId },
|
|
7484
7491
|
body: options.request
|
|
7485
7492
|
});
|
|
7486
7493
|
options.onAuthorization(start.authorization_url);
|
|
7487
|
-
return
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
+
return pollUntilDeadline({
|
|
7495
|
+
expiresAt: start.expires_at,
|
|
7496
|
+
expiredMessage: "MCP OAuth authorization expired before the secret was created",
|
|
7497
|
+
async fetchOnce() {
|
|
7498
|
+
const { data } = await sdk_gen_exports.listSecrets({
|
|
7499
|
+
client: options.client,
|
|
7500
|
+
path: { orgID: options.orgId },
|
|
7501
|
+
query: { mcp_oauth_flow_id: start.flow_id, limit: 1 }
|
|
7502
|
+
});
|
|
7503
|
+
return data.data[0];
|
|
7504
|
+
}
|
|
7494
7505
|
});
|
|
7495
7506
|
}
|
|
7496
7507
|
var zBrowserFlag = z7.boolean().default(true).describe("open the authorization URL in a browser");
|
|
@@ -7539,98 +7550,63 @@ var zMcpAddBody = zMcpoAuthStartRequest.omit({ owner: true, name: true }).extend
|
|
|
7539
7550
|
function targetLabel(target) {
|
|
7540
7551
|
return target === "agent" ? "agent" : "agent profile";
|
|
7541
7552
|
}
|
|
7542
|
-
function isRecord(value) {
|
|
7543
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7544
|
-
}
|
|
7545
7553
|
function serverEntry(url3, secretId) {
|
|
7546
7554
|
return { url: url3, auth: { type: "oauth", secret_id: secretId } };
|
|
7547
7555
|
}
|
|
7556
|
+
var zJsonRecord = z8.record(z8.string(), z8.json());
|
|
7548
7557
|
function prepareJsonConfig(config2, serverName, mcpUrl) {
|
|
7549
|
-
let
|
|
7558
|
+
let parsedJson;
|
|
7550
7559
|
try {
|
|
7551
|
-
|
|
7560
|
+
parsedJson = JSON.parse(config2.source ?? "");
|
|
7552
7561
|
} catch {
|
|
7553
7562
|
throw new CliInputError("the current agent config contains invalid JSON");
|
|
7554
7563
|
}
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7564
|
+
const parsed = zJsonRecord.safeParse(parsedJson);
|
|
7565
|
+
if (!parsed.success) throw new CliInputError("the current agent config must be an object");
|
|
7566
|
+
const mcp = zJsonRecord.optional().safeParse(parsed.data.mcp);
|
|
7567
|
+
if (!mcp.success) {
|
|
7558
7568
|
throw new CliInputError("the current agent config has an invalid mcp section");
|
|
7559
7569
|
}
|
|
7560
|
-
if (
|
|
7570
|
+
if (mcp.data !== void 0 && Object.hasOwn(mcp.data, serverName)) {
|
|
7561
7571
|
throw new CliInputError(`MCP server ${serverName} already exists in the current config`);
|
|
7562
7572
|
}
|
|
7563
7573
|
return {
|
|
7564
7574
|
currentConfigId: config2.id,
|
|
7565
7575
|
render(secretId) {
|
|
7566
|
-
const
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7576
|
+
const updated = {
|
|
7577
|
+
...parsed.data,
|
|
7578
|
+
mcp: { ...mcp.data, [serverName]: serverEntry(mcpUrl, secretId) }
|
|
7579
|
+
};
|
|
7580
|
+
return { source: `${JSON.stringify(updated, null, 2)}
|
|
7570
7581
|
`, sourceFormat: "json" };
|
|
7571
7582
|
}
|
|
7572
7583
|
};
|
|
7573
7584
|
}
|
|
7574
7585
|
function prepareYamlConfig(config2, serverName, mcpUrl) {
|
|
7575
|
-
const
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
];
|
|
7590
|
-
};
|
|
7591
|
-
let sectionEnd = lines.length;
|
|
7592
|
-
let childIndent = 2;
|
|
7593
|
-
if (mcpIndex !== -1) {
|
|
7594
|
-
const declaration = lines[mcpIndex] ?? "";
|
|
7595
|
-
const remainder = declaration.replace(/^mcp\s*:\s*/, "");
|
|
7596
|
-
if (!/^(?:#.*)?$/.test(remainder) && !/^\{\s*\}(?:\s*#.*)?$/.test(remainder)) {
|
|
7597
|
-
throw new CliInputError("mcp-add cannot edit an inline YAML mcp mapping");
|
|
7598
|
-
}
|
|
7599
|
-
for (let index = mcpIndex + 1; index < lines.length; index += 1) {
|
|
7600
|
-
const line = lines[index] ?? "";
|
|
7601
|
-
if (/^[^\s#]/.test(line)) {
|
|
7602
|
-
sectionEnd = index;
|
|
7603
|
-
break;
|
|
7604
|
-
}
|
|
7605
|
-
}
|
|
7606
|
-
const firstEntry = lines.slice(mcpIndex + 1, sectionEnd).find((line) => /^\s+\S/.test(line) && !/^\s*#/.test(line));
|
|
7607
|
-
const indent = firstEntry?.match(/^(\s+)/)?.[1]?.length;
|
|
7608
|
-
if (indent !== void 0) childIndent = indent;
|
|
7609
|
-
const existingPattern = new RegExp(`^\\s{${childIndent}}["']?${quotedServerName}["']?\\s*:`);
|
|
7610
|
-
if (lines.slice(mcpIndex + 1, sectionEnd).some((line) => existingPattern.test(line))) {
|
|
7611
|
-
throw new CliInputError(`MCP server ${serverName} already exists in the current config`);
|
|
7612
|
-
}
|
|
7586
|
+
const doc = parseDocument(config2.source ?? "");
|
|
7587
|
+
if (doc.errors.length > 0) {
|
|
7588
|
+
throw new CliInputError("the current agent config contains invalid YAML");
|
|
7589
|
+
}
|
|
7590
|
+
if (doc.contents !== null && !isMap(doc.contents)) {
|
|
7591
|
+
throw new CliInputError("the current agent config must be an object");
|
|
7592
|
+
}
|
|
7593
|
+
const mcp = doc.get("mcp", true);
|
|
7594
|
+
const emptyMcp = isScalar2(mcp) && mcp.value === null;
|
|
7595
|
+
if (mcp !== void 0 && !emptyMcp && !isMap(mcp)) {
|
|
7596
|
+
throw new CliInputError("the current agent config has an invalid mcp section");
|
|
7597
|
+
}
|
|
7598
|
+
if (isMap(mcp) && doc.hasIn(["mcp", serverName])) {
|
|
7599
|
+
throw new CliInputError(`MCP server ${serverName} already exists in the current config`);
|
|
7613
7600
|
}
|
|
7614
7601
|
return {
|
|
7615
7602
|
currentConfigId: config2.id,
|
|
7616
7603
|
render(secretId) {
|
|
7617
|
-
if (
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
source: `${base}${separator}mcp:
|
|
7622
|
-
${entry(2, secretId).join("\n")}
|
|
7623
|
-
`,
|
|
7624
|
-
sourceFormat: "yaml"
|
|
7625
|
-
};
|
|
7626
|
-
}
|
|
7627
|
-
const updated = [...lines];
|
|
7628
|
-
if (/^\{\s*\}/.test((updated[mcpIndex] ?? "").replace(/^mcp\s*:\s*/, ""))) {
|
|
7629
|
-
updated[mcpIndex] = "mcp:";
|
|
7604
|
+
if (isMap(mcp)) {
|
|
7605
|
+
doc.setIn(["mcp", serverName], serverEntry(mcpUrl, secretId));
|
|
7606
|
+
} else {
|
|
7607
|
+
doc.set("mcp", { [serverName]: serverEntry(mcpUrl, secretId) });
|
|
7630
7608
|
}
|
|
7631
|
-
|
|
7632
|
-
return { source: `${updated.join("\n").trimEnd()}
|
|
7633
|
-
`, sourceFormat: "yaml" };
|
|
7609
|
+
return { source: doc.toString(), sourceFormat: "yaml" };
|
|
7634
7610
|
}
|
|
7635
7611
|
};
|
|
7636
7612
|
}
|
|
@@ -7655,19 +7631,7 @@ async function loadConfig2(client2, scope, target, targetId) {
|
|
|
7655
7631
|
if (configId === void 0) throw new CliInputError("the agent has no current config");
|
|
7656
7632
|
return (await sdk_gen_exports.getAgentConfig({ client: client2, path: { ...path, agentConfigID: configId } })).data;
|
|
7657
7633
|
}
|
|
7658
|
-
function
|
|
7659
|
-
return {
|
|
7660
|
-
owner: { kind: "project", project_id: projectId },
|
|
7661
|
-
name: body.secret_name ?? `${body.server_name}-mcp`,
|
|
7662
|
-
mcp_url: body.mcp_url,
|
|
7663
|
-
...body.return_to !== void 0 ? { return_to: body.return_to } : {},
|
|
7664
|
-
...body.client_id !== void 0 ? { client_id: body.client_id } : {},
|
|
7665
|
-
...body.client_secret !== void 0 ? { client_secret: body.client_secret } : {},
|
|
7666
|
-
...body.scopes !== void 0 ? { scopes: body.scopes } : {},
|
|
7667
|
-
...body.metadata !== void 0 ? { metadata: body.metadata } : {}
|
|
7668
|
-
};
|
|
7669
|
-
}
|
|
7670
|
-
async function applyConfig(client2, scope, target, targetId, prepared, secret) {
|
|
7634
|
+
async function applyConfig(client2, scope, target, targetId, prepared, secret, report) {
|
|
7671
7635
|
const rendered = prepared.render(secret.id);
|
|
7672
7636
|
const path = { orgID: scope.orgId, projectID: scope.projectId };
|
|
7673
7637
|
if (target === "agent") {
|
|
@@ -7687,11 +7651,16 @@ async function applyConfig(client2, scope, target, targetId, prepared, secret) {
|
|
|
7687
7651
|
path,
|
|
7688
7652
|
body: { source: rendered.source, source_format: rendered.sourceFormat }
|
|
7689
7653
|
});
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7654
|
+
try {
|
|
7655
|
+
await sdk_gen_exports.updateAgentProfile({
|
|
7656
|
+
client: client2,
|
|
7657
|
+
path: { ...path, agentProfileID: targetId },
|
|
7658
|
+
body: { config: config2.id, expected_current_config_id: prepared.currentConfigId }
|
|
7659
|
+
});
|
|
7660
|
+
} catch (error) {
|
|
7661
|
+
report.warn(`agent config ${config2.id} was created, but the agent profile was not updated`);
|
|
7662
|
+
throw error;
|
|
7663
|
+
}
|
|
7695
7664
|
return config2.id;
|
|
7696
7665
|
}
|
|
7697
7666
|
async function runMcpAdd(context, target, targetId) {
|
|
@@ -7700,9 +7669,14 @@ async function runMcpAdd(context, target, targetId) {
|
|
|
7700
7669
|
orgId: context.path.orgID,
|
|
7701
7670
|
projectId: context.path.projectID
|
|
7702
7671
|
};
|
|
7703
|
-
const
|
|
7672
|
+
const { server_name, secret_name, browser, ...oauthFields } = body;
|
|
7673
|
+
const request = {
|
|
7674
|
+
...oauthFields,
|
|
7675
|
+
owner: { kind: "project", project_id: scope.projectId },
|
|
7676
|
+
name: secret_name ?? `${server_name}-mcp`
|
|
7677
|
+
};
|
|
7704
7678
|
const currentConfig = await loadConfig2(client2, scope, target, targetId);
|
|
7705
|
-
const prepared = prepareConfig(currentConfig,
|
|
7679
|
+
const prepared = prepareConfig(currentConfig, server_name, request.mcp_url);
|
|
7706
7680
|
let secret;
|
|
7707
7681
|
try {
|
|
7708
7682
|
secret = await authorizeMcpOAuthSecret({
|
|
@@ -7710,7 +7684,7 @@ async function runMcpAdd(context, target, targetId) {
|
|
|
7710
7684
|
orgId: scope.orgId,
|
|
7711
7685
|
request,
|
|
7712
7686
|
onAuthorization(url3) {
|
|
7713
|
-
openAuthorizationUrl(report, "Authorize this MCP server in your browser", url3,
|
|
7687
|
+
openAuthorizationUrl(report, "Authorize this MCP server in your browser", url3, browser);
|
|
7714
7688
|
report.start("Waiting for the MCP OAuth secret to be created");
|
|
7715
7689
|
}
|
|
7716
7690
|
});
|
|
@@ -7722,10 +7696,12 @@ async function runMcpAdd(context, target, targetId) {
|
|
|
7722
7696
|
report.start(`Updating the ${targetLabel(target)} config`);
|
|
7723
7697
|
let configId;
|
|
7724
7698
|
try {
|
|
7725
|
-
configId = await applyConfig(client2, scope, target, targetId, prepared, secret);
|
|
7699
|
+
configId = await applyConfig(client2, scope, target, targetId, prepared, secret, report);
|
|
7726
7700
|
} catch (error) {
|
|
7727
7701
|
report.fail("Config update failed");
|
|
7728
|
-
report.warn(
|
|
7702
|
+
report.warn(
|
|
7703
|
+
`OAuth secret ${secret.id} was created, but the ${targetLabel(target)} was not updated`
|
|
7704
|
+
);
|
|
7729
7705
|
throw error;
|
|
7730
7706
|
}
|
|
7731
7707
|
report.stop("Config updated");
|
|
@@ -7790,7 +7766,6 @@ async function loadSkillArchive(archivePath) {
|
|
|
7790
7766
|
|
|
7791
7767
|
// src/slack-integration.ts
|
|
7792
7768
|
import * as z10 from "zod";
|
|
7793
|
-
var POLL_INTERVAL_SECONDS2 = 2;
|
|
7794
7769
|
var zSlackBody = z10.object({
|
|
7795
7770
|
app_name: z10.string().optional().describe("name for a new Slack app"),
|
|
7796
7771
|
app_configuration_token: z10.string().optional().describe("Slack app configuration token for a new app"),
|
|
@@ -7856,88 +7831,54 @@ Pass --app-name and --app-configuration-token, or existing app credentials.`
|
|
|
7856
7831
|
}
|
|
7857
7832
|
return { kind: "create-app", body: result.data };
|
|
7858
7833
|
}
|
|
7859
|
-
async function profileSlackIntegrations(client2, orgId, projectId, profileId) {
|
|
7860
|
-
const { data } = await sdk_gen_exports.listIntegrationInstalls({
|
|
7861
|
-
client: client2,
|
|
7862
|
-
path: { orgID: orgId, projectID: projectId },
|
|
7863
|
-
query: { agent_profile_id: profileId, limit: 100 }
|
|
7864
|
-
});
|
|
7865
|
-
return data.data.filter(
|
|
7866
|
-
(install) => install.provider === "slack" && install.agent_profile_id === profileId
|
|
7867
|
-
);
|
|
7868
|
-
}
|
|
7869
|
-
async function snapshotIntegrations(client2, orgId, projectId, profileId) {
|
|
7870
|
-
return new Map(
|
|
7871
|
-
(await profileSlackIntegrations(client2, orgId, projectId, profileId)).map((install) => [
|
|
7872
|
-
install.id,
|
|
7873
|
-
{ state: install.state, updatedAt: install.updated_at }
|
|
7874
|
-
])
|
|
7875
|
-
);
|
|
7876
|
-
}
|
|
7877
|
-
function changedIntegration(integrations, before, expectedProviderAccountRef) {
|
|
7878
|
-
return integrations.find((integration) => {
|
|
7879
|
-
if (expectedProviderAccountRef !== void 0 && integration.provider_account_ref !== expectedProviderAccountRef) {
|
|
7880
|
-
return false;
|
|
7881
|
-
}
|
|
7882
|
-
const previous = before.get(integration.id);
|
|
7883
|
-
if (previous === void 0) return true;
|
|
7884
|
-
return integration.state !== previous.state || integration.updated_at !== previous.updatedAt;
|
|
7885
|
-
});
|
|
7886
|
-
}
|
|
7887
|
-
function defaultSleep3(seconds) {
|
|
7888
|
-
return new Promise((resolve2) => setTimeout(resolve2, seconds * 1e3));
|
|
7889
|
-
}
|
|
7890
|
-
async function pollForSlackIntegration(options) {
|
|
7891
|
-
const sleep = options.sleep ?? defaultSleep3;
|
|
7892
|
-
const now = options.now ?? Date.now;
|
|
7893
|
-
const deadline = Date.parse(options.expiresAt);
|
|
7894
|
-
while (now() < deadline) {
|
|
7895
|
-
const created = changedIntegration(
|
|
7896
|
-
await profileSlackIntegrations(
|
|
7897
|
-
options.client,
|
|
7898
|
-
options.orgId,
|
|
7899
|
-
options.projectId,
|
|
7900
|
-
options.profileId
|
|
7901
|
-
),
|
|
7902
|
-
options.before,
|
|
7903
|
-
options.expectedProviderAccountRef
|
|
7904
|
-
);
|
|
7905
|
-
if (created !== void 0) return created;
|
|
7906
|
-
await sleep(Math.min(POLL_INTERVAL_SECONDS2, Math.max(0, (deadline - now()) / 1e3)));
|
|
7907
|
-
}
|
|
7908
|
-
throw new CliInputError("Slack authorization expired before the integration was created");
|
|
7909
|
-
}
|
|
7910
7834
|
async function runSlackIntegration(context) {
|
|
7911
7835
|
const { client: client2, path, body, report } = context;
|
|
7912
7836
|
const request = parseRequest(body);
|
|
7913
|
-
const before = await snapshotIntegrations(client2, path.orgID, path.projectID, path.agentProfileID);
|
|
7914
7837
|
const setupPath = {
|
|
7915
7838
|
orgID: path.orgID,
|
|
7916
7839
|
projectID: path.projectID,
|
|
7917
7840
|
agentProfileID: path.agentProfileID
|
|
7918
7841
|
};
|
|
7919
|
-
|
|
7920
|
-
|
|
7842
|
+
let start;
|
|
7843
|
+
let slackAppId;
|
|
7844
|
+
if (request.kind === "create-app") {
|
|
7845
|
+
const { data } = await sdk_gen_exports.createSlackSetup({ client: client2, path: setupPath, body: request.body });
|
|
7846
|
+
start = data;
|
|
7847
|
+
slackAppId = data.slack_app_id;
|
|
7848
|
+
} else {
|
|
7849
|
+
const { data } = await sdk_gen_exports.createIntegrationOAuthSetup({
|
|
7850
|
+
client: client2,
|
|
7851
|
+
path: setupPath,
|
|
7852
|
+
body: request.body
|
|
7853
|
+
});
|
|
7854
|
+
start = data;
|
|
7855
|
+
}
|
|
7921
7856
|
openAuthorizationUrl(
|
|
7922
7857
|
report,
|
|
7923
7858
|
"Approve the Slack integration in your browser",
|
|
7924
|
-
start.
|
|
7859
|
+
start.oauth_url,
|
|
7925
7860
|
body.browser
|
|
7926
7861
|
);
|
|
7927
7862
|
report.start("Waiting for the Slack integration to be created");
|
|
7928
7863
|
let integration;
|
|
7929
7864
|
try {
|
|
7930
|
-
integration = await
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7865
|
+
integration = await pollUntilDeadline({
|
|
7866
|
+
expiresAt: start.expires_at,
|
|
7867
|
+
expiredMessage: "Slack authorization expired before the integration was created",
|
|
7868
|
+
async fetchOnce() {
|
|
7869
|
+
const { data } = await sdk_gen_exports.listIntegrationInstalls({
|
|
7870
|
+
client: client2,
|
|
7871
|
+
path: { orgID: path.orgID, projectID: path.projectID },
|
|
7872
|
+
query: { oauth_flow_id: start.flow_id, limit: 1 }
|
|
7873
|
+
});
|
|
7874
|
+
return data.data[0];
|
|
7875
|
+
}
|
|
7938
7876
|
});
|
|
7939
7877
|
} catch (error) {
|
|
7940
7878
|
report.fail("Slack authorization failed");
|
|
7879
|
+
if (slackAppId !== void 0) {
|
|
7880
|
+
report.warn(`Slack app ${slackAppId} was created, but the integration was not completed`);
|
|
7881
|
+
}
|
|
7941
7882
|
throw error;
|
|
7942
7883
|
}
|
|
7943
7884
|
report.stop("Slack integration created");
|
|
@@ -8625,6 +8566,213 @@ var commandGroups = [
|
|
|
8625
8566
|
path: zDeleteCronTriggerPath
|
|
8626
8567
|
})
|
|
8627
8568
|
]
|
|
8569
|
+
},
|
|
8570
|
+
{
|
|
8571
|
+
name: "grant",
|
|
8572
|
+
aliases: ["grants"],
|
|
8573
|
+
summary: "Manage resource grants to projects",
|
|
8574
|
+
groups: [
|
|
8575
|
+
{
|
|
8576
|
+
name: "skills",
|
|
8577
|
+
aliases: ["skill"],
|
|
8578
|
+
summary: "Manage skill grants",
|
|
8579
|
+
operations: [
|
|
8580
|
+
op({
|
|
8581
|
+
verb: "list",
|
|
8582
|
+
summary: "List a skill's project grants",
|
|
8583
|
+
fn: sdk_gen_exports.listSkillGrants,
|
|
8584
|
+
format: (response) => formatTable(["id", "target_project", "target_project_id", "created_at"])({
|
|
8585
|
+
data: response.data.map((item) => ({
|
|
8586
|
+
...item.grant,
|
|
8587
|
+
target_project: item.target_project.name
|
|
8588
|
+
})),
|
|
8589
|
+
next_cursor: response.next_cursor
|
|
8590
|
+
}),
|
|
8591
|
+
path: zListSkillGrantsPath,
|
|
8592
|
+
query: zListSkillGrantsQuery
|
|
8593
|
+
}),
|
|
8594
|
+
op({
|
|
8595
|
+
verb: "add",
|
|
8596
|
+
summary: "Grant a skill to a project",
|
|
8597
|
+
fn: sdk_gen_exports.createSkillGrant,
|
|
8598
|
+
format: formatRecord(),
|
|
8599
|
+
path: zCreateSkillGrantPath,
|
|
8600
|
+
body: zCreateSkillGrantBody
|
|
8601
|
+
}),
|
|
8602
|
+
op({
|
|
8603
|
+
verb: "delete",
|
|
8604
|
+
summary: "Remove a skill grant",
|
|
8605
|
+
fn: sdk_gen_exports.deleteSkillGrant,
|
|
8606
|
+
format: formatVoid("deleted"),
|
|
8607
|
+
path: zDeleteSkillGrantPath
|
|
8608
|
+
})
|
|
8609
|
+
]
|
|
8610
|
+
},
|
|
8611
|
+
{
|
|
8612
|
+
name: "secrets",
|
|
8613
|
+
aliases: ["secret"],
|
|
8614
|
+
summary: "Manage secret grants",
|
|
8615
|
+
operations: [
|
|
8616
|
+
op({
|
|
8617
|
+
verb: "list",
|
|
8618
|
+
summary: "List a secret's project grants",
|
|
8619
|
+
fn: sdk_gen_exports.listSecretGrants,
|
|
8620
|
+
format: (response) => formatTable(["id", "target_project", "target_project_id", "created_at"])({
|
|
8621
|
+
data: response.data.map((item) => ({
|
|
8622
|
+
...item.grant,
|
|
8623
|
+
target_project: item.target_project.name
|
|
8624
|
+
})),
|
|
8625
|
+
next_cursor: response.next_cursor
|
|
8626
|
+
}),
|
|
8627
|
+
path: zListSecretGrantsPath,
|
|
8628
|
+
query: zListSecretGrantsQuery
|
|
8629
|
+
}),
|
|
8630
|
+
op({
|
|
8631
|
+
verb: "add",
|
|
8632
|
+
summary: "Grant a secret to a project",
|
|
8633
|
+
fn: sdk_gen_exports.createSecretGrant,
|
|
8634
|
+
format: formatRecord(),
|
|
8635
|
+
path: zCreateSecretGrantPath,
|
|
8636
|
+
body: zCreateSecretGrantBody
|
|
8637
|
+
}),
|
|
8638
|
+
op({
|
|
8639
|
+
verb: "delete",
|
|
8640
|
+
summary: "Remove a secret grant",
|
|
8641
|
+
fn: sdk_gen_exports.deleteSecretGrant,
|
|
8642
|
+
format: formatVoid("deleted"),
|
|
8643
|
+
path: zDeleteSecretGrantPath
|
|
8644
|
+
})
|
|
8645
|
+
]
|
|
8646
|
+
},
|
|
8647
|
+
{
|
|
8648
|
+
name: "machines",
|
|
8649
|
+
aliases: ["machine"],
|
|
8650
|
+
summary: "Manage machine grants in a project",
|
|
8651
|
+
operations: [
|
|
8652
|
+
op({
|
|
8653
|
+
verb: "list",
|
|
8654
|
+
summary: "List a project's explicit machine grants",
|
|
8655
|
+
fn: sdk_gen_exports.listProjectMachineGrants,
|
|
8656
|
+
format: (response) => formatTable(["id", "machine", "machine_id", "source_kind", "created_at"])({
|
|
8657
|
+
data: response.data.map((item) => ({
|
|
8658
|
+
...item.grant,
|
|
8659
|
+
machine: item.machine.display_name
|
|
8660
|
+
})),
|
|
8661
|
+
next_cursor: response.next_cursor
|
|
8662
|
+
}),
|
|
8663
|
+
path: zListProjectMachineGrantsPath,
|
|
8664
|
+
query: zListProjectMachineGrantsQuery
|
|
8665
|
+
}),
|
|
8666
|
+
op({
|
|
8667
|
+
verb: "add",
|
|
8668
|
+
summary: "Grant a machine to a project",
|
|
8669
|
+
fn: sdk_gen_exports.createProjectMachineGrant,
|
|
8670
|
+
format: (response) => formatRecord()(response.grant),
|
|
8671
|
+
path: zCreateProjectMachineGrantPath,
|
|
8672
|
+
body: zCreateProjectMachineGrantBody
|
|
8673
|
+
}),
|
|
8674
|
+
op({
|
|
8675
|
+
verb: "delete",
|
|
8676
|
+
summary: "Remove a machine grant",
|
|
8677
|
+
fn: sdk_gen_exports.deleteProjectMachineGrant,
|
|
8678
|
+
format: formatVoid("deleted"),
|
|
8679
|
+
path: zDeleteProjectMachineGrantPath
|
|
8680
|
+
})
|
|
8681
|
+
]
|
|
8682
|
+
},
|
|
8683
|
+
{
|
|
8684
|
+
name: "pools",
|
|
8685
|
+
aliases: ["pool"],
|
|
8686
|
+
summary: "Manage machine pool grants in a project",
|
|
8687
|
+
operations: [
|
|
8688
|
+
op({
|
|
8689
|
+
verb: "list",
|
|
8690
|
+
summary: "List a project's machine pool grants",
|
|
8691
|
+
fn: sdk_gen_exports.listProjectMachinePoolGrants,
|
|
8692
|
+
format: (response) => formatTable(["id", "machine_pool", "machine_pool_id", "description", "created_at"])({
|
|
8693
|
+
data: response.data.map((item) => ({
|
|
8694
|
+
...item.grant,
|
|
8695
|
+
machine_pool: item.machine_pool.name
|
|
8696
|
+
})),
|
|
8697
|
+
next_cursor: response.next_cursor
|
|
8698
|
+
}),
|
|
8699
|
+
path: zListProjectMachinePoolGrantsPath,
|
|
8700
|
+
query: zListProjectMachinePoolGrantsQuery
|
|
8701
|
+
}),
|
|
8702
|
+
op({
|
|
8703
|
+
verb: "get",
|
|
8704
|
+
summary: "Fetch a machine pool grant",
|
|
8705
|
+
fn: sdk_gen_exports.getProjectMachinePoolGrant,
|
|
8706
|
+
format: formatRecord(),
|
|
8707
|
+
path: zGetProjectMachinePoolGrantPath
|
|
8708
|
+
}),
|
|
8709
|
+
op({
|
|
8710
|
+
verb: "add",
|
|
8711
|
+
summary: "Grant a machine pool to a project",
|
|
8712
|
+
fn: sdk_gen_exports.createProjectMachinePoolGrant,
|
|
8713
|
+
format: formatRecord(),
|
|
8714
|
+
path: zCreateProjectMachinePoolGrantPath,
|
|
8715
|
+
body: zCreateProjectMachinePoolGrantBody
|
|
8716
|
+
}),
|
|
8717
|
+
op({
|
|
8718
|
+
verb: "edit",
|
|
8719
|
+
summary: "Edit a machine pool grant's overrides",
|
|
8720
|
+
fn: sdk_gen_exports.updateProjectMachinePoolGrant,
|
|
8721
|
+
format: formatRecord(),
|
|
8722
|
+
path: zUpdateProjectMachinePoolGrantPath,
|
|
8723
|
+
body: zUpdateProjectMachinePoolGrantBody
|
|
8724
|
+
}),
|
|
8725
|
+
op({
|
|
8726
|
+
verb: "delete",
|
|
8727
|
+
summary: "Remove a machine pool grant",
|
|
8728
|
+
fn: sdk_gen_exports.deleteProjectMachinePoolGrant,
|
|
8729
|
+
format: formatVoid("deleted"),
|
|
8730
|
+
path: zDeleteProjectMachinePoolGrantPath
|
|
8731
|
+
})
|
|
8732
|
+
]
|
|
8733
|
+
},
|
|
8734
|
+
{
|
|
8735
|
+
name: "models",
|
|
8736
|
+
aliases: ["model"],
|
|
8737
|
+
summary: "Manage model grants in a project",
|
|
8738
|
+
operations: [
|
|
8739
|
+
op({
|
|
8740
|
+
verb: "list",
|
|
8741
|
+
summary: "List a project's model grants",
|
|
8742
|
+
fn: sdk_gen_exports.listProjectModelGrants,
|
|
8743
|
+
format: (response) => formatTable(["id", "model", "configured_model_id", "created_at"])({
|
|
8744
|
+
data: response.data.map((item) => ({ ...item.grant, model: item.model.name })),
|
|
8745
|
+
next_cursor: response.next_cursor
|
|
8746
|
+
}),
|
|
8747
|
+
path: zListProjectModelGrantsPath,
|
|
8748
|
+
query: zListProjectModelGrantsQuery
|
|
8749
|
+
}),
|
|
8750
|
+
op({
|
|
8751
|
+
verb: "add",
|
|
8752
|
+
summary: "Grant a configured model to a project",
|
|
8753
|
+
fn: sdk_gen_exports.createProjectModelGrant,
|
|
8754
|
+
format: (response) => formatRecord()(response.grant),
|
|
8755
|
+
path: zCreateProjectModelGrantPath,
|
|
8756
|
+
body: zCreateProjectModelGrantBody
|
|
8757
|
+
}),
|
|
8758
|
+
op({
|
|
8759
|
+
verb: "edit",
|
|
8760
|
+
summary: "Edit a model grant's overrides",
|
|
8761
|
+
fn: sdk_gen_exports.updateProjectModelGrant,
|
|
8762
|
+
format: (response) => formatRecord()(response.grant),
|
|
8763
|
+
path: zUpdateProjectModelGrantPath,
|
|
8764
|
+
body: zUpdateProjectModelGrantBody
|
|
8765
|
+
}),
|
|
8766
|
+
op({
|
|
8767
|
+
verb: "delete",
|
|
8768
|
+
summary: "Remove a model grant",
|
|
8769
|
+
fn: sdk_gen_exports.deleteProjectModelGrant,
|
|
8770
|
+
format: formatVoid("deleted"),
|
|
8771
|
+
path: zDeleteProjectModelGrantPath
|
|
8772
|
+
})
|
|
8773
|
+
]
|
|
8774
|
+
}
|
|
8775
|
+
]
|
|
8628
8776
|
}
|
|
8629
8777
|
];
|
|
8630
8778
|
var topLevelOperations = [
|
package/package.json
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnara",
|
|
3
|
-
"version": "1.0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Command-line interface for Omnara: launch and manage agents, organizations, integrations, and MCP servers",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://omnara.com",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/omnara-ai/omnara.git",
|
|
10
|
+
"directory": "frontend/packages/cli"
|
|
11
|
+
},
|
|
4
12
|
"type": "module",
|
|
5
13
|
"engines": {
|
|
6
|
-
"node": ">=
|
|
14
|
+
"node": ">=22"
|
|
7
15
|
},
|
|
8
16
|
"bin": {
|
|
9
17
|
"omnara": "./dist/bin.js"
|
|
@@ -15,6 +23,7 @@
|
|
|
15
23
|
"@clack/prompts": "^1.7.0",
|
|
16
24
|
"commander": "^14.0.0",
|
|
17
25
|
"tar": "^7.5.22",
|
|
26
|
+
"yaml": "^2.9.0",
|
|
18
27
|
"zod": "^4.4.3"
|
|
19
28
|
},
|
|
20
29
|
"devDependencies": {
|
|
@@ -26,7 +35,7 @@
|
|
|
26
35
|
"@omnara/sdk": "0.0.0"
|
|
27
36
|
},
|
|
28
37
|
"scripts": {
|
|
29
|
-
"build": "esbuild src/bin.ts --bundle --platform=node --format=esm --target=
|
|
38
|
+
"build": "esbuild src/bin.ts --bundle --platform=node --format=esm --target=node22 --outfile=dist/bin.js --banner:js='#!/usr/bin/env node' --external:@clack/prompts --external:commander --external:tar --external:yaml --external:zod",
|
|
30
39
|
"omnara": "tsx src/bin.ts",
|
|
31
40
|
"test": "vitest run",
|
|
32
41
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|