@rakay-technology/kraft 0.7.4 → 0.7.6

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 (48) hide show
  1. package/README.md +1 -11
  2. package/dist/bare-JM3EX7S4.js +27 -0
  3. package/dist/{chunk-EW4PHKB2.js → chunk-2UQFOUSZ.js} +8 -8
  4. package/dist/{chunk-WYNM7L22.js → chunk-2Y62WP2D.js} +2 -2
  5. package/dist/{chunk-N4OALTFK.js → chunk-3RCXJZJD.js} +1 -1
  6. package/dist/{chunk-PZVKPCKE.js → chunk-4UITBYUK.js} +5 -5
  7. package/dist/{chunk-DM3PKWDC.js → chunk-7UKBMDUF.js} +9 -9
  8. package/dist/{chunk-MNV2QFHW.js → chunk-BN23UUSF.js} +1 -1
  9. package/dist/{chunk-I2TOOF2A.js → chunk-CO6FAYLO.js} +1 -1
  10. package/dist/{chunk-AJ4QZLZ2.js → chunk-DFVWR6JM.js} +2 -2
  11. package/dist/{chunk-S3QBGGVP.js → chunk-DI54Y66N.js} +3 -3
  12. package/dist/{chunk-HMJUFZK7.js → chunk-DJNKEVZ7.js} +1 -1
  13. package/dist/{chunk-JSCZT76F.js → chunk-GABTH5TU.js} +10 -8
  14. package/dist/{chunk-XVKUFMIB.js → chunk-HFOE2IXZ.js} +1 -1
  15. package/dist/{chunk-RFOBMHQ7.js → chunk-JK7KKBXI.js} +4 -4
  16. package/dist/{chunk-XGCG4MD5.js → chunk-K24SBFI2.js} +1 -1
  17. package/dist/{chunk-TAML5WMA.js → chunk-MC4X55BW.js} +3 -3
  18. package/dist/chunk-ND23EK7Y.js +81645 -0
  19. package/dist/{chunk-PNNXWA2A.js → chunk-OZUFHE2T.js} +255 -104
  20. package/dist/{chunk-YZUKHG3S.js → chunk-PCOTSRS4.js} +3 -3
  21. package/dist/{chunk-MOLPYPVH.js → chunk-SPKRI7MF.js} +6 -6
  22. package/dist/{chunk-THTEUDBC.js → chunk-TVURAFJ5.js} +13 -13
  23. package/dist/{chunk-Y7PVJUXJ.js → chunk-VFPLICBX.js} +6 -6
  24. package/dist/{chunk-BQMFIXHI.js → chunk-XBGSR22I.js} +5 -5
  25. package/dist/{chunk-OFXBNFNL.js → chunk-YY5DEAZI.js} +2 -2
  26. package/dist/{chunk-PNRPKRJU.js → chunk-ZNVAHQRY.js} +6 -6
  27. package/dist/{chunk-YRSZPVMB.js → chunk-ZQJU5CTZ.js} +1 -1
  28. package/dist/{detect-676SNZK4.js → detect-N4HFQZ6Y.js} +4 -4
  29. package/dist/{docker-GOT3Q7DJ.js → docker-DU7JA2AK.js} +8 -8
  30. package/dist/{docker-edge-executor-VO6JHHW2.js → docker-edge-executor-MPIPQHNF.js} +7 -7
  31. package/dist/{edge-import-NFCHIW7G.js → edge-import-YDPEIQDU.js} +22 -22
  32. package/dist/{edge-preflight-QUJ757C6.js → edge-preflight-TT2777R5.js} +13 -13
  33. package/dist/{ensure-container-edge-Q7IZXHGM.js → ensure-container-edge-T5WRCJSE.js} +11 -11
  34. package/dist/{executor-GKXKN52K.js → executor-ZWF2J7GS.js} +6 -6
  35. package/dist/{host-channel-preflight-Z6HYSPKO.js → host-channel-preflight-Z4QG7Q44.js} +22 -22
  36. package/dist/index.js +343 -89
  37. package/dist/{local-executor-OMMDKXCM.js → local-executor-W3O5HDLM.js} +3 -3
  38. package/dist/{nginx-VITTWZZU.js → nginx-XLDZIG4E.js} +9 -9
  39. package/dist/node-bootstrap.js +72 -37
  40. package/dist/{openresty-lua-6I3Z6PEQ.js → openresty-lua-ZNE6IBYU.js} +7 -7
  41. package/dist/{privilege-UQAI2HV4.js → privilege-IMARWVU2.js} +5 -5
  42. package/dist/server/index.js +58812 -772
  43. package/dist/{setup-JWKZIECM.js → setup-I3MTOIPW.js} +12 -12
  44. package/dist/{ssh-client-NWQVRCV7.js → ssh-client-LOCZTEUC.js} +2 -2
  45. package/dist/{up-P5DMQ5YO.js → up-IADNO7AY.js} +25 -25
  46. package/package.json +1 -1
  47. package/dist/bare-HL2GUYE2.js +0 -27
  48. package/dist/chunk-PVOWHIND.js +0 -26781
package/dist/index.js CHANGED
@@ -4,29 +4,41 @@ import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  CACHE_DIR,
7
- RELEASES,
8
7
  RELEASES_DIR,
9
8
  assetUrl,
9
+ checkRepoReleases,
10
+ clearGithubToken,
11
+ dockerAvailable,
12
+ dockerHasAuthFor,
13
+ dockerLogin,
10
14
  downloadToFile,
11
15
  ensureDashboard,
12
16
  expectedSha256,
13
17
  fetchSidecar,
14
18
  formatBytes,
19
+ githubRepo,
20
+ githubToken,
21
+ githubTokenSource,
15
22
  hashFile,
16
23
  headlessProvision,
24
+ maskToken,
17
25
  normalizeUrl,
18
26
  parseSha256,
19
27
  readCliInstall,
28
+ readStoredGithubToken,
20
29
  releaseDir,
30
+ releasesPage,
21
31
  resolveLatestTag,
22
32
  restart,
23
33
  selfInvocation,
24
34
  serviceStatus,
25
35
  startService,
26
36
  stop,
37
+ storeGithubToken,
27
38
  upCommand,
39
+ validateGithubToken,
28
40
  writeCliInstall
29
- } from "./chunk-PNNXWA2A.js";
41
+ } from "./chunk-OZUFHE2T.js";
30
42
  import {
31
43
  bootstrapAdmin,
32
44
  detectPublicIp,
@@ -36,7 +48,7 @@ import {
36
48
  internalTokenRejectedProblem,
37
49
  waitDashboard,
38
50
  waitHealthy
39
- } from "./chunk-RFOBMHQ7.js";
51
+ } from "./chunk-JK7KKBXI.js";
40
52
  import {
41
53
  completeHostEdge,
42
54
  confirmEdgeAction,
@@ -46,7 +58,7 @@ import {
46
58
  renderEdgeConflict,
47
59
  repairEdgeConflict,
48
60
  rollbackHostEdge
49
- } from "./chunk-PZVKPCKE.js";
61
+ } from "./chunk-4UITBYUK.js";
50
62
  import {
51
63
  composeDown,
52
64
  composeInternalToken,
@@ -80,10 +92,10 @@ import {
80
92
  sourceBuildDir,
81
93
  storedApiPort,
82
94
  storedDashboardPort
83
- } from "./chunk-JSCZT76F.js";
95
+ } from "./chunk-GABTH5TU.js";
84
96
  import {
85
97
  startUnitHint
86
- } from "./chunk-EW4PHKB2.js";
98
+ } from "./chunk-2UQFOUSZ.js";
87
99
  import {
88
100
  DATA_DIR,
89
101
  LOG_DIR,
@@ -97,36 +109,37 @@ import "./chunk-42WQABXM.js";
97
109
  import "./chunk-DRK3MEDS.js";
98
110
  import "./chunk-3NQQXMDR.js";
99
111
  import "./chunk-RHLNVZMS.js";
100
- import "./chunk-TAML5WMA.js";
101
- import "./chunk-I2TOOF2A.js";
112
+ import "./chunk-MC4X55BW.js";
113
+ import "./chunk-CO6FAYLO.js";
102
114
  import {
103
115
  detectInstalledProxy,
104
116
  scanImportableSites
105
- } from "./chunk-THTEUDBC.js";
106
- import "./chunk-Y7PVJUXJ.js";
117
+ } from "./chunk-TVURAFJ5.js";
118
+ import "./chunk-VFPLICBX.js";
107
119
  import "./chunk-I3DPMTSF.js";
108
- import "./chunk-YZUKHG3S.js";
120
+ import "./chunk-PCOTSRS4.js";
109
121
  import "./chunk-ONKEYSMY.js";
110
122
  import "./chunk-ZWLDLTJP.js";
111
- import "./chunk-PNRPKRJU.js";
112
- import "./chunk-DM3PKWDC.js";
113
- import "./chunk-AJ4QZLZ2.js";
114
- import "./chunk-MOLPYPVH.js";
123
+ import "./chunk-ZNVAHQRY.js";
124
+ import "./chunk-7UKBMDUF.js";
125
+ import "./chunk-DFVWR6JM.js";
126
+ import "./chunk-SPKRI7MF.js";
115
127
  import "./chunk-ZVFS4LUA.js";
116
- import "./chunk-XGCG4MD5.js";
117
- import "./chunk-HMJUFZK7.js";
128
+ import "./chunk-K24SBFI2.js";
129
+ import "./chunk-DJNKEVZ7.js";
118
130
  import {
119
131
  LocalExecutor
120
- } from "./chunk-XVKUFMIB.js";
121
- import "./chunk-S3QBGGVP.js";
122
- import "./chunk-BQMFIXHI.js";
123
- import "./chunk-WYNM7L22.js";
124
- import "./chunk-N4OALTFK.js";
125
- import "./chunk-YRSZPVMB.js";
126
- import "./chunk-OFXBNFNL.js";
132
+ } from "./chunk-HFOE2IXZ.js";
133
+ import "./chunk-DI54Y66N.js";
134
+ import "./chunk-XBGSR22I.js";
135
+ import "./chunk-2Y62WP2D.js";
136
+ import "./chunk-3RCXJZJD.js";
137
+ import "./chunk-ZQJU5CTZ.js";
138
+ import "./chunk-YY5DEAZI.js";
127
139
  import "./chunk-3CJLKL6E.js";
128
- import "./chunk-MNV2QFHW.js";
140
+ import "./chunk-BN23UUSF.js";
129
141
  import {
142
+ DEFAULT_IMAGE_REGISTRY,
130
143
  HOST_CHANNEL_AUTH_REJECTED_SHORT,
131
144
  HOST_CHANNEL_PROVISION_COMMAND,
132
145
  LOCAL_API_URL,
@@ -146,11 +159,11 @@ import {
146
159
  summarizeHostChannelCause,
147
160
  validateReleaseRepository,
148
161
  validateReleaseVersionUrl
149
- } from "./chunk-PVOWHIND.js";
162
+ } from "./chunk-ND23EK7Y.js";
150
163
  import "./chunk-PXKCZB2I.js";
151
164
 
152
165
  // src/index.ts
153
- import { Command as Command28 } from "commander";
166
+ import { Command as Command29 } from "commander";
154
167
 
155
168
  // src/lib/output.ts
156
169
  import chalk from "chalk";
@@ -317,7 +330,7 @@ function getDashboardUrl(name) {
317
330
  }
318
331
 
319
332
  // src/lib/api-client.ts
320
- var USER_AGENT = `kraft-cli/${true ? "0.7.4" : "dev"}`;
333
+ var USER_AGENT = `kraft-cli/${true ? "0.7.6" : "dev"}`;
321
334
  function getApiUrl2() {
322
335
  return `${getApiUrl()}/api`;
323
336
  }
@@ -842,8 +855,8 @@ var initCmd = new Command7("init").description("Scaffold an kraft.json in the cu
842
855
  }
843
856
  const hints = detectHints(dir);
844
857
  const scaffold = { $schema: SCHEMA_URL, ...hints };
845
- const text3 = JSON.stringify(scaffold, null, 2) + "\n";
846
- writeFileSync3(path2, text3);
858
+ const text4 = JSON.stringify(scaffold, null, 2) + "\n";
859
+ writeFileSync3(path2, text4);
847
860
  if (isJsonMode()) {
848
861
  printJson({ path: path2, config: scaffold });
849
862
  return;
@@ -1216,7 +1229,7 @@ function looksCorrupted() {
1216
1229
  const err2 = lastServiceError();
1217
1230
  return !!err2 && CORRUPTION_RE.test(err2);
1218
1231
  }
1219
- function dockerAvailable() {
1232
+ function dockerAvailable2() {
1220
1233
  const r = spawnSync(
1221
1234
  "docker",
1222
1235
  ["version", "--format", "{{.Server.Version}}"],
@@ -1234,7 +1247,7 @@ function mapState(dockerState) {
1234
1247
  return "stopped";
1235
1248
  }
1236
1249
  function dockerServices() {
1237
- if (!dockerAvailable()) return [];
1250
+ if (!dockerAvailable2()) return [];
1238
1251
  const fmt = '{{.Names}} {{.State}} {{.Label "kraft.project"}}';
1239
1252
  const r = spawnSync(
1240
1253
  "docker",
@@ -1253,7 +1266,7 @@ function dockerServices() {
1253
1266
  });
1254
1267
  }
1255
1268
  function dockerNameRunning(nameFilter) {
1256
- if (!dockerAvailable()) return null;
1269
+ if (!dockerAvailable2()) return null;
1257
1270
  const r = spawnSync(
1258
1271
  "docker",
1259
1272
  ["ps", "--filter", `name=${nameFilter}`, "--format", "{{.Names}}"],
@@ -1263,7 +1276,7 @@ function dockerNameRunning(nameFilter) {
1263
1276
  return r.stdout.trim().length > 0;
1264
1277
  }
1265
1278
  async function hostControlCheck(api) {
1266
- const { checkHostChannel } = await import("./host-channel-preflight-Z6HYSPKO.js");
1279
+ const { checkHostChannel } = await import("./host-channel-preflight-Z4QG7Q44.js");
1267
1280
  return hostControlRow(await checkHostChannel().catch(() => null), api);
1268
1281
  }
1269
1282
  var NEVER_PROVISIONED_DETAIL = `never provisioned \u2014 run \`${HOST_CHANNEL_PROVISION_COMMAND}\``;
@@ -1822,7 +1835,7 @@ async function interactiveDoctor() {
1822
1835
  continue;
1823
1836
  }
1824
1837
  if (action2 === "host-control") {
1825
- const { verifyHostChannel } = await import("./host-channel-preflight-Z6HYSPKO.js");
1838
+ const { verifyHostChannel } = await import("./host-channel-preflight-Z4QG7Q44.js");
1826
1839
  const report3 = await verifyHostChannel().catch(() => null);
1827
1840
  if (report3?.status === "fixed")
1828
1841
  log2.success("Host control is reachable now.");
@@ -3853,8 +3866,8 @@ serviceCommand.addCommand(execCmd);
3853
3866
  import { Command as Command16 } from "commander";
3854
3867
  import chalk12 from "chalk";
3855
3868
  import ora2 from "ora";
3856
- function spin(text3) {
3857
- return isJsonMode() ? null : ora2(text3).start();
3869
+ function spin(text4) {
3870
+ return isJsonMode() ? null : ora2(text4).start();
3858
3871
  }
3859
3872
  function fail2(e) {
3860
3873
  if (e instanceof ApiError) {
@@ -4106,8 +4119,8 @@ import {
4106
4119
  confirm as confirm5,
4107
4120
  log as log3
4108
4121
  } from "@clack/prompts";
4109
- function spin2(text3) {
4110
- return isJsonMode() ? null : ora3(text3).start();
4122
+ function spin2(text4) {
4123
+ return isJsonMode() ? null : ora3(text4).start();
4111
4124
  }
4112
4125
  function fail3(e) {
4113
4126
  if (e instanceof ApiError) {
@@ -4214,7 +4227,7 @@ async function runRepair2(mode) {
4214
4227
  mode === "migrate" ? "Migrating the existing proxy's sites into the edge\u2026" : "Taking over :80/:443\u2026"
4215
4228
  );
4216
4229
  try {
4217
- const { repairEdgeConflict: repairEdgeConflict2 } = await import("./edge-preflight-QUJ757C6.js");
4230
+ const { repairEdgeConflict: repairEdgeConflict2 } = await import("./edge-preflight-TT2777R5.js");
4218
4231
  sp?.stop();
4219
4232
  const res = await repairEdgeConflict2(mode, apiPort(), onLog);
4220
4233
  reportRepair(res);
@@ -4377,7 +4390,7 @@ async function panelRepair(mode) {
4377
4390
  mode === "migrate" ? "Migrating the existing proxy's sites\u2026" : "Taking over :80/:443\u2026"
4378
4391
  );
4379
4392
  try {
4380
- const { repairEdgeConflict: repairEdgeConflict2 } = await import("./edge-preflight-QUJ757C6.js");
4393
+ const { repairEdgeConflict: repairEdgeConflict2 } = await import("./edge-preflight-TT2777R5.js");
4381
4394
  sp?.stop();
4382
4395
  const res = await repairEdgeConflict2(mode, apiPort(), onLog);
4383
4396
  renderRepair(res);
@@ -5482,7 +5495,7 @@ function printMonitoringNextSteps() {
5482
5495
  info(" kraft edge analytics -p <project> per-domain analytics");
5483
5496
  }
5484
5497
  async function runMonitoringInstall(opts) {
5485
- const up = await import("./up-P5DMQ5YO.js");
5498
+ const up = await import("./up-IADNO7AY.js");
5486
5499
  let adminName = opts.adminName;
5487
5500
  let adminEmail = opts.adminEmail;
5488
5501
  let adminPassword = opts.adminPassword;
@@ -6022,8 +6035,8 @@ function report2(obj, human) {
6022
6035
  if (isJsonMode()) printJson(obj);
6023
6036
  else human();
6024
6037
  }
6025
- function spinner3(text3) {
6026
- return isJsonMode() ? null : ora5(text3).start();
6038
+ function spinner3(text4) {
6039
+ return isJsonMode() ? null : ora5(text4).start();
6027
6040
  }
6028
6041
  async function confirm6(message, yes) {
6029
6042
  if (yes) return true;
@@ -6145,20 +6158,20 @@ var upgradeToAuthCommand = new Command19("upgrade-to-auth").description("Promote
6145
6158
  await guarded(async () => {
6146
6159
  const name = opts.name;
6147
6160
  const email = opts.email;
6148
- let password3 = opts.password;
6149
- if (!password3) {
6161
+ let password4 = opts.password;
6162
+ if (!password4) {
6150
6163
  if (!process.stdin.isTTY || isJsonMode()) {
6151
6164
  err("\n --password is required in non-interactive mode.\n");
6152
6165
  process.exit(1);
6153
6166
  }
6154
- password3 = await promptHidden(" New password: ");
6167
+ password4 = await promptHidden(" New password: ");
6155
6168
  }
6156
6169
  const res = await apiRequest("/system/upgrade-to-auth", {
6157
6170
  method: "POST",
6158
6171
  body: JSON.stringify({
6159
6172
  name,
6160
6173
  email,
6161
- password: password3,
6174
+ password: password4,
6162
6175
  useOwnMailServer: opts.useOwnMailServer === true
6163
6176
  })
6164
6177
  });
@@ -6427,8 +6440,8 @@ function guard2(fn) {
6427
6440
  }
6428
6441
  };
6429
6442
  }
6430
- function spin3(text3) {
6431
- return isJsonMode() ? null : ora6(text3).start();
6443
+ function spin3(text4) {
6444
+ return isJsonMode() ? null : ora6(text4).start();
6432
6445
  }
6433
6446
  function safeParse4(data) {
6434
6447
  try {
@@ -6758,17 +6771,17 @@ postmasterCmd.addCommand(
6758
6771
  "New password (min 12 chars); prompted if omitted"
6759
6772
  ).action(
6760
6773
  guard2(async (serverId, opts) => {
6761
- let password3 = opts.password;
6762
- if (!password3) {
6774
+ let password4 = opts.password;
6775
+ if (!password4) {
6763
6776
  if (isJsonMode()) {
6764
6777
  err(" --password is required in JSON mode.");
6765
6778
  process.exit(1);
6766
6779
  }
6767
6780
  const rl = createInterface7({ input: input6, output: output6 });
6768
- password3 = (await rl.question(" New postmaster password (min 12 chars): ")).trim();
6781
+ password4 = (await rl.question(" New postmaster password (min 12 chars): ")).trim();
6769
6782
  rl.close();
6770
6783
  }
6771
- if (!password3 || password3.length < 12) {
6784
+ if (!password4 || password4.length < 12) {
6772
6785
  err(" Password must be at least 12 characters.");
6773
6786
  process.exit(1);
6774
6787
  }
@@ -6777,7 +6790,7 @@ postmasterCmd.addCommand(
6777
6790
  "/mail/credentials/postmaster",
6778
6791
  {
6779
6792
  method: "POST",
6780
- body: JSON.stringify({ serverId, password: password3 })
6793
+ body: JSON.stringify({ serverId, password: password4 })
6781
6794
  }
6782
6795
  );
6783
6796
  sp?.succeed("Postmaster password updated.");
@@ -7293,8 +7306,8 @@ import chalk17 from "chalk";
7293
7306
  // src/lib/cmd-helpers.ts
7294
7307
  import chalk16 from "chalk";
7295
7308
  import ora8 from "ora";
7296
- function spin4(text3) {
7297
- return isJsonMode() ? null : ora8(text3).start();
7309
+ function spin4(text4) {
7310
+ return isJsonMode() ? null : ora8(text4).start();
7298
7311
  }
7299
7312
  function fail4(e) {
7300
7313
  if (e instanceof ApiError) {
@@ -7449,10 +7462,10 @@ var apiCommand = new Command23("api").description(
7449
7462
  if (opts.data) init.body = opts.data;
7450
7463
  try {
7451
7464
  const res = await apiRaw(url, init);
7452
- const text3 = await res.text();
7453
- let body = text3;
7465
+ const text4 = await res.text();
7466
+ let body = text4;
7454
7467
  try {
7455
- body = JSON.parse(text3);
7468
+ body = JSON.parse(text4);
7456
7469
  } catch {
7457
7470
  }
7458
7471
  if (typeof body === "string") {
@@ -7667,7 +7680,7 @@ var installCommand = new Command25("install").description("Download and install
7667
7680
  err(e.message);
7668
7681
  process.exit(1);
7669
7682
  }
7670
- const spin5 = (text3) => isJsonMode() ? null : ora9(text3).start();
7683
+ const spin5 = (text4) => isJsonMode() ? null : ora9(text4).start();
7671
7684
  let tag;
7672
7685
  try {
7673
7686
  if (opts.version) {
@@ -7684,7 +7697,7 @@ var installCommand = new Command25("install").description("Download and install
7684
7697
  const dir = releaseDir(tag);
7685
7698
  const assetPath = join9(dir, asset.name);
7686
7699
  const sidecarPath = `${assetPath}.sha256`;
7687
- const assetUrl2 = `${RELEASES}/download/${tag}/${asset.name}`;
7700
+ const assetUrl2 = `${releasesPage()}/download/${tag}/${asset.name}`;
7688
7701
  const sidecarUrl = `${assetUrl2}.sha256`;
7689
7702
  let downloaded = false;
7690
7703
  let sha;
@@ -8056,7 +8069,7 @@ function applyOnlyArgv(selfArgs, json) {
8056
8069
  // src/commands/update.ts
8057
8070
  async function verifyHostChannelAfterUpdate() {
8058
8071
  if (isJsonMode()) return;
8059
- const { verifyHostChannel } = await import("./host-channel-preflight-Z6HYSPKO.js");
8072
+ const { verifyHostChannel } = await import("./host-channel-preflight-Z4QG7Q44.js");
8060
8073
  await verifyHostChannel().catch(() => {
8061
8074
  });
8062
8075
  }
@@ -8156,7 +8169,7 @@ async function runSourceUpdate(source, opts) {
8156
8169
  }
8157
8170
  var REINSTALL_HINT = "curl -fsSL https://get.kraft.io | sh";
8158
8171
  async function runTarballUpdate(install, opts) {
8159
- const current = "0.7.4";
8172
+ const current = "0.7.6";
8160
8173
  let latest;
8161
8174
  try {
8162
8175
  latest = (await resolveLatestTag()).replace(/^v/, "");
@@ -8277,7 +8290,7 @@ var updateCommand = new Command26("update").description("Update the Kraft CLI +
8277
8290
  const cliInstall = readCliInstall();
8278
8291
  if (cliInstall?.method === "tarball")
8279
8292
  return runTarballUpdate(cliInstall, opts);
8280
- const current = "0.7.4";
8293
+ const current = "0.7.6";
8281
8294
  let latest;
8282
8295
  try {
8283
8296
  latest = (await resolveLatestTag()).replace(/^v/, "");
@@ -8474,6 +8487,222 @@ var cacheCommand = new Command27("cache").description("Manage the local download
8474
8487
  process.exit(1);
8475
8488
  }).addCommand(pathCmd).addCommand(listCmd6).addCommand(verifyCmd2).addCommand(cleanCmd);
8476
8489
 
8490
+ // src/commands/gh.ts
8491
+ import { Command as Command28 } from "commander";
8492
+ import { spawnSync as spawnSync8 } from "child_process";
8493
+ import { password as password2, select as select4, text as text2 } from "@clack/prompts";
8494
+ function registryHost() {
8495
+ const raw = process.env.KRAFT_IMAGE_REGISTRY?.trim() || DEFAULT_IMAGE_REGISTRY;
8496
+ return raw.split("/")[0] || "ghcr.io";
8497
+ }
8498
+ function cancelled(v) {
8499
+ return typeof v === "symbol";
8500
+ }
8501
+ async function askToken() {
8502
+ const v = await password2({
8503
+ message: "GitHub token (fine-grained PAT: Contents:read + Packages:read)",
8504
+ mask: "\u2022",
8505
+ validate: (s) => s.trim() ? void 0 : "Paste a token first."
8506
+ });
8507
+ if (cancelled(v)) return null;
8508
+ return v.trim();
8509
+ }
8510
+ async function runAuth(opts) {
8511
+ const repo = opts.repo?.trim() || githubRepo();
8512
+ const host = registryHost();
8513
+ let token = opts.token?.trim();
8514
+ let tokenReused = false;
8515
+ if (!token) {
8516
+ const stored = readStoredGithubToken();
8517
+ if (stored) {
8518
+ const prev = await validateGithubToken(stored);
8519
+ if (prev.valid) {
8520
+ token = stored;
8521
+ tokenReused = true;
8522
+ if (!isJsonMode())
8523
+ info(` Reusing stored token (${maskToken(stored)}).`);
8524
+ } else if (!process.stdin.isTTY) {
8525
+ err(
8526
+ "\n Stored token is no longer valid and there's no TTY to ask for a new one \u2014 re-run with `kraft gh auth --token <tok>`.\n"
8527
+ );
8528
+ process.exit(1);
8529
+ } else {
8530
+ info(" Stored token is no longer valid \u2014 let's replace it.\n");
8531
+ }
8532
+ }
8533
+ }
8534
+ if (!token) {
8535
+ if (!process.stdin.isTTY) {
8536
+ err(
8537
+ "\n No --token and no TTY \u2014 re-run with `kraft gh auth --token <tok>`.\n"
8538
+ );
8539
+ process.exit(1);
8540
+ }
8541
+ info(` Releases repo: ${repo}`);
8542
+ info(
8543
+ " Create a token at https://github.com/settings/personal-access-tokens/new"
8544
+ );
8545
+ info(" (fine-grained, this repo only: Contents:read + Packages:read).\n");
8546
+ const asked = await askToken();
8547
+ if (asked === null) {
8548
+ err("\n Cancelled \u2014 nothing was stored.\n");
8549
+ process.exit(1);
8550
+ }
8551
+ token = asked;
8552
+ }
8553
+ if (!token) {
8554
+ err("\n No token provided.\n");
8555
+ process.exit(1);
8556
+ }
8557
+ const check = await validateGithubToken(token);
8558
+ if (!check.valid) {
8559
+ err(
8560
+ check.status === 0 ? "\n Couldn't reach api.github.com \u2014 check your network and re-run.\n" : `
8561
+ Token rejected by GitHub (HTTP ${check.status}). Check it isn't expired or revoked.
8562
+ `
8563
+ );
8564
+ process.exit(1);
8565
+ }
8566
+ const releases = await checkRepoReleases(token, repo);
8567
+ if (!releases.reachable && !isJsonMode()) {
8568
+ info(
8569
+ ` Note: ${repo}/releases/latest is not reachable with this token (HTTP ${releases.status}) \u2014 either no release is published yet or the token lacks Contents:read on that repo. Storing anyway; the install will report the definitive error.
8570
+ `
8571
+ );
8572
+ }
8573
+ storeGithubToken(token);
8574
+ if (!isJsonMode()) {
8575
+ ok(
8576
+ tokenReused ? ` GitHub token still valid (${maskToken(token)}).` : ` GitHub token stored (~/.kraft/.github-token, 0600).`
8577
+ );
8578
+ if (releases.tag) info(` Latest release on ${repo}: ${releases.tag}`);
8579
+ }
8580
+ let docker = { loggedIn: false };
8581
+ if (opts.docker === false) {
8582
+ docker = { loggedIn: false, skipped: "opt-out (--no-docker)" };
8583
+ } else if (!dockerAvailable()) {
8584
+ docker = { loggedIn: false, skipped: "no docker on PATH" };
8585
+ if (!isJsonMode()) info(" No docker on PATH \u2014 skipping registry login.");
8586
+ } else {
8587
+ let username = opts.dockerUser?.trim();
8588
+ if (!username && !process.stdin.isTTY) {
8589
+ docker = { loggedIn: false, skipped: "no --docker-user and no TTY" };
8590
+ } else {
8591
+ if (!username) {
8592
+ const asked = await text2({
8593
+ message: `GitHub username for the registry login (${host})`,
8594
+ placeholder: process.env.USER || "username",
8595
+ validate: (s) => s.trim() ? void 0 : "A username is required."
8596
+ });
8597
+ if (cancelled(asked)) {
8598
+ err("\n Cancelled \u2014 token is stored, registry login skipped.\n");
8599
+ if (isJsonMode()) printJson({ authenticated: true, repo });
8600
+ else ok(" Next: run `kraft`.");
8601
+ return;
8602
+ }
8603
+ username = asked.trim();
8604
+ }
8605
+ const res = dockerLogin(host, username, token);
8606
+ docker = { loggedIn: res.ok };
8607
+ if (res.ok) {
8608
+ if (!isJsonMode()) ok(` Registry login OK (${host} as ${username}).`);
8609
+ } else {
8610
+ err(
8611
+ `
8612
+ Registry login failed (${host}): ${res.detail || "unknown error"}`
8613
+ );
8614
+ info(" Token is stored \u2014 fix the login with:");
8615
+ info(
8616
+ ` echo $CR_PAT | docker login ${host} -u ${username} --password-stdin
8617
+ `
8618
+ );
8619
+ }
8620
+ }
8621
+ }
8622
+ if (isJsonMode()) {
8623
+ printJson({
8624
+ authenticated: true,
8625
+ repo,
8626
+ latestRelease: releases.tag,
8627
+ registry: host,
8628
+ docker
8629
+ });
8630
+ } else {
8631
+ ok(" Next: run `kraft`.");
8632
+ }
8633
+ }
8634
+ function runStatus2() {
8635
+ const token = githubToken();
8636
+ const source = githubTokenSource();
8637
+ const host = registryHost();
8638
+ const status = {
8639
+ repo: githubRepo(),
8640
+ token: token ? maskToken(token) : null,
8641
+ tokenSource: source,
8642
+ registry: host,
8643
+ registryLogin: dockerHasAuthFor(host)
8644
+ };
8645
+ if (isJsonMode()) {
8646
+ printJson(status);
8647
+ return;
8648
+ }
8649
+ if (!token) {
8650
+ info(" No GitHub token on this box. Run `kraft gh auth` to add one.");
8651
+ info(` Releases repo: ${status.repo} | registry: ${host}`);
8652
+ return;
8653
+ }
8654
+ ok(` GitHub token: ${status.token} (from ${source})`);
8655
+ info(` Releases repo: ${status.repo}`);
8656
+ info(
8657
+ status.registryLogin ? ` Registry login: present for ${host}` : ` Registry login: MISSING for ${host} \u2014 re-run \`kraft gh auth\` (or docker login).`
8658
+ );
8659
+ }
8660
+ async function runLogout(opts) {
8661
+ const host = registryHost();
8662
+ if (!opts.yes && process.stdin.isTTY && !isJsonMode()) {
8663
+ const v = await select4({
8664
+ message: "Forget the stored GitHub token (and registry login)?",
8665
+ options: [
8666
+ { value: "yes", label: "Yes, log out" },
8667
+ { value: "no", label: "Cancel" }
8668
+ ]
8669
+ });
8670
+ if (cancelled(v) || v !== "yes") {
8671
+ info(" Cancelled \u2014 token kept.");
8672
+ return;
8673
+ }
8674
+ }
8675
+ const removed = clearGithubToken();
8676
+ let dockerOut = "";
8677
+ try {
8678
+ const r = spawnSync8("docker", ["logout", host], { encoding: "utf8" });
8679
+ dockerOut = `${r.stdout ?? ""}${r.stderr ?? ""}`.trim();
8680
+ } catch {
8681
+ }
8682
+ if (isJsonMode()) {
8683
+ printJson({ loggedOut: true, tokenRemoved: removed, registry: host });
8684
+ return;
8685
+ }
8686
+ ok(
8687
+ removed ? " GitHub token forgotten." : " No stored token (env-provided tokens are untouched)."
8688
+ );
8689
+ if (dockerOut) info(` docker: ${dockerOut}`);
8690
+ }
8691
+ var ghCommand = new Command28("gh").description(
8692
+ "GitHub auth for private releases + registries (one-time setup)"
8693
+ );
8694
+ ghCommand.command("auth").description(
8695
+ "Save a GitHub token (prompted, masked) and log the registry in \u2014 then plain `kraft` works"
8696
+ ).option(
8697
+ "--token <token>",
8698
+ "Token for non-interactive use (env GITHUB_TOKEN also works)"
8699
+ ).option(
8700
+ "--repo <owner/repo>",
8701
+ "Releases repo (default: KRAFT_GITHUB_REPO or rakay-technology/kraft)"
8702
+ ).option("--docker-user <user>", "GitHub username for the registry login").option("--no-docker", "Skip the registry login, store the token only").action(runAuth);
8703
+ ghCommand.command("status").description("Show what GitHub / registry auth this box has").action(runStatus2);
8704
+ ghCommand.command("logout").description("Forget the stored token (and registry login)").option("--yes", "Skip the confirmation prompt").action(runLogout);
8705
+
8477
8706
  // src/commands/wizard.ts
8478
8707
  import chalk19 from "chalk";
8479
8708
  import open2 from "open";
@@ -8482,9 +8711,9 @@ import { join as join13 } from "path";
8482
8711
  import {
8483
8712
  intro as intro4,
8484
8713
  outro as outro4,
8485
- text as text2,
8486
- password as password2,
8487
- select as select4,
8714
+ text as text3,
8715
+ password as password3,
8716
+ select as select5,
8488
8717
  spinner as spinner4,
8489
8718
  note as note3,
8490
8719
  log as log5,
@@ -8500,13 +8729,13 @@ function ensure2(value) {
8500
8729
  }
8501
8730
  async function promptLocalAdmin() {
8502
8731
  const name = ensure2(
8503
- await text2({
8732
+ await text3({
8504
8733
  message: "Your name",
8505
8734
  validate: (v) => v?.trim() ? void 0 : "Required"
8506
8735
  })
8507
8736
  ).trim();
8508
8737
  const email = ensure2(
8509
- await text2({
8738
+ await text3({
8510
8739
  message: "Email",
8511
8740
  placeholder: "you@example.com",
8512
8741
  // Same rule the headless path enforces (isValidEmail) — an `@`-only check
@@ -8515,13 +8744,13 @@ async function promptLocalAdmin() {
8515
8744
  })
8516
8745
  ).trim().toLowerCase();
8517
8746
  const pw = ensure2(
8518
- await password2({
8747
+ await password3({
8519
8748
  message: "Password",
8520
8749
  validate: (v) => v && v.length >= 8 ? void 0 : "At least 8 characters"
8521
8750
  })
8522
8751
  );
8523
8752
  ensure2(
8524
- await password2({
8753
+ await password3({
8525
8754
  message: "Confirm password",
8526
8755
  validate: (v) => v === pw ? void 0 : "Passwords don't match"
8527
8756
  })
@@ -8712,7 +8941,7 @@ async function runWizard() {
8712
8941
  }
8713
8942
  sp.stop("Couldn't detect the public IP automatically.", 1);
8714
8943
  publicHost = ensure2(
8715
- await text2({
8944
+ await text3({
8716
8945
  message: "This server's public IP or hostname",
8717
8946
  placeholder: "203.0.113.10",
8718
8947
  validate: (v) => v?.trim() ? void 0 : "Required \u2014 the edge proxy routes traffic to this address"
@@ -8729,7 +8958,7 @@ async function runWizard() {
8729
8958
  planning: while (true) {
8730
8959
  if (stage === "reach") {
8731
8960
  const reach = ensure2(
8732
- await select4({
8961
+ await select5({
8733
8962
  message: "How should this instance be reachable?",
8734
8963
  // Default to public — most people setting up on a server/VPS want a
8735
8964
  // domain + HTTPS; localhost-only is the deliberate opt-out.
@@ -8760,7 +8989,7 @@ async function runWizard() {
8760
8989
  }
8761
8990
  if (stage === "type") {
8762
8991
  const domainType = ensure2(
8763
- await select4({
8992
+ await select5({
8764
8993
  message: "How do you want a domain + HTTPS?",
8765
8994
  initialValue: canManage ? "custom" : "byo",
8766
8995
  options: [
@@ -8789,7 +9018,7 @@ async function runWizard() {
8789
9018
  }
8790
9019
  if (stage === "custom") {
8791
9020
  const raw2 = ensure2(
8792
- await text2({
9021
+ await text3({
8793
9022
  message: "Your domain",
8794
9023
  placeholder: "ops.example.com",
8795
9024
  initialValue: customDomainInput || void 0,
@@ -8816,7 +9045,7 @@ async function runWizard() {
8816
9045
  "DNS"
8817
9046
  );
8818
9047
  const go2 = ensure2(
8819
- await select4({
9048
+ await select5({
8820
9049
  message: "A record added?",
8821
9050
  options: [
8822
9051
  {
@@ -8839,7 +9068,7 @@ async function runWizard() {
8839
9068
  break planning;
8840
9069
  }
8841
9070
  const raw = ensure2(
8842
- await text2({
9071
+ await text3({
8843
9072
  message: "Your domain (served behind your proxy)",
8844
9073
  placeholder: "ops.example.com",
8845
9074
  initialValue: byoDomainInput || void 0,
@@ -8863,7 +9092,7 @@ async function runWizard() {
8863
9092
  "Confirm"
8864
9093
  );
8865
9094
  const go = ensure2(
8866
- await select4({
9095
+ await select5({
8867
9096
  message: "Continue?",
8868
9097
  options: [
8869
9098
  { value: "go", label: "Continue" },
@@ -8908,7 +9137,7 @@ async function runWizard() {
8908
9137
  }
8909
9138
  }
8910
9139
  }
8911
- const uiTag = `v${"0.7.4"}`;
9140
+ const uiTag = `v${"0.7.6"}`;
8912
9141
  if (method === "bare") {
8913
9142
  const dl = spinner4();
8914
9143
  dl.start("Pulling the Kraft dist from GitHub");
@@ -8928,6 +9157,9 @@ async function runWizard() {
8928
9157
  log5.info(
8929
9158
  "Check your network / that this release published its dashboard asset, then re-run `kraft`."
8930
9159
  );
9160
+ log5.info(
9161
+ "Private repo? Run `kraft gh auth` once (stores a token + registry login), then re-run `kraft`."
9162
+ );
8931
9163
  process.exit(1);
8932
9164
  }
8933
9165
  }
@@ -8942,7 +9174,7 @@ async function runWizard() {
8942
9174
  let allowHostControl = true;
8943
9175
  if (method === "compose") {
8944
9176
  allowHostControl = ensure2(
8945
- await select4({
9177
+ await select5({
8946
9178
  message: "Let Kraft operate this machine's OS?",
8947
9179
  initialValue: "allow",
8948
9180
  options: [
@@ -8973,7 +9205,7 @@ async function runWizard() {
8973
9205
  const dashboardPort = String(ports.dashboard);
8974
9206
  const moved = portMoveNotice(ports, composeTrustedOriginUrls());
8975
9207
  if (moved.length) log5.info(moved.join("\n"));
8976
- if (!pinnedImagesReady({ version: "0.7.4" })) {
9208
+ if (!pinnedImagesReady({ version: "0.7.6" })) {
8977
9209
  cancel4(
8978
9210
  "The pinned Kraft image tag isn't in the registry yet \u2014 nothing on this box was changed."
8979
9211
  );
@@ -8995,6 +9227,27 @@ async function runWizard() {
8995
9227
  );
8996
9228
  process.exit(1);
8997
9229
  }
9230
+ const regHost = registryHost();
9231
+ if (!dockerHasAuthFor(regHost)) {
9232
+ const regToken = githubToken();
9233
+ if (regToken) {
9234
+ const username = ensure2(
9235
+ await text3({
9236
+ message: `GitHub username for the registry login (${regHost})`,
9237
+ placeholder: process.env.USER || "username",
9238
+ validate: (v) => v?.trim() ? void 0 : "A username is required."
9239
+ })
9240
+ );
9241
+ const logged = dockerLogin(regHost, username.trim(), regToken);
9242
+ if (logged.ok) {
9243
+ log5.info(`Registry login OK (${regHost} as ${username.trim()}).`);
9244
+ } else {
9245
+ log5.warn(
9246
+ `Registry login failed (${regHost}): ${logged.detail || "unknown error"} \u2014 the pull below will report it. Fix with \`kraft gh auth\`.`
9247
+ );
9248
+ }
9249
+ }
9250
+ }
8998
9251
  log5.step(
8999
9252
  sourceBuildDir() ? "Building the Kraft images before touching :80/:443 (first run takes a few minutes)\u2026" : "Pulling images before touching :80/:443\u2026"
9000
9253
  );
@@ -9003,7 +9256,7 @@ async function runWizard() {
9003
9256
  dashboardPort,
9004
9257
  publicUrl,
9005
9258
  trustProxy: behindProxy,
9006
- version: "0.7.4",
9259
+ version: "0.7.6",
9007
9260
  noHostControl: !allowHostControl
9008
9261
  });
9009
9262
  if (!fetched.ok) {
@@ -9034,7 +9287,7 @@ async function runWizard() {
9034
9287
  dashboardPort,
9035
9288
  publicUrl,
9036
9289
  trustProxy: behindProxy,
9037
- version: "0.7.4",
9290
+ version: "0.7.6",
9038
9291
  noHostControl: !allowHostControl
9039
9292
  });
9040
9293
  if (!up.ok) {
@@ -9126,7 +9379,7 @@ async function runWizard() {
9126
9379
  if (!result.domainRegistered)
9127
9380
  liveUrl2 = `http://localhost:${started.dashPort}`;
9128
9381
  for (const w of result.warnings) log5.warn(w);
9129
- const { verifyHostChannel } = await import("./host-channel-preflight-Z6HYSPKO.js");
9382
+ const { verifyHostChannel } = await import("./host-channel-preflight-Z4QG7Q44.js");
9130
9383
  await verifyHostChannel().catch(() => {
9131
9384
  });
9132
9385
  finishSetup({
@@ -9274,7 +9527,7 @@ ${chalk19.dim("Dashboard".padEnd(11))}${dashUrl}
9274
9527
  );
9275
9528
  }
9276
9529
  const action2 = ensure2(
9277
- await select4({
9530
+ await select5({
9278
9531
  message: "What would you like to do?",
9279
9532
  options: [
9280
9533
  ...corrupted ? [
@@ -9397,7 +9650,7 @@ ${chalk19.dim("Dashboard".padEnd(11))}${dashUrl}
9397
9650
  }
9398
9651
  case "reset": {
9399
9652
  const pw = ensure2(
9400
- await password2({
9653
+ await password3({
9401
9654
  message: "New admin password",
9402
9655
  validate: (v) => v && v.length >= 8 ? void 0 : "At least 8 characters"
9403
9656
  })
@@ -9429,8 +9682,8 @@ function attachCompletion(program2) {
9429
9682
  }
9430
9683
 
9431
9684
  // src/index.ts
9432
- var program = new Command28();
9433
- program.name("kraft").description("Kraft CLI \u2014 install, run, and manage Kraft from your terminal").version("0.7.4").option("--json", "Machine-readable JSON output (stdout data only)").hook("preAction", (thisCommand) => {
9685
+ var program = new Command29();
9686
+ program.name("kraft").description("Kraft CLI \u2014 install, run, and manage Kraft from your terminal").version("0.7.6").option("--json", "Machine-readable JSON output (stdout data only)").hook("preAction", (thisCommand) => {
9434
9687
  if (thisCommand.opts().json) setJsonMode(true);
9435
9688
  }).action(async () => {
9436
9689
  const installed = serviceStatus().installed || readInstallMethod() === "compose";
@@ -9443,6 +9696,7 @@ program.addCommand(uninstallCommand);
9443
9696
  program.addCommand(installCommand);
9444
9697
  program.addCommand(updateCommand);
9445
9698
  program.addCommand(openCommand);
9699
+ program.addCommand(ghCommand);
9446
9700
  program.addCommand(loginCommand);
9447
9701
  program.addCommand(logoutCommand);
9448
9702
  program.addCommand(initCommand);