arc402-cli 0.4.0 → 0.4.2
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/arbitrator.d.ts.map +1 -1
- package/dist/commands/arbitrator.js +62 -13
- package/dist/commands/arbitrator.js.map +1 -1
- package/dist/commands/arena.d.ts.map +1 -1
- package/dist/commands/arena.js +4 -3
- package/dist/commands/arena.js.map +1 -1
- package/dist/commands/cancel.d.ts.map +1 -1
- package/dist/commands/cancel.js +20 -10
- package/dist/commands/cancel.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +1 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/deliver.d.ts.map +1 -1
- package/dist/commands/deliver.js +16 -3
- package/dist/commands/deliver.js.map +1 -1
- package/dist/commands/discover.d.ts.map +1 -1
- package/dist/commands/discover.js +2 -0
- package/dist/commands/discover.js.map +1 -1
- package/dist/commands/dispute.d.ts.map +1 -1
- package/dist/commands/dispute.js +11 -10
- package/dist/commands/dispute.js.map +1 -1
- package/dist/commands/hire.d.ts.map +1 -1
- package/dist/commands/hire.js +12 -2
- package/dist/commands/hire.js.map +1 -1
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +29 -29
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/negotiate.d.ts.map +1 -1
- package/dist/commands/negotiate.js +8 -7
- package/dist/commands/negotiate.js.map +1 -1
- package/dist/commands/openshell.d.ts.map +1 -1
- package/dist/commands/openshell.js +6 -5
- package/dist/commands/openshell.js.map +1 -1
- package/dist/commands/owner.d.ts.map +1 -1
- package/dist/commands/owner.js +2 -1
- package/dist/commands/owner.js.map +1 -1
- package/dist/commands/policy.d.ts.map +1 -1
- package/dist/commands/policy.js +22 -10
- package/dist/commands/policy.js.map +1 -1
- package/dist/commands/relay.js +6 -5
- package/dist/commands/relay.js.map +1 -1
- package/dist/commands/remediate.js +3 -2
- package/dist/commands/remediate.js.map +1 -1
- package/dist/commands/reputation.d.ts.map +1 -1
- package/dist/commands/reputation.js +12 -5
- package/dist/commands/reputation.js.map +1 -1
- package/dist/commands/trust.d.ts.map +1 -1
- package/dist/commands/trust.js +16 -1
- package/dist/commands/trust.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +6 -4
- package/dist/commands/verify.js.map +1 -1
- package/dist/commands/wallet.d.ts.map +1 -1
- package/dist/commands/wallet.js +202 -165
- package/dist/commands/wallet.js.map +1 -1
- package/dist/commands/watchtower.d.ts.map +1 -1
- package/dist/commands/watchtower.js +30 -13
- package/dist/commands/watchtower.js.map +1 -1
- package/dist/commands/workroom.d.ts.map +1 -1
- package/dist/commands/workroom.js +123 -95
- package/dist/commands/workroom.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/arbitrator.ts +45 -10
- package/src/commands/arena.ts +4 -3
- package/src/commands/cancel.ts +19 -10
- package/src/commands/config.ts +1 -0
- package/src/commands/deliver.ts +16 -3
- package/src/commands/discover.ts +2 -0
- package/src/commands/dispute.ts +12 -10
- package/src/commands/hire.ts +9 -2
- package/src/commands/migrate.ts +28 -26
- package/src/commands/negotiate.ts +8 -7
- package/src/commands/openshell.ts +7 -5
- package/src/commands/owner.ts +2 -1
- package/src/commands/policy.ts +18 -10
- package/src/commands/relay.ts +5 -5
- package/src/commands/remediate.ts +2 -2
- package/src/commands/reputation.ts +9 -5
- package/src/commands/trust.ts +10 -1
- package/src/commands/verify.ts +5 -4
- package/src/commands/wallet.ts +203 -165
- package/src/commands/watchtower.ts +25 -13
- package/src/commands/workroom.ts +121 -95
- package/src/config.ts +2 -1
|
@@ -49,16 +49,21 @@ export function registerWatchtowerCommands(program: Command): void {
|
|
|
49
49
|
.split(",")
|
|
50
50
|
.map((s: string) => s.trim())
|
|
51
51
|
.filter(Boolean);
|
|
52
|
+
const regSpinner = startSpinner('Registering watchtower…');
|
|
52
53
|
const result = await client.registerWatchtower({
|
|
53
54
|
name: opts.name,
|
|
54
55
|
description: opts.description,
|
|
55
56
|
capabilities,
|
|
56
57
|
});
|
|
57
58
|
if (opts.json || program.opts().json) {
|
|
59
|
+
regSpinner.stop();
|
|
58
60
|
console.log(JSON.stringify(result));
|
|
59
61
|
} else {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
regSpinner.succeed(c.success + c.white(' Registered as watchtower'));
|
|
63
|
+
renderTree([
|
|
64
|
+
{ label: 'Name', value: opts.name },
|
|
65
|
+
{ label: 'Tx', value: result.txHash, last: true },
|
|
66
|
+
]);
|
|
62
67
|
}
|
|
63
68
|
});
|
|
64
69
|
|
|
@@ -86,14 +91,19 @@ export function registerWatchtowerCommands(program: Command): void {
|
|
|
86
91
|
if (opts.json || program.opts().json) {
|
|
87
92
|
console.log(JSON.stringify(status, null, 2));
|
|
88
93
|
} else {
|
|
89
|
-
console.log(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
console.log('\n ' + c.mark + c.white(' Watchtower — ' + formatAddress(status.addr)));
|
|
95
|
+
const statusItems: { label: string; value: string; last?: boolean }[] = [
|
|
96
|
+
{ label: 'Name', value: status.name },
|
|
97
|
+
{ label: 'Description', value: status.description },
|
|
98
|
+
{ label: 'Capabilities', value: status.capabilities.join(', ') || '(none)' },
|
|
99
|
+
{ label: 'Active', value: String(status.active) },
|
|
100
|
+
];
|
|
94
101
|
if (status.registeredAt) {
|
|
95
|
-
|
|
102
|
+
statusItems.push({ label: 'Registered', value: new Date(status.registeredAt * 1000).toISOString(), last: true });
|
|
103
|
+
} else {
|
|
104
|
+
statusItems[statusItems.length - 1].last = true;
|
|
96
105
|
}
|
|
106
|
+
renderTree(statusItems);
|
|
97
107
|
}
|
|
98
108
|
});
|
|
99
109
|
|
|
@@ -164,7 +174,7 @@ export function registerWatchtowerCommands(program: Command): void {
|
|
|
164
174
|
if (opts.json) {
|
|
165
175
|
console.log(JSON.stringify({ event: "challenge_submitted", channelId, txHash: result.txHash }));
|
|
166
176
|
} else {
|
|
167
|
-
console.log(
|
|
177
|
+
console.log(' ' + c.success + c.white(' Challenge submitted — tx ' + result.txHash.slice(0, 12) + '...'));
|
|
168
178
|
}
|
|
169
179
|
return;
|
|
170
180
|
} else {
|
|
@@ -201,12 +211,13 @@ export function registerWatchtowerCommands(program: Command): void {
|
|
|
201
211
|
config.serviceAgreementAddress,
|
|
202
212
|
signer
|
|
203
213
|
);
|
|
214
|
+
const authSpinner = startSpinner('Authorizing watchtower…');
|
|
204
215
|
const result = await client.authorizeWatchtower(channelId, watchtower);
|
|
205
216
|
if (opts.json || program.opts().json) {
|
|
217
|
+
authSpinner.stop();
|
|
206
218
|
console.log(JSON.stringify(result));
|
|
207
219
|
} else {
|
|
208
|
-
|
|
209
|
-
console.log(`tx: ${result.txHash}`);
|
|
220
|
+
authSpinner.succeed(c.success + c.white(' Authorized: ' + formatAddress(watchtower)));
|
|
210
221
|
}
|
|
211
222
|
});
|
|
212
223
|
|
|
@@ -225,12 +236,13 @@ export function registerWatchtowerCommands(program: Command): void {
|
|
|
225
236
|
config.serviceAgreementAddress,
|
|
226
237
|
signer
|
|
227
238
|
);
|
|
239
|
+
const revokeSpinner = startSpinner('Revoking watchtower…');
|
|
228
240
|
const result = await client.revokeWatchtower(channelId, watchtower);
|
|
229
241
|
if (opts.json || program.opts().json) {
|
|
242
|
+
revokeSpinner.stop();
|
|
230
243
|
console.log(JSON.stringify(result));
|
|
231
244
|
} else {
|
|
232
|
-
|
|
233
|
-
console.log(`tx: ${result.txHash}`);
|
|
245
|
+
revokeSpinner.succeed(c.success + c.white(' Revoked: ' + formatAddress(watchtower)));
|
|
234
246
|
}
|
|
235
247
|
});
|
|
236
248
|
}
|
package/src/commands/workroom.ts
CHANGED
|
@@ -9,6 +9,10 @@ import {
|
|
|
9
9
|
runCmd,
|
|
10
10
|
} from "../openshell-runtime";
|
|
11
11
|
import { DAEMON_LOG, DAEMON_TOML } from "../daemon/config";
|
|
12
|
+
import { c } from "../ui/colors";
|
|
13
|
+
import { startSpinner } from "../ui/spinner";
|
|
14
|
+
import { renderTree } from "../ui/tree";
|
|
15
|
+
import { formatAddress } from "../ui/format";
|
|
12
16
|
|
|
13
17
|
// ─── Daemon lifecycle notify ──────────────────────────────────────────────────
|
|
14
18
|
|
|
@@ -113,33 +117,33 @@ export function registerWorkroomCommands(program: Command): void {
|
|
|
113
117
|
.command("init")
|
|
114
118
|
.description("Create the ARC-402 Workroom: build Docker image, validate policy, prepare runtime bundle.")
|
|
115
119
|
.action(async () => {
|
|
116
|
-
console.log("ARC-402 Workroom Init");
|
|
117
|
-
console.log("─────────────────────");
|
|
120
|
+
console.log(c.brightCyan("ARC-402 Workroom Init"));
|
|
121
|
+
console.log(c.dim("─────────────────────"));
|
|
118
122
|
|
|
119
123
|
// Check Docker
|
|
120
124
|
if (!dockerAvailable()) {
|
|
121
|
-
console.error("Docker is not available. Install Docker Desktop and try again.");
|
|
125
|
+
console.error(c.failure + " " + c.red("Docker is not available. Install Docker Desktop and try again."));
|
|
122
126
|
process.exit(1);
|
|
123
127
|
}
|
|
124
|
-
console.log("
|
|
128
|
+
console.log(" " + c.success + c.white(" Docker available"));
|
|
125
129
|
|
|
126
130
|
// Check policy file
|
|
127
131
|
if (!fs.existsSync(POLICY_FILE)) {
|
|
128
|
-
console.log("No policy file found. Generating default...");
|
|
132
|
+
console.log(c.dim("No policy file found. Generating default..."));
|
|
129
133
|
// Import and call the existing policy generator
|
|
130
134
|
const { registerOpenShellCommands } = require("./openshell");
|
|
131
|
-
console.log(`Policy file will be generated at: ${POLICY_FILE}`);
|
|
132
|
-
console.log("Run 'arc402 workroom policy preset core-launch' after init to apply defaults.");
|
|
135
|
+
console.log(c.dim(`Policy file will be generated at: ${POLICY_FILE}`));
|
|
136
|
+
console.log(c.dim("Run 'arc402 workroom policy preset core-launch' after init to apply defaults."));
|
|
133
137
|
} else {
|
|
134
|
-
console.log(
|
|
138
|
+
console.log(" " + c.success + c.dim(" Policy file: ") + c.white(POLICY_FILE));
|
|
135
139
|
}
|
|
136
140
|
|
|
137
141
|
// Check daemon.toml
|
|
138
142
|
if (!fs.existsSync(DAEMON_TOML)) {
|
|
139
|
-
console.error("daemon.toml not found. Run 'arc402 daemon init' first.");
|
|
143
|
+
console.error(c.failure + " " + c.red("daemon.toml not found. Run 'arc402 daemon init' first."));
|
|
140
144
|
process.exit(1);
|
|
141
145
|
}
|
|
142
|
-
console.log("
|
|
146
|
+
console.log(" " + c.success + c.white(" daemon.toml found"));
|
|
143
147
|
|
|
144
148
|
// Set up Arena directories and default policy
|
|
145
149
|
if (!fs.existsSync(ARENA_DATA_DIR)) {
|
|
@@ -147,9 +151,9 @@ export function registerWorkroomCommands(program: Command): void {
|
|
|
147
151
|
for (const sub of ["feed", "profile", "state", "queue"]) {
|
|
148
152
|
fs.mkdirSync(path.join(ARENA_DATA_DIR, sub), { recursive: true });
|
|
149
153
|
}
|
|
150
|
-
console.log("
|
|
154
|
+
console.log(" " + c.success + c.white(" Arena directories created"));
|
|
151
155
|
} else {
|
|
152
|
-
console.log("
|
|
156
|
+
console.log(" " + c.success + c.white(" Arena directories exist"));
|
|
153
157
|
}
|
|
154
158
|
|
|
155
159
|
// Copy default arena policy if not present
|
|
@@ -157,34 +161,34 @@ export function registerWorkroomCommands(program: Command): void {
|
|
|
157
161
|
const defaultArenaPolicy = path.join(WORKROOM_DIR, "arena-policy.yaml");
|
|
158
162
|
if (fs.existsSync(defaultArenaPolicy)) {
|
|
159
163
|
fs.copyFileSync(defaultArenaPolicy, ARENA_POLICY_FILE);
|
|
160
|
-
console.log("
|
|
164
|
+
console.log(" " + c.success + c.white(" Arena policy: default installed"));
|
|
161
165
|
} else {
|
|
162
|
-
console.log("
|
|
166
|
+
console.log(" " + c.warning + " " + c.yellow("Arena policy template not found — create manually at " + ARENA_POLICY_FILE));
|
|
163
167
|
}
|
|
164
168
|
} else {
|
|
165
|
-
console.log("
|
|
169
|
+
console.log(" " + c.success + c.white(" Arena policy exists"));
|
|
166
170
|
}
|
|
167
171
|
|
|
168
172
|
// Build image
|
|
169
173
|
if (!imageExists()) {
|
|
170
174
|
if (!buildImage()) {
|
|
171
|
-
console.error("Failed to build workroom image.");
|
|
175
|
+
console.error(c.failure + " " + c.red("Failed to build workroom image."));
|
|
172
176
|
process.exit(1);
|
|
173
177
|
}
|
|
174
178
|
}
|
|
175
|
-
console.log(
|
|
179
|
+
console.log(" " + c.success + c.dim(" Image: ") + c.white(WORKROOM_IMAGE));
|
|
176
180
|
|
|
177
181
|
// Package CLI runtime for the workroom
|
|
178
182
|
const cliDist = path.resolve(__dirname, "..", "..");
|
|
179
183
|
const cliPackage = path.resolve(__dirname, "..", "..", "..", "package.json");
|
|
180
184
|
if (fs.existsSync(cliDist) && fs.existsSync(cliPackage)) {
|
|
181
|
-
console.log("
|
|
185
|
+
console.log(" " + c.success + c.white(" CLI runtime available for workroom mount"));
|
|
182
186
|
} else {
|
|
183
|
-
console.warn("
|
|
187
|
+
console.warn(" " + c.warning + " " + c.yellow("CLI dist not found — workroom will need runtime bundle"));
|
|
184
188
|
}
|
|
185
189
|
|
|
186
|
-
console.log("\
|
|
187
|
-
console.log(
|
|
190
|
+
console.log("\n" + c.success + c.white(" Workroom initialized. Start with: arc402 workroom start"));
|
|
191
|
+
console.log(c.dim("Policy hash: ") + c.white(getPolicyHash()));
|
|
188
192
|
});
|
|
189
193
|
|
|
190
194
|
// ── start ─────────────────────────────────────────────────────────────────
|
|
@@ -229,7 +233,7 @@ export function registerWorkroomCommands(program: Command): void {
|
|
|
229
233
|
// CLI runtime path
|
|
230
234
|
const cliRoot = path.resolve(__dirname, "..", "..", "..");
|
|
231
235
|
|
|
232
|
-
console.log("Starting ARC-402 Workroom...");
|
|
236
|
+
console.log(c.dim("Starting ARC-402 Workroom..."));
|
|
233
237
|
|
|
234
238
|
const args = [
|
|
235
239
|
"run", "-d",
|
|
@@ -267,16 +271,18 @@ export function registerWorkroomCommands(program: Command): void {
|
|
|
267
271
|
spawnSync("sleep", ["2"]);
|
|
268
272
|
|
|
269
273
|
if (containerRunning()) {
|
|
270
|
-
console.log("\n
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
274
|
+
console.log("\n" + c.success + c.white(" ARC-402 Workroom is running"));
|
|
275
|
+
renderTree([
|
|
276
|
+
{ label: "Container", value: WORKROOM_CONTAINER },
|
|
277
|
+
{ label: "Policy hash", value: getPolicyHash() },
|
|
278
|
+
{ label: "Relay port", value: "4402" },
|
|
279
|
+
{ label: "Logs", value: "arc402 workroom logs", last: true },
|
|
280
|
+
]);
|
|
275
281
|
// Notify local daemon of workroom entry
|
|
276
282
|
notifyDaemonWorkroomStatus("entered");
|
|
277
283
|
} else {
|
|
278
|
-
console.error("Workroom started but exited immediately. Check logs:");
|
|
279
|
-
console.error(" docker logs arc402-workroom");
|
|
284
|
+
console.error(c.failure + " " + c.red("Workroom started but exited immediately. Check logs:"));
|
|
285
|
+
console.error(c.dim(" docker logs arc402-workroom"));
|
|
280
286
|
process.exit(1);
|
|
281
287
|
}
|
|
282
288
|
});
|
|
@@ -290,11 +296,11 @@ export function registerWorkroomCommands(program: Command): void {
|
|
|
290
296
|
console.log("Workroom is not running.");
|
|
291
297
|
return;
|
|
292
298
|
}
|
|
293
|
-
console.log("Stopping ARC-402 Workroom...");
|
|
299
|
+
console.log(c.dim("Stopping ARC-402 Workroom..."));
|
|
294
300
|
// Notify daemon before stopping (daemon may be inside container)
|
|
295
301
|
notifyDaemonWorkroomStatus("exited");
|
|
296
302
|
runCmd("docker", ["stop", WORKROOM_CONTAINER]);
|
|
297
|
-
console.log("
|
|
303
|
+
console.log(" " + c.success + c.white(" Workroom stopped"));
|
|
298
304
|
});
|
|
299
305
|
|
|
300
306
|
// ── status ────────────────────────────────────────────────────────────────
|
|
@@ -302,22 +308,26 @@ export function registerWorkroomCommands(program: Command): void {
|
|
|
302
308
|
.command("status")
|
|
303
309
|
.description("Show ARC-402 Workroom health, policy, and active state.")
|
|
304
310
|
.action(async () => {
|
|
305
|
-
console.log("ARC-402 Workroom Status");
|
|
306
|
-
console.log("───────────────────────");
|
|
311
|
+
console.log(c.brightCyan("ARC-402 Workroom Status"));
|
|
312
|
+
console.log(c.dim("───────────────────────"));
|
|
307
313
|
|
|
308
314
|
// Docker
|
|
309
315
|
if (!dockerAvailable()) {
|
|
310
|
-
console.log("Docker:
|
|
316
|
+
console.log(c.dim("Docker: ") + c.failure + " " + c.red("not available"));
|
|
311
317
|
return;
|
|
312
318
|
}
|
|
313
|
-
console.log("Docker:
|
|
319
|
+
console.log(c.dim("Docker: ") + c.success + c.white(" available"));
|
|
314
320
|
|
|
315
321
|
// Image
|
|
316
|
-
|
|
322
|
+
if (imageExists()) {
|
|
323
|
+
console.log(c.dim("Image: ") + c.success + " " + c.white(WORKROOM_IMAGE));
|
|
324
|
+
} else {
|
|
325
|
+
console.log(c.dim("Image: ") + c.failure + " " + c.red("not built (run: arc402 workroom init)"));
|
|
326
|
+
}
|
|
317
327
|
|
|
318
328
|
// Container
|
|
319
329
|
if (containerRunning()) {
|
|
320
|
-
console.log(
|
|
330
|
+
console.log(c.dim("Container: ") + c.success + c.white(` running (${WORKROOM_CONTAINER})`));
|
|
321
331
|
|
|
322
332
|
// Get container uptime
|
|
323
333
|
const inspect = runCmd("docker", ["inspect", WORKROOM_CONTAINER, "--format", "{{.State.StartedAt}}"]);
|
|
@@ -326,30 +336,38 @@ export function registerWorkroomCommands(program: Command): void {
|
|
|
326
336
|
const uptime = Math.floor((Date.now() - started.getTime()) / 1000);
|
|
327
337
|
const h = Math.floor(uptime / 3600);
|
|
328
338
|
const m = Math.floor((uptime % 3600) / 60);
|
|
329
|
-
console.log(
|
|
339
|
+
console.log(c.dim("Uptime: ") + c.white(`${h}h ${m}m`));
|
|
330
340
|
}
|
|
331
341
|
|
|
332
342
|
// Get iptables rule count from inside container
|
|
333
343
|
const rules = runCmd("docker", ["exec", WORKROOM_CONTAINER, "iptables", "-L", "OUTPUT", "-n", "--line-numbers"]);
|
|
334
344
|
if (rules.ok) {
|
|
335
345
|
const ruleCount = rules.stdout.split("\n").filter(l => l.match(/^\d+/)).length;
|
|
336
|
-
console.log(
|
|
346
|
+
console.log(c.dim("Network rules: ") + c.white(`${ruleCount} iptables rules enforced`));
|
|
337
347
|
}
|
|
338
348
|
} else if (containerExists()) {
|
|
339
|
-
console.log(
|
|
349
|
+
console.log(c.dim("Container: ") + c.warning + " " + c.yellow("stopped (run: arc402 workroom start)"));
|
|
340
350
|
} else {
|
|
341
|
-
console.log(
|
|
351
|
+
console.log(c.dim("Container: ") + c.failure + " " + c.red("not created (run: arc402 workroom init)"));
|
|
342
352
|
}
|
|
343
353
|
|
|
344
354
|
// Policy
|
|
345
|
-
|
|
346
|
-
|
|
355
|
+
if (fs.existsSync(POLICY_FILE)) {
|
|
356
|
+
console.log(c.dim("Policy file: ") + c.success + " " + c.white(POLICY_FILE));
|
|
357
|
+
} else {
|
|
358
|
+
console.log(c.dim("Policy file: ") + c.failure + " " + c.red("missing"));
|
|
359
|
+
}
|
|
360
|
+
console.log(c.dim("Policy hash: ") + c.white(getPolicyHash()));
|
|
347
361
|
|
|
348
362
|
// Arena
|
|
349
363
|
const arenaExists = fs.existsSync(ARENA_DATA_DIR);
|
|
350
364
|
const arenaPolicy = fs.existsSync(ARENA_POLICY_FILE);
|
|
351
|
-
|
|
352
|
-
|
|
365
|
+
if (arenaExists) {
|
|
366
|
+
console.log(c.dim("Arena data: ") + c.success + " " + c.white(ARENA_DATA_DIR));
|
|
367
|
+
} else {
|
|
368
|
+
console.log(c.dim("Arena data: ") + c.failure + " " + c.red("missing (run: arc402 workroom init)"));
|
|
369
|
+
}
|
|
370
|
+
console.log(c.dim("Arena policy: ") + (arenaPolicy ? c.success + c.white(" loaded") : c.failure + " " + c.red("missing")));
|
|
353
371
|
|
|
354
372
|
// Arena queue (pending approvals)
|
|
355
373
|
if (arenaExists) {
|
|
@@ -357,9 +375,9 @@ export function registerWorkroomCommands(program: Command): void {
|
|
|
357
375
|
if (fs.existsSync(queueDir)) {
|
|
358
376
|
const pending = fs.readdirSync(queueDir).filter(f => f.endsWith(".json")).length;
|
|
359
377
|
if (pending > 0) {
|
|
360
|
-
console.log(
|
|
378
|
+
console.log(c.dim("Arena queue: ") + c.warning + " " + c.yellow(`${pending} action(s) awaiting approval`));
|
|
361
379
|
} else {
|
|
362
|
-
console.log(
|
|
380
|
+
console.log(c.dim("Arena queue: ") + c.success + c.white(" empty"));
|
|
363
381
|
}
|
|
364
382
|
}
|
|
365
383
|
}
|
|
@@ -399,8 +417,8 @@ export function registerWorkroomCommands(program: Command): void {
|
|
|
399
417
|
.command("doctor")
|
|
400
418
|
.description("Diagnose workroom health: Docker, image, container, network, policy, daemon.")
|
|
401
419
|
.action(async () => {
|
|
402
|
-
console.log("ARC-402 Workroom Doctor");
|
|
403
|
-
console.log("───────────────────────");
|
|
420
|
+
console.log(c.brightCyan("ARC-402 Workroom Doctor"));
|
|
421
|
+
console.log(c.dim("───────────────────────"));
|
|
404
422
|
|
|
405
423
|
const checks: Array<{ label: string; pass: boolean; detail: string }> = [];
|
|
406
424
|
|
|
@@ -436,17 +454,19 @@ export function registerWorkroomCommands(program: Command): void {
|
|
|
436
454
|
}
|
|
437
455
|
|
|
438
456
|
// Print results
|
|
439
|
-
for (const
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
457
|
+
for (const chk of checks) {
|
|
458
|
+
if (chk.pass) {
|
|
459
|
+
console.log(" " + c.success + " " + c.dim(chk.label + ":") + " " + c.white(chk.detail));
|
|
460
|
+
} else {
|
|
461
|
+
console.log(" " + c.failure + " " + c.dim(chk.label + ":") + " " + c.red(chk.detail) + c.yellow(" ← FIX"));
|
|
462
|
+
}
|
|
443
463
|
}
|
|
444
464
|
|
|
445
|
-
const failures = checks.filter(
|
|
465
|
+
const failures = checks.filter(chk => !chk.pass);
|
|
446
466
|
if (failures.length === 0) {
|
|
447
|
-
console.log("\n
|
|
467
|
+
console.log("\n" + c.success + c.white(" All checks passed. Workroom is healthy."));
|
|
448
468
|
} else {
|
|
449
|
-
console.log(
|
|
469
|
+
console.log("\n" + c.failure + " " + c.red(`${failures.length} issue(s) found.`));
|
|
450
470
|
}
|
|
451
471
|
});
|
|
452
472
|
|
|
@@ -482,18 +502,18 @@ export function registerWorkroomCommands(program: Command): void {
|
|
|
482
502
|
console.error("Workroom is not running. Start it first: arc402 workroom start");
|
|
483
503
|
process.exit(1);
|
|
484
504
|
}
|
|
485
|
-
console.log(`Testing connectivity to ${host} from inside workroom...`);
|
|
505
|
+
console.log(c.dim(`Testing connectivity to ${host} from inside workroom...`));
|
|
486
506
|
const result = runCmd("docker", [
|
|
487
507
|
"exec", WORKROOM_CONTAINER,
|
|
488
508
|
"curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", "--max-time", "5",
|
|
489
509
|
`https://${host}`,
|
|
490
510
|
]);
|
|
491
511
|
if (result.ok && result.stdout.trim() !== "000") {
|
|
492
|
-
console.log(
|
|
512
|
+
console.log(" " + c.success + " " + c.white(host) + c.dim(` is reachable (HTTP ${result.stdout.trim()})`));
|
|
493
513
|
} else {
|
|
494
|
-
console.log(
|
|
495
|
-
console.log(" This host may not be in the workroom policy.");
|
|
496
|
-
console.log(" Add it with: arc402 openshell policy add <name> <host>");
|
|
514
|
+
console.log(" " + c.failure + " " + c.red(`${host} is NOT reachable from the workroom`));
|
|
515
|
+
console.log(c.dim(" This host may not be in the workroom policy."));
|
|
516
|
+
console.log(c.dim(" Add it with: arc402 openshell policy add <name> <host>"));
|
|
497
517
|
}
|
|
498
518
|
});
|
|
499
519
|
|
|
@@ -553,9 +573,9 @@ Write these learnings concisely. They will be available on your next job.
|
|
|
553
573
|
- If the task is unclear, produce the best interpretation and document assumptions
|
|
554
574
|
- Every deliverable must be verifiable against the task spec
|
|
555
575
|
`);
|
|
556
|
-
console.log(
|
|
576
|
+
console.log(" " + c.success + c.dim(` Worker SOUL.md created: ${soulPath}`));
|
|
557
577
|
} else {
|
|
558
|
-
console.log(
|
|
578
|
+
console.log(" " + c.success + c.dim(` Worker SOUL.md already exists: ${soulPath}`));
|
|
559
579
|
}
|
|
560
580
|
|
|
561
581
|
// Generate default MEMORY.md
|
|
@@ -572,7 +592,7 @@ Write these learnings concisely. They will be available on your next job.
|
|
|
572
592
|
|
|
573
593
|
No jobs completed yet. Learnings will accumulate here as the worker completes hired tasks.
|
|
574
594
|
`);
|
|
575
|
-
console.log(
|
|
595
|
+
console.log(" " + c.success + c.dim(` Worker MEMORY.md created: ${memoryPath}`));
|
|
576
596
|
}
|
|
577
597
|
|
|
578
598
|
// Generate learnings.md
|
|
@@ -586,7 +606,7 @@ No jobs completed yet. Learnings will accumulate here as the worker completes hi
|
|
|
586
606
|
|
|
587
607
|
No learnings yet. Complete your first hired task to start accumulating expertise.
|
|
588
608
|
`);
|
|
589
|
-
console.log(
|
|
609
|
+
console.log(" " + c.success + c.dim(` Learnings file created: ${learningsPath}`));
|
|
590
610
|
}
|
|
591
611
|
|
|
592
612
|
// Worker config
|
|
@@ -601,13 +621,13 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
601
621
|
total_earned_eth: "0",
|
|
602
622
|
};
|
|
603
623
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
604
|
-
console.log(
|
|
624
|
+
console.log(" " + c.success + c.dim(` Worker config created: ${configPath}`));
|
|
605
625
|
}
|
|
606
626
|
|
|
607
|
-
console.log(
|
|
608
|
-
console.log("Next: customize the worker SOUL.md and add skills.");
|
|
609
|
-
console.log(" arc402 workroom worker set-soul <file>");
|
|
610
|
-
console.log(" arc402 workroom worker set-skills <dir>");
|
|
627
|
+
console.log("\n" + c.success + c.white(` Worker initialized at: ${workerDir}`));
|
|
628
|
+
console.log(c.dim("Next: customize the worker SOUL.md and add skills."));
|
|
629
|
+
console.log(c.dim(" arc402 workroom worker set-soul <file>"));
|
|
630
|
+
console.log(c.dim(" arc402 workroom worker set-skills <dir>"));
|
|
611
631
|
});
|
|
612
632
|
|
|
613
633
|
worker
|
|
@@ -636,16 +656,18 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
636
656
|
? fs.readdirSync(skillsDir).length
|
|
637
657
|
: 0;
|
|
638
658
|
|
|
639
|
-
console.log("ARC-402 Workroom Worker");
|
|
640
|
-
console.log("───────────────────────");
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
659
|
+
console.log(c.brightCyan("ARC-402 Workroom Worker"));
|
|
660
|
+
console.log(c.dim("───────────────────────"));
|
|
661
|
+
renderTree([
|
|
662
|
+
{ label: "Name", value: config.name },
|
|
663
|
+
{ label: "Model", value: config.model },
|
|
664
|
+
{ label: "Created", value: config.created },
|
|
665
|
+
{ label: "Jobs done", value: String(config.job_count) },
|
|
666
|
+
{ label: "Job memories", value: String(jobFiles) },
|
|
667
|
+
{ label: "Learnings", value: learningsSize > 200 ? Math.round(learningsSize / 1024) + " KB" : "empty" },
|
|
668
|
+
{ label: "Skills", value: String(skillCount) },
|
|
669
|
+
{ label: "Total earned", value: config.total_earned_eth + " ETH", last: true },
|
|
670
|
+
]);
|
|
649
671
|
});
|
|
650
672
|
|
|
651
673
|
worker
|
|
@@ -659,7 +681,7 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
659
681
|
const dest = path.join(ARC402_DIR, "worker", "SOUL.md");
|
|
660
682
|
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
661
683
|
fs.copyFileSync(file, dest);
|
|
662
|
-
console.log(
|
|
684
|
+
console.log(" " + c.success + c.white(` Worker SOUL.md updated from: ${file}`));
|
|
663
685
|
});
|
|
664
686
|
|
|
665
687
|
worker
|
|
@@ -684,7 +706,7 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
684
706
|
fs.cpSync(src, dst, { recursive: true });
|
|
685
707
|
}
|
|
686
708
|
}
|
|
687
|
-
console.log(
|
|
709
|
+
console.log(" " + c.success + c.white(` ${files.length} items copied to worker skills`));
|
|
688
710
|
});
|
|
689
711
|
|
|
690
712
|
worker
|
|
@@ -710,10 +732,10 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
710
732
|
count++;
|
|
711
733
|
}
|
|
712
734
|
}
|
|
713
|
-
console.log(
|
|
714
|
-
console.log(
|
|
715
|
-
console.log(
|
|
716
|
-
console.log(
|
|
735
|
+
console.log(" " + c.success + c.white(` ${count} items copied to worker knowledge`));
|
|
736
|
+
console.log(" " + c.dim("Path:") + " " + c.white(dest));
|
|
737
|
+
console.log(c.dim(" The worker can reference these files during hired tasks."));
|
|
738
|
+
console.log(c.dim(" To update: run this command again with the updated directory."));
|
|
717
739
|
});
|
|
718
740
|
|
|
719
741
|
worker
|
|
@@ -767,7 +789,7 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
767
789
|
config.job_count = 0;
|
|
768
790
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
769
791
|
}
|
|
770
|
-
console.log("
|
|
792
|
+
console.log(" " + c.success + c.white(" Worker memory cleared. Starting fresh."));
|
|
771
793
|
});
|
|
772
794
|
|
|
773
795
|
// ── token usage ──────────────────────────────────────────────────────────
|
|
@@ -877,14 +899,18 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
877
899
|
return;
|
|
878
900
|
}
|
|
879
901
|
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
880
|
-
console.log("ARC-402 Earnings");
|
|
881
|
-
console.log("────────────────");
|
|
882
|
-
|
|
883
|
-
|
|
902
|
+
console.log(c.brightCyan("ARC-402 Earnings"));
|
|
903
|
+
console.log(c.dim("────────────────"));
|
|
904
|
+
const earningsItems: { label: string; value: string; last?: boolean }[] = [
|
|
905
|
+
{ label: "Total earned", value: config.total_earned_eth + " ETH" },
|
|
906
|
+
{ label: "Jobs completed", value: String(config.job_count) },
|
|
907
|
+
];
|
|
884
908
|
if (config.job_count > 0) {
|
|
885
909
|
const avg = (parseFloat(config.total_earned_eth) / config.job_count).toFixed(6);
|
|
886
|
-
|
|
910
|
+
earningsItems.push({ label: "Average/job", value: avg + " ETH" });
|
|
887
911
|
}
|
|
912
|
+
earningsItems[earningsItems.length - 1].last = true;
|
|
913
|
+
renderTree(earningsItems);
|
|
888
914
|
});
|
|
889
915
|
|
|
890
916
|
workroom
|
|
@@ -918,16 +944,16 @@ No learnings yet. Complete your first hired task to start accumulating expertise
|
|
|
918
944
|
console.error("Workroom is not running.");
|
|
919
945
|
process.exit(1);
|
|
920
946
|
}
|
|
921
|
-
console.log("Reloading workroom policy...");
|
|
947
|
+
console.log(c.dim("Reloading workroom policy..."));
|
|
922
948
|
// Trigger DNS refresh manually (which re-reads policy and updates iptables)
|
|
923
949
|
const result = runCmd("docker", [
|
|
924
950
|
"exec", WORKROOM_CONTAINER,
|
|
925
951
|
"bash", "-c", "/dns-refresh.sh /workroom/.arc402/openshell-policy.yaml &",
|
|
926
952
|
]);
|
|
927
953
|
if (result.ok) {
|
|
928
|
-
console.log("
|
|
954
|
+
console.log(" " + c.success + c.white(" Policy reload triggered"));
|
|
929
955
|
} else {
|
|
930
|
-
console.error("Failed to reload policy");
|
|
956
|
+
console.error(c.failure + " " + c.red("Failed to reload policy"));
|
|
931
957
|
}
|
|
932
958
|
});
|
|
933
959
|
}
|
package/src/config.ts
CHANGED
|
@@ -61,7 +61,8 @@ export function loadConfig(): Arc402Config {
|
|
|
61
61
|
network: "base-mainnet",
|
|
62
62
|
rpcUrl: defaults.rpcUrl ?? "https://mainnet.base.org",
|
|
63
63
|
trustRegistryAddress: defaults.trustRegistryAddress ?? "",
|
|
64
|
-
|
|
64
|
+
walletConnectProjectId: "455e9425343b9156fce1428250c9a54a",
|
|
65
|
+
agentRegistryAddress: (defaults as unknown as Record<string,string>).agentRegistryV2Address ?? defaults.agentRegistryAddress,
|
|
65
66
|
serviceAgreementAddress: defaults.serviceAgreementAddress,
|
|
66
67
|
reputationOracleAddress: defaults.reputationOracleAddress,
|
|
67
68
|
capabilityRegistryAddress: defaults.capabilityRegistryAddress,
|