@quantiya/codevibe-codex-plugin 2.0.117 → 2.0.119

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.
@@ -9363,20 +9363,102 @@ var import_node_crypto34, import_json_freeze14, init_class_b_verify = __esm({
9363
9363
  }
9364
9364
  });
9365
9365
 
9366
+ // src/substrate/process-group-run.ts
9367
+ function runInOwnProcessGroup(argv, opts) {
9368
+ return new Promise((resolve35, reject) => {
9369
+ let child = (0, import_node_child_process12.spawn)(SH, ["-c", GROUP_LEADER_SCRIPT, argv[0], ...argv.slice(1)], {
9370
+ stdio: ["pipe", "pipe", "pipe", "pipe", "pipe"],
9371
+ detached: !0,
9372
+ windowsHide: !0,
9373
+ env: opts.env
9374
+ }), status = child.stdio[3], release = child.stdio[4], stdoutChunks = [], stderrChunks = [];
9375
+ child.stdout?.on("data", (c) => stdoutChunks.push(c)), child.stderr?.on("data", (c) => stderrChunks.push(c));
9376
+ let reported = null, pending2 = "", releaseGroup = () => {
9377
+ try {
9378
+ release?.end();
9379
+ } catch {
9380
+ }
9381
+ };
9382
+ status?.on("data", (c) => {
9383
+ pending2 += c.toString();
9384
+ let at = pending2.indexOf(`
9385
+ `);
9386
+ if (at < 0) return;
9387
+ let code = Number(pending2.slice(0, at).trim());
9388
+ reported = Number.isInteger(code) ? code : null, releaseGroup();
9389
+ }), status?.on("error", () => {
9390
+ }), release?.on?.("error", () => {
9391
+ });
9392
+ let exited = !1, timedOut = !1, timer;
9393
+ if (opts.timeoutMs !== void 0 && (timer = setTimeout(() => {
9394
+ if (timedOut = !0, !exited && child.exitCode === null && child.signalCode === null && child.pid !== void 0)
9395
+ try {
9396
+ process.kill(-child.pid, "SIGKILL");
9397
+ } catch {
9398
+ }
9399
+ releaseGroup();
9400
+ }, opts.timeoutMs)), child.on("exit", () => {
9401
+ exited = !0;
9402
+ }), child.on("error", (err) => {
9403
+ timer && clearTimeout(timer), reject(err);
9404
+ }), child.on("close", () => {
9405
+ timer && clearTimeout(timer), resolve35({
9406
+ // No exit status for a timed-out run (as before) or when the leader was ended before it could report.
9407
+ exitCode: timedOut ? null : reported,
9408
+ stdout: Buffer.concat(stdoutChunks).toString("utf8"),
9409
+ stderr: Buffer.concat(stderrChunks).toString("utf8")
9410
+ });
9411
+ }), opts.input !== void 0 && child.stdin)
9412
+ child.stdin.on("error", () => {
9413
+ }), child.stdin.write(opts.input, "utf8", () => {
9414
+ try {
9415
+ child.stdin?.end();
9416
+ } catch {
9417
+ }
9418
+ });
9419
+ else if (child.stdin)
9420
+ try {
9421
+ child.stdin.end();
9422
+ } catch {
9423
+ }
9424
+ });
9425
+ }
9426
+ var import_node_child_process12, SH, GROUP_LEADER_SCRIPT, init_process_group_run = __esm({
9427
+ "src/substrate/process-group-run.ts"() {
9428
+ "use strict";
9429
+ import_node_child_process12 = require("node:child_process"), SH = "/bin/sh", GROUP_LEADER_SCRIPT = [
9430
+ "exec 5<&0",
9431
+ "( exec 3>&- 5<&- </dev/null; read -r _ <&4; kill -s KILL 0 ) &",
9432
+ '"$0" "$@" <&5 3>&- 4>&- 5<&- &',
9433
+ "c=$!",
9434
+ "exec 5<&- 4>&-",
9435
+ 'wait "$c"',
9436
+ "s=$?",
9437
+ "trap '' PIPE",
9438
+ `printf '%s\\n' "$s" >&3 2>/dev/null`,
9439
+ "exec 3>&-",
9440
+ "wait"
9441
+ ].join(`
9442
+ `);
9443
+ }
9444
+ });
9445
+
9366
9446
  // src/substrate/command-runner.ts
9367
- var import_node_child_process12, ChildProcessCommandRunner, init_command_runner = __esm({
9447
+ var import_node_child_process13, ChildProcessCommandRunner, init_command_runner = __esm({
9368
9448
  "src/substrate/command-runner.ts"() {
9369
9449
  "use strict";
9370
- import_node_child_process12 = require("node:child_process");
9450
+ import_node_child_process13 = require("node:child_process");
9371
9451
  init_env_scrub();
9372
9452
  init_process_tree();
9453
+ init_process_group_run();
9373
9454
  ChildProcessCommandRunner = class {
9374
9455
  run(argv, opts = {}) {
9375
- return new Promise((resolve35, reject) => {
9376
- let child = (0, import_node_child_process12.spawn)(argv[0], argv.slice(1), {
9456
+ let env = scrubSearchApiKeys({ ...process.env });
9457
+ return process.platform !== "win32" && opts.timeoutMs !== void 0 ? runInOwnProcessGroup(argv, { ...opts, env }) : new Promise((resolve35, reject) => {
9458
+ let child = (0, import_node_child_process13.spawn)(argv[0], argv.slice(1), {
9377
9459
  stdio: ["pipe", "pipe", "pipe"],
9378
9460
  windowsHide: !0,
9379
- env: scrubSearchApiKeys({ ...process.env })
9461
+ env
9380
9462
  }), stdoutChunks = [], stderrChunks = [];
9381
9463
  child.stdout?.on("data", (c) => stdoutChunks.push(c)), child.stderr?.on("data", (c) => stderrChunks.push(c));
9382
9464
  let timer;
@@ -9421,7 +9503,7 @@ var import_node_child_process12, ChildProcessCommandRunner, init_command_runner
9421
9503
  workingDirAuthority: opts.cwdAuthority,
9422
9504
  launchPathAuthorities: opts.launchPathAuthorities,
9423
9505
  ...opts.descendantReap ? { descendantReap: opts.descendantReap } : {}
9424
- }) : (0, import_node_child_process12.spawn)(argv[0], argv.slice(1), spawnOptions), proc = child;
9506
+ }) : (0, import_node_child_process13.spawn)(argv[0], argv.slice(1), spawnOptions), proc = child;
9425
9507
  if (opts.relayChannel) {
9426
9508
  let channel = child.stdio[3];
9427
9509
  if (!channel) throw new Error("spawnLong: the relay channel (fd 3) was not created");
@@ -9593,7 +9675,7 @@ async function executeSpawnSweep(opts) {
9593
9675
  strandedMembers: [],
9594
9676
  recordSha256
9595
9677
  };
9596
- let timeoutMs = opts.timeoutMs ?? 1e4, readProcStat = opts.readProcStat ?? defaultReadProcStat, spawner = opts.spawnHelper ?? import_node_child_process15.default.spawn, invocationToken = import_node_crypto45.default.randomBytes(8).toString("hex");
9678
+ let timeoutMs = opts.timeoutMs ?? 1e4, readProcStat = opts.readProcStat ?? defaultReadProcStat, spawner = opts.spawnHelper ?? import_node_child_process16.default.spawn, invocationToken = import_node_crypto45.default.randomBytes(8).toString("hex");
9597
9679
  return new Promise((resolve35) => {
9598
9680
  let settled = !1, timer = null, initialStat = null, child;
9599
9681
  try {
@@ -9804,10 +9886,10 @@ async function executeSpawnSweep(opts) {
9804
9886
  });
9805
9887
  });
9806
9888
  }
9807
- var import_node_child_process15, import_node_crypto45, import_node_fs36, import_node_path4, activeSpawnSweeps, init_spawn_sweep = __esm({
9889
+ var import_node_child_process16, import_node_crypto45, import_node_fs36, import_node_path4, activeSpawnSweeps, init_spawn_sweep = __esm({
9808
9890
  "src/local-executor/spawn-sweep.ts"() {
9809
9891
  "use strict";
9810
- import_node_child_process15 = __toESM(require("node:child_process")), import_node_crypto45 = __toESM(require("node:crypto")), import_node_fs36 = __toESM(require("node:fs")), import_node_path4 = __toESM(require("node:path"));
9892
+ import_node_child_process16 = __toESM(require("node:child_process")), import_node_crypto45 = __toESM(require("node:crypto")), import_node_fs36 = __toESM(require("node:fs")), import_node_path4 = __toESM(require("node:path"));
9811
9893
  init_logger2();
9812
9894
  init_spawn_sweep_binary();
9813
9895
  activeSpawnSweeps = /* @__PURE__ */ new Map();
@@ -10153,14 +10235,14 @@ async function collectRepoStates(authority, knownRepos, options = {}) {
10153
10235
  );
10154
10236
  return Promise.all(clamped.map((r) => collectOne(r, gitExec, timeoutMs)));
10155
10237
  }
10156
- var import_node_child_process17, path95, GIT_TIMEOUT_MS, SCRUBBED_ENV, defaultGitExec, init_dirty_state_collector = __esm({
10238
+ var import_node_child_process18, path95, GIT_TIMEOUT_MS, SCRUBBED_ENV, defaultGitExec, init_dirty_state_collector = __esm({
10157
10239
  "src/continuation/dirty-state-collector.ts"() {
10158
10240
  "use strict";
10159
- import_node_child_process17 = require("node:child_process"), path95 = __toESM(require("node:path")), GIT_TIMEOUT_MS = 5e3, SCRUBBED_ENV = (() => {
10241
+ import_node_child_process18 = require("node:child_process"), path95 = __toESM(require("node:path")), GIT_TIMEOUT_MS = 5e3, SCRUBBED_ENV = (() => {
10160
10242
  let out = {};
10161
10243
  return process.env.PATH && (out.PATH = process.env.PATH), process.env.LANG && (out.LANG = process.env.LANG), process.env.LC_ALL && (out.LC_ALL = process.env.LC_ALL), out;
10162
10244
  })(), defaultGitExec = (args, options) => new Promise((resolve35, reject) => {
10163
- (0, import_node_child_process17.execFile)(
10245
+ (0, import_node_child_process18.execFile)(
10164
10246
  "git",
10165
10247
  args,
10166
10248
  {
@@ -18765,6 +18847,15 @@ var queries = {
18765
18847
  }
18766
18848
  `
18767
18849
  ),
18850
+ // Sign-out: drop this computer's public key so new sessions stop wrapping a key for it (iOS does the same).
18851
+ removeDeviceKey: (
18852
+ /* GraphQL */
18853
+ `
18854
+ mutation RemoveDeviceKey($deviceId: ID!) {
18855
+ removeDeviceKey(deviceId: $deviceId)
18856
+ }
18857
+ `
18858
+ ),
18768
18859
  grantSessionKey: (
18769
18860
  /* GraphQL */
18770
18861
  `
@@ -26983,8 +27074,8 @@ var AppSyncClient = class _AppSyncClient {
26983
27074
  /**
26984
27075
  * List user device keys
26985
27076
  */
26986
- async listUserDeviceKeys() {
26987
- return (await this.graphqlRequest(queries.listUserDeviceKeys, {})).data.listUserDeviceKeys || [];
27077
+ async listUserDeviceKeys(options = {}) {
27078
+ return (await this.graphqlRequest(queries.listUserDeviceKeys, {}, !1, void 0, options.expectedUserId)).data.listUserDeviceKeys || [];
26988
27079
  }
26989
27080
  /**
26990
27081
  * CP-1.b IMPL r4 H-2 — list BACKEND_SERVICE device keys per design
@@ -27015,6 +27106,10 @@ var AppSyncClient = class _AppSyncClient {
27015
27106
  let input = { deviceId, publicKey, platform: platform2, deviceName };
27016
27107
  await this.graphqlRequest(mutations.registerDeviceKey, { input }), logger.info("[AppSyncClient] Device key registered", { deviceId, platform: platform2 });
27017
27108
  }
27109
+ /** Sign-out de-registration transport, fenced to `expectedUserId` on every replay (logic: `auth/device-deregistration.ts`). */
27110
+ async removeDeviceKey(deviceId, expectedUserId) {
27111
+ return (await this.graphqlRequest(mutations.removeDeviceKey, { deviceId }, !1, void 0, expectedUserId))?.data?.removeDeviceKey === !0;
27112
+ }
27018
27113
  /**
27019
27114
  * Grant a session key to an additional device by appending a new
27020
27115
  * per-device wrapped key blob to the session's encryptedKeys array.
@@ -32681,7 +32776,7 @@ async function clearRetiredPlannerCache(userId, cacheRoot = process.env.CODEVIBE
32681
32776
  }
32682
32777
 
32683
32778
  // src/orchestration-shell/index.ts
32684
- var path113 = __toESM(require("path")), os55 = __toESM(require("os")), import_promises6 = require("node:fs/promises"), fs93 = __toESM(require("node:fs")), import_node_fs54 = require("node:fs"), import_node_child_process19 = require("node:child_process"), import_node_util3 = require("node:util"), import_node_async_hooks = require("node:async_hooks");
32779
+ var path113 = __toESM(require("path")), os55 = __toESM(require("os")), import_promises6 = require("node:fs/promises"), fs93 = __toESM(require("node:fs")), import_node_fs54 = require("node:fs"), import_node_child_process20 = require("node:child_process"), import_node_util3 = require("node:util"), import_node_async_hooks = require("node:async_hooks");
32685
32780
 
32686
32781
  // src/orchestration-shell/web/sanitize.ts
32687
32782
  function sanitizeForTerminal(input) {
@@ -40581,6 +40676,11 @@ function filterSlashSuggestions(value, commands) {
40581
40676
  let q = value.toLowerCase();
40582
40677
  return commands.filter((c) => c.name.toLowerCase().startsWith(q));
40583
40678
  }
40679
+ function enterRunsTypedCommand(value, suggestions, highlight) {
40680
+ if (suggestions.length === 0 || !value.startsWith("/")) return !1;
40681
+ let pick2 = suggestions[Math.min(Math.max(highlight, 0), suggestions.length - 1)];
40682
+ return pick2 !== void 0 && pick2.name === value;
40683
+ }
40584
40684
  function formatSuggestionRow(opts) {
40585
40685
  let base2 = `${opts.highlighted ? "\u276F " : " "}${opts.name.padEnd(opts.namePad)}`, blurbBudget = opts.maxCols - base2.length - 1, full = blurbBudget > 0 ? `${base2} ${truncate(opts.blurb, blurbBudget)}` : base2;
40586
40686
  return truncate(full, Math.max(0, opts.maxCols));
@@ -40957,6 +41057,10 @@ function InputBar(props) {
40957
41057
  setHl((Math.min(highlightRef.current, n - 1) + 1) % n);
40958
41058
  return;
40959
41059
  }
41060
+ if (key.return && enterRunsTypedCommand(valueRef.current, live, highlightRef.current)) {
41061
+ setHl(0), doSubmit();
41062
+ return;
41063
+ }
40960
41064
  if (key.tab || key.return) {
40961
41065
  completeToHighlighted();
40962
41066
  return;
@@ -47487,7 +47591,9 @@ var DockerHandle = class {
47487
47591
  try {
47488
47592
  runRes = await this.runner.run(runArgv);
47489
47593
  } catch (e) {
47490
- throw await this.rollback(sessionDir, forwarder, workdirLease), new SubstrateLaunchError(
47594
+ throw await this.runner.run(buildKillArgv(id5)).catch(() => {
47595
+ }), await this.runner.run(buildRmArgv(id5)).catch(() => {
47596
+ }), await this.rollback(sessionDir, forwarder, workdirLease), new SubstrateLaunchError(
47491
47597
  "docker",
47492
47598
  `container run failed to spawn: ${e.message}`,
47493
47599
  e
@@ -49166,7 +49272,7 @@ var path58 = __toESM(require("node:path"));
49166
49272
  init_anchored_fs();
49167
49273
 
49168
49274
  // src/local-executor/verification-gates/shell-runner.ts
49169
- var import_node_child_process13 = require("node:child_process");
49275
+ var import_node_child_process14 = require("node:child_process");
49170
49276
  init_bounded_output();
49171
49277
  init_process_tree();
49172
49278
  init_workspace_authority();
@@ -49176,7 +49282,7 @@ async function runShellCommand(args) {
49176
49282
  let now = args.nowMs ?? Date.now, startedAt = now();
49177
49283
  if (args.signal?.aborted)
49178
49284
  return { exitCode: -1, stdout: "", stderr: "verification gate aborted", durationMs: 0 };
49179
- let spawner = args.spawnFn ?? import_node_child_process13.spawn, workingDirAuthority = args.workingDirAuthority;
49285
+ let spawner = args.spawnFn ?? import_node_child_process14.spawn, workingDirAuthority = args.workingDirAuthority;
49180
49286
  if (workingDirAuthority) {
49181
49287
  if (assertWorkspaceRootAuthoritySchema(workingDirAuthority), workingDirAuthority.canonicalPath !== args.cwd)
49182
49288
  throw new Error("verification cwd authority is bound to a different path");
@@ -50762,7 +50868,7 @@ async function listBaselineShards(stateDir, shadowDir) {
50762
50868
  }
50763
50869
 
50764
50870
  // src/local-executor/shadow-volume-probe.ts
50765
- var import_node_child_process14 = require("node:child_process"), import_node_crypto39 = require("node:crypto"), import_node_fs32 = require("node:fs"), fs55 = __toESM(require("node:fs/promises")), path63 = __toESM(require("node:path")), PROBE_ENTRY_RE = /^\.codevibe-probe-[0-9a-f]{32}(?:\.(?:renamed|link))?$/;
50871
+ var import_node_child_process15 = require("node:child_process"), import_node_crypto39 = require("node:crypto"), import_node_fs32 = require("node:fs"), fs55 = __toESM(require("node:fs/promises")), path63 = __toESM(require("node:path")), PROBE_ENTRY_RE = /^\.codevibe-probe-[0-9a-f]{32}(?:\.(?:renamed|link))?$/;
50766
50872
  function newProbeEntryName() {
50767
50873
  return `.codevibe-probe-${(0, import_node_crypto39.randomBytes)(16).toString("hex")}`;
50768
50874
  }
@@ -50770,7 +50876,7 @@ async function bootIdentity(platform2 = process.platform) {
50770
50876
  if (platform2 === "linux") return (await fs55.readFile("/proc/sys/kernel/random/boot_id", "utf8")).trim();
50771
50877
  if (platform2 === "darwin")
50772
50878
  return new Promise((resolve35, reject) => {
50773
- (0, import_node_child_process14.execFile)("/usr/sbin/sysctl", ["-n", "kern.boottime"], (err, stdout) => {
50879
+ (0, import_node_child_process15.execFile)("/usr/sbin/sysctl", ["-n", "kern.boottime"], (err, stdout) => {
50774
50880
  err ? reject(err) : resolve35(stdout.trim());
50775
50881
  });
50776
50882
  });
@@ -62690,7 +62796,7 @@ var crypto26 = __toESM(require("node:crypto")), fs72 = __toESM(require("node:fs/
62690
62796
  init_logger2();
62691
62797
 
62692
62798
  // src/local-executor/worktree-merge.ts
62693
- var import_node_child_process16 = require("node:child_process"), crypto25 = __toESM(require("node:crypto")), fs71 = __toESM(require("node:fs/promises")), os39 = __toESM(require("node:os")), path85 = __toESM(require("node:path")), import_node_util = require("node:util");
62799
+ var import_node_child_process17 = require("node:child_process"), crypto25 = __toESM(require("node:crypto")), fs71 = __toESM(require("node:fs/promises")), os39 = __toESM(require("node:os")), path85 = __toESM(require("node:path")), import_node_util = require("node:util");
62694
62800
 
62695
62801
  // src/local-executor/git-lock-retry.ts
62696
62802
  var realSleep = (ms) => new Promise((resolve35) => setTimeout(resolve35, ms));
@@ -62726,7 +62832,7 @@ function withGitLockRetry(op, opts = {}) {
62726
62832
  // src/local-executor/worktree-merge.ts
62727
62833
  init_env_scrub();
62728
62834
  init_logger2();
62729
- var execFile8 = (0, import_node_util.promisify)(import_node_child_process16.execFile), GIT_MAXBUF = 64 * 1024 * 1024, MERGE_IMPL_ID = "git-host-v1", DETERMINISM_CONTRACT_ID = "ort+histogram+diff3+renames+dirrenames+indent", cachedMergeImplId;
62835
+ var execFile8 = (0, import_node_util.promisify)(import_node_child_process17.execFile), GIT_MAXBUF = 64 * 1024 * 1024, MERGE_IMPL_ID = "git-host-v1", DETERMINISM_CONTRACT_ID = "ort+histogram+diff3+renames+dirrenames+indent", cachedMergeImplId;
62730
62836
  async function resolveMergeImplId() {
62731
62837
  if (cachedMergeImplId !== void 0) return cachedMergeImplId;
62732
62838
  try {
@@ -62982,7 +63088,7 @@ async function pinnedGit(repoDir, args, opts = {}) {
62982
63088
  async function pinnedGitWithInput(repoDir, args, input, opts = {}) {
62983
63089
  let configPrefix = [...W2_HERMETIC_CONFIG, ...PINNED_GIT_CONFIG];
62984
63090
  return await new Promise((resolve35, reject) => {
62985
- let child = (0, import_node_child_process16.spawn)("git", ["-C", repoDir, ...configPrefix, ...args], {
63091
+ let child = (0, import_node_child_process17.spawn)("git", ["-C", repoDir, ...configPrefix, ...args], {
62986
63092
  env: sanitizeGitEnv(),
62987
63093
  stdio: ["pipe", "pipe", "pipe"]
62988
63094
  }), stdout = "", stderr = "", stdoutBytes = 0;
@@ -75535,7 +75641,7 @@ var import_node_crypto55 = require("node:crypto"), import_node_fs47 = require("n
75535
75641
  init_spawn_sweep_binary();
75536
75642
 
75537
75643
  // src/substrate/pasta-isolation-check.ts
75538
- var import_node_child_process18 = require("node:child_process"), import_node_crypto54 = require("node:crypto"), fs82 = __toESM(require("node:fs")), import_node_net2 = __toESM(require("node:net")), path101 = __toESM(require("node:path"));
75644
+ var import_node_child_process19 = require("node:child_process"), import_node_crypto54 = require("node:crypto"), fs82 = __toESM(require("node:fs")), import_node_net2 = __toESM(require("node:net")), path101 = __toESM(require("node:path"));
75539
75645
  init_logger2();
75540
75646
  init_pasta();
75541
75647
  function evaluateIsolation(e) {
@@ -75648,7 +75754,7 @@ async function runIsolationCheck(opts = {}) {
75648
75754
  ISOLATION_PROBE_SOURCE,
75649
75755
  JSON.stringify(ports)
75650
75756
  ], stdout = await new Promise((resolve35, reject) => {
75651
- let child = (0, import_node_child_process18.spawn)(argv[0], argv.slice(1), { stdio: ["ignore", "pipe", "pipe"] }), out = "", err = "", timer = setTimeout(() => {
75757
+ let child = (0, import_node_child_process19.spawn)(argv[0], argv.slice(1), { stdio: ["ignore", "pipe", "pipe"] }), out = "", err = "", timer = setTimeout(() => {
75652
75758
  child.kill("SIGKILL"), reject(new Error("isolation probe timed out"));
75653
75759
  }, opts.timeoutMs ?? 6e4);
75654
75760
  child.stdout.on("data", (d) => {
@@ -88524,17 +88630,28 @@ ${formatImplementorPolicy(detected, updated, props.tier)}`
88524
88630
  trackLabelByTaskId,
88525
88631
  gateActionRecoveryBlocked: state.gateActionRecoveryBlocked
88526
88632
  }),
88527
- ...shownTaskProgress.length > 0 ? shownTaskProgress.map(
88528
- ([taskId, line], index) => React22.createElement(LiveProgressLine, {
88529
- key: `progress-${taskId}`,
88530
- progress: line,
88531
- label: (() => {
88532
- let l = taskLabel(state, taskId);
88533
- return l.startsWith("#") ? l : void 0;
88534
- })(),
88535
- ...index === shownTaskProgress.length - 1 && hiddenTaskProgress > 0 ? { moreCount: hiddenTaskProgress } : {}
88536
- })
88537
- ) : [],
88633
+ // CP-1.f live progress surfacing — the ephemeral spinner status lines,
88634
+ // rendered ONLY while work is busy: P46b §3.7 one line per busy single task
88635
+ // (`progressByTask`, capped, `(+n more)` on the last), then a window that
88636
+ // belongs to no task (classify / familiarize). An idle line returns null and
88637
+ // its row collapses. The per-task lines are ONE keyed child so their count
88638
+ // never shifts the InputBar's position (a shift remounted it: typed text and
88639
+ // keystrokes were lost while tasks started/stopped — Hendry item 3).
88640
+ React22.createElement(
88641
+ React22.Fragment,
88642
+ { key: "progress-tasks" },
88643
+ ...shownTaskProgress.map(
88644
+ ([taskId, line], index) => React22.createElement(LiveProgressLine, {
88645
+ key: `progress-${taskId}`,
88646
+ progress: line,
88647
+ label: (() => {
88648
+ let l = taskLabel(state, taskId);
88649
+ return l.startsWith("#") ? l : void 0;
88650
+ })(),
88651
+ ...index === shownTaskProgress.length - 1 && hiddenTaskProgress > 0 ? { moreCount: hiddenTaskProgress } : {}
88652
+ })
88653
+ )
88654
+ ),
88538
88655
  React22.createElement(LiveProgressLine, { key: "progress-untasked", progress: untaskedProgress }),
88539
88656
  // `/reviewer-setup` wizard (2026-06-29) — while open it REPLACES the InputBar
88540
88657
  // at the same layout slot and owns keyboard focus (arrow-key ink-select); on
@@ -96645,7 +96762,7 @@ function resolveBrowseUrls(modelUrls, prompt) {
96645
96762
  let usable = modelUrls.filter(isWellFormedHttpUrl);
96646
96763
  return usable.length > 0 ? usable : void 0;
96647
96764
  }
96648
- var execFileAsync = (0, import_node_util3.promisify)(import_node_child_process19.execFile);
96765
+ var execFileAsync = (0, import_node_util3.promisify)(import_node_child_process20.execFile);
96649
96766
  function recordStartedTask(store, result, agent) {
96650
96767
  result.outcome !== void 0 && result.outcome !== "running" || store.dispatch({
96651
96768
  type: "TASK_LIFECYCLE",
@@ -107711,7 +107828,7 @@ async function engageWriteConfinedResolverSandbox(input) {
107711
107828
  }
107712
107829
 
107713
107830
  // src/substrate-launch/le-env-scrub.ts
107714
- var import_node_child_process20 = require("node:child_process"), LE_ENV_SCRUBBED_MARKER = "CODEVIBE_LE_ENV_SCRUBBED", CRED_KEY_PATTERNS = [
107831
+ var import_node_child_process21 = require("node:child_process"), LE_ENV_SCRUBBED_MARKER = "CODEVIBE_LE_ENV_SCRUBBED", CRED_KEY_PATTERNS = [
107715
107832
  /^ANTHROPIC_/i,
107716
107833
  /^OPENAI_/i,
107717
107834
  /^GOOGLE_/i,
@@ -107750,7 +107867,7 @@ function scrubLeEnvOrReexec(deps = {}) {
107750
107867
  throw new Error(
107751
107868
  `[le-env-scrub] Refusing to launch the Local Executor: the scrub marker (${LE_ENV_SCRUBBED_MARKER}) is set but credential-shaped env vars are still present (${scrubbedKeys.join(", ")}). A genuine re-exec'd child has NO credential-shaped vars; this indicates a spoofed marker or a broken scrub. Fail closed (CP-7 I1, A5 parent-procargs vector) \u2014 never launch the LE with a vendor credential in its exec-time procargs.`
107752
107869
  );
107753
- let spawnSyncFn = deps.spawnSyncFn ?? import_node_child_process20.spawnSync, execPath = deps.execPath ?? process.execPath, argv = deps.argv ?? process.argv.slice(1), cwd = deps.cwd ?? process.cwd(), scrubbedEnv = buildScrubbedLeEnv(env);
107870
+ let spawnSyncFn = deps.spawnSyncFn ?? import_node_child_process21.spawnSync, execPath = deps.execPath ?? process.execPath, argv = deps.argv ?? process.argv.slice(1), cwd = deps.cwd ?? process.cwd(), scrubbedEnv = buildScrubbedLeEnv(env);
107754
107871
  try {
107755
107872
  deps.onScrub?.(scrubbedKeys);
107756
107873
  } catch {
@@ -13,6 +13,16 @@ export declare function isSlashCommandInProgress(value: string): boolean;
13
13
  * dropdown). A bare `/` returns the whole list.
14
14
  */
15
15
  export declare function filterSlashSuggestions(value: string, commands: SlashCommandInfo[]): SlashCommandInfo[];
16
+ /**
17
+ * True when Enter should RUN the input instead of completing it: the value is
18
+ * already exactly the highlighted slash command (`/exit` with `/exit`
19
+ * highlighted). A partial (`/ex`) or a highlight the user moved to another
20
+ * command still completes (Hendry 2026-11-12: a fully typed command must not
21
+ * need a second Enter).
22
+ */
23
+ export declare function enterRunsTypedCommand(value: string, suggestions: ReadonlyArray<{
24
+ name: string;
25
+ }>, highlight: number): boolean;
16
26
  /**
17
27
  * Builds a single dropdown row as ONE physical line (≤ `maxCols`) so it can
18
28
  * never wrap and inflate the dropdown's row count on a narrow terminal
@@ -0,0 +1,8 @@
1
+ import type { CommandResult } from './types';
2
+ export declare const GROUP_LEADER_SCRIPT: string;
3
+ export interface GroupRunOptions {
4
+ timeoutMs?: number;
5
+ input?: string;
6
+ env: NodeJS.ProcessEnv;
7
+ }
8
+ export declare function runInOwnProcessGroup(argv: string[], opts: GroupRunOptions): Promise<CommandResult>;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-core",
3
- "version": "2.0.101",
3
+ "version": "2.0.103",
4
4
  "description": "Core library for CodeVibe plugins - shared keychain, crypto, AppSync, and auth functionality",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-codex-plugin",
3
- "version": "2.0.117",
3
+ "version": "2.0.119",
4
4
  "description": "Control OpenAI Codex CLI from your iPhone and Android — real-time sync, approve file edits, send prompts by voice. Part of CodeVibe.",
5
5
  "main": "dist/server.js",
6
6
  "codevibe": {
@@ -47,7 +47,7 @@
47
47
  "node": ">=22.0.0"
48
48
  },
49
49
  "dependencies": {
50
- "@quantiya/codevibe-core": "^2.0.101",
50
+ "@quantiya/codevibe-core": "^2.0.103",
51
51
  "@quantiya/quorum-core": "^1.0.1",
52
52
  "chokidar": "^4.0.0",
53
53
  "dotenv": "^16.6.1",