tmux-ide 2.9.0-beta.46 → 2.9.0-beta.48

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 (65) hide show
  1. package/bin/cli.js +780 -546
  2. package/package.json +2 -2
  3. package/packages/contracts/src/automation-operations.ts +2 -0
  4. package/packages/core/src/interaction-receipts.ts +9 -1
  5. package/packages/daemon/dist/automation.js +21 -2
  6. package/packages/daemon/dist/command-center/automation.js +13 -1
  7. package/packages/daemon/dist/command-center/discovery.js +9 -2
  8. package/packages/daemon/dist/command-center/resources/agent-graph-overlay.js +2 -2
  9. package/packages/daemon/dist/command-center/resources/application-shell.js +21 -15
  10. package/packages/daemon/dist/command-center/resources/fleet-catalog.js +6 -4
  11. package/packages/daemon/dist/command-center/resources/fleet-resource-route.js +2 -2
  12. package/packages/daemon/dist/lib/daemon-embed.js +22 -3
  13. package/packages/daemon/dist/mcp.js +12 -4
  14. package/packages/daemon/dist/terminal/attachments/agent-status-probe.js +12 -0
  15. package/packages/daemon/dist/terminal/attachments/claude-team-names.js +130 -0
  16. package/packages/daemon/dist/terminal/attachments/native-runtime.js +1 -0
  17. package/packages/daemon/dist/terminal/mirror/session-channel.js +1 -0
  18. package/packages/daemon/dist/terminal/protocol/pane-display-name.js +40 -11
  19. package/packages/daemon/dist/terminal/protocol/session-descriptor-discovery.js +4 -5
  20. package/packages/daemon/dist/tui/mirror/runtime/application-home-agents-owner.js +17 -1
  21. package/packages/daemon/dist/tui/mirror/runtime/application-home-experience.js +1 -0
  22. package/packages/daemon/dist/tui/mirror/runtime/application-new-agent-owner.js +86 -0
  23. package/packages/daemon/dist/tui/mirror/runtime/application-palette-command-owner.js +5 -0
  24. package/packages/daemon/dist/tui/mirror/runtime/application-palette-input.js +1 -0
  25. package/packages/daemon/dist/tui/mirror/runtime/application-pane-activity-owner.js +4 -3
  26. package/packages/daemon/dist/tui/mirror/runtime/application-terminal-interaction-controller.js +24 -0
  27. package/packages/daemon/dist/tui/mirror/runtime/application-terminal-workspace-policy.js +7 -5
  28. package/packages/daemon/dist/tui/mirror/runtime/application-terminal-workspace.jsx +3 -0
  29. package/packages/daemon/dist/tui/mirror/ui/pane-interaction-presentation.js +30 -2
  30. package/packages/daemon/dist/tui/mirror/ui/pane-interaction.jsx +1 -1
  31. package/packages/daemon/dist/tui/mirror/workspace/application-command-description.js +6 -0
  32. package/packages/daemon/dist/tui/mirror/workspace/terminal-pane-header.jsx +4 -2
  33. package/packages/daemon/src/automation.ts +28 -2
  34. package/packages/daemon/src/command-center/automation.ts +16 -1
  35. package/packages/daemon/src/command-center/discovery.ts +13 -2
  36. package/packages/daemon/src/command-center/resources/agent-graph-overlay.ts +2 -1
  37. package/packages/daemon/src/command-center/resources/application-shell.ts +21 -18
  38. package/packages/daemon/src/command-center/resources/fleet-catalog.ts +9 -3
  39. package/packages/daemon/src/command-center/resources/fleet-resource-route.ts +5 -3
  40. package/packages/daemon/src/command-center/server.ts +1 -1
  41. package/packages/daemon/src/lib/daemon-embed.ts +29 -4
  42. package/packages/daemon/src/mcp.ts +16 -4
  43. package/packages/daemon/src/terminal/attachments/agent-status-probe.ts +17 -0
  44. package/packages/daemon/src/terminal/attachments/claude-team-names.ts +166 -0
  45. package/packages/daemon/src/terminal/attachments/native-runtime.ts +2 -0
  46. package/packages/daemon/src/terminal/mirror/session-channel.ts +1 -0
  47. package/packages/daemon/src/terminal/mirror/trusted-inventory.ts +1 -0
  48. package/packages/daemon/src/terminal/protocol/pane-display-name.ts +51 -13
  49. package/packages/daemon/src/terminal/protocol/session-descriptor-discovery.ts +4 -4
  50. package/packages/daemon/src/tui/mirror/runtime/application-home-agents-owner.ts +19 -2
  51. package/packages/daemon/src/tui/mirror/runtime/application-home-experience.ts +1 -0
  52. package/packages/daemon/src/tui/mirror/runtime/application-new-agent-dialog.tsx +97 -0
  53. package/packages/daemon/src/tui/mirror/runtime/application-new-agent-owner.ts +89 -0
  54. package/packages/daemon/src/tui/mirror/runtime/application-palette-command-owner.ts +6 -0
  55. package/packages/daemon/src/tui/mirror/runtime/application-palette-input.ts +1 -0
  56. package/packages/daemon/src/tui/mirror/runtime/application-pane-activity-owner.ts +9 -3
  57. package/packages/daemon/src/tui/mirror/runtime/application-root-v2.tsx +5 -4
  58. package/packages/daemon/src/tui/mirror/runtime/application-shell-view.tsx +30 -1
  59. package/packages/daemon/src/tui/mirror/runtime/application-terminal-interaction-controller.ts +27 -0
  60. package/packages/daemon/src/tui/mirror/runtime/application-terminal-workspace-policy.ts +10 -5
  61. package/packages/daemon/src/tui/mirror/runtime/application-terminal-workspace.tsx +3 -0
  62. package/packages/daemon/src/tui/mirror/ui/pane-interaction-presentation.ts +35 -2
  63. package/packages/daemon/src/tui/mirror/ui/pane-interaction.tsx +1 -1
  64. package/packages/daemon/src/tui/mirror/workspace/application-command-description.ts +7 -0
  65. package/packages/daemon/src/tui/mirror/workspace/terminal-pane-header.tsx +8 -2
package/bin/cli.js CHANGED
@@ -9845,6 +9845,8 @@ var init_automation_operations = __esm({
9845
9845
  ))();
9846
9846
  AutomationPanesResponseSchemaZ = /* @__PURE__ */ (() => z73.object({
9847
9847
  version: z73.literal(1),
9848
+ // Resolved by the daemon from the invoking pane credential, never a title.
9849
+ source: AutomationPaneEndpointSchemaZ.nullable().optional(),
9848
9850
  panes: z73.array(
9849
9851
  z73.object({
9850
9852
  endpoint: AutomationPaneEndpointSchemaZ,
@@ -11906,7 +11908,7 @@ var require_package = __commonJS({
11906
11908
  "package.json"(exports, module) {
11907
11909
  module.exports = {
11908
11910
  name: "tmux-ide",
11909
- version: "2.9.0-beta.46",
11911
+ version: "2.9.0-beta.48",
11910
11912
  description: "A visual, agent-aware IDE for any tmux session, with optional workspace presets",
11911
11913
  type: "module",
11912
11914
  bin: {
@@ -11970,7 +11972,7 @@ var require_package = __commonJS({
11970
11972
  postinstall: "node scripts/postinstall.js",
11971
11973
  docs: "turbo run dev --filter=@tmux-ide/docs",
11972
11974
  "demo:tui": "bun --preload @opentui/solid/preload docs/scripts/render-tui-demo.tsx",
11973
- "test:tui-renderer": "bun test --preload @opentui/solid/preload --preload ./packages/daemon/test-support/opentui-renderer-preload.ts ./packages/daemon/src/tui/mirror/automatic-contrast-renderer.test.tsx ./packages/daemon/src/tui/mirror/pane-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/native-grid-projection-renderer.test.tsx ./packages/daemon/src/tui/mirror/widget-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/missions-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/recipes-gallery-renderer.test.tsx ./packages/daemon/src/tui/mirror/shell-chrome-renderer.test.tsx ./packages/daemon/src/tui/mirror/sidebar-renderer.test.tsx ./packages/daemon/src/tui/mirror/home-files-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/changes-terminal-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/activity-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/features/files/session-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-terminal-workspace-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-shell-view-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-root-error-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-backpressure-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-demand-cadence-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/files-optional-feature-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/changes-optional-feature-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/missions-activity-optional-feature-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/dialogs-optional-feature-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/optional-feature-registry-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/palette-optional-feature-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/pane-scoped-terminal-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/features/rich-preview/feature.test.ts ./packages/daemon/src/tui/mirror/runtime/rich-preview-optional-feature-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/application-shell-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/pane-frame-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/terminal-pane-chrome-view.test.tsx ./packages/daemon/src/tui/mirror/workspace/terminal-window-strip-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/workbench-shell-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/workbench-dock-dual-host-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/agent-terminal-canvas-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/command-palette-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/opentui-insertion-stability-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-shell-home-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/terminal-pane-header-polish-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-home-agent-roster-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-home-agent-flow-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/guided-tour-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-shell-sidebar-catalog-renderer.test.tsx ./packages/daemon/src/tui/mirror/ui/ui-renderer.test.tsx ./packages/daemon/src/tui/mirror/ui/pane-interaction-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-machine-sidebar-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-add-machine-dialog-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-fleet-switcher-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-palette-preview-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-fleet-palette-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-fleet-session-actions-renderer.test.tsx",
11975
+ "test:tui-renderer": "bun test --preload @opentui/solid/preload --preload ./packages/daemon/test-support/opentui-renderer-preload.ts ./packages/daemon/src/tui/mirror/automatic-contrast-renderer.test.tsx ./packages/daemon/src/tui/mirror/pane-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/native-grid-projection-renderer.test.tsx ./packages/daemon/src/tui/mirror/widget-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/missions-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/recipes-gallery-renderer.test.tsx ./packages/daemon/src/tui/mirror/shell-chrome-renderer.test.tsx ./packages/daemon/src/tui/mirror/sidebar-renderer.test.tsx ./packages/daemon/src/tui/mirror/home-files-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/changes-terminal-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/activity-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/features/files/session-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-terminal-workspace-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-shell-view-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-root-error-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-backpressure-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-demand-cadence-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/files-optional-feature-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/changes-optional-feature-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/missions-activity-optional-feature-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/dialogs-optional-feature-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/optional-feature-registry-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/palette-optional-feature-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/pane-scoped-terminal-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/features/rich-preview/feature.test.ts ./packages/daemon/src/tui/mirror/runtime/rich-preview-optional-feature-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/application-shell-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/pane-frame-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/terminal-pane-chrome-view.test.tsx ./packages/daemon/src/tui/mirror/workspace/terminal-window-strip-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/workbench-shell-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/workbench-dock-dual-host-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/agent-terminal-canvas-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/command-palette-surface-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/opentui-insertion-stability-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-shell-home-renderer.test.tsx ./packages/daemon/src/tui/mirror/workspace/terminal-pane-header-polish-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-home-agent-roster-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-home-agent-flow-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/guided-tour-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-shell-sidebar-catalog-renderer.test.tsx ./packages/daemon/src/tui/mirror/ui/ui-renderer.test.tsx ./packages/daemon/src/tui/mirror/ui/pane-interaction-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-machine-sidebar-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-add-machine-dialog-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-new-agent-dialog-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-fleet-switcher-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-palette-preview-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-fleet-palette-renderer.test.tsx ./packages/daemon/src/tui/mirror/runtime/application-fleet-session-actions-renderer.test.tsx",
11974
11976
  "test:tui-smoke": "bun scripts/smoke-tui-missions.mjs",
11975
11977
  "test:tui-live": "node scripts/tui-testdrive.mjs smoke",
11976
11978
  "test:tui-testdrive": "node --test scripts/lib/tui-testdrive-clipboard-hook.test.mjs scripts/lib/tui-testdrive-input.test.mjs",
@@ -12829,8 +12831,8 @@ function subtreeEntries(entries, rootPid, maxDepth = 6) {
12829
12831
  function describeSubtree(entries, rootPid, limit = 8) {
12830
12832
  const seen = [];
12831
12833
  for (const command3 of subtreeCommands(entries, rootPid)) {
12832
- for (const token of commandTokens(command3)) {
12833
- if (!seen.includes(token)) seen.push(token);
12834
+ for (const token2 of commandTokens(command3)) {
12835
+ if (!seen.includes(token2)) seen.push(token2);
12834
12836
  if (seen.length >= limit) return seen;
12835
12837
  }
12836
12838
  }
@@ -12886,11 +12888,11 @@ function resolveAgentCommand(paneCmd, panePid, table2, opts = {}) {
12886
12888
  if (fast) return { manifest: fast, matchedCommand: paneCmd, source: "fast" };
12887
12889
  let best;
12888
12890
  for (const command3 of subtreeCommands(table2, panePid)) {
12889
- for (const token of commandTokens(command3)) {
12890
- const hit = pickManifest(token, manifests);
12891
+ for (const token2 of commandTokens(command3)) {
12892
+ const hit = pickManifest(token2, manifests);
12891
12893
  if (!hit) continue;
12892
12894
  const rank = manifests.indexOf(hit);
12893
- if (!best || rank < best.rank) best = { manifest: hit, matchedCommand: token, rank };
12895
+ if (!best || rank < best.rank) best = { manifest: hit, matchedCommand: token2, rank };
12894
12896
  if (best.rank === 0)
12895
12897
  return { manifest: best.manifest, matchedCommand: best.matchedCommand, source: "tree" };
12896
12898
  }
@@ -14358,7 +14360,7 @@ function agentPidsInSubtree(table2, panePid, bins) {
14358
14360
  const wanted = new Set(bins);
14359
14361
  const pids = [];
14360
14362
  for (const entry of subtreeEntries(table2, panePid)) {
14361
- if (commandTokens(entry.command).some((token) => wanted.has(token))) pids.push(entry.pid);
14363
+ if (commandTokens(entry.command).some((token2) => wanted.has(token2))) pids.push(entry.pid);
14362
14364
  }
14363
14365
  return pids;
14364
14366
  }
@@ -14706,14 +14708,14 @@ __export(cheatsheet_exports, {
14706
14708
  cheatsheetPopupCommand: () => cheatsheetPopupCommand,
14707
14709
  cheatsheetUnbindCommand: () => cheatsheetUnbindCommand
14708
14710
  });
14709
- function tokenCode(token) {
14710
- const m = /^colou?r(\d+)$/.exec(token);
14711
+ function tokenCode(token2) {
14712
+ const m = /^colou?r(\d+)$/.exec(token2);
14711
14713
  if (!m) return null;
14712
14714
  const n = Number(m[1]);
14713
14715
  return Number.isInteger(n) && n >= 0 && n <= 255 ? n : null;
14714
14716
  }
14715
- function legendMark(token, glyph) {
14716
- const code2 = tokenCode(token);
14717
+ function legendMark(token2, glyph) {
14718
+ const code2 = tokenCode(token2);
14717
14719
  return code2 === null ? dim(glyph) : color(code2, glyph);
14718
14720
  }
14719
14721
  function renderKey(tmuxKey) {
@@ -19439,13 +19441,16 @@ var init_workspace_registry = __esm({
19439
19441
  // packages/daemon/src/terminal/protocol/pane-display-name.ts
19440
19442
  function boundedName(value) {
19441
19443
  const name = value?.trim() ?? "";
19442
- return name.length > 0 && name.length <= 80 && !/[\0\r\n\t]/u.test(name) ? name : null;
19444
+ return name.length > 0 && name.length <= 80 && [...name].every((c) => {
19445
+ const code2 = c.codePointAt(0);
19446
+ return code2 > 31 && (code2 < 127 || code2 > 159);
19447
+ }) ? name : null;
19443
19448
  }
19444
19449
  function commandBasename(value) {
19445
19450
  const command3 = boundedName(value);
19446
19451
  if (!command3) return null;
19447
- const basename20 = command3.split("/").at(-1)?.trim() ?? "";
19448
- return basename20.length > 0 ? basename20 : null;
19452
+ const basename21 = command3.split("/").at(-1)?.trim() ?? "";
19453
+ return basename21.length > 0 ? basename21 : null;
19449
19454
  }
19450
19455
  function stableHash(value) {
19451
19456
  let hash = 2166136261;
@@ -19460,13 +19465,17 @@ function memorablePaneName(seed) {
19460
19465
  const second = stableHash(`${seed}:noun`);
19461
19466
  return `${ADJECTIVES[first % ADJECTIVES.length]}-${NOUNS[second % NOUNS.length]}`;
19462
19467
  }
19463
- function meaningfulTitle(value, currentCommand, hostName) {
19468
+ function meaningfulPaneTitle(value, currentCommand, hostName) {
19464
19469
  const title = boundedName(value);
19465
19470
  if (!title || GENERIC_TITLES.has(title.toLowerCase())) return null;
19471
+ if (["claude", "claude code", "codex", "node", "bun", currentCommand?.toLowerCase()].includes(
19472
+ title.toLowerCase()
19473
+ ))
19474
+ return null;
19466
19475
  if (title.startsWith("/") || title.startsWith("~") || title.includes("@")) return null;
19467
- if (currentCommand && GENERIC_SHELLS.has(currentCommand.toLowerCase()) && (/^[a-z0-9][a-z0-9.-]*\.[a-z0-9-]{2,}$/iu.test(title) || hostName && [hostName, hostName.split(".")[0]].some(
19476
+ if (/^[a-z0-9][a-z0-9.-]*\.[a-z0-9-]{2,}$/iu.test(title) || hostName && [hostName, hostName.split(".")[0]].some(
19468
19477
  (host) => host?.toLowerCase() === title.toLowerCase()
19469
- )))
19478
+ ))
19470
19479
  return null;
19471
19480
  return title;
19472
19481
  }
@@ -19474,18 +19483,36 @@ function resolvePaneDisplayName(input) {
19474
19483
  const configuredName = boundedName(input.configuredName);
19475
19484
  const configuredSource = input.configuredNameSource?.trim().toLowerCase() ?? "";
19476
19485
  const generatedName = memorablePaneName(input.semanticPaneId);
19477
- const legacyConfiguredName = configuredName && configuredName !== generatedName && !GENERIC_TITLES.has(configuredName.toLowerCase()) ? configuredName : null;
19486
+ const automaticHarnessName = [
19487
+ "claude",
19488
+ "claude code",
19489
+ "codex",
19490
+ "node",
19491
+ "bun",
19492
+ input.currentCommand?.toLowerCase()
19493
+ ].includes(configuredName?.toLowerCase() ?? "");
19494
+ const legacyConfiguredName = configuredName && configuredName !== generatedName && !automaticHarnessName && !GENERIC_TITLES.has(configuredName.toLowerCase()) ? configuredName : null;
19478
19495
  if (configuredName && configuredSource === "manual")
19479
19496
  return { name: configuredName, source: "manual" };
19480
- if (configuredName && (configuredSource === "agent" || input.paneType === "agent"))
19497
+ const teamName = boundedName(input.teamMemberName);
19498
+ if (teamName) return { name: teamName, source: "agent" };
19499
+ const reportedName = boundedName(input.agentDisplayName);
19500
+ if (reportedName && !["claude", "claude code", "codex", input.currentCommand?.toLowerCase()].includes(
19501
+ reportedName.toLowerCase()
19502
+ ))
19503
+ return { name: reportedName, source: "agent" };
19504
+ if (configuredName && !automaticHarnessName && (configuredSource === "agent" || input.paneType === "agent"))
19481
19505
  return { name: configuredName, source: "agent" };
19482
19506
  if (legacyConfiguredName && configuredSource !== "generated")
19483
19507
  return { name: legacyConfiguredName, source: "manual" };
19484
19508
  const command3 = commandBasename(input.currentCommand);
19509
+ const title = meaningfulPaneTitle(input.title, command3, input.hostName);
19510
+ if (title) return { name: title, source: "title" };
19511
+ if (reportedName) return { name: reportedName, source: "agent" };
19512
+ if (configuredName && configuredSource === "agent")
19513
+ return { name: configuredName, source: "agent" };
19485
19514
  if (command3 && !GENERIC_SHELLS.has(command3.toLowerCase()))
19486
19515
  return { name: command3, source: "process" };
19487
- const title = meaningfulTitle(input.title, command3, input.hostName);
19488
- if (title) return { name: title, source: "title" };
19489
19516
  return {
19490
19517
  name: configuredName && configuredSource === "generated" ? configuredName : generatedName,
19491
19518
  source: "generated"
@@ -20393,10 +20420,10 @@ var init_project_runtime_repository = __esm({
20393
20420
  assertLockDirectory(this.runtimeRoot);
20394
20421
  this.io.mkdir(lockDirectory);
20395
20422
  assertLockDirectory(lockDirectory);
20396
- const token = randomUUID5();
20423
+ const token2 = randomUUID5();
20397
20424
  const owner = `${JSON.stringify({
20398
20425
  version: 1,
20399
- token,
20426
+ token: token2,
20400
20427
  processInstanceId: PROJECT_RUNTIME_PROCESS_INSTANCE_ID,
20401
20428
  pid: process.pid,
20402
20429
  createdAtMs: Date.now()
@@ -20450,10 +20477,10 @@ var init_project_runtime_repository = __esm({
20450
20477
  const currentOwner = readFileSync21(lockPath, "utf-8");
20451
20478
  const afterRead = lstatSync8(lockPath);
20452
20479
  const parsed = JSON.parse(currentOwner);
20453
- if (afterRead.dev !== before.dev || afterRead.ino !== before.ino || parsed.token !== token || parsed.processInstanceId !== PROJECT_RUNTIME_PROCESS_INSTANCE_ID) {
20480
+ if (afterRead.dev !== before.dev || afterRead.ino !== before.ino || parsed.token !== token2 || parsed.processInstanceId !== PROJECT_RUNTIME_PROCESS_INSTANCE_ID) {
20454
20481
  throw new Error("writer lock ownership changed before release");
20455
20482
  }
20456
- const releasedPath = `${lockPath}.released-${token}`;
20483
+ const releasedPath = `${lockPath}.released-${token2}`;
20457
20484
  renameSync11(lockPath, releasedPath);
20458
20485
  const moved = lstatSync8(releasedPath);
20459
20486
  if (moved.dev !== before.dev || moved.ino !== before.ino) {
@@ -23130,8 +23157,8 @@ var init_pane_source_credentials = __esm({
23130
23157
  this.#tmux = tmux7;
23131
23158
  }
23132
23159
  rotateSession(session) {
23133
- for (const [token, grant] of this.#grants) {
23134
- if (grant.session === session) this.#grants.delete(token);
23160
+ for (const [token2, grant] of this.#grants) {
23161
+ if (grant.session === session) this.#grants.delete(token2);
23135
23162
  }
23136
23163
  for (const key2 of this.#tokensByPane.keys()) {
23137
23164
  if (key2.startsWith(`${session}\0`)) this.#tokensByPane.delete(key2);
@@ -23159,22 +23186,22 @@ var init_pane_source_credentials = __esm({
23159
23186
  const existing = existingToken ? this.#grants.get(existingToken) : void 0;
23160
23187
  if (existing?.semanticPaneId === semanticPaneId3 && installedToken === existingToken) continue;
23161
23188
  if (existingToken) this.#grants.delete(existingToken);
23162
- const token = randomBytes2(32).toString("base64url");
23189
+ const token2 = randomBytes2(32).toString("base64url");
23163
23190
  this.#tmux.run([
23164
23191
  "set-option",
23165
23192
  "-p",
23166
23193
  "-t",
23167
23194
  runtimePaneId,
23168
23195
  PANE_SOURCE_CREDENTIAL_OPTION,
23169
- token
23196
+ token2
23170
23197
  ]);
23171
- this.#tokensByPane.set(paneKey, token);
23172
- this.#grants.set(token, { bindingId: randomUUID7(), session, runtimePaneId, semanticPaneId: semanticPaneId3 });
23198
+ this.#tokensByPane.set(paneKey, token2);
23199
+ this.#grants.set(token2, { bindingId: randomUUID7(), session, runtimePaneId, semanticPaneId: semanticPaneId3 });
23173
23200
  }
23174
- for (const [paneKey, token] of this.#tokensByPane) {
23201
+ for (const [paneKey, token2] of this.#tokensByPane) {
23175
23202
  if (!paneKey.startsWith(`${session}\0`) || live.has(paneKey)) continue;
23176
23203
  this.#tokensByPane.delete(paneKey);
23177
- this.#grants.delete(token);
23204
+ this.#grants.delete(token2);
23178
23205
  }
23179
23206
  }
23180
23207
  /**
@@ -23218,9 +23245,9 @@ var init_pane_source_credentials = __esm({
23218
23245
  const existing = existingToken ? this.#grants.get(existingToken) : void 0;
23219
23246
  if (existing?.semanticPaneId === semanticPaneId3 && installedToken === existingToken)
23220
23247
  continue;
23221
- const token = randomBytes2(32).toString("base64url");
23248
+ const token2 = randomBytes2(32).toString("base64url");
23222
23249
  await runAsync(
23223
- ["set-option", "-p", "-t", runtimePaneId, PANE_SOURCE_CREDENTIAL_OPTION, token],
23250
+ ["set-option", "-p", "-t", runtimePaneId, PANE_SOURCE_CREDENTIAL_OPTION, token2],
23224
23251
  signal
23225
23252
  );
23226
23253
  signal?.throwIfAborted();
@@ -23229,8 +23256,8 @@ var init_pane_source_credentials = __esm({
23229
23256
  break;
23230
23257
  }
23231
23258
  if (existingToken) this.#grants.delete(existingToken);
23232
- this.#tokensByPane.set(paneKey, token);
23233
- this.#grants.set(token, {
23259
+ this.#tokensByPane.set(paneKey, token2);
23260
+ this.#grants.set(token2, {
23234
23261
  bindingId: randomUUID7(),
23235
23262
  session,
23236
23263
  runtimePaneId,
@@ -23238,10 +23265,10 @@ var init_pane_source_credentials = __esm({
23238
23265
  });
23239
23266
  }
23240
23267
  if (raced) continue;
23241
- for (const [paneKey, token] of this.#tokensByPane) {
23268
+ for (const [paneKey, token2] of this.#tokensByPane) {
23242
23269
  if (!paneKey.startsWith(`${session}\0`) || live.has(paneKey)) continue;
23243
23270
  this.#tokensByPane.delete(paneKey);
23244
- this.#grants.delete(token);
23271
+ this.#grants.delete(token2);
23245
23272
  }
23246
23273
  return;
23247
23274
  }
@@ -24684,6 +24711,118 @@ var init_development_log = __esm({
24684
24711
  }
24685
24712
  });
24686
24713
 
24714
+ // packages/daemon/src/terminal/attachments/claude-team-names.ts
24715
+ import { open, readdir } from "node:fs/promises";
24716
+ import { join as join31, basename as basename10 } from "node:path";
24717
+ function parseClaudeTeamMembers(value, directory) {
24718
+ if (!value || typeof value !== "object") return [];
24719
+ const config2 = value;
24720
+ if (!token(directory) || config2.name !== directory || !Array.isArray(config2.members) || config2.members.length > 128)
24721
+ return [];
24722
+ return config2.members.flatMap((value2) => {
24723
+ if (!value2 || typeof value2 !== "object") return [];
24724
+ const m = value2;
24725
+ if (!token(m.name) || m.name.length > 80 || !token(m.agentId) || m.backendType !== "tmux" || typeof m.tmuxPaneId !== "string" || !/^%\d+$/u.test(m.tmuxPaneId))
24726
+ return [];
24727
+ return [{ team: directory, name: m.name, agentId: m.agentId, paneId: m.tmuxPaneId }];
24728
+ });
24729
+ }
24730
+ function matchesProcess(command3, member) {
24731
+ const args = command3.trim().split(/\s+/u);
24732
+ const executable = args.shift() ?? "";
24733
+ if (basename10(executable) !== "claude" && !/\/claude\/versions\/\d[\w.-]*$/u.test(executable))
24734
+ return false;
24735
+ for (const [flag, expected] of [
24736
+ ["--team-name", member.team],
24737
+ ["--agent-id", member.agentId],
24738
+ ["--agent-name", member.name]
24739
+ ]) {
24740
+ const positions = args.flatMap(
24741
+ (arg, index) => arg === flag || arg.startsWith(`${flag}=`) ? [index] : []
24742
+ );
24743
+ if (positions.length !== 1) return false;
24744
+ const i = positions[0];
24745
+ if ((args[i] === flag ? args[i + 1] : args[i].slice(flag.length + 1)) !== expected)
24746
+ return false;
24747
+ }
24748
+ return true;
24749
+ }
24750
+ function resolveClaudeTeamName(pane, members, processes) {
24751
+ const subtree = subtreeEntries(processes, pane.pid);
24752
+ const matches = members.filter(
24753
+ (m) => m.paneId === pane.runtimePaneId && subtree.some((p) => matchesProcess(p.command, m))
24754
+ );
24755
+ return matches.length === 1 ? matches[0].name : null;
24756
+ }
24757
+ async function readMembers(directory) {
24758
+ try {
24759
+ const entries = await readdir(directory, { withFileTypes: true });
24760
+ if (entries.length > 128) return [];
24761
+ const members = [];
24762
+ for (const entry of entries) {
24763
+ if (!entry.isDirectory() || !token(entry.name)) continue;
24764
+ try {
24765
+ const file = await open(join31(directory, entry.name, "config.json"), "r");
24766
+ try {
24767
+ if (!(await file.stat()).isFile()) continue;
24768
+ const bytes = Buffer.alloc(256 * 1024 + 1);
24769
+ const { bytesRead } = await file.read(bytes, 0, bytes.length, 0);
24770
+ if (bytesRead > 256 * 1024) continue;
24771
+ members.push(
24772
+ ...parseClaudeTeamMembers(
24773
+ JSON.parse(bytes.subarray(0, bytesRead).toString("utf8")),
24774
+ entry.name
24775
+ )
24776
+ );
24777
+ } finally {
24778
+ await file.close();
24779
+ }
24780
+ } catch {
24781
+ }
24782
+ }
24783
+ return members;
24784
+ } catch {
24785
+ return [];
24786
+ }
24787
+ }
24788
+ function createClaudeTeamNameReader(directory, deps2 = {}) {
24789
+ const now = deps2.now ?? Date.now;
24790
+ let snapshot2 = null;
24791
+ let pending = null;
24792
+ return async (panes) => {
24793
+ if (!panes.length) return /* @__PURE__ */ new Map();
24794
+ if (!snapshot2 || now() - snapshot2.at >= 2e3) {
24795
+ pending ??= (async () => {
24796
+ try {
24797
+ const members = await (deps2.readMembers?.() ?? readMembers(directory));
24798
+ const processes = members.length ? await (deps2.readProcesses?.() ?? readProcessTableAsync()) : [];
24799
+ snapshot2 = { at: now(), members, processes };
24800
+ } catch {
24801
+ snapshot2 = { at: now(), members: [], processes: [] };
24802
+ }
24803
+ })().finally(() => {
24804
+ pending = null;
24805
+ });
24806
+ await pending;
24807
+ }
24808
+ const current = snapshot2;
24809
+ const names = /* @__PURE__ */ new Map();
24810
+ for (const pane of panes) {
24811
+ const name = resolveClaudeTeamName(pane, current.members, current.processes);
24812
+ if (name) names.set(pane.runtimePaneId, name);
24813
+ }
24814
+ return names;
24815
+ };
24816
+ }
24817
+ var token;
24818
+ var init_claude_team_names = __esm({
24819
+ "packages/daemon/src/terminal/attachments/claude-team-names.ts"() {
24820
+ "use strict";
24821
+ init_process_tree();
24822
+ token = (value) => typeof value === "string" && /^[a-zA-Z0-9_.@-]{1,160}$/u.test(value) && value !== "." && value !== "..";
24823
+ }
24824
+ });
24825
+
24687
24826
  // packages/daemon/src/lib/pane-source-discovery.ts
24688
24827
  var PaneSourceDiscovery;
24689
24828
  var init_pane_source_discovery = __esm({
@@ -25907,15 +26046,15 @@ var init_owned_native_interaction_bindings = __esm({
25907
26046
  return null;
25908
26047
  if ([...this.#connections.values()].some((c) => c.identity.connectionId === identity2.connectionId))
25909
26048
  return null;
25910
- const token = Object.freeze({ bindingId: randomUUID13() });
25911
- this.#connections.set(token, {
25912
- token,
26049
+ const token2 = Object.freeze({ bindingId: randomUUID13() });
26050
+ this.#connections.set(token2, {
26051
+ token: token2,
25913
26052
  identity: freeze(identity2),
25914
26053
  role,
25915
26054
  closedAt: null,
25916
26055
  oneShotCapture: false
25917
26056
  });
25918
- return token;
26057
+ return token2;
25919
26058
  }
25920
26059
  admit(raw) {
25921
26060
  return this.#admit(raw, false);
@@ -25925,19 +26064,19 @@ var init_owned_native_interaction_bindings = __esm({
25925
26064
  throw new TypeError("Invalid one-shot capture admission");
25926
26065
  return this.#admit({ ...raw, role: "viewer", commands: ["capture-pane"], source: null }, true);
25927
26066
  }
25928
- acknowledgeOneShotViewerCapture(token, rawIdentity, rawAck) {
26067
+ acknowledgeOneShotViewerCapture(token2, rawIdentity, rawAck) {
25929
26068
  const released = [...this.expire()];
25930
- const permit = this.#permits.get(token.operationId);
25931
- if (!permit || permit.token !== token || !permit.oneShotCapture || permit.acknowledgement)
26069
+ const permit = this.#permits.get(token2.operationId);
26070
+ if (!permit || permit.token !== token2 || !permit.oneShotCapture || permit.acknowledgement)
25932
26071
  return { acknowledged: false, decisions: released };
25933
26072
  const identity2 = NativeJournalIdentitySchemaZ.parse(rawIdentity), ack = NativeOperationIdentitySchemaZ.parse(rawAck);
25934
- if (identity2.serverEpoch !== this.#serverEpoch || ack.serverEpoch !== identity2.serverEpoch || ack.connectionId !== identity2.connectionId || ack.operationId !== token.operationId)
26073
+ if (identity2.serverEpoch !== this.#serverEpoch || ack.serverEpoch !== identity2.serverEpoch || ack.connectionId !== identity2.connectionId || ack.operationId !== token2.operationId)
25935
26074
  return { acknowledged: false, decisions: released };
25936
26075
  const connectionToken = this.registerConnection(identity2, "viewer");
25937
26076
  if (!connectionToken) return { acknowledged: false, decisions: released };
25938
26077
  this.#connections.get(connectionToken).oneShotCapture = true;
25939
26078
  try {
25940
- released.push(...this.acknowledge(token, connectionToken, ack));
26079
+ released.push(...this.acknowledge(token2, connectionToken, ack));
25941
26080
  } finally {
25942
26081
  released.push(...this.closeConnection(connectionToken));
25943
26082
  }
@@ -25984,7 +26123,7 @@ var init_owned_native_interaction_bindings = __esm({
25984
26123
  if (raw.role === "viewer" && !connection && !oneShotCapture) return null;
25985
26124
  if (this.#disposed || this.#permits.has(id2) || this.#permits.size >= this.#maxPermits)
25986
26125
  return null;
25987
- const token = Object.freeze({ operationId: id2 });
26126
+ const token2 = Object.freeze({ operationId: id2 });
25988
26127
  const request3 = freeze({
25989
26128
  ...structuredClone({ ...raw, connection: void 0 }),
25990
26129
  target,
@@ -25992,7 +26131,7 @@ var init_owned_native_interaction_bindings = __esm({
25992
26131
  });
25993
26132
  this.#permits.set(id2, {
25994
26133
  oneShotCapture,
25995
- token,
26134
+ token: token2,
25996
26135
  request: request3,
25997
26136
  expiresAt: this.#now() + this.#permitMs,
25998
26137
  completed: /* @__PURE__ */ new Map(),
@@ -26000,25 +26139,25 @@ var init_owned_native_interaction_bindings = __esm({
26000
26139
  acknowledgement: null,
26001
26140
  connection: connection ?? null
26002
26141
  });
26003
- return token;
26142
+ return token2;
26004
26143
  }
26005
26144
  /** Only a proven no-write refusal may call this. Exact tokens cannot cancel another attempt. */
26006
- cancelUndispatchedOperation(token) {
26007
- const permit = this.#permits.get(token.operationId);
26008
- if (!permit || permit.token !== token || permit.acknowledgement !== null) return [];
26145
+ cancelUndispatchedOperation(token2) {
26146
+ const permit = this.#permits.get(token2.operationId);
26147
+ if (!permit || permit.token !== token2 || permit.acknowledgement !== null) return [];
26009
26148
  return this.#retire((candidate) => candidate === permit);
26010
26149
  }
26011
26150
  /** Ambiguous dispatched work stays unknown; a verified acknowledgement remains valid. */
26012
- abandonUnacknowledgedOperation(token) {
26013
- const permit = this.#permits.get(token.operationId);
26014
- if (!permit || permit.token !== token || permit.acknowledgement !== null) return [];
26151
+ abandonUnacknowledgedOperation(token2) {
26152
+ const permit = this.#permits.get(token2.operationId);
26153
+ if (!permit || permit.token !== token2 || permit.acknowledgement !== null) return [];
26015
26154
  return this.#retire((candidate) => candidate === permit);
26016
26155
  }
26017
- acknowledge(token, connectionToken, raw) {
26156
+ acknowledge(token2, connectionToken, raw) {
26018
26157
  const ack = NativeOperationIdentitySchemaZ.parse(raw);
26019
26158
  const released = [...this.expire()];
26020
- const permit = this.#permits.get(token.operationId), connection = this.#connections.get(connectionToken);
26021
- if (this.#disposed || !permit || permit.token !== token || !connection || connection.role !== permit.request.role || connection.closedAt !== null && permit.acknowledgement === null || ack.operationId !== token.operationId || ack.serverEpoch !== this.#serverEpoch || ack.connectionId !== connection.identity.connectionId || permit.connection !== null && permit.connection !== connection)
26159
+ const permit = this.#permits.get(token2.operationId), connection = this.#connections.get(connectionToken);
26160
+ if (this.#disposed || !permit || permit.token !== token2 || !connection || connection.role !== permit.request.role || connection.closedAt !== null && permit.acknowledgement === null || ack.operationId !== token2.operationId || ack.serverEpoch !== this.#serverEpoch || ack.connectionId !== connection.identity.connectionId || permit.connection !== null && permit.connection !== connection)
26022
26161
  return released;
26023
26162
  if (permit.acknowledgement && !same3(permit.acknowledgement, ack)) return released;
26024
26163
  permit.connection = connection;
@@ -26075,26 +26214,26 @@ var init_owned_native_interaction_bindings = __esm({
26075
26214
  released.push(this.#unknown(pending.item, "pending-expired"));
26076
26215
  }
26077
26216
  for (const [id2, permit] of this.#permits) if (now >= permit.expiresAt) this.#permits.delete(id2);
26078
- for (const [token, connection] of this.#connections) {
26217
+ for (const [token2, connection] of this.#connections) {
26079
26218
  if (connection.closedAt !== null && (now >= connection.closedAt + this.#permitMs || ![...this.#permits.values()].some((permit) => permit.connection === connection)))
26080
- this.#connections.delete(token);
26219
+ this.#connections.delete(token2);
26081
26220
  }
26082
26221
  return released;
26083
26222
  }
26084
26223
  /** Authored helper exit preserves acknowledged proof until bounded permit expiry.
26085
26224
  * New admissions are denied; retained viewer closure retires immediately. */
26086
- closeConnection(token) {
26087
- const connection = this.#connections.get(token);
26225
+ closeConnection(token2) {
26226
+ const connection = this.#connections.get(token2);
26088
26227
  if (!connection) return [];
26089
26228
  if (connection.role === "viewer" && !connection.oneShotCapture)
26090
- return this.retireConnection(token);
26229
+ return this.retireConnection(token2);
26091
26230
  connection.closedAt ??= this.#now();
26092
26231
  return this.expire();
26093
26232
  }
26094
- retireConnection(token) {
26095
- const connection = this.#connections.get(token);
26233
+ retireConnection(token2) {
26234
+ const connection = this.#connections.get(token2);
26096
26235
  if (!connection) return [];
26097
- this.#connections.delete(token);
26236
+ this.#connections.delete(token2);
26098
26237
  return this.#retire((permit) => permit.connection === connection);
26099
26238
  }
26100
26239
  dispose() {
@@ -26152,9 +26291,9 @@ var init_owned_native_interaction_bindings = __esm({
26152
26291
  completions.push(proof);
26153
26292
  }
26154
26293
  }
26155
- for (const [token, connection] of this.#connections) {
26294
+ for (const [token2, connection] of this.#connections) {
26156
26295
  if (connection.closedAt !== null && ![...this.#permits.values()].some((permit) => permit.connection === connection))
26157
- this.#connections.delete(token);
26296
+ this.#connections.delete(token2);
26158
26297
  }
26159
26298
  for (const proof of completions) this.#onPlanComplete?.(proof);
26160
26299
  }
@@ -27305,6 +27444,265 @@ var init_live_session_identity = __esm({
27305
27444
  }
27306
27445
  });
27307
27446
 
27447
+ // packages/daemon/src/terminal/protocol/session-descriptor-discovery.ts
27448
+ function decodeTmuxArgument(value) {
27449
+ const encoded = value.length >= 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) ? value.slice(1, -1) : value;
27450
+ let decoded = "";
27451
+ for (let index = 0; index < encoded.length; index += 1) {
27452
+ const current = encoded[index];
27453
+ if (current !== "\\" || index + 1 >= encoded.length) {
27454
+ decoded += current;
27455
+ continue;
27456
+ }
27457
+ const escaped = encoded[++index];
27458
+ if (escaped === "e") decoded += "\x1B";
27459
+ else if (escaped === "n") decoded += "\n";
27460
+ else if (escaped === "r") decoded += "\r";
27461
+ else if (escaped === "t") decoded += " ";
27462
+ else if (/[0-7]/u.test(escaped)) {
27463
+ let octal = escaped;
27464
+ while (octal.length < 3 && /[0-7]/u.test(encoded[index + 1] ?? "")) {
27465
+ octal += encoded[++index];
27466
+ }
27467
+ decoded += String.fromCodePoint(Number.parseInt(octal, 8));
27468
+ } else if (escaped === "u") {
27469
+ const remaining = encoded.slice(index + 1);
27470
+ const unicode = remaining.match(/^(?:[0-9A-Fa-f]{8}|[0-9A-Fa-f]{4})/u)?.[0];
27471
+ if (unicode) {
27472
+ decoded += String.fromCodePoint(Number.parseInt(unicode, 16));
27473
+ index += unicode.length;
27474
+ } else {
27475
+ decoded += "u";
27476
+ }
27477
+ } else {
27478
+ decoded += escaped;
27479
+ }
27480
+ }
27481
+ return decoded;
27482
+ }
27483
+ function parseSessionPaneDescriptorReply(lines) {
27484
+ const descriptors = [];
27485
+ let malformedUtf8Records = 0;
27486
+ if (lines.length > 4096 || lines.reduce((bytes, line) => bytes + Buffer.byteLength(line, "latin1") + 1, 0) > 128 * 1024) {
27487
+ return { descriptors, malformedUtf8Records };
27488
+ }
27489
+ for (const line of lines) {
27490
+ const utf8Line = decodeControlReplyUtf8(line);
27491
+ if (utf8Line === null) {
27492
+ malformedUtf8Records += 1;
27493
+ continue;
27494
+ }
27495
+ const encoded = utf8Line.split(" ");
27496
+ if (encoded.length !== 21 && encoded.length !== 22) continue;
27497
+ const [
27498
+ runtimePaneId = "",
27499
+ semanticPaneId3 = "",
27500
+ role = "",
27501
+ type = "",
27502
+ currentCommand = "",
27503
+ cwd = "",
27504
+ windowIndexRaw = "",
27505
+ windowName = "",
27506
+ windowId = "",
27507
+ title = "",
27508
+ runtimeSessionId = "",
27509
+ paneIndexRaw = "",
27510
+ name = "",
27511
+ missionStamp = "",
27512
+ paneActiveRaw = "",
27513
+ windowActiveRaw = "",
27514
+ semanticWindowId = "",
27515
+ sessionName = "",
27516
+ windowPaneCountRaw = "",
27517
+ sessionWindowCountRaw = "",
27518
+ nativePaneBirthId = "",
27519
+ nameSource2 = ""
27520
+ ] = encoded.map(decodeTmuxArgument);
27521
+ if (!/^%(?:0|[1-9][0-9]*)$/u.test(runtimePaneId) || runtimePaneId.length > 32) continue;
27522
+ if (!/^\$(?:0|[1-9][0-9]*)$/u.test(runtimeSessionId) || runtimeSessionId.length > 32) continue;
27523
+ const parsedWindowIndex = Number(windowIndexRaw);
27524
+ const windowIndex = Number.isSafeInteger(parsedWindowIndex) && parsedWindowIndex >= 0 ? parsedWindowIndex : null;
27525
+ const paneIndex = Number(paneIndexRaw);
27526
+ const windowPaneCount = Number(windowPaneCountRaw);
27527
+ const sessionWindowCount = Number(sessionWindowCountRaw);
27528
+ if (!/^(?:0|[1-9][0-9]*)$/u.test(paneIndexRaw) || !Number.isSafeInteger(paneIndex)) continue;
27529
+ if (!/^[1-9][0-9]*$/u.test(windowPaneCountRaw) || !Number.isSafeInteger(windowPaneCount) || !/^[1-9][0-9]*$/u.test(sessionWindowCountRaw) || !Number.isSafeInteger(sessionWindowCount) || windowPaneCount < 1 || sessionWindowCount < 1)
27530
+ continue;
27531
+ if (!["0", "1"].includes(paneActiveRaw) || !["0", "1"].includes(windowActiveRaw)) continue;
27532
+ const bounded4 = (value, maximum) => value.length <= maximum && !/[\0\r\n\t]/u.test(value);
27533
+ if (!bounded4(semanticPaneId3, 256) || !bounded4(role, 256) || !bounded4(type, 256) || !bounded4(currentCommand, 512) || !bounded4(cwd, 4096) || !bounded4(title, 1024) || !bounded4(windowName, 1024) || !bounded4(name, 256) || !bounded4(missionStamp, 256) || !bounded4(semanticWindowId, 256) || !bounded4(sessionName, 160) || sessionName.length === 0 || windowId.length > 32) {
27534
+ continue;
27535
+ }
27536
+ descriptors.push({
27537
+ sessionName,
27538
+ runtimePaneId,
27539
+ runtimeSessionId,
27540
+ semanticPaneId: nonempty(semanticPaneId3),
27541
+ role: nonempty(role),
27542
+ type: nonempty(type),
27543
+ currentCommand: nonempty(currentCommand),
27544
+ cwd: nonempty(cwd),
27545
+ title: nonempty(title),
27546
+ windowIndex,
27547
+ windowName: nonempty(windowName),
27548
+ windowId: /^@(?:0|[1-9][0-9]*)$/u.test(windowId) ? windowId : null,
27549
+ semanticWindowId: nonempty(semanticWindowId),
27550
+ paneIndex,
27551
+ name: nonempty(name),
27552
+ nameSource: ["manual", "agent", "generated"].includes(nameSource2) ? nameSource2 : null,
27553
+ missionStamp: nonempty(missionStamp),
27554
+ nativePaneBirthId: nonempty(nativePaneBirthId),
27555
+ paneActive: paneActiveRaw === "1",
27556
+ windowActive: windowActiveRaw === "1",
27557
+ windowPaneCount,
27558
+ sessionWindowCount
27559
+ });
27560
+ }
27561
+ return { descriptors, malformedUtf8Records };
27562
+ }
27563
+ function nonempty(value) {
27564
+ return value.length > 0 ? value : null;
27565
+ }
27566
+ function decodeControlReplyUtf8(value) {
27567
+ try {
27568
+ return STRICT_UTF8_DECODER.decode(Buffer.from(value, "latin1"));
27569
+ } catch {
27570
+ return null;
27571
+ }
27572
+ }
27573
+ function positiveInteger(value, fallback) {
27574
+ return Number.isSafeInteger(value) && value > 0 ? value : fallback;
27575
+ }
27576
+ var SESSION_PANE_DESCRIPTOR_FORMAT, SessionDescriptorDiscovery, STRICT_UTF8_DECODER;
27577
+ var init_session_descriptor_discovery = __esm({
27578
+ "packages/daemon/src/terminal/protocol/session-descriptor-discovery.ts"() {
27579
+ "use strict";
27580
+ SESSION_PANE_DESCRIPTOR_FORMAT = [
27581
+ "#{pane_id}",
27582
+ "#{qa:@tmux_ide_pane_id}",
27583
+ "#{qa:@ide_role}",
27584
+ "#{qa:@ide_type}",
27585
+ "#{qa:pane_current_command}",
27586
+ "#{qa:pane_current_path}",
27587
+ "#{window_index}",
27588
+ "#{qa:window_name}",
27589
+ "#{window_id}",
27590
+ "#{qa:pane_title}",
27591
+ "#{session_id}",
27592
+ "#{pane_index}",
27593
+ "#{qa:@ide_name}",
27594
+ "#{qa:@tmux_ide_mission}",
27595
+ "#{pane_active}",
27596
+ "#{?window_active,1,0}",
27597
+ "#{qa:@tmux_ide_window_id}",
27598
+ "#{qa:session_name}",
27599
+ "#{window_panes}",
27600
+ "#{session_windows}",
27601
+ "#{pane_birth_id}",
27602
+ "#{qa:@tmux_ide_name_source}"
27603
+ ].join(" ");
27604
+ SessionDescriptorDiscovery = class {
27605
+ options;
27606
+ epoch = 0;
27607
+ cancelScheduled = null;
27608
+ disposed = false;
27609
+ constructor(options) {
27610
+ this.options = {
27611
+ ...options,
27612
+ maxAttempts: positiveInteger(options.maxAttempts, 3),
27613
+ baseDelayMs: positiveInteger(options.baseDelayMs, 50),
27614
+ schedule: options.schedule ?? ((callback, delayMs) => {
27615
+ const timer = setTimeout(callback, delayMs);
27616
+ return () => clearTimeout(timer);
27617
+ })
27618
+ };
27619
+ }
27620
+ discover(listedRuntimePaneIds) {
27621
+ if (this.disposed) return;
27622
+ this.invalidatePending();
27623
+ const epoch = this.epoch;
27624
+ this.attempt(epoch, new Set(listedRuntimePaneIds), 1);
27625
+ }
27626
+ invalidate() {
27627
+ if (this.disposed) return;
27628
+ this.invalidatePending();
27629
+ this.options.onStatus?.(null);
27630
+ }
27631
+ dispose() {
27632
+ if (this.disposed) return;
27633
+ this.invalidatePending();
27634
+ this.disposed = true;
27635
+ }
27636
+ invalidatePending() {
27637
+ this.epoch += 1;
27638
+ this.cancelScheduled?.();
27639
+ this.cancelScheduled = null;
27640
+ }
27641
+ attempt(epoch, listed, attempt) {
27642
+ void this.options.query().then((lines) => {
27643
+ if (!this.isCurrent(epoch)) return;
27644
+ const parsed = parseSessionPaneDescriptorReply(lines);
27645
+ const descriptorByRuntimePane = new Map(
27646
+ parsed.descriptors.filter((descriptor) => listed.has(descriptor.runtimePaneId)).map((descriptor) => [descriptor.runtimePaneId, descriptor])
27647
+ );
27648
+ const descriptors = [...descriptorByRuntimePane.values()];
27649
+ if (listed.size > 0 && descriptors.length === 0) {
27650
+ const malformedDetail = parsed.malformedUtf8Records > 0 ? `; ${parsed.malformedUtf8Records} malformed UTF-8 record${parsed.malformedUtf8Records === 1 ? " was" : "s were"} omitted` : "";
27651
+ throw new Error(
27652
+ `descriptor reply covered 0 of ${listed.size} live panes${malformedDetail}`
27653
+ );
27654
+ }
27655
+ if (descriptors.length !== listed.size || parsed.malformedUtf8Records > 0) {
27656
+ const malformedDetail = parsed.malformedUtf8Records > 0 ? `; omitted ${parsed.malformedUtf8Records} malformed UTF-8 record${parsed.malformedUtf8Records === 1 ? "" : "s"}` : "";
27657
+ this.options.onStatus?.({
27658
+ status: "partial",
27659
+ degraded: true,
27660
+ attempt,
27661
+ maxAttempts: this.options.maxAttempts,
27662
+ retryInMs: null,
27663
+ message: `Pane descriptor discovery published ${descriptors.length} of ${listed.size} live panes${malformedDetail}.`
27664
+ });
27665
+ } else {
27666
+ this.options.onStatus?.(null);
27667
+ }
27668
+ this.options.onDescriptors(descriptors, listed);
27669
+ }).catch((cause) => {
27670
+ if (!this.isCurrent(epoch)) return;
27671
+ const detail = cause instanceof Error ? cause.message : String(cause);
27672
+ if (attempt >= this.options.maxAttempts) {
27673
+ this.options.onStatus?.({
27674
+ status: "failed",
27675
+ degraded: true,
27676
+ attempt,
27677
+ maxAttempts: this.options.maxAttempts,
27678
+ retryInMs: null,
27679
+ message: `Pane descriptor discovery failed after ${attempt} attempts: ${detail}`
27680
+ });
27681
+ return;
27682
+ }
27683
+ const retryInMs = this.options.baseDelayMs * 2 ** (attempt - 1);
27684
+ this.options.onStatus?.({
27685
+ status: "retrying",
27686
+ degraded: true,
27687
+ attempt,
27688
+ maxAttempts: this.options.maxAttempts,
27689
+ retryInMs,
27690
+ message: `Pane descriptor discovery attempt ${attempt} failed: ${detail}`
27691
+ });
27692
+ this.cancelScheduled = this.options.schedule(() => {
27693
+ this.cancelScheduled = null;
27694
+ if (this.isCurrent(epoch)) this.attempt(epoch, listed, attempt + 1);
27695
+ }, retryInMs);
27696
+ });
27697
+ }
27698
+ isCurrent(epoch) {
27699
+ return !this.disposed && epoch === this.epoch;
27700
+ }
27701
+ };
27702
+ STRICT_UTF8_DECODER = new TextDecoder("utf-8", { fatal: true });
27703
+ }
27704
+ });
27705
+
27308
27706
  // packages/daemon/src/command-center/discovery.ts
27309
27707
  import { execFileSync as execFileSync15 } from "node:child_process";
27310
27708
  function tmuxSilent(args) {
@@ -27406,7 +27804,7 @@ function readAdoptedFleet(registry = getDefaultWorkspaceRegistry(), runTmux2 = _
27406
27804
  for (const line of panesRaw.split("\n")) {
27407
27805
  if (!line) continue;
27408
27806
  const fields = line.split(FLEET_FIELD_SEPARATOR);
27409
- if (fields.length !== 13 || fields[12] !== FLEET_LINE_SENTINEL) continue;
27807
+ if (fields.length !== 16 || fields[15] !== FLEET_LINE_SENTINEL) continue;
27410
27808
  const sessionName = fields[0];
27411
27809
  if (!adoptedSet.has(sessionName)) continue;
27412
27810
  const runtimePaneId = fields[1];
@@ -27419,6 +27817,9 @@ function readAdoptedFleet(registry = getDefaultWorkspaceRegistry(), runTmux2 = _
27419
27817
  panesBySession.set(sessionName, panes);
27420
27818
  }
27421
27819
  panes.push({
27820
+ nameSource: emptyToNull(decodeTmuxArgument(fields[14])),
27821
+ title: decodeTmuxArgument(fields[12]),
27822
+ name: emptyToNull(decodeTmuxArgument(fields[13])),
27422
27823
  runtimePaneId,
27423
27824
  semanticPaneId: emptyToNull(fields[2]),
27424
27825
  incarnation,
@@ -27490,6 +27891,7 @@ var _tmuxRunner, FLEET_FIELD_SEPARATOR, FLEET_LINE_SENTINEL, FLEET_PANE_FORMAT;
27490
27891
  var init_discovery = __esm({
27491
27892
  "packages/daemon/src/command-center/discovery.ts"() {
27492
27893
  "use strict";
27894
+ init_session_descriptor_discovery();
27493
27895
  init_native_pane_identity();
27494
27896
  init_live_session_identity();
27495
27897
  init_runtime_namespace();
@@ -27516,6 +27918,9 @@ var init_discovery = __esm({
27516
27918
  "#{@agent_display_name}",
27517
27919
  "#{@agent_hint}",
27518
27920
  "#{pane_birth_id}",
27921
+ "#{qa:pane_title}",
27922
+ "#{qa:@ide_name}",
27923
+ "#{qa:@tmux_ide_name_source}",
27519
27924
  FLEET_LINE_SENTINEL
27520
27925
  ].join(FLEET_FIELD_SEPARATOR);
27521
27926
  }
@@ -27537,7 +27942,7 @@ var init_semantic_resource_id = __esm({
27537
27942
 
27538
27943
  // packages/daemon/src/command-center/resources/application-shell.ts
27539
27944
  import { hostname } from "node:os";
27540
- import { basename as basename10 } from "node:path";
27945
+ import { basename as basename11 } from "node:path";
27541
27946
  function agentIdForPaneStamp(stamp) {
27542
27947
  return semanticResourceId("agent", stamp);
27543
27948
  }
@@ -27692,6 +28097,7 @@ function deprecatedStandalonePaneIdentities(panes) {
27692
28097
  });
27693
28098
  }
27694
28099
  function harnessForPane(pane) {
28100
+ if (pane.teamMemberName) return "claude-code";
27695
28101
  const detected = pane.agentKind?.toLowerCase();
27696
28102
  if (detected === "codex") return "codex";
27697
28103
  if (detected === "claude" || detected === "claude-code") return "claude-code";
@@ -27700,24 +28106,26 @@ function harnessForPane(pane) {
27700
28106
  if (executable.includes("claude")) return "claude-code";
27701
28107
  return "custom";
27702
28108
  }
27703
- function isGenericPaneLabel(value) {
27704
- const normalized = value?.trim().toLowerCase() ?? "";
27705
- return normalized.length === 0 || GENERIC_PANE_LABELS.has(normalized);
27706
- }
27707
28109
  function resolvedAgentLabel(pane, presentation, index) {
27708
- if (presentation.displayName !== void 0) {
27709
- return label(presentation.displayName, `Agent ${index + 1}`);
27710
- }
27711
- if (!isGenericPaneLabel(pane.name)) return label(pane.name, `Agent ${index + 1}`);
28110
+ const resolved2 = resolvePaneDisplayName({
28111
+ semanticPaneId: pane.semanticPaneId ?? `agent.${index}`,
28112
+ configuredName: pane.name,
28113
+ configuredNameSource: pane.nameSource,
28114
+ agentDisplayName: presentation.displayName,
28115
+ teamMemberName: pane.teamMemberName,
28116
+ currentCommand: pane.currentCommand,
28117
+ title: pane.title,
28118
+ hostName: hostname()
28119
+ });
28120
+ if (["manual", "agent", "title"].includes(resolved2.source))
28121
+ return label(resolved2.name, `Agent ${index + 1}`);
27712
28122
  const harness = harnessForPane(pane);
27713
28123
  if (harness === "codex") return "Codex";
27714
28124
  if (harness === "claude-code") return "Claude Code";
27715
- if (!isGenericPaneLabel(pane.title) && !isHostNameTitle(pane.title, hostname())) {
27716
- return label(pane.title, `Agent ${index + 1}`);
27717
- }
27718
- return `Agent ${index + 1}`;
28125
+ return resolved2.source === "process" ? label(resolved2.name, `Agent ${index + 1}`) : `Agent ${index + 1}`;
27719
28126
  }
27720
28127
  function isAgentPane(pane) {
28128
+ if (pane.teamMemberName) return true;
27721
28129
  if (pane.agentStateRaw != null && AGENT_STATE_STAMP.test(pane.agentStateRaw.trim())) {
27722
28130
  return true;
27723
28131
  }
@@ -27818,7 +28226,7 @@ function deepFreeze2(value) {
27818
28226
  }
27819
28227
  function projectApplicationShellResourceV1Core(session, paneIds, nowSec) {
27820
28228
  const sessionName = label(session.name, "tmux session");
27821
- const rootLabel = label(basename10(session.dir), sessionName);
28229
+ const rootLabel = label(basename11(session.dir), sessionName);
27822
28230
  const projectId = semanticResourceId("project", session.dir);
27823
28231
  const sessionId = semanticResourceId("session", session.name);
27824
28232
  const focusedIndex = session.panes.findIndex((pane) => pane.active);
@@ -28040,23 +28448,23 @@ function projectDeprecatedStandaloneApplicationShellResourceV1(session) {
28040
28448
  )
28041
28449
  );
28042
28450
  }
28043
- var GENERIC_PANE_LABELS, AGENT_STATE_STAMP;
28451
+ var AGENT_STATE_STAMP;
28044
28452
  var init_application_shell2 = __esm({
28045
28453
  "packages/daemon/src/command-center/resources/application-shell.ts"() {
28046
28454
  "use strict";
28455
+ init_pane_display_name();
28047
28456
  init_src();
28048
28457
  init_semantic_resource_id();
28049
28458
  init_classify();
28050
28459
  init_agent_resolution();
28051
28460
  init_fleet_catalog2();
28052
- GENERIC_PANE_LABELS = /* @__PURE__ */ new Set(["shell", "terminal", "tmux"]);
28053
28461
  AGENT_STATE_STAMP = /^(?:working|blocked|done|idle):\d+$/u;
28054
28462
  }
28055
28463
  });
28056
28464
 
28057
28465
  // packages/daemon/src/command-center/resources/fleet-catalog.ts
28058
28466
  import { createHash as createHash13 } from "node:crypto";
28059
- import { basename as basename11 } from "node:path";
28467
+ import { basename as basename12 } from "node:path";
28060
28468
  function digest(value) {
28061
28469
  return createHash13("sha256").update(value).digest("hex").slice(0, 20);
28062
28470
  }
@@ -28088,23 +28496,25 @@ function fleetLabel(value, fallback) {
28088
28496
  return normalized || fallback;
28089
28497
  }
28090
28498
  function fleetProjectLabel(cwd, fallback) {
28091
- const base2 = basename11(cwd).replace(/[/\\]/gu, "");
28499
+ const base2 = basename12(cwd).replace(/[/\\]/gu, "");
28092
28500
  return fleetLabel(base2, fallback);
28093
28501
  }
28094
28502
  function toPresentationPane(pane, index) {
28095
28503
  return {
28096
28504
  semanticPaneId: null,
28097
28505
  index,
28098
- title: "",
28506
+ title: pane.title ?? "",
28099
28507
  currentCommand: pane.currentCommand,
28100
28508
  active: pane.active,
28101
28509
  role: null,
28102
- name: null,
28510
+ name: pane.name ?? null,
28511
+ nameSource: pane.nameSource,
28103
28512
  type: null,
28104
28513
  agentKind: pane.agentHintRaw,
28105
28514
  agentStateRaw: pane.agentStateRaw,
28106
28515
  agentStatusTextRaw: pane.agentStatusTextRaw,
28107
28516
  agentDisplayNameRaw: pane.agentDisplayNameRaw,
28517
+ teamMemberName: pane.teamMemberName,
28108
28518
  // Authority-only: the fleet never scrapes an unopened session. `null` (not
28109
28519
  // `undefined`) keeps `resolveAgentPresentation` on the ground-truth path
28110
28520
  // while its scrape verdict resolves to `unknown` without any capture.
@@ -28122,7 +28532,10 @@ function projectSession(session, nowSec, remainingAgentBudget) {
28122
28532
  const presentation = resolveAgentPresentation(presentationPane, nowSec);
28123
28533
  agents.push({
28124
28534
  agentId: fleetAgentIdForPane(session.name, pane),
28125
- name: fleetLabel(presentation.displayName ?? pane.currentCommand, `Agent ${index + 1}`),
28535
+ name: fleetLabel(
28536
+ resolvedAgentLabel(presentationPane, presentation, index),
28537
+ `Agent ${index + 1}`
28538
+ ),
28126
28539
  harness: harnessForPane(presentationPane),
28127
28540
  activity: presentation.activity,
28128
28541
  attention: presentation.attention,
@@ -28169,9 +28582,9 @@ function launchCommandForHarness(harness) {
28169
28582
  return LAUNCH_COMMANDS[harness] ?? harness;
28170
28583
  }
28171
28584
  function paneStartHostsShell(startCommand) {
28172
- const token = startCommand.trim().split(/\s+/u)[0] ?? "";
28173
- const basename20 = token.replace(/^-/, "").replace(/\\/gu, "/").split("/").pop()?.toLowerCase() ?? "";
28174
- return basename20 === "" || SHELLS.has(basename20.replace(/\.exe$/u, ""));
28585
+ const token2 = startCommand.trim().split(/\s+/u)[0] ?? "";
28586
+ const basename21 = token2.replace(/^-/, "").replace(/\\/gu, "/").split("/").pop()?.toLowerCase() ?? "";
28587
+ return basename21 === "" || SHELLS.has(basename21.replace(/\.exe$/u, ""));
28175
28588
  }
28176
28589
  function interruptArgs2(paneId) {
28177
28590
  return ["send-keys", "-t", paneId, "C-c"];
@@ -29051,7 +29464,7 @@ function derivePromotionIdentity(sessionName) {
29051
29464
  sessionName
29052
29465
  });
29053
29466
  }
29054
- function positiveInteger(value) {
29467
+ function positiveInteger2(value) {
29055
29468
  if (!/^[1-9][0-9]*$/u.test(value)) return null;
29056
29469
  const parsed = Number(value);
29057
29470
  return Number.isSafeInteger(parsed) ? parsed : null;
@@ -29110,8 +29523,8 @@ function parseVerifyPanes(output) {
29110
29523
  const panes = [];
29111
29524
  for (const line of normalized.split("\n")) {
29112
29525
  const fields = line.split(FIELD);
29113
- const windowPaneCount = positiveInteger(fields[3] ?? "");
29114
- const sessionWindowCount = positiveInteger(fields[4] ?? "");
29526
+ const windowPaneCount = positiveInteger2(fields[3] ?? "");
29527
+ const sessionWindowCount = positiveInteger2(fields[4] ?? "");
29115
29528
  if (fields.length !== 10 || fields[9] !== SENTINEL || !/^(0|[1-9][0-9]*)$/u.test(fields[8]) || !Number.isSafeInteger(Number(fields[8])) || !/^\$[0-9]+$/u.test(fields[0]) || !/^@[0-9]+$/u.test(fields[1]) || !/^%[0-9]+$/u.test(fields[5]) || windowPaneCount === null || sessionWindowCount === null) {
29116
29529
  throw new WorkspacePromotionError("promotion_verification_failed", {
29117
29530
  reason: "invalid_tmux_pane_inventory"
@@ -29826,7 +30239,7 @@ function createNativeTmuxSessionOpener(options) {
29826
30239
  options.assertOpen();
29827
30240
  if (disposed) throw new Error("Session admission is retired");
29828
30241
  };
29829
- const open = async (liveSessionId) => {
30242
+ const open2 = async (liveSessionId) => {
29830
30243
  assertOpen();
29831
30244
  const records = await options.run([
29832
30245
  "list-sessions",
@@ -29881,7 +30294,7 @@ function createNativeTmuxSessionOpener(options) {
29881
30294
  const previous = pending.get(liveSessionId);
29882
30295
  if (previous) return previous;
29883
30296
  if (pending.size >= 16) throw new Error("Session admission capacity reached");
29884
- const operation = tail.then(() => open(liveSessionId)).finally(() => pending.delete(liveSessionId));
30297
+ const operation = tail.then(() => open2(liveSessionId)).finally(() => pending.delete(liveSessionId));
29885
30298
  pending.set(liveSessionId, operation);
29886
30299
  tail = operation.catch(() => {
29887
30300
  });
@@ -30398,10 +30811,10 @@ var init_control_channel = __esm({
30398
30811
  collector.failureReason ??= "foreign-sentinel";
30399
30812
  return true;
30400
30813
  }
30401
- const token = line.startsWith(ownPrefix) ? line.slice(ownPrefix.length) : null;
30814
+ const token2 = line.startsWith(ownPrefix) ? line.slice(ownPrefix.length) : null;
30402
30815
  if (!collector.started) {
30403
- if (token === null) return false;
30404
- if (token !== "start" || !this.inReply || this.currentReplyFlags !== 0 || this.currentReplyNum === null) {
30816
+ if (token2 === null) return false;
30817
+ if (token2 !== "start" || !this.inReply || this.currentReplyFlags !== 0 || this.currentReplyNum === null) {
30405
30818
  collector.failureReason ??= "sentinel-order";
30406
30819
  return true;
30407
30820
  }
@@ -30505,13 +30918,13 @@ var init_control_channel = __esm({
30505
30918
  }
30506
30919
  const markerRejected = `marker-rejected`;
30507
30920
  if (collector.blockOrdinal === markerBranchOrdinal) {
30508
- collector.failureReason ??= token === markerRejected ? "marker-rejected" : "sentinel-order";
30921
+ collector.failureReason ??= token2 === markerRejected ? "marker-rejected" : "sentinel-order";
30509
30922
  return true;
30510
30923
  }
30511
30924
  const expectedToken = collector.blockOrdinal === 2 ? "capture-end" : collector.blockOrdinal === 4 ? "cursor-end" : collector.blockOrdinal === statusOrdinal ? "status-ok" : collector.blockOrdinal === completeOrdinal ? "complete" : null;
30512
- if (expectedToken === null || token !== expectedToken)
30513
- collector.failureReason ??= token === "start" ? "duplicate-sentinel" : "sentinel-order";
30514
- if (collector.blockOrdinal === statusOrdinal && token === "status-ok") {
30925
+ if (expectedToken === null || token2 !== expectedToken)
30926
+ collector.failureReason ??= token2 === "start" ? "duplicate-sentinel" : "sentinel-order";
30927
+ if (collector.blockOrdinal === statusOrdinal && token2 === "status-ok") {
30515
30928
  if (collector.statusObserved) collector.failureReason ??= "duplicate-sentinel";
30516
30929
  collector.statusObserved = true;
30517
30930
  }
@@ -31502,265 +31915,6 @@ var init_layout_parse = __esm({
31502
31915
  }
31503
31916
  });
31504
31917
 
31505
- // packages/daemon/src/terminal/protocol/session-descriptor-discovery.ts
31506
- function decodeTmuxArgument(value) {
31507
- const encoded = value.length >= 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) ? value.slice(1, -1) : value;
31508
- let decoded = "";
31509
- for (let index = 0; index < encoded.length; index += 1) {
31510
- const current = encoded[index];
31511
- if (current !== "\\" || index + 1 >= encoded.length) {
31512
- decoded += current;
31513
- continue;
31514
- }
31515
- const escaped = encoded[++index];
31516
- if (escaped === "e") decoded += "\x1B";
31517
- else if (escaped === "n") decoded += "\n";
31518
- else if (escaped === "r") decoded += "\r";
31519
- else if (escaped === "t") decoded += " ";
31520
- else if (/[0-7]/u.test(escaped)) {
31521
- let octal = escaped;
31522
- while (octal.length < 3 && /[0-7]/u.test(encoded[index + 1] ?? "")) {
31523
- octal += encoded[++index];
31524
- }
31525
- decoded += String.fromCodePoint(Number.parseInt(octal, 8));
31526
- } else if (escaped === "u") {
31527
- const remaining = encoded.slice(index + 1);
31528
- const unicode = remaining.match(/^(?:[0-9A-Fa-f]{8}|[0-9A-Fa-f]{4})/u)?.[0];
31529
- if (unicode) {
31530
- decoded += String.fromCodePoint(Number.parseInt(unicode, 16));
31531
- index += unicode.length;
31532
- } else {
31533
- decoded += "u";
31534
- }
31535
- } else {
31536
- decoded += escaped;
31537
- }
31538
- }
31539
- return decoded;
31540
- }
31541
- function parseSessionPaneDescriptorReply(lines) {
31542
- const descriptors = [];
31543
- let malformedUtf8Records = 0;
31544
- if (lines.length > 4096 || lines.reduce((bytes, line) => bytes + Buffer.byteLength(line, "latin1") + 1, 0) > 128 * 1024) {
31545
- return { descriptors, malformedUtf8Records };
31546
- }
31547
- for (const line of lines) {
31548
- const utf8Line = decodeControlReplyUtf8(line);
31549
- if (utf8Line === null) {
31550
- malformedUtf8Records += 1;
31551
- continue;
31552
- }
31553
- const encoded = utf8Line.split(" ");
31554
- if (encoded.length !== 21) continue;
31555
- const [
31556
- runtimePaneId = "",
31557
- semanticPaneId3 = "",
31558
- role = "",
31559
- type = "",
31560
- currentCommand = "",
31561
- cwd = "",
31562
- windowIndexRaw = "",
31563
- windowName = "",
31564
- windowId = "",
31565
- title = "",
31566
- runtimeSessionId = "",
31567
- paneIndexRaw = "",
31568
- name = "",
31569
- missionStamp = "",
31570
- paneActiveRaw = "",
31571
- windowActiveRaw = "",
31572
- semanticWindowId = "",
31573
- sessionName = "",
31574
- windowPaneCountRaw = "",
31575
- sessionWindowCountRaw = "",
31576
- nativePaneBirthId = ""
31577
- ] = encoded.map(decodeTmuxArgument);
31578
- if (!/^%(?:0|[1-9][0-9]*)$/u.test(runtimePaneId) || runtimePaneId.length > 32) continue;
31579
- if (!/^\$(?:0|[1-9][0-9]*)$/u.test(runtimeSessionId) || runtimeSessionId.length > 32) continue;
31580
- const parsedWindowIndex = Number(windowIndexRaw);
31581
- const windowIndex = Number.isSafeInteger(parsedWindowIndex) && parsedWindowIndex >= 0 ? parsedWindowIndex : null;
31582
- const paneIndex = Number(paneIndexRaw);
31583
- const windowPaneCount = Number(windowPaneCountRaw);
31584
- const sessionWindowCount = Number(sessionWindowCountRaw);
31585
- if (!/^(?:0|[1-9][0-9]*)$/u.test(paneIndexRaw) || !Number.isSafeInteger(paneIndex)) continue;
31586
- if (!/^[1-9][0-9]*$/u.test(windowPaneCountRaw) || !Number.isSafeInteger(windowPaneCount) || !/^[1-9][0-9]*$/u.test(sessionWindowCountRaw) || !Number.isSafeInteger(sessionWindowCount) || windowPaneCount < 1 || sessionWindowCount < 1)
31587
- continue;
31588
- if (!["0", "1"].includes(paneActiveRaw) || !["0", "1"].includes(windowActiveRaw)) continue;
31589
- const bounded4 = (value, maximum) => value.length <= maximum && !/[\0\r\n\t]/u.test(value);
31590
- if (!bounded4(semanticPaneId3, 256) || !bounded4(role, 256) || !bounded4(type, 256) || !bounded4(currentCommand, 512) || !bounded4(cwd, 4096) || !bounded4(title, 1024) || !bounded4(windowName, 1024) || !bounded4(name, 256) || !bounded4(missionStamp, 256) || !bounded4(semanticWindowId, 256) || !bounded4(sessionName, 160) || sessionName.length === 0 || windowId.length > 32) {
31591
- continue;
31592
- }
31593
- descriptors.push({
31594
- sessionName,
31595
- runtimePaneId,
31596
- runtimeSessionId,
31597
- semanticPaneId: nonempty(semanticPaneId3),
31598
- role: nonempty(role),
31599
- type: nonempty(type),
31600
- currentCommand: nonempty(currentCommand),
31601
- cwd: nonempty(cwd),
31602
- title: nonempty(title),
31603
- windowIndex,
31604
- windowName: nonempty(windowName),
31605
- windowId: /^@(?:0|[1-9][0-9]*)$/u.test(windowId) ? windowId : null,
31606
- semanticWindowId: nonempty(semanticWindowId),
31607
- paneIndex,
31608
- name: nonempty(name),
31609
- // Source metadata is persisted for mutations, while this hot inventory
31610
- // stays wire-compatible. Generated names are recognized deterministically.
31611
- nameSource: null,
31612
- missionStamp: nonempty(missionStamp),
31613
- nativePaneBirthId: nonempty(nativePaneBirthId),
31614
- paneActive: paneActiveRaw === "1",
31615
- windowActive: windowActiveRaw === "1",
31616
- windowPaneCount,
31617
- sessionWindowCount
31618
- });
31619
- }
31620
- return { descriptors, malformedUtf8Records };
31621
- }
31622
- function nonempty(value) {
31623
- return value.length > 0 ? value : null;
31624
- }
31625
- function decodeControlReplyUtf8(value) {
31626
- try {
31627
- return STRICT_UTF8_DECODER.decode(Buffer.from(value, "latin1"));
31628
- } catch {
31629
- return null;
31630
- }
31631
- }
31632
- function positiveInteger2(value, fallback) {
31633
- return Number.isSafeInteger(value) && value > 0 ? value : fallback;
31634
- }
31635
- var SESSION_PANE_DESCRIPTOR_FORMAT, SessionDescriptorDiscovery, STRICT_UTF8_DECODER;
31636
- var init_session_descriptor_discovery = __esm({
31637
- "packages/daemon/src/terminal/protocol/session-descriptor-discovery.ts"() {
31638
- "use strict";
31639
- SESSION_PANE_DESCRIPTOR_FORMAT = [
31640
- "#{pane_id}",
31641
- "#{qa:@tmux_ide_pane_id}",
31642
- "#{qa:@ide_role}",
31643
- "#{qa:@ide_type}",
31644
- "#{qa:pane_current_command}",
31645
- "#{qa:pane_current_path}",
31646
- "#{window_index}",
31647
- "#{qa:window_name}",
31648
- "#{window_id}",
31649
- "#{qa:pane_title}",
31650
- "#{session_id}",
31651
- "#{pane_index}",
31652
- "#{qa:@ide_name}",
31653
- "#{qa:@tmux_ide_mission}",
31654
- "#{pane_active}",
31655
- "#{?window_active,1,0}",
31656
- "#{qa:@tmux_ide_window_id}",
31657
- "#{qa:session_name}",
31658
- "#{window_panes}",
31659
- "#{session_windows}",
31660
- "#{pane_birth_id}"
31661
- ].join(" ");
31662
- SessionDescriptorDiscovery = class {
31663
- options;
31664
- epoch = 0;
31665
- cancelScheduled = null;
31666
- disposed = false;
31667
- constructor(options) {
31668
- this.options = {
31669
- ...options,
31670
- maxAttempts: positiveInteger2(options.maxAttempts, 3),
31671
- baseDelayMs: positiveInteger2(options.baseDelayMs, 50),
31672
- schedule: options.schedule ?? ((callback, delayMs) => {
31673
- const timer = setTimeout(callback, delayMs);
31674
- return () => clearTimeout(timer);
31675
- })
31676
- };
31677
- }
31678
- discover(listedRuntimePaneIds) {
31679
- if (this.disposed) return;
31680
- this.invalidatePending();
31681
- const epoch = this.epoch;
31682
- this.attempt(epoch, new Set(listedRuntimePaneIds), 1);
31683
- }
31684
- invalidate() {
31685
- if (this.disposed) return;
31686
- this.invalidatePending();
31687
- this.options.onStatus?.(null);
31688
- }
31689
- dispose() {
31690
- if (this.disposed) return;
31691
- this.invalidatePending();
31692
- this.disposed = true;
31693
- }
31694
- invalidatePending() {
31695
- this.epoch += 1;
31696
- this.cancelScheduled?.();
31697
- this.cancelScheduled = null;
31698
- }
31699
- attempt(epoch, listed, attempt) {
31700
- void this.options.query().then((lines) => {
31701
- if (!this.isCurrent(epoch)) return;
31702
- const parsed = parseSessionPaneDescriptorReply(lines);
31703
- const descriptorByRuntimePane = new Map(
31704
- parsed.descriptors.filter((descriptor) => listed.has(descriptor.runtimePaneId)).map((descriptor) => [descriptor.runtimePaneId, descriptor])
31705
- );
31706
- const descriptors = [...descriptorByRuntimePane.values()];
31707
- if (listed.size > 0 && descriptors.length === 0) {
31708
- const malformedDetail = parsed.malformedUtf8Records > 0 ? `; ${parsed.malformedUtf8Records} malformed UTF-8 record${parsed.malformedUtf8Records === 1 ? " was" : "s were"} omitted` : "";
31709
- throw new Error(
31710
- `descriptor reply covered 0 of ${listed.size} live panes${malformedDetail}`
31711
- );
31712
- }
31713
- if (descriptors.length !== listed.size || parsed.malformedUtf8Records > 0) {
31714
- const malformedDetail = parsed.malformedUtf8Records > 0 ? `; omitted ${parsed.malformedUtf8Records} malformed UTF-8 record${parsed.malformedUtf8Records === 1 ? "" : "s"}` : "";
31715
- this.options.onStatus?.({
31716
- status: "partial",
31717
- degraded: true,
31718
- attempt,
31719
- maxAttempts: this.options.maxAttempts,
31720
- retryInMs: null,
31721
- message: `Pane descriptor discovery published ${descriptors.length} of ${listed.size} live panes${malformedDetail}.`
31722
- });
31723
- } else {
31724
- this.options.onStatus?.(null);
31725
- }
31726
- this.options.onDescriptors(descriptors, listed);
31727
- }).catch((cause) => {
31728
- if (!this.isCurrent(epoch)) return;
31729
- const detail = cause instanceof Error ? cause.message : String(cause);
31730
- if (attempt >= this.options.maxAttempts) {
31731
- this.options.onStatus?.({
31732
- status: "failed",
31733
- degraded: true,
31734
- attempt,
31735
- maxAttempts: this.options.maxAttempts,
31736
- retryInMs: null,
31737
- message: `Pane descriptor discovery failed after ${attempt} attempts: ${detail}`
31738
- });
31739
- return;
31740
- }
31741
- const retryInMs = this.options.baseDelayMs * 2 ** (attempt - 1);
31742
- this.options.onStatus?.({
31743
- status: "retrying",
31744
- degraded: true,
31745
- attempt,
31746
- maxAttempts: this.options.maxAttempts,
31747
- retryInMs,
31748
- message: `Pane descriptor discovery attempt ${attempt} failed: ${detail}`
31749
- });
31750
- this.cancelScheduled = this.options.schedule(() => {
31751
- this.cancelScheduled = null;
31752
- if (this.isCurrent(epoch)) this.attempt(epoch, listed, attempt + 1);
31753
- }, retryInMs);
31754
- });
31755
- }
31756
- isCurrent(epoch) {
31757
- return !this.disposed && epoch === this.epoch;
31758
- }
31759
- };
31760
- STRICT_UTF8_DECODER = new TextDecoder("utf-8", { fatal: true });
31761
- }
31762
- });
31763
-
31764
31918
  // packages/daemon/src/terminal/protocol/workspace-tmux-adapter.ts
31765
31919
  function planWorkspaceTmuxReconciliation(input) {
31766
31920
  const diagnostics = [];
@@ -34968,6 +35122,7 @@ var init_session_channel = __esm({
34968
35122
  active: descriptor.paneActive && descriptor.windowActive,
34969
35123
  role: descriptor.role,
34970
35124
  name: descriptor.name,
35125
+ ...descriptor.nameSource ? { nameSource: descriptor.nameSource } : {},
34971
35126
  type: descriptor.type,
34972
35127
  missionStamp: descriptor.missionStamp,
34973
35128
  nativePaneBirthId: descriptor.nativePaneBirthId ?? null,
@@ -55893,13 +56048,13 @@ var init_registry2 = __esm({
55893
56048
  if (!inventory) {
55894
56049
  throw new Error(`SessionRuntime ${session} lost its retained inventory authority`);
55895
56050
  }
55896
- const token = Object.freeze({});
55897
- this.#trustedInventoryTokens.set(token, runtime);
55898
- return Object.freeze({ inventory, token });
56051
+ const token2 = Object.freeze({});
56052
+ this.#trustedInventoryTokens.set(token2, runtime);
56053
+ return Object.freeze({ inventory, token: token2 });
55899
56054
  }
55900
- isTrustedSessionInventoryCandidateCurrent(session, token) {
56055
+ isTrustedSessionInventoryCandidateCurrent(session, token2) {
55901
56056
  if (this.#disposed) return false;
55902
- const runtime = this.#trustedInventoryTokens.get(token);
56057
+ const runtime = this.#trustedInventoryTokens.get(token2);
55903
56058
  return runtime !== void 0 && this.#sessions.get(session) === runtime && runtime.trustedInventoryQualified();
55904
56059
  }
55905
56060
  hasProofQualifiedInventory(session) {
@@ -59792,7 +59947,7 @@ var init_MonotonicPtyInput = __esm({
59792
59947
 
59793
59948
  // packages/daemon/src/terminal/NodePtyAdapter.ts
59794
59949
  import { chmodSync as chmodSync6, existsSync as existsSync26, statSync as statSync12 } from "node:fs";
59795
- import { dirname as dirname28, join as join31 } from "node:path";
59950
+ import { dirname as dirname28, join as join32 } from "node:path";
59796
59951
  import { createRequire as createRequire2 } from "node:module";
59797
59952
  import * as pty from "node-pty";
59798
59953
  function candidateSpawnHelperPaths() {
@@ -59805,9 +59960,9 @@ function candidateSpawnHelperPaths() {
59805
59960
  }
59806
59961
  const pkgDir = dirname28(pkgJsonPath);
59807
59962
  return [
59808
- join31(pkgDir, "build", "Release", "spawn-helper"),
59809
- join31(pkgDir, "build", "Debug", "spawn-helper"),
59810
- join31(pkgDir, "prebuilds", `${process.platform}-${process.arch}`, "spawn-helper")
59963
+ join32(pkgDir, "build", "Release", "spawn-helper"),
59964
+ join32(pkgDir, "build", "Debug", "spawn-helper"),
59965
+ join32(pkgDir, "prebuilds", `${process.platform}-${process.arch}`, "spawn-helper")
59811
59966
  ];
59812
59967
  }
59813
59968
  function ensureNodePtySpawnHelperExecutable(options = {}) {
@@ -60742,7 +60897,7 @@ var init_tmux_view_executor = __esm({
60742
60897
 
60743
60898
  // packages/daemon/src/terminal/attachments/pty-tmux-attachment-launcher.ts
60744
60899
  import { accessSync as accessSync8, constants as constants12, realpathSync as realpathSync15, statSync as statSync13 } from "node:fs";
60745
- import { delimiter as delimiter3, isAbsolute as isAbsolute16, join as join32 } from "node:path";
60900
+ import { delimiter as delimiter3, isAbsolute as isAbsolute16, join as join33 } from "node:path";
60746
60901
  import { randomUUID as randomUUID23 } from "node:crypto";
60747
60902
  import { execFileSync as execFileSync16 } from "node:child_process";
60748
60903
  function defaultSchedule2(callback, delayMs) {
@@ -60771,7 +60926,7 @@ function selectorArgv(selector) {
60771
60926
  function resolveTmuxExecutable3(pathValue = process.env.PATH) {
60772
60927
  for (const directory of (pathValue ?? "").split(delimiter3)) {
60773
60928
  if (!directory || !isAbsolute16(directory)) continue;
60774
- const candidate = join32(directory, "tmux");
60929
+ const candidate = join33(directory, "tmux");
60775
60930
  try {
60776
60931
  accessSync8(candidate, constants12.X_OK);
60777
60932
  if (!statSync13(candidate).isFile()) continue;
@@ -61553,6 +61708,7 @@ function projectTrustedMirrorInventory(trusted2, workspaceName, expectedSessionN
61553
61708
  active: pane.active,
61554
61709
  role: nullable2(pane.role),
61555
61710
  name: nullable2(pane.name),
61711
+ ...pane.nameSource ? { nameSource: nullable2(pane.nameSource) } : {},
61556
61712
  type: nullable2(pane.type),
61557
61713
  missionStamp: nullable2(pane.missionStamp),
61558
61714
  dir: boundedWireValue(pane.dir, 4096)
@@ -62122,7 +62278,7 @@ var init_native_runtime = __esm({
62122
62278
  return (typeof qualify === "function" ? qualify.call(sessionRuntimeRegistry, sessionName, runtimeSessionId, signal) : sessionRuntimeRegistry.prewarmSession(sessionName, signal)).then(() => void 0);
62123
62279
  };
62124
62280
  this.#discoverTrustedSessionInventory = typeof sessionRuntimeRegistry.describeTrustedSessionInventoryCandidate === "function" ? (sessionName, signal) => sessionRuntimeRegistry.describeTrustedSessionInventoryCandidate(sessionName, signal) : typeof sessionRuntimeRegistry.describeTrustedSessionInventory === "function" ? (sessionName, signal) => sessionRuntimeRegistry.describeTrustedSessionInventory(sessionName, signal).then((inventory) => ({ inventory, token: Object.freeze({}) })) : null;
62125
- this.#trustedSessionInventoryCurrent = typeof sessionRuntimeRegistry.isTrustedSessionInventoryCandidateCurrent === "function" ? (sessionName, token) => sessionRuntimeRegistry.isTrustedSessionInventoryCandidateCurrent(sessionName, token) : typeof sessionRuntimeRegistry.hasProofQualifiedInventory === "function" ? (sessionName) => sessionRuntimeRegistry.hasProofQualifiedInventory(sessionName) : null;
62281
+ this.#trustedSessionInventoryCurrent = typeof sessionRuntimeRegistry.isTrustedSessionInventoryCandidateCurrent === "function" ? (sessionName, token2) => sessionRuntimeRegistry.isTrustedSessionInventoryCandidateCurrent(sessionName, token2) : typeof sessionRuntimeRegistry.hasProofQualifiedInventory === "function" ? (sessionName) => sessionRuntimeRegistry.hasProofQualifiedInventory(sessionName) : null;
62126
62282
  this.#observeWorkspaceSession = (workspaceName, sessionName) => {
62127
62283
  const previousSessionName = sessionsByWorkspace.get(workspaceName);
62128
62284
  sessionsByWorkspace.set(workspaceName, sessionName);
@@ -63136,6 +63292,19 @@ function createTmuxAgentStatusProbe(deps2) {
63136
63292
  });
63137
63293
  emit(pane, raw, verdict, manifest.id);
63138
63294
  }
63295
+ if (deps2.readTeamNames) {
63296
+ const names = await deps2.readTeamNames(
63297
+ input.panes.flatMap((pane) => {
63298
+ const pid = options.get(pane.runtimePaneId)?.pid;
63299
+ return pid ? [{ runtimePaneId: pane.runtimePaneId, pid }] : [];
63300
+ })
63301
+ );
63302
+ throwIfAborted(signal);
63303
+ for (const [paneId, name] of names) {
63304
+ const fact = facts.get(paneId);
63305
+ if (fact) facts.set(paneId, { ...fact, teamMemberName: name });
63306
+ }
63307
+ }
63139
63308
  if (stagedVerdicts.size > SCRAPE_CACHE_MAX_ENTRIES) {
63140
63309
  const byAge = [...stagedVerdicts.entries()].sort(
63141
63310
  (a, b) => a[1].scrapedAtSec - b[1].scrapedAtSec
@@ -69264,9 +69433,9 @@ var init_pane_stream_upgrade = __esm({
69264
69433
 
69265
69434
  // packages/daemon/src/lib/embedded-tmux-server-owners.ts
69266
69435
  import { randomUUID as randomUUID30 } from "node:crypto";
69267
- import { join as join33 } from "node:path";
69436
+ import { join as join34 } from "node:path";
69268
69437
  async function createEmbeddedTmuxServerOwners(options) {
69269
- const path2 = join33(options.stateDirectory, "tmux-servers.json");
69438
+ const path2 = join34(options.stateDirectory, "tmux-servers.json");
69270
69439
  const persisted = readTmuxServerRegistrations(path2);
69271
69440
  const probe = createTmuxServerProbe(options.defaultAuthority.executablePath);
69272
69441
  const defaultObservation = await probe(options.defaultAuthority.socketSelector);
@@ -69327,7 +69496,7 @@ async function createEmbeddedTmuxServerOwners(options) {
69327
69496
  ...scope,
69328
69497
  tmuxAuthority: observation2.authority,
69329
69498
  nativeServerIdentity: observation2.nativeServerIdentity,
69330
- stateDirectory: join33(options.stateDirectory, "server-owners", registration.serverId),
69499
+ stateDirectory: join34(options.stateDirectory, "server-owners", registration.serverId),
69331
69500
  webSocketUrl: new URL(route, options.webSocketBaseUrl).href
69332
69501
  });
69333
69502
  attachOwner(route, owner);
@@ -71495,7 +71664,7 @@ var init_daemon_fleet_facts_observer = __esm({
71495
71664
 
71496
71665
  // packages/daemon/src/lib/directory-watcher.ts
71497
71666
  import { watch as fsWatch } from "node:fs";
71498
- import { join as join34, sep as sep9 } from "node:path";
71667
+ import { join as join35, sep as sep9 } from "node:path";
71499
71668
  async function loadParcel() {
71500
71669
  if (parcel !== void 0) return parcel;
71501
71670
  try {
@@ -71524,7 +71693,7 @@ function fsWatchDirectory(dir, onChange, ignore2, debounceMs, requireInstalled,
71524
71693
  const rel = filename.toString();
71525
71694
  if (rel.split(sep9).some((part) => ignoreSet.has(part))) return;
71526
71695
  if (timeout) clearTimeout(timeout);
71527
- timeout = setTimeout(() => onChange([{ type: "update", path: join34(dir, rel) }]), debounceMs);
71696
+ timeout = setTimeout(() => onChange([{ type: "update", path: join35(dir, rel) }]), debounceMs);
71528
71697
  });
71529
71698
  handle.on("error", reportUnavailable);
71530
71699
  handle.on("close", () => {
@@ -72730,12 +72899,12 @@ var init_auth_token = __esm({
72730
72899
 
72731
72900
  // packages/daemon/src/lib/app-settings.ts
72732
72901
  import { existsSync as existsSync27, mkdirSync as mkdirSync23, readFileSync as readFileSync25, renameSync as renameSync14, writeFileSync as writeFileSync20 } from "node:fs";
72733
- import { dirname as dirname31, join as join35 } from "node:path";
72902
+ import { dirname as dirname31, join as join36 } from "node:path";
72734
72903
  function settingsDir() {
72735
72904
  return resolveRuntimeNamespace().settingsDir;
72736
72905
  }
72737
72906
  function appSettingsPath() {
72738
- return runtimeOwnedPath(join35(settingsDir(), "app-settings.json"));
72907
+ return runtimeOwnedPath(join36(settingsDir(), "app-settings.json"));
72739
72908
  }
72740
72909
  function normalizeSettings(value) {
72741
72910
  if (!value || typeof value !== "object") return structuredClone(DEFAULT_SETTINGS);
@@ -72743,8 +72912,8 @@ function normalizeSettings(value) {
72743
72912
  if (!remote || typeof remote !== "object") return structuredClone(DEFAULT_SETTINGS);
72744
72913
  const enabled = remote.enabled === true;
72745
72914
  const rawToken = remote.token;
72746
- const token = typeof rawToken === "string" && rawToken.length > 0 ? rawToken : null;
72747
- return { remoteAccess: { enabled, token } };
72915
+ const token2 = typeof rawToken === "string" && rawToken.length > 0 ? rawToken : null;
72916
+ return { remoteAccess: { enabled, token: token2 } };
72748
72917
  }
72749
72918
  function readAppSettings() {
72750
72919
  const path2 = appSettingsPath();
@@ -72808,17 +72977,17 @@ async function appSetRemoteAccessHandler(input, deps2 = {}) {
72808
72977
  const writeSettings = deps2.writeSettings ?? writeAppSettings;
72809
72978
  const nextEnabled = input.enabled;
72810
72979
  const current = readSettings2();
72811
- const token = nextEnabled ? current.remoteAccess.token ?? (deps2.generateToken ?? generateAuthToken)() : null;
72980
+ const token2 = nextEnabled ? current.remoteAccess.token ?? (deps2.generateToken ?? generateAuthToken)() : null;
72812
72981
  const next = {
72813
72982
  ...current,
72814
- remoteAccess: { enabled: nextEnabled, token }
72983
+ remoteAccess: { enabled: nextEnabled, token: token2 }
72815
72984
  };
72816
72985
  writeSettings(next);
72817
72986
  const port = currentPort(deps2);
72818
72987
  const request3 = {
72819
72988
  enabled: nextEnabled,
72820
72989
  bindHostname: nextEnabled ? "0.0.0.0" : "127.0.0.1",
72821
- token,
72990
+ token: token2,
72822
72991
  port
72823
72992
  };
72824
72993
  const restartDaemon = deps2.restartDaemon ?? remoteAccessRestartBackend;
@@ -72839,8 +73008,8 @@ async function appSetRemoteAccessHandler(input, deps2 = {}) {
72839
73008
  return {
72840
73009
  enabled: true,
72841
73010
  url,
72842
- token,
72843
- qrPayload: `${url}?token=${encodeURIComponent(token ?? "")}`
73011
+ token: token2,
73012
+ qrPayload: `${url}?token=${encodeURIComponent(token2 ?? "")}`
72844
73013
  };
72845
73014
  }
72846
73015
  var remoteAccessRestartBackend, remoteAccessListenerPort;
@@ -72970,7 +73139,7 @@ var init_daemon_shutdown = __esm({
72970
73139
  // packages/daemon/src/lib/workspace-open.ts
72971
73140
  import { createHash as createHash21 } from "node:crypto";
72972
73141
  import { realpathSync as realpathSync19, statSync as statSync17 } from "node:fs";
72973
- import { basename as basename12, isAbsolute as isAbsolute19 } from "node:path";
73142
+ import { basename as basename13, isAbsolute as isAbsolute19 } from "node:path";
72974
73143
  function boundedAuthorityLimit3(value, fallback) {
72975
73144
  if (value === void 0) return fallback;
72976
73145
  if (!Number.isInteger(value) || value < 1 || value > MAX_OPERATIONS2) {
@@ -72985,7 +73154,7 @@ function boundedTmuxOutput2(value) {
72985
73154
  return value.replace(/(?:\r?\n)+$/u, "");
72986
73155
  }
72987
73156
  function safeBaseName2(projectDir) {
72988
- const value = basename12(projectDir).normalize("NFKD").replace(/[\u0300-\u036f]/gu, "").toLowerCase().replace(/[^a-z0-9_-]+/gu, "-").replace(/-+/gu, "-").replace(/^[-_]+|[-_]+$/gu, "").slice(0, 72);
73157
+ const value = basename13(projectDir).normalize("NFKD").replace(/[\u0300-\u036f]/gu, "").toLowerCase().replace(/[^a-z0-9_-]+/gu, "-").replace(/-+/gu, "-").replace(/^[-_]+|[-_]+$/gu, "").slice(0, 72);
72989
73158
  return value || "workspace";
72990
73159
  }
72991
73160
  function deriveWorkspaceOpenIdentity(canonicalProjectDir3) {
@@ -73776,12 +73945,12 @@ var init_workspace_open_handoff2 = __esm({
73776
73945
  const preferredPaneId = "initialPaneId" in opened.resource ? opened.resource.initialPaneId : void 0;
73777
73946
  const proof = await this.#deps.prepareRuntime(workspaceName, preferredPaneId);
73778
73947
  this.#assertCurrent(ownerClientId, revision, expectedDaemonInstanceId);
73779
- const token = randomUUID31();
73948
+ const token2 = randomUUID31();
73780
73949
  const result2 = {
73781
73950
  operationId,
73782
73951
  daemonInstanceId: this.#deps.daemonInstanceId,
73783
73952
  phase: "prepared",
73784
- prepareToken: token,
73953
+ prepareToken: token2,
73785
73954
  preparedRevision: revision,
73786
73955
  outcome: opened.outcome,
73787
73956
  workspaceName,
@@ -73789,10 +73958,10 @@ var init_workspace_open_handoff2 = __esm({
73789
73958
  proof
73790
73959
  };
73791
73960
  this.#dropClientRecords(ownerClientId);
73792
- const expiryTimer = this.#setTimer(() => this.#expire(token), this.#prepareTtlMs);
73793
- this.#preparedByToken.set(token, {
73961
+ const expiryTimer = this.#setTimer(() => this.#expire(token2), this.#prepareTtlMs);
73962
+ this.#preparedByToken.set(token2, {
73794
73963
  ownerClientId,
73795
- token,
73964
+ token: token2,
73796
73965
  revision,
73797
73966
  workspaceName,
73798
73967
  previousWorkspaceName,
@@ -73884,10 +74053,10 @@ var init_workspace_open_handoff2 = __esm({
73884
74053
  }
73885
74054
  }
73886
74055
  #dropClientRecords(ownerClientId) {
73887
- for (const [token, record] of this.#preparedByToken) {
74056
+ for (const [token2, record] of this.#preparedByToken) {
73888
74057
  if (record.ownerClientId === ownerClientId) {
73889
74058
  this.#clearTimer(record.expiryTimer);
73890
- this.#preparedByToken.delete(token);
74059
+ this.#preparedByToken.delete(token2);
73891
74060
  }
73892
74061
  }
73893
74062
  }
@@ -73904,15 +74073,15 @@ var init_workspace_open_handoff2 = __esm({
73904
74073
  this.#latestRevisionByClient.set(ownerClientId, revision);
73905
74074
  return revision;
73906
74075
  }
73907
- #expire(token) {
73908
- const record = this.#preparedByToken.get(token);
74076
+ #expire(token2) {
74077
+ const record = this.#preparedByToken.get(token2);
73909
74078
  if (!record) return;
73910
74079
  this.#clearTimer(record.expiryTimer);
73911
- this.#preparedByToken.delete(token);
74080
+ this.#preparedByToken.delete(token2);
73912
74081
  if (this.#latestRevisionByClient.get(record.ownerClientId) === record.revision) {
73913
74082
  this.#latestRevisionByClient.delete(record.ownerClientId);
73914
74083
  }
73915
- this.#expiredTokens.add(token);
74084
+ this.#expiredTokens.add(token2);
73916
74085
  while (this.#expiredTokens.size > this.#maxLiveClients) {
73917
74086
  const oldest = this.#expiredTokens.values().next().value;
73918
74087
  if (!oldest) break;
@@ -75675,9 +75844,9 @@ var init_active_projects = __esm({
75675
75844
  // packages/daemon/src/lib/environment-identity.ts
75676
75845
  import { randomUUID as randomUUID32 } from "node:crypto";
75677
75846
  import { linkSync as linkSync3, mkdirSync as mkdirSync24, readFileSync as readFileSync26, rmSync as rmSync4, writeFileSync as writeFileSync21 } from "node:fs";
75678
- import { dirname as dirname32, join as join36 } from "node:path";
75847
+ import { dirname as dirname32, join as join37 } from "node:path";
75679
75848
  function environmentIdentityPath() {
75680
- return runtimeOwnedPath(join36(stateHome(), "environment.json"));
75849
+ return runtimeOwnedPath(join37(stateHome(), "environment.json"));
75681
75850
  }
75682
75851
  function readPersistedEnvironmentId(path2) {
75683
75852
  try {
@@ -75758,7 +75927,7 @@ import {
75758
75927
  realpathSync as realpathSync20,
75759
75928
  statSync as statSync18
75760
75929
  } from "node:fs";
75761
- import { join as join37, resolve as resolve22 } from "node:path";
75930
+ import { join as join38, resolve as resolve22 } from "node:path";
75762
75931
  function classifySupervisor(facts) {
75763
75932
  if (facts.launcher === "embedded")
75764
75933
  return { kind: "embedded", evidence: "startEmbeddedDaemon host" };
@@ -76160,7 +76329,7 @@ function discoverLogFiles(options) {
76160
76329
  }
76161
76330
  for (const entry of entries) {
76162
76331
  if (!entry.isFile() || !LOG_FILE_NAME.test(entry.name)) continue;
76163
- consider(join37(dir, entry.name));
76332
+ consider(join38(dir, entry.name));
76164
76333
  }
76165
76334
  }
76166
76335
  for (const path2 of options.extraPaths ?? []) consider(resolve22(path2));
@@ -76442,6 +76611,8 @@ function mountAutomationRoutes(app, options) {
76442
76611
  `${base2}/panes`,
76443
76612
  route(async (c) => {
76444
76613
  const panes = [];
76614
+ const credential = c.req.header(PANE_SOURCE_CREDENTIAL_HEADER);
76615
+ let source = null;
76445
76616
  for (const scope of await options.owners.refresh()) {
76446
76617
  if (!scope.generation) continue;
76447
76618
  await options.owners.withOwner(
@@ -76456,6 +76627,18 @@ function mountAutomationRoutes(app, options) {
76456
76627
  pane.semanticPaneId
76457
76628
  );
76458
76629
  if (!endpoint) continue;
76630
+ if (credential) {
76631
+ const binding = owner.resolveInteractionSource(
76632
+ credential,
76633
+ endpoint.workspaceName,
76634
+ endpoint.semanticPaneId
76635
+ );
76636
+ if (binding && same4(binding.endpoint, endpoint)) {
76637
+ if (source && !same4(source, endpoint))
76638
+ throw new AutomationRequestError("invalid-source");
76639
+ source = endpoint;
76640
+ }
76641
+ }
76459
76642
  if (panes.length >= 4096) throw new AutomationRequestError("capacity");
76460
76643
  panes.push({
76461
76644
  endpoint,
@@ -76466,7 +76649,8 @@ function mountAutomationRoutes(app, options) {
76466
76649
  }
76467
76650
  );
76468
76651
  }
76469
- return c.json(AutomationPanesResponseSchemaZ.parse({ version: 1, panes }));
76652
+ if (credential && !source) throw new AutomationRequestError("invalid-source");
76653
+ return c.json(AutomationPanesResponseSchemaZ.parse({ version: 1, panes, source }));
76470
76654
  })
76471
76655
  );
76472
76656
  app.post(
@@ -77563,9 +77747,9 @@ import {
77563
77747
  unlinkSync as unlinkSync7,
77564
77748
  writeFileSync as writeFileSync22
77565
77749
  } from "node:fs";
77566
- import { dirname as dirname33, join as join38 } from "node:path";
77750
+ import { dirname as dirname33, join as join39 } from "node:path";
77567
77751
  function savedMachinesPath() {
77568
- return runtimeOwnedPath(join38(resolveRuntimeNamespace().registryDir, "machines.json"));
77752
+ return runtimeOwnedPath(join39(resolveRuntimeNamespace().registryDir, "machines.json"));
77569
77753
  }
77570
77754
  function loadSavedMachines(path2 = savedMachinesPath()) {
77571
77755
  let fd;
@@ -77696,9 +77880,9 @@ import {
77696
77880
  writeFileSync as writeFileSync23
77697
77881
  } from "node:fs";
77698
77882
  import { randomUUID as randomUUID35 } from "node:crypto";
77699
- import { dirname as dirname34, join as join39 } from "node:path";
77883
+ import { dirname as dirname34, join as join40 } from "node:path";
77700
77884
  function fleetClientStatePath() {
77701
- return runtimeOwnedPath(join39(resolveRuntimeNamespace().registryDir, "fleet-view.json"));
77885
+ return runtimeOwnedPath(join40(resolveRuntimeNamespace().registryDir, "fleet-view.json"));
77702
77886
  }
77703
77887
  function loadFleetClientState(path2 = fleetClientStatePath()) {
77704
77888
  let fd;
@@ -77931,14 +78115,14 @@ var init_schemas = __esm({
77931
78115
  import { createHash as createHash23 } from "node:crypto";
77932
78116
  import { realpathSync as realpathSync21 } from "node:fs";
77933
78117
  import { existsSync as existsSync28, mkdirSync as mkdirSync27, readFileSync as readFileSync29, renameSync as renameSync17, writeFileSync as writeFileSync24 } from "node:fs";
77934
- import { dirname as dirname35, join as join40 } from "node:path";
78118
+ import { dirname as dirname35, join as join41 } from "node:path";
77935
78119
  function path(dir) {
77936
78120
  const namespace = resolveRuntimeNamespace();
77937
78121
  if (namespace.development) {
77938
78122
  const identity2 = createHash23("sha256").update(realpathSync21(dir)).digest("hex");
77939
- return runtimeOwnedPath(join40(namespace.stateHome, "projects", identity2, "terminals.json"));
78123
+ return runtimeOwnedPath(join41(namespace.stateHome, "projects", identity2, "terminals.json"));
77940
78124
  }
77941
- return join40(dir, TERMINALS_FILE);
78125
+ return join41(dir, TERMINALS_FILE);
77942
78126
  }
77943
78127
  function ensureDir(dir) {
77944
78128
  mkdirSync27(dirname35(path(dir)), { recursive: true });
@@ -78029,7 +78213,7 @@ __export(auth_service_exports, {
78029
78213
  });
78030
78214
  import * as crypto2 from "node:crypto";
78031
78215
  import { readFileSync as readFileSync30, existsSync as existsSync29 } from "node:fs";
78032
- import { join as join41 } from "node:path";
78216
+ import { join as join42 } from "node:path";
78033
78217
  import { homedir as homedir5 } from "node:os";
78034
78218
  function base64url(buf) {
78035
78219
  const b = typeof buf === "string" ? Buffer.from(buf) : buf;
@@ -78048,8 +78232,8 @@ function signJwt(payload, secret, expiresInSec) {
78048
78232
  segments.push(base64url(sig));
78049
78233
  return segments.join(".");
78050
78234
  }
78051
- function verifyJwt(token, secret) {
78052
- const parts = token.split(".");
78235
+ function verifyJwt(token2, secret) {
78236
+ const parts = token2.split(".");
78053
78237
  if (parts.length !== 3) return { valid: false };
78054
78238
  const sigInput = parts[0] + "." + parts[1];
78055
78239
  const expected = crypto2.createHmac("sha256", secret).update(sigInput).digest();
@@ -78098,8 +78282,8 @@ var init_auth_service = __esm({
78098
78282
  generateToken(userId) {
78099
78283
  return signJwt({ userId }, this.jwtSecret, TOKEN_EXPIRY_SEC);
78100
78284
  }
78101
- verifyToken(token) {
78102
- const result2 = verifyJwt(token, this.jwtSecret);
78285
+ verifyToken(token2) {
78286
+ const result2 = verifyJwt(token2, this.jwtSecret);
78103
78287
  if (!result2.valid) return { valid: false };
78104
78288
  return { valid: true, userId: result2.payload.userId };
78105
78289
  }
@@ -78129,8 +78313,8 @@ var init_auth_service = __esm({
78129
78313
  return { success: false, error: "SSH key not authorized for this user" };
78130
78314
  }
78131
78315
  this.challenges.delete(auth.challengeId);
78132
- const token = this.generateToken(challenge.userId);
78133
- return { success: true, userId: challenge.userId, token };
78316
+ const token2 = this.generateToken(challenge.userId);
78317
+ return { success: true, userId: challenge.userId, token: token2 };
78134
78318
  }
78135
78319
  // ---- SSH helpers -------------------------------------------------------
78136
78320
  verifySSHSignature(challenge, signature, publicKeyStr) {
@@ -78175,7 +78359,7 @@ var init_auth_service = __esm({
78175
78359
  if (resolveRuntimeNamespace().development) return false;
78176
78360
  try {
78177
78361
  const home = userId === process.env.USER ? homedir5() : `/home/${userId}`;
78178
- const authKeysPath = join41(home, ".ssh", "authorized_keys");
78362
+ const authKeysPath = join42(home, ".ssh", "authorized_keys");
78179
78363
  if (!existsSync29(authKeysPath)) return false;
78180
78364
  const authorizedKeys = readFileSync30(authKeysPath, "utf-8");
78181
78365
  const parts = publicKey.trim().split(" ");
@@ -78206,8 +78390,8 @@ function authMiddleware(authService, config2) {
78206
78390
  if (!authHeader?.startsWith("Bearer ")) {
78207
78391
  return c.json({ error: "Missing or invalid Authorization header" }, 401);
78208
78392
  }
78209
- const token = authHeader.slice(7);
78210
- const result2 = authService.verifyToken(token);
78393
+ const token2 = authHeader.slice(7);
78394
+ const result2 = authService.verifyToken(token2);
78211
78395
  if (!result2.valid) {
78212
78396
  return c.json({ error: "Invalid or expired token" }, 401);
78213
78397
  }
@@ -81201,7 +81385,7 @@ var init_inspect = __esm({
81201
81385
  // packages/daemon/src/lib/filesystem-browser.ts
81202
81386
  import { realpathSync as realpathSync22, readdirSync as readdirSync6, statSync as statSync19 } from "node:fs";
81203
81387
  import { homedir as homedir6 } from "node:os";
81204
- import { isAbsolute as isAbsolute20, join as join42, resolve as resolve29, sep as sep10 } from "node:path";
81388
+ import { isAbsolute as isAbsolute20, join as join43, resolve as resolve29, sep as sep10 } from "node:path";
81205
81389
  function isUnderRoot(canonical, root) {
81206
81390
  if (canonical === root) return true;
81207
81391
  const prefix = root.endsWith(sep10) ? root : root + sep10;
@@ -81236,7 +81420,7 @@ __export(detect_exports, {
81236
81420
  detectStack: () => detectStack,
81237
81421
  suggestConfig: () => suggestConfig
81238
81422
  });
81239
- import { resolve as resolve30, basename as basename13 } from "node:path";
81423
+ import { resolve as resolve30, basename as basename14 } from "node:path";
81240
81424
  import { readFileSync as readFileSync31, existsSync as existsSync31 } from "node:fs";
81241
81425
  function fileExists(dir, name) {
81242
81426
  return existsSync31(resolve30(dir, name));
@@ -81338,7 +81522,7 @@ function detectStack(dir) {
81338
81522
  return detected;
81339
81523
  }
81340
81524
  function suggestConfig(dir, detected) {
81341
- const name = basename13(dir);
81525
+ const name = basename14(dir);
81342
81526
  const pm = detected.packageManager ?? "npm";
81343
81527
  const run = pm === "npm" ? "npm run" : pm;
81344
81528
  const config2 = {
@@ -81642,7 +81826,7 @@ var init_workspace_resource_ids = __esm({
81642
81826
 
81643
81827
  // packages/daemon/src/command-center/resources/workspace-files-authority.ts
81644
81828
  import { lstatSync as lstatSync13, readdirSync as readdirSync7, readFileSync as readFileSync32, realpathSync as realpathSync23 } from "node:fs";
81645
- import { basename as basename14, dirname as dirname37, resolve as resolvePath, sep as sep11 } from "node:path";
81829
+ import { basename as basename15, dirname as dirname37, resolve as resolvePath, sep as sep11 } from "node:path";
81646
81830
  import ignore from "ignore";
81647
81831
  function extensionOf(name) {
81648
81832
  const dot = name.lastIndexOf(".");
@@ -81895,7 +82079,7 @@ var init_workspace_files_authority = __esm({
81895
82079
  if (WorkspaceFileEntrySafe(entry)) entries.push(entry);
81896
82080
  }
81897
82081
  const truncated = totalEntries > entries.length;
81898
- const rootLabel = safeName(basename14(realRoot), "workspace");
82082
+ const rootLabel = safeName(basename15(realRoot), "workspace");
81899
82083
  const revision = filesRevision(
81900
82084
  JSON.stringify({ dir: relPath, entries: entries.map((e) => `${e.name}:${e.kind}`) })
81901
82085
  );
@@ -81905,7 +82089,7 @@ var init_workspace_files_authority = __esm({
81905
82089
  }
81906
82090
  const directory = relPath === "" ? { id: rootId, name: rootLabel, relativePath: null, parentId: null } : {
81907
82091
  id: targetId,
81908
- name: safeName(basename14(relPath), rootLabel),
82092
+ name: safeName(basename15(relPath), rootLabel),
81909
82093
  relativePath: relPath,
81910
82094
  parentId: this.parentId(rootId, relPath)
81911
82095
  };
@@ -81998,7 +82182,7 @@ var init_workspace_files_authority = __esm({
81998
82182
  "The requested file is unavailable."
81999
82183
  );
82000
82184
  }
82001
- if (!isWithin2(realRoot, resolvePath(realParent, basename14(abs)))) {
82185
+ if (!isWithin2(realRoot, resolvePath(realParent, basename15(abs)))) {
82002
82186
  return this.previewUnavailable(
82003
82187
  fileId,
82004
82188
  "outside-workspace",
@@ -82008,7 +82192,7 @@ var init_workspace_files_authority = __esm({
82008
82192
  if (stat3.isDirectory() || !stat3.isFile()) {
82009
82193
  return this.previewUnavailable(fileId, "not-a-file", "The resource is not a regular file.");
82010
82194
  }
82011
- const name = basename14(relPath);
82195
+ const name = basename15(relPath);
82012
82196
  const catalogRevision = filesRevision(`${relPath}:${stat3.size}:${stat3.mtimeMs}`);
82013
82197
  const totalBytes = stat3.size;
82014
82198
  if (totalBytes > WORKSPACE_FILE_PREVIEW_MAX_CHARACTERS) {
@@ -82156,11 +82340,11 @@ function parseStatusV2(buffer) {
82156
82340
  let detached = false;
82157
82341
  const changes = [];
82158
82342
  for (let i = 0; i < tokens.length; i += 1) {
82159
- const token = tokens[i];
82160
- if (token.length === 0) continue;
82161
- if (token.startsWith("# ")) {
82162
- if (token.startsWith("# branch.head ")) {
82163
- const value = token.slice("# branch.head ".length);
82343
+ const token2 = tokens[i];
82344
+ if (token2.length === 0) continue;
82345
+ if (token2.startsWith("# ")) {
82346
+ if (token2.startsWith("# branch.head ")) {
82347
+ const value = token2.slice("# branch.head ".length);
82164
82348
  if (value === "(detached)") {
82165
82349
  detached = true;
82166
82350
  branch = null;
@@ -82170,9 +82354,9 @@ function parseStatusV2(buffer) {
82170
82354
  }
82171
82355
  continue;
82172
82356
  }
82173
- const type = token[0];
82357
+ const type = token2[0];
82174
82358
  if (type === "1" || type === "2") {
82175
- const fields = token.split(" ");
82359
+ const fields = token2.split(" ");
82176
82360
  const xy = fields[1] ?? "..";
82177
82361
  const pathFrom = type === "1" ? 8 : 9;
82178
82362
  const path2 = fields.slice(pathFrom).join(" ");
@@ -82206,13 +82390,13 @@ function parseStatusV2(buffer) {
82206
82390
  }
82207
82391
  }
82208
82392
  } else if (type === "u") {
82209
- const fields = token.split(" ");
82393
+ const fields = token2.split(" ");
82210
82394
  const path2 = fields.slice(10).join(" ");
82211
82395
  if (path2.length > 0) {
82212
82396
  changes.push({ group: "unstaged", status: "conflicted", path: path2, originPath: null });
82213
82397
  }
82214
82398
  } else if (type === "?") {
82215
- const path2 = token.slice(2);
82399
+ const path2 = token2.slice(2);
82216
82400
  if (path2.length > 0) {
82217
82401
  changes.push({ group: "untracked", status: "untracked", path: path2, originPath: null });
82218
82402
  }
@@ -82224,9 +82408,9 @@ function parseNumstatZ(buffer) {
82224
82408
  const tokens = splitNul(buffer);
82225
82409
  const map = /* @__PURE__ */ new Map();
82226
82410
  for (let i = 0; i < tokens.length; i += 1) {
82227
- const token = tokens[i];
82228
- if (token.length === 0) continue;
82229
- const parts = token.split(" ");
82411
+ const token2 = tokens[i];
82412
+ if (token2.length === 0) continue;
82413
+ const parts = token2.split(" ");
82230
82414
  if (parts.length < 3) continue;
82231
82415
  const addRaw = parts[0];
82232
82416
  const delRaw = parts[1];
@@ -82316,7 +82500,7 @@ var init_workspace_changes_git = __esm({
82316
82500
  // packages/daemon/src/command-center/resources/workspace-changes-authority.ts
82317
82501
  import { spawnSync } from "node:child_process";
82318
82502
  import { readFileSync as readFileSync33, realpathSync as realpathSync24, statSync as statSync20 } from "node:fs";
82319
- import { basename as basename15, isAbsolute as isAbsolute22, relative as relative7, resolve as resolvePath2 } from "node:path";
82503
+ import { basename as basename16, isAbsolute as isAbsolute22, relative as relative7, resolve as resolvePath2 } from "node:path";
82320
82504
  function runGit(args, cwd) {
82321
82505
  const result2 = spawnSync("git", args, {
82322
82506
  cwd,
@@ -82370,7 +82554,7 @@ function buildChangeEntry(raw, displayPath, originPath, counts) {
82370
82554
  id: changeResourceId(raw.group, displayPath),
82371
82555
  group: raw.group,
82372
82556
  status: raw.status,
82373
- name: basename15(displayPath),
82557
+ name: basename16(displayPath),
82374
82558
  relativePath: displayPath,
82375
82559
  originPath: carriesOrigin ? originPath ?? null : null,
82376
82560
  binary: counts.binary,
@@ -83949,13 +84133,13 @@ function mountFleetResourceRoute(app, options) {
83949
84133
  unavailableMessage: "Fleet catalog capability is unavailable",
83950
84134
  mismatchMessage: "Fleet catalog access requires owner authority"
83951
84135
  });
83952
- app.get("/api/resources/fleet-catalog", (c) => {
84136
+ app.get("/api/resources/fleet-catalog", async (c) => {
83953
84137
  const gate = authorize(c);
83954
84138
  if (gate) return gate;
83955
84139
  c.header("Cache-Control", "no-store");
83956
84140
  let sessions;
83957
84141
  try {
83958
- sessions = options.readFleet ? options.readFleet() : readAdoptedFleet(options.registry);
84142
+ sessions = options.readFleet ? await options.readFleet() : readAdoptedFleet(options.registry);
83959
84143
  } catch {
83960
84144
  sessions = null;
83961
84145
  }
@@ -84003,8 +84187,8 @@ function nodeLabel(value) {
84003
84187
  return normalized.length > 0 ? normalized : null;
84004
84188
  }
84005
84189
  function groupId(missionId) {
84006
- const token = createHash27("sha256").update(missionId).digest("hex").slice(0, 32);
84007
- return `group.${token}`;
84190
+ const token2 = createHash27("sha256").update(missionId).digest("hex").slice(0, 32);
84191
+ return `group.${token2}`;
84008
84192
  }
84009
84193
  function projectApplicationShellAgentGraphOverlay(input) {
84010
84194
  const { session, appWindows, missionSnapshot, nowSec } = input;
@@ -84035,7 +84219,7 @@ function projectApplicationShellAgentGraphOverlay(input) {
84035
84219
  status: nodeStatus(presentation.detectStatus),
84036
84220
  statusSource: presentation.statusSource,
84037
84221
  attention: presentation.attention,
84038
- label: nodeLabel(presentation.displayName ?? pane.name ?? pane.title)
84222
+ label: nodeLabel(resolvedAgentLabel(pane, presentation, index))
84039
84223
  });
84040
84224
  nodeWindowIds.add(windowId);
84041
84225
  if (pane.role === "lead") leadWindowIds.push(windowId);
@@ -84588,9 +84772,9 @@ import {
84588
84772
  rmSync as rmSync5,
84589
84773
  writeFileSync as writeFileSync25
84590
84774
  } from "node:fs";
84591
- import { join as join43 } from "node:path";
84775
+ import { join as join44 } from "node:path";
84592
84776
  function assetRoot() {
84593
- return runtimeOwnedPath(join43(stateHome(), ASSET_DIRECTORY));
84777
+ return runtimeOwnedPath(join44(stateHome(), ASSET_DIRECTORY));
84594
84778
  }
84595
84779
  function ensureAssetRoot() {
84596
84780
  const root = assetRoot();
@@ -84610,8 +84794,8 @@ function safeName2(name) {
84610
84794
  }
84611
84795
  function assetPaths(root, assetId) {
84612
84796
  return {
84613
- data: join43(root, `${assetId}.bin`),
84614
- metadata: join43(root, `${assetId}.json`)
84797
+ data: join44(root, `${assetId}.bin`),
84798
+ metadata: join44(root, `${assetId}.json`)
84615
84799
  };
84616
84800
  }
84617
84801
  function parseMetadata(raw) {
@@ -84636,7 +84820,7 @@ function parseMetadata(raw) {
84636
84820
  }
84637
84821
  function pruneAssets(root, now = Date.now()) {
84638
84822
  const metadataFiles = readdirSync8(root).filter((name) => /^[0-9a-f]{64}\.json$/u.test(name)).map((name) => {
84639
- const path2 = join43(root, name);
84823
+ const path2 = join44(root, name);
84640
84824
  try {
84641
84825
  const stat3 = lstatSync14(path2);
84642
84826
  return stat3.isFile() && !stat3.isSymbolicLink() ? { name, mtimeMs: stat3.mtimeMs } : null;
@@ -84647,8 +84831,8 @@ function pruneAssets(root, now = Date.now()) {
84647
84831
  for (const [index, entry] of metadataFiles.entries()) {
84648
84832
  if (index < MAX_ASSET_FILES && now - entry.mtimeMs <= WIDGET_ASSET_RETENTION_MS) continue;
84649
84833
  const assetId = entry.name.slice(0, -".json".length);
84650
- rmSync5(join43(root, `${assetId}.json`), { force: true });
84651
- rmSync5(join43(root, `${assetId}.bin`), { force: true });
84834
+ rmSync5(join44(root, `${assetId}.json`), { force: true });
84835
+ rmSync5(join44(root, `${assetId}.bin`), { force: true });
84652
84836
  }
84653
84837
  }
84654
84838
  function publishWidgetAsset(bytes, options) {
@@ -84677,11 +84861,11 @@ function publishWidgetAsset(bytes, options) {
84677
84861
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
84678
84862
  };
84679
84863
  if (!existsSync33(paths.data)) {
84680
- const temporary = join43(root, `.${assetId}.${randomUUID37()}.bin`);
84864
+ const temporary = join44(root, `.${assetId}.${randomUUID37()}.bin`);
84681
84865
  writeFileSync25(temporary, bytes, { mode: 384, flag: "wx" });
84682
84866
  renameSync18(temporary, paths.data);
84683
84867
  }
84684
- const metadataTemporary = join43(root, `.${assetId}.${randomUUID37()}.json`);
84868
+ const metadataTemporary = join44(root, `.${assetId}.${randomUUID37()}.json`);
84685
84869
  writeFileSync25(metadataTemporary, `${JSON.stringify(metadata)}
84686
84870
  `, { mode: 384, flag: "wx" });
84687
84871
  renameSync18(metadataTemporary, paths.metadata);
@@ -84743,7 +84927,7 @@ __export(server_exports2, {
84743
84927
  import { execFile as execFile14 } from "node:child_process";
84744
84928
  import { promisify as promisify4 } from "node:util";
84745
84929
  import { existsSync as existsSync34, readdirSync as readdirSync9 } from "node:fs";
84746
- import { join as join44, dirname as dirname38, basename as basename16 } from "node:path";
84930
+ import { join as join45, dirname as dirname38, basename as basename17 } from "node:path";
84747
84931
  import { fileURLToPath as fileURLToPath9 } from "node:url";
84748
84932
  import { Hono as Hono3 } from "hono";
84749
84933
  import { streamSSE as streamSSE3 } from "hono/streaming";
@@ -84772,12 +84956,12 @@ function workspaceDockSummary(projectDir, workspaceName) {
84772
84956
  changeCount: safeCount(() => new ChangesAuthority(projectDir, workspaceName).changeCount())
84773
84957
  };
84774
84958
  }
84775
- function requireAuth(token, localBypassToken) {
84959
+ function requireAuth(token2, localBypassToken) {
84776
84960
  return async (c, next) => {
84777
- if (!token) return next();
84961
+ if (!token2) return next();
84778
84962
  const url = new URL(c.req.url);
84779
84963
  const suppliedToken = bearerToken(c.req.header("Authorization")) ?? url.searchParams.get("token");
84780
- if (suppliedToken === token || localBypassToken && suppliedToken === localBypassToken) {
84964
+ if (suppliedToken === token2 || localBypassToken && suppliedToken === localBypassToken) {
84781
84965
  return next();
84782
84966
  }
84783
84967
  return c.json({ error: "Remote access token required" }, 401);
@@ -84971,8 +85155,8 @@ function createApp(options = {}) {
84971
85155
  }
84972
85156
  const body = await c.req.json();
84973
85157
  const userId = body.userId ?? authService.getCurrentUser();
84974
- const token = authService.generateToken(userId);
84975
- return c.json({ token, userId });
85158
+ const token2 = authService.generateToken(userId);
85159
+ return c.json({ token: token2, userId });
84976
85160
  });
84977
85161
  app.post(
84978
85162
  "/api/v2/capabilities",
@@ -85170,7 +85354,7 @@ function createApp(options = {}) {
85170
85354
  app.post("/api/workspaces", zValidator("json", AddWorkspaceRequestSchemaZ), async (c) => {
85171
85355
  const body = c.req.valid("json");
85172
85356
  const registry = getDefaultWorkspaceRegistry();
85173
- const name = body.name ?? basename16(body.projectDir);
85357
+ const name = body.name ?? basename17(body.projectDir);
85174
85358
  if (!name || name.length === 0) {
85175
85359
  return c.json({ error: "Cannot derive workspace name from projectDir" }, 400);
85176
85360
  }
@@ -85988,7 +86172,7 @@ function listAvailableTemplates() {
85988
86172
  const __filename = fileURLToPath9(import.meta.url);
85989
86173
  const __dir = dirname38(__filename);
85990
86174
  const configuredTemplatesDir = process.env.TMUX_IDE_TEMPLATES_DIR;
85991
- const templatesDir = configuredTemplatesDir && isAbsolute23(configuredTemplatesDir) ? configuredTemplatesDir : join44(__dir, "..", "..", "..", "..", "templates");
86175
+ const templatesDir = configuredTemplatesDir && isAbsolute23(configuredTemplatesDir) ? configuredTemplatesDir : join45(__dir, "..", "..", "..", "..", "templates");
85992
86176
  if (!existsSync34(templatesDir)) return [];
85993
86177
  const labels = {
85994
86178
  default: { label: "Default", description: "Single Claude pane + dev/shell row" },
@@ -86184,6 +86368,7 @@ var init_types = __esm({
86184
86368
  });
86185
86369
 
86186
86370
  // packages/daemon/src/lib/daemon-embed.ts
86371
+ import { join as join46 } from "node:path";
86187
86372
  import { execFileSync as execFileSync20 } from "node:child_process";
86188
86373
  import { randomBytes as randomBytes8, randomUUID as randomUUID39 } from "node:crypto";
86189
86374
  import { createWriteStream } from "node:fs";
@@ -86304,11 +86489,11 @@ function isLoopbackRequest(req) {
86304
86489
  function isLoopbackBind(bindHostname) {
86305
86490
  return bindHostname === "127.0.0.1" || bindHostname === "::1" || bindHostname === "localhost";
86306
86491
  }
86307
- function isUpgradeAuthorized(req, token, localBypassToken, bindHostname) {
86308
- if (!token) return true;
86492
+ function isUpgradeAuthorized(req, token2, localBypassToken, bindHostname) {
86493
+ if (!token2) return true;
86309
86494
  if (isLoopbackBind(bindHostname) && isLoopbackRequest(req)) return true;
86310
86495
  const supplied = requestToken(req);
86311
- return supplied === token || localBypassToken != null && supplied === localBypassToken;
86496
+ return supplied === token2 || localBypassToken != null && supplied === localBypassToken;
86312
86497
  }
86313
86498
  function rejectUpgradeWithPolicy(wss, req, socket, head3) {
86314
86499
  wss.handleUpgrade(req, socket, head3, (ws) => {
@@ -86841,6 +87026,9 @@ async function startEmbeddedDaemonGeneration(opts) {
86841
87026
  }
86842
87027
  }
86843
87028
  const tmuxAuthority = resolveWorkspacePaneTmuxAuthority();
87029
+ const readTeamNames = createClaudeTeamNameReader(
87030
+ join46(resolveRuntimeNamespace().claudeDir, "teams")
87031
+ );
86844
87032
  const catalogTmuxRunner = createPinnedWorkspaceTmuxRunner(tmuxAuthority);
86845
87033
  const initialTmuxProof = captureTmuxServerProof(catalogTmuxRunner);
86846
87034
  const initialNativeIdentityParts = initialTmuxProof ? catalogTmuxRunner(["display-message", "-p", "#{pid} #{start_time}"]).split(" ") : null;
@@ -87253,6 +87441,7 @@ async function startEmbeddedDaemonGeneration(opts) {
87253
87441
  },
87254
87442
  agentStatusProbeFactory: ({ run }) => createTmuxAgentStatusProbe({
87255
87443
  run,
87444
+ readTeamNames,
87256
87445
  captureNative: (pane, signal) => backgroundCapture?.(
87257
87446
  {
87258
87447
  paneId: pane.runtimePaneId,
@@ -87514,16 +87703,34 @@ async function startEmbeddedDaemonGeneration(opts) {
87514
87703
  peekTerminalAttachmentRuntime,
87515
87704
  paneStreamRuntime,
87516
87705
  catalogLiveSessions: () => discoverLiveSessionSummaries(catalogTmuxRunner),
87517
- catalogFleet: () => readAdoptedFleet(
87518
- workspaceRegistry,
87519
- nativeGenerationTmuxRunner,
87520
- (sessionName2, pane) => pane.semanticPaneId ? interactionEvidence?.captureInventoryEndpoint(
87521
- sessionName2,
87522
- pane.runtimePaneId,
87523
- pane.semanticPaneId
87524
- ) ?? null : null,
87525
- () => observationSelector?.nativeServerEpoch ?? null
87526
- ),
87706
+ catalogFleet: async () => {
87707
+ const fleet = readAdoptedFleet(
87708
+ workspaceRegistry,
87709
+ nativeGenerationTmuxRunner,
87710
+ (sessionName2, pane) => pane.semanticPaneId ? interactionEvidence?.captureInventoryEndpoint(
87711
+ sessionName2,
87712
+ pane.runtimePaneId,
87713
+ pane.semanticPaneId
87714
+ ) ?? null : null,
87715
+ () => observationSelector?.nativeServerEpoch ?? null
87716
+ );
87717
+ if (!fleet) return null;
87718
+ const names = await readTeamNames(
87719
+ fleet.flatMap(
87720
+ (session) => session.panes.map((pane) => ({
87721
+ runtimePaneId: pane.runtimePaneId,
87722
+ pid: pane.incarnation
87723
+ }))
87724
+ )
87725
+ );
87726
+ return fleet.map((session) => ({
87727
+ ...session,
87728
+ panes: session.panes.map((pane) => {
87729
+ const name = names.get(pane.runtimePaneId);
87730
+ return name ? { ...pane, teamMemberName: name } : pane;
87731
+ })
87732
+ }));
87733
+ },
87527
87734
  fleetPreviewCapture: createFleetPreviewCapture(fleetFactsTmuxRunner, {
87528
87735
  serverEpoch: () => observationSelector?.nativeServerEpoch ?? null,
87529
87736
  capture: (request3, signal) => backgroundCapture?.(request3, signal) ?? Promise.resolve(null)
@@ -87903,6 +88110,7 @@ var requireFromHere2, DEFAULT_HOSTNAME, DEFAULT_GRACEFUL_MS, EMBEDDED_SESSION_NA
87903
88110
  var init_daemon_embed = __esm({
87904
88111
  "packages/daemon/src/lib/daemon-embed.ts"() {
87905
88112
  "use strict";
88113
+ init_claude_team_names();
87906
88114
  init_pane_source_discovery();
87907
88115
  init_background_native_capture();
87908
88116
  init_owned_viewer_factory();
@@ -88343,7 +88551,7 @@ __export(development_owner_exports, {
88343
88551
  verifyManagedDevelopmentAdmission: () => verifyManagedDevelopmentAdmission
88344
88552
  });
88345
88553
  import { realpathSync as realpathSync26, writeFileSync as writeFileSync26 } from "node:fs";
88346
- import { join as join45 } from "node:path";
88554
+ import { join as join47 } from "node:path";
88347
88555
  async function claimManagedDevelopmentLaunch(instance, attempt) {
88348
88556
  if (!/^[a-f0-9-]{36}$/u.test(attempt)) throw new Error("Invalid development launch attempt");
88349
88557
  const owner = readDevelopmentOwner(instance);
@@ -88351,7 +88559,7 @@ async function claimManagedDevelopmentLaunch(instance, attempt) {
88351
88559
  throw new Error("A live or unknown managed owner is protected");
88352
88560
  requireDevelopmentNotSuspended(instance);
88353
88561
  writeFileSync26(
88354
- join45(instance.root, `launch-${attempt}.json`),
88562
+ join47(instance.root, `launch-${attempt}.json`),
88355
88563
  JSON.stringify({ version: 1, attempt, pid: process.pid }),
88356
88564
  { flag: "wx", mode: 384 }
88357
88565
  );
@@ -88360,7 +88568,7 @@ async function claimManagedDevelopmentLaunch(instance, attempt) {
88360
88568
  function verifyManagedDevelopmentAdmission(instance, attempt, expected) {
88361
88569
  requireDevelopmentNotSuspended(instance);
88362
88570
  const current = readPrivateDevelopmentRecord(
88363
- join45(instance.root, "startup.json")
88571
+ join47(instance.root, "startup.json")
88364
88572
  );
88365
88573
  if (!current || current.attempt !== attempt || current.attempt !== expected.attempt || current.generation !== expected.generation || current.manifestHash !== expected.manifestHash)
88366
88574
  throw new Error("Managed owner admission changed before startup");
@@ -88371,7 +88579,7 @@ async function runManagedDevelopmentOwner() {
88371
88579
  if (!instance) throw new Error("Managed development owner requires a development namespace");
88372
88580
  const identity2 = await readDevelopmentIdentity(instance);
88373
88581
  const attempt = process.env.TMUX_IDE_DEVELOPMENT_ATTEMPT;
88374
- const pending = readPrivateDevelopmentRecord(join45(instance.root, "startup.json"));
88582
+ const pending = readPrivateDevelopmentRecord(join47(instance.root, "startup.json"));
88375
88583
  const build = readDevelopmentBuild(instance);
88376
88584
  if (!identity2 || identity2.capability !== namespace.cleanupToken || !attempt || pending?.attempt !== attempt || pending.generation !== build.generation || pending.manifestHash !== process.env.TMUX_IDE_DEVELOPMENT_BUILD_HASH)
88377
88585
  throw new Error("Development launch admission does not match owner");
@@ -88381,7 +88589,7 @@ async function runManagedDevelopmentOwner() {
88381
88589
  if (!incarnation) throw new Error("Cannot establish managed owner incarnation");
88382
88590
  await claimManagedDevelopmentLaunch(instance, attempt);
88383
88591
  verifyManagedDevelopmentAdmission(instance, attempt, pending);
88384
- const log = createBoundedDevelopmentLog(join45(instance.root, "logs/owner.log"));
88592
+ const log = createBoundedDevelopmentLog(join47(instance.root, "logs/owner.log"));
88385
88593
  const originalOut = process.stdout.write;
88386
88594
  const originalErr = process.stderr.write;
88387
88595
  const writer = ((chunk, encodingOrCallback, callback) => {
@@ -88398,7 +88606,7 @@ async function runManagedDevelopmentOwner() {
88398
88606
  json: true,
88399
88607
  expectedVersion: build.packageVersion,
88400
88608
  onOwnedReady: () => {
88401
- writeDevelopmentRecord(join45(instance.root, "owner.json"), {
88609
+ writeDevelopmentRecord(join47(instance.root, "owner.json"), {
88402
88610
  version: 1,
88403
88611
  attempt,
88404
88612
  pid: process.pid,
@@ -88445,7 +88653,7 @@ import {
88445
88653
  readdirSync as readdirSync10,
88446
88654
  copyFileSync as copyFileSync2
88447
88655
  } from "node:fs";
88448
- import { resolve as resolve32, join as join46, basename as basename17, dirname as dirname39 } from "node:path";
88656
+ import { resolve as resolve32, join as join48, basename as basename18, dirname as dirname39 } from "node:path";
88449
88657
  import { fileURLToPath as fileURLToPath10 } from "node:url";
88450
88658
  function copyTemplateSkills(targetDir) {
88451
88659
  const created = [];
@@ -88454,20 +88662,20 @@ function copyTemplateSkills(targetDir) {
88454
88662
  mkdirSync29(targetDir, { recursive: true });
88455
88663
  for (const file of readdirSync10(templateSkillsDir)) {
88456
88664
  if (!file.endsWith(".md")) continue;
88457
- const destination = join46(targetDir, file);
88458
- copyFileSync2(join46(templateSkillsDir, file), destination);
88665
+ const destination = join48(targetDir, file);
88666
+ copyFileSync2(join48(templateSkillsDir, file), destination);
88459
88667
  created.push(destination);
88460
88668
  }
88461
88669
  return created;
88462
88670
  }
88463
88671
  function scaffoldLibraryStubs(dir) {
88464
88672
  const created = [];
88465
- const libraryDir = join46(dir, ".tmux-ide", "library");
88673
+ const libraryDir = join48(dir, ".tmux-ide", "library");
88466
88674
  if (!existsSync35(libraryDir)) {
88467
88675
  mkdirSync29(libraryDir, { recursive: true });
88468
88676
  created.push(libraryDir);
88469
88677
  }
88470
- const archPath = join46(libraryDir, "architecture.md");
88678
+ const archPath = join48(libraryDir, "architecture.md");
88471
88679
  if (!existsSync35(archPath)) {
88472
88680
  writeFileSync27(
88473
88681
  archPath,
@@ -88475,7 +88683,7 @@ function scaffoldLibraryStubs(dir) {
88475
88683
  );
88476
88684
  created.push(archPath);
88477
88685
  }
88478
- const learningsPath = join46(libraryDir, "learnings.md");
88686
+ const learningsPath = join48(libraryDir, "learnings.md");
88479
88687
  if (!existsSync35(learningsPath)) {
88480
88688
  writeFileSync27(
88481
88689
  learningsPath,
@@ -88487,11 +88695,11 @@ function scaffoldLibraryStubs(dir) {
88487
88695
  }
88488
88696
  function scaffoldValidationContract(dir) {
88489
88697
  const created = [];
88490
- const tasksDir = join46(dir, ".tasks");
88698
+ const tasksDir = join48(dir, ".tasks");
88491
88699
  if (!existsSync35(tasksDir)) {
88492
88700
  mkdirSync29(tasksDir, { recursive: true });
88493
88701
  }
88494
- const contractPath = join46(tasksDir, "validation-contract.md");
88702
+ const contractPath = join48(tasksDir, "validation-contract.md");
88495
88703
  if (!existsSync35(contractPath)) {
88496
88704
  writeFileSync27(
88497
88705
  contractPath,
@@ -88505,7 +88713,7 @@ function scaffoldAgentsMd(dir, name) {
88505
88713
  const created = [];
88506
88714
  const agentsTemplatePath = resolve32(__dirname4, "..", "..", "..", "templates", "AGENTS.md");
88507
88715
  if (existsSync35(agentsTemplatePath)) {
88508
- const agentsPath = join46(dir, "AGENTS.md");
88716
+ const agentsPath = join48(dir, "AGENTS.md");
88509
88717
  if (!existsSync35(agentsPath)) {
88510
88718
  const content = readFileSync35(agentsTemplatePath, "utf-8").replace(/{{name}}/g, name);
88511
88719
  writeFileSync27(agentsPath, content);
@@ -88526,7 +88734,7 @@ function scaffoldTeamWorkspace(dir, name) {
88526
88734
  }
88527
88735
  function scaffoldMissionsWorkspace(dir, name) {
88528
88736
  const created = [];
88529
- const skillsDir = join46(dir, ".tmux-ide", "skills");
88737
+ const skillsDir = join48(dir, ".tmux-ide", "skills");
88530
88738
  created.push(...copyTemplateSkills(skillsDir));
88531
88739
  created.push(...scaffoldTeamWorkspace(dir, name));
88532
88740
  return created;
@@ -88547,7 +88755,7 @@ async function init({
88547
88755
  outputError(`Template "${template}" not found`, "NOT_FOUND");
88548
88756
  }
88549
88757
  let content = readFileSync35(templatePath, "utf-8");
88550
- const name2 = basename17(dir);
88758
+ const name2 = basename18(dir);
88551
88759
  content = content.replace(/^name: .+/m, `name: ${name2}`);
88552
88760
  const yaml6 = (await import("js-yaml")).default;
88553
88761
  const workspace = WorkspaceConfigV1SchemaZ.parse(yaml6.load(content));
@@ -88558,11 +88766,11 @@ async function init({
88558
88766
  created = scaffoldMissionsWorkspace(dir, name2);
88559
88767
  } else if (isTeamTemplate(template)) {
88560
88768
  created = [
88561
- ...copyTemplateSkills(join46(dir, ".tmux-ide", "skills")),
88769
+ ...copyTemplateSkills(join48(dir, ".tmux-ide", "skills")),
88562
88770
  ...scaffoldTeamWorkspace(dir, name2)
88563
88771
  ];
88564
88772
  } else {
88565
- created = copyTemplateSkills(join46(dir, ".tmux-ide", "skills"));
88773
+ created = copyTemplateSkills(join48(dir, ".tmux-ide", "skills"));
88566
88774
  }
88567
88775
  if (json2) {
88568
88776
  console.log(JSON.stringify({ created: true, template, name: name2, paths: created }));
@@ -88576,7 +88784,7 @@ async function init({
88576
88784
  return;
88577
88785
  }
88578
88786
  const detected = detectStack(dir);
88579
- const name = basename17(dir);
88787
+ const name = basename18(dir);
88580
88788
  if (detected.frameworks.length > 0) {
88581
88789
  const config2 = suggestConfig(dir, detected);
88582
88790
  writeConfig(dir, config2);
@@ -88604,7 +88812,7 @@ async function init({
88604
88812
  console.log("Edit it to configure your workspace, then run: tmux-ide");
88605
88813
  }
88606
88814
  }
88607
- const skillsDir = join46(dir, ".tmux-ide", "skills");
88815
+ const skillsDir = join48(dir, ".tmux-ide", "skills");
88608
88816
  if (!existsSync35(skillsDir)) {
88609
88817
  const created = copyTemplateSkills(skillsDir);
88610
88818
  if (created.length > 0 && !json2) {
@@ -89203,23 +89411,23 @@ __export(skill_sync_exports, {
89203
89411
  versionMarker: () => versionMarker
89204
89412
  });
89205
89413
  import { existsSync as existsSync36, mkdirSync as mkdirSync30, readFileSync as readFileSync36, writeFileSync as writeFileSync28 } from "node:fs";
89206
- import { dirname as dirname40, join as join47 } from "node:path";
89414
+ import { dirname as dirname40, join as join49 } from "node:path";
89207
89415
  import { fileURLToPath as fileURLToPath11 } from "node:url";
89208
89416
  function claudeDir() {
89209
89417
  return resolveRuntimeNamespace().claudeDir;
89210
89418
  }
89211
89419
  function skillTargetDir() {
89212
- return runtimeOwnedPath(join47(claudeDir(), "skills", "tmux-ide"));
89420
+ return runtimeOwnedPath(join49(claudeDir(), "skills", "tmux-ide"));
89213
89421
  }
89214
89422
  function skillTargetFile() {
89215
- return join47(skillTargetDir(), "SKILL.md");
89423
+ return join49(skillTargetDir(), "SKILL.md");
89216
89424
  }
89217
89425
  function defaultSkillSource() {
89218
89426
  const here = dirname40(fileURLToPath11(import.meta.url));
89219
89427
  const candidates = [
89220
- join47(here, "../skill/SKILL.md"),
89428
+ join49(here, "../skill/SKILL.md"),
89221
89429
  // bundled bin/cli.js → repo root
89222
- join47(here, "../../../../skill/SKILL.md")
89430
+ join49(here, "../../../../skill/SKILL.md")
89223
89431
  // dev src/lib → repo root
89224
89432
  ];
89225
89433
  return candidates.find((c) => existsSync36(c)) ?? candidates[0];
@@ -89236,7 +89444,7 @@ function rewriteVersionMarker(content, version) {
89236
89444
  return content.replace(VERSION_MARKER_RE, versionMarker(version));
89237
89445
  }
89238
89446
  function installedSkillVersion(dir = skillTargetDir()) {
89239
- const file = join47(dir, "SKILL.md");
89447
+ const file = join49(dir, "SKILL.md");
89240
89448
  if (!existsSync36(file)) return null;
89241
89449
  try {
89242
89450
  return parseSkillVersion(readFileSync36(file, "utf-8"));
@@ -89252,7 +89460,7 @@ function syncSkill({
89252
89460
  throw new Error("Automatic skill sync is disabled in development instances");
89253
89461
  const rendered = rewriteVersionMarker(readFileSync36(source, "utf-8"), version);
89254
89462
  const dir = skillTargetDir();
89255
- const target = join47(dir, "SKILL.md");
89463
+ const target = join49(dir, "SKILL.md");
89256
89464
  const existing = existsSync36(target) ? readFileSync36(target, "utf-8") : null;
89257
89465
  if (existing === rendered) {
89258
89466
  return { action: "unchanged", path: target, to: version };
@@ -91498,11 +91706,14 @@ var init_automation_client = __esm({
91498
91706
  // packages/daemon/src/automation.ts
91499
91707
  var automation_exports = {};
91500
91708
  __export(automation_exports, {
91709
+ AutomationInvocationIntentSchemaZ: () => AutomationInvocationIntentSchemaZ,
91501
91710
  invokingPaneCredential: () => invokingPaneCredential,
91502
91711
  localAutomationClient: () => localAutomationClient,
91503
91712
  readAutomationRequest: () => readAutomationRequest,
91713
+ resolveAutomationIntent: () => resolveAutomationIntent,
91504
91714
  runAutomationCli: () => runAutomationCli
91505
91715
  });
91716
+ import { z as z109 } from "zod";
91506
91717
  import { execFileSync as execFileSync22 } from "node:child_process";
91507
91718
  import { parseArgs } from "node:util";
91508
91719
  function invokingPaneCredential(env = process.env) {
@@ -91565,6 +91776,13 @@ async function readAutomationRequest(input) {
91565
91776
  throw new IdeError("Expected a JSON automation request on stdin", { code: "INVALID_REQUEST" });
91566
91777
  }
91567
91778
  }
91779
+ async function resolveAutomationIntent(input, client, options = {}) {
91780
+ const intent = AutomationInvocationIntentSchemaZ.parse(input);
91781
+ return AutomationOperationIntentSchemaZ.parse({
91782
+ ...intent,
91783
+ source: intent.source === void 0 ? (await client.discover(options)).source ?? null : intent.source
91784
+ });
91785
+ }
91568
91786
  async function runAutomationCli(args, dependencies = {}) {
91569
91787
  const { positionals: positionals2, values: values2 } = parseArgs({
91570
91788
  args: [...args],
@@ -91630,20 +91848,20 @@ async function runAutomationCli(args, dependencies = {}) {
91630
91848
  }
91631
91849
  return;
91632
91850
  }
91633
- const intent = AutomationOperationIntentSchemaZ.parse(input);
91851
+ const intent = await resolveAutomationIntent(input, client);
91634
91852
  if (command3 !== "reserve" && intent.kind !== command3)
91635
91853
  throw new IdeError("Automation command does not match intent kind", {
91636
91854
  code: "INVALID_REQUEST"
91637
91855
  });
91638
91856
  const reservation = await client.reserve(intent);
91639
- if (command3 === "reserve") output(reservation);
91857
+ if (command3 === "reserve") output({ ...reservation, intent });
91640
91858
  else output(await client.execute(reservation.handle, intent));
91641
91859
  } catch (error) {
91642
91860
  if (error instanceof AutomationInvocationError) throw new AutomationCliError(error);
91643
91861
  throw error;
91644
91862
  }
91645
91863
  }
91646
- var AutomationCliError;
91864
+ var AutomationCliError, AutomationInvocationIntentSchemaZ;
91647
91865
  var init_automation2 = __esm({
91648
91866
  "packages/daemon/src/automation.ts"() {
91649
91867
  "use strict";
@@ -91662,6 +91880,14 @@ var init_automation2 = __esm({
91662
91880
  return { ...super.toJSON(), handle: this.handle };
91663
91881
  }
91664
91882
  };
91883
+ AutomationInvocationIntentSchemaZ = z109.discriminatedUnion("kind", [
91884
+ AutomationOperationIntentSchemaZ.options[0].extend({
91885
+ source: AutomationOperationIntentSchemaZ.options[0].shape.source.optional()
91886
+ }),
91887
+ AutomationOperationIntentSchemaZ.options[1].extend({
91888
+ source: AutomationOperationIntentSchemaZ.options[1].shape.source.optional()
91889
+ })
91890
+ ]);
91665
91891
  }
91666
91892
  });
91667
91893
 
@@ -91673,7 +91899,7 @@ __export(mcp_exports, {
91673
91899
  });
91674
91900
  import { McpServer } from "@modelcontextprotocol/server";
91675
91901
  import { serveStdio, StdioServerTransport } from "@modelcontextprotocol/server/stdio";
91676
- import { z as z109 } from "zod";
91902
+ import { z as z110 } from "zod";
91677
91903
  async function call(work) {
91678
91904
  try {
91679
91905
  return result(await work());
@@ -91696,7 +91922,7 @@ function createTmuxIdeMcpServer(client) {
91696
91922
  "tmux_panes",
91697
91923
  {
91698
91924
  description: "Discover current panes across this daemon's tmux servers. Use returned endpoint objects unchanged; names and native pane numbers are not unique identities.",
91699
- inputSchema: z109.object({}).strict(),
91925
+ inputSchema: z110.object({}).strict(),
91700
91926
  annotations: { readOnlyHint: true, idempotentHint: true }
91701
91927
  },
91702
91928
  async (_args, context) => call(() => client.discover({ signal: context.mcpReq.signal }))
@@ -91704,17 +91930,25 @@ function createTmuxIdeMcpServer(client) {
91704
91930
  server.registerTool(
91705
91931
  "tmux_prepare",
91706
91932
  {
91707
- description: "Prepare a read or send and receive a generation-fenced operation handle. This does not send input. Save the handle before executing. A source claim requires this MCP process to hold that pane's valid credential; otherwise use source:null.",
91708
- inputSchema: z109.object({ intent: AutomationOperationIntentSchemaZ }).strict(),
91933
+ description: "Prepare a read or send and receive a generation-fenced operation handle. This does not send input. Save the handle before executing. Omit source to resolve this MCP process\u2019s verified pane automatically, or use source:null for an unbound caller. Save the returned intent unchanged with the handle.",
91934
+ inputSchema: z110.object({ intent: AutomationInvocationIntentSchemaZ }).strict(),
91709
91935
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
91710
91936
  },
91711
- async ({ intent }, context) => call(() => client.reserve(intent, { signal: context.mcpReq.signal }))
91937
+ async ({ intent }, context) => call(async () => {
91938
+ const resolved2 = await resolveAutomationIntent(intent, client, {
91939
+ signal: context.mcpReq.signal
91940
+ });
91941
+ return {
91942
+ ...await client.reserve(resolved2, { signal: context.mcpReq.signal }),
91943
+ intent: resolved2
91944
+ };
91945
+ })
91712
91946
  );
91713
91947
  server.registerTool(
91714
91948
  "tmux_execute",
91715
91949
  {
91716
91950
  description: "Execute a prepared read or send using its exact handle and unchanged intent. Sends may run terminal commands. On uncertainty, check status or retry this same handle; never prepare another operation. Read text is returned once; replay returns metadata only. A completed send is command completion, not proof the recipient consumed it.",
91717
- inputSchema: z109.object({
91951
+ inputSchema: z110.object({
91718
91952
  handle: AutomationOperationHandleSchemaZ,
91719
91953
  intent: AutomationOperationIntentSchemaZ
91720
91954
  }).strict(),
@@ -91726,7 +91960,7 @@ function createTmuxIdeMcpServer(client) {
91726
91960
  "tmux_operation_status",
91727
91961
  {
91728
91962
  description: "Look up a prepared operation without repeating its effect. Status contains no sent or captured text. Outcome-unknown includes expired retention and must not be interpreted as not executed.",
91729
- inputSchema: z109.object({ handle: AutomationOperationHandleSchemaZ }).strict(),
91963
+ inputSchema: z110.object({ handle: AutomationOperationHandleSchemaZ }).strict(),
91730
91964
  annotations: { readOnlyHint: true, idempotentHint: true }
91731
91965
  },
91732
91966
  async ({ handle }, context) => call(() => client.status(handle, { signal: context.mcpReq.signal }))
@@ -91735,9 +91969,9 @@ function createTmuxIdeMcpServer(client) {
91735
91969
  "tmux_interactions",
91736
91970
  {
91737
91971
  description: "Read at most one batch of scoped interaction metadata, optionally waiting for new events. Carry the returned cursor into the next call. Gaps explicitly mean missing history; these events contain no terminal contents.",
91738
- inputSchema: z109.object({
91972
+ inputSchema: z110.object({
91739
91973
  resume: TmuxInteractionCursorSchemaZ,
91740
- waitMs: z109.number().int().min(1).max(3e4).default(1e3)
91974
+ waitMs: z110.number().int().min(1).max(3e4).default(1e3)
91741
91975
  }).strict(),
91742
91976
  annotations: { readOnlyHint: true, idempotentHint: true }
91743
91977
  },
@@ -92000,7 +92234,7 @@ __export(worktree_exports, {
92000
92234
  worktreeSessionName: () => worktreeSessionName
92001
92235
  });
92002
92236
  import { execFileSync as execFileSync23 } from "node:child_process";
92003
- import { basename as basename18, dirname as dirname43, isAbsolute as isAbsolute24, join as join48, resolve as resolve39 } from "node:path";
92237
+ import { basename as basename19, dirname as dirname43, isAbsolute as isAbsolute24, join as join50, resolve as resolve39 } from "node:path";
92004
92238
  function sanitizeForTmux(part) {
92005
92239
  return part.replace(/[.:/\s]+/g, "-");
92006
92240
  }
@@ -92009,11 +92243,11 @@ function worktreeSessionName(project, branch) {
92009
92243
  }
92010
92244
  function defaultWorktreeBaseDir(repoDir) {
92011
92245
  const abs = resolve39(repoDir);
92012
- return join48(dirname43(abs), `${basename18(abs)}-worktrees`);
92246
+ return join50(dirname43(abs), `${basename19(abs)}-worktrees`);
92013
92247
  }
92014
92248
  function worktreePath(repoDir, branch, configuredDir) {
92015
92249
  const base2 = configuredDir && configuredDir.length > 0 ? isAbsolute24(configuredDir) ? configuredDir : resolve39(repoDir, configuredDir) : defaultWorktreeBaseDir(repoDir);
92016
- return join48(base2, branch);
92250
+ return join50(base2, branch);
92017
92251
  }
92018
92252
  function parseWorktreeList(porcelain) {
92019
92253
  const entries = [];
@@ -92148,7 +92382,7 @@ var init_worktree = __esm({
92148
92382
 
92149
92383
  // packages/daemon/src/lib/install-origin.ts
92150
92384
  import { existsSync as existsSync38, readFileSync as readFileSync38, realpathSync as realpathSync27 } from "node:fs";
92151
- import { dirname as dirname44, join as join49 } from "node:path";
92385
+ import { dirname as dirname44, join as join51 } from "node:path";
92152
92386
  import { fileURLToPath as fileURLToPath13 } from "node:url";
92153
92387
  function detectPackageManager(path2) {
92154
92388
  if (/\/(?:Cellar|Caskroom)\//.test(path2)) return "homebrew";
@@ -92163,9 +92397,9 @@ function findGitCheckoutRoot(startDir) {
92163
92397
  let dir = startDir;
92164
92398
  for (; ; ) {
92165
92399
  if (dir.endsWith("/node_modules")) return null;
92166
- if (existsSync38(join49(dir, ".git"))) {
92400
+ if (existsSync38(join51(dir, ".git"))) {
92167
92401
  try {
92168
- if (JSON.parse(readFileSync38(join49(dir, "package.json"), "utf8")).name === "tmux-ide")
92402
+ if (JSON.parse(readFileSync38(join51(dir, "package.json"), "utf8")).name === "tmux-ide")
92169
92403
  return dir;
92170
92404
  } catch {
92171
92405
  }
@@ -92186,7 +92420,7 @@ function installOrigin(cliDir = dirname44(fileURLToPath13(import.meta.url))) {
92186
92420
  let detected = detectPackageManager(path2);
92187
92421
  if (detected === "npm" || detected === "pnpm" || detected === "bun") {
92188
92422
  try {
92189
- if (JSON.parse(readFileSync38(join49(path2, "../package.json"), "utf8")).name !== "tmux-ide")
92423
+ if (JSON.parse(readFileSync38(join51(path2, "../package.json"), "utf8")).name !== "tmux-ide")
92190
92424
  detected = "unknown";
92191
92425
  } catch {
92192
92426
  detected = "unknown";
@@ -92212,7 +92446,7 @@ __export(update_exports, {
92212
92446
  runUpdate: () => runUpdate
92213
92447
  });
92214
92448
  import { realpathSync as realpathSync28 } from "node:fs";
92215
- import { dirname as dirname45, join as join50 } from "node:path";
92449
+ import { dirname as dirname45, join as join52 } from "node:path";
92216
92450
  import { execFileSync as execFileSync24 } from "node:child_process";
92217
92451
  function planUpdate(input) {
92218
92452
  const current = input.currentVersion ?? getCurrentVersion();
@@ -92289,7 +92523,7 @@ function runUpdate({ cliDir, dryRun, json: json2 = false }, dependencies = {}) {
92289
92523
  plan.executable === "bun" ? ["pm", "bin", "-g"] : ["root", "-g"]
92290
92524
  ).trim();
92291
92525
  if (!root.startsWith("/")) throw new Error("invalid manager path");
92292
- const target = plan.executable === "bun" ? dirname45(realpathSync28(join50(root, "tmux-ide"))) : realpathSync28(join50(root, "tmux-ide", "bin"));
92526
+ const target = plan.executable === "bun" ? dirname45(realpathSync28(join52(root, "tmux-ide"))) : realpathSync28(join52(root, "tmux-ide", "bin"));
92293
92527
  if (target !== source.path) throw new Error("different installation");
92294
92528
  } catch {
92295
92529
  plan = {
@@ -92346,7 +92580,7 @@ __export(pane_widget_exports, {
92346
92580
  paneWidgetId: () => paneWidgetId,
92347
92581
  paneWidgetIdForFile: () => paneWidgetIdForFile
92348
92582
  });
92349
- import { basename as basename19, extname } from "node:path";
92583
+ import { basename as basename20, extname } from "node:path";
92350
92584
  function imageMediaTypeFor(fileName) {
92351
92585
  return IMAGE_MEDIA_BY_EXTENSION.get(extname(fileName).toLowerCase()) ?? null;
92352
92586
  }
@@ -92364,7 +92598,7 @@ function buildMarkdownAnnouncement(text, title) {
92364
92598
  }
92365
92599
  }
92366
92600
  function buildImageAnnouncement(bytes, filePath) {
92367
- const name = basename19(filePath);
92601
+ const name = basename20(filePath);
92368
92602
  const media = imageMediaTypeFor(name);
92369
92603
  if (media === null) {
92370
92604
  throw new PaneWidgetRefusal(
@@ -92418,7 +92652,7 @@ function paneWidgetIdForFile(fileName) {
92418
92652
  if ([".md", ".markdown"].includes(extension)) return "markdown";
92419
92653
  if (IMAGE_MEDIA_BY_EXTENSION.has(extension)) return "image";
92420
92654
  if (extension === ".json") return "card";
92421
- const name = basename19(fileName) || fileName || "input";
92655
+ const name = basename20(fileName) || fileName || "input";
92422
92656
  throw new PaneWidgetRefusal(
92423
92657
  "unsupported-source",
92424
92658
  `tmux-ide cannot infer how to show "${name}". Supported: Markdown (.md, .markdown), raster images (${[...IMAGE_MEDIA_BY_EXTENSION.keys()].join(", ")}), and declarative cards (.json).`
@@ -92559,7 +92793,7 @@ var init_server3 = __esm({
92559
92793
 
92560
92794
  // bin/cli.ts
92561
92795
  import { parseArgs as parseArgs2 } from "node:util";
92562
- import { resolve as resolve40, dirname as dirname46, join as join51 } from "node:path";
92796
+ import { resolve as resolve40, dirname as dirname46, join as join53 } from "node:path";
92563
92797
  import { execFileSync as execFileSync25 } from "node:child_process";
92564
92798
  import { appendFileSync as appendFileSync2, existsSync as existsSync39, mkdirSync as mkdirSync31, writeFileSync as writeFileSync29 } from "node:fs";
92565
92799
  import { fileURLToPath as fileURLToPath14 } from "node:url";
@@ -92874,9 +93108,9 @@ Install bun (https://bun.sh) \u2014 the TUI surfaces run on it. Sources ship wit
92874
93108
  let automaticDiagnosticLog;
92875
93109
  if (surface === "app" && !process.env.TMUX_IDE_TUI_PERF_LOG && !process.env.TMUX_IDE_TUI_LOG) {
92876
93110
  try {
92877
- const logDirectory = join51(stateHome(), "logs");
93111
+ const logDirectory = join53(stateHome(), "logs");
92878
93112
  mkdirSync31(logDirectory, { recursive: true, mode: 448 });
92879
- automaticDiagnosticLog = join51(logDirectory, "tui-latest.jsonl");
93113
+ automaticDiagnosticLog = join53(logDirectory, "tui-latest.jsonl");
92880
93114
  writeFileSync29(
92881
93115
  automaticDiagnosticLog,
92882
93116
  `${JSON.stringify({
@@ -94337,7 +94571,7 @@ Known panels: ${POPUP_WIDGETS2.join(", ")}.`,
94337
94571
  } = await Promise.resolve().then(() => (init_pane_widget(), pane_widget_exports));
94338
94572
  const { publishWidgetAsset: publishWidgetAsset2, WidgetAssetStoreError: WidgetAssetStoreError2 } = await Promise.resolve().then(() => (init_widget_asset_store(), widget_asset_store_exports));
94339
94573
  const { readFileSync: readFileSync39, watchFile, unwatchFile } = await import("node:fs");
94340
- const { basename: basename20 } = await import("node:path");
94574
+ const { basename: basename21 } = await import("node:path");
94341
94575
  const readStdin = async () => {
94342
94576
  const chunks = [];
94343
94577
  for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk));
@@ -94358,9 +94592,9 @@ Known panels: ${POPUP_WIDGETS2.join(", ")}.`,
94358
94592
  const publish = () => {
94359
94593
  const asset = publishWidgetAsset2(readFileSync39(file), {
94360
94594
  media: "text/markdown",
94361
- name: basename20(file)
94595
+ name: basename21(file)
94362
94596
  });
94363
- return buildMarkdownAssetAnnouncement2(asset.assetId, basename20(file));
94597
+ return buildMarkdownAssetAnnouncement2(asset.assetId, basename21(file));
94364
94598
  };
94365
94599
  announcement = publish();
94366
94600
  watchedFile = file;
@@ -94375,14 +94609,14 @@ Known panels: ${POPUP_WIDGETS2.join(", ")}.`,
94375
94609
  if (!media) {
94376
94610
  throw new PaneWidgetRefusal2(
94377
94611
  "unsupported-media",
94378
- `"${basename20(file)}" is not a supported raster image.`
94612
+ `"${basename21(file)}" is not a supported raster image.`
94379
94613
  );
94380
94614
  }
94381
94615
  const asset = publishWidgetAsset2(readFileSync39(file), {
94382
94616
  media,
94383
- name: basename20(file)
94617
+ name: basename21(file)
94384
94618
  });
94385
- return buildImageAssetAnnouncement2(asset.assetId, { name: basename20(file) });
94619
+ return buildImageAssetAnnouncement2(asset.assetId, { name: basename21(file) });
94386
94620
  };
94387
94621
  announcement = publish();
94388
94622
  watchedFile = file;