@automatify-au/cli 0.1.15 → 0.1.16

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.
Files changed (2) hide show
  1. package/dist/automatify.cjs +554 -50
  2. package/package.json +1 -1
@@ -16172,6 +16172,504 @@ function createIngestFeatureHandler(deps = {}) {
16172
16172
  };
16173
16173
  }
16174
16174
 
16175
+ // src/profiles.ts
16176
+ var CONFIG_FLAGS7 = /* @__PURE__ */ new Set([
16177
+ "--config",
16178
+ "--base-url",
16179
+ "--project-key",
16180
+ "--issue-key",
16181
+ "--auth-mode",
16182
+ "--jira-email",
16183
+ "--jira-api-token"
16184
+ ]);
16185
+ function parseArgs8(args) {
16186
+ const flags = {};
16187
+ const boolFlags = /* @__PURE__ */ new Set();
16188
+ const unknownFlags = [];
16189
+ const supportedValueFlags = /* @__PURE__ */ new Set(["--id", ...CONFIG_FLAGS7]);
16190
+ const supportedBoolFlags = /* @__PURE__ */ new Set(["--json", "--dry-run", "--confirm", "--detach"]);
16191
+ for (let index = 0; index < args.length; index += 1) {
16192
+ const token = args[index];
16193
+ if (!token.startsWith("--")) {
16194
+ unknownFlags.push(token);
16195
+ continue;
16196
+ }
16197
+ if (supportedBoolFlags.has(token)) {
16198
+ boolFlags.add(token);
16199
+ continue;
16200
+ }
16201
+ if (!supportedValueFlags.has(token)) {
16202
+ unknownFlags.push(token);
16203
+ continue;
16204
+ }
16205
+ const value = args[index + 1];
16206
+ if (!value || value.startsWith("--")) {
16207
+ unknownFlags.push(token);
16208
+ continue;
16209
+ }
16210
+ flags[token] = value;
16211
+ index += 1;
16212
+ }
16213
+ return { flags, boolFlags, unknownFlags };
16214
+ }
16215
+ function pickConfigArgs7(parsed) {
16216
+ const args = [];
16217
+ for (const [flag, value] of Object.entries(parsed.flags)) {
16218
+ if (CONFIG_FLAGS7.has(flag)) {
16219
+ args.push(flag, value);
16220
+ }
16221
+ }
16222
+ return args;
16223
+ }
16224
+ function normalizeError6(error) {
16225
+ if (error instanceof ForgeClientError) {
16226
+ return `${error.code}: ${error.message}`;
16227
+ }
16228
+ if (error instanceof Error) {
16229
+ return error.message;
16230
+ }
16231
+ return "Unknown profiles command error.";
16232
+ }
16233
+ function missingProjectResponse3() {
16234
+ return {
16235
+ exitCode: ExitCode.ValidationError,
16236
+ stderr: ["ERROR: Missing project context. Set JIRA_PROJECT_KEY or pass --project-key."]
16237
+ };
16238
+ }
16239
+ function confirmationRequiredResponse(command) {
16240
+ return {
16241
+ exitCode: ExitCode.ValidationError,
16242
+ stderr: [`ERROR: ${command} is destructive and requires --confirm. Use --dry-run first to preview the cleanup.`]
16243
+ };
16244
+ }
16245
+ function remoteErrorResponse(code, message, stdout = []) {
16246
+ return {
16247
+ exitCode: ExitCode.RemoteError,
16248
+ stdout,
16249
+ stderr: [`ERROR: ${code}: ${message}`]
16250
+ };
16251
+ }
16252
+ function toJsonProfile(profile) {
16253
+ return {
16254
+ id: profile.id,
16255
+ label: profile.label,
16256
+ provider: profile.provider,
16257
+ endpointSummary: profile.endpointSummary,
16258
+ enabled: profile.enabled,
16259
+ isProjectDefault: profile.isProjectDefault ?? false,
16260
+ hasSecret: profile.hasSecret,
16261
+ createdAt: profile.createdAt,
16262
+ updatedAt: profile.updatedAt,
16263
+ lastUsedAt: profile.lastUsedAt ?? null
16264
+ };
16265
+ }
16266
+ function toJsonBinding(automation) {
16267
+ return {
16268
+ id: automation.id,
16269
+ scenarioId: automation.scenarioId,
16270
+ label: automation.label,
16271
+ profileId: automation.profileId ?? null,
16272
+ profileLabel: automation.profileLabel ?? null,
16273
+ materializedFromProjectDefault: automation.materializedFromProjectDefault ?? false,
16274
+ enabled: automation.enabled
16275
+ };
16276
+ }
16277
+ function profileLines(profiles) {
16278
+ if (profiles.length === 0) {
16279
+ return ["Automation profiles: 0", "No automation profiles found for the selected project."];
16280
+ }
16281
+ return [
16282
+ `Automation profiles: ${profiles.length}`,
16283
+ ...profiles.map((profile) => {
16284
+ const flags = [profile.isProjectDefault ? "default" : "", profile.enabled ? "enabled" : "disabled"].filter(
16285
+ Boolean
16286
+ );
16287
+ return `- ${profile.id} [${flags.join(", ")}] ${profile.label} (${profile.provider}) ${profile.endpointSummary}`;
16288
+ })
16289
+ ];
16290
+ }
16291
+ function bindingLines(bindings) {
16292
+ return bindings.map(
16293
+ (binding) => `- ${binding.id} scenario=${binding.scenarioId} ${binding.label}` + (binding.materializedFromProjectDefault ? " [project-default materialized]" : "")
16294
+ );
16295
+ }
16296
+ function profileBindings(automations, profileId) {
16297
+ return automations.filter((automation) => automation.mode === "profile" && automation.profileId === profileId);
16298
+ }
16299
+ function allProfileBindings(automations) {
16300
+ return automations.filter((automation) => automation.mode === "profile");
16301
+ }
16302
+ function createProfilesHandler(deps = {}) {
16303
+ const cwd = deps.cwd ?? process.cwd();
16304
+ const env = deps.env ?? process.env;
16305
+ return async (request, context) => {
16306
+ const [subcommand, ...restArgs] = request.args;
16307
+ const parsed = parseArgs8(restArgs);
16308
+ const useJson = parsed.boolFlags.has("--json");
16309
+ const dryRun = parsed.boolFlags.has("--dry-run");
16310
+ const confirmed = parsed.boolFlags.has("--confirm");
16311
+ const detach = parsed.boolFlags.has("--detach");
16312
+ const profileId = parsed.flags["--id"]?.trim() ?? "";
16313
+ const config = resolveCliConfig(pickConfigArgs7(parsed), env, cwd);
16314
+ const projectKey = config.values.projectKey;
16315
+ const issueKey = config.values.issueKey;
16316
+ const forgeContext = {
16317
+ projectKey: projectKey || void 0,
16318
+ issueKey: issueKey || void 0
16319
+ };
16320
+ if (parsed.unknownFlags.length > 0) {
16321
+ return {
16322
+ exitCode: ExitCode.UsageError,
16323
+ stderr: [`ERROR: Unknown or invalid arguments: ${parsed.unknownFlags.join(", ")}`]
16324
+ };
16325
+ }
16326
+ if (!projectKey) {
16327
+ return missingProjectResponse3();
16328
+ }
16329
+ if (dryRun && confirmed) {
16330
+ return {
16331
+ exitCode: ExitCode.UsageError,
16332
+ stderr: ["ERROR: Use either --dry-run or --confirm, not both."]
16333
+ };
16334
+ }
16335
+ if (subcommand === "list") {
16336
+ if (dryRun || confirmed || detach || profileId) {
16337
+ return {
16338
+ exitCode: ExitCode.UsageError,
16339
+ stderr: ["ERROR: profiles list accepts only configuration flags and optional --json."]
16340
+ };
16341
+ }
16342
+ try {
16343
+ const result = await context.invokeForgeContract("listScenarioAutomationProfiles", {
16344
+ context: forgeContext
16345
+ });
16346
+ if (!result.ok) {
16347
+ return remoteErrorResponse(result.error.code, result.error.message);
16348
+ }
16349
+ if (useJson) {
16350
+ return {
16351
+ exitCode: ExitCode.Success,
16352
+ stdout: toJsonLine({
16353
+ action: "profiles-list",
16354
+ projectKey,
16355
+ count: result.data.length,
16356
+ items: result.data.map(toJsonProfile)
16357
+ })
16358
+ };
16359
+ }
16360
+ return {
16361
+ exitCode: ExitCode.Success,
16362
+ stdout: profileLines(result.data)
16363
+ };
16364
+ } catch (error) {
16365
+ return {
16366
+ exitCode: ExitCode.TransportError,
16367
+ stderr: [`ERROR: ${normalizeError6(error)}`]
16368
+ };
16369
+ }
16370
+ }
16371
+ if (subcommand === "detach") {
16372
+ if (!profileId) {
16373
+ return {
16374
+ exitCode: ExitCode.ValidationError,
16375
+ stderr: ["ERROR: Missing required --id <PROFILE_ID> for profiles detach."]
16376
+ };
16377
+ }
16378
+ if (detach) {
16379
+ return {
16380
+ exitCode: ExitCode.UsageError,
16381
+ stderr: [
16382
+ "ERROR: --detach is only valid with profiles delete; profiles detach already performs that operation."
16383
+ ]
16384
+ };
16385
+ }
16386
+ if (!dryRun && !confirmed) {
16387
+ return confirmationRequiredResponse("profiles detach");
16388
+ }
16389
+ try {
16390
+ const result = await context.invokeForgeContract("listScenarioAutomations", {
16391
+ context: forgeContext
16392
+ });
16393
+ if (!result.ok) {
16394
+ return remoteErrorResponse(result.error.code, result.error.message);
16395
+ }
16396
+ const bindings = profileBindings(result.data, profileId);
16397
+ if (dryRun) {
16398
+ if (useJson) {
16399
+ return {
16400
+ exitCode: ExitCode.Success,
16401
+ stdout: toJsonLine({
16402
+ action: "profiles-detach",
16403
+ dryRun: true,
16404
+ projectKey,
16405
+ profileId,
16406
+ bindingCount: bindings.length,
16407
+ bindings: bindings.map(toJsonBinding)
16408
+ })
16409
+ };
16410
+ }
16411
+ return {
16412
+ exitCode: ExitCode.Success,
16413
+ stdout: [
16414
+ `Dry run: profile ${profileId} has ${bindings.length} automation binding(s) to detach.`,
16415
+ ...bindingLines(bindings),
16416
+ "No changes made."
16417
+ ]
16418
+ };
16419
+ }
16420
+ const deletedIds = [];
16421
+ for (const binding of bindings) {
16422
+ const deleted = await context.invokeForgeContract("deleteScenarioAutomation", {
16423
+ context: forgeContext,
16424
+ automationId: binding.id
16425
+ });
16426
+ if (!deleted.ok) {
16427
+ return remoteErrorResponse(deleted.error.code, deleted.error.message, [
16428
+ `Detached ${deletedIds.length} of ${bindings.length} automation binding(s) before the failure.`
16429
+ ]);
16430
+ }
16431
+ deletedIds.push(binding.id);
16432
+ }
16433
+ if (useJson) {
16434
+ return {
16435
+ exitCode: ExitCode.Success,
16436
+ stdout: toJsonLine({
16437
+ action: "profiles-detach",
16438
+ dryRun: false,
16439
+ projectKey,
16440
+ profileId,
16441
+ detachedCount: deletedIds.length,
16442
+ detachedAutomationIds: deletedIds
16443
+ })
16444
+ };
16445
+ }
16446
+ return {
16447
+ exitCode: ExitCode.Success,
16448
+ stdout: [`Detached ${deletedIds.length} automation binding(s) from profile ${profileId}.`]
16449
+ };
16450
+ } catch (error) {
16451
+ return {
16452
+ exitCode: ExitCode.TransportError,
16453
+ stderr: [`ERROR: ${normalizeError6(error)}`]
16454
+ };
16455
+ }
16456
+ }
16457
+ if (subcommand === "delete") {
16458
+ if (!profileId) {
16459
+ return {
16460
+ exitCode: ExitCode.ValidationError,
16461
+ stderr: ["ERROR: Missing required --id <PROFILE_ID> for profiles delete."]
16462
+ };
16463
+ }
16464
+ if (!dryRun && !confirmed) {
16465
+ return confirmationRequiredResponse("profiles delete");
16466
+ }
16467
+ try {
16468
+ let bindings = [];
16469
+ if (detach || dryRun) {
16470
+ const automations = await context.invokeForgeContract("listScenarioAutomations", {
16471
+ context: forgeContext
16472
+ });
16473
+ if (!automations.ok) {
16474
+ return remoteErrorResponse(automations.error.code, automations.error.message);
16475
+ }
16476
+ bindings = profileBindings(automations.data, profileId);
16477
+ }
16478
+ if (dryRun) {
16479
+ if (useJson) {
16480
+ return {
16481
+ exitCode: ExitCode.Success,
16482
+ stdout: toJsonLine({
16483
+ action: "profiles-delete",
16484
+ dryRun: true,
16485
+ projectKey,
16486
+ profileId,
16487
+ detach,
16488
+ bindingCount: bindings.length,
16489
+ bindings: bindings.map(toJsonBinding)
16490
+ })
16491
+ };
16492
+ }
16493
+ return {
16494
+ exitCode: ExitCode.Success,
16495
+ stdout: [
16496
+ `Dry run: profile ${profileId} would be deleted.`,
16497
+ detach ? `The command would first detach ${bindings.length} automation binding(s).` : `The command would not detach ${bindings.length} automation binding(s); Forge will block deletion if the profile is in use.`,
16498
+ ...bindingLines(bindings),
16499
+ "No changes made."
16500
+ ]
16501
+ };
16502
+ }
16503
+ const detachedIds = [];
16504
+ if (detach) {
16505
+ for (const binding of bindings) {
16506
+ const deletedBinding = await context.invokeForgeContract("deleteScenarioAutomation", {
16507
+ context: forgeContext,
16508
+ automationId: binding.id
16509
+ });
16510
+ if (!deletedBinding.ok) {
16511
+ return remoteErrorResponse(deletedBinding.error.code, deletedBinding.error.message, [
16512
+ `Detached ${detachedIds.length} of ${bindings.length} automation binding(s); profile ${profileId} was not deleted.`
16513
+ ]);
16514
+ }
16515
+ detachedIds.push(binding.id);
16516
+ }
16517
+ }
16518
+ const deletedProfile = await context.invokeForgeContract("deleteScenarioAutomationProfile", {
16519
+ context: forgeContext,
16520
+ profileId
16521
+ });
16522
+ if (!deletedProfile.ok) {
16523
+ return remoteErrorResponse(deletedProfile.error.code, deletedProfile.error.message, [
16524
+ `Detached ${detachedIds.length} automation binding(s) before profile deletion was rejected.`
16525
+ ]);
16526
+ }
16527
+ if (useJson) {
16528
+ return {
16529
+ exitCode: ExitCode.Success,
16530
+ stdout: toJsonLine({
16531
+ action: "profiles-delete",
16532
+ dryRun: false,
16533
+ projectKey,
16534
+ profileId,
16535
+ detachedCount: detachedIds.length,
16536
+ detachedAutomationIds: detachedIds,
16537
+ deleted: true
16538
+ })
16539
+ };
16540
+ }
16541
+ return {
16542
+ exitCode: ExitCode.Success,
16543
+ stdout: [
16544
+ `Deleted automation profile ${profileId}.`,
16545
+ detach ? `Detached ${detachedIds.length} automation binding(s) first.` : "No automatic detach was requested."
16546
+ ]
16547
+ };
16548
+ } catch (error) {
16549
+ return {
16550
+ exitCode: ExitCode.TransportError,
16551
+ stderr: [`ERROR: ${normalizeError6(error)}`]
16552
+ };
16553
+ }
16554
+ }
16555
+ if (subcommand === "clear") {
16556
+ if (profileId || detach) {
16557
+ return {
16558
+ exitCode: ExitCode.UsageError,
16559
+ stderr: [
16560
+ "ERROR: profiles clear clears every profile and profile-based binding; do not pass --id or --detach."
16561
+ ]
16562
+ };
16563
+ }
16564
+ if (!dryRun && !confirmed) {
16565
+ return confirmationRequiredResponse("profiles clear");
16566
+ }
16567
+ try {
16568
+ const [profilesResult, automationsResult] = await Promise.all([
16569
+ context.invokeForgeContract("listScenarioAutomationProfiles", {
16570
+ context: forgeContext
16571
+ }),
16572
+ context.invokeForgeContract("listScenarioAutomations", {
16573
+ context: forgeContext
16574
+ })
16575
+ ]);
16576
+ if (!profilesResult.ok) {
16577
+ return remoteErrorResponse(profilesResult.error.code, profilesResult.error.message);
16578
+ }
16579
+ if (!automationsResult.ok) {
16580
+ return remoteErrorResponse(automationsResult.error.code, automationsResult.error.message);
16581
+ }
16582
+ const profiles = profilesResult.data;
16583
+ const bindings = allProfileBindings(automationsResult.data);
16584
+ if (dryRun) {
16585
+ if (useJson) {
16586
+ return {
16587
+ exitCode: ExitCode.Success,
16588
+ stdout: toJsonLine({
16589
+ action: "profiles-clear",
16590
+ dryRun: true,
16591
+ projectKey,
16592
+ profileCount: profiles.length,
16593
+ bindingCount: bindings.length,
16594
+ profiles: profiles.map(toJsonProfile),
16595
+ bindings: bindings.map(toJsonBinding)
16596
+ })
16597
+ };
16598
+ }
16599
+ return {
16600
+ exitCode: ExitCode.Success,
16601
+ stdout: [
16602
+ `Dry run: would detach ${bindings.length} profile-based automation binding(s) and delete ${profiles.length} automation profile(s).`,
16603
+ ...bindingLines(bindings),
16604
+ ...profiles.map((profile) => `- profile ${profile.id} ${profile.label}`),
16605
+ "Direct (non-profile) scenario automations are preserved.",
16606
+ "No changes made."
16607
+ ]
16608
+ };
16609
+ }
16610
+ const detachedIds = [];
16611
+ for (const binding of bindings) {
16612
+ const deletedBinding = await context.invokeForgeContract("deleteScenarioAutomation", {
16613
+ context: forgeContext,
16614
+ automationId: binding.id
16615
+ });
16616
+ if (!deletedBinding.ok) {
16617
+ return remoteErrorResponse(deletedBinding.error.code, deletedBinding.error.message, [
16618
+ `Detached ${detachedIds.length} of ${bindings.length} profile-based automation binding(s). No profiles were deleted after the failure.`
16619
+ ]);
16620
+ }
16621
+ detachedIds.push(binding.id);
16622
+ }
16623
+ const deletedProfileIds = [];
16624
+ for (const profile of profiles) {
16625
+ const deletedProfile = await context.invokeForgeContract("deleteScenarioAutomationProfile", {
16626
+ context: forgeContext,
16627
+ profileId: profile.id
16628
+ });
16629
+ if (!deletedProfile.ok) {
16630
+ return remoteErrorResponse(deletedProfile.error.code, deletedProfile.error.message, [
16631
+ `Detached ${detachedIds.length} profile-based automation binding(s).`,
16632
+ `Deleted ${deletedProfileIds.length} of ${profiles.length} automation profile(s) before the failure.`
16633
+ ]);
16634
+ }
16635
+ deletedProfileIds.push(profile.id);
16636
+ }
16637
+ if (useJson) {
16638
+ return {
16639
+ exitCode: ExitCode.Success,
16640
+ stdout: toJsonLine({
16641
+ action: "profiles-clear",
16642
+ dryRun: false,
16643
+ projectKey,
16644
+ detachedCount: detachedIds.length,
16645
+ detachedAutomationIds: detachedIds,
16646
+ deletedProfileCount: deletedProfileIds.length,
16647
+ deletedProfileIds
16648
+ })
16649
+ };
16650
+ }
16651
+ return {
16652
+ exitCode: ExitCode.Success,
16653
+ stdout: [
16654
+ `Detached ${detachedIds.length} profile-based automation binding(s).`,
16655
+ `Deleted ${deletedProfileIds.length} automation profile(s).`,
16656
+ "Direct (non-profile) scenario automations were preserved."
16657
+ ]
16658
+ };
16659
+ } catch (error) {
16660
+ return {
16661
+ exitCode: ExitCode.TransportError,
16662
+ stderr: [`ERROR: ${normalizeError6(error)}`]
16663
+ };
16664
+ }
16665
+ }
16666
+ return {
16667
+ exitCode: ExitCode.UsageError,
16668
+ stderr: ["ERROR: Unsupported profiles subcommand. Use: list, detach, delete, or clear."]
16669
+ };
16670
+ };
16671
+ }
16672
+
16175
16673
  // src/runUpload.ts
16176
16674
  var import_node_fs13 = require("node:fs");
16177
16675
  var import_node_path13 = __toESM(require("node:path"), 1);
@@ -16181,7 +16679,7 @@ var STEP_RESULTS = [
16181
16679
  StepResult.Skipped,
16182
16680
  StepResult.Blocked
16183
16681
  ];
16184
- var CONFIG_FLAGS7 = /* @__PURE__ */ new Set([
16682
+ var CONFIG_FLAGS8 = /* @__PURE__ */ new Set([
16185
16683
  "--config",
16186
16684
  "--base-url",
16187
16685
  "--project-key",
@@ -16190,7 +16688,7 @@ var CONFIG_FLAGS7 = /* @__PURE__ */ new Set([
16190
16688
  "--jira-email",
16191
16689
  "--jira-api-token"
16192
16690
  ]);
16193
- function parseArgs8(args) {
16691
+ function parseArgs9(args) {
16194
16692
  const flags = {};
16195
16693
  const boolFlags = /* @__PURE__ */ new Set();
16196
16694
  const unknownFlags = [];
@@ -16201,7 +16699,7 @@ function parseArgs8(args) {
16201
16699
  "--feature-name",
16202
16700
  "--scenario-name",
16203
16701
  "--executed-at",
16204
- ...CONFIG_FLAGS7
16702
+ ...CONFIG_FLAGS8
16205
16703
  ]);
16206
16704
  const supportedBoolFlags = /* @__PURE__ */ new Set(["--stdin", "--json"]);
16207
16705
  for (let i = 0; i < args.length; i += 1) {
@@ -16227,16 +16725,16 @@ function parseArgs8(args) {
16227
16725
  }
16228
16726
  return { flags, boolFlags, unknownFlags };
16229
16727
  }
16230
- function pickConfigArgs7(parsed) {
16728
+ function pickConfigArgs8(parsed) {
16231
16729
  const configArgs = [];
16232
16730
  for (const [flag, value] of Object.entries(parsed.flags)) {
16233
- if (CONFIG_FLAGS7.has(flag)) {
16731
+ if (CONFIG_FLAGS8.has(flag)) {
16234
16732
  configArgs.push(flag, value);
16235
16733
  }
16236
16734
  }
16237
16735
  return configArgs;
16238
16736
  }
16239
- function normalizeError6(error) {
16737
+ function normalizeError7(error) {
16240
16738
  if (error instanceof ForgeClientError) {
16241
16739
  return `${error.code}: ${error.message}`;
16242
16740
  }
@@ -16321,8 +16819,8 @@ function createRunUploadHandler(deps = {}) {
16321
16819
  const env = deps.env ?? process.env;
16322
16820
  return async (request, context) => {
16323
16821
  const [, ...subArgs] = request.args;
16324
- const parsed = parseArgs8(subArgs);
16325
- const configArgs = pickConfigArgs7(parsed);
16822
+ const parsed = parseArgs9(subArgs);
16823
+ const configArgs = pickConfigArgs8(parsed);
16326
16824
  const config = resolveCliConfig(configArgs, env, cwd);
16327
16825
  const projectKey = config.values.projectKey;
16328
16826
  const issueKey = config.values.issueKey;
@@ -16355,7 +16853,7 @@ function createRunUploadHandler(deps = {}) {
16355
16853
  } catch (error) {
16356
16854
  return {
16357
16855
  exitCode: ExitCode.InternalError,
16358
- stderr: [`ERROR: Failed to read run payload source: ${normalizeError6(error)}`]
16856
+ stderr: [`ERROR: Failed to read run payload source: ${normalizeError7(error)}`]
16359
16857
  };
16360
16858
  }
16361
16859
  const payloadFromSource = parseRunPayload(raw);
@@ -16385,7 +16883,7 @@ function createRunUploadHandler(deps = {}) {
16385
16883
  } catch (error) {
16386
16884
  return {
16387
16885
  exitCode: ExitCode.TransportError,
16388
- stderr: [`ERROR: ${normalizeError6(error)}`]
16886
+ stderr: [`ERROR: ${normalizeError7(error)}`]
16389
16887
  };
16390
16888
  }
16391
16889
  }
@@ -16465,7 +16963,7 @@ function createRunUploadHandler(deps = {}) {
16465
16963
  featureName: runInput.featureName,
16466
16964
  scenarioName: runInput.scenarioName,
16467
16965
  executedAt: runInput.executedAt,
16468
- errorMessage: normalizeError6(error)
16966
+ errorMessage: normalizeError7(error)
16469
16967
  })
16470
16968
  };
16471
16969
  }
@@ -16477,14 +16975,14 @@ function createRunUploadHandler(deps = {}) {
16477
16975
  `Scenario: ${runInput.scenarioName}`,
16478
16976
  `ExecutedAt: ${runInput.executedAt}`
16479
16977
  ],
16480
- stderr: [`ERROR: ${normalizeError6(error)}`]
16978
+ stderr: [`ERROR: ${normalizeError7(error)}`]
16481
16979
  };
16482
16980
  }
16483
16981
  };
16484
16982
  }
16485
16983
 
16486
16984
  // src/runs.ts
16487
- var CONFIG_FLAGS8 = /* @__PURE__ */ new Set([
16985
+ var CONFIG_FLAGS9 = /* @__PURE__ */ new Set([
16488
16986
  "--config",
16489
16987
  "--base-url",
16490
16988
  "--project-key",
@@ -16493,11 +16991,11 @@ var CONFIG_FLAGS8 = /* @__PURE__ */ new Set([
16493
16991
  "--jira-email",
16494
16992
  "--jira-api-token"
16495
16993
  ]);
16496
- function parseArgs9(args) {
16994
+ function parseArgs10(args) {
16497
16995
  const flags = {};
16498
16996
  const boolFlags = /* @__PURE__ */ new Set();
16499
16997
  const unknownFlags = [];
16500
- const supportedValueFlags = /* @__PURE__ */ new Set(["--id", ...CONFIG_FLAGS8]);
16998
+ const supportedValueFlags = /* @__PURE__ */ new Set(["--id", ...CONFIG_FLAGS9]);
16501
16999
  const supportedBoolFlags = /* @__PURE__ */ new Set(["--json"]);
16502
17000
  for (let index = 0; index < args.length; index += 1) {
16503
17001
  const token = args[index];
@@ -16522,16 +17020,16 @@ function parseArgs9(args) {
16522
17020
  }
16523
17021
  return { flags, boolFlags, unknownFlags };
16524
17022
  }
16525
- function pickConfigArgs8(parsed) {
17023
+ function pickConfigArgs9(parsed) {
16526
17024
  const args = [];
16527
17025
  for (const [flag, value] of Object.entries(parsed.flags)) {
16528
- if (CONFIG_FLAGS8.has(flag)) {
17026
+ if (CONFIG_FLAGS9.has(flag)) {
16529
17027
  args.push(flag, value);
16530
17028
  }
16531
17029
  }
16532
17030
  return args;
16533
17031
  }
16534
- function normalizeError7(error) {
17032
+ function normalizeError8(error) {
16535
17033
  if (error instanceof ForgeClientError) {
16536
17034
  return `${error.code}: ${error.message}`;
16537
17035
  }
@@ -16584,7 +17082,7 @@ function runToLines(run) {
16584
17082
  }
16585
17083
  return lines;
16586
17084
  }
16587
- function missingProjectResponse3() {
17085
+ function missingProjectResponse4() {
16588
17086
  return {
16589
17087
  exitCode: ExitCode.ValidationError,
16590
17088
  stderr: ["ERROR: Missing project context. Set JIRA_PROJECT_KEY or pass --project-key."]
@@ -16595,9 +17093,9 @@ function createRunsHandler(deps = {}) {
16595
17093
  const env = deps.env ?? process.env;
16596
17094
  return async (request, context) => {
16597
17095
  const [subcommand, ...restArgs] = request.args;
16598
- const parsed = parseArgs9(restArgs);
17096
+ const parsed = parseArgs10(restArgs);
16599
17097
  const useJson = parsed.boolFlags.has("--json");
16600
- const config = resolveCliConfig(pickConfigArgs8(parsed), env, cwd);
17098
+ const config = resolveCliConfig(pickConfigArgs9(parsed), env, cwd);
16601
17099
  const projectKey = config.values.projectKey;
16602
17100
  const issueKey = config.values.issueKey;
16603
17101
  if (parsed.unknownFlags.length > 0) {
@@ -16607,7 +17105,7 @@ function createRunsHandler(deps = {}) {
16607
17105
  };
16608
17106
  }
16609
17107
  if (!projectKey) {
16610
- return missingProjectResponse3();
17108
+ return missingProjectResponse4();
16611
17109
  }
16612
17110
  if (subcommand === "show") {
16613
17111
  const runId = parsed.flags["--id"]?.trim() ?? "";
@@ -16649,7 +17147,7 @@ function createRunsHandler(deps = {}) {
16649
17147
  } catch (error) {
16650
17148
  return {
16651
17149
  exitCode: ExitCode.TransportError,
16652
- stderr: [`ERROR: ${normalizeError7(error)}`]
17150
+ stderr: [`ERROR: ${normalizeError8(error)}`]
16653
17151
  };
16654
17152
  }
16655
17153
  }
@@ -17629,7 +18127,7 @@ function defaultReadStdin() {
17629
18127
  process.stdin.on("error", reject);
17630
18128
  });
17631
18129
  }
17632
- function parseArgs10(args, valueFlags, boolFlags, allowApplyCollections = false) {
18130
+ function parseArgs11(args, valueFlags, boolFlags, allowApplyCollections = false) {
17633
18131
  const flags = {};
17634
18132
  const enabled = /* @__PURE__ */ new Set();
17635
18133
  const approvals = [];
@@ -18239,7 +18737,7 @@ async function inspectPlan(plan, repoRoot, secrets, context, deps) {
18239
18737
  };
18240
18738
  }
18241
18739
  function planCommand(args, deps) {
18242
- const parsed = parseArgs10(args, PLAN_VALUE_FLAGS, /* @__PURE__ */ new Set(["--set-default", "--disabled"]));
18740
+ const parsed = parseArgs11(args, PLAN_VALUE_FLAGS, /* @__PURE__ */ new Set(["--set-default", "--disabled"]));
18243
18741
  if (parsed.errors.length > 0) {
18244
18742
  return jsonResponse(
18245
18743
  errorPayload("USAGE_ERROR", "Invalid setup plan arguments.", parsed.errors),
@@ -18298,7 +18796,7 @@ function planCommand(args, deps) {
18298
18796
  }
18299
18797
  }
18300
18798
  async function applyCommand(args, context, deps) {
18301
- const parsed = parseArgs10(args, APPLY_VALUE_FLAGS, APPLY_BOOL_FLAGS, true);
18799
+ const parsed = parseArgs11(args, APPLY_VALUE_FLAGS, APPLY_BOOL_FLAGS, true);
18302
18800
  if (parsed.errors.length > 0) {
18303
18801
  return jsonResponse(
18304
18802
  errorPayload("USAGE_ERROR", "Invalid setup apply arguments.", parsed.errors),
@@ -18541,7 +19039,7 @@ async function applyAzureCommand(plan, parsed, context, deps, secrets) {
18541
19039
  });
18542
19040
  }
18543
19041
  async function doctorCommand(args, context, deps) {
18544
- const parsed = parseArgs10(args, APPLY_VALUE_FLAGS, /* @__PURE__ */ new Set(["--secrets-stdin"]), true);
19042
+ const parsed = parseArgs11(args, APPLY_VALUE_FLAGS, /* @__PURE__ */ new Set(["--secrets-stdin"]), true);
18545
19043
  if (parsed.approvals.length > 0) {
18546
19044
  return jsonResponse(errorPayload("USAGE_ERROR", "setup doctor does not accept --approve."), ExitCode.UsageError);
18547
19045
  }
@@ -18654,7 +19152,7 @@ function createSetupHandler(overrides = {}) {
18654
19152
  }
18655
19153
 
18656
19154
  // src/suites.ts
18657
- var CONFIG_FLAGS9 = /* @__PURE__ */ new Set([
19155
+ var CONFIG_FLAGS10 = /* @__PURE__ */ new Set([
18658
19156
  "--config",
18659
19157
  "--base-url",
18660
19158
  "--project-key",
@@ -18663,11 +19161,11 @@ var CONFIG_FLAGS9 = /* @__PURE__ */ new Set([
18663
19161
  "--jira-email",
18664
19162
  "--jira-api-token"
18665
19163
  ]);
18666
- function parseArgs11(args) {
19164
+ function parseArgs12(args) {
18667
19165
  const flags = {};
18668
19166
  const boolFlags = /* @__PURE__ */ new Set();
18669
19167
  const unknownFlags = [];
18670
- const supportedValueFlags = /* @__PURE__ */ new Set(["--key", ...CONFIG_FLAGS9]);
19168
+ const supportedValueFlags = /* @__PURE__ */ new Set(["--key", ...CONFIG_FLAGS10]);
18671
19169
  const supportedBoolFlags = /* @__PURE__ */ new Set(["--json"]);
18672
19170
  for (let index = 0; index < args.length; index += 1) {
18673
19171
  const token = args[index];
@@ -18692,16 +19190,16 @@ function parseArgs11(args) {
18692
19190
  }
18693
19191
  return { flags, boolFlags, unknownFlags };
18694
19192
  }
18695
- function pickConfigArgs9(parsed) {
19193
+ function pickConfigArgs10(parsed) {
18696
19194
  const args = [];
18697
19195
  for (const [flag, value] of Object.entries(parsed.flags)) {
18698
- if (CONFIG_FLAGS9.has(flag)) {
19196
+ if (CONFIG_FLAGS10.has(flag)) {
18699
19197
  args.push(flag, value);
18700
19198
  }
18701
19199
  }
18702
19200
  return args;
18703
19201
  }
18704
- function normalizeError8(error) {
19202
+ function normalizeError9(error) {
18705
19203
  if (error instanceof ForgeClientError) {
18706
19204
  return `${error.code}: ${error.message}`;
18707
19205
  }
@@ -18763,7 +19261,7 @@ function suiteCasesToLines(suite, items) {
18763
19261
  ...items.map((item) => `- ${item.key} [${item.status}] ${item.title}`)
18764
19262
  ];
18765
19263
  }
18766
- function missingProjectResponse4() {
19264
+ function missingProjectResponse5() {
18767
19265
  return {
18768
19266
  exitCode: ExitCode.ValidationError,
18769
19267
  stderr: ["ERROR: Missing project context. Set JIRA_PROJECT_KEY or pass --project-key."]
@@ -18780,9 +19278,9 @@ function createSuitesHandler(deps = {}) {
18780
19278
  const env = deps.env ?? process.env;
18781
19279
  return async (request, context) => {
18782
19280
  const [subcommand, ...restArgs] = request.args;
18783
- const parsed = parseArgs11(restArgs);
19281
+ const parsed = parseArgs12(restArgs);
18784
19282
  const useJson = parsed.boolFlags.has("--json");
18785
- const config = resolveCliConfig(pickConfigArgs9(parsed), env, cwd);
19283
+ const config = resolveCliConfig(pickConfigArgs10(parsed), env, cwd);
18786
19284
  const projectKey = config.values.projectKey;
18787
19285
  const issueKey = config.values.issueKey;
18788
19286
  if (parsed.unknownFlags.length > 0) {
@@ -18792,7 +19290,7 @@ function createSuitesHandler(deps = {}) {
18792
19290
  };
18793
19291
  }
18794
19292
  if (!projectKey) {
18795
- return missingProjectResponse4();
19293
+ return missingProjectResponse5();
18796
19294
  }
18797
19295
  if (subcommand === "list") {
18798
19296
  try {
@@ -18827,7 +19325,7 @@ function createSuitesHandler(deps = {}) {
18827
19325
  } catch (error) {
18828
19326
  return {
18829
19327
  exitCode: ExitCode.TransportError,
18830
- stderr: [`ERROR: ${normalizeError8(error)}`]
19328
+ stderr: [`ERROR: ${normalizeError9(error)}`]
18831
19329
  };
18832
19330
  }
18833
19331
  }
@@ -18868,7 +19366,7 @@ function createSuitesHandler(deps = {}) {
18868
19366
  } catch (error) {
18869
19367
  return {
18870
19368
  exitCode: ExitCode.TransportError,
18871
- stderr: [`ERROR: ${normalizeError8(error)}`]
19369
+ stderr: [`ERROR: ${normalizeError9(error)}`]
18872
19370
  };
18873
19371
  }
18874
19372
  }
@@ -18932,7 +19430,7 @@ function createSuitesHandler(deps = {}) {
18932
19430
  } catch (error) {
18933
19431
  return {
18934
19432
  exitCode: ExitCode.TransportError,
18935
- stderr: [`ERROR: ${normalizeError8(error)}`]
19433
+ stderr: [`ERROR: ${normalizeError9(error)}`]
18936
19434
  };
18937
19435
  }
18938
19436
  }
@@ -18944,7 +19442,7 @@ function createSuitesHandler(deps = {}) {
18944
19442
  }
18945
19443
 
18946
19444
  // src/sync.ts
18947
- var CONFIG_FLAGS10 = /* @__PURE__ */ new Set([
19445
+ var CONFIG_FLAGS11 = /* @__PURE__ */ new Set([
18948
19446
  "--config",
18949
19447
  "--base-url",
18950
19448
  "--project-key",
@@ -18954,11 +19452,11 @@ var CONFIG_FLAGS10 = /* @__PURE__ */ new Set([
18954
19452
  "--jira-api-token"
18955
19453
  ]);
18956
19454
  var RECONCILE_CONFIRM_TOKEN = "RECONCILE";
18957
- function parseArgs12(args) {
19455
+ function parseArgs13(args) {
18958
19456
  const flags = {};
18959
19457
  const boolFlags = /* @__PURE__ */ new Set();
18960
19458
  const unknownFlags = [];
18961
- const supportedValueFlags = /* @__PURE__ */ new Set(["--confirm", ...CONFIG_FLAGS10]);
19459
+ const supportedValueFlags = /* @__PURE__ */ new Set(["--confirm", ...CONFIG_FLAGS11]);
18962
19460
  const supportedBoolFlags = /* @__PURE__ */ new Set(["--json"]);
18963
19461
  for (let i = 0; i < args.length; i += 1) {
18964
19462
  const token = args[i];
@@ -18983,16 +19481,16 @@ function parseArgs12(args) {
18983
19481
  }
18984
19482
  return { flags, boolFlags, unknownFlags };
18985
19483
  }
18986
- function pickConfigArgs10(parsed) {
19484
+ function pickConfigArgs11(parsed) {
18987
19485
  const args = [];
18988
19486
  for (const [flag, value] of Object.entries(parsed.flags)) {
18989
- if (CONFIG_FLAGS10.has(flag)) {
19487
+ if (CONFIG_FLAGS11.has(flag)) {
18990
19488
  args.push(flag, value);
18991
19489
  }
18992
19490
  }
18993
19491
  return args;
18994
19492
  }
18995
- function normalizeError9(error) {
19493
+ function normalizeError10(error) {
18996
19494
  if (error instanceof ForgeClientError) {
18997
19495
  return `${error.code}: ${error.message}`;
18998
19496
  }
@@ -19043,9 +19541,9 @@ function createSyncHandler(deps = {}) {
19043
19541
  const env = deps.env ?? process.env;
19044
19542
  return async (request, context) => {
19045
19543
  const [subcommand, ...restArgs] = request.args;
19046
- const parsed = parseArgs12(restArgs);
19544
+ const parsed = parseArgs13(restArgs);
19047
19545
  const useJson = parsed.boolFlags.has("--json");
19048
- const config = resolveCliConfig(pickConfigArgs10(parsed), env, cwd);
19546
+ const config = resolveCliConfig(pickConfigArgs11(parsed), env, cwd);
19049
19547
  const projectKey = config.values.projectKey;
19050
19548
  const issueKey = config.values.issueKey;
19051
19549
  if (parsed.unknownFlags.length > 0) {
@@ -19095,7 +19593,7 @@ function createSyncHandler(deps = {}) {
19095
19593
  } catch (error) {
19096
19594
  return {
19097
19595
  exitCode: ExitCode.TransportError,
19098
- stderr: [`ERROR: ${normalizeError9(error)}`]
19596
+ stderr: [`ERROR: ${normalizeError10(error)}`]
19099
19597
  };
19100
19598
  }
19101
19599
  }
@@ -19141,7 +19639,7 @@ function createSyncHandler(deps = {}) {
19141
19639
  } catch (error) {
19142
19640
  return {
19143
19641
  exitCode: ExitCode.TransportError,
19144
- stderr: [`ERROR: ${normalizeError9(error)}`]
19642
+ stderr: [`ERROR: ${normalizeError10(error)}`]
19145
19643
  };
19146
19644
  }
19147
19645
  }
@@ -19197,6 +19695,12 @@ var COMMAND_REGISTRY = [
19197
19695
  subcommands: ["feature"],
19198
19696
  handler: createIngestFeatureHandler()
19199
19697
  },
19698
+ {
19699
+ name: "profiles",
19700
+ description: "Automation profile inspection, detach, delete, and demo cleanup commands",
19701
+ subcommands: ["list", "detach", "delete", "clear"],
19702
+ handler: createProfilesHandler()
19703
+ },
19200
19704
  {
19201
19705
  name: "run",
19202
19706
  description: "Execution result upload commands",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automatify-au/cli",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Forge-first CLI for Automatify Jira TestOps",
5
5
  "type": "module",
6
6
  "bin": {