@sous-io/sous 0.2.37 → 1.0.2

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 +1094 -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 -245
  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 -410
  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 -413
  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 -1107
  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
@@ -1,517 +0,0 @@
1
- /**
2
- * The files `sous repo init` writes, as plain string builders.
3
- *
4
- * These are deliberately not templates run through a template engine. A
5
- * scaffolded repository is read by a person before it is read by a machine, so
6
- * every file here is written to be explained: the comments are the point, and a
7
- * rendering step would only stand between the author of the scaffold and the
8
- * author of the new repository.
9
- *
10
- * Every builder returns a complete file, ending in a newline.
11
- */
12
-
13
- import {
14
- INDEX_FILENAME,
15
- RECIPE_MANIFEST_BASENAME,
16
- REPO_MANIFEST_BASENAME,
17
- } from "../formats/common.js";
18
- import { stringifyIndexFile, type IndexFile } from "../formats/index-file.js";
19
-
20
- /** What every builder needs to know about the repository being scaffolded. */
21
- export type ScaffoldContext = {
22
- /** The repository's short name, used as its suggested name and in the README. */
23
- name: string;
24
- /** The one namespace the scaffold declares. */
25
- namespace: string;
26
- /** The example recipe's name. */
27
- recipe: string;
28
- /** The version of sous doing the scaffolding, recorded in the index. */
29
- sousVersion: string;
30
- /** When the scaffold ran, recorded in the index. */
31
- generatedAt: string;
32
- };
33
-
34
- /** The path, relative to the repository root, of the example recipe's folder. */
35
- export function exampleRecipePath(context: ScaffoldContext): string {
36
- return `recipes/${context.namespace}/${context.recipe}`;
37
- }
38
-
39
- /**
40
- * The repo manifest at the root: what the repository publishes, and where each
41
- * recipe folder lives.
42
- *
43
- * @param context - The repository being scaffolded.
44
- */
45
- export function buildRepoManifest(context: ScaffoldContext): string {
46
- return `# The repo manifest: what this repository publishes.
47
- #
48
- # It is data, never code: sous reads it before anything is downloaded, so a
49
- # project can browse and validate what this repository publishes, and decide
50
- # whether to trust it, without executing anything.
51
-
52
- formatVersion: 1
53
-
54
- # A suggested short name. Each project chooses the name it actually uses when it
55
- # runs 'sous repo add', so two repositories suggesting the same name never clash.
56
- name: ${context.name}
57
-
58
- description: >-
59
- One paragraph saying what this repository publishes and who it is for.
60
-
61
- # Where to send a change. Shown to anyone whose provider cannot open a proposal
62
- # for them, so a contributor is never left without a route. Point it at this
63
- # repository's CONTRIBUTING.md once the repository has a public URL.
64
- # contribute: https://github.com/<owner>/${context.name}/blob/main/CONTRIBUTING.md
65
-
66
- # Namespaces group recipes. They are not versioned, and a project may subscribe
67
- # to a whole namespace, which means every recipe in it, including ones published
68
- # later.
69
- namespaces:
70
- ${context.namespace}:
71
- description: What the recipes in this namespace have in common.
72
-
73
- # Every recipe folder in this repository, as a path relative to this file. Each
74
- # folder holds one '${RECIPE_MANIFEST_BASENAME}.yaml'.
75
- recipes:
76
- - ${exampleRecipePath(context)}
77
- `;
78
- }
79
-
80
- /**
81
- * The example recipe manifest: one publishable unit, with the variables section
82
- * shown as commented-out example.
83
- *
84
- * @param context - The repository being scaffolded.
85
- */
86
- export function buildRecipeManifest(context: ScaffoldContext): string {
87
- return `# A recipe manifest: one publishable unit, with its own version.
88
- #
89
- # Copy this folder to start a new recipe, then add its path to the 'recipes'
90
- # list in the ${REPO_MANIFEST_BASENAME}.yaml at the root of this repository.
91
-
92
- formatVersion: 1
93
-
94
- namespace: ${context.namespace}
95
- name: ${context.recipe}
96
-
97
- # Recipe metadata is the source of truth for versions. 'sous repo release'
98
- # bumps this field and keeps the matching git tag consistent with it.
99
- version: 0.1.0
100
-
101
- description: >-
102
- One paragraph saying what this recipe gives a project that subscribes to it.
103
-
104
- # Build dependencies: fetched, pinned and addressable from this recipe's own
105
- # files, but their files do NOT enter a subscriber's output.
106
- # depends:
107
- # - core/shared-partials@^1.0.0
108
-
109
- # Co-subscriptions: subscribing to this recipe subscribes the project to these
110
- # as well, in full. Their questions run and their files DO enter the output.
111
- # subscribes:
112
- # - workflow/task-files
113
-
114
- # The files this recipe contributes, grouped by what they are. Paths are
115
- # relative to this folder.
116
- contents:
117
- - kind: skills
118
- include:
119
- - skills/**/*.md
120
-
121
- # Variables this recipe needs answered. A definition is a specification, never a
122
- # value: sous asks the question only when a subscribed recipe needs the variable
123
- # and no valid answer is already in scope.
124
- #
125
- # Every definition must carry a 'description' and an 'example'. The description
126
- # is the paragraph shown above the question and by 'sous vars show <name>'; it
127
- # says, in full sentences, what the setting is for, what the default does, and
128
- # what else is acceptable. The prompt is one plain question, nothing more. The
129
- # example is a realistic sample answer, shown with the question so nobody has to
130
- # guess what a good one looks like; it is documentation only and is never
131
- # stored, so use 'default' for a value a project should actually start with.
132
- #
133
- # variables:
134
- # - name: apiBaseUrl
135
- # type: url
136
- # prompt: Which API should this project talk to?
137
- # description: >-
138
- # Every request this recipe generates is sent to one deployment of the API,
139
- # and this setting says which one. The default points at the public
140
- # production host, but any deployment you can reach works, including a
141
- # staging host or a service running on your own machine.
142
- # example: https://api.example.com
143
- # default: https://api.example.com
144
- # required: true
145
- #
146
- # - name: serviceToken
147
- # type: string
148
- # # Name an environment variable explicitly to reuse a value the environment
149
- # # already carries. When omitted, 'sous repo release' derives one.
150
- # env: SERVICE_TOKEN
151
- # prompt: What is this project's service token?
152
- # description: >-
153
- # This recipe authenticates every call it makes with a service token, which
154
- # is issued per project and is not shared between them. Create one under
155
- # Settings, then Tokens, and give it read access to the project you are
156
- # configuring. There is no default; a token is always specific to you, and
157
- # it is stored in the gitignored env file so it never reaches git.
158
- # example: svc_0123456789abcdef0123
159
- # # A secret is always written to the gitignored '.sous/.env.local'.
160
- # secret: true
161
- # scope: local
162
- # validate:
163
- # minLength: 20
164
- `;
165
- }
166
-
167
- /**
168
- * The placeholder skill the example recipe contributes. It is named
169
- * `SKILL.tpl.md`, as every skill is, because it ends with the footer every
170
- * skill carries, and the footer's source path is only filled in by a render.
171
- *
172
- * @param context - The repository being scaffolded.
173
- */
174
- export function buildExampleSkill(context: ScaffoldContext): string {
175
- return `---
176
- name: example-skill
177
- description: >-
178
- Replace this with the sentence that tells an agent when to load the skill.
179
- Say what the skill covers and name the situations that should trigger it.
180
- ---
181
-
182
- # Example skill
183
-
184
- This file is a placeholder written by 'sous repo init'. Replace it with a real
185
- skill, or delete it once the ${context.recipe} recipe has content of its own.
186
-
187
- A skill is ordinary markdown. Everything under this recipe's 'contents' entry is
188
- compiled into a subscribing project's agent skill directory, so what you write
189
- here is what an agent reads there. The '.tpl.' in this file's name means it is
190
- rendered as a LiquidJS template on the way, and the name it is written under
191
- drops the '.tpl.'.
192
-
193
- ## What to put here
194
-
195
- Describe the concept the skill covers, then the rules an agent should follow
196
- when it applies. Keep it short enough to be read in full, and point at reference
197
- files for anything long.
198
-
199
- ## Source for this Skill
200
-
201
- This skill comes from the \`${context.namespace}/${context.recipe}\` recipe, installed by sous from a recipe
202
- repository. It was compiled from a template, so edit the source, never this output file.
203
-
204
- - Source Path: {{ sousTemplatePath }}
205
- `;
206
- }
207
-
208
- /**
209
- * The empty but valid index. `sous repo release` rewrites it; it exists from the
210
- * first commit so the repository is readable by sous before anything is
211
- * published.
212
- *
213
- * @param context - The repository being scaffolded.
214
- */
215
- export function buildIndexFile(context: ScaffoldContext): string {
216
- const index: IndexFile = {
217
- formatVersion: 1,
218
- name: context.name,
219
- generatedAt: context.generatedAt,
220
- generator: context.sousVersion,
221
- namespaces: {
222
- [context.namespace]: {
223
- description: "What the recipes in this namespace have in common.",
224
- },
225
- },
226
- recipes: {},
227
- };
228
- return stringifyIndexFile(index);
229
- }
230
-
231
- /**
232
- * The README, explaining the layout in plain language to whoever opens the
233
- * repository next.
234
- *
235
- * @param context - The repository being scaffolded.
236
- */
237
- export function buildReadme(context: ScaffoldContext): string {
238
- const recipeDir = exampleRecipePath(context);
239
- return `# ${context.name}
240
-
241
- A sous recipe repository. It publishes **recipes**, grouped into
242
- **namespaces**, that other projects subscribe to.
243
-
244
- ## Layout
245
-
246
- \`\`\`
247
- ${REPO_MANIFEST_BASENAME}.yaml what this repository publishes
248
- ${INDEX_FILENAME} the published catalog, written by sous
249
- ${recipeDir}/
250
- ${RECIPE_MANIFEST_BASENAME}.yaml one recipe: its version, contents and variables
251
- skills/ the files that recipe contributes
252
- \`\`\`
253
-
254
- ## The three files
255
-
256
- **\`${REPO_MANIFEST_BASENAME}.yaml\`** declares the namespaces this repository
257
- publishes and lists every recipe folder in it. It is hand-written, and it is the
258
- first thing sous reads.
259
-
260
- **\`${RECIPE_MANIFEST_BASENAME}.yaml\`** describes one recipe: which namespace it
261
- belongs to, what version it is at, what it depends on, which of its files a
262
- subscriber receives, and which variables it needs answered. It is hand-written
263
- too, and its \`version\` field is the source of truth for versions.
264
-
265
- **\`${INDEX_FILENAME}\`** is the catalog: every recipe, every published version,
266
- and a content hash for each one. It is written by \`sous repo release\` and
267
- committed. Do not edit it by hand.
268
-
269
- ## Adding a recipe
270
-
271
- 1. Copy \`${recipeDir}\` to a new folder under \`recipes/\`.
272
- 2. Edit its \`${RECIPE_MANIFEST_BASENAME}.yaml\`: set the namespace, the name, the
273
- version and the contents.
274
- 3. Add the new folder's path to the \`recipes\` list in
275
- \`${REPO_MANIFEST_BASENAME}.yaml\`.
276
- 4. Open a pull request. The workflow in \`.github/workflows/sous-release.yml\`
277
- checks that everything is consistent before it can be merged.
278
-
279
- ## Publishing
280
-
281
- Commit your recipe changes, then run \`sous repo release\`. It shows you what it
282
- would publish and asks once, then raises the version of every recipe whose files
283
- changed since the tag that last published it, regenerates \`${INDEX_FILENAME}\`,
284
- commits both, and cuts an annotated tag for each version. Add \`--push\` to push
285
- the commit and the tags, or push them yourself.
286
-
287
- Useful ways to narrow or steer it:
288
-
289
- \`\`\`bash
290
- sous repo release --dry-run # show the plan and stop
291
- sous repo release --namespace ${context.namespace} # only this namespace
292
- sous repo release --recipe ${context.namespace}/${context.recipe} # only this recipe
293
- sous repo release --bump minor # a minor step instead of a patch
294
- sous repo release --include-unchanged # release everything in scope anyway
295
- \`\`\`
296
-
297
- On a branch other than \`main\`, a release bumps and commits but cuts no tags:
298
- tags are cut on the default branch, by the workflow in
299
- \`.github/workflows/sous-release.yml\` after the merge. Pass \`--tag\` to cut them
300
- anyway. Tags are shaped \`namespace/recipe@version\`, and a version is published
301
- when its tag exists.
302
-
303
- To propose a change to a repository you do not maintain, commit it and run
304
- \`sous repo submit\`, which validates everything first and then opens a pull
305
- request through your provider's own command line tool.
306
-
307
- ## Contributing
308
-
309
- Improvements are welcome, including new recipes. Contribution instructions in this repository are
310
- written for agents: \`CONTRIBUTING.md\` says why, and \`CLAUDE.md\` is where an agent without the sous
311
- core skills starts.
312
-
313
- ## Using it
314
-
315
- In any project that has a sous config:
316
-
317
- \`\`\`bash
318
- sous repo add <the URL of this repository>
319
- sous subscribe ${context.namespace}/${context.recipe}
320
- sous build
321
- \`\`\`
322
-
323
- Adding a repository is what trusts it, so read a repository before you add it.
324
-
325
- ## Working on it
326
-
327
- \`sous repo link\` points a project at a working copy of this repository instead
328
- of at a published version, so you can edit a recipe and rebuild without
329
- releasing anything:
330
-
331
- \`\`\`bash
332
- sous repo link ${context.name} /path/to/this/checkout
333
- \`\`\`
334
-
335
- Builds say loudly when a repository is linked. Run \`sous repo unlink ${context.name}\`
336
- to go back to published versions.
337
-
338
- ## License
339
-
340
- This repository has no license yet. Until it has one, others may read it but not reuse it; add a
341
- \`LICENSE\` file before publishing.
342
- `;
343
- }
344
-
345
- /**
346
- * `CONTRIBUTING.md`: why this repository publishes no contribution
347
- * instructions for people, and where an agent starts instead. It is
348
- * `sous-io/sous-recipes`' own `CONTRIBUTING.md`, word for word apart from the
349
- * name, because that repository is the model every scaffold follows.
350
- *
351
- * @param context - The repository being scaffolded.
352
- */
353
- export function buildContributing(context: ScaffoldContext): string {
354
- return `# Contributing to ${context.name}
355
-
356
- Sous is built for agentic coding, so this repository does not publish contribution instructions for
357
- people. Everything here is written for agents to read.
358
-
359
- Any agent working in this repository is assumed to have, at minimum, the sous core skills, such as
360
- \`about-sous\`, \`about-agent-skills\`, \`about-sous-repos\` and \`about-sous-recipes\`. They explain
361
- everything an agent needs to know to contribute: how a recipe is written, how its version is raised,
362
- and how a change is checked, proposed and released.
363
-
364
- An agent without those skills starts at \`CLAUDE.md\`, at the root of this repository.
365
- `;
366
- }
367
-
368
- /** Where the sous core skills can be read online, at their latest published version. */
369
- const CORE_SKILLS_URL =
370
- "https://github.com/sous-io/sous-recipes/tree/main/recipes/core/sous-skills/skills";
371
-
372
- /** The official recipe repository every scaffold is modeled on. */
373
- const MODEL_REPOSITORY_URL = "https://github.com/sous-io/sous-recipes";
374
-
375
- /**
376
- * The root `CLAUDE.md`: the entry point for an agent working in the repository.
377
- * It points at the sous core skills rather than restating them, because they
378
- * are the source of truth for how a recipe repository works. It follows
379
- * `sous-io/sous-recipes`' own `CLAUDE.md`, minus what is only true there.
380
- *
381
- * @param context - The repository being scaffolded.
382
- */
383
- export function buildClaudeMd(context: ScaffoldContext): string {
384
- return `# ${context.name}
385
-
386
- This is a sous recipe repository. It publishes recipes: versioned bundles of agent skills, memories
387
- and partials that sous installs into the projects that subscribe to them.
388
-
389
- ## Recipe Repositories Are Part of Sous
390
-
391
- Writing a recipe, raising its version, checking a change, proposing it and releasing it all work
392
- here exactly as they do in any other sous recipe repository. How a recipe repository works is part
393
- of sous itself, so the sous core skills teach it, and they are the official source of truth for it.
394
- This file does not repeat them. The agent MUST read these before changing anything here:
395
-
396
- - \`about-sous-repos\`: a recipe repository as a whole; the repo manifest, namespaces, the index,
397
- release tags, what happens to a pull request and a merge, and proposing a change.
398
- - \`about-sous-recipes\`: one recipe; its manifest, how its version is raised, its variables, its
399
- contents, its dependencies and its partials.
400
- - \`about-agent-skills\`: how a skill is written, including the rules every new skill follows.
401
-
402
- An agent in a project that uses sous already has these skills. An agent that cannot install sous or
403
- use it reads them directly, as plain markdown files, online, at their latest published version:
404
-
405
- - ${CORE_SKILLS_URL}
406
-
407
- ## Where This Repository Came From
408
-
409
- \`sous repo init\` created this repository, modeled on \`sous-io/sous-recipes\`, the official recipe
410
- repository. Its files show a complete repository in use:
411
-
412
- - ${MODEL_REPOSITORY_URL}
413
- `;
414
- }
415
-
416
- /**
417
- * The root `AGENTS.md`: one line sending an agent that reads `AGENTS.md`
418
- * rather than `CLAUDE.md` to the same instructions.
419
- */
420
- export function buildAgentsMd(): string {
421
- return "Read `CLAUDE.md` in this directory; it holds the instructions for agents working in this\nrepository.\n";
422
- }
423
-
424
- /** The release workflow: validate every pull request, publish on merge. */
425
- export function buildReleaseWorkflow(): string {
426
- return `# Release automation for this sous recipe repository.
427
- #
428
- # Two jobs, both running the sous CLI straight from npm so nothing needs to be
429
- # installed into this repository:
430
- #
431
- # 'sous repo release --check' validates every manifest, confirms each recipe
432
- # folder matches what the repo manifest lists, and reports how merging would
433
- # rewrite the committed index, which the release after a merge regenerates.
434
- # It only reads; it never writes, commits or tags. That makes it the right
435
- # thing to run on a pull request.
436
- #
437
- # 'sous repo release --ci --push --yes' does the same validation and then
438
- # publishes. '--ci' raises no versions, accepts the plan it prints, and asks
439
- # no questions: the version bump belongs in the change being merged, so a
440
- # recipe that changed without one fails here rather than being given a version
441
- # nobody reviewed. It cuts an annotated tag for every version that does not
442
- # have one yet, dependency-first, and '--push' pushes the commit and those
443
- # tags. '--ci' implies '--yes'; passing it as well keeps this workflow working
444
- # with a sous old enough that it did not.
445
-
446
- name: sous release
447
-
448
- on:
449
- pull_request:
450
- push:
451
- branches:
452
- - main
453
-
454
- jobs:
455
- check:
456
- name: Validate recipes
457
- if: github.event_name == 'pull_request'
458
- runs-on: ubuntu-latest
459
- steps:
460
- - uses: actions/checkout@v4
461
- with:
462
- # The whole history, so the tags a version is checked against are
463
- # visible.
464
- fetch-depth: 0
465
- - uses: actions/setup-node@v4
466
- with:
467
- node-version: 22
468
- - name: Validate every manifest, the index and the tags
469
- run: npx --yes @sous-io/sous repo release --check
470
-
471
- release:
472
- name: Publish recipes
473
- if: github.event_name == 'push'
474
- runs-on: ubuntu-latest
475
- permissions:
476
- # Needed to push the release commit and the new tags.
477
- contents: write
478
- steps:
479
- - uses: actions/checkout@v4
480
- with:
481
- # The whole history, so existing tags are visible and versions that
482
- # were already published are not cut a second time.
483
- fetch-depth: 0
484
- - uses: actions/setup-node@v4
485
- with:
486
- node-version: 22
487
- - name: Identify the committer, in case the index has to be rewritten
488
- run: |
489
- git config user.name "github-actions[bot]"
490
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
491
- - name: Publish every new version
492
- run: npx --yes @sous-io/sous repo release --ci --push --yes
493
- `;
494
- }
495
-
496
- /**
497
- * The repository's `.gitignore`. A recipe repository holds text, so this stays
498
- * short: editor and operating system leftovers, and the machine-local files
499
- * sous writes when the repository is linked into a project.
500
- */
501
- export function buildGitignore(): string {
502
- return `# Operating system and editor leftovers
503
- .DS_Store
504
- Thumbs.db
505
- *.swp
506
-
507
- # Dependencies, if a recipe ever needs any
508
- node_modules/
509
-
510
- # Machine-local sous files, written when this repository is used from a project
511
- .sous/sous.state.json
512
- .sous/sous.pid
513
- .sous/sous.links.json
514
- .sous/repos/
515
- .sous/.env.local
516
- `;
517
- }