watch-tail 0.3.0 → 0.4.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 (97) hide show
  1. package/README.md +31 -3
  2. package/build/client/_app/immutable/assets/0.BPmQoXaO.css +2 -0
  3. package/build/client/_app/immutable/assets/0.BPmQoXaO.css.br +0 -0
  4. package/build/client/_app/immutable/assets/0.BPmQoXaO.css.gz +0 -0
  5. package/build/client/_app/immutable/chunks/{KFjMNKuK.js → Bw_9uNRP.js} +1 -1
  6. package/build/client/_app/immutable/chunks/Bw_9uNRP.js.br +0 -0
  7. package/build/client/_app/immutable/chunks/Bw_9uNRP.js.gz +0 -0
  8. package/build/client/_app/immutable/chunks/De_x7GQi.js +1 -0
  9. package/build/client/_app/immutable/chunks/De_x7GQi.js.br +0 -0
  10. package/build/client/_app/immutable/chunks/De_x7GQi.js.gz +0 -0
  11. package/build/client/_app/immutable/entry/{app.CO3UiVLU.js → app.Be166AxG.js} +2 -2
  12. package/build/client/_app/immutable/entry/app.Be166AxG.js.br +0 -0
  13. package/build/client/_app/immutable/entry/app.Be166AxG.js.gz +0 -0
  14. package/build/client/_app/immutable/entry/start.clEDpQL9.js +1 -0
  15. package/build/client/_app/immutable/entry/start.clEDpQL9.js.br +0 -0
  16. package/build/client/_app/immutable/entry/start.clEDpQL9.js.gz +0 -0
  17. package/build/client/_app/immutable/nodes/0.BJ6Zdc8H.js +1 -0
  18. package/build/client/_app/immutable/nodes/0.BJ6Zdc8H.js.br +4 -0
  19. package/build/client/_app/immutable/nodes/0.BJ6Zdc8H.js.gz +0 -0
  20. package/build/client/_app/immutable/nodes/{1.Bink5luw.js → 1.xMNWuLLz.js} +1 -1
  21. package/build/client/_app/immutable/nodes/1.xMNWuLLz.js.br +0 -0
  22. package/build/client/_app/immutable/nodes/1.xMNWuLLz.js.gz +0 -0
  23. package/build/client/_app/immutable/nodes/2.CaxDXwmh.js +5 -0
  24. package/build/client/_app/immutable/nodes/2.CaxDXwmh.js.br +0 -0
  25. package/build/client/_app/immutable/nodes/2.CaxDXwmh.js.gz +0 -0
  26. package/build/client/_app/version.json +1 -1
  27. package/build/client/_app/version.json.br +0 -0
  28. package/build/client/_app/version.json.gz +0 -0
  29. package/build/handler.js +4 -4
  30. package/build/index.js +4 -4
  31. package/build/server/chunks/chunks/{env2.js-D7xrfc37.js → env2.js-DXveJt1Y.js} +18 -12
  32. package/build/server/chunks/chunks/env2.js-DXveJt1Y.js.map +1 -0
  33. package/build/server/chunks/chunks/{internal.js-DKaleXjD.js → internal.js-Cc3oBhL-.js} +3 -3
  34. package/build/server/chunks/chunks/{internal.js-DKaleXjD.js.map → internal.js-Cc3oBhL-.js.map} +1 -1
  35. package/build/server/chunks/chunks/{state.js-B3c1pOs1.js → state.js-9DxsWxU-.js} +2 -2
  36. package/build/server/chunks/chunks/{state.js-B3c1pOs1.js.map → state.js-9DxsWxU-.js.map} +1 -1
  37. package/build/server/chunks/entries/endpoints/api/health/{_server.ts.js-aiNZfkco.js → _server.ts.js-BOjix7GN.js} +3 -2
  38. package/build/server/chunks/entries/endpoints/api/health/_server.ts.js-BOjix7GN.js.map +1 -0
  39. package/build/server/chunks/entries/endpoints/api/identity/_server.ts.js-g13uvmrX.js +72 -0
  40. package/build/server/chunks/entries/endpoints/api/identity/_server.ts.js-g13uvmrX.js.map +1 -0
  41. package/build/server/chunks/entries/endpoints/api/log-groups/{_server.ts.js-D143-vRl.js → _server.ts.js-CmHRxdZK.js} +3 -2
  42. package/build/server/chunks/entries/endpoints/api/log-groups/{_server.ts.js-D143-vRl.js.map → _server.ts.js-CmHRxdZK.js.map} +1 -1
  43. package/build/server/chunks/entries/endpoints/api/regions/{_server.ts.js-CDNL7msU.js → _server.ts.js-BgUwioxp.js} +3 -2
  44. package/build/server/chunks/entries/endpoints/api/regions/{_server.ts.js-CDNL7msU.js.map → _server.ts.js-BgUwioxp.js.map} +1 -1
  45. package/build/server/chunks/entries/endpoints/api/stream/{_server.ts.js-D_i-xW6_.js → _server.ts.js-CIYo4C-0.js} +3 -2
  46. package/build/server/chunks/entries/endpoints/api/stream/{_server.ts.js-D_i-xW6_.js.map → _server.ts.js-CIYo4C-0.js.map} +1 -1
  47. package/build/server/chunks/entries/fallbacks/{error.svelte.js-DwU8Vh5R.js → error.svelte.js-CFonuZkV.js} +3 -3
  48. package/build/server/chunks/entries/fallbacks/{error.svelte.js-DwU8Vh5R.js.map → error.svelte.js-CFonuZkV.js.map} +1 -1
  49. package/build/server/chunks/entries/pages/_layout.svelte.js-Dzluuq12.js +22 -0
  50. package/build/server/chunks/entries/pages/_layout.svelte.js-Dzluuq12.js.map +1 -0
  51. package/build/server/chunks/entries/pages/{_page.svelte.js-CsJstkpB.js → _page.svelte.js-CpwYbxbM.js} +36 -9
  52. package/build/server/chunks/entries/pages/_page.svelte.js-CpwYbxbM.js.map +1 -0
  53. package/build/server/chunks/{handler-Dw17Mzkr.js → handler-DS32NMsJ.js} +3 -3
  54. package/build/server/chunks/{handler-Dw17Mzkr.js.map → handler-DS32NMsJ.js.map} +1 -1
  55. package/build/server/chunks/{index.js-CAGsYI3V.js → index.js-HHu-yOEK.js} +2 -2
  56. package/build/server/chunks/{index.js-CAGsYI3V.js.map → index.js-HHu-yOEK.js.map} +1 -1
  57. package/build/server/chunks/{manifest.js-CVImQuLw.js → manifest.js-BUrA7Zyr.js} +16 -9
  58. package/build/server/chunks/manifest.js-BUrA7Zyr.js.map +1 -0
  59. package/build/server/chunks/nodes/{0.js-Bg4_hDjk.js → 0.js-gSRmrAt_.js} +4 -4
  60. package/build/server/chunks/nodes/{0.js-Bg4_hDjk.js.map → 0.js-gSRmrAt_.js.map} +1 -1
  61. package/build/server/chunks/nodes/{1.js-D_fOWpEW.js → 1.js-D68K7Ad_.js} +3 -3
  62. package/build/server/chunks/nodes/{1.js-D_fOWpEW.js.map → 1.js-D68K7Ad_.js.map} +1 -1
  63. package/build/server/chunks/nodes/2.js-ChYsaaoC.js +9 -0
  64. package/build/server/chunks/nodes/{2.js-t5EYxWxj.js.map → 2.js-ChYsaaoC.js.map} +1 -1
  65. package/dist/cli/index.js +150 -34
  66. package/dist/cli/preflight.js +42 -0
  67. package/dist/cli/ui.js +7 -3
  68. package/dist/lib/cli/aws.js +48 -0
  69. package/package.json +2 -1
  70. package/build/client/_app/immutable/assets/0.CocWI5K4.css +0 -2
  71. package/build/client/_app/immutable/assets/0.CocWI5K4.css.br +0 -0
  72. package/build/client/_app/immutable/assets/0.CocWI5K4.css.gz +0 -0
  73. package/build/client/_app/immutable/chunks/CsscK9Dm.js +0 -1
  74. package/build/client/_app/immutable/chunks/CsscK9Dm.js.br +0 -0
  75. package/build/client/_app/immutable/chunks/CsscK9Dm.js.gz +0 -0
  76. package/build/client/_app/immutable/chunks/KFjMNKuK.js.br +0 -0
  77. package/build/client/_app/immutable/chunks/KFjMNKuK.js.gz +0 -0
  78. package/build/client/_app/immutable/entry/app.CO3UiVLU.js.br +0 -0
  79. package/build/client/_app/immutable/entry/app.CO3UiVLU.js.gz +0 -0
  80. package/build/client/_app/immutable/entry/start.t_nX227Y.js +0 -1
  81. package/build/client/_app/immutable/entry/start.t_nX227Y.js.br +0 -0
  82. package/build/client/_app/immutable/entry/start.t_nX227Y.js.gz +0 -0
  83. package/build/client/_app/immutable/nodes/0.DHBUWbOo.js +0 -1
  84. package/build/client/_app/immutable/nodes/0.DHBUWbOo.js.br +0 -0
  85. package/build/client/_app/immutable/nodes/0.DHBUWbOo.js.gz +0 -0
  86. package/build/client/_app/immutable/nodes/1.Bink5luw.js.br +0 -0
  87. package/build/client/_app/immutable/nodes/1.Bink5luw.js.gz +0 -0
  88. package/build/client/_app/immutable/nodes/2.U0ljz8ot.js +0 -5
  89. package/build/client/_app/immutable/nodes/2.U0ljz8ot.js.br +0 -0
  90. package/build/client/_app/immutable/nodes/2.U0ljz8ot.js.gz +0 -0
  91. package/build/server/chunks/chunks/env2.js-D7xrfc37.js.map +0 -1
  92. package/build/server/chunks/entries/endpoints/api/health/_server.ts.js-aiNZfkco.js.map +0 -1
  93. package/build/server/chunks/entries/pages/_layout.svelte.js-Bx7lXkAi.js +0 -22
  94. package/build/server/chunks/entries/pages/_layout.svelte.js-Bx7lXkAi.js.map +0 -1
  95. package/build/server/chunks/entries/pages/_page.svelte.js-CsJstkpB.js.map +0 -1
  96. package/build/server/chunks/manifest.js-CVImQuLw.js.map +0 -1
  97. package/build/server/chunks/nodes/2.js-t5EYxWxj.js +0 -9
@@ -10,11 +10,11 @@ return {
10
10
  assets: new Set(["robots.txt"]),
11
11
  mimeTypes: {".txt":"text/plain"},
12
12
  _: {
13
- client: {start:"_app/immutable/entry/start.t_nX227Y.js",app:"_app/immutable/entry/app.CO3UiVLU.js",imports:["_app/immutable/entry/start.t_nX227Y.js","_app/immutable/chunks/CsscK9Dm.js","_app/immutable/chunks/ZAD2y5xJ.js","_app/immutable/entry/app.CO3UiVLU.js","_app/immutable/chunks/ZAD2y5xJ.js","_app/immutable/chunks/xihTtKlq.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
13
+ client: {start:"_app/immutable/entry/start.clEDpQL9.js",app:"_app/immutable/entry/app.Be166AxG.js",imports:["_app/immutable/entry/start.clEDpQL9.js","_app/immutable/chunks/De_x7GQi.js","_app/immutable/chunks/ZAD2y5xJ.js","_app/immutable/entry/app.Be166AxG.js","_app/immutable/chunks/ZAD2y5xJ.js","_app/immutable/chunks/xihTtKlq.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
14
14
  nodes: [
15
- __memo(() => import('./nodes/0.js-Bg4_hDjk.js')),
16
- __memo(() => import('./nodes/1.js-D_fOWpEW.js')),
17
- __memo(() => import('./nodes/2.js-t5EYxWxj.js'))
15
+ __memo(() => import('./nodes/0.js-gSRmrAt_.js')),
16
+ __memo(() => import('./nodes/1.js-D68K7Ad_.js')),
17
+ __memo(() => import('./nodes/2.js-ChYsaaoC.js'))
18
18
  ],
19
19
  remotes: {
20
20
 
@@ -32,28 +32,35 @@ return {
32
32
  pattern: /^\/api\/health\/?$/,
33
33
  params: [],
34
34
  page: null,
35
- endpoint: __memo(() => import('./entries/endpoints/api/health/_server.ts.js-aiNZfkco.js'))
35
+ endpoint: __memo(() => import('./entries/endpoints/api/health/_server.ts.js-BOjix7GN.js'))
36
+ },
37
+ {
38
+ id: "/api/identity",
39
+ pattern: /^\/api\/identity\/?$/,
40
+ params: [],
41
+ page: null,
42
+ endpoint: __memo(() => import('./entries/endpoints/api/identity/_server.ts.js-g13uvmrX.js'))
36
43
  },
37
44
  {
38
45
  id: "/api/log-groups",
39
46
  pattern: /^\/api\/log-groups\/?$/,
40
47
  params: [],
41
48
  page: null,
42
- endpoint: __memo(() => import('./entries/endpoints/api/log-groups/_server.ts.js-D143-vRl.js'))
49
+ endpoint: __memo(() => import('./entries/endpoints/api/log-groups/_server.ts.js-CmHRxdZK.js'))
43
50
  },
44
51
  {
45
52
  id: "/api/regions",
46
53
  pattern: /^\/api\/regions\/?$/,
47
54
  params: [],
48
55
  page: null,
49
- endpoint: __memo(() => import('./entries/endpoints/api/regions/_server.ts.js-CDNL7msU.js'))
56
+ endpoint: __memo(() => import('./entries/endpoints/api/regions/_server.ts.js-BgUwioxp.js'))
50
57
  },
51
58
  {
52
59
  id: "/api/stream",
53
60
  pattern: /^\/api\/stream\/?$/,
54
61
  params: [],
55
62
  page: null,
56
- endpoint: __memo(() => import('./entries/endpoints/api/stream/_server.ts.js-D_i-xW6_.js'))
63
+ endpoint: __memo(() => import('./entries/endpoints/api/stream/_server.ts.js-CIYo4C-0.js'))
57
64
  }
58
65
  ],
59
66
  prerendered_routes: new Set([]),
@@ -67,4 +74,4 @@ return {
67
74
  })();
68
75
 
69
76
  export { manifest as m };
70
- //# sourceMappingURL=manifest.js-CVImQuLw.js.map
77
+ //# sourceMappingURL=manifest.js-BUrA7Zyr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js-BUrA7Zyr.js","sources":["../../../.svelte-kit/output/server/manifest.js"],"sourcesContent":["export const manifest = (() => {\nfunction __memo(fn) {\n\tlet value;\n\treturn () => value ??= (value = fn());\n}\n\nreturn {\n\tappDir: \"_app\",\n\tappPath: \"_app\",\n\tassets: new Set([\"robots.txt\"]),\n\tmimeTypes: {\".txt\":\"text/plain\"},\n\t_: {\n\t\tclient: {start:\"_app/immutable/entry/start.clEDpQL9.js\",app:\"_app/immutable/entry/app.Be166AxG.js\",imports:[\"_app/immutable/entry/start.clEDpQL9.js\",\"_app/immutable/chunks/De_x7GQi.js\",\"_app/immutable/chunks/ZAD2y5xJ.js\",\"_app/immutable/entry/app.Be166AxG.js\",\"_app/immutable/chunks/ZAD2y5xJ.js\",\"_app/immutable/chunks/xihTtKlq.js\"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},\n\t\tnodes: [\n\t\t\t__memo(() => import('./nodes/0.js')),\n\t\t\t__memo(() => import('./nodes/1.js')),\n\t\t\t__memo(() => import('./nodes/2.js'))\n\t\t],\n\t\tremotes: {\n\t\t\t\n\t\t},\n\t\troutes: [\n\t\t\t{\n\t\t\t\tid: \"/\",\n\t\t\t\tpattern: /^\\/$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 2 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/health\",\n\t\t\t\tpattern: /^\\/api\\/health\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/health/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/identity\",\n\t\t\t\tpattern: /^\\/api\\/identity\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/identity/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/log-groups\",\n\t\t\t\tpattern: /^\\/api\\/log-groups\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/log-groups/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/regions\",\n\t\t\t\tpattern: /^\\/api\\/regions\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/regions/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/stream\",\n\t\t\t\tpattern: /^\\/api\\/stream\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/stream/_server.ts.js'))\n\t\t\t}\n\t\t],\n\t\tprerendered_routes: new Set([]),\n\t\tmatchers: async () => {\n\t\t\t\n\t\t\treturn { };\n\t\t},\n\t\tserver_assets: {}\n\t}\n}\n})();\n"],"names":[],"mappings":"AAAY,MAAC,QAAQ,GAAG,CAAC,MAAM;AAC/B,SAAS,MAAM,CAAC,EAAE,EAAE;AACpB,CAAC,IAAI,KAAK;AACV,CAAC,OAAO,MAAM,KAAK,MAAM,KAAK,GAAG,EAAE,EAAE,CAAC;AACtC;;AAEA,OAAO;AACP,CAAC,MAAM,EAAE,MAAM;AACf,CAAC,OAAO,EAAE,MAAM;AAChB,CAAC,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC;AAChC,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC;AACjC,CAAC,CAAC,EAAE;AACJ,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,wCAAwC,CAAC,GAAG,CAAC,sCAAsC,CAAC,OAAO,CAAC,CAAC,wCAAwC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,sCAAsC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAAC,KAAK,CAAC;AACrY,EAAE,KAAK,EAAE;AACT,GAAG,MAAM,CAAC,MAAM,OAAO,0BAAc,CAAC,CAAC;AACvC,GAAG,MAAM,CAAC,MAAM,OAAO,0BAAc,CAAC,CAAC;AACvC,GAAG,MAAM,CAAC,MAAM,OAAO,0BAAc,CAAC;AACtC,GAAG;AACH,EAAE,OAAO,EAAE;AACX;AACA,GAAG;AACH,EAAE,MAAM,EAAE;AACV,GAAG;AACH,IAAI,EAAE,EAAE,GAAG;AACX,IAAI,OAAO,EAAE,MAAM;AACnB,IAAI,MAAM,EAAE,EAAE;AACd,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;AAClD,IAAI,QAAQ,EAAE;AACd,IAAI;AACJ,GAAG;AACH,IAAI,EAAE,EAAE,aAAa;AACrB,IAAI,OAAO,EAAE,oBAAoB;AACjC,IAAI,MAAM,EAAE,EAAE;AACd,IAAI,IAAI,EAAE,IAAI;AACd,IAAI,QAAQ,EAAE,MAAM,CAAC,MAAM,OAAO,0DAA8C,CAAC;AACjF,IAAI;AACJ,GAAG;AACH,IAAI,EAAE,EAAE,eAAe;AACvB,IAAI,OAAO,EAAE,sBAAsB;AACnC,IAAI,MAAM,EAAE,EAAE;AACd,IAAI,IAAI,EAAE,IAAI;AACd,IAAI,QAAQ,EAAE,MAAM,CAAC,MAAM,OAAO,4DAAgD,CAAC;AACnF,IAAI;AACJ,GAAG;AACH,IAAI,EAAE,EAAE,iBAAiB;AACzB,IAAI,OAAO,EAAE,wBAAwB;AACrC,IAAI,MAAM,EAAE,EAAE;AACd,IAAI,IAAI,EAAE,IAAI;AACd,IAAI,QAAQ,EAAE,MAAM,CAAC,MAAM,OAAO,8DAAkD,CAAC;AACrF,IAAI;AACJ,GAAG;AACH,IAAI,EAAE,EAAE,cAAc;AACtB,IAAI,OAAO,EAAE,qBAAqB;AAClC,IAAI,MAAM,EAAE,EAAE;AACd,IAAI,IAAI,EAAE,IAAI;AACd,IAAI,QAAQ,EAAE,MAAM,CAAC,MAAM,OAAO,2DAA+C,CAAC;AAClF,IAAI;AACJ,GAAG;AACH,IAAI,EAAE,EAAE,aAAa;AACrB,IAAI,OAAO,EAAE,oBAAoB;AACjC,IAAI,MAAM,EAAE,EAAE;AACd,IAAI,IAAI,EAAE,IAAI;AACd,IAAI,QAAQ,EAAE,MAAM,CAAC,MAAM,OAAO,0DAA8C,CAAC;AACjF;AACA,GAAG;AACH,EAAE,kBAAkB,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC;AACjC,EAAE,QAAQ,EAAE,YAAY;AACxB;AACA,GAAG,OAAO,IAAI;AACd,EAAE,CAAC;AACH,EAAE,aAAa,EAAE;AACjB;AACA;AACA,CAAC;;"}
@@ -1,9 +1,9 @@
1
1
  const index = 0;
2
2
  let component_cache;
3
- const component = async () => component_cache ??= (await import('../entries/pages/_layout.svelte.js-Bx7lXkAi.js')).default;
4
- const imports = ["_app/immutable/nodes/0.DHBUWbOo.js","_app/immutable/chunks/ZAD2y5xJ.js","_app/immutable/chunks/xihTtKlq.js"];
5
- const stylesheets = ["_app/immutable/assets/0.CocWI5K4.css"];
3
+ const component = async () => component_cache ??= (await import('../entries/pages/_layout.svelte.js-Dzluuq12.js')).default;
4
+ const imports = ["_app/immutable/nodes/0.BJ6Zdc8H.js","_app/immutable/chunks/ZAD2y5xJ.js","_app/immutable/chunks/xihTtKlq.js"];
5
+ const stylesheets = ["_app/immutable/assets/0.BPmQoXaO.css"];
6
6
  const fonts = [];
7
7
 
8
8
  export { component, fonts, imports, index, stylesheets };
9
- //# sourceMappingURL=0.js-Bg4_hDjk.js.map
9
+ //# sourceMappingURL=0.js-gSRmrAt_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"0.js-Bg4_hDjk.js","sources":["../../../../.svelte-kit/output/server/nodes/0.js"],"sourcesContent":["\n\nexport const index = 0;\nlet component_cache;\nexport const component = async () => component_cache ??= (await import('../entries/pages/_layout.svelte.js')).default;\nexport const imports = [\"_app/immutable/nodes/0.DHBUWbOo.js\",\"_app/immutable/chunks/ZAD2y5xJ.js\",\"_app/immutable/chunks/xihTtKlq.js\"];\nexport const stylesheets = [\"_app/immutable/assets/0.CocWI5K4.css\"];\nexport const fonts = [];\n"],"names":[],"mappings":"AAEY,MAAC,KAAK,GAAG;AACrB,IAAI,eAAe;AACP,MAAC,SAAS,GAAG,YAAY,eAAe,KAAK,CAAC,MAAM,OAAO,gDAAoC,CAAC,EAAE;AAClG,MAAC,OAAO,GAAG,CAAC,oCAAoC,CAAC,mCAAmC,CAAC,mCAAmC;AACxH,MAAC,WAAW,GAAG,CAAC,sCAAsC;AACtD,MAAC,KAAK,GAAG;;"}
1
+ {"version":3,"file":"0.js-gSRmrAt_.js","sources":["../../../../.svelte-kit/output/server/nodes/0.js"],"sourcesContent":["\n\nexport const index = 0;\nlet component_cache;\nexport const component = async () => component_cache ??= (await import('../entries/pages/_layout.svelte.js')).default;\nexport const imports = [\"_app/immutable/nodes/0.BJ6Zdc8H.js\",\"_app/immutable/chunks/ZAD2y5xJ.js\",\"_app/immutable/chunks/xihTtKlq.js\"];\nexport const stylesheets = [\"_app/immutable/assets/0.BPmQoXaO.css\"];\nexport const fonts = [];\n"],"names":[],"mappings":"AAEY,MAAC,KAAK,GAAG;AACrB,IAAI,eAAe;AACP,MAAC,SAAS,GAAG,YAAY,eAAe,KAAK,CAAC,MAAM,OAAO,gDAAoC,CAAC,EAAE;AAClG,MAAC,OAAO,GAAG,CAAC,oCAAoC,CAAC,mCAAmC,CAAC,mCAAmC;AACxH,MAAC,WAAW,GAAG,CAAC,sCAAsC;AACtD,MAAC,KAAK,GAAG;;"}
@@ -1,9 +1,9 @@
1
1
  const index = 1;
2
2
  let component_cache;
3
- const component = async () => component_cache ??= (await import('../entries/fallbacks/error.svelte.js-DwU8Vh5R.js')).default;
4
- const imports = ["_app/immutable/nodes/1.Bink5luw.js","_app/immutable/chunks/ZAD2y5xJ.js","_app/immutable/chunks/xihTtKlq.js","_app/immutable/chunks/KFjMNKuK.js","_app/immutable/chunks/CsscK9Dm.js"];
3
+ const component = async () => component_cache ??= (await import('../entries/fallbacks/error.svelte.js-CFonuZkV.js')).default;
4
+ const imports = ["_app/immutable/nodes/1.xMNWuLLz.js","_app/immutable/chunks/ZAD2y5xJ.js","_app/immutable/chunks/xihTtKlq.js","_app/immutable/chunks/Bw_9uNRP.js","_app/immutable/chunks/De_x7GQi.js"];
5
5
  const stylesheets = [];
6
6
  const fonts = [];
7
7
 
8
8
  export { component, fonts, imports, index, stylesheets };
9
- //# sourceMappingURL=1.js-D_fOWpEW.js.map
9
+ //# sourceMappingURL=1.js-D68K7Ad_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"1.js-D_fOWpEW.js","sources":["../../../../.svelte-kit/output/server/nodes/1.js"],"sourcesContent":["\n\nexport const index = 1;\nlet component_cache;\nexport const component = async () => component_cache ??= (await import('../entries/fallbacks/error.svelte.js')).default;\nexport const imports = [\"_app/immutable/nodes/1.Bink5luw.js\",\"_app/immutable/chunks/ZAD2y5xJ.js\",\"_app/immutable/chunks/xihTtKlq.js\",\"_app/immutable/chunks/KFjMNKuK.js\",\"_app/immutable/chunks/CsscK9Dm.js\"];\nexport const stylesheets = [];\nexport const fonts = [];\n"],"names":[],"mappings":"AAEY,MAAC,KAAK,GAAG;AACrB,IAAI,eAAe;AACP,MAAC,SAAS,GAAG,YAAY,eAAe,KAAK,CAAC,MAAM,OAAO,kDAAsC,CAAC,EAAE;AACpG,MAAC,OAAO,GAAG,CAAC,oCAAoC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC;AAChM,MAAC,WAAW,GAAG;AACf,MAAC,KAAK,GAAG;;"}
1
+ {"version":3,"file":"1.js-D68K7Ad_.js","sources":["../../../../.svelte-kit/output/server/nodes/1.js"],"sourcesContent":["\n\nexport const index = 1;\nlet component_cache;\nexport const component = async () => component_cache ??= (await import('../entries/fallbacks/error.svelte.js')).default;\nexport const imports = [\"_app/immutable/nodes/1.xMNWuLLz.js\",\"_app/immutable/chunks/ZAD2y5xJ.js\",\"_app/immutable/chunks/xihTtKlq.js\",\"_app/immutable/chunks/Bw_9uNRP.js\",\"_app/immutable/chunks/De_x7GQi.js\"];\nexport const stylesheets = [];\nexport const fonts = [];\n"],"names":[],"mappings":"AAEY,MAAC,KAAK,GAAG;AACrB,IAAI,eAAe;AACP,MAAC,SAAS,GAAG,YAAY,eAAe,KAAK,CAAC,MAAM,OAAO,kDAAsC,CAAC,EAAE;AACpG,MAAC,OAAO,GAAG,CAAC,oCAAoC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC;AAChM,MAAC,WAAW,GAAG;AACf,MAAC,KAAK,GAAG;;"}
@@ -0,0 +1,9 @@
1
+ const index = 2;
2
+ let component_cache;
3
+ const component = async () => component_cache ??= (await import('../entries/pages/_page.svelte.js-CpwYbxbM.js')).default;
4
+ const imports = ["_app/immutable/nodes/2.CaxDXwmh.js","_app/immutable/chunks/ZAD2y5xJ.js","_app/immutable/chunks/De_x7GQi.js","_app/immutable/chunks/xihTtKlq.js","_app/immutable/chunks/Bw_9uNRP.js"];
5
+ const stylesheets = [];
6
+ const fonts = [];
7
+
8
+ export { component, fonts, imports, index, stylesheets };
9
+ //# sourceMappingURL=2.js-ChYsaaoC.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"2.js-t5EYxWxj.js","sources":["../../../../.svelte-kit/output/server/nodes/2.js"],"sourcesContent":["\n\nexport const index = 2;\nlet component_cache;\nexport const component = async () => component_cache ??= (await import('../entries/pages/_page.svelte.js')).default;\nexport const imports = [\"_app/immutable/nodes/2.U0ljz8ot.js\",\"_app/immutable/chunks/ZAD2y5xJ.js\",\"_app/immutable/chunks/CsscK9Dm.js\",\"_app/immutable/chunks/xihTtKlq.js\",\"_app/immutable/chunks/KFjMNKuK.js\"];\nexport const stylesheets = [];\nexport const fonts = [];\n"],"names":[],"mappings":"AAEY,MAAC,KAAK,GAAG;AACrB,IAAI,eAAe;AACP,MAAC,SAAS,GAAG,YAAY,eAAe,KAAK,CAAC,MAAM,OAAO,8CAAkC,CAAC,EAAE;AAChG,MAAC,OAAO,GAAG,CAAC,oCAAoC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC;AAChM,MAAC,WAAW,GAAG;AACf,MAAC,KAAK,GAAG;;"}
1
+ {"version":3,"file":"2.js-ChYsaaoC.js","sources":["../../../../.svelte-kit/output/server/nodes/2.js"],"sourcesContent":["\n\nexport const index = 2;\nlet component_cache;\nexport const component = async () => component_cache ??= (await import('../entries/pages/_page.svelte.js')).default;\nexport const imports = [\"_app/immutable/nodes/2.CaxDXwmh.js\",\"_app/immutable/chunks/ZAD2y5xJ.js\",\"_app/immutable/chunks/De_x7GQi.js\",\"_app/immutable/chunks/xihTtKlq.js\",\"_app/immutable/chunks/Bw_9uNRP.js\"];\nexport const stylesheets = [];\nexport const fonts = [];\n"],"names":[],"mappings":"AAEY,MAAC,KAAK,GAAG;AACrB,IAAI,eAAe;AACP,MAAC,SAAS,GAAG,YAAY,eAAe,KAAK,CAAC,MAAM,OAAO,8CAAkC,CAAC,EAAE;AAChG,MAAC,OAAO,GAAG,CAAC,oCAAoC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC;AAChM,MAAC,WAAW,GAAG;AACf,MAAC,KAAK,GAAG;;"}
package/dist/cli/index.js CHANGED
@@ -10,12 +10,12 @@
10
10
  import { spawn } from 'node:child_process';
11
11
  import { readFileSync } from 'node:fs';
12
12
  import { join } from 'node:path';
13
- import { buildChildEnv, describeChildEnv, isEmulatorEndpoint, isLocalEnvPresent, readConfigText, readCredentialsText, readProfiles, resolveRunRegion, signalExitCode, } from "../lib/cli/aws.js";
13
+ import { buildChildEnv, describeChildEnv, isEmulatorEndpoint, isLocalEnvPresent, readConfigText, readCredentialsText, readLocalEnvValues, readProfiles, resolveRunRegion, signalExitCode, suppressLocalEnvValues, } from "../lib/cli/aws.js";
14
14
  import { classifyCredentialFailure, describeStyle, isCredentialFailure, loginAdvice, readProfileStyle, } from "../lib/cli/credentials.js";
15
15
  import { handleCompletion } from "./completions.js";
16
16
  import { isLoopbackHost, parseCliArgs, usageText } from "./options.js";
17
17
  import { appRootFromHere, healthUrl, openBrowser as openBrowserDefault, startServer, stopServer, uiUrl, waitForHealth, } from "./server.js";
18
- import { isHeadless, probeCredentials as probeCredentialsDefault, runLogin as runLoginDefault, } from "./preflight.js";
18
+ import { isHeadless, probeCredentials as probeCredentialsDefault, readIdentity as readIdentityDefault, runLogin as runLoginDefault, shortIdentity, } from "./preflight.js";
19
19
  import { createUi, isInteractive } from "./ui.js";
20
20
  /** Reads the version from the package manifest next to the app root. */
21
21
  export function readVersion(appRoot) {
@@ -71,8 +71,10 @@ function defaultIo() {
71
71
  version: readVersion(appRoot),
72
72
  openBrowser: (url) => openBrowserDefault(url),
73
73
  readCredentialsText: () => readCredentialsText(),
74
+ readLocalEnvValues: () => (appRoot === null ? {} : readLocalEnvValues(appRoot)),
74
75
  probeCredentials: (input) => probeCredentialsDefault(input),
75
76
  runLogin: (command) => runLoginDefault(command),
77
+ readIdentity: (input) => readIdentityDefault(input),
76
78
  waitForHealth,
77
79
  startServerImpl: startServer,
78
80
  spawnImpl: spawn,
@@ -106,53 +108,71 @@ export function resolveCliRegion(options, io) {
106
108
  *
107
109
  * Emulator runs are skipped: `--floci` supplies throwaway keys on purpose.
108
110
  */
109
- async function ensureCredentials(input) {
110
- const { options, io, ui, url, region } = input;
111
+ /**
112
+ * Asks the running app whether it can read logs, and when it cannot because of
113
+ * credentials, decides which profile the run should be using.
114
+ *
115
+ * With no profile in play it asks, because a machine with several profiles is
116
+ * rarely served by the ambient default. The identity check and the login come
117
+ * after the app has been restarted with that profile: only then do they test
118
+ * the profile the user actually chose.
119
+ */
120
+ async function assessCredentials(input) {
121
+ const { options, io, ui, url, region, startProfile } = input;
111
122
  if (options.endpoint !== null)
112
- return;
123
+ return { status: 'ok' };
113
124
  const probe = await io.probeCredentials({ baseUrl: url, region });
114
125
  if (probe.ok)
115
- return;
126
+ return { status: 'ok' };
116
127
  if (!probe.credentialProblem || !isCredentialFailure(probe.code, probe.message)) {
117
- ui.warn(`could not list log groups: ${probe.message}`);
118
- return;
119
- }
120
- // The flag wins, then the ambient AWS_PROFILE: both decide which login
121
- // command can actually repair the failure.
122
- const profile = options.profile ?? ambientProfile(io.env) ?? 'default';
123
- const style = readProfileStyle(io.readConfigText(), io.readCredentialsText(), profile);
124
- const failure = classifyCredentialFailure(probe.message, probe.code);
125
- const advice = loginAdvice({
126
- style,
127
- failure,
128
- profile,
129
- remote: isHeadless(io.env),
130
- });
128
+ return { status: 'other', message: probe.message };
129
+ }
131
130
  ui.warn(`AWS credentials are not usable: ${probe.message}`);
131
+ let profile = startProfile ?? 'default';
132
+ let chosen = null;
133
+ if (startProfile === null) {
134
+ const profiles = io.readProfiles();
135
+ if (profiles.length > 1) {
136
+ const answer = await ui.choose('Which AWS profile should watch-tail use?', profiles.map((name) => ({ value: name, label: name })), profiles.includes('default') ? 'default' : profiles[0]);
137
+ if (answer !== null && answer !== 'default') {
138
+ chosen = answer;
139
+ profile = answer;
140
+ ui.info(`using profile ${answer}`);
141
+ }
142
+ }
143
+ }
144
+ return { status: 'credentials', profile, chosen, message: probe.message, code: probe.code };
145
+ }
146
+ /**
147
+ * Offers the login that repairs a credential failure, runs it if accepted, and
148
+ * reports what happened. The profile is the one the app is currently using.
149
+ */
150
+ async function offerLogin(input) {
151
+ const { io, ui, profile, failureMessage, failureCode } = input;
152
+ const name = profile ?? 'default';
153
+ const style = readProfileStyle(io.readConfigText(), io.readCredentialsText(), name);
154
+ const failure = classifyCredentialFailure(failureMessage, failureCode);
155
+ const advice = loginAdvice({ style, failure, profile, remote: isHeadless(io.env) });
132
156
  if (advice === null) {
133
157
  ui.info(style === 'static'
134
- ? `the ${describeStyle(style)} in profile "${profile}" look wrong - check them with \`aws configure --profile ${profile}\``
135
- : `no login command applies to profile "${profile}" (${describeStyle(style)})`);
136
- return;
158
+ ? `the ${describeStyle(style)} in profile "${name}" look wrong - check them with \`aws configure --profile ${name}\``
159
+ : `no login command applies to profile "${name}" (${describeStyle(style)})`);
160
+ return { login: 'none' };
137
161
  }
138
162
  const label = `aws ${advice.command.join(' ')}`;
139
163
  const accepted = await ui.confirm(`${advice.hint}. Run \`${label}\` now?`);
140
164
  if (!accepted) {
141
165
  ui.info(`run it yourself, then press Refresh in the UI: ${label}`);
142
- return;
166
+ return { login: 'declined' };
143
167
  }
144
168
  ui.info(`running ${label}`);
145
169
  const code = await io.runLogin(advice.command);
146
170
  if (code !== 0) {
147
171
  ui.warn(`${label} exited with code ${code}`);
148
172
  ui.info(`log in another terminal, then press Refresh in the UI: ${label}`);
149
- return;
173
+ return { login: 'failed' };
150
174
  }
151
- const retry = await io.probeCredentials({ baseUrl: url, region });
152
- if (retry.ok)
153
- ui.info('signed in - credentials work now');
154
- else
155
- ui.warn(`still failing after login: ${retry.message}`);
175
+ return { login: 'succeeded' };
156
176
  }
157
177
  /** Runs the CLI and returns its exit code. */
158
178
  export async function run(argv, overrides = {}) {
@@ -190,8 +210,21 @@ export async function run(argv, overrides = {}) {
190
210
  // `--profile` wins, then the ambient AWS_PROFILE: the credential check and
191
211
  // the login advice both need to know which profile is actually in play.
192
212
  const profile = options.profile ?? ambientProfile(io.env);
213
+ let baseEnv = io.env;
214
+ let suppressedLocalEnv = [];
215
+ if (options.endpoint === null) {
216
+ // The CLI is real-AWS-by-default, so a dev `.env.local` next to the app
217
+ // (which exists in this repository, and in any checkout of it) must not
218
+ // silently redirect the run at floci. `--floci` asks for that explicitly.
219
+ const suppressed = suppressLocalEnvValues({
220
+ env: io.env,
221
+ values: io.readLocalEnvValues(),
222
+ });
223
+ baseEnv = suppressed.env;
224
+ suppressedLocalEnv = suppressed.suppressed;
225
+ }
193
226
  const childEnv = buildChildEnv({
194
- base: io.env,
227
+ base: baseEnv,
195
228
  profile: options.profile,
196
229
  region,
197
230
  endpoint: options.endpoint,
@@ -220,11 +253,14 @@ export async function run(argv, overrides = {}) {
220
253
  if (!isLoopbackHost(options.host)) {
221
254
  ui.warn(`binding ${options.host}: the app has no authentication and uses your AWS access, so anyone who can reach it can read your logs`);
222
255
  }
223
- if (isLocalEnvPresent(io.appRoot) && options.profile !== null) {
256
+ if (suppressedLocalEnv.length > 0) {
257
+ ui.warn(`ignoring the emulator settings in .env.local (${suppressedLocalEnv.join(', ')}) - pass --floci to use them`);
258
+ }
259
+ else if (isLocalEnvPresent(io.appRoot) && options.profile !== null) {
224
260
  ui.warn('a .env.local with local emulator settings was found; it is ignored for this run');
225
261
  }
226
262
  ui.startSpinner('starting the local UI...');
227
- const child = io.startServerImpl({
263
+ let child = io.startServerImpl({
228
264
  appRoot: io.appRoot,
229
265
  env: childEnv,
230
266
  port: options.port,
@@ -240,7 +276,87 @@ export async function run(argv, overrides = {}) {
240
276
  ui.stopSpinner(`listening on ${url}`);
241
277
  // Before sending anyone to a UI that cannot load logs, check that AWS will
242
278
  // actually answer, and offer the login that fixes it.
243
- await ensureCredentials({ options, io, ui, url, region });
279
+ const assessment = await assessCredentials({
280
+ options,
281
+ io,
282
+ ui,
283
+ url,
284
+ region,
285
+ startProfile: profile,
286
+ });
287
+ if (assessment.status === 'other') {
288
+ ui.warn(`could not list log groups: ${assessment.message}`);
289
+ }
290
+ if (assessment.status === 'credentials') {
291
+ // A profile that was not in play needs the app restarted with it: that is
292
+ // the only way to find out whether its credentials already work, and the
293
+ // only way the browser can use it.
294
+ const activeProfile = assessment.chosen === null ? null : assessment.chosen;
295
+ let activeRegion = region;
296
+ let failureMessage = assessment.message;
297
+ let failureCode = assessment.code;
298
+ if (assessment.chosen !== null) {
299
+ activeRegion = resolveRunRegion({
300
+ region: options.region,
301
+ profile: assessment.chosen,
302
+ base: io.env,
303
+ configText: io.readConfigText(),
304
+ });
305
+ ui.info(`restarting with profile ${assessment.chosen}`);
306
+ await stopServer(child);
307
+ child = io.startServerImpl({
308
+ appRoot: io.appRoot,
309
+ env: buildChildEnv({
310
+ base: baseEnv,
311
+ profile: assessment.chosen,
312
+ region: activeRegion,
313
+ endpoint: null,
314
+ }),
315
+ port: options.port,
316
+ host: options.host,
317
+ verbose: options.verbose,
318
+ });
319
+ const healthy = await io.waitForHealth(healthUrl(url), { fetchImpl: fetch });
320
+ if (!healthy) {
321
+ ui.failSpinner(`the server did not come back up on ${url}`);
322
+ await stopServer(child);
323
+ return 1;
324
+ }
325
+ // Now the question is about the chosen profile, not the ambient one.
326
+ const identity = await io.readIdentity({ baseUrl: url, region: activeRegion });
327
+ if (identity.ok) {
328
+ ui.info(`profile ${assessment.chosen} already works (${shortIdentity(identity.identity.arn)}) - using it`);
329
+ ui.outro(`${url} (Ctrl+C to stop)`);
330
+ if (options.open)
331
+ io.openBrowser(url);
332
+ const code = await io.waitForStop(child);
333
+ ui.outro('stopped');
334
+ return code;
335
+ }
336
+ failureMessage = identity.message;
337
+ failureCode = identity.code;
338
+ }
339
+ const outcome = await offerLogin({
340
+ options,
341
+ io,
342
+ ui,
343
+ profile: activeProfile ?? assessment.profile,
344
+ failureMessage,
345
+ failureCode,
346
+ });
347
+ if (outcome.login === 'succeeded') {
348
+ const identity = await io.readIdentity({ baseUrl: url, region: activeRegion });
349
+ if (identity.ok) {
350
+ ui.info(`signed in as ${shortIdentity(identity.identity.arn)}${activeProfile === null ? '' : ` (${activeProfile})`}`);
351
+ }
352
+ else {
353
+ ui.warn(`still failing after login: ${identity.message}`);
354
+ }
355
+ }
356
+ else if (activeProfile !== null) {
357
+ ui.info(`the app is using profile ${activeProfile}; log in, then press Refresh in the UI`);
358
+ }
359
+ }
244
360
  if (options.open)
245
361
  io.openBrowser(url);
246
362
  ui.outro(`${url} (Ctrl+C to stop)`);
@@ -71,3 +71,45 @@ export function isHeadless(env = process.env) {
71
71
  return true;
72
72
  return false;
73
73
  }
74
+ /**
75
+ * Asks the app to call `sts:GetCallerIdentity`.
76
+ *
77
+ * This is the cheapest way to answer "do these credentials work at all?", and it
78
+ * is what tells the CLI not to offer a login for a profile that is already fine.
79
+ */
80
+ export async function readIdentity(input) {
81
+ const { baseUrl, region, fetchImpl = fetch, timeoutMs = 15_000 } = input;
82
+ const url = new URL('/api/identity', baseUrl);
83
+ if (region !== null && region !== '')
84
+ url.searchParams.set('region', region);
85
+ try {
86
+ const response = await fetchImpl(url, { signal: AbortSignal.timeout(timeoutMs) });
87
+ if (response.ok) {
88
+ return { ok: true, identity: (await response.json()) };
89
+ }
90
+ const body = (await response.json().catch(() => null));
91
+ return { ok: false, code: body?.code, message: body?.error ?? `HTTP ${response.status}` };
92
+ }
93
+ catch (error) {
94
+ return { ok: false, message: error instanceof Error ? error.message : String(error) };
95
+ }
96
+ }
97
+ /**
98
+ * Short label for an ARN, for messages.
99
+ *
100
+ * Role ARNs end with the session name and not the role
101
+ * (`assumed-role/MyRole/session-name`), so the role is the useful label; the
102
+ * session name is stripped.
103
+ */
104
+ export function shortIdentity(arn) {
105
+ if (arn.length === 0)
106
+ return 'unknown';
107
+ const resource = arn.split(':').at(-1) ?? arn;
108
+ const parts = resource.split('/').filter((part) => part.length > 0);
109
+ if (parts.length === 0)
110
+ return arn;
111
+ const [kind, name] = parts;
112
+ if ((kind === 'assumed-role' || kind === 'role' || kind === 'user') && name !== undefined)
113
+ return name;
114
+ return parts.at(-1) ?? arn;
115
+ }
package/dist/cli/ui.js CHANGED
@@ -6,14 +6,18 @@
6
6
  * falls back to plain lines, which also keeps the integration tests readable.
7
7
  */
8
8
  import { autocomplete, cancel, confirm, intro, isCancel, log, outro, spinner, } from '@clack/prompts';
9
- /** Decides whether the process can render animated output and ask questions. */
9
+ /**
10
+ * Decides whether the process can render animated output and ask questions.
11
+ *
12
+ * `NO_COLOR` is deliberately *not* consulted: it asks for no colour, which the
13
+ * prompt library honours on its own, and reading it as "do not prompt" silently
14
+ * disabled the login and profile questions for anyone who sets it.
15
+ */
10
16
  export function isInteractive(env = process.env) {
11
17
  if (env.CI !== undefined && env.CI !== '' && env.CI !== 'false')
12
18
  return false;
13
19
  if (env.WATCH_TAIL_PLAIN === '1')
14
20
  return false;
15
- if (env.NO_COLOR !== undefined && env.NO_COLOR !== '')
16
- return false;
17
21
  return process.stdout.isTTY === true && process.stdin.isTTY === true;
18
22
  }
19
23
  /**
@@ -215,6 +215,54 @@ export function buildChildEnv({ base, profile = null, region = null, endpoint =
215
215
  }
216
216
  return env;
217
217
  }
218
+ /**
219
+ * Parses a dotenv file into a plain map.
220
+ *
221
+ * Only `KEY=value` lines are read, with optional single or double quotes; the
222
+ * values are never applied to the caller's environment.
223
+ */
224
+ export function parseEnvFile(text) {
225
+ const values = {};
226
+ for (const raw of text.split('\n')) {
227
+ const line = raw.trim();
228
+ if (line.length === 0 || line.startsWith('#'))
229
+ continue;
230
+ const match = /^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(line);
231
+ if (match === null)
232
+ continue;
233
+ const value = match[2].trim().replace(/^(['"])(.*)\1$/, '$2');
234
+ values[match[1]] = value;
235
+ }
236
+ return values;
237
+ }
238
+ /** Reads `<appRoot>/.env.local`, or an empty map when it is missing. */
239
+ export function readLocalEnvValues(appRoot) {
240
+ return parseEnvFile(readTextFile(join(appRoot, LOCAL_ENV_FILE)));
241
+ }
242
+ /**
243
+ * Neutralises a `.env.local` that sits next to the app.
244
+ *
245
+ * The app applies that file to its own process (so `pnpm dev` can point at a
246
+ * local emulator), but the CLI is documented as real-AWS-by-default. A value
247
+ * from the file is therefore suppressed unless the caller already set the same
248
+ * key in their environment, which is theirs to decide. Blanking is how "unset"
249
+ * is expressed: dotenv loading never overrides a variable that exists, and the
250
+ * SDK ignores empty values.
251
+ */
252
+ export function suppressLocalEnvValues(input) {
253
+ const { env, values, keys = LOCAL_OVERRIDE_KEYS } = input;
254
+ const next = { ...env };
255
+ const suppressed = [];
256
+ for (const key of keys) {
257
+ if (values[key] === undefined)
258
+ continue;
259
+ if (normalize(env[key]) !== null)
260
+ continue; // the caller's own value wins
261
+ next[key] = '';
262
+ suppressed.push(key);
263
+ }
264
+ return { env: next, suppressed };
265
+ }
218
266
  /** True when the endpoint points at a local emulator rather than real AWS. */
219
267
  export function isEmulatorEndpoint(endpoint) {
220
268
  let hostname = '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "watch-tail",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Tail Amazon CloudWatch Logs in your browser: a local SvelteKit UI with live and historic streaming, ambient AWS credentials and floci support",
5
5
  "keywords": [
6
6
  "aws",
@@ -38,6 +38,7 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@aws-sdk/client-cloudwatch-logs": "^3.1129.0",
41
+ "@aws-sdk/client-sts": "^3.1130.0",
41
42
  "@bomb.sh/args": "^0.3.1",
42
43
  "@bomb.sh/tab": "^0.0.22",
43
44
  "@clack/prompts": "^1.8.0"
@@ -1,2 +0,0 @@
1
- /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-900:oklch(39.6% .141 25.723);--color-red-950:oklch(25.8% .092 26.042);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-900:oklch(41.4% .112 45.904);--color-amber-950:oklch(27.9% .077 45.635);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-900:oklch(37.8% .077 168.94);--color-emerald-950:oklch(26.2% .051 172.552);--color-sky-200:oklch(90.1% .058 230.902);--color-sky-300:oklch(82.8% .111 230.318);--color-sky-400:oklch(74.6% .16 232.661);--color-sky-500:oklch(68.5% .169 237.323);--color-sky-600:oklch(58.8% .158 241.966);--color-sky-700:oklch(50% .134 242.749);--color-sky-800:oklch(44.3% .11 240.79);--color-sky-900:oklch(39.1% .09 240.876);--color-sky-950:oklch(29.3% .066 243.157);--color-violet-300:oklch(81.1% .111 293.571);--color-violet-900:oklch(38% .189 293.745);--color-violet-950:oklch(28.3% .141 291.089);--color-fuchsia-300:oklch(83.3% .145 321.434);--color-neutral-100:oklch(97% 0 none);--color-neutral-200:oklch(92.2% 0 none);--color-neutral-300:oklch(87% 0 none);--color-neutral-400:oklch(70.8% 0 none);--color-neutral-500:oklch(55.6% 0 none);--color-neutral-600:oklch(43.9% 0 none);--color-neutral-700:oklch(37.1% 0 none);--color-neutral-800:oklch(26.9% 0 none);--color-neutral-900:oklch(20.5% 0 none);--color-neutral-950:oklch(14.5% 0 none);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-wider:.05em;--radius-md:.375rem;--radius-lg:.5rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-y-0{inset-block:0}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.h-5{height:calc(var(--spacing) * 5)}.h-dvh{height:100dvh}.min-h-0{min-height:0}.min-h-\[30rem\]{min-height:30rem}.min-h-full{min-height:100%}.w-2{width:calc(var(--spacing) * 2)}.w-40{width:calc(var(--spacing) * 40)}.w-\[7\.5rem\]{width:7.5rem}.w-full{width:100%}.w-max{width:max-content}.max-w-\[22rem\]{max-width:22rem}.min-w-0{min-width:0}.min-w-full{min-width:100%}.flex-1{flex:1}.flex-none{flex:none}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.animate-pulse{animation:var(--animate-pulse)}.cursor-col-resize{cursor:col-resize}.touch-none{touch-action:none}.resize{resize:both}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-amber-700{border-color:var(--color-amber-700)}.border-amber-900{border-color:var(--color-amber-900)}.border-emerald-900{border-color:var(--color-emerald-900)}.border-neutral-700{border-color:var(--color-neutral-700)}.border-neutral-800{border-color:var(--color-neutral-800)}.border-neutral-900{border-color:var(--color-neutral-900)}.border-red-900{border-color:var(--color-red-900)}.border-sky-700{border-color:var(--color-sky-700)}.border-sky-800{border-color:var(--color-sky-800)}.border-sky-900{border-color:var(--color-sky-900)}.border-transparent{border-color:#0000}.border-violet-900{border-color:var(--color-violet-900)}.bg-amber-400{background-color:var(--color-amber-400)}.bg-amber-950\/40{background-color:#46190166}@supports (color:color-mix(in lab, red, red)){.bg-amber-950\/40{background-color:color-mix(in oklab, var(--color-amber-950) 40%, transparent)}}.bg-amber-950\/50{background-color:#46190180}@supports (color:color-mix(in lab, red, red)){.bg-amber-950\/50{background-color:color-mix(in oklab, var(--color-amber-950) 50%, transparent)}}.bg-amber-950\/70{background-color:#461901b3}@supports (color:color-mix(in lab, red, red)){.bg-amber-950\/70{background-color:color-mix(in oklab, var(--color-amber-950) 70%, transparent)}}.bg-emerald-400{background-color:var(--color-emerald-400)}.bg-emerald-950\/70{background-color:#002c22b3}@supports (color:color-mix(in lab, red, red)){.bg-emerald-950\/70{background-color:color-mix(in oklab, var(--color-emerald-950) 70%, transparent)}}.bg-neutral-500{background-color:var(--color-neutral-500)}.bg-neutral-800\/60{background-color:#26262699}@supports (color:color-mix(in lab, red, red)){.bg-neutral-800\/60{background-color:color-mix(in oklab, var(--color-neutral-800) 60%, transparent)}}.bg-neutral-800\/80{background-color:#262626cc}@supports (color:color-mix(in lab, red, red)){.bg-neutral-800\/80{background-color:color-mix(in oklab, var(--color-neutral-800) 80%, transparent)}}.bg-neutral-900{background-color:var(--color-neutral-900)}.bg-neutral-900\/40{background-color:#17171766}@supports (color:color-mix(in lab, red, red)){.bg-neutral-900\/40{background-color:color-mix(in oklab, var(--color-neutral-900) 40%, transparent)}}.bg-neutral-900\/60{background-color:#17171799}@supports (color:color-mix(in lab, red, red)){.bg-neutral-900\/60{background-color:color-mix(in oklab, var(--color-neutral-900) 60%, transparent)}}.bg-neutral-900\/70{background-color:#171717b3}@supports (color:color-mix(in lab, red, red)){.bg-neutral-900\/70{background-color:color-mix(in oklab, var(--color-neutral-900) 70%, transparent)}}.bg-neutral-950{background-color:var(--color-neutral-950)}.bg-neutral-950\/60{background-color:#0a0a0a99}@supports (color:color-mix(in lab, red, red)){.bg-neutral-950\/60{background-color:color-mix(in oklab, var(--color-neutral-950) 60%, transparent)}}.bg-neutral-950\/90{background-color:#0a0a0ae6}@supports (color:color-mix(in lab, red, red)){.bg-neutral-950\/90{background-color:color-mix(in oklab, var(--color-neutral-950) 90%, transparent)}}.bg-red-400{background-color:var(--color-red-400)}.bg-red-950\/50{background-color:#46080980}@supports (color:color-mix(in lab, red, red)){.bg-red-950\/50{background-color:color-mix(in oklab, var(--color-red-950) 50%, transparent)}}.bg-red-950\/70{background-color:#460809b3}@supports (color:color-mix(in lab, red, red)){.bg-red-950\/70{background-color:color-mix(in oklab, var(--color-red-950) 70%, transparent)}}.bg-sky-400{background-color:var(--color-sky-400)}.bg-sky-950\/50{background-color:#052f4a80}@supports (color:color-mix(in lab, red, red)){.bg-sky-950\/50{background-color:color-mix(in oklab, var(--color-sky-950) 50%, transparent)}}.bg-sky-950\/60{background-color:#052f4a99}@supports (color:color-mix(in lab, red, red)){.bg-sky-950\/60{background-color:color-mix(in oklab, var(--color-sky-950) 60%, transparent)}}.bg-sky-950\/70{background-color:#052f4ab3}@supports (color:color-mix(in lab, red, red)){.bg-sky-950\/70{background-color:color-mix(in oklab, var(--color-sky-950) 70%, transparent)}}.bg-transparent{background-color:#0000}.bg-violet-950\/60{background-color:#2f0d6899}@supports (color:color-mix(in lab, red, red)){.bg-violet-950\/60{background-color:color-mix(in oklab, var(--color-violet-950) 60%, transparent)}}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.pr-1{padding-right:var(--spacing)}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.6875rem\]{font-size:.6875rem}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-200{color:var(--color-amber-200)}.text-amber-300{color:var(--color-amber-300)}.text-amber-300\/80{color:#ffd236cc}@supports (color:color-mix(in lab, red, red)){.text-amber-300\/80{color:color-mix(in oklab, var(--color-amber-300) 80%, transparent)}}.text-amber-400\/80{color:#fcbb00cc}@supports (color:color-mix(in lab, red, red)){.text-amber-400\/80{color:color-mix(in oklab, var(--color-amber-400) 80%, transparent)}}.text-emerald-300{color:var(--color-emerald-300)}.text-emerald-400\/80{color:#00d294cc}@supports (color:color-mix(in lab, red, red)){.text-emerald-400\/80{color:color-mix(in oklab, var(--color-emerald-400) 80%, transparent)}}.text-fuchsia-300{color:var(--color-fuchsia-300)}.text-neutral-100{color:var(--color-neutral-100)}.text-neutral-200{color:var(--color-neutral-200)}.text-neutral-300{color:var(--color-neutral-300)}.text-neutral-400{color:var(--color-neutral-400)}.text-neutral-500{color:var(--color-neutral-500)}.text-neutral-600{color:var(--color-neutral-600)}.text-red-300{color:var(--color-red-300)}.text-red-400{color:var(--color-red-400)}.text-sky-200{color:var(--color-sky-200)}.text-sky-300{color:var(--color-sky-300)}.text-sky-400{color:var(--color-sky-400)}.text-sky-400\/80{color:#00bcfecc}@supports (color:color-mix(in lab, red, red)){.text-sky-400\/80{color:color-mix(in oklab, var(--color-sky-400) 80%, transparent)}}.text-violet-300{color:var(--color-violet-300)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.selection\:bg-sky-900\/60 ::selection{background-color:#024a7099}@supports (color:color-mix(in lab, red, red)){.selection\:bg-sky-900\/60 ::selection{background-color:color-mix(in oklab, var(--color-sky-900) 60%, transparent)}}.selection\:bg-sky-900\/60::selection{background-color:#024a7099}@supports (color:color-mix(in lab, red, red)){.selection\:bg-sky-900\/60::selection{background-color:color-mix(in oklab, var(--color-sky-900) 60%, transparent)}}.placeholder\:text-neutral-600::placeholder{color:var(--color-neutral-600)}@media (hover:hover){.hover\:border-neutral-700:hover{border-color:var(--color-neutral-700)}.hover\:border-neutral-800:hover{border-color:var(--color-neutral-800)}.hover\:border-sky-600:hover{border-color:var(--color-sky-600)}.hover\:bg-neutral-900\/60:hover{background-color:#17171799}@supports (color:color-mix(in lab, red, red)){.hover\:bg-neutral-900\/60:hover{background-color:color-mix(in oklab, var(--color-neutral-900) 60%, transparent)}}.hover\:bg-sky-500\/30:hover{background-color:#00a5ef4d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-sky-500\/30:hover{background-color:color-mix(in oklab, var(--color-sky-500) 30%, transparent)}}.hover\:text-neutral-100:hover{color:var(--color-neutral-100)}.hover\:text-neutral-200:hover{color:var(--color-neutral-200)}}.focus\:border-sky-600:focus{border-color:var(--color-sky-600)}.focus\:bg-sky-500\/50:focus{background-color:#00a5ef80}@supports (color:color-mix(in lab, red, red)){.focus\:bg-sky-500\/50:focus{background-color:color-mix(in oklab, var(--color-sky-500) 50%, transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}@media (width>=40rem){.sm\:inline{display:inline}.sm\:px-4{padding-inline:calc(var(--spacing) * 4)}}@media (width>=64rem){.lg\:block{display:block}.lg\:w-2{width:calc(var(--spacing) * 2)}.lg\:shrink-0{flex-shrink:0}.lg\:flex-row{flex-direction:row}}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}