diff --git a/agents.md b/agents.md index 985154a..2393475 100644 --- a/agents.md +++ b/agents.md @@ -59,7 +59,28 @@ - `docs/plans/2026-02-15-clawpal-mvp-design.md`(设计) - `docs/plans/2026-02-15-clawpal-mvp-implementation-plan.md`(计划) -## 7. 安全与风险 +## 7. 部署 + +### 官网(clawpal.zhixian.io) + +使用 Cloudflare Pages Direct Upload 部署,源目录为 `docs/site/`。 + +部署命令: +```bash +npx wrangler pages deploy docs/site --project-name clawpal +``` + +项目域名:`clawpal.zhixian.io`(也可通过 `clawpal.pages.dev` 访问)。 + +### 桌面应用 Release + +通过 GitHub Actions 自动构建,push tag 触发(如 `v0.1.1`): +- CI workflow: `.github/workflows/release.yml` +- 构建产物:macOS (ARM/x64 .dmg)、Windows (.exe/.msi)、Linux (.deb/.AppImage) +- 需要 `TAURI_SIGNING_PRIVATE_KEY` 等 secrets,本地无法打 release bundle +- 发布新版本流程:更新 `package.json` + `src-tauri/Cargo.toml` 版本号 → commit → `git tag vX.Y.Z` → push + +## 8. 安全与风险 - 禁止提交明文密钥/配置路径泄露 - 避免大文件和自动生成产物直接提交 diff --git a/docs/site/index.html b/docs/site/index.html index a060d8d..5ae3724 100644 --- a/docs/site/index.html +++ b/docs/site/index.html @@ -423,6 +423,12 @@ + + + + + + @@ -449,14 +455,16 @@

Manage AI agents, models, and configs with a visual interface.
Stop editing JSON by hand.

+ Download - - View on GitHub + + GitHub - - Join Discord + + + Discord
diff --git a/src/App.tsx b/src/App.tsx index d9b87fe..dc3cd46 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,6 @@ import { useCallback, useEffect, useRef, useState } from "react"; +import { check } from "@tauri-apps/plugin-updater"; +import { relaunch } from "@tauri-apps/plugin-process"; import { Home } from "./pages/Home"; import { Recipes } from "./pages/Recipes"; import { Cook } from "./pages/Cook"; @@ -80,6 +82,30 @@ export function App() { setToasts((prev) => prev.filter((t) => t.id !== id)); }, []); + // App self-update (manual check from sidebar) + const [checkingAppUpdate, setCheckingAppUpdate] = useState(false); + + const handleCheckForUpdates = useCallback(async () => { + setCheckingAppUpdate(true); + try { + const update = await check(); + if (update) { + const confirmed = window.confirm(`ClawPal v${update.version} is available. Update and restart now?`); + if (confirmed) { + await update.downloadAndInstall(); + await relaunch(); + } + } else { + showToast("You're on the latest version"); + } + } catch (e) { + console.error("Update check failed:", e); + showToast(`Update check failed: ${e}`, "error"); + } finally { + setCheckingAppUpdate(false); + } + }, [showToast]); + const handleInstanceSelect = useCallback((id: string) => { setActiveInstance(id); if (id !== "local") { @@ -285,6 +311,14 @@ export function App() { > Settings + {/* Dirty config action bar */} diff --git a/src/components/UpgradeDialog.tsx b/src/components/UpgradeDialog.tsx index 91915f9..770eafb 100644 --- a/src/components/UpgradeDialog.tsx +++ b/src/components/UpgradeDialog.tsx @@ -11,6 +11,11 @@ import { type Step = "confirm" | "backup" | "upgrading" | "done"; +/** Strip ANSI escape codes from terminal output */ +function stripAnsi(str: string): string { + return str.replace(/\x1b\[[0-9;]*m/g, "").replace(/\x1b\[[0-9;]*[A-Za-z]/g, ""); +} + export function UpgradeDialog({ open, onOpenChange, @@ -31,6 +36,7 @@ export function UpgradeDialog({ const [output, setOutput] = useState(""); const [error, setError] = useState(""); const [loading, setLoading] = useState(false); + const [showLog, setShowLog] = useState(false); const reset = () => { setStep("confirm"); @@ -38,6 +44,7 @@ export function UpgradeDialog({ setOutput(""); setError(""); setLoading(false); + setShowLog(false); }; const handleClose = (open: boolean) => { @@ -77,11 +84,12 @@ export function UpgradeDialog({ const result = isRemote ? await api.remoteRunOpenclawUpgrade(instanceId) : await api.runOpenclawUpgrade(); - setOutput(result); + setOutput(stripAnsi(result)); setStep("done"); } catch (e) { - setOutput(String(e)); + setOutput(stripAnsi(String(e))); setError("Upgrade failed. See output below."); + setShowLog(true); } finally { setLoading(false); } @@ -163,9 +171,19 @@ export function UpgradeDialog({ Upgrade completed successfully.

{output && ( -
-                {output}
-              
+ <> + + {showLog && ( +
+                    {output}
+                  
+ )} + )}
)} diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 5972999..24bae84 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -201,9 +201,8 @@ export function Home({ return () => clearTimeout(timer); }, [isRemote, isConnected, instanceId]); - // ClawPal app self-update check (local only) + // ClawPal app self-update check useEffect(() => { - if (isRemote) return; setAppUpdateChecking(true); check() .then((update) => { @@ -213,10 +212,9 @@ export function Home({ }) .catch((e) => console.error("Failed to check app update:", e)) .finally(() => setAppUpdateChecking(false)); - }, [isRemote]); + }, []); const handleAppUpdate = useCallback(async () => { - if (isRemote) return; setAppUpdating(true); setAppUpdateProgress(0); try { @@ -242,7 +240,7 @@ export function Home({ setAppUpdating(false); setAppUpdateProgress(null); } - }, [isRemote]); + }, []); const handleDeleteAgent = (agentId: string) => { if (isRemote && !isConnected) return; @@ -303,8 +301,8 @@ export function Home({ )} - {/* ClawPal app self-update (local only) */} - {!isRemote && (appUpdateChecking || appUpdate) && ( + {/* ClawPal app self-update */} + {(appUpdateChecking || appUpdate) && ( <> App Update