Merge - #22
Open
Termina1 wants to merge 52 commits into
Open
Conversation
added 30 commits
May 10, 2026 11:41
…ly on desktop - text-sm → text-base (16px) prevents iOS Safari zoom when input focused - py-2 → py-1.5, minHeight 38px → 40px to fit larger font - Send button: mdiPlay → mdiSend icon, neutral color, active:scale-95 pressed state - Stop/Force-stop/Killing buttons: neutral colors, self-center alignment - Enter sends only on desktop (!isMobile), mobile uses button tap
Add qa/ios-visual/ — WebdriverIO 9 + Appium 3 + XCUITest on iOS Simulator. Test suite: - 7 visual smoke tests: session list, detail, focused input, root, settings, mobile shell - Deterministic fixture dashboard with isolated HOME, test-pi bridge replay - Fixture mode server seam (PI_DASHBOARD_FIXTURE_MODE) disables mDNS, bootstrap, plugins, auth, tunnel, push - Visual baselines in qa/ios-visual/visual/baseline/default/ Run: npm run ios-visual:fixture
…t bubbles Add overflow-wrap/word-break to .markdown-content to force long words/URLs/paths to break at container boundary. Add break-all to inline <code> for long identifiers without spaces.
… init Move const hasZrok out of if (!isFixture) block so it's accessible in the later if (config.tunnel) check. The block-scoped declaration was invisible outside the if-body.
Add viewport-fit=cover to meta viewport and safe-area-inset-bottom padding to CommandInput so the input bar clears the home indicator and rounded corners on notched iPhones.
…-qa review Skill takes a screenshot of the dashboard in the iOS Simulator via xcrun simctl io screenshot, then sends it to the visual-qa subagent for review. Reuses existing qa/ios-visual simulator infrastructure. Script: - Health-checks dashboard before screenshot - Auto-boots simulator if needed - Opens dashboard URL in Safari via simctl openurl - Waits for page load, captures screenshot - Shuts down simulator on exit Subagent: visual-qa (openai-codex/gpt-5.5) — analyzes for layout, typography, color, responsiveness, and visual artifact bugs.
Add name, description, license, and metadata to: - ios-visual-review - push-notify-user (project + extension)
…h-notify-user) Both skills were duplicated: project-level .pi/skills/ copies are canonical and validated fine; extension-level copies were identical stale leftovers causing pi discovery collisions (auto-resolved to project-level, extension copies skipped).
Rewrite screenshot flow to use Appium + XCUITest (same stack as qa/ios-visual tests). New screenshot.mjs: - Health-checks dashboard before session - Finds/boots iOS simulator via simctl - Starts Appium (or reuses running instance) - Creates WDIO session against Safari on simulator - Navigates to dashboard, waits for SPA root - Dismisses native Safari coachmark popups - Performs --action (idle / focus-input) - Saves web + native context screenshots - Prints web screenshot path to stdout Keeps legacy screenshot.sh for quick idle captures without Appium. SKILL.md rewritten with action table, full workflow, env vars, prerequisites, and subagent usage example.
- Delete screenshot.sh (replaced by Appium-based screenshot.mjs) - Add --session flag for focus-input to navigate to session detail - Fix REPO_ROOT path (was off by one level, hitting .pi/ dir) - Resolve webdriverio via createRequire from qa/ios-visual/node_modules
visual-qa subagent now does general visual quality reviews: - Bugs (layout, typography, colors, safe-area, etc.) - Improvements (hierarchy, density, alignment, contrast) - What's good (highlights successful decisions) - Overall verdict SKILL.md updated with broad review prompt examples.
Before taking screenshot, injects: - Red dashed outline around #root (APP boundary) - "APP" label in top-left corner - Dimmed overlay outside #root (browser/system chrome) Updated visual-qa subagent prompt to recognize the boundary: - Inside red border = app UI (can be changed) - Outside red border = browser/system chrome (ignore)
Bug: isKeyboardVisible() switched to NATIVE_APP but never restored web context, breaking all subsequent browser.execute() calls. Fix: save/restore context in finally block. Feature: draw red dashed outline + APP label on #root before screenshot so visual-qa can distinguish app UI from browser chrome.
When the software keyboard is active, the home indicator area is already behind the keyboard — adding env(safe-area-inset-bottom) creates a double gap. Detect keyboard visibility via visualViewport resize and apply safe-area padding only when keyboard is hidden.
Previous approach (outline on #root) was invisible — likely clipped by overflow:hidden or too thin on Retina. Now creates a separate fixed-position div matching #root's bounding rect with 4px dashed red border + APP label overlay.
Changed from position:fixed (viewport-only) to position:absolute inside #root with inset:0 so the red border spans the full scrollable content height, not just the visible viewport.
… contentEditable>
Replaces the <textarea> in CommandInput with a contenteditable div
(via react-contenteditable library) to remove the iOS keyboard
accessory bar (?? ??Done/???????) that appears above the software
keyboard on iOS Safari.
Key changes:
- New contenteditable-utils.ts: cursor position helpers + plaintext<->HTML conversion
- CommandInput.tsx: <textarea> -> <ContentEditable> with onBeforeInput,
IME composition guard, accessibility attributes, key-based remount
- Tests: adapted to contenteditable DOM semantics (39/39 passing)
- Design/adds react-contenteditable dependency
Altman review fixes applied: cursor walker rewritten, safeHtmlToPlain
no longer collapses newlines, disabled guard, IME guard on all paths,
onDrop handler, key={dropdownMode} to bypass shouldComponentUpdate
… to <div contentEditable>" This reverts commit 100eae7.
…ing, payload - PushNotificationsSection: PATCH → PUT /api/config - config-api: deep-merge push.defaults without dropping enabled/webPush - system-routes: live-reload config.push after save - event-wiring: pushPrefsMap + getPushDefaults passed to isPushTrigger - isPushTrigger: push successful agent_end when notifyCompletion=on - build-push-payload: 'Session completed' title for success agent_end - BellToggle: per-session bell in StatusBar - push-dispatcher: fix TS Promise<SendResult[][]> → flat() - usePushSubscription: fix Uint8Array → ArrayBuffer type - Removed 60s stale-view TTL gate from push path - Tests: push-trigger completion, config-api deep-merge, PushNotificationsSection save
Archived: openspec/changes/archive/2026-05-06-per-session-push-bell/ Specs synced: - agent-proactive-push: created (4 reqs) - per-session-push-prefs: created (6 reqs) - push-notifications: +1 added, ~1 modified, -1 removed
- WorktreeManager: add/list/remove git worktrees with error handling - process-manager: preSpawnHook for worktree creation before pi spawn - session-api: spawnMode 'worktree' with async 202+background spawn - event-wiring: detectWorktree, resolveMainRepoRoot, groupCwd - git-routes: GET/DELETE /api/git/worktrees endpoints - WorktreeSpawnDialog: base branch + new branch, instant close - SessionCard: WorktreeIndicator with branch badge + tooltip - session-grouping: use groupCwd for folder grouping - useMessageHandler: clear spawning state for groupCwd sessions - BranchPicker: removed isCurrent restriction - types: DashboardSession.worktree + groupCwd fields - tests: 28 unit + API + Playwright browser tests in Docker - skill: worktree-spawn for subagent usage
Moved to qa/push/ alongside other test suites.
Docker-based sandbox (sandbox/) runs pi-dashboard with version-controlled seed data (seed/ — 5 workspaces, 19 sessions) and headless Chromium for reproducible screenshot capture. - seed/: 5 fake developer workspaces covering active project, empty, openspec-heavy, multi-folder, and error states UI rendering - sandbox/: Dockerfile, docker-compose.yml, entrypoint.sh — dashboard (port 8000) + chromedp/headless-shell (CDP port 9222) - sandbox-designer skill: vision-capable agent producing Tailwind HTML mockups with <!-- state: ... --> annotations - browser-visual-debug: --sandbox flag + --scenario JSON-driven automation (10-step vocabulary: open, click, fill, type, select, press, wait, screenshot, scroll, snapshot) - openspec-propose: optional Docker-gated Design Phase with user review gates at scenario derivation and mockup approval stages - openspec-archive-change: seed.patch/Dockerfile.patch merge before archive - docs: Design Sandbox section in architecture.md, file-index-infra.md split - CHANGELOG: Unreleased entry Server fixes for sandbox compatibility: - session-scanner: dataUnavailable: false for disk-scanned sessions - server: preserve session status from .meta.json (don't force 'ended') - server: PI_SANDBOX env var bypasses network guard + WS upgrade check - client: suppress Disconnected banner when sessions exist (sessions.size > 0) Archived: openspec/changes/archive/2026-05-07-design-sandbox-infrastructure/
- Fix session ordering: use groupCwd instead of worktree cwd for sessionOrderManager and sessions_reordered broadcast - Add findMatchingWorktrees() helper with exact-prefix regex matching - Add cleanupWorktree checkbox to bulk archive confirm dialog - Remove all dashboard-managed worktrees on archive when checked - Add .pi/ whitelist to .gitignore (skills, agents, prompts tracked) - Add event-wiring ordering unit tests (4 tests) - Add session-ordering groupCwd tests (3 tests) - Add worktree-manager findMatchingWorktrees tests (5 tests) - Add bulk-archive cleanupWorktree type tests (3 tests) - Add SessionList placeholder/ordering tests (3 tests) - Add Docker + Playwright browser test (qa/worktree-placeholder/) - Add OpenSpec change artifacts (fix-worktree-placeholder-replacement)
- sandbox-designer agent: gemini-3.1-pro-preview + xhigh thinking, CSS constraint - sandbox-designer skill: CSS custom properties, intercom protocol, state validation - opsx-propose: scenario.json workflow, run-scenarios.sh, designer handshake - opsx-explore: Design Flow Awareness section - browser-visual-debug: One-Shot Capture for design screenshots - openspec-apply-change: mockup comparison guardrail - sandbox: --rich flag, run-scenarios.sh, capture-screenshots.sh, seed-bridge.mjs
- Updated meta.json with git/worktree/openspec/attached/cost fields - Updated JSONL with git_info_update + model_change events - Updated preferences.json with new cwd paths
- Prompts (.pi/prompts/opsx-*.md) are now thin wrappers delegating to skills - openspec-propose skill: Docker-isolated sandbox (no host port exposure), scenario.json-driven screenshots, mockup screenshot capture, user approval gate with subagent resume (not restart) - sandbox/docker-compose.yml: removed port mapping, all internal Docker network - Remove browser-visual-debug skill (replaced by scenario.json approach)
sandbox: - Install chromium + agent-browser in Dockerfile (no separate browser container) - Remove browser service from docker-compose, update healthcheck to verify Chrome - Launch headless Chromium in entrypoint.sh automatically - Add capture-screenshots.sh: one command to start sandbox, run scenarios, copy out skill (openspec-propose): - Document scenario.json flat-array format with example - Replace multi-step docker compose sequence with single capture-screenshots.sh call - Pass individual file paths (not directories) in subagent reads - Launch sandbox-designer subagent with async: true
- Single JSX render with responsive classes (no if(isMobile) branching) - Simplified to 5 rows desktop / 4 rows mobile - Meta chips for git, worktree, attached proposal - FolderActionBar: Tools dropdown (desktop), compact buttons (mobile) - Removed: TokenStats, FlowBadge, FlowLauncher, OpenSpecActions, PluginSlots, ProcessList, InlineRename, Drag-to-reorder, README button - Streaming/ask_user: clean monotone bg (no diagonal stripes) - ContextUsageBar: CSS custom properties instead of raw Tailwind colors - Fixed sandbox Dockerfile: chromium, agent-browser, npm run build - Updated openspec skills with lessons learned from implementation - Fixed 8 broken main specs (missing ## Requirements / ## Purpose headers)
Restructure design review as a state machine with checkpoint file and async subagents. Eliminate contradictions between skills, add --build to capture-screenshots.sh, and wire user into every review round via intercom. - sandbox/capture-screenshots.sh: add --build to force rebuild - sandbox-designer/SKILL.md: contact_supervisor for intercom, screenshot validation, non-sandbox rejection, async mode - openspec-apply-change/SKILL.md: Design Process State Machine (9 phases, checkpoint file, turn boundaries, intercom rules) - sandbox-designer agent: add contact_supervisor tool, update system prompt for intercom coordination - New specs: design-process-coordination, sandbox-designer-intercom, apply-change-design-loop - Updated specs: design-sandbox-docker (--build), design-sandbox- propose-integration (sandbox-only screenshots) Change: fix-design-process-coordination
- Delete packages/jj-plugin/ (~15 files) - Delete packages/shared/src/platform/jj.ts - Delete packages/server/src/routes/jj-routes.ts - Delete .pi/skills/jj-workspace/ and jj-workspace-fold-back/ - Delete jj-specific tests (4 files) - Delete openspec/specs/jj-workspace-plugin/ - Delete docs/plans/openspec-jj-bridge.md - Remove JjState type and DashboardSession.jjState field - Remove jj_state_update protocol message - Remove vcsKind/diffBase/baseLabel from SessionDiffResponse - Remove jj from ToolRegistry definitions - Remove gatherJjInfo() from bridge vcs-info - Remove sendJjStateIfChanged + lastJjStateJson from bridge - Remove enrichWithJjDiff/enrichWithVcsDiff from session-diff - Simplify session-grouping to pin > cwd - Remove clusterByWorkspaceName - Clean plugin-registry, FileDiffView, event-wiring, session-routes - Update README, architecture.md, all file-index docs - Remove jj-plugin from publish.yml, vitest.config, client deps - Remove .shadow/ from .gitignore, clean seed data - Add no-jj-regression.test.ts with grep gates All grep gates pass. Zero jj references remain in source/docs/config.
…s, unhealthy, light theme, labels - Use 3000px tall viewports in scenario.json (sidebar scrolls internally) - Remove 'reads' param from subagent invocation (sandbox-designer forbids it) - Add unhealthy container recovery step (docker compose down --volumes) - Add requirements for light+dark theme variants in mockups - Add requirement for visible <h2> labels above each state block - Add fullpage support and tall viewport docs to run-scenarios.sh
- Add turn-boundary pattern for designer invocation + user approval - Use checkpoint file (shared with apply-change state machine) - Add contact_supervisor instructions to task template - Complete turn instead of polling for async subagent results - Delete checkpoint on final summary
…ol contract pi's tool-definition-wrapper calls definition.execute(...), not handler. The tool was silently failing with 'definition.execute is not a function' on every invocation. Fixed by renaming handler→execute and matching the (toolCallId, params, signal, onUpdate, ctx) signature used by ask_user.
…-only Replace 'graceful fallback' and 'proceed without sandbox' with hard stops. If Docker unavailable or sandbox fails → STOP, ask user to install/fix Docker. Text-only proposal generation is never acceptable for UI changes.
Drop design-review-state.json file I/O. Agent writes its phase as a [STATE: phase=X | runId=Y | ...] line at end of turn, scans backwards on next turn to resume. Simpler, no file ops. Updated: apply-change SKILL, propose SKILL, design-process- coordination spec, apply-change-design-loop spec.
- sandbox-designer: if contact_supervisor fails with 'Multiple sessions',
fallback to intercom({to: <parent-session-id>})
- openspec-propose: include Parent session ID in designer task
- openspec-apply: same fallback in both init and review phases
- invocation rules updated in all three skills
pi does not persist plain-string tool results into toolResult.content,
leaving it absent and crashing estimateTokens with 'not iterable'.
Changed all return statements to [{type: 'text', text}] format.
pi 0.73.0 does finalized.result.content — raw arrays have no .content prop,
so JSON.stringify omits it and toolResult messages are written without content.
This crashes render-utils.js: result.content.filter() on undefined.
Return the AgentToolResult shape: {content: [...], details: {}}.
…ell word-splitting
curlArgs.join(' ') caused 'Content-Type: application/json' to be split into
two args by the shell. spawnSync with array args passes each argument intact.
Add maxHeapSizeMb to MemoryLimitsConfig (default 0 = Node default). Plumb nodeArgs through spawnNodeScript, cli.ts start, restart-helper, and bridge server-launcher so the setting takes effect on every code path: manual start, bridge auto-start, and /api/restart.
…estore type contracts
After resolving rebase conflicts toward incoming commits ("local wins"),
several files were left in a state that broke `tsc` or test assertions.
This commit reconciles them with the post-rebase snapshot:
- Re-thread `--max-old-space-size` through the modern `launchDashboardServer`
/ `spawnNodeScript` stack instead of the removed `resolveJitiImport` path.
Adds `nodeArgs` to `LaunchOpts` + `SpawnNodeScriptOptions`; plumbs
`config.maxHeapSizeMb` from CLI start, bridge launch, and `/api/restart`.
- Bump `packages/client` deps to ^0.5.1 and add `dashboard-plugin-runtime`.
- Extend `SpawnFailureCode` with worktree codes (`dirty_working_tree`,
`branch_not_found`, `not_a_git_repo`, `git_unavailable`,
`branch_already_checked_out`, `SPAWN_HOOK_ERR`, `FORK_DEGRADED_TO_NEW`).
`SpawnErrorBanner` switched to `Partial<Record>` with hints for new codes.
- `App.tsx` drops `openspecGroupsMap` / `retrySessionIds` props that the
redesigned `SessionList` no longer accepts.
- `session-api.ts` routes `execSync` through shared platform/exec to keep
the `no-direct-child-process` lint test passing.
- `push-notify-user-tool.ts` types `spawnSync<string>` so utf-8 stdout
isn't typed as `Buffer`.
- Drop the orphan `buildSpawnEnv` import + test block from the extension's
launcher test (function moved into `ToolResolver.buildSpawnEnv`).
- Honcho comments: remove stale jj references that tripped the
no-jj-regression test.
- Update redesigned-component test assertions: `SessionCard` pulse classes
(`/5` opacity, no `card-unread-pulse`), `ContextUsageBar` CSS-var fill,
`BranchPicker` no longer skips the current branch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Member
|
@Termina1 Very nice job! I have to analyze the pack you've made, lot of features and bugfixes have to check. |
Author
|
sorry, I didn't mean to send PR, made it accidentally I'm currently just experimenting with different stuff so not sure its useful for you |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.