@tokamak-private-dapps/private-state-cli 2.1.1 → 2.2.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.
- package/CHANGELOG.md +45 -0
- package/README.md +109 -38
- package/cli-assistant.html +11 -5
- package/commands/account.mjs +39 -0
- package/commands/channel.mjs +58 -0
- package/commands/index.mjs +62 -0
- package/commands/investigator.mjs +11 -0
- package/commands/notes.mjs +34 -0
- package/commands/system.mjs +49 -0
- package/commands/wallet.mjs +80 -0
- package/investigator/README.md +16 -6
- package/investigator/app.js +612 -17
- package/investigator/index.html +153 -90
- package/investigator/styles.css +277 -28
- package/lib/private-state-cli-command-registry.mjs +102 -30
- package/lib/private-state-runtime-management.mjs +294 -25
- package/lib/runtime.mjs +11572 -0
- package/package.json +2 -1
- package/private-state-bridge-cli.mjs +2 -11269
|
@@ -18,8 +18,34 @@ export const PRIVATE_STATE_CLI_FIELD_CATALOG = Object.freeze({
|
|
|
18
18
|
type: "password",
|
|
19
19
|
placeholder: "https://example-rpc",
|
|
20
20
|
valueLabel: "<URL>",
|
|
21
|
-
hint: "
|
|
21
|
+
hint: "Required by set rpc. Saved to ~/tokamak-private-channels/workspace/<network>/rpc-config.env.",
|
|
22
22
|
option: "--rpc-url",
|
|
23
|
+
},
|
|
24
|
+
provider: {
|
|
25
|
+
label: "RPC Provider",
|
|
26
|
+
type: "select",
|
|
27
|
+
options: ["alchemy", "ankr", "chainstack", "chainnodes", "quicknode"],
|
|
28
|
+
valueLabel: "<PROVIDER>",
|
|
29
|
+
hint: "Optional for set rpc. Uses the built-in provider table for eth_getLogs request rate and block range cap.",
|
|
30
|
+
option: "--provider",
|
|
31
|
+
optional: true,
|
|
32
|
+
},
|
|
33
|
+
logRequestsPerSecond: {
|
|
34
|
+
label: "Log Requests Per Second",
|
|
35
|
+
type: "text",
|
|
36
|
+
placeholder: "7.497",
|
|
37
|
+
valueLabel: "<N>",
|
|
38
|
+
hint: "Optional for set rpc. Required with --block-range-cap when --provider is not used.",
|
|
39
|
+
option: "--log-requests-per-second",
|
|
40
|
+
optional: true,
|
|
41
|
+
},
|
|
42
|
+
blockRangeCap: {
|
|
43
|
+
label: "Block Range Cap",
|
|
44
|
+
type: "text",
|
|
45
|
+
placeholder: "10",
|
|
46
|
+
valueLabel: "<N>",
|
|
47
|
+
hint: "Optional for set rpc. Required with --log-requests-per-second when --provider is not used.",
|
|
48
|
+
option: "--block-range-cap",
|
|
23
49
|
optional: true,
|
|
24
50
|
},
|
|
25
51
|
account: {
|
|
@@ -162,6 +188,13 @@ export const PRIVATE_STATE_CLI_FIELD_CATALOG = Object.freeze({
|
|
|
162
188
|
valueLabel: "<VERSION>",
|
|
163
189
|
optional: true,
|
|
164
190
|
},
|
|
191
|
+
readOnly: {
|
|
192
|
+
label: "Read-Only Install",
|
|
193
|
+
type: "checkbox",
|
|
194
|
+
hint: "Install only artifacts needed by channel-state read commands and commands that do not depend on channel state.",
|
|
195
|
+
option: "--read-only",
|
|
196
|
+
optional: true,
|
|
197
|
+
},
|
|
165
198
|
fromGenesis: {
|
|
166
199
|
label: "Scan From Genesis",
|
|
167
200
|
type: "checkbox",
|
|
@@ -213,7 +246,7 @@ const ACTION_IMPACT_HELP = Object.freeze({
|
|
|
213
246
|
acknowledgement: "Requires --acknowledge-action-impact after the user reviews the action-impact warning.",
|
|
214
247
|
illegalUse: "The command must not be used for money laundering, sanctions evasion, terrorist financing, illegal gambling, criminal-proceeds concealment, or regulatory evasion.",
|
|
215
248
|
secretRecovery: "Losing wallet secrets, viewing keys, or spending keys can prevent note discovery or note use; the CLI cannot recover lost secrets.",
|
|
216
|
-
|
|
249
|
+
exchangeControlledAddress: "Do not use an exchange-controlled address as a self-custody bridge source or direct bridge withdrawal target.",
|
|
217
250
|
policy: "The user must review the channel policy snapshot before accepting channel-bound actions.",
|
|
218
251
|
provenance: "Public observers cannot reconstruct private note counterparty relationships or note provenance from public contract state alone.",
|
|
219
252
|
});
|
|
@@ -221,10 +254,12 @@ const ACTION_IMPACT_HELP = Object.freeze({
|
|
|
221
254
|
export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
222
255
|
{
|
|
223
256
|
id: "install",
|
|
224
|
-
description: "Install
|
|
225
|
-
fields: ["docker", "includeLocalArtifacts", "groth16CliVersion", "tokamakZkEvmCliVersion"],
|
|
226
|
-
usage: "optional --docker, --include-local-artifacts, --groth16-cli-version, and --tokamak-zk-evm-cli-version",
|
|
257
|
+
description: "Install private-state CLI runtime artifacts in full or read-only mode.",
|
|
258
|
+
fields: ["readOnly", "docker", "includeLocalArtifacts", "groth16CliVersion", "tokamakZkEvmCliVersion"],
|
|
259
|
+
usage: "optional --read-only, --docker, --include-local-artifacts, --groth16-cli-version, and --tokamak-zk-evm-cli-version",
|
|
227
260
|
help: [
|
|
261
|
+
"Default full mode installs proof runtimes and all deployment artifacts needed by transaction-sending commands",
|
|
262
|
+
"--read-only installs only artifacts needed by channel-state read commands and commands unrelated to channel state",
|
|
228
263
|
"Version options install exact CLI package versions; omitted versions resolve to npm registry latest",
|
|
229
264
|
"Use --docker on Linux to forward Docker mode to the Tokamak zk-EVM and Groth16 runtimes",
|
|
230
265
|
"Use --include-local-artifacts to also install local deployment/ artifacts from the current working directory",
|
|
@@ -236,6 +271,18 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
236
271
|
fields: [],
|
|
237
272
|
usage: "no options",
|
|
238
273
|
},
|
|
274
|
+
{
|
|
275
|
+
id: "set-rpc",
|
|
276
|
+
display: "set rpc",
|
|
277
|
+
description: "Configure the network RPC URL and fixed eth_getLogs scan limits.",
|
|
278
|
+
fields: ["network", "rpcUrl", "provider", "logRequestsPerSecond", "blockRangeCap"],
|
|
279
|
+
usage: "--network, --rpc-url, and either --provider or both --log-requests-per-second and --block-range-cap",
|
|
280
|
+
help: [
|
|
281
|
+
"Writes ~/tokamak-private-channels/workspace/<network>/rpc-config.env",
|
|
282
|
+
"Built-in provider limits: ankr=27 calls/s and 3000 blocks, chainstack=22.5 calls/s and 100 blocks, chainnodes=22.5 calls/s and 20000 blocks, quicknode=13.5 calls/s and 5 blocks, alchemy=7.497 calls/s and 10 blocks",
|
|
283
|
+
"All bridge-facing and wallet commands read RPC settings from this file and do not accept --rpc-url",
|
|
284
|
+
],
|
|
285
|
+
},
|
|
239
286
|
{
|
|
240
287
|
id: "help-commands",
|
|
241
288
|
display: "help commands",
|
|
@@ -257,11 +304,12 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
257
304
|
{
|
|
258
305
|
id: "help-doctor",
|
|
259
306
|
display: "help doctor",
|
|
260
|
-
description: "Check private-state CLI package versions,
|
|
307
|
+
description: "Check private-state CLI package versions, install state, deployment artifacts, and command availability.",
|
|
261
308
|
fields: ["gpu", "json"],
|
|
262
309
|
usage: "optional --gpu and optional --json",
|
|
263
310
|
help: [
|
|
264
311
|
"Prints a concise human-readable table by default; use --json for the full machine-readable report",
|
|
312
|
+
"Reports whether each command is usable with the current read-only or full install state",
|
|
265
313
|
"Use --gpu to run live NVIDIA/Docker GPU probes",
|
|
266
314
|
],
|
|
267
315
|
},
|
|
@@ -278,8 +326,8 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
278
326
|
id: "help-transaction-fees",
|
|
279
327
|
display: "help transaction-fees",
|
|
280
328
|
description: "Estimate ETH and USD fees for transaction-sending commands from packaged measured gas data and live network fee data.",
|
|
281
|
-
fields: ["network", "
|
|
282
|
-
usage: "--network
|
|
329
|
+
fields: ["network", "json"],
|
|
330
|
+
usage: "--network and optional --json",
|
|
283
331
|
help: [
|
|
284
332
|
"Uses packages/apps/private-state/cli/assets/tx-fees.json as the measured gas source packaged with the CLI",
|
|
285
333
|
"Reads live fee data from the selected network RPC and live ETH/USD from CoinGecko",
|
|
@@ -314,15 +362,17 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
314
362
|
id: "account-get-bridge-fund",
|
|
315
363
|
display: "account get-bridge-fund",
|
|
316
364
|
description: "Read the local account's current shared bridge vault balance.",
|
|
317
|
-
|
|
318
|
-
|
|
365
|
+
installMode: "read-only",
|
|
366
|
+
fields: ["network", "account"],
|
|
367
|
+
usage: "--network, --account",
|
|
319
368
|
},
|
|
320
369
|
{
|
|
321
370
|
id: "channel-create",
|
|
322
371
|
display: "channel create",
|
|
323
372
|
description: "Create a bridge channel and initialize its workspace.",
|
|
324
|
-
|
|
325
|
-
|
|
373
|
+
installMode: "full",
|
|
374
|
+
fields: ["channelName", "joinToll", "network", "account"],
|
|
375
|
+
usage: "--channel-name, --join-toll, --network, --account",
|
|
326
376
|
help: [
|
|
327
377
|
"Prints the immutable policy snapshot before sending the transaction",
|
|
328
378
|
"Initializes the local channel workspace by replaying channel logs from channel genesis",
|
|
@@ -332,8 +382,9 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
332
382
|
id: "channel-recover-workspace",
|
|
333
383
|
display: "channel recover-workspace",
|
|
334
384
|
description: "Rebuild the local channel workspace from bridge state.",
|
|
335
|
-
|
|
336
|
-
|
|
385
|
+
installMode: "read-only",
|
|
386
|
+
fields: ["channelName", "network", "source", "fromGenesis"],
|
|
387
|
+
usage: "--channel-name, --network, optional --source, optional --from-genesis",
|
|
337
388
|
help: [
|
|
338
389
|
"By default, --source rpc resumes RPC log scanning from the workspace recovery index when available",
|
|
339
390
|
"--source mirror validates the channel leader's registered checkpoint manifest, downloads only the needed checkpoint or delta bundle, and then replays RPC logs to latest",
|
|
@@ -349,8 +400,9 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
349
400
|
id: "channel-set-workspace-mirror",
|
|
350
401
|
display: "channel set-workspace-mirror",
|
|
351
402
|
description: "Register or update the channel leader's workspace mirror base URL.",
|
|
352
|
-
|
|
353
|
-
|
|
403
|
+
installMode: "full",
|
|
404
|
+
fields: ["channelName", "network", "account", "url"],
|
|
405
|
+
usage: "--channel-name, --network, --account, --url",
|
|
354
406
|
help: [
|
|
355
407
|
"Only the on-chain channel leader can update the registered mirror URL",
|
|
356
408
|
"The URL points to a server implementing the private-state channel workspace mirror protocol",
|
|
@@ -360,8 +412,9 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
360
412
|
id: "channel-publish-workspace-mirror",
|
|
361
413
|
display: "channel publish-workspace-mirror",
|
|
362
414
|
description: "Build static workspace mirror files for the registered mirror URL.",
|
|
363
|
-
|
|
364
|
-
|
|
415
|
+
installMode: "read-only",
|
|
416
|
+
fields: ["channelName", "network", "account", "output", "force"],
|
|
417
|
+
usage: "--channel-name, --network, --account, --output, optional --force",
|
|
365
418
|
help: [
|
|
366
419
|
"Requires the local channel workspace to be current and ahead of the registered mirror checkpoint",
|
|
367
420
|
"--force ignores an unreadable or invalid existing mirror manifest and publishes a full checkpoint without a delta",
|
|
@@ -373,19 +426,21 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
373
426
|
id: "channel-get-meta",
|
|
374
427
|
display: "channel get-meta",
|
|
375
428
|
description: "Read channel existence, manager, vault, toll, refund schedule, and immutable policy snapshot.",
|
|
376
|
-
|
|
377
|
-
|
|
429
|
+
installMode: "read-only",
|
|
430
|
+
fields: ["channelName", "network"],
|
|
431
|
+
usage: "--channel-name, --network",
|
|
378
432
|
},
|
|
379
433
|
{
|
|
380
434
|
id: "account-deposit-bridge",
|
|
381
435
|
display: "account deposit-bridge",
|
|
382
436
|
description: "Deposit canonical tokens into the shared bridge vault.",
|
|
383
|
-
|
|
384
|
-
|
|
437
|
+
installMode: "read-only",
|
|
438
|
+
fields: ["amount", "network", "account", "acknowledgeActionImpact"],
|
|
439
|
+
usage: "--amount, --network, --account, --acknowledge-action-impact",
|
|
385
440
|
help: [
|
|
386
441
|
"Action impact: emits public L1 approval and bridge funding events that expose the local L1 account, bridge vault, amount, and transaction hashes.",
|
|
387
442
|
"Private note state is not changed by this command.",
|
|
388
|
-
ACTION_IMPACT_HELP.
|
|
443
|
+
ACTION_IMPACT_HELP.exchangeControlledAddress,
|
|
389
444
|
ACTION_IMPACT_HELP.illegalUse,
|
|
390
445
|
ACTION_IMPACT_HELP.acknowledgement,
|
|
391
446
|
],
|
|
@@ -394,12 +449,13 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
394
449
|
id: "account-withdraw-bridge",
|
|
395
450
|
display: "account withdraw-bridge",
|
|
396
451
|
description: "Withdraw tokens from the shared bridge vault back to the wallet.",
|
|
397
|
-
|
|
398
|
-
|
|
452
|
+
installMode: "read-only",
|
|
453
|
+
fields: ["amount", "network", "account", "acknowledgeActionImpact"],
|
|
454
|
+
usage: "--amount, --network, --account, --acknowledge-action-impact",
|
|
399
455
|
help: [
|
|
400
456
|
"Action impact: emits a public L1 bridge withdrawal event that exposes the local L1 recipient, bridge vault, amount, and transaction hash.",
|
|
401
457
|
"Private note state is not changed by this command; prior note provenance is not public by default.",
|
|
402
|
-
ACTION_IMPACT_HELP.
|
|
458
|
+
ACTION_IMPACT_HELP.exchangeControlledAddress,
|
|
403
459
|
ACTION_IMPACT_HELP.illegalUse,
|
|
404
460
|
ACTION_IMPACT_HELP.acknowledgement,
|
|
405
461
|
],
|
|
@@ -408,8 +464,9 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
408
464
|
id: "wallet-recover-workspace",
|
|
409
465
|
display: "wallet recover-workspace",
|
|
410
466
|
description: "Rebuild a recoverable local wallet from on-chain channel state.",
|
|
411
|
-
|
|
412
|
-
|
|
467
|
+
installMode: "read-only",
|
|
468
|
+
fields: ["channelName", "network", "account", "fromGenesis"],
|
|
469
|
+
usage: "--channel-name, --network, --account, optional --from-genesis",
|
|
413
470
|
help: [
|
|
414
471
|
"Rebuilds backup metadata from channel state without recreating the spending key",
|
|
415
472
|
"Derives and stores the viewing key when the local account signer can reproduce the registered viewing public key",
|
|
@@ -424,8 +481,9 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
424
481
|
id: "channel-join",
|
|
425
482
|
display: "channel join",
|
|
426
483
|
description: "Pay the channel join toll and bind a wallet to a channel-specific L2 identity.",
|
|
427
|
-
|
|
428
|
-
|
|
484
|
+
installMode: "full",
|
|
485
|
+
fields: ["channelName", "network", "account", "walletSecretPath", "acknowledgeActionImpact"],
|
|
486
|
+
usage: "--channel-name, --network, --account, --wallet-secret-path, --acknowledge-action-impact",
|
|
429
487
|
help: [
|
|
430
488
|
"Refreshes the local channel workspace through the saved recovery index before joining when the scan fits the 10 second pre-command budget",
|
|
431
489
|
"Fails instead of replaying from genesis; run channel recover-workspace --source rpc --from-genesis when a genesis rebuild is required",
|
|
@@ -443,6 +501,7 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
443
501
|
id: "wallet-get-meta",
|
|
444
502
|
display: "wallet get-meta",
|
|
445
503
|
description: "Check whether a wallet matches the on-chain channel registration.",
|
|
504
|
+
installMode: "read-only",
|
|
446
505
|
fields: ["wallet", "network"],
|
|
447
506
|
usage: "--wallet and --network",
|
|
448
507
|
help: [
|
|
@@ -512,6 +571,7 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
512
571
|
id: "wallet-deposit-channel",
|
|
513
572
|
display: "wallet deposit-channel",
|
|
514
573
|
description: "Move bridged funds into the channel L2 accounting balance.",
|
|
574
|
+
installMode: "full",
|
|
515
575
|
fields: ["wallet", "network", "amount", "acknowledgeActionImpact"],
|
|
516
576
|
usage: "--wallet, --network, --amount, and --acknowledge-action-impact",
|
|
517
577
|
help: [
|
|
@@ -528,6 +588,7 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
528
588
|
id: "wallet-withdraw-channel",
|
|
529
589
|
display: "wallet withdraw-channel",
|
|
530
590
|
description: "Move channel L2 balance back into the shared bridge vault.",
|
|
591
|
+
installMode: "full",
|
|
531
592
|
fields: ["wallet", "network", "amount", "acknowledgeActionImpact"],
|
|
532
593
|
usage: "--wallet, --network, --amount, and --acknowledge-action-impact",
|
|
533
594
|
help: [
|
|
@@ -545,6 +606,7 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
545
606
|
id: "wallet-get-channel-fund",
|
|
546
607
|
display: "wallet get-channel-fund",
|
|
547
608
|
description: "Read the current channel L2 accounting balance.",
|
|
609
|
+
installMode: "read-only",
|
|
548
610
|
fields: ["wallet", "network"],
|
|
549
611
|
usage: "--wallet and --network",
|
|
550
612
|
help: ["Refreshes the local channel workspace through the saved recovery index before reading the L2 accounting balance when the scan fits the 10 second pre-command budget"],
|
|
@@ -553,6 +615,7 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
553
615
|
id: "channel-exit",
|
|
554
616
|
display: "channel exit",
|
|
555
617
|
description: "Exit a channel. Both the CLI and bridge contract require a zero channel balance.",
|
|
618
|
+
installMode: "full",
|
|
556
619
|
fields: ["wallet", "network"],
|
|
557
620
|
usage: "--wallet and --network",
|
|
558
621
|
help: [
|
|
@@ -564,10 +627,12 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
564
627
|
id: "wallet-mint-notes",
|
|
565
628
|
display: "wallet mint-notes",
|
|
566
629
|
description: "Mint one or two private-state notes from the wallet's channel balance.",
|
|
630
|
+
installMode: "full",
|
|
567
631
|
fields: ["wallet", "network", "amounts", "acknowledgeActionImpact", "txSubmitter"],
|
|
568
632
|
usage: "--wallet, --network, --amounts, --acknowledge-action-impact, and optional --tx-submitter",
|
|
569
633
|
help: [
|
|
570
634
|
"Refreshes the local channel workspace through the saved recovery index before proving the mint when the scan fits the 10 second pre-command budget",
|
|
635
|
+
"Requires both viewing and spending key capability so the accepted mint can be recovered through the normal note event path",
|
|
571
636
|
"Use --tx-submitter <ACCOUNT> to let a separate local L1 account pay gas for stronger transaction privacy",
|
|
572
637
|
"Action impact: emits public accepted-transition, commitment, encrypted note-delivery, root update, and transaction events.",
|
|
573
638
|
"Private note state changes by creating local note plaintext and public commitments; note owner/value/salt are not public by default.",
|
|
@@ -582,6 +647,7 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
582
647
|
id: "wallet-transfer-notes",
|
|
583
648
|
display: "wallet transfer-notes",
|
|
584
649
|
description: "Spend input notes into the registered 1->1, 1->2, or 2->1 private transfer shapes.",
|
|
650
|
+
installMode: "full",
|
|
585
651
|
fields: ["wallet", "network", "noteIds", "recipients", "amounts", "acknowledgeActionImpact", "txSubmitter"],
|
|
586
652
|
usage: "--wallet, --network, --note-ids, --recipients, --amounts, --acknowledge-action-impact, and optional --tx-submitter",
|
|
587
653
|
help: [
|
|
@@ -600,6 +666,7 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
600
666
|
id: "wallet-redeem-notes",
|
|
601
667
|
display: "wallet redeem-notes",
|
|
602
668
|
description: "Redeem one tracked note back into the wallet's channel balance.",
|
|
669
|
+
installMode: "full",
|
|
603
670
|
fields: ["wallet", "network", "noteIds", "acknowledgeActionImpact", "txSubmitter"],
|
|
604
671
|
usage: "--wallet, --network, --note-ids, --acknowledge-action-impact, and optional --tx-submitter",
|
|
605
672
|
help: [
|
|
@@ -618,6 +685,7 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
618
685
|
id: "wallet-get-notes",
|
|
619
686
|
display: "wallet get-notes",
|
|
620
687
|
description: "Refresh received notes when the saved recovery index is recent, then show tracked note state.",
|
|
688
|
+
installMode: "read-only",
|
|
621
689
|
fields: ["wallet", "network", "exportEvidence", "acknowledgeFullNotePlaintextExport"],
|
|
622
690
|
usage: "--wallet, --network, optional --export-evidence, and optional --acknowledge-full-note-plaintext-export",
|
|
623
691
|
help: [
|
|
@@ -630,6 +698,10 @@ export const PRIVATE_STATE_CLI_COMMANDS = Object.freeze([
|
|
|
630
698
|
},
|
|
631
699
|
]);
|
|
632
700
|
|
|
701
|
+
export function privateStateCliCommandInstallMode(command) {
|
|
702
|
+
return command.installMode ?? "none";
|
|
703
|
+
}
|
|
704
|
+
|
|
633
705
|
export function privateStateCliCommandDisplay(command) {
|
|
634
706
|
return command.display ?? command.id;
|
|
635
707
|
}
|