Finding 6: serialize createOfflineModelRuntime so overlapping calls cannot
interleave their PI_OFFLINE save/restore pairs and leave the process offline,
and name the process-wide visibility of that window in the docblock.
Finding 7: assert the offline construction through the public refresh seam via
reloadConfig() — the request path that regressed — instead of reading upstream's
private modelNetworkEnabled field.
Finding 8.4/8.5: document the background provider-catalog refresh in
docs/config.md and docs/config.html (cadence, timeout, single retry, offline
opt-out via PI_WEB_OFFLINE / PI_OFFLINE only), and update the changeset to
match the behavior after the earlier fixes.
The shared ModelRuntime was constructed with network refreshes enabled, so
reloadConfig()/login()/logout() — called on the model picker, session model
changes, and auth dialogs — performed unbounded provider-catalog fetches.
A single stalled fetch blocked those requests for minutes and, through pi's
coalesced per-provider refresh, dragged session creation along with it.
Construct the runtime with PI_OFFLINE forced so every runtime-driven refresh
stays local, and add ModelCatalogRefresher as the single deliberate network
path: bounded by an abort timeout, serialized through one in-flight run,
scheduled in the background, and triggered after provider auth changes.
Update the single quiet-session-warnings changeset entry to cover the
final shipped behavior: status-bar expand/collapse toggle, the in-pane
minimise chevron restored in 2bdfd48, per-session remembered state, and
SVG warning icons. Frontmatter (patch) unchanged. No new changeset.
Relay restore-warning-chevron leg 2 (final).
Relaxes the provider policy from 'global config only' to 'global sources':
providers registered by agent-dir (global) extensions are learned once at
daemon startup and allowed on the shared runtime; project-extension
registrations are still rejected with a session warning. Global extensions
load identically for every session, so their providers are daemon-consistent
and cannot leak project state (#76).
- Shim now allows allowlisted ids through and also covers Pi 0.81's native
provider path (registerNativeProvider), closing a bypass.
- Startup learning step loads only global extensions against a scratch cwd
and diffs the runtime's registered provider ids.
- Bumps @earendil-works/* dev/peer ranges to >=0.81.1 <0.82; adapts to the
Agent.streamFn -> streamFunction rename.
- Docs, changeset, unit and acceptance tests updated (global-extension allow
path, late re-registration a la pi-tensorx, native provider rule).
Recurse into dirty submodules when building the Git status so their
modified and untracked files appear as full-path entries, and add a
commit-pointer entry (with short SHAs) only when the recorded commit
actually moved. Route diffs whose path falls inside a submodule to run
in that submodule's working tree so real per-file diffs are shown.
The changed-file list groups these under the submodule: tree view keeps
the nested structure and marks the submodule root with a badge, list
view flattens them into one expandable group pinned above the ordinary
files. Depth 1 only; ignored files are excluded; the panel stays
read-only.
Covered by client tree/list-grouping tests, parser tests, and a
server test that drives a real temporary repository and submodule.
Extract the Git panel into a dedicated `workspace-git-panel` Lit component
(mirroring the Files panel) and add a segmented List/Tree toggle next to
Refresh.
Tree view builds an in-memory, collapsible directory tree from the changed
files, starts fully collapsed, and offers a single expand-all/collapse-all
button (visible only in tree view). List view keeps the existing flat,
full-path rows. The selected view mode persists in localStorage under
`pi-web.gitFileView`; per-directory expand state is intentionally ephemeral.
- gitFileViewPreference.ts: localStorage-backed view preference (+ test)
- gitFileTree.ts: pure flat-paths -> nested-tree builder (+ test)
- WorkspaceGitPanel.ts: the panel component with toggle + tree state
- Only increment visual branch depth after forks so long linear session
histories stay in one lane instead of scrolling off-screen; lower the
max visual depth cap to match.
- Reset to the no-summary default when leaving an invalid custom summary
choice so Navigate is never permanently disabled by a stale invalid entry.
Retain client-owned machine affinity for each interactive auth flow and use it for prompt responses, polling, cancellation, and completion refreshes. This prevents a later machine selection from forwarding secrets to a different remote.\n\nRefs #74
Best-effort cancel a running auth flow when its start response arrives after the browser operation was closed or superseded, so sessiond does not retain orphaned provider polling or callback listeners.\n\nRefs #72
Relay issue-62-authstorage leg 7 (final): add patch changeset for the
session-daemon crash fix on Pi >=0.80.8, re-verify green, confirm goal
criteria and cleanup. Relay complete.
Show a pinned banner at the top of the session view with resource and
runtime diagnostics (skills, prompts, themes, extension load errors) plus
the Anthropic subscription-auth billing notice, recomputed live from the
current runtime so they stay accurate across browser reloads.
Warnings carry an optional dismiss capability; the Anthropic notice is
dismissable and durably suppressed through pi's own anthropicExtraUsage
warning setting. Also fixes the testing-guide skill frontmatter so it
loads.
Seed the in-flight partial assistant message (text, thinking, and
in-progress tool calls) when opening or reconnecting to a session that is
mid-stream, then continue streaming live deltas on top of it. Replaces the
blocking "Catching up..." placeholder and the end-of-turn transcript reload.
Server stamps every per-session UI event with a monotonic seq at the
SessionEventHub publish choke point and exposes
GET /sessions/:sessionId/stream-snapshot returning { seq, partial }. The
client fetches the snapshot on join, seeds the normalized partial into the
in-memory transcript (never the history cache), and applies buffered/live
events using the seq watermark for exactly-once delivery.
The snapshot is a progressive enhancement: a 404 from an older remote
pi-web or a not-yet-restarted session daemon falls back to an empty seed
(seq 0, drops nothing), so sessions still open and stream normally. The
stream-snapshot route is registered in the federation allowlist for
remote-machine proxying.