@sous-io/sous 0.1.0 → 0.2.0
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 +121 -35
- package/bin/run.js +10 -1
- package/docs/markdown/README.md +27 -0
- package/docs/markdown/_sidebar.md +18 -0
- package/docs/markdown/commands.md +308 -0
- package/docs/markdown/config-discovery.md +74 -0
- package/docs/markdown/config-inspection.md +69 -0
- package/docs/markdown/config-layers.md +92 -0
- package/docs/markdown/config-variables.md +79 -0
- package/docs/markdown/configuration.md +71 -0
- package/docs/markdown/design-principles.md +59 -0
- package/docs/markdown/repositories-authoring.md +408 -0
- package/docs/markdown/repositories-consuming.md +580 -0
- package/docs/markdown/repositories-file-formats.md +1084 -0
- package/docs/markdown/repositories-variables.md +387 -0
- package/docs/markdown/repositories.md +303 -0
- package/docs/markdown/skill-categories.md +58 -0
- package/package.json +73 -9
- package/{shared-prompts/skills/sous-skills → recipes/core/sous-skills/skills}/about-agent-skills/SKILL.tpl.md +20 -20
- package/{shared-prompts/skills/sous-skills → recipes/core/sous-skills/skills}/about-agent-skills/examples/about-something.md +2 -2
- package/{shared-prompts/skills/sous-skills → recipes/core/sous-skills/skills}/about-agent-skills/examples/do-something.md +1 -1
- package/{shared-prompts/skills/sous-skills → recipes/core/sous-skills/skills}/about-agent-skills/references/advanced-patterns.md +6 -6
- package/{shared-prompts/skills/sous-skills → recipes/core/sous-skills/skills}/about-agent-skills/references/commands.md +5 -5
- package/{shared-prompts/skills/sous-skills → recipes/core/sous-skills/skills}/about-agent-skills/references/frontmatter.md +3 -3
- package/{shared-prompts/skills/sous-skills → recipes/core/sous-skills/skills}/about-liquid-templates/SKILL.tpl.md +40 -25
- package/recipes/core/sous-skills/skills/about-sous/SKILL.tpl.md +70 -0
- package/recipes/core/sous-skills/skills/about-sous-configuration/SKILL.tpl.md +75 -0
- package/{shared-prompts/skills/sous-skills → recipes/core/sous-skills/skills}/create-skill/SKILL.tpl.md +8 -9
- package/recipes/core/sous-skills/sous.recipe.yaml +45 -0
- package/sous.config.schema.json +337 -0
- package/src/base-command.ts +220 -67
- package/src/commands/build.ts +150 -73
- package/src/commands/clear.ts +23 -15
- package/src/commands/compile.ts +74 -16
- package/src/commands/config/get.ts +110 -0
- package/src/commands/config/show.ts +32 -0
- package/src/commands/config/validate.ts +53 -0
- package/src/commands/help.ts +46 -0
- package/src/commands/launch.ts +36 -14
- package/src/commands/lock/rebuild.ts +241 -0
- package/src/commands/lock/show.ts +115 -0
- package/src/commands/namespace/list.ts +117 -0
- package/src/commands/namespace/show.ts +110 -0
- package/src/commands/prune.ts +3 -11
- package/src/commands/recipe/list.ts +95 -0
- package/src/commands/recipe/show.ts +301 -0
- package/src/commands/repo/add.ts +145 -0
- package/src/commands/repo/gc.ts +172 -0
- package/src/commands/repo/init.ts +136 -0
- package/src/commands/repo/link.ts +500 -0
- package/src/commands/repo/list.ts +179 -0
- package/src/commands/repo/release.ts +619 -0
- package/src/commands/repo/remove.ts +193 -0
- package/src/commands/repo/search.ts +189 -0
- package/src/commands/repo/submit.ts +133 -0
- package/src/commands/repo/unlink.ts +147 -0
- package/src/commands/subscription/add.ts +285 -0
- package/src/commands/subscription/list.ts +129 -0
- package/src/commands/subscription/remove.ts +181 -0
- package/src/commands/vars/ask.ts +374 -0
- package/src/commands/vars/index.ts +79 -0
- package/src/commands/vars/list.ts +67 -0
- package/src/commands/vars/show.ts +77 -0
- package/src/config-command.ts +30 -0
- package/src/lib/build-service.ts +206 -54
- package/src/lib/config-discovery.ts +220 -27
- package/src/lib/config-inspect.ts +145 -0
- package/src/lib/config-kernel.mjs +377 -0
- package/src/lib/config-schema.ts +361 -0
- package/src/lib/env-file.ts +328 -0
- package/src/lib/env-local.ts +18 -1
- package/src/lib/errors.ts +32 -0
- package/src/lib/include-resolver.ts +108 -15
- package/src/lib/interactive.ts +165 -0
- package/src/lib/markdown-compiler.ts +118 -37
- package/src/lib/package-info.ts +25 -0
- package/src/lib/pid-service.ts +32 -21
- package/src/lib/refs/find.ts +589 -0
- package/src/lib/refs/index.ts +12 -0
- package/src/lib/refs/pick.ts +147 -0
- package/src/lib/refs/scopes.ts +61 -0
- package/src/lib/repos/catalog-display.ts +116 -0
- package/src/lib/repos/catalog-inputs.ts +160 -0
- package/src/lib/repos/catalog.ts +722 -0
- package/src/lib/repos/core-recipe.ts +105 -0
- package/src/lib/repos/defaults.ts +175 -0
- package/src/lib/repos/formats/common.ts +389 -0
- package/src/lib/repos/formats/index-file.ts +215 -0
- package/src/lib/repos/formats/links-map.ts +96 -0
- package/src/lib/repos/formats/lockfile.ts +167 -0
- package/src/lib/repos/formats/patterns.ts +57 -0
- package/src/lib/repos/formats/recipe-manifest.ts +395 -0
- package/src/lib/repos/formats/repo-manifest.ts +88 -0
- package/src/lib/repos/formats/store-entry.ts +84 -0
- package/src/lib/repos/freshness.ts +208 -0
- package/src/lib/repos/git-clone.ts +312 -0
- package/src/lib/repos/identity.ts +89 -0
- package/src/lib/repos/index.ts +58 -0
- package/src/lib/repos/links.ts +353 -0
- package/src/lib/repos/load-manifest.ts +236 -0
- package/src/lib/repos/lock-service.ts +453 -0
- package/src/lib/repos/locked-namespace-resolver.ts +90 -0
- package/src/lib/repos/locked-recipes.ts +254 -0
- package/src/lib/repos/managed-layer.ts +422 -0
- package/src/lib/repos/namespace-resolver.ts +370 -0
- package/src/lib/repos/providers/base.ts +206 -0
- package/src/lib/repos/providers/git.ts +233 -0
- package/src/lib/repos/providers/github.ts +294 -0
- package/src/lib/repos/providers/gitlab.ts +263 -0
- package/src/lib/repos/providers/http.ts +102 -0
- package/src/lib/repos/providers/index-cache.ts +382 -0
- package/src/lib/repos/providers/index.ts +106 -0
- package/src/lib/repos/providers/local.ts +391 -0
- package/src/lib/repos/providers/provider.ts +401 -0
- package/src/lib/repos/recipe-config-layers.ts +287 -0
- package/src/lib/repos/recipe-targets.ts +223 -0
- package/src/lib/repos/ref-search.ts +46 -0
- package/src/lib/repos/ref.ts +513 -0
- package/src/lib/repos/reference-report.ts +122 -0
- package/src/lib/repos/release/bump.ts +161 -0
- package/src/lib/repos/release/git-state.ts +305 -0
- package/src/lib/repos/release/index-builder.ts +635 -0
- package/src/lib/repos/release/index.ts +16 -0
- package/src/lib/repos/release/plan.ts +512 -0
- package/src/lib/repos/release/submit-service.ts +496 -0
- package/src/lib/repos/release/tags.ts +243 -0
- package/src/lib/repos/release/validate.ts +463 -0
- package/src/lib/repos/resolver.ts +789 -0
- package/src/lib/repos/scaffold/index.ts +238 -0
- package/src/lib/repos/scaffold/templates.ts +413 -0
- package/src/lib/repos/seed.ts +414 -0
- package/src/lib/repos/store/contract.ts +64 -0
- package/src/lib/repos/store/hash.ts +114 -0
- package/src/lib/repos/store/recipe-store.ts +599 -0
- package/src/lib/repos/store/settings.ts +58 -0
- package/src/lib/repos/subscription-service.ts +2678 -0
- package/src/lib/repos/trust.ts +447 -0
- package/src/lib/settings.ts +546 -189
- package/src/lib/sous-home.ts +104 -0
- package/src/lib/state.ts +52 -20
- package/src/lib/vars/ask.ts +1152 -0
- package/src/lib/vars/definition-source.ts +252 -0
- package/src/lib/vars/display.ts +233 -0
- package/src/lib/vars/index.ts +18 -0
- package/src/lib/vars/ladder.ts +282 -0
- package/src/lib/vars/mappings.ts +265 -0
- package/src/lib/vars/names.ts +94 -0
- package/src/lib/vars/preanswers.ts +395 -0
- package/src/lib/vars/question-plan.ts +218 -0
- package/src/lib/vars/report.ts +228 -0
- package/src/lib/vars/safe-regex.ts +235 -0
- package/src/lib/vars/validate.ts +312 -0
- package/src/lib/watch-loop.ts +148 -0
- package/src/templating/init-liquid-engine.ts +58 -16
- package/src/utils/choice-prompt.ts +143 -0
- package/src/utils/command-errors.ts +186 -0
- package/src/utils/command-help.ts +45 -0
- package/src/utils/confirm-prompt.ts +110 -0
- package/src/utils/flags.ts +153 -0
- package/src/utils/formatting.ts +540 -55
- package/src/utils/prompts.ts +35 -1
- package/src/utils/sous-directory.ts +245 -0
- package/src/utils/table.ts +603 -0
- package/src/utils/value-prompt.ts +119 -0
- package/bin/xcv +0 -5
- package/shared-prompts/_partials/resume-task.md +0 -51
- package/shared-prompts/_partials/sub-agent-delegation.md +0 -32
- package/shared-prompts/_partials/update-task-file.md +0 -52
- package/shared-prompts/memories/automated-browser-tasks/INDEX.tpl.md +0 -52
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/SKILL.tpl.md +0 -102
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/examples/auth-failure-handling.mjs +0 -81
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/examples/chained-workflow.mjs +0 -126
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/examples/simple-fetch.mjs +0 -92
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/references/architecture.md +0 -61
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/references/auth-and-sessions.md +0 -65
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/references/ctx-api.md +0 -96
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/references/installation.md +0 -104
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/references/script-conventions.md +0 -243
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/chrome-state.mjs +0 -148
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/debug.mjs +0 -383
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/debug.spec.mjs +0 -267
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/eslint.config.mjs +0 -56
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/harness.mjs +0 -169
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/keyring.mjs +0 -59
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/logger.mjs +0 -25
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/params.mjs +0 -140
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/run.mjs +0 -140
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/settings.tpl.mjs +0 -1
- package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/utils.mjs +0 -185
- package/shared-prompts/skills/automated-browser-tasks/create-automated-browser-task/SKILL.tpl.md +0 -52
- package/shared-prompts/skills/automated-browser-tasks/running-automated-browser-tasks/SKILL.tpl.md +0 -59
- package/shared-prompts/skills/automated-browser-tasks/update-automated-browser-task/SKILL.tpl.md +0 -47
- package/shared-prompts/skills/control-flow/approve/SKILL.tpl.md +0 -26
- package/shared-prompts/skills/control-flow/opine/SKILL.tpl.md +0 -58
- package/shared-prompts/skills/control-flow/repeat/SKILL.tpl.md +0 -27
- package/shared-prompts/skills/control-flow/research/SKILL.tpl.md +0 -34
- package/shared-prompts/skills/sous-skills/about-sous/SKILL.tpl.md +0 -51
- package/shared-prompts/skills/task-files/about-task-files/SKILL.tpl.md +0 -122
- package/shared-prompts/skills/task-files/continue-task-in-new-branch/SKILL.tpl.md +0 -80
- package/shared-prompts/skills/task-files/go/SKILL.tpl.md +0 -14
- package/shared-prompts/skills/task-files/resume-task/SKILL.tpl.md +0 -13
- package/shared-prompts/skills/task-files/start-task/SKILL.tpl.md +0 -93
- package/shared-prompts/skills/task-files/update/SKILL.tpl.md +0 -14
- package/shared-prompts/skills/task-files/update-task-file/SKILL.tpl.md +0 -13
- /package/{shared-prompts/skills/sous-skills → recipes/core/sous-skills/skills}/about-agent-skills/references/substitutions.md +0 -0
- /package/{shared-prompts/skills/sous-skills → recipes/core/sous-skills/skills}/about-liquid-templates/references/liquid-filters.md +0 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# Repositories
|
|
2
|
+
|
|
3
|
+
A **repository** publishes shared agent configuration that any project can subscribe to. It is
|
|
4
|
+
an ordinary git repository holding a few manifest files and some markdown, and sous reads it
|
|
5
|
+
the way a package manager reads a registry: an index says what exists, a project says what it
|
|
6
|
+
wants, and a lockfile records exactly what it got.
|
|
7
|
+
|
|
8
|
+
This page explains the model and the guarantees. The task-oriented guides are
|
|
9
|
+
[Consuming recipes](repositories-consuming.md) and
|
|
10
|
+
[Authoring a repository](repositories-authoring.md), and every file schema lives in
|
|
11
|
+
[Repository file formats](repositories-file-formats.md).
|
|
12
|
+
|
|
13
|
+
## Repositories, namespaces, recipes
|
|
14
|
+
|
|
15
|
+
Three nouns carry the whole system.
|
|
16
|
+
|
|
17
|
+
- A **repository** is the unit of trust and the unit of distribution. You add one to a project,
|
|
18
|
+
which is also how you trust it, and everything else flows from that.
|
|
19
|
+
- A **namespace** groups related recipes inside a repository. It is a plain name, it is not
|
|
20
|
+
versioned, and a project can subscribe to a whole namespace at once.
|
|
21
|
+
- A **recipe** is the unit you subscribe to and the unit that carries a version. It may hold
|
|
22
|
+
skills, memories, prompts, config layers, variable definitions, or any mixture of them.
|
|
23
|
+
Subscribing to a recipe gets everything in it.
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
repository github.com/sous-io/sous-recipes
|
|
27
|
+
namespace workflow
|
|
28
|
+
recipe task-files 1.2.0
|
|
29
|
+
recipe github-projects 1.0.0
|
|
30
|
+
namespace communication
|
|
31
|
+
recipe control-flow 1.0.0
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
A recipe is named by a **ref**: `workflow` for a whole namespace, `workflow/task-files` for one
|
|
35
|
+
recipe, `workflow/task-files@^1.2.0` to constrain the version, and
|
|
36
|
+
`sous-recipes:workflow/task-files` when two added repositories publish the same ref and sous
|
|
37
|
+
needs to be told which one you meant. Refs resolve across the cached indexes of every repository
|
|
38
|
+
the project has added; a genuine conflict is an error asking for the qualified form, never a
|
|
39
|
+
silent first match. The full grammar is in
|
|
40
|
+
[Refs: how anything is named](repositories-file-formats.md#refs-how-anything-is-named).
|
|
41
|
+
|
|
42
|
+
A ref of one word is a guess at a name, and sous works out what it meant: it looks for a
|
|
43
|
+
namespace with that name first, and for a recipe with that name second, across every repository
|
|
44
|
+
the project trusts. One match is used and reported by its full ref; several are a question. See
|
|
45
|
+
[Subscribe to a recipe](repositories-consuming.md#subscribe-to-a-recipe).
|
|
46
|
+
|
|
47
|
+
## Trust
|
|
48
|
+
|
|
49
|
+
Adding a repository **is** trusting it. There is no separate trust command, no trusted-but-not-
|
|
50
|
+
added state, and no way to look inside a repository before deciding: until a repository is added,
|
|
51
|
+
sous downloads nothing from it, not even its index. That is deliberate. A trust decision made
|
|
52
|
+
by browsing content sous fetched from an untrusted source is not really a trust decision; the
|
|
53
|
+
decision rests on the URL and on who publishes it, and both of those are things you inspect
|
|
54
|
+
outside sous. Trusting a repository trusts every namespace and every recipe in it, including
|
|
55
|
+
recipes published later. Trusting alone executes nothing, but subscribing to something inside a
|
|
56
|
+
trusted repository can and probably will run scripts on your machine, so the trust question is
|
|
57
|
+
the last gate before that happens. Sous cannot tell you whether a repository deserves trust,
|
|
58
|
+
and it says so rather than implying otherwise.
|
|
59
|
+
|
|
60
|
+
`sous repo add` asks that question inline, with that wording. Resolution can also turn up a
|
|
61
|
+
repository a recipe depends on that your project has not added; those are asked about in one
|
|
62
|
+
consolidated question per round, each shown with its URL and the recipe that requires it. Any
|
|
63
|
+
refusal aborts the whole install, because sous installs a dependency closure whole or not at all.
|
|
64
|
+
|
|
65
|
+
```term
|
|
66
|
+
$ sous repo add https://github.com/sous-io/sous-recipes
|
|
67
|
+
// sous prints the repository, its location and what trusting it means
|
|
68
|
+
Do you trust this repository? (y/N)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Where there is no terminal to ask on, such as continuous integration, the run fails and names
|
|
72
|
+
both the repositories and the exact command that grants the trust. `--trust` acknowledges
|
|
73
|
+
without being asked, and is the flag a script uses; it is one spelling of the shared
|
|
74
|
+
confirmation flag, alongside `-y`, `--yes`, `-f` and `--force`:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
sous repo add https://github.com/sous-io/sous-recipes --trust
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Trust is project-level and lives in your project's config, so a colleague who clones the project
|
|
81
|
+
inherits it along with everything else. Trust plus the lockfile is the supply-chain defense:
|
|
82
|
+
nothing new enters a project except through an explicit, visible change to files under version
|
|
83
|
+
control.
|
|
84
|
+
|
|
85
|
+
!> Trust semantics do not soften for a repository that is already on your disk. A local path
|
|
86
|
+
added through the `local` provider goes through the same ceremony, because its recipes still run
|
|
87
|
+
on this machine.
|
|
88
|
+
|
|
89
|
+
## The official repository, and `core`
|
|
90
|
+
|
|
91
|
+
Sous publishes one official repository, [`sous-io/sous-recipes`](https://github.com/sous-io/sous-recipes).
|
|
92
|
+
Its namespaces are drawn from the canonical [skill categories](skill-categories.md), plus one
|
|
93
|
+
extra namespace called `core`.
|
|
94
|
+
|
|
95
|
+
`core` is the exception to everything else on this page. It holds the skills that teach an agent
|
|
96
|
+
what sous is, why generated files must not be edited by hand, and where the source of a managed
|
|
97
|
+
file lives; without them an agent will cheerfully edit a compiled `CLAUDE.md` and wonder why the
|
|
98
|
+
change keeps disappearing. So `core` is auto-subscribed in every project, at the version that
|
|
99
|
+
matches the sous CLI you are running, and its source ships inside the sous package itself and
|
|
100
|
+
seeds the machine-wide store on first run. A fresh install therefore works with no network at
|
|
101
|
+
all, and the release pipeline pushes the same content to the official repository under the same
|
|
102
|
+
version number, so the built-in copy and the published copy are the same bytes.
|
|
103
|
+
|
|
104
|
+
Both wirings are ordinary config entries, and both can be switched off:
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
subscriptions:
|
|
108
|
+
core:
|
|
109
|
+
enabled: false
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Everything else in the official repository is opt-in, one `sous subscription add` at a time, and
|
|
113
|
+
`sous subscription remove core` records that opt-out for you.
|
|
114
|
+
|
|
115
|
+
?> Namespace subscriptions are a first-class feature and are worth reaching for on other
|
|
116
|
+
repositories, especially a team repository whose namespace is genuinely one coherent set. In the
|
|
117
|
+
official repository they are not what you want: any arrangement of its content yields either
|
|
118
|
+
one-recipe namespaces or a namespace of unrelated recipes, so subscribe to official recipes one
|
|
119
|
+
at a time. `core` is the deliberate exception.
|
|
120
|
+
|
|
121
|
+
## `depends` versus `subscribes`
|
|
122
|
+
|
|
123
|
+
A recipe manifest can declare two different relationships to other recipes, and the difference
|
|
124
|
+
is exactly one thing: whose files end up in your project.
|
|
125
|
+
|
|
126
|
+
| Relationship | Fetched and pinned | Trust-gated | Addressable from the declaring recipe | Files enter your project |
|
|
127
|
+
|--------------|--------------------|-------------|---------------------------------------|--------------------------|
|
|
128
|
+
| `depends` | yes | yes | yes | no |
|
|
129
|
+
| `subscribes` | yes | yes | yes | yes |
|
|
130
|
+
|
|
131
|
+
`depends` is a build dependency: shared partials, shared variable definitions, anything a recipe
|
|
132
|
+
reads while rendering its own files. `subscribes` is a co-subscription: subscribing to the recipe
|
|
133
|
+
subscribes your project to the listed targets with full semantics, so their questions run and
|
|
134
|
+
their files land in your output. A curated bundle is simply a recipe made mostly of `subscribes`
|
|
135
|
+
entries; there is no special bundle type.
|
|
136
|
+
|
|
137
|
+
Both name their targets by LOCATION. A recipe in the same repository is a bare ref
|
|
138
|
+
(`workflow/sat`); a recipe in another repository is a locator URL whose scheme is the provider
|
|
139
|
+
(`github://sous-io/sous-recipes/workflow/sat@^1.1`), whose last two path segments are always the
|
|
140
|
+
namespace and the recipe. A project's own short name for a repository never appears in a
|
|
141
|
+
published manifest, because it is a label that project chose. The full grammar is in
|
|
142
|
+
[Repository file formats](repositories-file-formats.md#dependencies-named-by-location).
|
|
143
|
+
|
|
144
|
+
A release records what each version was published against, so installing a version installs the
|
|
145
|
+
versions it was released with rather than whatever its ranges reach today.
|
|
146
|
+
|
|
147
|
+
Both are declarative, and that is load-bearing rather than stylistic. Because the entire
|
|
148
|
+
dependency closure is readable from manifests alone, sous can show you every repository an
|
|
149
|
+
install would reach before it fetches any of them. Configuration that could subscribe by running
|
|
150
|
+
code would break that, which is why manifests are YAML or JSON and never JavaScript.
|
|
151
|
+
|
|
152
|
+
Removal is refcounted. Unsubscribing removes what that subscription alone brought in and leaves
|
|
153
|
+
anything another subscription or another recipe still holds, and says which of those holders
|
|
154
|
+
kept it.
|
|
155
|
+
|
|
156
|
+
## The lockfile
|
|
157
|
+
|
|
158
|
+
`.sous/sous.lock.json` records the exact version and content hash of everything the project uses,
|
|
159
|
+
along with who holds each entry. It is committed. A fresh clone with no store on the machine
|
|
160
|
+
rebuilds precisely what the lockfile describes, fetching those versions and no others, and asking
|
|
161
|
+
nothing:
|
|
162
|
+
|
|
163
|
+
```term
|
|
164
|
+
$ git clone git@github.com:my-team/my-project.git
|
|
165
|
+
>> 100%
|
|
166
|
+
$ sous build
|
|
167
|
+
Restoring recipes
|
|
168
|
+
This project's lockfile pins recipes that are not in the store on this machine,
|
|
169
|
+
so they are being fetched at exactly the versions it records.
|
|
170
|
+
restored: workflow/task-files
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Restore decides nothing. It never resolves a range, never picks a newer version, and never
|
|
174
|
+
prompts. Anything that would change what is installed changes the lockfile first, as a diff you
|
|
175
|
+
can read in review.
|
|
176
|
+
|
|
177
|
+
## Providers
|
|
178
|
+
|
|
179
|
+
A provider is everything sous knows about one kind of repository host, and it is the only place
|
|
180
|
+
a host-specific fact is allowed to live. Sous ships three: `github`, `gitlab` and `local`.
|
|
181
|
+
|
|
182
|
+
A provider has two sides:
|
|
183
|
+
|
|
184
|
+
- **The read side**, which every provider answers: recognize a repository URL, take it apart into
|
|
185
|
+
host, owner and name, hand back the repository's `sous.index.json`, and fetch one recipe's
|
|
186
|
+
subtree at one tag. Nothing here clones a whole repository.
|
|
187
|
+
- **The write side**, which only a provider that can propose a change answers: report whether its
|
|
188
|
+
command line tool is installed and signed in, say whether you can push to the repository
|
|
189
|
+
itself, fork it onto your account, and open the proposal. Each call answers with plain data, so
|
|
190
|
+
the command driving it never learns what tool ran.
|
|
191
|
+
|
|
192
|
+
Each provider declares the features it really has, `fetch` and `submit`, and sous consults that
|
|
193
|
+
list rather than a provider's name. `local` declares `fetch` only: a repository on your own disk
|
|
194
|
+
is edited directly, so asking sous to propose a change to it is refused with a message naming the
|
|
195
|
+
provider and the feature. A provider that supports a feature only partly says so plainly rather
|
|
196
|
+
than guessing; GitLab, for instance, reports that it cannot tell whether you may push instead of
|
|
197
|
+
sending you down a fork path it cannot finish.
|
|
198
|
+
|
|
199
|
+
?> Adding a provider is one file. A class extending `ProviderBase` inherits the subprocess, token
|
|
200
|
+
and refusal plumbing, implements the read path, declares its features, and overrides the write
|
|
201
|
+
calls it supports; adding it to the built-in list is the only other change. The interface is
|
|
202
|
+
internal for now, not a published plugin API.
|
|
203
|
+
|
|
204
|
+
## Where everything lives
|
|
205
|
+
|
|
206
|
+
| Location | Holds | Committed |
|
|
207
|
+
|----------|-------|-----------|
|
|
208
|
+
| `.sous/sous.lock.json` | the exact versions and hashes in use | yes |
|
|
209
|
+
| `.sous/conf.d/500-repos.jsonc` | the repositories the project trusts | yes |
|
|
210
|
+
| `.sous/conf.d/510-subscriptions.jsonc` | what the project subscribes to | yes |
|
|
211
|
+
| `.sous/conf.d/520-var-mappings.jsonc` | environment variable mapping records | yes |
|
|
212
|
+
| `.sous/sous.links.json` | this project's linked working copies | no |
|
|
213
|
+
| `.sous/repos/` | working copies cloned by `sous repo link` | no |
|
|
214
|
+
| `~/.sous/cache/` | the machine-wide recipe store | not in a project at all |
|
|
215
|
+
| `~/.sous/repos/` | working copies linked with `--global` | not in a project at all |
|
|
216
|
+
| `~/.sous/sous.links.json` | the machine-wide links map | not in a project at all |
|
|
217
|
+
|
|
218
|
+
The user-level directory is `~/.sous`, and `SOUS_HOME` moves it. Unlike `SOUS_CONFIG` and
|
|
219
|
+
`SOUS_DIR`, `SOUS_HOME` does not decide which project is active, so it may be set in
|
|
220
|
+
`.sous/.env.local` or `.sous/.env` as well as in the shell.
|
|
221
|
+
|
|
222
|
+
The three files in the `500` to `599` band are written by sous, and the band exists precisely so
|
|
223
|
+
that machine-written layers never collide with the config you wrote. Sous edits them by key, so
|
|
224
|
+
your comments, your key order and your formatting survive a write, and you may edit them
|
|
225
|
+
yourself. Sous never edits your primary config. You may
|
|
226
|
+
hand-write `repos:`, `subscriptions:` and `varMappings:` there yourself, and by the time anything
|
|
227
|
+
reads them the two are one merged map. See
|
|
228
|
+
[Managed config layers](repositories-file-formats.md#managed-config-layers).
|
|
229
|
+
|
|
230
|
+
Every directory sous creates for its own bookkeeping explains itself. The first time sous
|
|
231
|
+
creates one (`.sous/conf.d/`, `.sous/repos/`, `~/.sous` and everything under it), it writes a
|
|
232
|
+
short `README.md` there saying what the directory is, who writes to it, whether you may edit or
|
|
233
|
+
delete what is inside, and whether it is committed, plus an `AGENTS.md` and a `CLAUDE.md` holding
|
|
234
|
+
one line each pointing at that README. None of the three is ever overwritten, so anything you
|
|
235
|
+
write in them stays. Directories that hold rendered output are deliberately left alone: what
|
|
236
|
+
lands there is yours.
|
|
237
|
+
|
|
238
|
+
The store is disposable by design. Every entry in it is re-fetchable from the pins in some
|
|
239
|
+
project's lockfile, so deleting `~/.sous/cache` costs a download and nothing else. `sous repo gc`
|
|
240
|
+
collects it back to a size cap, least recently used first, and never evicts an entry this
|
|
241
|
+
project's lockfile still pins.
|
|
242
|
+
|
|
243
|
+
## Including recipe files in your own templates
|
|
244
|
+
|
|
245
|
+
A recipe's files are addressable from a template through the reserved `~` include sigil:
|
|
246
|
+
|
|
247
|
+
```markdown
|
|
248
|
+
@~workflow/task-files/_partials/shared.md
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
The `~` is required. A bare `@path` in an include is always a relative path or a declared alias,
|
|
252
|
+
with no namespace fallback, so an include line can never quietly stop meaning a file on disk and
|
|
253
|
+
start meaning a recipe. Inside a recipe's own files, `~<namespace>` resolves against that
|
|
254
|
+
recipe's declared dependencies at their pinned versions; in your project's templates it resolves
|
|
255
|
+
against your project's subscriptions.
|
|
256
|
+
|
|
257
|
+
A `~namespace` reference addresses a recipe's own files and nothing else, so the path after the
|
|
258
|
+
recipe name may not contain `.` or `..` segments and may not be absolute. One that tries to leave
|
|
259
|
+
the recipe directory is refused with an error saying so, exactly as every other path sous reads
|
|
260
|
+
refuses `..`.
|
|
261
|
+
|
|
262
|
+
## Freshness, always-pull, and links
|
|
263
|
+
|
|
264
|
+
By default a build uses what the lockfile pins and does not talk to the network. Two things
|
|
265
|
+
change that.
|
|
266
|
+
|
|
267
|
+
**Always-pull** installs a newer in-range version whenever one exists, rather than holding the
|
|
268
|
+
locked one. It is set per repository or per subscription, or asked for once with
|
|
269
|
+
`sous subscription add --always-pull`. It never widens the range a subscription or a dependency
|
|
270
|
+
declared; it re-resolves within it. The lockfile is still regenerated every time, so it always
|
|
271
|
+
records what the last build actually used, and a project using always-pull simply accepts
|
|
272
|
+
routine lockfile diffs as the record of what changed.
|
|
273
|
+
|
|
274
|
+
**The freshness window** decides how often sous bothers to look upstream at all: five minutes by
|
|
275
|
+
default, configurable as `store.freshnessSeconds`, with `store.watchPollSeconds` doing the same
|
|
276
|
+
job for watch mode. A check that fails never breaks a build. The last good index stands, the
|
|
277
|
+
build says what happened, and it carries on.
|
|
278
|
+
|
|
279
|
+
A **linked** repository sits outside all of this. `sous repo link` points one repository's
|
|
280
|
+
resolution at a working copy on your machine, which is how a maintainer edits recipes; edits
|
|
281
|
+
happen in a checkout, never in the store. A link bypasses versions, the lockfile and freshness
|
|
282
|
+
checks, and those bypasses belong to one person's machine rather than to the team, so every
|
|
283
|
+
build announces a linked repository loudly:
|
|
284
|
+
|
|
285
|
+
```text
|
|
286
|
+
One repository is LINKED to a working copy on this machine.
|
|
287
|
+
Their recipes are read from those checkouts, so versions, the lockfile and
|
|
288
|
+
freshness checks do not apply to them.
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Where to go next
|
|
292
|
+
|
|
293
|
+
- [Consuming recipes](repositories-consuming.md): adding, subscribing, building, and what lands
|
|
294
|
+
where
|
|
295
|
+
- [Authoring a repository](repositories-authoring.md): `sous repo init`, writing recipes,
|
|
296
|
+
releasing, and contributing
|
|
297
|
+
- [Recipe variables](repositories-variables.md): the resolution ladder, answers, and the
|
|
298
|
+
`sous vars` commands
|
|
299
|
+
- [Repository file formats](repositories-file-formats.md): every manifest, index and lockfile
|
|
300
|
+
schema
|
|
301
|
+
- [Skill categories](skill-categories.md): the canonical category list the official repository
|
|
302
|
+
uses as namespaces
|
|
303
|
+
- [Command reference](commands.md): every command and flag
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Skill Categories
|
|
2
|
+
|
|
3
|
+
Sous keeps one canonical list of skill categories. It is a small, closed vocabulary: it exists so
|
|
4
|
+
that a skill has an obvious home, so that two people filing similar skills reach for the same
|
|
5
|
+
word, and so that a reader scanning a repository can tell what is in it without opening
|
|
6
|
+
anything.
|
|
7
|
+
|
|
8
|
+
| Category | What belongs in it |
|
|
9
|
+
|----------|--------------------|
|
|
10
|
+
| `reasoning` | How an agent thinks through a problem: decomposition, self-checking, weighing evidence, knowing when it is stuck |
|
|
11
|
+
| `planning` | Turning an intent into an ordered plan, and keeping that plan current as the work moves |
|
|
12
|
+
| `architecture` | Designing systems and deciding structure: boundaries, dependencies, trade-offs, and how a decision gets recorded |
|
|
13
|
+
| `coding` | Writing and changing code: idioms, refactoring, language and framework practice |
|
|
14
|
+
| `data-manipulation` | Reading, transforming, querying and reshaping data, in files, databases or streams |
|
|
15
|
+
| `research` | Finding things out: searching a codebase, reading documentation, gathering evidence before acting |
|
|
16
|
+
| `tool-usage` | Driving a specific tool well: a CLI, a browser, an API, a service that has its own rules |
|
|
17
|
+
| `workflow` | The shape of the work itself: tickets, branches, task files, reviews, handoffs between sessions |
|
|
18
|
+
| `quality` | Confidence in what was built: tests, linting, review practice, and the standards being upheld |
|
|
19
|
+
| `communication` | How an agent talks: writing standards, interaction patterns, asking, reporting, disagreeing usefully |
|
|
20
|
+
| `operations` | Running things: builds, releases, deployment, environments, monitoring, recovery |
|
|
21
|
+
| `security` | Protecting the system and the people using it: secrets, permissions, supply chain, threat awareness |
|
|
22
|
+
|
|
23
|
+
## Adding a category is a decision
|
|
24
|
+
|
|
25
|
+
The list above is the whole list. It is deliberately comprehensive rather than deliberately
|
|
26
|
+
small, so that in practice a new skill fits an existing category, and the answer to "which one?"
|
|
27
|
+
is a judgment call about the skill rather than an invitation to invent a thirteenth word.
|
|
28
|
+
|
|
29
|
+
Adding a category is a considered change to a shared vocabulary, never an ad hoc choice made
|
|
30
|
+
while filing one skill. A category that gets added because one skill did not obviously fit tends
|
|
31
|
+
to attract nothing else, and the list stops being useful the moment it stops being small. If a
|
|
32
|
+
skill genuinely resists every category above, that is worth discussing as a gap in the
|
|
33
|
+
vocabulary, on its own, before anything is filed.
|
|
34
|
+
|
|
35
|
+
## Categories as namespaces
|
|
36
|
+
|
|
37
|
+
The official repository, [`sous-io/sous-recipes`](https://github.com/sous-io/sous-recipes), uses
|
|
38
|
+
this list directly: a namespace in that repository is a category from the table above, plus one
|
|
39
|
+
extra namespace, `core`, which holds the recipes that teach an agent about sous itself. `core` is
|
|
40
|
+
not a skill category. It is a distribution concern, and it exists because those recipes are
|
|
41
|
+
auto-subscribed in every project rather than chosen from a catalog.
|
|
42
|
+
|
|
43
|
+
Your own repository is under no obligation to use these names. Namespaces are just names, and a
|
|
44
|
+
team repository whose namespaces are its own product areas is a perfectly good repository. The
|
|
45
|
+
list is worth borrowing when what you publish is general-purpose skills that other people will
|
|
46
|
+
browse, because a shared vocabulary is what makes browsing work.
|
|
47
|
+
|
|
48
|
+
?> A namespace subscription gets every recipe in the namespace, including recipes published
|
|
49
|
+
later, which is exactly what you want from a coherent category and exactly what you do not want
|
|
50
|
+
from a grab bag. That is the practical reason to keep a namespace meaning one thing. See
|
|
51
|
+
[Consuming recipes](repositories-consuming.md).
|
|
52
|
+
|
|
53
|
+
## Where to go next
|
|
54
|
+
|
|
55
|
+
- [Repositories](repositories.md): the model, and how namespaces fit into it
|
|
56
|
+
- [Authoring a repository](repositories-authoring.md): declaring namespaces and filing recipes
|
|
57
|
+
under them
|
|
58
|
+
- [Design principles](design-principles.md): the constraints these choices answer to
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sous-io/sous",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Compiles AI coding agent configuration (CLAUDE.md, skills, memories) from LiquidJS templates",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -27,52 +27,116 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"bin": {
|
|
30
|
-
"
|
|
30
|
+
"sous": "./bin/run.js"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
|
-
"bin",
|
|
33
|
+
"bin/run.js",
|
|
34
34
|
"src",
|
|
35
35
|
"!src/**/*.spec.ts",
|
|
36
36
|
"!src/test",
|
|
37
|
-
"
|
|
37
|
+
"recipes",
|
|
38
|
+
"docs/markdown/*.md",
|
|
39
|
+
"sous.config.schema.json"
|
|
38
40
|
],
|
|
39
41
|
"scripts": {
|
|
40
42
|
"build": "tsc",
|
|
41
|
-
"sous:build": "./bin/
|
|
42
|
-
"claude": "./bin/
|
|
43
|
+
"sous:build": "./bin/sous build --rebuild",
|
|
44
|
+
"claude": "./bin/sous launch claude",
|
|
43
45
|
"clean": "rm -rf dist",
|
|
46
|
+
"schema:build": "tsx scripts/build-schema.mts",
|
|
47
|
+
"version:sync": "tsx scripts/sync-core-version.mts",
|
|
44
48
|
"test": "vitest run",
|
|
45
49
|
"test:watch": "vitest",
|
|
46
50
|
"test:coverage": "vitest run --coverage",
|
|
47
51
|
"test:e2e": "vitest run --config vitest.e2e.config.ts"
|
|
48
52
|
},
|
|
49
53
|
"dependencies": {
|
|
54
|
+
"@inquirer/core": "^11.1.7",
|
|
50
55
|
"@inquirer/prompts": "^8.3.2",
|
|
51
56
|
"@oclif/color": "^1.0.13",
|
|
52
57
|
"@oclif/core": "^4",
|
|
53
58
|
"chokidar": "^5.0.0",
|
|
54
59
|
"glob": "^13.0.6",
|
|
60
|
+
"jsonc-parser": "^3.3.1",
|
|
55
61
|
"liquidjs": "^10.25.0",
|
|
56
62
|
"minimatch": "^10.2.4",
|
|
63
|
+
"semver": "^7.8.5",
|
|
57
64
|
"tiktoken": "^1.0.22",
|
|
58
|
-
"tsx": "^4"
|
|
65
|
+
"tsx": "^4",
|
|
66
|
+
"yaml": "^2.9.0",
|
|
67
|
+
"zod": "^4.4.3"
|
|
59
68
|
},
|
|
60
69
|
"devDependencies": {
|
|
61
70
|
"@types/glob": "^8.1.0",
|
|
62
71
|
"@types/node": "^22",
|
|
72
|
+
"@types/semver": "^7.8.0",
|
|
63
73
|
"@vitest/coverage-v8": "^4.1.0",
|
|
64
74
|
"memfs": "^4.56.11",
|
|
65
75
|
"typescript": "^5",
|
|
66
76
|
"vitest": "^4.1.0"
|
|
67
77
|
},
|
|
68
78
|
"oclif": {
|
|
69
|
-
"bin": "
|
|
70
|
-
"dirname": "
|
|
79
|
+
"bin": "sous",
|
|
80
|
+
"dirname": "sous",
|
|
71
81
|
"flexibleTaxonomy": true,
|
|
72
82
|
"topicSeparator": " ",
|
|
83
|
+
"additionalHelpFlags": [
|
|
84
|
+
"-h"
|
|
85
|
+
],
|
|
73
86
|
"commands": {
|
|
74
87
|
"strategy": "pattern",
|
|
75
88
|
"target": "./src/commands"
|
|
89
|
+
},
|
|
90
|
+
"topics": {
|
|
91
|
+
"config": {
|
|
92
|
+
"description": "Inspect the merged configuration"
|
|
93
|
+
},
|
|
94
|
+
"configs": {
|
|
95
|
+
"description": "Inspect the merged configuration",
|
|
96
|
+
"hidden": true
|
|
97
|
+
},
|
|
98
|
+
"repo": {
|
|
99
|
+
"description": "Manage the recipe repositories this project trusts"
|
|
100
|
+
},
|
|
101
|
+
"repos": {
|
|
102
|
+
"description": "Manage the recipe repositories this project trusts",
|
|
103
|
+
"hidden": true
|
|
104
|
+
},
|
|
105
|
+
"lock": {
|
|
106
|
+
"description": "Inspect and repair this project's lockfile"
|
|
107
|
+
},
|
|
108
|
+
"locks": {
|
|
109
|
+
"description": "Inspect and repair this project's lockfile",
|
|
110
|
+
"hidden": true
|
|
111
|
+
},
|
|
112
|
+
"namespace": {
|
|
113
|
+
"description": "Browse the namespaces the trusted repositories publish"
|
|
114
|
+
},
|
|
115
|
+
"namespaces": {
|
|
116
|
+
"description": "Browse the namespaces the trusted repositories publish",
|
|
117
|
+
"hidden": true
|
|
118
|
+
},
|
|
119
|
+
"recipe": {
|
|
120
|
+
"description": "Browse the recipes the trusted repositories publish"
|
|
121
|
+
},
|
|
122
|
+
"recipes": {
|
|
123
|
+
"description": "Browse the recipes the trusted repositories publish",
|
|
124
|
+
"hidden": true
|
|
125
|
+
},
|
|
126
|
+
"subscription": {
|
|
127
|
+
"description": "Manage which recipes this project subscribes to"
|
|
128
|
+
},
|
|
129
|
+
"subscriptions": {
|
|
130
|
+
"description": "Manage which recipes this project subscribes to",
|
|
131
|
+
"hidden": true
|
|
132
|
+
},
|
|
133
|
+
"vars": {
|
|
134
|
+
"description": "Recipe variables and their answers"
|
|
135
|
+
},
|
|
136
|
+
"var": {
|
|
137
|
+
"description": "Recipe variables and their answers",
|
|
138
|
+
"hidden": true
|
|
139
|
+
}
|
|
76
140
|
}
|
|
77
141
|
},
|
|
78
142
|
"engines": {
|
|
@@ -10,12 +10,12 @@ user-invocable: false
|
|
|
10
10
|
# About Agent Skills
|
|
11
11
|
|
|
12
12
|
A skill is a directory containing a `SKILL.md` file and optional supporting files.
|
|
13
|
-
Skills extend what a coding agent can do
|
|
13
|
+
Skills extend what a coding agent can do; invoke them directly with `/skill-name`,
|
|
14
14
|
or they load automatically when the agent's decision logic matches the `description`.
|
|
15
15
|
|
|
16
16
|
## Where Skills Live
|
|
17
17
|
|
|
18
|
-
Skills for this project live at `{{ skillsRoot }}`. Create and edit skills there
|
|
18
|
+
Skills for this project live at `{{ skillsRoot }}`. Create and edit skills there,
|
|
19
19
|
never in `.claude/skills/` or `.codex/skills/` directly. See `create-skill` for
|
|
20
20
|
step-by-step instructions.
|
|
21
21
|
|
|
@@ -29,7 +29,7 @@ my-skill/
|
|
|
29
29
|
└── scripts/ # Optional. Executable scripts.
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
Supporting files must be referenced from `SKILL.md
|
|
32
|
+
Supporting files must be referenced from `SKILL.md`; the agent will not know they
|
|
33
33
|
exist otherwise. Keep `SKILL.md` under ~500 lines; move detailed reference material
|
|
34
34
|
to `references/` files.
|
|
35
35
|
|
|
@@ -46,17 +46,17 @@ user-invocable: false
|
|
|
46
46
|
---
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
**`name
|
|
49
|
+
**`name`**: becomes the `/slash-command`. Defaults to the directory name if omitted.
|
|
50
50
|
|
|
51
|
-
**`description
|
|
51
|
+
**`description`**: tells the agent when to invoke this skill. Use strong trigger
|
|
52
52
|
language: open with "YOU MUST load this skill when...". Under 500 chars.
|
|
53
53
|
|
|
54
|
-
**`disable-model-invocation
|
|
54
|
+
**`disable-model-invocation`**: set `true` to prevent the agent from invoking the
|
|
55
55
|
skill automatically. Use this for command skills that represent intentional,
|
|
56
56
|
user-initiated actions (e.g. `/commit`, `/deploy`). If it makes sense for the agent
|
|
57
57
|
to invoke the skill on the user's behalf, omit it.
|
|
58
58
|
|
|
59
|
-
**`user-invocable
|
|
59
|
+
**`user-invocable`**: set `false` to hide the skill from the `/` menu. Use this on
|
|
60
60
|
all topic skills (`about-*`). They are reference material the agent loads
|
|
61
61
|
automatically, not commands for the user to invoke.
|
|
62
62
|
|
|
@@ -69,14 +69,14 @@ shared scripts the action skills draw from. They are moderately descriptive and
|
|
|
69
69
|
across many workflows. Always set `user-invocable: false`. Use the `about-*` prefix when
|
|
70
70
|
the skill's primary purpose is background understanding.
|
|
71
71
|
|
|
72
|
-
A topic skill's body holds fundamental knowledge
|
|
72
|
+
A topic skill's body holds fundamental knowledge: what is needed in ~75%+ of use cases.
|
|
73
73
|
Deeper reference material (complete tables, edge cases, advanced patterns) goes in
|
|
74
74
|
`references/` files, loaded only when needed. When official documentation exists for the
|
|
75
75
|
topic, fetch it once and store distilled versions in `references/`, including the official
|
|
76
76
|
source URL so the agent can check anything not covered locally. This prevents repeated doc
|
|
77
77
|
fetches during work sessions.
|
|
78
78
|
|
|
79
|
-
**Action skills** perform a specific operation and are as thin as possible
|
|
79
|
+
**Action skills** perform a specific operation and are as thin as possible; they
|
|
80
80
|
contain only what is exclusive to that action. All shared knowledge belongs in the
|
|
81
81
|
parent topic skill. Action skills carry less cold-start context than topic skills: just
|
|
82
82
|
enough to not be opaque, then delegate depth upward with `YOU MUST load`. Name action
|
|
@@ -85,7 +85,7 @@ specific type, include it after the verb (e.g. `create-skill` operates on a "ski
|
|
|
85
85
|
The verb-first pattern immediately distinguishes action skills from topic skills in any
|
|
86
86
|
skill listing.
|
|
87
87
|
|
|
88
|
-
Non-command action skills must NOT have `disable-model-invocation: true
|
|
88
|
+
Non-command action skills must NOT have `disable-model-invocation: true`; that flag
|
|
89
89
|
removes the skill from the agent's context entirely, making it undiscoverable. A
|
|
90
90
|
non-command action skill relies on its description to tell the agent when to invoke it
|
|
91
91
|
automatically; omitting the flag is what makes that possible.
|
|
@@ -102,7 +102,7 @@ directory needs `.tpl.` naming or when writing LiquidJS syntax.
|
|
|
102
102
|
## General Principles
|
|
103
103
|
|
|
104
104
|
**Knowledge lives at the highest common ancestor.** If two skills need the same
|
|
105
|
-
knowledge, it belongs in the most general topic skill covering both
|
|
105
|
+
knowledge, it belongs in the most general topic skill covering both, never
|
|
106
106
|
duplicated across skills. Before adding content anywhere, ask whether it belongs
|
|
107
107
|
higher up.
|
|
108
108
|
|
|
@@ -117,7 +117,7 @@ directory). Teach the agent where to look rather than providing a snapshot that
|
|
|
117
117
|
stale. Only document things stable by nature.
|
|
118
118
|
|
|
119
119
|
**Use strong trigger language.** Descriptions must open with `YOU MUST load this
|
|
120
|
-
skill when...`. Cross-references to other skills must use `YOU MUST load
|
|
120
|
+
skill when...`. Cross-references to other skills must use `YOU MUST load`; weak
|
|
121
121
|
language like "consult" or "see" is not sufficient. In a skill body, write the
|
|
122
122
|
requirement so it binds whichever agent executes ("The agent performing this work MUST
|
|
123
123
|
load `x`"), not just the main session: delegated sub-agents start with fresh context and
|
|
@@ -135,8 +135,8 @@ that warrants its own skill.
|
|
|
135
135
|
|
|
136
136
|
## Template-Compiled Skills
|
|
137
137
|
|
|
138
|
-
Every skill distributed from a shared library
|
|
139
|
-
shared skill library
|
|
138
|
+
Every skill distributed from a shared library, whether this library (`sous`) or any other
|
|
139
|
+
shared skill library, must use `SKILL.tpl.md`, not `SKILL.md`. This is required because
|
|
140
140
|
every distributed skill must end with a `## Source for this Skill` section (see below), and
|
|
141
141
|
that section uses a template variable for the source path, which requires LiquidJS rendering.
|
|
142
142
|
No exceptions.
|
|
@@ -159,15 +159,15 @@ compile time.
|
|
|
159
159
|
|
|
160
160
|
## Examples
|
|
161
161
|
|
|
162
|
-
- [examples/about-something.md](examples/about-something.md)
|
|
163
|
-
- [examples/do-something.md](examples/do-something.md)
|
|
162
|
+
- [examples/about-something.md](examples/about-something.md): a complete example of a topic (`about-*`) skill
|
|
163
|
+
- [examples/do-something.md](examples/do-something.md): a complete example of an action skill (command)
|
|
164
164
|
|
|
165
165
|
## Reference Files
|
|
166
166
|
|
|
167
|
-
- [frontmatter.md](references/frontmatter.md)
|
|
168
|
-
- [substitutions.md](references/substitutions.md)
|
|
169
|
-
- [commands.md](references/commands.md)
|
|
170
|
-
- [advanced-patterns.md](references/advanced-patterns.md)
|
|
167
|
+
- [frontmatter.md](references/frontmatter.md): complete frontmatter field table and invocation matrix
|
|
168
|
+
- [substitutions.md](references/substitutions.md): `$ARGUMENTS`, `$ARGUMENTS[N]`, `$CLAUDE_SESSION_ID`, `$CLAUDE_SKILL_DIR`
|
|
169
|
+
- [commands.md](references/commands.md): command-specific conventions: descriptions, headings, arguments, `argument-hint`
|
|
170
|
+
- [advanced-patterns.md](references/advanced-patterns.md): dynamic context injection, subagent execution (`context: fork`), `allowed-tools`
|
|
171
171
|
|
|
172
172
|
## Source for this Skill
|
|
173
173
|
|
|
@@ -25,9 +25,9 @@ has its own configuration file under `deploy/config/`.
|
|
|
25
25
|
|
|
26
26
|
## Reference Files
|
|
27
27
|
|
|
28
|
-
- [references/environments.md](references/environments.md)
|
|
28
|
+
- [references/environments.md](references/environments.md): per-environment config
|
|
29
29
|
options, required env vars, and access requirements
|
|
30
|
-
- [references/rollback.md](references/rollback.md)
|
|
30
|
+
- [references/rollback.md](references/rollback.md): rollback procedures and known
|
|
31
31
|
failure modes
|
|
32
32
|
|
|
33
33
|
# Other Skills
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
---
|
|
5
5
|
name: deploy
|
|
6
6
|
description: >
|
|
7
|
-
YOU MUST use this skill when deploying the application. Do not use for rollbacks
|
|
7
|
+
YOU MUST use this skill when deploying the application. Do not use for rollbacks;
|
|
8
8
|
those follow a different process.
|
|
9
9
|
disable-model-invocation: true
|
|
10
10
|
---
|