@epilot/cli 0.1.113 → 0.1.114

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.113 — CLI for epilot APIs
32
+ epilot v0.1.114 — CLI for epilot APIs
33
33
 
34
34
  USAGE
35
35
  epilot <api> <operationId> [params...] [flags]
@@ -2113,12 +2113,12 @@
2113
2113
  "workflow",
2114
2114
  "scheduled"
2115
2115
  ],
2116
- "description": "Where the function can be used. `workflow` functions are selectable as actions in the flow builder and run with entity context. `scheduled` functions run automatically per installation on their cron schedule.\n"
2116
+ "description": "Where the function can be used. `workflow` functions are referenced by CUSTOM_FLOW_ACTION components (type `function`) and run with entity context. `scheduled` functions run automatically per installation on their cron schedule.\n"
2117
2117
  },
2118
2118
  "label": {
2119
2119
  "allOf": [
2120
2120
  {
2121
- "description": "Human-readable display name, e.g. shown in the flow builder action picker"
2121
+ "description": null
2122
2122
  },
2123
2123
  {
2124
2124
  "$ref": "#/components/schemas/TranslatedString"
@@ -2165,19 +2165,6 @@
2165
2165
  "type": "string"
2166
2166
  },
2167
2167
  "description": "Keys of installation options of type secret made available to the function via input.app_options\n"
2168
- },
2169
- "wait_for_callback": {
2170
- "type": "boolean",
2171
- "description": "Workflow functions only — wait for the callback_url to be called before completing the flow action\n"
2172
- },
2173
- "surfaces": {
2174
- "type": "object",
2175
- "description": "Workflow functions only — optional custom config UI shown in the flow builder",
2176
- "properties": {
2177
- "flow_action_config": {
2178
- "$ref": "#/components/schemas/AppBridgeSurfaceConfig"
2179
- }
2180
- }
2181
2168
  }
2182
2169
  }
2183
2170
  },
@@ -2594,18 +2581,48 @@
2594
2581
  }
2595
2582
  ]
2596
2583
  },
2584
+ "FunctionRefCustomActionConfig": {
2585
+ "allOf": [
2586
+ {
2587
+ "$ref": "#/components/schemas/BaseCustomActionConfig"
2588
+ },
2589
+ {
2590
+ "type": "object",
2591
+ "properties": {
2592
+ "type": {
2593
+ "type": "string",
2594
+ "enum": [
2595
+ "function"
2596
+ ]
2597
+ },
2598
+ "function_name": {
2599
+ "type": "string",
2600
+ "description": "Name of a `workflow`-type function of the same app version. The component provides the org-facing contract (name, options, config surface); the referenced function provides the code.\n"
2601
+ }
2602
+ },
2603
+ "required": [
2604
+ "type",
2605
+ "function_name"
2606
+ ]
2607
+ }
2608
+ ]
2609
+ },
2597
2610
  "CustomFlowConfig": {
2598
2611
  "type": "object",
2599
- "description": "Configuration of an external-integration flow action. Sandboxed code belongs in the app's `functions` (type `workflow`) instead — workflow functions are selectable directly in the flow builder without a component.\n",
2612
+ "description": "Configuration of a flow action component. `external_integration` calls an external HTTP endpoint; `function` runs a workflow-type app function in the epilot sandbox.\n",
2600
2613
  "oneOf": [
2601
2614
  {
2602
2615
  "$ref": "#/components/schemas/ExternalIntegrationCustomActionConfig"
2616
+ },
2617
+ {
2618
+ "$ref": "#/components/schemas/FunctionRefCustomActionConfig"
2603
2619
  }
2604
2620
  ],
2605
2621
  "discriminator": {
2606
2622
  "propertyName": "type",
2607
2623
  "mapping": {
2608
- "external_integration": "#/components/schemas/ExternalIntegrationCustomActionConfig"
2624
+ "external_integration": "#/components/schemas/ExternalIntegrationCustomActionConfig",
2625
+ "function": "#/components/schemas/FunctionRefCustomActionConfig"
2609
2626
  }
2610
2627
  }
2611
2628
  },
@@ -3,7 +3,7 @@ import {
3
3
  log,
4
4
  readManifest,
5
5
  writeManifest
6
- } from "./chunk-UDGF4AVJ.js";
6
+ } from "./chunk-6HMS3A5C.js";
7
7
  import "./chunk-M3M3C5WH.js";
8
8
  import "./chunk-YHQA2AVG.js";
9
9
  import "./chunk-7ZQ666ZQ.js";
@@ -15,6 +15,16 @@ import { existsSync, readFileSync, writeFileSync, readdirSync } from "fs";
15
15
  import { resolve, join } from "path";
16
16
  var TEMPLATES_REPO = "epilot-dev/app-templates";
17
17
  var TEMPLATE_REGISTRY = {
18
+ CUSTOM_FLOW_ACTION_FUNCTION: {
19
+ configOnly: true,
20
+ manifestType: "CUSTOM_FLOW_ACTION",
21
+ templateDir: "custom-flow-action-function",
22
+ description: "Flow action running a workflow function (code in epilot)",
23
+ configuration: () => ({
24
+ type: "function",
25
+ function_name: "<add-a-workflow-function-name>"
26
+ })
27
+ },
18
28
  CUSTOM_FLOW_ACTION_EXTERNAL: {
19
29
  configOnly: true,
20
30
  manifestType: "CUSTOM_FLOW_ACTION",
@@ -4,7 +4,7 @@ import {
4
4
  readManifest,
5
5
  validateScheduleExpression,
6
6
  writeManifest
7
- } from "./chunk-UDGF4AVJ.js";
7
+ } from "./chunk-6HMS3A5C.js";
8
8
  import "./chunk-M3M3C5WH.js";
9
9
  import "./chunk-YHQA2AVG.js";
10
10
  import "./chunk-7ZQ666ZQ.js";
@@ -29,7 +29,10 @@ var add_function_default = defineCommand({
29
29
  type: "string",
30
30
  description: 'Cron ("0 3 * * *") or rate ("rate(30 minutes)") expression to run the function once per installation'
31
31
  },
32
- label: { type: "string", description: "Display name shown to org admins (e.g. in the flow builder)" },
32
+ label: {
33
+ type: "string",
34
+ description: "Display name shown to org admins (e.g. in the installed app's functions summary)"
35
+ },
33
36
  timezone: { type: "string", description: "IANA timezone for cron schedules (default: Europe/Berlin)" },
34
37
  path: { type: "string", description: "Path to manifest.json (default: manifest.json)" }
35
38
  },
@@ -126,7 +129,9 @@ var add_function_default = defineCommand({
126
129
  if (args.schedule) {
127
130
  log.info(`Schedule: ${args.schedule} (runs once per installation, max 60s per run)`);
128
131
  } else {
129
- log.info("Selectable as an action in the flow builder once the app is installed");
132
+ log.info(
133
+ "Wire it into the flow builder with: epilot app add-component <name> --type CUSTOM_FLOW_ACTION_FUNCTION"
134
+ );
130
135
  }
131
136
  log.dim('Build with "npm run build", then "epilot app deploy"');
132
137
  }
@@ -136,8 +141,9 @@ var handlerTemplate = (name, fnType, schedule) => `// App function: ${name}
136
141
  // Runs automatically ${schedule?.startsWith("rate(") ? `every ${schedule.slice(5, -1)}` : `on "${schedule}"`} \u2014 once per installation,
137
142
  // inside the epilot code-execution sandbox with a 60 second budget. Do a
138
143
  // bounded amount of work per run; the next tick picks up the rest.` : `
139
- // Selectable as an action in the flow builder. Runs inside the epilot
140
- // code-execution sandbox with the triggering entity in \`input.entity\`.`}
144
+ // The code behind a flow action: reference it from a CUSTOM_FLOW_ACTION
145
+ // component ({ "type": "function", "function_name": "..." }). Runs inside the
146
+ // epilot code-execution sandbox with the triggering entity in \`input.entity\`.`}
141
147
  //
142
148
  // Runtime contract:
143
149
  // - top-level \`async function handler(input, context)\` \u2014 no \`export\`.
@@ -14,7 +14,7 @@ var api_default = defineCommand({
14
14
  args: {
15
15
  operation: { type: "positional", description: "operationId to call", required: false },
16
16
  param: { type: "string", alias: "p", description: "Parameter key=value" },
17
- data: { type: "string", alias: "d", description: "Request body JSON" },
17
+ data: { type: "string", alias: ["d", "body"], description: "Request body JSON" },
18
18
  header: { type: "string", alias: "H", description: "Custom header" },
19
19
  include: { type: "boolean", alias: "i", description: "Include response headers" },
20
20
  definition: { type: "string", description: "Override OpenAPI spec file/URL" },
@@ -45,7 +45,8 @@ var api_default = defineCommand({
45
45
  ...args,
46
46
  help: !!args._ophelp,
47
47
  _apihelp: !!args._apihelp,
48
- _args: positionalArgs
48
+ _args: positionalArgs,
49
+ _rawArgs: rawArgs
49
50
  });
50
51
  }
51
52
  });
@@ -0,0 +1,26 @@
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-5K7TXE74.js").then((m) => m.default),
12
+ "add-component": () => import("./add-component-YSPAIR3D.js").then((m) => m.default),
13
+ "remove-component": () => import("./remove-component-4XFMVBFW.js").then((m) => m.default),
14
+ "add-function": () => import("./add-function-6VYBWMRD.js").then((m) => m.default),
15
+ validate: () => import("./validate-B5MJWBXP.js").then((m) => m.default),
16
+ deploy: () => import("./deploy-3HGRSDVZ.js").then((m) => m.default),
17
+ dev: () => import("./dev-IYGZMQ5U.js").then((m) => m.default),
18
+ export: () => import("./export-TDFYIMNN.js").then((m) => m.default),
19
+ versions: () => import("./versions-KZG3AZCT.js").then((m) => m.default),
20
+ review: () => import("./review-BD2ZOXCZ.js").then((m) => m.default),
21
+ api: () => import("./api-HKW3N3TV.js").then((m) => m.default)
22
+ }
23
+ });
24
+ export {
25
+ app_default as default
26
+ };
@@ -11,7 +11,7 @@ import { defineCommand } from "citty";
11
11
  var main = defineCommand({
12
12
  meta: {
13
13
  name: "epilot",
14
- version: "0.1.113",
14
+ version: "0.1.114",
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-YY2UW6SA.js").then((m) => m.default),
34
- upgrade: () => import("../upgrade-KXJE4GVJ.js").then((m) => m.default),
34
+ upgrade: () => import("../upgrade-U5ADV54U.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-NATUF3YX.js").then((m) => m.default),
39
+ app: () => import("../app-TCMEJ6XJ.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.113" : (await null).default.version;
137
+ var VERSION = true ? "0.1.114" : (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);
@@ -282,9 +282,6 @@ function validateFunctions(functions, errors) {
282
282
  if (fn.type !== "scheduled" && fn.schedule !== void 0) {
283
283
  errors.push({ path: `${path}/schedule`, message: 'Only functions of type "scheduled" may declare a schedule' });
284
284
  }
285
- if (fn.type !== "workflow" && fn.wait_for_callback !== void 0) {
286
- errors.push({ path: `${path}/wait_for_callback`, message: "Only valid for workflow functions" });
287
- }
288
285
  if (typeof fn.name !== "string" || !FUNCTION_NAME_PATTERN.test(fn.name)) {
289
286
  errors.push({ path: `${path}/name`, message: "Required kebab-case string (a-z, 0-9, dashes; max 64 chars)" });
290
287
  } else if (seen.has(fn.name)) {
@@ -8,7 +8,7 @@ import {
8
8
  uploadDirectoryAsZip,
9
9
  uploadFileToPresignedUrl,
10
10
  writeManifest
11
- } from "./chunk-UDGF4AVJ.js";
11
+ } from "./chunk-6HMS3A5C.js";
12
12
  import "./chunk-M3M3C5WH.js";
13
13
  import "./chunk-YHQA2AVG.js";
14
14
  import "./chunk-7ZQ666ZQ.js";
@@ -81,9 +81,19 @@ var deploy_default = defineCommand({
81
81
  if (dryRun) {
82
82
  log.info(`[dry-run] Would create new version (cloned from ${targetVersion})`);
83
83
  } else {
84
- const result = await client.cloneVersion(appId, targetVersion);
85
- targetVersion = result.version;
86
- log.success(`Created version ${targetVersion}`);
84
+ try {
85
+ const result = await client.cloneVersion(appId, targetVersion);
86
+ targetVersion = result.version;
87
+ log.success(`Created version ${targetVersion}`);
88
+ } catch (err) {
89
+ if (err instanceof Error && err.message.includes("disable dev mode")) {
90
+ log.error("Cannot create a new version while development mode is enabled.");
91
+ log.info("Disable it first, then re-run the deploy:");
92
+ log.dim(` epilot app api patchMetadata --appId ${appId} -d '{"dev_mode": false}'`);
93
+ process.exit(1);
94
+ }
95
+ throw err;
96
+ }
87
97
  }
88
98
  }
89
99
  }
@@ -114,31 +124,8 @@ var deploy_default = defineCommand({
114
124
  log.error(`Handler not found for function "${fn.name}": ${handlerPath} \u2014 run "npm run build" first`);
115
125
  process.exit(1);
116
126
  }
117
- const { handler, assets: fnAssets, ...rest } = fn;
118
- const payload = { ...rest, code: readFileSync(handlerPath, "utf-8") };
119
- if (fnAssets?.zip) {
120
- const zipPath = resolve(manifestDir, fnAssets.zip);
121
- if (!existsSync(zipPath)) {
122
- log.warn(`Config UI directory not found for function "${fn.name}": ${zipPath} \u2014 skipping surface`);
123
- } else if (dryRun) {
124
- log.info(`[dry-run] Would zip and upload config UI for function ${fn.name}`);
125
- } else {
126
- const { upload_url, artifact_url } = await client.createZipUploadUrl(
127
- appId,
128
- targetVersion,
129
- `fn-${fn.name}`
130
- );
131
- const zipSize = await uploadDirectoryAsZip(upload_url, zipPath);
132
- log.success(`Uploaded config UI for function ${fn.name} (${formatFileSize(zipSize)})`);
133
- payload.surfaces = {
134
- flow_action_config: {
135
- app_url: artifact_url.replace(/\/[^/]+$/, "/index.html"),
136
- zip_url: artifact_url
137
- }
138
- };
139
- }
140
- }
141
- functionsPayload.push(payload);
127
+ const { handler, ...rest } = fn;
128
+ functionsPayload.push({ ...rest, code: readFileSync(handlerPath, "utf-8") });
142
129
  if (dryRun) {
143
130
  log.info(
144
131
  `[dry-run] Would deploy ${fn.type} function ${fn.name}${fn.schedule ? ` (schedule: ${fn.schedule})` : ""}`
@@ -3,7 +3,7 @@ import {
3
3
  createAppApiClient,
4
4
  log,
5
5
  readManifest
6
- } from "./chunk-UDGF4AVJ.js";
6
+ } from "./chunk-6HMS3A5C.js";
7
7
  import "./chunk-M3M3C5WH.js";
8
8
  import "./chunk-YHQA2AVG.js";
9
9
  import "./chunk-7ZQ666ZQ.js";
@@ -4,7 +4,7 @@ import {
4
4
  log,
5
5
  toManifest,
6
6
  writeManifest
7
- } from "./chunk-UDGF4AVJ.js";
7
+ } from "./chunk-6HMS3A5C.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-UDGF4AVJ.js";
5
+ } from "./chunk-6HMS3A5C.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-UDGF4AVJ.js";
6
+ } from "./chunk-6HMS3A5C.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-UDGF4AVJ.js";
6
+ } from "./chunk-6HMS3A5C.js";
7
7
  import "./chunk-M3M3C5WH.js";
8
8
  import "./chunk-YHQA2AVG.js";
9
9
  import "./chunk-7ZQ666ZQ.js";
@@ -60,7 +60,9 @@ var review_default = defineCommand({
60
60
  ...args["demo-url"] ? { demo_url: args["demo-url"] } : {}
61
61
  });
62
62
  log.success(`Review submitted for v${version}`);
63
- log.info(`Status: ${result.review?.review_status ?? "pending"}`);
63
+ log.info(
64
+ `Status: ${result?.review?.review_status ?? "pending"}`
65
+ );
64
66
  log.dim("The epilot team will review your app and update the status.");
65
67
  }
66
68
  });
@@ -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.113";
75
+ if (true) return "0.1.114";
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-UDGF4AVJ.js";
5
+ } from "./chunk-6HMS3A5C.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-UDGF4AVJ.js";
6
+ } from "./chunk-6HMS3A5C.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.113",
3
+ "version": "0.1.114",
4
4
  "description": "CLI for epilot APIs",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,26 +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-C66L5GFR.js").then((m) => m.default),
12
- "add-component": () => import("./add-component-TCF7V3KU.js").then((m) => m.default),
13
- "remove-component": () => import("./remove-component-7C7MPSBF.js").then((m) => m.default),
14
- "add-function": () => import("./add-function-VRVBRNY3.js").then((m) => m.default),
15
- validate: () => import("./validate-J35DJW3H.js").then((m) => m.default),
16
- deploy: () => import("./deploy-2U5FVEE7.js").then((m) => m.default),
17
- dev: () => import("./dev-JEAHUYQU.js").then((m) => m.default),
18
- export: () => import("./export-VLAY2KZP.js").then((m) => m.default),
19
- versions: () => import("./versions-2TMTHO7W.js").then((m) => m.default),
20
- review: () => import("./review-JZTMQNU3.js").then((m) => m.default),
21
- api: () => import("./api-5W2UMWCW.js").then((m) => m.default)
22
- }
23
- });
24
- export {
25
- app_default as default
26
- };