38 KiB
title, description
| title | description |
|---|---|
| Session API | Programmatic access to session data via the agentsview session CLI and REST endpoints |
The agentsview session command group is a stable, programmatic
surface for reading and writing session data. It is designed for
shell scripts, automation agents, and CI jobs that need structured
output rather than the web UI.
When an AgentsView daemon is running, the CLI proxies supported operations to it over HTTP. On a cold archive, read-only commands open local SQLite directly in read-only mode, while commands that need fresh data or need to write start or reuse the detached local daemon. This keeps one-off reads fast and keeps SQLite writes owned by one process.
Quick examples
# Search parsed message/tool content without scanning raw JSONL files.
agentsview session search "database timeout" --json --limit 10
# Recover recent context for one project, then fetch the first page
# of messages from a selected session.
agentsview session list --project myapp --limit 5 --json
agentsview session messages <session-id> --from 0 --limit 20 --json
# Query an already-running daemon explicitly.
agentsview session list --server http://127.0.0.1:8080 --json
# Read from configured PostgreSQL instead of local SQLite.
agentsview session search "regression" --pg --json
Stability
- Additive-only. New fields may appear at any time. Existing fields are never renamed or removed.
- Types are stable. A field that is a string stays a string.
- Unknown fields are safe to ignore. Well-behaved consumers tolerate forward-compatible additions.
HTTP and CLI share DTOs for bounded responses (same JSON object).
The CLI watch command emits NDJSON whose lines mirror the
underlying SSE events.
Transport
Detection uses kit daemon runtime records in AGENTSVIEW_DATA_DIR
and the daemon ping endpoint. Runtime records include service and
API metadata so incompatible or read-only daemons are not mistaken
for a writable local archive owner.
- If
--server <url>is set, supported commands proxy to that daemon over HTTP.--serverand--pgare mutually exclusive. The local configauth_tokenis not sent to explicit URLs; setAGENTSVIEW_SERVER_TOKENor pass--server-token-file <path>when that remote daemon requires auth. - If no explicit server is set and a local daemon is running, read and write commands proxy to it over HTTP.
- If a
pg servedaemon is running (read-only), read commands proxy to it butsession syncrefuses with a clear error. - If both a writable local daemon and a
pg servedaemon advertise the same data directory, the writable one wins so sync/write operations don't silently land on a read-only target. - If no daemon is running, read-only commands open the local archive directly in read-only mode.
- If a command requires fresh data or needs to write and no daemon
is running, the CLI starts
agentsview serve --background, waits for readiness, and proxies the operation to that daemon. - If
AGENTSVIEW_NO_DAEMON=1is set, the CLI never auto-starts a daemon. Read commands use direct read-only SQLite. Write commands run directly only after acquiring the per-data-dir write-owner lock. - If a writable daemon is known to own the local archive but is not reachable, write commands refuse instead of opening SQLite as a second writer. Read commands may still fall back to direct read-only SQLite.
session exportalways runs locally regardless of daemon state, and rejects--server,--pg, and--format/--jsonbecause it streams raw source bytes.
When a discovered local daemon requires auth (require_auth: true),
the CLI attaches Authorization: Bearer <token> using the
auth_token from the shared config. Explicit --server URLs are
different: they only receive a bearer token supplied with
AGENTSVIEW_SERVER_TOKEN or --server-token-file <path>, so a
local daemon token is not leaked to arbitrary remote URLs. Prefer
--server-token-file for long-running commands and shared hosts so
the token does not appear in process arguments.
--pg opens the configured PostgreSQL read store directly. It is
useful for automation running away from the UI server, but it is
read-only: session sync and session export reject it. If
AGENTSVIEW_PG_URL or [pg].url is configured, read commands still
use local SQLite unless --pg is supplied.
Common flags
| Flag | Description |
|---|---|
--format human|json |
Output format. Default human. |
--json |
Alias for --format json. |
--server <url> |
Explicit daemon URL for HTTP-backed operations. |
--server-token-file <path> |
Bearer token file for an explicit --server URL. |
--pg |
Read from configured PostgreSQL instead of SQLite. |
Shared metadata endpoints
The web UI and generated API clients use shared metadata endpoints for filter options:
GET /api/v1/projects
GET /api/v1/machines
GET /api/v1/branches
GET /api/v1/agents
GET /api/v1/branches returns distinct (project, branch) pairs
plus an opaque token field:
{
"branches": [
{
"project": "myapp",
"branch": "main",
"token": "..."
}
]
}
Pass the returned token back as the git_branch query parameter on
branch-aware endpoints. Treat it as opaque and URL-encode it in
manual HTTP calls. The token is scoped by both project and branch,
so app-a/main and app-b/main remain distinct, and an empty
branch remains distinct from a literal unknown branch.
Commands
agentsview session get
Return session metadata plus computed signal fields. Shape matches
GET /api/v1/sessions/{id}.
agentsview session get <id> [--format json]
{
"id": "abc-123",
"project": "myapp",
"machine": "workstation",
"agent": "claude",
"first_message": "...",
"display_name": "...",
"git_branch": "main",
"started_at": "2026-04-18T12:00:00Z",
"ended_at": "2026-04-18T13:00:00Z",
"message_count": 42,
"user_message_count": 7,
"health_score": 85,
"health_grade": "A",
"outcome": "completed",
"health_score_basis": ["..."],
"health_penalties": {"tool_retries": 5},
"parser_malformed_lines": 3,
"secret_leak_count": 0
}
health_score_basis and health_penalties are populated when
health_score is non-null. Both HTTP and CLI surfaces return them.
git_branch is the branch captured at sync time when the parser or
source metadata exposes it; sessions with no recorded branch omit
the field. parser_malformed_lines counts the malformed source
lines a parser skipped while still recovering the session and is
omitted when zero. Antigravity detail responses may also include
decode_confidence; the value low means the session came from an
unrecognized Antigravity schema fingerprint and was decoded
heuristically.
secret_leak_count (added in 0.30.0) counts definite-tier
findings from secret scanning and is stamped
inline during sync. Candidate-tier findings only show up after
an explicit agentsview secrets scan --backfill
and do not contribute to this count.
agentsview session list
Filtered session list. Response shape matches
GET /api/v1/sessions.
agentsview session list [flags]
{
"sessions": [ ... ],
"next_cursor": "...",
"total": 42
}
One-shot and automated sessions are excluded by default. When the first CLI
page hides any, session list writes an advisory to stderr with the hidden
count for each category and the --include-one-shot or --include-automated
flag that reveals it. Human and JSON stdout are unchanged, so redirecting or
piping structured output remains safe. The JSON total continues to describe
the filtered result, not the excluded sessions. Use the --include-* flags to
opt back in.
Date filters match a session when its activity window overlaps the selected date or range. Sessions that start before midnight and remain active after it therefore appear on both dates.
| Flag | HTTP param | Notes |
|---|---|---|
--project |
project |
string |
--exclude-project |
exclude_project |
string |
--machine |
machine |
string |
| — | git_branch |
opaque token from GET /api/v1/branches |
--agent |
agent |
string |
--date |
date |
YYYY-MM-DD |
--date-from |
date_from |
YYYY-MM-DD |
--date-to |
date_to |
YYYY-MM-DD |
--active-since |
active_since |
RFC3339 timestamp |
--since |
active_since |
Relative — Nh hours, Nd days, Nw weeks, Nm calendar months (not minutes), Ny years — or YYYY-MM-DD; resolved against now and mutually exclusive with --active-since |
--resume |
active_since |
CLI shortcut for sessions active in the last 15 minutes |
--active |
active_since |
Alias for --resume |
--min-messages |
min_messages |
int |
--max-messages |
max_messages |
int |
--min-user-messages |
min_user_messages |
int |
--include-one-shot |
include_one_shot |
bool |
--include-automated |
include_automated |
bool |
--include-children |
include_children |
bool |
--outcome |
outcome |
comma-separated |
--health-grade |
health_grade |
comma-separated |
--min-tool-failures |
min_tool_failures |
int; 0 is a meaningful filter |
--has-secret |
has_secret |
bool — only sessions with at least one definite secret finding |
--sort |
order_by |
comma-separated keys; optional :asc / :desc suffix per key |
--reverse, -r |
descending |
flips the default direction for unsuffixed sort keys |
--cursor |
cursor |
opaque string from prior response |
--limit |
limit |
int; default 200, max 500 |
Sort keys are recent, started, messages, user-messages,
output-tokens, peak-context, failures, retries,
edit-churn, compactions, context-pressure, health,
secrets, and id. recent defaults descending; the other keys
default ascending unless --reverse, descending=true, or an
explicit suffix overrides them.
Human CLI output is formatted for resuming work: it shows the full
session ID, age, agent, project, branch, message count, title, and
working directory, with a marker on sessions active in the last 15
minutes. --resume and --active set active_since to that
15-minute window unless --active-since is supplied explicitly.
HTTP callers should pass active_since directly.
Examples:
agentsview session list --resume
agentsview session list --sort messages:desc,started:asc
agentsview session list --sort health --reverse
agentsview session messages
Return a window of messages. Response shape matches
GET /api/v1/sessions/{id}/messages.
agentsview session messages <id> [--from N] [--limit N] [--direction asc|desc]
agentsview session messages <id> --around N [--before N] [--after N] [--role user,assistant]
--from is pointer-valued at the service layer: omitting it means
"start at the beginning" for ascending and "start at the newest
page" for descending; an explicit --from 0 means "start at ordinal
0" in both directions. --direction is validated to asc or desc.
Window and role flags (see Semantic Search for the cursor-follow workflow they support):
| Flag | HTTP param | Notes |
|---|---|---|
--around |
around |
Center a window on this ordinal; mutually exclusive with --from/--direction |
--before |
before |
Messages before the anchor (default 5); requires --around |
--after |
after |
Messages after the anchor (default 5); requires --around |
--role |
roles |
Comma-separated roles to include, e.g. user,assistant |
With a --role filter, --before/--after count filtered messages;
the anchor message is always included. Responses report the window's
first_ordinal/last_ordinal so callers can continue paging with
--from <last_ordinal + 1>.
{
"messages": [
{
"ordinal": 0,
"role": "user",
"content": "...",
"thinking_text": "",
"timestamp": "2026-04-18T12:00:00Z",
"is_system": false,
"source_type": "user",
"source_subtype": "",
"has_thinking": false,
"has_tool_use": false
}
],
"count": 1
}
thinking_text holds the concatenated text of any thinking blocks
the agent emitted, separated from the flattened content which
still contains inline [Thinking]...[/Thinking] markers for UI
rendering.
Promoted source_subtype values on is_system: true messages:
continuation, resume, interrupted, task_notification,
stop_hook, compact_boundary.
agentsview session tool-calls
Chronological flattened list of tool invocations.
agentsview session tool-calls <id>
{
"tool_calls": [
{
"ordinal": 3,
"timestamp": "2026-04-18T12:05:00Z",
"tool_use_id": "toolu_01abc...",
"tool_name": "Bash",
"category": "Bash",
"input_json": "{\"command\":\"ls\"}",
"skill_name": "",
"subagent_session_id": "",
"result_length": 128
}
],
"count": 1
}
input_json is a string — usually a serialized JSON object but may
be a plain string (e.g. "echo hello world" from Codex).
POST /api/v1/sessions/{id}/resume
Resume a local session in its native agent, or return the command that would be launched. This is an HTTP-only surface used by the web UI's resume menu.
POST /api/v1/sessions/{id}/resume
Request body:
{
"skip_permissions": false,
"fork_session": false,
"from_ordinal": 17,
"command_only": false,
"opener_id": ""
}
Response:
{
"launched": true,
"terminal": "Terminal",
"command": "cd /repo && claude --resume abc-123",
"cwd": "/repo"
}
command_only: true returns the command without launching a
terminal. When a launch is attempted but fails, the response still
includes the command with launched: false and an error code of
no_terminal_found or launch_failed. Read-only local mode can
still return commands, but remote sessions and read-only remote
serving cannot launch local programs.
For Claude Code sessions, setting fork_session: true without
from_ordinal appends Claude's native --fork-session flag to the
normal resume command. Setting both fork_session: true and
from_ordinal creates a message-point fork: AgentsView renders the
transcript through that message ordinal into a temporary prompt and
runs claude < prompt from the resolved session working directory.
Message-point forks are Claude-only, require fork_session, reject
opener_id, and return 404 when the ordinal is not present.
agentsview session export
Stream the raw session source file to stdout. This is a
local-only filesystem helper: the source file path is resolved
from the local SQLite archive, never from any daemon. Both
--server and --format/--json are rejected with an error — the
command also rejects --pg. It streams raw bytes, so
structured-output and remote-store flags don't apply.
agentsview session export <id>
Exit states:
| State | Behavior |
|---|---|
| Session in local archive, file on disk | Streams bytes verbatim |
| Session in local archive, file missing | Exit 1: error prefixed source file not found |
| Session in local archive, path empty | Exit 1: source file not found for session <id> |
| Session not in local archive | Exit 1: session not in local archive: <id> |
For a DB-derived export (HTML or markdown) use the HTTP endpoints
/api/v1/sessions/{id}/export or /api/v1/sessions/{id}/md.
Markdown export accepts an optional depth query parameter:
- omitted: root session only
depth=1: include direct child/subagent sessionsdepth=all: recurse through the child-session tree
Any other depth value is rejected.
agentsview session sync
Parse and insert a single session. Blocks until indexing and signal
computation complete. JSON output is the SessionDetail of the
synced session; human output is one line: synced: <id>.
agentsview session sync <path-or-id>
Argument resolution: if the argument is an existing filesystem path, it is treated as a raw JSONL file to parse. Otherwise it is treated as a session ID for re-parse.
With --server <url>, path-shaped arguments such as
/var/log/agent/session.jsonl or ./session.jsonl are sent to the
remote daemon as paths and resolved on that daemon host. Bare values
without path separators are treated as session IDs.
When a single JSONL maps to more than one session (for example a
Claude transcript with forked/resumed branches), session sync <path> refuses with an error that lists every candidate id. The
contract is "one session in, one SessionDetail back", so the CLI
never picks arbitrarily.
At that point the file has already been parsed and every candidate
session written to the local archive — the ambiguity check runs
after the sync engine finishes. Re-run session sync <id> with the
specific session you want; the <id> form resolves the file path
from the archive, so it only works for sessions already present
there.
session syncuses a writable local daemon when one is running, or starts a detached daemon when no compatible daemon is running. It then proxies toPOST /api/v1/sessions/syncso parsing and signal computation remain daemon-owned.- If a
pg servedaemon is running (read-only), sync refuses with a clear error. - If
AGENTSVIEW_NO_DAEMON=1is set, the CLI runs the sync in-process only after acquiring the local write-owner lock.
agentsview session watch
Stream NDJSON events as the session updates. Each line is a small object that wraps an SSE event.
agentsview session watch <id>
{"event":"session_updated","data":"abc-123"}
{"event":"heartbeat","data":"2026-04-18T12:05:00Z"}
Recognized event values today: session_updated, heartbeat.
New events may be added; consumers should ignore unknown events.
The command runs until interrupted (Ctrl+C) or the context is
cancelled. Like session export, it streams a fixed format and
rejects --format/--json.
Watch validates the session id before opening the stream. An
unknown id fails fast with a watch: session not found: <id>
error and non-zero exit instead of producing an indefinite
heartbeat stream — typos in automation scripts surface immediately.
When proxied to a daemon, the same condition surfaces as HTTP 404
at the transport layer before being translated to the CLI error.
agentsview session search
Substring, RE2 regex, or FTS5 search across message bodies,
tool inputs, and tool result content. Response shape matches
GET /api/v1/search/content.
agentsview session search <pattern> [flags]
{
"matches": [
{
"session_id": "abc-123",
"project": "myapp",
"ordinal": 17,
"ordinal_range": [12, 24],
"location": "tool_result",
"tool_name": "Bash",
"snippet": "...connecting to db with token ***REDACTED***..."
}
]
}
One-shot, automated, and subagent sessions are excluded by
default; opt back in with --include-one-shot,
--include-automated, or --include-children.
| Flag | HTTP param | Notes |
|---|---|---|
--regex |
mode=regex |
Treat pattern as an RE2 regex |
--fts |
mode=fts |
Tokenized FTS5 search; messages-only |
--semantic |
mode=semantic |
Vector search over user/assistant messages; messages-only — see Semantic Search |
--hybrid |
mode=hybrid |
Semantic + FTS reciprocal rank fusion; messages-only — see Semantic Search |
--scope |
scope |
top, all (default), or subordinate — semantic/hybrid only; supersedes include_children in those modes |
--context |
context |
int — N messages of context before/after each match (max 10) |
--in |
in |
Comma-separated: messages,tool_input,tool_result (default all) |
--exclude-system |
exclude_system |
Drop system messages from the scan |
--reveal |
reveal |
Show full secret values (localhost-only; warning to stderr) |
--project |
project |
string |
--exclude-project |
exclude_project |
string |
--machine |
machine |
string |
| — | git_branch |
opaque token from GET /api/v1/branches |
--agent |
agent |
string |
--date |
date |
YYYY-MM-DD |
--date-from |
date_from |
YYYY-MM-DD |
--date-to |
date_to |
YYYY-MM-DD |
--active-since |
active_since |
RFC3339 timestamp |
--since |
active_since |
Relative — Nh hours, Nd days, Nw weeks, Nm calendar months (not minutes), Ny years — or YYYY-MM-DD; resolved against now and mutually exclusive with --active-since |
--include-children |
include_children |
bool |
--include-automated |
include_automated |
bool |
--include-one-shot |
include_one_shot |
bool |
--limit |
limit |
int; default 50, max 500 |
--cursor |
cursor |
int — pagination cursor from a previous response |
--regex, --fts, --semantic, and --hybrid are mutually
exclusive. --fts is the fastest mode on large archives but only
searches message bodies; substring (the default) and regex modes
also walk tool_calls.input_json, tool_calls.result_content,
and the tool_result_events rows. --semantic and --hybrid
require an embedding index and return a single ranked page
(--cursor is rejected) — see Semantic Search
for setup, scoring, and limitations.
Every match, in every mode, carries the conversation-unit
citation described in
Hit shape:
ordinal_range — [start, end] of the conversation unit
containing the match, always present, [ordinal, ordinal] when
the match is its own unit — plus the lineage fields
subordinate, relationship, parent_session_id, and
is_sidechain. ordinal stays the anchor (the exact matched
message) in every mode. Only the lineage fields are omitempty:
a missing key unambiguously means top-level with no lineage,
while ordinal_range is never omitted, even at [0, 0].
score is the one field only --semantic/--hybrid emit.
--scope is rejected outside --semantic/--hybrid; in those
modes it supersedes --include-children, and
subagent/fork-typed or parent-linked sessions are exempt from
the default one-shot exclusion.
Snippets carry ~60 characters of context on each side of the
match, snapped to rune boundaries. Any substring that matches
the secret scanner rule set is masked unless
--reveal is passed. The same masking applies to the HTTP
endpoint when called from a remote origin — reveal=true is
only honored on a localhost-bound daemon.
agentsview session usage
Per-session token usage and cost estimate. Output shape is stable for the fields shown below; new fields may be added.
agentsview session usage <id> [--format json]
{
"session_id": "abc-123",
"agent": "claude",
"project": "myapp",
"total_output_tokens": 15230,
"peak_context_tokens": 84000,
"has_token_data": true,
"cost_usd": 2.41,
"has_cost": true,
"models": ["claude-opus-4-7"],
"unpriced_models": [],
"breakdown_count": 42,
"breakdown": [
{
"ordinal": 0,
"message_ordinal": 0,
"source": "message",
"label": "Prompt 1",
"timestamp": "2026-07-08T14:03:21Z",
"model": "claude-opus-4-7",
"input_tokens": 1200,
"output_tokens": 640,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 43000,
"cost_usd": 0.58,
"has_cost": true
}
],
"server_running": false
}
| Field | Notes |
|---|---|
total_output_tokens |
Sum of generated output tokens across the session |
peak_context_tokens |
Highest context-token count observed during the session |
has_token_data |
false when the session has no per-message token usage |
cost_usd |
Model-pricing estimate in USD; 0 when has_cost is false |
has_cost |
false if any contributing row is unpriced — never reports a partial total as complete |
models |
Models that contributed to the cost estimate, sorted by model name |
unpriced_models |
Omitted from JSON when empty; lists models seen but missing from pricing |
breakdown_count |
Number of per-step usage rows in the session; always populated |
breakdown |
Per-step usage rows, in session order; CLI JSON always includes them (added in 0.37.1) |
server_running |
true when the report came from an already-running daemon |
Each breakdown row carries the fields shown in the example:
| Row field | Notes |
|---|---|
ordinal |
Position of the row in the session's deduplicated usage stream |
message_ordinal |
Ordinal of the originating message; omitted when the row is not tied to one |
source |
message for per-message token usage; otherwise the usage-event source |
label |
Display label — Prompt N for message rows, Step N for other rows tied to a message, else the source name |
cost_usd |
Per-row estimate; 0 with has_cost: false when the model is unpriced |
Human output is a five-line summary:
Session: abc-123
Agent: claude
Output: 15230
Peak ctx: 84000
Cost: ~$2.41 (claude-opus-4-7)
The leading ~ on the cost line marks the figure as a
model-pricing estimate. When some contributing models are
unpriced, the cost line reads n/a (unpriced: model-x); when
the session has no token data at all, it reads n/a.
HTTP endpoint — as of 0.32.0, the same data is available over REST:
GET /api/v1/sessions/{id}/usage
The response uses the same JSON fields shown above and is
available from both local SQLite-backed agentsview serve and
read-only agentsview pg serve.
HTTP responses set server_running: true. As of 0.37.1, pass
?breakdown=true to include the per-step breakdown rows;
without it breakdown is [] while breakdown_count still
reports the row count. The CLI requests the breakdown on every
path (local, --server, and --pg), so its --format json
output always includes the rows. The session detail header uses
this endpoint to render its
per-step usage breakdown. Existing sessions
return 200 OK even when token or cost data is absent; inspect
has_token_data, has_cost, and unpriced_models to decide
how to present that state. Missing sessions return 404 with:
{
"error": {
"code": "session_not_found",
"message": "session not found"
}
}
Unexpected usage-query failures return 500 with
error.code = "usage_query_failed".
Exit codes — usage keeps the older token-use contract:
| Code | Meaning |
|---|---|
0 |
Token data or cost present and reported |
2 |
Session not found in the local archive |
3 |
Session exists but has neither token data nor cost |
The command uses a writable local daemon when one is running, or
starts a detached daemon when fresh local data is needed and no
compatible daemon is running. With AGENTSVIEW_NO_DAEMON=1, it
falls back to direct local SQLite after acquiring the write-owner
lock for any required refresh. Configured PostgreSQL does not
change this command's default local behavior; pass --pg to read
usage from the shared PostgreSQL store. With --server, it calls
GET /api/v1/sessions/{id}/usage on the explicit daemon. With
--pg, it reads usage from the shared PostgreSQL store.
Pricing comes from the same model_pricing table and
custom pricing overrides
that back agentsview usage daily. Replaces the older
agentsview token-use, which
remains as a deprecated alias.
Activity Report
The Activity report endpoint powers the top-level
Activity page and the agentsview activity report
CLI command. It returns one resolved range with concurrency buckets,
summary totals, breakdowns, and contributing sessions.
GET /api/v1/activity/report
Activity includes one-shot sessions by default. Automated sessions
are also included by default and can be filtered with the
automation query parameter.
The JSON response shares the same schema_version, pricing, and projects
metadata contract as agentsview activity report --json.
| Query param | Notes |
|---|---|
preset |
day, week, month, or custom |
date |
Anchor date for day/week/month presets (YYYY-MM-DD) |
from |
Custom range start, RFC3339 |
to |
Custom range end, RFC3339 |
timezone |
IANA timezone name; default UTC |
bucket |
Optional bucket override: 5m, 15m, 1h, 1d, or 1w |
project |
Filter by project |
git_branch |
Filter by opaque branch token from GET /api/v1/branches |
agent |
Filter by agent |
machine |
Filter by machine |
automation |
all, interactive, or automated; default all |
Response excerpt:
{
"schema_version": 1,
"pricing": {
"source": "fetched",
"table_version": "litellm-398a0b15378c",
"latest_row_updated_at": "2026-06-20T18:40:00Z",
"custom_override_count": 0,
"effective_row_count": 2428,
"digest": "sha256:8d815a1737bce68fa1a19ba977bf33c8c8efcc74deb954fcf62ce80e46e75f2c",
"cost_source": "mixed",
"fallback": {
"used": false,
"models": []
},
"models": {
"gpt-5.4": {
"matched_pattern": "gpt-5.4",
"input_cost_per_mtok": 2,
"output_cost_per_mtok": 8,
"cache_write_cost_per_mtok": 3,
"cache_read_cost_per_mtok": 0.5,
"cost_source": "computed"
}
}
},
"projects": {
"agentsview": {
"resolution": "resolved",
"identity": {
"key": "sha256:97879729c8ab311e9d4b28941e3a04830b28c527f00af53f2270212eccdbbd39",
"key_source": "git_remote",
"normalized_remote": "github.com/acme/agentsview"
}
}
},
"timezone": "America/Chicago",
"range_start": "2026-06-20T05:00:00Z",
"range_end": "2026-06-21T05:00:00Z",
"bucket_unit": "hour",
"bucket_seconds": 3600,
"partial": true,
"as_of": "2026-06-20T18:40:00Z",
"peak": {"agents": 4, "at": "2026-06-20T15:00:00Z"},
"totals": {
"active_minutes": 210.5,
"agent_minutes": 346.2,
"sessions": 18,
"untimed_sessions": 1,
"distinct_projects": 5,
"distinct_models": 4,
"output_tokens": 84231,
"cost": 12.34,
"automated_sessions": 3,
"interactive_sessions": 15
},
"buckets": [
{
"start": "2026-06-20T15:00:00Z",
"end": "2026-06-20T16:00:00Z",
"max_agents": 4,
"agent_minutes": 52.0,
"output_tokens": 12000,
"cost": 1.87,
"automated_at_peak": 1,
"interactive_at_peak": 3
}
],
"by_project": [{"key": "agentsview", "agent_minutes": 96.4, "cost": 4.20}],
"by_model": [{"key": "claude-sonnet-4-6", "agent_minutes": 80.0, "cost": 3.10}],
"by_agent": [{"key": "codex", "agent_minutes": 64.0, "cost": 2.85}],
"by_session": [
{
"session_id": "codex:abc",
"title": "Update docs",
"project": "agentsview",
"agent": "codex",
"primary_model": "gpt-5.4",
"models": ["gpt-5.4"],
"agent_minutes": 24.5,
"cost": 1.12,
"output_tokens": 9200,
"first_active": "2026-06-20T15:04:00Z",
"last_active": "2026-06-20T15:38:00Z",
"timing_quality": "timed",
"is_automated": false
}
],
"intervals": [
{
"session_id": "codex:abc",
"start": "2026-06-20T15:04:00Z",
"end": "2026-06-20T15:38:00Z"
}
]
}
Breakdown rows include total, automated, and interactive minutes and
costs. Session rows with no reliable timestamped activity use
"timing_quality": "untimed" and agent_minutes: null; they can
still contribute cost and output tokens when usage rows exist.
Secret Scanning
As of 0.30.0, AgentsView scans session content for credentials during sync and exposes findings through CLI, HTTP, and per- session metadata. Two confidence tiers exist:
| Tier | Rules | When scanned |
|---|---|---|
| Definite | Well-anchored vendor formats: AWS access keys, Anthropic sk-ant-…, OpenAI sk-proj-/sk-svcacct-/sk-admin-, GitHub ghp_… and github_pat_…, GitLab glpat-…, Slack xoxb/xoxa/xoxp/xoxr/xoxs, Stripe sk_live_… and rk_live_…, Google AIza…, npm npm_…, PyPI pypi-…, Hugging Face hf_…, SendGrid SG.…, PEM private-key blocks |
Inline during sync |
| Candidate | FP-prone heuristics: basic-auth URLs, JWTs, high-entropy assignments | Only when agentsview secrets scan runs explicitly |
Findings are written to a secret_findings table keyed by
session ID, with the rule name, confidence, location
(message / tool_input / tool_result / tool_result_event),
match coordinates, and a redacted_match value (the raw
secret is never stored). Each session also carries a
secret_leak_count and a secrets_rules_version so a future
ruleset bump can drive an incremental backfill.
HTTP API
GET /api/v1/secrets
POST /api/v1/secrets/scan
GET /api/v1/search/content (when called with text that matches a secret rule, snippets are masked)
GET /api/v1/secrets accepts: project, agent, date_from,
date_to, rule, confidence (definite / candidate /
all, default definite), reveal, limit, cursor.
reveal=true is only honored on a localhost-bound daemon —
remote callers that request reveal receive HTTP 403.
POST /api/v1/secrets/scan streams progress with
Server-Sent Events and accepts backfill, project, agent,
date_from, and date_to. It is only available from a
writable local daemon.
Listing sessions with findings
agentsview session list --has-secret (or has_secret=true on
GET /api/v1/sessions) returns only sessions with at least one
definite finding. The candidate tier does not contribute to
secret_leak_count and so does not surface through this filter.
CLI
The agentsview secrets command
group wraps the scan and list operations. The fast path is:
# Re-scan the archive with the full ruleset (definite + candidate)
agentsview secrets scan
# List definite findings (redacted; localhost-only --reveal for raw values)
agentsview secrets list
agentsview secrets list --reveal
PostgreSQL parity
When PostgreSQL sync is enabled, the
secret_findings table, the session-level secret_leak_count,
and the --has-secret filter all mirror to the shared
database. Substring and regex content search work the same way
against pg serve, with the same masking and --reveal
constraints.