@arp-protocol/cli 0.0.1 → 0.0.4
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/CHANGELOG.md +98 -0
- package/LICENSE +26 -0
- package/README.md +22 -8
- package/dist/chunks/backfill-5zmh0t43.js +1050 -0
- package/dist/chunks/{ccip-qmytgn8e.js → ccip-zxtpc4fx.js} +4 -4
- package/dist/chunks/check-k4qnc9ee.js +2011 -0
- package/dist/chunks/cli-00qp1sj2.js +116 -0
- package/dist/chunks/{cli-c8568g4c.js → cli-0gsbnq5w.js} +72 -72
- package/dist/chunks/{cli-zpft011j.js → cli-64fx73kx.js} +3 -3
- package/dist/chunks/cli-7c393v47.js +173 -0
- package/dist/chunks/{cli-0z6f3603.js → cli-8m56jsfx.js} +239 -183
- package/dist/chunks/{cli-v446mw5v.js → cli-fbwpcfvp.js} +34 -34
- package/dist/chunks/cli-kda5hz4w.js +23 -0
- package/dist/chunks/{cli-0hqxver6.js → cli-mhzh9z8k.js} +33 -33
- package/dist/chunks/{cli-tyey74p3.js → cli-n4qagybd.js} +6 -2
- package/dist/chunks/{cli-74hv4etk.js → cli-wer26exb.js} +4939 -4105
- package/dist/chunks/cli-zehr6kdx.js +719 -0
- package/dist/chunks/{commands-dnk10vze.js → commands-t5a0w785.js} +88 -17
- package/dist/chunks/{env-s4585w6j.js → env-n5ac8d1z.js} +1 -0
- package/dist/chunks/{index-3a3ssef1.js → index-jrs2shcc.js} +3 -3
- package/dist/chunks/line-kvm1ew55.js +215 -0
- package/dist/chunks/{node-init-4v2m2vj0.js → node-init-amedveja.js} +7 -6
- package/dist/chunks/{node-0ydee9hy.js → node-x35ncwhq.js} +7 -6
- package/dist/chunks/server-ek7fet5m.js +6924 -0
- package/dist/chunks/{share-g8v5qe6r.js → share-ax2k8805.js} +10 -5
- package/dist/cli.js +71 -19
- package/dist/hook.js +4178 -270
- package/package.json +10 -3
- package/dist/chunks/backfill-j4hxt1w1.js +0 -262
- package/dist/chunks/line-zy1tc2np.js +0 -45
- package/dist/chunks/server-jmyjttvv.js +0 -3170
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
"13579_default" as _13579_default
|
|
4
|
+
} from "./cli-7c393v47.js";
|
|
5
|
+
import {
|
|
6
|
+
domain_aliases_default
|
|
7
|
+
} from "./cli-00qp1sj2.js";
|
|
2
8
|
import {
|
|
3
9
|
arpHome,
|
|
4
10
|
loadOrCreateKeyFile,
|
|
5
11
|
stateFile
|
|
6
|
-
} from "./cli-
|
|
12
|
+
} from "./cli-n4qagybd.js";
|
|
7
13
|
import {
|
|
8
14
|
ARP_DOMAIN_ATTESTORS,
|
|
9
15
|
HAS_TAG,
|
|
@@ -12,6 +18,8 @@ import {
|
|
|
12
18
|
bundleMatchesReceipt,
|
|
13
19
|
contentIndexOf,
|
|
14
20
|
contentRequestTypedData,
|
|
21
|
+
contentsFileOf,
|
|
22
|
+
contentsLines,
|
|
15
23
|
createErc8004Client,
|
|
16
24
|
createPublicClient,
|
|
17
25
|
createWalletClient,
|
|
@@ -23,12 +31,18 @@ import {
|
|
|
23
31
|
intuitionToolAtomLookup,
|
|
24
32
|
multiVaultDeclareAbi,
|
|
25
33
|
multiVaultReads,
|
|
34
|
+
paymentAtomLabel,
|
|
35
|
+
readDomainTree,
|
|
36
|
+
readSkillContents,
|
|
26
37
|
receiptMatchesContent,
|
|
27
38
|
recoverContentRequester,
|
|
39
|
+
redactEndpointUrl,
|
|
28
40
|
renderSkillPrompt,
|
|
41
|
+
resolveDomain,
|
|
29
42
|
reviewSkill,
|
|
30
43
|
serveContent,
|
|
31
44
|
serveSkillBundle,
|
|
45
|
+
signCategoryRequest,
|
|
32
46
|
signLineRequest,
|
|
33
47
|
signListToolRequest,
|
|
34
48
|
signMintGasRequest,
|
|
@@ -36,19 +50,19 @@ import {
|
|
|
36
50
|
skillRefFromUrl,
|
|
37
51
|
sponsorProofDigest,
|
|
38
52
|
verifyContentReceipt
|
|
39
|
-
} from "./cli-
|
|
53
|
+
} from "./cli-wer26exb.js";
|
|
40
54
|
import {
|
|
41
55
|
encodeFunctionData
|
|
42
|
-
} from "./cli-
|
|
56
|
+
} from "./cli-0gsbnq5w.js";
|
|
43
57
|
import {
|
|
44
58
|
privateKeyToAccount
|
|
45
|
-
} from "./cli-
|
|
59
|
+
} from "./cli-fbwpcfvp.js";
|
|
46
60
|
import {
|
|
47
61
|
getAddress,
|
|
48
62
|
isHex,
|
|
49
63
|
keccak256,
|
|
50
64
|
stringToBytes
|
|
51
|
-
} from "./cli-
|
|
65
|
+
} from "./cli-mhzh9z8k.js";
|
|
52
66
|
|
|
53
67
|
// ../mcp/src/content.ts
|
|
54
68
|
import { existsSync, writeFileSync } from "node:fs";
|
|
@@ -96,175 +110,6 @@ var _1155_default = {
|
|
|
96
110
|
deployedAt: "2026-09-16",
|
|
97
111
|
gasCost: "0.0000228 TRUST for both enforcers"
|
|
98
112
|
};
|
|
99
|
-
// ../../data/deployments/13579.json
|
|
100
|
-
var _13579_default = {
|
|
101
|
-
chain: {
|
|
102
|
-
name: "Intuition Testnet",
|
|
103
|
-
chainId: 13579,
|
|
104
|
-
chainIdHex: "0x350b",
|
|
105
|
-
nativeCurrency: {
|
|
106
|
-
name: "Test Trust",
|
|
107
|
-
symbol: "tTRUST",
|
|
108
|
-
decimals: 18
|
|
109
|
-
},
|
|
110
|
-
rpcUrl: "https://testnet.rpc.intuition.systems/http",
|
|
111
|
-
explorerUrl: "https://testnet.explorer.intuition.systems",
|
|
112
|
-
graphqlUrl: "https://testnet.intuition.sh/v1/graphql",
|
|
113
|
-
_source: [
|
|
114
|
-
"Intuition skill: .claude/skills/intuition/SKILL.md (table at line 149, Viem chain config at line 184)",
|
|
115
|
-
"MetaMask deployments: ~/Project/metamask-smart-accounts-kit/packages/delegation-deployments/src/index.ts (CHAIN_ID.intuitionTestnet = 0x350b)"
|
|
116
|
-
]
|
|
117
|
-
},
|
|
118
|
-
intuition: {
|
|
119
|
-
_source: ".claude/skills/intuition/SKILL.md line 152",
|
|
120
|
-
multiVault: "0x2Ece8D4dEdcB9918A398528f3fa4688b1d2CAB91"
|
|
121
|
-
},
|
|
122
|
-
metamaskDelegationFramework: {
|
|
123
|
-
version: "1.3.0",
|
|
124
|
-
_source: "MetaMask deployments package (~/Project/metamask-smart-accounts-kit/packages/delegation-deployments/src/contractAddresses.ts → DEPLOYMENTS_1_3_0). All addresses are deterministic CREATE2 — same value on every chain MetaMask supports. Intuition Testnet (chainId 0x350b) is explicitly mapped to DEPLOYMENTS_1_3_0 at packages/delegation-deployments/src/index.ts line 148.",
|
|
125
|
-
delegationManager: "0xdb9B1e94B5b69Df7e401DDbedE43491141047dB3",
|
|
126
|
-
entryPoint: "0x0000000071727De22E5E9d8BAf0edAc6f37da032",
|
|
127
|
-
simpleFactory: "0x69Aa2f9fe1572F1B640E1bbc512f5c3a734fc77c",
|
|
128
|
-
implementations: {
|
|
129
|
-
hybridDeleGator: "0x48dBe696A4D990079e039489bA2053B36E8FFEC4",
|
|
130
|
-
multiSigDeleGator: "0x56a9EdB16a0105eb5a4C54f4C062e2868844f3A7",
|
|
131
|
-
eip7702StatelessDeleGator: "0x63c0c19a282a1B52b07dD5a65b58948A07DAE32B"
|
|
132
|
-
},
|
|
133
|
-
enforcers: {
|
|
134
|
-
_note: "Standard caveat enforcers. ARP composes its custom DomainScopeEnforcer + TrustStakeCapEnforcer alongside a subset of these.",
|
|
135
|
-
allowedCalldata: "0xc2b0d624c1c4319760C96503BA27C347F3260f55",
|
|
136
|
-
allowedMethods: "0x2c21fD0Cb9DC8445CB3fb0DC5E7Bb0Aca01842B5",
|
|
137
|
-
allowedTargets: "0x7F20f61b1f09b08D970938F6fa563634d65c4EeB",
|
|
138
|
-
approvalRevocation: "0xe264F1f09A19505a1ca1a86D5b01E8bFdb64324A",
|
|
139
|
-
blockNumber: "0x5d9818dF0AE3f66e9c3D0c5029DAF99d1823ca6c",
|
|
140
|
-
deployed: "0x24ff2AA430D53a8CD6788018E902E098083dcCd2",
|
|
141
|
-
erc20BalanceChange: "0xcdF6aB796408598Cea671d79506d7D48E97a5437",
|
|
142
|
-
erc20TransferAmount: "0xf100b0819427117EcF76Ed94B358B1A5b5C6D2Fc",
|
|
143
|
-
erc20PeriodTransfer: "0x474e3Ae7E169e940607cC624Da8A15Eb120139aB",
|
|
144
|
-
erc20Streaming: "0x56c97aE02f233B29fa03502Ecc0457266d9be00e",
|
|
145
|
-
erc721BalanceChange: "0x8aFdf96eDBbe7e1eD3f5Cd89C7E084841e12A09e",
|
|
146
|
-
erc721Transfer: "0x3790e6B7233f779b09DA74C72b6e94813925b9aF",
|
|
147
|
-
erc1155BalanceChange: "0x63c322732695cAFbbD488Fc6937A0A7B66fC001A",
|
|
148
|
-
exactCalldataBatch: "0x982FD5C86BBF425d7d1451f974192d4525113DfD",
|
|
149
|
-
exactCalldata: "0x99F2e9bF15ce5eC84685604836F71aB835DBBdED",
|
|
150
|
-
exactExecutionBatch: "0x1e141e455d08721Dd5BCDA1BaA6Ea5633Afd5017",
|
|
151
|
-
exactExecution: "0x146713078D39eCC1F5338309c28405ccf85Abfbb",
|
|
152
|
-
id: "0xC8B5D93463c893401094cc70e66A206fb5987997",
|
|
153
|
-
logicalOrWrapper: "0xE1302607a3251AF54c3a6e69318d6aa07F5eB46c",
|
|
154
|
-
limitedCalls: "0x04658B29F6b82ed55274221a06Fc97D318E25416",
|
|
155
|
-
nativeBalanceChange: "0xbD7B277507723490Cd50b12EaaFe87C616be6880",
|
|
156
|
-
argsEqualityCheck: "0x44B8C6ae3C304213c3e298495e12497Ed3E56E41",
|
|
157
|
-
nativeTokenPayment: "0x4803a326ddED6dDBc60e659e5ed12d85c7582811",
|
|
158
|
-
nativeTokenTransferAmount: "0xF71af580b9c3078fbc2BBF16FbB8EEd82b330320",
|
|
159
|
-
nativeTokenStreaming: "0xD10b97905a320b13a0608f7E9cC506b56747df19",
|
|
160
|
-
nativeTokenPeriodTransfer: "0x9BC0FAf4Aca5AE429F4c06aEEaC517520CB16BD9",
|
|
161
|
-
nonce: "0xDE4f2FAC4B3D87A1d9953Ca5FC09FCa7F366254f",
|
|
162
|
-
ownershipTransfer: "0x7EEf9734E7092032B5C56310Eb9BbD1f4A524681",
|
|
163
|
-
redeemer: "0xE144b0b2618071B4E56f746313528a669c7E65c5",
|
|
164
|
-
specificActionERC20TransferBatch: "0x6649b61c873F6F9686A1E1ae9ee98aC380c7bA13",
|
|
165
|
-
timestamp: "0x1046bb45C8d673d4ea75321280DB34899413c069",
|
|
166
|
-
valueLte: "0x92Bf12322527cAA612fd31a0e810472BBB106A8F",
|
|
167
|
-
multiTokenPeriod: "0xFB2f1a9BD76d3701B730E5d69C3219D42D80eBb7"
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
arp: {
|
|
171
|
-
endpointBinding: {
|
|
172
|
-
_note: "Task 39c, ADR 0094/0095. The two predicates the endpoint binding is written with: (agent identity atom) has endpoint (endpoint atom), and (pinned binding document) in context of (that triple). Both READ FROM THE GRAPH, neither minted by ARP: scripts/measure/endpoint-predicate.ts, run 2026-10-30, found `has endpoint` (Thing, 6 triples) and `in context of` (Thing, 29 triples) on testnet 13579, and none of `reachable at`, `is reachable at`, `served at`, `hosted at`. `in context of` differs from mainnet's 0x892054b0… (scripts/measure/nested-triples.ts), so never copy it across chains.",
|
|
173
|
-
measuredAt: "2026-10-30",
|
|
174
|
-
hasEndpoint: "0xa4488686eb3702e4e972a971ea008d6832a7f935b942366f1091566d1993a5f1",
|
|
175
|
-
inContextOf: "0x61a88b9c372c0d164d2caf66947b67ed0fcb4c457178a271b6b3dc39fb1f8862"
|
|
176
|
-
},
|
|
177
|
-
_note: "Written by scripts/deploy/deploy.sh --broadcast. Addresses are EOA-nonce-derived (CREATE). deploy.sh skips a contract whose address here already has code unless --force, and on a redeploy keeps the replaced address under <name>V<n>. ModuleRegistry and DomainScopeEnforcer were removed from src/ in 59ac83a; their entries are the record.",
|
|
178
|
-
deployer: "0xE596096F4176b682E300d73963e7B04B383C1AA1",
|
|
179
|
-
deployedAt: "2026-06-01T13:30:00Z",
|
|
180
|
-
moduleRegistry: "0xc9a2f66775828017e984E8be077fA2d17e0A41F4",
|
|
181
|
-
moduleRegistryV1: "0x777C28eCb4688D647B535098d11fB87A9746334f",
|
|
182
|
-
_moduleRegistryNote: "Redeployed 2026-06-03 with schemaURI uniqueness (ADR 0013). V1 address kept for historical reference; orphan (UI reads V2).",
|
|
183
|
-
domainScopeEnforcer: "0x516B82E29e3Ca46Ca810FC2EEf348932b198f7f9",
|
|
184
|
-
trustStakeCapEnforcer: "0x19e07280F1483Aa9aCDb1a7F8C61bfd20c7879Bc",
|
|
185
|
-
identityRegistry: "0xC165A2AD2E540A4069E02834009161E2b4490d5A",
|
|
186
|
-
sponsor: "0xE596096F4176b682E300d73963e7B04B383C1AA1",
|
|
187
|
-
_sponsorNote: "The address ARP's sponsoring service sends from on 13579 (apps/sponsor, ADR 0092, 0094): its GET / answered this on 2026-11-02. /tools counts every deposit it sent in Usage: the proof-gated ones, the edge creations it paid for, and, because the address is also ARP's deployer, 3 deposits written before the service existed (scripts/measure/sponsor-deposit-provenance.ts, 2026-11-03). Not a contract: an EOA whose key is in a 0600 file the agent never reads.",
|
|
188
|
-
deployedTxs: {
|
|
189
|
-
moduleRegistry: "0x6ee4f4d76dd55c69ea434f8c3c204cb6149df1c588910b1792db1650681fbc2e",
|
|
190
|
-
moduleRegistryV1: "0x02abe9a0c598df131995bc40927a4e0be0b86e7bdbfe747cfdf37fb19b069634",
|
|
191
|
-
domainScopeEnforcer: "0x6ca2c4e680b45eaa37147c2458bd38d756e6ffabb560755657cc9caf893df272",
|
|
192
|
-
trustStakeCapEnforcer: "0x8dd54ea3eeba14645531c501c3f1b8ec95e6a95788825e00fbe239ff32263159",
|
|
193
|
-
identityRegistry: "0x60b1f6ff7dbdcbca6864794eb9c5cf1e3ba94770daac6d2e77a4df00d726900c",
|
|
194
|
-
trustStakeCapEnforcerV1: "0x80e36828202a9c7606b92146076ed123155a94cfda3a2ab53013bd27be71764f"
|
|
195
|
-
},
|
|
196
|
-
explorerLinks: {
|
|
197
|
-
moduleRegistry: "https://testnet.explorer.intuition.systems/address/0xc9a2f66775828017e984E8be077fA2d17e0A41F4",
|
|
198
|
-
moduleRegistryV1: "https://testnet.explorer.intuition.systems/address/0x777C28eCb4688D647B535098d11fB87A9746334f",
|
|
199
|
-
domainScopeEnforcer: "https://testnet.explorer.intuition.systems/address/0x516B82E29e3Ca46Ca810FC2EEf348932b198f7f9",
|
|
200
|
-
trustStakeCapEnforcer: "https://testnet.explorer.intuition.systems/address/0x19e07280F1483Aa9aCDb1a7F8C61bfd20c7879Bc",
|
|
201
|
-
identityRegistry: "https://testnet.explorer.intuition.systems/address/0xC165A2AD2E540A4069E02834009161E2b4490d5A",
|
|
202
|
-
trustStakeCapEnforcerV1: "https://testnet.explorer.intuition.systems/address/0x7BB56819E9a413B8B4668C5cAF5C494c41dC0F8E"
|
|
203
|
-
},
|
|
204
|
-
modules: [
|
|
205
|
-
{
|
|
206
|
-
id: "1",
|
|
207
|
-
name: "Solidity Audit",
|
|
208
|
-
domain: "solidity-audit",
|
|
209
|
-
schemaURI: "ipfs://bafkreiembmtprqzufrdkvig74lskv6iazuatblm4hwmtxkf5a3v67mkdkm",
|
|
210
|
-
creator: "0xE596096F4176b682E300d73963e7B04B383C1AA1",
|
|
211
|
-
tx: "0xbd97979b197e4423293180e36d69f72e8eb07d2bb11bdfb2940ec918d6f6af3c"
|
|
212
|
-
}
|
|
213
|
-
],
|
|
214
|
-
intuitionAtoms: [
|
|
215
|
-
{
|
|
216
|
-
atomId: "0xde8890fca8dde322ca57bce0e20dfeb23be67332f9101305ebe72facdee032dc",
|
|
217
|
-
uri: "ipfs://bafkreiembmtprqzufrdkvig74lskv6iazuatblm4hwmtxkf5a3v67mkdkm",
|
|
218
|
-
tx: "0x97db7629c6c973d43c0c62325754d750ee262853bdbd87496b4b82c1ea3d0ac7"
|
|
219
|
-
}
|
|
220
|
-
],
|
|
221
|
-
rigAgents: {
|
|
222
|
-
_note: "Task 24. ERC-8004 agents on ARP's own testnet registry, minted 2026-10-19 on chain 13579. SIGNED BY THE AGENT SESSION using the operator's PRIVATE_KEY from .env, on the user's explicit authorisation — not by a human at a keyboard. See ADR 0037. security.md scopes its automation prohibition to mainnet, so this is permitted and was previously unwritten. Agents 1 and 2 were left with an EMPTY tokenURI deliberately: no-token-uri is 23% of the real cohort (32/140, scripts/measure/cohort-endpoints.ts), so they exercise a branch the three new agents cannot. Permanent: the ids are taken and setAgentURI leaves the superseded URI in the mint transaction's calldata.",
|
|
223
|
-
registry: "0xC165A2AD2E540A4069E02834009161E2b4490d5A",
|
|
224
|
-
agents: {
|
|
225
|
-
"3": {
|
|
226
|
-
slug: "rig-confirmed",
|
|
227
|
-
exercises: "confirmed/serves-declared-protocol + tools/list recovery",
|
|
228
|
-
endpoint: "http://localhost:3002/mcp",
|
|
229
|
-
_endpointNote: "ARP's own MCP server, local by default. ARP_MCP_ENDPOINT regenerates the file and setAgentURI can update the agent — but that escape hatch is a rehearsal prop: portability.md rule 4 says any step that works because ARP can write to the registry is not a step, and on mainnet ARP owns no registry. The real fix is a public endpoint.",
|
|
230
|
-
tx: "0xce4fee69c692ddf57d4537b23479d78384a9e2d06b733b532e419055ed50a086",
|
|
231
|
-
documentSha256_16: "478ac85cd6b2357f",
|
|
232
|
-
_documentShaNote: "sha256 of the data: URI, first 16 hex. Lets repo-vs-chain drift be detected: the fixtures in scripts/seed/rig-registration-files.ts are the source of truth for three permanent mints, and an edit to FILES would otherwise diverge silently. Checked by scripts/verify/verify-rig-claims.ts against a gate report. ONLY REPRODUCIBLE WITH ARP_MCP_ENDPOINT UNSET: OWN_ENDPOINT reads the environment and the document is hashed after substitution, so anyone with it exported sees a false DRIFT."
|
|
233
|
-
},
|
|
234
|
-
"4": {
|
|
235
|
-
slug: "rig-dead",
|
|
236
|
-
exercises: "confirmed/dead",
|
|
237
|
-
endpoint: "http://192.0.2.1/mcp",
|
|
238
|
-
_endpointNote: "TEST-NET-1, RFC 5737 — reserved and never routable, so it always times out. A .invalid hostname was tried first and gave inconclusive/transport-error, because a DNS failure is indistinguishable from our own network being down.",
|
|
239
|
-
tx: "0x87bf71cf0ce55db7f82ca617b8601ee87f870e67018b1097a311ed2d61cc7378",
|
|
240
|
-
uriUpdatedTx: "0x8f5950a61fca19b6a3f69b26f6c4159e29833689ed4b1623d8610206bfe87100",
|
|
241
|
-
documentSha256_16: "6db8b769dd551e98"
|
|
242
|
-
},
|
|
243
|
-
"5": {
|
|
244
|
-
slug: "rig-unprobeable",
|
|
245
|
-
exercises: "not-checkable ×2 — templated and non-http-identifier. Never a defect.",
|
|
246
|
-
tx: "0x859aff609fa10dba635ffd12d0b60b598c7c3174238f61962edb4b5eee1a0efd",
|
|
247
|
-
documentSha256_16: "f61a9d7f6637958e"
|
|
248
|
-
}
|
|
249
|
-
},
|
|
250
|
-
gate: {
|
|
251
|
-
command: "bun run scripts/verify/verify-cohort.ts --target intuition-testnet --ids 1,2,3,4,5 --tools --out /tmp/gate.json && bun run scripts/verify/verify-rig-claims.ts /tmp/gate.json",
|
|
252
|
-
ranAt: "2026-10-19",
|
|
253
|
-
result: "5 agents: 2 with no tokenURI (40%), 3 read. 4 endpoints: 2 confirmed (serves-declared-protocol, dead), 2 not-checkable (templated, non-http-identifier), 0 inconclusive, 1 capability list recovered (arp_tool_reputation).",
|
|
254
|
-
_requires: "apps/mcp/src/server.ts listening on :3002, or agent 3 reports inconclusive. The confirmed branch is therefore reproducible only on a host running that server — a known limit of this gate until ARP has a public endpoint.",
|
|
255
|
-
_widerThanSpecced: "--ids 1,2,3,4,5 rather than 3,4,5. Including the two empty-tokenURI agents exercises a fifth branch for two extra requests.",
|
|
256
|
-
_claimsCheck: "verify-rig-claims.ts asserts each fixture's `exercises` prose against the outcome the probe observed, and the document hashes against this file. The unit suite CANNOT close that class: confirmed and inconclusive are both probeable before a request is sent, and the mutation that actually shipped lived exactly there."
|
|
257
|
-
}
|
|
258
|
-
},
|
|
259
|
-
trustStakeCapEnforcerV1: "0x7BB56819E9a413B8B4668C5cAF5C494c41dC0F8E",
|
|
260
|
-
delegationRegister: {
|
|
261
|
-
_note: "Task 37c, ADR 0092 item 7. The two predicates a published delegation is written with: (delegator CAIP-10) delegate to (delegate CAIP-10), and (pinned document) in context of (that triple). Both READ FROM THE GRAPH, neither minted by ARP: on testnet 13579 on 2026-11-03 exactly one atom carries each label, a Thing, `delegate to` in 10 triples and `in context of` in 29. `in context of` is the one endpointBinding uses. Never copy either across chains.",
|
|
262
|
-
measuredAt: "2026-11-03",
|
|
263
|
-
delegateTo: "0xb56980d42a3b03455bf41ea20fe04ae223fca0b9e688994dc661414e81e6433b",
|
|
264
|
-
inContextOf: "0x61a88b9c372c0d164d2caf66947b67ed0fcb4c457178a271b6b3dc39fb1f8862"
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
113
|
// ../../data/catalogue/skills-13579.json
|
|
269
114
|
var skills_13579_default = {
|
|
270
115
|
_note: "What ARP wrote on chain for the skill catalogue. A RECORD, not a source of truth: every id here is a pure function of the URL or the word (ADR 0077, 0054), so the whole set is re-derivable with no credential and no network. What is not re-derivable is which ones ARP asserted, and which it later withdrew.",
|
|
@@ -6740,10 +6585,69 @@ function text(id, value) {
|
|
|
6740
6585
|
var isTermId = (value) => typeof value === "string" && /^0x[0-9a-fA-F]{64}$/.test(value);
|
|
6741
6586
|
var isAddress = (value) => typeof value === "string" && /^0x[0-9a-fA-F]{40}$/.test(value);
|
|
6742
6587
|
|
|
6588
|
+
// ../mcp/src/hosted.ts
|
|
6589
|
+
var HOSTED_FLAG = "ARP_HOSTED";
|
|
6590
|
+
var HOST_NAME = /^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z][a-z0-9-]{0,61}[a-z0-9]$/;
|
|
6591
|
+
var REFUSED_WHEN_HOSTED = [
|
|
6592
|
+
"ARP_RECEIPT_KEY",
|
|
6593
|
+
"ARP_AGENT_PRIVATE_KEY",
|
|
6594
|
+
"ARP_ALLOW_PRIVATE_PROBE"
|
|
6595
|
+
];
|
|
6596
|
+
function isHosted(env = process.env) {
|
|
6597
|
+
return env[HOSTED_FLAG] === "1";
|
|
6598
|
+
}
|
|
6599
|
+
function publicHost(env = process.env) {
|
|
6600
|
+
const name = (env["ARP_PUBLIC_HOST"] ?? "").trim().toLowerCase();
|
|
6601
|
+
return name === "" ? null : name;
|
|
6602
|
+
}
|
|
6603
|
+
function hostedRefusal(env = process.env) {
|
|
6604
|
+
const name = publicHost(env);
|
|
6605
|
+
const flag = env[HOSTED_FLAG];
|
|
6606
|
+
if (flag !== undefined && flag !== "" && flag !== "1") {
|
|
6607
|
+
return `${HOSTED_FLAG} must be 1 or unset, not ${flag}`;
|
|
6608
|
+
}
|
|
6609
|
+
if (!isHosted(env)) {
|
|
6610
|
+
return name === null ? null : `ARP_PUBLIC_HOST needs ${HOSTED_FLAG}=1: only the hosted read-only server answers a public name`;
|
|
6611
|
+
}
|
|
6612
|
+
if (env["ARP_TOOLS"] !== "read") {
|
|
6613
|
+
return `${HOSTED_FLAG}=1 serves ARP_TOOLS=read only, not ${env["ARP_TOOLS"] ?? "every tool"}`;
|
|
6614
|
+
}
|
|
6615
|
+
if (env["ARP_TARGET"] !== "testnet") {
|
|
6616
|
+
return `${HOSTED_FLAG}=1 reads testnet 13579 only: set ARP_TARGET=testnet`;
|
|
6617
|
+
}
|
|
6618
|
+
if (env["ARP_TRANSPORT"] === "stdio") {
|
|
6619
|
+
return `${HOSTED_FLAG}=1 serves HTTP; stdio is for a client on the same machine`;
|
|
6620
|
+
}
|
|
6621
|
+
for (const variable of REFUSED_WHEN_HOSTED) {
|
|
6622
|
+
if ((env[variable] ?? "") !== "")
|
|
6623
|
+
return `${HOSTED_FLAG}=1 refuses ${variable}: a hosted server holds no key and probes no private address`;
|
|
6624
|
+
}
|
|
6625
|
+
if (name === null) {
|
|
6626
|
+
return `${HOSTED_FLAG}=1 needs ARP_PUBLIC_HOST, the name the proxy forwards`;
|
|
6627
|
+
}
|
|
6628
|
+
if (!HOST_NAME.test(name)) {
|
|
6629
|
+
return `ARP_PUBLIC_HOST must be a bare host name such as mcp.example.org, not ${env["ARP_PUBLIC_HOST"]}`;
|
|
6630
|
+
}
|
|
6631
|
+
return null;
|
|
6632
|
+
}
|
|
6633
|
+
function loggable(error, message, env = process.env) {
|
|
6634
|
+
if (!isHosted(env))
|
|
6635
|
+
return message;
|
|
6636
|
+
return error instanceof Error ? error.name : "error";
|
|
6637
|
+
}
|
|
6638
|
+
|
|
6743
6639
|
// ../mcp/src/config.ts
|
|
6744
6640
|
import { resolve } from "node:path";
|
|
6641
|
+
var refusedHosting = hostedRefusal(process.env);
|
|
6642
|
+
if (refusedHosting !== null) {
|
|
6643
|
+
console.error(refusedHosting);
|
|
6644
|
+
process.exit(1);
|
|
6645
|
+
}
|
|
6646
|
+
var HOSTED = isHosted(process.env);
|
|
6745
6647
|
var PORT = Number(process.env.PORT ?? 3002);
|
|
6746
6648
|
var RECEIPT_SIGNER = (() => {
|
|
6649
|
+
if (HOSTED)
|
|
6650
|
+
return null;
|
|
6747
6651
|
try {
|
|
6748
6652
|
return receiptSigner();
|
|
6749
6653
|
} catch (error) {
|
|
@@ -6758,7 +6662,8 @@ function inProject(path, projectDir = process.env["ARP_PROJECT_DIR"]) {
|
|
|
6758
6662
|
var SKILLS_DIR = process.env["ARP_SKILLS_DIR"] === undefined ? undefined : inProject(process.env["ARP_SKILLS_DIR"]);
|
|
6759
6663
|
var READ_ONLY = process.env["ARP_TOOLS"] === "read" || DESKTOP;
|
|
6760
6664
|
var CONTENT_URL = process.env["ARP_CONTENT"] ?? "http://127.0.0.1:3002";
|
|
6761
|
-
var
|
|
6665
|
+
var SPONSOR_DEFAULT = "https://sponsor.arp.intuition.box";
|
|
6666
|
+
var SPONSOR_URL = process.env["ARP_SPONSOR"] ?? SPONSOR_DEFAULT;
|
|
6762
6667
|
var SESSION_LOG = inProject(process.env["ARP_SESSION_LOG"] ?? ".arp/session.jsonl");
|
|
6763
6668
|
var RECEIPTS_LOG = inProject(process.env["ARP_RECEIPTS"] ?? ".arp/receipts.jsonl");
|
|
6764
6669
|
var TARGETS = { mainnet: 1155, testnet: 13579 };
|
|
@@ -6793,6 +6698,12 @@ function required(value, what) {
|
|
|
6793
6698
|
return value;
|
|
6794
6699
|
}
|
|
6795
6700
|
var GRAPHQL = required(GRAPHQL_URL, "a graphqlUrl");
|
|
6701
|
+
var SKILLS_INDEX = (() => {
|
|
6702
|
+
const raw2 = process.env.ARP_SKILLS_INDEX_URL?.trim() ?? "";
|
|
6703
|
+
if (raw2 === "off")
|
|
6704
|
+
return null;
|
|
6705
|
+
return raw2 === "" ? "https://skills.sh" : raw2;
|
|
6706
|
+
})();
|
|
6796
6707
|
var RPC = required(RPC_URL, "an rpcUrl");
|
|
6797
6708
|
var MULTI_VAULT = required(MULTI_VAULT_RAW, "a multiVault");
|
|
6798
6709
|
var reads = multiVaultReads({ address: MULTI_VAULT, chainId, rpcUrl: RPC });
|
|
@@ -6836,7 +6747,8 @@ var IN_CONTEXT_OF = (() => {
|
|
|
6836
6747
|
})();
|
|
6837
6748
|
var LINE_PAYERS = (() => {
|
|
6838
6749
|
const arp = record.arp;
|
|
6839
|
-
|
|
6750
|
+
const wallets = [arp?.deployer, arp?.sponsor].filter((wallet) => typeof wallet === "string");
|
|
6751
|
+
return [...new Set(wallets)];
|
|
6840
6752
|
})();
|
|
6841
6753
|
function domainWalk() {
|
|
6842
6754
|
return {
|
|
@@ -6848,6 +6760,11 @@ function domainWalk() {
|
|
|
6848
6760
|
};
|
|
6849
6761
|
}
|
|
6850
6762
|
|
|
6763
|
+
// ../mcp/src/domain-words.ts
|
|
6764
|
+
function domainWords(tree, root = "tool") {
|
|
6765
|
+
return { labels: tree.subtree(root), aliases: domain_aliases_default.aliases };
|
|
6766
|
+
}
|
|
6767
|
+
|
|
6851
6768
|
// ../mcp/src/client-session.ts
|
|
6852
6769
|
var ASK_TIMEOUT_MS = 15 * 60 * 1000;
|
|
6853
6770
|
var declaredElicitation = false;
|
|
@@ -6978,7 +6895,7 @@ import { dirname as dirname2, join as join2 } from "node:path";
|
|
|
6978
6895
|
var SAFE_SKILL_NAME = /^[a-z0-9][a-z0-9._-]*$/i;
|
|
6979
6896
|
function installPrompt(receipt, files, installPath, context) {
|
|
6980
6897
|
const ref = skillRefFromUrl(receipt.receipt.url);
|
|
6981
|
-
|
|
6898
|
+
const prompt = renderSkillPrompt(reviewSkill({
|
|
6982
6899
|
repo: ref?.repo ?? receipt.receipt.url,
|
|
6983
6900
|
skill: ref?.skill ?? receipt.receipt.url,
|
|
6984
6901
|
path: receipt.receipt.path,
|
|
@@ -6987,6 +6904,9 @@ function installPrompt(receipt, files, installPath, context) {
|
|
|
6987
6904
|
files,
|
|
6988
6905
|
thirdParty: context.thirdParty
|
|
6989
6906
|
}), installPath);
|
|
6907
|
+
const contains = contentsLines(readSkillContents(files.map((file) => contentsFileOf(file.path, file.bytes))), 3);
|
|
6908
|
+
return { ...prompt, message: [prompt.message, "", "What its files contain:", ...contains].join(`
|
|
6909
|
+
`) };
|
|
6990
6910
|
}
|
|
6991
6911
|
function installFiles(skillsDir, skill, files) {
|
|
6992
6912
|
if (!SAFE_SKILL_NAME.test(skill))
|
|
@@ -7153,7 +7073,8 @@ async function getSkill(config, agent, atom) {
|
|
|
7153
7073
|
const line = { atom: signed.receipt.atom, url: signed.receipt.url, skill: ref?.skill ?? null, receipt: signed };
|
|
7154
7074
|
appendFileSync2(join4(config.stateDir, "receipts.jsonl"), `${JSON.stringify(line)}
|
|
7155
7075
|
`);
|
|
7156
|
-
const
|
|
7076
|
+
const contains = contentsLines(readSkillContents(files.map((file) => contentsFileOf(file.path, file.bytes))));
|
|
7077
|
+
const served = { atom: signed.receipt.atom, url: signed.receipt.url, name: ref?.skill ?? signed.receipt.url, text: new TextDecoder().decode(skillMd.bytes), contains };
|
|
7157
7078
|
if (config.skillsDir === undefined || ref === null || !SAFE_SKILL_NAME.test(ref.skill))
|
|
7158
7079
|
return served;
|
|
7159
7080
|
const prompt = installPrompt(signed, files, join4(config.skillsDir, ref.skill), config.reviewContext?.(signed.receipt.url) ?? { committedAt: null, thirdParty: [] });
|
|
@@ -7221,7 +7142,11 @@ async function approveSponsor(config, agent, ref, approval) {
|
|
|
7221
7142
|
const next = gas.body["next"];
|
|
7222
7143
|
await agent.send({ to: next.to, data: next.data, value: BigInt(next.value), chainId: DESKTOP_CHAIN_ID }, [approval]);
|
|
7223
7144
|
}
|
|
7224
|
-
async function writeLine(config, agent,
|
|
7145
|
+
async function writeLine(config, agent, asked) {
|
|
7146
|
+
const input = asked.payment === undefined ? asked : { ...asked, toolUrl: redactEndpointUrl(asked.toolUrl) };
|
|
7147
|
+
if (input.payment !== undefined && input.terms === undefined)
|
|
7148
|
+
throw new Error("a line with a payment names the terms it paid against");
|
|
7149
|
+
const terms = input.payment === undefined ? null : input.terms ?? null;
|
|
7225
7150
|
const state = await ensureAgent(config, agent);
|
|
7226
7151
|
const ref = { agentRegistry: registryRef(config), agentId: state.agentId };
|
|
7227
7152
|
await ensureIdentity(config, state);
|
|
@@ -7230,9 +7155,26 @@ async function writeLine(config, agent, input) {
|
|
|
7230
7155
|
const listing2 = await signListToolRequest({ address: agent.address, url: input.toolUrl, nonce: keccak256(stringToBytes(`list-${input.toolUrl}-${Date.now()}`)), expiresAt: expiresAt() }, DESKTOP_CHAIN_ID, agent.account);
|
|
7231
7156
|
const listed = await post(config, "/list-tool", { url: input.toolUrl, request: listing2 });
|
|
7232
7157
|
if (listed.status !== 200 || typeof listed.body["atomId"] !== "string") {
|
|
7233
|
-
|
|
7158
|
+
const rule = typeof listed.body["rule"] === "string" ? `, ${listed.body["rule"]}` : "";
|
|
7159
|
+
throw new Error(`the sponsor would not list ${input.toolUrl} (${listed.status}${rule}): ${String(listed.body["error"] ?? "")}`);
|
|
7234
7160
|
}
|
|
7235
7161
|
const tool = listed.body["atomId"];
|
|
7162
|
+
if (input.newDomain !== undefined && input.domain !== undefined) {
|
|
7163
|
+
const category = await signCategoryRequest({
|
|
7164
|
+
agent: agent.address,
|
|
7165
|
+
...ref,
|
|
7166
|
+
label: input.domain,
|
|
7167
|
+
parent: input.newDomain.parent,
|
|
7168
|
+
subject: tool,
|
|
7169
|
+
reason: input.newDomain.why,
|
|
7170
|
+
nonce: keccak256(stringToBytes(`category-${tool}-${input.domain}-${Date.now()}`)),
|
|
7171
|
+
expiresAt: expiresAt()
|
|
7172
|
+
}, DESKTOP_CHAIN_ID, agent.account);
|
|
7173
|
+
const filed = await post(config, "/propose-category", { request: category });
|
|
7174
|
+
if (filed.status !== 200) {
|
|
7175
|
+
throw new Error(`the domain "${input.domain}" could not be added (${filed.status}): ${String(filed.body["error"] ?? "")}`);
|
|
7176
|
+
}
|
|
7177
|
+
}
|
|
7236
7178
|
const wait = config.sleep ?? ((ms) => new Promise((done) => setTimeout(done, ms)));
|
|
7237
7179
|
const deadline = Date.now() + (config.indexerWaitMs ?? 120000);
|
|
7238
7180
|
let approved = false;
|
|
@@ -7244,6 +7186,13 @@ async function writeLine(config, agent, input) {
|
|
|
7244
7186
|
domain: input.domain ?? "",
|
|
7245
7187
|
outcome: input.outcome,
|
|
7246
7188
|
reason: input.reason ?? "",
|
|
7189
|
+
payment: input.payment === undefined ? "" : paymentAtomLabel(input.payment),
|
|
7190
|
+
endpoint: input.payment === undefined ? "" : input.toolUrl,
|
|
7191
|
+
need: input.need ?? "",
|
|
7192
|
+
payTo: terms?.payTo ?? "",
|
|
7193
|
+
asset: terms?.asset ?? "",
|
|
7194
|
+
price: terms?.price ?? "",
|
|
7195
|
+
termsAt: terms?.receivedAt ?? 0,
|
|
7247
7196
|
nonce: keccak256(stringToBytes(`line-${tool}-${Date.now()}`)),
|
|
7248
7197
|
expiresAt: expiresAt()
|
|
7249
7198
|
}, DESKTOP_CHAIN_ID, agent.account);
|
|
@@ -7258,7 +7207,7 @@ async function writeLine(config, agent, input) {
|
|
|
7258
7207
|
};
|
|
7259
7208
|
}
|
|
7260
7209
|
const error = String(answer.body["error"] ?? "");
|
|
7261
|
-
const notIndexedYet = answer.status === 403 && /no identity atom on the graph/.test(error) || answer.status === 422 && answer.body["retry"] === true || answer.status === 503 && answer.body["retry"] === true;
|
|
7210
|
+
const notIndexedYet = answer.status === 403 && /no identity atom on the graph/.test(error) || answer.status === 422 && answer.body["retry"] === true || answer.status === 503 && answer.body["retry"] === true || answer.status === 422 && answer.body["rule"] === "unknown_domain" && input.newDomain !== undefined;
|
|
7262
7211
|
if (notIndexedYet && Date.now() < deadline) {
|
|
7263
7212
|
await wait(5000);
|
|
7264
7213
|
continue;
|
|
@@ -7354,7 +7303,7 @@ Use when: "make a game", "build a browser game",…`, installs: 26583 }, "github
|
|
|
7354
7303
|
real-time WebSockets, scheduled tasks, tool integration, and chat capabilities.
|
|
7355
7304
|
Generates production-ready agent code…`, installs: 3702 }, "github.com/cloudflare/skills?skill=building-mcp-server-on-cloudflare": { description: `Builds remote MCP (Model Context Protocol) servers on Cloudflare Workers
|
|
7356
7305
|
with tools, OAuth authentication, and production deployment. Generates
|
|
7357
|
-
server code, configures auth providers, and deploys to…`, installs: 3424 }, "github.com/easyzoom/aix-skills?skill=webpage-to-markdown": { description: "Use when converting a public webpage URL into clean Markdown content", installs: null }, "github.com/JimLiu/baoyu-skills?skill=baoyu-url-to-markdown": { description: "Fetch any URL and convert to markdown using baoyu-fetch CLI (Chrome CDP with site-specific adapters). Built-in adapters for X/Twitter, YouTube transcripts, Hacker News threads, and generic pages via…", installs: null }, "github.com/WyattBlue/auto-editor?skill=auto-editor": { description: "Record a microphone or edit video/audio with the auto-editor CLI — cut out dead space (silence, motionlessness, black frames), set the pace, make manual cuts, and render the result. Use when someone…", installs: null }, "github.com/Melvynx/video-agent-skills?skill=short-editing": { description: "Edits a talking-head take end to end into a paper-style motion design short (1080x1920, also 1:1 and 16:9) with its own render engine (Node + Chrome + ffmpeg, free, offline). Use when the user says…", installs: null }, "github.com/clueso-ai/skills?skill=remove-filler-words": { description: `Strip ums, ahs, false starts, and rambling from a video's narration - clean the transcript, regenerate the voiceover, and keep the visuals aligned to the new timing. Use when the user says "remove…`, installs: null }, "github.com/browser-use/video-use?skill=video-use": { description: "Edit any video by conversation. Transcribe, cut, color grade, generate overlay animations, burn subtitles — for talking heads, montages, tutorials, travel, interviews. No presets, no menus. Ask…", installs: null }, "github.com/louisedesadeleer/cut-video?skill=cut-video": { description: "Tighten a long recording aggressively — remove silences, fillers, hedges, false starts, and repetitions while preserving laughs and comedic pauses. Cuts are driven by Montreal Forced Aligner (MFA)…", installs: null }, "github.com/softaworks/agent-toolkit?skill=web-to-markdown": { description: "Use ONLY when the user explicitly says: 'use the skill web-to-markdown ...' (or 'use a skill web-to-markdown ...'). Converts webpage URLs to clean Markdown by calling the local web2md CLI (Puppeteer…", installs: null }, "github.com/Wieedze/ARP?skill=arp": { description: "
|
|
7306
|
+
server code, configures auth providers, and deploys to…`, installs: 3424 }, "github.com/easyzoom/aix-skills?skill=webpage-to-markdown": { description: "Use when converting a public webpage URL into clean Markdown content", installs: null }, "github.com/JimLiu/baoyu-skills?skill=baoyu-url-to-markdown": { description: "Fetch any URL and convert to markdown using baoyu-fetch CLI (Chrome CDP with site-specific adapters). Built-in adapters for X/Twitter, YouTube transcripts, Hacker News threads, and generic pages via…", installs: null }, "github.com/WyattBlue/auto-editor?skill=auto-editor": { description: "Record a microphone or edit video/audio with the auto-editor CLI — cut out dead space (silence, motionlessness, black frames), set the pace, make manual cuts, and render the result. Use when someone…", installs: null }, "github.com/Melvynx/video-agent-skills?skill=short-editing": { description: "Edits a talking-head take end to end into a paper-style motion design short (1080x1920, also 1:1 and 16:9) with its own render engine (Node + Chrome + ffmpeg, free, offline). Use when the user says…", installs: null }, "github.com/clueso-ai/skills?skill=remove-filler-words": { description: `Strip ums, ahs, false starts, and rambling from a video's narration - clean the transcript, regenerate the voiceover, and keep the visuals aligned to the new timing. Use when the user says "remove…`, installs: null }, "github.com/browser-use/video-use?skill=video-use": { description: "Edit any video by conversation. Transcribe, cut, color grade, generate overlay animations, burn subtitles — for talking heads, montages, tutorials, travel, interviews. No presets, no menus. Ask…", installs: null }, "github.com/louisedesadeleer/cut-video?skill=cut-video": { description: "Tighten a long recording aggressively — remove silences, fillers, hedges, false starts, and repetitions while preserving laughs and comedic pauses. Cuts are driven by Montreal Forced Aligner (MFA)…", installs: null }, "github.com/softaworks/agent-toolkit?skill=web-to-markdown": { description: "Use ONLY when the user explicitly says: 'use the skill web-to-markdown ...' (or 'use a skill web-to-markdown ...'). Converts webpage URLs to clean Markdown by calling the local web2md CLI (Puppeteer…", installs: null }, "github.com/Wieedze/ARP?skill=arp": { description: "Check a skill, MCP server or API before you install or pay for it, and see what other agents declared about it. Use whenever a task needs a tool you do not already have — search the registry by the…", installs: null }, "github.com/intuition-box/ARP?skill=arp": { description: "Check a skill, MCP server or API before you install or pay for it, and see what other agents declared about it. Use whenever a task needs a tool you do not already have — search the registry by the…", installs: null } }
|
|
7358
7307
|
};
|
|
7359
7308
|
|
|
7360
7309
|
// ../mcp/src/tool-search.ts
|
|
@@ -7455,6 +7404,68 @@ function pageOf(entries, offset, limit) {
|
|
|
7455
7404
|
nextOffset: offset + limit < entries.length ? offset + limit : null
|
|
7456
7405
|
};
|
|
7457
7406
|
}
|
|
7407
|
+
function mergeIndexed(matched, indexed, options) {
|
|
7408
|
+
const out = [];
|
|
7409
|
+
const taken = new Set;
|
|
7410
|
+
const add = (entry) => {
|
|
7411
|
+
const key = options.keyOf(entry);
|
|
7412
|
+
if (key !== null) {
|
|
7413
|
+
if (taken.has(key))
|
|
7414
|
+
return;
|
|
7415
|
+
taken.add(key);
|
|
7416
|
+
}
|
|
7417
|
+
out.push(entry);
|
|
7418
|
+
};
|
|
7419
|
+
for (const entry of matched)
|
|
7420
|
+
if (options.leads(entry))
|
|
7421
|
+
add(entry);
|
|
7422
|
+
indexed.forEach(({ key }, index) => add(options.held(key) ?? options.make(index)));
|
|
7423
|
+
for (const entry of matched)
|
|
7424
|
+
add(entry);
|
|
7425
|
+
return out;
|
|
7426
|
+
}
|
|
7427
|
+
|
|
7428
|
+
// ../mcp/src/desktop/file-category.ts
|
|
7429
|
+
function isRecord(value) {
|
|
7430
|
+
return typeof value === "object" && value !== null;
|
|
7431
|
+
}
|
|
7432
|
+
async function fileCategory(args, deps) {
|
|
7433
|
+
let request;
|
|
7434
|
+
try {
|
|
7435
|
+
request = await deps.sign({
|
|
7436
|
+
label: args.category,
|
|
7437
|
+
parent: args.parent ?? "",
|
|
7438
|
+
subject: args.id,
|
|
7439
|
+
reason: args.reason ?? ""
|
|
7440
|
+
});
|
|
7441
|
+
} catch (error) {
|
|
7442
|
+
return { error: `this agent could not sign the request: ${error instanceof Error ? error.message : String(error)}` };
|
|
7443
|
+
}
|
|
7444
|
+
return submitCategory(request, deps);
|
|
7445
|
+
}
|
|
7446
|
+
async function submitCategory(request, deps) {
|
|
7447
|
+
let response;
|
|
7448
|
+
try {
|
|
7449
|
+
response = await deps.fetch(`${deps.sponsorUrl}/propose-category`, {
|
|
7450
|
+
method: "POST",
|
|
7451
|
+
headers: { "content-type": "application/json" },
|
|
7452
|
+
body: JSON.stringify({ request })
|
|
7453
|
+
});
|
|
7454
|
+
} catch {
|
|
7455
|
+
return { error: "ARP's sponsor is not reachable, so the category was not filed." };
|
|
7456
|
+
}
|
|
7457
|
+
const answer = await response.json().catch(() => null);
|
|
7458
|
+
if (response.ok && isRecord(answer) && typeof answer["label"] === "string") {
|
|
7459
|
+
return {
|
|
7460
|
+
filed: answer["label"],
|
|
7461
|
+
new_category: answer["newCategory"] === true,
|
|
7462
|
+
written: answer["created"] === true
|
|
7463
|
+
};
|
|
7464
|
+
}
|
|
7465
|
+
const rule = isRecord(answer) && typeof answer["rule"] === "string" ? answer["rule"] : "unknown";
|
|
7466
|
+
const detail = isRecord(answer) && typeof answer["error"] === "string" ? answer["error"] : `HTTP ${response.status}`;
|
|
7467
|
+
return { refused: rule, detail };
|
|
7468
|
+
}
|
|
7458
7469
|
|
|
7459
7470
|
// ../mcp/src/desktop/handlers.ts
|
|
7460
7471
|
var agent;
|
|
@@ -7495,6 +7506,49 @@ async function desktopTool(id, name, args) {
|
|
|
7495
7506
|
if (typeof atom !== "string" || !/^0x[0-9a-fA-F]{64}$/.test(atom)) {
|
|
7496
7507
|
return fail(id, -32602, "id must be the 0x + 32 bytes id from arp_find_tools");
|
|
7497
7508
|
}
|
|
7509
|
+
if (name === "arp_file_category") {
|
|
7510
|
+
const asked = args["category"];
|
|
7511
|
+
if (typeof asked !== "string" || asked.trim().length === 0) {
|
|
7512
|
+
return fail(id, -32602, "category must be a category name");
|
|
7513
|
+
}
|
|
7514
|
+
const parent = typeof args["parent"] === "string" ? args["parent"] : undefined;
|
|
7515
|
+
let category = asked;
|
|
7516
|
+
const resolved = resolveDomain(asked, domainWords(await readDomainTree(domainWalk())));
|
|
7517
|
+
if (resolved.status === "node")
|
|
7518
|
+
category = resolved.label;
|
|
7519
|
+
else if (parent === undefined) {
|
|
7520
|
+
return text(id, {
|
|
7521
|
+
refused: "unknown_category",
|
|
7522
|
+
detail: `"${asked}" is not a category.${resolved.suggestions.length === 0 ? "" : ` Closest: ${resolved.suggestions.join(", ")}.`} Pick one, or pass parent and reason to add it.`
|
|
7523
|
+
});
|
|
7524
|
+
}
|
|
7525
|
+
const reason = typeof args["reason"] === "string" ? args["reason"] : undefined;
|
|
7526
|
+
return text(id, await fileCategory({
|
|
7527
|
+
id: atom,
|
|
7528
|
+
category,
|
|
7529
|
+
...parent === undefined ? {} : { parent },
|
|
7530
|
+
...reason === undefined ? {} : { reason }
|
|
7531
|
+
}, {
|
|
7532
|
+
sponsorUrl: SPONSOR_URL,
|
|
7533
|
+
fetch: globalThis.fetch.bind(globalThis),
|
|
7534
|
+
sign: async (fields) => {
|
|
7535
|
+
const sender = agentFor();
|
|
7536
|
+
const config = loopConfig();
|
|
7537
|
+
const state = await ensureAgent(config, sender);
|
|
7538
|
+
return signCategoryRequest({
|
|
7539
|
+
agent: sender.address,
|
|
7540
|
+
agentRegistry: registryRef(config),
|
|
7541
|
+
agentId: state.agentId,
|
|
7542
|
+
label: fields.label,
|
|
7543
|
+
parent: fields.parent,
|
|
7544
|
+
subject: atom,
|
|
7545
|
+
reason: fields.reason,
|
|
7546
|
+
nonce: keccak256(stringToBytes(`category-${atom}-${Date.now()}`)),
|
|
7547
|
+
expiresAt: Math.floor(Date.now() / 1000) + 600
|
|
7548
|
+
}, DESKTOP_CHAIN_ID, sender.account);
|
|
7549
|
+
}
|
|
7550
|
+
}));
|
|
7551
|
+
}
|
|
7498
7552
|
const loop = loopConfig();
|
|
7499
7553
|
try {
|
|
7500
7554
|
if (name === "arp_get_skill") {
|
|
@@ -7502,6 +7556,8 @@ async function desktopTool(id, name, args) {
|
|
|
7502
7556
|
return text(id, {
|
|
7503
7557
|
name: skill.name,
|
|
7504
7558
|
source: skill.url,
|
|
7559
|
+
contains: skill.contains,
|
|
7560
|
+
show_the_person_first: "Show the person the `contains` lines above as they are before you follow the skill or install it: facts from its files, not a verdict.",
|
|
7505
7561
|
skill_md: skill.text,
|
|
7506
7562
|
...skill.installedAt !== undefined ? {
|
|
7507
7563
|
installed_at: skill.installedAt,
|
|
@@ -7524,4 +7580,4 @@ async function desktopTool(id, name, args) {
|
|
|
7524
7580
|
}
|
|
7525
7581
|
}
|
|
7526
7582
|
|
|
7527
|
-
export { serveContentRequest, result, fail, text, isTermId, isAddress, PORT, RECEIPT_SIGNER, DESKTOP, READ_ONLY, SESSION_LOG, RECEIPTS_LOG, targetName, chainId, record, sessionCatalogue, acceptedSigners, GRAPHQL, RPC, MULTI_VAULT, reads, toolAtoms, DOMAIN_ROOT, REACHABLE_ATOM, DOMAIN_ATTESTORS, directory, IN_CONTEXT_OF, LINE_PAYERS, domainWalk, skill_facts_default, recordClientCapabilities, stdioRouter, keyOf, describe, matchOf, rankOf, collapseCopies, cachedFor, pageOf, writeLine, loopConfig, agentFor, desktopTool };
|
|
7583
|
+
export { serveContentRequest, result, fail, text, isTermId, isAddress, publicHost, loggable, HOSTED, PORT, RECEIPT_SIGNER, DESKTOP, READ_ONLY, SPONSOR_URL, SESSION_LOG, RECEIPTS_LOG, targetName, chainId, record, sessionCatalogue, acceptedSigners, GRAPHQL, SKILLS_INDEX, RPC, MULTI_VAULT, reads, toolAtoms, DOMAIN_ROOT, REACHABLE_ATOM, DOMAIN_ATTESTORS, directory, IN_CONTEXT_OF, LINE_PAYERS, domainWalk, domainWords, skill_facts_default, recordClientCapabilities, stdioRouter, keyOf, describe, matchOf, rankOf, collapseCopies, cachedFor, pageOf, mergeIndexed, submitCategory, sponsorApproval, writeLine, loopConfig, agentFor, desktopTool };
|