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.
- package/bin/cli.js +780 -546
- package/package.json +2 -2
- package/packages/contracts/src/automation-operations.ts +2 -0
- package/packages/core/src/interaction-receipts.ts +9 -1
- package/packages/daemon/dist/automation.js +21 -2
- package/packages/daemon/dist/command-center/automation.js +13 -1
- package/packages/daemon/dist/command-center/discovery.js +9 -2
- package/packages/daemon/dist/command-center/resources/agent-graph-overlay.js +2 -2
- package/packages/daemon/dist/command-center/resources/application-shell.js +21 -15
- package/packages/daemon/dist/command-center/resources/fleet-catalog.js +6 -4
- package/packages/daemon/dist/command-center/resources/fleet-resource-route.js +2 -2
- package/packages/daemon/dist/lib/daemon-embed.js +22 -3
- package/packages/daemon/dist/mcp.js +12 -4
- package/packages/daemon/dist/terminal/attachments/agent-status-probe.js +12 -0
- package/packages/daemon/dist/terminal/attachments/claude-team-names.js +130 -0
- package/packages/daemon/dist/terminal/attachments/native-runtime.js +1 -0
- package/packages/daemon/dist/terminal/mirror/session-channel.js +1 -0
- package/packages/daemon/dist/terminal/protocol/pane-display-name.js +40 -11
- package/packages/daemon/dist/terminal/protocol/session-descriptor-discovery.js +4 -5
- package/packages/daemon/dist/tui/mirror/runtime/application-home-agents-owner.js +17 -1
- package/packages/daemon/dist/tui/mirror/runtime/application-home-experience.js +1 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-new-agent-owner.js +86 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-palette-command-owner.js +5 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-palette-input.js +1 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-pane-activity-owner.js +4 -3
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-interaction-controller.js +24 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-workspace-policy.js +7 -5
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-workspace.jsx +3 -0
- package/packages/daemon/dist/tui/mirror/ui/pane-interaction-presentation.js +30 -2
- package/packages/daemon/dist/tui/mirror/ui/pane-interaction.jsx +1 -1
- package/packages/daemon/dist/tui/mirror/workspace/application-command-description.js +6 -0
- package/packages/daemon/dist/tui/mirror/workspace/terminal-pane-header.jsx +4 -2
- package/packages/daemon/src/automation.ts +28 -2
- package/packages/daemon/src/command-center/automation.ts +16 -1
- package/packages/daemon/src/command-center/discovery.ts +13 -2
- package/packages/daemon/src/command-center/resources/agent-graph-overlay.ts +2 -1
- package/packages/daemon/src/command-center/resources/application-shell.ts +21 -18
- package/packages/daemon/src/command-center/resources/fleet-catalog.ts +9 -3
- package/packages/daemon/src/command-center/resources/fleet-resource-route.ts +5 -3
- package/packages/daemon/src/command-center/server.ts +1 -1
- package/packages/daemon/src/lib/daemon-embed.ts +29 -4
- package/packages/daemon/src/mcp.ts +16 -4
- package/packages/daemon/src/terminal/attachments/agent-status-probe.ts +17 -0
- package/packages/daemon/src/terminal/attachments/claude-team-names.ts +166 -0
- package/packages/daemon/src/terminal/attachments/native-runtime.ts +2 -0
- package/packages/daemon/src/terminal/mirror/session-channel.ts +1 -0
- package/packages/daemon/src/terminal/mirror/trusted-inventory.ts +1 -0
- package/packages/daemon/src/terminal/protocol/pane-display-name.ts +51 -13
- package/packages/daemon/src/terminal/protocol/session-descriptor-discovery.ts +4 -4
- package/packages/daemon/src/tui/mirror/runtime/application-home-agents-owner.ts +19 -2
- package/packages/daemon/src/tui/mirror/runtime/application-home-experience.ts +1 -0
- package/packages/daemon/src/tui/mirror/runtime/application-new-agent-dialog.tsx +97 -0
- package/packages/daemon/src/tui/mirror/runtime/application-new-agent-owner.ts +89 -0
- package/packages/daemon/src/tui/mirror/runtime/application-palette-command-owner.ts +6 -0
- package/packages/daemon/src/tui/mirror/runtime/application-palette-input.ts +1 -0
- package/packages/daemon/src/tui/mirror/runtime/application-pane-activity-owner.ts +9 -3
- package/packages/daemon/src/tui/mirror/runtime/application-root-v2.tsx +5 -4
- package/packages/daemon/src/tui/mirror/runtime/application-shell-view.tsx +30 -1
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-interaction-controller.ts +27 -0
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-workspace-policy.ts +10 -5
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-workspace.tsx +3 -0
- package/packages/daemon/src/tui/mirror/ui/pane-interaction-presentation.ts +35 -2
- package/packages/daemon/src/tui/mirror/ui/pane-interaction.tsx +1 -1
- package/packages/daemon/src/tui/mirror/workspace/application-command-description.ts +7 -0
- 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.
|
|
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
|
|
12833
|
-
if (!seen.includes(
|
|
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
|
|
12890
|
-
const hit = pickManifest(
|
|
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:
|
|
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((
|
|
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(
|
|
14710
|
-
const m = /^colou?r(\d+)$/.exec(
|
|
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(
|
|
14716
|
-
const code2 = tokenCode(
|
|
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 &&
|
|
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
|
|
19448
|
-
return
|
|
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
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
|
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 !==
|
|
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-${
|
|
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 [
|
|
23134
|
-
if (grant.session === session) this.#grants.delete(
|
|
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
|
|
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
|
-
|
|
23196
|
+
token2
|
|
23170
23197
|
]);
|
|
23171
|
-
this.#tokensByPane.set(paneKey,
|
|
23172
|
-
this.#grants.set(
|
|
23198
|
+
this.#tokensByPane.set(paneKey, token2);
|
|
23199
|
+
this.#grants.set(token2, { bindingId: randomUUID7(), session, runtimePaneId, semanticPaneId: semanticPaneId3 });
|
|
23173
23200
|
}
|
|
23174
|
-
for (const [paneKey,
|
|
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(
|
|
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
|
|
23248
|
+
const token2 = randomBytes2(32).toString("base64url");
|
|
23222
23249
|
await runAsync(
|
|
23223
|
-
["set-option", "-p", "-t", runtimePaneId, PANE_SOURCE_CREDENTIAL_OPTION,
|
|
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,
|
|
23233
|
-
this.#grants.set(
|
|
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,
|
|
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(
|
|
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
|
|
25911
|
-
this.#connections.set(
|
|
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
|
|
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(
|
|
26067
|
+
acknowledgeOneShotViewerCapture(token2, rawIdentity, rawAck) {
|
|
25929
26068
|
const released = [...this.expire()];
|
|
25930
|
-
const permit = this.#permits.get(
|
|
25931
|
-
if (!permit || permit.token !==
|
|
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 !==
|
|
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(
|
|
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
|
|
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
|
|
26142
|
+
return token2;
|
|
26004
26143
|
}
|
|
26005
26144
|
/** Only a proven no-write refusal may call this. Exact tokens cannot cancel another attempt. */
|
|
26006
|
-
cancelUndispatchedOperation(
|
|
26007
|
-
const permit = this.#permits.get(
|
|
26008
|
-
if (!permit || permit.token !==
|
|
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(
|
|
26013
|
-
const permit = this.#permits.get(
|
|
26014
|
-
if (!permit || permit.token !==
|
|
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(
|
|
26156
|
+
acknowledge(token2, connectionToken, raw) {
|
|
26018
26157
|
const ack = NativeOperationIdentitySchemaZ.parse(raw);
|
|
26019
26158
|
const released = [...this.expire()];
|
|
26020
|
-
const permit = this.#permits.get(
|
|
26021
|
-
if (this.#disposed || !permit || permit.token !==
|
|
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 [
|
|
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(
|
|
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(
|
|
26087
|
-
const connection = this.#connections.get(
|
|
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(
|
|
26229
|
+
return this.retireConnection(token2);
|
|
26091
26230
|
connection.closedAt ??= this.#now();
|
|
26092
26231
|
return this.expire();
|
|
26093
26232
|
}
|
|
26094
|
-
retireConnection(
|
|
26095
|
-
const connection = this.#connections.get(
|
|
26233
|
+
retireConnection(token2) {
|
|
26234
|
+
const connection = this.#connections.get(token2);
|
|
26096
26235
|
if (!connection) return [];
|
|
26097
|
-
this.#connections.delete(
|
|
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 [
|
|
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(
|
|
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 !==
|
|
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
|
|
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
|
-
|
|
27709
|
-
|
|
27710
|
-
|
|
27711
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
28173
|
-
const
|
|
28174
|
-
return
|
|
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
|
|
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 =
|
|
29114
|
-
const sessionWindowCount =
|
|
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
|
|
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(() =>
|
|
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
|
|
30814
|
+
const token2 = line.startsWith(ownPrefix) ? line.slice(ownPrefix.length) : null;
|
|
30402
30815
|
if (!collector.started) {
|
|
30403
|
-
if (
|
|
30404
|
-
if (
|
|
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 ??=
|
|
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 ||
|
|
30513
|
-
collector.failureReason ??=
|
|
30514
|
-
if (collector.blockOrdinal === statusOrdinal &&
|
|
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
|
|
55897
|
-
this.#trustedInventoryTokens.set(
|
|
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,
|
|
56055
|
+
isTrustedSessionInventoryCandidateCurrent(session, token2) {
|
|
55901
56056
|
if (this.#disposed) return false;
|
|
55902
|
-
const runtime = this.#trustedInventoryTokens.get(
|
|
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
|
|
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
|
-
|
|
59809
|
-
|
|
59810
|
-
|
|
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
|
|
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 =
|
|
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,
|
|
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
|
|
69436
|
+
import { join as join34 } from "node:path";
|
|
69268
69437
|
async function createEmbeddedTmuxServerOwners(options) {
|
|
69269
|
-
const path2 =
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
|
73948
|
+
const token2 = randomUUID31();
|
|
73780
73949
|
const result2 = {
|
|
73781
73950
|
operationId,
|
|
73782
73951
|
daemonInstanceId: this.#deps.daemonInstanceId,
|
|
73783
73952
|
phase: "prepared",
|
|
73784
|
-
prepareToken:
|
|
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(
|
|
73793
|
-
this.#preparedByToken.set(
|
|
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 [
|
|
74056
|
+
for (const [token2, record] of this.#preparedByToken) {
|
|
73888
74057
|
if (record.ownerClientId === ownerClientId) {
|
|
73889
74058
|
this.#clearTimer(record.expiryTimer);
|
|
73890
|
-
this.#preparedByToken.delete(
|
|
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(
|
|
73908
|
-
const record = this.#preparedByToken.get(
|
|
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(
|
|
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(
|
|
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
|
|
75847
|
+
import { dirname as dirname32, join as join37 } from "node:path";
|
|
75679
75848
|
function environmentIdentityPath() {
|
|
75680
|
-
return runtimeOwnedPath(
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
|
77750
|
+
import { dirname as dirname33, join as join39 } from "node:path";
|
|
77567
77751
|
function savedMachinesPath() {
|
|
77568
|
-
return runtimeOwnedPath(
|
|
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
|
|
77883
|
+
import { dirname as dirname34, join as join40 } from "node:path";
|
|
77700
77884
|
function fleetClientStatePath() {
|
|
77701
|
-
return runtimeOwnedPath(
|
|
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
|
|
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(
|
|
78123
|
+
return runtimeOwnedPath(join41(namespace.stateHome, "projects", identity2, "terminals.json"));
|
|
77940
78124
|
}
|
|
77941
|
-
return
|
|
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
|
|
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(
|
|
78052
|
-
const parts =
|
|
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(
|
|
78102
|
-
const result2 = verifyJwt(
|
|
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
|
|
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 =
|
|
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
|
|
78210
|
-
const result2 = authService.verifyToken(
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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(
|
|
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(
|
|
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,
|
|
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 =
|
|
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
|
|
82160
|
-
if (
|
|
82161
|
-
if (
|
|
82162
|
-
if (
|
|
82163
|
-
const value =
|
|
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 =
|
|
82357
|
+
const type = token2[0];
|
|
82174
82358
|
if (type === "1" || type === "2") {
|
|
82175
|
-
const fields =
|
|
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 =
|
|
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 =
|
|
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
|
|
82228
|
-
if (
|
|
82229
|
-
const parts =
|
|
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
|
|
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:
|
|
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
|
|
84007
|
-
return `group.${
|
|
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(
|
|
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
|
|
84775
|
+
import { join as join44 } from "node:path";
|
|
84592
84776
|
function assetRoot() {
|
|
84593
|
-
return runtimeOwnedPath(
|
|
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:
|
|
84614
|
-
metadata:
|
|
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 =
|
|
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(
|
|
84651
|
-
rmSync5(
|
|
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 =
|
|
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 =
|
|
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
|
|
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(
|
|
84959
|
+
function requireAuth(token2, localBypassToken) {
|
|
84776
84960
|
return async (c, next) => {
|
|
84777
|
-
if (!
|
|
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 ===
|
|
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
|
|
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 ??
|
|
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 :
|
|
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,
|
|
86308
|
-
if (!
|
|
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 ===
|
|
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: () =>
|
|
87518
|
-
|
|
87519
|
-
|
|
87520
|
-
|
|
87521
|
-
sessionName2,
|
|
87522
|
-
|
|
87523
|
-
|
|
87524
|
-
|
|
87525
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
88458
|
-
copyFileSync2(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
88698
|
+
const tasksDir = join48(dir, ".tasks");
|
|
88491
88699
|
if (!existsSync35(tasksDir)) {
|
|
88492
88700
|
mkdirSync29(tasksDir, { recursive: true });
|
|
88493
88701
|
}
|
|
88494
|
-
const contractPath =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
88769
|
+
...copyTemplateSkills(join48(dir, ".tmux-ide", "skills")),
|
|
88562
88770
|
...scaffoldTeamWorkspace(dir, name2)
|
|
88563
88771
|
];
|
|
88564
88772
|
} else {
|
|
88565
|
-
created = copyTemplateSkills(
|
|
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 =
|
|
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 =
|
|
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
|
|
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(
|
|
89420
|
+
return runtimeOwnedPath(join49(claudeDir(), "skills", "tmux-ide"));
|
|
89213
89421
|
}
|
|
89214
89422
|
function skillTargetFile() {
|
|
89215
|
-
return
|
|
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
|
-
|
|
89428
|
+
join49(here, "../skill/SKILL.md"),
|
|
89221
89429
|
// bundled bin/cli.js → repo root
|
|
89222
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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:
|
|
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.
|
|
91708
|
-
inputSchema:
|
|
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(() =>
|
|
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:
|
|
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:
|
|
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:
|
|
91972
|
+
inputSchema: z110.object({
|
|
91739
91973
|
resume: TmuxInteractionCursorSchemaZ,
|
|
91740
|
-
waitMs:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
92400
|
+
if (existsSync38(join51(dir, ".git"))) {
|
|
92167
92401
|
try {
|
|
92168
|
-
if (JSON.parse(readFileSync38(
|
|
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(
|
|
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
|
|
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(
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
93111
|
+
const logDirectory = join53(stateHome(), "logs");
|
|
92878
93112
|
mkdirSync31(logDirectory, { recursive: true, mode: 448 });
|
|
92879
|
-
automaticDiagnosticLog =
|
|
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:
|
|
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:
|
|
94595
|
+
name: basename21(file)
|
|
94362
94596
|
});
|
|
94363
|
-
return buildMarkdownAssetAnnouncement2(asset.assetId,
|
|
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
|
-
`"${
|
|
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:
|
|
94617
|
+
name: basename21(file)
|
|
94384
94618
|
});
|
|
94385
|
-
return buildImageAssetAnnouncement2(asset.assetId, { name:
|
|
94619
|
+
return buildImageAssetAnnouncement2(asset.assetId, { name: basename21(file) });
|
|
94386
94620
|
};
|
|
94387
94621
|
announcement = publish();
|
|
94388
94622
|
watchedFile = file;
|