feat: Agent Skills for the Sawala CLI and MCP servers, plus sawala skills install - #97
Merged
Conversation
Establish .agents/skills/ as the canonical Agent Skills directory (read by Codex and Copilot) with .claude/skills as a relative symlink for Claude Code. Adds the sawala-cli orientation skill: establish scope before acting, choose between CLI and MCP, the surface map, shared write conventions (PUT replacement), safety rails, and failure triage keyed to the CLI's real error strings.
Datana: collections, records, the filter grammar, the pipeline plane, and a
references/field-types.md covering every SchemaField type and the options keys
that are silently dropped.
Kontena: schemas, entries, locales, and the single-vs-collection distinction.
Documents the entry envelope ({locale,data,slug,status}) against Datana's bare
field-values body, since confusing them is a guaranteed 422.
Corrects two facts that no longer hold at HEAD: --q searches all text fields
(not data.title), and record list defaults to limit=100 (not 25).
Tugasna: boards/statuses/items/comments/tags/timeline plus a backlog reference. Documents two departures from the content stores — updates are PATCH not PUT, and dates are epoch-ms numbers not ISO strings. Sebar: the CLI is inbound email config (org-scoped) plus broadcast campaigns (project-scoped) — not sender/message management. broadcast create SENDS with no undo, so it is documented as dry-run-then-approve. Akuna: connections and data residency. Isolation is effectively one-way, so the skill requires status -> dry-run -> explicit user approval. Also corrects sawala-cli's shared write conventions: PUT-replacement is a Kontena/Datana rule, not universal.
kodena-deploy: the three deploy shapes, the mandatory kodena.json, and the blank Content-Type trap scoped correctly — Kodena's default shim already carries an extension-map safety net, so only worker-bundle (OpenNext) deploys are exposed. Also records that run_worker_first is set by the service, so callers should not try to set it. sawala-ajena: pull -> edit -> validate -> push --check as the only safe workflow, the token-derived scoping that puts no projectId in the path, the per-step enabled switch for bisecting, and the secret-free round-trip.
scripts/check-skills-coverage.mjs fails CI when a CLI command group or MCP tool name appears in no skill, when a skill breaks the Agent Skills spec (name pattern, name/dir match, description length, 500-line body, dangling links), or when a skill contains a credential-shaped string. Wired as npm run check:skills and added to ci.yml. Adding the tool names surfaced 53 undocumented tools; each is now in a CLI-to-MCP mapping table in the owning skill rather than a bare name list.
Relocates the eight customer-facing skills to packages/sawala/skills/ so they ride the npm tarball, symlinked back into .agents/skills/ so contributors and customers read the same bytes. Adds sawala skills list|install|uninstall. --target maps to each vendor's discovery directory (agents/codex -> .agents/skills, claude -> .claude/skills, copilot -> .github/skills or ~/.copilot/skills, all -> three); default is agents, which Codex and Copilot both read. When only .agents is written and a .claude/ exists, it suggests --target all or a symlink rather than acting. Requested names are matched against the bundled set and never joined into a path; destinations outside cwd/home need --force; existing folders are never overwritten without --force. 16 tests including four negative cases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Ships nine Agent Skills that teach an AI coding agent how to drive the Sawala CLI and MCP servers, plus a
sawala skills installcommand that puts them on a customer's machine and a CI guard that stops them drifting behind the code.The skills carry what
--helpdoes not: that a collection or schemaupdateis a PUT replacement so adding a field means pull-append-push, that a Datana boolean filter silently returns zero rows, that Tugasna dates are epoch-ms numbers, thatsebar broadcast createsends with no undo, and thatakuna isolateis effectively one-way.Layout — one copy, three vendors
SKILL.mdis a cross-vendor standard, but the discovery directory is not:.agents/skills/only — not.codex, not.claude.agents/skills/,.github/skills/, or.claude/skills/.claude/skills/So
.agents/skills/is canonical (the one directory Codex and Copilot both read) with.claude/skillsa relative symlink. No generated per-vendor copies, nothing to drift.The skills
sawala-cli(orientation, shared conventions, Formulir + Berkasna) ·sawala-kontena·sawala-datana·sawala-tugasna·sawala-sebar·sawala-akuna·sawala-ajena·kodena-deploy·sawala-cli-dev(internal, not published).Formulir and Berkasna get no skill of their own — read-only
list/getwith no traps, so a skill would only restate--help.Five documented facts were wrong at HEAD
Every gotcha was verified against source before being written down. Five did not survive:
--qsearches alltextfields, notdata.title. The service deliberately widened it; the CLI/MCP help strings are stale.record listsendslimit=100when the flag is omitted, while its help says 25.Content-Typedefect is already fixed for static deploys — the default shim carries an extension→MIME safety net. Only worker-bundle (OpenNext) deploys are exposed, because they replace that shim.run_worker_firstis set by the service, not the caller.Two CLI defects found, not fixed here
Documentation-only PR, so both are documented rather than patched:
SAWALA_PROJECTdesynchronises slug from id.loadContextreadsactiveProjectfrom the env var butactiveProjectIdonly from config. Kontena/Datana put the ULID in the path whileapiFetchsends the slug asx-project-id— so the request names two different projects. Cross-project correctness bug.requireActiveProjectadvertises--project, a flag@sawala/clinever wires (every call site isloadContext(SAWALA_BRAND)with no options). Onlykodena deploypasses them.Also stale: Datana's
--qand--limithelp strings. All four are small follow-ups.The guard
scripts/check-skills-coverage.mjs, wired asnpm run check:skillsand intoci.yml. Fails when a CLI command group or MCP tool name appears in no skill, when a skill breaks the spec (name pattern, name/dir match, description ≤1024, body ≤500 lines, dangling links), or when a skill contains a credential-shaped string.It tests mention, not correctness — no script can judge whether a description is accurate, and a stricter rule would be gamed by pasting names in a footer. Mention is enough to force the author to open the skill.
Adding the 53 tool names surfaced them as undocumented; each is now in a CLI↔MCP mapping table in its owning skill.
Verification
npm run typecheck— cleannpm run test— 538 passednpm run check:skills— 53/53 MCP tools, 29/29 command groups across 9 skillslist,install --dry-run(writes nothing),install, re-run refuses without--force,--target allwrites three copies--target,--dir /etc/cron.d— all exit 1 and write nothingpackages/sawala/test/skills.test.ts, including four negative casesNot done
Confirming activation in Codex and Copilot needs a human at those agents. The mechanical half is covered by the spec validation in CI; what remains is the disambiguation pass — that "add a field to my collection" reaches
sawala-datanaand notsawala-kontena, and three similar pairs.ExecPlan:
docs/plan/cli/PLAN-sawala-agent-skills.mdinsawala-cloud.