void 0.10.4 → 0.10.5

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 (37) hide show
  1. package/dist/{auth-cmd-CblKzAdD.mjs → auth-cmd-UoCwfDQv.mjs} +2 -2
  2. package/dist/{build-cmd-CJQSRupz.mjs → build-cmd-CVyuBHjP.mjs} +1 -1
  3. package/dist/{cache-CMzjhxHh.mjs → cache-ACORQCIq.mjs} +1 -1
  4. package/dist/{cancel-deploy-S2N8NSv6.mjs → cancel-deploy-Gi8zmoZC.mjs} +1 -1
  5. package/dist/cli/cli.mjs +41 -28
  6. package/dist/{client-YIzxv2ZO.mjs → client-BlbnA92X.mjs} +44 -0
  7. package/dist/{config--wXmVOoe.mjs → config-CbJS4Krx.mjs} +3 -3
  8. package/dist/{create-project-pLQdzEPe.mjs → create-project-LjvkYziS.mjs} +1 -1
  9. package/dist/{db-hAmBumot.mjs → db-C00yjN01.mjs} +17 -14
  10. package/dist/{delete-CfSe3EJO.mjs → delete-CplfvTgU.mjs} +1 -1
  11. package/dist/{deploy-DpOdwtla.mjs → deploy-CISNL5uK.mjs} +28 -30
  12. package/dist/{discover-C8N1I4tK.mjs → discover-ZWuBvt22.mjs} +1 -1
  13. package/dist/{domain-CkowysQx.mjs → domain-B4HpcgNG.mjs} +1 -1
  14. package/dist/{env-CIwG2y7G.mjs → env-DNMJpeVF.mjs} +3 -3
  15. package/dist/{env-types-CaJaIRXU.mjs → env-types-BS8cZead.mjs} +1 -1
  16. package/dist/{env-validation-LH6eoyW-.mjs → env-validation-BxbtBbjh.mjs} +1 -1
  17. package/dist/{gen-q6McxXgE.mjs → gen-C0pV2gRQ.mjs} +2 -2
  18. package/dist/{github-cmd-BvEKQmcD.mjs → github-cmd-CwtLD1yI.mjs} +118 -10
  19. package/dist/index.mjs +11 -11
  20. package/dist/{init-CZP69LJu.mjs → init-D58GxCtt.mjs} +7 -7
  21. package/dist/{link-BKLElphS.mjs → link-ZFmboqY3.mjs} +2 -2
  22. package/dist/{list-B7qXBBjo.mjs → list-CbNNjXTm.mjs} +1 -1
  23. package/dist/{login-B3l_sDwT.mjs → login-CvxxF_9z.mjs} +1 -1
  24. package/dist/{logs-AXm660MB.mjs → logs-BDZ9AuhM.mjs} +1 -1
  25. package/dist/{mcp-D2plINxM.mjs → mcp-C8BjRt_z.mjs} +1 -1
  26. package/dist/{plugin-inference-C3fLzFvP.mjs → plugin-inference-D04iL1mW.mjs} +1 -1
  27. package/dist/{prepare-DRRboRqH.mjs → prepare-DUo9q8cM.mjs} +6 -6
  28. package/dist/{preset-B7ZQZn0u.mjs → preset-D0My64KQ.mjs} +1 -1
  29. package/dist/{project-cmd-InegJruy.mjs → project-cmd-Dd1gNRdd.mjs} +8 -8
  30. package/dist/{project-tsconfig-BTNuNoJ0.mjs → project-tsconfig-DMBV55K2.mjs} +2 -2
  31. package/dist/{rollback-CHVE-DeT.mjs → rollback-DzmCCrFg.mjs} +1 -1
  32. package/dist/{route-types-D03ryMXz.mjs → route-types-BpSJEW20.mjs} +1 -1
  33. package/dist/{scan-DGEp1-1Q.mjs → scan---8wfN58.mjs} +1 -1
  34. package/dist/{secret-CVKwIOm3.mjs → secret-CMLYWkE-.mjs} +1 -1
  35. package/dist/sveltekit.mjs +1 -1
  36. package/package.json +2 -2
  37. package/skills/void/docs/reference/cli.md +14 -0
@@ -1,6 +1,6 @@
1
- import { f as getToken, g as removeToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
1
+ import { f as getToken, g as removeToken, n as PlatformClient } from "./client-BlbnA92X.mjs";
2
2
  import { c as R } from "./dist-abzUneor.mjs";
3
- import { n as runLoginCommand } from "./login-B3l_sDwT.mjs";
3
+ import { n as runLoginCommand } from "./login-CvxxF_9z.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
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";
2
+ import { f as getToken, n as PlatformClient, t as PlatformApiError } from "./client-BlbnA92X.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 { i as dim, n as cliTitle, r as createSpinner } from "./output-DeiS4oEX.mjs";
2
- import { f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
2
+ import { f as getToken, n as PlatformClient } from "./client-BlbnA92X.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-YIzxv2ZO.mjs";
2
+ import { f as getToken, n as PlatformClient } from "./client-BlbnA92X.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
@@ -643,6 +643,10 @@ const githubSubcommands = [
643
643
  {
644
644
  name: "link",
645
645
  description: "Link your GitHub account to Void"
646
+ },
647
+ {
648
+ name: "join",
649
+ description: "Join your organization's shared GitHub App installations"
646
650
  }
647
651
  ];
648
652
  function parseGithubArgs(args) {
@@ -659,6 +663,10 @@ function parseGithubArgs(args) {
659
663
  if (rest.length > 0) throw new Error(`github: Unexpected argument '${rest[0]}'.`);
660
664
  return { subcommand };
661
665
  }
666
+ if (subcommand === "join") {
667
+ if (rest.length > 0) throw new Error(`github: Unexpected argument '${rest[0]}'.`);
668
+ return { subcommand };
669
+ }
662
670
  if (subcommand === "connect") {
663
671
  let projectName = "";
664
672
  let installationId;
@@ -774,7 +782,7 @@ function parseGithubArgs(args) {
774
782
  projectName
775
783
  };
776
784
  }
777
- throw new Error("github: Usage: void github <install|installations|connect|update|status|link>.");
785
+ throw new Error("github: Usage: void github <install|installations|connect|update|status|link|join>.");
778
786
  }
779
787
  //#endregion
780
788
  //#region src/cli/ascii.ts
@@ -1095,12 +1103,17 @@ const HELP_TREE = {
1095
1103
  {
1096
1104
  command: "link",
1097
1105
  description: "Link your GitHub account to Void"
1106
+ },
1107
+ {
1108
+ command: "join",
1109
+ description: "Join your organization's shared GitHub App installations"
1098
1110
  }
1099
1111
  ],
1100
1112
  children: {
1101
1113
  install: basicSubcommand("Open the GitHub App install page in your browser.", "void github install"),
1102
1114
  installations: basicSubcommand("List your GitHub App installations.", "void github installations"),
1103
1115
  link: basicSubcommand("Link your GitHub account to Void.", "void github link"),
1116
+ join: basicSubcommand("Join your organization's shared GitHub App installations.", "void github join"),
1104
1117
  connect: {
1105
1118
  summary: "Connect a repository to a project for automatic deploys.",
1106
1119
  usage: ["void github connect [project] [options]"],
@@ -1937,7 +1950,7 @@ else if (command === "deploy") {
1937
1950
  R.error(err instanceof Error ? err.message : String(err));
1938
1951
  process.exit(1);
1939
1952
  }
1940
- import("../deploy-DpOdwtla.mjs").then((n) => n.t).then(({ runDeploy }) => {
1953
+ import("../deploy-CISNL5uK.mjs").then((n) => n.t).then(({ runDeploy }) => {
1941
1954
  runDeploy(root, {
1942
1955
  projectSlug: deployArgs.projectSlug,
1943
1956
  dir: deployArgs.dir,
@@ -1949,15 +1962,15 @@ else if (command === "deploy") {
1949
1962
  process.exit(1);
1950
1963
  });
1951
1964
  });
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)));
1965
+ } else if (command === "auth") runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (root, parsed) => import("../auth-cmd-UoCwfDQv.mjs").then(({ runAuthCommand }) => runAuthCommand(root, parsed)));
1966
+ else if (command === "project") runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (root, parsed) => import("../project-cmd-Dd1gNRdd.mjs").then(({ runProjectCommand }) => runProjectCommand(root, parsed)));
1967
+ else if (command === "secret") runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (root, parsed) => import("../secret-CMLYWkE-.mjs").then(({ runSecretCommand }) => runSecretCommand(root, parsed)));
1968
+ else if (command === "domain") runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (root, parsed) => import("../domain-B4HpcgNG.mjs").then(({ runDomainCommand }) => runDomainCommand(root, parsed)));
1969
+ else if (command === "db") runSubcommandGroup("db", dbSubcommands, parseDbArgs, (root, parsed) => import("../db-C00yjN01.mjs").then(({ runDbCommand }) => runDbCommand(root, parsed)));
1970
+ else if (command === "env") runSubcommandGroup("env", envSubcommands, parseEnvArgs, (root, parsed) => import("../env-DNMJpeVF.mjs").then(({ runEnvCommand }) => runEnvCommand(root, parsed)));
1971
+ else if (command === "gen") runSubcommandGroup("gen", genSubcommands, parseGenArgs, (root, parsed) => import("../gen-C0pV2gRQ.mjs").then(({ runGenCommand }) => runGenCommand(root, parsed)));
1972
+ else if (command === "github") runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (root, parsed) => import("../github-cmd-CwtLD1yI.mjs").then(({ runGithubCommand }) => runGithubCommand(root, parsed)));
1973
+ else if (command === "build") runSubcommandGroup("build", buildSubcommands, parseBuildArgs, (root, parsed) => import("../build-cmd-CVyuBHjP.mjs").then(({ runBuildCommand }) => runBuildCommand(root, parsed)));
1961
1974
  else if (command === "prepare") {
1962
1975
  const root = process.cwd();
1963
1976
  let prepareArgs;
@@ -1967,7 +1980,7 @@ else if (command === "prepare") {
1967
1980
  R.error(err instanceof Error ? err.message : String(err));
1968
1981
  process.exit(1);
1969
1982
  }
1970
- import("../prepare-DRRboRqH.mjs").then(({ runPrepareCommand }) => {
1983
+ import("../prepare-DUo9q8cM.mjs").then(({ runPrepareCommand }) => {
1971
1984
  runPrepareCommand(root, prepareArgs).catch((err) => {
1972
1985
  R.error(err.message ?? err);
1973
1986
  process.exit(1);
@@ -1975,7 +1988,7 @@ else if (command === "prepare") {
1975
1988
  });
1976
1989
  } else if (command === "init") {
1977
1990
  const root = process.cwd();
1978
- import("../init-CZP69LJu.mjs").then(({ runInitCommand, parseInitArgs }) => {
1991
+ import("../init-D58GxCtt.mjs").then(({ runInitCommand, parseInitArgs }) => {
1979
1992
  let initArgs;
1980
1993
  try {
1981
1994
  initArgs = parseInitArgs(args.slice(1));
@@ -1988,7 +2001,7 @@ else if (command === "prepare") {
1988
2001
  process.exit(1);
1989
2002
  });
1990
2003
  });
1991
- } else if (command === "mcp") import("../mcp-D2plINxM.mjs").then(({ runMcp }) => {
2004
+ } else if (command === "mcp") import("../mcp-C8BjRt_z.mjs").then(({ runMcp }) => {
1992
2005
  runMcp();
1993
2006
  });
1994
2007
  else if (command === "-v" || command === "--version") {
@@ -2029,7 +2042,7 @@ else if (command === "-v" || command === "--version") {
2029
2042
  },
2030
2043
  {
2031
2044
  name: "github",
2032
- hint: "install | installations | connect | update | status | link",
2045
+ hint: "install | installations | connect | update | status | link | join",
2033
2046
  description: "Connect a GitHub repository for automatic deploys"
2034
2047
  },
2035
2048
  {
@@ -2074,31 +2087,31 @@ else if (command === "-v" || command === "--version") {
2074
2087
  const root = process.cwd();
2075
2088
  switch (cmd) {
2076
2089
  case "init": {
2077
- const { runInitCommand, parseInitArgs } = await import("../init-CZP69LJu.mjs");
2090
+ const { runInitCommand, parseInitArgs } = await import("../init-D58GxCtt.mjs");
2078
2091
  await runInitCommand(root, parseInitArgs([]));
2079
2092
  return;
2080
2093
  }
2081
2094
  case "deploy": {
2082
- const { runDeploy } = await import("../deploy-DpOdwtla.mjs").then((n) => n.t);
2095
+ const { runDeploy } = await import("../deploy-CISNL5uK.mjs").then((n) => n.t);
2083
2096
  await runDeploy(root);
2084
2097
  return;
2085
2098
  }
2086
2099
  case "mcp": {
2087
- const { runMcp } = await import("../mcp-D2plINxM.mjs");
2100
+ const { runMcp } = await import("../mcp-C8BjRt_z.mjs");
2088
2101
  runMcp();
2089
2102
  return;
2090
2103
  }
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)));
2104
+ case "auth": return runSubcommandGroup("auth", authSubcommands, parseAuthArgs, (r, p) => import("../auth-cmd-UoCwfDQv.mjs").then(({ runAuthCommand }) => runAuthCommand(r, p)));
2105
+ case "project": return runSubcommandGroup("project", projectSubcommands, parseProjectArgs, (r, p) => import("../project-cmd-Dd1gNRdd.mjs").then(({ runProjectCommand }) => runProjectCommand(r, p)));
2106
+ case "secret": return runSubcommandGroup("secret", secretSubcommands, parseSecretArgs, (r, p) => import("../secret-CMLYWkE-.mjs").then(({ runSecretCommand }) => runSecretCommand(r, p)));
2107
+ case "domain": return runSubcommandGroup("domain", domainSubcommands, parseDomainArgs, (r, p) => import("../domain-B4HpcgNG.mjs").then(({ runDomainCommand }) => runDomainCommand(r, p)));
2108
+ case "github": return runSubcommandGroup("github", githubSubcommands, parseGithubArgs, (r, p) => import("../github-cmd-CwtLD1yI.mjs").then(({ runGithubCommand }) => runGithubCommand(r, p)));
2109
+ case "build": return runSubcommandGroup("build", buildSubcommands, parseBuildArgs, (r, p) => import("../build-cmd-CVyuBHjP.mjs").then(({ runBuildCommand }) => runBuildCommand(r, p)));
2110
+ case "db": return runSubcommandGroup("db", dbSubcommands, parseDbArgs, (r, p) => import("../db-C00yjN01.mjs").then(({ runDbCommand }) => runDbCommand(r, p)));
2111
+ case "env": return runSubcommandGroup("env", envSubcommands, parseEnvArgs, (r, p) => import("../env-DNMJpeVF.mjs").then(({ runEnvCommand }) => runEnvCommand(r, p)));
2112
+ case "gen": return runSubcommandGroup("gen", genSubcommands, parseGenArgs, (r, p) => import("../gen-C0pV2gRQ.mjs").then(({ runGenCommand }) => runGenCommand(r, p)));
2100
2113
  case "prepare": {
2101
- const { runPrepareCommand } = await import("../prepare-DRRboRqH.mjs");
2114
+ const { runPrepareCommand } = await import("../prepare-DUo9q8cM.mjs");
2102
2115
  await runPrepareCommand(root, parsePrepareArgs([]));
2103
2116
  return;
2104
2117
  }
@@ -873,6 +873,25 @@ var PlatformClient = class {
873
873
  if (!res.ok) await throwPlatformApiError("Failed to connect GitHub repository", res);
874
874
  return res.json();
875
875
  }
876
+ /**
877
+ * Start the per-repo connect-authorization round-trip used by a non-owner org
878
+ * member (Task 7 platform contract). The callback redirects back to `redirect`
879
+ * with either `?connect_grant=<signed>` (proof of per-repo access) or
880
+ * `?error=repo_not_accessible`. Mirrors {@link getGithubLinkUrl} but carries
881
+ * the installation + repo the grant is scoped to.
882
+ */
883
+ async getGithubConnectAuthorizeUrl(redirect, codeChallenge, installationId, repoFullName) {
884
+ const params = new URLSearchParams({
885
+ redirect,
886
+ code_challenge: codeChallenge,
887
+ code_challenge_method: "S256",
888
+ installationId,
889
+ repoFullName
890
+ });
891
+ const res = await fetch(`${this.baseUrl}/github/connect-authorize-url?${params}`, { headers: { ...this.authHeaders } });
892
+ if (!res.ok) await throwPlatformApiError("Failed to start GitHub connect authorization", res);
893
+ return res.json();
894
+ }
876
895
  async getGithubConnection(projectId) {
877
896
  const res = await fetch(`${this.baseUrl}/projects/${projectId}/github`, { headers: { ...this.authHeaders } });
878
897
  if (!res.ok) await throwPlatformApiError("Failed to get GitHub connection", res);
@@ -915,6 +934,31 @@ var PlatformClient = class {
915
934
  if (!res.ok) await throwPlatformApiError("Failed to complete GitHub link", res);
916
935
  return res.json();
917
936
  }
937
+ async getGithubJoinUrl(redirect, codeChallenge) {
938
+ const params = new URLSearchParams({
939
+ redirect,
940
+ code_challenge: codeChallenge,
941
+ code_challenge_method: "S256"
942
+ });
943
+ const res = await fetch(`${this.baseUrl}/github/join-url?${params}`, { headers: { ...this.authHeaders } });
944
+ if (!res.ok) await throwPlatformApiError("Failed to start GitHub join", res);
945
+ return res.json();
946
+ }
947
+ async completeGithubJoin(joinCode, codeVerifier) {
948
+ const res = await fetch(`${this.baseUrl}/github/join/complete`, {
949
+ method: "POST",
950
+ headers: {
951
+ "Content-Type": "application/json",
952
+ ...this.authHeaders
953
+ },
954
+ body: JSON.stringify({
955
+ join_code: joinCode,
956
+ code_verifier: codeVerifier
957
+ })
958
+ });
959
+ if (!res.ok) await throwPlatformApiError("Failed to complete GitHub join", res);
960
+ return res.json();
961
+ }
918
962
  };
919
963
  //#endregion
920
964
  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,7 +1,7 @@
1
1
  import { n as __exportAll } from "./chunk-DJd-R1mw.mjs";
2
2
  import { a as join, s as relative } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
3
3
  import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
4
- import { r as schemaSpecifier, t as discoverSchema } from "./discover-C8N1I4tK.mjs";
4
+ import { r as schemaSpecifier, t as discoverSchema } from "./discover-ZWuBvt22.mjs";
5
5
  import { mkdirSync, writeFileSync } from "node:fs";
6
6
  //#region src/drizzle/config.ts
7
7
  var config_exports = /* @__PURE__ */ __exportAll({ writeDrizzleConfig: () => writeDrizzleConfig });
@@ -21,13 +21,13 @@ function writeDrizzleConfig(root, dbPath, dialect = "sqlite") {
21
21
  const config = dialect === "postgresql" ? {
22
22
  dialect: "postgresql",
23
23
  schema: schemaSpecifier(schema, root),
24
- out: `./${relative(root, paths.migrationsDir).replace(/\\/g, "/")}`,
24
+ out: `./${relative(root, paths.migrationsDir)}`,
25
25
  migrations: { prefix: "timestamp" },
26
26
  dbCredentials: { url: dbPath }
27
27
  } : {
28
28
  dialect: "sqlite",
29
29
  schema: schemaSpecifier(schema, root),
30
- out: `./${relative(root, paths.migrationsDir).replace(/\\/g, "/")}`,
30
+ out: `./${relative(root, paths.migrationsDir)}`,
31
31
  migrations: { prefix: "timestamp" },
32
32
  dbCredentials: { url: dbPath }
33
33
  };
@@ -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-YIzxv2ZO.mjs";
3
+ import { d as getSiteDomain, t as PlatformApiError } from "./client-BlbnA92X.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,15 +2,15 @@ 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-YIzxv2ZO.mjs";
5
+ import { f as getToken, m as isStagingMode, n as PlatformClient, t as PlatformApiError } from "./client-BlbnA92X.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";
9
- import { r as detectFramework } from "./plugin-inference-C3fLzFvP.mjs";
9
+ import { r as detectFramework } from "./plugin-inference-D04iL1mW.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-q6McxXgE.mjs";
13
+ import { formatTimestamp } from "./gen-C0pV2gRQ.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";
@@ -81,8 +81,10 @@ function validatePendingMigrations(migrations, appliedNames) {
81
81
  validateMigrations(pending);
82
82
  }
83
83
  async function runDbCommand(root, args) {
84
- console.log();
85
- ge(cliTitle("db"));
84
+ const exportToStdout = args.action === "export" && !args.output;
85
+ if (exportToStdout) process.stderr.write("\n");
86
+ else console.log();
87
+ ge(cliTitle("db"), exportToStdout ? { output: process.stderr } : void 0);
86
88
  const dialect = getDatabaseDialect(readConfig(root));
87
89
  if (args.action === "push") await runPush(root, dialect);
88
90
  else if (args.action === "generate") await runGenerate(root, dialect);
@@ -97,7 +99,7 @@ async function runDbCommand(root, args) {
97
99
  else await runExport(root, args, dialect);
98
100
  }
99
101
  async function runPush(root, dialect) {
100
- const { writeDrizzleConfig } = await import("./config--wXmVOoe.mjs").then((n) => n.t);
102
+ const { writeDrizzleConfig } = await import("./config-CbJS4Krx.mjs").then((n) => n.t);
101
103
  let configPath;
102
104
  if (dialect === "postgresql") configPath = writeDrizzleConfig(root, getPgUrl(root), "postgresql");
103
105
  else {
@@ -120,7 +122,7 @@ async function runPush(root, dialect) {
120
122
  ye("Done.");
121
123
  }
122
124
  async function runGenerate(root, dialect) {
123
- const { writeDrizzleConfig } = await import("./config--wXmVOoe.mjs").then((n) => n.t);
125
+ const { writeDrizzleConfig } = await import("./config-CbJS4Krx.mjs").then((n) => n.t);
124
126
  const configPath = dialect === "postgresql" ? writeDrizzleConfig(root, "postgresql://dummy", "postgresql") : writeDrizzleConfig(root, ":memory:");
125
127
  try {
126
128
  runDrizzleKit(root, [
@@ -571,7 +573,7 @@ async function runStudio(root, dialect, remote) {
571
573
  process.exit(1);
572
574
  }
573
575
  const dbUrl = await fetchRemoteDatabaseUrl(new PlatformClient(token, { root }), projectConfig.projectId);
574
- const { writeDrizzleConfig } = await import("./config--wXmVOoe.mjs").then((n) => n.t);
576
+ const { writeDrizzleConfig } = await import("./config-CbJS4Krx.mjs").then((n) => n.t);
575
577
  const configPath = writeDrizzleConfig(root, dbUrl, "postgresql");
576
578
  R.info("Opening Drizzle Studio (remote)...");
577
579
  try {
@@ -586,7 +588,7 @@ async function runStudio(root, dialect, remote) {
586
588
  return;
587
589
  }
588
590
  if (dialect === "postgresql") {
589
- const { writeDrizzleConfig } = await import("./config--wXmVOoe.mjs").then((n) => n.t);
591
+ const { writeDrizzleConfig } = await import("./config-CbJS4Krx.mjs").then((n) => n.t);
590
592
  const configPath = writeDrizzleConfig(root, getPgUrl(root), "postgresql");
591
593
  R.info("Opening Drizzle Studio...");
592
594
  try {
@@ -600,7 +602,7 @@ async function runStudio(root, dialect, remote) {
600
602
  }
601
603
  return;
602
604
  }
603
- const { writeDrizzleConfig } = await import("./config--wXmVOoe.mjs").then((n) => n.t);
605
+ const { writeDrizzleConfig } = await import("./config-CbJS4Krx.mjs").then((n) => n.t);
604
606
  const { getMiniflareDatabasePath } = await import("./runner-BQyKUqAL.mjs");
605
607
  const dbPath = getMiniflareDatabasePath(getLocalD1PersistRoot(root), "local");
606
608
  if (!existsSync(dbPath)) {
@@ -854,13 +856,14 @@ async function runRenameMigrations(root, dialect) {
854
856
  ye("Done.");
855
857
  }
856
858
  async function runExport(root, args, dialect) {
859
+ const errOut = { output: process.stderr };
857
860
  if (dialect === "postgresql") {
858
861
  const parts = [];
859
862
  await withPgClient(root, async (client) => {
860
863
  let tables;
861
864
  if (args.table) {
862
865
  if ((await client.query("SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND tablename = $1", [args.table])).rows.length === 0) {
863
- R.error(`db: Table '${args.table}' not found.`);
866
+ R.error(`db: Table '${args.table}' not found.`, errOut);
864
867
  process.exit(1);
865
868
  }
866
869
  tables = [args.table];
@@ -902,7 +905,7 @@ async function runExport(root, args, dialect) {
902
905
  const { getMiniflareDatabasePath, openSqliteDatabase } = await import("./runner-BQyKUqAL.mjs");
903
906
  const dbPath = getMiniflareDatabasePath(getLocalD1PersistRoot(root), "local");
904
907
  if (!existsSync(dbPath)) {
905
- R.error("No local database found. Run `void dev` first.");
908
+ R.error("No local database found. Run `void dev` first.", errOut);
906
909
  process.exit(1);
907
910
  }
908
911
  const db = await openSqliteDatabase(dbPath, { readonly: true });
@@ -910,7 +913,7 @@ async function runExport(root, args, dialect) {
910
913
  let tables;
911
914
  if (args.table) {
912
915
  if (!db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(args.table)) {
913
- R.error(`db: Table '${args.table}' not found.`);
916
+ R.error(`db: Table '${args.table}' not found.`, errOut);
914
917
  process.exit(1);
915
918
  }
916
919
  tables = [args.table];
@@ -1047,7 +1050,7 @@ async function loadSeedFunction(seedPath) {
1047
1050
  return seed;
1048
1051
  }
1049
1052
  async function loadSeedSchema(root) {
1050
- const { discoverSchema } = await import("./discover-C8N1I4tK.mjs").then((n) => n.n);
1053
+ const { discoverSchema } = await import("./discover-ZWuBvt22.mjs").then((n) => n.n);
1051
1054
  const location = discoverSchema(root, readProjectPaths(root));
1052
1055
  if (!location) return {};
1053
1056
  if (location.type === "file") {
@@ -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-YIzxv2ZO.mjs";
2
+ import { f as getToken, n as PlatformClient } from "./client-BlbnA92X.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";
@@ -4,28 +4,29 @@ import { n as cliTitle, r as createSpinner, s as import_picocolors } from "./out
4
4
  import { i as resolveProjectPaths, n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
5
5
  import { t as findVoidAuthConfig } from "./config-hhMYPVRT.mjs";
6
6
  import { t as cfAccessHeaders } from "./cf-access-DKDsgwOU.mjs";
7
- import { a as isExpiredTokenError, f as getToken, i as isCliOutdatedError, m as isStagingMode, n as PlatformClient, o as parsePlatformErrorBody, p as getTokenSource, t as PlatformApiError, u as getApiUrl, y as ensureCloudflaredToken } from "./client-YIzxv2ZO.mjs";
7
+ import { a as isExpiredTokenError, f as getToken, i as isCliOutdatedError, m as isStagingMode, n as PlatformClient, o as parsePlatformErrorBody, p as getTokenSource, t as PlatformApiError, u as getApiUrl, y as ensureCloudflaredToken } from "./client-BlbnA92X.mjs";
8
8
  import { c as R, g as ge, u as Se, v as ue, x as q, y as ye } from "./dist-abzUneor.mjs";
9
9
  import { a as writeProjectConfig, r as readProjectConfig } from "./project-CH9pdo16.mjs";
10
10
  import { c as getDatabaseDialect, f as readConfig, l as isNodeTarget, p as resolveBindingNames } from "./config-8dLIngKW.mjs";
11
- import { a as scanQueuesSync, i as scanWebSocketRoutesSync, o as scanJobsSync, r as scanRoutes } from "./scan-DGEp1-1Q.mjs";
12
- import { i as inferProjectBindings, l as validateSsrEntry, n as FRAMEWORK_SCAN_DIRS, r as detectFramework } from "./plugin-inference-C3fLzFvP.mjs";
11
+ import { a as scanQueuesSync, i as scanWebSocketRoutesSync, o as scanJobsSync, r as scanRoutes } from "./scan---8wfN58.mjs";
12
+ import { i as inferProjectBindings, l as validateSsrEntry, n as FRAMEWORK_SCAN_DIRS, r as detectFramework } from "./plugin-inference-D04iL1mW.mjs";
13
13
  import { i as voidWarn, r as voidLog } from "./log-BdD_Fpms.mjs";
14
- import { t as discoverSchema } from "./discover-C8N1I4tK.mjs";
15
- import { t as findEnvFile } from "./env-types-CaJaIRXU.mjs";
16
- import { i as validateProdEnv, n as formatEnvReport, r as getDeployEnvDefaults, t as fetchRemoteSecretNames } from "./env-validation-LH6eoyW-.mjs";
17
- import { n as writeDrizzleConfig } from "./config--wXmVOoe.mjs";
14
+ import { n as mergeAndExpand, r as parseDotenvFile } from "./dotenv-lS94ymhM.mjs";
15
+ import { t as discoverSchema } from "./discover-ZWuBvt22.mjs";
16
+ import { t as findEnvFile } from "./env-types-BS8cZead.mjs";
17
+ import { i as validateProdEnv, n as formatEnvReport, r as getDeployEnvDefaults, t as fetchRemoteSecretNames } from "./env-validation-BxbtBbjh.mjs";
18
+ import { n as writeDrizzleConfig } from "./config-CbJS4Krx.mjs";
18
19
  import { t as collectMigrations } from "./collect-9rO3JFNM.mjs";
19
20
  import { n as buildMigrationPlanBundle } from "./plan-aD3wRDqF.mjs";
20
21
  import { r as validateMigrations, t as assertJournalCoherence } from "./validate-CNWm-PsL.mjs";
21
22
  import { t as scanPages } from "./scan-VCAM1oh3.mjs";
22
23
  import { n as STAGING_PROXY_URL, t as DEFAULT_PROXY_URL } from "./proxy-M3pxItg2.mjs";
23
- import { i as promptProjectSetupAction, n as promptAndCreateProject, r as promptProjectSelection } from "./create-project-pLQdzEPe.mjs";
24
+ import { i as promptProjectSetupAction, n as promptAndCreateProject, r as promptProjectSelection } from "./create-project-LjvkYziS.mjs";
24
25
  import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-D4O1_fZz.mjs";
25
26
  import { t as collectGitDeployMetadata } from "./git-metadata-Ce0AtSZL.mjs";
26
27
  import { n as lintDuplicateSources, r as mergeRoutingRules, t as lintDestinationSplats } from "./headers-BNWymgnH.mjs";
27
- import { t as promptForLoginToken } from "./login-B3l_sDwT.mjs";
28
- import { i as resolveProjectCommand, n as detectPreset, r as formatProjectCommand, t as FRAMEWORK_PRESETS } from "./preset-B7ZQZn0u.mjs";
28
+ import { t as promptForLoginToken } from "./login-CvxxF_9z.mjs";
29
+ import { i as resolveProjectCommand, n as detectPreset, r as formatProjectCommand, t as FRAMEWORK_PRESETS } from "./preset-D0My64KQ.mjs";
29
30
  import { createRequire } from "node:module";
30
31
  import { copyFileSync, cpSync, createWriteStream, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
31
32
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -56,6 +57,7 @@ function workerOwnsHtmlRouting(inputs) {
56
57
  function resolveAssetConfig(inputs) {
57
58
  return resolveAssetRoutingPolicy(inputs).assetConfig;
58
59
  }
60
+ const VOID_INTERNAL_WORKER_FIRST = ["/__void", "/__void/*"];
59
61
  function resolveAssetRoutingPolicy(inputs) {
60
62
  const workerFirst = workerOwnsHtmlRouting(inputs);
61
63
  const apiWorkerFirst = !workerFirst && (inputs.hasApiRoutes === true || inputs.authEnabled === true);
@@ -65,8 +67,15 @@ function resolveAssetRoutingPolicy(inputs) {
65
67
  run_worker_first: ["/**"]
66
68
  } : apiWorkerFirst ? {
67
69
  not_found_handling: "single-page-application",
68
- run_worker_first: ["/api", "/api/*"]
69
- } : { not_found_handling: "single-page-application" },
70
+ run_worker_first: [
71
+ "/api",
72
+ "/api/*",
73
+ ...VOID_INTERNAL_WORKER_FIRST
74
+ ]
75
+ } : {
76
+ not_found_handling: "single-page-application",
77
+ run_worker_first: [...VOID_INTERNAL_WORKER_FIRST]
78
+ },
70
79
  apiWorkerFirst,
71
80
  workerFirst,
72
81
  workerSpaFallback: workerFirst && !inputs.isSsr && !inputs.hasPages
@@ -1565,6 +1574,11 @@ const ASSET_MIME_TYPES = {
1565
1574
  svg: "image/svg+xml; charset=utf-8",
1566
1575
  txt: "text/plain; charset=utf-8",
1567
1576
  csv: "text/csv; charset=utf-8",
1577
+ md: "text/markdown; charset=utf-8",
1578
+ markdown: "text/markdown; charset=utf-8",
1579
+ yaml: "text/yaml; charset=utf-8",
1580
+ yml: "text/yaml; charset=utf-8",
1581
+ toml: "application/toml",
1568
1582
  png: "image/png",
1569
1583
  jpg: "image/jpeg",
1570
1584
  jpeg: "image/jpeg",
@@ -2341,6 +2355,7 @@ var deploy_exports = /* @__PURE__ */ __exportAll({
2341
2355
  ensurePreviouslyDeployedLiveBindingConfig: () => ensurePreviouslyDeployedLiveBindingConfig,
2342
2356
  generateDeployWrapperIfNeeded: () => generateDeployWrapperIfNeeded,
2343
2357
  hasDeploySchemaDrift: () => hasDeploySchemaDrift,
2358
+ loadDeployEnv: () => loadDeployEnv,
2344
2359
  promptDeployProjectConfig: () => promptDeployProjectConfig,
2345
2360
  resolveDeployLiveBindingConfig: () => resolveDeployLiveBindingConfig,
2346
2361
  resolveDeployWorkerMain: () => resolveDeployWorkerMain,
@@ -3646,24 +3661,7 @@ async function assertEnvSchemaValid(root, client, projectId) {
3646
3661
  * Later files win on conflict.
3647
3662
  */
3648
3663
  function loadDeployEnv(root) {
3649
- const files = [".env", ".env.production"];
3650
- const env = {};
3651
- for (const file of files) {
3652
- const filePath = join(root, file);
3653
- if (!existsSync(filePath)) continue;
3654
- const content = readFileSync(filePath, "utf-8");
3655
- for (const line of content.split("\n")) {
3656
- const trimmed = line.trim();
3657
- if (!trimmed || trimmed.startsWith("#")) continue;
3658
- const eqIndex = trimmed.indexOf("=");
3659
- if (eqIndex === -1) continue;
3660
- const key = trimmed.slice(0, eqIndex).trim();
3661
- let value = trimmed.slice(eqIndex + 1).trim();
3662
- if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'")) value = value.slice(1, -1);
3663
- env[key] = value;
3664
- }
3665
- }
3666
- const { sanitized, stripped } = stripInternalEnvKeys(env);
3664
+ const { sanitized, stripped } = stripInternalEnvKeys(mergeAndExpand([".env", ".env.production"].map((file) => parseDotenvFile(join(root, file), { expand: false })), { onWarn: (msg) => voidWarn(msg) }));
3667
3665
  if (stripped.length > 0) voidWarn(`Ignoring internal env keys from .env files: ${stripped.join(", ")}. These are reserved for Void runtime use and will not be shipped in the deploy manifest.`);
3668
3666
  return sanitized;
3669
3667
  }
@@ -36,7 +36,7 @@ function discoverSchema(root, paths = readProjectPaths(root)) {
36
36
  */
37
37
  function schemaSpecifier(location, root) {
38
38
  if (!root) return location.type === "file" ? "./db/schema.ts" : "./db/schema/*.ts";
39
- const rel = relative(root, location.path).replace(/\\/g, "/");
39
+ const rel = relative(root, location.path);
40
40
  return location.type === "file" ? `./${rel}` : `./${rel}/*.ts`;
41
41
  }
42
42
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { s as import_picocolors } from "./output-DeiS4oEX.mjs";
2
- import { f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
2
+ import { f as getToken, n as PlatformClient } from "./client-BlbnA92X.mjs";
3
3
  import { c as R, u as Se } from "./dist-abzUneor.mjs";
4
4
  import { r as readProjectConfig } from "./project-CH9pdo16.mjs";
5
5
  //#region src/cli/domain.ts
@@ -1,10 +1,10 @@
1
1
  import { a as join } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
2
  import { n as cliTitle } from "./output-DeiS4oEX.mjs";
3
- import { f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
3
+ import { f as getToken, n as PlatformClient } from "./client-BlbnA92X.mjs";
4
4
  import { c as R, g as ge, u as Se, y as ye } from "./dist-abzUneor.mjs";
5
5
  import { r as readProjectConfig } from "./project-CH9pdo16.mjs";
6
- import { r as generateEnvTypes, t as findEnvFile } from "./env-types-CaJaIRXU.mjs";
7
- import { a as loadUserEnvFile, i as validateProdEnv, n as formatEnvReport, t as fetchRemoteSecretNames } from "./env-validation-LH6eoyW-.mjs";
6
+ import { r as generateEnvTypes, t as findEnvFile } from "./env-types-BS8cZead.mjs";
7
+ import { a as loadUserEnvFile, i as validateProdEnv, n as formatEnvReport, t as fetchRemoteSecretNames } from "./env-validation-BxbtBbjh.mjs";
8
8
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
9
9
  //#region src/cli/env-example.ts
10
10
  /**
@@ -31,7 +31,7 @@ function findEnvFileForPaths(root, paths) {
31
31
  * @param outDir Absolute path to the project's `.void/` directory.
32
32
  */
33
33
  function generateEnvTypes(envFileAbs, outDir) {
34
- const importPath = relative(outDir, envFileAbs).replace(/\\/g, "/");
34
+ const importPath = relative(outDir, envFileAbs);
35
35
  const lines = [];
36
36
  lines.push("// Auto-generated by void — do not edit");
37
37
  lines.push("export {}");
@@ -1,7 +1,7 @@
1
1
  import { a as join } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
2
  import { i as voidWarn } from "./log-BdD_Fpms.mjs";
3
3
  import { n as mergeAndExpand, r as parseDotenvFile } from "./dotenv-lS94ymhM.mjs";
4
- import { t as findEnvFile } from "./env-types-CaJaIRXU.mjs";
4
+ import { t as findEnvFile } from "./env-types-BS8cZead.mjs";
5
5
  import { pathToFileURL } from "node:url";
6
6
  //#region src/host/load-user-env.ts
7
7
  /**
@@ -2,9 +2,9 @@ import { a as join, n as dirname, s as relative } from "./pathe.M-eThtNZ-BrPhGF_
2
2
  import { n as cliTitle } from "./output-DeiS4oEX.mjs";
3
3
  import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
4
4
  import { _ as me, c as R, g as ge, i as Ee, x as q, y as ye } from "./dist-abzUneor.mjs";
5
- import { n as ensureProjectTsconfig } from "./project-tsconfig-BTNuNoJ0.mjs";
5
+ import { n as ensureProjectTsconfig } from "./project-tsconfig-DMBV55K2.mjs";
6
6
  import { c as getDatabaseDialect, f as readConfig } from "./config-8dLIngKW.mjs";
7
- import { n as writeDrizzleConfig } from "./config--wXmVOoe.mjs";
7
+ import { n as writeDrizzleConfig } from "./config-CbJS4Krx.mjs";
8
8
  import { r as readJournal, t as collectMigrations } from "./collect-9rO3JFNM.mjs";
9
9
  import { n as listDrizzleArtifacts, t as assertJournalCoherence } from "./validate-CNWm-PsL.mjs";
10
10
  import { t as buildDrizzleKitSpawnEnv } from "./yarn-pnp-WLW2IHUY.mjs";
@@ -1,5 +1,5 @@
1
1
  import { s as import_picocolors } from "./output-DeiS4oEX.mjs";
2
- import { c as createCodeChallenge, f as getToken, h as openBrowser, l as createCodeVerifier, n as PlatformClient, o as parsePlatformErrorBody, s as awaitBrowserCallback, t as PlatformApiError } from "./client-YIzxv2ZO.mjs";
2
+ import { c as createCodeChallenge, f as getToken, h as openBrowser, l as createCodeVerifier, n as PlatformClient, o as parsePlatformErrorBody, s as awaitBrowserCallback, t as PlatformApiError } from "./client-BlbnA92X.mjs";
3
3
  import { _ as me, c as R, i as Ee, l as Re, x as q } 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";
@@ -106,6 +106,7 @@ async function runGithubCommand(root, args) {
106
106
  case "update": return runGithubUpdate(root, client, args);
107
107
  case "status": return runStatus(root, client, args);
108
108
  case "link": return runGithubLink(root, client);
109
+ case "join": return runGithubJoin(root, client);
109
110
  }
110
111
  }
111
112
  /**
@@ -187,6 +188,49 @@ async function runGithubLink(root, client) {
187
188
  if (status === "already_linked") R.success("GitHub account already linked.");
188
189
  else R.success("GitHub account linked.");
189
190
  }
191
+ /**
192
+ * Discover and join the shared GitHub App installations owned by the
193
+ * organizations the logged-in GitHub identity belongs to. Drives the same
194
+ * 3-endpoint localhost + PKCE handshake as {@link runGithubLink}, but against
195
+ * the platform's JOIN routes: membership upsert is idempotent, so unlike link
196
+ * there is no 409/already-linked conflict to map. The only special error is the
197
+ * fail-closed 503 raised when org-installation sharing is not configured on the
198
+ * instance.
199
+ */
200
+ async function runGithubJoin(root, client) {
201
+ const verifier = createCodeVerifier();
202
+ const challenge = createCodeChallenge(verifier);
203
+ const state = randomBytes(32).toString("hex");
204
+ let count;
205
+ try {
206
+ ({count} = await awaitBrowserCallback({
207
+ state,
208
+ buildAuthUrl: async (callback) => {
209
+ callback.searchParams.set("state", state);
210
+ const { url } = await client.getGithubJoinUrl(callback.href, challenge);
211
+ return url;
212
+ },
213
+ describeError: (p) => p.get("error") ? "GitHub authorization failed." : null,
214
+ onUrl: (url) => R.message(`Open this URL to join your organization's shared GitHub App installations:\n${import_picocolors.default.cyan(url)}`),
215
+ finalize: async (params) => {
216
+ const joinCode = params.get("join_code");
217
+ if (!joinCode) throw new Error("github: join callback did not return a join code.");
218
+ return client.completeGithubJoin(joinCode, verifier);
219
+ }
220
+ }));
221
+ } catch (err) {
222
+ if (err instanceof PlatformApiError && err.status === 503 && err.code === "github_oauth_not_configured") {
223
+ R.error("Organization installation sharing is not enabled on this Void instance.");
224
+ process.exit(1);
225
+ }
226
+ throw err;
227
+ }
228
+ if (count === 0) R.info("No new installations to join.");
229
+ else {
230
+ R.success(`Joined ${count} installation${count === 1 ? "" : "s"}.`);
231
+ R.message("Run `void github installations` to see them, then `void github connect`.");
232
+ }
233
+ }
190
234
  async function runInstallations(client) {
191
235
  const installations = await client.listGithubInstallations();
192
236
  if (installations.length === 0) {
@@ -195,6 +239,50 @@ async function runInstallations(client) {
195
239
  }
196
240
  R.message(formatInstallations(installations));
197
241
  }
242
+ /**
243
+ * Per-repo connect authorization round-trip for a non-owner org member.
244
+ *
245
+ * When the connect route returns 403 `connect_authorization_required` (Task 8),
246
+ * the member has no proof they can access the specific repo under the shared
247
+ * installation. This drives the same localhost + PKCE handshake as
248
+ * {@link runGithubLink}/{@link runGithubJoin}, but against the platform's
249
+ * connect-authorize route (Task 7): the callback mints and returns the grant IN
250
+ * the redirect URL (`?connect_grant=…`), so there is no separate `/complete`
251
+ * POST — `finalize` just reads the grant out of the callback query. A
252
+ * `?error=repo_not_accessible` callback is mapped to a friendly per-repo message
253
+ * by `describeError`, which rejects out of the handshake (no grant, no retry).
254
+ *
255
+ * Returns the grant plus the PKCE verifier the caller must echo to the connect
256
+ * route so the platform can bind the grant to this exchange.
257
+ */
258
+ async function runGithubConnectAuthorize(client, installationId, repoFullName) {
259
+ const verifier = createCodeVerifier();
260
+ const challenge = createCodeChallenge(verifier);
261
+ const state = randomBytes(32).toString("hex");
262
+ const { connectGrant } = await awaitBrowserCallback({
263
+ state,
264
+ buildAuthUrl: async (callback) => {
265
+ callback.searchParams.set("state", state);
266
+ const { url } = await client.getGithubConnectAuthorizeUrl(callback.href, challenge, installationId, repoFullName);
267
+ return url;
268
+ },
269
+ describeError: (p) => {
270
+ const e = p.get("error");
271
+ if (e === "repo_not_accessible") return `You don't have access to ${repoFullName} under this installation on GitHub.`;
272
+ return e ? "GitHub authorization failed." : null;
273
+ },
274
+ onUrl: (url) => R.message(`Open this URL to authorize access to ${repoFullName}:\n${import_picocolors.default.cyan(url)}`),
275
+ finalize: async (params) => {
276
+ const grant = params.get("connect_grant");
277
+ if (!grant) throw new Error("github: connect authorization did not return a grant.");
278
+ return { connectGrant: grant };
279
+ }
280
+ });
281
+ return {
282
+ connectGrant,
283
+ codeVerifier: verifier
284
+ };
285
+ }
198
286
  async function runConnect(root, client, args) {
199
287
  const isTTY = process.stdin.isTTY === true;
200
288
  let projectId;
@@ -367,17 +455,38 @@ async function runConnect(root, client, args) {
367
455
  const chosen = input.trim() || ".github/workflows/void-deploy.yml";
368
456
  if (chosen !== ".github/workflows/void-deploy.yml") workflowPath = chosen;
369
457
  }
458
+ const attemptConnect = (extra) => client.connectGithub(projectId, {
459
+ installationId: installation.installation_id,
460
+ repoFullName,
461
+ branch,
462
+ buildExecutor: executor,
463
+ workflowPath,
464
+ ...extra
465
+ });
370
466
  let connection;
371
467
  try {
372
- connection = await client.connectGithub(projectId, {
373
- installationId: installation.installation_id,
374
- repoFullName,
375
- branch,
376
- buildExecutor: executor,
377
- workflowPath
378
- });
468
+ connection = await attemptConnect();
379
469
  } catch (err) {
380
- if (err instanceof PlatformApiError) {
470
+ if (!(err instanceof PlatformApiError)) throw err;
471
+ if (err.status === 403 && err.code === "connect_authorization_required") {
472
+ if (!isTTY) {
473
+ R.error("connect: this installation requires per-repo authorization, which needs an interactive browser sign-in. Run `void github connect` locally to authorize, then retry.");
474
+ process.exit(1);
475
+ }
476
+ const grant = await runGithubConnectAuthorize(client, installation.installation_id, repoFullName);
477
+ try {
478
+ connection = await attemptConnect({
479
+ connectGrant: grant.connectGrant,
480
+ codeVerifier: grant.codeVerifier
481
+ });
482
+ } catch (retryErr) {
483
+ if (retryErr instanceof PlatformApiError && retryErr.status === 403) {
484
+ R.error("connect: GitHub authorization failed or expired. Run `void github connect` again.");
485
+ process.exit(1);
486
+ }
487
+ throw retryErr;
488
+ }
489
+ } else {
381
490
  const body = parsePlatformErrorBody(err.body);
382
491
  const code = body?.error ?? body?.message ?? "";
383
492
  const message = describeConnectError(err.status, code);
@@ -387,7 +496,6 @@ async function runConnect(root, client, args) {
387
496
  }
388
497
  throw err;
389
498
  }
390
- throw err;
391
499
  }
392
500
  if (workflowPath !== void 0 && connection.workflow_path !== workflowPath) {
393
501
  R.error(`connect: server did not apply workflow path ${workflowPath} (got ${connection.workflow_path ?? "none"}). The platform may be too old to support a custom workflow path.`);
package/dist/index.mjs CHANGED
@@ -1,22 +1,22 @@
1
1
  import { r as __toESM } from "./chunk-DJd-R1mw.mjs";
2
2
  import { a as join, n as dirname, s as relative } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
3
3
  import { u as require_picocolors } from "./output-DeiS4oEX.mjs";
4
- import { C as hasApiRoutes, S as resolveSandboxConfig, T as resolveAssetRoutingPolicy, _ as readWranglerCompat, a as prerenderPagesNode, b as SANDBOX_MIGRATION_TAG, c as stripInternalEnvKeys, d as ensureWranglerCompatibilityDate, f as ensureWranglerNodejsAlsFlag, g as readExistingLiveBindingConfig, h as normalizeWranglerCompatibilityFlags, i as prerenderPages, l as LIVE_MIGRATION_TAG, m as nextDurableObjectMigrationTag, n as resolveDistDir, o as filterLoadedEnv, p as hasDurableObjectSqliteMigration, r as resolveWorkerDirName, s as resolveRemoteMode, u as ensureWranglerCompat, v as resolveLiveBindingConfig, w as hasDocumentRoutes, x as isSandboxEnabled, y as syncWranglerBindings } from "./deploy-DpOdwtla.mjs";
4
+ import { C as hasApiRoutes, S as resolveSandboxConfig, T as resolveAssetRoutingPolicy, _ as readWranglerCompat, a as prerenderPagesNode, b as SANDBOX_MIGRATION_TAG, c as stripInternalEnvKeys, d as ensureWranglerCompatibilityDate, f as ensureWranglerNodejsAlsFlag, g as readExistingLiveBindingConfig, h as normalizeWranglerCompatibilityFlags, i as prerenderPages, l as LIVE_MIGRATION_TAG, m as nextDurableObjectMigrationTag, n as resolveDistDir, o as filterLoadedEnv, p as hasDurableObjectSqliteMigration, r as resolveWorkerDirName, s as resolveRemoteMode, u as ensureWranglerCompat, v as resolveLiveBindingConfig, w as hasDocumentRoutes, x as isSandboxEnabled, y as syncWranglerBindings } from "./deploy-CISNL5uK.mjs";
5
5
  import { i as resolveProjectPaths, n as readProjectPaths, t as assertNoRootSourceConventionConflicts } from "./project-paths-CCMrHYQm.mjs";
6
6
  import { n as loadVoidAuthConfig, t as findVoidAuthConfig } from "./config-hhMYPVRT.mjs";
7
- import { f as getToken, m as isStagingMode } from "./client-YIzxv2ZO.mjs";
7
+ import { f as getToken, m as isStagingMode } from "./client-BlbnA92X.mjs";
8
8
  import { r as readProjectConfig } from "./project-CH9pdo16.mjs";
9
- import { n as ensureProjectTsconfig, r as writeFileIfChanged } from "./project-tsconfig-BTNuNoJ0.mjs";
9
+ import { n as ensureProjectTsconfig, r as writeFileIfChanged } from "./project-tsconfig-DMBV55K2.mjs";
10
10
  import { c as getDatabaseDialect, f as readConfig, l as isNodeTarget, p as resolveBindingNames } from "./config-8dLIngKW.mjs";
11
- import { a as scanQueuesSync, i as scanWebSocketRoutesSync, n as scanRoutePatternsSync, o as scanJobsSync, r as scanRoutes, t as scanMiddlewareSync } from "./scan-DGEp1-1Q.mjs";
12
- import { a as SSR_CLIENT_ENTRY_RELATIVE_PATHS, c as validateSsrEntries, f as isIdentifier, g as walk, i as inferProjectBindings, l as validateSsrEntry, m as isMemberExpression, n as FRAMEWORK_SCAN_DIRS, o as SSR_SERVER_ENTRY_RELATIVE_PATHS, p as isLiteral, r as detectFramework, t as DEFAULT_SCAN_DIRS, u as inferBindingsFromSource } from "./plugin-inference-C3fLzFvP.mjs";
11
+ import { a as scanQueuesSync, i as scanWebSocketRoutesSync, n as scanRoutePatternsSync, o as scanJobsSync, r as scanRoutes, t as scanMiddlewareSync } from "./scan---8wfN58.mjs";
12
+ import { a as SSR_CLIENT_ENTRY_RELATIVE_PATHS, c as validateSsrEntries, f as isIdentifier, g as walk, i as inferProjectBindings, l as validateSsrEntry, m as isMemberExpression, n as FRAMEWORK_SCAN_DIRS, o as SSR_SERVER_ENTRY_RELATIVE_PATHS, p as isLiteral, r as detectFramework, t as DEFAULT_SCAN_DIRS, u as inferBindingsFromSource } from "./plugin-inference-D04iL1mW.mjs";
13
13
  import { i as voidWarn, n as voidError, r as voidLog, t as setShowTimestamp } from "./log-BdD_Fpms.mjs";
14
14
  import { r as parseDotenvFile } from "./dotenv-lS94ymhM.mjs";
15
- import { i as generateDbDts, n as generateQueueTypes, r as DRIZZLE_OPERATORS, t as generateRouteTypes } from "./route-types-D03ryMXz.mjs";
16
- import { t as discoverSchema } from "./discover-C8N1I4tK.mjs";
15
+ import { i as generateDbDts, n as generateQueueTypes, r as DRIZZLE_OPERATORS, t as generateRouteTypes } from "./route-types-BpSJEW20.mjs";
16
+ import { t as discoverSchema } from "./discover-ZWuBvt22.mjs";
17
17
  import { t as MagicString } from "./magic-string.es-C1Fb0uxq.mjs";
18
- import { n as findEnvFileForPaths, r as generateEnvTypes, t as findEnvFile } from "./env-types-CaJaIRXU.mjs";
19
- import { a as loadUserEnvFile } from "./env-validation-LH6eoyW-.mjs";
18
+ import { n as findEnvFileForPaths, r as generateEnvTypes, t as findEnvFile } from "./env-types-BS8cZead.mjs";
19
+ import { a as loadUserEnvFile } from "./env-validation-BxbtBbjh.mjs";
20
20
  import { i as resolveLayoutIds } from "./scan-VCAM1oh3.mjs";
21
21
  import { n as STAGING_PROXY_URL, t as DEFAULT_PROXY_URL } from "./proxy-M3pxItg2.mjs";
22
22
  import { n as lintDuplicateSources, r as mergeRoutingRules, t as lintDestinationSplats } from "./headers-BNWymgnH.mjs";
@@ -4916,7 +4916,7 @@ const STAGING_API_URL = "https://api.staging.void.cloud";
4916
4916
  */
4917
4917
  async function runAiSetupPrompt(root, token, staging, server) {
4918
4918
  const { select, text, isCancel, log } = await import("./dist-abzUneor.mjs").then((n) => n.p);
4919
- const { PlatformClient } = await import("./client-YIzxv2ZO.mjs").then((n) => n.r);
4919
+ const { PlatformClient } = await import("./client-BlbnA92X.mjs").then((n) => n.r);
4920
4920
  const { writeProjectConfig } = await import("./project-CH9pdo16.mjs").then((n) => n.n);
4921
4921
  const { inferDefaultSlug } = await import("./resolve-project-D4O1_fZz.mjs").then((n) => n.i);
4922
4922
  const client = new PlatformClient(token, staging ? STAGING_API_URL : DEFAULT_API_URL);
@@ -4945,7 +4945,7 @@ async function runAiSetupPrompt(root, token, staging, server) {
4945
4945
  let slug;
4946
4946
  if (result === "__create__") {
4947
4947
  const { validateProjectSlug } = await import("./project-slug-rX3kTOfY.mjs").then((n) => n.t);
4948
- const { createProjectWithSlugRetry } = await import("./create-project-pLQdzEPe.mjs").then((n) => n.t);
4948
+ const { createProjectWithSlugRetry } = await import("./create-project-LjvkYziS.mjs").then((n) => n.t);
4949
4949
  let created;
4950
4950
  try {
4951
4951
  created = await createProjectWithSlugRetry(client, inferDefaultSlug(root), async (defaultSlug) => {
@@ -1,19 +1,19 @@
1
1
  import { a as join, c as resolve, i as isAbsolute, n as dirname, s as relative, t as basename } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
2
  import { n as cliTitle } from "./output-DeiS4oEX.mjs";
3
3
  import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
4
- import { f as getToken, m as isStagingMode, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
4
+ import { f as getToken, m as isStagingMode, n as PlatformClient } from "./client-BlbnA92X.mjs";
5
5
  import { _ as me, c as R, g as ge, i as Ee, l as Re, u as Se, v as ue, x as q, y as ye } from "./dist-abzUneor.mjs";
6
6
  import { a as writeProjectConfig, r as readProjectConfig } from "./project-CH9pdo16.mjs";
7
- import { n as ensureProjectTsconfig, t as createProjectTsconfig } from "./project-tsconfig-BTNuNoJ0.mjs";
7
+ import { n as ensureProjectTsconfig, t as createProjectTsconfig } from "./project-tsconfig-DMBV55K2.mjs";
8
8
  import { c as getDatabaseDialect, f as readConfig } from "./config-8dLIngKW.mjs";
9
- import { r as detectFramework } from "./plugin-inference-C3fLzFvP.mjs";
9
+ import { r as detectFramework } from "./plugin-inference-D04iL1mW.mjs";
10
10
  import { r as parseDotenvFile, t as expandDotenv } from "./dotenv-lS94ymhM.mjs";
11
11
  import { t as MagicString } from "./magic-string.es-C1Fb0uxq.mjs";
12
- import { n as writeDrizzleConfig } from "./config--wXmVOoe.mjs";
12
+ import { n as writeDrizzleConfig } from "./config-CbJS4Krx.mjs";
13
13
  import { n as getAgentById, r as getPackageDir, t as detectAgents } from "./agents-MhSzNMiC.mjs";
14
- import { n as promptAndCreateProject, r as promptProjectSelection } from "./create-project-pLQdzEPe.mjs";
15
- import { t as promptForLoginToken } from "./login-B3l_sDwT.mjs";
16
- import { r as formatProjectCommand } from "./preset-B7ZQZn0u.mjs";
14
+ import { n as promptAndCreateProject, r as promptProjectSelection } from "./create-project-LjvkYziS.mjs";
15
+ import { t as promptForLoginToken } from "./login-CvxxF_9z.mjs";
16
+ import { r as formatProjectCommand } from "./preset-D0My64KQ.mjs";
17
17
  import { n as findInstalledYarnPnpRuntime, r as hasLocalLockfile, t as buildDrizzleKitSpawnEnv } from "./yarn-pnp-WLW2IHUY.mjs";
18
18
  import { createRequire } from "node:module";
19
19
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmdirSync, unlinkSync, writeFileSync } from "node:fs";
@@ -1,8 +1,8 @@
1
1
  import { n as cliTitle, s as import_picocolors } from "./output-DeiS4oEX.mjs";
2
- import { d as getSiteDomain, f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
2
+ import { d as getSiteDomain, f as getToken, n as PlatformClient } from "./client-BlbnA92X.mjs";
3
3
  import { _ as me, c as R, g as ge, y as ye } from "./dist-abzUneor.mjs";
4
4
  import { a as writeProjectConfig, r as readProjectConfig } from "./project-CH9pdo16.mjs";
5
- import { n as promptAndCreateProject, r as promptProjectSelection } from "./create-project-pLQdzEPe.mjs";
5
+ import { n as promptAndCreateProject, r as promptProjectSelection } from "./create-project-LjvkYziS.mjs";
6
6
  import { r as resolveProjectBySlug } from "./resolve-project-D4O1_fZz.mjs";
7
7
  //#region src/cli/link.ts
8
8
  async function runLink(root, slug) {
@@ -1,5 +1,5 @@
1
1
  import { a as ensureUtc, i as dim, l as tablePrefix, n as cliTitle, s as import_picocolors } from "./output-DeiS4oEX.mjs";
2
- import { f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
2
+ import { f as getToken, n as PlatformClient } from "./client-BlbnA92X.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 } from "./resolve-project-D4O1_fZz.mjs";
@@ -1,5 +1,5 @@
1
1
  import { n as cliTitle, r as createSpinner, s as import_picocolors } from "./output-DeiS4oEX.mjs";
2
- import { _ as runLogin, a as isExpiredTokenError, f as getToken, g as removeToken, m as isStagingMode, n as PlatformClient, p as getTokenSource, v as saveToken } from "./client-YIzxv2ZO.mjs";
2
+ import { _ as runLogin, a as isExpiredTokenError, f as getToken, g as removeToken, m as isStagingMode, n as PlatformClient, p as getTokenSource, v as saveToken } from "./client-BlbnA92X.mjs";
3
3
  import { _ as me, c as R, g as ge, i as Ee, x as q, y as ye } from "./dist-abzUneor.mjs";
4
4
  //#region src/cli/login.ts
5
5
  async function promptForLoginToken(root = process.cwd()) {
@@ -1,5 +1,5 @@
1
1
  import { i as dim, n as cliTitle, s as import_picocolors } from "./output-DeiS4oEX.mjs";
2
- import { f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
2
+ import { f as getToken, n as PlatformClient } from "./client-BlbnA92X.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
  //#region src/cli/logs.ts
@@ -1,5 +1,5 @@
1
1
  import { a as join, n as dirname } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
- import { f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
2
+ import { f as getToken, n as PlatformClient } from "./client-BlbnA92X.mjs";
3
3
  import { a as writeProjectConfig } from "./project-CH9pdo16.mjs";
4
4
  import { existsSync, readFileSync, readdirSync } from "node:fs";
5
5
  import { fileURLToPath } from "node:url";
@@ -359,7 +359,7 @@ const SSR_SERVER_ENTRY_RELATIVE_PATHS = ["src/main.ssr.ts", "src/main.ssr.tsx"];
359
359
  const SSR_CLIENT_ENTRY_RELATIVE_PATHS = ["src/main.client.ts", "src/main.client.tsx"];
360
360
  function resolveSingleEntry(root, entries, label, paths = readProjectPaths(root)) {
361
361
  const matches = entries.map((entryName) => ({
362
- relativePath: relative(root, join(paths.ssrDir, entryName)).replace(/\\/g, "/"),
362
+ relativePath: relative(root, join(paths.ssrDir, entryName)),
363
363
  absolutePath: join(paths.ssrDir, entryName)
364
364
  })).filter((entry) => existsSync(entry.absolutePath));
365
365
  if (matches.length === 0) return null;
@@ -3,13 +3,13 @@ import { n as cliTitle } from "./output-DeiS4oEX.mjs";
3
3
  import { i as resolveProjectPaths } from "./project-paths-CCMrHYQm.mjs";
4
4
  import { n as loadVoidAuthConfig, t as findVoidAuthConfig } from "./config-hhMYPVRT.mjs";
5
5
  import { c as R, g as ge, u as Se, y as ye } from "./dist-abzUneor.mjs";
6
- import { n as ensureProjectTsconfig, r as writeFileIfChanged } from "./project-tsconfig-BTNuNoJ0.mjs";
6
+ import { n as ensureProjectTsconfig, r as writeFileIfChanged } from "./project-tsconfig-DMBV55K2.mjs";
7
7
  import { c as getDatabaseDialect, f as readConfig } from "./config-8dLIngKW.mjs";
8
- import { r as scanRoutes } from "./scan-DGEp1-1Q.mjs";
9
- import { i as inferProjectBindings, n as FRAMEWORK_SCAN_DIRS, r as detectFramework } from "./plugin-inference-C3fLzFvP.mjs";
10
- import { i as generateDbDts, n as generateQueueTypes, t as generateRouteTypes } from "./route-types-D03ryMXz.mjs";
11
- import { t as discoverSchema } from "./discover-C8N1I4tK.mjs";
12
- import { r as generateEnvTypes, t as findEnvFile } from "./env-types-CaJaIRXU.mjs";
8
+ import { r as scanRoutes } from "./scan---8wfN58.mjs";
9
+ import { i as inferProjectBindings, n as FRAMEWORK_SCAN_DIRS, r as detectFramework } from "./plugin-inference-D04iL1mW.mjs";
10
+ import { i as generateDbDts, n as generateQueueTypes, t as generateRouteTypes } from "./route-types-BpSJEW20.mjs";
11
+ import { t as discoverSchema } from "./discover-ZWuBvt22.mjs";
12
+ import { r as generateEnvTypes, t as findEnvFile } from "./env-types-BS8cZead.mjs";
13
13
  import { n as generateVoidAuthDrizzleSchema, t as generateVoidAuthDatabaseModule } from "./drizzle-DqstQTGq.mjs";
14
14
  import { existsSync, mkdirSync, rmSync } from "node:fs";
15
15
  import { fileURLToPath } from "node:url";
@@ -1,6 +1,6 @@
1
1
  import { a as join, c as resolve } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
2
  import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
3
- import { s as hasSsrEntry } from "./plugin-inference-C3fLzFvP.mjs";
3
+ import { s as hasSsrEntry } from "./plugin-inference-D04iL1mW.mjs";
4
4
  import { i as readPackageJson, n as hasPackageDependency, t as getPackageDependencies } from "./package-json-Bg_GJdJB.mjs";
5
5
  import { existsSync } from "node:fs";
6
6
  //#region src/cli/preset.ts
@@ -1,5 +1,5 @@
1
1
  import { i as dim, l as tablePrefix, n as cliTitle, s as import_picocolors } from "./output-DeiS4oEX.mjs";
2
- import { d as getSiteDomain, f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
2
+ import { d as getSiteDomain, f as getToken, n as PlatformClient } from "./client-BlbnA92X.mjs";
3
3
  import { c as R, g as ge, y as ye } from "./dist-abzUneor.mjs";
4
4
  //#region src/cli/projects.ts
5
5
  async function runProjectsCommand(root) {
@@ -34,32 +34,32 @@ async function runProjectsCommand(root) {
34
34
  //#region src/cli/project-cmd.ts
35
35
  async function runProjectCommand(root, args) {
36
36
  if (args.subcommand === "status") {
37
- const { runListCommand } = await import("./list-B7qXBBjo.mjs");
37
+ const { runListCommand } = await import("./list-CbNNjXTm.mjs");
38
38
  return runListCommand(root, args.name || void 0);
39
39
  }
40
40
  if (args.subcommand === "link") {
41
- const { runLink } = await import("./link-BKLElphS.mjs");
41
+ const { runLink } = await import("./link-ZFmboqY3.mjs");
42
42
  return runLink(root, args.name || void 0);
43
43
  }
44
44
  if (args.subcommand === "list") return runProjectsCommand(root);
45
45
  if (args.subcommand === "logs") {
46
- const { runLogsCommand } = await import("./logs-AXm660MB.mjs");
46
+ const { runLogsCommand } = await import("./logs-BDZ9AuhM.mjs");
47
47
  return runLogsCommand(root, args.filter, args.range, args.deployment || void 0, args.level || void 0);
48
48
  }
49
49
  if (args.subcommand === "rollback") {
50
- const { runRollbackCommand } = await import("./rollback-CHVE-DeT.mjs");
50
+ const { runRollbackCommand } = await import("./rollback-DzmCCrFg.mjs");
51
51
  return runRollbackCommand(root, args.deployId || void 0);
52
52
  }
53
53
  if (args.subcommand === "cancel") {
54
- const { runCancelDeployCommand } = await import("./cancel-deploy-S2N8NSv6.mjs");
54
+ const { runCancelDeployCommand } = await import("./cancel-deploy-Gi8zmoZC.mjs");
55
55
  return runCancelDeployCommand(root, args.deployId || void 0);
56
56
  }
57
57
  if (args.subcommand === "delete") {
58
- const { runDeleteCommand } = await import("./delete-CfSe3EJO.mjs");
58
+ const { runDeleteCommand } = await import("./delete-CplfvTgU.mjs");
59
59
  return runDeleteCommand(root, args.name || void 0, { force: args.force });
60
60
  }
61
61
  if (args.subcommand === "purge-cache") {
62
- const { runPurgeCacheCommand } = await import("./cache-CMzjhxHh.mjs");
62
+ const { runPurgeCacheCommand } = await import("./cache-ACORQCIq.mjs");
63
63
  return runPurgeCacheCommand(root, args.projectSlug || void 0);
64
64
  }
65
65
  }
@@ -45,8 +45,8 @@ function createProjectTsconfig(root, hasRouteTypes, hasDb, hasSchema, options =
45
45
  if (options.redirectDbModule !== false) paths["void/db"] = ["./db.d.ts"];
46
46
  if (hasSchema) {
47
47
  const isDir = existsSync(pathsConfig.schemaDir) && !existsSync(pathsConfig.schemaFile);
48
- const schemaRel = relative(outDir, pathsConfig.schemaDir).replace(/\\/g, "/");
49
- const schemaFileRel = relative(outDir, pathsConfig.schemaFile).replace(/\\/g, "/");
48
+ const schemaRel = relative(outDir, pathsConfig.schemaDir);
49
+ const schemaFileRel = relative(outDir, pathsConfig.schemaFile);
50
50
  paths["@schema"] = [isDir ? `${schemaRel}/index.ts` : schemaFileRel];
51
51
  paths["@schema/*"] = [`${schemaRel}/*`];
52
52
  }
@@ -1,5 +1,5 @@
1
1
  import { a as ensureUtc, i as dim, n as cliTitle, r as createSpinner, s as import_picocolors } from "./output-DeiS4oEX.mjs";
2
- import { f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
2
+ import { f as getToken, n as PlatformClient } from "./client-BlbnA92X.mjs";
3
3
  import { _ as me, c as R, g as ge, i as Ee, 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/rollback.ts
@@ -1,5 +1,5 @@
1
1
  import { a as join, s as relative } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
- import { r as writeFileIfChanged } from "./project-tsconfig-BTNuNoJ0.mjs";
2
+ import { r as writeFileIfChanged } from "./project-tsconfig-DMBV55K2.mjs";
3
3
  import { mkdirSync } from "node:fs";
4
4
  //#region src/codegen/db-types.ts
5
5
  const DRIZZLE_OPERATORS = "sql, eq, ne, gt, gte, lt, lte, and, or, not, desc, asc, like, ilike, notLike, inArray, notInArray, isNull, isNotNull, between, notBetween, exists, notExists, count, sum, avg, min, max";
@@ -1,7 +1,7 @@
1
1
  import { a as join, i as isAbsolute, t as basename } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
2
  import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
3
3
  import { n as globSync, t as glob } from "./dist-5cGIJHQQ.mjs";
4
- import { d as isCallExpression, f as isIdentifier, h as isObjectExpression, p as isLiteral } from "./plugin-inference-C3fLzFvP.mjs";
4
+ import { d as isCallExpression, f as isIdentifier, h as isObjectExpression, p as isLiteral } from "./plugin-inference-D04iL1mW.mjs";
5
5
  import { o as parseRouteFilename, s as parseWebSocketFilename, t as scanPages } from "./scan-VCAM1oh3.mjs";
6
6
  import { readFileSync } from "node:fs";
7
7
  import { parseSync } from "vite";
@@ -1,5 +1,5 @@
1
1
  import { n as cliTitle } from "./output-DeiS4oEX.mjs";
2
- import { f as getToken, n as PlatformClient } from "./client-YIzxv2ZO.mjs";
2
+ import { f as getToken, n as PlatformClient } from "./client-BlbnA92X.mjs";
3
3
  import { _ as me, c as R, g as ge, n as Ce, u as Se, 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
  import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-D4O1_fZz.mjs";
@@ -51,7 +51,7 @@ function resolveTsconfigEntry(baseDir, entry) {
51
51
  return isAbsolute(entry) ? entry : resolve(baseDir, entry);
52
52
  }
53
53
  function relativeFrom(fromDir, target) {
54
- const value = relative(fromDir, target).replace(/\\/g, "/");
54
+ const value = relative(fromDir, target);
55
55
  return value.startsWith(".") ? value : `./${value}`;
56
56
  }
57
57
  function uniqueStrings(values) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "void",
3
- "version": "0.10.4",
3
+ "version": "0.10.5",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/voidzero-dev/void.git",
@@ -353,7 +353,7 @@
353
353
  "valibot": ">=1.0.0-beta.7",
354
354
  "vite": "^8.0.0",
355
355
  "zod": "^3.25.0 || ^4.0.0",
356
- "@void/md": "0.10.4"
356
+ "@void/md": "0.10.5"
357
357
  },
358
358
  "peerDependenciesMeta": {
359
359
  "@void/md": {
@@ -597,6 +597,16 @@ void github installations
597
597
 
598
598
  List all GitHub App installations linked to your account. Each entry includes the `[id: <installation_id>]` needed for `--installation` in non-interactive use.
599
599
 
600
+ ### `void github join`
601
+
602
+ ```
603
+ void github join
604
+ ```
605
+
606
+ Join the GitHub App installations your organization already has. If a teammate installed the Void GitHub App on a shared GitHub organization, run `void github join` to gain access to those installations without re-installing. Void opens your browser to authorize (a localhost + PKCE handshake, the same mechanics as `void github link`), confirms with GitHub which installations you can manage, and records your membership. Afterwards `void github installations` lists them and `void github connect` can connect your own projects to their repositories.
607
+
608
+ Requires an authenticated CLI (`void auth login` first) and organization-installation sharing enabled on your Void instance; when it is not enabled the command fails closed with a clear message. You can only join installations your GitHub authorization actually returns — you cannot name or join one you cannot access on GitHub.
609
+
600
610
  ### `void github connect`
601
611
 
602
612
  ```
@@ -633,6 +643,10 @@ void github connect my-app \
633
643
 
634
644
  **Project resolution** follows the same order as deploy: positional / `--project`, `VOID_PROJECT`, linked project (`.void/project.json`).
635
645
 
646
+ **Connecting as an organization member**
647
+
648
+ If you are a member of a GitHub organization but not the person who installed the App, `void github connect` first confirms that you personally have access to the specific repository. When it detects this, it opens your browser once to authorize access to that repo on GitHub (a localhost + PKCE handshake), then completes the connection automatically — no extra flags. Run `void github join` first so the installation appears in `void github installations`. You can only connect repositories you can access on GitHub; one you cannot see is refused with a clear message.
649
+
636
650
  ### `void github update`
637
651
 
638
652
  ```