arc402-cli 1.4.50 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/agreements.d.ts.map +1 -1
- package/dist/commands/agreements.js +19 -0
- package/dist/commands/agreements.js.map +1 -1
- package/dist/commands/arena-v2.d.ts.map +1 -1
- package/dist/commands/arena-v2.js +129 -4
- package/dist/commands/arena-v2.js.map +1 -1
- package/dist/commands/auth.d.ts +11 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +188 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/chat.d.ts +3 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +752 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/compute.d.ts.map +1 -1
- package/dist/commands/compute.js +84 -10
- package/dist/commands/compute.js.map +1 -1
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/daemon.js +44 -5
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/discover.d.ts.map +1 -1
- package/dist/commands/discover.js +20 -0
- package/dist/commands/discover.js.map +1 -1
- package/dist/commands/hermes-init.d.ts +1 -1
- package/dist/commands/hermes-init.js +9 -9
- package/dist/commands/hermes-init.js.map +1 -1
- package/dist/commands/hire.d.ts.map +1 -1
- package/dist/commands/hire.js +20 -0
- package/dist/commands/hire.js.map +1 -1
- package/dist/commands/index.d.ts +3 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +74 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/lifecycle.d.ts +3 -0
- package/dist/commands/lifecycle.d.ts.map +1 -0
- package/dist/commands/lifecycle.js +58 -0
- package/dist/commands/lifecycle.js.map +1 -0
- package/dist/commands/security.d.ts +3 -0
- package/dist/commands/security.d.ts.map +1 -0
- package/dist/commands/security.js +44 -0
- package/dist/commands/security.js.map +1 -0
- package/dist/commands/status.d.ts +18 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +179 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/subscription.d.ts +3 -0
- package/dist/commands/subscription.d.ts.map +1 -0
- package/dist/commands/subscription.js +465 -0
- package/dist/commands/subscription.js.map +1 -0
- package/dist/commands/workroom.d.ts.map +1 -1
- package/dist/commands/workroom.js +13 -0
- package/dist/commands/workroom.js.map +1 -1
- package/dist/commerce-client.d.ts +77 -0
- package/dist/commerce-client.d.ts.map +1 -0
- package/dist/commerce-client.js +224 -0
- package/dist/commerce-client.js.map +1 -0
- package/dist/commerce-index.d.ts +39 -0
- package/dist/commerce-index.d.ts.map +1 -0
- package/dist/commerce-index.js +294 -0
- package/dist/commerce-index.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/daemon/config.d.ts +1 -0
- package/dist/daemon/config.d.ts.map +1 -1
- package/dist/daemon/config.js +7 -3
- package/dist/daemon/config.js.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +18 -4
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon-client.d.ts +46 -0
- package/dist/daemon-client.d.ts.map +1 -0
- package/dist/daemon-client.js +80 -0
- package/dist/daemon-client.js.map +1 -0
- package/dist/index.js +40 -34
- package/dist/index.js.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +14 -0
- package/dist/program.js.map +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +61 -58
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/InputLine.d.ts +4 -2
- package/dist/tui/InputLine.d.ts.map +1 -1
- package/dist/tui/InputLine.js +79 -60
- package/dist/tui/InputLine.js.map +1 -1
- package/dist/tui/KernelPayloadRenderer.d.ts +12 -0
- package/dist/tui/KernelPayloadRenderer.d.ts.map +1 -0
- package/dist/tui/KernelPayloadRenderer.js +41 -0
- package/dist/tui/KernelPayloadRenderer.js.map +1 -0
- package/dist/tui/Viewport.d.ts +15 -5
- package/dist/tui/Viewport.d.ts.map +1 -1
- package/dist/tui/Viewport.js +18 -24
- package/dist/tui/Viewport.js.map +1 -1
- package/dist/tui/command-catalog.d.ts +11 -0
- package/dist/tui/command-catalog.d.ts.map +1 -0
- package/dist/tui/command-catalog.js +119 -0
- package/dist/tui/command-catalog.js.map +1 -0
- package/dist/tui/command-renderers.d.ts +33 -0
- package/dist/tui/command-renderers.d.ts.map +1 -0
- package/dist/tui/command-renderers.js +215 -0
- package/dist/tui/command-renderers.js.map +1 -0
- package/dist/tui/commerce-format.d.ts +3 -0
- package/dist/tui/commerce-format.d.ts.map +1 -0
- package/dist/tui/commerce-format.js +19 -0
- package/dist/tui/commerce-format.js.map +1 -0
- package/dist/tui/components/commerce/AgentPicker.d.ts +7 -0
- package/dist/tui/components/commerce/AgentPicker.d.ts.map +1 -0
- package/dist/tui/components/commerce/AgentPicker.js +33 -0
- package/dist/tui/components/commerce/AgentPicker.js.map +1 -0
- package/dist/tui/components/commerce/AgreementList.d.ts +18 -0
- package/dist/tui/components/commerce/AgreementList.d.ts.map +1 -0
- package/dist/tui/components/commerce/AgreementList.js +25 -0
- package/dist/tui/components/commerce/AgreementList.js.map +1 -0
- package/dist/tui/components/commerce/ComputeCard.d.ts +14 -0
- package/dist/tui/components/commerce/ComputeCard.d.ts.map +1 -0
- package/dist/tui/components/commerce/ComputeCard.js +9 -0
- package/dist/tui/components/commerce/ComputeCard.js.map +1 -0
- package/dist/tui/components/commerce/DiscoverList.d.ts +20 -0
- package/dist/tui/components/commerce/DiscoverList.d.ts.map +1 -0
- package/dist/tui/components/commerce/DiscoverList.js +22 -0
- package/dist/tui/components/commerce/DiscoverList.js.map +1 -0
- package/dist/tui/components/commerce/HireCard.d.ts +14 -0
- package/dist/tui/components/commerce/HireCard.d.ts.map +1 -0
- package/dist/tui/components/commerce/HireCard.js +11 -0
- package/dist/tui/components/commerce/HireCard.js.map +1 -0
- package/dist/tui/components/commerce/ProfileCard.d.ts +19 -0
- package/dist/tui/components/commerce/ProfileCard.d.ts.map +1 -0
- package/dist/tui/components/commerce/ProfileCard.js +10 -0
- package/dist/tui/components/commerce/ProfileCard.js.map +1 -0
- package/dist/tui/components/commerce/RoundsList.d.ts +18 -0
- package/dist/tui/components/commerce/RoundsList.d.ts.map +1 -0
- package/dist/tui/components/commerce/RoundsList.js +9 -0
- package/dist/tui/components/commerce/RoundsList.js.map +1 -0
- package/dist/tui/components/commerce/SquadCard.d.ts +25 -0
- package/dist/tui/components/commerce/SquadCard.d.ts.map +1 -0
- package/dist/tui/components/commerce/SquadCard.js +10 -0
- package/dist/tui/components/commerce/SquadCard.js.map +1 -0
- package/dist/tui/components/commerce/StatusCard.d.ts +21 -0
- package/dist/tui/components/commerce/StatusCard.d.ts.map +1 -0
- package/dist/tui/components/commerce/StatusCard.js +10 -0
- package/dist/tui/components/commerce/StatusCard.js.map +1 -0
- package/dist/tui/components/commerce/SubscribeCard.d.ts +13 -0
- package/dist/tui/components/commerce/SubscribeCard.d.ts.map +1 -0
- package/dist/tui/components/commerce/SubscribeCard.js +10 -0
- package/dist/tui/components/commerce/SubscribeCard.js.map +1 -0
- package/dist/tui/components/commerce/WorkroomCard.d.ts +18 -0
- package/dist/tui/components/commerce/WorkroomCard.d.ts.map +1 -0
- package/dist/tui/components/commerce/WorkroomCard.js +10 -0
- package/dist/tui/components/commerce/WorkroomCard.js.map +1 -0
- package/dist/tui/components/commerce/common.d.ts +53 -0
- package/dist/tui/components/commerce/common.d.ts.map +1 -0
- package/dist/tui/components/commerce/common.js +71 -0
- package/dist/tui/components/commerce/common.js.map +1 -0
- package/dist/tui/components/commerce/index.d.ts +11 -0
- package/dist/tui/components/commerce/index.d.ts.map +1 -0
- package/dist/tui/components/commerce/index.js +27 -0
- package/dist/tui/components/commerce/index.js.map +1 -0
- package/dist/tui/hire-interactive.d.ts +13 -0
- package/dist/tui/hire-interactive.d.ts.map +1 -0
- package/dist/tui/hire-interactive.js +157 -0
- package/dist/tui/hire-interactive.js.map +1 -0
- package/dist/tui/kernel-payload.d.ts +45 -0
- package/dist/tui/kernel-payload.d.ts.map +1 -0
- package/dist/tui/kernel-payload.js +8 -0
- package/dist/tui/kernel-payload.js.map +1 -0
- package/dist/tui/kernel.d.ts +6 -0
- package/dist/tui/kernel.d.ts.map +1 -0
- package/dist/tui/kernel.js +791 -0
- package/dist/tui/kernel.js.map +1 -0
- package/dist/tui/render-inline.d.ts +9 -0
- package/dist/tui/render-inline.d.ts.map +1 -0
- package/dist/tui/render-inline.js +32 -0
- package/dist/tui/render-inline.js.map +1 -0
- package/dist/tui/useChat.d.ts.map +1 -1
- package/dist/tui/useChat.js +2 -2
- package/dist/tui/useChat.js.map +1 -1
- package/dist/tui/useCommand.d.ts +2 -2
- package/dist/tui/useCommand.d.ts.map +1 -1
- package/dist/tui/useCommand.js +57 -19
- package/dist/tui/useCommand.js.map +1 -1
- package/dist/tui/useDaemonEvents.d.ts +4 -0
- package/dist/tui/useDaemonEvents.d.ts.map +1 -0
- package/dist/tui/useDaemonEvents.js +69 -0
- package/dist/tui/useDaemonEvents.js.map +1 -0
- package/dist/tui/useTerminalSize.d.ts +11 -0
- package/dist/tui/useTerminalSize.d.ts.map +1 -0
- package/dist/tui/useTerminalSize.js +32 -0
- package/dist/tui/useTerminalSize.js.map +1 -0
- package/dist/tui-esm/App.js +136 -0
- package/dist/tui-esm/App.js.map +1 -0
- package/dist/tui-esm/Footer.js +13 -0
- package/dist/tui-esm/Footer.js.map +1 -0
- package/dist/tui-esm/Header.js +19 -0
- package/dist/tui-esm/Header.js.map +1 -0
- package/dist/tui-esm/InputLine.js +121 -0
- package/dist/tui-esm/InputLine.js.map +1 -0
- package/dist/tui-esm/Viewport.js +39 -0
- package/dist/tui-esm/Viewport.js.map +1 -0
- package/dist/tui-esm/WalletConnectPairing.js +61 -0
- package/dist/tui-esm/WalletConnectPairing.js.map +1 -0
- package/dist/tui-esm/command-catalog.js +20 -0
- package/dist/tui-esm/command-catalog.js.map +1 -0
- package/dist/tui-esm/command-renderers.js +180 -0
- package/dist/tui-esm/command-renderers.js.map +1 -0
- package/dist/tui-esm/commerce-format.js +19 -0
- package/dist/tui-esm/commerce-format.js.map +1 -0
- package/dist/tui-esm/components/Button.js +21 -0
- package/dist/tui-esm/components/Button.js.map +1 -0
- package/dist/tui-esm/components/CeremonyView.js +10 -0
- package/dist/tui-esm/components/CeremonyView.js.map +1 -0
- package/dist/tui-esm/components/CompletionDropdown.js +23 -0
- package/dist/tui-esm/components/CompletionDropdown.js.map +1 -0
- package/dist/tui-esm/components/ConfirmPrompt.js +10 -0
- package/dist/tui-esm/components/ConfirmPrompt.js.map +1 -0
- package/dist/tui-esm/components/CustomTextInput.js +99 -0
- package/dist/tui-esm/components/CustomTextInput.js.map +1 -0
- package/dist/tui-esm/components/InteractiveTable.js +61 -0
- package/dist/tui-esm/components/InteractiveTable.js.map +1 -0
- package/dist/tui-esm/components/StepSpinner.js +32 -0
- package/dist/tui-esm/components/StepSpinner.js.map +1 -0
- package/dist/tui-esm/components/Toast.js +29 -0
- package/dist/tui-esm/components/Toast.js.map +1 -0
- package/dist/tui-esm/components/commerce/AgreementList.js +25 -0
- package/dist/tui-esm/components/commerce/AgreementList.js.map +1 -0
- package/dist/tui-esm/components/commerce/ComputeCard.js +9 -0
- package/dist/tui-esm/components/commerce/ComputeCard.js.map +1 -0
- package/dist/tui-esm/components/commerce/DiscoverList.js +14 -0
- package/dist/tui-esm/components/commerce/DiscoverList.js.map +1 -0
- package/dist/tui-esm/components/commerce/HireCard.js +11 -0
- package/dist/tui-esm/components/commerce/HireCard.js.map +1 -0
- package/dist/tui-esm/components/commerce/RoundsList.js +9 -0
- package/dist/tui-esm/components/commerce/RoundsList.js.map +1 -0
- package/dist/tui-esm/components/commerce/SquadCard.js +10 -0
- package/dist/tui-esm/components/commerce/SquadCard.js.map +1 -0
- package/dist/tui-esm/components/commerce/StatusCard.js +10 -0
- package/dist/tui-esm/components/commerce/StatusCard.js.map +1 -0
- package/dist/tui-esm/components/commerce/SubscribeCard.js +10 -0
- package/dist/tui-esm/components/commerce/SubscribeCard.js.map +1 -0
- package/dist/tui-esm/components/commerce/WorkroomCard.js +10 -0
- package/dist/tui-esm/components/commerce/WorkroomCard.js.map +1 -0
- package/dist/tui-esm/components/commerce/common.js +71 -0
- package/dist/tui-esm/components/commerce/common.js.map +1 -0
- package/dist/tui-esm/components/commerce/index.js +27 -0
- package/dist/tui-esm/components/commerce/index.js.map +1 -0
- package/dist/tui-esm/index.js +55 -0
- package/dist/tui-esm/index.js.map +1 -0
- package/dist/tui-esm/kernel.js +734 -0
- package/dist/tui-esm/kernel.js.map +1 -0
- package/dist/tui-esm/render-inline.js +32 -0
- package/dist/tui-esm/render-inline.js.map +1 -0
- package/dist/tui-esm/useChat.js +91 -0
- package/dist/tui-esm/useChat.js.map +1 -0
- package/dist/tui-esm/useCommand.js +142 -0
- package/dist/tui-esm/useCommand.js.map +1 -0
- package/dist/tui-esm/useNotifications.js +17 -0
- package/dist/tui-esm/useNotifications.js.map +1 -0
- package/dist/tui-esm/useScroll.js +46 -0
- package/dist/tui-esm/useScroll.js.map +1 -0
- package/dist/tui-esm/useTerminalSize.js +32 -0
- package/dist/tui-esm/useTerminalSize.js.map +1 -0
- package/dist/ui/banner.d.ts.map +1 -1
- package/dist/ui/banner.js +46 -2
- package/dist/ui/banner.js.map +1 -1
- package/hermes/DELIVERY-SPEC.md +219 -0
- package/hermes/HERMES-INTEGRATION-SPEC.md +338 -0
- package/hermes/plugins/arc402_hermes/__init__.py +5 -0
- package/hermes/plugins/arc402_hermes/plugin.py +489 -0
- package/hermes/plugins/arc402_hermes/py.typed +0 -0
- package/hermes/plugins/arc402_hermes.egg-info/PKG-INFO +24 -0
- package/hermes/plugins/arc402_hermes.egg-info/SOURCES.txt +10 -0
- package/hermes/plugins/arc402_hermes.egg-info/dependency_links.txt +1 -0
- package/hermes/plugins/arc402_hermes.egg-info/entry_points.txt +2 -0
- package/hermes/plugins/arc402_hermes.egg-info/requires.txt +5 -0
- package/hermes/plugins/arc402_hermes.egg-info/top_level.txt +1 -0
- package/hermes/plugins/arc402_plugin.py +489 -0
- package/hermes/plugins/dist/arc402_hermes-1.0.0-py3-none-any.whl +0 -0
- package/hermes/plugins/dist/arc402_hermes-1.0.0.tar.gz +0 -0
- package/hermes/plugins/pyproject.toml +47 -0
- package/hermes/skills/arc402-agent/SKILL.md +559 -0
- package/hermes/workroom/README.md +174 -0
- package/hermes/workroom/hermes-daemon.toml +21 -0
- package/hermes/workroom/hermes-worker/IDENTITY.md +44 -0
- package/hermes/workroom/hermes-worker/SOUL.md +45 -0
- package/hermes/workroom/hermes-worker/config.json +32 -0
- package/hermes/workroom/hermes-worker/datasets/.gitkeep +0 -0
- package/hermes/workroom/hermes-worker/knowledge/.gitkeep +0 -0
- package/hermes/workroom/hermes-worker/memory/learnings.md +9 -0
- package/hermes/workroom/hermes-worker/skills/.gitkeep +0 -0
- package/package.json +9 -3
- package/README.md +0 -288
|
@@ -0,0 +1,791 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
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.getTuiTopLevelCommands = getTuiTopLevelCommands;
|
|
37
|
+
exports.getTuiSubCommands = getTuiSubCommands;
|
|
38
|
+
exports.executeKernelForPayload = executeKernelForPayload;
|
|
39
|
+
exports.executeTuiKernel = executeTuiKernel;
|
|
40
|
+
const sdk_1 = require("@arc402/sdk");
|
|
41
|
+
const ethers_1 = require("ethers");
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const commerce_client_1 = require("../commerce-client");
|
|
45
|
+
const config_1 = require("../config");
|
|
46
|
+
const client_1 = require("../client");
|
|
47
|
+
const format_1 = require("../utils/format");
|
|
48
|
+
const config_2 = require("../daemon/config");
|
|
49
|
+
const command_renderers_1 = require("./command-renderers");
|
|
50
|
+
function readConfiguredWallet() {
|
|
51
|
+
if (fs.existsSync(config_2.DAEMON_TOML)) {
|
|
52
|
+
try {
|
|
53
|
+
const wallet = (0, config_2.loadDaemonConfig)().wallet.contract_address.trim();
|
|
54
|
+
if (wallet)
|
|
55
|
+
return wallet;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// ignore
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if ((0, config_1.configExists)()) {
|
|
62
|
+
try {
|
|
63
|
+
return (0, config_1.loadConfig)().walletContractAddress?.trim() || undefined;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// ignore
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
function renderDaemonGuidance(target) {
|
|
72
|
+
if (target.mode !== "local") {
|
|
73
|
+
return [
|
|
74
|
+
"Next steps:",
|
|
75
|
+
" 1. Confirm the remote daemon URL is correct and reachable.",
|
|
76
|
+
" 2. Re-run `arc402 chat --setup` if you want to switch back to a local node.",
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
const lines = ["Next steps:"];
|
|
80
|
+
if (!fs.existsSync(config_2.DAEMON_TOML)) {
|
|
81
|
+
lines.push(" 1. Run `arc402 daemon init` or `arc402 setup` to create ~/.arc402/daemon.toml.");
|
|
82
|
+
lines.push(" 2. Fill in wallet + node settings, then start the node with `arc402 daemon start`.");
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
lines.push(" 1. Start the local node with `arc402 daemon start`.");
|
|
86
|
+
lines.push(" 2. If it exits immediately, inspect `arc402 daemon logs` for the startup guidance.");
|
|
87
|
+
}
|
|
88
|
+
lines.push(" 3. Run `arc402 chat --setup` and choose Remote if this machine should not host the node.");
|
|
89
|
+
return lines;
|
|
90
|
+
}
|
|
91
|
+
const CAPABILITY_REGISTRY_EXTRA_ABI = [
|
|
92
|
+
"function getAgentsWithCapability(string calldata capability) external view returns (address[])",
|
|
93
|
+
];
|
|
94
|
+
function normalise(values) {
|
|
95
|
+
const min = Math.min(...values);
|
|
96
|
+
const max = Math.max(...values);
|
|
97
|
+
const range = max - min;
|
|
98
|
+
if (range === 0)
|
|
99
|
+
return values.map(() => 1);
|
|
100
|
+
return values.map((v) => (v - min) / range);
|
|
101
|
+
}
|
|
102
|
+
function computeCompositeScores(agents) {
|
|
103
|
+
if (agents.length === 0)
|
|
104
|
+
return [];
|
|
105
|
+
const trustVals = normalise(agents.map((a) => a.trustScore));
|
|
106
|
+
const stakeVals = normalise(agents.map((a) => Number(a.stake)));
|
|
107
|
+
const jobsVals = normalise(agents.map((a) => a.completedJobs));
|
|
108
|
+
const rawPrices = agents.map((a) => (a.priceUsd !== null ? a.priceUsd : -1));
|
|
109
|
+
const validPrices = rawPrices.filter((p) => p >= 0);
|
|
110
|
+
const maxPrice = validPrices.length > 0 ? Math.max(...validPrices) : 1;
|
|
111
|
+
const priceInvVals = rawPrices.map((p) => (p < 0 ? 0.5 : maxPrice > 0 ? 1 - p / maxPrice : 1));
|
|
112
|
+
return agents.map((agent, i) => ({
|
|
113
|
+
...agent,
|
|
114
|
+
compositeScore: trustVals[i] * 0.5 + stakeVals[i] * 0.2 + jobsVals[i] * 0.2 + priceInvVals[i] * 0.1,
|
|
115
|
+
rank: 0,
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
async function pingEndpoint(endpoint) {
|
|
119
|
+
if (!endpoint || !/^https?:\/\//.test(endpoint))
|
|
120
|
+
return "offline";
|
|
121
|
+
try {
|
|
122
|
+
const ctrl = new AbortController();
|
|
123
|
+
const tid = setTimeout(() => ctrl.abort(), 3000);
|
|
124
|
+
const resp = await fetch(`${endpoint.replace(/\/$/, "")}/health`, { signal: ctrl.signal });
|
|
125
|
+
clearTimeout(tid);
|
|
126
|
+
return resp.ok ? "online" : "offline";
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return "offline";
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function parseTokens(input) {
|
|
133
|
+
const tokens = [];
|
|
134
|
+
let current = "";
|
|
135
|
+
let inQuote = false;
|
|
136
|
+
let quoteChar = "";
|
|
137
|
+
let escape = false;
|
|
138
|
+
for (const ch of input) {
|
|
139
|
+
if (escape) {
|
|
140
|
+
current += ch;
|
|
141
|
+
escape = false;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (inQuote) {
|
|
145
|
+
if (quoteChar === '"' && ch === "\\") {
|
|
146
|
+
escape = true;
|
|
147
|
+
}
|
|
148
|
+
else if (ch === quoteChar) {
|
|
149
|
+
inQuote = false;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
current += ch;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else if (ch === '"' || ch === "'") {
|
|
156
|
+
inQuote = true;
|
|
157
|
+
quoteChar = ch;
|
|
158
|
+
}
|
|
159
|
+
else if (/\s/.test(ch)) {
|
|
160
|
+
if (current) {
|
|
161
|
+
tokens.push(current);
|
|
162
|
+
current = "";
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
current += ch;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (current)
|
|
170
|
+
tokens.push(current);
|
|
171
|
+
return tokens;
|
|
172
|
+
}
|
|
173
|
+
function readWorkroomStatusSnapshot() {
|
|
174
|
+
const policyFile = path.join(config_2.DAEMON_DIR, "openshell-policy.yaml");
|
|
175
|
+
let policyHash = "n/a";
|
|
176
|
+
if (fs.existsSync(policyFile)) {
|
|
177
|
+
const content = fs.readFileSync(policyFile, "utf-8");
|
|
178
|
+
const crypto = require("crypto");
|
|
179
|
+
policyHash = "0x" + crypto.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
180
|
+
}
|
|
181
|
+
const workerConfigPath = path.join(config_2.DAEMON_DIR, "worker", "config.json");
|
|
182
|
+
let harness = "arc";
|
|
183
|
+
if (fs.existsSync(workerConfigPath)) {
|
|
184
|
+
try {
|
|
185
|
+
const workerConfig = JSON.parse(fs.readFileSync(workerConfigPath, "utf-8"));
|
|
186
|
+
harness = workerConfig.harness ?? harness;
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// ignore
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const daemonLog = path.join(config_2.DAEMON_DIR, "daemon.log");
|
|
193
|
+
const statusLabel = fs.existsSync(daemonLog) ? "healthy" : "idle";
|
|
194
|
+
return {
|
|
195
|
+
statusLabel,
|
|
196
|
+
harness,
|
|
197
|
+
policyHash,
|
|
198
|
+
queueDepth: 0,
|
|
199
|
+
runtime: "arc402-workroom",
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function getTuiTopLevelCommands() {
|
|
203
|
+
return ["status", "discover", "agreements", "workroom", "subscription", "subscribe", "arena"];
|
|
204
|
+
}
|
|
205
|
+
function getTuiSubCommands() {
|
|
206
|
+
return new Map([
|
|
207
|
+
["workroom", ["status", "worker"]],
|
|
208
|
+
["subscription", ["status", "list", "cancel", "topup"]],
|
|
209
|
+
["arena", ["rounds", "squad"]],
|
|
210
|
+
["squad", ["list", "info"]],
|
|
211
|
+
]);
|
|
212
|
+
}
|
|
213
|
+
async function renderKernelPayload(payload) {
|
|
214
|
+
switch (payload.type) {
|
|
215
|
+
case "status":
|
|
216
|
+
await (0, command_renderers_1.printStatusCard)(payload.props);
|
|
217
|
+
if (payload.guidance?.length) {
|
|
218
|
+
const { writeTuiLine } = await Promise.resolve().then(() => __importStar(require("./render-inline")));
|
|
219
|
+
for (const line of payload.guidance)
|
|
220
|
+
writeTuiLine(line);
|
|
221
|
+
}
|
|
222
|
+
break;
|
|
223
|
+
case "discover":
|
|
224
|
+
await (0, command_renderers_1.printDiscoverList)(payload.props);
|
|
225
|
+
break;
|
|
226
|
+
case "agreements":
|
|
227
|
+
await (0, command_renderers_1.printAgreementList)(payload.props);
|
|
228
|
+
break;
|
|
229
|
+
case "workroom":
|
|
230
|
+
await (0, command_renderers_1.printWorkroomCard)(payload.props);
|
|
231
|
+
break;
|
|
232
|
+
case "subscribe":
|
|
233
|
+
await (0, command_renderers_1.printSubscribeCard)(payload.props);
|
|
234
|
+
break;
|
|
235
|
+
case "rounds":
|
|
236
|
+
await (0, command_renderers_1.printRoundsList)(payload.props);
|
|
237
|
+
break;
|
|
238
|
+
case "squad":
|
|
239
|
+
await (0, command_renderers_1.printSquadCard)(payload.props);
|
|
240
|
+
break;
|
|
241
|
+
case "squads":
|
|
242
|
+
for (const card of payload.cards) {
|
|
243
|
+
await (0, command_renderers_1.printSquadCard)(card);
|
|
244
|
+
const { writeTuiLine } = await Promise.resolve().then(() => __importStar(require("./render-inline")));
|
|
245
|
+
writeTuiLine("");
|
|
246
|
+
}
|
|
247
|
+
break;
|
|
248
|
+
case "not_found":
|
|
249
|
+
case "error": {
|
|
250
|
+
const { writeTuiLine } = await Promise.resolve().then(() => __importStar(require("./render-inline")));
|
|
251
|
+
writeTuiLine(payload.message);
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async function executeKernelForPayload(input) {
|
|
257
|
+
const tokens = parseTokens(input);
|
|
258
|
+
if (tokens.length === 0)
|
|
259
|
+
return null;
|
|
260
|
+
if (tokens[0] === "status") {
|
|
261
|
+
return fetchStatusProps(tokens.slice(1));
|
|
262
|
+
}
|
|
263
|
+
if (tokens[0] === "discover") {
|
|
264
|
+
return fetchDiscoverProps(tokens.slice(1));
|
|
265
|
+
}
|
|
266
|
+
if (tokens[0] === "agreements") {
|
|
267
|
+
return fetchAgreementsProps(tokens.slice(1));
|
|
268
|
+
}
|
|
269
|
+
if (tokens[0] === "workroom" && tokens[1] === "status") {
|
|
270
|
+
return fetchWorkroomStatusProps();
|
|
271
|
+
}
|
|
272
|
+
if (tokens[0] === "subscription") {
|
|
273
|
+
return fetchSubscriptionProps(tokens.slice(1));
|
|
274
|
+
}
|
|
275
|
+
if (tokens[0] === "subscribe") {
|
|
276
|
+
return fetchSubscribeInspectProps(tokens.slice(1));
|
|
277
|
+
}
|
|
278
|
+
if (tokens[0] === "arena" && tokens[1] === "rounds") {
|
|
279
|
+
return fetchArenaRoundsProps(tokens.slice(2));
|
|
280
|
+
}
|
|
281
|
+
if (tokens[0] === "arena" && tokens[1] === "squad" && tokens[2] === "list") {
|
|
282
|
+
return fetchArenaSquadListProps(tokens.slice(3));
|
|
283
|
+
}
|
|
284
|
+
if (tokens[0] === "arena" && tokens[1] === "squad" && tokens[2] === "info" && tokens[3]) {
|
|
285
|
+
return fetchArenaSquadInfoProps(tokens[3]);
|
|
286
|
+
}
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
async function executeTuiKernel(input) {
|
|
290
|
+
const payload = await executeKernelForPayload(input);
|
|
291
|
+
if (payload === null)
|
|
292
|
+
return false;
|
|
293
|
+
await renderKernelPayload(payload);
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
async function fetchStatusProps(args) {
|
|
297
|
+
const daemonUrlIndex = args.indexOf("--daemon-url");
|
|
298
|
+
const baseUrl = daemonUrlIndex >= 0 ? args[daemonUrlIndex + 1] : undefined;
|
|
299
|
+
const target = (0, commerce_client_1.resolveChatDaemonTarget)({ explicitBaseUrl: baseUrl });
|
|
300
|
+
try {
|
|
301
|
+
const [health, wallet, workroom, agreements] = await Promise.all([
|
|
302
|
+
(0, commerce_client_1.fetchDaemonHealth)({ baseUrl: target.baseUrl }),
|
|
303
|
+
(0, commerce_client_1.fetchDaemonWalletStatus)({ baseUrl: target.baseUrl }),
|
|
304
|
+
(0, commerce_client_1.fetchDaemonWorkroomStatus)({ baseUrl: target.baseUrl }),
|
|
305
|
+
(0, commerce_client_1.fetchDaemonAgreements)({ baseUrl: target.baseUrl }),
|
|
306
|
+
]);
|
|
307
|
+
const active = agreements.agreements.filter((agreement) => {
|
|
308
|
+
const status = String((agreement.status ?? agreement.state ?? "")).toLowerCase();
|
|
309
|
+
return status.includes("accept") || status.includes("active") || status.includes("proposed");
|
|
310
|
+
}).length;
|
|
311
|
+
const pendingVerification = agreements.agreements.filter((agreement) => {
|
|
312
|
+
const status = String((agreement.status ?? agreement.state ?? "")).toLowerCase();
|
|
313
|
+
return status.includes("verify") || status.includes("pending");
|
|
314
|
+
}).length;
|
|
315
|
+
const disputed = agreements.agreements.filter((agreement) => String((agreement.status ?? agreement.state ?? "")).toLowerCase().includes("disput")).length;
|
|
316
|
+
return {
|
|
317
|
+
type: "status",
|
|
318
|
+
props: {
|
|
319
|
+
wallet: wallet.wallet,
|
|
320
|
+
network: `chain ${wallet.chainId}`,
|
|
321
|
+
balance: target.mode === "local" ? target.baseUrl : `${target.mode} · ${target.baseUrl}`,
|
|
322
|
+
endpoint: wallet.rpcUrl,
|
|
323
|
+
agreements: { active, pendingVerification, disputed },
|
|
324
|
+
workroom: { status: workroom.status },
|
|
325
|
+
status: { label: health.ok ? "online" : "offline", tone: health.ok ? "success" : "danger" },
|
|
326
|
+
},
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
331
|
+
const fallbackWallet = readConfiguredWallet();
|
|
332
|
+
const daemonState = target.mode === "local"
|
|
333
|
+
? fs.existsSync(config_2.DAEMON_TOML)
|
|
334
|
+
? "configured locally but not responding"
|
|
335
|
+
: "not configured on this machine"
|
|
336
|
+
: "remote node unreachable";
|
|
337
|
+
return {
|
|
338
|
+
type: "status",
|
|
339
|
+
props: {
|
|
340
|
+
wallet: fallbackWallet ?? "not configured",
|
|
341
|
+
network: `${target.mode} node`,
|
|
342
|
+
balance: target.baseUrl,
|
|
343
|
+
endpoint: message,
|
|
344
|
+
workroom: { status: "waiting for daemon context" },
|
|
345
|
+
status: { label: daemonState, tone: "warning" },
|
|
346
|
+
},
|
|
347
|
+
guidance: renderDaemonGuidance(target),
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
async function fetchDiscoverProps(args) {
|
|
352
|
+
const config = (0, config_1.loadConfig)();
|
|
353
|
+
if (!config.agentRegistryAddress)
|
|
354
|
+
throw new Error("agentRegistryAddress missing in config");
|
|
355
|
+
const { provider } = await (0, client_1.getClient)(config);
|
|
356
|
+
const registryMod = await Promise.resolve().then(() => __importStar(require("@arc402/sdk")));
|
|
357
|
+
const registry = new registryMod.AgentRegistryClient(config.agentRegistryAddress, provider);
|
|
358
|
+
const capabilitySDK = config.capabilityRegistryAddress
|
|
359
|
+
? new registryMod.CapabilityRegistryClient(config.capabilityRegistryAddress, provider)
|
|
360
|
+
: null;
|
|
361
|
+
const sponsorship = config.sponsorshipAttestationAddress
|
|
362
|
+
? new registryMod.SponsorshipAttestationClient(config.sponsorshipAttestationAddress, provider)
|
|
363
|
+
: null;
|
|
364
|
+
const reputation = config.reputationOracleAddress
|
|
365
|
+
? new registryMod.ReputationOracleClient(config.reputationOracleAddress, provider)
|
|
366
|
+
: null;
|
|
367
|
+
const opts = {
|
|
368
|
+
capability: readFlag(args, "--capability"),
|
|
369
|
+
capabilityPrefix: readFlag(args, "--capability-prefix"),
|
|
370
|
+
serviceType: readFlag(args, "--service-type") ?? readFlag(args, "--type"),
|
|
371
|
+
minTrust: Number(readFlag(args, "--min-trust") ?? "0"),
|
|
372
|
+
maxPrice: Number(readFlag(args, "--max-price") ?? "0"),
|
|
373
|
+
minStake: BigInt(readFlag(args, "--min-stake") ?? "0"),
|
|
374
|
+
top: readFlag(args, "--top"),
|
|
375
|
+
sort: readFlag(args, "--sort") ?? "composite",
|
|
376
|
+
limit: Number(readFlag(args, "--limit") ?? "20"),
|
|
377
|
+
online: args.includes("--online"),
|
|
378
|
+
};
|
|
379
|
+
const effectiveSort = opts.top ? "trust" : opts.sort;
|
|
380
|
+
const limit = opts.top ? Number(opts.top) : opts.limit;
|
|
381
|
+
let candidateAddresses = null;
|
|
382
|
+
if (opts.capability && config.capabilityRegistryAddress) {
|
|
383
|
+
const capContract = new ethers_1.ethers.Contract(config.capabilityRegistryAddress, CAPABILITY_REGISTRY_EXTRA_ABI, provider);
|
|
384
|
+
try {
|
|
385
|
+
candidateAddresses = await capContract.getAgentsWithCapability(opts.capability);
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
candidateAddresses = null;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
let agentInfos;
|
|
392
|
+
if (candidateAddresses !== null) {
|
|
393
|
+
const results = await Promise.allSettled(candidateAddresses.map((addr) => registry.getAgent(addr)));
|
|
394
|
+
agentInfos = results
|
|
395
|
+
.filter((r) => r.status === "fulfilled")
|
|
396
|
+
.map((r) => r.value);
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
agentInfos = await registry.listAgents(limit * 10);
|
|
400
|
+
}
|
|
401
|
+
let filtered = agentInfos.filter((a) => a.active !== false);
|
|
402
|
+
if (opts.capability)
|
|
403
|
+
filtered = filtered.filter((a) => a.capabilities.some((c) => c === opts.capability));
|
|
404
|
+
if (opts.capabilityPrefix)
|
|
405
|
+
filtered = filtered.filter((a) => a.capabilities.some((c) => c.startsWith(opts.capabilityPrefix)));
|
|
406
|
+
if (opts.serviceType)
|
|
407
|
+
filtered = filtered.filter((a) => a.serviceType.toLowerCase().includes(String(opts.serviceType).toLowerCase()));
|
|
408
|
+
filtered = filtered.filter((a) => Number(a.trustScore ?? 0n) >= opts.minTrust);
|
|
409
|
+
if (opts.minStake > 0n) {
|
|
410
|
+
filtered = filtered.filter((a) => BigInt(a.stake ?? 0n) >= opts.minStake);
|
|
411
|
+
}
|
|
412
|
+
const enriched = await Promise.all(filtered.slice(0, limit * 5).map(async (agent) => {
|
|
413
|
+
const [operational, canonicalCapabilities, rep] = await Promise.all([
|
|
414
|
+
registry.getOperationalMetrics(agent.wallet),
|
|
415
|
+
capabilitySDK ? capabilitySDK.getCapabilities(agent.wallet) : Promise.resolve([]),
|
|
416
|
+
reputation ? reputation.getReputation(agent.wallet) : Promise.resolve(undefined),
|
|
417
|
+
sponsorship ? sponsorship.getHighestTier(agent.wallet) : Promise.resolve(undefined),
|
|
418
|
+
]);
|
|
419
|
+
let priceUsd = null;
|
|
420
|
+
if (agent.metadataURI && /^https?:\/\//.test(agent.metadataURI)) {
|
|
421
|
+
try {
|
|
422
|
+
const ctrl = new AbortController();
|
|
423
|
+
const tid = setTimeout(() => ctrl.abort(), 2000);
|
|
424
|
+
const resp = await fetch(agent.metadataURI, { signal: ctrl.signal });
|
|
425
|
+
clearTimeout(tid);
|
|
426
|
+
if (resp.ok) {
|
|
427
|
+
const meta = await resp.json();
|
|
428
|
+
if (meta.pricing?.priceUsd != null)
|
|
429
|
+
priceUsd = meta.pricing.priceUsd;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
// ignore
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if (opts.maxPrice > 0 && priceUsd !== null && priceUsd > opts.maxPrice)
|
|
437
|
+
return null;
|
|
438
|
+
const repObj = rep && typeof rep === "object" ? rep : {};
|
|
439
|
+
return {
|
|
440
|
+
wallet: agent.wallet,
|
|
441
|
+
name: agent.name,
|
|
442
|
+
serviceType: agent.serviceType,
|
|
443
|
+
endpoint: agent.endpoint,
|
|
444
|
+
metadataURI: agent.metadataURI,
|
|
445
|
+
capabilities: agent.capabilities,
|
|
446
|
+
canonicalCapabilities: canonicalCapabilities,
|
|
447
|
+
trustScore: Number(agent.trustScore ?? 0n),
|
|
448
|
+
stake: agent.stake ?? 0n,
|
|
449
|
+
completedJobs: Number(repObj.completedJobs ?? 0),
|
|
450
|
+
priceUsd,
|
|
451
|
+
compositeScore: 0,
|
|
452
|
+
rank: 0,
|
|
453
|
+
operational: {
|
|
454
|
+
uptimeScore: Number(operational.uptimeScore),
|
|
455
|
+
responseScore: Number(operational.responseScore),
|
|
456
|
+
},
|
|
457
|
+
};
|
|
458
|
+
}));
|
|
459
|
+
let scored = computeCompositeScores(enriched.filter((a) => a !== null));
|
|
460
|
+
switch (effectiveSort) {
|
|
461
|
+
case "trust":
|
|
462
|
+
scored.sort((a, b) => b.trustScore - a.trustScore);
|
|
463
|
+
break;
|
|
464
|
+
case "price":
|
|
465
|
+
scored.sort((a, b) => {
|
|
466
|
+
if (a.priceUsd === null && b.priceUsd === null)
|
|
467
|
+
return 0;
|
|
468
|
+
if (a.priceUsd === null)
|
|
469
|
+
return 1;
|
|
470
|
+
if (b.priceUsd === null)
|
|
471
|
+
return -1;
|
|
472
|
+
return a.priceUsd - b.priceUsd;
|
|
473
|
+
});
|
|
474
|
+
break;
|
|
475
|
+
case "jobs":
|
|
476
|
+
scored.sort((a, b) => b.completedJobs - a.completedJobs);
|
|
477
|
+
break;
|
|
478
|
+
case "stake":
|
|
479
|
+
scored.sort((a, b) => (b.stake > a.stake ? 1 : b.stake < a.stake ? -1 : 0));
|
|
480
|
+
break;
|
|
481
|
+
default:
|
|
482
|
+
scored.sort((a, b) => b.compositeScore - a.compositeScore);
|
|
483
|
+
}
|
|
484
|
+
scored = scored.slice(0, limit).map((a, i) => ({ ...a, rank: i + 1 }));
|
|
485
|
+
let withStatus = await Promise.all(scored.map(async (agent) => ({
|
|
486
|
+
...agent,
|
|
487
|
+
endpointStatus: agent.endpoint ? await pingEndpoint(agent.endpoint) : "unknown",
|
|
488
|
+
})));
|
|
489
|
+
if (opts.online)
|
|
490
|
+
withStatus = withStatus.filter((a) => a.endpointStatus === "online");
|
|
491
|
+
const onlineCount = withStatus.filter((a) => a.endpointStatus === "online").length;
|
|
492
|
+
return {
|
|
493
|
+
type: "discover",
|
|
494
|
+
props: {
|
|
495
|
+
summary: `${withStatus.length} agent${withStatus.length === 1 ? "" : "s"} · ${onlineCount} online`,
|
|
496
|
+
status: { label: effectiveSort, tone: "info" },
|
|
497
|
+
agents: withStatus.map((agent) => ({
|
|
498
|
+
rank: agent.rank,
|
|
499
|
+
name: agent.name,
|
|
500
|
+
wallet: agent.wallet,
|
|
501
|
+
serviceType: agent.serviceType,
|
|
502
|
+
trustScore: agent.trustScore,
|
|
503
|
+
compositeScore: agent.compositeScore,
|
|
504
|
+
endpointStatus: agent.endpointStatus,
|
|
505
|
+
capabilitySummary: (agent.canonicalCapabilities.length ? agent.canonicalCapabilities : agent.capabilities).slice(0, 3).join(", ") || "none",
|
|
506
|
+
priceLabel: agent.priceUsd === null ? undefined : `$${agent.priceUsd}`,
|
|
507
|
+
})),
|
|
508
|
+
},
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
async function fetchAgreementsProps(args) {
|
|
512
|
+
const asIndex = args.indexOf("--as");
|
|
513
|
+
const role = asIndex >= 0 ? (args[asIndex + 1] ?? "client") : "client";
|
|
514
|
+
const config = (0, config_1.loadConfig)();
|
|
515
|
+
if (!config.serviceAgreementAddress)
|
|
516
|
+
throw new Error("serviceAgreementAddress missing in config");
|
|
517
|
+
const { provider, address } = await (0, client_1.getClient)(config);
|
|
518
|
+
if (!address)
|
|
519
|
+
throw new Error("No wallet configured");
|
|
520
|
+
const client = new sdk_1.ServiceAgreementClient(config.serviceAgreementAddress, provider);
|
|
521
|
+
const agreements = role === "provider"
|
|
522
|
+
? await client.getProviderAgreements(address)
|
|
523
|
+
: await client.getClientAgreements(address);
|
|
524
|
+
const totalEscrowWei = agreements.reduce((sum, agreement) => sum + BigInt(agreement.price ?? 0n), 0n);
|
|
525
|
+
return {
|
|
526
|
+
type: "agreements",
|
|
527
|
+
props: {
|
|
528
|
+
roleLabel: role === "provider" ? "Provider Agreements" : "Client Agreements",
|
|
529
|
+
totalEscrowLabel: `${totalEscrowWei.toString()} wei escrowed`,
|
|
530
|
+
status: { label: `${agreements.length} total`, tone: "info" },
|
|
531
|
+
agreements: agreements.map((agreement) => ({
|
|
532
|
+
id: agreement.id.toString(),
|
|
533
|
+
counterparty: role === "provider" ? agreement.client : agreement.provider,
|
|
534
|
+
serviceType: agreement.serviceType,
|
|
535
|
+
status: (0, format_1.agreementStatusLabel)(agreement.status),
|
|
536
|
+
deadlineMinutes: Math.max(0, Math.round((Number(agreement.deadline) - Math.floor(Date.now() / 1000)) / 60)),
|
|
537
|
+
price: `${BigInt(agreement.price ?? 0n).toString()} wei`,
|
|
538
|
+
})),
|
|
539
|
+
},
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
async function fetchWorkroomStatusProps() {
|
|
543
|
+
const snapshot = readWorkroomStatusSnapshot();
|
|
544
|
+
return { type: "workroom", props: snapshot };
|
|
545
|
+
}
|
|
546
|
+
async function fetchSubscriptionProps(args) {
|
|
547
|
+
const sub = args[0] ?? "status";
|
|
548
|
+
const id = args[1];
|
|
549
|
+
const months = Number.parseInt(readFlag(args, "--months") ?? "1", 10);
|
|
550
|
+
if (sub === "status") {
|
|
551
|
+
return {
|
|
552
|
+
type: "subscribe",
|
|
553
|
+
props: {
|
|
554
|
+
provider: `subscription ${id ?? "unknown"}`,
|
|
555
|
+
planId: "status",
|
|
556
|
+
rateLabel: "pending query binding",
|
|
557
|
+
accessSummary: ["Contract/subgraph lookup pending"],
|
|
558
|
+
status: { label: "scaffold", tone: "warning" },
|
|
559
|
+
},
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
if (sub === "list") {
|
|
563
|
+
return {
|
|
564
|
+
type: "subscribe",
|
|
565
|
+
props: {
|
|
566
|
+
provider: "subscriptions",
|
|
567
|
+
planId: "list",
|
|
568
|
+
rateLabel: "query source pending",
|
|
569
|
+
accessSummary: ["List query scaffolding only"],
|
|
570
|
+
status: { label: "scaffold", tone: "warning" },
|
|
571
|
+
},
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
if (sub === "cancel") {
|
|
575
|
+
return {
|
|
576
|
+
type: "subscribe",
|
|
577
|
+
props: {
|
|
578
|
+
provider: `subscription ${id ?? "unknown"}`,
|
|
579
|
+
planId: "cancel",
|
|
580
|
+
rateLabel: "write path deferred",
|
|
581
|
+
accessSummary: ["Cancellation intentionally not wired in this phase"],
|
|
582
|
+
status: { label: "deferred", tone: "warning" },
|
|
583
|
+
},
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
if (sub === "topup") {
|
|
587
|
+
return {
|
|
588
|
+
type: "subscribe",
|
|
589
|
+
props: {
|
|
590
|
+
provider: `subscription ${id ?? "unknown"}`,
|
|
591
|
+
planId: "topup",
|
|
592
|
+
rateLabel: `+${months} months`,
|
|
593
|
+
months,
|
|
594
|
+
accessSummary: ["Top-up command shape is staged"],
|
|
595
|
+
status: { label: "scaffold", tone: "warning" },
|
|
596
|
+
},
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
throw new Error(`Unsupported subscription subcommand: ${sub}`);
|
|
600
|
+
}
|
|
601
|
+
async function fetchSubscribeInspectProps(args) {
|
|
602
|
+
const endpoint = args[0];
|
|
603
|
+
if (!endpoint)
|
|
604
|
+
throw new Error("subscribe requires an endpoint");
|
|
605
|
+
const inspection = await (0, commerce_client_1.inspectCommerceEndpoint)(endpoint);
|
|
606
|
+
const months = Number.parseInt(readFlag(args, "--months") ?? "1", 10);
|
|
607
|
+
const plan = readFlag(args, "--plan") ?? inspection.subscription?.plan ?? "unspecified";
|
|
608
|
+
return {
|
|
609
|
+
type: "subscribe",
|
|
610
|
+
props: {
|
|
611
|
+
provider: endpoint,
|
|
612
|
+
planId: plan,
|
|
613
|
+
rateLabel: inspection.subscription?.rate ?? inspection.x402?.amount ?? "n/a",
|
|
614
|
+
months,
|
|
615
|
+
paymentOptions: inspection.paymentOptions,
|
|
616
|
+
accessSummary: [inspection.subscription?.endpoint ?? endpoint, inspection.x402?.description ?? "read-only scaffold"],
|
|
617
|
+
status: { label: inspection.paymentRequired ? "payment required" : "inspect", tone: inspection.paymentRequired ? "warning" : "info" },
|
|
618
|
+
},
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
const ARENA_SUBGRAPH_URL = "https://api.studio.thegraph.com/query/1744310/arc-402/v0.3.0";
|
|
622
|
+
async function arenaGql(query) {
|
|
623
|
+
const res = await fetch(ARENA_SUBGRAPH_URL, {
|
|
624
|
+
method: "POST",
|
|
625
|
+
headers: { "Content-Type": "application/json" },
|
|
626
|
+
body: JSON.stringify({ query }),
|
|
627
|
+
});
|
|
628
|
+
if (!res.ok)
|
|
629
|
+
throw new Error(`Subgraph HTTP ${res.status}`);
|
|
630
|
+
const json = (await res.json());
|
|
631
|
+
if (json.errors?.length)
|
|
632
|
+
throw new Error(`Subgraph error: ${JSON.stringify(json.errors[0])}`);
|
|
633
|
+
return json.data ?? {};
|
|
634
|
+
}
|
|
635
|
+
function separator() {
|
|
636
|
+
return "─".repeat(60);
|
|
637
|
+
}
|
|
638
|
+
function formatSquadId(id) {
|
|
639
|
+
return `squad-0x${Number(id).toString(16)}`;
|
|
640
|
+
}
|
|
641
|
+
function parseSquadId(s) {
|
|
642
|
+
if (s.startsWith("squad-0x"))
|
|
643
|
+
return BigInt("0x" + s.slice(8));
|
|
644
|
+
return BigInt(s);
|
|
645
|
+
}
|
|
646
|
+
function truncateAddr(addr) {
|
|
647
|
+
return `${addr.slice(0, 6)}…${addr.slice(-4)}`;
|
|
648
|
+
}
|
|
649
|
+
function squadStatusLabel(status) {
|
|
650
|
+
const labels = { 0: "active", 1: "concluded", 2: "disbanded" };
|
|
651
|
+
return labels[status] ?? String(status);
|
|
652
|
+
}
|
|
653
|
+
function formatElapsed(ts) {
|
|
654
|
+
const now = Math.floor(Date.now() / 1000);
|
|
655
|
+
const diff = now - ts;
|
|
656
|
+
if (diff < 60)
|
|
657
|
+
return `${diff}s ago`;
|
|
658
|
+
if (diff < 3600)
|
|
659
|
+
return `${Math.floor(diff / 60)}m ago`;
|
|
660
|
+
if (diff < 86400)
|
|
661
|
+
return `${Math.floor(diff / 3600)}h ago`;
|
|
662
|
+
return `${Math.floor(diff / 86400)}d ago`;
|
|
663
|
+
}
|
|
664
|
+
async function fetchArenaRoundsProps(args) {
|
|
665
|
+
const limit = Number.parseInt(readFlag(args, "--limit") ?? "10", 10);
|
|
666
|
+
const data = await arenaGql(`{
|
|
667
|
+
arenaRounds(first: ${Math.max(1, Math.min(limit, 50))}, orderBy: createdAt, orderDirection: desc) {
|
|
668
|
+
id
|
|
669
|
+
question
|
|
670
|
+
category
|
|
671
|
+
yesPot
|
|
672
|
+
noPot
|
|
673
|
+
stakingClosesAt
|
|
674
|
+
resolvesAt
|
|
675
|
+
resolved
|
|
676
|
+
outcome
|
|
677
|
+
}
|
|
678
|
+
}`);
|
|
679
|
+
const rounds = (data["arenaRounds"] ?? []).map((round) => {
|
|
680
|
+
const r = round;
|
|
681
|
+
const yesPot = BigInt(String(r["yesPot"] ?? "0"));
|
|
682
|
+
const noPot = BigInt(String(r["noPot"] ?? "0"));
|
|
683
|
+
const resolvesAt = Number(r["resolvesAt"] ?? 0);
|
|
684
|
+
return {
|
|
685
|
+
id: String(r["id"]),
|
|
686
|
+
question: String(r["question"]),
|
|
687
|
+
category: String(r["category"] ?? ""),
|
|
688
|
+
yesLabel: yesPot.toString(),
|
|
689
|
+
noLabel: noPot.toString(),
|
|
690
|
+
timingLabel: resolvesAt > 0 ? formatElapsed(resolvesAt) : "timing n/a",
|
|
691
|
+
resolved: Boolean(r["resolved"]),
|
|
692
|
+
outcomeLabel: Boolean(r["outcome"]) ? "YES" : "NO",
|
|
693
|
+
};
|
|
694
|
+
});
|
|
695
|
+
return {
|
|
696
|
+
type: "rounds",
|
|
697
|
+
props: {
|
|
698
|
+
title: "Arena Rounds",
|
|
699
|
+
status: { label: "subgraph", tone: "info" },
|
|
700
|
+
rounds,
|
|
701
|
+
},
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
async function fetchArenaSquadListProps(args) {
|
|
705
|
+
const domain = readFlag(args, "--domain");
|
|
706
|
+
const domainFilter = domain ? `where: { domainTag: "${domain}" }` : "";
|
|
707
|
+
const data = await arenaGql(`{
|
|
708
|
+
researchSquads(${domainFilter} first: 50, orderBy: createdAt, orderDirection: desc) {
|
|
709
|
+
id name domainTag creator status inviteOnly memberCount createdAt
|
|
710
|
+
}
|
|
711
|
+
}`);
|
|
712
|
+
const squads = data["researchSquads"] ?? [];
|
|
713
|
+
if (squads.length === 0) {
|
|
714
|
+
return { type: "not_found", message: "No squads found." };
|
|
715
|
+
}
|
|
716
|
+
const cards = squads.map((s) => {
|
|
717
|
+
const sq = s;
|
|
718
|
+
return {
|
|
719
|
+
id: formatSquadId(BigInt(String(sq["id"]))),
|
|
720
|
+
name: String(sq["name"]),
|
|
721
|
+
domainTag: String(sq["domainTag"]),
|
|
722
|
+
statusLabel: squadStatusLabel(Number(sq["status"])),
|
|
723
|
+
creator: truncateAddr(String(sq["creator"])),
|
|
724
|
+
memberCount: Number(sq["memberCount"]),
|
|
725
|
+
inviteOnly: Boolean(sq["inviteOnly"]),
|
|
726
|
+
briefings: [{ preview: formatElapsed(Number(sq["createdAt"])), publishedLabel: "created" }],
|
|
727
|
+
};
|
|
728
|
+
});
|
|
729
|
+
return { type: "squads", cards };
|
|
730
|
+
}
|
|
731
|
+
async function fetchArenaSquadInfoProps(squadIdArg) {
|
|
732
|
+
const rawId = parseSquadId(squadIdArg).toString();
|
|
733
|
+
let data = await arenaGql(`{
|
|
734
|
+
researchSquad(id: "${rawId}") {
|
|
735
|
+
id name domainTag creator status inviteOnly memberCount
|
|
736
|
+
}
|
|
737
|
+
contributions(where: { squad: "${rawId}" }, first: 10, orderBy: timestamp, orderDirection: desc) {
|
|
738
|
+
id description timestamp author
|
|
739
|
+
}
|
|
740
|
+
squadMembers: contributions(where: { squad: "${rawId}" }, first: 100) {
|
|
741
|
+
author
|
|
742
|
+
}
|
|
743
|
+
}`);
|
|
744
|
+
const squad = data["researchSquad"];
|
|
745
|
+
if (!squad) {
|
|
746
|
+
return {
|
|
747
|
+
type: "not_found",
|
|
748
|
+
message: `Squad not found: ${squadIdArg}\n The subgraph may not have indexed this squad yet.`,
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
const allContribs = (data["squadMembers"] ?? []);
|
|
752
|
+
const seenAuthors = new Set();
|
|
753
|
+
const members = allContribs
|
|
754
|
+
.filter((c) => {
|
|
755
|
+
const author = String(c["author"] ?? "");
|
|
756
|
+
if (!author || seenAuthors.has(author))
|
|
757
|
+
return false;
|
|
758
|
+
seenAuthors.add(author);
|
|
759
|
+
return true;
|
|
760
|
+
})
|
|
761
|
+
.map((c) => ({
|
|
762
|
+
agent: truncateAddr(String(c["author"])),
|
|
763
|
+
role: "contributor",
|
|
764
|
+
}));
|
|
765
|
+
const briefings = (data["contributions"] ?? []).map((contribution) => {
|
|
766
|
+
const b = contribution;
|
|
767
|
+
return {
|
|
768
|
+
preview: String(b["description"] ?? "contribution"),
|
|
769
|
+
publishedLabel: formatElapsed(Number(b["timestamp"] ?? 0)),
|
|
770
|
+
};
|
|
771
|
+
});
|
|
772
|
+
return {
|
|
773
|
+
type: "squad",
|
|
774
|
+
props: {
|
|
775
|
+
id: formatSquadId(BigInt(String(squad["id"]))),
|
|
776
|
+
name: String(squad["name"]),
|
|
777
|
+
domainTag: String(squad["domainTag"]),
|
|
778
|
+
statusLabel: squadStatusLabel(Number(squad["status"])),
|
|
779
|
+
creator: truncateAddr(String(squad["creator"])),
|
|
780
|
+
memberCount: Number(squad["memberCount"]),
|
|
781
|
+
inviteOnly: Boolean(squad["inviteOnly"]),
|
|
782
|
+
members,
|
|
783
|
+
briefings,
|
|
784
|
+
},
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
function readFlag(args, flag) {
|
|
788
|
+
const idx = args.indexOf(flag);
|
|
789
|
+
return idx >= 0 ? args[idx + 1] : undefined;
|
|
790
|
+
}
|
|
791
|
+
//# sourceMappingURL=kernel.js.map
|