Skip to content

Merge - #22

Open
Termina1 wants to merge 52 commits into
BlackBeltTechnology:developfrom
Termina1:merge
Open

Merge#22
Termina1 wants to merge 52 commits into
BlackBeltTechnology:developfrom
Termina1:merge

Conversation

@Termina1

Copy link
Copy Markdown

No description provided.

Vyacheslav Shebanov 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.
Vyacheslav Shebanov and others added 22 commits May 10, 2026 11:49
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>
@Termina1 Termina1 closed this May 10, 2026
@Termina1
Termina1 deleted the merge branch May 10, 2026 22:30
@Termina1
Termina1 restored the merge branch May 10, 2026 22:30
@robertcsakany robertcsakany reopened this May 11, 2026
@robertcsakany

Copy link
Copy Markdown
Member

@Termina1 Very nice job! I have to analyze the pack you've made, lot of features and bugfixes have to check.

@Termina1

Copy link
Copy Markdown
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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants