@heyanon-arp/cli 0.0.7 → 0.0.8
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 +4 -4
- package/dist/cli.js +806 -784
- package/dist/cli.js.map +1 -1
- package/package.json +3 -4
- package/scripts/postinstall.mjs +7 -6
- package/examples/README.md +0 -157
- package/examples/worker-template.py +0 -834
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heyanon-arp/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Command-line client for the Agent Relationship Protocol — register agents, sign envelopes, run escrowed work cycles on Solana.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
24
|
"dist",
|
|
25
|
-
"examples",
|
|
26
25
|
"scripts/postinstall.mjs",
|
|
27
26
|
"LICENSE",
|
|
28
27
|
"README.md"
|
|
@@ -37,8 +36,8 @@
|
|
|
37
36
|
"commander": "^12.1.0",
|
|
38
37
|
"prompts": "^2.4.2",
|
|
39
38
|
"simple-update-notifier": "^2.0.0",
|
|
40
|
-
"@heyanon-arp/
|
|
41
|
-
"@heyanon-arp/
|
|
39
|
+
"@heyanon-arp/shield": "0.0.2",
|
|
40
|
+
"@heyanon-arp/sdk": "0.0.7"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|
|
44
43
|
"@types/jest": "^29.5.2",
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Onboarding must NEVER get in the way, so this is deliberately defensive:
|
|
10
10
|
* - only for an interactive GLOBAL install (`npm i -g @heyanon-arp/cli`)
|
|
11
|
-
* - silent in CI
|
|
11
|
+
* - silent only in CI and non-TTY / piped contexts (no user opt-out — the
|
|
12
|
+
* banner shows on every interactive GLOBAL install + update)
|
|
12
13
|
* - honours NO_COLOR
|
|
13
14
|
* - fully wrapped so a banner failure can never fail the install
|
|
14
15
|
*/
|
|
@@ -16,9 +17,8 @@ try {
|
|
|
16
17
|
const isGlobalInstall = process.env.npm_config_global === 'true' || process.env.npm_config_global === '1';
|
|
17
18
|
const inCI = Boolean(process.env.CI);
|
|
18
19
|
const interactive = Boolean(process.stdout && process.stdout.isTTY);
|
|
19
|
-
const muted = Boolean(process.env.HEYARP_NO_BANNER);
|
|
20
20
|
|
|
21
|
-
if (!isGlobalInstall || inCI || !interactive
|
|
21
|
+
if (!isGlobalInstall || inCI || !interactive) {
|
|
22
22
|
process.exit(0);
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -38,12 +38,13 @@ try {
|
|
|
38
38
|
` ${cyan('heyarp guide --setup')} ${dim('one-time setup: keys, server, multi-agent isolation')}`,
|
|
39
39
|
` ${cyan('heyarp guide --troubleshoot')} ${dim('common errors → fixes')}`,
|
|
40
40
|
'',
|
|
41
|
-
` ${bold('Driving heyarp from an AI agent?')} Pipe
|
|
41
|
+
` ${bold('Driving heyarp from an AI agent?')} Pipe YOUR role's guide into its system prompt`,
|
|
42
|
+
` ${dim('(role is per-deal: BUYER if you send the offer + pay; WORKER if an offer comes to you):')}`,
|
|
42
43
|
'',
|
|
43
|
-
` ${cyan('heyarp guide --role worker --format prompt')}`,
|
|
44
|
+
` ${cyan('heyarp guide --role worker --format prompt')} ${dim('# you do tasks, get paid')}`,
|
|
45
|
+
` ${cyan('heyarp guide --role buyer --format prompt')} ${dim('# you order tasks, pay')}`,
|
|
44
46
|
'',
|
|
45
47
|
` ${dim('Then:')} ${cyan('heyarp register')} ${dim('→ handshake → delegation → work → receipt → settlement.')}`,
|
|
46
|
-
` ${dim('Quiet this banner any time with HEYARP_NO_BANNER=1.')}`,
|
|
47
48
|
'',
|
|
48
49
|
];
|
|
49
50
|
process.stdout.write(`${lines.join('\n')}\n`);
|
package/examples/README.md
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
# `@heyanon-arp/cli` — bundled examples
|
|
2
|
-
|
|
3
|
-
This directory ships with the npm package and is reachable from
|
|
4
|
-
inside a working CLI install via `heyarp examples`:
|
|
5
|
-
|
|
6
|
-
```bash
|
|
7
|
-
heyarp examples list # list bundled examples
|
|
8
|
-
heyarp examples show worker # print to stdout
|
|
9
|
-
heyarp examples show worker > my-worker.py # pipe to file
|
|
10
|
-
heyarp examples copy worker --output ./my-worker.py # copy to disk
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
The CLI resolves bundled paths relative to its own runtime location
|
|
14
|
-
(`<node_modules>/@heyanon-arp/cli/examples/...`), so you do not need
|
|
15
|
-
network access or a checkout of the source repository — `npm i -g
|
|
16
|
-
@heyanon-arp/cli` is enough.
|
|
17
|
-
|
|
18
|
-
## Current examples
|
|
19
|
-
|
|
20
|
-
| File | Subject | Status |
|
|
21
|
-
|---|---|---|
|
|
22
|
-
| [`worker-template.py`](./worker-template.py) | Autonomous Python worker (handshake → delegation → work → receipt → settlement, all auto-mediated; terms ride inline on the offer, you fill in `handle_work_request()`) | Reference; FLAT pricing + full-release settlement only. MIT. |
|
|
23
|
-
|
|
24
|
-
## How to use the worker template
|
|
25
|
-
|
|
26
|
-
1. Register an agent (one-time):
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
heyarp register --name "MyWorker" --tag my-service
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
2. Copy the template:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
heyarp examples copy worker --output ./my-worker.py
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
3. Edit `handle_work_request(params, rel_id, del_id, req_id, sender_did)` in
|
|
39
|
-
the copied file — that is the only function with your business logic.
|
|
40
|
-
Everything else (FSM mediation, signing, settlement) is policy.
|
|
41
|
-
|
|
42
|
-
4. Set your agent's settlement public key. Either edit
|
|
43
|
-
`MY_SETTLEMENT_PUBKEY` at the top of the file, or set the
|
|
44
|
-
`ARP_SETTLEMENT_PUBKEY` env var. Find your key via:
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
heyarp whoami --local
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
The worker refuses to start while the placeholder is still in place
|
|
51
|
-
(so funds can never accidentally route to the template's default).
|
|
52
|
-
It also refuses if the value does not match your agent's actual
|
|
53
|
-
settlement key: the `receipt propose` escrow settlement step signs
|
|
54
|
-
with the agent's stored key, so a mismatch would route funds to the
|
|
55
|
-
agent's address rather than the one you set here. The preflight
|
|
56
|
-
resolves the real key via `heyarp whoami --local` and compares.
|
|
57
|
-
|
|
58
|
-
5. Pick your cluster. Defaults to **mainnet-beta** (cluster tag `1`).
|
|
59
|
-
Override for devnet testing:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
export ARP_CLUSTER_TAG=0
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
6. Run:
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
python3 my-worker.py
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
The worker connects to the server's inbox SSE stream and starts
|
|
72
|
-
accepting offers per the policy in the file.
|
|
73
|
-
|
|
74
|
-
## Environment variables
|
|
75
|
-
|
|
76
|
-
The template honours every override below — set them in the shell
|
|
77
|
-
that launches the worker, or in a process supervisor (systemd /
|
|
78
|
-
Docker / launchd).
|
|
79
|
-
|
|
80
|
-
| Variable | Default | Notes |
|
|
81
|
-
|---|---|---|
|
|
82
|
-
| `ARP_SETTLEMENT_PUBKEY` | _(required)_ | Your Solana settlement address from `heyarp whoami --local`. Worker refuses to start without it. |
|
|
83
|
-
| `ARP_SERVER_URL` | `https://api.heyanon.ai/arp` | Override to point at dev / staging / self-hosted. |
|
|
84
|
-
| `ARP_CLUSTER_TAG` | `1` (mainnet-beta) | `0` for devnet. Must match the cluster where the on-chain lock lives. |
|
|
85
|
-
| `ARP_MINT_PUBKEY` | System Program id (native SOL) | Set to the SPL token's mint address for non-SOL settlement. |
|
|
86
|
-
| `ARP_WORKER_DIR` | `~/.arp-worker/jobs` | Working directory for temp response payloads. Created lazily. |
|
|
87
|
-
| `HEYARP_PATH` | `heyarp` (from `$PATH`) | Absolute path to the CLI binary if it isn't on `$PATH`. |
|
|
88
|
-
|
|
89
|
-
## Caveats
|
|
90
|
-
|
|
91
|
-
- **Pricing model coverage — FLAT by the template's choice.** Terms
|
|
92
|
-
ride inline on the delegation offer (there is no separate contract
|
|
93
|
-
step), so the template's `auto_accept_delegation` reads the offer's
|
|
94
|
-
`pricingModel` straight off the delegation row and refuses non-flat
|
|
95
|
-
offers (a full-release signature on a `usage_based` lock would let
|
|
96
|
-
the buyer drain it). The settlement step folded into `receipt
|
|
97
|
-
propose` (escrow) DOES handle both: it auto-detects full (flat) vs
|
|
98
|
-
partial (`usage_based`, from the receipt's `usage.computed_amount`)
|
|
99
|
-
release and signs the right digest (`ARP-SOLANA-RELEASE-v1.5` /
|
|
100
|
-
`ARP-SOLANA-PARTIAL-RELEASE-v1.5`). To support `usage_based` work,
|
|
101
|
-
TWO changes are needed — not just one: (1) relax the FLAT-only gate
|
|
102
|
-
in `auto_accept_delegation`, AND (2) compute the per-task amount and
|
|
103
|
-
pass `--computed-amount` on the `receipt propose` call (the folded
|
|
104
|
-
settlement step binds the partial release to the receipt's
|
|
105
|
-
`usage.computed_amount` and refuses to settle a usage_based receipt
|
|
106
|
-
that lacks it).
|
|
107
|
-
- **Settlement is folded into `receipt propose` now.** For an escrow
|
|
108
|
-
delegation the ~90-line payee settlement ritual (resolve buyer key →
|
|
109
|
-
derive condition_hash → fetch amount/decimals/deadline → compute
|
|
110
|
-
expiry → sign → deliver) runs automatically as part of `heyarp
|
|
111
|
-
receipt propose ... --cluster-tag <0|1>`, right after the receipt
|
|
112
|
-
commits — so a worker can't forget the separate step (which would
|
|
113
|
-
strand the buyer's cosign on `ESC_SETTLEMENT_SIGS_MISSING`). It
|
|
114
|
-
auto-resolves the rest from the delegation id, signs the release
|
|
115
|
-
digest (reusing `wallet sign-settlement-release`), and delivers via a
|
|
116
|
-
`settlement_signature` envelope the buyer consumes with `receipt
|
|
117
|
-
cosign --auto-resolve-payee-sig`. Idempotent — safe to re-run.
|
|
118
|
-
`--cluster-tag` is REQUIRED for escrow (propose fails fast before
|
|
119
|
-
committing if it's missing). On partial failure (no RPC / lock not
|
|
120
|
-
yet visible) the receipt stays committed and the `--json` result's
|
|
121
|
-
`settlement` block reports `{delivered: false, error, recovery}`;
|
|
122
|
-
recover with `heyarp receipt send-payee-sig` (the no-RPC primitive)
|
|
123
|
-
or re-run propose once the lock is reachable.
|
|
124
|
-
- **Policy is hard-coded.** The auto-accept criteria live inline in
|
|
125
|
-
the Python file. A future `heyarp worker run --policy worker-policy.yaml`
|
|
126
|
-
worker daemon would move those into a
|
|
127
|
-
declarative config + add budget caps, observability, dry-run mode.
|
|
128
|
-
Until that ships, treat this template as a quick way to validate
|
|
129
|
-
the protocol against your business logic, not as a production
|
|
130
|
-
runner — at minimum, add a price ceiling check in
|
|
131
|
-
`auto_accept_delegation()` before accepting.
|
|
132
|
-
- **Single-tenant.** Events are processed serially in the SSE loop;
|
|
133
|
-
if you need parallelism, run multiple workers under **distinct DIDs**
|
|
134
|
-
(running two against the same identity will fight over
|
|
135
|
-
`sender_sequence`).
|
|
136
|
-
|
|
137
|
-
## Contributing an example
|
|
138
|
-
|
|
139
|
-
Drop a new file in this directory + update both this README and the
|
|
140
|
-
`heyarp examples list` registry (see
|
|
141
|
-
`packages/cli/src/commands/examples.ts`). Templates should:
|
|
142
|
-
|
|
143
|
-
- Carry an attribution header (author, license, status).
|
|
144
|
-
- Be self-contained (single file, no external repo checkouts).
|
|
145
|
-
- Document any `MY_*` constants the user must set before running.
|
|
146
|
-
- Default any "real money" parameters to **fail-fast sentinels**, not
|
|
147
|
-
the contributor's own keys / endpoints. The worker refuses to start
|
|
148
|
-
if a sentinel survives — the test that lands in `examples.spec.ts`
|
|
149
|
-
pins this contract.
|
|
150
|
-
- Use `--json` flags on every CLI invocation that has them (the
|
|
151
|
-
`--json` consistency pass); avoid regex parsing of
|
|
152
|
-
human-formatted output.
|
|
153
|
-
- Read error **codes**, not error text. In `--json` mode a failing
|
|
154
|
-
command emits `{"code": "...", "message": "..."}` on stderr.
|
|
155
|
-
Branch on `code` (the template's `error_code(r)` helper
|
|
156
|
-
parses it) rather than substring-matching the message — codes are
|
|
157
|
-
stable, messages are not.
|