@outerlayer/cli 0.1.0 → 0.1.1

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.
Files changed (27) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/dist/build-info.json +1 -1
  4. package/dist/{chunk-A6NNKRJU.js → chunk-3VQ4XXQA.js} +1 -1
  5. package/dist/{chunk-DEDV5V4U.js → chunk-BQB3U2VD.js} +2 -2
  6. package/dist/{chunk-VU34RWDU.js → chunk-HNCCD2IX.js} +1 -1
  7. package/dist/{chunk-4H56Y7O6.js → chunk-KKEU6FFR.js} +1 -1
  8. package/dist/{chunk-XN2XZFTK.js → chunk-NTTPJV35.js} +1 -1
  9. package/dist/{chunk-ECSYRPCC.js → chunk-R5KBGVII.js} +50 -4
  10. package/dist/{chunk-YMTXR7PJ.js → chunk-YOOSBOKS.js} +1 -1
  11. package/dist/{cli-3JYGL2OB.js → cli-EFJIG2VT.js} +104 -33
  12. package/dist/{emit-artifact-cmd-23F4YKQ3.js → emit-artifact-cmd-KPPD3YLO.js} +4 -4
  13. package/dist/{emit-commit-credit-cmd-2GX5M2BR.js → emit-commit-credit-cmd-656BRAQ4.js} +4 -4
  14. package/dist/{emit-finding-cmd-6K7ERPKG.js → emit-finding-cmd-VR5VEGXJ.js} +4 -4
  15. package/dist/{emit-result-cmd-NDFHMJX7.js → emit-result-cmd-YOA5BJKL.js} +4 -4
  16. package/dist/{hook-fast-CBW4ZETX.js → hook-fast-I2XTHDE6.js} +1 -1
  17. package/dist/{hook-wrap-fast-36WGE6EX.js → hook-wrap-fast-KXYNX3AD.js} +2 -2
  18. package/dist/index.js +4 -4
  19. package/dist/{loop-NFSOBUUJ.js → loop-BWE2BS6J.js} +7 -7
  20. package/dist/{status-WGOJTXZF.js → status-JHVSZYC5.js} +6 -6
  21. package/dist/{statusline-fast-Z5U5CEC6.js → statusline-fast-3C5OXHDD.js} +2 -2
  22. package/dist/{sync-cmd-C5UGI4SF.js → sync-cmd-S7Q6DWU3.js} +4 -4
  23. package/dist/{watch-V3K4PESQ.js → watch-NRLXJUST.js} +4 -4
  24. package/dist/{work-claim-cmd-FQDWQVT2.js → work-claim-cmd-HXB7K27H.js} +6 -6
  25. package/dist/{work-cmd-CW26EZZO.js → work-cmd-ABP6XDBP.js} +5 -5
  26. package/dist/{work-pr-cmd-W2QNMWXP.js → work-pr-cmd-GOYSPEN2.js} +4 -4
  27. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @outerlayer/cli
2
2
 
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 7754c0d: Hooks installed with `npx @outerlayer/cli init` no longer break when npm clears its cache. Run from a package runner's cache (`npx`, `pnpm dlx`, `yarn dlx`, `bunx`), `init` copies the CLI to `~/.outerlayer/cli` and points every hook and the status line at that copy. Re-running `init` moves hooks an earlier version pointed into the npx cache, and `npx @outerlayer/cli@latest init` upgrades the copy. A global or project install is used where it is, as before. `doctor` now fails when a hook runs a file that no longer exists, instead of reporting the hooks as installed.
8
+
3
9
  ## 0.1.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -145,7 +145,7 @@ before it gives up.
145
145
  |---|---|
146
146
  | `outerlayer sync` | Upload sessions launched with `OUTERLAYER_WORK` to your OuterLayer cloud workspace (incremental — only what's new since the last sync). Tier-gated client-side (`--tier metrics\|redacted\|full`, default `full`); `--dry-run` prints exactly what would leave the machine; `--all` re-sends everything (idempotent server-side). Credentials come from `outerlayer login`, `OUTERLAYER_*` env vars, or `--url/--app-id`. |
147
147
  | `outerlayer login [--url] [--app-id]` | Save the cloud URL, app id, and API key to `~/.outerlayer/config.json` once. The key is read from stdin (`echo "$KEY" \| outerlayer login …`) or a prompt with echo off; it is never a flag. `--no-input` refuses to prompt. |
148
- | `outerlayer init` | Install the capture hooks and the status-line segment. `--json` for scripts. Claude Code deletes transcripts after ~30 days; run `outerlayer daemon` separately to mirror them first — `init` does not start it for you. |
148
+ | `outerlayer init` | Install the capture hooks and the status-line segment. `--json` for scripts. Run through `npx`, it copies the CLI to `~/.outerlayer/cli` and points the hooks at that copy, so they survive npm clearing its cache; `npx @outerlayer/cli@latest init` upgrades it. From any other install, the hooks run that install. Claude Code deletes transcripts after ~30 days; run `outerlayer daemon` separately to mirror them first — `init` does not start it for you. |
149
149
  | `outerlayer daemon` | Run the copy-out daemon in the foreground (`--once` for a single sweep, which uploads nothing). Once cloud credentials exist, it also streams a launched session's new turns as they land — see Privacy, above. `outerlayer watch` is the former name and still works, with a warning. |
150
150
  | `outerlayer doctor` | Check the installation: hooks, status-line freshness, and sync health. `--json` prints the checks and a summary for scripts. |
151
151
  | `outerlayer context emit [--check]` | Compile `.outerlayer/` into each configured target tool's native files (targets come from `.outerlayer/config.json`). `--check` computes outputs and diffs against disk without writing (CI mode). Bare `outerlayer emit` with no name still compiles, with a deprecation warning. |
@@ -1 +1 @@
1
- {"id":"2026-09-23T16:41:05.295Z+7ad24522","root":"/Users/carbonteq/manage-ai/control-plane/cli-release","pkg":"outerlayer"}
1
+ {"id":"2026-09-24T11:40:02.645Z+05fbecd","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
@@ -647,4 +647,4 @@ function logHookError(home, err) {
647
647
  }
648
648
  }
649
649
 
650
- export { AUTO_SYNC_DEBOUNCE_MS, SYNC_STALE_AFTER_MS, WORK_ADD_RETRIES, assessSyncHealth, checkInstalledCliStaleness, contextPossiblyGoverned, formatAgo, handleWorkLaunch, hookFiredMarkerPath, maybeAutoSync, readSyncStatus, refreshCommand, runHookFast, sanitizeForContext, spoolDir, workspaceRootOf, writeSyncStatus };
650
+ export { AUTO_SYNC_DEBOUNCE_MS, SYNC_STALE_AFTER_MS, WORK_ADD_RETRIES, assessSyncHealth, checkInstalledCliStaleness, contextPossiblyGoverned, formatAgo, handleWorkLaunch, hookFiredMarkerPath, installedCliDistDir, maybeAutoSync, readSyncStatus, refreshCommand, runHookFast, sanitizeForContext, spoolDir, workspaceRootOf, writeSyncStatus };
@@ -3,9 +3,9 @@ import { createRequire } from 'node:module';
3
3
  import { C } from './chunk-YRYMNBGQ.js';
4
4
  import { readLaunchSpoolState, launchesPath, launchStatusIsDecisive } from './chunk-RCQXYLMO.js';
5
5
  import { readLatestProvenanceForSession, readContextProvenance } from './chunk-ZJSNLVCE.js';
6
- import { spoolDir, writeSyncStatus } from './chunk-A6NNKRJU.js';
6
+ import { spoolDir, writeSyncStatus } from './chunk-3VQ4XXQA.js';
7
7
  import { installPostRewriteHook } from './chunk-IWIUYLDR.js';
8
- import { hookExecSpoolPath, spoolDir as spoolDir$1 } from './chunk-YMTXR7PJ.js';
8
+ import { hookExecSpoolPath, spoolDir as spoolDir$1 } from './chunk-YOOSBOKS.js';
9
9
  import { readCloudConfig, cloudConfigPath, writeCloudConfig } from './chunk-TFUIDMOB.js';
10
10
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
11
11
  import { __export } from './chunk-Z5GEFMRW.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { resolveRepoIdentity, detectActiveSession } from './chunk-DEDV5V4U.js';
3
+ import { resolveRepoIdentity, detectActiveSession } from './chunk-BQB3U2VD.js';
4
4
  import { parseTrackerNumber, trackerNumberError } from './chunk-RCQXYLMO.js';
5
5
  import { readCloudConfig } from './chunk-TFUIDMOB.js';
6
6
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { startTimeOf, isSameProcess } from './chunk-OZ7C3XUE.js';
4
4
  import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-JJP7YLMN.js';
5
- import { postJson, WorkCommandError } from './chunk-VU34RWDU.js';
5
+ import { postJson, WorkCommandError } from './chunk-HNCCD2IX.js';
6
6
  import { relative, dirname, delimiter, join } from 'path';
7
7
  import { existsSync, readFileSync, mkdirSync, writeFileSync, openSync, statSync, closeSync, readdirSync } from 'fs';
8
8
  import { spawn } from 'child_process';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { decodeWrappedCommand } from './chunk-ECSYRPCC.js';
3
+ import { decodeWrappedCommand } from './chunk-R5KBGVII.js';
4
4
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
5
5
  import { readFileSync } from 'fs';
6
6
  import { spawn } from 'child_process';
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
4
4
  import { existsSync, readFileSync, mkdirSync, copyFileSync, writeFileSync } from 'fs';
5
- import { join, dirname } from 'path';
5
+ import { join, dirname, isAbsolute } from 'path';
6
6
 
7
7
  createRequire(import.meta.url);
8
8
  var REGISTERED_EVENTS = ["SessionStart", "SessionEnd", "Stop"];
@@ -46,14 +46,20 @@ function quoteBin(bin) {
46
46
  function isOurBin(bin, cliBin) {
47
47
  if (cliBin !== void 0 && normalizeBinPath(bin) === normalizeBinPath(cliBin)) return true;
48
48
  const parts = bin.replace(/\\/g, "/").split("/");
49
+ if (isPublishedPackageBin(parts)) return true;
49
50
  const base = (parts.pop() ?? "").toLowerCase();
50
51
  if (base === "outerlayer" || base === "outerlayer.exe" || base === "outerlayer.cmd") return true;
51
52
  return parts.some((p) => p.toLowerCase() === ".outerlayer");
52
53
  }
54
+ function isPublishedPackageBin(parts) {
55
+ const n = parts.length;
56
+ if (n === 2 && parts[0] === "@outerlayer" && /^cli(@[^/]+)?$/.test(parts[1])) return true;
57
+ return parts[n - 4] === "@outerlayer" && parts[n - 3] === "cli" && parts[n - 2] === "dist" && parts[n - 1] === "index.js";
58
+ }
53
59
  function normalizeBinPath(bin) {
54
60
  return bin.replace(/\\/g, "/");
55
61
  }
56
- function parseCliInvocation(command, cliBin) {
62
+ function splitCliInvocation(command, cliBin) {
57
63
  if (typeof command !== "string") return null;
58
64
  const tokens = tokenizeCommand(command.trim());
59
65
  if (!tokens) return null;
@@ -62,7 +68,25 @@ function parseCliInvocation(command, cliBin) {
62
68
  if (launcher === "node" || launcher === "node.exe" || launcher === "npx") i = 1;
63
69
  const bin = tokens[i];
64
70
  if (!bin || !isOurBin(bin, cliBin)) return null;
65
- return tokens.slice(i + 1);
71
+ return { bin, args: tokens.slice(i + 1), viaNpx: launcher === "npx" };
72
+ }
73
+ function parseCliInvocation(command, cliBin) {
74
+ return splitCliInvocation(command, cliBin)?.args ?? null;
75
+ }
76
+ function ourCommandBins(settings) {
77
+ const bins = [];
78
+ const add = (command) => {
79
+ const parsed = splitCliInvocation(command);
80
+ if (!parsed || parsed.viaNpx) return;
81
+ if (!["hook", "hook-wrap", "statusline"].includes(parsed.args[0] ?? "")) return;
82
+ if (parsed.bin.includes("$") || !isAbsolute(parsed.bin)) return;
83
+ if (!bins.includes(parsed.bin)) bins.push(parsed.bin);
84
+ };
85
+ for (const matchers of Object.values(settings?.hooks ?? {})) {
86
+ for (const matcher of matchers ?? []) for (const h of matcher.hooks ?? []) add(h.command);
87
+ }
88
+ add(settings?.statusLine?.command);
89
+ return bins;
66
90
  }
67
91
  function parseLifecycleHookCommand(command, cliBin) {
68
92
  const args = parseCliInvocation(command, cliBin);
@@ -246,6 +270,28 @@ function wrapHooks(settings, cliBin, opts = {}) {
246
270
  }
247
271
  return { next, changed, wrapped };
248
272
  }
273
+ function repointWrappedHooks(settings, cliBin) {
274
+ const next = settings ? structuredClone(settings) : {};
275
+ let changed = false;
276
+ if (!next.hooks || !cliBinResolvable(cliBin)) return { next, changed };
277
+ for (const matchers of Object.values(next.hooks)) {
278
+ for (const matcher of matchers ?? []) {
279
+ for (let hi = 0; hi < matcher.hooks.length; hi++) {
280
+ const h = matcher.hooks[hi];
281
+ const parsed = splitCliInvocation(h.command, cliBin);
282
+ if (!parsed || parsed.args[0] !== "hook-wrap") continue;
283
+ if (normalizeBinPath(parsed.bin) === normalizeBinPath(cliBin)) continue;
284
+ const original = wrappedOriginalCommand(h, cliBin);
285
+ if (original === null) continue;
286
+ const flag = parsed.args.includes("--capture-output") ? " --capture-output" : "";
287
+ const desired = `${quoteBin(cliBin)} hook-wrap --id ${encodeWrappedCommand(original)}${flag}`;
288
+ matcher.hooks[hi] = { ...h, command: desired, [WRAP_MARKER]: original };
289
+ changed = true;
290
+ }
291
+ }
292
+ }
293
+ return { next, changed };
294
+ }
249
295
  function statuslineCommand(cliBin) {
250
296
  return `${quoteBin(cliBin)} statusline`;
251
297
  }
@@ -331,4 +377,4 @@ function unwrapHooks(settings, cliBin) {
331
377
  return { next, changed, unwrapped };
332
378
  }
333
379
 
334
- export { AUTO_WRAP_EVENTS, REGISTERED_EVENTS, SettingsParseError, cliBinResolvable, decodeWrappedCommand, isOurHookCommand, isOurStatuslineSlot, listHookCandidates, mergeHooks, mergeStatusline, readSettings, removeHooks, removeStatusline, settingsPath, statuslineWrappedOriginal, unwrapHooks, wrapHooks, wrappedOriginalCommand, writeSettings };
380
+ export { AUTO_WRAP_EVENTS, REGISTERED_EVENTS, SettingsParseError, cliBinResolvable, decodeWrappedCommand, isOurHookCommand, isOurStatuslineSlot, listHookCandidates, mergeHooks, mergeStatusline, ourCommandBins, readSettings, removeHooks, removeStatusline, repointWrappedHooks, settingsPath, statuslineWrappedOriginal, unwrapHooks, wrapHooks, wrappedOriginalCommand, writeSettings };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { decodeWrappedCommand } from './chunk-ECSYRPCC.js';
3
+ import { decodeWrappedCommand } from './chunk-R5KBGVII.js';
4
4
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
5
5
  import { readFileSync, mkdirSync, appendFileSync, writeFileSync } from 'fs';
6
6
  import { spawn } from 'child_process';
@@ -2,22 +2,22 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { pinExists, readPin, readContextManifest, readDegraded, readSourceCache } from './chunk-A3WLZX2F.js';
4
4
  import './chunk-KFYJV2ZG.js';
5
- import { readStatuslineState, STATE_FRESH_MS } from './chunk-XN2XZFTK.js';
6
- import { compareVersions, SUPPORTED_VERSIONS, readSessionRepos } from './chunk-DEDV5V4U.js';
5
+ import { readStatuslineState, STATE_FRESH_MS } from './chunk-NTTPJV35.js';
6
+ import { compareVersions, SUPPORTED_VERSIONS, readSessionRepos } from './chunk-BQB3U2VD.js';
7
7
  import { C, NO_COLOR_FLAG, warnDeprecated, stripNoColor, API_KEY_FLAG_DEPRECATION } from './chunk-YRYMNBGQ.js';
8
8
  import { parseTrackerNumber, trackerNumberError } from './chunk-RCQXYLMO.js';
9
9
  import './chunk-ZJSNLVCE.js';
10
- import { hookFiredMarkerPath, sanitizeForContext, spoolDir, assessSyncHealth, readSyncStatus, SYNC_STALE_AFTER_MS, formatAgo, checkInstalledCliStaleness, workspaceRootOf, refreshCommand } from './chunk-A6NNKRJU.js';
10
+ import { hookFiredMarkerPath, installedCliDistDir, sanitizeForContext, spoolDir, assessSyncHealth, readSyncStatus, SYNC_STALE_AFTER_MS, formatAgo, checkInstalledCliStaleness, workspaceRootOf, refreshCommand } from './chunk-3VQ4XXQA.js';
11
11
  import { managedHookScripts, installPostRewriteHook, installPreCommitGuardHook, removePostRewriteHook, removePreCommitGuardHook, deadHooksState, preparePackageManagerCommand, contextExcludesPresent, postRewriteHookPresence } from './chunk-IWIUYLDR.js';
12
- import './chunk-YMTXR7PJ.js';
13
- import { SettingsParseError, settingsPath, readSettings, listHookCandidates, wrapHooks, writeSettings, unwrapHooks, REGISTERED_EVENTS, removeHooks, removeStatusline, cliBinResolvable, mergeHooks, AUTO_WRAP_EVENTS, mergeStatusline, isOurStatuslineSlot, statuslineWrappedOriginal, isOurHookCommand, wrappedOriginalCommand } from './chunk-ECSYRPCC.js';
12
+ import './chunk-YOOSBOKS.js';
13
+ import { SettingsParseError, settingsPath, readSettings, listHookCandidates, wrapHooks, writeSettings, unwrapHooks, REGISTERED_EVENTS, removeHooks, removeStatusline, cliBinResolvable, mergeHooks, repointWrappedHooks, AUTO_WRAP_EVENTS, mergeStatusline, isOurStatuslineSlot, statuslineWrappedOriginal, isOurHookCommand, ourCommandBins, wrappedOriginalCommand } from './chunk-R5KBGVII.js';
14
14
  import { readCloudConfig } from './chunk-TFUIDMOB.js';
15
15
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
16
16
  import './chunk-Z5GEFMRW.js';
17
17
  import { EventEmitter } from 'events';
18
18
  import childProcess, { execFileSync } from 'child_process';
19
- import path, { dirname, join } from 'path';
20
- import fs, { unlinkSync, existsSync, readFileSync, writeFileSync, accessSync, constants, statSync, readdirSync, mkdirSync, renameSync } from 'fs';
19
+ import path, { dirname, join, isAbsolute } from 'path';
20
+ import fs, { existsSync, unlinkSync, readFileSync, mkdirSync, cpSync, readdirSync, renameSync, statSync, rmSync, writeFileSync, accessSync, constants, realpathSync } from 'fs';
21
21
  import process2 from 'process';
22
22
  import { stripVTControlCharacters } from 'util';
23
23
  import { fileURLToPath } from 'url';
@@ -3380,6 +3380,52 @@ function useColor() {
3380
3380
 
3381
3381
  // ../../node_modules/commander/index.js
3382
3382
  new Command();
3383
+ function isEphemeralBin(bin) {
3384
+ return bin.replace(/\\/g, "/").split("/").some((p) => p === "_npx" || p === "dlx" || p.startsWith("dlx-") || p.startsWith("bunx-"));
3385
+ }
3386
+ function initHookBin(opts) {
3387
+ const { runningBin } = opts;
3388
+ if (opts.remove || !isAbsolute(runningBin) || !isEphemeralBin(runningBin) || !existsSync(runningBin)) return runningBin;
3389
+ return installCliCopy({ home: opts.home, sourceBin: runningBin }).bin;
3390
+ }
3391
+ var STALE_FILE_MS = 7 * 24 * 60 * 60 * 1e3;
3392
+ function samePath(a, b) {
3393
+ try {
3394
+ return realpathSync(a) === realpathSync(b);
3395
+ } catch {
3396
+ return false;
3397
+ }
3398
+ }
3399
+ function installCliCopy(opts) {
3400
+ const rename = opts.rename ?? renameSync;
3401
+ const now = opts.now ?? Date.now;
3402
+ const targetDist = installedCliDistDir(opts.home);
3403
+ const targetRoot = dirname(targetDist);
3404
+ const bin = join(targetDist, "index.js");
3405
+ const sourceDist = dirname(opts.sourceBin);
3406
+ if (samePath(sourceDist, targetDist)) return { bin, copied: false };
3407
+ mkdirSync(targetDist, { recursive: true });
3408
+ const staged = join(targetRoot, `.staging-${process.pid}-${now()}`);
3409
+ try {
3410
+ cpSync(sourceDist, join(staged, "dist"), { recursive: true });
3411
+ const sourcePkg = join(dirname(sourceDist), "package.json");
3412
+ if (existsSync(sourcePkg)) cpSync(sourcePkg, join(staged, "package.json"));
3413
+ const incoming = readdirSync(join(staged, "dist"));
3414
+ for (const name of incoming) {
3415
+ if (name !== "index.js") rename(join(staged, "dist", name), join(targetDist, name));
3416
+ }
3417
+ if (existsSync(join(staged, "package.json"))) rename(join(staged, "package.json"), join(targetRoot, "package.json"));
3418
+ rename(join(staged, "dist", "index.js"), bin);
3419
+ const shipped = new Set(incoming);
3420
+ for (const name of readdirSync(targetDist)) {
3421
+ const path2 = join(targetDist, name);
3422
+ if (!shipped.has(name) && now() - statSync(path2).mtimeMs > STALE_FILE_MS) rmSync(path2, { recursive: true, force: true });
3423
+ }
3424
+ } finally {
3425
+ rmSync(staged, { recursive: true, force: true });
3426
+ }
3427
+ return { bin, copied: true };
3428
+ }
3383
3429
  function manifestPath(home = homeFromEnv()) {
3384
3430
  return join(home, ".outerlayer", "hooks-manifest.json");
3385
3431
  }
@@ -3510,8 +3556,9 @@ function runInit(opts) {
3510
3556
  return { path: path2, changed: false, events: REGISTERED_EVENTS, wrapped: [], cliBinUnresolved: true };
3511
3557
  }
3512
3558
  const merged = mergeHooks(current, opts.cliBin);
3513
- let next = merged.next;
3514
- let changed = merged.changed;
3559
+ const repointed = repointWrappedHooks(merged.next, opts.cliBin);
3560
+ let next = repointed.next;
3561
+ let changed = merged.changed || repointed.changed;
3515
3562
  let wrapped = [];
3516
3563
  if (opts.wrapHooks ?? true) {
3517
3564
  const wrapResult = wrapHooks(next, opts.cliBin, { events: [...AUTO_WRAP_EVENTS] });
@@ -3858,6 +3905,15 @@ function checkHooksInstalled(home, cwd, firingFresh) {
3858
3905
  (event) => (settings.hooks?.[event] ?? []).some((b) => (b.hooks ?? []).some(isOurHookCommand))
3859
3906
  );
3860
3907
  if (installed.length === REGISTERED_EVENTS.length) {
3908
+ const missing = ourCommandBins(settings).filter((bin) => !cliBinResolvable(bin));
3909
+ if (missing.length > 0) {
3910
+ return {
3911
+ name,
3912
+ status: "fail",
3913
+ detail: `hooks in ${path2} run ${missing.join(", ")}, which no longer exists \u2014 no session is being captured`,
3914
+ fix: "Run `npx @outerlayer/cli init` to reinstall."
3915
+ };
3916
+ }
3861
3917
  return { name, status: "pass", detail: `${installed.join(", ")} (${scope})` };
3862
3918
  }
3863
3919
  if (installed.length > 0) {
@@ -4361,12 +4417,21 @@ function buildProgram(argv = process.argv) {
4361
4417
  "after",
4362
4418
  "\nIdempotent: settings are backed up before any write, and a second run\nchanges nothing. Wrapping adds one spawn per hook firing; undo it with\n`outerlayer hooks unwrap`. An occupied status-line slot is wrapped, never\nreplaced.\n"
4363
4419
  ).action((opts) => {
4364
- const cliBin = resolveCliBin();
4420
+ let cliBin = resolveCliBin();
4365
4421
  if (opts.org) {
4366
4422
  process.stdout.write(orgRolloutSnippet(cliBin) + "\n");
4367
4423
  return;
4368
4424
  }
4369
4425
  const scope = opts.project ? "project" : "user";
4426
+ try {
4427
+ cliBin = initHookBin({ home: homeFromEnv(), runningBin: cliBin, remove: opts.remove === true });
4428
+ } catch (err) {
4429
+ fail(
4430
+ `could not copy the CLI to ~/.outerlayer/cli: ${err instanceof Error ? err.message : String(err)}
4431
+ Hooks were not changed. Fix the permissions on ~/.outerlayer, then re-run ${C.yellow}outerlayer init${C.reset}.`
4432
+ );
4433
+ return;
4434
+ }
4370
4435
  try {
4371
4436
  const result = runInit({
4372
4437
  scope,
@@ -4445,7 +4510,7 @@ ${fails === 0 ? `${C.green}\u2713${C.reset}` : `${C.red}\u2717${C.reset}`} ${pas
4445
4510
  "\nIncremental: only sessions newer than the last checkpoint ship. The tier\nis applied on this machine before anything leaves it; `--dry-run` prints\nexactly what would. The hook-triggered background sync runs `--quiet`.\nExit 2 means the server rejected at least one session.\n"
4446
4511
  ).action(async (opts) => {
4447
4512
  warnIfApiKeyFlag(opts);
4448
- const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-C5UGI4SF.js');
4513
+ const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-S7Q6DWU3.js');
4449
4514
  try {
4450
4515
  const result = await runSync({
4451
4516
  url: opts.url,
@@ -4474,7 +4539,7 @@ ${fails === 0 ? `${C.green}\u2713${C.reset}` : `${C.red}\u2717${C.reset}`} ${pas
4474
4539
  if (invokedCommandToken(argv) === "watch") {
4475
4540
  warnDeprecated("`outerlayer watch` is now `outerlayer daemon`; the old name will be removed in a future release.");
4476
4541
  }
4477
- const { runWatch } = await import('./watch-V3K4PESQ.js');
4542
+ const { runWatch } = await import('./watch-NRLXJUST.js');
4478
4543
  await runWatch({ once: opts.once });
4479
4544
  });
4480
4545
  program2.command("hook <event>", { hidden: true }).description("capture-hook fast path, installed by `init`").action(() => {
@@ -4521,7 +4586,7 @@ function registerEmitCommands(program2) {
4521
4586
  return;
4522
4587
  }
4523
4588
  warnIfApiKeyFlag(opts);
4524
- const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-NDFHMJX7.js');
4589
+ const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-YOA5BJKL.js');
4525
4590
  try {
4526
4591
  const result = await runEmitResult({
4527
4592
  name,
@@ -4550,7 +4615,7 @@ function registerEmitCommands(program2) {
4550
4615
  '\n outerlayer emit artifact shot.png --caption "the dot row, current dot marked" --for LOGIN-01\n\nInside a recorded Claude Code session the artifact spools locally and ships,\nbound to that session, on the next `outerlayer sync` \u2014 but only if that\nsession was launched with OUTERLAYER_WORK; without it nothing the session\nproduces may leave the machine, and the command refuses rather than queue an\nartifact that can never ship. Otherwise it uploads immediately, anchored to a\npull request (--pr, or CI\'s PR context) or to the current git checkout. With\nnothing to attach it to, the command refuses.\n\n--replaces: an already-uploaded target is marked superseded and hidden\neverywhere, bytes and deep link untouched; a still-queued one is cancelled\nlocally so it never uploads. One correction can retire several duplicates.\n'
4551
4616
  ).action(async (file, opts) => {
4552
4617
  warnIfApiKeyFlag(opts);
4553
- const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-23F4YKQ3.js');
4618
+ const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-KPPD3YLO.js');
4554
4619
  let pr;
4555
4620
  if (opts.pr !== void 0) {
4556
4621
  pr = parseTrackerNumber(opts.pr);
@@ -4584,7 +4649,7 @@ function registerEmitCommands(program2) {
4584
4649
  '\n outerlayer emit finding --id r1-f1 --subject change --title "Off-by-one" \\\n --file src/loop.ts --line 42 --severity major --kind behavior \\\n --verdict confirmed --source reviewer --where "review pass 1"\n\nRecords one finding \u2014 what an agent noticed was wrong about the change, or\nabout a rule it ran on. Validated against the same contract the gateway\nchecks before anything is sent; a subject of context needs --rule-path,\n--rule-quote and --rule-relation together \u2014 all three are required, not\njust --rule-path.\n--item names the work item; without it, inside a recorded session, the\nitem that session was launched for is used automatically \u2014 a session may\nrecord findings on its own item, unlike `outerlayer emit <name>`.\n'
4585
4650
  ).action(async (opts) => {
4586
4651
  warnIfApiKeyFlag(opts);
4587
- const { runEmitFinding, EmitFindingError } = await import('./emit-finding-cmd-6K7ERPKG.js');
4652
+ const { runEmitFinding, EmitFindingError } = await import('./emit-finding-cmd-VR5VEGXJ.js');
4588
4653
  try {
4589
4654
  const result = await runEmitFinding({
4590
4655
  id: opts.id,
@@ -4627,7 +4692,7 @@ function registerEmitCommands(program2) {
4627
4692
  "\n outerlayer emit findings review.json --item 412\n\nRecords a whole batch at once \u2014 a FindingBatch JSON file (schemaVersion,\noptional headSha / contextSourceSha, and 1-500 findings), validated against\nthe same contract `emit finding` uses before anything is sent. Re-emitting\nan id already on the item replaces that row rather than adding a second one.\n--item names the work item; without it, inside a recorded session, the item\nthat session was launched for is used automatically.\n"
4628
4693
  ).action(async (file, opts) => {
4629
4694
  warnIfApiKeyFlag(opts);
4630
- const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-6K7ERPKG.js');
4695
+ const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-VR5VEGXJ.js');
4631
4696
  try {
4632
4697
  const result = await runEmitFindings({
4633
4698
  file,
@@ -4651,7 +4716,7 @@ function registerEmitCommands(program2) {
4651
4716
  '\nThe escape hatch for a checkout, and reflog, that no longer exists. Records\none explicit human attestation, uploaded immediately \u2014 no session detection,\nno spool. The attesting identity is the dashboard member the control plane\nresolves from the API key; it renders as "attested by <name>" in the PR\nevidence comment, distinct from recorded or recovered credit. Refused, with\nnothing stored, for a malformed SHA, an unknown PR, or a machine key with no\nmember to attest as.\n'
4652
4717
  ).action(async (opts) => {
4653
4718
  warnIfApiKeyFlag(opts);
4654
- const { runEmitCommitCredit, EmitCommitCreditError } = await import('./emit-commit-credit-cmd-2GX5M2BR.js');
4719
+ const { runEmitCommitCredit, EmitCommitCreditError } = await import('./emit-commit-credit-cmd-656BRAQ4.js');
4655
4720
  try {
4656
4721
  await runEmitCommitCredit({
4657
4722
  sha: opts.sha,
@@ -4677,7 +4742,7 @@ function registerWorkCommands(program2) {
4677
4742
  "\n outerlayer work add --issue 42\n\nRecords that a named source \u2014 a recorded session, a CI run, or the API\nkey's bound member \u2014 is working on an issue or pull request. This is\nthe only way an item becomes visible on the Floor. A second add of the\nsame subject by the same source is a no-op.\n"
4678
4743
  ).action(async (opts) => {
4679
4744
  warnIfApiKeyFlag(opts);
4680
- const { runWorkAdd, WorkCommandError } = await import('./work-cmd-CW26EZZO.js');
4745
+ const { runWorkAdd, WorkCommandError } = await import('./work-cmd-ABP6XDBP.js');
4681
4746
  try {
4682
4747
  await runWorkAdd(opts);
4683
4748
  } catch (err) {
@@ -4693,7 +4758,7 @@ function registerWorkCommands(program2) {
4693
4758
  "\n outerlayer work link-session 42\n\nNames an item that already exists on the calling session \u2014 it never\ncreates one. Create an item first with `outerlayer work add`. Linking\nthe same session to the same item twice is a no-op.\n"
4694
4759
  ).action(async (number, opts) => {
4695
4760
  warnIfApiKeyFlag(opts);
4696
- const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-CW26EZZO.js');
4761
+ const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-ABP6XDBP.js');
4697
4762
  try {
4698
4763
  await runWorkLinkSession({ ...opts, number });
4699
4764
  } catch (err) {
@@ -4715,7 +4780,7 @@ live addition remains on it.
4715
4780
  `
4716
4781
  ).action(async (opts) => {
4717
4782
  warnIfApiKeyFlag(opts);
4718
- const { runWorkRemove, WorkCommandError } = await import('./work-cmd-CW26EZZO.js');
4783
+ const { runWorkRemove, WorkCommandError } = await import('./work-cmd-ABP6XDBP.js');
4719
4784
  try {
4720
4785
  await runWorkRemove(opts);
4721
4786
  } catch (err) {
@@ -4728,7 +4793,7 @@ live addition remains on it.
4728
4793
  });
4729
4794
  workCmd.command("status").description("Show one item's stage, gate ledger, and additions").option("--item <number>", "the item's number inside this factory").option("--issue <number>", "issue number").option("--repo <owner/name>", "repository (default: the current checkout's remote)").option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "app id the key is bound to (or OUTERLAYER_APP_ID / config)").action(async (opts) => {
4730
4795
  warnIfApiKeyFlag(opts);
4731
- const { runWorkStatus, WorkCommandError } = await import('./work-cmd-CW26EZZO.js');
4796
+ const { runWorkStatus, WorkCommandError } = await import('./work-cmd-ABP6XDBP.js');
4732
4797
  try {
4733
4798
  await runWorkStatus(opts);
4734
4799
  } catch (err) {
@@ -4741,7 +4806,7 @@ live addition remains on it.
4741
4806
  });
4742
4807
  workCmd.command("list").description("List live work items for this factory").option("--stage <spec|build|review>", "filter by stage").option("--section <attention|waiting|flowing>", "filter by Queue section").option("--repo <owner/name>", "repository (default: the current checkout's remote)").option("--unclaimed", "only items with no live claim").option("--startable", "only items with no live claim, linked session, or linked pull request").option("--needs <amend>", "only items an open artifact fail is waiting on").option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "app id the key is bound to (or OUTERLAYER_APP_ID / config)").action(async (opts) => {
4743
4808
  warnIfApiKeyFlag(opts);
4744
- const { runWorkList, WorkCommandError } = await import('./work-cmd-CW26EZZO.js');
4809
+ const { runWorkList, WorkCommandError } = await import('./work-cmd-ABP6XDBP.js');
4745
4810
  try {
4746
4811
  await runWorkList(opts);
4747
4812
  } catch (err) {
@@ -4757,7 +4822,7 @@ live addition remains on it.
4757
4822
  "\n outerlayer work claim --item 42 --kind implement\n\nRecords a lease for this host. A live lease already held by a\ndifferent host is refused; claiming again under the same host extends\nit.\n"
4758
4823
  ).action(async (opts) => {
4759
4824
  warnIfApiKeyFlag(opts);
4760
- const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-FQDWQVT2.js');
4825
+ const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-HXB7K27H.js');
4761
4826
  try {
4762
4827
  await runWorkClaim(opts);
4763
4828
  } catch (err) {
@@ -4773,7 +4838,7 @@ live addition remains on it.
4773
4838
  "\n outerlayer work renew --item 42\n\nExtends this host's own live lease. Refused with a 410 if the lease\nhas expired, or a 403 if a different host holds it.\n"
4774
4839
  ).action(async (opts) => {
4775
4840
  warnIfApiKeyFlag(opts);
4776
- const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-FQDWQVT2.js');
4841
+ const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-HXB7K27H.js');
4777
4842
  try {
4778
4843
  await runWorkRenew(opts);
4779
4844
  } catch (err) {
@@ -4792,7 +4857,7 @@ live addition remains on it.
4792
4857
  "\n outerlayer work release --item 42 --outcome ok\n\nMarks this host's lease released, optionally with an outcome.\nReleasing an already-released lease is a no-op that returns the\nrecorded release time and outcome.\n"
4793
4858
  ).action(async (opts) => {
4794
4859
  warnIfApiKeyFlag(opts);
4795
- const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-FQDWQVT2.js');
4860
+ const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-HXB7K27H.js');
4796
4861
  try {
4797
4862
  await runWorkRelease(opts);
4798
4863
  } catch (err) {
@@ -4808,7 +4873,7 @@ live addition remains on it.
4808
4873
  "\n outerlayer work pr 481\n\nRun inside a session already on a work item. Records that pull\nrequest 481 in the checkout's repository belongs to that item \u2014 the\nsame fact a `pr-link` in the session's own transcript records on\nsync. Idempotent: declaring the same pull request twice is a no-op.\n"
4809
4874
  ).action(async (number, opts) => {
4810
4875
  warnIfApiKeyFlag(opts);
4811
- const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-W2QNMWXP.js');
4876
+ const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-GOYSPEN2.js');
4812
4877
  try {
4813
4878
  await runWorkPr({ ...opts, number });
4814
4879
  } catch (err) {
@@ -4825,7 +4890,7 @@ function registerRunnerCommands(program2) {
4825
4890
  const configOption = "the cloud config file to run against (default: ~/.outerlayer/config.json)";
4826
4891
  runnerCmd.command("start").description("Run the loop: claim work, run it, report, clean up, repeat").option("--config <path>", configOption).action(async (opts) => {
4827
4892
  const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-POF7DEQW.js');
4828
- const { start, RunnerStartError } = await import('./loop-NFSOBUUJ.js');
4893
+ const { start, RunnerStartError } = await import('./loop-BWE2BS6J.js');
4829
4894
  const { RunnerAlreadyRunningError } = await import('./pidfile-PTW76F56.js');
4830
4895
  const configPath = opts.config ?? defaultRunnerConfigPath();
4831
4896
  try {
@@ -4840,7 +4905,7 @@ function registerRunnerCommands(program2) {
4840
4905
  });
4841
4906
  runnerCmd.command("check").description("Validate the config, the hooks and the key, and print the effective settings").option("--config <path>", configOption).action(async (opts) => {
4842
4907
  const { defaultRunnerConfigPath, loadRunnerConfig, checkHooks: checkHooks2, RunnerConfigError } = await import('./config-POF7DEQW.js');
4843
- const { probeCredentials } = await import('./loop-NFSOBUUJ.js');
4908
+ const { probeCredentials } = await import('./loop-BWE2BS6J.js');
4844
4909
  const configPath = opts.config ?? defaultRunnerConfigPath();
4845
4910
  let config;
4846
4911
  try {
@@ -4913,15 +4978,15 @@ Next:
4913
4978
  });
4914
4979
  runnerCmd.command("stop").description("Take no more work; wait for running jobs to finish, then exit").option("--config <path>", "the cloud config file naming the runner to stop").option("--now", "end running jobs immediately, with outcome stopped").action(async (opts) => {
4915
4980
  const { defaultRunnerConfigPath } = await import('./config-POF7DEQW.js');
4916
- const { requestStop } = await import('./loop-NFSOBUUJ.js');
4981
+ const { requestStop } = await import('./loop-BWE2BS6J.js');
4917
4982
  const configPath = opts.config ?? defaultRunnerConfigPath();
4918
4983
  await requestStop(configPath, Boolean(opts.now));
4919
4984
  });
4920
4985
  runnerCmd.command("status").description("List running jobs; with --recent, finished ones too").option("--config <path>", "the cloud config file naming the runner to inspect").option("--recent", "also list finished jobs, newest first, capped at 20").option("--json", "machine-readable JSON output").action(async (opts) => {
4921
4986
  const { defaultRunnerConfigPath, loadRunnerConfig } = await import('./config-POF7DEQW.js');
4922
4987
  const { jobsDir } = await import('./paths-D2VGWWFI.js');
4923
- const { listJobFiles, runnerProcessState } = await import('./loop-NFSOBUUJ.js');
4924
- const { renderStatus } = await import('./status-WGOJTXZF.js');
4988
+ const { listJobFiles, runnerProcessState } = await import('./loop-BWE2BS6J.js');
4989
+ const { renderStatus } = await import('./status-JHVSZYC5.js');
4925
4990
  const path2 = await import('path');
4926
4991
  const configPath = opts.config ?? defaultRunnerConfigPath();
4927
4992
  const all = listJobFiles(configPath);
@@ -4959,7 +5024,7 @@ Next:
4959
5024
  });
4960
5025
  runnerCmd.command("logs").argument("<item>", "the work item's number in the factory").description("Print the newest attempt's log for one item").option("--config <path>", "the cloud config file naming the runner to inspect").option("-f, --follow", "keep printing as the log grows").action(async (itemArg, opts) => {
4961
5026
  const { defaultRunnerConfigPath } = await import('./config-POF7DEQW.js');
4962
- const { listJobFiles } = await import('./loop-NFSOBUUJ.js');
5027
+ const { listJobFiles } = await import('./loop-BWE2BS6J.js');
4963
5028
  const { newestAttempt, logPathFor, tail, RunnerLogsError } = await import('./logs-TRNPQM42.js');
4964
5029
  const configPath = opts.config ?? defaultRunnerConfigPath();
4965
5030
  const item = parseTrackerNumber(itemArg);
@@ -5100,7 +5165,13 @@ ${C.dim}${file.path}${C.reset}
5100
5165
  fail("--no-input forbids prompting; pass --all to wrap every candidate without being asked.");
5101
5166
  return;
5102
5167
  }
5103
- const cliBin = resolveCliBin();
5168
+ let cliBin;
5169
+ try {
5170
+ cliBin = initHookBin({ home: homeFromEnv(), runningBin: resolveCliBin(), remove: false });
5171
+ } catch (err) {
5172
+ fail(`could not copy the CLI to ~/.outerlayer/cli: ${err instanceof Error ? err.message : String(err)}`);
5173
+ return;
5174
+ }
5104
5175
  const scope = opts.project ? "project" : "user";
5105
5176
  const path2 = settingsPath(scope);
5106
5177
  let settings;
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { staleBuildRefusal, staleBuildWarning, ARTIFACT_MAX_CAPTION_LENGTH, ArtifactCriterionIdSchema, ARTIFACT_MAX_FILENAME_LENGTH, readEffectiveArtifactSpoolState, localArtifactIds, isArtifactTombstoned, mediaTypeForArtifactPath, inferArtifactKind, resolveRepoIdentity, detectActiveSession, launchRefusalForSession, artifactBlobsDir, appendArtifactRecord, artifactsSpoolPath, findPendingArtifactRecord, detectCi, appendArtifactTombstone, ARTIFACT_MAX_REPLACES_TARGETS } from './chunk-DEDV5V4U.js';
3
+ import { staleBuildRefusal, staleBuildWarning, ARTIFACT_MAX_CAPTION_LENGTH, ArtifactCriterionIdSchema, ARTIFACT_MAX_FILENAME_LENGTH, readEffectiveArtifactSpoolState, localArtifactIds, isArtifactTombstoned, mediaTypeForArtifactPath, inferArtifactKind, resolveRepoIdentity, detectActiveSession, launchRefusalForSession, artifactBlobsDir, appendArtifactRecord, artifactsSpoolPath, findPendingArtifactRecord, detectCi, appendArtifactTombstone, ARTIFACT_MAX_REPLACES_TARGETS } from './chunk-BQB3U2VD.js';
4
4
  import './chunk-YRYMNBGQ.js';
5
5
  import { parseTrackerNumber, trackerNumberError } from './chunk-RCQXYLMO.js';
6
6
  import './chunk-ZJSNLVCE.js';
7
- import './chunk-A6NNKRJU.js';
7
+ import './chunk-3VQ4XXQA.js';
8
8
  import './chunk-IWIUYLDR.js';
9
- import './chunk-YMTXR7PJ.js';
10
- import './chunk-ECSYRPCC.js';
9
+ import './chunk-YOOSBOKS.js';
10
+ import './chunk-R5KBGVII.js';
11
11
  import { readCloudConfig } from './chunk-TFUIDMOB.js';
12
12
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
13
13
  import './chunk-Z5GEFMRW.js';
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { resolveRepoIdentity, emitLaunchRefusal } from './chunk-DEDV5V4U.js';
3
+ import { resolveRepoIdentity, emitLaunchRefusal } from './chunk-BQB3U2VD.js';
4
4
  import './chunk-YRYMNBGQ.js';
5
5
  import { parseTrackerNumber, trackerNumberError } from './chunk-RCQXYLMO.js';
6
6
  import './chunk-ZJSNLVCE.js';
7
- import './chunk-A6NNKRJU.js';
7
+ import './chunk-3VQ4XXQA.js';
8
8
  import './chunk-IWIUYLDR.js';
9
- import './chunk-YMTXR7PJ.js';
10
- import './chunk-ECSYRPCC.js';
9
+ import './chunk-YOOSBOKS.js';
10
+ import './chunk-R5KBGVII.js';
11
11
  import { readCloudConfig } from './chunk-TFUIDMOB.js';
12
12
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
13
13
  import './chunk-Z5GEFMRW.js';
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { FindingBatchSchema, resolveRepoIdentity, detectActiveSession, launchRefusalForSession } from './chunk-DEDV5V4U.js';
3
+ import { FindingBatchSchema, resolveRepoIdentity, detectActiveSession, launchRefusalForSession } from './chunk-BQB3U2VD.js';
4
4
  import './chunk-YRYMNBGQ.js';
5
5
  import { launchedItemForSession, parseTrackerNumber, trackerNumberError } from './chunk-RCQXYLMO.js';
6
6
  import { readLatestProvenanceForSession } from './chunk-ZJSNLVCE.js';
7
- import './chunk-A6NNKRJU.js';
7
+ import './chunk-3VQ4XXQA.js';
8
8
  import './chunk-IWIUYLDR.js';
9
- import './chunk-YMTXR7PJ.js';
10
- import './chunk-ECSYRPCC.js';
9
+ import './chunk-YOOSBOKS.js';
10
+ import './chunk-R5KBGVII.js';
11
11
  import { readCloudConfig } from './chunk-TFUIDMOB.js';
12
12
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
13
13
  import './chunk-Z5GEFMRW.js';
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { EmittedNameSchema, ARTIFACT_REVIEW_CHECK_NAME, EMITTED_RESULT_MAX_LINK_LENGTH, EMITTED_RESULTS, EMITTED_RESULT_MAX_BODY_LENGTH, resolveRepoIdentity, detectActiveSession, launchRefusalForSession, detectCi } from './chunk-DEDV5V4U.js';
3
+ import { EmittedNameSchema, ARTIFACT_REVIEW_CHECK_NAME, EMITTED_RESULT_MAX_LINK_LENGTH, EMITTED_RESULTS, EMITTED_RESULT_MAX_BODY_LENGTH, resolveRepoIdentity, detectActiveSession, launchRefusalForSession, detectCi } from './chunk-BQB3U2VD.js';
4
4
  import './chunk-YRYMNBGQ.js';
5
5
  import { parseTrackerNumber, trackerNumberError } from './chunk-RCQXYLMO.js';
6
6
  import './chunk-ZJSNLVCE.js';
7
- import './chunk-A6NNKRJU.js';
7
+ import './chunk-3VQ4XXQA.js';
8
8
  import './chunk-IWIUYLDR.js';
9
- import './chunk-YMTXR7PJ.js';
10
- import './chunk-ECSYRPCC.js';
9
+ import './chunk-YOOSBOKS.js';
10
+ import './chunk-R5KBGVII.js';
11
11
  import { readCloudConfig } from './chunk-TFUIDMOB.js';
12
12
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
13
13
  import './chunk-Z5GEFMRW.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { AUTO_SYNC_DEBOUNCE_MS, WORK_ADD_RETRIES, contextPossiblyGoverned, handleWorkLaunch, hookFiredMarkerPath, maybeAutoSync, runHookFast, spoolDir } from './chunk-A6NNKRJU.js';
3
+ export { AUTO_SYNC_DEBOUNCE_MS, WORK_ADD_RETRIES, contextPossiblyGoverned, handleWorkLaunch, hookFiredMarkerPath, maybeAutoSync, runHookFast, spoolDir } from './chunk-3VQ4XXQA.js';
4
4
  import './chunk-IWIUYLDR.js';
5
5
  import './chunk-VNVZDWO3.js';
6
6
  import './chunk-Z5GEFMRW.js';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { hookExecSpoolPath, hookWrapStdio, installAbortForwarding, makeTailCollector, parseHookWrapArgs, runHookWrapFast, spoolDir } from './chunk-YMTXR7PJ.js';
4
- import './chunk-ECSYRPCC.js';
3
+ export { hookExecSpoolPath, hookWrapStdio, installAbortForwarding, makeTailCollector, parseHookWrapArgs, runHookWrapFast, spoolDir } from './chunk-YOOSBOKS.js';
4
+ import './chunk-R5KBGVII.js';
5
5
  import './chunk-VNVZDWO3.js';
6
6
  import './chunk-Z5GEFMRW.js';
7
7
 
package/dist/index.js CHANGED
@@ -6,20 +6,20 @@ createRequire(import.meta.url);
6
6
  // src/index.ts
7
7
  var argv = process.argv.slice(2);
8
8
  if (argv[0] === "hook") {
9
- const { runHookFast } = await import('./hook-fast-CBW4ZETX.js');
9
+ const { runHookFast } = await import('./hook-fast-I2XTHDE6.js');
10
10
  await runHookFast(argv[1]);
11
11
  process.exit(0);
12
12
  }
13
13
  if (argv[0] === "hook-wrap") {
14
- const { runHookWrapFast, parseHookWrapArgs } = await import('./hook-wrap-fast-36WGE6EX.js');
14
+ const { runHookWrapFast, parseHookWrapArgs } = await import('./hook-wrap-fast-KXYNX3AD.js');
15
15
  const { id, captureOutput } = parseHookWrapArgs(argv.slice(1));
16
16
  const code = await runHookWrapFast(id, { captureOutput });
17
17
  process.exit(code);
18
18
  }
19
19
  if (argv[0] === "statusline") {
20
- const { runStatuslineFast } = await import('./statusline-fast-Z5U5CEC6.js');
20
+ const { runStatuslineFast } = await import('./statusline-fast-3C5OXHDD.js');
21
21
  await runStatuslineFast(argv.slice(1));
22
22
  process.exit(0);
23
23
  }
24
- var { runCli } = await import('./cli-3JYGL2OB.js');
24
+ var { runCli } = await import('./cli-EFJIG2VT.js');
25
25
  await runCli(process.argv);
@@ -2,18 +2,18 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { loadRunnerConfig, checkHooks } from './chunk-WQ6VGRGZ.js';
4
4
  import { claimPidFile, readPidFile, releasePidFile } from './chunk-D77LS3UI.js';
5
- import { describeCallFailure, retrySend, LEASE_SECONDS, shortClaim, isUnfinished, writeJobFile, relativeToRunner, setStage, jobEnv, runHook, formatDuration, describeHookEnd, readProvisionOut, workdirProblem, runCommand, finishJob, isGroupAlive, outcomeFromExitCode, needsRenew, renewLease, formatClock, RENEW_INTERVAL_SECONDS, isTimedOut, readCpuUsec, isIdle, createRunnerLog, listAdoptableJobs, retryFailedReleases, recoverLostJobs, readJobFile, hookLimitsFor } from './chunk-4H56Y7O6.js';
5
+ import { describeCallFailure, retrySend, LEASE_SECONDS, shortClaim, isUnfinished, writeJobFile, relativeToRunner, setStage, jobEnv, runHook, formatDuration, describeHookEnd, readProvisionOut, workdirProblem, runCommand, finishJob, isGroupAlive, outcomeFromExitCode, needsRenew, renewLease, formatClock, RENEW_INTERVAL_SECONDS, isTimedOut, readCpuUsec, isIdle, createRunnerLog, listAdoptableJobs, retryFailedReleases, recoverLostJobs, readJobFile, hookLimitsFor } from './chunk-KKEU6FFR.js';
6
6
  import { startTimeOf, isSameProcess } from './chunk-OZ7C3XUE.js';
7
7
  import { RUNNER_DIR_MODE, runnerDir, attemptStamp, jobDir, jobsDir, pidFilePath } from './chunk-JJP7YLMN.js';
8
- import { WorkCommandError, getJson } from './chunk-VU34RWDU.js';
9
- import { RepoFilter } from './chunk-DEDV5V4U.js';
8
+ import { WorkCommandError, getJson } from './chunk-HNCCD2IX.js';
9
+ import { RepoFilter } from './chunk-BQB3U2VD.js';
10
10
  import './chunk-YRYMNBGQ.js';
11
11
  import './chunk-RCQXYLMO.js';
12
12
  import './chunk-ZJSNLVCE.js';
13
- import './chunk-A6NNKRJU.js';
13
+ import './chunk-3VQ4XXQA.js';
14
14
  import './chunk-IWIUYLDR.js';
15
- import './chunk-YMTXR7PJ.js';
16
- import './chunk-ECSYRPCC.js';
15
+ import './chunk-YOOSBOKS.js';
16
+ import './chunk-R5KBGVII.js';
17
17
  import './chunk-TFUIDMOB.js';
18
18
  import './chunk-VNVZDWO3.js';
19
19
  import './chunk-Z5GEFMRW.js';
@@ -151,7 +151,7 @@ async function runTick(state) {
151
151
  );
152
152
  }
153
153
  async function tryClaimAndStart(state, item, queue) {
154
- const { postJson } = await import('./work-cmd-CW26EZZO.js');
154
+ const { postJson } = await import('./work-cmd-ABP6XDBP.js');
155
155
  const log = logOf(state);
156
156
  const claim = await retrySend(
157
157
  () => postJson(
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { formatDuration, formatClock, relativeToRunner, LEASE_SECONDS, RENEW_INTERVAL_SECONDS } from './chunk-4H56Y7O6.js';
3
+ import { formatDuration, formatClock, relativeToRunner, LEASE_SECONDS, RENEW_INTERVAL_SECONDS } from './chunk-KKEU6FFR.js';
4
4
  import './chunk-OZ7C3XUE.js';
5
5
  import { runnerDir, jobsDir } from './chunk-JJP7YLMN.js';
6
- import './chunk-VU34RWDU.js';
7
- import './chunk-DEDV5V4U.js';
6
+ import './chunk-HNCCD2IX.js';
7
+ import './chunk-BQB3U2VD.js';
8
8
  import './chunk-YRYMNBGQ.js';
9
9
  import './chunk-RCQXYLMO.js';
10
10
  import './chunk-ZJSNLVCE.js';
11
- import './chunk-A6NNKRJU.js';
11
+ import './chunk-3VQ4XXQA.js';
12
12
  import './chunk-IWIUYLDR.js';
13
- import './chunk-YMTXR7PJ.js';
14
- import './chunk-ECSYRPCC.js';
13
+ import './chunk-YOOSBOKS.js';
14
+ import './chunk-R5KBGVII.js';
15
15
  import './chunk-TFUIDMOB.js';
16
16
  import './chunk-VNVZDWO3.js';
17
17
  import './chunk-Z5GEFMRW.js';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { STATE_FRESH_MS, WRAP_TIMEOUT_MS, localDateString, parseStatuslineArgs, parseStatuslineStdin, readStatuslineState, renderStatusline, runStatuslineFast, runWrappedStatusline, statuslineStatePath } from './chunk-XN2XZFTK.js';
4
- import './chunk-ECSYRPCC.js';
3
+ export { STATE_FRESH_MS, WRAP_TIMEOUT_MS, localDateString, parseStatuslineArgs, parseStatuslineStdin, readStatuslineState, renderStatusline, runStatuslineFast, runWrappedStatusline, statuslineStatePath } from './chunk-NTTPJV35.js';
4
+ import './chunk-R5KBGVII.js';
5
5
  import './chunk-VNVZDWO3.js';
6
6
  import './chunk-Z5GEFMRW.js';
7
7
 
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { CHUNK_PART_TARGET_BYTES, RETRYABLE_STATUSES, SyncConfigError, SyncTransportError, detectCi, isLoopbackUrl, resolveTier, runSync } from './chunk-DEDV5V4U.js';
3
+ export { CHUNK_PART_TARGET_BYTES, RETRYABLE_STATUSES, SyncConfigError, SyncTransportError, detectCi, isLoopbackUrl, resolveTier, runSync } from './chunk-BQB3U2VD.js';
4
4
  import './chunk-YRYMNBGQ.js';
5
5
  import './chunk-RCQXYLMO.js';
6
6
  import './chunk-ZJSNLVCE.js';
7
- import './chunk-A6NNKRJU.js';
7
+ import './chunk-3VQ4XXQA.js';
8
8
  import './chunk-IWIUYLDR.js';
9
- import './chunk-YMTXR7PJ.js';
10
- import './chunk-ECSYRPCC.js';
9
+ import './chunk-YOOSBOKS.js';
10
+ import './chunk-R5KBGVII.js';
11
11
  export { cloudConfigPath, readCloudConfig, writeCloudConfig } from './chunk-TFUIDMOB.js';
12
12
  import './chunk-VNVZDWO3.js';
13
13
  import './chunk-Z5GEFMRW.js';
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { StatuslineAggregator, CaptureDaemon, LiveUploader } from './chunk-DEDV5V4U.js';
3
+ import { StatuslineAggregator, CaptureDaemon, LiveUploader } from './chunk-BQB3U2VD.js';
4
4
  import './chunk-YRYMNBGQ.js';
5
5
  import './chunk-RCQXYLMO.js';
6
6
  import './chunk-ZJSNLVCE.js';
7
- import './chunk-A6NNKRJU.js';
7
+ import './chunk-3VQ4XXQA.js';
8
8
  import './chunk-IWIUYLDR.js';
9
- import './chunk-YMTXR7PJ.js';
10
- import './chunk-ECSYRPCC.js';
9
+ import './chunk-YOOSBOKS.js';
10
+ import './chunk-R5KBGVII.js';
11
11
  import './chunk-TFUIDMOB.js';
12
12
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
13
13
  import './chunk-Z5GEFMRW.js';
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { resolveCredentials, WorkCommandError, parsePositiveInt, postJson, resolveRepository, findLiveItem } from './chunk-VU34RWDU.js';
4
- export { WorkCommandError } from './chunk-VU34RWDU.js';
5
- import './chunk-DEDV5V4U.js';
3
+ import { resolveCredentials, WorkCommandError, parsePositiveInt, postJson, resolveRepository, findLiveItem } from './chunk-HNCCD2IX.js';
4
+ export { WorkCommandError } from './chunk-HNCCD2IX.js';
5
+ import './chunk-BQB3U2VD.js';
6
6
  import './chunk-YRYMNBGQ.js';
7
7
  import './chunk-RCQXYLMO.js';
8
8
  import './chunk-ZJSNLVCE.js';
9
- import './chunk-A6NNKRJU.js';
9
+ import './chunk-3VQ4XXQA.js';
10
10
  import './chunk-IWIUYLDR.js';
11
- import './chunk-YMTXR7PJ.js';
12
- import './chunk-ECSYRPCC.js';
11
+ import './chunk-YOOSBOKS.js';
12
+ import './chunk-R5KBGVII.js';
13
13
  import './chunk-TFUIDMOB.js';
14
14
  import './chunk-VNVZDWO3.js';
15
15
  import './chunk-Z5GEFMRW.js';
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { WorkCommandError, findLiveItem, getJson, parsePositiveInt, postJson, resolveCredentials, resolveRepository, runWorkAdd, runWorkLinkSession, runWorkList, runWorkRemove, runWorkStatus } from './chunk-VU34RWDU.js';
4
- import './chunk-DEDV5V4U.js';
3
+ export { WorkCommandError, findLiveItem, getJson, parsePositiveInt, postJson, resolveCredentials, resolveRepository, runWorkAdd, runWorkLinkSession, runWorkList, runWorkRemove, runWorkStatus } from './chunk-HNCCD2IX.js';
4
+ import './chunk-BQB3U2VD.js';
5
5
  import './chunk-YRYMNBGQ.js';
6
6
  import './chunk-RCQXYLMO.js';
7
7
  import './chunk-ZJSNLVCE.js';
8
- import './chunk-A6NNKRJU.js';
8
+ import './chunk-3VQ4XXQA.js';
9
9
  import './chunk-IWIUYLDR.js';
10
- import './chunk-YMTXR7PJ.js';
11
- import './chunk-ECSYRPCC.js';
10
+ import './chunk-YOOSBOKS.js';
11
+ import './chunk-R5KBGVII.js';
12
12
  import './chunk-TFUIDMOB.js';
13
13
  import './chunk-VNVZDWO3.js';
14
14
  import './chunk-Z5GEFMRW.js';
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { resolveRepoIdentity, detectActiveSession } from './chunk-DEDV5V4U.js';
3
+ import { resolveRepoIdentity, detectActiveSession } from './chunk-BQB3U2VD.js';
4
4
  import './chunk-YRYMNBGQ.js';
5
5
  import { parseTrackerNumber, trackerNumberError } from './chunk-RCQXYLMO.js';
6
6
  import './chunk-ZJSNLVCE.js';
7
- import './chunk-A6NNKRJU.js';
7
+ import './chunk-3VQ4XXQA.js';
8
8
  import './chunk-IWIUYLDR.js';
9
- import './chunk-YMTXR7PJ.js';
10
- import './chunk-ECSYRPCC.js';
9
+ import './chunk-YOOSBOKS.js';
10
+ import './chunk-R5KBGVII.js';
11
11
  import { readCloudConfig } from './chunk-TFUIDMOB.js';
12
12
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
13
13
  import './chunk-Z5GEFMRW.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outerlayer/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "OuterLayer CLI: init/doctor (hooks + daemon onboarding), watch, scan, and eval (validate/mine/qualify/report — execution-verified evals from your own PRs)",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Magu Studios, Inc.",