@wildorder/nightshift 0.1.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 (57) hide show
  1. package/dist/cli.js +252 -10
  2. package/dist/cli.js.map +1 -1
  3. package/dist/config.d.ts +4 -0
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +7 -0
  6. package/dist/config.js.map +1 -1
  7. package/dist/decision-ledger.d.ts +68 -0
  8. package/dist/decision-ledger.d.ts.map +1 -0
  9. package/dist/decision-ledger.js +108 -0
  10. package/dist/decision-ledger.js.map +1 -0
  11. package/dist/decision.d.ts +59 -0
  12. package/dist/decision.d.ts.map +1 -0
  13. package/dist/decision.js +0 -0
  14. package/dist/decision.js.map +1 -0
  15. package/dist/index.d.ts +9 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +9 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/init-project.d.ts +18 -0
  20. package/dist/init-project.d.ts.map +1 -0
  21. package/dist/init-project.js +259 -0
  22. package/dist/init-project.js.map +1 -0
  23. package/dist/install-prefs.d.ts +17 -0
  24. package/dist/install-prefs.d.ts.map +1 -0
  25. package/dist/install-prefs.js +55 -0
  26. package/dist/install-prefs.js.map +1 -0
  27. package/dist/install-skills.d.ts +83 -0
  28. package/dist/install-skills.d.ts.map +1 -0
  29. package/dist/install-skills.js +311 -0
  30. package/dist/install-skills.js.map +1 -0
  31. package/dist/install-wizard.d.ts +56 -0
  32. package/dist/install-wizard.d.ts.map +1 -0
  33. package/dist/install-wizard.js +166 -0
  34. package/dist/install-wizard.js.map +1 -0
  35. package/dist/manifest.d.ts +76 -0
  36. package/dist/manifest.d.ts.map +1 -0
  37. package/dist/manifest.js +95 -0
  38. package/dist/manifest.js.map +1 -0
  39. package/dist/package-assets.d.ts +3 -0
  40. package/dist/package-assets.d.ts.map +1 -0
  41. package/dist/package-assets.js +13 -0
  42. package/dist/package-assets.js.map +1 -0
  43. package/dist/run-program.d.ts +72 -0
  44. package/dist/run-program.d.ts.map +1 -0
  45. package/dist/run-program.js +482 -0
  46. package/dist/run-program.js.map +1 -0
  47. package/dist/skill-roots.d.ts +51 -0
  48. package/dist/skill-roots.d.ts.map +1 -0
  49. package/dist/skill-roots.js +181 -0
  50. package/dist/skill-roots.js.map +1 -0
  51. package/package.json +3 -1
  52. package/skills/init-project/SKILL.md +196 -0
  53. package/skills/plan-program/SKILL.md +274 -0
  54. package/templates/AGENTS.md +29 -0
  55. package/templates/CLAUDE.md +7 -0
  56. package/templates/universal-directives.md +50 -0
  57. package/templates/vision.md +46 -0
@@ -0,0 +1,311 @@
1
+ import { createHash } from "node:crypto";
2
+ import { mkdir, readFile, rm, rmdir, writeFile } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { dirname, join, resolve } from "node:path";
5
+ import { PACKAGE_ROOT } from "./package-assets.js";
6
+ import { detectTargets, pathExists, scanRoots, } from "./skill-roots.js";
7
+ export { ALL_TARGETS, DEFAULT_TARGETS, detectTargets, overrideEnvName, parseRootOverrides, parseTargets, } from "./skill-roots.js";
8
+ /**
9
+ * The skills that ship: the two human-judgment steps that sit outside the
10
+ * automated loop — deciding how the project is set up, and deciding what to
11
+ * build. Everything downstream of planning is a CLI command that composes
12
+ * its own brief and spawns clean agents.
13
+ */
14
+ export const WORKFLOWS = ["init-project", "plan-program"];
15
+ /**
16
+ * Skills this package used to install and now removes. Empty so far — kept
17
+ * because the mechanism matters: a retired skill left in a skills directory
18
+ * keeps instructing an agent to do work that has since moved into a command.
19
+ * Never list another package's skills here (program-pipeline's included);
20
+ * retirement is only for names this package itself installed.
21
+ */
22
+ export const RETIRED_WORKFLOWS = [];
23
+ /** Every name this package has ever installed, for scanning and cleanup. */
24
+ const ALL_KNOWN_WORKFLOWS = [
25
+ ...WORKFLOWS,
26
+ ...RETIRED_WORKFLOWS,
27
+ ];
28
+ const MARKER_PATTERN = /<!-- nightshift:sha256=([a-f0-9]{64}) -->\n?/u;
29
+ const COMMAND_EXTENSIONS = [".md", ".mdc", ".markdown", ".txt"];
30
+ function normalize(content) {
31
+ return content.replaceAll("\r\n", "\n");
32
+ }
33
+ function digest(content) {
34
+ return createHash("sha256").update(normalize(content)).digest("hex");
35
+ }
36
+ function withMarker(source) {
37
+ const normalized = normalize(source);
38
+ const marker = `<!-- nightshift:sha256=${digest(normalized)} -->\n`;
39
+ const frontmatterEnd = normalized.indexOf("\n---\n", 4);
40
+ if (!normalized.startsWith("---\n") || frontmatterEnd < 0) {
41
+ throw new Error("Skill must contain YAML frontmatter.");
42
+ }
43
+ const insertAt = frontmatterEnd + 5;
44
+ return `${normalized.slice(0, insertAt)}${marker}${normalized.slice(insertAt)}`;
45
+ }
46
+ function generatedFileIsUnmodified(content) {
47
+ const normalized = normalize(content);
48
+ const marker = normalized.match(MARKER_PATTERN);
49
+ if (!marker?.[1])
50
+ return false;
51
+ const withoutMarker = normalized.replace(MARKER_PATTERN, "");
52
+ return digest(withoutMarker) === marker[1];
53
+ }
54
+ function pathKey(path) {
55
+ return process.platform === "win32" ? path.toLowerCase() : path;
56
+ }
57
+ async function findDefinitionWarnings(projectRoot, userHome, detected, targets, destinations) {
58
+ const warnings = [];
59
+ const seen = new Set();
60
+ const selected = detected.filter((entry) => targets.includes(entry.target));
61
+ for (const location of scanRoots(selected, projectRoot, userHome)) {
62
+ for (const workflow of ALL_KNOWN_WORKFLOWS) {
63
+ const candidates = location.kind === "skill"
64
+ ? [join(location.root, workflow, "SKILL.md")]
65
+ : COMMAND_EXTENSIONS.map((extension) => join(location.root, `${workflow}${extension}`));
66
+ for (const candidate of candidates) {
67
+ const key = pathKey(candidate);
68
+ if (destinations.has(key) ||
69
+ seen.has(key) ||
70
+ !(await pathExists(candidate))) {
71
+ continue;
72
+ }
73
+ seen.add(key);
74
+ const content = await readFile(candidate, "utf8");
75
+ warnings.push({
76
+ workflow,
77
+ kind: location.kind,
78
+ scope: location.scope,
79
+ target: location.target,
80
+ path: location.scope === "project"
81
+ ? join(".", candidate.slice(projectRoot.length + 1))
82
+ : candidate,
83
+ packageManaged: location.kind === "skill" && generatedFileIsUnmodified(content),
84
+ });
85
+ }
86
+ }
87
+ }
88
+ return warnings;
89
+ }
90
+ /** Best-effort cleanup so pruning does not leave empty scaffolding behind. */
91
+ async function removeIfEmpty(path) {
92
+ try {
93
+ await rmdir(path);
94
+ }
95
+ catch {
96
+ // Still has content, or never existed. Either way there is nothing to do.
97
+ }
98
+ }
99
+ /**
100
+ * Project-scope skill files for the given targets. Project skills shadow
101
+ * user-scope ones, so the caller needs this before a user-scope install to
102
+ * know whether the install would actually take effect.
103
+ */
104
+ export async function findProjectCopies(cwd, targets, options = {}) {
105
+ const root = resolve(cwd);
106
+ const detected = await detectTargets({
107
+ home: resolve(options.home ?? homedir()),
108
+ ...(options.env ? { env: options.env } : {}),
109
+ ...(options.roots ? { roots: options.roots } : {}),
110
+ });
111
+ const copies = { managed: [], modified: [] };
112
+ for (const entry of detected) {
113
+ if (!targets.includes(entry.target))
114
+ continue;
115
+ for (const workflow of ALL_KNOWN_WORKFLOWS) {
116
+ const label = join(entry.projectRoot, workflow, "SKILL.md");
117
+ const path = join(root, label);
118
+ if (!(await pathExists(path)))
119
+ continue;
120
+ if (generatedFileIsUnmodified(await readFile(path, "utf8"))) {
121
+ copies.managed.push(label);
122
+ }
123
+ else {
124
+ copies.modified.push(label);
125
+ }
126
+ }
127
+ }
128
+ return copies;
129
+ }
130
+ async function pruneProjectCopies(projectRoot, detected, targets, result) {
131
+ for (const entry of detected) {
132
+ if (!targets.includes(entry.target))
133
+ continue;
134
+ const skillsRoot = join(projectRoot, entry.projectRoot);
135
+ for (const workflow of ALL_KNOWN_WORKFLOWS) {
136
+ const path = join(skillsRoot, workflow, "SKILL.md");
137
+ if (!(await pathExists(path)))
138
+ continue;
139
+ const label = join(entry.projectRoot, workflow, "SKILL.md");
140
+ if (generatedFileIsUnmodified(await readFile(path, "utf8"))) {
141
+ await rm(path);
142
+ await removeIfEmpty(dirname(path));
143
+ result.pruned.push(label);
144
+ }
145
+ else {
146
+ result.pruneSkipped.push(label);
147
+ }
148
+ }
149
+ await removeIfEmpty(skillsRoot);
150
+ }
151
+ }
152
+ /**
153
+ * Remove retired skills from **both** scopes, whatever scope this run is
154
+ * installing into.
155
+ *
156
+ * Scoping this to the install's own scopes was wrong: a stale skill almost
157
+ * always sits in the scope you *stopped* using. A project installed before
158
+ * the move to user-scope defaults keeps its project copies, and a later
159
+ * user-scope install would never look at them — leaving the retired skills
160
+ * exactly where the agent still reads them.
161
+ *
162
+ * Called only after a successful install, for the same reason pruning is: a
163
+ * run that aborted on a conflict must not have deleted anything.
164
+ */
165
+ async function retireWorkflows(projectRoot, detected, targets, result) {
166
+ const scopes = ["user", "project"];
167
+ const seen = new Set();
168
+ for (const entry of detected) {
169
+ if (!targets.includes(entry.target))
170
+ continue;
171
+ for (const scope of scopes) {
172
+ const skillsRoot = scope === "user"
173
+ ? entry.userRoot
174
+ : join(projectRoot, entry.projectRoot);
175
+ for (const workflow of RETIRED_WORKFLOWS) {
176
+ const path = join(skillsRoot, workflow, "SKILL.md");
177
+ const key = pathKey(path);
178
+ // Root overrides can point two targets at one directory.
179
+ if (seen.has(key))
180
+ continue;
181
+ seen.add(key);
182
+ if (!(await pathExists(path)))
183
+ continue;
184
+ const label = scope === "user"
185
+ ? path
186
+ : join(entry.projectRoot, workflow, "SKILL.md");
187
+ if (generatedFileIsUnmodified(await readFile(path, "utf8"))) {
188
+ await rm(path);
189
+ await removeIfEmpty(dirname(path));
190
+ result.retired.push(label);
191
+ }
192
+ else {
193
+ result.retiredKept.push(label);
194
+ }
195
+ }
196
+ }
197
+ }
198
+ }
199
+ export async function installSkills(input) {
200
+ const root = resolve(input.cwd);
201
+ const userHome = resolve(input.home ?? homedir());
202
+ const scopes = input.scopes ?? ["project"];
203
+ const result = {
204
+ installed: [],
205
+ updated: [],
206
+ skipped: [],
207
+ conflicts: [],
208
+ warnings: [],
209
+ pruned: [],
210
+ pruneSkipped: [],
211
+ retired: [],
212
+ retiredKept: [],
213
+ aborted: false,
214
+ };
215
+ const detected = await detectTargets({
216
+ home: userHome,
217
+ ...(input.env ? { env: input.env } : {}),
218
+ ...(input.roots ? { roots: input.roots } : {}),
219
+ });
220
+ const byTarget = new Map(detected.map((entry) => [entry.target, entry]));
221
+ const plans = [];
222
+ const planned = new Set();
223
+ for (const scope of scopes) {
224
+ for (const target of input.targets) {
225
+ const entry = byTarget.get(target);
226
+ if (!entry)
227
+ continue;
228
+ const skillsRoot = scope === "user" ? entry.userRoot : join(root, entry.projectRoot);
229
+ for (const workflow of WORKFLOWS) {
230
+ const destination = join(skillsRoot, workflow, "SKILL.md");
231
+ const key = pathKey(destination);
232
+ // Overrides can point two targets at one directory; write it once.
233
+ if (planned.has(key))
234
+ continue;
235
+ planned.add(key);
236
+ const label = scope === "user"
237
+ ? destination
238
+ : join(entry.projectRoot, workflow, "SKILL.md");
239
+ const source = await readFile(join(PACKAGE_ROOT, "skills", workflow, "SKILL.md"), "utf8");
240
+ const desired = withMarker(source);
241
+ if (!(await pathExists(destination))) {
242
+ plans.push({ label, destination, desired, action: "install" });
243
+ continue;
244
+ }
245
+ const current = await readFile(destination, "utf8");
246
+ if (normalize(current) === desired) {
247
+ plans.push({ label, destination, desired, action: "skip" });
248
+ }
249
+ else if (input.force || generatedFileIsUnmodified(current)) {
250
+ plans.push({ label, destination, desired, action: "update" });
251
+ }
252
+ else {
253
+ plans.push({ label, destination, desired, action: "conflict" });
254
+ }
255
+ }
256
+ }
257
+ }
258
+ result.warnings = await findDefinitionWarnings(root, userHome, detected, input.targets, planned);
259
+ result.conflicts = plans
260
+ .filter(({ action }) => action === "conflict")
261
+ .map(({ label }) => label);
262
+ result.skipped = plans
263
+ .filter(({ action }) => action === "skip")
264
+ .map(({ label }) => label);
265
+ if (result.conflicts.length > 0) {
266
+ result.aborted = true;
267
+ return result;
268
+ }
269
+ for (const plan of plans) {
270
+ if (plan.action === "install") {
271
+ await mkdir(dirname(plan.destination), { recursive: true });
272
+ await writeFile(plan.destination, plan.desired, "utf8");
273
+ result.installed.push(plan.label);
274
+ }
275
+ else if (plan.action === "update") {
276
+ await writeFile(plan.destination, plan.desired, "utf8");
277
+ result.updated.push(plan.label);
278
+ }
279
+ }
280
+ // Retired skills go from both scopes regardless of where this run installs:
281
+ // a stale copy anywhere keeps telling an agent to do work that is now a
282
+ // command.
283
+ await retireWorkflows(root, detected, input.targets, result);
284
+ // Only after a clean user-scope install: pruning first would delete the
285
+ // developer's working skills if the install then aborted.
286
+ if (input.pruneProject && scopes.includes("user") && !scopes.includes("project")) {
287
+ await pruneProjectCopies(root, detected, input.targets, result);
288
+ }
289
+ return result;
290
+ }
291
+ export async function doctor() {
292
+ const problems = [];
293
+ for (const workflow of WORKFLOWS) {
294
+ const path = join(PACKAGE_ROOT, "skills", workflow, "SKILL.md");
295
+ if (!(await pathExists(path))) {
296
+ problems.push(`Missing packaged skill: ${workflow}`);
297
+ }
298
+ }
299
+ for (const template of [
300
+ "vision.md",
301
+ "AGENTS.md",
302
+ "CLAUDE.md",
303
+ "universal-directives.md",
304
+ ]) {
305
+ if (!(await pathExists(join(PACKAGE_ROOT, "templates", template)))) {
306
+ problems.push(`Missing packaged template: ${template}`);
307
+ }
308
+ }
309
+ return problems;
310
+ }
311
+ //# sourceMappingURL=install-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-skills.js","sourceRoot":"","sources":["../src/install-skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import { type PreferredScope } from "./install-prefs.js";
2
+ import { type PromptStreams } from "./prompt.js";
3
+ import { type DetectedTarget, type InstallScope, type SkillTarget } from "./skill-roots.js";
4
+ export interface SkillPlanOptions {
5
+ cwd: string;
6
+ /** From `--targets`; presence alone suppresses the wizard. */
7
+ explicitTargets?: SkillTarget[];
8
+ /** From `--scope`. */
9
+ explicitScope?: PreferredScope;
10
+ /** From `--prune` / `--no-prune`. */
11
+ explicitPrune?: boolean;
12
+ /** From `--root <target>=<path>`. */
13
+ roots?: Partial<Record<SkillTarget, string>>;
14
+ /** From `--yes`: take the detected defaults without asking. */
15
+ yes?: boolean;
16
+ home?: string;
17
+ env?: NodeJS.ProcessEnv;
18
+ streams?: PromptStreams;
19
+ log?: (line: string) => void;
20
+ }
21
+ export interface SkillPlan {
22
+ targets: SkillTarget[];
23
+ scopes: InstallScope[];
24
+ pruneProject: boolean;
25
+ /** True when the user backed out; the caller must not write anything. */
26
+ cancelled: boolean;
27
+ detected: DetectedTarget[];
28
+ }
29
+ /** The option surface `install` and `setup` share, as plain values. */
30
+ export interface InstallArgvOptions {
31
+ cwd: string;
32
+ targets?: string;
33
+ scope?: string;
34
+ root: string[];
35
+ force: boolean;
36
+ yes: boolean;
37
+ prune?: boolean;
38
+ }
39
+ /**
40
+ * Rebuild a run's skill options as an `install` argv, so `setup` can hand off
41
+ * to the CLI it just installed rather than continuing in its own process —
42
+ * where the code in memory predates the files on disk.
43
+ *
44
+ * Every option must survive the round trip. Dropping `--scope` here would
45
+ * silently install to a different root than the user asked for, which is the
46
+ * exact class of failure this handoff exists to prevent.
47
+ */
48
+ export declare function installArgv(options: InstallArgvOptions, pruneCameFromCli: boolean): string[];
49
+ export declare function scopesFor(scope: PreferredScope): InstallScope[];
50
+ /**
51
+ * Decide what to install and where. Interactive only when a human is on both
52
+ * ends of the terminal and has not already answered on the command line;
53
+ * every other path resolves silently from detection and saved preferences.
54
+ */
55
+ export declare function planSkillInstall(options: SkillPlanOptions): Promise<SkillPlan>;
56
+ //# sourceMappingURL=install-wizard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-wizard.d.ts","sourceRoot":"","sources":["../src/install-wizard.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,8DAA8D;IAC9D,eAAe,CAAC,EAAE,WAAW,EAAE,CAAC;IAChC,sBAAsB;IACtB,aAAa,CAAC,EAAE,cAAc,CAAC;IAC/B,qCAAqC;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qCAAqC;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,+DAA+D;IAC/D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED,uEAAuE;AACvE,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,kBAAkB,EAC3B,gBAAgB,EAAE,OAAO,GACxB,MAAM,EAAE,CAUV;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,EAAE,CAG/D;AAMD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,SAAS,CAAC,CA8HpB"}
@@ -0,0 +1,166 @@
1
+ import { homedir } from "node:os";
2
+ import { resolve } from "node:path";
3
+ import { loadInstallPrefs, saveInstallPrefs, } from "./install-prefs.js";
4
+ import { findProjectCopies } from "./install-skills.js";
5
+ import { chooseMany, chooseOne, confirm, defaultStreams, isInteractive, } from "./prompt.js";
6
+ import { ALL_TARGETS, detectTargets, } from "./skill-roots.js";
7
+ /**
8
+ * Rebuild a run's skill options as an `install` argv, so `setup` can hand off
9
+ * to the CLI it just installed rather than continuing in its own process —
10
+ * where the code in memory predates the files on disk.
11
+ *
12
+ * Every option must survive the round trip. Dropping `--scope` here would
13
+ * silently install to a different root than the user asked for, which is the
14
+ * exact class of failure this handoff exists to prevent.
15
+ */
16
+ export function installArgv(options, pruneCameFromCli) {
17
+ const argv = ["install", "--cwd", options.cwd];
18
+ if (options.targets !== undefined)
19
+ argv.push("--targets", options.targets);
20
+ if (options.scope !== undefined)
21
+ argv.push("--scope", options.scope);
22
+ for (const override of options.root)
23
+ argv.push("--root", override);
24
+ if (options.force)
25
+ argv.push("--force");
26
+ if (options.yes)
27
+ argv.push("--yes");
28
+ // Commander gives --prune a value either way, so only forward a real one.
29
+ if (pruneCameFromCli)
30
+ argv.push(options.prune ? "--prune" : "--no-prune");
31
+ return argv;
32
+ }
33
+ export function scopesFor(scope) {
34
+ if (scope === "both")
35
+ return ["user", "project"];
36
+ return [scope];
37
+ }
38
+ function describeScope(scopes) {
39
+ return scopes.length === 2 ? "user and project" : (scopes[0] ?? "project");
40
+ }
41
+ /**
42
+ * Decide what to install and where. Interactive only when a human is on both
43
+ * ends of the terminal and has not already answered on the command line;
44
+ * every other path resolves silently from detection and saved preferences.
45
+ */
46
+ export async function planSkillInstall(options) {
47
+ const env = options.env ?? process.env;
48
+ const home = resolve(options.home ?? homedir());
49
+ const streams = options.streams ?? defaultStreams();
50
+ const log = options.log ?? ((line) => console.log(line));
51
+ const detected = await detectTargets({
52
+ home,
53
+ env,
54
+ ...(options.roots ? { roots: options.roots } : {}),
55
+ });
56
+ const present = detected.filter((entry) => entry.detected);
57
+ // With nothing detected — a fresh container, an unusual layout — installing
58
+ // everything is the old behavior and beats a silent no-op.
59
+ const fallbackTargets = present.length > 0 ? present.map((entry) => entry.target) : [...ALL_TARGETS];
60
+ const prefs = await loadInstallPrefs(home);
61
+ const interactive = !options.explicitTargets &&
62
+ !options.yes &&
63
+ isInteractive(streams, env);
64
+ if (!interactive) {
65
+ const targets = options.explicitTargets ?? prefs?.targets ?? fallbackTargets;
66
+ const scopes = scopesFor(options.explicitScope ?? prefs?.scope ?? "user");
67
+ if (!options.explicitTargets) {
68
+ const source = prefs ? "saved preferences" : "detected tools";
69
+ log(`installing to ${targets.join(", ")} at ${describeScope(scopes)} scope ` +
70
+ `(non-interactive, from ${source}; pass --targets or --scope to override)`);
71
+ }
72
+ return {
73
+ targets,
74
+ scopes,
75
+ pruneProject: options.explicitPrune ?? false,
76
+ cancelled: false,
77
+ detected,
78
+ };
79
+ }
80
+ const chosen = await chooseMany({
81
+ title: "Where should the workflow skills go?",
82
+ choices: detected.map((entry) => ({
83
+ value: entry.target,
84
+ label: entry.label,
85
+ hint: entry.detected
86
+ ? entry.userRoot
87
+ : `${entry.userRoot} (not detected)`,
88
+ })),
89
+ initial: prefs?.targets ?? fallbackTargets,
90
+ streams,
91
+ env,
92
+ });
93
+ if (!chosen)
94
+ return emptyPlan(detected);
95
+ if (chosen.length === 0) {
96
+ log("no targets selected; nothing to install");
97
+ return emptyPlan(detected);
98
+ }
99
+ let scope = options.explicitScope;
100
+ if (!scope) {
101
+ const picked = await chooseOne({
102
+ title: "Install for this machine or just this project?",
103
+ choices: [
104
+ {
105
+ value: "user",
106
+ label: "This machine",
107
+ hint: "one update covers every repository",
108
+ },
109
+ {
110
+ value: "project",
111
+ label: "This project",
112
+ hint: "checked into the repo, pinned per project",
113
+ },
114
+ { value: "both", label: "Both", hint: "project copies shadow machine ones" },
115
+ ],
116
+ initial: prefs?.scope ?? "user",
117
+ streams,
118
+ env,
119
+ });
120
+ if (!picked)
121
+ return emptyPlan(detected);
122
+ scope = picked;
123
+ }
124
+ const scopes = scopesFor(scope);
125
+ let pruneProject = options.explicitPrune ?? false;
126
+ // Only worth asking when project copies would shadow what we just installed.
127
+ if (options.explicitPrune === undefined &&
128
+ scopes.includes("user") &&
129
+ !scopes.includes("project")) {
130
+ const copies = await findProjectCopies(options.cwd, chosen, {
131
+ home,
132
+ env,
133
+ ...(options.roots ? { roots: options.roots } : {}),
134
+ });
135
+ if (copies.managed.length > 0) {
136
+ const answer = await confirm({
137
+ title: `Found ${copies.managed.length} project-scope skill file(s) in this repo. ` +
138
+ "They shadow the machine-wide ones. Remove them?",
139
+ initial: true,
140
+ streams,
141
+ env,
142
+ });
143
+ if (answer === undefined)
144
+ return emptyPlan(detected);
145
+ pruneProject = answer;
146
+ }
147
+ if (copies.modified.length > 0) {
148
+ log(`note ${copies.modified.length} edited project-scope skill file(s) will be left in place and keep shadowing:`);
149
+ for (const path of copies.modified)
150
+ log(` ${path}`);
151
+ }
152
+ }
153
+ const savedTo = await saveInstallPrefs({ targets: chosen, scope }, home);
154
+ log(`saved install preferences to ${savedTo}`);
155
+ return { targets: chosen, scopes, pruneProject, cancelled: false, detected };
156
+ }
157
+ function emptyPlan(detected) {
158
+ return {
159
+ targets: [],
160
+ scopes: [],
161
+ pruneProject: false,
162
+ cancelled: true,
163
+ detected,
164
+ };
165
+ }
166
+ //# sourceMappingURL=install-wizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-wizard.js","sourceRoot":"","sources":["../src/install-wizard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * The program manifest: the single canonical home for success criteria, the
4
+ * workstream roster, dependencies, and scope. `/plan-program` writes it; the
5
+ * runner reads it and writes workstream status back. Narrative belongs in
6
+ * the program document, never here — one canonical home per fact.
7
+ */
8
+ export declare const WORKSTREAM_STATUSES: readonly ["not_started", "in_progress", "complete", "failed", "parked"];
9
+ export type WorkstreamStatus = (typeof WORKSTREAM_STATUSES)[number];
10
+ declare const workstreamSchema: z.ZodObject<{
11
+ id: z.ZodString;
12
+ name: z.ZodString;
13
+ taskFile: z.ZodString;
14
+ status: z.ZodDefault<z.ZodEnum<{
15
+ not_started: "not_started";
16
+ in_progress: "in_progress";
17
+ complete: "complete";
18
+ failed: "failed";
19
+ parked: "parked";
20
+ }>>;
21
+ size: z.ZodOptional<z.ZodString>;
22
+ scope: z.ZodOptional<z.ZodObject<{
23
+ summary: z.ZodString;
24
+ includes: z.ZodDefault<z.ZodArray<z.ZodString>>;
25
+ excludes: z.ZodDefault<z.ZodArray<z.ZodString>>;
26
+ }, z.core.$strip>>;
27
+ dependencies: z.ZodDefault<z.ZodArray<z.ZodString>>;
28
+ packages: z.ZodDefault<z.ZodArray<z.ZodString>>;
29
+ }, z.core.$strip>;
30
+ declare const manifestSchema: z.ZodObject<{
31
+ program: z.ZodObject<{
32
+ id: z.ZodString;
33
+ name: z.ZodString;
34
+ description: z.ZodOptional<z.ZodString>;
35
+ status: z.ZodOptional<z.ZodString>;
36
+ created: z.ZodOptional<z.ZodString>;
37
+ executionMode: z.ZodOptional<z.ZodEnum<{
38
+ atomic: "atomic";
39
+ orchestrated: "orchestrated";
40
+ }>>;
41
+ executionModeReason: z.ZodOptional<z.ZodString>;
42
+ }, z.core.$loose>;
43
+ successCriteria: z.ZodDefault<z.ZodArray<z.ZodObject<{
44
+ id: z.ZodString;
45
+ description: z.ZodString;
46
+ }, z.core.$loose>>>;
47
+ packages: z.ZodDefault<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
48
+ workstreams: z.ZodArray<z.ZodObject<{
49
+ id: z.ZodString;
50
+ name: z.ZodString;
51
+ taskFile: z.ZodString;
52
+ status: z.ZodDefault<z.ZodEnum<{
53
+ not_started: "not_started";
54
+ in_progress: "in_progress";
55
+ complete: "complete";
56
+ failed: "failed";
57
+ parked: "parked";
58
+ }>>;
59
+ size: z.ZodOptional<z.ZodString>;
60
+ scope: z.ZodOptional<z.ZodObject<{
61
+ summary: z.ZodString;
62
+ includes: z.ZodDefault<z.ZodArray<z.ZodString>>;
63
+ excludes: z.ZodDefault<z.ZodArray<z.ZodString>>;
64
+ }, z.core.$strip>>;
65
+ dependencies: z.ZodDefault<z.ZodArray<z.ZodString>>;
66
+ packages: z.ZodDefault<z.ZodArray<z.ZodString>>;
67
+ }, z.core.$loose>>;
68
+ outOfScope: z.ZodDefault<z.ZodArray<z.ZodString>>;
69
+ }, z.core.$loose>;
70
+ export type Workstream = z.infer<typeof workstreamSchema>;
71
+ export type ProgramManifest = z.infer<typeof manifestSchema>;
72
+ export declare function manifestPath(root: string, programId: string): string;
73
+ export declare function loadManifest(root: string, programId: string): Promise<ProgramManifest>;
74
+ export declare function saveManifest(root: string, programId: string, manifest: ProgramManifest): Promise<void>;
75
+ export {};
76
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;GAKG;AAEH,eAAO,MAAM,mBAAmB,yEAMtB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAQpE,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;iBASpB,CAAC;AAEH,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsBV,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE7D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAOpE;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAyC1B;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,IAAI,CAAC,CAMf"}