Commit Graph

1122 Commits

Author SHA1 Message Date
Dotta
bb46423969 Fix agent skills autosave hydration\n\nCo-Authored-By: Paperclip <noreply@paperclip.ing> 2026-03-16 17:46:07 -05:00
Dotta
8460fee380 Reduce company skill list payloads
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 17:45:28 -05:00
Dotta
cca086b863 Merge public-gh/master into paperclip-company-import-export 2026-03-16 17:02:39 -05:00
Dotta
c578fb1575 Merge pull request #949 from paperclipai/feature/upgraded-costs-and-budgeting
feat(costs): add billing, quota, and budget control plane
2026-03-16 16:52:57 -05:00
Dotta
8fbbc4ada6 Fix budget incident resolution edge cases 2026-03-16 16:48:13 -05:00
Dotta
d77630154a Fix required Paperclip skill rows on agent detail 2026-03-16 16:39:21 -05:00
Dotta
1990b29018 Fix agent budget tab routing 2026-03-16 16:02:21 -05:00
Dotta
10d06bc1ca Separate required skills into own section on agent skills page
Required/built-in Paperclip skills are now shown in a dedicated
"Required by Paperclip" section at the bottom of the agent skills tab,
with checkboxes that are checked and disabled. Optional skills remain
in the main section above.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 16:01:20 -05:00
Dotta
728d9729ed Fix budget auth and monthly spend rollups 2026-03-16 15:41:48 -05:00
Dotta
0b76b1aced Fix import adapter configuration forms
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 15:41:06 -05:00
Dotta
5f2c2ee0e2 Harden budget enforcement and migration startup 2026-03-16 15:11:34 -05:00
Dotta
411952573e Add budget tabs and sidebar budget indicators 2026-03-16 15:11:01 -05:00
Dotta
76e6cc08a6 feat(costs): add billing, quota, and budget control plane 2026-03-16 15:11:01 -05:00
Sai Shankar
656b4659fc refactor(quota): move provider quota logic into adapter layer, add unit tests
- 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.
2026-03-16 15:08:54 -05:00
Sai Shankar
f383a37b01 fix(costs): replace non-null map assertions with nullish coalescing, clarify weekData guard 2026-03-16 15:08:54 -05:00
Sai Shankar
3529ccfa85 fix(costs): guard byProject against duplicate null keys, memoize ProviderQuotaCard row aggregations 2026-03-16 15:08:54 -05:00
Sai Shankar
7db3446a09 fix(costs): align byAgent run filter to startedAt, tighten providerTabItems memo deps, stabilize byProject row keys 2026-03-16 15:08:54 -05:00
Sai Shankar
9d21380699 feat(costs): add agent model breakdown, harden date validation, sync CostByProject type, fix quota threshold and tab-gated queries
- 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
2026-03-16 15:08:54 -05:00
Sai Shankar
db20f4f46e fix(costs): harden company auth check, fix frozen date memo, hide empty quota rows
- 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
2026-03-16 15:08:54 -05:00
Sai Shankar
bc991a96b4 fix(costs): guard routes, fix DST ranges, sync provider state, wire live updates
- add companyAccess guard to costs route
- fix effectiveProvider/activeProvider desync via sync-back useEffect
- move ROLLING_WINDOWS to module level; replace IIFE with useMemo in ProviderQuotaCard
- add NO_COMPANY sentinel to eliminate non-null assertions before enabled guard
- fix DST-unsafe 7d/30d ranges in useDateRange (use Date constructor)
- remove providerData from providerTabItems memo deps (use byProvider)
- normalize used_percent 0-1 vs 0-100 ambiguity in quota-windows service
- rename secondsToWindowLabel index param to fallback; pass explicit labels
- add 4.33 magic number comment; fix quota window key collision
- remove rounded-md from date inputs (violates --radius: 0 theme)
- wire cost_event invalidation in LiveUpdatesProvider
2026-03-16 15:08:54 -05:00
Sai Shankar
56c9d95daa feat(costs): consolidate /usage into /costs with Spend + Providers tabs
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
2026-03-16 15:08:54 -05:00
Sai Shankar
f14b6e449f feat(usage): add subscription quota windows per provider on /usage page
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
2026-03-16 15:08:54 -05:00
Sai Shankar
82bc00a3ae address greptile review: per-provider deficit notch, startedAt filter, weekRange refresh, deduplicate providerDisplayName 2026-03-16 15:08:54 -05:00
Sai Shankar
94018e0239 feat(ui): add resource and usage dashboard (/usage route)
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
2026-03-16 15:08:54 -05:00
Dotta
fed94d18f3 Improve imported agent adapter selection 2026-03-16 12:17:28 -05:00
Dotta
3dc3347a58 Merge pull request #162 from JonCSykes/feature/upload-company-logo
Feature/upload company logo
2026-03-16 11:10:07 -05:00
Dotta
0763e2eb20 fix: hide instructions file and show advanced fields in import adapter config
- Added hideInstructionsFile prop to AdapterConfigFieldsProps
- All adapter config-fields now conditionally hide the instructions file
  field when hideInstructionsFile is set (used during import since the
  AGENTS.md is automatically set as promptTemplate)
- Import adapter config panel now renders ClaudeLocalAdvancedFields
  (Chrome, skip permissions, max turns) when claude_local is selected

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 11:09:36 -05:00
Dotta
1548b73b77 feat: add adapter picker for imported agents
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>
2026-03-16 10:28:44 -05:00
Dotta
cf8bfe8d8e Fix company import file selection
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 10:14:09 -05:00
Dotta
6eceb9b886 Use attachment-size limit for company logos 2026-03-16 10:13:19 -05:00
Dotta
4dfd862f11 Address Greptile company logo feedback 2026-03-16 10:05:14 -05:00
Dotta
5d6dadda83 fix: default import target to new company instead of existing
The /company/import page now defaults the target dropdown to "Create new
company" instead of the current company. The existing company option is
still available in the dropdown.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 10:05:03 -05:00
Dotta
43fa4fc487 fix: show rename indicator on folder, not AGENTS.md file
Move the rename indicator (→ newName) in the file tree to only
display on the parent directory node, not on the individual file.
The preview header still shows the rename when viewing the file.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 09:58:33 -05:00
Dotta
bf9b057670 feat: show rename indicators in file tree and preview, right-align import button
- Move "Import n files" button to right side of its container
- Show "→ newName" rename indicator next to files/directories in the
  file tree when an agent or project is being renamed on import
- Show "→ newName" rename indicator in the file preview header when
  viewing a file that will be renamed
- Uses cyan color to distinguish rename info from action badges

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 09:54:20 -05:00
Dotta
4a5aba5bac Restrict company imports to GitHub and zip packages
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 09:52:16 -05:00
Dotta
0b829ea20b fix: move import button below renames panel
Move the "Import n files" button from the sticky header bar to below
the renames confirmation panel, so the user reviews renames first
before importing.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 09:47:29 -05:00
Dotta
2d548a9da0 Drop lockfile from PR branch 2026-03-16 09:37:23 -05:00
Dotta
86bb3d25cc fix: refine import renames panel per feedback
- Remove COMPANY.md from renames panel; just uncheck it silently in
  the file tree when importing to existing company
- Rename panel from "Conflicts to resolve" to "Renames"
- Add "skip" button on the left and "confirm rename" button on the
  right of each rename row
- Confirmed renames show a green checkmark and green-tinted row
- Skipped items gray out and uncheck the file in the tree
- Un-confirmed renames still proceed with the rename by default

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 09:35:26 -05:00
Dotta
e538329b0a Use asset-backed company logos 2026-03-16 09:25:39 -05:00
Dotta
ad494e74ad feat: replace collision strategy dropdown with inline conflict resolution UI
- 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>
2026-03-16 09:21:48 -05:00
Dotta
bc8fde5433 fix: remove GitHub source pinning warning from company import
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>
2026-03-16 09:08:12 -05:00
Dotta
8d0581ffb4 refactor: extract shared PackageFileTree component for import/export
Extract duplicated file tree types, helpers (buildFileTree, countFiles,
collectAllPaths, parseFrontmatter), and visual tree component into a
shared PackageFileTree component. Both import and export pages now use
the same underlying tree with consistent alignment and styling.

Import-specific behavior (action badges, unchecked opacity) is handled
via renderFileExtra and fileRowClassName props. Also removes the file
count subtitle from the import sidebar to match the export page.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 09:04:22 -05:00
Dotta
298cb4ab8a fix: auto-expand conflicting files and warn on agent overwrites during import
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>
2026-03-16 08:59:43 -05:00
Dotta
3572ef230d fix: update import page badge colors for consistency
- update: blue → yellow (amber)
- overwrite/replace: added as red
- create (green) and skip (gray) unchanged

Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 08:58:19 -05:00
Dotta
f8249af501 Stop exporting paperclipSkillSync in company packages
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 08:55:37 -05:00
Dotta
140c4e1feb fix: move import/export buttons to top left on org chart page
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 08:55:11 -05:00
Dotta
617aeaae0e Use zip archives for company export
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 08:54:50 -05:00
Dotta
b116e04894 fix: hide collision strategy dropdown when importing to new company
No collisions are possible when the target is a new company, so the
dropdown is unnecessary. The grid layout also adjusts to single-column
when only the target field is shown.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-16 08:54:10 -05:00
Dotta
dc1bf7e9c6 fix: match import page warning/error boxes to export page card style
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 08:53:45 -05:00
Dotta
1a5eaba622 Merge public-gh/master into review/pr-162 2026-03-16 08:47:05 -05:00