From 4e0e46dc2628b6775fa8c3a59e1255bcc8a31c30 Mon Sep 17 00:00:00 2001 From: Johnny Huynh <27847622+johnnyhuy@users.noreply.github.com> Date: Mon, 19 Oct 2026 20:13:35 +1100 Subject: [PATCH] feat: implement Figma workbench screens with UI test coverage Co-authored-by: OpenAI Codex --- .github/workflows/e2e.yml | 8 +- README.md | 10 + src/main/index.ts | 109 +- src/main/rpc.ts | 45 +- src/main/workbench-ipc.ts | 207 +++ src/main/workbench.ts | 366 +++++ src/preload/index.ts | 34 +- src/renderer/App.tsx | 1180 ++++++++------ src/renderer/api.ts | 72 +- .../assets/fonts/IBMPlexMono-LICENSE.txt | 93 ++ .../assets/fonts/IBMPlexMono-Regular.ttf | Bin 0 -> 135580 bytes .../assets/fonts/JetBrainsMono-LICENSE.txt | 93 ++ .../assets/fonts/JetBrainsMono-Variable.ttf | Bin 0 -> 187208 bytes .../assets/workbench/activity-terminal.svg | 6 + src/renderer/assets/workbench/appearance.svg | 6 + src/renderer/assets/workbench/changes.svg | 10 + src/renderer/assets/workbench/check.svg | 5 + .../assets/workbench/chevron-down.svg | 5 + src/renderer/assets/workbench/file-code.svg | 8 + src/renderer/assets/workbench/file.svg | 8 + src/renderer/assets/workbench/folder-open.svg | 5 + src/renderer/assets/workbench/folder.svg | 5 + .../assets/workbench/message-square.svg | 5 + src/renderer/assets/workbench/panel-left.svg | 6 + src/renderer/assets/workbench/paperclip.svg | 5 + src/renderer/assets/workbench/plus.svg | 6 + src/renderer/assets/workbench/search.svg | 6 + src/renderer/assets/workbench/settings.svg | 8 + src/renderer/assets/workbench/shield.svg | 6 + src/renderer/assets/workbench/skills.svg | 5 + .../assets/workbench/starter-changes.svg | 10 + .../assets/workbench/starter-search.svg | 6 + src/renderer/assets/workbench/terminal.svg | 6 + .../assets/workbench/welcome-mark.svg | 10 + src/renderer/components/BracketButton.tsx | 14 +- src/renderer/components/CommandPalette.tsx | 293 ++++ src/renderer/components/PierreDiff.tsx | 7 +- src/renderer/components/WorkbenchControls.tsx | 358 ++++ src/renderer/components/WorkbenchViews.tsx | 822 ++++++++++ src/renderer/design-system/fonts.css | 16 + src/renderer/main.tsx | 5 +- src/renderer/useWorkbench.ts | 519 ++++++ src/renderer/workbench.css | 1437 +++++++++++++++++ tests/e2e/app.test.ts | 494 +++++- tests/e2e/setup.ts | 41 + tests/fixtures/pi-rpc.cjs | 154 ++ tests/integration/CommandPalette.test.tsx | 80 + tests/integration/Composer.test.tsx | 55 + tests/integration/FilesView.test.tsx | 73 + tests/integration/SettingsView.test.tsx | 123 ++ tests/integration/setup.ts | 8 +- tests/unit/skills.test.ts | 73 + tests/unit/workbench.test.ts | 269 +++ vitest.e2e.config.ts | 3 +- 54 files changed, 6585 insertions(+), 613 deletions(-) create mode 100644 src/main/workbench-ipc.ts create mode 100644 src/main/workbench.ts create mode 100644 src/renderer/assets/fonts/IBMPlexMono-LICENSE.txt create mode 100644 src/renderer/assets/fonts/IBMPlexMono-Regular.ttf create mode 100644 src/renderer/assets/fonts/JetBrainsMono-LICENSE.txt create mode 100644 src/renderer/assets/fonts/JetBrainsMono-Variable.ttf create mode 100644 src/renderer/assets/workbench/activity-terminal.svg create mode 100644 src/renderer/assets/workbench/appearance.svg create mode 100644 src/renderer/assets/workbench/changes.svg create mode 100644 src/renderer/assets/workbench/check.svg create mode 100644 src/renderer/assets/workbench/chevron-down.svg create mode 100644 src/renderer/assets/workbench/file-code.svg create mode 100644 src/renderer/assets/workbench/file.svg create mode 100644 src/renderer/assets/workbench/folder-open.svg create mode 100644 src/renderer/assets/workbench/folder.svg create mode 100644 src/renderer/assets/workbench/message-square.svg create mode 100644 src/renderer/assets/workbench/panel-left.svg create mode 100644 src/renderer/assets/workbench/paperclip.svg create mode 100644 src/renderer/assets/workbench/plus.svg create mode 100644 src/renderer/assets/workbench/search.svg create mode 100644 src/renderer/assets/workbench/settings.svg create mode 100644 src/renderer/assets/workbench/shield.svg create mode 100644 src/renderer/assets/workbench/skills.svg create mode 100644 src/renderer/assets/workbench/starter-changes.svg create mode 100644 src/renderer/assets/workbench/starter-search.svg create mode 100644 src/renderer/assets/workbench/terminal.svg create mode 100644 src/renderer/assets/workbench/welcome-mark.svg create mode 100644 src/renderer/components/CommandPalette.tsx create mode 100644 src/renderer/components/WorkbenchControls.tsx create mode 100644 src/renderer/components/WorkbenchViews.tsx create mode 100644 src/renderer/useWorkbench.ts create mode 100644 src/renderer/workbench.css create mode 100644 tests/e2e/setup.ts create mode 100755 tests/fixtures/pi-rpc.cjs create mode 100644 tests/integration/CommandPalette.test.tsx create mode 100644 tests/integration/Composer.test.tsx create mode 100644 tests/integration/FilesView.test.tsx create mode 100644 tests/integration/SettingsView.test.tsx create mode 100644 tests/unit/skills.test.ts create mode 100644 tests/unit/workbench.test.ts diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index de3131a..c7702d0 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -16,12 +16,6 @@ jobs: with: install: true - run: bun install --frozen-lockfile - - run: npm install -g @earendil-works/pi-coding-agent - - run: bunx tsc -p tsconfig.main.json - - run: bunx tsc -p tsconfig.preload.json - - run: bunx vite build - - run: mise run dev:vite & - - run: bunx wait-on http://localhost:5173 - run: mise run test:e2e - name: upload test artefacts if: always() @@ -31,4 +25,4 @@ jobs: path: | /tmp/pidex-*.png test-results/ - if-no-files-found: ignore \ No newline at end of file + if-no-files-found: ignore diff --git a/README.md b/README.md index b320451..31b1175 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,16 @@ $ mise run dev # starts Vite + Electron For a production build: `mise run build` then `mise run start`. Native installers: `mise run package`. +### Tests + +```bash +$ bun run test:unit # parsers, session archives, workspace and skill discovery +$ bun run test:integration # React component behavior in jsdom +$ bun run test:e2e # real Electron UI on macOS +``` + +The E2E suite compiles main/preload, starts an isolated renderer server on a free port, and creates temporary Git workspaces, sessions, and app settings. It uses a deterministic Pi RPC fixture, so it needs no provider credentials. Screenshots are written to `test-results/workbench/`. Every PR runs all three test lanes; `mise run build` also runs lint, typecheck, unit and component tests. + ## Architecture ``` diff --git a/src/main/index.ts b/src/main/index.ts index f6001e4..8dc8f40 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1,10 +1,14 @@ import { app, BrowserWindow, dialog, ipcMain } from 'electron'; import fs from 'fs'; import path from 'path'; -import { listSessions, listWorkspaces, SESSIONS_ROOT } from './sessions'; +import { listSessions, listWorkspaces } from './sessions'; +import { sessionPath } from './workbench'; import { RpcSession } from './rpc'; +import { registerWorkbench, sessionDefaults } from './workbench-ipc'; const isDev = !app.isPackaged; +if (isDev && process.env.PIDEX_E2E_USER_DATA) + app.setPath('userData', process.env.PIDEX_E2E_USER_DATA); const sessions = new Map(); let sessionSeq = 0; let mainWindow: BrowserWindow | null = null; @@ -14,10 +18,13 @@ function customWorkspacesFile(): string { } function readCustomWorkspaces(): string[] { + if (process.env.PIDEX_E2E_CWD) return [process.env.PIDEX_E2E_CWD]; try { const raw = fs.readFileSync(customWorkspacesFile(), 'utf8'); const parsed = JSON.parse(raw); - return Array.isArray(parsed) ? parsed.filter((p): p is string => typeof p === 'string') : []; + return Array.isArray(parsed) + ? parsed.filter((p): p is string => typeof p === 'string') + : []; } catch { return []; } @@ -26,7 +33,10 @@ function readCustomWorkspaces(): string[] { function addCustomWorkspace(cwd: string): void { const existing = readCustomWorkspaces(); if (!existing.includes(cwd)) { - fs.writeFileSync(customWorkspacesFile(), JSON.stringify([...existing, cwd], null, 2)); + fs.writeFileSync( + customWorkspacesFile(), + JSON.stringify([...existing, cwd], null, 2), + ); } } @@ -53,8 +63,12 @@ function createWindow() { }); if (isDev) { - mainWindow.loadURL('http://localhost:5173'); - mainWindow.webContents.openDevTools({ mode: 'detach' }); + mainWindow.loadURL( + (process.env.PIDEX_E2E_CWD && process.env.PIDEX_E2E_RENDERER_URL) || + 'http://localhost:5173', + ); + if (!process.env.PIDEX_E2E_CWD) + mainWindow.webContents.openDevTools({ mode: 'detach' }); } else { mainWindow.loadFile(path.join(__dirname, '..', 'renderer', 'index.html')); } @@ -64,7 +78,11 @@ function createWindow() { }); } -ipcMain.handle('pidex:workspaces', () => listWorkspaces(readCustomWorkspaces())); +ipcMain.handle('pidex:workspaces', () => + listWorkspaces(readCustomWorkspaces()), +); + +registerWorkbench(() => mainWindow, readCustomWorkspaces, sessions); ipcMain.handle('pidex:workspace:add', async () => { if (!mainWindow) return { error: 'no window' }; @@ -72,7 +90,8 @@ ipcMain.handle('pidex:workspace:add', async () => { title: 'Add workspace', properties: ['openDirectory', 'createDirectory'], }); - if (result.canceled || result.filePaths.length === 0) return { error: 'cancelled' }; + if (result.canceled || result.filePaths.length === 0) + return { error: 'cancelled' }; const cwd = result.filePaths[0]; addCustomWorkspace(cwd); return { cwd }; @@ -85,14 +104,21 @@ ipcMain.handle('pidex:sessions', (_e, dirName: string) => { ipcMain.handle( 'pidex:session/open', - async (_e, req: { cwd: string; sessionFile?: string }) => { + async (_e, req: { cwd: string; sessionFile?: string; fork?: boolean }) => { const cwd = typeof req?.cwd === 'string' ? req.cwd : ''; - const sessionFile = typeof req?.sessionFile === 'string' ? req.sessionFile : undefined; + const sessionFile = + typeof req?.sessionFile === 'string' ? req.sessionFile : undefined; if (!cwd || !fs.existsSync(cwd)) { return { error: 'workspace path does not exist' }; } - if (sessionFile && !path.resolve(sessionFile).startsWith(SESSIONS_ROOT)) { - return { error: 'session file outside pi sessions root' }; + if (sessionFile) { + try { + await sessionPath(sessionFile); + } catch { + return { + error: 'session file outside pi sessions root or unavailable', + }; + } } const id = `s${++sessionSeq}`; @@ -103,11 +129,55 @@ ipcMain.handle( const message = err instanceof Error ? err.message : 'could not start pi'; return { error: message }; } - session.onEvent = (sessionId, event) => sendToRenderer('pidex:session:event', { sessionId, event }); - session.onExit = sessionId => sendToRenderer('pidex:session:exit', { sessionId }); + session.onEvent = (sessionId, event) => + sendToRenderer('pidex:session:event', { sessionId, event }); + session.onExit = (sessionId) => + sendToRenderer('pidex:session:exit', { sessionId }); sessions.set(id, session); - const [state, messages] = await Promise.all([session.getState(), session.getMessages()]); + if (req.fork && sessionFile) { + const cloned = await session.command({ type: 'clone' }); + if ( + !cloned.success || + (cloned.data as { cancelled?: boolean } | undefined)?.cancelled + ) { + sessions.delete(id); + session.dispose(); + return { error: cloned.error ?? 'Session fork was cancelled.' }; + } + } + + if (!sessionFile) { + const defaults = await sessionDefaults(cwd); + if (defaults.model && defaults.provider) { + const changed = await session.command({ + type: 'set_model', + provider: defaults.provider, + modelId: defaults.model, + }); + if (!changed.success) { + sessions.delete(id); + session.dispose(); + return { + error: changed.error ?? 'Could not apply the default model.', + }; + } + } + const thinking = await session.command({ + type: 'set_thinking_level', + level: defaults.thinking, + }); + if (!thinking.success) { + sessions.delete(id); + session.dispose(); + return { error: thinking.error ?? 'Could not apply reasoning effort.' }; + } + } + + const [state, messages] = await Promise.all([ + session.getState(), + session.getMessages(), + ]); const launchError = session.launchError(); if (launchError) { sessions.delete(id); @@ -117,7 +187,9 @@ ipcMain.handle( return { sessionId: id, state: state.success ? state.data : null, - messages: messages.success ? (messages.data as { messages?: unknown[] })?.messages ?? [] : [], + messages: messages.success + ? ((messages.data as { messages?: unknown[] })?.messages ?? []) + : [], }; }, ); @@ -127,7 +199,10 @@ ipcMain.handle( async (_e, req: { sessionId: string; text: string; streaming: boolean }) => { const session = sessions.get(req?.sessionId ?? ''); if (!session) return { error: 'no such session' }; - const response = await session.prompt(String(req.text ?? ''), Boolean(req.streaming)); + const response = await session.prompt( + String(req.text ?? ''), + Boolean(req.streaming), + ); return { success: response.success, error: response.error }; }, ); @@ -141,7 +216,7 @@ ipcMain.handle('pidex:session/commands', async (_e, sessionId: string) => { if (!session) return { commands: [] }; const response = await session.getCommands(); const data = response.data as { commands?: unknown[] } | undefined; - return { commands: response.success ? data?.commands ?? [] : [] }; + return { commands: response.success ? (data?.commands ?? []) : [] }; }); ipcMain.handle('pidex:session/close', (_e, sessionId: string) => { diff --git a/src/main/rpc.ts b/src/main/rpc.ts index 0e4deb8..975dcec 100644 --- a/src/main/rpc.ts +++ b/src/main/rpc.ts @@ -3,7 +3,8 @@ import fs from 'fs'; import os from 'os'; import path from 'path'; -const PI_MISSING = 'Could not find the pi command. Install it, or set PIDEX_PI to the binary.'; +const PI_MISSING = + 'Could not find the pi command. Install it, or set PIDEX_PI to the binary.'; type RpcEvent = Record & { type: string }; @@ -63,7 +64,7 @@ export function resolvePi( function childEnv(env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv { const current = (env.PATH ?? '').split(path.delimiter).filter(Boolean); - const extra = piPathDirs().filter(dir => !current.includes(dir)); + const extra = piPathDirs().filter((dir) => !current.includes(dir)); return { ...env, PATH: [...extra, ...current].join(path.delimiter) }; } @@ -75,16 +76,25 @@ class RpcSession { private seq = 0; private closed = false; private failed: string | null = null; - private pending = new Map void; timer: NodeJS.Timeout }>(); + private pending = new Map< + string, + { resolve: (r: RpcResponse) => void; timer: NodeJS.Timeout } + >(); onEvent: (sessionId: string, event: RpcEvent) => void = () => {}; onExit: (sessionId: string, code: number | null) => void = () => {}; - constructor(id: string, cwd: string, sessionFile?: string) { + constructor( + id: string, + cwd: string, + sessionFile?: string, + ephemeral = false, + ) { this.id = id; this.cwd = cwd; const bin = resolvePi(); if (!bin) throw new Error(PI_MISSING); const args = ['--mode', 'rpc']; + if (ephemeral) args.push('--no-session'); if (sessionFile) args.push('--session', sessionFile); this.proc = spawn(bin, args, { cwd, @@ -93,16 +103,16 @@ class RpcSession { }); this.proc.stdout!.setEncoding('utf8'); - this.proc.stdout!.on('data', chunk => this.handleChunk(chunk)); + this.proc.stdout!.on('data', (chunk) => this.handleChunk(chunk)); this.proc.stderr!.setEncoding('utf8'); this.proc.stderr!.on('data', () => {}); this.proc.stdin?.on('error', () => {}); - this.proc.on('error', err => { + this.proc.on('error', (err) => { const code = (err as NodeJS.ErrnoException).code; this.failed = code === 'ENOENT' ? PI_MISSING : err.message; this.close(null); }); - this.proc.on('exit', code => { + this.proc.on('exit', (code) => { this.failed ??= 'process exited'; this.close(code); }); @@ -160,10 +170,16 @@ class RpcSession { }); } const id = `req-${++this.seq}`; - return new Promise(resolve => { + return new Promise((resolve) => { const timer = setTimeout(() => { this.pending.delete(id); - resolve({ type: 'response', command: String(cmd.type ?? ''), success: false, id, error: 'timeout' }); + resolve({ + type: 'response', + command: String(cmd.type ?? ''), + success: false, + id, + error: 'timeout', + }); }, 30000); this.pending.set(id, { resolve, timer }); try { @@ -171,8 +187,15 @@ class RpcSession { } catch (err) { clearTimeout(timer); this.pending.delete(id); - const message = err instanceof Error ? err.message : 'could not write to pi'; - resolve({ type: 'response', command: String(cmd.type ?? ''), success: false, id, error: message }); + const message = + err instanceof Error ? err.message : 'could not write to pi'; + resolve({ + type: 'response', + command: String(cmd.type ?? ''), + success: false, + id, + error: message, + }); } }); } diff --git a/src/main/workbench-ipc.ts b/src/main/workbench-ipc.ts new file mode 100644 index 0000000..e9c397e --- /dev/null +++ b/src/main/workbench-ipc.ts @@ -0,0 +1,207 @@ +import { app, dialog, ipcMain, shell, type BrowserWindow } from 'electron'; +import fs from 'fs/promises'; +import os from 'os'; +import path from 'path'; +import { RpcSession } from './rpc'; +import { listWorkspaces } from './sessions'; +import { + DEFAULTS, + filePatch, + git, + inside, + inspectWorkspace, + listSkills, + readSession, + readText, + validateDefaults, + workspacePath, + type Defaults, +} from './workbench'; + +export function registerWorkbench( + getWindow: () => BrowserWindow | null, + customWorkspaces: () => string[], + sessions: Map, +) { + const settingsFile = () => + path.join(app.getPath('userData'), 'session-defaults.json'); + async function knownWorkspace(cwd: unknown): Promise { + if (typeof cwd !== 'string') throw new Error('Choose a workspace first.'); + const known = await listWorkspaces(customWorkspaces()); + if (!known.some((w) => w.cwd === cwd)) + throw new Error('Unknown workspace.'); + return cwd; + } + async function readDefaults(): Promise> { + try { + const parsed = JSON.parse(await fs.readFile(settingsFile(), 'utf8')); + return parsed && typeof parsed === 'object' && !Array.isArray(parsed) + ? parsed + : {}; + } catch { + return {}; + } + } + const handle = ( + channel: string, + fn: (...args: any[]) => Promise, + ) => { + ipcMain.handle(`pidex:${channel}`, async (_event, ...args) => { + try { + return { data: await fn(...args) }; + } catch (error) { + return { + error: error instanceof Error ? error.message : 'The action failed.', + }; + } + }); + }; + handle('workspace:inspect', async (cwd) => + inspectWorkspace(await knownWorkspace(cwd)), + ); + handle('workspace:read', async (cwd, file) => + readText(await workspacePath(await knownWorkspace(cwd), file)), + ); + handle('workspace:patch', async (cwd, file, staged, untracked) => + filePatch( + await knownWorkspace(cwd), + file, + Boolean(staged), + Boolean(untracked), + ), + ); + handle('workspace:git', async (cwd, action, file) => { + cwd = await knownWorkspace(cwd); + if (action === 'stage' || action === 'unstage') { + if ( + typeof file !== 'string' || + !file || + path.isAbsolute(file) || + !inside(path.resolve(cwd), path.resolve(cwd, file)) + ) + throw new Error('Invalid workspace file.'); + } + if (action === 'stage') { + await workspacePath(cwd, file).catch(async () => { + // A deleted tracked file is still a valid staging target. + await git(cwd, [ + '--literal-pathspecs', + 'ls-files', + '--error-unmatch', + '--', + file, + ]); + }); + await git(cwd, ['--literal-pathspecs', 'add', '--', file]); + } else if (action === 'stage-all') + await git(cwd, ['add', '--all', '--', '.']); + else if (action === 'unstage') { + // git restore --staged also handles paths containing glob metacharacters. + await git(cwd, [ + '--literal-pathspecs', + 'restore', + '--staged', + '--', + file, + ]); + } else if (action === 'commit') { + if (typeof file !== 'string' || !file.trim()) + throw new Error('Enter a commit message.'); + await git(cwd, ['commit', '-m', file.trim()]); + } else throw new Error('Unsupported Git action.'); + return inspectWorkspace(cwd); + }); + handle('session:preview', async (file) => readSession(file)); + handle('workspace:skills', async (cwd) => + listSkills(await knownWorkspace(cwd)), + ); + handle('workspace:open', async (cwd) => { + const error = await shell.openPath(await knownWorkspace(cwd)); + if (error) throw new Error(error); + }); + handle('workspace:attach', async () => { + const win = getWindow(); + if (!win) return []; + const result = await dialog.showOpenDialog(win, { + title: 'Reference files in your prompt', + properties: ['openFile', 'multiSelections'], + }); + return result.canceled ? [] : result.filePaths; + }); + handle( + 'settings:get', + async (cwd) => + (await readDefaults())[await knownWorkspace(cwd)] ?? DEFAULTS, + ); + handle('settings:save', async (cwd, value) => { + cwd = await knownWorkspace(cwd); + const settings = await readDefaults(); + const defaults = validateDefaults(value); + settings[cwd] = defaults; + await fs.mkdir(app.getPath('userData'), { recursive: true }); + const tmp = `${settingsFile()}.tmp`; + await fs.writeFile(tmp, JSON.stringify(settings, null, 2)); + await fs.rename(tmp, settingsFile()); + return defaults; + }); + handle('settings:providers', async () => { + const dir = path.join(os.homedir(), '.pi', 'agent'); + await fs.mkdir(dir, { recursive: true }); + const error = await shell.openPath(dir); + if (error) throw new Error(error); + }); + handle('models:list', async (cwd) => { + cwd = await knownWorkspace(cwd); + const existing = [...sessions.values()].find((s) => s.cwd === cwd); + const runtime = + existing ?? new RpcSession('model-probe', cwd, undefined, true); + try { + const response = await runtime.command({ type: 'get_available_models' }); + if (!response.success) + throw new Error(response.error ?? 'Could not load models.'); + const data = response.data as { + models?: { + id: string; + name?: string; + provider: string; + contextWindow?: number; + reasoning?: boolean; + }[]; + }; + return (data.models ?? []).map((m) => ({ + id: m.id, + name: m.name ?? m.id, + provider: m.provider, + contextWindow: m.contextWindow, + reasoning: m.reasoning, + })); + } finally { + if (!existing) runtime.dispose(); + } + }); + handle('session:model', async (id, provider, modelId) => { + const runtime = sessions.get(id); + if (!runtime) throw new Error('Resume the session to change its model.'); + const result = await runtime.command({ + type: 'set_model', + provider, + modelId, + }); + if (!result.success) + throw new Error(result.error ?? 'Could not change model.'); + }); +} + +export async function sessionDefaults(cwd: string): Promise { + try { + const all = JSON.parse( + await fs.readFile( + path.join(app.getPath('userData'), 'session-defaults.json'), + 'utf8', + ), + ); + return validateDefaults(all[cwd] ?? DEFAULTS); + } catch { + return DEFAULTS; + } +} diff --git a/src/main/workbench.ts b/src/main/workbench.ts new file mode 100644 index 0000000..9b63c94 --- /dev/null +++ b/src/main/workbench.ts @@ -0,0 +1,366 @@ +import { execFile } from 'child_process'; +import fs from 'fs/promises'; +import os from 'os'; +import path from 'path'; +import { promisify } from 'util'; +import { SESSIONS_ROOT } from './sessions'; + +const exec = promisify(execFile); +const OMIT = new Set([ + '.git', + 'node_modules', + 'dist', + 'out', + '.next', + '.venv', + 'coverage', +]); +const MAX_TEXT = 1024 * 1024; + +export type GitChange = { + path: string; + additions: number; + deletions: number; + staged: boolean; + untracked: boolean; +}; +export type WorkspaceDetails = { + branch: string; + changes: GitChange[]; + files: string[]; + gitError?: string; +}; +export type Defaults = { model: string; provider: string; thinking: string }; +export type SkillInfo = { + name: string; + description: string; + file: string; + source: 'Workspace' | 'Global'; +}; +export const DEFAULTS: Defaults = { + model: '', + provider: '', + thinking: 'medium', +}; + +export function inside(root: string, file: string): boolean { + const relative = path.relative(root, file); + return ( + relative !== '..' && + !relative.startsWith(`..${path.sep}`) && + !path.isAbsolute(relative) + ); +} + +export async function workspacePath( + cwd: string, + file: string, +): Promise { + if (typeof file !== 'string' || !file || path.isAbsolute(file)) + throw new Error('Choose a workspace file.'); + const root = await fs.realpath(cwd); + const target = await fs.realpath(path.resolve(root, file)); + if (!inside(root, target)) throw new Error('File is outside this workspace.'); + return target; +} + +export async function readText(file: string): Promise { + const handle = await fs.open(file, 'r'); + try { + const stat = await handle.stat(); + if (!stat.isFile() || stat.size > MAX_TEXT) + throw new Error('Preview supports text files up to 1 MB.'); + const buffer = await handle.readFile(); + if (buffer.includes(0)) + throw new Error('Binary files cannot be previewed.'); + return buffer.toString('utf8'); + } finally { + await handle.close(); + } +} + +export async function git(cwd: string, args: string[]): Promise { + const { stdout } = await exec( + 'git', + ['--no-pager', '-c', 'core.quotePath=false', ...args], + { + cwd, + timeout: 15_000, + maxBuffer: 8 * MAX_TEXT, + encoding: 'utf8', + }, + ); + return stdout; +} + +export function parseNumstat(text: string, staged: boolean): GitChange[] { + return text + .split('\0') + .filter(Boolean) + .flatMap((record) => { + const match = /^(\d+|-)\t(\d+|-)\t([\s\S]+)$/.exec(record); + return match + ? [ + { + path: match[3], + additions: Number(match[1]) || 0, + deletions: Number(match[2]) || 0, + staged, + untracked: false, + }, + ] + : []; + }); +} + +async function listFiles(cwd: string): Promise { + const files: string[] = []; + async function walk(relative: string, depth: number) { + if (depth > 7 || files.length >= 3000) return; + const entries = await fs.readdir(path.join(cwd, relative), { + withFileTypes: true, + }); + entries.sort( + (a, b) => + Number(b.isDirectory()) - Number(a.isDirectory()) || + a.name.localeCompare(b.name), + ); + for (const entry of entries) { + if ( + OMIT.has(entry.name) || + entry.isSymbolicLink() || + files.length >= 3000 + ) + continue; + const name = relative ? `${relative}/${entry.name}` : entry.name; + if (entry.isDirectory()) await walk(name, depth + 1).catch(() => {}); + else if (entry.isFile()) files.push(name); + } + } + await walk('', 0); + return files; +} + +export async function inspectWorkspace(cwd: string): Promise { + const files = await listFiles(cwd); + try { + const [branch, working, staged, untracked] = await Promise.all([ + git(cwd, ['branch', '--show-current']), + git(cwd, [ + 'diff', + '--no-ext-diff', + '--no-textconv', + '--no-renames', + '--numstat', + '-z', + '--relative', + '--', + '.', + ]), + git(cwd, [ + 'diff', + '--cached', + '--no-ext-diff', + '--no-textconv', + '--no-renames', + '--numstat', + '-z', + '--relative', + '--', + '.', + ]), + git(cwd, ['ls-files', '--others', '--exclude-standard', '-z']), + ]); + return { + branch: branch.trim(), + files, + changes: [ + ...parseNumstat(working, false), + ...parseNumstat(staged, true), + ...untracked + .split('\0') + .filter(Boolean) + .map((file) => ({ + path: file, + additions: 0, + deletions: 0, + staged: false, + untracked: true, + })), + ], + }; + } catch { + return { + branch: '', + changes: [], + files, + gitError: 'Git changes are unavailable for this folder.', + }; + } +} + +export async function filePatch( + cwd: string, + file: string, + staged: boolean, + untracked: boolean, +): Promise { + // Deleted paths cannot be realpathed. Lexical containment still protects Git pathspecs. + if ( + !file || + path.isAbsolute(file) || + !inside(path.resolve(cwd), path.resolve(cwd, file)) + ) + throw new Error('Invalid file path.'); + if (untracked) { + await readText(await workspacePath(cwd, file)); + try { + return await git(cwd, [ + 'diff', + '--no-index', + '--no-ext-diff', + '--no-textconv', + '--', + '/dev/null', + file, + ]); + } catch (error) { + // Git uses exit status 1 to report a valid patch with differences. + const result = error as { code?: number; stdout?: string }; + if (result.code === 1 && typeof result.stdout === 'string') + return result.stdout; + throw error; + } + } + return git(cwd, [ + '--literal-pathspecs', + 'diff', + ...(staged ? ['--cached'] : []), + '--no-ext-diff', + '--no-textconv', + '--relative', + '--', + file, + ]); +} + +export async function sessionPath( + file: string, + sessionsRoot = SESSIONS_ROOT, +): Promise { + const root = await fs.realpath(sessionsRoot); + const target = await fs.realpath(file); + if (!inside(root, target) || !target.endsWith('.jsonl')) + throw new Error('Invalid session file.'); + return target; +} + +export async function readSession( + file: string, + sessionsRoot = SESSIONS_ROOT, +): Promise { + const target = await sessionPath(file, sessionsRoot); + const stat = await fs.stat(target); + if (stat.size > 16 * MAX_TEXT) + throw new Error( + 'This session is too large to preview. Resume it to continue.', + ); + const records: { + id?: string; + parentId?: string; + type?: string; + message?: unknown; + }[] = []; + for (const line of (await fs.readFile(target, 'utf8')).split('\n')) { + try { + const record = JSON.parse(line); + if ( + record && + typeof record === 'object' && + !Array.isArray(record) && + typeof record.id === 'string' + ) + records.push(record); + } catch { + /* Partial final writes are expected. */ + } + } + // Follow the current branch rather than mixing messages from abandoned branches. + const byId = new Map(records.filter((r) => r.id).map((r) => [r.id, r])); + let current = records.at(-1); + const branch: unknown[] = []; + const seen = new Set(); + while (current) { + if (current.id && seen.has(current.id)) break; + if (current.id) seen.add(current.id); + if (current.type === 'message' && current.message) + branch.unshift(current.message); + current = current.parentId ? byId.get(current.parentId) : undefined; + } + return branch; +} + +export async function listSkills(cwd: string): Promise { + const result: SkillInfo[] = []; + const seen = new Set(); + for (const [root, source] of [ + [path.join(os.homedir(), '.pi', 'agent', 'skills'), 'Global'], + [path.join(os.homedir(), '.agents', 'skills'), 'Global'], + [path.join(cwd, '.pi', 'skills'), 'Workspace'], + [path.join(cwd, '.agents', 'skills'), 'Workspace'], + ] as const) { + async function walk(dir: string, depth: number) { + if (depth > 4 || result.length >= 500) return; + const real = await fs.realpath(dir); + if (seen.has(real)) return; + seen.add(real); + for (const entry of await fs.readdir(dir, { withFileTypes: true })) { + if (result.length >= 500) break; + const file = path.join(dir, entry.name); + try { + if ( + entry.isDirectory() || + (entry.isSymbolicLink() && (await fs.stat(file)).isDirectory()) + ) + await walk(file, depth + 1); + else if (entry.name === 'SKILL.md') { + const text = await readText(file); + const frontmatter = text.match(/^---\r?\n([\s\S]*?)\r?\n---/); + const field = (name: string) => + frontmatter?.[1] + .match(new RegExp(`^${name}:\\s*(.+)$`, 'm'))?.[1] + .replace(/^["']|["']$/g, '') ?? ''; + result.push({ + name: field('name') || path.basename(dir), + description: field('description'), + file, + source, + }); + } + } catch { + // A missing link or invalid skill must not hide its siblings. + } + } + } + await walk(root, 0).catch(() => {}); + } + return result; +} + +export function validateDefaults(value: unknown): Defaults { + const v = value as Partial | null; + if ( + !v || + typeof v.model !== 'string' || + typeof v.provider !== 'string' || + !['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'].includes( + v.thinking ?? '', + ) + ) + throw new Error('Invalid session defaults.'); + return { + model: v.model.slice(0, 200), + provider: v.provider.slice(0, 100), + thinking: v.thinking!, + }; +} diff --git a/src/preload/index.ts b/src/preload/index.ts index 012ceff..bdfca0c 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -13,22 +13,46 @@ contextBridge.exposeInMainWorld('pidex', { }, workspaces: () => ipcRenderer.invoke('pidex:workspaces'), addWorkspace: () => ipcRenderer.invoke('pidex:workspace:add'), + inspectWorkspace: (cwd: string) => + ipcRenderer.invoke('pidex:workspace:inspect', cwd), + readFile: (cwd: string, file: string) => + ipcRenderer.invoke('pidex:workspace:read', cwd, file), + filePatch: (cwd: string, file: string, staged: boolean, untracked: boolean) => + ipcRenderer.invoke('pidex:workspace:patch', cwd, file, staged, untracked), + gitAction: (cwd: string, action: string, file?: string) => + ipcRenderer.invoke('pidex:workspace:git', cwd, action, file), + previewSession: (file: string) => + ipcRenderer.invoke('pidex:session:preview', file), + skills: (cwd: string) => ipcRenderer.invoke('pidex:workspace:skills', cwd), + openProject: (cwd: string) => ipcRenderer.invoke('pidex:workspace:open', cwd), + attachFiles: () => ipcRenderer.invoke('pidex:workspace:attach'), + settings: (cwd: string) => ipcRenderer.invoke('pidex:settings:get', cwd), + saveSettings: (cwd: string, value: unknown) => + ipcRenderer.invoke('pidex:settings:save', cwd, value), + manageProviders: () => ipcRenderer.invoke('pidex:settings:providers'), + models: (cwd: string) => ipcRenderer.invoke('pidex:models:list', cwd), + setModel: (id: string, provider: string, model: string) => + ipcRenderer.invoke('pidex:session:model', id, provider, model), sessions: (dirName: string) => ipcRenderer.invoke('pidex:sessions', dirName), - openSession: (req: { cwd: string; sessionFile?: string }) => + openSession: (req: { cwd: string; sessionFile?: string; fork?: boolean }) => ipcRenderer.invoke('pidex:session/open', req), sendPrompt: (req: { sessionId: string; text: string; streaming: boolean }) => ipcRenderer.invoke('pidex:session/send', req), - abortSession: (sessionId: string) => ipcRenderer.invoke('pidex:session/abort', sessionId), + abortSession: (sessionId: string) => + ipcRenderer.invoke('pidex:session/abort', sessionId), sessionCommands: (sessionId: string) => ipcRenderer.invoke('pidex:session/commands', sessionId), - closeSession: (sessionId: string) => ipcRenderer.invoke('pidex:session/close', sessionId), + closeSession: (sessionId: string) => + ipcRenderer.invoke('pidex:session/close', sessionId), onSessionEvent: (cb: (payload: SessionEventPayload) => void) => { - const listener = (_event: unknown, payload: SessionEventPayload) => cb(payload); + const listener = (_event: unknown, payload: SessionEventPayload) => + cb(payload); ipcRenderer.on('pidex:session:event', listener); return () => ipcRenderer.removeListener('pidex:session:event', listener); }, onSessionExit: (cb: (payload: { sessionId: string }) => void) => { - const listener = (_event: unknown, payload: { sessionId: string }) => cb(payload); + const listener = (_event: unknown, payload: { sessionId: string }) => + cb(payload); ipcRenderer.on('pidex:session:exit', listener); return () => ipcRenderer.removeListener('pidex:session:exit', listener); }, diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index 59988a4..86798d3 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -1,544 +1,736 @@ -import { useEffect, useMemo, useRef, useState } from 'react'; -import { prepare, layout } from '@chenglou/pretext'; -import { PiMark } from './components/PiMark'; +import { useEffect, useRef, useState } from 'react'; import { PidexMark } from './components/PidexMark'; -import { FigureFrame } from './components/FigureFrame'; +import welcomeMark from './assets/workbench/welcome-mark.svg'; import { BracketButton } from './components/BracketButton'; -import { Markdown } from './components/Markdown'; -import { applyEvent, entriesFromMessages } from './timeline'; -import type { Entry } from './timeline'; -import type { SessionInfo, SlashCommand, WorkspaceInfo } from './api'; - -type SessionTab = { - runtimeId: string; - cwd: string; - workspaceName: string; - title: string; - model: string; - entries: Entry[]; - commands: SlashCommand[]; - running: boolean; - exited: boolean; -}; - -const BODY_FONT = '450 15px Newsreader, Georgia, serif'; - -function timeAgo(iso: string): string { - const seconds = Math.max(0, (Date.now() - new Date(iso).getTime()) / 1000); - if (seconds < 60) return 'now'; - if (seconds < 3600) return `${Math.floor(seconds / 60)}m`; - if (seconds < 86400) return `${Math.floor(seconds / 3600)}h`; - return `${Math.floor(seconds / 86400)}d`; -} - -function ToolOutput({ text }: { text: string }) { - const lines = text.split('\n'); - const shown = lines.slice(0, 14); - return ( - <> - {shown.map((line, i) => ( -
- {line} -
- ))} - {lines.length > shown.length ? ( -
… {lines.length - shown.length} more lines
- ) : null} - - ); -} +import { + Composer, + EmptyState, + Icon, + NavItem, + SearchField, + Transcript, +} from './components/WorkbenchControls'; +import { + ChangesView, + FilesView, + SettingsView, + SkillsView, +} from './components/WorkbenchViews'; +import { CommandPalette } from './components/CommandPalette'; +import { timeAgo, useWorkbench } from './useWorkbench'; function App() { - const [workspaces, setWorkspaces] = useState([]); - const [wsSessions, setWsSessions] = useState>({}); - const [expanded, setExpanded] = useState(null); - const [tabs, setTabs] = useState([]); - const [activeId, setActiveId] = useState(null); - const [draft, setDraft] = useState(''); - const [opening, setOpening] = useState(false); - const [openError, setOpenError] = useState(null); - const [slashIndex, setSlashIndex] = useState(0); - const [fontReady, setFontReady] = useState(false); + const b = useWorkbench(); + const { api, ws, active, view, details, sessions, preview } = b; + const [sidebar, setSidebar] = useState(true); + const [terminal, setTerminal] = useState(false); + const [palette, setPalette] = useState(false); + const [sessionQuery, setSessionQuery] = useState(''); + const [allHistory, setAllHistory] = useState(false); + const [paletteFile, setPaletteFile] = useState(''); + const [resetSettings, setResetSettings] = useState(0); const timelineRef = useRef(null); - const bootstrapped = useRef(false); - const openSessionRef = useRef<(ws: WorkspaceInfo, info?: SessionInfo) => Promise>( - async () => {}, - ); - - const activeTab = tabs.find(t => t.runtimeId === activeId) ?? null; - - useEffect(() => { - window.pidex.workspaces().then(async list => { - setWorkspaces(list); - const entries = await Promise.all( - list.map(ws => window.pidex.sessions(ws.dirName).then(s => [ws.dirName, s] as const)), - ); - const map: Record = {}; - for (const [dirName, s] of entries) map[dirName] = s; - setWsSessions(map); - const first = list[0]; - if (first && !bootstrapped.current) { - bootstrapped.current = true; - setExpanded(first.dirName); - const firstSession = map[first.dirName]?.[0]; - if (firstSession) openSessionRef.current(first, firstSession); - } - }); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); useEffect(() => { - const offEvent = window.pidex.onSessionEvent(({ sessionId, event }) => { - setTabs(prev => - prev.map(tab => { - if (tab.runtimeId !== sessionId) return tab; - const { entries, running } = applyEvent(tab.entries, event); - return { ...tab, entries, running: running ?? tab.running }; - }), - ); - }); - const offExit = window.pidex.onSessionExit(({ sessionId }) => { - setTabs(prev => - prev.map(tab => - tab.runtimeId === sessionId ? { ...tab, exited: true, running: false } : tab, - ), - ); - }); - return () => { - offEvent(); - offExit(); - }; - }, []); - - useEffect(() => { - timelineRef.current?.scrollTo({ top: timelineRef.current.scrollHeight }); - }, [activeTab?.entries.length, activeTab?.entries[activeTab.entries.length - 1]]); - + timelineRef.current?.scrollTo?.({ top: timelineRef.current.scrollHeight }); + }, [active?.entries, preview?.entries, view]); useEffect(() => { - let cancel = false; - const fonts = document.fonts; - if (!fonts?.load) { - setFontReady(true); - return; - } - fonts.load(BODY_FONT).then( - () => { - if (!cancel) setFontReady(true); - }, - () => { - if (!cancel) setFontReady(true); - }, - ); - return () => { - cancel = true; - }; - }, []); - - const measuredRows = useMemo(() => { - if (!activeTab || !fontReady) return 0; - let rows = 0; - for (const entry of activeTab.entries) { - if (entry.kind === 'tool') continue; - const text = entry.kind === 'assistant' ? entry.text || entry.thinking : entry.text; - if (!text) continue; - const prepared = prepare(text, BODY_FONT); - rows += layout(prepared, 780, 24).lineCount; - } - return rows; - }, [activeTab, fontReady]); - - const expandWorkspace = async (ws: WorkspaceInfo) => { - const next = expanded === ws.dirName ? null : ws.dirName; - setExpanded(next); - if (!next) return; - let sessions = wsSessions[next]; - if (!sessions) { - sessions = await window.pidex.sessions(next); - setWsSessions(prev => ({ ...prev, [next]: sessions })); - } - if (sessions[0]) openSession(ws, sessions[0]); - }; - - const addWorkspace = async () => { - const result = await window.pidex.addWorkspace(); - if (result.error || !result.cwd) return; - const list = await window.pidex.workspaces(); - setWorkspaces(list); - const added = list.find(w => w.cwd === result.cwd); - if (added) { - setExpanded(added.dirName); - setWsSessions(prev => ({ ...prev, [added.dirName]: [] })); - } - }; - - const openSession = async (ws: WorkspaceInfo, info?: SessionInfo) => { - const existing = tabs.find( - t => t.cwd === ws.cwd && t.title === (info?.title ?? 'new session'), - ); - if (existing) { - setActiveId(existing.runtimeId); - return; - } - setOpening(true); - setOpenError(null); - try { - const result = await window.pidex.openSession({ - cwd: ws.cwd, - sessionFile: info?.file, - }); - if (result.error || !result.sessionId) { - setOpenError(result.error ?? 'Could not open the session.'); - return; + const onKey = (event: KeyboardEvent) => { + if (!(event.metaKey || event.ctrlKey)) return; + if (event.key.toLowerCase() === 'k') { + event.preventDefault(); + setPalette((p) => !p); } - const model = - result.state?.model?.id ?? result.state?.model?.name ?? info?.model ?? 'default'; - const { commands } = await window.pidex.sessionCommands(result.sessionId); - const tab: SessionTab = { - runtimeId: result.sessionId, - cwd: ws.cwd, - workspaceName: ws.name, - title: info?.title ?? 'new session', - model, - entries: entriesFromMessages(result.messages ?? []), - commands, - running: Boolean(result.state?.isStreaming), - exited: false, - }; - setTabs(prev => [...prev, tab]); - setActiveId(tab.runtimeId); - } finally { - setOpening(false); - } - }; - openSessionRef.current = openSession; - - const closeTab = (runtimeId: string) => { - window.pidex.closeSession(runtimeId); - setTabs(prev => { - const next = prev.filter(t => t.runtimeId !== runtimeId); - if (activeId === runtimeId) setActiveId(next[next.length - 1]?.runtimeId ?? null); - return next; - }); - }; - - const send = async (raw?: string) => { - const text = (raw ?? draft).trim(); - if (!text || !activeTab || activeTab.exited) return; - const echo: Entry = { key: `local-${Date.now()}`, kind: 'user', text }; - setTabs(prev => - prev.map(t => (t.runtimeId === activeTab.runtimeId ? { ...t, entries: [...t.entries, echo] } : t)), - ); - setDraft(''); - setSlashIndex(0); - await window.pidex.sendPrompt({ - sessionId: activeTab.runtimeId, - text, - streaming: activeTab.running, - }); - }; - - const slashQuery = draft.startsWith('/') ? draft.slice(1) : null; - const slashMatches = slashQuery !== null && activeTab - ? activeTab.commands - .filter(c => c.name.toLowerCase().includes(slashQuery.toLowerCase())) - .slice(0, 8) - : []; - const slashOpen = slashQuery !== null && slashMatches.length > 0; - - const onComposerKey = (e: React.KeyboardEvent) => { - if (slashOpen) { - if (e.key === 'ArrowDown') { - e.preventDefault(); - setSlashIndex(i => (i + 1) % slashMatches.length); - return; + if (event.key === ',') { + event.preventDefault(); + b.navigate('settings'); } - if (e.key === 'ArrowUp') { - e.preventDefault(); - setSlashIndex(i => (i - 1 + slashMatches.length) % slashMatches.length); - return; + if (event.key.toLowerCase() === 'h' && event.shiftKey) { + event.preventDefault(); + b.navigate('history'); } - if (e.key === 'Tab') { - e.preventDefault(); - const cmd = slashMatches[Math.min(slashIndex, slashMatches.length - 1)]; - setDraft(`/${cmd.name} `); - setSlashIndex(0); - return; + if (event.key.toLowerCase() === 'b') { + event.preventDefault(); + setSidebar((v) => !v); } - if (e.key === 'Escape') { - e.preventDefault(); - setDraft(''); - setSlashIndex(0); - return; + if (event.key.toLowerCase() === 'o') { + event.preventDefault(); + void b.addWorkspace(); } - if (e.key === 'Enter') { - e.preventDefault(); - const cmd = slashMatches[Math.min(slashIndex, slashMatches.length - 1)]; - send(`/${cmd.name}`); - return; + }; + window.addEventListener('keydown', onKey); + return () => window.removeEventListener('keydown', onKey); + }); + + const composer = (placeholder?: string, label?: string) => ( + active && b.run(() => api.abortSession(active.runtimeId))} + onAttach={b.attach} + model={b.currentModel} + models={b.models} + onModel={b.changeModel} + running={view === 'session' && active?.running} + disabled={ + !ws || (view === 'session' && active?.exited) || b.previewLoading } - } - if (e.key === 'Enter') send(); + busy={b.busy} + placeholder={placeholder} + label={label} + commands={active?.commands ?? []} + modelDisabled={view === 'history'} + allowDefaultModel={view === 'new' || !active} + /> + ); + const filteredSessions = sessions.filter((s) => + `${s.title} ${s.model}`.toLowerCase().includes(sessionQuery.toLowerCase()), + ); + const title = { + new: 'Workspace', + session: active?.title ?? 'Session', + changes: 'Changes review', + history: 'Session history', + settings: 'Models & access', + skills: 'Skills', + files: 'Files & preview', + }[view]; + const branch = details.branch || ws?.branch || 'local'; + const context = `${ws?.name ?? 'pidex'} / ${branch} / ${view === 'history' ? `${sessions.length} sessions` : view === 'changes' ? `${details.changes.length} changes` : view === 'settings' ? 'workspace defaults' : 'local workspace'}`; + const live = b.tabs.filter((t) => t.cwd === ws?.cwd && !t.exited); + const exportSession = () => { + if (!preview) return; + const text = preview.entries + .map((e) => + e.kind === 'tool' + ? `## ${e.tool}\n\n${e.output}` + : `## ${e.kind}\n\n${e.text}`, + ) + .join('\n\n'); + const url = URL.createObjectURL( + new Blob([text], { type: 'text/markdown' }), + ); + const a = document.createElement('a'); + a.href = url; + a.download = 'pidex-session.md'; + a.click(); + setTimeout(() => URL.revokeObjectURL(url), 1000); }; return ( -
- - -
- - -
- {activeTab ? ( + Settings + +

+ {active?.running ? 'PI WORKING / LOCAL' : 'LOCAL WORKSPACE'} +

+ + )} +
+ {b.error && ( +
+ {b.error} + +
+ )} + {!ws ? ( +
+ +

Welcome to pidex

+

+ Pick a project folder to get started. Your conversations and + settings stay local. +

+
+ Open project +
~/projects /
+ void b.addWorkspace()} + disabled={b.loading || !api} + > + {b.loading ? 'Loading…' : 'Browse folder'} + +
+
+ ) : ( <> -
-
-

{activeTab.workspaceName}

- - {activeTab.exited ? 'exited' : activeTab.running ? 'running' : 'idle'} - -
- window.pidex.abortSession(activeTab.runtimeId)}> - Abort - -
-
-
- {activeTab.cwd} - - model {activeTab.model} - - - session {activeTab.title.slice(0, 48)} - +
+
+

{title}

+

{context}

+ {view === 'settings' ? ( + setResetSettings((v) => v + 1)}> + Restore defaults + + ) : view === 'history' ? ( + + Export + + ) : ( + + view === 'new' + ? void b.addWorkspace() + : b.navigate('files') + } + > + {view === 'new' ? 'Open project' : 'Browse files'} + + )}
- -
- {activeTab.entries.map(entry => { - if (entry.kind === 'tool') { - return ( - +
+
+ +
+

Start a session

+

Bring a task. Pi works in your workspace.

+
+
+
+ Work in + + {ws.cwd} +
+ {composer()} +
+ + +
- ); - })} -
- -
- {slashOpen ? ( -
- {slashMatches.map((cmd, i) => ( +
+ Continue a session - ))} +
+
+ {sessions.slice(0, 2).map((s) => ( + + ))} + {!sessions.length && ( +

+ No saved sessions yet. Start with a task above. +

+ )} +
- ) : null} -
- › - { - setDraft(e.target.value); - setSlashIndex(0); - }} - onKeyDown={onComposerKey} - placeholder={ - activeTab.exited - ? 'session exited' - : activeTab.running - ? `steer ${activeTab.workspaceName}…` - : `prompt ${activeTab.workspaceName}…` - } - disabled={activeTab.exited} - spellCheck={false} - />
-
- {activeTab.running ? 'enter to steer · / for commands' : 'enter to send · / for commands'} - {activeTab.model} + )} + {view === 'session' && + (active ? ( +
+
+
+ + {!active.entries.length && ( + + Send a task to start working with Pi. + + )} +
+ {composer( + active.exited + ? 'Session exited. Start a new session to continue.' + : active.running + ? 'Add a follow-up while pi works…' + : 'Continue this session…', + )} +
+ +
+ ) : ( + + Select a saved session or start a new one. + + ))} + {view === 'changes' && ( + + )} + {view === 'history' && ( +
+ +
+ {preview ? ( + <> +
+
+

{preview.info.title}

+

+ {preview.info.model || 'Pi'} / saved locally +

+
+ b.navigate('changes')} + > + Review changes + +
+
+ {b.previewLoading ? ( +

+ Loading session… +

+ ) : ( + <> + +
+ + Fork from here + + + Start a new session from this conversation. + +
+ + )} +
+ {composer('Continue this session…', 'Resume')} + + ) : ( + + Saved conversations will appear here. + + )} +
-
+ )} + {view === 'settings' && ( + b.navigate('files')} + /> + )} + {view === 'skills' && ( + + )} + {view === 'files' && ( + + )} - ) : ( -
- -

No session open

-

- Pick a session from the sidebar, or start a new one in the expanded workspace. -

- {openError ?

{openError}

: null} -
+ )} + {terminal && ( +
+
+ Session output + +
+
+                {active?.entries
+                  .filter((e) => e.kind === 'tool' && e.tool === 'bash')
+                  .map((e) =>
+                    e.kind === 'tool' ? `$ ${e.args}\n${e.output}` : '',
+                  )
+                  .join('\n\n') ||
+                  'Shell output from the current Pi session will appear here.'}
+              
+
)}
- -
-
- - {activeTab?.running ? 'agent running' : 'runtime linked'} - - {tabs.length} tabs -
+
+ + {!ws + ? 'RUNTIME IDLE' + : active?.exited + ? 'PI EXITED' + : active?.running + ? 'PI WORKING' + : b.busy + ? 'PI CONNECTING' + : b.modelError && !active + ? 'PI UNAVAILABLE' + : 'PI READY'} + - $ pidex — {measuredRows} rows measured · 0 dom reads + {view === 'history' + ? 'Local session archive' + : `${b.measuredRows} rows measured / ${b.tabs.length} open sessions`}
+ {palette && ( + setPalette(false)} + onWorkspace={b.selectWorkspace} + onSession={b.showSession} + onNavigate={b.navigate} + onFile={(file) => { + setPaletteFile(file); + b.navigate('files'); + }} + onCommand={b.useSkill} + onAddWorkspace={() => void b.addWorkspace()} + /> + )}
); } -export { App }; \ No newline at end of file +export { App }; diff --git a/src/renderer/api.ts b/src/renderer/api.ts index ba6faf8..840fd8f 100644 --- a/src/renderer/api.ts +++ b/src/renderer/api.ts @@ -1,3 +1,19 @@ +import type { + Defaults, + GitChange, + SkillInfo, + WorkspaceDetails, +} from '../main/workbench'; + +type Result = { data?: T; error?: string }; +type ModelInfo = { + id: string; + name: string; + provider: string; + contextWindow?: number; + reasoning?: boolean; +}; + type WorkspaceInfo = { dirName: string; name: string; @@ -48,9 +64,43 @@ type PidexApi = { versions: { electron: string; node: string }; workspaces: () => Promise; addWorkspace: () => Promise<{ cwd?: string; error?: string }>; + inspectWorkspace: (cwd: string) => Promise>; + readFile: (cwd: string, file: string) => Promise>; + filePatch: ( + cwd: string, + file: string, + staged: boolean, + untracked: boolean, + ) => Promise>; + gitAction: ( + cwd: string, + action: 'stage' | 'stage-all' | 'unstage' | 'commit', + file?: string, + ) => Promise>; + previewSession: (file: string) => Promise>; + skills: (cwd: string) => Promise>; + openProject: (cwd: string) => Promise>; + attachFiles: () => Promise>; + settings: (cwd: string) => Promise>; + saveSettings: (cwd: string, value: Defaults) => Promise>; + manageProviders: () => Promise>; + models: (cwd: string) => Promise>; + setModel: ( + id: string, + provider: string, + model: string, + ) => Promise>; sessions: (dirName: string) => Promise; - openSession: (req: { cwd: string; sessionFile?: string }) => Promise; - sendPrompt: (req: { sessionId: string; text: string; streaming: boolean }) => Promise<{ success?: boolean; error?: string }>; + openSession: (req: { + cwd: string; + sessionFile?: string; + fork?: boolean; + }) => Promise; + sendPrompt: (req: { + sessionId: string; + text: string; + streaming: boolean; + }) => Promise<{ success?: boolean; error?: string }>; abortSession: (sessionId: string) => Promise; sessionCommands: (sessionId: string) => Promise<{ commands: SlashCommand[] }>; closeSession: (sessionId: string) => Promise; @@ -64,4 +114,20 @@ declare global { } } -export type { WorkspaceInfo, SessionInfo, SessionState, OpenResult, SessionEventPayload, PidexApi, SlashCommand }; +export type { + WorkspaceInfo, + SessionInfo, + SessionState, + OpenResult, + SessionEventPayload, + PidexApi, + SlashCommand, +}; +export type { + Defaults, + GitChange, + SkillInfo, + WorkspaceDetails, + ModelInfo, + Result, +}; diff --git a/src/renderer/assets/fonts/IBMPlexMono-LICENSE.txt b/src/renderer/assets/fonts/IBMPlexMono-LICENSE.txt new file mode 100644 index 0000000..670c6c0 --- /dev/null +++ b/src/renderer/assets/fonts/IBMPlexMono-LICENSE.txt @@ -0,0 +1,93 @@ +Copyright © 2017 IBM Corp. with Reserved Font Name "Plex" + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/src/renderer/assets/fonts/IBMPlexMono-Regular.ttf b/src/renderer/assets/fonts/IBMPlexMono-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0c9770d5183ba60dc4350d3e011b782a320761ae GIT binary patch literal 135580 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 K5Q|D9=l=lr4cw*x literal 0 HcmV?d00001 diff --git a/src/renderer/assets/fonts/JetBrainsMono-LICENSE.txt b/src/renderer/assets/fonts/JetBrainsMono-LICENSE.txt new file mode 100644 index 0000000..821a3da --- /dev/null +++ b/src/renderer/assets/fonts/JetBrainsMono-LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: https://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/src/renderer/assets/fonts/JetBrainsMono-Variable.ttf b/src/renderer/assets/fonts/JetBrainsMono-Variable.ttf new file mode 100644 index 0000000000000000000000000000000000000000..aa310be8b717fe3774f9444dd89d5f4101cc6d10 GIT binary patch literal 187208 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�`t1>ioQcDTIG6x2X6$P-d@w| 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 literal 0 HcmV?d00001 diff --git a/src/renderer/assets/workbench/activity-terminal.svg b/src/renderer/assets/workbench/activity-terminal.svg new file mode 100644 index 0000000..99620b0 --- /dev/null +++ b/src/renderer/assets/workbench/activity-terminal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/renderer/assets/workbench/appearance.svg b/src/renderer/assets/workbench/appearance.svg new file mode 100644 index 0000000..be516ec --- /dev/null +++ b/src/renderer/assets/workbench/appearance.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/renderer/assets/workbench/changes.svg b/src/renderer/assets/workbench/changes.svg new file mode 100644 index 0000000..0cdd65a --- /dev/null +++ b/src/renderer/assets/workbench/changes.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/renderer/assets/workbench/check.svg b/src/renderer/assets/workbench/check.svg new file mode 100644 index 0000000..4275972 --- /dev/null +++ b/src/renderer/assets/workbench/check.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/renderer/assets/workbench/chevron-down.svg b/src/renderer/assets/workbench/chevron-down.svg new file mode 100644 index 0000000..9ebf018 --- /dev/null +++ b/src/renderer/assets/workbench/chevron-down.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/renderer/assets/workbench/file-code.svg b/src/renderer/assets/workbench/file-code.svg new file mode 100644 index 0000000..4c8afc9 --- /dev/null +++ b/src/renderer/assets/workbench/file-code.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/renderer/assets/workbench/file.svg b/src/renderer/assets/workbench/file.svg new file mode 100644 index 0000000..bcbe21c --- /dev/null +++ b/src/renderer/assets/workbench/file.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/renderer/assets/workbench/folder-open.svg b/src/renderer/assets/workbench/folder-open.svg new file mode 100644 index 0000000..ff92c86 --- /dev/null +++ b/src/renderer/assets/workbench/folder-open.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/renderer/assets/workbench/folder.svg b/src/renderer/assets/workbench/folder.svg new file mode 100644 index 0000000..8bfd171 --- /dev/null +++ b/src/renderer/assets/workbench/folder.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/renderer/assets/workbench/message-square.svg b/src/renderer/assets/workbench/message-square.svg new file mode 100644 index 0000000..4183784 --- /dev/null +++ b/src/renderer/assets/workbench/message-square.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/renderer/assets/workbench/panel-left.svg b/src/renderer/assets/workbench/panel-left.svg new file mode 100644 index 0000000..745a3fe --- /dev/null +++ b/src/renderer/assets/workbench/panel-left.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/renderer/assets/workbench/paperclip.svg b/src/renderer/assets/workbench/paperclip.svg new file mode 100644 index 0000000..fef973d --- /dev/null +++ b/src/renderer/assets/workbench/paperclip.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/renderer/assets/workbench/plus.svg b/src/renderer/assets/workbench/plus.svg new file mode 100644 index 0000000..3b88342 --- /dev/null +++ b/src/renderer/assets/workbench/plus.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/renderer/assets/workbench/search.svg b/src/renderer/assets/workbench/search.svg new file mode 100644 index 0000000..9b72762 --- /dev/null +++ b/src/renderer/assets/workbench/search.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/renderer/assets/workbench/settings.svg b/src/renderer/assets/workbench/settings.svg new file mode 100644 index 0000000..88bd56a --- /dev/null +++ b/src/renderer/assets/workbench/settings.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/renderer/assets/workbench/shield.svg b/src/renderer/assets/workbench/shield.svg new file mode 100644 index 0000000..52f4b23 --- /dev/null +++ b/src/renderer/assets/workbench/shield.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/renderer/assets/workbench/skills.svg b/src/renderer/assets/workbench/skills.svg new file mode 100644 index 0000000..e8c440a --- /dev/null +++ b/src/renderer/assets/workbench/skills.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/renderer/assets/workbench/starter-changes.svg b/src/renderer/assets/workbench/starter-changes.svg new file mode 100644 index 0000000..0cdd65a --- /dev/null +++ b/src/renderer/assets/workbench/starter-changes.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/renderer/assets/workbench/starter-search.svg b/src/renderer/assets/workbench/starter-search.svg new file mode 100644 index 0000000..02949fb --- /dev/null +++ b/src/renderer/assets/workbench/starter-search.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/renderer/assets/workbench/terminal.svg b/src/renderer/assets/workbench/terminal.svg new file mode 100644 index 0000000..08c86c2 --- /dev/null +++ b/src/renderer/assets/workbench/terminal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/renderer/assets/workbench/welcome-mark.svg b/src/renderer/assets/workbench/welcome-mark.svg new file mode 100644 index 0000000..1511fe8 --- /dev/null +++ b/src/renderer/assets/workbench/welcome-mark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/renderer/components/BracketButton.tsx b/src/renderer/components/BracketButton.tsx index 0c36dbd..271c16d 100644 --- a/src/renderer/components/BracketButton.tsx +++ b/src/renderer/components/BracketButton.tsx @@ -4,12 +4,22 @@ type BracketButtonProps = ButtonHTMLAttributes & { primary?: boolean; }; -function BracketButton({ primary = false, className, children, ...rest }: BracketButtonProps) { +function BracketButton({ + primary = false, + className, + children, + ...rest +}: BracketButtonProps) { const classes = ['ds-button', primary ? 'ds-button--primary' : '', className] .filter(Boolean) .join(' '); return ( - ); diff --git a/src/renderer/components/CommandPalette.tsx b/src/renderer/components/CommandPalette.tsx new file mode 100644 index 0000000..a429c89 --- /dev/null +++ b/src/renderer/components/CommandPalette.tsx @@ -0,0 +1,293 @@ +import { + useEffect, + useMemo, + useRef, + useState, + type KeyboardEvent, +} from 'react'; +import { Icon } from './WorkbenchControls'; +import type { SessionInfo, SlashCommand, WorkspaceInfo } from '../api'; +import type { View } from '../useWorkbench'; + +type Category = 'Commands' | 'Projects' | 'Sessions' | 'Files' | 'Skills'; +type Item = { + id: string; + title: string; + detail: string; + category: Category; + run: () => void; +}; + +export function CommandPalette({ + workspaces, + sessions, + files, + commands, + onClose, + onWorkspace, + onSession, + onNavigate, + onFile, + onCommand, + onAddWorkspace, +}: { + workspaces: WorkspaceInfo[]; + sessions: SessionInfo[]; + files: string[]; + commands: SlashCommand[]; + onClose: () => void; + onWorkspace: (ws: WorkspaceInfo) => void; + onSession: (session: SessionInfo) => void; + onNavigate: (view: View) => void; + onFile: (file: string) => void; + onCommand: (command: string) => void; + onAddWorkspace: () => void; +}) { + const [query, setQuery] = useState(''); + const [category, setCategory] = useState('Commands'); + const [index, setIndex] = useState(0); + const dialog = useRef(null); + const input = useRef(null); + useEffect(() => { + const previous = document.activeElement as HTMLElement | null; + input.current?.focus(); + return () => previous?.focus(); + }, []); + const items = useMemo( + () => [ + ...( + [ + ['New session', 'new'], + ['Session history', 'history'], + ['Review changes', 'changes'], + ['Browse files', 'files'], + ['Browse skills', 'skills'], + ['Models & access', 'settings'], + ] as const + ).map(([title, view]) => ({ + id: view, + title, + detail: 'Navigate in this workspace', + category: 'Commands' as const, + run: () => onNavigate(view), + })), + { + id: 'open-project', + title: 'Open project', + detail: 'Choose a local folder', + category: 'Commands', + run: onAddWorkspace, + }, + ...commands.map((c) => ({ + id: `command:${c.name}`, + title: `/${c.name}`, + detail: c.description ?? c.source ?? 'Pi command', + category: c.name.startsWith('skill:') + ? ('Skills' as const) + : ('Commands' as const), + run: () => onCommand(`/${c.name} `), + })), + ...workspaces.map((ws) => ({ + id: ws.cwd, + title: ws.name, + detail: ws.cwd, + category: 'Projects' as const, + run: () => onWorkspace(ws), + })), + ...sessions.map((s) => ({ + id: s.id, + title: s.title, + detail: `${s.messageCount} messages / ${s.model || 'Pi'}`, + category: 'Sessions' as const, + run: () => onSession(s), + })), + ...files.map((file) => ({ + id: file, + title: file.split('/').at(-1) ?? file, + detail: file, + category: 'Files' as const, + run: () => onFile(file), + })), + ], + [ + commands, + files, + onAddWorkspace, + onCommand, + onFile, + onNavigate, + onSession, + onWorkspace, + sessions, + workspaces, + ], + ); + const matches = items + .filter( + (item) => + item.category === category && + `${item.title} ${item.detail}` + .toLowerCase() + .includes(query.toLowerCase()), + ) + .slice(0, 80); + const selected = Math.min(index, Math.max(0, matches.length - 1)); + const choose = (item: Item) => { + onClose(); + item.run(); + }; + const keyDown = (e: KeyboardEvent) => { + if (e.key === 'Escape') { + e.preventDefault(); + e.stopPropagation(); + onClose(); + } + if (e.key === 'ArrowDown' || e.key === 'ArrowUp') { + e.preventDefault(); + setIndex( + (selected + (e.key === 'ArrowDown' ? 1 : -1) + matches.length) % + Math.max(1, matches.length), + ); + } + if (e.key === 'Enter' && matches[selected]) { + e.preventDefault(); + choose(matches[selected]); + } + if (e.key === 'Tab') { + const focusable = [ + ...(dialog.current?.querySelectorAll('input, button') ?? + []), + ]; + const first = focusable[0]; + const last = focusable.at(-1); + if (e.shiftKey && document.activeElement === first) { + e.preventDefault(); + last?.focus(); + } + if (!e.shiftKey && document.activeElement === last) { + e.preventDefault(); + first?.focus(); + } + } + }; + useEffect(() => { + dialog.current + ?.querySelector('[role="option"][aria-selected="true"]') + ?.scrollIntoView?.({ block: 'nearest' }); + }, [selected]); + return ( +
{ + if (e.currentTarget === e.target) onClose(); + }} + > +
+
+ ⌘ + › + { + setQuery(e.target.value); + setIndex(0); + }} + role="combobox" + aria-expanded="true" + aria-controls="quick-switch-results" + aria-activedescendant={ + matches[selected] ? `palette-result-${selected}` : undefined + } + /> + +
+
+ {( + ['Commands', 'Projects', 'Sessions', 'Files', 'Skills'] as const + ).map((name) => ( + + ))} +
+
+ {matches.map((item, i) => ( + + ))} + {!matches.length && ( +

+ No matching {category.toLowerCase()}. +

+ )} +
+
+ ↑↓ navigate · enter open · esc close + {matches.length} results +
+
+
+ ); +} diff --git a/src/renderer/components/PierreDiff.tsx b/src/renderer/components/PierreDiff.tsx index 4440abd..0aed08e 100644 --- a/src/renderer/components/PierreDiff.tsx +++ b/src/renderer/components/PierreDiff.tsx @@ -133,4 +133,9 @@ function PierreDiff({ oldFile, newFile, filename, className }: PierreDiffProps) ); } -export { PierreDiff }; \ No newline at end of file +export { PierreDiff }; + +/** Render an existing Git patch without regenerating or truncating its hunks. */ +export function PierrePatch({ patch }: { patch: string }) { + return ; +} diff --git a/src/renderer/components/WorkbenchControls.tsx b/src/renderer/components/WorkbenchControls.tsx new file mode 100644 index 0000000..0d3e3a7 --- /dev/null +++ b/src/renderer/components/WorkbenchControls.tsx @@ -0,0 +1,358 @@ +import { useRef, useState, type KeyboardEvent, type ReactNode } from 'react'; +import { BracketButton } from './BracketButton'; +import { FigureFrame } from './FigureFrame'; +import { Markdown } from './Markdown'; +import type { Entry } from '../timeline'; +import type { ModelInfo, SlashCommand } from '../api'; + +const icons = import.meta.glob('../assets/workbench/*.svg', { + eager: true, + query: '?url', + import: 'default', +}); +export type IconName = + | 'file-code' + | 'file' + | 'activity-terminal' + | 'starter-changes' + | 'starter-search' + | 'folder-open' + | 'folder' + | 'message-square' + | 'changes' + | 'skills' + | 'settings' + | 'terminal' + | 'paperclip' + | 'check' + | 'search' + | 'panel-left' + | 'chevron-down' + | 'shield' + | 'appearance' + | 'plus'; + +export function Icon({ name }: { name: IconName }) { + return ( + + ); +} + +export function NavItem({ + icon, + children, + detail, + active, + onClick, +}: { + icon: IconName; + children: ReactNode; + detail?: ReactNode; + active?: boolean; + onClick: () => void; +}) { + return ( + + ); +} + +export function SearchField({ + value, + onChange, + placeholder, + label, +}: { + value: string; + onChange: (value: string) => void; + placeholder: string; + label: string; +}) { + return ( + + ); +} + +export function Composer({ + draft, + onDraft, + onSend, + onStop, + onAttach, + model, + models, + onModel, + running = false, + disabled = false, + busy = false, + modelDisabled = false, + allowDefaultModel = true, + placeholder, + label = 'Send', + commands = [], +}: { + draft: string; + onDraft: (draft: string) => void; + onSend: (text?: string) => void; + onStop?: () => void; + onAttach: () => void; + model: string; + models: ModelInfo[]; + onModel: (value: string) => void; + running?: boolean; + disabled?: boolean; + busy?: boolean; + placeholder?: string; + label?: string; + commands?: SlashCommand[]; + modelDisabled?: boolean; + allowDefaultModel?: boolean; +}) { + const input = useRef(null); + const [index, setIndex] = useState(0); + const matches = draft.startsWith('/') + ? commands + .filter((c) => + c.name.toLowerCase().includes(draft.slice(1).toLowerCase()), + ) + .slice(0, 8) + : []; + const selected = Math.min(index, Math.max(0, matches.length - 1)); + const keyDown = (e: KeyboardEvent) => { + if (e.nativeEvent.isComposing) return; + if ( + matches.length && + ['ArrowDown', 'ArrowUp', 'Tab', 'Escape'].includes(e.key) + ) { + e.preventDefault(); + if (e.key === 'ArrowDown') setIndex((selected + 1) % matches.length); + if (e.key === 'ArrowUp') + setIndex((selected + matches.length - 1) % matches.length); + if (e.key === 'Tab') { + onDraft(`/${matches[selected].name} `); + setIndex(0); + } + if (e.key === 'Escape') onDraft(''); + return; + } + if (e.key === 'Escape' && running) { + e.preventDefault(); + onStop?.(); + } + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault(); + if (!disabled && !busy) + onSend(matches.length ? `/${matches[selected].name}` : undefined); + } + }; + return ( + + {matches.length > 0 && ( +
+ {matches.map((c, i) => ( + + ))} +
+ )} +
+ +