zk-agent-cli 0.1.0-beta.9 → 0.1.0-rc.1

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 (3) hide show
  1. package/README.md +127 -173
  2. package/dist/index.js +1460 -154
  3. package/package.json +4 -2
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli.ts
4
- import { Command as Command11, CommanderError } from "commander";
4
+ import { Command as Command13, CommanderError } from "commander";
5
5
  import { config as loadEnv } from "dotenv";
6
6
 
7
7
  // src/commands/operations.ts
@@ -7824,19 +7824,67 @@ function buildTopLevelNextRecommendedCommand(requestId, paymasterMode) {
7824
7824
  const command = requestId ? `zk-agent next --request-id ${requestId}` : "zk-agent next";
7825
7825
  return appendPaymasterMode(command, paymasterMode);
7826
7826
  }
7827
- function buildWalletCreateRecommendedCommand() {
7828
- return "zk-agent wallet create --await-local";
7827
+ function buildWalletCreateRecommendedCommand(paymasterMode) {
7828
+ return appendPaymasterMode("zk-agent wallet create --await-local", paymasterMode);
7829
7829
  }
7830
7830
  function buildRelayInspectRecommendedCommand(relayUrl = "<url>") {
7831
7831
  return `zk-agent relay inspect --relay-url ${relayUrl}`;
7832
7832
  }
7833
- function buildWalletCreateRemoteRecommendedCommand(relayUrl = "<url>", paymasterMode, walletName = "main", accountKind = "smart-account") {
7834
- const command = [
7833
+ function inferSessionHours(sessionPolicies, requestCreatedAt) {
7834
+ const expiresAt = sessionPolicies?.expiresAt;
7835
+ if (!expiresAt || !requestCreatedAt) return null;
7836
+ const createdAtMs = Date.parse(requestCreatedAt);
7837
+ const expiresAtMs = Date.parse(expiresAt);
7838
+ if (!Number.isFinite(createdAtMs) || !Number.isFinite(expiresAtMs) || expiresAtMs <= createdAtMs) {
7839
+ return null;
7840
+ }
7841
+ const hours = (expiresAtMs - createdAtMs) / (60 * 60 * 1e3);
7842
+ if (!Number.isFinite(hours) || hours <= 0) return null;
7843
+ const rounded = Math.round(hours * 1e3) / 1e3;
7844
+ if (Math.abs(rounded - 24) < 5e-4) {
7845
+ return null;
7846
+ }
7847
+ return Number.isInteger(rounded) ? String(rounded) : String(rounded).replace(/(?:\.0+|(\.\d*?)0+)$/, "$1");
7848
+ }
7849
+ function appendSessionPolicyFlags(commandParts, options) {
7850
+ const sessionHours = inferSessionHours(options?.sessionPolicies, options?.requestCreatedAt);
7851
+ if (sessionHours) {
7852
+ commandParts.push(`--session-hours ${sessionHours}`);
7853
+ }
7854
+ const transfers = options?.sessionPolicies?.transfers;
7855
+ if (Array.isArray(transfers)) {
7856
+ if (transfers.length === 0) {
7857
+ commandParts.push("--disallow-transfers");
7858
+ } else {
7859
+ for (const policy of transfers) {
7860
+ if (policy?.to) {
7861
+ commandParts.push(`--allow-transfer-to ${policy.to}`);
7862
+ }
7863
+ }
7864
+ }
7865
+ }
7866
+ const contractCalls = options?.sessionPolicies?.contractCalls;
7867
+ if (Array.isArray(contractCalls)) {
7868
+ if (contractCalls.length === 0) {
7869
+ commandParts.push("--disallow-contract-calls");
7870
+ } else {
7871
+ for (const policy of contractCalls) {
7872
+ if (policy?.address) {
7873
+ commandParts.push(`--allow-contract ${policy.address}`);
7874
+ }
7875
+ }
7876
+ }
7877
+ }
7878
+ }
7879
+ function buildWalletCreateRemoteRecommendedCommand(relayUrl = "<url>", paymasterMode, walletName = "main", accountKind = "smart-account", options) {
7880
+ const commandParts = [
7835
7881
  "zk-agent wallet create",
7836
7882
  walletName !== "main" ? `--name ${walletName}` : "",
7837
- accountKind !== "smart-account" ? `--account-kind ${accountKind}` : "",
7838
- `--relay-url ${relayUrl} --wait-relay --prompt-code`
7839
- ].filter(Boolean).join(" ");
7883
+ accountKind !== "smart-account" ? `--account-kind ${accountKind}` : ""
7884
+ ].filter(Boolean);
7885
+ appendSessionPolicyFlags(commandParts, options);
7886
+ commandParts.push(`--relay-url ${relayUrl} --wait-relay --prompt-code`);
7887
+ const command = commandParts.join(" ");
7840
7888
  return appendPaymasterMode(command, paymasterMode);
7841
7889
  }
7842
7890
  function buildWalletListRecommendedCommand() {
@@ -7845,6 +7893,9 @@ function buildWalletListRecommendedCommand() {
7845
7893
  function buildWalletStatusRecommendedCommand(walletName) {
7846
7894
  return `zk-agent wallet status --name ${walletName}`;
7847
7895
  }
7896
+ function buildWalletSignerShowRecommendedCommand(walletName) {
7897
+ return `zk-agent wallet signer show --name ${walletName}`;
7898
+ }
7848
7899
  function buildWalletSignerAttachRecommendedCommand(walletName, privateKeyRef = "<hex>") {
7849
7900
  return `zk-agent wallet signer attach --name ${walletName} --private-key ${privateKeyRef}`;
7850
7901
  }
@@ -7901,8 +7952,11 @@ function buildDiscoveryRecommendedCommands(input) {
7901
7952
  function buildWalletReapproveRecommendedCommand(walletName) {
7902
7953
  return `zk-agent wallet reapprove --name ${walletName} --await-local`;
7903
7954
  }
7904
- function buildWalletReapproveRemoteRecommendedCommand(walletName, relayUrl = "<url>") {
7905
- return `zk-agent wallet reapprove --name ${walletName} --relay-url ${relayUrl} --wait-relay --prompt-code`;
7955
+ function buildWalletReapproveRemoteRecommendedCommand(walletName, relayUrl = "<url>", options) {
7956
+ const commandParts = [`zk-agent wallet reapprove --name ${walletName}`];
7957
+ appendSessionPolicyFlags(commandParts, options);
7958
+ commandParts.push(`--relay-url ${relayUrl} --wait-relay --prompt-code`);
7959
+ return commandParts.join(" ");
7906
7960
  }
7907
7961
  function buildWalletNextRecommendedCommand(walletName) {
7908
7962
  return `zk-agent wallet next --name ${walletName}`;
@@ -7929,6 +7983,12 @@ function buildWorkflowPayRecommendedCommand(walletName, paymasterMode) {
7929
7983
  const command = `zk-agent workflow pay --wallet ${walletName} --to <address> --amount <amount>`;
7930
7984
  return appendPaymasterMode(command, paymasterMode);
7931
7985
  }
7986
+ function buildWorkflowFundRecommendedCommand(walletName) {
7987
+ return `zk-agent workflow fund --wallet ${walletName}`;
7988
+ }
7989
+ function buildWorkflowFundRunRecommendedCommand(walletName) {
7990
+ return `zk-agent workflow fund --wallet ${walletName} --amount <amount> --execute`;
7991
+ }
7932
7992
  function buildWorkflowShowRecommendedCommand(requestId) {
7933
7993
  return `zk-agent workflow show --request-id ${requestId}`;
7934
7994
  }
@@ -10066,18 +10126,109 @@ function createPlannedCommands() {
10066
10126
 
10067
10127
  // src/commands/setup.ts
10068
10128
  import { Command as Command2 } from "commander";
10129
+
10130
+ // src/lib/onboarding-summary.ts
10131
+ function buildOnboardingSummary(input) {
10132
+ return {
10133
+ stage: input.stage,
10134
+ baseline: "local-first",
10135
+ localOnly: input.localOnly,
10136
+ configExists: input.configExists,
10137
+ walletExists: input.walletExists ?? null,
10138
+ approvalReady: input.approvalReady ?? null,
10139
+ localExecutionKeyStored: input.localExecutionKeyStored ?? null,
10140
+ defaultChain: input.defaultChain ?? null,
10141
+ connectorUrl: input.connectorUrl ?? null,
10142
+ relayUrl: input.relayUrl ?? null,
10143
+ nextAction: input.nextAction ?? null,
10144
+ notes: [...input.notes ?? []]
10145
+ };
10146
+ }
10147
+ function onboardingSummaryLines(summary) {
10148
+ return [
10149
+ ["baseline", summary.baseline],
10150
+ ["local only", summary.localOnly ? "yes" : "no"]
10151
+ ];
10152
+ }
10153
+
10154
+ // src/lib/onboarding-paths.ts
10155
+ function formatRecommendedPath(commands) {
10156
+ return commands.join(" -> ");
10157
+ }
10158
+ function recommendedPathLines(paths) {
10159
+ if (!paths) return [];
10160
+ return [
10161
+ ["path (local)", formatRecommendedPath(paths.local)],
10162
+ ...paths.remoteBrowser?.length ? [["path (remote-browser)", formatRecommendedPath(paths.remoteBrowser)]] : []
10163
+ ];
10164
+ }
10165
+ function buildSetupRecommendedPaths(relayUrl = "<url>", paymasterMode) {
10166
+ const next = buildTopLevelNextRecommendedCommand(void 0, paymasterMode);
10167
+ return {
10168
+ local: [
10169
+ "zk-agent setup",
10170
+ next,
10171
+ buildWalletCreateRecommendedCommand(paymasterMode),
10172
+ next
10173
+ ],
10174
+ remoteBrowser: [
10175
+ "zk-agent setup",
10176
+ next,
10177
+ buildRelayInspectRecommendedCommand(relayUrl),
10178
+ buildWalletCreateRemoteRecommendedCommand(relayUrl, paymasterMode),
10179
+ next
10180
+ ]
10181
+ };
10182
+ }
10183
+ function buildWalletBootstrapRecommendedPaths(relayUrl = "<url>", paymasterMode, walletName = "main") {
10184
+ const next = buildTopLevelNextRecommendedCommand(void 0, paymasterMode);
10185
+ return {
10186
+ local: [buildWalletCreateRecommendedCommand(paymasterMode), next],
10187
+ remoteBrowser: [
10188
+ buildRelayInspectRecommendedCommand(relayUrl),
10189
+ buildWalletCreateRemoteRecommendedCommand(relayUrl, paymasterMode, walletName),
10190
+ next
10191
+ ]
10192
+ };
10193
+ }
10194
+ function buildWalletReapprovalRecommendedPaths(walletName, relayUrl = "<url>", paymasterMode) {
10195
+ const next = buildTopLevelNextRecommendedCommand(void 0, paymasterMode);
10196
+ return {
10197
+ local: [buildWalletReapproveRecommendedCommand(walletName), next],
10198
+ remoteBrowser: [
10199
+ buildRelayInspectRecommendedCommand(relayUrl),
10200
+ buildWalletReapproveRemoteRecommendedCommand(walletName, relayUrl),
10201
+ next
10202
+ ]
10203
+ };
10204
+ }
10205
+ function buildSignerRecoveryRecommendedPaths(walletName, paymasterMode) {
10206
+ return {
10207
+ local: [
10208
+ buildWalletSignerAttachRecommendedCommand(walletName),
10209
+ buildTopLevelNextRecommendedCommand(void 0, paymasterMode)
10210
+ ]
10211
+ };
10212
+ }
10213
+
10214
+ // src/commands/setup.ts
10069
10215
  function buildSetupHelpText() {
10070
10216
  return [
10071
10217
  "",
10072
10218
  "What setup does:",
10073
10219
  " Writes the local default chain and connector URL used by the first-run path.",
10074
10220
  "",
10221
+ "Validated first-run baseline:",
10222
+ " Default chain: zksync-sepolia",
10223
+ " Connector URL: http://localhost:4444",
10224
+ " Override --default-chain or --connector-url only when you intentionally deviate from that path.",
10225
+ "",
10075
10226
  "After setup, stay on the canonical local-first path:",
10076
10227
  " zk-agent next",
10077
10228
  " zk-agent wallet create --await-local",
10078
10229
  " zk-agent next",
10079
10230
  "",
10080
- "If the browser is not colocated with this terminal, switch at the wallet step:",
10231
+ "Remote-browser variant of the same path:",
10081
10232
  " zk-agent relay inspect --relay-url <url>",
10082
10233
  " zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
10083
10234
  " zk-agent next",
@@ -10088,7 +10239,7 @@ function buildSetupHelpText() {
10088
10239
  ].join("\n");
10089
10240
  }
10090
10241
  function createInitCommand() {
10091
- return new Command2("init").alias("setup").description("Initialize local zk-agent configuration for the default operator path").addHelpText("after", buildSetupHelpText()).option("--default-chain <chain>", "Default chain key", "zksync-era").option("--connector-url <url>", "Connector UI base URL", "http://localhost:4444").option("--force", "Overwrite an existing config", false).action(async (options) => {
10242
+ return new Command2("init").alias("setup").description("Initialize local zk-agent configuration for the validated first-run operator path").addHelpText("after", buildSetupHelpText()).option("--default-chain <chain>", "Default chain key", "zksync-sepolia").option("--connector-url <url>", "Connector UI base URL", "http://localhost:4444").option("--force", "Overwrite an existing config", false).action(async (options) => {
10092
10243
  const recommendedCommands = {
10093
10244
  next: buildTopLevelNextRecommendedCommand(),
10094
10245
  inspectDefaults: buildDefaultsRecommendedCommand(),
@@ -10097,13 +10248,28 @@ function createInitCommand() {
10097
10248
  createWalletRemote: buildWalletCreateRemoteRecommendedCommand(),
10098
10249
  afterWalletApproval: buildTopLevelNextRecommendedCommand()
10099
10250
  };
10251
+ const recommendedPaths = buildSetupRecommendedPaths();
10100
10252
  const existing = await loadProjectConfig();
10101
10253
  if (existing && !options.force) {
10254
+ const onboardingSummary2 = buildOnboardingSummary({
10255
+ stage: "wallet-bootstrap",
10256
+ localOnly: true,
10257
+ configExists: true,
10258
+ defaultChain: existing.defaultChain,
10259
+ connectorUrl: existing.connectorUrl,
10260
+ nextAction: recommendedCommands.next,
10261
+ notes: [
10262
+ "Setup did not overwrite the existing local defaults.",
10263
+ "Run zk-agent next so the CLI can choose wallet bootstrap or workflow follow-up from the current local state."
10264
+ ]
10265
+ });
10102
10266
  printResult(
10103
10267
  [
10104
10268
  ["status", "Config already exists. Re-run with --force to overwrite."],
10269
+ ...onboardingSummaryLines(onboardingSummary2),
10105
10270
  ["default chain", existing.defaultChain],
10106
10271
  ["connector", existing.connectorUrl],
10272
+ ...recommendedPathLines(recommendedPaths),
10107
10273
  ["next", recommendedCommands.next],
10108
10274
  ["inspect defaults", recommendedCommands.inspectDefaults],
10109
10275
  ["create wallet (local)", recommendedCommands.createWallet],
@@ -10115,24 +10281,40 @@ function createInitCommand() {
10115
10281
  ok: true,
10116
10282
  message: "Config already exists. Re-run with --force to overwrite.",
10117
10283
  config: existing,
10284
+ onboardingSummary: onboardingSummary2,
10285
+ recommendedPaths,
10118
10286
  recommendedCommands
10119
10287
  }
10120
10288
  );
10121
10289
  return;
10122
10290
  }
10123
10291
  const config = {
10124
- defaultChain: options.defaultChain || "zksync-era",
10292
+ defaultChain: options.defaultChain || "zksync-sepolia",
10125
10293
  connectorUrl: options.connectorUrl || "http://localhost:4444",
10126
10294
  provider: "zksync-sso",
10127
10295
  createdAt: existing?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
10128
10296
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
10129
10297
  };
10130
10298
  await saveProjectConfig(config);
10299
+ const onboardingSummary = buildOnboardingSummary({
10300
+ stage: "wallet-bootstrap",
10301
+ localOnly: true,
10302
+ configExists: true,
10303
+ defaultChain: config.defaultChain,
10304
+ connectorUrl: config.connectorUrl,
10305
+ nextAction: recommendedCommands.next,
10306
+ notes: [
10307
+ "Setup only writes local defaults and does not inspect wallet state.",
10308
+ "Stay on zk-agent next so the product entrypoint can decide between wallet bootstrap and workflow guidance."
10309
+ ]
10310
+ });
10131
10311
  printResult(
10132
10312
  [
10133
10313
  ["status", "Config saved"],
10314
+ ...onboardingSummaryLines(onboardingSummary),
10134
10315
  ["default chain", config.defaultChain],
10135
10316
  ["connector", config.connectorUrl],
10317
+ ...recommendedPathLines(recommendedPaths),
10136
10318
  ["next", recommendedCommands.next],
10137
10319
  ["inspect defaults", recommendedCommands.inspectDefaults],
10138
10320
  ["create wallet (local)", recommendedCommands.createWallet],
@@ -10140,7 +10322,7 @@ function createInitCommand() {
10140
10322
  ["create wallet (remote)", recommendedCommands.createWalletRemote],
10141
10323
  ["after approval", recommendedCommands.afterWalletApproval]
10142
10324
  ],
10143
- { ok: true, config, recommendedCommands }
10325
+ { ok: true, config, onboardingSummary, recommendedPaths, recommendedCommands }
10144
10326
  );
10145
10327
  });
10146
10328
  }
@@ -10504,10 +10686,14 @@ function agentProfileLines(summary) {
10504
10686
  }
10505
10687
 
10506
10688
  // src/lib/wallet-next.ts
10507
- function buildWalletNextRecommendedCommands(walletName, summary) {
10689
+ function buildWalletNextRecommendedCommands(walletName, summary, paymasterMode) {
10508
10690
  return {
10509
10691
  discoverAssets: buildAssetsRecommendedCommand(walletName),
10510
10692
  discoverOwnedTokens: buildOwnedTokensRecommendedCommand(walletName),
10693
+ ...paymasterMode === "approval-based" ? {
10694
+ discoverPaymasterTokens: buildPaymasterFeeTokensRecommendedCommand(summary.chain),
10695
+ inspectPaymasterToken: buildPaymasterFeeTokenResolveRecommendedCommand(summary.chain)
10696
+ } : {},
10511
10697
  discoverTokens: buildTokensRecommendedCommand(summary.chain),
10512
10698
  inspectToken: buildResolveTokenRecommendedCommand(summary.chain),
10513
10699
  walletStatus: buildWalletStatusRecommendedCommand(walletName),
@@ -10620,28 +10806,51 @@ function buildSetupCommand() {
10620
10806
  function buildTopLevelNextRecommendedCommand2(requestId) {
10621
10807
  return requestId ? `zk-agent next --request-id ${requestId}` : "zk-agent next";
10622
10808
  }
10809
+ function buildTopLevelWorkflowSummary(result, nextCommand) {
10810
+ return {
10811
+ status: result.status,
10812
+ readyForGoal: result.readyForGoal,
10813
+ nextCommand,
10814
+ blockingActionIds: result.blockingActionIds,
10815
+ fundingProgress: result.fundingProgress ? {
10816
+ kind: result.fundingProgress.kind,
10817
+ txHash: result.fundingProgress.txHash,
10818
+ status: result.fundingProgress.status,
10819
+ terminal: result.fundingProgress.terminal,
10820
+ finalized: result.fundingProgress.finalized
10821
+ } : void 0
10822
+ };
10823
+ }
10623
10824
  function appendPaymasterMode2(command, paymasterMode) {
10624
10825
  if (!paymasterMode) return command;
10625
10826
  return `${command} --paymaster-mode ${paymasterMode}`;
10626
10827
  }
10627
- function topLevelNextLines(scope, lines) {
10628
- return [["scope", scope], ...lines];
10828
+ function topLevelNextLines(scope, lines, onboardingSummary) {
10829
+ return [
10830
+ ["scope", scope],
10831
+ ...onboardingSummary ? onboardingSummaryLines(onboardingSummary) : [],
10832
+ ...lines
10833
+ ];
10629
10834
  }
10630
10835
  function buildNextHelpText() {
10631
10836
  return [
10632
10837
  "",
10633
10838
  "Use `next` as the product entrypoint:",
10839
+ " Stay on `next` until it points you at a wallet-specific or workflow-specific blocker.",
10840
+ "",
10634
10841
  " Fresh local-first routing:",
10635
10842
  " zk-agent setup",
10636
10843
  " zk-agent next",
10637
10844
  " zk-agent wallet create --await-local",
10638
10845
  " zk-agent next",
10639
10846
  "",
10640
- " If the browser is remote, switch at the wallet step instead of waiting for a local callback:",
10847
+ " Remote-browser variant of the same path:",
10641
10848
  " zk-agent relay inspect --relay-url <url>",
10642
10849
  " zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
10643
10850
  " zk-agent next",
10644
10851
  "",
10852
+ " If setup has not run yet, `next` will send you back to `zk-agent setup` first.",
10853
+ "",
10645
10854
  " Continue a stored workflow checkpoint:",
10646
10855
  " zk-agent next --request-id <id>",
10647
10856
  "",
@@ -10649,7 +10858,12 @@ function buildNextHelpText() {
10649
10858
  " zk-agent wallet next --name main",
10650
10859
  "",
10651
10860
  " Switch to the hosted remote-approval path only when the browser is not colocated:",
10652
- " zk-agent wallet --help",
10861
+ " zk-agent relay inspect --relay-url <url>",
10862
+ " zk-agent wallet create|reapprove --relay-url <url> --wait-relay --prompt-code",
10863
+ "",
10864
+ " Use wallet-layer commands when you already know the blocker is wallet-specific:",
10865
+ " zk-agent wallet next --name main",
10866
+ " zk-agent wallet status --name main",
10653
10867
  "",
10654
10868
  " Stay on the workflow layer only when you already have an explicit workflow or checkpoint:",
10655
10869
  " zk-agent workflow next --request-id <id>"
@@ -10740,6 +10954,7 @@ function createNextCommand(deps) {
10740
10954
  nextCommand: nextCommand2,
10741
10955
  agentProfile: workflowAgentProfile,
10742
10956
  agentFollowup: agentFollowup2,
10957
+ summary: buildTopLevelWorkflowSummary(result, nextCommand2),
10743
10958
  result,
10744
10959
  checkpoint: updatedCheckpoint,
10745
10960
  tokenDiscoverySummary: tokenDiscoverySummary2,
@@ -10755,20 +10970,35 @@ function createNextCommand(deps) {
10755
10970
  afterSetup: buildTopLevelNextRecommendedCommand2(),
10756
10971
  inspectDefaults: buildDefaultsRecommendedCommand()
10757
10972
  };
10973
+ const recommendedPaths2 = buildSetupRecommendedPaths("<url>", paymasterMode);
10974
+ const onboardingSummary2 = buildOnboardingSummary({
10975
+ stage: "setup",
10976
+ localOnly: true,
10977
+ configExists: false,
10978
+ walletExists: false,
10979
+ nextAction: recommendedCommands2.setup,
10980
+ notes: [
10981
+ "No local config was found, so setup is still the first required onboarding step.",
10982
+ "This scope is local-only and does not require live RPC reads."
10983
+ ]
10984
+ });
10758
10985
  printResult(
10759
10986
  topLevelNextLines("setup", [
10760
10987
  ["status", "No local config found"],
10761
10988
  ...agentProfileLines(agentProfile),
10762
10989
  ...agentFollowupLines(defaultAgentFollowup),
10990
+ ...recommendedPathLines(recommendedPaths2),
10763
10991
  ["next", recommendedCommands2.setup],
10764
10992
  ["after setup", recommendedCommands2.afterSetup],
10765
10993
  ["inspect defaults", recommendedCommands2.inspectDefaults]
10766
- ]),
10994
+ ], onboardingSummary2),
10767
10995
  {
10768
10996
  ok: true,
10769
10997
  scope: "setup",
10770
10998
  status: "action-required",
10771
10999
  nextCommand: recommendedCommands2.setup,
11000
+ onboardingSummary: onboardingSummary2,
11001
+ recommendedPaths: recommendedPaths2,
10772
11002
  agentProfile,
10773
11003
  agentFollowup: defaultAgentFollowup,
10774
11004
  recommendedCommands: recommendedCommands2
@@ -10791,6 +11021,24 @@ function createNextCommand(deps) {
10791
11021
  afterApproval: appendPaymasterMode2(buildTopLevelNextRecommendedCommand2(), paymasterMode),
10792
11022
  inspectDefaults: buildDefaultsRecommendedCommand()
10793
11023
  };
11024
+ const recommendedPaths2 = buildWalletBootstrapRecommendedPaths(
11025
+ "<url>",
11026
+ paymasterMode,
11027
+ walletName
11028
+ );
11029
+ const onboardingSummary2 = buildOnboardingSummary({
11030
+ stage: "wallet-bootstrap",
11031
+ localOnly: true,
11032
+ configExists: true,
11033
+ walletExists: false,
11034
+ defaultChain: config.defaultChain,
11035
+ connectorUrl: config.connectorUrl,
11036
+ nextAction: recommendedCommands2.createWallet,
11037
+ notes: [
11038
+ "Config exists, but no saved wallet record was found for this name yet.",
11039
+ "Use the remote approval fallback only when the browser is not colocated with this terminal."
11040
+ ]
11041
+ });
10794
11042
  printResult(
10795
11043
  topLevelNextLines("wallet-bootstrap", [
10796
11044
  ["status", `Wallet not found: ${walletName}`],
@@ -10798,18 +11046,21 @@ function createNextCommand(deps) {
10798
11046
  ["connector", config.connectorUrl],
10799
11047
  ...agentProfileLines(agentProfile),
10800
11048
  ...agentFollowupLines(defaultAgentFollowup),
11049
+ ...recommendedPathLines(recommendedPaths2),
10801
11050
  ["next", recommendedCommands2.createWallet],
10802
11051
  ["relay inspect", recommendedCommands2.relayInspect],
10803
11052
  ["remote fallback", recommendedCommands2.createWalletRemote],
10804
11053
  ["after approval", recommendedCommands2.afterApproval],
10805
11054
  ["inspect defaults", recommendedCommands2.inspectDefaults]
10806
- ]),
11055
+ ], onboardingSummary2),
10807
11056
  {
10808
11057
  ok: true,
10809
11058
  scope: "wallet-bootstrap",
10810
11059
  walletName,
10811
11060
  config,
10812
11061
  nextCommand: recommendedCommands2.createWallet,
11062
+ onboardingSummary: onboardingSummary2,
11063
+ recommendedPaths: recommendedPaths2,
10813
11064
  agentProfile,
10814
11065
  agentFollowup: defaultAgentFollowup,
10815
11066
  recommendedCommands: recommendedCommands2
@@ -10845,6 +11096,27 @@ function createNextCommand(deps) {
10845
11096
  paymasterMode
10846
11097
  );
10847
11098
  const nextCommand = summary.recommendedCommand || workflowPay;
11099
+ const onboardingSummary = buildOnboardingSummary({
11100
+ stage: inspection.approvalReady && inspection.localExecutionKeyStored ? "wallet-ready" : "wallet-recovery",
11101
+ localOnly: false,
11102
+ configExists: true,
11103
+ walletExists: true,
11104
+ approvalReady: inspection.approvalReady,
11105
+ localExecutionKeyStored: inspection.localExecutionKeyStored,
11106
+ defaultChain: config.defaultChain,
11107
+ connectorUrl: config.connectorUrl,
11108
+ nextAction: nextCommand,
11109
+ notes: !inspection.approvalReady ? [
11110
+ "Wallet metadata exists, but approved session metadata is still missing.",
11111
+ "Top-level next returns to live workflow guidance after wallet approval is restored."
11112
+ ] : !inspection.localExecutionKeyStored ? [
11113
+ "Approved session metadata exists, but no local execution signer is stored yet.",
11114
+ "Top-level next returns to live workflow guidance after the signer is attached."
11115
+ ] : [
11116
+ "Wallet approval and local signer state are present.",
11117
+ "Top-level next also inspects live deployment and balance state before recommending the workflow step."
11118
+ ]
11119
+ });
10848
11120
  const agentFollowup = buildAgentFollowup(agentProfile, {
10849
11121
  walletName: wallet.walletName,
10850
11122
  walletExists: true
@@ -10865,38 +11137,64 @@ function createNextCommand(deps) {
10865
11137
  nextAction: nextCommand,
10866
11138
  inspectDefaults: buildDefaultsRecommendedCommand()
10867
11139
  };
11140
+ const recoveryRecommendedCommands = !inspection.approvalReady ? {
11141
+ reapprove: buildWalletReapproveRecommendedCommand(wallet.walletName),
11142
+ relayInspect: buildRelayInspectRecommendedCommand(),
11143
+ reapproveRemote: buildWalletReapproveRemoteRecommendedCommand(wallet.walletName),
11144
+ afterRecovery: appendPaymasterMode2(buildTopLevelNextRecommendedCommand2(), paymasterMode)
11145
+ } : !inspection.localExecutionKeyStored ? {
11146
+ attachSigner: buildWalletSignerAttachRecommendedCommand(wallet.walletName),
11147
+ afterRecovery: appendPaymasterMode2(
11148
+ buildTopLevelNextRecommendedCommand2(),
11149
+ paymasterMode
11150
+ )
11151
+ } : {};
11152
+ const recommendedPaths = !inspection.approvalReady ? buildWalletReapprovalRecommendedPaths(wallet.walletName, "<url>", paymasterMode) : !inspection.localExecutionKeyStored ? buildSignerRecoveryRecommendedPaths(wallet.walletName, paymasterMode) : {
11153
+ local: [nextCommand]
11154
+ };
11155
+ const mergedRecommendedCommands = {
11156
+ ...recommendedCommands,
11157
+ ...recoveryRecommendedCommands
11158
+ };
10868
11159
  const tokenDiscoverySummary = buildWalletTokenDiscoverySummary({
10869
11160
  walletName: wallet.walletName,
10870
11161
  chain: wallet.chain,
10871
11162
  nextAction: nextCommand,
10872
11163
  paymasterMode,
10873
- recommendedCommands
11164
+ recommendedCommands: mergedRecommendedCommands
10874
11165
  });
10875
11166
  printResult(
10876
11167
  topLevelNextLines("wallet", [
10877
11168
  ...walletNextLines(summary),
10878
11169
  ...agentProfileLines(agentProfile),
10879
11170
  ...agentFollowupLines(agentFollowup),
11171
+ ...recommendedPathLines(recommendedPaths),
10880
11172
  ...summary.recommendedCommand ? [] : [["next", workflowPay]],
10881
- ["discover assets", recommendedCommands.discoverAssets],
10882
- ["discover owned tokens", recommendedCommands.discoverOwnedTokens],
10883
- ...recommendedCommands.discoverPaymasterTokens ? [["discover paymaster tokens", recommendedCommands.discoverPaymasterTokens]] : [],
10884
- ["discover tokens", recommendedCommands.discoverTokens],
10885
- ...recommendedCommands.inspectPaymasterToken ? [["inspect paymaster token", recommendedCommands.inspectPaymasterToken]] : [],
10886
- ["inspect token", recommendedCommands.inspectToken],
10887
- ["inspect defaults", recommendedCommands.inspectDefaults]
10888
- ]),
11173
+ ...mergedRecommendedCommands.reapprove ? [["reapprove", mergedRecommendedCommands.reapprove]] : [],
11174
+ ...mergedRecommendedCommands.attachSigner ? [["attach signer", mergedRecommendedCommands.attachSigner]] : [],
11175
+ ...mergedRecommendedCommands.relayInspect ? [["relay inspect", mergedRecommendedCommands.relayInspect]] : [],
11176
+ ...mergedRecommendedCommands.reapproveRemote ? [["remote fallback", mergedRecommendedCommands.reapproveRemote]] : [],
11177
+ ["discover assets", mergedRecommendedCommands.discoverAssets],
11178
+ ["discover owned tokens", mergedRecommendedCommands.discoverOwnedTokens],
11179
+ ...mergedRecommendedCommands.discoverPaymasterTokens ? [["discover paymaster tokens", mergedRecommendedCommands.discoverPaymasterTokens]] : [],
11180
+ ["discover tokens", mergedRecommendedCommands.discoverTokens],
11181
+ ...mergedRecommendedCommands.inspectPaymasterToken ? [["inspect paymaster token", mergedRecommendedCommands.inspectPaymasterToken]] : [],
11182
+ ["inspect token", mergedRecommendedCommands.inspectToken],
11183
+ ["inspect defaults", mergedRecommendedCommands.inspectDefaults]
11184
+ ], onboardingSummary),
10889
11185
  {
10890
11186
  ok: true,
10891
11187
  scope: "wallet",
10892
11188
  walletName: wallet.walletName,
11189
+ onboardingSummary,
11190
+ recommendedPaths,
10893
11191
  agentProfile,
10894
11192
  agentFollowup,
10895
11193
  inspection,
10896
11194
  summary,
10897
11195
  nextCommand,
10898
11196
  tokenDiscoverySummary,
10899
- recommendedCommands
11197
+ recommendedCommands: mergedRecommendedCommands
10900
11198
  }
10901
11199
  );
10902
11200
  });
@@ -10908,8 +11206,431 @@ function parsePaymasterMode(value) {
10908
11206
  throw new Error(`Unsupported paymaster mode: ${value}`);
10909
11207
  }
10910
11208
 
10911
- // src/commands/agent.ts
11209
+ // src/commands/doctor.ts
10912
11210
  import { Command as Command4 } from "commander";
11211
+ function buildDoctorHelpText() {
11212
+ return [
11213
+ "",
11214
+ "Use `doctor` when local state is unclear:",
11215
+ " zk-agent doctor",
11216
+ " zk-agent doctor --wallet main",
11217
+ " zk-agent doctor --wallet main --relay-url https://relay.example.com",
11218
+ "",
11219
+ "Default behavior:",
11220
+ " Inspects saved config, local wallet approval metadata, local signer state,",
11221
+ " and the shortest next command without requiring live RPC reads.",
11222
+ " Run this before guessing whether the blocker is setup, wallet approval, or local signer state.",
11223
+ "",
11224
+ "Remote-browser variant:",
11225
+ " Pass --relay-url when you want the remote approval fallback commands",
11226
+ " to use a concrete relay URL instead of a placeholder."
11227
+ ].join("\n");
11228
+ }
11229
+ function summarizeLocalWalletState(wallet) {
11230
+ const localExecutionPrivateKey = resolveLocalExecutionPrivateKey(wallet);
11231
+ return {
11232
+ exists: true,
11233
+ walletName: wallet.walletName,
11234
+ walletAddress: wallet.walletAddress,
11235
+ chain: wallet.chain,
11236
+ chainId: wallet.chainId,
11237
+ accountKind: wallet.accountKind || wallet.sessionPayload?.account?.kind || "smart-account",
11238
+ smartAccountProfileId: wallet.smartAccountProfileId || null,
11239
+ syncedAt: wallet.syncedAt || null,
11240
+ approvalReady: Boolean(wallet.sessionPayload),
11241
+ localExecutionKeyStored: Boolean(localExecutionPrivateKey),
11242
+ legacySessionKeyStored: Boolean(wallet.sessionPayload?.sessionPrivateKey),
11243
+ signerType: wallet.localExecutionAuthority?.signerType || wallet.sessionPayload?.account?.signerType || null,
11244
+ signerAddress: wallet.localExecutionAuthority?.signerAddress || deriveLocalExecutionSignerAddress(localExecutionPrivateKey) || null,
11245
+ signerSource: wallet.localExecutionAuthority?.source || (wallet.sessionPayload?.sessionPrivateKey ? "legacy-session-payload" : null)
11246
+ };
11247
+ }
11248
+ function buildSetupRecommendedCommands() {
11249
+ return {
11250
+ setup: "zk-agent setup",
11251
+ next: buildTopLevelNextRecommendedCommand(),
11252
+ inspectDefaults: buildDefaultsRecommendedCommand()
11253
+ };
11254
+ }
11255
+ function buildWalletBootstrapRecommendedCommands(walletName, relayUrl) {
11256
+ return {
11257
+ next: buildTopLevelNextRecommendedCommand(),
11258
+ inspectDefaults: buildDefaultsRecommendedCommand(),
11259
+ createWallet: buildWalletCreateRecommendedCommand(),
11260
+ relayInspect: buildRelayInspectRecommendedCommand(relayUrl),
11261
+ createWalletRemote: buildWalletCreateRemoteRecommendedCommand(relayUrl, void 0, walletName)
11262
+ };
11263
+ }
11264
+ function buildWalletRecoveryRecommendedCommands(wallet, relayUrl) {
11265
+ const shared = {
11266
+ next: buildTopLevelNextRecommendedCommand(),
11267
+ walletStatus: buildWalletStatusRecommendedCommand(wallet.walletName),
11268
+ walletNext: buildWalletNextRecommendedCommand(wallet.walletName),
11269
+ signerShow: buildWalletSignerShowRecommendedCommand(wallet.walletName),
11270
+ relayInspect: buildRelayInspectRecommendedCommand(relayUrl),
11271
+ reapproveRemote: buildWalletReapproveRemoteRecommendedCommand(wallet.walletName, relayUrl)
11272
+ };
11273
+ if (!wallet.approvalReady) {
11274
+ return {
11275
+ ...shared,
11276
+ reapprove: buildWalletReapproveRecommendedCommand(wallet.walletName)
11277
+ };
11278
+ }
11279
+ return {
11280
+ ...shared,
11281
+ attachSigner: buildWalletSignerAttachRecommendedCommand(wallet.walletName),
11282
+ reapprove: buildWalletReapproveRecommendedCommand(wallet.walletName)
11283
+ };
11284
+ }
11285
+ function buildWalletReadyRecommendedCommands(wallet) {
11286
+ return {
11287
+ next: buildTopLevelNextRecommendedCommand(),
11288
+ walletStatus: buildWalletStatusRecommendedCommand(wallet.walletName),
11289
+ walletNext: buildWalletNextRecommendedCommand(wallet.walletName),
11290
+ workflowPay: buildWorkflowPayRecommendedCommand(wallet.walletName),
11291
+ inspectDefaults: buildDefaultsRecommendedCommand()
11292
+ };
11293
+ }
11294
+ function buildDoctorResult(options) {
11295
+ if (!options.config) {
11296
+ const recommendedCommands2 = buildSetupRecommendedCommands();
11297
+ const onboardingSummary2 = buildOnboardingSummary({
11298
+ stage: "setup",
11299
+ localOnly: true,
11300
+ configExists: false,
11301
+ walletExists: Boolean(options.wallet),
11302
+ approvalReady: options.wallet?.approvalReady ?? null,
11303
+ localExecutionKeyStored: options.wallet?.localExecutionKeyStored ?? null,
11304
+ relayUrl: options.relayUrl || null,
11305
+ nextAction: recommendedCommands2.setup,
11306
+ notes: [
11307
+ "Local config is missing, so the canonical operator path should start with setup.",
11308
+ "Doctor is local-only by default and does not require live RPC reads."
11309
+ ]
11310
+ });
11311
+ return {
11312
+ scope: "setup",
11313
+ nextAction: recommendedCommands2.setup,
11314
+ recommendedPaths: buildSetupRecommendedPaths(options.relayUrl),
11315
+ onboardingSummary: onboardingSummary2,
11316
+ summary: {
11317
+ stage: "setup",
11318
+ configExists: false,
11319
+ walletExists: Boolean(options.wallet),
11320
+ approvalReady: options.wallet?.approvalReady ?? null,
11321
+ localExecutionKeyStored: options.wallet?.localExecutionKeyStored ?? null,
11322
+ relayUrl: options.relayUrl || null,
11323
+ nextAction: recommendedCommands2.setup,
11324
+ localOnly: true,
11325
+ notes: [
11326
+ "Local config is missing, so the canonical operator path should start with setup.",
11327
+ "Doctor is local-only by default and does not require live RPC reads."
11328
+ ]
11329
+ },
11330
+ recommendedCommands: recommendedCommands2
11331
+ };
11332
+ }
11333
+ if (!options.wallet) {
11334
+ const recommendedCommands2 = buildWalletBootstrapRecommendedCommands(
11335
+ options.walletName,
11336
+ options.relayUrl
11337
+ );
11338
+ const onboardingSummary2 = buildOnboardingSummary({
11339
+ stage: "wallet-bootstrap",
11340
+ localOnly: true,
11341
+ configExists: true,
11342
+ walletExists: false,
11343
+ defaultChain: options.config.defaultChain,
11344
+ connectorUrl: options.config.connectorUrl,
11345
+ relayUrl: options.relayUrl || null,
11346
+ nextAction: recommendedCommands2.createWallet,
11347
+ notes: [
11348
+ "Local config exists, but no saved wallet record was found for this name yet.",
11349
+ "Use the remote relay path only when the browser is not colocated with this terminal."
11350
+ ]
11351
+ });
11352
+ return {
11353
+ scope: "wallet-bootstrap",
11354
+ nextAction: recommendedCommands2.createWallet,
11355
+ recommendedPaths: buildWalletBootstrapRecommendedPaths(options.relayUrl, void 0, options.walletName),
11356
+ onboardingSummary: onboardingSummary2,
11357
+ summary: {
11358
+ stage: "wallet-bootstrap",
11359
+ configExists: true,
11360
+ walletExists: false,
11361
+ approvalReady: null,
11362
+ localExecutionKeyStored: null,
11363
+ relayUrl: options.relayUrl || null,
11364
+ nextAction: recommendedCommands2.createWallet,
11365
+ localOnly: true,
11366
+ notes: [
11367
+ "Local config exists, but no saved wallet record was found for this name yet.",
11368
+ "Use the remote relay path only when the browser is not colocated with this terminal."
11369
+ ]
11370
+ },
11371
+ recommendedCommands: recommendedCommands2
11372
+ };
11373
+ }
11374
+ if (!options.wallet.approvalReady) {
11375
+ const recommendedCommands2 = buildWalletRecoveryRecommendedCommands(
11376
+ options.wallet,
11377
+ options.relayUrl
11378
+ );
11379
+ const onboardingSummary2 = buildOnboardingSummary({
11380
+ stage: "wallet-recovery",
11381
+ localOnly: true,
11382
+ configExists: true,
11383
+ walletExists: true,
11384
+ approvalReady: false,
11385
+ localExecutionKeyStored: options.wallet.localExecutionKeyStored,
11386
+ defaultChain: options.config.defaultChain,
11387
+ connectorUrl: options.config.connectorUrl,
11388
+ relayUrl: options.relayUrl || null,
11389
+ nextAction: recommendedCommands2.reapprove,
11390
+ notes: [
11391
+ "A local wallet record exists, but approved session metadata is missing.",
11392
+ "Use the remote reapproval path only when the browser cannot return directly to this terminal."
11393
+ ]
11394
+ });
11395
+ return {
11396
+ scope: "wallet-recovery",
11397
+ nextAction: recommendedCommands2.reapprove,
11398
+ recommendedPaths: buildWalletReapprovalRecommendedPaths(
11399
+ options.wallet.walletName,
11400
+ options.relayUrl
11401
+ ),
11402
+ onboardingSummary: onboardingSummary2,
11403
+ summary: {
11404
+ stage: "wallet-recovery",
11405
+ configExists: true,
11406
+ walletExists: true,
11407
+ approvalReady: false,
11408
+ localExecutionKeyStored: options.wallet.localExecutionKeyStored,
11409
+ relayUrl: options.relayUrl || null,
11410
+ nextAction: recommendedCommands2.reapprove,
11411
+ localOnly: true,
11412
+ notes: [
11413
+ "A local wallet record exists, but approved session metadata is missing.",
11414
+ "Use the remote reapproval path only when the browser cannot return directly to this terminal."
11415
+ ]
11416
+ },
11417
+ recommendedCommands: recommendedCommands2
11418
+ };
11419
+ }
11420
+ if (!options.wallet.localExecutionKeyStored) {
11421
+ const attachSigner = buildWalletSignerAttachRecommendedCommand(options.wallet.walletName);
11422
+ const recommendedCommands2 = {
11423
+ ...buildWalletRecoveryRecommendedCommands(options.wallet, options.relayUrl),
11424
+ attachSigner
11425
+ };
11426
+ const onboardingSummary2 = buildOnboardingSummary({
11427
+ stage: "wallet-recovery",
11428
+ localOnly: true,
11429
+ configExists: true,
11430
+ walletExists: true,
11431
+ approvalReady: true,
11432
+ localExecutionKeyStored: false,
11433
+ defaultChain: options.config.defaultChain,
11434
+ connectorUrl: options.config.connectorUrl,
11435
+ relayUrl: options.relayUrl || null,
11436
+ nextAction: attachSigner,
11437
+ notes: [
11438
+ "Approved session metadata exists, but no local execution signer is stored yet.",
11439
+ "Doctor is local-only: it confirms stored signer state, not live chain deployment or gas balance."
11440
+ ]
11441
+ });
11442
+ return {
11443
+ scope: "wallet-recovery",
11444
+ nextAction: attachSigner,
11445
+ recommendedPaths: buildSignerRecoveryRecommendedPaths(options.wallet.walletName),
11446
+ onboardingSummary: onboardingSummary2,
11447
+ summary: {
11448
+ stage: "wallet-recovery",
11449
+ configExists: true,
11450
+ walletExists: true,
11451
+ approvalReady: true,
11452
+ localExecutionKeyStored: false,
11453
+ relayUrl: options.relayUrl || null,
11454
+ nextAction: attachSigner,
11455
+ localOnly: true,
11456
+ notes: [
11457
+ "Approved session metadata exists, but no local execution signer is stored yet.",
11458
+ "Doctor is local-only: it confirms stored signer state, not live chain deployment or gas balance."
11459
+ ]
11460
+ },
11461
+ recommendedCommands: recommendedCommands2
11462
+ };
11463
+ }
11464
+ const recommendedCommands = buildWalletReadyRecommendedCommands(options.wallet);
11465
+ const onboardingSummary = buildOnboardingSummary({
11466
+ stage: "wallet-ready",
11467
+ localOnly: true,
11468
+ configExists: true,
11469
+ walletExists: true,
11470
+ approvalReady: true,
11471
+ localExecutionKeyStored: true,
11472
+ defaultChain: options.config.defaultChain,
11473
+ connectorUrl: options.config.connectorUrl,
11474
+ relayUrl: options.relayUrl || null,
11475
+ nextAction: recommendedCommands.next,
11476
+ notes: [
11477
+ "Local config, approval metadata, and a local execution signer are all present.",
11478
+ "Run zk-agent next for the current shortest live path; doctor does not confirm RPC reachability, deployment state, or funding."
11479
+ ]
11480
+ });
11481
+ return {
11482
+ scope: "wallet-ready",
11483
+ nextAction: recommendedCommands.next,
11484
+ recommendedPaths: {
11485
+ local: [recommendedCommands.next]
11486
+ },
11487
+ onboardingSummary,
11488
+ summary: {
11489
+ stage: "wallet-ready",
11490
+ configExists: true,
11491
+ walletExists: true,
11492
+ approvalReady: true,
11493
+ localExecutionKeyStored: true,
11494
+ relayUrl: options.relayUrl || null,
11495
+ nextAction: recommendedCommands.next,
11496
+ localOnly: true,
11497
+ notes: [
11498
+ "Local config, approval metadata, and a local execution signer are all present.",
11499
+ "Run zk-agent next for the current shortest live path; doctor does not confirm RPC reachability, deployment state, or funding."
11500
+ ]
11501
+ },
11502
+ recommendedCommands
11503
+ };
11504
+ }
11505
+ function buildDoctorLines(input) {
11506
+ const lines = [
11507
+ ["scope", input.scope],
11508
+ ...onboardingSummaryLines(input.onboardingSummary),
11509
+ ["config", input.config ? "present" : "missing"]
11510
+ ];
11511
+ if (input.config) {
11512
+ lines.push(["default chain", input.config.defaultChain]);
11513
+ lines.push(["connector", input.config.connectorUrl]);
11514
+ }
11515
+ lines.push(["wallet", input.walletName]);
11516
+ lines.push(["wallet record", input.wallet ? "present" : "missing"]);
11517
+ if (input.wallet) {
11518
+ lines.push(["address", input.wallet.walletAddress]);
11519
+ lines.push(["account", input.wallet.accountKind]);
11520
+ lines.push(["chain", `${input.wallet.chain} (${input.wallet.chainId})`]);
11521
+ lines.push(["approval", input.wallet.approvalReady ? "present" : "missing"]);
11522
+ lines.push(["local signer", input.wallet.localExecutionKeyStored ? "stored" : "missing"]);
11523
+ lines.push([
11524
+ "legacy payload mirror",
11525
+ input.wallet.legacySessionKeyStored ? "present" : "missing"
11526
+ ]);
11527
+ if (input.wallet.signerType) {
11528
+ lines.push(["signer type", input.wallet.signerType]);
11529
+ }
11530
+ if (input.wallet.signerAddress) {
11531
+ lines.push(["signer address", input.wallet.signerAddress]);
11532
+ }
11533
+ if (input.wallet.signerSource) {
11534
+ lines.push(["signer source", input.wallet.signerSource]);
11535
+ }
11536
+ if (input.wallet.smartAccountProfileId) {
11537
+ lines.push(["smart-account profile", input.wallet.smartAccountProfileId]);
11538
+ }
11539
+ if (input.wallet.syncedAt) {
11540
+ lines.push(["synced at", input.wallet.syncedAt]);
11541
+ }
11542
+ }
11543
+ lines.push(["next", input.nextAction]);
11544
+ lines.push(...recommendedPathLines(input.recommendedPaths));
11545
+ if (input.recommendedCommands.createWallet) {
11546
+ lines.push(["create wallet (local)", input.recommendedCommands.createWallet]);
11547
+ }
11548
+ if (input.recommendedCommands.reapprove) {
11549
+ lines.push(["reapprove", input.recommendedCommands.reapprove]);
11550
+ }
11551
+ if (input.recommendedCommands.attachSigner) {
11552
+ lines.push(["attach signer", input.recommendedCommands.attachSigner]);
11553
+ }
11554
+ if (input.recommendedCommands.workflowPay) {
11555
+ lines.push(["workflow pay", input.recommendedCommands.workflowPay]);
11556
+ }
11557
+ if (input.recommendedCommands.relayInspect) {
11558
+ lines.push(["relay inspect", input.recommendedCommands.relayInspect]);
11559
+ }
11560
+ if (input.recommendedCommands.createWalletRemote) {
11561
+ lines.push(["create wallet (remote)", input.recommendedCommands.createWalletRemote]);
11562
+ }
11563
+ if (input.recommendedCommands.reapproveRemote) {
11564
+ lines.push(["reapprove (remote)", input.recommendedCommands.reapproveRemote]);
11565
+ }
11566
+ for (const note of input.summary.notes) {
11567
+ lines.push(["note", note]);
11568
+ }
11569
+ return lines;
11570
+ }
11571
+ function createDoctorCommand() {
11572
+ return new Command4("doctor").description("Local-only onboarding and wallet-recovery diagnostic for the default operator path").addHelpText("after", buildDoctorHelpText()).option("--wallet <name>", "Wallet name", "main").option(
11573
+ "--relay-url <url>",
11574
+ "Optional relay URL used only to make remote approval fallback commands concrete"
11575
+ ).action(async (options) => {
11576
+ const walletName = options.wallet?.trim() || "main";
11577
+ const config = await loadProjectConfig();
11578
+ const walletRecord = await loadWalletSession(walletName);
11579
+ const wallet = walletRecord ? summarizeLocalWalletState(walletRecord) : null;
11580
+ const result = buildDoctorResult({
11581
+ walletName,
11582
+ relayUrl: options.relayUrl,
11583
+ wallet,
11584
+ config
11585
+ });
11586
+ const agentProfile = await loadAgentIdentitySummary(walletName);
11587
+ const agentFollowup = buildAgentFollowup(agentProfile, {
11588
+ walletName,
11589
+ walletExists: Boolean(wallet)
11590
+ });
11591
+ printResult(
11592
+ [
11593
+ ...buildDoctorLines({
11594
+ scope: result.scope,
11595
+ walletName,
11596
+ config,
11597
+ wallet,
11598
+ onboardingSummary: result.onboardingSummary,
11599
+ summary: result.summary,
11600
+ recommendedPaths: result.recommendedPaths,
11601
+ recommendedCommands: result.recommendedCommands,
11602
+ nextAction: result.nextAction
11603
+ }),
11604
+ ...agentProfileLines(agentProfile),
11605
+ ...agentFollowupLines(agentFollowup)
11606
+ ],
11607
+ {
11608
+ ok: true,
11609
+ scope: result.scope,
11610
+ walletName,
11611
+ config: config ? {
11612
+ exists: true,
11613
+ defaultChain: config.defaultChain,
11614
+ connectorUrl: config.connectorUrl,
11615
+ provider: config.provider
11616
+ } : {
11617
+ exists: false
11618
+ },
11619
+ wallet,
11620
+ onboardingSummary: result.onboardingSummary,
11621
+ summary: result.summary,
11622
+ agentProfile,
11623
+ agentFollowup,
11624
+ nextAction: result.nextAction,
11625
+ recommendedPaths: result.recommendedPaths,
11626
+ recommendedCommands: result.recommendedCommands
11627
+ }
11628
+ );
11629
+ });
11630
+ }
11631
+
11632
+ // src/commands/agent.ts
11633
+ import { Command as Command5 } from "commander";
10913
11634
  function collectRepeatedString(value, previous) {
10914
11635
  return [...previous, value];
10915
11636
  }
@@ -10994,7 +11715,7 @@ function buildAgentSummaryLines(options) {
10994
11715
  return lines;
10995
11716
  }
10996
11717
  function createAgentCommand() {
10997
- const agent = new Command4("agent").description(
11718
+ const agent = new Command5("agent").description(
10998
11719
  "Manage local agent identity metadata without assuming a zkSync-native onchain reputation standard"
10999
11720
  );
11000
11721
  agent.addHelpText(
@@ -11187,7 +11908,7 @@ function createAgentCommand() {
11187
11908
  }
11188
11909
 
11189
11910
  // src/commands/defaults.ts
11190
- import { Command as Command5 } from "commander";
11911
+ import { Command as Command6 } from "commander";
11191
11912
  function inferPrimaryDiscoveryChain(defaults) {
11192
11913
  return defaults.defaultSelections.paymaster.validatedDefault?.chain || defaults.defaultSelections.swap.validatedDefault?.chain || defaults.defaultSelections.bridge.validatedWithdraw?.fromChain || defaults.defaultSelections.bridge.validatedDeposit?.toChain || defaults.validated.feeTokenEraVm?.chain || defaults.builtinChains.find((chain) => chain.key === "zksync-sepolia")?.key || defaults.builtinChains[0]?.key || "zksync-sepolia";
11193
11914
  }
@@ -11735,7 +12456,7 @@ function buildDefaultsLines(input) {
11735
12456
  return lines;
11736
12457
  }
11737
12458
  function createDefaultsCommand() {
11738
- return new Command5("defaults").description("Show the machine-readable registry of supported, validated, experimental, and manually configured defaults").addHelpText(
12459
+ return new Command6("defaults").description("Show the machine-readable registry of supported, validated, experimental, and manually configured defaults").addHelpText(
11739
12460
  "after",
11740
12461
  [
11741
12462
  "",
@@ -11794,7 +12515,7 @@ function createDefaultsCommand() {
11794
12515
  }
11795
12516
 
11796
12517
  // src/commands/resolve-token.ts
11797
- import { Command as Command6 } from "commander";
12518
+ import { Command as Command7 } from "commander";
11798
12519
  function resolveResolveTokenCommandDeps(deps) {
11799
12520
  return {
11800
12521
  loadWallet: deps?.loadWallet ?? (async (walletName) => {
@@ -11852,7 +12573,7 @@ function buildResolveTokenDiscoverySummary(result) {
11852
12573
  }
11853
12574
  function createResolveTokenCommand(deps) {
11854
12575
  const resolvedDeps = resolveResolveTokenCommandDeps(deps);
11855
- return new Command6("resolve-token").description("Resolve a token symbol or address against the configured local-first token registry").addHelpText(
12576
+ return new Command7("resolve-token").description("Resolve a token symbol or address against the configured local-first token registry").addHelpText(
11856
12577
  "after",
11857
12578
  [
11858
12579
  "",
@@ -11985,8 +12706,135 @@ function normalizeSource(value) {
11985
12706
  );
11986
12707
  }
11987
12708
 
12709
+ // src/commands/suite.ts
12710
+ import { Command as Command8 } from "commander";
12711
+
12712
+ // src/lib/operator-suite.ts
12713
+ function buildOperatorSuitePayload(options = {}) {
12714
+ const walletName = options.walletName?.trim() || "main";
12715
+ const chain = options.chain?.trim() || "zksync-sepolia";
12716
+ const flagshipCommand = buildWorkflowPayRecommendedCommand(walletName);
12717
+ const inspectDefaults = buildDefaultsRecommendedCommand();
12718
+ const discoveryCommand = buildAssetsRecommendedCommand(walletName);
12719
+ const paymasterCommand = buildWorkflowPayRecommendedCommand(walletName, "approval-based");
12720
+ const fundingCommand = buildWorkflowFundRecommendedCommand(walletName);
12721
+ const flagship = {
12722
+ id: "flagship-pay",
12723
+ title: "Flagship Pay",
12724
+ goal: "Run the default zkSync-native native-send path through the workflow layer.",
12725
+ primaryCommand: flagshipCommand,
12726
+ supportingCommands: [
12727
+ "zk-agent next",
12728
+ "zk-agent wallet status --name main",
12729
+ inspectDefaults
12730
+ ],
12731
+ skillPath: "skills/zk-aa/SKILL.md"
12732
+ };
12733
+ const slices = [
12734
+ {
12735
+ id: "discovery-defaults",
12736
+ title: "Discovery / Defaults",
12737
+ goal: "Discover owned assets, tracked defaults, and symbol-first token resolution before acting.",
12738
+ primaryCommand: discoveryCommand,
12739
+ supportingCommands: [
12740
+ inspectDefaults,
12741
+ `zk-agent tokens --chain ${chain}`,
12742
+ buildResolveTokenRecommendedCommand(chain, "USDC")
12743
+ ],
12744
+ skillPath: "skills/zk-discovery/SKILL.md",
12745
+ smokeCommand: `pnpm smoke:discovery -- --wallet ${walletName}`
12746
+ },
12747
+ {
12748
+ id: "paymaster-readiness",
12749
+ title: "Paymaster Readiness",
12750
+ goal: "Stay on the approval-based flagship path and recover the exact fee-token/default metadata when needed.",
12751
+ primaryCommand: paymasterCommand,
12752
+ supportingCommands: [
12753
+ inspectDefaults,
12754
+ buildPaymasterFeeTokensRecommendedCommand(chain),
12755
+ buildPaymasterFeeTokenResolveRecommendedCommand(chain)
12756
+ ],
12757
+ skillPath: "skills/zk-paymaster/SKILL.md",
12758
+ smokeCommand: `pnpm smoke:paymaster-success -- --wallet ${walletName}`
12759
+ },
12760
+ {
12761
+ id: "funding-readiness",
12762
+ title: "Funding Readiness",
12763
+ goal: "Ask the workflow layer for the exact funding route before executing bridge/deposit follow-up.",
12764
+ primaryCommand: fundingCommand,
12765
+ supportingCommands: [
12766
+ buildWorkflowFundRunRecommendedCommand(walletName),
12767
+ `zk-agent fund --wallet ${walletName} --amount <amount>`,
12768
+ buildWorkflowStatusRecommendedCommand("<request-id>")
12769
+ ],
12770
+ skillPath: "skills/zk-funding/SKILL.md",
12771
+ smokeCommand: `pnpm smoke:funding-readiness -- --wallet ${walletName}`
12772
+ }
12773
+ ];
12774
+ return {
12775
+ ok: true,
12776
+ summary: {
12777
+ suiteId: "zk-agent-operator-suite",
12778
+ walletName,
12779
+ chain,
12780
+ flagshipId: flagship.id,
12781
+ postFlagshipSliceIds: slices.map((entry) => entry.id),
12782
+ nextAction: flagship.primaryCommand
12783
+ },
12784
+ flagship,
12785
+ slices,
12786
+ recommendedCommands: {
12787
+ suite: "zk-agent suite",
12788
+ flagship: flagshipCommand,
12789
+ discovery: discoveryCommand,
12790
+ paymaster: paymasterCommand,
12791
+ funding: fundingCommand,
12792
+ inspectDefaults
12793
+ }
12794
+ };
12795
+ }
12796
+ function operatorSuiteLines(payload) {
12797
+ const sliceLines = payload.slices.flatMap((entry) => [
12798
+ [entry.id, formatRecommendedPath([entry.primaryCommand, ...entry.supportingCommands])],
12799
+ [`${entry.id} skill`, entry.skillPath],
12800
+ ...entry.smokeCommand ? [[`${entry.id} smoke`, entry.smokeCommand]] : []
12801
+ ]);
12802
+ return [
12803
+ ["suite", payload.summary.suiteId],
12804
+ ["wallet", payload.summary.walletName],
12805
+ ["chain", payload.summary.chain],
12806
+ ["flagship", formatRecommendedPath([payload.flagship.primaryCommand, "zk-agent next"])],
12807
+ ...sliceLines,
12808
+ ["next action", payload.summary.nextAction]
12809
+ ];
12810
+ }
12811
+
12812
+ // src/commands/suite.ts
12813
+ function createSuiteCommand() {
12814
+ return new Command8("suite").description("Show the flagship and post-flagship zkSync-native operator suite").option("--wallet <name>", "Wallet name used in example commands", "main").option("--chain <chain>", "Chain key used in example commands", "zksync-sepolia").addHelpText(
12815
+ "after",
12816
+ [
12817
+ "",
12818
+ " Current operator suite:",
12819
+ " zk-agent workflow pay --wallet main --to <address> --amount <amount>",
12820
+ " zk-agent assets --wallet main",
12821
+ " zk-agent workflow fund --wallet main",
12822
+ " zk-agent workflow pay --wallet main --to <address> --amount <amount> --paymaster-mode approval-based",
12823
+ "",
12824
+ " Use `suite` when you want the flagship path plus the current",
12825
+ " post-flagship discovery/defaults, funding, and paymaster surfaces in one place."
12826
+ ].join("\n")
12827
+ ).action((options) => {
12828
+ const payload = buildOperatorSuitePayload({
12829
+ walletName: options.wallet,
12830
+ chain: options.chain
12831
+ });
12832
+ printResult(operatorSuiteLines(payload), payload);
12833
+ });
12834
+ }
12835
+
11988
12836
  // src/commands/tokens.ts
11989
- import { Command as Command7 } from "commander";
12837
+ import { Command as Command9 } from "commander";
11990
12838
  var provider2 = new ZkSyncWalletProvider();
11991
12839
  function resolveTokensCommandDeps(deps) {
11992
12840
  return {
@@ -12116,7 +12964,7 @@ function buildTokenDiscoverySummary(result) {
12116
12964
  }
12117
12965
  function createTokensCommand(deps) {
12118
12966
  const resolvedDeps = resolveTokensCommandDeps(deps);
12119
- return new Command7("tokens").description("List discoverable tokens from the configured local-first token registry, or inspect the owned ERC-20 registry subset for one wallet").addHelpText(
12967
+ return new Command9("tokens").description("List discoverable tokens from the configured local-first token registry, or inspect the owned ERC-20 registry subset for one wallet").addHelpText(
12120
12968
  "after",
12121
12969
  [
12122
12970
  "",
@@ -12321,7 +13169,7 @@ function normalizeRole2(value) {
12321
13169
  }
12322
13170
 
12323
13171
  // src/commands/relay.ts
12324
- import { Command as Command8 } from "commander";
13172
+ import { Command as Command10 } from "commander";
12325
13173
 
12326
13174
  // src/lib/relay.ts
12327
13175
  import { createServer } from "node:http";
@@ -12829,10 +13677,79 @@ async function startRelayServer(options) {
12829
13677
  }
12830
13678
 
12831
13679
  // src/commands/relay.ts
12832
- function buildRelayServeRecommendedCommands(relayUrl) {
13680
+ function buildRelayServeRecommendedCommands(options) {
13681
+ const commands = {
13682
+ inspectRelay: buildRelayInspectRecommendedCommand(options.relayUrl),
13683
+ createWallet: buildWalletCreateRemoteRecommendedCommand(options.relayUrl),
13684
+ reapproveWallet: buildWalletReapproveRemoteRecommendedCommand("main", options.relayUrl)
13685
+ };
13686
+ if (options.publicOriginLooksLocal) {
13687
+ return {
13688
+ ...commands,
13689
+ restartWithPublicOrigin: "zk-agent relay serve --public-origin https://relay.example.com"
13690
+ };
13691
+ }
13692
+ return commands;
13693
+ }
13694
+ function buildRelayInspectRecommendedCommands(options) {
13695
+ const commands = {};
13696
+ if (options.compatible) {
13697
+ commands.createWallet = buildWalletCreateRemoteRecommendedCommand(options.publicOrigin);
13698
+ commands.reapproveWallet = buildWalletReapproveRemoteRecommendedCommand(
13699
+ "main",
13700
+ options.publicOrigin
13701
+ );
13702
+ }
13703
+ if (options.publicOriginLooksLocal) {
13704
+ commands.restartWithPublicOrigin = "zk-agent relay serve --public-origin https://relay.example.com";
13705
+ }
13706
+ return commands;
13707
+ }
13708
+ function buildRelayApprovalPaths(options) {
13709
+ const inspectRelay = buildRelayInspectRecommendedCommand(options.relayUrl);
13710
+ const next = buildTopLevelNextRecommendedCommand();
13711
+ const maybeInspectRelay = options.includeInspectRelay ? [inspectRelay] : [];
13712
+ return {
13713
+ createWallet: [
13714
+ ...maybeInspectRelay,
13715
+ buildWalletCreateRemoteRecommendedCommand(options.relayUrl),
13716
+ next
13717
+ ],
13718
+ reapproveWallet: [
13719
+ ...maybeInspectRelay,
13720
+ buildWalletReapproveRemoteRecommendedCommand("main", options.relayUrl),
13721
+ next
13722
+ ]
13723
+ };
13724
+ }
13725
+ function relayApprovalPathLines(paths) {
13726
+ if (!paths) return [];
13727
+ return [
13728
+ ["path create wallet", formatRecommendedPath(paths.createWallet)],
13729
+ ["path reapprove wallet", formatRecommendedPath(paths.reapproveWallet)]
13730
+ ];
13731
+ }
13732
+ function buildRelayHostedReadinessSummary(options) {
13733
+ let status;
13734
+ if (!options.compatible) {
13735
+ status = "incompatible";
13736
+ } else if (options.publicOriginLooksLocal && options.connectorUiAvailable !== true) {
13737
+ status = "needs-public-origin-and-ui";
13738
+ } else if (options.publicOriginLooksLocal) {
13739
+ status = "needs-public-origin";
13740
+ } else if (options.connectorUiAvailable !== true) {
13741
+ status = "needs-connector-ui";
13742
+ } else {
13743
+ status = "ready";
13744
+ }
12833
13745
  return {
12834
- createWallet: `zk-agent wallet create --relay-url ${relayUrl} --wait-relay --prompt-code`,
12835
- reapproveWallet: `zk-agent wallet reapprove --name main --relay-url ${relayUrl} --wait-relay --prompt-code`
13746
+ status,
13747
+ compatible: options.compatible,
13748
+ hostedApprovalReady: options.hostedShareRedirectReady,
13749
+ publicOriginConfigured: options.publicOriginSource === "configured",
13750
+ publicOriginLooksLocal: options.publicOriginLooksLocal,
13751
+ connectorUiAvailable: options.connectorUiAvailable,
13752
+ singleHostFileState: options.deploymentSummary.singleHostFileState
12836
13753
  };
12837
13754
  }
12838
13755
  function buildAdvertisedRelayBases(publicOrigin) {
@@ -12841,6 +13758,24 @@ function buildAdvertisedRelayBases(publicOrigin) {
12841
13758
  statusApiBaseUrl: `${publicOrigin}/api/requests`
12842
13759
  };
12843
13760
  }
13761
+ function buildRelayApprovalEndpointSummary(options) {
13762
+ let status;
13763
+ if (options.publicOriginLooksLocal) {
13764
+ status = "local-public-origin";
13765
+ } else if (options.relayUrlMatchesPublicOrigin === false) {
13766
+ status = "hosted-public-origin-via-proxy";
13767
+ } else {
13768
+ status = "hosted-public-origin";
13769
+ }
13770
+ return {
13771
+ status,
13772
+ publicOriginConfigured: options.publicOriginSource === "configured",
13773
+ publicOriginLooksLocal: options.publicOriginLooksLocal,
13774
+ relayUrlMatchesPublicOrigin: options.relayUrlMatchesPublicOrigin,
13775
+ shareLinkBaseUrl: options.shareLinkBaseUrl,
13776
+ statusApiBaseUrl: options.statusApiBaseUrl
13777
+ };
13778
+ }
12844
13779
  function isRecord3(value) {
12845
13780
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
12846
13781
  }
@@ -13026,6 +13961,21 @@ function buildRelayInspectPayload(relayUrl, rawHealth) {
13026
13961
  deploymentScope,
13027
13962
  sameHostRestartPersists
13028
13963
  });
13964
+ const approvalEndpointSummary = buildRelayApprovalEndpointSummary({
13965
+ publicOriginSource,
13966
+ publicOriginLooksLocal,
13967
+ relayUrlMatchesPublicOrigin,
13968
+ shareLinkBaseUrl,
13969
+ statusApiBaseUrl
13970
+ });
13971
+ const hostedReadinessSummary = buildRelayHostedReadinessSummary({
13972
+ compatible,
13973
+ publicOriginSource,
13974
+ publicOriginLooksLocal,
13975
+ connectorUiAvailable,
13976
+ hostedShareRedirectReady,
13977
+ deploymentSummary
13978
+ });
13029
13979
  const notes = [
13030
13980
  ...relayHostedReadinessNotes({
13031
13981
  compatible,
@@ -13065,16 +14015,26 @@ function buildRelayInspectPayload(relayUrl, rawHealth) {
13065
14015
  relayUrlMatchesOrigin,
13066
14016
  relayUrlMatchesPublicOrigin,
13067
14017
  publicOriginLooksLocal,
14018
+ approvalEndpointSummary,
13068
14019
  connectorUiAvailable,
13069
14020
  hostedShareRedirectReady,
14021
+ hostedReadinessSummary,
13070
14022
  deploymentSummary,
13071
14023
  capabilities: health?.capabilities || [],
13072
- recommendedCommands: compatible ? buildRelayServeRecommendedCommands(publicOrigin) : {},
14024
+ recommendedCommands: buildRelayInspectRecommendedCommands({
14025
+ publicOrigin,
14026
+ compatible,
14027
+ publicOriginLooksLocal
14028
+ }),
14029
+ relayApprovalPaths: compatible ? buildRelayApprovalPaths({
14030
+ relayUrl: publicOrigin,
14031
+ includeInspectRelay: false
14032
+ }) : void 0,
13073
14033
  notes
13074
14034
  };
13075
14035
  }
13076
14036
  function createRelayCommand() {
13077
- const relay = new Command8("relay").description("Run the local connector relay prototype server");
14037
+ const relay = new Command10("relay").description("Run the local connector relay prototype server");
13078
14038
  relay.addHelpText(
13079
14039
  "after",
13080
14040
  [
@@ -13112,7 +14072,14 @@ function createRelayCommand() {
13112
14072
  const connectorUiAvailable = server.connectorUiAvailable;
13113
14073
  const hostedShareRedirectReady = connectorUiAvailable && !publicOriginLooksLocal;
13114
14074
  const { shareLinkBaseUrl, statusApiBaseUrl } = buildAdvertisedRelayBases(publicOrigin);
13115
- const recommendedCommands = buildRelayServeRecommendedCommands(publicOrigin);
14075
+ const recommendedCommands = buildRelayServeRecommendedCommands({
14076
+ relayUrl: publicOrigin,
14077
+ publicOriginLooksLocal
14078
+ });
14079
+ const relayApprovalPaths = buildRelayApprovalPaths({
14080
+ relayUrl: publicOrigin,
14081
+ includeInspectRelay: true
14082
+ });
13116
14083
  const deploymentSummary = buildRelayDeploymentSummary({
13117
14084
  origin: server.origin,
13118
14085
  publicOrigin,
@@ -13126,6 +14093,21 @@ function createRelayCommand() {
13126
14093
  deploymentScope: "single-host",
13127
14094
  sameHostRestartPersists: true
13128
14095
  });
14096
+ const hostedReadinessSummary = buildRelayHostedReadinessSummary({
14097
+ compatible: true,
14098
+ publicOriginSource,
14099
+ publicOriginLooksLocal,
14100
+ connectorUiAvailable,
14101
+ hostedShareRedirectReady,
14102
+ deploymentSummary
14103
+ });
14104
+ const approvalEndpointSummary = buildRelayApprovalEndpointSummary({
14105
+ publicOriginSource,
14106
+ publicOriginLooksLocal,
14107
+ relayUrlMatchesPublicOrigin: null,
14108
+ shareLinkBaseUrl,
14109
+ statusApiBaseUrl
14110
+ });
13129
14111
  const notes = relayHostedReadinessNotes({
13130
14112
  compatible: true,
13131
14113
  publicOrigin,
@@ -13144,6 +14126,8 @@ function createRelayCommand() {
13144
14126
  shareLinkBaseUrl,
13145
14127
  statusApiBaseUrl,
13146
14128
  publicOriginLooksLocal,
14129
+ approvalEndpointSummary,
14130
+ hostedReadinessSummary,
13147
14131
  deploymentSummary,
13148
14132
  port: server.port,
13149
14133
  healthUrl: `${server.origin}/health`,
@@ -13160,6 +14144,7 @@ function createRelayCommand() {
13160
14144
  ...connectorUiAvailable ? ["connector-ui"] : []
13161
14145
  ],
13162
14146
  recommendedCommands,
14147
+ relayApprovalPaths,
13163
14148
  notes
13164
14149
  };
13165
14150
  if (shouldJsonOutput()) {
@@ -13179,13 +14164,22 @@ function createRelayCommand() {
13179
14164
  );
13180
14165
  humanLine("share-link base", shareLinkBaseUrl);
13181
14166
  humanLine("status api base", statusApiBaseUrl);
14167
+ humanLine("approval endpoint", approvalEndpointSummary.status);
13182
14168
  humanLine("health", `${server.origin}/health`);
14169
+ humanLine("hosted readiness", hostedReadinessSummary.status);
13183
14170
  humanLine("hosted ready", hostedShareRedirectReady ? "yes" : "no");
13184
14171
  if (connectorUiAvailable !== null) {
13185
14172
  humanLine("connector ui", connectorUiAvailable ? "available" : "missing");
13186
14173
  }
14174
+ humanLine("inspect relay", recommendedCommands.inspectRelay);
13187
14175
  humanLine("create wallet", recommendedCommands.createWallet);
13188
14176
  humanLine("reapprove wallet", recommendedCommands.reapproveWallet);
14177
+ for (const [label, value] of relayApprovalPathLines(relayApprovalPaths)) {
14178
+ humanLine(label, value);
14179
+ }
14180
+ if (recommendedCommands.restartWithPublicOrigin) {
14181
+ humanLine("restart with public origin", recommendedCommands.restartWithPublicOrigin);
14182
+ }
13189
14183
  for (const note of notes) {
13190
14184
  humanLine("note", note);
13191
14185
  }
@@ -13247,6 +14241,8 @@ function createRelayCommand() {
13247
14241
  }
13248
14242
  humanLine("share-link base", payload.shareLinkBaseUrl);
13249
14243
  humanLine("status api base", payload.statusApiBaseUrl);
14244
+ humanLine("approval endpoint", payload.approvalEndpointSummary.status);
14245
+ humanLine("hosted readiness", payload.hostedReadinessSummary.status);
13250
14246
  if (payload.relayUrlMatchesOrigin !== null) {
13251
14247
  humanLine("relay url matches origin", payload.relayUrlMatchesOrigin ? "yes" : "no");
13252
14248
  }
@@ -13271,6 +14267,15 @@ function createRelayCommand() {
13271
14267
  if (payload.recommendedCommands.reapproveWallet) {
13272
14268
  humanLine("reapprove wallet", payload.recommendedCommands.reapproveWallet);
13273
14269
  }
14270
+ for (const [label, value] of relayApprovalPathLines(payload.relayApprovalPaths)) {
14271
+ humanLine(label, value);
14272
+ }
14273
+ }
14274
+ if (payload.recommendedCommands.restartWithPublicOrigin) {
14275
+ humanLine(
14276
+ "restart with public origin",
14277
+ payload.recommendedCommands.restartWithPublicOrigin
14278
+ );
13274
14279
  }
13275
14280
  for (const note of payload.notes) {
13276
14281
  humanLine("note", note);
@@ -13282,7 +14287,7 @@ function createRelayCommand() {
13282
14287
  // src/commands/wallet.ts
13283
14288
  import { createServer as createServer2 } from "node:http";
13284
14289
  import { createInterface } from "node:readline/promises";
13285
- import { Command as Command9 } from "commander";
14290
+ import { Command as Command11 } from "commander";
13286
14291
 
13287
14292
  // ../account-profiles/src/profiles.ts
13288
14293
  import fs8 from "node:fs";
@@ -15217,7 +16222,9 @@ async function buildRelayStatusFollowUp(options) {
15217
16222
  walletName: options.relay.request?.walletName,
15218
16223
  relayUrl: options.relayUrl,
15219
16224
  paymasterMode: options.relay.request?.requestedPaymasterMode,
15220
- accountKind: options.relay.request?.requestedAccountKind
16225
+ accountKind: options.relay.request?.requestedAccountKind,
16226
+ sessionPolicies: options.relay.request?.policies,
16227
+ requestCreatedAt: options.relay.request?.createdAt
15221
16228
  });
15222
16229
  }
15223
16230
  if (options.relay.approval_ready) {
@@ -15262,11 +16269,18 @@ async function buildRelayExpiredRecoveryCommands(options) {
15262
16269
  };
15263
16270
  }
15264
16271
  const existingWallet = await loadWalletSession(walletName);
15265
- const reissueRemoteApproval = existingWallet ? buildWalletReapproveRemoteRecommendedCommand(walletName, options.relayUrl) : buildWalletCreateRemoteRecommendedCommand(
16272
+ const reissueRemoteApproval = existingWallet ? buildWalletReapproveRemoteRecommendedCommand(walletName, options.relayUrl, {
16273
+ sessionPolicies: options.sessionPolicies,
16274
+ requestCreatedAt: options.requestCreatedAt
16275
+ }) : buildWalletCreateRemoteRecommendedCommand(
15266
16276
  options.relayUrl,
15267
16277
  options.paymasterMode,
15268
16278
  walletName,
15269
- options.accountKind
16279
+ options.accountKind,
16280
+ {
16281
+ sessionPolicies: options.sessionPolicies,
16282
+ requestCreatedAt: options.requestCreatedAt
16283
+ }
15270
16284
  );
15271
16285
  return {
15272
16286
  nextAction: reissueRemoteApproval,
@@ -15274,7 +16288,7 @@ async function buildRelayExpiredRecoveryCommands(options) {
15274
16288
  relayInspect,
15275
16289
  reissueRemoteApproval
15276
16290
  },
15277
- note: "Relay approval expired. Reissue the remote request. If the original request used scoped session flags, add those same policy flags again."
16291
+ note: "Relay approval expired. Reissue the remote request. The recovery command preserves any CLI-expressible session-policy flags from the expired request."
15278
16292
  };
15279
16293
  }
15280
16294
  function buildRelayApprovalTimeoutError(options) {
@@ -15318,7 +16332,9 @@ async function buildRelayApprovalExpiredError(options) {
15318
16332
  walletName: options.walletName,
15319
16333
  relayUrl: options.relayUrl,
15320
16334
  paymasterMode: options.paymasterMode,
15321
- accountKind: options.accountKind
16335
+ accountKind: options.accountKind,
16336
+ sessionPolicies: options.sessionPolicies,
16337
+ requestCreatedAt: options.requestCreatedAt
15322
16338
  });
15323
16339
  return new AgentError(
15324
16340
  "RELAY_APPROVAL_EXPIRED",
@@ -15565,7 +16581,9 @@ async function finalizePublishedRelayWalletRequest(options) {
15565
16581
  walletName: options.walletRequest.walletName,
15566
16582
  relayUrl: options.relayUrl,
15567
16583
  paymasterMode: options.walletRequest.requestedPaymasterMode,
15568
- accountKind: options.walletRequest.requestedAccountKind
16584
+ accountKind: options.walletRequest.requestedAccountKind,
16585
+ sessionPolicies: options.walletRequest.policies,
16586
+ requestCreatedAt: options.walletRequest.createdAt
15569
16587
  });
15570
16588
  }
15571
16589
  throw error;
@@ -15936,32 +16954,32 @@ async function printBuiltinSmartAccountProfiles() {
15936
16954
  }
15937
16955
  function createWalletCommand(deps) {
15938
16956
  const resolvedDeps = resolveWalletCommandDeps(deps);
15939
- const wallet = new Command9("wallet").description(
16957
+ const wallet = new Command11("wallet").description(
15940
16958
  "Create, inspect, and recover local-first wallet sessions"
15941
16959
  );
15942
- const request = new Command9("request").description("Inspect and finalize pending wallet requests");
15943
- const signer = new Command9("signer").description(
16960
+ const request = new Command11("request").description("Inspect and finalize pending wallet requests");
16961
+ const signer = new Command11("signer").description(
15944
16962
  "Inspect and manage the stored local execution signer for a wallet"
15945
16963
  );
15946
- const smartAccount = new Command9("smart-account").description(
16964
+ const smartAccount = new Command11("smart-account").description(
15947
16965
  "Predict and deploy zkSync smart-account contracts from a supplied artifact or built-in profile"
15948
16966
  );
15949
- const sedLite = new Command9("sed-lite").description(
16967
+ const sedLite = new Command11("sed-lite").description(
15950
16968
  "Inspect and manage the SED modular smart-account profile"
15951
16969
  );
15952
- const nativeCapHook = new Command9("native-cap-hook").description(
16970
+ const nativeCapHook = new Command11("native-cap-hook").description(
15953
16971
  "Inspect and manage the first SED Lite validation-hook policy: native per-transaction spend caps"
15954
16972
  );
15955
- const targetAllowlistHook = new Command9("target-allowlist-hook").description(
16973
+ const targetAllowlistHook = new Command11("target-allowlist-hook").description(
15956
16974
  "Inspect and manage the SED Lite validation-hook policy that restricts transactions to an allowlisted target set"
15957
16975
  );
15958
- const selectorAllowlistHook = new Command9("selector-allowlist-hook").description(
16976
+ const selectorAllowlistHook = new Command11("selector-allowlist-hook").description(
15959
16977
  "Inspect and manage the SED Lite validation-hook policy that restricts contract calls to allowlisted target and selector pairs"
15960
16978
  );
15961
- const dailySpendLimit = new Command9("daily-spend-limit").description(
16979
+ const dailySpendLimit = new Command11("daily-spend-limit").description(
15962
16980
  "Read and update the native-token daily spend limit used by the built-in daily-spend-limit smart-account profile"
15963
16981
  );
15964
- const paymaster = new Command9("paymaster").description(
16982
+ const paymaster = new Command11("paymaster").description(
15965
16983
  "Manage saved paymaster defaults for stored wallets"
15966
16984
  );
15967
16985
  wallet.addHelpText(
@@ -15969,6 +16987,9 @@ function createWalletCommand(deps) {
15969
16987
  [
15970
16988
  "",
15971
16989
  "Local-first wallet path:",
16990
+ " Use this layer when the blocker is specifically about wallet approval or signer state.",
16991
+ " Otherwise start with `zk-agent next` or `zk-agent doctor`.",
16992
+ "",
15972
16993
  " First bootstrap:",
15973
16994
  " zk-agent wallet create --await-local",
15974
16995
  " zk-agent next",
@@ -15989,7 +17010,8 @@ function createWalletCommand(deps) {
15989
17010
  " zk-agent relay inspect --relay-url <url>",
15990
17011
  " zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
15991
17012
  " zk-agent wallet reapprove --name main --relay-url <url> --wait-relay --prompt-code",
15992
- " zk-agent next"
17013
+ " zk-agent next",
17014
+ " Use this only when the browser is not colocated with the terminal."
15993
17015
  ].join("\n")
15994
17016
  );
15995
17017
  request.addHelpText(
@@ -16060,7 +17082,28 @@ function createWalletCommand(deps) {
16060
17082
  ).option("--disallow-transfers", "Disable transfer capability for the approved session").option(
16061
17083
  "--disallow-contract-calls",
16062
17084
  "Disable contract-call capability for the approved session"
16063
- ).option("--connector-url <url>", "Connector UI base URL override").option("--relay-url <url>", "Relay server base URL for immediate remote approval publishing").option("--account-kind <kind>", "Requested account kind", "smart-account").option("--paymaster-mode <mode>", "Requested paymaster mode", "none").option("--await-local", "Immediately wait for a local connector approval callback").option("--wait-relay", "Wait for relay approval readiness and finalize from the same command (requires --relay-url and either --code or --prompt-code)").option("--code <code>", "6-digit relay approval code used together with --wait-relay").option("--prompt-code", "Read the 6-digit relay approval code from stdin after the relay approval is ready").option("--host <host>", "Loopback host to bind when using --await-local", "127.0.0.1").option("--port <port>", "Loopback port to bind when using --await-local (0 = choose a free port)", "0").option("--timeout-seconds <seconds>", "How long to wait when using --await-local or --wait-relay", "600").option("--interval-ms <milliseconds>", "How often to poll relay status while using --wait-relay", "2000").action(
17085
+ ).option("--connector-url <url>", "Connector UI base URL override").option("--relay-url <url>", "Relay server base URL for immediate remote approval publishing").option("--account-kind <kind>", "Requested account kind", "smart-account").option("--paymaster-mode <mode>", "Requested paymaster mode", "none").option("--await-local", "Immediately wait for a local connector approval callback").option("--wait-relay", "Wait for relay approval readiness and finalize from the same command (requires --relay-url and either --code or --prompt-code)").option("--code <code>", "6-digit relay approval code used together with --wait-relay").option("--prompt-code", "Read the 6-digit relay approval code from stdin after the relay approval is ready").option("--host <host>", "Loopback host to bind when using --await-local", "127.0.0.1").option("--port <port>", "Loopback port to bind when using --await-local (0 = choose a free port)", "0").option("--timeout-seconds <seconds>", "How long to wait when using --await-local or --wait-relay", "600").option("--interval-ms <milliseconds>", "How often to poll relay status while using --wait-relay", "2000").addHelpText(
17086
+ "after",
17087
+ [
17088
+ "",
17089
+ "Default wallet-create path:",
17090
+ " Keep `--await-local` as the local-first baseline when the browser and terminal are colocated.",
17091
+ "",
17092
+ " Fresh bootstrap:",
17093
+ " zk-agent next",
17094
+ " zk-agent wallet create --await-local",
17095
+ " zk-agent next",
17096
+ "",
17097
+ " Remote-browser fallback:",
17098
+ " zk-agent relay inspect --relay-url <url>",
17099
+ " zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
17100
+ " zk-agent next",
17101
+ "",
17102
+ "Environment note:",
17103
+ " No custom .env is required to create the wallet request itself.",
17104
+ " Add RPC env vars later, before live reads or broadcasts."
17105
+ ].join("\n")
17106
+ ).action(
16064
17107
  async (options) => {
16065
17108
  const config = await loadProjectConfig();
16066
17109
  const chain = options.chain || config?.defaultChain || "zksync-era";
@@ -16243,7 +17286,27 @@ function createWalletCommand(deps) {
16243
17286
  ).option("--disallow-transfers", "Disable transfer capability for the approved session").option(
16244
17287
  "--disallow-contract-calls",
16245
17288
  "Disable contract-call capability for the approved session"
16246
- ).option("--connector-url <url>", "Connector UI base URL override").option("--relay-url <url>", "Relay server base URL for immediate remote approval publishing").option("--await-local", "Immediately wait for a local connector approval callback").option("--wait-relay", "Wait for relay approval readiness and finalize from the same command (requires --relay-url and either --code or --prompt-code)").option("--code <code>", "6-digit relay approval code used together with --wait-relay").option("--prompt-code", "Read the 6-digit relay approval code from stdin after the relay approval is ready").option("--host <host>", "Loopback host to bind when using --await-local", "127.0.0.1").option("--port <port>", "Loopback port to bind when using --await-local (0 = choose a free port)", "0").option("--timeout-seconds <seconds>", "How long to wait when using --await-local or --wait-relay", "600").option("--interval-ms <milliseconds>", "How often to poll relay status while using --wait-relay", "2000").action(
17289
+ ).option("--connector-url <url>", "Connector UI base URL override").option("--relay-url <url>", "Relay server base URL for immediate remote approval publishing").option("--await-local", "Immediately wait for a local connector approval callback").option("--wait-relay", "Wait for relay approval readiness and finalize from the same command (requires --relay-url and either --code or --prompt-code)").option("--code <code>", "6-digit relay approval code used together with --wait-relay").option("--prompt-code", "Read the 6-digit relay approval code from stdin after the relay approval is ready").option("--host <host>", "Loopback host to bind when using --await-local", "127.0.0.1").option("--port <port>", "Loopback port to bind when using --await-local (0 = choose a free port)", "0").option("--timeout-seconds <seconds>", "How long to wait when using --await-local or --wait-relay", "600").option("--interval-ms <milliseconds>", "How often to poll relay status while using --wait-relay", "2000").addHelpText(
17290
+ "after",
17291
+ [
17292
+ "",
17293
+ "Default wallet-reapprove path:",
17294
+ " Use this when the wallet already exists locally but its approval/session must be refreshed.",
17295
+ "",
17296
+ " Colocated browser + terminal:",
17297
+ " zk-agent wallet reapprove --name main --await-local",
17298
+ " zk-agent next",
17299
+ "",
17300
+ " Remote-browser fallback:",
17301
+ " zk-agent relay inspect --relay-url <url>",
17302
+ " zk-agent wallet reapprove --name main --relay-url <url> --wait-relay --prompt-code",
17303
+ " zk-agent next",
17304
+ "",
17305
+ "Environment note:",
17306
+ " No custom .env is required to create the reapproval request itself.",
17307
+ " Add RPC env vars later, before live reads or broadcasts."
17308
+ ].join("\n")
17309
+ ).action(
16247
17310
  async (options) => {
16248
17311
  const walletRecord = await requireWalletRecord(options.name);
16249
17312
  const request2 = await createWalletReapprovalRequest({
@@ -16526,14 +17589,45 @@ function createWalletCommand(deps) {
16526
17589
  const walletRecord = await loadWalletSession(options.name);
16527
17590
  if (!walletRecord) throw new Error(`Wallet not found: ${options.name}`);
16528
17591
  const { inspection, summary } = await loadWalletStatusSummary(walletRecord, resolvedDeps);
16529
- printResult(walletStatusLines(inspection, summary), { ok: true, inspection, summary });
17592
+ const recommendedCommands = buildWalletNextRecommendedCommands(
17593
+ walletRecord.walletName,
17594
+ summary,
17595
+ resolveEffectivePaymasterSelection(walletRecord)?.mode
17596
+ );
17597
+ const tokenDiscoverySummary = buildWalletTokenDiscoverySummary({
17598
+ walletName: walletRecord.walletName,
17599
+ chain: summary.chain,
17600
+ nextAction: summary.recommendedCommand,
17601
+ paymasterMode: resolveEffectivePaymasterSelection(walletRecord)?.mode,
17602
+ recommendedCommands
17603
+ });
17604
+ printResult(
17605
+ [
17606
+ ...walletStatusLines(inspection, summary),
17607
+ ["discover assets", recommendedCommands.discoverAssets],
17608
+ ["discover owned tokens", recommendedCommands.discoverOwnedTokens],
17609
+ ...recommendedCommands.discoverPaymasterTokens ? [["discover paymaster tokens", recommendedCommands.discoverPaymasterTokens]] : [],
17610
+ ["discover tokens", recommendedCommands.discoverTokens],
17611
+ ...recommendedCommands.inspectPaymasterToken ? [["inspect paymaster token", recommendedCommands.inspectPaymasterToken]] : [],
17612
+ ["inspect token", recommendedCommands.inspectToken],
17613
+ ["wallet next", buildWalletNextRecommendedCommand(walletRecord.walletName)]
17614
+ ],
17615
+ {
17616
+ ok: true,
17617
+ inspection,
17618
+ summary,
17619
+ tokenDiscoverySummary,
17620
+ recommendedCommands
17621
+ }
17622
+ );
16530
17623
  });
16531
17624
  wallet.command("next").description("Explain the shortest next CLI steps to make a stored wallet operational").option("--name <name>", "Wallet name", "main").action(async (options) => {
16532
17625
  const walletRecord = await requireWalletRecord(options.name);
16533
17626
  const { inspection, summary } = await loadWalletStatusSummary(walletRecord, resolvedDeps);
16534
17627
  const recommendedCommands = buildWalletNextRecommendedCommands(
16535
17628
  walletRecord.walletName,
16536
- summary
17629
+ summary,
17630
+ resolveEffectivePaymasterSelection(walletRecord)?.mode
16537
17631
  );
16538
17632
  const tokenDiscoverySummary = buildWalletTokenDiscoverySummary({
16539
17633
  walletName: walletRecord.walletName,
@@ -16547,7 +17641,9 @@ function createWalletCommand(deps) {
16547
17641
  ...walletNextLines(summary),
16548
17642
  ["discover assets", recommendedCommands.discoverAssets],
16549
17643
  ["discover owned tokens", recommendedCommands.discoverOwnedTokens],
17644
+ ...recommendedCommands.discoverPaymasterTokens ? [["discover paymaster tokens", recommendedCommands.discoverPaymasterTokens]] : [],
16550
17645
  ["discover tokens", recommendedCommands.discoverTokens],
17646
+ ...recommendedCommands.inspectPaymasterToken ? [["inspect paymaster token", recommendedCommands.inspectPaymasterToken]] : [],
16551
17647
  ["inspect token", recommendedCommands.inspectToken],
16552
17648
  ["status command", recommendedCommands.walletStatus]
16553
17649
  ],
@@ -18512,7 +19608,7 @@ function createWalletCommand(deps) {
18512
19608
 
18513
19609
  // src/commands/workflow.ts
18514
19610
  import { randomBytes as randomBytes4 } from "node:crypto";
18515
- import { Command as Command10 } from "commander";
19611
+ import { Command as Command12 } from "commander";
18516
19612
  var defaultProvider2 = new ZkSyncWalletProvider();
18517
19613
  var defaultDefiProvider2 = new ZkSyncDefiProvider({
18518
19614
  walletWriter: defaultProvider2
@@ -19152,7 +20248,69 @@ function withAgentProfileLines(lines, agentProfile, agentFollowup) {
19152
20248
  ...agentFollowup ? agentFollowupLines(agentFollowup) : []
19153
20249
  ];
19154
20250
  }
19155
- async function printWorkflowRunCommandResult(execution) {
20251
+ function serializeWorkflowFundingProgress(fundingProgress) {
20252
+ return fundingProgress ? {
20253
+ kind: fundingProgress.kind,
20254
+ txHash: fundingProgress.txHash,
20255
+ status: fundingProgress.status,
20256
+ terminal: fundingProgress.terminal,
20257
+ finalized: fundingProgress.finalized
20258
+ } : void 0;
20259
+ }
20260
+ function buildWorkflowRuntimeSummary(options) {
20261
+ if (!options.status && !options.result) {
20262
+ throw new Error("Workflow runtime summary requires a workflow status or execution result.");
20263
+ }
20264
+ const nextCommand = options.nextCommand ?? options.result?.nextCommand ?? options.status?.fundingProgress?.nextCommand ?? options.status?.recommendedCommand;
20265
+ return {
20266
+ status: options.result?.stage ?? options.status?.status ?? "blocked",
20267
+ readyForGoal: options.result ? options.result.stage === "goal-executed" : Boolean(options.status?.readyForGoal),
20268
+ nextCommand,
20269
+ blockingActionIds: options.status?.blockingActionIds ?? [],
20270
+ fundingProgress: serializeWorkflowFundingProgress(options.status?.fundingProgress)
20271
+ };
20272
+ }
20273
+ function buildWorkflowEntrySummary(input) {
20274
+ if (input.plan) {
20275
+ return {
20276
+ entrypoint: "workflow",
20277
+ command: input.command,
20278
+ source: input.source || null,
20279
+ workflowRequestId: input.requestId || null,
20280
+ walletName: input.plan.walletName,
20281
+ intent: input.plan.intent,
20282
+ runtimeStatus: input.plan.status,
20283
+ readyForGoal: input.plan.readyForGoal,
20284
+ walletApprovalStatus: null,
20285
+ checkpointPersisted: typeof input.checkpointPersisted === "boolean" ? input.checkpointPersisted : null,
20286
+ nextAction: input.nextCommand || input.plan.recommendedCommand || null
20287
+ };
20288
+ }
20289
+ const runtimeSummary = buildWorkflowRuntimeSummary({
20290
+ status: input.status,
20291
+ result: input.result,
20292
+ nextCommand: input.nextCommand
20293
+ });
20294
+ const walletName = input.result?.walletName ?? input.status?.walletName;
20295
+ const intent = input.result?.intent ?? input.status?.intent;
20296
+ if (!walletName || !intent) {
20297
+ throw new Error("Workflow entry summary requires workflow status or execution metadata.");
20298
+ }
20299
+ return {
20300
+ entrypoint: "workflow",
20301
+ command: input.command,
20302
+ source: input.source || null,
20303
+ workflowRequestId: input.requestId || null,
20304
+ walletName,
20305
+ intent,
20306
+ runtimeStatus: runtimeSummary.status,
20307
+ readyForGoal: runtimeSummary.readyForGoal,
20308
+ walletApprovalStatus: buildWorkflowWalletApprovalSummary(input.walletApproval)?.status || null,
20309
+ checkpointPersisted: typeof input.checkpointPersisted === "boolean" ? input.checkpointPersisted : null,
20310
+ nextAction: runtimeSummary.nextCommand || null
20311
+ };
20312
+ }
20313
+ async function printWorkflowRunCommandResult(execution, command) {
19156
20314
  if (execution.result) {
19157
20315
  const agentProfile2 = await loadWorkflowAgentProfile(execution.result.walletName);
19158
20316
  const agentFollowup2 = buildAgentFollowup(agentProfile2, {
@@ -19175,6 +20333,21 @@ async function printWorkflowRunCommandResult(execution) {
19175
20333
  paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.goal),
19176
20334
  recommendedCommands: recommendedCommands2
19177
20335
  });
20336
+ const summary2 = buildWorkflowRuntimeSummary({
20337
+ status: execution.status,
20338
+ result: execution.result,
20339
+ nextCommand: execution.result.nextCommand
20340
+ });
20341
+ const workflowEntrySummary2 = buildWorkflowEntrySummary({
20342
+ command,
20343
+ source: execution.requestId ? "checkpoint" : "input",
20344
+ requestId: execution.requestId,
20345
+ checkpointPersisted: Boolean(execution.checkpoint || execution.requestId),
20346
+ status: execution.status,
20347
+ result: execution.result,
20348
+ walletApproval: execution.walletApproval,
20349
+ nextCommand: execution.result.nextCommand
20350
+ });
19178
20351
  printResult(
19179
20352
  prependWorkflowRequestId(
19180
20353
  execution.requestId,
@@ -19191,47 +20364,62 @@ async function printWorkflowRunCommandResult(execution) {
19191
20364
  {
19192
20365
  ok: true,
19193
20366
  ...serializeWorkflowRequestMeta(execution.requestId),
20367
+ workflowEntrySummary: workflowEntrySummary2,
19194
20368
  agentProfile: agentProfile2,
19195
20369
  agentFollowup: agentFollowup2,
20370
+ summary: summary2,
19196
20371
  result: execution.result,
19197
- walletRequestId: execution.walletApproval?.request.requestId,
19198
- walletApprovalRelay: execution.walletApproval?.relay,
19199
- ...workflowWalletApprovalRelayAliases(execution.walletApproval?.relay),
19200
- walletApprovalRecommendedCommands: execution.walletApproval?.recommendedCommands,
19201
- walletApproval: serializeWalletApproval(execution.walletApproval),
20372
+ ...serializeWorkflowWalletApprovalOutput(execution.walletApproval),
19202
20373
  tokenDiscoverySummary: tokenDiscoverySummary2,
19203
20374
  recommendedCommands: recommendedCommands2
19204
20375
  }
19205
20376
  );
19206
20377
  return;
19207
20378
  }
19208
- const agentProfile = await loadWorkflowAgentProfile(execution.status.walletName);
20379
+ const status = execution.status;
20380
+ if (!status) {
20381
+ throw new Error("Workflow run result is missing both execution result and status.");
20382
+ }
20383
+ const agentProfile = await loadWorkflowAgentProfile(status.walletName);
19209
20384
  const agentFollowup = buildAgentFollowup(agentProfile, {
19210
- walletName: execution.status.walletName,
20385
+ walletName: status.walletName,
19211
20386
  walletExists: true
19212
20387
  });
19213
20388
  const recommendedCommands = buildWorkflowRuntimeRecommendedCommands({
19214
20389
  requestId: execution.requestId,
19215
- walletName: execution.status.walletName,
19216
- nextAction: execution.status.recommendedCommand,
19217
- chain: execution.status.plan.chain,
19218
- intent: execution.status.intent,
20390
+ walletName: status.walletName,
20391
+ nextAction: status.recommendedCommand,
20392
+ chain: status.plan.chain,
20393
+ intent: status.intent,
19219
20394
  paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal)
19220
20395
  });
19221
20396
  const tokenDiscoverySummary = buildWorkflowTokenDiscoverySummary({
19222
- walletName: execution.status.walletName,
19223
- chain: execution.status.plan.chain,
19224
- intent: execution.status.intent,
19225
- nextAction: execution.status.recommendedCommand,
20397
+ walletName: status.walletName,
20398
+ chain: status.plan.chain,
20399
+ intent: status.intent,
20400
+ nextAction: status.recommendedCommand,
19226
20401
  paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal),
19227
20402
  recommendedCommands
19228
20403
  });
20404
+ const summary = buildWorkflowRuntimeSummary({
20405
+ status,
20406
+ nextCommand: status.recommendedCommand
20407
+ });
20408
+ const workflowEntrySummary = buildWorkflowEntrySummary({
20409
+ command,
20410
+ source: execution.requestId ? "checkpoint" : "input",
20411
+ requestId: execution.requestId,
20412
+ checkpointPersisted: Boolean(execution.checkpoint || execution.requestId),
20413
+ status,
20414
+ walletApproval: execution.walletApproval,
20415
+ nextCommand: status.recommendedCommand
20416
+ });
19229
20417
  printResult(
19230
20418
  prependWorkflowRequestId(
19231
20419
  execution.requestId,
19232
20420
  withAgentProfileLines(
19233
20421
  [
19234
- ...workflowStatusLines(execution.status),
20422
+ ...workflowStatusLines(status),
19235
20423
  ...workflowWalletApprovalLines(execution.walletApproval),
19236
20424
  ...workflowFollowupLines(recommendedCommands)
19237
20425
  ],
@@ -19242,15 +20430,13 @@ async function printWorkflowRunCommandResult(execution) {
19242
20430
  {
19243
20431
  ok: true,
19244
20432
  ...serializeWorkflowRequestMeta(execution.requestId),
20433
+ workflowEntrySummary,
19245
20434
  agentProfile,
19246
20435
  agentFollowup,
19247
- status: execution.status,
20436
+ summary,
20437
+ status,
19248
20438
  checkpoint: execution.checkpoint,
19249
- walletRequestId: execution.walletApproval?.request.requestId,
19250
- walletApprovalRelay: execution.walletApproval?.relay,
19251
- ...workflowWalletApprovalRelayAliases(execution.walletApproval?.relay),
19252
- walletApprovalRecommendedCommands: execution.walletApproval?.recommendedCommands,
19253
- walletApproval: serializeWalletApproval(execution.walletApproval),
20439
+ ...serializeWorkflowWalletApprovalOutput(execution.walletApproval),
19254
20440
  tokenDiscoverySummary,
19255
20441
  recommendedCommands
19256
20442
  }
@@ -19504,7 +20690,7 @@ async function executeWorkflowAutoCommand(options, deps = resolveWorkflowCommand
19504
20690
  walletApproval
19505
20691
  };
19506
20692
  }
19507
- async function printWorkflowAutoCommandResult(execution) {
20693
+ async function printWorkflowAutoCommandResult(execution, command) {
19508
20694
  const agentProfile = await loadWorkflowAgentProfile(execution.status.walletName);
19509
20695
  const agentFollowup = buildAgentFollowup(agentProfile, {
19510
20696
  walletName: execution.status.walletName,
@@ -19527,6 +20713,21 @@ async function printWorkflowAutoCommandResult(execution) {
19527
20713
  paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.goal) ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal),
19528
20714
  recommendedCommands
19529
20715
  });
20716
+ const summary = buildWorkflowRuntimeSummary({
20717
+ status: execution.status,
20718
+ result: execution.result,
20719
+ nextCommand: nextAction
20720
+ });
20721
+ const workflowEntrySummary = buildWorkflowEntrySummary({
20722
+ command,
20723
+ source: execution.source,
20724
+ requestId: execution.requestId,
20725
+ checkpointPersisted: execution.checkpointPersisted,
20726
+ status: execution.status,
20727
+ result: execution.result,
20728
+ walletApproval: execution.walletApproval,
20729
+ nextCommand: nextAction
20730
+ });
19530
20731
  const summaryLines = [
19531
20732
  ["source", execution.source],
19532
20733
  ["action", execution.action],
@@ -19553,16 +20754,14 @@ async function printWorkflowAutoCommandResult(execution) {
19553
20754
  action: execution.action,
19554
20755
  checkpointPersisted: execution.checkpointPersisted,
19555
20756
  ...serializeWorkflowRequestMeta(execution.requestId),
20757
+ workflowEntrySummary,
19556
20758
  agentProfile,
19557
20759
  agentFollowup,
20760
+ summary,
19558
20761
  status: execution.status,
19559
20762
  result: execution.result,
19560
20763
  checkpoint: execution.checkpoint,
19561
- walletRequestId: execution.walletApproval?.request.requestId,
19562
- walletApprovalRelay: execution.walletApproval?.relay,
19563
- ...workflowWalletApprovalRelayAliases(execution.walletApproval?.relay),
19564
- walletApprovalRecommendedCommands: execution.walletApproval?.recommendedCommands,
19565
- walletApproval: serializeWalletApproval(execution.walletApproval),
20764
+ ...serializeWorkflowWalletApprovalOutput(execution.walletApproval),
19566
20765
  tokenDiscoverySummary,
19567
20766
  recommendedCommands
19568
20767
  }
@@ -19760,6 +20959,7 @@ function serializeWalletApproval(walletApproval) {
19760
20959
  if (!walletApproval) return void 0;
19761
20960
  return {
19762
20961
  ...walletApproval,
20962
+ summary: buildWorkflowWalletApprovalSummary(walletApproval),
19763
20963
  ...workflowWalletApprovalRelayAliases(walletApproval.relay, {
19764
20964
  shareLinkBaseField: "relayShareLinkBaseUrl",
19765
20965
  statusApiBaseField: "relayStatusApiBaseUrl"
@@ -19769,6 +20969,34 @@ function serializeWalletApproval(walletApproval) {
19769
20969
  wallet: walletApproval.wallet ? sanitizeWalletRecord(walletApproval.wallet) : void 0
19770
20970
  };
19771
20971
  }
20972
+ function buildWorkflowWalletApprovalSummary(walletApproval) {
20973
+ if (!walletApproval) return void 0;
20974
+ let status = "await-local";
20975
+ if (walletApproval.stage === "approved") {
20976
+ status = "approved";
20977
+ } else if (walletApproval.recommendedCommands?.relayStatus && walletApproval.nextCommand === walletApproval.recommendedCommands.relayStatus) {
20978
+ status = "relay-pending";
20979
+ }
20980
+ return {
20981
+ status,
20982
+ walletRequestId: walletApproval.request.requestId,
20983
+ reusedRequest: walletApproval.reusedRequest,
20984
+ relayPublished: Boolean(walletApproval.relay),
20985
+ nextAction: walletApproval.nextCommand,
20986
+ afterApproval: walletApproval.recommendedCommands?.afterApproval || null,
20987
+ afterApprovalStatus: walletApproval.recommendedCommands?.afterApprovalStatus || null
20988
+ };
20989
+ }
20990
+ function serializeWorkflowWalletApprovalOutput(walletApproval) {
20991
+ return {
20992
+ walletRequestId: walletApproval?.request.requestId,
20993
+ walletApprovalRelay: walletApproval?.relay,
20994
+ ...workflowWalletApprovalRelayAliases(walletApproval?.relay),
20995
+ walletApprovalRecommendedCommands: walletApproval?.recommendedCommands,
20996
+ walletApprovalSummary: buildWorkflowWalletApprovalSummary(walletApproval),
20997
+ walletApproval: serializeWalletApproval(walletApproval)
20998
+ };
20999
+ }
19772
21000
  function workflowWalletApprovalRelayAliases(relay, fieldNames = {
19773
21001
  shareLinkBaseField: "walletApprovalRelayShareLinkBaseUrl",
19774
21002
  statusApiBaseField: "walletApprovalRelayStatusApiBaseUrl"
@@ -20120,7 +21348,7 @@ function applyWorkflowHelpCommandOrder(workflow) {
20120
21348
  }
20121
21349
  function createWorkflowCommand(deps) {
20122
21350
  const resolvedDeps = resolveWorkflowCommandDeps(deps);
20123
- const workflow = new Command10("workflow").description(
21351
+ const workflow = new Command12("workflow").description(
20124
21352
  "Plan, persist, and execute higher-level wallet workflows"
20125
21353
  );
20126
21354
  workflow.addHelpText("after", buildWorkflowHelpText());
@@ -20159,6 +21387,13 @@ function createWorkflowCommand(deps) {
20159
21387
  walletName: plan.walletName,
20160
21388
  walletExists: true
20161
21389
  });
21390
+ const workflowEntrySummary = buildWorkflowEntrySummary({
21391
+ command: "plan",
21392
+ source: "input",
21393
+ checkpointPersisted: false,
21394
+ plan,
21395
+ nextCommand: plan.recommendedCommand
21396
+ });
20162
21397
  printResult(
20163
21398
  withAgentProfileLines(
20164
21399
  [...workflowPlanLines(plan), ...workflowFollowupLines(recommendedCommands)],
@@ -20167,6 +21402,7 @@ function createWorkflowCommand(deps) {
20167
21402
  ),
20168
21403
  {
20169
21404
  ok: true,
21405
+ workflowEntrySummary,
20170
21406
  agentProfile,
20171
21407
  agentFollowup,
20172
21408
  inspection,
@@ -20308,6 +21544,14 @@ function createWorkflowCommand(deps) {
20308
21544
  {
20309
21545
  ok: true,
20310
21546
  ...serializeWorkflowRequestMeta(started.requestId),
21547
+ workflowEntrySummary: buildWorkflowEntrySummary({
21548
+ command: "start",
21549
+ source: "input",
21550
+ requestId: started.requestId,
21551
+ checkpointPersisted: true,
21552
+ status: started.status,
21553
+ nextCommand: started.status.recommendedCommand
21554
+ }),
20311
21555
  agentProfile,
20312
21556
  agentFollowup,
20313
21557
  checkpoint: started.checkpoint,
@@ -20327,7 +21571,7 @@ function createWorkflowCommand(deps) {
20327
21571
  includeLocalApproval: true
20328
21572
  }).action(withWorkflowInputErrorHandling(async (options) => {
20329
21573
  const execution = await executeWorkflowAutoCommand(options, resolvedDeps);
20330
- await printWorkflowAutoCommandResult(execution);
21574
+ await printWorkflowAutoCommandResult(execution, "auto");
20331
21575
  }));
20332
21576
  const pay = workflow.command("pay").description(
20333
21577
  "Guided flagship AA native-send path with checkpoint persistence, intent-scoped session recovery, and paymaster-aware defaults"
@@ -20344,7 +21588,7 @@ function createWorkflowCommand(deps) {
20344
21588
  applyWorkflowPayDefaults(options),
20345
21589
  resolvedDeps
20346
21590
  );
20347
- await printWorkflowAutoCommandResult(execution);
21591
+ await printWorkflowAutoCommandResult(execution, "pay");
20348
21592
  }));
20349
21593
  const run = workflow.command("run").description("Run the requested workflow, or stop on the next required prerequisite or funding step first").option(
20350
21594
  "--intent <intent>",
@@ -20356,7 +21600,7 @@ function createWorkflowCommand(deps) {
20356
21600
  includeLocalApproval: true
20357
21601
  }).action(withWorkflowInputErrorHandling(async (options) => {
20358
21602
  const execution = await executeWorkflowRunCommand(options, resolvedDeps);
20359
- await printWorkflowRunCommandResult(execution);
21603
+ await printWorkflowRunCommandResult(execution, "run");
20360
21604
  }));
20361
21605
  const status = workflow.command("status").description("Inspect whether a workflow is blocked, still waiting on funding, or ready to resume").option(
20362
21606
  "--intent <intent>",
@@ -20388,6 +21632,19 @@ function createWorkflowCommand(deps) {
20388
21632
  walletName: inspection.result.walletName,
20389
21633
  walletExists: true
20390
21634
  });
21635
+ const summary = buildWorkflowRuntimeSummary({
21636
+ status: inspection.result,
21637
+ nextCommand: inspection.result.recommendedCommand
21638
+ });
21639
+ const workflowEntrySummary = buildWorkflowEntrySummary({
21640
+ command: "status",
21641
+ source: options.requestId?.trim() ? "checkpoint" : "input",
21642
+ requestId: inspection.requestId,
21643
+ checkpointPersisted: Boolean(inspection.checkpoint),
21644
+ status: inspection.result,
21645
+ walletApproval: inspection.walletApproval,
21646
+ nextCommand: inspection.result.recommendedCommand
21647
+ });
20391
21648
  printResult(
20392
21649
  prependWorkflowRequestId(
20393
21650
  inspection.requestId,
@@ -20404,15 +21661,13 @@ function createWorkflowCommand(deps) {
20404
21661
  {
20405
21662
  ok: true,
20406
21663
  ...serializeWorkflowRequestMeta(inspection.requestId),
21664
+ workflowEntrySummary,
20407
21665
  agentProfile,
20408
21666
  agentFollowup,
21667
+ summary,
20409
21668
  result: inspection.result,
20410
21669
  checkpoint: inspection.checkpoint,
20411
- walletRequestId: inspection.walletApproval?.request.requestId,
20412
- walletApprovalRelay: inspection.walletApproval?.relay,
20413
- ...workflowWalletApprovalRelayAliases(inspection.walletApproval?.relay),
20414
- walletApprovalRecommendedCommands: inspection.walletApproval?.recommendedCommands,
20415
- walletApproval: serializeWalletApproval(inspection.walletApproval),
21670
+ ...serializeWorkflowWalletApprovalOutput(inspection.walletApproval),
20416
21671
  tokenDiscoverySummary,
20417
21672
  recommendedCommands
20418
21673
  }
@@ -20449,6 +21704,19 @@ function createWorkflowCommand(deps) {
20449
21704
  walletName: inspection.result.walletName,
20450
21705
  walletExists: true
20451
21706
  });
21707
+ const summary = buildWorkflowRuntimeSummary({
21708
+ status: inspection.result,
21709
+ nextCommand
21710
+ });
21711
+ const workflowEntrySummary = buildWorkflowEntrySummary({
21712
+ command: "next",
21713
+ source: options.requestId?.trim() ? "checkpoint" : "input",
21714
+ requestId: inspection.requestId,
21715
+ checkpointPersisted: Boolean(inspection.checkpoint),
21716
+ status: inspection.result,
21717
+ walletApproval: inspection.walletApproval,
21718
+ nextCommand
21719
+ });
20452
21720
  printResult(
20453
21721
  prependWorkflowRequestId(
20454
21722
  inspection.requestId,
@@ -20465,28 +21733,13 @@ function createWorkflowCommand(deps) {
20465
21733
  {
20466
21734
  ok: true,
20467
21735
  ...serializeWorkflowRequestMeta(inspection.requestId),
21736
+ workflowEntrySummary,
20468
21737
  agentProfile,
20469
21738
  agentFollowup,
20470
- summary: {
20471
- status: inspection.result.status,
20472
- readyForGoal: inspection.result.readyForGoal,
20473
- nextCommand,
20474
- blockingActionIds: inspection.result.blockingActionIds,
20475
- fundingProgress: inspection.result.fundingProgress ? {
20476
- kind: inspection.result.fundingProgress.kind,
20477
- txHash: inspection.result.fundingProgress.txHash,
20478
- status: inspection.result.fundingProgress.status,
20479
- terminal: inspection.result.fundingProgress.terminal,
20480
- finalized: inspection.result.fundingProgress.finalized
20481
- } : void 0
20482
- },
21739
+ summary,
20483
21740
  result: inspection.result,
20484
21741
  checkpoint: inspection.checkpoint,
20485
- walletRequestId: inspection.walletApproval?.request.requestId,
20486
- walletApprovalRelay: inspection.walletApproval?.relay,
20487
- ...workflowWalletApprovalRelayAliases(inspection.walletApproval?.relay),
20488
- walletApprovalRecommendedCommands: inspection.walletApproval?.recommendedCommands,
20489
- walletApproval: serializeWalletApproval(inspection.walletApproval),
21742
+ ...serializeWorkflowWalletApprovalOutput(inspection.walletApproval),
20490
21743
  tokenDiscoverySummary,
20491
21744
  recommendedCommands
20492
21745
  }
@@ -20524,6 +21777,19 @@ function createWorkflowCommand(deps) {
20524
21777
  walletName: inspection.result.walletName,
20525
21778
  walletExists: true
20526
21779
  });
21780
+ const summary2 = buildWorkflowRuntimeSummary({
21781
+ status: inspection.result,
21782
+ nextCommand: inspection.result.recommendedCommand
21783
+ });
21784
+ const workflowEntrySummary2 = buildWorkflowEntrySummary({
21785
+ command: "resume",
21786
+ source: options.requestId?.trim() ? "checkpoint" : "input",
21787
+ requestId: inspection.requestId,
21788
+ checkpointPersisted: Boolean(inspection.checkpoint),
21789
+ status: inspection.result,
21790
+ walletApproval: inspection.walletApproval,
21791
+ nextCommand: inspection.result.recommendedCommand
21792
+ });
20527
21793
  printResult(
20528
21794
  prependWorkflowRequestId(
20529
21795
  inspection.requestId,
@@ -20540,15 +21806,13 @@ function createWorkflowCommand(deps) {
20540
21806
  {
20541
21807
  ok: true,
20542
21808
  ...serializeWorkflowRequestMeta(inspection.requestId),
21809
+ workflowEntrySummary: workflowEntrySummary2,
20543
21810
  agentProfile: agentProfile2,
20544
21811
  agentFollowup: agentFollowup2,
21812
+ summary: summary2,
20545
21813
  status: inspection.result,
20546
21814
  checkpoint: inspection.checkpoint,
20547
- walletRequestId: inspection.walletApproval.request.requestId,
20548
- walletApprovalRelay: inspection.walletApproval.relay,
20549
- ...workflowWalletApprovalRelayAliases(inspection.walletApproval.relay),
20550
- walletApprovalRecommendedCommands: inspection.walletApproval.recommendedCommands,
20551
- walletApproval: serializeWalletApproval(inspection.walletApproval),
21815
+ ...serializeWorkflowWalletApprovalOutput(inspection.walletApproval),
20552
21816
  tokenDiscoverySummary: tokenDiscoverySummary2,
20553
21817
  recommendedCommands: recommendedCommands2
20554
21818
  }
@@ -20564,33 +21828,50 @@ function createWorkflowCommand(deps) {
20564
21828
  resolvedDeps
20565
21829
  );
20566
21830
  if (!execution.result) {
21831
+ const status2 = execution.status;
21832
+ if (!status2) {
21833
+ throw new Error("Workflow resume result is missing both execution result and status.");
21834
+ }
20567
21835
  const recommendedCommands2 = buildWorkflowRuntimeRecommendedCommands({
20568
21836
  requestId: execution.requestId,
20569
- walletName: execution.status.walletName,
20570
- nextAction: execution.status.recommendedCommand,
20571
- chain: execution.status.plan.chain,
20572
- intent: execution.status.intent,
21837
+ walletName: status2.walletName,
21838
+ nextAction: status2.recommendedCommand,
21839
+ chain: status2.plan.chain,
21840
+ intent: status2.intent,
20573
21841
  paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal)
20574
21842
  });
20575
21843
  const tokenDiscoverySummary2 = buildWorkflowTokenDiscoverySummary({
20576
- walletName: execution.status.walletName,
20577
- chain: execution.status.plan.chain,
20578
- intent: execution.status.intent,
20579
- nextAction: execution.status.recommendedCommand,
21844
+ walletName: status2.walletName,
21845
+ chain: status2.plan.chain,
21846
+ intent: status2.intent,
21847
+ nextAction: status2.recommendedCommand,
20580
21848
  paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal),
20581
21849
  recommendedCommands: recommendedCommands2
20582
21850
  });
20583
- const agentProfile2 = await loadWorkflowAgentProfile(execution.status.walletName);
21851
+ const agentProfile2 = await loadWorkflowAgentProfile(status2.walletName);
20584
21852
  const agentFollowup2 = buildAgentFollowup(agentProfile2, {
20585
- walletName: execution.status.walletName,
21853
+ walletName: status2.walletName,
20586
21854
  walletExists: true
20587
21855
  });
21856
+ const summary2 = buildWorkflowRuntimeSummary({
21857
+ status: status2,
21858
+ nextCommand: status2.recommendedCommand
21859
+ });
21860
+ const workflowEntrySummary2 = buildWorkflowEntrySummary({
21861
+ command: "resume",
21862
+ source: options.requestId?.trim() ? "checkpoint" : "input",
21863
+ requestId: execution.requestId,
21864
+ checkpointPersisted: Boolean(execution.checkpoint || execution.requestId),
21865
+ status: status2,
21866
+ walletApproval: execution.walletApproval,
21867
+ nextCommand: status2.recommendedCommand
21868
+ });
20588
21869
  printResult(
20589
21870
  prependWorkflowRequestId(
20590
21871
  execution.requestId,
20591
21872
  withAgentProfileLines(
20592
21873
  [
20593
- ...workflowStatusLines(execution.status),
21874
+ ...workflowStatusLines(status2),
20594
21875
  ...workflowWalletApprovalLines(execution.walletApproval),
20595
21876
  ...workflowFollowupLines(recommendedCommands2)
20596
21877
  ],
@@ -20601,15 +21882,13 @@ function createWorkflowCommand(deps) {
20601
21882
  {
20602
21883
  ok: true,
20603
21884
  ...serializeWorkflowRequestMeta(execution.requestId),
21885
+ workflowEntrySummary: workflowEntrySummary2,
20604
21886
  agentProfile: agentProfile2,
20605
21887
  agentFollowup: agentFollowup2,
20606
- status: execution.status,
21888
+ summary: summary2,
21889
+ status: status2,
20607
21890
  checkpoint: execution.checkpoint,
20608
- walletRequestId: execution.walletApproval?.request.requestId,
20609
- walletApprovalRelay: execution.walletApproval?.relay,
20610
- ...workflowWalletApprovalRelayAliases(execution.walletApproval?.relay),
20611
- walletApprovalRecommendedCommands: execution.walletApproval?.recommendedCommands,
20612
- walletApproval: serializeWalletApproval(execution.walletApproval),
21891
+ ...serializeWorkflowWalletApprovalOutput(execution.walletApproval),
20613
21892
  tokenDiscoverySummary: tokenDiscoverySummary2,
20614
21893
  recommendedCommands: recommendedCommands2
20615
21894
  }
@@ -20637,6 +21916,21 @@ function createWorkflowCommand(deps) {
20637
21916
  walletName: execution.result.walletName,
20638
21917
  walletExists: true
20639
21918
  });
21919
+ const summary = buildWorkflowRuntimeSummary({
21920
+ status: inspection.result,
21921
+ result: execution.result,
21922
+ nextCommand: execution.result.nextCommand ?? inspection.result.recommendedCommand
21923
+ });
21924
+ const workflowEntrySummary = buildWorkflowEntrySummary({
21925
+ command: "resume",
21926
+ source: options.requestId?.trim() ? "checkpoint" : "input",
21927
+ requestId: execution.requestId,
21928
+ checkpointPersisted: Boolean(execution.checkpoint || execution.requestId),
21929
+ status: inspection.result,
21930
+ result: execution.result,
21931
+ walletApproval: inspection.walletApproval,
21932
+ nextCommand: execution.result.nextCommand ?? inspection.result.recommendedCommand
21933
+ });
20640
21934
  printResult(
20641
21935
  prependWorkflowRequestId(
20642
21936
  execution.requestId,
@@ -20653,15 +21947,13 @@ function createWorkflowCommand(deps) {
20653
21947
  {
20654
21948
  ok: true,
20655
21949
  ...serializeWorkflowRequestMeta(execution.requestId),
21950
+ workflowEntrySummary,
20656
21951
  agentProfile,
20657
21952
  agentFollowup,
21953
+ summary,
20658
21954
  status: inspection.result,
20659
21955
  result: execution.result,
20660
- walletRequestId: inspection.walletApproval?.request.requestId,
20661
- walletApprovalRelay: inspection.walletApproval?.relay,
20662
- ...workflowWalletApprovalRelayAliases(inspection.walletApproval?.relay),
20663
- walletApprovalRecommendedCommands: inspection.walletApproval?.recommendedCommands,
20664
- walletApproval: serializeWalletApproval(inspection.walletApproval),
21956
+ ...serializeWorkflowWalletApprovalOutput(inspection.walletApproval),
20665
21957
  tokenDiscoverySummary,
20666
21958
  recommendedCommands
20667
21959
  }
@@ -20681,7 +21973,7 @@ function createWorkflowCommand(deps) {
20681
21973
  },
20682
21974
  resolvedDeps
20683
21975
  );
20684
- await printWorkflowRunCommandResult(execution);
21976
+ await printWorkflowRunCommandResult(execution, intent);
20685
21977
  }));
20686
21978
  }
20687
21979
  workflow.addCommand(
@@ -20710,6 +22002,16 @@ function buildDefaultOperatorPathHelpText() {
20710
22002
  " zk-agent next",
20711
22003
  ` ${buildWorkflowPayRecommendedCommand("main")}`,
20712
22004
  "",
22005
+ "Operator suite beyond flagship pay:",
22006
+ " zk-agent suite",
22007
+ "",
22008
+ "Validated first-run baseline:",
22009
+ " setup defaults to zksync-sepolia and the local connector at http://localhost:4444",
22010
+ " Override those only when you intentionally target a different chain or connector deployment.",
22011
+ "",
22012
+ "If local setup or wallet state is unclear:",
22013
+ " zk-agent doctor",
22014
+ "",
20713
22015
  "No custom .env is required for setup, next, or wallet create/reapprove request generation.",
20714
22016
  "Add RPC env vars later, before live reads or broadcasts.",
20715
22017
  "",
@@ -20720,9 +22022,11 @@ function buildDefaultOperatorPathHelpText() {
20720
22022
  }
20721
22023
  var ROOT_HELP_COMMAND_ORDER = [
20722
22024
  "next",
22025
+ "doctor",
20723
22026
  "init",
20724
22027
  "wallet",
20725
22028
  "workflow",
22029
+ "suite",
20726
22030
  "assets",
20727
22031
  "balances",
20728
22032
  "fund",
@@ -20756,15 +22060,17 @@ function applyRootHelpCommandOrder(program) {
20756
22060
  program.commands = sortedCommands;
20757
22061
  }
20758
22062
  function createProgram() {
20759
- const program = new Command11().name("zk-agent").description(
22063
+ const program = new Command13().name("zk-agent").description(
20760
22064
  "Local-first zkSync Era CLI for wallet approval, workflow execution, and hosted relay recovery"
20761
22065
  ).showHelpAfterError().option("--json", "Force JSON output for agent harnesses", false).hook("preAction", (thisCommand) => {
20762
22066
  if (thisCommand.optsWithGlobals().json) process.env.ZK_AGENT_OUTPUT = "json";
20763
22067
  });
20764
22068
  program.addCommand(createInitCommand());
20765
22069
  program.addCommand(createNextCommand());
22070
+ program.addCommand(createDoctorCommand());
20766
22071
  program.addCommand(createAgentCommand());
20767
22072
  program.addCommand(createDefaultsCommand());
22073
+ program.addCommand(createSuiteCommand());
20768
22074
  program.addCommand(createTokensCommand());
20769
22075
  program.addCommand(createResolveTokenCommand());
20770
22076
  program.addCommand(createRelayCommand());