Wire issue document list/get/upsert/delete operations through the
JSON-RPC protocol so plugins can manage issue documents with the same
capabilities available via the REST API.
Fixes#940
* public-gh/master: (51 commits)
Use attachment-size limit for company logos
Address Greptile company logo feedback
Drop lockfile from PR branch
Use asset-backed company logos
fix: use appType "custom" for Vite dev server so worktree branding is applied
docs: fix documentation drift — adapters, plugins, tech stack
docs: update documentation for accuracy after plugin system launch
chore: ignore superset artifacts
Dark theme for CodeMirror code blocks in MDXEditor
Remove duplicate @paperclipai/adapter-openclaw-gateway in server/package.json
Fix code block styles with robust prose overrides
Add Docker setup for untrusted PR review in isolated containers
Fix org chart canvas height to fit viewport without scrolling
Add doc-maintenance skill for periodic documentation accuracy audits
Fix sidebar scrollbar: hide track background when not hovering
Restyle markdown code blocks: dark background, smaller font, compact padding
Add archive project button and filter archived projects from selectors
fix: address review feedback — subscription cleanup, filter nullability, stale diagram
fix: wire plugin event subscriptions from worker to host
fix(ui): hide scrollbar track background when sidebar is not hovered
...
# Conflicts:
# packages/db/src/migrations/meta/0030_snapshot.json
# packages/db/src/migrations/meta/_journal.json
- Extract all Anthropic credential/API logic into claude-local/src/server/quota.ts
- Extract all OpenAI/WHAM credential/API logic into codex-local/src/server/quota.ts
- Add optional getQuotaWindows() to ServerAdapterModule in adapter-utils
- Rewrite quota-windows.ts as a 29-line thin aggregator with zero provider knowledge
- Wire getQuotaWindows into adapter registry for claude-local and codex-local
- Add 47 unit tests covering toPercent, secondsToWindowLabel, WHAM normalization,
readClaudeToken, readCodexToken, fetchClaudeQuota, fetchCodexQuota, fetchWithTimeout
- Add 8 unit tests covering parseDateRange validation and byProvider pro-rata math
Adding a third provider now requires only touching that provider's adapter.
- add byAgentModel endpoint and expandable per-agent model sub-rows in the spend tab
- validate date range inputs with isNaN + badRequest to return HTTP 400 on bad input
- move CostByProject from a local api/costs.ts definition into packages/shared types
- gate providerData query on mainTab === providers, consistent with weekData/windowData/quotaData
- fix byProject range filter from finishedAt to startedAt, consistent with byProvider runs query
- fix WHAM used_percent threshold from <= 1 to < 1 to avoid misclassifying 1% usage as 100%
- replace inline opacity style with tailwind bg-primary/85 class in ProviderQuotaCard
- reset expandedAgents set when company or date range changes
- sort agent model sub-rows by cost descending in ui memo
- add company existence check on quota-windows route to guard against
sentinel and forged company IDs (was a no-op assertCompanyAccess)
- fix useDateRange minuteTick memo frozen at mount; realign interval to
next calendar minute boundary via setTimeout + intervalRef pattern
- fix midnight timer in Costs.tsx to use stable [] dep and
self-scheduling todayTimerRef to avoid StrictMode double-invoke
- return null for rolling window rows with no DB data instead of
rendering $0.00 / 0 tok false zeros
- fix secondsToWindowLabel to handle windows >168h with actual day count
instead of silently falling back to 7d
- fix byProvider.get(p) non-null assertion to use ?? [] fallback
merge Usage page into Costs as two tabs ('Spend' and 'Providers'),
extract shared date-range logic to useDateRange() hook, delete /usage
route and sidebar entry, fix quota-windows bugs from prior review
reads local claude and codex auth files server-side, calls provider
quota apis (anthropic oauth usage, chatgpt wham/usage), and surfaces
live usedPercent per window in ProviderQuotaCard with threshold fill colors
adds a new /usage page that lets board operators see how much each ai
provider is consuming across any date window, with per-model breakdowns,
rolling 5h/24h/7d burn windows, weekly budget bars, and a deficit notch
when projected spend is on track to exceed the monthly budget.
- new GET /companies/:id/costs/by-provider endpoint aggregates cost events
by provider + model with pro-rated billing type splits from heartbeat runs
- new GET /companies/:id/costs/window-spend endpoint returns rolling window
spend (5h, 24h, 7d) per provider with no schema changes
- QuotaBar: reusable boxed-border progress bar with green/yellow/red
threshold fill colors and optional deficit notch
- ProviderQuotaCard: per-provider card showing budget allocation bars,
rolling windows, subscription usage, and model breakdown with token/cost
share overlays
- Usage page: date preset toggles (mtd, 7d, 30d, ytd, all, custom),
provider tabs, 30s polling plus ws invalidation on cost_event
- custom date range blocks queries until both dates are selected and
treats boundaries as local-time (not utc midnight) so full days are
included regardless of timezone
- query key to timestamp is floored to the nearest minute to prevent
cache churn on every 30s refetch tick
When importing a company, users can now choose the adapter type for each
imported agent. Defaults to the current company CEO's adapter type (or
claude_local if none). Includes an expandable "configure adapter" section
per agent that renders the adapter-specific config fields.
- Added adapterOverrides to import request schema and types
- Built AdapterPickerList UI component in CompanyImport.tsx
- Backend applies adapter overrides when creating/updating agents
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Remove the collision strategy dropdown; always default to "rename"
- Add a "Conflicts to resolve" chores list above the package file tree
showing each collision with editable rename fields (oldname → newname)
- Default rename uses source folder prefix (e.g. gstack-CEO)
- Per-item "skip" button that syncs with file tree checkboxes
- COMPANY.md defaults to skip when importing to an existing company
- Add nameOverrides support to API types and server so user-edited
renames are passed through to the import
Co-Authored-By: Paperclip <noreply@paperclip.ing>
We don't support regular updates to agents from GitHub sources yet,
so the "not pinned to a commit SHA" warning is misleading and unnecessary.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When importing into an existing company, files with "update" action (conflicts)
now have their parent directories auto-expanded so users immediately see what
will be overwritten. Additionally, server-side warnings are generated for any
agent or project that will be overwritten by the import.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Vite's "spa" appType adds its own SPA fallback middleware that serves
index.html directly, bypassing the custom catch-all route that calls
applyUiBranding(). Changing to "custom" lets our route handle HTML
serving, which injects the worktree-colored favicon and banner meta tags.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move all tasks to top-level tasks/ folder (no longer nested under
projects/slug/tasks/). The project slug is still in the frontmatter
for association.
- Search auto-expands parent dirs of matched files so matches are
always visible in the tree
- Restores previous expansion state when search is cleared
- All files already loaded in memory — search works across everything
with no pagination limit
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add `files` and `manifest` to CompanyPortabilityPreviewResult so the
import UI can show actual file contents and metadata
- Rewrite import preview as a file/folder tree (matching export page
design language) with per-file checkboxes to include/exclude items
- Show action badges (create/update/skip) on each file based on the
import plan, with unchecked files dimmed and badged as "skip"
- Add rich frontmatter preview: clicking a file shows parsed frontmatter
as structured data (name, title, reportsTo, skills) plus markdown body
- Include skills count in the sidebar summary
- Update import button to show dynamic file count that updates on
check/uncheck
- Both /tree/ and /blob/ GitHub URLs already supported by backend
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add scopedBus.clear() in dispose() to prevent subscription accumulation
on worker crash/restart cycles
- Use two-arg subscribe() overload when filter is null instead of passing
empty object; fix filter type to include null
- Update ASCII flow diagram: onEvent is a notification, not request/response
Plugin workers register event handlers via `ctx.events.on()` in the SDK,
but these subscriptions were never forwarded to the host process. The host
sends events via `notifyWorker("onEvent", ...)` which produces a JSON-RPC
notification (no `id`), but the worker only dispatched `onEvent` as a
request handler — notifications were silently dropped.
Changes:
- Add `events.subscribe` RPC method so workers can register subscriptions
on the host-side event bus during setup
- Handle `onEvent` notifications in the worker notification dispatcher
(previously only `agents.sessions.event` was handled)
- Add `events.subscribe` to HostServices interface, capability map, and
host client handler
- Add `subscribe` handler in host services that registers on the scoped
plugin event bus and forwards matched events to the worker