everything-dev 1.12.4 → 1.13.1

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 (124) hide show
  1. package/cli.js +1 -1
  2. package/dist/app.cjs +17 -5
  3. package/dist/app.cjs.map +1 -1
  4. package/dist/app.mjs +17 -5
  5. package/dist/app.mjs.map +1 -1
  6. package/dist/cli/init.cjs +143 -66
  7. package/dist/cli/init.cjs.map +1 -1
  8. package/dist/cli/init.d.cts +1 -1
  9. package/dist/cli/init.d.cts.map +1 -1
  10. package/dist/cli/init.d.mts +1 -1
  11. package/dist/cli/init.d.mts.map +1 -1
  12. package/dist/cli/init.mjs +144 -67
  13. package/dist/cli/init.mjs.map +1 -1
  14. package/dist/cli/prompts.cjs +3 -3
  15. package/dist/cli/prompts.cjs.map +1 -1
  16. package/dist/cli/prompts.mjs +3 -3
  17. package/dist/cli/prompts.mjs.map +1 -1
  18. package/dist/cli/sync.cjs +15 -56
  19. package/dist/cli/sync.cjs.map +1 -1
  20. package/dist/cli/sync.mjs +15 -56
  21. package/dist/cli/sync.mjs.map +1 -1
  22. package/dist/cli/upgrade.cjs +3 -1
  23. package/dist/cli/upgrade.cjs.map +1 -1
  24. package/dist/cli/upgrade.mjs +3 -1
  25. package/dist/cli/upgrade.mjs.map +1 -1
  26. package/dist/config.cjs +206 -69
  27. package/dist/config.cjs.map +1 -1
  28. package/dist/config.d.cts +13 -6
  29. package/dist/config.d.cts.map +1 -1
  30. package/dist/config.d.mts +13 -6
  31. package/dist/config.d.mts.map +1 -1
  32. package/dist/config.mjs +201 -71
  33. package/dist/config.mjs.map +1 -1
  34. package/dist/contract.d.cts +104 -8
  35. package/dist/contract.d.cts.map +1 -1
  36. package/dist/contract.d.mts +104 -8
  37. package/dist/contract.d.mts.map +1 -1
  38. package/dist/host.cjs +34 -1
  39. package/dist/host.cjs.map +1 -1
  40. package/dist/host.d.cts.map +1 -1
  41. package/dist/host.d.mts.map +1 -1
  42. package/dist/host.mjs +34 -1
  43. package/dist/host.mjs.map +1 -1
  44. package/dist/index.cjs +16 -0
  45. package/dist/index.d.cts +5 -3
  46. package/dist/index.d.mts +5 -3
  47. package/dist/index.mjs +5 -3
  48. package/dist/merge.cjs +113 -0
  49. package/dist/merge.cjs.map +1 -0
  50. package/dist/merge.d.cts +7 -0
  51. package/dist/merge.d.cts.map +1 -0
  52. package/dist/merge.d.mts +7 -0
  53. package/dist/merge.d.mts.map +1 -0
  54. package/dist/merge.mjs +107 -0
  55. package/dist/merge.mjs.map +1 -0
  56. package/dist/plugin.cjs +117 -105
  57. package/dist/plugin.cjs.map +1 -1
  58. package/dist/plugin.d.cts +114 -8
  59. package/dist/plugin.d.cts.map +1 -1
  60. package/dist/plugin.d.mts +114 -8
  61. package/dist/plugin.d.mts.map +1 -1
  62. package/dist/plugin.mjs +117 -105
  63. package/dist/plugin.mjs.map +1 -1
  64. package/dist/service-descriptor.cjs +21 -0
  65. package/dist/service-descriptor.cjs.map +1 -1
  66. package/dist/service-descriptor.d.cts +23 -1
  67. package/dist/service-descriptor.d.cts.map +1 -1
  68. package/dist/service-descriptor.d.mts +23 -1
  69. package/dist/service-descriptor.d.mts.map +1 -1
  70. package/dist/service-descriptor.mjs +21 -0
  71. package/dist/service-descriptor.mjs.map +1 -1
  72. package/dist/shared.cjs +24 -2
  73. package/dist/shared.cjs.map +1 -1
  74. package/dist/shared.d.cts +3 -0
  75. package/dist/shared.d.cts.map +1 -1
  76. package/dist/shared.d.mts +3 -0
  77. package/dist/shared.d.mts.map +1 -1
  78. package/dist/shared.mjs +25 -3
  79. package/dist/shared.mjs.map +1 -1
  80. package/dist/sidebar.cjs +124 -0
  81. package/dist/sidebar.cjs.map +1 -0
  82. package/dist/sidebar.d.cts +8 -0
  83. package/dist/sidebar.d.cts.map +1 -0
  84. package/dist/sidebar.d.mts +8 -0
  85. package/dist/sidebar.d.mts.map +1 -0
  86. package/dist/sidebar.mjs +122 -0
  87. package/dist/sidebar.mjs.map +1 -0
  88. package/dist/types.cjs +104 -10
  89. package/dist/types.cjs.map +1 -1
  90. package/dist/types.d.cts +256 -29
  91. package/dist/types.d.cts.map +1 -1
  92. package/dist/types.d.mts +256 -29
  93. package/dist/types.d.mts.map +1 -1
  94. package/dist/types.mjs +100 -11
  95. package/dist/types.mjs.map +1 -1
  96. package/dist/utils/path-match.cjs +18 -0
  97. package/dist/utils/path-match.cjs.map +1 -0
  98. package/dist/utils/path-match.mjs +17 -0
  99. package/dist/utils/path-match.mjs.map +1 -0
  100. package/dist/utils/save-config.cjs +19 -0
  101. package/dist/utils/save-config.cjs.map +1 -0
  102. package/dist/utils/save-config.mjs +18 -0
  103. package/dist/utils/save-config.mjs.map +1 -0
  104. package/package.json +3 -2
  105. package/skills/dev-workflow/SKILL.md +8 -0
  106. package/skills/extends-config/SKILL.md +132 -0
  107. package/skills/init-upgrade/SKILL.md +128 -0
  108. package/skills/publish-sync/SKILL.md +30 -0
  109. package/src/app.ts +15 -5
  110. package/src/cli/init.ts +199 -100
  111. package/src/cli/prompts.ts +2 -2
  112. package/src/cli/sync.ts +27 -96
  113. package/src/cli/upgrade.ts +2 -0
  114. package/src/config.ts +306 -119
  115. package/src/host.ts +45 -0
  116. package/src/index.ts +1 -0
  117. package/src/merge.ts +198 -0
  118. package/src/plugin.ts +340 -318
  119. package/src/service-descriptor.ts +23 -0
  120. package/src/shared.ts +48 -5
  121. package/src/sidebar.ts +162 -0
  122. package/src/types.ts +134 -28
  123. package/src/utils/path-match.ts +16 -0
  124. package/src/utils/save-config.ts +20 -0
package/dist/plugin.d.mts CHANGED
@@ -66,7 +66,11 @@ declare const _default: _$every_plugin0.LoadedPluginWithBinding<{
66
66
  config: _$_orpc_contract0.ContractProcedure<_$_orpc_contract0.Schema<unknown, unknown>, z.ZodObject<{
67
67
  config: z.ZodNullable<z.ZodObject<{
68
68
  account: z.ZodString;
69
- extends: z.ZodOptional<z.ZodString>;
69
+ extends: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
70
+ development: z.ZodOptional<z.ZodString>;
71
+ production: z.ZodOptional<z.ZodString>;
72
+ staging: z.ZodOptional<z.ZodString>;
73
+ }, z.core.$strip>]>>;
70
74
  domain: z.ZodOptional<z.ZodString>;
71
75
  testnet: z.ZodOptional<z.ZodString>;
72
76
  staging: z.ZodOptional<z.ZodObject<{
@@ -81,8 +85,12 @@ declare const _default: _$every_plugin0.LoadedPluginWithBinding<{
81
85
  strictVersion: z.ZodOptional<z.ZodBoolean>;
82
86
  shareScope: z.ZodOptional<z.ZodString>;
83
87
  }, z.core.$strip>>>>;
84
- plugins: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
85
- extends: z.ZodOptional<z.ZodString>;
88
+ plugins: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
89
+ extends: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
90
+ development: z.ZodOptional<z.ZodString>;
91
+ production: z.ZodOptional<z.ZodString>;
92
+ staging: z.ZodOptional<z.ZodString>;
93
+ }, z.core.$strip>]>>;
86
94
  development: z.ZodOptional<z.ZodString>;
87
95
  production: z.ZodOptional<z.ZodString>;
88
96
  integrity: z.ZodOptional<z.ZodString>;
@@ -92,7 +100,27 @@ declare const _default: _$every_plugin0.LoadedPluginWithBinding<{
92
100
  variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
93
101
  secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
94
102
  routes: z.ZodOptional<z.ZodArray<z.ZodString>>;
95
- }, z.core.$strip>>>;
103
+ sidebar: z.ZodOptional<z.ZodArray<z.ZodObject<{
104
+ icon: z.ZodString;
105
+ label: z.ZodString;
106
+ to: z.ZodOptional<z.ZodString>;
107
+ roleRequired: z.ZodOptional<z.ZodEnum<{
108
+ anon: "anon";
109
+ member: "member";
110
+ admin: "admin";
111
+ }>>;
112
+ }, z.core.$strip>>>;
113
+ app: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
114
+ shared: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
115
+ version: z.ZodString;
116
+ requiredVersion: z.ZodOptional<z.ZodString>;
117
+ singleton: z.ZodOptional<z.ZodBoolean>;
118
+ eager: z.ZodOptional<z.ZodBoolean>;
119
+ strictVersion: z.ZodOptional<z.ZodBoolean>;
120
+ shareScope: z.ZodOptional<z.ZodString>;
121
+ }, z.core.$strip>>>>;
122
+ plugins: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
123
+ }, z.core.$strip>]>>>;
96
124
  app: z.ZodObject<{
97
125
  host: z.ZodObject<{
98
126
  development: z.ZodString;
@@ -116,6 +144,16 @@ declare const _default: _$every_plugin0.LoadedPluginWithBinding<{
116
144
  proxy: z.ZodOptional<z.ZodString>;
117
145
  variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
118
146
  secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
147
+ sidebar: z.ZodOptional<z.ZodArray<z.ZodObject<{
148
+ icon: z.ZodString;
149
+ label: z.ZodString;
150
+ to: z.ZodOptional<z.ZodString>;
151
+ roleRequired: z.ZodOptional<z.ZodEnum<{
152
+ anon: "anon";
153
+ member: "member";
154
+ admin: "admin";
155
+ }>>;
156
+ }, z.core.$strip>>>;
119
157
  }, z.core.$strip>;
120
158
  auth: z.ZodOptional<z.ZodObject<{
121
159
  name: z.ZodString;
@@ -125,6 +163,16 @@ declare const _default: _$every_plugin0.LoadedPluginWithBinding<{
125
163
  proxy: z.ZodOptional<z.ZodString>;
126
164
  variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
127
165
  secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
166
+ sidebar: z.ZodOptional<z.ZodArray<z.ZodObject<{
167
+ icon: z.ZodString;
168
+ label: z.ZodString;
169
+ to: z.ZodOptional<z.ZodString>;
170
+ roleRequired: z.ZodOptional<z.ZodEnum<{
171
+ anon: "anon";
172
+ member: "member";
173
+ admin: "admin";
174
+ }>>;
175
+ }, z.core.$strip>>>;
128
176
  }, z.core.$strip>>;
129
177
  }, z.core.$strip>;
130
178
  }, z.core.$strip>>;
@@ -376,6 +424,12 @@ declare const _default: _$every_plugin0.LoadedPluginWithBinding<{
376
424
  proxy?: string | undefined;
377
425
  variables?: Record<string, string> | undefined;
378
426
  secrets?: string[] | undefined;
427
+ sidebar?: {
428
+ icon: string;
429
+ label: string;
430
+ to?: string | undefined;
431
+ roleRequired?: "anon" | "member" | "admin" | undefined;
432
+ }[] | undefined;
379
433
  };
380
434
  auth?: {
381
435
  name: string;
@@ -385,9 +439,19 @@ declare const _default: _$every_plugin0.LoadedPluginWithBinding<{
385
439
  proxy?: string | undefined;
386
440
  variables?: Record<string, string> | undefined;
387
441
  secrets?: string[] | undefined;
442
+ sidebar?: {
443
+ icon: string;
444
+ label: string;
445
+ to?: string | undefined;
446
+ roleRequired?: "anon" | "member" | "admin" | undefined;
447
+ }[] | undefined;
388
448
  } | undefined;
389
449
  };
390
- extends?: string | undefined;
450
+ extends?: string | {
451
+ development?: string | undefined;
452
+ production?: string | undefined;
453
+ staging?: string | undefined;
454
+ } | undefined;
391
455
  domain?: string | undefined;
392
456
  testnet?: string | undefined;
393
457
  staging?: {
@@ -402,8 +466,12 @@ declare const _default: _$every_plugin0.LoadedPluginWithBinding<{
402
466
  strictVersion?: boolean | undefined;
403
467
  shareScope?: string | undefined;
404
468
  }>> | undefined;
405
- plugins?: Record<string, {
406
- extends?: string | undefined;
469
+ plugins?: Record<string, string | {
470
+ extends?: string | {
471
+ development?: string | undefined;
472
+ production?: string | undefined;
473
+ staging?: string | undefined;
474
+ } | undefined;
407
475
  development?: string | undefined;
408
476
  production?: string | undefined;
409
477
  integrity?: string | undefined;
@@ -413,10 +481,26 @@ declare const _default: _$every_plugin0.LoadedPluginWithBinding<{
413
481
  variables?: Record<string, string> | undefined;
414
482
  secrets?: string[] | undefined;
415
483
  routes?: string[] | undefined;
484
+ sidebar?: {
485
+ icon: string;
486
+ label: string;
487
+ to?: string | undefined;
488
+ roleRequired?: "anon" | "member" | "admin" | undefined;
489
+ }[] | undefined;
490
+ app?: Record<string, unknown> | undefined;
491
+ shared?: Record<string, Record<string, {
492
+ version: string;
493
+ requiredVersion?: string | undefined;
494
+ singleton?: boolean | undefined;
495
+ eager?: boolean | undefined;
496
+ strictVersion?: boolean | undefined;
497
+ shareScope?: string | undefined;
498
+ }>> | undefined;
499
+ plugins?: Record<string, unknown> | undefined;
416
500
  }> | undefined;
417
501
  } | null;
418
502
  runtimeConfig: {
419
- env: "development" | "production";
503
+ env: "development" | "production" | "staging";
420
504
  account: string;
421
505
  networkId: "testnet" | "mainnet";
422
506
  host: {
@@ -485,6 +569,12 @@ declare const _default: _$every_plugin0.LoadedPluginWithBinding<{
485
569
  proxy?: string | undefined;
486
570
  variables?: Record<string, string> | undefined;
487
571
  secrets?: string[] | undefined;
572
+ sidebar?: {
573
+ icon: string;
574
+ label: string;
575
+ to?: string | undefined;
576
+ roleRequired?: "anon" | "member" | "admin" | undefined;
577
+ }[] | undefined;
488
578
  } | undefined;
489
579
  plugins?: Record<string, {
490
580
  name: string;
@@ -497,6 +587,22 @@ declare const _default: _$every_plugin0.LoadedPluginWithBinding<{
497
587
  variables?: Record<string, string> | undefined;
498
588
  secrets?: string[] | undefined;
499
589
  integrity?: string | undefined;
590
+ ui?: {
591
+ name: string;
592
+ url: string;
593
+ entry: string;
594
+ source: "local" | "remote";
595
+ localPath?: string | undefined;
596
+ port?: number | undefined;
597
+ integrity?: string | undefined;
598
+ } | undefined;
599
+ sidebar?: {
600
+ icon: string;
601
+ label: string;
602
+ to?: string | undefined;
603
+ roleRequired?: "anon" | "member" | "admin" | undefined;
604
+ }[] | undefined;
605
+ routes?: string[] | undefined;
500
606
  }> | undefined;
501
607
  } | null;
502
608
  configDir: string;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.mts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;;;cA8DwC,QAAA"}
1
+ {"version":3,"file":"plugin.d.mts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;;;cA8CwC,QAAA"}
package/dist/plugin.mjs CHANGED
@@ -1,10 +1,11 @@
1
- import { buildRegistryConfigUrl, buildRegistryConfigUrlForNetwork, fetchBosConfigFromFastKv, fetchPluginFromRegistry, fetchRemotePluginManifest, getRegistryNamespaceForAccount, getRegistryNamespaceForNetwork, parsePluginBosUrl } from "./fastkv.mjs";
1
+ import { buildRegistryConfigUrl, buildRegistryConfigUrlForNetwork, fetchBosConfigFromFastKv, fetchRemotePluginManifest, getRegistryNamespaceForAccount, getRegistryNamespaceForNetwork } from "./fastkv.mjs";
2
2
  import { getNetworkIdForAccount } from "./network.mjs";
3
3
  import { createPlugin, z } from "./sdk.mjs";
4
- import { buildRuntimePluginsForConfig, findConfigPath, getHostDevelopmentPort, getProjectRoot, loadConfig, resolveLocalDevelopmentPath } from "./config.mjs";
4
+ import { buildRuntimePluginsForConfig, findConfigPath, getHostDevelopmentPort, getProjectRoot, loadConfig, resolveLocalDevelopmentPath, writeResolvedConfig } from "./config.mjs";
5
5
  import { bosContract } from "./contract.mjs";
6
6
  import { syncApiContractBridge } from "./api-contract.mjs";
7
7
  import { buildRuntimeConfig, detectLocalPackages, prepareDevelopmentRuntimeConfig } from "./app.mjs";
8
+ import { saveBosConfig } from "./utils/save-config.mjs";
8
9
  import { copyFilteredFiles, fetchParentConfig, generateDatabaseMigrations, personalizeConfig, readTemplatekeep, resolveSourceDir, runBunInstall, runTypesGen, writeInitSnapshot } from "./cli/init.mjs";
9
10
  import { promptInitOptions } from "./cli/prompts.mjs";
10
11
  import { getStatus } from "./cli/status.mjs";
@@ -16,6 +17,7 @@ import { buildDescription, buildServiceDescriptorMap } from "./service-descripto
16
17
  import { devApp, startApp } from "./dev-session.mjs";
17
18
  import { addFunctionCallAccessKey, ensureNearCli, executeTransaction } from "./near-cli.mjs";
18
19
  import { syncAndGenerateSharedUi } from "./shared.mjs";
20
+ import { writePluginSidebarGen } from "./sidebar.mjs";
19
21
  import { run } from "./utils/run.mjs";
20
22
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
21
23
  import { basename, dirname, join, resolve } from "node:path";
@@ -54,6 +56,10 @@ const buildCommands = {
54
56
  }
55
57
  };
56
58
  const PUBLISH_FUNCTION_NAMES = ["__fastdata_kv"];
59
+ function getPluginRef(entry) {
60
+ if (!entry || typeof entry === "string") return null;
61
+ return entry;
62
+ }
57
63
  function parseSourceMode(value, defaultValue) {
58
64
  if (value === "local" || value === "remote") return value;
59
65
  return defaultValue;
@@ -81,7 +87,7 @@ function resolveWorkspaceTarget(key, bosConfig, runtimeConfig, configDir) {
81
87
  path: `${configDir}/${key}`
82
88
  };
83
89
  }
84
- const pluginPath = (runtimeConfig?.plugins?.[key])?.localPath ?? resolveLocalDevelopmentPath(bosConfig?.plugins?.[key]?.development, configDir);
90
+ const pluginPath = (runtimeConfig?.plugins?.[key])?.localPath ?? resolveLocalDevelopmentPath(getPluginRef(bosConfig?.plugins?.[key])?.development, configDir);
85
91
  if (pluginPath) return {
86
92
  key,
87
93
  kind: "plugin",
@@ -119,29 +125,25 @@ function defaultPluginKey(source) {
119
125
  }
120
126
  }
121
127
  function pluginLocalPath(configDir, attachment) {
122
- const source = attachment.development ?? attachment.production;
128
+ const ref = getPluginRef(attachment);
129
+ const source = ref?.development ?? ref?.production;
123
130
  if (!source?.startsWith("local:")) return null;
124
131
  return join(configDir, source.slice(6));
125
132
  }
126
- async function saveBosConfig(configDir, config) {
127
- const filePath = join(configDir, "bos.config.json");
128
- const next = `${JSON.stringify(config, null, 2)}\n`;
129
- try {
130
- if (readFileSync(filePath, "utf8") === next) return;
131
- } catch {}
132
- writeFileSync(filePath, next);
133
- }
134
133
  function listPluginAttachments(config) {
135
- return Object.entries(config?.plugins ?? {}).map(([key, attachment]) => ({
136
- key,
137
- development: attachment.development,
138
- production: attachment.production,
139
- localPath: attachment.development?.startsWith("local:") ? attachment.development.slice(6) : void 0,
140
- source: attachment.development?.startsWith("local:") ? "local" : "remote",
141
- integrity: attachment.integrity,
142
- version: attachment.version,
143
- name: attachment.name
144
- })).sort((a, b) => a.key.localeCompare(b.key));
134
+ return Object.entries(config?.plugins ?? {}).map(([key, attachment]) => {
135
+ const ref = getPluginRef(attachment);
136
+ return {
137
+ key,
138
+ development: ref?.development,
139
+ production: ref?.production,
140
+ localPath: ref?.development?.startsWith("local:") ? ref.development.slice(6) : void 0,
141
+ source: ref?.development?.startsWith("local:") ? "local" : "remote",
142
+ integrity: ref?.integrity,
143
+ version: ref?.version,
144
+ name: ref?.name
145
+ };
146
+ }).sort((a, b) => a.key.localeCompare(b.key));
145
147
  }
146
148
  async function refreshApiContractBridge(configDir, env = "development") {
147
149
  const refreshed = await loadConfig({
@@ -154,6 +156,7 @@ async function refreshApiContractBridge(configDir, env = "development") {
154
156
  runtimeConfig: refreshed.runtime,
155
157
  apiBaseUrl: refreshed.runtime.api.url
156
158
  });
159
+ writePluginSidebarGen(configDir, refreshed.config);
157
160
  }
158
161
  function extractPublishedUrl(output) {
159
162
  const match = output.match(/https?:\/\/[^\s"'<>]+/g);
@@ -235,7 +238,8 @@ async function buildWorkspaceTargets(opts) {
235
238
  if ((await syncAndGenerateSharedUi({
236
239
  configDir: opts.configDir,
237
240
  hostMode: "local",
238
- bosConfig: opts.bosConfig ?? void 0
241
+ bosConfig: opts.bosConfig ?? void 0,
242
+ extendsChain: []
239
243
  })).catalogChanged) await run("bun", ["install"], { cwd: opts.configDir });
240
244
  if (existing.some((entry) => entry.key === "api")) await buildEveryPluginQuietly(opts.configDir);
241
245
  await buildEverythingDevQuietly(opts.configDir);
@@ -292,62 +296,24 @@ var plugin_default = createPlugin({
292
296
  key: "",
293
297
  error: "No bos.config.json found"
294
298
  };
295
- const pluginRef = parsePluginBosUrl(input.source);
296
- let production = input.production ?? input.source;
297
- let integrity;
298
- let version;
299
- let name;
300
- if (pluginRef) try {
301
- const entry = await fetchPluginFromRegistry(pluginRef.accountId, pluginRef.pluginName);
302
- if (!entry) return {
303
- status: "error",
304
- key: "",
305
- error: `Plugin not found in registry: bos://${pluginRef.accountId}/plugins/${pluginRef.pluginName}`
306
- };
307
- const manifest = entry.manifest;
308
- if (manifest.schemaVersion !== 1 || manifest.kind !== "every-plugin/manifest" || !manifest.plugin?.name || !manifest.plugin?.version || !manifest.runtime?.remoteEntry) return {
309
- status: "error",
310
- key: "",
311
- error: `Invalid plugin manifest for bos://${pluginRef.accountId}/plugins/${pluginRef.pluginName}`
312
- };
313
- production = entry.metadata.cdnUrl || input.production || input.source;
314
- name = manifest.plugin.name;
315
- version = manifest.plugin.version;
316
- } catch (error) {
317
- return {
318
- status: "error",
319
- key: "",
320
- error: `Failed to resolve plugin from registry: ${error instanceof Error ? error.message : error}`
321
- };
322
- }
323
- if (!input.source.startsWith("local:") && !pluginRef && production.startsWith("https://")) try {
324
- const manifest = await fetchRemotePluginManifest(production);
325
- if (manifest) {
326
- name = manifest.plugin.name;
327
- version = manifest.plugin.version;
328
- }
329
- } catch {
330
- console.warn(`[plugin add] Could not fetch manifest from ${production}`);
331
- }
332
- if (!input.source.startsWith("local:") && production.startsWith("https://")) try {
333
- const computed = await computeSriHashForUrl(production);
334
- if (computed) integrity = computed;
335
- } catch {
336
- console.warn(`[plugin add] Could not compute integrity for ${production}`);
337
- }
338
- const key = sanitizePluginKey(input.as ?? (pluginRef ? pluginRef.pluginName : defaultPluginKey(input.source)));
299
+ const isBosRef = input.source.startsWith("bos://");
300
+ const isLocal = input.source.startsWith("local:");
301
+ const key = sanitizePluginKey(input.as ?? (isBosRef ? input.source.split("/").pop() ?? "plugin" : defaultPluginKey(input.source)));
339
302
  const existing = deps.bosConfig.plugins?.[key];
303
+ const existingEntry = existing && typeof existing === "object" ? existing : {};
340
304
  const nextPlugins = { ...deps.bosConfig.plugins ?? {} };
341
- nextPlugins[key] = input.source.startsWith("local:") ? {
342
- ...existing ?? {},
305
+ if (isBosRef) nextPlugins[key] = {
306
+ ...existingEntry,
307
+ extends: input.source
308
+ };
309
+ else if (isLocal) nextPlugins[key] = {
310
+ ...existingEntry,
343
311
  development: input.source,
344
- production: input.production ?? existing?.production
345
- } : {
346
- ...existing ?? {},
347
- production,
348
- ...integrity ? { integrity } : {},
349
- ...name ? { name } : {},
350
- ...version ? { version } : {}
312
+ ...existingEntry.extends ? {} : {}
313
+ };
314
+ else nextPlugins[key] = {
315
+ ...existingEntry,
316
+ production: input.production ?? input.source
351
317
  };
352
318
  deps.bosConfig = {
353
319
  ...deps.bosConfig,
@@ -355,13 +321,15 @@ var plugin_default = createPlugin({
355
321
  };
356
322
  await saveBosConfig(deps.configDir, deps.bosConfig);
357
323
  await refreshApiContractBridge(deps.configDir);
324
+ const stored = deps.bosConfig.plugins?.[key];
325
+ const storedObj = stored && typeof stored === "object" ? stored : {};
358
326
  return {
359
327
  status: "added",
360
328
  key,
361
- development: deps.bosConfig.plugins?.[key]?.development,
362
- production: deps.bosConfig.plugins?.[key]?.production,
363
- integrity,
364
- version
329
+ development: storedObj.development,
330
+ production: storedObj.production,
331
+ integrity: storedObj.integrity,
332
+ version: storedObj.version
365
333
  };
366
334
  }),
367
335
  pluginRemove: builder.pluginRemove.handler(async ({ input }) => {
@@ -406,6 +374,7 @@ var plugin_default = createPlugin({
406
374
  key: input.key,
407
375
  error: `Plugin '${input.key}' is not configured`
408
376
  };
377
+ const attachmentRef = getPluginRef(attachment);
409
378
  const localPath = pluginLocalPath(deps.configDir, attachment);
410
379
  if (!localPath) return {
411
380
  status: "error",
@@ -438,29 +407,36 @@ var plugin_default = createPlugin({
438
407
  let publishedUrl = extractPublishedUrl(`${stdout}\n${stderr}`);
439
408
  let manifest = null;
440
409
  if (publishedUrl) manifest = await fetchRemotePluginManifest(publishedUrl);
441
- else if (attachment.production) {
442
- manifest = await fetchRemotePluginManifest(attachment.production);
443
- if (manifest) publishedUrl = attachment.production;
410
+ else if (attachmentRef?.production) {
411
+ manifest = await fetchRemotePluginManifest(attachmentRef.production);
412
+ if (manifest) publishedUrl = attachmentRef.production;
444
413
  }
445
414
  const integrity = publishedUrl ? await computeSriHashForUrl(publishedUrl) : null;
446
415
  const version = manifest?.plugin.version ?? pkgJson.version;
447
416
  if (publishedUrl) {
448
- deps.bosConfig = {
449
- ...deps.bosConfig,
450
- plugins: {
451
- ...deps.bosConfig.plugins ?? {},
452
- [input.key]: {
453
- ...deps.bosConfig.plugins?.[input.key] ?? {},
454
- production: publishedUrl,
455
- ...integrity ? { integrity } : {},
456
- ...manifest?.plugin.name ? { name: manifest.plugin.name } : {},
457
- ...version ? { version } : {}
458
- }
459
- }
460
- };
461
- await saveBosConfig(deps.configDir, deps.bosConfig);
417
+ const pluginConfigPath = join(localPath, "bos.config.json");
418
+ if (existsSync(pluginConfigPath)) try {
419
+ const pluginConfig = JSON.parse(readFileSync(pluginConfigPath, "utf-8"));
420
+ if (!pluginConfig.app) pluginConfig.app = {};
421
+ const app = pluginConfig.app;
422
+ if (!app.api) app.api = {};
423
+ const api = app.api;
424
+ api.production = publishedUrl;
425
+ if (integrity) api.integrity = integrity;
426
+ else delete api.integrity;
427
+ writeFileSync(pluginConfigPath, `${JSON.stringify(pluginConfig, null, 2)}\n`);
428
+ console.log(` ✅ Updated ${pluginConfigPath}: app.api.production`);
429
+ } catch (err) {
430
+ console.error(` ❌ Failed to update plugin bos.config.json:`, err instanceof Error ? err.message : err);
431
+ }
462
432
  const account = deps.bosConfig.account;
463
433
  const network = getNetworkIdForAccount(account);
434
+ let pluginDomain;
435
+ if (existsSync(pluginConfigPath)) try {
436
+ const pluginConfig = JSON.parse(readFileSync(pluginConfigPath, "utf-8"));
437
+ if (typeof pluginConfig.domain === "string") pluginDomain = pluginConfig.domain;
438
+ } catch {}
439
+ if (!pluginDomain) pluginDomain = `${input.key}.${deps.bosConfig.domain ?? "everything.dev"}`;
464
440
  if (manifest && version) try {
465
441
  const registryEntries = {
466
442
  [`plugins/${account}/${input.key}/manifest.json`]: JSON.stringify(manifest),
@@ -475,6 +451,11 @@ var plugin_default = createPlugin({
475
451
  }),
476
452
  [`plugins/${account}/${input.key}/versions/${version}/manifest.json`]: JSON.stringify(manifest)
477
453
  };
454
+ if (existsSync(pluginConfigPath)) try {
455
+ const publishedPluginConfig = JSON.parse(readFileSync(pluginConfigPath, "utf-8"));
456
+ delete publishedPluginConfig.development;
457
+ registryEntries[`apps/${account}/${pluginDomain}/bos.config.json`] = JSON.stringify(publishedPluginConfig);
458
+ } catch {}
478
459
  const payload = JSON.stringify(registryEntries);
479
460
  const argsBase64 = Buffer.from(payload).toString("base64");
480
461
  const privateKey = process.env.NEAR_PRIVATE_KEY || process.env.BOS_NEAR_PRIVATE_KEY;
@@ -503,7 +484,7 @@ var plugin_default = createPlugin({
503
484
  key: input.key,
504
485
  path: localPath,
505
486
  script,
506
- production: publishedUrl ?? attachment.production,
487
+ production: publishedUrl ?? attachmentRef?.production,
507
488
  integrity: integrity ?? void 0,
508
489
  version: version ?? void 0
509
490
  };
@@ -520,13 +501,18 @@ var plugin_default = createPlugin({
520
501
  if ((await syncAndGenerateSharedUi({
521
502
  configDir: deps.configDir,
522
503
  hostMode: hostSource,
523
- bosConfig: deps.bosConfig ?? void 0
504
+ bosConfig: deps.bosConfig ?? void 0,
505
+ extendsChain: []
524
506
  })).catalogChanged) await run("bun", ["install"], { cwd: deps.configDir });
525
507
  if (apiSource === "local" && !proxy || localPackages.some((pkg) => pkg.startsWith("plugin:"))) await buildEveryPluginQuietly(deps.configDir);
526
508
  await buildEverythingDevQuietly(deps.configDir);
527
509
  const refreshed = await loadConfig({ cwd: deps.configDir });
528
510
  deps.bosConfig = refreshed?.config ?? deps.bosConfig;
529
511
  deps.runtimeConfig = refreshed?.runtime ?? deps.runtimeConfig;
512
+ if (deps.bosConfig) {
513
+ writeResolvedConfig(deps.configDir, deps.bosConfig, "development", refreshed?.source.extended);
514
+ writePluginSidebarGen(deps.configDir, deps.bosConfig);
515
+ }
530
516
  if (!deps.bosConfig) return {
531
517
  status: "error",
532
518
  description: "No bos.config.json found",
@@ -614,6 +600,7 @@ var plugin_default = createPlugin({
614
600
  env: "production",
615
601
  plugins: runtimePlugins
616
602
  });
603
+ writePluginSidebarGen(deps.configDir, config);
617
604
  const productionEnv = {};
618
605
  const warnings = [];
619
606
  if (!process.env.CORS_ORIGIN && config.domain) {
@@ -673,6 +660,9 @@ var plugin_default = createPlugin({
673
660
  built: [],
674
661
  skipped: []
675
662
  };
663
+ const buildEnv = input.deploy ? "production" : "development";
664
+ writeResolvedConfig(deps.configDir, deps.bosConfig, buildEnv);
665
+ writePluginSidebarGen(deps.configDir, deps.bosConfig);
676
666
  const targets = selectWorkspaceTargets(input.packages, deps.bosConfig);
677
667
  if (targets.length === 0) return {
678
668
  status: "error",
@@ -684,7 +674,7 @@ var plugin_default = createPlugin({
684
674
  apiSource: deps.bosConfig.app.api?.development ? "local" : "remote",
685
675
  authSource: deps.bosConfig.app.auth?.development ? "local" : "remote",
686
676
  hostSource: deps.bosConfig.app.host?.development ? "local" : "remote",
687
- env: "development",
677
+ env: buildEnv,
688
678
  plugins: deps.runtimeConfig?.plugins
689
679
  });
690
680
  await syncApiContractBridge({
@@ -754,7 +744,20 @@ var plugin_default = createPlugin({
754
744
  publishConfig = refreshed.config;
755
745
  }
756
746
  }
757
- const payload = JSON.stringify({ [`apps/${account}/${gateway}/bos.config.json`]: JSON.stringify(publishConfig) });
747
+ const registryEntries = { [`apps/${account}/${gateway}/bos.config.json`]: JSON.stringify(publishConfig) };
748
+ for (const [pluginKey, pluginEntry] of Object.entries(publishConfig.plugins ?? {})) {
749
+ const pluginRef = getPluginRef(pluginEntry);
750
+ if (!pluginRef?.development?.startsWith("local:")) continue;
751
+ const pluginConfigPath = join(join(deps.configDir, pluginRef.development.slice(6)), "bos.config.json");
752
+ if (!existsSync(pluginConfigPath)) continue;
753
+ try {
754
+ const pluginConfig = JSON.parse(readFileSync(pluginConfigPath, "utf-8"));
755
+ const pluginDomain = typeof pluginConfig.domain === "string" ? pluginConfig.domain : `${pluginKey}.${gateway}`;
756
+ delete pluginConfig.development;
757
+ registryEntries[`apps/${account}/${pluginDomain}/bos.config.json`] = JSON.stringify(pluginConfig);
758
+ } catch {}
759
+ }
760
+ const payload = JSON.stringify(registryEntries);
758
761
  const argsBase64 = Buffer.from(payload).toString("base64");
759
762
  const privateKey = input.privateKey || process.env.NEAR_PRIVATE_KEY || process.env.BOS_NEAR_PRIVATE_KEY;
760
763
  try {
@@ -878,7 +881,7 @@ var plugin_default = createPlugin({
878
881
  extendsAccount = extendsAccount || "dev.everything.near";
879
882
  extendsGateway = extendsGateway || "everything.dev";
880
883
  directory = directory || domain || extendsGateway;
881
- plugins = plugins?.length ? plugins : ["_template"];
884
+ plugins = plugins?.length ? plugins : ["settings"];
882
885
  try {
883
886
  await fetchParentConfig(extendsAccount, extendsGateway);
884
887
  } catch {
@@ -915,8 +918,9 @@ var plugin_default = createPlugin({
915
918
  error: "No .templatekeep found in template source"
916
919
  };
917
920
  const pluginRoutes = {};
918
- if (parentConfig.plugins) {
919
- for (const [key, ref] of Object.entries(parentConfig.plugins)) if (ref.routes && ref.routes.length > 0) pluginRoutes[key] = ref.routes;
921
+ if (parentConfig.plugins) for (const [key, entry] of Object.entries(parentConfig.plugins)) {
922
+ const entryRef = getPluginRef(entry);
923
+ if (entryRef?.routes && entryRef.routes.length > 0) pluginRoutes[key] = entryRef.routes;
920
924
  }
921
925
  const s = p.spinner();
922
926
  s.start("Setting up project");
@@ -946,6 +950,8 @@ var plugin_default = createPlugin({
946
950
  await runTypesGen(directory);
947
951
  await generateDatabaseMigrations(directory);
948
952
  }
953
+ const initConfig = await loadConfig({ cwd: directory });
954
+ if (initConfig?.config) writePluginSidebarGen(directory, initConfig.config);
949
955
  s.stop("Project initialized");
950
956
  return {
951
957
  status: "initialized",
@@ -986,7 +992,13 @@ var plugin_default = createPlugin({
986
992
  added: [],
987
993
  error: "No bos.config.json found in current directory"
988
994
  };
989
- return await syncTemplate(resolve(dirname(configPath)), input);
995
+ const projectDir = resolve(dirname(configPath));
996
+ const result = await syncTemplate(projectDir, input);
997
+ if (result.status === "synced" || result.status === "dry-run") {
998
+ const syncedConfig = await loadConfig({ cwd: projectDir });
999
+ if (syncedConfig?.config) writePluginSidebarGen(projectDir, syncedConfig.config);
1000
+ }
1001
+ return result;
990
1002
  } catch (error) {
991
1003
  return {
992
1004
  status: "error",