Instead of a hardcoded experimentId=daily_limit, randomly assign users
to one of four survey direction buckets (competitor, switching, workflow,
activation) matching the round 2 survey pattern.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Copy dev workflow skills (dev, dev1-start through dev7-pr, dev-debug,
ts-style-review) to project .claude/skills/ so they're available to all
contributors. Excludes twitter agent and browseros browser skills.
Update .gitignore to track .claude/skills/ and .claude/commands/.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: update to support more klavis MCP servers
* fix: minor icon fix
* fix: normalize klavis mcp auth flow compatibility
* feat: add API key auth flow for Klavis MCP servers
Servers that use API key authentication (Stripe, Cloudflare, Brave
Search, Exa, Mem0, Resend, Mixpanel, PostHog, Postman, Zendesk,
Intercom) were failing with "Failed to add app" because the frontend
only handled OAuth flows. This adds the complete API key auth path:
- Backend: apiKeyUrls in StrataCreateResponse, submitApiKey() method,
/servers/submit-api-key route
- Frontend: ApiKeyDialog component, useSubmitApiKey hook, ConnectMCP
updated to show dialog for API-key servers instead of opening OAuth
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove broken success check in Klavis submitApiKey
The Klavis /mcp-server/instance/set-auth endpoint returns
{ message: "Authentication updated successfully." } without a
success field. Our code checked `data.success` which was always
undefined, causing API key auth to fail even when Klavis accepted
the key. The request() method already throws on non-2xx responses,
so the explicit check was redundant and incorrect.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add Round 2 direction parameter to JTBD survey frontend
Thread direction parameter from popup trigger through URL params to the
survey chat API. Randomly assign one of 4 investigation directions
(competitor, switching, workflow, activation) when the in-app popup
triggers, encoding it as experimentId=r2_{direction} for analytics.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove direction param, encode in experimentId instead
Direction is now encoded entirely in experimentId (e.g., "r2_competitor").
Remove the separate direction URL param and prop threading — the backend
derives direction from experimentId. Simplifies the frontend to only
set experimentId with a random direction on popup trigger.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: setup
* fix: compact workflow tidbits within streamed assistant parts
feat: collapse workflow tidbit status messages in graph chat
* Revert "fix: compact workflow tidbits within streamed assistant parts"
This reverts commit f5fa6d6b7a480dfc001ede6de7949f45c7777f37.
* fix: collapse workflow tidbit status messages in graph chat
Tidbit messages (jokes/status ending with ...) during workflow execution
now replace each other in place instead of stacking as separate chat
bubbles. Handles both consecutive tidbit messages and multiple tidbit
text parts within a single streamed message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: compact multi-line tidbits within a single text part
Tidbits arrive as text-deltas accumulated into a single text part
(e.g. "Generating workflow…\nReticulating splines…\n..."). The previous
fix only handled separate parts and separate messages but not multiple
tidbit lines within one part. Added compactTidbitLinesInPart to trim
multi-line tidbit text to just the last line.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Added max-h-[85vh] and overflow-y-auto to DialogContent component
to enable scrolling when dialog content exceeds viewport height.
This fixes the scheduled task dialog not showing scroll when
content is too long.
https://claude.ai/code/session_01CP8aUnunJpW9mYwTbt3gpt
Co-authored-by: Claude <noreply@anthropic.com>
* chore: baseline setup
* fix: resolve stale closure bug in LLM Hub provider management
saveProvider and deleteProvider were wrapped in useCallback with
[providers] dependency, building updated arrays from the closure-captured
providers state. When adding a provider then deleting another, the delete
callback could have a stale providers array that didn't include the newly
added one — causing the new provider to be lost when written to storage.
Fix: read current state from persistent storage via loadProviders()
before every mutation, matching the pattern used in useLlmProviders.ts.
Remove useCallback wrappers since they no longer depend on providers state.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: inject stop button to pages controlled by agent (#334)
* chore: baseline setup
* feat(agent): When the agent is running, right now we inject an orange glow. See the `apps/age
Task ID: TOiaMuDz
* fix: clean up agent storage
* fix: improve the stop button style
* fix: type issues with stopAgentStorage
---------
Co-authored-by: BrowserOS Coding Agent <coding-agent@browseros.com>
Co-authored-by: Dani Akash <DaniAkash@users.noreply.github.com>
* fix: resolve stale closure bug in LLM Hub provider management
saveProvider and deleteProvider were wrapped in useCallback with
[providers] dependency, building updated arrays from the closure-captured
providers state. When adding a provider then deleting another, the delete
callback could have a stale providers array that didn't include the newly
added one — causing the new provider to be lost when written to storage.
Fix: read current state from persistent storage via loadProviders()
before every mutation, matching the pattern used in useLlmProviders.ts.
Remove useCallback wrappers since they no longer depend on providers state.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: BrowserOS Coding Agent <coding-agent@browseros.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Dani Akash <DaniAkash@users.noreply.github.com>
* chore: baseline setup
* feat(agent): When the agent is running, right now we inject an orange glow. See the `apps/age
Task ID: TOiaMuDz
* fix: clean up agent storage
* fix: improve the stop button style
* fix: type issues with stopAgentStorage
---------
Co-authored-by: BrowserOS Coding Agent <coding-agent@browseros.com>
Co-authored-by: Dani Akash <DaniAkash@users.noreply.github.com>
saveProvider and deleteProvider used useCallback with [providers]
dependency, causing a stale closure bug. When adding a new provider
then deleting another, the delete callback still referenced the old
providers array (before the add), losing the newly added provider.
Now reads current state from storage before each mutation, matching
the pattern used in useLlmProviders. Also removes unnecessary
useCallback wrappers per project conventions.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>