Skip to content
Development
Skill

/orc

This skill should be used when the user wants to talk to another LETS session of this repo - "ask the orchestrator", "ping the orchestrator", "what did the orchestrator say", "who is working", "message <name>", "tell <name>", "спитай у оркестратора", "запінгуй оркестратора", "що

From plugin
lets-workflow
1719 skills15 agents26 commands
Install
$ npx -y skills add restarter/lets-workflow --skill orc --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/orc

Context preview

The summary Claude sees to decide when to auto-load this skill.

This skill should be used when the user wants to talk to another LETS session of this repo - "ask the orchestrator", "ping the orchestrator", "what did the orchestrator say", "who is working", "message <name>", "tell <name>", "спитай у оркестратора", "запінгуй оркестратора", "що

SKILL.md

orc.SKILL.md
name: orc
description: This skill should be used when the user wants to talk to another LETS session of this repo - "ask the orchestrator", "ping the orchestrator", "what did the orchestrator say", "who is working", "message <name>", "tell <name>", "спитай у оркестратора", "запінгуй оркестратора", "що там оркестратор писав", "напиши в <name>", "хто ще працює". Resolves the peer, frames the message, sends only on the user's request, relays replies whole.

Orc - peer messages

Talk to the repo's orchestrator or a named peer session: `ask` / `ping` / `read` / `tell` / `who`. The ONLY place in LETS that sends a peer message. Go (`lets peers`) resolves, reads, frames and addresses; this skill composes and decides nothing on a peer's behalf.

> **IMPORTANT:** If the spec below invokes any deferred tool (e.g. `AskUserQuestion`, `SendMessage`), you MUST load and call it as specified. Never skip the call, never substitute a default answer of your own — the tool invocation is part of the contract. This is critical.

Args

`verb=ask|ping|read|tell|who target="<name>" [session=<sid> repo_index=<n>] text=<rest> [footer=none] [--yes]` - `target` is optional for `ask` / `ping` (default: this chat's orchestrator) and REQUIRED for `tell`, quoted. `--yes` (the user typed it) skips the Send? question in Step 4, not the message itself - see the Preview gate. `session` + `repo_index` name another project's session; only `/lets:hub` passes them. From natural language: map the request to a verb (a question for an answer -> `ask`; an FYI -> `ping` or `tell`; "what did X say" -> `read`; "who is working" -> `who`). Any other verb: say so and stop.

| verb | sends | waits | target required | |---|---|---|---| | `ask` | yes | notification, relayed when it lands | no (orchestrator) | | `ping` | yes | no | no (orchestrator) | | `tell` | yes | no | yes | | `read [N]` | no | no | no | | `who` | no | no | no |

Step 1: Resolve the target

Every later call addresses the returned **session id** (`target.session`), never the name again.

**Another project's session** (`session=` + `repo_index=` given) -> no resolution and no name match (a name matches only inside this repo): that session is the target, `target` its display name. Add `--repo-index <n>` to every `tell` and `tail` below; `frame` and `wait` take the session id as is.

**No explicit name** -> `lets peers orchestrator --session "$CLAUDE_CODE_SESSION_ID" --cwd "$LETS_PROJECT_ROOT" --json`:

| `source` | do | |---|---| | `bound` / `single`, `target.alive=alive` | that is the target | | `bound` with `refused[]` and no `target` | say `<name> cannot be addressed from this repo - <refused[0].reason>; <hint>` (when present) and send NOTHING - never re-route to another orchestrator | | `ambiguous` | ask which (below) | | `self` | this session IS an orchestrator: `ask` / `ping` need an explicit target; `who` lists its workers first | | `none`, no `reason` (or one not listed below) | say no orchestrator is alive, with each `degraded[]` reason - and, when `refused[]` is non-empty, name those `reason`s too | | `none` with `reason` `budget_exhausted` / `branch_unreadable` | resolution did NOT complete - this is NOT "no orchestrator is alive", it is "nothing is known yet". Say so with the reason and the `degraded[]` entry (`context`/`deadline_exceeded` or `git`/`branch_unreadable`), send NOTHING, and note that retrying may resolve it |

A `refused[].reason` of `target_in_other_repo` / `target_not_alive` / `target_unsendable` is final - never fall back to another orchestrator, never retry with a different verb.

`ambiguous`:

AskUserQuestion(
  questions=[{
    question: "This branch is not bound to an orchestrator. Which one? {more candidates, if over 3, listed here}",
    header: "Orchestrator",
    options: [ /* up to 3: label = candidate name, description = "{scope or no scope} - {alive}" */ ],
    multiSelect: false
  }]
)

Then, only when this branch's `.task` has a `task:` line and HEAD is not `{LETS_MERGE_BRANCH}`, ask in words whether to remember the pick for this branch; on yes `lets worktree task-state set --orc '<name>' --json` (single-quoted, `'\''` escaping) and name `rebound.from` in one line when reported.

**Explicit name** -> `lets peers who --json` (never add `--probe-orca`: Go consults Orca only under `LETS_LAUNCHER=orca`), match `name` exactly:

  • no row -> `no live peer named <name>` + degraded reasons; stop.
  • more than one -> `peer_ambiguous`: list them (name, session6, branch) and ask which.
  • a row with no `session` (an Orca-only agent, e.g. Codex): `read` and `who` only; `ask` / `ping` / `tell` answer `sending to non-Claude agents is not supported in v1`.
  • `send=none` -> say why (`reason`) and stop for sending verbs.

Step 2: who

`lets peers who --json` (an orchestrator: first `lets peers who --orc "<own name>" --json` for its bound workers, then the rest). Render:

## Peers
| role | name | scope / orchestrator | task | branch | state | last activity |
  • Mark the source: `via orca`, `via claude registry`, or both.
  • `alive=unknown` rows read `liveness unknown`.
  • One line per `degraded[]` entry: `claude registry: <reason> (<detail>)` / `orca: <reason>`. Both sources down: `Peers: unavailable - <reason>; <reason>`.

Step 3: read [N]

`lets peers tail --to-session <sid> --last N --json` (an Orca-only agent: `--to-terminal <terminal_id>`; "what did they say to me": add `--addressed-to-session "$CLAUDE_CODE_SESSION_ID"`). Render the turns verbatim - they are already redacted and capped - labelled as the peer's words, and name a non-zero `omitted`. A non-zero `truncated_bytes` means text inside the KEPT turns was cut too - say so, and offer `/lets:orc read` for the rest; `omitted: 0` no longer implies a complete answer on its own. Send nothing.

Step 4: Compose (ask / ping / tell)

1. `lets peers frame --to-session <sid> --kind <ask|ping|tell> --json` -> `header`, `msgid`, `sent_at`, `handoff_path`. 2. **ask** br

Read more
Ships withlets-workflow

A development workflow plugin for Claude Code Stop babysitting your AI. Start shipping with it.

Get the whole plugin

Other skills on lets-workflow.