Browse Source

big format

Dax Raad 3 tháng trước cách đây
mục cha
commit
1ea3a8eb9b
100 tập tin đã thay đổi với 1670 bổ sung1959 xóa
  1. 23 23
      AGENTS.md
  2. 1 1
      github/sst-env.d.ts
  3. 14 14
      logs/.2c5480b3b2480f80fa29b850af461dce619c0b2f-audit.json
  4. 1 1
      packages/console/app/src/component/dropdown.css
  5. 4 1
      packages/console/app/src/component/faq.tsx
  6. 113 20
      packages/console/app/src/component/icon.tsx
  7. 1 1
      packages/console/app/src/component/modal.css
  8. 4 1
      packages/console/app/src/routes/auth/authorize.ts
  9. 4 7
      packages/console/app/src/routes/brand/index.css
  10. 1 1
      packages/console/app/src/routes/user-menu.css
  11. 1 1
      packages/console/app/src/routes/workspace-picker.css
  12. 9 2
      packages/console/app/src/routes/workspace-picker.tsx
  13. 1 1
      packages/console/app/src/routes/workspace.css
  14. 1 1
      packages/console/app/src/routes/workspace/[id]/billing/billing-section.module.css
  15. 1 1
      packages/console/app/src/routes/workspace/[id]/billing/monthly-limit-section.module.css
  16. 4 1
      packages/console/app/src/routes/workspace/[id]/billing/payment-section.tsx
  17. 0 1
      packages/console/app/src/routes/workspace/[id]/billing/reload-section.module.css
  18. 3 6
      packages/console/app/src/routes/workspace/[id]/keys/key-section.module.css
  19. 8 2
      packages/console/app/src/routes/workspace/[id]/keys/key-section.tsx
  20. 6 1
      packages/console/app/src/routes/workspace/[id]/members/member-section.tsx
  21. 1 1
      packages/console/app/src/routes/workspace/[id]/members/role-dropdown.css
  22. 1 1
      packages/console/app/src/routes/workspace/[id]/new-user-section.module.css
  23. 12 3
      packages/console/app/src/routes/workspace/[id]/new-user-section.tsx
  24. 1 2
      packages/console/app/src/routes/workspace/[id]/provider-section.module.css
  25. 16 4
      packages/console/app/src/routes/workspace/[id]/provider-section.tsx
  26. 3 3
      packages/console/app/src/routes/workspace/[id]/settings/settings-section.module.css
  27. 96 36
      packages/console/app/src/routes/zen/index.tsx
  28. 48 13
      packages/console/app/src/routes/zen/util/provider/anthropic.ts
  29. 24 11
      packages/console/app/src/routes/zen/util/provider/openai-compatible.ts
  30. 63 16
      packages/console/app/src/routes/zen/util/provider/openai.ts
  31. 2 1
      packages/console/app/src/style/token/font.css
  32. 1 1
      packages/console/app/sst-env.d.ts
  33. 13 44
      packages/console/core/migrations/meta/0018_snapshot.json
  34. 13 44
      packages/console/core/migrations/meta/0019_snapshot.json
  35. 13 44
      packages/console/core/migrations/meta/0020_snapshot.json
  36. 13 44
      packages/console/core/migrations/meta/0021_snapshot.json
  37. 14 48
      packages/console/core/migrations/meta/0022_snapshot.json
  38. 16 54
      packages/console/core/migrations/meta/0023_snapshot.json
  39. 16 54
      packages/console/core/migrations/meta/0024_snapshot.json
  40. 16 54
      packages/console/core/migrations/meta/0025_snapshot.json
  41. 15 50
      packages/console/core/migrations/meta/0026_snapshot.json
  42. 15 50
      packages/console/core/migrations/meta/0027_snapshot.json
  43. 15 50
      packages/console/core/migrations/meta/0028_snapshot.json
  44. 15 50
      packages/console/core/migrations/meta/0029_snapshot.json
  45. 17 58
      packages/console/core/migrations/meta/0030_snapshot.json
  46. 19 66
      packages/console/core/migrations/meta/0031_snapshot.json
  47. 19 66
      packages/console/core/migrations/meta/0032_snapshot.json
  48. 19 66
      packages/console/core/migrations/meta/0033_snapshot.json
  49. 20 70
      packages/console/core/migrations/meta/0034_snapshot.json
  50. 20 70
      packages/console/core/migrations/meta/0035_snapshot.json
  51. 22 76
      packages/console/core/migrations/meta/0036_snapshot.json
  52. 22 76
      packages/console/core/migrations/meta/0037_snapshot.json
  53. 1 1
      packages/console/core/migrations/meta/_journal.json
  54. 28 25
      packages/console/core/src/aws.ts
  55. 8 2
      packages/console/core/src/drizzle/index.ts
  56. 8 2
      packages/console/core/src/key.ts
  57. 9 2
      packages/console/core/src/provider.ts
  58. 8 1
      packages/console/core/src/schema/auth.sql.ts
  59. 4 1
      packages/console/core/src/schema/model.sql.ts
  60. 4 1
      packages/console/core/src/schema/provider.sql.ts
  61. 9 1
      packages/console/core/src/schema/user.sql.ts
  62. 23 5
      packages/console/core/src/user.ts
  63. 87 87
      packages/console/core/sst-env.d.ts
  64. 87 87
      packages/console/function/sst-env.d.ts
  65. 21 4
      packages/console/mail/emails/templates/InviteEmail.tsx
  66. 1 1
      packages/console/mail/sst-env.d.ts
  67. 87 87
      packages/console/resource/sst-env.d.ts
  68. 2 4
      packages/desktop/src/sst-env.d.ts
  69. 1 1
      packages/desktop/sst-env.d.ts
  70. 5 1
      packages/function/src/api.ts
  71. 87 87
      packages/function/sst-env.d.ts
  72. 5 2
      packages/opencode/script/postinstall.mjs
  73. 13 2
      packages/opencode/script/schema.ts
  74. 16 2
      packages/opencode/src/agent/agent.ts
  75. 8 2
      packages/opencode/src/bus/index.ts
  76. 196 187
      packages/opencode/src/cli/cmd/auth.ts
  77. 5 1
      packages/opencode/src/cli/cmd/debug/lsp.ts
  78. 5 2
      packages/opencode/src/cli/cmd/debug/ripgrep.ts
  79. 2 1
      packages/opencode/src/cli/cmd/debug/snapshot.ts
  80. 1 1
      packages/opencode/src/cli/cmd/generate.ts
  81. 45 15
      packages/opencode/src/cli/cmd/github.ts
  82. 14 4
      packages/opencode/src/cli/cmd/run.ts
  83. 5 1
      packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx
  84. 2 2
      packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx
  85. 12 2
      packages/opencode/src/cli/cmd/tui/component/logo.tsx
  86. 3 5
      packages/opencode/src/cli/cmd/tui/context/route.tsx
  87. 1 0
      packages/opencode/src/cli/cmd/tui/context/sync.tsx
  88. 1 1
      packages/opencode/src/cli/cmd/tui/context/theme/nightowl.json
  89. 3 1
      packages/opencode/src/cli/cmd/tui/routes/session/dialog-message.tsx
  90. 10 2
      packages/opencode/src/cli/cmd/tui/routes/session/dialog-timeline.tsx
  91. 3 2
      packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
  92. 6 1
      packages/opencode/src/cli/cmd/tui/spawn.ts
  93. 3 1
      packages/opencode/src/cli/cmd/tui/ui/dialog-confirm.tsx
  94. 4 1
      packages/opencode/src/cli/cmd/tui/util/editor.ts
  95. 3 1
      packages/opencode/src/cli/cmd/upgrade.ts
  96. 4 1
      packages/opencode/src/config/config.ts
  97. 3 1
      packages/opencode/src/file/fzf.ts
  98. 9 2
      packages/opencode/src/file/ripgrep.ts
  99. 4 1
      packages/opencode/src/file/time.ts
  100. 4 2
      packages/opencode/src/file/watcher.ts

+ 23 - 23
AGENTS.md

@@ -21,27 +21,27 @@
 
 json
 {
-    "recipient_name": "multi_tool_use.parallel",
-    "parameters": {
-        "tool_uses": [
-            {
-                "recipient_name": "functions.read",
-                "parameters": {
-                    "filePath": "path/to/file.tsx"
-                }
-            },
-            {
-                "recipient_name": "functions.read",
-                "parameters": {
-                    "filePath": "path/to/file.ts"
-                }
-            },
-            {
-                "recipient_name": "functions.read",
-                "parameters": {
-                    "filePath": "path/to/file.md"
-                }
-            }
-        ]
-    }
+"recipient_name": "multi_tool_use.parallel",
+"parameters": {
+"tool_uses": [
+{
+"recipient_name": "functions.read",
+"parameters": {
+"filePath": "path/to/file.tsx"
+}
+},
+{
+"recipient_name": "functions.read",
+"parameters": {
+"filePath": "path/to/file.ts"
+}
+},
+{
+"recipient_name": "functions.read",
+"parameters": {
+"filePath": "path/to/file.md"
+}
+}
+]
+}
 }

+ 1 - 1
github/sst-env.d.ts

@@ -6,4 +6,4 @@
 /// <reference path="../sst-env.d.ts" />
 
 import "sst"
-export {}
+export {}

+ 14 - 14
logs/.2c5480b3b2480f80fa29b850af461dce619c0b2f-audit.json

@@ -1,15 +1,15 @@
 {
-    "keep": {
-        "days": true,
-        "amount": 14
-    },
-    "auditLog": "/home/thdxr/dev/projects/sst/opencode/logs/.2c5480b3b2480f80fa29b850af461dce619c0b2f-audit.json",
-    "files": [
-        {
-            "date": 1759827172859,
-            "name": "/home/thdxr/dev/projects/sst/opencode/logs/mcp-puppeteer-2025-10-07.log",
-            "hash": "a3d98b26edd793411b968a0d24cfeee8332138e282023c3b83ec169d55c67f16"
-        }
-    ],
-    "hashType": "sha256"
-}
+  "keep": {
+    "days": true,
+    "amount": 14
+  },
+  "auditLog": "/home/thdxr/dev/projects/sst/opencode/logs/.2c5480b3b2480f80fa29b850af461dce619c0b2f-audit.json",
+  "files": [
+    {
+      "date": 1759827172859,
+      "name": "/home/thdxr/dev/projects/sst/opencode/logs/mcp-puppeteer-2025-10-07.log",
+      "hash": "a3d98b26edd793411b968a0d24cfeee8332138e282023c3b83ec169d55c67f16"
+    }
+  ],
+  "hashType": "sha256"
+}

+ 1 - 1
packages/console/app/src/component/dropdown.css

@@ -77,4 +77,4 @@
       background-color: var(--color-accent-alpha);
     }
   }
-}
+}

+ 4 - 1
packages/console/app/src/component/faq.tsx

@@ -13,7 +13,10 @@ export function Faq(props: ParentProps & { question: string }) {
           fill="currentColor"
           xmlns="http://www.w3.org/2000/svg"
         >
-          <path d="M12.5 11.5H19V12.5H12.5V19H11.5V12.5H5V11.5H11.5V5H12.5V11.5Z" fill="currentColor" />
+          <path
+            d="M12.5 11.5H19V12.5H12.5V19H11.5V12.5H5V11.5H11.5V5H12.5V11.5Z"
+            fill="currentColor"
+          />
         </svg>
         <svg
           data-slot="faq-icon-minus"

+ 113 - 20
packages/console/app/src/component/icon.tsx

@@ -9,10 +9,23 @@ export function IconLogo(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
       <path d="M13.7124 9.14333V4.5719H18.2838V9.14333H13.7124Z" fill="currentColor" />
       <path d="M13.7124 13.7136V9.14221H18.2838V13.7136H13.7124Z" fill="currentColor" />
       <path d="M0 18.2857V13.7142H4.57143V18.2857H0Z" fill="currentColor" fill-opacity="0.2" />
-      <rect width="4.57143" height="4.57143" transform="translate(4.57178 13.7141)" fill="currentColor" />
-      <path d="M4.57178 18.2855V13.7141H9.14321V18.2855H4.57178Z" fill="currentColor" fill-opacity="0.2" />
+      <rect
+        width="4.57143"
+        height="4.57143"
+        transform="translate(4.57178 13.7141)"
+        fill="currentColor"
+      />
+      <path
+        d="M4.57178 18.2855V13.7141H9.14321V18.2855H4.57178Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
       <path d="M9.1438 18.2855V13.7141H13.7152V18.2855H9.1438Z" fill="currentColor" />
-      <path d="M13.7156 18.2855V13.7141H18.287V18.2855H13.7156Z" fill="currentColor" fill-opacity="0.2" />
+      <path
+        d="M13.7156 18.2855V13.7141H18.287V18.2855H13.7156Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
       <rect width="4.57143" height="4.57143" transform="translate(0 18.2859)" fill="currentColor" />
       <path d="M0 22.8572V18.2858H4.57143V22.8572H0Z" fill="currentColor" fill-opacity="0.2" />
       <rect
@@ -23,8 +36,16 @@ export function IconLogo(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
         fill-opacity="0.2"
       />
       <path d="M4.57178 22.8573V18.2859H9.14321V22.8573H4.57178Z" fill="currentColor" />
-      <path d="M9.1438 22.8573V18.2859H13.7152V22.8573H9.1438Z" fill="currentColor" fill-opacity="0.2" />
-      <path d="M13.7156 22.8573V18.2859H18.287V22.8573H13.7156Z" fill="currentColor" fill-opacity="0.2" />
+      <path
+        d="M9.1438 22.8573V18.2859H13.7152V22.8573H9.1438Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
+      <path
+        d="M13.7156 22.8573V18.2859H18.287V22.8573H13.7156Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
       <path d="M0 27.4292V22.8578H4.57143V27.4292H0Z" fill="currentColor" />
       <path d="M4.57178 27.4292V22.8578H9.14321V27.4292H4.57178Z" fill="currentColor" />
       <path d="M9.1438 27.4276V22.8562H13.7152V27.4276H9.1438Z" fill="currentColor" />
@@ -40,9 +61,21 @@ export function IconLogo(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
       <path d="M32.001 18.2855V13.7141H36.5724V18.2855H32.001Z" fill="currentColor" />
       <path d="M36.5698 18.2855V13.7141H41.1413V18.2855H36.5698Z" fill="currentColor" />
       <path d="M22.8572 22.8573V18.2859H27.4286V22.8573H22.8572Z" fill="currentColor" />
-      <path d="M27.4292 22.8573V18.2859H32.0006V22.8573H27.4292Z" fill="currentColor" fill-opacity="0.2" />
-      <path d="M32.001 22.8573V18.2859H36.5724V22.8573H32.001Z" fill="currentColor" fill-opacity="0.2" />
-      <path d="M36.5698 22.8573V18.2859H41.1413V22.8573H36.5698Z" fill="currentColor" fill-opacity="0.2" />
+      <path
+        d="M27.4292 22.8573V18.2859H32.0006V22.8573H27.4292Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
+      <path
+        d="M32.001 22.8573V18.2859H36.5724V22.8573H32.001Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
+      <path
+        d="M36.5698 22.8573V18.2859H41.1413V22.8573H36.5698Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
       <path d="M22.8572 27.4292V22.8578H27.4286V27.4292H22.8572Z" fill="currentColor" />
       <path d="M27.4292 27.4276V22.8562H32.0006V27.4276H27.4292Z" fill="currentColor" />
       <path d="M32.001 27.4276V22.8562H36.5724V27.4276H32.001Z" fill="currentColor" />
@@ -53,16 +86,40 @@ export function IconLogo(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
       <path d="M45.7144 13.7136V9.14221H50.2858V13.7136H45.7144Z" fill="currentColor" />
       <path d="M59.4299 13.7152V9.1438H64.0014V13.7152H59.4299Z" fill="currentColor" />
       <path d="M45.7144 18.2855V13.7141H50.2858V18.2855H45.7144Z" fill="currentColor" />
-      <path d="M50.2861 18.2857V13.7142H54.8576V18.2857H50.2861Z" fill="currentColor" fill-opacity="0.2" />
-      <path d="M54.8579 18.2855V13.7141H59.4293V18.2855H54.8579Z" fill="currentColor" fill-opacity="0.2" />
+      <path
+        d="M50.2861 18.2857V13.7142H54.8576V18.2857H50.2861Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
+      <path
+        d="M54.8579 18.2855V13.7141H59.4293V18.2855H54.8579Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
       <path d="M59.4299 18.2855V13.7141H64.0014V18.2855H59.4299Z" fill="currentColor" />
       <path d="M45.7144 22.8573V18.2859H50.2858V22.8573H45.7144Z" fill="currentColor" />
-      <path d="M50.2861 22.8572V18.2858H54.8576V22.8572H50.2861Z" fill="currentColor" fill-opacity="0.2" />
-      <path d="M54.8579 22.8573V18.2859H59.4293V22.8573H54.8579Z" fill="currentColor" fill-opacity="0.2" />
+      <path
+        d="M50.2861 22.8572V18.2858H54.8576V22.8572H50.2861Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
+      <path
+        d="M54.8579 22.8573V18.2859H59.4293V22.8573H54.8579Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
       <path d="M59.4299 22.8573V18.2859H64.0014V22.8573H59.4299Z" fill="currentColor" />
       <path d="M45.7144 27.4292V22.8578H50.2858V27.4292H45.7144Z" fill="currentColor" />
-      <path d="M50.2861 27.4286V22.8572H54.8576V27.4286H50.2861Z" fill="currentColor" fill-opacity="0.2" />
-      <path d="M54.8579 27.4285V22.8571H59.4293V27.4285H54.8579Z" fill="currentColor" fill-opacity="0.2" />
+      <path
+        d="M50.2861 27.4286V22.8572H54.8576V27.4286H50.2861Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
+      <path
+        d="M54.8579 27.4285V22.8571H59.4293V27.4285H54.8579Z"
+        fill="currentColor"
+        fill-opacity="0.2"
+      />
       <path d="M59.4299 27.4292V22.8578H64.0014V27.4292H59.4299Z" fill="currentColor" />
     </svg>
   )
@@ -70,7 +127,14 @@ export function IconLogo(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
 
 export function IconCopy(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
   return (
-    <svg {...props} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <svg
+      {...props}
+      width="24"
+      height="24"
+      viewBox="0 0 24 24"
+      fill="none"
+      xmlns="http://www.w3.org/2000/svg"
+    >
       <path
         d="M8.75 8.75V2.75H21.25V15.25H15.25M15.25 8.75H2.75V21.25H15.25V8.75Z"
         stroke="currentColor"
@@ -83,8 +147,20 @@ export function IconCopy(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
 
 export function IconCheck(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
   return (
-    <svg {...props} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
-      <path d="M2.75 15.0938L9 20.25L21.25 3.75" stroke="#03B000" stroke-width="2" stroke-linecap="square" />
+    <svg
+      {...props}
+      width="24"
+      height="24"
+      viewBox="0 0 24 24"
+      fill="none"
+      xmlns="http://www.w3.org/2000/svg"
+    >
+      <path
+        d="M2.75 15.0938L9 20.25L21.25 3.75"
+        stroke="#03B000"
+        stroke-width="2"
+        stroke-linecap="square"
+      />
     </svg>
   )
 }
@@ -113,7 +189,14 @@ export function IconStripe(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
 
 export function IconChevron(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
   return (
-    <svg {...props} width="8" height="6" viewBox="0 0 8 6" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <svg
+      {...props}
+      width="8"
+      height="6"
+      viewBox="0 0 8 6"
+      fill="none"
+      xmlns="http://www.w3.org/2000/svg"
+    >
       <path
         fill="currentColor"
         d="M4.00024 5.04041L7.37401 1.66663L6.66691 0.959525L4.00024 3.62619L1.33357 0.959525L0.626465 1.66663L4.00024 5.04041Z"
@@ -124,7 +207,14 @@ export function IconChevron(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
 
 export function IconWorkspaceLogo(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
   return (
-    <svg {...props} width="24" height="30" viewBox="0 0 24 30" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <svg
+      {...props}
+      width="24"
+      height="30"
+      viewBox="0 0 24 30"
+      fill="none"
+      xmlns="http://www.w3.org/2000/svg"
+    >
       <path d="M18 6H6V24H18V6ZM24 30H0V0H24V30Z" fill="currentColor" />
     </svg>
   )
@@ -144,7 +234,10 @@ export function IconOpenAI(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
 export function IconAnthropic(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
   return (
     <svg {...props} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
-      <path fill="currentColor" d="M13.7891 3.93188L20.2223 20.068H23.7502L17.317 3.93188H13.7891Z" />
+      <path
+        fill="currentColor"
+        d="M13.7891 3.93188L20.2223 20.068H23.7502L17.317 3.93188H13.7891Z"
+      />
       <path
         fill="currentColor"
         d="M6.32538 13.6827L8.52662 8.01201L10.7279 13.6827H6.32538ZM6.68225 3.93188L0.25 20.068H3.84652L5.16202 16.6794H11.8914L13.2067 20.068H16.8033L10.371 3.93188H6.68225Z"

+ 1 - 1
packages/console/app/src/component/modal.css

@@ -63,4 +63,4 @@
     font-weight: 600;
     color: var(--color-text);
   }
-}
+}

+ 4 - 1
packages/console/app/src/routes/auth/authorize.ts

@@ -2,6 +2,9 @@ import type { APIEvent } from "@solidjs/start/server"
 import { AuthClient } from "~/context/auth"
 
 export async function GET(input: APIEvent) {
-  const result = await AuthClient.authorize(new URL("./callback", input.request.url).toString(), "code")
+  const result = await AuthClient.authorize(
+    new URL("./callback", input.request.url).toString(),
+    "code",
+  )
   return Response.redirect(result.url, 302)
 }

+ 4 - 7
packages/console/app/src/routes/brand/index.css

@@ -299,7 +299,6 @@
       transition: all 0.2s ease;
       text-decoration: none;
 
-
       &:hover:not(:disabled) {
         background: var(--color-background-strong-hover);
       }
@@ -385,23 +384,21 @@
         0 1px 2px -1px rgba(19, 16, 16, 0.12);
 
       @media (max-width: 40rem) {
-        box-shadow:
-          0 0 0 1px rgba(19, 16, 16, 0.16)
+        box-shadow: 0 0 0 1px rgba(19, 16, 16, 0.16);
       }
 
-
       &:hover {
         background: var(--color-background);
       }
 
       &:active {
         transform: scale(0.98);
-        box-shadow: 0 0 0 1px rgba(19, 16, 16, 0.08), 0 6px 8px -8px rgba(19, 16, 16, 0.50);
+        box-shadow:
+          0 0 0 1px rgba(19, 16, 16, 0.08),
+          0 6px 8px -8px rgba(19, 16, 16, 0.5);
       }
     }
 
-
-
     @media (max-width: 60rem) {
       padding: 2rem 1.5rem;
     }

+ 1 - 1
packages/console/app/src/routes/user-menu.css

@@ -14,4 +14,4 @@
       color: var(--color-danger);
     }
   }
-}
+}

+ 1 - 1
packages/console/app/src/routes/workspace-picker.css

@@ -71,4 +71,4 @@
       color: var(--color-text-muted);
     }
   }
-}
+}

+ 9 - 2
packages/console/app/src/routes/workspace-picker.tsx

@@ -85,7 +85,10 @@ export function WorkspacePicker() {
       <Dropdown trigger={currentWorkspace()} align="left">
         <For each={workspaces()}>
           {(workspace) => (
-            <DropdownItem selected={workspace.id === params.id} onClick={() => handleSelectWorkspace(workspace.id)}>
+            <DropdownItem
+              selected={workspace.id === params.id}
+              onClick={() => handleSelectWorkspace(workspace.id)}
+            >
               {workspace.name || workspace.slug}
             </DropdownItem>
           )}
@@ -95,7 +98,11 @@ export function WorkspacePicker() {
         </button>
       </Dropdown>
 
-      <Modal open={store.showForm} onClose={() => setStore("showForm", false)} title="Create New Workspace">
+      <Modal
+        open={store.showForm}
+        onClose={() => setStore("showForm", false)}
+        title="Create New Workspace"
+      >
         <form data-slot="create-form" action={createWorkspace} method="post">
           <div data-slot="create-input-group">
             <input

+ 1 - 1
packages/console/app/src/routes/workspace.css

@@ -104,4 +104,4 @@
       }
     }
   }
-}
+}

+ 1 - 1
packages/console/app/src/routes/workspace/[id]/billing/billing-section.module.css

@@ -182,4 +182,4 @@
     padding: var(--space-4);
     min-width: 150px;
   }
-}
+}

+ 1 - 1
packages/console/app/src/routes/workspace/[id]/billing/monthly-limit-section.module.css

@@ -93,4 +93,4 @@
     margin: 0;
     line-height: 1.4;
   }
-}
+}

+ 4 - 1
packages/console/app/src/routes/workspace/[id]/billing/payment-section.tsx

@@ -89,7 +89,10 @@ export function PaymentSection() {
                       <td data-slot="payment-receipt">
                         <button
                           onClick={async () => {
-                            const receiptUrl = await downloadReceiptAction(params.id, payment.paymentID!)
+                            const receiptUrl = await downloadReceiptAction(
+                              params.id,
+                              payment.paymentID!,
+                            )
                             if (receiptUrl) {
                               window.open(receiptUrl, "_blank")
                             }

+ 0 - 1
packages/console/app/src/routes/workspace/[id]/billing/reload-section.module.css

@@ -259,4 +259,3 @@
     }
   }
 }
-

+ 3 - 6
packages/console/app/src/routes/workspace/[id]/keys/key-section.module.css

@@ -171,7 +171,6 @@
     }
 
     @media (max-width: 40rem) {
-
       th,
       td {
         padding: var(--space-2) var(--space-3);
@@ -181,8 +180,7 @@
       th {
         &:nth-child(3)
 
-        /* Date */
-          {
+        /* Date */ {
           display: none;
         }
       }
@@ -190,11 +188,10 @@
       td {
         &:nth-child(3)
 
-        /* Date */
-          {
+        /* Date */ {
           display: none;
         }
       }
     }
   }
-}
+}

+ 8 - 2
packages/console/app/src/routes/workspace/[id]/keys/key-section.tsx

@@ -146,14 +146,20 @@ export function KeySection() {
                             title="Copy API key"
                           >
                             <span>{key.keyDisplay}</span>
-                            <Show when={copied()} fallback={<IconCopy style={{ width: "14px", height: "14px" }} />}>
+                            <Show
+                              when={copied()}
+                              fallback={<IconCopy style={{ width: "14px", height: "14px" }} />}
+                            >
                               <IconCheck style={{ width: "14px", height: "14px" }} />
                             </Show>
                           </button>
                         </Show>
                       </td>
                       <td data-slot="key-user-email">{key.email}</td>
-                      <td data-slot="key-last-used" title={key.timeUsed ? formatDateUTC(key.timeUsed) : undefined}>
+                      <td
+                        data-slot="key-last-used"
+                        title={key.timeUsed ? formatDateUTC(key.timeUsed) : undefined}
+                      >
                         {key.timeUsed ? formatDateForTable(key.timeUsed) : "-"}
                       </td>
                       <td data-slot="key-actions">

+ 6 - 1
packages/console/app/src/routes/workspace/[id]/members/member-section.tsx

@@ -85,7 +85,12 @@ const updateMember = action(async (form: FormData) => {
   )
 }, "member.update")
 
-function MemberRow(props: { member: any; workspaceID: string; actorID: string; actorRole: string }) {
+function MemberRow(props: {
+  member: any
+  workspaceID: string
+  actorID: string
+  actorRole: string
+}) {
   const submission = useSubmission(updateMember)
   const isCurrentUser = () => props.actorID === props.member.id
   const isAdmin = () => props.actorRole === "admin"

+ 1 - 1
packages/console/app/src/routes/workspace/[id]/members/role-dropdown.css

@@ -69,4 +69,4 @@
       }
     }
   }
-}
+}

+ 1 - 1
packages/console/app/src/routes/workspace/[id]/new-user-section.module.css

@@ -140,4 +140,4 @@
       }
     }
   }
-}
+}

+ 12 - 3
packages/console/app/src/routes/workspace/[id]/new-user-section.tsx

@@ -43,15 +43,24 @@ export function NewUserSection() {
         <div data-component="feature-grid">
           <div data-slot="feature">
             <h3>Tested & Verified Models</h3>
-            <p>We've benchmarked and tested models specifically for coding agents to ensure the best performance.</p>
+            <p>
+              We've benchmarked and tested models specifically for coding agents to ensure the best
+              performance.
+            </p>
           </div>
           <div data-slot="feature">
             <h3>Highest Quality</h3>
-            <p>Access models configured for optimal performance - no downgrades or routing to cheaper providers.</p>
+            <p>
+              Access models configured for optimal performance - no downgrades or routing to cheaper
+              providers.
+            </p>
           </div>
           <div data-slot="feature">
             <h3>No Lock-in</h3>
-            <p>Use Zen with any coding agent, and continue using other providers with opencode whenever you want.</p>
+            <p>
+              Use Zen with any coding agent, and continue using other providers with opencode
+              whenever you want.
+            </p>
           </div>
         </div>
 

+ 1 - 2
packages/console/app/src/routes/workspace/[id]/provider-section.module.css

@@ -128,7 +128,6 @@
     }
 
     @media (max-width: 40rem) {
-
       th,
       td {
         padding: var(--space-2) var(--space-3);
@@ -136,4 +135,4 @@
       }
     }
   }
-}
+}

+ 16 - 4
packages/console/app/src/routes/workspace/[id]/provider-section.tsx

@@ -22,7 +22,9 @@ const removeProvider = action(async (form: FormData) => {
   if (!provider) return { error: "Provider is required" }
   const workspaceID = form.get("workspaceID")?.toString()
   if (!workspaceID) return { error: "Workspace ID is required" }
-  return json(await withActor(() => Provider.remove({ provider }), workspaceID), { revalidate: listProviders.key })
+  return json(await withActor(() => Provider.remove({ provider }), workspaceID), {
+    revalidate: listProviders.key,
+  })
 }, "provider.remove")
 
 const saveProvider = action(async (form: FormData) => {
@@ -53,7 +55,10 @@ const listProviders = query(async (workspaceID: string) => {
 function ProviderRow(props: { provider: Provider }) {
   const params = useParams()
   const providers = createAsync(() => listProviders(params.id))
-  const saveSubmission = useSubmission(saveProvider, ([fd]) => fd.get("provider")?.toString() === props.provider.key)
+  const saveSubmission = useSubmission(
+    saveProvider,
+    ([fd]) => fd.get("provider")?.toString() === props.provider.key,
+  )
   const removeSubmission = useSubmission(
     removeProvider,
     ([fd]) => fd.get("provider")?.toString() === props.provider.key,
@@ -89,9 +94,16 @@ function ProviderRow(props: { provider: Provider }) {
       <td data-slot="provider-key">
         <Show
           when={store.editing}
-          fallback={<span>{providerData() ? maskCredentials(providerData()!.credentials) : "-"}</span>}
+          fallback={
+            <span>{providerData() ? maskCredentials(providerData()!.credentials) : "-"}</span>
+          }
         >
-          <form id={`provider-form-${props.provider.key}`} action={saveProvider} method="post" data-slot="edit-form">
+          <form
+            id={`provider-form-${props.provider.key}`}
+            action={saveProvider}
+            method="post"
+            data-slot="edit-form"
+          >
             <div data-slot="input-wrapper">
               <input
                 ref={(r) => (input = r)}

+ 3 - 3
packages/console/app/src/routes/workspace/[id]/settings/settings-section.module.css

@@ -31,7 +31,7 @@
       margin: 0;
     }
 
-    >button {
+    > button {
       align-self: flex-start;
     }
   }
@@ -80,7 +80,7 @@
       }
     }
 
-    >button[type="reset"] {
+    > button[type="reset"] {
       align-self: flex-start;
     }
 
@@ -91,4 +91,4 @@
       margin-top: calc(var(--space-1) * -1);
     }
   }
-}
+}

+ 96 - 36
packages/console/app/src/routes/zen/index.tsx

@@ -28,7 +28,10 @@ export default function Home() {
   createAsync(() => checkLoggedIn())
   return (
     <main data-page="zen">
-      <HttpHeader name="Cache-Control" value="public, max-age=1, s-maxage=3600, stale-while-revalidate=86400" />
+      <HttpHeader
+        name="Cache-Control"
+        value="public, max-age=1, s-maxage=3600, stale-while-revalidate=86400"
+      />
       <Title>OpenCode Zen | A curated set of reliable optimized models for coding agents</Title>
       <Link rel="icon" type="image/svg+xml" href="/favicon-zen.svg" />
       <Meta property="og:image" content="/social-share-zen.png" />
@@ -44,13 +47,19 @@ export default function Home() {
               <img data-slot="zen logo dark" src={zenLogoDark} alt="zen logo dark" />
               <strong>Reliable optimized models for coding agents</strong>
               <p>
-                Zen gives you access to a curated set of AI models that OpenCode has tested and benchmarked specifically
-                for coding agents. No need to worry about inconsistent performance and quality, use validated models
-                that work.
+                Zen gives you access to a curated set of AI models that OpenCode has tested and
+                benchmarked specifically for coding agents. No need to worry about inconsistent
+                performance and quality, use validated models that work.
               </p>
               <div data-slot="model-logos">
                 <div>
-                  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <svg
+                    width="24"
+                    height="24"
+                    viewBox="0 0 24 24"
+                    fill="none"
+                    xmlns="http://www.w3.org/2000/svg"
+                  >
                     <mask
                       id="mask0_79_128586"
                       style="mask-type:luminance"
@@ -71,8 +80,17 @@ export default function Home() {
                   </svg>
                 </div>
                 <div>
-                  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
-                    <path d="M13.7891 3.93164L20.2223 20.0677H23.7502L17.317 3.93164H13.7891Z" fill="currentColor" />
+                  <svg
+                    width="24"
+                    height="24"
+                    viewBox="0 0 24 24"
+                    fill="none"
+                    xmlns="http://www.w3.org/2000/svg"
+                  >
+                    <path
+                      d="M13.7891 3.93164L20.2223 20.0677H23.7502L17.317 3.93164H13.7891Z"
+                      fill="currentColor"
+                    />
                     <path
                       d="M6.32538 13.6824L8.52662 8.01177L10.7279 13.6824H6.32538ZM6.68225 3.93164L0.25 20.0677H3.84652L5.16202 16.6791H11.8914L13.2067 20.0677H16.8033L10.371 3.93164H6.68225Z"
                       fill="currentColor"
@@ -80,7 +98,13 @@ export default function Home() {
                   </svg>
                 </div>
                 <div>
-                  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <svg
+                    width="24"
+                    height="24"
+                    viewBox="0 0 24 24"
+                    fill="none"
+                    xmlns="http://www.w3.org/2000/svg"
+                  >
                     <path
                       d="M9.16861 16.0529L17.2018 9.85156C17.5957 9.54755 18.1586 9.66612 18.3463 10.1384C19.3339 12.6288 18.8926 15.6217 16.9276 17.6766C14.9626 19.7314 12.2285 20.1821 9.72948 19.1557L6.9995 20.4775C10.9151 23.2763 15.6699 22.5841 18.6411 19.4749C20.9979 17.0103 21.7278 13.6508 21.0453 10.6214L21.0515 10.6278C20.0617 6.17736 21.2948 4.39847 23.8207 0.760904C23.8804 0.674655 23.9402 0.588405 24 0.5L20.6762 3.97585V3.96506L9.16658 16.0551"
                       fill="currentColor"
@@ -92,7 +116,13 @@ export default function Home() {
                   </svg>
                 </div>
                 <div>
-                  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <svg
+                    width="24"
+                    height="24"
+                    viewBox="0 0 24 24"
+                    fill="none"
+                    xmlns="http://www.w3.org/2000/svg"
+                  >
                     <path
                       fill-rule="evenodd"
                       clip-rule="evenodd"
@@ -102,7 +132,13 @@ export default function Home() {
                   </svg>
                 </div>
                 <div>
-                  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <svg
+                    width="24"
+                    height="24"
+                    viewBox="0 0 24 24"
+                    fill="none"
+                    xmlns="http://www.w3.org/2000/svg"
+                  >
                     <path
                       d="M12.6241 11.346L20.3848 3.44816C20.5309 3.29931 20.4487 3 20.2601 3H16.0842C16.0388 3 15.9949 3.01897 15.9594 3.05541L7.59764 11.5629C7.46721 11.6944 7.27446 11.5771 7.27446 11.3666V3.25183C7.27446 3.11242 7.18515 3 7.07594 3H4.19843C4.08932 3 4 3.11242 4 3.25183V20.7482C4 20.8876 4.08932 21 4.19843 21H7.07594C7.18515 21 7.27446 20.8876 7.27446 20.7482V17.1834C7.27446 17.1073 7.30136 17.0344 7.34815 16.987L9.94075 14.3486C10.0031 14.2853 10.0895 14.2757 10.159 14.3232L17.0934 19.5573C18.2289 20.3412 19.4975 20.8226 20.786 20.9652C20.9008 20.9778 21 20.8606 21 20.7133V17.3559C21 17.2276 20.9249 17.1232 20.8243 17.1073C20.0659 16.9853 19.326 16.6845 18.6569 16.222L12.6538 11.764C12.5291 11.6785 12.5135 11.4584 12.6241 11.346Z"
                       fill="currentColor"
@@ -112,7 +148,13 @@ export default function Home() {
               </div>
               <a href="/auth">
                 <span>Get started with Zen </span>
-                <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+                <svg
+                  width="24"
+                  height="24"
+                  viewBox="0 0 24 24"
+                  fill="none"
+                  xmlns="http://www.w3.org/2000/svg"
+                >
                   <path
                     d="M6.5 12L17 12M13 16.5L17.5 12L13 7.5"
                     stroke="currentColor"
@@ -124,14 +166,23 @@ export default function Home() {
             </div>
             <div data-slot="pricing-copy">
               <p>
-                <strong>Add $20 Pay as you go balance</strong> <span>(+$1.23 card processing fee)</span>
+                <strong>Add $20 Pay as you go balance</strong>{" "}
+                <span>(+$1.23 card processing fee)</span>
               </p>
               <p>Use with any agent. Set monthly spend limits. Cancel any time.</p>
             </div>
           </section>
 
           <section data-component="comparison">
-            <video src={compareVideo} autoplay playsinline loop muted preload="auto" poster={compareVideoPoster}>
+            <video
+              src={compareVideo}
+              autoplay
+              playsinline
+              loop
+              muted
+              preload="auto"
+              poster={compareVideoPoster}
+            >
               Your browser does not support the video tag.
             </video>
           </section>
@@ -140,8 +191,8 @@ export default function Home() {
             <div data-slot="section-title">
               <h3>What problem is Zen solving?</h3>
               <p>
-                There are so many models available, but only a few work well with coding agents. Most providers
-                configure them differently with varying results.
+                There are so many models available, but only a few work well with coding agents.
+                Most providers configure them differently with varying results.
               </p>
             </div>
             <p>We're fixing this for everyone, not just OpenCode users.</p>
@@ -176,14 +227,15 @@ export default function Home() {
               <li>
                 <span>[2]</span>
                 <div>
-                  <strong>Use Zen with transparent pricing</strong> - <a href="/docs/zen/#pricing">pay per request</a>{" "}
-                  with zero markups
+                  <strong>Use Zen with transparent pricing</strong> -{" "}
+                  <a href="/docs/zen/#pricing">pay per request</a> with zero markups
                 </div>
               </li>
               <li>
                 <span>[3]</span>
                 <div>
-                  <strong>Auto-top up</strong> - when your balance reaches $5 we’ll automatically add $20
+                  <strong>Auto-top up</strong> - when your balance reaches $5 we’ll automatically
+                  add $20
                 </div>
               </li>
             </ul>
@@ -195,8 +247,9 @@ export default function Home() {
               <div>
                 <span>[*]</span>
                 <p>
-                  All Zen models are hosted in the US. Providers follow a zero-retention policy and do not use your data
-                  for model training, with the <a href="/docs/zen/#privacy">following exceptions</a>.
+                  All Zen models are hosted in the US. Providers follow a zero-retention policy and
+                  do not use your data for model training, with the{" "}
+                  <a href="/docs/zen/#privacy">following exceptions</a>.
                 </p>
               </div>
             </div>
@@ -251,7 +304,8 @@ export default function Home() {
                   <span>ex-Head of Design, Laravel</span>
                 </div>
                 <div data-slot="quote">
-                  With <span>@OpenCode</span> Zen I know all the models are tested and perfect for coding agents.
+                  With <span>@OpenCode</span> Zen I know all the models are tested and perfect for
+                  coding agents.
                 </div>
               </div>
             </a>
@@ -275,38 +329,44 @@ export default function Home() {
             <ul>
               <li>
                 <Faq question="What is OpenCode Zen?">
-                  Zen is a curated set of AI models tested and benchmarked for coding agents created by the team behind
-                  OpenCode.
+                  Zen is a curated set of AI models tested and benchmarked for coding agents created
+                  by the team behind OpenCode.
                 </Faq>
               </li>
               <li>
                 <Faq question="What makes Zen more accurate?">
-                  Zen only provides models that have been specifically tested and benchmarked for coding agents. You
-                  wouldn’t use a butter knife to cut steak, don’t use poor models for coding.
+                  Zen only provides models that have been specifically tested and benchmarked for
+                  coding agents. You wouldn’t use a butter knife to cut steak, don’t use poor models
+                  for coding.
                 </Faq>
               </li>
               <li>
                 <Faq question="Is Zen cheaper?">
-                  Zen is not for profit. Zen passes through the costs from the model providers to you. The higher Zen’s
-                  usage the more OpenCode can negotiate better rates and pass those to you.
+                  Zen is not for profit. Zen passes through the costs from the model providers to
+                  you. The higher Zen’s usage the more OpenCode can negotiate better rates and pass
+                  those to you.
                 </Faq>
               </li>
               <li>
                 <Faq question="How much does Zen cost?">
-                  Zen <a href="/docs/zen/#pricing">charges per request</a> with zero markups, so you pay exactly what
-                  the model provider charges. Your total cost depends on usage, and you can set monthly spend limits in
-                  your <a href="/auth">account</a>. To cover costs, OpenCode adds only a small payment processing fee of
-                  $1.23 per $20 balance top-up.
+                  Zen <a href="/docs/zen/#pricing">charges per request</a> with zero markups, so you
+                  pay exactly what the model provider charges. Your total cost depends on usage, and
+                  you can set monthly spend limits in your <a href="/auth">account</a>. To cover
+                  costs, OpenCode adds only a small payment processing fee of $1.23 per $20 balance
+                  top-up.
                 </Faq>
               </li>
               <li>
                 <Faq question="What about data and privacy?">
-                  All Zen models are hosted in the US. Providers follow a zero-retention policy and do not use your data
-                  for model training, with the <a href="/docs/zen/#privacy">following exceptions</a>.
+                  All Zen models are hosted in the US. Providers follow a zero-retention policy and
+                  do not use your data for model training, with the{" "}
+                  <a href="/docs/zen/#privacy">following exceptions</a>.
                 </Faq>
               </li>
               <li>
-                <Faq question="Can I set spend limits?">Yes, you can set monthly spending limits in your account.</Faq>
+                <Faq question="Can I set spend limits?">
+                  Yes, you can set monthly spending limits in your account.
+                </Faq>
               </li>
               <li>
                 <Faq question="Can I cancel?">
@@ -315,8 +375,8 @@ export default function Home() {
               </li>
               <li>
                 <Faq question="Can I use Zen with other coding agents?">
-                  While Zen works great with OpenCode, you can use Zen with any agent. Follow the setup instructions in
-                  your preferred coding agent.
+                  While Zen works great with OpenCode, you can use Zen with any agent. Follow the
+                  setup instructions in your preferred coding agent.
                 </Faq>
               </li>
             </ul>

+ 48 - 13
packages/console/app/src/routes/zen/util/provider/anthropic.ts

@@ -98,7 +98,10 @@ export function fromAnthropicRequest(body: any): CommonRequest {
       typeof (src as any).media_type === "string" &&
       typeof (src as any).data === "string"
     )
-      return { type: "image_url", image_url: { url: `data:${(src as any).media_type};base64,${(src as any).data}` } }
+      return {
+        type: "image_url",
+        image_url: { url: `data:${(src as any).media_type};base64,${(src as any).data}` },
+      }
     return undefined
   }
 
@@ -120,12 +123,15 @@ export function fromAnthropicRequest(body: any): CommonRequest {
         if ((p as any).type === "tool_result") {
           const id = (p as any).tool_use_id
           const content =
-            typeof (p as any).content === "string" ? (p as any).content : JSON.stringify((p as any).content)
+            typeof (p as any).content === "string"
+              ? (p as any).content
+              : JSON.stringify((p as any).content)
           msgs.push({ role: "tool", tool_call_id: id, content })
         }
       }
       if (partsOut.length > 0) {
-        if (partsOut.length === 1 && partsOut[0].type === "text") msgs.push({ role: "user", content: partsOut[0].text })
+        if (partsOut.length === 1 && partsOut[0].type === "text")
+          msgs.push({ role: "user", content: partsOut[0].text })
         else msgs.push({ role: "user", content: partsOut })
       }
       continue
@@ -137,7 +143,8 @@ export function fromAnthropicRequest(body: any): CommonRequest {
       const tcs: any[] = []
       for (const p of partsIn) {
         if (!p || !(p as any).type) continue
-        if ((p as any).type === "text" && typeof (p as any).text === "string") texts.push((p as any).text)
+        if ((p as any).type === "text" && typeof (p as any).text === "string")
+          texts.push((p as any).text)
         if ((p as any).type === "tool_use") {
           const name = (p as any).name
           const id = (p as any).id
@@ -165,7 +172,11 @@ export function fromAnthropicRequest(body: any): CommonRequest {
         .filter((t: any) => t && typeof t === "object" && "input_schema" in t)
         .map((t: any) => ({
           type: "function",
-          function: { name: (t as any).name, description: (t as any).description, parameters: (t as any).input_schema },
+          function: {
+            name: (t as any).name,
+            description: (t as any).description,
+            parameters: (t as any).input_schema,
+          },
         }))
     : undefined
 
@@ -203,7 +214,9 @@ export function fromAnthropicRequest(body: any): CommonRequest {
 export function toAnthropicRequest(body: CommonRequest) {
   if (!body || typeof body !== "object") return body
 
-  const sysIn = Array.isArray(body.messages) ? body.messages.filter((m: any) => m && m.role === "system") : []
+  const sysIn = Array.isArray(body.messages)
+    ? body.messages.filter((m: any) => m && m.role === "system")
+    : []
   let ccCount = 0
   const cc = () => {
     ccCount++
@@ -354,7 +367,9 @@ export function fromAnthropicResponse(resp: any): CommonResponse {
 
   const idIn = (resp as any).id
   const id =
-    typeof idIn === "string" ? idIn.replace(/^msg_/, "chatcmpl_") : `chatcmpl_${Math.random().toString(36).slice(2)}`
+    typeof idIn === "string"
+      ? idIn.replace(/^msg_/, "chatcmpl_")
+      : `chatcmpl_${Math.random().toString(36).slice(2)}`
   const model = (resp as any).model
 
   const blocks: any[] = Array.isArray((resp as any).content) ? (resp as any).content : []
@@ -397,7 +412,9 @@ export function fromAnthropicResponse(resp: any): CommonResponse {
     const ct = typeof (u as any).output_tokens === "number" ? (u as any).output_tokens : undefined
     const total = pt != null && ct != null ? pt + ct : undefined
     const cached =
-      typeof (u as any).cache_read_input_tokens === "number" ? (u as any).cache_read_input_tokens : undefined
+      typeof (u as any).cache_read_input_tokens === "number"
+        ? (u as any).cache_read_input_tokens
+        : undefined
     const details = cached != null ? { cached_tokens: cached } : undefined
     return {
       prompt_tokens: pt,
@@ -452,7 +469,12 @@ export function toAnthropicResponse(resp: CommonResponse) {
         } catch {
           input = (tc as any).function.arguments
         }
-        content.push({ type: "tool_use", id: (tc as any).id, name: (tc as any).function.name, input })
+        content.push({
+          type: "tool_use",
+          id: (tc as any).id,
+          name: (tc as any).function.name,
+          input,
+        })
       }
     }
   }
@@ -511,13 +533,22 @@ export function fromAnthropicChunk(chunk: string): CommonChunk | string {
   if (json.type === "content_block_start") {
     const cb = json.content_block
     if (cb?.type === "text") {
-      out.choices.push({ index: json.index ?? 0, delta: { role: "assistant", content: "" }, finish_reason: null })
+      out.choices.push({
+        index: json.index ?? 0,
+        delta: { role: "assistant", content: "" },
+        finish_reason: null,
+      })
     } else if (cb?.type === "tool_use") {
       out.choices.push({
         index: json.index ?? 0,
         delta: {
           tool_calls: [
-            { index: json.index ?? 0, id: cb.id, type: "function", function: { name: cb.name, arguments: "" } },
+            {
+              index: json.index ?? 0,
+              id: cb.id,
+              type: "function",
+              function: { name: cb.name, arguments: "" },
+            },
           ],
         },
         finish_reason: null,
@@ -532,7 +563,9 @@ export function fromAnthropicChunk(chunk: string): CommonChunk | string {
     } else if (d?.type === "input_json_delta") {
       out.choices.push({
         index: json.index ?? 0,
-        delta: { tool_calls: [{ index: json.index ?? 0, function: { arguments: d.partial_json } }] },
+        delta: {
+          tool_calls: [{ index: json.index ?? 0, function: { arguments: d.partial_json } }],
+        },
         finish_reason: null,
       })
     }
@@ -558,7 +591,9 @@ export function fromAnthropicChunk(chunk: string): CommonChunk | string {
       prompt_tokens: u.input_tokens,
       completion_tokens: u.output_tokens,
       total_tokens: (u.input_tokens || 0) + (u.output_tokens || 0),
-      ...(u.cache_read_input_tokens ? { prompt_tokens_details: { cached_tokens: u.cache_read_input_tokens } } : {}),
+      ...(u.cache_read_input_tokens
+        ? { prompt_tokens_details: { cached_tokens: u.cache_read_input_tokens } }
+        : {}),
     }
   }
 

+ 24 - 11
packages/console/app/src/routes/zen/util/provider/openai-compatible.ts

@@ -57,7 +57,8 @@ export const oaCompatHelper = {
     const inputTokens = usage.prompt_tokens ?? 0
     const outputTokens = usage.completion_tokens ?? 0
     const reasoningTokens = usage.completion_tokens_details?.reasoning_tokens ?? undefined
-    const cacheReadTokens = usage.cached_tokens ?? usage.prompt_tokens_details?.cached_tokens ?? undefined
+    const cacheReadTokens =
+      usage.cached_tokens ?? usage.prompt_tokens_details?.cached_tokens ?? undefined
     return {
       inputTokens: inputTokens - (cacheReadTokens ?? 0),
       outputTokens,
@@ -79,7 +80,8 @@ export function fromOaCompatibleRequest(body: any): CommonRequest {
     if (!m || !m.role) continue
 
     if (m.role === "system") {
-      if (typeof m.content === "string" && m.content.length > 0) msgsOut.push({ role: "system", content: m.content })
+      if (typeof m.content === "string" && m.content.length > 0)
+        msgsOut.push({ role: "system", content: m.content })
       continue
     }
 
@@ -90,10 +92,12 @@ export function fromOaCompatibleRequest(body: any): CommonRequest {
         const parts: any[] = []
         for (const p of m.content) {
           if (!p || !p.type) continue
-          if (p.type === "text" && typeof p.text === "string") parts.push({ type: "text", text: p.text })
+          if (p.type === "text" && typeof p.text === "string")
+            parts.push({ type: "text", text: p.text })
           if (p.type === "image_url") parts.push({ type: "image_url", image_url: p.image_url })
         }
-        if (parts.length === 1 && parts[0].type === "text") msgsOut.push({ role: "user", content: parts[0].text })
+        if (parts.length === 1 && parts[0].type === "text")
+          msgsOut.push({ role: "user", content: parts[0].text })
         else if (parts.length > 0) msgsOut.push({ role: "user", content: parts })
       }
       continue
@@ -137,7 +141,8 @@ export function toOaCompatibleRequest(body: CommonRequest) {
     if (p.type === "image_url" && p.image_url) return { type: "image_url", image_url: p.image_url }
     const s = (p as any).source
     if (!s || typeof s !== "object") return undefined
-    if (s.type === "url" && typeof s.url === "string") return { type: "image_url", image_url: { url: s.url } }
+    if (s.type === "url" && typeof s.url === "string")
+      return { type: "image_url", image_url: { url: s.url } }
     if (s.type === "base64" && typeof s.media_type === "string" && typeof s.data === "string")
       return { type: "image_url", image_url: { url: `data:${s.media_type};base64,${s.data}` } }
     return undefined
@@ -147,7 +152,8 @@ export function toOaCompatibleRequest(body: CommonRequest) {
     if (!m || !m.role) continue
 
     if (m.role === "system") {
-      if (typeof m.content === "string" && m.content.length > 0) msgsOut.push({ role: "system", content: m.content })
+      if (typeof m.content === "string" && m.content.length > 0)
+        msgsOut.push({ role: "system", content: m.content })
       continue
     }
 
@@ -160,11 +166,13 @@ export function toOaCompatibleRequest(body: CommonRequest) {
         const parts: any[] = []
         for (const p of m.content) {
           if (!p || !p.type) continue
-          if (p.type === "text" && typeof p.text === "string") parts.push({ type: "text", text: p.text })
+          if (p.type === "text" && typeof p.text === "string")
+            parts.push({ type: "text", text: p.text })
           const ip = toImg(p)
           if (ip) parts.push(ip)
         }
-        if (parts.length === 1 && parts[0].type === "text") msgsOut.push({ role: "user", content: parts[0].text })
+        if (parts.length === 1 && parts[0].type === "text")
+          msgsOut.push({ role: "user", content: parts[0].text })
         else if (parts.length > 0) msgsOut.push({ role: "user", content: parts })
       }
       continue
@@ -317,7 +325,9 @@ export function toOaCompatibleResponse(resp: CommonResponse) {
 
   const idIn = (resp as any).id
   const id =
-    typeof idIn === "string" ? idIn.replace(/^msg_/, "chatcmpl_") : `chatcmpl_${Math.random().toString(36).slice(2)}`
+    typeof idIn === "string"
+      ? idIn.replace(/^msg_/, "chatcmpl_")
+      : `chatcmpl_${Math.random().toString(36).slice(2)}`
   const model = (resp as any).model
 
   const blocks: any[] = Array.isArray((resp as any).content) ? (resp as any).content : []
@@ -359,7 +369,8 @@ export function toOaCompatibleResponse(resp: CommonResponse) {
     const pt = typeof u.input_tokens === "number" ? u.input_tokens : undefined
     const ct = typeof u.output_tokens === "number" ? u.output_tokens : undefined
     const total = pt != null && ct != null ? pt + ct : undefined
-    const cached = typeof u.cache_read_input_tokens === "number" ? u.cache_read_input_tokens : undefined
+    const cached =
+      typeof u.cache_read_input_tokens === "number" ? u.cache_read_input_tokens : undefined
     const details = cached != null ? { cached_tokens: cached } : undefined
     return {
       prompt_tokens: pt,
@@ -532,7 +543,9 @@ export function toOaCompatibleChunk(chunk: CommonChunk): string {
       total_tokens: chunk.usage.total_tokens,
       ...(chunk.usage.prompt_tokens_details?.cached_tokens
         ? {
-            prompt_tokens_details: { cached_tokens: chunk.usage.prompt_tokens_details.cached_tokens },
+            prompt_tokens_details: {
+              cached_tokens: chunk.usage.prompt_tokens_details.cached_tokens,
+            },
           }
         : {}),
     }

+ 63 - 16
packages/console/app/src/routes/zen/util/provider/openai.ts

@@ -77,13 +77,20 @@ export function fromOpenaiRequest(body: any): CommonRequest {
       typeof (s as any).media_type === "string" &&
       typeof (s as any).data === "string"
     )
-      return { type: "image_url", image_url: { url: `data:${(s as any).media_type};base64,${(s as any).data}` } }
+      return {
+        type: "image_url",
+        image_url: { url: `data:${(s as any).media_type};base64,${(s as any).data}` },
+      }
     return undefined
   }
 
   const msgs: any[] = []
 
-  const inMsgs = Array.isArray(body.input) ? body.input : Array.isArray(body.messages) ? body.messages : []
+  const inMsgs = Array.isArray(body.input)
+    ? body.input
+    : Array.isArray(body.messages)
+      ? body.messages
+      : []
 
   for (const m of inMsgs) {
     if (!m) continue
@@ -96,7 +103,9 @@ export function fromOpenaiRequest(body: any): CommonRequest {
         const args = typeof a === "string" ? a : JSON.stringify(a ?? {})
         msgs.push({
           role: "assistant",
-          tool_calls: [{ id: (m as any).id, type: "function", function: { name, arguments: args } }],
+          tool_calls: [
+            { id: (m as any).id, type: "function", function: { name, arguments: args } },
+          ],
         })
       }
       if ((m as any).type === "function_call_output") {
@@ -113,7 +122,8 @@ export function fromOpenaiRequest(body: any): CommonRequest {
       if (typeof c === "string" && c.length > 0) msgs.push({ role: "system", content: c })
       if (Array.isArray(c)) {
         const t = c.find((p: any) => p && typeof p.text === "string")
-        if (t && typeof t.text === "string" && t.text.length > 0) msgs.push({ role: "system", content: t.text })
+        if (t && typeof t.text === "string" && t.text.length > 0)
+          msgs.push({ role: "system", content: t.text })
       }
       continue
     }
@@ -126,18 +136,24 @@ export function fromOpenaiRequest(body: any): CommonRequest {
         const parts: any[] = []
         for (const p of c) {
           if (!p || !(p as any).type) continue
-          if (((p as any).type === "text" || (p as any).type === "input_text") && typeof (p as any).text === "string")
+          if (
+            ((p as any).type === "text" || (p as any).type === "input_text") &&
+            typeof (p as any).text === "string"
+          )
             parts.push({ type: "text", text: (p as any).text })
           const ip = toImg(p)
           if (ip) parts.push(ip)
           if ((p as any).type === "tool_result") {
             const id = (p as any).tool_call_id
             const content =
-              typeof (p as any).content === "string" ? (p as any).content : JSON.stringify((p as any).content)
+              typeof (p as any).content === "string"
+                ? (p as any).content
+                : JSON.stringify((p as any).content)
             msgs.push({ role: "tool", tool_call_id: id, content })
           }
         }
-        if (parts.length === 1 && parts[0].type === "text") msgs.push({ role: "user", content: parts[0].text })
+        if (parts.length === 1 && parts[0].type === "text")
+          msgs.push({ role: "user", content: parts[0].text })
         else if (parts.length > 0) msgs.push({ role: "user", content: parts })
       }
       continue
@@ -153,7 +169,11 @@ export function fromOpenaiRequest(body: any): CommonRequest {
     }
 
     if ((m as any).role === "tool") {
-      msgs.push({ role: "tool", tool_call_id: (m as any).tool_call_id, content: (m as any).content })
+      msgs.push({
+        role: "tool",
+        tool_call_id: (m as any).tool_call_id,
+        content: (m as any).content,
+      })
       continue
     }
   }
@@ -210,7 +230,10 @@ export function toOpenaiRequest(body: CommonRequest) {
       typeof (s as any).media_type === "string" &&
       typeof (s as any).data === "string"
     )
-      return { type: "input_image", image_url: { url: `data:${(s as any).media_type};base64,${(s as any).data}` } }
+      return {
+        type: "input_image",
+        image_url: { url: `data:${(s as any).media_type};base64,${(s as any).data}` },
+      }
     return undefined
   }
 
@@ -257,7 +280,10 @@ export function toOpenaiRequest(body: CommonRequest) {
     }
 
     if ((m as any).role === "tool") {
-      const out = typeof (m as any).content === "string" ? (m as any).content : JSON.stringify((m as any).content)
+      const out =
+        typeof (m as any).content === "string"
+          ? (m as any).content
+          : JSON.stringify((m as any).content)
       input.push({ type: "function_call_output", call_id: (m as any).tool_call_id, output: out })
       continue
     }
@@ -325,7 +351,9 @@ export function fromOpenaiResponse(resp: any): CommonResponse {
 
   const idIn = (r as any).id
   const id =
-    typeof idIn === "string" ? idIn.replace(/^resp_/, "chatcmpl_") : `chatcmpl_${Math.random().toString(36).slice(2)}`
+    typeof idIn === "string"
+      ? idIn.replace(/^resp_/, "chatcmpl_")
+      : `chatcmpl_${Math.random().toString(36).slice(2)}`
   const model = (r as any).model ?? (resp as any).model
 
   const out = Array.isArray((r as any).output) ? (r as any).output : []
@@ -452,7 +480,9 @@ export function toOpenaiResponse(resp: CommonResponse) {
   })()
 
   return {
-    id: (resp as any).id?.replace(/^chatcmpl_/, "resp_") ?? `resp_${Math.random().toString(36).slice(2)}`,
+    id:
+      (resp as any).id?.replace(/^chatcmpl_/, "resp_") ??
+      `resp_${Math.random().toString(36).slice(2)}`,
     object: "response",
     model: (resp as any).model,
     output: outputItems,
@@ -498,7 +528,9 @@ export function fromOpenaiChunk(chunk: string): CommonChunk | string {
     if (typeof name === "string" && name.length > 0) {
       out.choices.push({
         index: 0,
-        delta: { tool_calls: [{ index: 0, id, type: "function", function: { name, arguments: "" } }] },
+        delta: {
+          tool_calls: [{ index: 0, id, type: "function", function: { name, arguments: "" } }],
+        },
         finish_reason: null,
       })
     }
@@ -555,7 +587,12 @@ export function toOpenaiChunk(chunk: CommonChunk): string {
   const model = chunk.model
 
   if (d.content) {
-    const data = { id, type: "response.output_text.delta", delta: d.content, response: { id, model } }
+    const data = {
+      id,
+      type: "response.output_text.delta",
+      delta: d.content,
+      response: { id, model },
+    }
     return `event: response.output_text.delta\ndata: ${JSON.stringify(data)}`
   }
 
@@ -565,7 +602,13 @@ export function toOpenaiChunk(chunk: CommonChunk): string {
         const data = {
           type: "response.output_item.added",
           output_index: 0,
-          item: { id: tc.id, type: "function_call", name: tc.function.name, call_id: tc.id, arguments: "" },
+          item: {
+            id: tc.id,
+            type: "function_call",
+            name: tc.function.name,
+            call_id: tc.id,
+            arguments: "",
+          },
         }
         return `event: response.output_item.added\ndata: ${JSON.stringify(data)}`
       }
@@ -593,7 +636,11 @@ export function toOpenaiChunk(chunk: CommonChunk): string {
         }
       : undefined
 
-    const data: any = { id, type: "response.completed", response: { id, model, ...(usage ? { usage } : {}) } }
+    const data: any = {
+      id,
+      type: "response.completed",
+      response: { id, model, ...(usage ? { usage } : {}) },
+    }
     return `event: response.completed\ndata: ${JSON.stringify(data)}`
   }
 

+ 2 - 1
packages/console/app/src/style/token/font.css

@@ -15,6 +15,7 @@ body {
   --font-size-9xl: 8rem;
 
   --font-mono:
-    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
+    "Courier New", monospace;
   --font-sans: var(--font-mono);
 }

+ 1 - 1
packages/console/app/sst-env.d.ts

@@ -6,4 +6,4 @@
 /// <reference path="../../../sst-env.d.ts" />
 
 import "sst"
-export {}
+export {}

+ 13 - 44
packages/console/core/migrations/meta/0018_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -486,17 +473,12 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         },
         "name": {
           "name": "name",
-          "columns": [
-            "workspace_id",
-            "name"
-          ],
+          "columns": ["workspace_id", "name"],
           "isUnique": true
         }
       },
@@ -504,10 +486,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -599,10 +578,7 @@
       "indexes": {
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         }
       },
@@ -610,10 +586,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -670,9 +643,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -680,9 +651,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -699,4 +668,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 13 - 44
packages/console/core/migrations/meta/0019_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -486,17 +473,12 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         },
         "name": {
           "name": "name",
-          "columns": [
-            "workspace_id",
-            "name"
-          ],
+          "columns": ["workspace_id", "name"],
           "isUnique": true
         }
       },
@@ -504,10 +486,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -599,10 +578,7 @@
       "indexes": {
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         }
       },
@@ -610,10 +586,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -670,9 +643,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -680,9 +651,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -699,4 +668,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 13 - 44
packages/console/core/migrations/meta/0020_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -486,17 +473,12 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         },
         "name": {
           "name": "name",
-          "columns": [
-            "workspace_id",
-            "name"
-          ],
+          "columns": ["workspace_id", "name"],
           "isUnique": true
         }
       },
@@ -504,10 +486,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -592,10 +571,7 @@
       "indexes": {
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         }
       },
@@ -603,10 +579,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -663,9 +636,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -673,9 +644,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -692,4 +661,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 13 - 44
packages/console/core/migrations/meta/0021_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -486,17 +473,12 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         },
         "name": {
           "name": "name",
-          "columns": [
-            "workspace_id",
-            "name"
-          ],
+          "columns": ["workspace_id", "name"],
           "isUnique": true
         }
       },
@@ -504,10 +486,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -599,10 +578,7 @@
       "indexes": {
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         }
       },
@@ -610,10 +586,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -670,9 +643,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -680,9 +651,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -699,4 +668,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 14 - 48
packages/console/core/migrations/meta/0022_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -486,17 +473,12 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         },
         "name": {
           "name": "name",
-          "columns": [
-            "workspace_id",
-            "name"
-          ],
+          "columns": ["workspace_id", "name"],
           "isUnique": true
         }
       },
@@ -504,10 +486,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -613,18 +592,12 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         }
       },
@@ -632,10 +605,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -692,9 +662,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -702,9 +670,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -721,4 +687,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 16 - 54
packages/console/core/migrations/meta/0023_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -486,17 +473,12 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         },
         "name": {
           "name": "name",
-          "columns": [
-            "workspace_id",
-            "name"
-          ],
+          "columns": ["workspace_id", "name"],
           "isUnique": true
         }
       },
@@ -504,10 +486,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -613,32 +592,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -646,10 +615,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -706,9 +672,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -716,9 +680,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -735,4 +697,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 16 - 54
packages/console/core/migrations/meta/0024_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -486,17 +473,12 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         },
         "name": {
           "name": "name",
-          "columns": [
-            "workspace_id",
-            "name"
-          ],
+          "columns": ["workspace_id", "name"],
           "isUnique": true
         }
       },
@@ -504,10 +486,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -599,32 +578,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -632,10 +601,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -692,9 +658,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -702,9 +666,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -721,4 +683,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 16 - 54
packages/console/core/migrations/meta/0025_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -493,17 +480,12 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         },
         "name": {
           "name": "name",
-          "columns": [
-            "workspace_id",
-            "name"
-          ],
+          "columns": ["workspace_id", "name"],
           "isUnique": true
         }
       },
@@ -511,10 +493,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -606,32 +585,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -639,10 +608,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -699,9 +665,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -709,9 +673,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -728,4 +690,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 15 - 50
packages/console/core/migrations/meta/0026_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -493,9 +480,7 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         }
       },
@@ -503,10 +488,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -598,32 +580,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -631,10 +603,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -691,9 +660,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -701,9 +668,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -720,4 +685,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 15 - 50
packages/console/core/migrations/meta/0027_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -479,9 +466,7 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         }
       },
@@ -489,10 +474,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -584,32 +566,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -617,10 +589,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -677,9 +646,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -687,9 +654,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -706,4 +671,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 15 - 50
packages/console/core/migrations/meta/0028_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -479,9 +466,7 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         }
       },
@@ -489,10 +474,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -584,32 +566,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -617,10 +589,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -677,9 +646,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -687,9 +654,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -706,4 +671,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 15 - 50
packages/console/core/migrations/meta/0029_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -479,9 +466,7 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         }
       },
@@ -489,10 +474,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -605,32 +587,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -638,10 +610,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -698,9 +667,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -708,9 +675,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -727,4 +692,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 17 - 58
packages/console/core/migrations/meta/0030_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -479,9 +466,7 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         }
       },
@@ -489,10 +474,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -549,10 +531,7 @@
       "indexes": {
         "model_workspace_model": {
           "name": "model_workspace_model",
-          "columns": [
-            "workspace_id",
-            "model"
-          ],
+          "columns": ["workspace_id", "model"],
           "isUnique": true
         }
       },
@@ -560,10 +539,7 @@
       "compositePrimaryKeys": {
         "model_workspace_id_id_pk": {
           "name": "model_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -676,32 +652,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -709,10 +675,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -769,9 +732,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -779,9 +740,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -798,4 +757,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 19 - 66
packages/console/core/migrations/meta/0031_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -398,10 +388,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -479,9 +466,7 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         }
       },
@@ -489,10 +474,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -549,10 +531,7 @@
       "indexes": {
         "model_workspace_model": {
           "name": "model_workspace_model",
-          "columns": [
-            "workspace_id",
-            "model"
-          ],
+          "columns": ["workspace_id", "model"],
           "isUnique": true
         }
       },
@@ -560,10 +539,7 @@
       "compositePrimaryKeys": {
         "model_workspace_id_id_pk": {
           "name": "model_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -627,10 +603,7 @@
       "indexes": {
         "workspace_provider": {
           "name": "workspace_provider",
-          "columns": [
-            "workspace_id",
-            "provider"
-          ],
+          "columns": ["workspace_id", "provider"],
           "isUnique": true
         }
       },
@@ -638,10 +611,7 @@
       "compositePrimaryKeys": {
         "provider_workspace_id_id_pk": {
           "name": "provider_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -754,32 +724,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -787,10 +747,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -847,9 +804,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -857,9 +812,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -876,4 +829,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 19 - 66
packages/console/core/migrations/meta/0032_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -180,9 +178,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -190,10 +186,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -280,10 +273,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -405,10 +395,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -486,9 +473,7 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         }
       },
@@ -496,10 +481,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -556,10 +538,7 @@
       "indexes": {
         "model_workspace_model": {
           "name": "model_workspace_model",
-          "columns": [
-            "workspace_id",
-            "model"
-          ],
+          "columns": ["workspace_id", "model"],
           "isUnique": true
         }
       },
@@ -567,10 +546,7 @@
       "compositePrimaryKeys": {
         "model_workspace_id_id_pk": {
           "name": "model_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -634,10 +610,7 @@
       "indexes": {
         "workspace_provider": {
           "name": "workspace_provider",
-          "columns": [
-            "workspace_id",
-            "provider"
-          ],
+          "columns": ["workspace_id", "provider"],
           "isUnique": true
         }
       },
@@ -645,10 +618,7 @@
       "compositePrimaryKeys": {
         "provider_workspace_id_id_pk": {
           "name": "provider_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -761,32 +731,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -794,10 +754,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -854,9 +811,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -864,9 +819,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -883,4 +836,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 19 - 66
packages/console/core/migrations/meta/0033_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -187,9 +185,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -197,10 +193,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -287,10 +280,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -412,10 +402,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -493,9 +480,7 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         }
       },
@@ -503,10 +488,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -563,10 +545,7 @@
       "indexes": {
         "model_workspace_model": {
           "name": "model_workspace_model",
-          "columns": [
-            "workspace_id",
-            "model"
-          ],
+          "columns": ["workspace_id", "model"],
           "isUnique": true
         }
       },
@@ -574,10 +553,7 @@
       "compositePrimaryKeys": {
         "model_workspace_id_id_pk": {
           "name": "model_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -641,10 +617,7 @@
       "indexes": {
         "workspace_provider": {
           "name": "workspace_provider",
-          "columns": [
-            "workspace_id",
-            "provider"
-          ],
+          "columns": ["workspace_id", "provider"],
           "isUnique": true
         }
       },
@@ -652,10 +625,7 @@
       "compositePrimaryKeys": {
         "provider_workspace_id_id_pk": {
           "name": "provider_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -768,32 +738,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -801,10 +761,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -861,9 +818,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -871,9 +826,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -890,4 +843,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 20 - 70
packages/console/core/migrations/meta/0034_snapshot.json

@@ -48,9 +48,7 @@
       "indexes": {
         "email": {
           "name": "email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": true
         }
       },
@@ -117,10 +115,7 @@
       "indexes": {
         "provider": {
           "name": "provider",
-          "columns": [
-            "provider",
-            "subject"
-          ],
+          "columns": ["provider", "subject"],
           "isUnique": true
         }
       },
@@ -257,9 +252,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -267,10 +260,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -357,10 +347,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -482,10 +469,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -563,9 +547,7 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         }
       },
@@ -573,10 +555,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -633,10 +612,7 @@
       "indexes": {
         "model_workspace_model": {
           "name": "model_workspace_model",
-          "columns": [
-            "workspace_id",
-            "model"
-          ],
+          "columns": ["workspace_id", "model"],
           "isUnique": true
         }
       },
@@ -644,10 +620,7 @@
       "compositePrimaryKeys": {
         "model_workspace_id_id_pk": {
           "name": "model_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -711,10 +684,7 @@
       "indexes": {
         "workspace_provider": {
           "name": "workspace_provider",
-          "columns": [
-            "workspace_id",
-            "provider"
-          ],
+          "columns": ["workspace_id", "provider"],
           "isUnique": true
         }
       },
@@ -722,10 +692,7 @@
       "compositePrimaryKeys": {
         "provider_workspace_id_id_pk": {
           "name": "provider_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -838,32 +805,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -871,10 +828,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -931,9 +885,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -941,9 +893,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -960,4 +910,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 20 - 70
packages/console/core/migrations/meta/0035_snapshot.json

@@ -102,17 +102,12 @@
       "indexes": {
         "provider": {
           "name": "provider",
-          "columns": [
-            "provider",
-            "subject"
-          ],
+          "columns": ["provider", "subject"],
           "isUnique": true
         },
         "account_id": {
           "name": "account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         }
       },
@@ -249,9 +244,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -259,10 +252,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -349,10 +339,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -474,10 +461,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -555,9 +539,7 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         }
       },
@@ -565,10 +547,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -625,10 +604,7 @@
       "indexes": {
         "model_workspace_model": {
           "name": "model_workspace_model",
-          "columns": [
-            "workspace_id",
-            "model"
-          ],
+          "columns": ["workspace_id", "model"],
           "isUnique": true
         }
       },
@@ -636,10 +612,7 @@
       "compositePrimaryKeys": {
         "model_workspace_id_id_pk": {
           "name": "model_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -703,10 +676,7 @@
       "indexes": {
         "workspace_provider": {
           "name": "workspace_provider",
-          "columns": [
-            "workspace_id",
-            "provider"
-          ],
+          "columns": ["workspace_id", "provider"],
           "isUnique": true
         }
       },
@@ -714,10 +684,7 @@
       "compositePrimaryKeys": {
         "provider_workspace_id_id_pk": {
           "name": "provider_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -830,32 +797,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -863,10 +820,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -923,9 +877,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -933,9 +885,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -952,4 +902,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 22 - 76
packages/console/core/migrations/meta/0036_snapshot.json

@@ -43,9 +43,7 @@
       "compositePrimaryKeys": {
         "account_id_pk": {
           "name": "account_id_pk",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -109,17 +107,12 @@
       "indexes": {
         "provider": {
           "name": "provider",
-          "columns": [
-            "provider",
-            "subject"
-          ],
+          "columns": ["provider", "subject"],
           "isUnique": true
         },
         "account_id": {
           "name": "account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         }
       },
@@ -127,9 +120,7 @@
       "compositePrimaryKeys": {
         "auth_id_pk": {
           "name": "auth_id_pk",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -263,9 +254,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -273,10 +262,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -363,10 +349,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -488,10 +471,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -569,9 +549,7 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         }
       },
@@ -579,10 +557,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -639,10 +614,7 @@
       "indexes": {
         "model_workspace_model": {
           "name": "model_workspace_model",
-          "columns": [
-            "workspace_id",
-            "model"
-          ],
+          "columns": ["workspace_id", "model"],
           "isUnique": true
         }
       },
@@ -650,10 +622,7 @@
       "compositePrimaryKeys": {
         "model_workspace_id_id_pk": {
           "name": "model_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -717,10 +686,7 @@
       "indexes": {
         "workspace_provider": {
           "name": "workspace_provider",
-          "columns": [
-            "workspace_id",
-            "provider"
-          ],
+          "columns": ["workspace_id", "provider"],
           "isUnique": true
         }
       },
@@ -728,10 +694,7 @@
       "compositePrimaryKeys": {
         "provider_workspace_id_id_pk": {
           "name": "provider_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -844,32 +807,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -877,10 +830,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -937,9 +887,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -947,9 +895,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -966,4 +912,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 22 - 76
packages/console/core/migrations/meta/0037_snapshot.json

@@ -43,9 +43,7 @@
       "compositePrimaryKeys": {
         "account_id_pk": {
           "name": "account_id_pk",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -109,17 +107,12 @@
       "indexes": {
         "provider": {
           "name": "provider",
-          "columns": [
-            "provider",
-            "subject"
-          ],
+          "columns": ["provider", "subject"],
           "isUnique": true
         },
         "account_id": {
           "name": "account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         }
       },
@@ -127,9 +120,7 @@
       "compositePrimaryKeys": {
         "auth_id_pk": {
           "name": "auth_id_pk",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -277,9 +268,7 @@
       "indexes": {
         "global_customer_id": {
           "name": "global_customer_id",
-          "columns": [
-            "customer_id"
-          ],
+          "columns": ["customer_id"],
           "isUnique": true
         }
       },
@@ -287,10 +276,7 @@
       "compositePrimaryKeys": {
         "billing_workspace_id_id_pk": {
           "name": "billing_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -377,10 +363,7 @@
       "compositePrimaryKeys": {
         "payment_workspace_id_id_pk": {
           "name": "payment_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -502,10 +485,7 @@
       "compositePrimaryKeys": {
         "usage_workspace_id_id_pk": {
           "name": "usage_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -583,9 +563,7 @@
       "indexes": {
         "global_key": {
           "name": "global_key",
-          "columns": [
-            "key"
-          ],
+          "columns": ["key"],
           "isUnique": true
         }
       },
@@ -593,10 +571,7 @@
       "compositePrimaryKeys": {
         "key_workspace_id_id_pk": {
           "name": "key_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -653,10 +628,7 @@
       "indexes": {
         "model_workspace_model": {
           "name": "model_workspace_model",
-          "columns": [
-            "workspace_id",
-            "model"
-          ],
+          "columns": ["workspace_id", "model"],
           "isUnique": true
         }
       },
@@ -664,10 +636,7 @@
       "compositePrimaryKeys": {
         "model_workspace_id_id_pk": {
           "name": "model_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -731,10 +700,7 @@
       "indexes": {
         "workspace_provider": {
           "name": "workspace_provider",
-          "columns": [
-            "workspace_id",
-            "provider"
-          ],
+          "columns": ["workspace_id", "provider"],
           "isUnique": true
         }
       },
@@ -742,10 +708,7 @@
       "compositePrimaryKeys": {
         "provider_workspace_id_id_pk": {
           "name": "provider_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -858,32 +821,22 @@
       "indexes": {
         "user_account_id": {
           "name": "user_account_id",
-          "columns": [
-            "workspace_id",
-            "account_id"
-          ],
+          "columns": ["workspace_id", "account_id"],
           "isUnique": true
         },
         "user_email": {
           "name": "user_email",
-          "columns": [
-            "workspace_id",
-            "email"
-          ],
+          "columns": ["workspace_id", "email"],
           "isUnique": true
         },
         "global_account_id": {
           "name": "global_account_id",
-          "columns": [
-            "account_id"
-          ],
+          "columns": ["account_id"],
           "isUnique": false
         },
         "global_email": {
           "name": "global_email",
-          "columns": [
-            "email"
-          ],
+          "columns": ["email"],
           "isUnique": false
         }
       },
@@ -891,10 +844,7 @@
       "compositePrimaryKeys": {
         "user_workspace_id_id_pk": {
           "name": "user_workspace_id_id_pk",
-          "columns": [
-            "workspace_id",
-            "id"
-          ]
+          "columns": ["workspace_id", "id"]
         }
       },
       "uniqueConstraints": {},
@@ -951,9 +901,7 @@
       "indexes": {
         "slug": {
           "name": "slug",
-          "columns": [
-            "slug"
-          ],
+          "columns": ["slug"],
           "isUnique": true
         }
       },
@@ -961,9 +909,7 @@
       "compositePrimaryKeys": {
         "workspace_id": {
           "name": "workspace_id",
-          "columns": [
-            "id"
-          ]
+          "columns": ["id"]
         }
       },
       "uniqueConstraints": {},
@@ -980,4 +926,4 @@
     "tables": {},
     "indexes": {}
   }
-}
+}

+ 1 - 1
packages/console/core/migrations/meta/_journal.json

@@ -269,4 +269,4 @@
       "breakpoints": true
     }
   ]
-}
+}

+ 28 - 25
packages/console/core/src/aws.ts

@@ -24,37 +24,40 @@ export namespace AWS {
       body: z.string(),
     }),
     async (input) => {
-      const res = await createClient().fetch("https://email.us-east-1.amazonaws.com/v2/email/outbound-emails", {
-        method: "POST",
-        headers: {
-          "X-Amz-Target": "SES.SendEmail",
-          "Content-Type": "application/json",
-        },
-        body: JSON.stringify({
-          FromEmailAddress: `OpenCode Zen <[email protected]>`,
-          Destination: {
-            ToAddresses: [input.to],
+      const res = await createClient().fetch(
+        "https://email.us-east-1.amazonaws.com/v2/email/outbound-emails",
+        {
+          method: "POST",
+          headers: {
+            "X-Amz-Target": "SES.SendEmail",
+            "Content-Type": "application/json",
           },
-          Content: {
-            Simple: {
-              Subject: {
-                Charset: "UTF-8",
-                Data: input.subject,
-              },
-              Body: {
-                Text: {
+          body: JSON.stringify({
+            FromEmailAddress: `OpenCode Zen <[email protected]>`,
+            Destination: {
+              ToAddresses: [input.to],
+            },
+            Content: {
+              Simple: {
+                Subject: {
                   Charset: "UTF-8",
-                  Data: input.body,
+                  Data: input.subject,
                 },
-                Html: {
-                  Charset: "UTF-8",
-                  Data: input.body,
+                Body: {
+                  Text: {
+                    Charset: "UTF-8",
+                    Data: input.body,
+                  },
+                  Html: {
+                    Charset: "UTF-8",
+                    Data: input.body,
+                  },
                 },
               },
             },
-          },
-        }),
-      })
+          }),
+        },
+      )
       if (!res.ok) {
         throw new Error(`Failed to send email: ${res.statusText}`)
       }

+ 8 - 2
packages/console/core/src/drizzle/index.ts

@@ -5,7 +5,10 @@ import { Client } from "@planetscale/database"
 
 import { MySqlTransaction, type MySqlTransactionConfig } from "drizzle-orm/mysql-core"
 import type { ExtractTablesWithRelations } from "drizzle-orm"
-import type { PlanetScalePreparedQueryHKT, PlanetscaleQueryResultHKT } from "drizzle-orm/planetscale-serverless"
+import type {
+  PlanetScalePreparedQueryHKT,
+  PlanetscaleQueryResultHKT,
+} from "drizzle-orm/planetscale-serverless"
 import { Context } from "../context"
 import { memo } from "../util/memo"
 
@@ -67,7 +70,10 @@ export namespace Database {
     }
   }
 
-  export async function transaction<T>(callback: (tx: TxOrDb) => Promise<T>, config?: MySqlTransactionConfig) {
+  export async function transaction<T>(
+    callback: (tx: TxOrDb) => Promise<T>,
+    config?: MySqlTransactionConfig,
+  ) {
     try {
       const { tx } = TransactionContext.use()
       return callback(tx)

+ 8 - 2
packages/console/core/src/key.ts

@@ -20,8 +20,14 @@ export namespace Key {
           email: AuthTable.subject,
         })
         .from(KeyTable)
-        .innerJoin(UserTable, and(eq(KeyTable.userID, UserTable.id), eq(KeyTable.workspaceID, UserTable.workspaceID)))
-        .innerJoin(AuthTable, and(eq(UserTable.accountID, AuthTable.accountID), eq(AuthTable.provider, "email")))
+        .innerJoin(
+          UserTable,
+          and(eq(KeyTable.userID, UserTable.id), eq(KeyTable.workspaceID, UserTable.workspaceID)),
+        )
+        .innerJoin(
+          AuthTable,
+          and(eq(UserTable.accountID, AuthTable.accountID), eq(AuthTable.provider, "email")),
+        )
         .where(
           and(
             ...[

+ 9 - 2
packages/console/core/src/provider.ts

@@ -11,7 +11,9 @@ export namespace Provider {
       tx
         .select()
         .from(ProviderTable)
-        .where(and(eq(ProviderTable.workspaceID, Actor.workspace()), isNull(ProviderTable.timeDeleted))),
+        .where(
+          and(eq(ProviderTable.workspaceID, Actor.workspace()), isNull(ProviderTable.timeDeleted)),
+        ),
     ),
   )
 
@@ -50,7 +52,12 @@ export namespace Provider {
       return Database.transaction((tx) =>
         tx
           .delete(ProviderTable)
-          .where(and(eq(ProviderTable.provider, provider), eq(ProviderTable.workspaceID, Actor.workspace()))),
+          .where(
+            and(
+              eq(ProviderTable.provider, provider),
+              eq(ProviderTable.workspaceID, Actor.workspace()),
+            ),
+          ),
       )
     },
   )

+ 8 - 1
packages/console/core/src/schema/auth.sql.ts

@@ -1,4 +1,11 @@
-import { index, mysqlEnum, mysqlTable, primaryKey, uniqueIndex, varchar } from "drizzle-orm/mysql-core"
+import {
+  index,
+  mysqlEnum,
+  mysqlTable,
+  primaryKey,
+  uniqueIndex,
+  varchar,
+} from "drizzle-orm/mysql-core"
 import { id, timestamps, ulid } from "../drizzle/types"
 
 export const AuthProvider = ["email", "github", "google"] as const

+ 4 - 1
packages/console/core/src/schema/model.sql.ts

@@ -9,5 +9,8 @@ export const ModelTable = mysqlTable(
     ...timestamps,
     model: varchar("model", { length: 64 }).notNull(),
   },
-  (table) => [...workspaceIndexes(table), uniqueIndex("model_workspace_model").on(table.workspaceID, table.model)],
+  (table) => [
+    ...workspaceIndexes(table),
+    uniqueIndex("model_workspace_model").on(table.workspaceID, table.model),
+  ],
 )

+ 4 - 1
packages/console/core/src/schema/provider.sql.ts

@@ -10,5 +10,8 @@ export const ProviderTable = mysqlTable(
     provider: varchar("provider", { length: 64 }).notNull(),
     credentials: text("credentials").notNull(),
   },
-  (table) => [...workspaceIndexes(table), uniqueIndex("workspace_provider").on(table.workspaceID, table.provider)],
+  (table) => [
+    ...workspaceIndexes(table),
+    uniqueIndex("workspace_provider").on(table.workspaceID, table.provider),
+  ],
 )

+ 9 - 1
packages/console/core/src/schema/user.sql.ts

@@ -1,4 +1,12 @@
-import { mysqlTable, uniqueIndex, varchar, int, mysqlEnum, index, bigint } from "drizzle-orm/mysql-core"
+import {
+  mysqlTable,
+  uniqueIndex,
+  varchar,
+  int,
+  mysqlEnum,
+  index,
+  bigint,
+} from "drizzle-orm/mysql-core"
 import { timestamps, ulid, utc, workspaceColumns } from "../drizzle/types"
 import { workspaceIndexes } from "./workspace.sql"
 

+ 23 - 5
packages/console/core/src/user.ts

@@ -26,7 +26,10 @@ export namespace User {
           authEmail: AuthTable.subject,
         })
         .from(UserTable)
-        .leftJoin(AuthTable, and(eq(UserTable.accountID, AuthTable.accountID), eq(AuthTable.provider, "email")))
+        .leftJoin(
+          AuthTable,
+          and(eq(UserTable.accountID, AuthTable.accountID), eq(AuthTable.provider, "email")),
+        )
         .where(and(eq(UserTable.workspaceID, Actor.workspace()), isNull(UserTable.timeDeleted))),
     ),
   )
@@ -36,7 +39,13 @@ export namespace User {
       tx
         .select()
         .from(UserTable)
-        .where(and(eq(UserTable.workspaceID, Actor.workspace()), eq(UserTable.id, id), isNull(UserTable.timeDeleted)))
+        .where(
+          and(
+            eq(UserTable.workspaceID, Actor.workspace()),
+            eq(UserTable.id, id),
+            isNull(UserTable.timeDeleted),
+          ),
+        )
         .then((rows) => rows[0]),
     ),
   )
@@ -48,7 +57,10 @@ export namespace User {
           email: AuthTable.subject,
         })
         .from(UserTable)
-        .leftJoin(AuthTable, and(eq(UserTable.accountID, AuthTable.accountID), eq(AuthTable.provider, "email")))
+        .leftJoin(
+          AuthTable,
+          and(eq(UserTable.accountID, AuthTable.accountID), eq(AuthTable.provider, "email")),
+        )
         .where(and(eq(UserTable.workspaceID, Actor.workspace()), eq(UserTable.id, id)))
         .then((rows) => rows[0]?.email),
     ),
@@ -130,10 +142,16 @@ export namespace User {
               workspaceName: WorkspaceTable.name,
             })
             .from(UserTable)
-            .innerJoin(AuthTable, and(eq(UserTable.accountID, AuthTable.accountID), eq(AuthTable.provider, "email")))
+            .innerJoin(
+              AuthTable,
+              and(eq(UserTable.accountID, AuthTable.accountID), eq(AuthTable.provider, "email")),
+            )
             .innerJoin(WorkspaceTable, eq(WorkspaceTable.id, workspaceID))
             .where(
-              and(eq(UserTable.workspaceID, workspaceID), eq(UserTable.id, Actor.assert("user").properties.userID)),
+              and(
+                eq(UserTable.workspaceID, workspaceID),
+                eq(UserTable.id, Actor.assert("user").properties.userID),
+              ),
             )
             .then((rows) => rows[0]),
         )

+ 87 - 87
packages/console/core/sst-env.d.ts

@@ -6,99 +6,99 @@
 import "sst"
 declare module "sst" {
   export interface Resource {
-    "ADMIN_SECRET": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "AUTH_API_URL": {
-      "type": "sst.sst.Linkable"
-      "value": string
-    }
-    "AWS_SES_ACCESS_KEY_ID": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "AWS_SES_SECRET_ACCESS_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "Console": {
-      "type": "sst.cloudflare.SolidStart"
-      "url": string
-    }
-    "Database": {
-      "database": string
-      "host": string
-      "password": string
-      "port": number
-      "type": "sst.sst.Linkable"
-      "username": string
-    }
-    "Desktop": {
-      "type": "sst.cloudflare.StaticSite"
-      "url": string
-    }
-    "EMAILOCTOPUS_API_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_APP_ID": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_APP_PRIVATE_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_CLIENT_ID_CONSOLE": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_CLIENT_SECRET_CONSOLE": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GOOGLE_CLIENT_ID": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "HONEYCOMB_API_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "STRIPE_SECRET_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "STRIPE_WEBHOOK_SECRET": {
-      "type": "sst.sst.Linkable"
-      "value": string
-    }
-    "Web": {
-      "type": "sst.cloudflare.Astro"
-      "url": string
-    }
-    "ZEN_MODELS1": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "ZEN_MODELS2": {
-      "type": "sst.sst.Secret"
-      "value": string
+    ADMIN_SECRET: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    AUTH_API_URL: {
+      type: "sst.sst.Linkable"
+      value: string
+    }
+    AWS_SES_ACCESS_KEY_ID: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    AWS_SES_SECRET_ACCESS_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    Console: {
+      type: "sst.cloudflare.SolidStart"
+      url: string
+    }
+    Database: {
+      database: string
+      host: string
+      password: string
+      port: number
+      type: "sst.sst.Linkable"
+      username: string
+    }
+    Desktop: {
+      type: "sst.cloudflare.StaticSite"
+      url: string
+    }
+    EMAILOCTOPUS_API_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_APP_ID: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_APP_PRIVATE_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_CLIENT_ID_CONSOLE: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_CLIENT_SECRET_CONSOLE: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GOOGLE_CLIENT_ID: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    HONEYCOMB_API_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    STRIPE_SECRET_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    STRIPE_WEBHOOK_SECRET: {
+      type: "sst.sst.Linkable"
+      value: string
+    }
+    Web: {
+      type: "sst.cloudflare.Astro"
+      url: string
+    }
+    ZEN_MODELS1: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    ZEN_MODELS2: {
+      type: "sst.sst.Secret"
+      value: string
     }
   }
 }
-// cloudflare 
-import * as cloudflare from "@cloudflare/workers-types";
+// cloudflare
+import * as cloudflare from "@cloudflare/workers-types"
 declare module "sst" {
   export interface Resource {
-    "Api": cloudflare.Service
-    "AuthApi": cloudflare.Service
-    "AuthStorage": cloudflare.KVNamespace
-    "Bucket": cloudflare.R2Bucket
-    "LogProcessor": cloudflare.Service
+    Api: cloudflare.Service
+    AuthApi: cloudflare.Service
+    AuthStorage: cloudflare.KVNamespace
+    Bucket: cloudflare.R2Bucket
+    LogProcessor: cloudflare.Service
   }
 }
 
 import "sst"
-export {}
+export {}

+ 87 - 87
packages/console/function/sst-env.d.ts

@@ -6,99 +6,99 @@
 import "sst"
 declare module "sst" {
   export interface Resource {
-    "ADMIN_SECRET": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "AUTH_API_URL": {
-      "type": "sst.sst.Linkable"
-      "value": string
-    }
-    "AWS_SES_ACCESS_KEY_ID": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "AWS_SES_SECRET_ACCESS_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "Console": {
-      "type": "sst.cloudflare.SolidStart"
-      "url": string
-    }
-    "Database": {
-      "database": string
-      "host": string
-      "password": string
-      "port": number
-      "type": "sst.sst.Linkable"
-      "username": string
-    }
-    "Desktop": {
-      "type": "sst.cloudflare.StaticSite"
-      "url": string
-    }
-    "EMAILOCTOPUS_API_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_APP_ID": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_APP_PRIVATE_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_CLIENT_ID_CONSOLE": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_CLIENT_SECRET_CONSOLE": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GOOGLE_CLIENT_ID": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "HONEYCOMB_API_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "STRIPE_SECRET_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "STRIPE_WEBHOOK_SECRET": {
-      "type": "sst.sst.Linkable"
-      "value": string
-    }
-    "Web": {
-      "type": "sst.cloudflare.Astro"
-      "url": string
-    }
-    "ZEN_MODELS1": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "ZEN_MODELS2": {
-      "type": "sst.sst.Secret"
-      "value": string
+    ADMIN_SECRET: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    AUTH_API_URL: {
+      type: "sst.sst.Linkable"
+      value: string
+    }
+    AWS_SES_ACCESS_KEY_ID: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    AWS_SES_SECRET_ACCESS_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    Console: {
+      type: "sst.cloudflare.SolidStart"
+      url: string
+    }
+    Database: {
+      database: string
+      host: string
+      password: string
+      port: number
+      type: "sst.sst.Linkable"
+      username: string
+    }
+    Desktop: {
+      type: "sst.cloudflare.StaticSite"
+      url: string
+    }
+    EMAILOCTOPUS_API_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_APP_ID: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_APP_PRIVATE_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_CLIENT_ID_CONSOLE: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_CLIENT_SECRET_CONSOLE: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GOOGLE_CLIENT_ID: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    HONEYCOMB_API_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    STRIPE_SECRET_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    STRIPE_WEBHOOK_SECRET: {
+      type: "sst.sst.Linkable"
+      value: string
+    }
+    Web: {
+      type: "sst.cloudflare.Astro"
+      url: string
+    }
+    ZEN_MODELS1: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    ZEN_MODELS2: {
+      type: "sst.sst.Secret"
+      value: string
     }
   }
 }
-// cloudflare 
-import * as cloudflare from "@cloudflare/workers-types";
+// cloudflare
+import * as cloudflare from "@cloudflare/workers-types"
 declare module "sst" {
   export interface Resource {
-    "Api": cloudflare.Service
-    "AuthApi": cloudflare.Service
-    "AuthStorage": cloudflare.KVNamespace
-    "Bucket": cloudflare.R2Bucket
-    "LogProcessor": cloudflare.Service
+    Api: cloudflare.Service
+    AuthApi: cloudflare.Service
+    AuthStorage: cloudflare.KVNamespace
+    Bucket: cloudflare.R2Bucket
+    LogProcessor: cloudflare.Service
   }
 }
 
 import "sst"
-export {}
+export {}

+ 21 - 4
packages/console/mail/emails/templates/InviteEmail.tsx

@@ -1,6 +1,18 @@
 // @ts-nocheck
 import React from "react"
-import { Img, Row, Html, Link, Body, Head, Button, Column, Preview, Section, Container } from "@jsx-email/all"
+import {
+  Img,
+  Row,
+  Html,
+  Link,
+  Body,
+  Head,
+  Button,
+  Column,
+  Preview,
+  Section,
+  Container,
+} from "@jsx-email/all"
 import { Text, Fonts, Title, A, Span } from "../components"
 import {
   unit,
@@ -52,8 +64,8 @@ export const InviteEmail = ({
             <Section style={{ padding: `${unit * 2}px 0 0 0` }}>
               <Text style={headingText}>Join your team's OpenCode workspace</Text>
               <Text style={contentText}>
-                You have been invited by <Span style={contentHighlightText}>{inviter}</Span> to join the{" "}
-                <Span style={contentHighlightText}>{workspaceName}</Span> workspace on OpenCode.
+                You have been invited by <Span style={contentHighlightText}>{inviter}</Span> to join
+                the <Span style={contentHighlightText}>{workspaceName}</Span> workspace on OpenCode.
               </Text>
             </Section>
 
@@ -61,7 +73,12 @@ export const InviteEmail = ({
               <Button style={button} href={url}>
                 <Text style={buttonText}>
                   Join workspace
-                  <Img width="24" height="24" src={`${assetsUrl}/right-arrow.png`} alt="Arrow right" />
+                  <Img
+                    width="24"
+                    height="24"
+                    src={`${assetsUrl}/right-arrow.png`}
+                    alt="Arrow right"
+                  />
                 </Text>
               </Button>
             </Section>

+ 1 - 1
packages/console/mail/sst-env.d.ts

@@ -6,4 +6,4 @@
 /// <reference path="../../../sst-env.d.ts" />
 
 import "sst"
-export {}
+export {}

+ 87 - 87
packages/console/resource/sst-env.d.ts

@@ -6,99 +6,99 @@
 import "sst"
 declare module "sst" {
   export interface Resource {
-    "ADMIN_SECRET": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "AUTH_API_URL": {
-      "type": "sst.sst.Linkable"
-      "value": string
-    }
-    "AWS_SES_ACCESS_KEY_ID": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "AWS_SES_SECRET_ACCESS_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "Console": {
-      "type": "sst.cloudflare.SolidStart"
-      "url": string
-    }
-    "Database": {
-      "database": string
-      "host": string
-      "password": string
-      "port": number
-      "type": "sst.sst.Linkable"
-      "username": string
-    }
-    "Desktop": {
-      "type": "sst.cloudflare.StaticSite"
-      "url": string
-    }
-    "EMAILOCTOPUS_API_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_APP_ID": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_APP_PRIVATE_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_CLIENT_ID_CONSOLE": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_CLIENT_SECRET_CONSOLE": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GOOGLE_CLIENT_ID": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "HONEYCOMB_API_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "STRIPE_SECRET_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "STRIPE_WEBHOOK_SECRET": {
-      "type": "sst.sst.Linkable"
-      "value": string
-    }
-    "Web": {
-      "type": "sst.cloudflare.Astro"
-      "url": string
-    }
-    "ZEN_MODELS1": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "ZEN_MODELS2": {
-      "type": "sst.sst.Secret"
-      "value": string
+    ADMIN_SECRET: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    AUTH_API_URL: {
+      type: "sst.sst.Linkable"
+      value: string
+    }
+    AWS_SES_ACCESS_KEY_ID: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    AWS_SES_SECRET_ACCESS_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    Console: {
+      type: "sst.cloudflare.SolidStart"
+      url: string
+    }
+    Database: {
+      database: string
+      host: string
+      password: string
+      port: number
+      type: "sst.sst.Linkable"
+      username: string
+    }
+    Desktop: {
+      type: "sst.cloudflare.StaticSite"
+      url: string
+    }
+    EMAILOCTOPUS_API_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_APP_ID: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_APP_PRIVATE_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_CLIENT_ID_CONSOLE: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_CLIENT_SECRET_CONSOLE: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GOOGLE_CLIENT_ID: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    HONEYCOMB_API_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    STRIPE_SECRET_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    STRIPE_WEBHOOK_SECRET: {
+      type: "sst.sst.Linkable"
+      value: string
+    }
+    Web: {
+      type: "sst.cloudflare.Astro"
+      url: string
+    }
+    ZEN_MODELS1: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    ZEN_MODELS2: {
+      type: "sst.sst.Secret"
+      value: string
     }
   }
 }
-// cloudflare 
-import * as cloudflare from "@cloudflare/workers-types";
+// cloudflare
+import * as cloudflare from "@cloudflare/workers-types"
 declare module "sst" {
   export interface Resource {
-    "Api": cloudflare.Service
-    "AuthApi": cloudflare.Service
-    "AuthStorage": cloudflare.KVNamespace
-    "Bucket": cloudflare.R2Bucket
-    "LogProcessor": cloudflare.Service
+    Api: cloudflare.Service
+    AuthApi: cloudflare.Service
+    AuthStorage: cloudflare.KVNamespace
+    Bucket: cloudflare.R2Bucket
+    LogProcessor: cloudflare.Service
   }
 }
 
 import "sst"
-export {}
+export {}

+ 2 - 4
packages/desktop/src/sst-env.d.ts

@@ -2,9 +2,7 @@
 /* tslint:disable */
 /* eslint-disable */
 /// <reference types="vite/client" />
-interface ImportMetaEnv {
-
-}
+interface ImportMetaEnv {}
 interface ImportMeta {
   readonly env: ImportMetaEnv
-}
+}

+ 1 - 1
packages/desktop/sst-env.d.ts

@@ -6,4 +6,4 @@
 /// <reference path="../../sst-env.d.ts" />
 
 import "sst"
-export {}
+export {}

+ 5 - 1
packages/function/src/api.ts

@@ -268,7 +268,11 @@ export default new Hono<{ Bindings: Env }>()
       // Verify permissions
       const userClient = new Octokit({ auth: token })
       const { data: repoData } = await userClient.repos.get({ owner, repo })
-      if (!repoData.permissions.admin && !repoData.permissions.push && !repoData.permissions.maintain)
+      if (
+        !repoData.permissions.admin &&
+        !repoData.permissions.push &&
+        !repoData.permissions.maintain
+      )
         throw new Error("User does not have write permissions")
 
       // Get installation token

+ 87 - 87
packages/function/sst-env.d.ts

@@ -6,99 +6,99 @@
 import "sst"
 declare module "sst" {
   export interface Resource {
-    "ADMIN_SECRET": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "AUTH_API_URL": {
-      "type": "sst.sst.Linkable"
-      "value": string
-    }
-    "AWS_SES_ACCESS_KEY_ID": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "AWS_SES_SECRET_ACCESS_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "Console": {
-      "type": "sst.cloudflare.SolidStart"
-      "url": string
-    }
-    "Database": {
-      "database": string
-      "host": string
-      "password": string
-      "port": number
-      "type": "sst.sst.Linkable"
-      "username": string
-    }
-    "Desktop": {
-      "type": "sst.cloudflare.StaticSite"
-      "url": string
-    }
-    "EMAILOCTOPUS_API_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_APP_ID": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_APP_PRIVATE_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_CLIENT_ID_CONSOLE": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GITHUB_CLIENT_SECRET_CONSOLE": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "GOOGLE_CLIENT_ID": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "HONEYCOMB_API_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "STRIPE_SECRET_KEY": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "STRIPE_WEBHOOK_SECRET": {
-      "type": "sst.sst.Linkable"
-      "value": string
-    }
-    "Web": {
-      "type": "sst.cloudflare.Astro"
-      "url": string
-    }
-    "ZEN_MODELS1": {
-      "type": "sst.sst.Secret"
-      "value": string
-    }
-    "ZEN_MODELS2": {
-      "type": "sst.sst.Secret"
-      "value": string
+    ADMIN_SECRET: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    AUTH_API_URL: {
+      type: "sst.sst.Linkable"
+      value: string
+    }
+    AWS_SES_ACCESS_KEY_ID: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    AWS_SES_SECRET_ACCESS_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    Console: {
+      type: "sst.cloudflare.SolidStart"
+      url: string
+    }
+    Database: {
+      database: string
+      host: string
+      password: string
+      port: number
+      type: "sst.sst.Linkable"
+      username: string
+    }
+    Desktop: {
+      type: "sst.cloudflare.StaticSite"
+      url: string
+    }
+    EMAILOCTOPUS_API_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_APP_ID: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_APP_PRIVATE_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_CLIENT_ID_CONSOLE: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GITHUB_CLIENT_SECRET_CONSOLE: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    GOOGLE_CLIENT_ID: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    HONEYCOMB_API_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    STRIPE_SECRET_KEY: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    STRIPE_WEBHOOK_SECRET: {
+      type: "sst.sst.Linkable"
+      value: string
+    }
+    Web: {
+      type: "sst.cloudflare.Astro"
+      url: string
+    }
+    ZEN_MODELS1: {
+      type: "sst.sst.Secret"
+      value: string
+    }
+    ZEN_MODELS2: {
+      type: "sst.sst.Secret"
+      value: string
     }
   }
 }
-// cloudflare 
-import * as cloudflare from "@cloudflare/workers-types";
+// cloudflare
+import * as cloudflare from "@cloudflare/workers-types"
 declare module "sst" {
   export interface Resource {
-    "Api": cloudflare.Service
-    "AuthApi": cloudflare.Service
-    "AuthStorage": cloudflare.KVNamespace
-    "Bucket": cloudflare.R2Bucket
-    "LogProcessor": cloudflare.Service
+    Api: cloudflare.Service
+    AuthApi: cloudflare.Service
+    AuthStorage: cloudflare.KVNamespace
+    Bucket: cloudflare.R2Bucket
+    LogProcessor: cloudflare.Service
   }
 }
 
 import "sst"
-export {}
+export {}

+ 5 - 2
packages/opencode/script/postinstall.mjs

@@ -77,7 +77,8 @@ async function regenerateWindowsCmdWrappers() {
 
     // npm_config_global is string | undefined
     // if it exists, the value is true
-    const isGlobal = process.env.npm_config_global === "true" || pkgPath.includes(path.join("npm", "node_modules"))
+    const isGlobal =
+      process.env.npm_config_global === "true" || pkgPath.includes(path.join("npm", "node_modules"))
 
     // The npm rebuild command does 2 things - Execute lifecycle scripts and rebuild bin links
     // We want to skip lifecycle scripts to avoid infinite loops, so we use --ignore-scripts
@@ -93,7 +94,9 @@ async function regenerateWindowsCmdWrappers() {
     console.log("Successfully rebuilt npm bin links")
   } catch (error) {
     console.error("Error rebuilding npm links:", error.message)
-    console.error("npm rebuild failed. You may need to manually run: npm rebuild opencode-ai --ignore-scripts")
+    console.error(
+      "npm rebuild failed. You may need to manually run: npm rebuild opencode-ai --ignore-scripts",
+    )
   }
 }
 

+ 13 - 2
packages/opencode/script/schema.ts

@@ -19,12 +19,23 @@ const result = z.toJSONSchema(Config.Info, {
     const schema = ctx.jsonSchema
 
     // Preserve strictness: set additionalProperties: false for objects
-    if (schema && typeof schema === "object" && schema.type === "object" && schema.additionalProperties === undefined) {
+    if (
+      schema &&
+      typeof schema === "object" &&
+      schema.type === "object" &&
+      schema.additionalProperties === undefined
+    ) {
       schema.additionalProperties = false
     }
 
     // Add examples and default descriptions for string fields with defaults
-    if (schema && typeof schema === "object" && "type" in schema && schema.type === "string" && schema?.default) {
+    if (
+      schema &&
+      typeof schema === "object" &&
+      "type" in schema &&
+      schema.type === "string" &&
+      schema?.default
+    ) {
       if (!schema.examples) {
         schema.examples = [schema.default]
       }

+ 16 - 2
packages/opencode/src/agent/agent.ts

@@ -143,7 +143,18 @@ export namespace Agent {
           tools: {},
           builtIn: false,
         }
-      const { name, model, prompt, tools, description, temperature, top_p, mode, permission, ...extra } = value
+      const {
+        name,
+        model,
+        prompt,
+        tools,
+        description,
+        temperature,
+        top_p,
+        mode,
+        permission,
+        ...extra
+      } = value
       item.options = {
         ...item.options,
         ...extra,
@@ -212,7 +223,10 @@ export namespace Agent {
   }
 }
 
-function mergeAgentPermissions(basePermission: any, overridePermission: any): Agent.Info["permission"] {
+function mergeAgentPermissions(
+  basePermission: any,
+  overridePermission: any,
+): Agent.Info["permission"] {
   if (typeof basePermission.bash === "string") {
     basePermission.bash = {
       "*": basePermission.bash,

+ 8 - 2
packages/opencode/src/bus/index.ts

@@ -19,7 +19,10 @@ export namespace Bus {
 
   const registry = new Map<string, EventDefinition>()
 
-  export function event<Type extends string, Properties extends ZodType>(type: Type, properties: Properties) {
+  export function event<Type extends string, Properties extends ZodType>(
+    type: Type,
+    properties: Properties,
+  ) {
     const result = {
       type,
       properties,
@@ -70,7 +73,10 @@ export namespace Bus {
 
   export function subscribe<Definition extends EventDefinition>(
     def: Definition,
-    callback: (event: { type: Definition["type"]; properties: z.infer<Definition["properties"]> }) => void,
+    callback: (event: {
+      type: Definition["type"]
+      properties: z.infer<Definition["properties"]>
+    }) => void,
   ) {
     return raw(def.type, callback)
   }

+ 196 - 187
packages/opencode/src/cli/cmd/auth.ts

@@ -14,7 +14,11 @@ export const AuthCommand = cmd({
   command: "auth",
   describe: "manage credentials",
   builder: (yargs) =>
-    yargs.command(AuthLoginCommand).command(AuthLogoutCommand).command(AuthListCommand).demandCommand(),
+    yargs
+      .command(AuthLoginCommand)
+      .command(AuthLogoutCommand)
+      .command(AuthListCommand)
+      .demandCommand(),
   async handler() {},
 })
 
@@ -60,7 +64,9 @@ export const AuthListCommand = cmd({
         prompts.log.info(`${provider} ${UI.Style.TEXT_DIM}${envVar}`)
       }
 
-      prompts.outro(`${activeEnvVars.length} environment variable` + (activeEnvVars.length === 1 ? "" : "s"))
+      prompts.outro(
+        `${activeEnvVars.length} environment variable` + (activeEnvVars.length === 1 ? "" : "s"),
+      )
     }
   },
 })
@@ -80,7 +86,9 @@ export const AuthLoginCommand = cmd({
         UI.empty()
         prompts.intro("Add credential")
         if (args.url) {
-          const wellknown = await fetch(`${args.url}/.well-known/opencode`).then((x) => x.json() as any)
+          const wellknown = await fetch(`${args.url}/.well-known/opencode`).then(
+            (x) => x.json() as any,
+          )
           prompts.log.info(`Running \`${wellknown.auth.command.join(" ")}\``)
           const proc = Bun.spawn({
             cmd: wellknown.auth.command,
@@ -102,223 +110,224 @@ export const AuthLoginCommand = cmd({
           prompts.outro("Done")
           return
         }
-      await ModelsDev.refresh().catch(() => {})
-      const providers = await ModelsDev.get()
-      const priority: Record<string, number> = {
-        opencode: 0,
-        anthropic: 1,
-        "github-copilot": 2,
-        openai: 3,
-        google: 4,
-        openrouter: 5,
-        vercel: 6,
-      }
-      let provider = await prompts.autocomplete({
-        message: "Select provider",
-        maxItems: 8,
-        options: [
-          ...pipe(
-            providers,
-            values(),
-            sortBy(
-              (x) => priority[x.id] ?? 99,
-              (x) => x.name ?? x.id,
+        await ModelsDev.refresh().catch(() => {})
+        const providers = await ModelsDev.get()
+        const priority: Record<string, number> = {
+          opencode: 0,
+          anthropic: 1,
+          "github-copilot": 2,
+          openai: 3,
+          google: 4,
+          openrouter: 5,
+          vercel: 6,
+        }
+        let provider = await prompts.autocomplete({
+          message: "Select provider",
+          maxItems: 8,
+          options: [
+            ...pipe(
+              providers,
+              values(),
+              sortBy(
+                (x) => priority[x.id] ?? 99,
+                (x) => x.name ?? x.id,
+              ),
+              map((x) => ({
+                label: x.name,
+                value: x.id,
+                hint: priority[x.id] <= 1 ? "recommended" : undefined,
+              })),
             ),
-            map((x) => ({
-              label: x.name,
-              value: x.id,
-              hint: priority[x.id] <= 1 ? "recommended" : undefined,
-            })),
-          ),
-          {
-            value: "other",
-            label: "Other",
-          },
-        ],
-      })
+            {
+              value: "other",
+              label: "Other",
+            },
+          ],
+        })
 
-      if (prompts.isCancel(provider)) throw new UI.CancelledError()
+        if (prompts.isCancel(provider)) throw new UI.CancelledError()
 
-      const plugin = await Plugin.list().then((x) => x.find((x) => x.auth?.provider === provider))
-      if (plugin && plugin.auth) {
-        let index = 0
-        if (plugin.auth.methods.length > 1) {
-          const method = await prompts.select({
-            message: "Login method",
-            options: [
-              ...plugin.auth.methods.map((x, index) => ({
-                label: x.label,
-                value: index.toString(),
-              })),
-            ],
-          })
-          if (prompts.isCancel(method)) throw new UI.CancelledError()
-          index = parseInt(method)
-        }
-        const method = plugin.auth.methods[index]
+        const plugin = await Plugin.list().then((x) => x.find((x) => x.auth?.provider === provider))
+        if (plugin && plugin.auth) {
+          let index = 0
+          if (plugin.auth.methods.length > 1) {
+            const method = await prompts.select({
+              message: "Login method",
+              options: [
+                ...plugin.auth.methods.map((x, index) => ({
+                  label: x.label,
+                  value: index.toString(),
+                })),
+              ],
+            })
+            if (prompts.isCancel(method)) throw new UI.CancelledError()
+            index = parseInt(method)
+          }
+          const method = plugin.auth.methods[index]
 
-        // Handle prompts for all auth types
-        await new Promise((resolve) => setTimeout(resolve, 10))
-        const inputs: Record<string, string> = {}
-        if (method.prompts) {
-          for (const prompt of method.prompts) {
-            if (prompt.condition && !prompt.condition(inputs)) {
-              continue
-            }
-            if (prompt.type === "select") {
-              const value = await prompts.select({
-                message: prompt.message,
-                options: prompt.options,
-              })
-              if (prompts.isCancel(value)) throw new UI.CancelledError()
-              inputs[prompt.key] = value
-            } else {
-              const value = await prompts.text({
-                message: prompt.message,
-                placeholder: prompt.placeholder,
-                validate: prompt.validate ? (v) => prompt.validate!(v ?? "") : undefined,
-              })
-              if (prompts.isCancel(value)) throw new UI.CancelledError()
-              inputs[prompt.key] = value
+          // Handle prompts for all auth types
+          await new Promise((resolve) => setTimeout(resolve, 10))
+          const inputs: Record<string, string> = {}
+          if (method.prompts) {
+            for (const prompt of method.prompts) {
+              if (prompt.condition && !prompt.condition(inputs)) {
+                continue
+              }
+              if (prompt.type === "select") {
+                const value = await prompts.select({
+                  message: prompt.message,
+                  options: prompt.options,
+                })
+                if (prompts.isCancel(value)) throw new UI.CancelledError()
+                inputs[prompt.key] = value
+              } else {
+                const value = await prompts.text({
+                  message: prompt.message,
+                  placeholder: prompt.placeholder,
+                  validate: prompt.validate ? (v) => prompt.validate!(v ?? "") : undefined,
+                })
+                if (prompts.isCancel(value)) throw new UI.CancelledError()
+                inputs[prompt.key] = value
+              }
             }
           }
-        }
 
-        if (method.type === "oauth") {
-          const authorize = await method.authorize(inputs)
-
-          if (authorize.url) {
-            prompts.log.info("Go to: " + authorize.url)
-          }
+          if (method.type === "oauth") {
+            const authorize = await method.authorize(inputs)
 
-          if (authorize.method === "auto") {
-            if (authorize.instructions) {
-              prompts.log.info(authorize.instructions)
+            if (authorize.url) {
+              prompts.log.info("Go to: " + authorize.url)
             }
-            const spinner = prompts.spinner()
-            spinner.start("Waiting for authorization...")
-            const result = await authorize.callback()
-            if (result.type === "failed") {
-              spinner.stop("Failed to authorize", 1)
+
+            if (authorize.method === "auto") {
+              if (authorize.instructions) {
+                prompts.log.info(authorize.instructions)
+              }
+              const spinner = prompts.spinner()
+              spinner.start("Waiting for authorization...")
+              const result = await authorize.callback()
+              if (result.type === "failed") {
+                spinner.stop("Failed to authorize", 1)
+              }
+              if (result.type === "success") {
+                const saveProvider = result.provider ?? provider
+                if ("refresh" in result) {
+                  const { type: _, provider: __, refresh, access, expires, ...extraFields } = result
+                  await Auth.set(saveProvider, {
+                    type: "oauth",
+                    refresh,
+                    access,
+                    expires,
+                    ...extraFields,
+                  })
+                }
+                if ("key" in result) {
+                  await Auth.set(saveProvider, {
+                    type: "api",
+                    key: result.key,
+                  })
+                }
+                spinner.stop("Login successful")
+              }
             }
-            if (result.type === "success") {
-              const saveProvider = result.provider ?? provider
-              if ("refresh" in result) {
-                const { type: _, provider: __, refresh, access, expires, ...extraFields } = result
-                await Auth.set(saveProvider, {
-                  type: "oauth",
-                  refresh,
-                  access,
-                  expires,
-                  ...extraFields,
-                })
+
+            if (authorize.method === "code") {
+              const code = await prompts.text({
+                message: "Paste the authorization code here: ",
+                validate: (x) => (x && x.length > 0 ? undefined : "Required"),
+              })
+              if (prompts.isCancel(code)) throw new UI.CancelledError()
+              const result = await authorize.callback(code)
+              if (result.type === "failed") {
+                prompts.log.error("Failed to authorize")
               }
-              if ("key" in result) {
-                await Auth.set(saveProvider, {
-                  type: "api",
-                  key: result.key,
-                })
+              if (result.type === "success") {
+                const saveProvider = result.provider ?? provider
+                if ("refresh" in result) {
+                  const { type: _, provider: __, refresh, access, expires, ...extraFields } = result
+                  await Auth.set(saveProvider, {
+                    type: "oauth",
+                    refresh,
+                    access,
+                    expires,
+                    ...extraFields,
+                  })
+                }
+                if ("key" in result) {
+                  await Auth.set(saveProvider, {
+                    type: "api",
+                    key: result.key,
+                  })
+                }
+                prompts.log.success("Login successful")
               }
-              spinner.stop("Login successful")
             }
+
+            prompts.outro("Done")
+            return
           }
 
-          if (authorize.method === "code") {
-            const code = await prompts.text({
-              message: "Paste the authorization code here: ",
-              validate: (x) => (x && x.length > 0 ? undefined : "Required"),
-            })
-            if (prompts.isCancel(code)) throw new UI.CancelledError()
-            const result = await authorize.callback(code)
-            if (result.type === "failed") {
-              prompts.log.error("Failed to authorize")
-            }
-            if (result.type === "success") {
-              const saveProvider = result.provider ?? provider
-              if ("refresh" in result) {
-                const { type: _, provider: __, refresh, access, expires, ...extraFields } = result
-                await Auth.set(saveProvider, {
-                  type: "oauth",
-                  refresh,
-                  access,
-                  expires,
-                  ...extraFields,
-                })
+          if (method.type === "api") {
+            if (method.authorize) {
+              const result = await method.authorize(inputs)
+              if (result.type === "failed") {
+                prompts.log.error("Failed to authorize")
               }
-              if ("key" in result) {
+              if (result.type === "success") {
+                const saveProvider = result.provider ?? provider
                 await Auth.set(saveProvider, {
                   type: "api",
                   key: result.key,
                 })
+                prompts.log.success("Login successful")
               }
-              prompts.log.success("Login successful")
+              prompts.outro("Done")
+              return
             }
           }
+        }
 
+        if (provider === "other") {
+          provider = await prompts.text({
+            message: "Enter provider id",
+            validate: (x) =>
+              x && x.match(/^[0-9a-z-]+$/) ? undefined : "a-z, 0-9 and hyphens only",
+          })
+          if (prompts.isCancel(provider)) throw new UI.CancelledError()
+          provider = provider.replace(/^@ai-sdk\//, "")
+          if (prompts.isCancel(provider)) throw new UI.CancelledError()
+          prompts.log.warn(
+            `This only stores a credential for ${provider} - you will need configure it in opencode.json, check the docs for examples.`,
+          )
+        }
+
+        if (provider === "amazon-bedrock") {
+          prompts.log.info(
+            "Amazon bedrock can be configured with standard AWS environment variables like AWS_BEARER_TOKEN_BEDROCK, AWS_PROFILE or AWS_ACCESS_KEY_ID",
+          )
           prompts.outro("Done")
           return
         }
 
-        if (method.type === "api") {
-          if (method.authorize) {
-            const result = await method.authorize(inputs)
-            if (result.type === "failed") {
-              prompts.log.error("Failed to authorize")
-            }
-            if (result.type === "success") {
-              const saveProvider = result.provider ?? provider
-              await Auth.set(saveProvider, {
-                type: "api",
-                key: result.key,
-              })
-              prompts.log.success("Login successful")
-            }
-            prompts.outro("Done")
-            return
-          }
+        if (provider === "opencode") {
+          prompts.log.info("Create an api key at https://opencode.ai/auth")
+        }
+
+        if (provider === "vercel") {
+          prompts.log.info("You can create an api key at https://vercel.link/ai-gateway-token")
         }
-      }
 
-      if (provider === "other") {
-        provider = await prompts.text({
-          message: "Enter provider id",
-          validate: (x) => (x && x.match(/^[0-9a-z-]+$/) ? undefined : "a-z, 0-9 and hyphens only"),
+        const key = await prompts.password({
+          message: "Enter your API key",
+          validate: (x) => (x && x.length > 0 ? undefined : "Required"),
+        })
+        if (prompts.isCancel(key)) throw new UI.CancelledError()
+        await Auth.set(provider, {
+          type: "api",
+          key,
         })
-        if (prompts.isCancel(provider)) throw new UI.CancelledError()
-        provider = provider.replace(/^@ai-sdk\//, "")
-        if (prompts.isCancel(provider)) throw new UI.CancelledError()
-        prompts.log.warn(
-          `This only stores a credential for ${provider} - you will need configure it in opencode.json, check the docs for examples.`,
-        )
-      }
 
-      if (provider === "amazon-bedrock") {
-        prompts.log.info(
-          "Amazon bedrock can be configured with standard AWS environment variables like AWS_BEARER_TOKEN_BEDROCK, AWS_PROFILE or AWS_ACCESS_KEY_ID",
-        )
         prompts.outro("Done")
-        return
-      }
-
-      if (provider === "opencode") {
-        prompts.log.info("Create an api key at https://opencode.ai/auth")
-      }
-
-      if (provider === "vercel") {
-        prompts.log.info("You can create an api key at https://vercel.link/ai-gateway-token")
-      }
-
-      const key = await prompts.password({
-        message: "Enter your API key",
-        validate: (x) => (x && x.length > 0 ? undefined : "Required"),
-      })
-      if (prompts.isCancel(key)) throw new UI.CancelledError()
-      await Auth.set(provider, {
-        type: "api",
-        key,
-      })
-
-      prompts.outro("Done")
       },
     })
   },

+ 5 - 1
packages/opencode/src/cli/cmd/debug/lsp.ts

@@ -7,7 +7,11 @@ import { EOL } from "os"
 export const LSPCommand = cmd({
   command: "lsp",
   builder: (yargs) =>
-    yargs.command(DiagnosticsCommand).command(SymbolsCommand).command(DocumentSymbolsCommand).demandCommand(),
+    yargs
+      .command(DiagnosticsCommand)
+      .command(SymbolsCommand)
+      .command(DocumentSymbolsCommand)
+      .demandCommand(),
   async handler() {},
 })
 

+ 5 - 2
packages/opencode/src/cli/cmd/debug/ripgrep.ts

@@ -6,7 +6,8 @@ import { cmd } from "../cmd"
 
 export const RipgrepCommand = cmd({
   command: "rg",
-  builder: (yargs) => yargs.command(TreeCommand).command(FilesCommand).command(SearchCommand).demandCommand(),
+  builder: (yargs) =>
+    yargs.command(TreeCommand).command(FilesCommand).command(SearchCommand).demandCommand(),
   async handler() {},
 })
 
@@ -18,7 +19,9 @@ const TreeCommand = cmd({
     }),
   async handler(args) {
     await bootstrap(process.cwd(), async () => {
-      process.stdout.write(await Ripgrep.tree({ cwd: Instance.directory, limit: args.limit }) + EOL)
+      process.stdout.write(
+        (await Ripgrep.tree({ cwd: Instance.directory, limit: args.limit })) + EOL,
+      )
     })
   },
 })

+ 2 - 1
packages/opencode/src/cli/cmd/debug/snapshot.ts

@@ -4,7 +4,8 @@ import { cmd } from "../cmd"
 
 export const SnapshotCommand = cmd({
   command: "snapshot",
-  builder: (yargs) => yargs.command(TrackCommand).command(PatchCommand).command(DiffCommand).demandCommand(),
+  builder: (yargs) =>
+    yargs.command(TrackCommand).command(PatchCommand).command(DiffCommand).demandCommand(),
   async handler() {},
 })
 

+ 1 - 1
packages/opencode/src/cli/cmd/generate.ts

@@ -6,7 +6,7 @@ export const GenerateCommand = {
   handler: async () => {
     const specs = await Server.openapi()
     const json = JSON.stringify(specs, null, 2)
-    
+
     // Wait for stdout to finish writing before process.exit() is called
     await new Promise<void>((resolve, reject) => {
       process.stdout.write(json, (err) => {

+ 45 - 15
packages/opencode/src/cli/cmd/github.ts

@@ -189,7 +189,9 @@ export const GithubInstallCommand = cmd({
           async function getAppInfo() {
             const project = Instance.project
             if (project.vcs !== "git") {
-              prompts.log.error(`Could not find git repository. Please run this command from a git repository.`)
+              prompts.log.error(
+                `Could not find git repository. Please run this command from a git repository.`,
+              )
               throw new UI.CancelledError()
             }
 
@@ -202,9 +204,13 @@ export const GithubInstallCommand = cmd({
             // ie. [email protected]:sst/opencode
             // ie. ssh://[email protected]/sst/opencode.git
             // ie. ssh://[email protected]/sst/opencode
-            const parsed = info.match(/^(?:(?:https?|ssh):\/\/)?(?:git@)?github\.com[:/]([^/]+)\/([^/.]+?)(?:\.git)?$/)
+            const parsed = info.match(
+              /^(?:(?:https?|ssh):\/\/)?(?:git@)?github\.com[:/]([^/]+)\/([^/.]+?)(?:\.git)?$/,
+            )
             if (!parsed) {
-              prompts.log.error(`Could not find git repository. Please run this command from a git repository.`)
+              prompts.log.error(
+                `Could not find git repository. Please run this command from a git repository.`,
+              )
               throw new UI.CancelledError()
             }
             const [, owner, repo] = parsed
@@ -445,7 +451,9 @@ export const GithubRunCommand = cmd({
               const summary = await summarize(response)
               await pushToLocalBranch(summary)
             }
-            const hasShared = prData.comments.nodes.some((c) => c.body.includes(`${shareBaseUrl}/s/${shareId}`))
+            const hasShared = prData.comments.nodes.some((c) =>
+              c.body.includes(`${shareBaseUrl}/s/${shareId}`),
+            )
             await updateComment(`${response}${footer({ image: !hasShared })}`)
           }
           // Fork PR
@@ -457,7 +465,9 @@ export const GithubRunCommand = cmd({
               const summary = await summarize(response)
               await pushToForkBranch(summary, prData)
             }
-            const hasShared = prData.comments.nodes.some((c) => c.body.includes(`${shareBaseUrl}/s/${shareId}`))
+            const hasShared = prData.comments.nodes.some((c) =>
+              c.body.includes(`${shareBaseUrl}/s/${shareId}`),
+            )
             await updateComment(`${response}${footer({ image: !hasShared })}`)
           }
         }
@@ -547,8 +557,12 @@ export const GithubRunCommand = cmd({
         // ie. <img alt="Image" src="https://github.com/user-attachments/assets/xxxx" />
         // ie. [api.json](https://github.com/user-attachments/files/21433810/api.json)
         // ie. ![Image](https://github.com/user-attachments/assets/xxxx)
-        const mdMatches = prompt.matchAll(/!?\[.*?\]\((https:\/\/github\.com\/user-attachments\/[^)]+)\)/gi)
-        const tagMatches = prompt.matchAll(/<img .*?src="(https:\/\/github\.com\/user-attachments\/[^"]+)" \/>/gi)
+        const mdMatches = prompt.matchAll(
+          /!?\[.*?\]\((https:\/\/github\.com\/user-attachments\/[^)]+)\)/gi,
+        )
+        const tagMatches = prompt.matchAll(
+          /<img .*?src="(https:\/\/github\.com\/user-attachments\/[^"]+)" \/>/gi,
+        )
         const matches = [...mdMatches, ...tagMatches].sort((a, b) => a.index - b.index)
         console.log("Images", JSON.stringify(matches, null, 2))
 
@@ -573,7 +587,10 @@ export const GithubRunCommand = cmd({
 
           // Replace img tag with file path, ie. @image.png
           const replacement = `@${filename}`
-          prompt = prompt.slice(0, start + offset) + replacement + prompt.slice(start + offset + tag.length)
+          prompt =
+            prompt.slice(0, start + offset) +
+            replacement +
+            prompt.slice(start + offset + tag.length)
           offset += replacement.length - tag.length
 
           const contentType = res.headers.get("content-type")
@@ -856,7 +873,8 @@ Co-authored-by: ${actor} <${actor}@users.noreply.github.com>"`
           throw new Error(`Failed to check permissions for user ${actor}: ${error}`)
         }
 
-        if (!["admin", "write"].includes(permission)) throw new Error(`User ${actor} does not have write permissions`)
+        if (!["admin", "write"].includes(permission))
+          throw new Error(`User ${actor} does not have write permissions`)
       }
 
       async function createComment() {
@@ -904,7 +922,9 @@ Co-authored-by: ${actor} <${actor}@users.noreply.github.com>"`
 
           return `<a href="${shareBaseUrl}/s/${shareId}"><img width="200" alt="${titleAlt}" src="https://social-cards.sst.dev/opencode-share/${title64}.png?model=${providerID}/${modelID}&version=${session.version}&id=${shareId}" /></a>\n`
         })()
-        const shareUrl = shareId ? `[opencode session](${shareBaseUrl}/s/${shareId})&nbsp;&nbsp;|&nbsp;&nbsp;` : ""
+        const shareUrl = shareId
+          ? `[opencode session](${shareBaseUrl}/s/${shareId})&nbsp;&nbsp;|&nbsp;&nbsp;`
+          : ""
         return `\n\n${image}${shareUrl}[github run](${runUrl})`
       }
 
@@ -1080,9 +1100,13 @@ query($owner: String!, $repo: String!, $number: Int!) {
           })
           .map((c) => `- ${c.author.login} at ${c.createdAt}: ${c.body}`)
 
-        const files = (pr.files.nodes || []).map((f) => `- ${f.path} (${f.changeType}) +${f.additions}/-${f.deletions}`)
+        const files = (pr.files.nodes || []).map(
+          (f) => `- ${f.path} (${f.changeType}) +${f.additions}/-${f.deletions}`,
+        )
         const reviewData = (pr.reviews.nodes || []).map((r) => {
-          const comments = (r.comments.nodes || []).map((c) => `    - ${c.path}:${c.line ?? "?"}: ${c.body}`)
+          const comments = (r.comments.nodes || []).map(
+            (c) => `    - ${c.path}:${c.line ?? "?"}: ${c.body}`,
+          )
           return [
             `- ${r.author.login} at ${r.submittedAt}:`,
             `  - Review body: ${r.body}`,
@@ -1104,9 +1128,15 @@ query($owner: String!, $repo: String!, $number: Int!) {
           `Deletions: ${pr.deletions}`,
           `Total Commits: ${pr.commits.totalCount}`,
           `Changed Files: ${pr.files.nodes.length} files`,
-          ...(comments.length > 0 ? ["<pull_request_comments>", ...comments, "</pull_request_comments>"] : []),
-          ...(files.length > 0 ? ["<pull_request_changed_files>", ...files, "</pull_request_changed_files>"] : []),
-          ...(reviewData.length > 0 ? ["<pull_request_reviews>", ...reviewData, "</pull_request_reviews>"] : []),
+          ...(comments.length > 0
+            ? ["<pull_request_comments>", ...comments, "</pull_request_comments>"]
+            : []),
+          ...(files.length > 0
+            ? ["<pull_request_changed_files>", ...files, "</pull_request_changed_files>"]
+            : []),
+          ...(reviewData.length > 0
+            ? ["<pull_request_reviews>", ...reviewData, "</pull_request_reviews>"]
+            : []),
           "</pull_request>",
         ].join("\n")
       }

+ 14 - 4
packages/opencode/src/cli/cmd/run.ts

@@ -137,7 +137,9 @@ export const RunCommand = cmd({
 
       const outputJsonEvent = (type: string, data: any) => {
         if (args.format === "json") {
-          process.stdout.write(JSON.stringify({ type, timestamp: Date.now(), sessionID, ...data }) + EOL)
+          process.stdout.write(
+            JSON.stringify({ type, timestamp: Date.now(), sessionID, ...data }) + EOL,
+          )
           return true
         }
         return false
@@ -157,7 +159,9 @@ export const RunCommand = cmd({
               const [tool, color] = TOOL[part.tool] ?? [part.tool, UI.Style.TEXT_INFO_BOLD]
               const title =
                 part.state.title ||
-                (Object.keys(part.state.input).length > 0 ? JSON.stringify(part.state.input) : "Unknown")
+                (Object.keys(part.state.input).length > 0
+                  ? JSON.stringify(part.state.input)
+                  : "Unknown")
               printEvent(color, tool, title)
               if (part.tool === "bash" && part.state.output?.trim()) {
                 UI.println()
@@ -280,7 +284,10 @@ export const RunCommand = cmd({
       }
 
       const cfgResult = await sdk.config.get()
-      if (cfgResult.data && (cfgResult.data.share === "auto" || Flag.OPENCODE_AUTO_SHARE || args.share)) {
+      if (
+        cfgResult.data &&
+        (cfgResult.data.share === "auto" || Flag.OPENCODE_AUTO_SHARE || args.share)
+      ) {
         const shareResult = await sdk.session.share({ path: { id: sessionID } }).catch((error) => {
           if (error instanceof Error && error.message.includes("disabled")) {
             UI.println(UI.Style.TEXT_DANGER_BOLD + "!  " + error.message)
@@ -333,7 +340,10 @@ export const RunCommand = cmd({
       }
 
       const cfgResult = await sdk.config.get()
-      if (cfgResult.data && (cfgResult.data.share === "auto" || Flag.OPENCODE_AUTO_SHARE || args.share)) {
+      if (
+        cfgResult.data &&
+        (cfgResult.data.share === "auto" || Flag.OPENCODE_AUTO_SHARE || args.share)
+      ) {
         const shareResult = await sdk.session.share({ path: { id: sessionID } }).catch((error) => {
           if (error instanceof Error && error.message.includes("disabled")) {
             UI.println(UI.Style.TEXT_DANGER_BOLD + "!  " + error.message)

+ 5 - 1
packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx

@@ -52,7 +52,11 @@ export function DialogModel() {
               description: provider.name,
               category: provider.name,
             })),
-            filter((x) => Boolean(ref()?.filter) || !local.model.recent().find((y) => isDeepEqual(y, x.value))),
+            filter(
+              (x) =>
+                Boolean(ref()?.filter) ||
+                !local.model.recent().find((y) => isDeepEqual(y, x.value)),
+            ),
           ),
         ),
       ),

+ 2 - 2
packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx

@@ -20,8 +20,8 @@ export function DialogSessionList() {
 
   const deleteKeybind = "ctrl+d"
 
-  const currentSessionID = createMemo(() => 
-    route.data.type === "session" ? route.data.sessionID : undefined
+  const currentSessionID = createMemo(() =>
+    route.data.type === "session" ? route.data.sessionID : undefined,
   )
 
   const options = createMemo(() => {

+ 12 - 2
packages/opencode/src/cli/cmd/tui/component/logo.tsx

@@ -3,9 +3,19 @@ import { TextAttributes } from "@opentui/core"
 import { For } from "solid-js"
 import { useTheme } from "@tui/context/theme"
 
-const LOGO_LEFT = [`                   `, `█▀▀█ █▀▀█ █▀▀█ █▀▀▄`, `█░░█ █░░█ █▀▀▀ █░░█`, `▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀  ▀`]
+const LOGO_LEFT = [
+  `                   `,
+  `█▀▀█ █▀▀█ █▀▀█ █▀▀▄`,
+  `█░░█ █░░█ █▀▀▀ █░░█`,
+  `▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀  ▀`,
+]
 
-const LOGO_RIGHT = [`             ▄     `, `█▀▀▀ █▀▀█ █▀▀█ █▀▀█`, `█░░░ █░░█ █░░█ █▀▀▀`, `▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀`]
+const LOGO_RIGHT = [
+  `             ▄     `,
+  `█▀▀▀ █▀▀█ █▀▀█ █▀▀█`,
+  `█░░░ █░░█ █░░█ █▀▀▀`,
+  `▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀`,
+]
 
 export function Logo() {
   const { theme } = useTheme()

+ 3 - 5
packages/opencode/src/cli/cmd/tui/context/route.tsx

@@ -17,13 +17,11 @@ export const { use: useRoute, provider: RouteProvider } = createSimpleContext({
   init: (props: { data?: Route }) => {
     const [store, setStore] = createStore<Route>(
       props.data ??
-      (
-        process.env["OPENCODE_ROUTE"]
+        (process.env["OPENCODE_ROUTE"]
           ? JSON.parse(process.env["OPENCODE_ROUTE"])
           : {
-            type: "home",
-          }
-      ),
+              type: "home",
+            }),
     )
 
     return {

+ 1 - 0
packages/opencode/src/cli/cmd/tui/context/sync.tsx

@@ -269,6 +269,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
         },
         async sync(sessionID: string) {
           const now = Date.now()
+          console.log("syncing", sessionID)
           const [session, messages, todo, diff] = await Promise.all([
             sdk.client.session.get({ path: { id: sessionID }, throwOnError: true }),
             sdk.client.session.messages({ path: { id: sessionID } }),

+ 1 - 1
packages/opencode/src/cli/cmd/tui/context/theme/nightowl.json

@@ -218,4 +218,4 @@
       "light": "nightOwlFg"
     }
   }
-}
+}

+ 3 - 1
packages/opencode/src/cli/cmd/tui/routes/session/dialog-message.tsx

@@ -7,7 +7,9 @@ import { useRoute } from "@tui/context/route"
 export function DialogMessage(props: { messageID: string; sessionID: string }) {
   const sync = useSync()
   const sdk = useSDK()
-  const message = createMemo(() => sync.data.message[props.sessionID]?.find((x) => x.id === props.messageID))
+  const message = createMemo(() =>
+    sync.data.message[props.sessionID]?.find((x) => x.id === props.messageID),
+  )
   const route = useRoute()
 
   return (

+ 10 - 2
packages/opencode/src/cli/cmd/tui/routes/session/dialog-timeline.tsx

@@ -19,7 +19,9 @@ export function DialogTimeline(props: { sessionID: string; onMove: (messageID: s
     const result = [] as DialogSelectOption<string>[]
     for (const message of messages) {
       if (message.role !== "user") continue
-      const part = (sync.data.part[message.id] ?? []).find((x) => x.type === "text" && !x.synthetic) as TextPart
+      const part = (sync.data.part[message.id] ?? []).find(
+        (x) => x.type === "text" && !x.synthetic,
+      ) as TextPart
       if (!part) continue
       result.push({
         title: part.text.replace(/\n/g, " "),
@@ -33,5 +35,11 @@ export function DialogTimeline(props: { sessionID: string; onMove: (messageID: s
     return result
   })
 
-  return <DialogSelect onMove={(option) => props.onMove(option.value)} title="Timeline" options={options()} />
+  return (
+    <DialogSelect
+      onMove={(option) => props.onMove(option.value)}
+      title="Timeline"
+      options={options()}
+    />
+  )
 }

+ 3 - 2
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx

@@ -105,14 +105,15 @@ export function Session() {
   const sidebarVisible = createMemo(() => sidebar() === "show" || (sidebar() === "auto" && wide()))
   const contentWidth = createMemo(() => dimensions().width - (sidebarVisible() ? 42 : 0) - 4)
 
-  createEffect(() => {
-    sync.session.sync(route.sessionID).catch(() => {
+  createEffect(async () => {
+    await sync.session.sync(route.sessionID).catch(() => {
       toast.show({
         message: `Session not found: ${route.sessionID}`,
         variant: "error",
       })
       return navigate({ type: "home" })
     })
+    scroll.scrollBy(100_000)
   })
 
   const toast = useToast()

+ 6 - 1
packages/opencode/src/cli/cmd/tui/spawn.ts

@@ -41,7 +41,12 @@ export const TuiSpawnCommand = cmd({
       )
       cwd = new URL("../../../../", import.meta.url).pathname
     } else cmd.push(process.execPath)
-    cmd.push("attach", server.url.toString(), "--dir", args.project ? path.resolve(args.project) : process.cwd())
+    cmd.push(
+      "attach",
+      server.url.toString(),
+      "--dir",
+      args.project ? path.resolve(args.project) : process.cwd(),
+    )
     const proc = Bun.spawn({
       cmd,
       cwd,

+ 3 - 1
packages/opencode/src/cli/cmd/tui/ui/dialog-confirm.tsx

@@ -53,7 +53,9 @@ export function DialogConfirm(props: DialogConfirmProps) {
                 dialog.clear()
               }}
             >
-              <text fg={key === store.active ? theme.background : theme.textMuted}>{Locale.titlecase(key)}</text>
+              <text fg={key === store.active ? theme.background : theme.textMuted}>
+                {Locale.titlecase(key)}
+              </text>
             </box>
           )}
         </For>

+ 4 - 1
packages/opencode/src/cli/cmd/tui/util/editor.ts

@@ -5,7 +5,10 @@ import { join } from "node:path"
 import { CliRenderer } from "@opentui/core"
 
 export namespace Editor {
-  export async function open(opts: { value: string; renderer: CliRenderer }): Promise<string | undefined> {
+  export async function open(opts: {
+    value: string
+    renderer: CliRenderer
+  }): Promise<string | undefined> {
     const editor = process.env["EDITOR"]
     if (!editor) return
 

+ 3 - 1
packages/opencode/src/cli/cmd/upgrade.ts

@@ -27,7 +27,9 @@ export const UpgradeCommand = {
     const detectedMethod = await Installation.method()
     const method = (args.method as Installation.Method) ?? detectedMethod
     if (method === "unknown") {
-      prompts.log.error(`opencode is installed to ${process.execPath} and may be managed by a package manager`)
+      prompts.log.error(
+        `opencode is installed to ${process.execPath} and may be managed by a package manager`,
+      )
       const install = await prompts.select({
         message: "Install anyways?",
         options: [

+ 4 - 1
packages/opencode/src/config/config.ts

@@ -574,7 +574,10 @@ export namespace Config {
                 .object({
                   apiKey: z.string().optional(),
                   baseURL: z.string().optional(),
-                  enterpriseUrl: z.string().optional().describe("GitHub Enterprise URL for copilot authentication"),
+                  enterpriseUrl: z
+                    .string()
+                    .optional()
+                    .describe("GitHub Enterprise URL for copilot authentication"),
                   timeout: z
                     .union([
                       z

+ 3 - 1
packages/opencode/src/file/fzf.ts

@@ -81,7 +81,9 @@ export namespace Fzf {
           })
       }
       if (config.extension === "zip") {
-        const zipFileReader = new ZipReader(new BlobReader(new Blob([await Bun.file(archivePath).arrayBuffer()])))
+        const zipFileReader = new ZipReader(
+          new BlobReader(new Blob([await Bun.file(archivePath).arrayBuffer()])),
+        )
         const entries = await zipFileReader.getEntries()
         let fzfEntry: any
         for (const entry of entries) {

+ 9 - 2
packages/opencode/src/file/ripgrep.ts

@@ -161,7 +161,9 @@ export namespace Ripgrep {
       }
       if (config.extension === "zip") {
         if (config.extension === "zip") {
-          const zipFileReader = new ZipReader(new BlobReader(new Blob([await Bun.file(archivePath).arrayBuffer()])))
+          const zipFileReader = new ZipReader(
+            new BlobReader(new Blob([await Bun.file(archivePath).arrayBuffer()])),
+          )
           const entries = await zipFileReader.getEntries()
           let rgEntry: any
           for (const entry of entries) {
@@ -354,7 +356,12 @@ export namespace Ripgrep {
     return lines.join("\n")
   }
 
-  export async function search(input: { cwd: string; pattern: string; glob?: string[]; limit?: number }) {
+  export async function search(input: {
+    cwd: string
+    pattern: string
+    glob?: string[]
+    limit?: number
+  }) {
     const args = [`${await filepath()}`, "--json", "--hidden", "--glob='!.git/*'"]
 
     if (input.glob) {

+ 4 - 1
packages/opencode/src/file/time.ts

@@ -27,7 +27,10 @@ export namespace FileTime {
 
   export async function assert(sessionID: string, filepath: string) {
     const time = get(sessionID, filepath)
-    if (!time) throw new Error(`You must read the file ${filepath} before overwriting it. Use the Read tool first`)
+    if (!time)
+      throw new Error(
+        `You must read the file ${filepath} before overwriting it. Use the Read tool first`,
+      )
     const stats = await Bun.file(filepath).stat()
     if (stats.mtime.getTime() > time.getTime()) {
       throw new Error(

+ 4 - 2
packages/opencode/src/file/watcher.ts

@@ -51,8 +51,10 @@ export namespace FileWatcher {
           for (const evt of evts) {
             log.info("event", evt)
             if (evt.type === "create") Bus.publish(Event.Updated, { file: evt.path, event: "add" })
-            if (evt.type === "update") Bus.publish(Event.Updated, { file: evt.path, event: "change" })
-            if (evt.type === "delete") Bus.publish(Event.Updated, { file: evt.path, event: "unlink" })
+            if (evt.type === "update")
+              Bus.publish(Event.Updated, { file: evt.path, event: "change" })
+            if (evt.type === "delete")
+              Bus.publish(Event.Updated, { file: evt.path, event: "unlink" })
           }
         },
         {

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác