Skip to content

Joysafeter v2#141

Open
yuzzjj wants to merge 267 commits intomainfrom
joysafeter-v2
Open

Joysafeter v2#141
yuzzjj wants to merge 267 commits intomainfrom
joysafeter-v2

Conversation

@yuzzjj
Copy link
Copy Markdown
Collaborator

@yuzzjj yuzzjj commented Apr 23, 2026

No description provided.

yuzzjj and others added 30 commits April 16, 2026 08:45
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements CodexProvider (JSON-RPC 2.0 over stdio) and OpenClawProvider
(stderr NDJSON), following the same pattern as ClaudeCodeProvider.
Updates registry to register all three providers and Dockerfile to
install Codex CLI. Adds 14 new unit tests covering event parsing for
both providers and registry integration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add real-time WebSocket execution stream with polling fallback
- Fix dark mode: replace hardcoded colors with CSS variables across
  execution-event, execution-timeline, mission-column, mission-card,
  and mission-detail-panel
- Fix undefined CSS vars (--bg-secondary, --bg-hover) with --surface-3
- Add proper loading, error, and empty states to execution timeline
- Add mobile touch scrolling to mission board

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…y-badge and agent-status

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…, reducer perf, task error handling

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add human-agent comment system for missions with auto-posting on
execution completion/failure, and fix critical chain-closure bugs:
execution completion now writes back mission status, clears
current_execution_id, terminates containers on cancel, and broadcasts
real-time events via WebSocket. Frontend notification provider
invalidates queries on mission/comment updates; Kanban shows all 7
status columns.

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
…tch 400

- Guard against non-dict JSON lines and string content blocks in Claude
  Code stream-json parsing (claude_code.py)
- Add isinstance check on result event's result field before calling .get()
- Default event.payload to {} in execution-event.tsx to prevent undefined access
- Expand ExecutionEventType and switch cases to handle backend event aliases
  (assistant_text, tool_use_start, tool_use_end, execution_started, etc.)
- Allow re-dispatch of IN_PROGRESS missions when current execution is terminal
- Mission board UI and filtering improvements

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
…sLive prop

- Share EVENT_CONFIG objects between alias pairs instead of duplicating
- Use config.label for status fallback instead of string replace
- Extract AgentPickerContent sub-component to eliminate duplicated
  Popover+Command blocks in mission-detail-panel
- Add isLive prop to ExecutionTimeline; past executions skip WebSocket
  and polling (N+1 connection fix)
- Limit past executions to 10 in detail panel
- Hoist inline imports in mission_service.py to module level
- Use Date.parse for isOverdue to avoid unnecessary Date allocations

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Containers are no longer destroyed after each execution — they stay
alive in a pool keyed by agent_profile_id and are reused on subsequent
dispatches. The pool also stores the Claude Code session_id so the
next execution resumes the prior conversation context via --resume.

- Add ContainerPool (container_pool.py) with get/put/release/evict/cleanup
- Rewrite ExecutionRunner.run() to pull from pool and release back
- Start a reaper background task (every 5 min) to evict idle containers
- On app shutdown, containers are left running for reuse after restart

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
… error display

- Extract shared credentials module (utils/credentials.py) with API key validation
- Pass credentials to docker exec via provider.execute(env=credentials)
- Detect Claude Code is_error flag to mark failed executions correctly
- Move build_credentials() before create_execution() to prevent orphan rows
- Add conditional refetchInterval — stop polling terminal executions/missions
- Use shared ACTIVE/TERMINAL status constants across frontend
- Fix cancel button visibility based on actual execution status
- Skip WebSocket for terminal executions in ExecutionTimeline
- Add toastError on dispatch/cancel failure in mission detail panel

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
- Add defaultOptions.mutations.onError to QueryClient with toastError
  so all mutation failures show a toast automatically — covers ~23
  previously silent call sites across missions, graphs, workspaces,
  folders, runs, and openclaw components
- Wrap mutateAsync in try/catch in mission-create-dialog to prevent
  unhandled promise rejection
- Remove redundant per-call-site onError from mission-detail-panel
  dispatch/cancel buttons (global handler covers them)

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
…error boundaries

- Add ValueError/RuntimeError/PermissionError → AppException translation in
  general_exception_handler, converting ~15 service-layer raises from 500 to
  proper 4xx responses without modifying any service code
- Remove duplicate Exception handler in main.py that overrode unified format
- Add safe_create_task() utility replacing ~15 bare asyncio.create_task calls
  with automatic error logging via done callbacks
- Fix skills.py DB session leak: fire-and-forget tasks now own their session
  via AsyncSessionLocal instead of using request-scoped db
- Fix codex.py ensure_future → put_nowait with QueueFull handling
- Add Next.js error boundaries (error.tsx + global-error.tsx) for page and
  root layout crash recovery
- Add QueryCache onError for background refetch failure toasts
- Add BaseService.safe_commit() with auto-rollback on failure

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
- Remove 5 dead `import asyncio` with misleading noqa comments in skills.py
- Fix _delete_from_container capturing closed request-scoped db session
- Migrate mission_service.py to safe_create_task, remove private duplicate
- Remove redundant except ValueError/PermissionError in mission_comments.py
  (global handler covers them; PermissionError was incorrectly mapped to 400)
- Move safe_create_task imports to module top-level across 6 files
- Add missing error.message fallback in global-error.tsx

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
… workspace ACL

- Fix SQL injection in memory_service.py: replace raw f-string topic query
  with text().bindparams() parameterized binding
- Add execution ownership verification to inject_message and approve_action
  endpoints — prevents cross-user execution manipulation
- Add DANGEROUS_PATTERNS command denylist to execute_local_command, shared
  with PydanticSandboxAdapter — blocks rm -rf /, mkfs, dd, fork bombs
- Add workspace membership checks to 16 endpoints across missions (7),
  agent_profiles (4), executions (1), mission_comments (4) using existing
  require_workspace_role dependency (viewer for reads, member for writes)
- Remove redundant except ValueError/PermissionError in missions.py

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
- Fix WorkspaceMemberRole imported from wrong module (app.models.enums → app.models.workspace)
- Reorder cheap enum validation before DB access check in create_mission
- Move session_registry import to top-level in executions.py
- Check session_registry (O(1)) before DB ownership query in inject/approve
- Unify HTTPException → NotFoundException for consistent error handling
- Move DANGEROUS_RE import to top-level in pydantic_adapter.py
- Move denylist check before try block in command_executor.py

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
…r, simplify

Backend:
- Add auto_approve toggle: bypassPermissions + DONE vs default + IN_REVIEW
- Add @agent mention dispatch in comments with dedup
- Add background scheduler (mission dispatcher + execution reaper)
- Add DELETE agent endpoint with orphan mission cleanup
- Expose agent profile fields, token usage (result_summary) in API
- Add control_request/control_response protocol for approval flow
- Add AssigneeType enum, TERMINAL_EXECUTION_STATUSES constant
- Extract _create_and_start_execution shared helper
- Convert post_execution_comment from classmethod to instance method
- Fix: token usage preserved in error paths (claude_code.py)
- Fix: custom_env → has_custom_env (security, write-only secrets)
- Fix: BACKLOG gating aligned between assignee and mention paths
- Consolidate list_dispatchable with optional workspace_id

Frontend:
- Add @mention input with agent dropdown in comment thread
- Render mentions as styled badges in comments
- Add auto_approve toggle in create dialog + detail panel
- Show token usage in execution timeline header
- Add status transition validation (MANUAL_TRANSITIONS)
- Add approval_resolved event type and display
- Lazy-load agent profiles (enabled on @ keystroke)

Migrations:
- Remove BLOCKED mission status
- Add auto_approve column to missions

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
… imports

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Switch dispatch/cancel/finalize callers in missions.py, executions.py,
mission_comments.py, and scheduler.py from MissionService to
ExecutionLifecycleService. The mission_comments.py 4-tuple unpacking
is intentionally ahead of the service return type change (Task 2.3).

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
…ng executions

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
…snapshot)

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
yuzzjj and others added 30 commits April 25, 2026 10:17
Aggregates execution events across all runs in a thread.
Cursor-based pagination via ?after=<event_id>.
Filters out copilot_* events server-side.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
- ThreadEvent type replaces ThreadMessage
- threadService.listThreadEvents and sendChat replace message methods
- useThreadEvents, useChatSend, useChatStream hooks

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
ChatPanel, ChatHistory, ChatEventBubble, ChatInput, ChatFilePreview,
AttachmentChip, ThreadSidebar — chat UI rendering execution events
as conversation bubbles.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
- ChatFilePreview: inline text content fetch with line preview, image
  fullscreen lightbox, PDF iframe viewer, auto-open small files
- ChatInput: drag-and-drop visual overlay, file validation with
  rejection logging, auto-resize textarea, max files indicator
- ChatHistory: streaming "Agent is working..." indicator
- All components have real error handling and loading states

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
- AgentChatTab, conversation-view, thread-list, use-agent-chat deleted
- ChatPanel now serves as chat tab in agent detail page
- workspaceId resolved in page component via useWorkspaces

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
- use-chat-stream: seq instead of sequence_no (matches ExecutionEvent type)
- ChatEventBubble: typeof check for payload.trace (unknown → string)
- ChatInput: cast ALLOWED_MIME_TYPES to readonly string[] for includes()

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
…0 errors

Published versions stay frozen after the publish flow, causing all
subsequent PATCH saves from the canvas to fail with 400. The builder
now detects frozen versions on load and auto-unfreezes them to draft.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
Introduce root-level WorkspaceProvider with Zustand-persisted workspace
selection, replacing 3 scattered workspace resolution patterns across 17+
files. Add permission guards (canEdit/canAdmin) to 7+ pages covering
agent settings, tools, sandboxes, tokens, agents list, memory, and tasks.
Fix crash on unauthenticated routes in useWorkspacePermissions hook.
Delete dead code (use-workspace-permission.ts).

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
The list-runs API requires workspace_id for permission validation, but
the copilot reconnect effect was omitting it, causing a 422 on page refresh.

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Replace soft-delete (archive) with hard delete that cascades through all
dependent records: versions, releases, runs, executions, events, artifacts,
and threads. Add delete button with destructive confirmation dialog to the
agent list page. Change grid from 3 to 4 columns. Fix AgentSummary schema
to include description field for list API.

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
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