arc402-cli 0.4.0 → 0.4.1
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
package/src/commands/migrate.ts
CHANGED
|
@@ -2,6 +2,10 @@ import { Command } from "commander";
|
|
|
2
2
|
import { ethers } from "ethers";
|
|
3
3
|
import { loadConfig } from "../config";
|
|
4
4
|
import { getClient, requireSigner } from "../client";
|
|
5
|
+
import { c } from '../ui/colors';
|
|
6
|
+
import { startSpinner } from '../ui/spinner';
|
|
7
|
+
import { renderTree } from '../ui/tree';
|
|
8
|
+
import { formatAddress } from '../ui/format';
|
|
5
9
|
|
|
6
10
|
const MIGRATION_REGISTRY_ABI = [
|
|
7
11
|
"function registerMigration(address oldWallet, address newWallet) external",
|
|
@@ -35,8 +39,10 @@ export function registerMigrateCommands(program: Command): void {
|
|
|
35
39
|
const { signer } = await requireSigner(config);
|
|
36
40
|
const contract = new ethers.Contract(config.migrationRegistryAddress, MIGRATION_REGISTRY_ABI, signer);
|
|
37
41
|
|
|
42
|
+
const migrateSpinner = startSpinner('Registering migration...');
|
|
38
43
|
const tx = await contract.registerMigration(oldWallet, newWallet);
|
|
39
44
|
const receipt = await tx.wait();
|
|
45
|
+
migrateSpinner.succeed('Migration registered');
|
|
40
46
|
|
|
41
47
|
const payload = {
|
|
42
48
|
oldWallet,
|
|
@@ -44,11 +50,11 @@ export function registerMigrateCommands(program: Command): void {
|
|
|
44
50
|
txHash: receipt.hash,
|
|
45
51
|
};
|
|
46
52
|
if (opts.json) return console.log(JSON.stringify(payload, null, 2));
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
renderTree([
|
|
54
|
+
{ label: 'Old', value: formatAddress(oldWallet) },
|
|
55
|
+
{ label: 'New', value: formatAddress(newWallet) },
|
|
56
|
+
{ label: 'Note', value: '10% trust score decay applied', last: true },
|
|
57
|
+
]);
|
|
52
58
|
});
|
|
53
59
|
|
|
54
60
|
// ─── migrate status <address> ──────────────────────────────────────────────
|
|
@@ -85,15 +91,15 @@ export function registerMigrateCommands(program: Command): void {
|
|
|
85
91
|
migratedFrom: wasSource ? migratedFrom : null,
|
|
86
92
|
};
|
|
87
93
|
if (opts.json) return console.log(JSON.stringify(payload, null, 2));
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
const statusItems: import('../ui/tree').TreeItem[] = [
|
|
95
|
+
{ label: 'Address', value: formatAddress(address) },
|
|
96
|
+
{ label: 'Active', value: formatAddress(activeWallet) },
|
|
97
|
+
{ label: 'Status', value: isCurrent ? 'current (no further migration)' : `migrated — resolves to ${formatAddress(activeWallet)}` },
|
|
98
|
+
];
|
|
99
|
+
if (hasMigrated) statusItems.push({ label: 'Migrated to', value: formatAddress(migratedTo) });
|
|
100
|
+
if (wasSource) statusItems.push({ label: 'Migrated from', value: formatAddress(migratedFrom) });
|
|
101
|
+
statusItems[statusItems.length - 1].last = true;
|
|
102
|
+
renderTree(statusItems);
|
|
97
103
|
});
|
|
98
104
|
|
|
99
105
|
// ─── migrate lineage <address> ────────────────────────────────────────────
|
|
@@ -158,18 +164,14 @@ export function registerMigrateCommands(program: Command): void {
|
|
|
158
164
|
};
|
|
159
165
|
if (opts.json) return console.log(JSON.stringify(payload, null, 2));
|
|
160
166
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if (i < entries.length) {
|
|
169
|
-
const e = entries[i];
|
|
170
|
-
if (e.timestamp) console.log(` migrated: ${e.timestamp}`);
|
|
171
|
-
if (e.scoreAtMigration) console.log(` score at migration: ${e.scoreAtMigration} (decay: ${Number(e.decayBps) / 100}%)`);
|
|
172
|
-
}
|
|
167
|
+
const lineageItems = lineage.map((addr, i) => {
|
|
168
|
+
const roleLabel = i === 0 ? ' (origin)' : i === lineage.length - 1 ? ' (current)' : '';
|
|
169
|
+
const e = i < entries.length ? entries[i] : null;
|
|
170
|
+
let value = formatAddress(addr) + roleLabel;
|
|
171
|
+
if (e?.timestamp) value += ` · ${e.timestamp}`;
|
|
172
|
+
if (e?.scoreAtMigration) value += ` · score: ${e.scoreAtMigration} (decay: ${Number(e.decayBps) / 100}%)`;
|
|
173
|
+
return { label: `[${i}]`, value, last: i === lineage.length - 1 };
|
|
173
174
|
});
|
|
175
|
+
renderTree(lineageItems);
|
|
174
176
|
});
|
|
175
177
|
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { loadConfig } from "../config";
|
|
12
12
|
import { requireSigner, getClient } from "../client";
|
|
13
13
|
import { hashFile, hashString } from "../utils/hash";
|
|
14
|
+
import { c } from '../ui/colors';
|
|
14
15
|
|
|
15
16
|
const sessionManager = new SessionManager();
|
|
16
17
|
|
|
@@ -102,7 +103,7 @@ export function registerNegotiateCommands(program: Command): void {
|
|
|
102
103
|
if (opts.json) {
|
|
103
104
|
console.log(JSON.stringify({ sessionId: session.sessionId, message: proposal }));
|
|
104
105
|
} else {
|
|
105
|
-
console.log(
|
|
106
|
+
console.log(' ' + c.success + c.white(' Session started: ' + session.sessionId.slice(0, 12) + '...'));
|
|
106
107
|
console.log(`Signed PROPOSE:`);
|
|
107
108
|
console.log(JSON.stringify(proposal, null, 2));
|
|
108
109
|
}
|
|
@@ -138,7 +139,7 @@ export function registerNegotiateCommands(program: Command): void {
|
|
|
138
139
|
if (opts.json) {
|
|
139
140
|
console.log(JSON.stringify(counter));
|
|
140
141
|
} else {
|
|
141
|
-
console.log(
|
|
142
|
+
console.log(' ' + c.success + c.white(' Counter added to session'));
|
|
142
143
|
console.log(JSON.stringify(counter, null, 2));
|
|
143
144
|
}
|
|
144
145
|
});
|
|
@@ -177,8 +178,8 @@ export function registerNegotiateCommands(program: Command): void {
|
|
|
177
178
|
message: accept,
|
|
178
179
|
}));
|
|
179
180
|
} else {
|
|
180
|
-
console.log(
|
|
181
|
-
console.log(
|
|
181
|
+
console.log(' ' + c.success + c.white(' Session ACCEPTED — transcript locked'));
|
|
182
|
+
console.log(' ' + c.dim(' Transcript:') + ' ' + c.white(updatedSession.transcriptHash ?? ''));
|
|
182
183
|
if (opts.record) {
|
|
183
184
|
console.log(`\nTranscript hash is ready to commit on-chain.`);
|
|
184
185
|
console.log(`Run: arc402 hire --session ${sessionId} to propose() and record the transcript hash.`);
|
|
@@ -212,7 +213,7 @@ export function registerNegotiateCommands(program: Command): void {
|
|
|
212
213
|
if (opts.json) {
|
|
213
214
|
console.log(JSON.stringify(reject));
|
|
214
215
|
} else {
|
|
215
|
-
console.log(
|
|
216
|
+
console.log(' ' + c.failure + c.white(' Session REJECTED'));
|
|
216
217
|
console.log(`Reason: ${opts.reason}`);
|
|
217
218
|
}
|
|
218
219
|
});
|
|
@@ -239,9 +240,9 @@ export function registerNegotiateCommands(program: Command): void {
|
|
|
239
240
|
if (opts.json) {
|
|
240
241
|
console.log(JSON.stringify(result));
|
|
241
242
|
} else if (result.valid) {
|
|
242
|
-
console.log(
|
|
243
|
+
console.log(' ' + c.success + c.white(' Valid — signer: ' + result.recoveredSigner));
|
|
243
244
|
} else {
|
|
244
|
-
console.error(
|
|
245
|
+
console.error(' ' + c.failure + c.white(' Invalid — ' + result.error));
|
|
245
246
|
process.exit(1);
|
|
246
247
|
}
|
|
247
248
|
});
|
|
@@ -3,6 +3,8 @@ import * as fs from "fs";
|
|
|
3
3
|
import * as path from "path";
|
|
4
4
|
import * as os from "os";
|
|
5
5
|
import * as YAML from "yaml";
|
|
6
|
+
import { c } from '../ui/colors';
|
|
7
|
+
import { startSpinner } from '../ui/spinner';
|
|
6
8
|
import {
|
|
7
9
|
ARC402_DIR,
|
|
8
10
|
DEFAULT_RUNTIME_REMOTE_ROOT,
|
|
@@ -757,7 +759,7 @@ If you update the local CLI build and want the sandbox to pick it up immediately
|
|
|
757
759
|
synced_at: new Date().toISOString(),
|
|
758
760
|
},
|
|
759
761
|
});
|
|
760
|
-
console.log(
|
|
762
|
+
console.log(' ' + c.success + c.white(` Runtime synced to ${provisioned.remoteRoot}`));
|
|
761
763
|
} catch (err) {
|
|
762
764
|
console.error(`Runtime sync failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
763
765
|
process.exit(1);
|
|
@@ -972,7 +974,7 @@ If you update the local CLI build and want the sandbox to pick it up immediately
|
|
|
972
974
|
const key = peerPolicyKey(cleanedHost);
|
|
973
975
|
const result = ensurePolicyEntry(policy, key, buildPolicyEntry(`peer-agent:${cleanedHost}`, cleanedHost));
|
|
974
976
|
applyAndPersistPolicy(policy);
|
|
975
|
-
console.log(
|
|
977
|
+
console.log(' ' + c.success + c.white(` Peer agent host ${cleanedHost} ${result} under ${key}`));
|
|
976
978
|
console.log(" This only affects sandbox outbound access. It does not claim or expose a public endpoint.");
|
|
977
979
|
});
|
|
978
980
|
|
|
@@ -989,7 +991,7 @@ If you update the local CLI build and want the sandbox to pick it up immediately
|
|
|
989
991
|
process.exit(1);
|
|
990
992
|
}
|
|
991
993
|
applyAndPersistPolicy(policy);
|
|
992
|
-
console.log(
|
|
994
|
+
console.log(' ' + c.success + c.white(` Peer agent host ${cleanedHost} removed (${key})`));
|
|
993
995
|
});
|
|
994
996
|
|
|
995
997
|
peerCmd
|
|
@@ -1018,7 +1020,7 @@ If you update the local CLI build and want the sandbox to pick it up immediately
|
|
|
1018
1020
|
const key = customPolicyKey(name);
|
|
1019
1021
|
const result = ensurePolicyEntry(policy, key, buildPolicyEntry(name, host, [...NODE_BINARIES, ...PYTHON_BINARIES]));
|
|
1020
1022
|
applyAndPersistPolicy(policy);
|
|
1021
|
-
console.log(
|
|
1023
|
+
console.log(' ' + c.success + c.white(` ${host} ${result} as ${key}`));
|
|
1022
1024
|
console.log(" Prefer `arc402 openshell policy peer add <host>` for peer agents or `preset <name>` for launch-safe expansion packs.");
|
|
1023
1025
|
});
|
|
1024
1026
|
|
|
@@ -1048,6 +1050,6 @@ If you update the local CLI build and want the sandbox to pick it up immediately
|
|
|
1048
1050
|
delete policy.network_policies[key];
|
|
1049
1051
|
|
|
1050
1052
|
applyAndPersistPolicy(policy);
|
|
1051
|
-
console.log(
|
|
1053
|
+
console.log(' ' + c.success + c.white(` ${removedHost} removed from daemon sandbox policy (hot-reloaded)`));
|
|
1052
1054
|
});
|
|
1053
1055
|
}
|
package/src/commands/owner.ts
CHANGED
|
@@ -28,7 +28,8 @@ export function registerOwnerCommands(program: Command): void {
|
|
|
28
28
|
if (!config.disputeArbitrationAddress) throw new Error("disputeArbitrationAddress missing in config");
|
|
29
29
|
const { signer } = await requireSigner(config);
|
|
30
30
|
const client = new DisputeArbitrationClient(config.disputeArbitrationAddress, signer);
|
|
31
|
+
const spinner = startSpinner('Accepting ownership…');
|
|
31
32
|
await client.acceptOwnership();
|
|
32
|
-
|
|
33
|
+
spinner.succeed(c.success + c.white(' Ownership accepted'));
|
|
33
34
|
});
|
|
34
35
|
}
|
package/src/commands/policy.ts
CHANGED
|
@@ -45,11 +45,11 @@ blocklist
|
|
|
45
45
|
const already = await contract.isBlocked(wallet, address);
|
|
46
46
|
if (already) {
|
|
47
47
|
if (opts.json) return console.log(JSON.stringify({ address, blocked: true, alreadyBlocked: true }));
|
|
48
|
-
return console.log(
|
|
48
|
+
return console.log(' ' + c.dim('Already blocked: ' + formatAddress(address)));
|
|
49
49
|
}
|
|
50
50
|
await (await contract.addToBlocklist(wallet, address)).wait();
|
|
51
51
|
if (opts.json) return console.log(JSON.stringify({ address, blocked: true }));
|
|
52
|
-
console.log(
|
|
52
|
+
console.log(' ' + c.success + c.white(' Blocked: ' + formatAddress(address)));
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
blocklist
|
|
@@ -67,11 +67,11 @@ blocklist
|
|
|
67
67
|
const isBlockedNow = await contract.isBlocked(wallet, address);
|
|
68
68
|
if (!isBlockedNow) {
|
|
69
69
|
if (opts.json) return console.log(JSON.stringify({ address, blocked: false, notBlocked: true }));
|
|
70
|
-
return console.log(
|
|
70
|
+
return console.log(' ' + c.dim('Not on blocklist: ' + formatAddress(address)));
|
|
71
71
|
}
|
|
72
72
|
await (await contract.removeFromBlocklist(wallet, address)).wait();
|
|
73
73
|
if (opts.json) return console.log(JSON.stringify({ address, blocked: false }));
|
|
74
|
-
console.log(
|
|
74
|
+
console.log(' ' + c.success + c.white(' Unblocked: ' + formatAddress(address)));
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
blocklist
|
|
@@ -89,7 +89,11 @@ blocklist
|
|
|
89
89
|
const contract = getPolicyEngine(config.policyEngineAddress, provider);
|
|
90
90
|
const blocked = await contract.isBlocked(wallet, address);
|
|
91
91
|
if (opts.json) return console.log(JSON.stringify({ address, blocked }));
|
|
92
|
-
|
|
92
|
+
if (blocked) {
|
|
93
|
+
console.log(' ' + c.warning + c.white(' ' + formatAddress(address) + ' is BLOCKED'));
|
|
94
|
+
} else {
|
|
95
|
+
console.log(' ' + c.success + c.white(' ' + formatAddress(address) + ' is not blocked'));
|
|
96
|
+
}
|
|
93
97
|
});
|
|
94
98
|
|
|
95
99
|
blocklist
|
|
@@ -147,11 +151,11 @@ shortlist
|
|
|
147
151
|
const alreadyPreferred = await contract.isPreferred(wallet, opts.capability, address);
|
|
148
152
|
if (alreadyPreferred) {
|
|
149
153
|
if (opts.json) return console.log(JSON.stringify({ address, capability: opts.capability, preferred: true, alreadyPreferred: true }));
|
|
150
|
-
return console.log(
|
|
154
|
+
return console.log(' ' + c.dim('Already shortlisted: ' + formatAddress(address) + ' for ' + opts.capability));
|
|
151
155
|
}
|
|
152
156
|
await (await contract.addPreferred(wallet, opts.capability, address)).wait();
|
|
153
157
|
if (opts.json) return console.log(JSON.stringify({ address, capability: opts.capability, preferred: true }));
|
|
154
|
-
console.log(
|
|
158
|
+
console.log(' ' + c.success + c.white(' Shortlisted: ' + formatAddress(address) + ' for ' + opts.capability));
|
|
155
159
|
});
|
|
156
160
|
|
|
157
161
|
shortlist
|
|
@@ -170,11 +174,11 @@ shortlist
|
|
|
170
174
|
const isPreferredNow = await contract.isPreferred(wallet, opts.capability, address);
|
|
171
175
|
if (!isPreferredNow) {
|
|
172
176
|
if (opts.json) return console.log(JSON.stringify({ address, capability: opts.capability, preferred: false, notPreferred: true }));
|
|
173
|
-
return console.log(
|
|
177
|
+
return console.log(' ' + c.dim('Not shortlisted: ' + formatAddress(address) + ' for ' + opts.capability));
|
|
174
178
|
}
|
|
175
179
|
await (await contract.removePreferred(wallet, opts.capability, address)).wait();
|
|
176
180
|
if (opts.json) return console.log(JSON.stringify({ address, capability: opts.capability, preferred: false }));
|
|
177
|
-
console.log(
|
|
181
|
+
console.log(' ' + c.success + c.white(' Removed from shortlist: ' + formatAddress(address) + ' for ' + opts.capability));
|
|
178
182
|
});
|
|
179
183
|
|
|
180
184
|
shortlist
|
|
@@ -193,7 +197,11 @@ shortlist
|
|
|
193
197
|
const contract = getPolicyEngine(config.policyEngineAddress, provider);
|
|
194
198
|
const preferred = await contract.isPreferred(wallet, opts.capability, address);
|
|
195
199
|
if (opts.json) return console.log(JSON.stringify({ address, capability: opts.capability, preferred }));
|
|
196
|
-
|
|
200
|
+
if (preferred) {
|
|
201
|
+
console.log(' ' + c.success + c.white(' ' + formatAddress(address) + ' is shortlisted for ' + opts.capability));
|
|
202
|
+
} else {
|
|
203
|
+
console.log(' ' + c.warning + c.white(' ' + formatAddress(address) + ' is NOT shortlisted for ' + opts.capability));
|
|
204
|
+
}
|
|
197
205
|
});
|
|
198
206
|
|
|
199
207
|
shortlist
|
package/src/commands/relay.ts
CHANGED
|
@@ -127,7 +127,7 @@ export function registerRelayCommands(program: Command): void {
|
|
|
127
127
|
console.log(JSON.stringify(result.data));
|
|
128
128
|
} else {
|
|
129
129
|
const d = result.data as { messageId?: string };
|
|
130
|
-
console.log(
|
|
130
|
+
console.log(' ' + c.success + c.white(' Sent — messageId: ' + d.messageId));
|
|
131
131
|
}
|
|
132
132
|
});
|
|
133
133
|
|
|
@@ -159,7 +159,7 @@ export function registerRelayCommands(program: Command): void {
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
if (messages.length === 0) {
|
|
162
|
-
console.log(
|
|
162
|
+
console.log(' ' + c.dim('No messages.'));
|
|
163
163
|
return;
|
|
164
164
|
}
|
|
165
165
|
|
|
@@ -217,7 +217,7 @@ export function registerRelayCommands(program: Command): void {
|
|
|
217
217
|
if (opts.json) {
|
|
218
218
|
console.log(JSON.stringify({ started: true, pid: child.pid, pidFile: PID_FILE }));
|
|
219
219
|
} else {
|
|
220
|
-
console.log(
|
|
220
|
+
console.log(' ' + c.success + c.white(' Daemon started (PID ' + child.pid + ')'));
|
|
221
221
|
}
|
|
222
222
|
});
|
|
223
223
|
|
|
@@ -230,7 +230,7 @@ export function registerRelayCommands(program: Command): void {
|
|
|
230
230
|
if (opts.json) {
|
|
231
231
|
console.log(JSON.stringify({ stopped: false, reason: "no pid file" }));
|
|
232
232
|
} else {
|
|
233
|
-
console.log(
|
|
233
|
+
console.log(' ' + c.dim('No running daemon found.'));
|
|
234
234
|
}
|
|
235
235
|
return;
|
|
236
236
|
}
|
|
@@ -242,7 +242,7 @@ export function registerRelayCommands(program: Command): void {
|
|
|
242
242
|
if (opts.json) {
|
|
243
243
|
console.log(JSON.stringify({ stopped: true, pid }));
|
|
244
244
|
} else {
|
|
245
|
-
console.log(
|
|
245
|
+
console.log(' ' + c.success + c.white(' Daemon stopped (PID ' + pid + ')'));
|
|
246
246
|
}
|
|
247
247
|
} catch (err: unknown) {
|
|
248
248
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -10,12 +10,12 @@ export function registerRemediateCommands(program: Command): void {
|
|
|
10
10
|
const remediate = program.command("remediate").description("Negotiated remediation before formal dispute");
|
|
11
11
|
remediate.command("request <id>").requiredOption("--text <feedback>").option("--uri <uri>", "Structured feedback URI", "").option("--file <path>").option("--previous <hash>", "Previous transcript hash", "0x0000000000000000000000000000000000000000000000000000000000000000").action(async (id, opts) => {
|
|
12
12
|
const config = loadConfig(); if (!config.serviceAgreementAddress) throw new Error("serviceAgreementAddress missing in config"); const { signer } = await requireSigner(config); const client = new ServiceAgreementClient(config.serviceAgreementAddress, signer);
|
|
13
|
-
const hash = opts.file ? hashFile(opts.file) : hashString(opts.text); await client.requestRevision(BigInt(id), hash, opts.uri, opts.previous); console.log(
|
|
13
|
+
const hash = opts.file ? hashFile(opts.file) : hashString(opts.text); await client.requestRevision(BigInt(id), hash, opts.uri, opts.previous); console.log(' ' + c.success + c.white(' Revision requested — agreement #' + id));
|
|
14
14
|
});
|
|
15
15
|
remediate.command("respond <id>").requiredOption("--type <type>", "revise|defend|counter|partial-settlement|human-review|escalate").requiredOption("--text <response>").option("--uri <uri>", "Structured response URI", "").option("--file <path>").option("--previous <hash>", "Previous transcript hash", "0x0000000000000000000000000000000000000000000000000000000000000000").option("--provider-payout <amount>", "Wei/token units for partial settlement", "0").action(async (id, opts) => {
|
|
16
16
|
const config = loadConfig(); if (!config.serviceAgreementAddress) throw new Error("serviceAgreementAddress missing in config"); const { signer } = await requireSigner(config); const client = new ServiceAgreementClient(config.serviceAgreementAddress, signer);
|
|
17
17
|
const map: Record<string, ProviderResponseType> = { revise: ProviderResponseType.REVISE, defend: ProviderResponseType.DEFEND, counter: ProviderResponseType.COUNTER, 'partial-settlement': ProviderResponseType.PARTIAL_SETTLEMENT, 'human-review': ProviderResponseType.REQUEST_HUMAN_REVIEW, escalate: ProviderResponseType.ESCALATE };
|
|
18
|
-
const hash = opts.file ? hashFile(opts.file) : hashString(opts.text); await client.respondToRevision(BigInt(id), map[String(opts.type)], hash, opts.uri, opts.previous, BigInt(opts.providerPayout)); console.log(
|
|
18
|
+
const hash = opts.file ? hashFile(opts.file) : hashString(opts.text); await client.respondToRevision(BigInt(id), map[String(opts.type)], hash, opts.uri, opts.previous, BigInt(opts.providerPayout)); console.log(' ' + c.success + c.white(' Response recorded — agreement #' + id));
|
|
19
19
|
});
|
|
20
20
|
remediate.command("status <id>").option("--json").action(async (id, opts) => {
|
|
21
21
|
const config = loadConfig(); if (!config.serviceAgreementAddress) throw new Error("serviceAgreementAddress missing in config"); const { provider } = await getClient(config); const client = new ServiceAgreementClient(config.serviceAgreementAddress, provider);
|
|
@@ -25,7 +25,7 @@ reputation
|
|
|
25
25
|
const oracle = new ReputationOracleClient(config.reputationOracleAddress, signer);
|
|
26
26
|
await oracle.publishSignal(address, ReputationSignalType.WARN, ethers.ZeroHash, opts.reason);
|
|
27
27
|
if (opts.json) return console.log(JSON.stringify({ address, signal: "WARN", reason: opts.reason }, null, 2));
|
|
28
|
-
console.log(
|
|
28
|
+
console.log(' ' + c.warning + c.white(' WARN published against ' + formatAddress(address)));
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
reputation
|
|
@@ -43,7 +43,7 @@ reputation
|
|
|
43
43
|
const oracle = new ReputationOracleClient(config.reputationOracleAddress, signer);
|
|
44
44
|
await oracle.publishSignal(address, ReputationSignalType.BLOCK, ethers.ZeroHash, opts.reason);
|
|
45
45
|
if (opts.json) return console.log(JSON.stringify({ address, signal: "BLOCK", reason: opts.reason }, null, 2));
|
|
46
|
-
console.log(
|
|
46
|
+
console.log(' ' + c.failure + c.white(' BLOCK published against ' + formatAddress(address)));
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
reputation
|
|
@@ -67,9 +67,13 @@ reputation
|
|
|
67
67
|
weightedScore: rep.weightedScore.toString(),
|
|
68
68
|
};
|
|
69
69
|
if (opts.json) return console.log(JSON.stringify(payload, null, 2));
|
|
70
|
-
console.log(
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
console.log('\n ' + c.mark + c.white(' Reputation — ' + formatAddress(address)));
|
|
71
|
+
renderTree([
|
|
72
|
+
{ label: 'Endorsements', value: rep.endorsements.toString() },
|
|
73
|
+
{ label: 'Warnings', value: rep.warnings.toString() },
|
|
74
|
+
{ label: 'Blocks', value: rep.blocks.toString() },
|
|
75
|
+
{ label: 'Score', value: rep.weightedScore.toString(), last: true },
|
|
76
|
+
]);
|
|
73
77
|
});
|
|
74
78
|
|
|
75
79
|
export default reputation;
|
package/src/commands/trust.ts
CHANGED
|
@@ -13,6 +13,15 @@ export function registerTrustCommand(program: Command): void {
|
|
|
13
13
|
const score = await trust.getScore(address); const sponsorship = config.sponsorshipAttestationAddress ? new SponsorshipAttestationClient(config.sponsorshipAttestationAddress, provider) : null; const reputation = config.reputationOracleAddress ? new ReputationOracleClient(config.reputationOracleAddress, provider) : null;
|
|
14
14
|
const highestTier = sponsorship ? await sponsorship.getHighestTier(address) : undefined; const rep = reputation ? await reputation.getReputation(address) : undefined;
|
|
15
15
|
if (opts.json) return console.log(JSON.stringify({ address, score, highestTier, reputation: rep }, (_k, value) => typeof value === 'bigint' ? value.toString() : value, 2));
|
|
16
|
-
console.log(
|
|
16
|
+
console.log('\n ' + c.mark + c.white(' Trust — ' + formatAddress(address)));
|
|
17
|
+
const trustTreeItems: { label: string; value: string; last?: boolean }[] = [
|
|
18
|
+
{ label: 'Score', value: String(score.score) },
|
|
19
|
+
{ label: 'Tier', value: getTrustTier(score.score) },
|
|
20
|
+
{ label: 'Next level', value: String(score.nextLevelAt) },
|
|
21
|
+
];
|
|
22
|
+
if (highestTier !== undefined) trustTreeItems.push({ label: 'Sponsorship', value: identityTierLabel(highestTier) });
|
|
23
|
+
if (rep) trustTreeItems.push({ label: 'Reputation', value: String(rep.weightedScore), last: true });
|
|
24
|
+
else trustTreeItems[trustTreeItems.length - 1].last = true;
|
|
25
|
+
renderTree(trustTreeItems);
|
|
17
26
|
});
|
|
18
27
|
}
|
package/src/commands/verify.ts
CHANGED
|
@@ -31,6 +31,7 @@ export function registerVerifyCommand(program: Command): void {
|
|
|
31
31
|
if (!config.serviceAgreementAddress) throw new Error("serviceAgreementAddress missing in config");
|
|
32
32
|
const { signer } = await requireSigner(config);
|
|
33
33
|
printSenderInfo(config);
|
|
34
|
+
const spinner = startSpinner('Submitting…');
|
|
34
35
|
|
|
35
36
|
// Pre-flight: check agreement is in PENDING_VERIFICATION status (J2-04)
|
|
36
37
|
if (!opts.auto) {
|
|
@@ -64,12 +65,12 @@ export function registerVerifyCommand(program: Command): void {
|
|
|
64
65
|
SERVICE_AGREEMENT_ABI, "autoRelease", [BigInt(id)],
|
|
65
66
|
);
|
|
66
67
|
if (opts.json) return console.log(JSON.stringify({ agreementId: id, action: "autoRelease", txHash: tx.hash }));
|
|
67
|
-
|
|
68
|
+
spinner.succeed('Auto-released — agreement #' + id + ' — tx ' + tx.hash.slice(0, 10) + '...');
|
|
68
69
|
} else {
|
|
69
70
|
const client = new ServiceAgreementClient(config.serviceAgreementAddress, signer);
|
|
70
71
|
const tx = await client.autoRelease(BigInt(id));
|
|
71
72
|
if (opts.json) return console.log(JSON.stringify({ agreementId: id, action: "autoRelease", txHash: tx.hash }));
|
|
72
|
-
|
|
73
|
+
spinner.succeed('Auto-released — agreement #' + id + ' — tx ' + tx.hash.slice(0, 10) + '...');
|
|
73
74
|
}
|
|
74
75
|
} else {
|
|
75
76
|
if (config.walletContractAddress) {
|
|
@@ -78,12 +79,12 @@ export function registerVerifyCommand(program: Command): void {
|
|
|
78
79
|
SERVICE_AGREEMENT_ABI, "verifyDeliverable", [BigInt(id)],
|
|
79
80
|
);
|
|
80
81
|
if (opts.json) return console.log(JSON.stringify({ agreementId: id, action: "verifyDeliverable", txHash: tx.hash }));
|
|
81
|
-
|
|
82
|
+
spinner.succeed('Verified — agreement #' + id + ' — escrow released');
|
|
82
83
|
} else {
|
|
83
84
|
const client = new ServiceAgreementClient(config.serviceAgreementAddress, signer);
|
|
84
85
|
const tx = await client.verifyDeliverable(BigInt(id));
|
|
85
86
|
if (opts.json) return console.log(JSON.stringify({ agreementId: id, action: "verifyDeliverable", txHash: tx.hash }));
|
|
86
|
-
|
|
87
|
+
spinner.succeed('Verified — agreement #' + id + ' — escrow released');
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
});
|