@yylo/cli
v0.2.10
Published
YYLO (why-lo): task-driven AI subagent orchestration.
Maintainers
Readme
YYLO CLI
YYLO is a command-line orchestrator for coding agents, repeatable workflows, and receipt-backed repository changes. It is for developers who want a quick agent loop and for project operators who need typed task, validation, merge, and release-readiness boundaries.
- npm package:
@yylo/cli - Commands:
yyloandyy(equivalent);yplisyy pi --live - Source: yylo-dev/yylo
YYLO orchestrates work. YYLO Ledger is the independent Git-native Record/task store, and YYLO Benchmark is the independent evaluation/evidence package. yy ledger and yy benchmark delegate to those separately installed CLIs; they are not bundled alternate implementations.
Terminal
Live agent session — ypl (yy pi --live) runs an interactive terminal agent; tool calls, streamed output, and the status bar render in the terminal:

Execution summary — after each run the orchestrator prints iterations, tool calls, cost, and session ids:

Quick start: install to first successful command
Prerequisites: Node.js 20.10 or newer, npm, and Git.
npm install --global '@yylo/cli@latest'
yy --version
mkdir yylo-demo
cd yylo-demo
git init
yy init --task "Document the onboarding path" --subagent pi
pwd # execute explicitly; watch is an optional read-only observerA successful run prints the installed YYLO version, initializes .juno_task/, then emits a watch receipt with "state":"COMPLETED", "exit_code":0, and nonzero log_bytes. This canary does not contact a model provider. In an empty, unborn Git repository, yy init creates the initial workspace commit, keeps the original branch as the product target, and creates a detached protected integration-owner worktree under the user state directory. Existing or dirty repositories are never committed or rearranged by this bootstrap.
Inspect the initialized workspace and exact command surface:
yy info --json
yy doctor workspace
yy --helpdoctor workspace is intentionally nonzero when it finds an actionable topology problem; it never fetches or changes the workspace.
Stable and prerelease channels
The stable npm channel is @latest (0.2.2). Prereleases remain on @next:
# Stable
npm install --global '@yylo/cli@latest'
# Explicit prerelease
npm install --global '@yylo/cli@next'
# Exact version matching this checkout (once published)
npm install -g @yylo/[email protected]
npm view '@yylo/cli' version dist-tags --json
yy --versionThis unreleased source targets CLI 0.2.10, requiring Ledger 0.4.0 exactly for universal Record retrieval and storage-kind-prefixed IDs. Older Ledger 0.3.3, prereleases, and later versions are rejected before delegation. Install the matching Ledger explicitly once published; ordinary delegation does not auto-install a substitute. A source bump neither publishes these versions nor activates installed runtimes.
Pin an exact version in CI. Installing @next is an intentional prerelease choice.
The first guarded release-helper checkpoint is exact --set v0.1.0-rc.1; later releases must use their separately authorized exact SemVer.
Next: run an agent, manage a typed task, or build a managed workflow.
Install agent skills explicitly
YYLO skill content is versioned independently in the public
yylo-dev/yylo-skills repository and
is not bundled in @yylo/cli. This CLI source requires stable skills ^2.1.0, declared
in package.json as yyloSkills.version. Install the latest compatible stable
release, or pin an exact compatible version once it is published. Source version
2.1.0 is not evidence that this skills release is available:
yy skills install
yy skills install --version 2.1.0
yy skills update
yy skills statusOnly skills install and skills update access the network. Acquisition is
staged through npx skills add first and falls back to a shallow exact-tag Git
clone. The seven user-intent-first skills (artifact-yylo, ledger-tasks-yylo,
plan-ledger-tasks-yylo, ralph-loop-yylo, understand-project-yylo,
wiki-yylo, and workflow-yylo) are copied to .agents/skills,
.claude/skills, and .pi/skills. During install/update, unchanged receipt-owned
copies upgrade automatically without --force. Customized or unrecorded differing
canonical directories refuse before mutation; review before explicitly forcing
replacement. An explicit install/update retires a legacy YYLO skill only when its
local install record and current digest prove it unchanged; customized/unrecorded
legacy and unrelated skills remain preserved. Status flags these legacy copies
because they can still inject obsolete instructions; review them separately,
never infer cleanup authority from successful installation.
skills list and skills status inspect local bytes and receipts offline. Status
reports the required range and outdated releases even when their hashes match.
No compatible published release means installation fails without changing skills;
it never falls back to an old release or an unsupported future major. Installing
the CLI alone does not install/update skills, and scripts update does not own
skills. Maintainers must publish the reviewed immutable skill release before
shipping a CLI that requires it; publication remains separately authorized.
What YYLO owns
| Need | Public surface | Boundary |
| --- | --- | --- |
| Agent run | yy pi, yy start, and the agent aliases listed by yy --help | Provider credentials and model availability remain external. |
| Session continuity | continue, clone, branches, switch, continuity | Scope state is isolated and explicit; cleanup is planned and reversible. |
| Optional observation | watch status|await|follow | Read existing execution evidence; never launch, retry, cancel, or complete tasks. |
| Validation evidence | evidence run|status|await | Content-addressed task evidence tied to exact inputs. |
| Repository topology | info, where, doctor workspace, integration | Read-only discovery is separate from guarded sync/repair/push. |
| Feature lifecycle | task start|run|status|checkpoint|preflight|finish | Implementation belongs in the returned exact-base task worktree. |
| Protected delivery | merge status [TASK_ID], merge land TASK_ID, merge project TASK_ID | One-task native Git composition plus expected-old ref update; Ledger projection is separate and retryable. |
| Maintainer release | repository scripts/release-cli.sh | Prepare is read-only; publish needs separate authority. |
| Records/evaluation | ledger, benchmark | Transparent delegation to independently installed canonical packages. |
Run yy --help for the complete top-level inventory of your installed version; each listed command prints its own usage when invoked with -h. The old lifecycle command is removed; use typed task and merge commands.
Stable machine output
Use --format json|ndjson --raw on task, merge, and integration commands, or Ledger's -f json|ndjson --raw, for a strict stdout-only data channel. The capabilities command publishes command-specific projections in either machine format. See Machine output contract for the versioned envelope and migration policy.
Beginner agent workflow
Install the coding agent you intend to use and configure its provider credentials separately. Pi is optional and supports multiple providers:
npm install --global '@mariozechner/pi-coding-agent'
yy pi --help
yy pi --no-session 'Summarize this repository and make no changes'The final command may contact the configured model provider. --no-session prevents Pi session persistence; it does not disable provider usage.
For a reusable prompt or shell-sensitive text, prefer a file:
printf '%s\n' 'Explain the test layout. Do not edit files.' > prompt.md
yy pi --prompt-file prompt.md --no-sessionInteractive Pi uses the ypl shortcut:
ypl 'Inspect the current task'ypl expands to yy pi --live. Live mode requires an interactive terminal and enabled Pi extensions.
Controlled iterations
yy -s pi -m :gpt -i 3 -p 'Implement the next small verified increment'
yy loop -n 2 \
--step 'yy pi "Implement the next increment"' \
--step 'npm test'Quote prompts so the shell does not expand backticks or $() before YYLO receives them. -i bounds iterations inside an agent invocation; yy loop -n bounds the outer command workflow.
The loop's -n/--iterations bounds the outer command workflow; agent
-i/--max-iterations still bounds iterations inside an agent invocation.
Inline steps are repeatable:
yylo loop -n 5 \
--step 'yy pi "Implement the next increment"' \
--step 'yy cc "Inspect and improve your work"' \
--step 'npm test'For a reusable workflow, save the same contract as flow.yaml:
iterations: 5
continuity: iteration
on_error: continue
steps:
- run: yy pi "Implement the next increment"
- run: yy cc "Inspect and improve your work"
- run: npm testyylo loop --workflow flow.yamlEvery step receives one-based loop metadata through YYLO_LOOP_ID,
YYLO_ITERATION, YYLO_ITERATION_COUNT, YYLO_STEP, and YYLO_STEP_COUNT.
Ledger references in prompts
Use ##ABC123, ##readable-slug, or ##{readable-slug} to include a Ledger
Record by exact ID, slug, or retained alias. Existing ## ABC123 spacing works.
Tasks, Wiki/PDR/workflow documents, and artifacts share native Record lookup;
ambiguous identities are never resolved by guessing. Brace references next to
punctuation that could be part of a slug (for example ##{design.v2}.).
Missing references remain unchanged. Lookup errors produce a manual-resolution
warning; references do not execute workflows or recursively expand Record text.
Hydration is bounded to 32 distinct identities, a shared 30-second lookup budget,
and 64 KiB of inserted context (16 KiB per Record). Oversized Records carry a
retrieval command instead. Artifacts include metadata; only verified inline UTF-8
text up to 4 KiB is included. Binary, local, and external artifact bytes are not
automatically read or downloaded. Use yy ledger record get ID_OR_SLUG for
explicit retrieval. Immutable IDs remain authoritative for task lifecycle and
Record relations.
Models and project shortcuts
yy pi --help is the source of truth for shipped aliases. Current Pi shortcuts include:
| Shortcut | Resolved model |
| --- | --- |
| :luna | openai-codex/gpt-5.6-luna |
| :sol | openai-codex/gpt-5.6-sol |
| :gpt | openai-codex/gpt-6-astra (Pi default) |
| :astra | openai-codex/gpt-6-astra |
| :mini | openai-codex/gpt-5.6-terra |
| :sonnet | anthropic/claude-sonnet-4-6 |
| :opus | anthropic/claude-opus-4-6 |
Aliases are subagent-specific; for example, Pi and Codex do not share the same :mini mapping.
Set a per-project default:
yy pi set-default-model :solAdd project shortcuts in .juno_task/config.json:
{
"modelShortcuts": {
"pi": {
":team-default": ":sol"
}
}
}Project shortcuts are scoped to the selected subagent and can reference shipped or project shortcuts. Unknown targets, malformed data, and cycles fail with an actionable error. Managed Workflow Runner model authorization is separate: explicit selectors must be exact members of workflowModels; an unflagged yy pi continues to inherit the configured default.
Observable local commands
watch optionally observes existing run evidence without owning execution:
npm test # execute explicitly in the authorized workspace
# If an existing producer has published a watch-compatible run:
yy watch status RUN_ID
yy watch follow RUN_ID
yy watch await RUN_IDRUN_ID is an existing run identity, not one created by npm test. watch exec is retired. All watch operations are read-only, and interruption stops only the observer. Missing or malformed terminal evidence is not success. Process exit, semantic outcome, cleanup, and task completion are distinct; task finish verifies delivery. Historical run directories are preserved.
Managed workflows and evidence
Fresh yy init installs managed scripts, prompts, and wiki guidance under .juno_task/. Update checksum-managed assets with:
yy scripts updateLocally customized files are preserved and a package candidate is written to a managed-conflict path. --force is an explicit replacement operation and creates backups; inspect conflicts before using it.
Workflow Runner
Use a reviewed YAML workflow for ordered, repeatable steps:
./.juno_task/scripts/workflow_runner.sh \
--init-example agent-chain .juno_task/workflows/agent-chain.yaml
./.juno_task/scripts/workflow_runner.sh lint \
--workflow .juno_task/workflows/agent-chain.yaml
./.juno_task/scripts/workflow_runner.sh \
--workflow .juno_task/workflows/agent-chain.yaml --dry-run \
--print-output none --no-print-step-stdoutA workflow run retains rendered command identity, stdout/stderr, responses, session IDs, declared receipt hashes, attempts, and terminal manifests. --tmux creates an observer session; it does not detach the producer.
If a producer was interrupted, diagnose before mutation:
./.juno_task/scripts/workflow_runner.sh recover-attempt RUN_DIRECTORY --dry-run
./.juno_task/scripts/workflow_runner.sh doctor RUN_DIRECTORYRUN_DIRECTORY is the printed durable run path. Recovery resumes only the first invalid step after verifying unchanged successful evidence. Never edit historical manifests to make them reusable.
Task validation evidence
At a clean coherent task commit:
yy task checkpoint TASK_ID
yy evidence run TASK_ID
yy evidence status TASK_ID
yy evidence await TASK_IDThese commands plan and retain exact-input validation evidence. They do not finish or merge the task.
Typed task and merge flow
This section is for repositories initialized with the current controller/task policy. Run lifecycle commands from the registered metadata controller. Never edit the integration-owner checkout.
Deterministic delivery, external implementation
yy task start TASK_ID
# External agent edits, tests and commits in the returned worktree.
# Retain the returned token privately for gated commands:
yy task finish TASK_ID --lease-token <current-token>
yy merge land TASK_ID
# Only if automatic Ledger projection needs recovery:
yy merge project TASK_IDTASK_ID is a Ledger task ID. Start prepares an isolated workspace; finish
verifies the clean committed result and queues it. Merge uses native Git and
automatically records verified integration in Ledger. Tests and semantic review
remain explicit project checks. Task run/resume and automatic implementation
budget recovery are retired. No implementation model, retry or repair engine is
hidden behind watch. Process exit is not completion. For interrupted work,
preserve the existing workspace and inspect status/lease-status before explicit
continuation; do not automatically reset or replay historical attempts.
Choose Simple or Advanced
For a new Simple project, run git init, then yy init --mode simple to
initialize immediately. Add --directory PATH to select an existing Git root.
For guided setup, yy init asks a final mode question:
- Simple (recommended to start): code, notebooks, notes and Ledger in one
checkout. Agents share files;
yy task localis bookkeeping, not delivery. No implicit commits, worktrees or package installation. - Advanced: a separate controller, isolated task worktrees and managed merging.
Use yy init --interactive --mode simple to skip the mode question. Inline
initialization retains Advanced behavior; yy init "Build an API" --mode advanced
makes that explicit. Plain yy init --mode simple now writes files, without
confirmation or an external plan. Existing preview automation must add --dry-run
(zero writes) or use optional --plan-file then --apply-plan for reviewed plans.
Initialization installs no dependencies and does not certify agent readiness.
Normal initialization does not convert existing workspaces. For a settled registered
metadata-only controller, preview then apply a fresh Advanced → Simple copy:
yy init --mode simple --from-advanced /controller --directory /new-project --plan-file /external/conversion.json
yy init --mode simple --apply-plan /external/conversion.jsonSource workspaces remain unchanged. Old instructions and settings are retained
inactive for manual review. Simple → Advanced is not supported, including with
--force.
Read Simple and Advanced workspaces for exact commands,
readiness recovery, persistence, and shared-checkout limits.
Manual implementation path (managed mode)
yy task start TASK_ID
# Change directory to the worktree printed by start.
# Read its AGENTS.md/CLAUDE.md, implement, run focused tests, and commit.
yy task finish TASK_ID
yy merge status TASK_ID
yy merge land TASK_ID
yy merge project TASK_IDThe ordinary path is clean commit -> yy task finish TASK_ID.
Optional read-only yy task preflight TASK_ID diagnoses admission before finish;
it is not a prerequisite. Delivery remains a separate one-task operation.
Safety invariants:
task startfreezes the protected target SHA, creates a dedicated branch/worktree, and completes configured dependency hydration before reportingWORKING.- Product edits and focused tests occur only in that task worktree. Controller metadata and integration-owner product bytes are separate authorities.
preflightis optional and read-only.finishindependently enforces scope, dirty-byte, runtime, hydration, requirements, ownership, and selected-validation checks, requires a clean committed tip, and queues it; it does not merge.- Tests and semantic reviews are explicit project checks outside merge. Merge launches no models, chooses no reviewers, schedules no suites, and maintains no validation cache.
merge landselects one immutable task source, composes in a private detached candidate, and uses Git expected-old ref protection. A moved target requires recomposition and renewed candidate checks.- A conflict remains private to its task and cannot block an unrelated task. Preserve conflicts and unrelated dirty bytes; do not reset, stash, force, rebase, squash, or clean to bypass them.
- Git success and Ledger projection are separate. A projection retry never repeats Git integration and never blocks another independent land.
Observation commands are safe to repeat:
yy task status TASK_ID
yy task doctor TASK_ID
yy merge status
yy merge status TASK_IDMerge status reports only independently landable active tasks and always reports
model_calls: 0. Historical queue receipts remain immutable data, not an
executable compatibility surface.
Maintainer npm release
Normal tasks and yy merge own integration. After an ordinary version bump is integrated, maintainers use scripts/release-cli.sh prepare CLI_VERSION BENCHMARK_VERSION, obtain explicit publication approval, and then run the separate publish command. The CLI has no release command.
Controller generation upgrades
Recognized controller generations migrate automatically on first task/agent use;
controller-local scripts, policy and executable identity move together. Diagnose
without changing state using yy scripts generation doctor. Unknown/customized
bytes are preserved, and fallback requires a trusted retained executable plus
scripts. See upgrade, recovery and validation guidance.
Maintainer release preparation gates the exact npm tarball and binds its immutable
acceptance report; this does not authorize publication.
Receipt-bound workspace relocation
When an entire controller is moved between machines, do not rewrite lifecycle JSON or historical receipts by hand. From a clean physical controller checkout, create and review an external plan, apply it once, then verify its immutable receipt:
node juno-code/scripts/workspace-relocation.mjs plan --controller "$PWD" \
--map /old/controller=/new/controller --map /old/worktrees=/new/worktrees \
--output /secure/relocation-plan.json
node juno-code/scripts/workspace-relocation.mjs apply --controller "$PWD" \
--plan /secure/relocation-plan.json --receipt /secure/relocation-receipt.json
node juno-code/scripts/workspace-relocation.mjs verify --controller "$PWD" \
--receipt /secure/relocation-receipt.jsonThe plan binds the Git common directory, HEAD/ref, task-state hash, exact JSON pointers, and old/new physical roots. Apply refuses dirty, stale, tampered, symlinked, replayed, or missing-commit inputs and preserves historical evidence. Scan shipped active surfaces separately with node juno-code/scripts/check-path-portability.mjs; fixtures, immutable receipts, logs, generated output, lockfiles, and security canaries are explicitly excluded rather than rewritten.
Workspace roles and recovery
For installed consumers, read upgrade boundaries and troubleshooting before changing runtime bindings, tracked scripts, or Ledger. Registration repair and provenance repair are not complete cross-version upgrade transactions.
| Workspace | Use it for | Do not use it for | | --- | --- | --- | | Metadata controller | Ledger/task/merge/release orchestration and durable receipts | Product implementation or target integration edits | | Task worktree | Scoped implementation, focused tests, coherent commits | Private controller state or protected-target mutation | | Integration owner | Clean latest integrated reads and guarded target ownership | Feature edits, Kanban/session writes, or dirt cleanup |
Discover routing without changing it:
yy info --json
yy where controller
yy where integration
yy where target
yy where task TASK_ID
yy doctor workspaceRouting is registration-based and fail-closed; YYLO does not guess a nearby controller, switch branches, or clean a checkout to manufacture compliance.
For integration-owner inspection and guarded refresh:
yy integration status
yy integration syncintegration status observes. integration sync is a mutation: it refuses dirty/diverged/ambiguous state and verifies nested gitlink availability before moving anything. yy integration push is separate remote authority and must not be inferred from sync, merge, or release readiness.
Ledger and Benchmark delegates
Install canonical packages independently:
python3 -m pip install 'yylo-ledger==0.4.0'
# Exact Benchmark dependency for CLI 0.2.10, once separately published:
npm install --global '@yylo/[email protected]'
yylo-ledger --help
yy ledger --help
yylo-benchmark --help
yy benchmark --helpCLI 0.2.10 source requires Benchmark 0.2.0 exactly, whose thin lifecycle is case draft/create → run → evaluate → report, plus append-only disqualify. Older Benchmark versions are rejected before dispatch. These source changes do not publish Benchmark, update installed skills, or activate a new global runtime.
Delegation preserves arguments, stdin/stdout/stderr, cwd, exit status, and signals. It never silently chooses a checkout-local or legacy executable. See the Ledger repository and Benchmark repository for package-specific guidance and prerelease boundaries.
Completion and help
yy completion install
yy completion status
yy help
yy --helpCompletion supports Bash, Zsh, and Fish. Use the nested help for your installed release rather than copying an option from a different channel.
Source-checkout toolchain (advanced)
A monorepo checkout containing juno-code/ and juno_kanban/ can build isolated source aliases without replacing normal global yy:
./juno-code/scripts/juno-002-source-toolchain.sh install
export PATH="$PWD/.juno_toolchain/juno-002/bin:$PATH"
yy-juno-002 --version
juno-kanban-juno-002 --version
./juno-code/scripts/juno-002-source-toolchain.sh statusyy ledger and its labelled yy kanban compatibility alias use the exact Ledger compatibility policy 0.4.0. The isolated source aliases also enforce the legacy controller package compatibility range juno-kanban >=2.0.5,<3.0.0. Source selection, controller registration, and data history are separate boundaries:
./juno-code/scripts/juno-002-source-toolchain.sh register-controller /path/to/controller controller-branch
./juno-code/scripts/juno-002-source-toolchain.sh controller-status
./juno-code/scripts/juno-002-source-toolchain.sh rollback-selectionThe path and branch are placeholders. rollback-selection changes only isolated executable selection. Switching branches never downgrades or restores Ledger data. Back up and migrate a board through Ledger's reviewed data procedures.
| Source lane | Owns | Must not do | | --- | --- | --- | | Controller | Metadata, orchestration, prompts, and receipts | Product implementation or implicit ref changes | | Task checkout | Scoped implementation and tests | Protected-target mutation | | Integration owner | Guarded candidate integration | Kanban/session writes or unrelated edits | | Small fix worktree | Exact-base small product repair | Bypass task/review/candidate boundaries |
Development
git clone https://github.com/yylo-dev/yylo.git
cd yylo
npm ci
npm test
npm run typecheck
npm run build
node dist/bin/cli.mjs --helpThe monorepo may embed YYLO CLI alongside Benchmark and a Ledger submodule, but each public package has its own manifest, version, release contract, and registry channel. A source checkout version is not evidence that the same version was published.
Help and links
- npm: @yylo/cli
- Source/issues: yylo-dev/yylo
- Ledger: yylo-dev/yylo-ledger
- Ledger package: yylo-ledger on PyPI
- Benchmark: yylo-dev/yylo-benchmark
License
MIT.
