arc402-cli 0.7.2 → 0.7.4
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/TUI-SPEC.md +214 -0
- package/dist/index.js +55 -1
- package/dist/index.js.map +1 -1
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +46 -567
- package/dist/repl.js.map +1 -1
- package/dist/tui/App.d.ts +12 -0
- package/dist/tui/App.d.ts.map +1 -0
- package/dist/tui/App.js +154 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/Footer.d.ts +11 -0
- package/dist/tui/Footer.d.ts.map +1 -0
- package/dist/tui/Footer.js +13 -0
- package/dist/tui/Footer.js.map +1 -0
- package/dist/tui/Header.d.ts +14 -0
- package/dist/tui/Header.d.ts.map +1 -0
- package/dist/tui/Header.js +19 -0
- package/dist/tui/Header.js.map +1 -0
- package/dist/tui/InputLine.d.ts +11 -0
- package/dist/tui/InputLine.d.ts.map +1 -0
- package/dist/tui/InputLine.js +145 -0
- package/dist/tui/InputLine.js.map +1 -0
- package/dist/tui/Viewport.d.ts +14 -0
- package/dist/tui/Viewport.d.ts.map +1 -0
- package/dist/tui/Viewport.js +48 -0
- package/dist/tui/Viewport.js.map +1 -0
- package/dist/tui/index.d.ts +2 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +55 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/useChat.d.ts +11 -0
- package/dist/tui/useChat.d.ts.map +1 -0
- package/dist/tui/useChat.js +91 -0
- package/dist/tui/useChat.js.map +1 -0
- package/dist/tui/useCommand.d.ts +12 -0
- package/dist/tui/useCommand.d.ts.map +1 -0
- package/dist/tui/useCommand.js +137 -0
- package/dist/tui/useCommand.js.map +1 -0
- package/dist/tui/useScroll.d.ts +17 -0
- package/dist/tui/useScroll.d.ts.map +1 -0
- package/dist/tui/useScroll.js +46 -0
- package/dist/tui/useScroll.js.map +1 -0
- package/package.json +5 -1
- package/src/index.ts +21 -1
- package/src/repl.ts +50 -676
- package/src/tui/App.tsx +214 -0
- package/src/tui/Footer.tsx +18 -0
- package/src/tui/Header.tsx +30 -0
- package/src/tui/InputLine.tsx +164 -0
- package/src/tui/Viewport.tsx +70 -0
- package/src/tui/index.tsx +72 -0
- package/src/tui/useChat.ts +103 -0
- package/src/tui/useCommand.ts +148 -0
- package/src/tui/useScroll.ts +65 -0
- package/tsconfig.json +6 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.launchTUI = launchTUI;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const ink_1 = require("ink");
|
|
9
|
+
const App_1 = require("./App");
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const os_1 = __importDefault(require("os"));
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
14
|
+
const pkg = require("../../package.json");
|
|
15
|
+
const CONFIG_PATH = path_1.default.join(os_1.default.homedir(), ".arc402", "config.json");
|
|
16
|
+
async function loadConfig() {
|
|
17
|
+
if (!fs_1.default.existsSync(CONFIG_PATH))
|
|
18
|
+
return {};
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(fs_1.default.readFileSync(CONFIG_PATH, "utf-8"));
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function getBalance(rpcUrl, address) {
|
|
27
|
+
try {
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
29
|
+
const ethersLib = require("ethers");
|
|
30
|
+
const provider = new ethersLib.ethers.JsonRpcProvider(rpcUrl);
|
|
31
|
+
const bal = await Promise.race([
|
|
32
|
+
provider.getBalance(address),
|
|
33
|
+
new Promise((_, r) => setTimeout(() => r(new Error("timeout")), 2000)),
|
|
34
|
+
]);
|
|
35
|
+
return `${parseFloat(ethersLib.ethers.formatEther(bal)).toFixed(4)} ETH`;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function launchTUI() {
|
|
42
|
+
const config = await loadConfig();
|
|
43
|
+
let walletDisplay;
|
|
44
|
+
if (config.walletContractAddress) {
|
|
45
|
+
const w = config.walletContractAddress;
|
|
46
|
+
walletDisplay = `${w.slice(0, 6)}...${w.slice(-4)}`;
|
|
47
|
+
}
|
|
48
|
+
let balance;
|
|
49
|
+
if (config.rpcUrl && config.walletContractAddress) {
|
|
50
|
+
balance = await getBalance(config.rpcUrl, config.walletContractAddress);
|
|
51
|
+
}
|
|
52
|
+
const { waitUntilExit } = (0, ink_1.render)((0, jsx_runtime_1.jsx)(App_1.App, { version: pkg.version, network: config.network, wallet: walletDisplay, balance: balance }));
|
|
53
|
+
await waitUntilExit();
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tui/index.tsx"],"names":[],"mappings":";;;;;AA+CA,8BAwBC;;AAtED,6BAA6B;AAC7B,+BAA4B;AAC5B,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AAEpB,8DAA8D;AAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAwB,CAAC;AAEjE,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;AAQtE,KAAK,UAAU,UAAU;IACvB,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAW,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,MAAc,EACd,OAAe;IAEf,IAAI,CAAC;QACH,8DAA8D;QAC9D,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAA4B,CAAC;QAC/D,MAAM,QAAQ,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC9D,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAC7B,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;YAC5B,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC1B,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAChD;SACF,CAAC,CAAC;QACH,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,SAAS;IAC7B,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAElC,IAAI,aAAiC,CAAC;IACtC,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,MAAM,CAAC,qBAAqB,CAAC;QACvC,aAAa,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACtD,CAAC;IAED,IAAI,OAA2B,CAAC;IAChC,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;QAClD,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,EAAE,aAAa,EAAE,GAAG,IAAA,YAAM,EAC9B,uBAAC,SAAG,IACF,OAAO,EAAE,GAAG,CAAC,OAAO,EACpB,OAAO,EAAE,MAAM,CAAC,OAAO,EACvB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,OAAO,GAChB,CACH,CAAC;IAEF,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface UseChatResult {
|
|
2
|
+
send: (message: string, onLine: (line: string) => void) => Promise<void>;
|
|
3
|
+
isSending: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Sends messages to the OpenClaw gateway and streams responses
|
|
7
|
+
* line-by-line into the viewport buffer via onLine callback.
|
|
8
|
+
*/
|
|
9
|
+
export declare function useChat(): UseChatResult;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=useChat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/tui/useChat.ts"],"names":[],"mappings":"AAIA,UAAU,aAAa;IACrB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,OAAO,IAAI,aAAa,CAyFvC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useChat = useChat;
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const colors_1 = require("../ui/colors");
|
|
10
|
+
/**
|
|
11
|
+
* Sends messages to the OpenClaw gateway and streams responses
|
|
12
|
+
* line-by-line into the viewport buffer via onLine callback.
|
|
13
|
+
*/
|
|
14
|
+
function useChat() {
|
|
15
|
+
const [isSending, setIsSending] = (0, react_1.useState)(false);
|
|
16
|
+
const send = (0, react_1.useCallback)(async (message, onLine) => {
|
|
17
|
+
setIsSending(true);
|
|
18
|
+
const trimmed = message.trim().slice(0, 10000);
|
|
19
|
+
// Show thinking placeholder
|
|
20
|
+
onLine(chalk_1.default.dim(" ◈ ") + chalk_1.default.dim("thinking..."));
|
|
21
|
+
let res;
|
|
22
|
+
try {
|
|
23
|
+
res = await fetch("http://localhost:19000/api/agent", {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: { "Content-Type": "application/json" },
|
|
26
|
+
body: JSON.stringify({ message: trimmed, session: "arc402-tui" }),
|
|
27
|
+
signal: AbortSignal.timeout(30000),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
32
|
+
const isDown = msg.includes("ECONNREFUSED") ||
|
|
33
|
+
msg.includes("fetch failed") ||
|
|
34
|
+
msg.includes("ENOTFOUND") ||
|
|
35
|
+
msg.includes("UND_ERR_SOCKET");
|
|
36
|
+
if (isDown) {
|
|
37
|
+
onLine(" " +
|
|
38
|
+
chalk_1.default.yellow("⚠") +
|
|
39
|
+
" " +
|
|
40
|
+
chalk_1.default.dim("OpenClaw gateway not running. Start with: ") +
|
|
41
|
+
chalk_1.default.white("openclaw gateway start"));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
onLine(` ${colors_1.c.failure} ${chalk_1.default.red(msg)}`);
|
|
45
|
+
}
|
|
46
|
+
setIsSending(false);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (!res.body) {
|
|
50
|
+
onLine(chalk_1.default.dim(" ◈ ") + chalk_1.default.white("(empty response)"));
|
|
51
|
+
setIsSending(false);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const flushLine = (line) => {
|
|
55
|
+
// Unwrap SSE data lines
|
|
56
|
+
if (line.startsWith("data: ")) {
|
|
57
|
+
line = line.slice(6);
|
|
58
|
+
if (line === "[DONE]")
|
|
59
|
+
return;
|
|
60
|
+
try {
|
|
61
|
+
const j = JSON.parse(line);
|
|
62
|
+
line = j.text ?? j.content ?? j.delta?.text ?? line;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
/* use raw */
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (line.trim()) {
|
|
69
|
+
onLine(chalk_1.default.dim(" ◈ ") + chalk_1.default.white(line));
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
const reader = res.body.getReader();
|
|
73
|
+
const decoder = new TextDecoder();
|
|
74
|
+
let buffer = "";
|
|
75
|
+
while (true) {
|
|
76
|
+
const { done, value } = await reader.read();
|
|
77
|
+
if (done)
|
|
78
|
+
break;
|
|
79
|
+
buffer += decoder.decode(value, { stream: true });
|
|
80
|
+
const lines = buffer.split("\n");
|
|
81
|
+
buffer = lines.pop() ?? "";
|
|
82
|
+
for (const line of lines)
|
|
83
|
+
flushLine(line);
|
|
84
|
+
}
|
|
85
|
+
if (buffer.trim())
|
|
86
|
+
flushLine(buffer);
|
|
87
|
+
setIsSending(false);
|
|
88
|
+
}, []);
|
|
89
|
+
return { send, isSending };
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=useChat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChat.js","sourceRoot":"","sources":["../../src/tui/useChat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface UseCommandResult {
|
|
2
|
+
execute: (input: string, onLine: (line: string) => void) => Promise<void>;
|
|
3
|
+
isRunning: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
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.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useCommand(): UseCommandResult;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=useCommand.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useCommand = useCommand;
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const program_1 = require("../program");
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const colors_1 = require("../ui/colors");
|
|
11
|
+
/**
|
|
12
|
+
* 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.
|
|
15
|
+
*/
|
|
16
|
+
function useCommand() {
|
|
17
|
+
const [isRunning, setIsRunning] = (0, react_1.useState)(false);
|
|
18
|
+
const execute = (0, react_1.useCallback)(async (input, onLine) => {
|
|
19
|
+
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]);
|
|
59
|
+
}
|
|
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))}`);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
onLine(` ${colors_1.c.failure} ${chalk_1.default.red(e.message ?? String(err))}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
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);
|
|
91
|
+
}
|
|
92
|
+
}, []);
|
|
93
|
+
return { execute, isRunning };
|
|
94
|
+
}
|
|
95
|
+
// Shell-style tokenizer
|
|
96
|
+
function parseTokens(input) {
|
|
97
|
+
const tokens = [];
|
|
98
|
+
let current = "";
|
|
99
|
+
let inQuote = false;
|
|
100
|
+
let quoteChar = "";
|
|
101
|
+
let escape = false;
|
|
102
|
+
for (const ch of input) {
|
|
103
|
+
if (escape) {
|
|
104
|
+
current += ch;
|
|
105
|
+
escape = false;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (inQuote) {
|
|
109
|
+
if (quoteChar === '"' && ch === "\\") {
|
|
110
|
+
escape = true;
|
|
111
|
+
}
|
|
112
|
+
else if (ch === quoteChar) {
|
|
113
|
+
inQuote = false;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
current += ch;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (ch === '"' || ch === "'") {
|
|
120
|
+
inQuote = true;
|
|
121
|
+
quoteChar = ch;
|
|
122
|
+
}
|
|
123
|
+
else if (ch === " ") {
|
|
124
|
+
if (current) {
|
|
125
|
+
tokens.push(current);
|
|
126
|
+
current = "";
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
current += ch;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (current)
|
|
134
|
+
tokens.push(current);
|
|
135
|
+
return tokens;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=useCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCommand.js","sourceRoot":"","sources":["../../src/tui/useCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface UseScrollResult {
|
|
2
|
+
scrollOffset: number;
|
|
3
|
+
setScrollOffset: (offset: number) => void;
|
|
4
|
+
viewportHeight: number;
|
|
5
|
+
isAutoScroll: boolean;
|
|
6
|
+
scrollUp: (lines?: number) => void;
|
|
7
|
+
scrollDown: (lines?: number) => void;
|
|
8
|
+
snapToBottom: () => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Manages scroll state for the Viewport.
|
|
12
|
+
* scrollOffset=0 means auto-scroll (pinned to bottom).
|
|
13
|
+
* Positive scrollOffset means scrolled up by that many lines.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useScroll(viewportHeight: number): UseScrollResult;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=useScroll.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useScroll.d.ts","sourceRoot":"","sources":["../../src/tui/useScroll.ts"],"names":[],"mappings":"AAGA,UAAU,eAAe;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,eAAe,CA8CjE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useScroll = useScroll;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const ink_1 = require("ink");
|
|
6
|
+
/**
|
|
7
|
+
* Manages scroll state for the Viewport.
|
|
8
|
+
* scrollOffset=0 means auto-scroll (pinned to bottom).
|
|
9
|
+
* Positive scrollOffset means scrolled up by that many lines.
|
|
10
|
+
*/
|
|
11
|
+
function useScroll(viewportHeight) {
|
|
12
|
+
const [scrollOffset, setScrollOffsetState] = (0, react_1.useState)(0);
|
|
13
|
+
const isAutoScroll = scrollOffset === 0;
|
|
14
|
+
const setScrollOffset = (0, react_1.useCallback)((offset) => {
|
|
15
|
+
setScrollOffsetState(Math.max(0, offset));
|
|
16
|
+
}, []);
|
|
17
|
+
const scrollUp = (0, react_1.useCallback)((lines) => {
|
|
18
|
+
const step = lines ?? viewportHeight;
|
|
19
|
+
setScrollOffsetState((prev) => prev + step);
|
|
20
|
+
}, [viewportHeight]);
|
|
21
|
+
const scrollDown = (0, react_1.useCallback)((lines) => {
|
|
22
|
+
const step = lines ?? viewportHeight;
|
|
23
|
+
setScrollOffsetState((prev) => Math.max(0, prev - step));
|
|
24
|
+
}, [viewportHeight]);
|
|
25
|
+
const snapToBottom = (0, react_1.useCallback)(() => {
|
|
26
|
+
setScrollOffsetState(0);
|
|
27
|
+
}, []);
|
|
28
|
+
(0, ink_1.useInput)((_input, key) => {
|
|
29
|
+
if (key.pageUp) {
|
|
30
|
+
scrollUp(viewportHeight);
|
|
31
|
+
}
|
|
32
|
+
else if (key.pageDown) {
|
|
33
|
+
scrollDown(viewportHeight);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
scrollOffset,
|
|
38
|
+
setScrollOffset,
|
|
39
|
+
viewportHeight,
|
|
40
|
+
isAutoScroll,
|
|
41
|
+
scrollUp,
|
|
42
|
+
scrollDown,
|
|
43
|
+
snapToBottom,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=useScroll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useScroll.js","sourceRoot":"","sources":["../../src/tui/useScroll.ts"],"names":[],"mappings":";;AAkBA,8BA8CC;AAhED,iCAA8C;AAC9C,6BAA+B;AAY/B;;;;GAIG;AACH,SAAgB,SAAS,CAAC,cAAsB;IAC9C,MAAM,CAAC,YAAY,EAAE,oBAAoB,CAAC,GAAG,IAAA,gBAAQ,EAAC,CAAC,CAAC,CAAC;IAEzD,MAAM,YAAY,GAAG,YAAY,KAAK,CAAC,CAAC;IAExC,MAAM,eAAe,GAAG,IAAA,mBAAW,EAAC,CAAC,MAAc,EAAE,EAAE;QACrD,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,QAAQ,GAAG,IAAA,mBAAW,EAC1B,CAAC,KAAc,EAAE,EAAE;QACjB,MAAM,IAAI,GAAG,KAAK,IAAI,cAAc,CAAC;QACrC,oBAAoB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC9C,CAAC,EACD,CAAC,cAAc,CAAC,CACjB,CAAC;IAEF,MAAM,UAAU,GAAG,IAAA,mBAAW,EAC5B,CAAC,KAAc,EAAE,EAAE;QACjB,MAAM,IAAI,GAAG,KAAK,IAAI,cAAc,CAAC;QACrC,oBAAoB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;IAC3D,CAAC,EACD,CAAC,cAAc,CAAC,CACjB,CAAC;IAEF,MAAM,YAAY,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QACpC,oBAAoB,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAA,cAAQ,EAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACvB,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,QAAQ,CAAC,cAAc,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACxB,UAAU,CAAC,cAAc,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,YAAY;QACZ,eAAe;QACf,cAAc;QACd,YAAY;QACZ,QAAQ;QACR,UAAU;QACV,YAAY;KACb,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arc402-cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
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"
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"@arc402/sdk": "^0.3.1",
|
|
15
15
|
"@coinbase/wallet-sdk": "^4.3.7",
|
|
16
16
|
"@types/better-sqlite3": "^7.6.13",
|
|
17
|
+
"@types/react": "^18.3.28",
|
|
17
18
|
"@walletconnect/keyvaluestorage": "^1.1.1",
|
|
18
19
|
"@walletconnect/sign-client": "^2.17.4",
|
|
19
20
|
"better-sqlite3": "^12.8.0",
|
|
@@ -21,10 +22,13 @@
|
|
|
21
22
|
"cli-table3": "^0.6.3",
|
|
22
23
|
"commander": "^12.1.0",
|
|
23
24
|
"ethers": "^6.13.4",
|
|
25
|
+
"ink": "^3.2.0",
|
|
26
|
+
"ink-text-input": "^4.0.3",
|
|
24
27
|
"jose": "^6.2.1",
|
|
25
28
|
"ora": "^8.1.1",
|
|
26
29
|
"prompts": "^2.4.2",
|
|
27
30
|
"qrcode-terminal": "^0.12.0",
|
|
31
|
+
"react": "^18.3.1",
|
|
28
32
|
"smol-toml": "^1.6.0",
|
|
29
33
|
"tweetnacl": "^1.0.3",
|
|
30
34
|
"yaml": "^2.8.2"
|
package/src/index.ts
CHANGED
|
@@ -27,6 +27,18 @@ function checkUpgrade(): void {
|
|
|
27
27
|
|
|
28
28
|
const printMode = process.argv.includes("--print");
|
|
29
29
|
|
|
30
|
+
// Detect if a subcommand was provided (any arg after the binary that doesn't start with -)
|
|
31
|
+
const knownSubcommands = (() => {
|
|
32
|
+
try {
|
|
33
|
+
const prog = createProgram();
|
|
34
|
+
return new Set(prog.commands.map((cmd) => cmd.name()));
|
|
35
|
+
} catch {
|
|
36
|
+
return new Set<string>();
|
|
37
|
+
}
|
|
38
|
+
})();
|
|
39
|
+
const argv = process.argv.slice(2).filter((a) => a !== "--print");
|
|
40
|
+
const hasSubcommand = argv.some((a) => !a.startsWith("-") && knownSubcommands.has(a));
|
|
41
|
+
|
|
30
42
|
if (printMode) {
|
|
31
43
|
// --print mode: skip REPL entirely, suppress ANSI/spinners, run command, exit.
|
|
32
44
|
// Used by OpenClaw agents running arc402 commands via ACP.
|
|
@@ -40,8 +52,16 @@ if (printMode) {
|
|
|
40
52
|
console.error(e instanceof Error ? e.message : String(e));
|
|
41
53
|
process.exit(1);
|
|
42
54
|
});
|
|
55
|
+
} else if (process.stdout.isTTY && !hasSubcommand && process.argv.length <= 2) {
|
|
56
|
+
// TTY with no subcommand — launch Ink TUI
|
|
57
|
+
checkUpgrade();
|
|
58
|
+
void import("./tui/index").then(({ launchTUI }) => launchTUI()).catch((e: unknown) => {
|
|
59
|
+
console.error("TUI failed to start:", e instanceof Error ? e.message : String(e));
|
|
60
|
+
// Fallback to REPL
|
|
61
|
+
void startREPL();
|
|
62
|
+
});
|
|
43
63
|
} else if (process.argv.length <= 2) {
|
|
44
|
-
// No subcommand — enter
|
|
64
|
+
// No subcommand, not TTY — enter basic REPL fallback
|
|
45
65
|
checkUpgrade();
|
|
46
66
|
void startREPL();
|
|
47
67
|
} else {
|