everything-dev 0.0.19 → 0.1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "everything-dev",
3
- "version": "0.0.19",
3
+ "version": "0.1.0",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
package/src/cli.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bun
2
+ import { spinner } from "@clack/prompts";
2
3
  import { program } from "commander";
3
4
  import { createPluginRuntime } from "every-plugin";
4
5
  import { getConfigDir, getConfigPath, getPackages, getTitle, loadConfig, type BosConfig } from "./config";
@@ -742,18 +743,20 @@ Zephyr Configuration:
742
743
 
743
744
  program
744
745
  .command("sync")
745
- .description("Sync dependencies and config from everything-dev CLI")
746
- .option("--account <account>", "NEAR account to sync from (default: every.near)")
747
- .option("--gateway <gateway>", "Gateway domain to sync from (default: everything.dev)")
746
+ .description("Sync dependencies and config from published bos.config.json")
747
+ .option("--account <account>", "NEAR account to sync from (default: from config)")
748
+ .option("--gateway <gateway>", "Gateway domain to sync from (default: from config)")
748
749
  .option("--network <network>", "Network: mainnet | testnet", "mainnet")
749
750
  .option("--force", "Force sync even if versions match")
750
751
  .option("--files", "Also sync template files (tsconfig, etc.)")
751
752
  .action(async (options: { account?: string; gateway?: string; network?: string; force?: boolean; files?: boolean }) => {
752
753
  console.log();
753
- const source = options.account || options.gateway
754
- ? `${options.account || "every.near"}/${options.gateway || "everything.dev"}`
755
- : "every.near/everything.dev";
756
- console.log(` ${icons.pkg} Syncing from ${colors.cyan(source)}...`);
754
+ const gateway = config?.gateway as { production?: string } | undefined;
755
+ const gatewayDomain = gateway?.production?.replace(/^https?:\/\//, "") || "everything.dev";
756
+ const source = `${options.account || config?.account || "every.near"}/${options.gateway || gatewayDomain}`;
757
+
758
+ const s = spinner();
759
+ s.start(`Syncing from ${source}...`);
757
760
 
758
761
  const result = await client.sync({
759
762
  account: options.account,
@@ -764,16 +767,19 @@ Zephyr Configuration:
764
767
  });
765
768
 
766
769
  if (result.status === "error") {
767
- console.error(colors.error(`${icons.err} Sync failed: ${result.error || "Unknown error"}`));
770
+ s.stop(colors.error(`${icons.err} Sync failed: ${result.error || "Unknown error"}`));
768
771
  process.exit(1);
769
772
  }
770
773
 
774
+ s.stop(colors.green(`${icons.ok} Synced from ${source}`));
775
+
771
776
  console.log();
772
777
  console.log(colors.cyan(frames.top(52)));
773
778
  console.log(` ${icons.ok} ${gradients.cyber("SYNCED")}`);
774
779
  console.log(colors.cyan(frames.bottom(52)));
775
780
  console.log();
776
781
  console.log(` ${colors.dim("Source:")} ${colors.cyan(`${result.account}/${result.gateway}`)}`);
782
+ console.log(` ${colors.dim("URL:")} ${colors.cyan(result.socialUrl)}`);
777
783
  console.log(` ${colors.dim("Host URL:")} ${colors.cyan(result.hostUrl)}`);
778
784
  console.log();
779
785
 
package/src/config.ts CHANGED
@@ -202,3 +202,48 @@ export function getGatewayUrl(env: "development" | "production" = "development")
202
202
  }
203
203
  return config.gateway[env];
204
204
  }
205
+
206
+ export async function packageExists(pkg: string): Promise<boolean> {
207
+ const dir = getConfigDir();
208
+ return Bun.file(`${dir}/${pkg}/package.json`).exists();
209
+ }
210
+
211
+ export async function resolvePackageModes(
212
+ packages: string[],
213
+ input: Record<string, SourceMode | undefined>
214
+ ): Promise<{ modes: Record<string, SourceMode>; autoRemote: string[] }> {
215
+ const dir = getConfigDir();
216
+ const modes: Record<string, SourceMode> = {};
217
+ const autoRemote: string[] = [];
218
+
219
+ for (const pkg of packages) {
220
+ const exists = await Bun.file(`${dir}/${pkg}/package.json`).exists();
221
+ const requestedMode = input[pkg] ?? "local";
222
+
223
+ if (!exists && requestedMode === "local") {
224
+ modes[pkg] = "remote";
225
+ autoRemote.push(pkg);
226
+ } else {
227
+ modes[pkg] = requestedMode;
228
+ }
229
+ }
230
+
231
+ return { modes, autoRemote };
232
+ }
233
+
234
+ export async function getExistingPackages(packages: string[]): Promise<{ existing: string[]; missing: string[] }> {
235
+ const dir = getConfigDir();
236
+ const existing: string[] = [];
237
+ const missing: string[] = [];
238
+
239
+ for (const pkg of packages) {
240
+ const exists = await Bun.file(`${dir}/${pkg}/package.json`).exists();
241
+ if (exists) {
242
+ existing.push(pkg);
243
+ } else {
244
+ missing.push(pkg);
245
+ }
246
+ }
247
+
248
+ return { existing, missing };
249
+ }
package/src/contract.ts CHANGED
@@ -223,6 +223,7 @@ const SyncResultSchema = z.object({
223
223
  status: z.enum(["synced", "error"]),
224
224
  account: z.string(),
225
225
  gateway: z.string(),
226
+ socialUrl: z.string().optional(),
226
227
  hostUrl: z.string(),
227
228
  catalogUpdated: z.boolean(),
228
229
  packagesUpdated: z.array(z.string()),
package/src/lib/sync.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { mkdtemp, rm, cp, mkdir } from "fs/promises";
2
- import { tmpdir } from "os";
3
- import { join, dirname } from "path";
4
1
  import { execa } from "execa";
2
+ import { cp, mkdir, mkdtemp, rm } from "fs/promises";
3
+ import { tmpdir } from "os";
4
+ import { dirname, join } from "path";
5
5
  import type { BosConfig } from "../config";
6
6
 
7
7
  export interface FileSyncResult {
@@ -24,10 +24,14 @@ export async function syncFiles(options: FileSyncOptions): Promise<FileSyncResul
24
24
  const results: FileSyncResult[] = [];
25
25
 
26
26
  for (const pkg of packages) {
27
+ const pkgDir = `${configDir}/${pkg}`;
28
+ const pkgDirExists = await Bun.file(`${pkgDir}/package.json`).exists();
29
+ if (!pkgDirExists) continue;
30
+
27
31
  const appConfig = bosConfig.app[pkg] as {
28
32
  template?: string;
29
33
  files?: string[];
30
- sync?: { dependencies?: boolean; devDependencies?: boolean; scripts?: string[] | true };
34
+ sync?: { dependencies?: boolean; devDependencies?: boolean };
31
35
  };
32
36
 
33
37
  if (!appConfig?.template || !appConfig?.files) {
@@ -44,7 +48,6 @@ export async function syncFiles(options: FileSyncOptions): Promise<FileSyncResul
44
48
  const filesSynced: string[] = [];
45
49
  const depsAdded: string[] = [];
46
50
  const depsUpdated: string[] = [];
47
- const pkgDir = `${configDir}/${pkg}`;
48
51
 
49
52
  for (const file of appConfig.files) {
50
53
  const srcPath = join(tempDir, file);
@@ -53,7 +56,7 @@ export async function syncFiles(options: FileSyncOptions): Promise<FileSyncResul
53
56
  try {
54
57
  const destDir = dirname(destPath);
55
58
  await mkdir(destDir, { recursive: true });
56
- await cp(srcPath, destPath, { force, recursive: true });
59
+ await cp(srcPath, destPath, { force: true, recursive: true });
57
60
  filesSynced.push(file);
58
61
  } catch {
59
62
  }
@@ -103,16 +106,10 @@ export async function syncFiles(options: FileSyncOptions): Promise<FileSyncResul
103
106
  }
104
107
  }
105
108
 
106
- if (syncConfig.scripts && templatePkg.scripts) {
109
+ if (templatePkg.scripts) {
107
110
  if (!localPkg.scripts) localPkg.scripts = {};
108
- const scriptsToSync = syncConfig.scripts === true
109
- ? Object.keys(templatePkg.scripts)
110
- : syncConfig.scripts;
111
-
112
- for (const scriptName of scriptsToSync) {
113
- if (templatePkg.scripts[scriptName]) {
114
- localPkg.scripts[scriptName] = templatePkg.scripts[scriptName];
115
- }
111
+ for (const [name, script] of Object.entries(templatePkg.scripts)) {
112
+ localPkg.scripts[name] = script;
116
113
  }
117
114
  }
118
115
 
package/src/plugin.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createPlugin } from "every-plugin";
2
2
  import { Effect } from "every-plugin/effect";
3
3
  import { z } from "every-plugin/zod";
4
- import { Graph } from "near-social-js";
4
+ import { Graph, calculateRequiredDeposit } from "near-social-js";
5
5
 
6
6
  import { createProcessRegistry } from "./lib/process-registry";
7
7
  import {
@@ -9,6 +9,7 @@ import {
9
9
  type BosConfig as BosConfigType,
10
10
  DEFAULT_DEV_CONFIG,
11
11
  getConfigDir,
12
+ getExistingPackages,
12
13
  getHost,
13
14
  getHostRemoteUrl,
14
15
  getPackages,
@@ -16,6 +17,7 @@ import {
16
17
  getRemotes,
17
18
  loadConfig,
18
19
  type RemoteConfig,
20
+ resolvePackageModes,
19
21
  type SourceMode,
20
22
  setConfig
21
23
  } from "./config";
@@ -197,10 +199,24 @@ export default createPlugin({
197
199
 
198
200
  createRouter: (deps: BosDeps, builder) => ({
199
201
  dev: builder.dev.handler(async ({ input }) => {
202
+ const { modes, autoRemote } = await resolvePackageModes(
203
+ ["host", "ui", "api"],
204
+ { host: input.host, ui: input.ui, api: input.api }
205
+ );
206
+
207
+ if (autoRemote.length > 0) {
208
+ console.log();
209
+ console.log(colors.cyan(` ${icons.config} Auto-detecting packages...`));
210
+ for (const pkg of autoRemote) {
211
+ console.log(colors.dim(` ${pkg} not found locally → using remote`));
212
+ }
213
+ console.log();
214
+ }
215
+
200
216
  const appConfig = buildAppConfig({
201
- host: input.host,
202
- ui: input.ui,
203
- api: input.api,
217
+ host: modes.host,
218
+ ui: modes.ui,
219
+ api: modes.api,
204
220
  proxy: input.proxy,
205
221
  });
206
222
 
@@ -211,6 +227,7 @@ export default createPlugin({
211
227
  status: "error" as const,
212
228
  description: "No remote URL configured for host",
213
229
  processes: [],
230
+ autoRemote,
214
231
  };
215
232
  }
216
233
  }
@@ -363,6 +380,27 @@ export default createPlugin({
363
380
  return {
364
381
  status: "error" as const,
365
382
  built: [],
383
+ skipped: [],
384
+ };
385
+ }
386
+
387
+ const { existing, missing } = await getExistingPackages(targets);
388
+
389
+ if (missing.length > 0) {
390
+ console.log();
391
+ console.log(colors.cyan(` ${icons.config} Auto-detecting packages...`));
392
+ for (const pkg of missing) {
393
+ console.log(colors.dim(` ${pkg} not found locally → skipping`));
394
+ }
395
+ console.log();
396
+ }
397
+
398
+ if (existing.length === 0) {
399
+ console.log(colors.dim(` No packages found locally to build`));
400
+ return {
401
+ status: "error" as const,
402
+ built: [],
403
+ skipped: missing,
366
404
  };
367
405
  }
368
406
 
@@ -384,7 +422,7 @@ export default createPlugin({
384
422
  }
385
423
  }
386
424
 
387
- for (const target of targets) {
425
+ for (const target of existing) {
388
426
  const buildConfig = buildCommands[target];
389
427
  if (!buildConfig) continue;
390
428
 
@@ -404,6 +442,7 @@ export default createPlugin({
404
442
  return {
405
443
  status: "success" as const,
406
444
  built,
445
+ skipped: missing,
407
446
  deployed: buildInput.deploy,
408
447
  };
409
448
  }),
@@ -434,9 +473,29 @@ export default createPlugin({
434
473
  const bosEnv = yield* loadBosEnv;
435
474
  const privateKey = nearPrivateKey || bosEnv.NEAR_PRIVATE_KEY;
436
475
 
437
- const socialArgs = buildSocialSetArgs(account, gatewayDomain, bosConfig);
476
+ const socialArgs = buildSocialSetArgs(account, gatewayDomain, bosConfig) as {
477
+ data: Record<string, Record<string, unknown>>;
478
+ };
438
479
  const argsBase64 = Buffer.from(JSON.stringify(socialArgs)).toString("base64");
439
480
 
481
+ const graph = new Graph({
482
+ network,
483
+ contractId: socialContract,
484
+ });
485
+ const storageBalance = yield* Effect.tryPromise({
486
+ try: () => graph.storageBalanceOf(account),
487
+ catch: () => new Error("Failed to fetch storage balance"),
488
+ });
489
+
490
+ const requiredDeposit = calculateRequiredDeposit({
491
+ data: socialArgs.data,
492
+ storageBalance: storageBalance ? {
493
+ available: BigInt(storageBalance.available),
494
+ total: BigInt(storageBalance.total),
495
+ } : null,
496
+ });
497
+ const depositAmount = requiredDeposit.toFixed();
498
+
440
499
  if (publishInput.dryRun) {
441
500
  return {
442
501
  status: "dry-run" as const,
@@ -453,7 +512,7 @@ export default createPlugin({
453
512
  network,
454
513
  privateKey,
455
514
  gas: "300Tgas",
456
- deposit: "0.05NEAR",
515
+ deposit: depositAmount === "0" ? "1" : depositAmount,
457
516
  });
458
517
 
459
518
  return {
@@ -1228,14 +1287,16 @@ export default createPlugin({
1228
1287
  const DEFAULT_SYNC_ACCOUNT = "every.near";
1229
1288
  const DEFAULT_SYNC_GATEWAY = "everything.dev";
1230
1289
 
1231
- const account = input.account || DEFAULT_SYNC_ACCOUNT;
1232
- const gateway = input.gateway || DEFAULT_SYNC_GATEWAY;
1290
+ const account = input.account || bosConfig?.account || DEFAULT_SYNC_ACCOUNT;
1291
+ const gateway = input.gateway || (bosConfig ? getGatewayDomain(bosConfig) : null) || DEFAULT_SYNC_GATEWAY;
1292
+ const socialUrl = `https://near.social/mob.near/widget/State.Inspector?key=${account}/bos/gateways/${gateway}`;
1233
1293
 
1234
1294
  if (!bosConfig) {
1235
1295
  return {
1236
1296
  status: "error" as const,
1237
1297
  account,
1238
1298
  gateway,
1299
+ socialUrl,
1239
1300
  hostUrl: "",
1240
1301
  catalogUpdated: false,
1241
1302
  packagesUpdated: [],
@@ -1362,10 +1423,12 @@ export default createPlugin({
1362
1423
  const packagesUpdated: string[] = [];
1363
1424
 
1364
1425
  for (const pkg of packages) {
1365
- const pkgPath = `${configDir}/${pkg}/package.json`;
1366
- const pkgFile = Bun.file(pkgPath);
1426
+ const pkgDir = `${configDir}/${pkg}`;
1427
+ const pkgDirExists = await Bun.file(`${pkgDir}/package.json`).exists();
1428
+ if (!pkgDirExists) continue;
1367
1429
 
1368
- if (!(await pkgFile.exists())) continue;
1430
+ const pkgPath = `${pkgDir}/package.json`;
1431
+ const pkgFile = Bun.file(pkgPath);
1369
1432
 
1370
1433
  const pkgJson = await pkgFile.json() as {
1371
1434
  dependencies?: Record<string, string>;
@@ -1413,6 +1476,7 @@ export default createPlugin({
1413
1476
  status: "synced" as const,
1414
1477
  account,
1415
1478
  gateway,
1479
+ socialUrl,
1416
1480
  hostUrl,
1417
1481
  catalogUpdated: true,
1418
1482
  packagesUpdated,