ActionView.Cli
0.17.0
See the version list below for details.
dotnet tool install --global ActionView.Cli --version 0.17.0
dotnet new tool-manifest
dotnet tool install --local ActionView.Cli --version 0.17.0
#tool dotnet:?package=ActionView.Cli&version=0.17.0
nuke :add-package ActionView.Cli --version 0.17.0
ActionView
ActionView is a review queue and action dashboard for DevOps and engineering workflows. External tools -- CI/CD pipelines, incident analyzers, GitHub bots, or any custom automation -- drop structured JSON entries into an inbox directory. ActionView picks them up, displays them in a real-time web dashboard, and lets you take actions (approve deploys, review PRs, acknowledge incidents) directly from the UI or the command line.
How It Works
External Tool ActionView You
───────────── ────────── ───
CI pipeline ─┐
GitHub bot ─┼─► inbox/ ─► active/ ─► Web Dashboard ─► Click "Approve"
Alerting ─┘ (watch) or CLI ─► archive/
- An external system writes a JSON file into the
inbox/directory. - ActionView's file watcher picks it up, validates it, and moves it to
active/. - The entry appears in the dashboard (pushed via SignalR) and/or the CLI.
- You review the content and trigger an action (HTTP call, CLI command, or dismiss).
- The entry moves to
archive/with an outcome record, or is deleted.
Invalid files are moved to errors/ with a companion .error.txt explaining the failure.
Installation
Prerequisites
- .NET 10 SDK
- Node.js (for the web dashboard)
Install as Global Tools
# Build the NuGet packages
dotnet pack src/ActionView.Cli -c Release
dotnet pack src/ActionView.Api -c Release
dotnet pack src/ActionView.Mcp -c Release
# Install the CLI
dotnet tool install --global --add-source ./artifacts ActionView.Cli
# Install the web server
dotnet tool install --global --add-source ./artifacts ActionView.Api
# Install the MCP server
dotnet tool install --global --add-source ./artifacts ActionView.Mcp
Build From Source
dotnet build src/ActionView.slnx
Run Tests
dotnet test src/ActionView.Tests
Usage
Web Dashboard
Start the server:
# As a global tool
actionview-server --config path/to/actionview.json
# From source (development mode — auto-launches Vite with hot reload)
dotnet run --project src/ActionView.Api
The dashboard is served at http://localhost:5000. In development mode, Vite runs on port 5173 and is reverse-proxied automatically.
The dashboard provides:
- Active view -- all pending entries, ordered by pinned → priority → severity → date (or a sort field/direction you choose), with real-time updates via SignalR.
- Saved views -- named filter presets (by tag and/or type) that split the feed into lanes such as Work and Personal. Configure them in
actionview.jsonor manage them from the UI (add, rename, change icon/tags, reorder, delete); each pill shows a live count, and an always-present All view shows everything. - Filtering & sort -- filter by type, severity, source, tags (with Any/All matching), and free-text search; sort by created/priority/severity/title, ascending or descending. Tags appear on each row and are click-to-filter.
- History view -- archived entries with outcomes, the same saved views / filters / sort, and a paginated Load more.
- Detail panel -- rendered content blocks (markdown, code with syntax highlighting, tables, JSON, key-value pairs, alerts, links) and action buttons.
- Live indicators -- connection status, unread badges.
CLI
actionview [command] [options] --config path/to/actionview.json
| Command | Description |
|---|---|
add [-f <file>] [-j <json>] |
Add a JSON entry to the inbox (accepts file, inline JSON, or stdin) |
list [--type] [--severity] [--source] [--search] [--tags] [--tag-mode any\|all] [--sort created\|priority\|severity\|title] [--dir asc\|desc] [--view <id\|name>] |
List active entries in a table |
dismiss <id> |
Archive an entry (supports partial ID matching) |
delete <id> [-f\|--force] |
Permanently delete an entry |
pin <id> |
Toggle pin on an active entry |
stats |
Show counts by type, severity, and directory |
schema |
Print the entry JSON schema to stdout |
template list |
List all registered templates |
template show <type> |
Show a template's full definition |
template register [-f <file>] [-j <json>] |
Register a new entry type template |
template remove <type> |
Remove a registered template |
MCP Server
ActionView includes an MCP (Model Context Protocol) server that exposes the review queue to AI agents. It runs as a separate binary over stdio transport.
Running the MCP server
# As a .NET tool
actionview-mcp [--read-only] [--config path/to/actionview.json]
# Via dnx (no install required, .NET 10+)
dnx ActionView.Mcp [--read-only]
# From source
dotnet run --project src/ActionView.Mcp -- --read-only
MCP client configuration
Add to your MCP client configuration (e.g., Claude Desktop, OpenCode, etc.):
{
"mcpServers": {
"actionview": {
"command": "actionview-mcp",
"args": ["--read-only", "--config", "/path/to/actionview.json"]
}
}
}
Or with dnx (no prior install needed):
{
"mcpServers": {
"actionview": {
"command": "dnx",
"args": ["ActionView.Mcp", "--", "--read-only"]
}
}
}
Available MCP tools
| Tool | Mode | Description |
|---|---|---|
list_entries |
read | List active entries with optional filters (type, severity, source, tags, tagMode any/all, search, view) and sort (sort, dir) |
get_entry |
read | Get a single entry by ID (supports partial ID match) |
list_templates |
read | List all registered templates |
get_template |
read | Get a template's full definition |
get_stats |
read | Get dashboard statistics |
get_schema |
read | Get the entry JSON schema |
add_entry |
write | Add a new entry to the review queue |
dismiss_entry |
write | Dismiss/archive an active entry |
delete_entry |
write | Permanently delete an active entry |
pin_entry |
write | Toggle pin on an active entry |
register_template |
write | Register or update a template |
remove_template |
write | Remove a registered template |
The --read-only flag restricts the server to read-mode tools only (plus add_entry is excluded). Write tools are only available when --read-only is not set.
Adding Entries
Any tool that can write a JSON file can create entries. Drop a .json file into the inbox directory:
# Copy a sample entry into the inbox
cp samples/pr-review.json data/inbox/
# Or use the CLI with a file
actionview add -f samples/deploy-approval.json
# Or pass inline JSON
actionview add -j '{"type":"alert","source":"monitoring","title":"Disk full on db-1"}'
The add command (and template register) also accepts JSON from stdin. If no --file or --json flag is given and input is piped, stdin is read automatically:
# Pipe from another command
cat entry.json | actionview add
curl -s https://api.example.com/pending-review | actionview add
# Explicit stdin via --file -
actionview add --file - < entry.json
This makes it easy to integrate ActionView into shell pipelines and scripts.
REST API
The server exposes these endpoints:
| Method | Path | Description |
|---|---|---|
GET |
/api/entries |
List active entries (query: type, severity, source, tags, tagMode, search, sort, dir) |
GET |
/api/entries/{id} |
Get entry detail (marks as viewed) |
POST |
/api/entries/{id}/actions/{actionIndex} |
Execute an entry action |
POST |
/api/entries/{entryId}/sections/{sectionIndex}/actions/{actionIndex} |
Execute a section action |
POST |
/api/entries/{id}/dismiss |
Dismiss (archive) an entry |
DELETE |
/api/entries/{id} |
Permanently delete an entry |
GET |
/api/history |
List archived entries (query: type, severity, source, tags, tagMode, search, sort, dir, limit, offset) |
GET |
/api/history/{id} |
Get archived entry detail |
GET |
/api/stats |
Dashboard statistics |
GET |
/api/views |
List saved views |
PUT |
/api/views |
Replace the saved views and persist them back to actionview.json |
GET |
/api/views/counts |
Active-entry counts per view (drives the pill badges) |
GET |
/api/config |
Client-facing config slice (e.g. the default tagMatchMode) |
GET |
/api/files?path={path} |
Serve a local file referenced by an entry. Gated by fileAccess.allowedRoots in actionview.json. |
GET |
/api/entries/{id}/export?format={md\|html\|json} |
Export an entry (active or archived) as Markdown, HTML, or raw JSON for archiving / printing. |
A SignalR hub is available at /hubs/entries and broadcasts EntriesAdded, EntryUpdated, EntryArchived, and EntryDeleted events.
Configuration
ActionView is configured via a actionview.json file:
{
"dataDirectory": "data",
"tagMatchMode": "any",
"views": [
{ "id": "work", "name": "Work", "icon": "briefcase", "tags": ["work"] },
{ "id": "personal", "name": "Personal", "icon": "user", "tags": ["personal"] },
{ "id": "deploys", "name": "Deploys", "icon": "rocket", "type": "deploy" }
],
"notifications": {
"enabled": false
},
"secrets": {
"CI_TOKEN": "env:CI_API_TOKEN",
"JIRA_TOKEN": "my-literal-token"
},
"fileAccess": {
"allowedRoots": ["C:/temp/Zakira.Replay"],
"maxFileSizeBytes": 20971520
}
}
Fields
| Field | Type | Default | Description |
|---|---|---|---|
dataDirectory |
string | ~/.actionview/ |
Root directory containing inbox/, active/, archive/, and errors/ subdirectories. Relative paths are resolved against the config file location. |
tagMatchMode |
"any" | "all" |
any |
Default combine mode for multi-tag filters: any (OR) or all (AND). A per-view tagMatch and the dashboard's Any/All toggle override it. |
views |
object[] | [] |
Saved filter presets ("views"). Each: id, name, optional icon (Lucide name), type, tags (string[]), and tagMatch (any/all). Editable from the dashboard, which persists changes back to this file. The built-in All view is always present and not stored here. |
notifications.enabled |
bool | true |
Enable Windows toast notifications when new entries arrive. |
secrets |
object | {} |
Key-value map of secrets used in action command placeholders. |
fileAccess.allowedRoots |
string[] | [] |
Absolute (or config-relative) directory paths whose contents /api/files is allowed to serve. Required for file:// image URLs in entries to load. Empty = no local files served. |
fileAccess.maxFileSizeBytes |
int | 20971520 (20 MiB) |
Maximum file size returned by /api/files. Larger files return HTTP 413. |
Config File Resolution
The config file is resolved in this order (first match wins):
--configCLI argumentACTIONVIEW_CONFIGenvironment variableActionView:ConfigPathinappsettings.json./actionview.jsonin the current directory
Secrets
Secrets are referenced in action commands using {{PLACEHOLDER}} syntax. They appear in HTTP URLs, headers, request bodies, and CLI arguments.
A secret value can be:
- A literal string -- used as-is.
- An environment variable reference -- prefixed with
env:, e.g."env:CI_API_TOKEN"reads theCI_API_TOKENenvironment variable at runtime.
If a placeholder is not found in the secrets map, ActionView falls back to looking up the placeholder name directly as an environment variable. Unresolved placeholders are left in place.
{
"secrets": {
"CI_TOKEN": "env:CI_API_TOKEN",
"SLACK_WEBHOOK": "https://hooks.slack.com/services/T00/B00/xxx"
}
}
Then in an action command:
{
"command": {
"type": "http",
"method": "POST",
"url": "https://api.example.com/deploy",
"headers": {
"Authorization": "Bearer {{CI_TOKEN}}"
}
}
}
Entry Format
Entries are JSON files conforming to the entry schema. You can print the schema with actionview schema.
Minimal Entry
{
"type": "alert",
"source": "monitoring",
"title": "CPU usage above 90% on prod-web-3"
}
Full Entry Structure
{
"schemaVersion": "1",
"type": "pr-review",
"source": "github-orchestrator",
"title": "PR #482: Add user preference caching layer",
"subtitle": "repo: acme/backend",
"severity": "medium",
"icon": "git-pull-request",
"tags": ["backend", "performance"],
"content": [ ],
"actions": [ ]
}
| Field | Required | Description |
|---|---|---|
type |
yes | Category string (e.g. pr-review, deploy, incident) |
source |
yes | Identifies the tool that created the entry |
title |
yes | Primary display text |
schemaVersion |
no | Must be "1" if present |
subtitle |
no | Secondary display text |
severity |
no | low, medium (default), high, or critical |
icon |
no | Lucide icon name |
tags |
no | Array of string labels |
content |
no | Ordered list of content blocks to render |
actions |
no | List of action buttons |
Content Blocks
The content array accepts these block types:
| Type | Description | Key Fields |
|---|---|---|
markdown |
GFM markdown with math (KaTeX), task lists, footnotes; embedded images render as click-to-enlarge thumbnails | body |
code |
Syntax-highlighted code with copy button, wrap/line-no toggles, and inline per-line annotations | body, language, filename, highlight, annotations |
diff |
Real unified/split diff view with add/remove gutters and per-hunk collapse | body (unified diff), oldFilename, newFilename, mode |
json |
Foldable, syntax-colored JSON tree with copy button | body |
table |
Sortable, filterable table with rich cells (link/status/badge/code/copy/markdown/image) | columns, rows, sortable, filterable |
keyValue |
Key-value grid with the same rich-cell value types as tables | pairs |
link |
One or many external links with optional description body and icon | url / links[], body, icon |
image |
Thumbnail with click-to-enlarge lightbox; supports annotations + timestamp links | url, alt, caption, maxWidth, imageAnnotations, timestampUrl |
gallery |
Grid of images sharing one lightbox carousel with prev/next + zoom | images[] |
video |
YouTube / Vimeo / file video with optional clipping and chapter list | url, provider, videoId, startTime, endTime, chapters |
file |
Downloadable attachment via /api/files (gated by fileAccess.allowedRoots) |
url, filename, fileSize, mimeType |
timeline |
Vertical timeline of dated events (level + icon + markdown body per event) | events[] |
tabs |
Tab strip; each tab carries its own content[] of nested blocks |
tabs[] |
stat |
Big-number stat with optional delta indicator and sparkline | value, delta, trend, unit, sparkline |
chart |
Line / bar / area / pie chart for monitoring snapshots | chartType, series, xAxis |
diagram |
Mermaid diagram (flowcharts, sequence, gantt) | body (Mermaid source) |
beforeAfter |
Image slider revealing before/after via a draggable handle | beforeUrl, afterUrl, beforeLabel, afterLabel |
section |
Collapsible group (default-collapsed + badge) with nested blocks | title, content, actions, defaultCollapsed, badge |
alert |
Colored banner with markdown body, optional dismiss, and inline actions | body, level, dismissible, actions |
divider |
Horizontal rule | (no fields) |
Actions
Actions define buttons that execute commands when clicked:
{
"label": "Approve Deploy",
"style": "success",
"confirmMessage": "Are you sure you want to approve this deployment?",
"command": {
"type": "http",
"method": "POST",
"url": "https://ci.example.com/api/deploy/{{DEPLOY_ID}}/approve",
"headers": {
"Authorization": "Bearer {{CI_TOKEN}}"
},
"body": "{\"approved_by\": \"actionview\"}"
},
"onSuccess": "archive"
}
| Field | Description |
|---|---|
label |
Button text |
style |
default, primary, success, or danger |
confirmMessage |
If set, a confirmation dialog (or form heading) is shown before execution |
command.type |
http or cli |
parameters |
Optional list of inputs the user supplies before the action runs (see below) |
onSuccess |
What to do after successful execution: archive, keep, or delete |
HTTP commands support method, url, headers, and body. All string values support {{VAR}} (secrets/env) and {{param.NAME}} (runtime user input) placeholder substitution.
CLI commands support program, args (string array), and workingDirectory.
Actions can also be placed inside section blocks to scope them to a specific part of the entry.
Parameterized Actions
Some actions need user input — for example, posting a PR review comment whose draft was written by an AI but should be editable before sending. Declare the inputs as parameters:
{
"label": "Post Comment",
"style": "primary",
"parameters": [
{
"name": "body",
"label": "Comment",
"type": "multiline",
"default": "Consider making CacheTTL configurable...",
"required": true,
"helpText": "Edit before posting."
}
],
"command": {
"type": "http",
"method": "POST",
"url": "https://api.github.com/repos/acme/backend/pulls/482/comments",
"headers": { "Authorization": "Bearer {{GITHUB_TOKEN}}" },
"body": { "body": "{{param.body}}" }
},
"onSuccess": "keep"
}
When parameters is present the UI expands an inline form under the button (textarea, select, number, boolean, or single-line text). The user's input is substituted into the command via {{param.NAME}} placeholders.
| Parameter field | Description |
|---|---|
name |
Identifier used as {{param.NAME}}. Must match [A-Za-z_][A-Za-z0-9_]*. |
label |
Field label shown in the form. |
type |
text, multiline, select, number, or boolean. Defaults to text. |
default |
Initial value (e.g. an AI's draft). For numeric/boolean fields the string is parsed. |
options |
Allowed values when type is select. |
required |
If true, a non-empty value must be supplied before execution. |
placeholder |
Placeholder text inside the input. |
helpText |
Help text shown beneath the input. |
Substitution rules:
{{param.NAME}}is resolved before{{SECRET}}so user input cannot collide with secret names.- Inside a JSON
body, substitution happens at the string-leaf level — special characters in user input (quotes, backslashes, newlines) are JSON-escaped automatically and cannot break the payload. - Drafts are persisted to
localStorageperentry+action, so a SignalR refresh while you're editing won't wipe your work.
Data Directory Layout
data/
inbox/ # Drop zone for new entry files
active/ # Validated entries currently shown in the dashboard
archive/ # Completed or dismissed entries with outcome metadata
errors/ # Invalid entries with .error.txt companion files
Samples
The samples/ directory contains example entries demonstrating different use cases:
- deploy-approval.json -- production deployment approval workflow with pre-deployment checks
- incident-rca.json -- incident root cause analysis review with config diffs and action items
- pr-review.json -- pull request review with code blocks, AI analysis, and review actions
Try them out:
cp samples/deploy-approval.json data/inbox/
Project Structure
actionview.json # Configuration
schemas/
entry.v1.schema.json # Entry JSON schema
samples/ # Example entry files
src/
ActionView.slnx # .NET solution file
ActionView.Core/ # Shared models and services
ActionView.Cli/ # CLI tool (actionview)
ActionView.Api/ # Web server (actionview-server)
ActionView.Mcp/ # MCP server (actionview-mcp)
ActionView.Tests/ # Test suite
client/ # React + TypeScript dashboard (Vite)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.17.1 | 100 | 6/16/2026 |
| 0.17.0 | 104 | 6/15/2026 |
| 0.16.2 | 104 | 6/7/2026 |
| 0.16.1 | 103 | 6/7/2026 |
| 0.16.0 | 95 | 6/7/2026 |
| 0.15.1 | 94 | 6/7/2026 |
| 0.15.0 | 99 | 6/7/2026 |
| 0.14.0 | 107 | 5/16/2026 |
| 0.13.0 | 107 | 5/12/2026 |
| 0.12.0 | 127 | 5/8/2026 |
| 0.11.0 | 121 | 4/24/2026 |
| 0.10.0 | 114 | 4/22/2026 |
| 0.9.0 | 110 | 4/19/2026 |
| 0.8.0 | 110 | 4/17/2026 |
| 0.7.0 | 108 | 4/14/2026 |
| 0.6.0 | 114 | 4/14/2026 |
| 0.5.0 | 110 | 4/14/2026 |
| 0.3.0 | 123 | 4/11/2026 |
| 0.2.0 | 119 | 4/4/2026 |
| 0.1.9 | 112 | 4/4/2026 |