Commit Graph

14 Commits

Author SHA1 Message Date
kshitijk4poor
8792f7237f test(worktree): share the seed identity and work repo across narrow-clone tests
Review follow-up: one module-level identity per test file, and
_seed_origin returns the work repo instead of tests rebuilding its path.
2026-09-28 16:23:22 +05:30
kshitijk4poor
77019b3b7d fix(worktree): refresh any valid branch name used as a base
The glob guard compared the name with `_sanitize_branch`, which also
rewrites valid names such as "fix+1" or "feat/foo@bar". Their base
fetch was skipped, so the new worktree started from a stale tracking
ref. The Python and Electron guards also disagreed on non-ASCII names,
because Python's `\w` is Unicode and JavaScript's is ASCII.

Ask git instead: `git check-ref-format --branch` accepts every valid
branch name and rejects the refspec metacharacters (`* ? [ : ^ \`),
and both twins now make the same call.
2026-09-28 16:23:22 +05:30
kshitijk4poor
e3fffd8c17 fix(worktree): keep a local slash-named branch local
The remote fallback for narrow clones read any "<remote>/<name>" with no
tracking ref as a remote branch, even when it was an existing local
branch such as "origin/feature". That meant a network fetch on every
such checkout, and when the remote had the branch, the request quietly
became a new `feature` tracking it instead of the user's own branch.
Check refs/heads/<requested> first, in the web_git mirror and in the
Electron twin.

The tests share one seeded origin. `feature` now sits past tag v0, so
"branched from the remote, not the tag" has teeth. The pair of
conversion tests is parametrized, and #125699's hand-built narrow clones
use the shared helpers.
2026-09-28 16:23:22 +05:30
kshitijk4poor
be1181c533 fix(worktree): register a remote branch only after the fetch finds it
Converting "origin/<branch>" registered the branch on the remote
(`remote set-branches --add`) before fetching it, on every clone shape.
For a branch the remote doesn't have, such as a typo, that left a
refspec whose source is missing, and every later plain `git fetch` in
the repo failed with "couldn't find remote ref". Normal clones also
gained a redundant fetch line for each converted branch.

Fetch with the explicit tracking refspec first and try `--track`, which
needs no config change on a normal clone. Only when `--track` cannot
map the ref (a narrow clone) and the fetch proved the branch exists is
the branch registered and its upstream set.

The base arm reuses the same fetch, and only for names the branch
sanitizer leaves unchanged: `base` comes from the API, and "origin/*"
inside a refspec fetches every branch.
2026-09-28 16:23:22 +05:30
Konstantin Khlopkov
d31d9b3724 fix(worktree): convert an origin/ branch on a tag-pinned narrow clone
`existingBranch: "origin/<branch>"` failed on both halves of the
existing-branch conversion arm when the checkout is a tag-pinned
narrow clone (remote.origin.fetch maps only the tag):

- tracking ref absent: the ref-based remote detection misread
  "origin/feature" as a local branch name, so worktree creation died
  with `fatal: invalid reference`;
- tracking ref present: `worktree add --track` could not reverse-map
  the ref through the tag-only refspec, dying with `cannot set up
  tracking information`.

Register the branch on the remote additively (set-branches --add
keeps the existing refspec), fetch it through the updater's forced
refspec, and fall back to explicit `--set-upstream-to` wiring when
`--track` cannot do it. Normal clones keep today's behavior: the
wildcard refspec already covers the branch, so the registration is a
no-op.

Complements #125699, which fixes the `base: "origin/<branch>"` arm.
Fixes #125686 (existing-branch half).

(cherry picked from commit 8b32ee69b7879804b74b5e59cc99deb5ba0a3dbc)
2026-09-28 16:23:22 +05:30
686f6c61
6941423f45 fix(worktree): fetch origin bases with a tracking refspec
Tag-pinned narrow clones map remote.origin.fetch to the tag, so a
by-name fetch never creates origin/<branch> and worktree add fails
with an invalid reference. Use the same refspec the updater already uses.

(cherry picked from commit 673aa8491f7b9a064445dd8b69992cd871e64365)
2026-09-28 16:23:22 +05:30
teknium1
b8052c8d4a test(web): trim the gh auth probe tests to two invariants
Keep: overlapping cache misses share one probe (never two `gh` at once);
a refresh issued mid-probe after a login flip gets the fresh answer and
still never overlaps. Dropped: the bounded-helper call-shape detector (the
descendant cleanup is proven by the live wrapper probe, not by asserting
the helper's name), and the two tests of pre-existing behaviour (fresh
cache short-circuit, missing `gh`).
2026-09-15 18:54:51 -07:00
KoNit-K
460768056d fix(web): bound and deduplicate gh auth probes 2026-09-15 18:54:51 -07:00
Teknium
f8f43c9523 fix(desktop): make git worktrees work end-to-end on a remote gateway backend
Cmd/Ctrl+Shift+B worktree flows on a remote gateway route through the
backend's /api/git mirror (hermes_cli/web_git.py), but that mirror had
drifted behind the Electron-local git ops the same UI drives locally, so
the flows broke exactly and only on remote connections:

- Convert-a-branch: the picker offers remote-tracking refs, and the
  Electron op turns "origin/feature" into a local tracking branch. The
  mirror ran `git worktree add <dir> origin/feature` verbatim, which
  either fails or detaches HEAD. It now resolves the ref's remote via
  git (never assuming "origin"), fetches best-effort, and creates the
  worktree with `--track -b <short-name>`.
- branch_list omitted remote-tracking refs entirely and never set the
  `isRemote` flag the renderer's HermesGitBranch contract requires —
  the convert picker on a remote gateway couldn't reach a teammate's
  branch and mislabeled every row's action.
- Branching off an `origin/…` base silently wired the new branch to the
  remote upstream; the mirror now passes `--no-track` like the Electron
  op does.

Renderer side, replace the silent degradation with a capability gate:
when a remote backend predates the /api/git worktree routes, worktree
creation failed with an opaque "Expected JSON … got HTML" toast. The
route-missing shapes now surface a clear "update the Hermes backend"
message (isGitEndpointMissingError, mirroring the sidebar batch-endpoint
detector); real git errors still pass through untouched.

Sibling audit (documented, no code change needed): repo status / review /
file-diff / git-root / default-cwd already route through desktopGit()'s
REST bridge or /api/fs on remote; repo scan is deliberately a no-op there.
Stale comments claiming "empty/false on a remote backend" in projects.ts
and coding-status.ts updated to describe the backend-routed reality.

Fixes #81724
2026-08-16 20:53:44 -07:00
Teknium
39975613b1 test: prune wave 2 + speed fixes — 28,106 → 19,757 test functions, suite wall 315s → 294s
Second, deeper pass over tools/gateway/hermes_cli plus first pass over
the trees wave 1 missed (acp, acp_adapter, skills, computer_use, docker,
dashboard, conformance, monitoring, secret_sources, hermes_state,
providers). Same rubric as wave 1 (AGENTS.md test policy); security,
alternation/caching invariants, issue-number regressions, and E2E kept.

Real test-quality fixes found and rooted out along the way:
- tests/tools/test_command_guards.py made real auxiliary-LLM HTTPS calls
  (DEFAULT_CONFIG smart-approval leaked in) — pinned approval
  mode=manual via autouse fixture: 17.4s → 0.4s.
- test_model_switch_custom_providers.py / test_user_providers_model_switch.py
  silently probed live provider catalogs (~2s/test) — stubbed
  cached_provider_model_ids/provider_model_ids/fetch_api_models.
- test_telegram_noise_filter.py: 15-platform copy-paste matrix over
  shared gateway.run logic → 3 representative platforms (55s → 3.9s).
- test_gateway_shutdown.py: stop()'s 5s interrupt-deadline loop spun on
  MagicMock agents — interrupt.side_effect now clears _running_agents
  (22s → 1.0s).
- test_gateway_inactivity_timeout.py poll-harness timings shrunk 3-5x
  (24s → 1.1s); test_mcp_stability.py backoff/SIGTERM-grace sleeps
  patched (15.4s → 2.5s); test_async_delegation.py negative-drain wait
  5s → 0.5s.
- test_telegram_init_deadline.py: loop-block margin restored to 1.0s
  with rationale comment — the watchdog-dump assertion needs the loop
  blocked well past deadline+grace under parallel load (flaked once in
  the 40-worker verification run at a 0.2s margin).

Verification: full hermetic suite via scripts/run_tests.sh —
2,438 files, 21,718 tests passed, 0 failed, 293.9s wall.
Suite totals vs original baseline: 46,820 → 19,757 test functions
(−57.8%), wall 583.5s → 293.9s (−50%), subprocess CPU 13,564s → 11,623s.
2026-07-29 13:39:40 -07:00
Teknium
6b81590c55 test: prune low-value tests suite-wide (wave 1) — 46,820 → 28,106 test functions
Systematic prune per AGENTS.md test policy, one pass over every major
test tree (gateway, hermes_cli, tools, agent, run_agent, plugins, cli,
cron, tui_gateway, honcho/openviking, root-level):

- DELETE: source-reading tests (read_text/getsource on prod files),
  change-detector tests (exact catalog counts, model-name snapshots,
  config version literals), mock-echo tests (assert a mock returns what
  it was told), assertion-free/trivial tests, near-duplicate
  parametrizations (boundaries + one representative kept), async/sync
  twin duplicates, cosmetic within-file variations.
- KEEP (mandatory): security/redaction/approval guards, message-role
  alternation invariants, prompt-caching/deterministic-call-id
  invariants, issue-number regression tests (deduped), E2E tests.
- 6 test files deleted outright (script-style/no-assert or fully
  redundant); conftest.py, fakes/, fixtures/ untouched.
- tests/acp/conftest.py added: autouse fixture stubs the live
  models.dev/GitHub/Copilot/Anthropic inventory fetches that ACP server
  tests performed on every session create — test_server.py 147s → 3.4s,
  and the tests are now genuinely hermetic.
- Sleep-based slowness shrunk where safe (codex_ttfb_watchdog,
  compression_concurrent_fork, etc.); no wall-clock assertion tightened.

Verification: full hermetic suite via scripts/run_tests.sh —
2439 files, 31,130 tests passed, 0 failed, 0 flaky retries, 315s wall
(baseline: 583s wall, 13,564s subprocess CPU).
2026-07-29 13:10:23 -07:00
Brooklyn Nicholson
f9b469d7de test(web_git): assert default branch invariant, not hardcoded main
CI git init defaults to master on some runners; compare branch to
defaultBranch instead of pinning a branch name.
2026-06-28 16:29:52 -05:00
Brooklyn Nicholson
4e9439cc3b fix(desktop): route composer context picking through remote-aware fs
Second pass on the remote-project flow: the project dialog and git cockpit were
remote-aware, but the composer's Add file/folder context picker still called the
native Electron picker directly. Route it through selectDesktopPaths so remote
sessions use the backend-aware picker instead of local disk paths; preserve local
multi-select behavior and keep remote folder selection single because the in-app
remote picker only supports one directory.

Also use readDesktopFileDataUrl for image previews so an already-known backend
image path can be read through /api/fs/read-data-url, and add focused coverage
for backend file-diff routing plus the plain-folder git init/worktree path.
2026-06-28 14:35:23 -05:00
Brooklyn Nicholson
fc86e35764 feat(desktop): make the git cockpit work over a remote gateway
After the folder picker fix, an added remote folder was still half-usable:
the desktop's git GUI (coding-rail status, worktree lanes, review pane,
branch switch, file diff) all ran Electron-local git on the USER's machine,
so against a remote-gateway repo they silently degraded to empty.

Mirror the whole surface over the dashboard REST API so it acts on the
BACKEND repo where sessions actually run:

- hermes_cli/web_git.py: git/gh logic (status, worktrees, branches, review
  list/diff/stage/unstage/revert/commit/commit-context/push/ship-info/
  create-pr, file-diff, worktree add/remove, branch switch) shelling to the
  system git, mirroring the Electron ops' shapes.
- web_server.py: /api/git/* routes (same auth gate + _fs_path hardening as
  /api/fs, executor-offloaded, mutations -> 400).
- apps/desktop desktop-git.ts: remote-aware facade exposing the same shape as
  window.hermesDesktop.git; coding-status / review / projects / model /
  desktop-fs route through desktopGit() so local stays Electron, remote hits
  /api/git/*.

Tests: tests/hermes_cli/test_web_server_git.py (real repo: status counts,
review classification, diff incl. untracked all-add, stage+commit roundtrip,
worktree/branch lifecycle, commit-context, gh-absent ship-info, auth) and
desktop-git.test.ts (local vs remote routing, envelope unwrap, POST bodies).
2026-06-28 14:26:09 -05:00