arc402-cli 0.7.4 → 0.7.5

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/dist/index.js CHANGED
@@ -86,8 +86,8 @@ if (printMode) {
86
86
  process.exit(1);
87
87
  });
88
88
  }
89
- else if (process.stdout.isTTY && !hasSubcommand && process.argv.length <= 2) {
90
- // TTY with no subcommand — launch Ink TUI
89
+ else if (process.stdout.isTTY && !hasSubcommand && process.argv.length <= 2 && !process.env.ARC402_NO_TUI) {
90
+ // TTY with no subcommand — launch Ink TUI (unless spawned by TUI as a child process)
91
91
  checkUpgrade();
92
92
  void Promise.resolve().then(() => __importStar(require("./tui/index"))).then(({ launchTUI }) => launchTUI()).catch((e) => {
93
93
  console.error("TUI failed to start:", e instanceof Error ? e.message : String(e));
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/tui/App.d.ts CHANGED
@@ -5,7 +5,15 @@ interface AppProps {
5
5
  balance?: string;
6
6
  }
7
7
  /**
8
- * Root TUI component — fixed header/footer with scrollable viewport.
8
+ * Root TUI component — box-drawn frame with fixed header/footer, scrollable viewport.
9
+ *
10
+ * ┌─────────────────────────────────────────────┐
11
+ * │ ASCII banner + status info │ ← FIXED header
12
+ * ├─────────────────────────────────────────────┤
13
+ * │ scrollable output │ ← VIEWPORT
14
+ * ├─────────────────────────────────────────────┤
15
+ * │ ◈ arc402 > _ │ ← FIXED footer
16
+ * └─────────────────────────────────────────────┘
9
17
  */
10
18
  export declare function App({ version, network, wallet, balance }: AppProps): import("react/jsx-runtime").JSX.Element;
11
19
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"AAiBA,UAAU,QAAQ;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,QAAQ,2CA0LlE"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"AAaA,UAAU,QAAQ;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,QAAQ,2CAgNlE"}
package/dist/tui/App.js CHANGED
@@ -9,21 +9,30 @@ const react_1 = require("react");
9
9
  const ink_1 = require("ink");
10
10
  const Header_1 = require("./Header");
11
11
  const Viewport_1 = require("./Viewport");
12
- const Footer_1 = require("./Footer");
13
12
  const InputLine_1 = require("./InputLine");
14
13
  const useCommand_1 = require("./useCommand");
15
14
  const useChat_1 = require("./useChat");
16
15
  const useScroll_1 = require("./useScroll");
17
16
  const program_1 = require("../program");
18
17
  const chalk_1 = __importDefault(require("chalk"));
19
- // eslint-disable-next-line @typescript-eslint/no-var-requires
20
- const pkg = require("../../package.json");
21
18
  const BUILTIN_CMDS = ["help", "exit", "quit", "clear", "status"];
22
19
  /**
23
- * Root TUI component — fixed header/footer with scrollable viewport.
20
+ * Root TUI component — box-drawn frame with fixed header/footer, scrollable viewport.
21
+ *
22
+ * ┌─────────────────────────────────────────────┐
23
+ * │ ASCII banner + status info │ ← FIXED header
24
+ * ├─────────────────────────────────────────────┤
25
+ * │ scrollable output │ ← VIEWPORT
26
+ * ├─────────────────────────────────────────────┤
27
+ * │ ◈ arc402 > _ │ ← FIXED footer
28
+ * └─────────────────────────────────────────────┘
24
29
  */
25
30
  function App({ version, network, wallet, balance }) {
26
31
  const { exit } = (0, ink_1.useApp)();
32
+ const { stdout } = (0, ink_1.useStdout)();
33
+ const cols = stdout?.columns ?? 60;
34
+ const W = Math.min(cols, 80); // inner width between │ chars
35
+ const inner = W - 2; // space between the two │ border chars
27
36
  const [outputBuffer, setOutputBuffer] = (0, react_1.useState)([
28
37
  chalk_1.default.dim(" Type 'help' to see available commands"),
29
38
  "",
@@ -32,8 +41,8 @@ function App({ version, network, wallet, balance }) {
32
41
  const { execute, isRunning } = (0, useCommand_1.useCommand)();
33
42
  const { send, isSending } = (0, useChat_1.useChat)();
34
43
  // Approximate viewport height for scroll management
35
- const HEADER_ROWS = 15;
36
- const FOOTER_ROWS = 1;
44
+ const HEADER_ROWS = 17;
45
+ const FOOTER_ROWS = 3;
37
46
  const rows = process.stdout.rows ?? 24;
38
47
  const viewportHeight = Math.max(1, rows - HEADER_ROWS - FOOTER_ROWS);
39
48
  const { scrollOffset, isAutoScroll, scrollUp, scrollDown, snapToBottom } = (0, useScroll_1.useScroll)(viewportHeight);
@@ -149,6 +158,9 @@ function App({ version, network, wallet, balance }) {
149
158
  setIsProcessing(false);
150
159
  }, [appendLine, execute, send, snapToBottom, topCmds, network, wallet, balance, exit]);
151
160
  const isDisabled = isProcessing || isRunning || isSending;
152
- return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", height: "100%", children: [(0, jsx_runtime_1.jsx)(Header_1.Header, { version: version, network: network, wallet: wallet, balance: balance }), (0, jsx_runtime_1.jsx)(ink_1.Box, { children: (0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "".repeat(60) }) }), (0, jsx_runtime_1.jsx)(Viewport_1.Viewport, { lines: outputBuffer, scrollOffset: scrollOffset, isAutoScroll: isAutoScroll }), (0, jsx_runtime_1.jsx)(Footer_1.Footer, { children: (0, jsx_runtime_1.jsx)(InputLine_1.InputLine, { onSubmit: handleCommand, isDisabled: isDisabled }) })] }));
161
+ const topBorder = "" + "".repeat(inner) + "";
162
+ const midBorder = "├" + "─".repeat(inner) + "┤";
163
+ const botBorder = "└" + "─".repeat(inner) + "┘";
164
+ return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", height: "100%", children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: topBorder }), (0, jsx_runtime_1.jsx)(Header_1.Header, { version: version, network: network, wallet: wallet, balance: balance, innerWidth: inner }), (0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: midBorder }), (0, jsx_runtime_1.jsx)(Viewport_1.Viewport, { lines: outputBuffer, scrollOffset: scrollOffset, isAutoScroll: isAutoScroll, innerWidth: inner }), (0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: midBorder }), (0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "\u2502" }), (0, jsx_runtime_1.jsx)(ink_1.Box, { flexGrow: 1, children: (0, jsx_runtime_1.jsx)(InputLine_1.InputLine, { onSubmit: handleCommand, isDisabled: isDisabled }) }), (0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "\u2502" })] }), (0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: botBorder })] }));
153
165
  }
154
166
  //# sourceMappingURL=App.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":";;;;;AA2BA,kBA0LC;;AArND,iCAAgE;AAChE,6BAAwC;AACxC,qCAAkC;AAClC,yCAAsC;AACtC,qCAAkC;AAClC,2CAAwC;AACxC,6CAA0C;AAC1C,uCAAoC;AACpC,2CAAwC;AACxC,wCAA2C;AAC3C,kDAA0B;AAE1B,8DAA8D;AAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAwB,CAAC;AAEjE,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AASjE;;GAEG;AACH,SAAgB,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAY;IACjE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,YAAM,GAAE,CAAC;IAC1B,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,IAAA,gBAAQ,EAAW;QACzD,eAAK,CAAC,GAAG,CAAC,yCAAyC,CAAC;QACpD,EAAE;KACH,CAAC,CAAC;IACH,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAExD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,IAAA,uBAAU,GAAE,CAAC;IAC5C,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAA,iBAAO,GAAE,CAAC;IAEtC,oDAAoD;IACpD,MAAM,WAAW,GAAG,EAAE,CAAC;IACvB,MAAM,WAAW,GAAG,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;IACvC,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC;IAErE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,GACtE,IAAA,qBAAS,EAAC,cAAc,CAAC,CAAC;IAE5B,qDAAqD;IACrD,MAAM,CAAC,OAAO,CAAC,GAAG,IAAA,gBAAQ,EAAW,GAAG,EAAE;QACxC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAA,uBAAa,GAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,IAAA,mBAAW,EAAC,CAAC,IAAY,EAAE,EAAE;QAC9C,eAAe,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7C,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,aAAa,GAAG,IAAA,mBAAW,EAC/B,KAAK,EAAE,KAAa,EAAiB,EAAE;QACrC,2BAA2B;QAC3B,UAAU,CACR,eAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YACnB,GAAG;YACH,eAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnB,GAAG;YACH,eAAK,CAAC,KAAK,CAAC,GAAG,CAAC;YAChB,GAAG;YACH,eAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CACrB,CAAC;QAEF,gCAAgC;QAChC,YAAY,EAAE,CAAC;QACf,eAAe,CAAC,IAAI,CAAC,CAAC;QAEtB,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,CAAC,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC,CAAC;QAE/C,0EAA0E;QAC1E,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACzC,UAAU,CACR,GAAG,GAAG,eAAK,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,eAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CACpD,CAAC;YACF,eAAe,CAAC,KAAK,CAAC,CAAC;YACvB,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,0EAA0E;QAC1E,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,eAAe,CAAC,EAAE,CAAC,CAAC;YACpB,eAAe,CAAC,KAAK,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;QAED,0EAA0E;QAC1E,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAA,uBAAa,GAAE,CAAC;gBAC7B,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpB,MAAM,QAAQ,GAAa,EAAE,CAAC;gBAC9B,IAAI,CAAC,eAAe,CAAC;oBACnB,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;oBACrC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;iBACtC,CAAC,CAAC;gBACH,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;gBACtD,CAAC;gBAAC,MAAM,CAAC;oBACP,0CAA0C;gBAC5C,CAAC;gBACD,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;oBAC7B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;wBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,KAAK,CAAC,IAAI,CAAC,eAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC;YAC/C,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,eAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;YACrC,KAAK,CAAC,IAAI,CACR,IAAI;gBACF,eAAK,CAAC,KAAK,CAAC,WAAW,CAAC;gBACxB,eAAK,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAC1D,CAAC;YACF,KAAK,CAAC,IAAI,CACR,IAAI;gBACF,eAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC;gBAC9B,eAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAC3C,CAAC;YACF,KAAK,CAAC,IAAI,CACR,eAAK,CAAC,GAAG,CACP,6DAA6D,CAC9D,CACF,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,MAAM,CAAC,IAAI,KAAK;gBAAE,UAAU,CAAC,CAAC,CAAC,CAAC;YACrC,eAAe,CAAC,KAAK,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;QAED,0EAA0E;QAC1E,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvB,IAAI,OAAO;gBACT,UAAU,CACR,IAAI,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,eAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CACrD,CAAC;YACJ,IAAI,MAAM;gBACR,UAAU,CAAC,IAAI,eAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,eAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAClE,IAAI,OAAO;gBACT,UAAU,CAAC,IAAI,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,eAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACnE,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO;gBACjC,UAAU,CAAC,eAAK,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC,CAAC;YAChF,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,eAAe,CAAC,KAAK,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;QAED,0EAA0E;QAC1E,MAAM,cAAc,GAAG,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,WAAW,GACf,cAAc,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,KAAK,EAAE,CAAC,CAAC;QAExE,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;YAC3D,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAC9B,CAAC;YACD,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,eAAe,CAAC,KAAK,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;QAED,0EAA0E;QAC1E,MAAM,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QACjC,UAAU,CAAC,EAAE,CAAC,CAAC;QACf,eAAe,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC,EACD,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CACnF,CAAC;IAEF,MAAM,UAAU,GAAG,YAAY,IAAI,SAAS,IAAI,SAAS,CAAC;IAE1D,OAAO,CACL,wBAAC,SAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,MAAM,EAAC,MAAM,aAEvC,uBAAC,eAAM,IACL,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,GAChB,EAGF,uBAAC,SAAG,cACF,uBAAC,UAAI,IAAC,QAAQ,kBAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAQ,GAClC,EAGN,uBAAC,mBAAQ,IACP,KAAK,EAAE,YAAY,EACnB,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,YAAY,GAC1B,EAGF,uBAAC,eAAM,cACL,uBAAC,qBAAS,IAAC,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,GAAI,GACvD,IACL,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"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"}
@@ -4,10 +4,11 @@ interface HeaderProps {
4
4
  network?: string;
5
5
  wallet?: string;
6
6
  balance?: string;
7
+ innerWidth?: number;
7
8
  }
8
9
  /**
9
10
  * Fixed header showing the ASCII art banner + status info.
10
- * Never re-renders unless config changes.
11
+ * Each line is framed with │ … │ box-drawing borders.
11
12
  */
12
13
  export declare const Header: React.NamedExoticComponent<HeaderProps>;
13
14
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../src/tui/Header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,yCAcjB,CAAC"}
1
+ {"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../src/tui/Header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,yCAoBjB,CAAC"}
@@ -10,10 +10,10 @@ const ink_1 = require("ink");
10
10
  const banner_1 = require("../ui/banner");
11
11
  /**
12
12
  * Fixed header showing the ASCII art banner + status info.
13
- * Never re-renders unless config changes.
13
+ * Each line is framed with │ … │ box-drawing borders.
14
14
  */
15
- exports.Header = react_1.default.memo(function Header({ network, wallet, balance, }) {
15
+ exports.Header = react_1.default.memo(function Header({ network, wallet, balance, innerWidth = 58, }) {
16
16
  const bannerLines = (0, banner_1.getBannerLines)({ network, wallet, balance });
17
- return ((0, jsx_runtime_1.jsx)(ink_1.Box, { flexDirection: "column", children: bannerLines.map((line, i) => ((0, jsx_runtime_1.jsx)(ink_1.Text, { children: line }, i))) }));
17
+ return ((0, jsx_runtime_1.jsx)(ink_1.Box, { flexDirection: "column", children: bannerLines.map((line, i) => ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "\u2502" }), (0, jsx_runtime_1.jsx)(ink_1.Text, { children: " " + line }), (0, jsx_runtime_1.jsx)(ink_1.Box, { flexGrow: 1 }), (0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "\u2502" })] }, i))) }));
18
18
  });
19
19
  //# sourceMappingURL=Header.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Header.js","sourceRoot":"","sources":["../../src/tui/Header.tsx"],"names":[],"mappings":";;;;;;;AAAA,kDAA0B;AAC1B,6BAAgC;AAChC,yCAA8C;AAS9C;;;GAGG;AACU,QAAA,MAAM,GAAG,eAAK,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,EAC/C,OAAO,EACP,MAAM,EACN,OAAO,GACK;IACZ,MAAM,WAAW,GAAG,IAAA,uBAAc,EAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IAEjE,OAAO,CACL,uBAAC,SAAG,IAAC,aAAa,EAAC,QAAQ,YACxB,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAC5B,uBAAC,UAAI,cAAU,IAAI,IAAR,CAAC,CAAe,CAC5B,CAAC,GACE,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"Header.js","sourceRoot":"","sources":["../../src/tui/Header.tsx"],"names":[],"mappings":";;;;;;;AAAA,kDAA0B;AAC1B,6BAAgC;AAChC,yCAA8C;AAU9C;;;GAGG;AACU,QAAA,MAAM,GAAG,eAAK,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,EAC/C,OAAO,EACP,MAAM,EACN,OAAO,EACP,UAAU,GAAG,EAAE,GACH;IACZ,MAAM,WAAW,GAAG,IAAA,uBAAc,EAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IAEjE,OAAO,CACL,uBAAC,SAAG,IAAC,aAAa,EAAC,QAAQ,YACxB,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAC5B,wBAAC,SAAG,eACF,uBAAC,UAAI,IAAC,QAAQ,6BAAS,EACvB,uBAAC,UAAI,cAAE,GAAG,GAAG,IAAI,GAAQ,EACzB,uBAAC,SAAG,IAAC,QAAQ,EAAE,CAAC,GAAI,EACpB,uBAAC,UAAI,IAAC,QAAQ,6BAAS,KAJf,CAAC,CAKL,CACP,CAAC,GACE,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -2,13 +2,12 @@ interface ViewportProps {
2
2
  lines: string[];
3
3
  scrollOffset: number;
4
4
  isAutoScroll: boolean;
5
+ innerWidth?: number;
5
6
  }
6
7
  /**
7
- * Scrollable output area that fills remaining terminal space.
8
- * Renders a window slice of the buffer, not terminal scroll.
9
- * scrollOffset=0 means pinned to bottom (auto-scroll).
10
- * Positive scrollOffset means scrolled up by that many lines.
8
+ * Scrollable output area framed with │ box-drawing borders.
9
+ * Fills remaining terminal space between header and footer separators.
11
10
  */
12
- export declare function Viewport({ lines, scrollOffset, isAutoScroll }: ViewportProps): import("react/jsx-runtime").JSX.Element;
11
+ export declare function Viewport({ lines, scrollOffset, isAutoScroll, innerWidth }: ViewportProps): import("react/jsx-runtime").JSX.Element;
13
12
  export {};
14
13
  //# sourceMappingURL=Viewport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Viewport.d.ts","sourceRoot":"","sources":["../../src/tui/Viewport.tsx"],"names":[],"mappings":"AAGA,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,aAAa,2CAsD5E"}
1
+ {"version":3,"file":"Viewport.d.ts","sourceRoot":"","sources":["../../src/tui/Viewport.tsx"],"names":[],"mappings":"AAGA,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,UAAe,EAAE,EAAE,aAAa,2CAmD7F"}
@@ -4,34 +4,24 @@ exports.Viewport = Viewport;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const ink_1 = require("ink");
6
6
  /**
7
- * Scrollable output area that fills remaining terminal space.
8
- * Renders a window slice of the buffer, not terminal scroll.
9
- * scrollOffset=0 means pinned to bottom (auto-scroll).
10
- * Positive scrollOffset means scrolled up by that many lines.
7
+ * Scrollable output area framed with │ box-drawing borders.
8
+ * Fills remaining terminal space between header and footer separators.
11
9
  */
12
- function Viewport({ lines, scrollOffset, isAutoScroll }) {
10
+ function Viewport({ lines, scrollOffset, isAutoScroll, innerWidth = 58 }) {
13
11
  const { stdout } = (0, ink_1.useStdout)();
14
12
  const termRows = stdout?.rows ?? 24;
15
- // We'll compute the viewport height: total rows minus fixed areas
16
- // Header is approximately bannerLines + separator (~14-16 rows)
17
- // Footer is 1 row
18
- // We'll use a reasonable estimate here; the parent App can pass exact height
19
- const HEADER_ROWS = 15; // approximate
20
- const FOOTER_ROWS = 1;
21
- const viewportHeight = Math.max(1, termRows - HEADER_ROWS - FOOTER_ROWS);
13
+ // Header (~14 rows) + top/mid/mid/bot borders (4) + footer input (1) = ~19 fixed rows
14
+ const FIXED_ROWS = 19;
15
+ const viewportHeight = Math.max(1, termRows - FIXED_ROWS);
22
16
  // Compute the window slice
23
- // scrollOffset=0 → show last viewportHeight lines
24
- // scrollOffset=N → show lines ending viewportHeight+N from end
25
17
  const totalLines = lines.length;
26
18
  let endIdx;
27
19
  let startIdx;
28
20
  if (scrollOffset === 0) {
29
- // Auto-scroll: pinned to bottom
30
21
  endIdx = totalLines;
31
22
  startIdx = Math.max(0, endIdx - viewportHeight);
32
23
  }
33
24
  else {
34
- // Scrolled up: scrollOffset lines from bottom
35
25
  endIdx = Math.max(0, totalLines - scrollOffset);
36
26
  startIdx = Math.max(0, endIdx - viewportHeight);
37
27
  }
@@ -43,6 +33,6 @@ function Viewport({ lines, scrollOffset, isAutoScroll }) {
43
33
  ...visibleLines,
44
34
  ];
45
35
  const canScrollDown = scrollOffset > 0;
46
- return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", flexGrow: 1, children: [(0, jsx_runtime_1.jsx)(ink_1.Box, { flexDirection: "column", flexGrow: 1, children: paddedLines.map((line, i) => ((0, jsx_runtime_1.jsx)(ink_1.Text, { children: line }, i))) }), canScrollDown && !isAutoScroll && ((0, jsx_runtime_1.jsx)(ink_1.Box, { justifyContent: "flex-end", children: (0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "\u2193 more" }) }))] }));
36
+ return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", flexGrow: 1, children: [paddedLines.map((line, i) => ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "\u2502" }), (0, jsx_runtime_1.jsx)(ink_1.Text, { children: " " + line }), (0, jsx_runtime_1.jsx)(ink_1.Box, { flexGrow: 1 }), (0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "\u2502" })] }, i))), canScrollDown && !isAutoScroll && ((0, jsx_runtime_1.jsxs)(ink_1.Box, { justifyContent: "flex-end", children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "\u2502 \u2193 more" }), (0, jsx_runtime_1.jsx)(ink_1.Box, { flexGrow: 1 }), (0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "\u2502" })] }))] }));
47
37
  }
48
38
  //# sourceMappingURL=Viewport.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Viewport.js","sourceRoot":"","sources":["../../src/tui/Viewport.tsx"],"names":[],"mappings":";;AAeA,4BAsDC;;AApED,6BAA2C;AAQ3C;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAiB;IAC3E,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,eAAS,GAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;IAEpC,kEAAkE;IAClE,gEAAgE;IAChE,kBAAkB;IAClB,6EAA6E;IAC7E,MAAM,WAAW,GAAG,EAAE,CAAC,CAAC,cAAc;IACtC,MAAM,WAAW,GAAG,CAAC,CAAC;IACtB,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC;IAEzE,2BAA2B;IAC3B,kDAAkD;IAClD,+DAA+D;IAC/D,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;IAChC,IAAI,MAAc,CAAC;IACnB,IAAI,QAAgB,CAAC;IAErB,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;QACvB,gCAAgC;QAChC,MAAM,GAAG,UAAU,CAAC;QACpB,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,8CAA8C;QAC9C,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC,CAAC;QAChD,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEnD,oDAAoD;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG;QAClB,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,GAAG,YAAY;KAChB,CAAC;IAEF,MAAM,aAAa,GAAG,YAAY,GAAG,CAAC,CAAC;IAEvC,OAAO,CACL,wBAAC,SAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,aACrC,uBAAC,SAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,YACpC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAC5B,uBAAC,UAAI,cAAU,IAAI,IAAR,CAAC,CAAe,CAC5B,CAAC,GACE,EACL,aAAa,IAAI,CAAC,YAAY,IAAI,CACjC,uBAAC,SAAG,IAAC,cAAc,EAAC,UAAU,YAC5B,uBAAC,UAAI,IAAC,QAAQ,kCAAc,GACxB,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"Viewport.js","sourceRoot":"","sources":["../../src/tui/Viewport.tsx"],"names":[],"mappings":";;AAcA,4BAmDC;;AAhED,6BAA2C;AAS3C;;;GAGG;AACH,SAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,GAAG,EAAE,EAAiB;IAC5F,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,eAAS,GAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;IAEpC,sFAAsF;IACtF,MAAM,UAAU,GAAG,EAAE,CAAC;IACtB,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC,CAAC;IAE1D,2BAA2B;IAC3B,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;IAChC,IAAI,MAAc,CAAC;IACnB,IAAI,QAAgB,CAAC;IAErB,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,GAAG,UAAU,CAAC;QACpB,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC,CAAC;QAChD,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEnD,oDAAoD;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG;QAClB,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,GAAG,YAAY;KAChB,CAAC;IAEF,MAAM,aAAa,GAAG,YAAY,GAAG,CAAC,CAAC;IAEvC,OAAO,CACL,wBAAC,SAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,aACpC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAC5B,wBAAC,SAAG,eACF,uBAAC,UAAI,IAAC,QAAQ,6BAAS,EACvB,uBAAC,UAAI,cAAE,GAAG,GAAG,IAAI,GAAQ,EACzB,uBAAC,SAAG,IAAC,QAAQ,EAAE,CAAC,GAAI,EACpB,uBAAC,UAAI,IAAC,QAAQ,6BAAS,KAJf,CAAC,CAKL,CACP,CAAC,EACD,aAAa,IAAI,CAAC,YAAY,IAAI,CACjC,wBAAC,SAAG,IAAC,cAAc,EAAC,UAAU,aAC5B,uBAAC,UAAI,IAAC,QAAQ,yCAAgB,EAC9B,uBAAC,SAAG,IAAC,QAAQ,EAAE,CAAC,GAAI,EACpB,uBAAC,UAAI,IAAC,QAAQ,6BAAS,IACnB,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
@@ -4,8 +4,13 @@ interface UseCommandResult {
4
4
  }
5
5
  /**
6
6
  * Dispatches parsed commands to the commander program.
7
- * Captures stdout/stderr by monkey-patching process.stdout.write
8
- * and routes all output to the viewport buffer via onLine callback.
7
+ *
8
+ * NON-INTERACTIVE commands: captures stdout/stderr by monkey-patching
9
+ * process.stdout.write and routes output to the viewport.
10
+ *
11
+ * INTERACTIVE commands (WalletConnect, prompts): spawns a child process
12
+ * running `arc402 <command>` with inherited stdin so that QR codes render
13
+ * and prompts accept input. Output is captured line-by-line into the viewport.
9
14
  */
10
15
  export declare function useCommand(): UseCommandResult;
11
16
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"useCommand.d.ts","sourceRoot":"","sources":["../../src/tui/useCommand.ts"],"names":[],"mappings":"AAKA,UAAU,gBAAgB;IACxB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,gBAAgB,CA+F7C"}
1
+ {"version":3,"file":"useCommand.d.ts","sourceRoot":"","sources":["../../src/tui/useCommand.ts"],"names":[],"mappings":"AAyCA,UAAU,gBAAgB;IACxB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,IAAI,gBAAgB,CAmB7C"}
@@ -6,91 +6,173 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.useCommand = useCommand;
7
7
  const react_1 = require("react");
8
8
  const program_1 = require("../program");
9
+ const child_process_1 = require("child_process");
9
10
  const chalk_1 = __importDefault(require("chalk"));
10
11
  const colors_1 = require("../ui/colors");
12
+ /**
13
+ * Commands that use interactive prompts or WalletConnect QR flows.
14
+ * These MUST run in a child process so they can own stdin/stdout directly,
15
+ * because Ink holds stdin in raw mode for its own input handling.
16
+ */
17
+ const INTERACTIVE_COMMANDS = new Set([
18
+ "wallet deploy",
19
+ "wallet set-guardian",
20
+ "wallet unfreeze",
21
+ "wallet authorize-machine-key",
22
+ "wallet revoke-machine-key",
23
+ "wallet set-passkey",
24
+ "wallet set-interceptor",
25
+ "wallet set-velocity-limit",
26
+ "wallet upgrade-registry",
27
+ "wallet execute-registry-upgrade",
28
+ "wallet cancel-registry-upgrade",
29
+ "wallet register-policy",
30
+ "wallet whitelist-contract",
31
+ "wallet governance setup",
32
+ "wallet policy set-limit",
33
+ "wallet policy set-daily-limit",
34
+ "wallet policy set",
35
+ "wallet import",
36
+ "config init",
37
+ ]);
38
+ function isInteractiveCommand(input) {
39
+ const normalized = input.trim();
40
+ for (const cmd of INTERACTIVE_COMMANDS) {
41
+ if (normalized === cmd || normalized.startsWith(cmd + " "))
42
+ return true;
43
+ }
44
+ return false;
45
+ }
11
46
  /**
12
47
  * Dispatches parsed commands to the commander program.
13
- * Captures stdout/stderr by monkey-patching process.stdout.write
14
- * and routes all output to the viewport buffer via onLine callback.
48
+ *
49
+ * NON-INTERACTIVE commands: captures stdout/stderr by monkey-patching
50
+ * process.stdout.write and routes output to the viewport.
51
+ *
52
+ * INTERACTIVE commands (WalletConnect, prompts): spawns a child process
53
+ * running `arc402 <command>` with inherited stdin so that QR codes render
54
+ * and prompts accept input. Output is captured line-by-line into the viewport.
15
55
  */
16
56
  function useCommand() {
17
57
  const [isRunning, setIsRunning] = (0, react_1.useState)(false);
18
58
  const execute = (0, react_1.useCallback)(async (input, onLine) => {
19
59
  setIsRunning(true);
20
- // Capture stdout/stderr
21
- const originalStdoutWrite = process.stdout.write.bind(process.stdout);
22
- const originalStderrWrite = process.stderr.write.bind(process.stderr);
23
- let captureBuffer = "";
24
- const flushBuffer = () => {
25
- if (!captureBuffer)
26
- return;
27
- const lines = captureBuffer.split("\n");
28
- captureBuffer = lines.pop() ?? "";
29
- for (const line of lines) {
30
- onLine(line);
31
- }
32
- };
33
- const capturedWrite = (chunk, encodingOrCb, cb) => {
34
- const str = typeof chunk === "string"
35
- ? chunk
36
- : Buffer.from(chunk).toString("utf8");
37
- captureBuffer += str;
38
- flushBuffer();
39
- // call callback if provided
40
- const callback = typeof encodingOrCb === "function" ? encodingOrCb : cb;
41
- if (callback)
42
- callback();
43
- return true;
44
- };
45
- // Monkey-patch (cast through unknown to bypass strict overload checking)
46
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
- process.stdout.write = capturedWrite;
48
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
- process.stderr.write = capturedWrite;
50
- try {
51
- const tokens = parseTokens(input);
52
- const prog = (0, program_1.createProgram)();
53
- prog.exitOverride();
54
- prog.configureOutput({
55
- writeOut: (str) => process.stdout.write(str),
56
- writeErr: (str) => process.stderr.write(str),
57
- });
58
- await prog.parseAsync(["node", "arc402", ...tokens]);
60
+ if (isInteractiveCommand(input)) {
61
+ await executeInteractive(input, onLine);
59
62
  }
60
- catch (err) {
61
- const e = err;
62
- if (e.code === "commander.helpDisplayed" ||
63
- e.code === "commander.version" ||
64
- e.code === "commander.executeSubCommandAsync") {
65
- // already written or normal exit — no-op
66
- }
67
- else if (e.code === "commander.unknownCommand") {
68
- const tokens = parseTokens(input);
69
- onLine(` ${colors_1.c.failure} ${chalk_1.default.red(`Unknown command: ${chalk_1.default.white(tokens[0])}`)} `);
70
- onLine(chalk_1.default.dim(" Type 'help' for available commands"));
71
- }
72
- else if (e.code?.startsWith("commander.")) {
73
- onLine(` ${colors_1.c.failure} ${chalk_1.default.red(e.message ?? String(err))}`);
63
+ else {
64
+ await executeInProcess(input, onLine);
65
+ }
66
+ setIsRunning(false);
67
+ }, []);
68
+ return { execute, isRunning };
69
+ }
70
+ /**
71
+ * Run an interactive command as a child process with inherited stdin.
72
+ * Ink is temporarily suspended so the child can own the terminal.
73
+ */
74
+ async function executeInteractive(input, onLine) {
75
+ const tokens = parseTokens(input);
76
+ onLine(chalk_1.default.dim(" ◈ Launching interactive session..."));
77
+ onLine("");
78
+ return new Promise((resolve) => {
79
+ // Spawn arc402 as a child process with full terminal access.
80
+ // Use stdio: 'inherit' so the child owns stdin/stdout/stderr directly.
81
+ // This means its output goes straight to the terminal (not captured in viewport)
82
+ // but that's correct — the child needs raw terminal access for QR codes, prompts, etc.
83
+ const child = (0, child_process_1.spawn)(process.execPath, [process.argv[1], ...tokens], {
84
+ stdio: "inherit",
85
+ env: { ...process.env, ARC402_NO_TUI: "1" }, // prevent child from launching its own TUI
86
+ cwd: process.cwd(),
87
+ });
88
+ child.on("close", (code) => {
89
+ onLine("");
90
+ if (code === 0) {
91
+ onLine(` ${colors_1.c.success} ${chalk_1.default.dim("Command completed")}`);
74
92
  }
75
93
  else {
76
- onLine(` ${colors_1.c.failure} ${chalk_1.default.red(e.message ?? String(err))}`);
94
+ onLine(` ${colors_1.c.failure} ${chalk_1.default.red(`Command exited with code ${code}`)}`);
77
95
  }
96
+ resolve();
97
+ });
98
+ child.on("error", (err) => {
99
+ onLine(` ${colors_1.c.failure} ${chalk_1.default.red(`Failed to spawn: ${err.message}`)}`);
100
+ resolve();
101
+ });
102
+ });
103
+ }
104
+ /**
105
+ * Run a non-interactive command in-process with captured output.
106
+ */
107
+ async function executeInProcess(input, onLine) {
108
+ // Capture stdout/stderr
109
+ const originalStdoutWrite = process.stdout.write.bind(process.stdout);
110
+ const originalStderrWrite = process.stderr.write.bind(process.stderr);
111
+ let captureBuffer = "";
112
+ const flushBuffer = () => {
113
+ if (!captureBuffer)
114
+ return;
115
+ const lines = captureBuffer.split("\n");
116
+ captureBuffer = lines.pop() ?? "";
117
+ for (const line of lines) {
118
+ onLine(line);
78
119
  }
79
- finally {
80
- // Flush remaining buffer
81
- if (captureBuffer.trim()) {
82
- onLine(captureBuffer);
83
- captureBuffer = "";
84
- }
85
- // Restore original write functions
86
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
87
- process.stdout.write = originalStdoutWrite;
88
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
- process.stderr.write = originalStderrWrite;
90
- setIsRunning(false);
120
+ };
121
+ const capturedWrite = (chunk, encodingOrCb, cb) => {
122
+ const str = typeof chunk === "string"
123
+ ? chunk
124
+ : Buffer.from(chunk).toString("utf8");
125
+ captureBuffer += str;
126
+ flushBuffer();
127
+ const callback = typeof encodingOrCb === "function" ? encodingOrCb : cb;
128
+ if (callback)
129
+ callback();
130
+ return true;
131
+ };
132
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
133
+ process.stdout.write = capturedWrite;
134
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
135
+ process.stderr.write = capturedWrite;
136
+ try {
137
+ const tokens = parseTokens(input);
138
+ const prog = (0, program_1.createProgram)();
139
+ prog.exitOverride();
140
+ prog.configureOutput({
141
+ writeOut: (str) => process.stdout.write(str),
142
+ writeErr: (str) => process.stderr.write(str),
143
+ });
144
+ await prog.parseAsync(["node", "arc402", ...tokens]);
145
+ }
146
+ catch (err) {
147
+ const e = err;
148
+ if (e.code === "commander.helpDisplayed" ||
149
+ e.code === "commander.version" ||
150
+ e.code === "commander.executeSubCommandAsync") {
151
+ // already written or normal exit — no-op
91
152
  }
92
- }, []);
93
- return { execute, isRunning };
153
+ else if (e.code === "commander.unknownCommand") {
154
+ const tokens = parseTokens(input);
155
+ onLine(` ${colors_1.c.failure} ${chalk_1.default.red(`Unknown command: ${chalk_1.default.white(tokens[0])}`)} `);
156
+ onLine(chalk_1.default.dim(" Type 'help' for available commands"));
157
+ }
158
+ else if (e.code?.startsWith("commander.")) {
159
+ onLine(` ${colors_1.c.failure} ${chalk_1.default.red(e.message ?? String(err))}`);
160
+ }
161
+ else {
162
+ onLine(` ${colors_1.c.failure} ${chalk_1.default.red(e.message ?? String(err))}`);
163
+ }
164
+ }
165
+ finally {
166
+ // Flush remaining buffer
167
+ if (captureBuffer.trim()) {
168
+ onLine(captureBuffer);
169
+ captureBuffer = "";
170
+ }
171
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
172
+ process.stdout.write = originalStdoutWrite;
173
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
174
+ process.stderr.write = originalStderrWrite;
175
+ }
94
176
  }
95
177
  // Shell-style tokenizer
96
178
  function parseTokens(input) {
@@ -1 +1 @@
1
- {"version":3,"file":"useCommand.js","sourceRoot":"","sources":["../../src/tui/useCommand.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useCommand.js","sourceRoot":"","sources":["../../src/tui/useCommand.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arc402-cli",
3
- "version": "0.7.4",
3
+ "version": "0.7.5",
4
4
  "description": "ARC-402 CLI for discovery, negotiation payloads, hire/remediation/dispute workflows, and network reads",
5
5
  "bin": {
6
6
  "arc402": "./dist/index.js"
package/src/index.ts CHANGED
@@ -52,8 +52,8 @@ if (printMode) {
52
52
  console.error(e instanceof Error ? e.message : String(e));
53
53
  process.exit(1);
54
54
  });
55
- } else if (process.stdout.isTTY && !hasSubcommand && process.argv.length <= 2) {
56
- // TTY with no subcommand — launch Ink TUI
55
+ } else if (process.stdout.isTTY && !hasSubcommand && process.argv.length <= 2 && !process.env.ARC402_NO_TUI) {
56
+ // TTY with no subcommand — launch Ink TUI (unless spawned by TUI as a child process)
57
57
  checkUpgrade();
58
58
  void import("./tui/index").then(({ launchTUI }) => launchTUI()).catch((e: unknown) => {
59
59
  console.error("TUI failed to start:", e instanceof Error ? e.message : String(e));
package/src/tui/App.tsx CHANGED
@@ -1,8 +1,7 @@
1
- import React, { useState, useCallback, useEffect } from "react";
2
- import { Box, Text, useApp } from "ink";
1
+ import React, { useState, useCallback } from "react";
2
+ import { Box, Text, useApp, useStdout } from "ink";
3
3
  import { Header } from "./Header";
4
4
  import { Viewport } from "./Viewport";
5
- import { Footer } from "./Footer";
6
5
  import { InputLine } from "./InputLine";
7
6
  import { useCommand } from "./useCommand";
8
7
  import { useChat } from "./useChat";
@@ -10,9 +9,6 @@ import { useScroll } from "./useScroll";
10
9
  import { createProgram } from "../program";
11
10
  import chalk from "chalk";
12
11
 
13
- // eslint-disable-next-line @typescript-eslint/no-var-requires
14
- const pkg = require("../../package.json") as { version: string };
15
-
16
12
  const BUILTIN_CMDS = ["help", "exit", "quit", "clear", "status"];
17
13
 
18
14
  interface AppProps {
@@ -23,10 +19,23 @@ interface AppProps {
23
19
  }
24
20
 
25
21
  /**
26
- * Root TUI component — fixed header/footer with scrollable viewport.
22
+ * Root TUI component — box-drawn frame with fixed header/footer, scrollable viewport.
23
+ *
24
+ * ┌─────────────────────────────────────────────┐
25
+ * │ ASCII banner + status info │ ← FIXED header
26
+ * ├─────────────────────────────────────────────┤
27
+ * │ scrollable output │ ← VIEWPORT
28
+ * ├─────────────────────────────────────────────┤
29
+ * │ ◈ arc402 > _ │ ← FIXED footer
30
+ * └─────────────────────────────────────────────┘
27
31
  */
28
32
  export function App({ version, network, wallet, balance }: AppProps) {
29
33
  const { exit } = useApp();
34
+ const { stdout } = useStdout();
35
+ const cols = stdout?.columns ?? 60;
36
+ const W = Math.min(cols, 80); // inner width between │ chars
37
+ const inner = W - 2; // space between the two │ border chars
38
+
30
39
  const [outputBuffer, setOutputBuffer] = useState<string[]>([
31
40
  chalk.dim(" Type 'help' to see available commands"),
32
41
  "",
@@ -37,8 +46,8 @@ export function App({ version, network, wallet, balance }: AppProps) {
37
46
  const { send, isSending } = useChat();
38
47
 
39
48
  // Approximate viewport height for scroll management
40
- const HEADER_ROWS = 15;
41
- const FOOTER_ROWS = 1;
49
+ const HEADER_ROWS = 17;
50
+ const FOOTER_ROWS = 3;
42
51
  const rows = process.stdout.rows ?? 24;
43
52
  const viewportHeight = Math.max(1, rows - HEADER_ROWS - FOOTER_ROWS);
44
53
 
@@ -183,32 +192,49 @@ export function App({ version, network, wallet, balance }: AppProps) {
183
192
 
184
193
  const isDisabled = isProcessing || isRunning || isSending;
185
194
 
195
+ const topBorder = "┌" + "─".repeat(inner) + "┐";
196
+ const midBorder = "├" + "─".repeat(inner) + "┤";
197
+ const botBorder = "└" + "─".repeat(inner) + "┘";
198
+
186
199
  return (
187
200
  <Box flexDirection="column" height="100%">
201
+ {/* Top border */}
202
+ <Text dimColor>{topBorder}</Text>
203
+
188
204
  {/* HEADER — fixed, never scrolls */}
189
205
  <Header
190
206
  version={version}
191
207
  network={network}
192
208
  wallet={wallet}
193
209
  balance={balance}
210
+ innerWidth={inner}
194
211
  />
195
212
 
196
- {/* Separator */}
197
- <Box>
198
- <Text dimColor>{"─".repeat(60)}</Text>
199
- </Box>
213
+ {/* Mid separator */}
214
+ <Text dimColor>{midBorder}</Text>
200
215
 
201
216
  {/* VIEWPORT — fills remaining space */}
202
217
  <Viewport
203
218
  lines={outputBuffer}
204
219
  scrollOffset={scrollOffset}
205
220
  isAutoScroll={isAutoScroll}
221
+ innerWidth={inner}
206
222
  />
207
223
 
208
- {/* FOOTER fixed, input pinned */}
209
- <Footer>
210
- <InputLine onSubmit={handleCommand} isDisabled={isDisabled} />
211
- </Footer>
224
+ {/* Footer separator */}
225
+ <Text dimColor>{midBorder}</Text>
226
+
227
+ {/* FOOTER — input pinned */}
228
+ <Box>
229
+ <Text dimColor>│</Text>
230
+ <Box flexGrow={1}>
231
+ <InputLine onSubmit={handleCommand} isDisabled={isDisabled} />
232
+ </Box>
233
+ <Text dimColor>│</Text>
234
+ </Box>
235
+
236
+ {/* Bottom border */}
237
+ <Text dimColor>{botBorder}</Text>
212
238
  </Box>
213
239
  );
214
240
  }
@@ -7,23 +7,30 @@ interface HeaderProps {
7
7
  network?: string;
8
8
  wallet?: string;
9
9
  balance?: string;
10
+ innerWidth?: number;
10
11
  }
11
12
 
12
13
  /**
13
14
  * Fixed header showing the ASCII art banner + status info.
14
- * Never re-renders unless config changes.
15
+ * Each line is framed with │ … │ box-drawing borders.
15
16
  */
16
17
  export const Header = React.memo(function Header({
17
18
  network,
18
19
  wallet,
19
20
  balance,
21
+ innerWidth = 58,
20
22
  }: HeaderProps) {
21
23
  const bannerLines = getBannerLines({ network, wallet, balance });
22
24
 
23
25
  return (
24
26
  <Box flexDirection="column">
25
27
  {bannerLines.map((line, i) => (
26
- <Text key={i}>{line}</Text>
28
+ <Box key={i}>
29
+ <Text dimColor>│</Text>
30
+ <Text>{" " + line}</Text>
31
+ <Box flexGrow={1} />
32
+ <Text dimColor>│</Text>
33
+ </Box>
27
34
  ))}
28
35
  </Box>
29
36
  );
@@ -5,39 +5,30 @@ interface ViewportProps {
5
5
  lines: string[];
6
6
  scrollOffset: number;
7
7
  isAutoScroll: boolean;
8
+ innerWidth?: number;
8
9
  }
9
10
 
10
11
  /**
11
- * Scrollable output area that fills remaining terminal space.
12
- * Renders a window slice of the buffer, not terminal scroll.
13
- * scrollOffset=0 means pinned to bottom (auto-scroll).
14
- * Positive scrollOffset means scrolled up by that many lines.
12
+ * Scrollable output area framed with │ box-drawing borders.
13
+ * Fills remaining terminal space between header and footer separators.
15
14
  */
16
- export function Viewport({ lines, scrollOffset, isAutoScroll }: ViewportProps) {
15
+ export function Viewport({ lines, scrollOffset, isAutoScroll, innerWidth = 58 }: ViewportProps) {
17
16
  const { stdout } = useStdout();
18
17
  const termRows = stdout?.rows ?? 24;
19
18
 
20
- // We'll compute the viewport height: total rows minus fixed areas
21
- // Header is approximately bannerLines + separator (~14-16 rows)
22
- // Footer is 1 row
23
- // We'll use a reasonable estimate here; the parent App can pass exact height
24
- const HEADER_ROWS = 15; // approximate
25
- const FOOTER_ROWS = 1;
26
- const viewportHeight = Math.max(1, termRows - HEADER_ROWS - FOOTER_ROWS);
19
+ // Header (~14 rows) + top/mid/mid/bot borders (4) + footer input (1) = ~19 fixed rows
20
+ const FIXED_ROWS = 19;
21
+ const viewportHeight = Math.max(1, termRows - FIXED_ROWS);
27
22
 
28
23
  // Compute the window slice
29
- // scrollOffset=0 → show last viewportHeight lines
30
- // scrollOffset=N → show lines ending viewportHeight+N from end
31
24
  const totalLines = lines.length;
32
25
  let endIdx: number;
33
26
  let startIdx: number;
34
27
 
35
28
  if (scrollOffset === 0) {
36
- // Auto-scroll: pinned to bottom
37
29
  endIdx = totalLines;
38
30
  startIdx = Math.max(0, endIdx - viewportHeight);
39
31
  } else {
40
- // Scrolled up: scrollOffset lines from bottom
41
32
  endIdx = Math.max(0, totalLines - scrollOffset);
42
33
  startIdx = Math.max(0, endIdx - viewportHeight);
43
34
  }
@@ -55,14 +46,19 @@ export function Viewport({ lines, scrollOffset, isAutoScroll }: ViewportProps) {
55
46
 
56
47
  return (
57
48
  <Box flexDirection="column" flexGrow={1}>
58
- <Box flexDirection="column" flexGrow={1}>
59
- {paddedLines.map((line, i) => (
60
- <Text key={i}>{line}</Text>
61
- ))}
62
- </Box>
49
+ {paddedLines.map((line, i) => (
50
+ <Box key={i}>
51
+ <Text dimColor>│</Text>
52
+ <Text>{" " + line}</Text>
53
+ <Box flexGrow={1} />
54
+ <Text dimColor>│</Text>
55
+ </Box>
56
+ ))}
63
57
  {canScrollDown && !isAutoScroll && (
64
58
  <Box justifyContent="flex-end">
65
- <Text dimColor>↓ more</Text>
59
+ <Text dimColor>│ more</Text>
60
+ <Box flexGrow={1} />
61
+ <Text dimColor>│</Text>
66
62
  </Box>
67
63
  )}
68
64
  </Box>
@@ -1,8 +1,44 @@
1
1
  import { useState, useCallback } from "react";
2
2
  import { createProgram } from "../program";
3
+ import { spawn } from "child_process";
3
4
  import chalk from "chalk";
4
5
  import { c } from "../ui/colors";
5
6
 
7
+ /**
8
+ * Commands that use interactive prompts or WalletConnect QR flows.
9
+ * These MUST run in a child process so they can own stdin/stdout directly,
10
+ * because Ink holds stdin in raw mode for its own input handling.
11
+ */
12
+ const INTERACTIVE_COMMANDS = new Set([
13
+ "wallet deploy",
14
+ "wallet set-guardian",
15
+ "wallet unfreeze",
16
+ "wallet authorize-machine-key",
17
+ "wallet revoke-machine-key",
18
+ "wallet set-passkey",
19
+ "wallet set-interceptor",
20
+ "wallet set-velocity-limit",
21
+ "wallet upgrade-registry",
22
+ "wallet execute-registry-upgrade",
23
+ "wallet cancel-registry-upgrade",
24
+ "wallet register-policy",
25
+ "wallet whitelist-contract",
26
+ "wallet governance setup",
27
+ "wallet policy set-limit",
28
+ "wallet policy set-daily-limit",
29
+ "wallet policy set",
30
+ "wallet import",
31
+ "config init",
32
+ ]);
33
+
34
+ function isInteractiveCommand(input: string): boolean {
35
+ const normalized = input.trim();
36
+ for (const cmd of INTERACTIVE_COMMANDS) {
37
+ if (normalized === cmd || normalized.startsWith(cmd + " ")) return true;
38
+ }
39
+ return false;
40
+ }
41
+
6
42
  interface UseCommandResult {
7
43
  execute: (input: string, onLine: (line: string) => void) => Promise<void>;
8
44
  isRunning: boolean;
@@ -10,8 +46,13 @@ interface UseCommandResult {
10
46
 
11
47
  /**
12
48
  * Dispatches parsed commands to the commander program.
13
- * Captures stdout/stderr by monkey-patching process.stdout.write
14
- * and routes all output to the viewport buffer via onLine callback.
49
+ *
50
+ * NON-INTERACTIVE commands: captures stdout/stderr by monkey-patching
51
+ * process.stdout.write and routes output to the viewport.
52
+ *
53
+ * INTERACTIVE commands (WalletConnect, prompts): spawns a child process
54
+ * running `arc402 <command>` with inherited stdin so that QR codes render
55
+ * and prompts accept input. Output is captured line-by-line into the viewport.
15
56
  */
16
57
  export function useCommand(): UseCommandResult {
17
58
  const [isRunning, setIsRunning] = useState(false);
@@ -20,89 +61,13 @@ export function useCommand(): UseCommandResult {
20
61
  async (input: string, onLine: (line: string) => void): Promise<void> => {
21
62
  setIsRunning(true);
22
63
 
23
- // Capture stdout/stderr
24
- const originalStdoutWrite = process.stdout.write.bind(process.stdout);
25
- const originalStderrWrite = process.stderr.write.bind(process.stderr);
26
-
27
- let captureBuffer = "";
28
-
29
- const flushBuffer = (): void => {
30
- if (!captureBuffer) return;
31
- const lines = captureBuffer.split("\n");
32
- captureBuffer = lines.pop() ?? "";
33
- for (const line of lines) {
34
- onLine(line);
35
- }
36
- };
37
-
38
- const capturedWrite = (
39
- chunk: string | Uint8Array,
40
- encodingOrCb?: BufferEncoding | ((err?: Error | null) => void),
41
- cb?: (err?: Error | null) => void
42
- ): boolean => {
43
- const str =
44
- typeof chunk === "string"
45
- ? chunk
46
- : Buffer.from(chunk).toString("utf8");
47
- captureBuffer += str;
48
- flushBuffer();
49
- // call callback if provided
50
- const callback =
51
- typeof encodingOrCb === "function" ? encodingOrCb : cb;
52
- if (callback) callback();
53
- return true;
54
- };
55
-
56
- // Monkey-patch (cast through unknown to bypass strict overload checking)
57
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
- (process.stdout as any).write = capturedWrite;
59
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
- (process.stderr as any).write = capturedWrite;
61
-
62
- try {
63
- const tokens = parseTokens(input);
64
- const prog = createProgram();
65
- prog.exitOverride();
66
- prog.configureOutput({
67
- writeOut: (str) => process.stdout.write(str),
68
- writeErr: (str) => process.stderr.write(str),
69
- });
70
-
71
- await prog.parseAsync(["node", "arc402", ...tokens]);
72
- } catch (err) {
73
- const e = err as { code?: string; message?: string };
74
- if (
75
- e.code === "commander.helpDisplayed" ||
76
- e.code === "commander.version" ||
77
- e.code === "commander.executeSubCommandAsync"
78
- ) {
79
- // already written or normal exit — no-op
80
- } else if (e.code === "commander.unknownCommand") {
81
- const tokens = parseTokens(input);
82
- onLine(
83
- ` ${c.failure} ${chalk.red(`Unknown command: ${chalk.white(tokens[0])}`)} `
84
- );
85
- onLine(chalk.dim(" Type 'help' for available commands"));
86
- } else if (e.code?.startsWith("commander.")) {
87
- onLine(` ${c.failure} ${chalk.red(e.message ?? String(err))}`);
88
- } else {
89
- onLine(` ${c.failure} ${chalk.red(e.message ?? String(err))}`);
90
- }
91
- } finally {
92
- // Flush remaining buffer
93
- if (captureBuffer.trim()) {
94
- onLine(captureBuffer);
95
- captureBuffer = "";
96
- }
97
-
98
- // Restore original write functions
99
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
100
- (process.stdout as any).write = originalStdoutWrite;
101
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
102
- (process.stderr as any).write = originalStderrWrite;
103
-
104
- setIsRunning(false);
64
+ if (isInteractiveCommand(input)) {
65
+ await executeInteractive(input, onLine);
66
+ } else {
67
+ await executeInProcess(input, onLine);
105
68
  }
69
+
70
+ setIsRunning(false);
106
71
  },
107
72
  []
108
73
  );
@@ -110,6 +75,138 @@ export function useCommand(): UseCommandResult {
110
75
  return { execute, isRunning };
111
76
  }
112
77
 
78
+ /**
79
+ * Run an interactive command as a child process with inherited stdin.
80
+ * Ink is temporarily suspended so the child can own the terminal.
81
+ */
82
+ async function executeInteractive(
83
+ input: string,
84
+ onLine: (line: string) => void
85
+ ): Promise<void> {
86
+ const tokens = parseTokens(input);
87
+
88
+ onLine(chalk.dim(" ◈ Launching interactive session..."));
89
+ onLine("");
90
+
91
+ return new Promise<void>((resolve) => {
92
+ // Spawn arc402 as a child process with full terminal access.
93
+ // Use stdio: 'inherit' so the child owns stdin/stdout/stderr directly.
94
+ // This means its output goes straight to the terminal (not captured in viewport)
95
+ // but that's correct — the child needs raw terminal access for QR codes, prompts, etc.
96
+ const child = spawn(
97
+ process.execPath,
98
+ [process.argv[1], ...tokens],
99
+ {
100
+ stdio: "inherit",
101
+ env: { ...process.env, ARC402_NO_TUI: "1" }, // prevent child from launching its own TUI
102
+ cwd: process.cwd(),
103
+ }
104
+ );
105
+
106
+ child.on("close", (code) => {
107
+ onLine("");
108
+ if (code === 0) {
109
+ onLine(` ${c.success} ${chalk.dim("Command completed")}`);
110
+ } else {
111
+ onLine(` ${c.failure} ${chalk.red(`Command exited with code ${code}`)}`);
112
+ }
113
+ resolve();
114
+ });
115
+
116
+ child.on("error", (err) => {
117
+ onLine(` ${c.failure} ${chalk.red(`Failed to spawn: ${err.message}`)}`);
118
+ resolve();
119
+ });
120
+ });
121
+ }
122
+
123
+ /**
124
+ * Run a non-interactive command in-process with captured output.
125
+ */
126
+ async function executeInProcess(
127
+ input: string,
128
+ onLine: (line: string) => void
129
+ ): Promise<void> {
130
+ // Capture stdout/stderr
131
+ const originalStdoutWrite = process.stdout.write.bind(process.stdout);
132
+ const originalStderrWrite = process.stderr.write.bind(process.stderr);
133
+
134
+ let captureBuffer = "";
135
+
136
+ const flushBuffer = (): void => {
137
+ if (!captureBuffer) return;
138
+ const lines = captureBuffer.split("\n");
139
+ captureBuffer = lines.pop() ?? "";
140
+ for (const line of lines) {
141
+ onLine(line);
142
+ }
143
+ };
144
+
145
+ const capturedWrite = (
146
+ chunk: string | Uint8Array,
147
+ encodingOrCb?: BufferEncoding | ((err?: Error | null) => void),
148
+ cb?: (err?: Error | null) => void
149
+ ): boolean => {
150
+ const str =
151
+ typeof chunk === "string"
152
+ ? chunk
153
+ : Buffer.from(chunk).toString("utf8");
154
+ captureBuffer += str;
155
+ flushBuffer();
156
+ const callback =
157
+ typeof encodingOrCb === "function" ? encodingOrCb : cb;
158
+ if (callback) callback();
159
+ return true;
160
+ };
161
+
162
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
163
+ (process.stdout as any).write = capturedWrite;
164
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
165
+ (process.stderr as any).write = capturedWrite;
166
+
167
+ try {
168
+ const tokens = parseTokens(input);
169
+ const prog = createProgram();
170
+ prog.exitOverride();
171
+ prog.configureOutput({
172
+ writeOut: (str) => process.stdout.write(str),
173
+ writeErr: (str) => process.stderr.write(str),
174
+ });
175
+
176
+ await prog.parseAsync(["node", "arc402", ...tokens]);
177
+ } catch (err) {
178
+ const e = err as { code?: string; message?: string };
179
+ if (
180
+ e.code === "commander.helpDisplayed" ||
181
+ e.code === "commander.version" ||
182
+ e.code === "commander.executeSubCommandAsync"
183
+ ) {
184
+ // already written or normal exit — no-op
185
+ } else if (e.code === "commander.unknownCommand") {
186
+ const tokens = parseTokens(input);
187
+ onLine(
188
+ ` ${c.failure} ${chalk.red(`Unknown command: ${chalk.white(tokens[0])}`)} `
189
+ );
190
+ onLine(chalk.dim(" Type 'help' for available commands"));
191
+ } else if (e.code?.startsWith("commander.")) {
192
+ onLine(` ${c.failure} ${chalk.red(e.message ?? String(err))}`);
193
+ } else {
194
+ onLine(` ${c.failure} ${chalk.red(e.message ?? String(err))}`);
195
+ }
196
+ } finally {
197
+ // Flush remaining buffer
198
+ if (captureBuffer.trim()) {
199
+ onLine(captureBuffer);
200
+ captureBuffer = "";
201
+ }
202
+
203
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
204
+ (process.stdout as any).write = originalStdoutWrite;
205
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
206
+ (process.stderr as any).write = originalStderrWrite;
207
+ }
208
+ }
209
+
113
210
  // Shell-style tokenizer
114
211
  function parseTokens(input: string): string[] {
115
212
  const tokens: string[] = [];