void 0.10.2 → 0.10.4

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 (69) hide show
  1. package/dist/{auth-cmd-DLvXvN-0.mjs → auth-cmd-CblKzAdD.mjs} +2 -2
  2. package/dist/{better-auth-shared-a7H3wk9J.d.mts → better-auth-shared-jkksALri.d.mts} +2 -2
  3. package/dist/build-cmd-CJQSRupz.mjs +140 -0
  4. package/dist/{cache-CHFZmqa5.mjs → cache-CMzjhxHh.mjs} +1 -1
  5. package/dist/{cancel-deploy-BwpT4U4a.mjs → cancel-deploy-S2N8NSv6.mjs} +1 -1
  6. package/dist/cli/cli.mjs +203 -42
  7. package/dist/{client-CTHvucDv.mjs → client-YIzxv2ZO.mjs} +12 -0
  8. package/dist/{create-project-CruTH_TQ.mjs → create-project-pLQdzEPe.mjs} +1 -1
  9. package/dist/{db-BxnfKs7f.mjs → db-hAmBumot.mjs} +3 -3
  10. package/dist/{delete-IQe1O4Re.mjs → delete-CfSe3EJO.mjs} +1 -1
  11. package/dist/{deploy-CuxXxVgz.mjs → deploy-DpOdwtla.mjs} +3 -3
  12. package/dist/{domain-Bq6kzr_T.mjs → domain-CkowysQx.mjs} +1 -1
  13. package/dist/{env-BD3U_0Av.mjs → env-CIwG2y7G.mjs} +1 -1
  14. package/dist/{env-helpers-ZatKyjen.d.mts → env-helpers-B_ks681T.d.mts} +1 -1
  15. package/dist/{gen-Dgi4D7GC.mjs → gen-q6McxXgE.mjs} +1 -1
  16. package/dist/{github-cmd-CD0Z8KCF.mjs → github-cmd-BvEKQmcD.mjs} +169 -8
  17. package/dist/{handler-DczZlaXR.d.mts → handler-B7rCOy21.d.mts} +3 -3
  18. package/dist/index.d.mts +3 -3
  19. package/dist/index.mjs +5 -5
  20. package/dist/{init-CTe46nIr.mjs → init-CZP69LJu.mjs} +5 -5
  21. package/dist/{link-BGFW4pHD.mjs → link-BKLElphS.mjs} +2 -2
  22. package/dist/{list-CbGxdbe7.mjs → list-B7qXBBjo.mjs} +1 -1
  23. package/dist/{login-v4wle1vn.mjs → login-B3l_sDwT.mjs} +1 -1
  24. package/dist/{logs-BFgY5Vqc.mjs → logs-AXm660MB.mjs} +1 -1
  25. package/dist/{mcp-STKL-uWs.mjs → mcp-D2plINxM.mjs} +1 -1
  26. package/dist/pages/client.d.mts +1 -1
  27. package/dist/pages/head-client.d.mts +1 -1
  28. package/dist/pages/head.d.mts +1 -1
  29. package/dist/pages/index.d.mts +2 -2
  30. package/dist/pages/islands-plugin.d.mts +1 -1
  31. package/dist/pages/protocol.d.mts +2 -2
  32. package/dist/{project-cmd-DZh-vbEL.mjs → project-cmd-InegJruy.mjs} +8 -8
  33. package/dist/{protocol-63PHtCHS.d.mts → protocol-6UZCowS1.d.mts} +3 -3
  34. package/dist/{rollback-o0M0Qo_n.mjs → rollback-CHVE-DeT.mjs} +1 -1
  35. package/dist/runtime/auth.d.mts +1 -1
  36. package/dist/runtime/better-auth-pg.d.mts +1 -1
  37. package/dist/runtime/better-auth.d.mts +1 -1
  38. package/dist/runtime/client-react.d.mts +2 -2
  39. package/dist/runtime/client-solid.d.mts +2 -2
  40. package/dist/runtime/client-svelte.d.mts +2 -2
  41. package/dist/runtime/client-vue.d.mts +2 -2
  42. package/dist/runtime/client.d.mts +2 -2
  43. package/dist/runtime/env-helpers.d.mts +1 -1
  44. package/dist/runtime/env-public-client.d.mts +1 -1
  45. package/dist/runtime/env-public.d.mts +2 -2
  46. package/dist/runtime/fetch-stream.d.mts +1 -1
  47. package/dist/runtime/fetch.d.mts +1 -1
  48. package/dist/runtime/handler.d.mts +1 -1
  49. package/dist/runtime/live.d.mts +2 -2
  50. package/dist/runtime/validator.d.mts +1 -1
  51. package/dist/runtime/ws-server.d.mts +2 -2
  52. package/dist/runtime/ws.d.mts +3 -3
  53. package/dist/{secret-gs_yyGZL.mjs → secret-CVKwIOm3.mjs} +1 -1
  54. package/package.json +2 -2
  55. package/skills/void/docs/guide/pages-routing/markdown.md +12 -0
  56. package/skills/void/docs/node_modules/void/node_modules/@void/md/README.md +2 -1
  57. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-footnote/README.md +135 -0
  58. package/skills/void/docs/reference/cli.md +75 -14
  59. /package/dist/{auth-nEUVHuFI.d.mts → auth-Dz2CCn4T.d.mts} +0 -0
  60. /package/dist/{fetch-error-BQMdPvge.d.mts → fetch-error-B6RaJ-eZ.d.mts} +0 -0
  61. /package/dist/{head-JAH2l3fg.d.mts → head-eOUCWUNy.d.mts} +0 -0
  62. /package/dist/{prepare-DH2WnEpD.mjs → prepare-DRRboRqH.mjs} +0 -0
  63. /package/dist/{providers-BkiAlEad.d.mts → providers-BJIoduK9.d.mts} +0 -0
  64. /package/dist/{runner-pg-BAheiT6v.mjs → runner-pg-EuhrFW3D.mjs} +0 -0
  65. /package/dist/{skills--OMgLmXW.mjs → skills-Dl3u05da.mjs} +0 -0
  66. /package/dist/{standard-schema-BCBv-QaP.d.mts → standard-schema-Cy0lfeWv.d.mts} +0 -0
  67. /package/dist/{subcommand-prompt-ClwpLlKD.mjs → subcommand-prompt-B8ng0FTS.mjs} +0 -0
  68. /package/dist/{types-BnHMXezo.d.mts → types-BodZGegX.d.mts} +0 -0
  69. /package/dist/{yarn-pnp-DhCHHLAz.mjs → yarn-pnp-WLW2IHUY.mjs} +0 -0
@@ -1,6 +1,6 @@
1
- import { f as getToken, g as removeToken, n as PlatformClient } from "./client-CTHvucDv.mjs";
1
+ import { f as getToken, g as removeToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
2
2
  import { c as R } from "./dist-abzUneor.mjs";
3
- import { n as runLoginCommand } from "./login-v4wle1vn.mjs";
3
+ import { n as runLoginCommand } from "./login-B3l_sDwT.mjs";
4
4
  import { execSync } from "node:child_process";
5
5
  //#region src/cli/auth-cmd.ts
6
6
  async function runAuthCommand(root, args) {
@@ -1,5 +1,5 @@
1
- import { i as VoidAuthConfig, n as AuthState } from "./auth-nEUVHuFI.mjs";
2
- import { t as VoidAuthProvider } from "./providers-BkiAlEad.mjs";
1
+ import { i as VoidAuthConfig, n as AuthState } from "./auth-Dz2CCn4T.mjs";
2
+ import { t as VoidAuthProvider } from "./providers-BJIoduK9.mjs";
3
3
  import { DBFieldAttribute } from "better-auth/db";
4
4
  import { BetterAuthOptions, betterAuth } from "better-auth";
5
5
  import { Context } from "hono";
@@ -0,0 +1,140 @@
1
+ import { i as dim, n as cliTitle, s as import_picocolors } from "./output-DeiS4oEX.mjs";
2
+ import { f as getToken, n as PlatformClient, t as PlatformApiError } from "./client-YIzxv2ZO.mjs";
3
+ import { c as R, g as ge, y as ye } from "./dist-abzUneor.mjs";
4
+ import { r as readProjectConfig } from "./project-CH9pdo16.mjs";
5
+ import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-D4O1_fZz.mjs";
6
+ import { appendFileSync, writeFileSync } from "node:fs";
7
+ //#region src/cli/build-cmd.ts
8
+ const POLL_MS = 1e3;
9
+ function sleep(ms) {
10
+ return new Promise((resolve) => setTimeout(resolve, ms));
11
+ }
12
+ /**
13
+ * Classifies a `getBuildLogs` failure during a follow/first-page fetch as fatal
14
+ * (surface + exit) vs transient (retry). A client error (4xx) is permanent —
15
+ * the build is gone, access was revoked, or the CLI is too old (426
16
+ * `cli_outdated`) — so retrying can't fix it; it is fatal, matching how the rest
17
+ * of the CLI surfaces 426 (see `deploy-errors.ts`, `github-cmd.ts`). The sole
18
+ * exception is 429 (rate limit), which IS transient. Everything else
19
+ * (5xx/timeout/DO-read blip) is transient and retried through.
20
+ */
21
+ function isFatalFollowError(err) {
22
+ return err instanceof PlatformApiError && err.status >= 400 && err.status < 500 && err.status !== 429;
23
+ }
24
+ /**
25
+ * Pure follow-loop: repeatedly fetch pages since a cursor, write each new
26
+ * line, and stop when the build reaches a terminal status. `fetchPage`,
27
+ * `write`, and `sleep` are injected so this is unit-testable. Returns the
28
+ * final status + terminal flag.
29
+ *
30
+ * A transient `fetchPage` failure (502/timeout/DO-read blip) must NOT kill the
31
+ * live tail: on catch we consult the injected `isFatal` — a fatal error
32
+ * (e.g. 401/403/404) rethrows, otherwise we call `onRetry` and retry from the
33
+ * SAME cursor on the next tick (no cursor advance, no write), so the tail
34
+ * survives blips instead of exiting the CLI.
35
+ */
36
+ async function followBuildLogs(opts) {
37
+ let cursor = opts.since;
38
+ let status = opts.status;
39
+ const pollMs = opts.pollMs ?? POLL_MS;
40
+ for (;;) {
41
+ await opts.sleep(pollMs);
42
+ let pageResult;
43
+ try {
44
+ pageResult = await opts.fetchPage(cursor);
45
+ } catch (err) {
46
+ if (opts.isFatal?.(err)) throw err;
47
+ opts.onRetry?.(err);
48
+ continue;
49
+ }
50
+ for (const l of pageResult.lines) opts.write(l.line);
51
+ cursor = pageResult.lastSeq;
52
+ status = pageResult.status;
53
+ if (pageResult.terminal) return {
54
+ status,
55
+ terminal: true
56
+ };
57
+ }
58
+ }
59
+ async function runBuildCommand(root, args) {
60
+ if (args.subcommand === "logs") return runBuildLogsCommand(root, args);
61
+ }
62
+ async function runBuildLogsCommand(root, args) {
63
+ console.log();
64
+ ge(cliTitle("build logs"));
65
+ const token = getToken(root);
66
+ if (!token) {
67
+ R.error("Not logged in. Run `void auth login` first.");
68
+ process.exit(1);
69
+ }
70
+ const client = new PlatformClient(token, { root });
71
+ let projectId;
72
+ const requestedSlug = getRequestedProjectSlug({ projectSlug: args.projectName });
73
+ if (requestedSlug) {
74
+ const resolved = resolveProjectBySlug(await client.listProjects(), requestedSlug);
75
+ if (!resolved) {
76
+ R.error(`build: No project found with slug '${requestedSlug}'.`);
77
+ process.exit(1);
78
+ }
79
+ projectId = resolved.projectId;
80
+ } else {
81
+ const linked = readProjectConfig(root);
82
+ if (!linked) {
83
+ R.error("build: No project specified. Pass a project with --project <slug>, set VOID_PROJECT, or link one with `void project link`.");
84
+ process.exit(1);
85
+ }
86
+ projectId = linked.projectId;
87
+ }
88
+ let buildId = args.buildId;
89
+ if (!buildId) {
90
+ const builds = await client.listBuilds(projectId, 1);
91
+ if (builds.length === 0) {
92
+ ye("No builds found. Push to your connected branch to trigger one.");
93
+ return;
94
+ }
95
+ buildId = builds[0].id;
96
+ }
97
+ const write = args.output ? (line) => appendFileSync(args.output, `${line}\n`) : (line) => console.log(line);
98
+ const onRetry = (err) => R.warn(`build: transient error while following (${err instanceof Error ? err.message : String(err)}); retrying…`);
99
+ let first;
100
+ for (;;) try {
101
+ first = await client.getBuildLogs(projectId, buildId, 0);
102
+ break;
103
+ } catch (err) {
104
+ if (isFatalFollowError(err)) {
105
+ if (err instanceof PlatformApiError && err.status === 404) R.error(`build: Build '${buildId}' not found for this project.`);
106
+ else R.error(err instanceof Error ? err.message : String(err));
107
+ process.exit(1);
108
+ }
109
+ if (!args.follow) {
110
+ R.error(err instanceof Error ? err.message : String(err));
111
+ process.exit(1);
112
+ }
113
+ onRetry(err);
114
+ await sleep(POLL_MS);
115
+ }
116
+ if (first.external) {
117
+ R.message(`This build ran on GitHub Actions. View logs:\n${import_picocolors.default.cyan(first.external)}`);
118
+ return;
119
+ }
120
+ if (args.output) writeFileSync(args.output, "");
121
+ for (const l of first.lines) write(l.line);
122
+ let status = first.status;
123
+ let terminal = first.terminal;
124
+ if (args.follow && !terminal) ({status, terminal} = await followBuildLogs({
125
+ fetchPage: (since) => client.getBuildLogs(projectId, buildId, since),
126
+ write,
127
+ sleep,
128
+ since: first.lastSeq,
129
+ status,
130
+ isFatal: isFatalFollowError,
131
+ onRetry
132
+ }));
133
+ if (!terminal) {
134
+ ye(dim("Build still running — pass -f to follow."));
135
+ return;
136
+ }
137
+ ye(dim(`Build ${status}.`));
138
+ }
139
+ //#endregion
140
+ export { runBuildCommand };
@@ -1,5 +1,5 @@
1
1
  import { i as dim, n as cliTitle, r as createSpinner } from "./output-DeiS4oEX.mjs";
2
- import { f as getToken, n as PlatformClient } from "./client-CTHvucDv.mjs";
2
+ import { f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
3
3
  import { c as R, g as ge, y as ye } from "./dist-abzUneor.mjs";
4
4
  import { r as readProjectConfig } from "./project-CH9pdo16.mjs";
5
5
  import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-D4O1_fZz.mjs";
@@ -1,5 +1,5 @@
1
1
  import { n as cliTitle } from "./output-DeiS4oEX.mjs";
2
- import { f as getToken, n as PlatformClient } from "./client-CTHvucDv.mjs";
2
+ import { f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
3
3
  import { c as R, g as ge, v as ue, x as q, y as ye } from "./dist-abzUneor.mjs";
4
4
  import { r as readProjectConfig } from "./project-CH9pdo16.mjs";
5
5
  //#region src/cli/cancel-deploy.ts
package/dist/cli/cli.mjs CHANGED
@@ -74,6 +74,46 @@ function parseAuthArgs(args) {
74
74
  return { subcommand };
75
75
  }
76
76
  //#endregion
77
+ //#region src/cli/build-args.ts
78
+ const buildSubcommands = [{
79
+ name: "logs",
80
+ arg: "[build]",
81
+ description: "Stream, tail, or download logs for a build"
82
+ }];
83
+ function parseBuildArgs(args) {
84
+ const subcommand = args[0];
85
+ const rest = args.slice(1);
86
+ if (subcommand !== "logs") throw new Error("build: Usage: void build logs [build] [--follow] [--output <file>] [--project <slug>].");
87
+ let buildId;
88
+ let follow = false;
89
+ let output;
90
+ let projectName;
91
+ for (let i = 0; i < rest.length; i++) {
92
+ const arg = rest[i];
93
+ if (arg === "-f" || arg === "--follow") follow = true;
94
+ else if (arg === "-o" || arg === "--output") {
95
+ if (i + 1 >= rest.length) throw new Error("build: --output requires a value.");
96
+ const value = rest[++i];
97
+ if (value.trim() === "") throw new Error("build: --output requires a value.");
98
+ output = value;
99
+ } else if (arg === "-p" || arg === "--project") {
100
+ if (i + 1 >= rest.length) throw new Error("build: --project requires a value.");
101
+ const value = rest[++i];
102
+ if (value.trim() === "") throw new Error("build: --project requires a value.");
103
+ projectName = value;
104
+ } else if (arg.startsWith("-")) throw new Error(`build: Unexpected argument '${arg}'.`);
105
+ else if (buildId) throw new Error(`build: Unexpected argument '${arg}'.`);
106
+ else buildId = arg;
107
+ }
108
+ return {
109
+ subcommand,
110
+ buildId,
111
+ follow,
112
+ output,
113
+ projectName
114
+ };
115
+ }
116
+ //#endregion
77
117
  //#region src/cli/db-args.ts
78
118
  const dbSubcommands = [
79
119
  {
@@ -593,7 +633,12 @@ const githubSubcommands = [
593
633
  {
594
634
  name: "update",
595
635
  arg: "[project]",
596
- description: "Update an existing connection's branch or build executor"
636
+ description: "Update an existing connection's branch, build executor, or deploy workflow"
637
+ },
638
+ {
639
+ name: "status",
640
+ arg: "[project]",
641
+ description: "Show a project's GitHub connection (repo, branch, executor, workflow)"
597
642
  },
598
643
  {
599
644
  name: "link",
@@ -620,6 +665,7 @@ function parseGithubArgs(args) {
620
665
  let repo;
621
666
  let branch;
622
667
  let executor;
668
+ let workflowPath;
623
669
  for (let i = 0; i < rest.length; i++) {
624
670
  const arg = rest[i];
625
671
  if (arg === "--installation") {
@@ -649,6 +695,11 @@ function parseGithubArgs(args) {
649
695
  if (value.trim() === "") throw new Error("github: --executor requires a value.");
650
696
  if (value !== "container" && value !== "github_actions") throw new Error("github: invalid --executor (expected container|github_actions).");
651
697
  executor = value;
698
+ } else if (arg === "--workflow") {
699
+ if (i + 1 >= rest.length) throw new Error("github: --workflow requires a value.");
700
+ const value = rest[++i];
701
+ if (value.trim() === "") throw new Error("github: --workflow requires a value.");
702
+ workflowPath = value.trim();
652
703
  } else if (arg.startsWith("-")) throw new Error(`github: Unexpected argument '${arg}'.`);
653
704
  else if (projectName) throw new Error(`github: Unexpected argument '${arg}'.`);
654
705
  else projectName = arg;
@@ -659,13 +710,15 @@ function parseGithubArgs(args) {
659
710
  installationId,
660
711
  repo,
661
712
  branch,
662
- executor
713
+ executor,
714
+ workflowPath
663
715
  };
664
716
  }
665
717
  if (subcommand === "update") {
666
718
  let projectName = "";
667
719
  let branch;
668
720
  let executor;
721
+ let workflowPath;
669
722
  for (let i = 0; i < rest.length; i++) {
670
723
  const arg = rest[i];
671
724
  if (arg === "--branch") {
@@ -685,6 +738,11 @@ function parseGithubArgs(args) {
685
738
  if (value.trim() === "") throw new Error("github: --executor requires a value.");
686
739
  if (value !== "container" && value !== "github_actions") throw new Error("github: invalid --executor (expected container|github_actions).");
687
740
  executor = value;
741
+ } else if (arg === "--workflow") {
742
+ if (i + 1 >= rest.length) throw new Error("github: --workflow requires a value.");
743
+ const value = rest[++i];
744
+ if (value.trim() === "") throw new Error("github: --workflow requires a value.");
745
+ workflowPath = value.trim();
688
746
  } else if (arg.startsWith("-")) throw new Error(`github: Unexpected argument '${arg}'.`);
689
747
  else if (projectName) throw new Error(`github: Unexpected argument '${arg}'.`);
690
748
  else projectName = arg;
@@ -693,10 +751,30 @@ function parseGithubArgs(args) {
693
751
  subcommand,
694
752
  projectName,
695
753
  branch,
696
- executor
754
+ executor,
755
+ workflowPath
697
756
  };
698
757
  }
699
- throw new Error("github: Usage: void github <install|installations|connect|update|link>.");
758
+ if (subcommand === "status") {
759
+ let projectName = "";
760
+ for (let i = 0; i < rest.length; i++) {
761
+ const arg = rest[i];
762
+ if (arg === "--project") {
763
+ if (i + 1 >= rest.length) throw new Error("github: --project requires a value.");
764
+ const value = rest[++i];
765
+ if (value.trim() === "") throw new Error("github: --project requires a value.");
766
+ if (projectName) throw new Error(`github: Unexpected argument '${value}'.`);
767
+ projectName = value;
768
+ } else if (arg.startsWith("-")) throw new Error(`github: Unexpected argument '${arg}'.`);
769
+ else if (projectName) throw new Error(`github: Unexpected argument '${arg}'.`);
770
+ else projectName = arg;
771
+ }
772
+ return {
773
+ subcommand,
774
+ projectName
775
+ };
776
+ }
777
+ throw new Error("github: Usage: void github <install|installations|connect|update|status|link>.");
700
778
  }
701
779
  //#endregion
702
780
  //#region src/cli/ascii.ts
@@ -1008,7 +1086,11 @@ const HELP_TREE = {
1008
1086
  },
1009
1087
  {
1010
1088
  command: "update [project]",
1011
- description: "Update an existing connection's branch or build executor"
1089
+ description: "Update an existing connection's branch, build executor, or deploy workflow"
1090
+ },
1091
+ {
1092
+ command: "status [project]",
1093
+ description: "Show a project's GitHub connection (repo, branch, executor, workflow)"
1012
1094
  },
1013
1095
  {
1014
1096
  command: "link",
@@ -1041,19 +1123,30 @@ const HELP_TREE = {
1041
1123
  },
1042
1124
  {
1043
1125
  command: "--executor <type>",
1044
- description: "Build executor: container (default) | github_actions"
1126
+ description: "Build executor: container (default) | github_actions; prompted interactively when omitted"
1127
+ },
1128
+ {
1129
+ command: "--workflow <path>",
1130
+ description: "Authorized deploy workflow file (default .github/workflows/void-deploy.yml); prompted interactively when using github_actions"
1045
1131
  }
1046
1132
  ],
1047
- examples: [{
1048
- command: "void github connect [project]",
1049
- description: "Connect a repository to a project"
1050
- }, {
1051
- command: "void github connect my-app --installation 42 --repo owner/repo --branch main",
1052
- description: "Non-interactive connect (all flags explicit)"
1053
- }]
1133
+ examples: [
1134
+ {
1135
+ command: "void github connect [project]",
1136
+ description: "Connect a repository to a project"
1137
+ },
1138
+ {
1139
+ command: "void github connect my-app --installation 42 --repo owner/repo --branch main",
1140
+ description: "Non-interactive connect (all flags explicit)"
1141
+ },
1142
+ {
1143
+ command: "void github connect my-app --repo owner/repo --branch main --executor github_actions",
1144
+ description: "Non-interactive connect using the GitHub Actions executor"
1145
+ }
1146
+ ]
1054
1147
  },
1055
1148
  update: {
1056
- summary: "Update an existing connection's branch or build executor.",
1149
+ summary: "Update an existing connection's branch, build executor, or deploy workflow.",
1057
1150
  usage: ["void github update [project] [options]"],
1058
1151
  options: [
1059
1152
  {
@@ -1066,7 +1159,11 @@ const HELP_TREE = {
1066
1159
  },
1067
1160
  {
1068
1161
  command: "--executor <type>",
1069
- description: "New build executor: container | github_actions"
1162
+ description: "New build executor: container | github_actions; prompted interactively when omitted"
1163
+ },
1164
+ {
1165
+ command: "--workflow <path>",
1166
+ description: "New authorized deploy workflow file under .github/workflows/; prompted interactively when using github_actions"
1070
1167
  }
1071
1168
  ],
1072
1169
  examples: [{
@@ -1076,9 +1173,64 @@ const HELP_TREE = {
1076
1173
  command: "void github update my-app --branch release",
1077
1174
  description: "Change the deploy branch"
1078
1175
  }]
1176
+ },
1177
+ status: {
1178
+ summary: "Show a project's GitHub connection settings.",
1179
+ usage: ["void github status [project] [options]"],
1180
+ options: [{
1181
+ command: "--project <name>",
1182
+ description: "Project name (alias for positional)"
1183
+ }],
1184
+ examples: [{
1185
+ command: "void github status",
1186
+ description: "Show the linked project's connection"
1187
+ }, {
1188
+ command: "void github status my-app",
1189
+ description: "Show a specific project connection"
1190
+ }]
1079
1191
  }
1080
1192
  }
1081
1193
  },
1194
+ build: {
1195
+ summary: "Inspect remote builds.",
1196
+ usage: ["void build <command>"],
1197
+ commands: [{
1198
+ command: "logs [build]",
1199
+ description: "Stream, tail, or download logs for a build"
1200
+ }],
1201
+ children: { logs: {
1202
+ summary: "Stream, tail, or download logs for a build.",
1203
+ usage: ["void build logs [build] [options]"],
1204
+ options: [
1205
+ {
1206
+ command: "--follow, -f",
1207
+ description: "Live-tail until the build finishes"
1208
+ },
1209
+ {
1210
+ command: "--output <file>, -o",
1211
+ description: "Write logs to a file instead of stdout"
1212
+ },
1213
+ {
1214
+ command: "--project <slug>, -p",
1215
+ description: "Target project (else linked / VOID_PROJECT)"
1216
+ }
1217
+ ],
1218
+ examples: [
1219
+ {
1220
+ command: "void build logs",
1221
+ description: "Print the latest build's logs"
1222
+ },
1223
+ {
1224
+ command: "void build logs -f",
1225
+ description: "Follow the latest build until it finishes"
1226
+ },
1227
+ {
1228
+ command: "void build logs bld_123 -o build.log",
1229
+ description: "Download a build's logs to a file"
1230
+ }
1231
+ ]
1232
+ } }
1233
+ },
1082
1234
  db: {
1083
1235
  summary: "Manage local and remote database state.",
1084
1236
  usage: ["void db <command>"],
@@ -1387,6 +1539,8 @@ function printGlobalHelp() {
1387
1539
  "",
1388
1540
  ...globalCommandGroup("github"),
1389
1541
  "",
1542
+ ...globalCommandGroup("build"),
1543
+ "",
1390
1544
  categoryTitle("database"),
1391
1545
  ...globalCommandLines("db", {
1392
1546
  execute: "execute <sql>",
@@ -1754,7 +1908,7 @@ async function runSubcommandGroup(command, subcommands, parse, run) {
1754
1908
  const sub = args[1];
1755
1909
  try {
1756
1910
  if ((!sub || sub.startsWith("-")) && process.stdin.isTTY) {
1757
- const { promptSubcommand } = await import("../subcommand-prompt-ClwpLlKD.mjs");
1911
+ const { promptSubcommand } = await import("../subcommand-prompt-B8ng0FTS.mjs");
1758
1912
  const result = await promptSubcommand(command, subcommands);
1759
1913
  if (!result) process.exit(0);
1760
1914
  await run(root, parse(buildArgs(result, args.slice(1))));
@@ -1783,7 +1937,7 @@ else if (command === "deploy") {
1783
1937
  R.error(err instanceof Error ? err.message : String(err));
1784
1938
  process.exit(1);
1785
1939
  }
1786
- import("../deploy-CuxXxVgz.mjs").then((n) => n.t).then(({ runDeploy }) => {
1940
+ import("../deploy-DpOdwtla.mjs").then((n) => n.t).then(({ runDeploy }) => {
1787
1941
  runDeploy(root, {
1788
1942
  projectSlug: deployArgs.projectSlug,
1789
1943
  dir: deployArgs.dir,
@@ -1795,14 +1949,15 @@ else if (command === "deploy") {
1795
1949
  process.exit(1);
1796
1950
  });
1797
1951
  });
1798
- } else if (command === "auth") runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (root, parsed) => import("../auth-cmd-DLvXvN-0.mjs").then(({ runAuthCommand }) => runAuthCommand(root, parsed)));
1799
- else if (command === "project") runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (root, parsed) => import("../project-cmd-DZh-vbEL.mjs").then(({ runProjectCommand }) => runProjectCommand(root, parsed)));
1800
- else if (command === "secret") runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (root, parsed) => import("../secret-gs_yyGZL.mjs").then(({ runSecretCommand }) => runSecretCommand(root, parsed)));
1801
- else if (command === "domain") runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (root, parsed) => import("../domain-Bq6kzr_T.mjs").then(({ runDomainCommand }) => runDomainCommand(root, parsed)));
1802
- else if (command === "db") runSubcommandGroup("db", dbSubcommands, parseDbArgs, (root, parsed) => import("../db-BxnfKs7f.mjs").then(({ runDbCommand }) => runDbCommand(root, parsed)));
1803
- else if (command === "env") runSubcommandGroup("env", envSubcommands, parseEnvArgs, (root, parsed) => import("../env-BD3U_0Av.mjs").then(({ runEnvCommand }) => runEnvCommand(root, parsed)));
1804
- else if (command === "gen") runSubcommandGroup("gen", genSubcommands, parseGenArgs, (root, parsed) => import("../gen-Dgi4D7GC.mjs").then(({ runGenCommand }) => runGenCommand(root, parsed)));
1805
- else if (command === "github") runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (root, parsed) => import("../github-cmd-CD0Z8KCF.mjs").then(({ runGithubCommand }) => runGithubCommand(root, parsed)));
1952
+ } else if (command === "auth") runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (root, parsed) => import("../auth-cmd-CblKzAdD.mjs").then(({ runAuthCommand }) => runAuthCommand(root, parsed)));
1953
+ else if (command === "project") runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (root, parsed) => import("../project-cmd-InegJruy.mjs").then(({ runProjectCommand }) => runProjectCommand(root, parsed)));
1954
+ else if (command === "secret") runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (root, parsed) => import("../secret-CVKwIOm3.mjs").then(({ runSecretCommand }) => runSecretCommand(root, parsed)));
1955
+ else if (command === "domain") runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (root, parsed) => import("../domain-CkowysQx.mjs").then(({ runDomainCommand }) => runDomainCommand(root, parsed)));
1956
+ else if (command === "db") runSubcommandGroup("db", dbSubcommands, parseDbArgs, (root, parsed) => import("../db-hAmBumot.mjs").then(({ runDbCommand }) => runDbCommand(root, parsed)));
1957
+ else if (command === "env") runSubcommandGroup("env", envSubcommands, parseEnvArgs, (root, parsed) => import("../env-CIwG2y7G.mjs").then(({ runEnvCommand }) => runEnvCommand(root, parsed)));
1958
+ else if (command === "gen") runSubcommandGroup("gen", genSubcommands, parseGenArgs, (root, parsed) => import("../gen-q6McxXgE.mjs").then(({ runGenCommand }) => runGenCommand(root, parsed)));
1959
+ else if (command === "github") runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (root, parsed) => import("../github-cmd-BvEKQmcD.mjs").then(({ runGithubCommand }) => runGithubCommand(root, parsed)));
1960
+ else if (command === "build") runSubcommandGroup("build", buildSubcommands, parseBuildArgs, (root, parsed) => import("../build-cmd-CJQSRupz.mjs").then(({ runBuildCommand }) => runBuildCommand(root, parsed)));
1806
1961
  else if (command === "prepare") {
1807
1962
  const root = process.cwd();
1808
1963
  let prepareArgs;
@@ -1812,7 +1967,7 @@ else if (command === "prepare") {
1812
1967
  R.error(err instanceof Error ? err.message : String(err));
1813
1968
  process.exit(1);
1814
1969
  }
1815
- import("../prepare-DH2WnEpD.mjs").then(({ runPrepareCommand }) => {
1970
+ import("../prepare-DRRboRqH.mjs").then(({ runPrepareCommand }) => {
1816
1971
  runPrepareCommand(root, prepareArgs).catch((err) => {
1817
1972
  R.error(err.message ?? err);
1818
1973
  process.exit(1);
@@ -1820,7 +1975,7 @@ else if (command === "prepare") {
1820
1975
  });
1821
1976
  } else if (command === "init") {
1822
1977
  const root = process.cwd();
1823
- import("../init-CTe46nIr.mjs").then(({ runInitCommand, parseInitArgs }) => {
1978
+ import("../init-CZP69LJu.mjs").then(({ runInitCommand, parseInitArgs }) => {
1824
1979
  let initArgs;
1825
1980
  try {
1826
1981
  initArgs = parseInitArgs(args.slice(1));
@@ -1833,7 +1988,7 @@ else if (command === "prepare") {
1833
1988
  process.exit(1);
1834
1989
  });
1835
1990
  });
1836
- } else if (command === "mcp") import("../mcp-STKL-uWs.mjs").then(({ runMcp }) => {
1991
+ } else if (command === "mcp") import("../mcp-D2plINxM.mjs").then(({ runMcp }) => {
1837
1992
  runMcp();
1838
1993
  });
1839
1994
  else if (command === "-v" || command === "--version") {
@@ -1874,9 +2029,14 @@ else if (command === "-v" || command === "--version") {
1874
2029
  },
1875
2030
  {
1876
2031
  name: "github",
1877
- hint: "install | installations | connect | update | link",
2032
+ hint: "install | installations | connect | update | status | link",
1878
2033
  description: "Connect a GitHub repository for automatic deploys"
1879
2034
  },
2035
+ {
2036
+ name: "build",
2037
+ hint: "logs",
2038
+ description: "Inspect remote builds"
2039
+ },
1880
2040
  {
1881
2041
  name: "db",
1882
2042
  hint: "status | reset | seed | execute | migrate | studio | export | rename-migrations",
@@ -1907,37 +2067,38 @@ else if (command === "-v" || command === "--version") {
1907
2067
  ];
1908
2068
  (async () => {
1909
2069
  printVoidHeader();
1910
- const { promptSubcommand } = await import("../subcommand-prompt-ClwpLlKD.mjs");
2070
+ const { promptSubcommand } = await import("../subcommand-prompt-B8ng0FTS.mjs");
1911
2071
  const result = await promptSubcommand("", topLevelCommands);
1912
2072
  if (!result) process.exit(0);
1913
2073
  const cmd = result.subcommand;
1914
2074
  const root = process.cwd();
1915
2075
  switch (cmd) {
1916
2076
  case "init": {
1917
- const { runInitCommand, parseInitArgs } = await import("../init-CTe46nIr.mjs");
2077
+ const { runInitCommand, parseInitArgs } = await import("../init-CZP69LJu.mjs");
1918
2078
  await runInitCommand(root, parseInitArgs([]));
1919
2079
  return;
1920
2080
  }
1921
2081
  case "deploy": {
1922
- const { runDeploy } = await import("../deploy-CuxXxVgz.mjs").then((n) => n.t);
2082
+ const { runDeploy } = await import("../deploy-DpOdwtla.mjs").then((n) => n.t);
1923
2083
  await runDeploy(root);
1924
2084
  return;
1925
2085
  }
1926
2086
  case "mcp": {
1927
- const { runMcp } = await import("../mcp-STKL-uWs.mjs");
2087
+ const { runMcp } = await import("../mcp-D2plINxM.mjs");
1928
2088
  runMcp();
1929
2089
  return;
1930
2090
  }
1931
- case "auth": return runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (r, p) => import("../auth-cmd-DLvXvN-0.mjs").then(({ runAuthCommand }) => runAuthCommand(r, p)));
1932
- case "project": return runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (r, p) => import("../project-cmd-DZh-vbEL.mjs").then(({ runProjectCommand }) => runProjectCommand(r, p)));
1933
- case "secret": return runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (r, p) => import("../secret-gs_yyGZL.mjs").then(({ runSecretCommand }) => runSecretCommand(r, p)));
1934
- case "domain": return runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (r, p) => import("../domain-Bq6kzr_T.mjs").then(({ runDomainCommand }) => runDomainCommand(r, p)));
1935
- case "github": return runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (r, p) => import("../github-cmd-CD0Z8KCF.mjs").then(({ runGithubCommand }) => runGithubCommand(r, p)));
1936
- case "db": return runSubcommandGroup("db", dbSubcommands, parseDbArgs, (r, p) => import("../db-BxnfKs7f.mjs").then(({ runDbCommand }) => runDbCommand(r, p)));
1937
- case "env": return runSubcommandGroup("env", envSubcommands, parseEnvArgs, (r, p) => import("../env-BD3U_0Av.mjs").then(({ runEnvCommand }) => runEnvCommand(r, p)));
1938
- case "gen": return runSubcommandGroup("gen", genSubcommands, parseGenArgs, (r, p) => import("../gen-Dgi4D7GC.mjs").then(({ runGenCommand }) => runGenCommand(r, p)));
2091
+ case "auth": return runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (r, p) => import("../auth-cmd-CblKzAdD.mjs").then(({ runAuthCommand }) => runAuthCommand(r, p)));
2092
+ case "project": return runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (r, p) => import("../project-cmd-InegJruy.mjs").then(({ runProjectCommand }) => runProjectCommand(r, p)));
2093
+ case "secret": return runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (r, p) => import("../secret-CVKwIOm3.mjs").then(({ runSecretCommand }) => runSecretCommand(r, p)));
2094
+ case "domain": return runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (r, p) => import("../domain-CkowysQx.mjs").then(({ runDomainCommand }) => runDomainCommand(r, p)));
2095
+ case "github": return runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (r, p) => import("../github-cmd-BvEKQmcD.mjs").then(({ runGithubCommand }) => runGithubCommand(r, p)));
2096
+ case "build": return runSubcommandGroup("build", buildSubcommands, parseBuildArgs, (r, p) => import("../build-cmd-CJQSRupz.mjs").then(({ runBuildCommand }) => runBuildCommand(r, p)));
2097
+ case "db": return runSubcommandGroup("db", dbSubcommands, parseDbArgs, (r, p) => import("../db-hAmBumot.mjs").then(({ runDbCommand }) => runDbCommand(r, p)));
2098
+ case "env": return runSubcommandGroup("env", envSubcommands, parseEnvArgs, (r, p) => import("../env-CIwG2y7G.mjs").then(({ runEnvCommand }) => runEnvCommand(r, p)));
2099
+ case "gen": return runSubcommandGroup("gen", genSubcommands, parseGenArgs, (r, p) => import("../gen-q6McxXgE.mjs").then(({ runGenCommand }) => runGenCommand(r, p)));
1939
2100
  case "prepare": {
1940
- const { runPrepareCommand } = await import("../prepare-DH2WnEpD.mjs");
2101
+ const { runPrepareCommand } = await import("../prepare-DRRboRqH.mjs");
1941
2102
  await runPrepareCommand(root, parsePrepareArgs([]));
1942
2103
  return;
1943
2104
  }
@@ -839,6 +839,18 @@ var PlatformClient = class {
839
839
  if (!res.ok) await throwPlatformApiError("Failed to fetch logs", res);
840
840
  return (await res.json()).data;
841
841
  }
842
+ async listBuilds(projectId, limit = 20) {
843
+ const params = new URLSearchParams({ limit: String(limit) });
844
+ const res = await fetch(`${this.baseUrl}/projects/${projectId}/builds?${params}`, { headers: { ...this.authHeaders } });
845
+ if (!res.ok) await throwPlatformApiError("Failed to list builds", res);
846
+ return (await res.json()).builds;
847
+ }
848
+ async getBuildLogs(projectId, buildId, since = 0) {
849
+ const params = new URLSearchParams({ since: String(since) });
850
+ const res = await fetch(`${this.baseUrl}/projects/${projectId}/builds/${buildId}/logs?${params}`, { headers: { ...this.authHeaders } });
851
+ if (!res.ok) await throwPlatformApiError("Failed to fetch build logs", res);
852
+ return res.json();
853
+ }
842
854
  async getGithubInstallUrl() {
843
855
  const res = await fetch(`${this.baseUrl}/github/install-url`, { headers: { ...this.authHeaders } });
844
856
  if (!res.ok) await throwPlatformApiError("Failed to get GitHub install URL", res);
@@ -1,6 +1,6 @@
1
1
  import { n as __exportAll } from "./chunk-DJd-R1mw.mjs";
2
2
  import { s as import_picocolors } from "./output-DeiS4oEX.mjs";
3
- import { d as getSiteDomain, t as PlatformApiError } from "./client-CTHvucDv.mjs";
3
+ import { d as getSiteDomain, t as PlatformApiError } from "./client-YIzxv2ZO.mjs";
4
4
  import { _ as me, c as R, i as Ee, l as Re, v as ue, x as q } from "./dist-abzUneor.mjs";
5
5
  import { a as writeProjectConfig } from "./project-CH9pdo16.mjs";
6
6
  import { n as validateProjectSlug } from "./project-slug-rX3kTOfY.mjs";
@@ -2,7 +2,7 @@ import { a as join, c as resolve, r as extname, s as relative } from "./pathe.M-
2
2
  import { i as dim, n as cliTitle, s as import_picocolors } from "./output-DeiS4oEX.mjs";
3
3
  import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
4
4
  import { t as cfAccessHeaders } from "./cf-access-DKDsgwOU.mjs";
5
- import { f as getToken, m as isStagingMode, n as PlatformClient, t as PlatformApiError } from "./client-CTHvucDv.mjs";
5
+ import { f as getToken, m as isStagingMode, n as PlatformClient, t as PlatformApiError } from "./client-YIzxv2ZO.mjs";
6
6
  import { c as R, g as ge, v as ue, x as q, y as ye } from "./dist-abzUneor.mjs";
7
7
  import { r as readProjectConfig } from "./project-CH9pdo16.mjs";
8
8
  import { c as getDatabaseDialect, f as readConfig, p as resolveBindingNames } from "./config-8dLIngKW.mjs";
@@ -10,7 +10,7 @@ import { r as detectFramework } from "./plugin-inference-C3fLzFvP.mjs";
10
10
  import { a as writeJournal, i as stripSqlExt, r as readJournal, t as collectMigrations } from "./collect-9rO3JFNM.mjs";
11
11
  import { n as listDrizzleArtifacts, r as validateMigrations, t as assertJournalCoherence } from "./validate-CNWm-PsL.mjs";
12
12
  import { n as STAGING_PROXY_URL, t as DEFAULT_PROXY_URL } from "./proxy-M3pxItg2.mjs";
13
- import { formatTimestamp } from "./gen-Dgi4D7GC.mjs";
13
+ import { formatTimestamp } from "./gen-q6McxXgE.mjs";
14
14
  import { existsSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
15
15
  import { fileURLToPath, pathToFileURL } from "node:url";
16
16
  import { execFileSync } from "node:child_process";
@@ -512,7 +512,7 @@ async function runMigrate(root, dialect, remote) {
512
512
  return;
513
513
  }
514
514
  if (dialect === "postgresql") {
515
- const { applyPgMigrations } = await import("./runner-pg-BAheiT6v.mjs");
515
+ const { applyPgMigrations } = await import("./runner-pg-EuhrFW3D.mjs");
516
516
  const applied = await withPgClient(root, async (client) => {
517
517
  let existingRows = [];
518
518
  try {
@@ -1,5 +1,5 @@
1
1
  import { n as cliTitle, r as createSpinner } from "./output-DeiS4oEX.mjs";
2
- import { f as getToken, n as PlatformClient } from "./client-CTHvucDv.mjs";
2
+ import { f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
3
3
  import { _ as me, c as R, g as ge, l as Re, u as Se, x as q, y as ye } from "./dist-abzUneor.mjs";
4
4
  import { i as removeProjectConfig, r as readProjectConfig } from "./project-CH9pdo16.mjs";
5
5
  import { r as resolveProjectBySlug } from "./resolve-project-D4O1_fZz.mjs";