@getmagical/cli 0.3.1 → 0.3.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/README.md CHANGED
@@ -129,20 +129,25 @@ mgcl --branch-id <branch-id> workbench patch readiness --target-draft-automation
129
129
  Branch creation defaults to main. Use `--source-branch-id` and optionally
130
130
  `--source-version-id` to fork from another branch or an older version in that
131
131
  branch's history. Names must use lowercase letters or numbers separated by
132
- single dashes, such as `release-2`. Spaces, underscores, slashes, backslashes,
133
- punctuation, uppercase letters, leading or trailing dashes, and repeated dashes
134
- are rejected before an API request. Branch IDs, not names, identify targets.
132
+ single dashes, such as `release-2`, and must be 100 characters or fewer.
133
+ Spaces, underscores, slashes, backslashes, punctuation, uppercase letters,
134
+ leading or trailing dashes, repeated dashes, and over-length names are
135
+ rejected before an API request. Branch IDs, not names, identify targets, and
136
+ every automation or branch ID must be a UUID; malformed IDs are rejected
137
+ before an API request.
135
138
  Merge previews the same change set as the web UI. A conflict returns
136
- `status: "conflict"` and does not change main or delete the branch. A
137
- conflict-free merge returns `status: "merged"`, the saved-main result, and
138
- deletes the source branch. Rename, delete, compare, and publish are
139
- intentionally deferred.
139
+ `status: "conflict"`, does not change main or delete the branch, and exits
140
+ nonzero so scripts gating on the exit code never mistake it for an applied
141
+ merge. A conflict-free merge returns `status: "merged"`, the saved-main
142
+ result, and deletes the source branch. Rename, delete, compare, and publish
143
+ are intentionally deferred.
140
144
 
141
145
  The global branch target is accepted by `automations update`, `automations
142
- run-draft`, `workbench diagnostics`, `workbench schema-suggestions`, and
143
- `workbench patch preview`, `readiness`, and `apply`. It is required by
144
- `automations branches get` and `merge`. Other commands reject `--branch-id`
145
- before making an API request. Branch-aware responses identify the selected
146
+ run-draft`, `automations diff-from-published`, `workbench diagnostics`,
147
+ `workbench schema-suggestions`, and `workbench patch preview`, `readiness`,
148
+ and `apply`. It is required by `automations branches get` and `merge`. Other
149
+ commands reject `--branch-id` before making an API request, and
150
+ `mgcl --help` lists the branch-aware commands. Branch-aware responses identify the selected
146
151
  target with `branchId` and `headVersionId`. Merge returns `branchId`, its exact
147
152
  preview and conflicts, plus the new main head as `applyResult.draftVersionId`
148
153
  when successful. Branch inspection excludes workspace authentication records
package/dist/index.js CHANGED
@@ -7764,6 +7764,10 @@ function safeJsonParseWithoutLogging(json) {
7764
7764
  }
7765
7765
  }
7766
7766
 
7767
+ // ../common/dist/src/constants/automation.js
7768
+ var AUTOMATION_BRANCH_NAME_MAX_LENGTH = 100;
7769
+ var AUTOMATION_BRANCH_NAME_MAX_LENGTH_MESSAGE = `Branch name must be ${AUTOMATION_BRANCH_NAME_MAX_LENGTH} characters or fewer.`;
7770
+
7767
7771
  // ../common/dist/src/constants/tool-declarations.js
7768
7772
  import { z as z15 } from "zod";
7769
7773
 
@@ -15396,12 +15400,14 @@ query GetAutomationAgents($ids: [ID!]!) {
15396
15400
  operationName: "GetAutomationDiffFromPublished",
15397
15401
  kind: "query",
15398
15402
  inputSchema: z27.object({
15399
- automationId: z27.string().min(1)
15403
+ automationId: z27.uuid("--automation-id must be a UUID."),
15404
+ branchId: z27.uuid("--branch-id must be a UUID.").optional()
15400
15405
  }),
15401
15406
  cli: {
15407
+ branchContext: "optional",
15402
15408
  name: "get-automation-diff-from-published",
15403
15409
  path: ["automations", "diff-from-published"],
15404
- description: "Fetch draft-vs-published automation JSON Patch.",
15410
+ description: "Fetch draft-vs-published automation JSON Patch for main or one branch.",
15405
15411
  resultKey: "automationDiffFromPublished",
15406
15412
  options: [
15407
15413
  stringOption({
@@ -15413,9 +15419,10 @@ query GetAutomationAgents($ids: [ID!]!) {
15413
15419
  ]
15414
15420
  },
15415
15421
  mcp: { fileName: "automationDiffFromPublished.graphql" },
15416
- document: `# Query JSON Patch changes from published automation JSON to draft automation JSON
15417
- query GetAutomationDiffFromPublished($automationId: ID!) {
15418
- automationDiffFromPublished(automationId: $automationId) {
15422
+ document: `# Query JSON Patch changes from published automation JSON to draft automation JSON.
15423
+ # Pass branchId to diff a branch head against published instead of the main draft.
15424
+ query GetAutomationDiffFromPublished($automationId: ID!, $branchId: ID) {
15425
+ automationDiffFromPublished(automationId: $automationId, branchId: $branchId) {
15419
15426
  automationId
15420
15427
  automationName
15421
15428
  mode
@@ -15975,7 +15982,7 @@ query ViewAutomationReview($automationId: ID!) {
15975
15982
  operationName: "ListAutomationBranches",
15976
15983
  kind: "query",
15977
15984
  inputSchema: z27.object({
15978
- automationId: z27.string().min(1)
15985
+ automationId: z27.uuid("--automation-id must be a UUID.")
15979
15986
  }),
15980
15987
  cli: {
15981
15988
  name: "list-automation-branches",
@@ -16010,10 +16017,13 @@ query ListAutomationBranches($automationId: ID!) {
16010
16017
  operationName: "CreateAutomationBranch",
16011
16018
  kind: "mutation",
16012
16019
  inputSchema: z27.object({
16013
- automationId: z27.string().min(1),
16014
- name: z27.string().regex(AUTOMATION_BRANCH_NAME_PATTERN, AUTOMATION_BRANCH_NAME_MESSAGE),
16015
- sourceBranchId: z27.string().min(1).optional(),
16016
- sourceVersionId: z27.string().min(1).optional()
16020
+ automationId: z27.uuid("--automation-id must be a UUID."),
16021
+ name: z27.string().regex(AUTOMATION_BRANCH_NAME_PATTERN, AUTOMATION_BRANCH_NAME_MESSAGE).max(
16022
+ AUTOMATION_BRANCH_NAME_MAX_LENGTH,
16023
+ AUTOMATION_BRANCH_NAME_MAX_LENGTH_MESSAGE
16024
+ ),
16025
+ sourceBranchId: z27.uuid("--source-branch-id must be a UUID.").optional(),
16026
+ sourceVersionId: z27.uuid("--source-version-id must be a UUID.").optional()
16017
16027
  }),
16018
16028
  cli: {
16019
16029
  name: "create-automation-branch",
@@ -16074,8 +16084,8 @@ mutation CreateAutomationBranch(
16074
16084
  operationName: "GetAutomationBranch",
16075
16085
  kind: "query",
16076
16086
  inputSchema: z27.object({
16077
- automationId: z27.string().min(1),
16078
- branchId: z27.string().min(1)
16087
+ automationId: z27.uuid("--automation-id must be a UUID."),
16088
+ branchId: z27.uuid("--branch-id must be a UUID.")
16079
16089
  }),
16080
16090
  cli: {
16081
16091
  branchContext: "required",
@@ -16106,14 +16116,14 @@ query GetAutomationBranch($automationId: ID!, $branchId: ID!) {
16106
16116
  operationName: "MergeAutomationBranch",
16107
16117
  kind: "mutation",
16108
16118
  inputSchema: z27.object({
16109
- automationId: z27.string().min(1),
16110
- branchId: z27.string().min(1)
16119
+ automationId: z27.uuid("--automation-id must be a UUID."),
16120
+ branchId: z27.uuid("--branch-id must be a UUID.")
16111
16121
  }),
16112
16122
  cli: {
16113
16123
  branchContext: "required",
16114
16124
  name: "merge-automation-branch",
16115
16125
  path: ["automations", "branches", "merge"],
16116
- description: "Preview and merge a branch into main when every change is conflict-free.",
16126
+ description: "Preview and merge a branch into main when every change is conflict-free. Exits nonzero when conflicts block the merge.",
16117
16127
  resultKey: "mergeAutomationBranch",
16118
16128
  options: [
16119
16129
  stringOption({
@@ -18586,7 +18596,7 @@ var pathwayRegressionAgentVersionRegressionRunResponseSchema = z28.object({
18586
18596
  automationVersionId: z28.string().min(1),
18587
18597
  baselineAgentVersionId: z28.string().min(1),
18588
18598
  baselineAutomationVersionId: z28.string().min(1),
18589
- baselineContractId: z28.string().min(1),
18599
+ baselineContractId: z28.string().min(1).nullable(),
18590
18600
  candidateContractId: z28.string().min(1),
18591
18601
  contractId: z28.string().min(1),
18592
18602
  paths: z28.array(pathwayRegressionAgentVersionRunPathSchema),
@@ -19464,6 +19474,32 @@ function configureCommandPresentation(command) {
19464
19474
  command.createHelp = () => new MagicalHelp();
19465
19475
  return command;
19466
19476
  }
19477
+ function formatBranchAwareCommandsHelp() {
19478
+ const branchAwareCommandLines = operationSpecs.flatMap((operationSpec) => {
19479
+ const { branchContext } = operationSpec.cli;
19480
+ if (branchContext === void 0) {
19481
+ return [];
19482
+ }
19483
+ return [
19484
+ `mgcl ${operationSpec.cli.path.join(" ")} (--branch-id ${branchContext})`
19485
+ ];
19486
+ }).toSorted();
19487
+ return formatExamples("Branch-aware commands", branchAwareCommandLines);
19488
+ }
19489
+ function formatRootAfterHelpText() {
19490
+ return `
19491
+ ${formatExamples("Quick start", [
19492
+ "mgcl auth login",
19493
+ "mgcl org list",
19494
+ "mgcl automations list --limit 10",
19495
+ "mgcl automation-runs get --id <run-id>",
19496
+ "mgcl update"
19497
+ ])}
19498
+
19499
+ ${formatBranchAwareCommandsHelp()}
19500
+
19501
+ ${formatOutputModesNote()}`;
19502
+ }
19467
19503
  function createOperationHelpExamples(operationSpec) {
19468
19504
  const commandPath = operationSpec.cli.path.join(" ");
19469
19505
  const baseCommand = operationSpec.cli.branchContext === "required" ? `mgcl --branch-id <branch-id> ${commandPath}` : `mgcl ${commandPath}`;
@@ -21903,6 +21939,7 @@ async function handleOperationCommand(dependencies, operationSpec, commandOption
21903
21939
  json: commandOptions.json,
21904
21940
  result
21905
21941
  });
21942
+ assertBranchMergeApplied(operationSpec, result);
21906
21943
  if (operationSpec.operationName === "ViewAutomationReview" && commandOptions["open"] && isRecord5(result) && typeof result["reportUrl"] === "string") {
21907
21944
  await dependencies.openExternalUrl(result["reportUrl"]).catch((error) => {
21908
21945
  dependencies.io.error(
@@ -21911,6 +21948,13 @@ async function handleOperationCommand(dependencies, operationSpec, commandOption
21911
21948
  });
21912
21949
  }
21913
21950
  }
21951
+ function assertBranchMergeApplied(operationSpec, result) {
21952
+ if (operationSpec.operationName === "MergeAutomationBranch" && (!isRecord5(result) || result["status"] !== "merged")) {
21953
+ throw new CliError(
21954
+ "Merge not applied. Review the merge output, resolve any conflicts, then merge again."
21955
+ );
21956
+ }
21957
+ }
21914
21958
  function getOperation(operationName) {
21915
21959
  const operationSpec = operationSpecs.find(
21916
21960
  (candidate) => candidate.operationName === operationName
@@ -22898,26 +22942,14 @@ function buildProgram(dependencies) {
22898
22942
  ).addOption(new Option3("--json", "Render JSON output.")).addOption(
22899
22943
  new Option3(
22900
22944
  "--branch-id <id>",
22901
- "Target a supported automation command at one branch; omit it to target main."
22945
+ 'Target a supported automation command at one branch; omit it to target main. "Branch-aware commands" below lists the commands that accept it.'
22902
22946
  )
22903
22947
  ).version(CLI_VERSION, "--version", `Display mgcl version (${CLI_VERSION}).`).addOption(
22904
22948
  new Option3(
22905
22949
  "--update",
22906
22950
  "Update mgcl to the latest published npm release."
22907
22951
  )
22908
- ).showHelpAfterError().showSuggestionAfterError().addHelpText(
22909
- "after",
22910
- `
22911
- ${formatExamples("Quick start", [
22912
- "mgcl auth login",
22913
- "mgcl org list",
22914
- "mgcl automations list --limit 10",
22915
- "mgcl automation-runs get --id <run-id>",
22916
- "mgcl update"
22917
- ])}
22918
-
22919
- ${formatOutputModesNote()}`
22920
- );
22952
+ ).showHelpAfterError().showSuggestionAfterError().addHelpText("after", formatRootAfterHelpText());
22921
22953
  program2.hook("preAction", (_thisCommand, actionCommand) => {
22922
22954
  const options = actionCommand.optsWithGlobals();
22923
22955
  const branchContext = commandBranchContexts.get(actionCommand);