@indigoai-us/hq-cli 5.345.174 → 5.345.176

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 (62) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/command-catalog.generated.d.ts +65 -0
  3. package/dist/command-catalog.generated.js +80 -0
  4. package/dist/commands/bot.d.ts +28 -2
  5. package/dist/commands/bot.js +32 -6
  6. package/dist/commands/daemon.js +16 -0
  7. package/dist/commands/dm.d.ts +7 -0
  8. package/dist/commands/dm.js +16 -4
  9. package/dist/commands/lanes-loop.d.ts +4 -1
  10. package/dist/commands/lanes-loop.js +23 -4
  11. package/dist/commands/lanes-shared.d.ts +5 -0
  12. package/dist/commands/lanes.d.ts +5 -7
  13. package/dist/commands/lanes.js +65 -5
  14. package/dist/commands/sync-core.d.ts +17 -0
  15. package/dist/commands/sync-core.js +46 -5
  16. package/dist/commands/sync-manifest.d.ts +6 -0
  17. package/dist/commands/sync-manifest.js +13 -0
  18. package/dist/hq-cloud-sync-runner/bin/sync-runner.js +448 -226
  19. package/dist/hq-cloud-sync-runner/package.json +1 -1
  20. package/dist/lib/bot/cli-update.d.ts +36 -0
  21. package/dist/lib/bot/cli-update.js +160 -42
  22. package/dist/lib/bot/run.d.ts +23 -0
  23. package/dist/lib/bot/run.js +174 -23
  24. package/dist/lib/bot/runtime/claude.d.ts +7 -1
  25. package/dist/lib/bot/runtime/claude.js +29 -0
  26. package/dist/lib/bot/runtime/codex.d.ts +5 -0
  27. package/dist/lib/bot/runtime/codex.js +13 -0
  28. package/dist/lib/bot/runtime/index.js +18 -2
  29. package/dist/lib/bot/runtime/types.d.ts +23 -0
  30. package/dist/lib/bot/runtime/types.js +13 -0
  31. package/dist/lib/bot/runtime-failure.d.ts +17 -6
  32. package/dist/lib/bot/runtime-failure.js +54 -9
  33. package/dist/lib/bot/runtime-sign-in-check.d.ts +32 -0
  34. package/dist/lib/bot/runtime-sign-in-check.js +53 -0
  35. package/dist/lib/bot/runtime-sign-in.d.ts +32 -3
  36. package/dist/lib/bot/runtime-sign-in.js +17 -2
  37. package/dist/lib/bot/status.d.ts +35 -1
  38. package/dist/lib/bot/status.js +28 -0
  39. package/dist/lib/daemon/catalog.d.ts +4 -0
  40. package/dist/lib/daemon/catalog.js +47 -19
  41. package/dist/lib/daemon/run.js +1 -0
  42. package/dist/lib/flag-registry-worker-source.generated.d.ts +1 -1
  43. package/dist/lib/flag-registry-worker-source.generated.js +1 -1
  44. package/dist/lib/lanes/loop-disposition.d.ts +44 -0
  45. package/dist/lib/lanes/loop-disposition.js +302 -0
  46. package/dist/lib/lanes/loop.d.ts +16 -3
  47. package/dist/lib/lanes/loop.js +167 -60
  48. package/dist/lib/lanes/reconcile.d.ts +5 -0
  49. package/dist/lib/lanes/reconcile.js +79 -4
  50. package/dist/lib/mesh/live/daemon/work-subscribe.d.ts +3 -0
  51. package/dist/lib/mesh/live/daemon/work-subscribe.js +41 -12
  52. package/dist/lib/sync-core/engine-home.d.ts +11 -4
  53. package/dist/lib/sync-core/engine-home.js +22 -21
  54. package/dist/lib/sync-core/manifest-scopes.d.ts +15 -0
  55. package/dist/lib/sync-core/manifest-scopes.js +26 -0
  56. package/dist/lib/sync-core/reconcile.d.ts +2 -2
  57. package/dist/lib/sync-core/reconcile.js +70 -46
  58. package/dist/lib/sync-core/release.d.ts +2 -2
  59. package/dist/lib/sync-core/release.js +31 -6
  60. package/dist/lib/sync-core/rollout-state.d.ts +6 -3
  61. package/dist/lib/sync-core/rollout-state.js +26 -22
  62. package/package.json +8 -8
@@ -1,3 +1,4 @@
1
+ import { readSessionCompanyLock } from "../lib/session-company-lock.js";
1
2
  /**
2
3
  * `hq lanes` — worker lane management and decision queue (spec §5–§7, §10–§11).
3
4
  *
@@ -50,7 +51,7 @@ import { LANE_FOCUS_GUARD_FLAG, LANE_FOCUS_DASHBOARD_FLAG, LANE_HIRE_GRANT_FINIS
50
51
  import { applyContinuitySettings, findWorkerContinuityLane, sameLaneHost, workerContinuityPrompt } from "../lib/lanes/worker-continuity.js";
51
52
  import { localHostIdsReferToSameMachine, observeLocalHostIdentity, resolveLocalHostIdentity } from "../lib/lanes/local-host-identity.js";
52
53
  import { commitIdleLoopStop, enqueueLoopEnvelope, interruptLoopQueue, interruptLoopQueueForStory, loopControllerIsAlive, loopLaneIsIdle, loopStatus, validateLoopEnvelope } from "../lib/lanes/loop.js";
53
- import { LOOP_CONTROLLER_RECOVERY_REASON, LOOP_STALL_RESTART_REASON, runLaneLoopController, startLaneLoopController } from "./lanes-loop.js";
54
+ import { LOOP_CONTROLLER_RECOVERY_REASON, LOOP_STALL_RESTART_REASON, runLaneLoopController, startLaneLoopController, startLaneLoopControllerWithAdmissionLockHeld } from "./lanes-loop.js";
54
55
  import { configuredCodexRolloutHomes, retainCodexRollouts } from "../lib/lanes/disk-guard.js";
55
56
  import { isControllerAliasOutpostId } from "../lib/lanes/admission-host.js";
56
57
  import { runLeadAutopilotPass } from "../lib/lanes/autopilot.js";
@@ -76,6 +77,7 @@ import { CompanySelectionError } from "../utils/company-selection-error.js";
76
77
  import { assertNoSecretText } from "../lib/lanes/text-scan.js";
77
78
  import { createLaneMesh, emitLaneDecisionEvents, emitLaneTerminalStateEvent, laneMeshEventIdentity, } from "../lib/lanes/mesh-events.js";
78
79
  import { sessionIdFromEnv } from "../lib/mesh/live/session-identity.js";
80
+ import { applyLoopDisposition, loopDispositionSnapshot } from "../lib/lanes/loop-disposition.js";
79
81
  import { listLaneReviews } from "../lib/lanes/reviews.js";
80
82
  import { effectiveAccountHome } from "../lib/lanes/account-home.js";
81
83
  import { remoteControlSelectionConfig, remoteControlSessionHome } from "../lib/lanes/remote-control-lane.js";
@@ -446,6 +448,7 @@ function resolveDeps(deps = {}) {
446
448
  killProcess: deps.killProcess,
447
449
  isAlive: deps.isAlive,
448
450
  readStarttime: deps.readStarttime,
451
+ controllerProcessIdentity: deps.controllerProcessIdentity,
449
452
  watcherLoopDeps: deps.watcherLoopDeps,
450
453
  stopSleepMs: deps.stopSleepMs,
451
454
  livenessDeps: deps.livenessDeps,
@@ -544,7 +547,7 @@ function startAdmittedLane(ctx, root, candidate) {
544
547
  queued_details: undefined,
545
548
  admission_reserved_at: undefined,
546
549
  }));
547
- startLaneLoopController(ctx, candidate.lane_id, true);
550
+ startLaneLoopControllerWithAdmissionLockHeld(ctx, candidate.lane_id, true);
548
551
  return admitted;
549
552
  }
550
553
  /**
@@ -4552,7 +4555,7 @@ async function runCreate(ctx, opts) {
4552
4555
  : { ...current });
4553
4556
  started = lane;
4554
4557
  if (admission.action === "start")
4555
- loopControllerPid = startLaneLoopController(ctx, lane.lane_id, true);
4558
+ loopControllerPid = await startLaneLoopController(ctx, lane.lane_id, true);
4556
4559
  }
4557
4560
  else if (admission.action === "start") {
4558
4561
  started = spawnLaneWorker(hqRoot, lane, {
@@ -9339,12 +9342,23 @@ async function runStop(ctx, laneId, reason, quiet = false) {
9339
9342
  throw new LanesError("already_terminal", `Loop lane ${lane.lane_id} is already ${lane.state}`, { lane_id: lane.lane_id, state: lane.state });
9340
9343
  }
9341
9344
  const controllerAlive = loopControllerIsAlive(runDirPath);
9345
+ // An explicitly disposed lane may already contain the requested stop.
9346
+ // Commit that idle stop before enqueue rejects a second stop or any
9347
+ // controller is restarted. This does not certify the abandoned effects.
9348
+ if (!controllerAlive && lane.terminal_details?.recovery_decision) {
9349
+ const finalized = await finalizeIdleLoopStop(ctx, lane);
9350
+ if (finalized) {
9351
+ if (!quiet)
9352
+ printJson({ ok: true, action: "stop", lane_id: lane.lane_id, terminal: true, lane: finalized, external_effects: "not-certified" });
9353
+ return;
9354
+ }
9355
+ }
9342
9356
  if (!controllerAlive && lane.state === "running") {
9343
9357
  await runInterrupt(ctx, lane.lane_id, "loop controller exited; recovering queued work before stop", { preserveLoopQueue: true, quiet: true, terminalReason: LOOP_CONTROLLER_RECOVERY_REASON });
9344
9358
  }
9345
9359
  const queued = enqueueLoopEnvelope({ runDir: runDirPath, laneId: lane.lane_id, envelope: { kind: "stop" }, now: ctx.now });
9346
9360
  if (!controllerAlive && lane.state !== "queued")
9347
- startLaneLoopController(ctx, lane.lane_id);
9361
+ await startLaneLoopController(ctx, lane.lane_id);
9348
9362
  const finalized = !controllerAlive ? await finalizeIdleLoopStop(ctx, readLane(hqRoot, lane.lane_id)) : undefined;
9349
9363
  const admitted = await admitQueuedFromCtx(ctx);
9350
9364
  if (!quiet)
@@ -10483,6 +10497,52 @@ export function registerLanesCommand(parent, deps = {}) {
10483
10497
  emitTerminal: (lane) => emitLaneTerminalStateSoft(ctx, lane),
10484
10498
  });
10485
10499
  }));
10500
+ lanes
10501
+ .command("recover-loop")
10502
+ .description("Preview or explicitly fail/abandon uncertain loop effects; never replay work")
10503
+ .argument("<lane-id>", "Loop lane id")
10504
+ .option("--disposition <action>", "fail or abandon; omit for a read-only preview")
10505
+ .option("--lane-version <number>", "Exact lane version from preview")
10506
+ .option("--fingerprint <sha256>", "Exact preview envelope/lease fingerprint")
10507
+ .option("--reason <text>", "Audited reason; does not certify external effects")
10508
+ .option("--attest-owner-investigated", "Attest unknown lease ownership was investigated and no live owner exists")
10509
+ .action(wrap(async (laneId, opts) => {
10510
+ const hqRoot = ctx.hqRoot();
10511
+ const authorize = (lane) => {
10512
+ if (!lane.loop_mode)
10513
+ throw new Error("Not a loop lane");
10514
+ const authorization = callerSeniorAuthorization(ctx, lane.senior);
10515
+ if (!authorization.authorized)
10516
+ throw new Error(`Only the lane's senior may recover it: ${authorization.reason}`);
10517
+ assertLaneRunsHereForAdmission(ctx, lane);
10518
+ const lock = readSessionCompanyLock({ ...ctx.env, HQ_ROOT: hqRoot });
10519
+ const company = (lane.company ?? lane.mesh_company)?.slug ?? "personal";
10520
+ const sessionId = sessionIdFromEnv(ctx.env);
10521
+ if ((sessionId && (!lock || lock.sessionId !== sessionId)) || (lock && !lock.companies.includes(company))) {
10522
+ throw new LanesError("lane_recovery_company_locked", "This session is not bound to the lane's company", { lane_id: lane.lane_id, company });
10523
+ }
10524
+ };
10525
+ const lane = readLane(hqRoot, laneId);
10526
+ authorize(lane);
10527
+ const enabled = await readLanesRegistryFlagFailOpen(LANE_CONDUCT_LOOP_FLAG, { company: lane.company ?? lane.mesh_company, defaultValue: true, env: ctx.env });
10528
+ if (!enabled)
10529
+ throw new Error("Loop lanes are disabled by the kill switch");
10530
+ if (!opts.disposition) {
10531
+ printJson({ ok: true, action: "recover-loop-preview", snapshot: loopDispositionSnapshot(hqRoot, lane), external_effects: "not-certified" });
10532
+ return;
10533
+ }
10534
+ if (opts.disposition !== "fail" && opts.disposition !== "abandon")
10535
+ throw new Error("Disposition must be fail or abandon");
10536
+ assertNoSecretText("recovery reason", opts.reason ?? "");
10537
+ const version = Number(opts.laneVersion);
10538
+ if (!opts.laneVersion || !Number.isSafeInteger(version) || version < 1)
10539
+ throw new Error("An exact preview version is required");
10540
+ const result = await applyLoopDisposition({ hqRoot, laneId, expectedVersion: version,
10541
+ fingerprint: opts.fingerprint ?? "", disposition: opts.disposition,
10542
+ reason: opts.reason ?? "", ownershipAttested: opts.attestOwnerInvestigated,
10543
+ authorize, now: ctx.now });
10544
+ printJson({ ok: true, action: "recover-loop", ...result });
10545
+ }));
10486
10546
  lanes
10487
10547
  .command("enqueue")
10488
10548
  .description("Validate and queue one phase envelope for a loop lane")
@@ -10526,7 +10586,7 @@ export function registerLanesCommand(parent, deps = {}) {
10526
10586
  await runInterrupt(ctx, lane.lane_id, "loop controller exited; recovering the queued phase", { preserveLoopQueue: true, quiet: true, terminalReason: LOOP_CONTROLLER_RECOVERY_REASON });
10527
10587
  }
10528
10588
  const shouldRestart = !controllerAlive && lane.state !== "queued";
10529
- const controllerPid = shouldRestart ? startLaneLoopController(ctx, lane.lane_id) : undefined;
10589
+ const controllerPid = shouldRestart ? await startLaneLoopController(ctx, lane.lane_id) : undefined;
10530
10590
  printJson({ ok: true, action: "enqueue", ...result, lane: lane.lane_id, ...(controllerPid ? { controller_pid: controllerPid } : {}) });
10531
10591
  }));
10532
10592
  lanes
@@ -1,5 +1,7 @@
1
1
  import type { Command } from "commander";
2
2
  import { type SyncCoreReconcileResult } from "../lib/sync-core/reconcile.js";
3
+ import { type EngineManifestScope } from "../lib/sync-core/manifest-scopes.js";
4
+ import type { RunSyncManifestOptions, RunSyncManifestOutcome, SyncManifestDeps } from "./sync-manifest.js";
3
5
  export interface SyncCoreReconcileCommandOptions {
4
6
  hqRoot?: string;
5
7
  companiesOnly?: boolean;
@@ -15,6 +17,21 @@ export interface SyncCoreCommandDeps {
15
17
  err: (line: string) => void;
16
18
  }
17
19
  export declare function runSyncCoreReconcile(opts: SyncCoreReconcileCommandOptions, d?: SyncCoreCommandDeps): Promise<SyncCoreReconcileResult>;
20
+ export interface SyncCoreManifestCommandOptions {
21
+ hqRoot?: string;
22
+ json?: boolean;
23
+ }
24
+ export interface SyncCoreManifestDeps extends SyncCoreCommandDeps {
25
+ runManifest?: (options: RunSyncManifestOptions, deps: SyncManifestDeps) => Promise<RunSyncManifestOutcome>;
26
+ manifestDeps?: () => SyncManifestDeps;
27
+ }
28
+ export interface SyncCoreManifestResult {
29
+ scope: EngineManifestScope;
30
+ status: string;
31
+ mode?: string;
32
+ errorKind?: string;
33
+ }
34
+ export declare function runSyncCoreManifest(opts: SyncCoreManifestCommandOptions, d?: SyncCoreManifestDeps): Promise<SyncCoreManifestResult[]>;
18
35
  export declare function runSyncCoreStatus(opts: {
19
36
  json?: boolean;
20
37
  }, d?: SyncCoreCommandDeps): void;
@@ -4,6 +4,7 @@ import * as path from "node:path";
4
4
  import { ensureSyncCoreBinary } from "../lib/sync-core/release.js";
5
5
  import { readCompanyRolloutFlag } from "../lib/sync-core/flag.js";
6
6
  import { reconcileSyncCore } from "../lib/sync-core/reconcile.js";
7
+ import { engineOwnedManifestScopes, manifestScopeArg } from "../lib/sync-core/manifest-scopes.js";
7
8
  import { readSyncCoreRolloutState, syncCoreRolloutStatePath } from "../lib/sync-core/rollout-state.js";
8
9
  import { readVaultSyncSwitches } from "../lib/vault-sync-switches.js";
9
10
  function defaultDeps() {
@@ -66,6 +67,45 @@ export async function runSyncCoreReconcile(opts, d = defaultDeps()) {
66
67
  d.out("no vault on this machine is switched to the new sync engine");
67
68
  return result;
68
69
  }
70
+ export async function runSyncCoreManifest(opts, d = defaultDeps()) {
71
+ const hqRoot = await resolveHqRoot(opts.hqRoot, d.env);
72
+ const scopes = engineOwnedManifestScopes(readVaultSyncSwitches(d.home), readSyncCoreRolloutState(d.home)?.vaults);
73
+ if (scopes.length === 0) {
74
+ if (opts.json)
75
+ d.out("[]");
76
+ else
77
+ d.out("no vault on this machine is owned by the new sync engine; the current sync uploads its own manifests");
78
+ return [];
79
+ }
80
+ const manifest = await import("./sync-manifest.js");
81
+ const runManifest = d.runManifest ?? manifest.runSyncManifest;
82
+ const manifestDeps = d.manifestDeps ?? manifest.createDefaultDeps;
83
+ const results = [];
84
+ for (const scope of scopes) {
85
+ const label = manifestScopeArg(scope);
86
+ try {
87
+ const outcome = await runManifest({ scopeArg: manifestScopeArg(scope), hqRoot, respectThrottle: true, json: true, engineOwned: true }, { ...manifestDeps(), log: () => { } });
88
+ const { status, mode, error } = outcome.result;
89
+ results.push({
90
+ scope,
91
+ status,
92
+ ...(mode ? { mode } : {}),
93
+ ...(error?.kind ? { errorKind: error.kind } : {}),
94
+ });
95
+ if (!opts.json)
96
+ d.out(`${label}: ${status}${mode ? ` (${mode})` : ""}${error?.kind ? ` ${error.kind}` : ""}`);
97
+ }
98
+ catch (err) {
99
+ results.push({ scope, status: "failed", errorKind: "command_error" });
100
+ d.err(`${label}: manifest pass failed: ${err instanceof Error ? err.message : String(err)}`);
101
+ }
102
+ }
103
+ if (opts.json)
104
+ d.out(JSON.stringify(results, null, 2));
105
+ if (results.some((r) => r.status === "failed"))
106
+ process.exitCode = 1;
107
+ return results;
108
+ }
69
109
  export function runSyncCoreStatus(opts, d = defaultDeps()) {
70
110
  const state = readSyncCoreRolloutState(d.home);
71
111
  if (opts.json) {
@@ -83,15 +123,16 @@ export function runSyncCoreStatus(opts, d = defaultDeps()) {
83
123
  for (const vault of state.vaults) {
84
124
  const legacyOff = vault.kind === "personal" ? switches.personalOff : switches.offCompanies.has(vault.slug ?? "");
85
125
  d.out(` ${vault.uid} ${vault.kind}${vault.slug ? ` ${vault.slug}` : ""} ${vault.phase === "full" ? "full" : "read-only"} legacy sync ${legacyOff ? "off" : "still on"} home ${vault.engineHome}`);
86
- if (vault.plan) {
87
- const p = vault.plan;
88
- d.out(` plan ${p.at}: ${p.remoteRows} server rows, ${p.localFiles} local files; would upload ${p.uploads}, download ${p.downloads}, delete ${p.deletes}, write ${p.conflicts} conflict or merge copies`);
126
+ if (vault.firstCycle) {
127
+ const c = vault.firstCycle;
128
+ d.out(` first full cycle ${c.at}: ${c.planned} planned, ${c.completed} completed, ${c.pending} pending, ${c.held} held, ${c.notApplied} not applied`);
129
+ d.out(` listed work${c.truncated ? ` (first ${c.listed} items only)` : ""}: ${c.uploads} uploads, ${c.downloads} downloads, ${c.deletes} deletes, ${c.conflicts} conflict or merge copies, ${c.deferred} deferred`);
89
130
  }
90
- if (vault.hold)
91
- d.out(` held read-only: ${vault.hold}`);
92
131
  }
93
132
  for (const skip of state.skipped ?? [])
94
133
  d.out(` ${skip.uid} skipped on this machine: ${skip.reason}`);
134
+ for (const hold of state.held ?? [])
135
+ d.out(` ${hold.uid} held: ${hold.reason}`);
95
136
  if (state.vaults.length === 0)
96
137
  d.out(" no vault is switched to the new sync engine");
97
138
  }
@@ -110,7 +110,13 @@ export interface RunSyncManifestOptions {
110
110
  * `resend_full_scheduled` too, and none of those uploaded anything.
111
111
  */
112
112
  json?: boolean;
113
+ engineOwned?: boolean;
113
114
  }
115
+ export declare const SYNC_CORE_OWNS_SCOPE_LEDGER_CLASS = "SyncCoreOwnsScope";
116
+ export declare class SyncCoreOwnsScope extends Error {
117
+ constructor();
118
+ }
119
+ export declare function engineOwnedLedger(): never;
114
120
  /** The machine-readable outcome `--json` prints. Fixed tokens only, no paths. */
115
121
  export interface ManifestOutcomeLine {
116
122
  status: string;
@@ -64,6 +64,16 @@ export const MANIFEST_UPLOAD_PATH = "/v1/sync-manifest/upload";
64
64
  export { MANIFEST_DISABLED_ENV, manifestUploadsDisabled };
65
65
  /** The literal `--scope` value that selects the personal (non-company) tree. */
66
66
  export const PERSONAL_SCOPE = "personal";
67
+ export const SYNC_CORE_OWNS_SCOPE_LEDGER_CLASS = "SyncCoreOwnsScope";
68
+ export class SyncCoreOwnsScope extends Error {
69
+ constructor() {
70
+ super("the new sync engine owns this scope; the legacy journal is not its ledger");
71
+ this.name = SYNC_CORE_OWNS_SCOPE_LEDGER_CLASS;
72
+ }
73
+ }
74
+ export function engineOwnedLedger() {
75
+ throw new SyncCoreOwnsScope();
76
+ }
67
77
  /** Build the `--json` line for one pass. The free-text error detail is left out. */
68
78
  export function manifestOutcomeLine(result) {
69
79
  return {
@@ -333,6 +343,7 @@ export async function runSyncManifest(options, deps) {
333
343
  dryRun: print,
334
344
  forceFull: options.full === true,
335
345
  ignoreThrottle: options.respectThrottle !== true,
346
+ ...(options.engineOwned === true ? { listJournalsImpl: engineOwnedLedger } : {}),
336
347
  });
337
348
  if (print) {
338
349
  deps.log(JSON.stringify(result.chunks ?? [], null, 2));
@@ -358,6 +369,7 @@ export function registerSyncManifestCommand(syncCmd) {
358
369
  .option("--print", "Build and print the chunks as JSON; upload nothing")
359
370
  .option("--json", "Print the pass outcome as one JSON line instead of a summary")
360
371
  .option("--respect-throttle", "Honour the 24h per-scope upload throttle instead of forcing a pass (for scheduled callers)")
372
+ .option("--engine-owned", "The new sync engine owns this scope here: build the manifest from disk alone and mark the legacy journal as not its ledger")
361
373
  .option("--hq-root <path>", `Local HQ tree root (default: ${DEFAULT_HQ_ROOT})`, DEFAULT_HQ_ROOT)
362
374
  .action(async (options) => {
363
375
  // Capability gate BEFORE anything else: on a published hq-cloud that
@@ -376,6 +388,7 @@ export function registerSyncManifestCommand(syncCmd) {
376
388
  print: options.print,
377
389
  respectThrottle: options.respectThrottle,
378
390
  json: options.json,
391
+ engineOwned: options.engineOwned,
379
392
  }, createDefaultDeps());
380
393
  if (outcome.exitCode !== 0)
381
394
  process.exit(outcome.exitCode);