@dev.sail.money/sailor 1.3.0-227 → 1.3.0-228

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.
Files changed (47) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +59 -498
  3. package/package.json +1 -5
  4. package/packages/cli/dist/index.cjs +0 -14
  5. package/packages/sdk/dist/fees.d.ts +2 -1
  6. package/packages/sdk/dist/fees.d.ts.map +1 -1
  7. package/packages/sdk/dist/fees.js +2 -1
  8. package/packages/sdk/dist/fees.js.map +1 -1
  9. package/packages/sdk/dist/intelligence.d.ts +1 -1
  10. package/packages/sdk/dist/intelligence.js +1 -1
  11. package/packages/sdk/package.json +2 -2
  12. package/templates/default/.agents/skills/sail-mandates/references/examples-index.md +1 -1
  13. package/templates/default/.agents/skills/sail-template-swap/SKILL.md +2 -2
  14. package/templates/default/.agents/skills/sail-template-swap-no-oracle/SKILL.md +2 -2
  15. package/templates/default/.agents/skills/sail-templates/SKILL.md +2 -2
  16. package/templates/default/docs/PERMISSION_MODEL.md +2 -2
  17. package/docs/PERMISSION_MODEL.md +0 -93
  18. package/examples/README.md +0 -24
  19. package/examples/lifi-permissions/LifiBoundedApprovePermissionCloneable.sol +0 -84
  20. package/examples/lifi-permissions/LifiDiamondSwapPermissionCloneable.sol +0 -97
  21. package/examples/lifi-permissions/README.md +0 -53
  22. package/scripts/check-docs.mjs +0 -309
  23. package/scripts/check-init.mjs +0 -123
  24. package/scripts/check-update.mjs +0 -177
  25. package/scripts/clean.mjs +0 -17
  26. /package/{examples → templates/default/examples}/custom-mandate/.sail/contracts/interfaces/IPermission.sol +0 -0
  27. /package/{examples → templates/default/examples}/custom-mandate/README.md +0 -0
  28. /package/{examples → templates/default/examples}/custom-mandate/foundry.toml +0 -0
  29. /package/{examples → templates/default/examples}/custom-mandate/mandates/BoundedCallPermission.sol +0 -0
  30. /package/{examples → templates/default/examples}/custom-mandate/mandates/README.md +0 -0
  31. /package/{examples → templates/default/examples}/custom-mandate/mandates/SailCalldata.sol +0 -0
  32. /package/{examples → templates/default/examples}/permissions/BoundedApproveAndCallBatch.sol +0 -0
  33. /package/{examples → templates/default/examples}/permissions/BoundedBorrow_AaveV3_Arbitrum.sol +0 -0
  34. /package/{examples → templates/default/examples}/permissions/BoundedLimitless_Base.sol +0 -0
  35. /package/{examples → templates/default/examples}/permissions/BoundedPerp_GMXv2_Arbitrum.sol +0 -0
  36. /package/{examples → templates/default/examples}/permissions/BoundedStake_Venice_Base.sol +0 -0
  37. /package/{examples → templates/default/examples}/permissions/BoundedSupply_AaveV3_Arbitrum.sol +0 -0
  38. /package/{examples → templates/default/examples}/permissions/BoundedSwapNative_UniswapV3_Base.sol +0 -0
  39. /package/{examples → templates/default/examples}/permissions/BoundedSwap_UniswapV3_Base.sol +0 -0
  40. /package/{examples → templates/default/examples}/permissions/BoundedSwap_UniswapV4_Unichain.sol +0 -0
  41. /package/{examples → templates/default/examples}/permissions/BoundedTransfer_ERC20_Ethereum.sol +0 -0
  42. /package/{examples → templates/default/examples}/permissions/BoundedVault_ERC4626_Base.sol +0 -0
  43. /package/{examples → templates/default/examples}/permissions/README.md +0 -0
  44. /package/{examples → templates/default/examples}/permissions/SailCalldata.sol +0 -0
  45. /package/{examples → templates/default/examples}/permissions/foundry.toml +0 -0
  46. /package/{examples → templates/default/examples}/permissions/interfaces/IBatchPermission.sol +0 -0
  47. /package/{examples → templates/default/examples}/permissions/interfaces/IPermission.sol +0 -0
package/AGENTS.md CHANGED
@@ -14,7 +14,7 @@ tooling to create SMAs, register permission contracts, and run strategy agents.
14
14
  | `packages/cli` | `sailor` | CLI: init, keys, account, mandate, onboard, station, ui, run, session, scan, status, owner, doctor, capabilities |
15
15
  | `packages/ui` | `sailor-ui` | Local dashboard + browser-driven onboarding wizard (per-project port, 3333–3999) |
16
16
  | `templates/default` | — | Default agent starter: neutral blank scaffold + Foundry workspace + onboarding guide (AGENTS.md) |
17
- | `examples/custom-mandate` | — | Solidity reference: IPermission scaffold (not a project template) |
17
+ | `templates/default/examples/custom-mandate` | — | Solidity reference: IPermission scaffold (not a project template) |
18
18
 
19
19
  ## Protocol roles
20
20
 
package/README.md CHANGED
@@ -1,85 +1,33 @@
1
1
  # Sailor
2
2
 
3
- > The operator toolkit for Sail Protocol — SDK, CLI, and local dashboard for building and running mandated agents.
4
-
5
- Sailor is the off-chain operator layer for [Sail Protocol](https://github.com/sail-money/SailProtocol): the tooling an operator uses to create a Separately Managed Account, register a mandate, and run a strategy agent against it. It wraps SailKernel dispatch, MandateFactory registration, and EIP-712 mandate signing behind a TypeScript SDK, a CLI, and a local dashboard. It does not deploy the protocol or author permission templates — those live in Sail Protocol. It targets already-deployed SailKernel instances and gives operators the tooling to drive them.
6
-
7
- ---
8
-
9
- ## What's inside
10
-
11
- | Package | Name | Role |
12
- |---|---|---|
13
- | `packages/sdk` | `@sail.money/sdk` / `@sail.money/sailor/sdk` | TypeScript library: SailorClient, EIP-712 helpers, ABIs, deployment registry, chain registry |
14
- | `packages/cli` | `@sail.money/sailor` | CLI for account setup, mandate signing, and agent execution |
15
- | `packages/ui` | `sailor-ui` | Local dashboard (per-project port; see Dashboard below) |
16
- | `templates/default` | — | The agent starter `sailor init` scaffolds: slim `AGENTS.md` + on-demand skills under `.agents/skills/` |
17
- | `examples/permissions` | — | Worked permission contracts by protocol and chain (reference, unaudited) |
18
- | `examples/custom-mandate` | — | Solidity reference: IPermission authoring scaffold |
19
- | `examples/lifi-permissions` | — | Solidity reference: LiFi clone permission contracts (source of the clone implementations) |
20
-
21
- ---
22
-
23
- ## Protocol model
24
-
25
- ```mermaid
26
- flowchart TD
27
- Owner["**Owner**<br/>holds the Safe · signs the mandate"]
28
- Manager["**Manager**<br/>agent · signs dispatches"]
29
- SMA["**SMA**<br/>Safe · holds assets · executes"]
30
- Mandate["**Mandate**<br/>set of permission contracts"]
31
- Kernel["**Sail Kernel**<br/>evaluates permission · trusted core<br/>dispatches to Safe on success"]
32
-
33
- Owner -- "01 deploys & owns" --> SMA
34
- Owner -- "02 signs mandate (EIP-712)" --> Mandate
35
- Owner -- "03 appoints · instant revocation" --> Manager
36
- Manager -- "04 signs dispatch (EIP-712)" --> Kernel
37
- Mandate -- "05 defines bounds" --> Kernel
38
- Kernel -- "06 ✓ executes · ✗ outside mandate: reverts" --> SMA
39
- ```
40
-
41
- Sailor is the operator tooling that drives the Manager/dispatch and mandate-registration flows (steps 02–05).
42
-
43
- ---
44
-
45
- ## Roles
46
-
47
- Sail Protocol separates three authority roles. Sailor operates all of them:
3
+ > The open-source toolkit TypeScript SDK, CLI, and local dashboard for operating agent-managed Separately Managed Accounts on [Sail Protocol](https://github.com/sail-money/protocol).
48
4
 
49
- | Role | Authority | Held by |
50
- |---|---|---|
51
- | **Owner** | Holds the Safe. Custody anchor. Always self-custodial. | The LP (Safe owner) |
52
- | **Permission Signer** | Authorizes the mandate. Signs registration and revocation via EIP-712. | Same as Owner, or a separate signing key |
53
- | **Manager** | Executes dispatches within mandate bounds. Signs each dispatch. | The agent wallet — encrypted in `.sail/keys/manager.json` |
5
+ [![npm version](https://img.shields.io/npm/v/%40sail.money%2Fsailor)](https://www.npmjs.com/package/@sail.money/sailor)
6
+ [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
7
+ [![Tests](https://github.com/sail-money/Sailor/actions/workflows/tests.yml/badge.svg)](https://github.com/sail-money/Sailor/actions/workflows/tests.yml)
8
+ [![node >= 18](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
54
9
 
55
- ---
10
+ ## What you can build
56
11
 
57
- ## How it works
12
+ An autonomous or semi-autonomous agent that manages capital inside a **self-custodial Safe**, bounded by **onchain permissions it cannot exceed**. The owner holds the Safe and signs a mandate — a set of permission contracts encoding exactly what the agent may do (which venues, which tokens, what size). The agent executes within those bounds; anything outside them is rejected by the SailKernel before it touches funds, and the owner can revoke the agent's dispatch rights instantly without moving assets. The trust model — what the contracts enforce versus what stays off-chain — is specified in the [Sail Protocol repo](https://github.com/sail-money/protocol) and the [whitepaper](https://github.com/sail-money/protocol/blob/main/docs/whitepaper/Sail_Protocol_Whitepaper.pdf).
58
13
 
59
- The path from nothing to a running agent follows the protocol lifecycle:
14
+ ## What's in the box
60
15
 
61
- 1. **Deploy your SMA and agent wallet** — `sailor onboard --new-sma` creates the SMA on-chain. `sailor account predict` computes the deterministic address in advance. The same owner, permission signer, manager, and salt produce the same SMA address on every supported chain.
62
- 2. **Author your permissions** — describe what the agent may do. Permission contracts encode the bounds: tokens, amounts, venues, call targets. Author them in the scaffolded Foundry workspace.
63
- 3. **Simulate, deploy, and sign your mandate** `sailor mandate simulate` probes a permission off-chain before authorizing it. `sailor mandate deploy --attach` deploys and registers it on-chain. `sailor mandate sign` builds and signs the registration payload against live on-chain state.
64
- 4. **Run** `sailor run` executes the agent loop. Three execution hosts compose: run it locally on a schedule, install it as a local OS service (`sailor service install` launchd/systemd/Task Scheduler) that restarts on crash, or let the GitHub Actions cron workflow the scaffold provides run it. `sailor trigger github` fires that workflow on demand.
65
- 5. **Operate** `sailor doctor` checks kernel health and gas balances; `sailor chains` lists supported chains and deployment addresses; `sailor session pause` instantly revokes dispatch rights without touching Safe custody. After a CLI upgrade, `sailor update` resyncs agent tooling files (skills, `AGENTS.md`, `Dockerfile`) without touching user code or runtime state.
66
-
67
- Run `npx sailor init my-agent`, open the scaffolded folder in Claude Code, Cursor, or any AI coding assistant, and say **"start"**.
68
-
69
- ### How the assistant is guided
70
-
71
- The scaffold follows the open [Agent Skills](https://agentskills.io) standard: a slim, always-loaded `AGENTS.md` carries the welcome flow, project-state map, and hard invariants, while detailed procedures live in seven on-demand skills under `.agents/skills/` (onboarding, project info, servers, transactions, mandates, CI, extensions). Assistants that scan skills load each one only when relevant; assistants that don't follow the routing table in `AGENTS.md` to the same plain-markdown files. Works in Claude Code, Cursor, Copilot, and Codex.
16
+ | Piece | What it does |
17
+ |---|---|
18
+ | **SDK** (`@sail.money/sailor/sdk`) | `SailorClient`, encrypted keyring, EIP-712 signing, dispatch submission, deployment + chain registries, template encoders |
19
+ | **CLI** (`sailor`) | Everything from `sailor init` to `sailor run`: keys, SMA deployment, mandate lifecycle, agent loop, doctor, session control |
20
+ | **Dashboard** (`sailor ui`) | Local web UI for onboarding, balances, mandate health, activity, and owner signing |
21
+ | **Scaffolded skills** | Step-by-step procedures under `.agents/skills/` that your AI coding assistant follows to set up and operate the agent |
72
22
 
73
- ---
23
+ **About the scaffold.** `sailor init` scaffolds your project from `templates/default/`, which ships two things together: the `.agents/skills` your assistant follows, and the **worked example permissions** (`templates/default/examples/` → your project's `examples/`) those skills teach from — protocol-specific bounding patterns (Uniswap, Aave, GMX, ERC-4626, and more) plus an `IPermission` authoring workspace. The examples are shipped teaching material inside every scaffold, not repo furniture.
74
24
 
75
25
  ## Installation
76
26
 
77
- ### Start a new agent project (recommended)
78
-
79
- Create a folder, step into it, then install and init:
27
+ ### npm
80
28
 
81
29
  ```bash
82
- # bash / zsh / macOS
30
+ # bash / zsh (macOS, Linux)
83
31
  mkdir my-agent && cd my-agent && npm i @sail.money/sailor && npx sailor init
84
32
  ```
85
33
 
@@ -88,476 +36,89 @@ mkdir my-agent && cd my-agent && npm i @sail.money/sailor && npx sailor init
88
36
  mkdir my-agent ; cd my-agent ; npm i @sail.money/sailor ; npx sailor init
89
37
  ```
90
38
 
91
- Then open the folder in your AI coding assistant and say **"start"**.
92
-
93
- > **npx shortcut** — skips the explicit install; npm downloads sailor on the fly:
94
- > ```sh
95
- > mkdir my-agent && cd my-agent && npx sailor init
96
- > ```
97
-
98
- ### Global CLI (for direct sailor commands)
99
-
100
- ```sh
101
- npm install -g @sail.money/sailor
102
- sailor init my-agent
103
- ```
39
+ Requires Node.js **>= 18**. For a global CLI instead: `npm install -g @sail.money/sailor`.
104
40
 
105
41
  ### Docker (no Node.js required)
106
42
 
107
- Run sailor from a pre-built image — useful when you don't want to install Node.js or want an isolated environment:
108
-
109
43
  ```bash
110
44
  mkdir my-agent && cd my-agent
111
45
  docker run -d --name agent -P -v "${PWD}:/workspace" sailmoney/sailor
112
46
  docker exec agent sailor init
113
47
  ```
114
48
 
115
- Then open the folder in your AI coding assistant and say **"start"**. See the [Docker Hub](#docker-hub-publish-dockeryml) section below for full usage details.
116
-
117
- ---
49
+ Project files live on your host via the volume mount; prefix `sailor` commands with `docker exec agent`. Full details: [docs/docker.md](./docs/docker.md).
118
50
 
119
51
  ## Quickstart
120
52
 
121
- Prerequisites:
122
-
123
- - Node.js 18+
124
- - A wallet (MetaMask, Rabby, Phantom, and more)
125
- - An RPC URL (e.g. Alchemy free tier)
126
- - A supported chain: **Ethereum, Base, Arbitrum, Unichain, Base Sepolia, or Eth Sepolia** — verified deployments are bundled in `@sail.money/sailor`.
127
-
128
- ### Recommended — assistant-driven
129
-
130
- ```bash
131
- # bash / zsh / macOS
132
- mkdir my-agent && cd my-agent && npm i @sail.money/sailor && npx sailor init && npm install
133
- ```
134
-
135
- ```powershell
136
- # PowerShell (Windows)
137
- mkdir my-agent ; cd my-agent ; npm i @sail.money/sailor ; npx sailor init ; npm install
138
- ```
139
-
140
- Open this folder in Claude Code, Cursor, Codex, or any AI coding assistant and say **"start"**. The scaffolded `AGENTS.md` and its skills guide the assistant through the whole flow — SMA deployment, strategy definition, mandate authoring, running, and automation. No manual steps required.
141
-
142
- ### Direct CLI reference
143
-
144
- ```bash
145
- # Discovery
146
- sailor chains # list supported chains and kernel addresses
147
- sailor capabilities # what you can build on this chain — read-only, no gas
148
- sailor doctor # kernel model + RPC reachability + gas balances
149
-
150
- # SMA setup
151
- sailor account predict # compute deterministic SMA address before deploying
152
- sailor onboard --new-sma # deploy SMA and optionally attach a mandate
153
-
154
- # Mandate lifecycle
155
- sailor mandate simulate # probe a permission off-chain (no gas) before registering
156
- sailor mandate sign # sign the mandate — reconciles against live on-chain state
157
- sailor mandate deploy # deploy a Foundry-compiled permission contract
158
- sailor mandate attach # register a deployed permission on an SMA (or a comma-separated list, in one signature)
159
-
160
- # Agent operation
161
- sailor run --once # single tick — confirm it works before automating
162
- sailor run # start the agent (continuous)
163
- sailor keys export-ci # copy encrypted agent wallet to ci-keystore.json for CI
164
-
165
- # Unattended execution
166
- sailor service install # run as a local OS daemon (launchd/systemd/Task Scheduler), restarts on crash
167
- sailor service status # whether the service is installed and running
168
- sailor service logs -f # follow the agent log (.sail/agent.log)
169
- sailor trigger github # fire the agent's GitHub Actions workflow on demand
170
-
171
- # Dashboard
172
- sailor ui start # prints the per-project dashboard URL
173
- sailor ui start --expose tailscale # also expose it on your tailnet over HTTPS (see Dashboard section)
174
-
175
- # Maintenance
176
- sailor update # re-sync skills, AGENTS.md, and tooling files after a CLI upgrade
177
- ```
178
-
179
- `sailor run` writes reverted transactions to stderr as `reverted: <txHash> (gas used: N)`; successful dispatches are appended to `.sail/activity.jsonl`.
180
-
181
- ---
182
-
183
- ## Templates
184
-
185
- `sailor init` scaffolds a new agent project from a template. By default it
186
- writes into the **current directory**; pass a name to create a subdirectory.
187
-
188
- ```bash
189
- sailor init # scaffold into cwd
190
- sailor init my-agent # create ./my-agent/ and scaffold there
191
- sailor init --template default # explicit (same as default)
192
- sailor init my-agent --template <name> # named subdirectory + specific template
193
- ```
194
-
195
- ### Available templates
196
-
197
- | Template | Description |
198
- |---|---|
199
- | `default` | Neutral agent starter. Includes a blank agent loop, Foundry workspace for permission contracts, GitHub Actions cron job, and the operator guide (`AGENTS.md`). For a complete worked example see `examples/dca/`. **Default.** |
200
-
201
- ### What makes a valid template
202
-
203
- A valid template is any directory under `templates/` that contains a
204
- `package.json`. Solidity reference sources live under `examples/`
205
- (`examples/permissions`, `examples/custom-mandate`, `examples/lifi-permissions`)
206
- — they are not project scaffolds and never appear in the template list.
207
-
208
- ### Adding a template
209
-
210
- 1. Create a directory under `templates/<your-template-name>/`.
211
- 2. Add a `package.json` (the `name` field is patched to the project name on
212
- init).
213
- 3. Add a `.sail/` workspace structure if the agent needs local state.
214
- 4. The template will appear automatically in `sailor init --template <name>`.
215
-
216
- Template files are bundled into the published `sailor` npm package via the
217
- `files` field in the root `package.json`.
218
-
219
- ---
220
-
221
- ## Dashboard (`sailor ui`)
222
-
223
- The Sailor dashboard is a local React app. It shows live account state, mandate
224
- health, signer balances, and recent activity — all read from the project's
225
- `.sail/` directory with no hosted backend.
226
-
227
- Each project gets its own deterministic port in the 3333–3999 range (derived
228
- from the project path, so several projects can run dashboards side by side).
229
- Use the URL the command prints, or read it from `.sail/runtime/ui.json` —
230
- do not assume port 3333.
231
-
232
- ### Commands
233
-
234
- ```bash
235
- sailor ui # start the dashboard (same as sailor ui start)
236
- sailor ui start # start the dashboard and print its URL
237
- sailor ui stop # stop the running dashboard
238
- sailor ui status # show whether the dashboard is running + URL + pid
239
- ```
240
-
241
- ### How it works
242
-
243
- `sailor ui start` spawns a bundled Express server (`server.cjs`) that:
244
-
245
- - Serves the pre-built React UI as static files on `/`
246
- - Exposes a local API on `/api` that reads `.sail/` state from the current
247
- working directory
248
-
249
- The server PID is written to `.sail/runtime/ui.json` on start. `sailor ui stop`
250
- reads that file, sends `SIGTERM` to the server process, and removes the file.
251
- This means you can start the dashboard in one terminal and stop it from another.
252
-
253
- ### Running in the background
254
-
255
- ```bash
256
- # macOS / Linux
257
- sailor ui start &
258
- sailor ui status # ● running http://localhost:<port> (pid 12345)
259
- sailor ui stop # Stopped Sailor UI (pid 12345).
260
-
261
- # Windows (PowerShell)
262
- Start-Job { sailor ui start }
263
- sailor ui status
264
- sailor ui stop
265
- ```
266
-
267
- ### Remote access over your tailnet (HTTPS) — optional
268
-
269
- The dashboard is local-only by default. To reach it from another device (e.g. a
270
- remote operator box), expose it over your [Tailscale](https://tailscale.com)
271
- tailnet on HTTPS:
272
-
273
- ```bash
274
- sailor ui start --expose tailscale
275
- # → Sailor UI started at http://localhost:<port>
276
- # → Exposed on your tailnet at https://<node>.<tailnet>.ts.net/
277
- ```
278
-
279
- It uses `tailscale serve` (tailnet-private), **never `funnel`** — only devices on
280
- your tailnet can reach it, not the public internet. `sailor ui stop` tears the
281
- tailnet proxy down along with the local server.
282
-
283
- Requirements:
284
-
285
- - `tailscale` installed and logged in (`tailscale up`).
286
- - Tailscale **Serve** enabled for your tailnet, plus **HTTPS certificates**
287
- (admin console → DNS → Enable HTTPS). If Serve is disabled, the command prints
288
- the enable link instead of reporting success.
289
-
290
- When exposed, the tailnet origin is added to the dashboard's CORS allowlist
291
- automatically. To allow additional origins (e.g. a custom HTTPS host in front of
292
- the station), set a comma-separated list — the local origin is always allowed:
293
-
294
- ```bash
295
- SAILOR_CORS_ORIGINS=https://hermes.example.ts.net,https://another.host
296
- ```
297
-
298
- By default the UI server binds `127.0.0.1` (local only). To reach it from another
299
- device **without** Tailscale — e.g. behind your own reverse proxy on a domain — bind
300
- all interfaces and throttle the key-management endpoints:
301
-
302
- ```bash
303
- SAILOR_HOST=0.0.0.0 # bind all interfaces (default 127.0.0.1)
304
- SAILOR_TRUST_PROXY=1 # hops to your proxy (or an IP allowlist), so rate limits key on the real client IP
305
- SAILOR_RATE_LIMIT_PER_MIN=100 # cap /api/signer + /api/onboard/generate-key (default 100)
306
- ```
307
-
308
- Behind a reverse proxy, set `SAILOR_TRUST_PROXY` (usually `1`) — otherwise the rate
309
- limiter sees only the proxy's IP and applies one shared bucket to all clients.
310
-
311
- The key-management endpoints are **unauthenticated** — only expose them behind your
312
- own auth (reverse-proxy basic-auth, or a private tailnet), never the open internet.
313
-
314
- ---
315
-
316
- ## Agent-driven onboarding & custom mandates
317
-
318
- On any of the six supported chains, an agent can drive the whole setup through
319
- a browser **signing station**. The station is a local HTTP + WebSocket daemon
320
- that bridges the CLI and the owner's wallet: the agent never holds the owner
321
- key — it pushes signing requests, the owner approves them in the browser, and
322
- the agent submits the transactions it's allowed to.
53
+ The recommended path is assistant-driven: open the scaffolded folder in Claude Code, Cursor, Codex, or any AI coding assistant and say **"start"** — the scaffold's `AGENTS.md` and skills walk the assistant through everything below. The direct-CLI version of the same journey:
323
54
 
324
55
  ```bash
325
- sailor keys generate # create the manager (agent) key
326
- sailor station start & # signing daemon (serves the UI)
327
- # owner opens the printed URL once and connects their wallet
328
- sailor owner connect # detect & persist the owner
329
- sailor scan # discover the owner's Safes + state
330
- sailor onboard --new-sma # create an SMA + (optionally) attach a mandate
331
- ```
332
-
333
- Agents author their own permission contracts and deploy them from the scaffolded
334
- Foundry workspace (`mandates/`, with `@sail/interfaces/IPermission.sol` vendored
335
- under `.sail/contracts/`):
336
-
337
- ```bash
338
- forge build
339
- sailor mandate deploy --contract MyMandate \
340
- --args '["0xPermissionSigner", ["0xTarget"]]' \
341
- --attach --sma 0xSafe
342
- ```
343
-
344
- `deploy` emits a contract-creation signing request (the owner signs it in the
345
- browser); the deployed address is read from the receipt and tracked in
346
- `.sail/state/mandates.json`. `attach` reads the signer nonce, has the owner sign
347
- a `RegisterPermission` EIP-712 message, then the agent submits
348
- `kernel.registerPermission` with the exact registration fee. Every command takes
349
- `--json` for headless agent use; set `SAIL_PASSPHRASE` to unlock the manager key
350
- non-interactively.
351
-
352
- `sailor mandate sign` reconciles against the live on-chain `getPermissions()` call
353
- before building the mandate payload — permissions revoked on-chain are excluded even
354
- if they remain in the local `.sail/state/mandates.json` (which is an append-only
355
- historical record and is never modified by the reconciliation).
356
-
357
- ### GitHub Actions CI
358
-
359
- The scaffolded `.github/workflows/agent-tick.yml` runs `sailor run --once` on a
360
- cron schedule using `npm ci` (no pnpm required). Setup:
361
-
362
- 1. `sailor keys export-ci` — copies the encrypted agent wallet to `ci-keystore.json`
363
- in the project root and allowlists it in `.gitignore`. The geth v3 keystore is
364
- safe to commit; the raw private key is never exposed.
365
- 2. Commit `ci-keystore.json`, `.sail/account.json`, and `.sail/mandate.json`.
366
- 3. Add two repository secrets (Settings → Secrets → Actions):
367
- - `SAIL_PASSPHRASE` — the passphrase that encrypts the agent wallet
368
- - `RPC_URL` — your RPC endpoint
369
-
370
- The workflow copies `ci-keystore.json` to `.sail/keys/manager.json`, then calls
371
- `npx sailor run --once` with `SAIL_PASSPHRASE` set so the key is unlocked
372
- non-interactively. No private key ever appears in the workflow file or in secrets.
373
-
374
- ---
56
+ npx sailor init my-agent && cd my-agent && npm install
375
57
 
376
- ## Packages
58
+ # 1. Generate the agent's encrypted signing key (geth keystore v3 on disk)
59
+ sailor keys generate --type agent-wallet
377
60
 
378
- Sailor ships as a **single npm package** the SDK is bundled inside it and exposed via a subpath export:
61
+ # 2. Connect your wallet as owner, then deploy the SMA (a Safe) on-chain
62
+ sailor owner connect
63
+ sailor onboard --new-sma
379
64
 
380
- | Package | Contents |
381
- |---|---|
382
- | `@sail.money/sailor` | CLI binary, UI server, templates, examples, and SDK |
383
-
384
- The SDK is available as a subpath export for use in agent code:
385
-
386
- ```ts
387
- import type { Agent, AgentContext, Dispatch } from '@sail.money/sailor/sdk'
388
- ```
389
-
390
- The SDK is also published separately as `@sail.money/sdk` for projects that consume it independently of the CLI.
65
+ # 3. Give the agent a mandate — register + configure a shared permission
66
+ # template (swap, transfer, deposit, ...). The skills flow drives this
67
+ # conversationally; directly, it is register then configure:
68
+ sailor mandate attach --address <templateAddress> --sma <yourSMA>
69
+ sailor mandate configure --address <templateAddress> --template SwapPermission --args-file swap-config.json
391
70
 
392
- ### npm (`publish-npm.yml`)
393
-
394
- Published to the public npm registry under the `@sail.money` scope.
395
-
396
- | Trigger | Package | Version | dist-tag |
397
- |---|---|---|---|
398
- | Tag push (`v*`) | `@sail.money/sailor` | `1.2.0` | `latest` |
399
- | Manual dispatch | `@dev.sail.money/sailor` | `1.2.0-42` | `dev` |
400
-
401
- ```bash
402
- npm install @sail.money/sailor # latest stable (tag push)
71
+ # 4. Run the agent loop (or --once for a single tick)
72
+ sailor run --once
403
73
  ```
404
74
 
405
- For dev builds, the package name changes scope to `@dev.sail.money`. Use an alias so your import paths stay the same:
75
+ **See an action get blocked.** The fail-closed guarantee is testable before anything is at risk probe the mandate off-chain with `sailor mandate simulate` (an `eth_call`; spends no gas, signs nothing):
406
76
 
407
77
  ```bash
408
- npm install "@sail.money/sailor@npm:@dev.sail.money/sailor@dev"
78
+ sailor mandate simulate --address <templateAddress> \
79
+ --target <someContractOutsideYourMandate> \
80
+ --calldata 0xa9059cbb... --expect fail
409
81
  ```
410
82
 
411
- This installs the latest dev build and makes it available as `@sail.money/sailor` locally`@sail.money/sailor/sdk` imports continue to work unchanged.
412
-
413
- ### GitHub Packages (`publish.yml`)
83
+ Each probed call prints a verdict — `PASS`, `FAIL`, or `REVERT` — which is the permission contract's real `evaluate()` decision, exactly what the kernel consults on a live dispatch. A call outside your mandate shows `FAIL` (and `--expect fail` exits non-zero on a mismatch, so you can wire it into CI). At runtime the same protection reads: `sailor run` skips any planned call no registered permission accepts logged to the console (`skipped: no registered permission authorizes call to <target>`) and to `.sail/activity.jsonl` as `dispatch_denied` and if a transaction ever reaches the kernel outside its bounds, the kernel reverts it. Deny by default, at every layer.
414
84
 
415
- Published to GitHub Packages under the `@sail-money` scope for internal testing — no public npm registry required.
85
+ Longer walkthrough, including revocation: [docs/getting-started.md](./docs/getting-started.md).
416
86
 
417
- | Trigger | Package | dist-tag |
418
- |---|---|---|
419
- | Merge to `main` | `@sail-money/sailor` | `latest` |
420
- | Manual dispatch | `@sail-money/sailor-dev` | `dev` |
421
-
422
- Both builds require an alias since the package scope differs from `@sail.money`:
423
-
424
- ```bash
425
- npm install "@sail.money/sailor@npm:@sail-money/sailor@latest" --registry https://npm.pkg.github.com
426
- npm install "@sail.money/sailor@npm:@sail-money/sailor-dev@dev" --registry https://npm.pkg.github.com
427
- ```
428
-
429
- Or pin in `package.json`:
430
-
431
- ```json
432
- "dependencies": {
433
- "@sail.money/sailor": "npm:@sail-money/sailor@latest"
434
- }
435
- ```
436
-
437
- ```json
438
- "dependencies": {
439
- "@sail.money/sailor": "npm:@sail-money/sailor-dev@dev"
440
- }
441
- ```
87
+ ## How the assistant is guided (skills)
442
88
 
443
- Either way, `@sail.money/sailor/sdk` imports work unchanged.
89
+ The scaffold follows the open [Agent Skills](https://agentskills.io) standard: a slim, always-loaded `AGENTS.md` carries the project map and hard invariants, while detailed procedures live in on-demand skills under `.agents/skills/` — onboarding, transactions, mandate authoring, shared-template configuration (one skill per template), automation, and more. Shared templates are registered and configured *through* the skills because the safe order of operations (register → configure → simulate → verify) is encoded there once, instead of re-derived by every assistant. Skills are plain markdown; assistants that don't scan skills follow the routing table in `AGENTS.md` to the same files. See [docs/templates-and-skills.md](./docs/templates-and-skills.md).
444
90
 
445
- ### Docker Hub (`publish-docker.yml`)
91
+ ## Documentation
446
92
 
447
- A pre-built image is published to Docker Hub so you can run the CLI without installing Node.js locally. The image uses Alpine Linux and includes `tsx` (required to compile TypeScript agent code at runtime).
448
-
449
- | Trigger | Tag |
93
+ | Doc | What's in it |
450
94
  |---|---|
451
- | Merge to `main` or manual dispatch | `sailmoney/sailor:dev` |
452
- | Tag push (`v*`) | `sailmoney/sailor:<version>` + `sailmoney/sailor:latest` |
453
-
454
- #### Starting the container
455
-
456
- Run this from your project root. `-P` publishes all exposed ports to random available host ports; use a fixed `-p <host>:3334` if you want a stable UI port.
457
-
458
- ```bash
459
- docker run -d --name agent -P -v "${PWD}:/workspace" sailmoney/sailor
460
- ```
461
-
462
- - `-d` — detached, runs in the background
463
- - `--name agent` — container name used in all `docker exec` calls
464
- - `-P` — maps container ports (UI: 3334, station: 3141) to random host ports
465
- - `-v "${PWD}:/workspace"` — mounts the current project into the container
466
-
467
- #### Running sailor commands
468
-
469
- All sailor commands run via `docker exec`:
470
-
471
- ```bash
472
- docker exec agent sailor --version
473
- docker exec agent sailor init
474
- docker exec agent sailor ui start
475
- docker exec agent sailor run --once
476
- ```
477
-
478
- Project files are on your **local filesystem** — read and write them directly from local paths. Only `sailor` commands need the `docker exec` prefix; the volume mount makes files accessible to both sides.
479
-
480
- #### Opening the dashboard
481
-
482
- The UI always binds to port **3334 inside the container**, but the host-side port depends on how `-P` mapped it. Resolve it before opening the browser:
483
-
484
- ```bash
485
- docker port agent 3334
486
- # → 0.0.0.0:49201 (open http://localhost:49201 in the browser)
487
- ```
488
-
489
- #### Stopping
490
-
491
- ```bash
492
- docker stop agent # stop the container
493
- docker start agent # restart it later (project files and state are on the host)
494
- ```
495
-
496
- ---
95
+ | [docs/getting-started.md](./docs/getting-started.md) | Long-form quickstart: install first SMA → first mandate → first run → revocation |
96
+ | [docs/cli-reference.md](./docs/cli-reference.md) | The full `sailor` command surface, grouped by workflow |
97
+ | [docs/sdk-usage.md](./docs/sdk-usage.md) | `SailorClient` basics and every SDK subpath export, with examples |
98
+ | [docs/docker.md](./docs/docker.md) | Image, volumes, key handling, dashboard access, headless operation |
99
+ | [docs/templates-and-skills.md](./docs/templates-and-skills.md) | The shared-template catalog and how skills drive configuration and use |
100
+ | [docs/architecture.md](./docs/architecture.md) | The Sailor Sail Protocol boundary: what's onchain vs what this toolkit does |
497
101
 
498
102
  ## Security model
499
103
 
500
- - The agent signs dispatches; the kernel evaluates the named permission on every call. A permission returning false or exceeding its gas cap is treated as denial — fail-closed.
501
- - The Owner key controls the Safe and is never read by Sailor. Mandate signing requires a deliberate action by the permission signer.
502
- - The manager key is encrypted on disk using geth keystore v3 (scrypt + aes-128-ctr) and is never transmitted.
503
- - The session can be paused instantly via `sailor session pause` or the dashboard stop button; this does not affect Safe custody.
504
- - All addresses passed to the CLI are normalized with `getAddress()` (EIP-55 checksum). Mixed-case or lowercase inputs are accepted and canonicalized before any on-chain call or state write.
505
-
506
- ---
507
-
508
- ## State of the project
509
-
510
- Sailor is functional and published as [`@sail.money/sailor`](https://www.npmjs.com/package/@sail.money/sailor) on npm (v1.2.0). The SDK, CLI, keystore, mandate flows, agent runner, and dashboard are implemented and have been exercised end to end.
104
+ - The agent signs dispatches; the **kernel evaluates the named permission on every call**. A permission returning false, reverting, or exceeding its gas cap is a denial — fail-closed.
105
+ - The **Owner key controls the Safe and is never read by Sailor**. Mandate registration requires a deliberate signature from the permission signer in the browser signing station.
106
+ - The **manager (agent) key is encrypted on disk** (geth keystore v3: scrypt + aes-128-ctr) and never transmitted.
107
+ - The session can be **paused instantly** (`sailor session pause` or the dashboard) revoking dispatch rights without touching Safe custody.
108
+ - All addresses are EIP-55 normalized before any on-chain call or state write.
511
109
 
512
- The Sail Protocol trusted core is deployed on eleven chains Ethereum, Base, Arbitrum, Optimism, Unichain, BSC, World Chain, HyperEVM, MegaETH, Base Sepolia, and Eth Sepolia — via CREATE2, with every core contract at the same address on every chain. All eleven run the selective dispatch model with zero fees and are bootstrapped with a genesis allowlist so `createAccount` is usable immediately. These deployments are under an ongoing external audit by [Octane Security](https://octane.security) and are not final — do not use them with funds you are not prepared to lose.
513
-
514
- Shared permission templates (swap, swap-no-oracle, borrow, deposit, withdraw, transfer, approve-and-call-batch) are deployed and verified against the current kernel on every chain; they're populated as `knownTemplates` for all eleven chains in `packages/sdk/src/deployments.ts` (`standaloneTemplates` stays empty — it's the EIP-1167 clone-implementation registry, and these are shared multi-tenant templates).
515
-
516
- ---
110
+ Vulnerability reports: see [SECURITY.md](./SECURITY.md) (off-chain toolkit)smart-contract issues go to the [protocol's policy](https://github.com/sail-money/protocol/blob/main/SECURITY.md).
517
111
 
518
112
  ## Deployments
519
113
 
520
- All core contracts are deployed at the same address on every supported chain via CREATE2 (commit `1dc1960`, 2026-07-01, Safe-governed). An SMA created with the same owner, permission signer, manager, fee policy, and salt has the same address on every supported chain.
521
-
522
- ### Core addresses (identical on all 11 chains)
523
-
524
- | Contract | Address |
525
- |---|---|
526
- | SailKernel | `0x38b508756c976e876EFF05a29E731A4d348BA6ED` |
527
- | SailGovernance | `0x4315B37cA4A315A7042af1Fcb37F8436f4D24356` |
528
- | TimelockController | `0xC1E5F9A581D4100Aa949f80204540a33aD97A7b6` |
529
- | MandateFactory | `0x6d2C802ffa0d9A8Ed69A5Bf22c1b63ccB566B8Fc` |
530
- | StandardFeePolicy | `0x1087312447C8a2BfA15EB9cE23590E3502DBA04b` |
531
- | SafeModuleEnabler | `0x7897Cb53a4be4a2eaAf46D60573C4Fd83b33fE1F` |
532
- | Deployer | `0xB01dCE443d052e44b7D13726c0EC9fFB7f5815B6` |
533
- | Treasury | `0x7b37F85575F1568a37dBA342BC5FE6d393F0872f` |
114
+ The SDK bundles verified deployments for **11 chains** — mainnets: Ethereum (1), Base (8453), Arbitrum (42161), Optimism (10), Unichain (130), BSC (56), World Chain (480), HyperEVM (999), MegaETH (4326); testnets: Base Sepolia (84532), Ethereum Sepolia (11155111). Every core contract sits at the same address on every chain via CREATE2 (SailKernel: `0x38b508756c976e876EFF05a29E731A4d348BA6ED`), and the seven shared permission templates (swap, swap-no-oracle, borrow, deposit, withdraw, transfer, approve-and-call-batch) are deployed and registered as `knownTemplates` on all of them. Query it yourself: `sailor chains` or `getSailDeployment(chainId)` from the SDK; the canonical record is the protocol repo's [deployments/addresses.md](https://github.com/sail-money/protocol/blob/main/deployments/addresses.md).
534
115
 
535
- These addresses are bundled in `@sail.money/sailor` and exposed via `getSailDeployment(chainId)` in the SDK. The Protocol repository is the canonical source of truth for deployment details see [deployments/addresses.md](https://github.com/sail-money/Protocol/blob/main/deployments/addresses.md).
536
-
537
- ### Supported chains
538
-
539
- | Chain | Chain ID |
540
- |---|---|
541
- | Ethereum | 1 |
542
- | Base | 8453 |
543
- | Arbitrum | 42161 |
544
- | Optimism | 10 |
545
- | Unichain | 130 |
546
- | BSC | 56 |
547
- | World Chain | 480 |
548
- | HyperEVM | 999 |
549
- | MegaETH | 4326 |
550
- | Base Sepolia | 84532 |
551
- | Eth Sepolia | 11155111 |
552
-
553
- ---
116
+ These deployments are under an ongoing external **security review** by [Octane](https://octane.security) and are not final do not use them with funds you are not prepared to lose.
554
117
 
555
118
  ## Contributing
556
119
 
557
- Sailor and Sail Protocol are separate repositories with separate concerns. Protocol questions SailKernel internals, permission templates, MandateFactory, fee policies belong in the [SailProtocol](../SailProtocol) repository. Sailor questions — the SDK, CLI, dashboard, and agent templates — belong here.
558
-
559
- ---
120
+ Sailor will be continuously enhanced through community participation and feedbackcontributions, issue reports, and design discussions are actively welcomed. Start with [CONTRIBUTING.md](./CONTRIBUTING.md).
560
121
 
561
122
  ## License
562
123
 
563
- MIT
124
+ [MIT](./LICENSE) © Agentic Finance Inc.