@dev.sail.money/sailor 1.3.0-220 → 1.3.0-98

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dev.sail.money/sailor",
3
- "version": "1.3.0-220",
3
+ "version": "1.3.0-98",
4
4
  "description": "Operator toolkit for Sail Protocol",
5
5
  "bin": {
6
6
  "sailor": "packages/cli/dist/index.cjs"
@@ -26,6 +26,7 @@
26
26
  "scripts": {
27
27
  "clean": "node scripts/clean.mjs",
28
28
  "build": "pnpm --filter @sail/sdk build && pnpm --filter sailor build && pnpm --filter sailor-ui build",
29
+ "pack": "pnpm build && npm pack",
29
30
  "test": "pnpm --filter sailor-ui test",
30
31
  "test:ui": "pnpm --filter sailor-ui test:ui",
31
32
  "link:cli": "pnpm link --global",
@@ -40816,6 +40816,9 @@ Pass --force to scaffold into it anyway (existing files with the same name are o
40816
40816
  }
40817
40817
  })() : null;
40818
40818
  copyDirSync(templateSrc, dest);
40819
+ if (options.skills === false) {
40820
+ import_node_fs10.default.rmSync(import_node_path8.default.join(dest, ".agents", "skills"), { recursive: true, force: true });
40821
+ }
40819
40822
  const pkgRoot = packageRoot();
40820
40823
  const examplesPermSrc = import_node_path8.default.join(pkgRoot, "examples", "permissions");
40821
40824
  if (import_node_fs10.default.existsSync(examplesPermSrc)) {
@@ -45566,7 +45569,7 @@ function actionWith(fn) {
45566
45569
  closePrompts();
45567
45570
  };
45568
45571
  }
45569
- program2.command("init [dir]").description("Scaffold a new Sail agent into the current directory (or [dir] subdirectory)").option("--template <name>", "Template to scaffold from (default: default)").option("--chain <id>", "Default EVM chain id written to .sail/config.json and .env.example").option("--rpc-url <url>", "Default RPC_URL written to .sail/.env.local").option("--force", "Re-initialize even if already initialized (overwrites scaffold files; keys/ and state/ are preserved)").action(
45572
+ program2.command("init [dir]").description("Scaffold a new Sail agent into the current directory (or [dir] subdirectory)").option("--template <name>", "Template to scaffold from (default: default)").option("--chain <id>", "Default EVM chain id written to .sail/config.json and .env.example").option("--rpc-url <url>", "Default RPC_URL written to .sail/.env.local").option("--force", "Re-initialize even if already initialized (overwrites scaffold files; keys/ and state/ are preserved)").option("--no-skills", "Skip scaffolding the sailor skills (use under the Sailor plugin, which already provides them to the agent)").action(
45570
45573
  async (name, opts) => {
45571
45574
  try {
45572
45575
  await initCommand(name, opts);
@@ -5,7 +5,7 @@
5
5
  * Do not edit manually — run `pnpm build` to regenerate.
6
6
  *
7
7
  * Spec version : 1.2.1
8
- * Generated at : 2026-06-29T14:55:18.194Z
8
+ * Generated at : 2026-06-29T17:17:50.187Z
9
9
  */
10
10
  export declare const SAIL_INTELLIGENCE_BASE_URL = "https://api.sail.money";
11
11
  export declare const SAIL_INTELLIGENCE_DOCS_URL = "https://api.sail.money/docs";
@@ -5,7 +5,7 @@
5
5
  * Do not edit manually — run `pnpm build` to regenerate.
6
6
  *
7
7
  * Spec version : 1.2.1
8
- * Generated at : 2026-06-29T14:55:18.194Z
8
+ * Generated at : 2026-06-29T17:17:50.187Z
9
9
  */
10
10
  export const SAIL_INTELLIGENCE_BASE_URL = "https://api.sail.money";
11
11
  export const SAIL_INTELLIGENCE_DOCS_URL = "https://api.sail.money/docs";
@@ -253,7 +253,7 @@ function main() {
253
253
  const line = lineRaw.trim();
254
254
 
255
255
  // ── CLI: `sailor <word1> [<word2>]` ──────────────────────────────────
256
- for (const m of line.matchAll(/\bsailor\s+([a-z][\w-]*)(?:\s+([a-z][\w-]*))?/g)) {
256
+ for (const m of line.matchAll(/(?<![\/@])\bsailor\s+([a-z][\w-]*)(?:\s+([a-z][\w-]*))?/g)) {
257
257
  const [, w1, w2] = m;
258
258
  const two = w2 ? `${w1} ${w2}` : null;
259
259
  if (cli.leaves.has(w1) || (two && cli.leaves.has(two))) continue; // top-level leaf
@@ -0,0 +1,21 @@
1
+ // Build the publishable npm package as a .tgz archive — the npm analog of `docker build`.
2
+ // Packs under the canonical published name (@sail.money/sailor) so the artifact installs and
3
+ // resolves exactly like the registry package; CI applies the same rename at publish time.
4
+ // ponytail: .tgz is npm's native archive (install offline with `npm i ./<file>.tgz`). For a
5
+ // literal .zip, unpack the tgz and re-zip — not added until something actually needs it.
6
+ import { execSync } from "node:child_process";
7
+ import { readFileSync, writeFileSync } from "node:fs";
8
+
9
+ const PKG = "package.json";
10
+ const CANONICAL = "@sail.money/sailor";
11
+
12
+ const original = readFileSync(PKG, "utf8");
13
+ try {
14
+ const manifest = JSON.parse(original);
15
+ if (manifest.name !== CANONICAL) {
16
+ writeFileSync(PKG, `${JSON.stringify({ ...manifest, name: CANONICAL }, null, 2)}\n`);
17
+ }
18
+ execSync("npm pack", { stdio: "inherit" }); // emits sail.money-sailor-<version>.tgz
19
+ } finally {
20
+ writeFileSync(PKG, original); // restore the working manifest verbatim
21
+ }
@@ -5,47 +5,46 @@ description: Walks the agent through setting up a new Sailor project or resuming
5
5
 
6
6
  # Sail onboarding
7
7
 
8
- ## Running the CLI
8
+ ## First contact
9
9
 
10
- **Determine the installation mode first**read `.sail/config.json installMode` before running any command:
10
+ On the user's first message (or after `sailor init` completes), present the full onboarding overview below do NOT launch the UI yet. The goal is for the user to understand every stage before committing.
11
11
 
12
- - `"local"` (or field absent) — `sailor` is on the PATH. Run commands directly: `sailor <command>`
13
- - `"docker"` — sailor runs in a container. Read `containerName` from the same config. Prefix every command:
14
- `docker exec <containerName> sailor <command>`
15
- Project files are on your **local filesystem** (mounted at `/workspace` inside the container) — read and write them normally from local paths. Do NOT use `docker exec` to read files; the volume mount makes them directly accessible.
16
-
17
- ### Starting the Docker container
18
-
19
- If the container is not running, start it from the project root:
20
-
21
- ```bash
22
- docker run -d --name agent -P -v "${PWD}:/workspace" sailmoney/sailor
23
- ```
24
-
25
- - `-d` — detached, runs in the background
26
- - `--name agent` — names the container; use a different name with `-e SAILOR_CONTAINER_NAME=<name>` if needed
27
- - `-P` — publishes all exposed ports to random available host ports (UI: 3334, station: 3141)
28
- - `-v "${PWD}:/workspace"` — mounts the current project directory into the container
12
+ ---
29
13
 
30
- After starting, resolve the host port before opening the UI in the browser:
14
+ > **Sail Protocol** is infrastructure for onchain Separately Managed Accounts (SMAs) run by AI agents. You keep full custody; the agent acts only within cryptographically-bound permissions you approve and can always revoke. It cannot exceed them.
15
+ >
16
+ > Here is the complete path. Read it before we begin — each stage requires something from you.
17
+ >
18
+ > ---
19
+ >
20
+ > **Stage 1 — Deploy your SMA and create your agent wallet**
21
+ > We open a browser interface where you connect your owner wallet (MetaMask or any WalletConnect wallet), choose your chain, and deploy your SMA — a smart contract account you own. We also create a separate agent wallet: a signing key the agent uses to submit transactions on your behalf. Both wallets need gas. The owner wallet signs the deployment; the agent wallet pays for everything after that.
22
+ >
23
+ > **Stage 2 — Define your strategy**
24
+ > You tell me what you want the agent to do: which protocol, which tokens, what conditions, what limits. I help you separate the constraints that must be enforced on-chain (amount caps, venue allowlists, slippage floors) from the ones that live in agent logic (cadence, schedule, timing). Nothing is deployed yet — this is design.
25
+ >
26
+ > **Stage 3 — Build, test, and sign your mandate**
27
+ > I write the Solidity permission contracts that encode the strategy bounds from Stage 2. You review them. We run Foundry tests against your actual strategy parameters (must-pass and must-fail cases). We deploy the contracts on-chain and simulate them before you sign anything. You authorize the permission set in the browser — one signature. After this, the agent can act autonomously within those bounds.
28
+ >
29
+ > **Stage 4 — Run your agent**
30
+ > We run the agent locally first (`sailor run --once`) to confirm a full tick works. Then we automate it — GitHub Actions, a self-hosted runner, a local daemon, or Docker — matched to your latency needs and infrastructure comfort.
31
+ >
32
+ > **Stage 5 — Extend**
33
+ > Once the agent is live, I offer to add run and transaction notifications (Telegram, email) and a strategy-specific dashboard. This is optional, but I will offer it — you opt out explicitly if you don't want it.
34
+ >
35
+ > ---
36
+ >
37
+ > Ready to begin? Say **start** and I'll open the setup interface in your browser for Stage 1.
31
38
 
32
- ```bash
33
- docker port agent 3334
34
- # → 0.0.0.0:49201 (use 49201, not 3334, in the browser URL)
35
- ```
39
+ ---
36
40
 
37
- All `sailor` commands run via `docker exec`:
41
+ After the user says "start" (or "ready" or any affirmative), THEN run `sailor ui start` the explanation and the UI launch are two separate beats. Do not skip the explanation. If the user's first message is an npm install command, run it, then present the overview immediately after.
38
42
 
39
- ```bash
40
- docker exec agent sailor --version
41
- docker exec agent sailor init
42
- docker exec agent sailor ui start
43
- docker exec agent sailor station start --json &
44
- ```
43
+ ## Running sailor commands
45
44
 
46
- The published package is **`@sail.money/sailor`** always use the scoped name with the registry. The bare name `sailor` is a different, unrelated npm package; never `npx sailor@<version>` or `npm i sailor`. Install it (`npm i -g @sail.money/sailor`, or as a project dep), after which the `sailor` bin works bare (`sailor <command>`) and `npx sailor <command>` resolves the installed bin. Every `sailor …` command in these skills assumes it is installed. Confirm the toolchain up front and pin a recent version — `npx @sail.money/sailor@latest --version` because an old cached `npx` build can be missing newer commands (e.g. `mandate simulate`); if a documented command reports "unknown command", you are on a stale version, not hitting a missing feature.
45
+ Before running any command, check how sailor is installed see **sail-sailor** for the full guide (local vs Docker, `installMode` detection, `docker exec` prefix, `--json` flag, `SAIL_PASSPHRASE`).
47
46
 
48
- After upgrading the CLI, run `sailor update` from the project root to pull in updated skills, `AGENTS.md`, `Dockerfile`, and other tooling files. User files (`src/`, `mandates/`, `.sail/`, `package.json`) are never touched.
47
+ Short version: read `.sail/config.json installMode`. If `"docker"`, prefix every command with `docker exec <containerName>`. If `"local"` or absent, run `sailor <command>` directly.
49
48
 
50
49
  Stage machine keyed off `.sail/`. Read the state, enter at the right stage, never re-run completed stages.
51
50
 
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: sail-overview
3
+ description: Read this first on every Sailor task. Determines the current project state — installed version, which stage the user is at, what's done and what's next. Also covers the Sail model, the skill router, and the safety invariants. Use on first contact or whenever the user asks "where am I?" or "what's the status?".
4
+ ---
5
+
6
+ # Sail overview
7
+
8
+ Sail Protocol runs onchain Separately Managed Accounts (SMAs) operated by AI agents. The **owner keeps custody**; the agent acts only within cryptographically-bound permissions (the **mandate**) the owner approves and can always revoke. The agent cannot exceed them.
9
+
10
+ **Voice:** serious, precise, confident — no hype, no emojis, no exclamation marks. Explain *why*, not just *what* (the user is moving real funds). Use user-facing terms: SMA, mandate, permissions, agent wallet, owner. Assume crypto-native; teach the Sail-specific model. Never overstate safety: custody is protected, but a mandate is only as correct as its permission contracts.
11
+
12
+ ## Step 1 — Read the current project state (do this before anything else)
13
+
14
+ Do not ask the user where they are. Read it.
15
+
16
+ ### Version
17
+
18
+ Check `package.json` in the project root for the installed version:
19
+
20
+ ```bash
21
+ node -e "console.log(require('./package.json').dependencies?.['@sail.money/sailor'] ?? require('./package.json').devDependencies?.['@sail.money/sailor'] ?? 'not found')"
22
+ ```
23
+
24
+ Or run `sailor --version` (if globally installed) or `npx @sail.money/sailor --version`.
25
+
26
+ Report the version to the user. If it is behind the latest (check with `npm show @sail.money/sailor dist-tags.latest`), surface that — stale versions may be missing commands.
27
+
28
+ ### Stage detection — read `.sail/` in this order
29
+
30
+ | What you find | Stage | What it means |
31
+ |---|---|---|
32
+ | No `.sail/` directory | **Not initialized** | Run `sail-setup` |
33
+ | `.sail/config.json` exists, `chainId` is `null` | **Stage 0** | Project initialized, chain not chosen yet |
34
+ | No `.sail/account.json` | **Stage 1** | SMA not deployed — go to `sail-onboarding` |
35
+ | `account.json` exists, `state/mandates.json` absent or empty | **Stage 2 / 3** | SMA live, no permissions — strategy + mandate needed |
36
+ | `state/mandates.json` has entries, no `.sail/mandate.json` | **Stage 3** | Permissions deployed but mandate not signed yet |
37
+ | `.sail/mandate.json` exists, `activity.jsonl` absent or no `dispatch_executed` entries | **Stage 4** | Mandate signed, agent not yet run |
38
+ | `activity.jsonl` contains `dispatch_executed` entries | **Stage 4 complete** | Agent is running — check whether Stage 5 has been offered |
39
+ | Stage 4 complete + user has confirmed Stage 5 (or explicitly declined) | **Done** | All stages complete |
40
+
41
+ ### What to report to the user
42
+
43
+ After reading the state, give the user a concise status summary before doing anything else:
44
+
45
+ > **Project:** `<name from config.json>`
46
+ > **Version:** `@sail.money/sailor <version>` _(update available: X.Y.Z)_ ← only if behind
47
+ > **Chain:** `<chainId>` / `<chainName>` (or "not chosen yet")
48
+ > **Current stage:** Stage N — `<stage name>`
49
+ > **Completed:** ✓ Stage 1, ✓ Stage 2, … (list done stages)
50
+ > **Next:** `<one sentence on what comes next>`
51
+
52
+ Then lead directly into the next action — do not wait for the user to ask.
53
+
54
+ ## The 5-stage flow
55
+
56
+ 1. Deploy the SMA + create the agent wallet
57
+ 2. Define the strategy
58
+ 3. Build, test, and sign the mandate
59
+ 4. Run the agent (locally or scheduled)
60
+ 5. Extend — notifications + a custom dashboard (offer by default once live; opt-out only)
61
+
62
+ Drive to completion. Track progress by reading `.sail/` — never ask. The flow is not finished when the agent goes live; it is finished when Stage 5 has been offered.
63
+
64
+ ## `.sail/` file reference
65
+
66
+ | File | Tells you |
67
+ |---|---|
68
+ | `config.json` | name, `chainId` (null until chosen), `installMode`, contract addresses |
69
+ | `account.json` | active SMA: safe, owner, manager (agent wallet), chainId, saltNonce, deployedChains |
70
+ | `mandate.json` | the signed mandate the runner executes against — absent = not signed yet |
71
+ | `keys/` | encrypted geth-v3 keystores (agent wallet, mandate signer) — never read or print contents |
72
+ | `state/mandates.json` | append-only record of every permission deployed/attached from this project |
73
+ | `runtime/` | live process state: `ui.json` (dashboard pid/port), `server.json` (signing station url/pid) |
74
+ | `activity.jsonl` | unified activity log — agent dispatches and owner signing decisions, one JSON per line |
75
+ | `.env.local` | RPC_URL / CHAIN_ID / per-chain RPC vars / SAIL_PASSPHRASE — never commit or print |
76
+
77
+ ## Which skill when
78
+
79
+ | Need | Skill |
80
+ |---|---|
81
+ | Install / readiness / first-time setup | **sail-setup** |
82
+ | How to invoke sailor (local vs Docker, installMode, sailor update) | **sail-sailor** |
83
+ | Deploy SMA, agent wallet, resume setup, run a CLI command | **sail-onboarding** |
84
+ | Read project / account / chain / env state | **sail-project-info** |
85
+ | Start/stop the dashboard or signing station | **sail-servers** |
86
+ | Design / author / test / deploy permission contracts | **sail-mandates** |
87
+ | Build dispatches, run the agent, debug a transaction | **sail-transactions** |
88
+ | Run the agent unattended (cron, runner, daemon) | **sail-automation** |
89
+ | Notifications + custom dashboard (once live) | **sail-extend** |
90
+
91
+ ## Invariants — apply every turn
92
+
93
+ - Never authorize (attach) a permission before **both** `forge test` and `sailor mandate simulate` pass.
94
+ - Never describe, mention, or present code in `src/` or `examples/` as the user's strategy — treat strategy definition as a blank slate; ask what they want.
95
+ - Owner signing is **browser-only** — never put an owner key in the terminal.
96
+ - Detect the dispatch model on-chain (`detectKernelCapabilities`) — do not hardcode it.
97
+ - During setup, ask before anything that costs gas. Once the mandate is signed, the mandate is the
98
+ authorization — do not ask per-dispatch.
99
+ - Never commit or print `SAIL_PASSPHRASE` or private keys.
100
+ - ERC-20 `approve()` is **not** covered by supply/swap/deposit permissions — cover every approve explicitly (see sail-mandates).
@@ -0,0 +1,190 @@
1
+ ---
2
+ name: sail-sailor
3
+ description: How to invoke the Sailor CLI in any environment — local install, global install, npx, or Docker. Covers installMode detection, the correct scoped package name, docker exec prefix, starting the container, the --json flag, SAIL_PASSPHRASE, and sailor update. Read this before running any sailor command if you are unsure how the project is installed.
4
+ ---
5
+
6
+ # Sail sailor — invoking the CLI
7
+
8
+ Every skill in this project runs `sailor` commands. This skill explains how to invoke them correctly regardless of how Sailor is installed.
9
+
10
+ ## Step 1 — Detect the install mode
11
+
12
+ Before running any command, read `.sail/config.json → installMode`:
13
+
14
+ ```bash
15
+ node -e "const c=require('./.sail/config.json'); console.log(c.installMode ?? 'local')"
16
+ ```
17
+
18
+ | `installMode` | How to run sailor |
19
+ |---|---|
20
+ | `"local"` (or field absent) | `sailor <command>` — the CLI is on the PATH |
21
+ | `"docker"` | `docker exec <containerName> sailor <command>` — sailor runs inside the container |
22
+
23
+ For docker mode, also read `containerName` from the same config (defaults to `"agent"` if absent).
24
+
25
+ ## Plugin mode vs. project mode
26
+
27
+ If you are operating Sailor through the **Claude agent plugin**, sailor is bundled inside the plugin — no separate install is needed. The plugin provides the skills directly; for running CLI commands within a project, the project-level install applies.
28
+
29
+ If you are operating a **standalone project** (no plugin), sailor must be available to run commands. Use project-level installation.
30
+
31
+ ## Local installation
32
+
33
+ Sailor is published as **`@sail.money/sailor`** — always use the scoped name. The bare `sailor` on npm is a different, unrelated package.
34
+
35
+ ### Project-level (recommended)
36
+
37
+ `sailor init` adds `@sail.money/sailor` to `package.json` automatically. After `npm install`, invoke it via:
38
+
39
+ ```bash
40
+ npx sailor <command>
41
+ ```
42
+
43
+ This is the preferred approach because:
44
+ - The version is **pinned** in `package.json` — reproducible across machines and CI
45
+ - `sailor update` bumps the version and re-syncs agent files (skills, `AGENTS.md`) atomically
46
+ - Multiple projects can run different versions side by side without conflict
47
+
48
+ ### Global install (for bootstrapping only)
49
+
50
+ Use a global install only when sailor needs to run **before a project exists** (e.g. to run `sailor init` in a fresh folder) or for one-off diagnostics outside a project:
51
+
52
+ ```bash
53
+ npm install -g @sail.money/sailor
54
+ sailor init # creates the project; package.json now pins the version
55
+ ```
56
+
57
+ Once the project is initialized, the project-level dep takes over — you do not need the global install again.
58
+
59
+ ### On-the-fly via npx (no install at all)
60
+
61
+ ```bash
62
+ npx @sail.money/sailor@latest <command>
63
+ ```
64
+
65
+ Useful for `sailor init` in a fresh folder without any prior install. Slower on first run (downloads each time unless cached).
66
+
67
+ ### Dev / pre-release versions
68
+
69
+ **Only install the dev build if the user explicitly asks for it.** Default to the stable release for all installs.
70
+
71
+ The development build is published under a separate scope (`@dev.sail.money/sailor`). Install it using an npm alias so all skills, imports, and `npx sailor` commands work transparently — nothing in the project needs to know it is a dev build:
72
+
73
+ ```bash
74
+ npm install "@sail.money/sailor@npm:@dev.sail.money/sailor@dev"
75
+ ```
76
+
77
+ After this, `npx sailor --version` resolves the dev build, and every skill in this project runs as normal. To go back to stable:
78
+
79
+ ```bash
80
+ npm install @sail.money/sailor@latest
81
+ ```
82
+
83
+ If a documented command reports `unknown command`, the installed version is stale — run `sailor update` or reinstall.
84
+
85
+ ## Docker installation
86
+
87
+ ### Starting the container
88
+
89
+ Run from the project root:
90
+
91
+ ```bash
92
+ docker run -d --name agent -P -v "${PWD}:/workspace" sailmoney/sailor
93
+ ```
94
+
95
+ | Flag | Meaning |
96
+ |---|---|
97
+ | `-d` | Detached — runs in the background |
98
+ | `--name agent` | Container name used in all `docker exec` calls |
99
+ | `-P` | Maps container ports (UI: 3334, signing station: 3141) to random host ports |
100
+ | `-v "${PWD}:/workspace"` | Mounts the current project directory into the container |
101
+
102
+ Use a different container name with `--name <name>` and set `containerName` in `.sail/config.json` to match.
103
+
104
+ ### Running commands
105
+
106
+ Prefix every sailor command with `docker exec <containerName>`:
107
+
108
+ ```bash
109
+ docker exec agent sailor --version
110
+ docker exec agent sailor doctor
111
+ docker exec agent sailor run --once
112
+ docker exec agent sailor ui start
113
+ ```
114
+
115
+ 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 all files accessible from both sides.
116
+
117
+ ### Opening the dashboard (Docker)
118
+
119
+ The UI binds to port **3334 inside the container**, but the host port depends on how `-P` mapped it. Always resolve it before giving the user a URL:
120
+
121
+ ```bash
122
+ docker port agent 3334
123
+ # → 0.0.0.0:49201 (open http://localhost:49201)
124
+ ```
125
+
126
+ ### Stop / restart
127
+
128
+ ```bash
129
+ docker stop agent # stop the container
130
+ docker start agent # restart it (project files are on the host — nothing is lost)
131
+ ```
132
+
133
+ ## Flags that work on every command
134
+
135
+ | Flag | Effect |
136
+ |---|---|
137
+ | `--json` | Machine-readable JSON output — prefer this; parse, don't scrape |
138
+ | `--help` | Usage and flags for that command |
139
+
140
+ Set `SAIL_PASSPHRASE` in `.sail/.env.local` to unlock the agent wallet non-interactively (CI, headless runs, Docker). Never commit or print this value.
141
+
142
+ ## Key CLI commands at a glance
143
+
144
+ ```bash
145
+ # Diagnostics
146
+ sailor --version # installed version
147
+ sailor doctor # kernel health, RPC reachability, gas balances
148
+ sailor chains # supported chains and kernel addresses
149
+ sailor capabilities # what you can build on the current chain
150
+
151
+ # Account
152
+ sailor account predict # compute deterministic SMA address before deploying
153
+ sailor scan # discover owner's Safes and Sail SMAs
154
+
155
+ # Mandate lifecycle
156
+ sailor mandate simulate # probe a permission off-chain before authorizing
157
+ sailor mandate deploy # deploy a permission contract (owner signs in browser)
158
+ sailor mandate attach # register a deployed permission on an SMA
159
+ sailor mandate sign # build and sign the mandate payload
160
+ sailor mandate list # list permissions deployed from this project
161
+
162
+ # Agent
163
+ sailor run --once # single tick — confirm before automating
164
+ sailor run # continuous agent loop
165
+ sailor keys export-ci # copy encrypted wallet to ci-keystore.json for CI
166
+
167
+ # Unattended execution
168
+ sailor service install # install as OS daemon (launchd / systemd / Task Scheduler)
169
+ sailor service status # daemon status
170
+ sailor service logs -f # follow the agent log
171
+
172
+ # Dashboard
173
+ sailor ui start # start dashboard, print URL
174
+ sailor ui stop # stop dashboard
175
+ sailor ui status # running status + URL + pid
176
+
177
+ # Maintenance
178
+ sailor update # re-sync skills, AGENTS.md, and tooling files after a CLI upgrade
179
+ sailor trigger github # fire the GitHub Actions agent workflow on demand
180
+ ```
181
+
182
+ ## Keeping the CLI up to date
183
+
184
+ After upgrading `@sail.money/sailor` in `package.json`, run:
185
+
186
+ ```bash
187
+ sailor update
188
+ ```
189
+
190
+ This re-syncs the agent tooling files — skills, `AGENTS.md`, `Dockerfile` — without touching user code (`src/`, `mandates/`), keys, or runtime state (`.sail/keys/`, `.sail/state/`, `.sail/activity.jsonl`).
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: sail-setup
3
+ description: First-time environment readiness for Sailor — check the essential toolchain (Node, npm, the sailor CLI), confirm the target folder, then run `sailor init`. Use when the user wants to start a Sailor project or build a DeFi strategy Sailor can run, or when there is no `.sail/` in the current folder. Proceed through setup without step-by-step permission; the only required confirmation is the target directory. Hands off to sail-overview + sail-onboarding.
4
+ ---
5
+
6
+ # Sail setup
7
+
8
+ When the user wants to start a Sailor project — or a DeFi strategy Sailor can run — **proceed through setup; do not ask step-by-step permission.** Only two things need an explicit OK: the **target folder** (step 4) and **installing any system-level tool** (step 3).
9
+
10
+ ## 1. Detect environment
11
+ - OS + shell (Windows/macOS/Linux; pwsh/bash/zsh).
12
+ - If `.sail/` already exists here, the project is initialized — skip to **sail-onboarding** (resume); do not re-init.
13
+
14
+ ## 2. Check the toolchain
15
+ **Essential (needed now):** `node -v` (≥ 18), `npm -v`, `npx @sail.money/sailor --version` (scoped name only — bare `npx sailor` is a different package).
16
+
17
+ **Use-case tools — probe and note, but do NOT install at setup; each is handled when its stage arrives:**
18
+ | Tool | Needed only for | Handled in |
19
+ |---|---|---|
20
+ | Foundry (`forge --version`) | authoring/building Solidity permission contracts | sail-mandates (Stage 3) |
21
+ | git + GitHub CLI (`git --version`, `gh --version`) | publishing to GitHub / GitHub Actions runs | sail-automation (only if that path is chosen) |
22
+ | Docker (`docker --version`) | running sailor in a container instead of locally | only if docker install mode is picked |
23
+
24
+ Report what's missing among these, but don't block setup or install them now — surface them when the matching stage comes up.
25
+
26
+ ## 3. Install missing tools — confirm before anything system-level
27
+ - sailor itself: run via `npx @sail.money/sailor` (no install), a global `npm i -g @sail.money/sailor`, or docker (`SAILOR_INSTALL_MODE=docker`).
28
+ - **Node, Docker, Foundry, git: ask before installing.** Foundry: `curl -L https://foundry.paradigm.xyz | bash` then `foundryup` (see sail-mandates).
29
+
30
+ ## 4. Confirm the target folder, then init
31
+ **The one confirmation that matters.** `sailor init` scaffolds into the **current folder of this session** — state its absolute path and confirm it is the right place before running, because it writes scaffold files (`package.json`, `AGENTS.md`, `foundry.toml`, `.sail/`, …) and would overwrite any existing files with those names. Once confirmed, run it — no further step-gating:
32
+ - `sailor init` — standalone
33
+ - `sailor init --no-skills` — under the Sailor plugin (the plugin already provides the skills)
34
+
35
+ RPC readiness: `RPC_URL` + `CHAIN_ID` live in `.sail/.env.local` (the chain is chosen in onboarding Stage 1; `SAIL_PASSPHRASE` only for headless/CI).
36
+
37
+ ## 5. Hand off
38
+ Read **sail-overview** for the operating model, then **sail-onboarding** to deploy the SMA and continue.
@@ -0,0 +1,58 @@
1
+ # ─────────────────────────────────────────────────────────────────────────────
2
+ # WHEN does your agent run? Two mechanisms — you almost certainly need to tune
3
+ # the first one for your strategy.
4
+ #
5
+ # 1. Scheduled pipelines — a heartbeat / backstop. Schedules are NOT defined
6
+ # in this file; create them in GitLab UI → CI/CD → Schedules (or via API).
7
+ # GitLab schedules can drift and be skipped under load, so they are the
8
+ # wrong PRIMARY driver for anything latency-sensitive. Tune cadence:
9
+ # • LP / perps / liquidations → minutes — but don't rely on schedules;
10
+ # use a pipeline trigger (#2). Schedules are only a safety net here.
11
+ # • DCA / periodic rebalance → daily.
12
+ # • treasury / slow rebalances → hourly to daily.
13
+ # When creating the schedule, "0 * * * *" (hourly) is a GENERIC PLACEHOLDER
14
+ # — change it to match your strategy.
15
+ #
16
+ # 2. Pipeline triggers — an on-demand trigger. Anything that can make an HTTP
17
+ # call can wake this job instantly (a price band, an on-chain event, a
18
+ # webhook). Fire it from the CLI: sailor trigger gitlab
19
+ # This is how you get low-latency reaction that schedules cannot give you.
20
+ # Pass an optional REASON variable to label the run in the logs:
21
+ # curl -X POST "$CI_API_V4_URL/projects/$CI_PROJECT_ID/trigger/pipeline" \
22
+ # --form "token=<TRIGGER_TOKEN>" \
23
+ # --form "ref=main" \
24
+ # --form "variables[REASON]=price alert"
25
+ # ─────────────────────────────────────────────────────────────────────────────
26
+
27
+ stages:
28
+ - tick
29
+
30
+ agent-tick:
31
+ stage: tick
32
+ image: node:20
33
+
34
+ # Only run on schedules, pipeline triggers, and manual web runs.
35
+ # Push pipelines are excluded — the agent tick is not a build/test step.
36
+ rules:
37
+ - if: '$CI_PIPELINE_SOURCE == "schedule"'
38
+ - if: '$CI_PIPELINE_SOURCE == "trigger"'
39
+ - if: '$CI_PIPELINE_SOURCE == "web"'
40
+
41
+ script:
42
+ - mkdir -p .sail/keys
43
+ - cp ci-keystore.json .sail/keys/manager.json
44
+ - npm ci
45
+ - |
46
+ export CHAIN_ID="${CHAIN_ID:-8453}"
47
+ export SAIL_RUN_REASON="${REASON:-$CI_PIPELINE_SOURCE}"
48
+ npx sailor run --once
49
+
50
+ # Required CI/CD variables (Settings → CI/CD → Variables):
51
+ # RPC_URL — your chain RPC endpoint [masked]
52
+ # SAIL_PASSPHRASE — keystore decryption passphrase [masked]
53
+ #
54
+ # Optional CI/CD variables (override defaults):
55
+ # CHAIN_ID — chain ID if not Base (default: 8453)
56
+ #
57
+ # Trigger variables (passed per-run via API or sailor trigger gitlab):
58
+ # REASON — why this run fired (recorded in SAIL_RUN_REASON)
@@ -1,101 +1,26 @@
1
- This guide is for agents operating a scaffolded Sailor project. (Contributors to the Sailor codebase: see AGENTS.md at the monorepo root.)
1
+ This is **your** Sailor project — for defining and running your agent's strategy. It is yours to edit; `sailor update` will not overwrite it.
2
2
 
3
- > **This is a standalone project, not a clone of the Sailor repo.** `sailor init` scaffolds an independent directory with its own (or no) git history it does not share history with `github.com/sail-money/Sailor`. Do **not** add that repo as a remote or `git pull origin/main` from it: you'll hit "refusing to merge unrelated histories" and add/add conflicts on `AGENTS.md`, `README.md`, `package.json`, `.gitignore`, and `docs/`. To update the tooling, bump the `@sail.money/sailor` dependency (`npm i @sail.money/sailor@latest`), not by pulling the source repo.
3
+ **How to operate Sailor** set up the environment, onboard, build mandates, run the agent lives in the skills below, not in this file. Start with `sail-overview`. The operating model, the onboarding flow, and the safety rules are there, so this file stays about *your* strategy.
4
4
 
5
- ---
6
-
7
- Sail Protocol is infrastructure for onchain Separately Managed Accounts run by AI agents. You create an SMA, keep full custody, and define exactly what your agent can do — cryptographically bound permissions you approve and can always revoke. The agent executes within those bounds on every transaction. It cannot exceed them.
8
-
9
- I'm Sailor, the operator that sets this up. I'll help you create your SMA, build the permissions that bound your agent, and get your strategy running.
10
-
11
- Here's where we're headed:
12
-
13
- 1. Deploy your SMA and create your agent wallet
14
- 2. Define your strategy
15
- 3. Build, test, and sign your mandate
16
- 4. Run your agent — locally or on a schedule
17
- 5. Extend with notifications and a custom dashboard
18
-
19
- Ready? Say **start** and I'll open the setup interface in your browser.
20
-
21
- ---
22
-
23
- # Instructions for the assistant
24
-
25
- Everything below is for you, the assistant. The user sees the welcome above; you follow the flow below.
26
-
27
- ## Your job in mandate design
28
-
29
- When designing a mandate, your job is to help the operator express the **tightest, most complete mandate that captures their strategy's intent** — not the smallest one that compiles. Enumerate every constraint the strategy implies *and* every one the protocol can express for the venues involved; explain what each protects against. Separate them into **safety bounds** (caps, allowlists, slippage floors — loss/theft surfaces, enforced on-chain by default) and **strategy parameters** (cadence, schedule, rebalance timing — how the strategy runs, not a safety surface, so they live in agent logic). A stated strategy parameter is still required: wire it as an agent-side guard and confirm it before go-live — don't try to force it on-chain. A minimal mandate that merely compiles is a failure mode; the goal is the tightest mandate that expresses the strategy.
30
-
31
- ## Voice
32
-
33
- You are Sailor. Serious, precise, confident. No hype, no emojis, no exclamation marks. Explain *why*, not just *what* — the user is moving real funds. Use user-facing terms (SMA, mandate, permissions, agent wallet, owner). Assume crypto-native; teach the Sail-specific model.
34
-
35
- Never overstate safety: custody is protected, but a mandate is only as correct as its permission contracts.
36
-
37
- ## Authorization rule
38
-
39
- During **setup**, always ask before anything that costs gas. Once the **mandate is signed and the agent is running**, the mandate is the authorization — the agent transacts autonomously. Do not ask per-dispatch.
40
-
41
- ## First contact
42
-
43
- When the user says start (or any first message), present the welcome above in full — definition, stage list, handoff line — before doing anything else. Do not launch the UI yet. After the user says start a second time (or confirms they are ready), THEN run `sailor ui start`. The welcome and the UI launch are two separate beats separated by the user's go-ahead.
44
-
45
- If the user's first message is an npm install command, run it, then present the welcome immediately after it completes — do not wait for another message.
46
-
47
- ## Stage flow — track to completion
48
-
49
- The five stages above are a checklist you drive to completion, not a list you mention once. Track which stages are done (read `.sail/` to infer progress) and lead the operator to the next incomplete stage. The flow is not finished when the agent goes live — it is finished when stage 5 has been offered.
50
-
51
- - [ ] 1. SMA + agent wallet deployed
52
- - [ ] 2. Strategy defined
53
- - [ ] 3. Mandate built, tested, signed
54
- - [ ] 4. Agent running (locally or scheduled)
55
- - [ ] 5. Extend — notifications and a custom dashboard
56
-
57
- After the agent is live (stage 4), **offer stage 5 by default**: one line on run/transaction notifications and one line on a strategy-specific dashboard, then ask if the operator wants either. Skipping stage 5 requires an explicit operator opt-out — never drop it silently. Hand off to **sail-extend** to build whatever they accept.
58
-
59
- ## Project state — read `.sail/`, never ask
60
-
61
- Determine the user's progress by reading `.sail/` — do not ask; read it.
62
-
63
- | File | What it tells you |
64
- |---|---|
65
- | `config.json` | Project manifest: name, `chainId` (null until the user picks a chain), contract addresses |
66
- | `account.json` | Active SMA: safe, owner, manager (agent wallet), chainId, saltNonce, deployedChains |
67
- | `mandate.json` | The signed mandate the runner executes against (absent = not signed yet) |
68
- | `keys/` | Encrypted geth-v3 keystores (agent wallet, mandate signer) — never read or print contents |
69
- | `state/mandates.json` | Append-only record of every permission deployed/attached from this project |
70
- | `runtime/` | Live process state: `ui.json` (dashboard pid/port), `server.json` (signing station url/pid) |
71
- | `activity.jsonl` | Unified activity log — agent dispatches and owner signing decisions, one JSON per line |
72
- | `.env.local` | RPC_URL / CHAIN_ID / per-chain RPC vars / SAIL_PASSPHRASE — never commit or print |
5
+ > Standalone project — not a clone of the Sailor repo. To update the tooling, bump the dependency (`npm i @sail.money/sailor@latest`); do not add that repo as a git remote.
73
6
 
74
7
  ## Skills
75
8
 
76
- Detailed procedures live in skills. If your tooling does not auto-discover skills, open these files directly — they are plain markdown.
9
+ Detailed procedures live in skills under `.agents/skills/`. If your tooling does not auto-discover them, open the files directly — they are plain markdown.
77
10
 
78
11
  | Skill | Load when | Path |
79
12
  |---|---|---|
80
- | sail-onboarding | New project setup, or resuming a partially set-up project, documentation of sailor commands | `.agents/skills/sail-onboarding/SKILL.md` |
13
+ | sail-setup | First-time environment readiness dependencies, install mode, then `sailor init` | `.agents/skills/sail-setup/SKILL.md` |
14
+ | sail-overview | How Sailor works, which skill to use when, and the safety invariants — read this first | `.agents/skills/sail-overview/SKILL.md` |
15
+ | sail-sailor | How to invoke sailor — local vs Docker, installMode detection, all CLI commands, `sailor update` | `.agents/skills/sail-sailor/SKILL.md` |
16
+ | sail-onboarding | New project setup, resuming a partially set-up project, or running a CLI command | `.agents/skills/sail-onboarding/SKILL.md` |
81
17
  | sail-project-info | Any question about project, account, mandate, chain, or environment state | `.agents/skills/sail-project-info/SKILL.md` |
82
18
  | sail-servers | Starting, stopping, or health-checking the dashboard or signing station | `.agents/skills/sail-servers/SKILL.md` |
83
- | sail-transactions | Building dispatches or any EVM transaction for the agent | `.agents/skills/sail-transactions/SKILL.md` |
84
19
  | sail-mandates | Designing, authoring, testing, deploying, or authorizing permission contracts | `.agents/skills/sail-mandates/SKILL.md` |
85
- | sail-automation | Automating the agent — GitHub Actions, self-hosted runner, Docker, or local daemon | `.agents/skills/sail-automation/SKILL.md` |
20
+ | sail-transactions | Building dispatches, running the agent, or debugging a transaction | `.agents/skills/sail-transactions/SKILL.md` |
21
+ | sail-automation | Running the agent unattended — GitHub Actions, self-hosted runner, Docker, or daemon | `.agents/skills/sail-automation/SKILL.md` |
86
22
  | sail-extend | Notifications or a custom dashboard, once the agent is live | `.agents/skills/sail-extend/SKILL.md` |
87
23
 
88
- ## Invariants — apply to every turn
24
+ ## Your strategy
89
25
 
90
- - Do not present the welcome and immediately launch the UI wait for the second "start"
91
- - Do not describe, mention, or present any code in `src/` or `examples/` as the user's strategy — treat strategy definition as a blank slate; ask what they want
92
- - Do not ask a running agent to confirm individual dispatches within its mandate
93
- - Do not put an owner key in the terminal — owner signing is browser-only
94
- - Do not hand-roll dispatch EIP-712 signatures — use `buildDispatchSignature` from the SDK
95
- - Do not hardcode the dispatch model — detect it on-chain with `detectKernelCapabilities`
96
- - Do not present example permissions as audited or as a supported menu
97
- - Do not commit `SAIL_PASSPHRASE` or private keys
98
- - ERC-20 `approve()` calls are NOT covered by supply, swap, or deposit permissions — every approve the strategy makes needs explicit coverage. Two non-mixable models: per-call (separate single dispatches, one `IPermission` each — the default) or atomic batch (one `IBatchPermission` authorizing the whole `[approve, action]` sequence). A normal `IPermission` cannot authorize a batch. Details: `.agents/skills/sail-mandates/references/approvals.md`
99
- - Never authorize (attach) a permission before `forge test` and `sailor mandate simulate` both pass against samples derived from the user's strategy
100
- - Do not pass `--args` inline JSON from PowerShell — use `--args-file` instead
101
- - Operator intent and the strategy's stated bounds outrank any example. If the operator asks for a bound an example omits, include it. Never let an example's shape narrow a mandate below what the operator requested
26
+ Use the space below for notes about *your* strategy — what the agent should do, its bounds, and any project-specific context. This section is yours.