arc402-cli 0.7.5 → 0.8.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/MIGRATION-SPEC.md +108 -0
- package/dist/abis.js +14 -17
- package/dist/abis.js.map +1 -1
- package/dist/bundler.d.ts +1 -1
- package/dist/bundler.d.ts.map +1 -1
- package/dist/bundler.js +27 -61
- package/dist/bundler.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +5 -9
- package/dist/client.js.map +1 -1
- package/dist/coinbase-smart-wallet.js +1 -4
- package/dist/coinbase-smart-wallet.js.map +1 -1
- package/dist/commands/accept.js +25 -28
- package/dist/commands/accept.js.map +1 -1
- package/dist/commands/agent-handshake.js +15 -18
- package/dist/commands/agent-handshake.js.map +1 -1
- package/dist/commands/agent.js +98 -104
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/agreements.js +62 -98
- package/dist/commands/agreements.js.map +1 -1
- package/dist/commands/arbitrator.js +45 -81
- package/dist/commands/arbitrator.js.map +1 -1
- package/dist/commands/arena-handshake.js +27 -30
- package/dist/commands/arena-handshake.js.map +1 -1
- package/dist/commands/arena.js +12 -18
- package/dist/commands/arena.js.map +1 -1
- package/dist/commands/backup.js +30 -36
- package/dist/commands/backup.js.map +1 -1
- package/dist/commands/cancel.js +15 -18
- package/dist/commands/cancel.js.map +1 -1
- package/dist/commands/channel.js +45 -81
- package/dist/commands/channel.js.map +1 -1
- package/dist/commands/coldstart.js +31 -34
- package/dist/commands/coldstart.js.map +1 -1
- package/dist/commands/config.js +23 -29
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/contract-interaction.js +12 -15
- package/dist/commands/contract-interaction.js.map +1 -1
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/daemon.js +98 -135
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/deliver.js +37 -76
- package/dist/commands/deliver.js.map +1 -1
- package/dist/commands/discover.js +24 -27
- package/dist/commands/discover.js.map +1 -1
- package/dist/commands/dispute.js +104 -110
- package/dist/commands/dispute.js.map +1 -1
- package/dist/commands/doctor.js +16 -55
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/endpoint.js +56 -95
- package/dist/commands/endpoint.js.map +1 -1
- package/dist/commands/feed.js +11 -18
- package/dist/commands/feed.js.map +1 -1
- package/dist/commands/hire.js +37 -40
- package/dist/commands/hire.js.map +1 -1
- package/dist/commands/migrate.js +30 -33
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/negotiate.d.ts.map +1 -1
- package/dist/commands/negotiate.js +34 -36
- package/dist/commands/negotiate.js.map +1 -1
- package/dist/commands/openshell.js +68 -104
- package/dist/commands/openshell.js.map +1 -1
- package/dist/commands/owner.js +17 -20
- package/dist/commands/owner.js.map +1 -1
- package/dist/commands/policy.js +41 -43
- package/dist/commands/policy.js.map +1 -1
- package/dist/commands/relay.d.ts.map +1 -1
- package/dist/commands/relay.js +18 -51
- package/dist/commands/relay.js.map +1 -1
- package/dist/commands/remediate.js +20 -23
- package/dist/commands/remediate.js.map +1 -1
- package/dist/commands/reputation.js +25 -27
- package/dist/commands/reputation.js.map +1 -1
- package/dist/commands/setup.js +65 -104
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/trust.js +17 -20
- package/dist/commands/trust.js.map +1 -1
- package/dist/commands/verify.js +18 -21
- package/dist/commands/verify.js.map +1 -1
- package/dist/commands/wallet.js +619 -625
- package/dist/commands/wallet.js.map +1 -1
- package/dist/commands/watch.js +33 -36
- package/dist/commands/watch.js.map +1 -1
- package/dist/commands/watchtower.js +37 -73
- package/dist/commands/watchtower.js.map +1 -1
- package/dist/commands/workroom.d.ts.map +1 -1
- package/dist/commands/workroom.js +138 -171
- package/dist/commands/workroom.js.map +1 -1
- package/dist/config.js +21 -65
- package/dist/config.js.map +1 -1
- package/dist/daemon/config.d.ts.map +1 -1
- package/dist/daemon/config.js +16 -53
- package/dist/daemon/config.js.map +1 -1
- package/dist/daemon/hire-listener.d.ts +3 -3
- package/dist/daemon/hire-listener.d.ts.map +1 -1
- package/dist/daemon/hire-listener.js +13 -47
- package/dist/daemon/hire-listener.js.map +1 -1
- package/dist/daemon/index.d.ts +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +50 -88
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/job-lifecycle.d.ts +1 -1
- package/dist/daemon/job-lifecycle.d.ts.map +1 -1
- package/dist/daemon/job-lifecycle.js +11 -51
- package/dist/daemon/job-lifecycle.js.map +1 -1
- package/dist/daemon/notify.d.ts +1 -1
- package/dist/daemon/notify.d.ts.map +1 -1
- package/dist/daemon/notify.js +19 -53
- package/dist/daemon/notify.js.map +1 -1
- package/dist/daemon/token-metering.js +8 -47
- package/dist/daemon/token-metering.js.map +1 -1
- package/dist/daemon/userops.d.ts +2 -2
- package/dist/daemon/userops.d.ts.map +1 -1
- package/dist/daemon/userops.js +23 -27
- package/dist/daemon/userops.js.map +1 -1
- package/dist/daemon/wallet-monitor.d.ts +1 -1
- package/dist/daemon/wallet-monitor.d.ts.map +1 -1
- package/dist/daemon/wallet-monitor.js +8 -12
- package/dist/daemon/wallet-monitor.js.map +1 -1
- package/dist/drain-v4.js +26 -64
- package/dist/drain-v4.js.map +1 -1
- package/dist/endpoint-config.js +20 -63
- package/dist/endpoint-config.js.map +1 -1
- package/dist/endpoint-notify.js +9 -48
- package/dist/endpoint-notify.js.map +1 -1
- package/dist/index.js +16 -50
- package/dist/index.js.map +1 -1
- package/dist/openshell-runtime.d.ts.map +1 -1
- package/dist/openshell-runtime.js +38 -82
- package/dist/openshell-runtime.js.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +77 -83
- package/dist/program.js.map +1 -1
- package/dist/repl.js +25 -31
- package/dist/repl.js.map +1 -1
- package/dist/signing.js +3 -6
- package/dist/signing.js.map +1 -1
- package/dist/telegram-notify.js +3 -40
- package/dist/telegram-notify.js.map +1 -1
- package/dist/tui/App.d.ts +1 -9
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +47 -65
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/Footer.js +4 -7
- package/dist/tui/Footer.js.map +1 -1
- package/dist/tui/Header.d.ts +1 -2
- package/dist/tui/Header.d.ts.map +1 -1
- package/dist/tui/Header.js +8 -14
- package/dist/tui/Header.js.map +1 -1
- package/dist/tui/InputLine.js +17 -23
- package/dist/tui/InputLine.js.map +1 -1
- package/dist/tui/Viewport.d.ts +5 -4
- package/dist/tui/Viewport.d.ts.map +1 -1
- package/dist/tui/Viewport.js +20 -13
- package/dist/tui/Viewport.js.map +1 -1
- package/dist/tui/WalletConnectPairing.d.ts +23 -0
- package/dist/tui/WalletConnectPairing.d.ts.map +1 -0
- package/dist/tui/WalletConnectPairing.js +75 -0
- package/dist/tui/WalletConnectPairing.js.map +1 -0
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +14 -21
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/useChat.js +13 -19
- package/dist/tui/useChat.js.map +1 -1
- package/dist/tui/useCommand.d.ts +2 -7
- package/dist/tui/useCommand.d.ts.map +1 -1
- package/dist/tui/useCommand.js +77 -165
- package/dist/tui/useCommand.js.map +1 -1
- package/dist/tui/useScroll.js +9 -12
- package/dist/tui/useScroll.js.map +1 -1
- package/dist/ui/banner.js +12 -19
- package/dist/ui/banner.js.map +1 -1
- package/dist/ui/colors.js +13 -19
- package/dist/ui/colors.js.map +1 -1
- package/dist/ui/format.js +6 -14
- package/dist/ui/format.js.map +1 -1
- package/dist/ui/spinner.js +6 -12
- package/dist/ui/spinner.js.map +1 -1
- package/dist/ui/tree.js +3 -6
- package/dist/ui/tree.js.map +1 -1
- package/dist/utils/format.js +27 -41
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/hash.js +4 -42
- package/dist/utils/hash.js.map +1 -1
- package/dist/utils/time.js +2 -6
- package/dist/utils/time.js.map +1 -1
- package/dist/wallet-router.d.ts +1 -1
- package/dist/wallet-router.d.ts.map +1 -1
- package/dist/wallet-router.js +12 -19
- package/dist/wallet-router.js.map +1 -1
- package/dist/walletconnect-session.d.ts +1 -1
- package/dist/walletconnect-session.d.ts.map +1 -1
- package/dist/walletconnect-session.js +6 -11
- package/dist/walletconnect-session.js.map +1 -1
- package/dist/walletconnect.d.ts +6 -1
- package/dist/walletconnect.d.ts.map +1 -1
- package/dist/walletconnect.js +32 -35
- package/dist/walletconnect.js.map +1 -1
- package/package.json +7 -6
- package/src/bundler.ts +1 -1
- package/src/client.ts +1 -1
- package/src/commands/accept.ts +7 -7
- package/src/commands/agent-handshake.ts +4 -4
- package/src/commands/agent.ts +9 -9
- package/src/commands/agreements.ts +8 -8
- package/src/commands/arbitrator.ts +5 -5
- package/src/commands/arena-handshake.ts +6 -6
- package/src/commands/arena.ts +2 -2
- package/src/commands/backup.ts +1 -1
- package/src/commands/cancel.ts +6 -6
- package/src/commands/channel.ts +6 -6
- package/src/commands/coldstart.ts +5 -5
- package/src/commands/config.ts +2 -2
- package/src/commands/contract-interaction.ts +2 -2
- package/src/commands/daemon.ts +14 -11
- package/src/commands/deliver.ts +9 -9
- package/src/commands/discover.ts +5 -5
- package/src/commands/dispute.ts +7 -7
- package/src/commands/doctor.ts +2 -2
- package/src/commands/endpoint.ts +6 -6
- package/src/commands/feed.ts +1 -1
- package/src/commands/hire.ts +10 -10
- package/src/commands/migrate.ts +7 -7
- package/src/commands/negotiate.ts +6 -5
- package/src/commands/openshell.ts +4 -4
- package/src/commands/owner.ts +5 -5
- package/src/commands/policy.ts +5 -5
- package/src/commands/relay.ts +5 -1
- package/src/commands/remediate.ts +5 -5
- package/src/commands/reputation.ts +6 -6
- package/src/commands/setup.ts +1 -1
- package/src/commands/trust.ts +6 -6
- package/src/commands/verify.ts +6 -6
- package/src/commands/wallet.ts +15 -15
- package/src/commands/watch.ts +3 -3
- package/src/commands/watchtower.ts +6 -6
- package/src/commands/workroom.ts +14 -10
- package/src/daemon/config.ts +2 -1
- package/src/daemon/hire-listener.ts +3 -3
- package/src/daemon/index.ts +10 -9
- package/src/daemon/job-lifecycle.ts +1 -1
- package/src/daemon/notify.ts +4 -4
- package/src/daemon/userops.ts +4 -4
- package/src/daemon/wallet-monitor.ts +2 -2
- package/src/endpoint-notify.ts +1 -1
- package/src/index.ts +8 -7
- package/src/openshell-runtime.ts +5 -1
- package/src/program.ts +36 -36
- package/src/repl.ts +3 -3
- package/src/tui/App.tsx +26 -47
- package/src/tui/Header.tsx +3 -10
- package/src/tui/InputLine.tsx +1 -1
- package/src/tui/Viewport.tsx +22 -18
- package/src/tui/WalletConnectPairing.tsx +131 -0
- package/src/tui/index.tsx +7 -8
- package/src/tui/useChat.ts +1 -1
- package/src/tui/useCommand.ts +86 -183
- package/src/ui/banner.ts +2 -2
- package/src/ui/tree.ts +1 -1
- package/src/wallet-router.ts +2 -2
- package/src/walletconnect-session.ts +1 -1
- package/src/walletconnect.ts +20 -5
- package/tsconfig.json +16 -7
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
import * as http from "http";
|
|
6
6
|
import * as https from "https";
|
|
7
7
|
import { ethers } from "ethers";
|
|
8
|
-
import type { DaemonConfig } from "./config";
|
|
9
|
-
import type { DaemonDB } from "./index";
|
|
10
|
-
import type { Notifier } from "./notify";
|
|
8
|
+
import type { DaemonConfig } from "./config.js";
|
|
9
|
+
import type { DaemonDB } from "./index.js";
|
|
10
|
+
import type { Notifier } from "./notify.js";
|
|
11
11
|
|
|
12
12
|
export interface HireProposal {
|
|
13
13
|
messageId: string;
|
package/src/daemon/index.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* Signals: SIGTERM → graceful shutdown.
|
|
9
9
|
*/
|
|
10
10
|
import * as fs from "fs";
|
|
11
|
+
import * as os from "os";
|
|
11
12
|
import * as path from "path";
|
|
12
13
|
import * as net from "net";
|
|
13
14
|
import * as http from "http";
|
|
@@ -25,12 +26,12 @@ import {
|
|
|
25
26
|
DAEMON_DB,
|
|
26
27
|
DAEMON_SOCK,
|
|
27
28
|
type DaemonConfig,
|
|
28
|
-
} from "./config";
|
|
29
|
-
import { verifyWallet, getWalletBalance } from "./wallet-monitor";
|
|
30
|
-
import { buildNotifier } from "./notify";
|
|
31
|
-
import { HireListener } from "./hire-listener";
|
|
32
|
-
import { UserOpsManager, buildAcceptCalldata } from "./userops";
|
|
33
|
-
import { generateReceipt, extractLearnings, createJobDirectory, cleanJobDirectory } from "./job-lifecycle";
|
|
29
|
+
} from "./config.js";
|
|
30
|
+
import { verifyWallet, getWalletBalance } from "./wallet-monitor.js";
|
|
31
|
+
import { buildNotifier } from "./notify.js";
|
|
32
|
+
import { HireListener } from "./hire-listener.js";
|
|
33
|
+
import { UserOpsManager, buildAcceptCalldata } from "./userops.js";
|
|
34
|
+
import { generateReceipt, extractLearnings, createJobDirectory, cleanJobDirectory } from "./job-lifecycle.js";
|
|
34
35
|
|
|
35
36
|
// ─── State DB ─────────────────────────────────────────────────────────────────
|
|
36
37
|
|
|
@@ -432,7 +433,7 @@ function formatUptime(seconds: number): string {
|
|
|
432
433
|
// ─── Daemon main ──────────────────────────────────────────────────────────────
|
|
433
434
|
|
|
434
435
|
// Extend config with serviceAgreementAddress (loaded from CLI config if available)
|
|
435
|
-
declare module "./config" {
|
|
436
|
+
declare module "./config.js" {
|
|
436
437
|
interface DaemonConfig {
|
|
437
438
|
serviceAgreementAddress?: string;
|
|
438
439
|
}
|
|
@@ -448,7 +449,7 @@ export async function runDaemon(foreground = false): Promise<void> {
|
|
|
448
449
|
let config: DaemonConfig;
|
|
449
450
|
try {
|
|
450
451
|
config = loadDaemonConfig();
|
|
451
|
-
log({ event: "config_loaded", path:
|
|
452
|
+
log({ event: "config_loaded", path: path.join(os.homedir(), ".arc402", "daemon.toml") });
|
|
452
453
|
} catch (err) {
|
|
453
454
|
process.stderr.write(`Config error: ${err}\n`);
|
|
454
455
|
process.exit(1);
|
|
@@ -763,7 +764,7 @@ export async function runDaemon(foreground = false): Promise<void> {
|
|
|
763
764
|
}
|
|
764
765
|
|
|
765
766
|
// Policy check
|
|
766
|
-
const { evaluatePolicy } = await import("./hire-listener");
|
|
767
|
+
const { evaluatePolicy } = await import("./hire-listener.js");
|
|
767
768
|
const activeCount = db.countActiveHireRequests();
|
|
768
769
|
const policyResult = evaluatePolicy(proposal, config, activeCount);
|
|
769
770
|
|
|
@@ -13,7 +13,7 @@ import * as fs from "fs";
|
|
|
13
13
|
import * as path from "path";
|
|
14
14
|
import * as os from "os";
|
|
15
15
|
import * as crypto from "crypto";
|
|
16
|
-
import { readUsageReport, type AggregatedTokenUsage } from "./token-metering";
|
|
16
|
+
import { readUsageReport, type AggregatedTokenUsage } from "./token-metering.js";
|
|
17
17
|
|
|
18
18
|
const ARC402_DIR = path.join(os.homedir(), ".arc402");
|
|
19
19
|
const RECEIPTS_DIR = path.join(ARC402_DIR, "receipts");
|
package/src/daemon/notify.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import * as https from "https";
|
|
6
6
|
import * as http from "http";
|
|
7
|
-
import type { DaemonConfig } from "./config";
|
|
7
|
+
import type { DaemonConfig } from "./config.js";
|
|
8
8
|
|
|
9
9
|
export type NotifyEvent =
|
|
10
10
|
| "hire_request"
|
|
@@ -133,11 +133,11 @@ export class EmailChannel implements NotificationChannel {
|
|
|
133
133
|
async send(title: string, body: string): Promise<void> {
|
|
134
134
|
// nodemailer is an optional runtime dependency — load via require to skip
|
|
135
135
|
// compile-time module resolution. Throws a clear message if not installed.
|
|
136
|
-
// eslint-disable-next-line @typescript-eslint/no-
|
|
136
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
137
137
|
let nodemailer: any;
|
|
138
138
|
try {
|
|
139
|
-
//
|
|
140
|
-
nodemailer =
|
|
139
|
+
// @ts-expect-error nodemailer is an optional dependency
|
|
140
|
+
nodemailer = await import("nodemailer");
|
|
141
141
|
} catch {
|
|
142
142
|
throw new Error("nodemailer is not installed. Run: npm install nodemailer");
|
|
143
143
|
}
|
package/src/daemon/userops.ts
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* Wraps protocol calls (accept, fulfill) into ERC-4337 UserOperations.
|
|
4
4
|
*/
|
|
5
5
|
import { ethers } from "ethers";
|
|
6
|
-
import { BundlerClient } from "../bundler";
|
|
7
|
-
import type { UserOperation } from "../bundler";
|
|
8
|
-
import type { DaemonConfig } from "./config";
|
|
9
|
-
import { ARC402_WALLET_EXECUTE_ABI } from "../abis";
|
|
6
|
+
import { BundlerClient } from "../bundler.js";
|
|
7
|
+
import type { UserOperation } from "../bundler.js";
|
|
8
|
+
import type { DaemonConfig } from "./config.js";
|
|
9
|
+
import { ARC402_WALLET_EXECUTE_ABI } from "../abis.js";
|
|
10
10
|
|
|
11
11
|
// ServiceAgreement calldata encoders
|
|
12
12
|
const SA_IFACE = new ethers.Interface([
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* Steps 4 and 5 of the daemon startup sequence (Spec 32 §3).
|
|
4
4
|
*/
|
|
5
5
|
import { ethers } from "ethers";
|
|
6
|
-
import type { DaemonConfig } from "./config";
|
|
6
|
+
import type { DaemonConfig } from "./config.js";
|
|
7
7
|
import {
|
|
8
8
|
ARC402_WALLET_GUARDIAN_ABI,
|
|
9
9
|
ARC402_WALLET_MACHINE_KEY_ABI,
|
|
10
|
-
} from "../abis";
|
|
10
|
+
} from "../abis.js";
|
|
11
11
|
|
|
12
12
|
export interface WalletStatus {
|
|
13
13
|
contractAddress: string;
|
package/src/endpoint-notify.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* and POSTs lifecycle events after onchain transactions.
|
|
5
5
|
*/
|
|
6
6
|
import { ethers } from "ethers";
|
|
7
|
-
import { AGENT_REGISTRY_ABI } from "./abis";
|
|
7
|
+
import { AGENT_REGISTRY_ABI } from "./abis.js";
|
|
8
8
|
import * as dns from "dns/promises";
|
|
9
9
|
|
|
10
10
|
export const DEFAULT_REGISTRY_ADDRESS = "0xD5c2851B00090c92Ba7F4723FB548bb30C9B6865";
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { createProgram } from "./program.js";
|
|
4
|
+
import { startREPL } from "./repl.js";
|
|
5
|
+
import { configExists, loadConfig, saveConfig } from "./config.js";
|
|
5
6
|
|
|
6
7
|
// ── Upgrade safety check ────────────────────────────────────────────────────
|
|
7
|
-
|
|
8
|
-
const currentVersion: string = (
|
|
8
|
+
const _require = createRequire(import.meta.url);
|
|
9
|
+
const currentVersion: string = (_require("../package.json") as { version: string }).version;
|
|
9
10
|
|
|
10
11
|
function checkUpgrade(): void {
|
|
11
12
|
if (!configExists()) return;
|
|
@@ -53,9 +54,9 @@ if (printMode) {
|
|
|
53
54
|
process.exit(1);
|
|
54
55
|
});
|
|
55
56
|
} else if (process.stdout.isTTY && !hasSubcommand && process.argv.length <= 2 && !process.env.ARC402_NO_TUI) {
|
|
56
|
-
// TTY with no subcommand — launch Ink TUI
|
|
57
|
+
// TTY with no subcommand — launch Ink TUI
|
|
57
58
|
checkUpgrade();
|
|
58
|
-
void import("./tui/index").then(({ launchTUI }) => launchTUI()).catch((e: unknown) => {
|
|
59
|
+
void import("./tui/index.js").then(({ launchTUI }) => launchTUI()).catch((e: unknown) => {
|
|
59
60
|
console.error("TUI failed to start:", e instanceof Error ? e.message : String(e));
|
|
60
61
|
// Fallback to REPL
|
|
61
62
|
void startREPL();
|
package/src/openshell-runtime.ts
CHANGED
|
@@ -3,7 +3,11 @@ import * as os from "os";
|
|
|
3
3
|
import * as path from "path";
|
|
4
4
|
import { spawnSync } from "child_process";
|
|
5
5
|
import { parse as parseToml } from "smol-toml";
|
|
6
|
-
import { loadConfig } from "./config";
|
|
6
|
+
import { loadConfig } from "./config.js";
|
|
7
|
+
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(__filename);
|
|
7
11
|
|
|
8
12
|
export const ARC402_DIR = path.join(os.homedir(), ".arc402");
|
|
9
13
|
export const OPENSHELL_TOML = path.join(ARC402_DIR, "openshell.toml");
|
package/src/program.ts
CHANGED
|
@@ -1,38 +1,39 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
1
2
|
import { Command } from "commander";
|
|
2
|
-
import { registerAcceptCommand } from "./commands/accept";
|
|
3
|
-
import { registerAgentCommands } from "./commands/agent";
|
|
4
|
-
import { registerAgreementsCommands } from "./commands/agreements";
|
|
5
|
-
import { registerArbitratorCommand } from "./commands/arbitrator";
|
|
6
|
-
import { registerCancelCommand } from "./commands/cancel";
|
|
7
|
-
import { registerChannelCommands } from "./commands/channel";
|
|
8
|
-
import { registerConfigCommands } from "./commands/config";
|
|
9
|
-
import { registerDeliverCommand } from "./commands/deliver";
|
|
10
|
-
import { registerDiscoverCommand } from "./commands/discover";
|
|
11
|
-
import { registerEndpointCommands } from "./commands/endpoint";
|
|
12
|
-
import { registerDisputeCommand } from "./commands/dispute";
|
|
13
|
-
import { registerHireCommand } from "./commands/hire";
|
|
14
|
-
import { registerHandshakeCommand } from "./commands/agent-handshake";
|
|
15
|
-
import { registerNegotiateCommands } from "./commands/negotiate";
|
|
16
|
-
import { registerRelayCommands } from "./commands/relay";
|
|
17
|
-
import { registerRemediateCommands } from "./commands/remediate";
|
|
18
|
-
import { registerDaemonCommands } from "./commands/daemon";
|
|
19
|
-
import { registerOpenShellCommands } from "./commands/openshell";
|
|
20
|
-
import { registerWorkroomCommands } from "./commands/workroom";
|
|
21
|
-
import { registerArenaHandshakeCommands } from "./commands/arena-handshake";
|
|
22
|
-
import { registerTrustCommand } from "./commands/trust";
|
|
23
|
-
import { registerWalletCommands } from "./commands/wallet";
|
|
24
|
-
import { registerOwnerCommands } from "./commands/owner";
|
|
25
|
-
import { registerSetupCommands } from "./commands/setup";
|
|
26
|
-
import { registerVerifyCommand } from "./commands/verify";
|
|
27
|
-
import { registerContractInteractionCommands } from "./commands/contract-interaction";
|
|
28
|
-
import { registerWatchtowerCommands } from "./commands/watchtower";
|
|
29
|
-
import { registerColdStartCommands } from "./commands/coldstart";
|
|
30
|
-
import { registerDoctorCommand } from "./commands/doctor";
|
|
31
|
-
import { registerMigrateCommands } from "./commands/migrate";
|
|
32
|
-
import { registerFeedCommand } from "./commands/feed";
|
|
33
|
-
import { registerArenaCommands } from "./commands/arena";
|
|
34
|
-
import { registerWatchCommand } from "./commands/watch";
|
|
35
|
-
import { registerBackupCommand } from "./commands/backup";
|
|
3
|
+
import { registerAcceptCommand } from "./commands/accept.js";
|
|
4
|
+
import { registerAgentCommands } from "./commands/agent.js";
|
|
5
|
+
import { registerAgreementsCommands } from "./commands/agreements.js";
|
|
6
|
+
import { registerArbitratorCommand } from "./commands/arbitrator.js";
|
|
7
|
+
import { registerCancelCommand } from "./commands/cancel.js";
|
|
8
|
+
import { registerChannelCommands } from "./commands/channel.js";
|
|
9
|
+
import { registerConfigCommands } from "./commands/config.js";
|
|
10
|
+
import { registerDeliverCommand } from "./commands/deliver.js";
|
|
11
|
+
import { registerDiscoverCommand } from "./commands/discover.js";
|
|
12
|
+
import { registerEndpointCommands } from "./commands/endpoint.js";
|
|
13
|
+
import { registerDisputeCommand } from "./commands/dispute.js";
|
|
14
|
+
import { registerHireCommand } from "./commands/hire.js";
|
|
15
|
+
import { registerHandshakeCommand } from "./commands/agent-handshake.js";
|
|
16
|
+
import { registerNegotiateCommands } from "./commands/negotiate.js";
|
|
17
|
+
import { registerRelayCommands } from "./commands/relay.js";
|
|
18
|
+
import { registerRemediateCommands } from "./commands/remediate.js";
|
|
19
|
+
import { registerDaemonCommands } from "./commands/daemon.js";
|
|
20
|
+
import { registerOpenShellCommands } from "./commands/openshell.js";
|
|
21
|
+
import { registerWorkroomCommands } from "./commands/workroom.js";
|
|
22
|
+
import { registerArenaHandshakeCommands } from "./commands/arena-handshake.js";
|
|
23
|
+
import { registerTrustCommand } from "./commands/trust.js";
|
|
24
|
+
import { registerWalletCommands } from "./commands/wallet.js";
|
|
25
|
+
import { registerOwnerCommands } from "./commands/owner.js";
|
|
26
|
+
import { registerSetupCommands } from "./commands/setup.js";
|
|
27
|
+
import { registerVerifyCommand } from "./commands/verify.js";
|
|
28
|
+
import { registerContractInteractionCommands } from "./commands/contract-interaction.js";
|
|
29
|
+
import { registerWatchtowerCommands } from "./commands/watchtower.js";
|
|
30
|
+
import { registerColdStartCommands } from "./commands/coldstart.js";
|
|
31
|
+
import { registerDoctorCommand } from "./commands/doctor.js";
|
|
32
|
+
import { registerMigrateCommands } from "./commands/migrate.js";
|
|
33
|
+
import { registerFeedCommand } from "./commands/feed.js";
|
|
34
|
+
import { registerArenaCommands } from "./commands/arena.js";
|
|
35
|
+
import { registerWatchCommand } from "./commands/watch.js";
|
|
36
|
+
import { registerBackupCommand } from "./commands/backup.js";
|
|
36
37
|
import reputation from "./commands/reputation.js";
|
|
37
38
|
import policy from "./commands/policy.js";
|
|
38
39
|
|
|
@@ -43,8 +44,7 @@ export function createProgram(): Command {
|
|
|
43
44
|
.description(
|
|
44
45
|
"ARC-402 CLI aligned to canonical-capability discovery → negotiate → hire → remediate → dispute workflow"
|
|
45
46
|
)
|
|
46
|
-
|
|
47
|
-
.version((require("../package.json") as { version: string }).version);
|
|
47
|
+
.version((createRequire(import.meta.url)("../package.json") as { version: string }).version);
|
|
48
48
|
|
|
49
49
|
registerConfigCommands(program);
|
|
50
50
|
registerHandshakeCommand(program);
|
package/src/repl.ts
CHANGED
|
@@ -3,9 +3,9 @@ import fs from "fs";
|
|
|
3
3
|
import path from "path";
|
|
4
4
|
import os from "os";
|
|
5
5
|
import readline from "readline";
|
|
6
|
-
import { createProgram } from "./program";
|
|
7
|
-
import { getBannerLines, BannerConfig } from "./ui/banner";
|
|
8
|
-
import { c } from "./ui/colors";
|
|
6
|
+
import { createProgram } from "./program.js";
|
|
7
|
+
import { getBannerLines, BannerConfig } from "./ui/banner.js";
|
|
8
|
+
import { c } from "./ui/colors.js";
|
|
9
9
|
|
|
10
10
|
// ─── Config helpers ────────────────────────────────────────────────────────────
|
|
11
11
|
|
package/src/tui/App.tsx
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import React, { useState, useCallback } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
1
|
+
import React, { useState, useCallback, useEffect } from "react";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { Box, Text, useApp } from "ink";
|
|
4
|
+
import { Header } from "./Header.js";
|
|
5
|
+
import { Viewport } from "./Viewport.js";
|
|
6
|
+
import { Footer } from "./Footer.js";
|
|
7
|
+
import { InputLine } from "./InputLine.js";
|
|
8
|
+
import { useCommand } from "./useCommand.js";
|
|
9
|
+
import { useChat } from "./useChat.js";
|
|
10
|
+
import { useScroll } from "./useScroll.js";
|
|
11
|
+
import { createProgram } from "../program.js";
|
|
10
12
|
import chalk from "chalk";
|
|
11
13
|
|
|
14
|
+
const pkg = createRequire(import.meta.url)("../../package.json") as { version: string };
|
|
15
|
+
|
|
12
16
|
const BUILTIN_CMDS = ["help", "exit", "quit", "clear", "status"];
|
|
13
17
|
|
|
14
18
|
interface AppProps {
|
|
@@ -19,23 +23,10 @@ interface AppProps {
|
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
/**
|
|
22
|
-
* Root TUI component —
|
|
23
|
-
*
|
|
24
|
-
* ┌─────────────────────────────────────────────┐
|
|
25
|
-
* │ ASCII banner + status info │ ← FIXED header
|
|
26
|
-
* ├─────────────────────────────────────────────┤
|
|
27
|
-
* │ scrollable output │ ← VIEWPORT
|
|
28
|
-
* ├─────────────────────────────────────────────┤
|
|
29
|
-
* │ ◈ arc402 > _ │ ← FIXED footer
|
|
30
|
-
* └─────────────────────────────────────────────┘
|
|
26
|
+
* Root TUI component — fixed header/footer with scrollable viewport.
|
|
31
27
|
*/
|
|
32
28
|
export function App({ version, network, wallet, balance }: AppProps) {
|
|
33
29
|
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
|
-
|
|
39
30
|
const [outputBuffer, setOutputBuffer] = useState<string[]>([
|
|
40
31
|
chalk.dim(" Type 'help' to see available commands"),
|
|
41
32
|
"",
|
|
@@ -46,8 +37,8 @@ export function App({ version, network, wallet, balance }: AppProps) {
|
|
|
46
37
|
const { send, isSending } = useChat();
|
|
47
38
|
|
|
48
39
|
// Approximate viewport height for scroll management
|
|
49
|
-
const HEADER_ROWS =
|
|
50
|
-
const FOOTER_ROWS =
|
|
40
|
+
const HEADER_ROWS = 15;
|
|
41
|
+
const FOOTER_ROWS = 1;
|
|
51
42
|
const rows = process.stdout.rows ?? 24;
|
|
52
43
|
const viewportHeight = Math.max(1, rows - HEADER_ROWS - FOOTER_ROWS);
|
|
53
44
|
|
|
@@ -192,49 +183,37 @@ export function App({ version, network, wallet, balance }: AppProps) {
|
|
|
192
183
|
|
|
193
184
|
const isDisabled = isProcessing || isRunning || isSending;
|
|
194
185
|
|
|
195
|
-
const topBorder = "┌" + "─".repeat(inner) + "┐";
|
|
196
|
-
const midBorder = "├" + "─".repeat(inner) + "┤";
|
|
197
|
-
const botBorder = "└" + "─".repeat(inner) + "┘";
|
|
198
|
-
|
|
199
186
|
return (
|
|
200
187
|
<Box flexDirection="column" height="100%">
|
|
201
|
-
{/* Top border */}
|
|
202
|
-
<Text dimColor>{topBorder}</Text>
|
|
203
|
-
|
|
204
188
|
{/* HEADER — fixed, never scrolls */}
|
|
205
189
|
<Header
|
|
206
190
|
version={version}
|
|
207
191
|
network={network}
|
|
208
192
|
wallet={wallet}
|
|
209
193
|
balance={balance}
|
|
210
|
-
innerWidth={inner}
|
|
211
194
|
/>
|
|
212
195
|
|
|
213
|
-
{/*
|
|
214
|
-
<
|
|
196
|
+
{/* Separator */}
|
|
197
|
+
<Box>
|
|
198
|
+
<Text dimColor>{"─".repeat(60)}</Text>
|
|
199
|
+
</Box>
|
|
215
200
|
|
|
216
201
|
{/* VIEWPORT — fills remaining space */}
|
|
217
202
|
<Viewport
|
|
218
203
|
lines={outputBuffer}
|
|
219
204
|
scrollOffset={scrollOffset}
|
|
220
205
|
isAutoScroll={isAutoScroll}
|
|
221
|
-
innerWidth={inner}
|
|
222
206
|
/>
|
|
223
207
|
|
|
224
|
-
{/*
|
|
225
|
-
<Text dimColor>{midBorder}</Text>
|
|
226
|
-
|
|
227
|
-
{/* FOOTER — input pinned */}
|
|
208
|
+
{/* Bottom separator */}
|
|
228
209
|
<Box>
|
|
229
|
-
<Text dimColor
|
|
230
|
-
<Box flexGrow={1}>
|
|
231
|
-
<InputLine onSubmit={handleCommand} isDisabled={isDisabled} />
|
|
232
|
-
</Box>
|
|
233
|
-
<Text dimColor>│</Text>
|
|
210
|
+
<Text dimColor>{"─".repeat(60)}</Text>
|
|
234
211
|
</Box>
|
|
235
212
|
|
|
236
|
-
{/*
|
|
237
|
-
<
|
|
213
|
+
{/* FOOTER — fixed, input pinned */}
|
|
214
|
+
<Footer>
|
|
215
|
+
<InputLine onSubmit={handleCommand} isDisabled={isDisabled} />
|
|
216
|
+
</Footer>
|
|
238
217
|
</Box>
|
|
239
218
|
);
|
|
240
219
|
}
|
package/src/tui/Header.tsx
CHANGED
|
@@ -1,36 +1,29 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
|
-
import { getBannerLines } from "../ui/banner";
|
|
3
|
+
import { getBannerLines } from "../ui/banner.js";
|
|
4
4
|
|
|
5
5
|
interface HeaderProps {
|
|
6
6
|
version: string;
|
|
7
7
|
network?: string;
|
|
8
8
|
wallet?: string;
|
|
9
9
|
balance?: string;
|
|
10
|
-
innerWidth?: number;
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* Fixed header showing the ASCII art banner + status info.
|
|
15
|
-
*
|
|
14
|
+
* Never re-renders unless config changes.
|
|
16
15
|
*/
|
|
17
16
|
export const Header = React.memo(function Header({
|
|
18
17
|
network,
|
|
19
18
|
wallet,
|
|
20
19
|
balance,
|
|
21
|
-
innerWidth = 58,
|
|
22
20
|
}: HeaderProps) {
|
|
23
21
|
const bannerLines = getBannerLines({ network, wallet, balance });
|
|
24
22
|
|
|
25
23
|
return (
|
|
26
24
|
<Box flexDirection="column">
|
|
27
25
|
{bannerLines.map((line, i) => (
|
|
28
|
-
<
|
|
29
|
-
<Text dimColor>│</Text>
|
|
30
|
-
<Text>{" " + line}</Text>
|
|
31
|
-
<Box flexGrow={1} />
|
|
32
|
-
<Text dimColor>│</Text>
|
|
33
|
-
</Box>
|
|
26
|
+
<Text key={i}>{line}</Text>
|
|
34
27
|
))}
|
|
35
28
|
</Box>
|
|
36
29
|
);
|
package/src/tui/InputLine.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useState, useCallback } from "react";
|
|
2
2
|
import { Box, Text, useInput } from "ink";
|
|
3
3
|
import TextInput from "ink-text-input";
|
|
4
|
-
import { createProgram } from "../program";
|
|
4
|
+
import { createProgram } from "../program.js";
|
|
5
5
|
|
|
6
6
|
const BUILTIN_CMDS = ["help", "exit", "quit", "clear", "status"];
|
|
7
7
|
|
package/src/tui/Viewport.tsx
CHANGED
|
@@ -5,30 +5,39 @@ interface ViewportProps {
|
|
|
5
5
|
lines: string[];
|
|
6
6
|
scrollOffset: number;
|
|
7
7
|
isAutoScroll: boolean;
|
|
8
|
-
innerWidth?: number;
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
|
-
* Scrollable output area
|
|
13
|
-
*
|
|
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.
|
|
14
15
|
*/
|
|
15
|
-
export function Viewport({ lines, scrollOffset, isAutoScroll
|
|
16
|
+
export function Viewport({ lines, scrollOffset, isAutoScroll }: ViewportProps) {
|
|
16
17
|
const { stdout } = useStdout();
|
|
17
18
|
const termRows = stdout?.rows ?? 24;
|
|
18
19
|
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
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);
|
|
22
27
|
|
|
23
28
|
// Compute the window slice
|
|
29
|
+
// scrollOffset=0 → show last viewportHeight lines
|
|
30
|
+
// scrollOffset=N → show lines ending viewportHeight+N from end
|
|
24
31
|
const totalLines = lines.length;
|
|
25
32
|
let endIdx: number;
|
|
26
33
|
let startIdx: number;
|
|
27
34
|
|
|
28
35
|
if (scrollOffset === 0) {
|
|
36
|
+
// Auto-scroll: pinned to bottom
|
|
29
37
|
endIdx = totalLines;
|
|
30
38
|
startIdx = Math.max(0, endIdx - viewportHeight);
|
|
31
39
|
} else {
|
|
40
|
+
// Scrolled up: scrollOffset lines from bottom
|
|
32
41
|
endIdx = Math.max(0, totalLines - scrollOffset);
|
|
33
42
|
startIdx = Math.max(0, endIdx - viewportHeight);
|
|
34
43
|
}
|
|
@@ -46,19 +55,14 @@ export function Viewport({ lines, scrollOffset, isAutoScroll, innerWidth = 58 }:
|
|
|
46
55
|
|
|
47
56
|
return (
|
|
48
57
|
<Box flexDirection="column" flexGrow={1}>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<Text
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<Text dimColor>│</Text>
|
|
55
|
-
</Box>
|
|
56
|
-
))}
|
|
58
|
+
<Box flexDirection="column" flexGrow={1}>
|
|
59
|
+
{paddedLines.map((line, i) => (
|
|
60
|
+
<Text key={i}>{line}</Text>
|
|
61
|
+
))}
|
|
62
|
+
</Box>
|
|
57
63
|
{canScrollDown && !isAutoScroll && (
|
|
58
64
|
<Box justifyContent="flex-end">
|
|
59
|
-
<Text dimColor
|
|
60
|
-
<Box flexGrow={1} />
|
|
61
|
-
<Text dimColor>│</Text>
|
|
65
|
+
<Text dimColor>↓ more</Text>
|
|
62
66
|
</Box>
|
|
63
67
|
)}
|
|
64
68
|
</Box>
|