lastlight 0.21.14 → 0.23.0

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.
@@ -0,0 +1,501 @@
1
+ /**
2
+ * `lastlight repo …` — the per-repository config layer (issue #180) from the
3
+ * *repo's* side.
4
+ *
5
+ * A managed repo may commit a `.lastlight/` directory that overrides a bounded
6
+ * subset of Last Light's config for runs against itself. Its on-disk shape
7
+ * mirrors a deployment overlay exactly — which is why this file leans on
8
+ * `fork-cli.ts` for the copying rather than reimplementing it:
9
+ *
10
+ * .lastlight/
11
+ * lastlight.yml # the config override
12
+ * workflows/prompts/*.md # prompt overrides — NEVER workflow YAML
13
+ * skills/<name>/SKILL.md # skill overrides
14
+ * agent-context/*.md # additive persona/rules files
15
+ *
16
+ * lastlight repo fork [target] Scaffold overridable assets into ./.lastlight/
17
+ * lastlight repo config validate Check ./.lastlight/ offline, exactly as the server would
18
+ * lastlight repo config show <o/r> Ask a connected server for the effective config
19
+ *
20
+ * Two deliberate differences from `lastlight fork`:
21
+ *
22
+ * 1. **The destination is never guessed.** `fork` falls back to the server
23
+ * home's `instance/` when cwd isn't an overlay; here that would silently
24
+ * write a repo's config into a deployment overlay (or vice versa). So the
25
+ * destination is always `<git repo root>/.lastlight`, and we refuse to run
26
+ * outside a git repo rather than pick something.
27
+ * 2. **The workflow YAML never travels.** A workflow defines phases, skills
28
+ * and permission profiles — the operator's call, not the repo's. Forking a
29
+ * workflow here copies only the prompts and skills its phases reference,
30
+ * and says so.
31
+ *
32
+ * `validate` is offline on purpose: it runs the SAME pure validators the server
33
+ * runs (`lastlight-shared/repo-config-schema`), so a repo can see what will be
34
+ * accepted before pushing to its default branch — which is the only ref the
35
+ * server ever reads the layer from.
36
+ */
37
+ import fs from "node:fs";
38
+ import path from "node:path";
39
+ import chalk from "chalk";
40
+ import { configureWorkflowAssets, listAgentWorkflows, resolveSkillPaths, DEFAULT_REPO_CONFIG_ALLOW_KEYS, REPO_CONFIG_FILE, defaultRepoConfigPolicy, parseRepoConfigYaml, repoLayerPathKind, sanitizeRepoConfigLayer, sanitizeRepoFiles, } from "lastlight-shared";
41
+ import { CLASSIFIER_PROMPTS, builtinAgentContext, copyDir, copyFile, hasBuiltins, isDir, resolveCoreRoot, workflowAssetRefs, } from "./fork-cli.js";
42
+ import { resolveServerHome } from "./cli-config.js";
43
+ /** The layer directory a repo commits, relative to its root. */
44
+ const LAYER_DIR = ".lastlight";
45
+ // ── repo root ──────────────────────────────────────────────────────────────
46
+ /**
47
+ * Walk up from `start` to the nearest git repo root. `.git` is a directory in a
48
+ * normal clone and a *file* in a worktree/submodule, so both count.
49
+ */
50
+ function findGitRoot(start) {
51
+ let dir = path.resolve(start);
52
+ for (;;) {
53
+ if (fs.existsSync(path.join(dir, ".git")))
54
+ return dir;
55
+ const parent = path.dirname(dir);
56
+ if (parent === dir)
57
+ return undefined;
58
+ dir = parent;
59
+ }
60
+ }
61
+ /**
62
+ * The repo whose `.lastlight/` we operate on. Explicit `--dir` wins; otherwise
63
+ * the git repo containing cwd. Refusing outside a git repo is the point: the
64
+ * server only ever reads this layer from a repo's default branch, so writing it
65
+ * somewhere unversioned would be a silent no-op.
66
+ */
67
+ function resolveRepoRoot(opts) {
68
+ const explicit = opts.dir ? path.resolve(opts.dir) : undefined;
69
+ const root = explicit ?? findGitRoot(process.cwd());
70
+ if (!root) {
71
+ throw new Error("lastlight repo must run inside a git repository — the .lastlight/ layer is read from the repo's " +
72
+ "default branch, so it has to be committed. cd into your repo (or pass --dir <repo>).");
73
+ }
74
+ if (explicit && !fs.existsSync(path.join(root, ".git"))) {
75
+ throw new Error(`${root} is not a git repository (no .git). The .lastlight/ layer must be committed.`);
76
+ }
77
+ return root;
78
+ }
79
+ /** Where the built-in assets are read FROM (never where we write). */
80
+ function resolveBuiltInRoot(opts) {
81
+ // An explicit --home is unambiguous intent; otherwise try the directory we're
82
+ // standing in (a core checkout) before the saved/default server home.
83
+ if (opts.home)
84
+ return resolveCoreRoot(path.resolve(opts.home));
85
+ return resolveCoreRoot(process.cwd(), resolveServerHome());
86
+ }
87
+ // ── repo fork ──────────────────────────────────────────────────────────────
88
+ /**
89
+ * Copy the prompts + skills one workflow references into `.lastlight/`.
90
+ *
91
+ * NOT the workflow YAML: a repo may retune what an agent is told, never which
92
+ * phases run, with which skills, under which permission profile.
93
+ */
94
+ function forkWorkflowAssets(coreRoot, layerDir, name, force) {
95
+ const { prompts, skills } = workflowAssetRefs(name);
96
+ const results = [];
97
+ for (const rel of prompts) {
98
+ const src = path.join(coreRoot, "workflows", rel);
99
+ if (!fs.existsSync(src))
100
+ continue; // overlay-only prompt, nothing to fork
101
+ results.push(copyFile(src, path.join(layerDir, "workflows", rel), `workflows/${rel}`, force));
102
+ }
103
+ for (const skill of skills) {
104
+ let src;
105
+ try {
106
+ src = resolveSkillPaths([skill])[0];
107
+ }
108
+ catch {
109
+ continue; // overlay-only or missing skill
110
+ }
111
+ results.push(copyDir(src, path.join(layerDir, "skills", skill), `skills/${skill}/`, force));
112
+ }
113
+ return results;
114
+ }
115
+ /** Copy the base intent-classifier prompts (skip any absent from core). */
116
+ function forkClassifierPrompts(coreRoot, layerDir, force) {
117
+ const results = [];
118
+ for (const rel of CLASSIFIER_PROMPTS) {
119
+ const src = path.join(coreRoot, "workflows", rel);
120
+ if (!fs.existsSync(src))
121
+ continue;
122
+ results.push(copyFile(src, path.join(layerDir, "workflows", rel), `workflows/${rel}`, force));
123
+ }
124
+ return results;
125
+ }
126
+ /** Copy agent-context files as a starting point. Additive-only at runtime — see {@link agentContextNote}. */
127
+ function forkAgentContext(coreRoot, layerDir, files, force) {
128
+ return files.map((file) => copyFile(path.join(coreRoot, "agent-context", file), path.join(layerDir, "agent-context", file), `agent-context/${file}`, force));
129
+ }
130
+ /** Everything a repo may contribute, for every workflow, deduped by destination path. */
131
+ function forkAllRepoAssets(coreRoot, layerDir, force) {
132
+ const byRel = new Map();
133
+ const add = (r) => {
134
+ const prev = byRel.get(r.rel);
135
+ // Prefer the most informative action: a real write beats a later skip.
136
+ if (!prev || (prev.action === "skipped" && r.action !== "skipped"))
137
+ byRel.set(r.rel, r);
138
+ };
139
+ for (const def of [...listAgentWorkflows()].sort((a, b) => a.name.localeCompare(b.name))) {
140
+ for (const r of forkWorkflowAssets(coreRoot, layerDir, def.name, force))
141
+ add(r);
142
+ }
143
+ for (const r of forkAgentContext(coreRoot, layerDir, builtinAgentContext(coreRoot), force))
144
+ add(r);
145
+ for (const r of forkClassifierPrompts(coreRoot, layerDir, force))
146
+ add(r);
147
+ return [...byRel.values()].sort((a, b) => a.rel.localeCompare(b.rel));
148
+ }
149
+ // ── repo fork reporting ────────────────────────────────────────────────────
150
+ const SYMBOLS = {
151
+ copied: chalk.green("+ copied"),
152
+ overwritten: chalk.yellow("↻ overwritten"),
153
+ skipped: chalk.dim("• skipped (exists)"),
154
+ };
155
+ /**
156
+ * The additive-only rule for `agent-context/`, stated where it bites. Built-in
157
+ * context files are concatenated into every session's AGENTS.md; a repo may
158
+ * ADD to that, never replace it — so a repo file whose basename matches a
159
+ * built-in is dropped at runtime. Forking them is still useful (they're the
160
+ * shape to copy), which is exactly why the warning has to be loud.
161
+ */
162
+ function agentContextNote(coreRoot, results) {
163
+ const builtins = new Set(builtinAgentContext(coreRoot));
164
+ const shadowing = results
165
+ .filter((r) => r.rel.startsWith("agent-context/"))
166
+ .map((r) => path.basename(r.rel))
167
+ .filter((name) => builtins.has(name));
168
+ if (shadowing.length === 0)
169
+ return [];
170
+ return [
171
+ chalk.yellow(`! Repo agent-context is ADDITIVE ONLY.`) +
172
+ chalk.dim(` ${shadowing.join(", ")} share a name with a built-in, so the server will IGNORE them.` +
173
+ ` Rename each to something repo-specific (e.g. project-notes.md) and keep only what you want ADDED.`),
174
+ ];
175
+ }
176
+ function printForkSummary(layerDir, results, notes) {
177
+ console.log(chalk.bold(`Forked into ${layerDir}\n`));
178
+ for (const r of results)
179
+ console.log(` ${SYMBOLS[r.action]} ${r.rel}`);
180
+ if (results.length === 0)
181
+ console.log(chalk.dim(" (nothing to copy)"));
182
+ const copied = results.filter((r) => r.action !== "skipped").length;
183
+ const skipped = results.length - copied;
184
+ console.log(chalk.dim(`\n${copied} written, ${skipped} skipped.` + (skipped ? " Re-run with --force to overwrite." : "")));
185
+ for (const note of notes)
186
+ console.log(`\n${note}`);
187
+ console.log(chalk.dim("\nNext: edit the files, then ") +
188
+ chalk.cyan("lastlight repo config validate") +
189
+ chalk.dim(", then commit them to your DEFAULT BRANCH — that is the only ref Last Light reads."));
190
+ }
191
+ /** `lastlight repo fork` with no target — what a repo may override. */
192
+ function listRepoForkable(coreRoot, layerDir) {
193
+ const forked = (rel) => (fs.existsSync(path.join(layerDir, rel)) ? chalk.green(" (present)") : "");
194
+ console.log(chalk.bold("Forkable into .lastlight/") + chalk.dim(` → ${layerDir}\n`));
195
+ console.log(chalk.bold("Workflows") + chalk.dim(" (prompts + skills only — a repo may not override workflow YAML)\n"));
196
+ for (const def of [...listAgentWorkflows()].sort((a, b) => a.name.localeCompare(b.name))) {
197
+ console.log(` ${def.name}`);
198
+ }
199
+ const context = builtinAgentContext(coreRoot);
200
+ if (context.length) {
201
+ console.log(chalk.bold("\nAgent-context") + chalk.dim(" (additive only — rename before committing)\n"));
202
+ for (const file of context)
203
+ console.log(` ${file}${forked(`agent-context/${file}`)}`);
204
+ }
205
+ console.log(chalk.bold("\nClassifier") + chalk.dim(" (lastlight repo fork classifier)\n"));
206
+ for (const rel of CLASSIFIER_PROMPTS)
207
+ console.log(` ${rel}${forked(path.join("workflows", rel))}`);
208
+ console.log(chalk.dim("\nFork one with: ") + chalk.cyan("lastlight repo fork <name>"));
209
+ console.log(chalk.dim("Fork everything with: ") + chalk.cyan("lastlight repo fork all"));
210
+ }
211
+ /** `lastlight repo fork [target] [sub]`. */
212
+ function repoFork(args, opts) {
213
+ const repoRoot = resolveRepoRoot(opts);
214
+ const layerDir = path.join(repoRoot, LAYER_DIR);
215
+ const coreRoot = resolveBuiltInRoot(opts);
216
+ if (!hasBuiltins(coreRoot)) {
217
+ // Defensive — resolveCoreRoot already throws a --home pointer when nothing
218
+ // ships built-ins.
219
+ throw new Error(`No built-in assets found at ${coreRoot} (expected workflows/ + skills/). Pass --home <checkout>.`);
220
+ }
221
+ configureWorkflowAssets({ builtInRoot: coreRoot });
222
+ const [target, sub] = args;
223
+ const force = opts.force ?? false;
224
+ if (!target)
225
+ return listRepoForkable(coreRoot, layerDir);
226
+ if (target === "all") {
227
+ const results = forkAllRepoAssets(coreRoot, layerDir, force);
228
+ return printForkSummary(layerDir, results, [WORKFLOW_YAML_NOTE, ...agentContextNote(coreRoot, results)]);
229
+ }
230
+ if (target === "agent-context") {
231
+ const available = builtinAgentContext(coreRoot);
232
+ if (!available.length)
233
+ throw new Error("No agent-context files found in the built-ins.");
234
+ let files = available;
235
+ if (sub) {
236
+ const file = sub.endsWith(".md") ? sub : `${sub}.md`;
237
+ if (!available.includes(file)) {
238
+ throw new Error(`Unknown agent-context file: ${sub}. Available: ${available.join(", ")}`);
239
+ }
240
+ files = [file];
241
+ }
242
+ const results = forkAgentContext(coreRoot, layerDir, files, force);
243
+ return printForkSummary(layerDir, results, agentContextNote(coreRoot, results));
244
+ }
245
+ if (target === "classifier") {
246
+ return printForkSummary(layerDir, forkClassifierPrompts(coreRoot, layerDir, force), []);
247
+ }
248
+ // Otherwise a workflow name — prompts + skills, never the YAML.
249
+ const names = listAgentWorkflows().map((d) => d.name).sort();
250
+ if (!names.includes(target)) {
251
+ throw new Error(`Unknown repo fork target: ${target}\n Workflows: ${names.join(", ")}\n` +
252
+ ` Agent-context: "agent-context" (optionally a file, e.g. agent-context soul.md).\n` +
253
+ ` Classifier: "classifier". Everything: "all".`);
254
+ }
255
+ printForkSummary(layerDir, forkWorkflowAssets(coreRoot, layerDir, target, force), [WORKFLOW_YAML_NOTE]);
256
+ }
257
+ const WORKFLOW_YAML_NOTE = chalk.yellow("! The workflow YAML was NOT copied.") +
258
+ chalk.dim(" A repo may override a workflow's PROMPTS and SKILLS, never its definition" +
259
+ " (phases, permission profiles, approval gates stay the operator's). To change those," +
260
+ " fork the workflow into the deployment overlay instead: lastlight fork <workflow>.");
261
+ // ── repo config validate ───────────────────────────────────────────────────
262
+ /**
263
+ * Read `.lastlight/` off disk into the same blob shape the server's GitHub
264
+ * fetch produces, so the identical validators run over it.
265
+ *
266
+ * `lstat` (not `stat`) so a symlink is reported as a symlink — the layer
267
+ * rejects those, and following it here would validate the wrong bytes.
268
+ */
269
+ function readLayerFiles(layerDir) {
270
+ const out = [];
271
+ const walk = (dir, prefix) => {
272
+ let entries;
273
+ try {
274
+ entries = fs.readdirSync(dir, { withFileTypes: true });
275
+ }
276
+ catch {
277
+ return;
278
+ }
279
+ for (const entry of entries) {
280
+ const abs = path.join(dir, entry.name);
281
+ const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
282
+ if (entry.isSymbolicLink()) {
283
+ out.push({ path: rel, mode: "120000", size: 0, content: Buffer.alloc(0) });
284
+ continue;
285
+ }
286
+ if (entry.isDirectory()) {
287
+ walk(abs, rel);
288
+ continue;
289
+ }
290
+ if (!entry.isFile())
291
+ continue;
292
+ const stat = fs.lstatSync(abs);
293
+ const content = fs.readFileSync(abs);
294
+ out.push({ path: rel, mode: stat.mode & 0o111 ? "100755" : "100644", size: content.length, content });
295
+ }
296
+ };
297
+ walk(layerDir, "");
298
+ return out.sort((a, b) => a.path.localeCompare(b.path));
299
+ }
300
+ /**
301
+ * The base the offline validator merges against: empty. It can't know the
302
+ * deployment's own values, and only one rule depends on them — the `approval`
303
+ * add-only check, which needs to know whether the operator had already set a
304
+ * gate. With an empty base every `approval: false` is reported as a no-op
305
+ * rather than a downgrade, which is the same *decision* (dropped) with a
306
+ * slightly gentler code. Reported in the summary so nobody reads more into it.
307
+ */
308
+ const OFFLINE_BASE = {
309
+ value: { models: {}, variants: {}, disabled: {}, approval: {} },
310
+ sources: { models: {}, variants: {}, disabled: {}, approval: {} },
311
+ };
312
+ function validateLayer(layerDir) {
313
+ const policy = defaultRepoConfigPolicy();
314
+ const files = readLayerFiles(layerDir);
315
+ const { accepted, warnings } = sanitizeRepoFiles(files, policy);
316
+ const configFile = accepted.find((f) => f.path === REPO_CONFIG_FILE);
317
+ const parsed = configFile ? parseRepoConfigYaml(configFile.content.toString("utf-8")) : { warnings: [] };
318
+ warnings.push(...parsed.warnings);
319
+ const sanitized = sanitizeRepoConfigLayer(parsed.config, policy, OFFLINE_BASE);
320
+ warnings.push(...sanitized.warnings);
321
+ return { layerDir, accepted: accepted.map((f) => f.path), applied: sanitized.layer, warnings };
322
+ }
323
+ const WARNING_LABEL = {
324
+ "invalid-yaml": "invalid YAML",
325
+ "not-a-mapping": "not a mapping",
326
+ "key-not-allowed": "key not allowed",
327
+ "invalid-value": "invalid value",
328
+ "model-not-allowed": "model not allowed",
329
+ "unknown-provider": "unknown provider",
330
+ "approval-downgrade": "approval downgrade",
331
+ "policy-downgrade": "policy downgrade",
332
+ "path-escape": "path escape",
333
+ symlink: "symlink",
334
+ "size-cap": "size cap",
335
+ "file-count-cap": "file-count cap",
336
+ "workflow-not-allowed": "workflow not allowed",
337
+ "assets-not-allowed": "assets not allowed",
338
+ "unrecognised-asset": "unrecognised asset",
339
+ "fetch-failed": "fetch failed",
340
+ };
341
+ /** `lastlight repo config validate` — offline, exits non-zero if anything was rejected. */
342
+ function repoConfigValidate(opts) {
343
+ const repoRoot = resolveRepoRoot(opts);
344
+ const layerDir = path.join(repoRoot, LAYER_DIR);
345
+ if (!isDir(layerDir)) {
346
+ throw new Error(`No ${LAYER_DIR}/ directory in ${repoRoot}. Create one with: lastlight repo fork <workflow>`);
347
+ }
348
+ const report = validateLayer(layerDir);
349
+ if (opts.json) {
350
+ console.log(JSON.stringify(report, null, 2));
351
+ return report.warnings.length > 0 ? 1 : 0;
352
+ }
353
+ console.log(chalk.bold(`Validating ${layerDir}\n`));
354
+ // What the layer contributes, by role.
355
+ const byKind = new Map();
356
+ for (const rel of report.accepted) {
357
+ const kind = repoLayerPathKind(rel) ?? "other";
358
+ byKind.set(kind, [...(byKind.get(kind) ?? []), rel]);
359
+ }
360
+ for (const [kind, paths] of [...byKind].sort()) {
361
+ console.log(` ${chalk.cyan(kind)}`);
362
+ for (const rel of paths)
363
+ console.log(` ${chalk.green("✓")} ${rel}`);
364
+ }
365
+ if (report.accepted.length === 0)
366
+ console.log(chalk.dim(" (no layer files)"));
367
+ if (Object.keys(report.applied).length > 0) {
368
+ console.log(chalk.bold("\nEffective config overrides"));
369
+ for (const line of flatten(report.applied))
370
+ console.log(` ${line}`);
371
+ }
372
+ else {
373
+ // "No overrides" is not the same as "nothing accepted": a `crons:` block is
374
+ // a fully supported, fully validated part of the layer that deliberately
375
+ // contributes nothing to the MERGED config — it's read off the raw layer by
376
+ // the scheduler at tick time (see `repoCronPrefs` in core's
377
+ // src/cron/repo-crons.ts). Saying so here stops a clean `crons:`-only layer
378
+ // reading as "my file was ignored".
379
+ console.log(chalk.dim(`\nNo config overrides (${REPO_CONFIG_FILE} is absent, empty, or fully rejected).`) +
380
+ chalk.dim(`\nA "crons:" block does not appear here — cron participation is applied separately, at tick time.`));
381
+ }
382
+ if (report.warnings.length > 0) {
383
+ console.log(chalk.bold(chalk.red(`\n${report.warnings.length} rejected`)));
384
+ for (const w of report.warnings) {
385
+ console.log(` ${chalk.red("✗")} ${chalk.dim(`[${WARNING_LABEL[w.code] ?? w.code}]`)} ${w.path}`);
386
+ console.log(` ${chalk.dim(w.message)}`);
387
+ }
388
+ console.log(chalk.dim(`\nChecked against the shipped default bounds (repoConfig.allowKeys: ${DEFAULT_REPO_CONFIG_ALLOW_KEYS.join(", ")}).` +
389
+ `\nA deployment may narrow them further — `) +
390
+ chalk.cyan("lastlight repo config show <owner/repo>") +
391
+ chalk.dim(" shows what a given server actually applies."));
392
+ return 1;
393
+ }
394
+ console.log(chalk.green("\n✓ Everything in this layer is within the shipped default bounds."));
395
+ console.log(chalk.dim(`Bounds checked: repoConfig.allowKeys = ${DEFAULT_REPO_CONFIG_ALLOW_KEYS.join(", ")}; a deployment may narrow them.` +
396
+ `\nRemember: only the layer on your DEFAULT BRANCH is ever read.`));
397
+ return 0;
398
+ }
399
+ /** Render a nested plain object as `a.b.c = value` lines, sorted. */
400
+ function flatten(node, prefix = "") {
401
+ const out = [];
402
+ for (const [key, value] of Object.entries(node).sort(([a], [b]) => a.localeCompare(b))) {
403
+ const dotted = prefix ? `${prefix}.${key}` : key;
404
+ if (value && typeof value === "object" && !Array.isArray(value)) {
405
+ out.push(...flatten(value, dotted));
406
+ }
407
+ else {
408
+ out.push(`${chalk.cyan(dotted)} = ${JSON.stringify(value)}`);
409
+ }
410
+ }
411
+ return out;
412
+ }
413
+ /** Tag a value with the layer that supplied it — `repo` is the interesting one. */
414
+ function sourceTag(source) {
415
+ if (!source)
416
+ return "";
417
+ return source === "repo" ? chalk.green(` (repo)`) : chalk.dim(` (${source})`);
418
+ }
419
+ function printSection(title, values, sources) {
420
+ const entries = Object.entries(values ?? {});
421
+ if (entries.length === 0)
422
+ return;
423
+ console.log(chalk.bold(`\n${title}`));
424
+ for (const [key, value] of entries.sort(([a], [b]) => a.localeCompare(b))) {
425
+ const source = typeof sources === "string" ? sources : sources?.[key];
426
+ console.log(` ${chalk.cyan(key)} = ${JSON.stringify(value)}${sourceTag(source)}`);
427
+ }
428
+ }
429
+ /** `lastlight repo config show <owner/repo>` — the server's effective, post-bounds view. */
430
+ async function repoConfigShow(ref, opts) {
431
+ if (!ref || !/^[^/\s]+\/[^/\s]+$/.test(ref)) {
432
+ throw new Error("Usage: lastlight repo config show <owner/repo>");
433
+ }
434
+ if (!opts.apiGet)
435
+ throw new Error("repo config show needs an admin-API client (run it via the lastlight CLI).");
436
+ const [owner, name] = ref.split("/");
437
+ const data = (await opts.apiGet(`/admin/api/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/config` +
438
+ (opts.refresh ? "?refresh=1" : "")));
439
+ if (opts.json) {
440
+ console.log(JSON.stringify(data, null, 2));
441
+ return;
442
+ }
443
+ console.log(chalk.bold(`Effective config for ${ref}`));
444
+ if (data.defaultBranch) {
445
+ const sha = data.treeSha ? data.treeSha.slice(0, 7) : "—";
446
+ console.log(chalk.dim(` .lastlight/ from ${data.defaultBranch}@${sha}, fetched ${data.fetchedAt ?? "—"}`));
447
+ }
448
+ else {
449
+ console.log(chalk.dim(" This repo commits no .lastlight/ — everything below is the instance config."));
450
+ }
451
+ printSection("Models", data.merged?.models, data.sources?.models);
452
+ printSection("Variants", data.merged?.variants, data.sources?.variants);
453
+ printSection("Disabled", data.merged?.disabled, data.sources?.disabled);
454
+ printSection("Approval gates", data.merged?.approval, data.sources?.approval);
455
+ printSection("Fix policy", data.merged?.fix, data.sources?.fix);
456
+ printSection("Dependencies policy", data.merged?.dependencies, data.sources?.dependencies);
457
+ printSection("Review policy", data.merged?.review, data.sources?.review);
458
+ if (data.assets?.length) {
459
+ console.log(chalk.bold("\nRepo assets"));
460
+ for (const asset of data.assets)
461
+ console.log(` ${chalk.green("✓")} ${asset}`);
462
+ }
463
+ if (data.warnings?.length) {
464
+ console.log(chalk.bold(chalk.yellow(`\n${data.warnings.length} rejected from this repo's layer`)));
465
+ for (const w of data.warnings) {
466
+ console.log(` ${chalk.yellow("!")} ${chalk.dim(`[${WARNING_LABEL[w.code] ?? w.code}]`)} ${w.path}`);
467
+ console.log(` ${chalk.dim(w.message)}`);
468
+ }
469
+ }
470
+ console.log(chalk.dim(`\nValues marked ${chalk.green("(repo)")}${chalk.dim(" came from this repo's .lastlight/.")}`));
471
+ }
472
+ // ── entry point ────────────────────────────────────────────────────────────
473
+ const USAGE = `Usage:
474
+ lastlight repo fork [<workflow>|agent-context [file]|classifier|all] [--home dir] [--force]
475
+ lastlight repo config validate [--json]
476
+ lastlight repo config show <owner/repo> [--refresh] [--json]`;
477
+ /**
478
+ * `lastlight repo <fork|config> …`. Returns the process exit code (non-zero
479
+ * when `config validate` rejected something) so `cli.ts` owns `process.exit`.
480
+ */
481
+ export async function repoCommand(args, opts) {
482
+ const [sub, ...rest] = args;
483
+ switch (sub) {
484
+ case "fork":
485
+ repoFork(rest, opts);
486
+ return 0;
487
+ case "config": {
488
+ const action = rest[0];
489
+ if (action === "validate")
490
+ return repoConfigValidate(opts);
491
+ if (action === "show") {
492
+ await repoConfigShow(rest[1], opts);
493
+ return 0;
494
+ }
495
+ throw new Error(`Unknown "repo config" action: ${action ?? "(none)"}\n${USAGE}`);
496
+ }
497
+ default:
498
+ throw new Error(`Unknown "repo" subcommand: ${sub ?? "(none)"}\n${USAGE}`);
499
+ }
500
+ }
501
+ //# sourceMappingURL=repo-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-cli.js","sourceRoot":"","sources":["../src/repo-cli.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lastlight",
3
- "version": "0.21.14",
3
+ "version": "0.23.0",
4
4
  "description": "Last Light CLI — a lean global client + host-local `server` lifecycle for the Last Light GitHub maintenance agent, plus the Claude Code plugin.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,8 +33,8 @@
33
33
  "@clack/prompts": "^1.7.0",
34
34
  "chalk": "^6.0.0",
35
35
  "cli-table3": "^0.6.5",
36
- "lastlight-workflow-engine": "0.1.6",
37
- "lastlight-shared": "0.1.7"
36
+ "lastlight-workflow-engine": "0.3.0",
37
+ "lastlight-shared": "0.3.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "^26.1.1",
@@ -2,8 +2,8 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin.json",
3
3
  "name": "lastlight",
4
4
  "displayName": "Last Light",
5
- "version": "0.21.14",
6
- "description": "Install, configure and operate Last Light (GitHub maintenance agent) — its server, CLI client, deployment overlay, and the Last Light Evals harness.",
5
+ "version": "0.23.0",
6
+ "description": "Install, configure and operate Last Light (GitHub maintenance agent) \u2014 its server, CLI client, deployment overlay, and the Last Light Evals harness.",
7
7
  "author": {
8
8
  "name": "Clifton Cunningham"
9
9
  },
@@ -148,10 +148,13 @@ or `--delete` removes the run dir.
148
148
 
149
149
  ## 5. Author eval cases (optional)
150
150
 
151
- Three tiers ship: **triage** (cheap, issue-triage), **code-fix** (heavy, build
152
- workflow with held-out tests), and **pr-review** (PR-review precision, graded by
151
+ Six tiers ship: **triage** (cheap, issue-triage), **code-fix** (heavy, build
152
+ workflow with held-out tests), **pr-review** (PR-review precision, graded by
153
153
  an LLM judge against a gold set → precision / recall / **F1** by default, the
154
- F-beta configurable via `EVAL_F_BETA`). To add cases or
154
+ F-beta configurable via `EVAL_F_BETA`), **repo-config** (a repo's committed
155
+ `.lastlight/` layer), **fix** (the diagnosis half of the fix loop — one case per
156
+ diagnosis class), and **dependency-merge** (a major bump per impact tier, which
157
+ measures the one policy the code deliberately does not enforce). To add cases or
155
158
  a custom tier, read **`references/instance-schema.md`** — it has the
156
159
  `SweBenchInstance` schema, the exact files to create for each tier, and worked
157
160
  examples.
@@ -179,6 +182,11 @@ Quick shape (paths are relative to the workspace's `evals/` dir):
179
182
  a real `AGENTS.md`/`CLAUDE.md` if the repo ships one (never shadowing it). This
180
183
  is how you prove *"adding this to your repo improves review quality"* — and the
181
184
  lever the **`lastlight-evals-loop`** skill drives.
185
+ - **Fix / dependency-merge case:** a `pr` seed, a `pr_state` block (the snapshot a
186
+ dispatch would have resolved — it is what supplies `{{ciSection}}`,
187
+ `{{attempt}}`, `{{mayMerge}}`) and an `expect_markers` verdict. A `fix` case
188
+ that needs a checkout also needs `repos-head/<id>/`, the PR's own commit on top
189
+ of the base tree.
182
190
  - **Custom tier:** a new `evals/datasets/<tier>/` with `tier.json` +
183
191
  `instances.json` (+ `repos/` & `tests/` for code-fix-style tiers). Discovery is
184
192
  automatic — no code change.