Gremlins: launch against a remote GitHub repo
Context
Today gremlins launch <pipeline> runs against the current working directory. Users increasingly want to launch a gremlin against another GitHub repo — without first cloning it, switching shells, or polluting their workspace. The common case is: "I know a pipeline I want to run, I know the repo to run it on, just do it."
Goals
- Launch a gremlin against an arbitrary GitHub repo with a single command.
- Don't require the user to clone, cd, or otherwise prep the target repo.
- Stay close to the existing
gremlins launch syntax — no new subcommand, no new mental model.
- Make the common case (pipeline lives in the target repo) ergonomic by not forcing the user to name the repo twice.
Non-goals
- Read-only / fork-and-PR flows. Assume the user has push rights to the target repo.
- Hosts other than GitHub.
- Managing the temp clone's lifecycle beyond "create or reuse." No automatic cleanup, no GC.
- Pipeline discovery (listing pipelines available in a remote repo). User names the pipeline explicitly.
Users
A developer who wants a gremlin to act on a repo other than the one they're currently in — for example, running a project's published .gremlins/*.yaml pipeline against that same project from anywhere on disk, or running a personal pipeline against someone else's code.
Behavior
Invocation forms
Both work, and match existing gremlins launch shape:
- Pipeline URL only —
gremlins launch <github-pipeline-url> --instructions "...". The repo is inferred from the URL; no --repo needed.
- Local pipeline + remote repo —
gremlins launch <local-pipeline-path> --repo <github-repo-url> --instructions "...". Pipeline comes from the user's machine; gremlin runs against the remote repo.
- Both —
gremlins launch <github-pipeline-url> --repo <github-repo-url> .... Explicit --repo wins; the pipeline URL is used only to fetch the YAML.
Pipeline URL resolution
Permissive: any GitHub URL form that can be resolved to a pipeline YAML works — blob/, raw/, tree-pointing, repo-shorthand with a path, etc. If the URL can't be resolved to a YAML file, fail with a clear error. No silent fallbacks.
Target repo + ref
The --repo value (or the repo inferred from a pipeline URL) may include a ref. The gremlin runs against that ref. Without a ref, the repo's default branch is used.
Working tree
Under /tmp/gremlins/, each target repo has a single shared shallow clone keyed off repo identity. Each launch gets its own worktree off that clone, keyed by gremlin id. The gremlin runs in its worktree.
Clone is reused across launches. First launch against a repo creates the shallow clone; subsequent launches reuse it (fetching as needed to satisfy the requested ref). If the clone is missing/corrupt/has the wrong remote, it's recreated.
Worktree is per-launch. Brought up at the ref --repo indicates, clean. Never shared between live runs.
Concurrency. The shared clone is locked during the fetch + worktree-creation step so concurrent launches against the same repo serialize through that critical section. Once each launch has its worktree, they proceed in parallel without contention.
Lifetime: clone and worktrees are left in place after the gremlin finishes, success or failure. The OS (or the user) cleans /tmp.
What the gremlin does
Whatever the pipeline says. From the pipeline's point of view, it's running in a normal git checkout of the target repo with push rights — opening PRs, producing diffs, writing reports, etc. all behave as they would in a local checkout.
Constraints
- Push access to the target repo is assumed (user's existing gh credentials).
- Shallow clone — don't pull full history unless the pipeline needs it. (If a pipeline genuinely requires deep history, that's a pipeline concern, not this feature's.)
- Must not interfere with the user's other checkouts of the same repo elsewhere on disk.
Acceptance criteria
gremlins launch <github-pipeline-url> runs the named pipeline against the repo that URL points into, with no --repo flag.
gremlins launch <local-pipeline> --repo <github-url> runs a local pipeline against the named remote repo.
- A ref embedded in either URL is honored; absent a ref, the default branch is used.
- A second launch against the same repo reuses the existing shared clone and gets its own worktree at the requested ref.
- Concurrent launches against the same repo serialize through clone/worktree setup, then run in parallel without corrupting each other.
- An unresolvable pipeline URL fails fast with a clear message.
- A gremlin that opens a PR against the remote repo succeeds end-to-end (clone → work → push → PR).
Auth
Piggyback on whatever GitHub auth is in the environment (same as today). Used for both fetching the pipeline YAML and for the clone/push against the target repo.
Gremlins: launch against a remote GitHub repo
Context
Today
gremlins launch <pipeline>runs against the current working directory. Users increasingly want to launch a gremlin against another GitHub repo — without first cloning it, switching shells, or polluting their workspace. The common case is: "I know a pipeline I want to run, I know the repo to run it on, just do it."Goals
gremlins launchsyntax — no new subcommand, no new mental model.Non-goals
Users
A developer who wants a gremlin to act on a repo other than the one they're currently in — for example, running a project's published
.gremlins/*.yamlpipeline against that same project from anywhere on disk, or running a personal pipeline against someone else's code.Behavior
Invocation forms
Both work, and match existing
gremlins launchshape:gremlins launch <github-pipeline-url> --instructions "...". The repo is inferred from the URL; no--reponeeded.gremlins launch <local-pipeline-path> --repo <github-repo-url> --instructions "...". Pipeline comes from the user's machine; gremlin runs against the remote repo.gremlins launch <github-pipeline-url> --repo <github-repo-url> .... Explicit--repowins; the pipeline URL is used only to fetch the YAML.Pipeline URL resolution
Permissive: any GitHub URL form that can be resolved to a pipeline YAML works —
blob/,raw/, tree-pointing, repo-shorthand with a path, etc. If the URL can't be resolved to a YAML file, fail with a clear error. No silent fallbacks.Target repo + ref
The
--repovalue (or the repo inferred from a pipeline URL) may include a ref. The gremlin runs against that ref. Without a ref, the repo's default branch is used.Working tree
Under
/tmp/gremlins/, each target repo has a single shared shallow clone keyed off repo identity. Each launch gets its own worktree off that clone, keyed by gremlin id. The gremlin runs in its worktree.Clone is reused across launches. First launch against a repo creates the shallow clone; subsequent launches reuse it (fetching as needed to satisfy the requested ref). If the clone is missing/corrupt/has the wrong remote, it's recreated.
Worktree is per-launch. Brought up at the ref
--repoindicates, clean. Never shared between live runs.Concurrency. The shared clone is locked during the fetch + worktree-creation step so concurrent launches against the same repo serialize through that critical section. Once each launch has its worktree, they proceed in parallel without contention.
Lifetime: clone and worktrees are left in place after the gremlin finishes, success or failure. The OS (or the user) cleans
/tmp.What the gremlin does
Whatever the pipeline says. From the pipeline's point of view, it's running in a normal git checkout of the target repo with push rights — opening PRs, producing diffs, writing reports, etc. all behave as they would in a local checkout.
Constraints
Acceptance criteria
gremlins launch <github-pipeline-url>runs the named pipeline against the repo that URL points into, with no--repoflag.gremlins launch <local-pipeline> --repo <github-url>runs a local pipeline against the named remote repo.Auth
Piggyback on whatever GitHub auth is in the environment (same as today). Used for both fetching the pipeline YAML and for the clone/push against the target repo.