ghostlab 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ghostlab-0.3.0 → ghostlab-0.4.0}/PKG-INFO +205 -87
- {ghostlab-0.3.0 → ghostlab-0.4.0}/README.md +202 -84
- {ghostlab-0.3.0 → ghostlab-0.4.0}/docs/cli.md +327 -18
- {ghostlab-0.3.0 → ghostlab-0.4.0}/docs/concepts.md +23 -3
- {ghostlab-0.3.0 → ghostlab-0.4.0}/docs/configured-agent-lab.md +40 -10
- {ghostlab-0.3.0 → ghostlab-0.4.0}/docs/datasets-evaluation.md +5 -5
- {ghostlab-0.3.0 → ghostlab-0.4.0}/docs/getting-started.md +48 -10
- {ghostlab-0.3.0 → ghostlab-0.4.0}/docs/ghostlab-vision-gap-and-roadmap.md +35 -19
- ghostlab-0.4.0/docs/index.md +49 -0
- ghostlab-0.4.0/docs/run-an-agent.md +147 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/README.md +12 -0
- ghostlab-0.4.0/examples/agent-lab/task-agent.json +20 -0
- ghostlab-0.4.0/examples/copilot-agent.json +46 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/llms.txt +12 -8
- {ghostlab-0.3.0 → ghostlab-0.4.0}/mkdocs.yml +2 -1
- {ghostlab-0.3.0 → ghostlab-0.4.0}/pyproject.toml +7 -1
- ghostlab-0.4.0/rehearsal/__init__.py +3 -0
- ghostlab-0.4.0/rehearsal/agent_exec.py +675 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/agent_profile.py +18 -5
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/agent_sandbox.py +33 -18
- ghostlab-0.4.0/rehearsal/artifact_run.py +919 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/cli.py +1034 -103
- ghostlab-0.4.0/rehearsal/config.py +863 -0
- ghostlab-0.4.0/rehearsal/copilot_backend.py +256 -0
- ghostlab-0.4.0/rehearsal/copilot_llm_backend.py +299 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/evaluate.py +182 -6
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/generate.py +38 -10
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/hosts/__init__.py +3 -2
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/jobs.py +311 -33
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/lab.py +66 -17
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/llm_backend.py +32 -12
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/opencode_backend.py +28 -1
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/orchestrator.py +125 -4
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/profile.py +61 -9
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/prompts.py +24 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/resolved_config.py +126 -29
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/runner_presets.py +52 -16
- ghostlab-0.4.0/rehearsal/runners.py +604 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/sandbox.py +489 -16
- ghostlab-0.4.0/rehearsal/scorecard.py +617 -0
- ghostlab-0.4.0/rehearsal/scorer_wrapper.py +154 -0
- ghostlab-0.4.0/rehearsal/scorers.py +2425 -0
- ghostlab-0.4.0/rehearsal/session_provenance.py +40 -0
- ghostlab-0.4.0/rehearsal/skills.py +124 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/spec.py +45 -14
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/tool_capture.py +211 -1
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/ui/app.py +224 -20
- ghostlab-0.4.0/rehearsal/workspace_export.py +703 -0
- ghostlab-0.3.0/runners/codex-cortex-local-aut.json → ghostlab-0.4.0/runners/codex-aut.example.json +1 -1
- ghostlab-0.3.0/runners/codex-cortex-local-session.json → ghostlab-0.4.0/runners/codex-session.example.json +1 -1
- ghostlab-0.4.0/runners/copilot-aut.example.json +30 -0
- ghostlab-0.4.0/runners/copilot-user.example.json +28 -0
- ghostlab-0.4.0/tests/openshell_fake.py +212 -0
- ghostlab-0.4.0/tests/test_agent_exec.py +366 -0
- ghostlab-0.4.0/tests/test_artifact_run.py +1249 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_cli_spec_flow.py +2 -1
- ghostlab-0.4.0/tests/test_copilot_backend.py +608 -0
- ghostlab-0.4.0/tests/test_copilot_llm_backend.py +279 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_evaluate.py +44 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_generate.py +26 -0
- ghostlab-0.4.0/tests/test_harness_runners.py +118 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_jobs.py +30 -2
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_opencode_backend.py +23 -0
- ghostlab-0.4.0/tests/test_sandbox.py +310 -0
- ghostlab-0.4.0/tests/test_scorecard.py +343 -0
- ghostlab-0.4.0/tests/test_scorers.py +2141 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_session_runner.py +28 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_skills.py +10 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_spec.py +12 -0
- ghostlab-0.3.0/docs/index.md +0 -36
- ghostlab-0.3.0/rehearsal/__init__.py +0 -3
- ghostlab-0.3.0/rehearsal/config.py +0 -221
- ghostlab-0.3.0/rehearsal/runners.py +0 -293
- ghostlab-0.3.0/rehearsal/scorecard.py +0 -266
- ghostlab-0.3.0/rehearsal/skills.py +0 -47
- ghostlab-0.3.0/runners/codex-cortex-aut.json +0 -20
- ghostlab-0.3.0/tests/test_sandbox.py +0 -132
- ghostlab-0.3.0/tests/test_scorecard.py +0 -112
- {ghostlab-0.3.0 → ghostlab-0.4.0}/.gitignore +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/CONTRIBUTING.md +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/LICENSE +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/docs/publishing.md +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/agent-lab/AGENTS.md +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/agent-lab/agent.json +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/agent-lab/mcp.json +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/agent-lab/repo/CHANGELOG.md +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/agent-lab/repo/README.md +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/agent-lab/repo/src/app.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/agent-lab/skills/release-notes/SKILL.md +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/agent-lab/tiny-mcp.js +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/agent.json +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/demo-skill/SKILL.md +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/mcp-config.json +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/scenario.json +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/examples/target.json +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/ghostlab/__init__.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/ghostlab/__main__.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/ghostlab/cli.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/__main__.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/agents.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/apps_host/__init__.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/apps_host/assertions.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/apps_host/executor.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/apps_host/live.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/apps_host/protocol.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/apps_host/renderer.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/apps_host/report.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/cli_ui.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/codex_backend.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/compare.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/contract.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/critique.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/dashboard.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/dataset.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/hosts/base.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/hosts/direct.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/hosts/runner.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/inspect.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/logging.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/mcp_apps.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/mcp_client.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/mcp_config.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/mcp_targets.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/opencode_config.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/personas.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/plan.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/plan_generate.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/readiness.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/report.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/review.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/rollout_report.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/sampling.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/setup_runtime.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/storage/__init__.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/storage/db.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/storage/hashing.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/storage/ids.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/storage/migrations/0001_initial.sql +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/storage/redact.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/storage/repository.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/termcolor.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/testrun.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/types.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/rehearsal/ui/__init__.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/runners/claude-process.example.json +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/runners/codex-process.example.json +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/runners/codex-user-emulator.json +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/runners/mock-aut.json +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/runners/mock-user.json +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_agents.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_apps_host.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_apps_live.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_codex_backend_sandbox.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_compare.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_config.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_configured_agent.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_contract.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_critique.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_dataset.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_hosts_runner.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_inspect_lint.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_mcp_apps.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_mcp_client.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_mcp_targets.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_orchestrator.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_personas.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_plan.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_plan_generate.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_profile.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_prompts.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_readiness.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_review.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_runner_presets.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_sampling.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_sandbox_stdio.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_setup_runtime.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_storage.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_testrun.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_tool_capture.py +0 -0
- {ghostlab-0.3.0 → ghostlab-0.4.0}/tests/test_widgets_and_dashboard.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: ghostlab
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Define an AI agent once (model, instructions, skills, MCPs) and run or evaluate it in Claude Code, Codex, Copilot, or OpenCode, sandboxed in NVIDIA OpenShell.
|
|
5
5
|
Project-URL: Documentation, https://sajjadgg.github.io/Ghostlab/
|
|
6
6
|
Project-URL: Homepage, https://github.com/sajjadGG/Ghostlab
|
|
7
7
|
Project-URL: Repository, https://github.com/sajjadGG/Ghostlab
|
|
@@ -10,7 +10,7 @@ Project-URL: Changelog, https://github.com/sajjadGG/Ghostlab/releases
|
|
|
10
10
|
Author: SajjadGG
|
|
11
11
|
License: MIT
|
|
12
12
|
License-File: LICENSE
|
|
13
|
-
Keywords: agents,ai-agents,claude,cli,codex,end-to-end-testing,evaluation,llm,llm-evaluation,mcp,mcp-apps,model-context-protocol,testing
|
|
13
|
+
Keywords: agent-skills,agents,ai-agents,claude,claude-code,cli,codex,end-to-end-testing,evaluation,github-copilot,llm,llm-evaluation,mcp,mcp-apps,model-context-protocol,opencode,openshell,sandbox,testing
|
|
14
14
|
Classifier: Development Status :: 3 - Alpha
|
|
15
15
|
Classifier: Environment :: Console
|
|
16
16
|
Classifier: Intended Audience :: Developers
|
|
@@ -42,48 +42,42 @@ Description-Content-Type: text/markdown
|
|
|
42
42
|
|
|
43
43
|
# Ghostlab
|
|
44
44
|
|
|
45
|
-
>
|
|
46
|
-
>
|
|
47
|
-
>
|
|
48
|
-
> widgets**.
|
|
45
|
+
> **Define an agent once — model, instructions, skills, MCPs, workspace — and run
|
|
46
|
+
> it in any coding-agent harness, sandboxed in NVIDIA OpenShell.** Use it to get
|
|
47
|
+
> a task done, or to evaluate how well the agent does its job.
|
|
49
48
|
|
|
50
49
|
[](https://github.com/sajjadGG/Ghostlab/actions)
|
|
50
|
+
[](https://pypi.org/project/ghostlab/)
|
|
51
51
|
[](https://sajjadgg.github.io/Ghostlab/)
|
|
52
52
|
[](pyproject.toml)
|
|
53
53
|
[](LICENSE)
|
|
54
54
|
[](llms.txt)
|
|
55
55
|
|
|
56
|
-
**Test an agent the way it is actually used** — not only with unit tests against
|
|
57
|
-
the protocol, but with a real coding agent (Codex / Claude) that picks tools,
|
|
58
|
-
makes mistakes, and tries to accomplish goals, while a second agent plays the
|
|
59
|
-
user. Protocol-level checks (schema errors, a tool call that 500s) are useful
|
|
60
|
-
sanity checks, but they aren't the real test — the real test is whether an
|
|
61
|
-
agent can actually get a task done with its configured MCPs, skills, workspace,
|
|
62
|
-
instructions, and runner, end to end.
|
|
63
|
-
|
|
64
56
|
📖 **Docs wiki:** https://sajjadgg.github.io/Ghostlab/ · 🤖 **For agents:** [`llms.txt`](llms.txt) · 🛠 **Contributing:** [`CONTRIBUTING.md`](CONTRIBUTING.md)
|
|
65
57
|
|
|
66
|
-
> **Naming:** the project and repo are **Ghostlab** (formerly *Rehearsal*). The CLI
|
|
67
|
-
> is `ghostlab`, with `rehearsal` kept as an alias, and the installed Python
|
|
68
|
-
> package is `rehearsal` — all the same project.
|
|
69
|
-
|
|
70
58
|
<p align="center">
|
|
71
59
|
<img src="static/ghostlablogo.png" width="400" alt="Logo" align="center">
|
|
72
60
|
</p>
|
|
73
61
|
|
|
74
|
-
|
|
62
|
+
Ghostlab does three things with one agent definition:
|
|
75
63
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
| | Command | What you get |
|
|
65
|
+
| --- | --- | --- |
|
|
66
|
+
| **Run** | `ghostlab exec` | The agent does a task in Claude Code, Codex, GitHub Copilot CLI, or OpenCode — inside a throwaway OpenShell sandbox — and you get its answer, tool trace, and any files it produced. |
|
|
67
|
+
| **Evaluate** | `ghostlab lab` / `create` → `test` → `review` | A second agent plays realistic users, drives the configured agent over multiple turns, and a judge scores the outcome against a release gate. |
|
|
68
|
+
| **Build eval sets** | `ghostlab create --target` / `--skill`, `generate-dataset` | Persona × scenario test sets generated from an MCP server's tools or a skill's `SKILL.md`, curated as files, rerunnable in CI. |
|
|
79
69
|
|
|
80
|
-
ghostlab
|
|
81
|
-
|
|
70
|
+
> **Naming:** the CLI is `ghostlab` (with `rehearsal` kept as an alias) and the
|
|
71
|
+
> installed Python package is `rehearsal` — all the same project.
|
|
72
|
+
|
|
73
|
+
## Install
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install ghostlab # add [ui] for the web UI, [apps] for MCP Apps rendering
|
|
77
|
+
ghostlab doctor # checks OpenShell and the agent CLIs
|
|
82
78
|
```
|
|
83
79
|
|
|
84
|
-
|
|
85
|
-
[`lab`](#evaluate-a-configured-agent-ghostlab-lab) when it is an **agent** — a
|
|
86
|
-
model plus instructions, skills, MCPs, permissions, and a codebase.
|
|
80
|
+
From a checkout: `python3 -m venv .venv && .venv/bin/pip install -e .`
|
|
87
81
|
|
|
88
82
|
Ghostlab uses [NVIDIA OpenShell](https://docs.nvidia.com/openshell/latest/)
|
|
89
83
|
as its default execution boundary. Install OpenShell, start a supported compute
|
|
@@ -103,6 +97,65 @@ brew services restart openshell
|
|
|
103
97
|
openshell status
|
|
104
98
|
```
|
|
105
99
|
|
|
100
|
+
## Run an agent: `ghostlab exec`
|
|
101
|
+
|
|
102
|
+
Describe the agent in one file:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"id": "release-helper",
|
|
107
|
+
"instructions": "Be concise. Never claim something was published.",
|
|
108
|
+
"runtime": { "backend": "claude", "model": "sonnet" },
|
|
109
|
+
"workspace": "repo",
|
|
110
|
+
"inputs": {
|
|
111
|
+
"mcps": [{ "config_ref": "mcp.json", "server": "tiny" }],
|
|
112
|
+
"skills": ["skills/release-notes"]
|
|
113
|
+
},
|
|
114
|
+
"sandbox": { "backend": "openshell", "providers": ["anthropic"] }
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Then hand it a task:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
ghostlab exec --agent agent.json "Draft release notes from CHANGELOG.md"
|
|
122
|
+
ghostlab exec --agent agent.json --backend copilot --model gpt-5-mini --provider copilot "..."
|
|
123
|
+
ghostlab exec --agent agent.json --prompt-file task.md --export /sandbox/repo/NOTES.md > answer.md
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The answer goes to stdout; status goes to stderr; the full trace — composed
|
|
127
|
+
prompt, raw harness stream, every MCP and built-in tool call, and
|
|
128
|
+
`exec.json` — is kept under `runs/`. The same definition runs in every harness:
|
|
129
|
+
|
|
130
|
+
| `runtime.backend` | Harness | How MCPs attach | How skills attach |
|
|
131
|
+
| --- | --- | --- | --- |
|
|
132
|
+
| `claude` | Claude Code (`claude -p`) | `--mcp-config` (strict), MCP tools pre-approved | Prompt preamble |
|
|
133
|
+
| `codex` | Codex (`codex exec --json`) | `-c mcp_servers.*` overrides | Prompt preamble |
|
|
134
|
+
| `copilot` | GitHub Copilot CLI | `--additional-mcp-config` | Prompt preamble |
|
|
135
|
+
| `opencode` | OpenCode (`opencode run`) | Generated `opencode.json` | Native `skills.paths` |
|
|
136
|
+
| `runner` | Any CLI in `runner.command` | Your command | Prompt preamble |
|
|
137
|
+
|
|
138
|
+
Under OpenShell (the default), the agent CLI, its stdio MCP servers, its skills,
|
|
139
|
+
and an uploaded copy of its workspace all live in one sandbox that is deleted
|
|
140
|
+
afterwards; credentials arrive through OpenShell providers (`--provider`) and
|
|
141
|
+
nothing on the host is touched. The OpenShell `base` image already ships all
|
|
142
|
+
four harness CLIs. `--sandbox local` runs on your machine and edits the
|
|
143
|
+
workspace in place — use it only for trusted agents. See
|
|
144
|
+
[Run an Agent](docs/run-an-agent.md).
|
|
145
|
+
|
|
146
|
+
## Evaluate an agent, an MCP server, or a skill
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
ghostlab lab # evaluate a configured agent (model, skills, MCPs, code)
|
|
150
|
+
ghostlab create # evaluate an MCP server or a skill
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Pick [`lab`](#evaluate-a-configured-agent-ghostlab-lab) when the thing under
|
|
154
|
+
test is an **agent** — a model plus instructions, skills, MCPs, permissions,
|
|
155
|
+
and a codebase — and `create` when it is an **MCP server** or a **skill**. The agent under test
|
|
156
|
+
can run in Codex, OpenCode, GitHub Copilot CLI, or Claude Code
|
|
157
|
+
(`--aut-backend claude`).
|
|
158
|
+
|
|
106
159
|
OpenShell is the default; there is no `--local` flag. Use the explicit
|
|
107
160
|
`--sandbox local` escape hatch only for trusted code that you intentionally
|
|
108
161
|
want to execute directly on the host:
|
|
@@ -121,11 +174,12 @@ logs with the run artifacts, and deletes the sandboxes at teardown. Local stdio
|
|
|
121
174
|
MCP processes in the job pipeline are routed through the same boundary. OpenShell failures remain
|
|
122
175
|
`harness_error`s and never silently fall back to host execution.
|
|
123
176
|
|
|
124
|
-
|
|
177
|
+
Interactive `ghostlab create` guides you through the
|
|
125
178
|
evaluation subject (agent/MCP/skill), OpenShell image/providers, generation
|
|
126
|
-
size, four model roles (AUT, user emulator, generation, and judge),
|
|
127
|
-
|
|
128
|
-
|
|
179
|
+
size, four model roles (AUT, user emulator, generation, and judge), separate AUT
|
|
180
|
+
and user runner backends, Copilot/VS Code custom-agent names, runner policy,
|
|
181
|
+
lifecycle/timeout, release gate, and whether to run immediately. The
|
|
182
|
+
Questionary/Rich terminal UI provides arrow-key selection,
|
|
129
183
|
multi-select suite picking, color, and numbered progress. The same choices
|
|
130
184
|
remain available as flags for scripts and CI.
|
|
131
185
|
|
|
@@ -135,9 +189,10 @@ remain available as flags for scripts and CI.
|
|
|
135
189
|
skills, workspace, and assets. `--target` and `--skill` remain simple shorthands.
|
|
136
190
|
2. **Discover** — connects to the target, lints its contract (schema errors,
|
|
137
191
|
risk labels), and probes any MCP Apps `ui://` widgets.
|
|
138
|
-
3. **Configure semantic testing** — wires the configured runner (Codex
|
|
139
|
-
|
|
140
|
-
|
|
192
|
+
3. **Configure semantic testing** — wires the configured runner (Codex,
|
|
193
|
+
OpenCode, or GitHub Copilot CLI) as the **agent-under-test** and displays its
|
|
194
|
+
exact command, model, custom agent, policy, parser, and timeout. The user
|
|
195
|
+
emulator receives a separate runner and never receives the AUT's target MCP.
|
|
141
196
|
4. **Generate a test plan** — personas × scenarios for the semantic/security
|
|
142
197
|
suites, plus deterministic coverage for every discovered tool
|
|
143
198
|
(`test-plan.yaml`), all editable afterward.
|
|
@@ -229,31 +284,6 @@ reasoning, and the full dual-agent transcript with inline tool calls:
|
|
|
229
284
|
<img src="static/case-report-transcript.png" width="760" alt="Per-case report with judge verdict and conversation transcript">
|
|
230
285
|
</p>
|
|
231
286
|
|
|
232
|
-
## Goal
|
|
233
|
-
|
|
234
|
-
Build a repeatable, sandboxed tester that can:
|
|
235
|
-
|
|
236
|
-
- Run arbitrary configured agents inside NVIDIA OpenShell.
|
|
237
|
-
- Compose zero or more MCPs, skills, instructions, workspace files, and assets.
|
|
238
|
-
- Launch one coding-agent session as the **agent-under-test**.
|
|
239
|
-
- Launch another coding-agent session as the **user emulator** (persona + goal driven).
|
|
240
|
-
- Drive multi-turn interactions between them.
|
|
241
|
-
- Capture full traces, tool activity, failures, and outcomes.
|
|
242
|
-
|
|
243
|
-
This lets you test with your existing Codex/Claude usage path, instead of wiring a separate LLM provider deployment just for E2E testing.
|
|
244
|
-
|
|
245
|
-
## Scope
|
|
246
|
-
|
|
247
|
-
Ghostlab is intentionally **app-agnostic**:
|
|
248
|
-
|
|
249
|
-
- Treats an agent configuration—not a single MCP—as the evaluation boundary.
|
|
250
|
-
- Works with MCP servers reachable by stdio/SSE/streamable HTTP and local skills.
|
|
251
|
-
- Supports local or remote MCP endpoints.
|
|
252
|
-
- Supports multiple coding-agent runners (Codex, OpenCode, Claude Code, and future adapters).
|
|
253
|
-
- Expresses an OpenCode agent's full configuration — model, instructions, skills, subagents, tool permissions, and any number of MCPs — and runs all of it inside the sandbox.
|
|
254
|
-
|
|
255
|
-
No Cortex-specific assumptions are required in the core harness.
|
|
256
|
-
|
|
257
287
|
## Reference
|
|
258
288
|
|
|
259
289
|
Everything below is the individual-command reference and advanced usage —
|
|
@@ -311,8 +341,9 @@ primary discovery input for one-MCP/one-skill jobs:
|
|
|
311
341
|
- `capabilities`: optional expected tools/resources/prompts
|
|
312
342
|
- `startup`: optional health checks and boot timeout
|
|
313
343
|
|
|
314
|
-
The canonical `agent` section contains
|
|
315
|
-
|
|
344
|
+
The canonical `agent` section contains a `runtime` (harness backend, model,
|
|
345
|
+
and harness-specific settings) or a raw `runner`, `instructions`, and composable
|
|
346
|
+
`inputs.mcps`, `inputs.skills`, and assets — the same file `ghostlab exec` runs. The sibling `sandbox` section defaults
|
|
316
347
|
to OpenShell and controls the image, uploads, workdir, policy, resource limits,
|
|
317
348
|
network mode, environment allowlist, providers, logs, and cleanup.
|
|
318
349
|
`backend: local` is explicit unsandboxed compatibility—not a fallback.
|
|
@@ -321,6 +352,7 @@ network mode, environment allowlist, providers, logs, and cleanup.
|
|
|
321
352
|
|
|
322
353
|
The package installs two equivalent console scripts: `ghostlab` and `rehearsal`.
|
|
323
354
|
|
|
355
|
+
- `ghostlab exec` — run a configured agent on one task in any harness (Claude Code, Codex, Copilot, OpenCode), inside OpenShell, and print its answer.
|
|
324
356
|
- `ghostlab lab` — guided setup for a **configured agent** (model, instructions, skills, MCPs, permissions, code), then generate scenarios from its inferred purpose and run them fully sandboxed.
|
|
325
357
|
- `ghostlab create` — the end-to-end wizard described above.
|
|
326
358
|
- `ghostlab init` — advanced: scaffold a standalone `ghostlab.yaml` **spec** from a target JSON (see [spec vs job](#spec-vs-job) — most users want `ghostlab create`).
|
|
@@ -335,7 +367,9 @@ The package installs two equivalent console scripts: `ghostlab` and `rehearsal`.
|
|
|
335
367
|
- `ghostlab run` — run one dual-agent E2E scenario directly.
|
|
336
368
|
- `ghostlab evaluate` — score a run into a pass/fail verdict (codex judge).
|
|
337
369
|
- `ghostlab critique` — rate a run's tool ergonomics from the agent's perspective (codex).
|
|
338
|
-
- `ghostlab scorecard` — roll run verdicts and critiques into a summary scorecard
|
|
370
|
+
- `ghostlab scorecard` — roll run verdicts and critiques into a summary scorecard, or aggregate benchmark attempts with `--attempts`.
|
|
371
|
+
- `ghostlab artifact-run` — run one configured agent once on a mutable workspace and export what it produced.
|
|
372
|
+
- `ghostlab scorer-run` — score an exported candidate workspace with a hidden scorer package.
|
|
339
373
|
- `ghostlab compare` — diff two dataset runs for regressions.
|
|
340
374
|
- `ghostlab apps-probe` / `apps-render` — probe/render MCP Apps `ui://` widgets.
|
|
341
375
|
- `ghostlab doctor` — check the sandbox and both LLM backends (`--probe` for a live check).
|
|
@@ -553,13 +587,13 @@ persona-specific scenarios, and the pairs become runnable cases:
|
|
|
553
587
|
ghostlab generate-dataset \
|
|
554
588
|
--profile runs/<id>-inspect/capabilities.json \
|
|
555
589
|
--personas 3 --scenarios-per-persona 3 --seed 7 \
|
|
556
|
-
--name
|
|
590
|
+
--name my-mcp
|
|
557
591
|
```
|
|
558
592
|
|
|
559
593
|
This writes a self-contained dataset directory:
|
|
560
594
|
|
|
561
595
|
```text
|
|
562
|
-
datasets/
|
|
596
|
+
datasets/my-mcp/
|
|
563
597
|
dataset.json manifest: mcp, seed, cases[]
|
|
564
598
|
personas/<id>.json
|
|
565
599
|
scenarios/<id>.json persona-namespaced; inline `persona` is a situational note
|
|
@@ -571,7 +605,7 @@ Before spending agent credits, check that the dataset makes sense:
|
|
|
571
605
|
|
|
572
606
|
```bash
|
|
573
607
|
ghostlab review-dataset \
|
|
574
|
-
--dataset datasets/
|
|
608
|
+
--dataset datasets/my-mcp \
|
|
575
609
|
--profile runs/<id>-inspect/capabilities.json
|
|
576
610
|
```
|
|
577
611
|
|
|
@@ -581,7 +615,7 @@ tools, personas with no scenarios). Curation is file-first — each case gets a
|
|
|
581
615
|
`status` in `dataset.json` (`pending` / `approved` / `rejected` / `needs-edit`):
|
|
582
616
|
|
|
583
617
|
```bash
|
|
584
|
-
ghostlab review-dataset --dataset datasets/
|
|
618
|
+
ghostlab review-dataset --dataset datasets/my-mcp \
|
|
585
619
|
--approve case-a case-b --reject case-c
|
|
586
620
|
```
|
|
587
621
|
|
|
@@ -589,9 +623,9 @@ ghostlab review-dataset --dataset datasets/cortex \
|
|
|
589
623
|
|
|
590
624
|
```bash
|
|
591
625
|
ghostlab run-dataset \
|
|
592
|
-
--dataset datasets/
|
|
626
|
+
--dataset datasets/my-mcp \
|
|
593
627
|
--target target.json \
|
|
594
|
-
--aut-runner runners/codex-
|
|
628
|
+
--aut-runner runners/codex-aut.example.json \
|
|
595
629
|
--user-runner runners/codex-user-emulator.json \
|
|
596
630
|
--provider openai \
|
|
597
631
|
--limit 2
|
|
@@ -634,6 +668,70 @@ ghostlab compare --base runs/<base>-summary --candidate runs/<cand>-summary \
|
|
|
634
668
|
Diffs case-by-case on verdict, listing regressions first, then fixes, then
|
|
635
669
|
other changes. Exits non-zero when there are regressions, so it can gate CI.
|
|
636
670
|
|
|
671
|
+
### Benchmark a coding agent: `artifact-run` / `scorer-run`
|
|
672
|
+
|
|
673
|
+
`run` evaluates a conversation. A benchmark task is the opposite shape: one
|
|
674
|
+
message, a repository the agent may rewrite, and a verdict that depends only on
|
|
675
|
+
the state it left behind. Two commands cover it, and neither one creates a user
|
|
676
|
+
emulator.
|
|
677
|
+
|
|
678
|
+
```bash
|
|
679
|
+
ghostlab artifact-run \
|
|
680
|
+
--agent agents/candidate.json \
|
|
681
|
+
--workspace <materialized-base-repo> \
|
|
682
|
+
--prompt-file tasks/<task_id>/public/prompt.txt \
|
|
683
|
+
--sandbox-image 'project@sha256:<digest>' \
|
|
684
|
+
--setup-command '["python3","-m","venv",".venv"]' \
|
|
685
|
+
--optional-export /sandbox/output/notes.json=notes.json \
|
|
686
|
+
--export-workspace candidate-state.tar.zst \
|
|
687
|
+
--run-dir attempts/<attempt_id>
|
|
688
|
+
|
|
689
|
+
ghostlab scorer-run \
|
|
690
|
+
--task tasks/<task_id>/public/task.json \
|
|
691
|
+
--scorer tasks/<task_id>/private/scorer/scorer.json \
|
|
692
|
+
--candidate attempts/<attempt_id>/candidate-state.tar.zst \
|
|
693
|
+
--trace attempts/<attempt_id>/events.jsonl \
|
|
694
|
+
--output attempts/<attempt_id>/score-report.json
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
The workspace is uploaded into an OpenShell sandbox, so the agent edits a
|
|
698
|
+
throwaway copy. Before that sandbox is deleted, `--export-workspace` takes a
|
|
699
|
+
canonical export: sorted paths with modes, sizes, and SHA-256 hashes in
|
|
700
|
+
`status.json`, a `diff.patch`, an `untracked.json`, and a deterministic archive
|
|
701
|
+
of exactly those files. Changed and untracked files are kept; `.git/` and the
|
|
702
|
+
usual build and cache directories are not. The post-run workspace hash is
|
|
703
|
+
recorded even without an archive. Required `--export` paths fail the run when
|
|
704
|
+
absent; `--optional-export` paths are downloaded only when present.
|
|
705
|
+
`--sandbox-image` replaces the agent definition's image with the task's pinned
|
|
706
|
+
project environment, and repeatable `--setup-command` values are JSON argument
|
|
707
|
+
arrays executed in that same sandbox before the agent turn. Artifact runs
|
|
708
|
+
require a root-owned `/usr/bin/python3` with the standard library; Ghostlab
|
|
709
|
+
validates that trusted exporter runtime before it sends the prompt and verifies
|
|
710
|
+
the downloaded archive against `status.json` before accepting the candidate
|
|
711
|
+
state.
|
|
712
|
+
|
|
713
|
+
`scorer-run` never reuses the agent's sandbox. The candidate is mounted
|
|
714
|
+
read-only at the path supplied by `repo_path`, hidden fixtures live at
|
|
715
|
+
`GHOSTLAB_FIXTURES_ROOT`, and only `GHOSTLAB_OUTPUT_ROOT` and `/tmp` are
|
|
716
|
+
writable. OpenShell 0.0.80 requires these roots below `/sandbox`; scorers must
|
|
717
|
+
use the score input and `GHOSTLAB_*_ROOT` variables rather than hard-code the
|
|
718
|
+
logical manifest paths. A fail-closed Landlock launcher applies this boundary
|
|
719
|
+
to the scorer process. A scorer that executes candidate code must invoke it
|
|
720
|
+
through `GHOSTLAB_SECURE_EXEC` (or an equivalently restrictive nested sandbox)
|
|
721
|
+
without granting fixture, input, scorer, or report access. The agent's trace is
|
|
722
|
+
redacted down to tool and timing evidence first, so the scorer cannot see who
|
|
723
|
+
produced the candidate. The deterministic phase runs with no network and no
|
|
724
|
+
provider credentials; a hybrid scorer's residual judge gets provider access
|
|
725
|
+
in a second sandbox that cannot execute anything. Ghostlab computes the total
|
|
726
|
+
outside both sandboxes: weights must sum to `1.0`, a failed hard gate forces
|
|
727
|
+
`0`, and unscored soft components are reported rather than renormalized away.
|
|
728
|
+
Scorer crashes, timeouts, judge outages, and unusable candidate artifacts get
|
|
729
|
+
their own statuses and are never turned into a zero.
|
|
730
|
+
|
|
731
|
+
`ghostlab scorecard --attempts <dir>` then rolls attempts up with equal weight
|
|
732
|
+
per rollout source, reporting pass rate, per-component means, seed spread,
|
|
733
|
+
valid coverage, and the error counts it deliberately excluded from the score.
|
|
734
|
+
|
|
637
735
|
### MCP Apps: `apps-probe` / `apps-render`
|
|
638
736
|
|
|
639
737
|
Some MCPs ship **MCP Apps UI** resources — a tool's `_meta.ui.resourceUri`
|
|
@@ -667,21 +765,21 @@ if the render errored or any assertion failed.
|
|
|
667
765
|
### Session runner (one live agent across turns)
|
|
668
766
|
|
|
669
767
|
By default each turn spawns a fresh agent process and the orchestrator replays
|
|
670
|
-
the transcript.
|
|
671
|
-
|
|
672
|
-
`
|
|
673
|
-
|
|
768
|
+
the transcript. Stateful runners keep native agent context: `codex-session`
|
|
769
|
+
captures a Codex `thread_id` and resumes it, while `copilot-session` assigns one
|
|
770
|
+
Copilot `--session-id` to every turn. Both avoid repeated cold starts and prompt
|
|
771
|
+
replay.
|
|
674
772
|
|
|
675
773
|
```bash
|
|
676
774
|
ghostlab run --target target.json --scenario <scenario.json> \
|
|
677
|
-
--aut-runner runners/codex-
|
|
775
|
+
--aut-runner runners/codex-session.example.json --user-runner <user.json>
|
|
678
776
|
```
|
|
679
777
|
|
|
680
778
|
### Validate your setup: `doctor`
|
|
681
779
|
|
|
682
780
|
```bash
|
|
683
781
|
ghostlab doctor # validates runners/*.json
|
|
684
|
-
ghostlab doctor --runners runners/codex-
|
|
782
|
+
ghostlab doctor --runners runners/codex-session.example.json
|
|
685
783
|
ghostlab doctor --sandbox local # trusted local mode; skips OpenShell checks
|
|
686
784
|
```
|
|
687
785
|
|
|
@@ -690,7 +788,7 @@ validates each runner's kind, command, and parser, and checks the OpenShell
|
|
|
690
788
|
CLI/gateway by default. Add `--probe` to verify a backend can actually answer
|
|
691
789
|
instead of only confirming its binary exists.
|
|
692
790
|
|
|
693
|
-
###
|
|
791
|
+
### Generation and judge backends (codex or opencode)
|
|
694
792
|
|
|
695
793
|
Ghostlab drives a coding-agent CLI for generation, the agent-under-test, and
|
|
696
794
|
judging. `inspect` needs no agent — it is a direct MCP client.
|
|
@@ -742,12 +840,12 @@ pass/fail/skip verdicts, gate failures). Set `NO_COLOR=1` (or
|
|
|
742
840
|
`GHOSTLAB_COLOR=0`) to disable it, `GHOSTLAB_COLOR=1` to force it on (e.g.
|
|
743
841
|
piping into a pager that groks ANSI).
|
|
744
842
|
|
|
745
|
-
Use `ghostlab config --job <name>` to see the exact effective
|
|
746
|
-
|
|
747
|
-
roles, composed MCP/skill inputs, and OpenShell configuration.
|
|
748
|
-
machine-readable output. If a command omits `-m`,
|
|
749
|
-
top-level model from Codex's `config.toml` and identifies
|
|
750
|
-
Streamlit Overview and Configure tab expose the same values.
|
|
843
|
+
Use `ghostlab config --job <name>` to see the exact effective AUT and user
|
|
844
|
+
runner commands, backend/model/custom-agent selection, policy, parser/timeout,
|
|
845
|
+
all four model roles, composed MCP/skill inputs, and OpenShell configuration.
|
|
846
|
+
Add `--json` for machine-readable output. If a Codex command omits `-m`,
|
|
847
|
+
Ghostlab resolves the top-level model from Codex's `config.toml` and identifies
|
|
848
|
+
that source. The Streamlit Overview and Configure tab expose the same values.
|
|
751
849
|
|
|
752
850
|
## Runner Configs
|
|
753
851
|
|
|
@@ -771,7 +869,9 @@ Process runner:
|
|
|
771
869
|
|
|
772
870
|
The process runner starts one fresh process per turn. `prompt_mode` can be
|
|
773
871
|
`stdin`, `append-arg`, or `replace-placeholder`. `ghostlab create` synthesizes
|
|
774
|
-
|
|
872
|
+
separate `jobs/<name>/runners/aut.json` and
|
|
873
|
+
`jobs/<name>/runners/user.json` files. The AUT receives the target MCP while
|
|
874
|
+
the user emulator explicitly does not. Codex wires the target
|
|
775
875
|
MCP in via codex's `-c mcp_servers.<id>...` overrides, including
|
|
776
876
|
`bearer_token_env_var` for `Bearer ${VAR}`-style auth headers) — see
|
|
777
877
|
`jobs/<name>/runners/aut.json` after running it. To use Claude Code or another
|
|
@@ -780,12 +880,30 @@ agent as the AUT instead, hand-write a runner JSON (see
|
|
|
780
880
|
`ghostlab create`/`ghostlab plan`, or add it directly under `hosts:` in
|
|
781
881
|
`job.yaml`.
|
|
782
882
|
|
|
783
|
-
|
|
883
|
+
GitHub Copilot CLI is a native runner, including custom agents shared with VS
|
|
884
|
+
Code:
|
|
784
885
|
|
|
785
886
|
```bash
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
887
|
+
ghostlab create --name copilot-eval --target https://example.com/mcp \
|
|
888
|
+
--aut-backend copilot --user-backend copilot \
|
|
889
|
+
--model gpt-5.4 --user-model gpt-5-mini \
|
|
890
|
+
--aut-agent release-reviewer --user-agent realistic-user \
|
|
891
|
+
--aut-reasoning-effort high --aut-context long_context \
|
|
892
|
+
--sandbox local --no-discover --yes
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
`--aut-agent`/`--user-agent` map to Copilot's `--agent`; a
|
|
896
|
+
`.github/agents/release-reviewer.agent.md` used in VS Code can therefore be
|
|
897
|
+
selected as `release-reviewer`. Use repeatable `--aut-copilot-arg` /
|
|
898
|
+
`--user-copilot-arg` and `--aut-runner-env` / `--user-runner-env` for settings
|
|
899
|
+
not represented by a dedicated flag. The declarative `agent.runtime` and
|
|
900
|
+
`test.user_runtime` objects in `job.yaml` expose model, agent, effort, context,
|
|
901
|
+
permissions, MCP/plugin settings, environment, and `extra_args`; the UI
|
|
902
|
+
Configure tab provides full JSON editors for both.
|
|
903
|
+
|
|
904
|
+
See `runners/copilot-aut.example.json`, `runners/copilot-user.example.json`,
|
|
905
|
+
and `examples/copilot-agent.json`. To use another process as either role, pass
|
|
906
|
+
low-level JSON with `--aut-runner` and/or `--user-runner`.
|
|
789
907
|
|
|
790
908
|
## Packaging & Release
|
|
791
909
|
|