Skip to content

Commands

Z-M-Huang edited this page May 1, 2026 · 5 revisions

Commands

Command extensions are UI-agnostic slash-commands that act on the main session. /model, /save, /resume, /reload, /provider, /tools, /sm attach — all commands regardless of whether the user typed them in a TUI, web UI, or script.

contractVersion: 1.0.1


Intent

Users need to act on the session outside the conversation: switch model, save the session, list tools, attach a state machine, reload the extension set. These actions must work the same way regardless of UI, so they cannot be modelled as UI affordances.

Commands are the UI-agnostic dispatch channel. A TUI, web UI, or script speaks the same Command Model.


Contract shape

classDiagram
    class CommandContract {
        kind : "Command"
        contractVersion : SemVer
        requiredCoreVersion : SemVerRange
        configSchema : JSONSchema
        loadedCardinality : unlimited
        activeCardinality : unlimited
        stateSlot : optional
        validationSeverity : optional
        discoveryRules : DiscoveryRules
        reloadBehavior : in-turn
        name : string
        description : string
        argumentHint : string?
        category : string?
        argsSchema : JSONSchema
    }
Loading

A command declares a name (without the leading /), a human description, an argsSchema for parsed arguments, and a handler registered through the common Extension Lifecycle. argumentHint and category are optional display metadata for command palettes and help output; they do not affect dispatch identity.


Command identity

Commands use flat names. A project-scoped command may shadow a bundled or global command of the same name. Scope layering applies.

Name collisions within a single layer are a validation error. Cross-layer shadowing is legal; /commands list reveals the origin layer of each bound command (same post-hoc inspection pattern as /tools).


Orthogonality with State Machines

Commands and SMs are orthogonal: commands never flow through SM stage gating, and the SM never vetoes a command. The canonical statement and rationale live in Command Model — Commands and SM orthogonality.


Configuration schema

Every command's configSchema must accept:

Field Meaning
enabled Whether the command is registered.
alias Optional list of alternate names. Aliases shadow identically.

Plus command-specific options.


Lifecycle

Phase Command responsibilities
init Validate config; load handler.
activate Register the command (and aliases) with the dispatcher.
deactivate Unregister; finish in-flight handler invocations.
dispose Release resources. Idempotent.

Commands run synchronously by default — the dispatch returns only after the handler completes. Long-running commands should emit progress events and return quickly.


Cardinality

Loaded: unlimited.

Active: unlimited. Every loaded command is callable by name. Shadowing resolves at dispatch time; see Command Model.


State slot

Optional. Typical uses:

  • Per-command usage counters (non-sensitive analytics).
  • Remembered options (/model remembers the last chosen model).

See Extension State.


Validation severity

Optional by default. A command that fails to load skips with a warning; the session runs without it.

Config may escalate a specific command to critical (a workflow-essential command in a project).


Discovery path

Commands live in a commands/ folder under each configuration scope layer:

Layer Location
Bundled Ships with the package (bundled commands listed below).
Global ~/.stud/commands/…
Project <cwd>/.stud/commands/…

Ordering

Commands are an unordered category. Each command has a unique name; dispatch is by name.


Catalog and completion

Core exposes a side-effect-free command catalog to UIs and scripts:

Surface Meaning
commands.list() Returns name, aliases, description, argument hint, category, origin layer, source extension, and turn-safety metadata.
commands.complete(input, cursor) Returns pure suggestions for the current command-line draft.
commands.dispatch(name, args) Executes the command through the authoritative command bus.

list() and complete() are projection surfaces. They do not run command handlers, read secrets, or mutate session state. A TUI slash palette uses them to render dropdowns, but pressing Enter still dispatches through commands.dispatch().

Completion providers are allowed for command-specific arguments (for example /model listing configured provider/model pairs), but they must be side-effect-free and cancellable. Long-running discovery belongs in command state or cached metadata, not on the keystroke path.


Reload behavior

reloadBehavior: in-turn. Commands can be reloaded at any stage boundary; a reload that removes a currently-active handler completes the in-flight invocation, then drops the handler.


Interaction with core

A command reads and writes only through the Host API:

  • host.session — a session accessor scoped to the main session (the only session a command may act on).
  • host.events.publish(…) — announce command completion.
  • host.audit — commands that mutate security-relevant state audit their effect.
  • Interaction Protocol — a command may ask the user to confirm a destructive action.

A command does not:

  • Drive a turn. /model sets the current model; it does not send a request on the user's behalf.
  • Write to another extension's state slot directly.
  • Bypass Project Trust for newly-discovered extensions.

Bundled commands

Command Purpose
/model Switch the current model (fails fast on capability mismatch).
/provider Switch the current provider.
/params Get or set session-runtime provider params. Mutation profile is documented below.
/save Persist the session snapshot via the active Session Store.
/resume Resume a session by ID from the active Session Store.
/reload Re-run discovery and validation across scopes; apply reload per category.
/tools List tools with origin layer and sensitivity.
/ui List active UI extensions, roles, and default-TUI region contributions.
/sm attach Attach a named State Machine (between turns only).
/sm detach Detach the current State Machine.

/params mutation profile

Aspect Behavior
Reads /params with no arguments lists the effective params bag (after merging defaultParams and prior runtime overrides), with values redacted per the audit pipeline.
Writes /params <path>=<value> (repeatable) sets a runtime override. Validates against the active adapter's configSchema plus the common bucket; rejects wire snake_case, forbidden credential-shaped keys, and secret-shaped values.
Turn safety turn-safe — does not bump the per-turn revisionId; the override lands in session-runtime state and is visible to the next turn's request.
Validity vs SM stages Refused while an SM stage is mid-Act. Allowed between stages and at the orchestrator session level. See Event and Command Ordering.
Audit Every invocation lands as a redacted delta in Audit Trail (path + shape-marker, never raw value).
Event Emits ParamsChanged on the Event Bus (subscribers may rerender; nothing controls flow by subscribing).
Persistence Runtime overrides are not persisted to the session manifest. Resume re-applies defaultParams only and emits RuntimeParamsNotResumed when prior audit records show non-persisted changes.

See Bundled commands for the operator view.

/model with no arguments is interactive-UI friendly: a UI may open a model picker that lists the entries in the current provider's models[]. Selecting one dispatches /model <name>, which runs Capability Negotiation and leaves the current model unchanged on hard mismatch. To switch across providers, dispatch /provider <id> first; the new provider's active.model (or its first models[] entry by default) becomes current, and /model then iterates within that provider.

Prompt-backed slash entries are commands too. The prompt-command bridge reads the Prompt Registry, exposes registered prompts as catalog entries, renders the selected prompt through the registry, and inserts or submits the rendered content through the normal input path.

There is no bundled /interactor <id> selector in the multi-interactor model. UI extensions are enabled or disabled through UI extension config and /reload; every active UI with the interactor role participates in Interaction Protocol fan-out.


Security notes

  • A command can change the current provider, model, or attached SM. These are trust-adjacent actions. They audit their effect into the Audit Trail.
  • Project-shadowed commands are trusted only if the project is trusted. A malicious project may ship a command named /save that exfiltrates the session. The first-run Project Trust prompt is the primary guard.
  • Commands do not bypass security modes. A command that wants to run a tool goes through the tool invocation path; it does not acquire an independent capability to call tools.
  • Commands are auditable. Every command invocation lands in the audit trail with its full arguments (post-redaction).

Related pages


Changelog

1.0.0 — initial

  • Command contract as documented above. Flat-name identity; SM orthogonality; in-turn reload.

1.0.1 — /params bundled command

  • Bundled commands list gains /params. New "Mutation profile" subsection documents reads (lists effective params with redacted values), writes (validates against Provider Params; rejects wire snake_case, forbidden credential-shaped keys, secret-shaped values), turn-safety (turn-safe; refused while a stage is mid-Act), audit (redacted deltas), event (ParamsChanged), and persistence (not persisted; resume re-applies defaultParams).
  • No removal or renaming of pre-existing commands; the additions are additive on top of 1.0.0.

Introduction

Reading

Core runtime

Contracts

Category contracts

Context

Security

Runtime behavior

Operations

Providers (bundled)

Integrations

Reference extensions

Tools

UI

Session Stores

Loggers

Providers

Hooks

Context Providers

Commands

Case studies

Flows

Maintainers

Clone this wiki locally