valise-sh 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/CHANGELOG.md +152 -2
  2. package/README.md +99 -146
  3. package/bin/valise +57 -5376
  4. package/docs/architecture.md +77 -121
  5. package/docs/contrib-modules.md +172 -218
  6. package/docs/installation.md +137 -83
  7. package/docs/module-abi.md +125 -126
  8. package/docs/projects.md +249 -0
  9. package/docs/release-policy.md +68 -93
  10. package/docs/shared-modules.md +40 -39
  11. package/examples/README.md +12 -11
  12. package/examples/e2e/README.md +59 -66
  13. package/examples/e2e/bundles.tsv +6 -0
  14. package/examples/e2e/module.d/e2e_aliases.meta +1 -2
  15. package/examples/e2e/module.d/e2e_completions_bash.meta +0 -1
  16. package/examples/e2e/module.d/e2e_completions_zsh.meta +0 -1
  17. package/examples/e2e/module.d/e2e_env_setup.meta +2 -3
  18. package/examples/e2e/module.d/e2e_fish_features.meta +0 -1
  19. package/examples/e2e/module.d/e2e_generated_config.meta +1 -2
  20. package/examples/e2e/module.d/e2e_ksh_features.meta +0 -1
  21. package/examples/e2e/module.d/e2e_layer_probe.meta +1 -2
  22. package/examples/e2e/module.d/e2e_optional_network.meta +1 -2
  23. package/examples/e2e/module.d/e2e_platform_tools.meta +8 -0
  24. package/examples/e2e/module.d/e2e_platform_tools_bsd.meta +2 -3
  25. package/examples/e2e/module.d/e2e_platform_tools_darwin.meta +2 -3
  26. package/examples/e2e/module.d/e2e_platform_tools_linux.meta +2 -3
  27. package/examples/e2e/valise.conf +4 -0
  28. package/examples/e2e/variants.tsv +3 -0
  29. package/examples/local/module.d/hello_valise.meta +1 -2
  30. package/examples/profile-project/README.md +78 -108
  31. package/examples/profile-project/bundles.tsv +8 -0
  32. package/examples/profile-project/{shell/layers → layers}/demo/module.d/contrib_demo_greeting.meta +1 -2
  33. package/examples/profile-project/{shell/module.d → module.d}/greeting.meta +1 -2
  34. package/examples/profile-project/{shell/module.d → module.d}/profile_main.meta +0 -1
  35. package/examples/profile-project/{shell/modules → modules}/greeting.sh +1 -1
  36. package/examples/profile-project/valise.conf +4 -0
  37. package/examples/profile-project/variants.tsv +3 -0
  38. package/examples/shared/README.md +13 -34
  39. package/examples/shared/module.d/contrib_shared_paths.meta +2 -3
  40. package/examples/shared/module.d/contrib_shared_umask.meta +1 -2
  41. package/examples/shared/modules/shared/contrib_shared_paths.sh +2 -2
  42. package/lib/capabilities.sh +40 -13
  43. package/lib/cli/commands.sh +278 -0
  44. package/lib/cli/common.sh +326 -0
  45. package/lib/cli/devtools.sh +539 -0
  46. package/lib/cli/fish-hook.sh +986 -0
  47. package/lib/cli/integration.sh +337 -0
  48. package/lib/cli/lifecycle.sh +578 -0
  49. package/lib/cli/project.sh +1807 -0
  50. package/lib/cli/store.sh +1023 -0
  51. package/lib/cli/usage.sh +308 -0
  52. package/lib/compiler.awk +11 -4
  53. package/lib/fish/loader.fish +69 -9
  54. package/lib/fish/metadata.fish +49 -5
  55. package/lib/fish/profile.fish +170 -0
  56. package/lib/loader.sh +6 -8
  57. package/lib/metadata.sh +111 -5
  58. package/manifests/parser-support.tsv +2 -2
  59. package/module.d/valise_editor.meta +9 -0
  60. package/module.d/valise_history.meta +9 -0
  61. package/module.d/valise_pager.meta +9 -0
  62. package/module.d/valise_path.meta +9 -0
  63. package/module.d/{platform_bsd.meta → valise_platform_bsd.meta} +3 -4
  64. package/module.d/{platform_linux.meta → valise_platform_linux.meta} +3 -4
  65. package/module.d/{platform_macos.meta → valise_platform_macos.meta} +3 -4
  66. package/module.d/{platform_posix.meta → valise_platform_posix.meta} +2 -3
  67. package/module.d/valise_xdg.meta +9 -0
  68. package/modules/system/{contrib_editor.sh → valise_editor.sh} +2 -2
  69. package/modules/system/{contrib_history.sh → valise_history.sh} +2 -2
  70. package/modules/system/{contrib_pager.sh → valise_pager.sh} +2 -2
  71. package/modules/system/{contrib_path.sh → valise_path.sh} +3 -3
  72. package/modules/system/{contrib_xdg.sh → valise_xdg.sh} +2 -2
  73. package/package.json +91 -10
  74. package/docs/variants.md +0 -327
  75. package/entrypoints/.gitkeep +0 -0
  76. package/entrypoints/fish/profile.fish +0 -99
  77. package/examples/e2e/build-manifest.sh +0 -138
  78. package/examples/local/.gitkeep +0 -0
  79. package/examples/profile-project/shell/release/bundle-roots +0 -9
  80. package/examples/profile-project/shell/release/install-variants +0 -3
  81. package/examples/profile-project/shell/release/module-registry.tsv +0 -4
  82. package/examples/profile-project/shell/release/project.conf +0 -3
  83. package/lib/.gitkeep +0 -0
  84. package/manifests/.gitkeep +0 -0
  85. package/module.d/.gitkeep +0 -0
  86. package/module.d/contrib_editor.meta +0 -10
  87. package/module.d/contrib_history.meta +0 -10
  88. package/module.d/contrib_pager.meta +0 -10
  89. package/module.d/contrib_path.meta +0 -10
  90. package/module.d/contrib_xdg.meta +0 -10
  91. package/modules/.gitkeep +0 -0
  92. /package/examples/profile-project/{shell/layers → layers}/demo/modules/shared/contrib_demo_greeting.sh +0 -0
package/package.json CHANGED
@@ -1,20 +1,101 @@
1
1
  {
2
2
  "name": "valise-sh",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Pure POSIX shell profile engine and CLI",
5
5
  "bin": {
6
6
  "valise": "./bin/valise"
7
7
  },
8
8
  "files": [
9
- "bin/",
10
- "lib/",
11
- "modules/",
12
- "entrypoints/",
13
- "module.d/",
14
- "manifests/",
15
- "docs/",
16
- "examples/",
17
- "!examples/**/build/",
9
+ "bin/valise",
10
+ "docs/architecture.md",
11
+ "docs/contrib-modules.md",
12
+ "docs/installation.md",
13
+ "docs/module-abi.md",
14
+ "docs/projects.md",
15
+ "docs/release-policy.md",
16
+ "docs/shared-modules.md",
17
+ "entrypoints/profile.sh",
18
+ "examples/README.md",
19
+ "examples/e2e/README.md",
20
+ "examples/e2e/bundles.tsv",
21
+ "examples/e2e/module.d/e2e_aliases.meta",
22
+ "examples/e2e/module.d/e2e_completions_bash.meta",
23
+ "examples/e2e/module.d/e2e_completions_zsh.meta",
24
+ "examples/e2e/module.d/e2e_env_setup.meta",
25
+ "examples/e2e/module.d/e2e_fish_features.meta",
26
+ "examples/e2e/module.d/e2e_generated_config.meta",
27
+ "examples/e2e/module.d/e2e_ksh_features.meta",
28
+ "examples/e2e/module.d/e2e_layer_probe.meta",
29
+ "examples/e2e/module.d/e2e_optional_network.meta",
30
+ "examples/e2e/module.d/e2e_platform_tools.meta",
31
+ "examples/e2e/module.d/e2e_platform_tools_bsd.meta",
32
+ "examples/e2e/module.d/e2e_platform_tools_darwin.meta",
33
+ "examples/e2e/module.d/e2e_platform_tools_linux.meta",
34
+ "examples/e2e/modules/e2e/aliases.sh",
35
+ "examples/e2e/modules/e2e/completions_bash.sh",
36
+ "examples/e2e/modules/e2e/completions_zsh.sh",
37
+ "examples/e2e/modules/e2e/env_setup.sh",
38
+ "examples/e2e/modules/e2e/fish_features.fish",
39
+ "examples/e2e/modules/e2e/generated_config.sh",
40
+ "examples/e2e/modules/e2e/ksh_features.sh",
41
+ "examples/e2e/modules/e2e/layer_probe.sh",
42
+ "examples/e2e/modules/e2e/optional_network.sh",
43
+ "examples/e2e/modules/e2e/platform_tools_bsd.sh",
44
+ "examples/e2e/modules/e2e/platform_tools_darwin.sh",
45
+ "examples/e2e/modules/e2e/platform_tools_linux.sh",
46
+ "examples/e2e/valise.conf",
47
+ "examples/e2e/variants.tsv",
48
+ "examples/local/module.d/hello_valise.meta",
49
+ "examples/local/modules/hello_valise.sh",
50
+ "examples/profile-project/README.md",
51
+ "examples/profile-project/bundles.tsv",
52
+ "examples/profile-project/layers/demo/module.d/contrib_demo_greeting.meta",
53
+ "examples/profile-project/layers/demo/modules/shared/contrib_demo_greeting.sh",
54
+ "examples/profile-project/module.d/greeting.meta",
55
+ "examples/profile-project/module.d/profile_main.meta",
56
+ "examples/profile-project/modules/greeting.sh",
57
+ "examples/profile-project/valise.conf",
58
+ "examples/profile-project/variants.tsv",
59
+ "examples/shared/README.md",
60
+ "examples/shared/module.d/contrib_shared_paths.meta",
61
+ "examples/shared/module.d/contrib_shared_umask.meta",
62
+ "examples/shared/modules/shared/contrib_shared_paths.sh",
63
+ "examples/shared/modules/shared/contrib_shared_umask.sh",
64
+ "lib/capabilities.sh",
65
+ "lib/cli/commands.sh",
66
+ "lib/cli/common.sh",
67
+ "lib/cli/devtools.sh",
68
+ "lib/cli/fish-hook.sh",
69
+ "lib/cli/integration.sh",
70
+ "lib/cli/lifecycle.sh",
71
+ "lib/cli/project.sh",
72
+ "lib/cli/store.sh",
73
+ "lib/cli/usage.sh",
74
+ "lib/compiler.awk",
75
+ "lib/fish/loader.fish",
76
+ "lib/fish/metadata.fish",
77
+ "lib/fish/profile.fish",
78
+ "lib/loader.sh",
79
+ "lib/metadata.sh",
80
+ "manifests/parser-support.tsv",
81
+ "module.d/valise_editor.meta",
82
+ "module.d/valise_history.meta",
83
+ "module.d/valise_pager.meta",
84
+ "module.d/valise_path.meta",
85
+ "module.d/valise_platform_bsd.meta",
86
+ "module.d/valise_platform_linux.meta",
87
+ "module.d/valise_platform_macos.meta",
88
+ "module.d/valise_platform_posix.meta",
89
+ "module.d/valise_xdg.meta",
90
+ "modules/platform/bsd/capabilities.sh",
91
+ "modules/platform/linux/capabilities.sh",
92
+ "modules/platform/macos/capabilities.sh",
93
+ "modules/platform/posix.sh",
94
+ "modules/system/valise_editor.sh",
95
+ "modules/system/valise_history.sh",
96
+ "modules/system/valise_pager.sh",
97
+ "modules/system/valise_path.sh",
98
+ "modules/system/valise_xdg.sh",
18
99
  "LICENSE",
19
100
  "CHANGELOG.md"
20
101
  ],
package/docs/variants.md DELETED
@@ -1,327 +0,0 @@
1
- # The compile and build contract
2
-
3
- This document describes how a consuming project turns metadata into an
4
- installed release: what each input file contains, what `valise compile`
5
- produces, what `valise build` packages, and how the two fail.
6
-
7
- Two different mechanisms share the word "variant". They compose, but they are
8
- not the same command.
9
-
10
- - **Build variants** are exclusion lists decided at compile time inside the
11
- consuming project. They live in `shell/release/install-variants`.
12
- - **Installed releases** are sealed directories on this machine. They are
13
- listed, switched, and pruned with `valise release list|use|prune`.
14
-
15
- Neither reads the other's file. `release use` never reads `install-variants`;
16
- variant exclusion is decided when the plans are compiled.
17
-
18
- ## The project layout
19
-
20
- A consuming project that uses the CLI has this shape:
21
-
22
- ```
23
- shell/
24
- module.d/ primary modules: <name>.meta
25
- modules/ primary module bodies
26
- layers/<provider>/ provider layers (optional)
27
- module.d/ layer modules: <name>.meta
28
- modules/ layer module bodies
29
- release/
30
- bundle-roots which modules seed each bundle, per shell
31
- install-variants build variants and their exclusion lists
32
- module-registry.tsv GENERATED from the metadata above
33
- project.conf project defaults (optional)
34
- ```
35
-
36
- `shell/module.d/` and `shell/release/module-registry.tsv` are the two markers
37
- that identify a directory as a valise project. A layer's `<provider>` is a
38
- path component made of letters, digits, `_`, `-`, and `.`; it may not start
39
- with `.` or contain `..`. The registry rejects any other provider name,
40
- because the compiler emits module identities from it as shell source text. The CLI resolves the project
41
- root from the working directory first, then from the engine's own location, so
42
- running `valise compile` from the project root always compiles *that* project
43
- rather than a tree that merely happens to contain the engine.
44
-
45
- ## Metadata is the source of truth
46
-
47
- Module metadata is data: `key=value` lines in a `.meta` file, parsed and
48
- validated, never sourced. See [module-abi.md](module-abi.md) for the full
49
- field list and the grammar each value must satisfy.
50
-
51
- The registry is a **generated artifact**, not a second source of truth. The
52
- generator is `valise registry`:
53
-
54
- ```sh
55
- valise registry # write shell/release/module-registry.tsv
56
- valise registry --check # compare, fail on drift, write nothing
57
- valise registry path/to/registry.tsv # write somewhere else
58
- ```
59
-
60
- `valise build` regenerates the registry before it builds, so a project
61
- that only has `.meta` files and bodies builds with no hand-written TSV. The
62
- generator refuses to publish a registry when the metadata is inconsistent:
63
- a `name` that does not match its filename, a missing body, a layer module
64
- without the `contrib_` prefix, a load path that is not representable, or an
65
- export name that is not a shell identifier.
66
-
67
- The registry is a tab-separated file with one header row and one row per
68
- module:
69
-
70
- | # | Column | Meaning |
71
- |---|---|---|
72
- | 1 | `name` | Module identifier. |
73
- | 2 | `version` | Optional version string; empty means unversioned. |
74
- | 3 | `side_effect` | Startup side-effect class. |
75
- | 4 | `requires` | Space-separated required dependencies. |
76
- | 5 | `optional` | Space-separated optional dependencies. |
77
- | 6 | `shells` | Space-separated shell identifiers. |
78
- | 7 | `platforms` | Space-separated platform identifiers. |
79
- | 8 | `exports` | Space-separated exported identifiers. |
80
- | 9 | `load` | Repository-relative body path, or empty for a meta module. |
81
- | 10 | `updates` | Space-separated update registration identifiers. |
82
- | 11 | `source` | Directory that holds the `.meta`: `shell/module.d` or `shell/layers/<provider>/module.d`. |
83
-
84
- Rows come out in a fixed order: the primary modules of `shell/module.d/`
85
- first, then the layer modules of each `shell/layers/<provider>/module.d/`,
86
- each group in C-locale name order. The order does not depend on the caller's
87
- locale, so regenerating an unchanged project produces a byte-identical file.
88
-
89
- ## Bundles: which modules seed each shell
90
-
91
- A bundle names the root modules for each shell. The file is
92
- `shell/release/bundle-roots`, tab-separated:
93
-
94
- ```
95
- # bundle shell roots
96
- default bash profile_main
97
- default zsh profile_main
98
- default ksh profile_main
99
- ```
100
-
101
- - Column 1 is the bundle name.
102
- - Column 2 is the shell the roots apply to.
103
- - Column 3 is a space-separated list of root module names.
104
-
105
- A root may be a bare name (`profile_main`), which resolves against
106
- `shell/module.d/`, or a qualified name (`contrib_tool@shell/layers/vendor/module.d`)
107
- that names its source directory explicitly. Use the qualified form when a
108
- layer module and a primary module share a name.
109
-
110
- The first row may be a header (`bundle`, `shell`, `roots`); it is not a bundle
111
- definition.
112
-
113
- A bundle names the **starting points**, not the final set. `valise compile`
114
- walks each root's `requires` and `optional` edges, so the installed plan
115
- contains the whole reachable closure. `valise explain-bundles` prints that
116
- closure per shell, which is the fastest way to see what a bundle actually
117
- loads:
118
-
119
- ```sh
120
- valise explain-bundles
121
- valise explain-bundles --bundle=default
122
- ```
123
-
124
- It reads `bundle-roots` and the registry directly, and needs no Python. An
125
- unknown `--bundle` name is an error, not an empty report.
126
-
127
- ## Variants: what to leave out
128
-
129
- A build variant is an exclusion list. The file is
130
- `shell/release/install-variants`, tab-separated:
131
-
132
- ```
133
- variant_name description excluded_modules
134
- default All project modules
135
- workstation-lean No editor defaults contrib_editor
136
- ```
137
-
138
- - Column 1 is the variant name.
139
- - Column 2 is a human-readable description.
140
- - Column 3 is a space-separated list of excluded modules.
141
-
142
- An exclusion is a bare module name (matching a `shell/module.d/` module) or a
143
- qualified name (`<name>@<source>`) that names the source directory
144
- explicitly. Every exclusion must match exactly one registry row; an unknown
145
- or ambiguous exclusion fails the compile rather than silently excluding
146
- nothing.
147
-
148
- Exclusion is applied to the whole resolved graph, not just the roots. A module
149
- excluded by name is not loaded, and neither is anything that depends on it.
150
- `valise explain-variant <name>` shows a variant's description, its exclusion
151
- list, and the per-shell impact.
152
-
153
- The variant and the bundle compose: the bundle decides the starting points
154
- and the layers they reach, and the variant then removes modules from the
155
- resolved graph.
156
-
157
- ## `valise compile`
158
-
159
- ```sh
160
- valise compile [--bundle=<name>] [--variant=<name>] <output-dir>
161
- ```
162
-
163
- Compile resolves the module graph and writes one plan per shell. It does not
164
- copy module bodies; that is `build`'s job.
165
-
166
- The steps, in order:
167
-
168
- 1. Resolve the project root. Fail with `cannot find source tree` when the
169
- project has no `shell/release/module-registry.tsv`.
170
- 2. Validate the variant: the name must appear exactly once in
171
- `install-variants`, and every exclusion must match exactly one registry
172
- row.
173
- 3. Validate the bundle when `--bundle` is given: the name must exist, and
174
- its roots must resolve.
175
- 4. For each of `bash`, `zsh`, and `ksh`, resolve the
176
- bundle's roots for that shell, walk the dependency closure, drop the
177
- variant's exclusions, select each module by `shells=`, emit its
178
- `platforms=` gate, and emit a plan.
179
- 5. Replace the output directory atomically.
180
-
181
- The output directory must be empty or absent. Compile stages into a private
182
- sibling directory and publishes only after every plan has compiled, so a
183
- failed compile never leaves a half-written output tree.
184
-
185
- ### What a plan contains
186
-
187
- Each plan is a POSIX shell file at `generated/installed-modules.<shell>`:
188
-
189
- ```
190
- # shell-profile-installed-modules-v1
191
- # Generated by valise compile; DO NOT EDIT.
192
- # plan=bash
193
- # roots=profile_main
194
- # order=hello profile_main
195
- ```
196
-
197
- The header names the format, the generator, the shell, the roots, and the
198
- resolved load order. The body then:
199
-
200
- - validates `VALISE_MODE` (`strict` or `permissive`; default `strict`);
201
- - probes the platform once and gates each module by `platforms=`;
202
- - sources `vendor/shell-profile/lib/capabilities.sh`, so `sp_cap_*` helpers
203
- stay available to module functions after the plan finishes;
204
- - checks each module's declared exports before and after loading it;
205
- - does not run a module whose required dependency is unavailable, whether that
206
- dependency failed or was skipped for this platform, and reports it by name;
207
- - in strict mode, returns nonzero at the first failure in the required closure:
208
- the bundle's roots and everything they require;
209
- - in permissive mode, reports each failure, continues with the unrelated
210
- modules, and returns zero;
211
- - treats an optional dependency as best effort: it loads first when it can, and
212
- its absence never affects the module that declared it. A failure is reported;
213
- an unsupported platform is expected and prints nothing;
214
- - when `VALISE_RELOAD=1` is set, clears the plan's declared exports first, so
215
- the plan can be sourced again.
216
-
217
- The plan is the compiled equivalent of the loader: same dependency rules,
218
- same export checks, same strict and permissive behavior. The plan is static and fast;
219
- the loader parses metadata at runtime and is the fallback for releases that
220
- ship an `entrypoints/` tree instead of `generated/` plans.
221
-
222
- ### Failure behavior
223
-
224
- Compile fails closed, before writing anything, when:
225
-
226
- - the project root cannot be resolved;
227
- - the variant is unknown or ambiguous;
228
- - a variant exclusion matches no registry row, or more than one;
229
- - the bundle is unknown, or its roots do not resolve;
230
- - a module in the closure has a `side_effect` that is not safe to source at
231
- startup (`generated-file`, `update-network`, `install-time`);
232
- - the capabilities prelude is missing or defines no `sp_cap_*` functions;
233
- - the registry names a module whose source, load path, or export name is not
234
- representable.
235
-
236
- Fish plans are not produced by the POSIX plan generator. `valise compile`
237
- emits POSIX plans only; a Fish integration uses the native Fish loader.
238
-
239
- ## `valise build`
240
-
241
- ```sh
242
- valise build [--bundle=<name>] [--variant=<name>] [out]
243
- ```
244
-
245
- Build a complete, installable release tree. It runs `valise
246
- compile` internally, so everything compile validates is validated here too.
247
-
248
- The built tree has this layout:
249
-
250
- ```
251
- generated/installed-modules.bash compiled plans
252
- generated/installed-modules.zsh
253
- generated/installed-modules.ksh
254
- module.d/<name>.meta primary module metadata
255
- modules/<path> primary module bodies
256
- layers/<provider>/module.d/<name>.meta layer metadata
257
- layers/<provider>/<path> layer bodies
258
- vendor/shell-profile/lib/capabilities.sh the capability prelude
259
- shell/release/ bundle-roots, install-variants, registry
260
- shell/install/profile-release.manifest the release manifest
261
- ```
262
-
263
- Build:
264
-
265
- 1. Runs from the project root — it needs `shell/module.d/`.
266
- 2. Regenerates `shell/release/module-registry.tsv` from the metadata.
267
- 3. Compiles the plans into a staging directory.
268
- 4. Copies the capability prelude from the installed engine. The packaged
269
- file is the same file the plans were built against.
270
- 5. Copies each module's metadata and body to its release path. A primary
271
- module lands at the release root; a layer module lands at
272
- `layers/<provider>/`, matching the paths the plan references.
273
- 6. Normalizes file modes to `0644` and writes the release manifest.
274
- 7. Publishes the tree at the destination.
275
-
276
- Like compile, build stages beside the destination and publishes only after
277
- the complete tree and its manifest exist. A failed build never leaves a
278
- partial release. The default destination is `build/release`; an existing
279
- default tree is replaced only after the new tree has compiled and been
280
- manifested. An explicit destination must be empty or absent.
281
-
282
- Building the same project twice produces byte-identical output, including
283
- the manifest.
284
-
285
- ## `valise build` and `valise apply`
286
-
287
- `valise build` produces the tree; `valise apply` adds install and shell
288
- integration on top of it:
289
-
290
- - `valise build [--variant=<name>] [--bundle=<name>] [out]` builds to
291
- `build/release` by default, reading the variant and bundle defaults from
292
- `shell/release/project.conf`.
293
- - `valise apply [--variant=<name>] [--bundle=<name>] [--no-integration]`
294
- builds, installs the release, writes the managed shell integration,
295
- verifies the active release, and reports what changed.
296
-
297
- Both are idempotent: running them twice leaves the same state.
298
-
299
- `shell/release/project.conf` holds the defaults:
300
-
301
- ```
302
- variant=default
303
- bundle=default
304
- ```
305
-
306
- ## `valise release list`, `use`, and `prune`
307
-
308
- These operate on the releases installed on this machine. No source tree is
309
- needed.
310
-
311
- ```sh
312
- valise release list
313
- valise release use <release-id>
314
- valise release prune --keep=3
315
- ```
316
-
317
- Release directories are named by the content-derived SHA-256 of their
318
- manifest, and the active one is marked in the list. `release use` verifies
319
- the named release byte-for-byte against its own manifest before switching the
320
- active pointer.
321
-
322
- `release prune --keep=N` removes old releases. It keeps the active release
323
- and the `N` newest others, ordered by directory modification time. Before
324
- removing any candidate it verifies the candidate against its own manifest; a
325
- release that fails verification is **kept** and reported, because a release
326
- that cannot be verified may be the only recoverable copy. The default is
327
- `--keep=3`.
File without changes
@@ -1,99 +0,0 @@
1
- # Copyright (c) 2026 Joseph Cumines
2
- # SPDX-License-Identifier: MIT
3
-
4
- # Generic Fish entrypoint adapter shipped with the valise engine.
5
- #
6
- # The valise Fish integration authenticates the active sealed release and
7
- # exports SHELL_PROJECT_ROOT pointing at its root before sourcing this file.
8
- # This adapter then requests modules the same way the POSIX entrypoint does:
9
- # VALISE_MODULES selects the graph (unset loads nothing), VALISE_MODE selects
10
- # strict or permissive failure handling (default permissive). It sources the
11
- # release's native Fish metadata and loader, consumes the loader's bootstrap
12
- # status marker, and publishes VALISE_FISH_READY=1 only after a successful
13
- # activation. Consuming projects may ship their own adapter at the same
14
- # release path to add project-specific selection policy.
15
-
16
- if not builtin set -q SHELL_PROJECT_ROOT
17
- builtin printf '%s\n' 'valise Fish entrypoint: SHELL_PROJECT_ROOT is not set' >&2
18
- return 1
19
- end
20
- set -l _valise_fish_entrypoint_root "$SHELL_PROJECT_ROOT"
21
-
22
- if not builtin test -r "$_valise_fish_entrypoint_root/lib/fish/metadata.fish"
23
- builtin printf '%s\n' "valise Fish entrypoint: metadata library is not readable: $_valise_fish_entrypoint_root/lib/fish/metadata.fish" >&2
24
- return 1
25
- end
26
- if not builtin test -r "$_valise_fish_entrypoint_root/lib/fish/loader.fish"
27
- builtin printf '%s\n' "valise Fish entrypoint: loader library is not readable: $_valise_fish_entrypoint_root/lib/fish/loader.fish" >&2
28
- return 1
29
- end
30
-
31
- # The bootstrap handshake variables are engine-private state. A forged or
32
- # stale marker must not survive into this activation: erase every visible
33
- # scope before requesting a fresh bootstrap, failing closed if an erase
34
- # is refused.
35
- for _valise_fish_entrypoint_stale in _sp_fish_loader_bootstrap_mode _sp_fish_loader_bootstrap_seeds _sp_fish_loader_bootstrap_status
36
- if builtin set -q -g "$_valise_fish_entrypoint_stale"; and not builtin set -e -g "$_valise_fish_entrypoint_stale"
37
- builtin printf '%s\n' "valise Fish entrypoint: cannot clear stale global $_valise_fish_entrypoint_stale" >&2
38
- return 1
39
- end
40
- if builtin set -q -U "$_valise_fish_entrypoint_stale"; and not builtin set -e -U "$_valise_fish_entrypoint_stale"
41
- builtin printf '%s\n' "valise Fish entrypoint: cannot clear stale universal $_valise_fish_entrypoint_stale" >&2
42
- return 1
43
- end
44
- end
45
-
46
- set -l _valise_fish_entrypoint_mode permissive
47
- if builtin set -q VALISE_MODE
48
- set _valise_fish_entrypoint_mode "$VALISE_MODE"
49
- end
50
-
51
- set -l _valise_fish_entrypoint_seeds
52
- if builtin set -q VALISE_MODULES; and builtin test -n "$VALISE_MODULES"
53
- set _valise_fish_entrypoint_seeds (builtin string split ' ' -- $VALISE_MODULES)
54
- end
55
-
56
- builtin set -gx _sp_fish_loader_bootstrap_mode "$_valise_fish_entrypoint_mode"
57
- builtin set -gx _sp_fish_loader_bootstrap_seeds $_valise_fish_entrypoint_seeds
58
-
59
- builtin source "$_valise_fish_entrypoint_root/lib/fish/metadata.fish"
60
- set -l _valise_fish_entrypoint_metadata_status $status
61
- if builtin test $_valise_fish_entrypoint_metadata_status -ne 0
62
- builtin set -e _sp_fish_loader_bootstrap_mode
63
- builtin set -e _sp_fish_loader_bootstrap_seeds
64
- return $_valise_fish_entrypoint_metadata_status
65
- end
66
-
67
- builtin source "$_valise_fish_entrypoint_root/lib/fish/loader.fish"
68
- set -l _valise_fish_entrypoint_loader_status $status
69
- # The loader consumes the bootstrap request when it sources cleanly; erase
70
- # any request a failed source left behind so it cannot leak to callers.
71
- if builtin set -q _sp_fish_loader_bootstrap_mode
72
- builtin set -e _sp_fish_loader_bootstrap_mode
73
- end
74
- if builtin set -q _sp_fish_loader_bootstrap_seeds
75
- builtin set -e _sp_fish_loader_bootstrap_seeds
76
- end
77
- if builtin test $_valise_fish_entrypoint_loader_status -ne 0
78
- # A failed source may have published a partial status marker; erase it
79
- # so the caller's fresh-marker check below cannot see stale state.
80
- if builtin set -q _sp_fish_loader_bootstrap_status
81
- builtin set -e _sp_fish_loader_bootstrap_status
82
- end
83
- return $_valise_fish_entrypoint_loader_status
84
- end
85
-
86
- # The loader publishes a fresh bootstrap status marker on every activation;
87
- # its absence means the loader never completed its handshake.
88
- if not builtin set -q _sp_fish_loader_bootstrap_status
89
- builtin printf '%s\n' 'valise Fish entrypoint: loader bootstrap status marker is absent' >&2
90
- return 1
91
- end
92
- set -l _valise_fish_entrypoint_status $_sp_fish_loader_bootstrap_status
93
- builtin set -e _sp_fish_loader_bootstrap_status
94
- if builtin test $_valise_fish_entrypoint_status -ne 0
95
- return $_valise_fish_entrypoint_status
96
- end
97
-
98
- builtin set -gx VALISE_FISH_READY 1
99
- return 0
@@ -1,138 +0,0 @@
1
- #!/bin/sh
2
-
3
- # Copyright (c) 2026 Joseph Cumines
4
- # SPDX-License-Identifier: MIT
5
-
6
- # build-manifest.sh: vendor engine files into an e2e release tree and
7
- # generate a profile-release.manifest with correct sizes and SHA-256 digests.
8
- #
9
- # Usage: sh build-manifest.sh [output-dir]
10
- # Default output-dir: examples/e2e/build/release
11
-
12
- set -eu
13
-
14
- _script_dir=$(cd "$(dirname "$0")" && pwd -P)
15
- _repo_root=$(cd "$_script_dir/../.." && pwd -P)
16
- _e2e_root="$_script_dir"
17
- _out_dir="${1:-$_e2e_root/build/release}"
18
- _valise="$_repo_root/bin/valise"
19
-
20
- [ -x "$_valise" ] || { printf 'ERROR: valise CLI not found at %s\n' "$_valise" >&2; exit 1; }
21
-
22
- # Prepare clean output directory
23
- rm -rf "$_out_dir"
24
- mkdir -p "$_out_dir"
25
-
26
- _vendor_copy() {
27
- _src="$_repo_root/$1"
28
- _dst="$_out_dir/$1"
29
- _dst_dir=$(dirname "$_dst")
30
- [ -f "$_src" ] || { printf 'ERROR: engine source missing: %s\n' "$_src" >&2; exit 1; }
31
- mkdir -p "$_dst_dir"
32
- cp "$_src" "$_dst"
33
- chmod 0644 "$_dst"
34
- }
35
-
36
- printf 'Vendoring engine files into %s...\n' "$_out_dir"
37
-
38
- # Core libraries
39
- _vendor_copy lib/metadata.sh
40
- _vendor_copy lib/loader.sh
41
- _vendor_copy lib/capabilities.sh
42
- _vendor_copy lib/compiler.awk
43
-
44
- # Fish libraries
45
- _vendor_copy lib/fish/loader.fish
46
- _vendor_copy lib/fish/metadata.fish
47
-
48
- # Generic Fish entrypoint adapter
49
- _vendor_copy entrypoints/fish/profile.fish
50
-
51
- # Entrypoint
52
- _vendor_copy entrypoints/profile.sh
53
-
54
- # Platform module metadata
55
- _vendor_copy module.d/platform_posix.meta
56
- _vendor_copy module.d/platform_macos.meta
57
- _vendor_copy module.d/platform_linux.meta
58
- _vendor_copy module.d/platform_bsd.meta
59
-
60
- # Platform module bodies
61
- _vendor_copy modules/platform/posix.sh
62
- _vendor_copy modules/platform/macos/capabilities.sh
63
- _vendor_copy modules/platform/linux/capabilities.sh
64
- _vendor_copy modules/platform/bsd/capabilities.sh
65
-
66
- # Shareable engine catalog (ships in every release built from this engine)
67
- _engine_contrib_count=0
68
- for _contrib_src in "$_repo_root"/module.d/contrib_*.meta; do
69
- [ -f "$_contrib_src" ] || continue
70
- _vendor_copy "module.d/$(basename "$_contrib_src")"
71
- _engine_contrib_count=$((_engine_contrib_count + 1))
72
- done
73
- for _contrib_src in "$_repo_root"/modules/system/contrib_*.sh; do
74
- [ -f "$_contrib_src" ] || continue
75
- _vendor_copy "modules/system/$(basename "$_contrib_src")"
76
- _engine_contrib_count=$((_engine_contrib_count + 1))
77
- done
78
- if [ "$_engine_contrib_count" -eq 0 ]; then
79
- printf 'ERROR: no shareable engine modules found in %s\n' "$_repo_root" >&2
80
- exit 1
81
- fi
82
-
83
- # --- Native e2e example modules ---
84
- _e2e_meta_count=0
85
- mkdir -p "$_out_dir/module.d"
86
- for _meta in "$_e2e_root"/module.d/e2e_*.meta; do
87
- [ -f "$_meta" ] || continue
88
- cp "$_meta" "$_out_dir/module.d/"
89
- chmod 0644 "$_out_dir/module.d/$(basename "$_meta")"
90
- _e2e_meta_count=$((_e2e_meta_count + 1))
91
- done
92
-
93
- _e2e_body_count=0
94
- mkdir -p "$_out_dir/modules/e2e"
95
- for _body in "$_e2e_root"/modules/e2e/*.sh "$_e2e_root"/modules/e2e/*.fish; do
96
- [ -f "$_body" ] || continue
97
- cp "$_body" "$_out_dir/modules/e2e/"
98
- chmod 0644 "$_out_dir/modules/e2e/$(basename "$_body")"
99
- _e2e_body_count=$((_e2e_body_count + 1))
100
- done
101
-
102
- if [ "$_e2e_meta_count" -eq 0 ]; then
103
- printf 'ERROR: no e2e module metadata found in %s\n' "$_e2e_root/module.d" >&2
104
- exit 1
105
- fi
106
- if [ "$_e2e_body_count" -eq 0 ]; then
107
- printf 'ERROR: no e2e module bodies found in %s\n' "$_e2e_root/modules/e2e" >&2
108
- exit 1
109
- fi
110
-
111
- # --- Vendor shared layer (cross-repo composition) ---
112
- _shared_src="$_repo_root/examples/shared"
113
- _shared_dst="$_out_dir/layer/shared"
114
- [ -d "$_shared_src/module.d" ] || { printf 'ERROR: shared provider missing: %s\n' "$_shared_src" >&2; exit 1; }
115
- mkdir -p "$_shared_dst/module.d" "$_shared_dst/modules"
116
- for _shared_meta in "$_shared_src"/module.d/*.meta; do
117
- [ -f "$_shared_meta" ] || { printf 'ERROR: no shared provider metadata in %s\n' "$_shared_src/module.d" >&2; exit 1; }
118
- cp "$_shared_meta" "$_shared_dst/module.d/"
119
- chmod 0644 "$_shared_dst/module.d/$(basename "$_shared_meta")"
120
- done
121
- for _shared_area in "$_shared_src"/modules/*; do
122
- [ -d "$_shared_area" ] || continue
123
- mkdir -p "$_shared_dst/modules/$(basename "$_shared_area")"
124
- for _shared_body in "$_shared_area"/*.sh; do
125
- [ -f "$_shared_body" ] || continue
126
- cp "$_shared_body" "$_shared_dst/modules/$(basename "$_shared_area")/"
127
- chmod 0644 "$_shared_dst/modules/$(basename "$_shared_area")/$(basename "$_shared_body")"
128
- done
129
- done
130
- _shared_rev=$(cd "$_shared_src" && git rev-parse HEAD 2>/dev/null || printf 'unknown')
131
- printf 'provider=examples/shared\nrevision=%s\n' "$_shared_rev" > "$_shared_dst/layer-pin.txt"
132
- chmod 0644 "$_shared_dst/layer-pin.txt"
133
-
134
- # Normalise file modes before manifesting
135
- find "$_out_dir" -type f -exec chmod 0644 {} +
136
-
137
- # --- Generate manifest using valise CLI ---
138
- "$_valise" make-manifest "$_out_dir"
File without changes