everything-dev 0.0.8 → 0.0.11

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.
package/package.json CHANGED
@@ -1,11 +1,40 @@
1
1
  {
2
2
  "name": "everything-dev",
3
- "version": "0.0.8",
3
+ "version": "0.0.11",
4
4
  "type": "module",
5
+ "main": "src/index.ts",
6
+ "exports": {
7
+ ".": "./src/index.ts",
8
+ "./types": "./src/types.ts"
9
+ },
10
+ "files": [
11
+ "src"
12
+ ],
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "catalog": {
17
+ "react": "^19.2.3",
18
+ "react-dom": "^19.2.3",
19
+ "@tanstack/react-query": "^5.90.11",
20
+ "@tanstack/react-router": "^1.153.2",
21
+ "@hot-labs/near-connect": "^0.8.2",
22
+ "near-kit": "^0.10.0",
23
+ "better-auth": "^1.4.6",
24
+ "better-near-auth": "^0.3.4",
25
+ "every-plugin": "0.8.9",
26
+ "drizzle-orm": "^0.45.1",
27
+ "drizzle-kit": "^0.31.8",
28
+ "@libsql/client": "^0.17.0",
29
+ "typescript": "^5.9.3",
30
+ "vitest": "^4.0.17",
31
+ "@types/node": "^25.0.3",
32
+ "@types/react": "^19.2.7",
33
+ "@types/react-dom": "^19.2.3"
34
+ },
5
35
  "bin": {
6
36
  "bos": "./src/cli.ts"
7
37
  },
8
- "main": "src/index.ts",
9
38
  "scripts": {
10
39
  "bos": "bun run src/cli.ts",
11
40
  "typecheck": "tsc --noEmit"
@@ -14,6 +43,9 @@
14
43
  "@clack/prompts": "^0.10.1",
15
44
  "@effect/platform": "^0.82.8",
16
45
  "@effect/platform-bun": "^0.58.1",
46
+ "@hono/node-server": "^1.19.9",
47
+ "@module-federation/enhanced": "^0.13.0",
48
+ "@module-federation/runtime-core": "^0.13.0",
17
49
  "@inquirer/prompts": "^8.2.0",
18
50
  "@libsql/client": "^0.17.0",
19
51
  "borsh": "^2.0.0",
@@ -22,8 +54,7 @@
22
54
  "commander": "^14.0.2",
23
55
  "degit": "^2.8.4",
24
56
  "effect": "^3.19.14",
25
- "every-plugin": "0.8.8",
26
- "everything-dev": "^0.0.4",
57
+ "every-plugin": "0.8.9",
27
58
  "execa": "^9.6.1",
28
59
  "gradient-string": "^3.0.0",
29
60
  "ink": "^5.2.1",
package/src/cli.ts CHANGED
@@ -230,35 +230,57 @@ async function main() {
230
230
 
231
231
  program
232
232
  .command("build")
233
- .description(`Build packages (${packages.join(", ")}). Deploys to Zephyr Cloud by default.`)
234
- .argument("[package]", "Package to build", "all")
233
+ .description(`Build packages locally (${packages.join(", ")})`)
234
+ .argument("[packages]", "Packages to build (comma-separated: host,ui,api)", "all")
235
+ .option("--force", "Force rebuild")
236
+ .action(async (pkgs: string, options) => {
237
+ console.log();
238
+ console.log(` ${icons.pkg} Building...`);
239
+
240
+ const result = await client.build({
241
+ packages: pkgs,
242
+ force: options.force || false,
243
+ deploy: false,
244
+ });
245
+
246
+ if (result.status === "error") {
247
+ console.error(colors.error(`${icons.err} Build failed`));
248
+ process.exit(1);
249
+ }
250
+
251
+ console.log();
252
+ console.log(colors.green(`${icons.ok} Built: ${result.built.join(", ")}`));
253
+ console.log();
254
+ });
255
+
256
+ program
257
+ .command("deploy")
258
+ .description(`Build and deploy to Zephyr Cloud (${packages.join(", ")})`)
259
+ .argument("[packages]", "Packages to deploy (comma-separated: host,ui,api)", "all")
235
260
  .option("--force", "Force rebuild")
236
- .option("--no-deploy", "Build locally without Zephyr deploy")
237
261
  .addHelpText("after", `
238
262
  Zephyr Configuration:
239
263
  Set ZE_SERVER_TOKEN and ZE_USER_EMAIL in .env.bos for CI/CD deployment.
240
264
  Docs: https://docs.zephyr-cloud.io/features/ci-cd-server-token
241
265
  `)
242
- .action(async (pkg: string, options) => {
266
+ .action(async (pkgs: string, options) => {
243
267
  console.log();
244
- console.log(` ${icons.pkg} Building${options.deploy ? " & deploying" : ""}...`);
268
+ console.log(` ${icons.pkg} Building & deploying...`);
245
269
 
246
270
  const result = await client.build({
247
- package: pkg,
271
+ packages: pkgs,
248
272
  force: options.force || false,
249
- deploy: options.deploy !== false,
273
+ deploy: true,
250
274
  });
251
275
 
252
276
  if (result.status === "error") {
253
- console.error(colors.error(`${icons.err} Build failed`));
277
+ console.error(colors.error(`${icons.err} Deploy failed`));
254
278
  process.exit(1);
255
279
  }
256
280
 
257
281
  console.log();
258
- console.log(colors.green(`${icons.ok} Built: ${result.built.join(", ")}`));
259
- if (result.deployed) {
260
- console.log(colors.dim(` Deployed to Zephyr Cloud`));
261
- }
282
+ console.log(colors.green(`${icons.ok} Deployed: ${result.built.join(", ")}`));
283
+ console.log(colors.dim(` Deployed to Zephyr Cloud`));
262
284
  console.log();
263
285
  });
264
286
 
@@ -632,6 +654,53 @@ Zephyr Configuration:
632
654
  console.log();
633
655
  });
634
656
 
657
+ program
658
+ .command("sync")
659
+ .description("Sync dependencies and config from everything-dev CLI")
660
+ .option("--account <account>", "NEAR account to sync from (default: every.near)")
661
+ .option("--gateway <gateway>", "Gateway domain to sync from (default: everything.dev)")
662
+ .option("--force", "Force sync even if versions match")
663
+ .action(async (options: { account?: string; gateway?: string; force?: boolean }) => {
664
+ console.log();
665
+ const source = options.account || options.gateway
666
+ ? `${options.account || "every.near"}/${options.gateway || "everything.dev"}`
667
+ : "every.near/everything.dev";
668
+ console.log(` ${icons.pkg} Syncing from ${colors.cyan(source)}...`);
669
+
670
+ const result = await client.sync({
671
+ account: options.account,
672
+ gateway: options.gateway,
673
+ force: options.force || false,
674
+ });
675
+
676
+ if (result.status === "error") {
677
+ console.error(colors.error(`${icons.err} Sync failed: ${result.error || "Unknown error"}`));
678
+ process.exit(1);
679
+ }
680
+
681
+ console.log();
682
+ console.log(colors.cyan(frames.top(52)));
683
+ console.log(` ${icons.ok} ${gradients.cyber("SYNCED")}`);
684
+ console.log(colors.cyan(frames.bottom(52)));
685
+ console.log();
686
+ console.log(` ${colors.dim("Source:")} ${colors.cyan(`${result.account}/${result.gateway}`)}`);
687
+ console.log(` ${colors.dim("CLI Version:")} ${colors.cyan(result.cliVersion)}`);
688
+ console.log(` ${colors.dim("Host URL:")} ${colors.cyan(result.hostUrl)}`);
689
+ console.log();
690
+
691
+ if (result.catalogUpdated) {
692
+ console.log(colors.green(` ${icons.ok} Updated root package.json catalog`));
693
+ }
694
+
695
+ if (result.packagesUpdated.length > 0) {
696
+ console.log(colors.green(` ${icons.ok} Updated packages: ${result.packagesUpdated.join(", ")}`));
697
+ }
698
+
699
+ console.log();
700
+ console.log(colors.dim(" Run 'bun install' to update lockfile"));
701
+ console.log();
702
+ });
703
+
635
704
  program
636
705
  .command("login")
637
706
  .description("Login to NOVA for encrypted secrets management")
package/src/config.ts CHANGED
@@ -1,13 +1,15 @@
1
1
  import { dirname, join } from "path";
2
-
3
- export type SourceMode = "local" | "remote";
4
-
5
- export interface AppConfig {
6
- host: SourceMode;
7
- ui: SourceMode;
8
- api: SourceMode;
9
- proxy?: boolean;
10
- }
2
+ import type {
3
+ AppConfig,
4
+ BosConfig,
5
+ GatewayConfig,
6
+ HostConfig,
7
+ PortConfig,
8
+ RemoteConfig,
9
+ SourceMode,
10
+ } from "./types";
11
+
12
+ export type { AppConfig, BosConfig, GatewayConfig, HostConfig, PortConfig, RemoteConfig, SourceMode };
11
13
 
12
14
  export const DEFAULT_DEV_CONFIG: AppConfig = {
13
15
  host: "local",
@@ -15,45 +17,6 @@ export const DEFAULT_DEV_CONFIG: AppConfig = {
15
17
  api: "local",
16
18
  };
17
19
 
18
- export interface HostConfig {
19
- title: string;
20
- description?: string;
21
- development: string;
22
- production: string;
23
- secrets?: string[];
24
- }
25
-
26
- export interface RemoteConfig {
27
- name: string;
28
- development: string;
29
- production: string;
30
- ssr?: string;
31
- proxy?: string;
32
- exposes?: Record<string, string>;
33
- variables?: Record<string, string>;
34
- secrets?: string[];
35
- }
36
-
37
- export interface GatewayConfig {
38
- development: string;
39
- production: string;
40
- }
41
-
42
- export interface BosConfig {
43
- account: string;
44
- gateway: GatewayConfig;
45
- templates?: Record<string, string>;
46
- create?: Record<string, string>;
47
- cli?: {
48
- remote?: string;
49
- local?: string;
50
- };
51
- app: {
52
- host: HostConfig;
53
- [remoteName: string]: HostConfig | RemoteConfig;
54
- };
55
- }
56
-
57
20
  let cachedConfig: BosConfig | null = null;
58
21
  let configDir: string | null = null;
59
22
  let configLoaded = false;
@@ -207,12 +170,6 @@ export function parsePort(url: string): number {
207
170
  }
208
171
  }
209
172
 
210
- export interface PortConfig {
211
- host: number;
212
- ui: number;
213
- api: number;
214
- }
215
-
216
173
  export function getPortsFromConfig(): PortConfig {
217
174
  const config = loadConfig();
218
175
  if (!config) {
package/src/contract.ts CHANGED
@@ -1,7 +1,11 @@
1
1
  import { oc } from "every-plugin/orpc";
2
2
  import { z } from "every-plugin/zod";
3
-
4
- const SourceModeSchema = z.enum(["local", "remote"]);
3
+ import {
4
+ BosConfigSchema,
5
+ HostConfigSchema,
6
+ RemoteConfigSchema,
7
+ SourceModeSchema,
8
+ } from "./types";
5
9
 
6
10
  const DevOptionsSchema = z.object({
7
11
  host: SourceModeSchema.default("local"),
@@ -44,9 +48,9 @@ const ServeResultSchema = z.object({
44
48
  });
45
49
 
46
50
  const BuildOptionsSchema = z.object({
47
- package: z.string().default("all"),
51
+ packages: z.string().default("all"),
48
52
  force: z.boolean().default(false),
49
- deploy: z.boolean().default(true),
53
+ deploy: z.boolean().default(false),
50
54
  });
51
55
 
52
56
  const BuildResultSchema = z.object({
@@ -88,36 +92,6 @@ const CreateResultSchema = z.object({
88
92
  path: z.string(),
89
93
  });
90
94
 
91
- const RemoteConfigSchema = z.object({
92
- name: z.string(),
93
- development: z.string(),
94
- production: z.string(),
95
- ssr: z.string().optional(),
96
- exposes: z.record(z.string(), z.string()).optional(),
97
- variables: z.record(z.string(), z.string()).optional(),
98
- secrets: z.array(z.string()).optional(),
99
- });
100
-
101
- const HostConfigSchema = z.object({
102
- title: z.string(),
103
- description: z.string().optional(),
104
- development: z.string(),
105
- production: z.string(),
106
- secrets: z.array(z.string()).optional(),
107
- });
108
-
109
- const BosConfigSchema = z.object({
110
- account: z.string(),
111
- cli: z.object({
112
- remote: z.string().optional(),
113
- local: z.string().optional(),
114
- }).optional(),
115
- create: z.record(z.string(), z.string()).optional(),
116
- app: z.object({
117
- host: HostConfigSchema,
118
- }).catchall(z.union([HostConfigSchema, RemoteConfigSchema])),
119
- });
120
-
121
95
  const InfoResultSchema = z.object({
122
96
  config: BosConfigSchema,
123
97
  packages: z.array(z.string()),
@@ -238,6 +212,23 @@ const GatewaySyncResultSchema = z.object({
238
212
  error: z.string().optional(),
239
213
  });
240
214
 
215
+ const SyncOptionsSchema = z.object({
216
+ account: z.string().optional(),
217
+ gateway: z.string().optional(),
218
+ force: z.boolean().optional(),
219
+ });
220
+
221
+ const SyncResultSchema = z.object({
222
+ status: z.enum(["synced", "error"]),
223
+ account: z.string(),
224
+ gateway: z.string(),
225
+ cliVersion: z.string(),
226
+ hostUrl: z.string(),
227
+ catalogUpdated: z.boolean(),
228
+ packagesUpdated: z.array(z.string()),
229
+ error: z.string().optional(),
230
+ });
231
+
241
232
  export const bosContract = oc.router({
242
233
  dev: oc
243
234
  .route({ method: "POST", path: "/dev" })
@@ -329,6 +320,11 @@ export const bosContract = oc.router({
329
320
  .route({ method: "POST", path: "/gateway/sync" })
330
321
  .input(GatewaySyncOptionsSchema)
331
322
  .output(GatewaySyncResultSchema),
323
+
324
+ sync: oc
325
+ .route({ method: "POST", path: "/sync" })
326
+ .input(SyncOptionsSchema)
327
+ .output(SyncResultSchema),
332
328
  });
333
329
 
334
330
  export type BosContract = typeof bosContract;
@@ -345,7 +341,6 @@ export type PublishOptions = z.infer<typeof PublishOptionsSchema>;
345
341
  export type PublishResult = z.infer<typeof PublishResultSchema>;
346
342
  export type CreateOptions = z.infer<typeof CreateOptionsSchema>;
347
343
  export type CreateResult = z.infer<typeof CreateResultSchema>;
348
- export type BosConfig = z.infer<typeof BosConfigSchema>;
349
344
  export type InfoResult = z.infer<typeof InfoResultSchema>;
350
345
  export type StatusOptions = z.infer<typeof StatusOptionsSchema>;
351
346
  export type StatusResult = z.infer<typeof StatusResultSchema>;
@@ -362,3 +357,5 @@ export type SecretsDeleteResult = z.infer<typeof SecretsDeleteResultSchema>;
362
357
  export type LoginOptions = z.infer<typeof LoginOptionsSchema>;
363
358
  export type LoginResult = z.infer<typeof LoginResultSchema>;
364
359
  export type LogoutResult = z.infer<typeof LogoutResultSchema>;
360
+ export type SyncOptions = z.infer<typeof SyncOptionsSchema>;
361
+ export type SyncResult = z.infer<typeof SyncResultSchema>;
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { default } from "./plugin";
2
2
  export { bosContract } from "./contract";
3
3
  export type * from "./contract";
4
+ export * from "./types";
@@ -29,7 +29,7 @@ const processConfigBases: Record<string, ProcessConfigBase> = {
29
29
  host: {
30
30
  name: "host",
31
31
  command: "bun",
32
- args: ["run", "tsx", "server.ts"],
32
+ args: ["run", "dev"],
33
33
  cwd: "host",
34
34
  readyPatterns: [/listening on/i, /server started/i, /ready/i, /running at/i],
35
35
  errorPatterns: [/error:/i, /failed/i, /exception/i],
@@ -37,7 +37,7 @@ const processConfigBases: Record<string, ProcessConfigBase> = {
37
37
  "ui-ssr": {
38
38
  name: "ui-ssr",
39
39
  command: "bun",
40
- args: ["run", "rsbuild", "build", "--watch"],
40
+ args: ["run", "build:ssr", "--watch"],
41
41
  cwd: "ui",
42
42
  readyPatterns: [/built in/i, /compiled.*successfully/i],
43
43
  errorPatterns: [/error/i, /failed/i],
@@ -45,7 +45,7 @@ const processConfigBases: Record<string, ProcessConfigBase> = {
45
45
  ui: {
46
46
  name: "ui",
47
47
  command: "bun",
48
- args: ["run", "rsbuild", "dev"],
48
+ args: ["run", "dev"],
49
49
  cwd: "ui",
50
50
  readyPatterns: [/ready in/i, /compiled.*successfully/i, /➜.*local:/i],
51
51
  errorPatterns: [/error/i, /failed to compile/i],
@@ -53,7 +53,7 @@ const processConfigBases: Record<string, ProcessConfigBase> = {
53
53
  api: {
54
54
  name: "api",
55
55
  command: "bun",
56
- args: ["run", "rspack", "serve"],
56
+ args: ["run", "dev"],
57
57
  cwd: "api",
58
58
  readyPatterns: [/compiled.*successfully/i, /listening/i, /started/i],
59
59
  errorPatterns: [/error/i, /failed/i],
package/src/plugin.ts CHANGED
@@ -4,9 +4,9 @@ import { z } from "every-plugin/zod";
4
4
  import { Graph } from "near-social-js";
5
5
 
6
6
  import {
7
+ type AppConfig,
7
8
  type BosConfig as BosConfigType,
8
9
  DEFAULT_DEV_CONFIG,
9
- type AppConfig,
10
10
  getConfigDir,
11
11
  getHost,
12
12
  getHostRemoteUrl,
@@ -25,14 +25,13 @@ import {
25
25
  createNovaClient,
26
26
  getNovaConfig,
27
27
  getSecretsGroupId,
28
- hasNovaCredentials,
29
28
  parseEnvFile,
30
29
  registerSecretsGroup,
31
30
  removeNovaCredentials,
32
31
  retrieveSecrets,
33
32
  saveNovaCredentials,
34
33
  uploadSecrets,
35
- verifyNovaCredentials,
34
+ verifyNovaCredentials
36
35
  } from "./lib/nova";
37
36
  import { type AppOrchestrator, startApp } from "./lib/orchestrator";
38
37
  import { run } from "./utils/run";
@@ -221,7 +220,7 @@ export default createPlugin({
221
220
  if (input.account && input.domain) {
222
221
  const graph = new Graph();
223
222
  const configPath = `${input.account}/bos/gateways/${input.domain}/bos.config.json`;
224
-
223
+
225
224
  try {
226
225
  const data = await graph.get({ keys: [configPath] });
227
226
  if (data) {
@@ -258,7 +257,7 @@ export default createPlugin({
258
257
  }
259
258
 
260
259
  const config = remoteConfig || deps.bosConfig;
261
-
260
+
262
261
  if (!config) {
263
262
  console.error("No configuration available. Provide --account and --domain, or run from a BOS project directory.");
264
263
  return {
@@ -324,17 +323,21 @@ export default createPlugin({
324
323
  }),
325
324
 
326
325
  build: builder.build.handler(async ({ input: buildInput }) => {
327
- const packages = getPackages();
326
+ const allPackages = getPackages();
328
327
  const { configDir } = deps;
329
328
 
330
- if (buildInput.package !== "all" && !packages.includes(buildInput.package)) {
329
+ const targets = buildInput.packages === "all"
330
+ ? allPackages
331
+ : buildInput.packages.split(",").map((p) => p.trim()).filter((p) => allPackages.includes(p));
332
+
333
+ if (targets.length === 0) {
334
+ console.log(colors.dim(` No valid packages to build`));
331
335
  return {
332
336
  status: "error" as const,
333
337
  built: [],
334
338
  };
335
339
  }
336
340
 
337
- const targets = buildInput.package === "all" ? packages : [buildInput.package];
338
341
  const built: string[] = [];
339
342
 
340
343
  const buildEffect = Effect.gen(function* () {
@@ -345,6 +348,7 @@ export default createPlugin({
345
348
  env.NODE_ENV = "development";
346
349
  } else {
347
350
  env.NODE_ENV = "production";
351
+ env.DEPLOY = "true";
348
352
  if (!hasZephyrConfig(bosEnv)) {
349
353
  console.log(colors.dim(` ${icons.config} Zephyr tokens not configured - you may be prompted to login`));
350
354
  console.log(colors.dim(` Setup: ${ZEPHYR_DOCS_URL}`));
@@ -377,7 +381,7 @@ export default createPlugin({
377
381
  }),
378
382
 
379
383
  publish: builder.publish.handler(async ({ input: publishInput }) => {
380
- const { bosConfig, nearPrivateKey } = deps;
384
+ const { configDir, bosConfig, nearPrivateKey } = deps;
381
385
 
382
386
  if (!bosConfig) {
383
387
  return {
@@ -397,7 +401,20 @@ export default createPlugin({
397
401
  const bosEnv = yield* loadBosEnv;
398
402
  const privateKey = nearPrivateKey || bosEnv.NEAR_PRIVATE_KEY;
399
403
 
400
- const socialArgs = buildSocialSetArgs(bosConfig.account, gatewayDomain, bosConfig);
404
+ const rootPkgPath = `${configDir}/package.json`;
405
+ const rootPkg = yield* Effect.tryPromise({
406
+ try: () => Bun.file(rootPkgPath).json() as Promise<{ version: string }>,
407
+ catch: (e) => new Error(`Failed to read root package.json: ${e}`),
408
+ });
409
+
410
+ const configToPublish = {
411
+ ...bosConfig,
412
+ cli: {
413
+ version: rootPkg.version,
414
+ },
415
+ };
416
+
417
+ const socialArgs = buildSocialSetArgs(bosConfig.account, gatewayDomain, configToPublish);
401
418
  const argsBase64 = Buffer.from(JSON.stringify(socialArgs)).toString("base64");
402
419
 
403
420
  if (publishInput.dryRun) {
@@ -524,7 +541,7 @@ export default createPlugin({
524
541
 
525
542
  status: builder.status.handler(async ({ input }) => {
526
543
  const config = deps.bosConfig;
527
-
544
+
528
545
  if (!config) {
529
546
  return { endpoints: [] };
530
547
  }
@@ -906,7 +923,7 @@ export default createPlugin({
906
923
  stdio: "inherit",
907
924
  });
908
925
 
909
- subprocess.catch(() => {});
926
+ subprocess.catch(() => { });
910
927
 
911
928
  return {
912
929
  status: "started" as const,
@@ -1018,5 +1035,188 @@ export default createPlugin({
1018
1035
  };
1019
1036
  }
1020
1037
  }),
1038
+
1039
+ sync: builder.sync.handler(async ({ input }) => {
1040
+ const { configDir, bosConfig } = deps;
1041
+
1042
+ const DEFAULT_SYNC_ACCOUNT = "every.near";
1043
+ const DEFAULT_SYNC_GATEWAY = "everything.dev";
1044
+
1045
+ const account = input.account || DEFAULT_SYNC_ACCOUNT;
1046
+ const gateway = input.gateway || DEFAULT_SYNC_GATEWAY;
1047
+
1048
+ if (!bosConfig) {
1049
+ return {
1050
+ status: "error" as const,
1051
+ account,
1052
+ gateway,
1053
+ cliVersion: "",
1054
+ hostUrl: "",
1055
+ catalogUpdated: false,
1056
+ packagesUpdated: [],
1057
+ error: "No bos.config.json found. Run from a BOS project directory.",
1058
+ };
1059
+ }
1060
+
1061
+ try {
1062
+ const graph = new Graph();
1063
+ const configPath = `${account}/bos/gateways/${gateway}/bos.config.json`;
1064
+
1065
+ let remoteConfig: { cli?: { version?: string }; app?: { host?: { production?: string } } } | null = null;
1066
+
1067
+ const data = await graph.get({ keys: [configPath] });
1068
+ if (data) {
1069
+ const parts = configPath.split("/");
1070
+ let current: unknown = data;
1071
+ for (const part of parts) {
1072
+ if (current && typeof current === "object" && part in current) {
1073
+ current = (current as Record<string, unknown>)[part];
1074
+ } else {
1075
+ current = null;
1076
+ break;
1077
+ }
1078
+ }
1079
+ if (typeof current === "string") {
1080
+ remoteConfig = JSON.parse(current);
1081
+ }
1082
+ }
1083
+
1084
+ if (!remoteConfig) {
1085
+ return {
1086
+ status: "error" as const,
1087
+ account,
1088
+ gateway,
1089
+ cliVersion: "",
1090
+ hostUrl: "",
1091
+ catalogUpdated: false,
1092
+ packagesUpdated: [],
1093
+ error: `No config found at ${configPath} on Near Social. Run 'bos publish' first.`,
1094
+ };
1095
+ }
1096
+
1097
+ const cliVersion = remoteConfig.cli?.version;
1098
+ if (!cliVersion) {
1099
+ return {
1100
+ status: "error" as const,
1101
+ account,
1102
+ gateway,
1103
+ cliVersion: "",
1104
+ hostUrl: "",
1105
+ catalogUpdated: false,
1106
+ packagesUpdated: [],
1107
+ error: `Published config is missing 'cli.version'. Republish with updated bos.config.json.`,
1108
+ };
1109
+ }
1110
+
1111
+ const hostUrl = remoteConfig.app?.host?.production;
1112
+ if (!hostUrl) {
1113
+ return {
1114
+ status: "error" as const,
1115
+ account,
1116
+ gateway,
1117
+ cliVersion,
1118
+ hostUrl: "",
1119
+ catalogUpdated: false,
1120
+ packagesUpdated: [],
1121
+ error: `Published config is missing 'app.host.production'. Republish with updated bos.config.json.`,
1122
+ };
1123
+ }
1124
+
1125
+ const npmUrl = `https://registry.npmjs.org/everything-dev/${cliVersion}`;
1126
+ const npmResponse = await fetch(npmUrl);
1127
+ if (!npmResponse.ok) {
1128
+ return {
1129
+ status: "error" as const,
1130
+ account,
1131
+ gateway,
1132
+ cliVersion,
1133
+ hostUrl,
1134
+ catalogUpdated: false,
1135
+ packagesUpdated: [],
1136
+ error: `Failed to fetch everything-dev@${cliVersion} from NPM (${npmResponse.status}). Ensure the version is published.`,
1137
+ };
1138
+ }
1139
+
1140
+ const npmPkg = await npmResponse.json() as { catalog?: Record<string, string> };
1141
+ const cliCatalog = npmPkg.catalog ?? {};
1142
+
1143
+ const bosConfigPath = `${configDir}/bos.config.json`;
1144
+ const updatedBosConfig = {
1145
+ ...bosConfig,
1146
+ cli: {
1147
+ version: cliVersion,
1148
+ },
1149
+ };
1150
+ await Bun.write(bosConfigPath, JSON.stringify(updatedBosConfig, null, 2));
1151
+
1152
+ const rootPkgPath = `${configDir}/package.json`;
1153
+ const rootPkg = await Bun.file(rootPkgPath).json() as {
1154
+ workspaces: { packages: string[]; catalog: Record<string, string> };
1155
+ [key: string]: unknown;
1156
+ };
1157
+
1158
+ rootPkg.workspaces.catalog = {
1159
+ ...cliCatalog,
1160
+ "everything-dev": cliVersion,
1161
+ };
1162
+ await Bun.write(rootPkgPath, JSON.stringify(rootPkg, null, 2));
1163
+
1164
+ const packages = ["host", "ui", "api"];
1165
+ const packagesUpdated: string[] = [];
1166
+
1167
+ for (const pkg of packages) {
1168
+ const pkgPath = `${configDir}/${pkg}/package.json`;
1169
+ const pkgFile = Bun.file(pkgPath);
1170
+
1171
+ if (!(await pkgFile.exists())) continue;
1172
+
1173
+ const pkgJson = await pkgFile.json() as {
1174
+ dependencies?: Record<string, string>;
1175
+ devDependencies?: Record<string, string>;
1176
+ peerDependencies?: Record<string, string>;
1177
+ };
1178
+
1179
+ let updated = false;
1180
+
1181
+ for (const depType of ["dependencies", "devDependencies", "peerDependencies"] as const) {
1182
+ const deps = pkgJson[depType];
1183
+ if (!deps) continue;
1184
+
1185
+ for (const [name, version] of Object.entries(deps)) {
1186
+ if (name in cliCatalog && version !== "catalog:") {
1187
+ deps[name] = "catalog:";
1188
+ updated = true;
1189
+ }
1190
+ }
1191
+ }
1192
+
1193
+ if (updated || input.force) {
1194
+ await Bun.write(pkgPath, JSON.stringify(pkgJson, null, 2));
1195
+ packagesUpdated.push(pkg);
1196
+ }
1197
+ }
1198
+
1199
+ return {
1200
+ status: "synced" as const,
1201
+ account,
1202
+ gateway,
1203
+ cliVersion,
1204
+ hostUrl,
1205
+ catalogUpdated: true,
1206
+ packagesUpdated,
1207
+ };
1208
+ } catch (error) {
1209
+ return {
1210
+ status: "error" as const,
1211
+ account,
1212
+ gateway,
1213
+ cliVersion: "",
1214
+ hostUrl: "",
1215
+ catalogUpdated: false,
1216
+ packagesUpdated: [],
1217
+ error: error instanceof Error ? error.message : "Unknown error",
1218
+ };
1219
+ }
1220
+ }),
1021
1221
  }),
1022
1222
  });
package/src/types.ts ADDED
@@ -0,0 +1,60 @@
1
+ import { z } from "every-plugin/zod";
2
+
3
+ export const SourceModeSchema = z.enum(["local", "remote"]);
4
+ export type SourceMode = z.infer<typeof SourceModeSchema>;
5
+
6
+ export const HostConfigSchema = z.object({
7
+ title: z.string(),
8
+ description: z.string().optional(),
9
+ development: z.string(),
10
+ production: z.string(),
11
+ secrets: z.array(z.string()).optional(),
12
+ });
13
+ export type HostConfig = z.infer<typeof HostConfigSchema>;
14
+
15
+ export const RemoteConfigSchema = z.object({
16
+ name: z.string(),
17
+ development: z.string(),
18
+ production: z.string(),
19
+ ssr: z.string().optional(),
20
+ proxy: z.string().optional(),
21
+ exposes: z.record(z.string(), z.string()).optional(),
22
+ variables: z.record(z.string(), z.string()).optional(),
23
+ secrets: z.array(z.string()).optional(),
24
+ });
25
+ export type RemoteConfig = z.infer<typeof RemoteConfigSchema>;
26
+
27
+ export const GatewayConfigSchema = z.object({
28
+ development: z.string(),
29
+ production: z.string(),
30
+ });
31
+ export type GatewayConfig = z.infer<typeof GatewayConfigSchema>;
32
+
33
+ export const BosConfigSchema = z.object({
34
+ account: z.string(),
35
+ gateway: GatewayConfigSchema,
36
+ templates: z.record(z.string(), z.string()).optional(),
37
+ create: z.record(z.string(), z.string()).optional(),
38
+ cli: z.object({
39
+ version: z.string().optional(),
40
+ }).optional(),
41
+ app: z.object({
42
+ host: HostConfigSchema,
43
+ }).catchall(z.union([HostConfigSchema, RemoteConfigSchema])),
44
+ });
45
+ export type BosConfig = z.infer<typeof BosConfigSchema>;
46
+
47
+ export const AppConfigSchema = z.object({
48
+ host: SourceModeSchema,
49
+ ui: SourceModeSchema,
50
+ api: SourceModeSchema,
51
+ proxy: z.boolean().optional(),
52
+ });
53
+ export type AppConfig = z.infer<typeof AppConfigSchema>;
54
+
55
+ export const PortConfigSchema = z.object({
56
+ host: z.number(),
57
+ ui: z.number(),
58
+ api: z.number(),
59
+ });
60
+ export type PortConfig = z.infer<typeof PortConfigSchema>;
package/tsconfig.json DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "types": ["bun"],
4
- "lib": ["ESNext", "DOM"],
5
- "module": "ESNext",
6
- "target": "ESNext",
7
- "moduleResolution": "bundler",
8
- "moduleDetection": "force",
9
- "allowImportingTsExtensions": true,
10
- "noEmit": true,
11
- "strict": true,
12
- "skipLibCheck": true,
13
- "jsx": "react-jsx",
14
- "jsxImportSource": "react",
15
- "allowSyntheticDefaultImports": true,
16
- "forceConsistentCasingInFileNames": true,
17
- "allowJs": true,
18
- "esModuleInterop": true,
19
- "resolveJsonModule": true
20
- },
21
- "include": ["src/**/*"]
22
- }