mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-29 21:33:54 +00:00
feat: tfcode
This commit is contained in:
parent
95340af79a
commit
cbcaa4ba46
2
bun.lock
2
bun.lock
@ -381,7 +381,7 @@
|
||||
},
|
||||
"packages/tfcode": {
|
||||
"name": "tfcode",
|
||||
"version": "1.0.14",
|
||||
"version": "1.0.16",
|
||||
"bin": {
|
||||
"tfcode": "./bin/tfcode",
|
||||
},
|
||||
|
||||
@ -542,7 +542,7 @@ export const dict = {
|
||||
"sidebar.project.recentSessions": "الجلسات الحديثة",
|
||||
"sidebar.project.viewAllSessions": "عرض جميع الجلسات",
|
||||
"sidebar.project.clearNotifications": "مسح الإشعارات",
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
"settings.section.desktop": "سطح المكتب",
|
||||
"settings.section.server": "الخادم",
|
||||
"settings.tab.general": "عام",
|
||||
|
||||
@ -549,7 +549,7 @@ export const dict = {
|
||||
"sidebar.project.recentSessions": "Sessões recentes",
|
||||
"sidebar.project.viewAllSessions": "Ver todas as sessões",
|
||||
"sidebar.project.clearNotifications": "Limpar notificações",
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
"settings.section.desktop": "Desktop",
|
||||
"settings.section.server": "Servidor",
|
||||
"settings.tab.general": "Geral",
|
||||
|
||||
@ -611,7 +611,7 @@ export const dict = {
|
||||
"sidebar.project.viewAllSessions": "Prikaži sve sesije",
|
||||
"sidebar.project.clearNotifications": "Očisti obavijesti",
|
||||
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
|
||||
"settings.section.desktop": "Desktop",
|
||||
"settings.section.server": "Server",
|
||||
|
||||
@ -607,7 +607,7 @@ export const dict = {
|
||||
"sidebar.project.viewAllSessions": "Vis alle sessioner",
|
||||
"sidebar.project.clearNotifications": "Ryd notifikationer",
|
||||
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
"settings.section.desktop": "Desktop",
|
||||
"settings.section.server": "Server",
|
||||
"settings.tab.general": "Generelt",
|
||||
|
||||
@ -558,7 +558,7 @@ export const dict = {
|
||||
"sidebar.project.recentSessions": "Letzte Sitzungen",
|
||||
"sidebar.project.viewAllSessions": "Alle Sitzungen anzeigen",
|
||||
"sidebar.project.clearNotifications": "Benachrichtigungen löschen",
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
"settings.section.desktop": "Desktop",
|
||||
"settings.section.server": "Server",
|
||||
"settings.tab.general": "Allgemein",
|
||||
|
||||
@ -119,7 +119,7 @@ export const dict = {
|
||||
"dialog.model.manage.description": "Customize which models appear in the model selector.",
|
||||
"dialog.model.manage.provider.toggle": "Toggle all {{provider}} models",
|
||||
|
||||
"dialog.model.unpaid.freeModels.title": "Free models provided by OpenCode",
|
||||
"dialog.model.unpaid.freeModels.title": "Free models provided by TF Code",
|
||||
"dialog.model.unpaid.addMore.title": "Add more models from popular providers",
|
||||
|
||||
"dialog.provider.viewAll": "Show more providers",
|
||||
@ -571,7 +571,7 @@ export const dict = {
|
||||
"session.revertDock.expand": "Expand rolled back messages",
|
||||
"session.revertDock.restore": "Restore message",
|
||||
|
||||
"session.new.title": "Build anything",
|
||||
"session.new.title": "Build with TF Code",
|
||||
"session.new.worktree.main": "Main branch",
|
||||
"session.new.worktree.mainWithBranch": "Main branch ({{branch}})",
|
||||
"session.new.worktree.create": "Create new worktree",
|
||||
@ -710,7 +710,7 @@ export const dict = {
|
||||
"debugBar.mem.tipUnavailable": "Used JS heap vs heap limit. Chromium only.",
|
||||
"debugBar.mem.tip": "Used JS heap vs heap limit. {{used}} of {{limit}}.",
|
||||
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
|
||||
"settings.section.desktop": "Desktop",
|
||||
"settings.section.server": "Server",
|
||||
|
||||
@ -614,7 +614,7 @@ export const dict = {
|
||||
"sidebar.project.viewAllSessions": "Ver todas las sesiones",
|
||||
"sidebar.project.clearNotifications": "Borrar notificaciones",
|
||||
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
|
||||
"settings.section.desktop": "Escritorio",
|
||||
"settings.section.server": "Servidor",
|
||||
|
||||
@ -556,7 +556,7 @@ export const dict = {
|
||||
"sidebar.project.recentSessions": "Sessions récentes",
|
||||
"sidebar.project.viewAllSessions": "Voir toutes les sessions",
|
||||
"sidebar.project.clearNotifications": "Effacer les notifications",
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
"settings.section.desktop": "Bureau",
|
||||
"settings.section.server": "Serveur",
|
||||
"settings.tab.general": "Général",
|
||||
|
||||
@ -546,7 +546,7 @@ export const dict = {
|
||||
"sidebar.project.recentSessions": "最近のセッション",
|
||||
"sidebar.project.viewAllSessions": "すべてのセッションを表示",
|
||||
"sidebar.project.clearNotifications": "通知をクリア",
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
"settings.section.desktop": "デスクトップ",
|
||||
"settings.section.server": "サーバー",
|
||||
"settings.tab.general": "一般",
|
||||
|
||||
@ -547,7 +547,7 @@ export const dict = {
|
||||
"sidebar.project.recentSessions": "최근 세션",
|
||||
"sidebar.project.viewAllSessions": "모든 세션 보기",
|
||||
"sidebar.project.clearNotifications": "알림 지우기",
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
"settings.section.desktop": "데스크톱",
|
||||
"settings.section.server": "서버",
|
||||
"settings.tab.general": "일반",
|
||||
|
||||
@ -614,7 +614,7 @@ export const dict = {
|
||||
"sidebar.project.viewAllSessions": "Vis alle sesjoner",
|
||||
"sidebar.project.clearNotifications": "Fjern varsler",
|
||||
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
|
||||
"settings.section.desktop": "Skrivebord",
|
||||
"settings.section.server": "Server",
|
||||
|
||||
@ -547,7 +547,7 @@ export const dict = {
|
||||
"sidebar.project.recentSessions": "Ostatnie sesje",
|
||||
"sidebar.project.viewAllSessions": "Zobacz wszystkie sesje",
|
||||
"sidebar.project.clearNotifications": "Wyczyść powiadomienia",
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
"settings.section.desktop": "Pulpit",
|
||||
"settings.section.server": "Serwer",
|
||||
"settings.tab.general": "Ogólne",
|
||||
|
||||
@ -612,7 +612,7 @@ export const dict = {
|
||||
"sidebar.project.viewAllSessions": "Посмотреть все сессии",
|
||||
"sidebar.project.clearNotifications": "Очистить уведомления",
|
||||
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
"settings.section.desktop": "Приложение",
|
||||
"settings.section.server": "Сервер",
|
||||
"settings.tab.general": "Основные",
|
||||
|
||||
@ -605,7 +605,7 @@ export const dict = {
|
||||
"sidebar.project.viewAllSessions": "ดูเซสชันทั้งหมด",
|
||||
"sidebar.project.clearNotifications": "ล้างการแจ้งเตือน",
|
||||
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
|
||||
"settings.section.desktop": "เดสก์ท็อป",
|
||||
"settings.section.server": "เซิร์ฟเวอร์",
|
||||
|
||||
@ -604,7 +604,7 @@ export const dict = {
|
||||
"sidebar.project.viewAllSessions": "查看全部会话",
|
||||
"sidebar.project.clearNotifications": "清除通知",
|
||||
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
|
||||
"settings.section.desktop": "桌面",
|
||||
"settings.section.server": "服务器",
|
||||
|
||||
@ -601,7 +601,7 @@ export const dict = {
|
||||
"sidebar.project.viewAllSessions": "查看全部工作階段",
|
||||
"sidebar.project.clearNotifications": "清除通知",
|
||||
|
||||
"app.name.desktop": "OpenCode Desktop",
|
||||
"app.name.desktop": "TF Code Desktop",
|
||||
"settings.section.desktop": "桌面",
|
||||
"settings.section.server": "伺服器",
|
||||
"settings.tab.general": "一般",
|
||||
|
||||
@ -9,16 +9,16 @@ import { app, BrowserWindow, dialog } from "electron"
|
||||
import pkg from "electron-updater"
|
||||
|
||||
const APP_NAMES: Record<string, string> = {
|
||||
dev: "OpenCode Dev",
|
||||
beta: "OpenCode Beta",
|
||||
prod: "OpenCode",
|
||||
dev: "TF Code Dev",
|
||||
beta: "TF Code Beta",
|
||||
prod: "TF Code",
|
||||
}
|
||||
const APP_IDS: Record<string, string> = {
|
||||
dev: "ai.opencode.desktop.dev",
|
||||
beta: "ai.opencode.desktop.beta",
|
||||
prod: "ai.opencode.desktop",
|
||||
}
|
||||
app.setName(app.isPackaged ? APP_NAMES[CHANNEL] : "OpenCode Dev")
|
||||
app.setName(app.isPackaged ? APP_NAMES[CHANNEL] : "TF Code Dev")
|
||||
app.setPath("userData", join(app.getPath("appData"), app.isPackaged ? APP_IDS[CHANNEL] : "ai.opencode.desktop.dev"))
|
||||
const { autoUpdater } = pkg
|
||||
|
||||
|
||||
@ -5,6 +5,9 @@ import { withNetworkOptions, resolveNetworkOptions } from "../network"
|
||||
import { Flag } from "../../flag/flag"
|
||||
import open from "open"
|
||||
import { networkInterfaces } from "os"
|
||||
import { existsSync } from "fs"
|
||||
import path from "path"
|
||||
import { $ } from "bun"
|
||||
|
||||
function getNetworkIPs() {
|
||||
const nets = networkInterfaces()
|
||||
@ -15,12 +18,8 @@ function getNetworkIPs() {
|
||||
if (!net) continue
|
||||
|
||||
for (const netInfo of net) {
|
||||
// Skip internal and non-IPv4 addresses
|
||||
if (netInfo.internal || netInfo.family !== "IPv4") continue
|
||||
|
||||
// Skip Docker bridge networks (typically 172.x.x.x)
|
||||
if (netInfo.address.startsWith("172.")) continue
|
||||
|
||||
results.push(netInfo.address)
|
||||
}
|
||||
}
|
||||
@ -28,6 +27,18 @@ function getNetworkIPs() {
|
||||
return results
|
||||
}
|
||||
|
||||
async function ensureAppBuilt() {
|
||||
const appDir = path.join(import.meta.dirname, "..", "..", "..", "..", "app")
|
||||
const distDir = path.join(appDir, "dist")
|
||||
|
||||
if (!existsSync(distDir) || !existsSync(path.join(distDir, "index.html"))) {
|
||||
UI.println(UI.Style.TEXT_INFO_BOLD + " Building web app...", UI.Style.TEXT_NORMAL)
|
||||
const result = $`cd ${appDir} && bun run build`.quiet()
|
||||
await result
|
||||
UI.println(UI.Style.TEXT_SUCCESS_BOLD + " Build complete!", UI.Style.TEXT_NORMAL)
|
||||
}
|
||||
}
|
||||
|
||||
export const WebCommand = cmd({
|
||||
command: "web",
|
||||
builder: (yargs) => withNetworkOptions(yargs),
|
||||
@ -36,6 +47,9 @@ export const WebCommand = cmd({
|
||||
if (!Flag.OPENCODE_SERVER_PASSWORD) {
|
||||
UI.println(UI.Style.TEXT_WARNING_BOLD + "! " + "OPENCODE_SERVER_PASSWORD is not set; server is unsecured.")
|
||||
}
|
||||
|
||||
await ensureAppBuilt()
|
||||
|
||||
const opts = await resolveNetworkOptions(args)
|
||||
const server = Server.listen(opts)
|
||||
UI.empty()
|
||||
@ -43,11 +57,9 @@ export const WebCommand = cmd({
|
||||
UI.empty()
|
||||
|
||||
if (opts.hostname === "0.0.0.0") {
|
||||
// Show localhost for local access
|
||||
const localhostUrl = `http://localhost:${server.port}`
|
||||
UI.println(UI.Style.TEXT_INFO_BOLD + " Local access: ", UI.Style.TEXT_NORMAL, localhostUrl)
|
||||
|
||||
// Show network IPs for remote access
|
||||
const networkIPs = getNetworkIPs()
|
||||
if (networkIPs.length > 0) {
|
||||
for (const ip of networkIPs) {
|
||||
@ -67,7 +79,6 @@ export const WebCommand = cmd({
|
||||
)
|
||||
}
|
||||
|
||||
// Open localhost in browser
|
||||
open(localhostUrl.toString()).catch(() => {})
|
||||
} else {
|
||||
const displayUrl = server.url.toString()
|
||||
|
||||
@ -2,9 +2,9 @@ import { Log } from "../util/log"
|
||||
import { describeRoute, generateSpecs, validator, resolver, openAPIRouteHandler } from "hono-openapi"
|
||||
import { Hono } from "hono"
|
||||
import { cors } from "hono/cors"
|
||||
import { proxy } from "hono/proxy"
|
||||
import { basicAuth } from "hono/basic-auth"
|
||||
import z from "zod"
|
||||
import path from "path"
|
||||
import { Provider } from "../provider/provider"
|
||||
import { NamedError } from "@opencode-ai/util/error"
|
||||
import { LSP } from "../lsp"
|
||||
@ -222,9 +222,9 @@ export namespace Server {
|
||||
openAPIRouteHandler(app, {
|
||||
documentation: {
|
||||
info: {
|
||||
title: "opencode",
|
||||
title: "tfcode",
|
||||
version: "0.0.3",
|
||||
description: "opencode api",
|
||||
description: "tfcode api",
|
||||
},
|
||||
openapi: "3.1.1",
|
||||
},
|
||||
@ -529,20 +529,33 @@ export namespace Server {
|
||||
},
|
||||
)
|
||||
.all("/*", async (c) => {
|
||||
const path = c.req.path
|
||||
const reqPath = c.req.path === "/" ? "/index.html" : c.req.path
|
||||
const appDist = path.join(import.meta.dirname, "..", "..", "..", "app", "dist")
|
||||
const publicDir = path.join(import.meta.dirname, "..", "..", "..", "app", "public")
|
||||
|
||||
const response = await proxy(`https://app.opencode.ai${path}`, {
|
||||
...c.req,
|
||||
headers: {
|
||||
...c.req.raw.headers,
|
||||
host: "app.opencode.ai",
|
||||
},
|
||||
})
|
||||
response.headers.set(
|
||||
"Content-Security-Policy",
|
||||
"default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; media-src 'self' data:; connect-src 'self' data:",
|
||||
)
|
||||
let filePath = path.join(appDist, reqPath)
|
||||
let file = Bun.file(filePath)
|
||||
|
||||
if (!(await file.exists())) {
|
||||
filePath = path.join(publicDir, reqPath)
|
||||
file = Bun.file(filePath)
|
||||
}
|
||||
|
||||
if (!(await file.exists())) {
|
||||
filePath = path.join(appDist, "index.html")
|
||||
file = Bun.file(filePath)
|
||||
}
|
||||
|
||||
if (await file.exists()) {
|
||||
const response = new Response(file)
|
||||
const contentType = file.type
|
||||
if (contentType) {
|
||||
response.headers.set("Content-Type", contentType)
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
return c.text("Not Found. Run 'bun run build' in packages/app first.", 404)
|
||||
})
|
||||
}
|
||||
|
||||
@ -551,9 +564,9 @@ export namespace Server {
|
||||
const result = await generateSpecs(Default(), {
|
||||
documentation: {
|
||||
info: {
|
||||
title: "opencode",
|
||||
title: "tfcode",
|
||||
version: "1.0.0",
|
||||
description: "opencode api",
|
||||
description: "tfcode api",
|
||||
},
|
||||
openapi: "3.1.1",
|
||||
},
|
||||
|
||||
@ -35,7 +35,7 @@ export const Logo = (props: { class?: string }) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 234 42"
|
||||
viewBox="0 0 180 42"
|
||||
fill="none"
|
||||
classList={{ [props.class ?? ""]: !!props.class }}
|
||||
>
|
||||
@ -44,18 +44,16 @@ export const Logo = (props: { class?: string }) => {
|
||||
<path d="M18 12H6V30H18V12ZM24 36H0V6H24V36Z" fill="var(--icon-base)" />
|
||||
<path d="M48 30H36V18H48V30Z" fill="var(--icon-weak-base)" />
|
||||
<path d="M36 30H48V12H36V30ZM54 36H36V42H30V6H54V36Z" fill="var(--icon-base)" />
|
||||
<path d="M84 24V30H66V24H84Z" fill="var(--icon-weak-base)" />
|
||||
<path d="M84 24H66V30H84V36H60V6H84V24ZM66 18H78V12H66V18Z" fill="var(--icon-base)" />
|
||||
<path d="M108 36H96V18H108V36Z" fill="var(--icon-weak-base)" />
|
||||
<path d="M108 12H96V36H90V6H108V12ZM114 36H108V12H114V36Z" fill="var(--icon-base)" />
|
||||
<path d="M144 30H126V18H144V30Z" fill="var(--icon-weak-base)" />
|
||||
<path d="M144 12H126V30H144V36H120V6H144V12Z" fill="var(--icon-strong-base)" />
|
||||
<path d="M168 30H156V18H168V30Z" fill="var(--icon-weak-base)" />
|
||||
<path d="M168 12H156V30H168V12ZM174 36H150V6H174V36Z" fill="var(--icon-strong-base)" />
|
||||
<path d="M198 30H186V18H198V30Z" fill="var(--icon-weak-base)" />
|
||||
<path d="M198 12H186V30H198V12ZM204 36H180V6H198V0H204V36Z" fill="var(--icon-strong-base)" />
|
||||
<path d="M234 24V30H216V24H234Z" fill="var(--icon-weak-base)" />
|
||||
<path d="M216 12V18H228V12H216ZM234 24H216V30H234V36H210V6H234V24Z" fill="var(--icon-strong-base)" />
|
||||
<text
|
||||
x="66"
|
||||
y="32"
|
||||
font-size="28"
|
||||
font-weight="600"
|
||||
fill="var(--icon-strong-base)"
|
||||
font-family="var(--font-family-sans)"
|
||||
>
|
||||
Code
|
||||
</text>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/desktop-theme.json",
|
||||
"name": "OpenCode",
|
||||
"name": "TF Code",
|
||||
"id": "opencode",
|
||||
"light": {
|
||||
"palette": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user