Commit Graph
781 Commits
Author SHA1 Message Date
Federico Jaramillo Martinez 90dd7ce401 docs(sessions): document background catalog refresh and contain offline env window
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.
2026-07-25 13:07:02 +02:00
Federico Jaramillo Martinez c5af390ab9 fix(sessions): abort in-flight catalog refresh on dispose
`dispose()` only cleared timers, so a refresh already in flight kept its
provider fetch alive for the rest of the timeout budget and could delay
daemon shutdown, which is exactly when sessiond disposes the refresher.
A refresher-lifetime AbortController is now combined with the per-run
timeout via `AbortSignal.any`, and `dispose()` aborts it. A
dispose-triggered abort logs as expected shutdown info rather than a
timeout warning or an error, whether the runtime resolves as aborted or
rejects.

`start()` is now idempotent: a second call previously overwrote both
timer handles and leaked the first pair, which kept firing.

Also replaces the `then().catch()` bookkeeping chain in `queueRefresh()`
with an awaited private `runCycle()`, keeping the coalescing, retry, and
dispose semantics unchanged.
2026-07-25 12:56:31 +02:00
Federico Jaramillo Martinez 3d3538c76b fix(sessions): size catalog refresh cadence, force, and retries
Tick the background catalog refresher hourly instead of every four hours:
pi stamps `checkedAt` after a fetch completes, so a tick at exactly its 4h
freshness window always landed a few seconds short and only fetched on
every other tick (~8h effective). Scheduled runs stay unforced, so the
extra ticks are nearly free and pi's gate keeps deciding when to fetch.

Auth-triggered refreshes now pass `force: true` so a re-login of a
provider refreshed within the last four hours actually reaches the
network. A request queued behind an in-flight run keeps the strongest
mode asked for, so a forced request is never downgraded.

Raise the whole-cycle timeout to 60s, since one run covers every
refreshable provider and a background job has no startup budget, and give
a timed-out or errored run exactly one bounded retry. Retries never earn
retries, are superseded by any fresh request, and are cleared by
`dispose()`.
2026-07-25 12:48:15 +02:00
Federico Jaramillo Martinez acda1cc0be fix(sessions): honor offline settings in background catalog refresher
The background model catalog refresher always requested a network refresh,
so sessiond fetched provider catalogs on a schedule even when the operator
set PI_OFFLINE or PI_WEB_OFFLINE. Before the refresher existed, those
settings made every runtime refresh local-only.

Add `offlineModeEnabled()` to the config module and inject the resulting
flag from sessiond's frozen daemon environment, so the refresher schedules
nothing and ignores auth-triggered requests in offline mode. The narrower
PI_SKIP_VERSION_CHECK / PI_WEB_SKIP_VERSION_CHECK keys are deliberately not
included: they only suppress release lookups.
2026-07-25 12:40:33 +02:00
Federico Jaramillo Martinez ed9c2f65bb fix(sessions): move provider catalog network refreshes off request paths
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.
2026-07-24 23:44:35 +02:00
Federico Jaramillo Martinez 83e9014a8a Merge pull request #92 from lizhuoran1019/feat/git-tree-submodule-navigation
feat(git): add tree view and submodule file navigation
2026-07-24 22:09:02 +02:00
Federico Jaramillo Martinez 095adfe550 test(ui): add WorkspaceGitPanel component-boundary tests 2026-07-24 12:30:56 +02:00
Federico Jaramillo Martinez 6db065e984 refactor(ui): dedupe git file helpers and memoize git view model
- N1: extract the copy-pasted pointerName/segmentName helpers from
  gitFileList.ts and gitFileTree.ts into gitFileShared.ts.
- N3: drop the dead conditional "tree" class (no CSS rule exists).
- N4 (P3): memoize computeViewState on (status, view) identity so renders
  from expand/collapse or diff selection skip the full model rebuild;
  expand state is read live at render time, never cached.
2026-07-24 12:09:55 +02:00
Federico Jaramillo Martinez 10ee3daa0c fix(ui): keep git view toggle stationary when expand-all appears
The right-anchored .toolbar-actions group rendered the view toggle left of
the conditional expand/collapse-all button, so the toggle jumped left
whenever the button appeared. Render expand/collapse-all first (leftmost)
so only the space to its left changes; the toggle and Refresh stay put.
2026-07-24 12:06:33 +02:00
Federico Jaramillo Martinez 65a20b59fe fix(git): render newly staged submodule pointer as new → <sha>
A staged submodule add records an all-zero head OID, which rendered as
0000000 → <sha>. Display the zero OID as "new" instead; the client
pointer label needs no change (N4).
2026-07-24 11:56:54 +02:00
Federico Jaramillo Martinez 842160f964 perf(git): parallelize submodule expansion and skip impossible submodule lookups
- expandSubmodules now fans out with Promise.all over the dirty
  submodules and concatenates results in input order, so the polled
  status endpoint no longer pays serial git status/rev-parse spawns
  (P1).
- submoduleForPath bails out before spawning git config when the path
  contains no '/' or the repo has no .gitmodules, removing a spawn
  from every diff call in plain repos (P2).
- Rename submodulePaths() to configuredSubmodulePaths() and the
  expandSubmodules local to dirtySubmodulePaths to disambiguate the
  two concepts (N2).
2026-07-24 11:55:56 +02:00
Federico Jaramillo Martinez 95102b8d78 fix(git): show staged submodule pointer moves and support spaced submodule paths
- parseStatus: detect staged submodule pointer moves by comparing the
  recorded HEAD/index OIDs (porcelain reports S... for a staged move, so
  the c flag never fires); staged moves previously vanished from the
  status response (PR #92 review finding B1).
- parseStatus: keep deleted gitlinks (index or working tree) as plain
  deletion rows instead of deferring them as submodules. Unstaged
  deletions vanished entirely, and staged deletions would render as a
  bogus pointer move to the zero OID. The finding assumed N... porcelain;
  git 2.54 actually emits .D/D. S... (finding S3's stated outcome).
- submodulePaths: parse 'git config -z' records so submodule paths with
  spaces survive .gitmodules key parsing instead of splitting lines at
  the first space (finding S1).
- tests: strip inherited GIT_* env vars in the fixture helper so the
  suite also passes when run from a git hook (pre-commit sets GIT_DIR).

Adds real-git fixture tests for staged moves, staged+dirty combos,
deleted submodules, inner renames, and spaced submodule/file paths.
2026-07-24 11:43:58 +02:00
Federico Jaramillo Martinez 63b85fc246 Merge branch 'pr-92-review' into test/pr-92 2026-07-24 10:21:29 +02:00
Federico Jaramillo Martinez 165928a543 docs(changeset): describe in-pane chevron in quiet-session-warnings
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).
2026-07-23 12:03:28 +02:00
Federico Jaramillo Martinez 8f6688e76e fix(ui): restore in-pane minimise chevron for session warnings
Re-add the minimise chevron to the expanded session-warnings pane in
ChatView, wired to the existing unified onToggleWarnings (toggle ≡
collapse in the expanded state). The status-bar warning toggle from
a13778c is retained unchanged; both controls share the single
sessionWarningVisibility mutation, so they cannot desync.

- ChatView: onToggleWarnings prop + handleToggleWarnings; chevron
  rendered inline via html (no svg re-import), guarded by
  onToggleWarnings === undefined.
- PiWebApp: renderChatView <chat-view> passes .onToggleWarnings.
- shared.ts: restore .session-warnings-controls / -collapse / icon CSS.
- ChatView.test.ts: restore the chevron-wiring test against
  onToggleWarnings via the session-warnings-collapse marker.

Relay restore-warning-chevron leg 1.
2026-07-23 12:03:28 +02:00
Federico Jaramillo Martinez 10f49f349c Merge pull request #91 from jmfederico/agent/global-provider-policy
fix: freeze extension providers to the global startup baseline
2026-07-23 12:01:01 +02:00
Federico Jaramillo Martinez e8d418a71a docs: distinguish Pi extensions from PI WEB plugins 2026-07-22 23:53:30 +02:00
Federico Jaramillo Martinez ced3261651 test(sessions): make unread checks portable 2026-07-22 23:36:28 +02:00
Federico Jaramillo Martinez e70b3d6bb9 fix(sessions): keep ignored provider mutations inert 2026-07-22 20:58:56 +02:00
Federico Jaramillo Martinez ee8d9e5359 docs: document immutable provider bootstrap 2026-07-22 20:46:41 +02:00
Federico Jaramillo Martinez 66f0ea44ce test(sessions): cover immutable provider baseline 2026-07-22 20:39:43 +02:00
Federico Jaramillo Martinez 04d8134ba4 fix(sessions): freeze providers after global bootstrap 2026-07-22 20:31:08 +02:00
Federico Jaramillo Martinez c2bf595999 feat(sessions): allow global-extension providers, require Pi 0.81
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).
2026-07-22 17:13:57 +02:00
lzr dd435cb1b0 feat(git): view submodule working-tree changes in the Git panel
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.
2026-07-22 21:35:06 +08:00
lzr 8a5aaf93a1 feat(git): add list/tree toggle for changed files in the Git panel
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
2026-07-22 21:34:54 +08:00
Federico Jaramillo Martinez 242911331a docs: document global provider policy and extension registration rejection 2026-07-22 09:36:32 +02:00
Federico Jaramillo Martinez fb4ceb5d04 test(sessions): cover the global provider policy
Unit tests for the policy shim (swallowed registrations, no-op
unregister, untouched global providers, rejection wording) and
acceptance tests wired as sessiond wires production: load-time
rejections surface as session warnings while extension tools and
commands keep working, late registrations are broadcast to active
sessions' notification inboxes, colliding provider ids across
workspaces cannot affect each other, and a project-level models.json
does not alter the shared runtime.
2026-07-22 09:30:40 +02:00
Federico Jaramillo Martinez 20d424c48f feat(sessions): reject extension-scoped provider registrations
PI WEB only supports globally configured providers (Pi built-ins,
agent-dir models.json, environment credentials). A daemon-wide shim on
the shared ModelRuntime swallows extension registerProvider calls and
makes unregisterProvider a no-op, so one workspace's extensions can no
longer corrupt the provider set of concurrent sessions (issue #76).

Rejections during a services load surface as session warnings through
the existing diagnostics pipeline; late registrations from session
event handlers broadcast a notification to active sessions. Everything
else extensions register keeps working.

Requires manual restart of pi-web-sessiond.service (daemon wiring changed).
2026-07-22 08:57:05 +02:00
Federico Jaramillo Martinez 24a3d3611e fix(ui): compact session tree indentation and allow default navigation after invalid custom input
- 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.
2026-07-21 11:11:10 +02:00
Federico Jaramillo Martinez a13778c97b fix(ui): keep warning toggle visible 2026-07-21 10:43:13 +02:00
Federico Jaramillo Martinez 115d74e79a feat(sessions): persist shared unread state 2026-07-20 19:36:16 +02:00
Federico Jaramillo Martinez a20a8c8c09 fix: preserve minimised warnings across session navigation 2026-07-20 19:35:45 +02:00
Federico Jaramillo Martinez 15c12aa1b8 Merge pull request #81 from jmfederico/agent/issue-80-assessment
fix(sessions): provide plain-text extension theme
2026-07-20 15:04:27 +02:00
Federico Jaramillo Martinez a884773357 fix(sessions): provide plain-text extension theme 2026-07-20 14:01:47 +02:00
Federico Jaramillo Martinez b48b147b5b fix(install): allow node-pty scripts with npm 12 2026-07-20 11:57:39 +02:00
Federico Jaramillo Martinez 4ca4a1d096 feat: add hierarchical session tree navigator 2026-07-20 10:40:17 +02:00
Federico Jaramillo Martinez a77c83b309 fix(sessions): clarify delegation tool guidance 2026-07-20 00:48:08 +02:00
Federico Jaramillo Martinez 2c777b4959 feat: add collapsible session warnings 2026-07-19 22:39:35 +02:00
Federico Jaramillo Martinez d5650aef5b fix: scope notifications to the selected chat 2026-07-19 10:37:36 +02:00
Federico Jaramillo Martinez df8cf5a250 Merge pull request #77 from jmfederico/agent/session-notification-inbox
feat(sessions): add ephemeral notification inbox
2026-07-19 06:15:05 +02:00
Federico Jaramillo Martinez b85e1b9ebe fix: show project activity for external worktrees 2026-07-19 06:13:09 +02:00
Federico Jaramillo Martinez 793b492153 fix(sessions): canonicalize notification route cwd 2026-07-19 02:24:38 +02:00
Federico Jaramillo Martinez 71fd091e0e fix(sessions): preserve notification inbox authority 2026-07-19 02:17:59 +02:00
Federico Jaramillo Martinez 503c2c743d fix(sessions): harden notification inbox reconnects 2026-07-19 01:49:06 +02:00
Federico Jaramillo Martinez ada6f0ce1f feat(ui): add session notification tray and badges 2026-07-19 01:28:45 +02:00
Federico Jaramillo Martinez 6e09df8329 feat(sessions): add daemon notification inbox protocol 2026-07-19 01:28:45 +02:00
Federico Jaramillo Martinez d77ca66f28 chore(release): v1.202607.1 2026-07-19 00:37:48 +02:00
Federico Jaramillo Martinez 008c83bf72 Merge pull request #73 from jmfederico/agent/pr-64-audit
fix(auth): preserve browser auth-flow ownership
2026-07-18 22:14:44 +02:00
Federico Jaramillo Martinez 8ea3018415 fix(auth): guard post-login status refresh
Skip opportunistic status requests when the flow's originating machine is no longer selected, and discard in-flight status results after the machine or session selection changes.\n\nRefs #74
2026-07-18 21:54:26 +02:00
Federico Jaramillo Martinez d29fbb98b2 Merge pull request #70 from jmfederico/agent/issue-67
fix(terminals): load interactive login profiles
2026-07-18 21:46:57 +02:00