@epilot/cli 0.1.139 → 0.1.141

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.139 — CLI for epilot APIs
32
+ epilot v0.1.141 — CLI for epilot APIs
33
33
 
34
34
  USAGE
35
35
  epilot <api> <operationId> [params...] [flags]
@@ -2617,7 +2617,7 @@
2617
2617
  "post": {
2618
2618
  "operationId": "continueInstallationJob",
2619
2619
  "summary": "continueInstallationJob",
2620
- "description": "Resume an installation job that is paused at `status: \"WAITING_USER_ACTION\"` after\nplanning. Works for both Terraform and V3 jobs. Not needed for V3 installs created\nwith `auto_apply: true` (including all bulk-install child jobs), which apply\nwithout pausing.\n",
2620
+ "description": "Resume an installation job that is paused at `status: \"WAITING_USER_ACTION\"` after\nplanning. Works for both Terraform and V3 jobs. Not needed for V3 installs created\nwith `auto_apply: true` (including all bulk-install child jobs), which apply\nwithout pausing.\n\nAlso resumes a V3 install paused at `status: \"REAUTH_REQUIRED\"`, where the\ncaller's credentials could not safely cover another run. The job keeps its\n`job_id`, so resuming continues from the operation-log checkpoint rather than\nre-applying completed work. The request's bearer token becomes the destination\ncredential; for a cross-org install whose SOURCE credential also expired, send a\nfreshly scoped source token as `source_auth_token` — the destination bearer is not\na valid substitute for it.\n",
2621
2621
  "tags": [
2622
2622
  "Jobs"
2623
2623
  ],
@@ -2636,7 +2636,7 @@
2636
2636
  "content": {
2637
2637
  "application/json": {
2638
2638
  "schema": {
2639
- "$ref": "#/components/schemas/BlueprintInstallationJobOptions"
2639
+ "$ref": "#/components/schemas/ContinueInstallationJobRequest"
2640
2640
  }
2641
2641
  }
2642
2642
  }
@@ -2655,6 +2655,60 @@
2655
2655
  }
2656
2656
  }
2657
2657
  },
2658
+ "/v2/blueprint-manifest/jobs/{job_id}:retry": {
2659
+ "post": {
2660
+ "operationId": "retryInstallationJob",
2661
+ "summary": "retryInstallationJob",
2662
+ "description": "Retry a finished V3 installation job whose status is `FAILED` or\n`PARTIAL_SUCCESS`. Starts a fresh install job (new `job_id`) with the same\nsource/destination and `auto_apply: true` — no `:continue` call is needed.\nThe plan phase re-resolves every resource: already-synced resources no-op,\nso effectively only the failed resources are re-applied.\n\nMust be called by a user of the destination org (where the job lives); the\ncaller's bearer token is used as the destination token. The plan reuses the\nmanifest persisted by the original install, so no source-org access is\nrequired. The original job's `options` (ignored resources, sync_notes) are\nreused when present; older jobs without persisted options fall back to the\ndestination blueprint's `ignored_resource_addresses`.\n",
2663
+ "tags": [
2664
+ "Jobs"
2665
+ ],
2666
+ "parameters": [
2667
+ {
2668
+ "in": "path",
2669
+ "required": true,
2670
+ "name": "job_id",
2671
+ "schema": {
2672
+ "$ref": "#/components/schemas/BlueprintJobID"
2673
+ }
2674
+ }
2675
+ ],
2676
+ "responses": {
2677
+ "202": {
2678
+ "description": "Retry install job started",
2679
+ "headers": {
2680
+ "Location": {
2681
+ "description": "Path to poll the resulting job: GET /v2/blueprint-manifest/jobs/{job_id}",
2682
+ "schema": {
2683
+ "type": "string"
2684
+ }
2685
+ }
2686
+ },
2687
+ "content": {
2688
+ "application/json": {
2689
+ "schema": {
2690
+ "type": "object",
2691
+ "properties": {
2692
+ "job_id": {
2693
+ "$ref": "#/components/schemas/BlueprintJobID"
2694
+ },
2695
+ "destination_blueprint_id": {
2696
+ "$ref": "#/components/schemas/BlueprintID"
2697
+ }
2698
+ }
2699
+ }
2700
+ }
2701
+ }
2702
+ },
2703
+ "400": {
2704
+ "description": "Job is not a retryable V3 installation job"
2705
+ },
2706
+ "404": {
2707
+ "description": "Job not found"
2708
+ }
2709
+ }
2710
+ }
2711
+ },
2658
2712
  "/v2/blueprint-manifest/jobs/{job_id}:cancel": {
2659
2713
  "post": {
2660
2714
  "operationId": "cancelBlueprintJob",
@@ -3354,6 +3408,29 @@
3354
3408
  "type": "boolean",
3355
3409
  "description": "When `true`, the install skips the manual plan-approval step and applies\nstraight after plan + snapshot succeed (no `:continue` call needed).\nDefaults to `false`. Used internally by the bulk-install worker.\n",
3356
3410
  "default": false
3411
+ },
3412
+ "session_credentials": {
3413
+ "type": "object",
3414
+ "description": "Lets the install refresh the caller's session on its own, so a run that\noutlives the ~60 minute token lifetime continues without the user present.\nHeld server-side for the job's lifetime, referenced from the state machine\nrather than embedded in it, and deleted when the job finishes.\n\nOptional. Without it an install that outruns its token pauses at\n`status: \"REAUTH_REQUIRED\"` and waits to be resumed through\n`POST /v2/blueprint-manifest/jobs/{job_id}:continue`.\n\nBounded by the refresh token itself (18 hours), not unlimited.\n",
3415
+ "required": [
3416
+ "refresh_token",
3417
+ "client_id"
3418
+ ],
3419
+ "properties": {
3420
+ "refresh_token": {
3421
+ "type": "string",
3422
+ "format": "password",
3423
+ "description": "Cognito refresh token for the caller, scoped to the source org."
3424
+ },
3425
+ "client_id": {
3426
+ "type": "string",
3427
+ "description": "The Cognito app client the refresh token was issued for. Required because\nepilot provisions one user pool and app client per organization at\nruntime, so the service cannot derive it.\n"
3428
+ },
3429
+ "pipeline_id": {
3430
+ "type": "string",
3431
+ "description": "Cross-org installs only. The destination credential is not a Cognito\nsession — it is minted from the refreshed source session through\nsandbox-api, so it is re-derived per continuation instead of stored.\n"
3432
+ }
3433
+ }
3357
3434
  }
3358
3435
  }
3359
3436
  },
@@ -5284,11 +5361,15 @@
5284
5361
  "$ref": "#/components/schemas/V3ResourceProgressEntry"
5285
5362
  }
5286
5363
  },
5364
+ "options": {
5365
+ "$ref": "#/components/schemas/BlueprintInstallationJobOptions"
5366
+ },
5287
5367
  "status": {
5288
5368
  "type": "string",
5289
5369
  "enum": [
5290
5370
  "IN_PROGRESS",
5291
5371
  "WAITING_USER_ACTION",
5372
+ "REAUTH_REQUIRED",
5292
5373
  "CANCELED",
5293
5374
  "SUCCESS",
5294
5375
  "PARTIAL_SUCCESS",
@@ -6440,6 +6521,23 @@
6440
6521
  }
6441
6522
  }
6442
6523
  },
6524
+ "ContinueInstallationJobRequest": {
6525
+ "allOf": [
6526
+ {
6527
+ "$ref": "#/components/schemas/BlueprintInstallationJobOptions"
6528
+ },
6529
+ {
6530
+ "type": "object",
6531
+ "properties": {
6532
+ "source_auth_token": {
6533
+ "description": "A freshly issued bearer for the SOURCE organization, used only when resuming a\njob paused at `REAUTH_REQUIRED` whose source credential also expired. Applies to\ncross-org installs: apply-time reads such as the authenticated File API fallback\nfor private source files run against the source org, so the destination bearer\ncannot stand in for them. Omit it to keep the source token the job already has.\n",
6534
+ "type": "string",
6535
+ "format": "password"
6536
+ }
6537
+ }
6538
+ }
6539
+ ]
6540
+ },
6443
6541
  "ManifestID": {
6444
6542
  "type": "string",
6445
6543
  "description": "ID of an imported / installed manifest",
@@ -6512,6 +6610,7 @@
6512
6610
  "PENDING",
6513
6611
  "STARTED",
6514
6612
  "WAITING_USER_ACTION",
6613
+ "REAUTH_REQUIRED",
6515
6614
  "CANCELED",
6516
6615
  "IN_PROGRESS",
6517
6616
  "SUCCESS",
@@ -763,6 +763,10 @@
763
763
  "$ref": "#/components/schemas/EntityRef",
764
764
  "description": "A reference (id and schema) to the entity to be used as source."
765
765
  },
766
+ "loop_ref": {
767
+ "$ref": "#/components/schemas/EntityRef",
768
+ "description": "Reference to the current iteration's entity when running inside a flow loop.\nWhen set, its fields and relations are merged into the source context;\non schema conflicts the loop entity wins, so paths like `<schema>._id` resolve\nto the iteration entity rather than to a same-schema relation of the source.\n"
769
+ },
766
770
  "targets": {
767
771
  "type": "array",
768
772
  "items": {
@@ -960,6 +964,11 @@
960
964
  "type": "string"
961
965
  }
962
966
  },
967
+ "use_uniqueness_criteria": {
968
+ "type": "boolean",
969
+ "default": false,
970
+ "description": "Execution wire flag set per automation by automation-workers: resolve the target entity via the organization's global uniqueness criteria (deduplication-api) instead of target_unique. Never persisted in stored mapping configs.\n"
971
+ },
963
972
  "loop_config": {
964
973
  "type": "object",
965
974
  "description": "contains config in case of running in loop mode",
@@ -970,8 +979,7 @@
970
979
  },
971
980
  "length": {
972
981
  "type": "number",
973
- "description": "a hard limit of how many times the loop is allowed to run.",
974
- "default": "the length of the array"
982
+ "description": "a hard limit of how many times the loop is allowed to run."
975
983
  }
976
984
  }
977
985
  },
@@ -1023,6 +1031,13 @@
1023
1031
  "items": {
1024
1032
  "type": "string"
1025
1033
  }
1034
+ },
1035
+ "graph_context": {
1036
+ "type": "array",
1037
+ "description": "Multi-hop entity graph lookups resolved before any mapping_attribute is evaluated. Each\nentry queries entity-api's `POST /v1/entity:graph` and merges every node's result into\nsourceContext under its own `graph.nodes[].id`, so mapping_attributes can `_copy`/`_template`\nfrom `<node id>.<field>`. A graph node's value overwrites any existing sourceContext key of\nthe same name (a source entity field, a 1-hop relation, or another graph node).\n",
1038
+ "items": {
1039
+ "$ref": "#/components/schemas/GraphContextEntry"
1040
+ }
1026
1041
  }
1027
1042
  },
1028
1043
  "required": [
@@ -1093,6 +1108,13 @@
1093
1108
  "description": "Include all relation tags (labels) present on the main entity relation",
1094
1109
  "default": false
1095
1110
  },
1111
+ "target_entity_tags": {
1112
+ "type": "array",
1113
+ "description": "Tags to add to the matched target entity's _tags array during mapping. Useful for assigning file collections to file entities.",
1114
+ "items": {
1115
+ "type": "string"
1116
+ }
1117
+ },
1096
1118
  "override_with_source_filter": {
1097
1119
  "type": "boolean",
1098
1120
  "description": "Whether to override the relation source_filter with the specified one",
@@ -1152,6 +1174,157 @@
1152
1174
  "mode"
1153
1175
  ]
1154
1176
  },
1177
+ "GraphContextEntry": {
1178
+ "type": "object",
1179
+ "description": "One multi-hop graph lookup against entity-api's `POST /v1/entity:graph`, resolved during\ngraph_context enrichment (before mapping_attributes are evaluated). Every node in `graph.nodes`\nis merged into sourceContext under its own `id`, so listing several nodes here costs one\nentity-api call, not one per node.\n\nIf a node's `cardinality` is \"one\" (or it is the seed node), exactly one entity must be found\nfor it: zero or multiple matches fail the mapping execution instead of silently mapping\nmissing/wrong data. If \"many\" (the default), it resolves to an array - possibly empty - with no\nsuch failure. Each node's cardinality is validated independently.\n\n`seed.entity_id` and any `graph.nodes[].filter[].value` may contain `{{handlebars}}` placeholders\n(e.g. `{{contract._id}}`, `{{contract.origin_order}}`), resolved against the in-progress\nsourceContext (the source entity, its 1-hop relations, and any custom variables already\nresolved) before the graph query is sent.\n",
1180
+ "properties": {
1181
+ "seed": {
1182
+ "$ref": "#/components/schemas/GraphSeed"
1183
+ },
1184
+ "graph": {
1185
+ "$ref": "#/components/schemas/GraphDefinition"
1186
+ }
1187
+ },
1188
+ "required": [
1189
+ "seed",
1190
+ "graph"
1191
+ ]
1192
+ },
1193
+ "GraphSeed": {
1194
+ "description": "Mirrors entity-api's GraphSeed (see entity-api openapi.yml) - the entity the graph traversal starts from.",
1195
+ "type": "object",
1196
+ "properties": {
1197
+ "entity_id": {
1198
+ "type": "string",
1199
+ "description": "The id of the seed entity. Supports `{{handlebars}}` placeholders resolved against sourceContext.",
1200
+ "example": "{{contract._id}}"
1201
+ },
1202
+ "node_id": {
1203
+ "type": "string",
1204
+ "description": "The node ID in `graph.nodes` that corresponds to the seed entity.",
1205
+ "example": "contact"
1206
+ }
1207
+ },
1208
+ "required": [
1209
+ "entity_id",
1210
+ "node_id"
1211
+ ]
1212
+ },
1213
+ "GraphDefinition": {
1214
+ "description": "Mirrors entity-api's GraphDefinition (see entity-api openapi.yml) - the shape of the graph to traverse.",
1215
+ "type": "object",
1216
+ "properties": {
1217
+ "nodes": {
1218
+ "type": "array",
1219
+ "items": {
1220
+ "$ref": "#/components/schemas/GraphNode"
1221
+ }
1222
+ },
1223
+ "edges": {
1224
+ "type": "array",
1225
+ "items": {
1226
+ "$ref": "#/components/schemas/GraphEdge"
1227
+ }
1228
+ }
1229
+ },
1230
+ "required": [
1231
+ "nodes",
1232
+ "edges"
1233
+ ]
1234
+ },
1235
+ "GraphNode": {
1236
+ "description": "Mirrors entity-api's GraphNode (see entity-api openapi.yml).",
1237
+ "type": "object",
1238
+ "properties": {
1239
+ "id": {
1240
+ "type": "string",
1241
+ "description": "Unique identifier for this node in the graph definition.",
1242
+ "example": "contact"
1243
+ },
1244
+ "schema": {
1245
+ "type": "string",
1246
+ "description": "Entity schema slug for this node.",
1247
+ "example": "contact"
1248
+ },
1249
+ "cardinality": {
1250
+ "type": "string",
1251
+ "enum": [
1252
+ "one",
1253
+ "many"
1254
+ ],
1255
+ "description": "\"one\": this node resolves to a single entity. \"many\" (default if unset): this node\nresolves to an array of entities.\n"
1256
+ },
1257
+ "fields": {
1258
+ "type": "array",
1259
+ "description": "Optional entity fields to include in the hydrated response for this node.",
1260
+ "items": {
1261
+ "type": "string"
1262
+ }
1263
+ },
1264
+ "filter": {
1265
+ "type": "array",
1266
+ "description": "Narrows this node's traversal results to entities matching every filter (AND semantics).\nUseful for disambiguating among multiple entities reachable via the same graph edge.\n",
1267
+ "items": {
1268
+ "$ref": "#/components/schemas/GraphNodeFilter"
1269
+ }
1270
+ }
1271
+ },
1272
+ "required": [
1273
+ "id",
1274
+ "schema"
1275
+ ]
1276
+ },
1277
+ "GraphNodeFilter": {
1278
+ "description": "Mirrors entity-api's GraphNodeFilter (see entity-api openapi.yml).",
1279
+ "type": "object",
1280
+ "properties": {
1281
+ "attribute": {
1282
+ "type": "string",
1283
+ "description": "Entity attribute name to match against.",
1284
+ "example": "order_number"
1285
+ },
1286
+ "value": {
1287
+ "description": "Literal value the attribute must exactly equal. Supports `{{handlebars}}` placeholders\nresolved against sourceContext when given as a string.\n",
1288
+ "oneOf": [
1289
+ {
1290
+ "type": "string",
1291
+ "nullable": true
1292
+ },
1293
+ {
1294
+ "type": "number"
1295
+ },
1296
+ {
1297
+ "type": "boolean"
1298
+ }
1299
+ ],
1300
+ "example": "{{contract.origin_order}}"
1301
+ }
1302
+ },
1303
+ "required": [
1304
+ "attribute",
1305
+ "value"
1306
+ ]
1307
+ },
1308
+ "GraphEdge": {
1309
+ "description": "Mirrors entity-api's GraphEdge (see entity-api openapi.yml).",
1310
+ "type": "object",
1311
+ "properties": {
1312
+ "from": {
1313
+ "type": "string",
1314
+ "description": "Source node ID.",
1315
+ "example": "contact"
1316
+ },
1317
+ "to": {
1318
+ "type": "string",
1319
+ "description": "Target node ID.",
1320
+ "example": "order"
1321
+ }
1322
+ },
1323
+ "required": [
1324
+ "from",
1325
+ "to"
1326
+ ]
1327
+ },
1155
1328
  "MappingAttributeV2": {
1156
1329
  "type": "object",
1157
1330
  "properties": {
@@ -1256,6 +1429,20 @@
1256
1429
  "_random": {
1257
1430
  "description": "Generate random ids / numbers",
1258
1431
  "$ref": "#/components/schemas/RandomOperation"
1432
+ },
1433
+ "_each": {
1434
+ "description": "Iterate over a source array. Use with _as and _map.\nThe value is a path to resolve from the source entity context.\nExample: \"submission.meterReadings\"\n",
1435
+ "type": "string",
1436
+ "example": "submission.meterReadings"
1437
+ },
1438
+ "_as": {
1439
+ "description": "Name for the current iteration item in _each.\nAccessed as $<name> in _copy paths within _map.\nExample: \"reading\" (accessed as $reading)\n",
1440
+ "type": "string",
1441
+ "example": "reading"
1442
+ },
1443
+ "_map": {
1444
+ "description": "Operation to evaluate per _each iteration item.\nCan be any OperationNode, typically an object with _copy\nreferences to the $<_as name> alias.\n",
1445
+ "$ref": "#/components/schemas/OperationNode"
1259
1446
  }
1260
1447
  },
1261
1448
  "additionalProperties": true
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  API_LIST
4
- } from "../chunk-4A3TISYH.js";
4
+ } from "../chunk-TPJG2M3D.js";
5
5
 
6
6
  // bin/epilot.ts
7
7
  import { runMain } from "citty";
@@ -11,7 +11,7 @@ import { defineCommand } from "citty";
11
11
  var main = defineCommand({
12
12
  meta: {
13
13
  name: "epilot",
14
- version: "0.1.139",
14
+ version: "0.1.141",
15
15
  description: "CLI for epilot APIs"
16
16
  },
17
17
  args: {
@@ -30,8 +30,8 @@ var main = defineCommand({
30
30
  auth: () => import("../auth-WMXFMPWE.js").then((m) => m.default),
31
31
  profile: () => import("../profile-OZJL5ZPT.js").then((m) => m.default),
32
32
  config: () => import("../config-DGZIMLZK.js").then((m) => m.default),
33
- completion: () => import("../completion-MSAMXF3P.js").then((m) => m.default),
34
- upgrade: () => import("../upgrade-X5UUYWOI.js").then((m) => m.default),
33
+ completion: () => import("../completion-6OBSXXHS.js").then((m) => m.default),
34
+ upgrade: () => import("../upgrade-3YLZVTGJ.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),
@@ -134,13 +134,13 @@ 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.139" : (await null).default.version;
137
+ var VERSION = true ? "0.1.141" : (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);
141
141
  var completionsIdx = args.indexOf("--_completions");
142
142
  if (completionsIdx >= 0) {
143
- const { handleCompletions } = await import("../completion-MSAMXF3P.js");
143
+ const { handleCompletions } = await import("../completion-6OBSXXHS.js");
144
144
  handleCompletions(args[completionsIdx + 1], args[completionsIdx + 2]);
145
145
  process.exit(0);
146
146
  }
@@ -173,7 +173,7 @@ var API_LIST = [
173
173
  kebabName: "blueprint-manifest",
174
174
  title: "Blueprint Manifest API",
175
175
  serverUrl: "https://blueprint-manifest.sls.epilot.io",
176
- operationCount: 72,
176
+ operationCount: 73,
177
177
  operationIds: [
178
178
  "getJob",
179
179
  "createExport",
@@ -220,6 +220,7 @@ var API_LIST = [
220
220
  "listBlueprintJobs",
221
221
  "getBlueprintJob",
222
222
  "continueInstallationJob",
223
+ "retryInstallationJob",
223
224
  "cancelBlueprintJob",
224
225
  "getMarketplaceListing",
225
226
  "createMarketplaceListing",
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  API_LIST
4
- } from "./chunk-4A3TISYH.js";
4
+ } from "./chunk-TPJG2M3D.js";
5
5
  import {
6
6
  DIM,
7
7
  GREEN,
@@ -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.139";
75
+ if (true) return "0.1.141";
76
76
  try {
77
77
  const output = execSync("npm ls -g @epilot/cli --depth=0 --json 2>/dev/null", {
78
78
  encoding: "utf-8",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epilot/cli",
3
- "version": "0.1.139",
3
+ "version": "0.1.141",
4
4
  "description": "CLI for epilot APIs",
5
5
  "type": "module",
6
6
  "bin": {