You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Browse filesBrowse the repository at this point in the historyBrowse files
authored
feat(sensor): add opencode support and complete the platform matrix (#30)
* feat(sensor): add opencode support and complete the platform matrix
Brings the open-source Sensor up to date with the agents and operating systems
it now needs to cover. All changes are additive: no source key, session-id
format or event uuid changes, so existing detection pipelines are unaffected.
New source: opencode (github.com/sst/opencode)
Reads both storage backends — the current SQLite database (opencode.db, or
opencode-<channel>.db on non-stable channels, opened read-only) and the older
JSON file tree in both its project-scoped and legacy layouts. Honors
$XDG_DATA_HOME and $OPENCODE_DB. Tools are classified against the built-in
registry, so anything else with an underscore is recorded as an MCP tool with
its server_name split out.
Windows support for the parsers that were missing it
cursor ~/AppData/Roaming/Cursor/User/globalStorage/state.vscdb
cline ~/AppData/Roaming/Cursor/User/globalStorage/saoudrizwan.claude-dev/tasks
warp ~/AppData/Local/warp/Warp/data/warp.sqlite
desktop ~/AppData/Roaming/Claude/local-agent-mode-sessions
Each parser now resolves against an ordered candidate list instead of an
either/or pair. Warp also gains the sandboxed macOS group-container path
(~/Library/Group Containers/2BBY89MBSN.dev.warp/...), which is where the
database actually lives on current builds — it was previously unreachable.
Claude Desktop agent mode: Dispatch sessions
Delegated background agents are stored one level deeper, under
agent/local_ditto_<uuid>/, and were not discovered at all. They now surface
under the existing claude_desktop source with a claude_desktop_dispatch_
session-id prefix and an is_dispatch flag, so unattended runs can be scored
separately from interactive ones. Interactive session ids are unchanged.
Session context also picks up plugins, skills, claude_code_version, the
memory/skills/plugins toggles and the available slash commands.
Observer: ingest_all() iterates a SOURCES table and resolves each parser as
self.<source>_parser, replacing seven near-identical branches. Platform-only
sources are declared in PLATFORM_RESTRICTED_SOURCES and the CLI derives its
--source choices from SOURCES, so adding an agent touches neither.
Also: 44 new tests, a Python 3.9-3.13 CI matrix for the Sensor job (the package
already declared >=3.9 but only 3.12 was exercised), OS and Python classifiers
in pyproject, and docs for the new source, platform matrix, session_context and
environment variables.
* fix(sensor): resolve Windows app-data roots from the environment; test 3.10
Addresses review on #30.
%APPDATA% and %LOCALAPPDATA% point outside the user profile on roaming-profile
and redirected-folder setups, so the profile-relative AppData paths added for
Cursor, Cline, Warp and Claude Desktop would silently find nothing on exactly
the managed Windows fleets this sensor targets. The new
utils/platform_paths.py consults the environment first and keeps the
profile-relative location only as a fallback, matching how the parsers
already honor XDG_DATA_HOME / XDG_CACHE_HOME / OPENCODE_DB.
Adopts the env-first approach from #25 by @krishnesh1, and extends it beyond
Cursor/Cline to Warp (%LOCALAPPDATA%) and Claude Desktop. Closes the failure
mode reported in #21 by @Rahul-s-007.
Also adds Python 3.10 to the Sensor CI matrix so every version advertised in
the package classifiers is exercised, documents APPDATA/LOCALAPPDATA in the
Sensor README, and adds six tests covering env-set/unset/empty resolution
plus an end-to-end redirected-%APPDATA% discovery test.
Co-authored-by: krishnesh1 <krishnesh1@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* ci(sensor): report aggregate "Sensor tests" check for branch protection
Branch protection requires a status context named exactly "Sensor tests" -
the job name before it became a per-version matrix. The matrix legs report
as "Sensor tests (py3.X)", so the required context was never reported and
the PR sat at "Expected - Waiting for status to be reported" with every
real check green.
Add a gate job with the original name that needs the matrix and fails
unless every leg succeeded. Runs under if: always() because a skipped job
would otherwise satisfy the required check even when a leg fails.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: krishnesh1 <krishnesh1@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
0 commit comments