@sous-io/sous 0.2.36 → 1.0.1

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.
Files changed (244) hide show
  1. package/README.md +14 -256
  2. package/dist/bin.js +11 -0
  3. package/dist/sous.js +1093 -0
  4. package/docs/markdown/README.md +5 -4
  5. package/docs/markdown/_sidebar.md +21 -1
  6. package/docs/markdown/commands.md +294 -431
  7. package/docs/markdown/config-discovery.md +25 -14
  8. package/docs/markdown/config-inspection.md +53 -31
  9. package/docs/markdown/config-layers.md +168 -66
  10. package/docs/markdown/config-variables.md +44 -11
  11. package/docs/markdown/configuration.md +104 -17
  12. package/docs/markdown/design-principles.md +4 -1
  13. package/docs/markdown/repositories-authoring.md +30 -0
  14. package/docs/markdown/repositories-consuming.md +72 -14
  15. package/docs/markdown/repositories-file-formats.md +31 -13
  16. package/docs/markdown/repositories-providers.md +48 -57
  17. package/docs/markdown/repositories-quickstart.md +3 -2
  18. package/docs/markdown/repositories-troubleshooting.md +27 -1
  19. package/docs/markdown/repositories-variables.md +6 -1
  20. package/docs/markdown/repositories.md +18 -8
  21. package/package.json +48 -107
  22. package/recipes/core/sous-skills/skills/about-liquid-templates/SKILL.tpl.md +4 -6
  23. package/recipes/core/sous-skills/skills/about-liquid-templates/references/liquid-filters.tpl.md +2 -0
  24. package/recipes/core/sous-skills/skills/about-sous/SKILL.tpl.md +10 -9
  25. package/recipes/core/sous-skills/skills/about-sous-configuration/SKILL.tpl.md +35 -14
  26. package/recipes/core/sous-skills/skills/about-sous-recipes/SKILL.tpl.md +51 -20
  27. package/recipes/core/sous-skills/sous.recipe.yaml +1 -1
  28. package/sous.config.schema.json +351 -132
  29. package/bin/run.js +0 -51
  30. package/src/base-command.ts +0 -457
  31. package/src/commands/build.ts +0 -181
  32. package/src/commands/clear.ts +0 -79
  33. package/src/commands/compile.ts +0 -155
  34. package/src/commands/config/get.ts +0 -110
  35. package/src/commands/config/show.ts +0 -32
  36. package/src/commands/config/validate.ts +0 -53
  37. package/src/commands/help.ts +0 -46
  38. package/src/commands/init.ts +0 -289
  39. package/src/commands/launch.ts +0 -139
  40. package/src/commands/lock/rebuild.ts +0 -239
  41. package/src/commands/lock/show.ts +0 -115
  42. package/src/commands/namespace/list.ts +0 -138
  43. package/src/commands/namespace/show.ts +0 -130
  44. package/src/commands/prune.ts +0 -43
  45. package/src/commands/recipe/list.ts +0 -112
  46. package/src/commands/recipe/show.ts +0 -439
  47. package/src/commands/repo/add.ts +0 -145
  48. package/src/commands/repo/contribute.ts +0 -604
  49. package/src/commands/repo/gc.ts +0 -173
  50. package/src/commands/repo/init.ts +0 -136
  51. package/src/commands/repo/link.ts +0 -899
  52. package/src/commands/repo/list.ts +0 -236
  53. package/src/commands/repo/release.ts +0 -685
  54. package/src/commands/repo/remove.ts +0 -194
  55. package/src/commands/repo/search.ts +0 -243
  56. package/src/commands/repo/submit.ts +0 -341
  57. package/src/commands/repo/unlink.ts +0 -461
  58. package/src/commands/subscription/add.ts +0 -286
  59. package/src/commands/subscription/list.ts +0 -208
  60. package/src/commands/subscription/remove.ts +0 -182
  61. package/src/commands/subscription/update.ts +0 -216
  62. package/src/commands/update.ts +0 -178
  63. package/src/commands/vars/ask.ts +0 -417
  64. package/src/commands/vars/index.ts +0 -79
  65. package/src/commands/vars/list.ts +0 -67
  66. package/src/commands/vars/show.ts +0 -77
  67. package/src/config-command.ts +0 -30
  68. package/src/lib/build-preparation.ts +0 -128
  69. package/src/lib/build-service.ts +0 -580
  70. package/src/lib/config-discovery.ts +0 -378
  71. package/src/lib/config-inspect.ts +0 -145
  72. package/src/lib/config-kernel.mjs +0 -379
  73. package/src/lib/config-schema.ts +0 -401
  74. package/src/lib/env-file.ts +0 -328
  75. package/src/lib/env-local.ts +0 -212
  76. package/src/lib/errors.ts +0 -32
  77. package/src/lib/glob-pattern.ts +0 -24
  78. package/src/lib/include-resolver.ts +0 -523
  79. package/src/lib/interactive.ts +0 -165
  80. package/src/lib/markdown-compiler.ts +0 -947
  81. package/src/lib/package-info.ts +0 -25
  82. package/src/lib/pid-service.ts +0 -99
  83. package/src/lib/project-install.d.mts +0 -44
  84. package/src/lib/project-install.mjs +0 -234
  85. package/src/lib/project-scaffold/index.ts +0 -332
  86. package/src/lib/project-scaffold/templates.ts +0 -240
  87. package/src/lib/repos/catalog-display.ts +0 -215
  88. package/src/lib/repos/catalog-inputs.ts +0 -288
  89. package/src/lib/repos/catalog.ts +0 -842
  90. package/src/lib/repos/contribute.ts +0 -452
  91. package/src/lib/repos/core-recipe.ts +0 -105
  92. package/src/lib/repos/declarations.ts +0 -187
  93. package/src/lib/repos/defaults.ts +0 -175
  94. package/src/lib/repos/formats/common.ts +0 -440
  95. package/src/lib/repos/formats/index-file.ts +0 -253
  96. package/src/lib/repos/formats/links-map.ts +0 -98
  97. package/src/lib/repos/formats/lockfile.ts +0 -169
  98. package/src/lib/repos/formats/patterns.ts +0 -57
  99. package/src/lib/repos/formats/recipe-manifest.ts +0 -205
  100. package/src/lib/repos/formats/repo-manifest.ts +0 -97
  101. package/src/lib/repos/formats/store-entry.ts +0 -84
  102. package/src/lib/repos/formats/variable-definition.ts +0 -268
  103. package/src/lib/repos/freshness.ts +0 -264
  104. package/src/lib/repos/git-clone.ts +0 -850
  105. package/src/lib/repos/identity.ts +0 -89
  106. package/src/lib/repos/index.ts +0 -57
  107. package/src/lib/repos/links.ts +0 -356
  108. package/src/lib/repos/load-manifest.ts +0 -237
  109. package/src/lib/repos/lock-service.ts +0 -454
  110. package/src/lib/repos/locked-namespace-resolver.ts +0 -232
  111. package/src/lib/repos/locked-recipe-lookup.ts +0 -123
  112. package/src/lib/repos/locked-recipes.ts +0 -254
  113. package/src/lib/repos/managed-layer.ts +0 -422
  114. package/src/lib/repos/memories-hash-name.ts +0 -33
  115. package/src/lib/repos/namespace-resolver.ts +0 -527
  116. package/src/lib/repos/providers/base.ts +0 -268
  117. package/src/lib/repos/providers/git.ts +0 -237
  118. package/src/lib/repos/providers/github.ts +0 -589
  119. package/src/lib/repos/providers/gitlab.ts +0 -332
  120. package/src/lib/repos/providers/http.ts +0 -128
  121. package/src/lib/repos/providers/index-cache.ts +0 -421
  122. package/src/lib/repos/providers/index.ts +0 -106
  123. package/src/lib/repos/providers/local.ts +0 -391
  124. package/src/lib/repos/providers/provider.ts +0 -615
  125. package/src/lib/repos/recipe-config-layers.ts +0 -316
  126. package/src/lib/repos/recipe-key-matcher.ts +0 -62
  127. package/src/lib/repos/recipe-memories.ts +0 -178
  128. package/src/lib/repos/recipe-targets.ts +0 -236
  129. package/src/lib/repos/ref-search.ts +0 -46
  130. package/src/lib/repos/release/bump.ts +0 -161
  131. package/src/lib/repos/release/changelog.ts +0 -461
  132. package/src/lib/repos/release/git-state.ts +0 -460
  133. package/src/lib/repos/release/index-builder.ts +0 -1108
  134. package/src/lib/repos/release/index.ts +0 -19
  135. package/src/lib/repos/release/plan.ts +0 -521
  136. package/src/lib/repos/release/settle.ts +0 -154
  137. package/src/lib/repos/release/submissions.ts +0 -214
  138. package/src/lib/repos/release/submit-checkout.ts +0 -290
  139. package/src/lib/repos/release/submit-questions.ts +0 -153
  140. package/src/lib/repos/release/submit-service.ts +0 -898
  141. package/src/lib/repos/release/tags.ts +0 -239
  142. package/src/lib/repos/release/validate.ts +0 -463
  143. package/src/lib/repos/resolver.ts +0 -1028
  144. package/src/lib/repos/scaffold/index.ts +0 -245
  145. package/src/lib/repos/scaffold/templates.ts +0 -517
  146. package/src/lib/repos/seed.ts +0 -473
  147. package/src/lib/repos/store/contract.ts +0 -64
  148. package/src/lib/repos/store/hash.ts +0 -191
  149. package/src/lib/repos/store/recipe-store.ts +0 -599
  150. package/src/lib/repos/store/settings.ts +0 -58
  151. package/src/lib/repos/subscription-service.ts +0 -3859
  152. package/src/lib/repos/trust.ts +0 -447
  153. package/src/lib/repos/update-plan.ts +0 -235
  154. package/src/lib/self-update/index.ts +0 -14
  155. package/src/lib/self-update/installs.ts +0 -412
  156. package/src/lib/self-update/managers.ts +0 -126
  157. package/src/lib/self-update/plan.ts +0 -315
  158. package/src/lib/self-update/registry.ts +0 -99
  159. package/src/lib/self-update/run.ts +0 -506
  160. package/src/lib/self-update/versions.ts +0 -243
  161. package/src/lib/settings.ts +0 -1105
  162. package/src/lib/sous-home.ts +0 -104
  163. package/src/lib/state.ts +0 -167
  164. package/src/lib/vars/answers.ts +0 -192
  165. package/src/lib/vars/ask.ts +0 -1152
  166. package/src/lib/vars/definition-source.ts +0 -261
  167. package/src/lib/vars/display.ts +0 -231
  168. package/src/lib/vars/index.ts +0 -20
  169. package/src/lib/vars/ladder.ts +0 -282
  170. package/src/lib/vars/mappings.ts +0 -260
  171. package/src/lib/vars/names.ts +0 -94
  172. package/src/lib/vars/preanswers.ts +0 -395
  173. package/src/lib/vars/question-plan.ts +0 -241
  174. package/src/lib/vars/report.ts +0 -228
  175. package/src/lib/vars/safe-regex.ts +0 -235
  176. package/src/lib/vars/secrets.ts +0 -131
  177. package/src/lib/vars/validate.ts +0 -312
  178. package/src/lib/version-report.ts +0 -90
  179. package/src/lib/watch-loop.ts +0 -148
  180. package/src/lib/watch-service.ts +0 -116
  181. package/src/services/ref-resolver/container.ts +0 -107
  182. package/src/services/ref-resolver/dependency.ts +0 -60
  183. package/src/services/ref-resolver/format.ts +0 -197
  184. package/src/services/ref-resolver/glob.ts +0 -115
  185. package/src/services/ref-resolver/hash-names.ts +0 -155
  186. package/src/services/ref-resolver/index.ts +0 -55
  187. package/src/services/ref-resolver/injectable.ts +0 -36
  188. package/src/services/ref-resolver/location.ts +0 -62
  189. package/src/services/ref-resolver/lookups/cached-index-lookup.ts +0 -53
  190. package/src/services/ref-resolver/lookups/catalog-lookup.ts +0 -23
  191. package/src/services/ref-resolver/lookups/catalog-matcher.ts +0 -261
  192. package/src/services/ref-resolver/lookups/chained-lookup.ts +0 -27
  193. package/src/services/ref-resolver/lookups/env-var-lookup.ts +0 -65
  194. package/src/services/ref-resolver/lookups/fetched-index-lookup.ts +0 -150
  195. package/src/services/ref-resolver/lookups/recorded-dependency-lookup.ts +0 -62
  196. package/src/services/ref-resolver/lookups/ref-lookup.ts +0 -54
  197. package/src/services/ref-resolver/lookups/variable-lookup.ts +0 -123
  198. package/src/services/ref-resolver/named-refs.ts +0 -144
  199. package/src/services/ref-resolver/parser/env-var-splitter.ts +0 -27
  200. package/src/services/ref-resolver/parser/location-splitter.ts +0 -239
  201. package/src/services/ref-resolver/parser/name-path-splitter.ts +0 -200
  202. package/src/services/ref-resolver/parser/partial-ref.ts +0 -84
  203. package/src/services/ref-resolver/parser/query-splitter.ts +0 -61
  204. package/src/services/ref-resolver/parser/range-splitter.ts +0 -52
  205. package/src/services/ref-resolver/parser/ref-parser.ts +0 -115
  206. package/src/services/ref-resolver/parser/repo-qualifier-splitter.ts +0 -51
  207. package/src/services/ref-resolver/parts.ts +0 -115
  208. package/src/services/ref-resolver/pruners/command-line-pruner.ts +0 -47
  209. package/src/services/ref-resolver/pruners/include-pruner.ts +0 -66
  210. package/src/services/ref-resolver/pruners/manifest-pruner.ts +0 -130
  211. package/src/services/ref-resolver/pruners/ref-pruner.ts +0 -135
  212. package/src/services/ref-resolver/pruners/rule-helpers.ts +0 -44
  213. package/src/services/ref-resolver/pruners/stored-key-pruner.ts +0 -136
  214. package/src/services/ref-resolver/ref-helpers.ts +0 -62
  215. package/src/services/ref-resolver/ref-picker-service.ts +0 -204
  216. package/src/services/ref-resolver/ref-report.ts +0 -84
  217. package/src/services/ref-resolver/ref-resolve-arguments.ts +0 -47
  218. package/src/services/ref-resolver/ref-resolve-result.ts +0 -36
  219. package/src/services/ref-resolver/ref-resolver-service.ts +0 -323
  220. package/src/services/ref-resolver/source.ts +0 -48
  221. package/src/services/ref-resolver/tokens.ts +0 -25
  222. package/src/services/ref-resolver/types.ts +0 -155
  223. package/src/templating/filters/bullet-list.ts +0 -9
  224. package/src/templating/filters/index.ts +0 -8
  225. package/src/templating/init-liquid-engine.ts +0 -139
  226. package/src/templating/lib/glob-files.ts +0 -74
  227. package/src/templating/lib/import-export.ts +0 -32
  228. package/src/templating/lib/secret-scope.ts +0 -41
  229. package/src/templating/lib/tag-args.ts +0 -19
  230. package/src/templating/tags/exportScalarVarsJs.ts +0 -46
  231. package/src/templating/tags/getFiles.ts +0 -89
  232. package/src/templating/tags/index.ts +0 -14
  233. package/src/templating/tags/listFiles.ts +0 -54
  234. package/src/templating/tags/showVars.ts +0 -28
  235. package/src/utils/choice-prompt.ts +0 -143
  236. package/src/utils/command-errors.ts +0 -186
  237. package/src/utils/command-help.ts +0 -45
  238. package/src/utils/confirm-prompt.ts +0 -110
  239. package/src/utils/flags.ts +0 -177
  240. package/src/utils/formatting.ts +0 -849
  241. package/src/utils/prompts.ts +0 -53
  242. package/src/utils/sous-directory.ts +0 -245
  243. package/src/utils/table.ts +0 -603
  244. package/src/utils/value-prompt.ts +0 -119
@@ -25,7 +25,8 @@ before fetching anything and asks about all of them in one question, listing eac
25
25
  that requires it; declining any of them stops the whole install.
26
26
 
27
27
  !> Trusting a repository trusts every namespace and recipe in it, including ones published later.
28
- Trusting alone runs nothing; subscribing to something inside it can run scripts on this machine.
28
+ Trusting alone runs nothing; subscribing to something inside it can run scripts on this machine,
29
+ and a sous plugin a recipe ships runs inside sous itself.
29
30
  See [Trust](repositories.md#trust).
30
31
 
31
32
  ## A ref that names more than one thing
@@ -330,6 +331,31 @@ active, so a project needing its own store can say `SOUS_HOME=~/caches/sous-home
330
331
  compare [Discovery and overrides](config-discovery.md), where `SOUS_CONFIG`, `SOUS_DIR` and
331
332
  `SOUS_CONFD` are read from the real environment only.
332
333
 
334
+ ## A private repository sous cannot read
335
+
336
+ ```text
337
+ Error: could not read gitlab.com/acme/private-recipes.
338
+ HTTP with token no token found (GITLAB_TOKEN unset; git has no stored credential for gitlab.com)
339
+ HTTP without token 302 to sign-in page: the repository is private
340
+ git Permission denied (publickey)
341
+ Fix one of these:
342
+ export GITLAB_TOKEN=<a token with read_repository>
343
+ set up git access to gitlab.com (an SSH key, or a credential helper)
344
+ ```
345
+
346
+ Sous tried every way it has to read the repository, and each line says why that one failed. Any one fix
347
+ is enough: a token in the environment, or git access to the host. `gh` and `glab` are not needed to read.
348
+ The order sous tries, and where it finds a token, are under
349
+ [Private repositories](repositories-providers.md#private-repositories).
350
+
351
+ ## A recipe that requires a plugin
352
+
353
+ A recipe may require a sous plugin from npm, with a version range. `sous subscription add` refuses such a
354
+ recipe while the plugin is missing or outside the range, and a build fails when a subscribed recipe's
355
+ requirement breaks later, for example after the plugin was removed from `package.json`. Both messages name
356
+ the plugin and the command that installs it. Run that command, or rerun the subscribe with
357
+ `--install-plugins`, which installs it through the project's package manager without asking.
358
+
333
359
  ## Where to go next
334
360
 
335
361
  - [Quickstart](repositories-quickstart.md): the shortest path from an empty project to a skill
@@ -231,6 +231,7 @@ advanced view draws, and the ladder table above. The name may be bare or the ful
231
231
  | `sous vars ask --all` | Asks every variable again, including the ones already answered |
232
232
  | `sous vars ask --accept-first` | When the name matches several things, takes the first one listed |
233
233
  | `sous vars ask --file <path>` | Reads definitions from a standalone definitions file |
234
+ | `sous vars ask --env-file <file>` | Stores every answer of the run in `.sous/.env` (committed) or `.sous/.env.local` (this machine only); any spelling that names one is accepted, and a secret or machine-specific variable sent to the committed file needs a yes (`--yes`) |
234
235
  | `sous vars ask --answer <name>=<value>` | Answers one question ahead of time; repeat it for each answer |
235
236
  | `sous vars ask --answers-file <path>` | Reads answers from a YAML or JSON file of `name: value` pairs |
236
237
  | `sous vars ask --dry-run` | Reports what would be asked and written, without writing anything |
@@ -330,6 +331,9 @@ empty string, and the build says so before it compiles, naming each such variabl
330
331
  it, and `sous vars ask` as the way to answer. The build still succeeds; an unanswered question is
331
332
  something to tell you about, not a reason to refuse the rest of the project.
332
333
 
334
+ A variable declared only by recipes that are not built on this machine, because their subscription is
335
+ switched off, is neither asked by `sous vars ask` nor required by the build.
336
+
333
337
  ?> Two recipes may ask the same question. Their shared answer renders in both, and in your own templates.
334
338
  When the recipe-scoped name gives one of them a different answer, that recipe's own files render its own
335
339
  answer while everything else, your templates included, renders the first definition's; `sous vars show`
@@ -337,7 +341,8 @@ tells you which names are in play.
337
341
 
338
342
  An answer is laid in exactly as it is stored: a path stays the string you typed, relative or absolute, and a
339
343
  number stays text. A template that needs an absolute path from a relative answer composes one under another
340
- name in `_vars`, for instance `taskFileDir: "${sousDir}/../${taskFileRoot}"`.
344
+ name in `_vars`, for instance `taskFileDir: "${projectRoot}/${taskFileRoot}"`. `projectRoot` is set by sous
345
+ (the directory holding `.sous/`); setting it in any `_vars` is an error.
341
346
 
342
347
  The `_env` block is still the way to reach any environment variable no recipe asks about.
343
348
 
@@ -48,7 +48,9 @@ $ sous namespace list
48
48
  A recipe is the unit you subscribe to and the only thing that carries a version. It may hold
49
49
  skills, memories, prompts, config layers and variable definitions in any mixture, and
50
50
  subscribing to it gets all of them. A recipe may ship a plugin for a coding tool (a Claude Code
51
- plugin, say), but never a plugin for sous itself; those come only with sous or as npm packages.
51
+ plugin, say), and it may ship a plugin for sous itself, as one bundled file (see
52
+ [Recipes that ship sous plugins](repositories-authoring.md#recipes-that-ship-sous-plugins)). A recipe may
53
+ also require sous plugins from npm.
52
54
 
53
55
  ```yaml
54
56
  # recipes/workflow/task-files/sous.recipe.yaml
@@ -194,10 +196,16 @@ this machine.
194
196
  Subscribing decides what is switched on, and it is not a second security gate. A recipe is
195
197
  **active** when the project subscribes to it directly or through its namespace, or when an active
196
198
  recipe lists it under `subscribes`; only an active recipe registers entry points of its own, such as
197
- output files, skills, tool hooks and tool plugins. A recipe held only through `depends` is a library:
199
+ output files, skills, tool hooks, tool plugins and sous plugins. A recipe held only through `depends` is a library:
198
200
  an active recipe may include, call or import its files, but it registers nothing itself. Activation
199
201
  keeps a project from running what it has no use for and keeps unrelated recipes from colliding;
200
- everything in a trusted repository is already trusted.
202
+ everything in a trusted repository is already trusted. Nothing inside a repository runs, a sous
203
+ plugin included, until the repository is trusted.
204
+
205
+ A subscription can be switched off on one machine and left on for everyone else, for example from
206
+ a `conf.d` file of your own. A switched-off subscription is not built: its outputs are pruned, its
207
+ variables are not asked, and its pins stay in the committed lockfile. `sous subscription disable <ref>`
208
+ and `sous subscription enable <ref>` switch one off and on.
201
209
 
202
210
  ## The official repository, and the built-in core
203
211
 
@@ -280,9 +288,9 @@ $ sous build
280
288
  ✓ /home/me/my-project/.claude/skills/start-task/SKILL.md (~1,996 tokens)
281
289
  ```
282
290
 
283
- Skills default to `<project root>/.claude/skills`, and the
284
- [`recipes`](repositories-file-formats.md#recipes-what-each-content-kind-does) block changes that. Memories are
285
- not copied anywhere; one include line in your instruction source pulls them in (see
291
+ Skills go to `<project root>/.claude/skills`, the skills directory the built-in Claude Code plugin names, and the
292
+ [`recipes`](repositories-file-formats.md#recipes-what-each-content-kind-does) block adds destinations of
293
+ your own. Memories are not copied as files; one include line in your instruction source pulls them in (see
286
294
  [Recipe memories](repositories-consuming.md#recipe-memories)).
287
295
 
288
296
  By default a build uses what the lockfile pins and does not talk to the network. Two things
@@ -321,8 +329,10 @@ and `varMappings:` in your primary config instead, which sous never touches. See
321
329
 
322
330
  Every directory sous creates for its own bookkeeping explains itself: the first time it creates
323
331
  one it writes a short `README.md` saying what the directory is, who writes to it, whether you may
324
- edit it and whether it is committed, plus an `AGENTS.md` and a `CLAUDE.md` pointing at that
325
- README. None is ever overwritten, and directories holding rendered output are left alone.
332
+ edit it and whether it is committed. Agent plugins add one-line pointer files beside it that tell
333
+ their agent to read the README: the built-in Claude Code plugin adds a `CLAUDE.md`, and a plugin for an
334
+ agent that reads `AGENTS.md` adds that. Each file is written once, none is ever overwritten, and
335
+ directories holding rendered output are left alone.
326
336
 
327
337
  ## Including recipe files in your own templates
328
338
 
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@sous-io/sous",
3
- "version": "0.2.36",
3
+ "version": "1.0.1",
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",
7
7
  "author": "Luke Chavers",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "git+https://github.com/sous-io/sous.git"
10
+ "url": "git+https://github.com/sous-io/sous.git",
11
+ "directory": "packages/sous"
11
12
  },
12
13
  "homepage": "https://sous.io",
13
14
  "bugs": "https://github.com/sous-io/sous/issues",
@@ -27,121 +28,61 @@
27
28
  "access": "public"
28
29
  },
29
30
  "bin": {
30
- "sous": "./bin/run.js"
31
+ "sous": "./dist/bin.js"
31
32
  },
32
33
  "files": [
33
- "bin/run.js",
34
- "src",
35
- "!src/**/*.spec.ts",
36
- "!src/test",
34
+ "dist/bin.js",
35
+ "dist/sous.js",
37
36
  "recipes",
38
37
  "docs/markdown/*.md",
39
38
  "sous.config.schema.json"
40
39
  ],
41
- "scripts": {
42
- "build": "tsc",
43
- "sous:build": "./bin/sous build --rebuild",
44
- "claude": "./bin/sous launch claude",
45
- "clean": "rm -rf dist",
46
- "schema:build": "tsx scripts/build-schema.mts",
47
- "version:sync": "tsx scripts/sync-core-version.mts",
48
- "test": "vitest run",
49
- "test:watch": "vitest",
50
- "test:coverage": "vitest run --coverage",
51
- "test:e2e": "vitest run --config vitest.e2e.config.ts"
52
- },
53
40
  "dependencies": {
54
- "@inquirer/core": "^11.1.7",
55
- "@inquirer/prompts": "^8.3.2",
56
- "@oclif/color": "^1.0.13",
57
- "@oclif/core": "^4",
58
- "chokidar": "^5.0.0",
59
- "glob": "^13.0.6",
60
- "inversify": "^8.2.3",
61
- "jsonc-parser": "^3.3.1",
62
- "liquidjs": "^10.25.0",
63
- "minimatch": "^10.2.4",
64
- "package-manager-detector": "^1.8.0",
65
- "semver": "^7.8.5",
66
- "tiktoken": "^1.0.22",
67
- "tsx": "^4",
68
- "yaml": "^2.9.0",
69
- "zod": "^4.4.3"
41
+ "@sous-io/plugin-api": "1.0.1"
70
42
  },
71
43
  "devDependencies": {
72
- "@types/glob": "^8.1.0",
73
- "@types/node": "^22",
74
- "@types/semver": "^7.8.0",
75
- "@vitest/coverage-v8": "^4.1.0",
76
- "memfs": "^4.56.11",
77
- "typescript": "^5",
78
- "vitest": "^4.1.0"
79
- },
80
- "oclif": {
81
- "bin": "sous",
82
- "dirname": "sous",
83
- "flexibleTaxonomy": true,
84
- "topicSeparator": " ",
85
- "additionalHelpFlags": [
86
- "-h"
87
- ],
88
- "commands": {
89
- "strategy": "pattern",
90
- "target": "./src/commands"
91
- },
92
- "topics": {
93
- "config": {
94
- "description": "Inspect the merged configuration"
95
- },
96
- "configs": {
97
- "description": "Inspect the merged configuration",
98
- "hidden": true
99
- },
100
- "repo": {
101
- "description": "Manage the recipe repositories this project trusts"
102
- },
103
- "repos": {
104
- "description": "Manage the recipe repositories this project trusts",
105
- "hidden": true
106
- },
107
- "lock": {
108
- "description": "Inspect and repair this project's lockfile"
109
- },
110
- "locks": {
111
- "description": "Inspect and repair this project's lockfile",
112
- "hidden": true
113
- },
114
- "namespace": {
115
- "description": "Browse the namespaces the trusted repositories publish"
116
- },
117
- "namespaces": {
118
- "description": "Browse the namespaces the trusted repositories publish",
119
- "hidden": true
120
- },
121
- "recipe": {
122
- "description": "Browse the recipes the trusted repositories publish"
123
- },
124
- "recipes": {
125
- "description": "Browse the recipes the trusted repositories publish",
126
- "hidden": true
127
- },
128
- "subscription": {
129
- "description": "Manage which recipes this project subscribes to"
130
- },
131
- "subscriptions": {
132
- "description": "Manage which recipes this project subscribes to",
133
- "hidden": true
134
- },
135
- "vars": {
136
- "description": "Recipe variables and their answers"
137
- },
138
- "var": {
139
- "description": "Recipe variables and their answers",
140
- "hidden": true
141
- }
142
- }
44
+ "esbuild": "^0.27.4",
45
+ "jsonc-parser": "^3.3.1",
46
+ "yaml": "^2.9.0",
47
+ "zod": "^4.4.3",
48
+ "@sous-io/core": "1.0.1",
49
+ "@sous-io/plugin-authoring": "1.0.1",
50
+ "@sous-io/plugin-build": "1.0.1",
51
+ "@sous-io/plugin-claude-code": "1.0.1",
52
+ "@sous-io/documents": "1.0.1",
53
+ "@sous-io/plugin-cli": "1.0.1",
54
+ "@sous-io/plugin-compiler": "1.0.1",
55
+ "@sous-io/plugin-confd": "1.0.1",
56
+ "@sous-io/plugin-config-files": "1.0.1",
57
+ "@sous-io/plugin-formats": "1.0.1",
58
+ "@sous-io/plugin-expressions": "1.0.1",
59
+ "@sous-io/plugin-git": "1.0.1",
60
+ "@sous-io/plugin-github": "1.0.1",
61
+ "@sous-io/plugin-gitlab": "1.0.1",
62
+ "@sous-io/plugin-host": "1.0.1",
63
+ "@sous-io/plugin-harnesses": "1.0.1",
64
+ "@sous-io/plugin-inspect": "1.0.1",
65
+ "@sous-io/plugin-init": "1.0.1",
66
+ "@sous-io/plugin-liquid": "1.0.1",
67
+ "@sous-io/plugin-local": "1.0.1",
68
+ "@sous-io/plugin-mcp": "1.0.1",
69
+ "@sous-io/plugin-memories": "1.0.1",
70
+ "@sous-io/plugin-npm": "1.0.1",
71
+ "@sous-io/plugin-recipe-answers": "1.0.1",
72
+ "@sous-io/plugin-pnpm": "1.0.1",
73
+ "@sous-io/plugin-recipes": "1.0.1",
74
+ "@sous-io/plugin-refs": "1.0.1",
75
+ "@sous-io/plugin-skills": "1.0.1",
76
+ "@sous-io/plugin-update": "1.0.1",
77
+ "@sous-io/plugin-yarn": "1.0.1",
78
+ "@sous-io/plugin-variables": "1.0.1"
143
79
  },
144
80
  "engines": {
145
81
  "node": ">=22"
82
+ },
83
+ "scripts": {
84
+ "test": "vitest run",
85
+ "typecheck": "tsc --noEmit -p .",
86
+ "build": "node scripts/bundle.mjs"
146
87
  }
147
- }
88
+ }
@@ -196,12 +196,10 @@ wins**; if none exist, the build errors listing every path tried:
196
196
 
197
197
  ## Custom Tags
198
198
 
199
- The tags below are built into sous. A recipe cannot add a tag or a filter, since that would be a
200
- Sous plugin; a Sous plugin comes only from sous's built-ins or an npm-style module.
201
-
202
- > "recipes will not be allowed to install _Sous_ plugins. All Sous plugins, besides any built-ins that ship with Sous, itself, will come from a NPM repo (or similar) as modules. Recipes _will_ be allowed to install tool plugins (e.g. Claude Code Plugins)."
203
- >
204
- > -- **Luke Chavers** in an agent session (2026-09-29)
199
+ The tags below are built into sous. A Sous plugin (a package that extends sous itself, which a
200
+ subscribed recipe may also ship) can add more tags and filters, and config expressions (`$if`,
201
+ `$expr`) can use the filters too. Run `sous plugins show` to list the tags and filters each loaded
202
+ plugin added before using one that is not documented here.
205
203
 
206
204
  **`showVars`**: dumps all variables currently in scope as a fenced JSON block.
207
205
  Useful during development to see exactly what variables are available at a given point
@@ -80,3 +80,5 @@ Standard filters available in all `.tpl.` files. Chained with `|`.
80
80
  | Filter | Description |
81
81
  |:-------|:------------|
82
82
  | `bulletList` | Convert array to markdown bullet list (`- item` per line) |
83
+
84
+ Sous plugins may add more filters; run `sous plugins show` to list them.
@@ -64,15 +64,16 @@ trust question reads only its index.
64
64
 
65
65
  Subscribing decides what is switched on, not what is safe. A recipe is active when the
66
66
  project subscribes to it, directly or through its namespace, or when an active recipe
67
- lists it under `subscribes`, and only an active recipe registers entry points of its own
68
- (output files, skills, tool hooks and tool plugins). A recipe held only through `depends` is a
69
- library: an active recipe may include, call or import its files, but it registers nothing
70
- itself. No recipe installs a Sous plugin; Sous plugins come only from sous's built-ins and from
71
- npm-style modules.
72
-
73
- > "recipes will not be allowed to install _Sous_ plugins. All Sous plugins, besides any built-ins that ship with Sous, itself, will come from a NPM repo (or similar) as modules. Recipes _will_ be allowed to install tool plugins (e.g. Claude Code Plugins)."
74
- >
75
- > -- **Luke Chavers** in an agent session (2026-09-29)
67
+ lists it under `subscribes`. Only an active recipe adds anything to the project: output files,
68
+ skills, tool hooks, tool plugins (such as a Claude Code plugin) and Sous plugins (code that
69
+ extends sous itself). A recipe held only through `depends` is a library: an active recipe may
70
+ include, call or import its files, but it adds nothing to the project itself.
71
+
72
+ A recipe's Sous plugin runs inside sous while sous builds the project's config, with the user's
73
+ own permissions, so it is code from that recipe's repository like any other. A recipe may also
74
+ require plugins from npm; `sous subscription add` refuses it while one is missing or outside
75
+ its version range, and offers to install it. Run `sous plugins show` to list every loaded plugin
76
+ and what it added.
76
77
 
77
78
  ## Sous's Own Documentation
78
79
 
@@ -17,12 +17,20 @@ metadata:
17
17
 
18
18
  # About Sous Configuration
19
19
 
20
- Sous reads one configuration per project from the project's `.sous/` directory: exactly ONE
21
- primary config (`sous.config.js|mjs|json|yaml`), optionally extended by `conf.d/` drop-in
22
- layers that deep-merge over it. One config describes one project; every setting lives at the
23
- top level of a single flat object. There is no user-level config and no multi-project map.
24
- Configs use `${var}` syntax, resolved by a fixpoint loop (declaration order never matters);
25
- `sous*`-prefixed variable names are reserved auto-vars.
20
+ Sous builds one configuration per project, from the project's `.sous/` directory: exactly ONE
21
+ primary config (`sous.config.js|mjs|json|yaml`), optionally extended by `conf.d/` drop-in files.
22
+ One config describes one project; every setting lives at the top level of a single flat object.
23
+ There is no user-level config, no multi-project map and no separate bootstrap config.
24
+
25
+ Plugins and subscribed recipes may change the config too. The primary config and the `conf.d/`
26
+ files are always applied after them, in file order, so the project's own files win over any plugin
27
+ or recipe. Sous may apply a file more than once while it builds the config, so a JS config's
28
+ `configure()` MUST give the same result every time it runs for the same input (no counters, no
29
+ writes to disk).
30
+
31
+ Configs use `${var}` syntax, resolved until every value settles (declaration order never
32
+ matters); `sous*`-prefixed names and `projectRoot` are auto-variables sous sets itself.
33
+ `projectRoot` is the directory holding `.sous/`; setting it in any `_vars` is an error.
26
34
 
27
35
  ## This Project's Configuration
28
36
 
@@ -40,10 +48,10 @@ Read these files for anything beyond this page; do not guess and do not search t
40
48
  - `{{ sousRootPath }}/docs/markdown/configuration.md`: the config file, its shape, composition
41
49
  - `{{ sousRootPath }}/docs/markdown/config-discovery.md`: how sous finds the config; flag/env
42
50
  precedence; env-file layering; discovery errors
43
- - `{{ sousRootPath }}/docs/markdown/config-layers.md`: merge semantics; the JS `configure()`
44
- contract; the builder API; the managed 5xx layer band
45
- - `{{ sousRootPath }}/docs/markdown/config-variables.md`: the scope chain; auto-vars; fixpoint
46
- resolution; error anatomy; `stateFilePath`/`pidFilePath`
51
+ - `{{ sousRootPath }}/docs/markdown/config-layers.md`: how the files combine; the JS
52
+ `configure()` contract; the builder API; patch files; the 5xx band the sous CLI writes
53
+ - `{{ sousRootPath }}/docs/markdown/config-variables.md`: the scope chain; auto-vars; how values
54
+ settle; error anatomy; `stateFilePath`/`pidFilePath`
47
55
  - `{{ sousRootPath }}/docs/markdown/config-inspection.md`: the validation pipeline; the JSON
48
56
  Schema artifact; the `sous config` commands
49
57
 
@@ -55,14 +63,27 @@ prefer the on-disk copies.
55
63
 
56
64
  - After editing any config file, run `sous config validate`: it runs schema validation plus
57
65
  full variable resolution, surfacing cycles and undefined `${refs}`. Use
58
- `sous config get <path> --layers` to see which file set a value.
66
+ `sous config get <path> --layers` to see which file or plugin changed a value, in order.
59
67
  - Hand-written config belongs in the primary file or your own `conf.d/` layers. Never
60
68
  hand-edit `conf.d/500-*` through `conf.d/599-*`; that band is reserved for layers the sous
61
69
  CLI writes.
62
- - The top-level `recipes` key says what the project does with each content kind its subscribed
63
- recipes publish: `recipes.skills.outputs` lists the directories skills are written to, and
70
+ - The top-level `recipes` key says what the project does with each kind of content its
71
+ subscribed recipes publish. Skills go to every skills directory an agent plugin adds (the
72
+ built-in Claude Code plugin adds `.claude/skills`) and to every directory listed in
73
+ `recipes.skills.outputs`; with neither, the build skips the skills and says why.
64
74
  `recipes.memories.first` and `recipes.memories.exclude` (globs over `namespace/recipe`, or
65
- `/regex/` strings) order and filter the memories the `@#memories/**/*.md` include pulls in.
75
+ `/regex/` strings) order and filter the recipe memories.
76
+ - The `plugins` key decides which Sous plugins (packages that extend sous itself) load, beyond
77
+ the built-ins and those listed in the project's `package.json`, and holds each plugin's own
78
+ options. `configuration.md` above documents its fields. Run `sous plugins show` to see which
79
+ plugins loaded and what each added.
80
+ - A value in a JSON, JSONC or YAML config may be a config expression (`$if`, `$elseif`, `$else`,
81
+ `$expr`), worked out when sous builds the config, for example to switch a subscription off on
82
+ one platform. See `configuration.md` above for the syntax.
83
+ - A `conf.d/*.patch.json` or `*.patch.jsonl` file holds raw edit operations (for example, remove
84
+ an array item) instead of config data. Read the "Patch files" section of `config-layers.md`
85
+ above before writing one: an array index in a patch file is NEVER recomputed, so it can hit the
86
+ wrong item if anything else changes that array.
66
87
  - Any config problem halts sous with a ConfigError naming the offending file; fix the named
67
88
  file rather than working around it.
68
89
  - Configs use `${var}`; template files use LiquidJS double-brace syntax. The two resolve at
@@ -2,8 +2,8 @@
2
2
  name: about-sous-recipes
3
3
  description: >
4
4
  YOU MUST load this skill when creating or changing a sous recipe: its sous.recipe.yaml, its
5
- version, the variables it asks for, the files it publishes, its depends or subscribes lists,
6
- or a partial or @~ include inside it.
5
+ version, the variables it asks for, the files it publishes, a Sous plugin it ships or requires,
6
+ its depends or subscribes lists, or a partial or @~ include inside it.
7
7
  user-invocable: false
8
8
  license: Apache-2.0
9
9
  compatibility:
@@ -49,21 +49,16 @@ The fields in that example:
49
49
  `sous repo search`.
50
50
  - `contents` is what a subscriber receives: one group per kind (`skills`, `memories`, `prompts` or
51
51
  `config`), each with `include` globs and optional `exclude` globs, relative to the recipe folder.
52
- The subscribing project decides where skills land; memories are included into its instruction
53
- files by one line, `@#memories/**/*.md` (see "Shipping Memories" below), and nothing takes
54
- prompts yet. A `config` file becomes
55
- a config layer in the project, loaded under the project's own config so the project always wins;
56
- it MUST be `.json`, `.jsonc`, `.yaml` or `.yml`, and every key outside `_aliases`, `_vars`,
57
- `compilation`, `recipes`, `runtimeContext`, `store` and `varMappings` is dropped with a
58
- warning. A recipe that only bundles others may leave `contents` out.
59
- - A recipe MAY install tool plugins (a plugin for a coding agent tool, such as a Claude Code
60
- plugin) and MUST NOT install a Sous plugin (one that extends sous itself). Sous plugins come only
61
- from the built-ins that ship with sous and from npm-style modules. A `config` file is
62
- configuration, not a Sous plugin.
63
-
64
- > "recipes will not be allowed to install _Sous_ plugins. All Sous plugins, besides any built-ins that ship with Sous, itself, will come from a NPM repo (or similar) as modules. Recipes _will_ be allowed to install tool plugins (e.g. Claude Code Plugins)."
65
- >
66
- > -- **Luke Chavers** in an agent session (2026-09-29)
52
+ The subscribing project decides where skills land (its config, and the Sous plugin for each
53
+ coding agent it uses, such as the built-in Claude Code plugin); memories reach its instruction
54
+ files as described in "Shipping Memories" below, and nothing takes prompts yet. A `config` file
55
+ is added to the project's config, and the project's own config files are applied after it, so
56
+ the project always wins. It MUST be `.json`, `.jsonc`, `.yaml` or
57
+ `.yml`, and every key outside `_aliases`, `_vars`, `compilation`, `plugins`, `recipes`,
58
+ `runtimeContext`, `store` and `varMappings` is dropped with a warning. Its `_vars` MUST NOT set
59
+ `projectRoot`, which sous sets itself (to the directory holding `.sous/`); setting it is an error. A recipe that only bundles others
60
+ may leave `contents` out.
61
+ - `plugin` and `requires` are described in "Shipping Sous Plugins" below.
67
62
  - `depends`, `subscribes` and `variables` are described below; `submissions` is in
68
63
  `about-sous-repos`.
69
64
 
@@ -163,14 +158,50 @@ Each entry names its target by where it lives:
163
158
  `local://` locators and `repo:` short names are refused: both are one project's private view of a
164
159
  repository, and a published manifest is read everywhere.
165
160
 
161
+ ## Shipping Sous Plugins
162
+
163
+ A recipe MAY ship a Sous plugin (code that extends sous itself, for example to add a Liquid
164
+ filter), and MAY install tool plugins (a plugin for a coding agent tool, such as a Claude Code
165
+ plugin).
166
+
167
+ A recipe's plugin is ONE self-contained bundled file, since sous never runs `npm install` for a
168
+ recipe; the same holds for every helper script a recipe ships. A `.d.ts` file beside it is
169
+ optional; sous copies it into the subscriber's `.sous/types/`, so other plugins in that project
170
+ get its types.
171
+
172
+ ```yaml
173
+ plugin:
174
+ bundle: plugin/index.js
175
+ types: plugin/index.d.ts
176
+ ```
177
+
178
+ Sous loads the plugin while it builds the subscriber's config, and only from a trusted
179
+ repository: nothing inside a repository runs before it is trusted. A recipe held only through
180
+ `depends` is a library and adds nothing to the subscriber, so its plugin NEVER loads.
181
+
182
+ A recipe can also require plugins from npm, each with a version range:
183
+
184
+ ```yaml
185
+ requires:
186
+ plugins:
187
+ sous-plugin-claude-code: "^1.0.0"
188
+ ```
189
+
190
+ `sous subscription add` refuses such a recipe while a required plugin is missing or outside its
191
+ version range. Run in a terminal, it offers to install the plugin; `--install-plugins` installs it
192
+ without asking. If a required plugin later goes missing, the build fails and names the plugin and
193
+ the command that installs it.
194
+
166
195
  ## Shipping Memories
167
196
 
168
197
  A memory is a fragment of an agent's always-loaded instructions. Publish one with a `contents`
169
198
  group of `kind: memories`, for example `include: [memories/**/*.md]`. A plain `.md` file is copied
170
199
  as it is; name a file `*.tpl.md` when it needs the subscriber's answers. The recipe never says where
171
- a memory lands: a subscribing project includes the memories of every recipe it holds directly with
172
- one line, `@#memories/**/*.md`, at the virtual path `#memories/<namespace>/<recipe>/<path>` (the path
173
- being relative to the pattern's static base). A recipe held only through `depends` is a library and
200
+ a memory lands. A subscribing project can include the memories of every recipe it holds directly
201
+ with one line, `@#memories/**/*.md`, at the virtual path `#memories/<namespace>/<recipe>/<path>`
202
+ (the path being relative to the pattern's static base). The Sous plugin for a coding agent may
203
+ also name the instruction file that agent reads (`CLAUDE.md` for Claude Code, for example), and
204
+ sous then adds the active recipes' memories to that file itself. A recipe held only through `depends` is a library and
174
205
  contributes none, and the subscriber's build warns about a published memory no output includes.
175
206
 
176
207
  ## Includes and Partials
@@ -11,7 +11,7 @@ formatVersion: 1
11
11
 
12
12
  namespace: core
13
13
  name: sous-skills
14
- version: 0.2.36
14
+ version: 1.0.1
15
15
 
16
16
  description: >-
17
17
  The skills that teach an agent what sous is and how it works: which files sous