everything-dev 0.0.14 → 0.0.16

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.14",
3
+ "version": "0.0.16",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
package/src/cli.ts CHANGED
@@ -213,8 +213,77 @@ async function main() {
213
213
  .description("Run CLI as HTTP server (exposes /api)")
214
214
  .option("-p, --port <port>", "Port to run on", "4000")
215
215
  .action(async (options) => {
216
- const result = await client.serve({
217
- port: parseInt(options.port, 10),
216
+ const port = parseInt(options.port, 10);
217
+
218
+ const { Hono } = await import("hono");
219
+ const { cors } = await import("hono/cors");
220
+ const { RPCHandler } = await import("@orpc/server/fetch");
221
+ const { OpenAPIHandler } = await import("@orpc/openapi/fetch");
222
+ const { OpenAPIReferencePlugin } = await import("@orpc/openapi/plugins");
223
+ const { ZodToJsonSchemaConverter } = await import("@orpc/zod/zod4");
224
+ const { onError } = await import("every-plugin/orpc");
225
+ const { formatORPCError } = await import("every-plugin/errors");
226
+
227
+ const app = new Hono();
228
+
229
+ app.use("/*", cors({ origin: "*", credentials: true }));
230
+
231
+ const rpcHandler = new RPCHandler(result.router, {
232
+ interceptors: [onError((error: unknown) => formatORPCError(error))],
233
+ });
234
+
235
+ const apiHandler = new OpenAPIHandler(result.router, {
236
+ plugins: [
237
+ new OpenAPIReferencePlugin({
238
+ schemaConverters: [new ZodToJsonSchemaConverter()],
239
+ specGenerateOptions: {
240
+ info: { title: "BOS CLI API", version: "1.0.0" },
241
+ servers: [{ url: `http://localhost:${port}/api` }],
242
+ },
243
+ }),
244
+ ],
245
+ interceptors: [onError((error: unknown) => formatORPCError(error))],
246
+ });
247
+
248
+ app.get("/", (c) => c.json({
249
+ ok: true,
250
+ plugin: "bos-cli",
251
+ status: "ready",
252
+ endpoints: {
253
+ health: "/",
254
+ docs: "/api",
255
+ rpc: "/api/rpc"
256
+ }
257
+ }));
258
+
259
+ app.all("/api/rpc/*", async (c) => {
260
+ const rpcResult = await rpcHandler.handle(c.req.raw, {
261
+ prefix: "/api/rpc",
262
+ context: {},
263
+ });
264
+ return rpcResult.response
265
+ ? new Response(rpcResult.response.body, rpcResult.response)
266
+ : c.text("Not Found", 404);
267
+ });
268
+
269
+ app.all("/api", async (c) => {
270
+ const apiResult = await apiHandler.handle(c.req.raw, {
271
+ prefix: "/api",
272
+ context: {},
273
+ });
274
+ return apiResult.response
275
+ ? new Response(apiResult.response.body, apiResult.response)
276
+ : c.text("Not Found", 404);
277
+ });
278
+
279
+ app.all("/api/*", async (c) => {
280
+ const apiResult = await apiHandler.handle(c.req.raw, {
281
+ prefix: "/api",
282
+ context: {},
283
+ });
284
+ return apiResult.response
285
+ ? new Response(apiResult.response.body, apiResult.response)
286
+ : c.text("Not Found", 404);
218
287
  });
219
288
 
220
289
  console.log();
@@ -222,10 +291,27 @@ async function main() {
222
291
  console.log(` ${icons.run} ${gradients.cyber("CLI SERVER")}`);
223
292
  console.log(colors.cyan(frames.bottom(48)));
224
293
  console.log();
225
- console.log(` ${colors.dim("URL:")} ${colors.white(result.url)}`);
226
- console.log(` ${colors.dim("RPC:")} ${colors.white(result.endpoints.rpc)}`);
227
- console.log(` ${colors.dim("Docs:")} ${colors.white(result.endpoints.docs)}`);
294
+ console.log(` ${colors.dim("URL:")} ${colors.white(`http://localhost:${port}`)}`);
295
+ console.log(` ${colors.dim("RPC:")} ${colors.white(`http://localhost:${port}/api/rpc`)}`);
296
+ console.log(` ${colors.dim("Docs:")} ${colors.white(`http://localhost:${port}/api`)}`);
228
297
  console.log();
298
+
299
+ const server = Bun.serve({
300
+ port,
301
+ fetch: app.fetch,
302
+ });
303
+
304
+ const shutdown = () => {
305
+ console.log();
306
+ console.log(colors.dim(" Shutting down..."));
307
+ server.stop();
308
+ process.exit(0);
309
+ };
310
+
311
+ process.on("SIGINT", shutdown);
312
+ process.on("SIGTERM", shutdown);
313
+
314
+ await new Promise(() => {});
229
315
  });
230
316
 
231
317
  program
@@ -659,8 +745,9 @@ Zephyr Configuration:
659
745
  .description("Sync dependencies and config from everything-dev CLI")
660
746
  .option("--account <account>", "NEAR account to sync from (default: every.near)")
661
747
  .option("--gateway <gateway>", "Gateway domain to sync from (default: everything.dev)")
748
+ .option("--network <network>", "Network: mainnet | testnet", "mainnet")
662
749
  .option("--force", "Force sync even if versions match")
663
- .action(async (options: { account?: string; gateway?: string; force?: boolean }) => {
750
+ .action(async (options: { account?: string; gateway?: string; network?: string; force?: boolean }) => {
664
751
  console.log();
665
752
  const source = options.account || options.gateway
666
753
  ? `${options.account || "every.near"}/${options.gateway || "everything.dev"}`
@@ -670,6 +757,7 @@ Zephyr Configuration:
670
757
  const result = await client.sync({
671
758
  account: options.account,
672
759
  gateway: options.gateway,
760
+ network: (options.network as "mainnet" | "testnet") || "mainnet",
673
761
  force: options.force || false,
674
762
  });
675
763
 
@@ -683,9 +771,8 @@ Zephyr Configuration:
683
771
  console.log(` ${icons.ok} ${gradients.cyber("SYNCED")}`);
684
772
  console.log(colors.cyan(frames.bottom(52)));
685
773
  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)}`);
774
+ console.log(` ${colors.dim("Source:")} ${colors.cyan(`${result.account}/${result.gateway}`)}`);
775
+ console.log(` ${colors.dim("Host URL:")} ${colors.cyan(result.hostUrl)}`);
689
776
  console.log();
690
777
 
691
778
  if (result.catalogUpdated) {
@@ -747,38 +834,161 @@ Zephyr Configuration:
747
834
  console.log();
748
835
  });
749
836
 
750
- depsCmd
751
- .command("sync")
752
- .description("Sync bos.config.json shared deps to package.json catalog")
753
- .argument("[category]", "Dependency category (ui | api)", "ui")
754
- .option("--no-install", "Skip running bun install")
755
- .action(async (category: string, options: { install: boolean }) => {
837
+ program
838
+ .command("kill")
839
+ .description("Kill all tracked BOS processes")
840
+ .option("--force", "Force kill with SIGKILL immediately")
841
+ .action(async (options: { force?: boolean }) => {
842
+ const result = await client.kill({ force: options.force ?? false });
843
+
756
844
  console.log();
757
- console.log(` ${icons.pkg} Syncing shared.${category} to catalog...`);
845
+ if (result.status === "error") {
846
+ console.error(colors.error(`${icons.err} ${result.error || "Failed to kill processes"}`));
847
+ process.exit(1);
848
+ }
758
849
 
759
- const result = await client.depsSync({
760
- category: category as "ui" | "api",
761
- install: options.install,
850
+ if (result.killed.length > 0) {
851
+ console.log(colors.green(`${icons.ok} Killed ${result.killed.length} processes`));
852
+ for (const pid of result.killed) {
853
+ console.log(colors.dim(` PID ${pid}`));
854
+ }
855
+ }
856
+ if (result.failed.length > 0) {
857
+ console.log(colors.error(`${icons.err} Failed to kill ${result.failed.length} processes`));
858
+ for (const pid of result.failed) {
859
+ console.log(colors.dim(` PID ${pid}`));
860
+ }
861
+ }
862
+ if (result.killed.length === 0 && result.failed.length === 0) {
863
+ console.log(colors.dim(" No tracked processes found"));
864
+ }
865
+ console.log();
866
+ });
867
+
868
+ program
869
+ .command("ps")
870
+ .description("List tracked BOS processes")
871
+ .action(async () => {
872
+ const result = await client.ps({});
873
+
874
+ console.log();
875
+ console.log(colors.cyan(frames.top(52)));
876
+ console.log(` ${icons.run} ${gradients.cyber("PROCESSES")}`);
877
+ console.log(colors.cyan(frames.bottom(52)));
878
+ console.log();
879
+
880
+ if (result.processes.length === 0) {
881
+ console.log(colors.dim(" No tracked processes"));
882
+ } else {
883
+ for (const proc of result.processes) {
884
+ const age = Math.round((Date.now() - proc.startedAt) / 1000);
885
+ console.log(` ${colors.white(proc.name)} ${colors.dim(`(PID ${proc.pid})`)}`);
886
+ console.log(` ${colors.dim("Port:")} ${colors.cyan(String(proc.port))}`);
887
+ console.log(` ${colors.dim("Age:")} ${colors.cyan(`${age}s`)}`);
888
+ }
889
+ }
890
+ console.log();
891
+ });
892
+
893
+ const docker = program
894
+ .command("docker")
895
+ .description("Docker container management");
896
+
897
+ docker
898
+ .command("build")
899
+ .description("Build Docker image")
900
+ .option("-t, --target <target>", "Build target: production | development", "production")
901
+ .option("--tag <tag>", "Custom image tag")
902
+ .option("--no-cache", "Build without cache")
903
+ .action(async (options: { target: string; tag?: string; noCache?: boolean }) => {
904
+ console.log();
905
+ console.log(` ${icons.pkg} Building Docker image (${options.target})...`);
906
+
907
+ const result = await client.dockerBuild({
908
+ target: options.target as "production" | "development",
909
+ tag: options.tag,
910
+ noCache: options.noCache ?? false,
762
911
  });
763
912
 
764
913
  if (result.status === "error") {
765
- console.error(colors.error(`${icons.err} ${result.error || "Sync failed"}`));
914
+ console.error(colors.error(`${icons.err} ${result.error || "Build failed"}`));
766
915
  process.exit(1);
767
916
  }
768
917
 
769
918
  console.log();
770
- console.log(colors.green(`${icons.ok} Synced ${result.synced.length} dependencies to catalog`));
771
-
772
- if (result.synced.length > 0) {
773
- for (const name of result.synced) {
774
- console.log(` ${colors.dim("•")} ${name}`);
919
+ console.log(colors.green(`${icons.ok} Built ${result.tag}`));
920
+ console.log();
921
+ });
922
+
923
+ docker
924
+ .command("run")
925
+ .description("Run Docker container")
926
+ .option("-t, --target <target>", "Image target: production | development", "production")
927
+ .option("-m, --mode <mode>", "Run mode: start | serve | dev", "start")
928
+ .option("-p, --port <port>", "Port to expose")
929
+ .option("-d, --detach", "Run in background")
930
+ .option("-e, --env <env...>", "Environment variables (KEY=value)")
931
+ .action(async (options: { target: string; mode: string; port?: string; detach?: boolean; env?: string[] }) => {
932
+ console.log();
933
+ console.log(` ${icons.run} Starting Docker container...`);
934
+
935
+ const envVars: Record<string, string> = {};
936
+ if (options.env) {
937
+ for (const e of options.env) {
938
+ const [key, ...rest] = e.split("=");
939
+ if (key) envVars[key] = rest.join("=");
775
940
  }
776
941
  }
777
942
 
778
- if (options.install) {
779
- console.log(colors.dim(" bun install complete"));
943
+ const result = await client.dockerRun({
944
+ target: options.target as "production" | "development",
945
+ mode: options.mode as "start" | "serve" | "dev",
946
+ port: options.port ? parseInt(options.port, 10) : undefined,
947
+ detach: options.detach ?? false,
948
+ env: Object.keys(envVars).length > 0 ? envVars : undefined,
949
+ });
950
+
951
+ if (result.status === "error") {
952
+ console.error(colors.error(`${icons.err} ${result.error || "Run failed"}`));
953
+ process.exit(1);
954
+ }
955
+
956
+ console.log();
957
+ console.log(colors.green(`${icons.ok} Container running`));
958
+ console.log(` ${colors.dim("URL:")} ${colors.cyan(result.url)}`);
959
+ if (result.containerId !== "attached") {
960
+ console.log(` ${colors.dim("Container:")} ${colors.cyan(result.containerId)}`);
961
+ }
962
+ console.log();
963
+ });
964
+
965
+ docker
966
+ .command("stop")
967
+ .description("Stop Docker container(s)")
968
+ .option("-c, --container <id>", "Container ID to stop")
969
+ .option("-a, --all", "Stop all containers for this app")
970
+ .action(async (options: { container?: string; all?: boolean }) => {
971
+ console.log();
972
+ console.log(` ${icons.pkg} Stopping containers...`);
973
+
974
+ const result = await client.dockerStop({
975
+ containerId: options.container,
976
+ all: options.all ?? false,
977
+ });
978
+
979
+ if (result.status === "error") {
980
+ console.error(colors.error(`${icons.err} ${result.error || "Stop failed"}`));
981
+ process.exit(1);
982
+ }
983
+
984
+ console.log();
985
+ if (result.stopped.length > 0) {
986
+ console.log(colors.green(`${icons.ok} Stopped ${result.stopped.length} container(s)`));
987
+ for (const id of result.stopped) {
988
+ console.log(colors.dim(` ${id}`));
989
+ }
780
990
  } else {
781
- console.log(colors.dim(" Run 'bun install' to update lockfile"));
991
+ console.log(colors.dim(" No containers stopped"));
782
992
  }
783
993
  console.log();
784
994
  });
package/src/contract.ts CHANGED
@@ -2,8 +2,6 @@ import { oc } from "every-plugin/orpc";
2
2
  import { z } from "every-plugin/zod";
3
3
  import {
4
4
  BosConfigSchema,
5
- HostConfigSchema,
6
- RemoteConfigSchema,
7
5
  SourceModeSchema,
8
6
  } from "./types";
9
7
 
@@ -27,6 +25,7 @@ const StartOptionsSchema = z.object({
27
25
  interactive: z.boolean().optional(),
28
26
  account: z.string().optional(),
29
27
  domain: z.string().optional(),
28
+ network: z.enum(["mainnet", "testnet"]).default("mainnet"),
30
29
  });
31
30
 
32
31
  const StartResultSchema = z.object({
@@ -215,17 +214,102 @@ const GatewaySyncResultSchema = z.object({
215
214
  const SyncOptionsSchema = z.object({
216
215
  account: z.string().optional(),
217
216
  gateway: z.string().optional(),
217
+ network: z.enum(["mainnet", "testnet"]).default("mainnet"),
218
218
  force: z.boolean().optional(),
219
+ files: z.boolean().optional(),
219
220
  });
220
221
 
221
222
  const SyncResultSchema = z.object({
222
223
  status: z.enum(["synced", "error"]),
223
224
  account: z.string(),
224
225
  gateway: z.string(),
225
- cliVersion: z.string(),
226
226
  hostUrl: z.string(),
227
227
  catalogUpdated: z.boolean(),
228
228
  packagesUpdated: z.array(z.string()),
229
+ filesSynced: z.array(z.object({
230
+ package: z.string(),
231
+ files: z.array(z.string()),
232
+ })).optional(),
233
+ error: z.string().optional(),
234
+ });
235
+
236
+ const FilesSyncOptionsSchema = z.object({
237
+ packages: z.array(z.string()).optional(),
238
+ force: z.boolean().optional(),
239
+ });
240
+
241
+ const FilesSyncResultSchema = z.object({
242
+ status: z.enum(["synced", "error"]),
243
+ synced: z.array(z.object({
244
+ package: z.string(),
245
+ files: z.array(z.string()),
246
+ depsAdded: z.array(z.string()).optional(),
247
+ depsUpdated: z.array(z.string()).optional(),
248
+ })),
249
+ error: z.string().optional(),
250
+ });
251
+
252
+ const KillOptionsSchema = z.object({
253
+ force: z.boolean().default(false),
254
+ });
255
+
256
+ const KillResultSchema = z.object({
257
+ status: z.enum(["killed", "error"]),
258
+ killed: z.array(z.number()),
259
+ failed: z.array(z.number()),
260
+ error: z.string().optional(),
261
+ });
262
+
263
+ const ProcessStatusSchema = z.object({
264
+ pid: z.number(),
265
+ name: z.string(),
266
+ port: z.number(),
267
+ startedAt: z.number(),
268
+ command: z.string(),
269
+ });
270
+
271
+ const PsResultSchema = z.object({
272
+ status: z.enum(["listed", "error"]),
273
+ processes: z.array(ProcessStatusSchema),
274
+ error: z.string().optional(),
275
+ });
276
+
277
+ const DockerBuildOptionsSchema = z.object({
278
+ target: z.enum(["production", "development"]).default("production"),
279
+ tag: z.string().optional(),
280
+ noCache: z.boolean().default(false),
281
+ });
282
+
283
+ const DockerBuildResultSchema = z.object({
284
+ status: z.enum(["built", "error"]),
285
+ image: z.string(),
286
+ tag: z.string(),
287
+ error: z.string().optional(),
288
+ });
289
+
290
+ const DockerRunOptionsSchema = z.object({
291
+ target: z.enum(["production", "development"]).default("production"),
292
+ mode: z.enum(["start", "serve", "dev"]).default("start"),
293
+ port: z.number().optional(),
294
+ detach: z.boolean().default(false),
295
+ env: z.record(z.string(), z.string()).optional(),
296
+ });
297
+
298
+ const DockerRunResultSchema = z.object({
299
+ status: z.enum(["running", "error"]),
300
+ containerId: z.string(),
301
+ url: z.string(),
302
+ error: z.string().optional(),
303
+ });
304
+
305
+ const DockerStopOptionsSchema = z.object({
306
+ containerId: z.string().optional(),
307
+ all: z.boolean().default(false),
308
+ });
309
+
310
+ const DockerStopResultSchema = z.object({
311
+ status: z.enum(["stopped", "error"]),
312
+ stopped: z.array(z.string()),
229
313
  error: z.string().optional(),
230
314
  });
231
315
 
@@ -245,17 +329,6 @@ const DepsUpdateResultSchema = z.object({
245
329
  error: z.string().optional(),
246
330
  });
247
331
 
248
- const DepsSyncOptionsSchema = z.object({
249
- category: z.enum(["ui", "api"]).default("ui"),
250
- install: z.boolean().default(true),
251
- });
252
-
253
- const DepsSyncResultSchema = z.object({
254
- status: z.enum(["synced", "error"]),
255
- synced: z.array(z.string()),
256
- error: z.string().optional(),
257
- });
258
-
259
332
  export const bosContract = oc.router({
260
333
  dev: oc
261
334
  .route({ method: "POST", path: "/dev" })
@@ -358,10 +431,34 @@ export const bosContract = oc.router({
358
431
  .input(DepsUpdateOptionsSchema)
359
432
  .output(DepsUpdateResultSchema),
360
433
 
361
- depsSync: oc
362
- .route({ method: "POST", path: "/deps/sync" })
363
- .input(DepsSyncOptionsSchema)
364
- .output(DepsSyncResultSchema),
434
+ filesSync: oc
435
+ .route({ method: "POST", path: "/files/sync" })
436
+ .input(FilesSyncOptionsSchema)
437
+ .output(FilesSyncResultSchema),
438
+
439
+ kill: oc
440
+ .route({ method: "POST", path: "/kill" })
441
+ .input(KillOptionsSchema)
442
+ .output(KillResultSchema),
443
+
444
+ ps: oc
445
+ .route({ method: "GET", path: "/ps" })
446
+ .output(PsResultSchema),
447
+
448
+ dockerBuild: oc
449
+ .route({ method: "POST", path: "/docker/build" })
450
+ .input(DockerBuildOptionsSchema)
451
+ .output(DockerBuildResultSchema),
452
+
453
+ dockerRun: oc
454
+ .route({ method: "POST", path: "/docker/run" })
455
+ .input(DockerRunOptionsSchema)
456
+ .output(DockerRunResultSchema),
457
+
458
+ dockerStop: oc
459
+ .route({ method: "POST", path: "/docker/stop" })
460
+ .input(DockerStopOptionsSchema)
461
+ .output(DockerStopResultSchema),
365
462
  });
366
463
 
367
464
  export type BosContract = typeof bosContract;
@@ -398,5 +495,5 @@ export type SyncOptions = z.infer<typeof SyncOptionsSchema>;
398
495
  export type SyncResult = z.infer<typeof SyncResultSchema>;
399
496
  export type DepsUpdateOptions = z.infer<typeof DepsUpdateOptionsSchema>;
400
497
  export type DepsUpdateResult = z.infer<typeof DepsUpdateResultSchema>;
401
- export type DepsSyncOptions = z.infer<typeof DepsSyncOptionsSchema>;
402
- export type DepsSyncResult = z.infer<typeof DepsSyncResultSchema>;
498
+ export type FilesSyncOptions = z.infer<typeof FilesSyncOptionsSchema>;
499
+ export type FilesSyncResult = z.infer<typeof FilesSyncResultSchema>;
package/src/lib/nova.ts CHANGED
@@ -35,7 +35,7 @@ export const getNovaConfig = Effect.gen(function* () {
35
35
 
36
36
  export function createNovaClient(config: NovaConfig): NovaSdk {
37
37
  return new NovaSdk(config.accountId, {
38
- sessionToken: config.sessionToken,
38
+ apiKey: config.sessionToken,
39
39
  });
40
40
  }
41
41
 
@@ -240,7 +240,7 @@ export const removeNovaCredentials = Effect.gen(function* () {
240
240
 
241
241
  export const verifyNovaCredentials = (accountId: string, sessionToken: string) =>
242
242
  Effect.gen(function* () {
243
- const nova = new NovaSdk(accountId, { sessionToken });
243
+ const nova = new NovaSdk(accountId, { apiKey: sessionToken });
244
244
 
245
245
  yield* Effect.tryPromise({
246
246
  try: () => nova.getBalance(),
@@ -12,6 +12,21 @@ import {
12
12
  import { renderStreamingView, type StreamingViewHandle } from "../components/streaming-view";
13
13
  import { getProcessConfig, makeDevProcess, type ProcessCallbacks, type ProcessHandle } from "./process";
14
14
 
15
+ const LOG_NOISE_PATTERNS = [
16
+ /\[ Federation Runtime \] Version .* from host of shared singleton module/,
17
+ /Executing an Effect versioned \d+\.\d+\.\d+ with a Runtime of version/,
18
+ /you may want to dedupe the effect dependencies/,
19
+ ];
20
+
21
+ const isDebugMode = (): boolean => {
22
+ return process.env.DEBUG === "true" || process.env.DEBUG === "1";
23
+ };
24
+
25
+ const shouldDisplayLog = (line: string): boolean => {
26
+ if (isDebugMode()) return true;
27
+ return !LOG_NOISE_PATTERNS.some(pattern => pattern.test(line));
28
+ };
29
+
15
30
  export interface AppOrchestrator {
16
31
  packages: string[];
17
32
  env: Record<string, string>;
@@ -153,7 +168,10 @@ export const runDevServers = (orchestrator: AppOrchestrator) =>
153
168
  isError,
154
169
  };
155
170
  allLogs.push(entry);
156
- view?.addLog(name, line, isError);
171
+
172
+ if (shouldDisplayLog(line)) {
173
+ view?.addLog(name, line, isError);
174
+ }
157
175
 
158
176
  if (logFile) {
159
177
  const logLine = formatLogLine(entry) + "\n";