@toon-protocol/townhouse 0.1.0-rc5 → 0.1.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.
@@ -0,0 +1,39 @@
1
+ import { createRequire } from 'module'; const require = createRequire(import.meta.url);
2
+
3
+ // src/constants.ts
4
+ var CONTAINER_PREFIX = "townhouse-";
5
+ var NODE_BTP_PORT = 3e3;
6
+ var DEFAULT_CONNECTOR_IMAGE = (
7
+ // v3.8.0 — latest published connector (Story 50.4 bump). Migrates local SQLite
8
+ // from better-sqlite3 to libsql (toon-protocol/connector#79 — removes the
9
+ // native-build failure on Node 24 that left the settlement/claim subsystem
10
+ // silently un-wired → value-bearing packets auto-fulfilled instead of
11
+ // claim-gated) AND makes inbound per-packet claim validation relation-aware
12
+ // (toon-protocol/connector#78 — a child node now skips the inline-claim
13
+ // requirement for PREPAREs forwarded from its parent, unblocking Story 50.3's
14
+ // AC#1 kind:1 F06 "No payment channel claim attached" on the apex→child hop).
15
+ // No breaking changes to the SDK/admin contract within 3.x (verified >=3.3.2
16
+ // through 3.8.0 — see packages/sdk/CONNECTOR_MIGRATION.md). Digest resolved via
17
+ // `docker buildx imagetools inspect` for tag 3.8.0. To bump: see
18
+ // CONNECTOR_RELEASE_CONTRACT.md.
19
+ "ghcr.io/toon-protocol/connector@sha256:3343c19649290043e521c81b467b7c6410b8eaedd76d48804ea9b6fc810cddb0"
20
+ );
21
+ var ACCOUNT_INDEX_TOWN = 0;
22
+ var ACCOUNT_INDEX_MILL = 1;
23
+ var ACCOUNT_INDEX_DVM = 2;
24
+ var TOWN_HEALTH_PORT = 3100;
25
+ var MILL_HEALTH_PORT = 3200;
26
+ var DVM_HEALTH_PORT = 3400;
27
+
28
+ export {
29
+ CONTAINER_PREFIX,
30
+ NODE_BTP_PORT,
31
+ DEFAULT_CONNECTOR_IMAGE,
32
+ ACCOUNT_INDEX_TOWN,
33
+ ACCOUNT_INDEX_MILL,
34
+ ACCOUNT_INDEX_DVM,
35
+ TOWN_HEALTH_PORT,
36
+ MILL_HEALTH_PORT,
37
+ DVM_HEALTH_PORT
38
+ };
39
+ //# sourceMappingURL=chunk-GQNBZJ6F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Shared constants for Townhouse package.\n *\n * Single source of truth for values used across multiple modules\n * (orchestrator, config-generator, CLI).\n */\n\n/** Container name prefix for all Townhouse-managed Docker containers */\nexport const CONTAINER_PREFIX = 'townhouse-';\n\n/** Internal BTP port exposed by node containers (Docker-internal only) */\nexport const NODE_BTP_PORT = 3000;\n\n/**\n * Default connector Docker image — digest-pinned per CONNECTOR_RELEASE_CONTRACT.md.\n *\n * To bump: capture a new digest by running the Story 45.1 publish workflow\n * against the desired connector tag, copy the resulting image-manifest.json\n * connector entry's digest, and update this constant + the contract canary\n * fixture. See packages/sdk/CONNECTOR_RELEASE_CONTRACT.md for the full bump\n * checklist + breaking-changes history.\n *\n * To read the human-readable tag for log output, consult dist/image-manifest.json:\n * manifest.images.connector.tag\n */\nexport const DEFAULT_CONNECTOR_IMAGE =\n // v3.8.0 — latest published connector (Story 50.4 bump). Migrates local SQLite\n // from better-sqlite3 to libsql (toon-protocol/connector#79 — removes the\n // native-build failure on Node 24 that left the settlement/claim subsystem\n // silently un-wired → value-bearing packets auto-fulfilled instead of\n // claim-gated) AND makes inbound per-packet claim validation relation-aware\n // (toon-protocol/connector#78 — a child node now skips the inline-claim\n // requirement for PREPAREs forwarded from its parent, unblocking Story 50.3's\n // AC#1 kind:1 F06 \"No payment channel claim attached\" on the apex→child hop).\n // No breaking changes to the SDK/admin contract within 3.x (verified >=3.3.2\n // through 3.8.0 — see packages/sdk/CONNECTOR_MIGRATION.md). Digest resolved via\n // `docker buildx imagetools inspect` for tag 3.8.0. To bump: see\n // CONNECTOR_RELEASE_CONTRACT.md.\n 'ghcr.io/toon-protocol/connector@sha256:3343c19649290043e521c81b467b7c6410b8eaedd76d48804ea9b6fc810cddb0';\n\n/**\n * HD wallet account indices per node type (Story 21.4, D21-008).\n * BIP-44 paths: m/44'/{coin}'/ACCOUNT'/0/0\n */\nexport const ACCOUNT_INDEX_TOWN = 0;\nexport const ACCOUNT_INDEX_MILL = 1;\nexport const ACCOUNT_INDEX_DVM = 2;\n\n/** BLS health port exposed by each node container type (internal Docker port). */\nexport const TOWN_HEALTH_PORT = 3100;\nexport const MILL_HEALTH_PORT = 3200;\nexport const DVM_HEALTH_PORT = 3400;\n"],"mappings":";;;AAQO,IAAM,mBAAmB;AAGzB,IAAM,gBAAgB;AActB,IAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaX;AAAA;AAMK,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB;AAG1B,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AACzB,IAAM,kBAAkB;","names":[]}
@@ -31,29 +31,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  mod
32
32
  ));
33
33
 
34
- // src/constants.ts
35
- var CONTAINER_PREFIX = "townhouse-";
36
- var NODE_BTP_PORT = 3e3;
37
- var DEFAULT_CONNECTOR_IMAGE = "ghcr.io/toon-protocol/connector@sha256:4a24ccb0997d7b025997e670546032f6a84cd18a77c490509016b85e181a344e";
38
- var ACCOUNT_INDEX_TOWN = 0;
39
- var ACCOUNT_INDEX_MILL = 1;
40
- var ACCOUNT_INDEX_DVM = 2;
41
- var TOWN_HEALTH_PORT = 3100;
42
- var MILL_HEALTH_PORT = 3200;
43
- var DVM_HEALTH_PORT = 3400;
44
-
45
34
  export {
46
35
  __require,
47
36
  __commonJS,
48
- __toESM,
49
- CONTAINER_PREFIX,
50
- NODE_BTP_PORT,
51
- DEFAULT_CONNECTOR_IMAGE,
52
- ACCOUNT_INDEX_TOWN,
53
- ACCOUNT_INDEX_MILL,
54
- ACCOUNT_INDEX_DVM,
55
- TOWN_HEALTH_PORT,
56
- MILL_HEALTH_PORT,
57
- DVM_HEALTH_PORT
37
+ __toESM
58
38
  };
59
- //# sourceMappingURL=chunk-UTFWPLTB.js.map
39
+ //# sourceMappingURL=chunk-I2R4CRUX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,65 @@
1
+ import { createRequire } from 'module'; const require = createRequire(import.meta.url);
2
+
3
+ // src/tui/format.ts
4
+ var DECIMAL_RE = /^-?\d+$/;
5
+ var MICRO_FRACTIONAL_DIGITS = 4;
6
+ function formatRelativeTime(iso, now = /* @__PURE__ */ new Date()) {
7
+ if (iso === null) return "\u2014";
8
+ const ms = Date.parse(iso);
9
+ if (!Number.isFinite(ms)) return "?";
10
+ const deltaSec = Math.max(0, Math.floor((now.getTime() - ms) / 1e3));
11
+ if (deltaSec < 60) return "<1m ago";
12
+ if (deltaSec < 3600) return `${Math.floor(deltaSec / 60)}m ago`;
13
+ if (deltaSec < 86400) return `${Math.floor(deltaSec / 3600)}h ago`;
14
+ if (deltaSec < 2592e3) return `${Math.floor(deltaSec / 86400)}d ago`;
15
+ return `${Math.floor(deltaSec / 2592e3)}mo ago`;
16
+ }
17
+ function formatUsdcMicro(decimalString, scale) {
18
+ if (!DECIMAL_RE.test(decimalString)) {
19
+ const env = process.env["NODE_ENV"];
20
+ if (env === "development" || env === "test") {
21
+ throw new Error(
22
+ `formatUsdcMicro: invalid decimal string: ${JSON.stringify(decimalString)}`
23
+ );
24
+ }
25
+ return "$?.????";
26
+ }
27
+ const negative = decimalString.startsWith("-");
28
+ const abs = negative ? decimalString.slice(1) : decimalString;
29
+ const divisor = BigInt(10) ** BigInt(scale);
30
+ const value = BigInt(abs);
31
+ const whole = value / divisor;
32
+ const remainder = value % divisor;
33
+ const fractionalStr = remainder.toString().padStart(scale, "0");
34
+ const cents = fractionalStr.slice(0, MICRO_FRACTIONAL_DIGITS).padEnd(MICRO_FRACTIONAL_DIGITS, "0");
35
+ const formatted = `$${whole.toString()}.${cents}`;
36
+ return negative && value !== 0n ? `-${formatted}` : formatted;
37
+ }
38
+ function formatUsdc(decimalString, scale) {
39
+ if (!DECIMAL_RE.test(decimalString)) {
40
+ const env = process.env["NODE_ENV"];
41
+ if (env === "development" || env === "test") {
42
+ throw new Error(
43
+ `formatUsdc: invalid decimal string: ${JSON.stringify(decimalString)}`
44
+ );
45
+ }
46
+ return "$?.??";
47
+ }
48
+ const negative = decimalString.startsWith("-");
49
+ const abs = negative ? decimalString.slice(1) : decimalString;
50
+ const divisor = BigInt(10) ** BigInt(scale);
51
+ const value = BigInt(abs);
52
+ const whole = value / divisor;
53
+ const remainder = value % divisor;
54
+ const fractionalStr = remainder.toString().padStart(scale, "0");
55
+ const cents = fractionalStr.slice(0, 2).padEnd(2, "0");
56
+ const formatted = `$${whole.toString()}.${cents}`;
57
+ return negative && value !== 0n ? `-${formatted}` : formatted;
58
+ }
59
+
60
+ export {
61
+ formatRelativeTime,
62
+ formatUsdcMicro,
63
+ formatUsdc
64
+ };
65
+ //# sourceMappingURL=chunk-JCOFMUPL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tui/format.ts"],"sourcesContent":["const DECIMAL_RE = /^-?\\d+$/;\nconst MICRO_FRACTIONAL_DIGITS = 4;\n\nexport function formatRelativeTime(\n iso: string | null,\n now: Date = new Date()\n): string {\n if (iso === null) return '—';\n const ms = Date.parse(iso);\n if (!Number.isFinite(ms)) return '?';\n // Clamp negative deltas (future-dated `at` from host/container clock skew) to 0.\n // Without the clamp, a claim ~hours in the future would silently render `<1m ago`\n // because every negative value already trips the `< 60` shortcut; the clamp makes\n // the future-tolerance contract explicit instead of incidental.\n const deltaSec = Math.max(0, Math.floor((now.getTime() - ms) / 1000));\n if (deltaSec < 60) return '<1m ago';\n if (deltaSec < 3600) return `${Math.floor(deltaSec / 60)}m ago`;\n if (deltaSec < 86_400) return `${Math.floor(deltaSec / 3600)}h ago`;\n if (deltaSec < 2_592_000) return `${Math.floor(deltaSec / 86_400)}d ago`;\n return `${Math.floor(deltaSec / 2_592_000)}mo ago`;\n}\n\nexport function formatUsdcMicro(decimalString: string, scale: number): string {\n if (!DECIMAL_RE.test(decimalString)) {\n const env = process.env['NODE_ENV'];\n if (env === 'development' || env === 'test') {\n throw new Error(\n `formatUsdcMicro: invalid decimal string: ${JSON.stringify(decimalString)}`\n );\n }\n return '$?.????';\n }\n\n const negative = decimalString.startsWith('-');\n const abs = negative ? decimalString.slice(1) : decimalString;\n\n const divisor = BigInt(10) ** BigInt(scale);\n const value = BigInt(abs);\n\n const whole = value / divisor;\n const remainder = value % divisor;\n\n const fractionalStr = remainder.toString().padStart(scale, '0');\n const cents = fractionalStr\n .slice(0, MICRO_FRACTIONAL_DIGITS)\n .padEnd(MICRO_FRACTIONAL_DIGITS, '0');\n\n const formatted = `$${whole.toString()}.${cents}`;\n return negative && value !== 0n ? `-${formatted}` : formatted;\n}\n\nexport function formatUsdc(decimalString: string, scale: number): string {\n if (!DECIMAL_RE.test(decimalString)) {\n const env = process.env['NODE_ENV'];\n if (env === 'development' || env === 'test') {\n throw new Error(\n `formatUsdc: invalid decimal string: ${JSON.stringify(decimalString)}`\n );\n }\n return '$?.??';\n }\n\n const negative = decimalString.startsWith('-');\n const abs = negative ? decimalString.slice(1) : decimalString;\n\n const divisor = BigInt(10) ** BigInt(scale);\n const value = BigInt(abs);\n\n // Truncate (do NOT round) — connector posture.\n const whole = value / divisor;\n const remainder = value % divisor;\n\n const fractionalStr = remainder.toString().padStart(scale, '0');\n const cents = fractionalStr.slice(0, 2).padEnd(2, '0');\n\n const formatted = `$${whole.toString()}.${cents}`;\n // Suppress `-$0.00` — value === 0n collapses negative zero.\n return negative && value !== 0n ? `-${formatted}` : formatted;\n}\n"],"mappings":";;;AAAA,IAAM,aAAa;AACnB,IAAM,0BAA0B;AAEzB,SAAS,mBACd,KACA,MAAY,oBAAI,KAAK,GACb;AACR,MAAI,QAAQ,KAAM,QAAO;AACzB,QAAM,KAAK,KAAK,MAAM,GAAG;AACzB,MAAI,CAAC,OAAO,SAAS,EAAE,EAAG,QAAO;AAKjC,QAAM,WAAW,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,QAAQ,IAAI,MAAM,GAAI,CAAC;AACpE,MAAI,WAAW,GAAI,QAAO;AAC1B,MAAI,WAAW,KAAM,QAAO,GAAG,KAAK,MAAM,WAAW,EAAE,CAAC;AACxD,MAAI,WAAW,MAAQ,QAAO,GAAG,KAAK,MAAM,WAAW,IAAI,CAAC;AAC5D,MAAI,WAAW,OAAW,QAAO,GAAG,KAAK,MAAM,WAAW,KAAM,CAAC;AACjE,SAAO,GAAG,KAAK,MAAM,WAAW,MAAS,CAAC;AAC5C;AAEO,SAAS,gBAAgB,eAAuB,OAAuB;AAC5E,MAAI,CAAC,WAAW,KAAK,aAAa,GAAG;AACnC,UAAM,MAAM,QAAQ,IAAI,UAAU;AAClC,QAAI,QAAQ,iBAAiB,QAAQ,QAAQ;AAC3C,YAAM,IAAI;AAAA,QACR,4CAA4C,KAAK,UAAU,aAAa,CAAC;AAAA,MAC3E;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,cAAc,WAAW,GAAG;AAC7C,QAAM,MAAM,WAAW,cAAc,MAAM,CAAC,IAAI;AAEhD,QAAM,UAAU,OAAO,EAAE,KAAK,OAAO,KAAK;AAC1C,QAAM,QAAQ,OAAO,GAAG;AAExB,QAAM,QAAQ,QAAQ;AACtB,QAAM,YAAY,QAAQ;AAE1B,QAAM,gBAAgB,UAAU,SAAS,EAAE,SAAS,OAAO,GAAG;AAC9D,QAAM,QAAQ,cACX,MAAM,GAAG,uBAAuB,EAChC,OAAO,yBAAyB,GAAG;AAEtC,QAAM,YAAY,IAAI,MAAM,SAAS,CAAC,IAAI,KAAK;AAC/C,SAAO,YAAY,UAAU,KAAK,IAAI,SAAS,KAAK;AACtD;AAEO,SAAS,WAAW,eAAuB,OAAuB;AACvE,MAAI,CAAC,WAAW,KAAK,aAAa,GAAG;AACnC,UAAM,MAAM,QAAQ,IAAI,UAAU;AAClC,QAAI,QAAQ,iBAAiB,QAAQ,QAAQ;AAC3C,YAAM,IAAI;AAAA,QACR,uCAAuC,KAAK,UAAU,aAAa,CAAC;AAAA,MACtE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,cAAc,WAAW,GAAG;AAC7C,QAAM,MAAM,WAAW,cAAc,MAAM,CAAC,IAAI;AAEhD,QAAM,UAAU,OAAO,EAAE,KAAK,OAAO,KAAK;AAC1C,QAAM,QAAQ,OAAO,GAAG;AAGxB,QAAM,QAAQ,QAAQ;AACtB,QAAM,YAAY,QAAQ;AAE1B,QAAM,gBAAgB,UAAU,SAAS,EAAE,SAAS,OAAO,GAAG;AAC9D,QAAM,QAAQ,cAAc,MAAM,GAAG,CAAC,EAAE,OAAO,GAAG,GAAG;AAErD,QAAM,YAAY,IAAI,MAAM,SAAS,CAAC,IAAI,KAAK;AAE/C,SAAO,YAAY,UAAU,KAAK,IAAI,SAAS,KAAK;AACtD;","names":[]}
package/dist/cli.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import Docker from 'dockerode';
3
+ import { C as ComposeLoaderOptions, T as TownhouseConfig, W as WalletManager, N as NodeType } from './manager-SsneW_Mj.js';
3
4
 
4
5
  /**
5
6
  * Cross-platform browser opener for the wizard CLI command.
@@ -9,6 +10,33 @@ interface BrowserOpener {
9
10
  open(url: string): Promise<void>;
10
11
  }
11
12
 
13
+ /**
14
+ * Port-collision preflight for `townhouse hs up` (Epic 49 Followup B).
15
+ *
16
+ * Detects host-port conflicts BEFORE handing off to Docker, so operators get
17
+ * an actionable error message instead of a cryptic mid-boot EADDRINUSE.
18
+ *
19
+ * Detection strategy (defense in depth):
20
+ * 1. Bind a transient TCP socket to 127.0.0.1:<port> and immediately close.
21
+ * If bind throws EADDRINUSE, the port is occupied. Pure Node, no deps,
22
+ * works on Linux/Mac/WSL — this is the source of truth.
23
+ * 2. If (1) flags a collision, ask Docker for the offending container's
24
+ * name + compose project so the message can name a culprit. Best-effort
25
+ * enrichment — Docker may be unreachable, in which case we still report
26
+ * the port and suggest `lsof` for non-Docker processes.
27
+ */
28
+
29
+ interface PortCollision {
30
+ /** The host port that is already bound. */
31
+ port: number;
32
+ /** Name of the Docker container holding the port (when known). */
33
+ containerName?: string;
34
+ /** Compose project the container belongs to (when known). */
35
+ composeProject?: string;
36
+ /** Container status string e.g. "Up 5 hours" (when known). */
37
+ status?: string;
38
+ }
39
+
12
40
  /**
13
41
  * CLI entrypoint for `@toon-protocol/townhouse` (Story 21.1).
14
42
  *
@@ -29,10 +57,74 @@ interface BrowserOpener {
29
57
  declare class CliHelpRequested extends Error {
30
58
  constructor();
31
59
  }
60
+ /**
61
+ * Dependency-injection overrides for the `hs up` / `hs down` CLI path.
62
+ * Used by unit tests to stub out Docker, file I/O, and admin client.
63
+ */
64
+ interface CliHsOverrides {
65
+ /** Override materializeComposeTemplate (avoids disk writes in tests). */
66
+ materializeComposeTemplate?: (profile: string, opts?: ComposeLoaderOptions) => {
67
+ composePath: string;
68
+ manifestPath: string;
69
+ };
70
+ /** Override the DockerOrchestrator constructor (avoids real Docker in tests). */
71
+ createOrchestrator?: (docker: Docker, config: TownhouseConfig, walletManager: WalletManager | undefined, options: {
72
+ profile: 'hs';
73
+ composePath: string;
74
+ }) => {
75
+ up: (profiles: NodeType[]) => Promise<void>;
76
+ down: () => Promise<void>;
77
+ on: (event: string, handler: (...args: unknown[]) => void) => unknown;
78
+ /**
79
+ * Pre-pull a single image ref (Epic 49 Followup D).
80
+ * Optional on the stub interface — when omitted on a real orchestrator,
81
+ * the cold-pull narration phase is skipped (silent degrade).
82
+ */
83
+ pullImage?: (image: string) => Promise<void>;
84
+ };
85
+ /** Override ConnectorAdminClient construction (avoids real HTTP in tests). */
86
+ createAdminClient?: (baseUrl: string, timeoutMs: number) => {
87
+ getHsHostname: () => Promise<{
88
+ hostname: string | null;
89
+ publishedAt: string | null;
90
+ }>;
91
+ };
92
+ /** Override `docker compose down -v` spawn for --rotate-keys (avoids real Docker). */
93
+ runComposeDown?: (composePath: string, withVolumes: boolean) => Promise<void>;
94
+ /**
95
+ * Override BootReconciler construction (Story 46.1). Tests inject a stub
96
+ * with a spied-on `reconcile()` to assert wiring without touching disk
97
+ * or the connector. When omitted, the default constructs a real
98
+ * `BootReconciler` against `~/.townhouse/{nodes.yaml,reconciler.log}`.
99
+ */
100
+ createReconciler?: (nodesYamlPath: string, reconcilerLogPath: string) => {
101
+ reconcile: () => Promise<void>;
102
+ };
103
+ /**
104
+ * Override the port-collision preflight check (Epic 49 Followup B).
105
+ * Default invokes `checkHsPortCollisions(docker)` from
106
+ * `./cli/preflight-ports.js`. Tests inject a stub that returns either
107
+ * `[]` (happy path) or a fabricated PortCollision[] (collision path) so
108
+ * the production socket-bind + Docker enrichment is not exercised in
109
+ * unit tests.
110
+ */
111
+ checkPortCollisions?: (docker: Docker) => Promise<PortCollision[]>;
112
+ }
113
+ /**
114
+ * Dependency-injection overrides for the `node add` / `node remove` / `node list` CLI path.
115
+ * Used by unit tests to stub `fetch` and the interactive confirmation prompt.
116
+ */
117
+ interface CliNodeCommandOverrides {
118
+ fetch?: (url: string, init?: RequestInit) => Promise<Response>;
119
+ confirm?: (question: string) => Promise<boolean>;
120
+ apiUrl?: string;
121
+ }
32
122
  /**
33
123
  * Main CLI entry — exported for testability (same pattern as Mill CLI).
34
124
  * Accepts optional dockerode instance for dependency injection in tests.
125
+ * The optional `hsOverrides` bag is used by unit tests to stub out Docker,
126
+ * file I/O, and admin-client calls in the `hs up` / `hs down` path.
35
127
  */
36
- declare function main(argv: string[], dockerInstance?: Docker, browserOpener?: BrowserOpener): Promise<void>;
128
+ declare function main(argv: string[], dockerInstance?: Docker, browserOpener?: BrowserOpener, hsOverrides?: CliHsOverrides, nodeCommandOverrides?: CliNodeCommandOverrides): Promise<void>;
37
129
 
38
- export { CliHelpRequested, main };
130
+ export { CliHelpRequested, type CliHsOverrides, type CliNodeCommandOverrides, main };