Skip to content

feat(workbench): add browser workspace, kanban feedback, and executor CLI foundations#1

Closed
gu87 wants to merge 105 commits into
mainfrom
codex/merge-8787-capabilities-into-9119
Closed

feat(workbench): add browser workspace, kanban feedback, and executor CLI foundations#1
gu87 wants to merge 105 commits into
mainfrom
codex/merge-8787-capabilities-into-9119

Conversation

@gu87

@gu87 gu87 commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Summary

This branch delivers three foundation layers for the Hermes Agent desktop workbench. First, a read-only Browser Workspace — an Electron host that renders external URLs and exposes a chat message insertion contract, without any browser automation capability. Second, kanban review/QA feedback events — structured defect tracking wired into the CLI kanban surface. Third, a complete executors framework spanning a typed registry, capability-based router, five CLI adapters, guarded worktree tools, context/inbox/prompt tooling, an IPC bridge, review chain primitives, and a top-level argparse CLI entry point. Two UI upgrades ship alongside: structured tool-result preview panels and embedded chat session routing. All executor modules are backed by 463 passing tests, destructive operations are gated behind confirmation prompts, and import side-effect guards prevent the CLI from leaking into live subsystems.

What Changed

Browser Workspace

  • Electron host scaffold: main.ts (lifecycle, window management, IPC handlers), preload.ts (context bridge), renderer.html (shell), schema.ts (typed contracts)
  • Chat message insertion contract (browser-workspace:insert-chat-message) validated against a golden contract-snapshot.json via validate-contract.mjs
  • Static dashboard plugin assets under plugins/browser-workspace/dashboard/
  • The host renders external URLs in a BrowserView; it does not implement click, type, submit, or navigate automation

Kanban Review/QA Feedback

  • hermes_cli/kanban_feedback.py — structured review and QA defect event types with typed routing
  • hermes_cli/kanban.py — kanban surface integration glue
  • hermes_cli/web_server.py — lightweight HTTP server for dashboard plugin delivery
  • Unit coverage in tests/hermes_cli/test_kanban_cli.py

Structured Preview UI

  • web/src/components/ToolCall.tsx — structured preview panel that renders tool results with formatted sections instead of raw JSON blobs
  • web/src/components/ChatSidebar.tsx — expanded sidebar with session list, routing, and status indicators
  • web/src/pages/ChatPage.tsx / web/src/pages/ConfigPage.tsx — page-level wiring for preview and sidebar
  • web/src/App.tsx — top-level routing integration

Embedded Chat Routing Mode

  • Chat session routing embedded into the web app shell so the UI can deep-link into specific sessions without full page reloads

Executors Framework

A — Core Registry and Router

  • executors/registry.py — typed executor registry with binary discovery and structured health probes
  • executors/router.py — capability-based router that produces recommendations and accepts user overrides
  • executors/types.py — shared dataclass type system (capabilities, routing decisions, health status, executor info)
  • executors/health.py — per-executor health checks with table and JSON output formatters

B — Adapters

  • executors/claude_code_adapter.py — Claude Code CLI adapter
  • executors/codex_adapter.py — Codex adapter
  • executors/deepseek_tui_adapter.py — DeepSeek TUI adapter
  • executors/hermes_local_adapter.py — Hermes local adapter
  • executors/opencode_adapter.py — OpenCode adapter
  • All adapters conform to the shared ExecutorCapabilities contract defined in types.py

C1 — Context / Inbox / Prompt Tools

  • executors/context.py + executors/context_cli.py — workspace context injection CLI
  • executors/inbox.py + executors/inbox_cli.py — external inbox management CLI
  • executors/prompt_builder.py — structured prompt assembly from context + task spec

C2 — Guarded Worktree Tools

  • executors/worktree.py + executors/worktree_cli.py — worktree create, list, merge, and discard
  • Merge and discard operations require explicit user confirmation or --force; the gate is verified in tests
  • Root resolution walks up to the parent repository, avoiding path assumptions

D1a — Bridge / IPC / Review Parsing Primitives

  • executors/ipc.py — typed IPC message protocol with structured envelopes
  • executors/bridge.py + executors/bridge_cli.py — run-event-log ↔ review bridge
  • executors/review_agent.py — review chain agent logic

D1b — Review Handler + Review CLI

  • executors/review_handler.py — review orchestration handler
  • executors/review_cli.py — review subcommand CLI

D2 — Top-Level CLI

  • executors/cli.py — argparse-based entry point wiring all subcommands: registry, health, routing, worktree, context, review, QA, inbox, and bridge
  • executors/__init__.py — package public API surface
  • Delegates destructive subcommands (worktree) to the guarded handler paths
  • Import side-effect guards verified in tests: importing the CLI module does not invoke shutil.which, load hermes_cli, or spawn subprocesses

Safety Boundaries

  • Browser Workspace is strictly read-only. The Electron host renders external URLs in a BrowserView and exposes a chat message insertion IPC contract. No agent can click, type, submit, or navigate within the rendered page. No browser automation capability exists in this PR.
  • No Chrome extension compatibility layer. The Browser Workspace uses an Electron shell, not a Chrome extension harness. Chrome extension APIs (tabs, scripting, debugger) are not used or polyfilled.
  • Worktree destructive operations are gated. Merge and discard both require explicit user confirmation (interactive prompt) or --force. Tests verify the gate blocks unconfirmed destructive calls.
  • Executor tests never call real external CLIs or models. All adapter tests use binary stubs or mock registries. No network requests, no child-process side effects, no real model invocations.
  • Import side-effect isolation. Five boundary guard tests confirm that importing executors/cli.py does not trigger shutil.which, does not load hermes_cli, does not spawn subprocesses, and does not import worktree, kanban_feedback, or other uncommitted modules at the top level.
  • No force push, no destructive repo operations. All worktree tests operate on temporary directories under $TMPDIR. No repository-level destructive operations are performed by any test.

Validation

Check Result
Browser host TypeScript compilation ✅ passes
Browser host contract validation (validate-contract.mjs) ✅ passes (snapshot matches schema)
Web build (web/) ✅ passes
Kanban CLI tests ✅ passes
Structured preview UI build ✅ passes
py_compile — all executor modules ✅ passes
tests/executors/ full suite 463 passed, 0 failed
tests/executors/test_cli.py ✅ 48 passed
Import side-effect guards (5 checks) ✅ all pass
Missing-binary fallback resilience (3 checks) ✅ all pass
Worktree confirmation gate tests ✅ gate blocks unconfirmed, --force bypasses

What Did Not Ship

  • Browser action automation — no click, type, submit, navigate, or scroll APIs
  • Chrome extension compatibility — no chrome.tabs / chrome.scripting / chrome.debugger bridge
  • ChatSessionSidebar wiring — kept as a local excluded draft, not connected to the app shell in this PR
  • Production Electron packaging, code signing, or auto-update
  • Full security threat model for the Electron Browser Workspace host
  • External browser adapter implementation (browser_adapter.py)
  • End-to-end multi-step executor orchestration pipelines
  • Bridge ↔ kanban feedback path integration (the two remain architecturally separate by design)

Risks / Follow-ups

  • Native macOS visual checks are still needed for the Electron Browser Workspace. TypeScript compilation and contract validation pass, but the rendered shell has not been visually verified on macOS.
  • Executors review/QA path remains separate from the kanban_feedback event path by design. Future work may bridge them at the routing or bridge layer, but for now they are independent subsystems.
  • ChatSessionSidebar is kept as a local excluded draft. It is not wired into the app shell and is not part of this PR. Downstream work will need to integrate it.
  • Larger end-to-end executor orchestration (multi-step run pipelines with real adapters) still needs integration testing. The current tests validate each module in isolation.
  • hermes_cli/kanban_feedback.py introduces a new feedback event path. Its interaction with the existing kanban CLI surface should be documented before downstream consumers adopt it.
  • Browser Workspace contract is validated against a golden snapshot. If the IPC contract evolves, the snapshot must be updated and re-validated.

Commit Breakdown

SHA Title Purpose
ce62fbc5c feat(browser-workspace): Electron host lifecycle + chat insertion contract Scaffold the read-only Browser Workspace: Electron main process lifecycle, preload context bridge, renderer shell, typed schema, contract validation script, and golden snapshot
312050bfe feat(kanban): add review and QA feedback events Structured review/QA defect event types, routing, and kanban surface integration
313b5d896 feat(ui): add structured preview panel for tool results Render structured tool-call results in a formatted preview panel instead of raw JSON
86d2b64e7 feat(ui): add embedded chat routing mode Add embedded chat session routing to the web app shell
51671f813 feat(executors): add core registry and router API Typed executor registry with binary discovery, health probes, and capability-based router
b9b28ddf4 feat(executors): add CLI adapter implementations Five adapters (Claude Code, Codex, DeepSeek TUI, Hermes local, OpenCode) implementing the shared capabilities contract
db8129cf0 feat(executors): add context inbox and prompt tools Workspace context injection CLI, external inbox management CLI, and structured prompt assembly
a95211d9e feat(executors): add guarded worktree tools Worktree create/list/merge/discard with confirmation gates on destructive operations and parent-repo root resolution
50bb17679 feat(executors): add bridge IPC and review parsing primitives Typed IPC message protocol, run-event-log ↔ review bridge, and review chain agent logic
5b150a6be feat(executors): add review handler and CLI subcommands Review orchestration handler and review subcommand CLI
7bbb0a3ed feat(executors): add top-level CLI integration Argparse-based entry point wiring all subcommands with import side-effect isolation and delegation to guarded handlers

🤖 Generated with Claude Code

Gu and others added 30 commits May 18, 2026 20:11
- 新增 agent/token_juice.py(137行),对标 OpenHuman TokenJuice
  Gate 1: 短输出直通 (<240 chars)
  Gate 2: 文件查看命令不压缩 (cat/tail/head/bat)
  Gate 3: 无效摘要丢弃 (压缩比 >= 95% 则拒绝)
- hermes_constants.py: 添加 TokenJuice 常量
- context_compressor.py: 在工具输出修剪和对话摘要两处集成安全阀
- model_metadata.py: 新增 MODEL_COST_PER_1K 价格表(10个主流模型)
  + get_model_cost_tier() 三级分档 (light/medium/heavy)
  + resolve_model_by_cost_tier() 按档位自动选模型
- auxiliary_client.py: 新增 get_cheapest_available_model(tier)
- delegate_tool.py: 子 agent 创建时支持 cost_tier 自动路由
  当 profile 设了 cost_tier 但未指定 model 时,自动选最便宜模型
- 新增 plugins/memory/fts5_builtin/ 插件(~250行,零依赖)
- store.py: SQLite + FTS5 虚拟表 + 自动同步触发器
- __init__.py: FTS5BuiltinProvider 实现 MemoryProvider 接口
  3 个工具: fts5_add / fts5_search / fts5_list
  prefetch() 走 user message 注入路径(保护 prefix cache)
- 配置: memory.provider: fts5_builtin
…tests

- token_juice: add absolute/relative floor checks in compression_safe_to_apply
- fts5_builtin: add on_memory_write mirror, UNIQUE constraint, WAL mode, limit clamping
- tests: add Gate3 regression, model cost-tier routing, fts5 provider tests
- assets: add screenshots, search configs, and worldcup snapshot

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Gu added 26 commits June 2, 2026 18:47
- DiscordEntryAdapter: normalizes Discord message payloads into EntryEvent
- Maps: guild->source, category->workspace, channel->session, thread->sub-session
- Bot/self-message rejection, intent detection (mention/command)
- Health reporting: configured/unconfigured
- Full isolation: adapter does not call agents/routes/policy directly
- 39 tests covering registration, normalization, mapping, rejection,
  unsupported entrypoints, adapter isolation, health, intent, pipeline
- Adds docs/known-issues/mcp-tooling-infra-test-failures.md for
  pre-existing infrastructure test debt classification
- FeishuEntryAdapter: normalizes Feishu inbound payloads into EntryEvent
- Maps: tenant_id -> workspace, chat_id -> session, thread_id -> sub-session
- Preserves existing Feishu transport (gateway/platforms/feishu.py untouched)
- Session_key support for backward compatibility with existing session model
- Intent detection: command (/) and mention (@)
- Health reporting: configured/unconfigured based on app_id
- 41 tests covering registration, normalization, mapping, rejection,
  unsupported entrypoints, adapter isolation, health, intent, pipeline
- Audit doc: docs/audits/feishu-source-of-truth-audit.md
- FeishuSessionBindingBridge: sidecar module that records Feishu session
  bindings without affecting existing message flow
- Hooked into FeishuAdapter._process_inbound_message() after session_key
  is built but before _dispatch_inbound_event()
- Uses FeishuEntryAdapter (Phase 5A) to normalize SessionSource into EntryEvent
- Writes to SessionBinding store (Phase 1) with key=feishu:{chat_id}:{thread_id}
- Fully isolated: failures are caught and logged, main flow continues
- Preserves all existing behavior: SessionStore, dispatch, transport untouched
- 9 tests covering happy path, thread/no-thread, idempotency, graceful
  failure, workspace derivation, lookup round-trip, fallback, no side effects
…teractive session cards

Phase 5B implementation:

- feishu_session_resolver.py: Full resolution chain
  (card > alias > p2p > thread > group > ambiguity > default)
  with FEISHU_AMBIGUITY_CARD_ENABLED feature flag (default: false)

- feishu_session_cards.py: Interactive card JSON builder for
  session selection, acknowledgement, and rejection cards

- FeishuEntryAdapter.resolve_session_with_ambiguity(): Delegates
  to resolver for full priority chain resolution

- session_binding.py: SessionBindingValue dataclass with source
  tracking (card/thread/alias/default), backward-compatible read
  of old 2-tuple format, BindingSource literal type

- feishu_session_binding_bridge.py: Extended with
  resolve_feishu_session_from_source(), check_feishu_ambiguity(),
  build_session_selection_card(), handle_select_session_card_action()

Tests: 177 v2.10 scoped tests pass (28 resolver + 17 binding +
21 bridge + 41 feishu adapter + 36 discord + 14 entry + 20 workspace/session)
Phase 5C implementation:

- feishu_permission_gate.py: Two-layer access control model
  (global allowlist + per-group policy: open/allowlist/blacklist/admin_only/disabled)
  Advisory only — does not modify routing or policy execution.
  Includes from_env() builder, check() method, health() snapshot.

- feishu.py: Add select_session card action handler (~8 lines)
  When a user taps a session selection card button, the action is
  dispatched to handle_select_session_card_action() from the bridge.

- Tests: 23 permission gate tests, 200 v2.10 scoped total
…lthCard, V210WorkspaceContext

- Add 5 backend API endpoints: workspaces list/get, sessions list/get, adapters/health
- Add v2.10 TypeScript types and API methods in api.ts
- Add AdapterHealthCard component to OperationsPage
- Add V210WorkspaceContext component to SessionsPage
- Add 12 backend API tests
- Add Phase 6 plan doc

Backend: 212 v2.10 scoped tests pass
Frontend: zero errors build
Phase 7 design doc for Mac App as lightweight desktop shell:
- WKWebView wrapping Web Console at localhost:9119
- Process lifecycle management
- macOS notification bridge
- mac_app EntryAdapter registration
- No code — design documentation only
Gate checks:
- Working tree clean, branch codex/merge-8787-capabilities-into-9119
- 212 v2.10 scoped tests passing, 0 failures
- Frontend build clean (TypeScript + Vite)
- Feishu transport: 9-line sidecar, feature-flagged
- No silent fallbacks, no ambiguities in disabled state
- All non-capabilities explicitly documented

Recommended tag: v2.10-multi-entry-session-binding
- Tag: v2.10-multi-entry-session-binding (858af63)
- 6 phases implemented, 212 tests passing
- Deferred: Lark CLI tooling, streaming cards, approvals, Discord prod, Mac App
- Recommended next: v2.11 Feishu Operation Layer
Six sections covering:
- A: Web Console (AdapterHealthCard, V210WorkspaceContext, API endpoints)
- B: Feishu understandability (entry adapter, resolver, ambiguity, permission gate)
- C: Discord dormant status verification
- D: Release boundaries (Lark CLI, streaming, approvals — none present)
- E: Observations log
- F: Go/No-Go for v2.11

All checks manual, no code changes required.
…d, V210WorkspaceContext

- Add operations + v210 i18n keys to types.ts, en.ts, zh.ts
- Translate key OperationsPage labels: title, agent health, queue, advisory
- Translate AdapterHealthCard: status labels, mode descriptions
- Translate V210WorkspaceContext: mode, workspaces, sessions, adapters
- Entrypoint labels in AdapterHealthCard now show in Chinese (飞书, CLI, etc.)
- All v2.10 components use i18n with fallback to English
- operations + v210 fields are optional in type (non-en/non-zh unchanged)

Frontend build: zero errors. Backend tests: 12 passed.
Bug fixes:
- setTitle('Operations') → setTitle(t.operations?.title ?? ...) with t dependency
- H1 header uses i18n (Agent 运营中心)
- Section labels use i18n (Agent 健康, 队列与调度)
- Badge labels use i18n (仅作参考, 仅作建议)

Fixed: original variable rename corrupted UI text strings (Some operations data).
This version only changes display labels, never touches variable names.

Build: successful. Tests: 12/12 passed.
…tract

browser-host/: new Electron child-process (status/start/stop + snapshot/screenshot/context proxies) — Phase 2B + 2C

plugins/browser-workspace/dashboard/: Codex-like sidebar tab (manifest + bundled dist/index.js) — Phase 4 entry point

hermes_cli/web_server.py: expose /api/browser-host/{status,start,stop,snapshot,screenshot,context} and read-only HTTP proxy to the host on localhost — Phase 2B/2C

web/src/pages/ChatPage.tsx: window.__HERMES_INSERT_CHAT_TEXT__ (term.paste path) + window.__HERMES_SET_BROWSER_CONTEXT_REF__ (metadata only — no DOM/selection/clipboard) — Phase 4A/4B

Out of scope: Kanban review/qa CLI + diff events; Codex-like embedded-chat nav reshuffle; ToolCall selected ring; ChatSidebar structured preview parser; executors/ module; dashboard screenshots.
Add review/qa CLI subcommands, emit diff events after dispatch, and publish diff/review/qa task events to the dashboard WebSocket stream.

Includes focused CLI tests for dispatch diff recording and review/QA result events.
Parse diff, review, QA, and artifact payloads from tool events and render them in a dedicated ChatSidebar detail panel.

Add ToolCall onClick/selected props for activity-list selection and highlight state, with graceful fallback for unparseable results.
Redirect root and unknown routes to /chat when embedded chat mode is enabled, slim the sidebar nav for chat-first usage, and add Config diagnostics links for hidden dashboard pages.
Add the core executor types, registry, router, and health helpers behind a core-safe package API that does not import adapter implementations.

Add router and registry tests covering keyword recommendations, fallback behavior, default manifests, and missing-binary health checks without invoking live models.
Add Hermes Local, Claude Code, Codex, OpenCode, and DeepSeek TUI executor adapters implementing the AgentExecutorAdapter protocol.

CLI adapters use asyncio subprocess array calls without shell=True; Hermes Local restores cwd with try/finally; DeepSeek TUI remains an explicit unavailable stub.

Add adapter registry tests covering imports, missing-binary health checks, inert imports, and no live CLI/model/worktree side effects.
Add project-scoped workspace context, inbox persistence, and per-executor prompt building utilities.

These tools write only to caller-supplied project .hermes files and do not invoke subprocesses, models, git, or external services.

Add tests covering JSON round trips, default loading, prompt generation, inbox lifecycle, and side-effect boundaries.
Add worktree lifecycle utilities and CLI helpers with dirty-tree rejection and confirmation gates for destructive merge/discard operations.

Fix the clean-working-tree preflight check so user dirty files reject worktree creation while .hermes infrastructure files are ignored as intended.

Add worktree tests covering dirty rejection, infra filtering, merge/discard confirmation, and tmp-repo-only git operations.
Add IPC dataclasses, review/QA prompt parsing primitives, and a fixture-driven bridge CLI simulation layer without importing the real review handler.

Keep D1a read-only and subprocess-free; bridge CLI uses local stubs for review/QA simulation while D1b decides the real review backend boundary.

Fix diff deletion parsing so file header lines are not counted as deletions.
Adds the executors/IPC rail for review and QA, parallel to the existing
hermes_cli.kanban_feedback trigger_* path. The two rails target different
consumers (Kanban SQLite vs. Electron IPC) and are NOT interchangeable.

- executors/review_handler.py: trigger_review_ipc / trigger_qa_ipc async
  wrappers around _launch_opencode, with shutil.which gate, OpencodeUnavailable
  exception, emit_diff_event side-channel, and stub_review_report / stub_qa_report
  fallback when opencode is absent. Module docstring documents the dual-rail
  architecture to prevent confusion with kanban_feedback.trigger_*.
- executors/review_cli.py: 6 subcommand handlers (build-prompt / parse /
  executor for both review and QA) + handle_review_command / handle_qa_command
  dispatchers. SEVERITY_ICONS map for human-readable output.
- tests/executors/test_review_handler.py: 582 lines, 9 test classes
  covering rename verification, IPC happy paths, fallback paths, subprocess
  invocation, side-channel events, stub reports, exception handling, and
  boundary guards (no kanban_feedback, no executors.cli, no executors.bridge,
  no sqlite3 imports, no real opencode invocation).
- tests/executors/test_review_cli.py: 443 lines, 9 test classes covering
  all 6 subcommand handlers, dispatchers, SEVERITY_ICONS lookup, and
  parallel boundary guards.

The rename trigger_* -> trigger_*_ipc was required to disambiguate from
hermes_cli.kanban_feedback.trigger_* which writes to the Kanban SQLite
task_events table. Both are live in parallel; callers pick the rail
appropriate to their consumer (CLI vs. Electron IPC).

70 new tests; full executors suite: 415 passing (was 345).
Add the argparse-based executor CLI entry point wiring registry, health, routing, worktree, context, review, QA, inbox, and bridge subcommands.

Preserve destructive operation gates by delegating worktree actions to the guarded C2 handlers, and keep imports free of hermes_cli or live external CLI side effects.

Add CLI tests covering registry commands, delegation, help output, missing binaries, import side effects, and boundary guards.
@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown

🚨 CRITICAL Supply Chain Risk Detected

This PR contains a pattern that has been used in real supply chain attacks. A maintainer must review the flagged code carefully before merging.

🚨 CRITICAL: Install-hook file added or modified

These files can execute code during package installation or interpreter startup.

Files:

hermes_cli/setup.py

Scanner only fires on high-signal indicators: .pth files, base64+exec/eval combos, subprocess with encoded commands, or install-hook files. Low-signal warnings were removed intentionally — if you're seeing this comment, the finding is worth inspecting.

@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown

🔎 Lint report: codex/merge-8787-capabilities-into-9119 vs origin/main

ruff

Total: 3 on HEAD, 0 on base (🆕 +3)

🆕 New issues (2):

Rule Count
PLW1514 2
First entries
executors/review_cli.py:159: [PLW1514] `pathlib.Path(...).read_text` without explicit `encoding` argument
executors/worktree.py:573: [PLW1514] `open` in text mode without explicit `encoding` argument

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 9033 on HEAD, 8915 on base (🆕 +118)

🆕 New issues (166):

Rule Count
unresolved-attribute 45
unresolved-import 40
invalid-argument-type 33
deprecated 8
unsupported-operator 7
invalid-assignment 6
invalid-parameter-default 5
unresolved-reference 4
not-iterable 4
invalid-return-type 4
not-subscriptable 4
no-matching-overload 2
empty-body 2
invalid-type-form 1
call-non-callable 1
First entries
tests/agent/test_entry_adapter.py:242: [unresolved-attribute] unresolved-attribute: Attribute `resolve_session` is not defined on `None` in union `EntryAdapter | None`
tools/delegate_tool.py:4071: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_subagent_effective_blocked` on type `ExternalCliChild`
tests/hermes_cli/test_web_server.py:336: [unresolved-attribute] unresolved-attribute: Attribute `append` is not defined on `int` in union `int | list[Unknown]`
executors/codex_adapter.py:280: [deprecated] deprecated: The function `utcnow` is deprecated: Use timezone-aware objects to represent datetimes in UTC; e.g. by calling .now(datetime.timezone.utc)
tests/managed_agents/test_kanban_bridge.py:201: [unresolved-attribute] unresolved-attribute: Unresolved attribute `execution_plan` on type `Task`
agent/conversation_loop.py:4121: [unresolved-attribute] unresolved-attribute: Attribute `fail` is not defined on `None` in union `Any | None`
tests/agent/test_entry_adapter.py:231: [unresolved-attribute] unresolved-attribute: Attribute `resolve_workspace` is not defined on `None` in union `EntryAdapter | None`
tests/plugins/memory/test_fts5_builtin_provider.py:9: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/agent/test_feishu_entry_adapter.py:6: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/agent/test_entry_adapter.py:3: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
agent/managed_agents/session_binding.py:58: [invalid-argument-type] invalid-argument-type: Argument is incorrect: Expected `Literal["card", "thread", "alias", "default"]`, found `str`
tests/executors/test_cli.py:135: [invalid-parameter-default] invalid-parameter-default: Default value of type `None` is not assignable to annotated parameter type `list[dict[str, Any]]`
tools/delegate_tool.py:2544: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_current_model_ref` on type `AIAgent`
tests/managed_agents/test_registry.py:4: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/executors/test_registry.py:252: [unresolved-attribute] unresolved-attribute: Attribute `lower` is not defined on `None` in union `str | None`
hermes_cli/kanban_db.py:1067: [unresolved-reference] unresolved-reference: Name `shutil` used when not defined
tools/delegate_tool.py:4321: [invalid-argument-type] invalid-argument-type: Argument to function `_build_external_cli_child` is incorrect: Expected `str`, found `Any | str | None | list[str]`
tests/executors/test_context.py:26: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/managed_agents/test_gateway.py:6: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
agent/conversation_loop.py:287: [invalid-assignment] invalid-assignment: Object of type `Any | None` is not assignable to attribute `fallback_used` on type `TaskCard | None`
tests/executors/test_review_cli.py:36: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/executors/test_ipc.py:20: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
gateway/platforms/feishu.py:2574: [unresolved-reference] unresolved-reference: Name `P2CardActionTrigger` used when not defined
tests/agent/test_feishu_permission_gate.py:4: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/executors/test_review_handler.py:546: [not-iterable] not-iterable: Object of type `None` is not iterable
... and 141 more

✅ Fixed issues (76):

Rule Count
invalid-argument-type 55
unresolved-attribute 11
unsupported-operator 4
invalid-assignment 3
unresolved-import 1
not-subscriptable 1
unresolved-reference 1
First entries
tests/skills/test_openclaw_migration.py:33: [invalid-argument-type] invalid-argument-type: Argument to function `module_from_spec` is incorrect: Expected `ModuleSpec`, found `ModuleSpec | None`
tests/hermes_cli/test_setup_openclaw_migration.py:427: [unsupported-operator] unsupported-operator: Operator `in` is not supported between objects of type `Literal["Discord"]` and `str | None`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2467: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["config.yaml session_reset"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2477: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["openclaw.json session (advanced)"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2410: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["archive/gateway-config.json"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2640: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["archive/channels-deep-config.json"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2757: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["openclaw.json approvals (rules)"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2772: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["archive/memory-backend-config.json"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2478: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["archive/session-config.json"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2680: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["openclaw.json browser (advanced)"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2715: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["config.yaml terminal"]`
tools/delegate_tool.py:3557: [invalid-argument-type] invalid-argument-type: Method `__getitem__` of type `Overload[(i: SupportsIndex, /) -> tuple[int, dict[str, Any] | dict[str, str | None | list[str]], Unknown], (s: slice[SupportsIndex | None, SupportsIndex | None, SupportsIndex | None], /) -> list[tuple[int, dict[str, Any] | dict[str, str | None | list[str]], Unknown]]]` cannot be called with key of type `str` on object of type `list[tuple[int, dict[str, Any] | dict[str, str | None | list[str]], Unknown]]`
tests/hermes_cli/test_setup_openclaw_migration.py:426: [unsupported-operator] unsupported-operator: Operator `in` is not supported between objects of type `Literal["Telegram"]` and `str | None`
agent/agent_router.py:374: [unsupported-operator] unsupported-operator: Operator `in` is not supported between objects of type `str & ~AlwaysFalsy` and `dict[Unknown, Unknown] | None`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2788: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["archive/skills-registry-config.json"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2375: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["config.yaml agent/compression/terminal"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:25: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to `<module 'yaml'>`
tests/hermes_cli/test_setup_openclaw_migration.py:561: [invalid-argument-type] invalid-argument-type: Argument to function `_gateway_platform_short_label` is incorrect: Expected `str`, found `str | list[str] | list[dict[str, str | bool]]`
agent/conversation_loop.py:216: [invalid-assignment] invalid-assignment: Object of type `Unknown` is not assignable to attribute `routing_basis` on type `TaskCard | None`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2264: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["openclaw.json hooks.*"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2552: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["agents.defaults.models"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2724: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["openclaw.json tools (full)"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2514: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal["config.yaml custom_providers"]`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:2585: [invalid-argument-type] invalid-argument-type: Argument to function `Migrator._get_channel_field` is incorrect: Expected `str`, found `str | dict[str, str] | Unknown`
optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py:1148: [invalid-argument-type] invalid-argument-type: Argument to bound method `Migrator.record` is incorrect: Expected `Path | None`, found `Literal[""]`
... and 51 more

Unchanged: 4644 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@gu87

gu87 commented Jun 6, 2026

Copy link
Copy Markdown
Owner Author

Wrong base repository/branch. This PR was opened against stale gu87:main, causing unrelated upstream files to appear in the diff (+82,204/−9,213, 347 files, 105 commits instead of the expected +18,058/−27, 60 files, 11 commits). Reopening against NousResearch/hermes-agent:main.

@gu87 gu87 closed this Jun 6, 2026
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