These guides are primarily for agent readers. They explain how agents use Sails. If you are a person, start at sails.app or Add Sails.

Check a site before you publish

check walks a folder and re-runs the validations that run when an agent writes a page, a handler, or a client script. There is no build command. Catch broken front matter, MiniJinja, *.api.sh types, and JS/TS parse errors before the public URL serves them.

Skill source of truth: /skills/check.md.

This is not TypeScript type-checking (typecheck walks for tsconfig.json and reports type errors). check --js only parses *.ts / *.tsx / *.js / *.jsx / *.mjs / *.cjs with SWC (same path as published transpile). It is also not a live HTTP hit (handler-test dry-runs a script against the session workspace).

Done looks like

check --path pages --pages

prints JSON with "ok": true and "errors": []. You then open the existing publish URL. You did not create a second mount to “test.”

Worked example: this guides site

Job: you edited pages/how-to/*.page.md. Confirm templates compile, then ship on the mount that already tracks the branch.

check --path pages --pages

Expected shape (counts change):

{
  "ok": true,
  "path": "sites/sails-guides/pages",
  "files_checked": 33,
  "shell_files": 0,
  "page_files": 33,
  "js_files": 0,
  "errors": [],
  "warnings": []
}

path is repo-relative. Exit status stays 0 unless the command itself failed (bad path). Read "ok". Warnings still allow "ok": true.

All three kinds, from the site root (pages + shell handlers + JS/TS under the tree):

check --path .

On this guides site that report includes js_files: 1 (public/theme.js) alongside the page count.

--path defaults to the current directory and must stay under $HOME. With no --shell / --pages / --js, all three run. Skips node_modules, .git, target, dist, .sails. Unsupported bash parameter expansions fail closed at compile time (see help doctor).

When "ok" is false

{
  "ok": false,
  "errors": [
    {
      "path": "pages/how-to/example.page.md",
      "line": 8,
      "column": 1,
      "kind": "frontmatter",
      "message": "…"
    }
  ]
}
kindMeaning
frontmatterYAML on a .page.html / .page.md
templateMiniJinja failed (same path as publish). line is the source file
shellBash syntax or unknown command in a script
typerequest / respond / tool schema mismatch. line is in the script body after front matter
javascriptSWC parse failed on a *.ts / *.tsx / *.js / *.jsx / *.mjs / *.cjs file

Fix the file, run check again, stop when "ok": true. Autosave already updates a published mount.

Worked example: form handler types

Job: you added pages/subscribe.api.sh next to a form. Lint it without POSTing the live URL.

check --path pages --shell

Then prove behavior:

handler-test pages/subscribe.api.sh --method POST --form 'email=ada@example.com'

handler-test prints JSON (kind: api) with status/body. Schema failures show up as assertable results (for example status 400), not a crash. It does not hit the published mount. --auth only accepts {"signed_in":true} or false — you cannot forge sub / role.

See Put a form on a site for a full subscribe form.

Worked example: client JS parse

Job: you edited public/theme.js (or a *.ts / *.tsx under the site). Confirm it parses the same way publish will transpile it.

check --path public --js

Expected shape when the file is clean:

{
  "ok": true,
  "path": "sites/sails-guides/public",
  "files_checked": 1,
  "shell_files": 0,
  "page_files": 0,
  "js_files": 1,
  "errors": [],
  "warnings": []
}

A syntax error lands in errors with kind: "javascript" and a line / column in that file. Fix the script, re-run until "ok": true.

TypeScript types are a different tool:

typecheck --path site

That walks up for tsconfig.json (or uses platform defaults). It does not compile MiniJinja and it does not replace check --js.

Flags

check help
FlagWhat it does
(none)--shell, --pages, and --js
--path PATHRoot to walk (default: cwd)
--shell*.sh, *.api.sh, *.mcp.sh, *.tool.sh
--pages.page.html / .page.md front matter + MiniJinja
--js*.ts / *.tsx / *.js / *.jsx / *.mjs / *.cjs SWC parse

Failure modes

What you seeWhat it meansWhat to do
"ok": false, kind: templateMiniJinja will fail at publishFix the component/page; do not guess the live HTML
"ok": false, kind: frontmatterYAML / required fieldsMatch other pages: title, current, draft: false
"ok": false, kind: typeHandler body vs response: / tool schemaAlign respond / tool with the schema; re-run check --shell
"ok": false, kind: javascriptSWC could not parse the scriptFix syntax at line / column; re-run check --js
Exit 0 but "ok": falseNormal — validation lives in JSONInspect errors; do not treat exit as green
typecheck clean, pages still breakDifferent toolcheck --pages
check --js clean, typecheck failsParse ≠ typesFix the reported type errors; keep using both
You ship create a second name to “test”Mounts are stable URLscheck, then edit; one mount per folder
handler-test looks fine, check failsDry-run is behavior; check is lint/types/parseFix both; ship only when check is "ok": true

See Publish a site and Static sites.