thinkwork-cli 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +123 -10
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
|
+
};
|
|
2
7
|
|
|
3
8
|
// src/cli.ts
|
|
4
9
|
import { Command } from "commander";
|
|
@@ -2690,7 +2695,116 @@ and AgentCore for per-stage detail.
|
|
|
2690
2695
|
|
|
2691
2696
|
// src/commands/mcp.ts
|
|
2692
2697
|
import chalk10 from "chalk";
|
|
2693
|
-
|
|
2698
|
+
|
|
2699
|
+
// ../../packages/admin-ops/src/client.ts
|
|
2700
|
+
var AdminOpsError = class extends Error {
|
|
2701
|
+
status;
|
|
2702
|
+
body;
|
|
2703
|
+
constructor(status, message, body) {
|
|
2704
|
+
super(message);
|
|
2705
|
+
this.name = "AdminOpsError";
|
|
2706
|
+
this.status = status;
|
|
2707
|
+
this.body = body;
|
|
2708
|
+
}
|
|
2709
|
+
};
|
|
2710
|
+
function createClient(config) {
|
|
2711
|
+
const fetchImpl = config.fetchImpl ?? fetch;
|
|
2712
|
+
const base = config.apiUrl.replace(/\/+$/, "");
|
|
2713
|
+
const doFetch = async (path2, init = {}) => {
|
|
2714
|
+
const headers = {
|
|
2715
|
+
"Content-Type": "application/json",
|
|
2716
|
+
Authorization: `Bearer ${config.authSecret}`,
|
|
2717
|
+
"x-api-key": config.authSecret
|
|
2718
|
+
};
|
|
2719
|
+
if (config.principalId) headers["x-principal-id"] = config.principalId;
|
|
2720
|
+
if (config.principalEmail) headers["x-principal-email"] = config.principalEmail;
|
|
2721
|
+
if (config.tenantId) headers["x-tenant-id"] = config.tenantId;
|
|
2722
|
+
if (config.agentId) headers["x-agent-id"] = config.agentId;
|
|
2723
|
+
const res = await fetchImpl(`${base}${path2}`, {
|
|
2724
|
+
...init,
|
|
2725
|
+
headers: { ...headers, ...init.headers }
|
|
2726
|
+
});
|
|
2727
|
+
if (!res.ok) {
|
|
2728
|
+
const body = await res.json().catch(() => ({}));
|
|
2729
|
+
const message = body.error ?? `HTTP ${res.status}`;
|
|
2730
|
+
throw new AdminOpsError(res.status, message, body);
|
|
2731
|
+
}
|
|
2732
|
+
return res.json();
|
|
2733
|
+
};
|
|
2734
|
+
const doGraphql = async (query, variables) => {
|
|
2735
|
+
const res = await doFetch("/graphql", {
|
|
2736
|
+
method: "POST",
|
|
2737
|
+
body: JSON.stringify({ query, variables: variables ?? {} })
|
|
2738
|
+
});
|
|
2739
|
+
if (res.errors && res.errors.length > 0) {
|
|
2740
|
+
const msg = res.errors.map((e) => e.message).join("; ");
|
|
2741
|
+
throw new AdminOpsError(200, msg, res);
|
|
2742
|
+
}
|
|
2743
|
+
return res.data;
|
|
2744
|
+
};
|
|
2745
|
+
return {
|
|
2746
|
+
apiUrl: base,
|
|
2747
|
+
tenantId: config.tenantId,
|
|
2748
|
+
fetch: doFetch,
|
|
2749
|
+
graphql: doGraphql,
|
|
2750
|
+
withTenant(tenantId) {
|
|
2751
|
+
return createClient({ ...config, tenantId });
|
|
2752
|
+
}
|
|
2753
|
+
};
|
|
2754
|
+
}
|
|
2755
|
+
|
|
2756
|
+
// ../../packages/admin-ops/src/tenants.ts
|
|
2757
|
+
var tenants_exports = {};
|
|
2758
|
+
__export(tenants_exports, {
|
|
2759
|
+
getTenant: () => getTenant,
|
|
2760
|
+
getTenantBySlug: () => getTenantBySlug,
|
|
2761
|
+
listTenants: () => listTenants,
|
|
2762
|
+
updateTenant: () => updateTenant
|
|
2763
|
+
});
|
|
2764
|
+
async function listTenants(client) {
|
|
2765
|
+
return client.fetch("/api/tenants");
|
|
2766
|
+
}
|
|
2767
|
+
async function getTenant(client, id) {
|
|
2768
|
+
return client.fetch(`/api/tenants/${encodeURIComponent(id)}`);
|
|
2769
|
+
}
|
|
2770
|
+
async function getTenantBySlug(client, slug) {
|
|
2771
|
+
return client.fetch(`/api/tenants/by-slug/${encodeURIComponent(slug)}`);
|
|
2772
|
+
}
|
|
2773
|
+
async function updateTenant(client, id, input4) {
|
|
2774
|
+
return client.fetch(`/api/tenants/${encodeURIComponent(id)}`, {
|
|
2775
|
+
method: "PUT",
|
|
2776
|
+
body: JSON.stringify(input4)
|
|
2777
|
+
});
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
// ../../packages/admin-ops/src/admin-keys.ts
|
|
2781
|
+
var admin_keys_exports = {};
|
|
2782
|
+
__export(admin_keys_exports, {
|
|
2783
|
+
createAdminKey: () => createAdminKey,
|
|
2784
|
+
listAdminKeys: () => listAdminKeys,
|
|
2785
|
+
revokeAdminKey: () => revokeAdminKey
|
|
2786
|
+
});
|
|
2787
|
+
async function createAdminKey(client, tenantIdOrSlug, input4 = {}) {
|
|
2788
|
+
return client.fetch(
|
|
2789
|
+
`/api/tenants/${encodeURIComponent(tenantIdOrSlug)}/mcp-admin-keys`,
|
|
2790
|
+
{
|
|
2791
|
+
method: "POST",
|
|
2792
|
+
body: JSON.stringify(input4)
|
|
2793
|
+
}
|
|
2794
|
+
);
|
|
2795
|
+
}
|
|
2796
|
+
async function listAdminKeys(client, tenantIdOrSlug) {
|
|
2797
|
+
const res = await client.fetch(
|
|
2798
|
+
`/api/tenants/${encodeURIComponent(tenantIdOrSlug)}/mcp-admin-keys`
|
|
2799
|
+
);
|
|
2800
|
+
return res.keys;
|
|
2801
|
+
}
|
|
2802
|
+
async function revokeAdminKey(client, tenantIdOrSlug, keyId) {
|
|
2803
|
+
await client.fetch(
|
|
2804
|
+
`/api/tenants/${encodeURIComponent(tenantIdOrSlug)}/mcp-admin-keys/${encodeURIComponent(keyId)}`,
|
|
2805
|
+
{ method: "DELETE" }
|
|
2806
|
+
);
|
|
2807
|
+
}
|
|
2694
2808
|
|
|
2695
2809
|
// src/api-client.ts
|
|
2696
2810
|
import { readFileSync as readFileSync5, existsSync as existsSync9 } from "fs";
|
|
@@ -3273,7 +3387,7 @@ old one.
|
|
|
3273
3387
|
apiUrl: ctx.api.apiUrl,
|
|
3274
3388
|
authSecret: ctx.api.authSecret
|
|
3275
3389
|
});
|
|
3276
|
-
const created = await
|
|
3390
|
+
const created = await admin_keys_exports.createAdminKey(client, ctx.tenant.slug, {
|
|
3277
3391
|
name: opts.name
|
|
3278
3392
|
});
|
|
3279
3393
|
printJson(created);
|
|
@@ -3293,7 +3407,7 @@ old one.
|
|
|
3293
3407
|
apiUrl: ctx.api.apiUrl,
|
|
3294
3408
|
authSecret: ctx.api.authSecret
|
|
3295
3409
|
});
|
|
3296
|
-
const all = await
|
|
3410
|
+
const all = await admin_keys_exports.listAdminKeys(client, ctx.tenant.slug);
|
|
3297
3411
|
const rows = opts.all ? all : all.filter((k) => !k.revoked_at);
|
|
3298
3412
|
printJson(rows);
|
|
3299
3413
|
printTable(rows, [
|
|
@@ -3316,7 +3430,7 @@ old one.
|
|
|
3316
3430
|
apiUrl: ctx.api.apiUrl,
|
|
3317
3431
|
authSecret: ctx.api.authSecret
|
|
3318
3432
|
});
|
|
3319
|
-
await
|
|
3433
|
+
await admin_keys_exports.revokeAdminKey(client, ctx.tenant.slug, keyId);
|
|
3320
3434
|
printSuccess(`MCP admin key revoked: ${keyId}`);
|
|
3321
3435
|
} catch (err) {
|
|
3322
3436
|
if (err instanceof AdminOpsError && err.status === 404) {
|
|
@@ -4799,7 +4913,6 @@ Examples:
|
|
|
4799
4913
|
}
|
|
4800
4914
|
|
|
4801
4915
|
// src/commands/tenant.ts
|
|
4802
|
-
import { createClient as createClient2, tenants as tenantOps, AdminOpsError as AdminOpsError2 } from "@thinkwork/admin-ops";
|
|
4803
4916
|
function registerTenantCommand(program2) {
|
|
4804
4917
|
const tenant = program2.command("tenant").alias("tenants").description("Manage tenants (workspaces) \u2014 create, rename, and configure plans / defaults.");
|
|
4805
4918
|
tenant.command("list").alias("ls").description("List tenants the caller can see.").option("-s, --stage <name>", "Deployment stage").addHelpText(
|
|
@@ -4815,8 +4928,8 @@ Examples:
|
|
|
4815
4928
|
const stage = await resolveStage({ flag: opts.stage });
|
|
4816
4929
|
const api = resolveApiConfig(stage);
|
|
4817
4930
|
if (!api) process.exit(1);
|
|
4818
|
-
const client =
|
|
4819
|
-
const rows = await
|
|
4931
|
+
const client = createClient({ apiUrl: api.apiUrl, authSecret: api.authSecret });
|
|
4932
|
+
const rows = await tenants_exports.listTenants(client);
|
|
4820
4933
|
printJson(rows);
|
|
4821
4934
|
printTable(rows, [
|
|
4822
4935
|
{ key: "slug", header: "SLUG" },
|
|
@@ -4841,11 +4954,11 @@ Examples:
|
|
|
4841
4954
|
const stage = await resolveStage({ flag: opts.stage });
|
|
4842
4955
|
const api = resolveApiConfig(stage);
|
|
4843
4956
|
if (!api) process.exit(1);
|
|
4844
|
-
const client =
|
|
4957
|
+
const client = createClient({ apiUrl: api.apiUrl, authSecret: api.authSecret });
|
|
4845
4958
|
const isUuid2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
|
|
4846
4959
|
idOrSlug
|
|
4847
4960
|
);
|
|
4848
|
-
const tenant2 = isUuid2 ? await
|
|
4961
|
+
const tenant2 = isUuid2 ? await tenants_exports.getTenant(client, idOrSlug) : await tenants_exports.getTenantBySlug(client, idOrSlug);
|
|
4849
4962
|
printJson(tenant2);
|
|
4850
4963
|
printTable([tenant2], [
|
|
4851
4964
|
{ key: "slug", header: "SLUG" },
|
|
@@ -4855,7 +4968,7 @@ Examples:
|
|
|
4855
4968
|
{ key: "id", header: "ID" }
|
|
4856
4969
|
]);
|
|
4857
4970
|
} catch (err) {
|
|
4858
|
-
if (err instanceof
|
|
4971
|
+
if (err instanceof AdminOpsError && err.status === 404) {
|
|
4859
4972
|
printError(`Tenant "${idOrSlug}" not found`);
|
|
4860
4973
|
process.exit(2);
|
|
4861
4974
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thinkwork-cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "Thinkwork CLI — deploy, manage, and interact with your Thinkwork stack",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -18,8 +18,7 @@
|
|
|
18
18
|
"commander": "^12.0.0",
|
|
19
19
|
"graphql": "^16.10.0",
|
|
20
20
|
"jszip": "^3.10.1",
|
|
21
|
-
"ora": "^9.3.0"
|
|
22
|
-
"@thinkwork/admin-ops": "0.0.0"
|
|
21
|
+
"ora": "^9.3.0"
|
|
23
22
|
},
|
|
24
23
|
"devDependencies": {
|
|
25
24
|
"@graphql-codegen/cli": "^5.0.6",
|
|
@@ -28,7 +27,8 @@
|
|
|
28
27
|
"tsup": "^8.0.0",
|
|
29
28
|
"tsx": "^4.0.0",
|
|
30
29
|
"typescript": "^5.5.0",
|
|
31
|
-
"vitest": "^2.0.0"
|
|
30
|
+
"vitest": "^2.0.0",
|
|
31
|
+
"@thinkwork/admin-ops": "0.0.0"
|
|
32
32
|
},
|
|
33
33
|
"engines": {
|
|
34
34
|
"node": ">=20"
|