superpowers-manager 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +340 -66
- package/dist/adapter-result.js +204 -0
- package/dist/adapter.js +690 -0
- package/dist/atomic.js +142 -0
- package/dist/cli-arguments.js +32 -0
- package/dist/cli.js +313 -0
- package/dist/codex-harness.js +271 -0
- package/dist/codex-json.js +89 -0
- package/dist/codex-prepare.js +199 -0
- package/dist/codex-presentation.js +259 -0
- package/dist/codex-state.js +78 -0
- package/dist/commands/context.js +1 -0
- package/dist/commands/install.js +291 -0
- package/dist/commands/pin.js +79 -0
- package/dist/commands/prepare.js +420 -0
- package/dist/commands/probe.js +257 -0
- package/dist/commands/track-latest.js +44 -0
- package/dist/commands/uninstall.js +217 -0
- package/dist/commands/unpin.js +95 -0
- package/dist/commands/update.js +79 -0
- package/dist/domain/fingerprint.js +4 -0
- package/dist/domain/refs.js +37 -0
- package/dist/effective-selection.js +123 -0
- package/dist/generated-plugin.js +748 -0
- package/dist/git.js +38 -0
- package/dist/harness.js +1 -0
- package/dist/hooks.js +290 -0
- package/dist/lifecycle.js +135 -0
- package/dist/manifest-overlay.js +125 -0
- package/dist/provenance.js +111 -0
- package/dist/python-json-format.js +83 -0
- package/dist/python-json.js +29 -0
- package/dist/python-text.js +74 -0
- package/dist/safe-path.js +137 -0
- package/dist/safety-error.js +10 -0
- package/dist/selection-state-cli.js +85 -0
- package/dist/selection-store.js +172 -0
- package/dist/selection.js +200 -0
- package/dist/status.js +24 -0
- package/dist/strict-json.js +248 -0
- package/dist/upstream-cli.js +110 -0
- package/dist/upstream-version.js +40 -0
- package/dist/upstream.js +253 -0
- package/dist/validate-generated-plugin-cli.js +118 -0
- package/dist/validator.js +317 -0
- package/dist/workspace.js +139 -0
- package/package.json +25 -4
- package/bin/superpowers-manager.js +0 -290
- package/scripts/adapters/codex/adapter +0 -603
- package/scripts/adapters/codex/lib.sh +0 -449
- package/scripts/adapters/codex/validate-generated-plugin.py +0 -314
- package/scripts/core/adapter.sh +0 -103
- package/scripts/core/common.sh +0 -59
- package/scripts/core/lifecycle.sh +0 -141
- package/scripts/core/provenance.sh +0 -135
- package/scripts/core/selection-state.py +0 -414
- package/scripts/core/selection.sh +0 -168
- package/scripts/core/status.sh +0 -27
- package/scripts/core/upstream.sh +0 -280
- package/scripts/core/validate-adapter-response.py +0 -284
- package/scripts/install +0 -59
- package/scripts/pin +0 -51
- package/scripts/prepare +0 -117
- package/scripts/probe +0 -82
- package/scripts/track-latest +0 -30
- package/scripts/uninstall +0 -35
- package/scripts/unpin +0 -41
- package/scripts/update +0 -34
package/README.md
CHANGED
|
@@ -16,16 +16,21 @@ npx superpowers-manager probe
|
|
|
16
16
|
npx superpowers-manager update
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
Use
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
Use Superpowers Manager to follow the latest stable Superpowers release directly
|
|
20
|
+
from upstream and apply updates with one command. By default, `install` and
|
|
21
|
+
`update` resolve the highest stable `vX.Y.Z` tag when invoked; saved pins and
|
|
22
|
+
invocation overrides take precedence. `probe` reports whether your installation
|
|
23
|
+
matches that selection without changing Codex state. Updates are user-triggered.
|
|
24
24
|
|
|
25
|
-
| Choose | Best fit |
|
|
26
|
-
|
|
27
|
-
|
|
|
28
|
-
|
|
|
25
|
+
| Choose | Version source | Best fit |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| `superpowers-manager` | Latest stable upstream tag by default, or your saved/overridden selection | Follow upstream stable with drift reporting and verified updates |
|
|
28
|
+
| Direct upstream repository | The configured Git ref, or the repository's default branch | Use Codex's native Git marketplace support |
|
|
29
|
+
| `superpowers@openai-curated` | The copy distributed in the curated marketplace | Use the curated integration and its refresh policy |
|
|
30
|
+
|
|
31
|
+
See [Comparing installation routes](#comparing-installation-routes) for commands
|
|
32
|
+
and update behavior. Use one provider at a time; see
|
|
33
|
+
[Provider ownership](#provider-ownership) before switching.
|
|
29
34
|
|
|
30
35
|
### Moving from `superpowers-wrapper`
|
|
31
36
|
|
|
@@ -39,14 +44,33 @@ It never removes the legacy provider automatically.
|
|
|
39
44
|
|
|
40
45
|
## Requirements and platforms
|
|
41
46
|
|
|
42
|
-
Superpowers Manager requires Node 24
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
The installed Superpowers Manager package requires Node >=24. Native source,
|
|
48
|
+
tests, and packaging tooling require Node >=24.12.0. Codex is the only supported
|
|
49
|
+
integration today. Every other requirement is per command, enforced by
|
|
50
|
+
preflight before any dispatch. This table is checked against production by
|
|
51
|
+
`tests/bin/readme-requirements.test.ts`; edit it when a command's requirements
|
|
52
|
+
change, in the same pull request.
|
|
53
|
+
|
|
54
|
+
<!-- requirements:begin -->
|
|
55
|
+
| Command | git | Python 3 | Codex CLI |
|
|
56
|
+
|---|---|---|---|
|
|
57
|
+
| `pin` | yes | no | no |
|
|
58
|
+
| `track-latest` | no | no | no |
|
|
59
|
+
| `unpin` | no | no | no |
|
|
60
|
+
| `prepare` | yes | only with SUPERPOWERS_VALIDATOR | no |
|
|
61
|
+
| `probe` | yes | no | yes |
|
|
62
|
+
| `install` | yes | no | yes |
|
|
63
|
+
| `update` | yes | no | yes |
|
|
64
|
+
| `uninstall` | no | no | yes |
|
|
65
|
+
<!-- requirements:end -->
|
|
66
|
+
|
|
67
|
+
See `docs/baseline/behavioral-inventory.md`'s `CLI-PREFLIGHT-01` for the
|
|
68
|
+
behaviour this table describes.
|
|
46
69
|
|
|
47
70
|
macOS and Linux are tested. WSL2 is supported. The native Windows path is
|
|
48
|
-
untested; the launcher looks for Git Bash
|
|
49
|
-
|
|
71
|
+
untested; the launcher no longer looks for Git Bash at all — every command runs
|
|
72
|
+
in-process, so no POSIX shell is discovered or required — but path handling
|
|
73
|
+
between MSYS and Codex remains a known risk area.
|
|
50
74
|
|
|
51
75
|
Network needs depend on the saved policy. `pin` verifies its target;
|
|
52
76
|
`track-latest` and invocation overrides resolve from upstream when applied; and
|
|
@@ -55,35 +79,119 @@ of a saved exact pin can reuse its recorded identity without upstream access.
|
|
|
55
79
|
Updates remain user-triggered; the manager does not run automatic or background
|
|
56
80
|
updates.
|
|
57
81
|
|
|
82
|
+
## Comparing installation routes
|
|
83
|
+
|
|
84
|
+
### Getting the latest stable release
|
|
85
|
+
|
|
86
|
+
The manager selects the highest stable upstream `vX.Y.Z` tag when its effective
|
|
87
|
+
policy is `latest-release`. It does not require the curated marketplace to
|
|
88
|
+
publish that release first. Saved pins and environment overrides can select a
|
|
89
|
+
different version or source; see [Choosing the upstream version](#choosing-the-upstream-version).
|
|
90
|
+
|
|
91
|
+
The direct repository route uses the Git ref you configure. Adding the repository
|
|
92
|
+
without `--ref` uses its default branch, which is not a latest-stable release
|
|
93
|
+
policy. The curated route uses the
|
|
94
|
+
[copy in `openai/plugins`](https://github.com/openai/plugins/tree/main/plugins/superpowers).
|
|
95
|
+
Refreshing that snapshot does not independently resolve the latest stable tag
|
|
96
|
+
from `obra/superpowers`; curated may match upstream or lag behind it.
|
|
97
|
+
|
|
98
|
+
The native CLI examples below were checked against Codex `0.153.3`. Upstream's
|
|
99
|
+
[marketplace manifest](https://github.com/obra/superpowers/blob/main/.agents/plugins/marketplace.json)
|
|
100
|
+
names its marketplace `superpowers-dev`.
|
|
101
|
+
|
|
102
|
+
### First install
|
|
103
|
+
|
|
104
|
+
These are alternative routes; do not run both to install duplicate providers.
|
|
105
|
+
|
|
106
|
+
| Step | Superpowers Manager | Direct upstream repository |
|
|
107
|
+
|---|---|---|
|
|
108
|
+
| 1 | `npx superpowers-manager install` | `codex plugin marketplace add https://github.com/obra/superpowers` |
|
|
109
|
+
| 2 | — | `codex plugin add superpowers@superpowers-dev` |
|
|
110
|
+
|
|
111
|
+
The manager follows upstream stable by default. For a specific release on the
|
|
112
|
+
direct route, choose its tag and add `--ref TAG` to the marketplace-add command.
|
|
113
|
+
|
|
114
|
+
### Staying current
|
|
115
|
+
|
|
116
|
+
| Action | Superpowers Manager | Direct upstream repository |
|
|
117
|
+
|---|---|---|
|
|
118
|
+
| Explicit update | `npx superpowers-manager update` | `codex plugin marketplace upgrade superpowers-dev` |
|
|
119
|
+
| Optional inspection | `npx superpowers-manager probe` | `codex plugin list` |
|
|
120
|
+
|
|
121
|
+
The manager probes first, skips prepare/install when current and update control
|
|
122
|
+
is valid, and verifies the resulting installed state after a refresh. `probe`
|
|
123
|
+
reports requested and resolved refs, desired/generated/installed commits, and
|
|
124
|
+
status. With a saved pin, "current" means matching that pin, not necessarily
|
|
125
|
+
matching the latest upstream release. See [Lifecycle commands](#lifecycle-commands).
|
|
126
|
+
|
|
127
|
+
Native marketplace upgrade follows its configured ref. In the checked Codex
|
|
128
|
+
version, it can skip unchanged snapshots and refreshes installed plugins when
|
|
129
|
+
the marketplace changes; a second `plugin add` is not required for that refresh.
|
|
130
|
+
Codex also has an automatic refresh path for configured Git marketplaces.
|
|
131
|
+
See the [native upgrade implementation](https://github.com/openai/codex/blob/rust-v0.153.3/codex-rs/core-plugins/src/manager.rs).
|
|
132
|
+
`plugin list` shows installed versions; comparing them with upstream stable is
|
|
133
|
+
separate inspection work, not a prerequisite for running an update.
|
|
134
|
+
|
|
135
|
+
### Changing the selected version
|
|
136
|
+
|
|
137
|
+
Replace `TAG` below with the exact release tag you want. For an already registered
|
|
138
|
+
direct marketplace, remove/add is a CLI route to changing its ref:
|
|
139
|
+
|
|
140
|
+
| Step | Superpowers Manager | Direct upstream repository |
|
|
141
|
+
|---|---|---|
|
|
142
|
+
| 1 | `npx superpowers-manager pin TAG` | `codex plugin marketplace remove superpowers-dev` |
|
|
143
|
+
| 2 | `npx superpowers-manager update` | `codex plugin marketplace add https://github.com/obra/superpowers --ref TAG` |
|
|
144
|
+
| 3 | — | `codex plugin add superpowers@superpowers-dev` |
|
|
145
|
+
|
|
146
|
+
The manager's `pin` saves verified intent without changing Codex state; `update`
|
|
147
|
+
applies it. To resume following stable releases, run
|
|
148
|
+
`npx superpowers-manager track-latest`, then `npx superpowers-manager update`.
|
|
149
|
+
The native sequence changes marketplace configuration immediately. In the checked
|
|
150
|
+
CLI, `marketplace upgrade` has no `--ref` option, and adding the same marketplace
|
|
151
|
+
name with a different ref is rejected. This sequence does not imply that editing
|
|
152
|
+
native configuration is impossible.
|
|
153
|
+
|
|
58
154
|
## What it does
|
|
59
155
|
|
|
60
156
|
- Resolves an upstream ref, defaulting to the latest stable `vX.Y.Z` release
|
|
61
157
|
tag.
|
|
62
158
|
- Clones/fetches upstream at that commit and assembles a Codex plugin tree under
|
|
63
|
-
`plugins/superpowers/` (skills, assets, license/readme, and
|
|
64
|
-
|
|
159
|
+
`plugins/superpowers/` (skills, assets, license/readme, manifest, and any
|
|
160
|
+
hook files that the upstream manifest allows).
|
|
65
161
|
- Stamps the generated manifest with a ref-aware manager version ending in
|
|
66
162
|
`+manager.<short-sha>` and writes the upstream provenance to
|
|
67
163
|
`.superpowers-upstream.json`.
|
|
68
|
-
- Validates the generated tree with the manager's shipped
|
|
69
|
-
|
|
70
|
-
|
|
164
|
+
- Validates the generated tree with the manager's shipped contract validator
|
|
165
|
+
before swapping it into place (a failed run never destroys a previously
|
|
166
|
+
generated tree).
|
|
71
167
|
- Registers the `superpowers-manager` marketplace and installs or refreshes
|
|
72
168
|
`superpowers@superpowers-manager` in Codex.
|
|
73
169
|
|
|
74
|
-
The generated plugin carries upstream skills, assets, and
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
170
|
+
The generated plugin carries upstream skills, assets, documentation, and the
|
|
171
|
+
upstream-owned hook policy. When upstream provides a Codex manifest, its
|
|
172
|
+
`hooks` declaration is preserved: exact `{}` suppresses the `hooks/` subtree;
|
|
173
|
+
active declarations conditionally materialize the upstream hook files; and a
|
|
174
|
+
missing `hooks` key or explicit empty array (`[]`) declaration uses Codex's
|
|
175
|
+
default discovery only when upstream ships `hooks/hooks.json`. Manifest-less
|
|
176
|
+
fallback refs use the committed minimal template and generate neither a manifest
|
|
177
|
+
`hooks` key nor a `hooks/` directory.
|
|
178
|
+
The manager never creates its own hooks or mutates Codex trust state.
|
|
179
|
+
|
|
180
|
+
Review upstream hook command definitions with Codex's `/hooks` flow. Codex
|
|
181
|
+
trust applies to a command definition, not to the contents of scripts that the
|
|
182
|
+
definition references. An explicit update of an older pin can therefore change
|
|
183
|
+
the contents of a trusted referenced script, or reveal a newly untrusted
|
|
184
|
+
upstream definition; review it before trusting or running it. This policy
|
|
185
|
+
eliminates latent hook-policy drift.
|
|
80
186
|
|
|
81
187
|
## Runtime architecture
|
|
82
188
|
|
|
83
|
-
- `
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
189
|
+
- The in-process TypeScript runtime under `src/` owns lifecycle dispatch,
|
|
190
|
+
status, and adapter-result handling;
|
|
191
|
+
see the [in-process adapter result contract](https://github.com/j7an/superpowers-manager/blob/main/docs/adapter-result-contract.md).
|
|
192
|
+
- Developers extending that runtime should start with the
|
|
193
|
+
[internal harness interface](https://github.com/j7an/superpowers-manager/blob/main/docs/harness-interface.md).
|
|
194
|
+
- `src/adapter.ts` owns build, inspection, reconciliation, and Codex mutation.
|
|
87
195
|
- Codex is the only supported adapter today; no public harness selector ships
|
|
88
196
|
yet.
|
|
89
197
|
|
|
@@ -97,10 +205,33 @@ after the built-in check. It receives the candidate plugin root as its only
|
|
|
97
205
|
argument. It cannot replace or bypass built-in validation, and either check
|
|
98
206
|
failing prevents the tree swap and all Codex mutation.
|
|
99
207
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
208
|
+
`SUPERPOWERS_VALIDATOR_EXECUTABLE=/path/to/validator` adds an optional external
|
|
209
|
+
validator after the built-in check. It names an executable, receiving the
|
|
210
|
+
candidate plugin root as its only argument. The manager constructs no shell
|
|
211
|
+
command string and supplies argv directly. On Linux, `execvp` may hand that
|
|
212
|
+
same argv to `/bin/sh` after `ENOEXEC`, and the values are preserved rather
|
|
213
|
+
than re-parsed, so a candidate path containing spaces or shell metacharacters
|
|
214
|
+
is passed through intact and cannot inject a command — on either platform. A
|
|
215
|
+
file with the exec bit set but no valid executable format is handled by the
|
|
216
|
+
platform's own `execvp` fallback, not by the manager: on Linux, `/bin/sh` runs
|
|
217
|
+
it as shell source; on darwin, it is
|
|
218
|
+
rejected outright as not runnable. Give the validator a shebang line or make
|
|
219
|
+
it a real binary, or its behavior will differ by platform. Exit 0 accepts;
|
|
220
|
+
any nonzero exit rejects and prevents the tree swap. The manager stops
|
|
221
|
+
waiting after 30 seconds and keeps at most 64 KiB of each of its output
|
|
222
|
+
streams. It cannot replace or bypass built-in validation, and it is not a
|
|
223
|
+
security boundary: it runs with the manager's own privileges, by design.
|
|
224
|
+
|
|
225
|
+
`SUPERPOWERS_VALIDATOR` is deprecated in favor of `SUPERPOWERS_VALIDATOR_EXECUTABLE`
|
|
226
|
+
and continues to work unchanged. The legacy variable requires `python3`; the
|
|
227
|
+
executable hook does not. Setting both is rejected at preflight, before any
|
|
228
|
+
network or Codex access, rather than silently resolved. Removal of the legacy
|
|
229
|
+
variable is deferred to a future major release.
|
|
230
|
+
|
|
231
|
+
The in-process install command keeps harness-specific validation in the Codex
|
|
232
|
+
adapter: phase 1 prepares the exact candidate first, then the adapter performs
|
|
233
|
+
its Codex and refresh-mode preflight before any Codex mutation. The CLI runs
|
|
234
|
+
its Codex preflight before invoking the lifecycle handler.
|
|
104
235
|
|
|
105
236
|
## Provider ownership
|
|
106
237
|
|
|
@@ -218,15 +349,17 @@ updates the official provider or any other provider automatically.
|
|
|
218
349
|
|
|
219
350
|
- **Upstream manifest first:** when upstream provides
|
|
220
351
|
`.codex-plugin/plugin.json`, `prepare` uses it as the generated manifest base
|
|
221
|
-
so future upstream metadata fields
|
|
352
|
+
so future upstream metadata fields, including its hook declaration, are
|
|
353
|
+
preserved by default.
|
|
222
354
|
- **Fallback template:** `plugins/superpowers/.codex-plugin/plugin.template.json`
|
|
223
355
|
is committed as a minimal fallback for older upstream refs that do not ship a
|
|
224
356
|
Codex manifest. It carries the placeholder version
|
|
225
|
-
`0.0.0+manager.template
|
|
357
|
+
`0.0.0+manager.template`, declares no hooks, and produces no `hooks/`
|
|
358
|
+
directory.
|
|
226
359
|
- **Manager overlay:** `prepare` replaces the version with a ref-aware manager
|
|
227
|
-
version
|
|
228
|
-
|
|
229
|
-
|
|
360
|
+
version and forces `skills` to `./skills/`. Unknown upstream manifest fields,
|
|
361
|
+
including `hooks`, remain preserved; the adapter materializes hook files only
|
|
362
|
+
according to the upstream declaration.
|
|
230
363
|
- Stable tags generate release-looking versions such as
|
|
231
364
|
`6.0.3+manager.896224c`; explicit prerelease tags generate versions such as
|
|
232
365
|
`6.1.0-beta.1+manager.abc1234`.
|
|
@@ -253,49 +386,190 @@ updates the official provider or any other provider automatically.
|
|
|
253
386
|
SUPERPOWERS_INSTALL_REFRESH_MODE=remove-add npx superpowers-manager update
|
|
254
387
|
```
|
|
255
388
|
|
|
389
|
+
## pnpm updates
|
|
390
|
+
|
|
391
|
+
A weekly Monday workflow (06:00 UTC), also available through manual dispatch,
|
|
392
|
+
opens or refreshes a dedicated pull request updating only `package.json`'s
|
|
393
|
+
`packageManager` pin. It selects a newer, non-deprecated stable pnpm release
|
|
394
|
+
within the pinned major after five days. If the current pin is deprecated,
|
|
395
|
+
the shared updater bypasses that waiting period and discloses it in the PR.
|
|
396
|
+
Major upgrades remain a manual decision; the lockfile is not updated by this
|
|
397
|
+
workflow.
|
|
398
|
+
|
|
399
|
+
The caller forwards only `RELEASE_BOT_PRIVATE_KEY` and uses
|
|
400
|
+
`vars.RELEASE_BOT_APP_ID` for App-authored PRs that can trigger CI. Keep both
|
|
401
|
+
configured. After adopting the caller, verify a manual run's App authentication
|
|
402
|
+
and inspect any resulting PR before treating live integration as validated.
|
|
403
|
+
|
|
256
404
|
## Tests
|
|
257
405
|
|
|
406
|
+
Install once, run the static gate before submission, and choose the package
|
|
407
|
+
script that matches the scope you are iterating on:
|
|
408
|
+
|
|
409
|
+
```sh
|
|
410
|
+
pnpm install --frozen-lockfile
|
|
411
|
+
pnpm run check:static
|
|
412
|
+
pnpm test
|
|
413
|
+
pnpm run test:unit
|
|
414
|
+
pnpm run test:integration
|
|
415
|
+
pnpm run test:harness:codex
|
|
416
|
+
pnpm run test:acceptance
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
The package scripts above are alternative iteration selectors; do not run every
|
|
420
|
+
row sequentially as a substitute for acceptance. `pnpm test` runs all shared
|
|
421
|
+
suites once, while the unit and integration scripts select one shared group.
|
|
422
|
+
`test:harness:codex` runs only the isolated Docker Codex probe. Complete
|
|
423
|
+
acceptance is `pnpm run check:static` followed by `pnpm run test:acceptance`
|
|
424
|
+
with explicit evidence for the package's minimum Node runtime.
|
|
425
|
+
|
|
426
|
+
To compare shared-suite scheduling while iterating, use:
|
|
427
|
+
|
|
428
|
+
```sh
|
|
429
|
+
sh tests/run.sh --concurrency 1
|
|
430
|
+
sh tests/run.sh --concurrency 2
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Every normally completed shared run emits both `run-node-suites: complete
|
|
434
|
+
status=<status>` and `tests/run.sh: complete failed=<count>`. Either sentinel
|
|
435
|
+
may report failure; if either is absent, the run was interrupted and is
|
|
436
|
+
incomplete.
|
|
437
|
+
|
|
438
|
+
Use a Homebrew-managed local pnpm by command name; do not use Corepack.
|
|
439
|
+
`check:static` checks formatting, lints, and typechecks production and tests without
|
|
440
|
+
emitting JavaScript. Run the maintained CLI directly with `node src/cli.ts`.
|
|
441
|
+
Tests and their subprocesses execute TypeScript against `src/` with no checkout
|
|
442
|
+
build. Future production coverage covers `src/`, including `src/cli.ts`; emitted
|
|
443
|
+
distribution files, tests, and packaging tools are outside that source scope.
|
|
444
|
+
No coverage collection is enabled by this migration.
|
|
445
|
+
|
|
446
|
+
On macOS, reuse an existing exact package-minimum Node executable when one is
|
|
447
|
+
already available:
|
|
448
|
+
|
|
449
|
+
```sh
|
|
450
|
+
export SPW_PACKAGE_NODE=/absolute/path/to/node-v24.0.0
|
|
451
|
+
export SPW_PACKAGE_NODE_VERSION=24.0.0
|
|
452
|
+
test "$("$SPW_PACKAGE_NODE" -p 'process.versions.node')" = "$SPW_PACKAGE_NODE_VERSION"
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
Otherwise, run this prerequisite setup from the worktree while a supported
|
|
456
|
+
native Node remains on `PATH`. It downloads an official Node archive into a
|
|
457
|
+
new temporary directory and verifies the selected checksum before extraction:
|
|
458
|
+
|
|
459
|
+
```sh
|
|
460
|
+
spw_runtime_dir=$(mktemp -d)
|
|
461
|
+
SPW_PACKAGE_NODE_VERSION=$(node -p 'const e=require("./package.json").engines.node; const m=/^>=(\d+)$/.exec(e); if(!m) throw Error("unsupported engines.node"); `${m[1]}.0.0`')
|
|
462
|
+
case "$(uname -m)" in
|
|
463
|
+
arm64) spw_node_arch=arm64 ;;
|
|
464
|
+
x86_64) spw_node_arch=x64 ;;
|
|
465
|
+
*) echo "unsupported macOS architecture" >&2; exit 1 ;;
|
|
466
|
+
esac
|
|
467
|
+
spw_node_archive="node-v${SPW_PACKAGE_NODE_VERSION}-darwin-${spw_node_arch}.tar.gz"
|
|
468
|
+
(
|
|
469
|
+
set -eu
|
|
470
|
+
cd "$spw_runtime_dir"
|
|
471
|
+
curl --fail --location --remote-name "https://nodejs.org/dist/v${SPW_PACKAGE_NODE_VERSION}/${spw_node_archive}"
|
|
472
|
+
curl --fail --location --remote-name "https://nodejs.org/dist/v${SPW_PACKAGE_NODE_VERSION}/SHASUMS256.txt"
|
|
473
|
+
rg -F " ${spw_node_archive}" SHASUMS256.txt > selected-sha256.txt
|
|
474
|
+
test "$(wc -l < selected-sha256.txt)" -eq 1
|
|
475
|
+
read -r spw_node_sha spw_selected_archive < selected-sha256.txt
|
|
476
|
+
test "$spw_selected_archive" = "$spw_node_archive"
|
|
477
|
+
shasum -a 256 -c selected-sha256.txt
|
|
478
|
+
tar -xzf "$spw_node_archive"
|
|
479
|
+
) || exit 1
|
|
480
|
+
SPW_PACKAGE_NODE="$spw_runtime_dir/node-v${SPW_PACKAGE_NODE_VERSION}-darwin-${spw_node_arch}/bin/node"
|
|
481
|
+
export SPW_PACKAGE_NODE SPW_PACKAGE_NODE_VERSION
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
The native runtime on `PATH` remains unchanged. With the package runtime
|
|
485
|
+
variables exported, complete acceptance is:
|
|
486
|
+
|
|
258
487
|
```sh
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
488
|
+
pnpm install --frozen-lockfile
|
|
489
|
+
pnpm run check:static
|
|
490
|
+
pnpm run test:acceptance
|
|
262
491
|
```
|
|
263
492
|
|
|
493
|
+
After the checks, remove only the temporary directory created by this
|
|
494
|
+
invocation and clear its variables:
|
|
495
|
+
|
|
496
|
+
```sh
|
|
497
|
+
rm -rf -- "$spw_runtime_dir"
|
|
498
|
+
unset SPW_PACKAGE_NODE SPW_PACKAGE_NODE_VERSION spw_node_arch spw_node_archive spw_runtime_dir
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
Linux CI provisions the exact package runtime with `actions/setup-node`.
|
|
502
|
+
Downloads happen only during prerequisite setup, never inside the hermetic test
|
|
503
|
+
cases.
|
|
504
|
+
|
|
505
|
+
Packaging compiles only production source into fresh external temporary staging:
|
|
506
|
+
|
|
507
|
+
```sh
|
|
508
|
+
node tests/tools/pack.ts --out-dir /absolute/existing/temporary/output
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
Allocate the existing output directory outside the checkout before running this
|
|
512
|
+
command. It returns npm-compatible JSON for one validated tarball and removes its
|
|
513
|
+
own staging. Bare checkout `npm pack` always fails with this command's guidance,
|
|
514
|
+
even if stale `dist/` exists. Maintained or manager-generated JavaScript must not
|
|
515
|
+
remain in the checkout; dependencies and generated upstream plugin content have
|
|
516
|
+
separate ownership. This developer command does not authorize publication; follow
|
|
517
|
+
`RELEASING.md` for the protected release procedure.
|
|
518
|
+
|
|
264
519
|
Layers 1-3 stay offline and hermetic: they use a fake local upstream repo plus
|
|
265
520
|
host-side fixtures, and they perform no mutation of the developer's or runner's
|
|
266
521
|
real Codex state.
|
|
267
522
|
|
|
268
|
-
Layer 4 is the Docker acceptance path.
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
523
|
+
Layer 4 is the Docker acceptance path. `pnpm run test:harness:codex` runs the
|
|
524
|
+
real Codex offline probe inside an isolated container home with networking
|
|
525
|
+
disabled. `pnpm run test:acceptance` composes one host-side shared run with that
|
|
526
|
+
probe. The container may mutate its throwaway container-local Codex state, but
|
|
527
|
+
it performs no mutation of the developer's or runner's real Codex state.
|
|
528
|
+
|
|
529
|
+
Release validation deliberately retains the combined shared-plus-Codex path at
|
|
530
|
+
both native endpoints:
|
|
531
|
+
|
|
532
|
+
```sh
|
|
533
|
+
SPW_NATIVE_NODE_VERSION=24.12.0 sh tests/container.sh
|
|
534
|
+
SPW_NATIVE_NODE_VERSION=24 sh tests/container.sh
|
|
535
|
+
```
|
|
275
536
|
|
|
276
|
-
The
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
537
|
+
The container probe uses Codex's `hooks/list` only as compatibility evidence
|
|
538
|
+
for the tested Codex build. It is not a stable Superpowers Manager API.
|
|
539
|
+
|
|
540
|
+
`sh tests/manual/codex-behavior-probe.sh` remains opt-in and covers native-only compatibility residue such as
|
|
541
|
+
path/cache and version-precedence behavior against an intentionally real local
|
|
542
|
+
Codex install. It is not part of acceptance. GitHub Actions runs two focused
|
|
543
|
+
`toolchain` entries and one blocking Codex integration job on pull requests
|
|
544
|
+
and pushes to `main`. The Node 24.12.0 toolchain entry checks native source
|
|
545
|
+
loading, the suite runner/assertion preload, and package-producer success and
|
|
546
|
+
failure. The latest-24 toolchain entry alone runs `pnpm run check:static` and
|
|
547
|
+
the full shared suite with package-minimum evidence. The independent `test` job
|
|
548
|
+
runs only the Codex offline probe on latest Node 24.x. Release acceptance still
|
|
549
|
+
runs the combined shared and Codex paths at both native endpoints, and the
|
|
550
|
+
installed npm executable is tested with Node 24.0.0. These runtime selectors
|
|
551
|
+
are separate from the Homebrew-managed local commands above.
|
|
280
552
|
|
|
281
553
|
## Repository layout
|
|
282
554
|
|
|
283
555
|
```
|
|
284
556
|
.agents/plugins/marketplace.json # local marketplace definition (tracked)
|
|
285
|
-
|
|
557
|
+
.github/ # CI, security, dependency, and release workflows (tracked)
|
|
558
|
+
config/upstream-ref # packaged upstream fallback policy (tracked)
|
|
559
|
+
docs/ # adapter result contract and baseline evidence (tracked)
|
|
560
|
+
package.json pnpm-lock.yaml tsconfig.json # package contract and locked toolchain (tracked)
|
|
286
561
|
plugins/superpowers/
|
|
287
|
-
.codex-plugin/plugin.template.json
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
tests/ # hermetic suite + manual Codex probe
|
|
297
|
-
.cache/upstream/ # upstream clone cache (gitignored)
|
|
562
|
+
.codex-plugin/plugin.template.json # fallback manifest template (tracked)
|
|
563
|
+
generated plugin tree # prepared from upstream (gitignored)
|
|
564
|
+
src/ # in-process TypeScript runtime (tracked)
|
|
565
|
+
cli.ts # sole maintained CLI entry, parsing, preflight, dispatch
|
|
566
|
+
commands/ # lifecycle and selection command handlers
|
|
567
|
+
adapter.ts # Codex integration
|
|
568
|
+
tests/ # hermetic suite and manual Codex probe (tracked)
|
|
569
|
+
migration-inventory/ # frozen historical evidence
|
|
570
|
+
tools/pack.ts # external staging and validated package emission
|
|
298
571
|
```
|
|
299
572
|
|
|
300
573
|
Everything under `plugins/superpowers/` except the fallback manifest template is
|
|
301
|
-
generated by `prepare` and ignored by Git; re-run
|
|
574
|
+
generated by `npx superpowers-manager prepare` and ignored by Git; re-run that
|
|
575
|
+
command to regenerate it.
|