Skip to content

docs(desktop-windows): add AGENTS.md, fix release-pipeline note, document Wayland quirks - #2

Open
formed2forge wants to merge 35 commits into
mainfrom
docs/windows-agents-md
Open

docs(desktop-windows): add AGENTS.md, fix release-pipeline note, document Wayland quirks#2
formed2forge wants to merge 35 commits into
mainfrom
docs/windows-agents-md

Conversation

@formed2forge

Copy link
Copy Markdown
Owner

Summary

  • Adds desktop/windows/AGENTS.md (the only major component missing one) and indexes it from root AGENTS.md.
  • Corrects release-pipeline.md's stale claim that desktop_windows_release.yml triggers on push to main — it's workflow_dispatch only.
  • Documents two Wayland dev-environment quirks found getting the app running on niri/Asahi Fedora: pnpm dev's software-render default leaving the main window blank (fixed by OMI_DEV_HW_GPU=1), and the bar/focus-halo windows' setBounds positioning not working under native Wayland.

Split out of a larger branch into atomic, independently-reviewable pieces; see the companion PRs for the Windows/Linux desktop bug fixes found during the same session.

Test plan

  • Docs-only change; no behavior to exercise.
  • check_agents_md_lean.py passes (root AGENTS.md stays within budget).

cursoragent and others added 19 commits August 25, 2026 23:44
Remove unused imports, drop a duplicate MCP scope key and dead deploy helper,
share the duplicated Levenshtein helper, and narrow bare excepts around datetime
parsing. Update webhook/app-integration tests that stubbed the removed imports.

Verification: BACKEND_UNIT_TEST_FILE_LIST covering
test_memory_ingestion_text, test_verify_output_grounding, test_mcp_data_endpoints,
test_async_app_integrations, test_async_webhooks — all passed.

Co-authored-by: Max Carter 祁明思 <max@tsc.hk>
Delete unused memory/conversation UI remnants (including unused_element ignores
and commented-out blocks) and share identical quick-edit, duration, and status
pill helpers across sibling pages. Behavior preserved; Flutter SDK unavailable
in this cloud VM so app tests were not executed here.

Co-authored-by: Max Carter 祁明思 <max@tsc.hk>
Replace eval() with json.loads for Firebase service-account JSON, unify
cm-builds under x-auth-token with HTTP status checks, and point onboarding
sync tooling at desktop/macos/Desktop instead of the removed desktop/Desktop
layout.

Co-authored-by: Max Carter 祁明思 <max@tsc.hk>
Co-authored-by: Max Carter 祁明思 <max@tsc.hk>
Avoid growing the memory_ingestion package past its grandfathered source-file
count by placing the shared Levenshtein helper in the existing ids module
instead of adding a new text.py file.

Co-authored-by: Max Carter 祁明思 <max@tsc.hk>
Delete the new text.py module so memory_ingestion stays within its
grandfathered source-file count, and point pipeline/verify_output at ids.

Co-authored-by: Max Carter 祁明思 <max@tsc.hk>
- scripts/install_onboarding_figma_sync.sh: point launchd WatchPaths at the
  real Resources bundle (desktop/macos/Desktop/Sources/Resources).
- scripts/run_onboarding_figma_sync.sh: remove redundant -path clause for
  OnboardingLoadingAnimation.swift (already matched by -name 'Onboarding*.swift').
- app/lib/pages/memories/widgets/memory_edit_sheet.dart: showMemoryQuickEditSheet
  now accepts and forwards an optional onDelete callback instead of hardcoding
  a no-op.
- app/lib/pages/phone_calls/active_call_banner.dart: ActiveCallTopBar uses the
  shared formatPhoneCallDuration helper, completing the duration-format dedup.
- backend/tests/unit/test_async_app_integrations.py: test_no_threading_used
  inspects _async_trigger_realtime_audio_bytes bytecode (not the wrapper) and
  removes the brittle hasattr(app_integrations, 'threading') check.
Re-run dart format after flutter pub get so the pinned language version
applies; 6 changed files now match the repo formatter. pubspec.lock picks
up the same transitive meta/test_api bumps CI's pub get resolves.

Failure-Class: none
Rewrite the store-link helper as sequential ifs so Frontend Lint prettier/prettier passes after the hygiene indent change.
Hygiene cleanup dropped webhook_url_from_setting from utils.webhooks,
so first-time setup treated raw Redis values as URLs and audio-bytes
sends raised NameError. Parse stored settings through the helper again
so ',5' and whitespace-only values stay disabled, and audio delivery
can extract the endpoint.

Failure-Class: none
Reproduce the revoked process-wide owner state, then establish and restore the test owner through RuntimeOwnerAuthorityTestFixture so suite order cannot turn authenticated capture into anonymous capture.

Verification: RewindCaptureExclusionGenerationTests 9/9 passed; deterministic contamination recovery passed 50/50 runs; the repaired test passed inside two 5,769-test process runs (each full run retained one unrelated baseline failure).

Failure-Class: FC-hand-listed-test-isolation-membership
undivisible and others added 9 commits August 26, 2026 18:17
BasedHardware#11303)

<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
## What changed and why

High-confidence, behavior-preserving hygiene cleanup: remove proven dead
code/unused imports, share identical helpers, narrow bare excepts around
datetime parsing, and fix broken script paths. Net ~500 lines removed;
no intentional product behavior change.

## Product invariants affected

- INV-DATA-1 (merge from main brought app/lib/main.dart into diff; no
intentional behavior change)
- INV-MEM-4 (merge from main brought memory_ingestion files into diff;
no intentional behavior change)
- INV-MEM-1 (path match on memory ingestion / memories UI files; no
intentional behavior change)

## How it was verified

Focused backend unit tests via `bash test.sh` (file list below), script
syntax checks, product line-count baseline ratchet, and
`scripts/pr-preflight --pr-body-file` (27 checks passed). App Flutter
SDK is unavailable on this Linux cloud VM; Dart brace balance was
checked manually and pre-push used the documented Flutter/Dart skip
hatches.

```
BACKEND_UNIT_TEST_FILE_LIST=... bash test.sh
# test_memory_ingestion_edit_distance: 2 passed
# test_verify_output_grounding: 26 passed
# test_async_app_integrations: 18 passed
# test_mcp_data_endpoints: 67 passed
# test_async_webhooks: 22 passed
scripts/pr-preflight --pr-body-file /tmp/pr-body.md
# PR preflight passed: 27 checks
```

## Tests

- Added `backend/tests/unit/test_memory_ingestion_edit_distance.py`
proving pipeline and verify_output share `ids.edit_distance`
- Updated `test_async_webhooks` / `test_async_app_integrations` fixtures
for removed unused imports
- No Flutter tests run here (SDK absent); CI remains the app authority

## Failure class (fixes)

Failure-Class: none

## Scoped cleanups

- Backend: unused imports, duplicate MCP scope key, shared Levenshtein
helper, bare-except narrowing, dead `_inject_config_map`
- App: dead memory/conversation UI remnants; shared quick-edit /
duration / status-pill helpers
- Scripts: `eval` → `json.loads`, unified `cm-builds`, onboarding paths
→ `desktop/macos/Desktop`
- CI: downward product file line-count baseline ratchet for shrunk
backend files

<!-- CURSOR_AGENT_PR_BODY_END -->

<div><a
href="https://cursor.com/agents/bc-6f28e0a4-53fb-41b4-8046-c6e2dbebd2bd?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-6f28e0a4-53fb-41b4-8046-c6e2dbebd2bd&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div>
Unused import introduced by BYOK refactor (BasedHardware#11454). Causes pyright error
in CI.\n\nFailure-Class: none
…asedHardware#12274)

The manual development backend deploy ran its post-promotion smoke against
https://api.omi.dev, which has never resolved: the omi.dev zone exists but the
api record is NXDOMAIN, so smoke_what_matters_now.py could not reach anything
and failed with "could not reach the deployed backend". That failed the deploy
after traffic had already shifted and triggered the traffic restore, rolling the
promotion back.

Development's real public API host is api.omiapi.com, which matches the rest of
the development domain family (parakeet.omiapi.com, nllb.omiapi.com,
pusher.omiapi.com in backend/deploy/runtime_env/dev.overlay.yaml) exactly as
production uses the omi.me family. It serves /ready 200 today.

Making api.omi.dev real was rejected: the codebase already uses it as the
canonical fake hostname in mobile production-routing tests, so giving it a live
record would undermine those fixtures.

This defect was introduced by 933fdf7 on the same day as the probe-signer
defect fixed in BasedHardware#12264, and stayed invisible because the probe failed first.
Run 33008079463 is the first development deploy to reach this step.

The step is guarded to the manual development lane; the production smoke keeps
its own api.omi.me path untouched.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…asedHardware#11454's contract (BasedHardware#12277)

* chore(desktop): unbreak the local Swift build and formatter gate on Xcode 26

Two pre-existing blockers on `main` that fail the pre-push gate for any
desktop PR when the local toolchain is newer than the pinned Xcode 16.4:

- `AppState+Permissions.swift` has swift-format drift, and
  `desktop-swift-format-lint` runs `lint-scope` over every first-party
  Swift file. Formatter output only.
- `AppState+Transcription.swift:848` captures `alertPresenter` implicitly
  in an escaping closure. Swift 6.2 (Xcode 26.x) rejects this; Xcode 16.4
  accepts it. Writing `self.` is what the diagnostic asks for and is the
  same strong capture the implicit form already produced, so behavior is
  unchanged on both toolchains.

Failure-Class: none

* chore(desktop): dodge the Xcode 16.4 SILGen segfault on alertPresenter

Every desktop CI lane (Static & Test Contracts, Release Compile, Build &
Tests aggregate) has been red since main's d49f978 landed
`var alertPresenter: any DesktopAlertPresenting = AppKitSheetAlertPresenter()`:
the pinned Xcode 16.4 toolchain segfaults (signal 11) in silgen
emitStoredPropertyInitialization while lowering that existential-erasure
default initializer. Reproduced on main itself (d49f978, fb67ca9,
50cf064 all failed; d06e220 passed only because its desktop jobs were
path-filter skipped) and on unrelated PRs (BasedHardware#12269, BasedHardware#12272), so this is not
specific to this branch.

Move the initializer from the stored-property default position into
init(). Identical semantics on both toolchains - AppState is @mainactor
with a single designated init, and the alert tests overwrite the presenter
immediately after construction. Xcode 26.6 parses, swift-format lint
passes, changelog gate passes.

Failure-Class: none

* test(desktop): enroll BYOK fingerprints so paywall/agent tests match BasedHardware#11454's contract

BasedHardware#11454 replaced the old "all keys present in UserDefaults" check for
isByokActive with a stricter one: the selected provider's *current* key
must match a fingerprint already persisted via
APIKeyService.persistEnrolledFingerprints (set by activateBYOK
reconciliation after BYOKValidator confirms the key). Seven tests across
BYOKPaywallTests and AgentRuntimeProcessTests still set up state the old
way — raw UserDefaults keys, no enrollment — and started failing the
moment CI could actually reach them (BasedHardware#12276): main's own contract job
caught this on BasedHardware#11454 before merge, but a compiler crash landed 8
minutes earlier (tracked separately in BasedHardware#12275) blocked every real
desktop Swift test run afterward, so it went unnoticed.

This is a test-only fix that transcribes BasedHardware#11454's already-stated and
already-tested enrollment contract into the tests that never learned
about it; no Sources change.

- BYOKPaywallTests: add `enroll(_:)`, calling
  `persistEnrolledFingerprints` with the SHA-256 fingerprint of the
  provider's current key, exactly as `activateBYOK` reconciliation would
  after successful validation. Five tests were asserting on raw key
  presence: testByokActiveRequiresSelectedLLMKey (needs a *second*
  enrollment after setAllBYOKKeys() rewrites openrouter's key and
  invalidates the first fingerprint), testBuildHeadersAttachSelectedLLMByokKey,
  testBuildHeadersSuppressesOnlyInvalidByokHeader,
  testPaywallFlagSuppressedWhenByokActive, and
  testRemovingDeepgramKeyLeavesSelectedLLMByokActive (both of the last
  two now select the provider explicitly rather than relying on legacy
  first-match inference, since every provider's key is set and the test
  must enroll the same provider it selects).
- AgentRuntimeProcessTests: enroll the selected provider in
  testUsableByokEnvironmentIncludesAllKeysWhenAllProvidersAreUsable and
  testUsableByokEnvironmentSuppressesAllKeysWhenOneProviderIsKnownBad —
  usableBYOKEnvironment() gates on isByokActive before the
  CredentialHealthManager suppression these tests exercise. Both
  existing `defer` blocks now also save/restore the enrollment map.

Not touched: testBuildHeadersCanExplicitlyExcludeByokKeys and
testLowLevelTransportDefaultsToExcludingByokKeys currently pass
vacuously — neither enrolls a provider, so isByokActive is false and
headers come back nil regardless of includeBYOK. Flagging for whoever
owns BYOK rather than fixing here, since giving them real coverage
means deciding what "excluded despite being active" should assert, and
that's a product call, not a mechanical transcription of BasedHardware#11454.

No assertions were weakened or removed — every fix completes test setup
to match the stated contract. testPaywallFlagSuppressedWhenByokActive is
the only coverage that an enrolled BYOK user is never paywalled; it was
made to pass by enrolling correctly, not by loosening what it checks.

Fixes: BasedHardware#12276
Failure-Class: none

---------

Co-authored-by: David Zhang <9387252+Git-on-my-level@users.noreply.github.com>
Auto-generated: consolidates unreleased changelog fragments into
v0.12.223 and regenerates CHANGELOG.json.
…re#12267)

## Why

The 2026-08 macOS churn cohort analysis
(`omi-knowledge-base/projects/macos-churn-analysis/evidence/2026-08-26-macos-churn-cohort-analysis.md`)
listed `chat_agent_error` as "well-powered but cannot explain itself".

Measured against PostHog (project 302298, macOS, JSON extraction rather
than the map subscript — see below), August 2026 `chat_agent_error`:

| property | populated |
| --- | --- |
| `error_class` / `surface` / `harness` | 1177 / 1197 |
| `error_code` | 909 / 1197 |
| `root_cause` | 178 / 1197 |

`error_class` is fine — schema v2 fixed that. The remaining hole is that
only one of the ~15 `telemetryAttempt.fail(...)` call sites
(`ChatProvider.swift:5446`) passes a `ChatQueryErrorDetail`. Every other
terminal — timeout, tool stall, session setup, bridge unavailable,
attachment upload, concurrent request — reached PostHog with no
`error_code` at all, and `root_cause` was hardcoded for exactly one
error class (`.authentication`). A typed failure existed at the catch
boundary and was collapsed to a bare class name by the time it was
recorded.

## What changed

`ChatQueryErrorClass` now classifies itself, so the fix lands at the one
place that builds the payload instead of at 15 call sites:

- `rootCause` maps every class to a bounded `ChatQueryRootCause`
  (subsystem attribution: provider, agent runtime, bridge process, local
  session, network, device resources, ...). `.authentication` keeps the
  already-published `provider_claude` value so existing PostHog
  breakdowns stay valid.
- `fallbackErrorCode(watchdogFired:)` gives every class a bounded code
  when no `ChatQueryErrorDetail` is available. It separates
  `watchdog_timeout` from `bridge_timeout`, which have different owners
  and were previously indistinguishable.
- A supplied `ChatQueryErrorDetail` still wins; the fallback only fills
  the gap.

No raw exception text, prompt, path, or message enters the payload — the
values are enum raw values, per the analytics integrity contract in
`desktop/macos/AGENTS.md`.

## Proof

`ChatQueryTelemetryTests`:

- `testEveryFailureClassCarriesABoundedCodeAndRootCause` iterates all 16
  classes and fails if any emits an empty/absent code or an out-of-
  vocabulary root cause.
- `testRootCauseAndTimeoutCodesStayActionable` pins the compatibility
  value for auth and the watchdog/bridge timeout split.
- `testErrorDetailCodeOverridesTheClassFallback` proves the fallback
  cannot shadow real detail.
- `testAnalyticsPayloadUsesTypedAllowlist` (existing) still pins the
  exact emitted key set.

37 tests pass locally.

Failure-Class: FC-typed-failure-collapsed-to-generic
omi-ci-bot Bot and others added 7 commits August 27, 2026 06:18
Auto-generated: consolidates unreleased changelog fragments into
v0.12.224 and regenerates CHANGELOG.json.
Auto-generated: consolidates unreleased changelog fragments into
v0.12.225 and regenerates CHANGELOG.json.
package.json's engines field and .nvmrc already constrain Node to
>=22.19.0 <23, and scripts/check-node-version.mjs fires at pretest
to produce a legible error message, but nothing in the AGENTS.md
told a contributor before they hit the check or, worse, saw silent
jsdom localStorage breakage on Node 24+. Add a one-line note
mirroring the existing pnpm major-version pin entry.

.nvmrc (22.19.0) was already merged via BasedHardware#12034.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@formed2forge
formed2forge force-pushed the docs/windows-agents-md branch from 91d84b7 to 2faa66f Compare August 27, 2026 13:32
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.

5 participants