Skip to content

Webview stream liveness & rail self-heal (#1583) - #1587

Merged
jeonghun-jj-lee merged 7 commits into
feature/free-tier-fleetfrom
amico/issue-1583-webview-stream-liveness
Sep 27, 2026
Merged

jeonghun-jj-lee merged 7 commits into
feature/free-tier-fleetfrom
amico/issue-1583-webview-stream-liveness

Conversation

@jeonghun-jj-lee

@jeonghun-jj-lee jeonghun-jj-lee commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Integration PR for #1583 — client-side recovery so local chat sessions stop needing a window reload.

Webview fix (the campaign)

Landing against the drifted base (integration repairs)

Gates (director-run, all green)

slice unit 4/4 + 38/38 · drift-gate PASS · overlay typecheck clean (7 pkgs) · build:binary compiles + smoke v1.18.29 · full fast suite 4991 passed / 0 failed (verified in a dirty dev env).

Base: feature/free-tier-fleet.

amicode-ci and others added 2 commits September 27, 2026 17:20
The overlay app's live SSE stream had no client-side liveness detection: when
the socket goes silently half-open (sleep/wake, Wi-Fi blip, engine replaced
without FIN/RST), the v1 event iterator neither throws nor completes, so
onSseError never fires, the for-await parks forever, streamStatus stays
"connected", and the transcript freezes until a manual reload.

- New zero-dependency pure module stream-liveness.ts exporting
  shouldReconnectIdleStream (unit-tested in-place via bun:test) — reconnect iff
  connected AND now - lastFrameAt > staleMs (strict).
- Watchdog in createServerSdkContextBase: track lastFrameAt (set on connect and
  each frame), a 5s setInterval force-reconnects a stale-but-connected stream at
  30s by aborting the per-attempt controller (same generation reconnects with
  the lastEventID cursor — lossless); cleared in onCleanup. Intentional abort is
  treated as closed by the existing catch, so the banner does not flip.
- Wake re-arm in onMount: visibilitychange (visible + stale >10s) and online
  (when connected) force a reconnect via a shared forceReconnect() closure,
  guarded on started && !abort.signal.aborted. A healthy stream (fresh
  lastFrameAt) causes no reconnect on a quick tab toggle.
- Refresh manifest hashes for the edited/added overlay files.
…-timeline.tsx

The slice-1 manifest patch corrupted two unrelated overlay entries to
stale pre-#1579 hashes, reddening drift_gate.mjs. Restore both to their
committed-disk hashes (disk is the source of truth). drift-gate PASS.
@coderabbitai

coderabbitai Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 093efc79-f1b3-4e47-83a6-3c877a416e41

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

amicode-ci and others added 2 commits September 27, 2026 17:28
…nect (#1585)

Add pure shouldRefetchOnReconnect(prev, next) to the UI package's problem.ts
(true iff false→true — a rising edge after a real disconnect; initial connect
undefined→true does not refetch). Wire AmicodeEntityRail with an optional
streamConnected?: () => boolean prop and a createEffect that tracks the prior
value in a plain closure let and refetches on the reconnect edge, never reading
the resource's own state (no feedback loop). The app mount supplies the app's
live SSE status via serverSDK().event.status().
…verlay typecheck

Base defect from #1570 (byte-identical to base HEAD): mock(() => {}) types
mock.calls[0] as [] so the .toEqual(["s1"]) assertion failed the fail-closed
overlay typecheck gate on feature/free-tier-fleet independent of #1583. Type the
mock param (id: string) so the assertion typechecks. Integration repair recorded
in the session ledger as a finding.
amico-director added 3 commits September 27, 2026 17:59
…ico/issue-1583-webview-stream-liveness

# Conflicts:
#	packages/app-bundle/manifest.json
…gate typecheck

Pre-existing base defect (from #1579 lineage): the import at extension.ts:114
went unused when its last consumer was removed, so 'pnpm -r run typecheck'
(the CI 'fast' gate) failed with TS6133 on feature/free-tier-fleet, independent
of #1583. UNARMED_PASSWORD on the same line stays (used at ~L1307).
The suite inherits the Amicode terminal's operational env (AMICODE_SERVICE_AUTH=open,
AMICO_FLEET_MULTIPLEX=1, AMICODE_ENGINE_UNARMED, AMICODE_SERVICE_PORT, AMICODE_APP_DIST,
OPENCODE_DB, OPENCODE_CONFIG_CONTENT, ...) that CI never sets — flipping service auth
mode, fleet data-plane routing, app-shelf boot shape, and terminal env injection under
the tests, so ~17 tests red locally while green in CI.

- add test/setup_hermetic_env.ts (vitest setupFiles): snapshot + clear AMICO*/AMICODE*/
  OPENCODE* per file, restore on teardown; explicit per-test values still win.
- cli_gate: skip the really-staged-bins check on a staged LAUNCHER, not just bin/
  (bin/launcher/* are gitignored build artifacts; a fresh worktree false-failed it).

Verified: full fast suite green in a dirty dev env (4991 passed, 0 failed); CI clean-env
behavior unchanged.
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