@ai-plugin-marketplace/core 0.1.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 (136) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +67 -0
  3. package/dist/config.d.ts +47 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +38 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/core.d.ts +291 -0
  8. package/dist/index.d.ts +15 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +13 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/pipeline/build.d.ts +90 -0
  13. package/dist/pipeline/build.d.ts.map +1 -0
  14. package/dist/pipeline/build.js +224 -0
  15. package/dist/pipeline/build.js.map +1 -0
  16. package/dist/pipeline/discover.d.ts +37 -0
  17. package/dist/pipeline/discover.d.ts.map +1 -0
  18. package/dist/pipeline/discover.js +71 -0
  19. package/dist/pipeline/discover.js.map +1 -0
  20. package/dist/pipeline/init-template.d.ts +33 -0
  21. package/dist/pipeline/init-template.d.ts.map +1 -0
  22. package/dist/pipeline/init-template.js +142 -0
  23. package/dist/pipeline/init-template.js.map +1 -0
  24. package/dist/pipeline/init.d.ts +39 -0
  25. package/dist/pipeline/init.d.ts.map +1 -0
  26. package/dist/pipeline/init.js +84 -0
  27. package/dist/pipeline/init.js.map +1 -0
  28. package/dist/pipeline/load-config.d.ts +47 -0
  29. package/dist/pipeline/load-config.d.ts.map +1 -0
  30. package/dist/pipeline/load-config.js +106 -0
  31. package/dist/pipeline/load-config.js.map +1 -0
  32. package/dist/pipeline/operations.d.ts +70 -0
  33. package/dist/pipeline/operations.d.ts.map +1 -0
  34. package/dist/pipeline/operations.js +100 -0
  35. package/dist/pipeline/operations.js.map +1 -0
  36. package/dist/pipeline/scaffold.d.ts +105 -0
  37. package/dist/pipeline/scaffold.d.ts.map +1 -0
  38. package/dist/pipeline/scaffold.js +422 -0
  39. package/dist/pipeline/scaffold.js.map +1 -0
  40. package/dist/pipeline/sentinel.d.ts +127 -0
  41. package/dist/pipeline/sentinel.d.ts.map +1 -0
  42. package/dist/pipeline/sentinel.js +263 -0
  43. package/dist/pipeline/sentinel.js.map +1 -0
  44. package/dist/pipeline/types.d.ts +178 -0
  45. package/dist/pipeline/types.d.ts.map +1 -0
  46. package/dist/pipeline/types.js +26 -0
  47. package/dist/pipeline/types.js.map +1 -0
  48. package/dist/pipeline/validate.d.ts +90 -0
  49. package/dist/pipeline/validate.d.ts.map +1 -0
  50. package/dist/pipeline/validate.js +617 -0
  51. package/dist/pipeline/validate.js.map +1 -0
  52. package/dist/targets/claude/scaffold.d.ts +32 -0
  53. package/dist/targets/claude/scaffold.d.ts.map +1 -0
  54. package/dist/targets/claude/scaffold.js +48 -0
  55. package/dist/targets/claude/scaffold.js.map +1 -0
  56. package/dist/targets/claude/schemas.d.ts +119 -0
  57. package/dist/targets/claude/schemas.d.ts.map +1 -0
  58. package/dist/targets/claude/schemas.js +204 -0
  59. package/dist/targets/claude/schemas.js.map +1 -0
  60. package/dist/targets/claude/transform.d.ts +40 -0
  61. package/dist/targets/claude/transform.d.ts.map +1 -0
  62. package/dist/targets/claude/transform.js +48 -0
  63. package/dist/targets/claude/transform.js.map +1 -0
  64. package/dist/targets/claude/validate.d.ts +25 -0
  65. package/dist/targets/claude/validate.d.ts.map +1 -0
  66. package/dist/targets/claude/validate.js +263 -0
  67. package/dist/targets/claude/validate.js.map +1 -0
  68. package/dist/targets/cursor/scaffold.d.ts +29 -0
  69. package/dist/targets/cursor/scaffold.d.ts.map +1 -0
  70. package/dist/targets/cursor/scaffold.js +45 -0
  71. package/dist/targets/cursor/scaffold.js.map +1 -0
  72. package/dist/targets/cursor/schemas.d.ts +49 -0
  73. package/dist/targets/cursor/schemas.d.ts.map +1 -0
  74. package/dist/targets/cursor/schemas.js +125 -0
  75. package/dist/targets/cursor/schemas.js.map +1 -0
  76. package/dist/targets/cursor/validate.d.ts +28 -0
  77. package/dist/targets/cursor/validate.d.ts.map +1 -0
  78. package/dist/targets/cursor/validate.js +181 -0
  79. package/dist/targets/cursor/validate.js.map +1 -0
  80. package/dist/targets/gemini/bundle.d.ts +25 -0
  81. package/dist/targets/gemini/bundle.d.ts.map +1 -0
  82. package/dist/targets/gemini/bundle.js +149 -0
  83. package/dist/targets/gemini/bundle.js.map +1 -0
  84. package/dist/targets/gemini/scaffold.d.ts +28 -0
  85. package/dist/targets/gemini/scaffold.d.ts.map +1 -0
  86. package/dist/targets/gemini/scaffold.js +57 -0
  87. package/dist/targets/gemini/scaffold.js.map +1 -0
  88. package/dist/targets/gemini/schemas.d.ts +53 -0
  89. package/dist/targets/gemini/schemas.d.ts.map +1 -0
  90. package/dist/targets/gemini/schemas.js +72 -0
  91. package/dist/targets/gemini/schemas.js.map +1 -0
  92. package/dist/targets/gemini/transform.d.ts +106 -0
  93. package/dist/targets/gemini/transform.d.ts.map +1 -0
  94. package/dist/targets/gemini/transform.js +137 -0
  95. package/dist/targets/gemini/transform.js.map +1 -0
  96. package/dist/targets/gemini/validate.d.ts +26 -0
  97. package/dist/targets/gemini/validate.d.ts.map +1 -0
  98. package/dist/targets/gemini/validate.js +146 -0
  99. package/dist/targets/gemini/validate.js.map +1 -0
  100. package/dist/targets/kiro/bundle.d.ts +32 -0
  101. package/dist/targets/kiro/bundle.d.ts.map +1 -0
  102. package/dist/targets/kiro/bundle.js +106 -0
  103. package/dist/targets/kiro/bundle.js.map +1 -0
  104. package/dist/targets/kiro/scaffold.d.ts +28 -0
  105. package/dist/targets/kiro/scaffold.d.ts.map +1 -0
  106. package/dist/targets/kiro/scaffold.js +55 -0
  107. package/dist/targets/kiro/scaffold.js.map +1 -0
  108. package/dist/targets/kiro/schemas.d.ts +100 -0
  109. package/dist/targets/kiro/schemas.d.ts.map +1 -0
  110. package/dist/targets/kiro/schemas.js +147 -0
  111. package/dist/targets/kiro/schemas.js.map +1 -0
  112. package/dist/targets/kiro/transform.d.ts +53 -0
  113. package/dist/targets/kiro/transform.d.ts.map +1 -0
  114. package/dist/targets/kiro/transform.js +113 -0
  115. package/dist/targets/kiro/transform.js.map +1 -0
  116. package/dist/targets/kiro/validate.d.ts +36 -0
  117. package/dist/targets/kiro/validate.d.ts.map +1 -0
  118. package/dist/targets/kiro/validate.js +232 -0
  119. package/dist/targets/kiro/validate.js.map +1 -0
  120. package/dist/targets/scaffold-kit.d.ts +56 -0
  121. package/dist/targets/scaffold-kit.d.ts.map +1 -0
  122. package/dist/targets/scaffold-kit.js +33 -0
  123. package/dist/targets/scaffold-kit.js.map +1 -0
  124. package/dist/targets/vercel/scaffold.d.ts +34 -0
  125. package/dist/targets/vercel/scaffold.d.ts.map +1 -0
  126. package/dist/targets/vercel/scaffold.js +58 -0
  127. package/dist/targets/vercel/scaffold.js.map +1 -0
  128. package/dist/targets/vercel/schemas.d.ts +42 -0
  129. package/dist/targets/vercel/schemas.d.ts.map +1 -0
  130. package/dist/targets/vercel/schemas.js +69 -0
  131. package/dist/targets/vercel/schemas.js.map +1 -0
  132. package/dist/targets/vercel/validate.d.ts +28 -0
  133. package/dist/targets/vercel/validate.d.ts.map +1 -0
  134. package/dist/targets/vercel/validate.js +180 -0
  135. package/dist/targets/vercel/validate.js.map +1 -0
  136. package/package.json +50 -0
@@ -0,0 +1,84 @@
1
+ /**
2
+ * `runInit` — scaffold a thin consumer repo (the "template") that depends on
3
+ * `@ai-plugin-marketplace/cli` and holds plugin sources only (§3.2, §11).
4
+ *
5
+ * This is the filesystem-writing orchestrator behind the public `init` operation and the
6
+ * `aipm init [dir]` CLI surface. The generated file *contents* live in `init-template.ts`; this
7
+ * module is the I/O boundary: it resolves the toolkit version to pin, refuses to clobber a
8
+ * non-empty target, and writes the seed tree.
9
+ *
10
+ * **Version pinning (§9.1 lockstep release).** core and cli ship in lockstep, so the `cli` dev
11
+ * dependency is pinned to a caret of core's *own* version — read at runtime from this package's
12
+ * `package.json`, resolved relative to {@link import.meta.url} exactly as `load-config.ts` resolves
13
+ * the package entrypoint. Today that yields `^0.1.0-alpha.0`; once 0.1.0 ships, an `init` run from
14
+ * the published cli pins `^0.1.0`.
15
+ *
16
+ * @see docs/specs/architecture.md §3.2 (template repo contents)
17
+ * @see docs/specs/architecture.md §9.1 (lockstep release lines)
18
+ * @see docs/specs/architecture.md §11 (template→toolkit dependency contract)
19
+ */
20
+ import * as fs from 'node:fs';
21
+ import * as path from 'node:path';
22
+ import { fileURLToPath } from 'node:url';
23
+ import { buildInitFiles } from './init-template.js';
24
+ /**
25
+ * Read this package's `package.json#version`, resolved relative to this module's location.
26
+ *
27
+ * When bundled to `dist/pipeline/init.js` this resolves `<pkgRoot>/package.json`; when run from
28
+ * source as `src/pipeline/init.ts` it resolves the same file (both sit two levels up). Mirrors the
29
+ * version-resolution approach in `cli/src/run.ts` and the entrypoint resolution in
30
+ * `load-config.ts`.
31
+ */
32
+ function coreVersion() {
33
+ const here = fileURLToPath(import.meta.url);
34
+ // here = <pkgRoot>/<src|dist>/pipeline/init.<ts|js>; package.json sits two levels up.
35
+ const pkgPath = path.join(path.dirname(here), '..', '..', 'package.json');
36
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
37
+ return pkg.version;
38
+ }
39
+ /**
40
+ * True iff `dir` does not exist, or exists as an empty directory. A non-empty directory (or a
41
+ * path that exists as a non-directory) is treated as "would clobber".
42
+ */
43
+ function isFreshTarget(dir) {
44
+ if (!fs.existsSync(dir))
45
+ return true;
46
+ const stat = fs.statSync(dir);
47
+ if (!stat.isDirectory())
48
+ return false;
49
+ return fs.readdirSync(dir).length === 0;
50
+ }
51
+ /**
52
+ * Scaffold a thin consumer repo at `targetDir` (§3.2).
53
+ *
54
+ * Writes `package.json` (with the `@ai-plugin-marketplace/cli` dev dependency pinned to a caret of
55
+ * the current toolkit version), `.gitignore`, `README.md`, both repo-root marketplace registries
56
+ * (`{ "plugins": [] }`), an empty `plugins/` (tracked via `.gitkeep`), and a CI workflow that runs
57
+ * `aipm build` then `aipm validate` (§10.5 freshness). The repo name defaults to
58
+ * `basename(targetDir)`; override it with `opts.name`.
59
+ *
60
+ * **Refuses to clobber.** If `targetDir` exists and is a non-empty directory (or exists as a
61
+ * non-directory), the function throws and writes nothing. Creating into a fresh or empty directory
62
+ * is fine.
63
+ *
64
+ * @param targetDir - Absolute or relative path to the directory to scaffold into.
65
+ * @param opts - Init options; `name` overrides the derived repo name.
66
+ * @throws {Error} When `targetDir` exists and is non-empty (or is not a directory).
67
+ */
68
+ export async function runInit(targetDir, opts = {}) {
69
+ const resolved = path.resolve(targetDir);
70
+ if (!isFreshTarget(resolved)) {
71
+ throw new Error(`Refusing to scaffold into '${resolved}': the directory already exists and is not empty. ` +
72
+ 'Choose a new path or an empty directory.');
73
+ }
74
+ const name = opts.name ?? path.basename(resolved);
75
+ const files = buildInitFiles(name, coreVersion());
76
+ fs.mkdirSync(resolved, { recursive: true });
77
+ for (const file of files) {
78
+ const full = path.join(resolved, file.path);
79
+ fs.mkdirSync(path.dirname(full), { recursive: true });
80
+ fs.writeFileSync(full, file.content, 'utf-8');
81
+ }
82
+ return Promise.resolve();
83
+ }
84
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/pipeline/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD;;;;;;;GAOG;AACH,SAAS,WAAW;IAClB,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5C,sFAAsF;IACtF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAwB,CAAC;IACjF,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;QAAE,OAAO,KAAK,CAAC;IACtC,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,SAAiB,EAAE,OAAoB,EAAE;IACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEzC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,8BAA8B,QAAQ,oDAAoD;YACxF,0CAA0C,CAC7C,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IAElD,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Runtime loader for a plugin's `aipm.config.ts` envelope (§6.1, P6).
3
+ *
4
+ * `aipm.config.ts` is authored in TypeScript and imports `defineConfig` from
5
+ * `@ai-plugin-marketplace/core`. The build (§5.2) and validate (§5.3) orchestrators need to
6
+ * evaluate that module at runtime to read its `default` export. We use {@link https://github.com/unjs/jiti | jiti}
7
+ * to transpile-and-import the TS module on the fly, then re-run it through {@link defineConfig}
8
+ * so the result is a properly-branded {@link AipmConfig} regardless of what the on-disk module
9
+ * happened to call.
10
+ *
11
+ * **Module resolution.** A plugin's `aipm.config.ts` can live anywhere on disk (including a
12
+ * temp dir during tests), so a bare `import '@ai-plugin-marketplace/core'` would not resolve
13
+ * by walking up from the config file. We register a jiti `alias` mapping the package specifier
14
+ * to this package's own entrypoint, derived from {@link import.meta.url}. The alias is
15
+ * extension-less so jiti resolves `index.ts` when running from source (vitest) and `index.js`
16
+ * when running from the compiled `dist/` (production) — both verified working.
17
+ *
18
+ * @see docs/specs/architecture.md §6.1 (envelope declaration), P6 (TypeScript end-to-end)
19
+ * @see docs/specs/architecture.md §5.2, §5.3 (build/validate consume the loaded envelope)
20
+ */
21
+ import type { AipmConfig } from '../config.js';
22
+ /** The canonical config filename every plugin must provide (§6.1). */
23
+ export declare const AIPM_CONFIG_FILENAME = "aipm.config.ts";
24
+ /**
25
+ * Error thrown when a plugin's `aipm.config.ts` cannot be located, imported, or validated.
26
+ * The build orchestrator surfaces this as a thrown error; the validate orchestrator catches it
27
+ * and converts it into an `envelope-invalid` finding (§10.1 step 1).
28
+ */
29
+ export declare class ConfigLoadError extends Error {
30
+ constructor(message: string, options?: {
31
+ cause?: unknown;
32
+ });
33
+ }
34
+ /**
35
+ * Load and validate a plugin's `aipm.config.ts`, returning the branded {@link AipmConfig}.
36
+ *
37
+ * The on-disk module's `default` export is re-validated through {@link defineConfig} so callers
38
+ * receive a value that provably passed the canonical Zod schema — even if the author bypassed
39
+ * `defineConfig` in their source (e.g. exported a plain object literal).
40
+ *
41
+ * @param pluginDir - Absolute path to the `plugins/<name>/` directory.
42
+ * @returns The validated, branded config.
43
+ * @throws {ConfigLoadError} If the file is absent, fails to import, has no default export, or
44
+ * the default export fails schema validation.
45
+ */
46
+ export declare function loadPluginConfig(pluginDir: string): Promise<AipmConfig>;
47
+ //# sourceMappingURL=load-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-config.d.ts","sourceRoot":"","sources":["../../src/pipeline/load-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AASH,OAAO,KAAK,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAEhE,sEAAsE;AACtE,eAAO,MAAM,oBAAoB,mBAAmB,CAAC;AAKrD;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D;AAmBD;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA4C7E"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Runtime loader for a plugin's `aipm.config.ts` envelope (§6.1, P6).
3
+ *
4
+ * `aipm.config.ts` is authored in TypeScript and imports `defineConfig` from
5
+ * `@ai-plugin-marketplace/core`. The build (§5.2) and validate (§5.3) orchestrators need to
6
+ * evaluate that module at runtime to read its `default` export. We use {@link https://github.com/unjs/jiti | jiti}
7
+ * to transpile-and-import the TS module on the fly, then re-run it through {@link defineConfig}
8
+ * so the result is a properly-branded {@link AipmConfig} regardless of what the on-disk module
9
+ * happened to call.
10
+ *
11
+ * **Module resolution.** A plugin's `aipm.config.ts` can live anywhere on disk (including a
12
+ * temp dir during tests), so a bare `import '@ai-plugin-marketplace/core'` would not resolve
13
+ * by walking up from the config file. We register a jiti `alias` mapping the package specifier
14
+ * to this package's own entrypoint, derived from {@link import.meta.url}. The alias is
15
+ * extension-less so jiti resolves `index.ts` when running from source (vitest) and `index.js`
16
+ * when running from the compiled `dist/` (production) — both verified working.
17
+ *
18
+ * @see docs/specs/architecture.md §6.1 (envelope declaration), P6 (TypeScript end-to-end)
19
+ * @see docs/specs/architecture.md §5.2, §5.3 (build/validate consume the loaded envelope)
20
+ */
21
+ import * as fs from 'node:fs';
22
+ import * as path from 'node:path';
23
+ import { fileURLToPath } from 'node:url';
24
+ import { createJiti } from 'jiti';
25
+ import { defineConfig } from '../config.js';
26
+ /** The canonical config filename every plugin must provide (§6.1). */
27
+ export const AIPM_CONFIG_FILENAME = 'aipm.config.ts';
28
+ /** The npm specifier a plugin's `aipm.config.ts` imports `defineConfig` from. */
29
+ const CORE_PACKAGE_SPECIFIER = '@ai-plugin-marketplace/core';
30
+ /**
31
+ * Error thrown when a plugin's `aipm.config.ts` cannot be located, imported, or validated.
32
+ * The build orchestrator surfaces this as a thrown error; the validate orchestrator catches it
33
+ * and converts it into an `envelope-invalid` finding (§10.1 step 1).
34
+ */
35
+ export class ConfigLoadError extends Error {
36
+ constructor(message, options) {
37
+ super(message, options);
38
+ this.name = 'ConfigLoadError';
39
+ }
40
+ }
41
+ /**
42
+ * Absolute path to this package's public entrypoint, **without** a file extension, derived from
43
+ * the location of this module. When bundled to `dist/pipeline/load-config.js` this resolves to
44
+ * `dist/index`; when run from source as `src/pipeline/load-config.ts` it resolves to `src/index`.
45
+ * jiti's resolver appends the correct extension in each case.
46
+ */
47
+ function corePackageEntrypoint() {
48
+ const here = fileURLToPath(import.meta.url);
49
+ // here = <pkgRoot>/<src|dist>/pipeline/load-config.<ts|js>; index sits two levels up.
50
+ return path.join(path.dirname(here), '..', 'index');
51
+ }
52
+ /** Absolute path to a plugin's `aipm.config.ts`, given the plugin directory. */
53
+ function configPathFor(pluginDir) {
54
+ return path.join(pluginDir, AIPM_CONFIG_FILENAME);
55
+ }
56
+ /**
57
+ * Load and validate a plugin's `aipm.config.ts`, returning the branded {@link AipmConfig}.
58
+ *
59
+ * The on-disk module's `default` export is re-validated through {@link defineConfig} so callers
60
+ * receive a value that provably passed the canonical Zod schema — even if the author bypassed
61
+ * `defineConfig` in their source (e.g. exported a plain object literal).
62
+ *
63
+ * @param pluginDir - Absolute path to the `plugins/<name>/` directory.
64
+ * @returns The validated, branded config.
65
+ * @throws {ConfigLoadError} If the file is absent, fails to import, has no default export, or
66
+ * the default export fails schema validation.
67
+ */
68
+ export async function loadPluginConfig(pluginDir) {
69
+ const configPath = configPathFor(pluginDir);
70
+ if (!fs.existsSync(configPath)) {
71
+ throw new ConfigLoadError(`No ${AIPM_CONFIG_FILENAME} found in ${pluginDir}. Every plugin must declare a support envelope (spec §6.1).`);
72
+ }
73
+ const jiti = createJiti(import.meta.url, {
74
+ alias: { [CORE_PACKAGE_SPECIFIER]: corePackageEntrypoint() },
75
+ // Disable the default↔namespace interop so a config with no `default` export reads as a
76
+ // genuinely-absent default rather than jiti synthesizing one from the namespace.
77
+ interopDefault: false,
78
+ // Disable caches so repeated loads (e.g. freshness re-reads) see current disk state.
79
+ moduleCache: false,
80
+ fsCache: false,
81
+ });
82
+ let mod;
83
+ try {
84
+ mod = await jiti.import(configPath);
85
+ }
86
+ catch (err) {
87
+ const message = err instanceof Error ? err.message : String(err);
88
+ throw new ConfigLoadError(`Failed to import ${AIPM_CONFIG_FILENAME}: ${message}`, {
89
+ cause: err,
90
+ });
91
+ }
92
+ const defaultExport = mod['default'];
93
+ if (defaultExport === undefined || defaultExport === null) {
94
+ throw new ConfigLoadError(`${AIPM_CONFIG_FILENAME} in ${pluginDir} has no default export. Export the result of \`defineConfig({...})\` as default.`);
95
+ }
96
+ // Re-validate through defineConfig so the result is a branded AipmConfig. defineConfig throws
97
+ // a ZodError on malformed input; wrap it so callers get a single ConfigLoadError type.
98
+ try {
99
+ return defineConfig(defaultExport);
100
+ }
101
+ catch (err) {
102
+ const message = err instanceof Error ? err.message : String(err);
103
+ throw new ConfigLoadError(`Invalid ${AIPM_CONFIG_FILENAME}: ${message}`, { cause: err });
104
+ }
105
+ }
106
+ //# sourceMappingURL=load-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../src/pipeline/load-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Public operation implementations.
3
+ *
4
+ * Each function here is a thin adapter over a pipeline orchestrator, with the pinned public
5
+ * signature from §8.1 of the spec. Business logic lives in the orchestrators
6
+ * (`build.ts`, `validate.ts`, `scaffold.ts`); this module only adapts arguments (e.g. deriving
7
+ * the plugins directory from the cwd for `scaffold`, and reading the CI environment for the
8
+ * freshness severity) so the public contract stays stable as implementations evolve.
9
+ *
10
+ * @see docs/specs/architecture.md §8.1
11
+ */
12
+ import type { BuildOptions, BuildResult, InitOptions, MigrateOptions, MigrateResult, ScaffoldOptions, SupportReport, TargetId, ValidateOptions, ValidationResult } from './types.js';
13
+ /**
14
+ * Build a single plugin or every plugin under a repo root. `path` may be a plugin directory
15
+ * (contains `aipm.config.ts`) or a repo root (contains `plugins/`); the orchestrator detects
16
+ * which and returns a length-1 array for single-plugin input. See §5.2, §8.1.
17
+ *
18
+ * @public
19
+ */
20
+ export declare function build(targetPath: string, opts?: BuildOptions): Promise<BuildResult[]>;
21
+ /**
22
+ * Validate a single plugin or every plugin under a repo root, in the order defined by §10.1.
23
+ * Freshness severity follows the CI environment (§10.2).
24
+ *
25
+ * @public
26
+ */
27
+ export declare function validate(targetPath: string, opts?: ValidateOptions): Promise<ValidationResult>;
28
+ /**
29
+ * Scaffold a thin consumer repo (the "template") at `targetDir` that depends on
30
+ * `@ai-plugin-marketplace/cli` and holds plugin sources only (§3.2, §11). The generated
31
+ * `package.json` pins the cli dev dependency to a caret of the current toolkit version (§9.1
32
+ * lockstep). Refuses to write into a non-empty directory.
33
+ *
34
+ * @public
35
+ */
36
+ export declare function init(targetDir: string, opts?: InitOptions): Promise<void>;
37
+ /**
38
+ * Scaffold a new plugin under `<cwd>/plugins/<name>`. The plugins directory is derived from the
39
+ * current working directory, matching how `aipm scaffold` is invoked from a template repo root.
40
+ *
41
+ * @public
42
+ */
43
+ export declare function scaffold(name: string, opts?: ScaffoldOptions): Promise<void>;
44
+ /**
45
+ * No-op in v0.1.0 per §8.1 of the spec. Always returns `status: 'no-migrations-needed'` because
46
+ * §9.4 constrains every `schemaVersion` to a single value. When real migrations ship, this
47
+ * must distinguish up-to-date from unknown-future-version.
48
+ *
49
+ * @public
50
+ */
51
+ export declare function migrate(_path: string, _opts?: MigrateOptions): Promise<MigrateResult>;
52
+ /**
53
+ * Diagnose a plugin's support envelope: declared targets, missing artifacts, addable targets (§6.4).
54
+ *
55
+ * @public
56
+ */
57
+ export declare function checkSupport(pluginDir: string): Promise<SupportReport>;
58
+ /**
59
+ * Scaffold skeleton files for a new target in an existing plugin (§6.4).
60
+ *
61
+ * @public
62
+ */
63
+ export declare function addTarget(pluginDir: string, target: TargetId): Promise<void>;
64
+ /**
65
+ * List the target IDs this toolkit version knows about (§6.4).
66
+ *
67
+ * @public
68
+ */
69
+ export declare function listTargets(): readonly TargetId[];
70
+ //# sourceMappingURL=operations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/pipeline/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,cAAc,EACd,aAAa,EACb,eAAe,EACf,aAAa,EACb,QAAQ,EACR,eAAe,EACf,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAOpB;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAErF;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAE9F;AAED;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhF;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAMrF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAEtE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,SAAS,QAAQ,EAAE,CAEjD"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Public operation implementations.
3
+ *
4
+ * Each function here is a thin adapter over a pipeline orchestrator, with the pinned public
5
+ * signature from §8.1 of the spec. Business logic lives in the orchestrators
6
+ * (`build.ts`, `validate.ts`, `scaffold.ts`); this module only adapts arguments (e.g. deriving
7
+ * the plugins directory from the cwd for `scaffold`, and reading the CI environment for the
8
+ * freshness severity) so the public contract stays stable as implementations evolve.
9
+ *
10
+ * @see docs/specs/architecture.md §8.1
11
+ */
12
+ import * as path from 'node:path';
13
+ import { runBuild } from './build.js';
14
+ import { runInit } from './init.js';
15
+ import { runScaffold, runAddTarget, runCheckSupport } from './scaffold.js';
16
+ import { TARGET_IDS } from './types.js';
17
+ import { runValidate } from './validate.js';
18
+ /** True when running in a CI environment. Freshness findings are hard in CI, soft locally (§10.2). */
19
+ function isCi() {
20
+ return Boolean(process.env['CI']);
21
+ }
22
+ /**
23
+ * Build a single plugin or every plugin under a repo root. `path` may be a plugin directory
24
+ * (contains `aipm.config.ts`) or a repo root (contains `plugins/`); the orchestrator detects
25
+ * which and returns a length-1 array for single-plugin input. See §5.2, §8.1.
26
+ *
27
+ * @public
28
+ */
29
+ export function build(targetPath, opts) {
30
+ return runBuild(targetPath, opts);
31
+ }
32
+ /**
33
+ * Validate a single plugin or every plugin under a repo root, in the order defined by §10.1.
34
+ * Freshness severity follows the CI environment (§10.2).
35
+ *
36
+ * @public
37
+ */
38
+ export function validate(targetPath, opts) {
39
+ return runValidate(targetPath, { ...opts, ci: isCi() });
40
+ }
41
+ /**
42
+ * Scaffold a thin consumer repo (the "template") at `targetDir` that depends on
43
+ * `@ai-plugin-marketplace/cli` and holds plugin sources only (§3.2, §11). The generated
44
+ * `package.json` pins the cli dev dependency to a caret of the current toolkit version (§9.1
45
+ * lockstep). Refuses to write into a non-empty directory.
46
+ *
47
+ * @public
48
+ */
49
+ export function init(targetDir, opts) {
50
+ return runInit(targetDir, opts);
51
+ }
52
+ /**
53
+ * Scaffold a new plugin under `<cwd>/plugins/<name>`. The plugins directory is derived from the
54
+ * current working directory, matching how `aipm scaffold` is invoked from a template repo root.
55
+ *
56
+ * @public
57
+ */
58
+ export function scaffold(name, opts = {}) {
59
+ const pluginsDir = path.join(process.cwd(), 'plugins');
60
+ return runScaffold(name, pluginsDir, opts);
61
+ }
62
+ /**
63
+ * No-op in v0.1.0 per §8.1 of the spec. Always returns `status: 'no-migrations-needed'` because
64
+ * §9.4 constrains every `schemaVersion` to a single value. When real migrations ship, this
65
+ * must distinguish up-to-date from unknown-future-version.
66
+ *
67
+ * @public
68
+ */
69
+ export function migrate(_path, _opts) {
70
+ return Promise.resolve({
71
+ status: 'no-migrations-needed',
72
+ migrationsApplied: 0,
73
+ filesChanged: [],
74
+ });
75
+ }
76
+ /**
77
+ * Diagnose a plugin's support envelope: declared targets, missing artifacts, addable targets (§6.4).
78
+ *
79
+ * @public
80
+ */
81
+ export function checkSupport(pluginDir) {
82
+ return runCheckSupport(pluginDir);
83
+ }
84
+ /**
85
+ * Scaffold skeleton files for a new target in an existing plugin (§6.4).
86
+ *
87
+ * @public
88
+ */
89
+ export function addTarget(pluginDir, target) {
90
+ return runAddTarget(pluginDir, target);
91
+ }
92
+ /**
93
+ * List the target IDs this toolkit version knows about (§6.4).
94
+ *
95
+ * @public
96
+ */
97
+ export function listTargets() {
98
+ return TARGET_IDS;
99
+ }
100
+ //# sourceMappingURL=operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/pipeline/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAc5C,sGAAsG;AACtG,SAAS,IAAI;IACX,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,UAAkB,EAAE,IAAmB;IAC3D,OAAO,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,UAAkB,EAAE,IAAsB;IACjE,OAAO,WAAW,CAAC,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAAC,SAAiB,EAAE,IAAkB;IACxD,OAAO,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAwB,EAAE;IAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;IACvD,OAAO,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,KAAsB;IAC3D,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,MAAM,EAAE,sBAAsB;QAC9B,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,EAAE;KACjB,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,OAAO,eAAe,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,SAAiB,EAAE,MAAgB;IAC3D,OAAO,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Pipeline orchestration for scaffolding and compatibility-assist (§6.4).
3
+ *
4
+ * Three orchestrators perform filesystem I/O around the per-target *pure* scaffold functions:
5
+ *
6
+ * - `runScaffold` — create a brand-new plugin (the `aipm scaffold` surface).
7
+ * - `runAddTarget` — add one target's skeleton to an existing plugin (`aipm add-target`).
8
+ * - `runCheckSupport` — report declared-but-incomplete and plausibly-addable targets
9
+ * (`aipm check-support`).
10
+ *
11
+ * Per §3.4/§12.4 the pipeline layer is the orchestration boundary and MAY import each target's
12
+ * `scaffold.ts`; the per-target scaffold modules themselves never import one another.
13
+ *
14
+ * Envelope reading (§6.1): loading and executing a TypeScript `aipm.config.ts` from disk is the
15
+ * build orchestrator's job and is not yet built. `runCheckSupport`/`runAddTarget` therefore read
16
+ * the declared targets *pragmatically* — by extracting the `targets: [...]` array literal out of
17
+ * the config source text (see `parseDeclaredTargets`). This tolerates the canonical
18
+ * `defineConfig({ ... })` form this module emits and common hand-authored variants, but it is a
19
+ * lexical heuristic, not a TS evaluation. Documented limitation: a config that computes `targets`
20
+ * dynamically (spread, variable reference, conditional) is not understood and yields an error.
21
+ *
22
+ * @see docs/specs/architecture.md §6 (support envelope)
23
+ * @see docs/specs/architecture.md §6.4 (compatibility-assist tooling)
24
+ * @see docs/specs/architecture.md §10.1 (validation contract — artifact tables reused here)
25
+ * @see docs/specs/architecture.md §12.5 (per-target scaffold.ts)
26
+ */
27
+ import type { ScaffoldOptions, SupportReport, TargetId } from './types.js';
28
+ /**
29
+ * Validate a plugin name against the canonical slug rules shared by every manifest schema:
30
+ * lowercase, starts with a letter, `[a-z0-9-]` only, no consecutive hyphens, no trailing hyphen.
31
+ *
32
+ * @throws Error with a clear message when the name is invalid.
33
+ */
34
+ export declare function validatePluginName(name: string): void;
35
+ /**
36
+ * Render the canonical `aipm.config.ts` source for a plugin with the given targets.
37
+ *
38
+ * Emits a `defineConfig({ version, targets })` literal importing from the public package root
39
+ * (§8.1 — the only public subpath). Deterministic: stable target ordering, no timestamps.
40
+ */
41
+ export declare function renderAipmConfig(targets: readonly TargetId[]): string;
42
+ /**
43
+ * Extract the declared targets from `aipm.config.ts` source text.
44
+ *
45
+ * Lexical heuristic (see module doc): finds the first `targets:` key and parses the immediately
46
+ * following `[...]` array of single/double-quoted string literals. Only IDs in `TARGET_IDS` are
47
+ * returned; unknown IDs are ignored (the shape validator surfaces those separately).
48
+ *
49
+ * @returns Declared target IDs in canonical order, deduplicated.
50
+ * @throws Error when no `targets: [...]` array literal can be located.
51
+ */
52
+ export declare function parseDeclaredTargets(configSource: string): TargetId[];
53
+ /**
54
+ * Create a brand-new plugin under `pluginsDir/<name>/`.
55
+ *
56
+ * Writes `aipm.config.ts` (via the `defineConfig` literal), each declared target's skeleton
57
+ * files, and the canonical `README.md` / `LICENSE`. Default targets are all known IDs when
58
+ * `opts.targets` is absent.
59
+ *
60
+ * Also registers the plugin in the template-level marketplace registries (§4.4) for each of
61
+ * Claude/Cursor in the envelope (`repoRoot = dirname(pluginsDir)`), so the scaffolded plugin
62
+ * passes `validate`'s `marketplace-registration` check (§10.1.4) out of the box.
63
+ *
64
+ * @throws Error when `name` is invalid or the plugin directory already exists.
65
+ */
66
+ export declare function runScaffold(name: string, pluginsDir: string, opts?: ScaffoldOptions): Promise<void>;
67
+ /**
68
+ * Scaffold one target's skeleton files into an existing plugin (§6.4 `aipm add-target`).
69
+ *
70
+ * Manifest fields are emitted as placeholders for the author to complete. Existing files are
71
+ * NEVER clobbered: if any file this target would write already exists, the function refuses and
72
+ * throws — the author resolves the conflict deliberately.
73
+ *
74
+ * The plugin's `aipm.config.ts` is updated to include `target` in its `targets` array when the
75
+ * lexical reader can locate the array (see module doc). Limitation: if the array cannot be parsed
76
+ * (dynamic/computed targets), the config is left untouched and the error message instructs the
77
+ * author to add the target manually — the function never leaves the envelope silently
78
+ * inconsistent.
79
+ *
80
+ * When `target` is Claude or Cursor, the plugin is also registered in the corresponding
81
+ * repo-root marketplace registry (§4.4) so adding the target keeps `validate` green. repoRoot is
82
+ * the plugin's grandparent (`<repoRoot>/plugins/<name>`), matching `discoverPlugins`.
83
+ *
84
+ * @throws Error when `pluginDir` does not exist, a target file already exists, or the config's
85
+ * targets array cannot be located for the update.
86
+ */
87
+ export declare function runAddTarget(pluginDir: string, target: TargetId): Promise<void>;
88
+ /**
89
+ * Report a plugin's support posture (§6.4 `aipm check-support`).
90
+ *
91
+ * Reads the declared envelope from `aipm.config.ts` (lexically — see module doc), then:
92
+ * - `missingArtifacts`: for each declared target, the `TARGET_MIN_REQUIRED` files absent on disk
93
+ * (Vercel's "at least one SKILL.md under a skills subdirectory" rule is applied specially,
94
+ * mirroring the
95
+ * validator). Only targets with at least one missing artifact appear.
96
+ * - `suggestions`: each undeclared known target, with `wouldNeed` = that target's min-required
97
+ * files (the concrete list of files the author would write to add it).
98
+ *
99
+ * Reuses the validator's `TARGET_MIN_REQUIRED` table so "missing" stays consistent with
100
+ * `aipm validate`.
101
+ *
102
+ * @throws Error when `pluginDir` or its `aipm.config.ts` is missing, or the envelope is unreadable.
103
+ */
104
+ export declare function runCheckSupport(pluginDir: string): Promise<SupportReport>;
105
+ //# sourceMappingURL=scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/pipeline/scaffold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAaH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AA0B3E;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAerD;AAMD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAUrE;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,QAAQ,EAAE,CAcrE;AAmJD;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCrF;AAmCD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA+B/E"}