@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.
- package/README.md +14 -256
- package/dist/bin.js +11 -0
- package/dist/sous.js +1094 -0
- package/docs/markdown/README.md +5 -4
- package/docs/markdown/_sidebar.md +21 -1
- package/docs/markdown/commands.md +294 -431
- package/docs/markdown/config-discovery.md +25 -14
- package/docs/markdown/config-inspection.md +53 -31
- package/docs/markdown/config-layers.md +168 -66
- package/docs/markdown/config-variables.md +44 -11
- package/docs/markdown/configuration.md +104 -17
- package/docs/markdown/design-principles.md +4 -1
- package/docs/markdown/repositories-authoring.md +30 -0
- package/docs/markdown/repositories-consuming.md +72 -14
- package/docs/markdown/repositories-file-formats.md +31 -13
- package/docs/markdown/repositories-providers.md +48 -57
- package/docs/markdown/repositories-quickstart.md +3 -2
- package/docs/markdown/repositories-troubleshooting.md +27 -1
- package/docs/markdown/repositories-variables.md +6 -1
- package/docs/markdown/repositories.md +18 -8
- package/package.json +48 -107
- package/recipes/core/sous-skills/skills/about-liquid-templates/SKILL.tpl.md +4 -6
- package/recipes/core/sous-skills/skills/about-liquid-templates/references/liquid-filters.tpl.md +2 -0
- package/recipes/core/sous-skills/skills/about-sous/SKILL.tpl.md +10 -9
- package/recipes/core/sous-skills/skills/about-sous-configuration/SKILL.tpl.md +35 -14
- package/recipes/core/sous-skills/skills/about-sous-recipes/SKILL.tpl.md +51 -20
- package/recipes/core/sous-skills/sous.recipe.yaml +1 -1
- package/sous.config.schema.json +351 -132
- package/bin/run.js +0 -51
- package/src/base-command.ts +0 -457
- package/src/commands/build.ts +0 -181
- package/src/commands/clear.ts +0 -79
- package/src/commands/compile.ts +0 -155
- package/src/commands/config/get.ts +0 -110
- package/src/commands/config/show.ts +0 -32
- package/src/commands/config/validate.ts +0 -53
- package/src/commands/help.ts +0 -46
- package/src/commands/init.ts +0 -289
- package/src/commands/launch.ts +0 -139
- package/src/commands/lock/rebuild.ts +0 -239
- package/src/commands/lock/show.ts +0 -115
- package/src/commands/namespace/list.ts +0 -138
- package/src/commands/namespace/show.ts +0 -130
- package/src/commands/prune.ts +0 -43
- package/src/commands/recipe/list.ts +0 -112
- package/src/commands/recipe/show.ts +0 -439
- package/src/commands/repo/add.ts +0 -145
- package/src/commands/repo/contribute.ts +0 -604
- package/src/commands/repo/gc.ts +0 -173
- package/src/commands/repo/init.ts +0 -136
- package/src/commands/repo/link.ts +0 -899
- package/src/commands/repo/list.ts +0 -236
- package/src/commands/repo/release.ts +0 -685
- package/src/commands/repo/remove.ts +0 -194
- package/src/commands/repo/search.ts +0 -243
- package/src/commands/repo/submit.ts +0 -341
- package/src/commands/repo/unlink.ts +0 -461
- package/src/commands/subscription/add.ts +0 -286
- package/src/commands/subscription/list.ts +0 -208
- package/src/commands/subscription/remove.ts +0 -182
- package/src/commands/subscription/update.ts +0 -216
- package/src/commands/update.ts +0 -178
- package/src/commands/vars/ask.ts +0 -417
- package/src/commands/vars/index.ts +0 -79
- package/src/commands/vars/list.ts +0 -67
- package/src/commands/vars/show.ts +0 -77
- package/src/config-command.ts +0 -30
- package/src/lib/build-preparation.ts +0 -128
- package/src/lib/build-service.ts +0 -580
- package/src/lib/config-discovery.ts +0 -378
- package/src/lib/config-inspect.ts +0 -145
- package/src/lib/config-kernel.mjs +0 -379
- package/src/lib/config-schema.ts +0 -401
- package/src/lib/env-file.ts +0 -328
- package/src/lib/env-local.ts +0 -212
- package/src/lib/errors.ts +0 -32
- package/src/lib/glob-pattern.ts +0 -24
- package/src/lib/include-resolver.ts +0 -523
- package/src/lib/interactive.ts +0 -165
- package/src/lib/markdown-compiler.ts +0 -947
- package/src/lib/package-info.ts +0 -25
- package/src/lib/pid-service.ts +0 -99
- package/src/lib/project-install.d.mts +0 -44
- package/src/lib/project-install.mjs +0 -234
- package/src/lib/project-scaffold/index.ts +0 -332
- package/src/lib/project-scaffold/templates.ts +0 -240
- package/src/lib/repos/catalog-display.ts +0 -215
- package/src/lib/repos/catalog-inputs.ts +0 -288
- package/src/lib/repos/catalog.ts +0 -842
- package/src/lib/repos/contribute.ts +0 -452
- package/src/lib/repos/core-recipe.ts +0 -105
- package/src/lib/repos/declarations.ts +0 -187
- package/src/lib/repos/defaults.ts +0 -175
- package/src/lib/repos/formats/common.ts +0 -440
- package/src/lib/repos/formats/index-file.ts +0 -253
- package/src/lib/repos/formats/links-map.ts +0 -98
- package/src/lib/repos/formats/lockfile.ts +0 -169
- package/src/lib/repos/formats/patterns.ts +0 -57
- package/src/lib/repos/formats/recipe-manifest.ts +0 -205
- package/src/lib/repos/formats/repo-manifest.ts +0 -97
- package/src/lib/repos/formats/store-entry.ts +0 -84
- package/src/lib/repos/formats/variable-definition.ts +0 -268
- package/src/lib/repos/freshness.ts +0 -264
- package/src/lib/repos/git-clone.ts +0 -850
- package/src/lib/repos/identity.ts +0 -89
- package/src/lib/repos/index.ts +0 -57
- package/src/lib/repos/links.ts +0 -356
- package/src/lib/repos/load-manifest.ts +0 -237
- package/src/lib/repos/lock-service.ts +0 -454
- package/src/lib/repos/locked-namespace-resolver.ts +0 -232
- package/src/lib/repos/locked-recipe-lookup.ts +0 -123
- package/src/lib/repos/locked-recipes.ts +0 -254
- package/src/lib/repos/managed-layer.ts +0 -422
- package/src/lib/repos/memories-hash-name.ts +0 -33
- package/src/lib/repos/namespace-resolver.ts +0 -527
- package/src/lib/repos/providers/base.ts +0 -268
- package/src/lib/repos/providers/git.ts +0 -245
- package/src/lib/repos/providers/github.ts +0 -589
- package/src/lib/repos/providers/gitlab.ts +0 -332
- package/src/lib/repos/providers/http.ts +0 -128
- package/src/lib/repos/providers/index-cache.ts +0 -421
- package/src/lib/repos/providers/index.ts +0 -106
- package/src/lib/repos/providers/local.ts +0 -410
- package/src/lib/repos/providers/provider.ts +0 -615
- package/src/lib/repos/recipe-config-layers.ts +0 -316
- package/src/lib/repos/recipe-key-matcher.ts +0 -62
- package/src/lib/repos/recipe-memories.ts +0 -178
- package/src/lib/repos/recipe-targets.ts +0 -236
- package/src/lib/repos/ref-search.ts +0 -46
- package/src/lib/repos/release/bump.ts +0 -161
- package/src/lib/repos/release/changelog.ts +0 -461
- package/src/lib/repos/release/git-state.ts +0 -460
- package/src/lib/repos/release/index-builder.ts +0 -1108
- package/src/lib/repos/release/index.ts +0 -19
- package/src/lib/repos/release/plan.ts +0 -521
- package/src/lib/repos/release/settle.ts +0 -154
- package/src/lib/repos/release/submissions.ts +0 -214
- package/src/lib/repos/release/submit-checkout.ts +0 -290
- package/src/lib/repos/release/submit-questions.ts +0 -153
- package/src/lib/repos/release/submit-service.ts +0 -898
- package/src/lib/repos/release/tags.ts +0 -239
- package/src/lib/repos/release/validate.ts +0 -463
- package/src/lib/repos/resolver.ts +0 -1028
- package/src/lib/repos/scaffold/index.ts +0 -245
- package/src/lib/repos/scaffold/templates.ts +0 -517
- package/src/lib/repos/seed.ts +0 -473
- package/src/lib/repos/store/contract.ts +0 -64
- package/src/lib/repos/store/hash.ts +0 -191
- package/src/lib/repos/store/recipe-store.ts +0 -599
- package/src/lib/repos/store/settings.ts +0 -58
- package/src/lib/repos/subscription-service.ts +0 -3859
- package/src/lib/repos/trust.ts +0 -447
- package/src/lib/repos/update-plan.ts +0 -235
- package/src/lib/self-update/index.ts +0 -14
- package/src/lib/self-update/installs.ts +0 -413
- package/src/lib/self-update/managers.ts +0 -126
- package/src/lib/self-update/plan.ts +0 -315
- package/src/lib/self-update/registry.ts +0 -99
- package/src/lib/self-update/run.ts +0 -506
- package/src/lib/self-update/versions.ts +0 -243
- package/src/lib/settings.ts +0 -1107
- package/src/lib/sous-home.ts +0 -104
- package/src/lib/state.ts +0 -167
- package/src/lib/vars/answers.ts +0 -192
- package/src/lib/vars/ask.ts +0 -1152
- package/src/lib/vars/definition-source.ts +0 -261
- package/src/lib/vars/display.ts +0 -231
- package/src/lib/vars/index.ts +0 -20
- package/src/lib/vars/ladder.ts +0 -282
- package/src/lib/vars/mappings.ts +0 -260
- package/src/lib/vars/names.ts +0 -94
- package/src/lib/vars/preanswers.ts +0 -395
- package/src/lib/vars/question-plan.ts +0 -241
- package/src/lib/vars/report.ts +0 -228
- package/src/lib/vars/safe-regex.ts +0 -235
- package/src/lib/vars/secrets.ts +0 -131
- package/src/lib/vars/validate.ts +0 -312
- package/src/lib/version-report.ts +0 -90
- package/src/lib/watch-loop.ts +0 -148
- package/src/lib/watch-service.ts +0 -116
- package/src/services/ref-resolver/container.ts +0 -107
- package/src/services/ref-resolver/dependency.ts +0 -60
- package/src/services/ref-resolver/format.ts +0 -197
- package/src/services/ref-resolver/glob.ts +0 -115
- package/src/services/ref-resolver/hash-names.ts +0 -155
- package/src/services/ref-resolver/index.ts +0 -55
- package/src/services/ref-resolver/injectable.ts +0 -36
- package/src/services/ref-resolver/location.ts +0 -62
- package/src/services/ref-resolver/lookups/cached-index-lookup.ts +0 -53
- package/src/services/ref-resolver/lookups/catalog-lookup.ts +0 -23
- package/src/services/ref-resolver/lookups/catalog-matcher.ts +0 -261
- package/src/services/ref-resolver/lookups/chained-lookup.ts +0 -27
- package/src/services/ref-resolver/lookups/env-var-lookup.ts +0 -65
- package/src/services/ref-resolver/lookups/fetched-index-lookup.ts +0 -150
- package/src/services/ref-resolver/lookups/recorded-dependency-lookup.ts +0 -62
- package/src/services/ref-resolver/lookups/ref-lookup.ts +0 -54
- package/src/services/ref-resolver/lookups/variable-lookup.ts +0 -123
- package/src/services/ref-resolver/named-refs.ts +0 -144
- package/src/services/ref-resolver/parser/env-var-splitter.ts +0 -27
- package/src/services/ref-resolver/parser/location-splitter.ts +0 -239
- package/src/services/ref-resolver/parser/name-path-splitter.ts +0 -200
- package/src/services/ref-resolver/parser/partial-ref.ts +0 -84
- package/src/services/ref-resolver/parser/query-splitter.ts +0 -61
- package/src/services/ref-resolver/parser/range-splitter.ts +0 -52
- package/src/services/ref-resolver/parser/ref-parser.ts +0 -115
- package/src/services/ref-resolver/parser/repo-qualifier-splitter.ts +0 -51
- package/src/services/ref-resolver/parts.ts +0 -115
- package/src/services/ref-resolver/pruners/command-line-pruner.ts +0 -47
- package/src/services/ref-resolver/pruners/include-pruner.ts +0 -66
- package/src/services/ref-resolver/pruners/manifest-pruner.ts +0 -130
- package/src/services/ref-resolver/pruners/ref-pruner.ts +0 -135
- package/src/services/ref-resolver/pruners/rule-helpers.ts +0 -44
- package/src/services/ref-resolver/pruners/stored-key-pruner.ts +0 -136
- package/src/services/ref-resolver/ref-helpers.ts +0 -62
- package/src/services/ref-resolver/ref-picker-service.ts +0 -204
- package/src/services/ref-resolver/ref-report.ts +0 -84
- package/src/services/ref-resolver/ref-resolve-arguments.ts +0 -47
- package/src/services/ref-resolver/ref-resolve-result.ts +0 -36
- package/src/services/ref-resolver/ref-resolver-service.ts +0 -323
- package/src/services/ref-resolver/source.ts +0 -48
- package/src/services/ref-resolver/tokens.ts +0 -25
- package/src/services/ref-resolver/types.ts +0 -155
- package/src/templating/filters/bullet-list.ts +0 -9
- package/src/templating/filters/index.ts +0 -8
- package/src/templating/init-liquid-engine.ts +0 -139
- package/src/templating/lib/glob-files.ts +0 -74
- package/src/templating/lib/import-export.ts +0 -32
- package/src/templating/lib/secret-scope.ts +0 -41
- package/src/templating/lib/tag-args.ts +0 -19
- package/src/templating/tags/exportScalarVarsJs.ts +0 -46
- package/src/templating/tags/getFiles.ts +0 -89
- package/src/templating/tags/index.ts +0 -14
- package/src/templating/tags/listFiles.ts +0 -54
- package/src/templating/tags/showVars.ts +0 -28
- package/src/utils/choice-prompt.ts +0 -143
- package/src/utils/command-errors.ts +0 -186
- package/src/utils/command-help.ts +0 -45
- package/src/utils/confirm-prompt.ts +0 -110
- package/src/utils/flags.ts +0 -177
- package/src/utils/formatting.ts +0 -849
- package/src/utils/prompts.ts +0 -53
- package/src/utils/sous-directory.ts +0 -245
- package/src/utils/table.ts +0 -603
- 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
|
-
}
|