alepha 0.19.2 → 0.19.3

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 (61) hide show
  1. package/dist/api/jobs/index.d.ts +24 -24
  2. package/dist/api/jobs/index.d.ts.map +1 -1
  3. package/dist/api/jobs/index.js +10 -4
  4. package/dist/api/jobs/index.js.map +1 -1
  5. package/dist/api/keys/index.d.ts +5 -5
  6. package/dist/api/users/index.d.ts +9 -19
  7. package/dist/api/users/index.d.ts.map +1 -1
  8. package/dist/api/verifications/index.d.ts +13 -13
  9. package/dist/cli/config/index.d.ts +6 -28
  10. package/dist/cli/config/index.d.ts.map +1 -1
  11. package/dist/cli/config/index.js +5 -10
  12. package/dist/cli/config/index.js.map +1 -1
  13. package/dist/cli/core/index.d.ts +11653 -208
  14. package/dist/cli/core/index.d.ts.map +1 -1
  15. package/dist/cli/core/index.js +48 -12
  16. package/dist/cli/core/index.js.map +1 -1
  17. package/dist/cli/devtools/index.d.ts +5 -0
  18. package/dist/cli/devtools/index.d.ts.map +1 -1
  19. package/dist/cli/devtools/index.js +4 -0
  20. package/dist/cli/devtools/index.js.map +1 -1
  21. package/dist/cli/platform/index.d.ts +69 -64
  22. package/dist/cli/platform/index.d.ts.map +1 -1
  23. package/dist/cli/platform/index.js +6 -2
  24. package/dist/cli/platform/index.js.map +1 -1
  25. package/dist/cli/vendor/index.d.ts +7 -2
  26. package/dist/cli/vendor/index.d.ts.map +1 -1
  27. package/dist/cli/vendor/index.js +6 -2
  28. package/dist/cli/vendor/index.js.map +1 -1
  29. package/dist/core/index.browser.js.map +1 -1
  30. package/dist/core/index.d.ts.map +1 -1
  31. package/dist/core/index.js +4 -0
  32. package/dist/core/index.js.map +1 -1
  33. package/dist/core/index.native.js +4 -0
  34. package/dist/core/index.native.js.map +1 -1
  35. package/dist/core/index.workerd.js +4 -0
  36. package/dist/core/index.workerd.js.map +1 -1
  37. package/dist/logger/index.d.ts.map +1 -1
  38. package/dist/logger/index.js +1 -1
  39. package/dist/logger/index.js.map +1 -1
  40. package/dist/orm/core/index.bun.js +25 -56
  41. package/dist/orm/core/index.bun.js.map +1 -1
  42. package/dist/orm/core/index.d.ts +9 -19
  43. package/dist/orm/core/index.d.ts.map +1 -1
  44. package/dist/orm/core/index.js +25 -56
  45. package/dist/orm/core/index.js.map +1 -1
  46. package/dist/orm/postgres/index.d.ts +2 -1
  47. package/dist/orm/postgres/index.d.ts.map +1 -1
  48. package/package.json +6 -6
  49. package/src/api/jobs/providers/JobProvider.ts +10 -6
  50. package/src/cli/config/defineConfig.ts +17 -46
  51. package/src/cli/core/providers/ViteDevServerProvider.ts +45 -3
  52. package/src/cli/core/services/PackageManagerUtils.ts +3 -1
  53. package/src/cli/core/services/ProjectScaffolder.ts +5 -5
  54. package/src/cli/core/templates/agentMd.ts +14 -5
  55. package/src/cli/devtools/index.ts +21 -1
  56. package/src/cli/platform/index.ts +23 -2
  57. package/src/cli/vendor/index.ts +20 -3
  58. package/src/core/Alepha.ts +10 -0
  59. package/src/logger/index.ts +6 -1
  60. package/src/orm/core/providers/DrizzleKitProvider.ts +56 -105
  61. package/tsconfig.base.json +0 -1
@@ -165,6 +165,11 @@ declare class VendorCommand {
165
165
  }
166
166
  //#endregion
167
167
  //#region ../../src/cli/vendor/index.d.ts
168
+ declare module "alepha/cli/config" {
169
+ interface AlephaCliConfig {
170
+ vendor?: VendorOptions;
171
+ }
172
+ }
168
173
  /**
169
174
  * CLI plugin for vendoring Alepha packages into external projects.
170
175
  *
@@ -179,10 +184,10 @@ declare class VendorCommand {
179
184
  * Configuration in `alepha.config.ts`:
180
185
  *
181
186
  * ```typescript
182
- * import { AlephaCliVendor } from "alepha/cli/vendor";
187
+ * import { AlephaCliVendorPlugin } from "alepha/cli/vendor";
183
188
  *
184
189
  * export default defineConfig({
185
- * services: [AlephaCliVendor],
190
+ * services: [AlephaCliVendorPlugin],
186
191
  * vendor: {
187
192
  * branch: "main",
188
193
  * packages: ["alepha", "@alepha/bucket-s3"],
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/cli/vendor/atoms/vendorOptions.ts","../../../src/cli/vendor/services/VendorService.ts","../../../src/cli/vendor/commands/VendorCommand.ts","../../../src/cli/vendor/index.ts"],"mappings":";;;;;;;;;;;;;;;cAQa,aAAA,EAAa,QAAA,CAAA,IAAA,CAAA,QAAA,CAAA,SAAA,UAAA,OAAA;;AAA1B;;;;6BA2BE,QAAA,CAAA,OAAA;;;;;;;EA3BwB;;;;;;;;;;KAgCd,aAAA,GAAgB,MAAA,QAAc,aAAA,CAAc,MAAA;;;;;;UCjCvC,iBAAA;EACf,IAAA;EACA,MAAA;EACA,MAAA;EACA,QAAA;EACA,KAAA;AAAA;;;;UAMe,gBAAA;EACf,MAAA;EACA,MAAA;EACA,OAAA,GAAU,gBAAA;AAAA;;;;UAMK,iBAAA;EACf,IAAA;EACA,MAAA;EACA,MAAA;EACA,QAAA;AAAA;;;;UAMe,iBAAA;EACf,IAAA;EACA,KAAA;EACA,QAAA;EACA,OAAA;AAAA;ADDF;;;AAAA,UCOiB,gBAAA;EACf,QAAA,EAAU,iBAAA;EACV,YAAA;AAAA;;;;cAMW,aAAA;EAAA,mBACQ,GAAA,EADK,gBAAA,CACF,MAAA;EAAA,mBACH,KAAA,EAAK,aAAA;EAAA,mBACL,EAAA,EAAE,kBAAA;;;;;;;;;EAUf,IAAA,CAAK,OAAA,EAAS,iBAAA,GAAoB,OAAA,CAAQ,gBAAA;EAlDjC;;;;;;EAsGT,IAAA,CAAK,OAAA,EAAS,iBAAA,GAAoB,OAAA,CAAQ,gBAAA;EAnGtC;;;EAAA,UAmHM,aAAA,CACd,IAAA,UACA,MAAA,UACA,QAAA,aACC,OAAA,CAAQ,gBAAA;EAjHqB;;;EAAA,UA4KhB,kBAAA,CAAmB,MAAA,WAAiB,OAAA;EA1KpD;;;EAAA,UAgNgB,WAAA,CAAY,MAAA,UAAgB,MAAA,WAAiB,OAAA;EA9MrD;AAMV;;EANU,mBAqOW,YAAA;EA/Na;;;EAAA,UAyOtB,SAAA,CAAU,QAAA;EArOpB;;;EAAA,UAyPgB,eAAA,CACd,QAAA,UACA,SAAA,WACC,OAAA;IAAU,KAAA;IAAiB,QAAA;IAAoB,OAAA;EAAA;AAAA;;;cCrRvC,aAAA;EAAA,mBACQ,GAAA,EADK,gBAAA,CACF,MAAA;EAAA,mBACH,OAAA,EAAO,QAAA;;;;;qBACP,aAAA,EAAa,aAAA;EAAA,mBACb,KAAA,EAAK,oBAAA;EAAA,mBACL,EAAA,EAAE,mBAAA;;;;YAKX,cAAA,CAAA;;;;;qBAiBS,SAAA,WAAS,OAAA;8BAtBP,QAAA,CAAA,QAAA;EAAA;EAAA,mBA+BF,IAAA,oBAAI,gBAAA,UAAA,OAAA;8BATK,QAAA,CAAA,QAAA;EAAA,IASL,QAAA,CAAA,OAAA;qBAmFJ,IAAA,EAAI,iBAAA,CAAA,gBAAA,CAAA,QAAA,CAAA,OAAA,CAnFA,QAAA,CAmFA,WAAA,GAAA,QAAA,CAAA,OAAA,EAAA,QAAA,CAAA,OAAA,CAAA,QAAA,CAAA,WAAA;EAAA,SA4DP,MAAA,EAAM,iBAAA,CAAA,gBAAA,CAAA,QAAA,CAAA,OAAA,CA5DC,QAAA,CA4DD,WAAA,GAAA,QAAA,CAAA,OAAA,EAAA,QAAA,CAAA,OAAA,CAAA,QAAA,CAAA,WAAA;AAAA;;;;;;;;;;;;AF3LxB;;;;;;;;;;;;;;;;cGwBa,qBAAA,EAAqB,QAAA,CAAA,OAAA,CAIhC,QAAA,CAJgC,MAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/cli/vendor/atoms/vendorOptions.ts","../../../src/cli/vendor/services/VendorService.ts","../../../src/cli/vendor/commands/VendorCommand.ts","../../../src/cli/vendor/index.ts"],"mappings":";;;;;;;;;;;;;;;cAQa,aAAA,EAAa,QAAA,CAAA,IAAA,CAAA,QAAA,CAAA,SAAA,UAAA,OAAA;;AAA1B;;;;6BA2BE,QAAA,CAAA,OAAA;;;;;;;EA3BwB;;;;;;;;;;KAgCd,aAAA,GAAgB,MAAA,QAAc,aAAA,CAAc,MAAA;;;;;;UCjCvC,iBAAA;EACf,IAAA;EACA,MAAA;EACA,MAAA;EACA,QAAA;EACA,KAAA;AAAA;;;;UAMe,gBAAA;EACf,MAAA;EACA,MAAA;EACA,OAAA,GAAU,gBAAA;AAAA;;;;UAMK,iBAAA;EACf,IAAA;EACA,MAAA;EACA,MAAA;EACA,QAAA;AAAA;;;;UAMe,iBAAA;EACf,IAAA;EACA,KAAA;EACA,QAAA;EACA,OAAA;AAAA;ADDF;;;AAAA,UCOiB,gBAAA;EACf,QAAA,EAAU,iBAAA;EACV,YAAA;AAAA;;;;cAMW,aAAA;EAAA,mBACQ,GAAA,EADK,gBAAA,CACF,MAAA;EAAA,mBACH,KAAA,EAAK,aAAA;EAAA,mBACL,EAAA,EAAE,kBAAA;;;;;;;;;EAUf,IAAA,CAAK,OAAA,EAAS,iBAAA,GAAoB,OAAA,CAAQ,gBAAA;EAlDjC;;;;;;EAsGT,IAAA,CAAK,OAAA,EAAS,iBAAA,GAAoB,OAAA,CAAQ,gBAAA;EAnGtC;;;EAAA,UAmHM,aAAA,CACd,IAAA,UACA,MAAA,UACA,QAAA,aACC,OAAA,CAAQ,gBAAA;EAjHqB;;;EAAA,UA4KhB,kBAAA,CAAmB,MAAA,WAAiB,OAAA;EA1KpD;;;EAAA,UAgNgB,WAAA,CAAY,MAAA,UAAgB,MAAA,WAAiB,OAAA;EA9MrD;AAMV;;EANU,mBAqOW,YAAA;EA/Na;;;EAAA,UAyOtB,SAAA,CAAU,QAAA;EArOpB;;;EAAA,UAyPgB,eAAA,CACd,QAAA,UACA,SAAA,WACC,OAAA;IAAU,KAAA;IAAiB,QAAA;IAAoB,OAAA;EAAA;AAAA;;;cCrRvC,aAAA;EAAA,mBACQ,GAAA,EADK,gBAAA,CACF,MAAA;EAAA,mBACH,OAAA,EAAO,QAAA;;;;;qBACP,aAAA,EAAa,aAAA;EAAA,mBACb,KAAA,EAAK,oBAAA;EAAA,mBACL,EAAA,EAAE,mBAAA;;;;YAKX,cAAA,CAAA;;;;;qBAiBS,SAAA,WAAS,OAAA;8BAtBP,QAAA,CAAA,QAAA;EAAA;EAAA,mBA+BF,IAAA,oBAAI,gBAAA,UAAA,OAAA;8BATK,QAAA,CAAA,QAAA;EAAA,IASL,QAAA,CAAA,OAAA;qBAmFJ,IAAA,EAAI,iBAAA,CAAA,gBAAA,CAAA,QAAA,CAAA,OAAA,CAnFA,QAAA,CAmFA,WAAA,GAAA,QAAA,CAAA,OAAA,EAAA,QAAA,CAAA,OAAA,CAAA,QAAA,CAAA,WAAA;EAAA,SA4DP,MAAA,EAAM,iBAAA,CAAA,gBAAA,CAAA,QAAA,CAAA,OAAA,CA5DC,QAAA,CA4DD,WAAA,GAAA,QAAA,CAAA,OAAA,EAAA,QAAA,CAAA,OAAA,CAAA,QAAA,CAAA,WAAA;AAAA;;;;YC1LZ,eAAA;IACR,MAAA,GAAS,aAAA;EAAA;AAAA;;;;AHFb;;;;;;;;;;;;;;;;;;;;;;cGiCa,qBAAA,EAAqB,QAAA,CAAA,OAAA,CAIhC,QAAA,CAJgC,MAAA"}
@@ -1,4 +1,5 @@
1
1
  import { $atom, $inject, $module, $state, AlephaError, t } from "alepha";
2
+ import { cliConfigPlugins } from "alepha/cli/config";
2
3
  import { PackageManagerUtils } from "alepha/cli";
3
4
  import { $command } from "alepha/command";
4
5
  import { $logger, ConsoleColorProvider } from "alepha/logger";
@@ -362,10 +363,10 @@ var VendorCommand = class {
362
363
  * Configuration in `alepha.config.ts`:
363
364
  *
364
365
  * ```typescript
365
- * import { AlephaCliVendor } from "alepha/cli/vendor";
366
+ * import { AlephaCliVendorPlugin } from "alepha/cli/vendor";
366
367
  *
367
368
  * export default defineConfig({
368
- * services: [AlephaCliVendor],
369
+ * services: [AlephaCliVendorPlugin],
369
370
  * vendor: {
370
371
  * branch: "main",
371
372
  * packages: ["alepha", "@alepha/bucket-s3"],
@@ -378,6 +379,9 @@ const AlephaCliVendorPlugin = $module({
378
379
  atoms: [vendorOptions],
379
380
  services: [VendorCommand, VendorService]
380
381
  });
382
+ cliConfigPlugins.push((config, alepha) => {
383
+ if (config.vendor) alepha.set(vendorOptions, config.vendor);
384
+ });
381
385
  //#endregion
382
386
  export { AlephaCliVendorPlugin, VendorCommand, VendorService, vendorOptions };
383
387
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/cli/vendor/atoms/vendorOptions.ts","../../../src/cli/vendor/services/VendorService.ts","../../../src/cli/vendor/commands/VendorCommand.ts","../../../src/cli/vendor/index.ts"],"sourcesContent":["import { $atom, type Static, t } from \"alepha\";\n\n/**\n * Vendor configuration atom.\n *\n * Filled from the `vendor` section of `alepha.config.ts`.\n * Read by `VendorCommand` to resolve remote, branch, and packages.\n */\nexport const vendorOptions = $atom({\n name: \"alepha.cli.vendor.options\",\n description: \"Vendor synchronization configuration\",\n schema: t.optional(\n t.object({\n /**\n * Git remote URL.\n *\n * @default \"git@github.com:feunard/alepha.git\"\n */\n remote: t.optional(t.text()),\n\n /**\n * Branch to sync from.\n *\n * @default \"main\"\n */\n branch: t.optional(t.text()),\n\n /**\n * Package directory names under `packages/` to sync.\n *\n * @example [\"alepha\", \"@alepha/bucket-s3\"]\n */\n packages: t.array(t.text()),\n }),\n ),\n});\n\n/**\n * Type for vendor options.\n */\nexport type VendorOptions = Static<typeof vendorOptions.schema>;\n","import { $inject } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider, ShellProvider } from \"alepha/system\";\n\n/**\n * Options for syncing vendored packages from a remote repository.\n */\nexport interface VendorSyncOptions {\n root: string;\n remote: string;\n branch: string;\n packages: string[];\n force?: boolean;\n}\n\n/**\n * Result of a vendor sync operation.\n */\nexport interface VendorSyncResult {\n synced: string[];\n errors: string[];\n aborted?: VendorDiffResult;\n}\n\n/**\n * Options for diffing vendored packages against a remote repository.\n */\nexport interface VendorDiffOptions {\n root: string;\n remote: string;\n branch: string;\n packages: string[];\n}\n\n/**\n * Diff result for a single vendored package.\n */\nexport interface VendorPackageDiff {\n name: string;\n added: string[];\n modified: string[];\n removed: string[];\n}\n\n/**\n * Result of a vendor diff operation.\n */\nexport interface VendorDiffResult {\n packages: VendorPackageDiff[];\n totalChanges: number;\n}\n\n/**\n * Handles syncing and diffing vendored packages from a remote git repository.\n */\nexport class VendorService {\n protected readonly log = $logger();\n protected readonly shell = $inject(ShellProvider);\n protected readonly fs = $inject(FileSystemProvider);\n\n /**\n * Sync vendored packages from a remote repository.\n *\n * Shallow-clones the remote once, then:\n * - Without `force`: diffs first. If local modifications exist, aborts\n * and returns the diff result without touching local files.\n * - With `force` (or no changes): removes local copies and replaces them.\n */\n async sync(options: VendorSyncOptions): Promise<VendorSyncResult> {\n const synced: string[] = [];\n const errors: string[] = [];\n let tmpDir: string | undefined;\n\n try {\n tmpDir = await this.cloneRemote(options.remote, options.branch);\n\n if (!options.force) {\n const diffResult = await this.diffFromClone(\n options.root,\n tmpDir,\n options.packages,\n );\n if (diffResult.totalChanges > 0) {\n return { synced: [], errors: [], aborted: diffResult };\n }\n }\n\n for (const pkg of options.packages) {\n const remotePkgDir = this.fs.join(tmpDir, \"packages\", pkg);\n const localPkgDir = this.fs.join(options.root, \"packages\", pkg);\n\n const remoteExists = await this.fs.exists(remotePkgDir);\n if (!remoteExists) {\n errors.push(`Package \"${pkg}\" not found in remote`);\n continue;\n }\n\n this.log.debug(`Syncing package: ${pkg}`);\n\n await this.fs.rm(localPkgDir, { recursive: true, force: true });\n await this.fs.cp(remotePkgDir, localPkgDir, { recursive: true });\n await this.removeIgnoredFiles(localPkgDir);\n\n synced.push(pkg);\n }\n } finally {\n if (tmpDir) {\n await this.fs.rm(tmpDir, { recursive: true, force: true });\n }\n }\n\n return { synced, errors };\n }\n\n /**\n * Diff vendored packages against a remote repository.\n *\n * Shallow-clones the remote, then for each package: recursively compares\n * files to identify added, modified, and removed files.\n */\n async diff(options: VendorDiffOptions): Promise<VendorDiffResult> {\n let tmpDir: string | undefined;\n\n try {\n tmpDir = await this.cloneRemote(options.remote, options.branch);\n return await this.diffFromClone(options.root, tmpDir, options.packages);\n } finally {\n if (tmpDir) {\n await this.fs.rm(tmpDir, { recursive: true, force: true });\n }\n }\n }\n\n /**\n * Diff local packages against an already-cloned remote.\n */\n protected async diffFromClone(\n root: string,\n tmpDir: string,\n packages: string[],\n ): Promise<VendorDiffResult> {\n const results: VendorPackageDiff[] = [];\n let totalChanges = 0;\n\n for (const pkg of packages) {\n const remotePkgDir = this.fs.join(tmpDir, \"packages\", pkg);\n const localPkgDir = this.fs.join(root, \"packages\", pkg);\n\n const remoteExists = await this.fs.exists(remotePkgDir);\n const localExists = await this.fs.exists(localPkgDir);\n\n if (!remoteExists && !localExists) {\n results.push({ name: pkg, added: [], modified: [], removed: [] });\n continue;\n }\n\n if (!remoteExists) {\n const localFiles = await this.fs.ls(localPkgDir, { recursive: true });\n results.push({\n name: pkg,\n added: [],\n modified: [],\n removed: localFiles,\n });\n totalChanges += localFiles.length;\n continue;\n }\n\n if (!localExists) {\n const remoteFiles = await this.fs.ls(remotePkgDir, { recursive: true });\n results.push({\n name: pkg,\n added: remoteFiles,\n modified: [],\n removed: [],\n });\n totalChanges += remoteFiles.length;\n continue;\n }\n\n const result = await this.diffDirectories(localPkgDir, remotePkgDir);\n const pkgChanges =\n result.added.length + result.modified.length + result.removed.length;\n totalChanges += pkgChanges;\n\n results.push({\n name: pkg,\n added: result.added,\n modified: result.modified,\n removed: result.removed,\n });\n }\n\n return { packages: results, totalChanges };\n }\n\n /**\n * Remove test files and ignored directories from a synced package.\n */\n protected async removeIgnoredFiles(pkgDir: string): Promise<void> {\n const allFiles = await this.fs.ls(pkgDir, { recursive: true });\n\n // Remove ignored files\n for (const file of allFiles) {\n if (\n file.endsWith(\".spec.ts\") ||\n file.endsWith(\".spec.tsx\") ||\n file === \"LICENSE\"\n ) {\n await this.fs.rm(this.fs.join(pkgDir, file), { force: true });\n }\n }\n\n // Remove ignored directories (find all occurrences at any depth)\n for (const file of allFiles) {\n for (const ignored of this.ignoredPaths) {\n if (\n file === ignored ||\n file.startsWith(`${ignored}/`) ||\n file.includes(`/${ignored}/`) ||\n file.endsWith(`/${ignored}`)\n ) {\n // Extract the path to the ignored directory itself\n const idx = file.indexOf(ignored);\n const dirPath = this.fs.join(\n pkgDir,\n file.substring(0, idx + ignored.length),\n );\n await this.fs.rm(dirPath, { recursive: true, force: true });\n }\n }\n }\n }\n\n /**\n * Clone a remote repository into a temporary directory.\n */\n protected async cloneRemote(remote: string, branch: string): Promise<string> {\n const tmpDir = this.fs.join(\n process.env.TMPDIR || \"/tmp\",\n `.alepha-vendor-${Date.now()}`,\n );\n\n this.log.debug(`Cloning ${remote}#${branch} into ${tmpDir}`);\n\n const output = await this.shell.run(\n `git clone --depth 1 --branch ${branch} --filter=blob:none ${remote} ${tmpDir}`,\n { capture: true },\n );\n\n if (output) {\n this.log.debug(output);\n }\n\n return tmpDir;\n }\n\n /**\n * Directories to ignore during diff comparisons.\n */\n protected readonly ignoredPaths = [\n \"__tests__\",\n \"assets/swagger-ui\",\n \"node_modules\",\n \"dist\",\n ];\n\n /**\n * Check if a file path should be ignored during diff.\n */\n protected isIgnored(filePath: string): boolean {\n if (\n filePath.endsWith(\".spec.ts\") ||\n filePath.endsWith(\".spec.tsx\") ||\n filePath === \"LICENSE\"\n ) {\n return true;\n }\n return this.ignoredPaths.some(\n (p) =>\n filePath === p ||\n filePath.startsWith(`${p}/`) ||\n filePath.includes(`/${p}/`) ||\n filePath.endsWith(`/${p}`),\n );\n }\n\n /**\n * Recursively compare two directories and return the differences.\n */\n protected async diffDirectories(\n localDir: string,\n remoteDir: string,\n ): Promise<{ added: string[]; modified: string[]; removed: string[] }> {\n const added: string[] = [];\n const modified: string[] = [];\n const removed: string[] = [];\n\n const [localFiles, remoteFiles] = await Promise.all([\n this.fs.ls(localDir, { recursive: true }),\n this.fs.ls(remoteDir, { recursive: true }),\n ]);\n\n const filteredLocal = localFiles.filter((f) => !this.isIgnored(f));\n const filteredRemote = remoteFiles.filter((f) => !this.isIgnored(f));\n\n const localSet = new Set(filteredLocal);\n const remoteSet = new Set(filteredRemote);\n\n for (const file of filteredRemote) {\n if (!localSet.has(file)) {\n added.push(file);\n continue;\n }\n\n try {\n const [localContent, remoteContent] = await Promise.all([\n this.fs.readFile(this.fs.join(localDir, file)),\n this.fs.readFile(this.fs.join(remoteDir, file)),\n ]);\n\n if (!localContent.equals(remoteContent)) {\n modified.push(file);\n }\n } catch {\n // Skip directories and unreadable entries\n }\n }\n\n for (const file of filteredLocal) {\n if (!remoteSet.has(file)) {\n removed.push(file);\n }\n }\n\n return { added, modified, removed };\n }\n}\n","import { $inject, $state, AlephaError, t } from \"alepha\";\nimport { PackageManagerUtils } from \"alepha/cli\";\nimport { $command } from \"alepha/command\";\nimport { $logger, ConsoleColorProvider } from \"alepha/logger\";\nimport { vendorOptions } from \"../atoms/vendorOptions.ts\";\nimport type {\n VendorDiffResult,\n VendorSyncResult,\n} from \"../services/VendorService.ts\";\nimport { VendorService } from \"../services/VendorService.ts\";\n\n/**\n * Default remote when none is configured.\n */\nconst DEFAULT_REMOTE = \"git@github.com:feunard/alepha.git\";\n\nexport class VendorCommand {\n protected readonly log = $logger();\n protected readonly options = $state(vendorOptions);\n protected readonly vendorService = $inject(VendorService);\n protected readonly color = $inject(ConsoleColorProvider);\n protected readonly pm = $inject(PackageManagerUtils);\n\n /**\n * Ensure vendor config is present and return resolved options.\n */\n protected resolveOptions() {\n if (!this.options) {\n throw new AlephaError(\n 'Missing vendor configuration. Add a \"vendor\" section to alepha.config.ts.',\n );\n }\n return {\n remote: this.options.remote ?? DEFAULT_REMOTE,\n branch: this.options.branch ?? \"main\",\n packages: this.options.packages,\n };\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // alepha vendor sync\n // ─────────────────────────────────────────────────────────────────────────\n\n protected readonly syncFlags = t.object({\n force: t.optional(\n t.boolean({\n aliases: [\"f\"],\n description: \"Skip local modification check\",\n }),\n ),\n });\n\n protected readonly sync = $command({\n name: \"sync\",\n description: \"Replace local packages with remote source\",\n flags: this.syncFlags,\n handler: async ({ flags, root, run }) => {\n const opts = this.resolveOptions();\n const c = this.color;\n\n let result: VendorSyncResult = { synced: [], errors: [] };\n\n await run({\n name: `Syncing from ${opts.branch}`,\n handler: async () => {\n result = await this.vendorService.sync({\n root,\n remote: opts.remote,\n branch: opts.branch,\n packages: opts.packages,\n force: flags.force,\n });\n },\n });\n\n if (result.aborted) {\n run.end();\n\n process.stdout.write(\n `\\nLocal modifications detected. Use ${c.set(\"CYAN\", \"--force\")} to overwrite.\\n`,\n );\n\n for (const pkg of result.aborted.packages) {\n const count =\n pkg.added.length + pkg.modified.length + pkg.removed.length;\n if (count === 0) continue;\n\n process.stdout.write(\n `\\n${c.set(\"CYAN\", pkg.name)}: ${count} ${count === 1 ? \"file differs\" : \"files differ\"}\\n`,\n );\n for (const file of pkg.added) {\n process.stdout.write(` ${c.set(\"GREEN\", \"A\")} ${file}\\n`);\n }\n for (const file of pkg.modified) {\n process.stdout.write(` ${c.set(\"ORANGE\", \"M\")} ${file}\\n`);\n }\n for (const file of pkg.removed) {\n process.stdout.write(` ${c.set(\"RED\", \"D\")} ${file}\\n`);\n }\n }\n\n process.stdout.write(\"\\n\");\n return;\n }\n\n if (result.synced.length > 0) {\n const pmName = await this.pm.getPackageManager(root);\n await run(`${pmName} install`, { root });\n }\n\n run.end();\n\n if (result.errors.length > 0) {\n for (const error of result.errors) {\n process.stdout.write(`${c.set(\"RED\", \" error\")} ${error}\\n`);\n }\n }\n\n if (result.synced.length > 0) {\n process.stdout.write(\n `\\nSynced ${c.set(\"CYAN\", String(result.synced.length))} ${result.synced.length === 1 ? \"package\" : \"packages\"} from ${c.set(\"CYAN\", opts.branch)}\\n`,\n );\n for (const pkg of result.synced) {\n process.stdout.write(` ${c.set(\"GREEN\", \"\\u2713\")} ${pkg}\\n`);\n }\n }\n\n process.stdout.write(\"\\n\");\n },\n });\n\n // ─────────────────────────────────────────────────────────────────────────\n // alepha vendor diff\n // ─────────────────────────────────────────────────────────────────────────\n\n protected readonly diff = $command({\n name: \"diff\",\n description: \"Compare local packages against remote\",\n handler: async ({ root, run }) => {\n const opts = this.resolveOptions();\n\n let result: VendorDiffResult = { packages: [], totalChanges: 0 };\n\n await run({\n name: `Cloning ${opts.remote} at ${opts.branch}`,\n handler: async () => {\n result = await this.vendorService.diff({\n root,\n remote: opts.remote,\n branch: opts.branch,\n packages: opts.packages,\n });\n },\n });\n\n run.end();\n\n if (result.totalChanges === 0) {\n process.stdout.write(\"\\nNo changes\\n\\n\");\n return;\n }\n\n const c = this.color;\n\n for (const pkg of result.packages) {\n const count =\n pkg.added.length + pkg.modified.length + pkg.removed.length;\n if (count === 0) {\n process.stdout.write(`\\n${c.set(\"CYAN\", pkg.name)}: no changes\\n`);\n continue;\n }\n\n process.stdout.write(\n `\\n${c.set(\"CYAN\", pkg.name)}: ${count} ${count === 1 ? \"file differs\" : \"files differ\"}\\n`,\n );\n\n for (const file of pkg.added) {\n process.stdout.write(` ${c.set(\"GREEN\", \"A\")} ${file}\\n`);\n }\n for (const file of pkg.modified) {\n process.stdout.write(` ${c.set(\"ORANGE\", \"M\")} ${file}\\n`);\n }\n for (const file of pkg.removed) {\n process.stdout.write(` ${c.set(\"RED\", \"D\")} ${file}\\n`);\n }\n }\n\n process.stdout.write(\"\\n\");\n },\n });\n\n // ─────────────────────────────────────────────────────────────────────────\n // Parent command\n // ─────────────────────────────────────────────────────────────────────────\n\n public readonly vendor = $command({\n name: \"vendor\",\n description: \"Vendor Alepha packages into the project\",\n children: [this.sync, this.diff],\n handler: async ({ help }) => {\n help();\n },\n });\n}\n","import { $module } from \"alepha\";\nimport { vendorOptions } from \"./atoms/vendorOptions.ts\";\nimport { VendorCommand } from \"./commands/VendorCommand.ts\";\nimport { VendorService } from \"./services/VendorService.ts\";\n\n// ---------------------------------------------------------------------------\n\n/**\n * CLI plugin for vendoring Alepha packages into external projects.\n *\n * Copies package source code from a git remote into the current project's\n * `packages/` directory. Useful for corporate projects that need a local\n * copy of Alepha for AI tooling, audits, documentation, or quick fixes.\n *\n * Commands:\n * - `alepha vendor sync` — replace local packages with remote source\n * - `alepha vendor diff` — compare local packages against remote HEAD\n *\n * Configuration in `alepha.config.ts`:\n *\n * ```typescript\n * import { AlephaCliVendor } from \"alepha/cli/vendor\";\n *\n * export default defineConfig({\n * services: [AlephaCliVendor],\n * vendor: {\n * branch: \"main\",\n * packages: [\"alepha\", \"@alepha/bucket-s3\"],\n * },\n * });\n * ```\n */\nexport const AlephaCliVendorPlugin = $module({\n name: \"alepha.cli.plugins.vendor\",\n atoms: [vendorOptions],\n services: [VendorCommand, VendorService],\n});\n\n// ---------------------------------------------------------------------------\n\nexport * from \"./atoms/vendorOptions.ts\";\nexport * from \"./commands/VendorCommand.ts\";\nexport * from \"./services/VendorService.ts\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/cli/vendor/atoms/vendorOptions.ts","../../../src/cli/vendor/services/VendorService.ts","../../../src/cli/vendor/commands/VendorCommand.ts","../../../src/cli/vendor/index.ts"],"sourcesContent":["import { $atom, type Static, t } from \"alepha\";\n\n/**\n * Vendor configuration atom.\n *\n * Filled from the `vendor` section of `alepha.config.ts`.\n * Read by `VendorCommand` to resolve remote, branch, and packages.\n */\nexport const vendorOptions = $atom({\n name: \"alepha.cli.vendor.options\",\n description: \"Vendor synchronization configuration\",\n schema: t.optional(\n t.object({\n /**\n * Git remote URL.\n *\n * @default \"git@github.com:feunard/alepha.git\"\n */\n remote: t.optional(t.text()),\n\n /**\n * Branch to sync from.\n *\n * @default \"main\"\n */\n branch: t.optional(t.text()),\n\n /**\n * Package directory names under `packages/` to sync.\n *\n * @example [\"alepha\", \"@alepha/bucket-s3\"]\n */\n packages: t.array(t.text()),\n }),\n ),\n});\n\n/**\n * Type for vendor options.\n */\nexport type VendorOptions = Static<typeof vendorOptions.schema>;\n","import { $inject } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider, ShellProvider } from \"alepha/system\";\n\n/**\n * Options for syncing vendored packages from a remote repository.\n */\nexport interface VendorSyncOptions {\n root: string;\n remote: string;\n branch: string;\n packages: string[];\n force?: boolean;\n}\n\n/**\n * Result of a vendor sync operation.\n */\nexport interface VendorSyncResult {\n synced: string[];\n errors: string[];\n aborted?: VendorDiffResult;\n}\n\n/**\n * Options for diffing vendored packages against a remote repository.\n */\nexport interface VendorDiffOptions {\n root: string;\n remote: string;\n branch: string;\n packages: string[];\n}\n\n/**\n * Diff result for a single vendored package.\n */\nexport interface VendorPackageDiff {\n name: string;\n added: string[];\n modified: string[];\n removed: string[];\n}\n\n/**\n * Result of a vendor diff operation.\n */\nexport interface VendorDiffResult {\n packages: VendorPackageDiff[];\n totalChanges: number;\n}\n\n/**\n * Handles syncing and diffing vendored packages from a remote git repository.\n */\nexport class VendorService {\n protected readonly log = $logger();\n protected readonly shell = $inject(ShellProvider);\n protected readonly fs = $inject(FileSystemProvider);\n\n /**\n * Sync vendored packages from a remote repository.\n *\n * Shallow-clones the remote once, then:\n * - Without `force`: diffs first. If local modifications exist, aborts\n * and returns the diff result without touching local files.\n * - With `force` (or no changes): removes local copies and replaces them.\n */\n async sync(options: VendorSyncOptions): Promise<VendorSyncResult> {\n const synced: string[] = [];\n const errors: string[] = [];\n let tmpDir: string | undefined;\n\n try {\n tmpDir = await this.cloneRemote(options.remote, options.branch);\n\n if (!options.force) {\n const diffResult = await this.diffFromClone(\n options.root,\n tmpDir,\n options.packages,\n );\n if (diffResult.totalChanges > 0) {\n return { synced: [], errors: [], aborted: diffResult };\n }\n }\n\n for (const pkg of options.packages) {\n const remotePkgDir = this.fs.join(tmpDir, \"packages\", pkg);\n const localPkgDir = this.fs.join(options.root, \"packages\", pkg);\n\n const remoteExists = await this.fs.exists(remotePkgDir);\n if (!remoteExists) {\n errors.push(`Package \"${pkg}\" not found in remote`);\n continue;\n }\n\n this.log.debug(`Syncing package: ${pkg}`);\n\n await this.fs.rm(localPkgDir, { recursive: true, force: true });\n await this.fs.cp(remotePkgDir, localPkgDir, { recursive: true });\n await this.removeIgnoredFiles(localPkgDir);\n\n synced.push(pkg);\n }\n } finally {\n if (tmpDir) {\n await this.fs.rm(tmpDir, { recursive: true, force: true });\n }\n }\n\n return { synced, errors };\n }\n\n /**\n * Diff vendored packages against a remote repository.\n *\n * Shallow-clones the remote, then for each package: recursively compares\n * files to identify added, modified, and removed files.\n */\n async diff(options: VendorDiffOptions): Promise<VendorDiffResult> {\n let tmpDir: string | undefined;\n\n try {\n tmpDir = await this.cloneRemote(options.remote, options.branch);\n return await this.diffFromClone(options.root, tmpDir, options.packages);\n } finally {\n if (tmpDir) {\n await this.fs.rm(tmpDir, { recursive: true, force: true });\n }\n }\n }\n\n /**\n * Diff local packages against an already-cloned remote.\n */\n protected async diffFromClone(\n root: string,\n tmpDir: string,\n packages: string[],\n ): Promise<VendorDiffResult> {\n const results: VendorPackageDiff[] = [];\n let totalChanges = 0;\n\n for (const pkg of packages) {\n const remotePkgDir = this.fs.join(tmpDir, \"packages\", pkg);\n const localPkgDir = this.fs.join(root, \"packages\", pkg);\n\n const remoteExists = await this.fs.exists(remotePkgDir);\n const localExists = await this.fs.exists(localPkgDir);\n\n if (!remoteExists && !localExists) {\n results.push({ name: pkg, added: [], modified: [], removed: [] });\n continue;\n }\n\n if (!remoteExists) {\n const localFiles = await this.fs.ls(localPkgDir, { recursive: true });\n results.push({\n name: pkg,\n added: [],\n modified: [],\n removed: localFiles,\n });\n totalChanges += localFiles.length;\n continue;\n }\n\n if (!localExists) {\n const remoteFiles = await this.fs.ls(remotePkgDir, { recursive: true });\n results.push({\n name: pkg,\n added: remoteFiles,\n modified: [],\n removed: [],\n });\n totalChanges += remoteFiles.length;\n continue;\n }\n\n const result = await this.diffDirectories(localPkgDir, remotePkgDir);\n const pkgChanges =\n result.added.length + result.modified.length + result.removed.length;\n totalChanges += pkgChanges;\n\n results.push({\n name: pkg,\n added: result.added,\n modified: result.modified,\n removed: result.removed,\n });\n }\n\n return { packages: results, totalChanges };\n }\n\n /**\n * Remove test files and ignored directories from a synced package.\n */\n protected async removeIgnoredFiles(pkgDir: string): Promise<void> {\n const allFiles = await this.fs.ls(pkgDir, { recursive: true });\n\n // Remove ignored files\n for (const file of allFiles) {\n if (\n file.endsWith(\".spec.ts\") ||\n file.endsWith(\".spec.tsx\") ||\n file === \"LICENSE\"\n ) {\n await this.fs.rm(this.fs.join(pkgDir, file), { force: true });\n }\n }\n\n // Remove ignored directories (find all occurrences at any depth)\n for (const file of allFiles) {\n for (const ignored of this.ignoredPaths) {\n if (\n file === ignored ||\n file.startsWith(`${ignored}/`) ||\n file.includes(`/${ignored}/`) ||\n file.endsWith(`/${ignored}`)\n ) {\n // Extract the path to the ignored directory itself\n const idx = file.indexOf(ignored);\n const dirPath = this.fs.join(\n pkgDir,\n file.substring(0, idx + ignored.length),\n );\n await this.fs.rm(dirPath, { recursive: true, force: true });\n }\n }\n }\n }\n\n /**\n * Clone a remote repository into a temporary directory.\n */\n protected async cloneRemote(remote: string, branch: string): Promise<string> {\n const tmpDir = this.fs.join(\n process.env.TMPDIR || \"/tmp\",\n `.alepha-vendor-${Date.now()}`,\n );\n\n this.log.debug(`Cloning ${remote}#${branch} into ${tmpDir}`);\n\n const output = await this.shell.run(\n `git clone --depth 1 --branch ${branch} --filter=blob:none ${remote} ${tmpDir}`,\n { capture: true },\n );\n\n if (output) {\n this.log.debug(output);\n }\n\n return tmpDir;\n }\n\n /**\n * Directories to ignore during diff comparisons.\n */\n protected readonly ignoredPaths = [\n \"__tests__\",\n \"assets/swagger-ui\",\n \"node_modules\",\n \"dist\",\n ];\n\n /**\n * Check if a file path should be ignored during diff.\n */\n protected isIgnored(filePath: string): boolean {\n if (\n filePath.endsWith(\".spec.ts\") ||\n filePath.endsWith(\".spec.tsx\") ||\n filePath === \"LICENSE\"\n ) {\n return true;\n }\n return this.ignoredPaths.some(\n (p) =>\n filePath === p ||\n filePath.startsWith(`${p}/`) ||\n filePath.includes(`/${p}/`) ||\n filePath.endsWith(`/${p}`),\n );\n }\n\n /**\n * Recursively compare two directories and return the differences.\n */\n protected async diffDirectories(\n localDir: string,\n remoteDir: string,\n ): Promise<{ added: string[]; modified: string[]; removed: string[] }> {\n const added: string[] = [];\n const modified: string[] = [];\n const removed: string[] = [];\n\n const [localFiles, remoteFiles] = await Promise.all([\n this.fs.ls(localDir, { recursive: true }),\n this.fs.ls(remoteDir, { recursive: true }),\n ]);\n\n const filteredLocal = localFiles.filter((f) => !this.isIgnored(f));\n const filteredRemote = remoteFiles.filter((f) => !this.isIgnored(f));\n\n const localSet = new Set(filteredLocal);\n const remoteSet = new Set(filteredRemote);\n\n for (const file of filteredRemote) {\n if (!localSet.has(file)) {\n added.push(file);\n continue;\n }\n\n try {\n const [localContent, remoteContent] = await Promise.all([\n this.fs.readFile(this.fs.join(localDir, file)),\n this.fs.readFile(this.fs.join(remoteDir, file)),\n ]);\n\n if (!localContent.equals(remoteContent)) {\n modified.push(file);\n }\n } catch {\n // Skip directories and unreadable entries\n }\n }\n\n for (const file of filteredLocal) {\n if (!remoteSet.has(file)) {\n removed.push(file);\n }\n }\n\n return { added, modified, removed };\n }\n}\n","import { $inject, $state, AlephaError, t } from \"alepha\";\nimport { PackageManagerUtils } from \"alepha/cli\";\nimport { $command } from \"alepha/command\";\nimport { $logger, ConsoleColorProvider } from \"alepha/logger\";\nimport { vendorOptions } from \"../atoms/vendorOptions.ts\";\nimport type {\n VendorDiffResult,\n VendorSyncResult,\n} from \"../services/VendorService.ts\";\nimport { VendorService } from \"../services/VendorService.ts\";\n\n/**\n * Default remote when none is configured.\n */\nconst DEFAULT_REMOTE = \"git@github.com:feunard/alepha.git\";\n\nexport class VendorCommand {\n protected readonly log = $logger();\n protected readonly options = $state(vendorOptions);\n protected readonly vendorService = $inject(VendorService);\n protected readonly color = $inject(ConsoleColorProvider);\n protected readonly pm = $inject(PackageManagerUtils);\n\n /**\n * Ensure vendor config is present and return resolved options.\n */\n protected resolveOptions() {\n if (!this.options) {\n throw new AlephaError(\n 'Missing vendor configuration. Add a \"vendor\" section to alepha.config.ts.',\n );\n }\n return {\n remote: this.options.remote ?? DEFAULT_REMOTE,\n branch: this.options.branch ?? \"main\",\n packages: this.options.packages,\n };\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // alepha vendor sync\n // ─────────────────────────────────────────────────────────────────────────\n\n protected readonly syncFlags = t.object({\n force: t.optional(\n t.boolean({\n aliases: [\"f\"],\n description: \"Skip local modification check\",\n }),\n ),\n });\n\n protected readonly sync = $command({\n name: \"sync\",\n description: \"Replace local packages with remote source\",\n flags: this.syncFlags,\n handler: async ({ flags, root, run }) => {\n const opts = this.resolveOptions();\n const c = this.color;\n\n let result: VendorSyncResult = { synced: [], errors: [] };\n\n await run({\n name: `Syncing from ${opts.branch}`,\n handler: async () => {\n result = await this.vendorService.sync({\n root,\n remote: opts.remote,\n branch: opts.branch,\n packages: opts.packages,\n force: flags.force,\n });\n },\n });\n\n if (result.aborted) {\n run.end();\n\n process.stdout.write(\n `\\nLocal modifications detected. Use ${c.set(\"CYAN\", \"--force\")} to overwrite.\\n`,\n );\n\n for (const pkg of result.aborted.packages) {\n const count =\n pkg.added.length + pkg.modified.length + pkg.removed.length;\n if (count === 0) continue;\n\n process.stdout.write(\n `\\n${c.set(\"CYAN\", pkg.name)}: ${count} ${count === 1 ? \"file differs\" : \"files differ\"}\\n`,\n );\n for (const file of pkg.added) {\n process.stdout.write(` ${c.set(\"GREEN\", \"A\")} ${file}\\n`);\n }\n for (const file of pkg.modified) {\n process.stdout.write(` ${c.set(\"ORANGE\", \"M\")} ${file}\\n`);\n }\n for (const file of pkg.removed) {\n process.stdout.write(` ${c.set(\"RED\", \"D\")} ${file}\\n`);\n }\n }\n\n process.stdout.write(\"\\n\");\n return;\n }\n\n if (result.synced.length > 0) {\n const pmName = await this.pm.getPackageManager(root);\n await run(`${pmName} install`, { root });\n }\n\n run.end();\n\n if (result.errors.length > 0) {\n for (const error of result.errors) {\n process.stdout.write(`${c.set(\"RED\", \" error\")} ${error}\\n`);\n }\n }\n\n if (result.synced.length > 0) {\n process.stdout.write(\n `\\nSynced ${c.set(\"CYAN\", String(result.synced.length))} ${result.synced.length === 1 ? \"package\" : \"packages\"} from ${c.set(\"CYAN\", opts.branch)}\\n`,\n );\n for (const pkg of result.synced) {\n process.stdout.write(` ${c.set(\"GREEN\", \"\\u2713\")} ${pkg}\\n`);\n }\n }\n\n process.stdout.write(\"\\n\");\n },\n });\n\n // ─────────────────────────────────────────────────────────────────────────\n // alepha vendor diff\n // ─────────────────────────────────────────────────────────────────────────\n\n protected readonly diff = $command({\n name: \"diff\",\n description: \"Compare local packages against remote\",\n handler: async ({ root, run }) => {\n const opts = this.resolveOptions();\n\n let result: VendorDiffResult = { packages: [], totalChanges: 0 };\n\n await run({\n name: `Cloning ${opts.remote} at ${opts.branch}`,\n handler: async () => {\n result = await this.vendorService.diff({\n root,\n remote: opts.remote,\n branch: opts.branch,\n packages: opts.packages,\n });\n },\n });\n\n run.end();\n\n if (result.totalChanges === 0) {\n process.stdout.write(\"\\nNo changes\\n\\n\");\n return;\n }\n\n const c = this.color;\n\n for (const pkg of result.packages) {\n const count =\n pkg.added.length + pkg.modified.length + pkg.removed.length;\n if (count === 0) {\n process.stdout.write(`\\n${c.set(\"CYAN\", pkg.name)}: no changes\\n`);\n continue;\n }\n\n process.stdout.write(\n `\\n${c.set(\"CYAN\", pkg.name)}: ${count} ${count === 1 ? \"file differs\" : \"files differ\"}\\n`,\n );\n\n for (const file of pkg.added) {\n process.stdout.write(` ${c.set(\"GREEN\", \"A\")} ${file}\\n`);\n }\n for (const file of pkg.modified) {\n process.stdout.write(` ${c.set(\"ORANGE\", \"M\")} ${file}\\n`);\n }\n for (const file of pkg.removed) {\n process.stdout.write(` ${c.set(\"RED\", \"D\")} ${file}\\n`);\n }\n }\n\n process.stdout.write(\"\\n\");\n },\n });\n\n // ─────────────────────────────────────────────────────────────────────────\n // Parent command\n // ─────────────────────────────────────────────────────────────────────────\n\n public readonly vendor = $command({\n name: \"vendor\",\n description: \"Vendor Alepha packages into the project\",\n children: [this.sync, this.diff],\n handler: async ({ help }) => {\n help();\n },\n });\n}\n","import { $module } from \"alepha\";\nimport { cliConfigPlugins } from \"alepha/cli/config\";\nimport { type VendorOptions, vendorOptions } from \"./atoms/vendorOptions.ts\";\nimport { VendorCommand } from \"./commands/VendorCommand.ts\";\nimport { VendorService } from \"./services/VendorService.ts\";\n\n// ---------------------------------------------------------------------------\n\ndeclare module \"alepha/cli/config\" {\n interface AlephaCliConfig {\n vendor?: VendorOptions;\n }\n}\n\n// ---------------------------------------------------------------------------\n\n/**\n * CLI plugin for vendoring Alepha packages into external projects.\n *\n * Copies package source code from a git remote into the current project's\n * `packages/` directory. Useful for corporate projects that need a local\n * copy of Alepha for AI tooling, audits, documentation, or quick fixes.\n *\n * Commands:\n * - `alepha vendor sync` — replace local packages with remote source\n * - `alepha vendor diff` — compare local packages against remote HEAD\n *\n * Configuration in `alepha.config.ts`:\n *\n * ```typescript\n * import { AlephaCliVendorPlugin } from \"alepha/cli/vendor\";\n *\n * export default defineConfig({\n * services: [AlephaCliVendorPlugin],\n * vendor: {\n * branch: \"main\",\n * packages: [\"alepha\", \"@alepha/bucket-s3\"],\n * },\n * });\n * ```\n */\nexport const AlephaCliVendorPlugin = $module({\n name: \"alepha.cli.plugins.vendor\",\n atoms: [vendorOptions],\n services: [VendorCommand, VendorService],\n});\n\n// ---------------------------------------------------------------------------\n\ncliConfigPlugins.push((config, alepha) => {\n if (config.vendor) {\n alepha.set(vendorOptions, config.vendor);\n }\n});\n\n// ---------------------------------------------------------------------------\n\nexport * from \"./atoms/vendorOptions.ts\";\nexport * from \"./commands/VendorCommand.ts\";\nexport * from \"./services/VendorService.ts\";\n"],"mappings":"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"}