@gadgetinc/ggt 2.2.0 → 3.0.0

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 (224) hide show
  1. package/README.md +392 -307
  2. package/dist/action-CF6zatIh.js +64 -0
  3. package/dist/action-CF6zatIh.js.map +1 -0
  4. package/dist/action-CrDCeX3F.js +8 -0
  5. package/dist/action-CrDCeX3F.js.map +1 -0
  6. package/dist/add-Basu3Gyf.js +1 -0
  7. package/dist/agent-plugin-CqgwTOk-.js +15 -0
  8. package/dist/agent-plugin-CqgwTOk-.js.map +1 -0
  9. package/dist/agent-plugin-DU9G5B1d.js +9 -0
  10. package/dist/agent-plugin-DU9G5B1d.js.map +1 -0
  11. package/dist/assert-Bu1E126Z.js +2 -0
  12. package/dist/assert-Bu1E126Z.js.map +1 -0
  13. package/dist/chunk-BjEoQXZ0.js +1 -0
  14. package/dist/collection-C2TCeYqY.js +2 -0
  15. package/dist/collection-C2TCeYqY.js.map +1 -0
  16. package/dist/collection-aM0fpch0.js +1 -0
  17. package/dist/command-2iNTc5dV.js +118 -0
  18. package/dist/command-2iNTc5dV.js.map +1 -0
  19. package/dist/completion-D96nxD5n.js +37 -0
  20. package/dist/completion-D96nxD5n.js.map +1 -0
  21. package/dist/configure-C8ge-2cK.js +15 -0
  22. package/dist/configure-C8ge-2cK.js.map +1 -0
  23. package/dist/debugger-BkYgApKn.js +22 -0
  24. package/dist/debugger-BkYgApKn.js.map +1 -0
  25. package/dist/defaults-B_eD7Pia.js +2 -0
  26. package/dist/defaults-B_eD7Pia.js.map +1 -0
  27. package/dist/deploy-Da6P2HXS.js +15 -0
  28. package/dist/deploy-Da6P2HXS.js.map +1 -0
  29. package/dist/dev-DWMSNcLl.js +32 -0
  30. package/dist/dev-DWMSNcLl.js.map +1 -0
  31. package/dist/dev-lock-BFanZSu1.js +10 -0
  32. package/dist/dev-lock-BFanZSu1.js.map +1 -0
  33. package/dist/directory-CNL03L6c.js +9 -0
  34. package/dist/directory-CNL03L6c.js.map +1 -0
  35. package/dist/env-DoWNvHzW.js +62 -0
  36. package/dist/env-DoWNvHzW.js.map +1 -0
  37. package/dist/esm-B25i6Etq.js +12 -0
  38. package/dist/esm-B25i6Etq.js.map +1 -0
  39. package/dist/esm-CJocZrdd.js +2 -0
  40. package/dist/esm-CJocZrdd.js.map +1 -0
  41. package/dist/eval-BceZMSd5.js +27 -0
  42. package/dist/eval-BceZMSd5.js.map +1 -0
  43. package/dist/execAsync-DrhcEHLd.js +2 -0
  44. package/dist/execAsync-DrhcEHLd.js.map +1 -0
  45. package/dist/filesync-De6asZeR.js +61 -0
  46. package/dist/filesync-De6asZeR.js.map +1 -0
  47. package/dist/getMachineId-bsd-Cch8Z6pV.js +2 -0
  48. package/dist/getMachineId-bsd-Cch8Z6pV.js.map +1 -0
  49. package/dist/getMachineId-darwin-kbQWK54o.js +3 -0
  50. package/dist/getMachineId-darwin-kbQWK54o.js.map +1 -0
  51. package/dist/getMachineId-linux-DdIel6zr.js +2 -0
  52. package/dist/getMachineId-linux-DdIel6zr.js.map +1 -0
  53. package/dist/getMachineId-unsupported-Bvmsh30k.js +2 -0
  54. package/dist/getMachineId-unsupported-Bvmsh30k.js.map +1 -0
  55. package/dist/getMachineId-win-BteHZe8j.js +2 -0
  56. package/dist/getMachineId-win-BteHZe8j.js.map +1 -0
  57. package/dist/ggt-B3HQjQRM.js +3 -0
  58. package/dist/ggt-B3HQjQRM.js.map +1 -0
  59. package/dist/handler-DZyG8Sel.js +4 -0
  60. package/dist/handler-DZyG8Sel.js.map +1 -0
  61. package/dist/http-CY3lPMkt.js +320 -0
  62. package/dist/http-CY3lPMkt.js.map +1 -0
  63. package/dist/indent-string-BVm-4tyL.js +2 -0
  64. package/dist/indent-string-BVm-4tyL.js.map +1 -0
  65. package/dist/list-lQKWZ6ZI.js +10 -0
  66. package/dist/list-lQKWZ6ZI.js.map +1 -0
  67. package/dist/login-Ce0tByNd.js +1 -0
  68. package/dist/logout-_sTWeaiQ.js +5 -0
  69. package/dist/logout-_sTWeaiQ.js.map +1 -0
  70. package/dist/logs-DbhJzz4M.js +9 -0
  71. package/dist/logs-DbhJzz4M.js.map +1 -0
  72. package/dist/main.js +2 -2
  73. package/dist/main.js.map +1 -7
  74. package/dist/model-CBiMKY0P.js +11 -0
  75. package/dist/model-CBiMKY0P.js.map +1 -0
  76. package/dist/ms-B7sMc0pR.js +2 -0
  77. package/dist/ms-B7sMc0pR.js.map +1 -0
  78. package/dist/open-CSsA4B-l.js +38 -0
  79. package/dist/open-CSsA4B-l.js.map +1 -0
  80. package/dist/p-map-DE0acmRv.js +2 -0
  81. package/dist/p-map-DE0acmRv.js.map +1 -0
  82. package/dist/problems-BMLsmxd4.js +11 -0
  83. package/dist/problems-BMLsmxd4.js.map +1 -0
  84. package/dist/prompt-C9nwJW0G.js +2 -0
  85. package/dist/prompt-C9nwJW0G.js.map +1 -0
  86. package/dist/pull-DpizmJGk.js +12 -0
  87. package/dist/pull-DpizmJGk.js.map +1 -0
  88. package/dist/push-67KBCw6c.js +12 -0
  89. package/dist/push-67KBCw6c.js.map +1 -0
  90. package/dist/root-D_UnUsp7.js +28 -0
  91. package/dist/root-D_UnUsp7.js.map +1 -0
  92. package/dist/select-Dey_sjjd.js +4 -0
  93. package/dist/select-Dey_sjjd.js.map +1 -0
  94. package/dist/session-BmzGF1t7.js +2 -0
  95. package/dist/session-BmzGF1t7.js.map +1 -0
  96. package/dist/spinner-BVmbgIil.js +8 -0
  97. package/dist/spinner-BVmbgIil.js.map +1 -0
  98. package/dist/src-DxCC1MV4.js +6 -0
  99. package/dist/src-DxCC1MV4.js.map +1 -0
  100. package/dist/status-P_RFQ7J0.js +13 -0
  101. package/dist/status-P_RFQ7J0.js.map +1 -0
  102. package/dist/subscribeToEnvironmentLogs-CUicaiw_.js +2 -0
  103. package/dist/subscribeToEnvironmentLogs-CUicaiw_.js.map +1 -0
  104. package/dist/sync-json-V52OzeCz.js +112 -0
  105. package/dist/sync-json-V52OzeCz.js.map +1 -0
  106. package/dist/table-MrBbxMay.js +11 -0
  107. package/dist/table-MrBbxMay.js.map +1 -0
  108. package/dist/update-CfxiL08e.js +12 -0
  109. package/dist/update-CfxiL08e.js.map +1 -0
  110. package/dist/update-iyhnL9-M.js +1 -0
  111. package/dist/var-ByWcufFt.js +59 -0
  112. package/dist/var-ByWcufFt.js.map +1 -0
  113. package/dist/version-B_9GB4u3.js +9 -0
  114. package/dist/version-B_9GB4u3.js.map +1 -0
  115. package/dist/whoami-BNcXIfz7.js +5 -0
  116. package/dist/whoami-BNcXIfz7.js.map +1 -0
  117. package/package.json +19 -23
  118. package/assets/favicon-128@4x.png +0 -0
  119. package/dist/add-TWLGKL2T.js +0 -82
  120. package/dist/add-TWLGKL2T.js.map +0 -7
  121. package/dist/agent-plugin-TN24O7FB.js +0 -10
  122. package/dist/agent-plugin-TN24O7FB.js.map +0 -7
  123. package/dist/chunk-2742UPMB.js +0 -10
  124. package/dist/chunk-2742UPMB.js.map +0 -7
  125. package/dist/chunk-3OM5WM7E.js +0 -2
  126. package/dist/chunk-3OM5WM7E.js.map +0 -7
  127. package/dist/chunk-442CSROP.js +0 -66
  128. package/dist/chunk-442CSROP.js.map +0 -7
  129. package/dist/chunk-7DYQUG5M.js +0 -2
  130. package/dist/chunk-7DYQUG5M.js.map +0 -7
  131. package/dist/chunk-DR4CXBD6.js +0 -11
  132. package/dist/chunk-DR4CXBD6.js.map +0 -7
  133. package/dist/chunk-F255O64V.js +0 -2
  134. package/dist/chunk-F255O64V.js.map +0 -7
  135. package/dist/chunk-GFQYFEEH.js +0 -2
  136. package/dist/chunk-GFQYFEEH.js.map +0 -7
  137. package/dist/chunk-GJGBTM5Y.js +0 -2
  138. package/dist/chunk-GJGBTM5Y.js.map +0 -7
  139. package/dist/chunk-HCULGPBH.js +0 -2
  140. package/dist/chunk-HCULGPBH.js.map +0 -7
  141. package/dist/chunk-J232VCIM.js +0 -2
  142. package/dist/chunk-J232VCIM.js.map +0 -7
  143. package/dist/chunk-JG2QCDK2.js +0 -118
  144. package/dist/chunk-JG2QCDK2.js.map +0 -7
  145. package/dist/chunk-JKZNSRLU.js +0 -8
  146. package/dist/chunk-JKZNSRLU.js.map +0 -7
  147. package/dist/chunk-JYE5LLIF.js +0 -9
  148. package/dist/chunk-JYE5LLIF.js.map +0 -7
  149. package/dist/chunk-KKIL22RY.js +0 -2
  150. package/dist/chunk-KKIL22RY.js.map +0 -7
  151. package/dist/chunk-L2XBSR7G.js +0 -2
  152. package/dist/chunk-L2XBSR7G.js.map +0 -7
  153. package/dist/chunk-MW6MXMSN.js +0 -2
  154. package/dist/chunk-MW6MXMSN.js.map +0 -7
  155. package/dist/chunk-OUIZQC4D.js +0 -12
  156. package/dist/chunk-OUIZQC4D.js.map +0 -7
  157. package/dist/chunk-R6KJLEKY.js +0 -28
  158. package/dist/chunk-R6KJLEKY.js.map +0 -7
  159. package/dist/chunk-SIR6HLN3.js +0 -69
  160. package/dist/chunk-SIR6HLN3.js.map +0 -7
  161. package/dist/chunk-SVWK2NXG.js +0 -2
  162. package/dist/chunk-SVWK2NXG.js.map +0 -7
  163. package/dist/chunk-T6UHSWMT.js +0 -2
  164. package/dist/chunk-T6UHSWMT.js.map +0 -7
  165. package/dist/chunk-WB6O2V5D.js +0 -11
  166. package/dist/chunk-WB6O2V5D.js.map +0 -7
  167. package/dist/chunk-XC4F2TLW.js +0 -113
  168. package/dist/chunk-XC4F2TLW.js.map +0 -7
  169. package/dist/chunk-YFUOXDPK.js +0 -10
  170. package/dist/chunk-YFUOXDPK.js.map +0 -7
  171. package/dist/chunk-ZSREFZXV.js +0 -211
  172. package/dist/chunk-ZSREFZXV.js.map +0 -7
  173. package/dist/chunk-ZYDMXS5R.js +0 -6
  174. package/dist/chunk-ZYDMXS5R.js.map +0 -7
  175. package/dist/configure-UJS7V2JX.js +0 -12
  176. package/dist/configure-UJS7V2JX.js.map +0 -7
  177. package/dist/debugger-QN2MCLBL.js +0 -41
  178. package/dist/debugger-QN2MCLBL.js.map +0 -7
  179. package/dist/deploy-J74PHPQA.js +0 -25
  180. package/dist/deploy-J74PHPQA.js.map +0 -7
  181. package/dist/dev-GGUSOOYP.js +0 -59
  182. package/dist/dev-GGUSOOYP.js.map +0 -7
  183. package/dist/esm-D77XRR65.js +0 -38
  184. package/dist/esm-D77XRR65.js.map +0 -7
  185. package/dist/eval-L6WHUFLU.js +0 -54
  186. package/dist/eval-L6WHUFLU.js.map +0 -7
  187. package/dist/getMachineId-bsd-QUXN4NKS.js +0 -2
  188. package/dist/getMachineId-bsd-QUXN4NKS.js.map +0 -7
  189. package/dist/getMachineId-darwin-TCXBAX22.js +0 -3
  190. package/dist/getMachineId-darwin-TCXBAX22.js.map +0 -7
  191. package/dist/getMachineId-linux-IJ3LYIOX.js +0 -2
  192. package/dist/getMachineId-linux-IJ3LYIOX.js.map +0 -7
  193. package/dist/getMachineId-unsupported-IKXBUCYY.js +0 -2
  194. package/dist/getMachineId-unsupported-IKXBUCYY.js.map +0 -7
  195. package/dist/getMachineId-win-6CX7VSFF.js +0 -2
  196. package/dist/getMachineId-win-6CX7VSFF.js.map +0 -7
  197. package/dist/ggt-5XNRJZSW.js +0 -44
  198. package/dist/ggt-5XNRJZSW.js.map +0 -7
  199. package/dist/list-756D46N5.js +0 -11
  200. package/dist/list-756D46N5.js.map +0 -7
  201. package/dist/login-GMWQRH7V.js +0 -2
  202. package/dist/login-GMWQRH7V.js.map +0 -7
  203. package/dist/logout-LQABTJFD.js +0 -7
  204. package/dist/logout-LQABTJFD.js.map +0 -7
  205. package/dist/logs-AQZB272X.js +0 -28
  206. package/dist/logs-AQZB272X.js.map +0 -7
  207. package/dist/open-OMZWPQ66.js +0 -74
  208. package/dist/open-OMZWPQ66.js.map +0 -7
  209. package/dist/problems-FZJKH52E.js +0 -14
  210. package/dist/problems-FZJKH52E.js.map +0 -7
  211. package/dist/pull-XYCYN7QN.js +0 -28
  212. package/dist/pull-XYCYN7QN.js.map +0 -7
  213. package/dist/push-3QM7ZFTC.js +0 -2
  214. package/dist/push-3QM7ZFTC.js.map +0 -7
  215. package/dist/status-PWAXNK5G.js +0 -14
  216. package/dist/status-PWAXNK5G.js.map +0 -7
  217. package/dist/update-QIQFJFRQ.js +0 -2
  218. package/dist/update-QIQFJFRQ.js.map +0 -7
  219. package/dist/var-N4WGGJXZ.js +0 -159
  220. package/dist/var-N4WGGJXZ.js.map +0 -7
  221. package/dist/version-AJKSJJDC.js +0 -11
  222. package/dist/version-AJKSJJDC.js.map +0 -7
  223. package/dist/whoami-KJYDSQSD.js +0 -7
  224. package/dist/whoami-KJYDSQSD.js.map +0 -7
@@ -0,0 +1,37 @@
1
+ import"./ms-B7sMc0pR.js";import"./prompt-C9nwJW0G.js";import{C as e,N as t,P as n}from"./http-CY3lPMkt.js";import{E as r,n as i,r as a,s as o,t as s}from"./command-2iNTc5dV.js";import"./collection-C2TCeYqY.js";import"./directory-CNL03L6c.js";import"./session-BmzGF1t7.js";import"./agent-plugin-DU9G5B1d.js";import"./update-CfxiL08e.js";import{t as c}from"./root-D_UnUsp7.js";const l=(...e)=>{let t=[];for(let n of e)for(let e of n)(e.type===`string`||e.type===`number`)&&t.push(e.name,...e.aliases);return t},u=async()=>{let n=t(c).filter(e=>!e.hidden),r=[],i=await Promise.all(s.map(e=>a(e)));for(let[n,a]of s.entries()){let o=i[n];if(o.hidden)continue;let s=t(e(o.flags??{})).filter(e=>!e.hidden),c=o.description,l=Object.entries(`subcommands`in o&&o.subcommands?o.subcommands:{}).map(([e,n])=>({name:e,description:n.description,aliases:n.aliases?.slice()??[],flags:t(n.flags??{}).filter(e=>!e.hidden)}));r.push({name:a,description:c,aliases:o.aliases?.slice()??[],flags:s,subcommands:l})}return{rootFlags:n,commands:r}},d=e=>{let t=[];t.push(`# bash completion for ggt -*- shell-script -*-`),t.push(``),t.push(`_ggt_completions() {`),t.push(' local cur="${COMP_WORDS[COMP_CWORD]}"'),t.push(``);let r=new Set,i=new Set,a=new Set,o=e=>{for(let t of e)if(t.hasCompleter){r.add(t.name);for(let e of t.aliases)r.add(e)}else if(t.valueName===`path`){i.add(t.name);for(let e of t.aliases)i.add(e)}else if(t.type===`string`||t.type===`number`){a.add(t.name);for(let e of t.aliases)a.add(e)}};o(e.rootFlags);for(let t of e.commands){o(t.flags);for(let e of t.subcommands)o(e.flags)}(r.size>0||i.size>0||a.size>0)&&(t.push(' local prev="${COMP_WORDS[COMP_CWORD-1]}"'),t.push(``),t.push(` case "$prev" in`),r.size>0&&(t.push(` ${[...r].join(`|`)})`),t.push(` local IFS=$'\\n'`),t.push(' COMPREPLY=($(ggt --__complete "${COMP_WORDS[@]:1}" 2>/dev/null))'),t.push(` return ;;`)),i.size>0&&(t.push(` ${[...i].join(`|`)})`),t.push(` COMPREPLY=($(compgen -f -- "$cur"))`),t.push(` return ;;`)),a.size>0&&(t.push(` ${[...a].join(`|`)})`),t.push(` return ;;`)),t.push(` esac`),t.push(``));let s=n(e.rootFlags),c=e.commands.flatMap(e=>[e.name,...e.aliases]);t.push(` if [[ $COMP_CWORD -eq 1 ]]; then`),t.push(` COMPREPLY=($(compgen -W "${[...c,...s].join(` `)}" -- "$cur"))`),t.push(` return`),t.push(` fi`),t.push(``),t.push(' case "${COMP_WORDS[1]}" in');for(let r of e.commands)if(r.subcommands.length>0){t.push(` ${[r.name,...r.aliases].join(`|`)})`);let i=l(e.rootFlags,r.flags);t.push(` local sub_cmd=`),t.push(` local __skip_next=0`),t.push(` for ((i=2; i < COMP_CWORD; i++)); do`),t.push(' local w="${COMP_WORDS[i]}"'),t.push(` if [[ $__skip_next -eq 1 ]]; then`),t.push(` __skip_next=0`),t.push(` continue`),t.push(` fi`),i.length>0&&(t.push(` case "$w" in`),t.push(` ${i.join(`|`)}) __skip_next=1; continue ;;`),t.push(` esac`)),t.push(` if [[ "$w" != -* ]]; then`),t.push(` sub_cmd="$w"`),t.push(` break`),t.push(` fi`),t.push(` done`),t.push(``);let a=r.subcommands.flatMap(e=>[e.name,...e.aliases]),o=n(r.flags);t.push(` if [[ -z "$sub_cmd" ]]; then`),t.push(` COMPREPLY=($(compgen -W "${[...a,...o,...s].join(` `)}" -- "$cur"))`),t.push(` else`),t.push(` case "$sub_cmd" in`);for(let e of r.subcommands){let i=n([...r.flags,...e.flags]);t.push(` ${[e.name,...e.aliases].join(`|`)})`),t.push(` COMPREPLY=($(compgen -W "${[...i,...s].join(` `)}" -- "$cur"))`),t.push(` ;;`)}t.push(` *)`),t.push(` COMPREPLY=($(compgen -W "${[...o,...s].join(` `)}" -- "$cur"))`),t.push(` ;;`),t.push(` esac`),t.push(` fi`),t.push(` ;;`)}else{let e=n(r.flags);t.push(` ${[r.name,...r.aliases].join(`|`)})`),t.push(` COMPREPLY=($(compgen -W "${[...e,...s].join(` `)}" -- "$cur"))`),t.push(` ;;`)}return t.push(` esac`),t.push(`}`),t.push(``),t.push(`complete -F _ggt_completions ggt`),t.push(``),t.join(`
2
+ `)},f=e=>{let t=[];t.push(`# fish completion for ggt`),t.push(``),t.push(`# Disable file completions by default`),t.push(`complete -c ggt -f`),t.push(``),t.push(`# Helper: invoke ggt's dynamic completer with correct partial`),t.push(`function __ggt_complete`),t.push(` set -l tokens (commandline -opc)[2..]`),t.push(` set -l current (commandline -ct)`),t.push(` # fish reports the flag token as $current without a trailing space;`),t.push(` # passing $current '' tells the handler to complete the flag value with an empty partial`),t.push(` if string match -q -- '-*' $current`),t.push(` ggt --__complete $tokens $current '' 2>/dev/null`),t.push(` else`),t.push(` ggt --__complete $tokens $current 2>/dev/null`),t.push(` end`),t.push(`end`),t.push(``),e.commands.filter(e=>e.subcommands.length>0).length>0&&(t.push(`# Helper: check if a specific subcommand of a parent command has been entered`),t.push(`# Usage: __ggt_seen_subcommand parentName [parentAlias...] -- subName [subAlias...] -- valueFlagName ...`),t.push(`function __ggt_seen_subcommand`),t.push(` set -l parents`),t.push(` set -l subs`),t.push(` set -l vflags`),t.push(` set -l sep_count 0`),t.push(` for arg in $argv`),t.push(` if test $arg = '--'`),t.push(` set sep_count (math $sep_count + 1)`),t.push(` else if test $sep_count -eq 2`),t.push(` set -a vflags $arg`),t.push(` else if test $sep_count -eq 1`),t.push(` set -a subs $arg`),t.push(` else`),t.push(` set -a parents $arg`),t.push(` end`),t.push(` end`),t.push(` set -l cmd (commandline -opc)`),t.push(` set -l found_parent 0`),t.push(` set -l skip_next 0`),t.push(` for word in $cmd`),t.push(` if test $found_parent -eq 1`),t.push(` if test $skip_next -eq 1`),t.push(` set skip_next 0`),t.push(` continue`),t.push(` end`),t.push(` if set -q vflags[1]; and contains -- $word $vflags`),t.push(` set skip_next 1`),t.push(` continue`),t.push(` end`),t.push(` if contains -- $word $subs`),t.push(` return 0`),t.push(` end`),t.push(` end`),t.push(` if contains -- $word $parents`),t.push(` set found_parent 1`),t.push(` end`),t.push(` end`),t.push(` return 1`),t.push(`end`),t.push(``),t.push(`# Helper: check if we are positioned for a subcommand (parent seen, no subcommand yet)`),t.push(`# Usage: __ggt_needs_subcommand parentName [parentAlias...] -- valueFlagName ...`),t.push(`function __ggt_needs_subcommand`),t.push(` set -l parents`),t.push(` set -l vflags`),t.push(` set -l after_sep 0`),t.push(` for a in $argv`),t.push(` if test $a = '--'`),t.push(` set after_sep 1`),t.push(` else if test $after_sep -eq 1`),t.push(` set -a vflags $a`),t.push(` else`),t.push(` set -a parents $a`),t.push(` end`),t.push(` end`),t.push(` set -l cmd (commandline -opc)`),t.push(` set -l found_parent 0`),t.push(` set -l skip_next 0`),t.push(` for word in $cmd`),t.push(` if test $found_parent -eq 1`),t.push(` if test $skip_next -eq 1`),t.push(` set skip_next 0`),t.push(` continue`),t.push(` end`),t.push(` if contains -- $word $vflags`),t.push(` set skip_next 1`),t.push(` continue`),t.push(` end`),t.push(` if string match -q -- '-*' $word`),t.push(` continue`),t.push(` end`),t.push(` return 1`),t.push(` end`),t.push(` if contains -- $word $parents`),t.push(` set found_parent 1`),t.push(` end`),t.push(` end`),t.push(` # parent was found but no subcommand yet`),t.push(` if test $found_parent -eq 1`),t.push(` return 0`),t.push(` end`),t.push(` return 1`),t.push(`end`),t.push(``)),t.push(`# Root flags`);for(let n of e.rootFlags)t.push(...p(n,`__fish_use_subcommand`));t.push(``),t.push(`# Commands`);for(let n of e.commands){let e=m(n.description);t.push(`complete -c ggt -n '__fish_use_subcommand' -a '${n.name}' -d '${e}'`);for(let r of n.aliases)t.push(`complete -c ggt -n '__fish_use_subcommand' -a '${r}' -d '${e}'`)}t.push(``);for(let n of e.commands){t.push(`# ${n.name}`);let r=[n.name,...n.aliases].join(` `);if(n.subcommands.length>0){for(let e of n.flags)t.push(...p(e,`__fish_seen_subcommand_from ${r}`));let i=l(n.flags,e.rootFlags),a=i.length>0?`__ggt_needs_subcommand ${r} -- ${i.join(` `)}`:`__ggt_needs_subcommand ${r}`;for(let e of n.subcommands){let n=m(e.description);t.push(`complete -c ggt -n '${a}' -a '${e.name}' -d '${n}'`);for(let r of e.aliases)t.push(`complete -c ggt -n '${a}' -a '${r}' -d '${n}'`)}let o=i.length>0?` -- ${i.join(` `)}`:``;for(let e of n.subcommands){let n=[e.name,...e.aliases].join(` `);for(let i of e.flags)t.push(...p(i,`__ggt_seen_subcommand ${r} -- ${n}${o}`))}for(let i of e.rootFlags){t.push(...p(i,`__fish_seen_subcommand_from ${r}`));for(let e of n.subcommands){let n=[e.name,...e.aliases].join(` `);t.push(...p(i,`__ggt_seen_subcommand ${r} -- ${n}${o}`))}}}else{for(let e of n.flags)t.push(...p(e,`__fish_seen_subcommand_from ${r}`));for(let n of e.rootFlags)t.push(...p(n,`__fish_seen_subcommand_from ${r}`))}t.push(``)}return t.join(`
3
+ `)},p=(e,t)=>{let n=[e.name.replace(/^--/,``)],r=[];for(let t of e.aliases)t.startsWith(`--`)?n.push(t.replace(/^--/,``)):t.startsWith(`-`)&&r.push(`-s ${t.replace(/^-/,``)}`);let i=[];return(e.type===`string`||e.type===`number`)&&(e.hasCompleter?i.push(`-rfa '(__ggt_complete)'`):e.valueName===`path`?i.push(`-rF`):i.push(`-x`)),e.description&&i.push(`-d '${m(e.description)}'`),n.map((e,n)=>{let a=[`complete -c ggt -n '${t}'`,`-l ${e}`];return n===0&&a.push(...r),a.push(...i),a.join(` `)})},m=e=>e.replace(/'/g,`'\\''`),h=e=>e.map((t,n)=>` ${t}${n<e.length-1?` \\`:``}`),g=e=>{let t=[];t.push(`#compdef ggt`),t.push(``);let n=e.rootFlags.some(e=>e.hasCompleter)||e.commands.some(e=>e.flags.some(e=>e.hasCompleter)||e.subcommands.some(e=>e.flags.some(e=>e.hasCompleter)));n&&(t.push(`_ggt_dynamic() {`),t.push(` local -a results`),t.push(' results=(${(f)"$(ggt --__complete "${_ggt_words[@]:1}" 2>/dev/null)"})'),t.push(` compadd -a results`),t.push(`}`),t.push(``));for(let n of e.commands)n.subcommands.length>0&&(t.push(..._(n,e.rootFlags)),t.push(``));t.push(`_ggt() {`),t.push(` local -a commands`),t.push(` local state`),n&&(t.push(` # Save the full word list before _arguments -C locally scopes $words`),t.push(' local -a _ggt_words=("${words[@]}")')),t.push(``),t.push(` _arguments -C \\`);for(let n of e.rootFlags)t.push(` ${v(n)} \\`);t.push(` '1:command:->command' \\`),t.push(` '*::arg:->args'`),t.push(``),t.push(` case $state in`),t.push(` command)`),t.push(` commands=(`);for(let n of e.commands){t.push(` '${n.name}:${y(n.description)}'`);for(let e of n.aliases)t.push(` '${e}:${y(n.description)}'`)}t.push(` )`),t.push(` _describe -t commands 'ggt command' commands`),t.push(` ;;`),t.push(` args)`),t.push(` case $words[1] in`);for(let n of e.commands)if(n.subcommands.length>0)t.push(` ${[n.name,...n.aliases].join(`|`)})`),t.push(` _ggt_${b(n.name)}`),t.push(` ;;`);else{let r=[...e.rootFlags,...n.flags];t.push(` ${[n.name,...n.aliases].join(`|`)})`),t.push(` _arguments \\`),t.push(...h(r.map(e=>v(e)))),t.push(` ;;`)}return t.push(` esac`),t.push(` ;;`),t.push(` esac`),t.push(`}`),t.push(``),t.push(`_ggt "$@"`),t.push(``),t.join(`
4
+ `)},_=(e,t)=>{let n=`_ggt_${b(e.name)}`,r=[];r.push(`${n}() {`),r.push(` local -a subcommands`),r.push(` local state`),r.push(``),r.push(` _arguments -C \\`);let i=[...t,...e.flags];for(let e of i)r.push(` ${v(e)} \\`);r.push(` '1:subcommand:->subcommand' \\`),r.push(` '*::arg:->args'`),r.push(``),r.push(` case $state in`),r.push(` subcommand)`),r.push(` subcommands=(`);for(let t of e.subcommands){r.push(` '${t.name}:${y(t.description)}'`);for(let e of t.aliases)r.push(` '${e}:${y(t.description)}'`)}r.push(` )`),r.push(` _describe -t subcommands '${e.name} subcommand' subcommands`),r.push(` ;;`),r.push(` args)`),r.push(` case $words[1] in`);for(let n of e.subcommands){let i=[...t,...e.flags,...n.flags];r.push(` ${[n.name,...n.aliases].join(`|`)})`),i.length>0&&(r.push(` _arguments \\`),r.push(...h(i.map(e=>v(e))))),r.push(` ;;`)}return r.push(` esac`),r.push(` ;;`),r.push(` esac`),r.push(`}`),r},v=e=>{let t=y(e.description),n=e.type===`string`||e.type===`number`,r=[e.name,...e.aliases],i=r.length>1?`'(${r.join(` `)})'`:``,a=n?e.hasCompleter?`:value:_ggt_dynamic`:e.valueName===`path`?`:value:_files`:`:value: `:``;if(r.length===1)return`${i}'${e.name}[${t}]${a}'`;let o=[];for(let e of r)o.push(`${i}'${e}[${t}]${a}'`);return o.join(` \\
5
+ `)},y=e=>e.replace(/\\/g,`\\\\`).replace(/'/g,`'\\''`).replace(/\[/g,`\\[`).replace(/\]/g,`\\]`).replace(/:/g,`\\:`),b=e=>e.replace(/-/g,`_`);var x=i({name:`completion`,description:`Generate shell completion scripts`,details:r`
6
+ Generates a completion script for your shell so that ggt commands,
7
+ subcommands, and flags are suggested when you press Tab. Run one of the
8
+ subcommands below and follow the installation instructions to enable it.
9
+ `,examples:[`ggt completion bash`,`ggt completion zsh`,`ggt completion fish`],sections:[{title:`Setup`,content:r`
10
+ Choose the section that matches your shell. After following the steps,
11
+ open a new terminal (or reload your shell config) for completions to
12
+ take effect. Re-run the generation command after updating ggt.
13
+
14
+ If ggt is not installed globally, you can use ${o.identifier(`npx ggt`)} in place
15
+ of ${o.identifier(`ggt`)} in the commands below.
16
+
17
+ Bash
18
+ ${o.identifier(`mkdir -p ~/.local/share/ggt`)}
19
+ ${o.identifier(`ggt completion bash > ~/.local/share/ggt/completion.bash`)}
20
+
21
+ Then add this line to your ${o.identifier(`~/.bashrc`)} (or ${o.identifier(`~/.bash_profile`)} on macOS):
22
+ ${o.identifier(`source "$HOME/.local/share/ggt/completion.bash"`)}
23
+
24
+ Zsh
25
+ ${o.identifier(`mkdir -p ~/.local/share/ggt`)}
26
+ ${o.identifier(`ggt completion zsh > ~/.local/share/ggt/completion.zsh`)}
27
+
28
+ Then add this line to your ${o.identifier(`~/.zshrc`)}:
29
+ ${o.identifier(`source "$HOME/.local/share/ggt/completion.zsh"`)}
30
+
31
+ If you get "command not found: compdef", add this before the line above:
32
+ ${o.identifier(`autoload -Uz compinit && compinit`)}
33
+
34
+ Fish
35
+ ${o.identifier(`ggt completion fish > ~/.config/fish/completions/ggt.fish`)}
36
+ `}],subcommands:e=>({bash:e({description:`Generate bash completion script`,run:async()=>{let e=await u();process.stdout.write(d(e))}}),zsh:e({description:`Generate zsh completion script`,run:async()=>{let e=await u();process.stdout.write(g(e))}}),fish:e({description:`Generate fish completion script`,run:async()=>{let e=await u();process.stdout.write(f(e))}})})});export{x as default};
37
+ //# sourceMappingURL=completion-D96nxD5n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion-D96nxD5n.js","names":["rootFlagsDef","colors"],"sources":["../src/services/completion/completions.ts","../src/services/completion/bash.ts","../src/services/completion/fish.ts","../src/services/completion/zsh.ts","../src/commands/completion.ts"],"sourcesContent":["import { flags as rootFlagsDef } from \"../../commands/root.ts\";\nimport { withAllowFlags } from \"../command/allow.ts\";\nimport { Commands, importCommand } from \"../command/command.ts\";\nimport { extractFlags, type FlagDef } from \"../command/flag.ts\";\n\n/**\n * Collects all flag names and aliases for flags that take a value (string or number).\n */\nexport const valueFlagNames = (...flagSets: FlagDef[][]): string[] => {\n const names: string[] = [];\n for (const flags of flagSets) {\n for (const f of flags) {\n if (f.type === \"string\" || f.type === \"number\") {\n names.push(f.name, ...f.aliases);\n }\n }\n }\n return names;\n};\n\nexport type CompletionSubcommandDef = {\n name: string;\n description: string;\n aliases: string[];\n flags: FlagDef[];\n};\n\nexport type CommandDef = {\n name: string;\n description: string;\n aliases: string[];\n flags: FlagDef[];\n subcommands: CompletionSubcommandDef[];\n};\n\nexport type CompletionData = {\n rootFlags: FlagDef[];\n commands: CommandDef[];\n};\n\n/**\n * Builds the complete completion data by introspecting all commands.\n */\nexport const getCompletionData = async (): Promise<CompletionData> => {\n const rootFlags = extractFlags(rootFlagsDef).filter((f) => !f.hidden);\n\n const commands: CommandDef[] = [];\n\n const modules = await Promise.all(Commands.map((cmd) => importCommand(cmd)));\n for (const [i, cmd] of Commands.entries()) {\n const mod = modules[i];\n if (mod.hidden) {\n continue;\n }\n const mergedFlagsDef = withAllowFlags(mod.flags ?? {});\n const flags = extractFlags(mergedFlagsDef).filter((f) => !f.hidden);\n const description = mod.description;\n const subcommands: CompletionSubcommandDef[] = Object.entries(\"subcommands\" in mod && mod.subcommands ? mod.subcommands : {}).map(\n ([name, sub]) => ({\n name,\n description: sub.description,\n aliases: (sub as { aliases?: readonly string[] }).aliases?.slice() ?? [],\n flags: extractFlags(sub.flags ?? {}).filter((f) => !f.hidden),\n }),\n );\n\n commands.push({ name: cmd, description, aliases: (mod as { aliases?: readonly string[] }).aliases?.slice() ?? [], flags, subcommands });\n }\n\n return { rootFlags, commands };\n};\n","import { flagWords, type FlagDef } from \"../command/flag.ts\";\nimport { valueFlagNames, type CompletionData } from \"./completions.ts\";\n\n/**\n * Generates a complete Bash completion script for ggt.\n */\nexport const generateBashCompletions = (data: CompletionData): string => {\n const lines: string[] = [];\n\n lines.push(\"# bash completion for ggt -*- shell-script -*-\");\n lines.push(\"\");\n lines.push(\"_ggt_completions() {\");\n lines.push(' local cur=\"${COMP_WORDS[COMP_CWORD]}\"');\n lines.push(\"\");\n\n // classify flags: dynamic completers, path flags (file completion), other value flags (suppress)\n const completerFlags = new Set<string>();\n const pathFlags = new Set<string>();\n const otherValueFlags = new Set<string>();\n const classifyFlags = (flags: FlagDef[]): void => {\n for (const f of flags) {\n if (f.hasCompleter) {\n completerFlags.add(f.name);\n for (const a of f.aliases) completerFlags.add(a);\n } else if (f.valueName === \"path\") {\n pathFlags.add(f.name);\n for (const a of f.aliases) pathFlags.add(a);\n } else if (f.type === \"string\" || f.type === \"number\") {\n otherValueFlags.add(f.name);\n for (const a of f.aliases) otherValueFlags.add(a);\n }\n }\n };\n classifyFlags(data.rootFlags);\n for (const cmd of data.commands) {\n classifyFlags(cmd.flags);\n for (const sub of cmd.subcommands) {\n classifyFlags(sub.flags);\n }\n }\n\n if (completerFlags.size > 0 || pathFlags.size > 0 || otherValueFlags.size > 0) {\n lines.push(' local prev=\"${COMP_WORDS[COMP_CWORD-1]}\"');\n lines.push(\"\");\n lines.push(' case \"$prev\" in');\n if (completerFlags.size > 0) {\n lines.push(` ${[...completerFlags].join(\"|\")})`);\n lines.push(\" local IFS=$'\\\\n'\");\n lines.push(' COMPREPLY=($(ggt --__complete \"${COMP_WORDS[@]:1}\" 2>/dev/null))');\n lines.push(\" return ;;\");\n }\n if (pathFlags.size > 0) {\n lines.push(` ${[...pathFlags].join(\"|\")})`);\n lines.push(' COMPREPLY=($(compgen -f -- \"$cur\"))');\n lines.push(\" return ;;\");\n }\n if (otherValueFlags.size > 0) {\n lines.push(` ${[...otherValueFlags].join(\"|\")})`);\n lines.push(\" return ;;\");\n }\n lines.push(\" esac\");\n lines.push(\"\");\n }\n\n const rootFlagWords = flagWords(data.rootFlags);\n const commandNames = data.commands.flatMap((c) => [c.name, ...c.aliases]);\n\n // top-level completion: commands + root flags\n lines.push(\" if [[ $COMP_CWORD -eq 1 ]]; then\");\n lines.push(` COMPREPLY=($(compgen -W \"${[...commandNames, ...rootFlagWords].join(\" \")}\" -- \"$cur\"))`);\n lines.push(\" return\");\n lines.push(\" fi\");\n lines.push(\"\");\n\n // per-command completion\n lines.push(' case \"${COMP_WORDS[1]}\" in');\n\n for (const cmd of data.commands) {\n if (cmd.subcommands.length > 0) {\n lines.push(` ${[cmd.name, ...cmd.aliases].join(\"|\")})`);\n\n // Collect all flag names (root + command) that take a value, so the\n // subcommand-finding loop can skip the flag's argument.\n const valueFlagList = valueFlagNames(data.rootFlags, cmd.flags);\n\n // Find the subcommand word by scanning COMP_WORDS after the command,\n // skipping flags and their values.\n lines.push(\" local sub_cmd=\");\n lines.push(\" local __skip_next=0\");\n lines.push(\" for ((i=2; i < COMP_CWORD; i++)); do\");\n lines.push(' local w=\"${COMP_WORDS[i]}\"');\n lines.push(\" if [[ $__skip_next -eq 1 ]]; then\");\n lines.push(\" __skip_next=0\");\n lines.push(\" continue\");\n lines.push(\" fi\");\n if (valueFlagList.length > 0) {\n lines.push(' case \"$w\" in');\n lines.push(` ${valueFlagList.join(\"|\")}) __skip_next=1; continue ;;`);\n lines.push(\" esac\");\n }\n lines.push(' if [[ \"$w\" != -* ]]; then');\n lines.push(' sub_cmd=\"$w\"');\n lines.push(\" break\");\n lines.push(\" fi\");\n lines.push(\" done\");\n lines.push(\"\");\n\n const subNames = cmd.subcommands.flatMap((s) => [s.name, ...s.aliases]);\n const cmdFlagList = flagWords(cmd.flags);\n\n lines.push(' if [[ -z \"$sub_cmd\" ]]; then');\n lines.push(` COMPREPLY=($(compgen -W \"${[...subNames, ...cmdFlagList, ...rootFlagWords].join(\" \")}\" -- \"$cur\"))`);\n lines.push(\" else\");\n lines.push(' case \"$sub_cmd\" in');\n\n for (const sub of cmd.subcommands) {\n const subFlagList = flagWords([...cmd.flags, ...sub.flags]);\n lines.push(` ${[sub.name, ...sub.aliases].join(\"|\")})`);\n lines.push(` COMPREPLY=($(compgen -W \"${[...subFlagList, ...rootFlagWords].join(\" \")}\" -- \"$cur\"))`);\n lines.push(\" ;;\");\n }\n\n lines.push(\" *)\");\n lines.push(` COMPREPLY=($(compgen -W \"${[...cmdFlagList, ...rootFlagWords].join(\" \")}\" -- \"$cur\"))`);\n lines.push(\" ;;\");\n lines.push(\" esac\");\n lines.push(\" fi\");\n lines.push(\" ;;\");\n } else {\n const cmdFlagList = flagWords(cmd.flags);\n lines.push(` ${[cmd.name, ...cmd.aliases].join(\"|\")})`);\n lines.push(` COMPREPLY=($(compgen -W \"${[...cmdFlagList, ...rootFlagWords].join(\" \")}\" -- \"$cur\"))`);\n lines.push(\" ;;\");\n }\n }\n\n lines.push(\" esac\");\n lines.push(\"}\");\n lines.push(\"\");\n lines.push(\"complete -F _ggt_completions ggt\");\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n};\n","import type { FlagDef } from \"../command/flag.ts\";\nimport { valueFlagNames, type CompletionData } from \"./completions.ts\";\n\n/**\n * Generates a complete Fish completion script for ggt.\n */\nexport const generateFishCompletions = (data: CompletionData): string => {\n const lines: string[] = [];\n\n lines.push(\"# fish completion for ggt\");\n lines.push(\"\");\n lines.push(\"# Disable file completions by default\");\n lines.push(\"complete -c ggt -f\");\n lines.push(\"\");\n\n // helper function for dynamic completions\n // When fish matches a flag (e.g. -a for --app) and evaluates the -a completer\n // for the flag's value, `commandline -ct` still returns the flag token itself\n // (e.g. \"-a\") if there's no space after it. This helper detects that case and\n // includes the flag as a preceding token with an empty partial, so the handler\n // sees e.g. [\"dev\", \"-a\", \"\"] and recognizes it as flag value completion.\n lines.push(\"# Helper: invoke ggt's dynamic completer with correct partial\");\n lines.push(\"function __ggt_complete\");\n lines.push(\" set -l tokens (commandline -opc)[2..]\");\n lines.push(\" set -l current (commandline -ct)\");\n lines.push(\" # fish reports the flag token as $current without a trailing space;\");\n lines.push(\" # passing $current '' tells the handler to complete the flag value with an empty partial\");\n lines.push(\" if string match -q -- '-*' $current\");\n lines.push(\" ggt --__complete $tokens $current '' 2>/dev/null\");\n lines.push(\" else\");\n lines.push(\" ggt --__complete $tokens $current 2>/dev/null\");\n lines.push(\" end\");\n lines.push(\"end\");\n lines.push(\"\");\n\n // helper function for subcommand detection\n const subcommandParents = data.commands.filter((c) => c.subcommands.length > 0);\n if (subcommandParents.length > 0) {\n lines.push(\"# Helper: check if a specific subcommand of a parent command has been entered\");\n lines.push(\"# Usage: __ggt_seen_subcommand parentName [parentAlias...] -- subName [subAlias...] -- valueFlagName ...\");\n lines.push(\"function __ggt_seen_subcommand\");\n lines.push(\" set -l parents\");\n lines.push(\" set -l subs\");\n lines.push(\" set -l vflags\");\n lines.push(\" set -l sep_count 0\");\n lines.push(\" for arg in $argv\");\n lines.push(\" if test $arg = '--'\");\n lines.push(\" set sep_count (math $sep_count + 1)\");\n lines.push(\" else if test $sep_count -eq 2\");\n lines.push(\" set -a vflags $arg\");\n lines.push(\" else if test $sep_count -eq 1\");\n lines.push(\" set -a subs $arg\");\n lines.push(\" else\");\n lines.push(\" set -a parents $arg\");\n lines.push(\" end\");\n lines.push(\" end\");\n lines.push(\" set -l cmd (commandline -opc)\");\n lines.push(\" set -l found_parent 0\");\n lines.push(\" set -l skip_next 0\");\n lines.push(\" for word in $cmd\");\n lines.push(\" if test $found_parent -eq 1\");\n lines.push(\" if test $skip_next -eq 1\");\n lines.push(\" set skip_next 0\");\n lines.push(\" continue\");\n lines.push(\" end\");\n lines.push(\" if set -q vflags[1]; and contains -- $word $vflags\");\n lines.push(\" set skip_next 1\");\n lines.push(\" continue\");\n lines.push(\" end\");\n lines.push(\" if contains -- $word $subs\");\n lines.push(\" return 0\");\n lines.push(\" end\");\n lines.push(\" end\");\n lines.push(\" if contains -- $word $parents\");\n lines.push(\" set found_parent 1\");\n lines.push(\" end\");\n lines.push(\" end\");\n lines.push(\" return 1\");\n lines.push(\"end\");\n lines.push(\"\");\n\n lines.push(\"# Helper: check if we are positioned for a subcommand (parent seen, no subcommand yet)\");\n lines.push(\"# Usage: __ggt_needs_subcommand parentName [parentAlias...] -- valueFlagName ...\");\n lines.push(\"function __ggt_needs_subcommand\");\n lines.push(\" set -l parents\");\n lines.push(\" set -l vflags\");\n lines.push(\" set -l after_sep 0\");\n lines.push(\" for a in $argv\");\n lines.push(\" if test $a = '--'\");\n lines.push(\" set after_sep 1\");\n lines.push(\" else if test $after_sep -eq 1\");\n lines.push(\" set -a vflags $a\");\n lines.push(\" else\");\n lines.push(\" set -a parents $a\");\n lines.push(\" end\");\n lines.push(\" end\");\n lines.push(\" set -l cmd (commandline -opc)\");\n lines.push(\" set -l found_parent 0\");\n lines.push(\" set -l skip_next 0\");\n lines.push(\" for word in $cmd\");\n lines.push(\" if test $found_parent -eq 1\");\n lines.push(\" if test $skip_next -eq 1\");\n lines.push(\" set skip_next 0\");\n lines.push(\" continue\");\n lines.push(\" end\");\n lines.push(\" if contains -- $word $vflags\");\n lines.push(\" set skip_next 1\");\n lines.push(\" continue\");\n lines.push(\" end\");\n lines.push(\" if string match -q -- '-*' $word\");\n lines.push(\" continue\");\n lines.push(\" end\");\n lines.push(\" return 1\");\n lines.push(\" end\");\n lines.push(\" if contains -- $word $parents\");\n lines.push(\" set found_parent 1\");\n lines.push(\" end\");\n lines.push(\" end\");\n lines.push(\" # parent was found but no subcommand yet\");\n lines.push(\" if test $found_parent -eq 1\");\n lines.push(\" return 0\");\n lines.push(\" end\");\n lines.push(\" return 1\");\n lines.push(\"end\");\n lines.push(\"\");\n }\n\n // root flags\n lines.push(\"# Root flags\");\n for (const flag of data.rootFlags) {\n lines.push(...fishFlagLine(flag, \"__fish_use_subcommand\"));\n }\n lines.push(\"\");\n\n // commands\n lines.push(\"# Commands\");\n for (const cmd of data.commands) {\n const desc = escapeFish(cmd.description);\n lines.push(`complete -c ggt -n '__fish_use_subcommand' -a '${cmd.name}' -d '${desc}'`);\n for (const alias of cmd.aliases) {\n lines.push(`complete -c ggt -n '__fish_use_subcommand' -a '${alias}' -d '${desc}'`);\n }\n }\n lines.push(\"\");\n\n // per-command flags and subcommands\n for (const cmd of data.commands) {\n lines.push(`# ${cmd.name}`);\n const cmdNames = [cmd.name, ...cmd.aliases].join(\" \");\n\n if (cmd.subcommands.length > 0) {\n // command-level flags (available when the parent is seen)\n for (const flag of cmd.flags) {\n lines.push(...fishFlagLine(flag, `__fish_seen_subcommand_from ${cmdNames}`));\n }\n\n // subcommand names\n const vFlags = valueFlagNames(cmd.flags, data.rootFlags);\n const needsSubCond =\n vFlags.length > 0 ? `__ggt_needs_subcommand ${cmdNames} -- ${vFlags.join(\" \")}` : `__ggt_needs_subcommand ${cmdNames}`;\n for (const sub of cmd.subcommands) {\n const desc = escapeFish(sub.description);\n lines.push(`complete -c ggt -n '${needsSubCond}' -a '${sub.name}' -d '${desc}'`);\n for (const alias of sub.aliases) {\n lines.push(`complete -c ggt -n '${needsSubCond}' -a '${alias}' -d '${desc}'`);\n }\n }\n\n // subcommand-specific flags\n const vFlagsSuffix = vFlags.length > 0 ? ` -- ${vFlags.join(\" \")}` : \"\";\n for (const sub of cmd.subcommands) {\n const subNames = [sub.name, ...sub.aliases].join(\" \");\n for (const flag of sub.flags) {\n lines.push(...fishFlagLine(flag, `__ggt_seen_subcommand ${cmdNames} -- ${subNames}${vFlagsSuffix}`));\n }\n }\n\n // root flags in parent and subcommand contexts\n for (const flag of data.rootFlags) {\n lines.push(...fishFlagLine(flag, `__fish_seen_subcommand_from ${cmdNames}`));\n for (const sub of cmd.subcommands) {\n const subNames = [sub.name, ...sub.aliases].join(\" \");\n lines.push(...fishFlagLine(flag, `__ggt_seen_subcommand ${cmdNames} -- ${subNames}${vFlagsSuffix}`));\n }\n }\n } else {\n for (const flag of cmd.flags) {\n lines.push(...fishFlagLine(flag, `__fish_seen_subcommand_from ${cmdNames}`));\n }\n\n // root flags in command context\n for (const flag of data.rootFlags) {\n lines.push(...fishFlagLine(flag, `__fish_seen_subcommand_from ${cmdNames}`));\n }\n }\n\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n};\n\n/**\n * Generates `complete` lines for a flag -- one per long name (canonical + long aliases).\n */\nconst fishFlagLine = (flag: FlagDef, condition: string): string[] => {\n const longNames = [flag.name.replace(/^--/, \"\")];\n const shortParts: string[] = [];\n\n for (const alias of flag.aliases) {\n if (alias.startsWith(\"--\")) {\n longNames.push(alias.replace(/^--/, \"\"));\n } else if (alias.startsWith(\"-\")) {\n shortParts.push(`-s ${alias.replace(/^-/, \"\")}`);\n }\n }\n\n const commonParts: string[] = [];\n\n if (flag.type === \"string\" || flag.type === \"number\") {\n if (flag.hasCompleter) {\n commonParts.push(\"-rfa '(__ggt_complete)'\");\n } else if (flag.valueName === \"path\") {\n commonParts.push(\"-rF\");\n } else {\n commonParts.push(\"-x\");\n }\n }\n\n if (flag.description) {\n commonParts.push(`-d '${escapeFish(flag.description)}'`);\n }\n\n return longNames.map((name, i) => {\n const parts = [`complete -c ggt -n '${condition}'`, `-l ${name}`];\n // only attach short aliases to the first (canonical) long name\n if (i === 0) {\n parts.push(...shortParts);\n }\n parts.push(...commonParts);\n return parts.join(\" \");\n });\n};\n\n/**\n * Escapes single quotes for fish shell strings.\n *\n * Fish doesn't support backslash-escaped quotes inside single-quoted\n * strings. Instead, end the quote, insert an escaped quote, and\n * restart: 'it'\\''s' -> it's\n */\nconst escapeFish = (str: string): string => {\n return str.replace(/'/g, \"'\\\\''\");\n};\n","import type { FlagDef } from \"../command/flag.ts\";\nimport type { CommandDef, CompletionData } from \"./completions.ts\";\n\n/**\n * Renders flag specs with trailing backslash continuation, indented for use\n * inside an `_arguments` block.\n */\nconst renderFlagSpecs = (flagSpecs: string[]): string[] => {\n return flagSpecs.map((spec, i) => {\n const suffix = i < flagSpecs.length - 1 ? \" \\\\\" : \"\";\n return ` ${spec}${suffix}`;\n });\n};\n\n/**\n * Generates a complete Zsh completion script for ggt.\n */\nexport const generateZshCompletions = (data: CompletionData): string => {\n const lines: string[] = [];\n\n lines.push(\"#compdef ggt\");\n lines.push(\"\");\n\n // check if any flag has a dynamic completer\n const hasDynamicFlags =\n data.rootFlags.some((f) => f.hasCompleter) ||\n data.commands.some((c) => c.flags.some((f) => f.hasCompleter) || c.subcommands.some((s) => s.flags.some((f) => f.hasCompleter)));\n\n if (hasDynamicFlags) {\n lines.push(\"_ggt_dynamic() {\");\n lines.push(\" local -a results\");\n lines.push(' results=(${(f)\"$(ggt --__complete \"${_ggt_words[@]:1}\" 2>/dev/null)\"})');\n lines.push(\" compadd -a results\");\n lines.push(\"}\");\n lines.push(\"\");\n }\n\n // helper functions for commands with subcommands\n for (const cmd of data.commands) {\n if (cmd.subcommands.length > 0) {\n lines.push(...generateSubcommandHelper(cmd, data.rootFlags));\n lines.push(\"\");\n }\n }\n\n // main _ggt function\n lines.push(\"_ggt() {\");\n lines.push(\" local -a commands\");\n lines.push(\" local state\");\n if (hasDynamicFlags) {\n lines.push(\" # Save the full word list before _arguments -C locally scopes $words\");\n lines.push(' local -a _ggt_words=(\"${words[@]}\")');\n }\n lines.push(\"\");\n lines.push(\" _arguments -C \\\\\");\n\n // root flags\n for (const flag of data.rootFlags) {\n lines.push(` ${zshFlagSpec(flag)} \\\\`);\n }\n\n lines.push(\" '1:command:->command' \\\\\");\n lines.push(\" '*::arg:->args'\");\n lines.push(\"\");\n\n // command state\n lines.push(\" case $state in\");\n lines.push(\" command)\");\n lines.push(\" commands=(\");\n for (const cmd of data.commands) {\n lines.push(` '${cmd.name}:${escapeZsh(cmd.description)}'`);\n for (const alias of cmd.aliases) {\n lines.push(` '${alias}:${escapeZsh(cmd.description)}'`);\n }\n }\n lines.push(\" )\");\n lines.push(\" _describe -t commands 'ggt command' commands\");\n lines.push(\" ;;\");\n\n // args state\n lines.push(\" args)\");\n lines.push(\" case $words[1] in\");\n\n for (const cmd of data.commands) {\n if (cmd.subcommands.length > 0) {\n lines.push(` ${[cmd.name, ...cmd.aliases].join(\"|\")})`);\n lines.push(` _ggt_${sanitizeName(cmd.name)}`);\n lines.push(\" ;;\");\n } else {\n const allFlags = [...data.rootFlags, ...cmd.flags];\n lines.push(` ${[cmd.name, ...cmd.aliases].join(\"|\")})`);\n lines.push(\" _arguments \\\\\");\n lines.push(...renderFlagSpecs(allFlags.map((f) => zshFlagSpec(f))));\n lines.push(\" ;;\");\n }\n }\n\n lines.push(\" esac\");\n lines.push(\" ;;\");\n lines.push(\" esac\");\n lines.push(\"}\");\n lines.push(\"\");\n lines.push('_ggt \"$@\"');\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n};\n\n/**\n * Generates a helper function for a command with subcommands.\n */\nconst generateSubcommandHelper = (cmd: CommandDef, rootFlags: FlagDef[]): string[] => {\n const fnName = `_ggt_${sanitizeName(cmd.name)}`;\n const lines: string[] = [];\n\n lines.push(`${fnName}() {`);\n lines.push(\" local -a subcommands\");\n lines.push(\" local state\");\n lines.push(\"\");\n lines.push(\" _arguments -C \\\\\");\n\n const parentFlags = [...rootFlags, ...cmd.flags];\n for (const flag of parentFlags) {\n lines.push(` ${zshFlagSpec(flag)} \\\\`);\n }\n\n lines.push(\" '1:subcommand:->subcommand' \\\\\");\n lines.push(\" '*::arg:->args'\");\n lines.push(\"\");\n\n lines.push(\" case $state in\");\n lines.push(\" subcommand)\");\n lines.push(\" subcommands=(\");\n for (const sub of cmd.subcommands) {\n lines.push(` '${sub.name}:${escapeZsh(sub.description)}'`);\n for (const alias of sub.aliases) {\n lines.push(` '${alias}:${escapeZsh(sub.description)}'`);\n }\n }\n lines.push(\" )\");\n lines.push(` _describe -t subcommands '${cmd.name} subcommand' subcommands`);\n lines.push(\" ;;\");\n\n lines.push(\" args)\");\n lines.push(\" case $words[1] in\");\n\n for (const sub of cmd.subcommands) {\n const allFlags = [...rootFlags, ...cmd.flags, ...sub.flags];\n lines.push(` ${[sub.name, ...sub.aliases].join(\"|\")})`);\n if (allFlags.length > 0) {\n lines.push(\" _arguments \\\\\");\n lines.push(...renderFlagSpecs(allFlags.map((f) => zshFlagSpec(f))));\n }\n lines.push(\" ;;\");\n }\n\n lines.push(\" esac\");\n lines.push(\" ;;\");\n lines.push(\" esac\");\n lines.push(\"}\");\n\n return lines;\n};\n\n/**\n * Formats a FlagDef into a zsh _arguments spec string.\n */\nconst zshFlagSpec = (flag: FlagDef): string => {\n const desc = escapeZsh(flag.description);\n const needsArg = flag.type === \"string\" || flag.type === \"number\";\n\n // build exclusion group from aliases\n const allNames = [flag.name, ...flag.aliases];\n const exclusion = allNames.length > 1 ? `'(${allNames.join(\" \")})'` : \"\";\n\n // trailing space in \":value: \" signals free-form arg to zsh _arguments\n const argSuffix = needsArg ? (flag.hasCompleter ? \":value:_ggt_dynamic\" : flag.valueName === \"path\" ? \":value:_files\" : \":value: \") : \"\";\n\n if (allNames.length === 1) {\n return `${exclusion}'${flag.name}[${desc}]${argSuffix}'`;\n }\n\n // generate one spec per alias so zsh sees all forms\n const specs: string[] = [];\n for (const name of allNames) {\n specs.push(`${exclusion}'${name}[${desc}]${argSuffix}'`);\n }\n return specs.join(\" \\\\\\n \");\n};\n\n/**\n * Escapes special characters for zsh completion descriptions.\n *\n * - Single quotes are escaped by ending the string, inserting `\\'`, and restarting\n * - Brackets are escaped because they delimit flag descriptions in `_arguments` specs\n * - Colons are escaped because they are significant delimiters in `_arguments`\n * and `_describe` entries (e.g., `'name:description'`)\n */\nconst escapeZsh = (str: string): string => {\n return str.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"'\\\\''\").replace(/\\[/g, \"\\\\[\").replace(/\\]/g, \"\\\\]\").replace(/:/g, \"\\\\:\");\n};\n\n/**\n * Sanitizes a command name for use as a function name (e.g., agent-plugin -> agent_plugin).\n */\nconst sanitizeName = (name: string): string => {\n return name.replace(/-/g, \"_\");\n};\n","import { defineCommand } from \"../services/command/command.ts\";\nimport { generateBashCompletions } from \"../services/completion/bash.ts\";\nimport { getCompletionData } from \"../services/completion/completions.ts\";\nimport { generateFishCompletions } from \"../services/completion/fish.ts\";\nimport { generateZshCompletions } from \"../services/completion/zsh.ts\";\nimport colors from \"../services/output/colors.ts\";\nimport { sprint } from \"../services/output/sprint.ts\";\n\nexport default defineCommand({\n name: \"completion\",\n description: \"Generate shell completion scripts\",\n details: sprint`\n Generates a completion script for your shell so that ggt commands,\n subcommands, and flags are suggested when you press Tab. Run one of the\n subcommands below and follow the installation instructions to enable it.\n `,\n examples: [\"ggt completion bash\", \"ggt completion zsh\", \"ggt completion fish\"],\n sections: [\n {\n title: \"Setup\",\n content: sprint`\n Choose the section that matches your shell. After following the steps,\n open a new terminal (or reload your shell config) for completions to\n take effect. Re-run the generation command after updating ggt.\n\n If ggt is not installed globally, you can use ${colors.identifier(\"npx ggt\")} in place\n of ${colors.identifier(\"ggt\")} in the commands below.\n\n Bash\n ${colors.identifier(\"mkdir -p ~/.local/share/ggt\")}\n ${colors.identifier(\"ggt completion bash > ~/.local/share/ggt/completion.bash\")}\n\n Then add this line to your ${colors.identifier(\"~/.bashrc\")} (or ${colors.identifier(\"~/.bash_profile\")} on macOS):\n ${colors.identifier('source \"$HOME/.local/share/ggt/completion.bash\"')}\n\n Zsh\n ${colors.identifier(\"mkdir -p ~/.local/share/ggt\")}\n ${colors.identifier(\"ggt completion zsh > ~/.local/share/ggt/completion.zsh\")}\n\n Then add this line to your ${colors.identifier(\"~/.zshrc\")}:\n ${colors.identifier('source \"$HOME/.local/share/ggt/completion.zsh\"')}\n\n If you get \"command not found: compdef\", add this before the line above:\n ${colors.identifier(\"autoload -Uz compinit && compinit\")}\n\n Fish\n ${colors.identifier(\"ggt completion fish > ~/.config/fish/completions/ggt.fish\")}\n `,\n },\n ],\n subcommands: (sub) => ({\n bash: sub({\n description: \"Generate bash completion script\",\n run: async () => {\n const data = await getCompletionData();\n process.stdout.write(generateBashCompletions(data));\n },\n }),\n zsh: sub({\n description: \"Generate zsh completion script\",\n run: async () => {\n const data = await getCompletionData();\n process.stdout.write(generateZshCompletions(data));\n },\n }),\n fish: sub({\n description: \"Generate fish completion script\",\n run: async () => {\n const data = await getCompletionData();\n process.stdout.write(generateFishCompletions(data));\n },\n }),\n }),\n});\n"],"mappings":"uXAQA,MAAa,GAAkB,GAAG,IAAoC,CACpE,IAAM,EAAkB,EAAE,CAC1B,IAAK,IAAM,KAAS,EAClB,IAAK,IAAM,KAAK,GACV,EAAE,OAAS,UAAY,EAAE,OAAS,WACpC,EAAM,KAAK,EAAE,KAAM,GAAG,EAAE,QAAQ,CAItC,OAAO,GA0BI,EAAoB,SAAqC,CACpE,IAAM,EAAY,EAAaA,EAAa,CAAC,OAAQ,GAAM,CAAC,EAAE,OAAO,CAE/D,EAAyB,EAAE,CAE3B,EAAU,MAAM,QAAQ,IAAI,EAAS,IAAK,GAAQ,EAAc,EAAI,CAAC,CAAC,CAC5E,IAAK,GAAM,CAAC,EAAG,KAAQ,EAAS,SAAS,CAAE,CACzC,IAAM,EAAM,EAAQ,GACpB,GAAI,EAAI,OACN,SAGF,IAAM,EAAQ,EADS,EAAe,EAAI,OAAS,EAAE,CAAC,CACZ,CAAC,OAAQ,GAAM,CAAC,EAAE,OAAO,CAC7D,EAAc,EAAI,YAClB,EAAyC,OAAO,QAAQ,gBAAiB,GAAO,EAAI,YAAc,EAAI,YAAc,EAAE,CAAC,CAAC,KAC3H,CAAC,EAAM,MAAU,CAChB,OACA,YAAa,EAAI,YACjB,QAAU,EAAwC,SAAS,OAAO,EAAI,EAAE,CACxE,MAAO,EAAa,EAAI,OAAS,EAAE,CAAC,CAAC,OAAQ,GAAM,CAAC,EAAE,OAAO,CAC9D,EACF,CAED,EAAS,KAAK,CAAE,KAAM,EAAK,cAAa,QAAU,EAAwC,SAAS,OAAO,EAAI,EAAE,CAAE,QAAO,cAAa,CAAC,CAGzI,MAAO,CAAE,YAAW,WAAU,EC/DnB,EAA2B,GAAiC,CACvE,IAAM,EAAkB,EAAE,CAE1B,EAAM,KAAK,iDAAiD,CAC5D,EAAM,KAAK,GAAG,CACd,EAAM,KAAK,uBAAuB,CAClC,EAAM,KAAK,0CAA0C,CACrD,EAAM,KAAK,GAAG,CAGd,IAAM,EAAiB,IAAI,IACrB,EAAY,IAAI,IAChB,EAAkB,IAAI,IACtB,EAAiB,GAA2B,CAChD,IAAK,IAAM,KAAK,EACd,GAAI,EAAE,aAAc,CAClB,EAAe,IAAI,EAAE,KAAK,CAC1B,IAAK,IAAM,KAAK,EAAE,QAAS,EAAe,IAAI,EAAE,SACvC,EAAE,YAAc,OAAQ,CACjC,EAAU,IAAI,EAAE,KAAK,CACrB,IAAK,IAAM,KAAK,EAAE,QAAS,EAAU,IAAI,EAAE,SAClC,EAAE,OAAS,UAAY,EAAE,OAAS,SAAU,CACrD,EAAgB,IAAI,EAAE,KAAK,CAC3B,IAAK,IAAM,KAAK,EAAE,QAAS,EAAgB,IAAI,EAAE,GAIvD,EAAc,EAAK,UAAU,CAC7B,IAAK,IAAM,KAAO,EAAK,SAAU,CAC/B,EAAc,EAAI,MAAM,CACxB,IAAK,IAAM,KAAO,EAAI,YACpB,EAAc,EAAI,MAAM,EAIxB,EAAe,KAAO,GAAK,EAAU,KAAO,GAAK,EAAgB,KAAO,KAC1E,EAAM,KAAK,6CAA6C,CACxD,EAAM,KAAK,GAAG,CACd,EAAM,KAAK,oBAAoB,CAC3B,EAAe,KAAO,IACxB,EAAM,KAAK,OAAO,CAAC,GAAG,EAAe,CAAC,KAAK,IAAI,CAAC,GAAG,CACnD,EAAM,KAAK,yBAAyB,CACpC,EAAM,KAAK,yEAAyE,CACpF,EAAM,KAAK,kBAAkB,EAE3B,EAAU,KAAO,IACnB,EAAM,KAAK,OAAO,CAAC,GAAG,EAAU,CAAC,KAAK,IAAI,CAAC,GAAG,CAC9C,EAAM,KAAK,4CAA4C,CACvD,EAAM,KAAK,kBAAkB,EAE3B,EAAgB,KAAO,IACzB,EAAM,KAAK,OAAO,CAAC,GAAG,EAAgB,CAAC,KAAK,IAAI,CAAC,GAAG,CACpD,EAAM,KAAK,kBAAkB,EAE/B,EAAM,KAAK,SAAS,CACpB,EAAM,KAAK,GAAG,EAGhB,IAAM,EAAgB,EAAU,EAAK,UAAU,CACzC,EAAe,EAAK,SAAS,QAAS,GAAM,CAAC,EAAE,KAAM,GAAG,EAAE,QAAQ,CAAC,CAGzE,EAAM,KAAK,qCAAqC,CAChD,EAAM,KAAK,gCAAgC,CAAC,GAAG,EAAc,GAAG,EAAc,CAAC,KAAK,IAAI,CAAC,eAAe,CACxG,EAAM,KAAK,aAAa,CACxB,EAAM,KAAK,OAAO,CAClB,EAAM,KAAK,GAAG,CAGd,EAAM,KAAK,+BAA+B,CAE1C,IAAK,IAAM,KAAO,EAAK,SACrB,GAAI,EAAI,YAAY,OAAS,EAAG,CAC9B,EAAM,KAAK,OAAO,CAAC,EAAI,KAAM,GAAG,EAAI,QAAQ,CAAC,KAAK,IAAI,CAAC,GAAG,CAI1D,IAAM,EAAgB,EAAe,EAAK,UAAW,EAAI,MAAM,CAI/D,EAAM,KAAK,uBAAuB,CAClC,EAAM,KAAK,4BAA4B,CACvC,EAAM,KAAK,6CAA6C,CACxD,EAAM,KAAK,qCAAqC,CAChD,EAAM,KAAK,4CAA4C,CACvD,EAAM,KAAK,0BAA0B,CACrC,EAAM,KAAK,qBAAqB,CAChC,EAAM,KAAK,aAAa,CACpB,EAAc,OAAS,IACzB,EAAM,KAAK,uBAAuB,CAClC,EAAM,KAAK,aAAa,EAAc,KAAK,IAAI,CAAC,8BAA8B,CAC9E,EAAM,KAAK,eAAe,EAE5B,EAAM,KAAK,oCAAoC,CAC/C,EAAM,KAAK,yBAAyB,CACpC,EAAM,KAAK,kBAAkB,CAC7B,EAAM,KAAK,aAAa,CACxB,EAAM,KAAK,aAAa,CACxB,EAAM,KAAK,GAAG,CAEd,IAAM,EAAW,EAAI,YAAY,QAAS,GAAM,CAAC,EAAE,KAAM,GAAG,EAAE,QAAQ,CAAC,CACjE,EAAc,EAAU,EAAI,MAAM,CAExC,EAAM,KAAK,qCAAqC,CAChD,EAAM,KAAK,oCAAoC,CAAC,GAAG,EAAU,GAAG,EAAa,GAAG,EAAc,CAAC,KAAK,IAAI,CAAC,eAAe,CACxH,EAAM,KAAK,aAAa,CACxB,EAAM,KAAK,6BAA6B,CAExC,IAAK,IAAM,KAAO,EAAI,YAAa,CACjC,IAAM,EAAc,EAAU,CAAC,GAAG,EAAI,MAAO,GAAG,EAAI,MAAM,CAAC,CAC3D,EAAM,KAAK,aAAa,CAAC,EAAI,KAAM,GAAG,EAAI,QAAQ,CAAC,KAAK,IAAI,CAAC,GAAG,CAChE,EAAM,KAAK,wCAAwC,CAAC,GAAG,EAAa,GAAG,EAAc,CAAC,KAAK,IAAI,CAAC,eAAe,CAC/G,EAAM,KAAK,iBAAiB,CAG9B,EAAM,KAAK,eAAe,CAC1B,EAAM,KAAK,wCAAwC,CAAC,GAAG,EAAa,GAAG,EAAc,CAAC,KAAK,IAAI,CAAC,eAAe,CAC/G,EAAM,KAAK,iBAAiB,CAC5B,EAAM,KAAK,eAAe,CAC1B,EAAM,KAAK,WAAW,CACtB,EAAM,KAAK,WAAW,KACjB,CACL,IAAM,EAAc,EAAU,EAAI,MAAM,CACxC,EAAM,KAAK,OAAO,CAAC,EAAI,KAAM,GAAG,EAAI,QAAQ,CAAC,KAAK,IAAI,CAAC,GAAG,CAC1D,EAAM,KAAK,kCAAkC,CAAC,GAAG,EAAa,GAAG,EAAc,CAAC,KAAK,IAAI,CAAC,eAAe,CACzG,EAAM,KAAK,WAAW,CAU1B,OANA,EAAM,KAAK,SAAS,CACpB,EAAM,KAAK,IAAI,CACf,EAAM,KAAK,GAAG,CACd,EAAM,KAAK,mCAAmC,CAC9C,EAAM,KAAK,GAAG,CAEP,EAAM,KAAK;EAAK,ECxIZ,EAA2B,GAAiC,CACvE,IAAM,EAAkB,EAAE,CAE1B,EAAM,KAAK,4BAA4B,CACvC,EAAM,KAAK,GAAG,CACd,EAAM,KAAK,wCAAwC,CACnD,EAAM,KAAK,qBAAqB,CAChC,EAAM,KAAK,GAAG,CAQd,EAAM,KAAK,gEAAgE,CAC3E,EAAM,KAAK,0BAA0B,CACrC,EAAM,KAAK,0CAA0C,CACrD,EAAM,KAAK,qCAAqC,CAChD,EAAM,KAAK,wEAAwE,CACnF,EAAM,KAAK,6FAA6F,CACxG,EAAM,KAAK,wCAAwC,CACnD,EAAM,KAAK,uDAAuD,CAClE,EAAM,KAAK,SAAS,CACpB,EAAM,KAAK,oDAAoD,CAC/D,EAAM,KAAK,QAAQ,CACnB,EAAM,KAAK,MAAM,CACjB,EAAM,KAAK,GAAG,CAGY,EAAK,SAAS,OAAQ,GAAM,EAAE,YAAY,OAAS,EAAE,CACzD,OAAS,IAC7B,EAAM,KAAK,gFAAgF,CAC3F,EAAM,KAAK,2GAA2G,CACtH,EAAM,KAAK,iCAAiC,CAC5C,EAAM,KAAK,mBAAmB,CAC9B,EAAM,KAAK,gBAAgB,CAC3B,EAAM,KAAK,kBAAkB,CAC7B,EAAM,KAAK,uBAAuB,CAClC,EAAM,KAAK,qBAAqB,CAChC,EAAM,KAAK,0BAA0B,CACrC,EAAM,KAAK,4CAA4C,CACvD,EAAM,KAAK,oCAAoC,CAC/C,EAAM,KAAK,2BAA2B,CACtC,EAAM,KAAK,oCAAoC,CAC/C,EAAM,KAAK,yBAAyB,CACpC,EAAM,KAAK,WAAW,CACtB,EAAM,KAAK,4BAA4B,CACvC,EAAM,KAAK,UAAU,CACrB,EAAM,KAAK,QAAQ,CACnB,EAAM,KAAK,kCAAkC,CAC7C,EAAM,KAAK,0BAA0B,CACrC,EAAM,KAAK,uBAAuB,CAClC,EAAM,KAAK,qBAAqB,CAChC,EAAM,KAAK,kCAAkC,CAC7C,EAAM,KAAK,iCAAiC,CAC5C,EAAM,KAAK,0BAA0B,CACrC,EAAM,KAAK,mBAAmB,CAC9B,EAAM,KAAK,YAAY,CACvB,EAAM,KAAK,2DAA2D,CACtE,EAAM,KAAK,0BAA0B,CACrC,EAAM,KAAK,mBAAmB,CAC9B,EAAM,KAAK,YAAY,CACvB,EAAM,KAAK,mCAAmC,CAC9C,EAAM,KAAK,mBAAmB,CAC9B,EAAM,KAAK,YAAY,CACvB,EAAM,KAAK,UAAU,CACrB,EAAM,KAAK,oCAAoC,CAC/C,EAAM,KAAK,2BAA2B,CACtC,EAAM,KAAK,UAAU,CACrB,EAAM,KAAK,QAAQ,CACnB,EAAM,KAAK,aAAa,CACxB,EAAM,KAAK,MAAM,CACjB,EAAM,KAAK,GAAG,CAEd,EAAM,KAAK,yFAAyF,CACpG,EAAM,KAAK,mFAAmF,CAC9F,EAAM,KAAK,kCAAkC,CAC7C,EAAM,KAAK,mBAAmB,CAC9B,EAAM,KAAK,kBAAkB,CAC7B,EAAM,KAAK,uBAAuB,CAClC,EAAM,KAAK,mBAAmB,CAC9B,EAAM,KAAK,wBAAwB,CACnC,EAAM,KAAK,wBAAwB,CACnC,EAAM,KAAK,oCAAoC,CAC/C,EAAM,KAAK,yBAAyB,CACpC,EAAM,KAAK,WAAW,CACtB,EAAM,KAAK,0BAA0B,CACrC,EAAM,KAAK,UAAU,CACrB,EAAM,KAAK,QAAQ,CACnB,EAAM,KAAK,kCAAkC,CAC7C,EAAM,KAAK,0BAA0B,CACrC,EAAM,KAAK,uBAAuB,CAClC,EAAM,KAAK,qBAAqB,CAChC,EAAM,KAAK,kCAAkC,CAC7C,EAAM,KAAK,iCAAiC,CAC5C,EAAM,KAAK,0BAA0B,CACrC,EAAM,KAAK,mBAAmB,CAC9B,EAAM,KAAK,YAAY,CACvB,EAAM,KAAK,qCAAqC,CAChD,EAAM,KAAK,0BAA0B,CACrC,EAAM,KAAK,mBAAmB,CAC9B,EAAM,KAAK,YAAY,CACvB,EAAM,KAAK,yCAAyC,CACpD,EAAM,KAAK,mBAAmB,CAC9B,EAAM,KAAK,YAAY,CACvB,EAAM,KAAK,iBAAiB,CAC5B,EAAM,KAAK,UAAU,CACrB,EAAM,KAAK,oCAAoC,CAC/C,EAAM,KAAK,2BAA2B,CACtC,EAAM,KAAK,UAAU,CACrB,EAAM,KAAK,QAAQ,CACnB,EAAM,KAAK,6CAA6C,CACxD,EAAM,KAAK,gCAAgC,CAC3C,EAAM,KAAK,eAAe,CAC1B,EAAM,KAAK,QAAQ,CACnB,EAAM,KAAK,aAAa,CACxB,EAAM,KAAK,MAAM,CACjB,EAAM,KAAK,GAAG,EAIhB,EAAM,KAAK,eAAe,CAC1B,IAAK,IAAM,KAAQ,EAAK,UACtB,EAAM,KAAK,GAAG,EAAa,EAAM,wBAAwB,CAAC,CAE5D,EAAM,KAAK,GAAG,CAGd,EAAM,KAAK,aAAa,CACxB,IAAK,IAAM,KAAO,EAAK,SAAU,CAC/B,IAAM,EAAO,EAAW,EAAI,YAAY,CACxC,EAAM,KAAK,kDAAkD,EAAI,KAAK,QAAQ,EAAK,GAAG,CACtF,IAAK,IAAM,KAAS,EAAI,QACtB,EAAM,KAAK,kDAAkD,EAAM,QAAQ,EAAK,GAAG,CAGvF,EAAM,KAAK,GAAG,CAGd,IAAK,IAAM,KAAO,EAAK,SAAU,CAC/B,EAAM,KAAK,KAAK,EAAI,OAAO,CAC3B,IAAM,EAAW,CAAC,EAAI,KAAM,GAAG,EAAI,QAAQ,CAAC,KAAK,IAAI,CAErD,GAAI,EAAI,YAAY,OAAS,EAAG,CAE9B,IAAK,IAAM,KAAQ,EAAI,MACrB,EAAM,KAAK,GAAG,EAAa,EAAM,+BAA+B,IAAW,CAAC,CAI9E,IAAM,EAAS,EAAe,EAAI,MAAO,EAAK,UAAU,CAClD,EACJ,EAAO,OAAS,EAAI,0BAA0B,EAAS,MAAM,EAAO,KAAK,IAAI,GAAK,0BAA0B,IAC9G,IAAK,IAAM,KAAO,EAAI,YAAa,CACjC,IAAM,EAAO,EAAW,EAAI,YAAY,CACxC,EAAM,KAAK,uBAAuB,EAAa,QAAQ,EAAI,KAAK,QAAQ,EAAK,GAAG,CAChF,IAAK,IAAM,KAAS,EAAI,QACtB,EAAM,KAAK,uBAAuB,EAAa,QAAQ,EAAM,QAAQ,EAAK,GAAG,CAKjF,IAAM,EAAe,EAAO,OAAS,EAAI,OAAO,EAAO,KAAK,IAAI,GAAK,GACrE,IAAK,IAAM,KAAO,EAAI,YAAa,CACjC,IAAM,EAAW,CAAC,EAAI,KAAM,GAAG,EAAI,QAAQ,CAAC,KAAK,IAAI,CACrD,IAAK,IAAM,KAAQ,EAAI,MACrB,EAAM,KAAK,GAAG,EAAa,EAAM,yBAAyB,EAAS,MAAM,IAAW,IAAe,CAAC,CAKxG,IAAK,IAAM,KAAQ,EAAK,UAAW,CACjC,EAAM,KAAK,GAAG,EAAa,EAAM,+BAA+B,IAAW,CAAC,CAC5E,IAAK,IAAM,KAAO,EAAI,YAAa,CACjC,IAAM,EAAW,CAAC,EAAI,KAAM,GAAG,EAAI,QAAQ,CAAC,KAAK,IAAI,CACrD,EAAM,KAAK,GAAG,EAAa,EAAM,yBAAyB,EAAS,MAAM,IAAW,IAAe,CAAC,OAGnG,CACL,IAAK,IAAM,KAAQ,EAAI,MACrB,EAAM,KAAK,GAAG,EAAa,EAAM,+BAA+B,IAAW,CAAC,CAI9E,IAAK,IAAM,KAAQ,EAAK,UACtB,EAAM,KAAK,GAAG,EAAa,EAAM,+BAA+B,IAAW,CAAC,CAIhF,EAAM,KAAK,GAAG,CAGhB,OAAO,EAAM,KAAK;EAAK,EAMnB,GAAgB,EAAe,IAAgC,CACnE,IAAM,EAAY,CAAC,EAAK,KAAK,QAAQ,MAAO,GAAG,CAAC,CAC1C,EAAuB,EAAE,CAE/B,IAAK,IAAM,KAAS,EAAK,QACnB,EAAM,WAAW,KAAK,CACxB,EAAU,KAAK,EAAM,QAAQ,MAAO,GAAG,CAAC,CAC/B,EAAM,WAAW,IAAI,EAC9B,EAAW,KAAK,MAAM,EAAM,QAAQ,KAAM,GAAG,GAAG,CAIpD,IAAM,EAAwB,EAAE,CAgBhC,OAdI,EAAK,OAAS,UAAY,EAAK,OAAS,YACtC,EAAK,aACP,EAAY,KAAK,0BAA0B,CAClC,EAAK,YAAc,OAC5B,EAAY,KAAK,MAAM,CAEvB,EAAY,KAAK,KAAK,EAItB,EAAK,aACP,EAAY,KAAK,OAAO,EAAW,EAAK,YAAY,CAAC,GAAG,CAGnD,EAAU,KAAK,EAAM,IAAM,CAChC,IAAM,EAAQ,CAAC,uBAAuB,EAAU,GAAI,MAAM,IAAO,CAMjE,OAJI,IAAM,GACR,EAAM,KAAK,GAAG,EAAW,CAE3B,EAAM,KAAK,GAAG,EAAY,CACnB,EAAM,KAAK,IAAI,EACtB,EAUE,EAAc,GACX,EAAI,QAAQ,KAAM,QAAQ,CCrP7B,EAAmB,GAChB,EAAU,KAAK,EAAM,IAEnB,eAAe,IADP,EAAI,EAAU,OAAS,EAAI,MAAQ,KAElD,CAMS,EAA0B,GAAiC,CACtE,IAAM,EAAkB,EAAE,CAE1B,EAAM,KAAK,eAAe,CAC1B,EAAM,KAAK,GAAG,CAGd,IAAM,EACJ,EAAK,UAAU,KAAM,GAAM,EAAE,aAAa,EAC1C,EAAK,SAAS,KAAM,GAAM,EAAE,MAAM,KAAM,GAAM,EAAE,aAAa,EAAI,EAAE,YAAY,KAAM,GAAM,EAAE,MAAM,KAAM,GAAM,EAAE,aAAa,CAAC,CAAC,CAE9H,IACF,EAAM,KAAK,mBAAmB,CAC9B,EAAM,KAAK,qBAAqB,CAChC,EAAM,KAAK,2EAA2E,CACtF,EAAM,KAAK,uBAAuB,CAClC,EAAM,KAAK,IAAI,CACf,EAAM,KAAK,GAAG,EAIhB,IAAK,IAAM,KAAO,EAAK,SACjB,EAAI,YAAY,OAAS,IAC3B,EAAM,KAAK,GAAG,EAAyB,EAAK,EAAK,UAAU,CAAC,CAC5D,EAAM,KAAK,GAAG,EAKlB,EAAM,KAAK,WAAW,CACtB,EAAM,KAAK,sBAAsB,CACjC,EAAM,KAAK,gBAAgB,CACvB,IACF,EAAM,KAAK,yEAAyE,CACpF,EAAM,KAAK,wCAAwC,EAErD,EAAM,KAAK,GAAG,CACd,EAAM,KAAK,qBAAqB,CAGhC,IAAK,IAAM,KAAQ,EAAK,UACtB,EAAM,KAAK,OAAO,EAAY,EAAK,CAAC,KAAK,CAG3C,EAAM,KAAK,+BAA+B,CAC1C,EAAM,KAAK,sBAAsB,CACjC,EAAM,KAAK,GAAG,CAGd,EAAM,KAAK,mBAAmB,CAC9B,EAAM,KAAK,eAAe,CAC1B,EAAM,KAAK,mBAAmB,CAC9B,IAAK,IAAM,KAAO,EAAK,SAAU,CAC/B,EAAM,KAAK,YAAY,EAAI,KAAK,GAAG,EAAU,EAAI,YAAY,CAAC,GAAG,CACjE,IAAK,IAAM,KAAS,EAAI,QACtB,EAAM,KAAK,YAAY,EAAM,GAAG,EAAU,EAAI,YAAY,CAAC,GAAG,CAGlE,EAAM,KAAK,UAAU,CACrB,EAAM,KAAK,qDAAqD,CAChE,EAAM,KAAK,WAAW,CAGtB,EAAM,KAAK,YAAY,CACvB,EAAM,KAAK,0BAA0B,CAErC,IAAK,IAAM,KAAO,EAAK,SACrB,GAAI,EAAI,YAAY,OAAS,EAC3B,EAAM,KAAK,WAAW,CAAC,EAAI,KAAM,GAAG,EAAI,QAAQ,CAAC,KAAK,IAAI,CAAC,GAAG,CAC9D,EAAM,KAAK,kBAAkB,EAAa,EAAI,KAAK,GAAG,CACtD,EAAM,KAAK,eAAe,KACrB,CACL,IAAM,EAAW,CAAC,GAAG,EAAK,UAAW,GAAG,EAAI,MAAM,CAClD,EAAM,KAAK,WAAW,CAAC,EAAI,KAAM,GAAG,EAAI,QAAQ,CAAC,KAAK,IAAI,CAAC,GAAG,CAC9D,EAAM,KAAK,0BAA0B,CACrC,EAAM,KAAK,GAAG,EAAgB,EAAS,IAAK,GAAM,EAAY,EAAE,CAAC,CAAC,CAAC,CACnE,EAAM,KAAK,eAAe,CAY9B,OARA,EAAM,KAAK,aAAa,CACxB,EAAM,KAAK,WAAW,CACtB,EAAM,KAAK,SAAS,CACpB,EAAM,KAAK,IAAI,CACf,EAAM,KAAK,GAAG,CACd,EAAM,KAAK,YAAY,CACvB,EAAM,KAAK,GAAG,CAEP,EAAM,KAAK;EAAK,EAMnB,GAA4B,EAAiB,IAAmC,CACpF,IAAM,EAAS,QAAQ,EAAa,EAAI,KAAK,GACvC,EAAkB,EAAE,CAE1B,EAAM,KAAK,GAAG,EAAO,MAAM,CAC3B,EAAM,KAAK,yBAAyB,CACpC,EAAM,KAAK,gBAAgB,CAC3B,EAAM,KAAK,GAAG,CACd,EAAM,KAAK,qBAAqB,CAEhC,IAAM,EAAc,CAAC,GAAG,EAAW,GAAG,EAAI,MAAM,CAChD,IAAK,IAAM,KAAQ,EACjB,EAAM,KAAK,OAAO,EAAY,EAAK,CAAC,KAAK,CAG3C,EAAM,KAAK,qCAAqC,CAChD,EAAM,KAAK,sBAAsB,CACjC,EAAM,KAAK,GAAG,CAEd,EAAM,KAAK,mBAAmB,CAC9B,EAAM,KAAK,kBAAkB,CAC7B,EAAM,KAAK,sBAAsB,CACjC,IAAK,IAAM,KAAO,EAAI,YAAa,CACjC,EAAM,KAAK,YAAY,EAAI,KAAK,GAAG,EAAU,EAAI,YAAY,CAAC,GAAG,CACjE,IAAK,IAAM,KAAS,EAAI,QACtB,EAAM,KAAK,YAAY,EAAM,GAAG,EAAU,EAAI,YAAY,CAAC,GAAG,CAGlE,EAAM,KAAK,UAAU,CACrB,EAAM,KAAK,mCAAmC,EAAI,KAAK,0BAA0B,CACjF,EAAM,KAAK,WAAW,CAEtB,EAAM,KAAK,YAAY,CACvB,EAAM,KAAK,0BAA0B,CAErC,IAAK,IAAM,KAAO,EAAI,YAAa,CACjC,IAAM,EAAW,CAAC,GAAG,EAAW,GAAG,EAAI,MAAO,GAAG,EAAI,MAAM,CAC3D,EAAM,KAAK,WAAW,CAAC,EAAI,KAAM,GAAG,EAAI,QAAQ,CAAC,KAAK,IAAI,CAAC,GAAG,CAC1D,EAAS,OAAS,IACpB,EAAM,KAAK,0BAA0B,CACrC,EAAM,KAAK,GAAG,EAAgB,EAAS,IAAK,GAAM,EAAY,EAAE,CAAC,CAAC,CAAC,EAErE,EAAM,KAAK,eAAe,CAQ5B,OALA,EAAM,KAAK,aAAa,CACxB,EAAM,KAAK,WAAW,CACtB,EAAM,KAAK,SAAS,CACpB,EAAM,KAAK,IAAI,CAER,GAMH,EAAe,GAA0B,CAC7C,IAAM,EAAO,EAAU,EAAK,YAAY,CAClC,EAAW,EAAK,OAAS,UAAY,EAAK,OAAS,SAGnD,EAAW,CAAC,EAAK,KAAM,GAAG,EAAK,QAAQ,CACvC,EAAY,EAAS,OAAS,EAAI,KAAK,EAAS,KAAK,IAAI,CAAC,IAAM,GAGhE,EAAY,EAAY,EAAK,aAAe,sBAAwB,EAAK,YAAc,OAAS,gBAAkB,WAAc,GAEtI,GAAI,EAAS,SAAW,EACtB,MAAO,GAAG,EAAU,GAAG,EAAK,KAAK,GAAG,EAAK,GAAG,EAAU,GAIxD,IAAM,EAAkB,EAAE,CAC1B,IAAK,IAAM,KAAQ,EACjB,EAAM,KAAK,GAAG,EAAU,GAAG,EAAK,GAAG,EAAK,GAAG,EAAU,GAAG,CAE1D,OAAO,EAAM,KAAK;cAAoB,EAWlC,EAAa,GACV,EAAI,QAAQ,MAAO,OAAO,CAAC,QAAQ,KAAM,QAAQ,CAAC,QAAQ,MAAO,MAAM,CAAC,QAAQ,MAAO,MAAM,CAAC,QAAQ,KAAM,MAAM,CAMrH,EAAgB,GACb,EAAK,QAAQ,KAAM,IAAI,CCtMhC,IAAA,EAAe,EAAc,CAC3B,KAAM,aACN,YAAa,oCACb,QAAS,CAAM;;;;IAKf,SAAU,CAAC,sBAAuB,qBAAsB,sBAAsB,CAC9E,SAAU,CACR,CACE,MAAO,QACP,QAAS,CAAM;;;;;wDAKmCC,EAAO,WAAW,UAAU,CAAC;aACxEA,EAAO,WAAW,MAAM,CAAC;;;YAG1BA,EAAO,WAAW,8BAA8B,CAAC;YACjDA,EAAO,WAAW,2DAA2D,CAAC;;uCAEnDA,EAAO,WAAW,YAAY,CAAC,OAAOA,EAAO,WAAW,kBAAkB,CAAC;cACpGA,EAAO,WAAW,kDAAkD,CAAC;;;YAGvEA,EAAO,WAAW,8BAA8B,CAAC;YACjDA,EAAO,WAAW,yDAAyD,CAAC;;uCAEjDA,EAAO,WAAW,WAAW,CAAC;cACvDA,EAAO,WAAW,iDAAiD,CAAC;;;cAGpEA,EAAO,WAAW,oCAAoC,CAAC;;;YAGzDA,EAAO,WAAW,4DAA4D,CAAC;QAEtF,CACF,CACD,YAAc,IAAS,CACrB,KAAM,EAAI,CACR,YAAa,kCACb,IAAK,SAAY,CACf,IAAM,EAAO,MAAM,GAAmB,CACtC,QAAQ,OAAO,MAAM,EAAwB,EAAK,CAAC,EAEtD,CAAC,CACF,IAAK,EAAI,CACP,YAAa,iCACb,IAAK,SAAY,CACf,IAAM,EAAO,MAAM,GAAmB,CACtC,QAAQ,OAAO,MAAM,EAAuB,EAAK,CAAC,EAErD,CAAC,CACF,KAAM,EAAI,CACR,YAAa,kCACb,IAAK,SAAY,CACf,IAAM,EAAO,MAAM,GAAmB,CACtC,QAAQ,OAAO,MAAM,EAAwB,EAAK,CAAC,EAEtD,CAAC,CACH,EACF,CAAC"}
@@ -0,0 +1,15 @@
1
+ import"./prompt-C9nwJW0G.js";import{E as e,n as t,s as n}from"./command-2iNTc5dV.js";import"./directory-CNL03L6c.js";import"./select-Dey_sjjd.js";import{t as r}from"./table-MrBbxMay.js";import{n as i,r as a,t as o}from"./defaults-B_eD7Pia.js";var s=t({name:`configure`,description:`Manage ggt configuration`,details:e`
2
+ Options like ${n.identifier(`--telemetry`)} and ${n.identifier(`--json`)} can be persisted so they apply to every
3
+ ggt command without being passed explicitly each time. The configuration is stored
4
+ locally and can be cleared at any time.
5
+ `,examples:[`ggt configure show`,`ggt configure change`,`ggt configure clear`],subcommands:t=>({show:t({description:`Show current configured defaults`,details:e`
6
+ Prints the current configuration as a table, showing the configured value
7
+ for each supported option. Options without a configured value are omitted.
8
+ `,examples:[`ggt configure show`],run:async e=>{let t=await i(e,!1);r({json:t,headers:[`Option`,`Configured Value`],rows:[[`telemetry`,String(t.telemetry)],[`json`,String(t.json)]],borders:`thick`})}}),change:t({description:`Interactively change configuration options`,details:e`
9
+ Walks through each configurable option and lets you pick a new value.
10
+ Changes take effect for all subsequent ggt commands.
11
+ `,examples:[`ggt configure change`],run:async e=>{await a(e)}}),clear:t({description:`Remove all configured defaults`,details:e`
12
+ Removes all persisted options, restoring ggt to its default behavior. This
13
+ does not affect environment variables or login sessions.
14
+ `,examples:[`ggt configure clear`],run:async e=>{await o(e)}})})});export{s as default};
15
+ //# sourceMappingURL=configure-C8ge-2cK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure-C8ge-2cK.js","names":["colors"],"sources":["../src/commands/configure.ts"],"sourcesContent":["import { defineCommand } from \"../services/command/command.ts\";\nimport { clearDefaultsConfig, loadDefaultsConfig, promptDefaultsConfig } from \"../services/config/defaults.ts\";\nimport colors from \"../services/output/colors.ts\";\nimport { sprint } from \"../services/output/sprint.ts\";\nimport { printTable } from \"../services/output/table.ts\";\n\nexport default defineCommand({\n name: \"configure\",\n description: \"Manage ggt configuration\",\n details: sprint`\n Options like ${colors.identifier(\"--telemetry\")} and ${colors.identifier(\"--json\")} can be persisted so they apply to every\n ggt command without being passed explicitly each time. The configuration is stored\n locally and can be cleared at any time.\n `,\n examples: [\"ggt configure show\", \"ggt configure change\", \"ggt configure clear\"],\n subcommands: (sub) => ({\n show: sub({\n description: \"Show current configured defaults\",\n details: sprint`\n Prints the current configuration as a table, showing the configured value\n for each supported option. Options without a configured value are omitted.\n `,\n examples: [\"ggt configure show\"],\n run: async (ctx) => {\n const defaults = await loadDefaultsConfig(ctx, false);\n printTable({\n json: defaults,\n headers: [\"Option\", \"Configured Value\"],\n rows: [\n [\"telemetry\", String(defaults.telemetry)],\n [\"json\", String(defaults.json)],\n ],\n borders: \"thick\",\n });\n },\n }),\n change: sub({\n description: \"Interactively change configuration options\",\n details: sprint`\n Walks through each configurable option and lets you pick a new value.\n Changes take effect for all subsequent ggt commands.\n `,\n examples: [\"ggt configure change\"],\n run: async (ctx) => {\n await promptDefaultsConfig(ctx);\n },\n }),\n clear: sub({\n description: \"Remove all configured defaults\",\n details: sprint`\n Removes all persisted options, restoring ggt to its default behavior. This\n does not affect environment variables or login sessions.\n `,\n examples: [\"ggt configure clear\"],\n run: async (ctx) => {\n await clearDefaultsConfig(ctx);\n },\n }),\n }),\n});\n"],"mappings":"mPAMA,IAAA,EAAe,EAAc,CAC3B,KAAM,YACN,YAAa,2BACb,QAAS,CAAM;mBACEA,EAAO,WAAW,cAAc,CAAC,OAAOA,EAAO,WAAW,SAAS,CAAC;;;IAIrF,SAAU,CAAC,qBAAsB,uBAAwB,sBAAsB,CAC/E,YAAc,IAAS,CACrB,KAAM,EAAI,CACR,YAAa,mCACb,QAAS,CAAM;;;QAIf,SAAU,CAAC,qBAAqB,CAChC,IAAK,KAAO,IAAQ,CAClB,IAAM,EAAW,MAAM,EAAmB,EAAK,GAAM,CACrD,EAAW,CACT,KAAM,EACN,QAAS,CAAC,SAAU,mBAAmB,CACvC,KAAM,CACJ,CAAC,YAAa,OAAO,EAAS,UAAU,CAAC,CACzC,CAAC,OAAQ,OAAO,EAAS,KAAK,CAAC,CAChC,CACD,QAAS,QACV,CAAC,EAEL,CAAC,CACF,OAAQ,EAAI,CACV,YAAa,6CACb,QAAS,CAAM;;;QAIf,SAAU,CAAC,uBAAuB,CAClC,IAAK,KAAO,IAAQ,CAClB,MAAM,EAAqB,EAAI,EAElC,CAAC,CACF,MAAO,EAAI,CACT,YAAa,iCACb,QAAS,CAAM;;;QAIf,SAAU,CAAC,sBAAsB,CACjC,IAAK,KAAO,IAAQ,CAClB,MAAM,EAAoB,EAAI,EAEjC,CAAC,CACH,EACF,CAAC"}
@@ -0,0 +1,22 @@
1
+ import"./ms-B7sMc0pR.js";import"./src-DxCC1MV4.js";import{r as e}from"./prompt-C9nwJW0G.js";import{D as t,E as n,O as r,j as i,q as a,t as o}from"./http-CY3lPMkt.js";import{E as s,c,d as l,n as u,s as d}from"./command-2iNTc5dV.js";import"./collection-C2TCeYqY.js";import"./directory-CNL03L6c.js";import"./session-BmzGF1t7.js";import{a as f,i as p,r as m}from"./sync-json-V52OzeCz.js";import"./select-Dey_sjjd.js";import{n as h}from"./spinner-BVmbgIil.js";import{existsSync as g,mkdirSync as _,readFileSync as v,writeFileSync as y}from"node:fs";import b from"node:path";import{createServer as x}from"node:http";import S,{nextTick as C}from"node:process";import{randomUUID as w}from"node:crypto";const T=Symbol(`singleComment`),E=Symbol(`multiComment`),D=()=>``,O=(e,t,n)=>e.slice(t,n).replace(/[^ \t\r\n]/g,` `),k=(e,t)=>{let n=t-1,r=0;for(;e[n]===`\\`;)--n,r+=1;return!!(r%2)};function A(e,{whitespace:t=!0,trailingCommas:n=!1}={}){if(typeof e!=`string`)throw TypeError(`Expected argument \`jsonString\` to be a \`string\`, got \`${typeof e}\``);let r=t?O:D,i=!1,a=!1,o=0,s=``,c=``,l=-1;for(let t=0;t<e.length;t++){let u=e[t],d=e[t+1];if(!a&&u===`"`&&(k(e,t)||(i=!i)),!i)if(!a&&u+d===`//`)s+=e.slice(o,t),o=t,a=T,t++;else if(a===T&&u+d===`\r
2
+ `){t++,a=!1,s+=r(e,o,t),o=t;continue}else if(a===T&&u===`
3
+ `)a=!1,s+=r(e,o,t),o=t;else if(!a&&u+d===`/*`){s+=e.slice(o,t),o=t,a=E,t++;continue}else if(a===E&&u+d===`*/`){t++,a=!1,s+=r(e,o,t+1),o=t+1;continue}else n&&!a&&(l===-1?u===`,`&&(c+=s+e.slice(o,t),s=``,o=t,l=t):u===`}`||u===`]`?(s+=e.slice(o,t),c+=r(s,0,1)+s.slice(1),s=``,o=t,l=-1):u!==` `&&u!==` `&&u!==`\r`&&u!==`
4
+ `&&(s+=e.slice(o,t),o=t,l=-1))}let u=a===T?r(e,o):e.slice(o);return c+s+u}const j=e=>JSON.parse(A(e,{trailingCommas:!0})),M=[`vscode`,`cursor`],N=`Starting ggt debugger`,P=`ggt debugger running on`;var F=class{_ctx;_appIdentity;_authHeaders;_sessionId;_port;_subdomain;_httpServer;_wsServer;_sessionManager;constructor(e,t){this._ctx=e,this._appIdentity=t.appIdentity,this._authHeaders=t.authHeaders,this._sessionId=t.sessionId,this._port=t.port,this._subdomain=this._buildSubdomain()}async start(){this._sessionManager=new I(this._ctx),this._httpServer=this._createHttpServer(),this._wsServer=new t.default({noServer:!0}),this._httpServer.on(`upgrade`,(e,t,n)=>{this._handleUpgrade(e,t,n)}),await this._listen()}stop(){this._ctx.log.debug(`shutting down proxy server`),this._wsServer?.close(),this._httpServer?.close(),this._ctx.log.info(`proxy server stopped`)}_buildSubdomain(){let{application:e,name:t,type:n}=this._appIdentity.environment;return n===`production`?e.slug:`${e.slug}--${t}`}_createHttpServer(){return x((e,t)=>{let n=new URL(e.url??`/`,`http://${e.headers.host}`);this._ctx.log.trace(`debugger proxy http request received`,{method:e.method,rUrl:e.url,urlPathname:n.pathname,url:n.toString()});try{n.pathname===`/json/version`?this._handleVersionRequest(t):n.pathname===`/json/list`?this._handleListRequest(t):this._handleNotFound(t,n)}catch(e){this._handleError(t,e)}})}_handleVersionRequest(e){let t={"Protocol-Version":`1.1`,Browser:`node.js/${this._appIdentity.environment.nodeVersion}`};this._ctx.log.trace(`debugger proxy http version request payload`,{payload:t}),e.setHeader(`Content-Type`,`application/json`),e.end(JSON.stringify(t))}_handleListRequest(e){let t=[{id:this._sessionId,type:`node`,title:`ggt debugger`,description:`authenticated CDP proxy to current sandbox process for ${this._appIdentity.environment.application.slug}@${this._appIdentity.environment.name}`,faviconUrl:`https://assets.gadget.dev/assets/environment/dev/favicon-32.png`,webSocketDebuggerUrl:`ws://127.0.0.1:${this._port}/${this._sessionId}`}];this._ctx.log.trace(`debugger proxy http list request payload`,{payload:t}),e.setHeader(`Content-Type`,`application/json`),e.end(JSON.stringify(t))}_handleNotFound(e,t){this._ctx.log.warn(`debugger proxy http request not found`,{url:t.toString()}),e.statusCode=404,e.end(`Not Found`)}_handleError(e,t){this._ctx.log.error(`error handling debugger proxy http request`,{error:t}),e.statusCode=500,e.end(`Internal Server Error`)}_handleUpgrade(e,t,n){if(!this._sessionManager||!this._wsServer){t.destroy();return}let r=new URL(e.url??`/`,`http://${e.headers.host}`);if(this._ctx.log.trace(`debugger proxy websocket upgrade request received`,{url:e.url,isConnecting:this._sessionManager.isConnecting,hasActiveConnection:this._sessionManager.hasActiveConnection}),r.pathname!==`/${this._sessionId}`){t.destroy();return}if(this._sessionManager.hasActiveConnection||this._sessionManager.isConnecting){this._ctx.log.debug(`rejecting upgrade request`,{hasActiveConnection:this._sessionManager.hasActiveConnection,isConnecting:this._sessionManager.isConnecting}),this._rejectUpgrade(t);return}this._sessionManager.clearStaleConnection(),this._acceptUpgrade(e,t,n)}_rejectUpgrade(e){e.write(`HTTP/1.1 409 Another debugger session is already running for this environment\r
5
+ Connection: close\r
6
+ \r
7
+ `),e.destroy()}_acceptUpgrade(e,t,n){!this._wsServer||!this._sessionManager||this._wsServer.handleUpgrade(e,t,n,e=>{this._ctx.log.info(`client websocket upgraded, establishing remote connection`),this._handleClientConnection(e)})}async _handleClientConnection(e){if(!this._sessionManager)return;let t=new L(this._ctx,e,this._sessionManager);try{let n=await this._establishRemoteConnection();t.connectToRemote(n),this._sessionManager.setActiveConnection(e)}catch(e){this._ctx.log.error(`error establishing remote debugger connection`,{error:e}),t.closeWithError(`Failed to establish remote debugger connection`)}}async _establishRemoteConnection(){let e=await o({context:{ctx:this._ctx},method:`POST`,url:`https://${this._subdomain}.${l.domains.app}/edit/api/debugger/start-session`,headers:{...this._authHeaders,"x-gadget-debugger-session-id":this._sessionId},responseType:`json`,resolveBodyOnly:!0});return this._ctx.log.debug(`debugger session created`,{session:e}),await new R(this._ctx,{wsUrl:e.wsUrl,sessionId:this._sessionId,authHeaders:this._authHeaders}).connect()}async _listen(){this._httpServer&&await new Promise((e,t)=>{let n=this._httpServer;if(!n){t(Error(`HTTP server is not initialized`));return}n.listen(this._port,`127.0.0.1`,()=>{this._ctx.log.info(`debugger proxy server listening`,{port:this._port}),e()}),n.on(`error`,t)})}},I=class{_ctx;_activeConnection;_isConnecting=!1;constructor(e){this._ctx=e}get hasActiveConnection(){return!!this._activeConnection&&this._activeConnection.readyState===n.default.OPEN}get isConnecting(){return this._isConnecting}setActiveConnection(e){this._activeConnection=e,this._isConnecting=!1}clearActiveConnection(){this._activeConnection=void 0}clearStaleConnection(){this._activeConnection&&=(this._ctx.log.debug(`clearing stale connection reference`),void 0)}startConnecting(){this._isConnecting=!0}stopConnecting(){this._isConnecting=!1}},L=class{_ctx;_clientWs;_sessionManager;_messageQueue=[];_remoteWs;_remoteReady=!1;constructor(e,t,n){this._ctx=e,this._clientWs=t,this._sessionManager=n,this._setupClientHandlers()}connectToRemote(e){this._remoteWs=e,this._setupRemoteHandlers(),this._flushMessageQueue()}closeWithError(e){this._sessionManager.stopConnecting(),this._clientWs.close(1011,e)}_setupClientHandlers(){this._clientWs.on(`message`,(e,t)=>{this._handleClientMessage(e,t)}),this._clientWs.on(`error`,e=>{this._ctx.log.error(`client websocket error`,{error:e.message,stack:e.stack}),this._remoteWs?.close()}),this._clientWs.on(`close`,()=>{this._ctx.log.info(`client websocket closed`),this._sessionManager.clearActiveConnection(),this._remoteWs?.close()})}_handleClientMessage(e,t){let n=t?`<binary data>`:String(e);this._ctx.log.trace(`received message from client`,{message:n}),this._remoteReady&&this._remoteWs?this._remoteWs.send(e,{binary:t}):this._messageQueue.push({data:e,isBinary:t})}_setupRemoteHandlers(){this._remoteWs&&(this._remoteWs.on(`message`,(e,t)=>{let n=t?`<binary data>`:String(e);this._ctx.log.trace(`received message from remote debugger`,{message:n}),this._clientWs.send(e,{binary:t})}),this._remoteWs.on(`error`,e=>{this._ctx.log.error(`remote debugger error`,{error:e.message,stack:e.stack}),this._clientWs.close(1011,`Remote debugger connection error, please reconnect`)}),this._remoteWs.on(`close`,()=>{this._ctx.log.info(`remote debugger connection closed`),this._clientWs.close(1011,`Remote debugger connection closed by server, please reconnect`)}),this._remoteReady=!0)}_flushMessageQueue(){if(this._remoteWs){this._ctx.log.debug(`remote debugger connected, flushing message queue`,{queueLength:this._messageQueue.length});for(let{data:e,isBinary:t}of this._messageQueue)this._remoteWs.send(e,{binary:t});this._messageQueue.length=0}}},R=class{_ctx;_wsUrl;_sessionId;_authHeaders;constructor(e,t){this._ctx=e,this._wsUrl=t.wsUrl,this._sessionId=t.sessionId,this._authHeaders=t.authHeaders}async connect(){let e,t,r=!1,i=new Promise((n,r)=>{e=n,t=r}),a=new n.default(this._wsUrl,{headers:{...this._authHeaders,"x-gadget-debugger-session-id":this._sessionId}});return a.on(`open`,()=>{this._ctx.log.debug(`connected to remote debugger`),!r&&(r=!0,e())}),a.on(`error`,e=>{this._ctx.log.error(`remote debugger error`,{error:e.message,stack:e.stack}),r||t(e)}),a.readyState===n.default.OPEN&&C(()=>{e()}),await i,a}},z=class{_vscodeDir;constructor(e){this._vscodeDir=b.join(e,`.vscode`)}get launchJsonPath(){return b.join(this._vscodeDir,`launch.json`)}get tasksJsonPath(){return b.join(this._vscodeDir,`tasks.json`)}hasLaunchConfiguration(){if(!g(this.launchJsonPath))return!1;try{return(j(v(this.launchJsonPath,`utf-8`)).configurations??[]).some(e=>e.name===`Gadget debugger`)}catch{return!1}}configure(e){g(this._vscodeDir)||_(this._vscodeDir,{recursive:!0}),this._configureLaunch(e),this._configureTasks()}_configureLaunch(e){let t={type:`node`,request:`attach`,name:`Gadget debugger`,address:`127.0.0.1`,port:e,localRoot:"${workspaceFolder}",remoteRoot:`/gadget/app`,preLaunchTask:`ggt debugger`,restart:!0,timeout:6e4},n;if(g(this.launchJsonPath)){let e=j(v(this.launchJsonPath,`utf-8`)),r=e.configurations??[],i=r.findIndex(e=>e.name===`Gadget debugger`);i>=0?r[i]=t:r.push(t),n={version:e.version,configurations:r}}else n={version:`0.2.0`,configurations:[t]};y(this.launchJsonPath,JSON.stringify(n,void 0,2)+`
8
+ `,`utf-8`)}_configureTasks(){let e={label:`ggt debugger`,type:`shell`,command:`ggt debugger`,isBackground:!0,problemMatcher:{pattern:{regexp:`^$`},background:{activeOnStart:!0,beginsPattern:N,endsPattern:P}}},t;if(g(this.tasksJsonPath)){let n=j(v(this.tasksJsonPath,`utf-8`)),r=n.tasks??[],i=r.findIndex(e=>e.label===`ggt debugger`);i>=0?r[i]=e:r.push(e),t={version:n.version,tasks:r}}else t={version:`2.0.0`,tasks:[e]};y(this.tasksJsonPath,JSON.stringify(t,void 0,2)+`
9
+ `,`utf-8`)}},B=u({name:`debugger`,description:`Connect a debugger to your app's environment`,details:s`
10
+ Starts a local Chrome DevTools Protocol (CDP) proxy that forwards debugging traffic
11
+ between your editor and your Gadget environment. Supported clients include VS Code,
12
+ Cursor, and Chrome DevTools. Use ${d.subdued(`--configure vscode`)} to generate
13
+ .vscode/launch.json and tasks.json for one-click attach debugging. Press Ctrl+C to
14
+ stop the proxy.
15
+ `,examples:[`ggt debugger`,`ggt debugger --port 9230`,`ggt debugger --configure vscode`,`ggt debugger --configure cursor`,`ggt debugger --app myApp --env development`,`ggt debugger --port 9230 --configure vscode`],positionals:[{name:`directory`,description:`App directory to use`,details:`Defaults to the current working directory when omitted.`}],flags:{...f,"--port":{type:Number,alias:[`-p`],description:`Local port for the CDP proxy`,valueName:`port`,details:`Defaults to 9229. Change this if the default port is already in use.`},"--configure":{type:String,alias:`-c`,description:`Write editor debug config files (vscode, cursor)`,valueName:`editor`,details:`Generates .vscode/launch.json and tasks.json for one-click attach debugging. Works with both VS Code and Cursor.`,complete:async(e,t)=>{let{filterByPrefix:n}=await import(`./collection-aM0fpch0.js`);return n([...M],t)}}},run:async(t,n)=>{let o=await m(n._[0]??S.cwd()),l=await p.load(t,{command:`debugger`,flags:n,directory:o});if(n[`--configure`]){let t=n[`--configure`].toLowerCase();if(!M.includes(t))throw new i(`Invalid editor "${n[`--configure`]}". Supported editors: ${M.join(`, `)}`,{usageHint:!1});let r=new z(o.path),a=n[`--port`]??9229;r.configure(a),c({ensureEmptyLineAbove:!0,content:d.success(`${e.tick} Configured ${t} debugger`)}),c({content:s`
16
+ Added configuration to:
17
+ • ${r.launchJsonPath}
18
+ • ${r.tasksJsonPath}
19
+
20
+ You can now start debugging by running the "Gadget debugger" launch configuration.
21
+ `});return}let u=h(`${N} for ${l.environment.name} environment`);t.log.info(`debugger command started`),t.log.trace(`sync json loaded`,{app:l.environment.application.slug,environment:l.environment.name});let f=r(t),g=n[`--port`]??9229,_=w();new z(o.path).hasLaunchConfiguration()||(t.log.warn(`vscode/cursor debugger configuration not found`),c({ensureEmptyLineAbove:!0,content:d.warning(`⚠ Gadget debugger not configured. Run "${d.identifier(`ggt debugger --configure ${M[0]}`)}" to set up.`)}));let v=new F(t,{appIdentity:l,authHeaders:f,sessionId:_,port:g});try{await v.start(),u.succeed(),c({ensureEmptyLineAbove:!0,content:d.success(`${e.tick} ${P} ws://localhost:${g}/${_}`)}),c({content:d.subdued(`Press Ctrl+C to stop`)}),await new Promise(e=>{t.onAbort(()=>{t.log.info(`abort signal received`),e()})}),v.stop(),c({ensureEmptyLineAbove:!0,content:`${e.tick} Proxy server stopped`})}catch(e){t.log.error(`debugger command failed`,{error:e}),await a(t,e)}}});export{B as default};
22
+ //# sourceMappingURL=debugger-BkYgApKn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debugger-BkYgApKn.js","names":["WebSocketServer","http","WebSocket","colors"],"sources":["../node_modules/.pnpm/strip-json-comments@5.0.3/node_modules/strip-json-comments/index.js","../src/commands/debugger.ts"],"sourcesContent":["const singleComment = Symbol('singleComment');\nconst multiComment = Symbol('multiComment');\n\nconst stripWithoutWhitespace = () => '';\n\n// Replace all characters except ASCII spaces, tabs and line endings with regular spaces to ensure valid JSON output.\nconst stripWithWhitespace = (string, start, end) => string.slice(start, end).replace(/[^ \\t\\r\\n]/g, ' ');\n\nconst isEscaped = (jsonString, quotePosition) => {\n\tlet index = quotePosition - 1;\n\tlet backslashCount = 0;\n\n\twhile (jsonString[index] === '\\\\') {\n\t\tindex -= 1;\n\t\tbackslashCount += 1;\n\t}\n\n\treturn Boolean(backslashCount % 2);\n};\n\nexport default function stripJsonComments(jsonString, {whitespace = true, trailingCommas = false} = {}) {\n\tif (typeof jsonString !== 'string') {\n\t\tthrow new TypeError(`Expected argument \\`jsonString\\` to be a \\`string\\`, got \\`${typeof jsonString}\\``);\n\t}\n\n\tconst strip = whitespace ? stripWithWhitespace : stripWithoutWhitespace;\n\n\tlet isInsideString = false;\n\tlet isInsideComment = false;\n\tlet offset = 0;\n\tlet buffer = '';\n\tlet result = '';\n\tlet commaIndex = -1;\n\n\tfor (let index = 0; index < jsonString.length; index++) {\n\t\tconst currentCharacter = jsonString[index];\n\t\tconst nextCharacter = jsonString[index + 1];\n\n\t\tif (!isInsideComment && currentCharacter === '\"') {\n\t\t\t// Enter or exit string\n\t\t\tconst escaped = isEscaped(jsonString, index);\n\t\t\tif (!escaped) {\n\t\t\t\tisInsideString = !isInsideString;\n\t\t\t}\n\t\t}\n\n\t\tif (isInsideString) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!isInsideComment && currentCharacter + nextCharacter === '//') {\n\t\t\t// Enter single-line comment\n\t\t\tbuffer += jsonString.slice(offset, index);\n\t\t\toffset = index;\n\t\t\tisInsideComment = singleComment;\n\t\t\tindex++;\n\t\t} else if (isInsideComment === singleComment && currentCharacter + nextCharacter === '\\r\\n') {\n\t\t\t// Exit single-line comment via \\r\\n\n\t\t\tindex++;\n\t\t\tisInsideComment = false;\n\t\t\tbuffer += strip(jsonString, offset, index);\n\t\t\toffset = index;\n\t\t\tcontinue;\n\t\t} else if (isInsideComment === singleComment && currentCharacter === '\\n') {\n\t\t\t// Exit single-line comment via \\n\n\t\t\tisInsideComment = false;\n\t\t\tbuffer += strip(jsonString, offset, index);\n\t\t\toffset = index;\n\t\t} else if (!isInsideComment && currentCharacter + nextCharacter === '/*') {\n\t\t\t// Enter multiline comment\n\t\t\tbuffer += jsonString.slice(offset, index);\n\t\t\toffset = index;\n\t\t\tisInsideComment = multiComment;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t} else if (isInsideComment === multiComment && currentCharacter + nextCharacter === '*/') {\n\t\t\t// Exit multiline comment\n\t\t\tindex++;\n\t\t\tisInsideComment = false;\n\t\t\tbuffer += strip(jsonString, offset, index + 1);\n\t\t\toffset = index + 1;\n\t\t\tcontinue;\n\t\t} else if (trailingCommas && !isInsideComment) {\n\t\t\tif (commaIndex !== -1) {\n\t\t\t\tif (currentCharacter === '}' || currentCharacter === ']') {\n\t\t\t\t\t// Strip trailing comma\n\t\t\t\t\tbuffer += jsonString.slice(offset, index);\n\t\t\t\t\tresult += strip(buffer, 0, 1) + buffer.slice(1);\n\t\t\t\t\tbuffer = '';\n\t\t\t\t\toffset = index;\n\t\t\t\t\tcommaIndex = -1;\n\t\t\t\t} else if (currentCharacter !== ' ' && currentCharacter !== '\\t' && currentCharacter !== '\\r' && currentCharacter !== '\\n') {\n\t\t\t\t\t// Hit non-whitespace following a comma; comma is not trailing\n\t\t\t\t\tbuffer += jsonString.slice(offset, index);\n\t\t\t\t\toffset = index;\n\t\t\t\t\tcommaIndex = -1;\n\t\t\t\t}\n\t\t\t} else if (currentCharacter === ',') {\n\t\t\t\t// Flush buffer prior to this point, and save new comma index\n\t\t\t\tresult += buffer + jsonString.slice(offset, index);\n\t\t\t\tbuffer = '';\n\t\t\t\toffset = index;\n\t\t\t\tcommaIndex = index;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst remaining = (isInsideComment === singleComment)\n\t\t? strip(jsonString, offset)\n\t\t: jsonString.slice(offset);\n\n\treturn result + buffer + remaining;\n}\n","import { randomUUID } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport type { Server as HttpServer, IncomingMessage, ServerResponse } from \"node:http\";\nimport { createServer } from \"node:http\";\nimport path from \"node:path\";\nimport process, { nextTick } from \"node:process\";\nimport type { Duplex } from \"node:stream\";\n\nimport stripJsonComments from \"strip-json-comments\";\nimport { WebSocket, WebSocketServer, type RawData } from \"ws\";\n\nimport { AppIdentity, AppIdentityFlags } from \"../services/command/app-identity.ts\";\nimport { defineCommand } from \"../services/command/command.ts\";\nimport type { Context } from \"../services/command/context.ts\";\nimport { FlagError } from \"../services/command/flag.ts\";\nimport { config } from \"../services/config/config.ts\";\nimport { loadSyncJsonDirectory } from \"../services/filesync/sync-json.ts\";\nimport { loadAuthHeaders } from \"../services/http/auth.ts\";\nimport { http } from \"../services/http/http.ts\";\nimport colors from \"../services/output/colors.ts\";\nimport { println } from \"../services/output/print.ts\";\nimport { reportErrorAndExit } from \"../services/output/report.ts\";\nimport { spin } from \"../services/output/spinner.ts\";\nimport { sprint } from \"../services/output/sprint.ts\";\nimport { symbol } from \"../services/output/symbols.ts\";\n\nconst parseJsonc = (text: string): unknown => {\n return JSON.parse(stripJsonComments(text, { trailingCommas: true }));\n};\n\nconst SupportedEditors = [\"vscode\", \"cursor\"] as const;\n\nconst StartingMessage = \"Starting ggt debugger\";\nconst RunningMessage = \"ggt debugger running on\";\n\ntype DebuggerSessionResponse = {\n wsUrl: string;\n lease: {\n sessionId: string;\n startedAt: string;\n expiresAt: string;\n };\n};\n\ntype DebuggerProxyOptions = {\n appIdentity: AppIdentity;\n authHeaders: Record<string, string>;\n sessionId: string;\n port: number;\n};\n\n/**\n * Manages the local debugger proxy server that connects CDP clients to the remote Gadget debugger.\n */\nclass DebuggerProxy {\n private readonly _ctx: Context;\n private readonly _appIdentity: AppIdentity;\n private readonly _authHeaders: Record<string, string>;\n private readonly _sessionId: string;\n private readonly _port: number;\n private readonly _subdomain: string;\n\n private _httpServer?: HttpServer;\n private _wsServer?: WebSocketServer;\n private _sessionManager?: DebuggerSessionManager;\n\n constructor(ctx: Context, options: DebuggerProxyOptions) {\n this._ctx = ctx;\n this._appIdentity = options.appIdentity;\n this._authHeaders = options.authHeaders;\n this._sessionId = options.sessionId;\n this._port = options.port;\n this._subdomain = this._buildSubdomain();\n }\n\n async start(): Promise<void> {\n this._sessionManager = new DebuggerSessionManager(this._ctx);\n this._httpServer = this._createHttpServer();\n this._wsServer = new WebSocketServer({ noServer: true });\n\n this._httpServer.on(\"upgrade\", (request, socket, head) => {\n this._handleUpgrade(request, socket, head);\n });\n\n await this._listen();\n }\n\n stop(): void {\n this._ctx.log.debug(\"shutting down proxy server\");\n this._wsServer?.close();\n this._httpServer?.close();\n this._ctx.log.info(\"proxy server stopped\");\n }\n\n private _buildSubdomain(): string {\n const { application, name, type } = this._appIdentity.environment;\n return type === \"production\" ? application.slug : `${application.slug}--${name}`;\n }\n\n private _createHttpServer(): HttpServer {\n return createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host}`);\n this._ctx.log.trace(\"debugger proxy http request received\", {\n method: req.method,\n rUrl: req.url,\n urlPathname: url.pathname,\n url: url.toString(),\n });\n\n try {\n if (url.pathname === \"/json/version\") {\n this._handleVersionRequest(res);\n } else if (url.pathname === \"/json/list\") {\n this._handleListRequest(res);\n } else {\n this._handleNotFound(res, url);\n }\n } catch (error) {\n this._handleError(res, error);\n }\n });\n }\n\n private _handleVersionRequest(res: ServerResponse): void {\n const versionPayload = {\n \"Protocol-Version\": \"1.1\",\n Browser: `node.js/${this._appIdentity.environment.nodeVersion}`,\n };\n this._ctx.log.trace(\"debugger proxy http version request payload\", { payload: versionPayload });\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify(versionPayload));\n }\n\n private _handleListRequest(res: ServerResponse): void {\n const listPayload = [\n {\n id: this._sessionId,\n type: \"node\",\n title: \"ggt debugger\",\n description: `authenticated CDP proxy to current sandbox process for ${this._appIdentity.environment.application.slug}@${this._appIdentity.environment.name}`,\n faviconUrl: \"https://assets.gadget.dev/assets/environment/dev/favicon-32.png\",\n webSocketDebuggerUrl: `ws://127.0.0.1:${this._port}/${this._sessionId}`,\n },\n ];\n this._ctx.log.trace(\"debugger proxy http list request payload\", { payload: listPayload });\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify(listPayload));\n }\n\n private _handleNotFound(res: ServerResponse, url: URL): void {\n this._ctx.log.warn(\"debugger proxy http request not found\", { url: url.toString() });\n res.statusCode = 404;\n res.end(\"Not Found\");\n }\n\n private _handleError(res: ServerResponse, error: unknown): void {\n this._ctx.log.error(\"error handling debugger proxy http request\", { error });\n res.statusCode = 500;\n res.end(\"Internal Server Error\");\n }\n\n private _handleUpgrade(request: IncomingMessage, socket: Duplex, head: Buffer): void {\n if (!this._sessionManager || !this._wsServer) {\n socket.destroy();\n return;\n }\n\n const url = new URL(request.url ?? \"/\", `http://${request.headers.host}`);\n this._ctx.log.trace(\"debugger proxy websocket upgrade request received\", {\n url: request.url,\n isConnecting: this._sessionManager.isConnecting,\n hasActiveConnection: this._sessionManager.hasActiveConnection,\n });\n\n if (url.pathname !== `/${this._sessionId}`) {\n socket.destroy();\n return;\n }\n\n if (this._sessionManager.hasActiveConnection || this._sessionManager.isConnecting) {\n this._ctx.log.debug(\"rejecting upgrade request\", {\n hasActiveConnection: this._sessionManager.hasActiveConnection,\n isConnecting: this._sessionManager.isConnecting,\n });\n this._rejectUpgrade(socket);\n return;\n }\n\n this._sessionManager.clearStaleConnection();\n this._acceptUpgrade(request, socket, head);\n }\n\n private _rejectUpgrade(socket: Duplex): void {\n const status = 409;\n const text = \"Another debugger session is already running for this environment\";\n socket.write(`HTTP/1.1 ${status} ${text}\\r\\nConnection: close\\r\\n\\r\\n`);\n socket.destroy();\n }\n\n private _acceptUpgrade(request: IncomingMessage, socket: Duplex, head: Buffer): void {\n if (!this._wsServer || !this._sessionManager) {\n return;\n }\n\n this._wsServer.handleUpgrade(request, socket, head, (clientWs) => {\n this._ctx.log.info(\"client websocket upgraded, establishing remote connection\");\n void this._handleClientConnection(clientWs);\n });\n }\n\n private async _handleClientConnection(clientWs: WebSocket): Promise<void> {\n if (!this._sessionManager) {\n return;\n }\n\n const connection = new ClientConnection(this._ctx, clientWs, this._sessionManager);\n\n try {\n const remoteWs = await this._establishRemoteConnection();\n connection.connectToRemote(remoteWs);\n this._sessionManager.setActiveConnection(clientWs);\n } catch (error) {\n this._ctx.log.error(\"error establishing remote debugger connection\", { error });\n connection.closeWithError(\"Failed to establish remote debugger connection\");\n }\n }\n\n private async _establishRemoteConnection(): Promise<WebSocket> {\n const session = await http<DebuggerSessionResponse>({\n context: { ctx: this._ctx },\n method: \"POST\",\n url: `https://${this._subdomain}.${config.domains.app}/edit/api/debugger/start-session`,\n headers: { ...this._authHeaders, \"x-gadget-debugger-session-id\": this._sessionId },\n responseType: \"json\",\n resolveBodyOnly: true,\n });\n\n this._ctx.log.debug(\"debugger session created\", { session });\n\n const remoteConnection = new RemoteDebuggerConnection(this._ctx, {\n wsUrl: session.wsUrl,\n sessionId: this._sessionId,\n authHeaders: this._authHeaders,\n });\n\n return await remoteConnection.connect();\n }\n\n private async _listen(): Promise<void> {\n if (!this._httpServer) {\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n const server = this._httpServer;\n if (!server) {\n reject(new Error(\"HTTP server is not initialized\"));\n return;\n }\n server.listen(this._port, \"127.0.0.1\", () => {\n this._ctx.log.info(\"debugger proxy server listening\", { port: this._port });\n resolve();\n });\n server.on(\"error\", reject);\n });\n }\n}\n\n/**\n * Manages the state of active debugger sessions and connections.\n */\nclass DebuggerSessionManager {\n private readonly _ctx: Context;\n private _activeConnection?: WebSocket;\n private _isConnecting = false;\n\n constructor(ctx: Context) {\n this._ctx = ctx;\n }\n\n get hasActiveConnection(): boolean {\n return !!this._activeConnection && this._activeConnection.readyState === WebSocket.OPEN;\n }\n\n get isConnecting(): boolean {\n return this._isConnecting;\n }\n\n setActiveConnection(ws: WebSocket): void {\n this._activeConnection = ws;\n this._isConnecting = false;\n }\n\n clearActiveConnection(): void {\n this._activeConnection = undefined;\n }\n\n clearStaleConnection(): void {\n if (this._activeConnection) {\n this._ctx.log.debug(\"clearing stale connection reference\");\n this._activeConnection = undefined;\n }\n }\n\n startConnecting(): void {\n this._isConnecting = true;\n }\n\n stopConnecting(): void {\n this._isConnecting = false;\n }\n}\n\n/**\n * Manages a client connection from a CDP debugger (VS Code, Chrome DevTools, etc).\n */\nclass ClientConnection {\n private readonly _ctx: Context;\n private readonly _clientWs: WebSocket;\n private readonly _sessionManager: DebuggerSessionManager;\n private readonly _messageQueue: { data: RawData; isBinary: boolean }[] = [];\n private _remoteWs?: WebSocket;\n private _remoteReady = false;\n\n constructor(ctx: Context, clientWs: WebSocket, sessionManager: DebuggerSessionManager) {\n this._ctx = ctx;\n this._clientWs = clientWs;\n this._sessionManager = sessionManager;\n this._setupClientHandlers();\n }\n\n connectToRemote(remoteWs: WebSocket): void {\n this._remoteWs = remoteWs;\n this._setupRemoteHandlers();\n this._flushMessageQueue();\n }\n\n closeWithError(reason: string): void {\n this._sessionManager.stopConnecting();\n this._clientWs.close(1011, reason);\n }\n\n private _setupClientHandlers(): void {\n this._clientWs.on(\"message\", (data: RawData, isBinary: boolean) => {\n this._handleClientMessage(data, isBinary);\n });\n\n this._clientWs.on(\"error\", (error: Error) => {\n this._ctx.log.error(\"client websocket error\", { error: error.message, stack: error.stack });\n this._remoteWs?.close();\n });\n\n this._clientWs.on(\"close\", () => {\n this._ctx.log.info(\"client websocket closed\");\n this._sessionManager.clearActiveConnection();\n this._remoteWs?.close();\n });\n }\n\n private _handleClientMessage(data: RawData, isBinary: boolean): void {\n // oxlint-disable-next-line no-base-to-string\n const messageString = isBinary ? \"<binary data>\" : String(data);\n this._ctx.log.trace(\"received message from client\", { message: messageString });\n\n if (this._remoteReady && this._remoteWs) {\n this._remoteWs.send(data, { binary: isBinary });\n } else {\n this._messageQueue.push({ data, isBinary });\n }\n }\n\n private _setupRemoteHandlers(): void {\n if (!this._remoteWs) {\n return;\n }\n\n this._remoteWs.on(\"message\", (data: RawData, isBinary: boolean) => {\n // oxlint-disable-next-line no-base-to-string\n const messageString = isBinary ? \"<binary data>\" : String(data);\n this._ctx.log.trace(\"received message from remote debugger\", { message: messageString });\n this._clientWs.send(data, { binary: isBinary });\n });\n\n this._remoteWs.on(\"error\", (error: Error) => {\n this._ctx.log.error(\"remote debugger error\", { error: error.message, stack: error.stack });\n this._clientWs.close(1011, \"Remote debugger connection error, please reconnect\");\n });\n\n this._remoteWs.on(\"close\", () => {\n this._ctx.log.info(\"remote debugger connection closed\");\n this._clientWs.close(1011, \"Remote debugger connection closed by server, please reconnect\");\n });\n\n this._remoteReady = true;\n }\n\n private _flushMessageQueue(): void {\n if (!this._remoteWs) {\n return;\n }\n\n this._ctx.log.debug(\"remote debugger connected, flushing message queue\", {\n queueLength: this._messageQueue.length,\n });\n\n for (const { data, isBinary } of this._messageQueue) {\n this._remoteWs.send(data, { binary: isBinary });\n }\n this._messageQueue.length = 0;\n }\n}\n\ntype RemoteDebuggerConnectionOptions = {\n wsUrl: string;\n sessionId: string;\n authHeaders: Record<string, string>;\n};\n\n/**\n * Manages a connection to the remote Gadget debugger WebSocket.\n */\nclass RemoteDebuggerConnection {\n private readonly _ctx: Context;\n private readonly _wsUrl: string;\n private readonly _sessionId: string;\n private readonly _authHeaders: Record<string, string>;\n\n constructor(ctx: Context, options: RemoteDebuggerConnectionOptions) {\n this._ctx = ctx;\n this._wsUrl = options.wsUrl;\n this._sessionId = options.sessionId;\n this._authHeaders = options.authHeaders;\n }\n\n async connect(): Promise<WebSocket> {\n let resolveConnection: () => void;\n let rejectConnection: (error: Error) => void;\n let connected = false;\n\n const connectionPromise = new Promise<void>((resolve, reject) => {\n resolveConnection = resolve;\n rejectConnection = reject;\n });\n\n const ws = new WebSocket(this._wsUrl, {\n headers: { ...this._authHeaders, \"x-gadget-debugger-session-id\": this._sessionId },\n });\n\n ws.on(\"open\", () => {\n this._ctx.log.debug(\"connected to remote debugger\");\n if (connected) {\n return;\n }\n connected = true;\n resolveConnection();\n });\n\n ws.on(\"error\", (error: Error) => {\n this._ctx.log.error(\"remote debugger error\", { error: error.message, stack: error.stack });\n if (!connected) {\n rejectConnection(error);\n }\n });\n\n if (ws.readyState === WebSocket.OPEN) {\n nextTick(() => {\n resolveConnection();\n });\n }\n\n await connectionPromise;\n\n return ws;\n }\n}\n\ntype VSCodeLaunchConfiguration = {\n type: string;\n request: string;\n name: string;\n address: string;\n port: number;\n localRoot: string;\n remoteRoot: string;\n preLaunchTask: string;\n restart: boolean;\n timeout: number;\n};\n\ntype VSCodeTask = {\n label: string;\n type: string;\n command: string;\n isBackground: boolean;\n problemMatcher: {\n pattern: { regexp: string };\n background: {\n activeOnStart: boolean;\n beginsPattern: string;\n endsPattern: string;\n };\n };\n};\n\n/**\n * Handles VS Code/Cursor debugger configuration setup.\n */\nclass DebuggerConfigurator {\n private readonly _vscodeDir: string;\n\n constructor(directory: string) {\n this._vscodeDir = path.join(directory, \".vscode\");\n }\n\n get launchJsonPath(): string {\n return path.join(this._vscodeDir, \"launch.json\");\n }\n\n get tasksJsonPath(): string {\n return path.join(this._vscodeDir, \"tasks.json\");\n }\n\n hasLaunchConfiguration(): boolean {\n if (!existsSync(this.launchJsonPath)) {\n return false;\n }\n\n try {\n const launchJson = parseJsonc(readFileSync(this.launchJsonPath, \"utf-8\")) as {\n configurations?: VSCodeLaunchConfiguration[];\n };\n const configurations = launchJson.configurations ?? [];\n return configurations.some((config) => config.name === \"Gadget debugger\");\n } catch {\n return false;\n }\n }\n\n configure(port: number): void {\n // Ensure .vscode directory exists\n if (!existsSync(this._vscodeDir)) {\n mkdirSync(this._vscodeDir, { recursive: true });\n }\n\n this._configureLaunch(port);\n this._configureTasks();\n }\n\n private _configureLaunch(port: number): void {\n const launchConfig: VSCodeLaunchConfiguration = {\n type: \"node\",\n request: \"attach\",\n name: \"Gadget debugger\",\n address: \"127.0.0.1\",\n port,\n localRoot: \"${workspaceFolder}\",\n remoteRoot: \"/gadget/app\",\n preLaunchTask: \"ggt debugger\",\n restart: true,\n timeout: 60000,\n };\n\n let launchJson: { version?: string; configurations: VSCodeLaunchConfiguration[] };\n\n if (existsSync(this.launchJsonPath)) {\n // Read existing launch.json\n const content = readFileSync(this.launchJsonPath, \"utf-8\");\n const parsed = parseJsonc(content) as { version?: string; configurations?: VSCodeLaunchConfiguration[] };\n\n // Ensure configurations array exists\n const configurations = parsed.configurations ?? [];\n\n // Check if configuration already exists\n const existingIndex = configurations.findIndex((config) => config.name === \"Gadget debugger\");\n\n if (existingIndex >= 0) {\n // Update existing configuration\n configurations[existingIndex] = launchConfig;\n } else {\n // Add new configuration\n configurations.push(launchConfig);\n }\n\n launchJson = {\n version: parsed.version,\n configurations,\n };\n } else {\n // Create new launch.json\n launchJson = {\n version: \"0.2.0\",\n configurations: [launchConfig],\n };\n }\n\n writeFileSync(this.launchJsonPath, JSON.stringify(launchJson, undefined, 2) + \"\\n\", \"utf-8\");\n }\n\n private _configureTasks(): void {\n const task: VSCodeTask = {\n label: \"ggt debugger\",\n type: \"shell\",\n command: \"ggt debugger\",\n isBackground: true,\n problemMatcher: {\n pattern: { regexp: \"^$\" },\n background: {\n activeOnStart: true,\n beginsPattern: StartingMessage,\n endsPattern: RunningMessage,\n },\n },\n };\n\n let tasksJson: { version?: string; tasks: VSCodeTask[] };\n\n if (existsSync(this.tasksJsonPath)) {\n // Read existing tasks.json\n const content = readFileSync(this.tasksJsonPath, \"utf-8\");\n const parsed = parseJsonc(content) as { version?: string; tasks?: VSCodeTask[] };\n\n // Ensure tasks array exists\n const tasks = parsed.tasks ?? [];\n\n // Check if task already exists\n const existingIndex = tasks.findIndex((t) => t.label === \"ggt debugger\");\n\n if (existingIndex >= 0) {\n // Update existing task\n tasks[existingIndex] = task;\n } else {\n // Add new task\n tasks.push(task);\n }\n\n tasksJson = {\n version: parsed.version,\n tasks,\n };\n } else {\n // Create new tasks.json\n tasksJson = {\n version: \"2.0.0\",\n tasks: [task],\n };\n }\n\n writeFileSync(this.tasksJsonPath, JSON.stringify(tasksJson, undefined, 2) + \"\\n\", \"utf-8\");\n }\n}\n\nexport default defineCommand({\n name: \"debugger\",\n description: \"Connect a debugger to your app's environment\",\n details: sprint`\n Starts a local Chrome DevTools Protocol (CDP) proxy that forwards debugging traffic\n between your editor and your Gadget environment. Supported clients include VS Code,\n Cursor, and Chrome DevTools. Use ${colors.subdued(\"--configure vscode\")} to generate\n .vscode/launch.json and tasks.json for one-click attach debugging. Press Ctrl+C to\n stop the proxy.\n `,\n examples: [\n \"ggt debugger\",\n \"ggt debugger --port 9230\",\n \"ggt debugger --configure vscode\",\n \"ggt debugger --configure cursor\",\n \"ggt debugger --app myApp --env development\",\n \"ggt debugger --port 9230 --configure vscode\",\n ],\n positionals: [\n {\n name: \"directory\",\n description: \"App directory to use\",\n details: \"Defaults to the current working directory when omitted.\",\n },\n ],\n flags: {\n ...AppIdentityFlags,\n \"--port\": {\n type: Number,\n alias: [\"-p\"],\n description: \"Local port for the CDP proxy\",\n valueName: \"port\",\n details: \"Defaults to 9229. Change this if the default port is already in use.\",\n },\n \"--configure\": {\n type: String,\n alias: \"-c\",\n description: \"Write editor debug config files (vscode, cursor)\",\n valueName: \"editor\",\n details: \"Generates .vscode/launch.json and tasks.json for one-click attach debugging. Works with both VS Code and Cursor.\",\n complete: async (_ctx, partial) => {\n const { filterByPrefix } = await import(\"../services/util/collection.ts\");\n return filterByPrefix([...SupportedEditors], partial);\n },\n },\n },\n run: async (ctx, flags) => {\n const directory = await loadSyncJsonDirectory(flags._[0] ?? process.cwd());\n const appIdentity = await AppIdentity.load(ctx, { command: \"debugger\", flags, directory });\n\n // Handle --configure option\n if (flags[\"--configure\"]) {\n const editor = flags[\"--configure\"].toLowerCase();\n if (!SupportedEditors.includes(editor as (typeof SupportedEditors)[number])) {\n throw new FlagError(`Invalid editor \"${flags[\"--configure\"]}\". Supported editors: ${SupportedEditors.join(\", \")}`, {\n usageHint: false,\n });\n }\n\n const configurator = new DebuggerConfigurator(directory.path);\n const port = flags[\"--port\"] ?? 9229;\n configurator.configure(port);\n\n println({\n ensureEmptyLineAbove: true,\n content: colors.success(`${symbol.tick} Configured ${editor} debugger`),\n });\n println({\n content: sprint`\n Added configuration to:\n • ${configurator.launchJsonPath}\n • ${configurator.tasksJsonPath}\n\n You can now start debugging by running the \"Gadget debugger\" launch configuration.\n `,\n });\n return;\n }\n\n const spinner = spin(`${StartingMessage} for ${appIdentity.environment.name} environment`);\n ctx.log.info(\"debugger command started\");\n\n ctx.log.trace(\"sync json loaded\", {\n app: appIdentity.environment.application.slug,\n environment: appIdentity.environment.name,\n });\n\n const authHeaders = loadAuthHeaders(ctx);\n const port = flags[\"--port\"] ?? 9229;\n const sessionId = randomUUID();\n\n // Check if VS Code launch configuration exists\n const configurator = new DebuggerConfigurator(directory.path);\n if (!configurator.hasLaunchConfiguration()) {\n ctx.log.warn(\"vscode/cursor debugger configuration not found\");\n println({\n ensureEmptyLineAbove: true,\n content: colors.warning(\n `⚠ Gadget debugger not configured. Run \"${colors.identifier(`ggt debugger --configure ${SupportedEditors[0]}`)}\" to set up.`,\n ),\n });\n }\n\n const proxy = new DebuggerProxy(ctx, {\n appIdentity,\n authHeaders,\n sessionId,\n port,\n });\n\n try {\n await proxy.start();\n\n spinner.succeed();\n println({\n ensureEmptyLineAbove: true,\n content: colors.success(`${symbol.tick} ${RunningMessage} ws://localhost:${port}/${sessionId}`),\n });\n println({ content: colors.subdued(\"Press Ctrl+C to stop\") });\n\n await new Promise<void>((resolve) => {\n ctx.onAbort(() => {\n ctx.log.info(\"abort signal received\");\n resolve();\n });\n });\n\n proxy.stop();\n println({ ensureEmptyLineAbove: true, content: `${symbol.tick} Proxy server stopped` });\n } catch (error) {\n ctx.log.error(\"debugger command failed\", { error });\n await reportErrorAndExit(ctx, error);\n }\n },\n});\n"],"x_google_ignoreList":[0],"mappings":"srBAAA,MAAM,EAAgB,OAAO,gBAAgB,CACvC,EAAe,OAAO,eAAe,CAErC,MAA+B,GAG/B,GAAuB,EAAQ,EAAO,IAAQ,EAAO,MAAM,EAAO,EAAI,CAAC,QAAQ,cAAe,IAAI,CAElG,GAAa,EAAY,IAAkB,CAChD,IAAI,EAAQ,EAAgB,EACxB,EAAiB,EAErB,KAAO,EAAW,KAAW,MAC5B,IACA,GAAkB,EAGnB,MAAO,GAAQ,EAAiB,IAGjC,SAAwB,EAAkB,EAAY,CAAC,aAAa,GAAM,iBAAiB,IAAS,EAAE,CAAE,CACvG,GAAI,OAAO,GAAe,SACzB,MAAU,UAAU,8DAA8D,OAAO,EAAW,IAAI,CAGzG,IAAM,EAAQ,EAAa,EAAsB,EAE7C,EAAiB,GACjB,EAAkB,GAClB,EAAS,EACT,EAAS,GACT,EAAS,GACT,EAAa,GAEjB,IAAK,IAAI,EAAQ,EAAG,EAAQ,EAAW,OAAQ,IAAS,CACvD,IAAM,EAAmB,EAAW,GAC9B,EAAgB,EAAW,EAAQ,GAEzC,GAAI,CAAC,GAAmB,IAAqB,MAE5B,EAAU,EAAY,EAAM,GAE3C,EAAiB,CAAC,IAIhB,GAIJ,GAAI,CAAC,GAAmB,EAAmB,IAAkB,KAE5D,GAAU,EAAW,MAAM,EAAQ,EAAM,CACzC,EAAS,EACT,EAAkB,EAClB,YACU,IAAoB,GAAiB,EAAmB,IAAkB;EAAQ,CAE5F,IACA,EAAkB,GAClB,GAAU,EAAM,EAAY,EAAQ,EAAM,CAC1C,EAAS,EACT,iBACU,IAAoB,GAAiB,IAAqB;EAEpE,EAAkB,GAClB,GAAU,EAAM,EAAY,EAAQ,EAAM,CAC1C,EAAS,UACC,CAAC,GAAmB,EAAmB,IAAkB,KAAM,CAEzE,GAAU,EAAW,MAAM,EAAQ,EAAM,CACzC,EAAS,EACT,EAAkB,EAClB,IACA,iBACU,IAAoB,GAAgB,EAAmB,IAAkB,KAAM,CAEzF,IACA,EAAkB,GAClB,GAAU,EAAM,EAAY,EAAQ,EAAQ,EAAE,CAC9C,EAAS,EAAQ,EACjB,cACU,GAAkB,CAAC,IACzB,IAAe,GAcR,IAAqB,MAE/B,GAAU,EAAS,EAAW,MAAM,EAAQ,EAAM,CAClD,EAAS,GACT,EAAS,EACT,EAAa,GAlBT,IAAqB,KAAO,IAAqB,KAEpD,GAAU,EAAW,MAAM,EAAQ,EAAM,CACzC,GAAU,EAAM,EAAQ,EAAG,EAAE,CAAG,EAAO,MAAM,EAAE,CAC/C,EAAS,GACT,EAAS,EACT,EAAa,IACH,IAAqB,KAAO,IAAqB,KAAQ,IAAqB,MAAQ,IAAqB;IAErH,GAAU,EAAW,MAAM,EAAQ,EAAM,CACzC,EAAS,EACT,EAAa,KAYjB,IAAM,EAAa,IAAoB,EACpC,EAAM,EAAY,EAAO,CACzB,EAAW,MAAM,EAAO,CAE3B,OAAO,EAAS,EAAS,ECrF1B,MAAM,EAAc,GACX,KAAK,MAAM,EAAkB,EAAM,CAAE,eAAgB,GAAM,CAAC,CAAC,CAGhE,EAAmB,CAAC,SAAU,SAAS,CAEvC,EAAkB,wBAClB,EAAiB,0BAqBvB,IAAM,EAAN,KAAoB,CAClB,KACA,aACA,aACA,WACA,MACA,WAEA,YACA,UACA,gBAEA,YAAY,EAAc,EAA+B,CACvD,KAAK,KAAO,EACZ,KAAK,aAAe,EAAQ,YAC5B,KAAK,aAAe,EAAQ,YAC5B,KAAK,WAAa,EAAQ,UAC1B,KAAK,MAAQ,EAAQ,KACrB,KAAK,WAAa,KAAK,iBAAiB,CAG1C,MAAM,OAAuB,CAC3B,KAAK,gBAAkB,IAAI,EAAuB,KAAK,KAAK,CAC5D,KAAK,YAAc,KAAK,mBAAmB,CAC3C,KAAK,UAAY,IAAIA,EAAAA,QAAgB,CAAE,SAAU,GAAM,CAAC,CAExD,KAAK,YAAY,GAAG,WAAY,EAAS,EAAQ,IAAS,CACxD,KAAK,eAAe,EAAS,EAAQ,EAAK,EAC1C,CAEF,MAAM,KAAK,SAAS,CAGtB,MAAa,CACX,KAAK,KAAK,IAAI,MAAM,6BAA6B,CACjD,KAAK,WAAW,OAAO,CACvB,KAAK,aAAa,OAAO,CACzB,KAAK,KAAK,IAAI,KAAK,uBAAuB,CAG5C,iBAAkC,CAChC,GAAM,CAAE,cAAa,OAAM,QAAS,KAAK,aAAa,YACtD,OAAO,IAAS,aAAe,EAAY,KAAO,GAAG,EAAY,KAAK,IAAI,IAG5E,mBAAwC,CACtC,OAAO,GAAc,EAAK,IAAQ,CAChC,IAAM,EAAM,IAAI,IAAI,EAAI,KAAO,IAAK,UAAU,EAAI,QAAQ,OAAO,CACjE,KAAK,KAAK,IAAI,MAAM,uCAAwC,CAC1D,OAAQ,EAAI,OACZ,KAAM,EAAI,IACV,YAAa,EAAI,SACjB,IAAK,EAAI,UAAU,CACpB,CAAC,CAEF,GAAI,CACE,EAAI,WAAa,gBACnB,KAAK,sBAAsB,EAAI,CACtB,EAAI,WAAa,aAC1B,KAAK,mBAAmB,EAAI,CAE5B,KAAK,gBAAgB,EAAK,EAAI,OAEzB,EAAO,CACd,KAAK,aAAa,EAAK,EAAM,GAE/B,CAGJ,sBAA8B,EAA2B,CACvD,IAAM,EAAiB,CACrB,mBAAoB,MACpB,QAAS,WAAW,KAAK,aAAa,YAAY,cACnD,CACD,KAAK,KAAK,IAAI,MAAM,8CAA+C,CAAE,QAAS,EAAgB,CAAC,CAC/F,EAAI,UAAU,eAAgB,mBAAmB,CACjD,EAAI,IAAI,KAAK,UAAU,EAAe,CAAC,CAGzC,mBAA2B,EAA2B,CACpD,IAAM,EAAc,CAClB,CACE,GAAI,KAAK,WACT,KAAM,OACN,MAAO,eACP,YAAa,0DAA0D,KAAK,aAAa,YAAY,YAAY,KAAK,GAAG,KAAK,aAAa,YAAY,OACvJ,WAAY,kEACZ,qBAAsB,kBAAkB,KAAK,MAAM,GAAG,KAAK,aAC5D,CACF,CACD,KAAK,KAAK,IAAI,MAAM,2CAA4C,CAAE,QAAS,EAAa,CAAC,CACzF,EAAI,UAAU,eAAgB,mBAAmB,CACjD,EAAI,IAAI,KAAK,UAAU,EAAY,CAAC,CAGtC,gBAAwB,EAAqB,EAAgB,CAC3D,KAAK,KAAK,IAAI,KAAK,wCAAyC,CAAE,IAAK,EAAI,UAAU,CAAE,CAAC,CACpF,EAAI,WAAa,IACjB,EAAI,IAAI,YAAY,CAGtB,aAAqB,EAAqB,EAAsB,CAC9D,KAAK,KAAK,IAAI,MAAM,6CAA8C,CAAE,QAAO,CAAC,CAC5E,EAAI,WAAa,IACjB,EAAI,IAAI,wBAAwB,CAGlC,eAAuB,EAA0B,EAAgB,EAAoB,CACnF,GAAI,CAAC,KAAK,iBAAmB,CAAC,KAAK,UAAW,CAC5C,EAAO,SAAS,CAChB,OAGF,IAAM,EAAM,IAAI,IAAI,EAAQ,KAAO,IAAK,UAAU,EAAQ,QAAQ,OAAO,CAOzE,GANA,KAAK,KAAK,IAAI,MAAM,oDAAqD,CACvE,IAAK,EAAQ,IACb,aAAc,KAAK,gBAAgB,aACnC,oBAAqB,KAAK,gBAAgB,oBAC3C,CAAC,CAEE,EAAI,WAAa,IAAI,KAAK,aAAc,CAC1C,EAAO,SAAS,CAChB,OAGF,GAAI,KAAK,gBAAgB,qBAAuB,KAAK,gBAAgB,aAAc,CACjF,KAAK,KAAK,IAAI,MAAM,4BAA6B,CAC/C,oBAAqB,KAAK,gBAAgB,oBAC1C,aAAc,KAAK,gBAAgB,aACpC,CAAC,CACF,KAAK,eAAe,EAAO,CAC3B,OAGF,KAAK,gBAAgB,sBAAsB,CAC3C,KAAK,eAAe,EAAS,EAAQ,EAAK,CAG5C,eAAuB,EAAsB,CAG3C,EAAO,MAAM;;;EAA0D,CACvE,EAAO,SAAS,CAGlB,eAAuB,EAA0B,EAAgB,EAAoB,CAC/E,CAAC,KAAK,WAAa,CAAC,KAAK,iBAI7B,KAAK,UAAU,cAAc,EAAS,EAAQ,EAAO,GAAa,CAChE,KAAK,KAAK,IAAI,KAAK,4DAA4D,CAC1E,KAAK,wBAAwB,EAAS,EAC3C,CAGJ,MAAc,wBAAwB,EAAoC,CACxE,GAAI,CAAC,KAAK,gBACR,OAGF,IAAM,EAAa,IAAI,EAAiB,KAAK,KAAM,EAAU,KAAK,gBAAgB,CAElF,GAAI,CACF,IAAM,EAAW,MAAM,KAAK,4BAA4B,CACxD,EAAW,gBAAgB,EAAS,CACpC,KAAK,gBAAgB,oBAAoB,EAAS,OAC3C,EAAO,CACd,KAAK,KAAK,IAAI,MAAM,gDAAiD,CAAE,QAAO,CAAC,CAC/E,EAAW,eAAe,iDAAiD,EAI/E,MAAc,4BAAiD,CAC7D,IAAM,EAAU,MAAMC,EAA8B,CAClD,QAAS,CAAE,IAAK,KAAK,KAAM,CAC3B,OAAQ,OACR,IAAK,WAAW,KAAK,WAAW,GAAG,EAAO,QAAQ,IAAI,kCACtD,QAAS,CAAE,GAAG,KAAK,aAAc,+BAAgC,KAAK,WAAY,CAClF,aAAc,OACd,gBAAiB,GAClB,CAAC,CAUF,OARA,KAAK,KAAK,IAAI,MAAM,2BAA4B,CAAE,UAAS,CAAC,CAQrD,MANkB,IAAI,EAAyB,KAAK,KAAM,CAC/D,MAAO,EAAQ,MACf,UAAW,KAAK,WAChB,YAAa,KAAK,aACnB,CAAC,CAE4B,SAAS,CAGzC,MAAc,SAAyB,CAChC,KAAK,aAIV,MAAM,IAAI,SAAe,EAAS,IAAW,CAC3C,IAAM,EAAS,KAAK,YACpB,GAAI,CAAC,EAAQ,CACX,EAAW,MAAM,iCAAiC,CAAC,CACnD,OAEF,EAAO,OAAO,KAAK,MAAO,gBAAmB,CAC3C,KAAK,KAAK,IAAI,KAAK,kCAAmC,CAAE,KAAM,KAAK,MAAO,CAAC,CAC3E,GAAS,EACT,CACF,EAAO,GAAG,QAAS,EAAO,EAC1B,GAOA,EAAN,KAA6B,CAC3B,KACA,kBACA,cAAwB,GAExB,YAAY,EAAc,CACxB,KAAK,KAAO,EAGd,IAAI,qBAA+B,CACjC,MAAO,CAAC,CAAC,KAAK,mBAAqB,KAAK,kBAAkB,aAAeC,EAAAA,QAAU,KAGrF,IAAI,cAAwB,CAC1B,OAAO,KAAK,cAGd,oBAAoB,EAAqB,CACvC,KAAK,kBAAoB,EACzB,KAAK,cAAgB,GAGvB,uBAA8B,CAC5B,KAAK,kBAAoB,IAAA,GAG3B,sBAA6B,CAC3B,AAEE,KAAK,qBADL,KAAK,KAAK,IAAI,MAAM,sCAAsC,CACjC,IAAA,IAI7B,iBAAwB,CACtB,KAAK,cAAgB,GAGvB,gBAAuB,CACrB,KAAK,cAAgB,KAOnB,EAAN,KAAuB,CACrB,KACA,UACA,gBACA,cAAyE,EAAE,CAC3E,UACA,aAAuB,GAEvB,YAAY,EAAc,EAAqB,EAAwC,CACrF,KAAK,KAAO,EACZ,KAAK,UAAY,EACjB,KAAK,gBAAkB,EACvB,KAAK,sBAAsB,CAG7B,gBAAgB,EAA2B,CACzC,KAAK,UAAY,EACjB,KAAK,sBAAsB,CAC3B,KAAK,oBAAoB,CAG3B,eAAe,EAAsB,CACnC,KAAK,gBAAgB,gBAAgB,CACrC,KAAK,UAAU,MAAM,KAAM,EAAO,CAGpC,sBAAqC,CACnC,KAAK,UAAU,GAAG,WAAY,EAAe,IAAsB,CACjE,KAAK,qBAAqB,EAAM,EAAS,EACzC,CAEF,KAAK,UAAU,GAAG,QAAU,GAAiB,CAC3C,KAAK,KAAK,IAAI,MAAM,yBAA0B,CAAE,MAAO,EAAM,QAAS,MAAO,EAAM,MAAO,CAAC,CAC3F,KAAK,WAAW,OAAO,EACvB,CAEF,KAAK,UAAU,GAAG,YAAe,CAC/B,KAAK,KAAK,IAAI,KAAK,0BAA0B,CAC7C,KAAK,gBAAgB,uBAAuB,CAC5C,KAAK,WAAW,OAAO,EACvB,CAGJ,qBAA6B,EAAe,EAAyB,CAEnE,IAAM,EAAgB,EAAW,gBAAkB,OAAO,EAAK,CAC/D,KAAK,KAAK,IAAI,MAAM,+BAAgC,CAAE,QAAS,EAAe,CAAC,CAE3E,KAAK,cAAgB,KAAK,UAC5B,KAAK,UAAU,KAAK,EAAM,CAAE,OAAQ,EAAU,CAAC,CAE/C,KAAK,cAAc,KAAK,CAAE,OAAM,WAAU,CAAC,CAI/C,sBAAqC,CAC9B,KAAK,YAIV,KAAK,UAAU,GAAG,WAAY,EAAe,IAAsB,CAEjE,IAAM,EAAgB,EAAW,gBAAkB,OAAO,EAAK,CAC/D,KAAK,KAAK,IAAI,MAAM,wCAAyC,CAAE,QAAS,EAAe,CAAC,CACxF,KAAK,UAAU,KAAK,EAAM,CAAE,OAAQ,EAAU,CAAC,EAC/C,CAEF,KAAK,UAAU,GAAG,QAAU,GAAiB,CAC3C,KAAK,KAAK,IAAI,MAAM,wBAAyB,CAAE,MAAO,EAAM,QAAS,MAAO,EAAM,MAAO,CAAC,CAC1F,KAAK,UAAU,MAAM,KAAM,qDAAqD,EAChF,CAEF,KAAK,UAAU,GAAG,YAAe,CAC/B,KAAK,KAAK,IAAI,KAAK,oCAAoC,CACvD,KAAK,UAAU,MAAM,KAAM,gEAAgE,EAC3F,CAEF,KAAK,aAAe,IAGtB,oBAAmC,CAC5B,QAAK,UAIV,MAAK,KAAK,IAAI,MAAM,oDAAqD,CACvE,YAAa,KAAK,cAAc,OACjC,CAAC,CAEF,IAAK,GAAM,CAAE,OAAM,cAAc,KAAK,cACpC,KAAK,UAAU,KAAK,EAAM,CAAE,OAAQ,EAAU,CAAC,CAEjD,KAAK,cAAc,OAAS,KAa1B,EAAN,KAA+B,CAC7B,KACA,OACA,WACA,aAEA,YAAY,EAAc,EAA0C,CAClE,KAAK,KAAO,EACZ,KAAK,OAAS,EAAQ,MACtB,KAAK,WAAa,EAAQ,UAC1B,KAAK,aAAe,EAAQ,YAG9B,MAAM,SAA8B,CAClC,IAAI,EACA,EACA,EAAY,GAEV,EAAoB,IAAI,SAAe,EAAS,IAAW,CAC/D,EAAoB,EACpB,EAAmB,GACnB,CAEI,EAAK,IAAIA,EAAAA,QAAU,KAAK,OAAQ,CACpC,QAAS,CAAE,GAAG,KAAK,aAAc,+BAAgC,KAAK,WAAY,CACnF,CAAC,CA0BF,OAxBA,EAAG,GAAG,WAAc,CAClB,KAAK,KAAK,IAAI,MAAM,+BAA+B,CAC/C,KAGJ,EAAY,GACZ,GAAmB,GACnB,CAEF,EAAG,GAAG,QAAU,GAAiB,CAC/B,KAAK,KAAK,IAAI,MAAM,wBAAyB,CAAE,MAAO,EAAM,QAAS,MAAO,EAAM,MAAO,CAAC,CACrF,GACH,EAAiB,EAAM,EAEzB,CAEE,EAAG,aAAeA,EAAAA,QAAU,MAC9B,MAAe,CACb,GAAmB,EACnB,CAGJ,MAAM,EAEC,IAmCL,EAAN,KAA2B,CACzB,WAEA,YAAY,EAAmB,CAC7B,KAAK,WAAa,EAAK,KAAK,EAAW,UAAU,CAGnD,IAAI,gBAAyB,CAC3B,OAAO,EAAK,KAAK,KAAK,WAAY,cAAc,CAGlD,IAAI,eAAwB,CAC1B,OAAO,EAAK,KAAK,KAAK,WAAY,aAAa,CAGjD,wBAAkC,CAChC,GAAI,CAAC,EAAW,KAAK,eAAe,CAClC,MAAO,GAGT,GAAI,CAKF,OAJmB,EAAW,EAAa,KAAK,eAAgB,QAAQ,CAAC,CAGvC,gBAAkB,EAAE,EAChC,KAAM,GAAW,EAAO,OAAS,kBAAkB,MACnE,CACN,MAAO,IAIX,UAAU,EAAoB,CAEvB,EAAW,KAAK,WAAW,EAC9B,EAAU,KAAK,WAAY,CAAE,UAAW,GAAM,CAAC,CAGjD,KAAK,iBAAiB,EAAK,CAC3B,KAAK,iBAAiB,CAGxB,iBAAyB,EAAoB,CAC3C,IAAM,EAA0C,CAC9C,KAAM,OACN,QAAS,SACT,KAAM,kBACN,QAAS,YACT,OACA,UAAW,qBACX,WAAY,cACZ,cAAe,eACf,QAAS,GACT,QAAS,IACV,CAEG,EAEJ,GAAI,EAAW,KAAK,eAAe,CAAE,CAGnC,IAAM,EAAS,EADC,EAAa,KAAK,eAAgB,QAAQ,CACxB,CAG5B,EAAiB,EAAO,gBAAkB,EAAE,CAG5C,EAAgB,EAAe,UAAW,GAAW,EAAO,OAAS,kBAAkB,CAEzF,GAAiB,EAEnB,EAAe,GAAiB,EAGhC,EAAe,KAAK,EAAa,CAGnC,EAAa,CACX,QAAS,EAAO,QAChB,iBACD,MAGD,EAAa,CACX,QAAS,QACT,eAAgB,CAAC,EAAa,CAC/B,CAGH,EAAc,KAAK,eAAgB,KAAK,UAAU,EAAY,IAAA,GAAW,EAAE,CAAG;EAAM,QAAQ,CAG9F,iBAAgC,CAC9B,IAAM,EAAmB,CACvB,MAAO,eACP,KAAM,QACN,QAAS,eACT,aAAc,GACd,eAAgB,CACd,QAAS,CAAE,OAAQ,KAAM,CACzB,WAAY,CACV,cAAe,GACf,cAAe,EACf,YAAa,EACd,CACF,CACF,CAEG,EAEJ,GAAI,EAAW,KAAK,cAAc,CAAE,CAGlC,IAAM,EAAS,EADC,EAAa,KAAK,cAAe,QAAQ,CACvB,CAG5B,EAAQ,EAAO,OAAS,EAAE,CAG1B,EAAgB,EAAM,UAAW,GAAM,EAAE,QAAU,eAAe,CAEpE,GAAiB,EAEnB,EAAM,GAAiB,EAGvB,EAAM,KAAK,EAAK,CAGlB,EAAY,CACV,QAAS,EAAO,QAChB,QACD,MAGD,EAAY,CACV,QAAS,QACT,MAAO,CAAC,EAAK,CACd,CAGH,EAAc,KAAK,cAAe,KAAK,UAAU,EAAW,IAAA,GAAW,EAAE,CAAG;EAAM,QAAQ,GAI9F,EAAe,EAAc,CAC3B,KAAM,WACN,YAAa,+CACb,QAAS,CAAM;;;uCAGsBC,EAAO,QAAQ,qBAAqB,CAAC;;;IAI1E,SAAU,CACR,eACA,2BACA,kCACA,kCACA,6CACA,8CACD,CACD,YAAa,CACX,CACE,KAAM,YACN,YAAa,uBACb,QAAS,0DACV,CACF,CACD,MAAO,CACL,GAAG,EACH,SAAU,CACR,KAAM,OACN,MAAO,CAAC,KAAK,CACb,YAAa,+BACb,UAAW,OACX,QAAS,uEACV,CACD,cAAe,CACb,KAAM,OACN,MAAO,KACP,YAAa,mDACb,UAAW,SACX,QAAS,mHACT,SAAU,MAAO,EAAM,IAAY,CACjC,GAAM,CAAE,kBAAmB,MAAM,OAAO,4BACxC,OAAO,EAAe,CAAC,GAAG,EAAiB,CAAE,EAAQ,EAExD,CACF,CACD,IAAK,MAAO,EAAK,IAAU,CACzB,IAAM,EAAY,MAAM,EAAsB,EAAM,EAAE,IAAM,EAAQ,KAAK,CAAC,CACpE,EAAc,MAAM,EAAY,KAAK,EAAK,CAAE,QAAS,WAAY,QAAO,YAAW,CAAC,CAG1F,GAAI,EAAM,eAAgB,CACxB,IAAM,EAAS,EAAM,eAAe,aAAa,CACjD,GAAI,CAAC,EAAiB,SAAS,EAA4C,CACzE,MAAM,IAAI,EAAU,mBAAmB,EAAM,eAAe,wBAAwB,EAAiB,KAAK,KAAK,GAAI,CACjH,UAAW,GACZ,CAAC,CAGJ,IAAM,EAAe,IAAI,EAAqB,EAAU,KAAK,CACvD,EAAO,EAAM,WAAa,KAChC,EAAa,UAAU,EAAK,CAE5B,EAAQ,CACN,qBAAsB,GACtB,QAASA,EAAO,QAAQ,GAAG,EAAO,KAAK,cAAc,EAAO,WAAW,CACxE,CAAC,CACF,EAAQ,CACN,QAAS,CAAM;;cAET,EAAa,eAAe;cAC5B,EAAa,cAAc;;;UAIlC,CAAC,CACF,OAGF,IAAM,EAAU,EAAK,GAAG,EAAgB,OAAO,EAAY,YAAY,KAAK,cAAc,CAC1F,EAAI,IAAI,KAAK,2BAA2B,CAExC,EAAI,IAAI,MAAM,mBAAoB,CAChC,IAAK,EAAY,YAAY,YAAY,KACzC,YAAa,EAAY,YAAY,KACtC,CAAC,CAEF,IAAM,EAAc,EAAgB,EAAI,CAClC,EAAO,EAAM,WAAa,KAC1B,EAAY,GAAY,CAGT,IAAI,EAAqB,EAAU,KAAK,CAC3C,wBAAwB,GACxC,EAAI,IAAI,KAAK,iDAAiD,CAC9D,EAAQ,CACN,qBAAsB,GACtB,QAASA,EAAO,QACd,0CAA0CA,EAAO,WAAW,4BAA4B,EAAiB,KAAK,CAAC,cAChH,CACF,CAAC,EAGJ,IAAM,EAAQ,IAAI,EAAc,EAAK,CACnC,cACA,cACA,YACA,OACD,CAAC,CAEF,GAAI,CACF,MAAM,EAAM,OAAO,CAEnB,EAAQ,SAAS,CACjB,EAAQ,CACN,qBAAsB,GACtB,QAASA,EAAO,QAAQ,GAAG,EAAO,KAAK,GAAG,EAAe,kBAAkB,EAAK,GAAG,IAAY,CAChG,CAAC,CACF,EAAQ,CAAE,QAASA,EAAO,QAAQ,uBAAuB,CAAE,CAAC,CAE5D,MAAM,IAAI,QAAe,GAAY,CACnC,EAAI,YAAc,CAChB,EAAI,IAAI,KAAK,wBAAwB,CACrC,GAAS,EACT,EACF,CAEF,EAAM,MAAM,CACZ,EAAQ,CAAE,qBAAsB,GAAM,QAAS,GAAG,EAAO,KAAK,uBAAwB,CAAC,OAChF,EAAO,CACd,EAAI,IAAI,MAAM,0BAA2B,CAAE,QAAO,CAAC,CACnD,MAAM,EAAmB,EAAK,EAAM,GAGzC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{o as e}from"./chunk-BjEoQXZ0.js";import{V as t,c as n,d as r,l as i}from"./command-2iNTc5dV.js";import{r as a}from"./directory-CNL03L6c.js";import{t as o}from"./select-Dey_sjjd.js";var s=e(t(),1);const c=async e=>{let t=r.defaultsConfigFile,i;if(await o({ensureEmptyLineAbove:!0,choices:[`default`,`configure`],content:`Default configuration from Gadget or configure manually`})===`configure`){let e=await o({ensureEmptyLineAbove:!0,choices:[`enable`,`disable`],content:`Automatically send crash reports and telemetry to Gadget`}),t=await o({ensureEmptyLineAbove:!0,choices:[`disable`,`enable`],content:`ggt output as JSON`});i={telemetry:e===`enable`,json:t===`enable`}}else i={telemetry:!0,json:!1};return await s.default.outputJSON(t,i).then(()=>{n(`Default arguments were saved.`)},t=>{e.log.error(`failed to write config`,{error:t.message})}),i},l=async(e,t)=>{let o=r.defaultsConfigFile,l;try{l=await s.default.readJSON(o)}catch(r){a(r),i.isInteractive&&t?(n(`No ggt defaults were found to have been configured. Please answer the prompts to configure your defaults.`),l=await c(e),n("To update these options later, see `ggt configure`.")):l={}}return l},u=async e=>{let t=r.defaultsConfigFile;await s.default.outputJSON(t,{}).then(()=>{n(`Default arguments were saved.`)},t=>{e.log.error(`failed to write config`,{error:t.message})})};export{l as n,c as r,u as t};
2
+ //# sourceMappingURL=defaults-B_eD7Pia.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults-B_eD7Pia.js","names":["fs"],"sources":["../src/services/config/defaults.ts"],"sourcesContent":["import fs from \"fs-extra\";\n\nimport type { Context } from \"../command/context.ts\";\nimport { swallowEnoent } from \"../filesync/directory.ts\";\nimport { output } from \"../output/output.ts\";\nimport { println } from \"../output/print.ts\";\nimport { select } from \"../output/select.ts\";\nimport { config } from \"./config.ts\";\n\nexport type DefaultsConfigData = {\n telemetry?: boolean;\n json?: boolean;\n};\n\nexport const promptDefaultsConfig = async (ctx: Context): Promise<DefaultsConfigData> => {\n const path = config.defaultsConfigFile;\n let selections: DefaultsConfigData;\n\n const defaultSelection = await select({\n ensureEmptyLineAbove: true,\n choices: [\"default\", \"configure\"],\n content: \"Default configuration from Gadget or configure manually\",\n });\n\n if (defaultSelection === \"configure\") {\n const telemetrySelection = await select({\n ensureEmptyLineAbove: true,\n choices: [\"enable\", \"disable\"],\n content: \"Automatically send crash reports and telemetry to Gadget\",\n });\n\n const jsonSelection = await select({\n ensureEmptyLineAbove: true,\n choices: [\"disable\", \"enable\"],\n content: \"ggt output as JSON\",\n });\n\n selections = {\n telemetry: telemetrySelection === \"enable\",\n json: jsonSelection === \"enable\",\n };\n } else {\n /* === \"default\" */\n selections = {\n telemetry: true,\n json: false,\n };\n }\n\n await fs.outputJSON(path, selections).then(\n () => {\n println(\"Default arguments were saved.\");\n },\n (err: unknown) => {\n ctx.log.error(\"failed to write config\", { error: (err as Error).message });\n },\n );\n\n return selections;\n};\n\nexport const loadDefaultsConfig = async (ctx: Context, promptIfMissing: boolean): Promise<DefaultsConfigData> => {\n const configFilePath = config.defaultsConfigFile;\n\n let configData: null | DefaultsConfigData;\n\n try {\n configData = (await fs.readJSON(configFilePath)) as DefaultsConfigData;\n } catch (error) {\n swallowEnoent(error);\n\n /* If there's no config defaults, and it isn't interactive, we can just move on. */\n if (output.isInteractive && promptIfMissing) {\n println(\"No ggt defaults were found to have been configured. Please answer the prompts to configure your defaults.\");\n configData = await promptDefaultsConfig(ctx);\n println(\"To update these options later, see `ggt configure`.\");\n } else {\n configData = {};\n }\n }\n\n return configData;\n};\n\nexport const clearDefaultsConfig = async (ctx: Context): Promise<void> => {\n const path = config.defaultsConfigFile;\n await fs.outputJSON(path, {}).then(\n () => {\n println(\"Default arguments were saved.\");\n },\n (err: unknown) => {\n ctx.log.error(\"failed to write config\", { error: (err as Error).message });\n },\n );\n};\n"],"mappings":"2MAcA,MAAa,EAAuB,KAAO,IAA8C,CACvF,IAAM,EAAO,EAAO,mBAChB,EAQJ,GANyB,MAAM,EAAO,CACpC,qBAAsB,GACtB,QAAS,CAAC,UAAW,YAAY,CACjC,QAAS,0DACV,CAAC,GAEuB,YAAa,CACpC,IAAM,EAAqB,MAAM,EAAO,CACtC,qBAAsB,GACtB,QAAS,CAAC,SAAU,UAAU,CAC9B,QAAS,2DACV,CAAC,CAEI,EAAgB,MAAM,EAAO,CACjC,qBAAsB,GACtB,QAAS,CAAC,UAAW,SAAS,CAC9B,QAAS,qBACV,CAAC,CAEF,EAAa,CACX,UAAW,IAAuB,SAClC,KAAM,IAAkB,SACzB,MAGD,EAAa,CACX,UAAW,GACX,KAAM,GACP,CAYH,OATA,MAAMA,EAAAA,QAAG,WAAW,EAAM,EAAW,CAAC,SAC9B,CACJ,EAAQ,gCAAgC,EAEzC,GAAiB,CAChB,EAAI,IAAI,MAAM,yBAA0B,CAAE,MAAQ,EAAc,QAAS,CAAC,EAE7E,CAEM,GAGI,EAAqB,MAAO,EAAc,IAA0D,CAC/G,IAAM,EAAiB,EAAO,mBAE1B,EAEJ,GAAI,CACF,EAAc,MAAMA,EAAAA,QAAG,SAAS,EAAe,OACxC,EAAO,CACd,EAAc,EAAM,CAGhB,EAAO,eAAiB,GAC1B,EAAQ,4GAA4G,CACpH,EAAa,MAAM,EAAqB,EAAI,CAC5C,EAAQ,sDAAsD,EAE9D,EAAa,EAAE,CAInB,OAAO,GAGI,EAAsB,KAAO,IAAgC,CACxE,IAAM,EAAO,EAAO,mBACpB,MAAMA,EAAAA,QAAG,WAAW,EAAM,EAAE,CAAC,CAAC,SACtB,CACJ,EAAQ,gCAAgC,EAEzC,GAAiB,CAChB,EAAI,IAAI,MAAM,yBAA0B,CAAE,MAAQ,EAAc,QAAS,CAAC,EAE7E"}
@@ -0,0 +1,15 @@
1
+ import"./ms-B7sMc0pR.js";import"./src-DxCC1MV4.js";import"./prompt-C9nwJW0G.js";import{G as e,dt as t,g as n,gt as r,q as i,s as a}from"./http-CY3lPMkt.js";import{Ct as o,E as s,T as c,c as l,l as u,n as d,s as f}from"./command-2iNTc5dV.js";import{c as p,l as m,t as h,u as g}from"./filesync-De6asZeR.js";import"./collection-C2TCeYqY.js";import{t as _}from"./indent-string-BVm-4tyL.js";import"./directory-CNL03L6c.js";import"./session-BmzGF1t7.js";import{_ as v,g as y,m as b,n as x,r as S,s as C,t as w}from"./sync-json-V52OzeCz.js";import"./select-Dey_sjjd.js";import{n as T}from"./spinner-BVmbgIil.js";import"./table-MrBbxMay.js";import{t as E}from"./assert-Bu1E126Z.js";import D from"node:assert";const O=Object.freeze({NOT_STARTED:`NOT_STARTED`,STARTING:`STARTING`,BUILDING_ASSETS:`BUILDING_ASSETS`,UPLOADING_ASSETS:`UPLOADING_ASSETS`,CONVERGING_STORAGE:`CONVERGING_STORAGE`,PUBLISHING_TREE:`PUBLISHING_TREE`,RELOADING_SANDBOX:`RELOADING_SANDBOX`,COMPLETED:`COMPLETED`}),k=(e,t)=>{switch(t){case O.NOT_STARTED:case O.STARTING:case O.BUILDING_ASSETS:case O.UPLOADING_ASSETS:return`Building frontend assets.`;case O.CONVERGING_STORAGE:return`Setting up database.`;case O.PUBLISHING_TREE:return`Copying ${e.environment.name}.`;case O.RELOADING_SANDBOX:return`Restarting app.`;case O.COMPLETED:return`Deploy complete!`;default:return`Unknown step.`}},A=(e,t)=>{switch(t){case O.NOT_STARTED:case O.STARTING:case O.BUILDING_ASSETS:case O.UPLOADING_ASSETS:return`Built frontend assets. ${g()}`;case O.CONVERGING_STORAGE:return`Setup database. ${g()}`;case O.PUBLISHING_TREE:return`Copied ${e.environment.name}. ${g()}`;case O.RELOADING_SANDBOX:return`Restarted app. ${g()}`;case O.COMPLETED:return`Deploy successful!`;default:return`Completed unknown step. ${g()}`}};var j=d({name:`deploy`,description:`Deploy an environment to production`,details:s`
2
+ Performs a two-step process: first pushes your local file changes to the environment,
3
+ then deploys that environment to production. If local and environment files have
4
+ diverged since the last sync, you'll be prompted to push your local changes and discard
5
+ the environment's changes before the deploy proceeds. Use --force to skip this prompt.
6
+ `,sections:[{title:`CI/CD Usage`,content:s`
7
+ In non-interactive environments, pass ${f.subdued(`--allow-all`)} or individual
8
+ ${f.subdued(`--allow-*`)} flags to skip interactive prompts:
9
+
10
+ ggt deploy --force --allow-all
11
+ ggt deploy --force --allow=problems,charges,data-delete
12
+ ggt deploy --force --allow-problems --allow-charges --allow-data-delete
13
+ `},{title:`See Also`,content:`ggt problems — Check for errors before deploying.
14
+ ggt push — Upload files without deploying to production.`}],examples:[`ggt deploy`,`ggt deploy --env staging`,`ggt deploy --force --allow-all`,`ggt deploy --force --allow=problems,charges,data-delete`,`ggt deploy --env staging --force --allow-problems --allow-charges --allow-data-delete`],flags:{...x,"--force":{type:Boolean,alias:`-f`,description:`Skip the push confirmation prompt`,details:`Any conflicting changes on the environment are discarded without prompting.`},"--environment":{...a,alias:[`-e`,`--env`,`--from`],description:`Environment to deploy from`,details:`The source development environment whose files and schema will be deployed to production. Defaults to the environment recorded in .gadget/sync.json.`},"--allow-problems":{type:Boolean,alias:`--allow-issues`,description:`Allow deploying with problems`,details:`Problems include Gelly errors, TypeScript errors, and missing references. Without this flag, the deploy is blocked until all issues are resolved.`,brief:!1},"--allow-charges":{type:Boolean,description:`Allow deploying with new charges`,details:`Use this flag in CI/CD pipelines to skip the interactive billing confirmation prompt that appears when a deploy would add charges to your plan.`,brief:!1},"--allow-data-delete":{type:Boolean,description:`Allow deploying with data loss`,details:`Removed models and fields have their production data permanently deleted. Without this flag, the deploy is blocked when removals are detected.`,brief:!1}},run:async(a,d)=>{let x=await S(process.cwd()),j=await w.loadOrAskAndInit(a,{command:`deploy`,flags:d,directory:x});l({ensureEmptyLineAbove:!0,content:`Deploying ${j.environment.name} to ${r(j.environment.application.primaryDomain,`https://${j.environment.application.primaryDomain}/`)}`});let M=new h(j),N=await M.hashes(a);if(!N.inSync&&(N.localChangesToPush.size>0||!N.onlyDotGadgetFilesChanged)){if(await M.print(a,{hashes:N}),!d[`--force`])if(l({ensureEmptyLineAbove:!0,content:`Your environment's files must match your local files before you can deploy.`}),u.isInteractive||c.testLike){let e;switch(!0){case N.bothChanged:e=s`Would you like to push your local changes and ${f.emphasis(`discard your environment's`)} changes now?`;break;case N.localChangesToPush.size>0:e=s`Would you like to push your local changes now?`;break;case N.environmentChanges.size>0:e=s`Do you want to ${f.emphasis(`discard your environment's`)} changes now?`;break;default:E(`no changes to push or discard`)}await n(e)}else l({ensureEmptyLineAbove:!0,content:`Assuming you want to push your local files now.`});await M.push(a,{command:`deploy`,hashes:N})}let P={localFilesVersion:String(j.filesVersion),force:d[`--allow-problems`],allowDeletedData:d[`--allow-data-delete`],allowCharges:d[`--allow-charges`]},F,I=O.NOT_STARTED,L=!1,R=j.edit.subscribe({subscription:t,variables:P,onError:async e=>{a.log.error(`failed to deploy`,{error:e}),F?.fail(k(j,I)+` `+g());let t=o(e.cause);if(t){let e=t[0];if(D(e,`expected graphqlError to be defined`),e.extensions.requiresUpgrade&&(l({ensureEmptyLineAbove:!0,content:e.message.replace(/GGT_PAYMENT_REQUIRED:?\s*/,``)}),process.exit(1)),e.extensions.requiresAdditionalCharge){l({ensureEmptyLineAbove:!0,content:e.message.replace(/GGT_PAYMENT_REQUIRED:?\s*/,``)}),await n({ensureEmptyLineAbove:!0,content:`Do you want to continue?`}),R.resubscribe({...P,allowCharges:!0});return}}await i(a,e)},onData:async({publishStatus:t})=>{if(!t){a.log.warn(`received empty publish status`);return}let{publishStarted:o,progress:c,issues:h,status:x,deletedModelsAndFields:S}=t,w=h.length>0,{deletedModels:E,deletedModelFields:D}=S??{deletedModels:[],deletedModelFields:[]},M=E.length>0||D.length>0;if(!L&&(w||M)){L=!0;let t=h.filter(e=>e.severity===b.Fatal);if(t.length>0&&await i(a,new C(v(t))),w&&(l({ensureEmptyLineAbove:!0,content:`${f.warning(`!`)} ${f.header(`Issues found in your development app`)}`}),y({problems:v(h)})),M){l({ensureEmptyLineAbove:!0,content:`${f.warning(`!`)} ${f.header(`Data deleted on deploy`)}`});let e=f.updated(`updated`),t=f.deleted(`deleted`),n=[];E.forEach(e=>{n.push({symbol:p,name:f.deleted(e),action:t,indent:0})}),D.forEach(({modelIdentifier:r,fields:i})=>{n.push({symbol:m,name:f.updated(r),action:e,indent:0}),i.forEach(e=>{n.push({symbol:p,name:f.deleted(e),action:t,indent:2})})});let r=n.reduce((e,t)=>Math.max(e,t.name.length),0),i=n.reduce((e,t)=>Math.max(e,t.indent),0);l({ensureEmptyLineAbove:!0,content:f.hint(`These changes will be applied to production based on the app you're deploying.`)});for(let e of n){let t=` `.repeat(e.indent*2),n=` `.repeat(r-e.name.length+2),a=` `.repeat((i-e.indent)*2);l({ensureEmptyLineAbove:!1,content:_(`${t}${e.symbol} ${e.name}${n}${a}${e.action}`,6)})}}if(!o)await n(`Do you want to continue?`),R.resubscribe({...P,force:!0,allowDeletedData:!0});else{let t=d[`--allow-data-delete`],n=d[`--allow-problems`];if(!t&&!n)throw new e(`expected --allow-data-delete or --allow-problems to be true`);n&&l(s`Deploying regardless of problems because "${f.hint(`--allow-problems`)}" was passed.`),t&&l(s`Deploying regardless of deleted data because "${f.hint(`--allow-data-delete`)}" was passed.`)}return}if(x?.code===`Errored`){F?.fail(k(j,I)+` `+g()),x.message&&l({ensureEmptyLineAbove:!0,content:f.error(x.message)}),x.output&&l({ensureEmptyLineAbove:!0,content:s`${r(`Check logs`,x.output)}`});return}if(c===O.COMPLETED){F?.succeed(A(j,I));let e=f.success(`Deploy successful!`);x?.output&&(e+=` ${r(`Check logs`,x.output)}.`),l({ensureEmptyLineAbove:!0,content:e});return}if(c!==I){let e=k(j,c);e!==F?.text&&(F?.succeed(A(j,I)),F=T({ensureEmptyLineAbove:I===O.NOT_STARTED||!u.isInteractive,content:e})),I=c}},onComplete:()=>{R.unsubscribe()}})}});export{j as default};
15
+ //# sourceMappingURL=deploy-Da6P2HXS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy-Da6P2HXS.js","names":["colors"],"sources":["../src/commands/deploy.ts"],"sourcesContent":["import assert from \"node:assert\";\n\nimport indentString from \"indent-string\";\nimport terminalLink from \"terminal-link\";\n\nimport { EnvArg } from \"../services/app/app.ts\";\nimport { PUBLISH_STATUS_SUBSCRIPTION } from \"../services/app/edit/operation.ts\";\nimport { defineCommand } from \"../services/command/command.ts\";\nimport { env } from \"../services/config/env.ts\";\nimport { deletedSymbol, updatedSymbol } from \"../services/filesync/changes.ts\";\nimport { DeployDisallowedError } from \"../services/filesync/error.ts\";\nimport { FileSync } from \"../services/filesync/filesync.ts\";\nimport { SyncJson, SyncJsonFlags, loadSyncJsonDirectory } from \"../services/filesync/sync-json.ts\";\nimport colors from \"../services/output/colors.ts\";\nimport { confirm } from \"../services/output/confirm.ts\";\nimport { output } from \"../services/output/output.ts\";\nimport { println } from \"../services/output/print.ts\";\nimport { ProblemSeverity, printProblems, publishIssuesToProblems } from \"../services/output/problems.ts\";\nimport { UnexpectedError, reportErrorAndExit } from \"../services/output/report.ts\";\nimport { spin, type spinner } from \"../services/output/spinner.ts\";\nimport { sprint } from \"../services/output/sprint.ts\";\nimport { ts } from \"../services/output/timestamp.ts\";\nimport { unreachable } from \"../services/util/assert.ts\";\nimport { parseGraphQLErrors } from \"../services/util/is.ts\";\n\nconst AppDeploymentSteps = Object.freeze({\n NOT_STARTED: \"NOT_STARTED\",\n STARTING: \"STARTING\",\n BUILDING_ASSETS: \"BUILDING_ASSETS\",\n UPLOADING_ASSETS: \"UPLOADING_ASSETS\",\n CONVERGING_STORAGE: \"CONVERGING_STORAGE\",\n PUBLISHING_TREE: \"PUBLISHING_TREE\",\n RELOADING_SANDBOX: \"RELOADING_SANDBOX\",\n COMPLETED: \"COMPLETED\",\n});\n\ntype AppDeploymentSteps = (typeof AppDeploymentSteps)[keyof typeof AppDeploymentSteps];\n\nconst stepToSpinnerStart = (syncJson: SyncJson, step: string): string => {\n switch (step) {\n case AppDeploymentSteps.NOT_STARTED:\n case AppDeploymentSteps.STARTING:\n case AppDeploymentSteps.BUILDING_ASSETS:\n case AppDeploymentSteps.UPLOADING_ASSETS:\n return \"Building frontend assets.\";\n case AppDeploymentSteps.CONVERGING_STORAGE:\n return \"Setting up database.\";\n case AppDeploymentSteps.PUBLISHING_TREE:\n return `Copying ${syncJson.environment.name}.`;\n case AppDeploymentSteps.RELOADING_SANDBOX:\n return \"Restarting app.\";\n case AppDeploymentSteps.COMPLETED:\n return \"Deploy complete!\";\n default:\n return \"Unknown step.\";\n }\n};\n\nconst stepToSpinnerEnd = (syncJson: SyncJson, step: string): string => {\n switch (step) {\n case AppDeploymentSteps.NOT_STARTED:\n case AppDeploymentSteps.STARTING:\n case AppDeploymentSteps.BUILDING_ASSETS:\n case AppDeploymentSteps.UPLOADING_ASSETS:\n return `Built frontend assets. ${ts()}`;\n case AppDeploymentSteps.CONVERGING_STORAGE:\n return `Setup database. ${ts()}`;\n case AppDeploymentSteps.PUBLISHING_TREE:\n return `Copied ${syncJson.environment.name}. ${ts()}`;\n case AppDeploymentSteps.RELOADING_SANDBOX:\n return `Restarted app. ${ts()}`;\n case AppDeploymentSteps.COMPLETED:\n return \"Deploy successful!\";\n default:\n return `Completed unknown step. ${ts()}`;\n }\n};\n\nexport default defineCommand({\n name: \"deploy\",\n description: \"Deploy an environment to production\",\n details: sprint`\n Performs a two-step process: first pushes your local file changes to the environment,\n then deploys that environment to production. If local and environment files have\n diverged since the last sync, you'll be prompted to push your local changes and discard\n the environment's changes before the deploy proceeds. Use --force to skip this prompt.\n `,\n sections: [\n {\n title: \"CI/CD Usage\",\n content: sprint`\n In non-interactive environments, pass ${colors.subdued(\"--allow-all\")} or individual\n ${colors.subdued(\"--allow-*\")} flags to skip interactive prompts:\n\n ggt deploy --force --allow-all\n ggt deploy --force --allow=problems,charges,data-delete\n ggt deploy --force --allow-problems --allow-charges --allow-data-delete\n `,\n },\n {\n title: \"See Also\",\n content: \"ggt problems — Check for errors before deploying.\\nggt push — Upload files without deploying to production.\",\n },\n ],\n examples: [\n \"ggt deploy\",\n \"ggt deploy --env staging\",\n \"ggt deploy --force --allow-all\",\n \"ggt deploy --force --allow=problems,charges,data-delete\",\n \"ggt deploy --env staging --force --allow-problems --allow-charges --allow-data-delete\",\n ],\n flags: {\n ...SyncJsonFlags,\n \"--force\": {\n type: Boolean,\n alias: \"-f\",\n description: \"Skip the push confirmation prompt\",\n details: \"Any conflicting changes on the environment are discarded without prompting.\",\n },\n \"--environment\": {\n ...EnvArg,\n alias: [\"-e\", \"--env\", \"--from\"],\n description: \"Environment to deploy from\",\n details:\n \"The source development environment whose files and schema will be deployed to production. Defaults to the environment recorded in .gadget/sync.json.\",\n },\n \"--allow-problems\": {\n type: Boolean,\n alias: \"--allow-issues\",\n description: \"Allow deploying with problems\",\n details:\n \"Problems include Gelly errors, TypeScript errors, and missing references. Without this flag, the deploy is blocked until all issues are resolved.\",\n brief: false,\n },\n \"--allow-charges\": {\n type: Boolean,\n description: \"Allow deploying with new charges\",\n details:\n \"Use this flag in CI/CD pipelines to skip the interactive billing confirmation prompt that appears when a deploy would add charges to your plan.\",\n brief: false,\n },\n \"--allow-data-delete\": {\n type: Boolean,\n description: \"Allow deploying with data loss\",\n details:\n \"Removed models and fields have their production data permanently deleted. Without this flag, the deploy is blocked when removals are detected.\",\n brief: false,\n },\n },\n run: async (ctx, flags) => {\n const directory = await loadSyncJsonDirectory(process.cwd());\n const syncJson = await SyncJson.loadOrAskAndInit(ctx, { command: \"deploy\", flags, directory });\n\n println({\n ensureEmptyLineAbove: true,\n content: `Deploying ${syncJson.environment.name} to ${terminalLink(syncJson.environment.application.primaryDomain, `https://${syncJson.environment.application.primaryDomain}/`)}`,\n });\n\n const filesync = new FileSync(syncJson);\n const hashes = await filesync.hashes(ctx);\n if (!hashes.inSync && (hashes.localChangesToPush.size > 0 || !hashes.onlyDotGadgetFilesChanged)) {\n // the following is true:\n // 1. our local files don't match our environment's files\n // 2. we have local changes to push or non .gadget/ files have changed on our environment\n // therefore, we need to push before we can deploy\n await filesync.print(ctx, { hashes });\n\n if (!flags[\"--force\"]) {\n // they didn't pass --force, so we need to ask them if they want to push\n println({\n ensureEmptyLineAbove: true,\n content: \"Your environment's files must match your local files before you can deploy.\",\n });\n\n if (output.isInteractive || env.testLike) {\n // we're interactive, so ask them what they want to do\n let content: string;\n switch (true) {\n case hashes.bothChanged:\n content = sprint`Would you like to push your local changes and ${colors.emphasis(\"discard your environment's\")} changes now?`;\n break;\n case hashes.localChangesToPush.size > 0:\n content = sprint`Would you like to push your local changes now?`;\n break;\n case hashes.environmentChanges.size > 0:\n content = sprint`Do you want to ${colors.emphasis(\"discard your environment's\")} changes now?`;\n break;\n default:\n unreachable(\"no changes to push or discard\");\n }\n\n await confirm(content);\n } else {\n // we're not interactive, so we're likely in a CI/CD environment\n // assume they want to push\n println({\n ensureEmptyLineAbove: true,\n content: \"Assuming you want to push your local files now.\",\n });\n }\n }\n\n await filesync.push(ctx, { command: \"deploy\", hashes });\n }\n\n const variables = {\n localFilesVersion: String(syncJson.filesVersion),\n force: flags[\"--allow-problems\"],\n allowDeletedData: flags[\"--allow-data-delete\"],\n allowCharges: flags[\"--allow-charges\"],\n };\n\n let spinner: spinner | undefined;\n let currentStep: AppDeploymentSteps = AppDeploymentSteps.NOT_STARTED;\n let printedProblems = false;\n\n const subscription = syncJson.edit.subscribe({\n subscription: PUBLISH_STATUS_SUBSCRIPTION,\n variables,\n onError: async (error) => {\n ctx.log.error(\"failed to deploy\", { error });\n spinner?.fail(stepToSpinnerStart(syncJson, currentStep) + \" \" + ts());\n\n const graphqlErrors = parseGraphQLErrors(error.cause);\n if (graphqlErrors) {\n const graphqlError = graphqlErrors[0];\n assert(graphqlError, \"expected graphqlError to be defined\");\n\n if (graphqlError.extensions[\"requiresUpgrade\"]) {\n println({ ensureEmptyLineAbove: true, content: graphqlError.message.replace(/GGT_PAYMENT_REQUIRED:?\\s*/, \"\") });\n // Exits immediately -- upgrade errors are user-facing, not platform bugs\n process.exit(1);\n }\n if (graphqlError.extensions[\"requiresAdditionalCharge\"]) {\n println({ ensureEmptyLineAbove: true, content: graphqlError.message.replace(/GGT_PAYMENT_REQUIRED:?\\s*/, \"\") });\n await confirm({ ensureEmptyLineAbove: true, content: \"Do you want to continue?\" });\n subscription.resubscribe({ ...variables, allowCharges: true });\n return;\n }\n }\n\n await reportErrorAndExit(ctx, error);\n },\n onData: async ({ publishStatus }): Promise<void> => {\n if (!publishStatus) {\n ctx.log.warn(\"received empty publish status\");\n return;\n }\n\n const { publishStarted, progress: step, issues, status, deletedModelsAndFields } = publishStatus;\n const hasIssues = issues.length > 0;\n\n const { deletedModels, deletedModelFields } = deletedModelsAndFields ?? { deletedModels: [], deletedModelFields: [] };\n const hasDataLoss = deletedModels.length > 0 || deletedModelFields.length > 0;\n\n if (!printedProblems && (hasIssues || hasDataLoss)) {\n printedProblems = true;\n\n const fatalIssues = issues.filter((issue) => issue.severity === ProblemSeverity.Fatal);\n if (fatalIssues.length > 0) {\n await reportErrorAndExit(ctx, new DeployDisallowedError(publishIssuesToProblems(fatalIssues)));\n }\n\n if (hasIssues) {\n println({\n ensureEmptyLineAbove: true,\n content: `${colors.warning(\"!\")} ${colors.header(\"Issues found in your development app\")}`,\n });\n printProblems({ problems: publishIssuesToProblems(issues) });\n }\n\n if (hasDataLoss) {\n println({\n ensureEmptyLineAbove: true,\n content: `${colors.warning(\"!\")} ${colors.header(\"Data deleted on deploy\")}`,\n });\n\n const updated = colors.updated(\"updated\");\n const deleted = colors.deleted(\"deleted\");\n\n const rows: { symbol: string; name: string; action: string; indent: number }[] = [];\n\n deletedModels.forEach((model: string) => {\n rows.push({ symbol: deletedSymbol, name: colors.deleted(model), action: deleted, indent: 0 });\n });\n\n deletedModelFields.forEach(({ modelIdentifier, fields }) => {\n rows.push({ symbol: updatedSymbol, name: colors.updated(modelIdentifier), action: updated, indent: 0 });\n fields.forEach((field) => {\n rows.push({ symbol: deletedSymbol, name: colors.deleted(field), action: deleted, indent: 2 });\n });\n });\n\n const longestNameLength = rows.reduce((longest, row) => Math.max(longest, row.name.length), 0);\n const longestIndent = rows.reduce((longest, row) => Math.max(longest, row.indent), 0);\n const indentSize = 2;\n\n println({\n ensureEmptyLineAbove: true,\n content: colors.hint(\"These changes will be applied to production based on the app you're deploying.\"),\n });\n for (const row of rows) {\n const indentation = \" \".repeat(row.indent * indentSize);\n const namePadding = \" \".repeat(longestNameLength - row.name.length + 2);\n const actionPadding = \" \".repeat((longestIndent - row.indent) * indentSize);\n println({\n ensureEmptyLineAbove: false,\n content: indentString(`${indentation}${row.symbol} ${row.name}${namePadding}${actionPadding}${row.action}`, 6),\n });\n }\n }\n\n if (!publishStarted) {\n await confirm(\"Do you want to continue?\");\n subscription.resubscribe({ ...variables, force: true, allowDeletedData: true });\n } else {\n const allowDataDelete = flags[\"--allow-data-delete\"];\n const allowProblems = flags[\"--allow-problems\"];\n\n if (!allowDataDelete && !allowProblems) {\n throw new UnexpectedError(\"expected --allow-data-delete or --allow-problems to be true\");\n }\n\n if (allowProblems) {\n println(sprint`Deploying regardless of problems because \"${colors.hint(\"--allow-problems\")}\" was passed.`);\n }\n\n if (allowDataDelete) {\n println(sprint`Deploying regardless of deleted data because \"${colors.hint(\"--allow-data-delete\")}\" was passed.`);\n }\n }\n\n return;\n }\n\n if (status?.code === \"Errored\") {\n spinner?.fail(stepToSpinnerStart(syncJson, currentStep) + \" \" + ts());\n\n if (status.message) {\n println({ ensureEmptyLineAbove: true, content: colors.error(status.message) });\n }\n if (status.output) {\n println({ ensureEmptyLineAbove: true, content: sprint`${terminalLink(\"Check logs\", status.output)}` });\n }\n return;\n }\n\n if (step === AppDeploymentSteps.COMPLETED) {\n spinner?.succeed(stepToSpinnerEnd(syncJson, currentStep));\n\n let content = colors.success(\"Deploy successful!\");\n if (status?.output) {\n content += ` ${terminalLink(\"Check logs\", status.output)}.`;\n }\n\n println({ ensureEmptyLineAbove: true, content });\n return;\n }\n\n if (step !== currentStep) {\n const spinnerText = stepToSpinnerStart(syncJson, step);\n if (spinnerText !== spinner?.text) {\n // stop the current spinner, if any, and start a new one\n spinner?.succeed(stepToSpinnerEnd(syncJson, currentStep));\n\n const ensureEmptyLineAbove = currentStep === AppDeploymentSteps.NOT_STARTED || !output.isInteractive;\n spinner = spin({ ensureEmptyLineAbove, content: spinnerText });\n }\n\n currentStep = step as AppDeploymentSteps;\n }\n },\n onComplete: () => {\n subscription.unsubscribe();\n },\n });\n },\n});\n"],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import{i as e,o as t,t as n}from"./chunk-BjEoQXZ0.js";import{t as r}from"./ms-B7sMc0pR.js";import"./src-DxCC1MV4.js";import{r as i}from"./prompt-C9nwJW0G.js";import{A as a,i as o,q as s,r as c}from"./http-CY3lPMkt.js";import{D as l,E as u,c as d,l as f,n as p,ot as m,s as h,y as g}from"./command-2iNTc5dV.js";import{i as _,n as v,r as y,s as b,t as ee}from"./filesync-De6asZeR.js";import"./collection-C2TCeYqY.js";import"./directory-CNL03L6c.js";import"./session-BmzGF1t7.js";import{d as x,n as S,r as C,t as w}from"./sync-json-V52OzeCz.js";import{t as T}from"./select-Dey_sjjd.js";import{n as E}from"./spinner-BVmbgIil.js";import"./table-MrBbxMay.js";import{a as D,o as te}from"./agent-plugin-DU9G5B1d.js";import{t as O}from"./assert-Bu1E126Z.js";import{r as k,t as A}from"./dev-lock-BFanZSu1.js";import{t as j}from"./subscribeToEnvironmentLogs-CUicaiw_.js";import{EventEmitter as ne}from"node:events";import M from"node:fs";import re from"node:os";import N from"node:path";import{promisify as P}from"node:util";import F from"node:process";var ie=t(a(),1),I=t(r(),1);const L=re.platform(),ae=L===`darwin`,R=L===`win32`,z=ae||R,oe=1250;var B;(function(e){e[e.DIR=1]=`DIR`,e[e.FILE=2]=`FILE`})(B||={});var V;(function(e){e.CHANGE=`change`,e.RENAME=`rename`})(V||={});var H;(function(e){e.CHANGE=`change`,e.ERROR=`error`})(H||={});var U;(function(e){e.ADD=`add`,e.ADD_DIR=`addDir`,e.CHANGE=`change`,e.RENAME=`rename`,e.RENAME_DIR=`renameDir`,e.UNLINK=`unlink`,e.UNLINK_DIR=`unlinkDir`})(U||={});var W;(function(e){e.ALL=`all`,e.CLOSE=`close`,e.ERROR=`error`,e.READY=`ready`})(W||={});const se=(e,t=1,n)=>{t=Math.max(1,t);let r=n?.leading??!1,i=n?.trailing??!0,a=Math.max(n?.maxWait??1/0,t),o,s,c=0,l=0,u=()=>{let e=Date.now(),n=e-c,r=e-l;return[e,n>=t||r>=a]},d=t=>{if(l=t,!o)return;let n=o;o=void 0,e.apply(void 0,n)},f=()=>{v(0)},p=()=>{s&&(f(),d(Date.now()))},m=e=>{if(l=e,r)return d(e)},h=e=>{if(i&&o)return d(e);o=void 0},g=()=>{s=void 0;let[e,t]=u();return t?h(e):_(e)},_=e=>{let n=e-c,r=e-l,i=t-n,o=a-r;return v(Math.min(i,o))},v=e=>{s&&clearTimeout(s),!(e<=0)&&(s=setTimeout(g,e))},y=(...e)=>{let[n,r]=u(),i=!!s;if(o=e,c=n,(r||!s)&&v(t),r)return i?d(n):m(n)};return y.cancel=f,y.flush=p,y},G=(e,t)=>function(...n){return e.apply(void 0,n).catch(t)},K=(e,t)=>function(...n){try{return e.apply(void 0,n)}catch(e){return t(e)}},ce=F.getuid?!F.getuid():!1,q=()=>void 0,J={isChangeErrorOk:e=>{if(!J.isNodeError(e))return!1;let{code:t}=e;return t===`ENOSYS`||!ce&&(t===`EINVAL`||t===`EPERM`)},isNodeError:e=>e instanceof Error,isRetriableError:e=>{if(!J.isNodeError(e))return!1;let{code:t}=e;return t===`EMFILE`||t===`ENFILE`||t===`EAGAIN`||t===`EBUSY`||t===`EACCESS`||t===`EACCES`||t===`EACCS`||t===`EPERM`},onChangeError:e=>{if(!J.isNodeError(e)||!J.isChangeErrorOk(e))throw e}};var le=new class{constructor(){this.interval=25,this.intervalId=void 0,this.limit=1e4,this.queueActive=new Set,this.queueWaiting=new Set,this.init=()=>{this.intervalId||=setInterval(this.tick,this.interval)},this.reset=()=>{this.intervalId&&(clearInterval(this.intervalId),delete this.intervalId)},this.add=e=>{this.queueWaiting.add(e),this.queueActive.size<this.limit/2?this.tick():this.init()},this.remove=e=>{this.queueWaiting.delete(e),this.queueActive.delete(e)},this.schedule=()=>new Promise(e=>{let t=()=>this.remove(n),n=()=>e(t);this.add(n)}),this.tick=()=>{if(!(this.queueActive.size>=this.limit)){if(!this.queueWaiting.size)return this.reset();for(let e of this.queueWaiting){if(this.queueActive.size>=this.limit)break;this.queueWaiting.delete(e),this.queueActive.add(e),e()}}}}};const Y=(e,t)=>function(n){return function r(...i){return le.schedule().then(a=>e.apply(void 0,i).then(e=>(a(),e),e=>{if(a(),Date.now()>=n)throw e;if(t(e)){let e=Math.round(100*Math.random());return new Promise(t=>setTimeout(t,e)).then(()=>r.apply(void 0,i))}throw e}))}},X=(e,t)=>function(n){return function r(...i){try{return e.apply(void 0,i)}catch(e){if(Date.now()>n)throw e;if(t(e))return r.apply(void 0,i);throw e}}},ue={attempt:{chmod:G(P(M.chmod),J.onChangeError),chown:G(P(M.chown),J.onChangeError),close:G(P(M.close),q),fsync:G(P(M.fsync),q),mkdir:G(P(M.mkdir),q),realpath:G(P(M.realpath),q),stat:G(P(M.stat),q),unlink:G(P(M.unlink),q),chmodSync:K(M.chmodSync,J.onChangeError),chownSync:K(M.chownSync,J.onChangeError),closeSync:K(M.closeSync,q),existsSync:K(M.existsSync,q),fsyncSync:K(M.fsync,q),mkdirSync:K(M.mkdirSync,q),realpathSync:K(M.realpathSync,q),statSync:K(M.statSync,q),unlinkSync:K(M.unlinkSync,q)},retry:{close:Y(P(M.close),J.isRetriableError),fsync:Y(P(M.fsync),J.isRetriableError),open:Y(P(M.open),J.isRetriableError),readFile:Y(P(M.readFile),J.isRetriableError),rename:Y(P(M.rename),J.isRetriableError),stat:Y(P(M.stat),J.isRetriableError),write:Y(P(M.write),J.isRetriableError),writeFile:Y(P(M.writeFile),J.isRetriableError),closeSync:X(M.closeSync,J.isRetriableError),fsyncSync:X(M.fsyncSync,J.isRetriableError),openSync:X(M.openSync,J.isRetriableError),readFileSync:X(M.readFileSync,J.isRetriableError),renameSync:X(M.renameSync,J.isRetriableError),statSync:X(M.statSync,J.isRetriableError),writeSync:X(M.writeSync,J.isRetriableError),writeFileSync:X(M.writeFileSync,J.isRetriableError)}},de=()=>{},fe=()=>{let e=de,t=de,n=!1,r=!1;return{promise:new Promise((i,a)=>{e=e=>(n=!0,i(e)),t=e=>(r=!0,a(e))}),resolve:e,reject:t,isPending:()=>!n&&!r,isResolved:()=>n,isRejected:()=>r}},pe=()=>{let{promise:e,resolve:t,isPending:n}=fe(),r=0,i=()=>{r+=1},a=()=>{--r,!r&&t()};return i(),queueMicrotask(a),{promise:e,isPending:n,increment:i,decrement:a}},me={then:e=>{e()}},he=e=>Array.isArray(e)?e:[e],ge=e=>typeof e==`function`,_e=(e,t)=>{let n=t?.followSymlinks??!1,r=t?.depth??1/0,i=t?.limit??1/0,a=he(t?.ignore??[]).map(e=>ge(e)?e:t=>e.test(t)),o=(e,t)=>a.some(n=>n(e,t)),s=t?.signal??{aborted:!1},c=t?.onDirents||(()=>{}),l=[],u=new Set,d={},f=[],p=new Set,m={},h=[],g=new Set,_={},v={},y=new Set,b={directories:[],directoriesNames:new Set,directoriesNamesToPaths:{},files:[],filesNames:new Set,filesNamesToPaths:{},symlinks:[],symlinksNames:new Set,symlinksNamesToPaths:{},map:{}},ee={directories:l,directoriesNames:u,directoriesNamesToPaths:d,files:f,filesNames:p,filesNamesToPaths:m,symlinks:h,symlinksNames:g,symlinksNamesToPaths:_,map:v},{promise:x,increment:S,decrement:C}=pe(),w=0,T=(e,t,n,a)=>{y.has(t)||w>=i||(w+=1,e.directories.push(t),e.directoriesNames.add(n),l.push(t),u.add(n),d.propertyIsEnumerable(n)||(d[n]=[]),d[n].push(t),y.add(t),!(a>=r)&&(w>=i||A(t,a+1)))},E=(e,t,n)=>{y.has(t)||w>=i||(w+=1,e.files.push(t),e.filesNames.add(n),f.push(t),p.add(n),m.propertyIsEnumerable(n)||(m[n]=[]),m[n].push(t),y.add(t))},D=(e,t,a,o)=>{y.has(t)||w>=i||(w+=1,e.symlinks.push(t),e.symlinksNames.add(a),h.push(t),g.add(a),_.propertyIsEnumerable(a)||(_[a]=[]),_[a].push(t),y.add(t),n&&(o>=r||w>=i||j(t,o+1)))},te=(e,t,n,r,i)=>{s.aborted||o(t,r.isDirectory())||(r.isDirectory()?T(e,t,n,i):r.isFile()?E(e,t,n):r.isSymbolicLink()&&D(e,t,n,i))},O=(e,t,n,r)=>{if(s.aborted)return;let i=t===N.sep?``:N.sep,a=n.name,c=`${t}${i}${a}`;o(c,n.isDirectory())||(n.isDirectory()?T(e,c,a,r):n.isFile()?E(e,c,a):n.isSymbolicLink()&&D(e,c,a,r))},k=(e,t,n,r)=>{for(let i=0,a=n.length;i<a;i++)O(e,t,n[i],r)},A=(e,t)=>{s.aborted||t>r||w>=i||(S(),M.readdir(e,{withFileTypes:!0},(n,r)=>{if(n||s.aborted||!r.length)return C();(c(r)||me).then(()=>{k(v[e]={directories:[],directoriesNames:new Set,directoriesNamesToPaths:{},files:[],filesNames:new Set,filesNamesToPaths:{},symlinks:[],symlinksNames:new Set,symlinksNamesToPaths:{}},e,r,t),C()})}))},j=(e,t)=>{S(),M.realpath(e,(n,r)=>{if(n||s.aborted)return C();M.stat(r,(n,i)=>{if(n||s.aborted)return C();let a=N.basename(r);te(v[e]={directories:[],directoriesNames:new Set,directoriesNamesToPaths:{},files:[],filesNames:new Set,filesNamesToPaths:{},symlinks:[],symlinksNames:new Set,symlinksNamesToPaths:{}},r,a,i,t),C()})})};return(async(e,t=1)=>(e=N.normalize(e),y.add(e),A(e,t),await x,s.aborted?b:ee))(e)},Z={lang:{debounce:se,attempt:e=>{try{return e()}catch(e){return Z.lang.castError(e)}},castArray:e=>Z.lang.isArray(e)?e:[e],castError:e=>Z.lang.isError(e)?e:Z.lang.isString(e)?Error(e):Error(`Unknown error`),defer:e=>setTimeout(e,0),isArray:e=>Array.isArray(e),isError:e=>e instanceof Error,isFunction:e=>typeof e==`function`,isNaN:e=>Number.isNaN(e),isNumber:e=>typeof e==`number`,isPrimitive:e=>{if(e===null)return!0;let t=typeof e;return t!==`object`&&t!==`function`},isShallowEqual:(e,t)=>{if(e===t)return!0;if(Z.lang.isNaN(e))return Z.lang.isNaN(t);if(Z.lang.isPrimitive(e)||Z.lang.isPrimitive(t))return e===t;for(let n in e)if(!(n in t))return!1;for(let n in t)if(e[n]!==t[n])return!1;return!0},isSet:e=>e instanceof Set,isString:e=>typeof e==`string`,isUndefined:e=>e===void 0,noop:()=>{},uniq:e=>e.length<2?e:Array.from(new Set(e))},fs:{getDepth:e=>Math.max(0,e.split(N.sep).length-1),getRealPath:(e,t)=>{try{return t?M.realpathSync.native(e):M.realpathSync(e)}catch{return}},isSubPath:(e,t)=>t.startsWith(e)&&t[e.length]===N.sep&&t.length-e.length>N.sep.length,poll:(e,t=2e4)=>ue.retry.stat(t)(e,{bigint:!0}).catch(Z.lang.noop),readdir:async(e,t,n=1/0,r=1/0,i,a)=>{if(a&&n===1&&e in a){let t=a[e];return[t.directories,t.files]}else{let a=await _e(e,{depth:n,limit:r,ignore:t,signal:i});return[a.directories,a.files]}}}};var ve=class{constructor(e,t,n){this.base=n,this.watcher=e,this.handler=t.handler,this.fswatcher=t.watcher,this.options=t.options,this.folderPath=t.folderPath,this.filePath=t.filePath,this.handlerBatched=this.base?this.base.onWatcherEvent.bind(this.base):this._makeHandlerBatched(this.options.debounce)}_isSubRoot(e){return this.filePath?e===this.filePath:e===this.folderPath||Z.fs.isSubPath(this.folderPath,e)}_makeHandlerBatched(e=300){return(()=>{let t=this.watcher._readyWait,n=[],r=new Set,i=async(e,t)=>{let n=this.options.ignoreInitial?[]:e,r=await this.eventsPopulate([...t]),i=this.eventsDeduplicate([...n,...r]);this.onTargetEvents(i)},a=Z.lang.debounce(()=>{this.watcher.isClosed()||(t=i(n,r),n=[],r=new Set)},e);return async(e,i=``,o=!1)=>{o?await this.eventsPopulate([i],n,!0):r.add(i),t.then(a)}})()}eventsDeduplicate(e){if(e.length<2)return e;let t={};return e.reduce((e,n)=>{let[r,i]=n,a=t[i];return r===a||r===U.CHANGE&&a===U.ADD?e:(t[i]=r,e.push(n),e)},[])}async eventsPopulate(e,t=[],n=!1){return await Promise.all(e.map(async r=>{let i=await this.watcher._poller.update(r,this.options.pollingTimeout);await Promise.all(i.map(async i=>{t.push([i,r]),i===U.ADD_DIR?await this.eventsPopulateAddDir(e,r,t,n):i===U.UNLINK_DIR&&await this.eventsPopulateUnlinkDir(e,r,t,n)}))})),t}async eventsPopulateAddDir(e,t,n=[],r=!1){if(r)return n;let i=this.options.recursive?this.options.depth??20:Math.min(1,this.options.depth??20),a=this.options.limit??1e7,[o,s]=await Z.fs.readdir(t,this.options.ignore,i,a,this.watcher._closeSignal),c=new Set(o),l=[...o,...s];return await Promise.all(l.map(t=>{if(!this.watcher.isIgnored(t,this.options.ignore,c.has(t))&&!e.includes(t))return this.eventsPopulate([t],n,!0)})),n}async eventsPopulateUnlinkDir(e,t,n=[],r=!1){if(r)return n;for(let r of this.watcher._poller.stats.keys())Z.fs.isSubPath(t,r)&&(e.includes(r)||await this.eventsPopulate([r],n,!0));return n}onTargetAdd(e){this._isSubRoot(e)&&(this.options.renameDetection?this.watcher._locker.getLockTargetAdd(e,this.options.renameTimeout):this.watcher.event(U.ADD,e))}onTargetAddDir(e){e!==this.folderPath&&this.options.recursive&&!z&&this.options.native!==!1&&this.watcher.watchDirectory(e,this.options,this.handler,void 0,this.base||this),this._isSubRoot(e)&&(this.options.renameDetection?this.watcher._locker.getLockTargetAddDir(e,this.options.renameTimeout):this.watcher.event(U.ADD_DIR,e))}onTargetChange(e){this._isSubRoot(e)&&this.watcher.event(U.CHANGE,e)}onTargetUnlink(e){this.watcher.watchersClose(N.dirname(e),e,!1),this._isSubRoot(e)&&(this.options.renameDetection?this.watcher._locker.getLockTargetUnlink(e,this.options.renameTimeout):this.watcher.event(U.UNLINK,e))}onTargetUnlinkDir(e){this.watcher.watchersClose(N.dirname(e),e,!1),this.watcher.watchersClose(e),this._isSubRoot(e)&&(this.options.renameDetection?this.watcher._locker.getLockTargetUnlinkDir(e,this.options.renameTimeout):this.watcher.event(U.UNLINK_DIR,e))}onTargetEvent(e){let[t,n]=e;t===U.ADD?this.onTargetAdd(n):t===U.ADD_DIR?this.onTargetAddDir(n):t===U.CHANGE?this.onTargetChange(n):t===U.UNLINK?this.onTargetUnlink(n):t===U.UNLINK_DIR&&this.onTargetUnlinkDir(n)}onTargetEvents(e){for(let t of e)this.onTargetEvent(t)}onWatcherEvent(e,t,n=!1){return this.handlerBatched(e,t,n)}onWatcherChange(e=V.CHANGE,t){if(this.watcher.isClosed())return;let n=N.resolve(this.folderPath,t||``);this.filePath&&n!==this.folderPath&&n!==this.filePath||this.watcher.isIgnored(n,this.options.ignore)||this.onWatcherEvent(e,n)}onWatcherError(e){R&&e.code===`EPERM`?this.onWatcherChange(V.CHANGE,``):this.watcher.error(e)}async init(){await this.initWatcherEvents(),await this.initInitialEvents()}async initWatcherEvents(){let e=this.onWatcherChange.bind(this);this.fswatcher.on(H.CHANGE,e);let t=this.onWatcherError.bind(this);this.fswatcher.on(H.ERROR,t)}async initInitialEvents(){let e=!this.watcher.isReady();if(this.filePath){if(this.watcher._poller.stats.has(this.filePath))return;await this.onWatcherEvent(V.CHANGE,this.filePath,e)}else{let t=this.options.recursive&&z&&this.options.native!==!1?this.options.depth??20:Math.min(1,this.options.depth??20),n=this.options.limit??1e7,[r,i]=await Z.fs.readdir(this.folderPath,this.options.ignore,t,n,this.watcher._closeSignal,this.options.readdirMap),a=new Set(r);a.add(this.folderPath);let o=[this.folderPath,...r,...i];await Promise.all(o.map(t=>{if(!this.watcher._poller.stats.has(t)&&!this.watcher.isIgnored(t,this.options.ignore,a.has(t)))return this.onWatcherEvent(V.CHANGE,t,e)}))}}};const Q={interval:100,intervalId:void 0,fns:new Map,init:()=>{Q.intervalId||=setInterval(Q.resolve,Q.interval)},reset:()=>{Q.intervalId&&(clearInterval(Q.intervalId),delete Q.intervalId)},add:(e,t)=>{Q.fns.set(e,Date.now()+t),Q.init()},remove:e=>{Q.fns.delete(e)},resolve:()=>{if(!Q.fns.size)return Q.reset();let e=Date.now();for(let[t,n]of Q.fns)n>=e||(Q.remove(t),t())}};var $=class e{constructor(e){this._watcher=e,this.reset()}getLockAdd(e,t=oe){let{ino:n,targetPath:r,events:i,locks:a}=e,o=()=>{let e=this._watcher._poller.paths.find(n||-1,e=>e!==r);if(e&&e!==r){if(Z.fs.getRealPath(r,!0)===e)return;this._watcher.event(i.rename,e,r)}else this._watcher.event(i.add,r)};if(!n)return o();let s=()=>{a.add.delete(n),Q.remove(c)},c=()=>{s(),o()};Q.add(c,t);let l=()=>{let e=a.unlink.get(n);if(!e)return;s();let t=e();r===t?i.change&&this._watcher._poller.stats.has(r)&&this._watcher.event(i.change,r):this._watcher.event(i.rename,t,r)};a.add.set(n,l),l()}getLockUnlink(e,t=oe){let{ino:n,targetPath:r,events:i,locks:a}=e,o=()=>{this._watcher.event(i.unlink,r)};if(!n)return o();let s=()=>{a.unlink.delete(n),Q.remove(c)},c=()=>{s(),o()};Q.add(c,t),a.unlink.set(n,()=>(s(),r)),a.add.get(n)?.()}getLockTargetAdd(t,n){let r=this._watcher._poller.getIno(t,U.ADD,B.FILE);return this.getLockAdd({ino:r,targetPath:t,events:e.FILE_EVENTS,locks:this._locksFile},n)}getLockTargetAddDir(t,n){let r=this._watcher._poller.getIno(t,U.ADD_DIR,B.DIR);return this.getLockAdd({ino:r,targetPath:t,events:e.DIR_EVENTS,locks:this._locksDir},n)}getLockTargetUnlink(t,n){let r=this._watcher._poller.getIno(t,U.UNLINK,B.FILE);return this.getLockUnlink({ino:r,targetPath:t,events:e.FILE_EVENTS,locks:this._locksFile},n)}getLockTargetUnlinkDir(t,n){let r=this._watcher._poller.getIno(t,U.UNLINK_DIR,B.DIR);return this.getLockUnlink({ino:r,targetPath:t,events:e.DIR_EVENTS,locks:this._locksDir},n)}reset(){this._locksAdd=new Map,this._locksAddDir=new Map,this._locksUnlink=new Map,this._locksUnlinkDir=new Map,this._locksDir={add:this._locksAddDir,unlink:this._locksUnlinkDir},this._locksFile={add:this._locksAdd,unlink:this._locksUnlink}}};$.DIR_EVENTS={add:U.ADD_DIR,rename:U.RENAME_DIR,unlink:U.UNLINK_DIR},$.FILE_EVENTS={add:U.ADD,change:U.CHANGE,rename:U.RENAME,unlink:U.UNLINK};var ye=class{constructor(){this.map=new Map}clear(){this.map.clear()}delete(e,t){if(Z.lang.isUndefined(t))return this.map.delete(e);if(this.map.has(e)){let n=this.map.get(e);if(Z.lang.isSet(n)){let r=n.delete(t);return n.size||this.map.delete(e),r}else if(n===t)return this.map.delete(e),!0}return!1}find(e,t){if(this.map.has(e)){let n=this.map.get(e);if(Z.lang.isSet(n))return Array.from(n).find(t);if(t(n))return n}}get(e){return this.map.get(e)}has(e,t){if(Z.lang.isUndefined(t))return this.map.has(e);if(this.map.has(e)){let n=this.map.get(e);return Z.lang.isSet(n)?n.has(t):n===t}return!1}set(e,t){if(this.map.has(e)){let n=this.map.get(e);Z.lang.isSet(n)?n.add(t):n!==t&&this.map.set(e,new Set([n,t]))}else this.map.set(e,t);return this}},be=class{constructor(e){this.ino=e.ino<=2**53-1?Number(e.ino):e.ino,this.size=Number(e.size),this.atimeMs=Number(e.atimeMs),this.mtimeMs=Number(e.mtimeMs),this.ctimeMs=Number(e.ctimeMs),this.birthtimeMs=Number(e.birthtimeMs),this._isFile=e.isFile(),this._isDirectory=e.isDirectory(),this._isSymbolicLink=e.isSymbolicLink()}isFile(){return this._isFile}isDirectory(){return this._isDirectory}isSymbolicLink(){return this._isSymbolicLink}},xe=class{constructor(){this.inos={},this.paths=new ye,this.stats=new Map}getIno(e,t,n){let r=this.inos[t];if(!r)return;let i=r[e];if(i&&!(n&&i[1]!==n))return i[0]}getStats(e){return this.stats.get(e)}async poll(e,t){let n=await Z.fs.poll(e,t);if(n&&(n.isFile()||n.isDirectory()))return new be(n)}reset(){this.inos={},this.paths=new ye,this.stats=new Map}async update(e,t){let n=this.getStats(e),r=await this.poll(e,t);if(this.updateStats(e,r),!n&&r){if(r.isFile())return this.updateIno(e,U.ADD,r),[U.ADD];if(r.isDirectory())return this.updateIno(e,U.ADD_DIR,r),[U.ADD_DIR]}else if(n&&!r){if(n.isFile())return this.updateIno(e,U.UNLINK,n),[U.UNLINK];if(n.isDirectory())return this.updateIno(e,U.UNLINK_DIR,n),[U.UNLINK_DIR]}else if(n&&r){if(n.isFile()){if(r.isFile())return n.ino===r.ino&&!n.size&&!r.size?[]:(this.updateIno(e,U.CHANGE,r),[U.CHANGE]);if(r.isDirectory())return this.updateIno(e,U.UNLINK,n),this.updateIno(e,U.ADD_DIR,r),[U.UNLINK,U.ADD_DIR]}else if(n.isDirectory()){if(r.isFile())return this.updateIno(e,U.UNLINK_DIR,n),this.updateIno(e,U.ADD,r),[U.UNLINK_DIR,U.ADD];if(r.isDirectory())return n.ino===r.ino?[]:(this.updateIno(e,U.UNLINK_DIR,n),this.updateIno(e,U.ADD_DIR,r),[U.UNLINK_DIR,U.ADD_DIR])}}return[]}updateIno(e,t,n){let r=this.inos[t]=this.inos[t]||(this.inos[t]={}),i=n.isFile()?B.FILE:B.DIR;r[e]=[n.ino,i]}updateStats(e,t){if(t)this.paths.set(t.ino,e),this.stats.set(e,t);else{let t=this.stats.get(e)?.ino||-1;this.paths.delete(t,e),this.stats.delete(e)}}},Se=class e extends ne{constructor(e,t,n){super(),this._closed=!1,this._ready=!1,this._closeAborter=new AbortController,this._closeSignal=this._closeAborter.signal,this.on(W.CLOSE,()=>this._closeAborter.abort()),this._closeWait=new Promise(e=>this.on(W.CLOSE,e)),this._readyWait=new Promise(e=>this.on(W.READY,e)),this._locker=new $(this),this._roots=new Set,this._poller=new xe,this._pollers=new Set,this._subwatchers=new Set,this._watchers={},this._watchersLock=Promise.resolve(),this._watchersRestorable={},this.watch(e,t,n)}isClosed(){return this._closed}isIgnored(e,t,n){return!!t&&(Z.lang.isFunction(t)?!!t(e,n):t.test(e))}isReady(){return this._ready}close(){return this._locker.reset(),this._poller.reset(),this._roots.clear(),this.watchersClose(),this.isClosed()?!1:(this._closed=!0,this.emit(W.CLOSE))}error(e){if(this.isClosed())return!1;let t=Z.lang.castError(e);return this.emit(W.ERROR,t)}event(e,t,n){return this.isClosed()?!1:(this.emit(W.ALL,e,t,n),this.emit(e,t,n))}ready(){return this.isClosed()||this.isReady()?!1:(this._ready=!0,this.emit(W.READY))}pollerExists(e,t){for(let n of this._pollers)if(n.targetPath===e&&Z.lang.isShallowEqual(n.options,t))return!0;return!1}subwatcherExists(e,t){for(let n of this._subwatchers)if(n.targetPath===e&&Z.lang.isShallowEqual(n.options,t))return!0;return!1}watchersClose(e,t,n=!0){if(e){let r=this._watchers[e];if(r)for(let e of[...r])t&&e.filePath!==t||this.watcherClose(e);if(n)for(let n in this._watchers)Z.fs.isSubPath(e,n)&&this.watchersClose(n,t,!1)}else for(let e in this._watchers)this.watchersClose(e,t,!1)}watchersLock(e){return this._watchersLock.then(()=>this._watchersLock=new Promise(async t=>{await e(),t()}))}watchersRestore(){delete this._watchersRestoreTimeout;let e=Object.entries(this._watchersRestorable);this._watchersRestorable={};for(let[t,n]of e)this.watchPath(t,n.options,n.handler)}async watcherAdd(e,t){let{folderPath:n}=e;(this._watchers[n]=this._watchers[n]||[]).push(e);let r=new ve(this,e,t);return await r.init(),r}watcherClose(e){e.watcher.close();let t=this._watchers[e.folderPath];if(t){let n=t.indexOf(e);t.splice(n,1),t.length||delete this._watchers[e.folderPath]}let n=e.filePath||e.folderPath;this._roots.has(n)&&(this._watchersRestorable[n]=e,this._watchersRestoreTimeout||=Z.lang.defer(()=>this.watchersRestore()))}watcherExists(e,t,n,r){if(this._watchers[e]?.find(e=>e.handler===n&&(!e.filePath||e.filePath===r)&&e.options.ignore===t.ignore&&!!e.options.native==!!t.native&&(!t.recursive||e.options.recursive)))return!0;let i=N.dirname(e);for(let a=1;a<1/0;a++){if(this._watchers[i]?.find(e=>(a===1||e.options.recursive&&a<=(e.options.depth??20))&&e.handler===n&&(!e.filePath||e.filePath===r)&&e.options.ignore===t.ignore&&!!e.options.native==!!t.native&&(!t.recursive||e.options.recursive&&z&&e.options.native!==!1)))return!0;if(!z)break;let o=N.dirname(e);if(i===o)break;i=o}return!1}async watchDirectories(e,t,n,r,i){if(this.isClosed())return;e=Z.lang.uniq(e).sort();let a;for(let o of e)if(!this.isIgnored(o,t.ignore,!0)&&!this.watcherExists(o,t,n,r))try{let e=!t.recursive||z&&t.native!==!1?t:{...t,recursive:!1},s={watcher:M.watch(o,e),handler:n,options:t,folderPath:o,filePath:r},c=a=await this.watcherAdd(s,i);if(this._roots.has(r||o)){let e={...t,ignoreInitial:!0,recursive:!1},r=N.dirname(o),i=o;await this.watchDirectories([r],e,n,i,c)}}catch(e){this.error(e)}return a}async watchDirectory(e,t,n,r,i){if(!this.isClosed()&&!this.isIgnored(e,t.ignore,!0)){if(!t.recursive||z&&t.native!==!1)return this.watchersLock(()=>this.watchDirectories([e],t,n,r,i));{t={...t,recursive:!0};let a=t.depth??20,o=t.limit??1e7,[s]=await Z.fs.readdir(e,t.ignore,a,o,this._closeSignal,t.readdirMap);return this.watchersLock(async()=>{let o=await this.watchDirectories([e],t,n,r,i);if(s.length){let c=Z.fs.getDepth(e);for(let e of s){let s=Z.fs.getDepth(e),l=Math.max(0,a-(s-c)),u={...t,depth:l};await this.watchDirectories([e],u,n,r,i||o)}}})}}}async watchFileOnce(t,n,r){if(this.isClosed()||(n={...n,ignoreInitial:!1},this.subwatcherExists(t,n)))return;let i={targetPath:t,options:n},a=(e,n)=>{n===t&&(c(),r())},o=new e(a),s=()=>{this._subwatchers.add(i),this.on(W.CLOSE,c),o.watchFile(t,n,a)},c=()=>{this._subwatchers.delete(i),this.removeListener(W.CLOSE,c),o.close()};return s()}async watchFile(e,t,n){if(this.isClosed()||this.isIgnored(e,t.ignore,!1))return;t={...t,recursive:!1};let r=N.dirname(e);return this.watchDirectory(r,t,n,e)}async watchPollingOnce(e,t,n){if(this.isClosed())return;let r=!1,i=new xe,a=await this.watchPolling(e,t,async()=>{r||(await i.update(e,t.pollingTimeout)).length&&(r||(r=!0,a(),n()))})}async watchPolling(e,t,n){if(this.isClosed()||this.pollerExists(e,t))return Z.lang.noop;let r={...t,interval:t.pollingInterval??3e3},i={targetPath:e,options:t},a=()=>{this._pollers.add(i),this.on(W.CLOSE,o),M.watchFile(e,r,n)},o=()=>{this._pollers.delete(i),this.removeListener(W.CLOSE,o),M.unwatchFile(e,n)};return Z.lang.attempt(a),()=>Z.lang.attempt(o)}async watchUnknownChild(e,t,n){return this.isClosed()?void 0:this.watchFileOnce(e,t,()=>this.watchPath(e,t,n))}async watchUnknownTarget(e,t,n){return this.isClosed()?void 0:this.watchPollingOnce(e,t,()=>this.watchPath(e,t,n))}async watchPaths(e,t,n){if(!this.isClosed())if(e=Z.lang.uniq(e).sort(),e.every((t,n)=>e.every((e,r)=>r===n||!Z.fs.isSubPath(t,e))))await Promise.all(e.map(e=>this.watchPath(e,t,n)));else for(let r of e)await this.watchPath(r,t,n)}async watchPath(e,t,n){if(this.isClosed()||(e=N.resolve(e),this.isIgnored(e,t.ignore)))return;let r=await Z.fs.poll(e,t.pollingTimeout);if(!r){let r=N.dirname(e);return(await Z.fs.poll(r,t.pollingTimeout))?.isDirectory()?this.watchUnknownChild(e,t,n):this.watchUnknownTarget(e,t,n)}else if(r.isFile())return this.watchFile(e,t,n);else if(r.isDirectory())return this.watchDirectory(e,t,n);else this.error(`"${e}" is not supported`)}async watch(e,t,n=Z.lang.noop){if(Z.lang.isFunction(e))return this.watch([],{},e);if(Z.lang.isUndefined(e))return this.watch([],t,n);if(Z.lang.isFunction(t))return this.watch(e,{},t);if(Z.lang.isUndefined(t))return this.watch(e,{},n);if(this.isClosed())return;this.isReady()&&(t.readdirMap=void 0);let r=Z.lang.castArray(e);r.forEach(e=>this._roots.add(e)),await this.watchPaths(r,t,n),!this.isClosed()&&(n!==Z.lang.noop&&this.on(W.ALL,n),t.readdirMap=void 0,this.ready())}},Ce=n((t=>{var n=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),r=n(t=>{Object.defineProperty(t,`__esModule`,{value:!0}),t.sync=t.isexe=void 0;var n=e(`node:fs`),r=e(`node:fs/promises`);t.isexe=async(e,t={})=>{let{ignoreErrors:n=!1}=t;try{return i(await(0,r.stat)(e),t)}catch(e){let t=e;if(n||t.code===`EACCES`)return!1;throw t}},t.sync=(e,t={})=>{let{ignoreErrors:r=!1}=t;try{return i((0,n.statSync)(e),t)}catch(e){let t=e;if(r||t.code===`EACCES`)return!1;throw t}};var i=(e,t)=>e.isFile()&&a(e,t),a=(e,t)=>{let n=t.uid??process.getuid?.(),r=t.groups??process.getgroups?.()??[],i=t.gid??process.getgid?.()??r[0];if(n===void 0||i===void 0)throw Error(`cannot get uid or gid`);let a=new Set([i,...r]),o=e.mode,s=e.uid,c=e.gid;return!!(o&1||o&8&&a.has(c)||o&64&&s===n||o&72&&n===0)}}),i=n(t=>{Object.defineProperty(t,`__esModule`,{value:!0}),t.sync=t.isexe=void 0;var n=e(`node:fs`),r=e(`node:fs/promises`),i=e(`node:path`);t.isexe=async(e,t={})=>{let{ignoreErrors:n=!1}=t;try{return o(await(0,r.stat)(e),e,t)}catch(e){let t=e;if(n||t.code===`EACCES`)return!1;throw t}},t.sync=(e,t={})=>{let{ignoreErrors:r=!1}=t;try{return o((0,n.statSync)(e),e,t)}catch(e){let t=e;if(r||t.code===`EACCES`)return!1;throw t}};var a=(e,t)=>{let{pathExt:n=process.env.PATHEXT||``}=t,r=n.split(i.delimiter);if(r.indexOf(``)!==-1)return!0;for(let t of r){let n=t.toLowerCase(),r=e.substring(e.length-n.length).toLowerCase();if(n&&r===n)return!0}return!1},o=(e,t,n)=>e.isFile()&&a(t,n)}),a=n(e=>{Object.defineProperty(e,`__esModule`,{value:!0})}),o=t&&t.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),s=t&&t.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,`default`,{enumerable:!0,value:t})}):function(e,t){e.default=t}),c=t&&t.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},e(t)};return function(t){if(t&&t.__esModule)return t;var n={};if(t!=null)for(var r=e(t),i=0;i<r.length;i++)r[i]!==`default`&&o(n,t,r[i]);return s(n,t),n}})(),l=t&&t.__exportStar||function(e,t){for(var n in e)n!==`default`&&!Object.prototype.hasOwnProperty.call(t,n)&&o(t,e,n)};Object.defineProperty(t,`__esModule`,{value:!0}),t.sync=t.isexe=t.posix=t.win32=void 0;var u=c(r());t.posix=u;var d=c(i());t.win32=d,l(a(),t);var f=(process.env._ISEXE_TEST_PLATFORM_||process.platform)===`win32`?d:u;t.isexe=f.isexe,t.sync=f.sync})),we=t(n(((t,n)=>{let{isexe:r,sync:i}=Ce(),{join:a,delimiter:o,sep:s,posix:c}=e(`path`),l=process.platform===`win32`,u=new RegExp(`[${c.sep}${s===c.sep?``:s}]`.replace(/(\\)/g,`\\$1`)),d=RegExp(`^\\.${u.source}`),f=e=>Object.assign(Error(`not found: ${e}`),{code:`ENOENT`}),p=(e,{path:t=process.env.PATH,pathExt:n=process.env.PATHEXT,delimiter:r=o})=>{let i=e.match(u)?[``]:[...l?[process.cwd()]:[],...(t||``).split(r)];if(l){let t=n||[`.EXE`,`.CMD`,`.BAT`,`.COM`].join(r),a=t.split(r).flatMap(e=>[e,e.toLowerCase()]);return e.includes(`.`)&&a[0]!==``&&a.unshift(``),{pathEnv:i,pathExt:a,pathExtExe:t}}return{pathEnv:i,pathExt:[``]}},m=(e,t)=>{let n=/^".*"$/.test(e)?e.slice(1,-1):e;return(!n&&d.test(t)?t.slice(0,2):``)+a(n,t)},h=async(e,t={})=>{let{pathEnv:n,pathExt:i,pathExtExe:a}=p(e,t),o=[];for(let s of n){let n=m(s,e);for(let e of i){let i=n+e;if(await r(i,{pathExt:a,ignoreErrors:!0})){if(!t.all)return i;o.push(i)}}}if(t.all&&o.length)return o;if(t.nothrow)return null;throw f(e)};n.exports=h,h.sync=(e,t={})=>{let{pathEnv:n,pathExt:r,pathExtExe:a}=p(e,t),o=[];for(let s of n){let n=m(s,e);for(let e of r){let r=n+e;if(i(r,{pathExt:a,ignoreErrors:!0})){if(!t.all)return r;o.push(r)}}}if(t.all&&o.length)return o;if(t.nothrow)return null;throw f(e)}}))(),1);const Te=((e,...t)=>{let n=l(e,...t);f.isInteractive?f.updateFooter(n):f.writeStdout(n)}),Ee=(e,t)=>{e.log.info(`notifying user`,{subtitle:t.subtitle,message:t.message}),process.stderr.write(`\x07`)};var De=p({name:`dev`,description:`Sync files and stream logs locally`,details:u`
2
+ Watches your local files and your Gadget environment for changes, syncing them
3
+ bidirectionally in real time. This lets you develop with your preferred editor while
4
+ keeping your environment up to date.
5
+
6
+ On first run, or when files have diverged since the last sync, an initial reconciliation
7
+ is performed. You must resolve any conflicts before continuous syncing begins.
8
+
9
+ While running, application logs are streamed to the terminal unless --no-logs is passed.
10
+ `,sections:[{title:`Ignoring files`,content:u`
11
+ Add a .ignore file (uses .gitignore syntax) to exclude files and folders from syncing.
12
+ These paths are always excluded:
13
+
14
+ • .DS_Store
15
+ • .gadget
16
+ • .git
17
+ • .shopify
18
+ • node_modules
19
+ `},{title:`Limitations`,content:u`
20
+ • Only syncs with development environments.
21
+ • Only supports yarn v1 for installing dependencies.
22
+ • Do not delete or move all files at once while syncing.
23
+ `}],examples:[`ggt dev`,`ggt dev ~/gadget/my-app`,`ggt dev --prefer local`,`ggt dev ~/gadget/my-app --app my-app --env development --prefer local`],positionals:[{name:`directory`,description:`Directory to sync files to`,details:`If the directory does not exist, it will be created. Defaults to the current working directory when omitted.`}],flags:{...S,...o,"--prefer":{type:y,description:`Auto-resolve conflicts using the given source`,details:`Use 'local' to keep your local file contents or 'environment' to keep the environment's version. Without this flag, you are prompted to choose for each conflict.`,valueName:`source`,complete:async(e,t,n)=>{let{filterByPrefix:r}=await import(`./collection-aM0fpch0.js`);return r([..._],t)}},"--file-push-delay":{type:Number,default:(0,I.default)(`100ms`),description:`Delay in ms before pushing file changes`,details:`Batches rapid file changes into a single push by waiting this long after the last change before sending. Increase if you see excessive network requests during bulk edits. Defaults to 100ms.`,valueName:`ms`,brief:!1},"--file-watch-debounce":{type:Number,default:(0,I.default)(`300ms`),description:`Debounce in ms for file watch events`,details:`How long the file watcher waits after the last filesystem event before emitting a change. Helps avoid duplicate events from editors that write files in multiple steps. Defaults to 300ms.`,valueName:`ms`,brief:!1},"--file-watch-poll-interval":{type:Number,default:(0,I.default)(`3s`),description:`Interval in ms for polling file changes`,details:`How often the file watcher polls for changes on filesystems that don't support native events (e.g. network drives). Defaults to 3s (3000ms).`,valueName:`ms`,brief:!1},"--file-watch-poll-timeout":{type:Number,default:(0,I.default)(`20s`),description:`Timeout in ms for file watch polling`,details:`How long to wait for a poll cycle to complete before timing out. Increase for very large directories where polling is slow. Defaults to 20s (20000ms).`,valueName:`ms`,brief:!1},"--file-watch-rename-timeout":{type:Number,default:(0,I.default)(`1.25s`),description:`Timeout in ms for detecting file renames`,details:`How long to wait for an add event to be followed by an unlink event (or vice versa) before treating them as separate operations instead of a rename. Defaults to 1.25s (1250ms).`,valueName:`ms`,brief:!1},"--no-logs":{type:Boolean,description:`Don't stream logs while syncing`,details:`Useful when you only need file sync without log output, for example when running alongside a separate ggt logs session or in a background terminal.`}},run:async(e,t)=>{if(!await(0,we.default)(`yarn`,{nothrow:!0}))throw new x;let n=await C(t._[0]??process.cwd()),r=await w.loadOrAskAndInit(e,{command:`dev`,flags:t,directory:n});await A(n),e.onAbort(async()=>{await k(n)}),await D({ctx:e,directory:r.directory}),await te({ctx:e,directory:r.directory}),Te({ensureEmptyLineAbove:!0,content:r.sprint()});let a=new ee(r),o=await a.hashes(e);if(!o.inSync)if(!r.previousEnvironment||o.localChangesToPush.size===0&&o.onlyDotGadgetFilesChanged)await a.merge(e,{hashes:o,printLocalChangesOptions:{limit:5},printEnvironmentChangesOptions:{limit:5}});else{await a.print(e,{hashes:o});let t=Object.values(v);switch(await T({ensureEmptyLineAbove:!0,choices:o.bothChanged?t:t.filter(e=>e!==v.MERGE),content:h.header(`What do you want to do?`),formatChoice:e=>{switch(e){case v.CANCEL:return u`Cancel (Ctrl+C)`;case v.MERGE:return u`Merge local and environment's changes`;case v.PUSH:switch(!0){case o.bothChanged:return u`Push local changes and ${h.emphasis(`discard environment's`)} changes`;case o.localChanges.size>0:return u`Push local changes`;case o.environmentChanges.size>0:return u`Discard environment's changes`;default:return O(`no changes to push or discard`)}case v.PULL:switch(!0){case o.bothChanged:return u`Pull environment's changes and ${h.emphasis(`discard local`)} changes`;case o.localChanges.size>0:return u`Discard local changes`;case o.environmentChanges.size>0:return u`Pull environment's changes`;default:return O(`no changes to pull or discard`)}}}})){case v.CANCEL:process.exit(0);break;case v.MERGE:await a.merge(e,{hashes:o});break;case v.PUSH:await a.push(e,{command:`dev`,hashes:o});break;case v.PULL:await a.pull(e,{hashes:o,force:!0});break}}let l=new Map,f=setInterval(()=>{for(let[e,t]of l)(0,ie.default)().isAfter(t+(0,I.default)(`5s`))&&l.delete(e)},(0,I.default)(`1s`)).unref(),p=a.subscribeToEnvironmentChanges(e,{onError:t=>e.abort(t),beforeChanges:({changed:e,deleted:t})=>{for(let n of[...e,...t]){l.set(n,Date.now());let e=N.dirname(n);for(;e!==`.`;)l.set(e+`/`,Date.now()),e=N.dirname(e)}}}),_;t[`--no-logs`]||(_=j(r.edit,t,{onError:t=>{e.abort(t)}}));let y=new b,S=g(t[`--file-push-delay`],async()=>{try{let t=r.gitBranch;if(await r.loadGitBranch(),t!==r.gitBranch){d({ensureEmptyLineAbove:!0,content:u`
24
+ Your git branch changed.
25
+
26
+ ${t} → ${r.gitBranch}
27
+ `});let e=E({ensureEmptyLineAbove:!0,content:`Waiting for file changes to settle.`});await c(`3s`),e.succeed()}let n=new b(y.entries());y.clear(),await a.mergeChangesWithEnvironment(e,{changes:n})}catch(t){e.log.error(`error sending changes to gadget`,{error:t}),e.abort(t)}});e.log.debug(`watching`,{path:r.directory.path});let ne=new Se(r.directory.path,{ignoreInitial:!0,recursive:!0,ignore:(e,t)=>{if(r.directory.relative(e).startsWith(`.gadget`))return!0;if(t===void 0)try{t=M.statSync(e).isDirectory()}catch{t=!1}return r.directory.ignores(e,t)},renameDetection:!0,renameTimeout:t[`--file-watch-rename-timeout`],debounce:t[`--file-watch-debounce`]},(t,n,i)=>{let a=t===`rename`||t===`renameDir`?i:n,o=t===`renameDir`||t===`addDir`||t===`unlinkDir`,s=r.directory.normalize(a,o);if(e.log.trace(`file event`,{event:t,isDirectory:o,path:s}),l.delete(s)){e.log.trace(`ignoring event because we caused it`,{event:t,path:s});return}if(a===r.directory.absolute(`.ignore`))r.directory.ignoreFileLoadedWithin((0,I.default)(`2s`))||r.directory.loadIgnoreFile().catch(t=>e.abort(t));else if(r.directory.ignores(a,o))return;switch(t){case`add`:case`addDir`:y.set(s,{type:`create`});break;case`rename`:case`renameDir`:{let e=r.directory.normalize(n,o);y.set(s,{type:`create`,oldPath:e});break}case`change`:y.set(s,{type:`update`});break;case`unlink`:case`unlinkDir`:y.set(s,{type:`delete`});break}S()}).once(`error`,t=>e.abort(t));e.onAbort(async t=>{e.log.info(`stopping`,{reason:t}),_?.unsubscribe(),p.unsubscribe(),ne.close(),clearInterval(f),await S.flush();try{await a.idle()}catch(t){e.log.error(`error while waiting for idle`,{error:t})}m(t)||(Ee(e,{subtitle:`Uh oh!`,message:`An error occurred while syncing files`}),await s(e,t))}),Te({ensureEmptyLineAbove:!0,content:u`
28
+ ${r.sprint()}
29
+
30
+ Waiting for file changes${i.ellipsis} ${h.hint(`Press Ctrl+C to stop`)}
31
+ `})}});export{De as default};
32
+ //# sourceMappingURL=dev-DWMSNcLl.js.map