lastlight 0.7.1 → 0.7.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lastlight",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "GitHub repository maintenance agent — Agent SDK harness",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin.json",
3
3
  "name": "lastlight",
4
4
  "displayName": "Last Light",
5
- "version": "0.7.1",
5
+ "version": "0.7.2",
6
6
  "description": "Install, configure and operate Last Light (GitHub maintenance agent) — its server, CLI client, deployment overlay, and the Last Light Evals harness.",
7
7
  "author": { "name": "Clifton Cunningham" },
8
8
  "homepage": "https://github.com/cliftonc/lastlight",
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lastlight-evals
3
- description: Scaffold, configure and run a Last Light EVALS workspace — the harness that runs Last Light's real workflows against a mocked GitHub and grades them deterministically. Use when the user wants to "set up / scaffold Last Light Evals", "create an evals workspace or instance", "run evals", "compare models", or author new eval cases (triage / code-fix instances). GitHub is mocked, so no real GitHub token is needed — only a model provider API key.
4
- version: 1.1.0
3
+ description: Scaffold, configure and run a Last Light EVALS workspace — the harness that runs Last Light's real workflows against a mocked GitHub and grades them deterministically. Use when the user wants to "set up / scaffold Last Light Evals", "create an evals workspace or instance", "run evals", "compare models", or author new eval cases — including "create an eval dataset/case from this PR/issue <github url>" (triage / code-fix instances). GitHub is mocked when running, so no real GitHub token is needed — only a model provider API key (the one exception is `add-case`, which reads real PRs/issues via `gh`).
4
+ version: 1.2.0
5
5
  tags: [lastlight, evals, benchmark, models, swe-bench]
6
6
  ---
7
7
 
@@ -121,6 +121,34 @@ Quick shape (paths are relative to the workspace's `evals/` dir):
121
121
  `instances.json` (+ `repos/` & `tests/` for code-fix-style tiers). Discovery is
122
122
  automatic — no code change.
123
123
 
124
+ ## 6. Author a case from a real GitHub PR or issue
125
+
126
+ When the user says **"create an eval dataset/case from this PR/issue <url>"**, use
127
+ the `add-case` subcommand — it does the mechanical extraction; you refine the
128
+ fuzzy parts.
129
+
130
+ ```bash
131
+ lastlight-evals add-case --pr <github-pr-url> --dry-run # propose a code-fix case; don't write
132
+ lastlight-evals add-case --pr <github-pr-url> # write into ./datasets (or --datasets/--overlay)
133
+ lastlight-evals add-case --issue <github-issue-url> --dry-run # propose a triage case
134
+ ```
135
+
136
+ - **From a PR (code-fix):** derives `repo`, `base_commit` (merge-base of base &
137
+ head) + `head_commit`, the PR's **test** diff as the held-out `test_patch`, and
138
+ auto-detects `FAIL_TO_PASS` / `PASS_TO_PASS` by running the tests at base (red)
139
+ vs head (green). Produces a **git-source** case (no `repos/<id>/` vendored): at
140
+ run time the harness clones the repo into the gitignored `./.eval-cache/` and
141
+ checks out `base_commit`.
142
+ - **From an issue (triage):** derives the `issue` seed + `problem_statement`, the
143
+ **labels that were applied** (from the issue events API, with *who* applied each)
144
+ → `expect_github.labels_added`, `issue_closed` if it was closed, and prints the
145
+ **reviewer comments** — the raw triage signal. You then assign
146
+ `triage_gold` (category/state) from those labels per the deployment's taxonomy.
147
+
148
+ The full flow, what you refine for each, the `test_cmd` / `setup_cmd` options for
149
+ non-`node --test` runners, and the trust/offline caveats are in
150
+ **`references/authoring-from-pr.md`** — read it before authoring.
151
+
124
152
  ## Done when
125
153
 
126
154
  The workspace is scaffolded (Separate: overlay in `instance/`, evals at root;
@@ -0,0 +1,117 @@
1
+ # Author an eval case from a real GitHub PR or issue
2
+
3
+ `lastlight-evals add-case` turns a real GitHub **PR** into a code-fix (build) case
4
+ or an **issue** into a triage case. It does the mechanical, reproducible
5
+ extraction with `gh` + `git`; **you** refine the judgement parts. The result is a
6
+ **git-source** case — no fixture repo is vendored; at run time the harness clones
7
+ the repo into the gitignored `./.eval-cache/` and checks out `base_commit` (see
8
+ the `instance-schema.md` "Git-source" flavor).
9
+
10
+ > **Trust + network.** Validation and the run-time checkout execute the repo's own
11
+ > code (`setup_cmd` / `test_cmd` / its tests). Only point this at repos you trust.
12
+ > The first run per repo fetches over the network; after that the cache makes it
13
+ > offline.
14
+
15
+ ## Prerequisites
16
+
17
+ - `gh` on PATH and authenticated (`gh auth login`) — used to read PR/issue metadata.
18
+ - `git`. Node 24+ (same as the rest of the harness).
19
+
20
+ ## Command
21
+
22
+ ```bash
23
+ lastlight-evals add-case --pr <github-pr-url> [options]
24
+ lastlight-evals add-case --issue <github-issue-url> [options]
25
+ ```
26
+
27
+ Options:
28
+
29
+ | flag | meaning |
30
+ |---|---|
31
+ | `--pr <url>` | a GitHub PR url → a **code-fix** (build) case |
32
+ | `--issue <url>` | a GitHub issue url → a **triage** case |
33
+ | `--tier <name>` | target tier dir (default `code-fix` for `--pr`, `triage` for `--issue`) |
34
+ | `--id <slug>` | `instance_id` (default derived from repo + number) |
35
+ | `--datasets <dir>` | datasets root to write into (a `<tier>/` subdir). Default `./datasets`, else `./evals/datasets` |
36
+ | `--overlay <dir>` | write into `<dir>/evals/datasets` instead |
37
+ | `--test-cmd "<cmd>"` | held-out test command (default `node --test`); stored as `test_cmd` |
38
+ | `--setup-cmd "<cmd>"` | install/build run before tests (e.g. `"npm ci"`); stored as `setup_cmd` |
39
+ | `--no-validate` | don't run the repo's tests to auto-detect `FAIL_TO_PASS` (just scaffold) |
40
+ | `--dry-run` | print the proposed instance JSON; don't write |
41
+
42
+ ## The recommended flow (CLI extracts → you refine)
43
+
44
+ 1. **Dry-run first.** `add-case --pr <url> --dry-run` prints the proposed instance.
45
+ The CLI derives:
46
+ - `repo`, `base_commit` (the **merge-base** of the base branch and the PR head —
47
+ the true fork point, not the base-branch tip), and `head_commit`;
48
+ - `test_patch` — the diff of the PR's **test** files (path heuristic: `test/`,
49
+ `tests/`, `__tests__/`, `spec/`, or `*.test.*` / `*.spec.*` / `*_test.*`);
50
+ - gold `patch` — the diff of the non-test files (reference only, never graded);
51
+ - `FAIL_TO_PASS` / `PASS_TO_PASS` — auto-detected by running the tests at base
52
+ (with `test_patch` applied → expect red) then at head (→ expect green), unless
53
+ `--no-validate`;
54
+ - `issue` + `problem_statement` (the PR's linked issue if it closes one, else the
55
+ PR title/body) and `expect_github: { pr_opened: { base, head_is_branch } }`.
56
+
57
+ 2. **Review and repair** what the CLI can't get right on its own:
58
+ - **Held-out tests.** If the heuristic mislabeled files (warns "No test files
59
+ detected", or grabbed a non-test), fix `test_patch` by hand, or rely on the
60
+ repo's in-repo tests via `--test-cmd`.
61
+ - **Verdicts.** If validation couldn't run (custom runner, deps), set
62
+ `FAIL_TO_PASS` to the genuinely bug-revealing test name(s). Leave it **empty
63
+ for suite mode** (graded on the test command's exit code) when the runner
64
+ emits no TAP names.
65
+ - **Problem statement.** Tighten it to what the agent should act on — drop PR
66
+ chatter; keep the bug description.
67
+ - **`test_cmd` / `setup_cmd`** for non-`node --test` repos, e.g.
68
+ `--test-cmd "npm test" --setup-cmd "npm ci"`.
69
+
70
+ 3. **Write it.** Re-run without `--dry-run` (add `--datasets <dir>` / `--overlay
71
+ <dir>` to target a specific workspace). The instance is appended to
72
+ `<root>/<tier>/instances.json` (creating `tier.json` if the tier is new).
73
+
74
+ 4. **Verify end-to-end.** Run the case with the cheapest model just to confirm the
75
+ plumbing — the sandbox seeds from the real repo at `base_commit` and grading
76
+ runs the held-out tests:
77
+
78
+ ```bash
79
+ EVAL_INSTANCE=<instance_id> lastlight-evals run code-fix --model haiku
80
+ ```
81
+
82
+ ## Test runners & grading
83
+
84
+ - **`node --test` (default).** Emits TAP; the CLI extracts per-test names and grades
85
+ each `FAIL_TO_PASS` / `PASS_TO_PASS` by name.
86
+ - **Any other runner via `--test-cmd`.** If it emits TAP with stable names, named
87
+ grading still works. Otherwise the case runs in **suite mode**: `FAIL_TO_PASS`
88
+ stays empty and the case is resolved iff the test command exits 0 (after the
89
+ held-out `test_patch` is applied). Use `--setup-cmd` for install/build.
90
+
91
+ ## Triage from an issue
92
+
93
+ `add-case --issue <url>` builds a triage case from a **resolved** issue — its
94
+ content plus the human triage outcome:
95
+
96
+ - `problem_statement` + the `issue` seed from the title/body. **Seed labels are
97
+ emptied on purpose** so the agent triages from scratch (the applied labels are
98
+ the gold it must reproduce, not an input).
99
+ - `expect_github.labels_added` = the labels that were applied to the issue (read
100
+ from the issue **events** API, so the evidence block also shows *who* applied
101
+ each — maintainer vs bot), and `issue_closed: true` if the issue was closed.
102
+ - An **evidence block** prints the applied labels and the reviewer comments
103
+ (author + first line) — the raw signal you turn into the gold decision.
104
+
105
+ What you refine before running:
106
+
107
+ - **`triage_gold`** (`{ category, state }`) — assign from the applied labels per
108
+ **the deployment's triage taxonomy** (the CLI can't know which label is the
109
+ category vs the workflow state, so it leaves `triage_gold` empty). `gradeTriage`
110
+ checks these label strings end up on the issue.
111
+ - **Prune** any non-triage labels (e.g. `good first issue`) out of `labels_added`.
112
+ - **Reviewer comments** — optionally turn a representative one into a
113
+ `comment_matches` regex (asserting the agent's triage comment covers the same
114
+ point), or move a genuinely *pre-triage* maintainer comment into `issue.comments`
115
+ as context the agent should see.
116
+
117
+ See `instance-schema.md` for the full triage field reference.
@@ -21,12 +21,18 @@ Datasets are discovered from (overlay > user > built-in): `<overlay>/evals/datas
21
21
  // ── SWE-bench core ──
22
22
  "instance_id": "triage__my-case", // unique id
23
23
  "repo": "owner/repo", // logical; fixture origin is a local bare repo
24
- "base_commit": "0000000...", // code-fix only
24
+ "base_commit": "0000000...", // code-fix. UNUSED for vendored fixtures
25
+ // (harness synthesizes one); for a
26
+ // git-source case it's the real SHA
27
+ // checked out at run time.
25
28
  "problem_statement": "short issue text",
26
29
  "patch": "...", // gold patch — reference only, NOT graded
27
- "test_patch": "...", // held-out tests (code-fix)
28
- "FAIL_TO_PASS": ["test id 1"], // must go red→green (code-fix)
30
+ "test_patch": "...", // held-out tests (code-fix), git-apply form
31
+ "FAIL_TO_PASS": ["test id 1"], // must go red→green. Empty ⇒ suite mode
29
32
  "PASS_TO_PASS": ["test id 2"], // must stay green (code-fix)
33
+ "test_cmd": ["npm", "test"], // held-out test argv (default: node --test)
34
+ "setup_cmd": ["npm", "ci"], // optional install/build before tests (git-source)
35
+ "head_commit": "abc123...", // PR head SHA — reference/authoring only
30
36
 
31
37
  // ── Last Light extensions ──
32
38
  "workflow": "issue-triage", // optional; defaults to the tier's defaultWorkflow
@@ -55,16 +61,27 @@ Append a `SweBenchInstance` to `datasets/triage/instances.json` with `issue`,
55
61
  `triage_gold`, and the `expect_github` assertions (e.g. `labels_added`). That's
56
62
  it — triage is graded on the triage decision + GitHub mutations.
57
63
 
58
- ## Add a code-fix case (three things, keyed by `instance_id`)
64
+ ## Two flavors of code-fix case
65
+
66
+ A code-fix instance gets its repo from **one of two** provenances; the rest of the
67
+ machinery (grading, dashboard) is identical.
68
+
69
+ **A. Vendored fixture** (three things, keyed by `instance_id`):
59
70
 
60
71
  1. **`datasets/code-fix/instances.json`** — append the instance with
61
- `base_commit`, `FAIL_TO_PASS`, `PASS_TO_PASS`, `issue`, and `expect_github`
62
- (e.g. `pr_opened`).
72
+ `FAIL_TO_PASS`, `PASS_TO_PASS`, `issue`, and `expect_github` (e.g. `pr_opened`).
63
73
  2. **`datasets/code-fix/repos/<instance_id>/`** — the fixture repo at the base
64
74
  commit (the buggy code *before* the fix; no held-out tests here).
65
75
  3. **`datasets/code-fix/tests/<instance_id>/`** — the held-out test files, copied
66
76
  into the repo at grade time and run to compute `FAIL_TO_PASS` / `PASS_TO_PASS`.
67
77
 
78
+ **B. Git-source (from a real PR)** — set `repo` + a real `base_commit` and a
79
+ `test_patch`; **no** `repos/<id>/` is vendored. At run time the harness clones the
80
+ repo into the gitignored `./.eval-cache/` and checks out `base_commit`. Don't
81
+ hand-build these — use `lastlight-evals add-case --pr <url>` (see
82
+ **`authoring-from-pr.md`**), which fills `base_commit`, `head_commit`,
83
+ `test_patch`, and the verdicts for you.
84
+
68
85
  ## Add a custom tier
69
86
 
70
87
  Create `datasets/<tier-name>/` with `tier.json` (`name`, `defaultWorkflow`,
@@ -78,7 +95,9 @@ and `tests/<id>/`. Discovery auto-finds it — no code change. Run it with
78
95
  (`expect_github`)?
79
96
  - **Triage:** did the decision match `triage_gold`?
80
97
  - **Execution (code-fix):** all `FAIL_TO_PASS` green AND all `PASS_TO_PASS` still
81
- green after applying held-out tests.
98
+ green after applying held-out tests. When the runner emits no TAP test names
99
+ (a non-`node --test` `test_cmd` and an empty `FAIL_TO_PASS`), grading falls back
100
+ to **suite mode** — resolved iff the test command exits 0.
82
101
  - With `--runs N` (N>1) the binary verdict is **worst-case** (passes only if every
83
102
  trial passed); the scorecard also shows per-verdict pass counts to expose
84
103
  variance.