@epilot/cli 0.1.82 → 0.1.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,7 +29,7 @@ npm install -g @epilot/cli
29
29
 
30
30
  <!-- usage-help -->
31
31
  ```
32
- epilot v0.1.82 — CLI for epilot APIs
32
+ epilot v0.1.83 — CLI for epilot APIs
33
33
 
34
34
  USAGE
35
35
  epilot <api> <operationId> [params...] [flags]
@@ -3,7 +3,7 @@ import {
3
3
  log,
4
4
  readManifest,
5
5
  writeManifest
6
- } from "./chunk-4TDAAJ6H.js";
6
+ } from "./chunk-QOD77YLW.js";
7
7
  import "./chunk-M3M3C5WH.js";
8
8
  import "./chunk-YHQA2AVG.js";
9
9
  import "./chunk-7ZQ666ZQ.js";
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/commands/app/index.ts
4
+ import { defineCommand } from "citty";
5
+ var app_default = defineCommand({
6
+ meta: {
7
+ name: "app",
8
+ description: "Manage epilot Apps \u2014 create, deploy, and manage app manifests"
9
+ },
10
+ subCommands: {
11
+ init: () => import("./init-345HGB5B.js").then((m) => m.default),
12
+ "add-component": () => import("./add-component-CJIQYDO5.js").then((m) => m.default),
13
+ "remove-component": () => import("./remove-component-LPTHVN4P.js").then((m) => m.default),
14
+ validate: () => import("./validate-TLSOTJAY.js").then((m) => m.default),
15
+ deploy: () => import("./deploy-NRQHZ635.js").then((m) => m.default),
16
+ export: () => import("./export-ZRDJCALM.js").then((m) => m.default),
17
+ versions: () => import("./versions-VA4H3EPK.js").then((m) => m.default),
18
+ review: () => import("./review-OZTM3XBD.js").then((m) => m.default),
19
+ api: () => import("./api-5W2UMWCW.js").then((m) => m.default)
20
+ }
21
+ });
22
+ export {
23
+ app_default as default
24
+ };
@@ -11,7 +11,7 @@ import { defineCommand } from "citty";
11
11
  var main = defineCommand({
12
12
  meta: {
13
13
  name: "epilot",
14
- version: "0.1.82",
14
+ version: "0.1.83",
15
15
  description: "CLI for epilot APIs"
16
16
  },
17
17
  args: {
@@ -31,12 +31,12 @@ var main = defineCommand({
31
31
  profile: () => import("../profile-OZJL5ZPT.js").then((m) => m.default),
32
32
  config: () => import("../config-DGZIMLZK.js").then((m) => m.default),
33
33
  completion: () => import("../completion-N6A4VCAE.js").then((m) => m.default),
34
- upgrade: () => import("../upgrade-YBOBA2V7.js").then((m) => m.default),
34
+ upgrade: () => import("../upgrade-5RN2XG2M.js").then((m) => m.default),
35
35
  "access-token": () => import("../access-token-WWE6BDJH.js").then((m) => m.default),
36
36
  address: () => import("../address-EH3C4CVB.js").then((m) => m.default),
37
37
  "address-suggestions": () => import("../address-suggestions-RRSLOBFW.js").then((m) => m.default),
38
38
  "ai-agents": () => import("../ai-agents-53M2KHPI.js").then((m) => m.default),
39
- app: () => import("../app-EULJIEDB.js").then((m) => m.default),
39
+ app: () => import("../app-TIWZ2LQC.js").then((m) => m.default),
40
40
  "audit-logs": () => import("../audit-logs-YFRK3EFU.js").then((m) => m.default),
41
41
  automation: () => import("../automation-4DEE3TUI.js").then((m) => m.default),
42
42
  billing: () => import("../billing-XX4VVOPI.js").then((m) => m.default),
@@ -134,7 +134,7 @@ process.stderr.on("error", (err) => {
134
134
  if (err.code === "EPIPE") process.exit(0);
135
135
  throw err;
136
136
  });
137
- var VERSION = true ? "0.1.82" : (await null).default.version;
137
+ var VERSION = true ? "0.1.83" : (await null).default.version;
138
138
  var reorderedArgv = hoistFlagsAfterSubcommand(process.argv.slice(2));
139
139
  process.argv = [process.argv[0], process.argv[1], ...reorderedArgv];
140
140
  var args = process.argv.slice(2);
@@ -1,7 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ loadCredentials,
3
4
  resolveToken
4
5
  } from "./chunk-M3M3C5WH.js";
6
+ import {
7
+ getResolvedProfile
8
+ } from "./chunk-YHQA2AVG.js";
5
9
  import {
6
10
  BOLD,
7
11
  DIM,
@@ -121,6 +125,33 @@ async function request(baseUrl, token, method, path, body) {
121
125
  }
122
126
  return text;
123
127
  }
128
+ var parseJwtPayload = (token) => {
129
+ try {
130
+ const parts = token.split(".");
131
+ if (parts.length !== 3) return null;
132
+ const payload = Buffer.from(parts[1], "base64url").toString("utf-8");
133
+ return JSON.parse(payload);
134
+ } catch {
135
+ return null;
136
+ }
137
+ };
138
+ function resolveOrgId(tokenFlag, profile) {
139
+ const token = resolveToken(tokenFlag, profile);
140
+ const claims = token ? parseJwtPayload(token) : null;
141
+ const fromToken = claims?.org_id ?? claims?.["custom:ivy_org_id"];
142
+ if (fromToken) return fromToken;
143
+ return getResolvedProfile(profile)?.org_id ?? loadCredentials()?.org_id;
144
+ }
145
+ function derivePermissionsBaseUrl(appBaseUrl) {
146
+ try {
147
+ const url = new URL(appBaseUrl);
148
+ if (!url.hostname.startsWith("app.")) return null;
149
+ url.hostname = url.hostname.replace(/^app\./, "permissions.");
150
+ return url.origin;
151
+ } catch {
152
+ return null;
153
+ }
154
+ }
124
155
  function createAppApiClient(opts) {
125
156
  const baseUrl = opts.server ?? DEFAULT_BASE_URL;
126
157
  const getToken = () => {
@@ -150,6 +181,28 @@ function createAppApiClient(opts) {
150
181
  async patchVersion(appId, version, payload) {
151
182
  await request(baseUrl, getToken(), "PATCH", `/v1/app-configurations/${appId}/versions/${version}`, payload);
152
183
  },
184
+ /**
185
+ * Upsert the app's role in the developer's own organization with the
186
+ * manifest grants. The role id is attached to the app version via
187
+ * `role_id`; on installation the App API creates a copy of it (from the
188
+ * version's grants) in the installer's organization.
189
+ */
190
+ async upsertAppRole(params) {
191
+ const permissionsBaseUrl = derivePermissionsBaseUrl(baseUrl);
192
+ if (!permissionsBaseUrl) {
193
+ throw new Error(`Cannot derive permissions API URL from ${baseUrl}`);
194
+ }
195
+ const roleId = `${params.orgId}:${params.appId}`;
196
+ await request(permissionsBaseUrl, getToken(), "PUT", `/v1/permissions/roles/${roleId}`, {
197
+ id: roleId,
198
+ organization_id: params.orgId,
199
+ type: "user_role",
200
+ slug: params.appId,
201
+ name: `Automatically created by App ${params.appName}`,
202
+ grants: params.grants
203
+ });
204
+ return roleId;
205
+ },
153
206
  async cloneVersion(appId, version) {
154
207
  return request(
155
208
  baseUrl,
@@ -358,6 +411,7 @@ export {
358
411
  validateManifest,
359
412
  readManifest,
360
413
  writeManifest,
414
+ resolveOrgId,
361
415
  createAppApiClient,
362
416
  uploadFileToPresignedUrl,
363
417
  uploadDirectoryAsZip,
@@ -4,10 +4,11 @@ import {
4
4
  formatFileSize,
5
5
  log,
6
6
  readManifest,
7
+ resolveOrgId,
7
8
  uploadDirectoryAsZip,
8
9
  uploadFileToPresignedUrl,
9
10
  writeManifest
10
- } from "./chunk-4TDAAJ6H.js";
11
+ } from "./chunk-QOD77YLW.js";
11
12
  import "./chunk-M3M3C5WH.js";
12
13
  import "./chunk-YHQA2AVG.js";
13
14
  import "./chunk-7ZQ666ZQ.js";
@@ -106,10 +107,32 @@ var deploy_default = defineCommand({
106
107
  }
107
108
  if (manifest.permissions?.length || manifest.blueprint?.manifest_id) {
108
109
  if (dryRun) {
110
+ if (manifest.permissions?.length) {
111
+ log.info("[dry-run] Would upsert app role in developer org");
112
+ }
109
113
  log.info("[dry-run] Would update version permissions/blueprint");
110
114
  } else {
115
+ let roleId;
116
+ if (manifest.permissions?.length) {
117
+ const orgId = resolveOrgId(args.token, args.profile);
118
+ if (orgId) {
119
+ try {
120
+ roleId = await client.upsertAppRole({
121
+ orgId,
122
+ appId,
123
+ appName: manifest.name,
124
+ grants: manifest.permissions
125
+ });
126
+ log.success(`Upserted app role ${roleId}`);
127
+ } catch (err) {
128
+ log.warn(`Could not upsert app role: ${err.message}`);
129
+ }
130
+ } else {
131
+ log.warn("Could not resolve org id \u2014 attaching grants without a developer-org role");
132
+ }
133
+ }
111
134
  await client.patchVersion(appId, targetVersion, {
112
- ...manifest.permissions?.length ? { grants: manifest.permissions } : {},
135
+ ...manifest.permissions?.length ? { grants: manifest.permissions, ...roleId ? { role_id: roleId } : {} } : {},
113
136
  ...manifest.blueprint?.manifest_id ? { manifest_id: manifest.blueprint.manifest_id } : {}
114
137
  });
115
138
  log.success(`Updated version ${targetVersion} (permissions/blueprint)`);
@@ -4,7 +4,7 @@ import {
4
4
  log,
5
5
  toManifest,
6
6
  writeManifest
7
- } from "./chunk-4TDAAJ6H.js";
7
+ } from "./chunk-QOD77YLW.js";
8
8
  import "./chunk-M3M3C5WH.js";
9
9
  import "./chunk-YHQA2AVG.js";
10
10
  import "./chunk-7ZQ666ZQ.js";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  log,
4
4
  writeManifest
5
- } from "./chunk-4TDAAJ6H.js";
5
+ } from "./chunk-QOD77YLW.js";
6
6
  import "./chunk-M3M3C5WH.js";
7
7
  import "./chunk-YHQA2AVG.js";
8
8
  import "./chunk-7ZQ666ZQ.js";
@@ -3,7 +3,7 @@ import {
3
3
  log,
4
4
  readManifest,
5
5
  writeManifest
6
- } from "./chunk-4TDAAJ6H.js";
6
+ } from "./chunk-QOD77YLW.js";
7
7
  import "./chunk-M3M3C5WH.js";
8
8
  import "./chunk-YHQA2AVG.js";
9
9
  import "./chunk-7ZQ666ZQ.js";
@@ -3,7 +3,7 @@ import {
3
3
  createAppApiClient,
4
4
  log,
5
5
  readManifest
6
- } from "./chunk-4TDAAJ6H.js";
6
+ } from "./chunk-QOD77YLW.js";
7
7
  import "./chunk-M3M3C5WH.js";
8
8
  import "./chunk-YHQA2AVG.js";
9
9
  import "./chunk-7ZQ666ZQ.js";
@@ -72,7 +72,7 @@ ${GREEN}${BOLD}Upgraded to @epilot/cli@${latest}${RESET}
72
72
  }
73
73
  });
74
74
  var getCurrentVersion = () => {
75
- if (true) return "0.1.82";
75
+ if (true) return "0.1.83";
76
76
  try {
77
77
  const output = execSync("npm ls -g @epilot/cli --depth=0 --json 2>/dev/null", {
78
78
  encoding: "utf-8",
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  log,
4
4
  validateManifest
5
- } from "./chunk-4TDAAJ6H.js";
5
+ } from "./chunk-QOD77YLW.js";
6
6
  import "./chunk-M3M3C5WH.js";
7
7
  import "./chunk-YHQA2AVG.js";
8
8
  import "./chunk-7ZQ666ZQ.js";
@@ -3,7 +3,7 @@ import {
3
3
  createAppApiClient,
4
4
  log,
5
5
  readManifest
6
- } from "./chunk-4TDAAJ6H.js";
6
+ } from "./chunk-QOD77YLW.js";
7
7
  import "./chunk-M3M3C5WH.js";
8
8
  import "./chunk-YHQA2AVG.js";
9
9
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epilot/cli",
3
- "version": "0.1.82",
3
+ "version": "0.1.83",
4
4
  "description": "CLI for epilot APIs",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/commands/app/index.ts
4
- import { defineCommand } from "citty";
5
- var app_default = defineCommand({
6
- meta: {
7
- name: "app",
8
- description: "Manage epilot Apps \u2014 create, deploy, and manage app manifests"
9
- },
10
- subCommands: {
11
- init: () => import("./init-QZTZF2JC.js").then((m) => m.default),
12
- "add-component": () => import("./add-component-IVVCAUGY.js").then((m) => m.default),
13
- "remove-component": () => import("./remove-component-HJA5OA3H.js").then((m) => m.default),
14
- validate: () => import("./validate-QUSO4DR4.js").then((m) => m.default),
15
- deploy: () => import("./deploy-JMJFXUKQ.js").then((m) => m.default),
16
- export: () => import("./export-JDDMBBNS.js").then((m) => m.default),
17
- versions: () => import("./versions-EUTT4SNW.js").then((m) => m.default),
18
- review: () => import("./review-7M27IRW6.js").then((m) => m.default),
19
- api: () => import("./api-5W2UMWCW.js").then((m) => m.default)
20
- }
21
- });
22
- export {
23
- app_default as default
24
- };