mirror of
https://github.com/NanmiCoder/claude-code-haha.git
synced 2026-10-10 03:43:11 +08:00
6bab6fbe97
Documents the agent writes open in the workspace panel instead of another application, and local images the agent mentions show up in the conversation. Workspace preview - PDF (pdf.js with its own layout and text layer), Word (docx-preview inside a scripts-disabled sandboxed iframe) and Excel (SheetJS; .xlsx, .xlsm, .xls) open in the side panel with zoom and fit, per-file scroll/zoom/sheet memory, and a refresh when the agent rewrites the file. The engines load lazily. - Bytes come from a new GET /api/sessions/:id/workspace/raw route, with an extension allowlist, size caps, the workspace boundary and canonical-path checks. The file endpoint returns metadata and a version for documents. The client fetches with the bearer credential, so it works in Electron, LAN H5 and remote access alike. - Chat links, output cards and the change card open pdf/docx/xlsx in the workspace; documents outside the workdir still go to the system application. - Image viewer with fit, zoom and pan, and "open in system app". Chat images - Markdown images outside the workdir, at ~/, C:\ and file:// paths render, open in the viewer, and offer "open original" (pictures only). - Images returned by tools such as Read appear as thumbnails under the call. Hardening found in review - previewFsUrl escapes each path segment; a double-escaped %2e%2e used to leave /preview-fs/<session>/. - The CORS, API timing and remote-access header decorators set headers in place. Rebuilding the response buffered whole files in memory and dropped Content-Length. - The engine owns the pdf.js worker, so closing one document no longer fails the next open. - Office archives are inflated in steps to check their real sizes, not the sizes they declare. - A viewer that fails to load stays in its panel instead of taking the window down. Adds pdfjs-dist, docx-preview, xlsx (SheetJS 0.20.3 tarball) and fflate as renderer dev dependencies; Vite bundles them. Refs #1397
43 lines
1.7 KiB
TypeScript
43 lines
1.7 KiB
TypeScript
import { readFileSync } from 'node:fs'
|
|
import { dirname, join } from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
const desktopRoot = dirname(fileURLToPath(import.meta.url))
|
|
|
|
describe('desktop build compatibility', () => {
|
|
it('keeps production bundles loadable in the macOS 12 Safari 15 WebView', () => {
|
|
const config = readFileSync(join(desktopRoot, 'vite.config.ts'), 'utf8')
|
|
|
|
expect(config).toContain("target: ['es2021', 'safari15']")
|
|
})
|
|
|
|
it('ships the data pdf.js reads at run time, without which a Chinese PDF is drawn as blanks', async () => {
|
|
// Not a text search: what matters is that the plugin is in the config that is actually used.
|
|
const { default: config } = await import('./vite.config')
|
|
|
|
const names = (config.plugins ?? []).flat(Infinity).map((plugin) => (plugin as { name?: string } | null)?.name)
|
|
|
|
expect(names).toContain('cc-haha:pdfjs-assets')
|
|
})
|
|
|
|
it('does not rely on CSS color-mix for startup-critical shell chrome', () => {
|
|
const css = readFileSync(join(desktopRoot, 'src', 'theme', 'globals.css'), 'utf8')
|
|
|
|
expect(css).not.toContain('color-mix(')
|
|
expect(css).toContain('--color-text-secondary-a72')
|
|
expect(css).toContain('--color-outline-a92')
|
|
})
|
|
|
|
it('loads xterm base styles before app globals in the desktop entry', () => {
|
|
const main = readFileSync(join(desktopRoot, 'src', 'main.tsx'), 'utf8')
|
|
|
|
const xtermImport = main.indexOf("import '@xterm/xterm/css/xterm.css'")
|
|
const globalsImport = main.indexOf("import './theme/globals.css'")
|
|
|
|
expect(xtermImport).toBeGreaterThanOrEqual(0)
|
|
expect(globalsImport).toBeGreaterThanOrEqual(0)
|
|
expect(xtermImport).toBeLessThan(globalsImport)
|
|
})
|
|
})
|