@arp-protocol/cli 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -2
- package/dist/chunks/backfill-j4hxt1w1.js +262 -0
- package/dist/chunks/ccip-qmytgn8e.js +198 -0
- package/dist/chunks/cli-0hqxver6.js +2042 -0
- package/dist/chunks/cli-0z6f3603.js +7527 -0
- package/dist/chunks/cli-3kbbwfbp.js +359 -0
- package/dist/chunks/cli-74hv4etk.js +14371 -0
- package/dist/chunks/cli-c8568g4c.js +4043 -0
- package/dist/chunks/cli-d3dy7cxe.js +2110 -0
- package/dist/chunks/cli-g5zvr10v.js +19 -0
- package/dist/chunks/cli-tyey74p3.js +303 -0
- package/dist/chunks/cli-v446mw5v.js +1033 -0
- package/dist/chunks/cli-zpft011j.js +43 -0
- package/dist/chunks/commands-dnk10vze.js +805 -0
- package/dist/chunks/env-s4585w6j.js +56 -0
- package/dist/chunks/index-3a3ssef1.js +53 -0
- package/dist/chunks/line-zy1tc2np.js +45 -0
- package/dist/chunks/node-0ydee9hy.js +593 -0
- package/dist/chunks/node-init-4v2m2vj0.js +255 -0
- package/dist/chunks/secp256k1-j2w0pmjr.js +17 -0
- package/dist/chunks/server-jmyjttvv.js +3170 -0
- package/dist/chunks/share-g8v5qe6r.js +101 -0
- package/dist/cli.js +229 -0
- package/dist/hook.js +1027 -0
- package/package.json +47 -4
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
decideShare,
|
|
4
|
+
installedFromReceipts,
|
|
5
|
+
installedFromSkillLock,
|
|
6
|
+
isSharingOn,
|
|
7
|
+
parseLocalFailures,
|
|
8
|
+
sharedLineKey
|
|
9
|
+
} from "./cli-74hv4etk.js";
|
|
10
|
+
import"./cli-c8568g4c.js";
|
|
11
|
+
import"./cli-v446mw5v.js";
|
|
12
|
+
import"./cli-0hqxver6.js";
|
|
13
|
+
import"./cli-d3dy7cxe.js";
|
|
14
|
+
import"./cli-3kbbwfbp.js";
|
|
15
|
+
import"./cli-g5zvr10v.js";
|
|
16
|
+
|
|
17
|
+
// src/share.ts
|
|
18
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
var read = (path) => existsSync(path) ? readFileSync(path, "utf8") : null;
|
|
21
|
+
function shared(env) {
|
|
22
|
+
const keys = new Set;
|
|
23
|
+
for (const row of (read(join(env.arpHome, "shared-failures.jsonl")) ?? "").split(`
|
|
24
|
+
`)) {
|
|
25
|
+
if (row.trim() === "")
|
|
26
|
+
continue;
|
|
27
|
+
try {
|
|
28
|
+
keys.add(sharedLineKey(JSON.parse(row)));
|
|
29
|
+
} catch {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return keys;
|
|
34
|
+
}
|
|
35
|
+
function decide(env) {
|
|
36
|
+
const on = isSharingOn(read(join(env.arpHome, "sharing.json")));
|
|
37
|
+
const decision = decideShare({
|
|
38
|
+
on,
|
|
39
|
+
failures: parseLocalFailures(read(join(env.arpHome, "failures.jsonl")) ?? ""),
|
|
40
|
+
installed: [
|
|
41
|
+
...installedFromSkillLock(read(join(env.home, ".agents", ".skill-lock.json"))),
|
|
42
|
+
...installedFromReceipts(read(join(env.arpHome, "receipts.jsonl"))),
|
|
43
|
+
...installedFromReceipts(read(join(env.cwd, ".arp", "receipts.jsonl")))
|
|
44
|
+
],
|
|
45
|
+
alreadyShared: shared(env)
|
|
46
|
+
});
|
|
47
|
+
return { ...decision, on };
|
|
48
|
+
}
|
|
49
|
+
function setSharing(env, on) {
|
|
50
|
+
mkdirSync(env.arpHome, { recursive: true });
|
|
51
|
+
writeFileSync(join(env.arpHome, "sharing.json"), `${JSON.stringify({ failures: on })}
|
|
52
|
+
`);
|
|
53
|
+
}
|
|
54
|
+
async function sendShared(env, write) {
|
|
55
|
+
const { on, lines } = decide(env);
|
|
56
|
+
if (!on)
|
|
57
|
+
return { sent: 0, failed: 0, firstError: null };
|
|
58
|
+
let sent = 0;
|
|
59
|
+
let failed = 0;
|
|
60
|
+
let firstError = null;
|
|
61
|
+
for (const line of lines) {
|
|
62
|
+
try {
|
|
63
|
+
await write(line);
|
|
64
|
+
appendFileSync(join(env.arpHome, "shared-failures.jsonl"), `${JSON.stringify(line)}
|
|
65
|
+
`);
|
|
66
|
+
sent += 1;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
failed += 1;
|
|
69
|
+
firstError ??= error instanceof Error ? error.message : String(error);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { sent, failed, firstError };
|
|
73
|
+
}
|
|
74
|
+
var WHY = {
|
|
75
|
+
sharing_off: "sharing is off",
|
|
76
|
+
no_public_source: "no known public source",
|
|
77
|
+
several_sources: "several sources with this name"
|
|
78
|
+
};
|
|
79
|
+
function describe(decision) {
|
|
80
|
+
const out = [`sharing is ${decision.on ? "on" : "off"}`];
|
|
81
|
+
if (decision.lines.length > 0) {
|
|
82
|
+
out.push("", "would be public on testnet 13579:");
|
|
83
|
+
for (const line of decision.lines) {
|
|
84
|
+
out.push(` ${line.toolUrl} ${line.domain ?? "(no domain)"} failed ${line.reason}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (decision.keptLocal.length > 0) {
|
|
88
|
+
out.push("", "stays on this machine:");
|
|
89
|
+
for (const row of decision.keptLocal)
|
|
90
|
+
out.push(` ${row.skill}: ${WHY[row.why]}`);
|
|
91
|
+
}
|
|
92
|
+
return `${out.join(`
|
|
93
|
+
`)}
|
|
94
|
+
`;
|
|
95
|
+
}
|
|
96
|
+
export {
|
|
97
|
+
setSharing,
|
|
98
|
+
sendShared,
|
|
99
|
+
describe,
|
|
100
|
+
decide
|
|
101
|
+
};
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
bufferedCopy
|
|
4
|
+
} from "./chunks/cli-tyey74p3.js";
|
|
5
|
+
import"./chunks/cli-v446mw5v.js";
|
|
6
|
+
import"./chunks/cli-0hqxver6.js";
|
|
7
|
+
import"./chunks/cli-d3dy7cxe.js";
|
|
8
|
+
import"./chunks/cli-3kbbwfbp.js";
|
|
9
|
+
import {
|
|
10
|
+
__require
|
|
11
|
+
} from "./chunks/cli-g5zvr10v.js";
|
|
12
|
+
|
|
13
|
+
// src/cli.ts
|
|
14
|
+
import { dirname } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
// package.json
|
|
17
|
+
var version = "0.0.1";
|
|
18
|
+
|
|
19
|
+
// src/cli.ts
|
|
20
|
+
var USAGE = `arp ${version} — ARP's agent-side programs
|
|
21
|
+
|
|
22
|
+
usage
|
|
23
|
+
arp mcp [--http] the MCP server. stdio by default, which is how an MCP client launches it
|
|
24
|
+
arp hook the runtime hook: one payload on stdin. Records what a session used in
|
|
25
|
+
.arp/session.jsonl, and a skill's failures in ~/.arp/failures.jsonl
|
|
26
|
+
arp backfill read old Claude Code transcripts into ~/.arp/failures.jsonl. Sends nothing
|
|
27
|
+
arp share say what would be public from ~/.arp/failures.jsonl, and what stays here.
|
|
28
|
+
arp share on, off (off by default). arp share send writes them on testnet
|
|
29
|
+
arp node the hire endpoint. Opt-in: it listens on 127.0.0.1 and is reached through
|
|
30
|
+
a tunnel you rent (cloudflared or ngrok, or ARP_NODE_PUBLIC_URL)
|
|
31
|
+
|
|
32
|
+
arp line write one public line on testnet 13579 through ARP's sponsor: --tool <url>
|
|
33
|
+
--outcome worked|failed [--domain <category>] [--reason <reason>]
|
|
34
|
+
arp init add the MCP server and the hook to every runtime found here
|
|
35
|
+
arp uninstall remove them, and only them
|
|
36
|
+
arp doctor check what is installed and that the server answers
|
|
37
|
+
arp init --node bind this node to your ERC-8004 agent: the token's owner signs once
|
|
38
|
+
--agent-registry eip155:<chain>:<registry> --agent-id <id>
|
|
39
|
+
--endpoint <https URL> --directory <handshake URL>
|
|
40
|
+
|
|
41
|
+
options for init, uninstall, doctor
|
|
42
|
+
--dry-run, -n show the changes, write nothing
|
|
43
|
+
--yes, -y agree without a prompt
|
|
44
|
+
--no-input never prompt; fail if a change needs agreement
|
|
45
|
+
--runtime a,b only these: claude, grok, cursor, gemini, codex, copilot
|
|
46
|
+
--project the project's files instead of your user ones
|
|
47
|
+
--print (init) print the MCP entry for any other client, write nothing
|
|
48
|
+
--sponsored (init) testnet tools that sign nothing for the user: ARP's sponsor
|
|
49
|
+
pays, and a fetched skill is installed into .claude/skills once you
|
|
50
|
+
accept the question it shows
|
|
51
|
+
--capture (init) hook every runtime and keep each payload, redacted, in
|
|
52
|
+
~/.arp/captures/ — to teach the hook a new runtime
|
|
53
|
+
--force (init) replace an MCP server named "arp" that ARP did not write
|
|
54
|
+
arp --version
|
|
55
|
+
arp --help
|
|
56
|
+
|
|
57
|
+
docs: https://github.com/Wieedze/ARP/blob/main/docs/22_RUNNING_THE_NODE.md
|
|
58
|
+
`;
|
|
59
|
+
var EXIT = { ok: 0, usage: 2, writeFailed: 5 };
|
|
60
|
+
var CLI_PATH = fileURLToPath(import.meta.url);
|
|
61
|
+
var ARGV = process.argv.slice(2);
|
|
62
|
+
var STDIO_INPUT = ARGV[0] === "mcp" && !ARGV.includes("--http") ? bufferedCopy(process.stdin) : undefined;
|
|
63
|
+
async function runNodeInit(rest) {
|
|
64
|
+
const { nodeInit, parseNodeInitFlags } = await import("./chunks/node-init-4v2m2vj0.js");
|
|
65
|
+
const flags = parseNodeInitFlags(rest);
|
|
66
|
+
if (flags instanceof Error) {
|
|
67
|
+
process.stderr.write(`arp init --node: ${flags.message}
|
|
68
|
+
`);
|
|
69
|
+
return EXIT.usage;
|
|
70
|
+
}
|
|
71
|
+
const { homedir } = await import("node:os");
|
|
72
|
+
const { createInterface } = await import("node:readline/promises");
|
|
73
|
+
return nodeInit(flags, {
|
|
74
|
+
env: process.env,
|
|
75
|
+
home: homedir(),
|
|
76
|
+
interactive: process.stdin.isTTY === true,
|
|
77
|
+
readLine: async (prompt) => {
|
|
78
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
79
|
+
try {
|
|
80
|
+
return await rl.question(prompt);
|
|
81
|
+
} finally {
|
|
82
|
+
rl.close();
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
out: (line) => process.stdout.write(`${line}
|
|
86
|
+
`),
|
|
87
|
+
err: (line) => process.stderr.write(`${line}
|
|
88
|
+
`)
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
async function shareCommand(rest) {
|
|
92
|
+
const { arpHome } = await import("./chunks/index-3a3ssef1.js");
|
|
93
|
+
const { homedir } = await import("node:os");
|
|
94
|
+
const share = await import("./chunks/share-g8v5qe6r.js");
|
|
95
|
+
const env = { arpHome: arpHome(process.env, homedir()), home: homedir(), cwd: process.cwd() };
|
|
96
|
+
if (rest[0] === "send") {
|
|
97
|
+
if (!share.decide(env).on) {
|
|
98
|
+
process.stderr.write("sharing is off: nothing was sent. `arp share on` turns it on\n");
|
|
99
|
+
return EXIT.ok;
|
|
100
|
+
}
|
|
101
|
+
process.env["ARP_TARGET"] ??= "testnet";
|
|
102
|
+
const { writeLineHere } = await import("./chunks/line-zy1tc2np.js");
|
|
103
|
+
const done = await share.sendShared(env, async (line) => {
|
|
104
|
+
await writeLineHere(line);
|
|
105
|
+
});
|
|
106
|
+
process.stdout.write(`sent ${done.sent}, failed ${done.failed}
|
|
107
|
+
`);
|
|
108
|
+
if (done.firstError !== null)
|
|
109
|
+
process.stderr.write(`${done.firstError}
|
|
110
|
+
`);
|
|
111
|
+
return done.failed === 0 ? EXIT.ok : 1;
|
|
112
|
+
}
|
|
113
|
+
if (rest[0] === "on" || rest[0] === "off")
|
|
114
|
+
share.setSharing(env, rest[0] === "on");
|
|
115
|
+
else if (rest[0] !== undefined) {
|
|
116
|
+
process.stderr.write(`usage: arp share [on|off|send]
|
|
117
|
+
`);
|
|
118
|
+
return EXIT.usage;
|
|
119
|
+
}
|
|
120
|
+
process.stdout.write(share.describe(share.decide(env)));
|
|
121
|
+
return EXIT.ok;
|
|
122
|
+
}
|
|
123
|
+
async function run(argv) {
|
|
124
|
+
const [command, ...rest] = argv;
|
|
125
|
+
if (command === "init" && rest.includes("--node"))
|
|
126
|
+
return runNodeInit(rest);
|
|
127
|
+
switch (command) {
|
|
128
|
+
case "mcp": {
|
|
129
|
+
const { main } = await import("./chunks/server-jmyjttvv.js");
|
|
130
|
+
await main(rest.includes("--http") ? rest : ["--stdio", ...rest], STDIO_INPUT);
|
|
131
|
+
return EXIT.ok;
|
|
132
|
+
}
|
|
133
|
+
case "hook":
|
|
134
|
+
await import(new URL("./hook.js", import.meta.url).href);
|
|
135
|
+
return EXIT.ok;
|
|
136
|
+
case "share":
|
|
137
|
+
try {
|
|
138
|
+
return await shareCommand(rest);
|
|
139
|
+
} catch (error) {
|
|
140
|
+
process.stderr.write(`arp share: ${error instanceof Error ? error.message : String(error)}
|
|
141
|
+
`);
|
|
142
|
+
return EXIT.writeFailed;
|
|
143
|
+
}
|
|
144
|
+
case "line": {
|
|
145
|
+
const flag = (name) => {
|
|
146
|
+
const at = rest.indexOf(`--${name}`);
|
|
147
|
+
return at === -1 ? undefined : rest[at + 1];
|
|
148
|
+
};
|
|
149
|
+
const toolUrl = flag("tool");
|
|
150
|
+
const outcome = flag("outcome");
|
|
151
|
+
if (toolUrl === undefined || outcome === undefined) {
|
|
152
|
+
process.stderr.write(`usage: arp line --tool <url> --outcome worked|failed [--domain <category>] [--reason <reason>]
|
|
153
|
+
`);
|
|
154
|
+
return EXIT.usage;
|
|
155
|
+
}
|
|
156
|
+
process.env["ARP_TARGET"] ??= "testnet";
|
|
157
|
+
const { lineFromArgs, writeLineHere } = await import("./chunks/line-zy1tc2np.js");
|
|
158
|
+
const input = lineFromArgs({ toolUrl, outcome, domain: flag("domain"), reason: flag("reason") });
|
|
159
|
+
if (input instanceof Error) {
|
|
160
|
+
process.stderr.write(`arp line: ${input.message}
|
|
161
|
+
`);
|
|
162
|
+
return EXIT.usage;
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
const written = await writeLineHere(input);
|
|
166
|
+
process.stdout.write(`${JSON.stringify(written)}
|
|
167
|
+
`);
|
|
168
|
+
return EXIT.ok;
|
|
169
|
+
} catch (error) {
|
|
170
|
+
process.stderr.write(`arp line: ${error instanceof Error ? error.message : String(error)}
|
|
171
|
+
`);
|
|
172
|
+
return 1;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
case "backfill": {
|
|
176
|
+
const { backfill } = await import("./chunks/backfill-j4hxt1w1.js");
|
|
177
|
+
const found = backfill();
|
|
178
|
+
process.stdout.write(`read ${found.transcripts} transcripts: ${found.uses} skill uses, ${found.added} new failures in ${found.file}
|
|
179
|
+
`);
|
|
180
|
+
return EXIT.ok;
|
|
181
|
+
}
|
|
182
|
+
case "node": {
|
|
183
|
+
const { main } = await import("./chunks/node-0ydee9hy.js");
|
|
184
|
+
await main();
|
|
185
|
+
return EXIT.ok;
|
|
186
|
+
}
|
|
187
|
+
case "init":
|
|
188
|
+
case "uninstall":
|
|
189
|
+
case "doctor": {
|
|
190
|
+
const install = await import("./chunks/commands-dnk10vze.js");
|
|
191
|
+
const { processEnv } = await import("./chunks/env-s4585w6j.js");
|
|
192
|
+
const flags = install.parseFlags(rest);
|
|
193
|
+
if (flags instanceof Error) {
|
|
194
|
+
process.stderr.write(`arp ${command}: ${flags.message}
|
|
195
|
+
`);
|
|
196
|
+
return EXIT.usage;
|
|
197
|
+
}
|
|
198
|
+
const env = processEnv(dirname(CLI_PATH), version);
|
|
199
|
+
if (command === "doctor")
|
|
200
|
+
return install.doctor(env, flags, CLI_PATH);
|
|
201
|
+
return command === "init" ? install.init(env, flags, CLI_PATH) : install.uninstall(env, flags, CLI_PATH);
|
|
202
|
+
}
|
|
203
|
+
case "--version":
|
|
204
|
+
case "-v":
|
|
205
|
+
process.stdout.write(`${version}
|
|
206
|
+
`);
|
|
207
|
+
return EXIT.ok;
|
|
208
|
+
case undefined:
|
|
209
|
+
case "help":
|
|
210
|
+
case "--help":
|
|
211
|
+
case "-h":
|
|
212
|
+
process.stdout.write(USAGE);
|
|
213
|
+
return EXIT.ok;
|
|
214
|
+
default:
|
|
215
|
+
process.stderr.write(`arp: unknown command '${command}'
|
|
216
|
+
|
|
217
|
+
${USAGE}`);
|
|
218
|
+
return EXIT.usage;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
process.stdout.on("error", (error) => {
|
|
222
|
+
if (error.code === "EPIPE")
|
|
223
|
+
process.exit(0);
|
|
224
|
+
throw error;
|
|
225
|
+
});
|
|
226
|
+
run(ARGV).then((code) => {
|
|
227
|
+
if (code !== EXIT.ok)
|
|
228
|
+
process.exit(code);
|
|
229
|
+
});
|