CLI Commands
The ostwin CLI is the unified entry point for all OSTwin operations — plan creation, execution, monitoring, skill management, and more. It lives at .agents/bin/ostwin and is a pure PowerShell script (requires pwsh 7+).
For a cross-surface inventory that includes bot slash commands and MCP tools, see Command Support Inventory.
Global Options
Section titled “Global Options”| Flag | Description |
|---|---|
-h, --help |
Show help text and exit |
-v, --version |
Show version and build hash |
ostwin run
Section titled “ostwin run”Execute a plan. This is the primary entry point for running work.
ostwin run <plan_id>ostwin run <plan_id> --dry-runostwin run <plan_id> --plainostwin run <plan_id> --json-eventsostwin run <plan_id> --debugostwin run <plan_id> --resume --expandostwin run <plan_id> --syncostwin run plans/my-feature.mdThe first positional argument is resolved in this order:
- Plan ID — a hex string (8–64 characters) resolved via the dashboard API to a plan file and working directory
- File path — an existing
.mdfile used directly - Fallback — passed through as-is (will error if invalid)
When a plan ID is provided and the dashboard is reachable, ostwin run automatically resolves the plan file location and extracts the working_dir from the plan metadata.
| Flag | Description |
|---|---|
--dry-run |
Parse plan, build DAG, but do not execute |
--resume |
Resume a previously stopped plan execution |
--sync |
Refresh rooms from the latest plan content |
--expand |
Expand the plan using AI before execution |
--plan-review |
Enable a synthetic PLAN-REVIEW room |
--enable-planning |
Generate an advisory planning DAG before launch |
--working-dir PATH |
Override the working directory for the plan |
--workspace-isolation shared|room-worktree |
Choose shared workspace execution or per-room Git worktrees |
--non-interactive, -n |
Skip all interactive prompts |
--debug |
Show raw debug diagnostics and set console/agent log levels to DEBUG |
--plain |
Force copy/paste-friendly lifecycle lines instead of live rendering |
--json-events |
Emit newline-delimited JSON events on stdout; diagnostics go to stderr |
Command-center output modes
Section titled “Command-center output modes”ostwin run is quiet by default. In a capable interactive terminal it renders the
live command center; in CI, redirected stdout, non-interactive sessions, too-small
or unsupported terminals, it falls back to plain text. NO_COLOR=1 disables ANSI
styling. Use --plain for screen readers and CI logs, --json-events for event
consumers, and --debug when you need runner/manager diagnostics.
Raw logs and full messages are not removed by the quiet renderer. Use
ostwin room <room-id> logs --full, ostwin room <room-id> messages --full, or
direct room files for post-mortem detail.
Auto Role Scaffolding
Section titled “Auto Role Scaffolding”If the plan references roles that are not installed, ostwin run will prompt (or auto-create in non-interactive mode) to scaffold the missing roles using Auto-CreateRole.ps1.
Project Initialization
Section titled “Project Initialization”Before execution, ostwin run ensures the project directory is initialized (runs init.ps1 idempotently). This creates .agents/ and .opencode/opencode.json if they don’t exist.
ostwin cron
Section titled “ostwin cron”Register and optionally schedule a resumable Ostwin run. This is the productized,
cross-platform version of the Makefile helper pattern: store the plan/run id once
with its working directory, then let an OS-native scheduler call ostwin cron run.
For a feature overview and operator checklist, see Cron Scheduling.
ostwin cron register <plan_id> --working-dir .ostwin cron run --dry-runostwin cron once <plan_id> --after 12h --working-dir .ostwin cron schedule <plan_id> --every 12h --working-dir .ostwin cron statusostwin cron unscheduleostwin cron unregisterostwin cron run loads the registered record and executes:
ostwin run <plan_id> --resume --working-dir <working_dir> --non-interactiveThe working directory is stored because native schedulers often start in a
different directory ($HOME, /, or C:\Windows\System32). Scheduler backends
are OS-native: Linux uses a systemd user timer with crontab fallback, macOS uses
launchd, and Windows uses Task Scheduler.
For one-time delayed execution, use ostwin cron once. It stores the same plan
record, installs a one-shot trigger, runs ostwin cron run-once, and then cleans
up the one-time trigger and cron config. macOS uses launchd, Linux uses
systemd-run or a Unix nohup/sleep fallback, and Windows uses a one-time
Task Scheduler task.
ostwin plan
Section titled “ostwin plan”Plan management with file-backed creation.
ostwin plan create --file plan.mdostwin plan create --file ./plans/brief.mdostwin plan create -f /absolute/path/brief.mdostwin plan start <plan_id>ostwin plan listostwin plan clear --force| Subcommand | Description |
|---|---|
create |
Create a plan via the dashboard API from an explicit file path |
start |
Execute a plan (same resolution as ostwin run) |
list |
List all plans tracked in the project |
clear |
Delete all plan files and zvec indexes |
plan create
Section titled “plan create”ostwin plan create --file brief.mdostwin plan create --file ./plans/brief.mdostwin plan create -f /absolute/path/brief.md| Argument | Description |
|---|---|
--file, -f |
Required relative or absolute path to the source Markdown file |
Creates the plan via the dashboard API from the source file and opens the plan editor in your browser. Positional, title-only, and default/blank plan creation are not supported by the CLI.
Requires the dashboard to be running (ostwin dashboard start).
plan start
Section titled “plan start”ostwin plan start <plan_id>ostwin plan start <plan_id> --dry-runAccepts the same plan_id or file path resolution as ostwin run, plus the same flags (--dry-run, --resume, --expand, --working-dir).
plan clear
Section titled “plan clear”ostwin plan clearostwin plan clear --forceRemoves all plan files from ~/.ostwin/.agents/plans/ (preserving PLAN.template.md) and clears the zvec index. Stops and restarts the dashboard if it was running.
| Flag | Description |
|---|---|
--force, -f, -y |
Skip confirmation prompt |
ostwin workspace
Section titled “ostwin workspace”Register Workspaces in the system catalog so platform administrators can assign them to users in User Management.
export OSTWIN_API_KEY="<platform-write-or-default-workspace-admin-key>"ostwin workspace create \ --name "Client Research" \ --slug client-research \ --description "Research and source ingestion for the client"For automation, add --json:
ostwin workspace create --name "Finance" --slug finance --json{"workspace_id":"ws_...","name":"Finance","slug":"finance","description":null,"catalog_registered":true}| Flag | Description |
|---|---|
--name, -n |
Required Workspace display name |
--slug, -s |
Required stable slug using 1–63 lowercase letters, digits, or hyphens |
--description, -d |
Optional Workspace description |
--json |
Emit a compact machine-readable result |
The dashboard must be running at DASHBOARD_URL (default:
http://localhost:3366). OSTWIN_API_KEY must contain a platform-write
credential or an owner/admin credential scoped to ws_default; the key is read
only from the environment so it does not appear in shell history or process
arguments.
The Workspace catalog is derived from the workspaces registry. This command
uses the authenticated POST /api/workspaces control-plane operation, assigns
the calling identity as the initial Workspace owner, and makes the Workspace
immediately available in the User Management assignment selector. There is no
separate catalog record to synchronize.
ostwin init
Section titled “ostwin init”Scaffold Agent OS into a project directory.
ostwin init # Initialize current directoryostwin init /path/to/project # Initialize a specific directoryostwin init --yes # Non-interactive mode| Flag | Description |
|---|---|
--yes, -y |
Accept all defaults without prompts |
--help, -h |
Show help |
Creates .agents/, config.json, role directories, and the opencode configuration. Lighter than a full install — it does not install Python or registry dependencies. It verifies the built-in CodeIndex MCP dependency and exits with code 69 when an approved CodeGraph CLI is unavailable. Release images provision and verify the version-pinned CLI before initialization; bypassing that check is unsupported in a release build.
ostwin sync
Section titled “ostwin sync”Sync framework updates from the global OSTwin installation to an initialized project.
ostwin syncostwin sync /path/to/projectostwin sync --agentsostwin sync --agents --agents-dir /tmp/opencode-agents| Flag | Description |
|---|---|
--agents |
Sync project role ROLE.md definitions from .agents/roles/ and contributes/roles/ into OpenCode’s agents directory |
--agents-dir PATH |
Override the OpenCode agents destination; defaults to ~/.config/opencode/agents |
--project-dir PATH |
Explicit project root for --agents mode |
Updates .agents/ scripts and configuration to match the installed version.
The target directory must already be initialized with .agents/; run ostwin init /path/to/project first for a new project.
With --agents, only OpenCode agent definitions are synced so opencode run --agent <role> can discover built-in and contributed roles.
ostwin status
Section titled “ostwin status”Show the current state of all war-rooms.
ostwin statusostwin status --watchostwin status --json| Flag | Description |
|---|---|
--json |
Machine-readable JSON output |
--watch |
Continuously refresh the status display |
Reads status, state_changed_at, and retries from each room directory.
ostwin logs
Section titled “ostwin logs”View war-room channel logs.
ostwin logsostwin logs room-001ostwin logs room-001 --followostwin logs --type done --last 20| Flag | Description |
|---|---|
--follow, -f |
Stream new log entries in real time |
--type TYPE |
Filter by message type (task, done, review, pass, fail, fix, error, signoff) |
--from ROLE |
Filter by sender role |
--last N |
Show only the last N messages |
ostwin stop
Section titled “ostwin stop”Graceful shutdown of running processes.
ostwin stopostwin stop --force| Flag | Description |
|---|---|
--force |
Force-kill the entire process tree immediately |
Stops the dashboard and any running channel processes. Without --force, sends a graceful termination signal and waits up to 5 seconds before force-killing.
ostwin rooms / room / epic / events / timeline / inspect / search
Section titled “ostwin rooms / room / epic / events / timeline / inspect / search”Read-only command-center inspection commands. They inspect the current war-room
root, selected by WARROOMS_DIR when set or <project>/.war-rooms by default.
OSTWIN_EVENTS_PATH overrides the event stream path.
ostwin roomsostwin rooms --jsonostwin room room-002ostwin room room-002 messages --full --last 10ostwin room room-002 logs --last 200ostwin epic EPIC-002 qaostwin events --json --last 50ostwin timeline --last 20ostwin inspectostwin search "manager triage" --limit 20ostwin search "qa failed" --json| Command | Description |
|---|---|
rooms |
List rooms in the current run; --json returns the full run-state object. |
room <room-id> |
Show one room summary and detail sections. Subcommands: brief, tasks, qa, messages, logs, artifacts, status. |
epic <EPIC-ID> |
Resolve an epic ref such as EPIC-002 to its room, then run the same room subcommands. |
events |
Read <war_rooms_dir>/events.jsonl as a human timeline or JSON array. Flags: --json, --last N, --follow. |
timeline |
Alias for events. |
inspect |
Print read-only inspection help and examples. |
search <query> |
Search bounded runtime evidence across room docs, messages, logs, artifacts metadata, and events. Flags: --limit N, --json. |
Room detail sections are backed by runtime files: config.json, progress.json,
lifecycle.json, status, retries, state_changed_at, task-ref,
pids/*.pid, brief.md, TASKS.md, QA.md, channel.jsonl, artifacts/**,
discovered room log files, and events.jsonl. See Command Center
for the full source-file map and terminal fallback guidance.
ostwin control
Section titled “ostwin control”Audited plan-run controls. These are intentionally separate from ostwin stop,
which remains dashboard/channel process shutdown.
ostwin control pause --reason "operator break" --yesostwin control resume --yesostwin control stop --reason "maintenance" --yesostwin control rerun room-002 --reason "retry after fix" --yesostwin control kill room-002 --role engineer --reason "hung process" --yesostwin control force-transition room-002 --to optimize --reason "manual QA reroute" --yes| Subcommand | Description |
|---|---|
pause |
Write <war_rooms_dir>/.paused and emit operator.plan.pause. |
resume |
Remove .paused and emit operator.plan.resume. |
stop |
Write <war_rooms_dir>/.stop-requested and emit operator.plan.stop; does not kill room processes. |
rerun <room-id> |
Write <room>/requests/rerun-current-role.json and emit operator.room.rerun; lifecycle accounting remains authoritative. |
kill <room-id> |
Audit then kill/remove the selected room role PID after confirmation. |
force-transition <room-id> --to STATE |
Validate the target state, audit, then update status, state_changed_at, and audit.log. |
Common options: --war-rooms-dir PATH, --actor NAME, --reason TEXT,
--role ROLE, --to STATE, --yes/-y, and --non-interactive/-n.
Risky controls default to No. Non-interactive contexts fail closed unless
--yes and a non-empty --reason are supplied.
ostwin dashboard
Section titled “ostwin dashboard”Manage the web dashboard server.
ostwin dashboard startostwin dashboard stopostwin dashboard restartostwin dashboard statusostwin dashboard logsostwin dashboard logs --followostwin dashboard autostartostwin dashboard autostart --uninstall| Subcommand | Description |
|---|---|
start |
Start the dashboard in the background |
stop |
Stop the running dashboard |
restart |
Stop and start the dashboard |
status |
Show running state, URL, and memory pool health |
logs |
Show the last 50 log lines (use -f to follow) |
autostart |
Register or remove dashboard startup on login |
The dashboard runs on port 3366 by default (overridable via DASHBOARD_PORT env var).
| Flag | Applies to | Description |
|---|---|---|
--port PORT |
start, restart, status, logs, autostart |
Override the dashboard port for the command invocation. Can appear before or after the subcommand. |
--project-dir PATH |
start, restart, autostart |
Project directory the dashboard should monitor. Defaults to OSTWIN_HOME. |
ostwin channel
Section titled “ostwin channel”Manage communication channel integrations (Telegram, Discord, Slack).
ostwin channel listostwin channel connect telegramostwin channel disconnect telegramostwin channel test telegramostwin channel pair telegramostwin channel pair telegram --regenerate| Subcommand | Description |
|---|---|
list |
List configured channels |
connect |
Connect a channel integration |
disconnect |
Disconnect a channel integration |
test |
Test channel connectivity |
pair |
Pair a channel with a war-room |
All channel commands delegate to the dashboard REST API. connect prompts for platform credentials when existing credentials are not available; pair --regenerate rotates the pairing code.
ostwin import
Section titled “ostwin import”Import a pack of knowledge, skills, and roles from one folder. The three kinds are applied in a fixed order — knowledge, then skills, then roles — because skills cite knowledge namespaces and roles cite skills.
ostwin import /path/to/pack --dry-runostwin import /path/to/packostwin import /path/to/pack --yesostwin import /path/to/pack --only skillsostwin import /path/to/pack --namespace docs=my-namespace --yesostwin import /path/to/pack --forceostwin import /path/to/pack --json --yesPack layout
Section titled “Pack layout”The importer recognizes exactly three top-level subdirectories. Any of them may be absent.
my-pack/├── knowledge/ # one subdirectory per namespace target│ ├── doc-digest/│ └── references/├── skills/ # one subdirectory per skill, each with SKILL.md│ ├── README.md # loose file — ignored│ └── my-skill/│ ├── SKILL.md│ ├── agents/│ └── references/└── roles/ # one subdirectory per role, each with ROLE.md ├── README.md # loose file — ignored └── my-role/ └── ROLE.mdA skill is an immediate child directory of skills/ that contains a readable SKILL.md; a role is an immediate child directory of roles/ that contains a readable ROLE.md. A role directory containing only ROLE.md is the normal case — role.json is synthesized by the importer from the ROLE.md heading structure, and a role.json present in the pack is ignored and reported, so a pack cannot inject a model, a runner, or MCP permissions it did not declare in ROLE.md.
Ignored entries
Section titled “Ignored entries”Nothing outside knowledge/, skills/, and roles/ is imported — but everything skipped is listed in the plan, so the ignore is never silent. The plan reports:
| Category | Behaviour |
|---|---|
Other top-level directories (data/, memory-mirror/, …) |
Ignored, listed under ignored.top_level_dirs |
Top-level files (README.md, …) |
Ignored, listed under ignored.top_level_files |
Loose files directly inside skills/ or roles/ |
Ignored — a namespace-less file is not a skill or a role |
Loose files directly inside knowledge/ |
Ignored — a namespace is declared per directory, so a loose file has no directory to name |
Dot-prefixed paths anywhere (.git/, .DS_Store, __pycache__/, node_modules/) |
Never copied and never ingested |
Files with an extension the knowledge indexer does not support (for example checksums.sha256) |
Reported under ignored.knowledge_unsupported so a 196-of-197 result never looks like data loss |
Executables and PowerShell scripts inside a skill directory; anything that is not a *.md file inside a role directory |
Refused by the security filter and listed under ignored.refused_entries |
Symlinks inside a skill or role tree are fatal, not skipped: the run aborts before anything is written.
The namespace prompt
Section titled “The namespace prompt”Every immediate child directory of knowledge/ needs a namespace id matching ^[a-z0-9][a-z0-9_-]{0,63}$. Resolution order:
--namespace DIR=NSon the command line (repeatable).- An interactive prompt, with a slugified form of the directory name pre-filled as the default.
--yes, which accepts every default without prompting.
Each knowledge directory needs a namespace.Namespace ids match ^[a-z0-9][a-z0-9_-]{0,63}$ (lowercase letters, digits, '-', '_').Press Enter to accept the default. Two directories may share one namespace: theircontent is added to it, nothing is replaced.
knowledge/doc-digest → namespace [doc-digest]: knowledge/references → namespace [references]:The default is derived by transliterating the directory name — Vietnamese diacritics and đ/Đ are folded, so Kế-toán-trưởng becomes ke-toan-truong. Your answer is never silently rewritten: an id that fails the pattern is rejected and re-prompted rather than slugified for you.
Two directories may target the same namespace. That is legal and additive — both directories are ingested into the one namespace, sequentially, and neither is treated as a conflict. An existing namespace is likewise reused, not replaced.
If stdin is not a terminal, a mapping is still unresolved, and --yes was not passed, the command fails with NAMESPACE_UNRESOLVED and lists the unresolved directories rather than guessing.
Knowledge requires a running dashboard
Section titled “Knowledge requires a running dashboard”Skills and roles are written directly to disk by the CLI. Knowledge is written only through the running dashboard’s HTTP API, so that a single writer owns the vector and graph stores. This leg needs:
- a reachable dashboard (
--dashboard-url, else$DASHBOARD_URL, elsehttp://localhost:3366), and OSTWIN_API_KEYset in the environment.
If knowledge is in scope and the dashboard is unreachable or rejects the key, the command fails during planning with DASHBOARD_UNREACHABLE or DASHBOARD_AUTH_FAILED before anything is written. It never falls back to a direct write. Use --only skills or --only roles to import the other two kinds while the dashboard is down.
Conflicts and --force
Section titled “Conflicts and --force”The default is skip-and-report: an existing, non-empty destination directory for a skill or a role is left untouched, the item is reported as skip-conflict, and the run exits 2. Nothing is destroyed without --force.
--force changes three things:
- an existing skill directory is replaced wholesale — files that exist in the installed skill but not in the pack are gone, not merged;
- an existing role directory is replaced the same way;
- knowledge is re-ingested even where the per-file content hash already matches, instead of being deduplicated away.
Replacement is staged and swapped atomically, and a destination that is a symlink is refused outright even with --force.
Note that two knowledge directories mapping to one namespace is not a conflict and needs no --force.
Worked example
Section titled “Worked example”The chinh-quyen-2-cap pack is a Vietnamese local-government corpus laid out exactly as above: two knowledge directories (doc-digest, 956 KB, and references, 162 MB), nine skills, and seventeen roles whose directories carry a ROLE.md and nothing the importer will copy besides it. Its ROLE.md and SKILL.md files both declare knowledge(namespace='chinhquyen-2-cap'), so both knowledge directories are answered with that one namespace.
ostwin import ~/PycharmProjects/chinh-quyen-2-cap \ --namespace doc-digest=chinhquyen-2-cap \ --namespace references=chinhquyen-2-cap \ --knowledge-language Vietnamese \ --dry-runostwin import — plan pack: /Users/you/PycharmProjects/chinh-quyen-2-cap dashboard: http://localhost:3366 (reachable) mode: dry-run conflicts: skip
knowledge (2 directories → 1 namespace) namespace chinhquyen-2-cap (new, language Vietnamese) knowledge/doc-digest 15 files 956.0 KB ingestible 15 knowledge/references 182 files 162.4 MB ingestible 181 vision OCR: on entity extraction: on note: 1 file has an unsupported extension and will be skipped references/checksums.sha256
skills (9) → ~/.local/share/ostwin/.agents/skills/global roles (17) → ~/.local/share/ostwin/.agents/roles
ignored (not one of knowledge/, skills/, roles/) directories: data/, memory-mirror/ files: README.md in skills/: README.md in roles/: README.mdDrop --dry-run to apply it. Skills land in ~/.local/share/ostwin/.agents/skills/global/<name>, roles in ~/.local/share/ostwin/.agents/roles/<name>, and each installed directory carries a .ostwin-import.json recording the source folder, the source git commit, and a content hash. After a role import, wire the new roles into OpenCode with the command the report prints:
ostwin mcp sync --roles-dir ~/.local/share/ostwin/.agents/rolesostwin import never runs that for you — ostwin mcp sync rewrites the OpenCode config for all roles, and an import must not have that blast radius.
Options
Section titled “Options”| Flag | Description |
|---|---|
--only KIND |
Import only knowledge, skills, or roles. Repeatable. Default: every kind present in the pack |
--namespace DIR=NS |
Map a knowledge/ subdirectory to a namespace id. Repeatable |
--knowledge-language LANG |
Language recorded when a namespace is created: English (default), Vietnamese, Chinese, Spanish. Existing namespaces keep theirs |
--no-vision-ocr |
Disable vision OCR for PDFs — much faster, but scanned PDFs yield no text |
--no-extract-entities |
Skip graph entity extraction (one LLM call per chunk). Much faster, weaker graph |
--poll-timeout SECONDS |
Maximum wall time to wait for one knowledge import job (default 21600, six hours) |
--no-wait |
Submit knowledge jobs and return their ids without polling. Always exits 2 |
--role-model MODEL |
Model id written into every synthesized role.json (default opencode/big-pickle) |
--role-timeout SECONDS |
timeout_seconds written into every synthesized role.json (default 900) |
--verify-model |
Probe --role-model reachability through the dashboard before writing roles. Advisory — a failure warns, it does not abort |
--force |
Overwrite existing skills and roles, and re-ingest already-indexed knowledge files |
-y, --yes |
Accept every default namespace and skip the confirmation prompt |
--dry-run |
Print the plan and exit without writing anything |
--json |
Print a machine-readable payload on stdout instead of the human report |
--dashboard-url URL |
Dashboard base URL. Default: $DASHBOARD_URL, else http://localhost:3366 |
Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 |
The plan was printed (--dry-run), every in-scope stage applied cleanly, or you declined at the confirmation prompt |
1 |
A fatal error, and nothing was written by any stage |
2 |
Something was written and something is incomplete — a conflict was skipped, a stage aborted after earlier work landed, some files failed to index, the skills index sync degraded, an entry was refused by the security filter, or --no-wait left jobs running |
130 |
Interrupted with Ctrl-C |
There is no rollback. Work that has already been applied is never undone; a partial run is reported in full instead.
ostwin skills
Section titled “ostwin skills”Manage skill discovery, installation, and updates.
ostwin skills search "web"ostwin skills install my-skillostwin skills install https://github.com/user/repoostwin skills install --from /path/to/skillostwin skills install my-skill --agent engineerostwin skills listostwin skills update --allostwin skills remove my-skillostwin skills sync| Subcommand | Description |
|---|---|
install |
Install a skill from ClawHub catalog, GitHub URL, or local directory |
list |
Show installed skills (via dashboard API) |
search |
Search the ClawHub catalog |
update |
Update a specific skill or all skills |
remove |
Uninstall a skill |
sync |
Synchronize skills across the project |
install sources
Section titled “install sources”The install subcommand supports three sources:
| Source | Example |
|---|---|
| ClawHub slug | ostwin skills install my-skill |
| GitHub URL | ostwin skills install https://github.com/user/skill-repo |
| Local directory | ostwin skills install --from /path/to/skill-dir |
When installing from a GitHub URL, ostwin clones the repository, scans for SKILL.md files, and installs each skill found. Nested skills (skills inside other skill directories) are skipped.
| Flag | Description |
|---|---|
--from DIR |
Install from a local directory |
--agent ROLE |
Install to a specific role’s skill directory instead of global |
ostwin mcp
Section titled “ostwin mcp”Manage MCP extensions and permissions.
ostwin mcp syncostwin mcp install <git-url> --name custom-serverostwin mcp install --http https://stitch.googleapis.com/mcpostwin mcp listostwin mcp catalogostwin mcp remove chrome-devtoolsostwin mcp test chrome-devtoolsostwin mcp test --allostwin mcp compileostwin mcp credentials set chrome-devtools API_KEYostwin mcp credentials listostwin mcp migrateostwin mcp init-project /path/to/project| Subcommand | Description |
|---|---|
sync |
Resolve MCP servers from role definitions and generate agent permissions |
install |
Install an MCP extension from catalog, git, or HTTP |
list |
Show installed extensions |
catalog |
Show available packages in the central catalog |
remove |
Uninstall an extension |
credentials |
Manage credentials in the vault (set, list, delete) |
test |
Test MCP server connectivity |
compile |
Compile the home MCP configuration for a project-local runtime |
migrate |
Move plaintext secrets from MCP configs into the vault where possible |
init-project |
Scaffold a per-project MCP directory |
mcp options
Section titled “mcp options”| Flag | Description |
|---|---|
--project-dir DIR |
Target project for MCP extension operations; defaults to the current project when .agents/mcp exists, otherwise ~/.ostwin. |
--name NAME |
Override the installed extension name for git/HTTP installs. |
--branch BRANCH |
Git branch for git installs. |
--http URL |
Register a remote HTTP MCP server instead of a local stdio server. |
--header K=V |
Add a header to an HTTP MCP server; repeatable. |
mcp sync
Section titled “mcp sync”ostwin mcp syncResolves MCP server references from role.json mcp_refs and generates the agent permission configuration in ~/.ostwin/.opencode/opencode.json. Run this after installing new MCP extensions or updating role configurations.
ostwin search-engine
Section titled “ostwin search-engine”Install and run the local SearXNG search engine under ~/.ostwin/search-engine using ~/.ostwin/.venv/bin/uv.
ostwin search-engine install --startostwin search-engine configure --port 6633 --bind 127.0.0.1ostwin search-engine startostwin search-engine stopostwin search-engine statusostwin search-engine settings| Subcommand | Description |
|---|---|
install |
Install the managed local SearXNG source, install requirements.txt with ~/.ostwin/.venv/bin/uv, and write config |
configure |
Write managed SearXNG settings |
start |
Start the local search engine |
stop |
Stop the local search engine |
status |
Show runtime status |
settings |
Print the managed settings file path and contents |
If the settings file has not been created yet, settings prints the expected path and suggests ostwin search-engine configure instead of failing.
ostwin memory
Section titled “ostwin memory”Manage agent memory namespaces.
ostwin memory listostwin memory stats <plan_id>ostwin memory tree <plan_id>ostwin memory clear <plan_id> --forceostwin memory delete <plan_id> <note_id>ostwin memory archive <plan_id>ostwin memory export <plan_id>| Subcommand | Description |
|---|---|
list |
List all namespaces with note counts and sizes |
stats |
Show stats for a namespace (notes, tags, keywords, paths) |
tree |
Show the note directory tree for a namespace |
clear |
Delete all notes in a namespace |
delete |
Delete a single note by ID |
archive |
Archive notes and start fresh |
export |
Export a namespace as .tar.gz |
Requires the dashboard to be running.
| Flag | Description |
|---|---|
--force |
Skip confirmation prompt (for clear) |
ostwin role
Section titled “ostwin role”Run a role’s subcommand or list available roles.
ostwin role # List all roles with subcommandsostwin role <name> # List subcommands for a roleostwin role <name> <sub> [args] # Run a role subcommandRoles define their subcommands in subcommands.json. Each subcommand has an invoke template that is resolved and executed in the role’s module root directory.
ostwin config
Section titled “ostwin config”View or update configuration.
ostwin config --get manager.poll_interval_secondsostwin config --set manager.default_model "google-vertex/gemini-3.1-pro"| Flag | Description |
|---|---|
--get KEY |
Read a configuration value |
--set KEY VALUE |
Write a configuration value |
ostwin health
Section titled “ostwin health”Check system health.
ostwin healthostwin health --json| Flag | Description |
|---|---|
--json |
Machine-readable JSON output |
Validates the PowerShell engine, dashboard API, dashboard frontend, memory daemon, and active war-room states.
ostwin test
Section titled “ostwin test”Run test suites.
ostwin testostwin test --suite NAME --verboseostwin test --path .agents/tests/plan/Start-Plan.Tests.ps1| Flag | Description |
|---|---|
--suite NAME |
Run a specific Pester suite (all, cli, plan, roles, manager, workspace, etc.) |
--path PATH |
Run a specific test file or directory |
--verbose |
Verbose output |
Executes Pester tests under .agents/tests/ and .agents/bin/tests/.
ostwin reload-env
Section titled “ostwin reload-env”Reload environment variables from ~/.ostwin/.env into MCP configuration files.
ostwin reload-envParses the .env file and injects all variables into the environment (or env) blocks of every configured MCP server. Useful after adding new API keys or changing environment configuration.
ostwin mac
Section titled “ostwin mac”macOS desktop automation shorthand. Delegates to the macos-automation-engineer role.
ostwin mac app helpostwin mac app listostwin mac window get-bounds Finderostwin mac capture full /tmp/screen.pngostwin mac type text "Hello World"ostwin mac click helpAvailable scripts: app, window, click, type, capture, system, finder, axbridge, devtools. Run ostwin mac <script> help for per-script usage.
| Script | Safe/read-only commands | State-changing or permission-gated commands |
|---|---|---|
app |
frontmost, list, is-running <AppName> |
launch, kill |
window |
get-bounds <AppName> |
move, resize, set-bounds, minimize, restore, fullscreen (Accessibility permission) |
capture |
None; help is safe | full, region, window, clipboard (Screen Recording permission) |
click |
None; help is safe | click, double-click, right-click, move (Accessibility permission for click actions) |
type |
None; help is safe | text, key, combo, hold (Accessibility permission) |
system |
volume-get, dark-mode-get, wifi-status, clipboard-get, default-read |
volume-set, mute, dark-mode-set, clipboard-set, notifications, default-write |
finder |
search, search-name, search-kind, preview, reveal, xattr-list, xattr-get |
copy, trash, xattr-set, xattr-rm |
axbridge |
window-list, read-focused, ui-tree |
click-button, menu-click (Accessibility permission) |
devtools |
brew-list, simctl-list, codesign-verify, keychain-list, xcrun |
xcode-build, xcode-test, keychain-get depending on target/tooling |
This is a shortcut for ostwin role macos-automation-engineer <script> <command>.
ostwin version
Section titled “ostwin version”Show the current version.
ostwin versionDisplays the version from config.json and the build hash (if available).
Environment Variables
Section titled “Environment Variables”| Variable | Description |
|---|---|
ENGINEER_CMD |
Override the CLI tool spawned for the engineer role |
QA_CMD |
Override the CLI tool spawned for the QA role |
MOCK_SIGNOFF |
Set to "true" for automatic signoff (testing) |
AGENT_OS_LOG_LEVEL |
Log level: DEBUG, INFO, WARN, ERROR (default: INFO) |
WARROOMS_DIR |
Override the war-rooms data directory (default: <project>/.war-rooms) |
DASHBOARD_PORT |
Override the dashboard port (default: 3366) |
DASHBOARD_URL |
Override the dashboard URL (default: http://localhost:3366) |
OSTWIN_HOME |
Override the OSTwin home directory (default: ~/.ostwin) |
OSTWIN_API_KEY |
API key for dashboard authentication |
OSTWIN_ALLOWED_HOSTS |
Exact comma-separated dashboard Host allowlist |
OSTWIN_BASE_URL |
Canonical external dashboard URL |
OSTWIN_WS_STRICT |
Require authenticated WebSocket admission (secure by default) |
OSTWIN_MAX_REQUEST_BODY_BYTES |
Global HTTP request-body limit (default: 16 MiB) |
RATE_LIMIT_ENABLED |
Opt in to the bounded per-peer HTTP limiter (default: false). Authentication brute-force budgets are separate and always enforced. |
RATE_LIMIT_WINDOW |
Rate-limit window in seconds, when enabled (default: 60) |
RATE_LIMIT_MAX |
Requests allowed per direct peer/window, when enabled (default: 600) |
OSTWIN_RATE_LIMIT_MAX_CLIENTS |
Maximum in-memory peer buckets (default: 4096) |
OSTWIN_SECURE_COOKIES |
Force the Secure attribute on browser credentials |
OSTWIN_TRUSTED_TLS_PROXY |
Assert that a trusted ingress terminates TLS |
Environment files are loaded in this order (later values do not override already-set variables):
~/.ostwin/.env— global<project-root>/.env— project root.agents/.env— agents directory
Plan ID Resolution
Section titled “Plan ID Resolution”When a command accepts a <plan_id> argument, the following resolution logic applies:
- Existing file — If the argument is a path to an existing file, use it directly and extract
working_dirfrom the file content - Hex ID — If the argument matches
^[0-9a-fA-F]{8,64}$(no slashes or dots), query the dashboard API at/api/plans/<id>to resolve the plan file location and working directory - Fallback — Pass through as-is
This means you can use either short hex IDs (e.g., a1b2c3d4e5f6) or full file paths interchangeably.
