arc402-cli 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +11 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +205 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/wallet.d.ts.map +1 -1
- package/dist/commands/wallet.js +56 -6
- package/dist/commands/wallet.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -2
- package/dist/config.js.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +294 -208
- package/dist/daemon/index.js.map +1 -1
- package/dist/endpoint-notify.d.ts +7 -0
- package/dist/endpoint-notify.d.ts.map +1 -1
- package/dist/endpoint-notify.js +104 -0
- package/dist/endpoint-notify.js.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +2 -0
- package/dist/program.js.map +1 -1
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +45 -34
- package/dist/repl.js.map +1 -1
- package/dist/ui/format.d.ts.map +1 -1
- package/dist/ui/format.js +2 -0
- package/dist/ui/format.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/config.ts +12 -2
- package/src/commands/doctor.ts +172 -0
- package/src/commands/wallet.ts +57 -6
- package/src/config.ts +9 -1
- package/src/daemon/index.ts +234 -140
- package/src/endpoint-notify.ts +73 -0
- package/src/program.ts +2 -0
- package/src/repl.ts +53 -42
- package/src/ui/format.ts +1 -0
package/src/repl.ts
CHANGED
|
@@ -6,17 +6,11 @@ import { createProgram } from "./program";
|
|
|
6
6
|
import { getBannerLines, BannerConfig } from "./ui/banner";
|
|
7
7
|
import { c } from "./ui/colors";
|
|
8
8
|
|
|
9
|
-
// ─── Sentinel to intercept process.exit() from commands ──────────────────────
|
|
10
|
-
|
|
11
|
-
class REPLExitSignal extends Error {
|
|
12
|
-
constructor(public readonly code: number = 0) {
|
|
13
|
-
super("repl-exit-signal");
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
9
|
// ─── Config / banner helpers ──────────────────────────────────────────────────
|
|
18
10
|
|
|
19
11
|
const CONFIG_PATH = path.join(os.homedir(), ".arc402", "config.json");
|
|
12
|
+
const HISTORY_PATH = path.join(os.homedir(), ".arc402", "repl_history");
|
|
13
|
+
const MAX_HISTORY = 1000;
|
|
20
14
|
|
|
21
15
|
async function loadBannerConfig(): Promise<BannerConfig | undefined> {
|
|
22
16
|
if (!fs.existsSync(CONFIG_PATH)) return undefined;
|
|
@@ -99,10 +93,21 @@ function parseTokens(input: string): string[] {
|
|
|
99
93
|
let current = "";
|
|
100
94
|
let inQuote = false;
|
|
101
95
|
let quoteChar = "";
|
|
96
|
+
let escape = false;
|
|
102
97
|
for (const ch of input) {
|
|
98
|
+
if (escape) {
|
|
99
|
+
current += ch;
|
|
100
|
+
escape = false;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
103
|
if (inQuote) {
|
|
104
|
-
if (ch ===
|
|
105
|
-
|
|
104
|
+
if (quoteChar === '"' && ch === "\\") {
|
|
105
|
+
escape = true;
|
|
106
|
+
} else if (ch === quoteChar) {
|
|
107
|
+
inQuote = false;
|
|
108
|
+
} else {
|
|
109
|
+
current += ch;
|
|
110
|
+
}
|
|
106
111
|
} else if (ch === '"' || ch === "'") {
|
|
107
112
|
inQuote = true;
|
|
108
113
|
quoteChar = ch;
|
|
@@ -174,6 +179,14 @@ class TUI {
|
|
|
174
179
|
async start(): Promise<void> {
|
|
175
180
|
this.bannerCfg = await loadBannerConfig();
|
|
176
181
|
|
|
182
|
+
// Load persisted history
|
|
183
|
+
try {
|
|
184
|
+
if (fs.existsSync(HISTORY_PATH)) {
|
|
185
|
+
const lines = fs.readFileSync(HISTORY_PATH, "utf-8").split("\n").filter(Boolean);
|
|
186
|
+
this.history = lines.slice(-MAX_HISTORY);
|
|
187
|
+
}
|
|
188
|
+
} catch { /* non-fatal */ }
|
|
189
|
+
|
|
177
190
|
// Build command metadata for completion
|
|
178
191
|
const template = createProgram();
|
|
179
192
|
this.topCmds = template.commands.map((cmd) => cmd.name());
|
|
@@ -529,42 +542,32 @@ class TUI {
|
|
|
529
542
|
writeErr: (str) => process.stderr.write(str),
|
|
530
543
|
});
|
|
531
544
|
|
|
532
|
-
const origExit = process.exit;
|
|
533
|
-
(process as NodeJS.Process).exit = ((code?: number) => {
|
|
534
|
-
throw new REPLExitSignal(code ?? 0);
|
|
535
|
-
}) as typeof process.exit;
|
|
536
|
-
|
|
537
545
|
try {
|
|
538
546
|
await prog.parseAsync(["node", "arc402", ...tokens]);
|
|
539
547
|
} catch (err) {
|
|
540
|
-
|
|
541
|
-
|
|
548
|
+
const e = err as { code?: string; message?: string };
|
|
549
|
+
if (
|
|
550
|
+
e.code === "commander.helpDisplayed" ||
|
|
551
|
+
e.code === "commander.version" ||
|
|
552
|
+
e.code === "commander.executeSubCommandAsync"
|
|
553
|
+
) {
|
|
554
|
+
// already written or normal exit
|
|
555
|
+
} else if (e.code === "commander.unknownCommand") {
|
|
556
|
+
process.stdout.write(
|
|
557
|
+
`\n ${c.failure} ${chalk.red(`Unknown command: ${chalk.white(tokens[0])}`)} \n`
|
|
558
|
+
);
|
|
559
|
+
process.stdout.write(
|
|
560
|
+
chalk.dim(" Type 'help' for available commands\n")
|
|
561
|
+
);
|
|
562
|
+
} else if (e.code?.startsWith("commander.")) {
|
|
563
|
+
process.stdout.write(
|
|
564
|
+
`\n ${c.failure} ${chalk.red(e.message ?? String(err))}\n`
|
|
565
|
+
);
|
|
542
566
|
} else {
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
e.code === "commander.version"
|
|
547
|
-
) {
|
|
548
|
-
// already written
|
|
549
|
-
} else if (e.code === "commander.unknownCommand") {
|
|
550
|
-
process.stdout.write(
|
|
551
|
-
`\n ${c.failure} ${chalk.red(`Unknown command: ${chalk.white(tokens[0])}`)} \n`
|
|
552
|
-
);
|
|
553
|
-
process.stdout.write(
|
|
554
|
-
chalk.dim(" Type 'help' for available commands\n")
|
|
555
|
-
);
|
|
556
|
-
} else if (e.code?.startsWith("commander.")) {
|
|
557
|
-
process.stdout.write(
|
|
558
|
-
`\n ${c.failure} ${chalk.red(e.message ?? String(err))}\n`
|
|
559
|
-
);
|
|
560
|
-
} else {
|
|
561
|
-
process.stdout.write(
|
|
562
|
-
`\n ${c.failure} ${chalk.red(e.message ?? String(err))}\n`
|
|
563
|
-
);
|
|
564
|
-
}
|
|
567
|
+
process.stdout.write(
|
|
568
|
+
`\n ${c.failure} ${chalk.red(e.message ?? String(err))}\n`
|
|
569
|
+
);
|
|
565
570
|
}
|
|
566
|
-
} finally {
|
|
567
|
-
(process as NodeJS.Process).exit = origExit;
|
|
568
571
|
}
|
|
569
572
|
|
|
570
573
|
// Restore raw mode + our listener (interactive commands may have toggled it)
|
|
@@ -579,7 +582,8 @@ class TUI {
|
|
|
579
582
|
|
|
580
583
|
// ── OpenClaw chat ─────────────────────────────────────────────────────────────
|
|
581
584
|
|
|
582
|
-
private async sendChat(
|
|
585
|
+
private async sendChat(rawMessage: string): Promise<void> {
|
|
586
|
+
const message = rawMessage.trim().slice(0, 10000);
|
|
583
587
|
write(ansi.move(this.scrollBot, 1));
|
|
584
588
|
|
|
585
589
|
let res: Response;
|
|
@@ -762,6 +766,13 @@ class TUI {
|
|
|
762
766
|
// ── Exit ──────────────────────────────────────────────────────────────────────
|
|
763
767
|
|
|
764
768
|
private exitGracefully(): void {
|
|
769
|
+
// Save history
|
|
770
|
+
try {
|
|
771
|
+
const toSave = this.history.slice(-MAX_HISTORY);
|
|
772
|
+
fs.mkdirSync(path.dirname(HISTORY_PATH), { recursive: true });
|
|
773
|
+
fs.writeFileSync(HISTORY_PATH, toSave.join("\n") + "\n", { mode: 0o600 });
|
|
774
|
+
} catch { /* non-fatal */ }
|
|
775
|
+
|
|
765
776
|
write(ansi.move(this.inputRow, 1) + ansi.clearLine);
|
|
766
777
|
write(" " + chalk.cyanBright("◈") + chalk.dim(" goodbye") + "\n");
|
|
767
778
|
write(ansi.resetScroll);
|
package/src/ui/format.ts
CHANGED
|
@@ -42,6 +42,7 @@ export function formatTimeAgo(timestampSeconds: number): string {
|
|
|
42
42
|
const now = Math.floor(Date.now() / 1000);
|
|
43
43
|
const delta = now - timestampSeconds;
|
|
44
44
|
|
|
45
|
+
if (delta < 0) return "in " + formatDuration(Math.abs(delta));
|
|
45
46
|
if (delta < 60) return "just now";
|
|
46
47
|
if (delta < 3600) {
|
|
47
48
|
const m = Math.floor(delta / 60);
|