oh-my-copilot 5.6.2 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +1 -0
  4. package/bridge/__pycache__/gyoshu_bridge.cpython-312.pyc +0 -0
  5. package/bridge/claude-md-coordinator.cjs +2 -2
  6. package/bridge/cli.cjs +78578 -75769
  7. package/bridge/mcp-server.cjs +36510 -32259
  8. package/bridge/runtime-cli.cjs +95 -34
  9. package/bridge/team-mcp.cjs +95 -34
  10. package/bridge/team.js +131 -70
  11. package/dist/__tests__/run-cjs-fail-closed-timeout.test.d.ts +2 -0
  12. package/dist/__tests__/run-cjs-fail-closed-timeout.test.d.ts.map +1 -0
  13. package/dist/__tests__/run-cjs-fail-closed-timeout.test.js +68 -0
  14. package/dist/__tests__/run-cjs-fail-closed-timeout.test.js.map +1 -0
  15. package/dist/__tests__/session-end-process-exit.test.js +70 -2
  16. package/dist/__tests__/session-end-process-exit.test.js.map +1 -1
  17. package/dist/cli/commands/__tests__/smoke-tier2.test.d.ts +2 -0
  18. package/dist/cli/commands/__tests__/smoke-tier2.test.d.ts.map +1 -0
  19. package/dist/cli/commands/__tests__/smoke-tier2.test.js +72 -0
  20. package/dist/cli/commands/__tests__/smoke-tier2.test.js.map +1 -0
  21. package/dist/cli/commands/smoke.d.ts +36 -0
  22. package/dist/cli/commands/smoke.d.ts.map +1 -0
  23. package/dist/cli/commands/smoke.js +169 -0
  24. package/dist/cli/commands/smoke.js.map +1 -0
  25. package/dist/cli/index.d.ts.map +1 -1
  26. package/dist/cli/index.js +39 -0
  27. package/dist/cli/index.js.map +1 -1
  28. package/dist/constants/names.d.ts +1 -0
  29. package/dist/constants/names.d.ts.map +1 -1
  30. package/dist/constants/names.js +1 -0
  31. package/dist/constants/names.js.map +1 -1
  32. package/dist/hooks/session-end/index.d.ts +2 -3
  33. package/dist/hooks/session-end/index.d.ts.map +1 -1
  34. package/dist/hooks/session-end/index.js +3 -10
  35. package/dist/hooks/session-end/index.js.map +1 -1
  36. package/dist/hooks/session-end/wiki-foreground-bootstrap.d.ts +17 -0
  37. package/dist/hooks/session-end/wiki-foreground-bootstrap.d.ts.map +1 -0
  38. package/dist/hooks/session-end/wiki-foreground-bootstrap.js +20 -0
  39. package/dist/hooks/session-end/wiki-foreground-bootstrap.js.map +1 -0
  40. package/dist/lib/__tests__/atomic-write.test.js +32 -1
  41. package/dist/lib/__tests__/atomic-write.test.js.map +1 -1
  42. package/dist/lib/__tests__/mode-state-lock.test.js +121 -12
  43. package/dist/lib/__tests__/mode-state-lock.test.js.map +1 -1
  44. package/dist/lib/atomic-write.d.ts +13 -3
  45. package/dist/lib/atomic-write.d.ts.map +1 -1
  46. package/dist/lib/atomic-write.js +29 -15
  47. package/dist/lib/atomic-write.js.map +1 -1
  48. package/dist/lib/mode-state-io.d.ts +2 -2
  49. package/dist/lib/mode-state-io.d.ts.map +1 -1
  50. package/dist/lib/mode-state-io.js +16 -10
  51. package/dist/lib/mode-state-io.js.map +1 -1
  52. package/dist/mcp/__tests__/host-smoke-tool.test.d.ts +2 -0
  53. package/dist/mcp/__tests__/host-smoke-tool.test.d.ts.map +1 -0
  54. package/dist/mcp/__tests__/host-smoke-tool.test.js +174 -0
  55. package/dist/mcp/__tests__/host-smoke-tool.test.js.map +1 -0
  56. package/dist/mcp/disable-tools.d.ts.map +1 -1
  57. package/dist/mcp/disable-tools.js +1 -0
  58. package/dist/mcp/disable-tools.js.map +1 -1
  59. package/dist/mcp/tool-registry.d.ts.map +1 -1
  60. package/dist/mcp/tool-registry.js +2 -0
  61. package/dist/mcp/tool-registry.js.map +1 -1
  62. package/dist/smoke/__tests__/copilot-sdk-driver.test.d.ts +2 -0
  63. package/dist/smoke/__tests__/copilot-sdk-driver.test.d.ts.map +1 -0
  64. package/dist/smoke/__tests__/copilot-sdk-driver.test.js +561 -0
  65. package/dist/smoke/__tests__/copilot-sdk-driver.test.js.map +1 -0
  66. package/dist/smoke/__tests__/copilot-sdk-scenarios.test.d.ts +2 -0
  67. package/dist/smoke/__tests__/copilot-sdk-scenarios.test.d.ts.map +1 -0
  68. package/dist/smoke/__tests__/copilot-sdk-scenarios.test.js +311 -0
  69. package/dist/smoke/__tests__/copilot-sdk-scenarios.test.js.map +1 -0
  70. package/dist/smoke/__tests__/copilot-session-eval.test.d.ts +2 -0
  71. package/dist/smoke/__tests__/copilot-session-eval.test.d.ts.map +1 -0
  72. package/dist/smoke/__tests__/copilot-session-eval.test.js +264 -0
  73. package/dist/smoke/__tests__/copilot-session-eval.test.js.map +1 -0
  74. package/dist/smoke/__tests__/copilot-smoke.test.d.ts +2 -0
  75. package/dist/smoke/__tests__/copilot-smoke.test.d.ts.map +1 -0
  76. package/dist/smoke/__tests__/copilot-smoke.test.js +482 -0
  77. package/dist/smoke/__tests__/copilot-smoke.test.js.map +1 -0
  78. package/dist/smoke/copilot-binary.d.ts +21 -0
  79. package/dist/smoke/copilot-binary.d.ts.map +1 -0
  80. package/dist/smoke/copilot-binary.js +46 -0
  81. package/dist/smoke/copilot-binary.js.map +1 -0
  82. package/dist/smoke/copilot-sdk-driver.d.ts +186 -0
  83. package/dist/smoke/copilot-sdk-driver.d.ts.map +1 -0
  84. package/dist/smoke/copilot-sdk-driver.js +622 -0
  85. package/dist/smoke/copilot-sdk-driver.js.map +1 -0
  86. package/dist/smoke/copilot-sdk-scenarios.d.ts +159 -0
  87. package/dist/smoke/copilot-sdk-scenarios.d.ts.map +1 -0
  88. package/dist/smoke/copilot-sdk-scenarios.js +510 -0
  89. package/dist/smoke/copilot-sdk-scenarios.js.map +1 -0
  90. package/dist/smoke/copilot-session-eval.d.ts +90 -0
  91. package/dist/smoke/copilot-session-eval.d.ts.map +1 -0
  92. package/dist/smoke/copilot-session-eval.js +323 -0
  93. package/dist/smoke/copilot-session-eval.js.map +1 -0
  94. package/dist/smoke/copilot-smoke.d.ts +228 -0
  95. package/dist/smoke/copilot-smoke.d.ts.map +1 -0
  96. package/dist/smoke/copilot-smoke.js +818 -0
  97. package/dist/smoke/copilot-smoke.js.map +1 -0
  98. package/dist/smoke/process-utils.d.ts +47 -0
  99. package/dist/smoke/process-utils.d.ts.map +1 -0
  100. package/dist/smoke/process-utils.js +99 -0
  101. package/dist/smoke/process-utils.js.map +1 -0
  102. package/dist/team/__tests__/tmux-session.pane-env.test.d.ts +2 -0
  103. package/dist/team/__tests__/tmux-session.pane-env.test.d.ts.map +1 -0
  104. package/dist/team/__tests__/tmux-session.pane-env.test.js +52 -0
  105. package/dist/team/__tests__/tmux-session.pane-env.test.js.map +1 -0
  106. package/dist/team/tmux-session.d.ts +7 -0
  107. package/dist/team/tmux-session.d.ts.map +1 -1
  108. package/dist/team/tmux-session.js +80 -18
  109. package/dist/team/tmux-session.js.map +1 -1
  110. package/dist/tools/host-smoke-tool.d.ts +34 -0
  111. package/dist/tools/host-smoke-tool.d.ts.map +1 -0
  112. package/dist/tools/host-smoke-tool.js +133 -0
  113. package/dist/tools/host-smoke-tool.js.map +1 -0
  114. package/docs/CLAUDE.md +1 -1
  115. package/docs/DEVELOPERS.md +101 -0
  116. package/docs/HOOKS.md +1 -1
  117. package/docs/MIGRATION.md +71 -0
  118. package/docs/REFERENCE.md +42 -1
  119. package/docs/TOOLS.md +32 -1
  120. package/package.json +11 -2
  121. package/plugin.json +1 -1
  122. package/scripts/dev/repro-state-lock.mjs +1 -1
  123. package/scripts/lib/atomic-write.mjs +4 -2
  124. package/scripts/lib/state-lock.mjs +21 -12
  125. package/scripts/run.cjs +13 -3
  126. package/scripts/wiki-session-end.mjs +2 -1
  127. package/templates/hooks/lib/atomic-write.mjs +4 -2
@@ -7343,33 +7343,33 @@ function ensureDirSync(dir) {
7343
7343
  }
7344
7344
  }
7345
7345
  function verifyPrivateTempFile(fd, tempPath, label, operations) {
7346
- const fdStats = fsSync.fstatSync(fd);
7346
+ const fdStats = descriptorStats(fd, operations);
7347
7347
  let pathStats;
7348
7348
  try {
7349
- pathStats = (operations?.lstat ?? fsSync.lstatSync)(tempPath);
7349
+ pathStats = pathnameStats(tempPath, operations);
7350
7350
  } catch {
7351
7351
  throw new Error(`${label} temporary file was replaced before rename`);
7352
7352
  }
7353
7353
  const isWindows = process.platform === "win32";
7354
- const isPrivateRegularSingleLink = (stats) => stats.isFile() && (isWindows ? stats.nlink <= 1 : stats.nlink === 1) && (isWindows || (stats.mode & 511) === 384);
7354
+ const isPrivateRegularSingleLink = (stats) => stats.isFile() && (isWindows ? Number(stats.nlink) <= 1 : Number(stats.nlink) === 1) && (isWindows || (Number(stats.mode) & 511) === 384);
7355
7355
  if (!isPrivateRegularSingleLink(fdStats) || !isPrivateRegularSingleLink(pathStats)) {
7356
7356
  throw new Error(
7357
7357
  `${label} temporary file must be a private regular single-link file`
7358
7358
  );
7359
7359
  }
7360
- if (!sameFileIdentity(fdStats, pathStats)) {
7360
+ if (!sameFileIdentity(fileIdentityOf(fdStats), fileIdentityOf(pathStats))) {
7361
7361
  throw new Error(`${label} temporary file was replaced before rename`);
7362
7362
  }
7363
7363
  }
7364
7364
  function verifyPublishedFile(fd, filePath, label, operations) {
7365
- const fdStats = fsSync.fstatSync(fd);
7365
+ const fdStats = descriptorStats(fd, operations);
7366
7366
  let pathStats;
7367
7367
  try {
7368
- pathStats = (operations?.lstat ?? fsSync.lstatSync)(filePath);
7368
+ pathStats = pathnameStats(filePath, operations);
7369
7369
  } catch {
7370
7370
  throw new Error(`${label} target was replaced at publication`);
7371
7371
  }
7372
- if (!pathStats.isFile() || !sameFileIdentity(fdStats, pathStats)) {
7372
+ if (!pathStats.isFile() || !sameFileIdentity(fileIdentityOf(fdStats), fileIdentityOf(pathStats))) {
7373
7373
  throw new Error(`${label} target was replaced at publication`);
7374
7374
  }
7375
7375
  }
@@ -7393,26 +7393,33 @@ function preservePriorTarget(filePath, operations) {
7393
7393
  return null;
7394
7394
  }
7395
7395
  }
7396
+ function descriptorStats(fd, operations) {
7397
+ return operations ? fsSync.fstatSync(fd) : fsSync.fstatSync(fd, { bigint: true });
7398
+ }
7399
+ function pathnameStats(filePath, operations) {
7400
+ return operations ? operations.lstat(filePath) : fsSync.lstatSync(filePath, { bigint: true });
7401
+ }
7402
+ function fileIdentityOf(stats) {
7403
+ return { dev: BigInt(stats.dev), ino: BigInt(stats.ino) };
7404
+ }
7396
7405
  function sameFileIdentity(a, b) {
7397
7406
  if (a.ino !== b.ino) return false;
7398
7407
  const isWindows = process.platform === "win32";
7399
- if (isWindows && (a.dev === 0 || b.dev === 0)) {
7408
+ if (isWindows && (a.dev === 0n || b.dev === 0n)) {
7400
7409
  return true;
7401
7410
  }
7402
7411
  return a.dev === b.dev;
7403
7412
  }
7404
7413
  function currentFileIdentity(filePath, operations) {
7405
7414
  try {
7406
- const stats = (operations?.lstat ?? fsSync.lstatSync)(filePath);
7407
- return { dev: stats.dev, ino: stats.ino };
7415
+ return fileIdentityOf(pathnameStats(filePath, operations));
7408
7416
  } catch {
7409
7417
  return null;
7410
7418
  }
7411
7419
  }
7412
- function descriptorIdentity(fd) {
7420
+ function descriptorIdentity(fd, operations) {
7413
7421
  try {
7414
- const stats = fsSync.fstatSync(fd);
7415
- return { dev: stats.dev, ino: stats.ino };
7422
+ return fileIdentityOf(descriptorStats(fd, operations));
7416
7423
  } catch {
7417
7424
  return null;
7418
7425
  }
@@ -10173,7 +10180,8 @@ __export(tmux_session_exports, {
10173
10180
  waitForPaneReady: () => waitForPaneReady,
10174
10181
  waitForStartupPaneReady: () => waitForStartupPaneReady,
10175
10182
  workerPaneBelongsToOwnedProviderTarget: () => workerPaneBelongsToOwnedProviderTarget,
10176
- workerPaneBelongsToProviderTarget: () => workerPaneBelongsToProviderTarget
10183
+ workerPaneBelongsToProviderTarget: () => workerPaneBelongsToProviderTarget,
10184
+ workerPaneShellCommand: () => workerPaneShellCommand
10177
10185
  });
10178
10186
  function tmuxArgsForIdentity(identity, args) {
10179
10187
  return ["-S", identity.socket_path, ...args];
@@ -11048,23 +11056,66 @@ async function verifyWorkerStartCommandSubmitted(paneId, startCmd, opts = {}) {
11048
11056
  }
11049
11057
  return false;
11050
11058
  }
11059
+ function writePaneEnvFile(values) {
11060
+ const directory = (0, import_fs24.mkdtempSync)((0, import_path25.join)((0, import_os8.tmpdir)(), "omc-pane-env-"));
11061
+ const file = (0, import_path25.join)(directory, "env");
11062
+ const body = Object.entries(values).map(([key, value]) => `export ${key}=${shellQuote(value)}
11063
+ `).join("");
11064
+ (0, import_fs24.writeFileSync)(file, body, { mode: 384, flag: "wx" });
11065
+ return file;
11066
+ }
11067
+ function discardPaneEnvFile(envFile) {
11068
+ if (!envFile) return;
11069
+ (0, import_fs24.rmSync)((0, import_path25.dirname)(envFile), { recursive: true, force: true });
11070
+ }
11051
11071
  function workerPaneShellCommand() {
11052
11072
  if (process.platform === "win32" && !isUnixLikeOnWindows()) {
11053
- return [getDefaultShell()];
11073
+ return { args: [getDefaultShell()], envFile: null };
11054
11074
  }
11055
- if (process.platform === "win32") return [];
11075
+ if (process.platform === "win32") return { args: [], envFile: null };
11056
11076
  const shell = getDefaultShell();
11057
11077
  const baseline = buildProviderEnvironment({ SHELL: shell });
11078
+ const inline = buildProviderEnvironment({ SHELL: shell }, process.env, process.platform, []);
11079
+ const passthrough = Object.fromEntries(
11080
+ Object.entries(baseline).filter(([key, value]) => inline[key] !== value)
11081
+ );
11058
11082
  const inheritedPaneEnvironment = ["TERM", "TMUX", "TMUX_PANE", "TMUX_TMPDIR", "LANG", "LC_ALL", "LC_CTYPE"].map((key) => `${key}="$${key}"`);
11083
+ const inlineAssignments = Object.entries(inline).map(([key, value]) => `${key}=${shellQuote(value)}`);
11084
+ if (Object.keys(passthrough).length === 0) {
11085
+ const command2 = [
11086
+ "/usr/bin/env",
11087
+ "-i",
11088
+ ...inlineAssignments,
11089
+ ...inheritedPaneEnvironment,
11090
+ shellQuote(shell),
11091
+ "-l"
11092
+ ].join(" ");
11093
+ return { args: [command2], envFile: null };
11094
+ }
11095
+ const envFile = writePaneEnvFile(passthrough);
11096
+ const bootstrap = '. "$OMC_PANE_ENV_FILE" && rm -rf -- "${OMC_PANE_ENV_FILE%/*}" && unset OMC_PANE_ENV_FILE && exec "$SHELL" -l';
11059
11097
  const command = [
11060
11098
  "/usr/bin/env",
11061
11099
  "-i",
11062
- ...Object.entries(baseline).map(([key, value]) => `${key}=${shellQuote(value)}`),
11100
+ ...inlineAssignments,
11101
+ `OMC_PANE_ENV_FILE=${shellQuote(envFile)}`,
11063
11102
  ...inheritedPaneEnvironment,
11064
- shellQuote(shell),
11065
- "-l"
11103
+ "/bin/sh",
11104
+ "-c",
11105
+ shellQuote(bootstrap)
11066
11106
  ].join(" ");
11067
- return [command];
11107
+ return { args: [command], envFile };
11108
+ }
11109
+ async function runPaneCreationCommand(identity, nativeCommand, paneShell) {
11110
+ let result;
11111
+ try {
11112
+ result = await runGuardedNativeTmuxCommand(identity, nativeCommand);
11113
+ } catch (error) {
11114
+ discardPaneEnvFile(paneShell.envFile);
11115
+ throw error;
11116
+ }
11117
+ if (result.outcome === "not_executed") discardPaneEnvFile(paneShell.envFile);
11118
+ return result;
11068
11119
  }
11069
11120
  function escapeForCmdSet(value) {
11070
11121
  return value.replace(/(["%])/g, "$1$1");
@@ -11363,6 +11414,7 @@ async function splitTeamWorkerPaneWithEvidence(splitTarget, direction, cwd, prov
11363
11414
  };
11364
11415
  }
11365
11416
  const splitType = direction === "right" ? "-h" : "-v";
11417
+ const splitPaneShell = workerPaneShellCommand();
11366
11418
  const splitArgs = [
11367
11419
  "split-window",
11368
11420
  splitType,
@@ -11374,11 +11426,12 @@ async function splitTeamWorkerPaneWithEvidence(splitTarget, direction, cwd, prov
11374
11426
  "#{pane_id} #{socket_path} #{pid}",
11375
11427
  "-c",
11376
11428
  cwd,
11377
- ...workerPaneShellCommand()
11429
+ ...splitPaneShell.args
11378
11430
  ];
11379
- const splitResult = await runGuardedNativeTmuxCommand(
11431
+ const splitResult = await runPaneCreationCommand(
11380
11432
  identity,
11381
- tmuxCommandString(splitArgs, ["#{pane_id} #{socket_path} #{pid}"])
11433
+ tmuxCommandString(splitArgs, ["#{pane_id} #{socket_path} #{pid}"]),
11434
+ splitPaneShell
11382
11435
  );
11383
11436
  const parsed = splitResult.outcome === "executed" ? parseTmuxCreationRecord(
11384
11437
  splitResult.stdout,
@@ -11480,6 +11533,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
11480
11533
  sessionMode: "detached-session",
11481
11534
  ...tmuxServerIdentity ? { tmuxServerIdentity: { ...tmuxServerIdentity } } : {}
11482
11535
  });
11536
+ const detachedPaneShell = workerPaneShellCommand();
11483
11537
  const detachedArgs = [
11484
11538
  "new-session",
11485
11539
  "-d",
@@ -11490,7 +11544,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
11490
11544
  detachedSessionName,
11491
11545
  "-c",
11492
11546
  cwd,
11493
- ...workerPaneShellCommand()
11547
+ ...detachedPaneShell.args
11494
11548
  ];
11495
11549
  const cleanupFreshDetachedServer = async () => {
11496
11550
  if (isPsmux() && freshSocketPathForEvidence) {
@@ -11519,9 +11573,10 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
11519
11573
  if (existingDetachedIdentity) {
11520
11574
  tmuxServerIdentity = existingDetachedIdentity;
11521
11575
  try {
11522
- detachedResult = await runGuardedNativeTmuxCommand(
11576
+ detachedResult = await runPaneCreationCommand(
11523
11577
  existingDetachedIdentity,
11524
- tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"])
11578
+ tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"]),
11579
+ detachedPaneShell
11525
11580
  );
11526
11581
  } catch (error) {
11527
11582
  const cleaned = await cleanupDetachedSession();
@@ -11581,11 +11636,13 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
11581
11636
  throw new Error("tmux_server_identity_unavailable");
11582
11637
  }
11583
11638
  freshDetachedServerIdentity = tmuxServerIdentity;
11584
- detachedResult = await runGuardedNativeTmuxCommand(
11639
+ detachedResult = await runPaneCreationCommand(
11585
11640
  tmuxServerIdentity,
11586
- tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"])
11641
+ tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"]),
11642
+ detachedPaneShell
11587
11643
  );
11588
11644
  } catch (error) {
11645
+ discardPaneEnvFile(detachedPaneShell.envFile);
11589
11646
  const cleaned = await cleanupDetachedSession();
11590
11647
  if (!cleaned && freshDetachedServerStarted) {
11591
11648
  throw new TeamSessionCreationError(
@@ -11765,6 +11822,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
11765
11822
  if (useDedicatedWindow) {
11766
11823
  const targetSession = sessionAndWindow.split(":")[0] ?? sessionAndWindow;
11767
11824
  const windowName = `omc-${sanitizeName(teamName)}`.slice(0, 32);
11825
+ const newWindowPaneShell = workerPaneShellCommand();
11768
11826
  const newWindowArgs = [
11769
11827
  "new-window",
11770
11828
  "-d",
@@ -11777,13 +11835,14 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
11777
11835
  windowName,
11778
11836
  "-c",
11779
11837
  cwd,
11780
- ...workerPaneShellCommand()
11838
+ ...newWindowPaneShell.args
11781
11839
  ];
11782
11840
  let newWindowResult;
11783
11841
  try {
11784
- newWindowResult = await runGuardedNativeTmuxCommand(
11842
+ newWindowResult = await runPaneCreationCommand(
11785
11843
  tmuxServerIdentity,
11786
- tmuxCommandString(newWindowArgs, ["#S:#I #{pane_id} #{socket_path} #{pid}"])
11844
+ tmuxCommandString(newWindowArgs, ["#S:#I #{pane_id} #{socket_path} #{pid}"]),
11845
+ newWindowPaneShell
11787
11846
  );
11788
11847
  } catch (error) {
11789
11848
  const creationError = new TeamSessionCreationError(
@@ -11933,6 +11992,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
11933
11992
  continue;
11934
11993
  }
11935
11994
  const splitType = i === 0 ? "-h" : "-v";
11995
+ const splitPaneShell = workerPaneShellCommand();
11936
11996
  const splitArgs = [
11937
11997
  "split-window",
11938
11998
  splitType,
@@ -11944,11 +12004,12 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
11944
12004
  "#{pane_id} #{socket_path} #{pid}",
11945
12005
  "-c",
11946
12006
  cwd,
11947
- ...workerPaneShellCommand()
12007
+ ...splitPaneShell.args
11948
12008
  ];
11949
- const splitResult = await runGuardedNativeTmuxCommand(
12009
+ const splitResult = await runPaneCreationCommand(
11950
12010
  tmuxServerIdentity,
11951
- tmuxCommandString(splitArgs, ["#{pane_id} #{socket_path} #{pid}"])
12011
+ tmuxCommandString(splitArgs, ["#{pane_id} #{socket_path} #{pid}"]),
12012
+ splitPaneShell
11952
12013
  );
11953
12014
  if (splitResult.outcome !== "executed") {
11954
12015
  const creationError = new TeamSessionCreationError(
@@ -12066,33 +12066,33 @@ function ensureDirSync(dir) {
12066
12066
  }
12067
12067
  }
12068
12068
  function verifyPrivateTempFile(fd, tempPath, label, operations) {
12069
- const fdStats = fsSync.fstatSync(fd);
12069
+ const fdStats = descriptorStats(fd, operations);
12070
12070
  let pathStats;
12071
12071
  try {
12072
- pathStats = (operations?.lstat ?? fsSync.lstatSync)(tempPath);
12072
+ pathStats = pathnameStats(tempPath, operations);
12073
12073
  } catch {
12074
12074
  throw new Error(`${label} temporary file was replaced before rename`);
12075
12075
  }
12076
12076
  const isWindows = process.platform === "win32";
12077
- const isPrivateRegularSingleLink = (stats) => stats.isFile() && (isWindows ? stats.nlink <= 1 : stats.nlink === 1) && (isWindows || (stats.mode & 511) === 384);
12077
+ const isPrivateRegularSingleLink = (stats) => stats.isFile() && (isWindows ? Number(stats.nlink) <= 1 : Number(stats.nlink) === 1) && (isWindows || (Number(stats.mode) & 511) === 384);
12078
12078
  if (!isPrivateRegularSingleLink(fdStats) || !isPrivateRegularSingleLink(pathStats)) {
12079
12079
  throw new Error(
12080
12080
  `${label} temporary file must be a private regular single-link file`
12081
12081
  );
12082
12082
  }
12083
- if (!sameFileIdentity(fdStats, pathStats)) {
12083
+ if (!sameFileIdentity(fileIdentityOf(fdStats), fileIdentityOf(pathStats))) {
12084
12084
  throw new Error(`${label} temporary file was replaced before rename`);
12085
12085
  }
12086
12086
  }
12087
12087
  function verifyPublishedFile(fd, filePath, label, operations) {
12088
- const fdStats = fsSync.fstatSync(fd);
12088
+ const fdStats = descriptorStats(fd, operations);
12089
12089
  let pathStats;
12090
12090
  try {
12091
- pathStats = (operations?.lstat ?? fsSync.lstatSync)(filePath);
12091
+ pathStats = pathnameStats(filePath, operations);
12092
12092
  } catch {
12093
12093
  throw new Error(`${label} target was replaced at publication`);
12094
12094
  }
12095
- if (!pathStats.isFile() || !sameFileIdentity(fdStats, pathStats)) {
12095
+ if (!pathStats.isFile() || !sameFileIdentity(fileIdentityOf(fdStats), fileIdentityOf(pathStats))) {
12096
12096
  throw new Error(`${label} target was replaced at publication`);
12097
12097
  }
12098
12098
  }
@@ -12116,26 +12116,33 @@ function preservePriorTarget(filePath, operations) {
12116
12116
  return null;
12117
12117
  }
12118
12118
  }
12119
+ function descriptorStats(fd, operations) {
12120
+ return operations ? fsSync.fstatSync(fd) : fsSync.fstatSync(fd, { bigint: true });
12121
+ }
12122
+ function pathnameStats(filePath, operations) {
12123
+ return operations ? operations.lstat(filePath) : fsSync.lstatSync(filePath, { bigint: true });
12124
+ }
12125
+ function fileIdentityOf(stats) {
12126
+ return { dev: BigInt(stats.dev), ino: BigInt(stats.ino) };
12127
+ }
12119
12128
  function sameFileIdentity(a, b) {
12120
12129
  if (a.ino !== b.ino) return false;
12121
12130
  const isWindows = process.platform === "win32";
12122
- if (isWindows && (a.dev === 0 || b.dev === 0)) {
12131
+ if (isWindows && (a.dev === 0n || b.dev === 0n)) {
12123
12132
  return true;
12124
12133
  }
12125
12134
  return a.dev === b.dev;
12126
12135
  }
12127
12136
  function currentFileIdentity(filePath, operations) {
12128
12137
  try {
12129
- const stats = (operations?.lstat ?? fsSync.lstatSync)(filePath);
12130
- return { dev: stats.dev, ino: stats.ino };
12138
+ return fileIdentityOf(pathnameStats(filePath, operations));
12131
12139
  } catch {
12132
12140
  return null;
12133
12141
  }
12134
12142
  }
12135
- function descriptorIdentity(fd) {
12143
+ function descriptorIdentity(fd, operations) {
12136
12144
  try {
12137
- const stats = fsSync.fstatSync(fd);
12138
- return { dev: stats.dev, ino: stats.ino };
12145
+ return fileIdentityOf(descriptorStats(fd, operations));
12139
12146
  } catch {
12140
12147
  return null;
12141
12148
  }
@@ -13433,7 +13440,8 @@ __export(tmux_session_exports, {
13433
13440
  waitForPaneReady: () => waitForPaneReady,
13434
13441
  waitForStartupPaneReady: () => waitForStartupPaneReady,
13435
13442
  workerPaneBelongsToOwnedProviderTarget: () => workerPaneBelongsToOwnedProviderTarget,
13436
- workerPaneBelongsToProviderTarget: () => workerPaneBelongsToProviderTarget
13443
+ workerPaneBelongsToProviderTarget: () => workerPaneBelongsToProviderTarget,
13444
+ workerPaneShellCommand: () => workerPaneShellCommand
13437
13445
  });
13438
13446
  function tmuxArgsForIdentity(identity, args) {
13439
13447
  return ["-S", identity.socket_path, ...args];
@@ -14308,23 +14316,66 @@ async function verifyWorkerStartCommandSubmitted(paneId, startCmd, opts = {}) {
14308
14316
  }
14309
14317
  return false;
14310
14318
  }
14319
+ function writePaneEnvFile(values) {
14320
+ const directory = (0, import_fs22.mkdtempSync)((0, import_path24.join)((0, import_os7.tmpdir)(), "omc-pane-env-"));
14321
+ const file = (0, import_path24.join)(directory, "env");
14322
+ const body = Object.entries(values).map(([key, value]) => `export ${key}=${shellQuote(value)}
14323
+ `).join("");
14324
+ (0, import_fs22.writeFileSync)(file, body, { mode: 384, flag: "wx" });
14325
+ return file;
14326
+ }
14327
+ function discardPaneEnvFile(envFile) {
14328
+ if (!envFile) return;
14329
+ (0, import_fs22.rmSync)((0, import_path24.dirname)(envFile), { recursive: true, force: true });
14330
+ }
14311
14331
  function workerPaneShellCommand() {
14312
14332
  if (process.platform === "win32" && !isUnixLikeOnWindows()) {
14313
- return [getDefaultShell()];
14333
+ return { args: [getDefaultShell()], envFile: null };
14314
14334
  }
14315
- if (process.platform === "win32") return [];
14335
+ if (process.platform === "win32") return { args: [], envFile: null };
14316
14336
  const shell = getDefaultShell();
14317
14337
  const baseline = buildProviderEnvironment({ SHELL: shell });
14338
+ const inline = buildProviderEnvironment({ SHELL: shell }, process.env, process.platform, []);
14339
+ const passthrough = Object.fromEntries(
14340
+ Object.entries(baseline).filter(([key, value]) => inline[key] !== value)
14341
+ );
14318
14342
  const inheritedPaneEnvironment = ["TERM", "TMUX", "TMUX_PANE", "TMUX_TMPDIR", "LANG", "LC_ALL", "LC_CTYPE"].map((key) => `${key}="$${key}"`);
14343
+ const inlineAssignments = Object.entries(inline).map(([key, value]) => `${key}=${shellQuote(value)}`);
14344
+ if (Object.keys(passthrough).length === 0) {
14345
+ const command2 = [
14346
+ "/usr/bin/env",
14347
+ "-i",
14348
+ ...inlineAssignments,
14349
+ ...inheritedPaneEnvironment,
14350
+ shellQuote(shell),
14351
+ "-l"
14352
+ ].join(" ");
14353
+ return { args: [command2], envFile: null };
14354
+ }
14355
+ const envFile = writePaneEnvFile(passthrough);
14356
+ const bootstrap = '. "$OMC_PANE_ENV_FILE" && rm -rf -- "${OMC_PANE_ENV_FILE%/*}" && unset OMC_PANE_ENV_FILE && exec "$SHELL" -l';
14319
14357
  const command = [
14320
14358
  "/usr/bin/env",
14321
14359
  "-i",
14322
- ...Object.entries(baseline).map(([key, value]) => `${key}=${shellQuote(value)}`),
14360
+ ...inlineAssignments,
14361
+ `OMC_PANE_ENV_FILE=${shellQuote(envFile)}`,
14323
14362
  ...inheritedPaneEnvironment,
14324
- shellQuote(shell),
14325
- "-l"
14363
+ "/bin/sh",
14364
+ "-c",
14365
+ shellQuote(bootstrap)
14326
14366
  ].join(" ");
14327
- return [command];
14367
+ return { args: [command], envFile };
14368
+ }
14369
+ async function runPaneCreationCommand(identity, nativeCommand, paneShell) {
14370
+ let result;
14371
+ try {
14372
+ result = await runGuardedNativeTmuxCommand(identity, nativeCommand);
14373
+ } catch (error2) {
14374
+ discardPaneEnvFile(paneShell.envFile);
14375
+ throw error2;
14376
+ }
14377
+ if (result.outcome === "not_executed") discardPaneEnvFile(paneShell.envFile);
14378
+ return result;
14328
14379
  }
14329
14380
  function escapeForCmdSet(value) {
14330
14381
  return value.replace(/(["%])/g, "$1$1");
@@ -14623,6 +14674,7 @@ async function splitTeamWorkerPaneWithEvidence(splitTarget, direction, cwd, prov
14623
14674
  };
14624
14675
  }
14625
14676
  const splitType = direction === "right" ? "-h" : "-v";
14677
+ const splitPaneShell = workerPaneShellCommand();
14626
14678
  const splitArgs = [
14627
14679
  "split-window",
14628
14680
  splitType,
@@ -14634,11 +14686,12 @@ async function splitTeamWorkerPaneWithEvidence(splitTarget, direction, cwd, prov
14634
14686
  "#{pane_id} #{socket_path} #{pid}",
14635
14687
  "-c",
14636
14688
  cwd,
14637
- ...workerPaneShellCommand()
14689
+ ...splitPaneShell.args
14638
14690
  ];
14639
- const splitResult = await runGuardedNativeTmuxCommand(
14691
+ const splitResult = await runPaneCreationCommand(
14640
14692
  identity,
14641
- tmuxCommandString(splitArgs, ["#{pane_id} #{socket_path} #{pid}"])
14693
+ tmuxCommandString(splitArgs, ["#{pane_id} #{socket_path} #{pid}"]),
14694
+ splitPaneShell
14642
14695
  );
14643
14696
  const parsed = splitResult.outcome === "executed" ? parseTmuxCreationRecord(
14644
14697
  splitResult.stdout,
@@ -14740,6 +14793,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
14740
14793
  sessionMode: "detached-session",
14741
14794
  ...tmuxServerIdentity ? { tmuxServerIdentity: { ...tmuxServerIdentity } } : {}
14742
14795
  });
14796
+ const detachedPaneShell = workerPaneShellCommand();
14743
14797
  const detachedArgs = [
14744
14798
  "new-session",
14745
14799
  "-d",
@@ -14750,7 +14804,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
14750
14804
  detachedSessionName,
14751
14805
  "-c",
14752
14806
  cwd,
14753
- ...workerPaneShellCommand()
14807
+ ...detachedPaneShell.args
14754
14808
  ];
14755
14809
  const cleanupFreshDetachedServer = async () => {
14756
14810
  if (isPsmux() && freshSocketPathForEvidence) {
@@ -14779,9 +14833,10 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
14779
14833
  if (existingDetachedIdentity) {
14780
14834
  tmuxServerIdentity = existingDetachedIdentity;
14781
14835
  try {
14782
- detachedResult = await runGuardedNativeTmuxCommand(
14836
+ detachedResult = await runPaneCreationCommand(
14783
14837
  existingDetachedIdentity,
14784
- tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"])
14838
+ tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"]),
14839
+ detachedPaneShell
14785
14840
  );
14786
14841
  } catch (error2) {
14787
14842
  const cleaned = await cleanupDetachedSession();
@@ -14841,11 +14896,13 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
14841
14896
  throw new Error("tmux_server_identity_unavailable");
14842
14897
  }
14843
14898
  freshDetachedServerIdentity = tmuxServerIdentity;
14844
- detachedResult = await runGuardedNativeTmuxCommand(
14899
+ detachedResult = await runPaneCreationCommand(
14845
14900
  tmuxServerIdentity,
14846
- tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"])
14901
+ tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"]),
14902
+ detachedPaneShell
14847
14903
  );
14848
14904
  } catch (error2) {
14905
+ discardPaneEnvFile(detachedPaneShell.envFile);
14849
14906
  const cleaned = await cleanupDetachedSession();
14850
14907
  if (!cleaned && freshDetachedServerStarted) {
14851
14908
  throw new TeamSessionCreationError(
@@ -15025,6 +15082,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
15025
15082
  if (useDedicatedWindow) {
15026
15083
  const targetSession = sessionAndWindow.split(":")[0] ?? sessionAndWindow;
15027
15084
  const windowName = `omc-${sanitizeName(teamName)}`.slice(0, 32);
15085
+ const newWindowPaneShell = workerPaneShellCommand();
15028
15086
  const newWindowArgs = [
15029
15087
  "new-window",
15030
15088
  "-d",
@@ -15037,13 +15095,14 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
15037
15095
  windowName,
15038
15096
  "-c",
15039
15097
  cwd,
15040
- ...workerPaneShellCommand()
15098
+ ...newWindowPaneShell.args
15041
15099
  ];
15042
15100
  let newWindowResult;
15043
15101
  try {
15044
- newWindowResult = await runGuardedNativeTmuxCommand(
15102
+ newWindowResult = await runPaneCreationCommand(
15045
15103
  tmuxServerIdentity,
15046
- tmuxCommandString(newWindowArgs, ["#S:#I #{pane_id} #{socket_path} #{pid}"])
15104
+ tmuxCommandString(newWindowArgs, ["#S:#I #{pane_id} #{socket_path} #{pid}"]),
15105
+ newWindowPaneShell
15047
15106
  );
15048
15107
  } catch (error2) {
15049
15108
  const creationError = new TeamSessionCreationError(
@@ -15193,6 +15252,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
15193
15252
  continue;
15194
15253
  }
15195
15254
  const splitType = i === 0 ? "-h" : "-v";
15255
+ const splitPaneShell = workerPaneShellCommand();
15196
15256
  const splitArgs = [
15197
15257
  "split-window",
15198
15258
  splitType,
@@ -15204,11 +15264,12 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
15204
15264
  "#{pane_id} #{socket_path} #{pid}",
15205
15265
  "-c",
15206
15266
  cwd,
15207
- ...workerPaneShellCommand()
15267
+ ...splitPaneShell.args
15208
15268
  ];
15209
- const splitResult = await runGuardedNativeTmuxCommand(
15269
+ const splitResult = await runPaneCreationCommand(
15210
15270
  tmuxServerIdentity,
15211
- tmuxCommandString(splitArgs, ["#{pane_id} #{socket_path} #{pid}"])
15271
+ tmuxCommandString(splitArgs, ["#{pane_id} #{socket_path} #{pid}"]),
15272
+ splitPaneShell
15212
15273
  );
15213
15274
  if (splitResult.outcome !== "executed") {
15214
15275
  const creationError = new TeamSessionCreationError(