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

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 +21 -1
  2. package/dist/index.js +1152 -140
  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 Command12, CommanderError } from "commander";
5
5
  import { config as loadEnv } from "dotenv";
6
6
 
7
7
  // src/commands/operations.ts
@@ -7830,13 +7830,61 @@ function buildWalletCreateRecommendedCommand() {
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}`;
@@ -10066,12 +10120,43 @@ function createPlannedCommands() {
10066
10120
 
10067
10121
  // src/commands/setup.ts
10068
10122
  import { Command as Command2 } from "commander";
10123
+
10124
+ // src/lib/onboarding-summary.ts
10125
+ function buildOnboardingSummary(input) {
10126
+ return {
10127
+ stage: input.stage,
10128
+ baseline: "local-first",
10129
+ localOnly: input.localOnly,
10130
+ configExists: input.configExists,
10131
+ walletExists: input.walletExists ?? null,
10132
+ approvalReady: input.approvalReady ?? null,
10133
+ localExecutionKeyStored: input.localExecutionKeyStored ?? null,
10134
+ defaultChain: input.defaultChain ?? null,
10135
+ connectorUrl: input.connectorUrl ?? null,
10136
+ relayUrl: input.relayUrl ?? null,
10137
+ nextAction: input.nextAction ?? null,
10138
+ notes: [...input.notes ?? []]
10139
+ };
10140
+ }
10141
+ function onboardingSummaryLines(summary) {
10142
+ return [
10143
+ ["baseline", summary.baseline],
10144
+ ["local only", summary.localOnly ? "yes" : "no"]
10145
+ ];
10146
+ }
10147
+
10148
+ // src/commands/setup.ts
10069
10149
  function buildSetupHelpText() {
10070
10150
  return [
10071
10151
  "",
10072
10152
  "What setup does:",
10073
10153
  " Writes the local default chain and connector URL used by the first-run path.",
10074
10154
  "",
10155
+ "Validated first-run baseline:",
10156
+ " Default chain: zksync-sepolia",
10157
+ " Connector URL: http://localhost:4444",
10158
+ " Override --default-chain or --connector-url only when you intentionally deviate from that path.",
10159
+ "",
10075
10160
  "After setup, stay on the canonical local-first path:",
10076
10161
  " zk-agent next",
10077
10162
  " zk-agent wallet create --await-local",
@@ -10088,7 +10173,7 @@ function buildSetupHelpText() {
10088
10173
  ].join("\n");
10089
10174
  }
10090
10175
  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) => {
10176
+ 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
10177
  const recommendedCommands = {
10093
10178
  next: buildTopLevelNextRecommendedCommand(),
10094
10179
  inspectDefaults: buildDefaultsRecommendedCommand(),
@@ -10099,9 +10184,22 @@ function createInitCommand() {
10099
10184
  };
10100
10185
  const existing = await loadProjectConfig();
10101
10186
  if (existing && !options.force) {
10187
+ const onboardingSummary2 = buildOnboardingSummary({
10188
+ stage: "wallet-bootstrap",
10189
+ localOnly: true,
10190
+ configExists: true,
10191
+ defaultChain: existing.defaultChain,
10192
+ connectorUrl: existing.connectorUrl,
10193
+ nextAction: recommendedCommands.next,
10194
+ notes: [
10195
+ "Setup did not overwrite the existing local defaults.",
10196
+ "Run zk-agent next so the CLI can choose wallet bootstrap or workflow follow-up from the current local state."
10197
+ ]
10198
+ });
10102
10199
  printResult(
10103
10200
  [
10104
10201
  ["status", "Config already exists. Re-run with --force to overwrite."],
10202
+ ...onboardingSummaryLines(onboardingSummary2),
10105
10203
  ["default chain", existing.defaultChain],
10106
10204
  ["connector", existing.connectorUrl],
10107
10205
  ["next", recommendedCommands.next],
@@ -10115,22 +10213,36 @@ function createInitCommand() {
10115
10213
  ok: true,
10116
10214
  message: "Config already exists. Re-run with --force to overwrite.",
10117
10215
  config: existing,
10216
+ onboardingSummary: onboardingSummary2,
10118
10217
  recommendedCommands
10119
10218
  }
10120
10219
  );
10121
10220
  return;
10122
10221
  }
10123
10222
  const config = {
10124
- defaultChain: options.defaultChain || "zksync-era",
10223
+ defaultChain: options.defaultChain || "zksync-sepolia",
10125
10224
  connectorUrl: options.connectorUrl || "http://localhost:4444",
10126
10225
  provider: "zksync-sso",
10127
10226
  createdAt: existing?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
10128
10227
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
10129
10228
  };
10130
10229
  await saveProjectConfig(config);
10230
+ const onboardingSummary = buildOnboardingSummary({
10231
+ stage: "wallet-bootstrap",
10232
+ localOnly: true,
10233
+ configExists: true,
10234
+ defaultChain: config.defaultChain,
10235
+ connectorUrl: config.connectorUrl,
10236
+ nextAction: recommendedCommands.next,
10237
+ notes: [
10238
+ "Setup only writes local defaults and does not inspect wallet state.",
10239
+ "Stay on zk-agent next so the product entrypoint can decide between wallet bootstrap and workflow guidance."
10240
+ ]
10241
+ });
10131
10242
  printResult(
10132
10243
  [
10133
10244
  ["status", "Config saved"],
10245
+ ...onboardingSummaryLines(onboardingSummary),
10134
10246
  ["default chain", config.defaultChain],
10135
10247
  ["connector", config.connectorUrl],
10136
10248
  ["next", recommendedCommands.next],
@@ -10140,7 +10252,7 @@ function createInitCommand() {
10140
10252
  ["create wallet (remote)", recommendedCommands.createWalletRemote],
10141
10253
  ["after approval", recommendedCommands.afterWalletApproval]
10142
10254
  ],
10143
- { ok: true, config, recommendedCommands }
10255
+ { ok: true, config, onboardingSummary, recommendedCommands }
10144
10256
  );
10145
10257
  });
10146
10258
  }
@@ -10504,10 +10616,14 @@ function agentProfileLines(summary) {
10504
10616
  }
10505
10617
 
10506
10618
  // src/lib/wallet-next.ts
10507
- function buildWalletNextRecommendedCommands(walletName, summary) {
10619
+ function buildWalletNextRecommendedCommands(walletName, summary, paymasterMode) {
10508
10620
  return {
10509
10621
  discoverAssets: buildAssetsRecommendedCommand(walletName),
10510
10622
  discoverOwnedTokens: buildOwnedTokensRecommendedCommand(walletName),
10623
+ ...paymasterMode === "approval-based" ? {
10624
+ discoverPaymasterTokens: buildPaymasterFeeTokensRecommendedCommand(summary.chain),
10625
+ inspectPaymasterToken: buildPaymasterFeeTokenResolveRecommendedCommand(summary.chain)
10626
+ } : {},
10511
10627
  discoverTokens: buildTokensRecommendedCommand(summary.chain),
10512
10628
  inspectToken: buildResolveTokenRecommendedCommand(summary.chain),
10513
10629
  walletStatus: buildWalletStatusRecommendedCommand(walletName),
@@ -10620,17 +10736,38 @@ function buildSetupCommand() {
10620
10736
  function buildTopLevelNextRecommendedCommand2(requestId) {
10621
10737
  return requestId ? `zk-agent next --request-id ${requestId}` : "zk-agent next";
10622
10738
  }
10739
+ function buildTopLevelWorkflowSummary(result, nextCommand) {
10740
+ return {
10741
+ status: result.status,
10742
+ readyForGoal: result.readyForGoal,
10743
+ nextCommand,
10744
+ blockingActionIds: result.blockingActionIds,
10745
+ fundingProgress: result.fundingProgress ? {
10746
+ kind: result.fundingProgress.kind,
10747
+ txHash: result.fundingProgress.txHash,
10748
+ status: result.fundingProgress.status,
10749
+ terminal: result.fundingProgress.terminal,
10750
+ finalized: result.fundingProgress.finalized
10751
+ } : void 0
10752
+ };
10753
+ }
10623
10754
  function appendPaymasterMode2(command, paymasterMode) {
10624
10755
  if (!paymasterMode) return command;
10625
10756
  return `${command} --paymaster-mode ${paymasterMode}`;
10626
10757
  }
10627
- function topLevelNextLines(scope, lines) {
10628
- return [["scope", scope], ...lines];
10758
+ function topLevelNextLines(scope, lines, onboardingSummary) {
10759
+ return [
10760
+ ["scope", scope],
10761
+ ...onboardingSummary ? onboardingSummaryLines(onboardingSummary) : [],
10762
+ ...lines
10763
+ ];
10629
10764
  }
10630
10765
  function buildNextHelpText() {
10631
10766
  return [
10632
10767
  "",
10633
10768
  "Use `next` as the product entrypoint:",
10769
+ " Stay on `next` until it points you at a wallet-specific or workflow-specific blocker.",
10770
+ "",
10634
10771
  " Fresh local-first routing:",
10635
10772
  " zk-agent setup",
10636
10773
  " zk-agent next",
@@ -10642,6 +10779,8 @@ function buildNextHelpText() {
10642
10779
  " zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
10643
10780
  " zk-agent next",
10644
10781
  "",
10782
+ " If setup has not run yet, `next` will send you back to `zk-agent setup` first.",
10783
+ "",
10645
10784
  " Continue a stored workflow checkpoint:",
10646
10785
  " zk-agent next --request-id <id>",
10647
10786
  "",
@@ -10651,6 +10790,9 @@ function buildNextHelpText() {
10651
10790
  " Switch to the hosted remote-approval path only when the browser is not colocated:",
10652
10791
  " zk-agent wallet --help",
10653
10792
  "",
10793
+ " Use `wallet --help` when you already know the blocker is wallet-specific:",
10794
+ " zk-agent wallet next --name main",
10795
+ "",
10654
10796
  " Stay on the workflow layer only when you already have an explicit workflow or checkpoint:",
10655
10797
  " zk-agent workflow next --request-id <id>"
10656
10798
  ].join("\n");
@@ -10740,6 +10882,7 @@ function createNextCommand(deps) {
10740
10882
  nextCommand: nextCommand2,
10741
10883
  agentProfile: workflowAgentProfile,
10742
10884
  agentFollowup: agentFollowup2,
10885
+ summary: buildTopLevelWorkflowSummary(result, nextCommand2),
10743
10886
  result,
10744
10887
  checkpoint: updatedCheckpoint,
10745
10888
  tokenDiscoverySummary: tokenDiscoverySummary2,
@@ -10755,6 +10898,17 @@ function createNextCommand(deps) {
10755
10898
  afterSetup: buildTopLevelNextRecommendedCommand2(),
10756
10899
  inspectDefaults: buildDefaultsRecommendedCommand()
10757
10900
  };
10901
+ const onboardingSummary2 = buildOnboardingSummary({
10902
+ stage: "setup",
10903
+ localOnly: true,
10904
+ configExists: false,
10905
+ walletExists: false,
10906
+ nextAction: recommendedCommands2.setup,
10907
+ notes: [
10908
+ "No local config was found, so setup is still the first required onboarding step.",
10909
+ "This scope is local-only and does not require live RPC reads."
10910
+ ]
10911
+ });
10758
10912
  printResult(
10759
10913
  topLevelNextLines("setup", [
10760
10914
  ["status", "No local config found"],
@@ -10763,12 +10917,13 @@ function createNextCommand(deps) {
10763
10917
  ["next", recommendedCommands2.setup],
10764
10918
  ["after setup", recommendedCommands2.afterSetup],
10765
10919
  ["inspect defaults", recommendedCommands2.inspectDefaults]
10766
- ]),
10920
+ ], onboardingSummary2),
10767
10921
  {
10768
10922
  ok: true,
10769
10923
  scope: "setup",
10770
10924
  status: "action-required",
10771
10925
  nextCommand: recommendedCommands2.setup,
10926
+ onboardingSummary: onboardingSummary2,
10772
10927
  agentProfile,
10773
10928
  agentFollowup: defaultAgentFollowup,
10774
10929
  recommendedCommands: recommendedCommands2
@@ -10791,6 +10946,19 @@ function createNextCommand(deps) {
10791
10946
  afterApproval: appendPaymasterMode2(buildTopLevelNextRecommendedCommand2(), paymasterMode),
10792
10947
  inspectDefaults: buildDefaultsRecommendedCommand()
10793
10948
  };
10949
+ const onboardingSummary2 = buildOnboardingSummary({
10950
+ stage: "wallet-bootstrap",
10951
+ localOnly: true,
10952
+ configExists: true,
10953
+ walletExists: false,
10954
+ defaultChain: config.defaultChain,
10955
+ connectorUrl: config.connectorUrl,
10956
+ nextAction: recommendedCommands2.createWallet,
10957
+ notes: [
10958
+ "Config exists, but no saved wallet record was found for this name yet.",
10959
+ "Use the remote approval fallback only when the browser is not colocated with this terminal."
10960
+ ]
10961
+ });
10794
10962
  printResult(
10795
10963
  topLevelNextLines("wallet-bootstrap", [
10796
10964
  ["status", `Wallet not found: ${walletName}`],
@@ -10803,13 +10971,14 @@ function createNextCommand(deps) {
10803
10971
  ["remote fallback", recommendedCommands2.createWalletRemote],
10804
10972
  ["after approval", recommendedCommands2.afterApproval],
10805
10973
  ["inspect defaults", recommendedCommands2.inspectDefaults]
10806
- ]),
10974
+ ], onboardingSummary2),
10807
10975
  {
10808
10976
  ok: true,
10809
10977
  scope: "wallet-bootstrap",
10810
10978
  walletName,
10811
10979
  config,
10812
10980
  nextCommand: recommendedCommands2.createWallet,
10981
+ onboardingSummary: onboardingSummary2,
10813
10982
  agentProfile,
10814
10983
  agentFollowup: defaultAgentFollowup,
10815
10984
  recommendedCommands: recommendedCommands2
@@ -10845,6 +11014,27 @@ function createNextCommand(deps) {
10845
11014
  paymasterMode
10846
11015
  );
10847
11016
  const nextCommand = summary.recommendedCommand || workflowPay;
11017
+ const onboardingSummary = buildOnboardingSummary({
11018
+ stage: inspection.approvalReady && inspection.localExecutionKeyStored ? "wallet-ready" : "wallet-recovery",
11019
+ localOnly: false,
11020
+ configExists: true,
11021
+ walletExists: true,
11022
+ approvalReady: inspection.approvalReady,
11023
+ localExecutionKeyStored: inspection.localExecutionKeyStored,
11024
+ defaultChain: config.defaultChain,
11025
+ connectorUrl: config.connectorUrl,
11026
+ nextAction: nextCommand,
11027
+ notes: !inspection.approvalReady ? [
11028
+ "Wallet metadata exists, but approved session metadata is still missing.",
11029
+ "Top-level next returns to live workflow guidance after wallet approval is restored."
11030
+ ] : !inspection.localExecutionKeyStored ? [
11031
+ "Approved session metadata exists, but no local execution signer is stored yet.",
11032
+ "Top-level next returns to live workflow guidance after the signer is attached."
11033
+ ] : [
11034
+ "Wallet approval and local signer state are present.",
11035
+ "Top-level next also inspects live deployment and balance state before recommending the workflow step."
11036
+ ]
11037
+ });
10848
11038
  const agentFollowup = buildAgentFollowup(agentProfile, {
10849
11039
  walletName: wallet.walletName,
10850
11040
  walletExists: true
@@ -10885,11 +11075,12 @@ function createNextCommand(deps) {
10885
11075
  ...recommendedCommands.inspectPaymasterToken ? [["inspect paymaster token", recommendedCommands.inspectPaymasterToken]] : [],
10886
11076
  ["inspect token", recommendedCommands.inspectToken],
10887
11077
  ["inspect defaults", recommendedCommands.inspectDefaults]
10888
- ]),
11078
+ ], onboardingSummary),
10889
11079
  {
10890
11080
  ok: true,
10891
11081
  scope: "wallet",
10892
11082
  walletName: wallet.walletName,
11083
+ onboardingSummary,
10893
11084
  agentProfile,
10894
11085
  agentFollowup,
10895
11086
  inspection,
@@ -10908,8 +11099,418 @@ function parsePaymasterMode(value) {
10908
11099
  throw new Error(`Unsupported paymaster mode: ${value}`);
10909
11100
  }
10910
11101
 
10911
- // src/commands/agent.ts
11102
+ // src/commands/doctor.ts
10912
11103
  import { Command as Command4 } from "commander";
11104
+ function buildDoctorHelpText() {
11105
+ return [
11106
+ "",
11107
+ "Use `doctor` when local state is unclear:",
11108
+ " zk-agent doctor",
11109
+ " zk-agent doctor --wallet main",
11110
+ " zk-agent doctor --wallet main --relay-url https://relay.example.com",
11111
+ "",
11112
+ "Default behavior:",
11113
+ " Inspects saved config, local wallet approval metadata, local signer state,",
11114
+ " and the shortest next command without requiring live RPC reads.",
11115
+ " Run this before guessing whether the blocker is setup, wallet approval, or local signer state.",
11116
+ "",
11117
+ "Remote-browser recovery path:",
11118
+ " Pass --relay-url when you want the remote approval fallback commands",
11119
+ " to use a concrete relay URL instead of a placeholder."
11120
+ ].join("\n");
11121
+ }
11122
+ function summarizeLocalWalletState(wallet) {
11123
+ const localExecutionPrivateKey = resolveLocalExecutionPrivateKey(wallet);
11124
+ return {
11125
+ exists: true,
11126
+ walletName: wallet.walletName,
11127
+ walletAddress: wallet.walletAddress,
11128
+ chain: wallet.chain,
11129
+ chainId: wallet.chainId,
11130
+ accountKind: wallet.accountKind || wallet.sessionPayload?.account?.kind || "smart-account",
11131
+ smartAccountProfileId: wallet.smartAccountProfileId || null,
11132
+ syncedAt: wallet.syncedAt || null,
11133
+ approvalReady: Boolean(wallet.sessionPayload),
11134
+ localExecutionKeyStored: Boolean(localExecutionPrivateKey),
11135
+ legacySessionKeyStored: Boolean(wallet.sessionPayload?.sessionPrivateKey),
11136
+ signerType: wallet.localExecutionAuthority?.signerType || wallet.sessionPayload?.account?.signerType || null,
11137
+ signerAddress: wallet.localExecutionAuthority?.signerAddress || deriveLocalExecutionSignerAddress(localExecutionPrivateKey) || null,
11138
+ signerSource: wallet.localExecutionAuthority?.source || (wallet.sessionPayload?.sessionPrivateKey ? "legacy-session-payload" : null)
11139
+ };
11140
+ }
11141
+ function buildSetupRecommendedCommands() {
11142
+ return {
11143
+ setup: "zk-agent setup",
11144
+ next: buildTopLevelNextRecommendedCommand(),
11145
+ inspectDefaults: buildDefaultsRecommendedCommand()
11146
+ };
11147
+ }
11148
+ function buildWalletBootstrapRecommendedCommands(walletName, relayUrl) {
11149
+ return {
11150
+ next: buildTopLevelNextRecommendedCommand(),
11151
+ inspectDefaults: buildDefaultsRecommendedCommand(),
11152
+ createWallet: buildWalletCreateRecommendedCommand(),
11153
+ relayInspect: buildRelayInspectRecommendedCommand(relayUrl),
11154
+ createWalletRemote: buildWalletCreateRemoteRecommendedCommand(relayUrl, void 0, walletName)
11155
+ };
11156
+ }
11157
+ function buildWalletRecoveryRecommendedCommands(wallet, relayUrl) {
11158
+ const shared = {
11159
+ next: buildTopLevelNextRecommendedCommand(),
11160
+ walletStatus: buildWalletStatusRecommendedCommand(wallet.walletName),
11161
+ walletNext: buildWalletNextRecommendedCommand(wallet.walletName),
11162
+ signerShow: buildWalletSignerShowRecommendedCommand(wallet.walletName),
11163
+ relayInspect: buildRelayInspectRecommendedCommand(relayUrl),
11164
+ reapproveRemote: buildWalletReapproveRemoteRecommendedCommand(wallet.walletName, relayUrl)
11165
+ };
11166
+ if (!wallet.approvalReady) {
11167
+ return {
11168
+ ...shared,
11169
+ reapprove: buildWalletReapproveRecommendedCommand(wallet.walletName)
11170
+ };
11171
+ }
11172
+ return {
11173
+ ...shared,
11174
+ attachSigner: buildWalletSignerAttachRecommendedCommand(wallet.walletName),
11175
+ reapprove: buildWalletReapproveRecommendedCommand(wallet.walletName)
11176
+ };
11177
+ }
11178
+ function buildWalletReadyRecommendedCommands(wallet) {
11179
+ return {
11180
+ next: buildTopLevelNextRecommendedCommand(),
11181
+ walletStatus: buildWalletStatusRecommendedCommand(wallet.walletName),
11182
+ walletNext: buildWalletNextRecommendedCommand(wallet.walletName),
11183
+ workflowPay: buildWorkflowPayRecommendedCommand(wallet.walletName),
11184
+ inspectDefaults: buildDefaultsRecommendedCommand()
11185
+ };
11186
+ }
11187
+ function buildDoctorResult(options) {
11188
+ if (!options.config) {
11189
+ const recommendedCommands2 = buildSetupRecommendedCommands();
11190
+ const onboardingSummary2 = buildOnboardingSummary({
11191
+ stage: "setup",
11192
+ localOnly: true,
11193
+ configExists: false,
11194
+ walletExists: Boolean(options.wallet),
11195
+ approvalReady: options.wallet?.approvalReady ?? null,
11196
+ localExecutionKeyStored: options.wallet?.localExecutionKeyStored ?? null,
11197
+ relayUrl: options.relayUrl || null,
11198
+ nextAction: recommendedCommands2.setup,
11199
+ notes: [
11200
+ "Local config is missing, so the canonical operator path should start with setup.",
11201
+ "Doctor is local-only by default and does not require live RPC reads."
11202
+ ]
11203
+ });
11204
+ return {
11205
+ scope: "setup",
11206
+ nextAction: recommendedCommands2.setup,
11207
+ onboardingSummary: onboardingSummary2,
11208
+ summary: {
11209
+ stage: "setup",
11210
+ configExists: false,
11211
+ walletExists: Boolean(options.wallet),
11212
+ approvalReady: options.wallet?.approvalReady ?? null,
11213
+ localExecutionKeyStored: options.wallet?.localExecutionKeyStored ?? null,
11214
+ relayUrl: options.relayUrl || null,
11215
+ nextAction: recommendedCommands2.setup,
11216
+ localOnly: true,
11217
+ notes: [
11218
+ "Local config is missing, so the canonical operator path should start with setup.",
11219
+ "Doctor is local-only by default and does not require live RPC reads."
11220
+ ]
11221
+ },
11222
+ recommendedCommands: recommendedCommands2
11223
+ };
11224
+ }
11225
+ if (!options.wallet) {
11226
+ const recommendedCommands2 = buildWalletBootstrapRecommendedCommands(
11227
+ options.walletName,
11228
+ options.relayUrl
11229
+ );
11230
+ const onboardingSummary2 = buildOnboardingSummary({
11231
+ stage: "wallet-bootstrap",
11232
+ localOnly: true,
11233
+ configExists: true,
11234
+ walletExists: false,
11235
+ defaultChain: options.config.defaultChain,
11236
+ connectorUrl: options.config.connectorUrl,
11237
+ relayUrl: options.relayUrl || null,
11238
+ nextAction: recommendedCommands2.createWallet,
11239
+ notes: [
11240
+ "Local config exists, but no saved wallet record was found for this name yet.",
11241
+ "Use the remote relay path only when the browser is not colocated with this terminal."
11242
+ ]
11243
+ });
11244
+ return {
11245
+ scope: "wallet-bootstrap",
11246
+ nextAction: recommendedCommands2.createWallet,
11247
+ onboardingSummary: onboardingSummary2,
11248
+ summary: {
11249
+ stage: "wallet-bootstrap",
11250
+ configExists: true,
11251
+ walletExists: false,
11252
+ approvalReady: null,
11253
+ localExecutionKeyStored: null,
11254
+ relayUrl: options.relayUrl || null,
11255
+ nextAction: recommendedCommands2.createWallet,
11256
+ localOnly: true,
11257
+ notes: [
11258
+ "Local config exists, but no saved wallet record was found for this name yet.",
11259
+ "Use the remote relay path only when the browser is not colocated with this terminal."
11260
+ ]
11261
+ },
11262
+ recommendedCommands: recommendedCommands2
11263
+ };
11264
+ }
11265
+ if (!options.wallet.approvalReady) {
11266
+ const recommendedCommands2 = buildWalletRecoveryRecommendedCommands(
11267
+ options.wallet,
11268
+ options.relayUrl
11269
+ );
11270
+ const onboardingSummary2 = buildOnboardingSummary({
11271
+ stage: "wallet-recovery",
11272
+ localOnly: true,
11273
+ configExists: true,
11274
+ walletExists: true,
11275
+ approvalReady: false,
11276
+ localExecutionKeyStored: options.wallet.localExecutionKeyStored,
11277
+ defaultChain: options.config.defaultChain,
11278
+ connectorUrl: options.config.connectorUrl,
11279
+ relayUrl: options.relayUrl || null,
11280
+ nextAction: recommendedCommands2.reapprove,
11281
+ notes: [
11282
+ "A local wallet record exists, but approved session metadata is missing.",
11283
+ "Use the remote reapproval path only when the browser cannot return directly to this terminal."
11284
+ ]
11285
+ });
11286
+ return {
11287
+ scope: "wallet-recovery",
11288
+ nextAction: recommendedCommands2.reapprove,
11289
+ onboardingSummary: onboardingSummary2,
11290
+ summary: {
11291
+ stage: "wallet-recovery",
11292
+ configExists: true,
11293
+ walletExists: true,
11294
+ approvalReady: false,
11295
+ localExecutionKeyStored: options.wallet.localExecutionKeyStored,
11296
+ relayUrl: options.relayUrl || null,
11297
+ nextAction: recommendedCommands2.reapprove,
11298
+ localOnly: true,
11299
+ notes: [
11300
+ "A local wallet record exists, but approved session metadata is missing.",
11301
+ "Use the remote reapproval path only when the browser cannot return directly to this terminal."
11302
+ ]
11303
+ },
11304
+ recommendedCommands: recommendedCommands2
11305
+ };
11306
+ }
11307
+ if (!options.wallet.localExecutionKeyStored) {
11308
+ const attachSigner = buildWalletSignerAttachRecommendedCommand(options.wallet.walletName);
11309
+ const recommendedCommands2 = {
11310
+ ...buildWalletRecoveryRecommendedCommands(options.wallet, options.relayUrl),
11311
+ attachSigner
11312
+ };
11313
+ const onboardingSummary2 = buildOnboardingSummary({
11314
+ stage: "wallet-recovery",
11315
+ localOnly: true,
11316
+ configExists: true,
11317
+ walletExists: true,
11318
+ approvalReady: true,
11319
+ localExecutionKeyStored: false,
11320
+ defaultChain: options.config.defaultChain,
11321
+ connectorUrl: options.config.connectorUrl,
11322
+ relayUrl: options.relayUrl || null,
11323
+ nextAction: attachSigner,
11324
+ notes: [
11325
+ "Approved session metadata exists, but no local execution signer is stored yet.",
11326
+ "Doctor is local-only: it confirms stored signer state, not live chain deployment or gas balance."
11327
+ ]
11328
+ });
11329
+ return {
11330
+ scope: "wallet-recovery",
11331
+ nextAction: attachSigner,
11332
+ onboardingSummary: onboardingSummary2,
11333
+ summary: {
11334
+ stage: "wallet-recovery",
11335
+ configExists: true,
11336
+ walletExists: true,
11337
+ approvalReady: true,
11338
+ localExecutionKeyStored: false,
11339
+ relayUrl: options.relayUrl || null,
11340
+ nextAction: attachSigner,
11341
+ localOnly: true,
11342
+ notes: [
11343
+ "Approved session metadata exists, but no local execution signer is stored yet.",
11344
+ "Doctor is local-only: it confirms stored signer state, not live chain deployment or gas balance."
11345
+ ]
11346
+ },
11347
+ recommendedCommands: recommendedCommands2
11348
+ };
11349
+ }
11350
+ const recommendedCommands = buildWalletReadyRecommendedCommands(options.wallet);
11351
+ const onboardingSummary = buildOnboardingSummary({
11352
+ stage: "wallet-ready",
11353
+ localOnly: true,
11354
+ configExists: true,
11355
+ walletExists: true,
11356
+ approvalReady: true,
11357
+ localExecutionKeyStored: true,
11358
+ defaultChain: options.config.defaultChain,
11359
+ connectorUrl: options.config.connectorUrl,
11360
+ relayUrl: options.relayUrl || null,
11361
+ nextAction: recommendedCommands.next,
11362
+ notes: [
11363
+ "Local config, approval metadata, and a local execution signer are all present.",
11364
+ "Run zk-agent next for the current shortest live path; doctor does not confirm RPC reachability, deployment state, or funding."
11365
+ ]
11366
+ });
11367
+ return {
11368
+ scope: "wallet-ready",
11369
+ nextAction: recommendedCommands.next,
11370
+ onboardingSummary,
11371
+ summary: {
11372
+ stage: "wallet-ready",
11373
+ configExists: true,
11374
+ walletExists: true,
11375
+ approvalReady: true,
11376
+ localExecutionKeyStored: true,
11377
+ relayUrl: options.relayUrl || null,
11378
+ nextAction: recommendedCommands.next,
11379
+ localOnly: true,
11380
+ notes: [
11381
+ "Local config, approval metadata, and a local execution signer are all present.",
11382
+ "Run zk-agent next for the current shortest live path; doctor does not confirm RPC reachability, deployment state, or funding."
11383
+ ]
11384
+ },
11385
+ recommendedCommands
11386
+ };
11387
+ }
11388
+ function buildDoctorLines(input) {
11389
+ const lines = [
11390
+ ["scope", input.scope],
11391
+ ...onboardingSummaryLines(input.onboardingSummary),
11392
+ ["config", input.config ? "present" : "missing"]
11393
+ ];
11394
+ if (input.config) {
11395
+ lines.push(["default chain", input.config.defaultChain]);
11396
+ lines.push(["connector", input.config.connectorUrl]);
11397
+ }
11398
+ lines.push(["wallet", input.walletName]);
11399
+ lines.push(["wallet record", input.wallet ? "present" : "missing"]);
11400
+ if (input.wallet) {
11401
+ lines.push(["address", input.wallet.walletAddress]);
11402
+ lines.push(["account", input.wallet.accountKind]);
11403
+ lines.push(["chain", `${input.wallet.chain} (${input.wallet.chainId})`]);
11404
+ lines.push(["approval", input.wallet.approvalReady ? "present" : "missing"]);
11405
+ lines.push(["local signer", input.wallet.localExecutionKeyStored ? "stored" : "missing"]);
11406
+ lines.push([
11407
+ "legacy payload mirror",
11408
+ input.wallet.legacySessionKeyStored ? "present" : "missing"
11409
+ ]);
11410
+ if (input.wallet.signerType) {
11411
+ lines.push(["signer type", input.wallet.signerType]);
11412
+ }
11413
+ if (input.wallet.signerAddress) {
11414
+ lines.push(["signer address", input.wallet.signerAddress]);
11415
+ }
11416
+ if (input.wallet.signerSource) {
11417
+ lines.push(["signer source", input.wallet.signerSource]);
11418
+ }
11419
+ if (input.wallet.smartAccountProfileId) {
11420
+ lines.push(["smart-account profile", input.wallet.smartAccountProfileId]);
11421
+ }
11422
+ if (input.wallet.syncedAt) {
11423
+ lines.push(["synced at", input.wallet.syncedAt]);
11424
+ }
11425
+ }
11426
+ lines.push(["next", input.nextAction]);
11427
+ if (input.recommendedCommands.createWallet) {
11428
+ lines.push(["create wallet (local)", input.recommendedCommands.createWallet]);
11429
+ }
11430
+ if (input.recommendedCommands.reapprove) {
11431
+ lines.push(["reapprove", input.recommendedCommands.reapprove]);
11432
+ }
11433
+ if (input.recommendedCommands.attachSigner) {
11434
+ lines.push(["attach signer", input.recommendedCommands.attachSigner]);
11435
+ }
11436
+ if (input.recommendedCommands.workflowPay) {
11437
+ lines.push(["workflow pay", input.recommendedCommands.workflowPay]);
11438
+ }
11439
+ if (input.recommendedCommands.relayInspect) {
11440
+ lines.push(["relay inspect", input.recommendedCommands.relayInspect]);
11441
+ }
11442
+ if (input.recommendedCommands.createWalletRemote) {
11443
+ lines.push(["create wallet (remote)", input.recommendedCommands.createWalletRemote]);
11444
+ }
11445
+ if (input.recommendedCommands.reapproveRemote) {
11446
+ lines.push(["reapprove (remote)", input.recommendedCommands.reapproveRemote]);
11447
+ }
11448
+ for (const note of input.summary.notes) {
11449
+ lines.push(["note", note]);
11450
+ }
11451
+ return lines;
11452
+ }
11453
+ function createDoctorCommand() {
11454
+ 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(
11455
+ "--relay-url <url>",
11456
+ "Optional relay URL used only to make remote approval fallback commands concrete"
11457
+ ).action(async (options) => {
11458
+ const walletName = options.wallet?.trim() || "main";
11459
+ const config = await loadProjectConfig();
11460
+ const walletRecord = await loadWalletSession(walletName);
11461
+ const wallet = walletRecord ? summarizeLocalWalletState(walletRecord) : null;
11462
+ const result = buildDoctorResult({
11463
+ walletName,
11464
+ relayUrl: options.relayUrl,
11465
+ wallet,
11466
+ config
11467
+ });
11468
+ const agentProfile = await loadAgentIdentitySummary(walletName);
11469
+ const agentFollowup = buildAgentFollowup(agentProfile, {
11470
+ walletName,
11471
+ walletExists: Boolean(wallet)
11472
+ });
11473
+ printResult(
11474
+ [
11475
+ ...buildDoctorLines({
11476
+ scope: result.scope,
11477
+ walletName,
11478
+ config,
11479
+ wallet,
11480
+ onboardingSummary: result.onboardingSummary,
11481
+ summary: result.summary,
11482
+ recommendedCommands: result.recommendedCommands,
11483
+ nextAction: result.nextAction
11484
+ }),
11485
+ ...agentProfileLines(agentProfile),
11486
+ ...agentFollowupLines(agentFollowup)
11487
+ ],
11488
+ {
11489
+ ok: true,
11490
+ scope: result.scope,
11491
+ walletName,
11492
+ config: config ? {
11493
+ exists: true,
11494
+ defaultChain: config.defaultChain,
11495
+ connectorUrl: config.connectorUrl,
11496
+ provider: config.provider
11497
+ } : {
11498
+ exists: false
11499
+ },
11500
+ wallet,
11501
+ onboardingSummary: result.onboardingSummary,
11502
+ summary: result.summary,
11503
+ agentProfile,
11504
+ agentFollowup,
11505
+ nextAction: result.nextAction,
11506
+ recommendedCommands: result.recommendedCommands
11507
+ }
11508
+ );
11509
+ });
11510
+ }
11511
+
11512
+ // src/commands/agent.ts
11513
+ import { Command as Command5 } from "commander";
10913
11514
  function collectRepeatedString(value, previous) {
10914
11515
  return [...previous, value];
10915
11516
  }
@@ -10994,7 +11595,7 @@ function buildAgentSummaryLines(options) {
10994
11595
  return lines;
10995
11596
  }
10996
11597
  function createAgentCommand() {
10997
- const agent = new Command4("agent").description(
11598
+ const agent = new Command5("agent").description(
10998
11599
  "Manage local agent identity metadata without assuming a zkSync-native onchain reputation standard"
10999
11600
  );
11000
11601
  agent.addHelpText(
@@ -11187,7 +11788,7 @@ function createAgentCommand() {
11187
11788
  }
11188
11789
 
11189
11790
  // src/commands/defaults.ts
11190
- import { Command as Command5 } from "commander";
11791
+ import { Command as Command6 } from "commander";
11191
11792
  function inferPrimaryDiscoveryChain(defaults) {
11192
11793
  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
11794
  }
@@ -11735,7 +12336,7 @@ function buildDefaultsLines(input) {
11735
12336
  return lines;
11736
12337
  }
11737
12338
  function createDefaultsCommand() {
11738
- return new Command5("defaults").description("Show the machine-readable registry of supported, validated, experimental, and manually configured defaults").addHelpText(
12339
+ return new Command6("defaults").description("Show the machine-readable registry of supported, validated, experimental, and manually configured defaults").addHelpText(
11739
12340
  "after",
11740
12341
  [
11741
12342
  "",
@@ -11794,7 +12395,7 @@ function createDefaultsCommand() {
11794
12395
  }
11795
12396
 
11796
12397
  // src/commands/resolve-token.ts
11797
- import { Command as Command6 } from "commander";
12398
+ import { Command as Command7 } from "commander";
11798
12399
  function resolveResolveTokenCommandDeps(deps) {
11799
12400
  return {
11800
12401
  loadWallet: deps?.loadWallet ?? (async (walletName) => {
@@ -11852,7 +12453,7 @@ function buildResolveTokenDiscoverySummary(result) {
11852
12453
  }
11853
12454
  function createResolveTokenCommand(deps) {
11854
12455
  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(
12456
+ return new Command7("resolve-token").description("Resolve a token symbol or address against the configured local-first token registry").addHelpText(
11856
12457
  "after",
11857
12458
  [
11858
12459
  "",
@@ -11986,7 +12587,7 @@ function normalizeSource(value) {
11986
12587
  }
11987
12588
 
11988
12589
  // src/commands/tokens.ts
11989
- import { Command as Command7 } from "commander";
12590
+ import { Command as Command8 } from "commander";
11990
12591
  var provider2 = new ZkSyncWalletProvider();
11991
12592
  function resolveTokensCommandDeps(deps) {
11992
12593
  return {
@@ -12116,7 +12717,7 @@ function buildTokenDiscoverySummary(result) {
12116
12717
  }
12117
12718
  function createTokensCommand(deps) {
12118
12719
  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(
12720
+ return new Command8("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
12721
  "after",
12121
12722
  [
12122
12723
  "",
@@ -12321,7 +12922,7 @@ function normalizeRole2(value) {
12321
12922
  }
12322
12923
 
12323
12924
  // src/commands/relay.ts
12324
- import { Command as Command8 } from "commander";
12925
+ import { Command as Command9 } from "commander";
12325
12926
 
12326
12927
  // src/lib/relay.ts
12327
12928
  import { createServer } from "node:http";
@@ -12829,10 +13430,52 @@ async function startRelayServer(options) {
12829
13430
  }
12830
13431
 
12831
13432
  // src/commands/relay.ts
12832
- function buildRelayServeRecommendedCommands(relayUrl) {
13433
+ function buildRelayServeRecommendedCommands(options) {
13434
+ const commands = {
13435
+ inspectRelay: `zk-agent relay inspect --relay-url ${options.relayUrl}`,
13436
+ createWallet: `zk-agent wallet create --relay-url ${options.relayUrl} --wait-relay --prompt-code`,
13437
+ reapproveWallet: `zk-agent wallet reapprove --name main --relay-url ${options.relayUrl} --wait-relay --prompt-code`
13438
+ };
13439
+ if (options.publicOriginLooksLocal) {
13440
+ return {
13441
+ ...commands,
13442
+ restartWithPublicOrigin: "zk-agent relay serve --public-origin https://relay.example.com"
13443
+ };
13444
+ }
13445
+ return commands;
13446
+ }
13447
+ function buildRelayInspectRecommendedCommands(options) {
13448
+ const commands = {};
13449
+ if (options.compatible) {
13450
+ commands.createWallet = `zk-agent wallet create --relay-url ${options.publicOrigin} --wait-relay --prompt-code`;
13451
+ commands.reapproveWallet = `zk-agent wallet reapprove --name main --relay-url ${options.publicOrigin} --wait-relay --prompt-code`;
13452
+ }
13453
+ if (options.publicOriginLooksLocal) {
13454
+ commands.restartWithPublicOrigin = "zk-agent relay serve --public-origin https://relay.example.com";
13455
+ }
13456
+ return commands;
13457
+ }
13458
+ function buildRelayHostedReadinessSummary(options) {
13459
+ let status;
13460
+ if (!options.compatible) {
13461
+ status = "incompatible";
13462
+ } else if (options.publicOriginLooksLocal && options.connectorUiAvailable !== true) {
13463
+ status = "needs-public-origin-and-ui";
13464
+ } else if (options.publicOriginLooksLocal) {
13465
+ status = "needs-public-origin";
13466
+ } else if (options.connectorUiAvailable !== true) {
13467
+ status = "needs-connector-ui";
13468
+ } else {
13469
+ status = "ready";
13470
+ }
12833
13471
  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`
13472
+ status,
13473
+ compatible: options.compatible,
13474
+ hostedApprovalReady: options.hostedShareRedirectReady,
13475
+ publicOriginConfigured: options.publicOriginSource === "configured",
13476
+ publicOriginLooksLocal: options.publicOriginLooksLocal,
13477
+ connectorUiAvailable: options.connectorUiAvailable,
13478
+ singleHostFileState: options.deploymentSummary.singleHostFileState
12836
13479
  };
12837
13480
  }
12838
13481
  function buildAdvertisedRelayBases(publicOrigin) {
@@ -12841,6 +13484,24 @@ function buildAdvertisedRelayBases(publicOrigin) {
12841
13484
  statusApiBaseUrl: `${publicOrigin}/api/requests`
12842
13485
  };
12843
13486
  }
13487
+ function buildRelayApprovalEndpointSummary(options) {
13488
+ let status;
13489
+ if (options.publicOriginLooksLocal) {
13490
+ status = "local-public-origin";
13491
+ } else if (options.relayUrlMatchesPublicOrigin === false) {
13492
+ status = "hosted-public-origin-via-proxy";
13493
+ } else {
13494
+ status = "hosted-public-origin";
13495
+ }
13496
+ return {
13497
+ status,
13498
+ publicOriginConfigured: options.publicOriginSource === "configured",
13499
+ publicOriginLooksLocal: options.publicOriginLooksLocal,
13500
+ relayUrlMatchesPublicOrigin: options.relayUrlMatchesPublicOrigin,
13501
+ shareLinkBaseUrl: options.shareLinkBaseUrl,
13502
+ statusApiBaseUrl: options.statusApiBaseUrl
13503
+ };
13504
+ }
12844
13505
  function isRecord3(value) {
12845
13506
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
12846
13507
  }
@@ -13026,6 +13687,21 @@ function buildRelayInspectPayload(relayUrl, rawHealth) {
13026
13687
  deploymentScope,
13027
13688
  sameHostRestartPersists
13028
13689
  });
13690
+ const approvalEndpointSummary = buildRelayApprovalEndpointSummary({
13691
+ publicOriginSource,
13692
+ publicOriginLooksLocal,
13693
+ relayUrlMatchesPublicOrigin,
13694
+ shareLinkBaseUrl,
13695
+ statusApiBaseUrl
13696
+ });
13697
+ const hostedReadinessSummary = buildRelayHostedReadinessSummary({
13698
+ compatible,
13699
+ publicOriginSource,
13700
+ publicOriginLooksLocal,
13701
+ connectorUiAvailable,
13702
+ hostedShareRedirectReady,
13703
+ deploymentSummary
13704
+ });
13029
13705
  const notes = [
13030
13706
  ...relayHostedReadinessNotes({
13031
13707
  compatible,
@@ -13065,16 +13741,22 @@ function buildRelayInspectPayload(relayUrl, rawHealth) {
13065
13741
  relayUrlMatchesOrigin,
13066
13742
  relayUrlMatchesPublicOrigin,
13067
13743
  publicOriginLooksLocal,
13744
+ approvalEndpointSummary,
13068
13745
  connectorUiAvailable,
13069
13746
  hostedShareRedirectReady,
13747
+ hostedReadinessSummary,
13070
13748
  deploymentSummary,
13071
13749
  capabilities: health?.capabilities || [],
13072
- recommendedCommands: compatible ? buildRelayServeRecommendedCommands(publicOrigin) : {},
13750
+ recommendedCommands: buildRelayInspectRecommendedCommands({
13751
+ publicOrigin,
13752
+ compatible,
13753
+ publicOriginLooksLocal
13754
+ }),
13073
13755
  notes
13074
13756
  };
13075
13757
  }
13076
13758
  function createRelayCommand() {
13077
- const relay = new Command8("relay").description("Run the local connector relay prototype server");
13759
+ const relay = new Command9("relay").description("Run the local connector relay prototype server");
13078
13760
  relay.addHelpText(
13079
13761
  "after",
13080
13762
  [
@@ -13112,7 +13794,10 @@ function createRelayCommand() {
13112
13794
  const connectorUiAvailable = server.connectorUiAvailable;
13113
13795
  const hostedShareRedirectReady = connectorUiAvailable && !publicOriginLooksLocal;
13114
13796
  const { shareLinkBaseUrl, statusApiBaseUrl } = buildAdvertisedRelayBases(publicOrigin);
13115
- const recommendedCommands = buildRelayServeRecommendedCommands(publicOrigin);
13797
+ const recommendedCommands = buildRelayServeRecommendedCommands({
13798
+ relayUrl: publicOrigin,
13799
+ publicOriginLooksLocal
13800
+ });
13116
13801
  const deploymentSummary = buildRelayDeploymentSummary({
13117
13802
  origin: server.origin,
13118
13803
  publicOrigin,
@@ -13126,6 +13811,21 @@ function createRelayCommand() {
13126
13811
  deploymentScope: "single-host",
13127
13812
  sameHostRestartPersists: true
13128
13813
  });
13814
+ const hostedReadinessSummary = buildRelayHostedReadinessSummary({
13815
+ compatible: true,
13816
+ publicOriginSource,
13817
+ publicOriginLooksLocal,
13818
+ connectorUiAvailable,
13819
+ hostedShareRedirectReady,
13820
+ deploymentSummary
13821
+ });
13822
+ const approvalEndpointSummary = buildRelayApprovalEndpointSummary({
13823
+ publicOriginSource,
13824
+ publicOriginLooksLocal,
13825
+ relayUrlMatchesPublicOrigin: null,
13826
+ shareLinkBaseUrl,
13827
+ statusApiBaseUrl
13828
+ });
13129
13829
  const notes = relayHostedReadinessNotes({
13130
13830
  compatible: true,
13131
13831
  publicOrigin,
@@ -13144,6 +13844,8 @@ function createRelayCommand() {
13144
13844
  shareLinkBaseUrl,
13145
13845
  statusApiBaseUrl,
13146
13846
  publicOriginLooksLocal,
13847
+ approvalEndpointSummary,
13848
+ hostedReadinessSummary,
13147
13849
  deploymentSummary,
13148
13850
  port: server.port,
13149
13851
  healthUrl: `${server.origin}/health`,
@@ -13179,13 +13881,19 @@ function createRelayCommand() {
13179
13881
  );
13180
13882
  humanLine("share-link base", shareLinkBaseUrl);
13181
13883
  humanLine("status api base", statusApiBaseUrl);
13884
+ humanLine("approval endpoint", approvalEndpointSummary.status);
13182
13885
  humanLine("health", `${server.origin}/health`);
13886
+ humanLine("hosted readiness", hostedReadinessSummary.status);
13183
13887
  humanLine("hosted ready", hostedShareRedirectReady ? "yes" : "no");
13184
13888
  if (connectorUiAvailable !== null) {
13185
13889
  humanLine("connector ui", connectorUiAvailable ? "available" : "missing");
13186
13890
  }
13891
+ humanLine("inspect relay", recommendedCommands.inspectRelay);
13187
13892
  humanLine("create wallet", recommendedCommands.createWallet);
13188
13893
  humanLine("reapprove wallet", recommendedCommands.reapproveWallet);
13894
+ if (recommendedCommands.restartWithPublicOrigin) {
13895
+ humanLine("restart with public origin", recommendedCommands.restartWithPublicOrigin);
13896
+ }
13189
13897
  for (const note of notes) {
13190
13898
  humanLine("note", note);
13191
13899
  }
@@ -13247,6 +13955,8 @@ function createRelayCommand() {
13247
13955
  }
13248
13956
  humanLine("share-link base", payload.shareLinkBaseUrl);
13249
13957
  humanLine("status api base", payload.statusApiBaseUrl);
13958
+ humanLine("approval endpoint", payload.approvalEndpointSummary.status);
13959
+ humanLine("hosted readiness", payload.hostedReadinessSummary.status);
13250
13960
  if (payload.relayUrlMatchesOrigin !== null) {
13251
13961
  humanLine("relay url matches origin", payload.relayUrlMatchesOrigin ? "yes" : "no");
13252
13962
  }
@@ -13272,6 +13982,12 @@ function createRelayCommand() {
13272
13982
  humanLine("reapprove wallet", payload.recommendedCommands.reapproveWallet);
13273
13983
  }
13274
13984
  }
13985
+ if (payload.recommendedCommands.restartWithPublicOrigin) {
13986
+ humanLine(
13987
+ "restart with public origin",
13988
+ payload.recommendedCommands.restartWithPublicOrigin
13989
+ );
13990
+ }
13275
13991
  for (const note of payload.notes) {
13276
13992
  humanLine("note", note);
13277
13993
  }
@@ -13282,7 +13998,7 @@ function createRelayCommand() {
13282
13998
  // src/commands/wallet.ts
13283
13999
  import { createServer as createServer2 } from "node:http";
13284
14000
  import { createInterface } from "node:readline/promises";
13285
- import { Command as Command9 } from "commander";
14001
+ import { Command as Command10 } from "commander";
13286
14002
 
13287
14003
  // ../account-profiles/src/profiles.ts
13288
14004
  import fs8 from "node:fs";
@@ -15217,7 +15933,9 @@ async function buildRelayStatusFollowUp(options) {
15217
15933
  walletName: options.relay.request?.walletName,
15218
15934
  relayUrl: options.relayUrl,
15219
15935
  paymasterMode: options.relay.request?.requestedPaymasterMode,
15220
- accountKind: options.relay.request?.requestedAccountKind
15936
+ accountKind: options.relay.request?.requestedAccountKind,
15937
+ sessionPolicies: options.relay.request?.policies,
15938
+ requestCreatedAt: options.relay.request?.createdAt
15221
15939
  });
15222
15940
  }
15223
15941
  if (options.relay.approval_ready) {
@@ -15262,11 +15980,18 @@ async function buildRelayExpiredRecoveryCommands(options) {
15262
15980
  };
15263
15981
  }
15264
15982
  const existingWallet = await loadWalletSession(walletName);
15265
- const reissueRemoteApproval = existingWallet ? buildWalletReapproveRemoteRecommendedCommand(walletName, options.relayUrl) : buildWalletCreateRemoteRecommendedCommand(
15983
+ const reissueRemoteApproval = existingWallet ? buildWalletReapproveRemoteRecommendedCommand(walletName, options.relayUrl, {
15984
+ sessionPolicies: options.sessionPolicies,
15985
+ requestCreatedAt: options.requestCreatedAt
15986
+ }) : buildWalletCreateRemoteRecommendedCommand(
15266
15987
  options.relayUrl,
15267
15988
  options.paymasterMode,
15268
15989
  walletName,
15269
- options.accountKind
15990
+ options.accountKind,
15991
+ {
15992
+ sessionPolicies: options.sessionPolicies,
15993
+ requestCreatedAt: options.requestCreatedAt
15994
+ }
15270
15995
  );
15271
15996
  return {
15272
15997
  nextAction: reissueRemoteApproval,
@@ -15274,7 +15999,7 @@ async function buildRelayExpiredRecoveryCommands(options) {
15274
15999
  relayInspect,
15275
16000
  reissueRemoteApproval
15276
16001
  },
15277
- note: "Relay approval expired. Reissue the remote request. If the original request used scoped session flags, add those same policy flags again."
16002
+ note: "Relay approval expired. Reissue the remote request. The recovery command preserves any CLI-expressible session-policy flags from the expired request."
15278
16003
  };
15279
16004
  }
15280
16005
  function buildRelayApprovalTimeoutError(options) {
@@ -15318,7 +16043,9 @@ async function buildRelayApprovalExpiredError(options) {
15318
16043
  walletName: options.walletName,
15319
16044
  relayUrl: options.relayUrl,
15320
16045
  paymasterMode: options.paymasterMode,
15321
- accountKind: options.accountKind
16046
+ accountKind: options.accountKind,
16047
+ sessionPolicies: options.sessionPolicies,
16048
+ requestCreatedAt: options.requestCreatedAt
15322
16049
  });
15323
16050
  return new AgentError(
15324
16051
  "RELAY_APPROVAL_EXPIRED",
@@ -15565,7 +16292,9 @@ async function finalizePublishedRelayWalletRequest(options) {
15565
16292
  walletName: options.walletRequest.walletName,
15566
16293
  relayUrl: options.relayUrl,
15567
16294
  paymasterMode: options.walletRequest.requestedPaymasterMode,
15568
- accountKind: options.walletRequest.requestedAccountKind
16295
+ accountKind: options.walletRequest.requestedAccountKind,
16296
+ sessionPolicies: options.walletRequest.policies,
16297
+ requestCreatedAt: options.walletRequest.createdAt
15569
16298
  });
15570
16299
  }
15571
16300
  throw error;
@@ -15936,32 +16665,32 @@ async function printBuiltinSmartAccountProfiles() {
15936
16665
  }
15937
16666
  function createWalletCommand(deps) {
15938
16667
  const resolvedDeps = resolveWalletCommandDeps(deps);
15939
- const wallet = new Command9("wallet").description(
16668
+ const wallet = new Command10("wallet").description(
15940
16669
  "Create, inspect, and recover local-first wallet sessions"
15941
16670
  );
15942
- const request = new Command9("request").description("Inspect and finalize pending wallet requests");
15943
- const signer = new Command9("signer").description(
16671
+ const request = new Command10("request").description("Inspect and finalize pending wallet requests");
16672
+ const signer = new Command10("signer").description(
15944
16673
  "Inspect and manage the stored local execution signer for a wallet"
15945
16674
  );
15946
- const smartAccount = new Command9("smart-account").description(
16675
+ const smartAccount = new Command10("smart-account").description(
15947
16676
  "Predict and deploy zkSync smart-account contracts from a supplied artifact or built-in profile"
15948
16677
  );
15949
- const sedLite = new Command9("sed-lite").description(
16678
+ const sedLite = new Command10("sed-lite").description(
15950
16679
  "Inspect and manage the SED modular smart-account profile"
15951
16680
  );
15952
- const nativeCapHook = new Command9("native-cap-hook").description(
16681
+ const nativeCapHook = new Command10("native-cap-hook").description(
15953
16682
  "Inspect and manage the first SED Lite validation-hook policy: native per-transaction spend caps"
15954
16683
  );
15955
- const targetAllowlistHook = new Command9("target-allowlist-hook").description(
16684
+ const targetAllowlistHook = new Command10("target-allowlist-hook").description(
15956
16685
  "Inspect and manage the SED Lite validation-hook policy that restricts transactions to an allowlisted target set"
15957
16686
  );
15958
- const selectorAllowlistHook = new Command9("selector-allowlist-hook").description(
16687
+ const selectorAllowlistHook = new Command10("selector-allowlist-hook").description(
15959
16688
  "Inspect and manage the SED Lite validation-hook policy that restricts contract calls to allowlisted target and selector pairs"
15960
16689
  );
15961
- const dailySpendLimit = new Command9("daily-spend-limit").description(
16690
+ const dailySpendLimit = new Command10("daily-spend-limit").description(
15962
16691
  "Read and update the native-token daily spend limit used by the built-in daily-spend-limit smart-account profile"
15963
16692
  );
15964
- const paymaster = new Command9("paymaster").description(
16693
+ const paymaster = new Command10("paymaster").description(
15965
16694
  "Manage saved paymaster defaults for stored wallets"
15966
16695
  );
15967
16696
  wallet.addHelpText(
@@ -15969,6 +16698,9 @@ function createWalletCommand(deps) {
15969
16698
  [
15970
16699
  "",
15971
16700
  "Local-first wallet path:",
16701
+ " Use this layer when the blocker is specifically about wallet approval or signer state.",
16702
+ " Otherwise start with `zk-agent next` or `zk-agent doctor`.",
16703
+ "",
15972
16704
  " First bootstrap:",
15973
16705
  " zk-agent wallet create --await-local",
15974
16706
  " zk-agent next",
@@ -15989,7 +16721,8 @@ function createWalletCommand(deps) {
15989
16721
  " zk-agent relay inspect --relay-url <url>",
15990
16722
  " zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
15991
16723
  " zk-agent wallet reapprove --name main --relay-url <url> --wait-relay --prompt-code",
15992
- " zk-agent next"
16724
+ " zk-agent next",
16725
+ " Use this only when the browser is not colocated with the terminal."
15993
16726
  ].join("\n")
15994
16727
  );
15995
16728
  request.addHelpText(
@@ -16060,7 +16793,28 @@ function createWalletCommand(deps) {
16060
16793
  ).option("--disallow-transfers", "Disable transfer capability for the approved session").option(
16061
16794
  "--disallow-contract-calls",
16062
16795
  "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(
16796
+ ).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(
16797
+ "after",
16798
+ [
16799
+ "",
16800
+ "Default wallet-create path:",
16801
+ " Keep `--await-local` as the local-first baseline when the browser and terminal are colocated.",
16802
+ "",
16803
+ " Fresh bootstrap:",
16804
+ " zk-agent next",
16805
+ " zk-agent wallet create --await-local",
16806
+ " zk-agent next",
16807
+ "",
16808
+ " Remote-browser fallback:",
16809
+ " zk-agent relay inspect --relay-url <url>",
16810
+ " zk-agent wallet create --relay-url <url> --wait-relay --prompt-code",
16811
+ " zk-agent next",
16812
+ "",
16813
+ "Environment note:",
16814
+ " No custom .env is required to create the wallet request itself.",
16815
+ " Add RPC env vars later, before live reads or broadcasts."
16816
+ ].join("\n")
16817
+ ).action(
16064
16818
  async (options) => {
16065
16819
  const config = await loadProjectConfig();
16066
16820
  const chain = options.chain || config?.defaultChain || "zksync-era";
@@ -16243,7 +16997,27 @@ function createWalletCommand(deps) {
16243
16997
  ).option("--disallow-transfers", "Disable transfer capability for the approved session").option(
16244
16998
  "--disallow-contract-calls",
16245
16999
  "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(
17000
+ ).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(
17001
+ "after",
17002
+ [
17003
+ "",
17004
+ "Default wallet-reapprove path:",
17005
+ " Use this when the wallet already exists locally but its approval/session must be refreshed.",
17006
+ "",
17007
+ " Colocated browser + terminal:",
17008
+ " zk-agent wallet reapprove --name main --await-local",
17009
+ " zk-agent next",
17010
+ "",
17011
+ " Remote-browser fallback:",
17012
+ " zk-agent relay inspect --relay-url <url>",
17013
+ " zk-agent wallet reapprove --name main --relay-url <url> --wait-relay --prompt-code",
17014
+ " zk-agent next",
17015
+ "",
17016
+ "Environment note:",
17017
+ " No custom .env is required to create the reapproval request itself.",
17018
+ " Add RPC env vars later, before live reads or broadcasts."
17019
+ ].join("\n")
17020
+ ).action(
16247
17021
  async (options) => {
16248
17022
  const walletRecord = await requireWalletRecord(options.name);
16249
17023
  const request2 = await createWalletReapprovalRequest({
@@ -16526,14 +17300,45 @@ function createWalletCommand(deps) {
16526
17300
  const walletRecord = await loadWalletSession(options.name);
16527
17301
  if (!walletRecord) throw new Error(`Wallet not found: ${options.name}`);
16528
17302
  const { inspection, summary } = await loadWalletStatusSummary(walletRecord, resolvedDeps);
16529
- printResult(walletStatusLines(inspection, summary), { ok: true, inspection, summary });
17303
+ const recommendedCommands = buildWalletNextRecommendedCommands(
17304
+ walletRecord.walletName,
17305
+ summary,
17306
+ resolveEffectivePaymasterSelection(walletRecord)?.mode
17307
+ );
17308
+ const tokenDiscoverySummary = buildWalletTokenDiscoverySummary({
17309
+ walletName: walletRecord.walletName,
17310
+ chain: summary.chain,
17311
+ nextAction: summary.recommendedCommand,
17312
+ paymasterMode: resolveEffectivePaymasterSelection(walletRecord)?.mode,
17313
+ recommendedCommands
17314
+ });
17315
+ printResult(
17316
+ [
17317
+ ...walletStatusLines(inspection, summary),
17318
+ ["discover assets", recommendedCommands.discoverAssets],
17319
+ ["discover owned tokens", recommendedCommands.discoverOwnedTokens],
17320
+ ...recommendedCommands.discoverPaymasterTokens ? [["discover paymaster tokens", recommendedCommands.discoverPaymasterTokens]] : [],
17321
+ ["discover tokens", recommendedCommands.discoverTokens],
17322
+ ...recommendedCommands.inspectPaymasterToken ? [["inspect paymaster token", recommendedCommands.inspectPaymasterToken]] : [],
17323
+ ["inspect token", recommendedCommands.inspectToken],
17324
+ ["wallet next", buildWalletNextRecommendedCommand(walletRecord.walletName)]
17325
+ ],
17326
+ {
17327
+ ok: true,
17328
+ inspection,
17329
+ summary,
17330
+ tokenDiscoverySummary,
17331
+ recommendedCommands
17332
+ }
17333
+ );
16530
17334
  });
16531
17335
  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
17336
  const walletRecord = await requireWalletRecord(options.name);
16533
17337
  const { inspection, summary } = await loadWalletStatusSummary(walletRecord, resolvedDeps);
16534
17338
  const recommendedCommands = buildWalletNextRecommendedCommands(
16535
17339
  walletRecord.walletName,
16536
- summary
17340
+ summary,
17341
+ resolveEffectivePaymasterSelection(walletRecord)?.mode
16537
17342
  );
16538
17343
  const tokenDiscoverySummary = buildWalletTokenDiscoverySummary({
16539
17344
  walletName: walletRecord.walletName,
@@ -16547,7 +17352,9 @@ function createWalletCommand(deps) {
16547
17352
  ...walletNextLines(summary),
16548
17353
  ["discover assets", recommendedCommands.discoverAssets],
16549
17354
  ["discover owned tokens", recommendedCommands.discoverOwnedTokens],
17355
+ ...recommendedCommands.discoverPaymasterTokens ? [["discover paymaster tokens", recommendedCommands.discoverPaymasterTokens]] : [],
16550
17356
  ["discover tokens", recommendedCommands.discoverTokens],
17357
+ ...recommendedCommands.inspectPaymasterToken ? [["inspect paymaster token", recommendedCommands.inspectPaymasterToken]] : [],
16551
17358
  ["inspect token", recommendedCommands.inspectToken],
16552
17359
  ["status command", recommendedCommands.walletStatus]
16553
17360
  ],
@@ -18512,7 +19319,7 @@ function createWalletCommand(deps) {
18512
19319
 
18513
19320
  // src/commands/workflow.ts
18514
19321
  import { randomBytes as randomBytes4 } from "node:crypto";
18515
- import { Command as Command10 } from "commander";
19322
+ import { Command as Command11 } from "commander";
18516
19323
  var defaultProvider2 = new ZkSyncWalletProvider();
18517
19324
  var defaultDefiProvider2 = new ZkSyncDefiProvider({
18518
19325
  walletWriter: defaultProvider2
@@ -19152,7 +19959,69 @@ function withAgentProfileLines(lines, agentProfile, agentFollowup) {
19152
19959
  ...agentFollowup ? agentFollowupLines(agentFollowup) : []
19153
19960
  ];
19154
19961
  }
19155
- async function printWorkflowRunCommandResult(execution) {
19962
+ function serializeWorkflowFundingProgress(fundingProgress) {
19963
+ return fundingProgress ? {
19964
+ kind: fundingProgress.kind,
19965
+ txHash: fundingProgress.txHash,
19966
+ status: fundingProgress.status,
19967
+ terminal: fundingProgress.terminal,
19968
+ finalized: fundingProgress.finalized
19969
+ } : void 0;
19970
+ }
19971
+ function buildWorkflowRuntimeSummary(options) {
19972
+ if (!options.status && !options.result) {
19973
+ throw new Error("Workflow runtime summary requires a workflow status or execution result.");
19974
+ }
19975
+ const nextCommand = options.nextCommand ?? options.result?.nextCommand ?? options.status?.fundingProgress?.nextCommand ?? options.status?.recommendedCommand;
19976
+ return {
19977
+ status: options.result?.stage ?? options.status?.status ?? "blocked",
19978
+ readyForGoal: options.result ? options.result.stage === "goal-executed" : Boolean(options.status?.readyForGoal),
19979
+ nextCommand,
19980
+ blockingActionIds: options.status?.blockingActionIds ?? [],
19981
+ fundingProgress: serializeWorkflowFundingProgress(options.status?.fundingProgress)
19982
+ };
19983
+ }
19984
+ function buildWorkflowEntrySummary(input) {
19985
+ if (input.plan) {
19986
+ return {
19987
+ entrypoint: "workflow",
19988
+ command: input.command,
19989
+ source: input.source || null,
19990
+ workflowRequestId: input.requestId || null,
19991
+ walletName: input.plan.walletName,
19992
+ intent: input.plan.intent,
19993
+ runtimeStatus: input.plan.status,
19994
+ readyForGoal: input.plan.readyForGoal,
19995
+ walletApprovalStatus: null,
19996
+ checkpointPersisted: typeof input.checkpointPersisted === "boolean" ? input.checkpointPersisted : null,
19997
+ nextAction: input.nextCommand || input.plan.recommendedCommand || null
19998
+ };
19999
+ }
20000
+ const runtimeSummary = buildWorkflowRuntimeSummary({
20001
+ status: input.status,
20002
+ result: input.result,
20003
+ nextCommand: input.nextCommand
20004
+ });
20005
+ const walletName = input.result?.walletName ?? input.status?.walletName;
20006
+ const intent = input.result?.intent ?? input.status?.intent;
20007
+ if (!walletName || !intent) {
20008
+ throw new Error("Workflow entry summary requires workflow status or execution metadata.");
20009
+ }
20010
+ return {
20011
+ entrypoint: "workflow",
20012
+ command: input.command,
20013
+ source: input.source || null,
20014
+ workflowRequestId: input.requestId || null,
20015
+ walletName,
20016
+ intent,
20017
+ runtimeStatus: runtimeSummary.status,
20018
+ readyForGoal: runtimeSummary.readyForGoal,
20019
+ walletApprovalStatus: buildWorkflowWalletApprovalSummary(input.walletApproval)?.status || null,
20020
+ checkpointPersisted: typeof input.checkpointPersisted === "boolean" ? input.checkpointPersisted : null,
20021
+ nextAction: runtimeSummary.nextCommand || null
20022
+ };
20023
+ }
20024
+ async function printWorkflowRunCommandResult(execution, command) {
19156
20025
  if (execution.result) {
19157
20026
  const agentProfile2 = await loadWorkflowAgentProfile(execution.result.walletName);
19158
20027
  const agentFollowup2 = buildAgentFollowup(agentProfile2, {
@@ -19175,6 +20044,21 @@ async function printWorkflowRunCommandResult(execution) {
19175
20044
  paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.goal),
19176
20045
  recommendedCommands: recommendedCommands2
19177
20046
  });
20047
+ const summary2 = buildWorkflowRuntimeSummary({
20048
+ status: execution.status,
20049
+ result: execution.result,
20050
+ nextCommand: execution.result.nextCommand
20051
+ });
20052
+ const workflowEntrySummary2 = buildWorkflowEntrySummary({
20053
+ command,
20054
+ source: execution.requestId ? "checkpoint" : "input",
20055
+ requestId: execution.requestId,
20056
+ checkpointPersisted: Boolean(execution.checkpoint || execution.requestId),
20057
+ status: execution.status,
20058
+ result: execution.result,
20059
+ walletApproval: execution.walletApproval,
20060
+ nextCommand: execution.result.nextCommand
20061
+ });
19178
20062
  printResult(
19179
20063
  prependWorkflowRequestId(
19180
20064
  execution.requestId,
@@ -19191,47 +20075,62 @@ async function printWorkflowRunCommandResult(execution) {
19191
20075
  {
19192
20076
  ok: true,
19193
20077
  ...serializeWorkflowRequestMeta(execution.requestId),
20078
+ workflowEntrySummary: workflowEntrySummary2,
19194
20079
  agentProfile: agentProfile2,
19195
20080
  agentFollowup: agentFollowup2,
20081
+ summary: summary2,
19196
20082
  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),
20083
+ ...serializeWorkflowWalletApprovalOutput(execution.walletApproval),
19202
20084
  tokenDiscoverySummary: tokenDiscoverySummary2,
19203
20085
  recommendedCommands: recommendedCommands2
19204
20086
  }
19205
20087
  );
19206
20088
  return;
19207
20089
  }
19208
- const agentProfile = await loadWorkflowAgentProfile(execution.status.walletName);
20090
+ const status = execution.status;
20091
+ if (!status) {
20092
+ throw new Error("Workflow run result is missing both execution result and status.");
20093
+ }
20094
+ const agentProfile = await loadWorkflowAgentProfile(status.walletName);
19209
20095
  const agentFollowup = buildAgentFollowup(agentProfile, {
19210
- walletName: execution.status.walletName,
20096
+ walletName: status.walletName,
19211
20097
  walletExists: true
19212
20098
  });
19213
20099
  const recommendedCommands = buildWorkflowRuntimeRecommendedCommands({
19214
20100
  requestId: execution.requestId,
19215
- walletName: execution.status.walletName,
19216
- nextAction: execution.status.recommendedCommand,
19217
- chain: execution.status.plan.chain,
19218
- intent: execution.status.intent,
20101
+ walletName: status.walletName,
20102
+ nextAction: status.recommendedCommand,
20103
+ chain: status.plan.chain,
20104
+ intent: status.intent,
19219
20105
  paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal)
19220
20106
  });
19221
20107
  const tokenDiscoverySummary = buildWorkflowTokenDiscoverySummary({
19222
- walletName: execution.status.walletName,
19223
- chain: execution.status.plan.chain,
19224
- intent: execution.status.intent,
19225
- nextAction: execution.status.recommendedCommand,
20108
+ walletName: status.walletName,
20109
+ chain: status.plan.chain,
20110
+ intent: status.intent,
20111
+ nextAction: status.recommendedCommand,
19226
20112
  paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal),
19227
20113
  recommendedCommands
19228
20114
  });
20115
+ const summary = buildWorkflowRuntimeSummary({
20116
+ status,
20117
+ nextCommand: status.recommendedCommand
20118
+ });
20119
+ const workflowEntrySummary = buildWorkflowEntrySummary({
20120
+ command,
20121
+ source: execution.requestId ? "checkpoint" : "input",
20122
+ requestId: execution.requestId,
20123
+ checkpointPersisted: Boolean(execution.checkpoint || execution.requestId),
20124
+ status,
20125
+ walletApproval: execution.walletApproval,
20126
+ nextCommand: status.recommendedCommand
20127
+ });
19229
20128
  printResult(
19230
20129
  prependWorkflowRequestId(
19231
20130
  execution.requestId,
19232
20131
  withAgentProfileLines(
19233
20132
  [
19234
- ...workflowStatusLines(execution.status),
20133
+ ...workflowStatusLines(status),
19235
20134
  ...workflowWalletApprovalLines(execution.walletApproval),
19236
20135
  ...workflowFollowupLines(recommendedCommands)
19237
20136
  ],
@@ -19242,15 +20141,13 @@ async function printWorkflowRunCommandResult(execution) {
19242
20141
  {
19243
20142
  ok: true,
19244
20143
  ...serializeWorkflowRequestMeta(execution.requestId),
20144
+ workflowEntrySummary,
19245
20145
  agentProfile,
19246
20146
  agentFollowup,
19247
- status: execution.status,
20147
+ summary,
20148
+ status,
19248
20149
  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),
20150
+ ...serializeWorkflowWalletApprovalOutput(execution.walletApproval),
19254
20151
  tokenDiscoverySummary,
19255
20152
  recommendedCommands
19256
20153
  }
@@ -19504,7 +20401,7 @@ async function executeWorkflowAutoCommand(options, deps = resolveWorkflowCommand
19504
20401
  walletApproval
19505
20402
  };
19506
20403
  }
19507
- async function printWorkflowAutoCommandResult(execution) {
20404
+ async function printWorkflowAutoCommandResult(execution, command) {
19508
20405
  const agentProfile = await loadWorkflowAgentProfile(execution.status.walletName);
19509
20406
  const agentFollowup = buildAgentFollowup(agentProfile, {
19510
20407
  walletName: execution.status.walletName,
@@ -19527,6 +20424,21 @@ async function printWorkflowAutoCommandResult(execution) {
19527
20424
  paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.goal) ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal),
19528
20425
  recommendedCommands
19529
20426
  });
20427
+ const summary = buildWorkflowRuntimeSummary({
20428
+ status: execution.status,
20429
+ result: execution.result,
20430
+ nextCommand: nextAction
20431
+ });
20432
+ const workflowEntrySummary = buildWorkflowEntrySummary({
20433
+ command,
20434
+ source: execution.source,
20435
+ requestId: execution.requestId,
20436
+ checkpointPersisted: execution.checkpointPersisted,
20437
+ status: execution.status,
20438
+ result: execution.result,
20439
+ walletApproval: execution.walletApproval,
20440
+ nextCommand: nextAction
20441
+ });
19530
20442
  const summaryLines = [
19531
20443
  ["source", execution.source],
19532
20444
  ["action", execution.action],
@@ -19553,16 +20465,14 @@ async function printWorkflowAutoCommandResult(execution) {
19553
20465
  action: execution.action,
19554
20466
  checkpointPersisted: execution.checkpointPersisted,
19555
20467
  ...serializeWorkflowRequestMeta(execution.requestId),
20468
+ workflowEntrySummary,
19556
20469
  agentProfile,
19557
20470
  agentFollowup,
20471
+ summary,
19558
20472
  status: execution.status,
19559
20473
  result: execution.result,
19560
20474
  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),
20475
+ ...serializeWorkflowWalletApprovalOutput(execution.walletApproval),
19566
20476
  tokenDiscoverySummary,
19567
20477
  recommendedCommands
19568
20478
  }
@@ -19760,6 +20670,7 @@ function serializeWalletApproval(walletApproval) {
19760
20670
  if (!walletApproval) return void 0;
19761
20671
  return {
19762
20672
  ...walletApproval,
20673
+ summary: buildWorkflowWalletApprovalSummary(walletApproval),
19763
20674
  ...workflowWalletApprovalRelayAliases(walletApproval.relay, {
19764
20675
  shareLinkBaseField: "relayShareLinkBaseUrl",
19765
20676
  statusApiBaseField: "relayStatusApiBaseUrl"
@@ -19769,6 +20680,34 @@ function serializeWalletApproval(walletApproval) {
19769
20680
  wallet: walletApproval.wallet ? sanitizeWalletRecord(walletApproval.wallet) : void 0
19770
20681
  };
19771
20682
  }
20683
+ function buildWorkflowWalletApprovalSummary(walletApproval) {
20684
+ if (!walletApproval) return void 0;
20685
+ let status = "await-local";
20686
+ if (walletApproval.stage === "approved") {
20687
+ status = "approved";
20688
+ } else if (walletApproval.recommendedCommands?.relayStatus && walletApproval.nextCommand === walletApproval.recommendedCommands.relayStatus) {
20689
+ status = "relay-pending";
20690
+ }
20691
+ return {
20692
+ status,
20693
+ walletRequestId: walletApproval.request.requestId,
20694
+ reusedRequest: walletApproval.reusedRequest,
20695
+ relayPublished: Boolean(walletApproval.relay),
20696
+ nextAction: walletApproval.nextCommand,
20697
+ afterApproval: walletApproval.recommendedCommands?.afterApproval || null,
20698
+ afterApprovalStatus: walletApproval.recommendedCommands?.afterApprovalStatus || null
20699
+ };
20700
+ }
20701
+ function serializeWorkflowWalletApprovalOutput(walletApproval) {
20702
+ return {
20703
+ walletRequestId: walletApproval?.request.requestId,
20704
+ walletApprovalRelay: walletApproval?.relay,
20705
+ ...workflowWalletApprovalRelayAliases(walletApproval?.relay),
20706
+ walletApprovalRecommendedCommands: walletApproval?.recommendedCommands,
20707
+ walletApprovalSummary: buildWorkflowWalletApprovalSummary(walletApproval),
20708
+ walletApproval: serializeWalletApproval(walletApproval)
20709
+ };
20710
+ }
19772
20711
  function workflowWalletApprovalRelayAliases(relay, fieldNames = {
19773
20712
  shareLinkBaseField: "walletApprovalRelayShareLinkBaseUrl",
19774
20713
  statusApiBaseField: "walletApprovalRelayStatusApiBaseUrl"
@@ -20120,7 +21059,7 @@ function applyWorkflowHelpCommandOrder(workflow) {
20120
21059
  }
20121
21060
  function createWorkflowCommand(deps) {
20122
21061
  const resolvedDeps = resolveWorkflowCommandDeps(deps);
20123
- const workflow = new Command10("workflow").description(
21062
+ const workflow = new Command11("workflow").description(
20124
21063
  "Plan, persist, and execute higher-level wallet workflows"
20125
21064
  );
20126
21065
  workflow.addHelpText("after", buildWorkflowHelpText());
@@ -20159,6 +21098,13 @@ function createWorkflowCommand(deps) {
20159
21098
  walletName: plan.walletName,
20160
21099
  walletExists: true
20161
21100
  });
21101
+ const workflowEntrySummary = buildWorkflowEntrySummary({
21102
+ command: "plan",
21103
+ source: "input",
21104
+ checkpointPersisted: false,
21105
+ plan,
21106
+ nextCommand: plan.recommendedCommand
21107
+ });
20162
21108
  printResult(
20163
21109
  withAgentProfileLines(
20164
21110
  [...workflowPlanLines(plan), ...workflowFollowupLines(recommendedCommands)],
@@ -20167,6 +21113,7 @@ function createWorkflowCommand(deps) {
20167
21113
  ),
20168
21114
  {
20169
21115
  ok: true,
21116
+ workflowEntrySummary,
20170
21117
  agentProfile,
20171
21118
  agentFollowup,
20172
21119
  inspection,
@@ -20308,6 +21255,14 @@ function createWorkflowCommand(deps) {
20308
21255
  {
20309
21256
  ok: true,
20310
21257
  ...serializeWorkflowRequestMeta(started.requestId),
21258
+ workflowEntrySummary: buildWorkflowEntrySummary({
21259
+ command: "start",
21260
+ source: "input",
21261
+ requestId: started.requestId,
21262
+ checkpointPersisted: true,
21263
+ status: started.status,
21264
+ nextCommand: started.status.recommendedCommand
21265
+ }),
20311
21266
  agentProfile,
20312
21267
  agentFollowup,
20313
21268
  checkpoint: started.checkpoint,
@@ -20327,7 +21282,7 @@ function createWorkflowCommand(deps) {
20327
21282
  includeLocalApproval: true
20328
21283
  }).action(withWorkflowInputErrorHandling(async (options) => {
20329
21284
  const execution = await executeWorkflowAutoCommand(options, resolvedDeps);
20330
- await printWorkflowAutoCommandResult(execution);
21285
+ await printWorkflowAutoCommandResult(execution, "auto");
20331
21286
  }));
20332
21287
  const pay = workflow.command("pay").description(
20333
21288
  "Guided flagship AA native-send path with checkpoint persistence, intent-scoped session recovery, and paymaster-aware defaults"
@@ -20344,7 +21299,7 @@ function createWorkflowCommand(deps) {
20344
21299
  applyWorkflowPayDefaults(options),
20345
21300
  resolvedDeps
20346
21301
  );
20347
- await printWorkflowAutoCommandResult(execution);
21302
+ await printWorkflowAutoCommandResult(execution, "pay");
20348
21303
  }));
20349
21304
  const run = workflow.command("run").description("Run the requested workflow, or stop on the next required prerequisite or funding step first").option(
20350
21305
  "--intent <intent>",
@@ -20356,7 +21311,7 @@ function createWorkflowCommand(deps) {
20356
21311
  includeLocalApproval: true
20357
21312
  }).action(withWorkflowInputErrorHandling(async (options) => {
20358
21313
  const execution = await executeWorkflowRunCommand(options, resolvedDeps);
20359
- await printWorkflowRunCommandResult(execution);
21314
+ await printWorkflowRunCommandResult(execution, "run");
20360
21315
  }));
20361
21316
  const status = workflow.command("status").description("Inspect whether a workflow is blocked, still waiting on funding, or ready to resume").option(
20362
21317
  "--intent <intent>",
@@ -20388,6 +21343,19 @@ function createWorkflowCommand(deps) {
20388
21343
  walletName: inspection.result.walletName,
20389
21344
  walletExists: true
20390
21345
  });
21346
+ const summary = buildWorkflowRuntimeSummary({
21347
+ status: inspection.result,
21348
+ nextCommand: inspection.result.recommendedCommand
21349
+ });
21350
+ const workflowEntrySummary = buildWorkflowEntrySummary({
21351
+ command: "status",
21352
+ source: options.requestId?.trim() ? "checkpoint" : "input",
21353
+ requestId: inspection.requestId,
21354
+ checkpointPersisted: Boolean(inspection.checkpoint),
21355
+ status: inspection.result,
21356
+ walletApproval: inspection.walletApproval,
21357
+ nextCommand: inspection.result.recommendedCommand
21358
+ });
20391
21359
  printResult(
20392
21360
  prependWorkflowRequestId(
20393
21361
  inspection.requestId,
@@ -20404,15 +21372,13 @@ function createWorkflowCommand(deps) {
20404
21372
  {
20405
21373
  ok: true,
20406
21374
  ...serializeWorkflowRequestMeta(inspection.requestId),
21375
+ workflowEntrySummary,
20407
21376
  agentProfile,
20408
21377
  agentFollowup,
21378
+ summary,
20409
21379
  result: inspection.result,
20410
21380
  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),
21381
+ ...serializeWorkflowWalletApprovalOutput(inspection.walletApproval),
20416
21382
  tokenDiscoverySummary,
20417
21383
  recommendedCommands
20418
21384
  }
@@ -20449,6 +21415,19 @@ function createWorkflowCommand(deps) {
20449
21415
  walletName: inspection.result.walletName,
20450
21416
  walletExists: true
20451
21417
  });
21418
+ const summary = buildWorkflowRuntimeSummary({
21419
+ status: inspection.result,
21420
+ nextCommand
21421
+ });
21422
+ const workflowEntrySummary = buildWorkflowEntrySummary({
21423
+ command: "next",
21424
+ source: options.requestId?.trim() ? "checkpoint" : "input",
21425
+ requestId: inspection.requestId,
21426
+ checkpointPersisted: Boolean(inspection.checkpoint),
21427
+ status: inspection.result,
21428
+ walletApproval: inspection.walletApproval,
21429
+ nextCommand
21430
+ });
20452
21431
  printResult(
20453
21432
  prependWorkflowRequestId(
20454
21433
  inspection.requestId,
@@ -20465,28 +21444,13 @@ function createWorkflowCommand(deps) {
20465
21444
  {
20466
21445
  ok: true,
20467
21446
  ...serializeWorkflowRequestMeta(inspection.requestId),
21447
+ workflowEntrySummary,
20468
21448
  agentProfile,
20469
21449
  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
- },
21450
+ summary,
20483
21451
  result: inspection.result,
20484
21452
  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),
21453
+ ...serializeWorkflowWalletApprovalOutput(inspection.walletApproval),
20490
21454
  tokenDiscoverySummary,
20491
21455
  recommendedCommands
20492
21456
  }
@@ -20524,6 +21488,19 @@ function createWorkflowCommand(deps) {
20524
21488
  walletName: inspection.result.walletName,
20525
21489
  walletExists: true
20526
21490
  });
21491
+ const summary2 = buildWorkflowRuntimeSummary({
21492
+ status: inspection.result,
21493
+ nextCommand: inspection.result.recommendedCommand
21494
+ });
21495
+ const workflowEntrySummary2 = buildWorkflowEntrySummary({
21496
+ command: "resume",
21497
+ source: options.requestId?.trim() ? "checkpoint" : "input",
21498
+ requestId: inspection.requestId,
21499
+ checkpointPersisted: Boolean(inspection.checkpoint),
21500
+ status: inspection.result,
21501
+ walletApproval: inspection.walletApproval,
21502
+ nextCommand: inspection.result.recommendedCommand
21503
+ });
20527
21504
  printResult(
20528
21505
  prependWorkflowRequestId(
20529
21506
  inspection.requestId,
@@ -20540,15 +21517,13 @@ function createWorkflowCommand(deps) {
20540
21517
  {
20541
21518
  ok: true,
20542
21519
  ...serializeWorkflowRequestMeta(inspection.requestId),
21520
+ workflowEntrySummary: workflowEntrySummary2,
20543
21521
  agentProfile: agentProfile2,
20544
21522
  agentFollowup: agentFollowup2,
21523
+ summary: summary2,
20545
21524
  status: inspection.result,
20546
21525
  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),
21526
+ ...serializeWorkflowWalletApprovalOutput(inspection.walletApproval),
20552
21527
  tokenDiscoverySummary: tokenDiscoverySummary2,
20553
21528
  recommendedCommands: recommendedCommands2
20554
21529
  }
@@ -20564,33 +21539,50 @@ function createWorkflowCommand(deps) {
20564
21539
  resolvedDeps
20565
21540
  );
20566
21541
  if (!execution.result) {
21542
+ const status2 = execution.status;
21543
+ if (!status2) {
21544
+ throw new Error("Workflow resume result is missing both execution result and status.");
21545
+ }
20567
21546
  const recommendedCommands2 = buildWorkflowRuntimeRecommendedCommands({
20568
21547
  requestId: execution.requestId,
20569
- walletName: execution.status.walletName,
20570
- nextAction: execution.status.recommendedCommand,
20571
- chain: execution.status.plan.chain,
20572
- intent: execution.status.intent,
21548
+ walletName: status2.walletName,
21549
+ nextAction: status2.recommendedCommand,
21550
+ chain: status2.plan.chain,
21551
+ intent: status2.intent,
20573
21552
  paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal)
20574
21553
  });
20575
21554
  const tokenDiscoverySummary2 = buildWorkflowTokenDiscoverySummary({
20576
- walletName: execution.status.walletName,
20577
- chain: execution.status.plan.chain,
20578
- intent: execution.status.intent,
20579
- nextAction: execution.status.recommendedCommand,
21555
+ walletName: status2.walletName,
21556
+ chain: status2.plan.chain,
21557
+ intent: status2.intent,
21558
+ nextAction: status2.recommendedCommand,
20580
21559
  paymasterMode: execution.walletApproval?.request.requestedPaymasterMode ?? extractWorkflowGoalPaymasterMode(execution.checkpoint?.goal),
20581
21560
  recommendedCommands: recommendedCommands2
20582
21561
  });
20583
- const agentProfile2 = await loadWorkflowAgentProfile(execution.status.walletName);
21562
+ const agentProfile2 = await loadWorkflowAgentProfile(status2.walletName);
20584
21563
  const agentFollowup2 = buildAgentFollowup(agentProfile2, {
20585
- walletName: execution.status.walletName,
21564
+ walletName: status2.walletName,
20586
21565
  walletExists: true
20587
21566
  });
21567
+ const summary2 = buildWorkflowRuntimeSummary({
21568
+ status: status2,
21569
+ nextCommand: status2.recommendedCommand
21570
+ });
21571
+ const workflowEntrySummary2 = buildWorkflowEntrySummary({
21572
+ command: "resume",
21573
+ source: options.requestId?.trim() ? "checkpoint" : "input",
21574
+ requestId: execution.requestId,
21575
+ checkpointPersisted: Boolean(execution.checkpoint || execution.requestId),
21576
+ status: status2,
21577
+ walletApproval: execution.walletApproval,
21578
+ nextCommand: status2.recommendedCommand
21579
+ });
20588
21580
  printResult(
20589
21581
  prependWorkflowRequestId(
20590
21582
  execution.requestId,
20591
21583
  withAgentProfileLines(
20592
21584
  [
20593
- ...workflowStatusLines(execution.status),
21585
+ ...workflowStatusLines(status2),
20594
21586
  ...workflowWalletApprovalLines(execution.walletApproval),
20595
21587
  ...workflowFollowupLines(recommendedCommands2)
20596
21588
  ],
@@ -20601,15 +21593,13 @@ function createWorkflowCommand(deps) {
20601
21593
  {
20602
21594
  ok: true,
20603
21595
  ...serializeWorkflowRequestMeta(execution.requestId),
21596
+ workflowEntrySummary: workflowEntrySummary2,
20604
21597
  agentProfile: agentProfile2,
20605
21598
  agentFollowup: agentFollowup2,
20606
- status: execution.status,
21599
+ summary: summary2,
21600
+ status: status2,
20607
21601
  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),
21602
+ ...serializeWorkflowWalletApprovalOutput(execution.walletApproval),
20613
21603
  tokenDiscoverySummary: tokenDiscoverySummary2,
20614
21604
  recommendedCommands: recommendedCommands2
20615
21605
  }
@@ -20637,6 +21627,21 @@ function createWorkflowCommand(deps) {
20637
21627
  walletName: execution.result.walletName,
20638
21628
  walletExists: true
20639
21629
  });
21630
+ const summary = buildWorkflowRuntimeSummary({
21631
+ status: inspection.result,
21632
+ result: execution.result,
21633
+ nextCommand: execution.result.nextCommand ?? inspection.result.recommendedCommand
21634
+ });
21635
+ const workflowEntrySummary = buildWorkflowEntrySummary({
21636
+ command: "resume",
21637
+ source: options.requestId?.trim() ? "checkpoint" : "input",
21638
+ requestId: execution.requestId,
21639
+ checkpointPersisted: Boolean(execution.checkpoint || execution.requestId),
21640
+ status: inspection.result,
21641
+ result: execution.result,
21642
+ walletApproval: inspection.walletApproval,
21643
+ nextCommand: execution.result.nextCommand ?? inspection.result.recommendedCommand
21644
+ });
20640
21645
  printResult(
20641
21646
  prependWorkflowRequestId(
20642
21647
  execution.requestId,
@@ -20653,15 +21658,13 @@ function createWorkflowCommand(deps) {
20653
21658
  {
20654
21659
  ok: true,
20655
21660
  ...serializeWorkflowRequestMeta(execution.requestId),
21661
+ workflowEntrySummary,
20656
21662
  agentProfile,
20657
21663
  agentFollowup,
21664
+ summary,
20658
21665
  status: inspection.result,
20659
21666
  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),
21667
+ ...serializeWorkflowWalletApprovalOutput(inspection.walletApproval),
20665
21668
  tokenDiscoverySummary,
20666
21669
  recommendedCommands
20667
21670
  }
@@ -20681,7 +21684,7 @@ function createWorkflowCommand(deps) {
20681
21684
  },
20682
21685
  resolvedDeps
20683
21686
  );
20684
- await printWorkflowRunCommandResult(execution);
21687
+ await printWorkflowRunCommandResult(execution, intent);
20685
21688
  }));
20686
21689
  }
20687
21690
  workflow.addCommand(
@@ -20710,6 +21713,13 @@ function buildDefaultOperatorPathHelpText() {
20710
21713
  " zk-agent next",
20711
21714
  ` ${buildWorkflowPayRecommendedCommand("main")}`,
20712
21715
  "",
21716
+ "Validated first-run baseline:",
21717
+ " setup defaults to zksync-sepolia and the local connector at http://localhost:4444",
21718
+ " Override those only when you intentionally target a different chain or connector deployment.",
21719
+ "",
21720
+ "If local setup or wallet state is unclear:",
21721
+ " zk-agent doctor",
21722
+ "",
20713
21723
  "No custom .env is required for setup, next, or wallet create/reapprove request generation.",
20714
21724
  "Add RPC env vars later, before live reads or broadcasts.",
20715
21725
  "",
@@ -20720,6 +21730,7 @@ function buildDefaultOperatorPathHelpText() {
20720
21730
  }
20721
21731
  var ROOT_HELP_COMMAND_ORDER = [
20722
21732
  "next",
21733
+ "doctor",
20723
21734
  "init",
20724
21735
  "wallet",
20725
21736
  "workflow",
@@ -20756,13 +21767,14 @@ function applyRootHelpCommandOrder(program) {
20756
21767
  program.commands = sortedCommands;
20757
21768
  }
20758
21769
  function createProgram() {
20759
- const program = new Command11().name("zk-agent").description(
21770
+ const program = new Command12().name("zk-agent").description(
20760
21771
  "Local-first zkSync Era CLI for wallet approval, workflow execution, and hosted relay recovery"
20761
21772
  ).showHelpAfterError().option("--json", "Force JSON output for agent harnesses", false).hook("preAction", (thisCommand) => {
20762
21773
  if (thisCommand.optsWithGlobals().json) process.env.ZK_AGENT_OUTPUT = "json";
20763
21774
  });
20764
21775
  program.addCommand(createInitCommand());
20765
21776
  program.addCommand(createNextCommand());
21777
+ program.addCommand(createDoctorCommand());
20766
21778
  program.addCommand(createAgentCommand());
20767
21779
  program.addCommand(createDefaultsCommand());
20768
21780
  program.addCommand(createTokensCommand());