@wemuda/launchrail 1.7.0 → 1.8.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 +36 -20
- package/assets/agents-docs/domain.md +59 -0
- package/assets/agents-docs/issue-tracker-github.md +51 -0
- package/assets/agents-docs/issue-tracker-gitlab.md +52 -0
- package/assets/agents-docs/issue-tracker-linear.md +52 -0
- package/assets/agents-docs/issue-tracker-local.md +45 -0
- package/assets/ralph.permission-guard.py +90 -0
- package/assets/ralph.workflow.js +26 -8
- package/assets/skills/NOTICE.md +41 -0
- package/assets/skills/launchrail/launch/SKILL.md +67 -0
- package/assets/skills/launchrail/launch/workflow.md +77 -0
- package/assets/skills/launchrail/launch-browser-smoke/SKILL.md +49 -0
- package/assets/skills/launchrail/launch-code-review/SKILL.md +89 -0
- package/assets/skills/launchrail/launch-design-validation/SKILL.md +44 -0
- package/assets/skills/launchrail/launch-discovery/SKILL.md +33 -0
- package/assets/skills/launchrail/launch-grill/CONTEXT-FORMAT.md +62 -0
- package/assets/skills/launchrail/launch-grill/SKILL.md +48 -0
- package/assets/skills/launchrail/launch-grill/domain-modeling.md +45 -0
- package/assets/skills/launchrail/launch-implement/SKILL.md +46 -0
- package/assets/skills/launchrail/launch-project-alignment/SKILL.md +48 -0
- package/assets/skills/launchrail/launch-ralph/SKILL.md +100 -0
- package/assets/skills/launchrail/launch-ralph-implement/SKILL.md +17 -0
- package/assets/skills/launchrail/launch-research/SKILL.md +16 -0
- package/assets/skills/launchrail/launch-resolving-merge-conflicts/SKILL.md +15 -0
- package/assets/skills/launchrail/launch-spec/SKILL.md +77 -0
- package/assets/skills/launchrail/launch-tickets/SKILL.md +107 -0
- package/assets/skills/launchrail/launch-vision-creation/SKILL.md +60 -0
- package/assets/skills/launchrail/launch-wayfinder/SKILL.md +130 -0
- package/dist/commands/add.js +21 -4
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/doctor.js +42 -32
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts +3 -7
- package/dist/commands/init.js +62 -85
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/sync.js +11 -0
- package/dist/commands/sync.js.map +1 -1
- package/dist/index.js +0 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/agentsDocs.d.ts +4 -0
- package/dist/lib/agentsDocs.js +32 -0
- package/dist/lib/agentsDocs.js.map +1 -0
- package/dist/lib/claudeSettings.d.ts +74 -11
- package/dist/lib/claudeSettings.js +185 -17
- package/dist/lib/claudeSettings.js.map +1 -1
- package/dist/lib/detect.d.ts +0 -2
- package/dist/lib/detect.js +0 -1
- package/dist/lib/detect.js.map +1 -1
- package/dist/lib/manifest.d.ts +14 -1
- package/dist/lib/manifest.js +18 -1
- package/dist/lib/manifest.js.map +1 -1
- package/dist/lib/migrations.js +202 -1
- package/dist/lib/migrations.js.map +1 -1
- package/dist/lib/project.js +9 -1
- package/dist/lib/project.js.map +1 -1
- package/dist/lib/ralph.d.ts +16 -5
- package/dist/lib/ralph.js +32 -9
- package/dist/lib/ralph.js.map +1 -1
- package/dist/lib/seeds.js +3 -1
- package/dist/lib/seeds.js.map +1 -1
- package/dist/lib/skills.d.ts +12 -0
- package/dist/lib/skills.js +57 -0
- package/dist/lib/skills.js.map +1 -0
- package/dist/lib/upstream.d.ts +6 -6
- package/dist/lib/upstream.js +1 -1
- package/dist/lib/upstream.js.map +1 -1
- package/package.json +1 -1
- package/dist/lib/claudeCli.d.ts +0 -51
- package/dist/lib/claudeCli.js +0 -71
- package/dist/lib/claudeCli.js.map +0 -1
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
|
+
import { RALPH_GUARD_HOOK_PATH } from "./ralph.js";
|
|
3
4
|
/**
|
|
4
|
-
* Consuming projects subscribe to
|
|
5
|
-
* committed, project-scoped declaration in .claude/settings.json (ADR-0003,
|
|
6
|
-
* extended
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
5
|
+
* Consuming projects used to subscribe to workflow Claude Code plugins through
|
|
6
|
+
* a committed, project-scoped declaration in .claude/settings.json (ADR-0003,
|
|
7
|
+
* extended by ADR-0011, retired by ADR-0019/0020 — skills ship as files now).
|
|
8
|
+
* This module remains to plan additive merges and, mostly, their inverse: the
|
|
9
|
+
* migrations that strip the retired declarations from consumers. The file is
|
|
10
|
+
* project-owned and shared with unrelated Claude Code configuration, so it is
|
|
11
|
+
* never tracked in the lockfile and never replaced — only the named keys are
|
|
12
|
+
* ever added or removed.
|
|
12
13
|
*/
|
|
13
14
|
export const CLAUDE_SETTINGS_PATH = join(".claude", "settings.json");
|
|
14
|
-
/**
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The workflow plugin roster is empty: the skills are Launchrail's own and ship
|
|
17
|
+
* as managed files (ADR-0019/0020), never as plugins. Kept as an (empty) array
|
|
18
|
+
* because the legacy declaration migrations plan through it.
|
|
19
|
+
*/
|
|
20
|
+
export const PLUGIN_DECLARATIONS = [];
|
|
21
|
+
/**
|
|
22
|
+
* The declarations Launchrail wrote before it shipped skills as files
|
|
23
|
+
* (ADR-0003/0011). The vendor migration strips these from a consumer's
|
|
24
|
+
* settings.json; they live here only so it knows what to remove.
|
|
25
|
+
*/
|
|
26
|
+
export const RETIRED_PLUGIN_DECLARATIONS = [
|
|
16
27
|
{ marketplace: "launchrail", repo: "wemuda/launchrail", pluginKey: "launchrail@launchrail", label: "Launchrail" },
|
|
17
28
|
{
|
|
18
29
|
marketplace: "mattpocock",
|
|
@@ -21,7 +32,20 @@ export const PLUGIN_DECLARATIONS = [
|
|
|
21
32
|
label: "Matt Pocock's skills",
|
|
22
33
|
},
|
|
23
34
|
];
|
|
24
|
-
|
|
35
|
+
/**
|
|
36
|
+
* The declaration Launchrail added when a project selected the retired
|
|
37
|
+
* `superpowers` implementation loop (ADR-0017, removed by ADR-0020). The
|
|
38
|
+
* independence migration removes it — only from projects whose manifest had
|
|
39
|
+
* selected that loop, so a declaration the user added for their own reasons
|
|
40
|
+
* is never touched.
|
|
41
|
+
*/
|
|
42
|
+
export const RETIRED_SUPERPOWERS_DECLARATION = {
|
|
43
|
+
marketplace: "superpowers-dev",
|
|
44
|
+
repo: "obra/superpowers",
|
|
45
|
+
pluginKey: "superpowers@superpowers-dev",
|
|
46
|
+
label: "Superpowers",
|
|
47
|
+
};
|
|
48
|
+
function readSettings(root, declarations) {
|
|
25
49
|
const path = join(root, CLAUDE_SETTINGS_PATH);
|
|
26
50
|
if (!existsSync(path))
|
|
27
51
|
return { settings: null, state: "no-file" };
|
|
@@ -36,15 +60,20 @@ function readSettings(root) {
|
|
|
36
60
|
return { settings: null, state: "invalid-json" };
|
|
37
61
|
}
|
|
38
62
|
const settings = data;
|
|
39
|
-
const declared =
|
|
63
|
+
const declared = declarations.every((d) => settings.extraKnownMarketplaces?.[d.marketplace] !== undefined &&
|
|
40
64
|
settings.enabledPlugins?.[d.pluginKey] !== undefined);
|
|
41
65
|
return { settings, state: declared ? "declared" : "undeclared" };
|
|
42
66
|
}
|
|
43
|
-
export function declarationState(root) {
|
|
44
|
-
return readSettings(root).state;
|
|
67
|
+
export function declarationState(root, declarations = PLUGIN_DECLARATIONS) {
|
|
68
|
+
return readSettings(root, declarations).state;
|
|
45
69
|
}
|
|
46
|
-
export function planPluginDeclaration(root) {
|
|
47
|
-
|
|
70
|
+
export function planPluginDeclaration(root, declarations = PLUGIN_DECLARATIONS) {
|
|
71
|
+
// Nothing to declare (the core roster is vendored now) — never create or touch
|
|
72
|
+
// the file just to write empty declaration objects.
|
|
73
|
+
if (declarations.length === 0) {
|
|
74
|
+
return { kind: "skip-declared", detail: "no workflow plugins to declare", content: null };
|
|
75
|
+
}
|
|
76
|
+
const { settings, state } = readSettings(root, declarations);
|
|
48
77
|
if (state === "invalid-json") {
|
|
49
78
|
return { kind: "skip-invalid", detail: "unparseable JSON — not touching it", content: null };
|
|
50
79
|
}
|
|
@@ -54,7 +83,7 @@ export function planPluginDeclaration(root) {
|
|
|
54
83
|
const merged = settings ? { ...settings } : {};
|
|
55
84
|
merged.extraKnownMarketplaces = { ...merged.extraKnownMarketplaces };
|
|
56
85
|
merged.enabledPlugins = { ...merged.enabledPlugins };
|
|
57
|
-
for (const d of
|
|
86
|
+
for (const d of declarations) {
|
|
58
87
|
if (merged.extraKnownMarketplaces[d.marketplace] === undefined) {
|
|
59
88
|
merged.extraKnownMarketplaces[d.marketplace] = { source: { source: "github", repo: d.repo } };
|
|
60
89
|
}
|
|
@@ -79,4 +108,143 @@ export function applyPluginDeclaration(root, plan) {
|
|
|
79
108
|
writeFileSync(abs, plan.content, "utf8");
|
|
80
109
|
return true;
|
|
81
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Plan removal of retired plugin declarations from .claude/settings.json — the
|
|
113
|
+
* additive inverse of planPluginDeclaration (ADR-0019). Only the named keys are
|
|
114
|
+
* dropped; anything else the project put there (other marketplaces/plugins, a
|
|
115
|
+
* selected loop's declaration, unrelated settings) is preserved, and a container
|
|
116
|
+
* emptied by the removal is dropped rather than left as `{}`.
|
|
117
|
+
*/
|
|
118
|
+
export function planRemovePluginDeclaration(root, declarations = RETIRED_PLUGIN_DECLARATIONS) {
|
|
119
|
+
const path = join(root, CLAUDE_SETTINGS_PATH);
|
|
120
|
+
if (!existsSync(path))
|
|
121
|
+
return { kind: "skip-no-file", detail: "no .claude/settings.json", content: null };
|
|
122
|
+
let data;
|
|
123
|
+
try {
|
|
124
|
+
data = JSON.parse(readFileSync(path, "utf8"));
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return { kind: "skip-invalid", detail: "unparseable JSON — not touching it", content: null };
|
|
128
|
+
}
|
|
129
|
+
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
130
|
+
return { kind: "skip-invalid", detail: "unparseable JSON — not touching it", content: null };
|
|
131
|
+
}
|
|
132
|
+
const settings = data;
|
|
133
|
+
let changed = false;
|
|
134
|
+
for (const d of declarations) {
|
|
135
|
+
if (settings.extraKnownMarketplaces && d.marketplace in settings.extraKnownMarketplaces) {
|
|
136
|
+
delete settings.extraKnownMarketplaces[d.marketplace];
|
|
137
|
+
changed = true;
|
|
138
|
+
}
|
|
139
|
+
if (settings.enabledPlugins && d.pluginKey in settings.enabledPlugins) {
|
|
140
|
+
delete settings.enabledPlugins[d.pluginKey];
|
|
141
|
+
changed = true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (!changed)
|
|
145
|
+
return { kind: "skip-absent", detail: "no retired plugin declarations present", content: null };
|
|
146
|
+
if (settings.extraKnownMarketplaces && Object.keys(settings.extraKnownMarketplaces).length === 0) {
|
|
147
|
+
delete settings.extraKnownMarketplaces;
|
|
148
|
+
}
|
|
149
|
+
if (settings.enabledPlugins && Object.keys(settings.enabledPlugins).length === 0) {
|
|
150
|
+
delete settings.enabledPlugins;
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
kind: "remove",
|
|
154
|
+
detail: "removing the retired workflow plugin declarations",
|
|
155
|
+
content: JSON.stringify(settings, null, 2) + "\n",
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/** Execute a removal plan. Returns true when the file was written. */
|
|
159
|
+
export function applyRemovePluginDeclaration(root, plan) {
|
|
160
|
+
if (plan.content === null)
|
|
161
|
+
return false;
|
|
162
|
+
writeFileSync(join(root, CLAUDE_SETTINGS_PATH), plan.content, "utf8");
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* The Ralph unattended-launch guard (ADR-0021). The hook *file* is a managed
|
|
167
|
+
* Ralph asset (see `ralphFiles`); this is its registration in the project-owned,
|
|
168
|
+
* shared `.claude/settings.json` — an additive `PreToolUse(Workflow)` entry that
|
|
169
|
+
* runs the guard. Like the plugin declaration, the file is never lockfile-tracked
|
|
170
|
+
* and never replaced wholesale: the registration is an idempotent merge that
|
|
171
|
+
* preserves every other setting and hook a project already carries.
|
|
172
|
+
*/
|
|
173
|
+
export const RALPH_GUARD_HOOK_COMMAND = `python3 "$CLAUDE_PROJECT_DIR/${RALPH_GUARD_HOOK_PATH}"`;
|
|
174
|
+
/** A PreToolUse hook is "ours" when its command invokes the guard script, whatever the matcher. */
|
|
175
|
+
function isGuardCommand(hook) {
|
|
176
|
+
return typeof hook.command === "string" && hook.command.includes("ralph-permission-guard.py");
|
|
177
|
+
}
|
|
178
|
+
function guardRegistered(settings) {
|
|
179
|
+
const preToolUse = settings?.hooks?.PreToolUse;
|
|
180
|
+
if (!Array.isArray(preToolUse))
|
|
181
|
+
return false;
|
|
182
|
+
return preToolUse.some((entry) => Array.isArray(entry?.hooks) && entry.hooks.some(isGuardCommand));
|
|
183
|
+
}
|
|
184
|
+
/** Whether the guard hook is already registered in a project's settings.json. */
|
|
185
|
+
export function ralphGuardHookState(root) {
|
|
186
|
+
const path = join(root, CLAUDE_SETTINGS_PATH);
|
|
187
|
+
if (!existsSync(path))
|
|
188
|
+
return "no-file";
|
|
189
|
+
let data;
|
|
190
|
+
try {
|
|
191
|
+
data = JSON.parse(readFileSync(path, "utf8"));
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
return "invalid-json";
|
|
195
|
+
}
|
|
196
|
+
if (typeof data !== "object" || data === null || Array.isArray(data))
|
|
197
|
+
return "invalid-json";
|
|
198
|
+
return guardRegistered(data) ? "registered" : "unregistered";
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Plan registration of the Ralph guard hook in .claude/settings.json. Additive
|
|
202
|
+
* and idempotent: an existing registration (matched by the guard command, not by
|
|
203
|
+
* exact JSON) is left alone, unparseable JSON is never touched, and every
|
|
204
|
+
* unrelated setting — including other hooks — is preserved.
|
|
205
|
+
*/
|
|
206
|
+
export function planRalphGuardHook(root) {
|
|
207
|
+
const path = join(root, CLAUDE_SETTINGS_PATH);
|
|
208
|
+
const exists = existsSync(path);
|
|
209
|
+
let settings = null;
|
|
210
|
+
if (exists) {
|
|
211
|
+
let data;
|
|
212
|
+
try {
|
|
213
|
+
data = JSON.parse(readFileSync(path, "utf8"));
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return { kind: "skip-invalid", detail: "unparseable JSON — not touching it", content: null };
|
|
217
|
+
}
|
|
218
|
+
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
219
|
+
return { kind: "skip-invalid", detail: "unparseable JSON — not touching it", content: null };
|
|
220
|
+
}
|
|
221
|
+
settings = data;
|
|
222
|
+
}
|
|
223
|
+
if (guardRegistered(settings)) {
|
|
224
|
+
return { kind: "skip-registered", detail: "Ralph guard hook already registered", content: null };
|
|
225
|
+
}
|
|
226
|
+
const merged = settings ? { ...settings } : {};
|
|
227
|
+
const hooks = { ...merged.hooks };
|
|
228
|
+
hooks.PreToolUse = [
|
|
229
|
+
...(Array.isArray(hooks.PreToolUse) ? hooks.PreToolUse : []),
|
|
230
|
+
{ matcher: "Workflow", hooks: [{ type: "command", command: RALPH_GUARD_HOOK_COMMAND }] },
|
|
231
|
+
];
|
|
232
|
+
merged.hooks = hooks;
|
|
233
|
+
return {
|
|
234
|
+
kind: exists ? "merge" : "create",
|
|
235
|
+
detail: exists
|
|
236
|
+
? "registering the Ralph unattended-launch guard, keeping existing settings"
|
|
237
|
+
: "registers the Ralph unattended-launch guard for this project",
|
|
238
|
+
content: JSON.stringify(merged, null, 2) + "\n",
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/** Execute a hook-registration plan. Returns true when the file was written. */
|
|
242
|
+
export function applyRalphGuardHook(root, plan) {
|
|
243
|
+
if (plan.content === null)
|
|
244
|
+
return false;
|
|
245
|
+
const abs = join(root, CLAUDE_SETTINGS_PATH);
|
|
246
|
+
mkdirSync(dirname(abs), { recursive: true });
|
|
247
|
+
writeFileSync(abs, plan.content, "utf8");
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
82
250
|
//# sourceMappingURL=claudeSettings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudeSettings.js","sourceRoot":"","sources":["../../src/lib/claudeSettings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"claudeSettings.js","sourceRoot":"","sources":["../../src/lib/claudeSettings.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/detect.d.ts
CHANGED
|
@@ -17,8 +17,6 @@ export interface RepoDetection {
|
|
|
17
17
|
hasAgentsMd: boolean;
|
|
18
18
|
hasClaudeMd: boolean;
|
|
19
19
|
hasManifest: boolean;
|
|
20
|
-
/** docs/agents/ is the output location of Matt Pocock's /setup-matt-pocock-skills. */
|
|
21
|
-
hasMattPocockSetup: boolean;
|
|
22
20
|
/** The repo already carries real work (source manifest or agent files) — default the interview to the `existing` origin. */
|
|
23
21
|
looksEstablished: boolean;
|
|
24
22
|
}
|
package/dist/lib/detect.js
CHANGED
|
@@ -82,7 +82,6 @@ export function detectRepo(root) {
|
|
|
82
82
|
hasAgentsMd: existsSync(join(root, "AGENTS.md")),
|
|
83
83
|
hasClaudeMd: existsSync(join(root, "CLAUDE.md")),
|
|
84
84
|
hasManifest: existsSync(join(root, MANIFEST_FILENAME)),
|
|
85
|
-
hasMattPocockSetup: existsSync(join(root, "docs", "agents")),
|
|
86
85
|
// A package.json or pre-existing agent files mean there is already a
|
|
87
86
|
// project here to adopt, not a blank slate to start from.
|
|
88
87
|
looksEstablished: hasPackageJson ||
|
package/dist/lib/detect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/lib/detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/lib/detect.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/manifest.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type Mode = (typeof MODES)[number];
|
|
|
8
8
|
*/
|
|
9
9
|
export declare const ORIGINS: readonly ["new", "existing"];
|
|
10
10
|
export type Origin = (typeof ORIGINS)[number];
|
|
11
|
-
export declare const ISSUE_TRACKERS: readonly ["github", "linear", "none"];
|
|
11
|
+
export declare const ISSUE_TRACKERS: readonly ["github", "gitlab", "linear", "local", "none"];
|
|
12
12
|
export type IssueTracker = (typeof ISSUE_TRACKERS)[number];
|
|
13
13
|
export declare const TESTING_KEYS: readonly ["unitCommand", "devCommand", "e2eCommand", "smokeCommand", "appUrl"];
|
|
14
14
|
export type TestingKey = (typeof TESTING_KEYS)[number];
|
|
@@ -38,6 +38,19 @@ export interface ModuleEnableResult {
|
|
|
38
38
|
source: string;
|
|
39
39
|
changed: boolean;
|
|
40
40
|
}
|
|
41
|
+
export interface KeyRemovalResult {
|
|
42
|
+
source: string;
|
|
43
|
+
changed: boolean;
|
|
44
|
+
/** The removed key's value, when the key was present. */
|
|
45
|
+
previous: unknown;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Remove a retired top-level key from an existing manifest source. Like
|
|
49
|
+
* `setModuleEnabled`, this is a deliberate structural exception to "never
|
|
50
|
+
* rewrite seeded files", applied via a YAML document round-trip that preserves
|
|
51
|
+
* the user's comments and formatting.
|
|
52
|
+
*/
|
|
53
|
+
export declare function removeManifestKey(source: string, key: string): KeyRemovalResult;
|
|
41
54
|
/**
|
|
42
55
|
* Enable a module and record testing commands in an existing manifest source.
|
|
43
56
|
*
|
package/dist/lib/manifest.js
CHANGED
|
@@ -7,7 +7,7 @@ export const MODES = ["spike", "standard-mvp", "high-rigor"];
|
|
|
7
7
|
* the code and fill gaps — instead of the from-scratch vision flow (ADR-0013).
|
|
8
8
|
*/
|
|
9
9
|
export const ORIGINS = ["new", "existing"];
|
|
10
|
-
export const ISSUE_TRACKERS = ["github", "linear", "none"];
|
|
10
|
+
export const ISSUE_TRACKERS = ["github", "gitlab", "linear", "local", "none"];
|
|
11
11
|
export const TESTING_KEYS = ["unitCommand", "devCommand", "e2eCommand", "smokeCommand", "appUrl"];
|
|
12
12
|
function isRecord(value) {
|
|
13
13
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -88,6 +88,9 @@ export function validateManifest(data) {
|
|
|
88
88
|
errors.push("modules must map module names to booleans");
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
+
// `implementationLoop` (ADR-0017) was removed by ADR-0020 — Ralph is the
|
|
92
|
+
// loop. Manifests that still carry the key stay valid: unknown keys are
|
|
93
|
+
// ignored here, and the independence migration deletes it.
|
|
91
94
|
if (errors.length > 0)
|
|
92
95
|
return { manifest: null, errors };
|
|
93
96
|
return {
|
|
@@ -118,6 +121,20 @@ export function serializeManifest(manifest) {
|
|
|
118
121
|
"# This file is yours to edit; Launchrail reads it and never force-overwrites it.\n";
|
|
119
122
|
return header + stringify(manifest);
|
|
120
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Remove a retired top-level key from an existing manifest source. Like
|
|
126
|
+
* `setModuleEnabled`, this is a deliberate structural exception to "never
|
|
127
|
+
* rewrite seeded files", applied via a YAML document round-trip that preserves
|
|
128
|
+
* the user's comments and formatting.
|
|
129
|
+
*/
|
|
130
|
+
export function removeManifestKey(source, key) {
|
|
131
|
+
const doc = parseDocument(source);
|
|
132
|
+
if (!doc.has(key))
|
|
133
|
+
return { source, changed: false, previous: undefined };
|
|
134
|
+
const previous = doc.get(key);
|
|
135
|
+
doc.delete(key);
|
|
136
|
+
return { source: doc.toString(), changed: true, previous };
|
|
137
|
+
}
|
|
121
138
|
/**
|
|
122
139
|
* Enable a module and record testing commands in an existing manifest source.
|
|
123
140
|
*
|
package/dist/lib/manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/lib/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAEnD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,YAAY,CAAU,CAAC;AAGtE;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,UAAU,CAAU,CAAC;AAGpD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/lib/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAEnD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,YAAY,CAAU,CAAC;AAGtE;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,UAAU,CAAU,CAAC;AAGpD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAU,CAAC;AAGvF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,CAAU,CAAC;AAoB3G,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAa;IAC5C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,iCAAiC,CAAC,EAAE,CAAC;IACzE,CAAC;IACD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,IAAI,CAAC,aAAa,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,kCAAkC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/F,CAAC;IACD,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAE,KAA2B,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACvF,MAAM,CAAC,IAAI,CAAC,wBAAwB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,4EAA4E;IAC5E,0DAA0D;IAC1D,IAAI,MAAM,GAAW,KAAK,CAAC;IAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAK,OAA6B,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5F,MAAM,GAAG,IAAI,CAAC,MAAgB,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,0BAA0B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,IAAI,YAAY,GAAiB,MAAM,CAAC;IACxC,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACpC,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,IAAK,cAAoC,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;YAC/G,YAAY,GAAG,IAAI,CAAC,YAA4B,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,gCAAgC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,IAAI,mBAAmB,GAAG,IAAI,CAAC;IAC/B,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACnC,IAAI,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,OAAO,IAAI,CAAC,WAAW,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;YAC5F,mBAAmB,GAAG,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC;QAC7D,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAsC;QACjD,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,IAAI;QAChB,UAAU,EAAE,IAAI;QAChB,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,IAAI;KACb,CAAC;IACF,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;gBAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBAChC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;oBAAE,SAAS;gBACpD,IAAI,OAAO,KAAK,KAAK,QAAQ;oBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;;oBAC/C,MAAM,CAAC,IAAI,CAAC,WAAW,GAAG,2BAA2B,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,IAAI,OAAO,GAA4B,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACtD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,EAAE,CAAC;YAC/F,OAAO,GAAG,IAAI,CAAC,OAAkC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,wEAAwE;IACxE,2DAA2D;IAE3D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACzD,OAAO;QACL,QAAQ,EAAE;YACR,aAAa,EAAE,CAAC;YAChB,IAAI,EAAE,IAAI,CAAC,IAAY;YACvB,MAAM;YACN,YAAY;YACZ,WAAW,EAAE,EAAE,mBAAmB,EAAE;YACpC,OAAO;YACP,OAAO;SACR;QACD,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,iBAAiB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3G,CAAC;IACD,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAkB;IAClD,MAAM,MAAM,GACV,wEAAwE;QACxE,oFAAoF,CAAC;IACvF,OAAO,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AACtC,CAAC;AAcD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,GAAW;IAC3D,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IAC1E,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAc,EACd,MAAc,EACd,OAAmD;IAEnD,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC5C,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;QACrC,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,CAAC;YAC1C,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YACnC,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC;AAC7C,CAAC"}
|
package/dist/lib/migrations.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, readFileSync, rmdirSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { sha256 } from "./checksum.js";
|
|
4
|
+
import { applyPluginDeclaration, applyRalphGuardHook, applyRemovePluginDeclaration, CLAUDE_SETTINGS_PATH, planPluginDeclaration, planRalphGuardHook, planRemovePluginDeclaration, RETIRED_SUPERPOWERS_DECLARATION, } from "./claudeSettings.js";
|
|
5
|
+
import { MANIFEST_FILENAME, parseManifest, removeManifestKey, setModuleEnabled } from "./manifest.js";
|
|
6
|
+
import { RALPH_MODULE, RALPH_WORKFLOW_PATH, ralphFiles } from "./ralph.js";
|
|
7
|
+
import { SKILLS_DEST_PREFIX, skillFiles } from "./skills.js";
|
|
8
|
+
import { applyPlan, planWrites } from "./writer.js";
|
|
2
9
|
/**
|
|
3
10
|
* Every structural change ever shipped, in order. Entries must be idempotent —
|
|
4
11
|
* planning against an already-migrated repository yields no changes — and every
|
|
@@ -21,6 +28,39 @@ export const MIGRATIONS = [
|
|
|
21
28
|
};
|
|
22
29
|
},
|
|
23
30
|
},
|
|
31
|
+
{
|
|
32
|
+
// Newest migration, but order-independent, so it sits at its lexicographic
|
|
33
|
+
// position to keep the registry date-ordered rather than at the end.
|
|
34
|
+
id: "2026-08-ralph-permission-guard",
|
|
35
|
+
description: `register Ralph's unattended-launch guard hook in ${CLAUDE_SETTINGS_PATH} (ADR-0021)`,
|
|
36
|
+
plan(ctx) {
|
|
37
|
+
// The guard hook *file* flows through the regular managed-file surface
|
|
38
|
+
// (sync regenerates ralphFiles() after migrations run); this migration only
|
|
39
|
+
// performs the structural change the writer can't express — the additive
|
|
40
|
+
// PreToolUse(Workflow) registration in the shared, project-owned
|
|
41
|
+
// settings.json. Post-ADR-0020 Ralph is the implementation loop, so every
|
|
42
|
+
// valid manifest is a Ralph project (mirroring the wire-default-loop
|
|
43
|
+
// migration below). This runs before that migration in id order, but the
|
|
44
|
+
// hook file it registers still lands in the same sync — whether wire or the
|
|
45
|
+
// managed-file pass writes it.
|
|
46
|
+
const none = { changes: [], apply: () => { } };
|
|
47
|
+
const manifestPath = join(ctx.cwd, MANIFEST_FILENAME);
|
|
48
|
+
if (!existsSync(manifestPath))
|
|
49
|
+
return none;
|
|
50
|
+
const parsed = parseManifest(readFileSync(manifestPath, "utf8"));
|
|
51
|
+
if (!parsed.manifest)
|
|
52
|
+
return none;
|
|
53
|
+
const hook = planRalphGuardHook(ctx.cwd);
|
|
54
|
+
if (hook.content === null)
|
|
55
|
+
return none;
|
|
56
|
+
return {
|
|
57
|
+
changes: [`${CLAUDE_SETTINGS_PATH} — ${hook.detail}`],
|
|
58
|
+
apply: () => {
|
|
59
|
+
applyRalphGuardHook(ctx.cwd, hook);
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
},
|
|
24
64
|
{
|
|
25
65
|
id: "2026-08-upstream-plugin-declarations",
|
|
26
66
|
description: `declare the upstream workflow plugins (Matt Pocock's skills) in ${CLAUDE_SETTINGS_PATH} (ADR-0011)`,
|
|
@@ -38,6 +78,167 @@ export const MIGRATIONS = [
|
|
|
38
78
|
};
|
|
39
79
|
},
|
|
40
80
|
},
|
|
81
|
+
{
|
|
82
|
+
id: "2026-08-vendor-workflow-skills",
|
|
83
|
+
description: `vendor the workflow skills as managed files under .claude/skills/ and remove the retired plugin declarations from ${CLAUDE_SETTINGS_PATH} (ADR-0019)`,
|
|
84
|
+
plan(ctx) {
|
|
85
|
+
// The skill files themselves flow through the regular managed-file surface
|
|
86
|
+
// (sync regenerates it after migrations run); this migration only performs
|
|
87
|
+
// the structural change the writer can't express — stripping the retired
|
|
88
|
+
// launchrail/mattpocock declarations from a consumer's settings.json.
|
|
89
|
+
const removal = planRemovePluginDeclaration(ctx.cwd);
|
|
90
|
+
if (removal.content === null)
|
|
91
|
+
return { changes: [], apply: () => { } };
|
|
92
|
+
return {
|
|
93
|
+
changes: [`${CLAUDE_SETTINGS_PATH} — ${removal.detail}`],
|
|
94
|
+
apply: () => {
|
|
95
|
+
applyRemovePluginDeclaration(ctx.cwd, removal);
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: "2026-08-wire-default-implementation-loop",
|
|
102
|
+
description: "install the built-in implementation loop's materials when the manifest selects ralph, so /launch-implement works without `launchrail add ralph` (ADR-0018)",
|
|
103
|
+
plan(ctx) {
|
|
104
|
+
const none = { changes: [], apply: () => { } };
|
|
105
|
+
const manifestPath = join(ctx.cwd, MANIFEST_FILENAME);
|
|
106
|
+
if (!existsSync(manifestPath))
|
|
107
|
+
return none;
|
|
108
|
+
const source = readFileSync(manifestPath, "utf8");
|
|
109
|
+
const parsed = parseManifest(source);
|
|
110
|
+
// An invalid manifest is sync's own precondition failure, not this
|
|
111
|
+
// migration's. Ralph is the implementation loop (ADR-0020), so every
|
|
112
|
+
// valid manifest gets its materials; before ADR-0020 this checked the
|
|
113
|
+
// manifest's `implementationLoop` selection.
|
|
114
|
+
if (!parsed.manifest)
|
|
115
|
+
return none;
|
|
116
|
+
const changes = [];
|
|
117
|
+
const manifestUpdate = setModuleEnabled(source, RALPH_MODULE, {});
|
|
118
|
+
if (manifestUpdate.changed)
|
|
119
|
+
changes.push(`${MANIFEST_FILENAME} — enable the ralph module`);
|
|
120
|
+
const actions = planWrites(ctx.cwd, ralphFiles(), ctx.lockfile);
|
|
121
|
+
for (const action of actions) {
|
|
122
|
+
if (action.kind === "create" || action.kind === "update") {
|
|
123
|
+
changes.push(`${action.spec.relPath} — ${action.detail}`);
|
|
124
|
+
}
|
|
125
|
+
if (action.kind === "conflict") {
|
|
126
|
+
changes.push(`${RALPH_WORKFLOW_PATH} — local modifications kept (eject or revert to receive updates)`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (changes.length === 0)
|
|
130
|
+
return none;
|
|
131
|
+
return {
|
|
132
|
+
changes,
|
|
133
|
+
apply: () => {
|
|
134
|
+
if (manifestUpdate.changed)
|
|
135
|
+
writeFileSync(manifestPath, manifestUpdate.source, "utf8");
|
|
136
|
+
applyPlan(ctx.cwd, actions, ctx.lockfile);
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
id: "2026-08-workflow-skills-independence",
|
|
143
|
+
description: "retire the vendored upstream skills in favor of Launchrail's own complete launch-* set, and drop the removed implementationLoop manifest field (ADR-0020)",
|
|
144
|
+
plan(ctx) {
|
|
145
|
+
const changes = [];
|
|
146
|
+
// 1. Skill files the surface no longer ships (the vendored bare-name
|
|
147
|
+
// snapshot and its NOTICE): delete each tracked file that is unmodified
|
|
148
|
+
// since Launchrail wrote it; a locally-modified copy is kept on disk and
|
|
149
|
+
// handed to the project. Either way the lockfile stops tracking the
|
|
150
|
+
// path. The absorbed launch-* skills arrive through the regular managed
|
|
151
|
+
// surface right after migrations run — this only clears what they
|
|
152
|
+
// replace.
|
|
153
|
+
const current = new Set(skillFiles().map((spec) => spec.relPath));
|
|
154
|
+
const removable = [];
|
|
155
|
+
const keptModified = [];
|
|
156
|
+
for (const [relPath, entry] of Object.entries(ctx.lockfile.files)) {
|
|
157
|
+
if (!relPath.startsWith(`${SKILLS_DEST_PREFIX}/`) || entry.class === "ejected" || current.has(relPath)) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const abs = join(ctx.cwd, relPath);
|
|
161
|
+
if (existsSync(abs) && sha256(readFileSync(abs, "utf8")) !== entry.checksum) {
|
|
162
|
+
keptModified.push(relPath);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
removable.push(relPath);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (removable.length > 0) {
|
|
169
|
+
changes.push(`${SKILLS_DEST_PREFIX} — remove ${removable.length} retired skill file(s)`);
|
|
170
|
+
}
|
|
171
|
+
for (const relPath of keptModified) {
|
|
172
|
+
changes.push(`${relPath} — locally modified; kept on disk, no longer managed`);
|
|
173
|
+
}
|
|
174
|
+
// 2. The manifest's implementationLoop field is retired — Ralph is the
|
|
175
|
+
// implementation loop, no field selects it.
|
|
176
|
+
const manifestPath = join(ctx.cwd, MANIFEST_FILENAME);
|
|
177
|
+
const manifestSource = existsSync(manifestPath) ? readFileSync(manifestPath, "utf8") : null;
|
|
178
|
+
const keyRemoval = manifestSource === null ? null : removeManifestKey(manifestSource, "implementationLoop");
|
|
179
|
+
if (keyRemoval?.changed) {
|
|
180
|
+
changes.push(`${MANIFEST_FILENAME} — remove the retired implementationLoop field`);
|
|
181
|
+
}
|
|
182
|
+
// 3. A project that had selected superpowers converges on Ralph: the
|
|
183
|
+
// plugin declaration Launchrail added for that loop is removed (only
|
|
184
|
+
// then — a declaration the user added themselves is never touched) and
|
|
185
|
+
// Ralph's materials install.
|
|
186
|
+
const wasSuperpowers = keyRemoval?.previous === "superpowers";
|
|
187
|
+
const settingsRemoval = wasSuperpowers
|
|
188
|
+
? planRemovePluginDeclaration(ctx.cwd, [RETIRED_SUPERPOWERS_DECLARATION])
|
|
189
|
+
: null;
|
|
190
|
+
if (settingsRemoval !== null && settingsRemoval.content !== null) {
|
|
191
|
+
changes.push(`${CLAUDE_SETTINGS_PATH} — ${settingsRemoval.detail}`);
|
|
192
|
+
}
|
|
193
|
+
const ralphEnable = wasSuperpowers && keyRemoval ? setModuleEnabled(keyRemoval.source, RALPH_MODULE, {}) : null;
|
|
194
|
+
if (ralphEnable?.changed) {
|
|
195
|
+
changes.push(`${MANIFEST_FILENAME} — enable the ralph module (superpowers loop retired)`);
|
|
196
|
+
}
|
|
197
|
+
const ralphActions = wasSuperpowers ? planWrites(ctx.cwd, ralphFiles(), ctx.lockfile) : [];
|
|
198
|
+
for (const action of ralphActions) {
|
|
199
|
+
if (action.kind === "create" || action.kind === "update") {
|
|
200
|
+
changes.push(`${action.spec.relPath} — ${action.detail}`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (changes.length === 0)
|
|
204
|
+
return { changes: [], apply: () => { } };
|
|
205
|
+
const skillsRoot = join(ctx.cwd, SKILLS_DEST_PREFIX);
|
|
206
|
+
return {
|
|
207
|
+
changes,
|
|
208
|
+
apply: () => {
|
|
209
|
+
for (const relPath of removable) {
|
|
210
|
+
const abs = join(ctx.cwd, relPath);
|
|
211
|
+
if (existsSync(abs))
|
|
212
|
+
unlinkSync(abs);
|
|
213
|
+
delete ctx.lockfile.files[relPath];
|
|
214
|
+
}
|
|
215
|
+
for (const relPath of keptModified)
|
|
216
|
+
delete ctx.lockfile.files[relPath];
|
|
217
|
+
// Clear the skill directories the deletes emptied, deepest first;
|
|
218
|
+
// rmdir refuses a non-empty directory, which is exactly the guard.
|
|
219
|
+
const dirs = [...new Set(removable.map((relPath) => dirname(join(ctx.cwd, relPath))))].sort((a, b) => b.length - a.length);
|
|
220
|
+
for (const dir of dirs) {
|
|
221
|
+
for (let d = dir; d !== skillsRoot && d.startsWith(skillsRoot); d = dirname(d)) {
|
|
222
|
+
try {
|
|
223
|
+
rmdirSync(d);
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const manifestFinal = ralphEnable ?? keyRemoval;
|
|
231
|
+
if (manifestFinal && (keyRemoval?.changed || ralphEnable?.changed)) {
|
|
232
|
+
writeFileSync(manifestPath, manifestFinal.source, "utf8");
|
|
233
|
+
}
|
|
234
|
+
if (settingsRemoval !== null)
|
|
235
|
+
applyRemovePluginDeclaration(ctx.cwd, settingsRemoval);
|
|
236
|
+
if (ralphActions.length > 0)
|
|
237
|
+
applyPlan(ctx.cwd, ralphActions, ctx.lockfile);
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
},
|
|
241
|
+
},
|
|
41
242
|
];
|
|
42
243
|
export function migrationIds(registry = MIGRATIONS) {
|
|
43
244
|
return registry.map((migration) => migration.id);
|