Platform Specification
The CLI
One CLI for both agents and humans. Designed so agents can work fluently and humans can set things up, observe, and intervene without friction. Every detail rethought from first principles.
Design Principles
Why the CLI works the way it does
One CLI, two audiences
Agents and humans use the same oc command. Agents use it to act, check permissions, store memories. Humans use it to connect integrations, manage trust, observe sessions, and approve requests. Same tool, different verbs.
Short commands, deep capabilities
Most commands are one or two words. oc do, oc find, oc can, oc recall. Every token an agent types costs compute. The CLI respects that.
Permissions are integrated, not separate
When an agent runs oc do, the permission check happens automatically. If approval is needed, the agent waits inline. No separate "check then act" workflow unless the agent wants one.
Trust grows, friction decreases
The first session requires explicit permissions. Over time, permissions accumulate and modes upgrade from approve to auto as trust is earned. The agent works with less interruption. The system gets out of the way.
# In a hosted session, oc is pre-installed and authenticated. # For local use: curl -fsSL https://opencompany.dev/install.sh | sh oc login # Opens browser for OAuth # Or with a token export OC_TOKEN="oc_live_..." # All commands support --json for machine-readable output.
The Permission Model
The core of how trust works between humans and agents
The syntax
Every permission follows one pattern:
Read it as: "on [namespace], [verb] the [resource]." The verb comes before the resource because it follows natural English order and because resources are hierarchical paths — placing them last means wildcards read cleanly from left to right.
Grammar rules:
- • Separators:
:separates namespace, verb, and resource./separates hierarchy within resources. - • Actions (what you invoke) are
namespace:verb— e.g.github:merge,slack:send - • Permissions (what you hold) are
namespace:verb:resource— e.g.github:merge:acme/api/pulls/456 - • Resource paths use
/for hierarchy:org/repo/type/instance - • Wildcards:
*matches any single segment. Applied to verb or any resource segment. - • Mode: Every permission is granted with a mode —
auto(just do it) orapprove(ask the human first). Mode is part of the grant, not a separate policy.
# Specific github:read:acme/api/pulls/456 # read one PR slack:send:#engineering # send to one channel stripe:read:charges/ch_abc123 # read one charge # Wildcards on resource (most common) github:read:acme/api/* # read anything in a repo github:read:acme/* # read anything in an org slack:send:* # send to any channel stripe:read:* # read any Stripe resource # Wildcards on verb github:*:acme/api/pulls/456 # do anything to one PR slack:*:#engineering # do anything in one channel # Broad github:read:* # read anything on GitHub github:*:* # full GitHub access platform:*:* # all platform compute actions *:*:* # unrestricted (admin only)
Why this order?
namespace:verb:resource was chosen over namespace:resource:verb for three reasons:
- Natural language: "github: read from acme/api" reads better than "github: acme/api: read."
- Hierarchical resources stay at the end: Resources often have path structure (
acme/api/pulls/456). Placing them last means wildcards expand naturally:acme/api/*→acme/*→*. - Grouping by intent: When listing permissions, you see what actions are available first, then where. "I can read from these three repos" is more useful than "in this repo, I can do these three things."
How matching works
When an action is invoked, the platform gateway resolves the target resource from the arguments and checks if any permission matches. This happens at the gateway before credentials are injected — no permission, no outbound request. A permission matches if every segment is equal or wildcarded.
# Agent runs: oc do github:comment --repo acme/api --pr 456 --body "LGTM" # Platform resolves target: github:comment:acme/api/pulls/456 # Checks permissions in order: github:comment:acme/api/pulls/456 → exact match ✓ github:comment:acme/api/* → wildcard match ✓ github:comment:acme/* → wildcard match ✓ github:*:acme/api/* → wildcard match ✓ github:comment:* → wildcard match ✓ *:*:* → wildcard match ✓ github:read:acme/api/* → verb mismatch ✗ github:comment:other-org/* → resource mismatch ✗
Permission lifetime
Every permission has an expiry. There are two values that matter:
never
Persists until explicitly revoked. Included in every future session. Represents earned trust. Granted by humans via oc trust grant.
session end
Disappears when the session ends. Useful for one-off elevated access. Granted at spawn time or via mid-session approval.
When a session starts, the agent receives all its never-expiry permissions plus any session-specific grants. Over time, as humans grant more persistent permissions, sessions start with broader access and less friction.
# Grant a persistent permission (expires: never) $ oc trust grant code-reviewer github:read:acme/* --mode auto ✓ Permission granted (auto, never) # Grant with approve mode $ oc trust grant code-reviewer github:merge:acme/api/* --mode approve ✓ Permission granted (approve, never) # View an agent's trust profile $ oc trust show code-reviewer Agent: code-reviewer Trust: established (47 sessions, 0 incidents) PERMISSION MODE DELEGATABLE EXPIRES github:read:acme/* auto yes never github:comment:acme/* auto yes never github:merge:acme/api/* approve no never slack:send:#engineering auto yes never slack:read:* auto yes never platform:*:* auto yes never # Upgrade mode (trust has been earned) $ oc trust grant code-reviewer github:merge:acme/api/* --mode auto ✓ Permission updated: approve → auto # Revoke $ oc trust revoke code-reviewer github:merge:acme/api/* ✓ Permission revoked
Mode: the two ways to hold a permission
Every permission is granted with a mode. Mode is not a separate policy layer — it's part of the permission itself. Think of it like managing an intern: you might give them permission to merge PRs but tell them to check with you each time. The permission and the oversight are one decision.
auto
Agent acts freely. No human in the loop. For actions you trust the agent to handle independently.
"You can read any file in the repo — just do it."
approve
Agent has the authority, but must get sign-off each time. The human sees the specific action, context, and reasoning before it executes.
"You can merge PRs, but run each one by me."
Why not three modes?
No "first-use" or "auto-after-one-approval." The permission model should be obvious: either you trust the agent to act or you want to see each action. If after a few approvals you decide the agent handles it well, upgrade the mode to auto. That's an explicit trust decision, not an automatic escalation.
Trust escalation
Trust is not a static property. It changes based on track record. The platform tracks agent behavior and surfaces trust level to humans, making it easy to decide when to grant or upgrade permissions.
New
Few permissions, most in approve mode. Reads might be auto, everything else requires sign-off. Human reviews output carefully.
Established
More permissions granted. Familiar actions upgraded from approve to auto. New domains and high-risk actions still in approve.
Trusted
Wide permissions, mostly auto. Only genuinely dangerous actions — production deploys, financial transactions — remain in approve. The agent works with minimal interruption.
Trust grows two ways: granting new permissions, and upgrading existing ones from approve to auto. Both are explicit human decisions. The platform suggests upgrades but humans always decide.
Checking permissions (agent side)
# Do I have this permission? $ oc can github:read:acme/api/pulls/456 ✓ Allowed (auto — via github:read:acme/*) # What about this? $ oc can github:merge:acme/api/pulls/456 ⏳ Allowed with approval (approve — via github:merge:acme/api/*) # And this? $ oc can stripe:create:charges/new ✗ No permission — request it with: oc request stripe:create:charges/new # List everything I have $ oc permissions PERMISSION MODE DELEGATABLE EXPIRES github:read:acme/* auto yes never github:comment:acme/* auto yes never github:merge:acme/api/* approve no never slack:send:#engineering auto yes never slack:read:* auto yes never platform:*:* auto yes never
# Request a permission mid-session
$ oc request stripe:read:charges/* \
--reason "Customer asked about recent charges, need to look them up"
Request submitted: req_abc123
Waiting for approval from louis... (timeout: 5m)
✓ Approved by louis (23s)
Permission granted: stripe:read:charges/* (auto, session end)
# The human saw this and had four choices:
# 1. "Approve (this session)" → auto, expires: session end
# 2. "Approve (persist, auto)" → auto, expires: never
# 3. "Approve (persist, approve)" → approve, expires: never
# 4. "Deny" → agent gets an errorHow permissions are remembered
Every approval decision is stored. The platform builds a history of what's been requested, granted, and denied. This serves three purposes:
Mode upgrades are informed. When an agent has been approved 10 times for the same permission, the platform surfaces this: "Consider upgrading to auto." The human sees the history and decides.
Trust profiles are accurate. Session count, approval rate, incident history — all tracked and surfaced to humans when they're deciding about new permissions and mode upgrades.
Agents learn the landscape. When an agent is denied, the reason is stored. Future sessions can recall why a permission was denied and adjust their approach.
Actions
Finding things to do, then doing them
oc do — execute an action
The command agents use most. Every oc do routes through the platform gateway, which handles the full lifecycle: permission check, approval flow (if needed), credential injection, execution against the external API, audit logging, and verification. One call, everything handled.
$ oc do slack:send --channel "#engineering" --message "Build failed on main"
✓ slack:send:#engineering (auto)
✓ Sent (msg_abc123, 89ms)
{
"message_id": "msg_abc123",
"channel": "#engineering",
"timestamp": "2025-01-22T14:30:01Z"
}$ oc do github:merge --repo acme/api --pr 456 --method squash
⏳ github:merge:acme/api/pulls/456 (approve)
Requesting approval from louis... (timeout: 5m)
Notified via: push, slack
✓ Approved by louis (8s)
✓ Merged (sha: abc123def)
{
"merged": true,
"sha": "abc123def456",
"method": "squash"
}$ oc do stripe:create --type refund --charge ch_abc --amount 5000 ⏳ stripe:create:refunds/ch_abc (approve) Requesting approval from louis... (timeout: 5m) ✗ Denied by louis: "Check with finance team first — amount over $20" Error: Permission denied for stripe:create:refunds/ch_abc # The denial reason is stored. Future sessions can recall it: # oc recall "stripe refund denials" → "Amounts over $20 need finance approval"
$ oc do github:merge --repo acme/api --pr 789 ⏳ github:merge:acme/api/pulls/789 (approve) Requesting approval from louis... (timeout: 5m) ✗ Approval timed out (5m). Session clock was paused during wait. Error: No response for github:merge:acme/api/pulls/789 Hint: Louis can still approve later: oc approve req_abc123
Session clock pauses during approval waits
If a session has a 5-minute budget and the agent waits 3 minutes for approval, the session still has 5 minutes of work time left. Approval wait time is not charged against the budget. The agent is not consuming resources while waiting.
Anti-abuse limits
- • Max pending requests: 3 concurrent approval requests per session. A 4th blocks until one resolves.
- • Wall-clock timeout: Sessions have an independent wall-clock limit (default: 30 minutes) regardless of session-clock pausing. Prevents indefinite blocking workflows.
- • Request rate limit: Max 10 approval requests per session. After that, additional requests are auto-denied.
oc find — discover actions by intent
Agents don't always know the action name. They know what they want to accomplish. oc find takes natural language and returns matching actions, ranked by relevance, with permission status.
$ oc find "notify the team about a build failure"
ACTION RELEVANCE PERMISSION STATUS
slack:send 0.95 ✓ auto (slack:send:*)
email:send 0.82 ✗ integration not connected
github:create 0.45 ✓ approve (github:create:acme/*/issues)
# With detail
$ oc find "notify the team" --detail
1. slack:send (0.95)
Permission: ✓ auto (slack:send:*)
Cost: free
Input: channel (string, required)
message (string, required)
thread_ts (string, optional)
Output: message_id, channel, timestamp
2. email:send (0.82)
Permission: ✗ integration not connected
Setup: oc connect email
Cost: freeVerification and rollback
Every action returns verification data — proof that it worked — and rollback information where applicable. Because all actions route through the platform gateway, verification is captured at the infrastructure level, not self-reported by the agent. This is what makes it possible to audit outcomes, not just intentions.
$ oc do slack:send --channel "#engineering" --message "PR #456 merged" --verbose
{
"action": "slack:send",
"status": "success",
"output": {
"message_id": "msg_abc123",
"channel": "C0123ABCD",
"timestamp": "1705934400.000100"
},
"verification": {
"method": "api_response",
"status_code": 200,
"confirmed": true,
"verified_at": "2025-01-22T14:30:01Z"
},
"rollback": {
"action": "slack:delete",
"args": { "channel": "C0123ABCD", "timestamp": "1705934400.000100" },
"permission_needed": "slack:delete:#engineering"
},
"cost": { "cents": 0 },
"duration_ms": 89,
"permission_used": "slack:send:* (auto)"
}oc actions — list what's available
$ oc actions NAMESPACE ACTION TYPE COST github read-pr integration free github comment integration free github review integration free github merge integration free github create-issue integration free slack send integration free slack read integration free stripe read integration free stripe create integration free platform summarize compute ~$0.02 platform embed compute ~$0.001 platform web-scrape paid ~$0.05 # Filter by namespace $ oc actions --namespace github
Memory
What persists, how it's stored, how it's found
oc remember — store a memory
Memory lives at the platform level, not inside sessions. When you store a memory, it goes to the platform's memory store, tagged with a scope. When you search, the platform checks your memory:read permissions and only returns memories you're allowed to see.
$ oc remember "Louis prefers tabs over spaces" ✓ Stored as fact (scope: user:louis, confidence: 0.9) $ oc remember "Deploy failed — missing DB migration on the payments table" ✓ Stored as episode (scope: project:acme/api, confidence: 1.0) $ oc remember "Always check for SQL injection when reviewing user input handlers" ✓ Stored as procedure (scope: project:acme/api, confidence: 0.85)
$ oc remember "The auth system uses JWT with 1h expiry and refresh tokens" \
--type fact \
--scope project:acme/api \
--confidence 0.95
✓ Stored: mem_abc123
$ oc remember "Jan 22: Reviewed and merged PR #456, found SQL injection" \
--type episode \
--tags security,pr-review \
--outcome success
✓ Stored: mem_def456Memory types
fact
Something true. May become stale. Confidence decays over time unless reinforced.
episode
Something that happened. Immutable. Timestamped. Context may shift in relevance but the event itself is permanent.
procedure
How to do something. A learned pattern. Strengthened by repetition, weakened by disuse.
oc recall — search memory
Semantic search by default. Describe what you're looking for in natural language and the platform returns relevant memories, ranked by a combination of relevance, recency, and confidence. Stale or contradicted facts are flagged.
$ oc recall "deployment process"
TYPE AGE CONFIDENCE CONTENT
fact 2w 0.90 Deploy target is Vercel
procedure 1mo 0.85 Always run e2e tests before deploying
episode 3mo - Mar 15: Deploy failed, missing DB migration
fact 1y 0.40 Deploy target is Heroku
↳ STALE — contradicted by newer fact# By type $ oc recall "testing" --type procedure # By scope $ oc recall "deployment" --scope project:acme/api # By recency $ oc recall "decisions" --since 7d # By type, scope, and recency combined $ oc recall "auth" --type fact --scope project:acme/api --since 30d
$ oc recall mem_abc123
{
"id": "mem_abc123",
"type": "fact",
"content": "The auth system uses JWT with 1h expiry and refresh tokens",
"scope": "project:acme/api",
"confidence": 0.95,
"created": "2025-01-22T14:30:00Z",
"created_by": "sess_xyz789",
"last_accessed": "2025-01-24T10:15:00Z",
"access_count": 7,
"reinforced_by": ["sess_abc111", "sess_abc222"]
}Access control
Memory access uses the same permission model as everything else. No special --memory-scope flag — memory permissions are granted like any other permission.
Scope hierarchy: org > workspace > project > user > session. Memories are visible to agents whose permissions cover the scope.
When oc recall runs, the platform checks the session's memory:read:* permissions and only returns memories from accessible scopes. When oc remember runs, it checks memory:write:*. Same gateway, same enforcement, same audit trail.
Confidence and decay
Facts become stale. A deployment target recorded a year ago might have changed. The platform handles this through confidence decay and reinforcement:
- -Facts lose confidence over time unless accessed or reinforced.
- -When a fact is confirmed by a new session, its confidence resets upward.
- -When a new fact contradicts an old one, the old one is flagged as stale.
- -Procedures strengthen with repetition and weaken with disuse.
- -Episodes are immutable — they happened. But their relevance to current search is ranked by recency.
$ oc forget mem_abc123 ✓ Removed: "Deploy target is Heroku" (fact, was already stale) # Forget by content match $ oc forget --match "Heroku" Found 2 memories matching "Heroku". Remove all? (y/n)
Sessions & Delegation
The execution context and how work gets distributed
oc status — where am I, what can I do
The first thing an agent sees when a session starts. One command, everything you need to orient: task, budget, permissions. Memory access is visible in the permissions list.
$ oc status SESSION sess_abc123 ORG acme WORKSPACE engineering TASK Review PR #456 for security issues PARENT louis (human) AGENT code-reviewer (v2.0) BUDGET $5.00 remaining · 5:00 remaining PERMISSIONS (7) github:read:acme/* auto never github:comment:acme/* auto never github:merge:acme/api/* approve never slack:send:#engineering auto never slack:read:* auto never platform:*:* auto never spawn:* auto never delegatable memory:read:project/acme/api auto never memory:read:user/louis auto never memory:write:project/acme/api auto session end
{
"session_id": "sess_abc123",
"org": "acme",
"workspace": "engineering",
"status": "active",
"task": "Review PR #456 for security issues",
"parent": { "type": "human", "id": "louis" },
"agent": { "id": "code-reviewer", "version": "2.0" },
"budget": {
"cost": { "used_cents": 0, "limit_cents": 500 },
"time": { "used_seconds": 0, "limit_seconds": 300 }
},
"permissions": [...]
}Spawning sessions
Sessions are created by humans or by other agents. A human spawns the initial session. That agent can spawn sub-sessions with narrower scope.
$ oc spawn code-reviewer \
--task "Review PR #456 for security issues" \
--permission "github:merge:acme/api/pulls/456 --mode approve" \
--budget 500 \
--timeout 300
Session: sess_abc123
Agent: code-reviewer (v2.0)
Status: active
# Persistent permissions (expires: never) are automatically included.
# The --permission flag adds session-scoped permissions on top.
# Watch it work
$ oc watch sess_abc123
# Or get the result when done
$ oc result sess_abc123 --wait# From inside my session:
$ oc spawn security-reviewer \
--task "Check PR #456 for SQL injection in user input handlers" \
--permission "github:read:acme/api/pulls/456" \
--permission "memory:read:project/acme/api" \
--budget 50 \
--timeout 60 \
--wait
Spawning sub-session...
Session: sess_sub_789
Agent: security-reviewer (v1.0)
Parent: sess_abc123 (me)
Waiting for result...
{
"session_id": "sess_sub_789",
"status": "completed",
"duration_seconds": 42,
"cost_cents": 18,
"output": {
"findings": [
{
"severity": "high",
"file": "src/api/users.ts",
"line": 45,
"issue": "Unsanitized user input in SQL query",
"recommendation": "Use parameterized queries"
}
]
}
}Delegation constraints
- - I can only delegate permissions I have AND that are marked delegatable.
- - Sub-session budget cannot exceed my remaining budget.
- - Sub-session actions count against my budget.
- - The trust chain only narrows. A sub-session can never have more access than its parent.
- - Max spawn depth: 3 levels (human → agent → sub-agent → sub-sub-agent). Prevents recursive spawning.
- - Max concurrent sub-sessions: 5 per parent. Total sub-session tree capped at 20 per root session.
Managing sub-sessions
# List my sub-sessions
$ oc agents
ID STATUS AGENT COST DURATION
sess_sub_789 completed security-reviewer $0.18 42s
sess_sub_abc active summarize $0.03 8s
sess_sub_def failed test-runner $0.12 60s (timeout)
# Get result
$ oc result sess_sub_789
{ "findings": [...] }
# Kill a running sub-session
$ oc kill sess_sub_abcLifecycle
A session ends when the agent completes its task, hits a budget limit, times out, encounters an unrecoverable error, or is killed by a human. Memories stored during the session already live at the platform level — nothing needs to be "saved." The session log is finalized for audit.
Human Interface
Setup, observation, approval, intervention
oc connect — set up integrations
Integrations are connected at the platform level. Credentials (OAuth tokens, API keys) are stored platform-side and never exposed to agent sessions. When an agent takes an action, the platform gateway injects the real credentials into the outbound request.
# OAuth flow (opens browser)
$ oc connect slack
Opening browser for OAuth...
✓ Slack connected (workspace: Acme Inc)
Credentials: stored platform-side (never exposed to sessions)
Actions available: slack:send, slack:read, slack:react, slack:list
# API key
$ oc connect stripe --key sk_live_abc123
✓ Stripe connected
Credentials: stored platform-side (never exposed to sessions)
Actions available: stripe:read, stripe:create, stripe:update
# Token
$ oc connect github --token ghp_abc123
✓ GitHub connected (user: louis)
Credentials: stored platform-side (never exposed to sessions)
Actions available: github:read-pr, github:comment, github:review,
github:merge, github:create-issue, github:read-repo
# List integrations
$ oc integrations
INTEGRATION STATUS ACTIONS CONNECTED CREDENTIAL
slack connected 4 louis OAuth token (platform-stored)
github connected 7 louis OAuth token (platform-stored)
stripe connected 4 louis API key (platform-stored)Why platform-stored credentials?
Sessions never hold external credentials. All actions route through the platform gateway, which injects credentials at request time. This means: a compromised session can't leak tokens, permissions can be revoked instantly (takes effect on the next request), and every action is audited at one central point.
Observation — watch and log
$ oc watch sess_abc123 14:30:01 ▸ Session started (code-reviewer v2.0, budget: $5/5m) 14:30:02 ▸ memory:read project/acme/api (14 facts, 4 episodes, 2 procedures) 14:30:03 ▸ github:read-pr acme/api #456 ✓ (234ms) 14:30:05 ▸ platform:summarize (4 files, 1847 lines) ✓ (1.2s, $0.02) 14:30:07 ▸ Spawned: security-reviewer → sess_sub_789 14:30:49 ▸ Sub-session completed ($0.18, 42s) — 1 finding 14:30:50 ▸ github:comment acme/api #456 ✓ (156ms) 14:30:51 ▸ slack:send #engineering ✓ (89ms) 14:30:52 ▸ github:merge acme/api #456 ⏳ awaiting approval 14:31:00 ▸ github:merge acme/api #456 ✓ approved by louis 14:31:01 ▸ Memory stored: episode "Reviewed PR #456, found SQL injection" 14:31:02 ▸ Session completed ($0.43, 61s, 7 actions)
$ oc log sess_abc123 SESSION sess_abc123 AGENT code-reviewer (v2.0) PARENT louis STATUS completed DURATION 61s COST $0.43 ACTIONS 7 TIMELINE 14:30:03 github:read-pr acme/api #456 ✓ $0.00 234ms 14:30:05 platform:summarize 4 files ✓ $0.02 1.2s 14:30:07 spawn security-reviewer ✓ $0.18 42s 14:30:50 github:comment acme/api #456 ✓ $0.00 156ms 14:30:51 slack:send #engineering ✓ $0.00 89ms 14:31:00 github:merge acme/api #456 ✓ $0.00 312ms 14:31:01 memory:store episode ✓ - - PERMISSIONS USED github:read:acme/* (auto) github:comment:acme/* (auto) github:merge:acme/api/* (approve, approved at 14:31:00) slack:send:#engineering (auto) platform:*:* (auto) MEMORIES CREATED episode: "Reviewed PR #456, found SQL injection in user input handler" # JSON output for programmatic analysis $ oc log sess_abc123 --json
Approval
When an agent needs approval, speed matters. The agent is blocked and waiting. The platform notifies humans through their configured channels — not just the CLI.
Notification channels
oc pending — poll for pending requests# List pending requests $ oc pending ID SESSION ACTION AGE REASON req_abc sess_123 github:merge:acme/api/pulls/456 12s Review complete, all checks passing req_def sess_456 stripe:create:refunds/ch_789 2m Customer requested refund ($15) # Approve (this action only, session-scoped) $ oc approve req_abc ✓ Approved: github:merge:acme/api/pulls/456 # Approve and persist (keeps approve mode — agent still checks in each time) $ oc approve req_abc --persist ✓ Approved: github:merge:acme/api/pulls/456 ✓ Permission persisted: github:merge:acme/api/pulls/456 (approve, never) # Approve, persist, and upgrade to auto (full trust) $ oc approve req_abc --persist --mode auto ✓ Approved: github:merge:acme/api/pulls/456 ✓ Permission persisted: github:merge:acme/api/pulls/456 (auto, never) # Deny with reason $ oc deny req_def --reason "Check with finance team first" ✗ Denied: stripe:create:refunds/ch_789
--persist, the approval is session-scoped — it disappears when the session ends. With --persist, the permission lives forever (defaults to approve mode). Adding --mode auto says "I trust you to handle this from now on." To widen scope, use oc trust grant explicitly.Intervention
Humans can intervene in any running session at any time. The controls are simple and non-destructive by default.
# Pause (agent is suspended, can be resumed) $ oc session pause sess_abc123 ✓ Paused sess_abc123 # Resume $ oc session resume sess_abc123 ✓ Resumed sess_abc123 # Add budget mid-session $ oc session budget sess_abc123 --add 200 ✓ Budget updated: $2.12 / $7.00 # Revoke a permission mid-session $ oc session revoke sess_abc123 slack:send:* ✓ Permission revoked. Agent will be notified on next action. # Kill $ oc session kill sess_abc123 --reason "No longer needed" ✓ Killed sess_abc123 (was active, 61s, $0.43)
Organization & Workspace
Everything operates within an organization and workspace. By default, org = workspace — no extra complexity until you need to subdivide for teams or departments.
# View current org info $ oc org Organization: Acme Inc (acme) Members: louis (admin), alice (member) Workspaces: 2 (engineering, support) Billing: Team plan Integrations: 3 org-level (GitHub, Stripe, Datadog) # Invite a member $ oc org invite alice@acme.com --role member ✓ Invitation sent
# List workspaces $ oc workspace list NAME AGENTS INTEGRATIONS MEMBERS * engineering 4 5 (3 org + 2 workspace) 3 support 2 4 (3 org + 1 workspace) 2 # Switch active workspace $ oc workspace switch support ✓ Switched to workspace: support # Create a new workspace $ oc workspace create data-team ✓ Created workspace: data-team Inherits 3 org-level integrations # View workspace details $ oc workspace show engineering Workspace: engineering (default) Org: Acme Inc Integrations: 5 (3 inherited from org + 2 workspace-level) org: GitHub, Stripe, Datadog ws: Slack #engineering, Jira Agents: code-reviewer, deploy-bot, test-runner, security-scanner Active sessions: 2
Command Reference
Every command, at a glance
All commands support --json for machine-readable output and --help for usage details.
A CLI that makes agents powerful and humans confident.
Minimal commands. Integrated permissions. Trust that grows.