@g3nomaly/core 0.2.0 → 0.3.1

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 (113) hide show
  1. package/dist/cli/commands/installFromSources.d.ts +49 -0
  2. package/dist/cli/commands/installFromSources.d.ts.map +1 -0
  3. package/dist/cli/commands/installFromSources.js +138 -0
  4. package/dist/cli/commands/installFromSources.js.map +1 -0
  5. package/dist/cli/commands/ls.d.ts +11 -0
  6. package/dist/cli/commands/ls.d.ts.map +1 -1
  7. package/dist/cli/commands/ls.js +43 -0
  8. package/dist/cli/commands/ls.js.map +1 -1
  9. package/dist/cli/commands/sources.d.ts +45 -0
  10. package/dist/cli/commands/sources.d.ts.map +1 -0
  11. package/dist/cli/commands/sources.js +89 -0
  12. package/dist/cli/commands/sources.js.map +1 -0
  13. package/dist/cli/index.d.ts +9 -0
  14. package/dist/cli/index.d.ts.map +1 -1
  15. package/dist/cli/index.js +6 -0
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/cli/installDialogues.d.ts +15 -0
  18. package/dist/cli/installDialogues.d.ts.map +1 -0
  19. package/dist/cli/installDialogues.js +72 -0
  20. package/dist/cli/installDialogues.js.map +1 -0
  21. package/dist/cli/pick.d.ts +14 -0
  22. package/dist/cli/pick.d.ts.map +1 -0
  23. package/dist/cli/pick.js +35 -0
  24. package/dist/cli/pick.js.map +1 -0
  25. package/dist/cli/report.d.ts +34 -0
  26. package/dist/cli/report.d.ts.map +1 -0
  27. package/dist/cli/report.js +71 -0
  28. package/dist/cli/report.js.map +1 -0
  29. package/dist/config/types.d.ts +0 -16
  30. package/dist/config/types.d.ts.map +1 -1
  31. package/dist/config/types.js +0 -2
  32. package/dist/config/types.js.map +1 -1
  33. package/dist/installer/files.d.ts +15 -0
  34. package/dist/installer/files.d.ts.map +1 -0
  35. package/dist/installer/files.js +22 -0
  36. package/dist/installer/files.js.map +1 -0
  37. package/dist/installer/index.d.ts +13 -0
  38. package/dist/installer/index.d.ts.map +1 -1
  39. package/dist/installer/index.js +7 -0
  40. package/dist/installer/index.js.map +1 -1
  41. package/dist/installer/manifest.d.ts +59 -0
  42. package/dist/installer/manifest.d.ts.map +1 -0
  43. package/dist/installer/manifest.js +60 -0
  44. package/dist/installer/manifest.js.map +1 -0
  45. package/dist/installer/manifestSources.d.ts +21 -0
  46. package/dist/installer/manifestSources.d.ts.map +1 -0
  47. package/dist/installer/manifestSources.js +39 -0
  48. package/dist/installer/manifestSources.js.map +1 -0
  49. package/dist/installer/marketplace.d.ts +34 -0
  50. package/dist/installer/marketplace.d.ts.map +1 -0
  51. package/dist/installer/marketplace.js +64 -0
  52. package/dist/installer/marketplace.js.map +1 -0
  53. package/dist/installer/origin.d.ts +43 -0
  54. package/dist/installer/origin.d.ts.map +1 -0
  55. package/dist/installer/origin.js +22 -0
  56. package/dist/installer/origin.js.map +1 -0
  57. package/dist/installer/resolve.d.ts +78 -0
  58. package/dist/installer/resolve.d.ts.map +1 -0
  59. package/dist/installer/resolve.js +184 -0
  60. package/dist/installer/resolve.js.map +1 -0
  61. package/dist/installer/sourceRegistry.d.ts +59 -0
  62. package/dist/installer/sourceRegistry.d.ts.map +1 -0
  63. package/dist/installer/sourceRegistry.js +71 -0
  64. package/dist/installer/sourceRegistry.js.map +1 -0
  65. package/dist/sources/checkout.d.ts +14 -0
  66. package/dist/sources/checkout.d.ts.map +1 -0
  67. package/dist/sources/checkout.js +27 -0
  68. package/dist/sources/checkout.js.map +1 -0
  69. package/dist/sources/git.d.ts +9 -0
  70. package/dist/sources/git.d.ts.map +1 -0
  71. package/dist/sources/git.js +22 -0
  72. package/dist/sources/git.js.map +1 -0
  73. package/dist/sources/index.d.ts +5 -0
  74. package/dist/sources/index.d.ts.map +1 -0
  75. package/dist/sources/index.js +6 -0
  76. package/dist/sources/index.js.map +1 -0
  77. package/dist/sources/local.d.ts +10 -0
  78. package/dist/sources/local.d.ts.map +1 -0
  79. package/dist/sources/local.js +20 -0
  80. package/dist/sources/local.js.map +1 -0
  81. package/dist/sources/npm.d.ts +13 -0
  82. package/dist/sources/npm.d.ts.map +1 -0
  83. package/dist/sources/npm.js +128 -0
  84. package/dist/sources/npm.js.map +1 -0
  85. package/dist/sources/packageJson.d.ts +3 -0
  86. package/dist/sources/packageJson.d.ts.map +1 -0
  87. package/dist/sources/packageJson.js +13 -0
  88. package/dist/sources/packageJson.js.map +1 -0
  89. package/dist/sources/parse.d.ts +34 -0
  90. package/dist/sources/parse.d.ts.map +1 -0
  91. package/dist/sources/parse.js +92 -0
  92. package/dist/sources/parse.js.map +1 -0
  93. package/dist/sources/process.d.ts +18 -0
  94. package/dist/sources/process.d.ts.map +1 -0
  95. package/dist/sources/process.js +43 -0
  96. package/dist/sources/process.js.map +1 -0
  97. package/dist/sources/register.d.ts +16 -0
  98. package/dist/sources/register.d.ts.map +1 -0
  99. package/dist/sources/register.js +37 -0
  100. package/dist/sources/register.js.map +1 -0
  101. package/dist/sources/types.d.ts +73 -0
  102. package/dist/sources/types.d.ts.map +1 -0
  103. package/dist/sources/types.js +36 -0
  104. package/dist/sources/types.js.map +1 -0
  105. package/dist/utils/errors.d.ts +3 -0
  106. package/dist/utils/errors.d.ts.map +1 -0
  107. package/dist/utils/errors.js +6 -0
  108. package/dist/utils/errors.js.map +1 -0
  109. package/dist/utils/index.d.ts +1 -0
  110. package/dist/utils/index.d.ts.map +1 -1
  111. package/dist/utils/index.js +1 -0
  112. package/dist/utils/index.js.map +1 -1
  113. package/package.json +5 -1
@@ -0,0 +1,64 @@
1
+ // packages/core/src/installer/marketplace.ts
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { z } from "zod";
5
+ /** Folders a plugin or marketplace manifest may sit in, in the order they are tried. */
6
+ export const MANIFEST_DIRS = [".claude-plugin", ".cursor-plugin"];
7
+ const MARKETPLACE_FILE = "marketplace.json";
8
+ const MarketplaceSchema = z.object({
9
+ plugins: z.array(z.object({
10
+ name: z.string().min(1),
11
+ source: z.unknown(),
12
+ })).default([]),
13
+ });
14
+ /**
15
+ * First existing `<dir>/.claude-plugin/<file>` or `<dir>/.cursor-plugin/<file>`.
16
+ *
17
+ * @returns absolute path, or `null` when neither exists
18
+ */
19
+ export function manifestFile(dir, file) {
20
+ for (const manifestDir of MANIFEST_DIRS) {
21
+ const candidate = path.join(dir, manifestDir, file);
22
+ if (fs.existsSync(candidate))
23
+ return candidate;
24
+ }
25
+ return null;
26
+ }
27
+ /**
28
+ * Resolves `rel` against `base` and rejects a result outside `root`.
29
+ *
30
+ * @param root - Absolute folder nothing may leave, e.g. a source checkout
31
+ * @throws when the path points outside `root`
32
+ */
33
+ export function resolveInside(root, base, rel) {
34
+ const resolved = path.resolve(base, rel);
35
+ if (resolved !== root && !resolved.startsWith(root + path.sep)) {
36
+ throw new Error(`manifest path "${rel}" points outside the source`);
37
+ }
38
+ return resolved;
39
+ }
40
+ /**
41
+ * The plugins a source's `marketplace.json` lists. Plugins whose `source` is
42
+ * not a relative path (a git or npm reference) are skipped with a warning.
43
+ *
44
+ * @param root - Absolute root of the source
45
+ * @returns `null` when the source has no marketplace
46
+ * @throws when the marketplace is not valid JSON, or a plugin path leaves the source
47
+ */
48
+ export function readMarketplace(root) {
49
+ const file = manifestFile(root, MARKETPLACE_FILE);
50
+ if (file === null)
51
+ return null;
52
+ const marketplace = MarketplaceSchema.parse(JSON.parse(fs.readFileSync(file, "utf8")));
53
+ const plugins = [];
54
+ const warnings = [];
55
+ for (const plugin of marketplace.plugins) {
56
+ if (typeof plugin.source !== "string") {
57
+ warnings.push(`${plugin.name}: marketplace source is not a relative path, skipped`);
58
+ continue;
59
+ }
60
+ plugins.push({ name: plugin.name, dir: resolveInside(root, root, plugin.source) });
61
+ }
62
+ return { plugins, warnings };
63
+ }
64
+ //# sourceMappingURL=marketplace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketplace.js","sourceRoot":"","sources":["../../src/installer/marketplace.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,wFAAwF;AACxF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAA;AAEjE,MAAM,gBAAgB,GAAG,kBAAkB,CAAA;AAE3C,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QACxB,IAAI,EAAI,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;KACpB,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAChB,CAAC,CAAA;AASF;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,IAAY;IACpD,KAAK,MAAM,WAAW,IAAI,aAAa,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,CAAA;QACnD,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAA;IAChD,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,IAAY,EAAE,GAAW;IACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACxC,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,6BAA6B,CAAC,CAAA;IACrE,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAA;IACjD,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAE9B,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IACtF,MAAM,OAAO,GAAwB,EAAE,CAAA;IACvC,MAAM,QAAQ,GAAa,EAAE,CAAA;IAC7B,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QACzC,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACtC,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,sDAAsD,CAAC,CAAA;YACnF,SAAQ;QACV,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACpF,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;AAC9B,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Where an entry came from: the registered source, the folder its file paths
4
+ * resolve against, and the revision the source was read at.
5
+ */
6
+ export declare const EntryOriginSchema: z.ZodObject<{
7
+ source: z.ZodString;
8
+ dir: z.ZodString;
9
+ commit: z.ZodOptional<z.ZodString>;
10
+ version: z.ZodOptional<z.ZodString>;
11
+ }, z.core.$strip>;
12
+ export type EntryOrigin = z.infer<typeof EntryOriginSchema>;
13
+ /** A registry entry read from a source: the base fields plus its origin. */
14
+ export declare const OriginEntrySchema: z.ZodObject<{
15
+ name: z.ZodString;
16
+ description: z.ZodOptional<z.ZodString>;
17
+ version: z.ZodOptional<z.ZodString>;
18
+ group: z.ZodOptional<z.ZodString>;
19
+ registryDependencies: z.ZodOptional<z.ZodArray<z.ZodString>>;
20
+ files: z.ZodArray<z.ZodObject<{
21
+ path: z.ZodString;
22
+ type: z.ZodString;
23
+ hash: z.ZodOptional<z.ZodString>;
24
+ version: z.ZodOptional<z.ZodString>;
25
+ }, z.core.$strip>>;
26
+ origin: z.ZodObject<{
27
+ source: z.ZodString;
28
+ dir: z.ZodString;
29
+ commit: z.ZodOptional<z.ZodString>;
30
+ version: z.ZodOptional<z.ZodString>;
31
+ }, z.core.$strip>;
32
+ }, z.core.$strip>;
33
+ export type OriginEntry = z.infer<typeof OriginEntrySchema>;
34
+ /** What a source's reader passes to the function that reads one entry folder. */
35
+ export interface ReadContext {
36
+ /** Origin recorded on the entry */
37
+ origin: EntryOrigin;
38
+ /** Group the entry is listed under, e.g. the plugin it ships in */
39
+ group: string;
40
+ /** Version to record when the entry's own manifest has none */
41
+ version?: string;
42
+ }
43
+ //# sourceMappingURL=origin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"origin.d.ts","sourceRoot":"","sources":["../../src/installer/origin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;iBAS5B,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;iBAE5B,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,iFAAiF;AACjF,MAAM,WAAW,WAAW;IAC1B,mCAAmC;IACnC,MAAM,EAAI,WAAW,CAAA;IACrB,mEAAmE;IACnE,KAAK,EAAK,MAAM,CAAA;IAChB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB"}
@@ -0,0 +1,22 @@
1
+ // packages/core/src/installer/origin.ts
2
+ import { z } from "zod";
3
+ import { BaseRegistryEntrySchema } from "../registry/types";
4
+ /**
5
+ * Where an entry came from: the registered source, the folder its file paths
6
+ * resolve against, and the revision the source was read at.
7
+ */
8
+ export const EntryOriginSchema = z.object({
9
+ /** Name of the registered source, e.g. `g3n-skills` */
10
+ source: z.string().min(1),
11
+ /** Source-relative folder that `files[].path` resolves against, e.g. `skills/speech` or `dist/components` */
12
+ dir: z.string(),
13
+ /** Commit a git source resolved to */
14
+ commit: z.string().min(1).optional(),
15
+ /** Version an npm source resolved to, or the version in a local source's package.json */
16
+ version: z.string().min(1).optional(),
17
+ });
18
+ /** A registry entry read from a source: the base fields plus its origin. */
19
+ export const OriginEntrySchema = BaseRegistryEntrySchema.extend({
20
+ origin: EntryOriginSchema,
21
+ });
22
+ //# sourceMappingURL=origin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"origin.js","sourceRoot":"","sources":["../../src/installer/origin.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAE3D;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,uDAAuD;IACvD,MAAM,EAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,6GAA6G;IAC7G,GAAG,EAAM,CAAC,CAAC,MAAM,EAAE;IACnB,sCAAsC;IACtC,MAAM,EAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACrC,yFAAyF;IACzF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACtC,CAAC,CAAA;AAIF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,MAAM,CAAC;IAC9D,MAAM,EAAE,iBAAiB;CAC1B,CAAC,CAAA"}
@@ -0,0 +1,78 @@
1
+ import type { OriginEntry } from "./origin";
2
+ import type { SourceOffer } from "./sourceRegistry";
3
+ /** An entry or group as named on the command line or in `registryDependencies`. */
4
+ export interface EntryRequest {
5
+ name: string;
6
+ /** Registered source the name must come from, when given as `<name>@<source>` */
7
+ source?: string;
8
+ }
9
+ /** Entries a set of requests resolved to, and what could not be resolved. */
10
+ export interface Resolution<T extends OriginEntry> {
11
+ /** Resolved entries by key, `registryDependencies` rewritten to the resolved keys */
12
+ entries: Map<string, SourceOffer<T>>;
13
+ /** Requests and dependencies no source offers, e.g. `ghost` or `ghost@mine` */
14
+ unknown: string[];
15
+ /** One message per name more than one source offers, naming the qualified forms to pick from */
16
+ ambiguous: string[];
17
+ /** Why an entry nobody named is in the set, e.g. `{ vocabulary: "dep of plan" }` */
18
+ notes: Record<string, string>;
19
+ }
20
+ /** One entry with its dependencies resolved across sources. */
21
+ export interface ResolvedDependencies<T extends OriginEntry> {
22
+ /** The entry with `registryDependencies` rewritten to the resolved keys */
23
+ offer: SourceOffer<T>;
24
+ dependencies: SourceOffer<T>[];
25
+ /** Dependencies no source offers, e.g. `ghost (dep of plan)` */
26
+ unknown: string[];
27
+ ambiguous: string[];
28
+ }
29
+ /**
30
+ * Reads `emphasise` or `emphasise@g3n-skills`; names are matched in
31
+ * lowercase. A leading `@` belongs to the name, as in `@shadcn/button@shadcn`.
32
+ */
33
+ export declare function parseRequest(token: string): EntryRequest;
34
+ /** A request as it is typed, e.g. `emphasise@g3n-skills`. */
35
+ export declare function formatRequest(request: EntryRequest): string;
36
+ /**
37
+ * Resolves the `registryDependencies` of one entry against every offer. A
38
+ * dependency that cannot be resolved keeps its bare name in the rewritten
39
+ * list and is reported in `unknown` or `ambiguous`.
40
+ *
41
+ * @param preferred - Source to take a key from when several offer it: where it is installed, or where the request named it
42
+ */
43
+ export declare function resolveDependencies<T extends OriginEntry>(offer: SourceOffer<T>, offers: readonly SourceOffer<T>[], preferred?: Record<string, string>): ResolvedDependencies<T>;
44
+ /**
45
+ * Resolves entry and group names against every offer, with the dependency
46
+ * closure of each across sources. An entry named in the request settles which
47
+ * source its key comes from for every dependency. Two different entries
48
+ * wanted under one key are reported as ambiguous, since a target holds one
49
+ * folder per key.
50
+ *
51
+ * @param installed - Source each installed key came from
52
+ */
53
+ export declare function resolveRequests<T extends OriginEntry>(tokens: readonly string[], offers: readonly SourceOffer<T>[], installed?: Record<string, string>): Resolution<T>;
54
+ /**
55
+ * Resolves entry and group names against what a target has installed, with
56
+ * `<name>@<source>` keeping only entries installed from that source. Works
57
+ * from the install manifest alone, so no source needs to be reachable.
58
+ *
59
+ * @returns installed keys in the order named, and the names that match nothing installed
60
+ */
61
+ export declare function resolveInstalled<T extends OriginEntry>(tokens: readonly string[], installed: Record<string, T>): {
62
+ keys: string[];
63
+ unknown: string[];
64
+ };
65
+ /** Source each installed key came from, across manifests; the first manifest wins on a clash. */
66
+ export declare function installedOrigins<T extends OriginEntry>(installed: readonly Record<string, T>[]): Record<string, string>;
67
+ /**
68
+ * The fresh offer for each installed key, from the source it was installed
69
+ * from and never another, with its dependencies resolved.
70
+ *
71
+ * @param preferred - Source each installed key came from, across targets
72
+ * @returns the offers found, and the keys whose source is gone or no longer offers them
73
+ */
74
+ export declare function resolveUpdates<T extends OriginEntry>(keys: readonly string[], installed: Record<string, T>, offers: readonly SourceOffer<T>[], preferred?: Record<string, string>): {
75
+ offers: SourceOffer<T>[];
76
+ missing: string[];
77
+ };
78
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/installer/resolve.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEnD,mFAAmF;AACnF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAK,MAAM,CAAA;IACf,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,6EAA6E;AAC7E,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,WAAW;IAC/C,qFAAqF;IACrF,OAAO,EAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;IACtC,+EAA+E;IAC/E,OAAO,EAAI,MAAM,EAAE,CAAA;IACnB,gGAAgG;IAChG,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,oFAAoF;IACpF,KAAK,EAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED,+DAA+D;AAC/D,MAAM,WAAW,oBAAoB,CAAC,CAAC,SAAS,WAAW;IACzD,2EAA2E;IAC3E,KAAK,EAAS,WAAW,CAAC,CAAC,CAAC,CAAA;IAC5B,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9B,gEAAgE;IAChE,OAAO,EAAO,MAAM,EAAE,CAAA;IACtB,SAAS,EAAK,MAAM,EAAE,CAAA;CACvB;AAID;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAKxD;AAED,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAE3D;AAqDD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,WAAW,EACvD,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,EACrB,MAAM,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE,EACjC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACrC,oBAAoB,CAAC,CAAC,CAAC,CAiBzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,WAAW,EACnD,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,MAAM,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE,EACjC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACrC,UAAU,CAAC,CAAC,CAAC,CAuCf;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,WAAW,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAYtJ;AAED,iGAAiG;AACjG,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,WAAW,EAAE,SAAS,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIvH;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,WAAW,EAClD,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAC5B,MAAM,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE,EACjC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACrC;IAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CASjD"}
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Reads `emphasise` or `emphasise@g3n-skills`; names are matched in
3
+ * lowercase. A leading `@` belongs to the name, as in `@shadcn/button@shadcn`.
4
+ */
5
+ export function parseRequest(token) {
6
+ const at = token.indexOf("@", 1);
7
+ return at > 0
8
+ ? { name: token.slice(0, at).toLowerCase(), source: token.slice(at + 1) }
9
+ : { name: token.toLowerCase() };
10
+ }
11
+ /** A request as it is typed, e.g. `emphasise@g3n-skills`. */
12
+ export function formatRequest(request) {
13
+ return request.source === undefined ? request.name : `${request.name}@${request.source}`;
14
+ }
15
+ /** Name of the source an offer comes from. */
16
+ function sourceOf(offer) {
17
+ return offer.entry.origin.source;
18
+ }
19
+ /** Names of the sources the offers come from, each once, sorted. */
20
+ function uniqueSources(offers) {
21
+ return [...new Set(offers.map(sourceOf))].sort();
22
+ }
23
+ /**
24
+ * Entries one request names. A group name expands to every entry in it and
25
+ * wins over an entry with the same key. A name offered by several sources is
26
+ * settled by the preferred source for it, and is ambiguous otherwise.
27
+ */
28
+ function matchRequest(request, offers, preferred) {
29
+ const pool = request.source === undefined ? offers : offers.filter((o) => sourceOf(o) === request.source);
30
+ const group = pool.filter((o) => o.entry.group === request.name);
31
+ const matches = group.length > 0 ? group : pool.filter((o) => o.key === request.name);
32
+ if (matches.length === 0)
33
+ return null;
34
+ const sources = uniqueSources(matches);
35
+ if (sources.length === 1)
36
+ return matches;
37
+ const pinned = preferred[request.name];
38
+ if (pinned !== undefined && sources.includes(pinned))
39
+ return matches.filter((o) => sourceOf(o) === pinned);
40
+ return { ambiguous: `${request.name} is offered by ${sources.length} sources, name one: ${sources.map((s) => `${request.name}@${s}`).join(", ")}` };
41
+ }
42
+ /**
43
+ * The entry a dependency of `dependent` points at: the named source when the
44
+ * dependency is qualified, else the dependent's own source, else the source
45
+ * preferred for the key, else the only source offering it.
46
+ */
47
+ function matchDependency(token, dependent, offers, preferred) {
48
+ const request = parseRequest(token);
49
+ const named = offers.filter((o) => o.key === request.name);
50
+ const from = (source) => named.find((o) => sourceOf(o) === source);
51
+ if (request.source !== undefined)
52
+ return from(request.source) ?? null;
53
+ const settled = from(sourceOf(dependent)) ?? from(preferred[request.name]);
54
+ if (settled !== undefined)
55
+ return settled;
56
+ if (named.length <= 1)
57
+ return named[0] ?? null;
58
+ return { ambiguous: `${dependent.key} depends on ${request.name}, offered by ${uniqueSources(named).join(", ")}; qualify it as ${request.name}@<source>` };
59
+ }
60
+ /**
61
+ * Resolves the `registryDependencies` of one entry against every offer. A
62
+ * dependency that cannot be resolved keeps its bare name in the rewritten
63
+ * list and is reported in `unknown` or `ambiguous`.
64
+ *
65
+ * @param preferred - Source to take a key from when several offer it: where it is installed, or where the request named it
66
+ */
67
+ export function resolveDependencies(offer, offers, preferred = {}) {
68
+ const result = { offer, dependencies: [], unknown: [], ambiguous: [] };
69
+ const keys = (offer.entry.registryDependencies ?? []).map((token) => {
70
+ const match = matchDependency(token, offer, offers, preferred);
71
+ if (match === null) {
72
+ result.unknown.push(`${token} (dep of ${offer.key})`);
73
+ return parseRequest(token).name;
74
+ }
75
+ if ("ambiguous" in match) {
76
+ result.ambiguous.push(match.ambiguous);
77
+ return parseRequest(token).name;
78
+ }
79
+ result.dependencies.push(match);
80
+ return match.key;
81
+ });
82
+ result.offer = { ...offer, entry: { ...offer.entry, registryDependencies: keys.length > 0 ? keys : undefined } };
83
+ return result;
84
+ }
85
+ /**
86
+ * Resolves entry and group names against every offer, with the dependency
87
+ * closure of each across sources. An entry named in the request settles which
88
+ * source its key comes from for every dependency. Two different entries
89
+ * wanted under one key are reported as ambiguous, since a target holds one
90
+ * folder per key.
91
+ *
92
+ * @param installed - Source each installed key came from
93
+ */
94
+ export function resolveRequests(tokens, offers, installed = {}) {
95
+ const preferred = { ...installed };
96
+ const result = { entries: new Map(), unknown: [], ambiguous: [], notes: {} };
97
+ const named = new Set();
98
+ const add = (offer, note) => {
99
+ const existing = result.entries.get(offer.key);
100
+ if (existing !== undefined) {
101
+ if (sourceOf(existing) !== sourceOf(offer)) {
102
+ result.ambiguous.push(`${offer.key} is wanted from both ${sourceOf(existing)} and ${sourceOf(offer)}`);
103
+ }
104
+ return;
105
+ }
106
+ const resolved = resolveDependencies(offer, offers, preferred);
107
+ result.entries.set(offer.key, resolved.offer);
108
+ result.unknown.push(...resolved.unknown);
109
+ result.ambiguous.push(...resolved.ambiguous);
110
+ if (note !== undefined && !named.has(offer.key))
111
+ result.notes[offer.key] = note;
112
+ for (const dependency of resolved.dependencies)
113
+ add(dependency, `dep of ${offer.key}`);
114
+ };
115
+ const requested = [];
116
+ for (const token of tokens) {
117
+ const request = parseRequest(token);
118
+ const match = matchRequest(request, offers, preferred);
119
+ if (match === null)
120
+ result.unknown.push(formatRequest(request));
121
+ else if ("ambiguous" in match)
122
+ result.ambiguous.push(match.ambiguous);
123
+ else
124
+ requested.push(...match);
125
+ }
126
+ for (const offer of requested) {
127
+ named.add(offer.key);
128
+ preferred[offer.key] = sourceOf(offer);
129
+ }
130
+ for (const offer of requested)
131
+ add(offer);
132
+ result.unknown = [...new Set(result.unknown)];
133
+ result.ambiguous = [...new Set(result.ambiguous)];
134
+ return result;
135
+ }
136
+ /**
137
+ * Resolves entry and group names against what a target has installed, with
138
+ * `<name>@<source>` keeping only entries installed from that source. Works
139
+ * from the install manifest alone, so no source needs to be reachable.
140
+ *
141
+ * @returns installed keys in the order named, and the names that match nothing installed
142
+ */
143
+ export function resolveInstalled(tokens, installed) {
144
+ const keys = [];
145
+ const unknown = [];
146
+ for (const token of tokens) {
147
+ const request = parseRequest(token);
148
+ const pool = Object.entries(installed).filter(([, entry]) => request.source === undefined || entry.origin.source === request.source);
149
+ const group = pool.filter(([, entry]) => entry.group === request.name).map(([key]) => key);
150
+ const matches = group.length > 0 ? group : pool.filter(([key]) => key === request.name).map(([key]) => key);
151
+ if (matches.length === 0)
152
+ unknown.push(formatRequest(request));
153
+ keys.push(...matches);
154
+ }
155
+ return { keys: [...new Set(keys)], unknown };
156
+ }
157
+ /** Source each installed key came from, across manifests; the first manifest wins on a clash. */
158
+ export function installedOrigins(installed) {
159
+ const origins = {};
160
+ for (const record of installed)
161
+ for (const [key, entry] of Object.entries(record))
162
+ origins[key] ??= entry.origin.source;
163
+ return origins;
164
+ }
165
+ /**
166
+ * The fresh offer for each installed key, from the source it was installed
167
+ * from and never another, with its dependencies resolved.
168
+ *
169
+ * @param preferred - Source each installed key came from, across targets
170
+ * @returns the offers found, and the keys whose source is gone or no longer offers them
171
+ */
172
+ export function resolveUpdates(keys, installed, offers, preferred = {}) {
173
+ const found = [];
174
+ const missing = [];
175
+ for (const key of keys) {
176
+ const fresh = offers.find((o) => o.key === key && sourceOf(o) === installed[key]?.origin.source);
177
+ if (fresh === undefined)
178
+ missing.push(key);
179
+ else
180
+ found.push(resolveDependencies(fresh, offers, preferred).offer);
181
+ }
182
+ return { offers: found, missing };
183
+ }
184
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/installer/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { type RegistryStore } from "../registry/registry.store";
2
+ import type { RegisteredSource, SourceCheckout } from "../sources/types";
3
+ import type { EntrySource } from "../cli/types";
4
+ import { type OriginEntry } from "./origin";
5
+ /** What a package's reader found in one checked-out source. */
6
+ export interface SourceEntries<T extends OriginEntry> {
7
+ /** Entries by key, each with its `origin` filled in */
8
+ entries: [string, T][];
9
+ warnings: string[];
10
+ }
11
+ /** Reads the entries one checked-out source offers; each installer supplies its own. */
12
+ export type ReadSource<T extends OriginEntry> = (checkout: SourceCheckout) => Promise<SourceEntries<T>>;
13
+ /** A source that could not be checked out or read, with the reason. */
14
+ export interface FailedSource {
15
+ name: string;
16
+ error: string;
17
+ }
18
+ /**
19
+ * The entries a set of sources offers, one registry store per source, read
20
+ * from checkouts that stay on disk until `dispose` so the install can copy
21
+ * files out of them.
22
+ *
23
+ * Built by `loadSourceRegistry` in each installer's `add`, `update`, `ls` and
24
+ * `source add` commands. `offers` lists every entry for name resolution, and
25
+ * `entrySource` copies an entry's files from its checkout.
26
+ */
27
+ export interface SourceRegistry<T extends OriginEntry> {
28
+ /** Entries by source name, in the order the sources were given */
29
+ sources: Map<string, RegistryStore<T>>;
30
+ checkouts: Map<string, SourceCheckout>;
31
+ warnings: string[];
32
+ failed: FailedSource[];
33
+ dispose: () => void;
34
+ }
35
+ /** One entry one source offers. */
36
+ export interface SourceOffer<T extends OriginEntry> {
37
+ key: string;
38
+ entry: T;
39
+ }
40
+ /**
41
+ * Checks out each source and reads its entries with `readSource`, all
42
+ * sources at once. A source that cannot be checked out or read lands in
43
+ * `failed` instead of throwing, so one unreachable source does not stop the
44
+ * rest. A key offered twice by one source keeps the first, with a warning.
45
+ *
46
+ * @param projectRoot - Absolute root that local source paths and the `node_modules` lookup start from
47
+ */
48
+ export declare function loadSourceRegistry<T extends OriginEntry>(sources: readonly RegisteredSource[], projectRoot: string, readSource: ReadSource<T>): Promise<SourceRegistry<T>>;
49
+ /** Every entry of every source, sources in their given order and keys sorted within each. */
50
+ export declare function offers<T extends OriginEntry>(registry: SourceRegistry<T>): SourceOffer<T>[];
51
+ /**
52
+ * File source for the core install commands: a file at `files[].path` is
53
+ * copied from `<checkout>/<origin.dir>/<path>` in the checkout of the
54
+ * entry's source.
55
+ */
56
+ export declare function entrySource<T extends OriginEntry>(registry: SourceRegistry<T>): EntrySource;
57
+ /** Registry the core install commands take, keyed by entry key. */
58
+ export declare function offerRegistry<T extends OriginEntry>(selected: Iterable<SourceOffer<T>>): Record<string, T>;
59
+ //# sourceMappingURL=sourceRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceRegistry.d.ts","sourceRoot":"","sources":["../../src/installer/sourceRegistry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAIpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAExE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AAE9D,+DAA+D;AAC/D,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,WAAW;IAClD,uDAAuD;IACvD,OAAO,EAAG,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAA;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,wFAAwF;AACxF,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;AAEvG,uEAAuE;AACvE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAG,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,WAAW;IACnD,kEAAkE;IAClE,OAAO,EAAI,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IACxC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IACtC,QAAQ,EAAG,MAAM,EAAE,CAAA;IACnB,MAAM,EAAK,YAAY,EAAE,CAAA;IACzB,OAAO,EAAI,MAAM,IAAI,CAAA;CACtB;AAED,mCAAmC;AACnC,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,WAAW;IAChD,GAAG,EAAI,MAAM,CAAA;IACb,KAAK,EAAE,CAAC,CAAA;CACT;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,SAAS,WAAW,EAC5D,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CA6B5B;AAED,6FAA6F;AAC7F,wBAAgB,MAAM,CAAC,CAAC,SAAS,WAAW,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,CAG3F;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,WAAW,CAO3F;AAED,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,CAAC,SAAS,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAI1G"}
@@ -0,0 +1,71 @@
1
+ // packages/core/src/installer/sourceRegistry.ts
2
+ import path from "node:path";
3
+ import { createRegistryStore } from "../registry/registry.store";
4
+ import { register } from "../registry/registry.mutations";
5
+ import { entries } from "../registry/registry.selectors";
6
+ import { checkoutSource } from "../sources/checkout";
7
+ import { errorMessage } from "../utils/errors";
8
+ import { copySource } from "./install";
9
+ import { OriginEntrySchema } from "./origin";
10
+ /**
11
+ * Checks out each source and reads its entries with `readSource`, all
12
+ * sources at once. A source that cannot be checked out or read lands in
13
+ * `failed` instead of throwing, so one unreachable source does not stop the
14
+ * rest. A key offered twice by one source keeps the first, with a warning.
15
+ *
16
+ * @param projectRoot - Absolute root that local source paths and the `node_modules` lookup start from
17
+ */
18
+ export async function loadSourceRegistry(sources, projectRoot, readSource) {
19
+ const registry = { sources: new Map(), checkouts: new Map(), warnings: [], failed: [], dispose: () => { } };
20
+ registry.dispose = () => { for (const checkout of registry.checkouts.values())
21
+ checkout.dispose(); };
22
+ const results = await Promise.allSettled(sources.map(async (source) => {
23
+ const checkout = await checkoutSource(source, projectRoot);
24
+ registry.checkouts.set(source.name, checkout);
25
+ return readSource(checkout);
26
+ }));
27
+ results.forEach((result, index) => {
28
+ const name = sources[index]?.name ?? "";
29
+ if (result.status === "rejected") {
30
+ registry.failed.push({ name, error: errorMessage(result.reason) });
31
+ return;
32
+ }
33
+ const store = createRegistryStore();
34
+ for (const [key, entry] of result.value.entries) {
35
+ if (store.store.state[key] !== undefined) {
36
+ registry.warnings.push(`${name}: "${key}" is offered twice, using the first`);
37
+ continue;
38
+ }
39
+ register(store, key, entry);
40
+ }
41
+ registry.sources.set(name, store);
42
+ registry.warnings.push(...result.value.warnings.map((warning) => `${name}: ${warning}`));
43
+ });
44
+ return registry;
45
+ }
46
+ /** Every entry of every source, sources in their given order and keys sorted within each. */
47
+ export function offers(registry) {
48
+ return [...registry.sources.values()].flatMap((store) => Object.entries(entries(store)).sort(([a], [b]) => a.localeCompare(b)).map(([key, entry]) => ({ key, entry })));
49
+ }
50
+ /**
51
+ * File source for the core install commands: a file at `files[].path` is
52
+ * copied from `<checkout>/<origin.dir>/<path>` in the checkout of the
53
+ * entry's source.
54
+ */
55
+ export function entrySource(registry) {
56
+ return (entry) => {
57
+ const { origin } = OriginEntrySchema.pick({ origin: true }).parse(entry);
58
+ const checkout = registry.checkouts.get(origin.source);
59
+ if (checkout === undefined)
60
+ throw new Error(`source ${origin.source} of "${entry.name}" is not checked out`);
61
+ return copySource((filePath) => path.join(checkout.dir, origin.dir, filePath));
62
+ };
63
+ }
64
+ /** Registry the core install commands take, keyed by entry key. */
65
+ export function offerRegistry(selected) {
66
+ const registry = {};
67
+ for (const offer of selected)
68
+ registry[offer.key] = offer.entry;
69
+ return registry;
70
+ }
71
+ //# sourceMappingURL=sourceRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceRegistry.js","sourceRoot":"","sources":["../../src/installer/sourceRegistry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { SourceCheckout, SourceSpec } from "./types";
2
+ /**
3
+ * Resolves a source to a folder holding its files: a shallow clone for git,
4
+ * an installed or downloaded package for npm, the folder itself for local.
5
+ *
6
+ * @param projectRoot - Absolute project root; local paths and the `node_modules` lookup start there
7
+ */
8
+ export declare function checkoutSource(source: {
9
+ name: string;
10
+ spec: SourceSpec;
11
+ }, projectRoot: string): Promise<SourceCheckout>;
12
+ /** One line naming where a source comes from, e.g. `git https://github.com/me/skills.git#main`. */
13
+ export declare function describeSource(spec: SourceSpec): string;
14
+ //# sourceMappingURL=checkout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../../src/sources/checkout.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1D;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAO7H;AAED,mGAAmG;AACnG,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAMvD"}
@@ -0,0 +1,27 @@
1
+ // packages/core/src/sources/checkout.ts
2
+ import { checkoutGit } from "./git";
3
+ import { checkoutLocal } from "./local";
4
+ import { checkoutNpm } from "./npm";
5
+ /**
6
+ * Resolves a source to a folder holding its files: a shallow clone for git,
7
+ * an installed or downloaded package for npm, the folder itself for local.
8
+ *
9
+ * @param projectRoot - Absolute project root; local paths and the `node_modules` lookup start there
10
+ */
11
+ export async function checkoutSource(source, projectRoot) {
12
+ const { name, spec } = source;
13
+ switch (spec.kind) {
14
+ case "git": return checkoutGit(name, spec);
15
+ case "npm": return checkoutNpm(name, spec, projectRoot);
16
+ case "local": return checkoutLocal(name, spec, projectRoot);
17
+ }
18
+ }
19
+ /** One line naming where a source comes from, e.g. `git https://github.com/me/skills.git#main`. */
20
+ export function describeSource(spec) {
21
+ switch (spec.kind) {
22
+ case "git": return `git ${spec.url}${spec.ref === undefined ? "" : `#${spec.ref}`}`;
23
+ case "npm": return `npm ${spec.package}${spec.version === undefined ? "" : `@${spec.version}`}`;
24
+ case "local": return `local ${spec.path}`;
25
+ }
26
+ }
27
+ //# sourceMappingURL=checkout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkout.js","sourceRoot":"","sources":["../../src/sources/checkout.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAGpC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAA0C,EAAE,WAAmB;IAClG,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;IAC9B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,KAAK,EAAI,OAAO,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC7C,KAAK,KAAK,EAAI,OAAO,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;QAC1D,KAAK,OAAO,EAAE,OAAO,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,cAAc,CAAC,IAAgB;IAC7C,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,KAAK,EAAI,OAAO,OAAO,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACtF,KAAK,KAAK,EAAI,OAAO,OAAO,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QAClG,KAAK,OAAO,EAAE,OAAO,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5C,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { GitSourceSpec, SourceCheckout } from "./types";
2
+ /**
3
+ * Shallow-clones a git source into a temporary folder, at its `ref` when set
4
+ * and at the default branch otherwise, and resolves the commit it landed on.
5
+ *
6
+ * @throws when the clone fails, e.g. an unknown ref or an unreachable host
7
+ */
8
+ export declare function checkoutGit(name: string, spec: GitSourceSpec): Promise<SourceCheckout>;
9
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/sources/git.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE7D;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAW5F"}