@specific.dev/cli 0.1.62 → 0.1.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/admin/404/index.html +1 -1
  2. package/dist/admin/404.html +1 -1
  3. package/dist/admin/__next.!KGRlZmF1bHQp.__PAGE__.txt +2 -2
  4. package/dist/admin/__next.!KGRlZmF1bHQp.txt +5 -5
  5. package/dist/admin/__next._full.txt +8 -8
  6. package/dist/admin/__next._head.txt +1 -1
  7. package/dist/admin/__next._index.txt +3 -3
  8. package/dist/admin/__next._tree.txt +1 -1
  9. package/dist/admin/_next/static/chunks/{59b95f8f36877231.js → 369cccd775763aa2.js} +2 -2
  10. package/dist/admin/_next/static/chunks/497f00630c8a5681.js +1 -0
  11. package/dist/admin/_next/static/chunks/{422a5aac8222197b.js → c7954d71061f1f9b.js} +2 -2
  12. package/dist/admin/_next/static/chunks/e3baf0c708c5b9ae.js +1 -0
  13. package/dist/admin/_not-found/__next._full.txt +3 -3
  14. package/dist/admin/_not-found/__next._head.txt +1 -1
  15. package/dist/admin/_not-found/__next._index.txt +3 -3
  16. package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
  17. package/dist/admin/_not-found/__next._not-found.txt +1 -1
  18. package/dist/admin/_not-found/__next._tree.txt +1 -1
  19. package/dist/admin/_not-found/index.html +1 -1
  20. package/dist/admin/_not-found/index.txt +3 -3
  21. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +2 -2
  22. package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +1 -1
  23. package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +5 -5
  24. package/dist/admin/databases/__next._full.txt +8 -8
  25. package/dist/admin/databases/__next._head.txt +1 -1
  26. package/dist/admin/databases/__next._index.txt +3 -3
  27. package/dist/admin/databases/__next._tree.txt +1 -1
  28. package/dist/admin/databases/index.html +1 -1
  29. package/dist/admin/databases/index.txt +8 -8
  30. package/dist/admin/fullscreen/__next._full.txt +4 -4
  31. package/dist/admin/fullscreen/__next._head.txt +1 -1
  32. package/dist/admin/fullscreen/__next._index.txt +3 -3
  33. package/dist/admin/fullscreen/__next._tree.txt +1 -1
  34. package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +2 -2
  35. package/dist/admin/fullscreen/__next.fullscreen.txt +1 -1
  36. package/dist/admin/fullscreen/databases/__next._full.txt +4 -4
  37. package/dist/admin/fullscreen/databases/__next._head.txt +1 -1
  38. package/dist/admin/fullscreen/databases/__next._index.txt +3 -3
  39. package/dist/admin/fullscreen/databases/__next._tree.txt +1 -1
  40. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +2 -2
  41. package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +1 -1
  42. package/dist/admin/fullscreen/databases/__next.fullscreen.txt +1 -1
  43. package/dist/admin/fullscreen/databases/index.html +1 -1
  44. package/dist/admin/fullscreen/databases/index.txt +4 -4
  45. package/dist/admin/fullscreen/index.html +1 -1
  46. package/dist/admin/fullscreen/index.txt +4 -4
  47. package/dist/admin/index.html +1 -1
  48. package/dist/admin/index.txt +8 -8
  49. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +8 -0
  50. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +9 -0
  51. package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +4 -0
  52. package/dist/admin/workflows/__next._full.txt +27 -0
  53. package/dist/admin/workflows/__next._head.txt +6 -0
  54. package/dist/admin/workflows/__next._index.txt +7 -0
  55. package/dist/admin/workflows/__next._tree.txt +5 -0
  56. package/dist/admin/workflows/index.html +1 -0
  57. package/dist/admin/workflows/index.txt +27 -0
  58. package/dist/cli.js +1286 -324
  59. package/dist/docs/builds.md +59 -13
  60. package/dist/docs/index.md +4 -0
  61. package/dist/docs/integrations/temporal.md +4 -0
  62. package/dist/docs/temporal.md +98 -0
  63. package/dist/docs/volumes.md +63 -0
  64. package/dist/postinstall.js +1 -1
  65. package/package.json +4 -2
  66. package/dist/admin/_next/static/chunks/144304e5f91b7ae5.js +0 -1
  67. /package/dist/admin/_next/static/{bSt01e539un5ZT_sTTRm7 → 3gQ1McserxEZ29fmlvSRS}/_buildManifest.js +0 -0
  68. /package/dist/admin/_next/static/{bSt01e539un5ZT_sTTRm7 → 3gQ1McserxEZ29fmlvSRS}/_clientMiddlewareManifest.json +0 -0
  69. /package/dist/admin/_next/static/{bSt01e539un5ZT_sTTRm7 → 3gQ1McserxEZ29fmlvSRS}/_ssgManifest.js +0 -0
package/dist/cli.js CHANGED
@@ -238,15 +238,15 @@ var init_wsl_utils = __esm({
238
238
  const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
239
239
  return stdout.trim();
240
240
  };
241
- convertWslPathToWindows = async (path27) => {
242
- if (/^[a-z]+:\/\//i.test(path27)) {
243
- return path27;
241
+ convertWslPathToWindows = async (path28) => {
242
+ if (/^[a-z]+:\/\//i.test(path28)) {
243
+ return path28;
244
244
  }
245
245
  try {
246
- const { stdout } = await execFile2("wslpath", ["-aw", path27], { encoding: "utf8" });
246
+ const { stdout } = await execFile2("wslpath", ["-aw", path28], { encoding: "utf8" });
247
247
  return stdout.trim();
248
248
  } catch {
249
- return path27;
249
+ return path28;
250
250
  }
251
251
  };
252
252
  }
@@ -754,8 +754,8 @@ var require_dist = __commonJS({
754
754
  var $global, $module, $NaN = NaN;
755
755
  if ("undefined" != typeof window ? $global = window : "undefined" != typeof self ? $global = self : "undefined" != typeof global ? ($global = global).require = __require : $global = this, void 0 === $global || void 0 === $global.Array) throw new Error("no global object found");
756
756
  if ("undefined" != typeof module && ($module = module), !$global.fs && $global.require) try {
757
- var fs29 = $global.require("fs");
758
- "object" == typeof fs29 && null !== fs29 && 0 !== Object.keys(fs29).length && ($global.fs = fs29);
757
+ var fs30 = $global.require("fs");
758
+ "object" == typeof fs30 && null !== fs30 && 0 !== Object.keys(fs30).length && ($global.fs = fs30);
759
759
  } catch (e) {
760
760
  }
761
761
  if (!$global.fs) {
@@ -182942,6 +182942,487 @@ var require_dist = __commonJS({
182942
182942
  }
182943
182943
  });
182944
182944
 
182945
+ // node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js
182946
+ var require_picocolors = __commonJS({
182947
+ "node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js"(exports, module) {
182948
+ var p = process || {};
182949
+ var argv = p.argv || [];
182950
+ var env2 = p.env || {};
182951
+ var isColorSupported = !(!!env2.NO_COLOR || argv.includes("--no-color")) && (!!env2.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env2.TERM !== "dumb" || !!env2.CI);
182952
+ var formatter = (open3, close, replace = open3) => (input) => {
182953
+ let string = "" + input, index = string.indexOf(close, open3.length);
182954
+ return ~index ? open3 + replaceClose(string, close, replace, index) + close : open3 + string + close;
182955
+ };
182956
+ var replaceClose = (string, close, replace, index) => {
182957
+ let result = "", cursor = 0;
182958
+ do {
182959
+ result += string.substring(cursor, index) + replace;
182960
+ cursor = index + close.length;
182961
+ index = string.indexOf(close, cursor);
182962
+ } while (~index);
182963
+ return result + string.substring(cursor);
182964
+ };
182965
+ var createColors = (enabled = isColorSupported) => {
182966
+ let f = enabled ? formatter : () => String;
182967
+ return {
182968
+ isColorSupported: enabled,
182969
+ reset: f("\x1B[0m", "\x1B[0m"),
182970
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
182971
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
182972
+ italic: f("\x1B[3m", "\x1B[23m"),
182973
+ underline: f("\x1B[4m", "\x1B[24m"),
182974
+ inverse: f("\x1B[7m", "\x1B[27m"),
182975
+ hidden: f("\x1B[8m", "\x1B[28m"),
182976
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
182977
+ black: f("\x1B[30m", "\x1B[39m"),
182978
+ red: f("\x1B[31m", "\x1B[39m"),
182979
+ green: f("\x1B[32m", "\x1B[39m"),
182980
+ yellow: f("\x1B[33m", "\x1B[39m"),
182981
+ blue: f("\x1B[34m", "\x1B[39m"),
182982
+ magenta: f("\x1B[35m", "\x1B[39m"),
182983
+ cyan: f("\x1B[36m", "\x1B[39m"),
182984
+ white: f("\x1B[37m", "\x1B[39m"),
182985
+ gray: f("\x1B[90m", "\x1B[39m"),
182986
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
182987
+ bgRed: f("\x1B[41m", "\x1B[49m"),
182988
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
182989
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
182990
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
182991
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
182992
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
182993
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
182994
+ blackBright: f("\x1B[90m", "\x1B[39m"),
182995
+ redBright: f("\x1B[91m", "\x1B[39m"),
182996
+ greenBright: f("\x1B[92m", "\x1B[39m"),
182997
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
182998
+ blueBright: f("\x1B[94m", "\x1B[39m"),
182999
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
183000
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
183001
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
183002
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
183003
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
183004
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
183005
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
183006
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
183007
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
183008
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
183009
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
183010
+ };
183011
+ };
183012
+ module.exports = createColors();
183013
+ module.exports.createColors = createColors;
183014
+ }
183015
+ });
183016
+
183017
+ // node_modules/.pnpm/js-tokens@4.0.0/node_modules/js-tokens/index.js
183018
+ var require_js_tokens = __commonJS({
183019
+ "node_modules/.pnpm/js-tokens@4.0.0/node_modules/js-tokens/index.js"(exports) {
183020
+ Object.defineProperty(exports, "__esModule", {
183021
+ value: true
183022
+ });
183023
+ exports.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyus]{1,6}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g;
183024
+ exports.matchToToken = function(match) {
183025
+ var token = { type: "invalid", value: match[0], closed: void 0 };
183026
+ if (match[1]) token.type = "string", token.closed = !!(match[3] || match[4]);
183027
+ else if (match[5]) token.type = "comment";
183028
+ else if (match[6]) token.type = "comment", token.closed = !!match[7];
183029
+ else if (match[8]) token.type = "regex";
183030
+ else if (match[9]) token.type = "number";
183031
+ else if (match[10]) token.type = "name";
183032
+ else if (match[11]) token.type = "punctuator";
183033
+ else if (match[12]) token.type = "whitespace";
183034
+ return token;
183035
+ };
183036
+ }
183037
+ });
183038
+
183039
+ // node_modules/.pnpm/@babel+helper-validator-identifier@7.28.5/node_modules/@babel/helper-validator-identifier/lib/identifier.js
183040
+ var require_identifier = __commonJS({
183041
+ "node_modules/.pnpm/@babel+helper-validator-identifier@7.28.5/node_modules/@babel/helper-validator-identifier/lib/identifier.js"(exports) {
183042
+ "use strict";
183043
+ Object.defineProperty(exports, "__esModule", {
183044
+ value: true
183045
+ });
183046
+ exports.isIdentifierChar = isIdentifierChar;
183047
+ exports.isIdentifierName = isIdentifierName;
183048
+ exports.isIdentifierStart = isIdentifierStart;
183049
+ var nonASCIIidentifierStartChars = "\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088F\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5C\u0C5D\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDC-\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C8A\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7DC\uA7F1-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC";
183050
+ var nonASCIIidentifierChars = "\xB7\u0300-\u036F\u0387\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u0897-\u089F\u08CA-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0966-\u096F\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09E6-\u09EF\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A66-\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AE6-\u0AEF\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B66-\u0B6F\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0BE6-\u0BEF\u0C00-\u0C04\u0C3C\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0CE6-\u0CEF\u0CF3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D66-\u0D6F\u0D81-\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0E50-\u0E59\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECE\u0ED0-\u0ED9\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1040-\u1049\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F-\u109D\u135D-\u135F\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u17E0-\u17E9\u180B-\u180D\u180F-\u1819\u18A9\u1920-\u192B\u1930-\u193B\u1946-\u194F\u19D0-\u19DA\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AB0-\u1ABD\u1ABF-\u1ADD\u1AE0-\u1AEB\u1B00-\u1B04\u1B34-\u1B44\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BB0-\u1BB9\u1BE6-\u1BF3\u1C24-\u1C37\u1C40-\u1C49\u1C50-\u1C59\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DFF\u200C\u200D\u203F\u2040\u2054\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\u30FB\uA620-\uA629\uA66F\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA82C\uA880\uA881\uA8B4-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F1\uA8FF-\uA909\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9D0-\uA9D9\uA9E5\uA9F0-\uA9F9\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA50-\uAA59\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uABF0-\uABF9\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFF10-\uFF19\uFF3F\uFF65";
183051
+ var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
183052
+ var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
183053
+ nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
183054
+ var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 7, 25, 39, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 39, 27, 10, 22, 251, 41, 7, 1, 17, 5, 57, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 31, 9, 2, 0, 3, 0, 2, 37, 2, 0, 26, 0, 2, 0, 45, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 200, 32, 32, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 24, 43, 261, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 26, 3994, 6, 582, 6842, 29, 1763, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 433, 44, 212, 63, 33, 24, 3, 24, 45, 74, 6, 0, 67, 12, 65, 1, 2, 0, 15, 4, 10, 7381, 42, 31, 98, 114, 8702, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 229, 29, 3, 0, 208, 30, 2, 2, 2, 1, 2, 6, 3, 4, 10, 1, 225, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4381, 3, 5773, 3, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 8489];
183055
+ var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 7, 9, 32, 4, 318, 1, 78, 5, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 68, 8, 2, 0, 3, 0, 2, 3, 2, 4, 2, 0, 15, 1, 83, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 7, 19, 58, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 199, 7, 137, 9, 54, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 55, 9, 266, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 10, 5350, 0, 7, 14, 11465, 27, 2343, 9, 87, 9, 39, 4, 60, 6, 26, 9, 535, 9, 470, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4178, 9, 519, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 245, 1, 2, 9, 233, 0, 3, 0, 8, 1, 6, 0, 475, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];
183056
+ function isInAstralSet(code, set) {
183057
+ let pos = 65536;
183058
+ for (let i = 0, length = set.length; i < length; i += 2) {
183059
+ pos += set[i];
183060
+ if (pos > code) return false;
183061
+ pos += set[i + 1];
183062
+ if (pos >= code) return true;
183063
+ }
183064
+ return false;
183065
+ }
183066
+ function isIdentifierStart(code) {
183067
+ if (code < 65) return code === 36;
183068
+ if (code <= 90) return true;
183069
+ if (code < 97) return code === 95;
183070
+ if (code <= 122) return true;
183071
+ if (code <= 65535) {
183072
+ return code >= 170 && nonASCIIidentifierStart.test(String.fromCharCode(code));
183073
+ }
183074
+ return isInAstralSet(code, astralIdentifierStartCodes);
183075
+ }
183076
+ function isIdentifierChar(code) {
183077
+ if (code < 48) return code === 36;
183078
+ if (code < 58) return true;
183079
+ if (code < 65) return false;
183080
+ if (code <= 90) return true;
183081
+ if (code < 97) return code === 95;
183082
+ if (code <= 122) return true;
183083
+ if (code <= 65535) {
183084
+ return code >= 170 && nonASCIIidentifier.test(String.fromCharCode(code));
183085
+ }
183086
+ return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
183087
+ }
183088
+ function isIdentifierName(name) {
183089
+ let isFirst = true;
183090
+ for (let i = 0; i < name.length; i++) {
183091
+ let cp = name.charCodeAt(i);
183092
+ if ((cp & 64512) === 55296 && i + 1 < name.length) {
183093
+ const trail = name.charCodeAt(++i);
183094
+ if ((trail & 64512) === 56320) {
183095
+ cp = 65536 + ((cp & 1023) << 10) + (trail & 1023);
183096
+ }
183097
+ }
183098
+ if (isFirst) {
183099
+ isFirst = false;
183100
+ if (!isIdentifierStart(cp)) {
183101
+ return false;
183102
+ }
183103
+ } else if (!isIdentifierChar(cp)) {
183104
+ return false;
183105
+ }
183106
+ }
183107
+ return !isFirst;
183108
+ }
183109
+ }
183110
+ });
183111
+
183112
+ // node_modules/.pnpm/@babel+helper-validator-identifier@7.28.5/node_modules/@babel/helper-validator-identifier/lib/keyword.js
183113
+ var require_keyword = __commonJS({
183114
+ "node_modules/.pnpm/@babel+helper-validator-identifier@7.28.5/node_modules/@babel/helper-validator-identifier/lib/keyword.js"(exports) {
183115
+ "use strict";
183116
+ Object.defineProperty(exports, "__esModule", {
183117
+ value: true
183118
+ });
183119
+ exports.isKeyword = isKeyword;
183120
+ exports.isReservedWord = isReservedWord;
183121
+ exports.isStrictBindOnlyReservedWord = isStrictBindOnlyReservedWord;
183122
+ exports.isStrictBindReservedWord = isStrictBindReservedWord;
183123
+ exports.isStrictReservedWord = isStrictReservedWord;
183124
+ var reservedWords = {
183125
+ keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"],
183126
+ strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"],
183127
+ strictBind: ["eval", "arguments"]
183128
+ };
183129
+ var keywords = new Set(reservedWords.keyword);
183130
+ var reservedWordsStrictSet = new Set(reservedWords.strict);
183131
+ var reservedWordsStrictBindSet = new Set(reservedWords.strictBind);
183132
+ function isReservedWord(word, inModule) {
183133
+ return inModule && word === "await" || word === "enum";
183134
+ }
183135
+ function isStrictReservedWord(word, inModule) {
183136
+ return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word);
183137
+ }
183138
+ function isStrictBindOnlyReservedWord(word) {
183139
+ return reservedWordsStrictBindSet.has(word);
183140
+ }
183141
+ function isStrictBindReservedWord(word, inModule) {
183142
+ return isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word);
183143
+ }
183144
+ function isKeyword(word) {
183145
+ return keywords.has(word);
183146
+ }
183147
+ }
183148
+ });
183149
+
183150
+ // node_modules/.pnpm/@babel+helper-validator-identifier@7.28.5/node_modules/@babel/helper-validator-identifier/lib/index.js
183151
+ var require_lib = __commonJS({
183152
+ "node_modules/.pnpm/@babel+helper-validator-identifier@7.28.5/node_modules/@babel/helper-validator-identifier/lib/index.js"(exports) {
183153
+ "use strict";
183154
+ Object.defineProperty(exports, "__esModule", {
183155
+ value: true
183156
+ });
183157
+ Object.defineProperty(exports, "isIdentifierChar", {
183158
+ enumerable: true,
183159
+ get: function() {
183160
+ return _identifier.isIdentifierChar;
183161
+ }
183162
+ });
183163
+ Object.defineProperty(exports, "isIdentifierName", {
183164
+ enumerable: true,
183165
+ get: function() {
183166
+ return _identifier.isIdentifierName;
183167
+ }
183168
+ });
183169
+ Object.defineProperty(exports, "isIdentifierStart", {
183170
+ enumerable: true,
183171
+ get: function() {
183172
+ return _identifier.isIdentifierStart;
183173
+ }
183174
+ });
183175
+ Object.defineProperty(exports, "isKeyword", {
183176
+ enumerable: true,
183177
+ get: function() {
183178
+ return _keyword.isKeyword;
183179
+ }
183180
+ });
183181
+ Object.defineProperty(exports, "isReservedWord", {
183182
+ enumerable: true,
183183
+ get: function() {
183184
+ return _keyword.isReservedWord;
183185
+ }
183186
+ });
183187
+ Object.defineProperty(exports, "isStrictBindOnlyReservedWord", {
183188
+ enumerable: true,
183189
+ get: function() {
183190
+ return _keyword.isStrictBindOnlyReservedWord;
183191
+ }
183192
+ });
183193
+ Object.defineProperty(exports, "isStrictBindReservedWord", {
183194
+ enumerable: true,
183195
+ get: function() {
183196
+ return _keyword.isStrictBindReservedWord;
183197
+ }
183198
+ });
183199
+ Object.defineProperty(exports, "isStrictReservedWord", {
183200
+ enumerable: true,
183201
+ get: function() {
183202
+ return _keyword.isStrictReservedWord;
183203
+ }
183204
+ });
183205
+ var _identifier = require_identifier();
183206
+ var _keyword = require_keyword();
183207
+ }
183208
+ });
183209
+
183210
+ // node_modules/.pnpm/@babel+code-frame@7.29.0/node_modules/@babel/code-frame/lib/index.js
183211
+ var require_lib2 = __commonJS({
183212
+ "node_modules/.pnpm/@babel+code-frame@7.29.0/node_modules/@babel/code-frame/lib/index.js"(exports) {
183213
+ "use strict";
183214
+ Object.defineProperty(exports, "__esModule", { value: true });
183215
+ var picocolors = require_picocolors();
183216
+ var jsTokens = require_js_tokens();
183217
+ var helperValidatorIdentifier = require_lib();
183218
+ function isColorSupported() {
183219
+ return typeof process === "object" && (process.env.FORCE_COLOR === "0" || process.env.FORCE_COLOR === "false") ? false : picocolors.isColorSupported;
183220
+ }
183221
+ var compose = (f, g) => (v) => f(g(v));
183222
+ function buildDefs(colors) {
183223
+ return {
183224
+ keyword: colors.cyan,
183225
+ capitalized: colors.yellow,
183226
+ jsxIdentifier: colors.yellow,
183227
+ punctuator: colors.yellow,
183228
+ number: colors.magenta,
183229
+ string: colors.green,
183230
+ regex: colors.magenta,
183231
+ comment: colors.gray,
183232
+ invalid: compose(compose(colors.white, colors.bgRed), colors.bold),
183233
+ gutter: colors.gray,
183234
+ marker: compose(colors.red, colors.bold),
183235
+ message: compose(colors.red, colors.bold),
183236
+ reset: colors.reset
183237
+ };
183238
+ }
183239
+ var defsOn = buildDefs(picocolors.createColors(true));
183240
+ var defsOff = buildDefs(picocolors.createColors(false));
183241
+ function getDefs(enabled) {
183242
+ return enabled ? defsOn : defsOff;
183243
+ }
183244
+ var sometimesKeywords = /* @__PURE__ */ new Set(["as", "async", "from", "get", "of", "set"]);
183245
+ var NEWLINE$1 = /\r\n|[\n\r\u2028\u2029]/;
183246
+ var BRACKET = /^[()[\]{}]$/;
183247
+ var tokenize;
183248
+ var JSX_TAG = /^[a-z][\w-]*$/i;
183249
+ var getTokenType = function(token, offset, text) {
183250
+ if (token.type === "name") {
183251
+ const tokenValue = token.value;
183252
+ if (helperValidatorIdentifier.isKeyword(tokenValue) || helperValidatorIdentifier.isStrictReservedWord(tokenValue, true) || sometimesKeywords.has(tokenValue)) {
183253
+ return "keyword";
183254
+ }
183255
+ if (JSX_TAG.test(tokenValue) && (text[offset - 1] === "<" || text.slice(offset - 2, offset) === "</")) {
183256
+ return "jsxIdentifier";
183257
+ }
183258
+ const firstChar = String.fromCodePoint(tokenValue.codePointAt(0));
183259
+ if (firstChar !== firstChar.toLowerCase()) {
183260
+ return "capitalized";
183261
+ }
183262
+ }
183263
+ if (token.type === "punctuator" && BRACKET.test(token.value)) {
183264
+ return "bracket";
183265
+ }
183266
+ if (token.type === "invalid" && (token.value === "@" || token.value === "#")) {
183267
+ return "punctuator";
183268
+ }
183269
+ return token.type;
183270
+ };
183271
+ tokenize = function* (text) {
183272
+ let match;
183273
+ while (match = jsTokens.default.exec(text)) {
183274
+ const token = jsTokens.matchToToken(match);
183275
+ yield {
183276
+ type: getTokenType(token, match.index, text),
183277
+ value: token.value
183278
+ };
183279
+ }
183280
+ };
183281
+ function highlight(text) {
183282
+ if (text === "") return "";
183283
+ const defs = getDefs(true);
183284
+ let highlighted = "";
183285
+ for (const {
183286
+ type,
183287
+ value
183288
+ } of tokenize(text)) {
183289
+ if (type in defs) {
183290
+ highlighted += value.split(NEWLINE$1).map((str) => defs[type](str)).join("\n");
183291
+ } else {
183292
+ highlighted += value;
183293
+ }
183294
+ }
183295
+ return highlighted;
183296
+ }
183297
+ var deprecationWarningShown = false;
183298
+ var NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
183299
+ function getMarkerLines(loc, source, opts, startLineBaseZero) {
183300
+ const startLoc = Object.assign({
183301
+ column: 0,
183302
+ line: -1
183303
+ }, loc.start);
183304
+ const endLoc = Object.assign({}, startLoc, loc.end);
183305
+ const {
183306
+ linesAbove = 2,
183307
+ linesBelow = 3
183308
+ } = opts || {};
183309
+ const startLine = startLoc.line - startLineBaseZero;
183310
+ const startColumn = startLoc.column;
183311
+ const endLine = endLoc.line - startLineBaseZero;
183312
+ const endColumn = endLoc.column;
183313
+ let start = Math.max(startLine - (linesAbove + 1), 0);
183314
+ let end = Math.min(source.length, endLine + linesBelow);
183315
+ if (startLine === -1) {
183316
+ start = 0;
183317
+ }
183318
+ if (endLine === -1) {
183319
+ end = source.length;
183320
+ }
183321
+ const lineDiff = endLine - startLine;
183322
+ const markerLines = {};
183323
+ if (lineDiff) {
183324
+ for (let i = 0; i <= lineDiff; i++) {
183325
+ const lineNumber = i + startLine;
183326
+ if (!startColumn) {
183327
+ markerLines[lineNumber] = true;
183328
+ } else if (i === 0) {
183329
+ const sourceLength = source[lineNumber - 1].length;
183330
+ markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];
183331
+ } else if (i === lineDiff) {
183332
+ markerLines[lineNumber] = [0, endColumn];
183333
+ } else {
183334
+ const sourceLength = source[lineNumber - i].length;
183335
+ markerLines[lineNumber] = [0, sourceLength];
183336
+ }
183337
+ }
183338
+ } else {
183339
+ if (startColumn === endColumn) {
183340
+ if (startColumn) {
183341
+ markerLines[startLine] = [startColumn, 0];
183342
+ } else {
183343
+ markerLines[startLine] = true;
183344
+ }
183345
+ } else {
183346
+ markerLines[startLine] = [startColumn, endColumn - startColumn];
183347
+ }
183348
+ }
183349
+ return {
183350
+ start,
183351
+ end,
183352
+ markerLines
183353
+ };
183354
+ }
183355
+ function codeFrameColumns2(rawLines, loc, opts = {}) {
183356
+ const shouldHighlight = opts.forceColor || isColorSupported() && opts.highlightCode;
183357
+ const startLineBaseZero = (opts.startLine || 1) - 1;
183358
+ const defs = getDefs(shouldHighlight);
183359
+ const lines = rawLines.split(NEWLINE);
183360
+ const {
183361
+ start,
183362
+ end,
183363
+ markerLines
183364
+ } = getMarkerLines(loc, lines, opts, startLineBaseZero);
183365
+ const hasColumns = loc.start && typeof loc.start.column === "number";
183366
+ const numberMaxWidth = String(end + startLineBaseZero).length;
183367
+ const highlightedLines = shouldHighlight ? highlight(rawLines) : rawLines;
183368
+ let frame = highlightedLines.split(NEWLINE, end).slice(start, end).map((line, index2) => {
183369
+ const number = start + 1 + index2;
183370
+ const paddedNumber = ` ${number + startLineBaseZero}`.slice(-numberMaxWidth);
183371
+ const gutter = ` ${paddedNumber} |`;
183372
+ const hasMarker = markerLines[number];
183373
+ const lastMarkerLine = !markerLines[number + 1];
183374
+ if (hasMarker) {
183375
+ let markerLine = "";
183376
+ if (Array.isArray(hasMarker)) {
183377
+ const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " ");
183378
+ const numberOfMarkers = hasMarker[1] || 1;
183379
+ markerLine = ["\n ", defs.gutter(gutter.replace(/\d/g, " ")), " ", markerSpacing, defs.marker("^").repeat(numberOfMarkers)].join("");
183380
+ if (lastMarkerLine && opts.message) {
183381
+ markerLine += " " + defs.message(opts.message);
183382
+ }
183383
+ }
183384
+ return [defs.marker(">"), defs.gutter(gutter), line.length > 0 ? ` ${line}` : "", markerLine].join("");
183385
+ } else {
183386
+ return ` ${defs.gutter(gutter)}${line.length > 0 ? ` ${line}` : ""}`;
183387
+ }
183388
+ }).join("\n");
183389
+ if (opts.message && !hasColumns) {
183390
+ frame = `${" ".repeat(numberMaxWidth + 1)}${opts.message}
183391
+ ${frame}`;
183392
+ }
183393
+ if (shouldHighlight) {
183394
+ return defs.reset(frame);
183395
+ } else {
183396
+ return frame;
183397
+ }
183398
+ }
183399
+ function index(rawLines, lineNumber, colNumber, opts = {}) {
183400
+ if (!deprecationWarningShown) {
183401
+ deprecationWarningShown = true;
183402
+ const message = "Passing lineNumber and colNumber is deprecated to @babel/code-frame. Please use `codeFrameColumns`.";
183403
+ if (process.emitWarning) {
183404
+ process.emitWarning(message, "DeprecationWarning");
183405
+ } else {
183406
+ const deprecationError = new Error(message);
183407
+ deprecationError.name = "DeprecationWarning";
183408
+ console.warn(new Error(message));
183409
+ }
183410
+ }
183411
+ colNumber = Math.max(colNumber, 0);
183412
+ const location = {
183413
+ start: {
183414
+ column: colNumber,
183415
+ line: lineNumber
183416
+ }
183417
+ };
183418
+ return codeFrameColumns2(rawLines, location, opts);
183419
+ }
183420
+ exports.codeFrameColumns = codeFrameColumns2;
183421
+ exports.default = index;
183422
+ exports.highlight = highlight;
183423
+ }
183424
+ });
183425
+
182945
183426
  // src/cli.tsx
182946
183427
  import { Command } from "commander";
182947
183428
 
@@ -184014,7 +184495,7 @@ function trackEvent(event, properties) {
184014
184495
  event,
184015
184496
  properties: {
184016
184497
  ...properties,
184017
- cli_version: "0.1.62",
184498
+ cli_version: "0.1.63",
184018
184499
  platform: process.platform,
184019
184500
  node_version: process.version,
184020
184501
  project_id: getProjectId(),
@@ -184382,6 +184863,10 @@ var BETA_REGISTRY = [
184382
184863
  {
184383
184864
  name: "reshape",
184384
184865
  description: "Zero-downtime database schema migrations using Reshape"
184866
+ },
184867
+ {
184868
+ name: "temporal",
184869
+ description: "Managed Temporal workflow engine for durable workflows and background tasks"
184385
184870
  }
184386
184871
  ];
184387
184872
 
@@ -184428,11 +184913,11 @@ function saveBetas(enabled, projectDir) {
184428
184913
  // src/commands/docs.tsx
184429
184914
  var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
184430
184915
  var docsDir = join8(__dirname2, "docs");
184431
- function docsCommand(path27) {
184432
- const docPath = resolveDocPath(path27);
184916
+ function docsCommand(path28) {
184917
+ const docPath = resolveDocPath(path28);
184433
184918
  if (!docPath) {
184434
184919
  console.error(
184435
- `Documentation not found: ${path27 || "index"}
184920
+ `Documentation not found: ${path28 || "index"}
184436
184921
 
184437
184922
  Run 'specific docs' to see available topics.`
184438
184923
  );
@@ -184451,16 +184936,16 @@ function filterBetaTags(content, enabledBetas) {
184451
184936
  }
184452
184937
  );
184453
184938
  }
184454
- function resolveDocPath(path27) {
184455
- if (!path27) {
184939
+ function resolveDocPath(path28) {
184940
+ if (!path28) {
184456
184941
  const indexPath2 = join8(docsDir, "index.md");
184457
184942
  return existsSync7(indexPath2) ? indexPath2 : null;
184458
184943
  }
184459
- const directPath = join8(docsDir, `${path27}.md`);
184944
+ const directPath = join8(docsDir, `${path28}.md`);
184460
184945
  if (existsSync7(directPath)) {
184461
184946
  return directPath;
184462
184947
  }
184463
- const indexPath = join8(docsDir, path27, "index.md");
184948
+ const indexPath = join8(docsDir, path28, "index.md");
184464
184949
  if (existsSync7(indexPath)) {
184465
184950
  return indexPath;
184466
184951
  }
@@ -184575,6 +185060,28 @@ function parseReferenceString(str) {
184575
185060
  };
184576
185061
  }
184577
185062
  }
185063
+ const temporalMatch = str.match(/^temporal\.(\w+)\.(\w+)$/);
185064
+ if (temporalMatch && temporalMatch[1] && temporalMatch[2]) {
185065
+ const attr = temporalMatch[2];
185066
+ if (["url", "namespace", "api_key"].includes(attr)) {
185067
+ return {
185068
+ type: "temporal",
185069
+ name: temporalMatch[1],
185070
+ attribute: attr
185071
+ };
185072
+ }
185073
+ }
185074
+ const volumeMatch = str.match(/^volume\.(\w+)\.(\w+)$/);
185075
+ if (volumeMatch && volumeMatch[1] && volumeMatch[2]) {
185076
+ const attr = volumeMatch[2];
185077
+ if (["path"].includes(attr)) {
185078
+ return {
185079
+ type: "volume",
185080
+ volumeName: volumeMatch[1],
185081
+ attribute: attr
185082
+ };
185083
+ }
185084
+ }
184578
185085
  const configMatch = str.match(/^config\.(\w+)$/);
184579
185086
  if (configMatch && configMatch[1]) {
184580
185087
  return { type: "config", name: configMatch[1] };
@@ -184685,16 +185192,31 @@ function parseBuilds(buildData) {
184685
185192
  }
184686
185193
  const fieldObj = fields;
184687
185194
  const base = fieldObj.base;
184688
- if (!base) {
184689
- throw new Error(`Build "${name}" is missing required field "base". Supported values: ${VALID_BASES.join(", ")}`);
185195
+ const dockerfile = fieldObj.dockerfile;
185196
+ if (base && dockerfile) {
185197
+ throw new Error(`Build "${name}" cannot have both "base" and "dockerfile". Use one or the other.`);
185198
+ }
185199
+ if (!base && !dockerfile) {
185200
+ throw new Error(`Build "${name}" must have either "base" (supported: ${VALID_BASES.join(", ")}) or "dockerfile" (path to a custom Dockerfile).`);
184690
185201
  }
184691
- if (typeof base !== "string" || !VALID_BASES.includes(base)) {
184692
- throw new Error(`Build "${name}" has invalid base "${base}". Supported values: ${VALID_BASES.join(", ")}`);
185202
+ if (base) {
185203
+ if (typeof base !== "string" || !VALID_BASES.includes(base)) {
185204
+ throw new Error(`Build "${name}" has invalid base "${base}". Supported values: ${VALID_BASES.join(", ")}`);
185205
+ }
185206
+ }
185207
+ if (dockerfile) {
185208
+ if (typeof dockerfile !== "string" || dockerfile.trim() === "") {
185209
+ throw new Error(`Build "${name}" has invalid "dockerfile" value. Must be a non-empty path string.`);
185210
+ }
185211
+ if (fieldObj.command) {
185212
+ throw new Error(`Build "${name}" cannot have both "dockerfile" and "command". When using a custom Dockerfile, the build steps are defined in the Dockerfile itself.`);
185213
+ }
184693
185214
  }
184694
185215
  const dev = parseDevBlock(fieldObj.dev);
184695
185216
  const build = {
184696
185217
  name,
184697
- base
185218
+ ...base ? { base } : {},
185219
+ ...dockerfile ? { dockerfile: String(dockerfile) } : {}
184698
185220
  };
184699
185221
  if (fieldObj.command) {
184700
185222
  build.command = String(fieldObj.command);
@@ -184783,6 +185305,22 @@ function parseEndpoints(fieldObj) {
184783
185305
  }
184784
185306
  return endpoints;
184785
185307
  }
185308
+ function parseVolumes(fieldObj) {
185309
+ const volumes = [];
185310
+ const volumeData = fieldObj.volume;
185311
+ if (!volumeData) {
185312
+ return volumes;
185313
+ }
185314
+ if (typeof volumeData !== "object") {
185315
+ return volumes;
185316
+ }
185317
+ if (!Array.isArray(volumeData)) {
185318
+ for (const [name] of Object.entries(volumeData)) {
185319
+ volumes.push({ name });
185320
+ }
185321
+ }
185322
+ return volumes;
185323
+ }
184786
185324
  function parseServices(serviceData) {
184787
185325
  if (!serviceData || typeof serviceData !== "object" || Array.isArray(serviceData)) {
184788
185326
  return [];
@@ -184806,6 +185344,10 @@ function parseServices(serviceData) {
184806
185344
  service.root = String(fieldObj.root);
184807
185345
  }
184808
185346
  const endpoints = parseEndpoints(fieldObj);
185347
+ const volumes = parseVolumes(fieldObj);
185348
+ if (volumes.length > 0) {
185349
+ service.volumes = volumes;
185350
+ }
184809
185351
  if (fieldObj.expose !== void 0) {
184810
185352
  service.expose = {};
184811
185353
  if (endpoints.length === 0) {
@@ -184899,6 +185441,16 @@ function parseStorage(data) {
184899
185441
  }
184900
185442
  return result;
184901
185443
  }
185444
+ function parseTemporal(data) {
185445
+ if (!data || typeof data !== "object" || Array.isArray(data)) {
185446
+ return [];
185447
+ }
185448
+ const result = [];
185449
+ for (const [name] of Object.entries(data)) {
185450
+ result.push({ name });
185451
+ }
185452
+ return result;
185453
+ }
184902
185454
  function parseConfigDevBlock(dev) {
184903
185455
  if (!dev) {
184904
185456
  return void 0;
@@ -185010,6 +185562,7 @@ async function parseConfig(hcl) {
185010
185562
  postgres: parsePostgres(json.postgres),
185011
185563
  redis: parseRedis(json.redis),
185012
185564
  storage: parseStorage(json.storage),
185565
+ temporal: parseTemporal(json.temporal),
185013
185566
  configs: parseConfigs(json.config),
185014
185567
  secrets: parseSecrets(json.secret),
185015
185568
  environments: parseEnvironments(json.environment)
@@ -185108,12 +185661,101 @@ function validateEndpointReferences(config) {
185108
185661
  });
185109
185662
  }
185110
185663
  }
185664
+ if (ref.type === "volume") {
185665
+ const volumeRef = ref;
185666
+ const volumeExists = service.volumes?.some((v) => v.name === volumeRef.volumeName);
185667
+ if (!volumeExists) {
185668
+ errors.push({
185669
+ service: service.name,
185670
+ message: `Service "${service.name}" references volume "${volumeRef.volumeName}" in env var "${key}", but that volume is not defined on this service.`
185671
+ });
185672
+ }
185673
+ }
185111
185674
  }
185112
185675
  }
185113
185676
  }
185114
185677
  return errors;
185115
185678
  }
185116
185679
 
185680
+ // node_modules/.pnpm/@specific+config@file+..+config/node_modules/@specific/config/dist/errors.js
185681
+ function parseHclErrors(rawError) {
185682
+ const raw = rawError.trim();
185683
+ if (!raw.startsWith("parse config: [")) {
185684
+ return [];
185685
+ }
185686
+ const inner = raw.slice("parse config: [".length, -1);
185687
+ const errors = [];
185688
+ const locationPattern = /:(\d+),(\d+)-(?:(\d+),)?(\d+):\s*/g;
185689
+ const locations = [];
185690
+ let match;
185691
+ while ((match = locationPattern.exec(inner)) !== null) {
185692
+ const line = parseInt(match[1], 10);
185693
+ const colStart = parseInt(match[2], 10);
185694
+ const endLine = match[3] ? parseInt(match[3], 10) : line;
185695
+ const colEnd = parseInt(match[4], 10);
185696
+ locations.push({
185697
+ index: match.index,
185698
+ line,
185699
+ colStart,
185700
+ endLine,
185701
+ colEnd,
185702
+ matchEnd: match.index + match[0].length
185703
+ });
185704
+ }
185705
+ for (let i = 0; i < locations.length; i++) {
185706
+ const loc = locations[i];
185707
+ const nextStart = locations[i + 1]?.index ?? inner.length;
185708
+ const messageText = inner.slice(loc.matchEnd, nextStart).trim();
185709
+ const semicolonIdx = messageText.indexOf(";");
185710
+ let title;
185711
+ let description;
185712
+ if (semicolonIdx !== -1) {
185713
+ title = messageText.slice(0, semicolonIdx).trim();
185714
+ description = messageText.slice(semicolonIdx + 1).trim();
185715
+ } else {
185716
+ title = messageText;
185717
+ description = "";
185718
+ }
185719
+ errors.push({
185720
+ line: loc.line,
185721
+ colStart: loc.colStart,
185722
+ endLine: loc.endLine,
185723
+ colEnd: loc.colEnd,
185724
+ title,
185725
+ description
185726
+ });
185727
+ }
185728
+ return errors;
185729
+ }
185730
+
185731
+ // src/lib/format-config-error.ts
185732
+ var import_code_frame = __toESM(require_lib2(), 1);
185733
+ function formatConfigError(err, fileContents, filePath) {
185734
+ const raw = err instanceof Error ? err.message : String(err);
185735
+ const errors = parseHclErrors(raw);
185736
+ if (errors.length === 0) {
185737
+ return `Error: Invalid configuration: ${raw}`;
185738
+ }
185739
+ const name = filePath ?? "specific.hcl";
185740
+ const header = errors.length === 1 ? `Error in ${name}:` : `${errors.length} errors in ${name}:`;
185741
+ const blocks = errors.map((e) => {
185742
+ const frame = (0, import_code_frame.codeFrameColumns)(
185743
+ fileContents,
185744
+ {
185745
+ start: { line: e.line, column: e.colStart },
185746
+ end: { line: e.endLine, column: e.colEnd }
185747
+ },
185748
+ { highlightCode: false, message: e.description }
185749
+ );
185750
+ return ` ${e.title}
185751
+
185752
+ ${frame}`;
185753
+ });
185754
+ return `${header}
185755
+
185756
+ ${blocks.join("\n\n")}`;
185757
+ }
185758
+
185117
185759
  // src/lib/bin/types.ts
185118
185760
  var BinaryNotFoundError = class extends Error {
185119
185761
  constructor(binaryName, version, platformInfo) {
@@ -185457,6 +186099,25 @@ var reshapeBinary = {
185457
186099
  executables: ["reshape"]
185458
186100
  };
185459
186101
 
186102
+ // src/lib/bin/definitions/temporal.ts
186103
+ var temporalBinary = {
186104
+ name: "temporal",
186105
+ versions: ["1.3.0"],
186106
+ urlTemplate: "https://temporal.download/cli/archive/v{version}?platform={platform}&arch={arch}",
186107
+ platformMapping: {
186108
+ darwin: {
186109
+ arm64: { platform: "darwin", arch: "arm64" },
186110
+ x64: { platform: "darwin", arch: "amd64" }
186111
+ },
186112
+ linux: {
186113
+ arm64: { platform: "linux", arch: "arm64" },
186114
+ x64: { platform: "linux", arch: "amd64" }
186115
+ }
186116
+ },
186117
+ stripComponents: 0,
186118
+ executables: ["temporal"]
186119
+ };
186120
+
185460
186121
  // src/commands/check.tsx
185461
186122
  async function runReshapeCheck(migrationsDir) {
185462
186123
  try {
@@ -185488,9 +186149,21 @@ function CheckUI() {
185488
186149
  });
185489
186150
  return;
185490
186151
  }
186152
+ const hcl = fs13.readFileSync(configPath, "utf-8");
185491
186153
  try {
185492
- const hcl = fs13.readFileSync(configPath, "utf-8");
185493
186154
  const config2 = await parseConfig(hcl);
186155
+ for (const build of config2.builds) {
186156
+ if (build.dockerfile) {
186157
+ const dockerfilePath = path9.resolve(process.cwd(), build.dockerfile);
186158
+ if (!fs13.existsSync(dockerfilePath)) {
186159
+ setState({
186160
+ status: "error",
186161
+ error: `Build "${build.name}": Dockerfile not found at "${build.dockerfile}" (resolved to ${dockerfilePath})`
186162
+ });
186163
+ return;
186164
+ }
186165
+ }
186166
+ }
185494
186167
  const reshapeChecks2 = [];
185495
186168
  for (const pg of config2.postgres) {
185496
186169
  if (pg.reshape?.enabled) {
@@ -185522,7 +186195,7 @@ function CheckUI() {
185522
186195
  } catch (err) {
185523
186196
  setState({
185524
186197
  status: "error",
185525
- error: err instanceof Error ? err.message : String(err)
186198
+ error: formatConfigError(err, hcl, configPath)
185526
186199
  });
185527
186200
  }
185528
186201
  }
@@ -185532,7 +186205,7 @@ function CheckUI() {
185532
186205
  return /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { color: "blue" }, /* @__PURE__ */ React3.createElement(Spinner3, { type: "dots" })), /* @__PURE__ */ React3.createElement(Text3, null, " Checking configuration..."));
185533
186206
  }
185534
186207
  if (state.status === "error") {
185535
- return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { color: "red" }, "Error: ", state.error));
186208
+ return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { color: "red" }, state.error));
185536
186209
  }
185537
186210
  const { config } = state;
185538
186211
  if (!config) {
@@ -185541,7 +186214,7 @@ function CheckUI() {
185541
186214
  const reshapeChecks = state.reshapeChecks ?? [];
185542
186215
  const reshapeErrors = reshapeChecks.filter((r) => !r.success);
185543
186216
  const hasReshapeErrors = reshapeErrors.length > 0;
185544
- return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: hasReshapeErrors ? "yellow" : "green" }, hasReshapeErrors ? "Configuration is valid but reshape migrations have errors" : "Configuration is valid"), config.builds.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Builds (", config.builds.length, "):"), config.builds.map((b) => /* @__PURE__ */ React3.createElement(Text3, { key: b.name }, " ", "- ", b.name))), config.services.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Services (", config.services.length, "):"), config.services.map((s) => /* @__PURE__ */ React3.createElement(Text3, { key: s.name }, " ", "- ", s.name))), config.postgres.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Postgres (", config.postgres.length, "):"), config.postgres.map((p) => /* @__PURE__ */ React3.createElement(Text3, { key: p.name }, " ", "- ", p.name, p.reshape?.enabled ? " (reshape enabled)" : ""))), reshapeChecks.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Reshape Migrations:"), reshapeChecks.map((r) => /* @__PURE__ */ React3.createElement(Box3, { key: r.databaseName, flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, null, " ", /* @__PURE__ */ React3.createElement(Text3, { color: r.success ? "green" : "red" }, r.success ? "pass" : "fail"), " ", r.databaseName, " (", r.migrationsDir, ")"), r.error && /* @__PURE__ */ React3.createElement(Text3, { color: "red" }, " ", r.error)))), config.redis.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Redis (", config.redis.length, "):"), config.redis.map((r) => /* @__PURE__ */ React3.createElement(Text3, { key: r.name }, " ", "- ", r.name))), config.storage.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Storage (", config.storage.length, "):"), config.storage.map((s) => /* @__PURE__ */ React3.createElement(Text3, { key: s.name }, " ", "- ", s.name))), config.configs.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Config (", config.configs.length, "):"), config.configs.map((c) => /* @__PURE__ */ React3.createElement(Text3, { key: c.name }, " ", "- ", c.name, c.default ? ` (default: ${c.default})` : ""))), config.environments.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Environments (", config.environments.length, "):"), config.environments.map((e) => /* @__PURE__ */ React3.createElement(Text3, { key: e.name }, " ", "- ", e.name))));
186217
+ return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: hasReshapeErrors ? "yellow" : "green" }, hasReshapeErrors ? "Configuration is valid but reshape migrations have errors" : "Configuration is valid"), config.builds.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Builds (", config.builds.length, "):"), config.builds.map((b) => /* @__PURE__ */ React3.createElement(Text3, { key: b.name }, " ", "- ", b.name, b.base ? ` (${b.base})` : "", b.dockerfile ? ` (dockerfile: ${b.dockerfile})` : ""))), config.services.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Services (", config.services.length, "):"), config.services.map((s) => /* @__PURE__ */ React3.createElement(Text3, { key: s.name }, " ", "- ", s.name))), config.postgres.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Postgres (", config.postgres.length, "):"), config.postgres.map((p) => /* @__PURE__ */ React3.createElement(Text3, { key: p.name }, " ", "- ", p.name, p.reshape?.enabled ? " (reshape enabled)" : ""))), reshapeChecks.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Reshape Migrations:"), reshapeChecks.map((r) => /* @__PURE__ */ React3.createElement(Box3, { key: r.databaseName, flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, null, " ", /* @__PURE__ */ React3.createElement(Text3, { color: r.success ? "green" : "red" }, r.success ? "pass" : "fail"), " ", r.databaseName, " (", r.migrationsDir, ")"), r.error && /* @__PURE__ */ React3.createElement(Text3, { color: "red" }, " ", r.error)))), config.redis.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Redis (", config.redis.length, "):"), config.redis.map((r) => /* @__PURE__ */ React3.createElement(Text3, { key: r.name }, " ", "- ", r.name))), config.storage.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Storage (", config.storage.length, "):"), config.storage.map((s) => /* @__PURE__ */ React3.createElement(Text3, { key: s.name }, " ", "- ", s.name))), config.configs.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Config (", config.configs.length, "):"), config.configs.map((c) => /* @__PURE__ */ React3.createElement(Text3, { key: c.name }, " ", "- ", c.name, c.default ? ` (default: ${c.default})` : ""))), config.environments.length > 0 && /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true }, "Environments (", config.environments.length, "):"), config.environments.map((e) => /* @__PURE__ */ React3.createElement(Text3, { key: e.name }, " ", "- ", e.name))));
185545
186218
  }
185546
186219
  function checkCommand() {
185547
186220
  render3(/* @__PURE__ */ React3.createElement(CheckUI, null));
@@ -185551,8 +186224,8 @@ function checkCommand() {
185551
186224
  import React6, { useState as useState5, useEffect as useEffect3, useRef } from "react";
185552
186225
  import { render as render4, Text as Text6, Box as Box6, useApp as useApp2, Static } from "ink";
185553
186226
  import Spinner4 from "ink-spinner";
185554
- import * as fs22 from "fs";
185555
- import * as path19 from "path";
186227
+ import * as fs23 from "fs";
186228
+ import * as path20 from "path";
185556
186229
 
185557
186230
  // node_modules/.pnpm/chokidar@5.0.0/node_modules/chokidar/index.js
185558
186231
  import { EventEmitter } from "node:events";
@@ -185644,7 +186317,7 @@ var ReaddirpStream = class extends Readable {
185644
186317
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
185645
186318
  const statMethod = opts.lstat ? lstat : stat;
185646
186319
  if (wantBigintFsStats) {
185647
- this._stat = (path27) => statMethod(path27, { bigint: true });
186320
+ this._stat = (path28) => statMethod(path28, { bigint: true });
185648
186321
  } else {
185649
186322
  this._stat = statMethod;
185650
186323
  }
@@ -185669,8 +186342,8 @@ var ReaddirpStream = class extends Readable {
185669
186342
  const par = this.parent;
185670
186343
  const fil = par && par.files;
185671
186344
  if (fil && fil.length > 0) {
185672
- const { path: path27, depth } = par;
185673
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path27));
186345
+ const { path: path28, depth } = par;
186346
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path28));
185674
186347
  const awaited = await Promise.all(slice);
185675
186348
  for (const entry of awaited) {
185676
186349
  if (!entry)
@@ -185710,20 +186383,20 @@ var ReaddirpStream = class extends Readable {
185710
186383
  this.reading = false;
185711
186384
  }
185712
186385
  }
185713
- async _exploreDir(path27, depth) {
186386
+ async _exploreDir(path28, depth) {
185714
186387
  let files;
185715
186388
  try {
185716
- files = await readdir(path27, this._rdOptions);
186389
+ files = await readdir(path28, this._rdOptions);
185717
186390
  } catch (error) {
185718
186391
  this._onError(error);
185719
186392
  }
185720
- return { files, depth, path: path27 };
186393
+ return { files, depth, path: path28 };
185721
186394
  }
185722
- async _formatEntry(dirent, path27) {
186395
+ async _formatEntry(dirent, path28) {
185723
186396
  let entry;
185724
186397
  const basename6 = this._isDirent ? dirent.name : dirent;
185725
186398
  try {
185726
- const fullPath = presolve(pjoin(path27, basename6));
186399
+ const fullPath = presolve(pjoin(path28, basename6));
185727
186400
  entry = { path: prelative(this._root, fullPath), fullPath, basename: basename6 };
185728
186401
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
185729
186402
  } catch (err) {
@@ -186123,16 +186796,16 @@ var delFromSet = (main, prop, item) => {
186123
186796
  };
186124
186797
  var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
186125
186798
  var FsWatchInstances = /* @__PURE__ */ new Map();
186126
- function createFsWatchInstance(path27, options2, listener, errHandler, emitRaw) {
186799
+ function createFsWatchInstance(path28, options2, listener, errHandler, emitRaw) {
186127
186800
  const handleEvent = (rawEvent, evPath) => {
186128
- listener(path27);
186129
- emitRaw(rawEvent, evPath, { watchedPath: path27 });
186130
- if (evPath && path27 !== evPath) {
186131
- fsWatchBroadcast(sp.resolve(path27, evPath), KEY_LISTENERS, sp.join(path27, evPath));
186801
+ listener(path28);
186802
+ emitRaw(rawEvent, evPath, { watchedPath: path28 });
186803
+ if (evPath && path28 !== evPath) {
186804
+ fsWatchBroadcast(sp.resolve(path28, evPath), KEY_LISTENERS, sp.join(path28, evPath));
186132
186805
  }
186133
186806
  };
186134
186807
  try {
186135
- return fs_watch(path27, {
186808
+ return fs_watch(path28, {
186136
186809
  persistent: options2.persistent
186137
186810
  }, handleEvent);
186138
186811
  } catch (error) {
@@ -186148,12 +186821,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
186148
186821
  listener(val1, val2, val3);
186149
186822
  });
186150
186823
  };
186151
- var setFsWatchListener = (path27, fullPath, options2, handlers) => {
186824
+ var setFsWatchListener = (path28, fullPath, options2, handlers) => {
186152
186825
  const { listener, errHandler, rawEmitter } = handlers;
186153
186826
  let cont = FsWatchInstances.get(fullPath);
186154
186827
  let watcher;
186155
186828
  if (!options2.persistent) {
186156
- watcher = createFsWatchInstance(path27, options2, listener, errHandler, rawEmitter);
186829
+ watcher = createFsWatchInstance(path28, options2, listener, errHandler, rawEmitter);
186157
186830
  if (!watcher)
186158
186831
  return;
186159
186832
  return watcher.close.bind(watcher);
@@ -186164,7 +186837,7 @@ var setFsWatchListener = (path27, fullPath, options2, handlers) => {
186164
186837
  addAndConvert(cont, KEY_RAW, rawEmitter);
186165
186838
  } else {
186166
186839
  watcher = createFsWatchInstance(
186167
- path27,
186840
+ path28,
186168
186841
  options2,
186169
186842
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
186170
186843
  errHandler,
@@ -186179,7 +186852,7 @@ var setFsWatchListener = (path27, fullPath, options2, handlers) => {
186179
186852
  cont.watcherUnusable = true;
186180
186853
  if (isWindows && error.code === "EPERM") {
186181
186854
  try {
186182
- const fd = await open2(path27, "r");
186855
+ const fd = await open2(path28, "r");
186183
186856
  await fd.close();
186184
186857
  broadcastErr(error);
186185
186858
  } catch (err) {
@@ -186210,7 +186883,7 @@ var setFsWatchListener = (path27, fullPath, options2, handlers) => {
186210
186883
  };
186211
186884
  };
186212
186885
  var FsWatchFileInstances = /* @__PURE__ */ new Map();
186213
- var setFsWatchFileListener = (path27, fullPath, options2, handlers) => {
186886
+ var setFsWatchFileListener = (path28, fullPath, options2, handlers) => {
186214
186887
  const { listener, rawEmitter } = handlers;
186215
186888
  let cont = FsWatchFileInstances.get(fullPath);
186216
186889
  const copts = cont && cont.options;
@@ -186232,7 +186905,7 @@ var setFsWatchFileListener = (path27, fullPath, options2, handlers) => {
186232
186905
  });
186233
186906
  const currmtime = curr.mtimeMs;
186234
186907
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
186235
- foreach(cont.listeners, (listener2) => listener2(path27, curr));
186908
+ foreach(cont.listeners, (listener2) => listener2(path28, curr));
186236
186909
  }
186237
186910
  })
186238
186911
  };
@@ -186262,13 +186935,13 @@ var NodeFsHandler = class {
186262
186935
  * @param listener on fs change
186263
186936
  * @returns closer for the watcher instance
186264
186937
  */
186265
- _watchWithNodeFs(path27, listener) {
186938
+ _watchWithNodeFs(path28, listener) {
186266
186939
  const opts = this.fsw.options;
186267
- const directory = sp.dirname(path27);
186268
- const basename6 = sp.basename(path27);
186940
+ const directory = sp.dirname(path28);
186941
+ const basename6 = sp.basename(path28);
186269
186942
  const parent = this.fsw._getWatchedDir(directory);
186270
186943
  parent.add(basename6);
186271
- const absolutePath = sp.resolve(path27);
186944
+ const absolutePath = sp.resolve(path28);
186272
186945
  const options2 = {
186273
186946
  persistent: opts.persistent
186274
186947
  };
@@ -186278,12 +186951,12 @@ var NodeFsHandler = class {
186278
186951
  if (opts.usePolling) {
186279
186952
  const enableBin = opts.interval !== opts.binaryInterval;
186280
186953
  options2.interval = enableBin && isBinaryPath(basename6) ? opts.binaryInterval : opts.interval;
186281
- closer = setFsWatchFileListener(path27, absolutePath, options2, {
186954
+ closer = setFsWatchFileListener(path28, absolutePath, options2, {
186282
186955
  listener,
186283
186956
  rawEmitter: this.fsw._emitRaw
186284
186957
  });
186285
186958
  } else {
186286
- closer = setFsWatchListener(path27, absolutePath, options2, {
186959
+ closer = setFsWatchListener(path28, absolutePath, options2, {
186287
186960
  listener,
186288
186961
  errHandler: this._boundHandleError,
186289
186962
  rawEmitter: this.fsw._emitRaw
@@ -186299,13 +186972,13 @@ var NodeFsHandler = class {
186299
186972
  if (this.fsw.closed) {
186300
186973
  return;
186301
186974
  }
186302
- const dirname8 = sp.dirname(file);
186975
+ const dirname9 = sp.dirname(file);
186303
186976
  const basename6 = sp.basename(file);
186304
- const parent = this.fsw._getWatchedDir(dirname8);
186977
+ const parent = this.fsw._getWatchedDir(dirname9);
186305
186978
  let prevStats = stats;
186306
186979
  if (parent.has(basename6))
186307
186980
  return;
186308
- const listener = async (path27, newStats) => {
186981
+ const listener = async (path28, newStats) => {
186309
186982
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
186310
186983
  return;
186311
186984
  if (!newStats || newStats.mtimeMs === 0) {
@@ -186319,16 +186992,16 @@ var NodeFsHandler = class {
186319
186992
  this.fsw._emit(EV.CHANGE, file, newStats2);
186320
186993
  }
186321
186994
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
186322
- this.fsw._closeFile(path27);
186995
+ this.fsw._closeFile(path28);
186323
186996
  prevStats = newStats2;
186324
186997
  const closer2 = this._watchWithNodeFs(file, listener);
186325
186998
  if (closer2)
186326
- this.fsw._addPathCloser(path27, closer2);
186999
+ this.fsw._addPathCloser(path28, closer2);
186327
187000
  } else {
186328
187001
  prevStats = newStats2;
186329
187002
  }
186330
187003
  } catch (error) {
186331
- this.fsw._remove(dirname8, basename6);
187004
+ this.fsw._remove(dirname9, basename6);
186332
187005
  }
186333
187006
  } else if (parent.has(basename6)) {
186334
187007
  const at = newStats.atimeMs;
@@ -186355,7 +187028,7 @@ var NodeFsHandler = class {
186355
187028
  * @param item basename of this item
186356
187029
  * @returns true if no more processing is needed for this entry.
186357
187030
  */
186358
- async _handleSymlink(entry, directory, path27, item) {
187031
+ async _handleSymlink(entry, directory, path28, item) {
186359
187032
  if (this.fsw.closed) {
186360
187033
  return;
186361
187034
  }
@@ -186365,7 +187038,7 @@ var NodeFsHandler = class {
186365
187038
  this.fsw._incrReadyCount();
186366
187039
  let linkPath;
186367
187040
  try {
186368
- linkPath = await fsrealpath(path27);
187041
+ linkPath = await fsrealpath(path28);
186369
187042
  } catch (e) {
186370
187043
  this.fsw._emitReady();
186371
187044
  return true;
@@ -186375,12 +187048,12 @@ var NodeFsHandler = class {
186375
187048
  if (dir.has(item)) {
186376
187049
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
186377
187050
  this.fsw._symlinkPaths.set(full, linkPath);
186378
- this.fsw._emit(EV.CHANGE, path27, entry.stats);
187051
+ this.fsw._emit(EV.CHANGE, path28, entry.stats);
186379
187052
  }
186380
187053
  } else {
186381
187054
  dir.add(item);
186382
187055
  this.fsw._symlinkPaths.set(full, linkPath);
186383
- this.fsw._emit(EV.ADD, path27, entry.stats);
187056
+ this.fsw._emit(EV.ADD, path28, entry.stats);
186384
187057
  }
186385
187058
  this.fsw._emitReady();
186386
187059
  return true;
@@ -186410,9 +187083,9 @@ var NodeFsHandler = class {
186410
187083
  return;
186411
187084
  }
186412
187085
  const item = entry.path;
186413
- let path27 = sp.join(directory, item);
187086
+ let path28 = sp.join(directory, item);
186414
187087
  current.add(item);
186415
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path27, item)) {
187088
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path28, item)) {
186416
187089
  return;
186417
187090
  }
186418
187091
  if (this.fsw.closed) {
@@ -186421,8 +187094,8 @@ var NodeFsHandler = class {
186421
187094
  }
186422
187095
  if (item === target || !target && !previous.has(item)) {
186423
187096
  this.fsw._incrReadyCount();
186424
- path27 = sp.join(dir, sp.relative(dir, path27));
186425
- this._addToNodeFs(path27, initialAdd, wh, depth + 1);
187097
+ path28 = sp.join(dir, sp.relative(dir, path28));
187098
+ this._addToNodeFs(path28, initialAdd, wh, depth + 1);
186426
187099
  }
186427
187100
  }).on(EV.ERROR, this._boundHandleError);
186428
187101
  return new Promise((resolve10, reject) => {
@@ -186491,13 +187164,13 @@ var NodeFsHandler = class {
186491
187164
  * @param depth Child path actually targeted for watch
186492
187165
  * @param target Child path actually targeted for watch
186493
187166
  */
186494
- async _addToNodeFs(path27, initialAdd, priorWh, depth, target) {
187167
+ async _addToNodeFs(path28, initialAdd, priorWh, depth, target) {
186495
187168
  const ready = this.fsw._emitReady;
186496
- if (this.fsw._isIgnored(path27) || this.fsw.closed) {
187169
+ if (this.fsw._isIgnored(path28) || this.fsw.closed) {
186497
187170
  ready();
186498
187171
  return false;
186499
187172
  }
186500
- const wh = this.fsw._getWatchHelpers(path27);
187173
+ const wh = this.fsw._getWatchHelpers(path28);
186501
187174
  if (priorWh) {
186502
187175
  wh.filterPath = (entry) => priorWh.filterPath(entry);
186503
187176
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -186513,8 +187186,8 @@ var NodeFsHandler = class {
186513
187186
  const follow = this.fsw.options.followSymlinks;
186514
187187
  let closer;
186515
187188
  if (stats.isDirectory()) {
186516
- const absPath = sp.resolve(path27);
186517
- const targetPath = follow ? await fsrealpath(path27) : path27;
187189
+ const absPath = sp.resolve(path28);
187190
+ const targetPath = follow ? await fsrealpath(path28) : path28;
186518
187191
  if (this.fsw.closed)
186519
187192
  return;
186520
187193
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -186524,29 +187197,29 @@ var NodeFsHandler = class {
186524
187197
  this.fsw._symlinkPaths.set(absPath, targetPath);
186525
187198
  }
186526
187199
  } else if (stats.isSymbolicLink()) {
186527
- const targetPath = follow ? await fsrealpath(path27) : path27;
187200
+ const targetPath = follow ? await fsrealpath(path28) : path28;
186528
187201
  if (this.fsw.closed)
186529
187202
  return;
186530
187203
  const parent = sp.dirname(wh.watchPath);
186531
187204
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
186532
187205
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
186533
- closer = await this._handleDir(parent, stats, initialAdd, depth, path27, wh, targetPath);
187206
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path28, wh, targetPath);
186534
187207
  if (this.fsw.closed)
186535
187208
  return;
186536
187209
  if (targetPath !== void 0) {
186537
- this.fsw._symlinkPaths.set(sp.resolve(path27), targetPath);
187210
+ this.fsw._symlinkPaths.set(sp.resolve(path28), targetPath);
186538
187211
  }
186539
187212
  } else {
186540
187213
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
186541
187214
  }
186542
187215
  ready();
186543
187216
  if (closer)
186544
- this.fsw._addPathCloser(path27, closer);
187217
+ this.fsw._addPathCloser(path28, closer);
186545
187218
  return false;
186546
187219
  } catch (error) {
186547
187220
  if (this.fsw._handleError(error)) {
186548
187221
  ready();
186549
- return path27;
187222
+ return path28;
186550
187223
  }
186551
187224
  }
186552
187225
  }
@@ -186589,24 +187262,24 @@ function createPattern(matcher) {
186589
187262
  }
186590
187263
  return () => false;
186591
187264
  }
186592
- function normalizePath(path27) {
186593
- if (typeof path27 !== "string")
187265
+ function normalizePath(path28) {
187266
+ if (typeof path28 !== "string")
186594
187267
  throw new Error("string expected");
186595
- path27 = sp2.normalize(path27);
186596
- path27 = path27.replace(/\\/g, "/");
187268
+ path28 = sp2.normalize(path28);
187269
+ path28 = path28.replace(/\\/g, "/");
186597
187270
  let prepend = false;
186598
- if (path27.startsWith("//"))
187271
+ if (path28.startsWith("//"))
186599
187272
  prepend = true;
186600
- path27 = path27.replace(DOUBLE_SLASH_RE, "/");
187273
+ path28 = path28.replace(DOUBLE_SLASH_RE, "/");
186601
187274
  if (prepend)
186602
- path27 = "/" + path27;
186603
- return path27;
187275
+ path28 = "/" + path28;
187276
+ return path28;
186604
187277
  }
186605
187278
  function matchPatterns(patterns, testString, stats) {
186606
- const path27 = normalizePath(testString);
187279
+ const path28 = normalizePath(testString);
186607
187280
  for (let index = 0; index < patterns.length; index++) {
186608
187281
  const pattern = patterns[index];
186609
- if (pattern(path27, stats)) {
187282
+ if (pattern(path28, stats)) {
186610
187283
  return true;
186611
187284
  }
186612
187285
  }
@@ -186644,19 +187317,19 @@ var toUnix = (string) => {
186644
187317
  }
186645
187318
  return str;
186646
187319
  };
186647
- var normalizePathToUnix = (path27) => toUnix(sp2.normalize(toUnix(path27)));
186648
- var normalizeIgnored = (cwd = "") => (path27) => {
186649
- if (typeof path27 === "string") {
186650
- return normalizePathToUnix(sp2.isAbsolute(path27) ? path27 : sp2.join(cwd, path27));
187320
+ var normalizePathToUnix = (path28) => toUnix(sp2.normalize(toUnix(path28)));
187321
+ var normalizeIgnored = (cwd = "") => (path28) => {
187322
+ if (typeof path28 === "string") {
187323
+ return normalizePathToUnix(sp2.isAbsolute(path28) ? path28 : sp2.join(cwd, path28));
186651
187324
  } else {
186652
- return path27;
187325
+ return path28;
186653
187326
  }
186654
187327
  };
186655
- var getAbsolutePath = (path27, cwd) => {
186656
- if (sp2.isAbsolute(path27)) {
186657
- return path27;
187328
+ var getAbsolutePath = (path28, cwd) => {
187329
+ if (sp2.isAbsolute(path28)) {
187330
+ return path28;
186658
187331
  }
186659
- return sp2.join(cwd, path27);
187332
+ return sp2.join(cwd, path28);
186660
187333
  };
186661
187334
  var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
186662
187335
  var DirEntry = class {
@@ -186721,10 +187394,10 @@ var WatchHelper = class {
186721
187394
  dirParts;
186722
187395
  followSymlinks;
186723
187396
  statMethod;
186724
- constructor(path27, follow, fsw) {
187397
+ constructor(path28, follow, fsw) {
186725
187398
  this.fsw = fsw;
186726
- const watchPath = path27;
186727
- this.path = path27 = path27.replace(REPLACER_RE, "");
187399
+ const watchPath = path28;
187400
+ this.path = path28 = path28.replace(REPLACER_RE, "");
186728
187401
  this.watchPath = watchPath;
186729
187402
  this.fullWatchPath = sp2.resolve(watchPath);
186730
187403
  this.dirParts = [];
@@ -186864,20 +187537,20 @@ var FSWatcher = class extends EventEmitter {
186864
187537
  this._closePromise = void 0;
186865
187538
  let paths = unifyPaths(paths_);
186866
187539
  if (cwd) {
186867
- paths = paths.map((path27) => {
186868
- const absPath = getAbsolutePath(path27, cwd);
187540
+ paths = paths.map((path28) => {
187541
+ const absPath = getAbsolutePath(path28, cwd);
186869
187542
  return absPath;
186870
187543
  });
186871
187544
  }
186872
- paths.forEach((path27) => {
186873
- this._removeIgnoredPath(path27);
187545
+ paths.forEach((path28) => {
187546
+ this._removeIgnoredPath(path28);
186874
187547
  });
186875
187548
  this._userIgnored = void 0;
186876
187549
  if (!this._readyCount)
186877
187550
  this._readyCount = 0;
186878
187551
  this._readyCount += paths.length;
186879
- Promise.all(paths.map(async (path27) => {
186880
- const res = await this._nodeFsHandler._addToNodeFs(path27, !_internal, void 0, 0, _origAdd);
187552
+ Promise.all(paths.map(async (path28) => {
187553
+ const res = await this._nodeFsHandler._addToNodeFs(path28, !_internal, void 0, 0, _origAdd);
186881
187554
  if (res)
186882
187555
  this._emitReady();
186883
187556
  return res;
@@ -186899,17 +187572,17 @@ var FSWatcher = class extends EventEmitter {
186899
187572
  return this;
186900
187573
  const paths = unifyPaths(paths_);
186901
187574
  const { cwd } = this.options;
186902
- paths.forEach((path27) => {
186903
- if (!sp2.isAbsolute(path27) && !this._closers.has(path27)) {
187575
+ paths.forEach((path28) => {
187576
+ if (!sp2.isAbsolute(path28) && !this._closers.has(path28)) {
186904
187577
  if (cwd)
186905
- path27 = sp2.join(cwd, path27);
186906
- path27 = sp2.resolve(path27);
187578
+ path28 = sp2.join(cwd, path28);
187579
+ path28 = sp2.resolve(path28);
186907
187580
  }
186908
- this._closePath(path27);
186909
- this._addIgnoredPath(path27);
186910
- if (this._watched.has(path27)) {
187581
+ this._closePath(path28);
187582
+ this._addIgnoredPath(path28);
187583
+ if (this._watched.has(path28)) {
186911
187584
  this._addIgnoredPath({
186912
- path: path27,
187585
+ path: path28,
186913
187586
  recursive: true
186914
187587
  });
186915
187588
  }
@@ -186973,38 +187646,38 @@ var FSWatcher = class extends EventEmitter {
186973
187646
  * @param stats arguments to be passed with event
186974
187647
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
186975
187648
  */
186976
- async _emit(event, path27, stats) {
187649
+ async _emit(event, path28, stats) {
186977
187650
  if (this.closed)
186978
187651
  return;
186979
187652
  const opts = this.options;
186980
187653
  if (isWindows)
186981
- path27 = sp2.normalize(path27);
187654
+ path28 = sp2.normalize(path28);
186982
187655
  if (opts.cwd)
186983
- path27 = sp2.relative(opts.cwd, path27);
186984
- const args = [path27];
187656
+ path28 = sp2.relative(opts.cwd, path28);
187657
+ const args = [path28];
186985
187658
  if (stats != null)
186986
187659
  args.push(stats);
186987
187660
  const awf = opts.awaitWriteFinish;
186988
187661
  let pw;
186989
- if (awf && (pw = this._pendingWrites.get(path27))) {
187662
+ if (awf && (pw = this._pendingWrites.get(path28))) {
186990
187663
  pw.lastChange = /* @__PURE__ */ new Date();
186991
187664
  return this;
186992
187665
  }
186993
187666
  if (opts.atomic) {
186994
187667
  if (event === EVENTS.UNLINK) {
186995
- this._pendingUnlinks.set(path27, [event, ...args]);
187668
+ this._pendingUnlinks.set(path28, [event, ...args]);
186996
187669
  setTimeout(() => {
186997
- this._pendingUnlinks.forEach((entry, path28) => {
187670
+ this._pendingUnlinks.forEach((entry, path29) => {
186998
187671
  this.emit(...entry);
186999
187672
  this.emit(EVENTS.ALL, ...entry);
187000
- this._pendingUnlinks.delete(path28);
187673
+ this._pendingUnlinks.delete(path29);
187001
187674
  });
187002
187675
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
187003
187676
  return this;
187004
187677
  }
187005
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path27)) {
187678
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path28)) {
187006
187679
  event = EVENTS.CHANGE;
187007
- this._pendingUnlinks.delete(path27);
187680
+ this._pendingUnlinks.delete(path28);
187008
187681
  }
187009
187682
  }
187010
187683
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -187022,16 +187695,16 @@ var FSWatcher = class extends EventEmitter {
187022
187695
  this.emitWithAll(event, args);
187023
187696
  }
187024
187697
  };
187025
- this._awaitWriteFinish(path27, awf.stabilityThreshold, event, awfEmit);
187698
+ this._awaitWriteFinish(path28, awf.stabilityThreshold, event, awfEmit);
187026
187699
  return this;
187027
187700
  }
187028
187701
  if (event === EVENTS.CHANGE) {
187029
- const isThrottled = !this._throttle(EVENTS.CHANGE, path27, 50);
187702
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path28, 50);
187030
187703
  if (isThrottled)
187031
187704
  return this;
187032
187705
  }
187033
187706
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
187034
- const fullPath = opts.cwd ? sp2.join(opts.cwd, path27) : path27;
187707
+ const fullPath = opts.cwd ? sp2.join(opts.cwd, path28) : path28;
187035
187708
  let stats2;
187036
187709
  try {
187037
187710
  stats2 = await stat3(fullPath);
@@ -187062,23 +187735,23 @@ var FSWatcher = class extends EventEmitter {
187062
187735
  * @param timeout duration of time to suppress duplicate actions
187063
187736
  * @returns tracking object or false if action should be suppressed
187064
187737
  */
187065
- _throttle(actionType, path27, timeout) {
187738
+ _throttle(actionType, path28, timeout) {
187066
187739
  if (!this._throttled.has(actionType)) {
187067
187740
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
187068
187741
  }
187069
187742
  const action = this._throttled.get(actionType);
187070
187743
  if (!action)
187071
187744
  throw new Error("invalid throttle");
187072
- const actionPath = action.get(path27);
187745
+ const actionPath = action.get(path28);
187073
187746
  if (actionPath) {
187074
187747
  actionPath.count++;
187075
187748
  return false;
187076
187749
  }
187077
187750
  let timeoutObject;
187078
187751
  const clear = () => {
187079
- const item = action.get(path27);
187752
+ const item = action.get(path28);
187080
187753
  const count = item ? item.count : 0;
187081
- action.delete(path27);
187754
+ action.delete(path28);
187082
187755
  clearTimeout(timeoutObject);
187083
187756
  if (item)
187084
187757
  clearTimeout(item.timeoutObject);
@@ -187086,7 +187759,7 @@ var FSWatcher = class extends EventEmitter {
187086
187759
  };
187087
187760
  timeoutObject = setTimeout(clear, timeout);
187088
187761
  const thr = { timeoutObject, clear, count: 0 };
187089
- action.set(path27, thr);
187762
+ action.set(path28, thr);
187090
187763
  return thr;
187091
187764
  }
187092
187765
  _incrReadyCount() {
@@ -187100,44 +187773,44 @@ var FSWatcher = class extends EventEmitter {
187100
187773
  * @param event
187101
187774
  * @param awfEmit Callback to be called when ready for event to be emitted.
187102
187775
  */
187103
- _awaitWriteFinish(path27, threshold, event, awfEmit) {
187776
+ _awaitWriteFinish(path28, threshold, event, awfEmit) {
187104
187777
  const awf = this.options.awaitWriteFinish;
187105
187778
  if (typeof awf !== "object")
187106
187779
  return;
187107
187780
  const pollInterval = awf.pollInterval;
187108
187781
  let timeoutHandler;
187109
- let fullPath = path27;
187110
- if (this.options.cwd && !sp2.isAbsolute(path27)) {
187111
- fullPath = sp2.join(this.options.cwd, path27);
187782
+ let fullPath = path28;
187783
+ if (this.options.cwd && !sp2.isAbsolute(path28)) {
187784
+ fullPath = sp2.join(this.options.cwd, path28);
187112
187785
  }
187113
187786
  const now = /* @__PURE__ */ new Date();
187114
187787
  const writes = this._pendingWrites;
187115
187788
  function awaitWriteFinishFn(prevStat) {
187116
187789
  statcb(fullPath, (err, curStat) => {
187117
- if (err || !writes.has(path27)) {
187790
+ if (err || !writes.has(path28)) {
187118
187791
  if (err && err.code !== "ENOENT")
187119
187792
  awfEmit(err);
187120
187793
  return;
187121
187794
  }
187122
187795
  const now2 = Number(/* @__PURE__ */ new Date());
187123
187796
  if (prevStat && curStat.size !== prevStat.size) {
187124
- writes.get(path27).lastChange = now2;
187797
+ writes.get(path28).lastChange = now2;
187125
187798
  }
187126
- const pw = writes.get(path27);
187799
+ const pw = writes.get(path28);
187127
187800
  const df = now2 - pw.lastChange;
187128
187801
  if (df >= threshold) {
187129
- writes.delete(path27);
187802
+ writes.delete(path28);
187130
187803
  awfEmit(void 0, curStat);
187131
187804
  } else {
187132
187805
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
187133
187806
  }
187134
187807
  });
187135
187808
  }
187136
- if (!writes.has(path27)) {
187137
- writes.set(path27, {
187809
+ if (!writes.has(path28)) {
187810
+ writes.set(path28, {
187138
187811
  lastChange: now,
187139
187812
  cancelWait: () => {
187140
- writes.delete(path27);
187813
+ writes.delete(path28);
187141
187814
  clearTimeout(timeoutHandler);
187142
187815
  return event;
187143
187816
  }
@@ -187148,8 +187821,8 @@ var FSWatcher = class extends EventEmitter {
187148
187821
  /**
187149
187822
  * Determines whether user has asked to ignore this path.
187150
187823
  */
187151
- _isIgnored(path27, stats) {
187152
- if (this.options.atomic && DOT_RE.test(path27))
187824
+ _isIgnored(path28, stats) {
187825
+ if (this.options.atomic && DOT_RE.test(path28))
187153
187826
  return true;
187154
187827
  if (!this._userIgnored) {
187155
187828
  const { cwd } = this.options;
@@ -187159,17 +187832,17 @@ var FSWatcher = class extends EventEmitter {
187159
187832
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
187160
187833
  this._userIgnored = anymatch(list, void 0);
187161
187834
  }
187162
- return this._userIgnored(path27, stats);
187835
+ return this._userIgnored(path28, stats);
187163
187836
  }
187164
- _isntIgnored(path27, stat4) {
187165
- return !this._isIgnored(path27, stat4);
187837
+ _isntIgnored(path28, stat4) {
187838
+ return !this._isIgnored(path28, stat4);
187166
187839
  }
187167
187840
  /**
187168
187841
  * Provides a set of common helpers and properties relating to symlink handling.
187169
187842
  * @param path file or directory pattern being watched
187170
187843
  */
187171
- _getWatchHelpers(path27) {
187172
- return new WatchHelper(path27, this.options.followSymlinks, this);
187844
+ _getWatchHelpers(path28) {
187845
+ return new WatchHelper(path28, this.options.followSymlinks, this);
187173
187846
  }
187174
187847
  // Directory helpers
187175
187848
  // -----------------
@@ -187201,63 +187874,63 @@ var FSWatcher = class extends EventEmitter {
187201
187874
  * @param item base path of item/directory
187202
187875
  */
187203
187876
  _remove(directory, item, isDirectory) {
187204
- const path27 = sp2.join(directory, item);
187205
- const fullPath = sp2.resolve(path27);
187206
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path27) || this._watched.has(fullPath);
187207
- if (!this._throttle("remove", path27, 100))
187877
+ const path28 = sp2.join(directory, item);
187878
+ const fullPath = sp2.resolve(path28);
187879
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path28) || this._watched.has(fullPath);
187880
+ if (!this._throttle("remove", path28, 100))
187208
187881
  return;
187209
187882
  if (!isDirectory && this._watched.size === 1) {
187210
187883
  this.add(directory, item, true);
187211
187884
  }
187212
- const wp = this._getWatchedDir(path27);
187885
+ const wp = this._getWatchedDir(path28);
187213
187886
  const nestedDirectoryChildren = wp.getChildren();
187214
- nestedDirectoryChildren.forEach((nested) => this._remove(path27, nested));
187887
+ nestedDirectoryChildren.forEach((nested) => this._remove(path28, nested));
187215
187888
  const parent = this._getWatchedDir(directory);
187216
187889
  const wasTracked = parent.has(item);
187217
187890
  parent.remove(item);
187218
187891
  if (this._symlinkPaths.has(fullPath)) {
187219
187892
  this._symlinkPaths.delete(fullPath);
187220
187893
  }
187221
- let relPath = path27;
187894
+ let relPath = path28;
187222
187895
  if (this.options.cwd)
187223
- relPath = sp2.relative(this.options.cwd, path27);
187896
+ relPath = sp2.relative(this.options.cwd, path28);
187224
187897
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
187225
187898
  const event = this._pendingWrites.get(relPath).cancelWait();
187226
187899
  if (event === EVENTS.ADD)
187227
187900
  return;
187228
187901
  }
187229
- this._watched.delete(path27);
187902
+ this._watched.delete(path28);
187230
187903
  this._watched.delete(fullPath);
187231
187904
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
187232
- if (wasTracked && !this._isIgnored(path27))
187233
- this._emit(eventName, path27);
187234
- this._closePath(path27);
187905
+ if (wasTracked && !this._isIgnored(path28))
187906
+ this._emit(eventName, path28);
187907
+ this._closePath(path28);
187235
187908
  }
187236
187909
  /**
187237
187910
  * Closes all watchers for a path
187238
187911
  */
187239
- _closePath(path27) {
187240
- this._closeFile(path27);
187241
- const dir = sp2.dirname(path27);
187242
- this._getWatchedDir(dir).remove(sp2.basename(path27));
187912
+ _closePath(path28) {
187913
+ this._closeFile(path28);
187914
+ const dir = sp2.dirname(path28);
187915
+ this._getWatchedDir(dir).remove(sp2.basename(path28));
187243
187916
  }
187244
187917
  /**
187245
187918
  * Closes only file-specific watchers
187246
187919
  */
187247
- _closeFile(path27) {
187248
- const closers = this._closers.get(path27);
187920
+ _closeFile(path28) {
187921
+ const closers = this._closers.get(path28);
187249
187922
  if (!closers)
187250
187923
  return;
187251
187924
  closers.forEach((closer) => closer());
187252
- this._closers.delete(path27);
187925
+ this._closers.delete(path28);
187253
187926
  }
187254
- _addPathCloser(path27, closer) {
187927
+ _addPathCloser(path28, closer) {
187255
187928
  if (!closer)
187256
187929
  return;
187257
- let list = this._closers.get(path27);
187930
+ let list = this._closers.get(path28);
187258
187931
  if (!list) {
187259
187932
  list = [];
187260
- this._closers.set(path27, list);
187933
+ this._closers.set(path28, list);
187261
187934
  }
187262
187935
  list.push(closer);
187263
187936
  }
@@ -187738,7 +188411,7 @@ config {
187738
188411
  this.name = "MissingConfigError";
187739
188412
  }
187740
188413
  };
187741
- function resolveEnvValue(value, resources, secrets, configs, servicePort, serviceEndpoints, currentServicePorts, publicUrls) {
188414
+ function resolveEnvValue(value, resources, secrets, configs, servicePort, serviceEndpoints, currentServicePorts, publicUrls, volumePaths) {
187742
188415
  if (typeof value === "string") {
187743
188416
  return value;
187744
188417
  }
@@ -187753,7 +188426,8 @@ function resolveEnvValue(value, resources, secrets, configs, servicePort, servic
187753
188426
  servicePort,
187754
188427
  serviceEndpoints,
187755
188428
  currentServicePorts,
187756
- publicUrls
188429
+ publicUrls,
188430
+ volumePaths
187757
188431
  );
187758
188432
  }).join("");
187759
188433
  }
@@ -187900,6 +188574,22 @@ function resolveEnvValue(value, resources, secrets, configs, servicePort, servic
187900
188574
  throw new Error(`Unknown storage attribute: ${String(value.attribute)}`);
187901
188575
  }
187902
188576
  }
188577
+ case "temporal": {
188578
+ const temporal = resources.get(value.name);
188579
+ if (!temporal || temporal.type !== "temporal") {
188580
+ throw new Error(`Temporal "${value.name}" not found`);
188581
+ }
188582
+ switch (value.attribute) {
188583
+ case "url":
188584
+ return temporal.url;
188585
+ case "namespace":
188586
+ return value.name;
188587
+ case "api_key":
188588
+ return "";
188589
+ default:
188590
+ throw new Error(`Unknown temporal attribute: ${String(value.attribute)}`);
188591
+ }
188592
+ }
187903
188593
  case "config": {
187904
188594
  const configValue = configs.get(value.name);
187905
188595
  if (configValue === void 0) {
@@ -187914,13 +188604,24 @@ function resolveEnvValue(value, resources, secrets, configs, servicePort, servic
187914
188604
  }
187915
188605
  return secretValue;
187916
188606
  }
188607
+ case "volume": {
188608
+ const volumeRef = value;
188609
+ if (!volumePaths) {
188610
+ throw new Error("Volume reference used but no volume paths provided");
188611
+ }
188612
+ const volumePath = volumePaths.get(volumeRef.volumeName);
188613
+ if (volumePath === void 0) {
188614
+ throw new Error(`Volume "${volumeRef.volumeName}" not found`);
188615
+ }
188616
+ return volumePath;
188617
+ }
187917
188618
  case "build":
187918
188619
  throw new Error(`Build references cannot be used as env values`);
187919
188620
  default:
187920
188621
  throw new Error(`Unknown reference type`);
187921
188622
  }
187922
188623
  }
187923
- function resolveEnv(env2, resources, secrets, configs, servicePort, serviceEndpoints, currentServicePorts, publicUrls) {
188624
+ function resolveEnv(env2, resources, secrets, configs, servicePort, serviceEndpoints, currentServicePorts, publicUrls, volumePaths) {
187924
188625
  if (!env2) {
187925
188626
  return {};
187926
188627
  }
@@ -187934,7 +188635,8 @@ function resolveEnv(env2, resources, secrets, configs, servicePort, serviceEndpo
187934
188635
  servicePort,
187935
188636
  serviceEndpoints,
187936
188637
  currentServicePorts,
187937
- publicUrls
188638
+ publicUrls,
188639
+ volumePaths
187938
188640
  );
187939
188641
  }
187940
188642
  return resolved;
@@ -187949,12 +188651,12 @@ function resolveEnvForExec(env2, resources, secrets, configs) {
187949
188651
  resolved[key] = value;
187950
188652
  continue;
187951
188653
  }
187952
- if (value.type === "port" || value.type === "endpoint" || value.type === "service") {
188654
+ if (value.type === "port" || value.type === "endpoint" || value.type === "service" || value.type === "volume") {
187953
188655
  continue;
187954
188656
  }
187955
188657
  if (value.type === "interpolated") {
187956
188658
  const hasSkippableRef = value.parts.some(
187957
- (part) => part.type === "ref" && (part.ref.type === "port" || part.ref.type === "endpoint" || part.ref.type === "service")
188659
+ (part) => part.type === "ref" && (part.ref.type === "port" || part.ref.type === "endpoint" || part.ref.type === "service" || part.ref.type === "volume")
187958
188660
  );
187959
188661
  if (hasSkippableRef) {
187960
188662
  continue;
@@ -187968,7 +188670,7 @@ function resolveEnvForExec(env2, resources, secrets, configs) {
187968
188670
  }
187969
188671
 
187970
188672
  // src/lib/dev/service-runner.ts
187971
- function startService(service, resources, secrets, configs, endpointPorts, serviceEndpoints, onLog, publicUrls, cwd) {
188673
+ function startService(service, resources, secrets, configs, endpointPorts, serviceEndpoints, onLog, publicUrls, cwd, volumePaths) {
187972
188674
  const command = service.dev?.command ?? service.command;
187973
188675
  if (!command) {
187974
188676
  throw new Error(`Service "${service.name}" has no command`);
@@ -187986,7 +188688,8 @@ function startService(service, resources, secrets, configs, endpointPorts, servi
187986
188688
  defaultPort,
187987
188689
  serviceEndpoints,
187988
188690
  endpointPorts,
187989
- publicUrls
188691
+ publicUrls,
188692
+ volumePaths
187990
188693
  );
187991
188694
  const child = spawn2(command, {
187992
188695
  shell: true,
@@ -188277,6 +188980,7 @@ var HTTPS_PORT = 443;
188277
188980
  var DOMAIN_SUFFIX = ".local.spcf.app";
188278
188981
  var ADMIN_DOMAIN = "local.spcf.app";
188279
188982
  var DRIZZLE_GATEWAY_PREFIX = "__drizzle_gateway";
188983
+ var TEMPORAL_UI_PREFIX = "__temporal";
188280
188984
  var MIME_TYPES = {
188281
188985
  ".html": "text/html",
188282
188986
  ".css": "text/css",
@@ -188295,6 +188999,7 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
188295
188999
  const serviceMap = /* @__PURE__ */ new Map();
188296
189000
  const adminPortMap = /* @__PURE__ */ new Map();
188297
189001
  const drizzleGatewayPortMap = /* @__PURE__ */ new Map();
189002
+ const temporalUiPortMap = /* @__PURE__ */ new Map();
188298
189003
  const buildMapKey = (serviceName, key) => {
188299
189004
  return key === "default" ? serviceName : `${serviceName}.${key}`;
188300
189005
  };
@@ -188305,6 +189010,7 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
188305
189010
  serviceMap.clear();
188306
189011
  adminPortMap.clear();
188307
189012
  drizzleGatewayPortMap.clear();
189013
+ temporalUiPortMap.clear();
188308
189014
  for (const svc of registryServices) {
188309
189015
  serviceMap.set(buildMapKey(svc.serviceName, svc.key), svc.port);
188310
189016
  }
@@ -188313,6 +189019,9 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
188313
189019
  if (registration.drizzleGatewayPort !== void 0) {
188314
189020
  drizzleGatewayPortMap.set(key, registration.drizzleGatewayPort);
188315
189021
  }
189022
+ if (registration.temporalUiPort !== void 0) {
189023
+ temporalUiPortMap.set(key, registration.temporalUiPort);
189024
+ }
188316
189025
  }
188317
189026
  writeLog("proxy", `Updated service map: ${serviceMap.size} services, ${adminPortMap.size} admin instances, ${drizzleGatewayPortMap.size} drizzle gateways`);
188318
189027
  };
@@ -188326,9 +189035,32 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
188326
189035
  res.end(`<h1>Bad Gateway</h1><p>Service unavailable: ${err.message}</p>`);
188327
189036
  }
188328
189037
  });
189038
+ proxy.on("proxyRes", (proxyRes, req) => {
189039
+ const host = req.headers?.host || "";
189040
+ if (extractTemporalUiKey(host) !== null || extractDrizzleGatewayKey(host) !== null) {
189041
+ delete proxyRes.headers["x-frame-options"];
189042
+ const csp = proxyRes.headers["content-security-policy"];
189043
+ if (typeof csp === "string" && csp.includes("frame-ancestors")) {
189044
+ proxyRes.headers["content-security-policy"] = csp.split(";").filter((d) => !d.trim().startsWith("frame-ancestors")).join(";");
189045
+ }
189046
+ }
189047
+ });
188329
189048
  const handleRequest = (req, res) => {
188330
189049
  const host = req.headers.host || "";
188331
189050
  const hostname2 = host.split(":")[0];
189051
+ const temporalKey = extractTemporalUiKey(host);
189052
+ if (temporalKey !== null) {
189053
+ const temporalPort = temporalUiPortMap.get(temporalKey);
189054
+ if (temporalPort) {
189055
+ proxy.web(req, res, {
189056
+ target: `http://127.0.0.1:${temporalPort}`
189057
+ });
189058
+ return;
189059
+ }
189060
+ res.writeHead(503, { "Content-Type": "text/html" });
189061
+ res.end("<h1>Workflow Engine</h1><p>No workflow engine running for this instance.</p>");
189062
+ return;
189063
+ }
188332
189064
  const drizzleKey = extractDrizzleGatewayKey(host);
188333
189065
  if (drizzleKey !== null) {
188334
189066
  const drizzlePort = drizzleGatewayPortMap.get(drizzleKey);
@@ -188373,6 +189105,26 @@ async function startHttpProxy(services, certificate, getState, instanceKey = "de
188373
189105
  };
188374
189106
  const handleUpgrade = (req, socket, head) => {
188375
189107
  const host = req.headers.host || "";
189108
+ const temporalKey = extractTemporalUiKey(host);
189109
+ if (temporalKey !== null) {
189110
+ const temporalPort = temporalUiPortMap.get(temporalKey);
189111
+ if (temporalPort) {
189112
+ proxy.ws(req, socket, head, { target: `http://127.0.0.1:${temporalPort}` });
189113
+ return;
189114
+ }
189115
+ socket.end("HTTP/1.1 404 Not Found\r\n\r\n");
189116
+ return;
189117
+ }
189118
+ const drizzleKey = extractDrizzleGatewayKey(host);
189119
+ if (drizzleKey !== null) {
189120
+ const drizzlePort = drizzleGatewayPortMap.get(drizzleKey);
189121
+ if (drizzlePort) {
189122
+ proxy.ws(req, socket, head, { target: `http://127.0.0.1:${drizzlePort}` });
189123
+ return;
189124
+ }
189125
+ socket.end("HTTP/1.1 404 Not Found\r\n\r\n");
189126
+ return;
189127
+ }
188376
189128
  const adminKey = extractAdminKey(host);
188377
189129
  if (adminKey !== null) {
188378
189130
  if (adminPortMap.has(adminKey)) {
@@ -188508,6 +189260,23 @@ function extractDrizzleGatewayKey(host) {
188508
189260
  }
188509
189261
  return null;
188510
189262
  }
189263
+ function extractTemporalUiKey(host) {
189264
+ const hostname2 = host.split(":")[0];
189265
+ if (!hostname2 || !hostname2.endsWith(DOMAIN_SUFFIX)) {
189266
+ return null;
189267
+ }
189268
+ const prefix = hostname2.slice(0, -DOMAIN_SUFFIX.length);
189269
+ if (!prefix) {
189270
+ return null;
189271
+ }
189272
+ const parts = prefix.split(".");
189273
+ if (parts.length === 1 && parts[0] === TEMPORAL_UI_PREFIX) {
189274
+ return "default";
189275
+ } else if (parts.length === 2 && parts[0] === TEMPORAL_UI_PREFIX && parts[1]) {
189276
+ return parts[1];
189277
+ }
189278
+ return null;
189279
+ }
188511
189280
  function extractAdminKey(host) {
188512
189281
  const hostname2 = host.split(":")[0];
188513
189282
  if (!hostname2) {
@@ -189266,9 +190035,110 @@ function createReshapeWatcher(options2) {
189266
190035
  };
189267
190036
  }
189268
190037
 
190038
+ // src/lib/dev/temporal-manager.ts
190039
+ import * as fs20 from "fs";
190040
+ import * as path17 from "path";
190041
+ import * as net4 from "net";
190042
+ import { spawn as spawn5 } from "child_process";
190043
+ async function startTemporalDevServer(temporals, grpcPort, uiPort, dataDir, onProgress) {
190044
+ const binary = await ensureBinary(temporalBinary, void 0, onProgress);
190045
+ const dbPath = path17.join(process.cwd(), dataDir, "temporal.db");
190046
+ const dbDir = path17.dirname(dbPath);
190047
+ if (!fs20.existsSync(dbDir)) {
190048
+ fs20.mkdirSync(dbDir, { recursive: true });
190049
+ }
190050
+ const host = "127.0.0.1";
190051
+ const namespaceArgs = temporals.flatMap((t) => ["--namespace", t.name]);
190052
+ const proc = spawn5(
190053
+ binary.executables["temporal"],
190054
+ [
190055
+ "server",
190056
+ "start-dev",
190057
+ "--port",
190058
+ String(grpcPort),
190059
+ "--ui-port",
190060
+ String(uiPort),
190061
+ "--db-filename",
190062
+ dbPath,
190063
+ ...namespaceArgs,
190064
+ "--log-format",
190065
+ "pretty"
190066
+ ],
190067
+ {
190068
+ stdio: ["ignore", "pipe", "pipe"]
190069
+ }
190070
+ );
190071
+ pipeProcess("temporal", proc);
190072
+ await waitForTcpPort4(host, grpcPort);
190073
+ const stopServer = () => stopProcess4(proc);
190074
+ const instances = temporals.map((temporal, i) => ({
190075
+ name: temporal.name,
190076
+ type: "temporal",
190077
+ port: grpcPort,
190078
+ host,
190079
+ user: "",
190080
+ password: "",
190081
+ dbName: temporal.name,
190082
+ url: `${host}:${grpcPort}`,
190083
+ uiPort,
190084
+ // Only the first instance owns the server lifecycle
190085
+ stop: i === 0 ? stopServer : async () => {
190086
+ }
190087
+ }));
190088
+ return instances;
190089
+ }
190090
+ async function waitForTcpPort4(host, port, timeoutMs = 3e4) {
190091
+ const startTime = Date.now();
190092
+ while (Date.now() - startTime < timeoutMs) {
190093
+ const isOpen = await checkTcpPort4(host, port);
190094
+ if (isOpen) {
190095
+ return;
190096
+ }
190097
+ await new Promise((resolve10) => setTimeout(resolve10, 100));
190098
+ }
190099
+ throw new Error(`Temporal port ${port} did not become available within timeout`);
190100
+ }
190101
+ function checkTcpPort4(host, port) {
190102
+ return new Promise((resolve10) => {
190103
+ const socket = new net4.Socket();
190104
+ socket.setTimeout(1e3);
190105
+ socket.on("connect", () => {
190106
+ socket.destroy();
190107
+ resolve10(true);
190108
+ });
190109
+ socket.on("timeout", () => {
190110
+ socket.destroy();
190111
+ resolve10(false);
190112
+ });
190113
+ socket.on("error", () => {
190114
+ socket.destroy();
190115
+ resolve10(false);
190116
+ });
190117
+ socket.connect(port, host);
190118
+ });
190119
+ }
190120
+ async function stopProcess4(proc) {
190121
+ return new Promise((resolve10) => {
190122
+ if (proc.killed || proc.exitCode !== null) {
190123
+ resolve10();
190124
+ return;
190125
+ }
190126
+ proc.once("exit", () => {
190127
+ clearTimeout(forceKillTimeout);
190128
+ resolve10();
190129
+ });
190130
+ proc.kill("SIGTERM");
190131
+ const forceKillTimeout = setTimeout(() => {
190132
+ if (!proc.killed && proc.exitCode === null) {
190133
+ proc.kill("SIGKILL");
190134
+ }
190135
+ }, 2e3);
190136
+ });
190137
+ }
190138
+
189269
190139
  // src/lib/dev/resource-starter.ts
189270
190140
  function findRequiredResources(service) {
189271
- const required = { postgres: [], redis: [], storage: [] };
190141
+ const required = { postgres: [], redis: [], storage: [], temporal: [] };
189272
190142
  if (service.env) {
189273
190143
  for (const value of Object.values(service.env)) {
189274
190144
  if (typeof value !== "object" || value === null) continue;
@@ -189280,6 +190150,8 @@ function findRequiredResources(service) {
189280
190150
  required.redis.push(ref.name);
189281
190151
  } else if (ref.type === "storage" && !required.storage.includes(ref.name)) {
189282
190152
  required.storage.push(ref.name);
190153
+ } else if (ref.type === "temporal" && !required.temporal.includes(ref.name)) {
190154
+ required.temporal.push(ref.name);
189283
190155
  }
189284
190156
  }
189285
190157
  }
@@ -189306,14 +190178,17 @@ async function startResources(options2) {
189306
190178
  let postgresConfigs;
189307
190179
  let redisConfigs;
189308
190180
  let storageConfigs;
190181
+ let temporalConfigs;
189309
190182
  if (selection.mode === "all") {
189310
190183
  postgresConfigs = config.postgres;
189311
190184
  redisConfigs = config.redis;
189312
190185
  storageConfigs = config.storage;
190186
+ temporalConfigs = config.temporal;
189313
190187
  } else {
189314
190188
  postgresConfigs = config.postgres.filter((p) => selection.postgres.includes(p.name));
189315
190189
  redisConfigs = config.redis.filter((r) => selection.redis.includes(r.name));
189316
190190
  storageConfigs = config.storage.filter((s) => selection.storage.includes(s.name));
190191
+ temporalConfigs = config.temporal.filter((t) => selection.temporal.includes(t.name));
189317
190192
  }
189318
190193
  for (const pg of postgresConfigs) {
189319
190194
  if (signal?.cancelled) {
@@ -189399,6 +190274,25 @@ async function startResources(options2) {
189399
190274
  if (instance.secretKey) dbState.secretKey = instance.secretKey;
189400
190275
  await stateManager.registerDatabase(storage.name, dbState);
189401
190276
  }
190277
+ if (temporalConfigs.length > 0) {
190278
+ if (signal?.cancelled) {
190279
+ return { resources, electric, startedResources, startedElectric, cancelled: true };
190280
+ }
190281
+ const grpcPort = portAllocator.allocate("temporal-grpc");
190282
+ const uiPort = portAllocator.allocate("temporal-ui");
190283
+ const names = temporalConfigs.map((t) => t.name).join(", ");
190284
+ log(`Starting temporal dev server on port ${grpcPort} (UI: ${uiPort}) with namespaces: ${names}`);
190285
+ callbacks.onResourceStarting?.(temporalConfigs[0].name, "temporal");
190286
+ const instances = await startTemporalDevServer(temporalConfigs, grpcPort, uiPort, dataDir, (progress) => {
190287
+ callbacks.onResourceProgress?.(temporalConfigs[0].name, progress);
190288
+ });
190289
+ for (const instance of instances) {
190290
+ resources.set(instance.name, instance);
190291
+ startedResources.push(instance);
190292
+ callbacks.onResourceReady?.(instance.name, instance);
190293
+ log(`Temporal namespace "${instance.name}" ready`);
190294
+ }
190295
+ }
189402
190296
  if (shouldStartElectric) {
189403
190297
  const syncDatabases = detectSyncDatabases(config);
189404
190298
  for (const pgName of syncDatabases) {
@@ -189449,24 +190343,24 @@ function watchConfigFile(configPath, debounceMs, onChange) {
189449
190343
  }
189450
190344
 
189451
190345
  // src/lib/dev/subdomain-generator.ts
189452
- import * as fs20 from "fs";
189453
- import * as path17 from "path";
190346
+ import * as fs21 from "fs";
190347
+ import * as path18 from "path";
189454
190348
  import { generateSlug } from "random-word-slugs";
189455
190349
  var StableSubdomainAllocator = class {
189456
190350
  tunnelsDir;
189457
190351
  tunnelsFilePath;
189458
190352
  baseSlug = null;
189459
190353
  constructor(projectRoot, key = "default") {
189460
- this.tunnelsDir = path17.join(projectRoot, ".specific", "keys", key);
189461
- this.tunnelsFilePath = path17.join(this.tunnelsDir, "tunnels.json");
190354
+ this.tunnelsDir = path18.join(projectRoot, ".specific", "keys", key);
190355
+ this.tunnelsFilePath = path18.join(this.tunnelsDir, "tunnels.json");
189462
190356
  this.loadTunnels();
189463
190357
  }
189464
190358
  loadTunnels() {
189465
- if (!fs20.existsSync(this.tunnelsFilePath)) {
190359
+ if (!fs21.existsSync(this.tunnelsFilePath)) {
189466
190360
  return;
189467
190361
  }
189468
190362
  try {
189469
- const content = fs20.readFileSync(this.tunnelsFilePath, "utf-8");
190363
+ const content = fs21.readFileSync(this.tunnelsFilePath, "utf-8");
189470
190364
  const data = JSON.parse(content);
189471
190365
  if (data.version === 1 && data.baseSlug) {
189472
190366
  this.baseSlug = data.baseSlug;
@@ -189476,14 +190370,14 @@ var StableSubdomainAllocator = class {
189476
190370
  }
189477
190371
  }
189478
190372
  saveTunnels() {
189479
- if (!fs20.existsSync(this.tunnelsDir)) {
189480
- fs20.mkdirSync(this.tunnelsDir, { recursive: true });
190373
+ if (!fs21.existsSync(this.tunnelsDir)) {
190374
+ fs21.mkdirSync(this.tunnelsDir, { recursive: true });
189481
190375
  }
189482
190376
  const data = {
189483
190377
  version: 1,
189484
190378
  baseSlug: this.baseSlug
189485
190379
  };
189486
- fs20.writeFileSync(this.tunnelsFilePath, JSON.stringify(data, null, 2));
190380
+ fs21.writeFileSync(this.tunnelsFilePath, JSON.stringify(data, null, 2));
189487
190381
  }
189488
190382
  generateBaseSlug() {
189489
190383
  return generateSlug(2, {
@@ -189520,7 +190414,7 @@ var StableSubdomainAllocator = class {
189520
190414
 
189521
190415
  // node_modules/.pnpm/@specific+tunnel-client@file+..+tunnel+client/node_modules/@specific/tunnel-client/dist/index.js
189522
190416
  import { EventEmitter as EventEmitter2 } from "node:events";
189523
- import * as net4 from "node:net";
190417
+ import * as net5 from "node:net";
189524
190418
  var DEFAULT_HOST = "https://tunnel.spcf.app";
189525
190419
  var RECONNECT_DELAYS = [1e3, 2e3, 4e3, 8e3, 15e3];
189526
190420
  async function register(baseUrl, subdomain) {
@@ -189562,7 +190456,7 @@ var TunnelClientImpl = class extends EventEmitter2 {
189562
190456
  }
189563
190457
  }
189564
190458
  addPoolConnection() {
189565
- const remote = net4.connect({ host: this.tunnelHost, port: this.info.port });
190459
+ const remote = net5.connect({ host: this.tunnelHost, port: this.info.port });
189566
190460
  remote.setKeepAlive(true, 3e4);
189567
190461
  this.pool.add(remote);
189568
190462
  remote.once("data", (firstChunk) => {
@@ -189577,7 +190471,7 @@ var TunnelClientImpl = class extends EventEmitter2 {
189577
190471
  remote.on("close", () => this.onIdleClose(remote, errored));
189578
190472
  }
189579
190473
  pipeToLocal(remote, firstChunk) {
189580
- const local = net4.connect({ host: "127.0.0.1", port: this.localPort }, () => {
190474
+ const local = net5.connect({ host: "127.0.0.1", port: this.localPort }, () => {
189581
190475
  local.write(firstChunk);
189582
190476
  remote.pipe(local);
189583
190477
  local.pipe(remote);
@@ -189639,10 +190533,10 @@ async function startTunnel(serviceName, endpointName, port, subdomain, callbacks
189639
190533
  }
189640
190534
 
189641
190535
  // src/lib/dev/proxy-registry.ts
189642
- import * as fs21 from "fs";
189643
- import * as path18 from "path";
190536
+ import * as fs22 from "fs";
190537
+ import * as path19 from "path";
189644
190538
  import * as os8 from "os";
189645
- import * as net5 from "net";
190539
+ import * as net6 from "net";
189646
190540
  var ProxyRegistryManager = class {
189647
190541
  proxyDir;
189648
190542
  ownerPath;
@@ -189651,14 +190545,14 @@ var ProxyRegistryManager = class {
189651
190545
  isOwner = false;
189652
190546
  registryWatcher = null;
189653
190547
  constructor() {
189654
- this.proxyDir = path18.join(os8.homedir(), ".specific", "proxy");
189655
- this.ownerPath = path18.join(this.proxyDir, "owner.json");
189656
- this.registryPath = path18.join(this.proxyDir, "registry.json");
189657
- this.lockPath = path18.join(this.proxyDir, "registry.lock");
190548
+ this.proxyDir = path19.join(os8.homedir(), ".specific", "proxy");
190549
+ this.ownerPath = path19.join(this.proxyDir, "owner.json");
190550
+ this.registryPath = path19.join(this.proxyDir, "registry.json");
190551
+ this.lockPath = path19.join(this.proxyDir, "registry.lock");
189658
190552
  }
189659
190553
  ensureProxyDir() {
189660
- if (!fs21.existsSync(this.proxyDir)) {
189661
- fs21.mkdirSync(this.proxyDir, { recursive: true });
190554
+ if (!fs22.existsSync(this.proxyDir)) {
190555
+ fs22.mkdirSync(this.proxyDir, { recursive: true });
189662
190556
  }
189663
190557
  }
189664
190558
  isProcessRunning(pid) {
@@ -189676,7 +190570,7 @@ var ProxyRegistryManager = class {
189676
190570
  */
189677
190571
  isProxyListening(port, timeoutMs = 1e3) {
189678
190572
  return new Promise((resolve10) => {
189679
- const socket = new net5.Socket();
190573
+ const socket = new net6.Socket();
189680
190574
  let resolved = false;
189681
190575
  const cleanup = () => {
189682
190576
  if (!resolved) {
@@ -189715,15 +190609,15 @@ var ProxyRegistryManager = class {
189715
190609
  const startTime = Date.now();
189716
190610
  while (Date.now() - startTime < timeoutMs) {
189717
190611
  try {
189718
- const fd = fs21.openSync(
190612
+ const fd = fs22.openSync(
189719
190613
  this.lockPath,
189720
- fs21.constants.O_CREAT | fs21.constants.O_EXCL | fs21.constants.O_WRONLY
190614
+ fs22.constants.O_CREAT | fs22.constants.O_EXCL | fs22.constants.O_WRONLY
189721
190615
  );
189722
- fs21.writeSync(fd, String(process.pid));
189723
- fs21.closeSync(fd);
190616
+ fs22.writeSync(fd, String(process.pid));
190617
+ fs22.closeSync(fd);
189724
190618
  return () => {
189725
190619
  try {
189726
- fs21.unlinkSync(this.lockPath);
190620
+ fs22.unlinkSync(this.lockPath);
189727
190621
  } catch {
189728
190622
  }
189729
190623
  };
@@ -189732,16 +190626,16 @@ var ProxyRegistryManager = class {
189732
190626
  if (err.code === "EEXIST") {
189733
190627
  try {
189734
190628
  const lockPid = parseInt(
189735
- fs21.readFileSync(this.lockPath, "utf-8").trim(),
190629
+ fs22.readFileSync(this.lockPath, "utf-8").trim(),
189736
190630
  10
189737
190631
  );
189738
190632
  if (!this.isProcessRunning(lockPid)) {
189739
- fs21.unlinkSync(this.lockPath);
190633
+ fs22.unlinkSync(this.lockPath);
189740
190634
  continue;
189741
190635
  }
189742
190636
  } catch {
189743
190637
  try {
189744
- fs21.unlinkSync(this.lockPath);
190638
+ fs22.unlinkSync(this.lockPath);
189745
190639
  } catch {
189746
190640
  }
189747
190641
  continue;
@@ -189761,8 +190655,8 @@ var ProxyRegistryManager = class {
189761
190655
  async claimProxyOwnership(key) {
189762
190656
  const releaseLock = await this.acquireLock();
189763
190657
  try {
189764
- if (fs21.existsSync(this.ownerPath)) {
189765
- const content = fs21.readFileSync(this.ownerPath, "utf-8");
190658
+ if (fs22.existsSync(this.ownerPath)) {
190659
+ const content = fs22.readFileSync(this.ownerPath, "utf-8");
189766
190660
  const ownerFile2 = JSON.parse(content);
189767
190661
  if (await this.isProxyOwnerHealthy(ownerFile2.owner.pid)) {
189768
190662
  return false;
@@ -189792,11 +190686,11 @@ var ProxyRegistryManager = class {
189792
190686
  }
189793
190687
  const releaseLock = await this.acquireLock();
189794
190688
  try {
189795
- if (fs21.existsSync(this.ownerPath)) {
189796
- const content = fs21.readFileSync(this.ownerPath, "utf-8");
190689
+ if (fs22.existsSync(this.ownerPath)) {
190690
+ const content = fs22.readFileSync(this.ownerPath, "utf-8");
189797
190691
  const ownerFile = JSON.parse(content);
189798
190692
  if (ownerFile.owner.pid === process.pid) {
189799
- fs21.unlinkSync(this.ownerPath);
190693
+ fs22.unlinkSync(this.ownerPath);
189800
190694
  }
189801
190695
  }
189802
190696
  this.isOwner = false;
@@ -189808,12 +190702,12 @@ var ProxyRegistryManager = class {
189808
190702
  * Get the current proxy owner.
189809
190703
  */
189810
190704
  async getProxyOwner() {
189811
- if (!fs21.existsSync(this.ownerPath)) {
190705
+ if (!fs22.existsSync(this.ownerPath)) {
189812
190706
  return null;
189813
190707
  }
189814
190708
  const releaseLock = await this.acquireLock();
189815
190709
  try {
189816
- const content = fs21.readFileSync(this.ownerPath, "utf-8");
190710
+ const content = fs22.readFileSync(this.ownerPath, "utf-8");
189817
190711
  const ownerFile = JSON.parse(content);
189818
190712
  if (!await this.isProxyOwnerHealthy(ownerFile.owner.pid)) {
189819
190713
  return null;
@@ -189834,7 +190728,7 @@ var ProxyRegistryManager = class {
189834
190728
  /**
189835
190729
  * Register services for a key.
189836
190730
  */
189837
- async registerServices(key, adminPort, services, drizzleGatewayPort) {
190731
+ async registerServices(key, adminPort, services, drizzleGatewayPort, temporalUiPort) {
189838
190732
  const releaseLock = await this.acquireLock();
189839
190733
  try {
189840
190734
  const registry = this.readRegistry();
@@ -189845,6 +190739,9 @@ var ProxyRegistryManager = class {
189845
190739
  if (drizzleGatewayPort !== void 0) {
189846
190740
  registration.drizzleGatewayPort = drizzleGatewayPort;
189847
190741
  }
190742
+ if (temporalUiPort !== void 0) {
190743
+ registration.temporalUiPort = temporalUiPort;
190744
+ }
189848
190745
  registry.keys[key] = registration;
189849
190746
  registry.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
189850
190747
  this.writeFileAtomic(this.registryPath, registry);
@@ -189907,7 +190804,7 @@ var ProxyRegistryManager = class {
189907
190804
  */
189908
190805
  watchRegistry(onChange) {
189909
190806
  this.ensureProxyDir();
189910
- if (!fs21.existsSync(this.registryPath)) {
190807
+ if (!fs22.existsSync(this.registryPath)) {
189911
190808
  const emptyRegistry = {
189912
190809
  version: 1,
189913
190810
  keys: {},
@@ -189950,13 +190847,13 @@ var ProxyRegistryManager = class {
189950
190847
  async attemptElection(key) {
189951
190848
  const releaseLock = await this.acquireLock();
189952
190849
  try {
189953
- if (fs21.existsSync(this.ownerPath)) {
189954
- const content = fs21.readFileSync(this.ownerPath, "utf-8");
190850
+ if (fs22.existsSync(this.ownerPath)) {
190851
+ const content = fs22.readFileSync(this.ownerPath, "utf-8");
189955
190852
  const ownerFile2 = JSON.parse(content);
189956
190853
  if (await this.isProxyOwnerHealthy(ownerFile2.owner.pid)) {
189957
190854
  return false;
189958
190855
  }
189959
- fs21.unlinkSync(this.ownerPath);
190856
+ fs22.unlinkSync(this.ownerPath);
189960
190857
  }
189961
190858
  const ownerFile = {
189962
190859
  version: 1,
@@ -189974,7 +190871,7 @@ var ProxyRegistryManager = class {
189974
190871
  }
189975
190872
  }
189976
190873
  readRegistry() {
189977
- if (!fs21.existsSync(this.registryPath)) {
190874
+ if (!fs22.existsSync(this.registryPath)) {
189978
190875
  return {
189979
190876
  version: 1,
189980
190877
  keys: {},
@@ -189982,7 +190879,7 @@ var ProxyRegistryManager = class {
189982
190879
  };
189983
190880
  }
189984
190881
  try {
189985
- const content = fs21.readFileSync(this.registryPath, "utf-8");
190882
+ const content = fs22.readFileSync(this.registryPath, "utf-8");
189986
190883
  return JSON.parse(content);
189987
190884
  } catch {
189988
190885
  return {
@@ -189995,8 +190892,8 @@ var ProxyRegistryManager = class {
189995
190892
  writeFileAtomic(filePath, data) {
189996
190893
  this.ensureProxyDir();
189997
190894
  const tmpPath = filePath + ".tmp";
189998
- fs21.writeFileSync(tmpPath, JSON.stringify(data, null, 2));
189999
- fs21.renameSync(tmpPath, filePath);
190895
+ fs22.writeFileSync(tmpPath, JSON.stringify(data, null, 2));
190896
+ fs22.renameSync(tmpPath, filePath);
190000
190897
  }
190001
190898
  };
190002
190899
 
@@ -190309,16 +191206,16 @@ function DevUI({ instanceKey, tunnelEnabled }) {
190309
191206
  }, [state.status]);
190310
191207
  useEffect3(() => {
190311
191208
  if (state.status !== "running") return;
190312
- const configPath = path19.join(process.cwd(), "specific.hcl");
191209
+ const configPath = path20.join(process.cwd(), "specific.hcl");
190313
191210
  const watcher = watchConfigFile(configPath, 1e3, () => {
190314
191211
  try {
190315
- const hcl = fs22.readFileSync(configPath, "utf-8");
191212
+ const hcl = fs23.readFileSync(configPath, "utf-8");
190316
191213
  parseConfig(hcl).then(() => {
190317
191214
  triggerReload();
190318
191215
  }).catch((err) => {
190319
191216
  setState((s) => ({
190320
191217
  ...s,
190321
- parseError: `Config error: ${err instanceof Error ? err.message : String(err)}`
191218
+ parseError: formatConfigError(err, hcl, configPath)
190322
191219
  }));
190323
191220
  });
190324
191221
  } catch (err) {
@@ -190437,8 +191334,8 @@ function DevUI({ instanceKey, tunnelEnabled }) {
190437
191334
  }));
190438
191335
  return;
190439
191336
  }
190440
- const configPath = path19.join(process.cwd(), "specific.hcl");
190441
- if (!fs22.existsSync(configPath)) {
191337
+ const configPath = path20.join(process.cwd(), "specific.hcl");
191338
+ if (!fs23.existsSync(configPath)) {
190442
191339
  writeLog("system", "Waiting for specific.hcl to appear");
190443
191340
  setState((s) => ({
190444
191341
  ...s,
@@ -190456,14 +191353,14 @@ function DevUI({ instanceKey, tunnelEnabled }) {
190456
191353
  return;
190457
191354
  }
190458
191355
  let config2;
191356
+ const hcl = fs23.readFileSync(configPath, "utf-8");
190459
191357
  try {
190460
- const hcl = fs22.readFileSync(configPath, "utf-8");
190461
191358
  config2 = await parseConfig(hcl);
190462
191359
  } catch (err) {
190463
191360
  setState((s) => ({
190464
191361
  ...s,
190465
191362
  status: "error",
190466
- error: err instanceof Error ? err.message : String(err)
191363
+ error: formatConfigError(err, hcl, configPath)
190467
191364
  }));
190468
191365
  return;
190469
191366
  }
@@ -190482,6 +191379,10 @@ function DevUI({ instanceKey, tunnelEnabled }) {
190482
191379
  colorMap.set(`res:${storage.name}`, COLORS[colorIndex % COLORS.length]);
190483
191380
  colorIndex++;
190484
191381
  }
191382
+ for (const temporal of config2.temporal) {
191383
+ colorMap.set(`res:${temporal.name}`, COLORS[colorIndex % COLORS.length]);
191384
+ colorIndex++;
191385
+ }
190485
191386
  for (const service of config2.services) {
190486
191387
  colorMap.set(
190487
191388
  `svc:${service.name}`,
@@ -190563,7 +191464,7 @@ function DevUI({ instanceKey, tunnelEnabled }) {
190563
191464
  const drizzleGateway = await startDrizzleGateway(
190564
191465
  postgresResources,
190565
191466
  drizzlePort,
190566
- path19.join(process.cwd(), ".specific", "keys", instanceKey)
191467
+ path20.join(process.cwd(), ".specific", "keys", instanceKey)
190567
191468
  );
190568
191469
  startedDrizzleGateway = drizzleGateway;
190569
191470
  drizzleGatewayRef.current = drizzleGateway;
@@ -190583,7 +191484,7 @@ function DevUI({ instanceKey, tunnelEnabled }) {
190583
191484
  if (pg.reshape?.enabled) {
190584
191485
  const resource = resources2.get(pg.name);
190585
191486
  if (!resource) continue;
190586
- const migrationsDir = path19.resolve(
191487
+ const migrationsDir = path20.resolve(
190587
191488
  process.cwd(),
190588
191489
  pg.reshape.migrations_dir ?? "migrations"
190589
191490
  );
@@ -190751,10 +191652,10 @@ Add them to the config block in specific.local`);
190751
191652
  }
190752
191653
  const services2 = [];
190753
191654
  function resolveServiceCwd(service) {
190754
- if (service.root) return path19.resolve(process.cwd(), service.root);
191655
+ if (service.root) return path20.resolve(process.cwd(), service.root);
190755
191656
  if (service.build) {
190756
191657
  const build = config2.builds.find((b) => b.name === service.build.name);
190757
- if (build?.root) return path19.resolve(process.cwd(), build.root);
191658
+ if (build?.root) return path20.resolve(process.cwd(), build.root);
190758
191659
  }
190759
191660
  return process.cwd();
190760
191661
  }
@@ -190773,6 +191674,14 @@ Add them to the config block in specific.local`);
190773
191674
  "system",
190774
191675
  `Starting service "${service.name}"${portsList ? ` on port${endpointPorts.size > 1 ? "s" : ""} ${portsList}` : ""}`
190775
191676
  );
191677
+ const volumePaths = /* @__PURE__ */ new Map();
191678
+ if (service.volumes) {
191679
+ for (const vol of service.volumes) {
191680
+ const volumeDir = path20.resolve(`.specific/keys/${instanceKey}/data/volumes/${service.name}/${vol.name}`);
191681
+ fs23.mkdirSync(volumeDir, { recursive: true });
191682
+ volumePaths.set(vol.name, volumeDir);
191683
+ }
191684
+ }
190776
191685
  const running = startService(
190777
191686
  service,
190778
191687
  resources2,
@@ -190782,7 +191691,8 @@ Add them to the config block in specific.local`);
190782
191691
  serviceEndpoints,
190783
191692
  (line) => addLog(line, colorMap),
190784
191693
  publicUrls,
190785
- resolveServiceCwd(service)
191694
+ resolveServiceCwd(service),
191695
+ volumePaths
190786
191696
  );
190787
191697
  services2.push(running);
190788
191698
  startedServices.push(running);
@@ -190820,6 +191730,14 @@ Add them to the config block in specific.local`);
190820
191730
  if (!service.command && !service.dev?.command) continue;
190821
191731
  try {
190822
191732
  const endpointPorts = serviceEndpointPorts.get(service.name) || /* @__PURE__ */ new Map();
191733
+ const volumePaths = /* @__PURE__ */ new Map();
191734
+ if (service.volumes) {
191735
+ for (const vol of service.volumes) {
191736
+ const volumeDir = path20.resolve(`.specific/keys/${instanceKey}/data/volumes/${service.name}/${vol.name}`);
191737
+ fs23.mkdirSync(volumeDir, { recursive: true });
191738
+ volumePaths.set(vol.name, volumeDir);
191739
+ }
191740
+ }
190823
191741
  const running = startService(
190824
191742
  service,
190825
191743
  resources2,
@@ -190829,7 +191747,8 @@ Add them to the config block in specific.local`);
190829
191747
  serviceEndpoints,
190830
191748
  (line) => addLog(line, colorMap),
190831
191749
  void 0,
190832
- resolveServiceCwd(service)
191750
+ resolveServiceCwd(service),
191751
+ volumePaths
190833
191752
  );
190834
191753
  newServices.push(running);
190835
191754
  } catch (err) {
@@ -190916,6 +191835,7 @@ Add them to the config block in specific.local`);
190916
191835
  runningServicePorts.set(s.name, s.ports.get("default"));
190917
191836
  }
190918
191837
  const projectId = hasProjectId() ? readProjectId() : void 0;
191838
+ const hasTemporal = config2.temporal.length > 0;
190919
191839
  const getState = () => ({
190920
191840
  status: "running",
190921
191841
  services: config2.services.filter((svc) => runningServicePorts.has(svc.name) || svc.serve).map((svc) => ({
@@ -190931,16 +191851,20 @@ Add them to the config block in specific.local`);
190931
191851
  host: r.host,
190932
191852
  syncEnabled: r.type === "postgres" && syncDatabases.has(name)
190933
191853
  })),
190934
- projectId
191854
+ projectId,
191855
+ hasTemporal
190935
191856
  });
190936
191857
  const adminServer = await startAdminServer(getState);
190937
191858
  adminServerRef.current = adminServer;
190938
191859
  writeLog("system", `Admin API server started on port ${adminServer.port}`);
191860
+ const temporalInstance = [...resources2.values()].find((r) => r.type === "temporal");
191861
+ const temporalUiPort = temporalInstance?.uiPort;
190939
191862
  await proxyRegistry.registerServices(
190940
191863
  instanceKey,
190941
191864
  adminServer.port,
190942
191865
  serviceInfos,
190943
- startedDrizzleGateway?.port
191866
+ startedDrizzleGateway?.port,
191867
+ temporalUiPort
190944
191868
  );
190945
191869
  writeLog("system", `Registered ${serviceInfos.length} services with proxy registry`);
190946
191870
  const becameProxyOwner = await proxyRegistry.claimProxyOwnership(instanceKey);
@@ -191137,7 +192061,7 @@ Add them to the config block in specific.local`);
191137
192061
  return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Text6, null, /* @__PURE__ */ React6.createElement(Text6, { color: "yellow" }, /* @__PURE__ */ React6.createElement(Spinner4, { type: "dots" })), /* @__PURE__ */ React6.createElement(Text6, null, " No specific.hcl in project yet. Go build something with your coding agent!")));
191138
192062
  }
191139
192063
  if (state.status === "error") {
191140
- return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Text6, { color: "red" }, "Error: ", state.error));
192064
+ return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Text6, { color: "red" }, state.error));
191141
192065
  }
191142
192066
  if (state.status === "stopping") {
191143
192067
  return /* @__PURE__ */ React6.createElement(Box6, null, /* @__PURE__ */ React6.createElement(Text6, { color: "yellow" }, /* @__PURE__ */ React6.createElement(Spinner4, { type: "dots" })), /* @__PURE__ */ React6.createElement(Text6, null, " Shutting down..."));
@@ -191150,7 +192074,7 @@ Add them to the config block in specific.local`);
191150
192074
  return /* @__PURE__ */ React6.createElement(Box6, null, /* @__PURE__ */ React6.createElement(Text6, { color: "blue" }, /* @__PURE__ */ React6.createElement(Spinner4, { type: "dots" })));
191151
192075
  }
191152
192076
  if (state.status === "starting") {
191153
- return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Text6, null, /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: "cyan" }, "Specific dev server"), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " (Ctrl+C to stop)")), /* @__PURE__ */ React6.createElement(Text6, null, " "), (config.postgres.length > 0 || config.redis.length > 0 || config.storage.length > 0) && /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { bold: true }, "Resources:"), config.postgres.map((pg) => {
192077
+ return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Text6, null, /* @__PURE__ */ React6.createElement(Text6, { bold: true, color: "cyan" }, "Specific dev server"), /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, " (Ctrl+C to stop)")), /* @__PURE__ */ React6.createElement(Text6, null, " "), (config.postgres.length > 0 || config.redis.length > 0 || config.storage.length > 0 || config.temporal.length > 0) && /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { bold: true }, "Resources:"), config.postgres.map((pg) => {
191154
192078
  const instance = resources.get(pg.name);
191155
192079
  const resStatus = state.resourceStatus.get(pg.name);
191156
192080
  const isReady = !!instance;
@@ -191188,6 +192112,22 @@ Add them to the config block in specific.local`);
191188
192112
  const isReady = !!instance;
191189
192113
  const statusText = resStatus?.status === "starting" ? " starting..." : "";
191190
192114
  return /* @__PURE__ */ React6.createElement(Text6, { key: storage.name }, /* @__PURE__ */ React6.createElement(Text6, { color: isReady ? "green" : "gray" }, " \u25CF "), /* @__PURE__ */ React6.createElement(Text6, null, storage.name, " (storage)"), instance && /* @__PURE__ */ React6.createElement(Text6, null, " \u2192 localhost:", instance.port), !isReady && statusText && /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, statusText));
192115
+ }), config.temporal.map((temporal) => {
192116
+ const instance = resources.get(temporal.name);
192117
+ const resStatus = state.resourceStatus.get(temporal.name);
192118
+ const isReady = !!instance;
192119
+ let statusText = "";
192120
+ if (resStatus?.status === "downloading") {
192121
+ const progress = resStatus.downloadProgress;
192122
+ if (progress?.percent !== void 0) {
192123
+ statusText = ` downloading ${progress.percent}%`;
192124
+ } else {
192125
+ statusText = " downloading...";
192126
+ }
192127
+ } else if (resStatus?.status === "starting") {
192128
+ statusText = " starting...";
192129
+ }
192130
+ return /* @__PURE__ */ React6.createElement(Text6, { key: temporal.name }, /* @__PURE__ */ React6.createElement(Text6, { color: isReady ? "green" : "gray" }, " \u25CF "), /* @__PURE__ */ React6.createElement(Text6, null, temporal.name, " (temporal)"), instance && /* @__PURE__ */ React6.createElement(Text6, null, " \u2192 localhost:", instance.port), !isReady && statusText && /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, statusText));
191191
192131
  }), /* @__PURE__ */ React6.createElement(Text6, null, " ")), config.services.length > 0 && /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Text6, { bold: true }, "Services:"), config.services.map((svc) => {
191192
192132
  const running = services.find((s) => s.name === svc.name);
191193
192133
  const isReady = !!running;
@@ -191284,11 +192224,22 @@ Add them to the config block in specific.local`);
191284
192224
  }),
191285
192225
  { key: "storage-space", content: /* @__PURE__ */ React6.createElement(Text6, null, " ") }
191286
192226
  ] : [],
192227
+ ...config.temporal.length > 0 ? [
192228
+ { key: "temporal-header", content: /* @__PURE__ */ React6.createElement(Text6, { bold: true }, "Temporal:") },
192229
+ ...config.temporal.map((temporal) => {
192230
+ const instance = resources.get(temporal.name);
192231
+ return {
192232
+ key: `temporal-${temporal.name}`,
192233
+ content: /* @__PURE__ */ React6.createElement(Text6, null, /* @__PURE__ */ React6.createElement(Text6, { color: "green" }, " \u25CF "), /* @__PURE__ */ React6.createElement(Text6, null, temporal.name), instance && /* @__PURE__ */ React6.createElement(Text6, null, " \u2192 localhost:", instance.port))
192234
+ };
192235
+ }),
192236
+ { key: "temporal-space", content: /* @__PURE__ */ React6.createElement(Text6, null, " ") }
192237
+ ] : [],
191287
192238
  { key: "separator", content: /* @__PURE__ */ React6.createElement(Text6, { dimColor: true }, "\u2500".repeat(50)) },
191288
192239
  ...state.parseError ? [
191289
192240
  {
191290
192241
  key: "parse-error",
191291
- content: /* @__PURE__ */ React6.createElement(Text6, { color: "red" }, "Warning: ", state.parseError)
192242
+ content: /* @__PURE__ */ React6.createElement(Text6, { color: "red" }, state.parseError)
191292
192243
  }
191293
192244
  ] : [],
191294
192245
  ...output.map((line, i) => ({
@@ -191304,7 +192255,7 @@ function devCommand(instanceKey, tunnelEnabled = false) {
191304
192255
 
191305
192256
  // src/lib/dev/git-worktree.ts
191306
192257
  import { execSync as execSync3 } from "child_process";
191307
- import * as path20 from "path";
192258
+ import * as path21 from "path";
191308
192259
  function isInWorktree() {
191309
192260
  try {
191310
192261
  const commonDir = execSync3("git rev-parse --git-common-dir", {
@@ -191315,8 +192266,8 @@ function isInWorktree() {
191315
192266
  encoding: "utf-8",
191316
192267
  stdio: ["pipe", "pipe", "pipe"]
191317
192268
  }).trim();
191318
- const resolvedCommonDir = path20.resolve(commonDir);
191319
- const resolvedGitDir = path20.resolve(gitDir);
192269
+ const resolvedCommonDir = path21.resolve(commonDir);
192270
+ const resolvedGitDir = path21.resolve(gitDir);
191320
192271
  return resolvedCommonDir !== resolvedGitDir;
191321
192272
  } catch {
191322
192273
  return false;
@@ -191331,7 +192282,7 @@ function getWorktreeName() {
191331
192282
  encoding: "utf-8",
191332
192283
  stdio: ["pipe", "pipe", "pipe"]
191333
192284
  }).trim();
191334
- return path20.basename(gitDir);
192285
+ return path21.basename(gitDir);
191335
192286
  } catch {
191336
192287
  return null;
191337
192288
  }
@@ -191346,36 +192297,37 @@ init_open();
191346
192297
  import React7, { useState as useState6, useEffect as useEffect4, useCallback } from "react";
191347
192298
  import { render as render5, Text as Text7, Box as Box7, useApp as useApp3, useInput as useInput5 } from "ink";
191348
192299
  import Spinner5 from "ink-spinner";
191349
- import * as fs24 from "fs";
191350
- import * as path22 from "path";
192300
+ import * as fs25 from "fs";
192301
+ import * as path23 from "path";
191351
192302
 
191352
192303
  // src/lib/deploy/build-tester.ts
191353
- import { spawn as spawn5 } from "child_process";
191354
- import { existsSync as existsSync21 } from "fs";
191355
- import { join as join22, resolve as resolve7 } from "path";
192304
+ import { spawn as spawn6 } from "child_process";
192305
+ import { existsSync as existsSync22 } from "fs";
192306
+ import { join as join23, resolve as resolve7 } from "path";
191356
192307
  function getDependencyInstallCommand(build, projectDir) {
192308
+ if (!build.base) return null;
191357
192309
  switch (build.base) {
191358
192310
  case "node":
191359
- if (existsSync21(join22(projectDir, "pnpm-lock.yaml"))) {
192311
+ if (existsSync22(join23(projectDir, "pnpm-lock.yaml"))) {
191360
192312
  return "pnpm install --frozen-lockfile";
191361
- } else if (existsSync21(join22(projectDir, "yarn.lock"))) {
192313
+ } else if (existsSync22(join23(projectDir, "yarn.lock"))) {
191362
192314
  return "yarn install --frozen-lockfile";
191363
- } else if (existsSync21(join22(projectDir, "package-lock.json"))) {
192315
+ } else if (existsSync22(join23(projectDir, "package-lock.json"))) {
191364
192316
  return "npm ci";
191365
- } else if (existsSync21(join22(projectDir, "package.json"))) {
192317
+ } else if (existsSync22(join23(projectDir, "package.json"))) {
191366
192318
  return "npm install";
191367
192319
  }
191368
192320
  return null;
191369
192321
  case "python":
191370
- if (existsSync21(join22(projectDir, "poetry.lock"))) {
192322
+ if (existsSync22(join23(projectDir, "poetry.lock"))) {
191371
192323
  return "poetry install --no-interaction";
191372
- } else if (existsSync21(join22(projectDir, "Pipfile.lock"))) {
192324
+ } else if (existsSync22(join23(projectDir, "Pipfile.lock"))) {
191373
192325
  return "pipenv install --deploy";
191374
- } else if (existsSync21(join22(projectDir, "Pipfile"))) {
192326
+ } else if (existsSync22(join23(projectDir, "Pipfile"))) {
191375
192327
  return "pipenv install";
191376
- } else if (existsSync21(join22(projectDir, "pyproject.toml"))) {
192328
+ } else if (existsSync22(join23(projectDir, "pyproject.toml"))) {
191377
192329
  return "pip install .";
191378
- } else if (existsSync21(join22(projectDir, "requirements.txt"))) {
192330
+ } else if (existsSync22(join23(projectDir, "requirements.txt"))) {
191379
192331
  return "pip install -r requirements.txt";
191380
192332
  }
191381
192333
  return null;
@@ -191393,7 +192345,7 @@ function runCommand2(command, projectDir, buildName) {
191393
192345
  const stdout = [];
191394
192346
  const stderr = [];
191395
192347
  writeLog("build-test", `[${buildName}] Running: ${command}`);
191396
- const child = spawn5(command, {
192348
+ const child = spawn6(command, {
191397
192349
  shell: true,
191398
192350
  cwd: projectDir,
191399
192351
  env: { ...process.env },
@@ -191441,6 +192393,15 @@ function runCommand2(command, projectDir, buildName) {
191441
192393
  }
191442
192394
  async function testBuild(build, projectDir) {
191443
192395
  const startTime = Date.now();
192396
+ if (build.dockerfile) {
192397
+ writeLog("build-test", `Skipping test for build "${build.name}" (custom Dockerfile)`);
192398
+ return {
192399
+ buildName: build.name,
192400
+ success: true,
192401
+ output: "Skipped: custom Dockerfile build",
192402
+ durationMs: Date.now() - startTime
192403
+ };
192404
+ }
191444
192405
  const outputs = [];
191445
192406
  const workDir = build.root ? resolve7(projectDir, build.root) : projectDir;
191446
192407
  writeLog("build-test", `Starting test for build "${build.name}" (base: ${build.base}, workDir: ${workDir})`);
@@ -191521,8 +192482,8 @@ async function testAllBuilds(builds, projectDir) {
191521
192482
 
191522
192483
  // src/lib/tarball/create.ts
191523
192484
  import { execSync as execSync4 } from "child_process";
191524
- import * as fs23 from "fs";
191525
- import * as path21 from "path";
192485
+ import * as fs24 from "fs";
192486
+ import * as path22 from "path";
191526
192487
  import { createTarPacker, createEntryItemGenerator } from "tar-vern";
191527
192488
  function isInsideGitRepository(dir) {
191528
192489
  try {
@@ -191579,10 +192540,10 @@ var EXCLUDED_DIRS = [
191579
192540
  ];
191580
192541
  async function collectPaths(baseDir, currentDir, exclude) {
191581
192542
  const results = [];
191582
- const entries = await fs23.promises.readdir(currentDir, { withFileTypes: true });
192543
+ const entries = await fs24.promises.readdir(currentDir, { withFileTypes: true });
191583
192544
  for (const entry of entries) {
191584
- const fullPath = path21.join(currentDir, entry.name);
191585
- const relativePath = path21.relative(baseDir, fullPath);
192545
+ const fullPath = path22.join(currentDir, entry.name);
192546
+ const relativePath = path22.relative(baseDir, fullPath);
191586
192547
  if (entry.isDirectory()) {
191587
192548
  if (!exclude.includes(entry.name)) {
191588
192549
  results.push(relativePath);
@@ -191597,8 +192558,8 @@ async function collectPaths(baseDir, currentDir, exclude) {
191597
192558
  }
191598
192559
  async function createTarArchive(projectDir) {
191599
192560
  writeLog("tarball", "Creating tarball using tar-vern (non-git project)");
191600
- const configPath = path21.join(projectDir, "specific.hcl");
191601
- if (!fs23.existsSync(configPath)) {
192561
+ const configPath = path22.join(projectDir, "specific.hcl");
192562
+ if (!fs24.existsSync(configPath)) {
191602
192563
  throw new Error("specific.hcl not found in project directory");
191603
192564
  }
191604
192565
  const relativePaths = await collectPaths(projectDir, projectDir, EXCLUDED_DIRS);
@@ -191615,8 +192576,8 @@ async function createTarArchive(projectDir) {
191615
192576
  }
191616
192577
  function findWidestContext(projectDir, contexts) {
191617
192578
  if (contexts.length === 0) return ".";
191618
- const absolute = contexts.map((c) => path21.resolve(projectDir, c));
191619
- const segments = absolute.map((p) => p.split(path21.sep).filter(Boolean));
192579
+ const absolute = contexts.map((c) => path22.resolve(projectDir, c));
192580
+ const segments = absolute.map((p) => p.split(path22.sep).filter(Boolean));
191620
192581
  const firstSegments = segments[0];
191621
192582
  if (!firstSegments) return ".";
191622
192583
  const minLen = Math.min(...segments.map((s) => s.length));
@@ -191630,12 +192591,12 @@ function findWidestContext(projectDir, contexts) {
191630
192591
  }
191631
192592
  }
191632
192593
  const ancestorSegments = firstSegments.slice(0, commonLength);
191633
- const ancestor = path21.sep + ancestorSegments.join(path21.sep);
191634
- return path21.relative(projectDir, ancestor) || ".";
192594
+ const ancestor = path22.sep + ancestorSegments.join(path22.sep);
192595
+ return path22.relative(projectDir, ancestor) || ".";
191635
192596
  }
191636
192597
  async function createProjectTarball(projectDir, context = ".") {
191637
- const contextDir = path21.resolve(projectDir, context);
191638
- const appPath = path21.relative(contextDir, projectDir) || ".";
192598
+ const contextDir = path22.resolve(projectDir, context);
192599
+ const appPath = path22.relative(contextDir, projectDir) || ".";
191639
192600
  writeLog("tarball", `Context: ${contextDir}, appPath: ${appPath}`);
191640
192601
  let tarball;
191641
192602
  if (isInsideGitRepository(contextDir)) {
@@ -192522,19 +193483,17 @@ ${errorMsg}`
192522
193483
  ), phase === "error" && /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "red" }, "Error: ", error)), phase === "success" && /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text7, { color: "green" }, "Deployment successful!"), deployment?.publicUrls && Object.keys(deployment.publicUrls).length > 0 && /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text7, { bold: true }, "Public URLs:"), Object.entries(deployment.publicUrls).map(([name, url]) => /* @__PURE__ */ React7.createElement(Text7, { key: name }, " ", name, ": ", /* @__PURE__ */ React7.createElement(Text7, { color: "cyan" }, url))))));
192523
193484
  }
192524
193485
  async function deployCommand(environment, options2) {
192525
- const configPath = path22.join(process.cwd(), "specific.hcl");
192526
- if (!fs24.existsSync(configPath)) {
193486
+ const configPath = path23.join(process.cwd(), "specific.hcl");
193487
+ if (!fs25.existsSync(configPath)) {
192527
193488
  console.error("Error: No specific.hcl found in current directory");
192528
193489
  process.exit(1);
192529
193490
  }
192530
193491
  let config;
193492
+ const hcl = fs25.readFileSync(configPath, "utf-8");
192531
193493
  try {
192532
- const hcl = fs24.readFileSync(configPath, "utf-8");
192533
193494
  config = await parseConfig(hcl);
192534
193495
  } catch (err) {
192535
- console.error(
192536
- `Error: Invalid configuration: ${err instanceof Error ? err.message : String(err)}`
192537
- );
193496
+ console.error(formatConfigError(err, hcl, configPath));
192538
193497
  process.exit(1);
192539
193498
  }
192540
193499
  const env2 = environment || "prod";
@@ -192552,9 +193511,9 @@ async function deployCommand(environment, options2) {
192552
193511
  }
192553
193512
 
192554
193513
  // src/commands/exec.tsx
192555
- import { spawn as spawn6 } from "child_process";
192556
- import * as fs25 from "fs";
192557
- import * as path23 from "path";
193514
+ import { spawn as spawn7 } from "child_process";
193515
+ import * as fs26 from "fs";
193516
+ import * as path24 from "path";
192558
193517
  async function execCommand(serviceName, command, instanceKey = "default") {
192559
193518
  if (command.length === 0) {
192560
193519
  console.error(
@@ -192582,17 +193541,17 @@ async function execCommand(serviceName, command, instanceKey = "default") {
192582
193541
  }
192583
193542
  }
192584
193543
  };
192585
- const configPath = path23.join(process.cwd(), "specific.hcl");
192586
- if (!fs25.existsSync(configPath)) {
193544
+ const configPath = path24.join(process.cwd(), "specific.hcl");
193545
+ if (!fs26.existsSync(configPath)) {
192587
193546
  console.error("Error: No specific.hcl found in current directory");
192588
193547
  process.exit(1);
192589
193548
  }
192590
193549
  let config;
193550
+ const hcl = fs26.readFileSync(configPath, "utf-8");
192591
193551
  try {
192592
- const hcl = fs25.readFileSync(configPath, "utf-8");
192593
193552
  config = await parseConfig(hcl);
192594
193553
  } catch (err) {
192595
- console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
193554
+ console.error(formatConfigError(err, hcl, configPath));
192596
193555
  process.exit(1);
192597
193556
  }
192598
193557
  const service = config.services.find((s) => s.name === serviceName);
@@ -192660,7 +193619,8 @@ async function execCommand(serviceName, command, instanceKey = "default") {
192660
193619
  mode: "required",
192661
193620
  postgres: required.postgres,
192662
193621
  redis: required.redis,
192663
- storage: required.storage
193622
+ storage: required.storage,
193623
+ temporal: required.temporal
192664
193624
  },
192665
193625
  stateManager,
192666
193626
  dataDir: `.specific/keys/${instanceKey}/data`,
@@ -192705,14 +193665,14 @@ async function execCommand(serviceName, command, instanceKey = "default") {
192705
193665
  process.on("SIGTERM", () => handleSignal("SIGTERM"));
192706
193666
  let effectiveCwd = process.cwd();
192707
193667
  if (service.root) {
192708
- effectiveCwd = path23.resolve(process.cwd(), service.root);
193668
+ effectiveCwd = path24.resolve(process.cwd(), service.root);
192709
193669
  } else if (service.build) {
192710
193670
  const build = config.builds.find((b) => b.name === service.build.name);
192711
193671
  if (build?.root) {
192712
- effectiveCwd = path23.resolve(process.cwd(), build.root);
193672
+ effectiveCwd = path24.resolve(process.cwd(), build.root);
192713
193673
  }
192714
193674
  }
192715
- child = spawn6(command[0], command.slice(1), {
193675
+ child = spawn7(command[0], command.slice(1), {
192716
193676
  cwd: effectiveCwd,
192717
193677
  env: {
192718
193678
  ...process.env,
@@ -192736,9 +193696,9 @@ async function execCommand(serviceName, command, instanceKey = "default") {
192736
193696
  }
192737
193697
 
192738
193698
  // src/commands/psql.tsx
192739
- import { spawn as spawn7 } from "child_process";
192740
- import * as fs26 from "fs";
192741
- import * as path24 from "path";
193699
+ import { spawn as spawn8 } from "child_process";
193700
+ import * as fs27 from "fs";
193701
+ import * as path25 from "path";
192742
193702
  async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []) {
192743
193703
  let startedResources = [];
192744
193704
  let ownsInstances = false;
@@ -192755,17 +193715,17 @@ async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []
192755
193715
  }
192756
193716
  }
192757
193717
  };
192758
- const configPath = path24.join(process.cwd(), "specific.hcl");
192759
- if (!fs26.existsSync(configPath)) {
193718
+ const configPath = path25.join(process.cwd(), "specific.hcl");
193719
+ if (!fs27.existsSync(configPath)) {
192760
193720
  console.error("Error: No specific.hcl found in current directory");
192761
193721
  process.exit(1);
192762
193722
  }
192763
193723
  let config;
193724
+ const hcl = fs27.readFileSync(configPath, "utf-8");
192764
193725
  try {
192765
- const hcl = fs26.readFileSync(configPath, "utf-8");
192766
193726
  config = await parseConfig(hcl);
192767
193727
  } catch (err) {
192768
- console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
193728
+ console.error(formatConfigError(err, hcl, configPath));
192769
193729
  process.exit(1);
192770
193730
  }
192771
193731
  const availableDatabases = config.postgres.map((p) => p.name);
@@ -192814,7 +193774,8 @@ async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []
192814
193774
  mode: "required",
192815
193775
  postgres: [targetDb],
192816
193776
  redis: [],
192817
- storage: []
193777
+ storage: [],
193778
+ temporal: []
192818
193779
  },
192819
193780
  stateManager,
192820
193781
  dataDir: `.specific/keys/${instanceKey}/data`,
@@ -192858,7 +193819,7 @@ async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []
192858
193819
  };
192859
193820
  process.on("SIGINT", () => handleSignal("SIGINT"));
192860
193821
  process.on("SIGTERM", () => handleSignal("SIGTERM"));
192861
- child = spawn7(psqlPath, ["-h", dbState.host, "-p", String(dbState.port), "-U", dbState.user, "-d", dbState.dbName, ...extraArgs], {
193822
+ child = spawn8(psqlPath, ["-h", dbState.host, "-p", String(dbState.port), "-U", dbState.user, "-d", dbState.dbName, ...extraArgs], {
192862
193823
  cwd: process.cwd(),
192863
193824
  env: {
192864
193825
  ...process.env,
@@ -192883,9 +193844,9 @@ async function psqlCommand(databaseName, instanceKey = "default", extraArgs = []
192883
193844
  }
192884
193845
 
192885
193846
  // src/commands/reshape.tsx
192886
- import { spawn as spawn8 } from "child_process";
192887
- import * as fs27 from "fs";
192888
- import * as path25 from "path";
193847
+ import { spawn as spawn9 } from "child_process";
193848
+ import * as fs28 from "fs";
193849
+ import * as path26 from "path";
192889
193850
  var VALID_ACTIONS = ["start", "complete", "status", "abort", "check"];
192890
193851
  var MIGRATION_SUBCOMMANDS = ["start", "complete", "abort"];
192891
193852
  var OFFLINE_ACTIONS = ["check"];
@@ -192897,13 +193858,13 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
192897
193858
  process.exit(1);
192898
193859
  }
192899
193860
  const isOfflineAction = OFFLINE_ACTIONS.includes(action);
192900
- const configPath = path25.join(process.cwd(), "specific.hcl");
193861
+ const configPath = path26.join(process.cwd(), "specific.hcl");
192901
193862
  let config;
192902
193863
  let migrationsDir = "migrations";
192903
193864
  let targetDb;
192904
193865
  try {
192905
- if (fs27.existsSync(configPath)) {
192906
- const configContent = fs27.readFileSync(configPath, "utf-8");
193866
+ if (fs28.existsSync(configPath)) {
193867
+ const configContent = fs28.readFileSync(configPath, "utf-8");
192907
193868
  config = await parseConfig(configContent);
192908
193869
  if (databaseName) {
192909
193870
  const postgresConfig = config.postgres.find((p) => p.name === databaseName);
@@ -193007,7 +193968,8 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
193007
193968
  mode: "required",
193008
193969
  postgres: [targetDb],
193009
193970
  redis: [],
193010
- storage: []
193971
+ storage: [],
193972
+ temporal: []
193011
193973
  },
193012
193974
  stateManager,
193013
193975
  dataDir: `.specific/keys/${instanceKey}/data`,
@@ -193036,9 +193998,9 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
193036
193998
  }
193037
193999
  const isMigrationSubcommand = MIGRATION_SUBCOMMANDS.includes(action);
193038
194000
  const reshapeArgs = isMigrationSubcommand ? ["migration", action] : [action];
193039
- const fullMigrationsPath = path25.join(process.cwd(), migrationsDir);
194001
+ const fullMigrationsPath = path26.join(process.cwd(), migrationsDir);
193040
194002
  if (action === "check" || action === "start") {
193041
- if (fs27.existsSync(fullMigrationsPath)) {
194003
+ if (fs28.existsSync(fullMigrationsPath)) {
193042
194004
  reshapeArgs.push("--dirs", fullMigrationsPath);
193043
194005
  } else if (action === "check") {
193044
194006
  console.error(`Error: Migrations directory not found: ${fullMigrationsPath}`);
@@ -193060,7 +194022,7 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
193060
194022
  };
193061
194023
  process.on("SIGINT", () => handleSignal("SIGINT"));
193062
194024
  process.on("SIGTERM", () => handleSignal("SIGTERM"));
193063
- child = spawn8(reshapePath, reshapeArgs, {
194025
+ child = spawn9(reshapePath, reshapeArgs, {
193064
194026
  cwd: process.cwd(),
193065
194027
  env: {
193066
194028
  ...process.env,
@@ -193088,21 +194050,21 @@ async function reshapeCommand(action, databaseName, instanceKey = "default") {
193088
194050
  import React8, { useState as useState7, useEffect as useEffect5 } from "react";
193089
194051
  import { render as render6, Text as Text8, Box as Box8 } from "ink";
193090
194052
  import Spinner6 from "ink-spinner";
193091
- import * as fs28 from "fs";
193092
- import * as path26 from "path";
194053
+ import * as fs29 from "fs";
194054
+ import * as path27 from "path";
193093
194055
  function CleanUI({ instanceKey }) {
193094
194056
  const [state, setState] = useState7({ status: "checking" });
193095
194057
  useEffect5(() => {
193096
194058
  async function clean() {
193097
194059
  const projectRoot = process.cwd();
193098
- const specificDir = path26.join(projectRoot, ".specific");
193099
- if (!fs28.existsSync(specificDir)) {
194060
+ const specificDir = path27.join(projectRoot, ".specific");
194061
+ if (!fs29.existsSync(specificDir)) {
193100
194062
  setState({ status: "nothing" });
193101
194063
  return;
193102
194064
  }
193103
194065
  if (instanceKey) {
193104
- const keyDir = path26.join(specificDir, "keys", instanceKey);
193105
- if (!fs28.existsSync(keyDir)) {
194066
+ const keyDir = path27.join(specificDir, "keys", instanceKey);
194067
+ if (!fs29.existsSync(keyDir)) {
193106
194068
  setState({ status: "nothing" });
193107
194069
  return;
193108
194070
  }
@@ -193118,7 +194080,7 @@ function CleanUI({ instanceKey }) {
193118
194080
  await stateManager.cleanStaleState();
193119
194081
  setState({ status: "cleaning" });
193120
194082
  try {
193121
- fs28.rmSync(keyDir, { recursive: true, force: true });
194083
+ fs29.rmSync(keyDir, { recursive: true, force: true });
193122
194084
  setState({ status: "success" });
193123
194085
  } catch (err) {
193124
194086
  setState({
@@ -193127,13 +194089,13 @@ function CleanUI({ instanceKey }) {
193127
194089
  });
193128
194090
  }
193129
194091
  } else {
193130
- const keysDir = path26.join(specificDir, "keys");
193131
- if (!fs28.existsSync(keysDir)) {
194092
+ const keysDir = path27.join(specificDir, "keys");
194093
+ if (!fs29.existsSync(keysDir)) {
193132
194094
  setState({ status: "nothing" });
193133
194095
  return;
193134
194096
  }
193135
- const keys = fs28.readdirSync(keysDir).filter(
193136
- (f) => fs28.statSync(path26.join(keysDir, f)).isDirectory()
194097
+ const keys = fs29.readdirSync(keysDir).filter(
194098
+ (f) => fs29.statSync(path27.join(keysDir, f)).isDirectory()
193137
194099
  );
193138
194100
  for (const key of keys) {
193139
194101
  const stateManager2 = new InstanceStateManager(projectRoot, key);
@@ -193157,7 +194119,7 @@ function CleanUI({ instanceKey }) {
193157
194119
  }
193158
194120
  setState({ status: "cleaning" });
193159
194121
  try {
193160
- fs28.rmSync(keysDir, { recursive: true, force: true });
194122
+ fs29.rmSync(keysDir, { recursive: true, force: true });
193161
194123
  setState({ status: "success" });
193162
194124
  } catch (err) {
193163
194125
  setState({
@@ -193320,7 +194282,7 @@ function betaCommand() {
193320
194282
  var program = new Command();
193321
194283
  var env = "production";
193322
194284
  var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
193323
- program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.62").enablePositionalOptions();
194285
+ program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.63").enablePositionalOptions();
193324
194286
  program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").action((options2) => initCommand(options2));
193325
194287
  program.command("docs [topic]").description("Fetch LLM-optimized documentation").action(docsCommand);
193326
194288
  program.command("check").description("Validate specific.hcl configuration").action(checkCommand);