Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
5ae51b3
Batch AI chat stream updates
JustYannicc Jul 3, 2026
18481a2
Batch cursor prompt stream updates
JustYannicc Jul 3, 2026
be66d99
perf(ai): batch Raycast useAI streaming
JustYannicc Jul 3, 2026
a1d8c7b
ci: add project regression checks
JustYannicc Jul 3, 2026
a1225c6
Add bundled TS import helper for tests
JustYannicc Jul 3, 2026
0799e71
fix(types): make renderer typecheck clean
JustYannicc Jul 3, 2026
835bf3a
ci(claude): fix review action on fork PRs
JustYannicc Jul 3, 2026
4605c88
fix(i18n): restore Italian parity checks
JustYannicc Jul 3, 2026
d4c6a9f
fix(pnpm): approve native build scripts
JustYannicc Jul 3, 2026
986c87a
perf: cache local icon asset existence checks
JustYannicc Jul 3, 2026
9e4eed3
Virtualize emoji grid list rendering
JustYannicc Jul 3, 2026
5245253
Memoize Phosphor icon resolution
JustYannicc Jul 3, 2026
cfe2ec3
Cache emoji caret session state
JustYannicc Jul 3, 2026
83d6b0b
Stabilize list item registry order
JustYannicc Jul 3, 2026
e03ad3e
perf(launcher): window command list rendering
JustYannicc Jul 3, 2026
f07b554
perf(grid): virtualize grid rendering
JustYannicc Jul 3, 2026
949a6fd
perf(icons): coalesce file icon IPC
JustYannicc Jul 3, 2026
6f06eb4
perf(settings): coalesce AI status polling
JustYannicc Jul 3, 2026
8ca7ec9
Remove root search ranking diagnostics
JustYannicc Jul 3, 2026
fb857f2
perf: optimize file search delete batches
JustYannicc Jul 3, 2026
dee7108
perf: memoize frecency sorting defaults
JustYannicc Jul 3, 2026
68cb050
Avoid interval file-index rebuilds
JustYannicc Jul 3, 2026
9f246ce
Avoid full script reads for command headers
JustYannicc Jul 3, 2026
12f951e
Optimize root search command scoring
JustYannicc Jul 3, 2026
a2737ce
perf(runtime): reduce extension and menubar churn
JustYannicc Jul 3, 2026
7ed6c2a
Speed up path-like file search queries
JustYannicc Jul 3, 2026
dff8539
Add file search perf harness
JustYannicc Jul 3, 2026
caa78e1
perf(browser-search): index hot query path
JustYannicc Jul 3, 2026
321d103
fix(browser-search): narrow indexed nickname candidates
JustYannicc Jul 3, 2026
644e72d
test: trim benchmark script eof whitespace
JustYannicc Jul 3, 2026
0007d73
perf(mac): reduce native polling and async IO stalls
JustYannicc Jul 3, 2026
6a43c57
Merge remote-tracking branch 'fork/codex/consolidate-validation-check…
JustYannicc Jul 3, 2026
5f84095
Merge remote-tracking branch 'fork/codex/consolidate-runtime-backgrou…
JustYannicc Jul 3, 2026
2a0d894
Merge remote-tracking branch 'fork/codex/consolidate-rendering-icons-…
JustYannicc Jul 3, 2026
50e7dd5
Merge remote-tracking branch 'fork/codex/consolidate-search-indexing'…
JustYannicc Jul 3, 2026
2916daf
Merge remote-tracking branch 'fork/codex/consolidate-ai-streaming-sta…
JustYannicc Jul 3, 2026
52288a0
Merge remote-tracking branch 'fork/codex/consolidate-native-async-io'…
JustYannicc Jul 3, 2026
057fbb8
perf(ai): batch stream IPC chunks
JustYannicc Jul 3, 2026
b73c39c
perf(ai): cache local model status probes
JustYannicc Jul 3, 2026
9dfbb5b
perf(ai): clean up stream abort listeners
JustYannicc Jul 3, 2026
7136d22
perf(camera): remove redundant mkdir subprocess
JustYannicc Jul 3, 2026
79a74fc
perf(audio): bulk-write captured WAV samples
JustYannicc Jul 3, 2026
31caa81
perf(settings): clean up Ollama pull listeners
JustYannicc Jul 3, 2026
3db732e
fix(audio): preserve idle meter conversion path
JustYannicc Jul 8, 2026
241809a
fix(runtime): address PR 530 review feedback
JustYannicc Jul 8, 2026
3855272
Merge remote-tracking branch 'origin/main' into repair/pr-556
JustYannicc Jul 12, 2026
5357009
ci: allow cross-platform lockfile install
JustYannicc Jul 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ on:

jobs:
claude-review:
# Fork PRs do not receive the OIDC token/secrets required by
# anthropics/claude-code-action on pull_request workflows.
if: github.event.pull_request.head.repo.full_name == github.repository
# Optional: Filter by PR author
# if: |
# github.event.pull_request.user.login == 'external-contributor' ||
Expand Down Expand Up @@ -41,4 +44,3 @@ jobs:
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options

56 changes: 56 additions & 0 deletions .github/workflows/project-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Project Checks

on:
pull_request:
branches:
- main
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read

concurrency:
group: project-checks-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test-i18n-build:
name: Tests, i18n, and build
runs-on: ubuntu-latest
timeout-minutes: 15
env:
CI: true
ELECTRON_SKIP_BINARY_DOWNLOAD: '1'
SUPERCMD_SKIP_ELECTRON_TESTS: '1'

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm
cache-dependency-path: package-lock.json

- name: Install dependencies without native postinstall scripts
# package.json pins darwin esbuild packages for release packaging; --force lets Ubuntu install the lockfile.
run: npm ci --ignore-scripts --force

- name: Run tests
run: npm test

- name: Check i18n
run: npm run check:i18n

- name: Build main process
run: npm run build:main

- name: Build renderer
run: npm run build:renderer
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
cache: npm

- name: Install dependencies
run: npm ci
run: npm ci --force

- name: Run node test suite
run: npm test
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
"build": "npm run build:main && npm run build:renderer && npm run build:native",
"build:main": "tsc -p tsconfig.main.json && cp src/main/emoji-data.json dist/main/emoji-data.json",
"build:renderer": "vite build",
"measure:launcher-command-list": "node scripts/measure-launcher-command-list-render.mjs",
"check:i18n": "node scripts/check-i18n.mjs",
"perf:file-search": "node scripts/file-search-perf-harness.mjs",
"test": "node --test 'scripts/test-*.mjs'",
"build:native": "node scripts/build-native.mjs",
"ensure:cross-arch-esbuild": "node scripts/ensure-cross-arch-esbuild.mjs",
Expand Down
5 changes: 5 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
allowBuilds:
electron: true
esbuild: true
extract-file-icon: true
node-window-manager: true
106 changes: 106 additions & 0 deletions scripts/bench-ax-bfs-queue.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import Foundation

private struct Node {
let firstChild: Int
let childCount: Int
}

private let depthLimit = 8
private let branching = 3
private var nodes: [Node] = []
private var frontier: [(index: Int, depth: Int)] = [(0, 0)]

nodes.reserveCapacity(9_841)
nodes.append(Node(firstChild: -1, childCount: 0))

var frontierIndex = 0
while frontierIndex < frontier.count {
let (nodeIndex, depth) = frontier[frontierIndex]
frontierIndex += 1
guard depth < depthLimit else { continue }

let firstChild = nodes.count
for _ in 0..<branching {
nodes.append(Node(firstChild: -1, childCount: 0))
frontier.append((nodes.count - 1, depth + 1))
}
nodes[nodeIndex] = Node(firstChild: firstChild, childCount: branching)
}

private let roots = [0, 1, 2].filter { $0 < nodes.count }
private let maxDepth = 8
private let maxElements = 240
private let iterations = 20_000

@inline(never)
private func removeFirstTraversal() -> Int {
var queue = roots.map { ($0, 0) }
var inspected = 0
var checksum = 0

while let (nodeIndex, depth) = queue.first {
queue.removeFirst()
inspected += 1
if inspected > maxElements { break }

checksum &+= nodeIndex &+ depth
if depth >= maxDepth { continue }

let node = nodes[nodeIndex]
if node.childCount > 0 {
for offset in 0..<node.childCount {
queue.append((node.firstChild + offset, depth + 1))
}
}
}
return checksum
}

@inline(never)
private func cursorTraversal() -> Int {
var queue = roots.map { ($0, 0) }
var queueIndex = 0
var inspected = 0
var checksum = 0

while queueIndex < queue.count {
let (nodeIndex, depth) = queue[queueIndex]
queueIndex += 1
inspected += 1
if inspected > maxElements { break }

checksum &+= nodeIndex &+ depth
if depth >= maxDepth { continue }

let node = nodes[nodeIndex]
if node.childCount > 0 {
for offset in 0..<node.childCount {
queue.append((node.firstChild + offset, depth + 1))
}
}
}
return checksum
}

@inline(never)
private func measure(_ label: String, _ block: () -> Int) -> (label: String, ms: Double, checksum: Int) {
var checksum = 0
let start = DispatchTime.now().uptimeNanoseconds
for _ in 0..<iterations {
checksum &+= block()
}
let elapsed = DispatchTime.now().uptimeNanoseconds - start
return (label, Double(elapsed) / 1_000_000.0, checksum)
}

let removeFirstWarmup = removeFirstTraversal()
let cursorWarmup = cursorTraversal()
precondition(removeFirstWarmup == cursorWarmup)

let removeFirst = measure("removeFirst", removeFirstTraversal)
let cursor = measure("cursor", cursorTraversal)

print("nodes=\(nodes.count) roots=\(roots.count) maxDepth=\(maxDepth) maxElements=\(maxElements) iterations=\(iterations)")
print("\(removeFirst.label): \(String(format: "%.2f", removeFirst.ms)) ms checksum=\(removeFirst.checksum)")
print("\(cursor.label): \(String(format: "%.2f", cursor.ms)) ms checksum=\(cursor.checksum)")
print("speedup: \(String(format: "%.2fx", removeFirst.ms / cursor.ms))")
101 changes: 101 additions & 0 deletions scripts/bench-script-command-discovery.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env node

import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { performance } from 'node:perf_hooks';
import { loadScriptCommandRunner } from './lib/script-command-runner-harness.mjs';

const fileCount = Number(process.env.SUPERCMD_BENCH_SCRIPT_COUNT || 40);
const bodyBytesPerFile = Number(process.env.SUPERCMD_BENCH_SCRIPT_BODY_BYTES || 1024 * 1024);

function formatBytes(bytes) {
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KiB`;
return `${(bytes / (1024 * 1024)).toFixed(1)} MiB`;
}

function makeLargeScript(title, bodyBytes) {
const header = `#!/bin/bash
# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title ${title}
# @raycast.mode fullOutput

# Optional parameters:
# @raycast.packageName Benchmark
# @raycast.icon ⚡
# @raycast.description Large script command fixture
# @raycast.needsConfirmation false

exit 0
`;
const line = `# ${'x'.repeat(253)}\n`;
const repeatCount = Math.max(0, Math.ceil(bodyBytes / Buffer.byteLength(line)));
return header + line.repeat(repeatCount);
}

function snapshot(metrics) {
return {
readFileSyncCalls: metrics.readFileSyncCalls,
readFileSyncBytes: metrics.readFileSyncBytes,
readSyncCalls: metrics.readSyncCalls,
readSyncBytes: metrics.readSyncBytes,
openSyncCalls: metrics.openSyncCalls,
totalBytes: metrics.readFileSyncBytes + metrics.readSyncBytes,
};
}

function printMetric(label, durationMs, metricSnapshot) {
console.log(`${label}: ${durationMs.toFixed(1)}ms`);
console.log(` readFileSync: ${metricSnapshot.readFileSyncCalls} calls, ${formatBytes(metricSnapshot.readFileSyncBytes)}`);
console.log(` readSync: ${metricSnapshot.readSyncCalls} calls, ${formatBytes(metricSnapshot.readSyncBytes)}`);
console.log(` total runner bytes read: ${formatBytes(metricSnapshot.totalBytes)}`);
}

const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'supercmd-script-bench-'));
const scriptsDir = path.join(tempRoot, 'script-commands');
const userDataDir = path.join(tempRoot, 'user-data');
fs.mkdirSync(scriptsDir, { recursive: true });
fs.mkdirSync(userDataDir, { recursive: true });

try {
for (let i = 0; i < fileCount; i += 1) {
const scriptPath = path.join(scriptsDir, `large-command-${String(i + 1).padStart(3, '0')}.sh`);
fs.writeFileSync(scriptPath, makeLargeScript(`Large Command ${i + 1}`, bodyBytesPerFile), {
mode: 0o755,
});
}

process.env.SUPERCMD_SCRIPT_COMMAND_PATHS = scriptsDir;
const { module: runner, metrics, resetMetrics } = await loadScriptCommandRunner({
userDataDir,
scriptCommandFolders: [],
instrumentFs: true,
});

resetMetrics();
const discoveryStart = performance.now();
const commands = runner.discoverScriptCommands();
const discoveryMs = performance.now() - discoveryStart;
const discoveryMetrics = snapshot(metrics);

if (commands.length !== fileCount) {
throw new Error(`Expected ${fileCount} commands, discovered ${commands.length}`);
}

resetMetrics();
const executeStart = performance.now();
await runner.executeScriptCommand(commands[0].id);
const executeMs = performance.now() - executeStart;
const executeMetrics = snapshot(metrics);

console.log('Script command discovery benchmark');
console.log(`files: ${fileCount}`);
console.log(`body bytes per file: ${formatBytes(bodyBytesPerFile)}`);
printMetric('discovery', discoveryMs, discoveryMetrics);
printMetric('cached execution shebang lookup', executeMs, executeMetrics);
} finally {
delete process.env.SUPERCMD_SCRIPT_COMMAND_PATHS;
fs.rmSync(tempRoot, { recursive: true, force: true });
}
Loading
Loading