@g3nomaly/core 0.1.6 → 0.2.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 (93) hide show
  1. package/dist/cli/commands/add.d.ts +17 -0
  2. package/dist/cli/commands/add.d.ts.map +1 -0
  3. package/dist/cli/commands/add.js +76 -0
  4. package/dist/cli/commands/add.js.map +1 -0
  5. package/dist/cli/commands/ls.d.ts +5 -0
  6. package/dist/cli/commands/ls.d.ts.map +1 -0
  7. package/dist/cli/commands/ls.js +22 -0
  8. package/dist/cli/commands/ls.js.map +1 -0
  9. package/dist/cli/commands/remove.d.ts +13 -0
  10. package/dist/cli/commands/remove.d.ts.map +1 -0
  11. package/dist/cli/commands/remove.js +109 -0
  12. package/dist/cli/commands/remove.js.map +1 -0
  13. package/dist/cli/commands/update.d.ts +10 -0
  14. package/dist/cli/commands/update.d.ts.map +1 -0
  15. package/dist/cli/commands/update.js +92 -0
  16. package/dist/cli/commands/update.js.map +1 -0
  17. package/dist/cli/dialogue.d.ts +74 -0
  18. package/dist/cli/dialogue.d.ts.map +1 -0
  19. package/dist/cli/dialogue.js +117 -0
  20. package/dist/cli/dialogue.js.map +1 -0
  21. package/dist/cli/index.d.ts +10 -0
  22. package/dist/cli/index.d.ts.map +1 -0
  23. package/dist/cli/index.js +10 -0
  24. package/dist/cli/index.js.map +1 -0
  25. package/dist/cli/theme.d.ts +23 -0
  26. package/dist/cli/theme.d.ts.map +1 -0
  27. package/dist/cli/theme.js +25 -0
  28. package/dist/cli/theme.js.map +1 -0
  29. package/dist/cli/types.d.ts +45 -0
  30. package/dist/cli/types.d.ts.map +1 -0
  31. package/dist/cli/types.js +2 -0
  32. package/dist/cli/types.js.map +1 -0
  33. package/dist/config/config.d.ts +7 -10
  34. package/dist/config/config.d.ts.map +1 -1
  35. package/dist/config/config.js +17 -27
  36. package/dist/config/config.js.map +1 -1
  37. package/dist/config/index.d.ts +3 -3
  38. package/dist/config/index.d.ts.map +1 -1
  39. package/dist/config/index.js +2 -2
  40. package/dist/config/index.js.map +1 -1
  41. package/dist/config/types.d.ts +35 -36
  42. package/dist/config/types.d.ts.map +1 -1
  43. package/dist/config/types.js +14 -17
  44. package/dist/config/types.js.map +1 -1
  45. package/dist/installer/classify.d.ts +7 -0
  46. package/dist/installer/classify.d.ts.map +1 -0
  47. package/dist/installer/classify.js +47 -0
  48. package/dist/installer/classify.js.map +1 -0
  49. package/dist/installer/index.d.ts +6 -0
  50. package/dist/installer/index.d.ts.map +1 -0
  51. package/dist/installer/index.js +7 -0
  52. package/dist/installer/index.js.map +1 -0
  53. package/dist/installer/install.d.ts +13 -0
  54. package/dist/installer/install.d.ts.map +1 -0
  55. package/dist/installer/install.js +61 -0
  56. package/dist/installer/install.js.map +1 -0
  57. package/dist/installer/io.d.ts +4 -0
  58. package/dist/installer/io.d.ts.map +1 -0
  59. package/dist/installer/io.js +18 -0
  60. package/dist/installer/io.js.map +1 -0
  61. package/dist/installer/remove.d.ts +14 -0
  62. package/dist/installer/remove.d.ts.map +1 -0
  63. package/dist/installer/remove.js +37 -0
  64. package/dist/installer/remove.js.map +1 -0
  65. package/dist/installer/types.d.ts +80 -0
  66. package/dist/installer/types.d.ts.map +1 -0
  67. package/dist/installer/types.js +21 -0
  68. package/dist/installer/types.js.map +1 -0
  69. package/dist/registry/registry.selectors.d.ts +11 -0
  70. package/dist/registry/registry.selectors.d.ts.map +1 -1
  71. package/dist/registry/registry.selectors.js +24 -0
  72. package/dist/registry/registry.selectors.js.map +1 -1
  73. package/dist/registry/types.d.ts +2 -0
  74. package/dist/registry/types.d.ts.map +1 -1
  75. package/dist/registry/types.js +5 -0
  76. package/dist/registry/types.js.map +1 -1
  77. package/dist/utils/index.d.ts +3 -0
  78. package/dist/utils/index.d.ts.map +1 -1
  79. package/dist/utils/index.js +2 -0
  80. package/dist/utils/index.js.map +1 -1
  81. package/dist/utils/merge.d.ts +6 -0
  82. package/dist/utils/merge.d.ts.map +1 -0
  83. package/dist/utils/merge.js +21 -0
  84. package/dist/utils/merge.js.map +1 -0
  85. package/dist/utils/packageMeta.d.ts +12 -0
  86. package/dist/utils/packageMeta.d.ts.map +1 -0
  87. package/dist/utils/packageMeta.js +20 -0
  88. package/dist/utils/packageMeta.js.map +1 -0
  89. package/dist/utils/prompt.d.ts +3 -0
  90. package/dist/utils/prompt.d.ts.map +1 -0
  91. package/dist/utils/prompt.js +8 -0
  92. package/dist/utils/prompt.js.map +1 -0
  93. package/package.json +12 -2
@@ -0,0 +1,17 @@
1
+ import type { BaseFileEntry, BaseRegistry } from "../../registry/types";
2
+ import type { FileSource, InstallerIO } from "../../installer/types";
3
+ import type { AddDialogues, EntrySource, InstallOptions, InstallTarget } from "../types";
4
+ /** Hash of the package's current version of a file, derived from its content. */
5
+ export declare function latestHashFrom(source: FileSource, io: InstallerIO): (file: BaseFileEntry) => Promise<string>;
6
+ export declare function pickerChoices(registry: BaseRegistry): {
7
+ value: string;
8
+ label: string;
9
+ }[];
10
+ /**
11
+ * Installs entries into every target, keeping locally modified files. With no
12
+ * keys and an `onNoValue` dialogue the user picks from the registry. Local
13
+ * changes prompt keep/overwrite through `onCollision` unless `--force`.
14
+ * The caller resolves keys before and saves each target's store after.
15
+ */
16
+ export declare function addEntries(registry: BaseRegistry, targets: InstallTarget[], source: EntrySource, keys: string[], options?: InstallOptions, dialogues?: AddDialogues): Promise<void>;
17
+ //# sourceMappingURL=add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/add.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIxE,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIrE,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAKzF,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,WAAW,GAAG,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,MAAM,CAAC,CAM5G;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAKxF;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,aAAa,EAAE,EACxB,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,cAAmB,EAC5B,SAAS,GAAE,YAAiB,GAC3B,OAAO,CAAC,IAAI,CAAC,CA4Cf"}
@@ -0,0 +1,76 @@
1
+ // packages/core/src/cli/commands/add.ts
2
+ import chalk from "chalk";
3
+ import { z } from "zod";
4
+ import { get } from "../../registry/registry.selectors";
5
+ import { register } from "../../registry/registry.mutations";
6
+ import { applyClassifications, classifyFiles, recordedHashes } from "../../installer";
7
+ import { createInstallerIO } from "../../installer/io";
8
+ import { ConflictDecision, FileState } from "../../installer/types";
9
+ import { hashString } from "../../hash/hash";
10
+ import { guardCancel } from "../../utils/prompt";
11
+ import { runDialogueValue } from "../dialogue";
12
+ import { c, lineSuccess, lineWarn, lineInfo } from "../theme";
13
+ const KeysSchema = z.array(z.string());
14
+ /** Hash of the package's current version of a file, derived from its content. */
15
+ export function latestHashFrom(source, io) {
16
+ return async (file) => {
17
+ const content = await source(file);
18
+ if (content === null)
19
+ return "";
20
+ return content.kind === "copy" ? io.hashFile(content.sourcePath) : hashString(content.content);
21
+ };
22
+ }
23
+ export function pickerChoices(registry) {
24
+ return Object.entries(registry).map(([key, meta]) => ({
25
+ value: key,
26
+ label: `${c.key(key)} ${chalk.dim("—")} ${chalk.dim(meta.description ?? meta.name)}`,
27
+ }));
28
+ }
29
+ /**
30
+ * Installs entries into every target, keeping locally modified files. With no
31
+ * keys and an `onNoValue` dialogue the user picks from the registry. Local
32
+ * changes prompt keep/overwrite through `onCollision` unless `--force`.
33
+ * The caller resolves keys before and saves each target's store after.
34
+ */
35
+ export async function addEntries(registry, targets, source, keys, options = {}, dialogues = {}) {
36
+ const io = createInstallerIO();
37
+ if (keys.length === 0 && dialogues.onNoValue !== undefined) {
38
+ const picked = guardCancel(await runDialogueValue(dialogues.onNoValue, { keyChoices: pickerChoices(registry) }, options.answers));
39
+ keys = KeysSchema.parse(picked ?? []);
40
+ }
41
+ for (const target of targets) {
42
+ if (targets.length > 1)
43
+ console.log(c.header(target.label));
44
+ for (const key of keys) {
45
+ const meta = registry[key];
46
+ if (!meta)
47
+ continue;
48
+ const fileSource = await source(meta);
49
+ const classifications = await classifyFiles(meta.files, target.installDir, recordedHashes(get(target.store, key)), io, latestHashFrom(fileSource, io));
50
+ let decision = ConflictDecision.Keep;
51
+ const hasLocalChanges = classifications.some((cl) => cl.state >= FileState.UserOnly);
52
+ if (hasLocalChanges && !options.force && dialogues.onCollision !== undefined) {
53
+ const answer = await runDialogueValue(dialogues.onCollision, { key: c.key(key), target: c.target(target.label) }, options.answers);
54
+ if (answer === ConflictDecision.Overwrite)
55
+ decision = ConflictDecision.Overwrite;
56
+ }
57
+ const result = await applyClassifications(classifications, fileSource, { decision, force: options.force ?? false }, io);
58
+ for (const file of result.missingSource) {
59
+ console.log(lineWarn(`No content for ${c.file(file)} in the package source — skipped`));
60
+ }
61
+ for (const file of result.kept) {
62
+ console.log(lineWarn(`${c.file(file)} has local changes — kept ${chalk.dim(`(use ${c.flag("-f")} to overwrite)`)}`));
63
+ }
64
+ if (result.written.length > 0) {
65
+ console.log(lineSuccess(`Installed ${c.key(key)} ${chalk.dim(`(${result.written.length} file${result.written.length === 1 ? "" : "s"})`)}`));
66
+ }
67
+ else if (result.kept.length === 0) {
68
+ console.log(lineInfo(`${c.key(key)} — already up to date`));
69
+ }
70
+ // Always record the on-disk state — its hashes are the baseline that
71
+ // lets later runs tell user edits from package changes.
72
+ register(target.store, key, { ...meta, files: result.files.map((f) => ({ ...f, version: meta.version })) });
73
+ }
74
+ }
75
+ }
76
+ //# sourceMappingURL=add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/cli/commands/add.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { BaseRegistry } from "../../registry/types";
2
+ import type { LSOptions } from "../types";
3
+ /** Lists the entries of a registry, grouped by each entry's `group`. */
4
+ export declare function lsEntries(registry: BaseRegistry, options?: LSOptions): void;
5
+ //# sourceMappingURL=ls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/ls.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,GAAE,SAAc,GAAG,IAAI,CAiB/E"}
@@ -0,0 +1,22 @@
1
+ // packages/core/src/cli/commands/ls.ts
2
+ import chalk from "chalk";
3
+ import { c } from "../theme";
4
+ /** Lists the entries of a registry, grouped by each entry's `group`. */
5
+ export function lsEntries(registry, options = {}) {
6
+ if (options.json === true) {
7
+ console.log(JSON.stringify(registry, null, 2));
8
+ return;
9
+ }
10
+ const byGroup = {};
11
+ for (const [key, meta] of Object.entries(registry))
12
+ (byGroup[meta.group ?? "default"] ??= []).push(key);
13
+ for (const group of Object.keys(byGroup).sort()) {
14
+ console.log(c.header(group));
15
+ for (const key of (byGroup[group] ?? []).sort()) {
16
+ const meta = registry[key];
17
+ console.log(` ${c.key(key.padEnd(26))} ${chalk.dim(meta?.description ?? "")}`);
18
+ }
19
+ console.log();
20
+ }
21
+ }
22
+ //# sourceMappingURL=ls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ls.js","sourceRoot":"","sources":["../../../src/cli/commands/ls.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,CAAC,EAAE,MAAM,UAAU,CAAC;AAE7B,wEAAwE;AACxE,MAAM,UAAU,SAAS,CAAC,QAAsB,EAAE,OAAO,GAAc,EAAE;IACvE,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAA6B,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAExG,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7B,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAChD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { BaseRegistry } from "../../registry/types";
2
+ import type { InstallOptions, InstallTarget, RemoveDialogues } from "../types";
3
+ /**
4
+ * Removes installed entries and drops them from each target's store. With no
5
+ * keys and an `onNoValue` dialogue the user picks from what is installed.
6
+ * Removal is all-or-nothing per entry: local changes prompt keep/remove
7
+ * through `onCollision` (kept entirely without it), and an entry with files
8
+ * missing on disk proceeds only when `onIncomplete` confirms. Installed
9
+ * dependents (via `registryDependencies`) are offered for cascade removal
10
+ * through `onCascade`. The caller saves each target's store after.
11
+ */
12
+ export declare function removeEntries(registry: BaseRegistry, targets: InstallTarget[], keys: string[], options?: InstallOptions, dialogues?: RemoveDialogues): Promise<void>;
13
+ //# sourceMappingURL=remove.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/remove.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAqB,MAAM,sBAAsB,CAAC;AAO5E,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AA0B/E;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,aAAa,EAAE,EACxB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,cAAmB,EAC5B,SAAS,GAAE,eAAoB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA4Ef"}
@@ -0,0 +1,109 @@
1
+ // packages/core/src/cli/commands/remove.ts
2
+ import chalk from "chalk";
3
+ import path from "node:path";
4
+ import { z } from "zod";
5
+ import { entries as storeEntries, entryDependencies, get } from "../../registry/registry.selectors";
6
+ import { unregister } from "../../registry/registry.mutations";
7
+ import { recordedHashes, removeInstalledFiles } from "../../installer";
8
+ import { createInstallerIO } from "../../installer/io";
9
+ import { ConflictDecision } from "../../installer/types";
10
+ import { guardCancel } from "../../utils/prompt";
11
+ import { runDialogueValue } from "../dialogue";
12
+ import { c, lineSuccess, lineWarn, lineInfo } from "../theme";
13
+ const KeysSchema = z.array(z.string());
14
+ async function diskState(entry, installDir, io) {
15
+ const recorded = recordedHashes(entry);
16
+ const missing = [];
17
+ const modified = [];
18
+ for (const file of entry.files) {
19
+ const destPath = path.join(installDir, file.path);
20
+ if (!io.exists(destPath)) {
21
+ missing.push(file.path);
22
+ continue;
23
+ }
24
+ const recordedHash = recorded[file.path];
25
+ if (recordedHash !== undefined && (await io.hashFile(destPath)) !== recordedHash)
26
+ modified.push(file.path);
27
+ }
28
+ return { missing, modified };
29
+ }
30
+ /**
31
+ * Removes installed entries and drops them from each target's store. With no
32
+ * keys and an `onNoValue` dialogue the user picks from what is installed.
33
+ * Removal is all-or-nothing per entry: local changes prompt keep/remove
34
+ * through `onCollision` (kept entirely without it), and an entry with files
35
+ * missing on disk proceeds only when `onIncomplete` confirms. Installed
36
+ * dependents (via `registryDependencies`) are offered for cascade removal
37
+ * through `onCascade`. The caller saves each target's store after.
38
+ */
39
+ export async function removeEntries(registry, targets, keys, options = {}, dialogues = {}) {
40
+ const io = createInstallerIO();
41
+ if (keys.length === 0 && dialogues.onNoValue !== undefined) {
42
+ const installed = [...new Set(targets.flatMap((t) => Object.keys(storeEntries(t.store))))].sort();
43
+ if (installed.length === 0) {
44
+ console.log(lineInfo("Nothing installed."));
45
+ return;
46
+ }
47
+ const choices = installed.map((key) => ({ value: key, label: c.key(key) }));
48
+ const picked = guardCancel(await runDialogueValue(dialogues.onNoValue, { keyChoices: choices }, options.answers));
49
+ keys = KeysSchema.parse(picked ?? []);
50
+ }
51
+ for (const target of targets) {
52
+ if (targets.length > 1)
53
+ console.log(c.header(target.label));
54
+ const targetKeys = Object.keys(storeEntries(target.store));
55
+ // Mutable queue so cascade confirmations can append dependents mid-loop.
56
+ const queue = [...keys];
57
+ let i = 0;
58
+ while (i < queue.length) {
59
+ const key = queue[i++];
60
+ const installed = get(target.store, key);
61
+ if (!installed) {
62
+ console.log(lineInfo(`${c.key(key)} — not installed`));
63
+ continue;
64
+ }
65
+ const dependents = entryDependencies(key, registry, targetKeys).filter((d) => !queue.includes(d));
66
+ if (dependents.length > 0) {
67
+ console.log(lineWarn(`${dependents.map((d) => c.key(d)).join(", ")} depend${dependents.length === 1 ? "s" : ""} on ${c.key(key)}.`));
68
+ if (dialogues.onCascade !== undefined) {
69
+ const also = await runDialogueValue(dialogues.onCascade, { key: c.key(key), dependents: dependents.map((d) => c.key(d)).join(", ") }, options.answers);
70
+ if (also === true)
71
+ queue.push(...dependents);
72
+ }
73
+ }
74
+ const state = await diskState(installed, target.installDir, io);
75
+ if (state.missing.length > 0 && dialogues.onIncomplete !== undefined) {
76
+ console.log(lineWarn(`${c.key(key)} is incomplete on disk — missing ${state.missing.map((f) => c.file(f)).join(", ")}`));
77
+ const proceed = await runDialogueValue(dialogues.onIncomplete, { key: c.key(key), target: c.target(target.label), missing: state.missing.map((f) => c.file(f)).join(", ") }, options.answers);
78
+ if (proceed !== true) {
79
+ console.log(lineInfo(`${c.key(key)} — skipped`));
80
+ continue;
81
+ }
82
+ }
83
+ let force = options.force ?? false;
84
+ if (state.modified.length > 0 && !force) {
85
+ console.log(lineWarn(`${c.key(key)} has local changes in ${state.modified.map((f) => c.file(f)).join(", ")}`));
86
+ if (dialogues.onCollision !== undefined) {
87
+ const answer = await runDialogueValue(dialogues.onCollision, { key: c.key(key), target: c.target(target.label) }, options.answers);
88
+ if (answer === ConflictDecision.Overwrite)
89
+ force = true;
90
+ }
91
+ if (!force) {
92
+ console.log(lineInfo(`${c.key(key)} — kept ${chalk.dim(`(use ${c.flag("-f")} to remove)`)}`));
93
+ continue;
94
+ }
95
+ }
96
+ const result = await removeInstalledFiles(installed.files, target.installDir, { force }, io);
97
+ if (result.removed.length > 0) {
98
+ console.log(lineSuccess(`Removed ${c.key(key)} ${chalk.dim(`(${result.removed.length} file${result.removed.length === 1 ? "" : "s"})`)}`));
99
+ }
100
+ if (result.kept.length === 0) {
101
+ unregister(target.store, key);
102
+ }
103
+ else {
104
+ console.log(lineInfo(`${c.key(key)} kept in manifest (some files were kept)`));
105
+ }
106
+ }
107
+ }
108
+ }
109
+ //# sourceMappingURL=remove.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.js","sourceRoot":"","sources":["../../../src/cli/commands/remove.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { BaseRegistry } from "../../registry/types";
2
+ import type { EntrySource, InstallOptions, InstallTarget, UpdateDialogues } from "../types";
3
+ /**
4
+ * Re-installs entries already present in a target's manifest; with no keys
5
+ * everything installed is updated. Local changes prompt keep/overwrite
6
+ * through `onCollision` unless `--force`. The caller resolves keys before
7
+ * and saves each target's store after.
8
+ */
9
+ export declare function updateEntries(registry: BaseRegistry, targets: InstallTarget[], source: EntrySource, keys: string[], options?: InstallOptions, dialogues?: UpdateDialogues): Promise<void>;
10
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/update.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAMzD,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAkB5F;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,aAAa,EAAE,EACxB,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,cAAmB,EAC5B,SAAS,GAAE,eAAoB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAoEf"}
@@ -0,0 +1,92 @@
1
+ // packages/core/src/cli/commands/update.ts
2
+ import chalk from "chalk";
3
+ import path from "node:path";
4
+ import { entries as storeEntries, get } from "../../registry/registry.selectors";
5
+ import { register } from "../../registry/registry.mutations";
6
+ import { applyClassifications, classifyFiles, recordedHashes, removeInstalledFiles } from "../../installer";
7
+ import { createInstallerIO } from "../../installer/io";
8
+ import { ConflictDecision, FileState } from "../../installer/types";
9
+ import { runDialogueValue } from "../dialogue";
10
+ import { c, lineSuccess, lineWarn, lineInfo } from "../theme";
11
+ import { latestHashFrom } from "./add";
12
+ const DRY_RUN_LABELS = {
13
+ [FileState.UpToDate]: chalk.dim("up to date"),
14
+ [FileState.SafeUpdate]: chalk.cyan("would update") + chalk.dim(" (package changed, file unmodified)"),
15
+ [FileState.UserOnly]: chalk.yellow("would keep") + chalk.dim(" — local changes"),
16
+ [FileState.Conflict]: chalk.red("conflict") + chalk.dim(" — keep or overwrite"),
17
+ };
18
+ function printDryRun(classifications) {
19
+ for (const cl of classifications) {
20
+ const rel = c.file(path.relative(process.cwd(), cl.destPath));
21
+ console.log(` ${rel.padEnd(50)} ${DRY_RUN_LABELS[cl.state]}`);
22
+ }
23
+ }
24
+ /**
25
+ * Re-installs entries already present in a target's manifest; with no keys
26
+ * everything installed is updated. Local changes prompt keep/overwrite
27
+ * through `onCollision` unless `--force`. The caller resolves keys before
28
+ * and saves each target's store after.
29
+ */
30
+ export async function updateEntries(registry, targets, source, keys, options = {}, dialogues = {}) {
31
+ const io = createInstallerIO();
32
+ for (const target of targets) {
33
+ if (targets.length > 1)
34
+ console.log(c.header(target.label));
35
+ const targetKeys = Object.keys(storeEntries(target.store)).sort();
36
+ const wanted = keys.length > 0 ? targetKeys.filter((k) => keys.includes(k)) : targetKeys;
37
+ if (wanted.length === 0) {
38
+ console.log(lineInfo("Nothing to update."));
39
+ continue;
40
+ }
41
+ for (const key of wanted) {
42
+ const meta = registry[key];
43
+ if (!meta) {
44
+ console.log(lineWarn(`${c.key(key)} is installed but no longer in the package — leaving as is`));
45
+ continue;
46
+ }
47
+ const installed = get(target.store, key);
48
+ const fileSource = await source(meta);
49
+ const classifications = await classifyFiles(meta.files, target.installDir, recordedHashes(installed), io, latestHashFrom(fileSource, io));
50
+ const stale = (installed?.files ?? []).filter((f) => !meta.files.some((m) => m.path === f.path));
51
+ if (options.dryRun) {
52
+ console.log(chalk.bold(c.key(key)));
53
+ printDryRun(classifications);
54
+ for (const file of stale) {
55
+ console.log(` ${c.file(file.path).padEnd(50)} ${chalk.red("would remove")}${chalk.dim(" — no longer in the package")}`);
56
+ }
57
+ continue;
58
+ }
59
+ let decision = ConflictDecision.Keep;
60
+ const hasLocalChanges = classifications.some((cl) => cl.state >= FileState.UserOnly);
61
+ if (hasLocalChanges && !options.force && dialogues.onCollision !== undefined) {
62
+ const answer = await runDialogueValue(dialogues.onCollision, { key: c.key(key), target: c.target(target.label) }, options.answers);
63
+ if (answer === ConflictDecision.Overwrite)
64
+ decision = ConflictDecision.Overwrite;
65
+ }
66
+ const result = await applyClassifications(classifications, fileSource, { decision, force: options.force ?? false }, io);
67
+ if (stale.length > 0) {
68
+ const removal = await removeInstalledFiles(stale, target.installDir, { force: options.force }, io);
69
+ for (const file of removal.kept) {
70
+ console.log(lineWarn(`${c.file(file)} left the package but has local changes — kept ${chalk.dim(`(use ${c.flag("-f")} to remove)`)}`));
71
+ }
72
+ if (removal.removed.length > 0) {
73
+ console.log(lineInfo(`Removed ${removal.removed.length} file${removal.removed.length === 1 ? "" : "s"} no longer in ${c.key(key)}`));
74
+ }
75
+ }
76
+ for (const file of result.missingSource) {
77
+ console.log(lineWarn(`No content for ${c.file(file)} in the package source — skipped`));
78
+ }
79
+ if (result.kept.length > 0) {
80
+ console.log(lineWarn(`${c.key(key)} — kept ${result.kept.map((f) => c.file(f)).join(", ")}`));
81
+ }
82
+ if (result.written.length > 0) {
83
+ console.log(lineSuccess(`Updated ${c.key(key)} ${chalk.dim(`(${result.written.length} file${result.written.length === 1 ? "" : "s"})`)}`));
84
+ }
85
+ else if (result.kept.length === 0) {
86
+ console.log(lineInfo(`${c.key(key)} — already up to date`));
87
+ }
88
+ register(target.store, key, { ...meta, files: result.files.map((f) => ({ ...f, version: meta.version })) });
89
+ }
90
+ }
91
+ }
92
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/commands/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ export declare const StepKind: {
2
+ readonly Select: 0;
3
+ readonly MultiSelect: 1;
4
+ readonly Confirm: 2;
5
+ readonly Text: 3;
6
+ };
7
+ export type StepKind = (typeof StepKind)[keyof typeof StepKind];
8
+ export type DialogueAnswers = Record<string, unknown>;
9
+ export interface StepChoice<V = unknown> {
10
+ value: V;
11
+ label: string;
12
+ }
13
+ /** A literal value, or a function deriving it from the walk's input. */
14
+ export type Resolvable<Input, V> = V | ((input: Input) => V);
15
+ /**
16
+ * One question of a dialogue. `when` decides whether the step runs at all; a
17
+ * skipped step records no answer and falls through to `next`. `next` links to
18
+ * the following step: a step id for linear flow, a function of the answer for
19
+ * branching, absent to end. `{name}` placeholders in messages and labels are
20
+ * filled from the walk's input.
21
+ */
22
+ interface StepBase<Input> {
23
+ message: string;
24
+ when?: (input: Input, answers: DialogueAnswers) => boolean;
25
+ next?: string | ((answer: unknown, answers: DialogueAnswers, input: Input) => string | null);
26
+ }
27
+ export interface SelectStep<Input = DialogueAnswers> extends StepBase<Input> {
28
+ kind: typeof StepKind.Select;
29
+ choices: Resolvable<Input, StepChoice[]>;
30
+ initial?: Resolvable<Input, string | number | boolean>;
31
+ }
32
+ export interface MultiSelectStep<Input = DialogueAnswers> extends StepBase<Input> {
33
+ kind: typeof StepKind.MultiSelect;
34
+ choices: Resolvable<Input, StepChoice[]>;
35
+ initial?: Resolvable<Input, unknown[]>;
36
+ required?: boolean;
37
+ }
38
+ export interface ConfirmStep<Input = DialogueAnswers> extends StepBase<Input> {
39
+ kind: typeof StepKind.Confirm;
40
+ initial?: Resolvable<Input, boolean>;
41
+ }
42
+ export interface TextStep<Input = DialogueAnswers> extends StepBase<Input> {
43
+ kind: typeof StepKind.Text;
44
+ initial?: Resolvable<Input, string>;
45
+ validate?: (value: string | undefined) => string | undefined;
46
+ }
47
+ export type DialogueStep<Input = DialogueAnswers> = SelectStep<Input> | MultiSelectStep<Input> | ConfirmStep<Input> | TextStep<Input>;
48
+ /**
49
+ * A command's interaction with the user: a graph of steps keyed by id,
50
+ * entered at the first key and linked through each step's `next`. Commands
51
+ * take dialogues through named slots (e.g. `onNoValue`, `onCollision`) and
52
+ * run them with `runDialogueValue`; init flows are linked lists run with
53
+ * `runDialogue`. Preset answers (`options.answers`, keyed by step id) skip
54
+ * the terminal prompt — that is how tests and non-interactive runs answer.
55
+ */
56
+ export interface Dialogue<Input = DialogueAnswers> {
57
+ steps: Record<string, DialogueStep<Input>>;
58
+ }
59
+ /**
60
+ * Walks a dialogue from its first step, skipping steps whose `when` is
61
+ * false, and collects answers by step id. A preset answer in `answers` is
62
+ * recorded without prompting; anything else renders in the terminal.
63
+ * Returns the cancel symbol as soon as any step is cancelled. Unknown step
64
+ * ids throw.
65
+ */
66
+ export declare function runDialogue<Input>(dialogue: Dialogue<Input>, input: Input, answers?: DialogueAnswers): Promise<DialogueAnswers | symbol>;
67
+ /**
68
+ * Runs a dialogue and returns the answer of its last executed step — the
69
+ * contract for the commands' named dialogue slots. Returns undefined when no
70
+ * step ran, or the cancel symbol.
71
+ */
72
+ export declare function runDialogueValue<Input>(dialogue: Dialogue<Input>, input: Input, answers?: DialogueAnswers): Promise<unknown>;
73
+ export {};
74
+ //# sourceMappingURL=dialogue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialogue.d.ts","sourceRoot":"","sources":["../../src/cli/dialogue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ // packages/core/src/cli/dialogue.ts
2
+ import * as p from "@clack/prompts";
3
+ export const StepKind = {
4
+ Select: 0,
5
+ MultiSelect: 1,
6
+ Confirm: 2,
7
+ Text: 3,
8
+ };
9
+ // ---------------------------------------------------------------------------
10
+ // Resolving
11
+ // ---------------------------------------------------------------------------
12
+ function interpolate(template, input) {
13
+ const record = (typeof input === "object" && input !== null ? input : {});
14
+ return template.replace(/\{(\w+)\}/g, (match, name) => {
15
+ const value = record[name];
16
+ return value === undefined ? match : String(value);
17
+ });
18
+ }
19
+ function resolveValue(value, input) {
20
+ return typeof value === "function" ? value(input) : value;
21
+ }
22
+ function resolveStep(id, step, input) {
23
+ const resolved = { id, kind: step.kind, message: interpolate(step.message, input) };
24
+ switch (step.kind) {
25
+ case StepKind.Select:
26
+ case StepKind.MultiSelect: {
27
+ const choices = resolveValue(step.choices, input) ?? [];
28
+ resolved.choices = choices.map((choice) => ({ ...choice, label: interpolate(choice.label, input) }));
29
+ resolved.initial = resolveValue(step.initial, input);
30
+ if (step.kind === StepKind.MultiSelect)
31
+ resolved.required = step.required;
32
+ return resolved;
33
+ }
34
+ case StepKind.Confirm:
35
+ resolved.initial = resolveValue(step.initial, input);
36
+ return resolved;
37
+ case StepKind.Text:
38
+ resolved.initial = resolveValue(step.initial, input);
39
+ resolved.validate = step.validate;
40
+ return resolved;
41
+ }
42
+ }
43
+ // ---------------------------------------------------------------------------
44
+ // Rendering
45
+ // ---------------------------------------------------------------------------
46
+ async function render(step) {
47
+ switch (step.kind) {
48
+ case StepKind.Select:
49
+ return p.select({
50
+ message: step.message,
51
+ options: step.choices ?? [],
52
+ initialValue: step.initial,
53
+ });
54
+ case StepKind.MultiSelect:
55
+ return p.multiselect({
56
+ message: step.message,
57
+ options: step.choices ?? [],
58
+ initialValues: step.initial,
59
+ required: step.required,
60
+ });
61
+ case StepKind.Confirm:
62
+ return p.confirm({
63
+ message: step.message,
64
+ initialValue: step.initial ?? false,
65
+ });
66
+ case StepKind.Text:
67
+ return p.text({
68
+ message: step.message,
69
+ initialValue: step.initial,
70
+ validate: step.validate,
71
+ });
72
+ default:
73
+ throw new Error(`unknown step kind ${String(step.kind)}`);
74
+ }
75
+ }
76
+ // ---------------------------------------------------------------------------
77
+ // Walking
78
+ // ---------------------------------------------------------------------------
79
+ /**
80
+ * Walks a dialogue from its first step, skipping steps whose `when` is
81
+ * false, and collects answers by step id. A preset answer in `answers` is
82
+ * recorded without prompting; anything else renders in the terminal.
83
+ * Returns the cancel symbol as soon as any step is cancelled. Unknown step
84
+ * ids throw.
85
+ */
86
+ export async function runDialogue(dialogue, input, answers = {}) {
87
+ const collected = {};
88
+ let id = Object.keys(dialogue.steps)[0] ?? null;
89
+ while (id !== null) {
90
+ const step = dialogue.steps[id];
91
+ if (step === undefined)
92
+ throw new Error(`dialogue has no step "${id}"`);
93
+ let answer = undefined;
94
+ if (step.when === undefined || step.when(input, collected)) {
95
+ const preset = answers[id];
96
+ answer = preset !== undefined ? preset : await render(resolveStep(id, step, input));
97
+ if (typeof answer === "symbol")
98
+ return answer;
99
+ collected[id] = answer;
100
+ }
101
+ id = typeof step.next === "function" ? step.next(answer, collected, input) : step.next ?? null;
102
+ }
103
+ return collected;
104
+ }
105
+ /**
106
+ * Runs a dialogue and returns the answer of its last executed step — the
107
+ * contract for the commands' named dialogue slots. Returns undefined when no
108
+ * step ran, or the cancel symbol.
109
+ */
110
+ export async function runDialogueValue(dialogue, input, answers = {}) {
111
+ const record = await runDialogue(dialogue, input, answers);
112
+ if (typeof record === "symbol")
113
+ return record;
114
+ const last = Object.keys(record).at(-1);
115
+ return last === undefined ? undefined : record[last];
116
+ }
117
+ //# sourceMappingURL=dialogue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialogue.js","sourceRoot":"","sources":["../../src/cli/dialogue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export * from "./types";
2
+ export { ConflictDecision, FileState } from "../installer/types";
3
+ export { StepKind, runDialogue, runDialogueValue } from "./dialogue";
4
+ export type { Dialogue, DialogueStep, DialogueAnswers, StepChoice, Resolvable, SelectStep, MultiSelectStep, ConfirmStep, TextStep, } from "./dialogue";
5
+ export { addEntries } from "./commands/add";
6
+ export { updateEntries } from "./commands/update";
7
+ export { removeEntries } from "./commands/remove";
8
+ export { lsEntries } from "./commands/ls";
9
+ export { c, sym, lineSuccess, lineWarn, lineInfo, lineError } from "./theme";
10
+ //# sourceMappingURL=index.d.ts.map