Adam 3 месяцев назад
Родитель
Сommit
3d43214075

+ 2 - 2
packages/desktop/src/components/file-tree.tsx

@@ -19,7 +19,7 @@ export default function FileTree(props: {
       component={p.as ?? "div"}
       classList={{
         "p-0.5 w-full flex items-center gap-x-2 hover:bg-background-element": true,
-        "bg-background-element": local.file.active()?.path === p.node.path,
+        // "bg-background-element": local.file.active()?.path === p.node.path,
         [props.nodeClass ?? ""]: !!props.nodeClass,
       }}
       style={`padding-left: ${level * 10}px`}
@@ -55,7 +55,7 @@ export default function FileTree(props: {
           "text-xs whitespace-nowrap truncate": true,
           "text-text-muted/40": p.node.ignored,
           "text-text-muted/80": !p.node.ignored,
-          "!text-text": local.file.active()?.path === p.node.path,
+          // "!text-text": local.file.active()?.path === p.node.path,
           "!text-primary": local.file.changed(p.node.path),
         }}
       >

+ 108 - 170
packages/desktop/src/context/local.tsx

@@ -1,16 +1,7 @@
 import { createStore, produce, reconcile } from "solid-js/store"
 import { batch, createEffect, createMemo } from "solid-js"
-import { pipe, sumBy, uniqueBy } from "remeda"
-import type {
-  FileContent,
-  FileNode,
-  Model,
-  Provider,
-  File as FileStatus,
-  Part,
-  Message,
-  AssistantMessage,
-} from "@opencode-ai/sdk"
+import { uniqueBy } from "remeda"
+import type { FileContent, FileNode, Model, Provider, File as FileStatus } from "@opencode-ai/sdk"
 import { createSimpleContext } from "./helper"
 import { useSDK } from "./sdk"
 import { useSync } from "./sync"
@@ -204,18 +195,18 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
     const file = (() => {
       const [store, setStore] = createStore<{
         node: Record<string, LocalFile>
-        opened: string[]
-        active?: string
+        // opened: string[]
+        // active?: string
       }>({
         node: Object.fromEntries(sync.data.node.map((x) => [x.path, x])),
-        opened: [],
+        // opened: [],
       })
 
-      const active = createMemo(() => {
-        if (!store.active) return undefined
-        return store.node[store.active]
-      })
-      const opened = createMemo(() => store.opened.map((x) => store.node[x]))
+      // const active = createMemo(() => {
+      //   if (!store.active) return undefined
+      //   return store.node[store.active]
+      // })
+      // const opened = createMemo(() => store.opened.map((x) => store.node[x]))
       const changeset = createMemo(() => new Set(sync.data.changes.map((f) => f.path)))
       const changes = createMemo(() => Array.from(changeset()).sort((a, b) => a.localeCompare(b)))
 
@@ -303,16 +294,16 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
       const open = async (path: string, options?: { pinned?: boolean; view?: LocalFile["view"] }) => {
         const relativePath = relative(path)
         if (!store.node[relativePath]) await fetch(path)
-        setStore("opened", (x) => {
-          if (x.includes(relativePath)) return x
-          return [
-            ...opened()
-              .filter((x) => x.pinned)
-              .map((x) => x.path),
-            relativePath,
-          ]
-        })
-        setStore("active", relativePath)
+        // setStore("opened", (x) => {
+        //   if (x.includes(relativePath)) return x
+        //   return [
+        //     ...opened()
+        //       .filter((x) => x.pinned)
+        //       .map((x) => x.path),
+        //     relativePath,
+        //   ]
+        // })
+        // setStore("active", relativePath)
         context.addActive()
         if (options?.pinned) setStore("node", path, "pinned", true)
         if (options?.view && store.node[relativePath].view === undefined) setStore("node", path, "view", options.view)
@@ -363,22 +354,11 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
       })
 
       return {
-        active,
-        opened,
         node: (path: string) => store.node[path],
         update: (path: string, node: LocalFile) => setStore("node", path, reconcile(node)),
         open,
         load,
         init,
-        close(path: string) {
-          setStore("opened", (opened) => opened.filter((x) => x !== path))
-          if (store.active === path) {
-            const index = store.opened.findIndex((f) => f === path)
-            const previous = store.opened[Math.max(0, index - 1)]
-            setStore("active", previous)
-          }
-          resetNode(path)
-        },
         expand(path: string) {
           setStore("node", path, "expanded", true)
           if (store.node[path].loaded) return
@@ -394,17 +374,6 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
         scroll(path: string, scrollTop: number) {
           setStore("node", path, "scrollTop", scrollTop)
         },
-        move(path: string, to: number) {
-          const index = store.opened.findIndex((f) => f === path)
-          if (index === -1) return
-          setStore(
-            "opened",
-            produce((opened) => {
-              opened.splice(to, 0, opened.splice(index, 1)[0])
-            }),
-          )
-          setStore("node", path, "pinned", true)
-        },
         view(path: string): View {
           const n = store.node[path]
           return n && n.view ? n.view : "raw"
@@ -444,14 +413,48 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
         },
         search,
         relative,
+        // active,
+        // opened,
+        // close(path: string) {
+        //   setStore("opened", (opened) => opened.filter((x) => x !== path))
+        //   if (store.active === path) {
+        //     const index = store.opened.findIndex((f) => f === path)
+        //     const previous = store.opened[Math.max(0, index - 1)]
+        //     setStore("active", previous)
+        //   }
+        //   resetNode(path)
+        // },
+        // move(path: string, to: number) {
+        //   const index = store.opened.findIndex((f) => f === path)
+        //   if (index === -1) return
+        //   setStore(
+        //     "opened",
+        //     produce((opened) => {
+        //       opened.splice(to, 0, opened.splice(index, 1)[0])
+        //     }),
+        //   )
+        //   setStore("node", path, "pinned", true)
+        // },
       }
     })()
 
     const session = (() => {
       const [store, setStore] = createStore<{
         active?: string
-        activeMessage?: string
-      }>({})
+        tabs: Record<
+          string,
+          {
+            active?: string
+            opened: string[]
+          }
+        >
+      }>({
+        tabs: {
+          "": {
+            opened: [],
+          },
+        },
+      })
 
       const active = createMemo(() => {
         if (!store.active) return undefined
@@ -461,134 +464,69 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
       createEffect(() => {
         if (!store.active) return
         sync.session.sync(store.active)
-      })
 
-      const valid = (part: Part) => {
-        if (!part) return false
-        switch (part.type) {
-          case "step-start":
-          case "step-finish":
-          case "file":
-          case "patch":
-            return false
-          case "text":
-            return !part.synthetic && part.text.trim()
-          case "reasoning":
-            return part.text.trim()
-          case "tool":
-            switch (part.tool) {
-              case "todoread":
-              case "todowrite":
-              case "list":
-              case "grep":
-                return false
-            }
-            return true
-          default:
-            return true
+        if (!store.tabs[store.active]) {
+          setStore("tabs", store.active, {
+            opened: [],
+          })
         }
-      }
-
-      const hasValidParts = (message: Message) => {
-        return sync.data.part[message.id]?.filter(valid).length > 0
-      }
-      // const hasTextPart = (message: Message) => {
-      //   return !!sync.data.part[message.id]?.filter(valid).find((p) => p.type === "text")
-      // }
-
-      const messages = createMemo(() => (store.active ? (sync.data.message[store.active] ?? []) : []))
-      const messagesWithValidParts = createMemo(() => messages().filter(hasValidParts) ?? [])
-      const userMessages = createMemo(() =>
-        messages()
-          .filter((m) => m.role === "user")
-          .sort((a, b) => b.id.localeCompare(a.id)),
-      )
-
-      const cost = createMemo(() => {
-        const total = pipe(
-          messages(),
-          sumBy((x) => (x.role === "assistant" ? x.cost : 0)),
-        )
-        return new Intl.NumberFormat("en-US", {
-          style: "currency",
-          currency: "USD",
-        }).format(total)
-      })
-
-      const last = createMemo(() => {
-        return messages().findLast((x) => x.role === "assistant") as AssistantMessage
-      })
-
-      const lastUserMessage = createMemo(() => {
-        return userMessages()?.at(0)
-      })
-
-      const activeMessage = createMemo(() => {
-        if (!store.active || !store.activeMessage) return lastUserMessage()
-        return sync.data.message[store.active]?.find((m) => m.id === store.activeMessage)
-      })
-
-      const model = createMemo(() => {
-        if (!last()) return
-        const model = sync.data.provider.find((x) => x.id === last().providerID)?.models[last().modelID]
-        return model
       })
 
-      const tokens = createMemo(() => {
-        if (!last()) return
-        const tokens = last().tokens
-        const total = tokens.input + tokens.output + tokens.reasoning + tokens.cache.read + tokens.cache.write
-        return new Intl.NumberFormat("en-US", {
-          notation: "compact",
-          compactDisplay: "short",
-        }).format(total)
-      })
-
-      const context = createMemo(() => {
-        if (!last()) return
-        if (!model()?.limit.context) return 0
-        const tokens = last().tokens
-        const total = tokens.input + tokens.output + tokens.reasoning + tokens.cache.read + tokens.cache.write
-        return Math.round((total / model()!.limit.context) * 100)
-      })
-
-      const getMessageText = (message: Message | Message[] | undefined): string => {
-        if (!message) return ""
-        if (Array.isArray(message)) return message.map((m) => getMessageText(m)).join(" ")
-        return sync.data.part[message.id]
-          ?.filter((p) => p.type === "text")
-          ?.filter((p) => !p.synthetic)
-          .map((p) => p.text)
-          .join(" ")
-      }
+      const tabs = createMemo(() => store.tabs[store.active ?? ""])
 
       return {
         active,
-        activeMessage,
-        lastUserMessage,
-        cost,
-        last,
-        model,
-        tokens,
-        context,
-        messages,
-        messagesWithValidParts,
-        userMessages,
-        // working,
-        getMessageText,
         setActive(sessionId: string | undefined) {
           setStore("active", sessionId)
-          setStore("activeMessage", undefined)
         },
         clearActive() {
           setStore("active", undefined)
-          setStore("activeMessage", undefined)
         },
-        setActiveMessage(messageId: string | undefined) {
-          setStore("activeMessage", messageId)
+        tabs,
+        copyTabs(from: string, to: string) {
+          setStore("tabs", to, {
+            opened: store.tabs[from]?.opened ?? [],
+          })
+        },
+        setActiveTab(tab: string | undefined) {
+          setStore("tabs", store.active ?? "", "active", tab)
+        },
+        async open(tab: string) {
+          if (tab !== "chat") {
+            await file.open(tab)
+          }
+          if (!tabs()?.opened?.includes(tab)) {
+            setStore("tabs", store.active ?? "", "opened", [...(tabs()?.opened ?? []), tab])
+          }
+          setStore("tabs", store.active ?? "", "active", tab)
         },
-        clearActiveMessage() {
-          setStore("activeMessage", undefined)
+        close(tab: string) {
+          batch(() => {
+            if (!tabs()) return
+            setStore("tabs", store.active ?? "", {
+              active: tabs()!.active,
+              opened: tabs()!.opened.filter((x) => x !== tab),
+            })
+            if (tabs()!.active === tab) {
+              const index = tabs()!.opened.findIndex((f) => f === tab)
+              const previous = tabs()!.opened[Math.max(0, index - 1)]
+              setStore("tabs", store.active ?? "", "active", previous)
+            }
+          })
+        },
+        move(tab: string, to: number) {
+          if (!tabs()) return
+          const index = tabs()!.opened.findIndex((f) => f === tab)
+          if (index === -1) return
+          setStore(
+            "tabs",
+            store.active ?? "",
+            "opened",
+            produce((opened) => {
+              opened.splice(to, 0, opened.splice(index, 1)[0])
+            }),
+          )
+          // setStore("node", path, "pinned", true)
         },
       }
     })()
@@ -611,9 +549,9 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
         all() {
           return store.items
         },
-        active() {
-          return store.activeTab ? file.active() : undefined
-        },
+        // active() {
+        //   return store.activeTab ? file.active() : undefined
+        // },
         addActive() {
           setStore("activeTab", true)
         },

+ 323 - 340
packages/desktop/src/pages/index.tsx

@@ -10,10 +10,10 @@ import {
   Diff,
   Collapsible,
   DiffChanges,
-  ProgressCircle,
   Message,
   Typewriter,
   Card,
+  Code,
 } from "@opencode-ai/ui"
 import { FileIcon } from "@/ui"
 import FileTree from "@/components/file-tree"
@@ -35,7 +35,6 @@ import {
 } from "@thisbeyond/solid-dnd"
 import type { DragEvent, Transformer } from "@thisbeyond/solid-dnd"
 import type { JSX } from "solid-js"
-import { Code } from "@/components/code"
 import { useSync } from "@/context/sync"
 import { useSDK } from "@/context/sdk"
 import { type AssistantMessage as AssistantMessageType } from "@opencode-ai/sdk"
@@ -54,14 +53,6 @@ export default function Page() {
   let messageScrollElement!: HTMLDivElement
   const [activeItem, setActiveItem] = createSignal<string | undefined>(undefined)
 
-  createEffect(() => {
-    // Set first message as active if none selected
-    const userMessages = local.session.userMessages()
-    if (userMessages.length > 0 && !local.session.activeMessage()) {
-      local.session.setActiveMessage(userMessages[0].id)
-    }
-  })
-
   const MOD = typeof navigator === "object" && /(Mac|iPod|iPhone|iPad)/.test(navigator.platform) ? "Meta" : "Control"
 
   onMount(() => {
@@ -91,26 +82,26 @@ export default function Page() {
       return
     }
 
-    if (local.file.active()) {
-      const active = local.file.active()!
-      if (event.key === "Enter" && active.selection) {
-        local.context.add({
-          type: "file",
-          path: active.path,
-          selection: { ...active.selection },
-        })
-        return
-      }
-
-      if (event.getModifierState(MOD)) {
-        if (event.key.toLowerCase() === "a") {
-          return
-        }
-        if (event.key.toLowerCase() === "c") {
-          return
-        }
-      }
-    }
+    // if (local.file.active()) {
+    //   const active = local.file.active()!
+    //   if (event.key === "Enter" && active.selection) {
+    //     local.context.add({
+    //       type: "file",
+    //       path: active.path,
+    //       selection: { ...active.selection },
+    //     })
+    //     return
+    //   }
+    //
+    //   if (event.getModifierState(MOD)) {
+    //     if (event.key.toLowerCase() === "a") {
+    //       return
+    //     }
+    //     if (event.key.toLowerCase() === "c") {
+    //       return
+    //     }
+    //   }
+    // }
 
     if (event.key.length === 1 && event.key !== "Unidentified" && !(event.ctrlKey || event.metaKey)) {
       inputRef?.focus()
@@ -140,21 +131,22 @@ export default function Page() {
     }
   }
 
-  const navigateChange = (dir: 1 | -1) => {
-    const active = local.file.active()
-    if (!active) return
-    const current = local.file.changeIndex(active.path)
-    const next = current === undefined ? (dir === 1 ? 0 : -1) : current + dir
-    local.file.setChangeIndex(active.path, next)
-  }
+  // const navigateChange = (dir: 1 | -1) => {
+  //   const active = local.file.active()
+  //   if (!active) return
+  //   const current = local.file.changeIndex(active.path)
+  //   const next = current === undefined ? (dir === 1 ? 0 : -1) : current + dir
+  //   local.file.setChangeIndex(active.path, next)
+  // }
 
   const handleTabChange = (path: string) => {
-    if (path === "chat" || path === "review") return
-    local.file.open(path)
+    local.session.setActiveTab(path)
+    if (path === "chat") return
+    local.session.open(path)
   }
 
   const handleTabClose = (file: LocalFile) => {
-    local.file.close(file.path)
+    local.session.close(file.path)
   }
 
   const handleDragStart = (event: unknown) => {
@@ -166,11 +158,11 @@ export default function Page() {
   const handleDragOver = (event: DragEvent) => {
     const { draggable, droppable } = event
     if (draggable && droppable) {
-      const currentFiles = local.file.opened().map((file) => file.path)
-      const fromIndex = currentFiles.indexOf(draggable.id.toString())
-      const toIndex = currentFiles.indexOf(droppable.id.toString())
-      if (fromIndex !== toIndex) {
-        local.file.move(draggable.id.toString(), toIndex)
+      const currentFiles = local.session.tabs()?.opened.map((file) => file)
+      const fromIndex = currentFiles?.indexOf(draggable.id.toString())
+      const toIndex = currentFiles?.indexOf(droppable.id.toString())
+      if (fromIndex !== toIndex && toIndex !== undefined) {
+        local.session.move(draggable.id.toString(), toIndex)
       }
     }
   }
@@ -179,20 +171,20 @@ export default function Page() {
     setActiveItem(undefined)
   }
 
-  const scrollDiffItem = (element: HTMLElement) => {
-    element.scrollIntoView({ block: "start", behavior: "instant" })
-  }
+  // const scrollDiffItem = (element: HTMLElement) => {
+  //   element.scrollIntoView({ block: "start", behavior: "instant" })
+  // }
 
   const handleDiffTriggerClick = (event: MouseEvent) => {
     // disabling scroll to diff for now
     return
-    const target = event.currentTarget as HTMLElement
-    queueMicrotask(() => {
-      if (target.getAttribute("aria-expanded") !== "true") return
-      const item = target.closest('[data-slot="accordion-item"]') as HTMLElement | null
-      if (!item) return
-      scrollDiffItem(item)
-    })
+    // const target = event.currentTarget as HTMLElement
+    // queueMicrotask(() => {
+    //   if (target.getAttribute("aria-expanded") !== "true") return
+    //   const item = target.closest('[data-slot="accordion-item"]') as HTMLElement | null
+    //   if (!item) return
+    //   scrollDiffItem(item)
+    // })
   }
 
   const handlePromptSubmit = async (parts: ContentPart[]) => {
@@ -205,6 +197,10 @@ export default function Page() {
     if (!session) return
 
     local.session.setActive(session.id)
+    if (!existingSession) {
+      local.session.copyTabs("", session.id)
+    }
+    local.session.setActiveTab(undefined)
     const toAbsolutePath = (path: string) => (path.startsWith("/") ? path : sync.absolute(path))
 
     const text = parts.map((part) => part.content).join("")
@@ -427,20 +423,26 @@ export default function Page() {
           >
             <DragDropSensors />
             <ConstrainDragYAxis />
-            <Tabs onChange={handleTabChange}>
+            <Tabs value={local.session.tabs()?.active ?? "chat"} onChange={handleTabChange}>
               <div class="sticky top-0 shrink-0 flex">
                 <Tabs.List>
                   <Tabs.Trigger value="chat" class="flex gap-x-4 items-center">
                     <div>Chat</div>
-                    <Tooltip value={`${local.session.tokens() ?? 0} Tokens`} class="flex items-center gap-1.5">
-                      <ProgressCircle percentage={local.session.context() ?? 0} />
-                      <div class="text-14-regular text-text-weak text-right">{local.session.context() ?? 0}%</div>
-                    </Tooltip>
+                    {/* <Tooltip value={`${local.session.tokens() ?? 0} Tokens`} class="flex items-center gap-1.5"> */}
+                    {/*   <ProgressCircle percentage={local.session.context() ?? 0} /> */}
+                    {/*   <div class="text-14-regular text-text-weak text-right">{local.session.context() ?? 0}%</div> */}
+                    {/* </Tooltip> */}
                   </Tabs.Trigger>
                   {/* <Tabs.Trigger value="review">Review</Tabs.Trigger> */}
-                  <SortableProvider ids={local.file.opened().map((file) => file.path)}>
-                    <For each={local.file.opened()}>
-                      {(file) => <SortableTab file={file} onTabClick={handleFileClick} onTabClose={handleTabClose} />}
+                  <SortableProvider ids={local.session.tabs()?.opened ?? []}>
+                    <For each={local.session.tabs()?.opened ?? []}>
+                      {(file) => (
+                        <SortableTab
+                          file={local.file.node(file)}
+                          onTabClick={handleFileClick}
+                          onTabClose={handleTabClose}
+                        />
+                      )}
                     </For>
                   </SortableProvider>
                   <div class="bg-background-base h-full flex items-center justify-center border-b border-border-weak-base px-3">
@@ -452,64 +454,6 @@ export default function Page() {
                     />
                   </div>
                 </Tabs.List>
-                <div class="hidden shrink-0 h-full _flex items-center gap-1 px-2 border-b border-border-subtle/40">
-                  <Show when={local.file.active() && local.file.active()!.content?.diff}>
-                    {(() => {
-                      const activeFile = local.file.active()!
-                      const view = local.file.view(activeFile.path)
-                      return (
-                        <div class="flex items-center gap-1">
-                          <Show when={view !== "raw"}>
-                            <div class="mr-1 flex items-center gap-1">
-                              <Tooltip value="Previous change" placement="bottom">
-                                <IconButton icon="arrow-up" variant="ghost" onClick={() => navigateChange(-1)} />
-                              </Tooltip>
-                              <Tooltip value="Next change" placement="bottom">
-                                <IconButton icon="arrow-down" variant="ghost" onClick={() => navigateChange(1)} />
-                              </Tooltip>
-                            </div>
-                          </Show>
-                          <Tooltip value="Raw" placement="bottom">
-                            <IconButton
-                              icon="file-text"
-                              variant="ghost"
-                              classList={{
-                                "text-text": view === "raw",
-                                "text-text-muted/70": view !== "raw",
-                                "bg-background-element": view === "raw",
-                              }}
-                              onClick={() => local.file.setView(activeFile.path, "raw")}
-                            />
-                          </Tooltip>
-                          <Tooltip value="Unified diff" placement="bottom">
-                            <IconButton
-                              icon="checklist"
-                              variant="ghost"
-                              classList={{
-                                "text-text": view === "diff-unified",
-                                "text-text-muted/70": view !== "diff-unified",
-                                "bg-background-element": view === "diff-unified",
-                              }}
-                              onClick={() => local.file.setView(activeFile.path, "diff-unified")}
-                            />
-                          </Tooltip>
-                          <Tooltip value="Split diff" placement="bottom">
-                            <IconButton
-                              icon="columns"
-                              variant="ghost"
-                              classList={{
-                                "text-text": view === "diff-split",
-                                "text-text-muted/70": view !== "diff-split",
-                                "bg-background-element": view === "diff-split",
-                              }}
-                              onClick={() => local.file.setView(activeFile.path, "diff-split")}
-                            />
-                          </Tooltip>
-                        </div>
-                      )
-                    })()}
-                  </Show>
-                </div>
               </div>
               <Tabs.Content value="chat" class="@container select-text flex flex-col flex-1 min-h-0 overflow-y-hidden">
                 <div class="relative px-6 pt-12 max-w-2xl w-full mx-auto flex flex-col flex-1 min-h-0">
@@ -537,250 +481,289 @@ export default function Page() {
                       </div>
                     }
                   >
-                    {(activeSession) => (
-                      <div class="pt-3 flex flex-col flex-1 min-h-0">
-                        <div class="flex-1 min-h-0">
-                          <Show when={local.session.userMessages().length > 1}>
-                            <ul
-                              role="list"
-                              class="absolute right-full mr-8 hidden w-60 shrink-0 @7xl:flex flex-col items-start gap-1"
-                            >
-                              <For each={local.session.userMessages()}>
+                    {(session) => {
+                      const [store, setStore] = createStore<{
+                        messageId?: string
+                      }>()
+
+                      const messages = createMemo(() => sync.data.message[session().id] ?? [])
+                      const userMessages = createMemo(() =>
+                        messages()
+                          .filter((m) => m.role === "user")
+                          .sort((a, b) => b.id.localeCompare(a.id)),
+                      )
+                      const lastUserMessage = createMemo(() => {
+                        return userMessages()?.at(0)
+                      })
+                      const activeMessage = createMemo(() => {
+                        if (!store.messageId) return lastUserMessage()
+                        return userMessages()?.find((m) => m.id === store.messageId)
+                      })
+
+                      return (
+                        <div class="pt-3 flex flex-col flex-1 min-h-0">
+                          <div class="flex-1 min-h-0">
+                            <Show when={userMessages().length > 1}>
+                              <ul
+                                role="list"
+                                class="absolute right-full mr-8 hidden w-60 shrink-0 @7xl:flex flex-col items-start gap-1"
+                              >
+                                <For each={userMessages()}>
+                                  {(message) => {
+                                    const diffs = createMemo(() => message.summary?.diffs ?? [])
+                                    const assistantMessages = createMemo(() => {
+                                      return sync.data.message[session().id]?.filter(
+                                        (m) => m.role === "assistant" && m.parentID == message.id,
+                                      ) as AssistantMessageType[]
+                                    })
+                                    const error = createMemo(() => assistantMessages().find((m) => m?.error)?.error)
+                                    const working = createMemo(() => !message.summary?.body && !error())
+
+                                    return (
+                                      <li class="group/li flex items-center self-stretch">
+                                        <button
+                                          class="flex items-center self-stretch w-full gap-x-2 py-1 cursor-default"
+                                          onClick={() => setStore("messageId", message.id)}
+                                        >
+                                          <Switch>
+                                            <Match when={working()}>
+                                              <Spinner class="text-text-base shrink-0 w-[18px] aspect-square" />
+                                            </Match>
+                                            <Match when={true}>
+                                              <DiffChanges diff={diffs()} variant="bars" />
+                                            </Match>
+                                          </Switch>
+                                          <div
+                                            data-active={activeMessage()?.id === message.id}
+                                            classList={{
+                                              "text-14-regular text-text-weak whitespace-nowrap truncate min-w-0": true,
+                                              "text-text-weak data-[active=true]:text-text-strong group-hover/li:text-text-base": true,
+                                            }}
+                                          >
+                                            <Show when={message.summary?.title} fallback="New message">
+                                              {message.summary?.title}
+                                            </Show>
+                                          </div>
+                                        </button>
+                                      </li>
+                                    )
+                                  }}
+                                </For>
+                              </ul>
+                            </Show>
+                            <div ref={messageScrollElement} class="grow min-w-0 h-full overflow-y-auto no-scrollbar">
+                              <For each={userMessages()}>
                                 {(message) => {
-                                  const diffs = createMemo(() => message.summary?.diffs ?? [])
+                                  const isActive = createMemo(() => activeMessage()?.id === message.id)
+                                  const [titled, setTitled] = createSignal(!!message.summary?.title)
                                   const assistantMessages = createMemo(() => {
-                                    return sync.data.message[activeSession().id]?.filter(
+                                    return sync.data.message[session().id]?.filter(
                                       (m) => m.role === "assistant" && m.parentID == message.id,
                                     ) as AssistantMessageType[]
                                   })
                                   const error = createMemo(() => assistantMessages().find((m) => m?.error)?.error)
-                                  const working = createMemo(() => !message.summary?.body && !error())
+                                  const [completed, setCompleted] = createSignal(!!message.summary?.body || !!error())
+                                  const [expanded, setExpanded] = createSignal(false)
+                                  const parts = createMemo(() => sync.data.part[message.id])
+                                  const title = createMemo(() => message.summary?.title)
+                                  const summary = createMemo(() => message.summary?.body)
+                                  const diffs = createMemo(() => message.summary?.diffs ?? [])
+                                  const hasToolPart = createMemo(() =>
+                                    assistantMessages()
+                                      ?.flatMap((m) => sync.data.part[m.id])
+                                      .some((p) => p?.type === "tool"),
+                                  )
+                                  const working = createMemo(() => !summary() && !error())
+
+                                  // allowing time for the animations to finish
+                                  createEffect(() => {
+                                    title()
+                                    setTimeout(() => setTitled(!!title()), 10_000)
+                                  })
+                                  createEffect(() => {
+                                    const complete = !!summary() || !!error()
+                                    setTimeout(() => setCompleted(complete), 1200)
+                                  })
 
                                   return (
-                                    <li class="group/li flex items-center self-stretch">
-                                      <button
-                                        class="flex items-center self-stretch w-full gap-x-2 py-1 cursor-default"
-                                        onClick={() => local.session.setActiveMessage(message.id)}
+                                    <Show when={isActive()}>
+                                      <div
+                                        data-message={message.id}
+                                        class="flex flex-col items-start self-stretch gap-8 pb-50"
                                       >
-                                        <Switch>
-                                          <Match when={working()}>
-                                            <Spinner class="text-text-base shrink-0 w-[18px] aspect-square" />
-                                          </Match>
-                                          <Match when={true}>
-                                            <DiffChanges diff={diffs()} variant="bars" />
-                                          </Match>
-                                        </Switch>
-                                        <div
-                                          data-active={local.session.activeMessage()?.id === message.id}
-                                          classList={{
-                                            "text-14-regular text-text-weak whitespace-nowrap truncate min-w-0": true,
-                                            "text-text-weak data-[active=true]:text-text-strong group-hover/li:text-text-base": true,
-                                          }}
-                                        >
-                                          <Show when={message.summary?.title} fallback="New message">
-                                            {message.summary?.title}
-                                          </Show>
-                                        </div>
-                                      </button>
-                                    </li>
-                                  )
-                                }}
-                              </For>
-                            </ul>
-                          </Show>
-                          <div ref={messageScrollElement} class="grow min-w-0 h-full overflow-y-auto no-scrollbar">
-                            <For each={local.session.userMessages()}>
-                              {(message) => {
-                                const isActive = createMemo(() => local.session.activeMessage()?.id === message.id)
-                                const [titled, setTitled] = createSignal(!!message.summary?.title)
-                                const assistantMessages = createMemo(() => {
-                                  return sync.data.message[activeSession().id]?.filter(
-                                    (m) => m.role === "assistant" && m.parentID == message.id,
-                                  ) as AssistantMessageType[]
-                                })
-                                const error = createMemo(() => assistantMessages().find((m) => m?.error)?.error)
-                                const [completed, setCompleted] = createSignal(!!message.summary?.body || !!error())
-                                const [expanded, setExpanded] = createSignal(false)
-                                const parts = createMemo(() => sync.data.part[message.id])
-                                const title = createMemo(() => message.summary?.title)
-                                const summary = createMemo(() => message.summary?.body)
-                                const diffs = createMemo(() => message.summary?.diffs ?? [])
-                                const hasToolPart = createMemo(() =>
-                                  assistantMessages()
-                                    ?.flatMap((m) => sync.data.part[m.id])
-                                    .some((p) => p?.type === "tool"),
-                                )
-                                const working = createMemo(() => !summary() && !error())
-
-                                // allowing time for the animations to finish
-                                createEffect(() => {
-                                  title()
-                                  setTimeout(() => setTitled(!!title()), 10_000)
-                                })
-                                createEffect(() => {
-                                  const complete = !!summary() || !!error()
-                                  setTimeout(() => setCompleted(complete), 1200)
-                                })
-
-                                return (
-                                  <Show when={isActive()}>
-                                    <div
-                                      data-message={message.id}
-                                      class="flex flex-col items-start self-stretch gap-8 pb-50"
-                                    >
-                                      {/* Title */}
-                                      <div class="py-2 flex flex-col items-start gap-2 self-stretch sticky top-0 bg-background-stronger z-10">
-                                        <div class="w-full text-14-medium text-text-strong">
-                                          <Show
-                                            when={titled()}
-                                            fallback={
-                                              <Typewriter
-                                                as="h1"
-                                                text={title()}
-                                                class="overflow-hidden text-ellipsis min-w-0 text-nowrap"
-                                              />
-                                            }
-                                          >
-                                            <h1 class="overflow-hidden text-ellipsis min-w-0 text-nowrap">{title()}</h1>
-                                          </Show>
-                                        </div>
-                                      </div>
-                                      <div class="-mt-8">
-                                        <Message message={message} parts={parts()} />
-                                      </div>
-                                      {/* Summary */}
-                                      <Show when={completed()}>
-                                        <div class="w-full flex flex-col gap-6 items-start self-stretch">
-                                          <div class="flex flex-col items-start gap-1 self-stretch">
-                                            <h2 class="text-12-medium text-text-weak">
-                                              <Switch>
-                                                <Match when={diffs().length}>Summary</Match>
-                                                <Match when={true}>Response</Match>
-                                              </Switch>
-                                            </h2>
-                                            <Show when={summary()}>
-                                              {(summary) => (
-                                                <Markdown
-                                                  classList={{ "[&>*]:fade-up-text": !diffs().length }}
-                                                  text={summary()}
+                                        {/* Title */}
+                                        <div class="py-2 flex flex-col items-start gap-2 self-stretch sticky top-0 bg-background-stronger z-10">
+                                          <div class="w-full text-14-medium text-text-strong">
+                                            <Show
+                                              when={titled()}
+                                              fallback={
+                                                <Typewriter
+                                                  as="h1"
+                                                  text={title()}
+                                                  class="overflow-hidden text-ellipsis min-w-0 text-nowrap"
                                                 />
-                                              )}
+                                              }
+                                            >
+                                              <h1 class="overflow-hidden text-ellipsis min-w-0 text-nowrap">
+                                                {title()}
+                                              </h1>
                                             </Show>
                                           </div>
-                                          <Accordion class="w-full" multiple>
-                                            <For each={diffs()}>
-                                              {(diff) => (
-                                                <Accordion.Item value={diff.file}>
-                                                  <Accordion.Header>
-                                                    <Accordion.Trigger onClick={handleDiffTriggerClick}>
-                                                      <div class="flex items-center justify-between w-full gap-5">
-                                                        <div class="grow flex items-center gap-5 min-w-0">
-                                                          <FileIcon
-                                                            node={{ path: diff.file, type: "file" }}
-                                                            class="shrink-0 size-4"
-                                                          />
-                                                          <div class="flex grow min-w-0">
-                                                            <Show when={diff.file.includes("/")}>
-                                                              <span class="text-text-base truncate-start">
-                                                                {getDirectory(diff.file)}&lrm;
+                                        </div>
+                                        <div class="-mt-8">
+                                          <Message message={message} parts={parts()} />
+                                        </div>
+                                        {/* Summary */}
+                                        <Show when={completed()}>
+                                          <div class="w-full flex flex-col gap-6 items-start self-stretch">
+                                            <div class="flex flex-col items-start gap-1 self-stretch">
+                                              <h2 class="text-12-medium text-text-weak">
+                                                <Switch>
+                                                  <Match when={diffs().length}>Summary</Match>
+                                                  <Match when={true}>Response</Match>
+                                                </Switch>
+                                              </h2>
+                                              <Show when={summary()}>
+                                                {(summary) => (
+                                                  <Markdown
+                                                    classList={{ "[&>*]:fade-up-text": !diffs().length }}
+                                                    text={summary()}
+                                                  />
+                                                )}
+                                              </Show>
+                                            </div>
+                                            <Accordion class="w-full" multiple>
+                                              <For each={diffs()}>
+                                                {(diff) => (
+                                                  <Accordion.Item value={diff.file}>
+                                                    <Accordion.Header>
+                                                      <Accordion.Trigger onClick={handleDiffTriggerClick}>
+                                                        <div class="flex items-center justify-between w-full gap-5">
+                                                          <div class="grow flex items-center gap-5 min-w-0">
+                                                            <FileIcon
+                                                              node={{ path: diff.file, type: "file" }}
+                                                              class="shrink-0 size-4"
+                                                            />
+                                                            <div class="flex grow min-w-0">
+                                                              <Show when={diff.file.includes("/")}>
+                                                                <span class="text-text-base truncate-start">
+                                                                  {getDirectory(diff.file)}&lrm;
+                                                                </span>
+                                                              </Show>
+                                                              <span class="text-text-strong shrink-0">
+                                                                {getFilename(diff.file)}
                                                               </span>
-                                                            </Show>
-                                                            <span class="text-text-strong shrink-0">
-                                                              {getFilename(diff.file)}
-                                                            </span>
+                                                            </div>
+                                                          </div>
+                                                          <div class="shrink-0 flex gap-4 items-center justify-end">
+                                                            <DiffChanges diff={diff} />
+                                                            <Icon name="chevron-grabber-vertical" size="small" />
                                                           </div>
                                                         </div>
-                                                        <div class="shrink-0 flex gap-4 items-center justify-end">
-                                                          <DiffChanges diff={diff} />
-                                                          <Icon name="chevron-grabber-vertical" size="small" />
-                                                        </div>
-                                                      </div>
-                                                    </Accordion.Trigger>
-                                                  </Accordion.Header>
-                                                  <Accordion.Content>
-                                                    <Diff
-                                                      before={{
-                                                        name: diff.file!,
-                                                        contents: diff.before!,
-                                                      }}
-                                                      after={{
-                                                        name: diff.file!,
-                                                        contents: diff.after!,
+                                                      </Accordion.Trigger>
+                                                    </Accordion.Header>
+                                                    <Accordion.Content>
+                                                      <Diff
+                                                        before={{
+                                                          name: diff.file!,
+                                                          contents: diff.before!,
+                                                        }}
+                                                        after={{
+                                                          name: diff.file!,
+                                                          contents: diff.after!,
+                                                        }}
+                                                      />
+                                                    </Accordion.Content>
+                                                  </Accordion.Item>
+                                                )}
+                                              </For>
+                                            </Accordion>
+                                          </div>
+                                        </Show>
+                                        <Show when={error() && !expanded()}>
+                                          <Card variant="error" class="text-text-on-critical-base">
+                                            {error()?.data?.message as string}
+                                          </Card>
+                                        </Show>
+                                        {/* Response */}
+                                        <div class="w-full">
+                                          <Switch>
+                                            <Match when={!completed()}>
+                                              <MessageProgress
+                                                assistantMessages={assistantMessages}
+                                                done={!working()}
+                                              />
+                                            </Match>
+                                            <Match when={completed() && hasToolPart()}>
+                                              <Collapsible variant="ghost" open={expanded()} onOpenChange={setExpanded}>
+                                                <Collapsible.Trigger class="text-text-weak hover:text-text-strong">
+                                                  <div class="flex items-center gap-1 self-stretch">
+                                                    <div class="text-12-medium">
+                                                      <Switch>
+                                                        <Match when={expanded()}>Hide details</Match>
+                                                        <Match when={!expanded()}>Show details</Match>
+                                                      </Switch>
+                                                    </div>
+                                                    <Collapsible.Arrow />
+                                                  </div>
+                                                </Collapsible.Trigger>
+                                                <Collapsible.Content>
+                                                  <div class="w-full flex flex-col items-start self-stretch gap-3">
+                                                    <For each={assistantMessages()}>
+                                                      {(assistantMessage) => {
+                                                        const parts = createMemo(
+                                                          () => sync.data.part[assistantMessage.id],
+                                                        )
+                                                        return <Message message={assistantMessage} parts={parts()} />
                                                       }}
-                                                    />
-                                                  </Accordion.Content>
-                                                </Accordion.Item>
-                                              )}
-                                            </For>
-                                          </Accordion>
-                                        </div>
-                                      </Show>
-                                      <Show when={error() && !expanded()}>
-                                        <Card variant="error" class="text-text-on-critical-base">
-                                          {error()?.data?.message as string}
-                                        </Card>
-                                      </Show>
-                                      {/* Response */}
-                                      <div class="w-full">
-                                        <Switch>
-                                          <Match when={!completed()}>
-                                            <MessageProgress assistantMessages={assistantMessages} done={!working()} />
-                                          </Match>
-                                          <Match when={completed() && hasToolPart()}>
-                                            <Collapsible variant="ghost" open={expanded()} onOpenChange={setExpanded}>
-                                              <Collapsible.Trigger class="text-text-weak hover:text-text-strong">
-                                                <div class="flex items-center gap-1 self-stretch">
-                                                  <div class="text-12-medium">
-                                                    <Switch>
-                                                      <Match when={expanded()}>Hide details</Match>
-                                                      <Match when={!expanded()}>Show details</Match>
-                                                    </Switch>
+                                                    </For>
+                                                    <Show when={error()}>
+                                                      <Card variant="error" class="text-text-on-critical-base">
+                                                        {error()?.data?.message as string}
+                                                      </Card>
+                                                    </Show>
                                                   </div>
-                                                  <Collapsible.Arrow />
-                                                </div>
-                                              </Collapsible.Trigger>
-                                              <Collapsible.Content>
-                                                <div class="w-full flex flex-col items-start self-stretch gap-3">
-                                                  <For each={assistantMessages()}>
-                                                    {(assistantMessage) => {
-                                                      const parts = createMemo(
-                                                        () => sync.data.part[assistantMessage.id],
-                                                      )
-                                                      return <Message message={assistantMessage} parts={parts()} />
-                                                    }}
-                                                  </For>
-                                                  <Show when={error()}>
-                                                    <Card variant="error" class="text-text-on-critical-base">
-                                                      {error()?.data?.message as string}
-                                                    </Card>
-                                                  </Show>
-                                                </div>
-                                              </Collapsible.Content>
-                                            </Collapsible>
-                                          </Match>
-                                        </Switch>
+                                                </Collapsible.Content>
+                                              </Collapsible>
+                                            </Match>
+                                          </Switch>
+                                        </div>
                                       </div>
-                                    </div>
-                                  </Show>
-                                )
-                              }}
-                            </For>
+                                    </Show>
+                                  )
+                                }}
+                              </For>
+                            </div>
                           </div>
                         </div>
-                      </div>
-                    )}
+                      )
+                    }}
                   </Show>
                 </div>
               </Tabs.Content>
               {/* <Tabs.Content value="review" class="select-text"></Tabs.Content> */}
-              <For each={local.file.opened()}>
+              <For each={local.session.tabs()?.opened}>
                 {(file) => (
-                  <Tabs.Content value={file.path} class="select-text">
+                  <Tabs.Content value={file} class="select-text">
                     {(() => {
-                      const view = local.file.view(file.path)
-                      const showRaw = view === "raw" || !file.content?.diff
-                      const code = showRaw ? (file.content?.content ?? "") : (file.content?.diff ?? "")
-                      return <Code path={file.path} code={code} class="[&_code]:pb-60" />
+                      {
+                        /* const view = local.file.view(file) */
+                      }
+                      {
+                        /* const showRaw = view === "raw" || !file.content?.diff */
+                      }
+                      {
+                        /* const code = showRaw ? (file.content?.content ?? "") : (file.content?.diff ?? "") */
+                      }
+                      const node = local.file.node(file)
+                      return (
+                        <Code
+                          file={{ name: node.path, contents: node.content?.content ?? "" }}
+                          disableFileHeader
+                          overflow="scroll"
+                          class="pt-3 pb-40"
+                        />
+                      )
                     })()}
                   </Tabs.Content>
                 )}
@@ -847,7 +830,7 @@ export default function Page() {
           items={local.file.search}
           key={(x) => x}
           onOpenChange={(open) => setStore("fileSelectOpen", open)}
-          onSelect={(x) => (x ? local.file.open(x, { pinned: true }) : undefined)}
+          onSelect={(x) => (x ? local.session.open(x) : undefined)}
         >
           {(i) => (
             <div

+ 3 - 0
packages/ui/src/components/code.css

@@ -0,0 +1,3 @@
+[data-component="code"] {
+  overflow: hidden;
+}

+ 52 - 0
packages/ui/src/components/code.tsx

@@ -0,0 +1,52 @@
+import { type FileContents, File, FileOptions, LineAnnotation } from "@pierre/precision-diffs"
+import { ComponentProps, createEffect, splitProps } from "solid-js"
+
+export type CodeProps<T = {}> = FileOptions<T> & {
+  file: FileContents
+  annotations?: LineAnnotation<T>[]
+  class?: string
+  classList?: ComponentProps<"div">["classList"]
+}
+
+export function Code<T>(props: CodeProps<T>) {
+  let container!: HTMLDivElement
+  const [local, others] = splitProps(props, ["file", "class", "classList", "annotations"])
+  const file = () => local.file
+
+  createEffect(() => {
+    const instance = new File<T>({
+      theme: { dark: "oc-1-dark", light: "oc-1-light" }, // or any Shiki theme
+      overflow: "wrap", // or 'scroll'
+      themeType: "system", // 'system', 'light', or 'dark'
+      disableLineNumbers: false, // optional
+      // lang: 'typescript', // optional - auto-detected from filename if not provided
+      ...others,
+    })
+
+    instance.render({
+      file: file(),
+      lineAnnotations: local.annotations,
+      containerWrapper: container,
+    })
+  })
+
+  return (
+    <div
+      data-component="code"
+      style={{
+        "--pjs-font-family": "var(--font-family-mono)",
+        "--pjs-font-size": "var(--font-size-small)",
+        "--pjs-line-height": "24px",
+        "--pjs-tab-size": 2,
+        "--pjs-font-features": "var(--font-family-mono--font-feature-settings)",
+        "--pjs-header-font-family": "var(--font-family-sans)",
+        "--pjs-gap-block": 0,
+      }}
+      classList={{
+        ...(local.classList || {}),
+        [local.class ?? ""]: !!local.class,
+      }}
+      ref={container}
+    />
+  )
+}

+ 3574 - 4
packages/ui/src/components/diff.tsx

@@ -4,7 +4,8 @@ import {
   type DiffLineAnnotation,
   type HunkData,
   FileDiffOptions,
-  // registerCustomTheme,
+  registerCustomTheme,
+  ThemeRegistrationResolved,
 } from "@pierre/precision-diffs"
 import { ComponentProps, createEffect, splitProps } from "solid-js"
 
@@ -16,8 +17,6 @@ export type DiffProps<T = {}> = FileDiffOptions<T> & {
   classList?: ComponentProps<"div">["classList"]
 }
 
-// registerCustomTheme("opencode", () => import("./theme.json"))
-
 // interface ThreadMetadata {
 //   threadId: string
 // }
@@ -50,13 +49,14 @@ export function Diff<T>(props: DiffProps<T>) {
   //   theme: "pierre-dark",
   //   themes: undefined,
   // })
+  //
 
   // When ready to render, simply call .render with old/new file, optional
   // annotations and a container element to hold the diff
   createEffect(() => {
     const instance = new FileDiff<T>({
       // theme: "pierre-light",
-      theme: { dark: "pierre-dark", light: "pierre-light" },
+      theme: { dark: "oc-1-dark", light: "oc-1-light" },
       // When using the 'themes' prop, 'themeType' allows you to force 'dark'
       // or 'light' theme, or inherit from the OS ('system') theme.
       themeType: "system",
@@ -178,3 +178,3573 @@ export function Diff<T>(props: DiffProps<T>) {
     />
   )
 }
+
+registerCustomTheme("oc-1-light", () => {
+  return Promise.resolve({
+    name: "oc-1-light",
+    type: "light",
+    colors: {
+      "editor.background": "transparent",
+      "editor.foreground": "#070707",
+      foreground: "#070707",
+      focusBorder: "#008cff",
+      "selection.background": "#dfe7ff",
+      "editor.selectionBackground": "#008cff2e",
+      "editor.lineHighlightBackground": "#dfe7ff8c",
+      "editorCursor.foreground": "#008cff",
+      "editorLineNumber.foreground": "#84848A",
+      "editorLineNumber.activeForeground": "#6C6C71",
+      "editorIndentGuide.background": "#eeeeef",
+      "editorIndentGuide.activeBackground": "#dbdbdd",
+      "diffEditor.insertedTextBackground": "#00cab133",
+      "diffEditor.deletedTextBackground": "#ff2e3f33",
+      "sideBar.background": "#f8f8f8",
+      "sideBar.foreground": "#6C6C71",
+      "sideBar.border": "#eeeeef",
+      "sideBarTitle.foreground": "#070707",
+      "sideBarSectionHeader.background": "#f8f8f8",
+      "sideBarSectionHeader.foreground": "#6C6C71",
+      "sideBarSectionHeader.border": "#eeeeef",
+      "activityBar.background": "#f8f8f8",
+      "activityBar.foreground": "#070707",
+      "activityBar.border": "#eeeeef",
+      "activityBar.activeBorder": "#008cff",
+      "activityBarBadge.background": "#008cff",
+      "activityBarBadge.foreground": "#ffffff",
+      "titleBar.activeBackground": "#f8f8f8",
+      "titleBar.activeForeground": "#070707",
+      "titleBar.inactiveBackground": "#f8f8f8",
+      "titleBar.inactiveForeground": "#84848A",
+      "titleBar.border": "#eeeeef",
+      "list.activeSelectionBackground": "#dfe7ffcc",
+      "list.activeSelectionForeground": "#070707",
+      "list.inactiveSelectionBackground": "#dfe7ff73",
+      "list.hoverBackground": "#dfe7ff59",
+      "list.focusOutline": "#008cff",
+      "tab.activeBackground": "#ffffff",
+      "tab.activeForeground": "#070707",
+      "tab.activeBorderTop": "#008cff",
+      "tab.inactiveBackground": "#f8f8f8",
+      "tab.inactiveForeground": "#84848A",
+      "tab.border": "#eeeeef",
+      "editorGroupHeader.tabsBackground": "#f8f8f8",
+      "editorGroupHeader.tabsBorder": "#eeeeef",
+      "panel.background": "#f8f8f8",
+      "panel.border": "#eeeeef",
+      "panelTitle.activeBorder": "#008cff",
+      "panelTitle.activeForeground": "#070707",
+      "panelTitle.inactiveForeground": "#84848A",
+      "statusBar.background": "#f8f8f8",
+      "statusBar.foreground": "#6C6C71",
+      "statusBar.border": "#eeeeef",
+      "statusBar.noFolderBackground": "#f8f8f8",
+      "statusBar.debuggingBackground": "#ffca00",
+      "statusBar.debuggingForeground": "#ffffff",
+      "statusBarItem.remoteBackground": "#f8f8f8",
+      "statusBarItem.remoteForeground": "#6C6C71",
+      "input.background": "#f2f2f3",
+      "input.border": "#dbdbdd",
+      "input.foreground": "#070707",
+      "input.placeholderForeground": "#8E8E95",
+      "dropdown.background": "#f2f2f3",
+      "dropdown.border": "#dbdbdd",
+      "dropdown.foreground": "#070707",
+      "button.background": "#008cff",
+      "button.foreground": "#ffffff",
+      "button.hoverBackground": "#1a98ff",
+      "textLink.foreground": "#008cff",
+      "textLink.activeForeground": "#008cff",
+      "gitDecoration.addedResourceForeground": "#00cab1",
+      "gitDecoration.conflictingResourceForeground": "#ffca00",
+      "gitDecoration.modifiedResourceForeground": "#008cff",
+      "gitDecoration.deletedResourceForeground": "#ff2e3f",
+      "gitDecoration.untrackedResourceForeground": "#00cab1",
+      "gitDecoration.ignoredResourceForeground": "#84848A",
+      "terminal.titleForeground": "#6C6C71",
+      "terminal.titleInactiveForeground": "#84848A",
+      "terminal.background": "#f8f8f8",
+      "terminal.foreground": "#6C6C71",
+      "terminal.ansiBlack": "#1F1F21",
+      "terminal.ansiRed": "#ff2e3f",
+      "terminal.ansiGreen": "#0dbe4e",
+      "terminal.ansiYellow": "#ffca00",
+      "terminal.ansiBlue": "#008cff",
+      "terminal.ansiMagenta": "#c635e4",
+      "terminal.ansiCyan": "#08c0ef",
+      "terminal.ansiWhite": "#c6c6c8",
+      "terminal.ansiBrightBlack": "#1F1F21",
+      "terminal.ansiBrightRed": "#ff2e3f",
+      "terminal.ansiBrightGreen": "#0dbe4e",
+      "terminal.ansiBrightYellow": "#ffca00",
+      "terminal.ansiBrightBlue": "#008cff",
+      "terminal.ansiBrightMagenta": "#c635e4",
+      "terminal.ansiBrightCyan": "#08c0ef",
+      "terminal.ansiBrightWhite": "#c6c6c8",
+    },
+    tokenColors: [
+      {
+        scope: ["comment", "punctuation.definition.comment"],
+        settings: {
+          foreground: "#84848A",
+        },
+      },
+      {
+        scope: "comment markup.link",
+        settings: {
+          foreground: "#84848A",
+        },
+      },
+      {
+        scope: ["string", "constant.other.symbol"],
+        settings: {
+          foreground: "#199f43",
+        },
+      },
+      {
+        scope: ["punctuation.definition.string.begin", "punctuation.definition.string.end"],
+        settings: {
+          foreground: "#199f43",
+        },
+      },
+      {
+        scope: ["constant.numeric", "constant.language.boolean"],
+        settings: {
+          foreground: "#1ca1c7",
+        },
+      },
+      {
+        scope: "constant",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "punctuation.definition.constant",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "constant.language",
+        settings: {
+          foreground: "#1ca1c7",
+        },
+      },
+      {
+        scope: "variable.other.constant",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "keyword",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "keyword.control",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: ["storage", "storage.type", "storage.modifier"],
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "token.storage",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: [
+          "keyword.operator.new",
+          "keyword.operator.expression.instanceof",
+          "keyword.operator.expression.typeof",
+          "keyword.operator.expression.void",
+          "keyword.operator.expression.delete",
+          "keyword.operator.expression.in",
+          "keyword.operator.expression.of",
+          "keyword.operator.expression.keyof",
+        ],
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "keyword.operator.delete",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: ["variable", "identifier", "meta.definition.variable"],
+        settings: {
+          foreground: "#d47628",
+        },
+      },
+      {
+        scope: [
+          "variable.other.readwrite",
+          "meta.object-literal.key",
+          "support.variable.property",
+          "support.variable.object.process",
+          "support.variable.object.node",
+        ],
+        settings: {
+          foreground: "#d47628",
+        },
+      },
+      {
+        scope: "variable.language",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "variable.parameter.function",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "function.parameter",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "variable.parameter",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "variable.parameter.function.language.python",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "variable.parameter.function.python",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: [
+          "support.function",
+          "entity.name.function",
+          "meta.function-call",
+          "meta.require",
+          "support.function.any-method",
+          "variable.function",
+        ],
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "keyword.other.special-method",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "entity.name.function",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "support.function.console",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: ["support.type", "entity.name.type", "entity.name.class", "storage.type"],
+        settings: {
+          foreground: "#c635e4",
+        },
+      },
+      {
+        scope: ["support.class", "entity.name.type.class"],
+        settings: {
+          foreground: "#c635e4",
+        },
+      },
+      {
+        scope: ["entity.name.class", "variable.other.class.js", "variable.other.class.ts"],
+        settings: {
+          foreground: "#c635e4",
+        },
+      },
+      {
+        scope: "entity.name.class.identifier.namespace.type",
+        settings: {
+          foreground: "#c635e4",
+        },
+      },
+      {
+        scope: "entity.name.type.namespace",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "entity.other.inherited-class",
+        settings: {
+          foreground: "#c635e4",
+        },
+      },
+      {
+        scope: "entity.name.namespace",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "keyword.operator",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: ["keyword.operator.logical", "keyword.operator.bitwise", "keyword.operator.channel"],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: [
+          "keyword.operator.arithmetic",
+          "keyword.operator.comparison",
+          "keyword.operator.relational",
+          "keyword.operator.increment",
+          "keyword.operator.decrement",
+        ],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "keyword.operator.assignment",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "keyword.operator.assignment.compound",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: [
+          "keyword.operator.assignment.compound.js",
+          "keyword.operator.assignment.compound.ts",
+        ],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "keyword.operator.ternary",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "keyword.operator.optional",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "punctuation",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "punctuation.separator.delimiter",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "punctuation.separator.key-value",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "punctuation.terminator",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "meta.brace",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "meta.brace.square",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "meta.brace.round",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "function.brace",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: ["punctuation.definition.parameters", "punctuation.definition.typeparameters"],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: ["punctuation.definition.block", "punctuation.definition.tag"],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: ["meta.tag.tsx", "meta.tag.jsx", "meta.tag.js", "meta.tag.ts"],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "keyword.operator.expression.import",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "keyword.operator.module",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "support.type.object.console",
+        settings: {
+          foreground: "#d47628",
+        },
+      },
+      {
+        scope: ["support.module.node", "support.type.object.module", "entity.name.type.module"],
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "support.constant.math",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "support.constant.property.math",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "support.constant.json",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "support.type.object.dom",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: ["support.variable.dom", "support.variable.property.dom"],
+        settings: {
+          foreground: "#d47628",
+        },
+      },
+      {
+        scope: "support.variable.property.process",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "meta.property.object",
+        settings: {
+          foreground: "#d47628",
+        },
+      },
+      {
+        scope: "variable.parameter.function.js",
+        settings: {
+          foreground: "#d47628",
+        },
+      },
+      {
+        scope: ["keyword.other.template.begin", "keyword.other.template.end"],
+        settings: {
+          foreground: "#199f43",
+        },
+      },
+      {
+        scope: ["keyword.other.substitution.begin", "keyword.other.substitution.end"],
+        settings: {
+          foreground: "#199f43",
+        },
+      },
+      {
+        scope: [
+          "punctuation.definition.template-expression.begin",
+          "punctuation.definition.template-expression.end",
+        ],
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "meta.template.expression",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "punctuation.section.embedded",
+        settings: {
+          foreground: "#d47628",
+        },
+      },
+      {
+        scope: "variable.interpolation",
+        settings: {
+          foreground: "#d47628",
+        },
+      },
+      {
+        scope: ["punctuation.section.embedded.begin", "punctuation.section.embedded.end"],
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "punctuation.quasi.element",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: [
+          "support.type.primitive.ts",
+          "support.type.builtin.ts",
+          "support.type.primitive.tsx",
+          "support.type.builtin.tsx",
+        ],
+        settings: {
+          foreground: "#c635e4",
+        },
+      },
+      {
+        scope: "support.type.type.flowtype",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "support.type.primitive",
+        settings: {
+          foreground: "#c635e4",
+        },
+      },
+      {
+        scope: "support.variable.magic.python",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "variable.parameter.function.language.special.self.python",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: [
+          "punctuation.separator.period.python",
+          "punctuation.separator.element.python",
+          "punctuation.parenthesis.begin.python",
+          "punctuation.parenthesis.end.python",
+        ],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: [
+          "punctuation.definition.arguments.begin.python",
+          "punctuation.definition.arguments.end.python",
+          "punctuation.separator.arguments.python",
+          "punctuation.definition.list.begin.python",
+          "punctuation.definition.list.end.python",
+        ],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "support.type.python",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "keyword.operator.logical.python",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "meta.function-call.generic.python",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "constant.character.format.placeholder.other.python",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "meta.function.decorator.python",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: ["support.token.decorator.python", "meta.function.decorator.identifier.python"],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "storage.modifier.lifetime.rust",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "support.function.std.rust",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "entity.name.lifetime.rust",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "variable.language.rust",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "keyword.operator.misc.rust",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "keyword.operator.sigil.rust",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "support.constant.core.rust",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: ["meta.function.c", "meta.function.cpp"],
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: [
+          "punctuation.section.block.begin.bracket.curly.cpp",
+          "punctuation.section.block.end.bracket.curly.cpp",
+          "punctuation.terminator.statement.c",
+          "punctuation.section.block.begin.bracket.curly.c",
+          "punctuation.section.block.end.bracket.curly.c",
+          "punctuation.section.parens.begin.bracket.round.c",
+          "punctuation.section.parens.end.bracket.round.c",
+          "punctuation.section.parameters.begin.bracket.round.c",
+          "punctuation.section.parameters.end.bracket.round.c",
+        ],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: [
+          "keyword.operator.assignment.c",
+          "keyword.operator.comparison.c",
+          "keyword.operator.c",
+          "keyword.operator.increment.c",
+          "keyword.operator.decrement.c",
+          "keyword.operator.bitwise.shift.c",
+        ],
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: [
+          "keyword.operator.assignment.cpp",
+          "keyword.operator.comparison.cpp",
+          "keyword.operator.cpp",
+          "keyword.operator.increment.cpp",
+          "keyword.operator.decrement.cpp",
+          "keyword.operator.bitwise.shift.cpp",
+        ],
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: ["punctuation.separator.c", "punctuation.separator.cpp"],
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: ["support.type.posix-reserved.c", "support.type.posix-reserved.cpp"],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: ["keyword.operator.sizeof.c", "keyword.operator.sizeof.cpp"],
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "variable.c",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: ["storage.type.annotation.java", "storage.type.object.array.java"],
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "source.java",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: [
+          "punctuation.section.block.begin.java",
+          "punctuation.section.block.end.java",
+          "punctuation.definition.method-parameters.begin.java",
+          "punctuation.definition.method-parameters.end.java",
+          "meta.method.identifier.java",
+          "punctuation.section.method.begin.java",
+          "punctuation.section.method.end.java",
+          "punctuation.terminator.java",
+          "punctuation.section.class.begin.java",
+          "punctuation.section.class.end.java",
+          "punctuation.section.inner-class.begin.java",
+          "punctuation.section.inner-class.end.java",
+          "meta.method-call.java",
+          "punctuation.section.class.begin.bracket.curly.java",
+          "punctuation.section.class.end.bracket.curly.java",
+          "punctuation.section.method.begin.bracket.curly.java",
+          "punctuation.section.method.end.bracket.curly.java",
+          "punctuation.separator.period.java",
+          "punctuation.bracket.angle.java",
+          "punctuation.definition.annotation.java",
+          "meta.method.body.java",
+        ],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "meta.method.java",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: ["storage.modifier.import.java", "storage.type.java", "storage.type.generic.java"],
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "keyword.operator.instanceof.java",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "meta.definition.variable.name.java",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "token.variable.parameter.java",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "import.storage.java",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "token.package.keyword",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "token.package",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "token.storage.type.java",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "keyword.operator.assignment.go",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: ["keyword.operator.arithmetic.go", "keyword.operator.address.go"],
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "entity.name.package.go",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: [
+          "support.other.namespace.use.php",
+          "support.other.namespace.use-as.php",
+          "support.other.namespace.php",
+          "entity.other.alias.php",
+          "meta.interface.php",
+        ],
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "keyword.operator.error-control.php",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "keyword.operator.type.php",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: ["punctuation.section.array.begin.php", "punctuation.section.array.end.php"],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: [
+          "storage.type.php",
+          "meta.other.type.phpdoc.php",
+          "keyword.other.type.php",
+          "keyword.other.array.phpdoc.php",
+        ],
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: [
+          "meta.function-call.php",
+          "meta.function-call.object.php",
+          "meta.function-call.static.php",
+        ],
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: [
+          "punctuation.definition.parameters.begin.bracket.round.php",
+          "punctuation.definition.parameters.end.bracket.round.php",
+          "punctuation.separator.delimiter.php",
+          "punctuation.section.scope.begin.php",
+          "punctuation.section.scope.end.php",
+          "punctuation.terminator.expression.php",
+          "punctuation.definition.arguments.begin.bracket.round.php",
+          "punctuation.definition.arguments.end.bracket.round.php",
+          "punctuation.definition.storage-type.begin.bracket.round.php",
+          "punctuation.definition.storage-type.end.bracket.round.php",
+          "punctuation.definition.array.begin.bracket.round.php",
+          "punctuation.definition.array.end.bracket.round.php",
+          "punctuation.definition.begin.bracket.round.php",
+          "punctuation.definition.end.bracket.round.php",
+          "punctuation.definition.begin.bracket.curly.php",
+          "punctuation.definition.end.bracket.curly.php",
+          "punctuation.definition.section.switch-block.end.bracket.curly.php",
+          "punctuation.definition.section.switch-block.start.bracket.curly.php",
+          "punctuation.definition.section.switch-block.begin.bracket.curly.php",
+          "punctuation.definition.section.switch-block.end.bracket.curly.php",
+        ],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: [
+          "support.constant.ext.php",
+          "support.constant.std.php",
+          "support.constant.core.php",
+          "support.constant.parser-token.php",
+        ],
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: ["entity.name.goto-label.php", "support.other.php"],
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: [
+          "keyword.operator.logical.php",
+          "keyword.operator.bitwise.php",
+          "keyword.operator.arithmetic.php",
+        ],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "keyword.operator.regexp.php",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "keyword.operator.comparison.php",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: ["keyword.operator.heredoc.php", "keyword.operator.nowdoc.php"],
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "variable.other.class.php",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "invalid.illegal.non-null-typehinted.php",
+        settings: {
+          foreground: "#f44747",
+        },
+      },
+      {
+        scope: "variable.other.generic-type.haskell",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "storage.type.haskell",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "storage.type.cs",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "entity.name.variable.local.cs",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "entity.name.label.cs",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: [
+          "entity.name.scope-resolution.function.call",
+          "entity.name.scope-resolution.function.definition",
+        ],
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: [
+          "punctuation.definition.delayed.unison",
+          "punctuation.definition.list.begin.unison",
+          "punctuation.definition.list.end.unison",
+          "punctuation.definition.ability.begin.unison",
+          "punctuation.definition.ability.end.unison",
+          "punctuation.operator.assignment.as.unison",
+          "punctuation.separator.pipe.unison",
+          "punctuation.separator.delimiter.unison",
+          "punctuation.definition.hash.unison",
+        ],
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "support.constant.edge",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "support.type.prelude.elm",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "support.constant.elm",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "entity.global.clojure",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "meta.symbol.clojure",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "constant.keyword.clojure",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: ["meta.arguments.coffee", "variable.parameter.function.coffee"],
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "storage.modifier.import.groovy",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "meta.method.groovy",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "meta.definition.variable.name.groovy",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "meta.definition.class.inherited.classes.groovy",
+        settings: {
+          foreground: "#199f43",
+        },
+      },
+      {
+        scope: "support.variable.semantic.hlsl",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: [
+          "support.type.texture.hlsl",
+          "support.type.sampler.hlsl",
+          "support.type.object.hlsl",
+          "support.type.object.rw.hlsl",
+          "support.type.fx.hlsl",
+          "support.type.object.hlsl",
+        ],
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: ["text.variable", "text.bracketed"],
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: ["support.type.swift", "support.type.vb.asp"],
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "meta.scope.prerequisites.makefile",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "source.makefile",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "source.ini",
+        settings: {
+          foreground: "#199f43",
+        },
+      },
+      {
+        scope: "constant.language.symbol.ruby",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: ["function.parameter.ruby", "function.parameter.cs"],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "constant.language.symbol.elixir",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope:
+          "text.html.laravel-blade source.php.embedded.line.html entity.name.tag.laravel-blade",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope:
+          "text.html.laravel-blade source.php.embedded.line.html support.constant.laravel-blade",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "entity.name.function.xi",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "entity.name.class.xi",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "constant.character.character-class.regexp.xi",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "constant.regexp.xi",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "keyword.control.xi",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "invalid.xi",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "beginning.punctuation.definition.quote.markdown.xi",
+        settings: {
+          foreground: "#199f43",
+        },
+      },
+      {
+        scope: "beginning.punctuation.definition.list.markdown.xi",
+        settings: {
+          foreground: "#84848A",
+        },
+      },
+      {
+        scope: "constant.character.xi",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "accent.xi",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "wikiword.xi",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "constant.other.color.rgb-value.xi",
+        settings: {
+          foreground: "#ffffff",
+        },
+      },
+      {
+        scope: "punctuation.definition.tag.xi",
+        settings: {
+          foreground: "#84848A",
+        },
+      },
+      {
+        scope: ["support.constant.property-value.scss", "support.constant.property-value.css"],
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: ["keyword.operator.css", "keyword.operator.scss", "keyword.operator.less"],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: [
+          "support.constant.color.w3c-standard-color-name.css",
+          "support.constant.color.w3c-standard-color-name.scss",
+        ],
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "punctuation.separator.list.comma.css",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "support.type.vendored.property-name.css",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "support.type.property-name.css",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "support.type.property-name",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "support.constant.property-value",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "support.constant.font-name",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "entity.other.attribute-name.class.css",
+        settings: {
+          foreground: "#16a994",
+          fontStyle: "normal",
+        },
+      },
+      {
+        scope: "entity.other.attribute-name.id",
+        settings: {
+          foreground: "#7b43f8",
+          fontStyle: "normal",
+        },
+      },
+      {
+        scope: [
+          "entity.other.attribute-name.pseudo-element",
+          "entity.other.attribute-name.pseudo-class",
+        ],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "meta.selector",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "selector.sass",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "rgb-value",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "inline-color-decoration rgb-value",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "less rgb-value",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "control.elements",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "keyword.operator.less",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "entity.name.tag",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "entity.other.attribute-name",
+        settings: {
+          foreground: "#16a994",
+          fontStyle: "normal",
+        },
+      },
+      {
+        scope: "constant.character.entity",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "meta.tag",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "invalid.illegal.bad-ampersand.html",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "markup.heading",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: ["markup.heading punctuation.definition.heading", "entity.name.section"],
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "entity.name.section.markdown",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "punctuation.definition.heading.markdown",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "markup.heading.setext",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: ["markup.heading.setext.1.markdown", "markup.heading.setext.2.markdown"],
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: ["markup.bold", "todo.bold"],
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "punctuation.definition.bold",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "punctuation.definition.bold.markdown",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: ["markup.italic", "punctuation.definition.italic", "todo.emphasis"],
+        settings: {
+          foreground: "#fc2b73",
+          fontStyle: "italic",
+        },
+      },
+      {
+        scope: "emphasis md",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "markup.italic.markdown",
+        settings: {
+          fontStyle: "italic",
+        },
+      },
+      {
+        scope: ["markup.underline.link.markdown", "markup.underline.link.image.markdown"],
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: ["string.other.link.title.markdown", "string.other.link.description.markdown"],
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "punctuation.definition.metadata.markdown",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: ["markup.inline.raw.markdown", "markup.inline.raw.string.markdown"],
+        settings: {
+          foreground: "#199f43",
+        },
+      },
+      {
+        scope: "punctuation.definition.list.begin.markdown",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "punctuation.definition.list.markdown",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "beginning.punctuation.definition.list.markdown",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: [
+          "punctuation.definition.string.begin.markdown",
+          "punctuation.definition.string.end.markdown",
+        ],
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "markup.quote.markdown",
+        settings: {
+          foreground: "#84848A",
+        },
+      },
+      {
+        scope: "keyword.other.unit",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "markup.changed.diff",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: [
+          "meta.diff.header.from-file",
+          "meta.diff.header.to-file",
+          "punctuation.definition.from-file.diff",
+          "punctuation.definition.to-file.diff",
+        ],
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "markup.inserted.diff",
+        settings: {
+          foreground: "#199f43",
+        },
+      },
+      {
+        scope: "markup.deleted.diff",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "string.regexp",
+        settings: {
+          foreground: "#17a5af",
+        },
+      },
+      {
+        scope: "constant.other.character-class.regexp",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "keyword.operator.quantifier.regexp",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "constant.character.escape",
+        settings: {
+          foreground: "#1ca1c7",
+        },
+      },
+      {
+        scope: "source.json meta.structure.dictionary.json > string.quoted.json",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope:
+          "source.json meta.structure.dictionary.json > string.quoted.json > punctuation.string",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: [
+          "source.json meta.structure.dictionary.json > value.json > string.quoted.json",
+          "source.json meta.structure.array.json > value.json > string.quoted.json",
+          "source.json meta.structure.dictionary.json > value.json > string.quoted.json > punctuation",
+          "source.json meta.structure.array.json > value.json > string.quoted.json > punctuation",
+        ],
+        settings: {
+          foreground: "#199f43",
+        },
+      },
+      {
+        scope: [
+          "source.json meta.structure.dictionary.json > constant.language.json",
+          "source.json meta.structure.array.json > constant.language.json",
+        ],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "support.type.property-name.json",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "support.type.property-name.json punctuation",
+        settings: {
+          foreground: "#d52c36",
+        },
+      },
+      {
+        scope: "punctuation.definition.block.sequence.item.yaml",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "block.scope.end",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "block.scope.begin",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "token.info-token",
+        settings: {
+          foreground: "#7b43f8",
+        },
+      },
+      {
+        scope: "token.warn-token",
+        settings: {
+          foreground: "#d5a910",
+        },
+      },
+      {
+        scope: "token.error-token",
+        settings: {
+          foreground: "#f44747",
+        },
+      },
+      {
+        scope: "token.debug-token",
+        settings: {
+          foreground: "#fc2b73",
+        },
+      },
+      {
+        scope: "invalid.illegal",
+        settings: {
+          foreground: "#ffffff",
+        },
+      },
+      {
+        scope: "invalid.broken",
+        settings: {
+          foreground: "#ffffff",
+        },
+      },
+      {
+        scope: "invalid.deprecated",
+        settings: {
+          foreground: "#ffffff",
+        },
+      },
+      {
+        scope: "invalid.unimplemented",
+        settings: {
+          foreground: "#ffffff",
+        },
+      },
+    ],
+    semanticTokenColors: {
+      comment: "#84848A",
+      string: "#199f43",
+      number: "#1ca1c7",
+      regexp: "#17a5af",
+      keyword: "#fc2b73",
+      variable: "#d47628",
+      parameter: "#79797F",
+      property: "#d47628",
+      function: "#7b43f8",
+      method: "#7b43f8",
+      type: "#c635e4",
+      class: "#c635e4",
+      namespace: "#d5a910",
+      enumMember: "#08c0ef",
+      "variable.constant": "#d5a910",
+      "variable.defaultLibrary": "#d5a910",
+    },
+  } as unknown as ThemeRegistrationResolved)
+})
+
+registerCustomTheme("oc-1-dark", () => {
+  return Promise.resolve({
+    name: "oc-1-dark",
+    type: "dark",
+    colors: {
+      "editor.background": "transparent",
+      "editor.foreground": "#fbfbfb",
+      foreground: "#fbfbfb",
+      focusBorder: "#1a76d4",
+      "selection.background": "#19253c",
+      "editor.selectionBackground": "#1a76d44d",
+      "editor.lineHighlightBackground": "#19253c8c",
+      "editorCursor.foreground": "#1a76d4",
+      "editorLineNumber.foreground": "#84848A",
+      "editorLineNumber.activeForeground": "#adadb1",
+      "editorIndentGuide.background": "#39393c",
+      "editorIndentGuide.activeBackground": "#2e2e30",
+      "diffEditor.insertedTextBackground": "#00cab11a",
+      "diffEditor.deletedTextBackground": "#ff2e3f1a",
+      "sideBar.background": "#141415",
+      "sideBar.foreground": "#adadb1",
+      "sideBar.border": "#070707",
+      "sideBarTitle.foreground": "#fbfbfb",
+      "sideBarSectionHeader.background": "#141415",
+      "sideBarSectionHeader.foreground": "#adadb1",
+      "sideBarSectionHeader.border": "#070707",
+      "activityBar.background": "#141415",
+      "activityBar.foreground": "#fbfbfb",
+      "activityBar.border": "#070707",
+      "activityBar.activeBorder": "#1a76d4",
+      "activityBarBadge.background": "#1a76d4",
+      "activityBarBadge.foreground": "#070707",
+      "titleBar.activeBackground": "#141415",
+      "titleBar.activeForeground": "#fbfbfb",
+      "titleBar.inactiveBackground": "#141415",
+      "titleBar.inactiveForeground": "#84848A",
+      "titleBar.border": "#070707",
+      "list.activeSelectionBackground": "#19253c99",
+      "list.activeSelectionForeground": "#fbfbfb",
+      "list.inactiveSelectionBackground": "#19253c73",
+      "list.hoverBackground": "#19253c59",
+      "list.focusOutline": "#1a76d4",
+      "tab.activeBackground": "#070707",
+      "tab.activeForeground": "#fbfbfb",
+      "tab.activeBorderTop": "#1a76d4",
+      "tab.inactiveBackground": "#141415",
+      "tab.inactiveForeground": "#84848A",
+      "tab.border": "#070707",
+      "editorGroupHeader.tabsBackground": "#141415",
+      "editorGroupHeader.tabsBorder": "#070707",
+      "panel.background": "#141415",
+      "panel.border": "#070707",
+      "panelTitle.activeBorder": "#1a76d4",
+      "panelTitle.activeForeground": "#fbfbfb",
+      "panelTitle.inactiveForeground": "#84848A",
+      "statusBar.background": "#141415",
+      "statusBar.foreground": "#adadb1",
+      "statusBar.border": "#070707",
+      "statusBar.noFolderBackground": "#141415",
+      "statusBar.debuggingBackground": "#ffca00",
+      "statusBar.debuggingForeground": "#070707",
+      "statusBarItem.remoteBackground": "#141415",
+      "statusBarItem.remoteForeground": "#adadb1",
+      "input.background": "#1F1F21",
+      "input.border": "#424245",
+      "input.foreground": "#fbfbfb",
+      "input.placeholderForeground": "#79797F",
+      "dropdown.background": "#1F1F21",
+      "dropdown.border": "#424245",
+      "dropdown.foreground": "#fbfbfb",
+      "button.background": "#1a76d4",
+      "button.foreground": "#070707",
+      "button.hoverBackground": "#186bc0",
+      "textLink.foreground": "#1a76d4",
+      "textLink.activeForeground": "#1a76d4",
+      "gitDecoration.addedResourceForeground": "#00cab1",
+      "gitDecoration.conflictingResourceForeground": "#ffca00",
+      "gitDecoration.modifiedResourceForeground": "#1a76d4",
+      "gitDecoration.deletedResourceForeground": "#ff2e3f",
+      "gitDecoration.untrackedResourceForeground": "#00cab1",
+      "gitDecoration.ignoredResourceForeground": "#84848A",
+      "terminal.titleForeground": "#adadb1",
+      "terminal.titleInactiveForeground": "#84848A",
+      "terminal.background": "#141415",
+      "terminal.foreground": "#adadb1",
+      "terminal.ansiBlack": "#141415",
+      "terminal.ansiRed": "#ff2e3f",
+      "terminal.ansiGreen": "#0dbe4e",
+      "terminal.ansiYellow": "#ffca00",
+      "terminal.ansiBlue": "#008cff",
+      "terminal.ansiMagenta": "#c635e4",
+      "terminal.ansiCyan": "#08c0ef",
+      "terminal.ansiWhite": "#c6c6c8",
+      "terminal.ansiBrightBlack": "#141415",
+      "terminal.ansiBrightRed": "#ff2e3f",
+      "terminal.ansiBrightGreen": "#0dbe4e",
+      "terminal.ansiBrightYellow": "#ffca00",
+      "terminal.ansiBrightBlue": "#008cff",
+      "terminal.ansiBrightMagenta": "#c635e4",
+      "terminal.ansiBrightCyan": "#08c0ef",
+      "terminal.ansiBrightWhite": "#c6c6c8",
+    },
+    tokenColors: [
+      {
+        scope: ["comment", "punctuation.definition.comment"],
+        settings: {
+          foreground: "#84848A",
+        },
+      },
+      {
+        scope: "comment markup.link",
+        settings: {
+          foreground: "#84848A",
+        },
+      },
+      {
+        scope: ["string", "constant.other.symbol"],
+        settings: {
+          foreground: "#5ecc71",
+        },
+      },
+      {
+        scope: ["punctuation.definition.string.begin", "punctuation.definition.string.end"],
+        settings: {
+          foreground: "#5ecc71",
+        },
+      },
+      {
+        scope: ["constant.numeric", "constant.language.boolean"],
+        settings: {
+          foreground: "#68cdf2",
+        },
+      },
+      {
+        scope: "constant",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "punctuation.definition.constant",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "constant.language",
+        settings: {
+          foreground: "#68cdf2",
+        },
+      },
+      {
+        scope: "variable.other.constant",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "keyword",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "keyword.control",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: ["storage", "storage.type", "storage.modifier"],
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "token.storage",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: [
+          "keyword.operator.new",
+          "keyword.operator.expression.instanceof",
+          "keyword.operator.expression.typeof",
+          "keyword.operator.expression.void",
+          "keyword.operator.expression.delete",
+          "keyword.operator.expression.in",
+          "keyword.operator.expression.of",
+          "keyword.operator.expression.keyof",
+        ],
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "keyword.operator.delete",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: ["variable", "identifier", "meta.definition.variable"],
+        settings: {
+          foreground: "#ffa359",
+        },
+      },
+      {
+        scope: [
+          "variable.other.readwrite",
+          "meta.object-literal.key",
+          "support.variable.property",
+          "support.variable.object.process",
+          "support.variable.object.node",
+        ],
+        settings: {
+          foreground: "#ffa359",
+        },
+      },
+      {
+        scope: "variable.language",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "variable.parameter.function",
+        settings: {
+          foreground: "#adadb1",
+        },
+      },
+      {
+        scope: "function.parameter",
+        settings: {
+          foreground: "#adadb1",
+        },
+      },
+      {
+        scope: "variable.parameter",
+        settings: {
+          foreground: "#adadb1",
+        },
+      },
+      {
+        scope: "variable.parameter.function.language.python",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "variable.parameter.function.python",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: [
+          "support.function",
+          "entity.name.function",
+          "meta.function-call",
+          "meta.require",
+          "support.function.any-method",
+          "variable.function",
+        ],
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "keyword.other.special-method",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "entity.name.function",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "support.function.console",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: ["support.type", "entity.name.type", "entity.name.class", "storage.type"],
+        settings: {
+          foreground: "#d568ea",
+        },
+      },
+      {
+        scope: ["support.class", "entity.name.type.class"],
+        settings: {
+          foreground: "#d568ea",
+        },
+      },
+      {
+        scope: ["entity.name.class", "variable.other.class.js", "variable.other.class.ts"],
+        settings: {
+          foreground: "#d568ea",
+        },
+      },
+      {
+        scope: "entity.name.class.identifier.namespace.type",
+        settings: {
+          foreground: "#d568ea",
+        },
+      },
+      {
+        scope: "entity.name.type.namespace",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "entity.other.inherited-class",
+        settings: {
+          foreground: "#d568ea",
+        },
+      },
+      {
+        scope: "entity.name.namespace",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "keyword.operator",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: ["keyword.operator.logical", "keyword.operator.bitwise", "keyword.operator.channel"],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: [
+          "keyword.operator.arithmetic",
+          "keyword.operator.comparison",
+          "keyword.operator.relational",
+          "keyword.operator.increment",
+          "keyword.operator.decrement",
+        ],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "keyword.operator.assignment",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "keyword.operator.assignment.compound",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: [
+          "keyword.operator.assignment.compound.js",
+          "keyword.operator.assignment.compound.ts",
+        ],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "keyword.operator.ternary",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "keyword.operator.optional",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "punctuation",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "punctuation.separator.delimiter",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "punctuation.separator.key-value",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "punctuation.terminator",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "meta.brace",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "meta.brace.square",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "meta.brace.round",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "function.brace",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: ["punctuation.definition.parameters", "punctuation.definition.typeparameters"],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: ["punctuation.definition.block", "punctuation.definition.tag"],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: ["meta.tag.tsx", "meta.tag.jsx", "meta.tag.js", "meta.tag.ts"],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "keyword.operator.expression.import",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "keyword.operator.module",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "support.type.object.console",
+        settings: {
+          foreground: "#ffa359",
+        },
+      },
+      {
+        scope: ["support.module.node", "support.type.object.module", "entity.name.type.module"],
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "support.constant.math",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "support.constant.property.math",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "support.constant.json",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "support.type.object.dom",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: ["support.variable.dom", "support.variable.property.dom"],
+        settings: {
+          foreground: "#ffa359",
+        },
+      },
+      {
+        scope: "support.variable.property.process",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "meta.property.object",
+        settings: {
+          foreground: "#ffa359",
+        },
+      },
+      {
+        scope: "variable.parameter.function.js",
+        settings: {
+          foreground: "#ffa359",
+        },
+      },
+      {
+        scope: ["keyword.other.template.begin", "keyword.other.template.end"],
+        settings: {
+          foreground: "#5ecc71",
+        },
+      },
+      {
+        scope: ["keyword.other.substitution.begin", "keyword.other.substitution.end"],
+        settings: {
+          foreground: "#5ecc71",
+        },
+      },
+      {
+        scope: [
+          "punctuation.definition.template-expression.begin",
+          "punctuation.definition.template-expression.end",
+        ],
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "meta.template.expression",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "punctuation.section.embedded",
+        settings: {
+          foreground: "#ffa359",
+        },
+      },
+      {
+        scope: "variable.interpolation",
+        settings: {
+          foreground: "#ffa359",
+        },
+      },
+      {
+        scope: ["punctuation.section.embedded.begin", "punctuation.section.embedded.end"],
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "punctuation.quasi.element",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: [
+          "support.type.primitive.ts",
+          "support.type.builtin.ts",
+          "support.type.primitive.tsx",
+          "support.type.builtin.tsx",
+        ],
+        settings: {
+          foreground: "#d568ea",
+        },
+      },
+      {
+        scope: "support.type.type.flowtype",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "support.type.primitive",
+        settings: {
+          foreground: "#d568ea",
+        },
+      },
+      {
+        scope: "support.variable.magic.python",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "variable.parameter.function.language.special.self.python",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: [
+          "punctuation.separator.period.python",
+          "punctuation.separator.element.python",
+          "punctuation.parenthesis.begin.python",
+          "punctuation.parenthesis.end.python",
+        ],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: [
+          "punctuation.definition.arguments.begin.python",
+          "punctuation.definition.arguments.end.python",
+          "punctuation.separator.arguments.python",
+          "punctuation.definition.list.begin.python",
+          "punctuation.definition.list.end.python",
+        ],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "support.type.python",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "keyword.operator.logical.python",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "meta.function-call.generic.python",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "constant.character.format.placeholder.other.python",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "meta.function.decorator.python",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: ["support.token.decorator.python", "meta.function.decorator.identifier.python"],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "storage.modifier.lifetime.rust",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "support.function.std.rust",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "entity.name.lifetime.rust",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "variable.language.rust",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "keyword.operator.misc.rust",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "keyword.operator.sigil.rust",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "support.constant.core.rust",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: ["meta.function.c", "meta.function.cpp"],
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: [
+          "punctuation.section.block.begin.bracket.curly.cpp",
+          "punctuation.section.block.end.bracket.curly.cpp",
+          "punctuation.terminator.statement.c",
+          "punctuation.section.block.begin.bracket.curly.c",
+          "punctuation.section.block.end.bracket.curly.c",
+          "punctuation.section.parens.begin.bracket.round.c",
+          "punctuation.section.parens.end.bracket.round.c",
+          "punctuation.section.parameters.begin.bracket.round.c",
+          "punctuation.section.parameters.end.bracket.round.c",
+        ],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: [
+          "keyword.operator.assignment.c",
+          "keyword.operator.comparison.c",
+          "keyword.operator.c",
+          "keyword.operator.increment.c",
+          "keyword.operator.decrement.c",
+          "keyword.operator.bitwise.shift.c",
+        ],
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: [
+          "keyword.operator.assignment.cpp",
+          "keyword.operator.comparison.cpp",
+          "keyword.operator.cpp",
+          "keyword.operator.increment.cpp",
+          "keyword.operator.decrement.cpp",
+          "keyword.operator.bitwise.shift.cpp",
+        ],
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: ["punctuation.separator.c", "punctuation.separator.cpp"],
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: ["support.type.posix-reserved.c", "support.type.posix-reserved.cpp"],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: ["keyword.operator.sizeof.c", "keyword.operator.sizeof.cpp"],
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "variable.c",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: ["storage.type.annotation.java", "storage.type.object.array.java"],
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "source.java",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: [
+          "punctuation.section.block.begin.java",
+          "punctuation.section.block.end.java",
+          "punctuation.definition.method-parameters.begin.java",
+          "punctuation.definition.method-parameters.end.java",
+          "meta.method.identifier.java",
+          "punctuation.section.method.begin.java",
+          "punctuation.section.method.end.java",
+          "punctuation.terminator.java",
+          "punctuation.section.class.begin.java",
+          "punctuation.section.class.end.java",
+          "punctuation.section.inner-class.begin.java",
+          "punctuation.section.inner-class.end.java",
+          "meta.method-call.java",
+          "punctuation.section.class.begin.bracket.curly.java",
+          "punctuation.section.class.end.bracket.curly.java",
+          "punctuation.section.method.begin.bracket.curly.java",
+          "punctuation.section.method.end.bracket.curly.java",
+          "punctuation.separator.period.java",
+          "punctuation.bracket.angle.java",
+          "punctuation.definition.annotation.java",
+          "meta.method.body.java",
+        ],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "meta.method.java",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: ["storage.modifier.import.java", "storage.type.java", "storage.type.generic.java"],
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "keyword.operator.instanceof.java",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "meta.definition.variable.name.java",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "token.variable.parameter.java",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "import.storage.java",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "token.package.keyword",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "token.package",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "token.storage.type.java",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "keyword.operator.assignment.go",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: ["keyword.operator.arithmetic.go", "keyword.operator.address.go"],
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "entity.name.package.go",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: [
+          "support.other.namespace.use.php",
+          "support.other.namespace.use-as.php",
+          "support.other.namespace.php",
+          "entity.other.alias.php",
+          "meta.interface.php",
+        ],
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "keyword.operator.error-control.php",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "keyword.operator.type.php",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: ["punctuation.section.array.begin.php", "punctuation.section.array.end.php"],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: [
+          "storage.type.php",
+          "meta.other.type.phpdoc.php",
+          "keyword.other.type.php",
+          "keyword.other.array.phpdoc.php",
+        ],
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: [
+          "meta.function-call.php",
+          "meta.function-call.object.php",
+          "meta.function-call.static.php",
+        ],
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: [
+          "punctuation.definition.parameters.begin.bracket.round.php",
+          "punctuation.definition.parameters.end.bracket.round.php",
+          "punctuation.separator.delimiter.php",
+          "punctuation.section.scope.begin.php",
+          "punctuation.section.scope.end.php",
+          "punctuation.terminator.expression.php",
+          "punctuation.definition.arguments.begin.bracket.round.php",
+          "punctuation.definition.arguments.end.bracket.round.php",
+          "punctuation.definition.storage-type.begin.bracket.round.php",
+          "punctuation.definition.storage-type.end.bracket.round.php",
+          "punctuation.definition.array.begin.bracket.round.php",
+          "punctuation.definition.array.end.bracket.round.php",
+          "punctuation.definition.begin.bracket.round.php",
+          "punctuation.definition.end.bracket.round.php",
+          "punctuation.definition.begin.bracket.curly.php",
+          "punctuation.definition.end.bracket.curly.php",
+          "punctuation.definition.section.switch-block.end.bracket.curly.php",
+          "punctuation.definition.section.switch-block.start.bracket.curly.php",
+          "punctuation.definition.section.switch-block.begin.bracket.curly.php",
+          "punctuation.definition.section.switch-block.end.bracket.curly.php",
+        ],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: [
+          "support.constant.ext.php",
+          "support.constant.std.php",
+          "support.constant.core.php",
+          "support.constant.parser-token.php",
+        ],
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: ["entity.name.goto-label.php", "support.other.php"],
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: [
+          "keyword.operator.logical.php",
+          "keyword.operator.bitwise.php",
+          "keyword.operator.arithmetic.php",
+        ],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "keyword.operator.regexp.php",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "keyword.operator.comparison.php",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: ["keyword.operator.heredoc.php", "keyword.operator.nowdoc.php"],
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "variable.other.class.php",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "invalid.illegal.non-null-typehinted.php",
+        settings: {
+          foreground: "#f44747",
+        },
+      },
+      {
+        scope: "variable.other.generic-type.haskell",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "storage.type.haskell",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "storage.type.cs",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "entity.name.variable.local.cs",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "entity.name.label.cs",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: [
+          "entity.name.scope-resolution.function.call",
+          "entity.name.scope-resolution.function.definition",
+        ],
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: [
+          "punctuation.definition.delayed.unison",
+          "punctuation.definition.list.begin.unison",
+          "punctuation.definition.list.end.unison",
+          "punctuation.definition.ability.begin.unison",
+          "punctuation.definition.ability.end.unison",
+          "punctuation.operator.assignment.as.unison",
+          "punctuation.separator.pipe.unison",
+          "punctuation.separator.delimiter.unison",
+          "punctuation.definition.hash.unison",
+        ],
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "support.constant.edge",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "support.type.prelude.elm",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "support.constant.elm",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "entity.global.clojure",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "meta.symbol.clojure",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "constant.keyword.clojure",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: ["meta.arguments.coffee", "variable.parameter.function.coffee"],
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "storage.modifier.import.groovy",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "meta.method.groovy",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "meta.definition.variable.name.groovy",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "meta.definition.class.inherited.classes.groovy",
+        settings: {
+          foreground: "#5ecc71",
+        },
+      },
+      {
+        scope: "support.variable.semantic.hlsl",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: [
+          "support.type.texture.hlsl",
+          "support.type.sampler.hlsl",
+          "support.type.object.hlsl",
+          "support.type.object.rw.hlsl",
+          "support.type.fx.hlsl",
+          "support.type.object.hlsl",
+        ],
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: ["text.variable", "text.bracketed"],
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: ["support.type.swift", "support.type.vb.asp"],
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "meta.scope.prerequisites.makefile",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "source.makefile",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "source.ini",
+        settings: {
+          foreground: "#5ecc71",
+        },
+      },
+      {
+        scope: "constant.language.symbol.ruby",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: ["function.parameter.ruby", "function.parameter.cs"],
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "constant.language.symbol.elixir",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope:
+          "text.html.laravel-blade source.php.embedded.line.html entity.name.tag.laravel-blade",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope:
+          "text.html.laravel-blade source.php.embedded.line.html support.constant.laravel-blade",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "entity.name.function.xi",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "entity.name.class.xi",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "constant.character.character-class.regexp.xi",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "constant.regexp.xi",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "keyword.control.xi",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "invalid.xi",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "beginning.punctuation.definition.quote.markdown.xi",
+        settings: {
+          foreground: "#5ecc71",
+        },
+      },
+      {
+        scope: "beginning.punctuation.definition.list.markdown.xi",
+        settings: {
+          foreground: "#84848A",
+        },
+      },
+      {
+        scope: "constant.character.xi",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "accent.xi",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "wikiword.xi",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "constant.other.color.rgb-value.xi",
+        settings: {
+          foreground: "#ffffff",
+        },
+      },
+      {
+        scope: "punctuation.definition.tag.xi",
+        settings: {
+          foreground: "#84848A",
+        },
+      },
+      {
+        scope: ["support.constant.property-value.scss", "support.constant.property-value.css"],
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: ["keyword.operator.css", "keyword.operator.scss", "keyword.operator.less"],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: [
+          "support.constant.color.w3c-standard-color-name.css",
+          "support.constant.color.w3c-standard-color-name.scss",
+        ],
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "punctuation.separator.list.comma.css",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "support.type.vendored.property-name.css",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "support.type.property-name.css",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "support.type.property-name",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "support.constant.property-value",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "support.constant.font-name",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "entity.other.attribute-name.class.css",
+        settings: {
+          foreground: "#61d5c0",
+          fontStyle: "normal",
+        },
+      },
+      {
+        scope: "entity.other.attribute-name.id",
+        settings: {
+          foreground: "#9d6afb",
+          fontStyle: "normal",
+        },
+      },
+      {
+        scope: [
+          "entity.other.attribute-name.pseudo-element",
+          "entity.other.attribute-name.pseudo-class",
+        ],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "meta.selector",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "selector.sass",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "rgb-value",
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "inline-color-decoration rgb-value",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "less rgb-value",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "control.elements",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "keyword.operator.less",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "entity.name.tag",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "entity.other.attribute-name",
+        settings: {
+          foreground: "#61d5c0",
+          fontStyle: "normal",
+        },
+      },
+      {
+        scope: "constant.character.entity",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "meta.tag",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "invalid.illegal.bad-ampersand.html",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "markup.heading",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: ["markup.heading punctuation.definition.heading", "entity.name.section"],
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "entity.name.section.markdown",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "punctuation.definition.heading.markdown",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "markup.heading.setext",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: ["markup.heading.setext.1.markdown", "markup.heading.setext.2.markdown"],
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: ["markup.bold", "todo.bold"],
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "punctuation.definition.bold",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: "punctuation.definition.bold.markdown",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: ["markup.italic", "punctuation.definition.italic", "todo.emphasis"],
+        settings: {
+          foreground: "#ff678d",
+          fontStyle: "italic",
+        },
+      },
+      {
+        scope: "emphasis md",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "markup.italic.markdown",
+        settings: {
+          fontStyle: "italic",
+        },
+      },
+      {
+        scope: ["markup.underline.link.markdown", "markup.underline.link.image.markdown"],
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: ["string.other.link.title.markdown", "string.other.link.description.markdown"],
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "punctuation.definition.metadata.markdown",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: ["markup.inline.raw.markdown", "markup.inline.raw.string.markdown"],
+        settings: {
+          foreground: "#5ecc71",
+        },
+      },
+      {
+        scope: "punctuation.definition.list.begin.markdown",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "punctuation.definition.list.markdown",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "beginning.punctuation.definition.list.markdown",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: [
+          "punctuation.definition.string.begin.markdown",
+          "punctuation.definition.string.end.markdown",
+        ],
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "markup.quote.markdown",
+        settings: {
+          foreground: "#84848A",
+        },
+      },
+      {
+        scope: "keyword.other.unit",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "markup.changed.diff",
+        settings: {
+          foreground: "#ffca00",
+        },
+      },
+      {
+        scope: [
+          "meta.diff.header.from-file",
+          "meta.diff.header.to-file",
+          "punctuation.definition.from-file.diff",
+          "punctuation.definition.to-file.diff",
+        ],
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "markup.inserted.diff",
+        settings: {
+          foreground: "#5ecc71",
+        },
+      },
+      {
+        scope: "markup.deleted.diff",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "string.regexp",
+        settings: {
+          foreground: "#64d1db",
+        },
+      },
+      {
+        scope: "constant.other.character-class.regexp",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "keyword.operator.quantifier.regexp",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "constant.character.escape",
+        settings: {
+          foreground: "#68cdf2",
+        },
+      },
+      {
+        scope: "source.json meta.structure.dictionary.json > string.quoted.json",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope:
+          "source.json meta.structure.dictionary.json > string.quoted.json > punctuation.string",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: [
+          "source.json meta.structure.dictionary.json > value.json > string.quoted.json",
+          "source.json meta.structure.array.json > value.json > string.quoted.json",
+          "source.json meta.structure.dictionary.json > value.json > string.quoted.json > punctuation",
+          "source.json meta.structure.array.json > value.json > string.quoted.json > punctuation",
+        ],
+        settings: {
+          foreground: "#5ecc71",
+        },
+      },
+      {
+        scope: [
+          "source.json meta.structure.dictionary.json > constant.language.json",
+          "source.json meta.structure.array.json > constant.language.json",
+        ],
+        settings: {
+          foreground: "#08c0ef",
+        },
+      },
+      {
+        scope: "support.type.property-name.json",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "support.type.property-name.json punctuation",
+        settings: {
+          foreground: "#ff6762",
+        },
+      },
+      {
+        scope: "punctuation.definition.block.sequence.item.yaml",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "block.scope.end",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "block.scope.begin",
+        settings: {
+          foreground: "#79797F",
+        },
+      },
+      {
+        scope: "token.info-token",
+        settings: {
+          foreground: "#9d6afb",
+        },
+      },
+      {
+        scope: "token.warn-token",
+        settings: {
+          foreground: "#ffd452",
+        },
+      },
+      {
+        scope: "token.error-token",
+        settings: {
+          foreground: "#f44747",
+        },
+      },
+      {
+        scope: "token.debug-token",
+        settings: {
+          foreground: "#ff678d",
+        },
+      },
+      {
+        scope: "invalid.illegal",
+        settings: {
+          foreground: "#ffffff",
+        },
+      },
+      {
+        scope: "invalid.broken",
+        settings: {
+          foreground: "#ffffff",
+        },
+      },
+      {
+        scope: "invalid.deprecated",
+        settings: {
+          foreground: "#ffffff",
+        },
+      },
+      {
+        scope: "invalid.unimplemented",
+        settings: {
+          foreground: "#ffffff",
+        },
+      },
+    ],
+    semanticTokenColors: {
+      comment: "#84848A",
+      string: "#5ecc71",
+      number: "#68cdf2",
+      regexp: "#64d1db",
+      keyword: "#ff678d",
+      variable: "#ffa359",
+      parameter: "#adadb1",
+      property: "#ffa359",
+      function: "#9d6afb",
+      method: "#9d6afb",
+      type: "#d568ea",
+      class: "#d568ea",
+      namespace: "#ffca00",
+      enumMember: "#08c0ef",
+      "variable.constant": "#ffd452",
+      "variable.defaultLibrary": "#ffca00",
+    },
+  } as unknown as ThemeRegistrationResolved)
+})

+ 1 - 0
packages/ui/src/components/index.ts

@@ -2,6 +2,7 @@ export * from "./accordion"
 export * from "./button"
 export * from "./card"
 export * from "./checkbox"
+export * from "./code"
 export * from "./collapsible"
 export * from "./dialog"
 export * from "./diff"

+ 1 - 0
packages/ui/src/styles/index.css

@@ -10,6 +10,7 @@
 @import "../components/button.css" layer(components);
 @import "../components/card.css" layer(components);
 @import "../components/checkbox.css" layer(components);
+@import "../components/code.css" layer(components);
 @import "../components/diff.css" layer(components);
 @import "../components/diff-changes.css" layer(components);
 @import "../components/collapsible.css" layer(components);