@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
@@ -1,241 +1 @@
1
- const commandRegistry = {
2
- about: { path: "./commands/about.js", exportName: "about" },
3
- add: { path: "./commands/add.js", exportName: "add" },
4
- "ai:context": { path: "./commands/ai-context.js", exportName: "aiContext" },
5
- auth: { path: "./commands/auth.js", exportName: "auth" },
6
- build: { path: "./commands/build.js", exportName: "build" },
7
- cd: { path: "./commands/cd.js", exportName: "cd" },
8
- changelog: { path: "./commands/changelog.js", exportName: "changelog" },
9
- clean: { path: "./commands/clean.js", exportName: "clean" },
10
- cloud: { path: "./commands/cloud.js", exportName: "cloud" },
11
- commit: { path: "./commands/commit.js", exportName: "commit" },
12
- completion: { path: "./commands/completion.js", exportName: "completion" },
13
- "config:migrate": { path: "./commands/config-migrate.js", exportName: "configMigrate" },
14
- configure: { path: "./commands/configure.js", exportName: "configure" },
15
- create: { path: "./commands/create.js", exportName: "create" },
16
- new: { path: "./commands/create.js", exportName: "create" },
17
- deploy: { path: "./commands/deploy.js", exportName: "deploy" },
18
- dev: { path: "./commands/dev.js", exportName: "dev" },
19
- "desktop:apple:doctor": { path: "./commands/desktop-apple.js", exportName: "desktopApple" },
20
- "desktop:apple:csr": { path: "./commands/desktop-apple.js", exportName: "desktopApple" },
21
- "desktop:apple:init": { path: "./commands/desktop-apple.js", exportName: "desktopApple" },
22
- "desktop:apple:package": { path: "./commands/desktop-apple.js", exportName: "desktopApple" },
23
- "desktop:apple:provision": { path: "./commands/desktop-apple.js", exportName: "desktopApple" },
24
- "desktop:apple:publish": { path: "./commands/desktop-apple.js", exportName: "desktopApple" },
25
- dns: { path: "./commands/dns.js", exportName: "dns" },
26
- "dns:pull": { path: "./commands/dns.js", exportName: "dns" },
27
- "dns:diff": { path: "./commands/dns.js", exportName: "dns" },
28
- "dns:sync": { path: "./commands/dns.js", exportName: "dns" },
29
- doctor: { path: "./commands/doctor.js", exportName: "doctor" },
30
- domains: { path: "./commands/domains.js", exportName: "domains" },
31
- email: { path: "./commands/email.js", exportName: "email" },
32
- env: { path: "./commands/env.js", exportName: "env" },
33
- "extension:init": { path: "./commands/extension.js", exportName: "extension" },
34
- "extension:build": { path: "./commands/extension.js", exportName: "extension" },
35
- "extension:package": { path: "./commands/extension.js", exportName: "extension" },
36
- "extension:chrome:publish": { path: "./commands/extension.js", exportName: "extension" },
37
- "extension:chrome:status": { path: "./commands/extension.js", exportName: "extension" },
38
- "extension:firefox:publish": { path: "./commands/extension.js", exportName: "extension" },
39
- "extension:safari:init": { path: "./commands/extension.js", exportName: "extension" },
40
- "extension:safari:provision": { path: "./commands/extension.js", exportName: "extension" },
41
- "extension:safari:app": { path: "./commands/extension.js", exportName: "extension" },
42
- "extension:safari:publish": { path: "./commands/extension.js", exportName: "extension" },
43
- "dashboard:install": { path: "./commands/features.js", exportName: "features" },
44
- "dashboard:uninstall": { path: "./commands/features.js", exportName: "features" },
45
- "commerce:install": { path: "./commands/features.js", exportName: "features" },
46
- "commerce:uninstall": { path: "./commands/features.js", exportName: "features" },
47
- "cms:install": { path: "./commands/features.js", exportName: "features" },
48
- "cms:uninstall": { path: "./commands/features.js", exportName: "features" },
49
- "marketing:install": { path: "./commands/features.js", exportName: "features" },
50
- "marketing:uninstall": { path: "./commands/features.js", exportName: "features" },
51
- "monitoring:install": { path: "./commands/features.js", exportName: "features" },
52
- "monitoring:uninstall": { path: "./commands/features.js", exportName: "features" },
53
- "realtime:install": { path: "./commands/features.js", exportName: "features" },
54
- "realtime:uninstall": { path: "./commands/features.js", exportName: "features" },
55
- "queue:install": { path: "./commands/features.js", exportName: "features" },
56
- "queue:uninstall": { path: "./commands/features.js", exportName: "features" },
57
- fresh: { path: "./commands/fresh.js", exportName: "fresh" },
58
- generate: { path: "./commands/generate.js", exportName: "generate" },
59
- http: { path: "./commands/http.js", exportName: "http" },
60
- install: { path: "./commands/install.js", exportName: "install" },
61
- key: { path: "./commands/key.js", exportName: "key" },
62
- lint: { path: "./commands/lint.js", exportName: "lint" },
63
- format: { path: "./commands/lint.js", exportName: "lint" },
64
- "format:check": { path: "./commands/lint.js", exportName: "lint" },
65
- list: { path: "./commands/list.js", exportName: "list" },
66
- mail: { path: "./commands/mail.js", exportName: "mailCommands" },
67
- "mail:preview": { path: "./commands/mail.js", exportName: "mailCommands" },
68
- maintenance: { path: "./commands/maintenance.js", exportName: "maintenance" },
69
- down: { path: "./commands/maintenance.js", exportName: "maintenance" },
70
- up: { path: "./commands/maintenance.js", exportName: "maintenance" },
71
- status: { path: "./commands/maintenance.js", exportName: "maintenance" },
72
- "coming-soon": { path: "./commands/maintenance.js", exportName: "maintenance" },
73
- "coming-soon:status": { path: "./commands/maintenance.js", exportName: "maintenance" },
74
- launch: { path: "./commands/maintenance.js", exportName: "maintenance" },
75
- make: { path: "./commands/make.js", exportName: "make" },
76
- "scaffold:crud": { path: "./commands/make.js", exportName: "make" },
77
- migrate: { path: "./commands/migrate.js", exportName: "migrate" },
78
- "migrate:fresh": { path: "./commands/migrate.js", exportName: "migrate" },
79
- "migrate:switch": { path: "./commands/migrate.js", exportName: "migrate" },
80
- "migrate:dns": { path: "./commands/migrate.js", exportName: "migrate" },
81
- "migrate:project": { path: "./commands/migrate-project.js", exportName: "migrateProject" },
82
- outdated: { path: "./commands/outdated.js", exportName: "outdated" },
83
- package: { path: "./commands/package.js", exportName: "packageCommands" },
84
- phone: { path: "./commands/phone.js", exportName: "phone" },
85
- ports: { path: "./commands/ports.js", exportName: "ports" },
86
- "link:core": { path: "./commands/link.js", exportName: "link" },
87
- "user:add": { path: "./commands/user.js", exportName: "user" },
88
- "user:list": { path: "./commands/user.js", exportName: "user" },
89
- "unlink:core": { path: "./commands/link.js", exportName: "link" },
90
- prepublish: { path: "./commands/prepublish.js", exportName: "prepublish" },
91
- projects: { path: "./commands/projects.js", exportName: "projects" },
92
- publish: { path: "./commands/publish.js", exportName: "publish" },
93
- "publish:model": { path: "./commands/publish.js", exportName: "publish" },
94
- "publish:controller": { path: "./commands/publish.js", exportName: "publish" },
95
- "publish:middleware": { path: "./commands/publish.js", exportName: "publish" },
96
- "publish:action": { path: "./commands/publish.js", exportName: "publish" },
97
- "publish:core": { path: "./commands/publish.js", exportName: "publish" },
98
- "core:status": { path: "./commands/publish.js", exportName: "publish" },
99
- queue: { path: "./commands/queue.js", exportName: "queue" },
100
- release: { path: "./commands/release.js", exportName: "release" },
101
- route: { path: "./commands/route.js", exportName: "route" },
102
- saas: { path: "./commands/saas.js", exportName: "saas" },
103
- "stripe:setup": { path: "./commands/saas.js", exportName: "saas" },
104
- schedule: { path: "./commands/schedule.js", exportName: "schedule" },
105
- search: { path: "./commands/search.js", exportName: "search" },
106
- "search-engine:update": { path: "./commands/search.js", exportName: "search" },
107
- "search-engine:settings": { path: "./commands/search.js", exportName: "search" },
108
- seed: { path: "./commands/seed.js", exportName: "seed" },
109
- "seed:roles": { path: "./commands/seed.js", exportName: "seed" },
110
- "roles:seed": { path: "./commands/seed.js", exportName: "seed" },
111
- preview: { path: "./commands/serve.js", exportName: "preview" },
112
- serve: { path: "./commands/serve.js", exportName: "serve" },
113
- "serve:api": { path: "./commands/serve.js", exportName: "serveApi" },
114
- setup: { path: "./commands/setup.js", exportName: "setup" },
115
- "setup:ai": { path: "./commands/setup.js", exportName: "setup" },
116
- "setup:ssl": { path: "./commands/setup.js", exportName: "setup" },
117
- "setup:oh-my-zsh": { path: "./commands/setup.js", exportName: "setup" },
118
- "ai:setup": { path: "./commands/setup.js", exportName: "setup" },
119
- share: { path: "./commands/share.js", exportName: "share" },
120
- stack: { path: "./commands/stacks.js", exportName: "stacks" },
121
- sms: { path: "./commands/sms.js", exportName: "sms" },
122
- telemetry: { path: "./commands/telemetry.js", exportName: "telemetryCommand" },
123
- test: { path: "./commands/test.js", exportName: "test" },
124
- tinker: { path: "./commands/tinker.js", exportName: "tinker" },
125
- types: { path: "./commands/types.js", exportName: "types" },
126
- undeploy: { path: "./commands/cloud.js", exportName: "cloud" },
127
- upgrade: { path: "./commands/upgrade.js", exportName: "upgrade" },
128
- version: { path: "./commands/version.js", exportName: "version" },
129
- "protocol:conformance": { path: "./commands/protocol.js", exportName: "protocol" },
130
- "protocol:sync": { path: "./commands/protocol.js", exportName: "protocol" },
131
- "protocol:check": { path: "./commands/protocol.js", exportName: "protocol" },
132
- "protocol:manifest": { path: "./commands/protocol.js", exportName: "protocol" },
133
- "protocol:manifest:check": { path: "./commands/protocol.js", exportName: "protocol" },
134
- "protocol:release": { path: "./commands/protocol.js", exportName: "protocol" },
135
- "protocol:release:check": { path: "./commands/protocol.js", exportName: "protocol" },
136
- "protocol:drivers": { path: "./commands/protocol.js", exportName: "protocol" },
137
- "protocol:drivers:check": { path: "./commands/protocol.js", exportName: "protocol" },
138
- "protocol:drivers:test": { path: "./commands/protocol.js", exportName: "protocol" },
139
- "protocol:desktop": { path: "./commands/protocol.js", exportName: "protocol" },
140
- "protocol:desktop:check": { path: "./commands/protocol.js", exportName: "protocol" },
141
- "protocol:pantry": { path: "./commands/protocol.js", exportName: "protocol" },
142
- "protocol:pantry:check": { path: "./commands/protocol.js", exportName: "protocol" },
143
- "protocol:craft": { path: "./commands/protocol.js", exportName: "protocol" },
144
- "protocol:craft:check": { path: "./commands/protocol.js", exportName: "protocol" },
145
- "docs:buddy": { path: "./commands/docs.js", exportName: "docs" },
146
- "docs:buddy:check": { path: "./commands/docs.js", exportName: "docs" },
147
- "docs:artifacts": { path: "./commands/docs.js", exportName: "docs" },
148
- "docs:artifacts:check": { path: "./commands/docs.js", exportName: "docs" },
149
- "docs:links": { path: "./commands/docs.js", exportName: "docs" },
150
- "docs:links:check": { path: "./commands/docs.js", exportName: "docs" }
151
- }, commandGroups = {
152
- minimal: ["version", "help"],
153
- development: ["dev", "build", "test", "lint"],
154
- database: ["migrate", "seed", "fresh"],
155
- scaffolding: ["make", "generate"],
156
- deployment: ["deploy", "release", "cloud"],
157
- info: ["about", "doctor", "list"]
158
- }, loadedRegistrars = new WeakMap;
159
- function loaderKey(loader) {
160
- return `${loader.path}#${loader.exportName}`;
161
- }
162
- export function markLoaded(buddy, commandName) {
163
- const loader = commandRegistry[commandName];
164
- if (!loader)
165
- return;
166
- let set = loadedRegistrars.get(buddy);
167
- if (!set) {
168
- set = new Set;
169
- loadedRegistrars.set(buddy, set);
170
- }
171
- set.add(loaderKey(loader));
172
- }
173
- export async function loadCommand(commandName, buddy) {
174
- const loader = commandRegistry[commandName];
175
- if (!loader)
176
- return !1;
177
- let set = loadedRegistrars.get(buddy);
178
- if (!set) {
179
- set = new Set;
180
- loadedRegistrars.set(buddy, set);
181
- }
182
- const key = loaderKey(loader);
183
- if (set.has(key))
184
- return !0;
185
- set.add(key);
186
- try {
187
- const commandFunction = (await import(loader.path))[loader.exportName];
188
- if (typeof commandFunction === "function") {
189
- commandFunction(buddy);
190
- return !0;
191
- } else
192
- return !1;
193
- } catch {
194
- return !1;
195
- }
196
- }
197
- export async function loadCommands(commandNames, buddy) {
198
- const timeout = (ms) => new Promise((_, reject) => setTimeout(() => reject(Error("timeout")), ms)), seen = new Set, unique = [];
199
- for (const name of commandNames) {
200
- const loader = commandRegistry[name], key = loader ? `${loader.path}#${loader.exportName}` : `name:${name}`;
201
- if (seen.has(key))
202
- continue;
203
- seen.add(key);
204
- unique.push(name);
205
- }
206
- await Promise.all(unique.map(async (name) => {
207
- try {
208
- await Promise.race([
209
- loadCommand(name, buddy),
210
- timeout(5000)
211
- ]);
212
- } catch {}
213
- }));
214
- }
215
- export async function loadCommandGroup(groupName, buddy) {
216
- const commands = commandGroups[groupName];
217
- if (commands)
218
- await loadCommands(commands, buddy);
219
- }
220
- export async function loadAllCommands(buddy) {
221
- const allCommands = Object.keys(commandRegistry);
222
- await loadCommands(allCommands, buddy);
223
- }
224
- export function getCommandNames() {
225
- return Object.keys(commandRegistry);
226
- }
227
- export function getCommandsToLoad(args) {
228
- const requestedCommand = args[0], isVersionFlag = requestedCommand === "--version" || requestedCommand === "-v", isHelpFlag = requestedCommand === "--help" || requestedCommand === "-h", isHelpWord = requestedCommand === "help";
229
- if (isVersionFlag)
230
- return ["version"];
231
- if (!requestedCommand || isHelpFlag || isHelpWord)
232
- return Object.keys(commandRegistry);
233
- const baseCommand = requestedCommand.split(":")[0];
234
- if (baseCommand === "list")
235
- return ["list", ...Object.keys(commandRegistry).filter((k) => k !== "list")];
236
- if (commandRegistry[requestedCommand])
237
- return [requestedCommand];
238
- if (commandRegistry[baseCommand])
239
- return [baseCommand];
240
- return Object.keys(commandRegistry);
241
- }
1
+ const commandRegistry={about:{path:"./commands/about.js",exportName:"about"},add:{path:"./commands/add.js",exportName:"add"},"ai:context":{path:"./commands/ai-context.js",exportName:"aiContext"},auth:{path:"./commands/auth.js",exportName:"auth"},build:{path:"./commands/build.js",exportName:"build"},cd:{path:"./commands/cd.js",exportName:"cd"},changelog:{path:"./commands/changelog.js",exportName:"changelog"},clean:{path:"./commands/clean.js",exportName:"clean"},cloud:{path:"./commands/cloud.js",exportName:"cloud"},commit:{path:"./commands/commit.js",exportName:"commit"},completion:{path:"./commands/completion.js",exportName:"completion"},"config:migrate":{path:"./commands/config-migrate.js",exportName:"configMigrate"},configure:{path:"./commands/configure.js",exportName:"configure"},create:{path:"./commands/create.js",exportName:"create"},new:{path:"./commands/create.js",exportName:"create"},deploy:{path:"./commands/deploy.js",exportName:"deploy"},dev:{path:"./commands/dev.js",exportName:"dev"},"desktop:apple:doctor":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:csr":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:init":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:package":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:provision":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:publish":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},dns:{path:"./commands/dns.js",exportName:"dns"},"dns:pull":{path:"./commands/dns.js",exportName:"dns"},"dns:diff":{path:"./commands/dns.js",exportName:"dns"},"dns:sync":{path:"./commands/dns.js",exportName:"dns"},doctor:{path:"./commands/doctor.js",exportName:"doctor"},domains:{path:"./commands/domains.js",exportName:"domains"},email:{path:"./commands/email.js",exportName:"email"},env:{path:"./commands/env.js",exportName:"env"},"extension:init":{path:"./commands/extension.js",exportName:"extension"},"extension:build":{path:"./commands/extension.js",exportName:"extension"},"extension:package":{path:"./commands/extension.js",exportName:"extension"},"extension:chrome:publish":{path:"./commands/extension.js",exportName:"extension"},"extension:chrome:status":{path:"./commands/extension.js",exportName:"extension"},"extension:firefox:publish":{path:"./commands/extension.js",exportName:"extension"},"extension:safari:init":{path:"./commands/extension.js",exportName:"extension"},"extension:safari:provision":{path:"./commands/extension.js",exportName:"extension"},"extension:safari:app":{path:"./commands/extension.js",exportName:"extension"},"extension:safari:publish":{path:"./commands/extension.js",exportName:"extension"},"dashboard:install":{path:"./commands/features.js",exportName:"features"},"dashboard:uninstall":{path:"./commands/features.js",exportName:"features"},"commerce:install":{path:"./commands/features.js",exportName:"features"},"commerce:uninstall":{path:"./commands/features.js",exportName:"features"},"cms:install":{path:"./commands/features.js",exportName:"features"},"cms:uninstall":{path:"./commands/features.js",exportName:"features"},"marketing:install":{path:"./commands/features.js",exportName:"features"},"marketing:uninstall":{path:"./commands/features.js",exportName:"features"},"monitoring:install":{path:"./commands/features.js",exportName:"features"},"monitoring:uninstall":{path:"./commands/features.js",exportName:"features"},"realtime:install":{path:"./commands/features.js",exportName:"features"},"realtime:uninstall":{path:"./commands/features.js",exportName:"features"},"queue:install":{path:"./commands/features.js",exportName:"features"},"queue:uninstall":{path:"./commands/features.js",exportName:"features"},fresh:{path:"./commands/fresh.js",exportName:"fresh"},generate:{path:"./commands/generate.js",exportName:"generate"},http:{path:"./commands/http.js",exportName:"http"},install:{path:"./commands/install.js",exportName:"install"},key:{path:"./commands/key.js",exportName:"key"},lint:{path:"./commands/lint.js",exportName:"lint"},format:{path:"./commands/lint.js",exportName:"lint"},"format:check":{path:"./commands/lint.js",exportName:"lint"},list:{path:"./commands/list.js",exportName:"list"},mail:{path:"./commands/mail.js",exportName:"mailCommands"},"mail:preview":{path:"./commands/mail.js",exportName:"mailCommands"},maintenance:{path:"./commands/maintenance.js",exportName:"maintenance"},down:{path:"./commands/maintenance.js",exportName:"maintenance"},up:{path:"./commands/maintenance.js",exportName:"maintenance"},status:{path:"./commands/maintenance.js",exportName:"maintenance"},"coming-soon":{path:"./commands/maintenance.js",exportName:"maintenance"},"coming-soon:status":{path:"./commands/maintenance.js",exportName:"maintenance"},launch:{path:"./commands/maintenance.js",exportName:"maintenance"},make:{path:"./commands/make.js",exportName:"make"},"scaffold:crud":{path:"./commands/make.js",exportName:"make"},migrate:{path:"./commands/migrate.js",exportName:"migrate"},"migrate:fresh":{path:"./commands/migrate.js",exportName:"migrate"},"migrate:switch":{path:"./commands/migrate.js",exportName:"migrate"},"migrate:dns":{path:"./commands/migrate.js",exportName:"migrate"},"migrate:project":{path:"./commands/migrate-project.js",exportName:"migrateProject"},outdated:{path:"./commands/outdated.js",exportName:"outdated"},package:{path:"./commands/package.js",exportName:"packageCommands"},phone:{path:"./commands/phone.js",exportName:"phone"},ports:{path:"./commands/ports.js",exportName:"ports"},"link:core":{path:"./commands/link.js",exportName:"link"},"user:add":{path:"./commands/user.js",exportName:"user"},"user:list":{path:"./commands/user.js",exportName:"user"},"unlink:core":{path:"./commands/link.js",exportName:"link"},prepublish:{path:"./commands/prepublish.js",exportName:"prepublish"},projects:{path:"./commands/projects.js",exportName:"projects"},publish:{path:"./commands/publish.js",exportName:"publish"},"publish:model":{path:"./commands/publish.js",exportName:"publish"},"publish:controller":{path:"./commands/publish.js",exportName:"publish"},"publish:middleware":{path:"./commands/publish.js",exportName:"publish"},"publish:action":{path:"./commands/publish.js",exportName:"publish"},"publish:core":{path:"./commands/publish.js",exportName:"publish"},"core:status":{path:"./commands/publish.js",exportName:"publish"},queue:{path:"./commands/queue.js",exportName:"queue"},release:{path:"./commands/release.js",exportName:"release"},route:{path:"./commands/route.js",exportName:"route"},saas:{path:"./commands/saas.js",exportName:"saas"},"stripe:setup":{path:"./commands/saas.js",exportName:"saas"},schedule:{path:"./commands/schedule.js",exportName:"schedule"},search:{path:"./commands/search.js",exportName:"search"},"search-engine:update":{path:"./commands/search.js",exportName:"search"},"search-engine:settings":{path:"./commands/search.js",exportName:"search"},seed:{path:"./commands/seed.js",exportName:"seed"},"seed:roles":{path:"./commands/seed.js",exportName:"seed"},"roles:seed":{path:"./commands/seed.js",exportName:"seed"},preview:{path:"./commands/serve.js",exportName:"preview"},serve:{path:"./commands/serve.js",exportName:"serve"},"serve:api":{path:"./commands/serve.js",exportName:"serveApi"},setup:{path:"./commands/setup.js",exportName:"setup"},"setup:ai":{path:"./commands/setup.js",exportName:"setup"},"setup:ssl":{path:"./commands/setup.js",exportName:"setup"},"setup:oh-my-zsh":{path:"./commands/setup.js",exportName:"setup"},"ai:setup":{path:"./commands/setup.js",exportName:"setup"},share:{path:"./commands/share.js",exportName:"share"},stack:{path:"./commands/stacks.js",exportName:"stacks"},sms:{path:"./commands/sms.js",exportName:"sms"},telemetry:{path:"./commands/telemetry.js",exportName:"telemetryCommand"},test:{path:"./commands/test.js",exportName:"test"},tinker:{path:"./commands/tinker.js",exportName:"tinker"},types:{path:"./commands/types.js",exportName:"types"},undeploy:{path:"./commands/cloud.js",exportName:"cloud"},upgrade:{path:"./commands/upgrade.js",exportName:"upgrade"},version:{path:"./commands/version.js",exportName:"version"},"protocol:conformance":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:sync":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:check":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:manifest":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:manifest:check":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:release":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:release:check":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:drivers":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:drivers:check":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:drivers:test":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:desktop":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:desktop:check":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:pantry":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:pantry:check":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:craft":{path:"./commands/protocol.js",exportName:"protocol"},"protocol:craft:check":{path:"./commands/protocol.js",exportName:"protocol"},"docs:buddy":{path:"./commands/docs.js",exportName:"docs"},"docs:buddy:check":{path:"./commands/docs.js",exportName:"docs"},"docs:artifacts":{path:"./commands/docs.js",exportName:"docs"},"docs:artifacts:check":{path:"./commands/docs.js",exportName:"docs"},"docs:links":{path:"./commands/docs.js",exportName:"docs"},"docs:links:check":{path:"./commands/docs.js",exportName:"docs"}},commandGroups={minimal:["version","help"],development:["dev","build","test","lint"],database:["migrate","seed","fresh"],scaffolding:["make","generate"],deployment:["deploy","release","cloud"],info:["about","doctor","list"]},loadedRegistrars=new WeakMap;function loaderKey(loader){return`${loader.path}#${loader.exportName}`}export function markLoaded(buddy,commandName){const loader=commandRegistry[commandName];if(!loader)return;let set=loadedRegistrars.get(buddy);if(!set){set=new Set;loadedRegistrars.set(buddy,set)}set.add(loaderKey(loader))}export async function loadCommand(commandName,buddy){const loader=commandRegistry[commandName];if(!loader)return!1;let set=loadedRegistrars.get(buddy);if(!set){set=new Set;loadedRegistrars.set(buddy,set)}const key=loaderKey(loader);if(set.has(key))return!0;set.add(key);try{const commandFunction=(await import(loader.path))[loader.exportName];if(typeof commandFunction==="function"){commandFunction(buddy);return!0}else return!1}catch{return!1}}export async function loadCommands(commandNames,buddy){const timeout=(ms)=>new Promise((_,reject)=>setTimeout(()=>reject(Error("timeout")),ms)),seen=new Set,unique=[];for(const name of commandNames){const loader=commandRegistry[name],key=loader?`${loader.path}#${loader.exportName}`:`name:${name}`;if(seen.has(key))continue;seen.add(key);unique.push(name)}await Promise.all(unique.map(async(name)=>{try{await Promise.race([loadCommand(name,buddy),timeout(5000)])}catch{}}))}export async function loadCommandGroup(groupName,buddy){const commands=commandGroups[groupName];if(commands)await loadCommands(commands,buddy)}export async function loadAllCommands(buddy){const allCommands=Object.keys(commandRegistry);await loadCommands(allCommands,buddy)}export function getCommandNames(){return Object.keys(commandRegistry)}export function getCommandsToLoad(args){const requestedCommand=args[0],isVersionFlag=requestedCommand==="--version"||requestedCommand==="-v",isHelpFlag=requestedCommand==="--help"||requestedCommand==="-h",isHelpWord=requestedCommand==="help";if(isVersionFlag)return["version"];if(!requestedCommand||isHelpFlag||isHelpWord)return Object.keys(commandRegistry);const baseCommand=requestedCommand.split(":")[0];if(baseCommand==="list")return["list",...Object.keys(commandRegistry).filter((k)=>k!=="list")];if(commandRegistry[requestedCommand])return[requestedCommand];if(commandRegistry[baseCommand])return[baseCommand];return Object.keys(commandRegistry)}
@@ -1,62 +1,2 @@
1
- import { laravelDriver } from "./laravel";
2
- import { railsDriver } from "./rails";
3
- export const DRIVERS = {
4
- laravel: laravelDriver,
5
- rails: railsDriver
6
- };
7
- export async function runMigrator(req) {
8
- const driver = DRIVERS[req.from];
9
- if (!driver)
10
- throw Error(`Unknown source framework: ${req.from}. Supported: ${Object.keys(DRIVERS).join(", ")}`);
11
- const startedAt = new Date().toISOString(), entries = await driver.migrate(req), finishedAt = new Date().toISOString();
12
- return {
13
- source: req.source,
14
- target: req.target,
15
- from: req.from,
16
- startedAt,
17
- finishedAt,
18
- entries
19
- };
20
- }
21
- export function renderReport(report) {
22
- const lines = [];
23
- lines.push(`# Migration report \u2014 ${report.from} \u2192 Stacks`);
24
- lines.push("");
25
- lines.push(`- **Source**: \`${report.source}\``);
26
- lines.push(`- **Target**: \`${report.target}\``);
27
- lines.push(`- **Started**: ${report.startedAt}`);
28
- lines.push(`- **Finished**: ${report.finishedAt}`);
29
- lines.push("");
30
- const groups = groupEntriesByStatus(report.entries);
31
- for (const [status, label] of [
32
- ["translated", "Translated"],
33
- ["copied", "Copied verbatim"],
34
- ["skipped", "Skipped (hand-port required)"],
35
- ["failed", "Failed"]
36
- ]) {
37
- const group = groups[status] ?? [];
38
- if (group.length === 0)
39
- continue;
40
- lines.push(`## ${label} (${group.length})`);
41
- lines.push("");
42
- for (const e of group) {
43
- const arrow = e.target ? ` \u2192 \`${e.target}\`` : "", note = e.note ? ` \u2014 ${e.note}` : "";
44
- lines.push(`- \`${e.source}\`${arrow}${note}`);
45
- }
46
- lines.push("");
47
- }
48
- lines.push("---");
49
- lines.push("");
50
- lines.push("Re-run `./buddy migrate:project <name> --from=" + report.from + "` after fixing the source project to refresh emitted files. Translated outputs are overwritten; skipped entries are not.");
51
- return lines.join(`
52
- `);
53
- }
54
- function groupEntriesByStatus(entries) {
55
- const out = {};
56
- for (const e of entries) {
57
- if (!out[e.status])
58
- out[e.status] = [];
59
- out[e.status].push(e);
60
- }
61
- return out;
62
- }
1
+ import{laravelDriver}from"./laravel";import{railsDriver}from"./rails";export const DRIVERS={laravel:laravelDriver,rails:railsDriver};export async function runMigrator(req){const driver=DRIVERS[req.from];if(!driver)throw Error(`Unknown source framework: ${req.from}. Supported: ${Object.keys(DRIVERS).join(", ")}`);const startedAt=new Date().toISOString(),entries=await driver.migrate(req),finishedAt=new Date().toISOString();return{source:req.source,target:req.target,from:req.from,startedAt,finishedAt,entries}}export function renderReport(report){const lines=[];lines.push(`# Migration report \u2014 ${report.from} \u2192 Stacks`);lines.push("");lines.push(`- **Source**: \`${report.source}\``);lines.push(`- **Target**: \`${report.target}\``);lines.push(`- **Started**: ${report.startedAt}`);lines.push(`- **Finished**: ${report.finishedAt}`);lines.push("");const groups=groupEntriesByStatus(report.entries);for(const[status,label]of[["translated","Translated"],["copied","Copied verbatim"],["skipped","Skipped (hand-port required)"],["failed","Failed"]]){const group=groups[status]??[];if(group.length===0)continue;lines.push(`## ${label} (${group.length})`);lines.push("");for(const e of group){const arrow=e.target?` \u2192 \`${e.target}\``:"",note=e.note?` \u2014 ${e.note}`:"";lines.push(`- \`${e.source}\`${arrow}${note}`)}lines.push("")}lines.push("---");lines.push("");lines.push("Re-run `./buddy migrate:project <name> --from="+report.from+"` after fixing the source project to refresh emitted files. Translated outputs are overwritten; skipped entries are not.");return lines.join(`
2
+ `)}function groupEntriesByStatus(entries){const out={};for(const e of entries){if(!out[e.status])out[e.status]=[];out[e.status].push(e)}return out}
@@ -1,148 +1 @@
1
- import { existsSync, readdirSync } from "node:fs";
2
- import { copyFile, mkdir, readFile, writeFile } from "node:fs/promises";
3
- import { basename, join } from "node:path";
4
- import { laravelFilenameToStacks, parseLaravelMigration } from "./migrations";
5
- import { parseLaravelModel } from "./models";
6
- export const laravelDriver = {
7
- name: "laravel",
8
- async migrate(req) {
9
- const entries = [];
10
- entries.push(...await migrateEnv(req));
11
- entries.push(...await migrateMigrations(req));
12
- entries.push(...await migrateModels(req));
13
- entries.push(...summariseDeferred(req));
14
- return entries;
15
- }
16
- };
17
- async function migrateEnv(req) {
18
- const out = [];
19
- for (const file of [".env", ".env.example"]) {
20
- const sourcePath = join(req.source, file);
21
- if (!existsSync(sourcePath))
22
- continue;
23
- const targetPath = join(req.target, file);
24
- if (!req.dryRun) {
25
- await mkdir(req.target, { recursive: !0 });
26
- await copyFile(sourcePath, targetPath);
27
- }
28
- out.push({
29
- source: file,
30
- target: file,
31
- status: "copied",
32
- note: "Laravel-specific keys (BROADCAST_DRIVER, FILESYSTEM_DISK names) may need renaming; Stacks reads APP_*/DB_*/MAIL_* keys as-is."
33
- });
34
- }
35
- return out;
36
- }
37
- async function migrateMigrations(req) {
38
- const dir = join(req.source, "database", "migrations");
39
- if (!existsSync(dir))
40
- return [];
41
- const files = readdirSync(dir).filter((f) => f.endsWith(".php")).sort(), targetDir = join(req.target, "database", "migrations");
42
- if (!req.dryRun)
43
- await mkdir(targetDir, { recursive: !0 });
44
- const out = [];
45
- for (let i = 0;i < files.length; i++) {
46
- const file = files[i], rel = `database/migrations/${file}`;
47
- try {
48
- const body = await readFile(join(dir, file), "utf8"), parsed = parseLaravelMigration(body);
49
- if (!parsed) {
50
- out.push({
51
- source: rel,
52
- target: "",
53
- status: "skipped",
54
- note: "No `Schema::create(...)` block found (likely an alter / drop / data-only migration)."
55
- });
56
- continue;
57
- }
58
- const sequence = i + 1, outRel = `database/migrations/${laravelFilenameToStacks(file, sequence, parsed.table)}`;
59
- if (!req.dryRun)
60
- await writeFile(join(req.target, outRel), parsed.sql);
61
- const skippedNote = parsed.skipped.length > 0 ? ` Skipped ${parsed.skipped.length} line(s) inside the create block \u2014 hand-port from the source migration.` : "";
62
- out.push({
63
- source: rel,
64
- target: outRel,
65
- status: "translated",
66
- note: `CREATE TABLE \`${parsed.table}\` emitted.${skippedNote}`
67
- });
68
- } catch (err) {
69
- out.push({
70
- source: rel,
71
- target: "",
72
- status: "failed",
73
- note: `Parse error: ${err instanceof Error ? err.message : String(err)}`
74
- });
75
- }
76
- }
77
- return out;
78
- }
79
- async function migrateModels(req) {
80
- const dir = join(req.source, "app", "Models");
81
- if (!existsSync(dir))
82
- return [];
83
- const files = readdirSync(dir).filter((f) => f.endsWith(".php")), targetDir = join(req.target, "app", "Models");
84
- if (!req.dryRun)
85
- await mkdir(targetDir, { recursive: !0 });
86
- const out = [];
87
- for (const file of files) {
88
- const rel = `app/Models/${file}`;
89
- try {
90
- const body = await readFile(join(dir, file), "utf8"), parsed = parseLaravelModel(body);
91
- if (!parsed) {
92
- out.push({
93
- source: rel,
94
- target: "",
95
- status: "skipped",
96
- note: "No class declaration found."
97
- });
98
- continue;
99
- }
100
- const outRel = `app/Models/${`${parsed.className}.ts`}`;
101
- if (!req.dryRun)
102
- await writeFile(join(req.target, outRel), parsed.tsSource);
103
- const notes = [
104
- `Attributes: ${parsed.fillable.length} fillable, ${Object.keys(parsed.casts).length} cast`,
105
- parsed.relationships.length > 0 ? `Relationships: ${parsed.relationships.map((r) => `${r.name}(${r.kind})`).join(", ")}` : null,
106
- ...parsed.notes
107
- ].filter(Boolean).join(" | ");
108
- out.push({
109
- source: rel,
110
- target: outRel,
111
- status: "translated",
112
- note: notes || `Model ${parsed.className} emitted.`
113
- });
114
- } catch (err) {
115
- out.push({
116
- source: rel,
117
- target: "",
118
- status: "failed",
119
- note: `Parse error: ${err instanceof Error ? err.message : String(err)}`
120
- });
121
- }
122
- }
123
- return out;
124
- }
125
- const DEFERRED_SURFACES = [
126
- { path: "routes", note: "routes/web.php + routes/api.php \u2014 port to routes/web.ts + routes/api.ts using the Stacks router DSL." },
127
- { path: "app/Http/Controllers", note: "Controllers \u2192 Stacks Actions in app/Actions/. Each controller method maps to one Action file." },
128
- { path: "resources/views", note: "Blade templates \u2192 stx components in resources/views/." },
129
- { path: "database/seeders", note: "Seeders \u2192 database/seeders/*.ts using Stacks SeederContract." },
130
- { path: "app/Console/Commands", note: "Artisan commands \u2192 app/Commands/*.ts in your Stacks project." },
131
- { path: "app/Jobs", note: "Queue jobs \u2192 app/Jobs/*.ts; pair with config/queue.ts driver settings." },
132
- { path: "composer.json", note: "Dependency map \u2014 Laravel packages don't translate 1:1; the Stacks docs cover the closest @stacksjs/* equivalents." }
133
- ];
134
- function summariseDeferred(req) {
135
- const out = [];
136
- for (const surface of DEFERRED_SURFACES) {
137
- const sourcePath = join(req.source, surface.path);
138
- if (!existsSync(sourcePath))
139
- continue;
140
- out.push({
141
- source: surface.path,
142
- target: "",
143
- status: "skipped",
144
- note: surface.note
145
- });
146
- }
147
- return out;
148
- }
1
+ import{existsSync,readdirSync}from"node:fs";import{copyFile,mkdir,readFile,writeFile}from"node:fs/promises";import{basename,join}from"node:path";import{laravelFilenameToStacks,parseLaravelMigration}from"./migrations";import{parseLaravelModel}from"./models";export const laravelDriver={name:"laravel",async migrate(req){const entries=[];entries.push(...await migrateEnv(req));entries.push(...await migrateMigrations(req));entries.push(...await migrateModels(req));entries.push(...summariseDeferred(req));return entries}};async function migrateEnv(req){const out=[];for(const file of[".env",".env.example"]){const sourcePath=join(req.source,file);if(!existsSync(sourcePath))continue;const targetPath=join(req.target,file);if(!req.dryRun){await mkdir(req.target,{recursive:!0});await copyFile(sourcePath,targetPath)}out.push({source:file,target:file,status:"copied",note:"Laravel-specific keys (BROADCAST_DRIVER, FILESYSTEM_DISK names) may need renaming; Stacks reads APP_*/DB_*/MAIL_* keys as-is."})}return out}async function migrateMigrations(req){const dir=join(req.source,"database","migrations");if(!existsSync(dir))return[];const files=readdirSync(dir).filter((f)=>f.endsWith(".php")).sort(),targetDir=join(req.target,"database","migrations");if(!req.dryRun)await mkdir(targetDir,{recursive:!0});const out=[];for(let i=0;i<files.length;i++){const file=files[i],rel=`database/migrations/${file}`;try{const body=await readFile(join(dir,file),"utf8"),parsed=parseLaravelMigration(body);if(!parsed){out.push({source:rel,target:"",status:"skipped",note:"No `Schema::create(...)` block found (likely an alter / drop / data-only migration)."});continue}const sequence=i+1,outRel=`database/migrations/${laravelFilenameToStacks(file,sequence,parsed.table)}`;if(!req.dryRun)await writeFile(join(req.target,outRel),parsed.sql);const skippedNote=parsed.skipped.length>0?` Skipped ${parsed.skipped.length} line(s) inside the create block \u2014 hand-port from the source migration.`:"";out.push({source:rel,target:outRel,status:"translated",note:`CREATE TABLE \`${parsed.table}\` emitted.${skippedNote}`})}catch(err){out.push({source:rel,target:"",status:"failed",note:`Parse error: ${err instanceof Error?err.message:String(err)}`})}}return out}async function migrateModels(req){const dir=join(req.source,"app","Models");if(!existsSync(dir))return[];const files=readdirSync(dir).filter((f)=>f.endsWith(".php")),targetDir=join(req.target,"app","Models");if(!req.dryRun)await mkdir(targetDir,{recursive:!0});const out=[];for(const file of files){const rel=`app/Models/${file}`;try{const body=await readFile(join(dir,file),"utf8"),parsed=parseLaravelModel(body);if(!parsed){out.push({source:rel,target:"",status:"skipped",note:"No class declaration found."});continue}const outRel=`app/Models/${`${parsed.className}.ts`}`;if(!req.dryRun)await writeFile(join(req.target,outRel),parsed.tsSource);const notes=[`Attributes: ${parsed.fillable.length} fillable, ${Object.keys(parsed.casts).length} cast`,parsed.relationships.length>0?`Relationships: ${parsed.relationships.map((r)=>`${r.name}(${r.kind})`).join(", ")}`:null,...parsed.notes].filter(Boolean).join(" | ");out.push({source:rel,target:outRel,status:"translated",note:notes||`Model ${parsed.className} emitted.`})}catch(err){out.push({source:rel,target:"",status:"failed",note:`Parse error: ${err instanceof Error?err.message:String(err)}`})}}return out}const DEFERRED_SURFACES=[{path:"routes",note:"routes/web.php + routes/api.php \u2014 port to routes/web.ts + routes/api.ts using the Stacks router DSL."},{path:"app/Http/Controllers",note:"Controllers \u2192 Stacks Actions in app/Actions/. Each controller method maps to one Action file."},{path:"resources/views",note:"Blade templates \u2192 stx components in resources/views/."},{path:"database/seeders",note:"Seeders \u2192 database/seeders/*.ts using Stacks SeederContract."},{path:"app/Console/Commands",note:"Artisan commands \u2192 app/Commands/*.ts in your Stacks project."},{path:"app/Jobs",note:"Queue jobs \u2192 app/Jobs/*.ts; pair with config/queue.ts driver settings."},{path:"composer.json",note:"Dependency map \u2014 Laravel packages don't translate 1:1; the Stacks docs cover the closest @stacksjs/* equivalents."}];function summariseDeferred(req){const out=[];for(const surface of DEFERRED_SURFACES){const sourcePath=join(req.source,surface.path);if(!existsSync(sourcePath))continue;out.push({source:surface.path,target:"",status:"skipped",note:surface.note})}return out}