@dev.sail.money/sailor 1.2.1-94 → 1.3.0-206
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 +63 -0
- package/package.json +2 -1
- package/packages/cli/dist/index.cjs +70 -2
- package/packages/sdk/dist/intelligence.d.ts +1 -1
- package/packages/sdk/dist/intelligence.js +1 -1
- package/scripts/clean.mjs +17 -0
- package/templates/default/.agents/skills/sail-onboarding/SKILL.md +36 -0
- package/templates/default/.agents/skills/sail-servers/SKILL.md +26 -0
- package/templates/default/AGENTS.md +1 -1
package/README.md
CHANGED
|
@@ -102,6 +102,18 @@ npm install -g @sail.money/sailor
|
|
|
102
102
|
sailor init my-agent
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
+
### Docker (no Node.js required)
|
|
106
|
+
|
|
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
|
+
```bash
|
|
110
|
+
mkdir my-agent && cd my-agent
|
|
111
|
+
docker run -d --name agent -P -v "${PWD}:/workspace" sailmoney/sailor
|
|
112
|
+
docker exec agent sailor init
|
|
113
|
+
```
|
|
114
|
+
|
|
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
|
+
|
|
105
117
|
---
|
|
106
118
|
|
|
107
119
|
## Quickstart
|
|
@@ -382,6 +394,57 @@ Or pin in `package.json`:
|
|
|
382
394
|
|
|
383
395
|
Either way, `@sail.money/sailor/sdk` imports work unchanged.
|
|
384
396
|
|
|
397
|
+
### Docker Hub (`publish-docker.yml`)
|
|
398
|
+
|
|
399
|
+
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).
|
|
400
|
+
|
|
401
|
+
| Trigger | Tag |
|
|
402
|
+
|---|---|
|
|
403
|
+
| Merge to `main` or manual dispatch | `sailmoney/sailor:dev` |
|
|
404
|
+
| Tag push (`v*`) | `sailmoney/sailor:<version>` + `sailmoney/sailor:latest` |
|
|
405
|
+
|
|
406
|
+
#### Starting the container
|
|
407
|
+
|
|
408
|
+
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.
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
docker run -d --name agent -P -v "${PWD}:/workspace" sailmoney/sailor
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
- `-d` — detached, runs in the background
|
|
415
|
+
- `--name agent` — container name used in all `docker exec` calls
|
|
416
|
+
- `-P` — maps container ports (UI: 3334, station: 3141) to random host ports
|
|
417
|
+
- `-v "${PWD}:/workspace"` — mounts the current project into the container
|
|
418
|
+
|
|
419
|
+
#### Running sailor commands
|
|
420
|
+
|
|
421
|
+
All sailor commands run via `docker exec`:
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
docker exec agent sailor --version
|
|
425
|
+
docker exec agent sailor init
|
|
426
|
+
docker exec agent sailor ui start
|
|
427
|
+
docker exec agent sailor run --once
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
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.
|
|
431
|
+
|
|
432
|
+
#### Opening the dashboard
|
|
433
|
+
|
|
434
|
+
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:
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
docker port agent 3334
|
|
438
|
+
# → 0.0.0.0:49201 (open http://localhost:49201 in the browser)
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
#### Stopping
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
docker stop agent # stop the container
|
|
445
|
+
docker start agent # restart it later (project files and state are on the host)
|
|
446
|
+
```
|
|
447
|
+
|
|
385
448
|
---
|
|
386
449
|
|
|
387
450
|
## Security model
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dev.sail.money/sailor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0-206",
|
|
4
4
|
"description": "Operator toolkit for Sail Protocol",
|
|
5
5
|
"bin": {
|
|
6
6
|
"sailor": "packages/cli/dist/index.cjs"
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"AGENTS.md"
|
|
25
25
|
],
|
|
26
26
|
"scripts": {
|
|
27
|
+
"clean": "node scripts/clean.mjs",
|
|
27
28
|
"build": "pnpm --filter @sail/sdk build && pnpm --filter sailor build && pnpm --filter sailor-ui build",
|
|
28
29
|
"test": "pnpm --filter sailor-ui test",
|
|
29
30
|
"test:ui": "pnpm --filter sailor-ui test:ui",
|
|
@@ -38519,7 +38519,8 @@ var import_websocket2 = __toESM(require_websocket2(), 1);
|
|
|
38519
38519
|
var import_websocket_server2 = __toESM(require_websocket_server2(), 1);
|
|
38520
38520
|
|
|
38521
38521
|
// src/signing/server.ts
|
|
38522
|
-
var
|
|
38522
|
+
var _signingPort = parseInt(process.env.SAILOR_STATION_PORT ?? "", 10);
|
|
38523
|
+
var DEFAULT_SIGNING_PORT = Number.isFinite(_signingPort) && _signingPort >= 1 && _signingPort <= 65535 ? _signingPort : 3141;
|
|
38523
38524
|
var RUNTIME_SUBDIR = (0, import_node_path4.join)(".sail", "runtime");
|
|
38524
38525
|
var SERVER_STATE_FILE = "server.json";
|
|
38525
38526
|
var REQUEST_SECRET_HEADER = "x-sailor-secret";
|
|
@@ -40693,6 +40694,9 @@ function scaffoldProjectWorkspace(dest, name, options) {
|
|
|
40693
40694
|
import_node_fs9.default.mkdirSync(import_node_path8.default.join(sailDir2, "keys"), { recursive: true });
|
|
40694
40695
|
import_node_fs9.default.mkdirSync(import_node_path8.default.join(sailDir2, "runtime"), { recursive: true });
|
|
40695
40696
|
import_node_fs9.default.mkdirSync(import_node_path8.default.join(sailDir2, "state"), { recursive: true });
|
|
40697
|
+
const installMode = process.env.SAILOR_INSTALL_MODE === "docker" ? "docker" : "local";
|
|
40698
|
+
const _rawContainerName = process.env.SAILOR_CONTAINER_NAME ?? "agent";
|
|
40699
|
+
const containerName = /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(_rawContainerName) ? _rawContainerName : "agent";
|
|
40696
40700
|
import_node_fs9.default.writeFileSync(
|
|
40697
40701
|
import_node_path8.default.join(sailDir2, "config.json"),
|
|
40698
40702
|
`${JSON.stringify(
|
|
@@ -40703,6 +40707,8 @@ function scaffoldProjectWorkspace(dest, name, options) {
|
|
|
40703
40707
|
// null = chain not yet chosen; Stage 1 will set this
|
|
40704
40708
|
stateDir: ".sail/state",
|
|
40705
40709
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40710
|
+
installMode,
|
|
40711
|
+
...installMode === "docker" ? { containerName } : {},
|
|
40706
40712
|
contracts: {
|
|
40707
40713
|
kernel: "",
|
|
40708
40714
|
mandateFactory: ""
|
|
@@ -40794,6 +40800,14 @@ Pass --force to scaffold into it anyway (existing files with the same name are o
|
|
|
40794
40800
|
"This project is already initialized.\nRun `sailor update` to re-sync template files, or `sailor init --force` to re-initialize (overwrites scaffold files; your .sail/keys/ and .sail/state/ are left in place)."
|
|
40795
40801
|
);
|
|
40796
40802
|
}
|
|
40803
|
+
const existingConfigPath = import_node_path8.default.join(dest, ".sail", "config.json");
|
|
40804
|
+
const previousConfig = import_node_fs9.default.existsSync(existingConfigPath) ? (() => {
|
|
40805
|
+
try {
|
|
40806
|
+
return JSON.parse(import_node_fs9.default.readFileSync(existingConfigPath, "utf-8"));
|
|
40807
|
+
} catch {
|
|
40808
|
+
return null;
|
|
40809
|
+
}
|
|
40810
|
+
})() : null;
|
|
40797
40811
|
copyDirSync(templateSrc, dest);
|
|
40798
40812
|
const pkgRoot = packageRoot();
|
|
40799
40813
|
const examplesPermSrc = import_node_path8.default.join(pkgRoot, "examples", "permissions");
|
|
@@ -40833,6 +40847,18 @@ Pass --force to scaffold into it anyway (existing files with the same name are o
|
|
|
40833
40847
|
}
|
|
40834
40848
|
scaffoldProjectWorkspace(dest, name, options);
|
|
40835
40849
|
scaffoldFoundryWorkspace(dest);
|
|
40850
|
+
const newMode = process.env.SAILOR_INSTALL_MODE === "docker" ? "docker" : "local";
|
|
40851
|
+
if (previousConfig?.installMode === "docker" && newMode === "local") {
|
|
40852
|
+
const prev = previousConfig.containerName ?? "agent";
|
|
40853
|
+
console.log(`
|
|
40854
|
+
Switched to local install. If the Docker container is still running:`);
|
|
40855
|
+
console.log(` docker stop ${prev}`);
|
|
40856
|
+
console.log(`You can restart it anytime with the standard docker run command.`);
|
|
40857
|
+
} else if (previousConfig?.installMode === "local" && newMode === "docker") {
|
|
40858
|
+
const containerName = process.env.SAILOR_CONTAINER_NAME ?? "agent";
|
|
40859
|
+
console.log(`
|
|
40860
|
+
Switched to Docker install (container: ${containerName}).`);
|
|
40861
|
+
}
|
|
40836
40862
|
printWelcome(
|
|
40837
40863
|
dest,
|
|
40838
40864
|
name,
|
|
@@ -40943,6 +40969,12 @@ Created ${name}/`);
|
|
|
40943
40969
|
"\u2551 If you skip this step, setup WILL break and you will have to \u2551",
|
|
40944
40970
|
"\u2551 restart. There are no shortcuts. \u2551",
|
|
40945
40971
|
"\u2551 \u2551",
|
|
40972
|
+
"\u2551 IF SAILOR IS RUNNING IN DOCKER: \u2551",
|
|
40973
|
+
"\u2551 \u2022 Read project files from your local filesystem \u2014 they are \u2551",
|
|
40974
|
+
"\u2551 shared via volume mount, do NOT use docker exec to read them. \u2551",
|
|
40975
|
+
"\u2551 \u2022 Prefix every sailor command with: \u2551",
|
|
40976
|
+
"\u2551 docker exec <containerName> sailor <command> \u2551",
|
|
40977
|
+
"\u2551 \u2551",
|
|
40946
40978
|
"\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D",
|
|
40947
40979
|
""
|
|
40948
40980
|
].join("\n"));
|
|
@@ -40996,6 +41028,41 @@ async function updateCommand() {
|
|
|
40996
41028
|
}
|
|
40997
41029
|
const added = [];
|
|
40998
41030
|
copyDirSyncIfMissing(templateSrc, dest, added);
|
|
41031
|
+
const configPath = import_node_path9.default.join(dest, ".sail", "config.json");
|
|
41032
|
+
try {
|
|
41033
|
+
const config = JSON.parse(import_node_fs10.default.readFileSync(configPath, "utf-8"));
|
|
41034
|
+
const newMode = process.env.SAILOR_INSTALL_MODE === "docker" ? "docker" : "local";
|
|
41035
|
+
const _rawContainerName = process.env.SAILOR_CONTAINER_NAME ?? "agent";
|
|
41036
|
+
const containerName = /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(_rawContainerName) ? _rawContainerName : "agent";
|
|
41037
|
+
if (config.installMode !== newMode) {
|
|
41038
|
+
const previousMode = config.installMode;
|
|
41039
|
+
const previousContainer = config.containerName;
|
|
41040
|
+
config.installMode = newMode;
|
|
41041
|
+
if (newMode === "docker") {
|
|
41042
|
+
config.containerName = containerName;
|
|
41043
|
+
} else {
|
|
41044
|
+
delete config.containerName;
|
|
41045
|
+
}
|
|
41046
|
+
import_node_fs10.default.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
|
|
41047
|
+
`, "utf-8");
|
|
41048
|
+
if (previousMode === "docker" && newMode === "local") {
|
|
41049
|
+
const prev = previousContainer ?? "agent";
|
|
41050
|
+
console.log(`
|
|
41051
|
+
Switched to local install. If the Docker container is still running:`);
|
|
41052
|
+
console.log(` docker stop ${prev}`);
|
|
41053
|
+
console.log(`You can restart it anytime with the standard docker run command.`);
|
|
41054
|
+
} else if (newMode === "docker") {
|
|
41055
|
+
console.log(`
|
|
41056
|
+
Switched to Docker install (container: ${containerName}).`);
|
|
41057
|
+
}
|
|
41058
|
+
} else if (newMode === "docker" && config.containerName !== containerName) {
|
|
41059
|
+
config.containerName = containerName;
|
|
41060
|
+
import_node_fs10.default.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
|
|
41061
|
+
`, "utf-8");
|
|
41062
|
+
}
|
|
41063
|
+
} catch {
|
|
41064
|
+
console.warn("Warning: could not update install mode in .sail/config.json");
|
|
41065
|
+
}
|
|
40999
41066
|
if (removed.length === 0 && updated.length === 0 && added.length === 0) {
|
|
41000
41067
|
console.log("Nothing to update.");
|
|
41001
41068
|
return;
|
|
@@ -45148,7 +45215,8 @@ async function uiCommand() {
|
|
|
45148
45215
|
const serverBundle = import_node_path16.default.resolve(distDir, "server.cjs");
|
|
45149
45216
|
const projectRoot = process.cwd();
|
|
45150
45217
|
const sailDir2 = import_node_path16.default.join(projectRoot, ".sail");
|
|
45151
|
-
const
|
|
45218
|
+
const envPort = Number(process.env.PORT);
|
|
45219
|
+
const port = await findFreePort(Number.isInteger(envPort) && envPort > 0 && envPort <= 65535 ? envPort : projectPort(projectRoot));
|
|
45152
45220
|
if (!import_node_fs20.default.existsSync(serverBundle)) {
|
|
45153
45221
|
throw new Error(`Server bundle not found at ${serverBundle}. Re-run the sailor build.`);
|
|
45154
45222
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Do not edit manually — run `pnpm build` to regenerate.
|
|
6
6
|
*
|
|
7
7
|
* Spec version : 1.2.0
|
|
8
|
-
* Generated at : 2026-06-
|
|
8
|
+
* Generated at : 2026-06-23T09:10:35.761Z
|
|
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.0
|
|
8
|
-
* Generated at : 2026-06-
|
|
8
|
+
* Generated at : 2026-06-23T09:10:35.761Z
|
|
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";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { rmSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
const targets = [
|
|
4
|
+
"node_modules",
|
|
5
|
+
"packages/sdk/node_modules",
|
|
6
|
+
"packages/sdk/dist",
|
|
7
|
+
"packages/sdk/tsconfig.tsbuildinfo",
|
|
8
|
+
"packages/cli/node_modules",
|
|
9
|
+
"packages/cli/dist",
|
|
10
|
+
"packages/ui/node_modules",
|
|
11
|
+
"packages/ui/dist",
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
for (const p of targets) {
|
|
15
|
+
rmSync(p, { recursive: true, force: true });
|
|
16
|
+
console.log(` removed ${p}`);
|
|
17
|
+
}
|
|
@@ -7,6 +7,42 @@ description: Walks the agent through setting up a new Sailor project or resuming
|
|
|
7
7
|
|
|
8
8
|
## Running the CLI
|
|
9
9
|
|
|
10
|
+
**Determine the installation mode first** — read `.sail/config.json → installMode` before running any command:
|
|
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
|
|
29
|
+
|
|
30
|
+
After starting, resolve the host port before opening the UI in the browser:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
docker port agent 3334
|
|
34
|
+
# → 0.0.0.0:49201 (use 49201, not 3334, in the browser URL)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
All `sailor` commands run via `docker exec`:
|
|
38
|
+
|
|
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
|
+
```
|
|
45
|
+
|
|
10
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.
|
|
11
47
|
|
|
12
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.
|
|
@@ -36,6 +36,32 @@ sailor station stop --json # SIGTERM, verified against the recorded URL first
|
|
|
36
36
|
|
|
37
37
|
Signing-flow commands (`mandate deploy/attach/deploy-clone/revoke`, `onboard`, `account deploy-chain`, `account rotate-signer`, `owner connect`) push requests to a running station daemon if one exists, otherwise they spin up an ephemeral in-process signing server for the duration of the command. Starting a persistent station first means the owner connects their wallet once and approves a whole sequence of requests in the same browser tab — do this before any multi-step signing flow.
|
|
38
38
|
|
|
39
|
+
## Docker installation
|
|
40
|
+
|
|
41
|
+
If `.sail/config.json → installMode` is `"docker"`, prefix every command with `docker exec <containerName>` (read `containerName` from the same config):
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
docker exec agent sailor ui start
|
|
45
|
+
docker exec agent sailor ui status
|
|
46
|
+
docker exec agent sailor ui stop
|
|
47
|
+
|
|
48
|
+
docker exec agent sailor station start --json
|
|
49
|
+
docker exec agent sailor station status --json
|
|
50
|
+
docker exec agent sailor station stop --json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The UI always binds to port **3334 inside the container** (the image sets `ENV PORT=3334`), but the host-side port depends on how the container was started. Before giving the user a URL, resolve the actual host port:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
docker port <containerName> 3334
|
|
57
|
+
# → 0.0.0.0:3334 (host port matches)
|
|
58
|
+
# → 0.0.0.0:8080 (host port is different — use 8080 in the URL)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The URL to open in the browser is `http://localhost:<host-port>` where `<host-port>` is what `docker port` returned, not necessarily 3334. Never hard-code the port — always resolve it first.
|
|
62
|
+
|
|
63
|
+
Project files at `/workspace` are your local directory — read and write them directly from local paths; only `sailor` commands need the `docker exec` prefix.
|
|
64
|
+
|
|
39
65
|
## Troubleshooting
|
|
40
66
|
|
|
41
67
|
- Command stuck "waiting"? It is blocked on a browser signature — check `GET /config` `pendingCount`, and tell the user to open the station URL and approve. Signing requests time out after 10 minutes.
|
|
@@ -77,7 +77,7 @@ Detailed procedures live in skills. If your tooling does not auto-discover skill
|
|
|
77
77
|
|
|
78
78
|
| Skill | Load when | Path |
|
|
79
79
|
|---|---|---|
|
|
80
|
-
| sail-onboarding | New project setup, or resuming a partially set-up project | `.agents/skills/sail-onboarding/SKILL.md` |
|
|
80
|
+
| sail-onboarding | New project setup, or resuming a partially set-up project, documentation of sailor commands | `.agents/skills/sail-onboarding/SKILL.md` |
|
|
81
81
|
| sail-project-info | Any question about project, account, mandate, chain, or environment state | `.agents/skills/sail-project-info/SKILL.md` |
|
|
82
82
|
| sail-servers | Starting, stopping, or health-checking the dashboard or signing station | `.agents/skills/sail-servers/SKILL.md` |
|
|
83
83
|
| sail-transactions | Building dispatches or any EVM transaction for the agent | `.agents/skills/sail-transactions/SKILL.md` |
|