@eve-horizon/cli 0.2.27 → 0.2.28

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/assets/local-k8s/base/agent-runtime-deployment.yaml +82 -0
  2. package/assets/local-k8s/base/agent-runtime-pvc.yaml +13 -0
  3. package/assets/local-k8s/base/agent-runtime-service.yaml +15 -0
  4. package/assets/local-k8s/base/api-deployment.yaml +63 -0
  5. package/assets/local-k8s/base/api-ingress.yaml +19 -0
  6. package/assets/local-k8s/base/api-rbac.yaml +43 -0
  7. package/assets/local-k8s/base/api-service.yaml +14 -0
  8. package/assets/local-k8s/base/app-secret.yaml +27 -0
  9. package/assets/local-k8s/base/auth-bootstrap-configmap.yaml +73 -0
  10. package/assets/local-k8s/base/auth-bootstrap-job.yaml +48 -0
  11. package/assets/local-k8s/base/buildkitd-deployment.yaml +38 -0
  12. package/assets/local-k8s/base/buildkitd-network-policy.yaml +19 -0
  13. package/assets/local-k8s/base/buildkitd-pvc.yaml +11 -0
  14. package/assets/local-k8s/base/buildkitd-service.yaml +14 -0
  15. package/assets/local-k8s/base/db-migrate-job.yaml +23 -0
  16. package/assets/local-k8s/base/gateway-deployment.yaml +51 -0
  17. package/assets/local-k8s/base/gateway-ingress.yaml +26 -0
  18. package/assets/local-k8s/base/gateway-service.yaml +14 -0
  19. package/assets/local-k8s/base/kustomization.yaml +42 -0
  20. package/assets/local-k8s/base/mailpit-deployment.yaml +44 -0
  21. package/assets/local-k8s/base/mailpit-ingress.yaml +19 -0
  22. package/assets/local-k8s/base/mailpit-service.yaml +17 -0
  23. package/assets/local-k8s/base/namespace.yaml +6 -0
  24. package/assets/local-k8s/base/orchestrator-deployment.yaml +81 -0
  25. package/assets/local-k8s/base/orchestrator-service.yaml +14 -0
  26. package/assets/local-k8s/base/postgres-secret.yaml +10 -0
  27. package/assets/local-k8s/base/postgres-statefulset.yaml +53 -0
  28. package/assets/local-k8s/base/registry-configmap.yaml +34 -0
  29. package/assets/local-k8s/base/registry-deployment.yaml +53 -0
  30. package/assets/local-k8s/base/registry-pvc.yaml +11 -0
  31. package/assets/local-k8s/base/registry-service.yaml +15 -0
  32. package/assets/local-k8s/base/sso-deployment.yaml +66 -0
  33. package/assets/local-k8s/base/sso-ingress.yaml +19 -0
  34. package/assets/local-k8s/base/sso-service.yaml +14 -0
  35. package/assets/local-k8s/base/supabase-auth-cors-middleware.yaml +22 -0
  36. package/assets/local-k8s/base/supabase-auth-deployment.yaml +100 -0
  37. package/assets/local-k8s/base/supabase-auth-ingress.yaml +21 -0
  38. package/assets/local-k8s/base/supabase-auth-service.yaml +14 -0
  39. package/assets/local-k8s/base/worker-deployment.yaml +69 -0
  40. package/assets/local-k8s/base/worker-rbac.yaml +124 -0
  41. package/assets/local-k8s/base/worker-service.yaml +14 -0
  42. package/assets/local-k8s/overlays/local/agent-runtime-org-id.patch.yaml +22 -0
  43. package/assets/local-k8s/overlays/local/agent-runtime-pvc.patch.yaml +8 -0
  44. package/assets/local-k8s/overlays/local/app-secret-ollama.patch.yaml +7 -0
  45. package/assets/local-k8s/overlays/local/kustomization.yaml +10 -0
  46. package/assets/local-k8s/overlays/local/managed-db.patch.yaml +21 -0
  47. package/dist/index.js +1298 -132
  48. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -5182,8 +5182,8 @@ var require_promise = __commonJS({
5182
5182
  exports2.Deferred = void 0;
5183
5183
  var Deferred = class {
5184
5184
  constructor() {
5185
- this._promise = new Promise((resolve7, reject) => {
5186
- this._resolve = resolve7;
5185
+ this._promise = new Promise((resolve8, reject) => {
5186
+ this._resolve = resolve8;
5187
5187
  this._reject = reject;
5188
5188
  });
5189
5189
  }
@@ -5246,10 +5246,10 @@ var require_exporter = __commonJS({
5246
5246
  var api_1 = (init_esm(), __toCommonJS(esm_exports));
5247
5247
  var suppress_tracing_1 = require_suppress_tracing();
5248
5248
  function _export(exporter, arg) {
5249
- return new Promise((resolve7) => {
5249
+ return new Promise((resolve8) => {
5250
5250
  api_1.context.with((0, suppress_tracing_1.suppressTracing)(api_1.context.active()), () => {
5251
5251
  exporter.export(arg, (result) => {
5252
- resolve7(result);
5252
+ resolve8(result);
5253
5253
  });
5254
5254
  });
5255
5255
  });
@@ -8791,7 +8791,7 @@ var require_homedir = __commonJS({
8791
8791
  "../../node_modules/.pnpm/resolve@1.22.11/node_modules/resolve/lib/homedir.js"(exports2, module2) {
8792
8792
  "use strict";
8793
8793
  var os4 = require("os");
8794
- module2.exports = os4.homedir || function homedir5() {
8794
+ module2.exports = os4.homedir || function homedir6() {
8795
8795
  var home = process.env.HOME;
8796
8796
  var user = process.env.LOGNAME || process.env.USER || process.env.LNAME || process.env.USERNAME;
8797
8797
  if (process.platform === "win32") {
@@ -9277,11 +9277,11 @@ var require_async = __commonJS({
9277
9277
  var relativePathRegex = /^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/;
9278
9278
  var windowsDriveRegex = /^\w:[/\\]*$/;
9279
9279
  var nodeModulesRegex = /[/\\]node_modules[/\\]*$/;
9280
- var homedir5 = getHomedir();
9280
+ var homedir6 = getHomedir();
9281
9281
  var defaultPaths = function() {
9282
9282
  return [
9283
- path6.join(homedir5, ".node_modules"),
9284
- path6.join(homedir5, ".node_libraries")
9283
+ path6.join(homedir6, ".node_modules"),
9284
+ path6.join(homedir6, ".node_libraries")
9285
9285
  ];
9286
9286
  };
9287
9287
  var defaultIsFile = function isFile(file, cb) {
@@ -9335,7 +9335,7 @@ var require_async = __commonJS({
9335
9335
  }
9336
9336
  return dirs;
9337
9337
  };
9338
- module2.exports = function resolve7(x, options, callback) {
9338
+ module2.exports = function resolve8(x, options, callback) {
9339
9339
  var cb = callback;
9340
9340
  var opts = options;
9341
9341
  if (typeof options === "function") {
@@ -9770,11 +9770,11 @@ var require_sync = __commonJS({
9770
9770
  var relativePathRegex = /^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/;
9771
9771
  var windowsDriveRegex = /^\w:[/\\]*$/;
9772
9772
  var nodeModulesRegex = /[/\\]node_modules[/\\]*$/;
9773
- var homedir5 = getHomedir();
9773
+ var homedir6 = getHomedir();
9774
9774
  var defaultPaths = function() {
9775
9775
  return [
9776
- path6.join(homedir5, ".node_modules"),
9777
- path6.join(homedir5, ".node_libraries")
9776
+ path6.join(homedir6, ".node_modules"),
9777
+ path6.join(homedir6, ".node_libraries")
9778
9778
  ];
9779
9779
  };
9780
9780
  var defaultIsFile = function isFile(file) {
@@ -10068,16 +10068,16 @@ var require_require_in_the_middle = __commonJS({
10068
10068
  }
10069
10069
  }
10070
10070
  var _resolve;
10071
- function resolve7(moduleName, basedir) {
10071
+ function resolve8(moduleName, basedir) {
10072
10072
  if (!_resolve) {
10073
10073
  if (require.resolve && require.resolve.paths) {
10074
10074
  _resolve = function(moduleName2, basedir2) {
10075
10075
  return require.resolve(moduleName2, { paths: [basedir2] });
10076
10076
  };
10077
10077
  } else {
10078
- const resolve8 = require_resolve();
10078
+ const resolve9 = require_resolve();
10079
10079
  _resolve = function(moduleName2, basedir2) {
10080
- return resolve8.sync(moduleName2, { basedir: basedir2 });
10080
+ return resolve9.sync(moduleName2, { basedir: basedir2 });
10081
10081
  };
10082
10082
  }
10083
10083
  }
@@ -10235,7 +10235,7 @@ var require_require_in_the_middle = __commonJS({
10235
10235
  if (!matchFound) {
10236
10236
  let res;
10237
10237
  try {
10238
- res = resolve7(moduleName, basedir);
10238
+ res = resolve8(moduleName, basedir);
10239
10239
  } catch (e) {
10240
10240
  debug("could not resolve module: %s", moduleName);
10241
10241
  self2._cache.set(filename, exports3, core);
@@ -10537,8 +10537,8 @@ var require_import_in_the_middle = __commonJS({
10537
10537
  function waitForAllMessagesAcknowledged() {
10538
10538
  const timer2 = setInterval(() => {
10539
10539
  }, 1e3);
10540
- const promise = new Promise((resolve7) => {
10541
- resolveFn = resolve7;
10540
+ const promise = new Promise((resolve8) => {
10541
+ resolveFn = resolve8;
10542
10542
  }).then(() => {
10543
10543
  clearInterval(timer2);
10544
10544
  });
@@ -18249,10 +18249,10 @@ var require_instrumentation3 = __commonJS({
18249
18249
  if (typeof (maybePromise === null || maybePromise === void 0 ? void 0 : maybePromise.then) === "function") {
18250
18250
  return maybePromise.then((value) => {
18251
18251
  plugin._applyResponseHook(span, null, value);
18252
- return new Promise((resolve7) => plugin._endSpan(span, void 0, () => resolve7(value)));
18252
+ return new Promise((resolve8) => plugin._endSpan(span, void 0, () => resolve8(value)));
18253
18253
  }, (err) => {
18254
18254
  plugin._applyResponseHook(span, err);
18255
- return new Promise((resolve7, reject) => plugin._endSpan(span, err, () => reject(err)));
18255
+ return new Promise((resolve8, reject) => plugin._endSpan(span, err, () => reject(err)));
18256
18256
  });
18257
18257
  }
18258
18258
  return maybePromise;
@@ -19484,7 +19484,7 @@ var require_aws_sdk = __commonJS({
19484
19484
  const requestMetadata = self2.servicesExtensions.requestPreSpanHook(normalizedRequest, self2.getConfig(), self2._diag);
19485
19485
  const span = self2._startAwsV3Span(normalizedRequest, requestMetadata);
19486
19486
  const activeContextWithSpan = api_1.trace.setSpan(api_1.context.active(), span);
19487
- const handlerPromise = new Promise((resolve7, reject) => {
19487
+ const handlerPromise = new Promise((resolve8, reject) => {
19488
19488
  Promise.resolve(regionPromise).then((resolvedRegion) => {
19489
19489
  normalizedRequest.region = resolvedRegion;
19490
19490
  span.setAttribute(enums_1.AttributeNames.AWS_REGION, resolvedRegion);
@@ -19542,7 +19542,7 @@ var require_aws_sdk = __commonJS({
19542
19542
  span.end();
19543
19543
  });
19544
19544
  promiseWithResponseLogic.then((res) => {
19545
- resolve7(res);
19545
+ resolve8(res);
19546
19546
  }).catch((err) => reject(err));
19547
19547
  });
19548
19548
  });
@@ -20194,12 +20194,12 @@ var require_instrumentation5 = __commonJS({
20194
20194
  }
20195
20195
  function wrapPromise(span, promise, successCallback) {
20196
20196
  return promise.then((result) => {
20197
- return new Promise((resolve7) => {
20197
+ return new Promise((resolve8) => {
20198
20198
  if (successCallback) {
20199
20199
  successCallback(span, result);
20200
20200
  }
20201
20201
  span.end();
20202
- resolve7(result);
20202
+ resolve8(result);
20203
20203
  });
20204
20204
  }).catch((error) => {
20205
20205
  return new Promise((_, reject) => {
@@ -22394,7 +22394,7 @@ var require_instrumentation12 = __commonJS({
22394
22394
  };
22395
22395
  const functionWithOriginalProperties = patchedFunctionWithOriginalProperties(patchedFunction, original);
22396
22396
  const promisified = function(path6) {
22397
- return new Promise((resolve7) => functionWithOriginalProperties(path6, resolve7));
22397
+ return new Promise((resolve8) => functionWithOriginalProperties(path6, resolve8));
22398
22398
  };
22399
22399
  Object.defineProperty(promisified, "name", { value: functionName });
22400
22400
  Object.defineProperty(functionWithOriginalProperties, util_1.promisify.custom, {
@@ -27944,8 +27944,8 @@ var require_promise2 = __commonJS({
27944
27944
  exports2.Deferred = void 0;
27945
27945
  var Deferred = class {
27946
27946
  constructor() {
27947
- this._promise = new Promise((resolve7, reject) => {
27948
- this._resolve = resolve7;
27947
+ this._promise = new Promise((resolve8, reject) => {
27948
+ this._resolve = resolve8;
27949
27949
  this._reject = reject;
27950
27950
  });
27951
27951
  }
@@ -28008,10 +28008,10 @@ var require_exporter2 = __commonJS({
28008
28008
  var api_1 = (init_esm(), __toCommonJS(esm_exports));
28009
28009
  var suppress_tracing_1 = require_suppress_tracing2();
28010
28010
  function _export(exporter, arg) {
28011
- return new Promise((resolve7) => {
28011
+ return new Promise((resolve8) => {
28012
28012
  api_1.context.with((0, suppress_tracing_1.suppressTracing)(api_1.context.active()), () => {
28013
28013
  exporter.export(arg, (result) => {
28014
- resolve7(result);
28014
+ resolve8(result);
28015
28015
  });
28016
28016
  });
28017
28017
  });
@@ -29941,7 +29941,7 @@ var require_instrumentation18 = __commonJS({
29941
29941
  _getConsumerRunPatch() {
29942
29942
  const instrumentation = this;
29943
29943
  return (original) => {
29944
- return function run(...args) {
29944
+ return function run2(...args) {
29945
29945
  const config = args[0];
29946
29946
  if (config === null || config === void 0 ? void 0 : config.eachMessage) {
29947
29947
  if ((0, instrumentation_1.isWrapped)(config.eachMessage)) {
@@ -35758,11 +35758,11 @@ var require_instrumentation28 = __commonJS({
35758
35758
  }
35759
35759
  if (result instanceof Promise) {
35760
35760
  return result.then((result2) => {
35761
- return new Promise((resolve7) => {
35761
+ return new Promise((resolve8) => {
35762
35762
  utils.handleExecutionResult(plugin.getConfig(), span, result2);
35763
35763
  recordDuration();
35764
35764
  span.end();
35765
- resolve7(result2);
35765
+ resolve8(result2);
35766
35766
  });
35767
35767
  }).catch((error) => {
35768
35768
  return new Promise((_, reject) => {
@@ -37077,10 +37077,10 @@ var require_utils27 = __commonJS({
37077
37077
  };
37078
37078
  exports2.renameHttpSpan = renameHttpSpan;
37079
37079
  var once = (fn) => {
37080
- let run = true;
37080
+ let run2 = true;
37081
37081
  return () => {
37082
- if (run) {
37083
- run = false;
37082
+ if (run2) {
37083
+ run2 = false;
37084
37084
  fn();
37085
37085
  }
37086
37086
  };
@@ -38786,7 +38786,7 @@ var require_utils30 = __commonJS({
38786
38786
  "use strict";
38787
38787
  Object.defineProperty(exports2, "__esModule", { value: true });
38788
38788
  exports2.normalizeType = exports2.normalizeArch = void 0;
38789
- var normalizeArch = (nodeArchString) => {
38789
+ var normalizeArch2 = (nodeArchString) => {
38790
38790
  switch (nodeArchString) {
38791
38791
  case "arm":
38792
38792
  return "arm32";
@@ -38798,7 +38798,7 @@ var require_utils30 = __commonJS({
38798
38798
  return nodeArchString;
38799
38799
  }
38800
38800
  };
38801
- exports2.normalizeArch = normalizeArch;
38801
+ exports2.normalizeArch = normalizeArch2;
38802
38802
  var normalizeType = (nodePlatform) => {
38803
38803
  switch (nodePlatform) {
38804
38804
  case "sunos":
@@ -39672,7 +39672,7 @@ var require_AlibabaCloudEcsDetector = __commonJS({
39672
39672
  return await this._fetchString(options);
39673
39673
  }
39674
39674
  async _fetchString(options) {
39675
- return new Promise((resolve7, reject) => {
39675
+ return new Promise((resolve8, reject) => {
39676
39676
  const timeoutId = setTimeout(() => {
39677
39677
  req.destroy(new Error("ECS metadata api request timed out."));
39678
39678
  }, this.MILLISECONDS_TIME_OUT);
@@ -39690,7 +39690,7 @@ var require_AlibabaCloudEcsDetector = __commonJS({
39690
39690
  reject(err);
39691
39691
  });
39692
39692
  res.on("end", () => {
39693
- resolve7(rawData);
39693
+ resolve8(rawData);
39694
39694
  });
39695
39695
  });
39696
39696
  req.on("error", (err) => {
@@ -39947,7 +39947,7 @@ var require_AwsEc2DetectorSync = __commonJS({
39947
39947
  * the identity properties in a local map.
39948
39948
  */
39949
39949
  async _fetchString(options) {
39950
- return new Promise((resolve7, reject) => {
39950
+ return new Promise((resolve8, reject) => {
39951
39951
  const timeoutId = setTimeout(() => {
39952
39952
  req.abort();
39953
39953
  reject(new Error("EC2 metadata api request timed out."));
@@ -39961,7 +39961,7 @@ var require_AwsEc2DetectorSync = __commonJS({
39961
39961
  res.on("end", () => {
39962
39962
  if (statusCode && statusCode >= 200 && statusCode < 300) {
39963
39963
  try {
39964
- resolve7(rawData);
39964
+ resolve8(rawData);
39965
39965
  } catch (e) {
39966
39966
  reject(e);
39967
39967
  }
@@ -40127,14 +40127,14 @@ var require_AwsEcsDetectorSync = __commonJS({
40127
40127
  return match[1];
40128
40128
  }
40129
40129
  static _getUrlAsJson(url) {
40130
- return new Promise((resolve7, reject) => {
40130
+ return new Promise((resolve8, reject) => {
40131
40131
  const request = http.get(url, (response) => {
40132
40132
  if (response.statusCode && response.statusCode >= 400) {
40133
40133
  reject(new Error(`Request to '${url}' failed with status ${response.statusCode}`));
40134
40134
  }
40135
40135
  let responseBody = "";
40136
40136
  response.on("data", (chunk) => responseBody += chunk.toString());
40137
- response.on("end", () => resolve7(responseBody));
40137
+ response.on("end", () => resolve8(responseBody));
40138
40138
  request.on("error", reject);
40139
40139
  });
40140
40140
  request.setTimeout(HTTP_TIMEOUT_IN_MS, () => {
@@ -40319,7 +40319,7 @@ var require_AwsEksDetectorSync = __commonJS({
40319
40319
  * the identity properties in a local map.
40320
40320
  */
40321
40321
  async _fetchString(options) {
40322
- return await new Promise((resolve7, reject) => {
40322
+ return await new Promise((resolve8, reject) => {
40323
40323
  const timeoutId = setTimeout(() => {
40324
40324
  req.abort();
40325
40325
  reject(new Error("EKS metadata api request timed out."));
@@ -40333,7 +40333,7 @@ var require_AwsEksDetectorSync = __commonJS({
40333
40333
  res.on("end", () => {
40334
40334
  if (statusCode && statusCode >= 200 && statusCode < 300) {
40335
40335
  try {
40336
- resolve7(rawData);
40336
+ resolve8(rawData);
40337
40337
  } catch (e) {
40338
40338
  reject(e);
40339
40339
  }
@@ -42880,7 +42880,7 @@ var require_lib2 = __commonJS({
42880
42880
  let accum = [];
42881
42881
  let accumBytes = 0;
42882
42882
  let abort = false;
42883
- return new Body.Promise(function(resolve7, reject) {
42883
+ return new Body.Promise(function(resolve8, reject) {
42884
42884
  let resTimeout;
42885
42885
  if (_this4.timeout) {
42886
42886
  resTimeout = setTimeout(function() {
@@ -42914,7 +42914,7 @@ var require_lib2 = __commonJS({
42914
42914
  }
42915
42915
  clearTimeout(resTimeout);
42916
42916
  try {
42917
- resolve7(Buffer.concat(accum, accumBytes));
42917
+ resolve8(Buffer.concat(accum, accumBytes));
42918
42918
  } catch (err) {
42919
42919
  reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, "system", err));
42920
42920
  }
@@ -43589,7 +43589,7 @@ var require_lib2 = __commonJS({
43589
43589
  throw new Error("native promise missing, set fetch.Promise to your favorite alternative");
43590
43590
  }
43591
43591
  Body.Promise = fetch2.Promise;
43592
- return new fetch2.Promise(function(resolve7, reject) {
43592
+ return new fetch2.Promise(function(resolve8, reject) {
43593
43593
  const request = new Request(url, opts);
43594
43594
  const options = getNodeRequestOptions(request);
43595
43595
  const send = (options.protocol === "https:" ? https : http).request;
@@ -43722,7 +43722,7 @@ var require_lib2 = __commonJS({
43722
43722
  requestOpts.body = void 0;
43723
43723
  requestOpts.headers.delete("content-length");
43724
43724
  }
43725
- resolve7(fetch2(new Request(locationURL, requestOpts)));
43725
+ resolve8(fetch2(new Request(locationURL, requestOpts)));
43726
43726
  finalize();
43727
43727
  return;
43728
43728
  }
@@ -43743,7 +43743,7 @@ var require_lib2 = __commonJS({
43743
43743
  const codings = headers.get("Content-Encoding");
43744
43744
  if (!request.compress || request.method === "HEAD" || codings === null || res.statusCode === 204 || res.statusCode === 304) {
43745
43745
  response = new Response(body, response_options);
43746
- resolve7(response);
43746
+ resolve8(response);
43747
43747
  return;
43748
43748
  }
43749
43749
  const zlibOptions = {
@@ -43753,7 +43753,7 @@ var require_lib2 = __commonJS({
43753
43753
  if (codings == "gzip" || codings == "x-gzip") {
43754
43754
  body = body.pipe(zlib.createGunzip(zlibOptions));
43755
43755
  response = new Response(body, response_options);
43756
- resolve7(response);
43756
+ resolve8(response);
43757
43757
  return;
43758
43758
  }
43759
43759
  if (codings == "deflate" || codings == "x-deflate") {
@@ -43765,12 +43765,12 @@ var require_lib2 = __commonJS({
43765
43765
  body = body.pipe(zlib.createInflateRaw());
43766
43766
  }
43767
43767
  response = new Response(body, response_options);
43768
- resolve7(response);
43768
+ resolve8(response);
43769
43769
  });
43770
43770
  raw.on("end", function() {
43771
43771
  if (!response) {
43772
43772
  response = new Response(body, response_options);
43773
- resolve7(response);
43773
+ resolve8(response);
43774
43774
  }
43775
43775
  });
43776
43776
  return;
@@ -43778,11 +43778,11 @@ var require_lib2 = __commonJS({
43778
43778
  if (codings == "br" && typeof zlib.createBrotliDecompress === "function") {
43779
43779
  body = body.pipe(zlib.createBrotliDecompress());
43780
43780
  response = new Response(body, response_options);
43781
- resolve7(response);
43781
+ resolve8(response);
43782
43782
  return;
43783
43783
  }
43784
43784
  response = new Response(body, response_options);
43785
- resolve7(response);
43785
+ resolve8(response);
43786
43786
  });
43787
43787
  writeToStream(req, request);
43788
43788
  });
@@ -44141,8 +44141,8 @@ var require_retry = __commonJS({
44141
44141
  }
44142
44142
  const delay = getNextRetryDelay(config);
44143
44143
  err.config.retryConfig.currentRetryAttempt += 1;
44144
- const backoff2 = config.retryBackoff ? config.retryBackoff(err, delay) : new Promise((resolve7) => {
44145
- setTimeout(resolve7, delay);
44144
+ const backoff2 = config.retryBackoff ? config.retryBackoff(err, delay) : new Promise((resolve8) => {
44145
+ setTimeout(resolve8, delay);
44146
44146
  });
44147
44147
  if (config.onRetryAttempt) {
44148
44148
  config.onRetryAttempt(err);
@@ -44624,8 +44624,8 @@ var require_helpers = __commonJS({
44624
44624
  function req(url, opts = {}) {
44625
44625
  const href = typeof url === "string" ? url : url.href;
44626
44626
  const req2 = (href.startsWith("https:") ? https : http).request(url, opts);
44627
- const promise = new Promise((resolve7, reject) => {
44628
- req2.once("response", resolve7).once("error", reject).end();
44627
+ const promise = new Promise((resolve8, reject) => {
44628
+ req2.once("response", resolve8).once("error", reject).end();
44629
44629
  });
44630
44630
  req2.then = promise.then.bind(promise);
44631
44631
  return req2;
@@ -44802,7 +44802,7 @@ var require_parse_proxy_response = __commonJS({
44802
44802
  var debug_1 = __importDefault(require_src3());
44803
44803
  var debug = (0, debug_1.default)("https-proxy-agent:parse-proxy-response");
44804
44804
  function parseProxyResponse(socket) {
44805
- return new Promise((resolve7, reject) => {
44805
+ return new Promise((resolve8, reject) => {
44806
44806
  let buffersLength = 0;
44807
44807
  const buffers = [];
44808
44808
  function read() {
@@ -44868,7 +44868,7 @@ var require_parse_proxy_response = __commonJS({
44868
44868
  }
44869
44869
  debug("got proxy server response: %o %o", firstLine, headers);
44870
44870
  cleanup();
44871
- resolve7({
44871
+ resolve8({
44872
44872
  connect: {
44873
44873
  statusCode,
44874
44874
  statusText,
@@ -45169,11 +45169,11 @@ var require_gaxios = __commonJS({
45169
45169
  if (!opts.validateStatus(translatedResponse.status)) {
45170
45170
  if (opts.responseType === "stream") {
45171
45171
  let response = "";
45172
- await new Promise((resolve7) => {
45172
+ await new Promise((resolve8) => {
45173
45173
  (translatedResponse === null || translatedResponse === void 0 ? void 0 : translatedResponse.data).on("data", (chunk) => {
45174
45174
  response += chunk;
45175
45175
  });
45176
- (translatedResponse === null || translatedResponse === void 0 ? void 0 : translatedResponse.data).on("end", resolve7);
45176
+ (translatedResponse === null || translatedResponse === void 0 ? void 0 : translatedResponse.data).on("end", resolve8);
45177
45177
  });
45178
45178
  translatedResponse.data = response;
45179
45179
  }
@@ -48246,7 +48246,7 @@ var require_AzureVmDetector = __commonJS({
48246
48246
  Metadata: "True"
48247
48247
  }
48248
48248
  };
48249
- const metadata = await new Promise((resolve7, reject) => {
48249
+ const metadata = await new Promise((resolve8, reject) => {
48250
48250
  const timeoutId = setTimeout(() => {
48251
48251
  req.destroy();
48252
48252
  reject(new Error("Azure metadata service request timed out."));
@@ -48260,7 +48260,7 @@ var require_AzureVmDetector = __commonJS({
48260
48260
  res.on("end", () => {
48261
48261
  if (statusCode && statusCode >= 200 && statusCode < 300) {
48262
48262
  try {
48263
- resolve7(JSON.parse(rawData));
48263
+ resolve8(JSON.parse(rawData));
48264
48264
  } catch (error) {
48265
48265
  reject(error);
48266
48266
  }
@@ -50468,6 +50468,95 @@ eve-new-project-setup skill to complete configuration.`,
50468
50468
  "eve init my-app --template https://github.com/myorg/custom-starter"
50469
50469
  ]
50470
50470
  },
50471
+ local: {
50472
+ description: `Local development environment management.
50473
+
50474
+ Manages a local k3d Kubernetes cluster running the Eve platform.
50475
+ Requires Docker Desktop; k3d and kubectl are auto-managed by the CLI.`,
50476
+ usage: "eve local <up|down|status|reset|logs|health> [options]",
50477
+ subcommands: {
50478
+ up: {
50479
+ description: "Create/prepare local cluster and deploy Eve services",
50480
+ usage: "eve local up [--skip-deploy] [--skip-health] [--timeout <seconds>] [--version <tag>] [--verbose]",
50481
+ options: [
50482
+ "--skip-deploy Create cluster only, skip deploy step",
50483
+ "--skip-health Skip waiting for API health",
50484
+ "--timeout <sec> Health wait timeout in seconds (default: 300)",
50485
+ "--version <tag> Platform image version (default: latest)",
50486
+ "--verbose Print detailed command output"
50487
+ ],
50488
+ examples: [
50489
+ "eve local up",
50490
+ "eve local up --version 0.1.70",
50491
+ "eve local up --skip-deploy",
50492
+ "eve local up --timeout 600"
50493
+ ]
50494
+ },
50495
+ down: {
50496
+ description: "Stop local stack resources, or destroy cluster entirely",
50497
+ usage: "eve local down [--destroy] [--force]",
50498
+ options: [
50499
+ "--destroy Delete k3d cluster and persistent data",
50500
+ "--force Skip confirmation prompts"
50501
+ ],
50502
+ examples: [
50503
+ "eve local down",
50504
+ "eve local down --destroy --force"
50505
+ ]
50506
+ },
50507
+ status: {
50508
+ description: "Show cluster state, service readiness, and URLs",
50509
+ usage: "eve local status [--watch] [--json]",
50510
+ options: [
50511
+ "--watch Refresh every 5 seconds",
50512
+ "--json Machine-readable JSON output"
50513
+ ],
50514
+ examples: [
50515
+ "eve local status",
50516
+ "eve local status --watch",
50517
+ "eve local status --json"
50518
+ ]
50519
+ },
50520
+ reset: {
50521
+ description: "Destroy and recreate local stack",
50522
+ usage: "eve local reset [--force]",
50523
+ options: [
50524
+ "--force Skip confirmation prompts"
50525
+ ],
50526
+ examples: [
50527
+ "eve local reset --force"
50528
+ ]
50529
+ },
50530
+ logs: {
50531
+ description: "Stream or dump logs from local stack services",
50532
+ usage: "eve local logs [service] [--follow] [--tail <n>] [--since <duration>]",
50533
+ options: [
50534
+ "[service] api|orchestrator|worker|gateway|agent-runtime|auth|postgres|mailpit|sso",
50535
+ "--follow Follow logs in real time",
50536
+ "--tail <n> Show last n lines (default: 50)",
50537
+ "--since <duration> Show logs since duration (for example: 5m, 1h)"
50538
+ ],
50539
+ examples: [
50540
+ "eve local logs",
50541
+ "eve local logs api --follow",
50542
+ "eve local logs worker --tail 200"
50543
+ ]
50544
+ },
50545
+ health: {
50546
+ description: "Quick health check (exit code 0 when healthy)",
50547
+ usage: "eve local health [--json]",
50548
+ examples: [
50549
+ "eve local health",
50550
+ "eve local health --json"
50551
+ ]
50552
+ }
50553
+ },
50554
+ examples: [
50555
+ "eve local up",
50556
+ "eve local status --json",
50557
+ "eve local down --destroy --force"
50558
+ ]
50559
+ },
50471
50560
  system: {
50472
50561
  description: "System administration and health checks (admin scope required for most commands).",
50473
50562
  usage: "eve system <subcommand> [options]",
@@ -51205,6 +51294,7 @@ function showMainHelp() {
51205
51294
  console.log(" org Manage organizations");
51206
51295
  console.log(" project Manage projects");
51207
51296
  console.log(" manifest Validate manifests (schema, secrets)");
51297
+ console.log(" local Manage local k3d stack lifecycle and diagnostics");
51208
51298
  console.log(" job Manage jobs (create, list, show, update, claim, etc.)");
51209
51299
  console.log(" env Manage environments (list, show, deploy)");
51210
51300
  console.log(" build Manage builds (create, run, logs, artifacts)");
@@ -63767,7 +63857,7 @@ async function handleWatch(positionals, flags, context2) {
63767
63857
  let jobCompleted = false;
63768
63858
  const statusPollingPromise = (async () => {
63769
63859
  while (!jobCompleted && !streamEnded) {
63770
- await new Promise((resolve7) => setTimeout(resolve7, 3e3));
63860
+ await new Promise((resolve8) => setTimeout(resolve8, 3e3));
63771
63861
  if (jobCompleted || streamEnded) break;
63772
63862
  const elapsed = Math.round((Date.now() - startTime) / 1e3);
63773
63863
  if (elapsed >= maxTimeout) {
@@ -64242,15 +64332,15 @@ async function handleRunnerLogs(positionals, flags, context2) {
64242
64332
  const kubectl = (0, import_child_process.spawn)("kubectl", kubectlArgs, {
64243
64333
  stdio: "inherit"
64244
64334
  });
64245
- return new Promise((resolve7, reject) => {
64335
+ return new Promise((resolve8, reject) => {
64246
64336
  kubectl.on("error", (error) => {
64247
64337
  reject(new Error(`Failed to execute kubectl: ${error.message}`));
64248
64338
  });
64249
64339
  kubectl.on("exit", (code) => {
64250
64340
  if (code === 0) {
64251
- resolve7();
64341
+ resolve8();
64252
64342
  } else {
64253
- resolve7();
64343
+ resolve8();
64254
64344
  }
64255
64345
  });
64256
64346
  });
@@ -65309,7 +65399,7 @@ Poll with: eve auth request-access --status ${requestData.id}`);
65309
65399
  const POLL_INTERVAL_MS = 5e3;
65310
65400
  let current = requestData;
65311
65401
  while (current.status === "pending") {
65312
- await new Promise((resolve7) => setTimeout(resolve7, POLL_INTERVAL_MS));
65402
+ await new Promise((resolve8) => setTimeout(resolve8, POLL_INTERVAL_MS));
65313
65403
  const pollResponse = await requestRaw(context2, `/auth/request-access/${current.id}`, {
65314
65404
  allowError: true,
65315
65405
  tokenOverride: ""
@@ -65547,8 +65637,8 @@ async function offerGitHubKeyRegistration(context2, email) {
65547
65637
  }
65548
65638
  console.log(`
65549
65639
  Found ${keys.length} SSH key(s) for github.com/${username.trim()}`);
65550
- const confirm = await rl.question("Register them? [Y/n]: ");
65551
- if (confirm.toLowerCase() === "n" || confirm.toLowerCase() === "no") {
65640
+ const confirm2 = await rl.question("Register them? [Y/n]: ");
65641
+ if (confirm2.toLowerCase() === "n" || confirm2.toLowerCase() === "no") {
65552
65642
  return false;
65553
65643
  }
65554
65644
  let registered = 0;
@@ -67628,7 +67718,7 @@ async function watchPipelineRun(context2, projectId, pipelineName, runId, timeou
67628
67718
  }
67629
67719
  return detail.run.status;
67630
67720
  }
67631
- await new Promise((resolve7) => setTimeout(resolve7, pollIntervalMs));
67721
+ await new Promise((resolve8) => setTimeout(resolve8, pollIntervalMs));
67632
67722
  }
67633
67723
  console.log(` Pipeline run did not complete within ${timeoutSeconds}s.`);
67634
67724
  console.log(` Run "eve pipeline show-run ${pipelineName} ${runId}" to check status.`);
@@ -67651,7 +67741,7 @@ async function watchDeploymentStatus(context2, projectId, envName, timeoutSecond
67651
67741
  console.log(" Deployment is ready.");
67652
67742
  return;
67653
67743
  }
67654
- await new Promise((resolve7) => setTimeout(resolve7, pollIntervalMs));
67744
+ await new Promise((resolve8) => setTimeout(resolve8, pollIntervalMs));
67655
67745
  }
67656
67746
  console.log(` Timeout after ${timeoutSeconds}s. Run "eve env diagnose ${projectId} ${envName}" for details.`);
67657
67747
  }
@@ -67747,41 +67837,41 @@ function formatPipelineRunList(runs) {
67747
67837
  console.log("");
67748
67838
  console.log("Run ID".padEnd(30) + "Pipeline".padEnd(20) + "Status".padEnd(20) + "Created");
67749
67839
  console.log("-".repeat(100));
67750
- for (const run of runs) {
67751
- const runId = run.id.padEnd(30);
67752
- const pipeline = run.pipeline_name.padEnd(20);
67753
- const status = run.status.padEnd(20);
67754
- const created = new Date(run.created_at).toLocaleString();
67840
+ for (const run2 of runs) {
67841
+ const runId = run2.id.padEnd(30);
67842
+ const pipeline = run2.pipeline_name.padEnd(20);
67843
+ const status = run2.status.padEnd(20);
67844
+ const created = new Date(run2.created_at).toLocaleString();
67755
67845
  console.log(`${runId}${pipeline}${status}${created}`);
67756
67846
  }
67757
67847
  console.log("");
67758
67848
  console.log(`Total: ${runs.length} runs`);
67759
67849
  }
67760
67850
  function formatPipelineRunDetail(detail) {
67761
- const { run, steps } = detail;
67762
- console.log(`Run ID: ${run.id}`);
67763
- console.log(`Pipeline: ${run.pipeline_name}`);
67764
- console.log(`Status: ${run.status}`);
67765
- if (run.env_name) {
67766
- console.log(`Environment: ${run.env_name}`);
67767
- }
67768
- if (run.git_sha) {
67769
- console.log(`Git SHA: ${run.git_sha}`);
67770
- }
67771
- if ("step_outputs" in run && run.step_outputs) {
67772
- const deployOutput = run.step_outputs.deploy;
67851
+ const { run: run2, steps } = detail;
67852
+ console.log(`Run ID: ${run2.id}`);
67853
+ console.log(`Pipeline: ${run2.pipeline_name}`);
67854
+ console.log(`Status: ${run2.status}`);
67855
+ if (run2.env_name) {
67856
+ console.log(`Environment: ${run2.env_name}`);
67857
+ }
67858
+ if (run2.git_sha) {
67859
+ console.log(`Git SHA: ${run2.git_sha}`);
67860
+ }
67861
+ if ("step_outputs" in run2 && run2.step_outputs) {
67862
+ const deployOutput = run2.step_outputs.deploy;
67773
67863
  if (deployOutput?.preview_url) {
67774
67864
  console.log(`Preview: ${deployOutput.preview_url}`);
67775
67865
  }
67776
67866
  }
67777
- if (run.started_at) {
67778
- console.log(`Started: ${run.started_at}`);
67867
+ if (run2.started_at) {
67868
+ console.log(`Started: ${run2.started_at}`);
67779
67869
  }
67780
- if (run.completed_at) {
67781
- console.log(`Completed: ${run.completed_at}`);
67870
+ if (run2.completed_at) {
67871
+ console.log(`Completed: ${run2.completed_at}`);
67782
67872
  }
67783
- if (run.error_message) {
67784
- console.log(`Error: ${run.error_message}`);
67873
+ if (run2.error_message) {
67874
+ console.log(`Error: ${run2.error_message}`);
67785
67875
  }
67786
67876
  console.log("");
67787
67877
  console.log("Steps:");
@@ -69108,9 +69198,9 @@ var originError = /* @__PURE__ */ Symbol("OriginError");
69108
69198
  var CLOSE = {};
69109
69199
  var Query = class extends Promise {
69110
69200
  constructor(strings, args, handler, canceller, options = {}) {
69111
- let resolve7, reject;
69201
+ let resolve8, reject;
69112
69202
  super((a, b2) => {
69113
- resolve7 = a;
69203
+ resolve8 = a;
69114
69204
  reject = b2;
69115
69205
  });
69116
69206
  this.tagged = Array.isArray(strings.raw);
@@ -69121,7 +69211,7 @@ var Query = class extends Promise {
69121
69211
  this.options = options;
69122
69212
  this.state = null;
69123
69213
  this.statement = null;
69124
- this.resolve = (x) => (this.active = false, resolve7(x));
69214
+ this.resolve = (x) => (this.active = false, resolve8(x));
69125
69215
  this.reject = (x) => (this.active = false, reject(x));
69126
69216
  this.active = false;
69127
69217
  this.cancelled = null;
@@ -69169,12 +69259,12 @@ var Query = class extends Promise {
69169
69259
  if (this.executed && !this.active)
69170
69260
  return { done: true };
69171
69261
  prev && prev();
69172
- const promise = new Promise((resolve7, reject) => {
69262
+ const promise = new Promise((resolve8, reject) => {
69173
69263
  this.cursorFn = (value) => {
69174
- resolve7({ value, done: false });
69264
+ resolve8({ value, done: false });
69175
69265
  return new Promise((r) => prev = r);
69176
69266
  };
69177
- this.resolve = () => (this.active = false, resolve7({ done: true }));
69267
+ this.resolve = () => (this.active = false, resolve8({ done: true }));
69178
69268
  this.reject = (x) => (this.active = false, reject(x));
69179
69269
  });
69180
69270
  this.execute();
@@ -69801,12 +69891,12 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
69801
69891
  x.on("drain", drain);
69802
69892
  return x;
69803
69893
  }
69804
- async function cancel({ pid, secret }, resolve7, reject) {
69894
+ async function cancel({ pid, secret }, resolve8, reject) {
69805
69895
  try {
69806
69896
  cancelMessage = bytes_default().i32(16).i32(80877102).i32(pid).i32(secret).end(16);
69807
69897
  await connect();
69808
69898
  socket.once("error", reject);
69809
- socket.once("close", resolve7);
69899
+ socket.once("close", resolve8);
69810
69900
  } catch (error2) {
69811
69901
  reject(error2);
69812
69902
  }
@@ -70753,7 +70843,7 @@ function parseEvent(x) {
70753
70843
  // ../../node_modules/.pnpm/postgres@3.4.8/node_modules/postgres/src/large.js
70754
70844
  var import_stream2 = __toESM(require("stream"), 1);
70755
70845
  function largeObject(sql, oid, mode = 131072 | 262144) {
70756
- return new Promise(async (resolve7, reject) => {
70846
+ return new Promise(async (resolve8, reject) => {
70757
70847
  await sql.begin(async (sql2) => {
70758
70848
  let finish;
70759
70849
  !oid && ([{ oid }] = await sql2`select lo_creat(-1) as oid`);
@@ -70779,7 +70869,7 @@ function largeObject(sql, oid, mode = 131072 | 262144) {
70779
70869
  ) seek
70780
70870
  `
70781
70871
  };
70782
- resolve7(lo);
70872
+ resolve8(lo);
70783
70873
  return new Promise(async (r) => finish = r);
70784
70874
  async function readable({
70785
70875
  highWaterMark = 2048 * 8,
@@ -70953,8 +71043,8 @@ function Postgres(a, b2) {
70953
71043
  }
70954
71044
  async function reserve() {
70955
71045
  const queue = queue_default();
70956
- const c = open.length ? open.shift() : await new Promise((resolve7, reject) => {
70957
- const query = { reserve: resolve7, reject };
71046
+ const c = open.length ? open.shift() : await new Promise((resolve8, reject) => {
71047
+ const query = { reserve: resolve8, reject };
70958
71048
  queries.push(query);
70959
71049
  closed.length && connect(closed.shift(), query);
70960
71050
  });
@@ -70991,9 +71081,9 @@ function Postgres(a, b2) {
70991
71081
  let uncaughtError, result;
70992
71082
  name && await sql2`savepoint ${sql2(name)}`;
70993
71083
  try {
70994
- result = await new Promise((resolve7, reject) => {
71084
+ result = await new Promise((resolve8, reject) => {
70995
71085
  const x = fn2(sql2);
70996
- Promise.resolve(Array.isArray(x) ? Promise.all(x) : x).then(resolve7, reject);
71086
+ Promise.resolve(Array.isArray(x) ? Promise.all(x) : x).then(resolve8, reject);
70997
71087
  });
70998
71088
  if (uncaughtError)
70999
71089
  throw uncaughtError;
@@ -71050,8 +71140,8 @@ function Postgres(a, b2) {
71050
71140
  return c.execute(query) ? move(c, busy) : move(c, full);
71051
71141
  }
71052
71142
  function cancel(query) {
71053
- return new Promise((resolve7, reject) => {
71054
- query.state ? query.active ? connection_default(options).cancel(query.state, resolve7, reject) : query.cancelled = { resolve: resolve7, reject } : (queries.remove(query), query.cancelled = true, query.reject(Errors.generic("57014", "canceling statement due to user request")), resolve7());
71143
+ return new Promise((resolve8, reject) => {
71144
+ query.state ? query.active ? connection_default(options).cancel(query.state, resolve8, reject) : query.cancelled = { resolve: resolve8, reject } : (queries.remove(query), query.cancelled = true, query.reject(Errors.generic("57014", "canceling statement due to user request")), resolve8());
71055
71145
  });
71056
71146
  }
71057
71147
  async function end({ timeout = null } = {}) {
@@ -71070,11 +71160,11 @@ function Postgres(a, b2) {
71070
71160
  async function close() {
71071
71161
  await Promise.all(connections.map((c) => c.end()));
71072
71162
  }
71073
- async function destroy(resolve7) {
71163
+ async function destroy(resolve8) {
71074
71164
  await Promise.all(connections.map((c) => c.terminate()));
71075
71165
  while (queries.length)
71076
71166
  queries.shift().reject(Errors.connection("CONNECTION_DESTROYED", options));
71077
- resolve7();
71167
+ resolve8();
71078
71168
  }
71079
71169
  function connect(c, query) {
71080
71170
  move(c, connecting);
@@ -74147,20 +74237,20 @@ async function handleRun3(positionals, flags, context2, json) {
74147
74237
  if (!buildId) {
74148
74238
  throw new Error("Usage: eve build run <build_id>");
74149
74239
  }
74150
- const run = await requestJson(
74240
+ const run2 = await requestJson(
74151
74241
  context2,
74152
74242
  `/builds/${buildId}/runs`,
74153
74243
  { method: "POST" }
74154
74244
  );
74155
74245
  if (json) {
74156
- outputJson(run, json);
74246
+ outputJson(run2, json);
74157
74247
  return;
74158
74248
  }
74159
- console.log(`Build run started: ${run.id}`);
74160
- console.log(` Build: ${run.build_id}`);
74161
- console.log(` Status: ${run.status}`);
74162
- if (run.backend) {
74163
- console.log(` Backend: ${run.backend}`);
74249
+ console.log(`Build run started: ${run2.id}`);
74250
+ console.log(` Build: ${run2.build_id}`);
74251
+ console.log(` Status: ${run2.status}`);
74252
+ if (run2.backend) {
74253
+ console.log(` Backend: ${run2.backend}`);
74164
74254
  }
74165
74255
  }
74166
74256
  async function handleRuns2(positionals, flags, context2, json) {
@@ -74373,17 +74463,17 @@ function formatBuildDetail(build) {
74373
74463
  function formatRunList(runs) {
74374
74464
  console.log("Run ID".padEnd(30) + "Status".padEnd(15) + "Backend".padEnd(15) + "Started");
74375
74465
  console.log("-".repeat(80));
74376
- for (const run of runs) {
74377
- const id = run.id.padEnd(30);
74378
- const status = run.status.padEnd(15);
74379
- const backend = (run.backend ?? "-").padEnd(15);
74380
- const started = run.started_at ? new Date(run.started_at).toLocaleString() : "-";
74466
+ for (const run2 of runs) {
74467
+ const id = run2.id.padEnd(30);
74468
+ const status = run2.status.padEnd(15);
74469
+ const backend = (run2.backend ?? "-").padEnd(15);
74470
+ const started = run2.started_at ? new Date(run2.started_at).toLocaleString() : "-";
74381
74471
  console.log(`${id}${status}${backend}${started}`);
74382
- if (run.error_message) {
74383
- console.log(` Error: ${run.error_message}`);
74472
+ if (run2.error_message) {
74473
+ console.log(` Error: ${run2.error_message}`);
74384
74474
  }
74385
- if (run.error_code) {
74386
- const info = getErrorCodeInfo2(run.error_code);
74475
+ if (run2.error_code) {
74476
+ const info = getErrorCodeInfo2(run2.error_code);
74387
74477
  console.log(` Error Type: ${info.label}`);
74388
74478
  console.log(` Hint: ${info.hint}`);
74389
74479
  }
@@ -74779,7 +74869,7 @@ async function handleThread(subcommand, positionals, flags, context2) {
74779
74869
  const message = err instanceof Error ? err.message : String(err);
74780
74870
  console.error(`Poll error: ${message}`);
74781
74871
  }
74782
- await new Promise((resolve7) => setTimeout(resolve7, pollInterval));
74872
+ await new Promise((resolve8) => setTimeout(resolve8, pollInterval));
74783
74873
  }
74784
74874
  }
74785
74875
  case "distill": {
@@ -78445,6 +78535,1079 @@ async function handleFs(subcommand, positionals, flags, context2) {
78445
78535
  }
78446
78536
  }
78447
78537
 
78538
+ // src/commands/local.ts
78539
+ var import_node_fs19 = require("node:fs");
78540
+ var import_node_crypto = require("node:crypto");
78541
+ var import_node_child_process10 = require("node:child_process");
78542
+ var import_node_os6 = require("node:os");
78543
+ var import_node_path18 = require("node:path");
78544
+ var import_promises2 = require("node:readline/promises");
78545
+ var DEFAULT_CLUSTER_NAME = "eve-local";
78546
+ var DEFAULT_KUBE_CONTEXT = "k3d-eve-local";
78547
+ var MANAGED_BIN_DIR = (0, import_node_path18.join)((0, import_node_os6.homedir)(), ".eve", "bin");
78548
+ var LOCAL_API_URL = "http://api.eve.lvh.me";
78549
+ var WATCH_INTERVAL_MS = 5e3;
78550
+ var K3D_VERSION = "v5.7.5";
78551
+ var KUBECTL_STABLE_URL = "https://dl.k8s.io/release/stable.txt";
78552
+ var LOCAL_STACK_ROOT = (0, import_node_path18.resolve)(__dirname, "..", "assets", "local-k8s");
78553
+ var LOCAL_STACK_OVERLAY = (0, import_node_path18.join)(LOCAL_STACK_ROOT, "overlays", "local");
78554
+ var LOCAL_STACK_BASE = (0, import_node_path18.join)(LOCAL_STACK_ROOT, "base");
78555
+ var SERVICE_DEFINITIONS = [
78556
+ { id: "api", workload: "eve-api", kind: "deployment" },
78557
+ { id: "orchestrator", workload: "eve-orchestrator", kind: "deployment" },
78558
+ { id: "worker", workload: "eve-worker", kind: "deployment" },
78559
+ { id: "gateway", workload: "eve-gateway", kind: "deployment" },
78560
+ { id: "agent-runtime", workload: "eve-agent-runtime", kind: "statefulset" },
78561
+ { id: "auth", workload: "supabase-auth", kind: "deployment" },
78562
+ { id: "mailpit", workload: "mailpit", kind: "deployment" },
78563
+ { id: "sso", workload: "eve-sso", kind: "deployment" }
78564
+ ];
78565
+ var PLATFORM_IMAGES = [
78566
+ { component: "api", remote: "ghcr.io/eve-horizon/api", local: "eve-horizon/api:local" },
78567
+ { component: "orchestrator", remote: "ghcr.io/eve-horizon/orchestrator", local: "eve-horizon/orchestrator:local" },
78568
+ { component: "worker", remote: "ghcr.io/eve-horizon/worker", local: "eve-horizon/worker:local" },
78569
+ { component: "gateway", remote: "ghcr.io/eve-horizon/gateway", local: "eve-horizon/gateway:local" },
78570
+ { component: "agent-runtime", remote: "ghcr.io/eve-horizon/agent-runtime", local: "eve-horizon/agent-runtime:local" },
78571
+ { component: "sso", remote: "ghcr.io/eve-horizon/sso", local: "eve-horizon/sso:local" }
78572
+ ];
78573
+ var LOG_TARGETS = {
78574
+ api: { resource: "eve-api", kind: "deployment" },
78575
+ orchestrator: { resource: "eve-orchestrator", kind: "deployment" },
78576
+ worker: { resource: "eve-worker", kind: "deployment" },
78577
+ gateway: { resource: "eve-gateway", kind: "deployment" },
78578
+ "agent-runtime": { resource: "eve-agent-runtime", kind: "statefulset" },
78579
+ auth: { resource: "supabase-auth", kind: "deployment" },
78580
+ postgres: { resource: "postgres", kind: "statefulset" },
78581
+ mailpit: { resource: "mailpit", kind: "deployment" },
78582
+ sso: { resource: "eve-sso", kind: "deployment" }
78583
+ };
78584
+ async function handleLocal(subcommand, positionals, flags, _context) {
78585
+ const json = Boolean(flags.json);
78586
+ switch (subcommand) {
78587
+ case "up":
78588
+ await handleUp(flags, json);
78589
+ return;
78590
+ case "down":
78591
+ await handleDown(flags, json);
78592
+ return;
78593
+ case "status":
78594
+ await handleStatus4(flags, json);
78595
+ return;
78596
+ case "reset":
78597
+ await handleReset3(flags, json);
78598
+ return;
78599
+ case "logs":
78600
+ handleLogs7(positionals, flags);
78601
+ return;
78602
+ case "health":
78603
+ await handleHealth2(flags, json);
78604
+ return;
78605
+ default:
78606
+ throw new Error("Usage: eve local <up|down|status|reset|logs|health> [options]");
78607
+ }
78608
+ }
78609
+ async function handleUp(flags, json) {
78610
+ const skipDeploy = getBooleanFlag(flags, ["skip-deploy"]) ?? false;
78611
+ const skipHealth = getBooleanFlag(flags, ["skip-health"]) ?? false;
78612
+ const verbose = getBooleanFlag(flags, ["verbose"]) ?? false;
78613
+ const timeoutSeconds = parseTimeoutSeconds(flags, 300);
78614
+ const requestedVersion = getStringFlag(flags, ["version"]) ?? "latest";
78615
+ const runtimeOptions = {
78616
+ quiet: json,
78617
+ verbose
78618
+ };
78619
+ ensureTool("docker", "Install Docker Desktop.");
78620
+ assertDockerRunning();
78621
+ await ensureManagedTool("k3d", runtimeOptions);
78622
+ await ensureManagedTool("kubectl", runtimeOptions);
78623
+ assertLocalAssetsPresent();
78624
+ await ensureClusterReady(runtimeOptions);
78625
+ let deployedVersion = null;
78626
+ if (!skipDeploy) {
78627
+ deployedVersion = await resolveRequestedVersion(requestedVersion, runtimeOptions);
78628
+ await importPlatformImages(deployedVersion, runtimeOptions);
78629
+ applyLocalManifests(runtimeOptions);
78630
+ waitForStatefulSetRollout("postgres", Math.max(timeoutSeconds, 180), runtimeOptions);
78631
+ runDbMigration(Math.max(timeoutSeconds, 180), runtimeOptions);
78632
+ generateAuthSecrets(runtimeOptions);
78633
+ runAuthBootstrap(Math.max(timeoutSeconds, 120), runtimeOptions);
78634
+ restartAndWaitRollouts(Math.max(timeoutSeconds, 180), runtimeOptions);
78635
+ }
78636
+ let api = await probeApiHealth(LOCAL_API_URL);
78637
+ if (!skipHealth) {
78638
+ api = await waitForApiHealth(LOCAL_API_URL, timeoutSeconds);
78639
+ }
78640
+ const result = {
78641
+ cluster: DEFAULT_CLUSTER_NAME,
78642
+ context: DEFAULT_KUBE_CONTEXT,
78643
+ version: deployedVersion,
78644
+ skip_deploy: skipDeploy,
78645
+ skip_health: skipHealth,
78646
+ api,
78647
+ urls: {
78648
+ api: LOCAL_API_URL,
78649
+ auth: "http://auth.eve.lvh.me",
78650
+ mail: "http://mail.eve.lvh.me",
78651
+ sso: "http://sso.eve.lvh.me"
78652
+ }
78653
+ };
78654
+ if (json) {
78655
+ outputJson(result, true);
78656
+ return;
78657
+ }
78658
+ console.log("");
78659
+ console.log("Local Eve stack is ready:");
78660
+ console.log(` API: ${result.urls.api}`);
78661
+ console.log(` Auth: ${result.urls.auth}`);
78662
+ console.log(` Mail: ${result.urls.mail}`);
78663
+ console.log(` SSO: ${result.urls.sso}`);
78664
+ console.log("");
78665
+ console.log("Next steps:");
78666
+ console.log(` export EVE_API_URL=${LOCAL_API_URL}`);
78667
+ console.log(' eve org ensure "my-org" --slug my-org');
78668
+ }
78669
+ async function handleDown(flags, json) {
78670
+ const destroy = getBooleanFlag(flags, ["destroy"]) ?? false;
78671
+ const force = getBooleanFlag(flags, ["force"]) ?? false;
78672
+ if (destroy && !force) {
78673
+ const confirmed = await confirm("Destroy local cluster and all persisted data? [y/N] ");
78674
+ if (!confirmed) {
78675
+ throw new Error("Aborted.");
78676
+ }
78677
+ }
78678
+ const k3d = findExecutable("k3d");
78679
+ if (!k3d) {
78680
+ outputJson(
78681
+ { stopped: false, reason: "k3d_missing", cluster: DEFAULT_CLUSTER_NAME },
78682
+ json,
78683
+ "k3d is not installed. Run 'eve local up' first."
78684
+ );
78685
+ return;
78686
+ }
78687
+ if (destroy) {
78688
+ const cluster2 = getClusterSnapshot();
78689
+ if (!cluster2.exists) {
78690
+ outputJson({ destroyed: false, reason: "cluster_not_found", cluster: DEFAULT_CLUSTER_NAME }, json, "Cluster not found. Nothing to destroy.");
78691
+ return;
78692
+ }
78693
+ run(k3d, ["cluster", "delete", DEFAULT_CLUSTER_NAME]);
78694
+ outputJson({ destroyed: true, cluster: DEFAULT_CLUSTER_NAME }, json, `Destroyed cluster '${DEFAULT_CLUSTER_NAME}'.`);
78695
+ return;
78696
+ }
78697
+ const cluster = getClusterSnapshot();
78698
+ if (!cluster.exists) {
78699
+ outputJson({ stopped: false, reason: "cluster_not_found", cluster: DEFAULT_CLUSTER_NAME }, json, "Cluster not found. Nothing to stop.");
78700
+ return;
78701
+ }
78702
+ if (!cluster.running) {
78703
+ outputJson({ stopped: true, already_stopped: true, cluster: DEFAULT_CLUSTER_NAME }, json, `Cluster '${DEFAULT_CLUSTER_NAME}' is already stopped.`);
78704
+ return;
78705
+ }
78706
+ run(k3d, ["cluster", "stop", DEFAULT_CLUSTER_NAME]);
78707
+ outputJson(
78708
+ { stopped: true, cluster: DEFAULT_CLUSTER_NAME, context: DEFAULT_KUBE_CONTEXT },
78709
+ json,
78710
+ `Stopped cluster '${DEFAULT_CLUSTER_NAME}' (state preserved).`
78711
+ );
78712
+ }
78713
+ async function handleReset3(flags, json) {
78714
+ const force = getBooleanFlag(flags, ["force"]) ?? false;
78715
+ if (!force) {
78716
+ const confirmed = await confirm("Reset local stack (destroy + recreate)? [y/N] ");
78717
+ if (!confirmed) {
78718
+ throw new Error("Aborted.");
78719
+ }
78720
+ }
78721
+ await handleDown({ ...flags, destroy: true, force: true }, false);
78722
+ await handleUp({ ...flags, "skip-deploy": false }, false);
78723
+ if (json) {
78724
+ outputJson({ reset: true, cluster: DEFAULT_CLUSTER_NAME }, true);
78725
+ }
78726
+ }
78727
+ async function handleStatus4(flags, json) {
78728
+ const watch = getBooleanFlag(flags, ["watch"]) ?? false;
78729
+ do {
78730
+ const report = await collectStatus();
78731
+ if (json) {
78732
+ outputJson(report, true);
78733
+ } else {
78734
+ if (watch) {
78735
+ process.stdout.write("\x1Bc");
78736
+ }
78737
+ renderStatus(report);
78738
+ }
78739
+ if (!watch) return;
78740
+ await sleep(WATCH_INTERVAL_MS);
78741
+ } while (true);
78742
+ }
78743
+ async function handleHealth2(_flags, json) {
78744
+ const report = await collectStatus();
78745
+ const unhealthyServices = report.services.filter((service) => !service.healthy);
78746
+ const healthy = report.cluster.running && report.api.ok && unhealthyServices.length === 0;
78747
+ const payload = {
78748
+ healthy,
78749
+ cluster: report.cluster,
78750
+ api: report.api,
78751
+ unhealthy_services: unhealthyServices.map((service) => service.id)
78752
+ };
78753
+ if (json) {
78754
+ outputJson(payload, true);
78755
+ } else {
78756
+ const icon = healthy ? "OK" : "FAIL";
78757
+ console.log(`${icon} Local stack health: ${healthy ? "healthy" : "unhealthy"}`);
78758
+ console.log(` Cluster: ${report.cluster.exists ? report.cluster.running ? "running" : "stopped" : "missing"}`);
78759
+ console.log(` API: ${report.api.ok ? `ok (${report.api.status ?? "ok"})` : `unreachable (${report.api.error ?? "unknown"})`}`);
78760
+ if (unhealthyServices.length > 0) {
78761
+ console.log(` Services: unhealthy -> ${unhealthyServices.map((service) => service.id).join(", ")}`);
78762
+ }
78763
+ }
78764
+ if (!healthy) {
78765
+ process.exitCode = 1;
78766
+ }
78767
+ }
78768
+ function handleLogs7(positionals, flags) {
78769
+ const kubectl = findExecutable("kubectl");
78770
+ if (!kubectl) {
78771
+ throw new Error("kubectl is not installed. Run 'eve local up' first.");
78772
+ }
78773
+ const cluster = getClusterSnapshot();
78774
+ if (!cluster.running) {
78775
+ throw new Error(`Cluster '${DEFAULT_CLUSTER_NAME}' is not running. Start it with: eve local up`);
78776
+ }
78777
+ const service = positionals[0];
78778
+ const follow = getBooleanFlag(flags, ["follow", "f"]) ?? false;
78779
+ const tail = getStringFlag(flags, ["tail"]) ?? "50";
78780
+ const since = getStringFlag(flags, ["since"]);
78781
+ const args = ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "logs"];
78782
+ if (service) {
78783
+ const target = LOG_TARGETS[service];
78784
+ if (!target) {
78785
+ const names = Object.keys(LOG_TARGETS).join(", ");
78786
+ throw new Error(`Unknown service '${service}'. Supported services: ${names}`);
78787
+ }
78788
+ args.push(`${target.kind}/${target.resource}`);
78789
+ } else {
78790
+ args.push("-l", "app.kubernetes.io/name in (eve-api,eve-orchestrator,eve-worker,eve-gateway,eve-agent-runtime,supabase-auth,eve-sso,mailpit,postgres)");
78791
+ args.push("--all-containers=true");
78792
+ }
78793
+ args.push("--tail", tail);
78794
+ if (since) {
78795
+ args.push("--since", since);
78796
+ }
78797
+ if (follow) {
78798
+ args.push("-f");
78799
+ }
78800
+ run(kubectl, args, { stdio: "inherit" });
78801
+ }
78802
+ async function collectStatus() {
78803
+ const cluster = getClusterSnapshot();
78804
+ const services = getServiceStatuses(cluster.running);
78805
+ const api = await probeApiHealth(LOCAL_API_URL);
78806
+ return {
78807
+ cluster: {
78808
+ name: DEFAULT_CLUSTER_NAME,
78809
+ context: DEFAULT_KUBE_CONTEXT,
78810
+ exists: cluster.exists,
78811
+ running: cluster.running
78812
+ },
78813
+ services,
78814
+ api,
78815
+ urls: {
78816
+ api: LOCAL_API_URL,
78817
+ auth: "http://auth.eve.lvh.me",
78818
+ mail: "http://mail.eve.lvh.me",
78819
+ sso: "http://sso.eve.lvh.me"
78820
+ }
78821
+ };
78822
+ }
78823
+ function renderStatus(report) {
78824
+ const healthyServices = report.services.filter((service) => service.healthy).length;
78825
+ const totalServices = report.services.length;
78826
+ const clusterStatus = report.cluster.exists ? report.cluster.running ? "running" : "stopped" : "missing";
78827
+ console.log("Local Eve Environment");
78828
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
78829
+ console.log(`Cluster: ${report.cluster.name} (${clusterStatus})`);
78830
+ console.log(`Context: ${report.cluster.context}`);
78831
+ console.log(`API Health: ${report.api.ok ? `ok (${report.api.status ?? "ok"})` : `unreachable (${report.api.error ?? "unknown"})`}`);
78832
+ console.log("");
78833
+ console.log(`Services (${healthyServices}/${totalServices} healthy):`);
78834
+ for (const service of report.services) {
78835
+ const icon = service.healthy ? "OK" : "FAIL";
78836
+ const ready2 = `${service.ready}/${service.desired}`;
78837
+ const name = service.id.padEnd(13);
78838
+ const workload = `${service.kind}/${service.workload}`;
78839
+ console.log(` ${icon} ${name} ${ready2.padEnd(5)} ${workload}`);
78840
+ }
78841
+ console.log("");
78842
+ console.log("URLs:");
78843
+ console.log(` API: ${report.urls.api}`);
78844
+ console.log(` Auth: ${report.urls.auth}`);
78845
+ console.log(` Mail: ${report.urls.mail}`);
78846
+ console.log(` SSO: ${report.urls.sso}`);
78847
+ }
78848
+ function getServiceStatuses(clusterRunning) {
78849
+ if (!clusterRunning) {
78850
+ return SERVICE_DEFINITIONS.map((service) => ({
78851
+ id: service.id,
78852
+ workload: service.workload,
78853
+ kind: service.kind,
78854
+ exists: false,
78855
+ desired: 0,
78856
+ ready: 0,
78857
+ healthy: false
78858
+ }));
78859
+ }
78860
+ const kubectl = findExecutable("kubectl");
78861
+ if (!kubectl) {
78862
+ return SERVICE_DEFINITIONS.map((service) => ({
78863
+ id: service.id,
78864
+ workload: service.workload,
78865
+ kind: service.kind,
78866
+ exists: false,
78867
+ desired: 0,
78868
+ ready: 0,
78869
+ healthy: false
78870
+ }));
78871
+ }
78872
+ const raw = run(
78873
+ kubectl,
78874
+ ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "get", "deployments,statefulsets", "-o", "json"],
78875
+ { stdio: "pipe", allowFailure: true }
78876
+ );
78877
+ if (raw.status !== 0) {
78878
+ return SERVICE_DEFINITIONS.map((service) => ({
78879
+ id: service.id,
78880
+ workload: service.workload,
78881
+ kind: service.kind,
78882
+ exists: false,
78883
+ desired: 0,
78884
+ ready: 0,
78885
+ healthy: false
78886
+ }));
78887
+ }
78888
+ let parsed = {};
78889
+ try {
78890
+ parsed = JSON.parse(raw.stdout);
78891
+ } catch {
78892
+ return SERVICE_DEFINITIONS.map((service) => ({
78893
+ id: service.id,
78894
+ workload: service.workload,
78895
+ kind: service.kind,
78896
+ exists: false,
78897
+ desired: 0,
78898
+ ready: 0,
78899
+ healthy: false
78900
+ }));
78901
+ }
78902
+ const deployments = /* @__PURE__ */ new Map();
78903
+ const statefulsets = /* @__PURE__ */ new Map();
78904
+ for (const item of parsed.items ?? []) {
78905
+ const kind = String(item.kind ?? "").toLowerCase();
78906
+ const metadata = item.metadata ?? {};
78907
+ const name = String(metadata.name ?? "");
78908
+ if (!name) continue;
78909
+ if (kind === "deployment") {
78910
+ deployments.set(name, item);
78911
+ } else if (kind === "statefulset") {
78912
+ statefulsets.set(name, item);
78913
+ }
78914
+ }
78915
+ return SERVICE_DEFINITIONS.map((service) => {
78916
+ const source = service.kind === "deployment" ? deployments.get(service.workload) : statefulsets.get(service.workload);
78917
+ if (!source) {
78918
+ return {
78919
+ id: service.id,
78920
+ workload: service.workload,
78921
+ kind: service.kind,
78922
+ exists: false,
78923
+ desired: 0,
78924
+ ready: 0,
78925
+ healthy: false
78926
+ };
78927
+ }
78928
+ const spec = source.spec ?? {};
78929
+ const status = source.status ?? {};
78930
+ const desired = Number(spec.replicas ?? status.replicas ?? 1);
78931
+ const ready2 = Number(status.readyReplicas ?? 0);
78932
+ const healthy = desired > 0 && ready2 >= desired;
78933
+ return {
78934
+ id: service.id,
78935
+ workload: service.workload,
78936
+ kind: service.kind,
78937
+ exists: true,
78938
+ desired: Number.isFinite(desired) ? desired : 0,
78939
+ ready: Number.isFinite(ready2) ? ready2 : 0,
78940
+ healthy
78941
+ };
78942
+ });
78943
+ }
78944
+ async function ensureManagedTool(tool, runtimeOptions) {
78945
+ if (findExecutable(tool)) {
78946
+ return;
78947
+ }
78948
+ (0, import_node_fs19.mkdirSync)(MANAGED_BIN_DIR, { recursive: true });
78949
+ if (tool === "k3d") {
78950
+ printProgress(runtimeOptions, `Installing k3d ${K3D_VERSION} into ${MANAGED_BIN_DIR}...`);
78951
+ await installK3dBinary();
78952
+ } else {
78953
+ printProgress(runtimeOptions, `Installing kubectl into ${MANAGED_BIN_DIR}...`);
78954
+ await installKubectlBinary();
78955
+ }
78956
+ if (!findExecutable(tool)) {
78957
+ throw new Error(`Failed to install ${tool} into ${MANAGED_BIN_DIR}.`);
78958
+ }
78959
+ }
78960
+ async function installK3dBinary() {
78961
+ const platform2 = normalizePlatform(process.platform);
78962
+ const arch = normalizeArch(process.arch);
78963
+ const url = `https://github.com/k3d-io/k3d/releases/download/${K3D_VERSION}/k3d-${platform2}-${arch}`;
78964
+ await downloadBinary(url, (0, import_node_path18.join)(MANAGED_BIN_DIR, "k3d"));
78965
+ }
78966
+ async function installKubectlBinary() {
78967
+ const platform2 = normalizePlatform(process.platform);
78968
+ const arch = normalizeArch(process.arch);
78969
+ const stable = (await fetchText(KUBECTL_STABLE_URL)).trim();
78970
+ if (!/^v\d+\.\d+\.\d+$/.test(stable)) {
78971
+ throw new Error(`Unexpected kubectl stable release format: '${stable}'`);
78972
+ }
78973
+ const binaryUrl = `https://dl.k8s.io/release/${stable}/bin/${platform2}/${arch}/kubectl`;
78974
+ const checksumUrl = `${binaryUrl}.sha256`;
78975
+ const [binary, checksumText] = await Promise.all([
78976
+ downloadBytes(binaryUrl),
78977
+ fetchText(checksumUrl)
78978
+ ]);
78979
+ const expectedChecksum = checksumText.trim();
78980
+ const actualChecksum = (0, import_node_crypto.createHash)("sha256").update(binary).digest("hex");
78981
+ if (expectedChecksum !== actualChecksum) {
78982
+ throw new Error(`kubectl checksum verification failed (expected ${expectedChecksum}, got ${actualChecksum}).`);
78983
+ }
78984
+ writeExecutable((0, import_node_path18.join)(MANAGED_BIN_DIR, "kubectl"), binary);
78985
+ }
78986
+ function normalizePlatform(platform2) {
78987
+ if (platform2 === "darwin" || platform2 === "linux") {
78988
+ return platform2;
78989
+ }
78990
+ throw new Error(`Unsupported platform '${platform2}'. 'eve local up' currently supports macOS and Linux.`);
78991
+ }
78992
+ function normalizeArch(arch) {
78993
+ if (arch === "x64") return "amd64";
78994
+ if (arch === "arm64") return "arm64";
78995
+ throw new Error(`Unsupported CPU architecture '${arch}'.`);
78996
+ }
78997
+ async function downloadBinary(url, destination) {
78998
+ const bytes = await downloadBytes(url);
78999
+ writeExecutable(destination, bytes);
79000
+ }
79001
+ async function downloadBytes(url) {
79002
+ const response = await fetch(url, {
79003
+ headers: {
79004
+ "User-Agent": "eve-cli-local-stack",
79005
+ Accept: "*/*"
79006
+ }
79007
+ });
79008
+ if (!response.ok) {
79009
+ throw new Error(`Download failed (${response.status}) for ${url}`);
79010
+ }
79011
+ const arrayBuffer = await response.arrayBuffer();
79012
+ return Buffer.from(arrayBuffer);
79013
+ }
79014
+ async function fetchText(url, headers) {
79015
+ const response = await fetch(url, {
79016
+ headers: {
79017
+ "User-Agent": "eve-cli-local-stack",
79018
+ Accept: "application/json,text/plain,*/*",
79019
+ ...headers ?? {}
79020
+ }
79021
+ });
79022
+ if (!response.ok) {
79023
+ throw new Error(`Request failed (${response.status}) for ${url}`);
79024
+ }
79025
+ return response.text();
79026
+ }
79027
+ function writeExecutable(destination, bytes) {
79028
+ const tempPath = `${destination}.tmp-${Date.now()}-${process.pid}`;
79029
+ (0, import_node_fs19.writeFileSync)(tempPath, bytes);
79030
+ (0, import_node_fs19.chmodSync)(tempPath, 493);
79031
+ (0, import_node_fs19.renameSync)(tempPath, destination);
79032
+ }
79033
+ async function ensureClusterReady(runtimeOptions) {
79034
+ const k3d = requireToolPath("k3d", "Run 'eve local up' again to auto-install managed tools.");
79035
+ const cluster = getClusterSnapshot();
79036
+ if (!cluster.exists) {
79037
+ printProgress(runtimeOptions, `Creating cluster '${DEFAULT_CLUSTER_NAME}'...`);
79038
+ run(
79039
+ k3d,
79040
+ [
79041
+ "cluster",
79042
+ "create",
79043
+ DEFAULT_CLUSTER_NAME,
79044
+ "--api-port",
79045
+ "127.0.0.1:6443",
79046
+ "-p",
79047
+ "80:80@loadbalancer",
79048
+ "-p",
79049
+ "443:443@loadbalancer"
79050
+ ],
79051
+ { stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe" }
79052
+ );
79053
+ } else if (!cluster.running) {
79054
+ printProgress(runtimeOptions, `Starting cluster '${DEFAULT_CLUSTER_NAME}'...`);
79055
+ run(k3d, ["cluster", "start", DEFAULT_CLUSTER_NAME], {
79056
+ stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe"
79057
+ });
79058
+ } else {
79059
+ printProgress(runtimeOptions, `Cluster '${DEFAULT_CLUSTER_NAME}' is already running.`);
79060
+ }
79061
+ trySelectLocalContext();
79062
+ await ensureClusterConnectivity(runtimeOptions);
79063
+ }
79064
+ async function ensureClusterConnectivity(runtimeOptions) {
79065
+ const kubectl = requireToolPath("kubectl", "Run 'eve local up' again to auto-install managed tools.");
79066
+ const maxAttempts = 3;
79067
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
79068
+ const probe = run(kubectl, ["--context", DEFAULT_KUBE_CONTEXT, "get", "nodes"], {
79069
+ stdio: "pipe",
79070
+ allowFailure: true
79071
+ });
79072
+ if (probe.status === 0) {
79073
+ return;
79074
+ }
79075
+ const errorText = `${probe.stderr}
79076
+ ${probe.stdout}`;
79077
+ if (!errorText.includes("EOF")) {
79078
+ throw new Error(`Cannot connect to local cluster: ${probe.stderr.trim() || probe.stdout.trim()}`);
79079
+ }
79080
+ printProgress(runtimeOptions, `Cluster API returned EOF (attempt ${attempt}/${maxAttempts}); restarting load balancer...`);
79081
+ run("docker", [`restart`, `k3d-${DEFAULT_CLUSTER_NAME}-serverlb`], { allowFailure: true, stdio: "pipe" });
79082
+ await sleep(2e3);
79083
+ }
79084
+ throw new Error(`Failed to connect to cluster '${DEFAULT_CLUSTER_NAME}' after retrying load balancer restart.`);
79085
+ }
79086
+ async function resolveRequestedVersion(requestedVersion, runtimeOptions) {
79087
+ if (requestedVersion === "latest") {
79088
+ const version2 = await resolveLatestPlatformVersion();
79089
+ printProgress(runtimeOptions, `Resolved platform version: ${version2}`);
79090
+ return version2;
79091
+ }
79092
+ const normalized = normalizeVersion(requestedVersion);
79093
+ if (!normalized) {
79094
+ throw new Error(`Invalid --version value '${requestedVersion}'. Use a semantic version like '0.1.50' or 'latest'.`);
79095
+ }
79096
+ return normalized;
79097
+ }
79098
+ async function resolveLatestPlatformVersion() {
79099
+ const semverSets = await Promise.all(
79100
+ PLATFORM_IMAGES.map(async (image) => {
79101
+ const tags = await fetchRegistryTags(image.remote);
79102
+ return new Set(
79103
+ tags.map((tag) => normalizeVersion(tag)).filter((value) => Boolean(value))
79104
+ );
79105
+ })
79106
+ );
79107
+ if (semverSets.length === 0) {
79108
+ throw new Error("No platform images configured for local stack deployment.");
79109
+ }
79110
+ let intersection = new Set(semverSets[0]);
79111
+ for (const set of semverSets.slice(1)) {
79112
+ intersection = new Set(Array.from(intersection).filter((version2) => set.has(version2)));
79113
+ }
79114
+ const candidates = Array.from(intersection);
79115
+ if (candidates.length === 0) {
79116
+ throw new Error(
79117
+ "Unable to resolve a common platform version from GHCR tags. Re-run with --version <x.y.z>."
79118
+ );
79119
+ }
79120
+ candidates.sort(compareSemverDesc);
79121
+ return candidates[0];
79122
+ }
79123
+ async function fetchRegistryTags(imageRef) {
79124
+ const repository = imageRef.replace(/^ghcr\.io\//, "");
79125
+ const tokenPayload = await fetchText(`https://ghcr.io/token?scope=repository:${repository}:pull`);
79126
+ const token = JSON.parse(tokenPayload).token;
79127
+ if (!token) {
79128
+ throw new Error(`Unable to fetch GHCR token for ${imageRef}.`);
79129
+ }
79130
+ const tagsPayload = await fetchText(
79131
+ `https://ghcr.io/v2/${repository}/tags/list?n=200`,
79132
+ { Authorization: `Bearer ${token}` }
79133
+ );
79134
+ return JSON.parse(tagsPayload).tags ?? [];
79135
+ }
79136
+ function normalizeVersion(value) {
79137
+ const trimmed = value.trim();
79138
+ if (!trimmed) return null;
79139
+ let candidate = trimmed;
79140
+ if (candidate.startsWith("release-v")) {
79141
+ candidate = candidate.slice("release-v".length);
79142
+ } else if (candidate.startsWith("v")) {
79143
+ candidate = candidate.slice(1);
79144
+ }
79145
+ return /^\d+\.\d+\.\d+$/.test(candidate) ? candidate : null;
79146
+ }
79147
+ function compareSemverDesc(a, b2) {
79148
+ const pa = a.split(".").map((part) => Number.parseInt(part, 10));
79149
+ const pb = b2.split(".").map((part) => Number.parseInt(part, 10));
79150
+ for (let i = 0; i < 3; i += 1) {
79151
+ const diff = (pb[i] ?? 0) - (pa[i] ?? 0);
79152
+ if (diff !== 0) {
79153
+ return diff;
79154
+ }
79155
+ }
79156
+ return 0;
79157
+ }
79158
+ async function importPlatformImages(version2, runtimeOptions) {
79159
+ const docker = requireToolPath("docker", "Install Docker Desktop.");
79160
+ const k3d = requireToolPath("k3d", "Run 'eve local up' again to auto-install managed tools.");
79161
+ const stdio = runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe";
79162
+ for (const image of PLATFORM_IMAGES) {
79163
+ const remoteTag = `${image.remote}:${version2}`;
79164
+ printProgress(runtimeOptions, `Pulling image ${remoteTag}...`);
79165
+ const pull = pullImageWithRetry(docker, remoteTag, stdio, runtimeOptions);
79166
+ if (pull.status !== 0) {
79167
+ throw new Error(
79168
+ `Failed to pull ${remoteTag}. Ensure GHCR image visibility is public and the version exists. Try: eve local up --version <x.y.z>`
79169
+ );
79170
+ }
79171
+ run(docker, ["tag", remoteTag, image.local], { stdio });
79172
+ printProgress(runtimeOptions, `Importing image ${image.component} into k3d...`);
79173
+ importImageViaTar(docker, k3d, image.local, image.component, stdio);
79174
+ }
79175
+ }
79176
+ function importImageViaTar(docker, k3d, imageTag, component, stdio) {
79177
+ const tarPath = (0, import_node_path18.join)((0, import_node_os6.tmpdir)(), `eve-local-${component}-${Date.now()}-${process.pid}.tar`);
79178
+ try {
79179
+ run(docker, ["image", "save", "--platform", "linux/amd64", imageTag, "-o", tarPath], { stdio });
79180
+ run(k3d, ["image", "import", "--mode", "direct", tarPath, "-c", DEFAULT_CLUSTER_NAME], { stdio });
79181
+ } finally {
79182
+ if ((0, import_node_fs19.existsSync)(tarPath)) {
79183
+ (0, import_node_fs19.unlinkSync)(tarPath);
79184
+ }
79185
+ }
79186
+ }
79187
+ function pullImageWithRetry(docker, remoteTag, stdio, runtimeOptions) {
79188
+ const maxAttempts = 3;
79189
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
79190
+ const pull = run(docker, ["pull", "--platform", "linux/amd64", remoteTag], {
79191
+ stdio,
79192
+ allowFailure: true,
79193
+ timeoutMs: 7 * 60 * 1e3
79194
+ });
79195
+ if (pull.status === 0) {
79196
+ return pull;
79197
+ }
79198
+ const combined = `${pull.stderr}
79199
+ ${pull.stdout}`.toLowerCase();
79200
+ const retryable = combined.includes("unexpected eof") || combined.includes("short read") || combined.includes("i/o timeout") || combined.includes("timed out");
79201
+ if (!retryable || attempt === maxAttempts) {
79202
+ return pull;
79203
+ }
79204
+ printProgress(runtimeOptions, `Pull failed for ${remoteTag} (attempt ${attempt}/${maxAttempts}). Retrying...`);
79205
+ }
79206
+ return { status: 1, stdout: "", stderr: "pull retry exhausted" };
79207
+ }
79208
+ function applyLocalManifests(runtimeOptions) {
79209
+ const kubectl = requireToolPath("kubectl", "Run 'eve local up' again to auto-install managed tools.");
79210
+ printProgress(runtimeOptions, "Applying local Kubernetes manifests...");
79211
+ run(
79212
+ kubectl,
79213
+ ["--context", DEFAULT_KUBE_CONTEXT, "apply", "-k", LOCAL_STACK_OVERLAY],
79214
+ { stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe" }
79215
+ );
79216
+ }
79217
+ function runDbMigration(timeoutSeconds, runtimeOptions) {
79218
+ const kubectl = requireToolPath("kubectl", "Run 'eve local up' again to auto-install managed tools.");
79219
+ const migrateJobPath = (0, import_node_path18.join)(LOCAL_STACK_BASE, "db-migrate-job.yaml");
79220
+ printProgress(runtimeOptions, "Running database migrations...");
79221
+ run(kubectl, ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "delete", "job/eve-db-migrate", "--ignore-not-found"], {
79222
+ stdio: "pipe",
79223
+ allowFailure: true
79224
+ });
79225
+ run(kubectl, ["--context", DEFAULT_KUBE_CONTEXT, "apply", "-f", migrateJobPath], {
79226
+ stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe"
79227
+ });
79228
+ const wait = run(
79229
+ kubectl,
79230
+ ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "wait", "--for=condition=complete", "job/eve-db-migrate", timeoutArg(timeoutSeconds)],
79231
+ {
79232
+ stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe",
79233
+ allowFailure: true
79234
+ }
79235
+ );
79236
+ if (wait.status !== 0) {
79237
+ run(kubectl, ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "logs", "job/eve-db-migrate"], { stdio: "inherit", allowFailure: true });
79238
+ throw new Error("Database migration failed. Inspect job logs above.");
79239
+ }
79240
+ }
79241
+ function generateAuthSecrets(runtimeOptions) {
79242
+ const kubectl = requireToolPath("kubectl", "Run 'eve local up' again to auto-install managed tools.");
79243
+ printProgress(runtimeOptions, "Generating auth secrets...");
79244
+ const existingJwtSecret = readSecretValue(kubectl, "SUPABASE_JWT_SECRET");
79245
+ const existingAdminPassword = readSecretValue(kubectl, "EVE_AUTH_ADMIN_PASSWORD");
79246
+ const existingAuthPrivateKey = readSecretValue(kubectl, "EVE_AUTH_PRIVATE_KEY");
79247
+ const existingAuthPublicKey = readSecretValue(kubectl, "EVE_AUTH_PUBLIC_KEY");
79248
+ const existingInternalApiKey = readSecretValue(kubectl, "EVE_INTERNAL_API_KEY");
79249
+ const existingSecretsMasterKey = readSecretValue(kubectl, "EVE_SECRETS_MASTER_KEY");
79250
+ const existingBootstrapToken = readSecretValue(kubectl, "EVE_BOOTSTRAP_TOKEN");
79251
+ const jwtSecret = existingJwtSecret || (0, import_node_crypto.randomBytes)(32).toString("hex");
79252
+ const adminPassword = existingAdminPassword || (0, import_node_crypto.randomBytes)(24).toString("base64url").slice(0, 32);
79253
+ const dbUrl = `postgres://eve_auth_admin:${adminPassword}@postgres.eve.svc.cluster.local:5432/eve?sslmode=disable`;
79254
+ let authPrivateKey = existingAuthPrivateKey;
79255
+ let authPublicKey = existingAuthPublicKey;
79256
+ if (!authPrivateKey || !authPublicKey) {
79257
+ const keyPair = (0, import_node_crypto.generateKeyPairSync)("rsa", {
79258
+ modulusLength: 2048,
79259
+ publicKeyEncoding: { type: "spki", format: "pem" },
79260
+ privateKeyEncoding: { type: "pkcs8", format: "pem" }
79261
+ });
79262
+ authPrivateKey = keyPair.privateKey;
79263
+ authPublicKey = keyPair.publicKey;
79264
+ }
79265
+ const iat = Math.floor(Date.now() / 1e3);
79266
+ const exp = iat + 10 * 365 * 24 * 60 * 60;
79267
+ const serviceKey = generateHs256Jwt({ role: "service_role", iss: "supabase", iat, exp }, jwtSecret);
79268
+ const anonKey = generateHs256Jwt({ role: "anon", iss: "supabase", iat, exp }, jwtSecret);
79269
+ const stringData = {
79270
+ EVE_INTERNAL_API_KEY: existingInternalApiKey || (0, import_node_crypto.randomBytes)(24).toString("hex"),
79271
+ EVE_SECRETS_MASTER_KEY: existingSecretsMasterKey || (0, import_node_crypto.randomBytes)(32).toString("hex"),
79272
+ EVE_BOOTSTRAP_TOKEN: existingBootstrapToken || (0, import_node_crypto.randomBytes)(24).toString("hex"),
79273
+ SUPABASE_JWT_SECRET: jwtSecret,
79274
+ EVE_AUTH_ADMIN_PASSWORD: adminPassword,
79275
+ SUPABASE_AUTH_DATABASE_URL: dbUrl,
79276
+ SUPABASE_AUTH_SERVICE_KEY: serviceKey,
79277
+ SUPABASE_ANON_KEY: anonKey,
79278
+ EVE_AUTH_PRIVATE_KEY: authPrivateKey,
79279
+ EVE_AUTH_PUBLIC_KEY: authPublicKey
79280
+ };
79281
+ const optionalKeys = [
79282
+ "EVE_GITHUB_WEBHOOK_SECRET",
79283
+ "EVE_SLACK_SIGNING_SECRET",
79284
+ "EVE_GATEWAY_PROJECT_ID"
79285
+ ];
79286
+ for (const key of optionalKeys) {
79287
+ const value = process.env[key];
79288
+ if (typeof value === "string" && value.length > 0) {
79289
+ stringData[key] = value;
79290
+ }
79291
+ }
79292
+ const patchPayload = JSON.stringify({ stringData });
79293
+ run(
79294
+ kubectl,
79295
+ ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "patch", "secret", "eve-app", "--type", "merge", "-p", patchPayload],
79296
+ { stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe" }
79297
+ );
79298
+ }
79299
+ function readSecretValue(kubectl, key) {
79300
+ const result = run(
79301
+ kubectl,
79302
+ ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "get", "secret", "eve-app", "-o", `jsonpath={.data.${key}}`],
79303
+ { stdio: "pipe", allowFailure: true }
79304
+ );
79305
+ if (result.status !== 0) {
79306
+ return "";
79307
+ }
79308
+ const encoded = result.stdout.trim();
79309
+ if (!encoded) {
79310
+ return "";
79311
+ }
79312
+ try {
79313
+ return Buffer.from(encoded, "base64").toString("utf8");
79314
+ } catch {
79315
+ return "";
79316
+ }
79317
+ }
79318
+ function runAuthBootstrap(timeoutSeconds, runtimeOptions) {
79319
+ const kubectl = requireToolPath("kubectl", "Run 'eve local up' again to auto-install managed tools.");
79320
+ const bootstrapJobPath = (0, import_node_path18.join)(LOCAL_STACK_BASE, "auth-bootstrap-job.yaml");
79321
+ printProgress(runtimeOptions, "Bootstrapping auth database role...");
79322
+ run(kubectl, ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "delete", "job/auth-db-bootstrap", "--ignore-not-found"], {
79323
+ stdio: "pipe",
79324
+ allowFailure: true
79325
+ });
79326
+ run(kubectl, ["--context", DEFAULT_KUBE_CONTEXT, "apply", "-f", bootstrapJobPath], {
79327
+ stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe"
79328
+ });
79329
+ const wait = run(
79330
+ kubectl,
79331
+ ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "wait", "--for=condition=complete", "job/auth-db-bootstrap", timeoutArg(timeoutSeconds)],
79332
+ {
79333
+ stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe",
79334
+ allowFailure: true
79335
+ }
79336
+ );
79337
+ if (wait.status !== 0) {
79338
+ run(kubectl, ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "logs", "job/auth-db-bootstrap"], { stdio: "inherit", allowFailure: true });
79339
+ throw new Error("Auth bootstrap failed. Inspect job logs above.");
79340
+ }
79341
+ }
79342
+ function restartAndWaitRollouts(timeoutSeconds, runtimeOptions) {
79343
+ const kubectl = requireToolPath("kubectl", "Run 'eve local up' again to auto-install managed tools.");
79344
+ printProgress(runtimeOptions, "Restarting and waiting for service rollouts...");
79345
+ run(
79346
+ kubectl,
79347
+ [
79348
+ "--context",
79349
+ DEFAULT_KUBE_CONTEXT,
79350
+ "-n",
79351
+ "eve",
79352
+ "rollout",
79353
+ "restart",
79354
+ "deployment/eve-api",
79355
+ "deployment/eve-orchestrator",
79356
+ "deployment/eve-worker",
79357
+ "deployment/eve-gateway",
79358
+ "deployment/supabase-auth",
79359
+ "deployment/mailpit",
79360
+ "deployment/eve-sso"
79361
+ ],
79362
+ { stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe" }
79363
+ );
79364
+ run(
79365
+ kubectl,
79366
+ ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "rollout", "restart", "statefulset/eve-agent-runtime"],
79367
+ { stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe" }
79368
+ );
79369
+ const workloads = [
79370
+ { kind: "deployment", name: "eve-api" },
79371
+ { kind: "deployment", name: "eve-orchestrator" },
79372
+ { kind: "deployment", name: "eve-worker" },
79373
+ { kind: "deployment", name: "eve-gateway" },
79374
+ { kind: "deployment", name: "supabase-auth" },
79375
+ { kind: "deployment", name: "mailpit" },
79376
+ { kind: "deployment", name: "eve-sso" },
79377
+ { kind: "statefulset", name: "eve-agent-runtime" }
79378
+ ];
79379
+ for (const workload of workloads) {
79380
+ const status = run(
79381
+ kubectl,
79382
+ ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "rollout", "status", `${workload.kind}/${workload.name}`, timeoutArg(timeoutSeconds)],
79383
+ {
79384
+ stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe",
79385
+ allowFailure: true
79386
+ }
79387
+ );
79388
+ if (status.status !== 0) {
79389
+ throw new Error(`Rollout failed for ${workload.kind}/${workload.name}. Run 'eve local status' and inspect service logs with 'eve local logs <service>'.`);
79390
+ }
79391
+ }
79392
+ }
79393
+ function waitForStatefulSetRollout(name, timeoutSeconds, runtimeOptions) {
79394
+ const kubectl = requireToolPath("kubectl", "Run 'eve local up' again to auto-install managed tools.");
79395
+ const status = run(
79396
+ kubectl,
79397
+ ["--context", DEFAULT_KUBE_CONTEXT, "-n", "eve", "rollout", "status", `statefulset/${name}`, timeoutArg(timeoutSeconds)],
79398
+ {
79399
+ stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe",
79400
+ allowFailure: true
79401
+ }
79402
+ );
79403
+ if (status.status !== 0) {
79404
+ throw new Error(`StatefulSet '${name}' did not become ready in ${timeoutSeconds}s.`);
79405
+ }
79406
+ }
79407
+ function timeoutArg(timeoutSeconds) {
79408
+ return `--timeout=${Math.max(timeoutSeconds, 1)}s`;
79409
+ }
79410
+ function generateHs256Jwt(payload, secret) {
79411
+ const headerBase64 = Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })).toString("base64url");
79412
+ const payloadBase64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
79413
+ const signature = (0, import_node_crypto.createHmac)("sha256", secret).update(`${headerBase64}.${payloadBase64}`).digest("base64url");
79414
+ return `${headerBase64}.${payloadBase64}.${signature}`;
79415
+ }
79416
+ function assertLocalAssetsPresent() {
79417
+ const files = [
79418
+ LOCAL_STACK_OVERLAY,
79419
+ LOCAL_STACK_BASE,
79420
+ (0, import_node_path18.join)(LOCAL_STACK_OVERLAY, "kustomization.yaml"),
79421
+ (0, import_node_path18.join)(LOCAL_STACK_BASE, "db-migrate-job.yaml"),
79422
+ (0, import_node_path18.join)(LOCAL_STACK_BASE, "auth-bootstrap-job.yaml")
79423
+ ];
79424
+ for (const file of files) {
79425
+ if (!(0, import_node_fs19.existsSync)(file)) {
79426
+ throw new Error(
79427
+ `Missing local stack assets at ${file}. Reinstall the CLI or ensure package assets were published.`
79428
+ );
79429
+ }
79430
+ }
79431
+ }
79432
+ async function waitForApiHealth(url, timeoutSeconds) {
79433
+ const deadline = Date.now() + Math.max(timeoutSeconds, 1) * 1e3;
79434
+ let latest = await probeApiHealth(url);
79435
+ while (!latest.ok && Date.now() < deadline) {
79436
+ await sleep(2e3);
79437
+ latest = await probeApiHealth(url);
79438
+ }
79439
+ if (!latest.ok) {
79440
+ throw new Error(`Local API did not become healthy within ${timeoutSeconds}s (${latest.error ?? "unknown error"}).`);
79441
+ }
79442
+ return latest;
79443
+ }
79444
+ async function probeApiHealth(url) {
79445
+ const controller = new AbortController();
79446
+ const timeout = setTimeout(() => controller.abort(), 3e3);
79447
+ try {
79448
+ const response = await fetch(`${url}/health`, { signal: controller.signal });
79449
+ if (!response.ok) {
79450
+ return {
79451
+ url,
79452
+ ok: false,
79453
+ error: `HTTP ${response.status}`
79454
+ };
79455
+ }
79456
+ const payload = await response.json();
79457
+ return {
79458
+ url,
79459
+ ok: payload.status === "ok" || payload.status === "healthy",
79460
+ status: payload.status,
79461
+ timestamp: payload.timestamp
79462
+ };
79463
+ } catch (error) {
79464
+ const message = error instanceof Error ? error.message : String(error);
79465
+ return {
79466
+ url,
79467
+ ok: false,
79468
+ error: message
79469
+ };
79470
+ } finally {
79471
+ clearTimeout(timeout);
79472
+ }
79473
+ }
79474
+ function getClusterSnapshot() {
79475
+ const k3d = findExecutable("k3d");
79476
+ if (!k3d) {
79477
+ return { exists: false, running: false };
79478
+ }
79479
+ const result = run(k3d, ["cluster", "list", "-o", "json"], {
79480
+ stdio: "pipe",
79481
+ allowFailure: true
79482
+ });
79483
+ if (result.status !== 0) {
79484
+ return { exists: false, running: false };
79485
+ }
79486
+ try {
79487
+ const payload = JSON.parse(result.stdout);
79488
+ const cluster = payload.find((item) => item.name === DEFAULT_CLUSTER_NAME);
79489
+ if (!cluster) {
79490
+ return { exists: false, running: false };
79491
+ }
79492
+ const serversRunning = Number(cluster.serversRunning ?? 0);
79493
+ const serversCount = Number(cluster.serversCount ?? 0);
79494
+ return {
79495
+ exists: true,
79496
+ running: serversCount > 0 && serversRunning >= serversCount
79497
+ };
79498
+ } catch {
79499
+ return { exists: false, running: false };
79500
+ }
79501
+ }
79502
+ function parseTimeoutSeconds(flags, defaultValue) {
79503
+ const raw = getStringFlag(flags, ["timeout"]);
79504
+ if (!raw) return defaultValue;
79505
+ const value = Number.parseInt(raw, 10);
79506
+ if (!Number.isFinite(value) || value <= 0) {
79507
+ throw new Error(`Invalid --timeout value: ${raw}`);
79508
+ }
79509
+ return value;
79510
+ }
79511
+ function run(command, args, options = {}) {
79512
+ const env = { ...process.env };
79513
+ if ((0, import_node_fs19.existsSync)(MANAGED_BIN_DIR)) {
79514
+ env.PATH = `${MANAGED_BIN_DIR}:${env.PATH ?? ""}`;
79515
+ }
79516
+ const result = (0, import_node_child_process10.spawnSync)(command, args, {
79517
+ cwd: options.cwd,
79518
+ encoding: "utf8",
79519
+ stdio: options.stdio ?? "pipe",
79520
+ env,
79521
+ timeout: options.timeoutMs
79522
+ });
79523
+ const status = result.status ?? 1;
79524
+ const stdout = result.stdout ?? "";
79525
+ const stderr = result.stderr ?? "";
79526
+ if (status !== 0 && !options.allowFailure) {
79527
+ const message = stderr.trim() || stdout.trim() || `${command} exited with status ${status}`;
79528
+ throw new Error(message);
79529
+ }
79530
+ return { status, stdout, stderr };
79531
+ }
79532
+ function findExecutable(name) {
79533
+ const managed = (0, import_node_path18.join)(MANAGED_BIN_DIR, name);
79534
+ if ((0, import_node_fs19.existsSync)(managed)) {
79535
+ return managed;
79536
+ }
79537
+ const found = (0, import_node_child_process10.spawnSync)("which", [name], {
79538
+ encoding: "utf8",
79539
+ stdio: "pipe"
79540
+ });
79541
+ if (found.status === 0 && found.stdout.trim()) {
79542
+ return found.stdout.trim();
79543
+ }
79544
+ return void 0;
79545
+ }
79546
+ function ensureTool(name, installHint) {
79547
+ if (!findExecutable(name)) {
79548
+ throw new Error(`Missing required tool '${name}'. ${installHint}`);
79549
+ }
79550
+ }
79551
+ function requireToolPath(name, hint) {
79552
+ const path6 = findExecutable(name);
79553
+ if (!path6) {
79554
+ throw new Error(`Missing required tool '${name}'. ${hint}`);
79555
+ }
79556
+ return path6;
79557
+ }
79558
+ function assertDockerRunning() {
79559
+ const docker = findExecutable("docker");
79560
+ if (!docker) {
79561
+ throw new Error("Missing required tool 'docker'. Install Docker Desktop.");
79562
+ }
79563
+ const result = run(docker, ["info"], { stdio: "pipe", allowFailure: true });
79564
+ if (result.status !== 0) {
79565
+ throw new Error("Docker daemon is not reachable. Start Docker Desktop and retry.");
79566
+ }
79567
+ }
79568
+ function trySelectLocalContext() {
79569
+ const kubectl = findExecutable("kubectl");
79570
+ if (!kubectl) {
79571
+ return;
79572
+ }
79573
+ const exists = run(
79574
+ kubectl,
79575
+ ["config", "get-contexts", DEFAULT_KUBE_CONTEXT],
79576
+ { stdio: "pipe", allowFailure: true }
79577
+ );
79578
+ if (exists.status !== 0) {
79579
+ return;
79580
+ }
79581
+ run(
79582
+ kubectl,
79583
+ ["config", "use-context", DEFAULT_KUBE_CONTEXT],
79584
+ { stdio: "pipe", allowFailure: true }
79585
+ );
79586
+ }
79587
+ function printProgress(runtimeOptions, message) {
79588
+ if (!runtimeOptions.quiet) {
79589
+ console.log(message);
79590
+ }
79591
+ }
79592
+ async function confirm(promptText) {
79593
+ if (!process.stdin.isTTY) {
79594
+ return false;
79595
+ }
79596
+ const rl = (0, import_promises2.createInterface)({ input: process.stdin, output: process.stdout });
79597
+ try {
79598
+ const answer = await rl.question(promptText);
79599
+ const normalized = answer.trim().toLowerCase();
79600
+ return normalized === "y" || normalized === "yes";
79601
+ } finally {
79602
+ rl.close();
79603
+ }
79604
+ }
79605
+ function sleep(ms) {
79606
+ return new Promise((resolvePromise) => {
79607
+ setTimeout(resolvePromise, ms);
79608
+ });
79609
+ }
79610
+
78448
79611
  // src/index.ts
78449
79612
  async function main2() {
78450
79613
  const { flags, positionals } = parseArgs(process.argv.slice(2));
@@ -78585,6 +79748,9 @@ async function main2() {
78585
79748
  case "fs":
78586
79749
  await handleFs(subcommand, rest, flags, context2);
78587
79750
  return;
79751
+ case "local":
79752
+ await handleLocal(subcommand, rest, flags, context2);
79753
+ return;
78588
79754
  default:
78589
79755
  showMainHelp();
78590
79756
  }