Vendor the anti-slop Oxlint plugin at tools/oxlint/anti-slop and register it
in oxlint.config.ts, with Oxlint's own rule categories disabled so ESLint
stays the general-purpose linter.
Add scripts/anti-slop.mjs (bun run deslop) mirroring the React Doctor batch
interface: next-batch, check-batch, active, release, top, file. Batch handoff
directories now double as file claims shared across clones via
~/.openchamber/maintenance-claims, so concurrent maintenance batches from
either pipeline never select the same file.
Harden both scheduled maintenance flows: stop on a dirty worktree, stop on
NO BATCH AVAILABLE, validate per package instead of workspace-wide, and pin
react-doctor to 0.9.12. The anti-slop task command documents concrete
good and bad fixes and forbids laundering types to satisfy a rule.
Branch status resolves an open PR across the whole fork network first, so a
merged fork PR can never hide an open upstream PR for the same head. Only when
no target has an open PR does the branch's newest closed/merged PR come back,
as history.
The panel shows that history as a compact note and offers creating the next PR
below it, instead of either sticking on a terminal PR or going blank after a
merge. Terminal associations stay persisted for reload continuity but are never
treated as authority: they revalidate on the discovery cadence and on focus.
History is looked up only for the branch's own remote and name, and remembered
per repo+branch, so the extra lookup cannot exhaust the route's resolve budget.
The checks summary and merge-permission lookup are skipped for a closed or
merged PR, where neither is actionable.
Auto-derived project labels were title-cased, turning .ssh into .Ssh and
opencode-claude into Opencode Claude. Show the folder name verbatim in the
sidebar, window title, settings selector and notification templates, and
migrate persisted legacy labels back to the folder name (manual renames
are preserved).
Create no longer aborts when recoverStaleDraftDirectory rewrites the
implicit new-chat draft to the active project during the create probe.
Also rank the Unreleased Chat bullet below the changelog highlights.
Co-authored-by: serkraser <serkraser@gmail.com>
Keep both Unreleased changelog bullets: the lastDirectory new-chat
fallback and the Git PR panel stale-status fix from main.
Co-authored-by: serkraser <serkraser@gmail.com>
When a regular new-chat draft inherits a deleted lastDirectory, update
the visible draft target to the active project immediately. lastDirectory
still stays unchanged until session creation succeeds.
Co-authored-by: serkraser <serkraser@gmail.com>
Add store persist/hydrate regressions for terminal branch associations
and a server test that a complete empty open list does not query closed
PRs. Inline the open-only matcher state so the next repo target can win.
Co-authored-by: serkraser <serkraser@gmail.com>
Branch PR status now resolves open PRs only, revalidates closed/merged
associations on a discovery cadence, and clears authoritative empty
results so the panel can self-heal without a manual refresh.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
New chats inherited a persisted lastDirectory even after that worktree
was removed, so the first message saved but the prompt never started.
Validate the implicit draft directory, fall back to the active project
only when OpenCode confirms the path is missing, and leave explicit
worktree targets and unknown probes unchanged.
Co-authored-by: serkraser <serkraser@gmail.com>
Keep session-message loads and retries on messagesEnabled so a mounted
session-chat panel can materialize history even before the visibility
handshake, and cover the enabled-gate with the real hook.
Co-authored-by: serkraser <serkraser@gmail.com>
The helper reimplemented `if (!enabled) return []` locally, so those
cases never exercised the real hook. Keep the snapshot-builder and
source-contract coverage instead.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Replace the fake enabled-gate helper's store fixture with
buildSessionMessageRecordsSnapshot so the regression covers the same
record shape ChatContainer renders.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Busy context-panel session chats could render only the working-status row
when the iframe booted inactive or lost its visibility handshake, because
message reads shared the composer/background-work gate. Keep message
subscriptions enabled in the mounted session-chat panel so materialized
history remains visible (#2903, #2892).
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
d353638f3 replaced both `runtimeFetch('/api/small-model/generate')` calls
with `requestSmallModel` but left the original import in place, so
`@typescript-eslint/no-unused-vars` fails `bun run --filter '*' lint` on
main:
packages/ui/src/lib/gitApi.ts
5:10 error 'runtimeFetch' is defined but never used
This blocks CI for every open PR, since pull_request runs lint against the
merge with main.
The Skills Catalog source dropdown showed "ClawdHub"; the registry brands
itself as ClawHub. Update curated/fallback labels across web, UI, and VS Code,
align docs, and add regression tests.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
The opencode-claude integration registers its provider as `claude-code`, which
never matched the `claude` quota provider, so the collapsed Usage section in
the work status panel showed no limit for a model from that integration.
Claude windows also reported no duration, leaving the headline to fall back to
whichever row came first instead of the limit that runs out soonest. The
session and weekly windows now carry their length; extra usage stays without
one because it is a monthly spend cap.
Claude quota only worked when the user had signed into Anthropic through
OpenCode. Credentials are now discovered from Claude Code itself first: the
macOS Keychain entry, then the Linux/WSL credentials file (honouring
CLAUDE_CONFIG_DIR), then OpenCode auth.json, then CLAUDE_CODE_OAUTH_TOKEN.
All sources stay read-only and the OAuth token is never refreshed: Anthropic
allows one live refresh token per client_id, so refreshing here would sign the
user out of Claude Code. Credentials are re-read per request instead, and an
expired token reports that Claude Code needs a sign-in rather than a bare 401.
Usage is now read from the limits[] array, so model-scoped weekly limits work
again after Anthropic stopped populating seven_day_sonnet/seven_day_opus, and
new limit kinds no longer need a code change. Adds extra-usage spend and the
plan name, and holds the last good values through Anthropic's 429s with a
cooldown and an account-keyed cache.
Adds a keydown handler on the comment input that stops propagation
Keeps Enter-to-submit behavior working in the annotation overlay
Cleans up the new event listener when the overlay is removed
Data already reloads on mount, after mutations, and after Apply & Restart,
so the section Refresh button was redundant noise.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Remove the repeated installed/status block inside expanded third-party
cards, and phrase page/plugin descriptions as adding a subscription to
use as an OpenChamber provider.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
The icon sprite was injected once and never updated, so HMR/new glyphs
like telegram-fill left <use> refs empty. Append missing symbols on render.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
The Integrations cards render Icon(plugin.icon), so Claude Code /
Command Code / Cursor brand glyphs belong in the sprite. Also restore
claude-code.svg and the Command Code ProviderLogo fallback used after
Set up opens the Providers page. Leave out unused opencode.svg.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Keep only the Settings Integrations page wiring: three plugins, i18n,
search/metadata, and the plugins-store registry boolean needed for
failure status. Remove ProviderLogo fallbacks, SVG assets, custom sprite
icons, and the separate IntegrationCard layer.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Adding the third-party integrations import shifted the existing UTF-8 BOM
onto line 2 and tripped no-irregular-whitespace.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Add a Settings → Integrations page for installing and managing the three
supported OpenCode provider plugins (Claude Code, Command Code, Cursor),
with search, i18n, and plugin-registry status wiring.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
A server running with authentication disabled pairs and connects fine, but
the saved connection has no bearer token. Auto-connect silently bailed on
the missing token and the resume reprobe reported it as 'unreachable',
so every return to the app kicked the user to the connect screen.
Treat a saved tokenless connection as valid: probe it without a bearer and
let the probe decide — auth disabled connects, auth enabled later reports
needs-login. Bail out only when an expected token cannot be read.