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
|
@@ -1,55 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.registerWorkroomCommands = registerWorkroomCommands;
|
|
37
|
-
const fs = __importStar(require("fs"));
|
|
38
|
-
const path = __importStar(require("path"));
|
|
39
|
-
const http = __importStar(require("http"));
|
|
40
|
-
const child_process_1 = require("child_process");
|
|
41
|
-
const openshell_runtime_1 = require("../openshell-runtime");
|
|
42
|
-
const config_1 = require("../daemon/config");
|
|
43
|
-
const colors_1 = require("../ui/colors");
|
|
44
|
-
const tree_1 = require("../ui/tree");
|
|
1
|
+
import * as crypto from "node:crypto";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import * as http from "http";
|
|
5
|
+
import { spawnSync } from "child_process";
|
|
6
|
+
import { ARC402_DIR, runCmd, } from "../openshell-runtime.js";
|
|
7
|
+
import { DAEMON_TOML, loadDaemonConfig } from "../daemon/config.js";
|
|
8
|
+
import { c } from "../ui/colors.js";
|
|
9
|
+
import { renderTree } from "../ui/tree.js";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = path.dirname(__filename);
|
|
45
13
|
// ─── Daemon lifecycle notify ──────────────────────────────────────────────────
|
|
46
14
|
function notifyDaemonWorkroomStatus(event, agentAddress, jobId, port = 4402) {
|
|
47
15
|
try {
|
|
48
16
|
// Try to read port from daemon config
|
|
49
17
|
let daemonPort = port;
|
|
50
|
-
if (fs.existsSync(
|
|
18
|
+
if (fs.existsSync(DAEMON_TOML)) {
|
|
51
19
|
try {
|
|
52
|
-
const { loadDaemonConfig } = require("../daemon/config");
|
|
53
20
|
const cfg = loadDaemonConfig();
|
|
54
21
|
daemonPort = cfg.relay?.listen_port ?? port;
|
|
55
22
|
}
|
|
@@ -77,25 +44,25 @@ function notifyDaemonWorkroomStatus(event, agentAddress, jobId, port = 4402) {
|
|
|
77
44
|
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
78
45
|
const WORKROOM_IMAGE = "arc402-workroom";
|
|
79
46
|
const WORKROOM_CONTAINER = "arc402-workroom";
|
|
80
|
-
const POLICY_FILE = path.join(
|
|
81
|
-
const ARENA_POLICY_FILE = path.join(
|
|
82
|
-
const ARENA_DATA_DIR = path.join(
|
|
47
|
+
const POLICY_FILE = path.join(ARC402_DIR, "openshell-policy.yaml");
|
|
48
|
+
const ARENA_POLICY_FILE = path.join(ARC402_DIR, "arena-policy.yaml");
|
|
49
|
+
const ARENA_DATA_DIR = path.join(ARC402_DIR, "arena");
|
|
83
50
|
const WORKROOM_DIR = path.join(__dirname, "..", "..", "..", "workroom"); // relative to cli/dist
|
|
84
51
|
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
85
52
|
function dockerAvailable() {
|
|
86
|
-
const r =
|
|
53
|
+
const r = runCmd("docker", ["info", "--format", "{{.ServerVersion}}"]);
|
|
87
54
|
return r.ok;
|
|
88
55
|
}
|
|
89
56
|
function containerExists() {
|
|
90
|
-
const r =
|
|
57
|
+
const r = runCmd("docker", ["inspect", WORKROOM_CONTAINER, "--format", "{{.State.Status}}"]);
|
|
91
58
|
return r.ok;
|
|
92
59
|
}
|
|
93
60
|
function containerRunning() {
|
|
94
|
-
const r =
|
|
61
|
+
const r = runCmd("docker", ["inspect", WORKROOM_CONTAINER, "--format", "{{.State.Running}}"]);
|
|
95
62
|
return r.ok && r.stdout.trim() === "true";
|
|
96
63
|
}
|
|
97
64
|
function imageExists() {
|
|
98
|
-
const r =
|
|
65
|
+
const r = runCmd("docker", ["image", "inspect", WORKROOM_IMAGE, "--format", "{{.Id}}"]);
|
|
99
66
|
return r.ok;
|
|
100
67
|
}
|
|
101
68
|
function buildImage() {
|
|
@@ -106,7 +73,7 @@ function buildImage() {
|
|
|
106
73
|
return false;
|
|
107
74
|
}
|
|
108
75
|
console.log("Building ARC-402 Workroom image...");
|
|
109
|
-
const result =
|
|
76
|
+
const result = spawnSync("docker", ["build", "-t", WORKROOM_IMAGE, workroomSrc], {
|
|
110
77
|
stdio: "inherit",
|
|
111
78
|
});
|
|
112
79
|
return result.status === 0;
|
|
@@ -115,11 +82,11 @@ function getPolicyHash() {
|
|
|
115
82
|
if (!fs.existsSync(POLICY_FILE))
|
|
116
83
|
return "(no policy file)";
|
|
117
84
|
const content = fs.readFileSync(POLICY_FILE, "utf-8");
|
|
118
|
-
|
|
85
|
+
// crypto imported at top level
|
|
119
86
|
return "0x" + crypto.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
120
87
|
}
|
|
121
88
|
// ─── Commands ─────────────────────────────────────────────────────────────────
|
|
122
|
-
function registerWorkroomCommands(program) {
|
|
89
|
+
export function registerWorkroomCommands(program) {
|
|
123
90
|
const workroom = program
|
|
124
91
|
.command("workroom")
|
|
125
92
|
.description("ARC-402 Workroom — governed execution environment for hired work. Your OpenClaw stays on the host; work runs inside the workroom.");
|
|
@@ -128,75 +95,75 @@ function registerWorkroomCommands(program) {
|
|
|
128
95
|
.command("init")
|
|
129
96
|
.description("Create the ARC-402 Workroom: build Docker image, validate policy, prepare runtime bundle.")
|
|
130
97
|
.action(async () => {
|
|
131
|
-
console.log(
|
|
132
|
-
console.log(
|
|
98
|
+
console.log(c.brightCyan("ARC-402 Workroom Init"));
|
|
99
|
+
console.log(c.dim("─────────────────────"));
|
|
133
100
|
// Check Docker
|
|
134
101
|
if (!dockerAvailable()) {
|
|
135
|
-
console.error(
|
|
102
|
+
console.error(c.failure + " " + c.red("Docker is not available. Install Docker Desktop and try again."));
|
|
136
103
|
process.exit(1);
|
|
137
104
|
}
|
|
138
|
-
console.log(" " +
|
|
105
|
+
console.log(" " + c.success + c.white(" Docker available"));
|
|
139
106
|
// Check policy file
|
|
140
107
|
if (!fs.existsSync(POLICY_FILE)) {
|
|
141
|
-
console.log(
|
|
108
|
+
console.log(c.dim("No policy file found. Generating default..."));
|
|
142
109
|
// Import and call the existing policy generator
|
|
143
|
-
const { registerOpenShellCommands } =
|
|
144
|
-
console.log(
|
|
145
|
-
console.log(
|
|
110
|
+
const { registerOpenShellCommands } = await import("./openshell.js");
|
|
111
|
+
console.log(c.dim(`Policy file will be generated at: ${POLICY_FILE}`));
|
|
112
|
+
console.log(c.dim("Run 'arc402 workroom policy preset core-launch' after init to apply defaults."));
|
|
146
113
|
}
|
|
147
114
|
else {
|
|
148
|
-
console.log(" " +
|
|
115
|
+
console.log(" " + c.success + c.dim(" Policy file: ") + c.white(POLICY_FILE));
|
|
149
116
|
}
|
|
150
117
|
// Check daemon.toml
|
|
151
|
-
if (!fs.existsSync(
|
|
152
|
-
console.error(
|
|
118
|
+
if (!fs.existsSync(DAEMON_TOML)) {
|
|
119
|
+
console.error(c.failure + " " + c.red("daemon.toml not found. Run 'arc402 daemon init' first."));
|
|
153
120
|
process.exit(1);
|
|
154
121
|
}
|
|
155
|
-
console.log(" " +
|
|
122
|
+
console.log(" " + c.success + c.white(" daemon.toml found"));
|
|
156
123
|
// Set up Arena directories and default policy
|
|
157
124
|
if (!fs.existsSync(ARENA_DATA_DIR)) {
|
|
158
125
|
fs.mkdirSync(ARENA_DATA_DIR, { recursive: true });
|
|
159
126
|
for (const sub of ["feed", "profile", "state", "queue"]) {
|
|
160
127
|
fs.mkdirSync(path.join(ARENA_DATA_DIR, sub), { recursive: true });
|
|
161
128
|
}
|
|
162
|
-
console.log(" " +
|
|
129
|
+
console.log(" " + c.success + c.white(" Arena directories created"));
|
|
163
130
|
}
|
|
164
131
|
else {
|
|
165
|
-
console.log(" " +
|
|
132
|
+
console.log(" " + c.success + c.white(" Arena directories exist"));
|
|
166
133
|
}
|
|
167
134
|
// Copy default arena policy if not present
|
|
168
135
|
if (!fs.existsSync(ARENA_POLICY_FILE)) {
|
|
169
136
|
const defaultArenaPolicy = path.join(WORKROOM_DIR, "arena-policy.yaml");
|
|
170
137
|
if (fs.existsSync(defaultArenaPolicy)) {
|
|
171
138
|
fs.copyFileSync(defaultArenaPolicy, ARENA_POLICY_FILE);
|
|
172
|
-
console.log(" " +
|
|
139
|
+
console.log(" " + c.success + c.white(" Arena policy: default installed"));
|
|
173
140
|
}
|
|
174
141
|
else {
|
|
175
|
-
console.log(" " +
|
|
142
|
+
console.log(" " + c.warning + " " + c.yellow("Arena policy template not found — create manually at " + ARENA_POLICY_FILE));
|
|
176
143
|
}
|
|
177
144
|
}
|
|
178
145
|
else {
|
|
179
|
-
console.log(" " +
|
|
146
|
+
console.log(" " + c.success + c.white(" Arena policy exists"));
|
|
180
147
|
}
|
|
181
148
|
// Build image
|
|
182
149
|
if (!imageExists()) {
|
|
183
150
|
if (!buildImage()) {
|
|
184
|
-
console.error(
|
|
151
|
+
console.error(c.failure + " " + c.red("Failed to build workroom image."));
|
|
185
152
|
process.exit(1);
|
|
186
153
|
}
|
|
187
154
|
}
|
|
188
|
-
console.log(" " +
|
|
155
|
+
console.log(" " + c.success + c.dim(" Image: ") + c.white(WORKROOM_IMAGE));
|
|
189
156
|
// Package CLI runtime for the workroom
|
|
190
157
|
const cliDist = path.resolve(__dirname, "..", "..");
|
|
191
158
|
const cliPackage = path.resolve(__dirname, "..", "..", "..", "package.json");
|
|
192
159
|
if (fs.existsSync(cliDist) && fs.existsSync(cliPackage)) {
|
|
193
|
-
console.log(" " +
|
|
160
|
+
console.log(" " + c.success + c.white(" CLI runtime available for workroom mount"));
|
|
194
161
|
}
|
|
195
162
|
else {
|
|
196
|
-
console.warn(" " +
|
|
163
|
+
console.warn(" " + c.warning + " " + c.yellow("CLI dist not found — workroom will need runtime bundle"));
|
|
197
164
|
}
|
|
198
|
-
console.log("\n" +
|
|
199
|
-
console.log(
|
|
165
|
+
console.log("\n" + c.success + c.white(" Workroom initialized. Start with: arc402 workroom start"));
|
|
166
|
+
console.log(c.dim("Policy hash: ") + c.white(getPolicyHash()));
|
|
200
167
|
});
|
|
201
168
|
// ── start ─────────────────────────────────────────────────────────────────
|
|
202
169
|
workroom
|
|
@@ -213,7 +180,7 @@ function registerWorkroomCommands(program) {
|
|
|
213
180
|
}
|
|
214
181
|
// Remove stopped container if exists
|
|
215
182
|
if (containerExists()) {
|
|
216
|
-
|
|
183
|
+
runCmd("docker", ["rm", "-f", WORKROOM_CONTAINER]);
|
|
217
184
|
}
|
|
218
185
|
// Build image if needed
|
|
219
186
|
if (!imageExists()) {
|
|
@@ -233,20 +200,20 @@ function registerWorkroomCommands(program) {
|
|
|
233
200
|
}
|
|
234
201
|
// CLI runtime path
|
|
235
202
|
const cliRoot = path.resolve(__dirname, "..", "..", "..");
|
|
236
|
-
console.log(
|
|
203
|
+
console.log(c.dim("Starting ARC-402 Workroom..."));
|
|
237
204
|
const args = [
|
|
238
205
|
"run", "-d",
|
|
239
206
|
"--name", WORKROOM_CONTAINER,
|
|
240
207
|
"--restart", "unless-stopped",
|
|
241
208
|
"--cap-add", "NET_ADMIN", // Required for iptables
|
|
242
209
|
// Mount config (read-write for daemon state/logs)
|
|
243
|
-
"-v", `${
|
|
210
|
+
"-v", `${ARC402_DIR}:/workroom/.arc402:rw`,
|
|
244
211
|
// Mount CLI runtime (read-only)
|
|
245
212
|
"-v", `${cliRoot}:/workroom/runtime:ro`,
|
|
246
213
|
// Mount jobs directory
|
|
247
|
-
"-v", `${path.join(
|
|
214
|
+
"-v", `${path.join(ARC402_DIR, "jobs")}:/workroom/jobs:rw`,
|
|
248
215
|
// Mount worker directory (identity, memory, skills, knowledge)
|
|
249
|
-
"-v", `${path.join(
|
|
216
|
+
"-v", `${path.join(ARC402_DIR, "worker")}:/workroom/worker:rw`,
|
|
250
217
|
// Mount Arena data directory (feed index, profile cache, state, queue)
|
|
251
218
|
"-v", `${ARENA_DATA_DIR}:/workroom/arena:rw`,
|
|
252
219
|
// Inject secrets as env vars
|
|
@@ -259,16 +226,16 @@ function registerWorkroomCommands(program) {
|
|
|
259
226
|
"-p", "4402:4402",
|
|
260
227
|
WORKROOM_IMAGE,
|
|
261
228
|
];
|
|
262
|
-
const result =
|
|
229
|
+
const result = spawnSync("docker", args, { stdio: "inherit" });
|
|
263
230
|
if (result.status !== 0) {
|
|
264
231
|
console.error("Failed to start workroom container.");
|
|
265
232
|
process.exit(1);
|
|
266
233
|
}
|
|
267
234
|
// Wait briefly and check health
|
|
268
|
-
|
|
235
|
+
spawnSync("sleep", ["2"]);
|
|
269
236
|
if (containerRunning()) {
|
|
270
|
-
console.log("\n" +
|
|
271
|
-
|
|
237
|
+
console.log("\n" + c.success + c.white(" ARC-402 Workroom is running"));
|
|
238
|
+
renderTree([
|
|
272
239
|
{ label: "Container", value: WORKROOM_CONTAINER },
|
|
273
240
|
{ label: "Policy hash", value: getPolicyHash() },
|
|
274
241
|
{ label: "Relay port", value: "4402" },
|
|
@@ -278,8 +245,8 @@ function registerWorkroomCommands(program) {
|
|
|
278
245
|
notifyDaemonWorkroomStatus("entered");
|
|
279
246
|
}
|
|
280
247
|
else {
|
|
281
|
-
console.error(
|
|
282
|
-
console.error(
|
|
248
|
+
console.error(c.failure + " " + c.red("Workroom started but exited immediately. Check logs:"));
|
|
249
|
+
console.error(c.dim(" docker logs arc402-workroom"));
|
|
283
250
|
process.exit(1);
|
|
284
251
|
}
|
|
285
252
|
});
|
|
@@ -292,85 +259,85 @@ function registerWorkroomCommands(program) {
|
|
|
292
259
|
console.log("Workroom is not running.");
|
|
293
260
|
return;
|
|
294
261
|
}
|
|
295
|
-
console.log(
|
|
262
|
+
console.log(c.dim("Stopping ARC-402 Workroom..."));
|
|
296
263
|
// Notify daemon before stopping (daemon may be inside container)
|
|
297
264
|
notifyDaemonWorkroomStatus("exited");
|
|
298
|
-
|
|
299
|
-
console.log(" " +
|
|
265
|
+
runCmd("docker", ["stop", WORKROOM_CONTAINER]);
|
|
266
|
+
console.log(" " + c.success + c.white(" Workroom stopped"));
|
|
300
267
|
});
|
|
301
268
|
// ── status ────────────────────────────────────────────────────────────────
|
|
302
269
|
workroom
|
|
303
270
|
.command("status")
|
|
304
271
|
.description("Show ARC-402 Workroom health, policy, and active state.")
|
|
305
272
|
.action(async () => {
|
|
306
|
-
console.log(
|
|
307
|
-
console.log(
|
|
273
|
+
console.log(c.brightCyan("ARC-402 Workroom Status"));
|
|
274
|
+
console.log(c.dim("───────────────────────"));
|
|
308
275
|
// Docker
|
|
309
276
|
if (!dockerAvailable()) {
|
|
310
|
-
console.log(
|
|
277
|
+
console.log(c.dim("Docker: ") + c.failure + " " + c.red("not available"));
|
|
311
278
|
return;
|
|
312
279
|
}
|
|
313
|
-
console.log(
|
|
280
|
+
console.log(c.dim("Docker: ") + c.success + c.white(" available"));
|
|
314
281
|
// Image
|
|
315
282
|
if (imageExists()) {
|
|
316
|
-
console.log(
|
|
283
|
+
console.log(c.dim("Image: ") + c.success + " " + c.white(WORKROOM_IMAGE));
|
|
317
284
|
}
|
|
318
285
|
else {
|
|
319
|
-
console.log(
|
|
286
|
+
console.log(c.dim("Image: ") + c.failure + " " + c.red("not built (run: arc402 workroom init)"));
|
|
320
287
|
}
|
|
321
288
|
// Container
|
|
322
289
|
if (containerRunning()) {
|
|
323
|
-
console.log(
|
|
290
|
+
console.log(c.dim("Container: ") + c.success + c.white(` running (${WORKROOM_CONTAINER})`));
|
|
324
291
|
// Get container uptime
|
|
325
|
-
const inspect =
|
|
292
|
+
const inspect = runCmd("docker", ["inspect", WORKROOM_CONTAINER, "--format", "{{.State.StartedAt}}"]);
|
|
326
293
|
if (inspect.ok) {
|
|
327
294
|
const started = new Date(inspect.stdout.trim());
|
|
328
295
|
const uptime = Math.floor((Date.now() - started.getTime()) / 1000);
|
|
329
296
|
const h = Math.floor(uptime / 3600);
|
|
330
297
|
const m = Math.floor((uptime % 3600) / 60);
|
|
331
|
-
console.log(
|
|
298
|
+
console.log(c.dim("Uptime: ") + c.white(`${h}h ${m}m`));
|
|
332
299
|
}
|
|
333
300
|
// Get iptables rule count from inside container
|
|
334
|
-
const rules =
|
|
301
|
+
const rules = runCmd("docker", ["exec", WORKROOM_CONTAINER, "iptables", "-L", "OUTPUT", "-n", "--line-numbers"]);
|
|
335
302
|
if (rules.ok) {
|
|
336
303
|
const ruleCount = rules.stdout.split("\n").filter(l => l.match(/^\d+/)).length;
|
|
337
|
-
console.log(
|
|
304
|
+
console.log(c.dim("Network rules: ") + c.white(`${ruleCount} iptables rules enforced`));
|
|
338
305
|
}
|
|
339
306
|
}
|
|
340
307
|
else if (containerExists()) {
|
|
341
|
-
console.log(
|
|
308
|
+
console.log(c.dim("Container: ") + c.warning + " " + c.yellow("stopped (run: arc402 workroom start)"));
|
|
342
309
|
}
|
|
343
310
|
else {
|
|
344
|
-
console.log(
|
|
311
|
+
console.log(c.dim("Container: ") + c.failure + " " + c.red("not created (run: arc402 workroom init)"));
|
|
345
312
|
}
|
|
346
313
|
// Policy
|
|
347
314
|
if (fs.existsSync(POLICY_FILE)) {
|
|
348
|
-
console.log(
|
|
315
|
+
console.log(c.dim("Policy file: ") + c.success + " " + c.white(POLICY_FILE));
|
|
349
316
|
}
|
|
350
317
|
else {
|
|
351
|
-
console.log(
|
|
318
|
+
console.log(c.dim("Policy file: ") + c.failure + " " + c.red("missing"));
|
|
352
319
|
}
|
|
353
|
-
console.log(
|
|
320
|
+
console.log(c.dim("Policy hash: ") + c.white(getPolicyHash()));
|
|
354
321
|
// Arena
|
|
355
322
|
const arenaExists = fs.existsSync(ARENA_DATA_DIR);
|
|
356
323
|
const arenaPolicy = fs.existsSync(ARENA_POLICY_FILE);
|
|
357
324
|
if (arenaExists) {
|
|
358
|
-
console.log(
|
|
325
|
+
console.log(c.dim("Arena data: ") + c.success + " " + c.white(ARENA_DATA_DIR));
|
|
359
326
|
}
|
|
360
327
|
else {
|
|
361
|
-
console.log(
|
|
328
|
+
console.log(c.dim("Arena data: ") + c.failure + " " + c.red("missing (run: arc402 workroom init)"));
|
|
362
329
|
}
|
|
363
|
-
console.log(
|
|
330
|
+
console.log(c.dim("Arena policy: ") + (arenaPolicy ? c.success + c.white(" loaded") : c.failure + " " + c.red("missing")));
|
|
364
331
|
// Arena queue (pending approvals)
|
|
365
332
|
if (arenaExists) {
|
|
366
333
|
const queueDir = path.join(ARENA_DATA_DIR, "queue");
|
|
367
334
|
if (fs.existsSync(queueDir)) {
|
|
368
335
|
const pending = fs.readdirSync(queueDir).filter(f => f.endsWith(".json")).length;
|
|
369
336
|
if (pending > 0) {
|
|
370
|
-
console.log(
|
|
337
|
+
console.log(c.dim("Arena queue: ") + c.warning + " " + c.yellow(`${pending} action(s) awaiting approval`));
|
|
371
338
|
}
|
|
372
339
|
else {
|
|
373
|
-
console.log(
|
|
340
|
+
console.log(c.dim("Arena queue: ") + c.success + c.white(" empty"));
|
|
374
341
|
}
|
|
375
342
|
}
|
|
376
343
|
}
|
|
@@ -387,7 +354,7 @@ function registerWorkroomCommands(program) {
|
|
|
387
354
|
args.push("-f");
|
|
388
355
|
args.push("--tail", opts.lines);
|
|
389
356
|
args.push(WORKROOM_CONTAINER);
|
|
390
|
-
|
|
357
|
+
spawnSync("docker", args, { stdio: "inherit" });
|
|
391
358
|
});
|
|
392
359
|
// ── shell ─────────────────────────────────────────────────────────────────
|
|
393
360
|
workroom
|
|
@@ -398,7 +365,7 @@ function registerWorkroomCommands(program) {
|
|
|
398
365
|
console.error("Workroom is not running.");
|
|
399
366
|
process.exit(1);
|
|
400
367
|
}
|
|
401
|
-
|
|
368
|
+
spawnSync("docker", ["exec", "-it", WORKROOM_CONTAINER, "/bin/bash"], {
|
|
402
369
|
stdio: "inherit",
|
|
403
370
|
});
|
|
404
371
|
});
|
|
@@ -407,8 +374,8 @@ function registerWorkroomCommands(program) {
|
|
|
407
374
|
.command("doctor")
|
|
408
375
|
.description("Diagnose workroom health: Docker, image, container, network, policy, daemon.")
|
|
409
376
|
.action(async () => {
|
|
410
|
-
console.log(
|
|
411
|
-
console.log(
|
|
377
|
+
console.log(c.brightCyan("ARC-402 Workroom Doctor"));
|
|
378
|
+
console.log(c.dim("───────────────────────"));
|
|
412
379
|
const checks = [];
|
|
413
380
|
// Docker
|
|
414
381
|
const docker = dockerAvailable();
|
|
@@ -423,32 +390,32 @@ function registerWorkroomCommands(program) {
|
|
|
423
390
|
const policyExists = fs.existsSync(POLICY_FILE);
|
|
424
391
|
checks.push({ label: "Policy file", pass: policyExists, detail: policyExists ? POLICY_FILE : "missing" });
|
|
425
392
|
// daemon.toml
|
|
426
|
-
const daemonCfg = fs.existsSync(
|
|
393
|
+
const daemonCfg = fs.existsSync(DAEMON_TOML);
|
|
427
394
|
checks.push({ label: "daemon.toml", pass: daemonCfg, detail: daemonCfg ? "found" : "missing — run: arc402 daemon init" });
|
|
428
395
|
// Machine key env
|
|
429
396
|
const mk = !!process.env.ARC402_MACHINE_KEY;
|
|
430
397
|
checks.push({ label: "Machine key env", pass: mk, detail: mk ? "set" : "ARC402_MACHINE_KEY not in environment" });
|
|
431
398
|
// Network connectivity (if running)
|
|
432
399
|
if (running) {
|
|
433
|
-
const rpcTest =
|
|
400
|
+
const rpcTest = runCmd("docker", ["exec", WORKROOM_CONTAINER, "curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", "--max-time", "5", "https://mainnet.base.org"]);
|
|
434
401
|
const rpcOk = rpcTest.ok && rpcTest.stdout.trim() !== "000";
|
|
435
402
|
checks.push({ label: "Base RPC from workroom", pass: rpcOk, detail: rpcOk ? `HTTP ${rpcTest.stdout.trim()}` : "FAILED — network policy may be blocking RPC" });
|
|
436
403
|
}
|
|
437
404
|
// Print results
|
|
438
405
|
for (const chk of checks) {
|
|
439
406
|
if (chk.pass) {
|
|
440
|
-
console.log(" " +
|
|
407
|
+
console.log(" " + c.success + " " + c.dim(chk.label + ":") + " " + c.white(chk.detail));
|
|
441
408
|
}
|
|
442
409
|
else {
|
|
443
|
-
console.log(" " +
|
|
410
|
+
console.log(" " + c.failure + " " + c.dim(chk.label + ":") + " " + c.red(chk.detail) + c.yellow(" ← FIX"));
|
|
444
411
|
}
|
|
445
412
|
}
|
|
446
413
|
const failures = checks.filter(chk => !chk.pass);
|
|
447
414
|
if (failures.length === 0) {
|
|
448
|
-
console.log("\n" +
|
|
415
|
+
console.log("\n" + c.success + c.white(" All checks passed. Workroom is healthy."));
|
|
449
416
|
}
|
|
450
417
|
else {
|
|
451
|
-
console.log("\n" +
|
|
418
|
+
console.log("\n" + c.failure + " " + c.red(`${failures.length} issue(s) found.`));
|
|
452
419
|
}
|
|
453
420
|
});
|
|
454
421
|
// ── policy (delegate to existing openshell policy commands) ───────────────
|
|
@@ -481,19 +448,19 @@ function registerWorkroomCommands(program) {
|
|
|
481
448
|
console.error("Workroom is not running. Start it first: arc402 workroom start");
|
|
482
449
|
process.exit(1);
|
|
483
450
|
}
|
|
484
|
-
console.log(
|
|
485
|
-
const result =
|
|
451
|
+
console.log(c.dim(`Testing connectivity to ${host} from inside workroom...`));
|
|
452
|
+
const result = runCmd("docker", [
|
|
486
453
|
"exec", WORKROOM_CONTAINER,
|
|
487
454
|
"curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", "--max-time", "5",
|
|
488
455
|
`https://${host}`,
|
|
489
456
|
]);
|
|
490
457
|
if (result.ok && result.stdout.trim() !== "000") {
|
|
491
|
-
console.log(" " +
|
|
458
|
+
console.log(" " + c.success + " " + c.white(host) + c.dim(` is reachable (HTTP ${result.stdout.trim()})`));
|
|
492
459
|
}
|
|
493
460
|
else {
|
|
494
|
-
console.log(" " +
|
|
495
|
-
console.log(
|
|
496
|
-
console.log(
|
|
461
|
+
console.log(" " + c.failure + " " + c.red(`${host} is NOT reachable from the workroom`));
|
|
462
|
+
console.log(c.dim(" This host may not be in the workroom policy."));
|
|
463
|
+
console.log(c.dim(" Add it with: arc402 openshell policy add <name> <host>"));
|
|
497
464
|
}
|
|
498
465
|
});
|
|
499
466
|
// ── worker ─────────────────────────────────────────────────────────────────
|
|
@@ -504,7 +471,7 @@ function registerWorkroomCommands(program) {
|
|
|
504
471
|
.option("--name <name>", "Worker display name", "Worker")
|
|
505
472
|
.option("--model <model>", "Preferred LLM model for task execution")
|
|
506
473
|
.action(async (opts) => {
|
|
507
|
-
const workerDir = path.join(
|
|
474
|
+
const workerDir = path.join(ARC402_DIR, "worker");
|
|
508
475
|
const memoryDir = path.join(workerDir, "memory");
|
|
509
476
|
const skillsDir = path.join(workerDir, "skills");
|
|
510
477
|
fs.mkdirSync(memoryDir, { recursive: true });
|
|
@@ -549,10 +516,10 @@ Write these learnings concisely. They will be available on your next job.
|
|
|
549
516
|
- If the task is unclear, produce the best interpretation and document assumptions
|
|
550
517
|
- Every deliverable must be verifiable against the task spec
|
|
551
518
|
`);
|
|
552
|
-
console.log(" " +
|
|
519
|
+
console.log(" " + c.success + c.dim(` Worker SOUL.md created: ${soulPath}`));
|
|
553
520
|
}
|
|
554
521
|
else {
|
|
555
|
-
console.log(" " +
|
|
522
|
+
console.log(" " + c.success + c.dim(` Worker SOUL.md already exists: ${soulPath}`));
|
|
556
523
|
}
|
|
557
524
|
// Generate default MEMORY.md
|
|
558
525
|
const memoryPath = path.join(workerDir, "MEMORY.md");
|
|
@@ -568,7 +535,7 @@ Write these learnings concisely. They will be available on your next job.
|
|
|
568
535
|
|
|
569
536
|
No jobs completed yet. Learnings will accumulate here as the worker completes hired tasks.
|
|
570
537
|
`);
|
|
571
|
-
console.log(" " +
|
|
538
|
+
console.log(" " + c.success + c.dim(` Worker MEMORY.md created: ${memoryPath}`));
|
|
572
539
|
}
|
|
573
540
|
// Generate learnings.md
|
|
574
541
|
const learningsPath = path.join(memoryDir, "learnings.md");
|
|
@@ -581,7 +548,7 @@ No jobs completed yet. Learnings will accumulate here as the worker completes hi
|
|
|
581
548
|
|
|
582
549
|
No learnings yet. Complete your first hired task to start accumulating expertise.
|
|
583
550
|
`);
|
|
584
|
-
console.log(" " +
|
|
551
|
+
console.log(" " + c.success + c.dim(` Learnings file created: ${learningsPath}`));
|
|
585
552
|
}
|
|
586
553
|
// Worker config
|
|
587
554
|
const configPath = path.join(workerDir, "config.json");
|
|
@@ -595,18 +562,18 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
595
562
|
total_earned_eth: "0",
|
|
596
563
|
};
|
|
597
564
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
598
|
-
console.log(" " +
|
|
565
|
+
console.log(" " + c.success + c.dim(` Worker config created: ${configPath}`));
|
|
599
566
|
}
|
|
600
|
-
console.log("\n" +
|
|
601
|
-
console.log(
|
|
602
|
-
console.log(
|
|
603
|
-
console.log(
|
|
567
|
+
console.log("\n" + c.success + c.white(` Worker initialized at: ${workerDir}`));
|
|
568
|
+
console.log(c.dim("Next: customize the worker SOUL.md and add skills."));
|
|
569
|
+
console.log(c.dim(" arc402 workroom worker set-soul <file>"));
|
|
570
|
+
console.log(c.dim(" arc402 workroom worker set-skills <dir>"));
|
|
604
571
|
});
|
|
605
572
|
worker
|
|
606
573
|
.command("status")
|
|
607
574
|
.description("Show worker identity, job count, learnings, and configuration.")
|
|
608
575
|
.action(async () => {
|
|
609
|
-
const workerDir = path.join(
|
|
576
|
+
const workerDir = path.join(ARC402_DIR, "worker");
|
|
610
577
|
const configPath = path.join(workerDir, "config.json");
|
|
611
578
|
if (!fs.existsSync(configPath)) {
|
|
612
579
|
console.error("Worker not initialized. Run: arc402 workroom worker init");
|
|
@@ -625,9 +592,9 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
625
592
|
const skillCount = fs.existsSync(skillsDir)
|
|
626
593
|
? fs.readdirSync(skillsDir).length
|
|
627
594
|
: 0;
|
|
628
|
-
console.log(
|
|
629
|
-
console.log(
|
|
630
|
-
|
|
595
|
+
console.log(c.brightCyan("ARC-402 Workroom Worker"));
|
|
596
|
+
console.log(c.dim("───────────────────────"));
|
|
597
|
+
renderTree([
|
|
631
598
|
{ label: "Name", value: config.name },
|
|
632
599
|
{ label: "Model", value: config.model },
|
|
633
600
|
{ label: "Created", value: config.created },
|
|
@@ -646,10 +613,10 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
646
613
|
console.error(`File not found: ${file}`);
|
|
647
614
|
process.exit(1);
|
|
648
615
|
}
|
|
649
|
-
const dest = path.join(
|
|
616
|
+
const dest = path.join(ARC402_DIR, "worker", "SOUL.md");
|
|
650
617
|
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
651
618
|
fs.copyFileSync(file, dest);
|
|
652
|
-
console.log(" " +
|
|
619
|
+
console.log(" " + c.success + c.white(` Worker SOUL.md updated from: ${file}`));
|
|
653
620
|
});
|
|
654
621
|
worker
|
|
655
622
|
.command("set-skills <dir>")
|
|
@@ -659,7 +626,7 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
659
626
|
console.error(`Directory not found: ${dir}`);
|
|
660
627
|
process.exit(1);
|
|
661
628
|
}
|
|
662
|
-
const dest = path.join(
|
|
629
|
+
const dest = path.join(ARC402_DIR, "worker", "skills");
|
|
663
630
|
fs.mkdirSync(dest, { recursive: true });
|
|
664
631
|
// Copy all files from source to dest
|
|
665
632
|
const files = fs.readdirSync(dir);
|
|
@@ -674,7 +641,7 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
674
641
|
fs.cpSync(src, dst, { recursive: true });
|
|
675
642
|
}
|
|
676
643
|
}
|
|
677
|
-
console.log(" " +
|
|
644
|
+
console.log(" " + c.success + c.white(` ${files.length} items copied to worker skills`));
|
|
678
645
|
});
|
|
679
646
|
worker
|
|
680
647
|
.command("set-knowledge <dir>")
|
|
@@ -684,7 +651,7 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
684
651
|
console.error(`Directory not found: ${dir}`);
|
|
685
652
|
process.exit(1);
|
|
686
653
|
}
|
|
687
|
-
const dest = path.join(
|
|
654
|
+
const dest = path.join(ARC402_DIR, "worker", "knowledge");
|
|
688
655
|
fs.mkdirSync(dest, { recursive: true });
|
|
689
656
|
const files = fs.readdirSync(dir);
|
|
690
657
|
let count = 0;
|
|
@@ -700,16 +667,16 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
700
667
|
count++;
|
|
701
668
|
}
|
|
702
669
|
}
|
|
703
|
-
console.log(" " +
|
|
704
|
-
console.log(" " +
|
|
705
|
-
console.log(
|
|
706
|
-
console.log(
|
|
670
|
+
console.log(" " + c.success + c.white(` ${count} items copied to worker knowledge`));
|
|
671
|
+
console.log(" " + c.dim("Path:") + " " + c.white(dest));
|
|
672
|
+
console.log(c.dim(" The worker can reference these files during hired tasks."));
|
|
673
|
+
console.log(c.dim(" To update: run this command again with the updated directory."));
|
|
707
674
|
});
|
|
708
675
|
worker
|
|
709
676
|
.command("knowledge")
|
|
710
677
|
.description("List the worker's knowledge directory contents.")
|
|
711
678
|
.action(async () => {
|
|
712
|
-
const knowledgeDir = path.join(
|
|
679
|
+
const knowledgeDir = path.join(ARC402_DIR, "worker", "knowledge");
|
|
713
680
|
if (!fs.existsSync(knowledgeDir)) {
|
|
714
681
|
console.log("No knowledge directory. Add one with: arc402 workroom worker set-knowledge <dir>");
|
|
715
682
|
return;
|
|
@@ -730,7 +697,7 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
730
697
|
.command("memory")
|
|
731
698
|
.description("Show the worker's accumulated learnings.")
|
|
732
699
|
.action(async () => {
|
|
733
|
-
const learningsPath = path.join(
|
|
700
|
+
const learningsPath = path.join(ARC402_DIR, "worker", "memory", "learnings.md");
|
|
734
701
|
if (!fs.existsSync(learningsPath)) {
|
|
735
702
|
console.log("No learnings yet. Complete a hired task first.");
|
|
736
703
|
return;
|
|
@@ -741,7 +708,7 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
741
708
|
.command("memory-reset")
|
|
742
709
|
.description("Clear the worker's accumulated memory (start fresh).")
|
|
743
710
|
.action(async () => {
|
|
744
|
-
const memoryDir = path.join(
|
|
711
|
+
const memoryDir = path.join(ARC402_DIR, "worker", "memory");
|
|
745
712
|
if (fs.existsSync(memoryDir)) {
|
|
746
713
|
const files = fs.readdirSync(memoryDir);
|
|
747
714
|
for (const f of files)
|
|
@@ -749,20 +716,20 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
749
716
|
fs.writeFileSync(path.join(memoryDir, "learnings.md"), `# Accumulated Learnings\n\n*Reset: ${new Date().toISOString()}*\n\nNo learnings yet.\n`);
|
|
750
717
|
}
|
|
751
718
|
// Reset job count in config
|
|
752
|
-
const configPath = path.join(
|
|
719
|
+
const configPath = path.join(ARC402_DIR, "worker", "config.json");
|
|
753
720
|
if (fs.existsSync(configPath)) {
|
|
754
721
|
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
755
722
|
config.job_count = 0;
|
|
756
723
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
757
724
|
}
|
|
758
|
-
console.log(" " +
|
|
725
|
+
console.log(" " + c.success + c.white(" Worker memory cleared. Starting fresh."));
|
|
759
726
|
});
|
|
760
727
|
// ── token usage ──────────────────────────────────────────────────────────
|
|
761
728
|
workroom
|
|
762
729
|
.command("token-usage [agreementId]")
|
|
763
730
|
.description("Show token usage for a specific agreement or across all jobs.")
|
|
764
731
|
.action(async (agreementId) => {
|
|
765
|
-
const { readUsageReport, formatUsageReport } =
|
|
732
|
+
const { readUsageReport, formatUsageReport } = await import("../daemon/token-metering.js");
|
|
766
733
|
if (agreementId) {
|
|
767
734
|
const usage = readUsageReport(agreementId);
|
|
768
735
|
if (!usage) {
|
|
@@ -773,7 +740,7 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
773
740
|
}
|
|
774
741
|
else {
|
|
775
742
|
// Aggregate across all receipts
|
|
776
|
-
const receiptsDir = path.join(
|
|
743
|
+
const receiptsDir = path.join(ARC402_DIR, "receipts");
|
|
777
744
|
if (!fs.existsSync(receiptsDir)) {
|
|
778
745
|
console.log("No receipts yet.");
|
|
779
746
|
return;
|
|
@@ -814,7 +781,7 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
814
781
|
.command("receipts")
|
|
815
782
|
.description("List all execution receipts from completed jobs.")
|
|
816
783
|
.action(async () => {
|
|
817
|
-
const receiptsDir = path.join(
|
|
784
|
+
const receiptsDir = path.join(ARC402_DIR, "receipts");
|
|
818
785
|
if (!fs.existsSync(receiptsDir)) {
|
|
819
786
|
console.log("No receipts yet.");
|
|
820
787
|
return;
|
|
@@ -842,7 +809,7 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
842
809
|
.command("receipt <agreementId>")
|
|
843
810
|
.description("Show full execution receipt for a specific job.")
|
|
844
811
|
.action(async (agreementId) => {
|
|
845
|
-
const receiptPath = path.join(
|
|
812
|
+
const receiptPath = path.join(ARC402_DIR, "receipts", `${agreementId}.json`);
|
|
846
813
|
if (!fs.existsSync(receiptPath)) {
|
|
847
814
|
console.error(`No receipt found for agreement: ${agreementId}`);
|
|
848
815
|
process.exit(1);
|
|
@@ -854,14 +821,14 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
854
821
|
.description("Show total earnings from completed jobs.")
|
|
855
822
|
.option("--period <period>", "Time period (e.g. 7d, 30d, all)", "all")
|
|
856
823
|
.action(async (opts) => {
|
|
857
|
-
const configPath = path.join(
|
|
824
|
+
const configPath = path.join(ARC402_DIR, "worker", "config.json");
|
|
858
825
|
if (!fs.existsSync(configPath)) {
|
|
859
826
|
console.log("No worker configured. Run: arc402 workroom worker init");
|
|
860
827
|
return;
|
|
861
828
|
}
|
|
862
829
|
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
863
|
-
console.log(
|
|
864
|
-
console.log(
|
|
830
|
+
console.log(c.brightCyan("ARC-402 Earnings"));
|
|
831
|
+
console.log(c.dim("────────────────"));
|
|
865
832
|
const earningsItems = [
|
|
866
833
|
{ label: "Total earned", value: config.total_earned_eth + " ETH" },
|
|
867
834
|
{ label: "Jobs completed", value: String(config.job_count) },
|
|
@@ -871,13 +838,13 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
871
838
|
earningsItems.push({ label: "Average/job", value: avg + " ETH" });
|
|
872
839
|
}
|
|
873
840
|
earningsItems[earningsItems.length - 1].last = true;
|
|
874
|
-
|
|
841
|
+
renderTree(earningsItems);
|
|
875
842
|
});
|
|
876
843
|
workroom
|
|
877
844
|
.command("history")
|
|
878
845
|
.description("Show job history with outcomes and earnings.")
|
|
879
846
|
.action(async () => {
|
|
880
|
-
const memoryDir = path.join(
|
|
847
|
+
const memoryDir = path.join(ARC402_DIR, "worker", "memory");
|
|
881
848
|
if (!fs.existsSync(memoryDir)) {
|
|
882
849
|
console.log("No job history yet.");
|
|
883
850
|
return;
|
|
@@ -903,17 +870,17 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
903
870
|
console.error("Workroom is not running.");
|
|
904
871
|
process.exit(1);
|
|
905
872
|
}
|
|
906
|
-
console.log(
|
|
873
|
+
console.log(c.dim("Reloading workroom policy..."));
|
|
907
874
|
// Trigger DNS refresh manually (which re-reads policy and updates iptables)
|
|
908
|
-
const result =
|
|
875
|
+
const result = runCmd("docker", [
|
|
909
876
|
"exec", WORKROOM_CONTAINER,
|
|
910
877
|
"bash", "-c", "/dns-refresh.sh /workroom/.arc402/openshell-policy.yaml &",
|
|
911
878
|
]);
|
|
912
879
|
if (result.ok) {
|
|
913
|
-
console.log(" " +
|
|
880
|
+
console.log(" " + c.success + c.white(" Policy reload triggered"));
|
|
914
881
|
}
|
|
915
882
|
else {
|
|
916
|
-
console.error(
|
|
883
|
+
console.error(c.failure + " " + c.red("Failed to reload policy"));
|
|
917
884
|
}
|
|
918
885
|
});
|
|
919
886
|
}
|