Skip to content

Kruh and jj vcs support#25

Draft
jonasnobile wants to merge 46 commits intomainfrom
feat/extensions-kruh
Draft

Kruh and jj vcs support#25
jonasnobile wants to merge 46 commits intomainfrom
feat/extensions-kruh

Conversation

@jonasnobile
Copy link
Member

@jonasnobile jonasnobile commented Feb 24, 2026

No description provided.

@jonasnobile jonasnobile force-pushed the feat/extensions-kruh branch from 50ae4de to 36d5969 Compare March 2, 2026 14:11
@jonasnobile jonasnobile changed the title R;160R;43R Kruh Mar 2, 2026
@jonasnobile jonasnobile changed the title Kruh Kruh and jj vcs support Mar 2, 2026
@jonasnobile jonasnobile force-pushed the feat/extensions-kruh branch from 43015a7 to 8e208b8 Compare March 2, 2026 21:27
jonasnobile and others added 26 commits March 3, 2026 16:26
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ApiLayoutNode::App for embedding custom app panes in layouts,
and ActionRequest::CreateApp/CloseApp for managing app lifecycle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce App as a first-class layout leaf node alongside Terminal.
Add workspace methods for app CRUD (add, close, replace, tab),
focus management (focus_app_by_id), and generalized layout operations
(find_leaf_path) that work with both terminals and apps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement KruhPane — a native GPUI rewrite of the kruh automated
AI agent loop tool. Includes agent subprocess management, STATUS.md
parsing, prompt building, async iteration loop, config with 8 agent
definitions, and full render views for plan picking, task browsing,
editing, and running states.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ings

Wire app pane support throughout the UI layer:
- AppPaneEntity wrapper and app registry with factory dispatch
- Generalize PaneDrag to handle both terminals and apps
- App rendering in layout container with entity caching
- Tab bar support for app tabs (icons, labels, close, drag)
- AppPickerOverlay for creating apps (open as tab / replace pane)
- NewKruhApp and ShowAppPicker keybinding actions
- App items in sidebar with focus tracking
- Start App buttons on bookmark project column
- Action dispatch and remote type conversions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ensures an AGENT.md with default workflow guidelines is created in the
plans directory before each loop iteration. The prompt now references
AGENT.md when present so agents follow consistent conventions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ion traits

Adds serializable view-state and action types for remote rendering:
- New okena-core::app_state module with AppViewState and AppAction marker traits
- KruhViewState / KruhScreen enum for full UI snapshot
- KruhAction enum covering navigation, loop control, editor, and settings
- Supporting view-info structs (PlanViewInfo, IssueViewInfo, LoopViewInfo, etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements is_jj_repo, get_status, get_diff_file_summary,
get_diff_with_options, and get_file_contents_for_diff using
jj CLI subprocess calls and the existing parse_unified_diff parser.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Maps all 6 KruhState variants to the pure-data KruhViewState type,
capping loop output at 200 lines. No GPUI handles or Instants in output.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add four new public functions:
- update_frontmatter_content: pure upsert of YAML frontmatter keys
- update_issue_frontmatter: I/O wrapper for file-level updates
- extract_extra_frontmatter_keys: returns non-config frontmatter pairs
- iso_now: current local time formatted as YYYY-MM-DDTHH:MM:SS

Includes 10 unit tests covering creation, overwrite, body preservation,
empty input, key extraction, and timestamp format validation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces src/vcs.rs that detects the active VCS (Jujutsu preferred
over Git for colocated repos) and dispatches status, diff, and file
content queries to the appropriate backend. Includes a 5-second TTL
cache for jj status results mirroring the git module's cache pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After each iteration starts, write startedAt/agent/model/iteration to
the current issue file's frontmatter. After the agent exits, write
endedAt/exitCode/duration. Uses smol::unblock for async I/O; failures
are silently ignored to avoid breaking the loop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- watcher: use vcs::get_vcs_status instead of git::get_git_status
- diff_viewer: use vcs::is_vcs_repo, vcs::get_diff_with_options
- diff_viewer/syntax: use vcs::get_file_contents_for_diff
- Update "Not a git repository" message to "Not a version-controlled repository"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Dispatches every KruhAction variant to an existing or new stub method,
enabling remote clients to mutate KruhPane state without a Window handle.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Store extra (non-config) frontmatter keys when opening an issue in the
editor and merge them back alongside override keys on save, preventing
run metadata (startedAt, endedAt, exitCode, duration, iteration) from
being stripped. Also adds test_editor_roundtrip_preserves_metadata and
fixes pre-existing build errors from incomplete AppAction variant handling.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update project_column, context_menu, terminal_actions, and execute to
use vcs:: functions instead of calling git:: directly. Worktree-gated
features remain restricted to VcsBackend::Git.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Jujutsu has no staging area, so the Unstaged/Staged toggle is
irrelevant for jj repos. Track the VCS backend in DiffViewer and
hide the toggle (and its footer hint) when backend is Jujutsu.
Also block the Tab key for jj repos to prevent toggling mode.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
jonasnobile and others added 20 commits March 3, 2026 17:36
KruhPane now receives an AppStateBroadcaster via its constructor and
publishes a serialized KruhViewState snapshot on every notify, debounced
at 100ms to prevent flooding during rapid agent output.

The broadcaster is created once in Okena::new() and threaded through:
  Okena → RootView → ProjectColumn → LayoutContainer (+ child containers
  in split/tabs) → app_registry::create_app_pane() → KruhPane::new()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add AppEntityRegistry with type-erased view_state/handle_action closures
- KruhPane registers itself on construction, unregisters on drop
- Add GlobalAppEntityRegistry GPUI global set in Okena::new
- Add GetAppState and AppAction variants to RemoteCommand
- Handle both commands in the remote command loop
- Handle new variants in headless bridge (no-op responses)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Thread AppStateBroadcaster through AppState and RemoteServer::start.
Implement SubscribeApps/UnsubscribeApps/AppAction WS message handlers,
deliver initial state on subscribe, and push AppStateChanged events to
subscribed clients via a new tokio::select! branch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Walk ApiLayoutNode trees in the state response and call
get_view_state() for each App node so clients receive the current
KruhViewState on initial load, before subscribing to WebSocket updates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Change AppEntityHandle::handle_action closure type to accept &mut App
(Context<T> derefs to App, so this works from any GPUI context).
Handle ActionRequest::AppAction in execute_action via the
GlobalAppEntityRegistry global, enabling POST /v1/actions to dispatch
app-specific actions. Update RemoteCommand::AppAction handler to wrap
the call in cx.update().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add app_state_changed WebSocket handling in RemoteClient reader loop
- Subscribe/unsubscribe app streams on state_changed events
- Add WsClientMessage::SubscribeApps/UnsubscribeApps/AppAction and
  ConnectionEvent::AppStateChanged to okena-core types
- Add send_ws_message to RemoteConnection
- Add RemoteConnectionManager::register_app_pane and AppStateChanged
  handling to push state updates to RemoteAppPane entities
- Create RemoteAppPane GPUI entity that renders KruhViewState and
  dispatches KruhActions via ActionDispatcher
- LayoutContainer creates RemoteAppPane for remote projects instead of
  going through app_registry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add app variant to ApiLayoutNode and KruhViewState/KruhScreen types
- Add subscribeApps/unsubscribeApps/sendAppAction to WsManager
- Add appStates to app store with set_app_state reducer
- Create KruhPane component with all 6 screen variants
- Add app case to LayoutRenderer and AppPane component
- Handle app_state_changed WS message in App.tsx
- Subscribe to app IDs after fetching state
- Fix collectTerminalIds to handle app nodes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Plan to write run metadata (startedAt, endedAt, exitCode, duration,
iteration, agent, model) into issue file YAML frontmatter during
Kruh loop iterations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract agent workflow guidelines to standalone .plans/ files and add
CLAUDE.md with flex layout rules for app panes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace size_full() with flex_1().w_full().min_h_0() on divs that are
flex-column children, and add flex_shrink_0() on fixed headers/footers.
size_full() sets percentage-based height which doesn't resolve correctly
in Taffy when the parent uses flex layout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add LoopOverview state with loop cards, per-loop controls (pause,
skip, step, quit), scrollbar helpers, and keyboard navigation
(left/right to switch loops, p/s/q/t shortcuts). Replaces the
single-run Running view with a multi-loop dashboard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jonasnobile jonasnobile force-pushed the feat/extensions-kruh branch from 8e208b8 to 139511b Compare March 3, 2026 17:42
@jonasnobile jonasnobile marked this pull request as draft March 9, 2026 10:42
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.

1 participant