Update oxlint and oxfmt

This commit is contained in:
Neil 2026-05-30 13:09:17 -07:00 committed by GitHub
parent bbff68c85b
commit ddbb6a1e7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
36 changed files with 712 additions and 655 deletions

View File

@ -88,7 +88,7 @@ The workflow resolves the next version from GitHub Releases, bumps `package.json
**How the next version is chosen:**
All stable kinds (`patch`, `minor`, `major`) are computed off the latest *stable* release, ignoring any RCs in between.
All stable kinds (`patch`, `minor`, `major`) are computed off the latest _stable_ release, ignoring any RCs in between.
- `kind=rc` + last tag was stable (e.g. `v1.3.14`) → `v1.3.15-rc.0`.
- `kind=rc` + active RC series (e.g. `v1.3.15-rc.2`) → `v1.3.15-rc.3`.

View File

@ -1,6 +1,6 @@
name: Bug report
description: Report a problem with Orca
title: "[Bug]: "
title: '[Bug]: '
labels:
- bug
body:

View File

@ -1,6 +1,6 @@
name: Feature request
description: Suggest an improvement for Orca
title: "[Feature]: "
title: '[Feature]: '
labels:
- enhancement
body:

View File

@ -1,6 +1,6 @@
name: Other
description: Report another Orca issue type
title: "[Other]: "
title: '[Other]: '
body:
- type: textarea
id: details

View File

@ -1,5 +1,5 @@
{
"$schema": "https://raw.githubusercontent.com/nicolo-ribaudo/oxc-project.github.io/refs/heads/json-schemas/oxlint/v0.17.0/config.json",
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["typescript", "react", "react-hooks", "react-perf", "unicorn"],
"categories": {
"correctness": "error"

View File

@ -12,7 +12,7 @@ Keep comments short — one or two lines. Capture only the non-obvious reason (s
## File and Module Naming
Never use vague names like `helpers`, `utils`, `common`, `misc`, or `shared-stuff` for files, folders, or modules. They carry zero information and tend to become dumping grounds. Name files after what they *actually* contain — prefer the concrete domain concept (e.g. `tab-group-state.ts`, `terminal-orphan-cleanup.ts`) over the generic role (`tabs-helpers.ts`, `terminal-utils.ts`). If you find yourself reaching for `helpers`, the file probably has more than one responsibility and should be split, or there's a better name hiding in the code that describes what the functions operate on.
Never use vague names like `helpers`, `utils`, `common`, `misc`, or `shared-stuff` for files, folders, or modules. They carry zero information and tend to become dumping grounds. Name files after what they _actually_ contain — prefer the concrete domain concept (e.g. `tab-group-state.ts`, `terminal-orphan-cleanup.ts`) over the generic role (`tabs-helpers.ts`, `terminal-utils.ts`). If you find yourself reaching for `helpers`, the file probably has more than one responsibility and should be split, or there's a better name hiding in the code that describes what the functions operate on.
## Worktree Safety

View File

@ -26,7 +26,7 @@
## Supported Agents
Orca supports any CLI agent (*not just this list*).
Orca supports any CLI agent (_not just this list_).
<p>
<a href="https://docs.anthropic.com/claude/docs/claude-code"><kbd><img src="docs/assets/claude-logo.svg" width="16" valign="middle" /> Claude Code</kbd></a> &nbsp;
@ -80,7 +80,7 @@ Orca supports any CLI agent (*not just this list*).
- **[Download from onOrca.dev](https://onOrca.dev)**
- Or via **[GitHub Releases page](https://github.com/stablyai/orca/releases/latest)**
*Alternatively, install from a package manager:*
_Alternatively, install from a package manager:_
### macOS (Homebrew)

View File

@ -11,7 +11,11 @@ const args = new Set(process.argv.slice(2))
const requestedApps = valueFlag('--apps')
const includeScreenshot = args.has('--screenshot')
const session = valueFlag('--session') ?? `computer-smoke-${process.pid}`
const preferredApps = (requestedApps ?? process.env.ORCA_COMPUTER_SMOKE_APPS ?? 'Finder,TextEdit,Spotify,Slack,Microsoft Edge')
const preferredApps = (
requestedApps ??
process.env.ORCA_COMPUTER_SMOKE_APPS ??
'Finder,TextEdit,Spotify,Slack,Microsoft Edge'
)
.split(',')
.map((app) => app.trim())
.filter(Boolean)
@ -23,8 +27,12 @@ if (!existsSync(cliPath)) {
const list = unwrapResult(runCli(['computer', 'list-apps', '--json']))
const apps = Array.isArray(list.apps) ? list.apps : []
const availableNames = new Set(apps.map((app) => String(app.name ?? '').toLowerCase()))
const availableBundles = new Set(apps.map((app) => String(app.bundleId ?? '').toLowerCase()).filter(Boolean))
const targets = preferredApps.filter((app) => availableNames.has(app.toLowerCase()) || availableBundles.has(app.toLowerCase()))
const availableBundles = new Set(
apps.map((app) => String(app.bundleId ?? '').toLowerCase()).filter(Boolean)
)
const targets = preferredApps.filter(
(app) => availableNames.has(app.toLowerCase()) || availableBundles.has(app.toLowerCase())
)
console.log(`computer-use smoke: ${apps.length} apps listed`)
if (targets.length === 0) {
@ -34,16 +42,19 @@ if (targets.length === 0) {
let failures = 0
for (const app of targets) {
const result = runCli([
'computer',
'get-app-state',
'--session',
session,
'--app',
app,
...(includeScreenshot ? [] : ['--no-screenshot']),
'--json'
], { allowFailure: true })
const result = runCli(
[
'computer',
'get-app-state',
'--session',
session,
'--app',
app,
...(includeScreenshot ? [] : ['--no-screenshot']),
'--json'
],
{ allowFailure: true }
)
if (!result.ok) {
failures += 1
@ -57,15 +68,19 @@ for (const app of targets) {
const lineCount = treeText.split('\n').filter(Boolean).length
const secondaryActions = (treeText.match(/Secondary Actions:/g) ?? []).length
const settable = (treeText.match(/\bsettable\b/g) ?? []).length
const screenshotState = state.screenshot ? `${state.screenshot.width}x${state.screenshot.height}` : 'missing'
console.log([
`computer-use smoke: ${snapshot.app.name}`,
`${snapshot.elementCount} elements`,
`${lineCount} lines`,
`${secondaryActions} secondary-action lines`,
`${settable} settable elements`,
`screenshot=${screenshotState}`
].join(' | '))
const screenshotState = state.screenshot
? `${state.screenshot.width}x${state.screenshot.height}`
: 'missing'
console.log(
[
`computer-use smoke: ${snapshot.app.name}`,
`${snapshot.elementCount} elements`,
`${lineCount} lines`,
`${secondaryActions} secondary-action lines`,
`${settable} settable elements`,
`screenshot=${screenshotState}`
].join(' | ')
)
}
if (failures > 0) {
@ -86,7 +101,8 @@ function runCli(cliArgs, options = {}) {
encoding: 'utf8',
env: {
...process.env,
ORCA_USER_DATA_PATH: process.env.ORCA_COMPUTER_SMOKE_USER_DATA_PATH ?? defaultDevUserDataPath()
ORCA_USER_DATA_PATH:
process.env.ORCA_COMPUTER_SMOKE_USER_DATA_PATH ?? defaultDevUserDataPath()
}
})
if (child.status !== 0) {

View File

@ -10,9 +10,7 @@ const scriptDir = path.dirname(fileURLToPath(import.meta.url))
const source = path.join(scriptDir, 'orca-dev')
const commandPath =
process.platform === 'darwin' || process.platform === 'linux'
? '/usr/local/bin/orca-dev'
: null
process.platform === 'darwin' || process.platform === 'linux' ? '/usr/local/bin/orca-dev' : null
if (!commandPath) {
console.log('[orca-dev] Skipping global symlink (unsupported platform).')
@ -21,7 +19,9 @@ if (!commandPath) {
function isOwnedByUs(target) {
try {
if (!lstatSync(target).isSymbolicLink()) { return false }
if (!lstatSync(target).isSymbolicLink()) {
return false
}
return readlinkSync(target) === source
} catch {
return false

View File

@ -86,7 +86,7 @@ describe('Electron runtime package contract', () => {
expect(releaseWorkflow.jobs['homebrew-bump'].if).toContain(
"startsWith(needs.cut.outputs.tag, 'v')"
)
expect(releaseWorkflow.jobs['homebrew-bump'].if).not.toContain("-rc.")
expect(releaseWorkflow.jobs['homebrew-bump'].if).not.toContain('-rc.')
expect(releaseWorkflow.jobs['homebrew-bump-published-rc-draft'].with.tag).toBe(
'${{ needs.cut.outputs.latest_published_rc_tag }}'
)

View File

@ -7,10 +7,7 @@ const PAYLOAD_CHARS = Number.parseInt(process.env.ORCA_PTY_BENCH_PAYLOAD_CHARS ?
const RUNS = Number.parseInt(process.env.ORCA_PTY_BENCH_RUNS ?? '30', 10)
const MEASURE_TIMER_DELAYS = process.env.ORCA_PTY_BENCH_MEASURE_TIMER_DELAYS !== '0'
const INGRESS_CHUNKS = Number.parseInt(process.env.ORCA_PTY_BENCH_INGRESS_CHUNKS ?? '96', 10)
const INGRESS_CHUNK_CHARS = Number.parseInt(
process.env.ORCA_PTY_BENCH_INGRESS_CHARS ?? '65536',
10
)
const INGRESS_CHUNK_CHARS = Number.parseInt(process.env.ORCA_PTY_BENCH_INGRESS_CHARS ?? '65536', 10)
const CHUNK_CHARS = 16 * 1024
const MAX_WRITES_PER_SLICE = 2
const RECENT_PTY_OUTPUT_LIMIT = 4096
@ -30,14 +27,10 @@ if (!Number.isInteger(RUNS) || RUNS <= 0) {
throw new Error(`ORCA_PTY_BENCH_RUNS must be positive, received ${RUNS}`)
}
if (!Number.isInteger(INGRESS_CHUNKS) || INGRESS_CHUNKS <= 0) {
throw new Error(
`ORCA_PTY_BENCH_INGRESS_CHUNKS must be positive, received ${INGRESS_CHUNKS}`
)
throw new Error(`ORCA_PTY_BENCH_INGRESS_CHUNKS must be positive, received ${INGRESS_CHUNKS}`)
}
if (!Number.isInteger(INGRESS_CHUNK_CHARS) || INGRESS_CHUNK_CHARS <= 0) {
throw new Error(
`ORCA_PTY_BENCH_INGRESS_CHARS must be positive, received ${INGRESS_CHUNK_CHARS}`
)
throw new Error(`ORCA_PTY_BENCH_INGRESS_CHARS must be positive, received ${INGRESS_CHUNK_CHARS}`)
}
function makePendingData() {

View File

@ -85,13 +85,18 @@ export async function publishCompleteDraftReleases({
// Why: only release-cut-authored RC drafts with a complete asset set are
// resumed here; incomplete drafts stay private for the normal rebuild path.
await githubJson(fetchImpl, `https://api.github.com/repos/${repo}/releases/${release.id}`, token, {
method: 'PATCH',
body: JSON.stringify({
draft: false,
prerelease: isRcTag(tag)
})
})
await githubJson(
fetchImpl,
`https://api.github.com/repos/${repo}/releases/${release.id}`,
token,
{
method: 'PATCH',
body: JSON.stringify({
draft: false,
prerelease: isRcTag(tag)
})
}
)
published.push(tag)
log(`Published complete RC draft release ${tag}`)
}

View File

@ -241,12 +241,7 @@ function ensureRelativeSymlink(linkPath, target) {
}
function restoreElectronFrameworkSymlinks(appPath) {
const frameworkPath = path.join(
appPath,
'Contents',
'Frameworks',
'Electron Framework.framework'
)
const frameworkPath = path.join(appPath, 'Contents', 'Frameworks', 'Electron Framework.framework')
const versionsPath = path.join(frameworkPath, 'Versions')
if (!existsSync(path.join(versionsPath, 'A'))) {
return

View File

@ -142,10 +142,7 @@ export class OrcaTerminal {
*/
probePtyIdWithScreenshot(maxId = 10, screenshotPath = tempScreenshotPath('orca-pty-probe.png')) {
for (let i = 1; i <= maxId; i++) {
evalInRenderer(
this.port,
`window.api.pty.write('${i}', '\\x03\\x15echo PTY_ID_${i}\\r')`
)
evalInRenderer(this.port, `window.api.pty.write('${i}', '\\x03\\x15echo PTY_ID_${i}\\r')`)
}
sleep(2_000)
this.screenshot(screenshotPath)

View File

@ -170,9 +170,7 @@ function verifyAsar(asarPath) {
const writeKeyMatch = WRITE_KEY_RE.exec(indexJs)
if (!buildIdentityMatch) {
console.error(
`::error::BUILD_IDENTITY constant missing or unexpected value in ${asarPath}`
)
console.error(`::error::BUILD_IDENTITY constant missing or unexpected value in ${asarPath}`)
const sample = indexJs.match(/.{0,80}BUILD_IDENTITY.{0,80}/g)?.slice(0, 5) ?? []
for (const line of sample) {
console.error(` ${line.slice(0, 200)}`)
@ -213,9 +211,7 @@ for (const asarPath of asarMatches) {
const distinctIdentities = new Set(results.map((r) => r.buildIdentity))
if (distinctIdentities.size > 1) {
console.error(
`::error::asars disagree on BUILD_IDENTITY: ${[...distinctIdentities].join(', ')}`
)
console.error(`::error::asars disagree on BUILD_IDENTITY: ${[...distinctIdentities].join(', ')}`)
for (const r of results) {
console.error(` - ${r.asarPath}: ${r.buildIdentity}`)
}

View File

@ -1,6 +1,6 @@
# Orca UI Style Guide
This is the **UI/visual design** doc for Orca — color tokens, typography, component selection, and UX rules. It is *not* an architecture doc; for system-level design see code and inline comments. Token values live in `src/renderer/src/assets/main.css` (canonical); this file documents the *roles and rules* for using them.
This is the **UI/visual design** doc for Orca — color tokens, typography, component selection, and UX rules. It is _not_ an architecture doc; for system-level design see code and inline comments. Token values live in `src/renderer/src/assets/main.css` (canonical); this file documents the _roles and rules_ for using them.
## Overview
@ -14,12 +14,12 @@ When in doubt:
## Source of truth
| Concern | Canonical location |
| -------------------- | ------------------------------------------------ |
| Color tokens | `src/renderer/src/assets/main.css` (`:root`, `.dark`) |
| Tailwind theme bindings | Same file, `@theme inline { … }` block |
| Component primitives | `src/renderer/src/components/ui/` (shadcn-style) |
| App typography / scrollbars / titlebar chrome | Same `main.css` |
| Concern | Canonical location |
| --------------------------------------------- | ----------------------------------------------------- |
| Color tokens | `src/renderer/src/assets/main.css` (`:root`, `.dark`) |
| Tailwind theme bindings | Same file, `@theme inline { … }` block |
| Component primitives | `src/renderer/src/components/ui/` (shadcn-style) |
| App typography / scrollbars / titlebar chrome | Same `main.css` |
Never hardcode a hex value in component code if a variable already covers it. If a new token is needed, add it to `main.css` (both `:root` and `.dark`), expose it in the `@theme inline` block, then use it.
@ -27,21 +27,21 @@ Never hardcode a hex value in component code if a variable already covers it. If
Tokens come in pairs: a **surface** and a **foreground** that meets contrast on it. Always use them together.
| Role | Use it for | Don't use it for |
| ---------------------------------- | ------------------------------------------------------------- | --------------------------------------------- |
| `background` / `foreground` | App canvas, default text | Cards, popovers, sidebar (have their own) |
| `card` / `card-foreground` | Panels lifted off the canvas | The canvas itself |
| `popover` / `popover-foreground` | Floating menus, dropdowns, hovercards | Inline UI |
| `primary` / `primary-foreground` | The single affirmative action in a flow (Save, Confirm) | Decorative accents; hover states; secondary actions |
| `secondary` / `secondary-foreground` | Lower-emphasis actions next to a primary | The affirmative action |
| `muted` / `muted-foreground` | De-emphasized text, captions, placeholders, disabled chrome | Body copy; primary actions |
| `accent` / `accent-foreground` | Hover/active backgrounds for ghost buttons and list rows | Solid filled buttons (use `secondary` instead) |
| `destructive` / `destructive-foreground` | Delete, discard, irreversible-action buttons; error states | Cancel buttons (Cancel is not destructive) |
| `border` | All hairlines: dividers, input outlines, card edges | Heavy emphasis; that's `ring` |
| `input` | Form field background only | Anywhere outside form fields |
| `ring` | Focus-visible outlines, active selection halos | Persistent decoration |
| `sidebar` (+ variants) | The worktree sidebar and its children | Other panels |
| `editor-surface` | Background of Monaco / markdown editor panes | App chrome |
| Role | Use it for | Don't use it for |
| ---------------------------------------- | ----------------------------------------------------------- | --------------------------------------------------- |
| `background` / `foreground` | App canvas, default text | Cards, popovers, sidebar (have their own) |
| `card` / `card-foreground` | Panels lifted off the canvas | The canvas itself |
| `popover` / `popover-foreground` | Floating menus, dropdowns, hovercards | Inline UI |
| `primary` / `primary-foreground` | The single affirmative action in a flow (Save, Confirm) | Decorative accents; hover states; secondary actions |
| `secondary` / `secondary-foreground` | Lower-emphasis actions next to a primary | The affirmative action |
| `muted` / `muted-foreground` | De-emphasized text, captions, placeholders, disabled chrome | Body copy; primary actions |
| `accent` / `accent-foreground` | Hover/active backgrounds for ghost buttons and list rows | Solid filled buttons (use `secondary` instead) |
| `destructive` / `destructive-foreground` | Delete, discard, irreversible-action buttons; error states | Cancel buttons (Cancel is not destructive) |
| `border` | All hairlines: dividers, input outlines, card edges | Heavy emphasis; that's `ring` |
| `input` | Form field background only | Anywhere outside form fields |
| `ring` | Focus-visible outlines, active selection halos | Persistent decoration |
| `sidebar` (+ variants) | The worktree sidebar and its children | Other panels |
| `editor-surface` | Background of Monaco / markdown editor panes | App chrome |
The `sidebar` family expands into `--sidebar`, `--sidebar-foreground`, `--sidebar-primary`, `--sidebar-primary-foreground`, `--sidebar-accent`, `--sidebar-accent-foreground`, `--sidebar-border`, and `--sidebar-ring` — use them inside the worktree sidebar so its hover/selected/focus states stay consistent and don't bleed into other panels. `editor-surface` is its own token (not just `background`) because Monaco and the markdown editor have a slightly darker surface in dark mode to match VS Code conventions; reach for it whenever you're rendering an editor pane.
@ -49,17 +49,17 @@ The `sidebar` family expands into `--sidebar`, `--sidebar-foreground`, `--sideba
For diff status, file-tree decorations, and the changes view, use the git decoration tokens (mirroring VS Code's palette so users transferring from VS Code aren't surprised):
| Token | State |
| ------------------------------ | ------------------------------ |
| `--git-decoration-added` | Added / new |
| `--git-decoration-modified` | Modified |
| `--git-decoration-deleted` | Deleted |
| `--git-decoration-renamed` | Renamed |
| `--git-decoration-untracked` | Untracked |
| `--git-decoration-copied` | Copied |
| `--git-decoration-ignored` | Ignored by git |
| Token | State |
| ---------------------------- | -------------- |
| `--git-decoration-added` | Added / new |
| `--git-decoration-modified` | Modified |
| `--git-decoration-deleted` | Deleted |
| `--git-decoration-renamed` | Renamed |
| `--git-decoration-untracked` | Untracked |
| `--git-decoration-copied` | Copied |
| `--git-decoration-ignored` | Ignored by git |
Use these *only* for git status. Don't reuse them for unrelated state colors — that breaks the convention.
Use these _only_ for git status. Don't reuse them for unrelated state colors — that breaks the convention.
### List rows: hover, selected, current
@ -68,7 +68,7 @@ A common point of drift. Use these conventions for any list-style row (worktrees
- **Idle:** transparent background.
- **Hover:** `bg-accent` (in the worktree sidebar, `bg-sidebar-accent`).
- **Keyboard-selected (cmdk highlight):** `data-[selected=true]:bg-accent` plus a `border-border` outline so the active row stays visible while the user types. The `data-selected` attribute is set by `cmdk` automatically.
- **Persistent "current" / "active" row** (e.g. the worktree the user is viewing): also `bg-accent`, *plus* a `data-current="true"` attribute so CSS or future styling can distinguish it from the cmdk highlight.
- **Persistent "current" / "active" row** (e.g. the worktree the user is viewing): also `bg-accent`, _plus_ a `data-current="true"` attribute so CSS or future styling can distinguish it from the cmdk highlight.
- **Don't:** hardcode `bg-[#ededed]` / `bg-[#333333]` or invent a "selected" color. The accent token already adapts to light/dark and matches the rest of the app.
### Color mixing
@ -118,14 +118,14 @@ Use the shadcn primitives in `src/renderer/src/components/ui/` before writing an
Variants in priority order:
| Variant | Use case |
| ------------- | ---------------------------------------------------------------- |
| `default` | The single affirmative action in a flow. |
| `secondary` | Lower-emphasis sibling next to a `default`. |
| `outline` | Toolbar / standalone actions where a filled button feels heavy. |
| Variant | Use case |
| ------------- | ------------------------------------------------------------------ |
| `default` | The single affirmative action in a flow. |
| `secondary` | Lower-emphasis sibling next to a `default`. |
| `outline` | Toolbar / standalone actions where a filled button feels heavy. |
| `ghost` | Icon buttons, list-row triggers, anywhere chrome should disappear. |
| `link` | Inline text actions inside paragraphs. |
| `destructive` | Delete, discard, irreversible. Never for Cancel. |
| `link` | Inline text actions inside paragraphs. |
| `destructive` | Delete, discard, irreversible. Never for Cancel. |
Sizes: `default` (36px), `sm` (32px), `xs` (24px), `lg` (40px), plus `icon`, `icon-xs`, `icon-sm`, `icon-lg`. Match the size to the surrounding row height — don't drop a `default` button into a 28px toolbar.
@ -137,26 +137,26 @@ Browse `src/renderer/src/components/ui/` for the full list. Most wrap a Radix UI
When a control has multiple plausible primitives, use this fork:
| You want… | Reach for | Don't use |
| -------------------------------------------------------- | -------------------------- | ---------------------------------------- |
| Hover-only label on an icon-only button | `Tooltip` | `HoverCard` (too heavy), title attr |
| Hover preview of richer content (avatar + summary) | `HoverCard` | `Tooltip` (no rich content) |
| Click-revealed menu with actions | `DropdownMenu` | `Popover` with hand-rolled list |
| Right-click contextual actions | `ContextMenu` | `DropdownMenu` (different invocation) |
| Click-revealed surface with arbitrary content (form, picker) | `Popover` | `Dialog` (it traps focus and dims) |
| Modal that demands a decision before you continue | `Dialog` | `Popover`, inline overlay |
| Drawer / panel sliding in from an edge | `Sheet` | `Dialog` centered |
| Single choice from a known list | `Select` | Custom listbox |
| Single choice with search / fuzzy filtering | `Command` inside `Popover` | `Select` (no search) |
| Multi-select with search | `repo-multi-combobox` / `team-multi-combobox` (mirror their pattern) | Roll a new one |
| Transient confirmation ("Saved", "Copied") | `sonner` toast | `Dialog`, inline banner |
| Persistent inline status ("3 errors") | inline text + `Badge` | toast (toasts disappear) |
| You want… | Reach for | Don't use |
| ------------------------------------------------------------ | -------------------------------------------------------------------- | ------------------------------------- |
| Hover-only label on an icon-only button | `Tooltip` | `HoverCard` (too heavy), title attr |
| Hover preview of richer content (avatar + summary) | `HoverCard` | `Tooltip` (no rich content) |
| Click-revealed menu with actions | `DropdownMenu` | `Popover` with hand-rolled list |
| Right-click contextual actions | `ContextMenu` | `DropdownMenu` (different invocation) |
| Click-revealed surface with arbitrary content (form, picker) | `Popover` | `Dialog` (it traps focus and dims) |
| Modal that demands a decision before you continue | `Dialog` | `Popover`, inline overlay |
| Drawer / panel sliding in from an edge | `Sheet` | `Dialog` centered |
| Single choice from a known list | `Select` | Custom listbox |
| Single choice with search / fuzzy filtering | `Command` inside `Popover` | `Select` (no search) |
| Multi-select with search | `repo-multi-combobox` / `team-multi-combobox` (mirror their pattern) | Roll a new one |
| Transient confirmation ("Saved", "Copied") | `sonner` toast | `Dialog`, inline banner |
| Persistent inline status ("3 errors") | inline text + `Badge` | toast (toasts disappear) |
If you find yourself styling around a primitive (`<Popover>` to act like a `<Dialog>`, or vice versa), stop and reconsider — the focus-management semantics differ and a future contributor will be misled by the mismatch.
### Tooltips
Tooltips exist to *name* a control whose meaning isn't obvious from its appearance. They are not the place to teach, persuade, or warn — anything users need to read while acting belongs in the visible UI.
Tooltips exist to _name_ a control whose meaning isn't obvious from its appearance. They are not the place to teach, persuade, or warn — anything users need to read while acting belongs in the visible UI.
- **Use a tooltip when:** an icon-only button or compact chip needs a label. Toolbar icons, badges with abbreviations, truncated paths.
- **Don't use a tooltip when:** the control already has a visible label, the content is interactive (links, buttons), or the message is critical (errors, blocking warnings — those go inline).
@ -172,7 +172,9 @@ Tooltips exist to *name* a control whose meaning isn't obvious from its appearan
<Settings />
</Button>
</TooltipTrigger>
<TooltipContent side="top" sideOffset={4}>Settings</TooltipContent>
<TooltipContent side="top" sideOffset={4}>
Settings
</TooltipContent>
</Tooltip>
```
@ -185,11 +187,11 @@ Icons come from **`lucide-react`**. Don't import a second icon library.
- **`size-7`+:** for featured/empty-state hero icons only.
- **Stroke width:** lucide's default 2px. Don't override per-icon.
- **Color:** inherit from surrounding text — `text-muted-foreground` for secondary, `text-destructive` for destructive, etc. Don't apply a token to the SVG directly when the parent already carries the right color.
- **Spinner:** the canonical loading icon is `<Loader2 className="size-4 animate-spin" />`. For 3s+ multi-step work, prefer a label that names the stage ("Cloning…" → "Installing…") over an unlabeled spinner. See *UX rule 1*.
- **Spinner:** the canonical loading icon is `<Loader2 className="size-4 animate-spin" />`. For 3s+ multi-step work, prefer a label that names the stage ("Cloning…" → "Installing…") over an unlabeled spinner. See _UX rule 1_.
### Keyboard shortcut chips
Use **`<ShortcutKeyCombo />`** from `src/renderer/src/components/ShortcutKeyCombo.tsx`. It renders a consistent key-cap style and inserts a `+` separator on Windows/Linux (Mac shows adjacent glyphs, no separator). It does **not** transform key strings — the *caller* picks the platform-appropriate labels and passes them in:
Use **`<ShortcutKeyCombo />`** from `src/renderer/src/components/ShortcutKeyCombo.tsx`. It renders a consistent key-cap style and inserts a `+` separator on Windows/Linux (Mac shows adjacent glyphs, no separator). It does **not** transform key strings — the _caller_ picks the platform-appropriate labels and passes them in:
```tsx
const isMac = navigator.userAgent.includes('Mac')
@ -204,7 +206,7 @@ See `Landing.tsx` for the canonical pattern. Don't roll a one-off `<kbd>` — kb
- **Tooltips on icon buttons** — append the chip after the label, trailing.
- **Dropdown / context-menu items** — use `<DropdownMenuShortcut>` (or its context-menu equivalent) for the right-aligned chip; don't position one yourself.
- **Never on Cancel, Dismiss, or `link`-variant inline actions** — see *UX rule 3*.
- **Never on Cancel, Dismiss, or `link`-variant inline actions** — see _UX rule 3_.
**The label MUST match the actual binding for the platform.** If the keyboard handler reads `metaKey` on Mac and `ctrlKey` elsewhere, the chip must show `⌘` on Mac and `Ctrl` elsewhere. Mismatched chips are worse than no chip.
@ -235,25 +237,25 @@ These are the rules a contributor will most often get wrong if they're working i
### 1. Match in-flight feedback to perceived duration
The right question isn't *"should this control change while it's working?"* — it's *"how long does the action take, and what does the user need to know during that time?"*
The right question isn't _"should this control change while it's working?"_ — it's _"how long does the action take, and what does the user need to know during that time?"_
| Duration | Feedback |
| ------------------- | ------------------------------------------------------- |
| 0100 ms | None. Anything visible reads as a glitch. |
| 100 ms1 s | Disabled state only. |
| 1 s3 s | Disabled + spinner or label swap. |
| 3 s+ or multi-step | Stage labels, progress, optional reassurance. |
| Duration | Feedback |
| ------------------ | --------------------------------------------- |
| 0100 ms | None. Anything visible reads as a glitch. |
| 100 ms1 s | Disabled state only. |
| 1 s3 s | Disabled + spinner or label swap. |
| 3 s+ or multi-step | Stage labels, progress, optional reassurance. |
Two corollaries:
- **Pre-reserve any space you'll later occupy.** If a control may swap to a longer label or grow an icon, fix its footprint up front (use `width`, not `min-width`). A control that resizes mid-action looks broken even when the action succeeded.
- **Don't pick worst-case feedback for everyone.** If the action is fast locally and slow remotely (SSH), defer the visible loading state by ~200ms. Local users see nothing; remote users get appropriate feedback. Bind the *disabled* state immediately (so double-clicks don't double-submit) and the *visible* state on a timer.
- **Don't pick worst-case feedback for everyone.** If the action is fast locally and slow remotely (SSH), defer the visible loading state by ~200ms. Local users see nothing; remote users get appropriate feedback. Bind the _disabled_ state immediately (so double-clicks don't double-submit) and the _visible_ state on a timer.
### 2. Look for sibling components before designing in isolation
If your component has a sibling — same domain, overlapping behavior, often visible at adjacent moments in the same flow — the two should read as one design. Same icons, same shortcut conventions, same submit semantics. A user moving between them shouldn't perceive a seam.
This is *not* "match every existing pattern." Some repo patterns are debt and copying them spreads the debt. The narrower claim is about *adjacent* components. Diverging from a sibling needs a reason: either the sibling is wrong (fix both) or the new component has a real difference in role (commit to it).
This is _not_ "match every existing pattern." Some repo patterns are debt and copying them spreads the debt. The narrower claim is about _adjacent_ components. Diverging from a sibling needs a reason: either the sibling is wrong (fix both) or the new component has a real difference in role (commit to it).
When there's no sibling, match the surrounding chrome — button sizes, icon weights, copy tone — and don't manufacture a sibling from a screen the user will never correlate with this one.
@ -268,7 +270,7 @@ Orca runs on macOS, Linux, and Windows. Every UI change must hold up on all thre
- **Modifier keys:** Never hardcode `e.metaKey`. Use `navigator.userAgent.includes('Mac')` to choose `metaKey` on Mac and `ctrlKey` on Linux/Windows. Electron menu accelerators should use `CmdOrCtrl`.
- **Shortcut labels:** Display `⌘` / `⇧` on Mac; display `Ctrl+` / `Shift+` on other platforms. The label must reflect the actual binding for that platform.
- **Window chrome:** macOS shows traffic lights; the titlebar reserves an 80px gutter (`titlebar-traffic-light-pad`) so they don't overlap content. Don't put hit targets in that band on Mac.
- **SSH:** Many users run Orca on a remote machine. Loading states, focus management, and animations must hold up under 50200 ms of extra latency. Test under simulated latency (or actual SSH) — local-only verification isn't enough. See *UX rules → 1*.
- **SSH:** Many users run Orca on a remote machine. Loading states, focus management, and animations must hold up under 50200 ms of extra latency. Test under simulated latency (or actual SSH) — local-only verification isn't enough. See _UX rules → 1_.
## When this guide is silent

View File

@ -43,17 +43,14 @@ The behavior must work from both the titlebar tab strip and split-group tab stri
`TabBar` owns input text, pending state, focus, and dropdown close behavior. It does not create browser tabs or files. `groupId` should be `groupId ?? worktreeId`, matching the existing `resolvedGroupId` fallback.
3. Add a small hook/helper pair instead of duplicating Quick Open logic:
- `useTabEntryFileList` loads the file list when the menu opens, using the same inputs as `QuickOpen`: active worktree path, `getConnectionId(worktreeId)`, nested worktree exclusions, and active SSH target status. It cancels stale requests on close or key changes.
- A pure classifier/opening helper accepts the query, file-list snapshot, load/error state, worktree metadata, runtime context, and target group.
4. Wire the callback in both owners:
- `Terminal.tsx` titlebar fallback resolves the current active worktree and target group the same way `handleNewTab` / `handleNewBrowserTab` do.
- `useTabGroupWorkspaceModel` passes its explicit `worktreeId` and `groupId`. Do not rely on ambient `activeGroupIdByWorktree`; split-group `+` can be invoked from an unfocused group.
5. Classify submissions in this order:
- Empty after trim: reject inline.
- Explicit URL: accept only `http://` and `https://` URLs with a parseable host.
- Existing file: once the file-list snapshot is ready, normalize query separators for matching, prefer exact relative-path match, then exact basename match, then `rankQuickOpenFiles`. Before opening, `statRuntimePath` the matched absolute path and reject directories/stale missing matches instead of blindly opening stale list entries.
@ -61,14 +58,12 @@ The behavior must work from both the titlebar tab strip and split-group tab stri
- New file: only after file listing has completed successfully with no existing-file match and no host-like URL match. Treat the query as a relative worktree path. If listing fails, allow explicit `http://` / `https://` URLs only; keep bare host-like inputs blocked because they cannot be disambiguated from files.
6. Validate new file paths before joining:
- Reject POSIX absolute paths, Windows drive paths, UNC paths, `~`, empty path, trailing slash, control characters, `.` / `..` segments, and empty raw segments such as `a//b`.
- Normalize `\` to `/` only after absolute-path checks, then run segment validation on the normalized path too so traversal like `a\..\b` is still rejected.
- Build the absolute path with `joinPath(worktreePath, relativePath)`, then create with `createRuntimePath(context, absolutePath, 'file')`.
- On `EEXIST` / "exists", immediately `statRuntimePath`; if it is now a file, open it. If it is a directory, show an error. This handles another window/process winning the create race.
7. Open actions:
- URL: in paired web clients, call `createWebRuntimeSessionBrowserTab({ worktreeId, url, targetGroupId: groupId })`; otherwise call `createBrowserTab(worktreeId, url, { activate: true, targetGroupId: groupId, title: url })`. Do not use `openNewBrowserTabInActiveWorkspace`; it only opens the default URL.
- Existing/new file: call `openFile(fileInfo, { preview: false, targetGroupId: groupId })` with `language: detectLanguage(relativePath)`. Include the active runtime environment owner as `runtimeEnvironmentId` through the normal `openFile` fallback; do not suppress runtime ownership.

View File

@ -21,37 +21,37 @@ Do not upload this state as broad analytics. Product analytics should continue t
## Feature Catalog
| Feature | Interaction ID | Record when | Education use |
| --- | --- | --- | --- |
| Review notes to agent | `review-notes` | A diff or markdown review note is added, or review notes are marked sent to an agent. | Suppress or target a future review-notes tour/tip about adding line notes and sending focused feedback back to an agent. |
| AI commit generation | `ai-commit-generation` | AI commit-message generation is enabled or an AI commit message is generated. | Suppress future education about AI commit generation. No contextual tour is planned for this branch. |
| AI PR generation | `ai-pr-generation` | AI pull-request title/body/draft fields are generated. | Suppress future education about AI PR generation. No contextual tour is planned for this branch. |
| Floating Workspace | `floating-workspace` | The floating workspace opens, is enabled, or is configured. | Suppress future tips about the global terminal/browser/markdown workspace. No contextual tour is planned for this branch. |
| Quick Commands | `quick-commands` | A terminal quick command is created or edited. | Suppress future tips about saved terminal commands. No contextual tour is planned for this branch. |
| Computer Use setup | `computer-use-setup` | Computer Use is selected in onboarding, a permission setup is opened, or the skill setup terminal opens. | Suppress setup-focused tips once the user has started setup. |
| Computer Use | `computer-use` | A successful `computer.*` runtime method other than capability probing is handled. | Suppress future usage tips once an agent has actually invoked Computer Use. |
| Mobile pairing | `mobile-pairing` | Mobile is enabled or a mobile pairing QR/code is generated. | Suppress future mobile-pairing tips. No contextual tour is planned for this branch. |
| Browser element grab | `browser-grab` | Browser grab mode is started, an element is copied, or an element screenshot is copied. | Suppress future tips about grabbing page context once the user has used the element picker. |
| Browser annotations | `browser-annotations` | Browser annotation mode is started, an annotation is added, browser annotations are copied, or browser annotations are cleared. | Suppress future tips about annotating local pages and sending concrete UI feedback to an agent. |
| Cookie import | `cookie-import` | Browser cookies are imported from another browser or file, imported through runtime browser profile methods, or default imported cookies are cleared. | Suppress future cookie-import education without conflating cookie setup with Agent Browser Use itself. |
| Workspace board actions | `workspace-board-actions` | A card/status action, lane configuration, density change, pin drop, or board drag action is used. | Keep the existing workspace-board tour, and avoid repeating deeper board-action education after real use. |
| Automation creation | `automation-created` | A local automation or external Hermes cron is created. | Keep the existing Automations tour, and suppress creation-focused education after the user creates one. |
| Automation run | `automation-run` | A local or external automation run is manually queued. | Keep the existing Automations tour, and suppress run/inspection education after the user queues a run. |
| Resource Manager | `resource-manager` | The Resource Manager status-bar popover is opened, or its status-bar visibility is toggled in Appearance/status-bar controls. | Suppress future tips about CPU, memory, session, daemon, and workspace disk-scan controls after the user has found the manager. |
| Workspace cleanup / disk space | `workspace-cleanup` | The Space page opens, a workspace disk scan starts/cancels, or cleanup removes scanned workspace rows. | Suppress future tips about scanning workspace disk usage and reclaiming old workspace storage. |
| Ports | `ports` | The Ports popover opens, the Ports status-bar item is configured, external ports are expanded, or a port is opened/copied/stopped. | Suppress future tips about discovering and acting on workspace ports. |
| SSH | `ssh` | SSH status opens, SSH status-bar visibility changes, a target is added/imported/tested, or an SSH target is connected/disconnected. | Suppress future SSH setup/status tips after the user has interacted with remote target controls. |
| Provider usage tracking | `usage-tracking` | Stats & Usage is opened, Claude/Codex/OpenCode usage analytics are enabled, provider usage details are opened from the status bar, Gemini usage/OAuth is configured, or provider usage status-bar toggles are changed. | Suppress future tips about where to find token/rate-limit/usage tracking for Claude, Codex, Gemini, OpenCode, and related providers. |
| Claude account switching | `claude-account-switching` | A Claude managed account is added, selected, reauthenticated, removed, or selected from the status bar. | Suppress future tips about using multiple Claude accounts once the user has started account management. |
| Codex account switching | `codex-account-switching` | A Codex managed account is added, selected, reauthenticated, removed, or selected from the status bar. | Suppress future tips about Codex account switching and restart follow-up flows. |
| Workspace tabs | `terminal-tabs` | A workspace tab is created, reordered, renamed, recolored, pinned/unpinned, moved, or closed. | Suppress future tips about tab-level workspace organization. These are real workspace tabs, not workspace board cards. |
| Split panes | `terminal-panes` | A split group is created from the pane shortcut/menu, a split is resized, or panes are merged. | Suppress future tips about pane-level split workflows. |
| Tab splits | `tab-splits` | A workspace tab is moved into another pane or split into a new pane from a tab split/drop action. | Suppress future tips about tab-level split workflows separately from pane creation/resizing. |
| Agent Browser Use setup | `agent-browser-setup` | Browser Use is selected in onboarding, enabled in settings, or its setup terminal opens. | Suppress future setup tips once the user has started Browser Use setup. |
| Agent Browser Use | `agent-browser-use` | A successful non-profile `browser.*` runtime method is handled. | Suppress future usage tips once an agent/runtime has actually driven Orca's browser. |
| Agent Orchestration setup | `agent-orchestration-setup` | Orchestration is selected in onboarding, enabled in settings, or its setup terminal opens. | Suppress future setup tips once the user has started Orchestration setup. |
| Agent Orchestration | `agent-orchestration` | A successful `orchestration.*` runtime method is handled. | Suppress future usage tips once an agent/runtime has actually used orchestration. |
| Notifications | `notifications` | Notifications are enabled in onboarding/settings or a test notification is sent. | Suppress future notification setup tips. |
| Feature | Interaction ID | Record when | Education use |
| ------------------------------ | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| Review notes to agent | `review-notes` | A diff or markdown review note is added, or review notes are marked sent to an agent. | Suppress or target a future review-notes tour/tip about adding line notes and sending focused feedback back to an agent. |
| AI commit generation | `ai-commit-generation` | AI commit-message generation is enabled or an AI commit message is generated. | Suppress future education about AI commit generation. No contextual tour is planned for this branch. |
| AI PR generation | `ai-pr-generation` | AI pull-request title/body/draft fields are generated. | Suppress future education about AI PR generation. No contextual tour is planned for this branch. |
| Floating Workspace | `floating-workspace` | The floating workspace opens, is enabled, or is configured. | Suppress future tips about the global terminal/browser/markdown workspace. No contextual tour is planned for this branch. |
| Quick Commands | `quick-commands` | A terminal quick command is created or edited. | Suppress future tips about saved terminal commands. No contextual tour is planned for this branch. |
| Computer Use setup | `computer-use-setup` | Computer Use is selected in onboarding, a permission setup is opened, or the skill setup terminal opens. | Suppress setup-focused tips once the user has started setup. |
| Computer Use | `computer-use` | A successful `computer.*` runtime method other than capability probing is handled. | Suppress future usage tips once an agent has actually invoked Computer Use. |
| Mobile pairing | `mobile-pairing` | Mobile is enabled or a mobile pairing QR/code is generated. | Suppress future mobile-pairing tips. No contextual tour is planned for this branch. |
| Browser element grab | `browser-grab` | Browser grab mode is started, an element is copied, or an element screenshot is copied. | Suppress future tips about grabbing page context once the user has used the element picker. |
| Browser annotations | `browser-annotations` | Browser annotation mode is started, an annotation is added, browser annotations are copied, or browser annotations are cleared. | Suppress future tips about annotating local pages and sending concrete UI feedback to an agent. |
| Cookie import | `cookie-import` | Browser cookies are imported from another browser or file, imported through runtime browser profile methods, or default imported cookies are cleared. | Suppress future cookie-import education without conflating cookie setup with Agent Browser Use itself. |
| Workspace board actions | `workspace-board-actions` | A card/status action, lane configuration, density change, pin drop, or board drag action is used. | Keep the existing workspace-board tour, and avoid repeating deeper board-action education after real use. |
| Automation creation | `automation-created` | A local automation or external Hermes cron is created. | Keep the existing Automations tour, and suppress creation-focused education after the user creates one. |
| Automation run | `automation-run` | A local or external automation run is manually queued. | Keep the existing Automations tour, and suppress run/inspection education after the user queues a run. |
| Resource Manager | `resource-manager` | The Resource Manager status-bar popover is opened, or its status-bar visibility is toggled in Appearance/status-bar controls. | Suppress future tips about CPU, memory, session, daemon, and workspace disk-scan controls after the user has found the manager. |
| Workspace cleanup / disk space | `workspace-cleanup` | The Space page opens, a workspace disk scan starts/cancels, or cleanup removes scanned workspace rows. | Suppress future tips about scanning workspace disk usage and reclaiming old workspace storage. |
| Ports | `ports` | The Ports popover opens, the Ports status-bar item is configured, external ports are expanded, or a port is opened/copied/stopped. | Suppress future tips about discovering and acting on workspace ports. |
| SSH | `ssh` | SSH status opens, SSH status-bar visibility changes, a target is added/imported/tested, or an SSH target is connected/disconnected. | Suppress future SSH setup/status tips after the user has interacted with remote target controls. |
| Provider usage tracking | `usage-tracking` | Stats & Usage is opened, Claude/Codex/OpenCode usage analytics are enabled, provider usage details are opened from the status bar, Gemini usage/OAuth is configured, or provider usage status-bar toggles are changed. | Suppress future tips about where to find token/rate-limit/usage tracking for Claude, Codex, Gemini, OpenCode, and related providers. |
| Claude account switching | `claude-account-switching` | A Claude managed account is added, selected, reauthenticated, removed, or selected from the status bar. | Suppress future tips about using multiple Claude accounts once the user has started account management. |
| Codex account switching | `codex-account-switching` | A Codex managed account is added, selected, reauthenticated, removed, or selected from the status bar. | Suppress future tips about Codex account switching and restart follow-up flows. |
| Workspace tabs | `terminal-tabs` | A workspace tab is created, reordered, renamed, recolored, pinned/unpinned, moved, or closed. | Suppress future tips about tab-level workspace organization. These are real workspace tabs, not workspace board cards. |
| Split panes | `terminal-panes` | A split group is created from the pane shortcut/menu, a split is resized, or panes are merged. | Suppress future tips about pane-level split workflows. |
| Tab splits | `tab-splits` | A workspace tab is moved into another pane or split into a new pane from a tab split/drop action. | Suppress future tips about tab-level split workflows separately from pane creation/resizing. |
| Agent Browser Use setup | `agent-browser-setup` | Browser Use is selected in onboarding, enabled in settings, or its setup terminal opens. | Suppress future setup tips once the user has started Browser Use setup. |
| Agent Browser Use | `agent-browser-use` | A successful non-profile `browser.*` runtime method is handled. | Suppress future usage tips once an agent/runtime has actually driven Orca's browser. |
| Agent Orchestration setup | `agent-orchestration-setup` | Orchestration is selected in onboarding, enabled in settings, or its setup terminal opens. | Suppress future setup tips once the user has started Orchestration setup. |
| Agent Orchestration | `agent-orchestration` | A successful `orchestration.*` runtime method is handled. | Suppress future usage tips once an agent/runtime has actually used orchestration. |
| Notifications | `notifications` | Notifications are enabled in onboarding/settings or a test notification is sent. | Suppress future notification setup tips. |
## Surface-Level Features

View File

@ -15,11 +15,11 @@ This file records operational availability. Event contracts still live in `src/s
## Boundary Fields
| Field | Meaning |
| --- | --- |
| `code_merged_at_utc` | When the implementation reached `main`. Useful for source history only. |
| `first_released_at_utc` | First release commit/build that contains the code. This is the earliest possible user exposure. |
| `first_seen_at_utc` | First observed PostHog row for the event/property. This proves at least one event flowed. |
| Field | Meaning |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
| `code_merged_at_utc` | When the implementation reached `main`. Useful for source history only. |
| `first_released_at_utc` | First release commit/build that contains the code. This is the earliest possible user exposure. |
| `first_seen_at_utc` | First observed PostHog row for the event/property. This proves at least one event flowed. |
| `dashboard_ready_at_utc` | Earliest lower bound for saved dashboards after all required signals have first-valid rows and pass any validation window. |
First-valid means the released app version has been observed, the required event/property fields are populated, joins used by the dashboard are available, and any validation window listed in the rollout entry has passed.
@ -48,32 +48,32 @@ D1+/D3+/D7+ retention means the user fired `app_opened` at least once after 24/7
Scope: `nth_repo_added` on repo/activation/retention events. Current schemas declare it on `app_opened`, `repo_added`, `add_repo_setup_step_action`, `add_repo_existing_workspaces_detected`, `workspace_created`, `workspace_create_failed`, `setup_script_prompt_shown`, `setup_script_prompt_action`, `agent_started`, `agent_prompt_sent`, and `agent_error`. The original rollout covered `app_opened`, `repo_added`, `add_repo_setup_step_action`, `workspace_created`, `workspace_create_failed`, `agent_started`, and `agent_error`; later events have their own first-seen timestamps below.
| Field | Value |
| --- | --- |
| PR | `#1591` |
| Merge commit | `002e2acc38cad262d694049cc86c0962ffd381ce` |
| `code_merged_at_utc` | `2026-05-08T17:50:44Z` |
| First release | `v1.3.42-rc.1` |
| First release commit | `b6dab85aaa0e9b600ec93846824ba815542a1e1e` |
| `first_released_at_utc` | `2026-05-08T17:56:35Z` |
| Earliest `first_seen_at_utc` | `2026-05-08T18:40:00.354Z` on `app_opened` |
| `dashboard_ready_at_utc` | Event-dependent. Use `2026-05-08T18:40:00.354Z` for general `app_opened` repo-count cuts; use `2026-05-08T20:01:06.364Z` or later for first-repo activation cuts requiring `repo_added`. |
| Field | Value |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| PR | `#1591` |
| Merge commit | `002e2acc38cad262d694049cc86c0962ffd381ce` |
| `code_merged_at_utc` | `2026-05-08T17:50:44Z` |
| First release | `v1.3.42-rc.1` |
| First release commit | `b6dab85aaa0e9b600ec93846824ba815542a1e1e` |
| `first_released_at_utc` | `2026-05-08T17:56:35Z` |
| Earliest `first_seen_at_utc` | `2026-05-08T18:40:00.354Z` on `app_opened` |
| `dashboard_ready_at_utc` | Event-dependent. Use `2026-05-08T18:40:00.354Z` for general `app_opened` repo-count cuts; use `2026-05-08T20:01:06.364Z` or later for first-repo activation cuts requiring `repo_added`. |
PostHog evidence checked at `2026-05-23T23:34:32Z`:
| Event | First seen with `nth_repo_added` |
| --- | --- |
| `app_opened` | `2026-05-08T18:40:00.354Z` (`1.3.42-rc.1`) |
| `workspace_created` | `2026-05-08T19:15:06.913Z` |
| `agent_started` | `2026-05-08T19:15:07.130Z` |
| `agent_prompt_sent` | `TBD` |
| `repo_added` | `2026-05-08T20:01:06.364Z` (`1.3.42`) |
| `add_repo_setup_step_action` | `2026-05-08T20:01:20.897Z` |
| `workspace_create_failed` | `2026-05-08T23:04:32.315Z` |
| `agent_error` | `2026-05-13T14:13:16.096Z` |
| `add_repo_existing_workspaces_detected` | `2026-05-20T05:33:20.160Z` |
| `setup_script_prompt_shown` | `2026-05-21T04:09:04.231Z` |
| `setup_script_prompt_action` | `2026-05-21T04:10:31.616Z` |
| Event | First seen with `nth_repo_added` |
| --------------------------------------- | ------------------------------------------ |
| `app_opened` | `2026-05-08T18:40:00.354Z` (`1.3.42-rc.1`) |
| `workspace_created` | `2026-05-08T19:15:06.913Z` |
| `agent_started` | `2026-05-08T19:15:07.130Z` |
| `agent_prompt_sent` | `TBD` |
| `repo_added` | `2026-05-08T20:01:06.364Z` (`1.3.42`) |
| `add_repo_setup_step_action` | `2026-05-08T20:01:20.897Z` |
| `workspace_create_failed` | `2026-05-08T23:04:32.315Z` |
| `agent_error` | `2026-05-13T14:13:16.096Z` |
| `add_repo_existing_workspaces_detected` | `2026-05-20T05:33:20.160Z` |
| `setup_script_prompt_shown` | `2026-05-21T04:09:04.231Z` |
| `setup_script_prompt_action` | `2026-05-21T04:10:31.616Z` |
Dashboard caveats:
@ -87,26 +87,26 @@ Scope: `cohort` on onboarding events. Current schemas declare it on `onboarding_
The original `#1608` rollout covered `onboarding_started`, `onboarding_step_viewed`, `onboarding_step_completed`, `onboarding_step_skipped`, `onboarding_step4_path_clicked`, `onboarding_step4_path_failed`, `onboarding_completed`, `onboarding_dismissed`, `onboarding_agent_picked`, and onboarding import events. Later onboarding events joined the roster by declaring `cohort` in their schemas.
| Field | Value |
| --- | --- |
| PR | `#1608` |
| Merge commit | `318e2b4c2c501b50280dc9e5b11ed34bd899bdd9` |
| `code_merged_at_utc` | `2026-05-09T02:57:18Z` |
| First release | `v1.3.44` |
| First release commit | `e602decf1d35dc54c84eea516fc2b9afdc065cce` |
| `first_released_at_utc` | `2026-05-09T08:05:39Z` |
| Earliest `first_seen_at_utc` | `2026-05-09T09:54:03.038Z` on `onboarding_started { cohort: 'fresh_install' }` (`1.3.45`) |
| `dashboard_ready_at_utc` | `2026-05-09T09:54:03.038Z` for fresh-install onboarding-start cohorts; use later event-specific first-seen timestamps where a tile requires another event. |
| Field | Value |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| PR | `#1608` |
| Merge commit | `318e2b4c2c501b50280dc9e5b11ed34bd899bdd9` |
| `code_merged_at_utc` | `2026-05-09T02:57:18Z` |
| First release | `v1.3.44` |
| First release commit | `e602decf1d35dc54c84eea516fc2b9afdc065cce` |
| `first_released_at_utc` | `2026-05-09T08:05:39Z` |
| Earliest `first_seen_at_utc` | `2026-05-09T09:54:03.038Z` on `onboarding_started { cohort: 'fresh_install' }` (`1.3.45`) |
| `dashboard_ready_at_utc` | `2026-05-09T09:54:03.038Z` for fresh-install onboarding-start cohorts; use later event-specific first-seen timestamps where a tile requires another event. |
Later onboarding cohort events:
| Event | PR | First release | `first_seen_at_utc` |
| --- | --- | --- | --- |
| `onboarding_feature_setup_run` | `#1853` (`2e5ac1c8ebdc93f6281622d9e4ef60ab14c71096`) | `v1.4.2-rc.1` at `2026-05-14T22:23:46Z` | `2026-05-15T05:55:37.248Z` (`1.4.2-rc.4`) |
| `onboarding_feature_setup_terminal_opened` | `#1853` (`2e5ac1c8ebdc93f6281622d9e4ef60ab14c71096`) | `v1.4.2-rc.1` at `2026-05-14T22:23:46Z` | `2026-05-15T05:55:37.261Z` (`1.4.2-rc.4`) |
| Event | PR | First release | `first_seen_at_utc` |
| ---------------------------------------------- | ---------------------------------------------------- | --------------------------------------- | ----------------------------------------- |
| `onboarding_feature_setup_run` | `#1853` (`2e5ac1c8ebdc93f6281622d9e4ef60ab14c71096`) | `v1.4.2-rc.1` at `2026-05-14T22:23:46Z` | `2026-05-15T05:55:37.248Z` (`1.4.2-rc.4`) |
| `onboarding_feature_setup_terminal_opened` | `#1853` (`2e5ac1c8ebdc93f6281622d9e4ef60ab14c71096`) | `v1.4.2-rc.1` at `2026-05-14T22:23:46Z` | `2026-05-15T05:55:37.261Z` (`1.4.2-rc.4`) |
| `onboarding_feature_setup_terminal_interacted` | `#1853` (`2e5ac1c8ebdc93f6281622d9e4ef60ab14c71096`) | `v1.4.2-rc.1` at `2026-05-14T22:23:46Z` | `2026-05-15T11:47:28.022Z` (`1.4.2-rc.6`) |
| `onboarding_feature_setup_toggled` | `#1853` (`2e5ac1c8ebdc93f6281622d9e4ef60ab14c71096`) | `v1.4.2-rc.1` at `2026-05-14T22:23:46Z` | `2026-05-17T03:03:54.535Z` (`1.4.3`) |
| `onboarding_task_sources_snapshot` | `#2275` (`ececd27fd8203a7acb3e430fa016fb4653aaa93c`) | `v1.4.7-rc.1` at `2026-05-19T00:47:11Z` | `2026-05-19T04:18:23.872Z` (`1.4.7`) |
| `onboarding_feature_setup_toggled` | `#1853` (`2e5ac1c8ebdc93f6281622d9e4ef60ab14c71096`) | `v1.4.2-rc.1` at `2026-05-14T22:23:46Z` | `2026-05-17T03:03:54.535Z` (`1.4.3`) |
| `onboarding_task_sources_snapshot` | `#2275` (`ececd27fd8203a7acb3e430fa016fb4653aaa93c`) | `v1.4.7-rc.1` at `2026-05-19T00:47:11Z` | `2026-05-19T04:18:23.872Z` (`1.4.7`) |
Dashboard caveats:
@ -121,26 +121,26 @@ Dashboard caveats:
Scope: first feature-wall tour event family before the inline onboarding tour. This added base open/close and tile activity telemetry. Historical `feature_wall_closed` rows from this rollout have `dwell_ms`; the source/depth fields needed for tour cohort retention only arrive in the later tour telemetry rollout.
| Field | Value |
| --- | --- |
| PR | `#1772` |
| Merge commit | `fdf7d9e97a46f27b3667d9bae6c8aca5d11345d8` |
| `code_merged_at_utc` | `2026-05-14T22:20:50Z` |
| First release | `v1.4.2-rc.1` |
| First release commit | `c66e9801fe5f159cac23564ec7c028957973692a` |
| `first_released_at_utc` | `2026-05-14T22:23:46Z` |
| `first_seen_at_utc` | `2026-05-15T06:15:30.263Z` on `feature_wall_opened { source: 'popup' }` (`1.4.2-rc.4`) |
| Field | Value |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| PR | `#1772` |
| Merge commit | `fdf7d9e97a46f27b3667d9bae6c8aca5d11345d8` |
| `code_merged_at_utc` | `2026-05-14T22:20:50Z` |
| First release | `v1.4.2-rc.1` |
| First release commit | `c66e9801fe5f159cac23564ec7c028957973692a` |
| `first_released_at_utc` | `2026-05-14T22:23:46Z` |
| `first_seen_at_utc` | `2026-05-15T06:15:30.263Z` on `feature_wall_opened { source: 'popup' }` (`1.4.2-rc.4`) |
| `dashboard_ready_at_utc` | Event-dependent. Useful for base feature-wall usage after first-seen rows, not for inline-tour cohort retention. |
PostHog evidence checked at `2026-05-23T23:34:32Z`:
| Event/property | `first_seen_at_utc` |
| --- | --- |
| `feature_wall_opened { source: 'popup' }` | `2026-05-15T06:15:30.263Z` (`1.4.2-rc.4`) |
| `feature_wall_tile_focused` | `2026-05-15T06:15:31.073Z` (`1.4.2-rc.4`) |
| `feature_wall_closed` with legacy `dwell_ms` only | `2026-05-15T06:18:22.677Z` |
| `feature_wall_tile_clicked` | `2026-05-17T04:35:04.142Z` (`1.4.3`) |
| `feature_wall_opened { source: 'help_menu' }` | `2026-05-17T07:02:23.278Z` (`1.4.3`) |
| Event/property | `first_seen_at_utc` |
| ------------------------------------------------- | ----------------------------------------- |
| `feature_wall_opened { source: 'popup' }` | `2026-05-15T06:15:30.263Z` (`1.4.2-rc.4`) |
| `feature_wall_tile_focused` | `2026-05-15T06:15:31.073Z` (`1.4.2-rc.4`) |
| `feature_wall_closed` with legacy `dwell_ms` only | `2026-05-15T06:18:22.677Z` |
| `feature_wall_tile_clicked` | `2026-05-17T04:35:04.142Z` (`1.4.3`) |
| `feature_wall_opened { source: 'help_menu' }` | `2026-05-17T07:02:23.278Z` (`1.4.3`) |
Dashboard caveats:
@ -151,16 +151,16 @@ Dashboard caveats:
Scope: optional "Explore Orca" tour during onboarding and the Help menu entry point. This shipped the product surface, not the full retention cohort instrumentation. It also added `source = 'onboarding'` to the feature-wall open source enum and added feature-wall group/feature/docs click events with source.
| Field | Value |
| --- | --- |
| PR | `#2652` |
| Merge commit | `669ade23133b9905fff1b6ed22755ee2911ea517` |
| `code_merged_at_utc` | `2026-05-23T19:21:14Z` |
| First release | `v1.4.23-rc.0` |
| First release commit | `1f1171e0dee5d0fbf969de56845882bf8deb9037` |
| `first_released_at_utc` | `2026-05-23T20:14:38Z` |
| First app version observed | `1.4.23-rc.0` at `2026-05-23T20:54:12.343Z` |
| `dashboard_ready_at_utc` | `TBD`; do not use this surface-only rollout for tour cohort retention tiles. |
| Field | Value |
| -------------------------- | ---------------------------------------------------------------------------- |
| PR | `#2652` |
| Merge commit | `669ade23133b9905fff1b6ed22755ee2911ea517` |
| `code_merged_at_utc` | `2026-05-23T19:21:14Z` |
| First release | `v1.4.23-rc.0` |
| First release commit | `1f1171e0dee5d0fbf969de56845882bf8deb9037` |
| `first_released_at_utc` | `2026-05-23T20:14:38Z` |
| First app version observed | `1.4.23-rc.0` at `2026-05-23T20:54:12.343Z` |
| `dashboard_ready_at_utc` | `TBD`; do not use this surface-only rollout for tour cohort retention tiles. |
Dashboard caveats:
@ -179,32 +179,32 @@ Added/changed signals:
- `feature_wall_closed` optional `source`, `exit_action`, `furthest_step`, `last_group_id`, and bounded visited/completed depth counts.
- `feature_wall_opened { source: 'onboarding' }` through the inline tour surface.
| Field | Value |
| --- | --- |
| PR | `#2713` |
| Branch commit | `9115143927dce38547545a07e58b85d17796fd7a` |
| Merge commit | `b9c55bb07127f799528761ec31d7e2b7f8598c07` |
| `code_merged_at_utc` | `2026-05-23T21:15:11Z` |
| First release | `v1.4.23-rc.1` |
| First release commit | `c74765922e770c6540496735a5a2be838457256a` |
| `first_released_at_utc` | `2026-05-23T21:16:38Z` |
| `first_seen_at_utc` | `TBD` |
| `dashboard_ready_at_utc` | `TBD` |
| Field | Value |
| ------------------------ | ------------------------------------------ |
| PR | `#2713` |
| Branch commit | `9115143927dce38547545a07e58b85d17796fd7a` |
| Merge commit | `b9c55bb07127f799528761ec31d7e2b7f8598c07` |
| `code_merged_at_utc` | `2026-05-23T21:15:11Z` |
| First release | `v1.4.23-rc.1` |
| First release commit | `c74765922e770c6540496735a5a2be838457256a` |
| `first_released_at_utc` | `2026-05-23T21:16:38Z` |
| `first_seen_at_utc` | `TBD` |
| `dashboard_ready_at_utc` | `TBD` |
Required readiness signals:
| Signal | `first_seen_at_utc` |
| --- | --- |
| `onboarding_tour_outcome` with valid `outcome` and joinable fresh-install start | `TBD` |
| `onboarding_step_viewed { value_kind: 'tour' }` | `TBD` |
| `feature_wall_closed` with non-null `source`, `exit_action`, and expected depth fields | `TBD` |
| Signal | `first_seen_at_utc` |
| -------------------------------------------------------------------------------------- | ------------------- |
| `onboarding_tour_outcome` with valid `outcome` and joinable fresh-install start | `TBD` |
| `onboarding_step_viewed { value_kind: 'tour' }` | `TBD` |
| `feature_wall_closed` with non-null `source`, `exit_action`, and expected depth fields | `TBD` |
QA/opportunistic signals:
| Signal | `first_seen_at_utc` |
| --- | --- |
| Signal | `first_seen_at_utc` |
| ------------------------------------------------ | --------------------------------------------------------------- |
| `onboarding_step_skipped { value_kind: 'tour' }` | `TBD`; do not gate dashboard readiness on natural skip traffic. |
| `feature_wall_opened { source: 'onboarding' }` | `TBD`; surface availability only. |
| `feature_wall_opened { source: 'onboarding' }` | `TBD`; surface availability only. |
PostHog evidence checked at `2026-05-23T23:34:32Z`:

View File

@ -1,3 +1,4 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"rules": {}
}

View File

@ -52,8 +52,8 @@
"@types/react-native": "^0.73.0",
"@types/ws": "^8.18.1",
"expo-module-scripts": "^55.0.2",
"oxfmt": "^0.47.0",
"oxlint": "^1.63.0",
"oxfmt": "^0.52.0",
"oxlint": "^1.67.0",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"vitest": "^4.1.5"

View File

@ -121,11 +121,11 @@ importers:
specifier: ^55.0.2
version: 55.0.2(@babel/core@7.29.0)(@babel/runtime@7.29.2)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(esbuild@0.27.7)(eslint@9.39.4)(expo@55.0.23)(jest@29.7.0(@types/node@25.8.0))(prettier@2.8.8)(react-native@0.83.9(@babel/core@7.29.0)(@react-native/metro-config@0.85.2(@babel/core@7.29.0))(@types/react@19.2.14)(react@19.2.6))(react-refresh@0.14.2)(react-test-renderer@19.2.0(react@19.2.6))(react@19.2.6)
oxfmt:
specifier: ^0.47.0
version: 0.47.0
specifier: ^0.52.0
version: 0.52.0
oxlint:
specifier: ^1.63.0
version: 1.63.0
specifier: ^1.67.0
version: 1.67.0
tsx:
specifier: ^4.21.0
version: 4.21.0
@ -1374,230 +1374,246 @@ packages:
'@oxc-project/types@0.129.0':
resolution: {integrity: sha512-3oz8m3FGdr2nDXVqmFUw7jolKliC4MoyXYIG2c7gpjBnzUWQpUGIYcXYKxTdTi+N2jusvt610ckTMkxdwHkYEg==}
'@oxfmt/binding-android-arm-eabi@0.47.0':
resolution: {integrity: sha512-KrMQRdMi/upr81qT4ijK6X6BNp6jqpMY7FwILQnwIy9QLc3qpnhUx5rsCLGzn4ewsCQ0CNAspN2ogmP1GXLyLw==}
'@oxfmt/binding-android-arm-eabi@0.52.0':
resolution: {integrity: sha512-17EMSJnQ9g+upVHrAUYDMfH5lvRKQ9Nvg8WtEoH72oDr1VpWz+7/o3tD97U1EToen2YAQ/68JmtDYkQUi20dfQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@oxfmt/binding-android-arm64@0.47.0':
resolution: {integrity: sha512-r4ixS/PeUpAFKgrpDoZ5pSkthjZzVzKd95525Aazj+aOv9H4ulK5zYHGb7wFY5n5kZxHK8TbOJUZgoEb1ohddQ==}
'@oxfmt/binding-android-arm64@0.52.0':
resolution: {integrity: sha512-A2G1IdwGEW2lLJkIxcvuirRH1CzSl/e0NX11zTlW1gvxJThfwbI/BEoaKrTNpm7M2FchvIf6guvIQU7d5iz+OQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@oxfmt/binding-darwin-arm64@0.47.0':
resolution: {integrity: sha512-CLWxiKpMl+195cm09CuaWEhJK0CirRkoMa07aR9+9AFPat2LfIKtwx1JqxZM0MTvcMe6+adlJNdVL6jdInvq3g==}
'@oxfmt/binding-darwin-arm64@0.52.0':
resolution: {integrity: sha512-f9+bLvOYxy7NttCLFTvQ7afmqDOWY4wIP9xdvfj5trQ1qj6f2UFAGwZESlfsMjvJNTyRpXfIlOanCI9FOvoeQA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@oxfmt/binding-darwin-x64@0.47.0':
resolution: {integrity: sha512-Xq5fjTYDC50faUeLSm0rZdBqoTgleXEdD7NpJdARtQIczkCJn3xNjMUSQQkUmh4CtxkKTNL68lytcOK3e/osgg==}
'@oxfmt/binding-darwin-x64@0.52.0':
resolution: {integrity: sha512-YSTB9sJ5nnQd/Q0ddHkgof0ZCHPAnWZT1IW2SJ8omz7CP7KluJhO1fNHrpqdxCtpztJwSs4hY1uAee35wKxxaw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@oxfmt/binding-freebsd-x64@0.47.0':
resolution: {integrity: sha512-QOU9ZIJ52p5askcEC0QJvvr8trHAWoonul8bgISo6gYUL3s50zkqafBYcNAr9LJZQbsZtPfIWHk9+5+nUp1qJQ==}
'@oxfmt/binding-freebsd-x64@0.52.0':
resolution: {integrity: sha512-NIrRNTTPCs4UbmVs0bxLSCDlLCtIRMJIXklNKaXa5Oj2/K1UIMBvgE8+uPVo01Io3N9HF0+GAX+aAHjUgZS7vA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@oxfmt/binding-linux-arm-gnueabihf@0.47.0':
resolution: {integrity: sha512-oJxDM1aBhPvz9gmElBv8UpxyiqhwfjcbrSxT5F0xtuUzY6dQI27/AQPIt3eu3Z5Yvn0kQl5R7MA3Z+MbnRvCBw==}
'@oxfmt/binding-linux-arm-gnueabihf@0.52.0':
resolution: {integrity: sha512-JXUCde8mn3GpgQouz2PXUokgy/uT1QrRJBL2s983VWcSQp62wTFYiNXgTKdeo1Jgbr0IgUnKKvzIk/YBlj/nVQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxfmt/binding-linux-arm-musleabihf@0.47.0':
resolution: {integrity: sha512-g8Lh50VS4ibGz2q6v7r9UZY4D0dM16SdrFYOMzhqIoCwGcai8VMIRUAcqn1/jlCsOOzUXJ741+kCeJt0cofakQ==}
'@oxfmt/binding-linux-arm-musleabihf@0.52.0':
resolution: {integrity: sha512-psbUXaRZ+V8DaXz10Qf7LSHtdtdKAmC8fxXgeU608jjzrmWK4quamZMOpl6sf+dikoFHA85uE93Q0BqxrCdQrQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxfmt/binding-linux-arm64-gnu@0.47.0':
resolution: {integrity: sha512-YrNT1vQ0asaXoRbrvYENPqmBfOQ9Xr8enPNOULeYfg44VjCcrUowFy5QZr+WawE0zyP8cH9e9Gxxg0fDEFzhcg==}
'@oxfmt/binding-linux-arm64-gnu@0.52.0':
resolution: {integrity: sha512-Jw7MgWUU9lcLCcy82updISP3EthTlfvAwR6gWNxPzqly7+fLvOi2gHQE9xXQjpqaVLm/8P+gOzlv9ODuoVlaaw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-arm64-musl@0.47.0':
resolution: {integrity: sha512-IxtQC/sbBi4ubbY+MdwdanRWrG9InQJVZqyMsBa5IUaQcnSg86gQme574HxXMC1p4bo4YhV99zQ+wNnGCvEgzw==}
'@oxfmt/binding-linux-arm64-musl@0.52.0':
resolution: {integrity: sha512-wZg6bLjDvh2KibyI3QFUYo8GTXneIFsd0JvehtvJiUmQ8WRPERgxd/VM4ctWb86U5FT1FkqgS8/wZKVB+AZScg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxfmt/binding-linux-ppc64-gnu@0.47.0':
resolution: {integrity: sha512-EWXEhOMbWO0q6eJSbu0QLkU8cKi0ljlYLngeDs2Ocu/pm1rrLwyQiYzlFbdnMRURI4w9ndr1sI9rSbhlJ5o23Q==}
'@oxfmt/binding-linux-ppc64-gnu@0.52.0':
resolution: {integrity: sha512-IngE8uxhNvxcMrLjZNDo9xNLY7rEK33AKnaMd2B46he1e/mz2CfcW6If/U1wUjdRZddm1QzQaciqZkuMkdh1FA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-riscv64-gnu@0.47.0':
resolution: {integrity: sha512-tZrjS11TUiDuEpRaqdk8K9F9xETRyKXfuZKmdeW+Gj7coBnm7+8sBEfyt033EAFEQSlkniAXvBLh+Qja2ioGBQ==}
'@oxfmt/binding-linux-riscv64-gnu@0.52.0':
resolution: {integrity: sha512-H3+DdFMv/efN3Efmhsv18jDrpiWWqKG7wsfAlQBqAt6z/E2Bx+TwEj2Nowe51CPOWB8/mFBC2dAMSgVFLvvowA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-riscv64-musl@0.47.0':
resolution: {integrity: sha512-KBFy+2CFKUCZzYwX2ZOPQKck1vjQbz+hextuc19G4r0WRJwadfAeuQMQRQvB+Ivc8brlbOVg7et8K7E467440g==}
'@oxfmt/binding-linux-riscv64-musl@0.52.0':
resolution: {integrity: sha512-zji+1kb7lJKohSDjzC1IsS+K/cKRs1hdVf0ZH0VbdbiakmtLvN9twBoXo/k8VdjFax7kfo+DyPxS7vv52br1aw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxfmt/binding-linux-s390x-gnu@0.47.0':
resolution: {integrity: sha512-REUPFKVGSiK99B+9eaPhluEVglzaoj/SMykNC5SUiV2RSsBfV5lWN7Y0iCIc251Wz3GaeAGZsJ/zj3gjarxdFg==}
'@oxfmt/binding-linux-s390x-gnu@0.52.0':
resolution: {integrity: sha512-hcLBYedpCy7ToUvvBidWk7+11Yhg1oAZ4+6hKPic/mQI6NaqXJSXMps5nFlwUuX2ewhtLZZDPg63TI042qGKBg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-x64-gnu@0.47.0':
resolution: {integrity: sha512-KVftVSVEDeIfRW3TIeLe3aNI/iY4m1fu5mDwHcisKMZSCMKLkrhFsjowC7o9RoqNPxbbglm2+/6KAKBIts2t0Q==}
'@oxfmt/binding-linux-x64-gnu@0.52.0':
resolution: {integrity: sha512-IDO2loXK2OtTOhSPchU9MW25mWL2QCDGdJbjN8MXKZVS80qXe5gMTwQWu/gMJ3juoBHbkuUZNB2N1LHzNT7DoA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-x64-musl@0.47.0':
resolution: {integrity: sha512-DTsmGEaA2860Aq5VUyDO8/MT9NFxwVL93RnRYmpMwK6DsSkThmvEpqoUDDljziEpAedMRG19SCogrNbINSbLUQ==}
'@oxfmt/binding-linux-x64-musl@0.52.0':
resolution: {integrity: sha512-mAV2Hjn0SatJ+KoAzKUC3eJhdJ8wv+3m1KyuS0dTsbF0c5weq+QrCt/DRZZM+uj/XiKzCDEUKYsBF30e2qkcyw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxfmt/binding-openharmony-arm64@0.47.0':
resolution: {integrity: sha512-8r5BDro7fLOBoq1JXHLVSs55OlrxQhEso4HVo0TcY7OXJUPYfjPoOaYL5us+yIwqyP9rQwN+rxuiNFSmaxSuOQ==}
'@oxfmt/binding-openharmony-arm64@0.52.0':
resolution: {integrity: sha512-vd4npaUIwChxp7XzkqmepBWTT9YMcSe/NBApVGPC30/lLyOVaV3dvma1SKo03t8O73BPRAG7EyJzGlN5cJM5hQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@oxfmt/binding-win32-arm64-msvc@0.47.0':
resolution: {integrity: sha512-qtz/gzm8IjSPUlseZ0ofW8zyHLoZsuP5HTfcGGkWkUblB89JT8GNYH3ICqjbDsqsGqXum0/ZndXTFplSdXFIcg==}
'@oxfmt/binding-win32-arm64-msvc@0.52.0':
resolution: {integrity: sha512-k2sz6gWQdMfh5HPpIS+Bw/0UEV/kaK2xuqJRrWL233sEHx9WLlsmvlPFM4HUNThkYbSN0U0vPW7LVKZWDS8hPQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@oxfmt/binding-win32-ia32-msvc@0.47.0':
resolution: {integrity: sha512-5vIcdcIDE7nCx+MXN6sm8kbC4zajDB31E86rez4i45iHNH/2NjdKlJ720xcHTr3eeiMcttCGPHPhE1TjtBDGZw==}
'@oxfmt/binding-win32-ia32-msvc@0.52.0':
resolution: {integrity: sha512-rhke69GTcArodLHpjMTfNnvjTEBryDeZcUCKK/VjXDMtfTULl6QRh0ymX5/hbCUv2WjYm9h/QbW++q2vE15gWQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@oxfmt/binding-win32-x64-msvc@0.47.0':
resolution: {integrity: sha512-Sr59Y5ms54ONBjxFeWhVlGyQcHXxcl9DxC23f6yXlRkcos7LXBLoO+KDfxexjHIOZh7cWqrWduzvUjJ+pHp8cQ==}
'@oxfmt/binding-win32-x64-msvc@0.52.0':
resolution: {integrity: sha512-q5xL7oeXkZdEtNZWBdvehJcmt+GRu9l2bK40yJs1jJXlqq+r0Hygb1rTjq+FM2o/2xyt4cufH6KRplHp3Jjsvw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
'@oxlint/binding-android-arm-eabi@1.63.0':
resolution: {integrity: sha512-A9xLtQt7i0OA1PoB/meog6kikXI9CdwEp7ZwQqmgnpKn3G3b1orvTDy8CQ6T7w1HvDrgWGB78PkFKcWgibcTCg==}
'@oxlint/binding-android-arm-eabi@1.67.0':
resolution: {integrity: sha512-VrSi571rDv1N8HaEDM+DEX8nmT0y9jJo8tzzW13vsOWTx59xQczCIJx68n2zWOXRT5YKZsOZXp4qkHN/10x4mw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@oxlint/binding-android-arm64@1.63.0':
resolution: {integrity: sha512-SQo+ZMvdR9l3CxZp5W5gFNxSiDxclY6lOzzNpKYLF8asESpm3Pwumx0gER5T7aHLF1/2BAAtLD3DiDkdgy4V1A==}
'@oxlint/binding-android-arm64@1.67.0':
resolution: {integrity: sha512-l6+NdYxMoRohix5r5bbigW16LPicceCwGcQ6LKKuE1kUdjgFfQolJjrJsQYPFetIs78Gxj/G/f5TEGoTCwj9nQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@oxlint/binding-darwin-arm64@1.63.0':
resolution: {integrity: sha512-6W82XjJDTmMnjg30427l0dufpnyLoq7wEukKdM6/g2VIybRVuQiBVh43EA4b+UxZ3+tLcKm+Or/pXGNgLCEU8g==}
'@oxlint/binding-darwin-arm64@1.67.0':
resolution: {integrity: sha512-jOzXxS1AxFxhImLIRbtGIMrEwaXcgMw3gR57WB1cRk8ai+vpr6726kxXqVvlNsrXtJ/FrmOm8RxlC0m8SW24Qg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@oxlint/binding-darwin-x64@1.63.0':
resolution: {integrity: sha512-CnWd/YCuVG5W1BYkjJEVbJG11o526O9qAwBEQM+nh8K19CRFUkFdROXCyYkGmroHEYQe4vgQ6+lh3550Lp35Xw==}
'@oxlint/binding-darwin-x64@1.67.0':
resolution: {integrity: sha512-3DFAVY94OqjIZHXIPz37yGRSWwOFTAqChQ64/M69GYLawzP0KiwdhDNfqdKKYT0bTR/DNxmMnQsj3ns+8+X/Lg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@oxlint/binding-freebsd-x64@1.63.0':
resolution: {integrity: sha512-a4eZAqrmtajqcxfdAzC+l7g3PaE3V8hpAYqqeD3fTxLXOMFdK3eNTZrU80n4dDEVm0JXy1aL5PqvqWldBl6zYA==}
'@oxlint/binding-freebsd-x64@1.67.0':
resolution: {integrity: sha512-e4dDKZuLu8TR9DEBssWSDahlPgZBwojTTHZUvnjBRJfJJbpxYCjfjKfi0Z1+CSLMiJBwI2yCDtRM1XJQaARjmg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@oxlint/binding-linux-arm-gnueabihf@1.63.0':
resolution: {integrity: sha512-tYUtU9TdbU3uXF5D62g5zXJ13iniFGhXQx5vp9cyEjGdbSAY3VdFBSaldYvyoDmgMZ0ZYuwQP1Y4t2Fhejwa0w==}
'@oxlint/binding-linux-arm-gnueabihf@1.67.0':
resolution: {integrity: sha512-BKytFdcQzbITV3xlnzDUDTEDtbUMCCiC4EaNTDZ4FyT8gdNvBC4gfiLucXp/sQl0XU3p7syTlorUWVVVBZab2g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxlint/binding-linux-arm-musleabihf@1.63.0':
resolution: {integrity: sha512-I5r3twFf776UZg9dmRo2xbrKt00tTkORXEVe0ctg4vdTkQvJAjiCHxnbAU2HL1AiJ9cqADA76MAliuilsAWnvg==}
'@oxlint/binding-linux-arm-musleabihf@1.67.0':
resolution: {integrity: sha512-XYAv0esBDX7BpTzRDjVX2Vdj+zndd8ll2dFQiaeQ6zTZr7A8GRDTN7fH3FP3jU+O0vCDx85oH/EtG7BzPgAXuw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxlint/binding-linux-arm64-gnu@1.63.0':
resolution: {integrity: sha512-t7ltUkg6FFh4b564QyGir8xIj/QZbXu8FlcRkcyW9+ztr/mfRHlvUOFd95pJCXi9s/L5DrUeWWgpXRS+V+6igQ==}
'@oxlint/binding-linux-arm64-gnu@1.67.0':
resolution: {integrity: sha512-zizRMjA0i6u/2B0evgda04iycu+MoNuf1pBy6Eh+1CjC5wMEG7qN5zdDKTCvFc0KSYSDM9QTG3gjZHirgtQuKg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-arm64-musl@1.63.0':
resolution: {integrity: sha512-Q5mmZy/XWjuYFUuQyYjOvZ5U/JkKEwnpir6hGxhh6HcdP0V/BKxLo8dqkfF/t7r7AguB17dfS/8+go5AQDRR6g==}
'@oxlint/binding-linux-arm64-musl@1.67.0':
resolution: {integrity: sha512-zB/Tf6sUjmmvvbva9Gj3JTJ8rJ9t4I8/U0o6vSRtd0DRIsIuyegBwJAzhSUFQHdMijIRJkW0exs/yBhpw2S20w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxlint/binding-linux-ppc64-gnu@1.63.0':
resolution: {integrity: sha512-uBGtuZ0TzLB4x5wVa82HGNvYqY8buwDhyCnCP0R0gkk9szqVsP0MeTtD5HX7EsEuFIt+aYmYxuxeVxs3nTSwtQ==}
'@oxlint/binding-linux-ppc64-gnu@1.67.0':
resolution: {integrity: sha512-kgU40Gt74CK0TCsF51KZymkIwN9U0BajKsMijB52zPqOeZU9NAHkA/NSQkZDHEaCakx42DxhXkODiAqf2b4Gug==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-riscv64-gnu@1.63.0':
resolution: {integrity: sha512-h4s6FwxE+9MeA181o0dnDwHP32Y/bG8EiB/vrD6Ib+AMt6haigDc/0bUtI/sLmQDBMJnUfaCmtSSrEAqjtEVrA==}
'@oxlint/binding-linux-riscv64-gnu@1.67.0':
resolution: {integrity: sha512-tOYhkk/iaG9aD3FvGpBFd1Lrw0x0RaVoJBxjUkfNzS50rC5NS5BteNCwgr8A2zCdADrIIoze6D7u6U5Ic++/iQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-riscv64-musl@1.63.0':
resolution: {integrity: sha512-2EaNcCBR8Mcjl5ARtuN3BdEpVkX7KpjSjMGZ/mJMIeaXgTtdz5ytg2VwygMSStA/k0ixfvZFoZOfjDEcouV5vQ==}
'@oxlint/binding-linux-riscv64-musl@1.67.0':
resolution: {integrity: sha512-sEtywrPb+0b+tHYl1SDCrw903fiC4eyKoNqzP3v+f2JT3Xcv4NEYG+P8rj+eEnX7IWhqV/xj8/JmcmVj21CXaA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxlint/binding-linux-s390x-gnu@1.63.0':
resolution: {integrity: sha512-p4hlf/fd7TrYYl3QrWWD0GocqJefwMu3cHQhmi2FvEB/YOvFb5DZN3SMBaPi7B1TM5DeypkEtrVib674q1KKPg==}
'@oxlint/binding-linux-s390x-gnu@1.67.0':
resolution: {integrity: sha512-BvR8Moa0zCLxroOx4vZaZN9nUfwAUpSTwjZdxZyKy4bv3PrzrXrxKR/ZQ0L9wNSvlPhnMJeZfa3q5w6ZCTuN6Q==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-x64-gnu@1.63.0':
resolution: {integrity: sha512-Vgq9rkRVcPcjbcH+ihYTfpeR7vCXfqpd+z5ItTGc0yYUV59L5ceHYN1iV4H9bKGV7Rn5hkVc7x3mSvHegduENA==}
'@oxlint/binding-linux-x64-gnu@1.67.0':
resolution: {integrity: sha512-mm2cxM6fksOpq6l0uFws8BUGKAR4dNa/cZCn37Npq7PFbhD5HDJqWfnoIvTaeRKMy5XdS2tO0MA0qbHDrnXAAA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-x64-musl@1.63.0':
resolution: {integrity: sha512-3/Lkq/ncooA61rorrC+ZQed1Bc4VpGj+WnGsp58zmxKgvZ2vhreu+dcVyr3mX8NUpq7mfZ4gDDTou/yrF1Pd7A==}
'@oxlint/binding-linux-x64-musl@1.67.0':
resolution: {integrity: sha512-WmbMuLapKyDlobMkXAaAL0Y+Uczh4LETfIfQsUpbId4Ip8Ai82/jqeYTOoUCkuuhBFapgqP253+d83tLKOksJg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxlint/binding-openharmony-arm64@1.63.0':
resolution: {integrity: sha512-0/EdD/6hDkx5Mfd769PTjvEM8mZ/6Dfukp1dBCL/2PjlIVGEtYdNZyok6ChqYPsT9JcFnlQnUeQzO0/1L/oC9w==}
'@oxlint/binding-openharmony-arm64@1.67.0':
resolution: {integrity: sha512-9g/PqxYJelzzTAOR5Y+RiRqdeydhEuXv2KxNeFcAKQ7UsvnWSY1OP4MsuPMbTO2Pf70tz7mFhl1j13H3fyh+8g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@oxlint/binding-win32-arm64-msvc@1.63.0':
resolution: {integrity: sha512-wb0CUkN8ngwPiRQBjD1Cj0LsHeNvm+Xt6YBHDMtj2DVQVD6Oj8Ri7g6BD+KICf6LaBqZlmzOvy6nF9E/8yyGOg==}
'@oxlint/binding-win32-arm64-msvc@1.67.0':
resolution: {integrity: sha512-2VhwE6Gatb0vJGnN0TBuQMbKCOiZlSQ/zJvVWYLK4a9d4iDiJOen/yVQkGpmsJ90MuH66fzi0kEKI0jRQMDxGA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@oxlint/binding-win32-ia32-msvc@1.63.0':
resolution: {integrity: sha512-BX5iq+ovdNlVYhSn5qPMUIT0uwAwt2lmEnCnzK+Gkhw4DovIvhGb96OFhV8yzQNUnQxn/xGkOR+X+BLrLDNm8w==}
'@oxlint/binding-win32-ia32-msvc@1.67.0':
resolution: {integrity: sha512-EQ3VExXfeM1InbE5+JjufhZZTWy+kHUwgt3yZR7gQ47Je/mE0WspQPan0OJznh493L5anM210YNJtH1PXjTSFg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@oxlint/binding-win32-x64-msvc@1.63.0':
resolution: {integrity: sha512-QeN/WELOfsXMeYwxvfgQrl6CbVftYUCZsGXHjXQd5Trccm8+i4gmtxaOui4xbJQaiDlviF8F3yLSBloQUeFsfA==}
'@oxlint/binding-win32-x64-msvc@1.67.0':
resolution: {integrity: sha512-bw24y+/1MHS4QDkons3YyHkPT9uCMoLHHgQhb+mb8NOjTYwub1CZ+K9Ngr8aO5DMrDrkqHwTzlTwFP2vS8Y/ZQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
@ -4721,20 +4737,31 @@ packages:
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
engines: {node: '>= 0.4'}
oxfmt@0.47.0:
resolution: {integrity: sha512-OFbkbzxKCpooQEnRmpTDnuwTX8KHXzZTQ4Df/hz85fpS67Pl+lxPEFvUtin56HIIS0B1k4X8oIzTXRZPufA2CA==}
oxfmt@0.52.0:
resolution: {integrity: sha512-nJlYM35F64zTDMecCNhoHNkf+D/eHv7xcjj9XDSj+bFAVtN93m7v8DQMdHd6nDG6Akf/kEYYHmDUBs2Dz27Sug==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
svelte: ^5.0.0
vite-plus: '*'
peerDependenciesMeta:
svelte:
optional: true
vite-plus:
optional: true
oxlint@1.63.0:
resolution: {integrity: sha512-9TGXetdjgIHOJ9OiReomP7nnrMkV9HxC1xM2ramJSLQpzxjsAJtQwa4wqkJN2f/uCrqZuJseFuSlWDdvcruveg==}
oxlint@1.67.0:
resolution: {integrity: sha512-blwwaHPdoH8piQ5/z0KHeoHFR7FZgl12WluKJfu4qFLPkZl6mK04PkLE45Fw1NxfBRSlh40Gu7MkxHUw++ociQ==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
oxlint-tsgolint: '>=0.22.1'
vite-plus: '*'
peerDependenciesMeta:
oxlint-tsgolint:
optional: true
vite-plus:
optional: true
p-limit@2.3.0:
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
@ -7638,118 +7665,118 @@ snapshots:
'@oxc-project/types@0.129.0': {}
'@oxfmt/binding-android-arm-eabi@0.47.0':
'@oxfmt/binding-android-arm-eabi@0.52.0':
optional: true
'@oxfmt/binding-android-arm64@0.47.0':
'@oxfmt/binding-android-arm64@0.52.0':
optional: true
'@oxfmt/binding-darwin-arm64@0.47.0':
'@oxfmt/binding-darwin-arm64@0.52.0':
optional: true
'@oxfmt/binding-darwin-x64@0.47.0':
'@oxfmt/binding-darwin-x64@0.52.0':
optional: true
'@oxfmt/binding-freebsd-x64@0.47.0':
'@oxfmt/binding-freebsd-x64@0.52.0':
optional: true
'@oxfmt/binding-linux-arm-gnueabihf@0.47.0':
'@oxfmt/binding-linux-arm-gnueabihf@0.52.0':
optional: true
'@oxfmt/binding-linux-arm-musleabihf@0.47.0':
'@oxfmt/binding-linux-arm-musleabihf@0.52.0':
optional: true
'@oxfmt/binding-linux-arm64-gnu@0.47.0':
'@oxfmt/binding-linux-arm64-gnu@0.52.0':
optional: true
'@oxfmt/binding-linux-arm64-musl@0.47.0':
'@oxfmt/binding-linux-arm64-musl@0.52.0':
optional: true
'@oxfmt/binding-linux-ppc64-gnu@0.47.0':
'@oxfmt/binding-linux-ppc64-gnu@0.52.0':
optional: true
'@oxfmt/binding-linux-riscv64-gnu@0.47.0':
'@oxfmt/binding-linux-riscv64-gnu@0.52.0':
optional: true
'@oxfmt/binding-linux-riscv64-musl@0.47.0':
'@oxfmt/binding-linux-riscv64-musl@0.52.0':
optional: true
'@oxfmt/binding-linux-s390x-gnu@0.47.0':
'@oxfmt/binding-linux-s390x-gnu@0.52.0':
optional: true
'@oxfmt/binding-linux-x64-gnu@0.47.0':
'@oxfmt/binding-linux-x64-gnu@0.52.0':
optional: true
'@oxfmt/binding-linux-x64-musl@0.47.0':
'@oxfmt/binding-linux-x64-musl@0.52.0':
optional: true
'@oxfmt/binding-openharmony-arm64@0.47.0':
'@oxfmt/binding-openharmony-arm64@0.52.0':
optional: true
'@oxfmt/binding-win32-arm64-msvc@0.47.0':
'@oxfmt/binding-win32-arm64-msvc@0.52.0':
optional: true
'@oxfmt/binding-win32-ia32-msvc@0.47.0':
'@oxfmt/binding-win32-ia32-msvc@0.52.0':
optional: true
'@oxfmt/binding-win32-x64-msvc@0.47.0':
'@oxfmt/binding-win32-x64-msvc@0.52.0':
optional: true
'@oxlint/binding-android-arm-eabi@1.63.0':
'@oxlint/binding-android-arm-eabi@1.67.0':
optional: true
'@oxlint/binding-android-arm64@1.63.0':
'@oxlint/binding-android-arm64@1.67.0':
optional: true
'@oxlint/binding-darwin-arm64@1.63.0':
'@oxlint/binding-darwin-arm64@1.67.0':
optional: true
'@oxlint/binding-darwin-x64@1.63.0':
'@oxlint/binding-darwin-x64@1.67.0':
optional: true
'@oxlint/binding-freebsd-x64@1.63.0':
'@oxlint/binding-freebsd-x64@1.67.0':
optional: true
'@oxlint/binding-linux-arm-gnueabihf@1.63.0':
'@oxlint/binding-linux-arm-gnueabihf@1.67.0':
optional: true
'@oxlint/binding-linux-arm-musleabihf@1.63.0':
'@oxlint/binding-linux-arm-musleabihf@1.67.0':
optional: true
'@oxlint/binding-linux-arm64-gnu@1.63.0':
'@oxlint/binding-linux-arm64-gnu@1.67.0':
optional: true
'@oxlint/binding-linux-arm64-musl@1.63.0':
'@oxlint/binding-linux-arm64-musl@1.67.0':
optional: true
'@oxlint/binding-linux-ppc64-gnu@1.63.0':
'@oxlint/binding-linux-ppc64-gnu@1.67.0':
optional: true
'@oxlint/binding-linux-riscv64-gnu@1.63.0':
'@oxlint/binding-linux-riscv64-gnu@1.67.0':
optional: true
'@oxlint/binding-linux-riscv64-musl@1.63.0':
'@oxlint/binding-linux-riscv64-musl@1.67.0':
optional: true
'@oxlint/binding-linux-s390x-gnu@1.63.0':
'@oxlint/binding-linux-s390x-gnu@1.67.0':
optional: true
'@oxlint/binding-linux-x64-gnu@1.63.0':
'@oxlint/binding-linux-x64-gnu@1.67.0':
optional: true
'@oxlint/binding-linux-x64-musl@1.63.0':
'@oxlint/binding-linux-x64-musl@1.67.0':
optional: true
'@oxlint/binding-openharmony-arm64@1.63.0':
'@oxlint/binding-openharmony-arm64@1.67.0':
optional: true
'@oxlint/binding-win32-arm64-msvc@1.63.0':
'@oxlint/binding-win32-arm64-msvc@1.67.0':
optional: true
'@oxlint/binding-win32-ia32-msvc@1.63.0':
'@oxlint/binding-win32-ia32-msvc@1.67.0':
optional: true
'@oxlint/binding-win32-x64-msvc@1.63.0':
'@oxlint/binding-win32-x64-msvc@1.67.0':
optional: true
'@pkgr/core@0.2.9': {}
@ -11759,51 +11786,51 @@ snapshots:
object-keys: 1.1.1
safe-push-apply: 1.0.0
oxfmt@0.47.0:
oxfmt@0.52.0:
dependencies:
tinypool: 2.1.0
optionalDependencies:
'@oxfmt/binding-android-arm-eabi': 0.47.0
'@oxfmt/binding-android-arm64': 0.47.0
'@oxfmt/binding-darwin-arm64': 0.47.0
'@oxfmt/binding-darwin-x64': 0.47.0
'@oxfmt/binding-freebsd-x64': 0.47.0
'@oxfmt/binding-linux-arm-gnueabihf': 0.47.0
'@oxfmt/binding-linux-arm-musleabihf': 0.47.0
'@oxfmt/binding-linux-arm64-gnu': 0.47.0
'@oxfmt/binding-linux-arm64-musl': 0.47.0
'@oxfmt/binding-linux-ppc64-gnu': 0.47.0
'@oxfmt/binding-linux-riscv64-gnu': 0.47.0
'@oxfmt/binding-linux-riscv64-musl': 0.47.0
'@oxfmt/binding-linux-s390x-gnu': 0.47.0
'@oxfmt/binding-linux-x64-gnu': 0.47.0
'@oxfmt/binding-linux-x64-musl': 0.47.0
'@oxfmt/binding-openharmony-arm64': 0.47.0
'@oxfmt/binding-win32-arm64-msvc': 0.47.0
'@oxfmt/binding-win32-ia32-msvc': 0.47.0
'@oxfmt/binding-win32-x64-msvc': 0.47.0
'@oxfmt/binding-android-arm-eabi': 0.52.0
'@oxfmt/binding-android-arm64': 0.52.0
'@oxfmt/binding-darwin-arm64': 0.52.0
'@oxfmt/binding-darwin-x64': 0.52.0
'@oxfmt/binding-freebsd-x64': 0.52.0
'@oxfmt/binding-linux-arm-gnueabihf': 0.52.0
'@oxfmt/binding-linux-arm-musleabihf': 0.52.0
'@oxfmt/binding-linux-arm64-gnu': 0.52.0
'@oxfmt/binding-linux-arm64-musl': 0.52.0
'@oxfmt/binding-linux-ppc64-gnu': 0.52.0
'@oxfmt/binding-linux-riscv64-gnu': 0.52.0
'@oxfmt/binding-linux-riscv64-musl': 0.52.0
'@oxfmt/binding-linux-s390x-gnu': 0.52.0
'@oxfmt/binding-linux-x64-gnu': 0.52.0
'@oxfmt/binding-linux-x64-musl': 0.52.0
'@oxfmt/binding-openharmony-arm64': 0.52.0
'@oxfmt/binding-win32-arm64-msvc': 0.52.0
'@oxfmt/binding-win32-ia32-msvc': 0.52.0
'@oxfmt/binding-win32-x64-msvc': 0.52.0
oxlint@1.63.0:
oxlint@1.67.0:
optionalDependencies:
'@oxlint/binding-android-arm-eabi': 1.63.0
'@oxlint/binding-android-arm64': 1.63.0
'@oxlint/binding-darwin-arm64': 1.63.0
'@oxlint/binding-darwin-x64': 1.63.0
'@oxlint/binding-freebsd-x64': 1.63.0
'@oxlint/binding-linux-arm-gnueabihf': 1.63.0
'@oxlint/binding-linux-arm-musleabihf': 1.63.0
'@oxlint/binding-linux-arm64-gnu': 1.63.0
'@oxlint/binding-linux-arm64-musl': 1.63.0
'@oxlint/binding-linux-ppc64-gnu': 1.63.0
'@oxlint/binding-linux-riscv64-gnu': 1.63.0
'@oxlint/binding-linux-riscv64-musl': 1.63.0
'@oxlint/binding-linux-s390x-gnu': 1.63.0
'@oxlint/binding-linux-x64-gnu': 1.63.0
'@oxlint/binding-linux-x64-musl': 1.63.0
'@oxlint/binding-openharmony-arm64': 1.63.0
'@oxlint/binding-win32-arm64-msvc': 1.63.0
'@oxlint/binding-win32-ia32-msvc': 1.63.0
'@oxlint/binding-win32-x64-msvc': 1.63.0
'@oxlint/binding-android-arm-eabi': 1.67.0
'@oxlint/binding-android-arm64': 1.67.0
'@oxlint/binding-darwin-arm64': 1.67.0
'@oxlint/binding-darwin-x64': 1.67.0
'@oxlint/binding-freebsd-x64': 1.67.0
'@oxlint/binding-linux-arm-gnueabihf': 1.67.0
'@oxlint/binding-linux-arm-musleabihf': 1.67.0
'@oxlint/binding-linux-arm64-gnu': 1.67.0
'@oxlint/binding-linux-arm64-musl': 1.67.0
'@oxlint/binding-linux-ppc64-gnu': 1.67.0
'@oxlint/binding-linux-riscv64-gnu': 1.67.0
'@oxlint/binding-linux-riscv64-musl': 1.67.0
'@oxlint/binding-linux-s390x-gnu': 1.67.0
'@oxlint/binding-linux-x64-gnu': 1.67.0
'@oxlint/binding-linux-x64-musl': 1.67.0
'@oxlint/binding-openharmony-arm64': 1.67.0
'@oxlint/binding-win32-arm64-msvc': 1.67.0
'@oxlint/binding-win32-ia32-msvc': 1.67.0
'@oxlint/binding-win32-x64-msvc': 1.67.0
p-limit@2.3.0:
dependencies:

View File

@ -155,8 +155,8 @@
"electron-vite": "^5.0.0",
"husky": "^9.1.7",
"lint-staged": "^16.4.0",
"oxfmt": "^0.41.0",
"oxlint": "^1.63.0",
"oxfmt": "^0.52.0",
"oxlint": "^1.67.0",
"react": "^19.2.5",
"react-dom": "^19.2.5",
"react-grab": "^0.1.33",

View File

@ -306,11 +306,11 @@ importers:
specifier: ^16.4.0
version: 16.4.0
oxfmt:
specifier: ^0.41.0
version: 0.41.0
specifier: ^0.52.0
version: 0.52.0
oxlint:
specifier: ^1.63.0
version: 1.63.0
specifier: ^1.67.0
version: 1.67.0
react:
specifier: ^19.2.5
version: 19.2.5
@ -1150,246 +1150,246 @@ packages:
'@open-draft/until@2.1.0':
resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==}
'@oxfmt/binding-android-arm-eabi@0.41.0':
resolution: {integrity: sha512-REfrqeMKGkfMP+m/ScX4f5jJBSmVNYcpoDF8vP8f8eYPDuPGZmzp56NIUsYmx3h7f6NzC6cE3gqh8GDWrJHCKw==}
'@oxfmt/binding-android-arm-eabi@0.52.0':
resolution: {integrity: sha512-17EMSJnQ9g+upVHrAUYDMfH5lvRKQ9Nvg8WtEoH72oDr1VpWz+7/o3tD97U1EToen2YAQ/68JmtDYkQUi20dfQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@oxfmt/binding-android-arm64@0.41.0':
resolution: {integrity: sha512-s0b1dxNgb2KomspFV2LfogC2XtSJB42POXF4bMCLJyvQmAGos4ZtjGPfQreToQEaY0FQFjz3030ggI36rF1q5g==}
'@oxfmt/binding-android-arm64@0.52.0':
resolution: {integrity: sha512-A2G1IdwGEW2lLJkIxcvuirRH1CzSl/e0NX11zTlW1gvxJThfwbI/BEoaKrTNpm7M2FchvIf6guvIQU7d5iz+OQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@oxfmt/binding-darwin-arm64@0.41.0':
resolution: {integrity: sha512-EGXGualADbv/ZmamE7/2DbsrYmjoPlAmHEpTL4vapLF4EfVD6fr8/uQDFnPJkUBjiSWFJZtFNsGeN1B6V3owmA==}
'@oxfmt/binding-darwin-arm64@0.52.0':
resolution: {integrity: sha512-f9+bLvOYxy7NttCLFTvQ7afmqDOWY4wIP9xdvfj5trQ1qj6f2UFAGwZESlfsMjvJNTyRpXfIlOanCI9FOvoeQA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@oxfmt/binding-darwin-x64@0.41.0':
resolution: {integrity: sha512-WxySJEvdQQYMmyvISH3qDpTvoS0ebnIP63IMxLLWowJyPp/AAH0hdWtlo+iGNK5y3eVfa5jZguwNaQkDKWpGSw==}
'@oxfmt/binding-darwin-x64@0.52.0':
resolution: {integrity: sha512-YSTB9sJ5nnQd/Q0ddHkgof0ZCHPAnWZT1IW2SJ8omz7CP7KluJhO1fNHrpqdxCtpztJwSs4hY1uAee35wKxxaw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@oxfmt/binding-freebsd-x64@0.41.0':
resolution: {integrity: sha512-Y2kzMkv3U3oyuYaR4wTfGjOTYTXiFC/hXmG0yVASKkbh02BJkvD98Ij8bIevr45hNZ0DmZEgqiXF+9buD4yMYQ==}
'@oxfmt/binding-freebsd-x64@0.52.0':
resolution: {integrity: sha512-NIrRNTTPCs4UbmVs0bxLSCDlLCtIRMJIXklNKaXa5Oj2/K1UIMBvgE8+uPVo01Io3N9HF0+GAX+aAHjUgZS7vA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@oxfmt/binding-linux-arm-gnueabihf@0.41.0':
resolution: {integrity: sha512-ptazDjdUyhket01IjPTT6ULS1KFuBfTUU97osTP96X5y/0oso+AgAaJzuH81oP0+XXyrWIHbRzozSAuQm4p48g==}
'@oxfmt/binding-linux-arm-gnueabihf@0.52.0':
resolution: {integrity: sha512-JXUCde8mn3GpgQouz2PXUokgy/uT1QrRJBL2s983VWcSQp62wTFYiNXgTKdeo1Jgbr0IgUnKKvzIk/YBlj/nVQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxfmt/binding-linux-arm-musleabihf@0.41.0':
resolution: {integrity: sha512-UkoL2OKxFD+56bPEBcdGn+4juTW4HRv/T6w1dIDLnvKKWr6DbarB/mtHXlADKlFiJubJz8pRkttOR7qjYR6lTA==}
'@oxfmt/binding-linux-arm-musleabihf@0.52.0':
resolution: {integrity: sha512-psbUXaRZ+V8DaXz10Qf7LSHtdtdKAmC8fxXgeU608jjzrmWK4quamZMOpl6sf+dikoFHA85uE93Q0BqxrCdQrQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxfmt/binding-linux-arm64-gnu@0.41.0':
resolution: {integrity: sha512-gofu0PuumSOHYczD8p62CPY4UF6ee+rSLZJdUXkpwxg6pILiwSDBIouPskjF/5nF3A7QZTz2O9KFNkNxxFN9tA==}
'@oxfmt/binding-linux-arm64-gnu@0.52.0':
resolution: {integrity: sha512-Jw7MgWUU9lcLCcy82updISP3EthTlfvAwR6gWNxPzqly7+fLvOi2gHQE9xXQjpqaVLm/8P+gOzlv9ODuoVlaaw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-arm64-musl@0.41.0':
resolution: {integrity: sha512-VfVZxL0+6RU86T8F8vKiDBa+iHsr8PAjQmKGBzSCAX70b6x+UOMFl+2dNihmKmUwqkCazCPfYjt6SuAPOeQJ3g==}
'@oxfmt/binding-linux-arm64-musl@0.52.0':
resolution: {integrity: sha512-wZg6bLjDvh2KibyI3QFUYo8GTXneIFsd0JvehtvJiUmQ8WRPERgxd/VM4ctWb86U5FT1FkqgS8/wZKVB+AZScg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxfmt/binding-linux-ppc64-gnu@0.41.0':
resolution: {integrity: sha512-bwzokz2eGvdfJbc0i+zXMJ4BBjQPqg13jyWpEEZDOrBCQ91r8KeY2Mi2kUeuMTZNFXju+jcAbAbpyJxRGla0eg==}
'@oxfmt/binding-linux-ppc64-gnu@0.52.0':
resolution: {integrity: sha512-IngE8uxhNvxcMrLjZNDo9xNLY7rEK33AKnaMd2B46he1e/mz2CfcW6If/U1wUjdRZddm1QzQaciqZkuMkdh1FA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-riscv64-gnu@0.41.0':
resolution: {integrity: sha512-POLM//PCH9uqDeNDwWL3b3DkMmI3oI2cU6hwc2lnztD1o7dzrQs3R9nq555BZ6wI7t2lyhT9CS+CRaz5X0XqLA==}
'@oxfmt/binding-linux-riscv64-gnu@0.52.0':
resolution: {integrity: sha512-H3+DdFMv/efN3Efmhsv18jDrpiWWqKG7wsfAlQBqAt6z/E2Bx+TwEj2Nowe51CPOWB8/mFBC2dAMSgVFLvvowA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-riscv64-musl@0.41.0':
resolution: {integrity: sha512-NNK7PzhFqLUwx/G12Xtm6scGv7UITvyGdAR5Y+TlqsG+essnuRWR4jRNODWRjzLZod0T3SayRbnkSIWMBov33w==}
'@oxfmt/binding-linux-riscv64-musl@0.52.0':
resolution: {integrity: sha512-zji+1kb7lJKohSDjzC1IsS+K/cKRs1hdVf0ZH0VbdbiakmtLvN9twBoXo/k8VdjFax7kfo+DyPxS7vv52br1aw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxfmt/binding-linux-s390x-gnu@0.41.0':
resolution: {integrity: sha512-qVf/zDC5cN9eKe4qI/O/m445er1IRl6swsSl7jHkqmOSVfknwCe5JXitYjZca+V/cNJSU/xPlC5EFMabMMFDpw==}
'@oxfmt/binding-linux-s390x-gnu@0.52.0':
resolution: {integrity: sha512-hcLBYedpCy7ToUvvBidWk7+11Yhg1oAZ4+6hKPic/mQI6NaqXJSXMps5nFlwUuX2ewhtLZZDPg63TI042qGKBg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-x64-gnu@0.41.0':
resolution: {integrity: sha512-ojxYWu7vUb6ysYqVCPHuAPVZHAI40gfZ0PDtZAMwVmh2f0V8ExpPIKoAKr7/8sNbAXJBBpZhs2coypIo2jJX4w==}
'@oxfmt/binding-linux-x64-gnu@0.52.0':
resolution: {integrity: sha512-IDO2loXK2OtTOhSPchU9MW25mWL2QCDGdJbjN8MXKZVS80qXe5gMTwQWu/gMJ3juoBHbkuUZNB2N1LHzNT7DoA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-x64-musl@0.41.0':
resolution: {integrity: sha512-O2exZLBxoCMIv2vlvcbkdedazJPTdG0VSup+0QUCfYQtx751zCZNboX2ZUOiQ/gDTdhtXvSiot0h6GEGkOyalA==}
'@oxfmt/binding-linux-x64-musl@0.52.0':
resolution: {integrity: sha512-mAV2Hjn0SatJ+KoAzKUC3eJhdJ8wv+3m1KyuS0dTsbF0c5weq+QrCt/DRZZM+uj/XiKzCDEUKYsBF30e2qkcyw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxfmt/binding-openharmony-arm64@0.41.0':
resolution: {integrity: sha512-N+31/VoL+z+NNBt8viy3I4NaIdPbiYeOnB884LKqvXldaE2dRztdPv3q5ipfZYv0RwFp7JfqS4I27K/DSHCakg==}
'@oxfmt/binding-openharmony-arm64@0.52.0':
resolution: {integrity: sha512-vd4npaUIwChxp7XzkqmepBWTT9YMcSe/NBApVGPC30/lLyOVaV3dvma1SKo03t8O73BPRAG7EyJzGlN5cJM5hQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@oxfmt/binding-win32-arm64-msvc@0.41.0':
resolution: {integrity: sha512-Z7NAtu/RN8kjCQ1y5oDD0nTAeRswh3GJ93qwcW51srmidP7XPBmZbLlwERu1W5veCevQJtPS9xmkpcDTYsGIwQ==}
'@oxfmt/binding-win32-arm64-msvc@0.52.0':
resolution: {integrity: sha512-k2sz6gWQdMfh5HPpIS+Bw/0UEV/kaK2xuqJRrWL233sEHx9WLlsmvlPFM4HUNThkYbSN0U0vPW7LVKZWDS8hPQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@oxfmt/binding-win32-ia32-msvc@0.41.0':
resolution: {integrity: sha512-uNxxP3l4bJ6VyzIeRqCmBU2Q0SkCFgIhvx9/9dJ9V8t/v+jP1IBsuaLwCXGR8JPHtkj4tFp+RHtUmU2ZYAUpMA==}
'@oxfmt/binding-win32-ia32-msvc@0.52.0':
resolution: {integrity: sha512-rhke69GTcArodLHpjMTfNnvjTEBryDeZcUCKK/VjXDMtfTULl6QRh0ymX5/hbCUv2WjYm9h/QbW++q2vE15gWQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@oxfmt/binding-win32-x64-msvc@0.41.0':
resolution: {integrity: sha512-49ZSpbZ1noozyPapE8SUOSm3IN0Ze4b5nkO+4+7fq6oEYQQJFhE0saj5k/Gg4oewVPdjn0L3ZFeWk2Vehjcw7A==}
'@oxfmt/binding-win32-x64-msvc@0.52.0':
resolution: {integrity: sha512-q5xL7oeXkZdEtNZWBdvehJcmt+GRu9l2bK40yJs1jJXlqq+r0Hygb1rTjq+FM2o/2xyt4cufH6KRplHp3Jjsvw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
'@oxlint/binding-android-arm-eabi@1.63.0':
resolution: {integrity: sha512-A9xLtQt7i0OA1PoB/meog6kikXI9CdwEp7ZwQqmgnpKn3G3b1orvTDy8CQ6T7w1HvDrgWGB78PkFKcWgibcTCg==}
'@oxlint/binding-android-arm-eabi@1.67.0':
resolution: {integrity: sha512-VrSi571rDv1N8HaEDM+DEX8nmT0y9jJo8tzzW13vsOWTx59xQczCIJx68n2zWOXRT5YKZsOZXp4qkHN/10x4mw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@oxlint/binding-android-arm64@1.63.0':
resolution: {integrity: sha512-SQo+ZMvdR9l3CxZp5W5gFNxSiDxclY6lOzzNpKYLF8asESpm3Pwumx0gER5T7aHLF1/2BAAtLD3DiDkdgy4V1A==}
'@oxlint/binding-android-arm64@1.67.0':
resolution: {integrity: sha512-l6+NdYxMoRohix5r5bbigW16LPicceCwGcQ6LKKuE1kUdjgFfQolJjrJsQYPFetIs78Gxj/G/f5TEGoTCwj9nQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@oxlint/binding-darwin-arm64@1.63.0':
resolution: {integrity: sha512-6W82XjJDTmMnjg30427l0dufpnyLoq7wEukKdM6/g2VIybRVuQiBVh43EA4b+UxZ3+tLcKm+Or/pXGNgLCEU8g==}
'@oxlint/binding-darwin-arm64@1.67.0':
resolution: {integrity: sha512-jOzXxS1AxFxhImLIRbtGIMrEwaXcgMw3gR57WB1cRk8ai+vpr6726kxXqVvlNsrXtJ/FrmOm8RxlC0m8SW24Qg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@oxlint/binding-darwin-x64@1.63.0':
resolution: {integrity: sha512-CnWd/YCuVG5W1BYkjJEVbJG11o526O9qAwBEQM+nh8K19CRFUkFdROXCyYkGmroHEYQe4vgQ6+lh3550Lp35Xw==}
'@oxlint/binding-darwin-x64@1.67.0':
resolution: {integrity: sha512-3DFAVY94OqjIZHXIPz37yGRSWwOFTAqChQ64/M69GYLawzP0KiwdhDNfqdKKYT0bTR/DNxmMnQsj3ns+8+X/Lg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@oxlint/binding-freebsd-x64@1.63.0':
resolution: {integrity: sha512-a4eZAqrmtajqcxfdAzC+l7g3PaE3V8hpAYqqeD3fTxLXOMFdK3eNTZrU80n4dDEVm0JXy1aL5PqvqWldBl6zYA==}
'@oxlint/binding-freebsd-x64@1.67.0':
resolution: {integrity: sha512-e4dDKZuLu8TR9DEBssWSDahlPgZBwojTTHZUvnjBRJfJJbpxYCjfjKfi0Z1+CSLMiJBwI2yCDtRM1XJQaARjmg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@oxlint/binding-linux-arm-gnueabihf@1.63.0':
resolution: {integrity: sha512-tYUtU9TdbU3uXF5D62g5zXJ13iniFGhXQx5vp9cyEjGdbSAY3VdFBSaldYvyoDmgMZ0ZYuwQP1Y4t2Fhejwa0w==}
'@oxlint/binding-linux-arm-gnueabihf@1.67.0':
resolution: {integrity: sha512-BKytFdcQzbITV3xlnzDUDTEDtbUMCCiC4EaNTDZ4FyT8gdNvBC4gfiLucXp/sQl0XU3p7syTlorUWVVVBZab2g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxlint/binding-linux-arm-musleabihf@1.63.0':
resolution: {integrity: sha512-I5r3twFf776UZg9dmRo2xbrKt00tTkORXEVe0ctg4vdTkQvJAjiCHxnbAU2HL1AiJ9cqADA76MAliuilsAWnvg==}
'@oxlint/binding-linux-arm-musleabihf@1.67.0':
resolution: {integrity: sha512-XYAv0esBDX7BpTzRDjVX2Vdj+zndd8ll2dFQiaeQ6zTZr7A8GRDTN7fH3FP3jU+O0vCDx85oH/EtG7BzPgAXuw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxlint/binding-linux-arm64-gnu@1.63.0':
resolution: {integrity: sha512-t7ltUkg6FFh4b564QyGir8xIj/QZbXu8FlcRkcyW9+ztr/mfRHlvUOFd95pJCXi9s/L5DrUeWWgpXRS+V+6igQ==}
'@oxlint/binding-linux-arm64-gnu@1.67.0':
resolution: {integrity: sha512-zizRMjA0i6u/2B0evgda04iycu+MoNuf1pBy6Eh+1CjC5wMEG7qN5zdDKTCvFc0KSYSDM9QTG3gjZHirgtQuKg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-arm64-musl@1.63.0':
resolution: {integrity: sha512-Q5mmZy/XWjuYFUuQyYjOvZ5U/JkKEwnpir6hGxhh6HcdP0V/BKxLo8dqkfF/t7r7AguB17dfS/8+go5AQDRR6g==}
'@oxlint/binding-linux-arm64-musl@1.67.0':
resolution: {integrity: sha512-zB/Tf6sUjmmvvbva9Gj3JTJ8rJ9t4I8/U0o6vSRtd0DRIsIuyegBwJAzhSUFQHdMijIRJkW0exs/yBhpw2S20w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxlint/binding-linux-ppc64-gnu@1.63.0':
resolution: {integrity: sha512-uBGtuZ0TzLB4x5wVa82HGNvYqY8buwDhyCnCP0R0gkk9szqVsP0MeTtD5HX7EsEuFIt+aYmYxuxeVxs3nTSwtQ==}
'@oxlint/binding-linux-ppc64-gnu@1.67.0':
resolution: {integrity: sha512-kgU40Gt74CK0TCsF51KZymkIwN9U0BajKsMijB52zPqOeZU9NAHkA/NSQkZDHEaCakx42DxhXkODiAqf2b4Gug==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-riscv64-gnu@1.63.0':
resolution: {integrity: sha512-h4s6FwxE+9MeA181o0dnDwHP32Y/bG8EiB/vrD6Ib+AMt6haigDc/0bUtI/sLmQDBMJnUfaCmtSSrEAqjtEVrA==}
'@oxlint/binding-linux-riscv64-gnu@1.67.0':
resolution: {integrity: sha512-tOYhkk/iaG9aD3FvGpBFd1Lrw0x0RaVoJBxjUkfNzS50rC5NS5BteNCwgr8A2zCdADrIIoze6D7u6U5Ic++/iQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-riscv64-musl@1.63.0':
resolution: {integrity: sha512-2EaNcCBR8Mcjl5ARtuN3BdEpVkX7KpjSjMGZ/mJMIeaXgTtdz5ytg2VwygMSStA/k0ixfvZFoZOfjDEcouV5vQ==}
'@oxlint/binding-linux-riscv64-musl@1.67.0':
resolution: {integrity: sha512-sEtywrPb+0b+tHYl1SDCrw903fiC4eyKoNqzP3v+f2JT3Xcv4NEYG+P8rj+eEnX7IWhqV/xj8/JmcmVj21CXaA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxlint/binding-linux-s390x-gnu@1.63.0':
resolution: {integrity: sha512-p4hlf/fd7TrYYl3QrWWD0GocqJefwMu3cHQhmi2FvEB/YOvFb5DZN3SMBaPi7B1TM5DeypkEtrVib674q1KKPg==}
'@oxlint/binding-linux-s390x-gnu@1.67.0':
resolution: {integrity: sha512-BvR8Moa0zCLxroOx4vZaZN9nUfwAUpSTwjZdxZyKy4bv3PrzrXrxKR/ZQ0L9wNSvlPhnMJeZfa3q5w6ZCTuN6Q==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-x64-gnu@1.63.0':
resolution: {integrity: sha512-Vgq9rkRVcPcjbcH+ihYTfpeR7vCXfqpd+z5ItTGc0yYUV59L5ceHYN1iV4H9bKGV7Rn5hkVc7x3mSvHegduENA==}
'@oxlint/binding-linux-x64-gnu@1.67.0':
resolution: {integrity: sha512-mm2cxM6fksOpq6l0uFws8BUGKAR4dNa/cZCn37Npq7PFbhD5HDJqWfnoIvTaeRKMy5XdS2tO0MA0qbHDrnXAAA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-x64-musl@1.63.0':
resolution: {integrity: sha512-3/Lkq/ncooA61rorrC+ZQed1Bc4VpGj+WnGsp58zmxKgvZ2vhreu+dcVyr3mX8NUpq7mfZ4gDDTou/yrF1Pd7A==}
'@oxlint/binding-linux-x64-musl@1.67.0':
resolution: {integrity: sha512-WmbMuLapKyDlobMkXAaAL0Y+Uczh4LETfIfQsUpbId4Ip8Ai82/jqeYTOoUCkuuhBFapgqP253+d83tLKOksJg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxlint/binding-openharmony-arm64@1.63.0':
resolution: {integrity: sha512-0/EdD/6hDkx5Mfd769PTjvEM8mZ/6Dfukp1dBCL/2PjlIVGEtYdNZyok6ChqYPsT9JcFnlQnUeQzO0/1L/oC9w==}
'@oxlint/binding-openharmony-arm64@1.67.0':
resolution: {integrity: sha512-9g/PqxYJelzzTAOR5Y+RiRqdeydhEuXv2KxNeFcAKQ7UsvnWSY1OP4MsuPMbTO2Pf70tz7mFhl1j13H3fyh+8g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@oxlint/binding-win32-arm64-msvc@1.63.0':
resolution: {integrity: sha512-wb0CUkN8ngwPiRQBjD1Cj0LsHeNvm+Xt6YBHDMtj2DVQVD6Oj8Ri7g6BD+KICf6LaBqZlmzOvy6nF9E/8yyGOg==}
'@oxlint/binding-win32-arm64-msvc@1.67.0':
resolution: {integrity: sha512-2VhwE6Gatb0vJGnN0TBuQMbKCOiZlSQ/zJvVWYLK4a9d4iDiJOen/yVQkGpmsJ90MuH66fzi0kEKI0jRQMDxGA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@oxlint/binding-win32-ia32-msvc@1.63.0':
resolution: {integrity: sha512-BX5iq+ovdNlVYhSn5qPMUIT0uwAwt2lmEnCnzK+Gkhw4DovIvhGb96OFhV8yzQNUnQxn/xGkOR+X+BLrLDNm8w==}
'@oxlint/binding-win32-ia32-msvc@1.67.0':
resolution: {integrity: sha512-EQ3VExXfeM1InbE5+JjufhZZTWy+kHUwgt3yZR7gQ47Je/mE0WspQPan0OJznh493L5anM210YNJtH1PXjTSFg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@oxlint/binding-win32-x64-msvc@1.63.0':
resolution: {integrity: sha512-QeN/WELOfsXMeYwxvfgQrl6CbVftYUCZsGXHjXQd5Trccm8+i4gmtxaOui4xbJQaiDlviF8F3yLSBloQUeFsfA==}
'@oxlint/binding-win32-x64-msvc@1.67.0':
resolution: {integrity: sha512-bw24y+/1MHS4QDkons3YyHkPT9uCMoLHHgQhb+mb8NOjTYwub1CZ+K9Ngr8aO5DMrDrkqHwTzlTwFP2vS8Y/ZQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
@ -5152,20 +5152,31 @@ packages:
outvariant@1.4.3:
resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==}
oxfmt@0.41.0:
resolution: {integrity: sha512-sKLdJZdQ3bw6x9qKiT7+eID4MNEXlDHf5ZacfIircrq6Qwjk0L6t2/JQlZZrVHTXJawK3KaMuBoJnEJPcqCEdg==}
oxfmt@0.52.0:
resolution: {integrity: sha512-nJlYM35F64zTDMecCNhoHNkf+D/eHv7xcjj9XDSj+bFAVtN93m7v8DQMdHd6nDG6Akf/kEYYHmDUBs2Dz27Sug==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
svelte: ^5.0.0
vite-plus: '*'
peerDependenciesMeta:
svelte:
optional: true
vite-plus:
optional: true
oxlint@1.63.0:
resolution: {integrity: sha512-9TGXetdjgIHOJ9OiReomP7nnrMkV9HxC1xM2ramJSLQpzxjsAJtQwa4wqkJN2f/uCrqZuJseFuSlWDdvcruveg==}
oxlint@1.67.0:
resolution: {integrity: sha512-blwwaHPdoH8piQ5/z0KHeoHFR7FZgl12WluKJfu4qFLPkZl6mK04PkLE45Fw1NxfBRSlh40Gu7MkxHUw++ociQ==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
oxlint-tsgolint: '>=0.22.1'
vite-plus: '*'
peerDependenciesMeta:
oxlint-tsgolint:
optional: true
vite-plus:
optional: true
p-cancelable@2.1.1:
resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==}
@ -7177,118 +7188,118 @@ snapshots:
'@open-draft/until@2.1.0': {}
'@oxfmt/binding-android-arm-eabi@0.41.0':
'@oxfmt/binding-android-arm-eabi@0.52.0':
optional: true
'@oxfmt/binding-android-arm64@0.41.0':
'@oxfmt/binding-android-arm64@0.52.0':
optional: true
'@oxfmt/binding-darwin-arm64@0.41.0':
'@oxfmt/binding-darwin-arm64@0.52.0':
optional: true
'@oxfmt/binding-darwin-x64@0.41.0':
'@oxfmt/binding-darwin-x64@0.52.0':
optional: true
'@oxfmt/binding-freebsd-x64@0.41.0':
'@oxfmt/binding-freebsd-x64@0.52.0':
optional: true
'@oxfmt/binding-linux-arm-gnueabihf@0.41.0':
'@oxfmt/binding-linux-arm-gnueabihf@0.52.0':
optional: true
'@oxfmt/binding-linux-arm-musleabihf@0.41.0':
'@oxfmt/binding-linux-arm-musleabihf@0.52.0':
optional: true
'@oxfmt/binding-linux-arm64-gnu@0.41.0':
'@oxfmt/binding-linux-arm64-gnu@0.52.0':
optional: true
'@oxfmt/binding-linux-arm64-musl@0.41.0':
'@oxfmt/binding-linux-arm64-musl@0.52.0':
optional: true
'@oxfmt/binding-linux-ppc64-gnu@0.41.0':
'@oxfmt/binding-linux-ppc64-gnu@0.52.0':
optional: true
'@oxfmt/binding-linux-riscv64-gnu@0.41.0':
'@oxfmt/binding-linux-riscv64-gnu@0.52.0':
optional: true
'@oxfmt/binding-linux-riscv64-musl@0.41.0':
'@oxfmt/binding-linux-riscv64-musl@0.52.0':
optional: true
'@oxfmt/binding-linux-s390x-gnu@0.41.0':
'@oxfmt/binding-linux-s390x-gnu@0.52.0':
optional: true
'@oxfmt/binding-linux-x64-gnu@0.41.0':
'@oxfmt/binding-linux-x64-gnu@0.52.0':
optional: true
'@oxfmt/binding-linux-x64-musl@0.41.0':
'@oxfmt/binding-linux-x64-musl@0.52.0':
optional: true
'@oxfmt/binding-openharmony-arm64@0.41.0':
'@oxfmt/binding-openharmony-arm64@0.52.0':
optional: true
'@oxfmt/binding-win32-arm64-msvc@0.41.0':
'@oxfmt/binding-win32-arm64-msvc@0.52.0':
optional: true
'@oxfmt/binding-win32-ia32-msvc@0.41.0':
'@oxfmt/binding-win32-ia32-msvc@0.52.0':
optional: true
'@oxfmt/binding-win32-x64-msvc@0.41.0':
'@oxfmt/binding-win32-x64-msvc@0.52.0':
optional: true
'@oxlint/binding-android-arm-eabi@1.63.0':
'@oxlint/binding-android-arm-eabi@1.67.0':
optional: true
'@oxlint/binding-android-arm64@1.63.0':
'@oxlint/binding-android-arm64@1.67.0':
optional: true
'@oxlint/binding-darwin-arm64@1.63.0':
'@oxlint/binding-darwin-arm64@1.67.0':
optional: true
'@oxlint/binding-darwin-x64@1.63.0':
'@oxlint/binding-darwin-x64@1.67.0':
optional: true
'@oxlint/binding-freebsd-x64@1.63.0':
'@oxlint/binding-freebsd-x64@1.67.0':
optional: true
'@oxlint/binding-linux-arm-gnueabihf@1.63.0':
'@oxlint/binding-linux-arm-gnueabihf@1.67.0':
optional: true
'@oxlint/binding-linux-arm-musleabihf@1.63.0':
'@oxlint/binding-linux-arm-musleabihf@1.67.0':
optional: true
'@oxlint/binding-linux-arm64-gnu@1.63.0':
'@oxlint/binding-linux-arm64-gnu@1.67.0':
optional: true
'@oxlint/binding-linux-arm64-musl@1.63.0':
'@oxlint/binding-linux-arm64-musl@1.67.0':
optional: true
'@oxlint/binding-linux-ppc64-gnu@1.63.0':
'@oxlint/binding-linux-ppc64-gnu@1.67.0':
optional: true
'@oxlint/binding-linux-riscv64-gnu@1.63.0':
'@oxlint/binding-linux-riscv64-gnu@1.67.0':
optional: true
'@oxlint/binding-linux-riscv64-musl@1.63.0':
'@oxlint/binding-linux-riscv64-musl@1.67.0':
optional: true
'@oxlint/binding-linux-s390x-gnu@1.63.0':
'@oxlint/binding-linux-s390x-gnu@1.67.0':
optional: true
'@oxlint/binding-linux-x64-gnu@1.63.0':
'@oxlint/binding-linux-x64-gnu@1.67.0':
optional: true
'@oxlint/binding-linux-x64-musl@1.63.0':
'@oxlint/binding-linux-x64-musl@1.67.0':
optional: true
'@oxlint/binding-openharmony-arm64@1.63.0':
'@oxlint/binding-openharmony-arm64@1.67.0':
optional: true
'@oxlint/binding-win32-arm64-msvc@1.63.0':
'@oxlint/binding-win32-arm64-msvc@1.67.0':
optional: true
'@oxlint/binding-win32-ia32-msvc@1.63.0':
'@oxlint/binding-win32-ia32-msvc@1.67.0':
optional: true
'@oxlint/binding-win32-x64-msvc@1.63.0':
'@oxlint/binding-win32-x64-msvc@1.67.0':
optional: true
'@parcel/watcher-android-arm64@2.5.6':
@ -11454,51 +11465,51 @@ snapshots:
outvariant@1.4.3: {}
oxfmt@0.41.0:
oxfmt@0.52.0:
dependencies:
tinypool: 2.1.0
optionalDependencies:
'@oxfmt/binding-android-arm-eabi': 0.41.0
'@oxfmt/binding-android-arm64': 0.41.0
'@oxfmt/binding-darwin-arm64': 0.41.0
'@oxfmt/binding-darwin-x64': 0.41.0
'@oxfmt/binding-freebsd-x64': 0.41.0
'@oxfmt/binding-linux-arm-gnueabihf': 0.41.0
'@oxfmt/binding-linux-arm-musleabihf': 0.41.0
'@oxfmt/binding-linux-arm64-gnu': 0.41.0
'@oxfmt/binding-linux-arm64-musl': 0.41.0
'@oxfmt/binding-linux-ppc64-gnu': 0.41.0
'@oxfmt/binding-linux-riscv64-gnu': 0.41.0
'@oxfmt/binding-linux-riscv64-musl': 0.41.0
'@oxfmt/binding-linux-s390x-gnu': 0.41.0
'@oxfmt/binding-linux-x64-gnu': 0.41.0
'@oxfmt/binding-linux-x64-musl': 0.41.0
'@oxfmt/binding-openharmony-arm64': 0.41.0
'@oxfmt/binding-win32-arm64-msvc': 0.41.0
'@oxfmt/binding-win32-ia32-msvc': 0.41.0
'@oxfmt/binding-win32-x64-msvc': 0.41.0
'@oxfmt/binding-android-arm-eabi': 0.52.0
'@oxfmt/binding-android-arm64': 0.52.0
'@oxfmt/binding-darwin-arm64': 0.52.0
'@oxfmt/binding-darwin-x64': 0.52.0
'@oxfmt/binding-freebsd-x64': 0.52.0
'@oxfmt/binding-linux-arm-gnueabihf': 0.52.0
'@oxfmt/binding-linux-arm-musleabihf': 0.52.0
'@oxfmt/binding-linux-arm64-gnu': 0.52.0
'@oxfmt/binding-linux-arm64-musl': 0.52.0
'@oxfmt/binding-linux-ppc64-gnu': 0.52.0
'@oxfmt/binding-linux-riscv64-gnu': 0.52.0
'@oxfmt/binding-linux-riscv64-musl': 0.52.0
'@oxfmt/binding-linux-s390x-gnu': 0.52.0
'@oxfmt/binding-linux-x64-gnu': 0.52.0
'@oxfmt/binding-linux-x64-musl': 0.52.0
'@oxfmt/binding-openharmony-arm64': 0.52.0
'@oxfmt/binding-win32-arm64-msvc': 0.52.0
'@oxfmt/binding-win32-ia32-msvc': 0.52.0
'@oxfmt/binding-win32-x64-msvc': 0.52.0
oxlint@1.63.0:
oxlint@1.67.0:
optionalDependencies:
'@oxlint/binding-android-arm-eabi': 1.63.0
'@oxlint/binding-android-arm64': 1.63.0
'@oxlint/binding-darwin-arm64': 1.63.0
'@oxlint/binding-darwin-x64': 1.63.0
'@oxlint/binding-freebsd-x64': 1.63.0
'@oxlint/binding-linux-arm-gnueabihf': 1.63.0
'@oxlint/binding-linux-arm-musleabihf': 1.63.0
'@oxlint/binding-linux-arm64-gnu': 1.63.0
'@oxlint/binding-linux-arm64-musl': 1.63.0
'@oxlint/binding-linux-ppc64-gnu': 1.63.0
'@oxlint/binding-linux-riscv64-gnu': 1.63.0
'@oxlint/binding-linux-riscv64-musl': 1.63.0
'@oxlint/binding-linux-s390x-gnu': 1.63.0
'@oxlint/binding-linux-x64-gnu': 1.63.0
'@oxlint/binding-linux-x64-musl': 1.63.0
'@oxlint/binding-openharmony-arm64': 1.63.0
'@oxlint/binding-win32-arm64-msvc': 1.63.0
'@oxlint/binding-win32-ia32-msvc': 1.63.0
'@oxlint/binding-win32-x64-msvc': 1.63.0
'@oxlint/binding-android-arm-eabi': 1.67.0
'@oxlint/binding-android-arm64': 1.67.0
'@oxlint/binding-darwin-arm64': 1.67.0
'@oxlint/binding-darwin-x64': 1.67.0
'@oxlint/binding-freebsd-x64': 1.67.0
'@oxlint/binding-linux-arm-gnueabihf': 1.67.0
'@oxlint/binding-linux-arm-musleabihf': 1.67.0
'@oxlint/binding-linux-arm64-gnu': 1.67.0
'@oxlint/binding-linux-arm64-musl': 1.67.0
'@oxlint/binding-linux-ppc64-gnu': 1.67.0
'@oxlint/binding-linux-riscv64-gnu': 1.67.0
'@oxlint/binding-linux-riscv64-musl': 1.67.0
'@oxlint/binding-linux-s390x-gnu': 1.67.0
'@oxlint/binding-linux-x64-gnu': 1.67.0
'@oxlint/binding-linux-x64-musl': 1.67.0
'@oxlint/binding-openharmony-arm64': 1.67.0
'@oxlint/binding-win32-arm64-msvc': 1.67.0
'@oxlint/binding-win32-ia32-msvc': 1.67.0
'@oxlint/binding-win32-x64-msvc': 1.67.0
p-cancelable@2.1.1: {}

View File

@ -34,7 +34,7 @@ Use `orca` (or `orca-ide` on Linux) for:
- stopping or waiting on Orca-managed terminals
- creating and managing scheduled Orca automations
- accessing repos known to Orca
Do not use `orca` / `orca-ide` when plain shell tools are simpler and Orca state does not matter.
Do not use `orca` / `orca-ide` when plain shell tools are simpler and Orca state does not matter.
Examples:
@ -539,12 +539,12 @@ orca exec --command "keyboard inserttext \"text\"" --json # bypasses key event
### Browser Error Codes
| Error Code | Meaning | Recovery |
|-----------|---------|----------|
| `browser_no_tab` | No browser tab is open in this worktree | Open a tab, or use `--worktree all` to check other worktrees |
| `browser_stale_ref` | Ref is invalid (page changed since snapshot) | Run `orca snapshot` to get fresh refs |
| `browser_tab_not_found` | Tab index does not exist | Run `orca tab list` to see available tabs |
| `browser_error` | Error from the browser automation engine | Read the message for details; common causes: element not found, navigation timeout, JS error |
| Error Code | Meaning | Recovery |
| ----------------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `browser_no_tab` | No browser tab is open in this worktree | Open a tab, or use `--worktree all` to check other worktrees |
| `browser_stale_ref` | Ref is invalid (page changed since snapshot) | Run `orca snapshot` to get fresh refs |
| `browser_tab_not_found` | Tab index does not exist | Run `orca tab list` to see available tabs |
| `browser_error` | Error from the browser automation engine | Read the message for details; common causes: element not found, navigation timeout, JS error |
### Browser Worked Example

View File

@ -57,15 +57,15 @@ Why: `--wait` blocks until a matching message arrives or the timeout expires (de
**Group addresses** resolve to terminal handles:
| Group | Resolves To |
|-------|------------|
| `@all` | All terminal handles except sender |
| `@idle` | Handles where the agent is currently idle |
| `@claude` | Handles running Claude Code |
| `@codex` | Handles running Codex |
| `@opencode` | Handles running OpenCode |
| `@gemini` | Handles running Gemini |
| `@worktree:<id>` | All handles in a specific worktree |
| Group | Resolves To |
| ---------------- | ----------------------------------------- |
| `@all` | All terminal handles except sender |
| `@idle` | Handles where the agent is currently idle |
| `@claude` | Handles running Claude Code |
| `@codex` | Handles running Codex |
| `@opencode` | Handles running OpenCode |
| `@gemini` | Handles running Gemini |
| `@worktree:<id>` | All handles in a specific worktree |
Group messages fan out: one message per recipient, shared `thread_id`, independent read tracking.

View File

@ -526,9 +526,9 @@ describe('AgentBrowserBridge', () => {
expect(wc.on).toHaveBeenCalledWith('did-finish-load', expect.any(Function))
})
const finishListener = wc.on.mock.calls.find(([event]) => event === 'did-finish-load')?.[1] as
| (() => void)
| undefined
const finishListener = wc.on.mock.calls.find(
([event]) => event === 'did-finish-load'
)?.[1] as (() => void) | undefined
const failListener = wc.on.mock.calls.find(([event]) => event === 'did-fail-load')?.[1] as
| (() => void)
| undefined

View File

@ -104,6 +104,7 @@ Update snapshots with `vitest -u`.
## When to use this framework
Use this framework for **new shell-ready tests** where:
- You want the test to be easy to replicate manually
- The setup is shell-script-based (file creation, env vars)
- You want a declarative snapshot-driven style

View File

@ -130,9 +130,15 @@ describe('updater-nudge', () => {
it('bounded range match', () => {
expect(versionMatchesRange('1.1.5', { minVersion: '1.1.0', maxVersion: '1.1.19' })).toBe(true)
expect(versionMatchesRange('1.1.0', { minVersion: '1.1.0', maxVersion: '1.1.19' })).toBe(true)
expect(versionMatchesRange('1.1.19', { minVersion: '1.1.0', maxVersion: '1.1.19' })).toBe(true)
expect(versionMatchesRange('1.0.9', { minVersion: '1.1.0', maxVersion: '1.1.19' })).toBe(false)
expect(versionMatchesRange('1.2.0', { minVersion: '1.1.0', maxVersion: '1.1.19' })).toBe(false)
expect(versionMatchesRange('1.1.19', { minVersion: '1.1.0', maxVersion: '1.1.19' })).toBe(
true
)
expect(versionMatchesRange('1.0.9', { minVersion: '1.1.0', maxVersion: '1.1.19' })).toBe(
false
)
expect(versionMatchesRange('1.2.0', { minVersion: '1.1.0', maxVersion: '1.1.19' })).toBe(
false
)
})
it('upper-only range match', () => {

View File

@ -33,10 +33,18 @@ export async function fetchNudge(): Promise<NudgeConfig | null> {
return null
}
if (minVersion !== undefined && typeof minVersion !== 'string') {return null}
if (maxVersion !== undefined && typeof maxVersion !== 'string') {return null}
if (minVersion !== undefined && !isValidVersion(minVersion)) {return null}
if (maxVersion !== undefined && !isValidVersion(maxVersion)) {return null}
if (minVersion !== undefined && typeof minVersion !== 'string') {
return null
}
if (maxVersion !== undefined && typeof maxVersion !== 'string') {
return null
}
if (minVersion !== undefined && !isValidVersion(minVersion)) {
return null
}
if (maxVersion !== undefined && !isValidVersion(maxVersion)) {
return null
}
if (
minVersion !== undefined &&
maxVersion !== undefined &&

View File

@ -1784,7 +1784,9 @@ export default function RichMarkdownEditor({
targetModeLabel="This note"
triggerClassName="rich-markdown-review-note-send"
disabledTooltip="Note already sent"
onDelivered={(notes) => void clearDeliveredDiffComments(worktreeId, notes)}
onDelivered={(notes) =>
void clearDeliveredDiffComments(worktreeId, notes)
}
/>
}
/>

View File

@ -349,29 +349,31 @@ const DeleteWorktreeDialog = React.memo(function DeleteWorktreeDialog() {
</div>
)}
{!isMainWorktree && allowSkipConfirm && !canForceDelete && (
// Why: only show "Don't ask again" for the primary confirmation. The
// force-delete variant is a recovery path that shouldn't double as a
// preference checkpoint; see handleDelete for the matching guard.
<button
type="button"
role="checkbox"
aria-checked={dontAskAgain}
onClick={() => setDontAskAgain((prev) => !prev)}
className="flex items-center gap-2 rounded-sm px-1 py-1 text-xs text-foreground/80 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
>
<span
className={`flex size-4 items-center justify-center rounded-sm border transition-colors ${
dontAskAgain
? 'border-foreground bg-foreground text-background'
: 'border-muted-foreground bg-transparent'
}`}
{!isMainWorktree &&
allowSkipConfirm &&
!canForceDelete && (
// Why: only show "Don't ask again" for the primary confirmation. The
// force-delete variant is a recovery path that shouldn't double as a
// preference checkpoint; see handleDelete for the matching guard.
<button
type="button"
role="checkbox"
aria-checked={dontAskAgain}
onClick={() => setDontAskAgain((prev) => !prev)}
className="flex items-center gap-2 rounded-sm px-1 py-1 text-xs text-foreground/80 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
>
{dontAskAgain ? <Check className="size-3" strokeWidth={3} /> : null}
</span>
Don&apos;t ask again
</button>
)}
<span
className={`flex size-4 items-center justify-center rounded-sm border transition-colors ${
dontAskAgain
? 'border-foreground bg-foreground text-background'
: 'border-muted-foreground bg-transparent'
}`}
>
{dontAskAgain ? <Check className="size-3" strokeWidth={3} /> : null}
</span>
Don&apos;t ask again
</button>
)}
<DialogFooter>
<Button variant="outline" onClick={() => handleOpenChange(false)} disabled={isDeleting}>

View File

@ -1,7 +1,7 @@
import * as React from "react"
import { Progress as ProgressPrimitive } from "radix-ui"
import * as React from 'react'
import { Progress as ProgressPrimitive } from 'radix-ui'
import { cn } from "@/lib/utils"
import { cn } from '@/lib/utils'
function Progress({
className,
@ -11,10 +11,7 @@ function Progress({
return (
<ProgressPrimitive.Root
data-slot="progress"
className={cn(
"relative h-2 w-full overflow-hidden rounded-full bg-primary/20",
className
)}
className={cn('relative h-2 w-full overflow-hidden rounded-full bg-primary/20', className)}
{...props}
>
<ProgressPrimitive.Indicator

View File

@ -121,10 +121,16 @@ describe('diffViewStateCache', () => {
it('works with setWithLRU for diff-tab keys', () => {
const diffState = {
original: { cursorState: [], viewState: { scrollTop: 10, scrollTopWithoutViewZones: 10, scrollLeft: 0 } },
modified: { cursorState: [], viewState: { scrollTop: 20, scrollTopWithoutViewZones: 20, scrollLeft: 0 } },
original: {
cursorState: [],
viewState: { scrollTop: 10, scrollTopWithoutViewZones: 10, scrollLeft: 0 }
},
modified: {
cursorState: [],
viewState: { scrollTop: 20, scrollTopWithoutViewZones: 20, scrollLeft: 0 }
},
modelState: { unchangedRegions: [] }
} as unknown as (typeof diffViewStateCache extends Map<string, infer T> ? T : never)
} as unknown as typeof diffViewStateCache extends Map<string, infer T> ? T : never
setWithLRU(diffViewStateCache, 'diff-tab', diffState)

View File

@ -2,10 +2,7 @@
<html>
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, viewport-fit=cover"
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<title>Orca Web</title>
</head>
<body>

View File

@ -23,7 +23,7 @@ If the test could be rewritten to import the slice and drive it directly without
## E2E Assertions Must Target the DOM, Not the Store
`window.__store` is fine for *setup* (seeding a repo, pre-filling a draft, stubbing hydration timing) but the thing a spec finally `expect()`s on must be user-observable — `getByRole`, `toBeVisible`, `toHaveText`, `toContainText`. A spec that both writes to the store and reads it back is asserting that Zustand's setter works, not that Orca works.
`window.__store` is fine for _setup_ (seeding a repo, pre-filling a draft, stubbing hydration timing) but the thing a spec finally `expect()`s on must be user-observable — `getByRole`, `toBeVisible`, `toHaveText`, `toContainText`. A spec that both writes to the store and reads it back is asserting that Zustand's setter works, not that Orca works.
Why this matters: the `'create-worktree'` modal key lived on in the `activeModal` union long after `AddWorktreeDialog.tsx` was deleted in #710, so `store.openModal('create-worktree')` + `store.activeModal === 'create-worktree'` round-trips succeeded against a modal that rendered nothing. That tautology is what let #1186 (React error #31 in `StartFromField`) ship — the store-layer test passed while the composer actively crashed for real users.