diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index b70ff16..e980ca3 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -1,4 +1,4 @@ -# Desktop packages (design § "桌面端原型 · 打包与更新", milestone M3). +# Desktop packages: Electron installers for the desktop shell. # # Reusable three-OS matrix: stage the pnpm-deploy app tree, run electron-builder, and # upload the installers as workflow artifacts named desktop-. release.yml calls this diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1652993..47ba290 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -79,7 +79,7 @@ jobs: # Desktop installers (Electron shell, three-OS matrix). Runs BEFORE the release job: # Release assets are immutable once published, so the installers must exist when the - # Release is created. See design § "桌面端原型 · 打包与更新" (M3). + # Release is created. desktop: needs: check-release if: needs.check-release.outputs.exists != 'true' diff --git a/packages/desktop/electron-builder.yml b/packages/desktop/electron-builder.yml index 7d7068f..6269f46 100644 --- a/packages/desktop/electron-builder.yml +++ b/packages/desktop/electron-builder.yml @@ -1,4 +1,4 @@ -# electron-builder config (design § "桌面端原型 · 打包与更新", milestone M3). +# electron-builder config for the desktop shell installers. # # The app directory is the pnpm-deploy staging tree assembled by scripts/stage.mjs — # a portable, self-contained node_modules (workspace packages materialized) plus the diff --git a/packages/desktop/src/main.ts b/packages/desktop/src/main.ts index 0b73235..50121de 100644 --- a/packages/desktop/src/main.ts +++ b/packages/desktop/src/main.ts @@ -1,5 +1,5 @@ /** - * Desktop shell main process (design § "桌面端原型"). + * Desktop shell main process. * * One window over the embedded server: fork penguin-server as a utilityProcess on the * shared data root (PENGUIN_HOME or ~/.penguin/data), learn its port (last launch's when diff --git a/packages/desktop/src/util.ts b/packages/desktop/src/util.ts index f620097..2883c5a 100644 --- a/packages/desktop/src/util.ts +++ b/packages/desktop/src/util.ts @@ -13,8 +13,7 @@ export function parsePortFile(content: string): number | null { /** * The App origin for a port. Always `localhost`: on loopback the App is canonicalized - * onto localhost and `127.0.0.1` is reserved as the preview host, which rejects /api - * (see design § "桌面端原型 · 进程模型"). + * onto localhost and `127.0.0.1` is reserved as the preview host, which rejects /api. */ export function appOriginFor(port: number): string { return `http://localhost:${port}`; @@ -41,9 +40,9 @@ export function isAppUrl(url: string, origin: string | null): boolean { /** * Whether a URL belongs to this instance's local surface: the app origin itself or its - * loopback counterpart on the same port, which is where Workspace previews are served - * (see design § "Workspace 文件预览"). Preview windows navigate freely within it; anything - * else is external and belongs in the system browser. + * loopback counterpart on the same port, which is where Workspace previews are served. + * Preview windows navigate freely within it; anything else is external and belongs in + * the system browser. */ export function isLocalSurfaceUrl(url: string, origin: string | null): boolean { if (origin === null) return false; diff --git a/packages/server/src/auth/service.ts b/packages/server/src/auth/service.ts index 057b576..1efbb3a 100644 --- a/packages/server/src/auth/service.ts +++ b/packages/server/src/auth/service.ts @@ -59,9 +59,9 @@ function sha256Hex(value: string): string { /** * How a session was established: "password" via the login form, "desktop" via the - * desktop shell's one-shot token (see design § "桌面端原型 · 桌面登录"). Persisted per - * session so desktop-specific allowances (password change without the old password) - * apply only to sessions the shell itself opened. Legacy rows (NULL) read as "password". + * desktop shell's one-shot token. Persisted per session so desktop-specific allowances + * (password change without the old password) apply only to sessions the shell itself + * opened. Legacy rows (NULL) read as "password". */ export type SessionVia = "password" | "desktop"; diff --git a/packages/server/src/config.ts b/packages/server/src/config.ts index 575f884..47eb66a 100644 --- a/packages/server/src/config.ts +++ b/packages/server/src/config.ts @@ -36,7 +36,7 @@ export interface ServerConfig { * `https://preview.example.com`. It must differ from the App origin by **hostname** — * cookies ignore ports, so a second port would still share the session cookie. Unset * is the norm locally: the loopback counterpart (`127.0.0.1` <-> `localhost`) is - * derived per request instead. See design § "Workspace 文件预览". + * derived per request instead. */ previewOrigin: string | null; /** @@ -45,7 +45,7 @@ export interface ServerConfig { * `penguin-<4 digits>` password, printed once to the server console. In desktop mode * an unpinned value resolves to a FULLY random password instead (never printed): * sign-in there goes through the shell's one-shot token, so nobody needs to read the - * seed. See design § "桌面端原型 · 桌面登录". + * seed. */ seedAdminPassword: string | null; /** Login session validity period (7 days). */ @@ -56,7 +56,7 @@ export interface ServerConfig { * Desktop mode (PENGUIN_DESKTOP_TOKEN): the per-launch token minted by the desktop * shell. Non-null enables the one-shot desktop-login and Bearer-token shutdown * endpoints and requires a loopback HOST — desktop mode passes the token through a - * URL, which must never leave the machine. See design § "桌面端原型". + * URL, which must never leave the machine. */ desktopToken: string | null; /** diff --git a/packages/server/src/http/routes/auth.ts b/packages/server/src/http/routes/auth.ts index 6290672..9047d4d 100644 --- a/packages/server/src/http/routes/auth.ts +++ b/packages/server/src/http/routes/auth.ts @@ -47,7 +47,7 @@ export function authRoutes(deps: AppDeps): Hono { // token for a standard admin cookie session and lands on the app — the desktop user // never sees the login page. 404 outside desktop mode (the route "doesn't exist"); // a wrong or already-used token is a plain 401 with no distinction, so a leaked URL - // reveals nothing and cannot be replayed. See design § "桌面端原型 · 桌面登录". + // reveals nothing and cannot be replayed. app.get("/desktop-login", (c) => { const desktop = deps.desktop; if (!desktop) throw new HttpError(404, "not_found", "Desktop mode is not enabled."); diff --git a/packages/server/src/http/routes/me.ts b/packages/server/src/http/routes/me.ts index 70e0331..f4c9e39 100644 --- a/packages/server/src/http/routes/me.ts +++ b/packages/server/src/http/routes/me.ts @@ -36,7 +36,7 @@ export function meRoutes(deps: AppDeps): Hono { // Self-service password change (user settings): validates the old password; on success, the initial-password prompt disappears from GET /api/me. // Desktop sessions may omit oldPassword: the seed password of a desktop-created root is // random and never shown, so its holder has nothing to type — the shell's redeemed - // token already proved machine ownership (see design § "桌面端原型 · 桌面登录"). + // token already proved machine ownership. app.put("/password", async (c) => { const body = await readJson(c); const newPassword = requireString(body, "newPassword", { label: "newPassword" }); diff --git a/packages/server/src/http/routes/preview.ts b/packages/server/src/http/routes/preview.ts index f730bf5..b6c5858 100644 --- a/packages/server/src/http/routes/preview.ts +++ b/packages/server/src/http/routes/preview.ts @@ -12,8 +12,6 @@ * lets third-party embeds run. That only stays safe while the host check below holds — * this same process also answers on the App origin, and serving Agent-written HTML there * would be a same-origin XSS with full API access. - * - * Design: design/specs/05-ARCHITECTURE.md § "Workspace 文件预览". */ import { Hono } from "hono"; import type { SessionsRepo } from "../../db/repos/sessions.js"; diff --git a/packages/server/src/http/routes/sessions.ts b/packages/server/src/http/routes/sessions.ts index 8a9c522..f6c068a 100644 --- a/packages/server/src/http/routes/sessions.ts +++ b/packages/server/src/http/routes/sessions.ts @@ -837,7 +837,7 @@ export function sessionsRoutes(deps: AppDeps): Hono { }); // "Open in a new tab" for Workspace HTML: mints a token and redirects to the separate - // preview origin (see design § "Workspace 文件预览"). + // preview origin. // // A redirect rather than a JSON endpoint the UI fetches, because the alternative is // worse on two counts: opening the tab after an await trips popup blockers, and a diff --git a/packages/server/src/lock.ts b/packages/server/src/lock.ts index 80aae7f..71658d2 100644 --- a/packages/server/src/lock.ts +++ b/packages/server/src/lock.ts @@ -11,7 +11,7 @@ * * Published as `@prismshadow/penguin-server/lock` (side-effect-free) so the CLI and the * desktop shell can pre-check a root without importing the package entry, which starts - * listening. Docs: design § "桌面端原型 · 数据根与实例互斥". + * listening. */ import fs from "node:fs"; import net from "node:net"; diff --git a/packages/server/src/services/desktop-service.ts b/packages/server/src/services/desktop-service.ts index f978c9d..4ec5ebc 100644 --- a/packages/server/src/services/desktop-service.ts +++ b/packages/server/src/services/desktop-service.ts @@ -12,7 +12,6 @@ * where killing a child is a hard TerminateProcess). * * Comparisons hash both sides first so timingSafeEqual gets equal-length buffers. - * Docs: design § "桌面端原型 · 桌面登录". */ import { createHash, timingSafeEqual } from "node:crypto"; diff --git a/packages/server/src/services/preview-token.ts b/packages/server/src/services/preview-token.ts index 59597a0..29d5771 100644 --- a/packages/server/src/services/preview-token.ts +++ b/packages/server/src/services/preview-token.ts @@ -1,8 +1,7 @@ /** * Signed tokens for Workspace HTML preview on a separate origin. * - * The preview origin deliberately differs from the App origin (see - * design/specs/05-ARCHITECTURE.md § "Workspace 文件预览"), so it never receives the + * The preview origin deliberately differs from the App origin, so it never receives the * session cookie — cookies are keyed by host and ignore port, which is why the two * must differ by hostname and not merely by port. Authorization therefore travels in * the URL as a short-lived HMAC token instead. diff --git a/packages/server/test/workspace-preview.test.ts b/packages/server/test/workspace-preview.test.ts index 3739f5a..c95f1e3 100644 --- a/packages/server/test/workspace-preview.test.ts +++ b/packages/server/test/workspace-preview.test.ts @@ -4,7 +4,7 @@ * * The load-bearing case is "same token, App origin's Host": the preview route answers on * the same process as the App, so if it served Agent-written HTML there, it would be a - * same-origin XSS with the session cookie attached. See design § "Workspace 文件预览". + * same-origin XSS with the session cookie attached. */ import fs from "node:fs/promises"; import path from "node:path"; diff --git a/packages/web/src/state/use-completion-notifications.ts b/packages/web/src/state/use-completion-notifications.ts index 04e073f..a6b20ab 100644 --- a/packages/web/src/state/use-completion-notifications.ts +++ b/packages/web/src/state/use-completion-notifications.ts @@ -1,6 +1,6 @@ /** * Desktop task-completion notifications, renderer-side only (standard Web Notification - * API — no preload, no private IPC, per design § "桌面端原型 · 进程模型"). + * API — no preload, no private IPC: the desktop window stays a plain browser environment). * * Watches the tracked Session list for active→idle transitions (lib/completion-notify) * and, when the window is hidden or unfocused, shows a system notification with the