@awak-app/simy-cli
v0.3.3
Published
Local SIMY executor for non-coding Local Tasks and Agentic Loop runs.
Readme
SIMY CLI
Local execution agent for SIMY Local Tasks and Agentic Loop runs.
For normal use, install SIMY globally and keep its background agent running:
npm install -g @awak-app/simy-cli
simy --daemonThis is the recommended installation because the daemon can safely install
patch releases and restart itself when no Agentic Loop task is active. To run
the interactive chat after installation, use simy.
For a one-time evaluation or source development, these modes remain supported:
npx @awak-app/simy-cli
npm start
simy --no-tui
simy --host https://simy.example.comThe published CLI connects to https://app.simy.one by default. Use --host
with an absolute SIMY Web origin for another deployment. Non-loopback hosts
must use HTTPS. SIMY_WEB_ORIGIN and the legacy SIMY_API_ORIGIN remain
available for automation, but the command-line flag takes precedence.
The CLI starts a loopback HTTP agent on a random available port, keeps a 48-hour, origin-scoped local session, and opens a native coding chat. The first chat message creates the remote audit ledger and starts the local Agentic Loop state machine; SIMY Web mirrors the lifecycle but is not required as the task entry point. The CLI also accepts backend-issued launch challenges for Web-led runs. It builds the requirement charter, runs Codex or Claude Code, audits structured completion evidence, and re-instructs the executor within the configured attempt budget.
Before Web creates an Agentic Loop, it classifies whether the request actually needs a managed PR, verification, evidence, and merge lifecycle. A bounded ordinary task is sent to CLI 0.2.2 or newer through the one-time direct executor instead. CLI independently recomputes the guardrail, restricts read-only work at the Provider command boundary, and permits exactly one Provider invocation. It does not create an Agentic Loop ledger, audit session, or retry lifecycle for that task.
Local Tasks
CLI API contract v9 promotes non-coding work to a first-class Local Task runtime. A Local Task is separate from Agentic Loop: it runs one bounded Codex or Claude Code session without Git branches, pull requests, audits, or automatic Provider retries. Knowledge-work deliverables use an isolated task sandbox by default, so they do not require a repository.
POST /v1/local-tasks/start accepts JSON or the same verified multipart
attachment envelope used by Agentic Loop and requires a stable
Idempotency-Key. Repeating the same request returns the original task; using
the same key for different content returns
LOCAL_TASK_IDEMPOTENCY_CONFLICT. GET /v1/local-tasks/reconcile with the same
header recovers a task when the original response was lost. Only the key hash is
persisted. Task state, verified inputs, and the event log stay under
~/.simy/tasks/<task-id>/. Tasks that do not need a Git
repository run in ~/simy/<task-id>/, with generated files in its outputs/
directory. The public snapshot exposes this user-facing workspace as
workspace_display_path without exposing internal state paths. Set
SIMY_LOCAL_TASK_WORKSPACE_ROOT to override the default workspace root.
Local Tasks provide:
GET /v1/local-tasks/<id>for the current structured snapshot;GET /v1/local-tasks/reconcilefor request-key reconciliation;GET /v1/local-tasks/<id>/streamfor live Server-Sent Events;POST /v1/local-tasks/<id>/controlwith{"action":"stop"};GET /v1/local-tasks/<id>/artifacts/<artifact-id>for a verified output;- one Provider invocation, a configurable Provider-token safety budget, and a bounded runtime timeout;
- restart-safe terminal persistence. An interrupted active task fails closed after CLI restart and is never replayed automatically.
Interactive Pipelines can use the same daemon worker for a local_task node.
The CLI still invokes the selected Provider exactly once. Before the node is
reported as successful, every output file is re-verified, uploaded through a
task-bound short-lived URL, and committed only after SIMY rechecks its byte
size and SHA-256 digest. Ordinary My AI Local Tasks keep their existing local
verified-download behavior. Scheduled or unattended Pipeline runs are not
allowed to select a desktop implicitly.
Web and Backend may opt into durable_local_task_steps for a versioned
multi-step Local Task. The daemon then claims and executes one closed-schema
step at a time (maximum eight), with an independent Provider invocation
boundary per step and aggregate step, token, and runtime budgets. The task
workspace is stable for the turn while each lease attempt has its own local
record. A step that crossed its Provider boundary is never replayed
automatically.
Plan initialization uses a two-phase claim. Web stores an authoritative
execution_spec.controlled_plan; the CLI validates that its Provider,
operation, permission, repository, approval target, and aggregate budgets
cannot exceed the enclosing execution spec, then submits the exact plan for
Backend persistence. The CLI never asks a Provider to infer or expand a plan.
Older one-shot requests receive a deterministic one-step compatibility plan.
Human approval and unknown Provider results are distinct non-executable
dispositions. Neither holds a Provider process, heartbeat lease, or update
work reservation. Only bounded summaries and verified artifact references from
completed steps may enter the next step's context. Unknown plan fields,
unscoped approvals, unsafe paths, and Provider-supplied risk metadata fail
closed. The original local_task_execution.v1 one-shot path remains available
unchanged for clients that do not negotiate this feature.
Contract 10 additionally advertises bounded_local_task_subtasks. Backend
admits at most two Provider children at once from a closed parallel_reads
plan with 2-4 source-bound candidates. When Crew declines or times out, the
same v2 contract can admit one serial_uploaded read-only child for 2-4
uploaded sources; this fallback never routes those uploads through the v1 CLI
staging materializer. The CLI never prefetches beyond an available execution slot:
each child starts only after a fenced server claim and an explicitly confirmed
invocation boundary. Children inherit the parent Provider and model, run in
separate read-only task sandboxes, receive only verified immutable SIMY uploads,
and cannot use mutation tools or nested delegation. Downloaded bytes are checked
against the claimed size and SHA-256 digest, then exposed through a mode 0400
file without revealing the storage URI to the Provider.
Cancellation uses one pool-wide abort signal and prevents new claims. Unknown
invocation or final-status boundaries are never replayed automatically. Sibling
fan-in summaries remain explicitly untrusted data, and all lease, generation,
budget, usage, and elapsed-time bigint fields cross the JSON boundary as
canonical decimal strings. The contract 9 durable_local_task_steps path
remains serial and unchanged.
External side effects such as sending messages, submitting forms, uploading, or
purchasing are outside this MVP. The router rejects them instead of silently
granting broad permissions. The legacy /v1/direct-execution/* contract remains
available for older Web clients.
CLI updates
The CLI checks the npm registry at startup and once per hour while it is
running. A daemon installed with npm install -g automatically installs stable
patch releases only after a strict idle check confirms that there is no active,
paused, blocked, or human-waiting task, executor child process, or pending
ledger write. It stops accepting new work during installation, starts the new
daemon, verifies its version and local health handoff, and only then closes the
old process.
Foreground, npx, source-checkout, fixed-port, minor, and major updates are not
restarted silently. The CLI instead displays the exact command a normal user
can run:
npm install -g @awak-app/simy-cli@<version> && simy --daemonUse --no-auto-update or SIMY_AUTO_UPDATE=0 to disable background checks.
The current update state is also exposed by GET /v1/health as cli_update.
Auto-update E2E screenshots are generated locally under
.artifacts/cli-auto-update/; this ignored directory must not be committed.
Executor compatibility
SIMY checks the selected executor with --version before an Agentic Loop can
start. The currently validated compatibility floors are Codex 0.144.0 and
Claude Code 2.1.200. A missing, older, or unversioned executable fails the
preflight and returns the installed version, required version, and a recovery
command to SIMY Web. Update Codex with
npm install -g @openai/codex@latest; update Claude Code with claude update.
Your Desktop executor
SIMY CLI is the desktop execution target, shown to users as Your Desktop.
It can run either Codex or Claude Code as a child process inside the verified
local Git checkout. Device heartbeats advertise both desktop provider
capabilities and their installed/required versions. Preflight and every standard
provider dispatch fail closed unless the selected binary is compatible; there
is no fallback to an unverified executable name.
Legacy local requests without execution_target continue to resolve to
desktop. A request marked for the hosted simy target is rejected by the
local CLI boundary so hosted and desktop execution cannot be confused. The
target and bound device id are preserved in the run Charter, redacted Web
ledger snapshot, and restored run.
Blocked recovery contract
Every waiting_human, blocked, or failed lifecycle event includes a
versioned detail.recovery object. It provides a stable reason code, a
user-safe explanation, a primary action, executable action metadata, and
bounded technical details. Preflight failures use the same contract for
executor updates, repository selection, and CLI reconnection. Web clients must
validate the action type before rendering or executing it; raw local error text
is not copied into the recovery contract.
Provider token budget
Each run accepts a configurable token_budget (or the explicit
provider_token_budget alias) from 1 to 10,000,000 Provider tokens. The default
is 250,000. Provider tokens are the Codex or Claude Code usage reported for the
run; they are a safety limit and are not billed as SIMY tokens.
When a run reaches this limit, its recovery contract suggests a higher rounded
limit. SIMY Web can edit that suggestion and call
POST /v1/agentic-loop/:run_id/provider-token-budget with
provider_token_budget. The CLI persists the higher limit and resumes the same
run. SIMY token consumption remains a separate platform billing record.
Interactive console
Running simy in a terminal opens the Agentic Loop chat. It discovers the
current GitHub repository and branch, selects an available executor, and keeps
the composer active so a natural-language request can start immediately. Each
run appears in a selectable list with its lifecycle state, process ID, and a
bounded live transcript. Use --no-tui for the foreground HTTP-agent behavior
or --daemon to run without the chat.
The console supports these direct controls:
Up/Downorj/k: select a run.i: enter human guidance. Guidance submitted while a provider process is active is queued for the next executor handoff; a waiting run resumes as a new attempt in the same lifecycle record.p: pause or resume the selected local process on POSIX systems.r: refresh pull request, review, and CI evidence.x, thenx: stop the selected run with confirmation.?: show the command reference;q: leave the console.
Use /new, /repo <owner/name>, /branch <name>, and
/executor <codex|claude> to compose another task. /attach <path> adds a
verified local file reference without copying or deleting the source file.
Slash commands also provide explicit human gates: /continue, /approve,
/criteria, /checks, /recheck, /pause, /resume, and /stop. Approval
notes, acceptance criteria, and required checks are recorded in the run charter
before orchestration continues. The console does not pretend that noninteractive
codex exec or claude -p accepts mid-process stdin; active-run guidance is
shown as queued until the next executor attempt.
Structured run snapshots and process events are persisted remotely. Executor instructions and the latest bounded log lines are redacted at both the CLI and Web ingestion boundaries before they are persisted with SHA-256 integrity hashes. Raw transcripts, environment values, and unbounded stdout are never stored remotely; live raw output is streamed directly from localhost to the active Web UI. The persisted snapshot records the redaction policy and whether input or output was redacted or truncated.
The local PR lifecycle is intentionally separate from deployment:
- Classify request risk and build a requirement charter.
- Require explicit acceptance criteria plus an approved design summary for high-risk work.
- Run the coding executor and verify its result against local Git evidence.
- Run a separate AI audit session without granting it an implementation role.
- Mark the result
pr_ready_for_reviewwhile GitHub checks or peer approval are pending. - Mark it
merge_readyonly after the observed PR head/base, CI checks, merge state, and human approval all pass.
The Web UI can refresh review and CI evidence with
POST /v1/agentic-loop/:run_id/recheck. Passing the local implementation gate
does not by itself make a PR merge-ready.
Start simy from the selected repository or a workspace containing it. Set
SIMY_REPO_ROOT when repositories live under a different root. The CLI
verifies the checkout's GitHub origin before starting an executor.
The real-PTY console E2E can be rerun with npm run test:e2e:console. It starts
from an empty CLI chat, types repository, branch, executor, attachment, and task
input through a pseudoterminal, creates the Web ledger, spawns real child
processes, and exercises HIL plus lifecycle controls. It regenerates the
screenshots, terminal frames, raw transcript, and SHA-256 manifest under
docs/pr-evidence/cli-agentic-loop-console/.
Publishing
Publishing is handled by GitHub Actions in .github/workflows/publish.yml.
- Every push tag matching
v*.*.*runs checks and publishes to npm. - Manual workflow runs perform the same checks; set
publish=trueto publish. - The repository must define an
NPM_TOKENsecret with publish access to@awak-app/simy-cli. - The package check inspects the final npm tarball contents and fails if any source map file would be published.
