Skip to content

One command installs the agent rules where agent tools read them #157

Closed
2 of 2 issues completed
Closed

Description

@V3RON

Request: #154

Problem

Simlock is advisory. It works only when every agent knows the rules: lease first, never call simctl or adb directly, build iOS apps so they can be installed on Simlock's simulators. Today those rules live on the website, and the operator copies a sample block into each agent's AGENTS.md or CLAUDE.md by hand, on each machine or project, and again whenever the rules change. That sample block is already out of date: it never mentions agent-device, which is how most agents now use Simlock. A missing or stale copy is invisible until an agent breaks another agent's device.

Who it is for

  • An agent of any kind (agent-device first, then the simlock CLI, then MCP) that needs a device and must know the rules before it touches one.
  • An operator setting up Simlock for agents that run under Claude Code or Codex, for themselves on one machine or for a whole team through one project.

Outcome

  • One command, simlock instructions, prints the full rules for the installed Simlock version as one Markdown text. It covers agent-device, iOS builds, the simlock CLI and MCP, one section each, and only what works today.
  • An MCP client gets a short version of the rules automatically when it connects, and can read the full text as a resource.
  • One command, simlock setup, installs a small simlock skill for Claude Code and Codex. The skill says what Simlock is, when to use it, how to check it is set up, and to run simlock instructions for the rules. The rules are never copied into the skill, so an upgrade needs no re-run.
  • In a terminal, setup asks whether to install for this user or this project (user by default), and per tool whether to connect Simlock's MCP server too (no by default). Flags answer both questions for scripts.
  • The website docs teach this flow in place of the hand-copied block.

How it works for the user

flowchart TD
  Op[Operator runs simlock setup] --> Scope{Terminal?}
  Scope -->|yes| AskScope[Asks: this project only? y/N]
  Scope -->|no, or --json| User[User scope unless --project]
  AskScope --> Write[Writes the simlock skill for each tool found]
  User --> Write
  Write --> Refuse{A file or symlink where the skill directory goes?}
  Refuse -->|yes| Stop[SETUP_REFUSED, exit 2, nothing written]
  Refuse -->|no| Mcp{MCP: --mcp, or yes at the prompt?}
  Mcp -->|yes| Add[Runs the tool's own mcp add]
  Mcp -->|no| Report[Prints what it wrote, replaced, skipped]
  Add --> Report
  Report --> Agent[Next agent session loads the skill]
  Agent --> Who[Agent runs simlock whoami]
  Who --> Rules[Agent runs simlock instructions and follows it]
Loading

Before:

$ simlock instructions
{"error":{"code":"USAGE","message":"Unknown command: instructions (run `simlock --help` for usage)"}}

After:

$ simlock instructions
# Using Simlock to share iOS simulators and Android emulators
...
## Rules for every agent
...
## agent-device
...

$ simlock setup
Install only for this project (not every project)? [y/N]
Also connect Simlock's MCP server to Claude Code? [y/N] y
claude-code  skill  wrote      /Users/me/.claude/skills/simlock
claude-code  mcp    connected
codex        skill  skipped    /Users/me/.agents/skills/simlock  (Codex not found here; pass --tool codex to install anyway)

Examples

Input Today After
simlock instructions USAGE, exit 2 the rules on stdout, exit 0
simlock instructions --json USAGE, exit 2 {"instructions":"<the same text>"}
simlock instructions --bogus USAGE, exit 2 USAGE, exit 2
simlock setup in a terminal, both answers default USAGE, exit 2 skill installed for the user in each tool found, no MCP
simlock setup --project --tool codex USAGE, exit 2 ./.agents/skills/simlock/SKILL.md
simlock setup --tool cursor USAGE, exit 2 USAGE, exit 2, nothing written
simlock setup --mcp, claude not installed USAGE, exit 2 skill installed, mcp skipped (claude not found), exit 0
simlock setup, a file at ~/.claude/skills/simlock USAGE, exit 2 SETUP_REFUSED, exit 2, nothing written

What could go wrong

  • The rules say something Simlock no longer does, and an agent follows them. Likely over time; each later change to the commands has to update its section.
  • An agent starts without the skill because setup wrote it where the tool does not look. Unlikely: paths come from the tools' own source.
  • setup changes a file outside the simlock skill directory, or a tool's MCP config the operator did not agree to. Unlikely: MCP is connected only after a yes or --mcp, and through the tool's own command.

Words used

  • rules text: the Markdown simlock instructions prints, e.g. its ## agent-device section.
  • section: one ## part of the rules text for one way an agent uses Simlock (agent-device, the CLI, MCP), plus the rules for every agent.
  • router skill: the short SKILL.md setup installs. It points at simlock instructions and holds no rules itself.
  • skill directory: <tool's skills directory>/simlock, e.g. ~/.claude/skills/simlock. Simlock owns it whole.
  • scope: where setup installs. User: under the home directory, for every project. Project: under the current directory, to commit with the app.
  • server instructions: the text an MCP server sends when a client connects. Claude Code adds it to the agent's prompt, cut at 4096 characters by default.

Non-goals

Completion conditions

  • simlock instructions prints the rules on stdout, exit 0, without connecting to or starting a daemon; --json prints the same text in one JSON object. Checked by e2e.
  • The rules text has the sections Rules for every agent, agent-device, iOS builds, simlock CLI and MCP, in that order, and each names what the Behaviours table lists. Checked by unit tests that read the expected values from the code that defines them.
  • The text and the skill name no file path in this repository.
  • An MCP client that connects gets server instructions of at most 4096 characters, and can read simlock://instructions, equal to what the CLI prints. Checked by e2e.
  • On a machine with no Simlock files, simlock setup for Claude Code and then for Codex, followed by starting each tool, gives the agent the simlock skill without a paste. Checked by hand per tool, and by an e2e test that finds the skill at the documented place.
  • The user scope writes only under the home directory; the project scope only under the current directory. Nothing outside the skill directories and their missing parent directories changes, except MCP config written by the tool's own command after a yes or --mcp.
  • Re-running setup leaves the same files.
  • No command of this feature connects to or starts the daemon.
  • The website's CLI reference and "Connect your agent" page describe both commands; the hand-copied rules block is gone.

Open questions

Decisions

  • None needs an ADR: every choice is local to one task and cheap to reverse. Recorded here:
    • The rules text is one Markdown text with fixed ## sections, one per surface. A later feature changing a surface edits its section in the same PR (documentation rule 9 covers it: the text is CLI output).
    • The skill is a router, not a copy, so the rules always match the installed Simlock.
    • setup connects MCP only through claude mcp add / codex mcp add. codex mcp add has no project scope, so a project-scope run never connects MCP for Codex.
    • Codex skills go to .agents/skills/simlock (user: under the home directory; project: under the current directory). That is where Codex 0.163.0 reads them; ~/.codex/skills is deprecated.

Shared values

Value or state Rule Written by Read by Source
Command simlock instructions Prints the rules text; --json wraps it as {"instructions": <text>}; never contacts a daemon #147 #620 (the router tells the agent to run it) #147 F1, F2
Section headings of the rules text ## Rules for every agent, ## agent-device, ## iOS builds, ## simlock CLI, ## MCP, in that order #147 #147 (MCP server instructions take the first and last), #620 (the skill holds none of them), later features this spec
simlock whoami as the setup check The rules and the router name it as the way an agent checks it is set up #147, #620 agents #620 F5
Gateway-exempt commands instructions and setup join daemon start, daemon install, daemon uninstall, config set, mcp #147 adds instructions, #620 adds setup src/cli/index.ts GATEWAY_EXEMPT_PATHS #147 F6
Website pages reference/cli.mdx, getting-started/connect-your-agent.mdx #147 adds the instructions section and replaces the hand-copied block; #620 adds the setup section and the setup step #147, then #620 users #147 F9

Behaviours

Behaviour (invoker, action, what it sees) Seam Cases Task
A user runs simlock instructions and gets the rules text, no daemon e2e/agent-instructions.test.ts (fast) plain → text, exit 0, no socket; --json → one object equal to the text; --bogus and a positional → USAGE exit 2; --help → usage line #147
A user passes --gateway or --local to simlock instructions on a machine with no gateway and still gets the text src/cli/index.test.ts --gateway; --local #147
A reader of the rules text finds every section and required item src/instructions/index.test.ts headings in order; each required item of #147's content table; every refused verb from the drivers' constants; exit codes 10, 11, 13, 14 from their definitions; the agent-device lease-ended message from its constant; the website URL last #147
The rules text and the router skill name no path in this repository src/instructions/index.test.ts rules text; MCP server instructions; skill (added by #620) #147, #620
An MCP client connects and gets the server instructions, and reads the resource e2e/mcp-session.test.ts getInstructions() is Rules for every agent + MCP + pointer, at most 4096 characters; simlock://instructions is text/markdown and equals CLI output; every listTools name appears in the text #147
An operator runs simlock setup and gets the skill in the right place for the scope src/instructions/setup.test.ts user → ~/.claude/skills/simlock/SKILL.md, ~/.agents/skills/simlock/SKILL.md, nothing under cwd; project → the same under cwd, nothing under home #620
setup picks tools src/instructions/setup.test.ts none named: only tools found, others skipped; a file named .claude → skipped; --tool codex with no .codex → installed, directories created #620
setup asks in a terminal and never blocks a script src/instructions/setup.test.ts prompt yes → project; prompt default → user; --user/--project → no scope prompt; no terminal → user, no MCP; --json → no prompt #620
setup re-run replaces only its own files src/instructions/setup.test.ts second run → replaced, same bytes; a stale file in the skill directory → removed; SKILL.md that is a directory → replaced by the file #620
setup refuses a file or symlink where the skill directory goes src/instructions/setup.test.ts + src/cli/index.test.ts file; symlink; refusal in the second tool → nothing written for the first; CLI → SETUP_REFUSED exit 2, stdout empty #620
setup connects MCP through the tool's command src/instructions/setup.test.ts (scripted process runner) add ok → connected; Claude Code already exists → already; other add failure → failed with its message; no answer in 30 s → failed; tool not on PATH → skipped; Codex at project scope → skipped; --no-mcp → nothing run #620
An agent reads the router skill src/instructions/index.test.ts front matter name: simlock and a description; body names simlock whoami and simlock instructions; body holds none of the rules sections; ends with the website URL for when simlock is missing #620
setup prints its report src/cli/index.test.ts human lines per tool and step; --json one SetupReport object; an MCP failure → report, then SETUP_MCP_FAILED, exit 1; --tool bogus, two --tool, a positional, --mcp with --no-mcp, --user with --project → USAGE exit 2, nothing written; --gateway with no gateway → runs; --help → usage #620
An operator runs simlock setup for real and the skill lands where the tool reads it e2e/setup.test.ts (fast) --tool claude-code --mcp with temp HOME and a fake claude on PATH → SKILL.md under HOME, the fake got mcp add -s user simlock -- simlock mcp, no socket; --project --tool codex → .agents/skills/simlock/SKILL.md under cwd, nothing under HOME #620

Tasks

flowchart LR
  T147["#147 rules text, instructions, MCP"] --> T620["#620 simlock setup"]
Loading

Completion conditions: the first four and the last are delivered by #147's Done when, except their skill and setup halves (no repository path in the skill; the website describing setup), which #620 delivers with the others.

Open work in the same area:

Written by an agent.

Activity

  1. added
    feature:specSpec in progress, business and technical together.
    on Sep 28, 2026
  2. V3RON commented on Sep 28, 2026

    @V3RON
    ContributorAuthor

    Spec updated: Who it is for, Outcome, Non-goals and Completion conditions amended from the interview; Open questions emptied.

    Written by an agent.


    Generated by Claude Code

  3. V3RON commented on Sep 28, 2026

    @V3RON
    ContributorAuthor

    Spec updated: Decisions and Technical spec added; the command is simlock setup, no ADR.

    Written by an agent.


    Generated by Claude Code

  4. added
    feature:readyNo sub-issues; one PR delivers the whole feature.
    and removed
    feature:specSpec in progress, business and technical together.
    on Sep 28, 2026
  5. self-assigned this
    on Sep 28, 2026
  6. added a commit that references this issue on Sep 29, 2026
    9f509b3
  7. github-actions commented on Oct 2, 2026

    @github-actions

    Claim released: no activity for 3 days. The label is unchanged; the next agent starts from the branch and the last handoff.

  8. github-actions commented on Oct 5, 2026

    @github-actions

    Claim released: no activity for 3 days. The label is unchanged; the next agent starts from the branch and the last handoff.

  9. github-actions commented on Oct 9, 2026

    @github-actions

    Claim released: no activity for 3 days. The label is unchanged; the next agent starts from the branch and the last handoff.

  10. github-actions commented on Oct 12, 2026

    @github-actions

    Claim released: no activity for 3 days. The label is unchanged; the next agent starts from the branch and the last handoff.

  11. removed
    feature:readyNo sub-issues; one PR delivers the whole feature.
    on Oct 16, 2026
  12. added
    feature:specSpec in progress, business and technical together.
    on Oct 16, 2026
  13. V3RON commented on Oct 16, 2026

    @V3RON
    ContributorAuthor

    Spec updated: Technical spec moved to task #620 (task:draft); Shared values and Tasks added; back to feature:spec until #620 is ready.

    Written by an agent.

  14. V3RON commented on Oct 23, 2026

    @V3RON
    ContributorAuthor

    Spec updated: Problem, Who it is for, Outcome, Non-goals and Completion conditions rewritten for the router skill, MCP connect and agent-device; Decisions, Shared values and a Behaviours table added; #147 is now this feature's first task.

    Written by an agent.

  15. added
    feature:plannedSplit into tasks. Never picked up itself.
    and removed
    feature:specSpec in progress, business and technical together.
    on Oct 23, 2026
  16. V3RON commented on Oct 23, 2026

    @V3RON
    ContributorAuthor

    Note from #961 (per-platform lease limits, planned): lease.maxPerRequester may become {"ios":1,"android":1}, so one agent can hold an iOS and an Android lease at once. The instructions text in #147 ("you already hold a lease or have a request queued") stays true per platform; no change needed unless you want it to mention the per-platform form.

    Written by an agent.

  17. V3RON commented on Oct 23, 2026

    @V3RON
    ContributorAuthor

    Delivery run

    Merged: none (stopped before the gate, as the maintainer asked)
    Ready in stack #970: #960 (#147) → #969 (#620), both reviewed (2 rounds each, 3 blocking findings, all fixed)
    Parked: none
    Waiting: the stack's sync and gate (stack-sync.sh 969, then merge-pr.sh 969); the by-hand Claude Code / Codex check on #969
    Decided: none

    Written by an agent.

  18. github-actions commented on Oct 24, 2026

    @github-actions

    All 2 sub-issues are closed. If the completion conditions hold on main, close this feature and flip its ADRs to Accepted.

  19. github-actions commented on Oct 24, 2026

    @github-actions

    All 2 sub-issues are closed. If the completion conditions hold on main, close this feature and flip its ADRs to Accepted.

  20. V3RON commented on Oct 24, 2026

    @V3RON
    ContributorAuthor

    All sub-issues are closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature:plannedSplit into tasks. Never picked up itself.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions