chore: drop design-doc citations from code comments (English-only sweep) (#236)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -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-<OS>. release.yml calls this
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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;
|
||||
/**
|
||||
|
||||
@@ -47,7 +47,7 @@ export function authRoutes(deps: AppDeps): Hono<AppEnv> {
|
||||
// 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.");
|
||||
|
||||
@@ -36,7 +36,7 @@ export function meRoutes(deps: AppDeps): Hono<AppEnv> {
|
||||
// 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" });
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -837,7 +837,7 @@ export function sessionsRoutes(deps: AppDeps): Hono<AppEnv> {
|
||||
});
|
||||
|
||||
// "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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user