Same styling fix as NewIssueDialog — removes the rounded-md border
from the workspace toggle in the issue detail view.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Removes the rounded border around the execution workspace toggle section
and increases top/bottom padding for better visual spacing.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The zod schema validates archivedAt as a datetime string, but Drizzle's
timestamp column expects a Date object. The string was passed directly to
db.update(), causing a 500 error. Now we convert the string to a Date
in the route handler before calling the service.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When dragging or pasting an image into a markdown editor field, the cursor
would end up right next to the image making it hard to continue typing.
Now inserts two newlines after the image so a new paragraph is ready.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Headers were butting up against previous paragraphs too closely. Changed
rendered markdown header selectors from :where() to direct element selectors
to increase CSS specificity and beat Tailwind prose defaults. Bumped
margin-top from 1.15rem to 1.75rem. Also added top margins to MDXEditor
headers (h1: 1.4em, h2: 1.3em, h3: 1.2em) which previously had none.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Swap the browser alert dialog for an in-page confirm/cancel button pair.
Shows a loading spinner while the archive request is in flight, then the
redirect and toast (from prior commit) handle the rest.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The sticky float-right save/cancel bar was rendering (invisible via
opacity-0) on all tabs including runs, causing it to push the runs
layout content. Now only rendered when showConfigActionBar is true.
Also reverts the negative margin workaround from the previous attempt.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When no goals are linked, hide the "None" label and just show the
"+ Goal" button. When goals exist, add left margin to the button so
it doesn't crowd the goal badges.
Closes PAP-522
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously archiving a project silently navigated to /projects with no
feedback. Now it navigates to /dashboard and shows a success toast for
both archive and unarchive actions.
Closes PAP-521
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use negative right margin to counteract the Layout container padding,
giving the runs detail panel more horizontal space especially on
smaller screens.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename "List" tab to "Issues" and reorder: Issues, Overview, Configuration
- Cache the last active tab per project in localStorage
- On revisit, restore the cached tab instead of always defaulting to Issues
Closes PAP-520
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove unnecessary `as any` casts on capability strings (now valid
PluginCapability members) and add company-membership guards to match
production behavior in plugin-host-services.ts.
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
- 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
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>
- README: mark plugin system as shipped in roadmap
- SPEC: update adapter table with openclaw_gateway, gemini-local, hermes_local
- SPEC: update plugin architecture section to reflect shipped status
- Add .doc-review-cursor for future maintenance runs
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The code blocks users see in issue documents are rendered by CodeMirror
(via MDXEditor's codeMirrorPlugin), not by MarkdownBody. MDXEditor
bundles cm6-theme-basic-light which gives them a white background.
Added dark overrides for all CodeMirror elements:
- .cm-editor: dark background (#1e1e2e), light text (#cdd6f4)
- .cm-gutters: darker gutter with muted line numbers
- .cm-activeLine, .cm-selectionBackground: subtle dark highlights
- .cm-cursor: light cursor for visibility
- Language selector dropdown: dark-themed to match
- Reduced pre padding to 0 since CodeMirror handles its own spacing
Uses \!important to beat CodeMirror's programmatically-injected theme
styles (EditorView.theme generates high-specificity scoped selectors).
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Previous attempt was being overridden by Tailwind prose/prose-invert
CSS variables. This fix:
- Overrides --tw-prose-pre-bg and --tw-prose-invert-pre-bg CSS variables
on .paperclip-markdown to force dark background in both modes
- Uses .paperclip-markdown pre with \!important for bulletproof overrides
- Removes conflicting prose-pre: utility classes from MarkdownBody
- Adds explicit pre code reset (inherit color/size, no background)
- Verified visually with Playwright at desktop and mobile viewports
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Adds a dedicated Docker environment for reviewing untrusted pull requests
with codex/claude, keeping CLI auth state in volumes and using a separate
scratch workspace for PR checkouts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>