Merge branch 'dev' into fix/keybind-modal-suspension
commit
569cbcb708
|
|
@ -3,14 +3,6 @@ description: "Setup Bun with caching and install dependencies"
|
|||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Cache Bun dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.bun/install/cache
|
||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-bun-
|
||||
|
||||
- name: Get baseline download URL
|
||||
id: bun-url
|
||||
shell: bash
|
||||
|
|
@ -31,6 +23,19 @@ runs:
|
|||
bun-version-file: ${{ !steps.bun-url.outputs.url && 'package.json' || '' }}
|
||||
bun-download-url: ${{ steps.bun-url.outputs.url }}
|
||||
|
||||
- name: Get cache directory
|
||||
id: cache
|
||||
shell: bash
|
||||
run: echo "dir=$(bun pm cache)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Cache Bun dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-bun-
|
||||
|
||||
- name: Install setuptools for distutils compatibility
|
||||
run: python3 -m pip install setuptools || pip install setuptools || true
|
||||
shell: bash
|
||||
|
|
|
|||
|
|
@ -780,27 +780,31 @@ export function MessageTimeline(props: {
|
|||
{(commentAccessor: () => MessageComment) => {
|
||||
const comment = createMemo(() => commentAccessor())
|
||||
return (
|
||||
<div class="shrink-0 max-w-[260px] rounded-[6px] border border-border-weak-base bg-background-stronger px-2.5 py-2">
|
||||
<div class="flex items-center gap-1.5 min-w-0 text-11-medium text-text-strong">
|
||||
<FileIcon
|
||||
node={{ path: comment().path, type: "file" }}
|
||||
class="size-3.5 shrink-0"
|
||||
/>
|
||||
<span class="truncate">{getFilename(comment().path)}</span>
|
||||
<Show when={comment().selection}>
|
||||
{(selection) => (
|
||||
<span class="shrink-0 text-text-weak">
|
||||
{selection().startLine === selection().endLine
|
||||
? `:${selection().startLine}`
|
||||
: `:${selection().startLine}-${selection().endLine}`}
|
||||
</span>
|
||||
)}
|
||||
</Show>
|
||||
</div>
|
||||
<div class="pt-1 text-12-regular text-text-strong whitespace-pre-wrap break-words">
|
||||
{comment().comment}
|
||||
</div>
|
||||
</div>
|
||||
<Show when={comment()}>
|
||||
{(c) => (
|
||||
<div class="shrink-0 max-w-[260px] rounded-[6px] border border-border-weak-base bg-background-stronger px-2.5 py-2">
|
||||
<div class="flex items-center gap-1.5 min-w-0 text-11-medium text-text-strong">
|
||||
<FileIcon
|
||||
node={{ path: c().path, type: "file" }}
|
||||
class="size-3.5 shrink-0"
|
||||
/>
|
||||
<span class="truncate">{getFilename(c().path)}</span>
|
||||
<Show when={c().selection}>
|
||||
{(selection) => (
|
||||
<span class="shrink-0 text-text-weak">
|
||||
{selection().startLine === selection().endLine
|
||||
? `:${selection().startLine}`
|
||||
: `:${selection().startLine}-${selection().endLine}`}
|
||||
</span>
|
||||
)}
|
||||
</Show>
|
||||
</div>
|
||||
<div class="pt-1 text-12-regular text-text-strong whitespace-pre-wrap break-words">
|
||||
{c().comment}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Show>
|
||||
)
|
||||
}}
|
||||
</Index>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export default defineConfig({
|
|||
},
|
||||
renderer: {
|
||||
plugins: [appPlugin],
|
||||
publicDir: "../app/public",
|
||||
publicDir: "../../../app/public",
|
||||
root: "src/renderer",
|
||||
build: {
|
||||
rollupOptions: {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { join, dirname, resolve } from "node:path"
|
||||
import { existsSync } from "node:fs"
|
||||
import { fileURLToPath } from "node:url"
|
||||
|
||||
const dir = dirname(fileURLToPath(import.meta.url))
|
||||
const root = resolve(dir, "../..")
|
||||
|
||||
const html = async (name: string) => Bun.file(join(dir, name)).text()
|
||||
|
||||
/**
|
||||
* Electron loads renderer HTML via `win.loadFile()` which uses the `file://`
|
||||
* protocol. Absolute paths like `src="/foo.js"` resolve to the filesystem root
|
||||
* (e.g. `file:///C:/foo.js` on Windows) instead of relative to the app bundle.
|
||||
*
|
||||
* All local resource references must use relative paths (`./`).
|
||||
*/
|
||||
describe("electron renderer html", () => {
|
||||
for (const name of ["index.html", "loading.html"]) {
|
||||
describe(name, () => {
|
||||
test("script src attributes use relative paths", async () => {
|
||||
const content = await html(name)
|
||||
const srcs = [...content.matchAll(/\bsrc=["']([^"']+)["']/g)].map((m) => m[1])
|
||||
for (const src of srcs) {
|
||||
expect(src).not.toMatch(/^\/[^/]/)
|
||||
}
|
||||
})
|
||||
|
||||
test("link href attributes use relative paths", async () => {
|
||||
const content = await html(name)
|
||||
const hrefs = [...content.matchAll(/<link[^>]+href=["']([^"']+)["']/g)].map((m) => m[1])
|
||||
for (const href of hrefs) {
|
||||
expect(href).not.toMatch(/^\/[^/]/)
|
||||
}
|
||||
})
|
||||
|
||||
test("no web manifest link (not applicable in Electron)", async () => {
|
||||
const content = await html(name)
|
||||
expect(content).not.toContain('rel="manifest"')
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Vite resolves `publicDir` relative to `root`, not the config file.
|
||||
* This test reads the actual values from electron.vite.config.ts to catch
|
||||
* regressions where the publicDir path no longer resolves correctly
|
||||
* after the renderer root is accounted for.
|
||||
*/
|
||||
describe("electron vite publicDir", () => {
|
||||
test("configured publicDir resolves to a directory with oc-theme-preload.js", async () => {
|
||||
const config = await Bun.file(join(root, "electron.vite.config.ts")).text()
|
||||
const pub = config.match(/publicDir:\s*["']([^"']+)["']/)
|
||||
const rendererRoot = config.match(/root:\s*["']([^"']+)["']/)
|
||||
expect(pub).not.toBeNull()
|
||||
expect(rendererRoot).not.toBeNull()
|
||||
const resolved = resolve(root, rendererRoot![1], pub![1])
|
||||
expect(existsSync(resolved)).toBe(true)
|
||||
expect(existsSync(join(resolved, "oc-theme-preload.js"))).toBe(true)
|
||||
})
|
||||
})
|
||||
|
|
@ -4,20 +4,19 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>OpenCode</title>
|
||||
<link rel="icon" type="image/png" href="/favicon-96x96-v3.png" sizes="96x96" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon-v3.svg" />
|
||||
<link rel="shortcut icon" href="/favicon-v3.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-v3.png" />
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<link rel="icon" type="image/png" href="./favicon-96x96-v3.png" sizes="96x96" />
|
||||
<link rel="icon" type="image/svg+xml" href="./favicon-v3.svg" />
|
||||
<link rel="shortcut icon" href="./favicon-v3.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="./apple-touch-icon-v3.png" />
|
||||
<meta name="theme-color" content="#F8F7F7" />
|
||||
<meta name="theme-color" content="#131010" media="(prefers-color-scheme: dark)" />
|
||||
<meta property="og:image" content="/social-share.png" />
|
||||
<meta property="twitter:image" content="/social-share.png" />
|
||||
<script id="oc-theme-preload-script" src="/oc-theme-preload.js"></script>
|
||||
<meta property="og:image" content="./social-share.png" />
|
||||
<meta property="twitter:image" content="./social-share.png" />
|
||||
<script id="oc-theme-preload-script" src="./oc-theme-preload.js"></script>
|
||||
</head>
|
||||
<body class="antialiased overscroll-none text-12-regular overflow-hidden">
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root" class="flex flex-col h-dvh"></div>
|
||||
<script src="/index.tsx" type="module"></script>
|
||||
<script src="./index.tsx" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -4,20 +4,19 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>OpenCode</title>
|
||||
<link rel="icon" type="image/png" href="/favicon-96x96-v3.png" sizes="96x96" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon-v3.svg" />
|
||||
<link rel="shortcut icon" href="/favicon-v3.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-v3.png" />
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<link rel="icon" type="image/png" href="./favicon-96x96-v3.png" sizes="96x96" />
|
||||
<link rel="icon" type="image/svg+xml" href="./favicon-v3.svg" />
|
||||
<link rel="shortcut icon" href="./favicon-v3.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="./apple-touch-icon-v3.png" />
|
||||
<meta name="theme-color" content="#F8F7F7" />
|
||||
<meta name="theme-color" content="#131010" media="(prefers-color-scheme: dark)" />
|
||||
<meta property="og:image" content="/social-share.png" />
|
||||
<meta property="twitter:image" content="/social-share.png" />
|
||||
<script id="oc-theme-preload-script" src="/oc-theme-preload.js"></script>
|
||||
<meta property="og:image" content="./social-share.png" />
|
||||
<meta property="twitter:image" content="./social-share.png" />
|
||||
<script id="oc-theme-preload-script" src="./oc-theme-preload.js"></script>
|
||||
</head>
|
||||
<body class="antialiased overscroll-none text-12-regular overflow-hidden">
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root" class="flex flex-col h-dvh"></div>
|
||||
<script src="/loading.tsx" type="module"></script>
|
||||
<script src="./loading.tsx" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -18,5 +18,6 @@
|
|||
"types": ["vite/client", "node", "electron"]
|
||||
},
|
||||
"references": [{ "path": "../app" }],
|
||||
"include": ["src", "package.json"]
|
||||
"include": ["src", "package.json"],
|
||||
"exclude": ["src/**/*.test.ts"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,7 +178,6 @@ for (const item of targets) {
|
|||
conditions: ["browser"],
|
||||
tsconfig: "./tsconfig.json",
|
||||
plugins: [solidPlugin],
|
||||
sourcemap: "external",
|
||||
compile: {
|
||||
autoloadBunfig: false,
|
||||
autoloadDotenv: false,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { Show } from "solid-js"
|
||||
import { Style, Link } from "@solidjs/meta"
|
||||
import inter from "../assets/fonts/inter.woff2"
|
||||
import ibmPlexMonoRegular from "../assets/fonts/ibm-plex-mono.woff2"
|
||||
|
|
@ -166,8 +167,10 @@ export const Font = () => {
|
|||
}
|
||||
${monoNerdCss}
|
||||
`}</Style>
|
||||
<Link rel="preload" href={inter} as="font" type="font/woff2" crossorigin="anonymous" />
|
||||
<Link rel="preload" href={ibmPlexMonoRegular} as="font" type="font/woff2" crossorigin="anonymous" />
|
||||
<Show when={typeof location === "undefined" || location.protocol !== "file:"}>
|
||||
<Link rel="preload" href={inter} as="font" type="font/woff2" crossorigin="anonymous" />
|
||||
<Link rel="preload" href={ibmPlexMonoRegular} as="font" type="font/woff2" crossorigin="anonymous" />
|
||||
</Show>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue