Commit Graph

2313 Commits

Author SHA1 Message Date
shivammittal274
a85f94de40 feat(cli): add strata commands for Klavis MCP integrations (#700)
Expose the 7 Klavis Strata MCP tools as CLI subcommands under
`browseros-cli strata`, so CLI users (claude-code, gemini-cli) can
discover and execute actions on 40+ external services.

Commands: check, discover, actions, details, exec, search, auth.
Includes discovery flow guidance in help text, integration tests,
and an "Integrations:" group in the root help output.
2026-04-14 17:32:05 +05:30
Dani Akash
6708ab834b fix: restore openai compatible openclaw providers (#699) 2026-04-14 14:15:11 +05:30
shivammittal274
007208d54b feat: add connector_mcp_servers tool for strata MCP server discovery (#698)
Agents connecting over MCP URL/CLI (like claude-code) had no way to know
which Klavis connectors were available or authenticated, causing them to
fall back to browser automation. This adds a connector_mcp_servers tool
that checks connection status and returns an auth URL when needed.
2026-04-14 13:09:30 +05:30
shivammittal274
dd85ae503f fix(openclaw): compose file path and extension auth (#697)
* fix(openclaw): compose file path after service dir move, loopback auth fallback

- Fix COMPOSE_RESOURCE path: services moved to api/services/openclaw/
  so the relative path needs one more parent directory traversal
- Fix requireTrustedAppOrigin middleware: Chrome extensions cannot set
  the Origin header (forbidden header name). When Origin is absent,
  fall back to checking the Host header is a loopback address. The
  server only binds to loopback so only local processes can reach it.
  Requests with an explicit non-trusted Origin are still rejected.

* fix: request header check

* chore: remove setup openclaw button

---------

Co-authored-by: Dani Akash <DaniAkash@users.noreply.github.com>
2026-04-14 12:53:02 +05:30
Dani Akash
452906d3ca fix: first time run (#696)
* fix: openclaw creation

* fix: request formats

* ci: extend code quality to dev
2026-04-14 12:29:53 +05:30
Nikhil
0397d3e393 chore: release alpha: 0.0.83 (#695) 2026-04-13 18:00:52 -07:00
Nikhil
edd681012c refactor: consolidate services under api/services/ (#693)
Move openclaw/ and terminal/ service modules from src/services/ into
src/api/services/ so all server-side services live in one directory
alongside chat-service, klavis, mcp, and sdk. Update relative imports
in moved files and all callers.
2026-04-13 17:21:45 -07:00
Nikhil
ce7c209ba6 feat: add OpenClaw agent command center and terminal (#692)
* feat: agent command center new tab with OpenClaw conversation history

* feat: add web terminal for Podman container shell access

* feat: align agent command center with new tab

* fix: simplify agent command center styling

* style: polish agent terminal layout and theming

* style: simplify agent terminal styling

* fix: address PR review comments for OpenClaw routes

* fix: handle OpenClaw client start and error states

* fix: resolve remaining OpenClaw review comments
2026-04-13 17:06:48 -07:00
Nikhil
6548220bcb chore: merge pull request #690 (feat/acls-approvals)
feat: acl approvals
2026-04-13 09:45:46 -07:00
Neel Gupta
14eeba7c20 Feat: Improved ACL robustness with semantic and fuzzy matching (#665)
* feat: Add enhanced python-based ACL

* fix: Port enhanced ACL to TypeScript

* fix: greptile suggested bugs
2026-04-13 09:43:33 -07:00
Nikhil Sonti
3c629c5929 feat: tool approvals, governance dashboard, and execution history
- Add tool approval system with per-category approval configuration
- Build unified Governance dashboard (renamed from Admin) with pending
  approvals view and execution audit log
- Move execution history tracking into the app shell
- Extract buildChatRequestBody helper and add newtab system prompt
- Add approval config change detection for mid-conversation rebuilds
2026-04-13 09:43:30 -07:00
Nikhil
77dcd37000 feat: ACLs and support enforcing (#583)
* feat: add ACL rules for per-site element-level agent restrictions

Implement Access Control List (ACL) rules that let users block the agent
from interacting with specific elements on specific websites. Rules are
defined in a new Settings > ACL Rules page and enforced server-side in
executeTool() before any input tool handler runs.

- Shared ACL types and site pattern matching (packages/shared)
- Extension storage, settings UI with rule cards and add dialog
- Server-side guard in executeTool() checking tool+page+element
- Browser class extensions for element property resolution via CDP
- Visual overlay injection (red "BLOCKED" mask) via Runtime.evaluate
- Rules transported in chat request body alongside declinedApps

* fix: address review comments for ACL rules

- Add selector-to-property matching in matchesElement (tag, id, class)
- Remove scroll from guarded tools set (read-like action)

* fix: ACL site pattern matching fails on multi-segment URL paths

The glob-to-regex conversion used [^/]* for wildcard (*) which only
matches a single path segment. "*.amazon.com/*" failed to match
"www.amazon.com/cart/smart-wagon" because the trailing * couldn't
cross the slash between "cart" and "smart-wagon".

Fix: Split URL matching into hostname vs path parts. Path wildcards
now use .* to match across slashes. Also add simple domain matching
so users can just type "amazon.com" instead of "*.amazon.com/*".

* fix: wire up ACL overlay injection after take_snapshot

applyAclOverlays was defined but never called. Now triggers after
take_snapshot completes on pages matching ACL rules, so the agent
sees red "BLOCKED" overlays on restricted elements.

* refactor: rework 0326-acl_rules based on feedback
2026-04-13 09:42:45 -07:00
Nikhil
6d0dff7b1a feat: claw integration with browseros (#688)
* feat(openclaw): add foundation — paths constant, browseros-dir helper, static compose file

Add OPENCLAW_DIR_NAME to shared paths constant, getOpenClawDir() to
browseros-dir.ts, and a static docker-compose.yml resource file that
uses native .env variable substitution instead of YAML template strings.

* feat(openclaw): add PodmanRuntime container engine abstraction

Manages Podman CLI interactions: machine lifecycle (init/start/stop),
availability checks, command execution with streaming output, and
running container enumeration. Linux skips machine ops since Podman
runs natively.

* feat(openclaw): add config builder and container runtime

openclaw-config.ts: pure functions to build openclaw.json and .env files
from BrowserOS settings. Maps provider keys, sets permissive defaults
(full exec, cron, web search, MCP bridge to BrowserOS).

container-runtime.ts: compose-level abstraction over PodmanRuntime for
the browseros-openclaw project. Handles up/down/restart/pull, health
checks, .env file writes, and safe machine shutdown.

* feat(openclaw): add OpenClawService orchestrator

Main service managing the single OpenClaw container. Handles full
lifecycle (setup/start/stop/restart/shutdown), agent CRUD with config
rewrites and gateway restarts, chat proxy to /v1/chat/completions,
provider key updates, auto-start on BrowserOS boot, and status reporting.

* feat(openclaw): add API routes and server wiring

Add /api/claw/* routes for container lifecycle (setup/start/stop/restart),
agent CRUD (list/create/delete), chat proxy with SSE streaming, provider
key management, and log retrieval. Register routes in server.ts, add
OpenClaw auto-start on BrowserOS boot and graceful shutdown in main.ts.

* fix(openclaw): resolve type errors in service and podman runtime

Fix TIMEOUTS.TOOL_EXECUTION → TIMEOUTS.TOOL_CALL to match shared
constants. Fix ReadableStream undefined/null type mismatch in
PodmanRuntime.runCommand stream draining.

* feat(openclaw): add agents page UI with chat, create, and lifecycle controls

Add /agents route with AgentsPage showing OpenClaw status, agent list,
create dialog, and per-agent chat. Includes useOpenClaw hook for
server communication, AgentChat component with SSE streaming, and
sidebar navigation entry.

* feat(openclaw): add provider selector to setup flow

Add LLM provider selector using useLlmProviders hook. Filters out
OAuth-only providers, pre-selects the user's default, and passes
providerType/apiKey/modelId to the setup endpoint so OpenClaw gets
a working LLM configuration on first setup.

* feat(openclaw): per-agent provider selection

Each agent can now have its own LLM provider. The Create Agent dialog
includes a provider selector that passes providerType/apiKey/modelId
to the backend. The service writes per-agent model config to
openclaw.json and merges the API key into the container's .env file.

* fix(openclaw): write gateway auth token to openclaw.json

The gateway was returning 401 because auth.mode was set to "token"
without providing the actual token value. Now the token is written
to gateway.auth.token in openclaw.json so the gateway and our chat
proxy agree on the same token.

* feat(openclaw): add GatewayClient WebSocket RPC client

Persistent WS client for the OpenClaw Gateway protocol. Handles the
challenge → connect → hello-ok handshake (as openclaw-control-ui with
operator.admin scope), JSON-RPC with pending map + timeouts, and
auto-reconnect. Exposes typed methods for agents.list, agents.create,
agents.delete, and health.

* refactor(openclaw): simplify config to bootstrap-only, add /readyz health

Config no longer contains agents.list — agent CRUD is handled via WS RPC.
buildOpenClawConfig → buildBootstrapConfig, removed makeAgentEntry and
AgentEntry (agents managed by OpenClaw runtime). Added isReady() and
waitForReady() using /readyz for gateway readiness checks.

* refactor(openclaw): agent CRUD via WS RPC, per-agent chat targeting

Replace JSON mutation + restart with GatewayClient WS RPC calls for
agents.create, agents.delete, agents.list. Chat proxy now uses
model: "openclaw/<agentId>" for per-agent targeting. Setup writes
bootstrap config once then creates "main" agent via WS after gateway
starts. Container restarts only when a new provider env var is added.

* fix(openclaw): use agentId field in setup response mapping

Fix type error: GatewayAgentEntry uses agentId not id.

* fix(openclaw): log service progress through server logger

* feat(openclaw): WS streaming, device auth, MCP port fix (#687)

* feat(openclaw): WS streaming, device auth, MCP port fix

- Fix GatewayClient WS handshake: add Ed25519 device identity signing,
  Origin header, mode: cli (mode: ui requires device identity always)
- Add auto device pairing flow: generate client identity, attempt WS
  connect (triggers pending), approve via openclaw CLI, reconnect
- Replace HTTP /v1/chat/completions proxy with WS-based streaming that
  surfaces tool calls, thinking blocks, and text deltas
- Add chatStream() to GatewayClient returning ReadableStream of typed
  OpenClawStreamEvent (text-delta, thinking, tool-start/end, lifecycle)
- Update chat route to stream WS events as SSE to the extension
- Pass actual server port to OpenClaw config (fixes MCP bridge in dev)
- Rewrite AgentChat.tsx with turn-based model using Message/MessageContent
  components matching sidepanel pattern, with tool batching logic that
  groups consecutive tools and breaks on text/thinking (same as sidepanel)
- Add execInContainer() to ContainerRuntime for CLI commands
- Fix gateway response field mapping (id→agentId, agents.list/create)
- Skip creating main agent if gateway auto-creates it

* fix(openclaw): retry WS connect on signature expired (Podman clock skew)

Podman VM clock drifts when Mac sleeps, causing Ed25519 signature
validation to fail with "device signature expired" on auto-start.
Add connectGatewayWithRetry() that restarts the container (resyncs
clock) and re-approves the device if needed.

* fix(openclaw): address PR review — stream cleanup, error handling

- Fix silent catch in setup(): only swallow "pairing required" and
  "signature expired" errors, re-throw everything else
- Guard JSON.parse in approvePendingDevice(): check exit code and
  wrap parse in try/catch with descriptive error messages
- Add try/finally in chat SSE route: reader.cancel() on disconnect
- Add cancel callback to chatStream ReadableStream: restores
  ws.onmessage when stream is cancelled (prevents handler leak)

---------

Co-authored-by: shivammittal274 <56757235+shivammittal274@users.noreply.github.com>
2026-04-13 09:13:40 -07:00
Felarof
f78068bb9d chore: add .omc/ to gitignore (#682)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:53:24 -07:00
github-actions[bot]
6b18ebb1d8 docs: update agent extension changelog for v0.0.99 (#660)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-10 09:53:44 -07:00
shivammittal274
1f2e783ab9 fix: enable agent interaction with elements inside iframes (#667)
* fix: enable agent interaction with elements inside iframes

Fetch accessibility trees from all frames via Page.getFrameTree() +
per-frame Accessibility.getFullAXTree(frameId), so iframe elements
appear in snapshots with valid backendNodeIds. Pages without iframes
take the original single-call path with zero overhead.

Update snapshot tree builders to walk multiple RootWebArea roots from
merged multi-frame trees. Extract same-origin iframe content in the
markdown walker; show [iframe: url] placeholder for cross-origin.

* fix: namespace AX nodeIds by frameId to prevent cross-frame collisions

CDP AXNodeId values are frame-scoped — each frame's accessibility tree
starts its own counter from 1. Prefix nodeId and childIds with frameId
before merging so the nodeMap in snapshot builders never overwrites
nodes from a different frame.
2026-04-09 23:14:53 +05:30
Felarof
df7873562d Revert Kimi partnership UI, restore daily limit survey (#663)
* docs: add uBlock Origin install info to getting started and ad-blocking pages

Chrome dropped support for the full uBlock Origin extension — highlight
that BrowserOS brings it back and make it easy to install from both the
getting started guide and the dedicated ad-blocking page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: revert Kimi partnership UI, restore daily limit survey

Remove Kimi/Moonshot AI partnership branding from the rate limit
banner, provider card, provider templates, and LLM hub. Restore
the original survey CTA on daily limit errors. Moonshot AI remains
as a regular provider template without the "Recommended" badge.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address Greptile review comments

- Guard survey CTA with !isCreditsExhausted to avoid showing it for
  credits-exhausted users who already see "View Usage & Billing"
- Remove dead kimi-launch feature flag files (kimi-launch.ts,
  useKimiLaunch.ts)
- Remove unused KIMI_RATE_LIMIT analytics events
- Remove VITE_PUBLIC_KIMI_LAUNCH from env schema and .env.example

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 16:39:00 -07:00
shivammittal274
412386b489 fix: ensure custom model entry is always visible in model selector (#662)
The merged PR (#661) injected custom entries into filteredModels, but
cmdk auto-scrolls to its first selected CommandItem, pushing the custom
entry out of view. Fix by using forceMount on a separate CommandGroup
and resetting scroll to top on every keystroke via requestAnimationFrame.
2026-04-09 02:40:38 +05:30
shivammittal274
33617ba9e7 feat: show custom model ID as first option in model selector (#661)
* feat: show custom model ID as first option in model selector

When typing in the model dropdown, the user's exact input now appears as the
first selectable row, followed by fuzzy search suggestions. This makes entering
custom model IDs intuitive — previously the option was hidden behind a
zero-results-only Enter shortcut that fuzzy search almost always prevented.

* fix: correct is_custom_model flag and prevent duplicate analytics events

- Use modelInfoList check instead of hardcoding is_custom_model: true in
  the Enter key handler
- Add stopPropagation to prevent cmdk's root keydown handler from also
  firing onSelect, which caused duplicate MODEL_SELECTED_EVENT emissions
2026-04-09 01:44:17 +05:30
Nikhil
6712e1d321 chore: bump server and extension version (#659) browseros-server-v0.0.82 agent-extension-v0.0.99 2026-04-08 10:18:24 -07:00
Dani Akash
94540d9e87 chore(agent): remove workflows feature (#656) 2026-04-08 08:42:22 +05:30
Nikhil
bb62213e84 fix: install linux sysroot in configure, not via gclient hook (#653)
* fix: install linux sysroot in configure, not via gclient hook

`gn gen` was failing on the arm64 leg with `Missing sysroot
(//build/linux/debian_bullseye_arm64-sysroot)`. The previous design
relied on `git_setup` writing `target_cpus` to `.gclient` so that
`gclient sync`'s DEPS hook would download the cross-arch sysroot. That
chain breaks for any chromium_src that was synced before cross-arch
support landed (the hook is gated on .gclient state at sync time) and
for partial pipeline runs that skip git_setup entirely. Nothing in
configure declared or verified its sysroot precondition.

Make configure self-healing: on Linux, invoke
`build/linux/sysroot_scripts/install-sysroot.py --arch=<target>`
directly before `gn gen`. install-sysroot.py is idempotent (stamp file
+ SHA check), fast when already installed, and decoupled from .gclient
— it's exactly what the failing assertion's error message recommends.
The script accepts our arch names directly: `x64` translates to `amd64`
internally via ARCH_TRANSLATIONS, and `arm64` is a valid pass-through.

Also temporarily pin release.linux.yaml to x64 only while we validate
the sysroot bootstrap end-to-end. Flip back to `[x64, arm64]` once
arm64 is green.

* chore: pin release.linux.yaml to arm64-only for sysroot bootstrap test

x64 already builds cleanly — the failing leg is arm64 cross-compile from
an x64 host. Pin the config to arm64 to exercise the new
install-sysroot.py path in configure without burning time on x64.
Flip back to [x64, arm64] once arm64 is green.
2026-04-07 11:12:21 -07:00
Nikhil
dee3086a48 feat(server): cache klavis createStrata to unblock /chat hot path (#654)
* feat(server): cache klavis createStrata to unblock /chat hot path

Conversation creation in /chat was blocking on a Worker-proxied
klavisClient.createStrata round-trip every time the user had any
managed Klavis app connected. The 5s KLAVIS_TIMEOUT_MS in the
ai-worker proxy existed specifically to bound this latency, but
the same cap also caused user-visible 504s on /klavis/servers/remove
since Strata DELETE operations routinely take >5s. Without caching
we couldn't raise the timeout without regressing chat creation.

This adds an in-process cache for Strata createStrata responses,
keyed by (browserosId, hashed sorted-server-set) and gated by a 1h
TTL. The cache stores only immutable JSON metadata (strataServerUrl,
strataId, addedServers); per-session MCP clients continue to be
opened and disposed by AiSdkAgent exactly as before, which keeps
the cache concurrency-safe by construction.

Cache invalidation has two layers: (a) the cache key embeds the
server set, so adding/removing apps naturally produces a different
key; (b) POST /klavis/servers/add and DELETE /klavis/servers/remove
explicitly call invalidate(browserosId) after their underlying
Klavis API call succeeds, as defense-in-depth.

Other changes:
- Consolidates klavis-related services into a new
  apps/server/src/api/services/klavis/ directory; moves
  register-klavis-mcp.ts -> strata-proxy.ts and adds strata-cache.ts
  there. lib/clients/klavis/ stays unchanged.
- Refactors KlavisClient.removeServer into a low-level
  deleteServersFromStrata(strataId, servers) primitive. The
  cache-lookup + delete + invalidate orchestration moves up into
  routes/klavis.ts where it belongs, eliminating the lib->api
  layering inversion the original removeServer would have introduced.
- Uses Bun.hash (xxhash64) for fixed-width 16-hex-char keys, with
  serverKey verified on read to make collision risk strictly zero.
- Dedupes concurrent fetches via in-flight Promise sharing, with
  identity-checks before delete to avoid races between invalidate()
  and a racing replacement insert.

Follow-up (separate PR): bump KLAVIS_TIMEOUT_MS to 30000 in
ai-worker/wrangler.toml so /klavis/servers/remove stops 504-ing.

* fix: address greptile review comments for klavis strata cache

- Drop dead `invalidated` field on InflightEntry. It was added to
  support a "discard post-resolution if invalidated" check that I
  later replaced with identity-checked deletes during self-review,
  but I forgot to remove the field and the misleading comment
  referencing it. Simplify Map<string, InflightEntry> to plain
  Map<string, Promise<CacheEntry>>.
- Lower cache miss log from info to debug. Misses fire on every new
  conversation; matching the existing debug-level for hits.
- Stop routing the /klavis/servers/remove handler through
  klavisStrataCache.getOrFetch. The chat hot path keys its cache by
  the user's full enabled-server set (e.g. hash('Gmail,Linear')),
  so a single-server lookup here (hash('Gmail')) is guaranteed to
  miss, write a spurious entry, and then have it immediately
  cleared by invalidate() on the next line. Call createStrata
  directly to recover the strataId, mirroring the original
  removeServer flow.
2026-04-07 11:11:41 -07:00
Nikhil
8de2bf984f feat: build linux x64 + arm64 in a single invocation (#652)
`release.linux.yaml` now declares `architecture: [x64, arm64]` and the
runner loops the entire pipeline once per architecture. depot_tools
fetches both Linux sysroots automatically — `git_setup` idempotently
ensures `target_cpus = ['x64', 'arm64']` is in `.gclient` before
`gclient sync`, so cross-compiling arm64 from an x64 host just works.

The resolver returns `List[Context]` (single-element for the common
single-arch case), and `build/cli/build.py` loops `execute_pipeline` over
the per-arch contexts. Modules stay 100% arch-agnostic — no new
orchestration module, no new YAML schema beyond the list form.

Also fix a cross-compile bug in `build/modules/package/linux.py`: the
appimagetool binary must match the BUILD machine's arch (it executes
locally), not the target arch. Split into a host-keyed
`LINUX_HOST_APPIMAGETOOL` lookup vs the existing target-keyed
`LINUX_ARCHITECTURE_CONFIG`. Target arch is still passed to appimagetool
via the `ARCH` env var.

- build/common/resolver.py: scalar OR list `architecture` -> List[Context]
- build/cli/build.py: loop pipeline per arch, log multi-arch headers
- build/config/release.linux.yaml: `architecture: [x64, arm64]`
- build/modules/setup/git.py: idempotent `target_cpus` edit on Linux
- build/modules/package/linux.py: host vs target appimagetool split
- build/modules/package/linux_test.py: cover the host/target split
2026-04-06 13:08:06 -07:00
Nikhil
1b8720740c feat: add linux arm64 release support (#651)
* feat: support linux arm64 release artifacts

* fix: address PR review comments for 0406-linux_arm64_support
2026-04-06 10:20:38 -07:00
Nikhil
91be726381 refactor: remove --compile-only flag, consolidate into --ci (#646)
The --compile-only and --ci flags served overlapping purposes for CI
builds. Remove --compile-only entirely since --ci already handles the
CI use case (skip R2, skip prod env validation, local zip packaging)
and --no-upload covers the upload-skipping use case for full builds.
2026-04-03 14:58:52 -07:00
Nikhil
ff5386a24a fix: agent storage issue on update (#643)
* fix: agent storage erase issue fix

* fix: remove the guard against remote
2026-04-03 14:50:14 -07:00
Nikhil
a5f3c4da65 fix: skip windows exe patching in ci mode to avoid wine dependency (#645)
The server release CI workflow fails on ubuntu-latest because
patch-windows-exe.ts requires Wine to run rcedit. Thread the existing
--ci flag through compileServerBinaries so Windows PE metadata patching
is skipped in CI mode with a warning log.
browseros-server-v0.0.81
2026-04-03 14:46:33 -07:00
Nikhil
e5a852dd3d chore: update server version (#644) 2026-04-03 14:29:07 -07:00
Felarof
aee30ce8e1 Update README.md (#638) 2026-04-02 13:00:11 -07:00
Nikhil
0833c8d42d fix: windows app-data location fix (#637) 2026-04-02 08:53:04 -07:00
Nikhil
036c7f280b fix: tab-grouping cdp crash (#635)
* fix: tab group crash + history fix

* fix: tab group crash + history fix
2026-04-01 15:06:41 -07:00
Nikhil
000429277d fix: isolate server release packaging to ci mode (#629)
* fix: relax compile-only release env requirements

* refactor: add ci mode for server release builds
2026-03-31 20:57:44 -07:00
Nikhil
f8535fd96d fix: exclude eval framework from language stats via gitattributes (#630) 2026-03-31 20:44:06 -07:00
Nikhil
f0cbf77924 feat: add server release workflow (#627)
* feat: add server release workflow

* fix: address PR review comments for 0331-add_server_release_workflow

* refactor: rework 0331-add_server_release_workflow based on feedback

* refactor: rework 0331-add_server_release_workflow based on feedback
2026-03-31 17:37:06 -07:00
Nikhil
17be06eb2f fix: report release cli version correctly (#626) browseros-cli-v0.2.2 2026-03-31 16:17:57 -07:00
Nikhil
0e90785500 fix: accept port-only input in CLI init command (#625)
Users can now run `browseros-cli init 9000` in addition to the full URL.
Updated default example port from 9004 to 9000.
2026-03-31 16:16:30 -07:00
Nikhil
2bb432b0f2 feat: use hidden pages for scheduled tasks (#624)
* feat: use hidden pages for scheduled tasks

* refactor: rework 0331-use_hidden_pages_for_scheduled_tasks based on feedback
2026-03-31 16:02:47 -07:00
shivammittal274
565ce18eba feat: add npm/npx distribution for BrowserOS CLI (#618)
* feat(cli): skip self-update prompts for package manager installs

Checks BROWSEROS_INSTALL_METHOD env var (npm, brew) and skips automatic
update checks. Users should use their package manager's update mechanism.
FormatNotice now shows the appropriate upgrade command based on install method.

* feat(cli): add npm bin wrapper for browseros-cli

* feat(cli): add npm postinstall script to download platform binary

Downloads the correct platform binary from GitHub releases during npm
install, verifies SHA256 checksums, and extracts to .binary directory.

* feat(cli): add npm package metadata and README

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: move npm package files to correct monorepo path

The bin wrapper and postinstall were created at apps/cli/npm/ instead of
packages/browseros-agent/apps/cli/npm/. Moves them to the correct location.

* style: use node: protocol for builtin module imports

* feat(cli): add Makefile npm targets and release workflow npm publish step

Adds npm-version and npm-publish Makefile targets for version sync.
Adds Node.js setup and npm publish step to the release workflow.
Adds npm/npx install instructions to release notes template.

* fix(cli): fail on missing checksum entry and limit redirect depth

- Abort if checksums.txt downloaded but archive entry is missing
- Warn if checksums.txt itself failed to download
- Cap redirect depth at 5 to prevent stack overflow on circular redirects

* fix(cli): match install.sh checksum behavior — warn instead of abort

The existing shell installer (install.sh) warns and continues when the
checksum entry is missing from checksums.txt. Match that behavior in the
npm postinstall to avoid unnecessary install failures. Both files come
from the same GitHub release, so the checksum is a corruption check,
not a strong security boundary.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 22:30:58 +05:30
shivammittal274
81350c0d7f feat: replace model picker with shadcn Combobox + fuse.js fuzzy search (#617)
The model picker in NewProviderDialog rendered inline, causing dialog
resizing and lacked keyboard navigation. Replace it with a Popover +
Command (shadcn Combobox) pattern and add fuse.js for fuzzy search.

- Replace custom ModelPickerList with Popover + Command dropdown
- Add fuse.js for fuzzy model search (replaces string.includes)
- Add MODEL_SELECTED_EVENT and AI_PROVIDER_UPDATED_EVENT analytics
- Enrich PROVIDER_SELECTED_EVENT with model_id in chat sessions
2026-03-30 16:38:21 +05:30
Nikhil
9bdb2413ec feat: clean-up - remove obsolete controller extension (#610)
* refactor(server): remove obsolete controller extension backend

* fix: address review feedback for PR #610
2026-03-27 17:01:04 -07:00
Nikhil
ace9307878 feat: add browseros-cli self-updater (#605)
* feat: add browseros-cli self-updater

* fix: address review comments for 0327-cli_self_updater

* fix: address PR review comments for 0327-cli_self_updater

* fix: replace goreleaser with Makefile-based release build

Remove .goreleaser.yml (required Pro license for monorepo field) and
consolidate cross-compilation into `make release`. CI now uses the same
Makefile target, fixing a bug where POSTHOG_API_KEY was missing from
release ldflags.

* fix: address critical self-updater bugs from code review

- Fix SHA256 checksum mismatch: verify archive checksum before extraction
  instead of verifying extracted binary against archive hash (was always
  failing). Add VerifyChecksum() and integration test.
- Fix JSON field name mismatch: TypeScript was emitting camelCase
  (publishedAt, archiveFormat) but Go expected snake_case
  (published_at, archive_format). Manifest parsing was silently broken.
- Add decompression size limit (256 MB) to prevent zip/gzip bombs.
- Don't update LastCheckedAt on transient errors so retry happens on
  next CLI invocation instead of waiting 24h.
browseros-cli-v0.2.0
2026-03-27 14:52:54 -07:00
Nikhil
83a25ad301 fix: make SDK navigation tolerate unfocused startup tabs (#607) 2026-03-27 14:34:36 -07:00
github-actions[bot]
4b191a759c docs: update agent extension changelog for v0.0.98 (#609)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-27 14:34:02 -07:00
Nikhil
d02b3f74e6 chore: update agent version (#608) agent-extension-v0.0.98 2026-03-27 13:58:42 -07:00
Nikhil
86c62f14a5 chore: fix version number for extension (#606) 2026-03-27 13:18:10 -07:00
Nikhil
42c3e8fe01 fix: standardize release names to "BrowserOS <Product> - vX.Y.Z" format (#604)
Update workflow release titles for Extension, Agent SDK, and CLI to use
consistent branding. Existing GitHub releases also renamed via gh CLI.
2026-03-27 13:17:56 -07:00
Nikhil
517750e880 feat: add PostHog to CLI (#603)
* feat: add PostHog usage analytics to CLI

Add anonymous command-level analytics to browseros-cli using the PostHog
Go SDK. Tracks which commands are executed, their success/failure status,
and duration — no PII or person profiles.

- New analytics package with Init/Track/Close singleton
- Distinct ID resolves from server's browseros_id (server.json), falls
  back to CLI-generated UUID (~/.config/browseros-cli/install_id)
- API key injected at build time via ldflags (dev builds = silent no-op)
- Server now writes browseros_id into server.json for cross-surface
  identity correlation

* fix: address PR review feedback for #603

- Return "unknown" for unrecognized args in commandName to avoid
  sending arbitrary user input to PostHog
- Revert goreleaser to {{ .Env.POSTHOG_API_KEY }} (intentional hard
  fail — release builds must have the key set)
- go mod tidy to fix posthog-go direct/indirect marker
- Add POSTHOG_API_KEY to .env.production.example
2026-03-27 12:05:34 -07:00
Nikhil
6c053a5f29 feat: upload CLI binaries to CDN and gate release to core team (#602)
* feat: upload CLI binaries to CDN during release and gate workflow to core team

- Extend scripts/build/cli/upload.ts with uploadCliRelease() that pushes
  archives + checksums to R2 under versioned (cli/v{VERSION}/) and latest
  (cli/latest/) paths, plus a version.txt for lightweight latest resolution
- Update scripts/build/cli.ts entry point with --release/--version/--binaries-dir
  flags (existing no-args behavior preserved for upload:cli-installers)
- Rewrite install.sh and install.ps1 to fetch from cdn.browseros.com instead of
  GitHub releases API — eliminates rate limits and API dependency
- Add environment: release-core to release-cli.yml for core-team gating via
  GitHub environment protection rules
- Add Bun setup + CDN upload step to the workflow between build and GitHub release

* fix: address review feedback for PR #602

- Make loadProdEnv return empty map when .env.production is absent so
  pickEnv falls through to process.env in CI (Greptile P1)
- Add semver format validation for version string in install.sh and
  install.ps1 to guard against malformed CDN responses
- Pass inputs.version via env var instead of inline ${{ }} interpolation
  to prevent command injection in workflow shell
2026-03-27 11:47:31 -07:00
Nikhil
1c5ffdf878 fix: harden cli installer bootstrap (#601)
* fix: harden cli installer bootstrap

* refactor: rework 0327-harden_cli_installers based on feedback
2026-03-27 11:24:16 -07:00