Skip to content

fix: restore the 32 upstream files the consolidation deleted (packaged app boot fix)#155

Merged
OmarB97 merged 3 commits into
mainfrom
fix/restore-consolidation-deleted-upstream-files
Jun 10, 2026
Merged

fix: restore the 32 upstream files the consolidation deleted (packaged app boot fix)#155
OmarB97 merged 3 commits into
mainfrom
fix/restore-consolidation-deleted-upstream-files

Conversation

@OmarB97

@OmarB97 OmarB97 commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Why

The packaged desktop app built from the freshly merged #152 dies at boot: a hidden modal, zero renderer processes, busy main thread. Root cause: the June consolidation (9ac0530) deleted 35 files outright — git recorded them as deliberate fork deletions, so the #152 merge correctly preserved the deletions — and one of them, electron/desktop-uninstall.cjs, is required at main.cjs top level in upstream's (now merged) main process. 32 of the 35 still exist upstream; their restored tests then exposed the stale code counterparts the same way the #152 restorations were found.

What changed

  • All 32 upstream-extant deleted files restored verbatim (electron uninstall module + tests, assert-dist-built, gui_uninstall.py, uninstall-section.tsx, 14 upstream test suites, README.ur-pk, simplify-code skill, media/presets tests).
  • Code counterparts the restored tests pinned, each verified 9ac-only in fork history before taking upstream wholesale: hermes_cli/uninstall.py, hermes_cli/secrets_cli.py, hermes_cli/gateway.py, gateway/platforms/weixin.py, gateway/platforms/slack.py, agent/auxiliary_client.py, agent/image_routing.py, plugins/model-providers/kimi-coding/, apps/desktop/src/lib/media.ts, apps/desktop/src/themes/presets.ts.
  • Feature-merge where the fork genuinely evolved: agent/context_compressor.py gains upstream's cross-session stale-summary guard ([Bug]: Context compaction cross-contamination — cron session summaries leak into unrelated live conversations NousResearch/hermes-agent#38788) and the temporal-anchoring prompt rule alongside the fork's live_context_tokens + 0.85 threshold; global.d.ts gains the DesktopUninstall* declarations its (already-merged) bridge API references; ClientSessionState gains turnStartedAt plus its initializer.

How to review

  1. git log 9ac053087 --diff-filter=D --name-only against this diff — every restored file traces to that deletion set or to a test it re-enabled.
  2. The context_compressor diff is the only multi-source file: the two upstream blocks are comment-marked, and the fork's live-estimate machinery is untouched (suite covers both).
  3. Everything else is git checkout upstream/main -- <path> verbatim; spot-check any file against upstream.

Evidence

  • Boot failure proof: packaged build from merge upstream (88+ commits): resolve the 26-file conflict, restore consolidation-lost code, green the Tests workflow #152 main → Cannot find module './desktop-uninstall.cjs' class (asar listing lacked the file; app pid alive with zero Helper processes). After restore: main.cjs parses, build green.
  • Restored suites green per-file: gui_uninstall 25, compressor 99 (incl. the two restored feature suites), kimi 19, weixin 13, systemd-directives 11, aux-headers 8, slack-channel-scope 7, custom-providers-vision 13, bitwarden-non-tty 5.
  • Desktop: tsc -p . --noEmit green; production vite build green; test:desktop:platforms 141/141.

Verification

  • All counts above re-run at this head locally.
  • Post-merge deploy receipt (rebuild + swap /Applications/Hermes.app, boot smoke with renderer processes + window) lands on MeshBoard task hermes-fork-resolve-85-commit-upstream-sync-25-file's event log.

Risks / gaps

  • Remaining 3 of 35 deletions have no upstream counterpart (fork-only artifacts) — intentionally not restored; low risk.
  • The rotating shard-5 CI noise may attribute unrelated failures to this PR — already tracked as hermes-ci-rotating-shard-bound-test-failures-under-the.

Collaborators

  • @OmarB97 (operator)
  • Claude Fable 5 (ko-mac.claude, upstream-sync instance)

… code counterparts

The June consolidation (9ac0530) deleted 35 files outright, 32 of which
still exist upstream — including electron/desktop-uninstall.cjs, required at
main.cjs top level, which made the packaged app die into a hidden modal at
boot (zero renderers, busy main thread). All 32 restored from upstream, plus
the stale code counterparts their tests exposed, each verified 9ac-only in
fork history before taking upstream wholesale: hermes_cli/{uninstall,
secrets_cli,gateway}.py, gateway/platforms/{weixin,slack}.py,
agent/{auxiliary_client,image_routing}.py, plugins kimi-coding,
lib/{media,presets}. Targeted ports where the fork genuinely evolved:
context_compressor gains upstream's cross-session stale-summary guard
(NousResearch#38788) and temporal-anchoring prompt rule alongside the fork's
live_context_tokens + 0.85 threshold; global.d.ts gains the
DesktopUninstall* declarations; ClientSessionState gains turnStartedAt
(+ initializer).

Verified: tsc green, vite build green, 122/122 platform node tests, and all
restored python suites green per-file (uninstall 25, compressor 99, kimi 19,
weixin 13, systemd 11, aux-headers 8, slack scope 7, vision 13, bitwarden 5).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

🔎 Lint report: fix/restore-consolidation-deleted-upstream-files vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 10689 on HEAD, 10647 on base (🆕 +42)

🆕 New issues (30):

Rule Count
unresolved-import 14
invalid-argument-type 6
invalid-assignment 4
unresolved-attribute 2
not-subscriptable 1
no-matching-overload 1
unsupported-operator 1
invalid-parameter-default 1
First entries
agent/auxiliary_client.py:3318: [invalid-argument-type] invalid-argument-type: Argument to function `_apply_user_default_headers` is incorrect: Expected `dict[Unknown, Unknown] | None`, found `Unknown | str | None`
tests/run_agent/test_vision_tool_messages.py:16: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/run_agent/test_infinite_compaction_loop.py:214: [invalid-assignment] invalid-assignment: Object of type `MagicMock` is not assignable to attribute `_generate_summary` of type `def _generate_summary(self, turns_to_summarize: list[dict[str, Any]], focus_topic: str | None = None) -> str | None`
tests/agent/test_custom_providers_vision.py:11: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/plugins/model_providers/test_kimi_profile.py:14: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
run_agent.py:3899: [unresolved-attribute] unresolved-attribute: Object of type `Self@_apply_user_default_headers` has no attribute `_client_kwargs`
tests/test_yuanbao_shutdown.py:29: [unresolved-import] unresolved-import: Module `gateway.platforms.yuanbao` has no member `WS_CLOSE_TIMEOUT_S`
tests/agent/test_auxiliary_user_default_headers.py:41: [not-subscriptable] not-subscriptable: Cannot subscript object of type `None` with no `__getitem__` method
tests/test_yuanbao_shutdown.py:24: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/run_agent/test_infinite_compaction_loop.py:36: [invalid-argument-type] invalid-argument-type: Argument to `ContextCompressor.__init__` is incorrect: Expected `int`, found `str | int | float`
tests/run_agent/test_infinite_compaction_loop.py:36: [invalid-argument-type] invalid-argument-type: Argument to `ContextCompressor.__init__` is incorrect: Expected `str`, found `str | int | float`
tests/run_agent/test_infinite_compaction_loop.py:36: [invalid-argument-type] invalid-argument-type: Argument to `ContextCompressor.__init__` is incorrect: Expected `int | None`, found `str | int | float`
tests/gateway/test_auto_voice_reply_format.py:7: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/agent/test_context_compressor_cross_session_guard.py:26: [no-matching-overload] no-matching-overload: No overload of bound method `MutableMapping.setdefault` matches arguments
tests/run_agent/test_infinite_compaction_loop.py:123: [invalid-assignment] invalid-assignment: Object of type `(msgs, he) -> Unknown` is not assignable to attribute `_find_tail_cut_by_tokens` of type `def _find_tail_cut_by_tokens(self, messages: list[dict[str, Any]], head_end: int, token_budget: int | None = None) -> int`
tests/hermes_cli/test_gui_uninstall.py:12: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/run_agent/test_infinite_compaction_loop.py:36: [invalid-argument-type] invalid-argument-type: Argument to `ContextCompressor.__init__` is incorrect: Expected `bool`, found `str | int | float`
run_agent.py:3892: [unresolved-attribute] unresolved-attribute: Object of type `Self@_apply_user_default_headers` has no attribute `api_mode`
tests/agent/test_auxiliary_user_default_headers.py:70: [unsupported-operator] unsupported-operator: Operator `not in` is not supported between objects of type `Literal["X-Drop"]` and `dict[Unknown, Unknown] | None`
tests/gateway/test_weixin_typing.py:7: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/gateway/test_slack_channel_session_scope.py:40: [invalid-assignment] invalid-assignment: Object of type `AsyncMock` is not assignable to attribute `handle_message` of type `def handle_message(self, event: MessageEvent) -> CoroutineType[Any, Any, None]`
tests/test_output_cap_parsing.py:1: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/hermes_cli/test_secrets_bitwarden_non_tty.py:11: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
hermes_cli/gateway.py:645: [unresolved-import] unresolved-import: Module `hermes_cli._subprocess_compat` has no member `windows_detach_flags_without_breakaway`
tests/run_agent/test_infinite_compaction_loop.py:130: [invalid-assignment] invalid-assignment: Object of type `bound method ContextCompressor._find_tail_cut_by_tokens(messages: list[dict[str, Any]], head_end: int, token_budget: int | None = None) -> int` is not assignable to attribute `_find_tail_cut_by_tokens` of type `def _find_tail_cut_by_tokens(self, messages: list[dict[str, Any]], head_end: int, token_budget: int | None = None) -> int`
... and 5 more

✅ Fixed issues (3):

Rule Count
unresolved-import 2
unresolved-reference 1
First entries
run_agent.py:2022: [unresolved-reference] unresolved-reference: Name `SimpleNamespace` used when not defined
hermes_cli/main.py:4172: [unresolved-import] unresolved-import: Cannot resolve imported module `hermes_cli.gui_uninstall`
hermes_cli/main.py:4182: [unresolved-import] unresolved-import: Module `hermes_cli.uninstall` has no member `run_gui_uninstall`

Unchanged: 5569 pre-existing issues carried over.

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

Omar Baradei and others added 2 commits June 10, 2026 14:04
…nsports counterparts

The first wave's restored tests exposed the next layer of consolidation
casualties, all 9ac-only in fork history and taken from upstream wholesale:
run_agent.py (vision-tool-message gating, with the fork's sender_device
flush and _emit_token_usage regrafted), providers/base.py, the
plugins/model-providers tree (xiaomi supports_vision_tool_messages=False,
kimi-coding profile), windows-native docs, and three stale test files.
Targeted ports: context_compressor regains upstream's no-op ineffective-
compression registration (NousResearch#40803 anti-thrash); the three fork-era kimi
kwargs tests now pin upstream's thinking-XOR-reasoning_effort contract
(sending both risks Moonshot 400s — the profile docstring documents it).

run_agent suite 376/376; compressor suites 131/131; providers 105/105;
vision/compaction/windows suites green per-file.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…etadata feature-merged

Stale fork-era test files replaced with upstream's current contracts
(opencode-go XOR reasoning, multimodal tool recovery, slack approval
buttons, tui npm install — all 9ac-only fork history). model_metadata.py is
a true feature-merge: the fork's llama.cpp/local-AI context-limit parsing
(available-context-size, structured n_ctx, provider-confirmed cache caps)
plus upstream's current parse_available_output_tokens_from_error (OpenRouter
breakdown + char-based caps). model_metadata 100/100 + output-cap 9/9 +
run_agent dir 1702/1704 (2 = cross-file contamination, green per-file).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@OmarB97 OmarB97 merged commit 9b6611e into main Jun 10, 2026
27 of 29 checks passed
OmarB97 pushed a commit that referenced this pull request Jun 10, 2026
A unit test could reach a real 'pip install': with the elevenlabs SDK
absent, any agent init whose tool checks touch a lazy feature walks
check_tts_requirements -> ensure("tts.elevenlabs") ->
_venv_pip_install (allow_lazy_installs fails open by design). Under
tests/run_agent/test_create_openai_client_proxy_env.py the install
tunnels through the test's fake proxy env vars and hangs to the suite
timeout — the intermittent test (3) failures on #148/#155.

Set HERMES_DISABLE_LAZY_INSTALLS=1 in _hermetic_environment, next to
the equivalent TIRITH_ENABLED guard: ensure() now raises
FeatureUnavailable immediately and the TTS check degrades to False
deterministically. tests/tools/test_lazy_deps.py already overrides the
var in both directions per test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
OmarB97 pushed a commit that referenced this pull request Jun 10, 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.

1 participant