@stacksjs/buddy 0.70.257 → 0.70.259

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.d.ts +11 -1
  2. package/dist/cli.js +5 -164
  3. package/dist/commands/about.js +1 -35
  4. package/dist/commands/add.js +1 -25
  5. package/dist/commands/ai-context.js +4 -27
  6. package/dist/commands/auth.js +1 -68
  7. package/dist/commands/build.js +1 -221
  8. package/dist/commands/cd.js +8 -39
  9. package/dist/commands/changelog.js +1 -32
  10. package/dist/commands/clean.js +1 -44
  11. package/dist/commands/cloud.js +2 -519
  12. package/dist/commands/commit.js +1 -16
  13. package/dist/commands/completion.js +6 -42
  14. package/dist/commands/config-migrate.js +6 -94
  15. package/dist/commands/configure.js +2 -45
  16. package/dist/commands/create.js +1 -162
  17. package/dist/commands/deploy.d.ts +10 -4
  18. package/dist/commands/deploy.js +13 -1664
  19. package/dist/commands/desktop-apple.js +12 -399
  20. package/dist/commands/dev.js +6 -1083
  21. package/dist/commands/dns.js +3 -103
  22. package/dist/commands/docs/buddy-commands.js +10 -132
  23. package/dist/commands/docs/buddy-commands.test.js +1 -38
  24. package/dist/commands/docs/framework-repo.js +1 -14
  25. package/dist/commands/docs/framework-repo.test.js +1 -68
  26. package/dist/commands/docs/generated-artifacts.js +3 -70
  27. package/dist/commands/docs/generated-artifacts.test.js +1 -19
  28. package/dist/commands/docs/links.js +2 -85
  29. package/dist/commands/docs/links.test.js +4 -66
  30. package/dist/commands/docs.js +1 -24
  31. package/dist/commands/doctor.js +2 -478
  32. package/dist/commands/domains.js +2 -152
  33. package/dist/commands/email.js +31 -503
  34. package/dist/commands/env.js +1 -312
  35. package/dist/commands/extension.js +1 -239
  36. package/dist/commands/features.js +9 -345
  37. package/dist/commands/fresh.js +1 -46
  38. package/dist/commands/generate.js +2 -152
  39. package/dist/commands/http.js +1 -33
  40. package/dist/commands/index.js +1 -57
  41. package/dist/commands/install.js +1 -22
  42. package/dist/commands/key.js +1 -23
  43. package/dist/commands/link.js +2 -147
  44. package/dist/commands/lint.js +2 -46
  45. package/dist/commands/list.js +1 -140
  46. package/dist/commands/mail.js +15 -1477
  47. package/dist/commands/maintenance.js +1 -141
  48. package/dist/commands/make.js +1 -392
  49. package/dist/commands/migrate-project.js +1 -49
  50. package/dist/commands/migrate.js +27 -625
  51. package/dist/commands/outdated.js +1 -19
  52. package/dist/commands/package.js +1 -17
  53. package/dist/commands/phone.js +17 -181
  54. package/dist/commands/ports.js +2 -118
  55. package/dist/commands/prepublish.js +1 -17
  56. package/dist/commands/projects.js +1 -29
  57. package/dist/commands/protocol/craft-evidence.js +4 -98
  58. package/dist/commands/protocol/craft-evidence.test.js +1 -20
  59. package/dist/commands/protocol/desktop-lifecycle-report.js +3 -57
  60. package/dist/commands/protocol/desktop-lifecycle-report.test.js +1 -32
  61. package/dist/commands/protocol/desktop-support.js +2 -32
  62. package/dist/commands/protocol/desktop-workflow.test.js +3 -35
  63. package/dist/commands/protocol/driver-registry.js +2 -71
  64. package/dist/commands/protocol/pantry-evidence.js +4 -144
  65. package/dist/commands/protocol/pantry-evidence.test.js +1 -29
  66. package/dist/commands/protocol/release-manifest.js +3 -102
  67. package/dist/commands/protocol/release-manifest.test.js +2 -34
  68. package/dist/commands/protocol/run-conformance.js +4 -346
  69. package/dist/commands/protocol/run-conformance.test.js +1 -52
  70. package/dist/commands/protocol/run-driver-contracts.js +4 -83
  71. package/dist/commands/protocol/run-driver-contracts.test.js +1 -18
  72. package/dist/commands/protocol/source-manifest.js +3 -113
  73. package/dist/commands/protocol/sync-suite.js +3 -136
  74. package/dist/commands/protocol/sync-suite.test.js +1 -44
  75. package/dist/commands/protocol.js +1 -60
  76. package/dist/commands/publish.js +8 -500
  77. package/dist/commands/queue.js +1 -248
  78. package/dist/commands/release.js +1 -42
  79. package/dist/commands/route.js +1 -21
  80. package/dist/commands/run-tool.js +1 -9
  81. package/dist/commands/saas.js +1 -25
  82. package/dist/commands/schedule.js +1 -61
  83. package/dist/commands/search.js +1 -84
  84. package/dist/commands/seed.js +1 -47
  85. package/dist/commands/serve.js +1 -55
  86. package/dist/commands/setup-ai.js +2 -121
  87. package/dist/commands/setup.js +2 -305
  88. package/dist/commands/share.js +1 -214
  89. package/dist/commands/sms.js +32 -319
  90. package/dist/commands/stacks.js +1 -72
  91. package/dist/commands/telemetry.js +1 -74
  92. package/dist/commands/test.js +1 -130
  93. package/dist/commands/tinker.js +1 -37
  94. package/dist/commands/types.js +1 -18
  95. package/dist/commands/upgrade.js +1 -98
  96. package/dist/commands/user.js +3 -84
  97. package/dist/commands/version.js +1 -14
  98. package/dist/config.js +1 -231
  99. package/dist/custom-cli.js +1 -23
  100. package/dist/database-preflight.js +1 -88
  101. package/dist/global-options.js +1 -4
  102. package/dist/index.js +1 -1
  103. package/dist/lazy-commands.js +1 -241
  104. package/dist/migrators/index.js +2 -62
  105. package/dist/migrators/laravel/index.js +1 -148
  106. package/dist/migrators/laravel/migrations.js +4 -231
  107. package/dist/migrators/laravel/models.js +8 -111
  108. package/dist/migrators/rails/index.js +1 -11
  109. package/dist/production-server.js +1 -257
  110. package/dist/project-setup.js +1 -36
  111. package/dist/serve-entry.js +1 -5
  112. package/dist/version-info.js +1 -5
  113. package/package.json +54 -47
package/dist/cli.d.ts CHANGED
@@ -1 +1,11 @@
1
- export {};
1
+ import type { CLI } from '@stacksjs/cli';
2
+ /**
3
+ * Attach aliases to the command a just-loaded file registered.
4
+ *
5
+ * The registry key may carry arguments (`'send-emails <type>'`) while the
6
+ * registered command is named by its first word, so the lookup matches on
7
+ * that. Nothing is thrown when no command matches: a registry entry whose
8
+ * file registers a differently-named command is a mistake worth a log
9
+ * line, not a reason to take the whole CLI down.
10
+ */
11
+ export declare function applyAliases(buddy: CLI, signature: string, aliases: string[]): void;
package/dist/cli.js CHANGED
@@ -1,165 +1,6 @@
1
1
  #!/usr/bin/env bun
2
- import process from "node:process";
3
- import { cli, log } from "@stacksjs/cli";
4
- import { path as p } from "@stacksjs/path";
5
- import { registerGlobalOptions } from "./global-options";
6
- import { shouldSkipAppKeyCheck } from "./project-setup";
7
- try {
8
- const { isSupportedBunVersion, minimumBunVersion } = await import("@stacksjs/utils"), currentBunVersion = typeof Bun < "u" ? Bun.version : process.versions.bun;
9
- if (currentBunVersion && !isSupportedBunVersion(currentBunVersion)) {
10
- console.error(`[buddy] Bun v${minimumBunVersion} or later is required (current: v${currentBunVersion}). Run: bun upgrade`);
11
- process.exit(1);
12
- }
13
- } catch {}
14
- const args = process.argv.slice(2), requestedCommand = args[0] || "help", isHelpFlag = args.includes("--help") || args.includes("-h"), isVersionOnly = ["--version", "-V", "version"].includes(requestedCommand), isHelpMode = requestedCommand === "help" || isHelpFlag && args.length <= 2, skipAppKeyCheck = shouldSkipAppKeyCheck(requestedCommand, { isHelpFlag, isHelpMode }), needsFullSetup = !isVersionOnly;
15
- if (needsFullSetup) {
16
- const reportFatal = (label, error) => {
17
- log.debug(`Buddy ${label}`);
18
- try {
19
- process.stderr.write(`
20
- [buddy] ${label}: ${error?.stack ?? String(error)}
21
- `);
22
- } catch {}
23
- log.error(error);
24
- return process.exit(1);
25
- };
26
- process.on("uncaughtException", (error) => reportFatal("uncaughtException", error));
27
- process.on("unhandledRejection", (error) => reportFatal("unhandledRejection", error));
28
- }
29
- async function main() {
30
- const buddy = cli("buddy");
31
- registerGlobalOptions(buddy, {
32
- version: requestedCommand !== "upgrade" && requestedCommand !== "update"
33
- });
34
- const configPath = "./buddy.config.js";
35
- try {
36
- await Bun.file(configPath).text();
37
- const { applyBuddyConfig } = await import("./config.js");
38
- await applyBuddyConfig(buddy);
39
- } catch {}
40
- if (needsFullSetup) {
41
- p.ensureRuntimeDirectories();
42
- const { loadCommands, getCommandsToLoad, markLoaded } = await import("./lazy-commands.js"), { setup } = await import("./commands/setup.js");
43
- setup(buddy);
44
- markLoaded(buddy, "setup");
45
- if (!skipAppKeyCheck) {
46
- const { runAction } = await import("@stacksjs/actions"), { Action } = await import("@stacksjs/enums"), { ensureProjectIsInitialized } = await import("@stacksjs/utils");
47
- if (!await ensureProjectIsInitialized()) {
48
- log.info("Your `APP_KEY` is not yet set");
49
- log.info("Generating application key...");
50
- const result = await runAction(Action.KeyGenerate);
51
- if (result.isErr) {
52
- log.error("Failed to set random application key.", result.error);
53
- process.exit(1);
54
- }
55
- }
56
- }
57
- const commandsToLoad = getCommandsToLoad(args);
58
- await loadCommands(commandsToLoad, buddy);
59
- await dynamicImports(buddy);
60
- } else {
61
- const { loadCommand } = await import("./lazy-commands.js");
62
- await loadCommand("version", buddy);
63
- }
64
- buddy.help();
65
- if (args.length === 0 && process.stdin.isTTY && !buddy.isNoInteraction)
66
- await showInteractiveMenu(buddy);
67
- else
68
- await parseOrExit(buddy);
69
- }
70
- async function showInteractiveMenu(buddy) {
71
- const { bold, green, intro } = await import("@stacksjs/cli"), { select } = await import("@stacksjs/cli");
72
- await intro("buddy");
73
- console.log(bold(green("What would you like to do?")));
74
- console.log("");
75
- const choice = await select({
76
- message: "Select a command:",
77
- choices: [
78
- { value: "dev", label: "Start development server" },
79
- { value: "build", label: "Build for production" },
80
- { value: "test", label: "Run tests" },
81
- { value: "list", label: "List all commands" },
82
- { value: "doctor", label: "Run health checks" },
83
- { value: "about", label: "Show system information" },
84
- { value: "help", label: "Show help" },
85
- { value: "exit", label: "Exit" }
86
- ],
87
- initial: 0
88
- });
89
- console.log("");
90
- if (choice === "exit")
91
- process.exit(0);
92
- else if (choice === "help")
93
- buddy.outputHelp();
94
- else {
95
- process.argv = ["bun", "buddy", choice];
96
- await parseOrExit(buddy);
97
- }
98
- }
99
- async function parseOrExit(buddy) {
100
- try {
101
- await buddy.parse();
102
- } catch (error) {
103
- if (!(error?.name === "ClappError" || error?.isUsageError === !0))
104
- throw error;
105
- process.stderr.write(`${error.message}
106
- `);
107
- if (error.usage)
108
- process.stderr.write(`${error.usage}
109
- `);
110
- process.exit(typeof error.exitCode === "number" ? error.exitCode : 2);
111
- }
112
- }
113
- await main();
114
- async function dynamicImports(buddy) {
115
- const { fs } = await import("@stacksjs/storage"), commandsDir = p.appPath("Commands");
116
- try {
117
- const registry = (await import(p.appPath("Commands.ts"))).default || {};
118
- for (const [signature, config] of Object.entries(registry)) {
119
- const commandConfig = typeof config === "string" ? { file: config, enabled: !0 } : config;
120
- if (commandConfig.enabled === !1)
121
- continue;
122
- const commandPath = `${commandsDir}/${commandConfig.file}.ts`;
123
- if (!fs.existsSync(commandPath)) {
124
- log.debug(`Command file not found: ${commandPath} (registered as '${signature}')`);
125
- continue;
126
- }
127
- try {
128
- const dynamicImport = await import(commandPath);
129
- if (typeof dynamicImport.default === "function") {
130
- dynamicImport.default(buddy);
131
- if (commandConfig.aliases && Array.isArray(commandConfig.aliases))
132
- for (const alias of commandConfig.aliases)
133
- buddy.alias(signature, alias);
134
- } else
135
- log.error(`Expected a default export function in ${commandConfig.file}.ts, but got:`, dynamicImport.default);
136
- } catch (error) {
137
- log.error(`Failed to load command ${commandConfig.file}:`, error);
138
- }
139
- }
140
- } catch {
141
- if (!fs.existsSync(commandsDir)) {
142
- log.debug("app/Commands directory not found, skipping user commands");
143
- return;
144
- }
145
- log.debug("Commands.ts not found, using auto-discovery");
146
- const commandFiles = fs.readdirSync(commandsDir).filter((file) => file.endsWith(".ts"));
147
- for (const file of commandFiles) {
148
- const commandPath = `${commandsDir}/${file}`;
149
- try {
150
- const dynamicImport = await import(commandPath);
151
- if (typeof dynamicImport.default === "function")
152
- dynamicImport.default(buddy);
153
- else
154
- log.debug(`Skipping ${file} \u2014 no default export function`);
155
- } catch (error) {
156
- log.error(`Failed to load command ${file}:`, error);
157
- }
158
- }
159
- }
160
- try {
161
- const listenerImport = await import(p.listenersPath("Console.ts"));
162
- if (typeof listenerImport.default === "function")
163
- listenerImport.default(buddy);
164
- } catch {}
165
- }
2
+ import process from"node:process";import{cli,log}from"@stacksjs/cli";import{path as p}from"@stacksjs/path";import{registerGlobalOptions}from"./global-options";import{shouldSkipAppKeyCheck}from"./project-setup";try{const{isSupportedBunVersion,minimumBunVersion}=await import("@stacksjs/utils"),currentBunVersion=typeof Bun<"u"?Bun.version:process.versions.bun;if(currentBunVersion&&!isSupportedBunVersion(currentBunVersion)){console.error(`[buddy] Bun v${minimumBunVersion} or later is required (current: v${currentBunVersion}). Run: bun upgrade`);process.exit(1)}}catch{}const args=process.argv.slice(2),requestedCommand=args[0]||"help",isHelpFlag=args.includes("--help")||args.includes("-h"),isVersionOnly=["--version","-V","version"].includes(requestedCommand),isHelpMode=requestedCommand==="help"||isHelpFlag&&args.length<=2,skipAppKeyCheck=shouldSkipAppKeyCheck(requestedCommand,{isHelpFlag,isHelpMode}),needsFullSetup=!isVersionOnly;if(needsFullSetup){const reportFatal=(label,error)=>{log.debug(`Buddy ${label}`);try{process.stderr.write(`
3
+ [buddy] ${label}: ${error?.stack??String(error)}
4
+ `)}catch{}log.error(error);return process.exit(1)};process.on("uncaughtException",(error)=>reportFatal("uncaughtException",error));process.on("unhandledRejection",(error)=>reportFatal("unhandledRejection",error))}async function main(){const buddy=cli("buddy");registerGlobalOptions(buddy,{version:requestedCommand!=="upgrade"&&requestedCommand!=="update"});const configPath="./buddy.config.js";try{await Bun.file(configPath).text();const{applyBuddyConfig}=await import("./config.js");await applyBuddyConfig(buddy)}catch{}if(needsFullSetup){p.ensureRuntimeDirectories();const{loadCommands,getCommandsToLoad,markLoaded}=await import("./lazy-commands.js"),{setup}=await import("./commands/setup.js");setup(buddy);markLoaded(buddy,"setup");if(!skipAppKeyCheck){const{runAction}=await import("@stacksjs/actions"),{Action}=await import("@stacksjs/enums"),{ensureProjectIsInitialized}=await import("@stacksjs/utils");if(!await ensureProjectIsInitialized()){log.info("Your `APP_KEY` is not yet set");log.info("Generating application key...");const result=await runAction(Action.KeyGenerate);if(result.isErr){log.error("Failed to set random application key.",result.error);process.exit(1)}}}const commandsToLoad=getCommandsToLoad(args);await loadCommands(commandsToLoad,buddy);await dynamicImports(buddy)}else{const{loadCommand}=await import("./lazy-commands.js");await loadCommand("version",buddy)}buddy.help();if(args.length===0&&process.stdin.isTTY&&!buddy.isNoInteraction)await showInteractiveMenu(buddy);else await parseOrExit(buddy)}async function showInteractiveMenu(buddy){const{bold,green,intro}=await import("@stacksjs/cli"),{select}=await import("@stacksjs/cli");await intro("buddy");console.log(bold(green("What would you like to do?")));console.log("");const choice=await select({message:"Select a command:",choices:[{value:"dev",label:"Start development server"},{value:"build",label:"Build for production"},{value:"test",label:"Run tests"},{value:"list",label:"List all commands"},{value:"doctor",label:"Run health checks"},{value:"about",label:"Show system information"},{value:"help",label:"Show help"},{value:"exit",label:"Exit"}],initial:0});console.log("");if(choice==="exit")process.exit(0);else if(choice==="help")buddy.outputHelp();else{process.argv=["bun","buddy",choice];await parseOrExit(buddy)}}async function parseOrExit(buddy){try{await buddy.parse()}catch(error){if(!(error?.name==="ClappError"||error?.isUsageError===!0))throw error;process.stderr.write(`${error.message}
5
+ `);if(error.usage)process.stderr.write(`${error.usage}
6
+ `);process.exit(typeof error.exitCode==="number"?error.exitCode:2)}}await main();export function applyAliases(buddy,signature,aliases){const name=signature.trim().split(/\s+/)[0],command=buddy.commands?.find((c)=>c.name===name);if(!command||typeof command.alias!=="function"){log.debug(`Could not alias '${name}': no matching command was registered.`);return}for(const alias of aliases)command.alias(alias)}async function dynamicImports(buddy){const{fs}=await import("@stacksjs/storage"),commandsDir=p.appPath("Commands");try{const registry=(await import(p.appPath("Commands.ts"))).default||{};for(const[signature,config]of Object.entries(registry)){const commandConfig=typeof config==="string"?{file:config,enabled:!0}:config;if(commandConfig.enabled===!1)continue;const commandPath=`${commandsDir}/${commandConfig.file}.ts`;if(!fs.existsSync(commandPath)){log.debug(`Command file not found: ${commandPath} (registered as '${signature}')`);continue}try{const dynamicImport=await import(commandPath);if(typeof dynamicImport.default==="function"){dynamicImport.default(buddy);if(commandConfig.aliases?.length)applyAliases(buddy,signature,commandConfig.aliases)}else log.error(`Expected a default export function in ${commandConfig.file}.ts, but got:`,dynamicImport.default)}catch(error){log.error(`Failed to load command ${commandConfig.file}:`,error)}}}catch{if(!fs.existsSync(commandsDir)){log.debug("app/Commands directory not found, skipping user commands");return}log.debug("Commands.ts not found, using auto-discovery");const commandFiles=fs.readdirSync(commandsDir).filter((file)=>file.endsWith(".ts"));for(const file of commandFiles){const commandPath=`${commandsDir}/${file}`;try{const dynamicImport=await import(commandPath);if(typeof dynamicImport.default==="function")dynamicImport.default(buddy);else log.debug(`Skipping ${file} \u2014 no default export function`)}catch(error){log.error(`Failed to load command ${file}:`,error)}}}try{const listenerImport=await import(p.listenersPath("Console.ts"));if(typeof listenerImport.default==="function")listenerImport.default(buddy)}catch{}}
@@ -1,35 +1 @@
1
- import process from "node:process";
2
- import { bold, dim, green, intro, log, onUnknownSubcommand } from "@stacksjs/cli";
3
- import { storage } from "@stacksjs/storage";
4
- export function about(buddy) {
5
- buddy.command("about", "Display diagnostic information about Stacks").action(async () => {
6
- log.debug("Running `buddy about` ...");
7
- await intro("buddy about");
8
- try {
9
- const stacksVersion = (await storage.readPackageJson("./package.json")).version || "unknown", bunVersion = process.versions.bun || "N/A", nodeVersion = process.versions.node || "N/A", os = process.platform, arch = process.arch, osVersion = process.version, env = process.env.NODE_ENV || process.env.APP_ENV || "development";
10
- log.info("");
11
- log.info(green(bold("Stacks Framework")));
12
- log.info(dim("\u2500".repeat(50)));
13
- log.info("");
14
- log.info(bold("Version Information:"));
15
- log.info(` Stacks: ${dim(stacksVersion)}`);
16
- log.info(` Bun: ${dim(bunVersion)}`);
17
- if (nodeVersion !== "N/A")
18
- log.info(` Node: ${dim(nodeVersion)}`);
19
- log.info("");
20
- log.info(bold("Environment:"));
21
- log.info(` Mode: ${dim(env)}`);
22
- log.info(` OS: ${dim(`${os} ${arch}`)}`);
23
- log.info(` Runtime: ${dim(osVersion)}`);
24
- log.info("");
25
- log.info(bold("Configuration:"));
26
- log.info(` Cache: ${dim("file")}`);
27
- log.info(` Debug: ${dim(process.env.DEBUG ? "enabled" : "disabled")}`);
28
- log.info("");
29
- } catch (error) {
30
- log.error("Failed to retrieve system information:", error);
31
- process.exit(1);
32
- }
33
- });
34
- onUnknownSubcommand(buddy, "about");
35
- }
1
+ import process from"node:process";import{bold,dim,green,intro,log,onUnknownSubcommand}from"@stacksjs/cli";import{storage}from"@stacksjs/storage";export function about(buddy){buddy.command("about","Display diagnostic information about Stacks").action(async()=>{log.debug("Running `buddy about` ...");await intro("buddy about");try{const stacksVersion=(await storage.readPackageJson("./package.json")).version||"unknown",bunVersion=process.versions.bun||"N/A",nodeVersion=process.versions.node||"N/A",os=process.platform,arch=process.arch,osVersion=process.version,env=process.env.NODE_ENV||process.env.APP_ENV||"development";log.info("");log.info(green(bold("Stacks Framework")));log.info(dim("\u2500".repeat(50)));log.info("");log.info(bold("Version Information:"));log.info(` Stacks: ${dim(stacksVersion)}`);log.info(` Bun: ${dim(bunVersion)}`);if(nodeVersion!=="N/A")log.info(` Node: ${dim(nodeVersion)}`);log.info("");log.info(bold("Environment:"));log.info(` Mode: ${dim(env)}`);log.info(` OS: ${dim(`${os} ${arch}`)}`);log.info(` Runtime: ${dim(osVersion)}`);log.info("");log.info(bold("Configuration:"));log.info(` Cache: ${dim("file")}`);log.info(` Debug: ${dim(process.env.DEBUG?"enabled":"disabled")}`);log.info("")}catch(error){log.error("Failed to retrieve system information:",error);process.exit(1)}});onUnknownSubcommand(buddy,"about")}
@@ -1,25 +1 @@
1
- import process from "node:process";
2
- import { installStack } from "@stacksjs/actions";
3
- import { intro, italic, log, onUnknownSubcommand, outro } from "@stacksjs/cli";
4
- import { ExitCode } from "@stacksjs/types";
5
- export function add(buddy) {
6
- buddy.command("add <stack>", "Pull a registered stack and merge its project files into this Stacks application").option("--force", "Overwrite existing files", { default: !1 }).option("--dry-run", "Show which files would be installed without changing the project", { default: !1 }).option("--conflict <strategy>", "Resolve existing files with skip, overwrite, or backup", { default: "skip" }).option("-p, --project <path>", "Target a specific Stacks project").option("--verbose", "Show every file copied or skipped", { default: !1 }).example("buddy add calendar").example("buddy add table --dry-run").example("buddy add calendar --conflict backup").action(async (stack, options) => {
7
- const perf = await intro("buddy add");
8
- if (!await installStack({
9
- name: stack,
10
- force: options.force,
11
- dryRun: options.dryRun,
12
- conflict: options.conflict,
13
- project: options.project,
14
- verbose: options.verbose
15
- })) {
16
- await outro(`Could not add stack ${italic(stack)}.`, { startTime: perf, useSeconds: !0 });
17
- process.exit(ExitCode.FatalError);
18
- }
19
- if (options.dryRun)
20
- log.info("Dry run complete. No project files were changed.");
21
- await outro(`Stack ${italic(stack)} added.`, { startTime: perf, useSeconds: !0 });
22
- process.exit(ExitCode.Success);
23
- });
24
- onUnknownSubcommand(buddy, "add");
25
- }
1
+ import process from"node:process";import{installStack}from"@stacksjs/actions";import{intro,italic,log,onUnknownSubcommand,outro}from"@stacksjs/cli";import{ExitCode}from"@stacksjs/types";export function add(buddy){buddy.command("add <stack>","Pull a registered stack and merge its project files into this Stacks application").option("--force","Overwrite existing files",{default:!1}).option("--dry-run","Show which files would be installed without changing the project",{default:!1}).option("--conflict <strategy>","Resolve existing files with skip, overwrite, or backup",{default:"skip"}).option("-p, --project <path>","Target a specific Stacks project").option("--verbose","Show every file copied or skipped",{default:!1}).example("buddy add calendar").example("buddy add table --dry-run").example("buddy add calendar --conflict backup").action(async(stack,options)=>{const perf=await intro("buddy add");if(!await installStack({name:stack,force:options.force,dryRun:options.dryRun,conflict:options.conflict,project:options.project,verbose:options.verbose})){await outro(`Could not add stack ${italic(stack)}.`,{startTime:perf,useSeconds:!0});process.exit(ExitCode.FatalError)}if(options.dryRun)log.info("Dry run complete. No project files were changed.");await outro(`Stack ${italic(stack)} added.`,{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});onUnknownSubcommand(buddy,"add")}
@@ -1,29 +1,6 @@
1
- import { mkdirSync, writeFileSync } from "node:fs";
2
- import { dirname, resolve } from "node:path";
3
- import process from "node:process";
4
- import { buildProjectContext } from "@stacksjs/ai";
5
- import { onUnknownSubcommand } from "@stacksjs/cli";
6
- export function generateAiContextOutput(options = {}, projectRoot = process.cwd()) {
7
- const maxChars = options.maxChars === void 0 ? void 0 : Number(options.maxChars), result = buildProjectContext(projectRoot, { maxChars, model: options.model }), output = options.json ? `${JSON.stringify(result, null, 2)}
8
- ` : `${result.text}
1
+ import{mkdirSync,writeFileSync}from"node:fs";import{dirname,resolve}from"node:path";import process from"node:process";import{buildProjectContext}from"@stacksjs/ai";import{onUnknownSubcommand}from"@stacksjs/cli";export function generateAiContextOutput(options={},projectRoot=process.cwd()){const maxChars=options.maxChars===void 0?void 0:Number(options.maxChars),result=buildProjectContext(projectRoot,{maxChars,model:options.model}),output=options.json?`${JSON.stringify(result,null,2)}
2
+ `:`${result.text}
9
3
 
10
4
  Context metrics:
11
- ${JSON.stringify(result.metrics, null, 2)}
12
- `;
13
- if (!options.output)
14
- return { output, outputPath: null };
15
- const outputPath = resolve(projectRoot, String(options.output));
16
- mkdirSync(dirname(outputPath), { recursive: !0 });
17
- writeFileSync(outputPath, output);
18
- return { output, outputPath };
19
- }
20
- export function aiContext(buddy) {
21
- buddy.command("ai:context", "Generate compact deterministic project context for coding models").option("-J, --json", "Emit the versioned machine-readable context contract", { default: !1 }).option("-o, --output [path]", "Write output to a file instead of stdout").option("--max-chars [characters]", "Maximum characters in the prompt context payload", { default: 4000 }).option("--model [model]", "Model family used for the heuristic token estimate", { default: "gpt-4o" }).example("buddy ai:context").example("buddy ai:context --json").example("buddy ai:context --json --output storage/framework/runtime/ai-context.json").action((options) => {
22
- const generated = generateAiContextOutput(options);
23
- if (generated.outputPath)
24
- console.log(`Wrote AI project context to ${generated.outputPath}`);
25
- else
26
- process.stdout.write(generated.output);
27
- });
28
- onUnknownSubcommand(buddy, "ai:context");
29
- }
5
+ ${JSON.stringify(result.metrics,null,2)}
6
+ `;if(!options.output)return{output,outputPath:null};const outputPath=resolve(projectRoot,String(options.output));mkdirSync(dirname(outputPath),{recursive:!0});writeFileSync(outputPath,output);return{output,outputPath}}export function aiContext(buddy){buddy.command("ai:context","Generate compact deterministic project context for coding models").option("-J, --json","Emit the versioned machine-readable context contract",{default:!1}).option("-o, --output [path]","Write output to a file instead of stdout").option("--max-chars [characters]","Maximum characters in the prompt context payload",{default:4000}).option("--model [model]","Model family used for the heuristic token estimate",{default:"gpt-4o"}).example("buddy ai:context").example("buddy ai:context --json").example("buddy ai:context --json --output storage/framework/runtime/ai-context.json").action((options)=>{const generated=generateAiContextOutput(options);if(generated.outputPath)console.log(`Wrote AI project context to ${generated.outputPath}`);else process.stdout.write(generated.output)});onUnknownSubcommand(buddy,"ai:context")}
@@ -1,68 +1 @@
1
- import process from "node:process";
2
- import { runAction } from "@stacksjs/actions";
3
- import { intro, log, onUnknownSubcommand, outro } from "@stacksjs/cli";
4
- import { Action } from "@stacksjs/enums";
5
- import { ExitCode } from "@stacksjs/types";
6
- export function auth(buddy) {
7
- const descriptions = {
8
- setup: "Set up authentication (migrations + personal access client)",
9
- token: "Create a personal access client token",
10
- client: "Create a new OAuth client",
11
- prune: "Prune expired and revoked tokens",
12
- project: "Target a specific project",
13
- verbose: "Enable verbose output"
14
- };
15
- buddy.command("auth:setup", descriptions.setup).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
16
- log.debug("Running `buddy auth:setup` ...", options);
17
- const perf = await intro("buddy auth:setup"), result = await runAction(Action.AuthSetup, options);
18
- if (result.isErr) {
19
- await outro("While setting up authentication, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
20
- process.exit(ExitCode.FatalError);
21
- }
22
- await outro("Authentication setup completed successfully.", {
23
- startTime: perf,
24
- useSeconds: !0
25
- });
26
- process.exit(ExitCode.Success);
27
- });
28
- buddy.command("auth:token", descriptions.token).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
29
- log.debug("Running `buddy auth:token` ...", options);
30
- const perf = await intro("buddy auth:token"), result = await runAction(Action.CreatePersonalAccessClient, options);
31
- if (result.isErr) {
32
- await outro("While creating the personal access client token, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
33
- process.exit(ExitCode.FatalError);
34
- }
35
- await outro("Personal access client token created successfully.", {
36
- startTime: perf,
37
- useSeconds: !0
38
- });
39
- process.exit(ExitCode.Success);
40
- });
41
- buddy.command("auth:client", descriptions.client).option("-n, --name [name]", "Client name", { default: "OAuth Client" }).option("-r, --redirect [redirect]", "Redirect URI", { default: "http://localhost" }).option("--personal", "Create a personal access client", { default: !1 }).option("--password", "Create a password grant client", { default: !1 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
42
- log.debug("Running `buddy auth:client` ...", options);
43
- const perf = await intro("buddy auth:client"), result = await runAction(Action.AuthClient, options);
44
- if (result.isErr) {
45
- await outro("While creating the OAuth client, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
46
- process.exit(ExitCode.FatalError);
47
- }
48
- await outro("OAuth client created successfully.", {
49
- startTime: perf,
50
- useSeconds: !0
51
- });
52
- process.exit(ExitCode.Success);
53
- });
54
- buddy.command("auth:prune", descriptions.prune).option("--expired", "Prune expired tokens (default: true)", { default: !0 }).option("--revoked", "Prune revoked tokens (default: true)", { default: !0 }).option("-d, --days [days]", "Prune revoked tokens older than N days", { default: 7 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
55
- log.debug("Running `buddy auth:prune` ...", options);
56
- const perf = await intro("buddy auth:prune"), result = await runAction(Action.AuthPrune, options);
57
- if (result.isErr) {
58
- await outro("While pruning tokens, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
59
- process.exit(ExitCode.FatalError);
60
- }
61
- await outro("Token pruning completed successfully.", {
62
- startTime: perf,
63
- useSeconds: !0
64
- });
65
- process.exit(ExitCode.Success);
66
- });
67
- onUnknownSubcommand(buddy, "auth");
68
- }
1
+ import process from"node:process";import{runAction}from"@stacksjs/actions";import{intro,log,onUnknownSubcommand,outro}from"@stacksjs/cli";import{Action}from"@stacksjs/enums";import{ExitCode}from"@stacksjs/types";export function auth(buddy){const descriptions={setup:"Set up authentication (migrations + personal access client)",token:"Create a personal access client token",client:"Create a new OAuth client",prune:"Prune expired and revoked tokens",project:"Target a specific project",verbose:"Enable verbose output"};buddy.command("auth:setup",descriptions.setup).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy auth:setup` ...",options);const perf=await intro("buddy auth:setup"),result=await runAction(Action.AuthSetup,options);if(result.isErr){await outro("While setting up authentication, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}await outro("Authentication setup completed successfully.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("auth:token",descriptions.token).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy auth:token` ...",options);const perf=await intro("buddy auth:token"),result=await runAction(Action.CreatePersonalAccessClient,options);if(result.isErr){await outro("While creating the personal access client token, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}await outro("Personal access client token created successfully.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("auth:client",descriptions.client).option("-n, --name [name]","Client name",{default:"OAuth Client"}).option("-r, --redirect [redirect]","Redirect URI",{default:"http://localhost"}).option("--personal","Create a personal access client",{default:!1}).option("--password","Create a password grant client",{default:!1}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy auth:client` ...",options);const perf=await intro("buddy auth:client"),result=await runAction(Action.AuthClient,options);if(result.isErr){await outro("While creating the OAuth client, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}await outro("OAuth client created successfully.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("auth:prune",descriptions.prune).option("--expired","Prune expired tokens (default: true)",{default:!0}).option("--revoked","Prune revoked tokens (default: true)",{default:!0}).option("-d, --days [days]","Prune revoked tokens older than N days",{default:7}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy auth:prune` ...",options);const perf=await intro("buddy auth:prune"),result=await runAction(Action.AuthPrune,options);if(result.isErr){await outro("While pruning tokens, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}await outro("Token pruning completed successfully.",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});onUnknownSubcommand(buddy,"auth")}
@@ -1,221 +1 @@
1
- import process from "node:process";
2
- import { intro, log, multiselect, onUnknownSubcommand, outro } from "@stacksjs/cli";
3
- import { Action } from "@stacksjs/enums";
4
- import { hasTTY, isCI } from "@stacksjs/env";
5
- import { ExitCode } from "@stacksjs/types";
6
- let _runAction;
7
- async function runAction(...args) {
8
- if (!_runAction)
9
- _runAction = (await import("@stacksjs/actions")).runAction;
10
- return _runAction(...args);
11
- }
12
- export function build(buddy) {
13
- const descriptions = {
14
- build: "Build any of your libraries (packages) for production use",
15
- components: "Build your component library",
16
- webComponents: "Build your framework agnostic web component library",
17
- elements: "An alias to the -w flag",
18
- buddy: "Build the Buddy binary",
19
- functions: "Build your function library",
20
- desktop: "Build the Desktop Application",
21
- dmg: "Package the desktop build as a macOS .app inside a .dmg",
22
- pages: "Build your frontend",
23
- docs: "Build your documentation",
24
- framework: "Build Stacks framework",
25
- cli: "Automagically build the CLI",
26
- server: "Build the Stacks cloud server (Docker image)",
27
- frontendStatic: "Build the prerendered marketing/public static site (storage/framework/frontend-dist)",
28
- select: "What are you trying to build?",
29
- project: "Target a specific project",
30
- verbose: "Enable verbose output"
31
- };
32
- buddy.command("build [type]", descriptions.build).option("-c, --components", descriptions.components).option("-w, --web-components", descriptions.webComponents).option("-e, --elements", descriptions.elements).option("-f, --functions", descriptions.functions).option("-k, --desktop", descriptions.desktop).option("-p, --views", descriptions.pages).option("--pages", descriptions.pages).option("-d, --docs", descriptions.docs).option("-b, --buddy", descriptions.buddy, { default: !1 }).option("-s, --stacks", descriptions.framework, { default: !1 }).option("--project [project]", descriptions.project, { default: !1 }).option("--server", descriptions.server, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (server, options) => {
33
- log.debug("Running `buddy build` ...", options);
34
- applyBuildTarget(server, options);
35
- if (hasNoOptions(options)) {
36
- if (!isCI && hasTTY && process.stdin.isTTY) {
37
- const answers = await multiselect({
38
- message: descriptions.select,
39
- choices: [
40
- { label: "Frontend (views)", value: "views" },
41
- { label: "Components", value: "components" },
42
- { label: "Web Components", value: "webComponents" },
43
- { label: "Functions", value: "functions" },
44
- { label: "Desktop application", value: "desktop" },
45
- { label: "Documentation", value: "docs" },
46
- { label: "Stacks framework", value: "stacks" },
47
- { label: "Buddy CLI", value: "buddy" },
48
- { label: "Server (Docker image)", value: "server" }
49
- ]
50
- }), selected = new Set(answers);
51
- if (selected.has("views"))
52
- options.views = !0;
53
- if (selected.has("components"))
54
- options.components = !0;
55
- if (selected.has("webComponents"))
56
- options.webComponents = !0;
57
- if (selected.has("functions"))
58
- options.functions = !0;
59
- if (selected.has("desktop"))
60
- options.desktop = !0;
61
- if (selected.has("docs"))
62
- options.docs = !0;
63
- if (selected.has("stacks"))
64
- options.stacks = !0;
65
- if (selected.has("buddy"))
66
- options.buddy = !0;
67
- if (selected.has("server"))
68
- options.server = !0;
69
- }
70
- if (hasNoOptions(options)) {
71
- options.views = !0;
72
- log.info("No build target specified, defaulting to the frontend (views). See `buddy build --help` for all targets.");
73
- }
74
- }
75
- let succeeded = !0;
76
- if (options.docs)
77
- succeeded = await runBuildAction(Action.BuildDocs, "documentation") && succeeded;
78
- if (options.components)
79
- succeeded = await runBuildAction(Action.BuildComponentLibs, "component libraries") && succeeded;
80
- if (options.webComponents)
81
- succeeded = await runBuildAction(Action.BuildWebComponentLib, "web component library") && succeeded;
82
- if (options.functions)
83
- succeeded = await runBuildAction(Action.BuildFunctionLib, "function library") && succeeded;
84
- if (options.desktop)
85
- succeeded = await runBuildAction(Action.BuildDesktop, "desktop application") && succeeded;
86
- if (options.views)
87
- succeeded = await runBuildAction(Action.BuildViews, "frontend") && succeeded;
88
- if (options.stacks)
89
- succeeded = await runBuildAction(Action.BuildStacks, "Stacks framework") && succeeded;
90
- if (options.buddy)
91
- succeeded = await runBuildAction(Action.BuildCli, "Buddy CLI") && succeeded;
92
- if (options.server)
93
- succeeded = await runBuildAction(Action.BuildServer, "server") && succeeded;
94
- if (!succeeded)
95
- process.exit(ExitCode.FatalError);
96
- process.exit(ExitCode.Success);
97
- });
98
- buddy.command("build:components", "Automagically build component libraries for production use & npm/CDN distribution").alias("prod:components").option("-c, --components", descriptions.components, { default: !0 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
99
- log.debug("Running `buddy build:components` ...", options);
100
- if (!await runBuildAction(Action.BuildComponentLibs, "component libraries"))
101
- process.exit(ExitCode.FatalError);
102
- });
103
- buddy.command("build:cli", descriptions.cli).alias("prod:cli").option("-b, --buddy", descriptions.buddy, { default: !0 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
104
- log.debug("Running `buddy build:cli` ...", options);
105
- await runAction(Action.BuildCli, options);
106
- });
107
- buddy.command("build:server", descriptions.server).alias("prod:server").alias("build:docker").option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
108
- log.debug("Running `buddy build:server` ...", options);
109
- await runAction(Action.BuildServer, options);
110
- });
111
- buddy.command("build:functions", "Automagically build function library for npm/CDN distribution").option("-f, --functions", descriptions.functions, { default: !0 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
112
- log.debug("Running `buddy build:functions` ...", options);
113
- await runAction(Action.BuildFunctionLib, options);
114
- });
115
- buddy.command("build:web-components", "Automagically build Web Component library for npm/CDN distribution").alias("build:wc").alias("prod:web-components").alias("prod:wc").option("-w, --web-components", descriptions.webComponents, {
116
- default: !0
117
- }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
118
- log.debug("Running `buddy build:web-components` ...", options);
119
- if (!await runBuildAction(Action.BuildWebComponentLib, "web component library"))
120
- process.exit(ExitCode.FatalError);
121
- });
122
- buddy.command("build:frontend", descriptions.pages).alias("build:pages").alias("build:views").alias("prod:frontend").option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
123
- log.debug("Running `buddy build:frontend` ...", options);
124
- await runAction(Action.BuildViews, options);
125
- });
126
- buddy.command("build:docs", "Automagically build your documentation site.").alias("prod:docs").alias("build:documentation").alias("prod:documentation").option("-d, --docs", descriptions.docs, { default: !0 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
127
- log.debug("Running `buddy build:docs` ...", options);
128
- await runAction(Action.BuildDocs, options);
129
- });
130
- buddy.command("build:frontend-static", descriptions.frontendStatic).alias("build:public").alias("prod:frontend-static").option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
131
- log.debug("Running `buddy build:frontend-static` ...", options);
132
- await runAction(Action.BuildFrontendStatic, options);
133
- });
134
- buddy.command("build:core", "Automagically build the Stacks core.").option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
135
- log.debug("Running `buddy build:core` ...", options);
136
- const startTime = await intro("buddy build:core"), result = await runAction(Action.BuildCore, options);
137
- if (result.isErr) {
138
- log.error("Failed to build the Stacks core.", result.error);
139
- process.exit(ExitCode.FatalError);
140
- }
141
- await outro("Core packages built successfully", {
142
- startTime,
143
- useSeconds: !0
144
- });
145
- });
146
- buddy.command("build:desktop", descriptions.desktop).alias("prod:desktop").option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
147
- log.debug("Running `buddy build:desktop` ...", options);
148
- const perf = await intro("buddy build:desktop"), result = await runAction(Action.BuildDesktop, options);
149
- if (result.isErr) {
150
- await outro("While running the build:desktop command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
151
- process.exit(ExitCode.FatalError);
152
- }
153
- console.log("");
154
- await outro("Exited", { startTime: perf, useSeconds: !0 });
155
- process.exit(ExitCode.Success);
156
- });
157
- buddy.command("build:dmg", descriptions.dmg).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
158
- log.debug("Running `buddy build:dmg` ...", options);
159
- const perf = await intro("buddy build:dmg"), result = await runAction(Action.BuildDmg, options);
160
- if (result.isErr) {
161
- await outro("While running the build:dmg command, there was an issue", { startTime: perf, useSeconds: !0 }, result.error);
162
- process.exit(ExitCode.FatalError);
163
- }
164
- console.log("");
165
- await outro("Exited", { startTime: perf, useSeconds: !0 });
166
- process.exit(ExitCode.Success);
167
- });
168
- buddy.command("build:stacks", "Build the Stacks framework.").option("-s, --stacks", descriptions.framework, { default: !0 }).option("-p, --project [project]", descriptions.project, { default: !1 }).option("--verbose", descriptions.verbose, { default: !1 }).action(async (options) => {
169
- log.debug("Running `buddy build:stacks` ...", options);
170
- const startTime = await intro("buddy build:stacks"), result = await runAction(Action.BuildStacks, options);
171
- if (result.isErr) {
172
- log.error("Failed to build Stacks.", result.error);
173
- process.exit(ExitCode.FatalError);
174
- }
175
- await outro("Stacks built successfully", { startTime, useSeconds: !0 });
176
- });
177
- onUnknownSubcommand(buddy, "build");
178
- }
179
- function hasNoOptions(options) {
180
- return !options.components && !options.webComponents && !options.elements && !options.functions && !options.desktop && !options.views && !options.docs && !options.stacks && !options.buddy && !options.server;
181
- }
182
- export function applyBuildTarget(target, options) {
183
- switch (target) {
184
- case "components":
185
- options.components = !0;
186
- break;
187
- case "web-components":
188
- options.webComponents = !0;
189
- break;
190
- case "functions":
191
- options.functions = !0;
192
- break;
193
- case "desktop":
194
- options.desktop = !0;
195
- break;
196
- case "views":
197
- options.views = !0;
198
- break;
199
- case "docs":
200
- options.docs = !0;
201
- break;
202
- case "buddy":
203
- case "cli":
204
- options.buddy = !0;
205
- break;
206
- case "stacks":
207
- options.stacks = !0;
208
- break;
209
- case "server":
210
- options.server = !0;
211
- break;
212
- }
213
- }
214
- async function runBuildAction(action, target) {
215
- const result = await runAction(action);
216
- if (result.isErr) {
217
- log.error(`Failed to build ${target}.`, result.error);
218
- return !1;
219
- }
220
- return !0;
221
- }
1
+ import process from"node:process";import{intro,log,multiselect,onUnknownSubcommand,outro}from"@stacksjs/cli";import{Action}from"@stacksjs/enums";import{hasTTY,isCI}from"@stacksjs/env";import{ExitCode}from"@stacksjs/types";let _runAction;async function runAction(...args){if(!_runAction)_runAction=(await import("@stacksjs/actions")).runAction;return _runAction(...args)}export function build(buddy){const descriptions={build:"Build any of your libraries (packages) for production use",components:"Build your component library",webComponents:"Build your framework agnostic web component library",elements:"An alias to the -w flag",buddy:"Build the Buddy binary",functions:"Build your function library",desktop:"Build the Desktop Application",dmg:"Package the desktop build as a macOS .app inside a .dmg",pages:"Build your frontend",docs:"Build your documentation",framework:"Build Stacks framework",cli:"Automagically build the CLI",server:"Build the Stacks cloud server (Docker image)",frontendStatic:"Build the prerendered marketing/public static site (storage/framework/frontend-dist)",select:"What are you trying to build?",project:"Target a specific project",verbose:"Enable verbose output"};buddy.command("build [type]",descriptions.build).option("-c, --components",descriptions.components).option("-w, --web-components",descriptions.webComponents).option("-e, --elements",descriptions.elements).option("-f, --functions",descriptions.functions).option("-k, --desktop",descriptions.desktop).option("-p, --views",descriptions.pages).option("--pages",descriptions.pages).option("-d, --docs",descriptions.docs).option("-b, --buddy",descriptions.buddy,{default:!1}).option("-s, --stacks",descriptions.framework,{default:!1}).option("--project [project]",descriptions.project,{default:!1}).option("--server",descriptions.server,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(server,options)=>{log.debug("Running `buddy build` ...",options);applyBuildTarget(server,options);if(hasNoOptions(options)){if(!isCI&&hasTTY&&process.stdin.isTTY){const answers=await multiselect({message:descriptions.select,choices:[{label:"Frontend (views)",value:"views"},{label:"Components",value:"components"},{label:"Web Components",value:"webComponents"},{label:"Functions",value:"functions"},{label:"Desktop application",value:"desktop"},{label:"Documentation",value:"docs"},{label:"Stacks framework",value:"stacks"},{label:"Buddy CLI",value:"buddy"},{label:"Server (Docker image)",value:"server"}]}),selected=new Set(answers);if(selected.has("views"))options.views=!0;if(selected.has("components"))options.components=!0;if(selected.has("webComponents"))options.webComponents=!0;if(selected.has("functions"))options.functions=!0;if(selected.has("desktop"))options.desktop=!0;if(selected.has("docs"))options.docs=!0;if(selected.has("stacks"))options.stacks=!0;if(selected.has("buddy"))options.buddy=!0;if(selected.has("server"))options.server=!0}if(hasNoOptions(options)){options.views=!0;log.info("No build target specified, defaulting to the frontend (views). See `buddy build --help` for all targets.")}}let succeeded=!0;if(options.docs)succeeded=await runBuildAction(Action.BuildDocs,"documentation")&&succeeded;if(options.components)succeeded=await runBuildAction(Action.BuildComponentLibs,"component libraries")&&succeeded;if(options.webComponents)succeeded=await runBuildAction(Action.BuildWebComponentLib,"web component library")&&succeeded;if(options.functions)succeeded=await runBuildAction(Action.BuildFunctionLib,"function library")&&succeeded;if(options.desktop)succeeded=await runBuildAction(Action.BuildDesktop,"desktop application")&&succeeded;if(options.views)succeeded=await runBuildAction(Action.BuildViews,"frontend")&&succeeded;if(options.stacks)succeeded=await runBuildAction(Action.BuildStacks,"Stacks framework")&&succeeded;if(options.buddy)succeeded=await runBuildAction(Action.BuildCli,"Buddy CLI")&&succeeded;if(options.server)succeeded=await runBuildAction(Action.BuildServer,"server")&&succeeded;if(!succeeded)process.exit(ExitCode.FatalError);process.exit(ExitCode.Success)});buddy.command("build:components","Automagically build component libraries for production use & npm/CDN distribution").alias("prod:components").option("-c, --components",descriptions.components,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:components` ...",options);if(!await runBuildAction(Action.BuildComponentLibs,"component libraries"))process.exit(ExitCode.FatalError)});buddy.command("build:cli",descriptions.cli).alias("prod:cli").option("-b, --buddy",descriptions.buddy,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:cli` ...",options);await runAction(Action.BuildCli,options)});buddy.command("build:server",descriptions.server).alias("prod:server").alias("build:docker").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:server` ...",options);await runAction(Action.BuildServer,options)});buddy.command("build:functions","Automagically build function library for npm/CDN distribution").option("-f, --functions",descriptions.functions,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:functions` ...",options);await runAction(Action.BuildFunctionLib,options)});buddy.command("build:web-components","Automagically build Web Component library for npm/CDN distribution").alias("build:wc").alias("prod:web-components").alias("prod:wc").option("-w, --web-components",descriptions.webComponents,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:web-components` ...",options);if(!await runBuildAction(Action.BuildWebComponentLib,"web component library"))process.exit(ExitCode.FatalError)});buddy.command("build:frontend",descriptions.pages).alias("build:pages").alias("build:views").alias("prod:frontend").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:frontend` ...",options);await runAction(Action.BuildViews,options)});buddy.command("build:docs","Automagically build your documentation site.").alias("prod:docs").alias("build:documentation").alias("prod:documentation").option("-d, --docs",descriptions.docs,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:docs` ...",options);await runAction(Action.BuildDocs,options)});buddy.command("build:frontend-static",descriptions.frontendStatic).alias("build:public").alias("prod:frontend-static").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:frontend-static` ...",options);await runAction(Action.BuildFrontendStatic,options)});buddy.command("build:core","Automagically build the Stacks core.").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:core` ...",options);const startTime=await intro("buddy build:core"),result=await runAction(Action.BuildCore,options);if(result.isErr){log.error("Failed to build the Stacks core.",result.error);process.exit(ExitCode.FatalError)}await outro("Core packages built successfully",{startTime,useSeconds:!0})});buddy.command("build:desktop",descriptions.desktop).alias("prod:desktop").option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:desktop` ...",options);const perf=await intro("buddy build:desktop"),result=await runAction(Action.BuildDesktop,options);if(result.isErr){await outro("While running the build:desktop command, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}console.log("");await outro("Exited",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("build:dmg",descriptions.dmg).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:dmg` ...",options);const perf=await intro("buddy build:dmg"),result=await runAction(Action.BuildDmg,options);if(result.isErr){await outro("While running the build:dmg command, there was an issue",{startTime:perf,useSeconds:!0},result.error);process.exit(ExitCode.FatalError)}console.log("");await outro("Exited",{startTime:perf,useSeconds:!0});process.exit(ExitCode.Success)});buddy.command("build:stacks","Build the Stacks framework.").option("-s, --stacks",descriptions.framework,{default:!0}).option("-p, --project [project]",descriptions.project,{default:!1}).option("--verbose",descriptions.verbose,{default:!1}).action(async(options)=>{log.debug("Running `buddy build:stacks` ...",options);const startTime=await intro("buddy build:stacks"),result=await runAction(Action.BuildStacks,options);if(result.isErr){log.error("Failed to build Stacks.",result.error);process.exit(ExitCode.FatalError)}await outro("Stacks built successfully",{startTime,useSeconds:!0})});onUnknownSubcommand(buddy,"build")}function hasNoOptions(options){return!options.components&&!options.webComponents&&!options.elements&&!options.functions&&!options.desktop&&!options.views&&!options.docs&&!options.stacks&&!options.buddy&&!options.server}export function applyBuildTarget(target,options){switch(target){case"components":options.components=!0;break;case"web-components":options.webComponents=!0;break;case"functions":options.functions=!0;break;case"desktop":options.desktop=!0;break;case"views":options.views=!0;break;case"docs":options.docs=!0;break;case"buddy":case"cli":options.buddy=!0;break;case"stacks":options.stacks=!0;break;case"server":options.server=!0;break}}async function runBuildAction(action,target){const result=await runAction(action);if(result.isErr){log.error(`Failed to build ${target}.`,result.error);return!1}return!0}