void 0.10.1 → 0.10.3

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 (70) hide show
  1. package/dist/{auth-cmd-DBnbrX9Y.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-DNX0hLsO.mjs → cache-CMzjhxHh.mjs} +1 -1
  5. package/dist/{cancel-deploy-CDzkVaYZ.mjs → cancel-deploy-S2N8NSv6.mjs} +1 -1
  6. package/dist/cli/cli.mjs +208 -29
  7. package/dist/{client-D4awzTnj.mjs → client-YIzxv2ZO.mjs} +30 -1
  8. package/dist/{create-project-CGodxfzH.mjs → create-project-pLQdzEPe.mjs} +1 -1
  9. package/dist/{db-ERzz4oly.mjs → db-hAmBumot.mjs} +3 -3
  10. package/dist/{delete-CJZGDLBR.mjs → delete-CfSe3EJO.mjs} +1 -1
  11. package/dist/{deploy-Cwa5sooV.mjs → deploy-DpOdwtla.mjs} +138 -4
  12. package/dist/{domain-WvoAHE6w.mjs → domain-CkowysQx.mjs} +1 -1
  13. package/dist/{env-Cx4czPsR.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-CUB041gj.mjs → github-cmd-D3L0f93X.mjs} +147 -3
  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-DvaRDMIc.mjs → init-CZP69LJu.mjs} +13 -22
  21. package/dist/{link-CpbWJY3P.mjs → link-BKLElphS.mjs} +2 -2
  22. package/dist/{list-BkwE5vH4.mjs → list-B7qXBBjo.mjs} +1 -1
  23. package/dist/{login-Ca6mhQVI.mjs → login-B3l_sDwT.mjs} +1 -1
  24. package/dist/{logs-ArQzZquo.mjs → logs-AXm660MB.mjs} +1 -1
  25. package/dist/{mcp-Cc2MMXdQ.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-CWZeawuN.mjs → project-cmd-InegJruy.mjs} +8 -8
  33. package/dist/{protocol-63PHtCHS.d.mts → protocol-6UZCowS1.d.mts} +3 -3
  34. package/dist/{rollback-BJ60ktsW.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-BRbXyu7E.mjs → secret-CVKwIOm3.mjs} +1 -1
  54. package/package.json +2 -2
  55. package/skills/void/docs/guide/deployment.md +1 -12
  56. package/skills/void/docs/guide/pages-routing/markdown.md +12 -0
  57. package/skills/void/docs/node_modules/void/node_modules/@void/md/README.md +2 -1
  58. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/markdown-it-footnote/README.md +135 -0
  59. package/skills/void/docs/reference/cli.md +71 -8
  60. /package/dist/{auth-nEUVHuFI.d.mts → auth-Dz2CCn4T.d.mts} +0 -0
  61. /package/dist/{fetch-error-BQMdPvge.d.mts → fetch-error-B6RaJ-eZ.d.mts} +0 -0
  62. /package/dist/{head-JAH2l3fg.d.mts → head-eOUCWUNy.d.mts} +0 -0
  63. /package/dist/{prepare-DH2WnEpD.mjs → prepare-DRRboRqH.mjs} +0 -0
  64. /package/dist/{providers-BkiAlEad.d.mts → providers-BJIoduK9.d.mts} +0 -0
  65. /package/dist/{runner-pg-BAheiT6v.mjs → runner-pg-EuhrFW3D.mjs} +0 -0
  66. /package/dist/{skills--OMgLmXW.mjs → skills-Dl3u05da.mjs} +0 -0
  67. /package/dist/{standard-schema-BCBv-QaP.d.mts → standard-schema-Cy0lfeWv.d.mts} +0 -0
  68. /package/dist/{subcommand-prompt-ClwpLlKD.mjs → subcommand-prompt-B8ng0FTS.mjs} +0 -0
  69. /package/dist/{types-BnHMXezo.d.mts → types-BodZGegX.d.mts} +0 -0
  70. /package/dist/{yarn-pnp-DhCHHLAz.mjs → yarn-pnp-WLW2IHUY.mjs} +0 -0
@@ -1,6 +1,6 @@
1
- import { d as getToken, h as removeToken, n as PlatformClient } from "./client-D4awzTnj.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-Ca6mhQVI.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 { d as getToken, n as PlatformClient } from "./client-D4awzTnj.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 { d as getToken, n as PlatformClient } from "./client-D4awzTnj.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
  {
@@ -590,6 +630,11 @@ const githubSubcommands = [
590
630
  arg: "[project]",
591
631
  description: "Connect a repository to a project for auto-deploy"
592
632
  },
633
+ {
634
+ name: "update",
635
+ arg: "[project]",
636
+ description: "Update an existing connection's branch, build executor, or deploy workflow"
637
+ },
593
638
  {
594
639
  name: "link",
595
640
  description: "Link your GitHub account to Void"
@@ -615,6 +660,7 @@ function parseGithubArgs(args) {
615
660
  let repo;
616
661
  let branch;
617
662
  let executor;
663
+ let workflowPath;
618
664
  for (let i = 0; i < rest.length; i++) {
619
665
  const arg = rest[i];
620
666
  if (arg === "--installation") {
@@ -644,6 +690,11 @@ function parseGithubArgs(args) {
644
690
  if (value.trim() === "") throw new Error("github: --executor requires a value.");
645
691
  if (value !== "container" && value !== "github_actions") throw new Error("github: invalid --executor (expected container|github_actions).");
646
692
  executor = value;
693
+ } else if (arg === "--workflow") {
694
+ if (i + 1 >= rest.length) throw new Error("github: --workflow requires a value.");
695
+ const value = rest[++i];
696
+ if (value.trim() === "") throw new Error("github: --workflow requires a value.");
697
+ workflowPath = value.trim();
647
698
  } else if (arg.startsWith("-")) throw new Error(`github: Unexpected argument '${arg}'.`);
648
699
  else if (projectName) throw new Error(`github: Unexpected argument '${arg}'.`);
649
700
  else projectName = arg;
@@ -654,10 +705,52 @@ function parseGithubArgs(args) {
654
705
  installationId,
655
706
  repo,
656
707
  branch,
657
- executor
708
+ executor,
709
+ workflowPath
658
710
  };
659
711
  }
660
- throw new Error("github: Usage: void github <install|installations|connect|link>.");
712
+ if (subcommand === "update") {
713
+ let projectName = "";
714
+ let branch;
715
+ let executor;
716
+ let workflowPath;
717
+ for (let i = 0; i < rest.length; i++) {
718
+ const arg = rest[i];
719
+ if (arg === "--branch") {
720
+ if (i + 1 >= rest.length) throw new Error("github: --branch requires a value.");
721
+ const value = rest[++i];
722
+ if (value.trim() === "") throw new Error("github: --branch requires a value.");
723
+ branch = value.trim();
724
+ } else if (arg === "--project") {
725
+ if (i + 1 >= rest.length) throw new Error("github: --project requires a value.");
726
+ const value = rest[++i];
727
+ if (value.trim() === "") throw new Error("github: --project requires a value.");
728
+ if (projectName) throw new Error(`github: Unexpected argument '${value}'.`);
729
+ projectName = value;
730
+ } else if (arg === "--executor") {
731
+ if (i + 1 >= rest.length) throw new Error("github: --executor requires a value.");
732
+ const value = rest[++i];
733
+ if (value.trim() === "") throw new Error("github: --executor requires a value.");
734
+ if (value !== "container" && value !== "github_actions") throw new Error("github: invalid --executor (expected container|github_actions).");
735
+ executor = value;
736
+ } else if (arg === "--workflow") {
737
+ if (i + 1 >= rest.length) throw new Error("github: --workflow requires a value.");
738
+ const value = rest[++i];
739
+ if (value.trim() === "") throw new Error("github: --workflow requires a value.");
740
+ workflowPath = value.trim();
741
+ } else if (arg.startsWith("-")) throw new Error(`github: Unexpected argument '${arg}'.`);
742
+ else if (projectName) throw new Error(`github: Unexpected argument '${arg}'.`);
743
+ else projectName = arg;
744
+ }
745
+ return {
746
+ subcommand,
747
+ projectName,
748
+ branch,
749
+ executor,
750
+ workflowPath
751
+ };
752
+ }
753
+ throw new Error("github: Usage: void github <install|installations|connect|update|link>.");
661
754
  }
662
755
  //#endregion
663
756
  //#region src/cli/ascii.ts
@@ -967,6 +1060,10 @@ const HELP_TREE = {
967
1060
  command: "connect [project]",
968
1061
  description: "Connect a repository to a project for auto-deploy"
969
1062
  },
1063
+ {
1064
+ command: "update [project]",
1065
+ description: "Update an existing connection's branch, build executor, or deploy workflow"
1066
+ },
970
1067
  {
971
1068
  command: "link",
972
1069
  description: "Link your GitHub account to Void"
@@ -999,6 +1096,10 @@ const HELP_TREE = {
999
1096
  {
1000
1097
  command: "--executor <type>",
1001
1098
  description: "Build executor: container (default) | github_actions"
1099
+ },
1100
+ {
1101
+ command: "--workflow <path>",
1102
+ description: "Authorized deploy workflow file (default .github/workflows/void-deploy.yml)"
1002
1103
  }
1003
1104
  ],
1004
1105
  examples: [{
@@ -1008,9 +1109,78 @@ const HELP_TREE = {
1008
1109
  command: "void github connect my-app --installation 42 --repo owner/repo --branch main",
1009
1110
  description: "Non-interactive connect (all flags explicit)"
1010
1111
  }]
1112
+ },
1113
+ update: {
1114
+ summary: "Update an existing connection's branch, build executor, or deploy workflow.",
1115
+ usage: ["void github update [project] [options]"],
1116
+ options: [
1117
+ {
1118
+ command: "--project <name>",
1119
+ description: "Project name (alias for positional)"
1120
+ },
1121
+ {
1122
+ command: "--branch <name>",
1123
+ description: "New branch to deploy from"
1124
+ },
1125
+ {
1126
+ command: "--executor <type>",
1127
+ description: "New build executor: container | github_actions"
1128
+ },
1129
+ {
1130
+ command: "--workflow <path>",
1131
+ description: "New authorized deploy workflow file (under .github/workflows/)"
1132
+ }
1133
+ ],
1134
+ examples: [{
1135
+ command: "void github update my-app --executor github_actions",
1136
+ description: "Switch an existing connection to the GitHub Actions executor"
1137
+ }, {
1138
+ command: "void github update my-app --branch release",
1139
+ description: "Change the deploy branch"
1140
+ }]
1011
1141
  }
1012
1142
  }
1013
1143
  },
1144
+ build: {
1145
+ summary: "Inspect remote builds.",
1146
+ usage: ["void build <command>"],
1147
+ commands: [{
1148
+ command: "logs [build]",
1149
+ description: "Stream, tail, or download logs for a build"
1150
+ }],
1151
+ children: { logs: {
1152
+ summary: "Stream, tail, or download logs for a build.",
1153
+ usage: ["void build logs [build] [options]"],
1154
+ options: [
1155
+ {
1156
+ command: "--follow, -f",
1157
+ description: "Live-tail until the build finishes"
1158
+ },
1159
+ {
1160
+ command: "--output <file>, -o",
1161
+ description: "Write logs to a file instead of stdout"
1162
+ },
1163
+ {
1164
+ command: "--project <slug>, -p",
1165
+ description: "Target project (else linked / VOID_PROJECT)"
1166
+ }
1167
+ ],
1168
+ examples: [
1169
+ {
1170
+ command: "void build logs",
1171
+ description: "Print the latest build's logs"
1172
+ },
1173
+ {
1174
+ command: "void build logs -f",
1175
+ description: "Follow the latest build until it finishes"
1176
+ },
1177
+ {
1178
+ command: "void build logs bld_123 -o build.log",
1179
+ description: "Download a build's logs to a file"
1180
+ }
1181
+ ]
1182
+ } }
1183
+ },
1014
1184
  db: {
1015
1185
  summary: "Manage local and remote database state.",
1016
1186
  usage: ["void db <command>"],
@@ -1319,6 +1489,8 @@ function printGlobalHelp() {
1319
1489
  "",
1320
1490
  ...globalCommandGroup("github"),
1321
1491
  "",
1492
+ ...globalCommandGroup("build"),
1493
+ "",
1322
1494
  categoryTitle("database"),
1323
1495
  ...globalCommandLines("db", {
1324
1496
  execute: "execute <sql>",
@@ -1686,7 +1858,7 @@ async function runSubcommandGroup(command, subcommands, parse, run) {
1686
1858
  const sub = args[1];
1687
1859
  try {
1688
1860
  if ((!sub || sub.startsWith("-")) && process.stdin.isTTY) {
1689
- const { promptSubcommand } = await import("../subcommand-prompt-ClwpLlKD.mjs");
1861
+ const { promptSubcommand } = await import("../subcommand-prompt-B8ng0FTS.mjs");
1690
1862
  const result = await promptSubcommand(command, subcommands);
1691
1863
  if (!result) process.exit(0);
1692
1864
  await run(root, parse(buildArgs(result, args.slice(1))));
@@ -1715,7 +1887,7 @@ else if (command === "deploy") {
1715
1887
  R.error(err instanceof Error ? err.message : String(err));
1716
1888
  process.exit(1);
1717
1889
  }
1718
- import("../deploy-Cwa5sooV.mjs").then((n) => n.t).then(({ runDeploy }) => {
1890
+ import("../deploy-DpOdwtla.mjs").then((n) => n.t).then(({ runDeploy }) => {
1719
1891
  runDeploy(root, {
1720
1892
  projectSlug: deployArgs.projectSlug,
1721
1893
  dir: deployArgs.dir,
@@ -1727,14 +1899,15 @@ else if (command === "deploy") {
1727
1899
  process.exit(1);
1728
1900
  });
1729
1901
  });
1730
- } else if (command === "auth") runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (root, parsed) => import("../auth-cmd-DBnbrX9Y.mjs").then(({ runAuthCommand }) => runAuthCommand(root, parsed)));
1731
- else if (command === "project") runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (root, parsed) => import("../project-cmd-CWZeawuN.mjs").then(({ runProjectCommand }) => runProjectCommand(root, parsed)));
1732
- else if (command === "secret") runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (root, parsed) => import("../secret-BRbXyu7E.mjs").then(({ runSecretCommand }) => runSecretCommand(root, parsed)));
1733
- else if (command === "domain") runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (root, parsed) => import("../domain-WvoAHE6w.mjs").then(({ runDomainCommand }) => runDomainCommand(root, parsed)));
1734
- else if (command === "db") runSubcommandGroup("db", dbSubcommands, parseDbArgs, (root, parsed) => import("../db-ERzz4oly.mjs").then(({ runDbCommand }) => runDbCommand(root, parsed)));
1735
- else if (command === "env") runSubcommandGroup("env", envSubcommands, parseEnvArgs, (root, parsed) => import("../env-Cx4czPsR.mjs").then(({ runEnvCommand }) => runEnvCommand(root, parsed)));
1736
- else if (command === "gen") runSubcommandGroup("gen", genSubcommands, parseGenArgs, (root, parsed) => import("../gen-Dgi4D7GC.mjs").then(({ runGenCommand }) => runGenCommand(root, parsed)));
1737
- else if (command === "github") runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (root, parsed) => import("../github-cmd-CUB041gj.mjs").then(({ runGithubCommand }) => runGithubCommand(root, parsed)));
1902
+ } else if (command === "auth") runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (root, parsed) => import("../auth-cmd-CblKzAdD.mjs").then(({ runAuthCommand }) => runAuthCommand(root, parsed)));
1903
+ else if (command === "project") runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (root, parsed) => import("../project-cmd-InegJruy.mjs").then(({ runProjectCommand }) => runProjectCommand(root, parsed)));
1904
+ else if (command === "secret") runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (root, parsed) => import("../secret-CVKwIOm3.mjs").then(({ runSecretCommand }) => runSecretCommand(root, parsed)));
1905
+ else if (command === "domain") runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (root, parsed) => import("../domain-CkowysQx.mjs").then(({ runDomainCommand }) => runDomainCommand(root, parsed)));
1906
+ else if (command === "db") runSubcommandGroup("db", dbSubcommands, parseDbArgs, (root, parsed) => import("../db-hAmBumot.mjs").then(({ runDbCommand }) => runDbCommand(root, parsed)));
1907
+ else if (command === "env") runSubcommandGroup("env", envSubcommands, parseEnvArgs, (root, parsed) => import("../env-CIwG2y7G.mjs").then(({ runEnvCommand }) => runEnvCommand(root, parsed)));
1908
+ else if (command === "gen") runSubcommandGroup("gen", genSubcommands, parseGenArgs, (root, parsed) => import("../gen-q6McxXgE.mjs").then(({ runGenCommand }) => runGenCommand(root, parsed)));
1909
+ else if (command === "github") runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (root, parsed) => import("../github-cmd-D3L0f93X.mjs").then(({ runGithubCommand }) => runGithubCommand(root, parsed)));
1910
+ else if (command === "build") runSubcommandGroup("build", buildSubcommands, parseBuildArgs, (root, parsed) => import("../build-cmd-CJQSRupz.mjs").then(({ runBuildCommand }) => runBuildCommand(root, parsed)));
1738
1911
  else if (command === "prepare") {
1739
1912
  const root = process.cwd();
1740
1913
  let prepareArgs;
@@ -1744,7 +1917,7 @@ else if (command === "prepare") {
1744
1917
  R.error(err instanceof Error ? err.message : String(err));
1745
1918
  process.exit(1);
1746
1919
  }
1747
- import("../prepare-DH2WnEpD.mjs").then(({ runPrepareCommand }) => {
1920
+ import("../prepare-DRRboRqH.mjs").then(({ runPrepareCommand }) => {
1748
1921
  runPrepareCommand(root, prepareArgs).catch((err) => {
1749
1922
  R.error(err.message ?? err);
1750
1923
  process.exit(1);
@@ -1752,7 +1925,7 @@ else if (command === "prepare") {
1752
1925
  });
1753
1926
  } else if (command === "init") {
1754
1927
  const root = process.cwd();
1755
- import("../init-DvaRDMIc.mjs").then(({ runInitCommand, parseInitArgs }) => {
1928
+ import("../init-CZP69LJu.mjs").then(({ runInitCommand, parseInitArgs }) => {
1756
1929
  let initArgs;
1757
1930
  try {
1758
1931
  initArgs = parseInitArgs(args.slice(1));
@@ -1765,7 +1938,7 @@ else if (command === "prepare") {
1765
1938
  process.exit(1);
1766
1939
  });
1767
1940
  });
1768
- } else if (command === "mcp") import("../mcp-Cc2MMXdQ.mjs").then(({ runMcp }) => {
1941
+ } else if (command === "mcp") import("../mcp-D2plINxM.mjs").then(({ runMcp }) => {
1769
1942
  runMcp();
1770
1943
  });
1771
1944
  else if (command === "-v" || command === "--version") {
@@ -1806,9 +1979,14 @@ else if (command === "-v" || command === "--version") {
1806
1979
  },
1807
1980
  {
1808
1981
  name: "github",
1809
- hint: "install | installations | connect | link",
1982
+ hint: "install | installations | connect | update | link",
1810
1983
  description: "Connect a GitHub repository for automatic deploys"
1811
1984
  },
1985
+ {
1986
+ name: "build",
1987
+ hint: "logs",
1988
+ description: "Inspect remote builds"
1989
+ },
1812
1990
  {
1813
1991
  name: "db",
1814
1992
  hint: "status | reset | seed | execute | migrate | studio | export | rename-migrations",
@@ -1839,37 +2017,38 @@ else if (command === "-v" || command === "--version") {
1839
2017
  ];
1840
2018
  (async () => {
1841
2019
  printVoidHeader();
1842
- const { promptSubcommand } = await import("../subcommand-prompt-ClwpLlKD.mjs");
2020
+ const { promptSubcommand } = await import("../subcommand-prompt-B8ng0FTS.mjs");
1843
2021
  const result = await promptSubcommand("", topLevelCommands);
1844
2022
  if (!result) process.exit(0);
1845
2023
  const cmd = result.subcommand;
1846
2024
  const root = process.cwd();
1847
2025
  switch (cmd) {
1848
2026
  case "init": {
1849
- const { runInitCommand, parseInitArgs } = await import("../init-DvaRDMIc.mjs");
2027
+ const { runInitCommand, parseInitArgs } = await import("../init-CZP69LJu.mjs");
1850
2028
  await runInitCommand(root, parseInitArgs([]));
1851
2029
  return;
1852
2030
  }
1853
2031
  case "deploy": {
1854
- const { runDeploy } = await import("../deploy-Cwa5sooV.mjs").then((n) => n.t);
2032
+ const { runDeploy } = await import("../deploy-DpOdwtla.mjs").then((n) => n.t);
1855
2033
  await runDeploy(root);
1856
2034
  return;
1857
2035
  }
1858
2036
  case "mcp": {
1859
- const { runMcp } = await import("../mcp-Cc2MMXdQ.mjs");
2037
+ const { runMcp } = await import("../mcp-D2plINxM.mjs");
1860
2038
  runMcp();
1861
2039
  return;
1862
2040
  }
1863
- case "auth": return runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (r, p) => import("../auth-cmd-DBnbrX9Y.mjs").then(({ runAuthCommand }) => runAuthCommand(r, p)));
1864
- case "project": return runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (r, p) => import("../project-cmd-CWZeawuN.mjs").then(({ runProjectCommand }) => runProjectCommand(r, p)));
1865
- case "secret": return runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (r, p) => import("../secret-BRbXyu7E.mjs").then(({ runSecretCommand }) => runSecretCommand(r, p)));
1866
- case "domain": return runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (r, p) => import("../domain-WvoAHE6w.mjs").then(({ runDomainCommand }) => runDomainCommand(r, p)));
1867
- case "github": return runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (r, p) => import("../github-cmd-CUB041gj.mjs").then(({ runGithubCommand }) => runGithubCommand(r, p)));
1868
- case "db": return runSubcommandGroup("db", dbSubcommands, parseDbArgs, (r, p) => import("../db-ERzz4oly.mjs").then(({ runDbCommand }) => runDbCommand(r, p)));
1869
- case "env": return runSubcommandGroup("env", envSubcommands, parseEnvArgs, (r, p) => import("../env-Cx4czPsR.mjs").then(({ runEnvCommand }) => runEnvCommand(r, p)));
1870
- case "gen": return runSubcommandGroup("gen", genSubcommands, parseGenArgs, (r, p) => import("../gen-Dgi4D7GC.mjs").then(({ runGenCommand }) => runGenCommand(r, p)));
2041
+ case "auth": return runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (r, p) => import("../auth-cmd-CblKzAdD.mjs").then(({ runAuthCommand }) => runAuthCommand(r, p)));
2042
+ case "project": return runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (r, p) => import("../project-cmd-InegJruy.mjs").then(({ runProjectCommand }) => runProjectCommand(r, p)));
2043
+ case "secret": return runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (r, p) => import("../secret-CVKwIOm3.mjs").then(({ runSecretCommand }) => runSecretCommand(r, p)));
2044
+ case "domain": return runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (r, p) => import("../domain-CkowysQx.mjs").then(({ runDomainCommand }) => runDomainCommand(r, p)));
2045
+ case "github": return runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (r, p) => import("../github-cmd-D3L0f93X.mjs").then(({ runGithubCommand }) => runGithubCommand(r, p)));
2046
+ case "build": return runSubcommandGroup("build", buildSubcommands, parseBuildArgs, (r, p) => import("../build-cmd-CJQSRupz.mjs").then(({ runBuildCommand }) => runBuildCommand(r, p)));
2047
+ case "db": return runSubcommandGroup("db", dbSubcommands, parseDbArgs, (r, p) => import("../db-hAmBumot.mjs").then(({ runDbCommand }) => runDbCommand(r, p)));
2048
+ case "env": return runSubcommandGroup("env", envSubcommands, parseEnvArgs, (r, p) => import("../env-CIwG2y7G.mjs").then(({ runEnvCommand }) => runEnvCommand(r, p)));
2049
+ case "gen": return runSubcommandGroup("gen", genSubcommands, parseGenArgs, (r, p) => import("../gen-q6McxXgE.mjs").then(({ runGenCommand }) => runGenCommand(r, p)));
1871
2050
  case "prepare": {
1872
- const { runPrepareCommand } = await import("../prepare-DH2WnEpD.mjs");
2051
+ const { runPrepareCommand } = await import("../prepare-DRRboRqH.mjs");
1873
2052
  await runPrepareCommand(root, parsePrepareArgs([]));
1874
2053
  return;
1875
2054
  }
@@ -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);
@@ -861,6 +873,23 @@ var PlatformClient = class {
861
873
  if (!res.ok) await throwPlatformApiError("Failed to connect GitHub repository", res);
862
874
  return res.json();
863
875
  }
876
+ async getGithubConnection(projectId) {
877
+ const res = await fetch(`${this.baseUrl}/projects/${projectId}/github`, { headers: { ...this.authHeaders } });
878
+ if (!res.ok) await throwPlatformApiError("Failed to get GitHub connection", res);
879
+ return res.json();
880
+ }
881
+ async updateGithubConnection(projectId, body) {
882
+ const res = await fetch(`${this.baseUrl}/projects/${projectId}/github`, {
883
+ method: "PATCH",
884
+ headers: {
885
+ "Content-Type": "application/json",
886
+ ...this.authHeaders
887
+ },
888
+ body: JSON.stringify(body)
889
+ });
890
+ if (!res.ok) await throwPlatformApiError("Failed to update GitHub connection", res);
891
+ return res.json();
892
+ }
864
893
  async getGithubLinkUrl(redirect, codeChallenge) {
865
894
  const params = new URLSearchParams({
866
895
  redirect,
@@ -888,4 +917,4 @@ var PlatformClient = class {
888
917
  }
889
918
  };
890
919
  //#endregion
891
- export { saveToken as _, isExpiredTokenError as a, createCodeChallenge as c, getToken as d, getTokenSource as f, runLogin as g, removeToken as h, isCliOutdatedError as i, createCodeVerifier as l, openBrowser as m, PlatformClient as n, parsePlatformErrorBody as o, isStagingMode as p, client_exports as r, awaitBrowserCallback as s, PlatformApiError as t, getSiteDomain as u };
920
+ export { runLogin as _, isExpiredTokenError as a, createCodeChallenge as c, getSiteDomain as d, getToken as f, removeToken as g, openBrowser as h, isCliOutdatedError as i, createCodeVerifier as l, isStagingMode as m, PlatformClient as n, parsePlatformErrorBody as o, getTokenSource as p, client_exports as r, awaitBrowserCallback as s, PlatformApiError as t, getApiUrl as u, saveToken as v, ensureCloudflaredToken as y };
@@ -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 { t as PlatformApiError, u as getSiteDomain } from "./client-D4awzTnj.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 { d as getToken, n as PlatformClient, p as isStagingMode, t as PlatformApiError } from "./client-D4awzTnj.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 { d as getToken, n as PlatformClient } from "./client-D4awzTnj.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";