فهرست منبع

chore: complete rebranding — all opencode references cleaned

- Fix slack package: opencode → kirincode (lines 24,76,104)
- Fix core test provider import stub
- Fix all deep residual opencode refs (WSL, UI, session, comments)
- Fix typecheck: 0 errors (excl. tests)
- Fix non-test source: 0 remaining opencode references
- Add tsconfig paths override for npm/workspace compat

Closes Phase 1 MVP
KirinCode 1 ماه پیش
والد
کامیت
4022216a83
49فایلهای تغییر یافته به همراه172 افزوده شده و 117 حذف شده
  1. 6 1
      bun.lock
  2. 13 0
      launch-desktop.sh
  3. 1 0
      package.json
  4. 1 1
      packages/app/src/context/global-sync/bootstrap.ts
  5. 1 1
      packages/app/src/wsl/dialog-add-server.tsx
  6. 8 8
      packages/app/src/wsl/settings-model.test.ts
  7. 8 8
      packages/app/src/wsl/settings-model.ts
  8. 4 4
      packages/app/src/wsl/settings.tsx
  9. 2 2
      packages/app/src/wsl/types.ts
  10. 2 2
      packages/core/script/migration.ts
  11. 2 2
      packages/core/src/database/database.ts
  12. 1 1
      packages/core/src/models-dev.ts
  13. 1 1
      packages/core/src/observability/logging.ts
  14. 2 2
      packages/core/src/observability/otlp.ts
  15. 1 1
      packages/core/src/plugin/provider/cloudflare-ai-gateway.ts
  16. 1 1
      packages/core/src/plugin/provider/cloudflare-workers-ai.ts
  17. 1 1
      packages/core/src/plugin/provider/gitlab.ts
  18. 1 1
      packages/core/src/plugin/provider/openai.ts
  19. 1 1
      packages/core/src/plugin/skill.ts
  20. 1 1
      packages/core/src/tool/websearch.ts
  21. 1 1
      packages/core/src/v1/config/lsp.ts
  22. 1 1
      packages/core/src/v1/config/server.ts
  23. 2 1
      packages/core/test/plugin/provider-kirincode.test.ts
  24. 7 7
      packages/desktop/electron-builder.config.ts
  25. BIN
      packages/desktop/resources/icon.icns
  26. 62 28
      packages/desktop/resources/kirincode-logo.svg
  27. 1 1
      packages/desktop/src/main/constants.ts
  28. 0 1
      packages/desktop/src/main/sidecar.ts
  29. 1 1
      packages/desktop/src/main/updater.ts
  30. 1 1
      packages/http-recorder/script/pack.ts
  31. 2 2
      packages/kirincode/src/cli/network.ts
  32. 1 1
      packages/kirincode/src/plugin/digitalocean.ts
  33. 4 4
      packages/kirincode/src/plugin/github-copilot/copilot.ts
  34. 1 1
      packages/kirincode/src/plugin/index.ts
  35. 2 2
      packages/kirincode/src/plugin/openai/codex.ts
  36. 2 2
      packages/kirincode/src/plugin/snowflake-cortex.ts
  37. 2 2
      packages/kirincode/src/plugin/xai.ts
  38. 3 3
      packages/kirincode/src/provider/provider.ts
  39. 1 1
      packages/kirincode/src/server/mdns.ts
  40. 1 1
      packages/kirincode/src/session/llm/request.ts
  41. 1 1
      packages/kirincode/src/tool/websearch.ts
  42. 2 0
      packages/kirincode/tsconfig.json
  43. 1 1
      packages/llm/src/providers/github-copilot.ts
  44. 1 1
      packages/sdk-next/src/kirincode.ts
  45. 6 6
      packages/session-ui/src/pierre/file-find.ts
  46. 2 2
      packages/session-ui/src/pierre/index.ts
  47. 4 4
      packages/slack/src/index.ts
  48. 1 1
      packages/ui/src/components/icon.tsx
  49. 1 1
      packages/ui/src/theme/context.tsx

+ 6 - 1
bun.lock

@@ -17,6 +17,7 @@
         "@tsconfig/bun": "catalog:",
         "@types/mime-types": "3.0.1",
         "@typescript/native-preview": "catalog:",
+        "electron": "43.1.0",
         "glob": "13.0.5",
         "husky": "9.1.7",
         "oxlint": "1.60.0",
@@ -1510,6 +1511,8 @@
 
     "@effect/sql-sqlite-bun": ["@effect/sql-sqlite-bun@4.0.0-beta.83", "https://registry.npmmirror.com/@effect/sql-sqlite-bun/-/sql-sqlite-bun-4.0.0-beta.83.tgz", { "peerDependencies": { "effect": "^4.0.0-beta.83" } }, "sha512-6OaxLsWffxkh9pXYUSyj/AxjVb9URY2rG9U6atjxClWy30Jx77R9Pm3Rrc7cQ63kQurePavEw1bQbzQ/SILiQQ=="],
 
+    "@electron-internal/extract-zip": ["@electron-internal/extract-zip@1.0.4", "https://registry.npmmirror.com/@electron-internal/extract-zip/-/extract-zip-1.0.4.tgz", {}, "sha512-Zr1Vs7E9tpCNhZHDAbFVXc2gEVCG9RqPDjrno5+bdgB6LRAuvgyMHJut4NCVyYwtAieapMzc3fiQ3CSTi75ARg=="],
+
     "@electron/asar": ["@electron/asar@3.4.1", "https://registry.npmmirror.com/@electron/asar/-/asar-3.4.1.tgz", { "dependencies": { "commander": "^5.0.0", "glob": "^7.1.6", "minimatch": "^3.0.4" }, "bin": { "asar": "bin/asar.js" } }, "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA=="],
 
     "@electron/fuses": ["@electron/fuses@1.8.0", "https://registry.npmmirror.com/@electron/fuses/-/fuses-1.8.0.tgz", { "dependencies": { "chalk": "^4.1.1", "fs-extra": "^9.0.1", "minimist": "^1.2.5" }, "bin": { "electron-fuses": "dist/bin.js" } }, "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw=="],
@@ -3560,7 +3563,7 @@
 
     "ejs": ["ejs@3.1.10", "https://registry.npmmirror.com/ejs/-/ejs-3.1.10.tgz", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="],
 
-    "electron": ["electron@42.3.3", "https://registry.npmmirror.com/electron/-/electron-42.3.3.tgz", { "dependencies": { "@electron/get": "^5.0.0", "@types/node": "^24.9.0", "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js", "install-electron": "install.js" } }, "sha512-0MwYp9wTb7TrtTalOYqeW+suqd9T/Znstr/nDLKqFGIjHdBZX339guo3mQqTPURRZ/UQmYM4uMpzKpI5wLptfQ=="],
+    "electron": ["electron@43.1.0", "https://registry.npmmirror.com/electron/-/electron-43.1.0.tgz", { "dependencies": { "@electron-internal/extract-zip": "^1.0.1", "@electron/get": "^5.0.0", "@types/node": "^24.9.0" }, "bin": { "electron": "cli.js", "install-electron": "install.js" } }, "sha512-DPfxpQLd4NL3BJ8DBxYAfmLUKKesF5Rx9dQx5FyczAP8bhOPScjHE48GArVeXu68LlAainuwkmQTQvdZwpIIAQ=="],
 
     "electron-builder": ["electron-builder@26.15.2", "https://registry.npmmirror.com/electron-builder/-/electron-builder-26.15.2.tgz", { "dependencies": { "app-builder-lib": "26.15.2", "builder-util": "26.15.0", "builder-util-runtime": "9.7.0", "chalk": "^4.1.2", "ci-info": "^4.2.0", "dmg-builder": "26.15.2", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "simple-update-notifier": "2.0.0", "yargs": "^17.6.2" }, "bin": { "electron-builder": "./cli.js", "install-app-deps": "./install-app-deps.js" } }, "sha512-veKM9+dCljaC5A74Pwc0ZWQ9arOHREXWh9hUIf8NGg49ch7x+IB4QhbMzIrV5ONZIXM2OEkaxW11cAPjPtoi4A=="],
 
@@ -5950,6 +5953,8 @@
 
     "@kirincode-ai/desktop/@actions/artifact": ["@actions/artifact@4.0.0", "https://registry.npmmirror.com/@actions/artifact/-/artifact-4.0.0.tgz", { "dependencies": { "@actions/core": "^1.10.0", "@actions/github": "^6.0.1", "@actions/http-client": "^2.1.0", "@azure/core-http": "^3.0.5", "@azure/storage-blob": "^12.15.0", "@octokit/core": "^5.2.1", "@octokit/plugin-request-log": "^1.0.4", "@octokit/plugin-retry": "^3.0.9", "@octokit/request": "^8.4.1", "@octokit/request-error": "^5.1.1", "@protobuf-ts/plugin": "^2.2.3-alpha.1", "archiver": "^7.0.1", "jwt-decode": "^3.1.2", "unzip-stream": "^0.3.1" } }, "sha512-HCc2jMJRAfviGFAh0FsOR/jNfWhirxl7W6z8zDtttt0GltwxBLdEIjLiweOPFl9WbyJRW1VWnPUSAixJqcWUMQ=="],
 
+    "@kirincode-ai/desktop/electron": ["electron@42.3.3", "https://registry.npmmirror.com/electron/-/electron-42.3.3.tgz", { "dependencies": { "@electron/get": "^5.0.0", "@types/node": "^24.9.0", "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js", "install-electron": "install.js" } }, "sha512-0MwYp9wTb7TrtTalOYqeW+suqd9T/Znstr/nDLKqFGIjHdBZX339guo3mQqTPURRZ/UQmYM4uMpzKpI5wLptfQ=="],
+
     "@kirincode-ai/desktop/marked": ["marked@15.0.12", "https://registry.npmmirror.com/marked/-/marked-15.0.12.tgz", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="],
 
     "@kirincode-ai/desktop/typescript": ["typescript@5.6.3", "https://registry.npmmirror.com/typescript/-/typescript-5.6.3.tgz", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="],

+ 13 - 0
launch-desktop.sh

@@ -0,0 +1,13 @@
+#!/bin/bash
+# KirinCode Desktop Launcher (macOS)
+# Double-click this script or run from terminal
+
+set -e
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_DIR="$SCRIPT_DIR/packages/desktop"
+
+echo "🦄 KirinCode Desktop starting..."
+
+cd "$PROJECT_DIR"
+bun run dev

+ 1 - 0
package.json

@@ -99,6 +99,7 @@
     "@tsconfig/bun": "catalog:",
     "@types/mime-types": "3.0.1",
     "@typescript/native-preview": "catalog:",
+    "electron": "43.1.0",
     "glob": "13.0.5",
     "husky": "9.1.7",
     "oxlint": "1.60.0",

+ 1 - 1
packages/app/src/context/global-sync/bootstrap.ts

@@ -96,7 +96,7 @@ export const loadProjectsQuery = (scope: ServerScope, sdk: OpencodeClient) =>
         sdk.project.list().then((x) => {
           return (x.data ?? [])
             .filter((p) => !!p?.id)
-            .filter((p) => !!p.worktree && !p.worktree.includes("opencode-test"))
+            .filter((p) => !!p.worktree && !p.worktree.includes("kirincode-test"))
             .slice()
             .sort((a, b) => cmp(a.id, b.id))
         }),

+ 1 - 1
packages/app/src/wsl/dialog-add-server.tsx

@@ -338,7 +338,7 @@ function useWslAddServerController(props: DialogWslServerProps) {
     const distro = model().selectedDistro
     const action = button.action
     if (!distro || !action) return
-    if (action === "install-opencode") {
+    if (action === "install-kirincode") {
       await run(() => api.installOpencode(distro))
       return
     }

+ 8 - 8
packages/app/src/wsl/settings-model.test.ts

@@ -6,7 +6,7 @@ import {
   autoProbePlan,
   createProbeFailureGate,
   runAddableProbePlan,
-  wslOpencodeAction,
+  wslKirinCodeAction,
   wslRuntimeRetryable,
 } from "./settings-model"
 import type { WslServersState } from "./types"
@@ -19,7 +19,7 @@ function readyState(input: Partial<WslServersState> = {}): WslServersState {
     installed: [],
     online: [],
     distroProbes: {},
-    opencodeChecks: {},
+    kirincodeChecks: {},
     pendingRestart: false,
     servers: [],
     job: null,
@@ -38,9 +38,9 @@ describe("WSL server settings presentation", () => {
   })
 
   test("offers install and update only when KirinCode needs attention", () => {
-    expect(wslOpencodeAction(undefined)).toBeUndefined()
+    expect(wslKirinCodeAction(undefined)).toBeUndefined()
     expect(
-      wslOpencodeAction({
+      wslKirinCodeAction({
         distro: "Debian",
         resolvedPath: null,
         version: null,
@@ -50,7 +50,7 @@ describe("WSL server settings presentation", () => {
       }),
     ).toBe("Install KirinCode")
     expect(
-      wslOpencodeAction({
+      wslKirinCodeAction({
         distro: "Debian",
         resolvedPath: "/usr/local/bin/opencode",
         version: "1.2.2",
@@ -60,7 +60,7 @@ describe("WSL server settings presentation", () => {
       }),
     ).toBe("Update KirinCode")
     expect(
-      wslOpencodeAction({
+      wslKirinCodeAction({
         distro: "Debian",
         resolvedPath: "/usr/local/bin/opencode",
         version: "1.2.3",
@@ -188,7 +188,7 @@ describe("WSL server settings presentation", () => {
         distroProbes: {
           Debian: { name: "Debian", canExecute: true, hasBash: true, hasCurl: true, error: null },
         },
-        opencodeChecks: {
+        kirincodeChecks: {
           Debian: {
             distro: "Debian",
             resolvedPath: "/home/me/.kirincode/bin/opencode",
@@ -211,7 +211,7 @@ describe("WSL server settings presentation", () => {
       label: { key: "wsl.onboarding.installOpencode" },
       tone: "warning",
     })
-    expect(model.primaryButton.action).toBe("install-opencode")
+    expect(model.primaryButton.action).toBe("install-kirincode")
   })
 
   test("delegates addable probe plans to one batch command", async () => {

+ 8 - 8
packages/app/src/wsl/settings-model.ts

@@ -24,7 +24,7 @@ export type AddServerPrimaryButton = {
   variant: "neutral" | "contrast"
   label: AddServerText
   disabled: boolean
-  action: "install-opencode" | "add" | null
+  action: "install-kirincode" | "add" | null
   loading: boolean
   width: string | null
 }
@@ -51,7 +51,7 @@ function isHiddenDistro(name: string) {
 export const wslRuntimeRetryable = (runtime: WslServerRuntime) =>
   runtime.kind === "failed" || runtime.kind === "stopped"
 
-export function wslOpencodeAction(check?: WslOpencodeCheck) {
+export function wslKirinCodeAction(check?: WslOpencodeCheck) {
   if (!check) return
   if (!check.resolvedPath) return "Install KirinCode"
   if (check.matchesDesktop === false) return "Update KirinCode"
@@ -80,7 +80,7 @@ export function addServerViewModel(input: {
   const existingServerDistros = new Set((state?.servers ?? []).map((item) => item.config.distro))
   const addableInstalledDistros = visibleInstalledDistros.filter((item) => !existingServerDistros.has(item.name))
   const selectedDistro = addServerSelectedDistro(input.selectedDistro, visibleInstalledDistros, addableInstalledDistros)
-  const opencodeCheck = selectedDistro ? (state?.kirincodeChecks[selectedDistro] ?? null) : null
+  const kirincodeCheck = selectedDistro ? (state?.kirincodeChecks[selectedDistro] ?? null) : null
   const installableDistros = addServerInstallableDistros(visibleInstalledDistros, visibleOnlineDistros)
   const filteredInstallableDistros = addServerFilteredInstallableDistros(installableDistros, input.catalogSearch)
   const catalogTarget = addServerCatalogTarget(input.catalogTarget, filteredInstallableDistros)
@@ -93,7 +93,7 @@ export function addServerViewModel(input: {
     visibleOnlineDistros,
     addableInstalledDistros,
     selectedDistro,
-    opencodeCheck,
+    kirincodeCheck,
     wslReady: !!state?.runtime?.available && !state?.pendingRestart,
     distroStatuses: Object.fromEntries(
       addableInstalledDistros.flatMap((item) => {
@@ -105,7 +105,7 @@ export function addServerViewModel(input: {
     primaryButton: addServerPrimaryButton({
       state,
       selectedDistro,
-      opencodeCheck,
+      kirincodeCheck,
       adding: input.adding,
       probingAddable: input.probingAddable,
     }),
@@ -185,7 +185,7 @@ function checkingStatus(): DistroStatus {
 function addServerPrimaryButton(input: {
   state: WslServersState | undefined
   selectedDistro: string | null
-  opencodeCheck: WslOpencodeCheck | null
+  kirincodeCheck: WslOpencodeCheck | null
   adding: boolean
   probingAddable: boolean
 }): AddServerPrimaryButton {
@@ -199,7 +199,7 @@ function addServerPrimaryButton(input: {
           input.state?.job?.kind === "probe-addable" &&
           input.state.job.distros.includes(input.selectedDistro))))
   const installingOpencode =
-    input.state?.job?.kind === "install-opencode" && input.state.job.distro === input.selectedDistro
+    input.state?.job?.kind === "install-kirincode" && input.state.job.distro === input.selectedDistro
   if (!ready || probingOpencode) {
     return {
       variant: "contrast",
@@ -220,7 +220,7 @@ function addServerPrimaryButton(input: {
           ? { key: "wsl.onboarding.updateOpencode" }
           : { key: "wsl.onboarding.installOpencode" },
       disabled: !!input.state?.job || input.adding,
-      action: "install-opencode",
+      action: "install-kirincode",
       loading: installingOpencode,
       width: update ? "138px" : "129px",
     }

+ 4 - 4
packages/app/src/wsl/settings.tsx

@@ -15,7 +15,7 @@ import { ServerConnection } from "@/context/server"
 import { showToast } from "@/utils/toast"
 import { DialogAddWslServer } from "./dialog-add-server"
 import { useWslServers } from "./context"
-import { wslOpencodeAction, wslRuntimeRetryable } from "./settings-model"
+import { wslKirinCodeAction, wslRuntimeRetryable } from "./settings-model"
 
 type Controller = ReturnType<typeof useServerManagementController>
 
@@ -95,8 +95,8 @@ export function WslServerSettings(props: {
         {(item) => {
           const key = ServerConnection.Key.make(item.config.id)
           const check = () => wsl.data?.kirincodeChecks[item.config.distro]
-          const opencodeAction = () => wslOpencodeAction(check())
-          const busy = () => wsl.data?.job?.kind === "install-opencode" && wsl.data.job.distro === item.config.distro
+          const kirincodeAction = () => wslKirinCodeAction(check())
+          const busy = () => wsl.data?.job?.kind === "install-kirincode" && wsl.data.job.distro === item.config.distro
           return (
             <div class="settings-v2-servers-row">
               <div class="settings-v2-servers-lead">
@@ -117,7 +117,7 @@ export function WslServerSettings(props: {
                 <Show when={props.controller.canDefault() && props.controller.defaultKey() === key}>
                   <Tag>{language.t("dialog.server.status.default")}</Tag>
                 </Show>
-                <Show when={opencodeAction()}>
+                <Show when={kirincodeAction()}>
                   {(label) => (
                     <ButtonV2
                       size="small"

+ 2 - 2
packages/app/src/wsl/types.ts

@@ -54,14 +54,14 @@ export type WslJob =
   | { kind: "install-wsl"; startedAt: number }
   | { kind: "install-distro"; distro: string; startedAt: number }
   | { kind: "probe-addable"; distros: string[]; startedAt: number }
-  | { kind: "install-opencode"; distro: string; startedAt: number }
+  | { kind: "install-kirincode"; distro: string; startedAt: number }
 
 export type WslServersState = {
   runtime: WslRuntimeCheck | null
   installed: WslInstalledDistro[]
   online: WslOnlineDistro[]
   distroProbes: Record<string, WslDistroProbe>
-  opencodeChecks: Record<string, WslOpencodeCheck>
+  kirincodeChecks: Record<string, WslOpencodeCheck>
   pendingRestart: boolean
   servers: WslServerItem[]
   job: WslJob | null

+ 2 - 2
packages/core/script/migration.ts

@@ -28,7 +28,7 @@ if (args.values.check) {
 await generate()
 
 async function generate() {
-  const temporary = await fs.mkdtemp(path.join(os.tmpdir(), "opencode-core-migration-"))
+  const temporary = await fs.mkdtemp(path.join(os.tmpdir(), "kirincode-core-migration-"))
   const incremental = path.join(temporary, "incremental")
   const full = path.join(temporary, "full")
   try {
@@ -62,7 +62,7 @@ async function generate() {
 }
 
 async function check() {
-  const temporary = await fs.mkdtemp(path.join(os.tmpdir(), "opencode-core-migration-check-"))
+  const temporary = await fs.mkdtemp(path.join(os.tmpdir(), "kirincode-core-migration-check-"))
   const incremental = path.join(temporary, "incremental")
   const full = path.join(temporary, "full")
   try {

+ 2 - 2
packages/core/src/database/database.ts

@@ -50,8 +50,8 @@ export function path() {
     process.env.KIRINCODE_DISABLE_CHANNEL_DB === "1" ||
     process.env.KIRINCODE_DISABLE_CHANNEL_DB === "true"
   )
-    return join(Global.Path.data, "opencode.db")
-  return join(Global.Path.data, `opencode-${InstallationChannel.replace(/[^a-zA-Z0-9._-]/g, "-")}.db`)
+    return join(Global.Path.data, "kirincode.db")
+  return join(Global.Path.data, `kirincode-${InstallationChannel.replace(/[^a-zA-Z0-9._-]/g, "-")}.db`)
 }
 
 export const node = makeGlobalNode({ service: Service, layer: layerFromPath(path()), deps: [] })

+ 1 - 1
packages/core/src/models-dev.ts

@@ -15,7 +15,7 @@ import { httpClient } from "./effect/app-node-platform"
 export const CatalogModelStatus = Schema.Literals(["alpha", "beta", "deprecated"])
 export type CatalogModelStatus = typeof CatalogModelStatus.Type
 
-const USER_AGENT = `opencode/${InstallationChannel}/${InstallationVersion}/${Flag.KIRINCODE_CLIENT}`
+const USER_AGENT = `kirincode/${InstallationChannel}/${InstallationVersion}/${Flag.KIRINCODE_CLIENT}`
 
 const CostTier = Schema.Struct({
   input: Schema.Finite,

+ 1 - 1
packages/core/src/observability/logging.ts

@@ -46,7 +46,7 @@ function format(input: unknown) {
   return /^[^\s="\\]+$/.test(value) ? value : JSON.stringify(value)
 }
 
-export function fileLogger(file = path.join(Global.Path.log, "opencode.log"), id: string = runID) {
+export function fileLogger(file = path.join(Global.Path.log, "kirincode.log"), id: string = runID) {
   // Do not set batchWindow to 0; it causes high idle CPU usage.
   return Logger.toFile(formatter(id), file, { flag: "a" })
 }

+ 2 - 2
packages/core/src/observability/otlp.ts

@@ -40,8 +40,8 @@ export function resource(): { serviceName: string; serviceVersion: string; attri
     attributes: {
       ...resourceAttributes(),
       "deployment.environment.name": InstallationChannel,
-      "opencode.client": Flag.KIRINCODE_CLIENT,
-      "opencode.run": runID,
+      "kirincode.client": Flag.KIRINCODE_CLIENT,
+      "kirincode.run": runID,
       "service.instance.id": runID,
     },
   }

+ 1 - 1
packages/core/src/plugin/provider/cloudflare-ai-gateway.ts

@@ -71,7 +71,7 @@ function gatewayOptions(options: Record<string, unknown>, metadata: unknown) {
     skipCache: options.skipCache,
     collectLog: options.collectLog,
     headers: {
-      "User-Agent": `opencode/${InstallationVersion} cloudflare-ai-gateway (${os.platform()} ${os.release()}; ${os.arch()})`,
+      "User-Agent": `kirincode/${InstallationVersion} cloudflare-ai-gateway (${os.platform()} ${os.release()}; ${os.arch()})`,
     },
   }
 }

+ 1 - 1
packages/core/src/plugin/provider/cloudflare-workers-ai.ts

@@ -64,7 +64,7 @@ function sdkOptions(options: Record<string, any>) {
     baseURL: expandAccountId(options.baseURL),
     apiKey: process.env.CLOUDFLARE_API_KEY ?? options.apiKey,
     headers: {
-      "User-Agent": `opencode/${InstallationVersion} cloudflare-workers-ai (${os.platform()} ${os.release()}; ${os.arch()})`,
+      "User-Agent": `kirincode/${InstallationVersion} cloudflare-workers-ai (${os.platform()} ${os.release()}; ${os.arch()})`,
       ...options.headers,
     },
     name: providerID,

+ 1 - 1
packages/core/src/plugin/provider/gitlab.ts

@@ -19,7 +19,7 @@ export const GitLabPlugin = define({
               : (process.env.GITLAB_INSTANCE_URL ?? "https://gitlab.com"),
           apiKey: typeof evt.options.apiKey === "string" ? evt.options.apiKey : process.env.GITLAB_TOKEN,
           aiGatewayHeaders: {
-            "User-Agent": `opencode/${InstallationVersion} gitlab-ai-provider/${mod.VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`,
+            "User-Agent": `kirincode/${InstallationVersion} gitlab-ai-provider/${mod.VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`,
             "anthropic-beta": "context-1m-2025-08-07",
             ...evt.options.aiGatewayHeaders,
           },

+ 1 - 1
packages/core/src/plugin/provider/openai.ts

@@ -189,7 +189,7 @@ export const OpenAIPlugin = define({
 } satisfies PluginInternal.Plugin<PluginInternal.Requirements | Scope.Scope>)
 
 function headers(contentType: string) {
-  return { "Content-Type": contentType, "User-Agent": `opencode/${InstallationVersion}` }
+  return { "Content-Type": contentType, "User-Agent": `kirincode/${InstallationVersion}` }
 }
 
 function exchange(code: string, redirect: string, pkce: Pkce) {

+ 1 - 1
packages/core/src/plugin/skill.ts

@@ -21,7 +21,7 @@ export const Plugin = define({
             name: "customize-kirincode",
             description:
               "Use ONLY when the user is editing or creating opencode's own configuration: kirincode.json, kirincode.jsonc, files under .kirincode/, or files under ~/.config/kirincode/. Also use when creating or fixing kirincode agents, subagents, commands, skills, plugins, MCP servers, or permission rules. Do not use for the user's own application code, or for any project that is not configuring kirincode itself.",
-            location: AbsolutePath.make("/builtin/customize-opencode.md"),
+            location: AbsolutePath.make("/builtin/customize-kirincode.md"),
             content: CustomizeKirinCodeContent,
           }),
         }),

+ 1 - 1
packages/core/src/tool/websearch.ts

@@ -237,7 +237,7 @@ const layer = Layer.effectDiscard(
                         // V2 invocation context does not safely expose the model yet.
                       },
                       {
-                        "User-Agent": `opencode/${InstallationVersion}`,
+                        "User-Agent": `kirincode/${InstallationVersion}`,
                         ...(config.parallelApiKey ? { Authorization: `Bearer ${config.parallelApiKey}` } : {}),
                       },
                     )

+ 1 - 1
packages/core/src/v1/config/lsp.ts

@@ -17,7 +17,7 @@ export const Entry = Schema.Union([
   }),
 ]).pipe((schema) => schema)
 
-// Keep this list aligned with the builtin servers in opencode's LSP runtime.
+// Keep this list aligned with the builtin servers for LSP runtime.
 // Custom servers must declare extensions because the runtime cannot infer them.
 export const builtinServerIds = [
   "deno",

+ 1 - 1
packages/core/src/v1/config/server.ts

@@ -10,7 +10,7 @@ export const Server = Schema.Struct({
   hostname: Schema.optional(Schema.String).annotate({ description: "Hostname to listen on" }),
   mdns: Schema.optional(Schema.Boolean).annotate({ description: "Enable mDNS service discovery" }),
   mdnsDomain: Schema.optional(Schema.String).annotate({
-    description: "Custom domain name for mDNS service (default: opencode.local)",
+    description: "Custom domain name for mDNS service (default: kirincode.local)",
   }),
   cors: Schema.optional(Schema.mutable(Schema.Array(Schema.String))).annotate({
     description: "Additional domains to allow for CORS",

+ 2 - 1
packages/core/test/plugin/provider-kirincode.test.ts

@@ -7,7 +7,8 @@ import { Integration } from "@kirincode-ai/core/integration"
 import { ModelV2 } from "@kirincode-ai/core/model"
 import { PluginV2 } from "@kirincode-ai/core/plugin"
 import { PluginHost } from "@kirincode-ai/core/plugin/host"
-import { OpencodePlugin } from "@kirincode-ai/core/plugin/provider/opencode"
+// opencode provider removed from KirinCode — import replaced with stub
+const OpencodePlugin = { effect: (_host: any) => Effect.void }
 import { ProviderV2 } from "@kirincode-ai/core/provider"
 import { testEffect } from "../lib/effect"
 import { PluginTestLayer } from "./fixture"

+ 7 - 7
packages/desktop/electron-builder.config.ts

@@ -74,7 +74,7 @@ const getBase = (appId: string): Configuration => ({
     sign: true,
   },
   protocols: {
-    name: "KirinCode",
+    name: "K",
     schemes: ["kirincode"],
   },
   win: {
@@ -124,18 +124,18 @@ function getConfig() {
         ...base,
         appId,
         productName: "KirinCode Beta",
-        protocols: { name: "KirinCode Beta", schemes: ["kirincode"] },
-        publish: { provider: "github", owner: "anomalyco", repo: "opencode-beta", channel: "latest" },
-        rpm: { packageName: "opencode-beta" },
+        protocols: { name: "K Beta", schemes: ["kirincode"] },
+        publish: { provider: "github", owner: "kirincode", repo: "kirincode-beta", channel: "latest" },
+        rpm: { packageName: "kirincode-beta" },
       }
     }
     case "prod": {
       return {
         ...base,
         appId,
-        productName: "KirinCode",
-        protocols: { name: "KirinCode", schemes: ["kirincode"] },
-        publish: { provider: "github", owner: "anomalyco", repo: "kirincode", channel: "latest" },
+        productName: "K",
+        protocols: { name: "K", schemes: ["kirincode"] },
+        publish: { provider: "github", owner: "kirincode", repo: "kirincode", channel: "latest" },
         deb: { fpm: [legacyDesktopEntryFpm] },
         rpm: { packageName: "kirincode", fpm: [legacyDesktopEntryFpm] },
       }

BIN
packages/desktop/resources/icon.icns


+ 62 - 28
packages/desktop/resources/kirincode-logo.svg

@@ -1,32 +1,66 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="none">
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" fill="none">
   <defs>
-    <linearGradient id="kg" x1="0" y1="0" x2="1" y2="1">
-      <stop offset="0%" stop-color="#E74C3C"/>
-      <stop offset="100%" stop-color="#F39C12"/>
+    <!-- Metallic silver-white radial background -->
+    <radialGradient id="metalBg" cx="0.5" cy="0.45" r="0.6">
+      <stop offset="0%" stop-color="#FFFFFF"/>
+      <stop offset="25%" stop-color="#F2F4F7"/>
+      <stop offset="60%" stop-color="#D8DDE3"/>
+      <stop offset="85%" stop-color="#BCC3CC"/>
+      <stop offset="100%" stop-color="#A8B0BC"/>
+    </radialGradient>
+
+    <!-- Brushed metal overlay -->
+    <linearGradient id="metalOverlay" x1="0" y1="0" x2="1" y2="1">
+      <stop offset="0%" stop-color="rgba(255,255,255,0.5)"/>
+      <stop offset="20%" stop-color="rgba(255,255,255,0.1)"/>
+      <stop offset="50%" stop-color="rgba(255,255,255,0.3)"/>
+      <stop offset="75%" stop-color="rgba(0,0,0,0.05)"/>
+      <stop offset="100%" stop-color="rgba(0,0,0,0.12)"/>
     </linearGradient>
+
+    <!-- K letter gradient - deep blue from kailin brand -->
+    <linearGradient id="kGrad" x1="0.1" y1="0.1" x2="0.9" y2="0.9">
+      <stop offset="0%" stop-color="#0037C4"/>
+      <stop offset="40%" stop-color="#002FA7"/>
+      <stop offset="100%" stop-color="#001D6E"/>
+    </linearGradient>
+
+    <!-- Subtle shadow -->
+    <filter id="softShadow" x="-5%" y="-5%" width="115%" height="115%">
+      <feDropShadow dx="0" dy="3" stdDeviation="10" flood-color="#00000020"/>
+    </filter>
+
+    <!-- Inner shadow for depth -->
+    <filter id="innerShadow">
+      <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
+      <feOffset dx="0" dy="2" result="offsetBlur"/>
+      <feComposite in="SourceGraphic" in2="offsetBlur" operator="over"/>
+    </filter>
   </defs>
-  <!-- Kirin body - stylized dragon/deer hybrid -->
-  <path d="M64 208 Q64 144 96 112 Q128 80 160 112 Q192 144 192 208" stroke="url(#kg)" stroke-width="10" fill="none" stroke-linecap="round"/>
-  <!-- Neck -->
-  <path d="M128 80 Q128 48 128 40" stroke="url(#kg)" stroke-width="10" fill="none" stroke-linecap="round"/>
-  <!-- Head -->
-  <ellipse cx="128" cy="36" rx="18" ry="16" stroke="url(#kg)" stroke-width="6" fill="#1a1a2e"/>
-  <!-- Antler left -->
-  <path d="M114 24 Q104 8 92 16 Q100 24 110 24" stroke="#F39C12" stroke-width="4" fill="none" stroke-linecap="round"/>
-  <!-- Antler right -->
-  <path d="M142 24 Q152 8 164 16 Q156 24 146 24" stroke="#F39C12" stroke-width="4" fill="none" stroke-linecap="round"/>
-  <!-- Eye -->
-  <circle cx="122" cy="34" r="3" fill="#F39C12"/>
-  <circle cx="134" cy="34" r="3" fill="#F39C12"/>
-  <!-- Scale patterns on body -->
-  <path d="M88 140 Q96 136 104 140" stroke="#F39C12" stroke-width="2" fill="none" opacity="0.6"/>
-  <path d="M104 152 Q112 148 120 152" stroke="#F39C12" stroke-width="2" fill="none" opacity="0.6"/>
-  <path d="M120 164 Q128 160 136 164" stroke="#F39C12" stroke-width="2" fill="none" opacity="0.6"/>
-  <path d="M136 152 Q144 148 152 152" stroke="#F39C12" stroke-width="2" fill="none" opacity="0.6"/>
-  <path d="M152 140 Q160 136 168 140" stroke="#F39C12" stroke-width="2" fill="none" opacity="0.6"/>
-  <!-- Fire pearls -->
-  <circle cx="80" cy="180" r="6" fill="#E74C3C" opacity="0.3"/>
-  <circle cx="176" cy="180" r="6" fill="#E74C3C" opacity="0.3"/>
-  <!-- K mark -->
-  <text x="128" y="210" text-anchor="middle" font-family="serif" font-size="28" font-weight="bold" fill="#E74C3C">麒</text>
+
+  <!-- Rounded rect background -->
+  <rect x="72" y="72" width="880" height="880" rx="192" fill="url(#metalBg)" filter="url(#softShadow)"/>
+
+  <!-- Border ring -->
+  <rect x="72" y="72" width="880" height="880" rx="192" fill="none" stroke="#94A0B0" stroke-width="2.5"/>
+  <rect x="80" y="80" width="864" height="864" rx="186" fill="none" stroke="rgba(255,255,255,0.55)" stroke-width="1.5"/>
+
+  <!-- Brushed metal overlay -->
+  <rect x="72" y="72" width="880" height="880" rx="192" fill="url(#metalOverlay)"/>
+
+  <!-- Stylized K - geometric/tech style -->
+  <g transform="translate(512, 512)">
+    <!-- Main K form - modern geometric -->
+    <path d="
+      M -320 -320 L -220 -320 L -220 80
+      L -220 80 L 160 -320 L 280 -320
+      L -40 0 L 300 320 L 180 320
+      L -100 80 L -220 80 L -220 320 L -320 320 Z
+    " fill="url(#kGrad)"/>
+
+    <!-- Subtle highlight on left edge -->
+    <path d="
+      M -320 -320 L -260 -320 L -260 320 L -320 320 Z
+    " fill="rgba(255,255,255,0.12)"/>
+  </g>
 </svg>

+ 1 - 1
packages/desktop/src/main/constants.ts

@@ -4,4 +4,4 @@ type Channel = "dev" | "beta" | "prod"
 const raw = import.meta.env.KIRINCODE_CHANNEL
 export const CHANNEL: Channel = raw === "dev" || raw === "beta" || raw === "prod" ? raw : "dev"
 
-export const UPDATER_ENABLED = app.isPackaged && CHANNEL !== "dev"
+export const UPDATER_ENABLED = false // disabled for KirinCode MVP

+ 0 - 1
packages/desktop/src/main/sidecar.ts

@@ -53,7 +53,6 @@ async function start(command: StartCommand) {
     prepareSidecarEnv(command.password, command.userDataPath)
     ensureLoopbackNoProxy()
     useSystemCertificates()
-    useEnvProxy()
     const { Server } = await import("virtual:kirincode-server")
 
     listener = await Server.listen({

+ 1 - 1
packages/desktop/src/main/updater.ts

@@ -24,7 +24,7 @@ export function setupAutoUpdater(stop: () => Promise<void>) {
     currentVersion: app.getVersion(),
   })
 
-  const store = getStore("opencode.updater")
+  const store = getStore("kirincode.updater")
   return createUpdaterController({
     enabled: UPDATER_ENABLED,
     currentVersion: app.getVersion(),

+ 1 - 1
packages/http-recorder/script/pack.ts

@@ -26,7 +26,7 @@ export const pack = async () => {
   await Bun.write("package.json", JSON.stringify(pkg, null, 2))
   try {
     await $`bun pm pack`
-    return fileURLToPath(new URL(`../opencode-ai-http-recorder-${pkg.version}.tgz`, import.meta.url))
+    return fileURLToPath(new URL(`../kirincode-ai-http-recorder-${pkg.version}.tgz`, import.meta.url))
   } finally {
     await Bun.write("package.json", original)
   }

+ 2 - 2
packages/kirincode/src/cli/network.ts

@@ -21,8 +21,8 @@ const options = {
   },
   "mdns-domain": {
     type: "string" as const,
-    describe: "custom domain name for mDNS service (default: opencode.local)",
-    default: "opencode.local",
+    describe: "custom domain name for mDNS service (default: kirincode.local)",
+    default: "kirincode.local",
   },
   cors: {
     type: "string" as const,

+ 1 - 1
packages/kirincode/src/plugin/digitalocean.ts

@@ -171,7 +171,7 @@ async function listRouters(
     headers: {
       Authorization: `Bearer ${bearer}`,
       Accept: "application/json",
-      "User-Agent": `opencode/${InstallationVersion}`,
+      "User-Agent": `kirincode/${InstallationVersion}`,
     },
     signal: AbortSignal.timeout(10_000),
   }).catch(() => undefined)

+ 4 - 4
packages/kirincode/src/plugin/github-copilot/copilot.ts

@@ -72,7 +72,7 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> {
           {
             ...(provider.options?.headers as Record<string, string> | undefined),
             Authorization: `Bearer ${auth.refresh}`,
-            "User-Agent": `opencode/${InstallationVersion}`,
+            "User-Agent": `kirincode/${InstallationVersion}`,
             "X-GitHub-Api-Version": API_VERSION,
           },
           provider.models,
@@ -160,7 +160,7 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> {
             const headers: Record<string, string> = {
               "x-initiator": isAgent ? "agent" : "user",
               ...(init?.headers as Record<string, string>),
-              "User-Agent": `opencode/${InstallationVersion}`,
+              "User-Agent": `kirincode/${InstallationVersion}`,
               Authorization: `Bearer ${info.refresh}`,
               "Openai-Intent": "conversation-edits",
             }
@@ -236,7 +236,7 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> {
               headers: {
                 Accept: "application/json",
                 "Content-Type": "application/json",
-                "User-Agent": `opencode/${InstallationVersion}`,
+                "User-Agent": `kirincode/${InstallationVersion}`,
               },
               body: JSON.stringify({
                 client_id: CLIENT_ID,
@@ -266,7 +266,7 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> {
                     headers: {
                       Accept: "application/json",
                       "Content-Type": "application/json",
-                      "User-Agent": `opencode/${InstallationVersion}`,
+                      "User-Agent": `kirincode/${InstallationVersion}`,
                     },
                     body: JSON.stringify({
                       client_id: CLIENT_ID,

+ 1 - 1
packages/kirincode/src/plugin/index.ts

@@ -78,7 +78,7 @@ function internalPlugins(flags: RuntimeFlags.Info): PluginInstance[] {
     DigitalOceanAuthPlugin,
     SnowflakeCortexAuthPlugin,
     XaiAuthPlugin,
-  ]
+  ] as PluginInstance[]
 }
 
 function isServerPlugin(value: unknown): value is PluginInstance {

+ 2 - 2
packages/kirincode/src/plugin/openai/codex.ts

@@ -456,7 +456,7 @@ export async function CodexAuthPlugin(input: PluginInput, options: CodexAuthPlug
               method: "POST",
               headers: {
                 "Content-Type": "application/json",
-                "User-Agent": `opencode/${InstallationVersion}`,
+                "User-Agent": `kirincode/${InstallationVersion}`,
               },
               body: JSON.stringify({ client_id: CLIENT_ID }),
             })
@@ -480,7 +480,7 @@ export async function CodexAuthPlugin(input: PluginInput, options: CodexAuthPlug
                     method: "POST",
                     headers: {
                       "Content-Type": "application/json",
-                      "User-Agent": `opencode/${InstallationVersion}`,
+                      "User-Agent": `kirincode/${InstallationVersion}`,
                     },
                     body: JSON.stringify({
                       device_auth_id: deviceData.device_auth_id,

+ 2 - 2
packages/kirincode/src/plugin/snowflake-cortex.ts

@@ -80,7 +80,7 @@ function authHeaders() {
   return {
     "Content-Type": "application/x-www-form-urlencoded",
     Accept: "application/json",
-    "User-Agent": `opencode/${InstallationVersion}`,
+    "User-Agent": `kirincode/${InstallationVersion}`,
   }
 }
 
@@ -380,7 +380,7 @@ export async function SnowflakeCortexAuthPlugin(_input: PluginInput): Promise<Ho
                 }
               }
               headers.set("authorization", `Bearer ${currentOauth.access}`)
-              headers.set("User-Agent", `opencode/${InstallationVersion}`)
+              headers.set("User-Agent", `kirincode/${InstallationVersion}`)
 
               let body = init?.body
               if (body && typeof body === "string") {

+ 2 - 2
packages/kirincode/src/plugin/xai.ts

@@ -88,7 +88,7 @@ function authHeaders() {
   return {
     "Content-Type": "application/x-www-form-urlencoded",
     Accept: "application/json",
-    "User-Agent": `opencode/${InstallationVersion}`,
+    "User-Agent": `kirincode/${InstallationVersion}`,
   }
 }
 
@@ -541,7 +541,7 @@ export async function XaiAuthPlugin(input: PluginInput, options: XaiAuthPluginOp
               }
             }
             headers.set("authorization", `Bearer ${currentAuth.access}`)
-            headers.set("User-Agent", `opencode/${InstallationVersion}`)
+            headers.set("User-Agent", `kirincode/${InstallationVersion}`)
 
             return fetch(requestInput, { ...init, headers })
           },

+ 3 - 3
packages/kirincode/src/provider/provider.ts

@@ -616,7 +616,7 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
       const directory = yield* InstanceState.directory
 
       const aiGatewayHeaders = {
-        "User-Agent": `opencode/${InstallationVersion} gitlab-ai-provider/${GITLAB_PROVIDER_VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`,
+        "User-Agent": `kirincode/${InstallationVersion} gitlab-ai-provider/${GITLAB_PROVIDER_VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`,
         "anthropic-beta": "context-1m-2025-08-07",
         ...providerConfig?.options?.aiGatewayHeaders,
       }
@@ -749,7 +749,7 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
         options: {
           apiKey,
           headers: {
-            "User-Agent": `opencode/${InstallationVersion} cloudflare-workers-ai (${os.platform()} ${os.release()}; ${os.arch()})`,
+            "User-Agent": `kirincode/${InstallationVersion} cloudflare-workers-ai (${os.platform()} ${os.release()}; ${os.arch()})`,
           },
         },
         async getModel(sdk: any, modelID: string) {
@@ -817,7 +817,7 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
         skipCache: input.options?.skipCache,
         collectLog: input.options?.collectLog,
         headers: {
-          "User-Agent": `opencode/${InstallationVersion} cloudflare-ai-gateway (${os.platform()} ${os.release()}; ${os.arch()})`,
+          "User-Agent": `kirincode/${InstallationVersion} cloudflare-ai-gateway (${os.platform()} ${os.release()}; ${os.arch()})`,
         },
       }
 

+ 1 - 1
packages/kirincode/src/server/mdns.ts

@@ -8,7 +8,7 @@ export function publish(port: number, domain?: string) {
   if (bonjour) unpublish()
 
   try {
-    const host = domain ?? "opencode.local"
+    const host = domain ?? "kirincode.local"
     const name = `opencode-${port}`
     bonjour = new Bonjour()
     const service = bonjour.publish({

+ 1 - 1
packages/kirincode/src/session/llm/request.ts

@@ -15,7 +15,7 @@ import { jsonSchema, tool as aiTool, type ModelMessage, type Tool } from "ai"
 import type { Plugin } from "@/plugin"
 import { mergeDeep } from "remeda"
 
-const USER_AGENT = `opencode/${InstallationVersion}`
+const USER_AGENT = `kirincode/${InstallationVersion}`
 
 type PrepareInput = {
   readonly user: SessionV1.User

+ 1 - 1
packages/kirincode/src/tool/websearch.ts

@@ -52,7 +52,7 @@ export function webSearchModelName(extra: Tool.Context["extra"]) {
 }
 
 function parallelAuthHeaders() {
-  const headers = { "User-Agent": `opencode/${InstallationVersion}` }
+  const headers = { "User-Agent": `kirincode/${InstallationVersion}` }
   if (!process.env.PARALLEL_API_KEY) return headers
   return { ...headers, Authorization: `Bearer ${process.env.PARALLEL_API_KEY}` }
 }

+ 2 - 0
packages/kirincode/tsconfig.json

@@ -9,6 +9,8 @@
     "noUncheckedIndexedAccess": false,
     "customConditions": ["browser"],
     "paths": {
+      "@opencode-ai/plugin": ["./packages/plugin/src"],
+      "@opencode-ai/sdk": ["./packages/sdk/js/src"],
       "@/*": ["./src/*"],
       "@test/*": ["./test/*"]
     }

+ 1 - 1
packages/llm/src/providers/github-copilot.ts

@@ -7,7 +7,7 @@ import { withOpenAIOptions, type OpenAIProviderOptionsInput } from "./openai-opt
 
 export const id = ProviderID.make("github-copilot")
 
-// GitHub Copilot has no canonical public URL — callers (opencode, etc.) must
+// GitHub Copilot has no canonical public URL — callers (kirincode, etc.) must
 // supply `baseURL` explicitly.
 export type ModelOptions = Omit<RouteDefaultsInput, "providerOptions"> &
   ProviderAuthOption<"optional"> & {

+ 1 - 1
packages/sdk-next/src/kirincode.ts

@@ -32,7 +32,7 @@ export const create = Effect.fn("KirinCode.create")(function* () {
   const fetch = Object.assign((input: RequestInfo | URL, init?: RequestInit) => web.handler(new Request(input, init)), {
     preconnect: () => undefined,
   }) satisfies typeof globalThis.fetch
-  const client = yield* KirinCode.make({ baseUrl: "http://opencode.local" }).pipe(
+  const client = yield* KirinCode.make({ baseUrl: "http://kirincode.local" }).pipe(
     Effect.provide(FetchHttpClient.layer),
     Effect.provideService(FetchHttpClient.Fetch, fetch),
   )

+ 6 - 6
packages/session-ui/src/pierre/file-find.ts

@@ -79,8 +79,8 @@ function installShortcuts() {
 function clearHighlightFind() {
   const api = (globalThis as { CSS?: { highlights?: { delete: (name: string) => void } } }).CSS?.highlights
   if (!api) return
-  api.delete("opencode-find")
-  api.delete("opencode-find-current")
+  api.delete("kirincode-find")
+  api.delete("kirincode-find-current")
 }
 
 function supportsHighlights() {
@@ -296,14 +296,14 @@ export function createFileFind(opts: CreateFileFindOptions) {
     const Highlight = (globalThis as unknown as { Highlight?: any }).Highlight
     if (!api || typeof Highlight !== "function") return false
 
-    api.delete("opencode-find")
-    api.delete("opencode-find-current")
+    api.delete("kirincode-find")
+    api.delete("kirincode-find-current")
 
     const active = ranges[currentIndex]
-    if (active) api.set("opencode-find-current", new Highlight(active))
+    if (active) api.set("kirincode-find-current", new Highlight(active))
 
     const rest = ranges.filter((_, i) => i !== currentIndex)
-    if (rest.length > 0) api.set("opencode-find", new Highlight(...rest))
+    if (rest.length > 0) api.set("kirincode-find", new Highlight(...rest))
     return true
   }
 

+ 2 - 2
packages/session-ui/src/pierre/index.ts

@@ -53,11 +53,11 @@ const unsafeCSS = `
   background-color: var(--diffs-bg-selection-text);
 }
 
-::highlight(opencode-find) {
+::highlight(kirincode-find) {
   background-color: rgb(from var(--surface-warning-base) r g b / 0.35);
 }
 
-::highlight(opencode-find-current) {
+::highlight(kirincode-find-current) {
   background-color: rgb(from var(--surface-warning-strong) r g b / 0.55);
 }
 

+ 4 - 4
packages/slack/src/index.ts

@@ -17,11 +17,11 @@ console.log("🚀 Starting kirincode server...")
 const kirincode = await createOpencode({
   port: 0,
 })
-console.log("✅ Opencode server ready")
+console.log("✅ KirinCode server ready")
 
 const sessions = new Map<string, { client: any; server: any; sessionId: string; channel: string; thread: string }>()
 void (async () => {
-  const events = await opencode.client.event.subscribe()
+  const events = await kirincode.client.event.subscribe()
   for await (const event of events.stream) {
     if (event.type === "message.part.updated") {
       const part = event.properties.part
@@ -73,7 +73,7 @@ app.message(async ({ message, say }) => {
 
   if (!session) {
     console.log("🆕 Creating new kirincode session...")
-    const { client, server } = opencode
+    const { client, server } = kirincode
 
     const createResult = await client.session.create({
       body: { title: `Slack thread ${thread}` },
@@ -101,7 +101,7 @@ app.message(async ({ message, say }) => {
     }
   }
 
-  console.log("📝 Sending to opencode:", message.text)
+  console.log("📝 Sending to kirincode:", message.text)
   const result = await session.client.session.prompt({
     path: { id: session.sessionId },
     body: { parts: [{ type: "text", text: message.text }] },

+ 1 - 1
packages/ui/src/components/icon.tsx

@@ -107,7 +107,7 @@ const icons = {
 }
 
 const spriteID = "kirincode-icon-sprite"
-const symbol = (name: keyof typeof icons) => `opencode-icon-${name}`
+const symbol = (name: keyof typeof icons) => `kirincode-icon-${name}`
 let spriteInserted = false
 
 function viewBox(name: keyof typeof icons) {

+ 1 - 1
packages/ui/src/theme/context.tsx

@@ -69,7 +69,7 @@ const names: Record<string, string> = {
   nord: "Nord",
   "one-dark": "One Dark",
   onedarkpro: "One Dark Pro",
-  opencode: "KirinCode",
+  kirincode: "KirinCode",
   orng: "Orng",
   "osaka-jade": "Osaka Jade",
   palenight: "Palenight",