superpowers-manager 0.3.0 → 0.5.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 (41) hide show
  1. package/README.md +63 -325
  2. package/dist/adapter.js +91 -46
  3. package/dist/artifact-tree.js +110 -0
  4. package/dist/atomic.js +103 -7
  5. package/dist/cli-arguments.js +37 -0
  6. package/dist/cli.js +97 -40
  7. package/dist/codex-compatibility.js +126 -0
  8. package/dist/codex-conflicts.js +99 -0
  9. package/dist/codex-harness.js +321 -0
  10. package/dist/codex-json.js +7 -0
  11. package/dist/codex-prepare.js +255 -0
  12. package/dist/codex-presentation.js +282 -0
  13. package/dist/commands/install.js +187 -173
  14. package/dist/commands/mutation.js +71 -0
  15. package/dist/commands/prepare.js +87 -188
  16. package/dist/commands/probe.js +191 -176
  17. package/dist/commands/uninstall.js +52 -139
  18. package/dist/commands/update.js +33 -88
  19. package/dist/generated-plugin.js +3 -3
  20. package/dist/harness-compatibility.js +13 -0
  21. package/dist/harness.js +1 -0
  22. package/dist/lifecycle.js +1 -86
  23. package/dist/manifest-overlay.js +2 -2
  24. package/dist/pi-compatibility.js +73 -0
  25. package/dist/pi-harness.js +63 -0
  26. package/dist/pi-install.js +495 -0
  27. package/dist/pi-native.js +81 -0
  28. package/dist/pi-package.js +153 -0
  29. package/dist/pi-paths.js +30 -0
  30. package/dist/pi-prepare.js +111 -0
  31. package/dist/pi-presentation.js +67 -0
  32. package/dist/pi-settings.js +171 -0
  33. package/dist/pi-shared-skills.js +413 -0
  34. package/dist/pi-state.js +311 -0
  35. package/dist/resource-lock.js +265 -0
  36. package/dist/safe-path.js +21 -5
  37. package/dist/strict-json.js +1 -1
  38. package/dist/upstream-workspace.js +8 -0
  39. package/dist/validator.js +3 -2
  40. package/package.json +19 -18
  41. package/bin/superpowers-manager.js +0 -16
@@ -0,0 +1,282 @@
1
+ import { normalizeCodexInstall, normalizeCodexInstalled, } from "./codex-harness.js";
2
+ import { displaySource } from "./selection.js";
3
+ // One ordered table drives both formats, preserving the public human and
4
+ // porcelain field order exposed through the harness presentation.
5
+ export function fields(f) {
6
+ return [
7
+ { key: "harness", label: "harness", value: f.harness },
8
+ { key: "requested_ref", label: "requested ref", value: f.requestedRef },
9
+ { key: "resolved_ref", label: "resolved ref", value: f.resolvedRef },
10
+ { key: "desired_commit", label: "desired commit", value: f.desiredCommit },
11
+ {
12
+ key: "generated_commit",
13
+ label: "generated plugin commit",
14
+ value: f.generatedCommit,
15
+ absent: "not present",
16
+ },
17
+ {
18
+ key: "installed_commit",
19
+ label: "installed manager commit or fingerprint",
20
+ value: f.installedCommit,
21
+ absent: "not detected",
22
+ },
23
+ {
24
+ key: "identity_state",
25
+ label: "Codex identity state",
26
+ value: f.identityState,
27
+ },
28
+ { key: "status", label: "status", value: f.status },
29
+ {
30
+ key: "selection_origin",
31
+ label: "selection origin",
32
+ value: f.selectionOrigin,
33
+ },
34
+ { key: "selection_mode", label: "selection mode", value: f.selectionMode },
35
+ {
36
+ key: "upstream_source_origin",
37
+ label: "upstream source origin",
38
+ value: f.upstreamSourceOrigin,
39
+ },
40
+ {
41
+ key: "effective_source",
42
+ label: "effective source",
43
+ value: f.effectiveSource,
44
+ },
45
+ { key: "saved_mode", label: "saved mode", value: f.savedMode },
46
+ { key: "saved_source", label: "saved source", value: f.savedSource },
47
+ {
48
+ key: "saved_requested_ref",
49
+ label: "saved requested ref",
50
+ value: f.savedRequestedRef,
51
+ },
52
+ {
53
+ key: "saved_resolved_ref",
54
+ label: "saved resolved ref",
55
+ value: f.savedResolvedRef,
56
+ },
57
+ { key: "saved_commit", label: "saved commit", value: f.savedCommit },
58
+ { key: "update_control", label: "update control", value: f.updateControl },
59
+ ];
60
+ }
61
+ const NO_FACTS = {
62
+ harness: "codex",
63
+ requestedRef: "",
64
+ resolvedRef: "",
65
+ desiredCommit: "",
66
+ generatedCommit: "",
67
+ installedCommit: "",
68
+ identityState: "",
69
+ status: "",
70
+ selectionOrigin: "",
71
+ selectionMode: "",
72
+ upstreamSourceOrigin: "",
73
+ effectiveSource: "",
74
+ savedMode: "",
75
+ savedSource: "",
76
+ savedRequestedRef: "",
77
+ savedResolvedRef: "",
78
+ savedCommit: "",
79
+ updateControl: "",
80
+ };
81
+ export const PROBE_PORCELAIN_KEYS = fields(NO_FACTS).map((field) => field.key);
82
+ export function formatPorcelain(f) {
83
+ return fields(f)
84
+ .map((field) => `${field.key}=${field.value}\n`)
85
+ .join("");
86
+ }
87
+ export function formatHuman(f) {
88
+ let text = fields(f)
89
+ .map((field) => {
90
+ const shown = field.value.length === 0 && field.absent !== undefined
91
+ ? field.absent
92
+ : field.value;
93
+ return `${field.label}: ${shown}\n`;
94
+ })
95
+ .join("");
96
+ if (f.selectionOrigin !== f.upstreamSourceOrigin) {
97
+ text +=
98
+ "warning: effective ref and source have mixed origins " +
99
+ `(ref: ${f.selectionOrigin}, source: ${f.upstreamSourceOrigin})\n`;
100
+ }
101
+ return text;
102
+ }
103
+ function verificationOutput(kind, hint) {
104
+ const stderr = [
105
+ kind === "mismatch"
106
+ ? "error: installed manager fingerprint does not match the prepared plugin after install."
107
+ : "error: installed manager fingerprint is not detectable after install.",
108
+ ];
109
+ if (hint.length > 0)
110
+ stderr.push(`hint: ${hint}`);
111
+ return { stdout: [], stderr };
112
+ }
113
+ export function codexInstallReceipt(missingHint, mismatchHint) {
114
+ return {
115
+ missingVerificationOutput: verificationOutput("missing", missingHint),
116
+ mismatchVerificationOutput: verificationOutput("mismatch", mismatchHint),
117
+ };
118
+ }
119
+ // Compatibility export target for src/lifecycle.ts. Delegate to the production
120
+ // normalizers and renderer so the retained verdict cannot drift from commands.
121
+ export function verifyInstalledFingerprint(desiredCommit, installResult, inspectResult) {
122
+ const receipt = normalizeCodexInstall(installResult);
123
+ const inspection = normalizeCodexInstalled(inspectResult, desiredCommit);
124
+ const output = codexPresentation.renderInstallVerification(desiredCommit, receipt, inspection);
125
+ const ok = inspection.status === 0 &&
126
+ inspection.outcome.ok &&
127
+ inspection.outcome.result.kind === "current";
128
+ return { ok, stdout: output.stdout, stderr: output.stderr };
129
+ }
130
+ function probeFacts(facts) {
131
+ const selection = facts.selection;
132
+ const saved = selection.saved;
133
+ return {
134
+ harness: "codex",
135
+ requestedRef: selection.requestedRef,
136
+ resolvedRef: selection.resolvedRef,
137
+ desiredCommit: selection.desiredCommit,
138
+ generatedCommit: facts.prepared.observedIdentity,
139
+ installedCommit: facts.installed.observedIdentity,
140
+ identityState: facts.ownership.presentationValue,
141
+ status: facts.status,
142
+ selectionOrigin: selection.selectionOrigin,
143
+ selectionMode: selection.selectionMode,
144
+ upstreamSourceOrigin: selection.upstreamSourceOrigin,
145
+ effectiveSource: displaySource(selection.effectiveSource),
146
+ savedMode: saved.saved_mode,
147
+ savedSource: saved.saved_source.length > 0 ? displaySource(saved.saved_source) : "",
148
+ savedRequestedRef: saved.saved_requested_ref,
149
+ savedResolvedRef: saved.saved_resolved_ref,
150
+ savedCommit: saved.saved_commit,
151
+ updateControl: facts.control.presentationValue,
152
+ };
153
+ }
154
+ function invocationFailure(argv) {
155
+ return {
156
+ unexpected: `cannot invoke Codex adapter for ${argv}`,
157
+ invalidStatus: `adapter reported a failure status for ${argv}`,
158
+ };
159
+ }
160
+ function callFailure(site, ctx, removalInput) {
161
+ switch (site) {
162
+ case "prepare":
163
+ return {
164
+ unexpected: "cannot build the generated plugin candidate",
165
+ invalidStatus: "adapter reported failure without an error outcome",
166
+ };
167
+ case "probe-installed":
168
+ return {
169
+ unexpected: "cannot inspect Codex adapter state for view fingerprint",
170
+ invalidStatus: "adapter reported a failure status for inspect --view fingerprint",
171
+ };
172
+ case "probe-ownership":
173
+ return {
174
+ unexpected: "cannot inspect Codex adapter state for view ownership",
175
+ invalidStatus: "adapter reported a failure status for inspect --view ownership",
176
+ };
177
+ case "probe-control":
178
+ return {
179
+ unexpected: "cannot inspect Codex adapter state for view update-control",
180
+ invalidStatus: "adapter reported a failure status for inspect --view update-control",
181
+ };
182
+ case "install-ownership":
183
+ case "remove-ownership":
184
+ case "post-remove":
185
+ return invocationFailure("inspect --view ownership");
186
+ case "install-control":
187
+ return invocationFailure("inspect --view update-control");
188
+ case "install":
189
+ return invocationFailure(`install --package-root ${ctx.root}`);
190
+ case "post-install":
191
+ return {
192
+ unexpected: "cannot invoke Codex adapter for inspect --view fingerprint",
193
+ invalidStatus: "installed manager fingerprint inspection failed after install.",
194
+ };
195
+ case "remove": {
196
+ const input = removalInput ?? {
197
+ pluginPresent: false,
198
+ marketplacePresent: false,
199
+ };
200
+ return invocationFailure(`uninstall --plugin-present ${String(input.pluginPresent)}` +
201
+ ` --marketplace-present ${String(input.marketplacePresent)}`);
202
+ }
203
+ }
204
+ }
205
+ export const codexPresentation = {
206
+ installNotice: "Note: remove or disable conflicting Superpowers providers yourself before" +
207
+ " relying on manager skills.",
208
+ currentNotice: "manager is current",
209
+ renderProbe(snapshot) {
210
+ const facts = probeFacts(snapshot);
211
+ const conflicts = snapshot.ownership.presentationConflicts ?? [];
212
+ const additional = [
213
+ ["installation_state", snapshot.installed.kind],
214
+ ["resource_state", snapshot.resourceState ?? "idle"],
215
+ ["compatibility", snapshot.compatibility.kind],
216
+ ["compatibility_reason", snapshot.compatibility.reason],
217
+ ];
218
+ return {
219
+ human: formatHuman(facts) +
220
+ additional
221
+ .map(([key, value]) => `${key.replaceAll("_", " ")}: ${value}\n`)
222
+ .join("") +
223
+ conflicts
224
+ .map((conflict) => `ownership conflict: ${conflict}\n`)
225
+ .join(""),
226
+ porcelain: formatPorcelain(facts) +
227
+ additional.map(([key, value]) => `${key}=${value}\n`).join("") +
228
+ conflicts
229
+ .map((conflict) => `ownership_conflict=${conflict}\n`)
230
+ .join(""),
231
+ };
232
+ },
233
+ renderInstallVerification(desiredCommit, receipt, inspection) {
234
+ if (inspection.status !== 0 || !inspection.outcome.ok) {
235
+ const malformed = !inspection.outcome.ok &&
236
+ inspection.outcome.error.code === "malformed-result";
237
+ return {
238
+ stdout: [],
239
+ stderr: [
240
+ malformed
241
+ ? "error: cannot parse installed manager fingerprint inspection result after install."
242
+ : "error: installed manager fingerprint inspection failed after install.",
243
+ ],
244
+ };
245
+ }
246
+ const observed = inspection.outcome.result.observedIdentity;
247
+ const stdout = [
248
+ `desired_commit=${desiredCommit}`,
249
+ `installed_commit=${observed}`,
250
+ ];
251
+ if (inspection.outcome.result.kind === "current") {
252
+ return { stdout: [...stdout, "manager updated"], stderr: [] };
253
+ }
254
+ if (receipt.status !== 0 || !receipt.outcome.ok) {
255
+ return {
256
+ stdout,
257
+ stderr: [
258
+ inspection.outcome.result.kind === "absent"
259
+ ? "error: installed manager fingerprint is not detectable after install."
260
+ : "error: installed manager fingerprint does not match the prepared plugin after install.",
261
+ ],
262
+ };
263
+ }
264
+ const output = inspection.outcome.result.kind === "absent"
265
+ ? receipt.outcome.result.missingVerificationOutput
266
+ : receipt.outcome.result.mismatchVerificationOutput;
267
+ return { stdout, stderr: output.stderr };
268
+ },
269
+ renderRemovalCompletion(ownership) {
270
+ return {
271
+ stdout: [
272
+ ...ownership.postRemovalOutput.stdout,
273
+ "uninstall complete",
274
+ "note: local generated artifacts under plugins/superpowers/ and " +
275
+ ".cache/upstream/ were left in place; remove them manually or " +
276
+ "regenerate with npx superpowers-manager prepare.",
277
+ ],
278
+ stderr: ownership.postRemovalOutput.stderr,
279
+ };
280
+ },
281
+ callFailure,
282
+ };