everything-dev 1.12.4 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/dist/app.cjs +17 -5
  2. package/dist/app.cjs.map +1 -1
  3. package/dist/app.mjs +17 -5
  4. package/dist/app.mjs.map +1 -1
  5. package/dist/cli/init.cjs +151 -74
  6. package/dist/cli/init.cjs.map +1 -1
  7. package/dist/cli/init.d.cts +1 -1
  8. package/dist/cli/init.d.cts.map +1 -1
  9. package/dist/cli/init.d.mts +1 -1
  10. package/dist/cli/init.d.mts.map +1 -1
  11. package/dist/cli/init.mjs +152 -75
  12. package/dist/cli/init.mjs.map +1 -1
  13. package/dist/cli/prompts.cjs +3 -3
  14. package/dist/cli/prompts.cjs.map +1 -1
  15. package/dist/cli/prompts.mjs +3 -3
  16. package/dist/cli/prompts.mjs.map +1 -1
  17. package/dist/cli/status.cjs +22 -0
  18. package/dist/cli/status.cjs.map +1 -1
  19. package/dist/cli/status.mjs +22 -0
  20. package/dist/cli/status.mjs.map +1 -1
  21. package/dist/cli/sync.cjs +15 -56
  22. package/dist/cli/sync.cjs.map +1 -1
  23. package/dist/cli/sync.mjs +15 -56
  24. package/dist/cli/sync.mjs.map +1 -1
  25. package/dist/cli/upgrade.cjs +59 -5
  26. package/dist/cli/upgrade.cjs.map +1 -1
  27. package/dist/cli/upgrade.mjs +59 -5
  28. package/dist/cli/upgrade.mjs.map +1 -1
  29. package/dist/cli.cjs +1 -1
  30. package/dist/cli.cjs.map +1 -1
  31. package/dist/cli.mjs +1 -1
  32. package/dist/cli.mjs.map +1 -1
  33. package/dist/config.cjs +206 -69
  34. package/dist/config.cjs.map +1 -1
  35. package/dist/config.d.cts +13 -6
  36. package/dist/config.d.cts.map +1 -1
  37. package/dist/config.d.mts +13 -6
  38. package/dist/config.d.mts.map +1 -1
  39. package/dist/config.mjs +201 -71
  40. package/dist/config.mjs.map +1 -1
  41. package/dist/contract.d.cts +106 -10
  42. package/dist/contract.d.cts.map +1 -1
  43. package/dist/contract.d.mts +106 -10
  44. package/dist/contract.d.mts.map +1 -1
  45. package/dist/host.cjs +34 -1
  46. package/dist/host.cjs.map +1 -1
  47. package/dist/host.d.cts.map +1 -1
  48. package/dist/host.d.mts.map +1 -1
  49. package/dist/host.mjs +34 -1
  50. package/dist/host.mjs.map +1 -1
  51. package/dist/index.cjs +16 -0
  52. package/dist/index.d.cts +5 -3
  53. package/dist/index.d.mts +5 -3
  54. package/dist/index.mjs +5 -3
  55. package/dist/internal/manifest-normalizer.cjs +14 -1
  56. package/dist/internal/manifest-normalizer.cjs.map +1 -1
  57. package/dist/internal/manifest-normalizer.mjs +14 -1
  58. package/dist/internal/manifest-normalizer.mjs.map +1 -1
  59. package/dist/merge.cjs +113 -0
  60. package/dist/merge.cjs.map +1 -0
  61. package/dist/merge.d.cts +7 -0
  62. package/dist/merge.d.cts.map +1 -0
  63. package/dist/merge.d.mts +7 -0
  64. package/dist/merge.d.mts.map +1 -0
  65. package/dist/merge.mjs +107 -0
  66. package/dist/merge.mjs.map +1 -0
  67. package/dist/orchestrator.d.cts +1 -1
  68. package/dist/orchestrator.d.mts +1 -1
  69. package/dist/plugin.cjs +117 -105
  70. package/dist/plugin.cjs.map +1 -1
  71. package/dist/plugin.d.cts +115 -9
  72. package/dist/plugin.d.cts.map +1 -1
  73. package/dist/plugin.d.mts +115 -9
  74. package/dist/plugin.d.mts.map +1 -1
  75. package/dist/plugin.mjs +117 -105
  76. package/dist/plugin.mjs.map +1 -1
  77. package/dist/service-descriptor.cjs +21 -0
  78. package/dist/service-descriptor.cjs.map +1 -1
  79. package/dist/service-descriptor.d.cts +23 -1
  80. package/dist/service-descriptor.d.cts.map +1 -1
  81. package/dist/service-descriptor.d.mts +23 -1
  82. package/dist/service-descriptor.d.mts.map +1 -1
  83. package/dist/service-descriptor.mjs +21 -0
  84. package/dist/service-descriptor.mjs.map +1 -1
  85. package/dist/shared.cjs +24 -2
  86. package/dist/shared.cjs.map +1 -1
  87. package/dist/shared.d.cts +3 -0
  88. package/dist/shared.d.cts.map +1 -1
  89. package/dist/shared.d.mts +3 -0
  90. package/dist/shared.d.mts.map +1 -1
  91. package/dist/shared.mjs +25 -3
  92. package/dist/shared.mjs.map +1 -1
  93. package/dist/sidebar.cjs +124 -0
  94. package/dist/sidebar.cjs.map +1 -0
  95. package/dist/sidebar.d.cts +8 -0
  96. package/dist/sidebar.d.cts.map +1 -0
  97. package/dist/sidebar.d.mts +8 -0
  98. package/dist/sidebar.d.mts.map +1 -0
  99. package/dist/sidebar.mjs +122 -0
  100. package/dist/sidebar.mjs.map +1 -0
  101. package/dist/types.cjs +104 -10
  102. package/dist/types.cjs.map +1 -1
  103. package/dist/types.d.cts +256 -29
  104. package/dist/types.d.cts.map +1 -1
  105. package/dist/types.d.mts +256 -29
  106. package/dist/types.d.mts.map +1 -1
  107. package/dist/types.mjs +100 -11
  108. package/dist/types.mjs.map +1 -1
  109. package/dist/utils/path-match.cjs +18 -0
  110. package/dist/utils/path-match.cjs.map +1 -0
  111. package/dist/utils/path-match.mjs +17 -0
  112. package/dist/utils/path-match.mjs.map +1 -0
  113. package/dist/utils/save-config.cjs +19 -0
  114. package/dist/utils/save-config.cjs.map +1 -0
  115. package/dist/utils/save-config.mjs +18 -0
  116. package/dist/utils/save-config.mjs.map +1 -0
  117. package/package.json +6 -6
  118. package/skills/dev-workflow/SKILL.md +8 -0
  119. package/skills/extends-config/SKILL.md +132 -0
  120. package/skills/init-upgrade/SKILL.md +128 -0
  121. package/skills/publish-sync/SKILL.md +30 -0
  122. package/src/app.ts +15 -5
  123. package/src/cli/init.ts +207 -108
  124. package/src/cli/prompts.ts +2 -2
  125. package/src/cli/status.ts +20 -0
  126. package/src/cli/sync.ts +27 -96
  127. package/src/cli/upgrade.ts +65 -3
  128. package/src/cli.ts +1 -1
  129. package/src/config.ts +306 -119
  130. package/src/host.ts +45 -0
  131. package/src/index.ts +1 -0
  132. package/src/internal/manifest-normalizer.ts +16 -4
  133. package/src/merge.ts +198 -0
  134. package/src/plugin.ts +340 -318
  135. package/src/service-descriptor.ts +23 -0
  136. package/src/shared.ts +48 -5
  137. package/src/sidebar.ts +162 -0
  138. package/src/types.ts +134 -28
  139. package/src/utils/path-match.ts +16 -0
  140. package/src/utils/save-config.ts +20 -0
  141. package/cli.js +0 -10
package/src/cli/init.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  existsSync,
6
6
  lstatSync,
7
7
  mkdirSync,
8
+ mkdtempSync,
8
9
  readFileSync,
9
10
  rmSync,
10
11
  writeFileSync,
@@ -20,40 +21,12 @@ import {
20
21
  normalizePackageManifestsInTree,
21
22
  } from "../internal/manifest-normalizer";
22
23
  import type { BosConfig } from "../types";
24
+ import { isPathExcluded } from "../utils/path-match";
25
+ import { saveBosConfig } from "../utils/save-config";
23
26
  import { writeSnapshot } from "./snapshot";
24
27
 
25
28
  const require = createRequire(import.meta.url);
26
29
 
27
- const BOS_CONFIG_ORDER = [
28
- "extends",
29
- "account",
30
- "domain",
31
- "testnet",
32
- "staging",
33
- "repository",
34
- "app",
35
- "plugins",
36
- "shared",
37
- ];
38
-
39
- function rebuildOrderedConfig(config: Record<string, unknown>): Record<string, unknown> {
40
- const ordered: Record<string, unknown> = {};
41
-
42
- for (const key of BOS_CONFIG_ORDER) {
43
- if (key in config) {
44
- ordered[key] = config[key];
45
- }
46
- }
47
-
48
- for (const key of Object.keys(config)) {
49
- if (!BOS_CONFIG_ORDER.includes(key)) {
50
- ordered[key] = config[key];
51
- }
52
- }
53
-
54
- return ordered;
55
- }
56
-
57
30
  interface SourceResult {
58
31
  sourceDir: string;
59
32
  parentConfig: BosConfig;
@@ -86,6 +59,19 @@ export async function resolveSourceDir(opts: {
86
59
  return { sourceDir, parentConfig, cleanup };
87
60
  }
88
61
 
62
+ export async function readTemplatekeep(sourceDir: string): Promise<string[]> {
63
+ const keepFile = join(sourceDir, ".templatekeep");
64
+ if (!existsSync(keepFile)) {
65
+ return [];
66
+ }
67
+
68
+ const content = readFileSync(keepFile, "utf-8");
69
+ return content
70
+ .split("\n")
71
+ .map((line) => line.trim())
72
+ .filter((line) => line.length > 0 && !line.startsWith("#"));
73
+ }
74
+
89
75
  export async function fetchParentConfig(
90
76
  extendsAccount: string,
91
77
  extendsGateway: string,
@@ -161,19 +147,6 @@ function parseGitHubUrl(url: string): { owner: string; repo: string; branch: str
161
147
  return null;
162
148
  }
163
149
 
164
- export async function readTemplatekeep(sourceDir: string): Promise<string[]> {
165
- const keepFile = join(sourceDir, ".templatekeep");
166
- if (!existsSync(keepFile)) {
167
- return [];
168
- }
169
-
170
- const content = readFileSync(keepFile, "utf-8");
171
- return content
172
- .split("\n")
173
- .map((line) => line.trim())
174
- .filter((line) => line.length > 0 && !line.startsWith("#"));
175
- }
176
-
177
150
  export async function copyFilteredFiles(
178
151
  sourceDir: string,
179
152
  destination: string,
@@ -218,7 +191,7 @@ export async function copyFilteredFiles(
218
191
  const pluginName = pluginMatch[1];
219
192
  if (!(options.plugins?.includes(pluginName) ?? true)) continue;
220
193
  }
221
- if (isRouteExcluded(match, excludedRoutePatterns)) continue;
194
+ if (isPathExcluded(match, excludedRoutePatterns)) continue;
222
195
  allFiles.add(match);
223
196
  }
224
197
  }
@@ -235,7 +208,7 @@ export async function copyFilteredFiles(
235
208
  absolute: false,
236
209
  });
237
210
  for (const match of matches) {
238
- if (!isRouteExcluded(match, excludedRoutePatterns)) {
211
+ if (!isPathExcluded(match, excludedRoutePatterns)) {
239
212
  routeFiles.add(match);
240
213
  }
241
214
  }
@@ -266,19 +239,6 @@ export async function copyFilteredFiles(
266
239
  return count;
267
240
  }
268
241
 
269
- function isRouteExcluded(filePath: string, excludedPatterns: string[]): boolean {
270
- if (excludedPatterns.length === 0) return false;
271
- for (const pattern of excludedPatterns) {
272
- if (pattern.endsWith("/**")) {
273
- const prefix = pattern.slice(0, -3);
274
- if (filePath.startsWith(`${prefix}/`) || filePath === prefix) return true;
275
- } else if (filePath === pattern || filePath.startsWith(`${pattern}/`)) {
276
- return true;
277
- }
278
- }
279
- return false;
280
- }
281
-
282
242
  export async function personalizeConfig(
283
243
  destination: string,
284
244
  opts: {
@@ -334,13 +294,124 @@ export async function personalizeConfig(
334
294
  }
335
295
 
336
296
  if (isInit) {
297
+ const parentDomain = opts.extendsGateway;
298
+
337
299
  for (const pluginKey of Object.keys(plugins)) {
338
300
  const plugin = plugins[pluginKey];
339
- if (plugin && typeof plugin === "object") {
340
- const p = plugin as Record<string, unknown>;
341
- delete p.production;
342
- delete p.integrity;
301
+ let pluginObj: Record<string, unknown>;
302
+
303
+ if (typeof plugin === "string") {
304
+ pluginObj = { extends: plugin };
305
+ plugins[pluginKey] = pluginObj;
306
+ } else if (plugin && typeof plugin === "object") {
307
+ pluginObj = { ...(plugin as Record<string, unknown>) };
308
+ } else {
309
+ continue;
343
310
  }
311
+
312
+ if (
313
+ pluginObj.development &&
314
+ typeof pluginObj.development === "string" &&
315
+ pluginObj.development.startsWith("local:")
316
+ ) {
317
+ const pluginDir = join(destination, pluginObj.development.slice("local:".length));
318
+ const pluginConfigPath = join(pluginDir, "bos.config.json");
319
+
320
+ if (existsSync(pluginConfigPath)) {
321
+ try {
322
+ const pluginConfig = JSON.parse(readFileSync(pluginConfigPath, "utf-8")) as Record<
323
+ string,
324
+ unknown
325
+ >;
326
+ delete pluginConfig.extends;
327
+ if (pluginConfig.app && typeof pluginConfig.app === "object") {
328
+ const app = pluginConfig.app as Record<string, unknown>;
329
+ for (const entryKey of Object.keys(app)) {
330
+ const entry = app[entryKey];
331
+ if (entry && typeof entry === "object") {
332
+ const e = entry as Record<string, unknown>;
333
+ delete e.production;
334
+ delete e.integrity;
335
+ }
336
+ }
337
+ }
338
+ writeFileSync(pluginConfigPath, `${JSON.stringify(pluginConfig, null, 2)}\n`);
339
+ } catch {}
340
+ } else if (existsSync(pluginDir)) {
341
+ const pluginConfig: Record<string, unknown> = {};
342
+ pluginConfig.domain = `${pluginKey}.${opts.domain ?? parentDomain}`;
343
+ pluginConfig.app = { api: { development: "local:." } };
344
+
345
+ if (opts.pluginRoutes?.[pluginKey]) {
346
+ pluginConfig.routes = opts.pluginRoutes[pluginKey];
347
+ }
348
+ if (pluginObj.sidebar) {
349
+ pluginConfig.sidebar = pluginObj.sidebar;
350
+ }
351
+
352
+ mkdirSync(pluginDir, { recursive: true });
353
+ writeFileSync(pluginConfigPath, `${JSON.stringify(pluginConfig, null, 2)}\n`);
354
+ }
355
+
356
+ const cleanEntry: Record<string, unknown> = { development: pluginObj.development };
357
+ if (pluginObj.extends) {
358
+ cleanEntry.extends = pluginObj.extends;
359
+ }
360
+ if (pluginObj.secrets) {
361
+ cleanEntry.secrets = pluginObj.secrets;
362
+ }
363
+ if (pluginObj.variables) {
364
+ cleanEntry.variables = pluginObj.variables;
365
+ }
366
+ plugins[pluginKey] = cleanEntry;
367
+ } else {
368
+ delete pluginObj.production;
369
+ delete pluginObj.integrity;
370
+ delete pluginObj.sidebar;
371
+ delete pluginObj.routes;
372
+ }
373
+ }
374
+ } else {
375
+ for (const pluginKey of Object.keys(plugins)) {
376
+ const pluginDir = resolve(
377
+ destination,
378
+ (plugins[pluginKey] as Record<string, unknown>)?.development
379
+ ?.toString()
380
+ ?.slice("local:".length) ?? "",
381
+ );
382
+ const pluginConfigPath = join(pluginDir, "bos.config.json");
383
+ if (!existsSync(pluginConfigPath)) continue;
384
+
385
+ try {
386
+ const pluginConfig = JSON.parse(readFileSync(pluginConfigPath, "utf-8")) as Record<
387
+ string,
388
+ unknown
389
+ >;
390
+ let changed = false;
391
+
392
+ if ("extends" in pluginConfig) {
393
+ delete pluginConfig.extends;
394
+ changed = true;
395
+ }
396
+ if (pluginConfig.app && typeof pluginConfig.app === "object") {
397
+ const app = pluginConfig.app as Record<string, unknown>;
398
+ for (const entryKey of Object.keys(app)) {
399
+ const entry = app[entryKey];
400
+ if (entry && typeof entry === "object") {
401
+ const e = entry as Record<string, unknown>;
402
+ if ("production" in e || "integrity" in e) {
403
+ delete e.production;
404
+ delete e.integrity;
405
+ changed = true;
406
+ }
407
+ }
408
+ }
409
+ }
410
+
411
+ if (changed) {
412
+ writeFileSync(pluginConfigPath, `${JSON.stringify(pluginConfig, null, 2)}\n`);
413
+ }
414
+ } catch {}
344
415
  }
345
416
  }
346
417
 
@@ -349,7 +420,7 @@ export async function personalizeConfig(
349
420
  }
350
421
  }
351
422
 
352
- writeFileSync(configPath, `${JSON.stringify(rebuildOrderedConfig(config), null, 2)}\n`);
423
+ await saveBosConfig(destination, config);
353
424
  }
354
425
 
355
426
  const pkgPath = join(destination, "package.json");
@@ -377,14 +448,14 @@ export async function personalizeConfig(
377
448
  scripts[key] = scripts[key].replaceAll(from, to);
378
449
  }
379
450
  };
380
- rewrite("dev", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
381
- rewrite("dev:ui", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
382
- rewrite("dev:api", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
383
- rewrite("dev:proxy", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
384
- rewrite("build", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
385
- rewrite("deploy", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
386
- rewrite("publish", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
387
- rewrite("start", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
451
+ rewrite("dev", "packages/everything-dev/src/cli.ts", "node_modules/.bin/bos");
452
+ rewrite("dev:ui", "packages/everything-dev/src/cli.ts", "node_modules/.bin/bos");
453
+ rewrite("dev:api", "packages/everything-dev/src/cli.ts", "node_modules/.bin/bos");
454
+ rewrite("dev:proxy", "packages/everything-dev/src/cli.ts", "node_modules/.bin/bos");
455
+ rewrite("build", "packages/everything-dev/src/cli.ts", "node_modules/.bin/bos");
456
+ rewrite("deploy", "packages/everything-dev/src/cli.ts", "node_modules/.bin/bos");
457
+ rewrite("publish", "packages/everything-dev/src/cli.ts", "node_modules/.bin/bos");
458
+ rewrite("start", "packages/everything-dev/src/cli.ts", "node_modules/.bin/bos");
388
459
 
389
460
  scripts.postinstall = "node_modules/.bin/bos types gen || true";
390
461
  scripts["types:gen"] = "node_modules/.bin/bos types gen";
@@ -463,32 +534,71 @@ export async function personalizeConfig(
463
534
  );
464
535
  }
465
536
 
466
- const authTypesGenPath = join(destination, "ui", "src", "lib", "auth-types.gen.ts");
467
- if (!existsSync(authTypesGenPath)) {
468
- mkdirSync(dirname(authTypesGenPath), { recursive: true });
469
- writeFileSync(
470
- authTypesGenPath,
471
- `import type { Auth } from "better-auth";\nexport type { Auth } from "better-auth";\nexport type AuthSessionUser = NonNullable<Auth["$Infer"]["Session"]["user"]> & {\n role?: string | null;\n isAnonymous?: boolean | null;\n walletAddress?: string | null;\n banned?: boolean | null;\n};\nexport type AuthSessionData = NonNullable<Auth["$Infer"]["Session"]["session"]> & {\n activeOrganizationId?: string | null;\n};\nexport type AuthSession = {\n user: AuthSessionUser | null;\n session: AuthSessionData | null;\n};\nexport interface AuthOrganizationContext {\n activeOrganizationId: string | null;\n organization: { id: string; name: string; slug: string; logo?: string | null; metadata?: Record<string, unknown> } | null;\n member: { id: string; role: string } | null;\n isPersonal: boolean;\n hasOrganization: boolean;\n}\nexport interface AuthRequestContext {\n user: AuthSessionUser | null;\n userId: string | null;\n isAuthenticated: boolean;\n authMethod: "session" | "apiKey" | "anonymous" | "none";\n near: {\n primaryAccountId: string | null;\n linkedAccounts: Array<{ accountId: string; network: string; publicKey: string; isPrimary: boolean }>;\n hasNearAccount: boolean;\n };\n organization: AuthOrganizationContext;\n organizations?: Array<{ id: string; role: string; name?: string; slug?: string }>;\n}\nexport type AuthActiveMember = { id: string | null; role: string | null; organizationId: string | null };\nexport type AuthOrganization = NonNullable<AuthOrganizationContext["organization"]>;\nexport type AuthOrganizationMember = NonNullable<AuthOrganizationContext["member"]>;\nexport type AuthOrganizationSummary = NonNullable<AuthRequestContext["organizations"]>[number];\nexport type AuthBaseSession = Auth["$Infer"]["Session"];\nexport type createAuthInstance = never;\nexport interface AuthServices {\n auth: Auth;\n db: unknown;\n driver: { close(): Promise<void> };\n handler: (req: Request) => Promise<Response>;\n}\n`,
472
- );
537
+ const authTypesContent = generateAuthTypesTemplate();
538
+ const authTypesPaths = [
539
+ join(destination, "ui", "src", "lib", "auth-types.gen.ts"),
540
+ join(destination, "api", "src", "lib", "auth-types.gen.ts"),
541
+ ];
542
+ if (existsSync(join(destination, "host", "src"))) {
543
+ authTypesPaths.push(join(destination, "host", "src", "lib", "auth-types.gen.ts"));
473
544
  }
474
-
475
- const apiAuthTypesGenPath = join(destination, "api", "src", "lib", "auth-types.gen.ts");
476
- if (!existsSync(apiAuthTypesGenPath)) {
477
- mkdirSync(dirname(apiAuthTypesGenPath), { recursive: true });
478
- writeFileSync(
479
- apiAuthTypesGenPath,
480
- `import type { Auth } from "better-auth";\nexport type { Auth } from "better-auth";\nexport type AuthSessionUser = NonNullable<Auth["$Infer"]["Session"]["user"]> & {\n role?: string | null;\n isAnonymous?: boolean | null;\n walletAddress?: string | null;\n banned?: boolean | null;\n};\nexport type AuthSessionData = NonNullable<Auth["$Infer"]["Session"]["session"]> & {\n activeOrganizationId?: string | null;\n};\nexport type AuthSession = {\n user: AuthSessionUser | null;\n session: AuthSessionData | null;\n};\nexport interface AuthOrganizationContext {\n activeOrganizationId: string | null;\n organization: { id: string; name: string; slug: string; logo?: string | null; metadata?: Record<string, unknown> } | null;\n member: { id: string; role: string } | null;\n isPersonal: boolean;\n hasOrganization: boolean;\n}\nexport interface AuthRequestContext {\n user: AuthSessionUser | null;\n userId: string | null;\n isAuthenticated: boolean;\n authMethod: "session" | "apiKey" | "anonymous" | "none";\n near: {\n primaryAccountId: string | null;\n linkedAccounts: Array<{ accountId: string; network: string; publicKey: string; isPrimary: boolean }>;\n hasNearAccount: boolean;\n };\n organization: AuthOrganizationContext;\n organizations?: Array<{ id: string; role: string; name?: string; slug?: string }>;\n}\nexport type AuthActiveMember = { id: string | null; role: string | null; organizationId: string | null };\nexport type AuthOrganization = NonNullable<AuthOrganizationContext["organization"]>;\nexport type AuthOrganizationMember = NonNullable<AuthOrganizationContext["member"]>;\nexport type AuthOrganizationSummary = NonNullable<AuthRequestContext["organizations"]>[number];\nexport type AuthBaseSession = Auth["$Infer"]["Session"];\nexport type createAuthInstance = never;\nexport interface AuthServices {\n auth: Auth;\n db: unknown;\n driver: { close(): Promise<void> };\n handler: (req: Request) => Promise<Response>;\n}\n`,
481
- );
545
+ for (const authTypesGenPath of authTypesPaths) {
546
+ if (!existsSync(authTypesGenPath)) {
547
+ mkdirSync(dirname(authTypesGenPath), { recursive: true });
548
+ writeFileSync(authTypesGenPath, authTypesContent);
549
+ }
482
550
  }
551
+ }
483
552
 
484
- const hostAuthTypesGenPath = join(destination, "host", "src", "lib", "auth-types.gen.ts");
485
- if (existsSync(join(destination, "host", "src")) && !existsSync(hostAuthTypesGenPath)) {
486
- mkdirSync(dirname(hostAuthTypesGenPath), { recursive: true });
487
- writeFileSync(
488
- hostAuthTypesGenPath,
489
- `import type { Auth } from "better-auth";\nexport type { Auth } from "better-auth";\nexport type AuthSessionUser = NonNullable<Auth["$Infer"]["Session"]["user"]> & {\n role?: string | null;\n isAnonymous?: boolean | null;\n walletAddress?: string | null;\n banned?: boolean | null;\n};\nexport type AuthSessionData = NonNullable<Auth["$Infer"]["Session"]["session"]> & {\n activeOrganizationId?: string | null;\n};\nexport type AuthSession = {\n user: AuthSessionUser | null;\n session: AuthSessionData | null;\n};\nexport interface AuthOrganizationContext {\n activeOrganizationId: string | null;\n organization: { id: string; name: string; slug: string; logo?: string | null; metadata?: Record<string, unknown> } | null;\n member: { id: string; role: string } | null;\n isPersonal: boolean;\n hasOrganization: boolean;\n}\nexport interface AuthRequestContext {\n user: AuthSessionUser | null;\n userId: string | null;\n isAuthenticated: boolean;\n authMethod: "session" | "apiKey" | "anonymous" | "none";\n near: {\n primaryAccountId: string | null;\n linkedAccounts: Array<{ accountId: string; network: string; publicKey: string; isPrimary: boolean }>;\n hasNearAccount: boolean;\n };\n organization: AuthOrganizationContext;\n organizations?: Array<{ id: string; role: string; name?: string; slug?: string }>;\n}\nexport type AuthActiveMember = { id: string | null; role: string | null; organizationId: string | null };\nexport type AuthOrganization = NonNullable<AuthOrganizationContext["organization"]>;\nexport type AuthOrganizationMember = NonNullable<AuthOrganizationContext["member"]>;\nexport type AuthOrganizationSummary = NonNullable<AuthRequestContext["organizations"]>[number];\nexport type AuthBaseSession = Auth["$Infer"]["Session"];\nexport type createAuthInstance = never;\nexport interface AuthServices {\n auth: Auth;\n db: unknown;\n driver: { close(): Promise<void> };\n handler: (req: Request) => Promise<Response>;\n}\n`,
490
- );
491
- }
553
+ function generateAuthTypesTemplate(): string {
554
+ return `import type { Auth } from "better-auth";
555
+ export type { Auth } from "better-auth";
556
+ export type AuthSessionUser = NonNullable<Auth["$Infer"]["Session"]["user"]> & {
557
+ role?: string | null;
558
+ isAnonymous?: boolean | null;
559
+ walletAddress?: string | null;
560
+ banned?: boolean | null;
561
+ };
562
+ export type AuthSessionData = NonNullable<Auth["$Infer"]["Session"]["session"]> & {
563
+ activeOrganizationId?: string | null;
564
+ };
565
+ export type AuthSession = {
566
+ user: AuthSessionUser | null;
567
+ session: AuthSessionData | null;
568
+ };
569
+ export interface AuthOrganizationContext {
570
+ activeOrganizationId: string | null;
571
+ organization: { id: string; name: string; slug: string; logo?: string | null; metadata?: Record<string, unknown> } | null;
572
+ member: { id: string; role: string } | null;
573
+ isPersonal: boolean;
574
+ hasOrganization: boolean;
575
+ }
576
+ export interface AuthRequestContext {
577
+ user: AuthSessionUser | null;
578
+ userId: string | null;
579
+ isAuthenticated: boolean;
580
+ authMethod: "session" | "apiKey" | "anonymous" | "none";
581
+ near: {
582
+ primaryAccountId: string | null;
583
+ linkedAccounts: Array<{ accountId: string; network: string; publicKey: string; isPrimary: boolean }>;
584
+ hasNearAccount: boolean;
585
+ };
586
+ organization: AuthOrganizationContext;
587
+ organizations?: Array<{ id: string; role: string; name?: string; slug?: string }>;
588
+ }
589
+ export type AuthActiveMember = { id: string | null; role: string | null; organizationId: string | null };
590
+ export type AuthOrganization = NonNullable<AuthOrganizationContext["organization"]>;
591
+ export type AuthOrganizationMember = NonNullable<AuthOrganizationContext["member"]>;
592
+ export type AuthOrganizationSummary = NonNullable<AuthRequestContext["organizations"]>[number];
593
+ export type AuthBaseSession = Auth["$Infer"]["Session"];
594
+ export type createAuthInstance = never;
595
+ export interface AuthServices {
596
+ auth: Auth;
597
+ db: unknown;
598
+ driver: { close(): Promise<void> };
599
+ handler: (req: Request) => Promise<Response>;
600
+ }
601
+ `;
492
602
  }
493
603
 
494
604
  export async function runBunInstall(destination: string): Promise<void> {
@@ -579,7 +689,7 @@ export async function writeInitSnapshot(
579
689
  for (const match of matches) {
580
690
  const pluginMatch = match.match(/^plugins\/([^/]+)/);
581
691
  if (pluginMatch && !(options.plugins?.includes(pluginMatch[1]) ?? true)) continue;
582
- if (isRouteExcluded(match, excludedRoutePatterns)) continue;
692
+ if (isPathExcluded(match, excludedRoutePatterns)) continue;
583
693
  allFiles.add(match);
584
694
  }
585
695
  }
@@ -595,7 +705,7 @@ export async function writeInitSnapshot(
595
705
  absolute: false,
596
706
  });
597
707
  for (const match of matches) {
598
- if (!isRouteExcluded(match, excludedRoutePatterns)) {
708
+ if (!isPathExcluded(match, excludedRoutePatterns)) {
599
709
  allFiles.add(match);
600
710
  }
601
711
  }
@@ -626,18 +736,7 @@ function computeHash(data: Uint8Array): string {
626
736
  }
627
737
 
628
738
  function mkTmpDir(prefix: string): string {
629
- const base = join(tmpdir(), prefix);
630
- let attempt = 0;
631
- while (true) {
632
- const dir = `${base}-${Date.now()}-${attempt}`;
633
- try {
634
- mkdirSync(dir, { recursive: true });
635
- return dir;
636
- } catch {
637
- attempt++;
638
- if (attempt > 10) throw new Error("Failed to create temp directory");
639
- }
640
- }
739
+ return mkdtempSync(join(tmpdir(), `${prefix}-`));
641
740
  }
642
741
 
643
742
  export async function generateDatabaseMigrations(destination: string): Promise<void> {
@@ -16,7 +16,7 @@ function deriveAccountFromDomain(domain: string, extendsAccount: string): string
16
16
  return `${firstSegment}.${suffix}`;
17
17
  }
18
18
 
19
- const AVAILABLE_PLUGINS = [{ value: "_template", label: "template" }];
19
+ const AVAILABLE_PLUGINS = [{ value: "settings", label: "settings" }];
20
20
 
21
21
  export async function promptInitOptions(input: {
22
22
  extendsAccount?: string;
@@ -89,7 +89,7 @@ export async function promptInitOptions(input: {
89
89
  ((await p.multiselect({
90
90
  message: "Select plugins:",
91
91
  options: AVAILABLE_PLUGINS,
92
- initialValues: ["_template"],
92
+ initialValues: ["settings"],
93
93
  required: false,
94
94
  })) as string[]);
95
95
 
package/src/cli/status.ts CHANGED
@@ -7,6 +7,19 @@ import { readSnapshot } from "./snapshot";
7
7
 
8
8
  const FRAMEWORK_PACKAGES = ["everything-dev", "every-plugin"];
9
9
 
10
+ const CATALOG_TOOL_PACKAGES = [
11
+ "@rspack/core",
12
+ "@rspack/cli",
13
+ "@rsbuild/core",
14
+ "@rsbuild/plugin-react",
15
+ "@module-federation/enhanced",
16
+ "@module-federation/node",
17
+ "@module-federation/rsbuild-plugin",
18
+ "@module-federation/runtime-core",
19
+ "@module-federation/sdk",
20
+ "@module-federation/dts-plugin",
21
+ ] as const;
22
+
10
23
  async function fetchLatestNpmVersion(packageName: string): Promise<string | null> {
11
24
  try {
12
25
  const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
@@ -61,6 +74,13 @@ export async function getStatus(projectDir: string): Promise<StatusResult> {
61
74
  packages.push({ name, installed, latest: latest ?? undefined });
62
75
  }
63
76
 
77
+ for (const name of CATALOG_TOOL_PACKAGES) {
78
+ const installed = readInstalledVersion(projectDir, name);
79
+ if (!installed) continue;
80
+ const latest = await fetchLatestNpmVersion(name);
81
+ packages.push({ name, installed, latest: latest ?? undefined });
82
+ }
83
+
64
84
  const snapshot = await readSnapshot(projectDir);
65
85
 
66
86
  const extendsRef = config.extends as string | undefined;