tmux-ide 2.9.0-beta.47 → 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 +724 -533
- package/package.json +2 -2
- 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/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-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/workspace/application-command-description.js +6 -0
- 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/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-root-v2.tsx +5 -4
- package/packages/daemon/src/tui/mirror/runtime/application-shell-view.tsx +23 -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/workspace/application-command-description.ts +7 -0
package/bin/cli.js
CHANGED
|
@@ -11908,7 +11908,7 @@ var require_package = __commonJS({
|
|
|
11908
11908
|
"package.json"(exports, module) {
|
|
11909
11909
|
module.exports = {
|
|
11910
11910
|
name: "tmux-ide",
|
|
11911
|
-
version: "2.9.0-beta.
|
|
11911
|
+
version: "2.9.0-beta.48",
|
|
11912
11912
|
description: "A visual, agent-aware IDE for any tmux session, with optional workspace presets",
|
|
11913
11913
|
type: "module",
|
|
11914
11914
|
bin: {
|
|
@@ -11972,7 +11972,7 @@ var require_package = __commonJS({
|
|
|
11972
11972
|
postinstall: "node scripts/postinstall.js",
|
|
11973
11973
|
docs: "turbo run dev --filter=@tmux-ide/docs",
|
|
11974
11974
|
"demo:tui": "bun --preload @opentui/solid/preload docs/scripts/render-tui-demo.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-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",
|
|
11976
11976
|
"test:tui-smoke": "bun scripts/smoke-tui-missions.mjs",
|
|
11977
11977
|
"test:tui-live": "node scripts/tui-testdrive.mjs smoke",
|
|
11978
11978
|
"test:tui-testdrive": "node --test scripts/lib/tui-testdrive-clipboard-hook.test.mjs scripts/lib/tui-testdrive-input.test.mjs",
|
|
@@ -12831,8 +12831,8 @@ function subtreeEntries(entries, rootPid, maxDepth = 6) {
|
|
|
12831
12831
|
function describeSubtree(entries, rootPid, limit = 8) {
|
|
12832
12832
|
const seen = [];
|
|
12833
12833
|
for (const command3 of subtreeCommands(entries, rootPid)) {
|
|
12834
|
-
for (const
|
|
12835
|
-
if (!seen.includes(
|
|
12834
|
+
for (const token2 of commandTokens(command3)) {
|
|
12835
|
+
if (!seen.includes(token2)) seen.push(token2);
|
|
12836
12836
|
if (seen.length >= limit) return seen;
|
|
12837
12837
|
}
|
|
12838
12838
|
}
|
|
@@ -12888,11 +12888,11 @@ function resolveAgentCommand(paneCmd, panePid, table2, opts = {}) {
|
|
|
12888
12888
|
if (fast) return { manifest: fast, matchedCommand: paneCmd, source: "fast" };
|
|
12889
12889
|
let best;
|
|
12890
12890
|
for (const command3 of subtreeCommands(table2, panePid)) {
|
|
12891
|
-
for (const
|
|
12892
|
-
const hit = pickManifest(
|
|
12891
|
+
for (const token2 of commandTokens(command3)) {
|
|
12892
|
+
const hit = pickManifest(token2, manifests);
|
|
12893
12893
|
if (!hit) continue;
|
|
12894
12894
|
const rank = manifests.indexOf(hit);
|
|
12895
|
-
if (!best || rank < best.rank) best = { manifest: hit, matchedCommand:
|
|
12895
|
+
if (!best || rank < best.rank) best = { manifest: hit, matchedCommand: token2, rank };
|
|
12896
12896
|
if (best.rank === 0)
|
|
12897
12897
|
return { manifest: best.manifest, matchedCommand: best.matchedCommand, source: "tree" };
|
|
12898
12898
|
}
|
|
@@ -14360,7 +14360,7 @@ function agentPidsInSubtree(table2, panePid, bins) {
|
|
|
14360
14360
|
const wanted = new Set(bins);
|
|
14361
14361
|
const pids = [];
|
|
14362
14362
|
for (const entry of subtreeEntries(table2, panePid)) {
|
|
14363
|
-
if (commandTokens(entry.command).some((
|
|
14363
|
+
if (commandTokens(entry.command).some((token2) => wanted.has(token2))) pids.push(entry.pid);
|
|
14364
14364
|
}
|
|
14365
14365
|
return pids;
|
|
14366
14366
|
}
|
|
@@ -14708,14 +14708,14 @@ __export(cheatsheet_exports, {
|
|
|
14708
14708
|
cheatsheetPopupCommand: () => cheatsheetPopupCommand,
|
|
14709
14709
|
cheatsheetUnbindCommand: () => cheatsheetUnbindCommand
|
|
14710
14710
|
});
|
|
14711
|
-
function tokenCode(
|
|
14712
|
-
const m = /^colou?r(\d+)$/.exec(
|
|
14711
|
+
function tokenCode(token2) {
|
|
14712
|
+
const m = /^colou?r(\d+)$/.exec(token2);
|
|
14713
14713
|
if (!m) return null;
|
|
14714
14714
|
const n = Number(m[1]);
|
|
14715
14715
|
return Number.isInteger(n) && n >= 0 && n <= 255 ? n : null;
|
|
14716
14716
|
}
|
|
14717
|
-
function legendMark(
|
|
14718
|
-
const code2 = tokenCode(
|
|
14717
|
+
function legendMark(token2, glyph) {
|
|
14718
|
+
const code2 = tokenCode(token2);
|
|
14719
14719
|
return code2 === null ? dim(glyph) : color(code2, glyph);
|
|
14720
14720
|
}
|
|
14721
14721
|
function renderKey(tmuxKey) {
|
|
@@ -19441,13 +19441,16 @@ var init_workspace_registry = __esm({
|
|
|
19441
19441
|
// packages/daemon/src/terminal/protocol/pane-display-name.ts
|
|
19442
19442
|
function boundedName(value) {
|
|
19443
19443
|
const name = value?.trim() ?? "";
|
|
19444
|
-
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;
|
|
19445
19448
|
}
|
|
19446
19449
|
function commandBasename(value) {
|
|
19447
19450
|
const command3 = boundedName(value);
|
|
19448
19451
|
if (!command3) return null;
|
|
19449
|
-
const
|
|
19450
|
-
return
|
|
19452
|
+
const basename21 = command3.split("/").at(-1)?.trim() ?? "";
|
|
19453
|
+
return basename21.length > 0 ? basename21 : null;
|
|
19451
19454
|
}
|
|
19452
19455
|
function stableHash(value) {
|
|
19453
19456
|
let hash = 2166136261;
|
|
@@ -19462,13 +19465,17 @@ function memorablePaneName(seed) {
|
|
|
19462
19465
|
const second = stableHash(`${seed}:noun`);
|
|
19463
19466
|
return `${ADJECTIVES[first % ADJECTIVES.length]}-${NOUNS[second % NOUNS.length]}`;
|
|
19464
19467
|
}
|
|
19465
|
-
function
|
|
19468
|
+
function meaningfulPaneTitle(value, currentCommand, hostName) {
|
|
19466
19469
|
const title = boundedName(value);
|
|
19467
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;
|
|
19468
19475
|
if (title.startsWith("/") || title.startsWith("~") || title.includes("@")) return null;
|
|
19469
|
-
if (
|
|
19476
|
+
if (/^[a-z0-9][a-z0-9.-]*\.[a-z0-9-]{2,}$/iu.test(title) || hostName && [hostName, hostName.split(".")[0]].some(
|
|
19470
19477
|
(host) => host?.toLowerCase() === title.toLowerCase()
|
|
19471
|
-
))
|
|
19478
|
+
))
|
|
19472
19479
|
return null;
|
|
19473
19480
|
return title;
|
|
19474
19481
|
}
|
|
@@ -19476,18 +19483,36 @@ function resolvePaneDisplayName(input) {
|
|
|
19476
19483
|
const configuredName = boundedName(input.configuredName);
|
|
19477
19484
|
const configuredSource = input.configuredNameSource?.trim().toLowerCase() ?? "";
|
|
19478
19485
|
const generatedName = memorablePaneName(input.semanticPaneId);
|
|
19479
|
-
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;
|
|
19480
19495
|
if (configuredName && configuredSource === "manual")
|
|
19481
19496
|
return { name: configuredName, source: "manual" };
|
|
19482
|
-
|
|
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"))
|
|
19483
19505
|
return { name: configuredName, source: "agent" };
|
|
19484
19506
|
if (legacyConfiguredName && configuredSource !== "generated")
|
|
19485
19507
|
return { name: legacyConfiguredName, source: "manual" };
|
|
19486
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" };
|
|
19487
19514
|
if (command3 && !GENERIC_SHELLS.has(command3.toLowerCase()))
|
|
19488
19515
|
return { name: command3, source: "process" };
|
|
19489
|
-
const title = meaningfulTitle(input.title, command3, input.hostName);
|
|
19490
|
-
if (title) return { name: title, source: "title" };
|
|
19491
19516
|
return {
|
|
19492
19517
|
name: configuredName && configuredSource === "generated" ? configuredName : generatedName,
|
|
19493
19518
|
source: "generated"
|
|
@@ -20395,10 +20420,10 @@ var init_project_runtime_repository = __esm({
|
|
|
20395
20420
|
assertLockDirectory(this.runtimeRoot);
|
|
20396
20421
|
this.io.mkdir(lockDirectory);
|
|
20397
20422
|
assertLockDirectory(lockDirectory);
|
|
20398
|
-
const
|
|
20423
|
+
const token2 = randomUUID5();
|
|
20399
20424
|
const owner = `${JSON.stringify({
|
|
20400
20425
|
version: 1,
|
|
20401
|
-
token,
|
|
20426
|
+
token: token2,
|
|
20402
20427
|
processInstanceId: PROJECT_RUNTIME_PROCESS_INSTANCE_ID,
|
|
20403
20428
|
pid: process.pid,
|
|
20404
20429
|
createdAtMs: Date.now()
|
|
@@ -20452,10 +20477,10 @@ var init_project_runtime_repository = __esm({
|
|
|
20452
20477
|
const currentOwner = readFileSync21(lockPath, "utf-8");
|
|
20453
20478
|
const afterRead = lstatSync8(lockPath);
|
|
20454
20479
|
const parsed = JSON.parse(currentOwner);
|
|
20455
|
-
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) {
|
|
20456
20481
|
throw new Error("writer lock ownership changed before release");
|
|
20457
20482
|
}
|
|
20458
|
-
const releasedPath = `${lockPath}.released-${
|
|
20483
|
+
const releasedPath = `${lockPath}.released-${token2}`;
|
|
20459
20484
|
renameSync11(lockPath, releasedPath);
|
|
20460
20485
|
const moved = lstatSync8(releasedPath);
|
|
20461
20486
|
if (moved.dev !== before.dev || moved.ino !== before.ino) {
|
|
@@ -23132,8 +23157,8 @@ var init_pane_source_credentials = __esm({
|
|
|
23132
23157
|
this.#tmux = tmux7;
|
|
23133
23158
|
}
|
|
23134
23159
|
rotateSession(session) {
|
|
23135
|
-
for (const [
|
|
23136
|
-
if (grant.session === session) this.#grants.delete(
|
|
23160
|
+
for (const [token2, grant] of this.#grants) {
|
|
23161
|
+
if (grant.session === session) this.#grants.delete(token2);
|
|
23137
23162
|
}
|
|
23138
23163
|
for (const key2 of this.#tokensByPane.keys()) {
|
|
23139
23164
|
if (key2.startsWith(`${session}\0`)) this.#tokensByPane.delete(key2);
|
|
@@ -23161,22 +23186,22 @@ var init_pane_source_credentials = __esm({
|
|
|
23161
23186
|
const existing = existingToken ? this.#grants.get(existingToken) : void 0;
|
|
23162
23187
|
if (existing?.semanticPaneId === semanticPaneId3 && installedToken === existingToken) continue;
|
|
23163
23188
|
if (existingToken) this.#grants.delete(existingToken);
|
|
23164
|
-
const
|
|
23189
|
+
const token2 = randomBytes2(32).toString("base64url");
|
|
23165
23190
|
this.#tmux.run([
|
|
23166
23191
|
"set-option",
|
|
23167
23192
|
"-p",
|
|
23168
23193
|
"-t",
|
|
23169
23194
|
runtimePaneId,
|
|
23170
23195
|
PANE_SOURCE_CREDENTIAL_OPTION,
|
|
23171
|
-
|
|
23196
|
+
token2
|
|
23172
23197
|
]);
|
|
23173
|
-
this.#tokensByPane.set(paneKey,
|
|
23174
|
-
this.#grants.set(
|
|
23198
|
+
this.#tokensByPane.set(paneKey, token2);
|
|
23199
|
+
this.#grants.set(token2, { bindingId: randomUUID7(), session, runtimePaneId, semanticPaneId: semanticPaneId3 });
|
|
23175
23200
|
}
|
|
23176
|
-
for (const [paneKey,
|
|
23201
|
+
for (const [paneKey, token2] of this.#tokensByPane) {
|
|
23177
23202
|
if (!paneKey.startsWith(`${session}\0`) || live.has(paneKey)) continue;
|
|
23178
23203
|
this.#tokensByPane.delete(paneKey);
|
|
23179
|
-
this.#grants.delete(
|
|
23204
|
+
this.#grants.delete(token2);
|
|
23180
23205
|
}
|
|
23181
23206
|
}
|
|
23182
23207
|
/**
|
|
@@ -23220,9 +23245,9 @@ var init_pane_source_credentials = __esm({
|
|
|
23220
23245
|
const existing = existingToken ? this.#grants.get(existingToken) : void 0;
|
|
23221
23246
|
if (existing?.semanticPaneId === semanticPaneId3 && installedToken === existingToken)
|
|
23222
23247
|
continue;
|
|
23223
|
-
const
|
|
23248
|
+
const token2 = randomBytes2(32).toString("base64url");
|
|
23224
23249
|
await runAsync(
|
|
23225
|
-
["set-option", "-p", "-t", runtimePaneId, PANE_SOURCE_CREDENTIAL_OPTION,
|
|
23250
|
+
["set-option", "-p", "-t", runtimePaneId, PANE_SOURCE_CREDENTIAL_OPTION, token2],
|
|
23226
23251
|
signal
|
|
23227
23252
|
);
|
|
23228
23253
|
signal?.throwIfAborted();
|
|
@@ -23231,8 +23256,8 @@ var init_pane_source_credentials = __esm({
|
|
|
23231
23256
|
break;
|
|
23232
23257
|
}
|
|
23233
23258
|
if (existingToken) this.#grants.delete(existingToken);
|
|
23234
|
-
this.#tokensByPane.set(paneKey,
|
|
23235
|
-
this.#grants.set(
|
|
23259
|
+
this.#tokensByPane.set(paneKey, token2);
|
|
23260
|
+
this.#grants.set(token2, {
|
|
23236
23261
|
bindingId: randomUUID7(),
|
|
23237
23262
|
session,
|
|
23238
23263
|
runtimePaneId,
|
|
@@ -23240,10 +23265,10 @@ var init_pane_source_credentials = __esm({
|
|
|
23240
23265
|
});
|
|
23241
23266
|
}
|
|
23242
23267
|
if (raced) continue;
|
|
23243
|
-
for (const [paneKey,
|
|
23268
|
+
for (const [paneKey, token2] of this.#tokensByPane) {
|
|
23244
23269
|
if (!paneKey.startsWith(`${session}\0`) || live.has(paneKey)) continue;
|
|
23245
23270
|
this.#tokensByPane.delete(paneKey);
|
|
23246
|
-
this.#grants.delete(
|
|
23271
|
+
this.#grants.delete(token2);
|
|
23247
23272
|
}
|
|
23248
23273
|
return;
|
|
23249
23274
|
}
|
|
@@ -24686,6 +24711,118 @@ var init_development_log = __esm({
|
|
|
24686
24711
|
}
|
|
24687
24712
|
});
|
|
24688
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
|
+
|
|
24689
24826
|
// packages/daemon/src/lib/pane-source-discovery.ts
|
|
24690
24827
|
var PaneSourceDiscovery;
|
|
24691
24828
|
var init_pane_source_discovery = __esm({
|
|
@@ -25909,15 +26046,15 @@ var init_owned_native_interaction_bindings = __esm({
|
|
|
25909
26046
|
return null;
|
|
25910
26047
|
if ([...this.#connections.values()].some((c) => c.identity.connectionId === identity2.connectionId))
|
|
25911
26048
|
return null;
|
|
25912
|
-
const
|
|
25913
|
-
this.#connections.set(
|
|
25914
|
-
token,
|
|
26049
|
+
const token2 = Object.freeze({ bindingId: randomUUID13() });
|
|
26050
|
+
this.#connections.set(token2, {
|
|
26051
|
+
token: token2,
|
|
25915
26052
|
identity: freeze(identity2),
|
|
25916
26053
|
role,
|
|
25917
26054
|
closedAt: null,
|
|
25918
26055
|
oneShotCapture: false
|
|
25919
26056
|
});
|
|
25920
|
-
return
|
|
26057
|
+
return token2;
|
|
25921
26058
|
}
|
|
25922
26059
|
admit(raw) {
|
|
25923
26060
|
return this.#admit(raw, false);
|
|
@@ -25927,19 +26064,19 @@ var init_owned_native_interaction_bindings = __esm({
|
|
|
25927
26064
|
throw new TypeError("Invalid one-shot capture admission");
|
|
25928
26065
|
return this.#admit({ ...raw, role: "viewer", commands: ["capture-pane"], source: null }, true);
|
|
25929
26066
|
}
|
|
25930
|
-
acknowledgeOneShotViewerCapture(
|
|
26067
|
+
acknowledgeOneShotViewerCapture(token2, rawIdentity, rawAck) {
|
|
25931
26068
|
const released = [...this.expire()];
|
|
25932
|
-
const permit = this.#permits.get(
|
|
25933
|
-
if (!permit || permit.token !==
|
|
26069
|
+
const permit = this.#permits.get(token2.operationId);
|
|
26070
|
+
if (!permit || permit.token !== token2 || !permit.oneShotCapture || permit.acknowledgement)
|
|
25934
26071
|
return { acknowledged: false, decisions: released };
|
|
25935
26072
|
const identity2 = NativeJournalIdentitySchemaZ.parse(rawIdentity), ack = NativeOperationIdentitySchemaZ.parse(rawAck);
|
|
25936
|
-
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)
|
|
25937
26074
|
return { acknowledged: false, decisions: released };
|
|
25938
26075
|
const connectionToken = this.registerConnection(identity2, "viewer");
|
|
25939
26076
|
if (!connectionToken) return { acknowledged: false, decisions: released };
|
|
25940
26077
|
this.#connections.get(connectionToken).oneShotCapture = true;
|
|
25941
26078
|
try {
|
|
25942
|
-
released.push(...this.acknowledge(
|
|
26079
|
+
released.push(...this.acknowledge(token2, connectionToken, ack));
|
|
25943
26080
|
} finally {
|
|
25944
26081
|
released.push(...this.closeConnection(connectionToken));
|
|
25945
26082
|
}
|
|
@@ -25986,7 +26123,7 @@ var init_owned_native_interaction_bindings = __esm({
|
|
|
25986
26123
|
if (raw.role === "viewer" && !connection && !oneShotCapture) return null;
|
|
25987
26124
|
if (this.#disposed || this.#permits.has(id2) || this.#permits.size >= this.#maxPermits)
|
|
25988
26125
|
return null;
|
|
25989
|
-
const
|
|
26126
|
+
const token2 = Object.freeze({ operationId: id2 });
|
|
25990
26127
|
const request3 = freeze({
|
|
25991
26128
|
...structuredClone({ ...raw, connection: void 0 }),
|
|
25992
26129
|
target,
|
|
@@ -25994,7 +26131,7 @@ var init_owned_native_interaction_bindings = __esm({
|
|
|
25994
26131
|
});
|
|
25995
26132
|
this.#permits.set(id2, {
|
|
25996
26133
|
oneShotCapture,
|
|
25997
|
-
token,
|
|
26134
|
+
token: token2,
|
|
25998
26135
|
request: request3,
|
|
25999
26136
|
expiresAt: this.#now() + this.#permitMs,
|
|
26000
26137
|
completed: /* @__PURE__ */ new Map(),
|
|
@@ -26002,25 +26139,25 @@ var init_owned_native_interaction_bindings = __esm({
|
|
|
26002
26139
|
acknowledgement: null,
|
|
26003
26140
|
connection: connection ?? null
|
|
26004
26141
|
});
|
|
26005
|
-
return
|
|
26142
|
+
return token2;
|
|
26006
26143
|
}
|
|
26007
26144
|
/** Only a proven no-write refusal may call this. Exact tokens cannot cancel another attempt. */
|
|
26008
|
-
cancelUndispatchedOperation(
|
|
26009
|
-
const permit = this.#permits.get(
|
|
26010
|
-
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 [];
|
|
26011
26148
|
return this.#retire((candidate) => candidate === permit);
|
|
26012
26149
|
}
|
|
26013
26150
|
/** Ambiguous dispatched work stays unknown; a verified acknowledgement remains valid. */
|
|
26014
|
-
abandonUnacknowledgedOperation(
|
|
26015
|
-
const permit = this.#permits.get(
|
|
26016
|
-
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 [];
|
|
26017
26154
|
return this.#retire((candidate) => candidate === permit);
|
|
26018
26155
|
}
|
|
26019
|
-
acknowledge(
|
|
26156
|
+
acknowledge(token2, connectionToken, raw) {
|
|
26020
26157
|
const ack = NativeOperationIdentitySchemaZ.parse(raw);
|
|
26021
26158
|
const released = [...this.expire()];
|
|
26022
|
-
const permit = this.#permits.get(
|
|
26023
|
-
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)
|
|
26024
26161
|
return released;
|
|
26025
26162
|
if (permit.acknowledgement && !same3(permit.acknowledgement, ack)) return released;
|
|
26026
26163
|
permit.connection = connection;
|
|
@@ -26077,26 +26214,26 @@ var init_owned_native_interaction_bindings = __esm({
|
|
|
26077
26214
|
released.push(this.#unknown(pending.item, "pending-expired"));
|
|
26078
26215
|
}
|
|
26079
26216
|
for (const [id2, permit] of this.#permits) if (now >= permit.expiresAt) this.#permits.delete(id2);
|
|
26080
|
-
for (const [
|
|
26217
|
+
for (const [token2, connection] of this.#connections) {
|
|
26081
26218
|
if (connection.closedAt !== null && (now >= connection.closedAt + this.#permitMs || ![...this.#permits.values()].some((permit) => permit.connection === connection)))
|
|
26082
|
-
this.#connections.delete(
|
|
26219
|
+
this.#connections.delete(token2);
|
|
26083
26220
|
}
|
|
26084
26221
|
return released;
|
|
26085
26222
|
}
|
|
26086
26223
|
/** Authored helper exit preserves acknowledged proof until bounded permit expiry.
|
|
26087
26224
|
* New admissions are denied; retained viewer closure retires immediately. */
|
|
26088
|
-
closeConnection(
|
|
26089
|
-
const connection = this.#connections.get(
|
|
26225
|
+
closeConnection(token2) {
|
|
26226
|
+
const connection = this.#connections.get(token2);
|
|
26090
26227
|
if (!connection) return [];
|
|
26091
26228
|
if (connection.role === "viewer" && !connection.oneShotCapture)
|
|
26092
|
-
return this.retireConnection(
|
|
26229
|
+
return this.retireConnection(token2);
|
|
26093
26230
|
connection.closedAt ??= this.#now();
|
|
26094
26231
|
return this.expire();
|
|
26095
26232
|
}
|
|
26096
|
-
retireConnection(
|
|
26097
|
-
const connection = this.#connections.get(
|
|
26233
|
+
retireConnection(token2) {
|
|
26234
|
+
const connection = this.#connections.get(token2);
|
|
26098
26235
|
if (!connection) return [];
|
|
26099
|
-
this.#connections.delete(
|
|
26236
|
+
this.#connections.delete(token2);
|
|
26100
26237
|
return this.#retire((permit) => permit.connection === connection);
|
|
26101
26238
|
}
|
|
26102
26239
|
dispose() {
|
|
@@ -26154,9 +26291,9 @@ var init_owned_native_interaction_bindings = __esm({
|
|
|
26154
26291
|
completions.push(proof);
|
|
26155
26292
|
}
|
|
26156
26293
|
}
|
|
26157
|
-
for (const [
|
|
26294
|
+
for (const [token2, connection] of this.#connections) {
|
|
26158
26295
|
if (connection.closedAt !== null && ![...this.#permits.values()].some((permit) => permit.connection === connection))
|
|
26159
|
-
this.#connections.delete(
|
|
26296
|
+
this.#connections.delete(token2);
|
|
26160
26297
|
}
|
|
26161
26298
|
for (const proof of completions) this.#onPlanComplete?.(proof);
|
|
26162
26299
|
}
|
|
@@ -27307,6 +27444,265 @@ var init_live_session_identity = __esm({
|
|
|
27307
27444
|
}
|
|
27308
27445
|
});
|
|
27309
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
|
+
|
|
27310
27706
|
// packages/daemon/src/command-center/discovery.ts
|
|
27311
27707
|
import { execFileSync as execFileSync15 } from "node:child_process";
|
|
27312
27708
|
function tmuxSilent(args) {
|
|
@@ -27408,7 +27804,7 @@ function readAdoptedFleet(registry = getDefaultWorkspaceRegistry(), runTmux2 = _
|
|
|
27408
27804
|
for (const line of panesRaw.split("\n")) {
|
|
27409
27805
|
if (!line) continue;
|
|
27410
27806
|
const fields = line.split(FLEET_FIELD_SEPARATOR);
|
|
27411
|
-
if (fields.length !==
|
|
27807
|
+
if (fields.length !== 16 || fields[15] !== FLEET_LINE_SENTINEL) continue;
|
|
27412
27808
|
const sessionName = fields[0];
|
|
27413
27809
|
if (!adoptedSet.has(sessionName)) continue;
|
|
27414
27810
|
const runtimePaneId = fields[1];
|
|
@@ -27421,6 +27817,9 @@ function readAdoptedFleet(registry = getDefaultWorkspaceRegistry(), runTmux2 = _
|
|
|
27421
27817
|
panesBySession.set(sessionName, panes);
|
|
27422
27818
|
}
|
|
27423
27819
|
panes.push({
|
|
27820
|
+
nameSource: emptyToNull(decodeTmuxArgument(fields[14])),
|
|
27821
|
+
title: decodeTmuxArgument(fields[12]),
|
|
27822
|
+
name: emptyToNull(decodeTmuxArgument(fields[13])),
|
|
27424
27823
|
runtimePaneId,
|
|
27425
27824
|
semanticPaneId: emptyToNull(fields[2]),
|
|
27426
27825
|
incarnation,
|
|
@@ -27492,6 +27891,7 @@ var _tmuxRunner, FLEET_FIELD_SEPARATOR, FLEET_LINE_SENTINEL, FLEET_PANE_FORMAT;
|
|
|
27492
27891
|
var init_discovery = __esm({
|
|
27493
27892
|
"packages/daemon/src/command-center/discovery.ts"() {
|
|
27494
27893
|
"use strict";
|
|
27894
|
+
init_session_descriptor_discovery();
|
|
27495
27895
|
init_native_pane_identity();
|
|
27496
27896
|
init_live_session_identity();
|
|
27497
27897
|
init_runtime_namespace();
|
|
@@ -27518,6 +27918,9 @@ var init_discovery = __esm({
|
|
|
27518
27918
|
"#{@agent_display_name}",
|
|
27519
27919
|
"#{@agent_hint}",
|
|
27520
27920
|
"#{pane_birth_id}",
|
|
27921
|
+
"#{qa:pane_title}",
|
|
27922
|
+
"#{qa:@ide_name}",
|
|
27923
|
+
"#{qa:@tmux_ide_name_source}",
|
|
27521
27924
|
FLEET_LINE_SENTINEL
|
|
27522
27925
|
].join(FLEET_FIELD_SEPARATOR);
|
|
27523
27926
|
}
|
|
@@ -27539,7 +27942,7 @@ var init_semantic_resource_id = __esm({
|
|
|
27539
27942
|
|
|
27540
27943
|
// packages/daemon/src/command-center/resources/application-shell.ts
|
|
27541
27944
|
import { hostname } from "node:os";
|
|
27542
|
-
import { basename as
|
|
27945
|
+
import { basename as basename11 } from "node:path";
|
|
27543
27946
|
function agentIdForPaneStamp(stamp) {
|
|
27544
27947
|
return semanticResourceId("agent", stamp);
|
|
27545
27948
|
}
|
|
@@ -27694,6 +28097,7 @@ function deprecatedStandalonePaneIdentities(panes) {
|
|
|
27694
28097
|
});
|
|
27695
28098
|
}
|
|
27696
28099
|
function harnessForPane(pane) {
|
|
28100
|
+
if (pane.teamMemberName) return "claude-code";
|
|
27697
28101
|
const detected = pane.agentKind?.toLowerCase();
|
|
27698
28102
|
if (detected === "codex") return "codex";
|
|
27699
28103
|
if (detected === "claude" || detected === "claude-code") return "claude-code";
|
|
@@ -27702,24 +28106,26 @@ function harnessForPane(pane) {
|
|
|
27702
28106
|
if (executable.includes("claude")) return "claude-code";
|
|
27703
28107
|
return "custom";
|
|
27704
28108
|
}
|
|
27705
|
-
function isGenericPaneLabel(value) {
|
|
27706
|
-
const normalized = value?.trim().toLowerCase() ?? "";
|
|
27707
|
-
return normalized.length === 0 || GENERIC_PANE_LABELS.has(normalized);
|
|
27708
|
-
}
|
|
27709
28109
|
function resolvedAgentLabel(pane, presentation, index) {
|
|
27710
|
-
|
|
27711
|
-
|
|
27712
|
-
|
|
27713
|
-
|
|
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}`);
|
|
27714
28122
|
const harness = harnessForPane(pane);
|
|
27715
28123
|
if (harness === "codex") return "Codex";
|
|
27716
28124
|
if (harness === "claude-code") return "Claude Code";
|
|
27717
|
-
|
|
27718
|
-
return label(pane.title, `Agent ${index + 1}`);
|
|
27719
|
-
}
|
|
27720
|
-
return `Agent ${index + 1}`;
|
|
28125
|
+
return resolved2.source === "process" ? label(resolved2.name, `Agent ${index + 1}`) : `Agent ${index + 1}`;
|
|
27721
28126
|
}
|
|
27722
28127
|
function isAgentPane(pane) {
|
|
28128
|
+
if (pane.teamMemberName) return true;
|
|
27723
28129
|
if (pane.agentStateRaw != null && AGENT_STATE_STAMP.test(pane.agentStateRaw.trim())) {
|
|
27724
28130
|
return true;
|
|
27725
28131
|
}
|
|
@@ -27820,7 +28226,7 @@ function deepFreeze2(value) {
|
|
|
27820
28226
|
}
|
|
27821
28227
|
function projectApplicationShellResourceV1Core(session, paneIds, nowSec) {
|
|
27822
28228
|
const sessionName = label(session.name, "tmux session");
|
|
27823
|
-
const rootLabel = label(
|
|
28229
|
+
const rootLabel = label(basename11(session.dir), sessionName);
|
|
27824
28230
|
const projectId = semanticResourceId("project", session.dir);
|
|
27825
28231
|
const sessionId = semanticResourceId("session", session.name);
|
|
27826
28232
|
const focusedIndex = session.panes.findIndex((pane) => pane.active);
|
|
@@ -28042,23 +28448,23 @@ function projectDeprecatedStandaloneApplicationShellResourceV1(session) {
|
|
|
28042
28448
|
)
|
|
28043
28449
|
);
|
|
28044
28450
|
}
|
|
28045
|
-
var
|
|
28451
|
+
var AGENT_STATE_STAMP;
|
|
28046
28452
|
var init_application_shell2 = __esm({
|
|
28047
28453
|
"packages/daemon/src/command-center/resources/application-shell.ts"() {
|
|
28048
28454
|
"use strict";
|
|
28455
|
+
init_pane_display_name();
|
|
28049
28456
|
init_src();
|
|
28050
28457
|
init_semantic_resource_id();
|
|
28051
28458
|
init_classify();
|
|
28052
28459
|
init_agent_resolution();
|
|
28053
28460
|
init_fleet_catalog2();
|
|
28054
|
-
GENERIC_PANE_LABELS = /* @__PURE__ */ new Set(["shell", "terminal", "tmux"]);
|
|
28055
28461
|
AGENT_STATE_STAMP = /^(?:working|blocked|done|idle):\d+$/u;
|
|
28056
28462
|
}
|
|
28057
28463
|
});
|
|
28058
28464
|
|
|
28059
28465
|
// packages/daemon/src/command-center/resources/fleet-catalog.ts
|
|
28060
28466
|
import { createHash as createHash13 } from "node:crypto";
|
|
28061
|
-
import { basename as
|
|
28467
|
+
import { basename as basename12 } from "node:path";
|
|
28062
28468
|
function digest(value) {
|
|
28063
28469
|
return createHash13("sha256").update(value).digest("hex").slice(0, 20);
|
|
28064
28470
|
}
|
|
@@ -28090,23 +28496,25 @@ function fleetLabel(value, fallback) {
|
|
|
28090
28496
|
return normalized || fallback;
|
|
28091
28497
|
}
|
|
28092
28498
|
function fleetProjectLabel(cwd, fallback) {
|
|
28093
|
-
const base2 =
|
|
28499
|
+
const base2 = basename12(cwd).replace(/[/\\]/gu, "");
|
|
28094
28500
|
return fleetLabel(base2, fallback);
|
|
28095
28501
|
}
|
|
28096
28502
|
function toPresentationPane(pane, index) {
|
|
28097
28503
|
return {
|
|
28098
28504
|
semanticPaneId: null,
|
|
28099
28505
|
index,
|
|
28100
|
-
title: "",
|
|
28506
|
+
title: pane.title ?? "",
|
|
28101
28507
|
currentCommand: pane.currentCommand,
|
|
28102
28508
|
active: pane.active,
|
|
28103
28509
|
role: null,
|
|
28104
|
-
name: null,
|
|
28510
|
+
name: pane.name ?? null,
|
|
28511
|
+
nameSource: pane.nameSource,
|
|
28105
28512
|
type: null,
|
|
28106
28513
|
agentKind: pane.agentHintRaw,
|
|
28107
28514
|
agentStateRaw: pane.agentStateRaw,
|
|
28108
28515
|
agentStatusTextRaw: pane.agentStatusTextRaw,
|
|
28109
28516
|
agentDisplayNameRaw: pane.agentDisplayNameRaw,
|
|
28517
|
+
teamMemberName: pane.teamMemberName,
|
|
28110
28518
|
// Authority-only: the fleet never scrapes an unopened session. `null` (not
|
|
28111
28519
|
// `undefined`) keeps `resolveAgentPresentation` on the ground-truth path
|
|
28112
28520
|
// while its scrape verdict resolves to `unknown` without any capture.
|
|
@@ -28124,7 +28532,10 @@ function projectSession(session, nowSec, remainingAgentBudget) {
|
|
|
28124
28532
|
const presentation = resolveAgentPresentation(presentationPane, nowSec);
|
|
28125
28533
|
agents.push({
|
|
28126
28534
|
agentId: fleetAgentIdForPane(session.name, pane),
|
|
28127
|
-
name: fleetLabel(
|
|
28535
|
+
name: fleetLabel(
|
|
28536
|
+
resolvedAgentLabel(presentationPane, presentation, index),
|
|
28537
|
+
`Agent ${index + 1}`
|
|
28538
|
+
),
|
|
28128
28539
|
harness: harnessForPane(presentationPane),
|
|
28129
28540
|
activity: presentation.activity,
|
|
28130
28541
|
attention: presentation.attention,
|
|
@@ -28171,9 +28582,9 @@ function launchCommandForHarness(harness) {
|
|
|
28171
28582
|
return LAUNCH_COMMANDS[harness] ?? harness;
|
|
28172
28583
|
}
|
|
28173
28584
|
function paneStartHostsShell(startCommand) {
|
|
28174
|
-
const
|
|
28175
|
-
const
|
|
28176
|
-
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, ""));
|
|
28177
28588
|
}
|
|
28178
28589
|
function interruptArgs2(paneId) {
|
|
28179
28590
|
return ["send-keys", "-t", paneId, "C-c"];
|
|
@@ -29053,7 +29464,7 @@ function derivePromotionIdentity(sessionName) {
|
|
|
29053
29464
|
sessionName
|
|
29054
29465
|
});
|
|
29055
29466
|
}
|
|
29056
|
-
function
|
|
29467
|
+
function positiveInteger2(value) {
|
|
29057
29468
|
if (!/^[1-9][0-9]*$/u.test(value)) return null;
|
|
29058
29469
|
const parsed = Number(value);
|
|
29059
29470
|
return Number.isSafeInteger(parsed) ? parsed : null;
|
|
@@ -29112,8 +29523,8 @@ function parseVerifyPanes(output) {
|
|
|
29112
29523
|
const panes = [];
|
|
29113
29524
|
for (const line of normalized.split("\n")) {
|
|
29114
29525
|
const fields = line.split(FIELD);
|
|
29115
|
-
const windowPaneCount =
|
|
29116
|
-
const sessionWindowCount =
|
|
29526
|
+
const windowPaneCount = positiveInteger2(fields[3] ?? "");
|
|
29527
|
+
const sessionWindowCount = positiveInteger2(fields[4] ?? "");
|
|
29117
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) {
|
|
29118
29529
|
throw new WorkspacePromotionError("promotion_verification_failed", {
|
|
29119
29530
|
reason: "invalid_tmux_pane_inventory"
|
|
@@ -29828,7 +30239,7 @@ function createNativeTmuxSessionOpener(options) {
|
|
|
29828
30239
|
options.assertOpen();
|
|
29829
30240
|
if (disposed) throw new Error("Session admission is retired");
|
|
29830
30241
|
};
|
|
29831
|
-
const
|
|
30242
|
+
const open2 = async (liveSessionId) => {
|
|
29832
30243
|
assertOpen();
|
|
29833
30244
|
const records = await options.run([
|
|
29834
30245
|
"list-sessions",
|
|
@@ -29883,7 +30294,7 @@ function createNativeTmuxSessionOpener(options) {
|
|
|
29883
30294
|
const previous = pending.get(liveSessionId);
|
|
29884
30295
|
if (previous) return previous;
|
|
29885
30296
|
if (pending.size >= 16) throw new Error("Session admission capacity reached");
|
|
29886
|
-
const operation = tail.then(() =>
|
|
30297
|
+
const operation = tail.then(() => open2(liveSessionId)).finally(() => pending.delete(liveSessionId));
|
|
29887
30298
|
pending.set(liveSessionId, operation);
|
|
29888
30299
|
tail = operation.catch(() => {
|
|
29889
30300
|
});
|
|
@@ -30400,10 +30811,10 @@ var init_control_channel = __esm({
|
|
|
30400
30811
|
collector.failureReason ??= "foreign-sentinel";
|
|
30401
30812
|
return true;
|
|
30402
30813
|
}
|
|
30403
|
-
const
|
|
30814
|
+
const token2 = line.startsWith(ownPrefix) ? line.slice(ownPrefix.length) : null;
|
|
30404
30815
|
if (!collector.started) {
|
|
30405
|
-
if (
|
|
30406
|
-
if (
|
|
30816
|
+
if (token2 === null) return false;
|
|
30817
|
+
if (token2 !== "start" || !this.inReply || this.currentReplyFlags !== 0 || this.currentReplyNum === null) {
|
|
30407
30818
|
collector.failureReason ??= "sentinel-order";
|
|
30408
30819
|
return true;
|
|
30409
30820
|
}
|
|
@@ -30507,13 +30918,13 @@ var init_control_channel = __esm({
|
|
|
30507
30918
|
}
|
|
30508
30919
|
const markerRejected = `marker-rejected`;
|
|
30509
30920
|
if (collector.blockOrdinal === markerBranchOrdinal) {
|
|
30510
|
-
collector.failureReason ??=
|
|
30921
|
+
collector.failureReason ??= token2 === markerRejected ? "marker-rejected" : "sentinel-order";
|
|
30511
30922
|
return true;
|
|
30512
30923
|
}
|
|
30513
30924
|
const expectedToken = collector.blockOrdinal === 2 ? "capture-end" : collector.blockOrdinal === 4 ? "cursor-end" : collector.blockOrdinal === statusOrdinal ? "status-ok" : collector.blockOrdinal === completeOrdinal ? "complete" : null;
|
|
30514
|
-
if (expectedToken === null ||
|
|
30515
|
-
collector.failureReason ??=
|
|
30516
|
-
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") {
|
|
30517
30928
|
if (collector.statusObserved) collector.failureReason ??= "duplicate-sentinel";
|
|
30518
30929
|
collector.statusObserved = true;
|
|
30519
30930
|
}
|
|
@@ -31504,265 +31915,6 @@ var init_layout_parse = __esm({
|
|
|
31504
31915
|
}
|
|
31505
31916
|
});
|
|
31506
31917
|
|
|
31507
|
-
// packages/daemon/src/terminal/protocol/session-descriptor-discovery.ts
|
|
31508
|
-
function decodeTmuxArgument(value) {
|
|
31509
|
-
const encoded = value.length >= 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) ? value.slice(1, -1) : value;
|
|
31510
|
-
let decoded = "";
|
|
31511
|
-
for (let index = 0; index < encoded.length; index += 1) {
|
|
31512
|
-
const current = encoded[index];
|
|
31513
|
-
if (current !== "\\" || index + 1 >= encoded.length) {
|
|
31514
|
-
decoded += current;
|
|
31515
|
-
continue;
|
|
31516
|
-
}
|
|
31517
|
-
const escaped = encoded[++index];
|
|
31518
|
-
if (escaped === "e") decoded += "\x1B";
|
|
31519
|
-
else if (escaped === "n") decoded += "\n";
|
|
31520
|
-
else if (escaped === "r") decoded += "\r";
|
|
31521
|
-
else if (escaped === "t") decoded += " ";
|
|
31522
|
-
else if (/[0-7]/u.test(escaped)) {
|
|
31523
|
-
let octal = escaped;
|
|
31524
|
-
while (octal.length < 3 && /[0-7]/u.test(encoded[index + 1] ?? "")) {
|
|
31525
|
-
octal += encoded[++index];
|
|
31526
|
-
}
|
|
31527
|
-
decoded += String.fromCodePoint(Number.parseInt(octal, 8));
|
|
31528
|
-
} else if (escaped === "u") {
|
|
31529
|
-
const remaining = encoded.slice(index + 1);
|
|
31530
|
-
const unicode = remaining.match(/^(?:[0-9A-Fa-f]{8}|[0-9A-Fa-f]{4})/u)?.[0];
|
|
31531
|
-
if (unicode) {
|
|
31532
|
-
decoded += String.fromCodePoint(Number.parseInt(unicode, 16));
|
|
31533
|
-
index += unicode.length;
|
|
31534
|
-
} else {
|
|
31535
|
-
decoded += "u";
|
|
31536
|
-
}
|
|
31537
|
-
} else {
|
|
31538
|
-
decoded += escaped;
|
|
31539
|
-
}
|
|
31540
|
-
}
|
|
31541
|
-
return decoded;
|
|
31542
|
-
}
|
|
31543
|
-
function parseSessionPaneDescriptorReply(lines) {
|
|
31544
|
-
const descriptors = [];
|
|
31545
|
-
let malformedUtf8Records = 0;
|
|
31546
|
-
if (lines.length > 4096 || lines.reduce((bytes, line) => bytes + Buffer.byteLength(line, "latin1") + 1, 0) > 128 * 1024) {
|
|
31547
|
-
return { descriptors, malformedUtf8Records };
|
|
31548
|
-
}
|
|
31549
|
-
for (const line of lines) {
|
|
31550
|
-
const utf8Line = decodeControlReplyUtf8(line);
|
|
31551
|
-
if (utf8Line === null) {
|
|
31552
|
-
malformedUtf8Records += 1;
|
|
31553
|
-
continue;
|
|
31554
|
-
}
|
|
31555
|
-
const encoded = utf8Line.split(" ");
|
|
31556
|
-
if (encoded.length !== 21) continue;
|
|
31557
|
-
const [
|
|
31558
|
-
runtimePaneId = "",
|
|
31559
|
-
semanticPaneId3 = "",
|
|
31560
|
-
role = "",
|
|
31561
|
-
type = "",
|
|
31562
|
-
currentCommand = "",
|
|
31563
|
-
cwd = "",
|
|
31564
|
-
windowIndexRaw = "",
|
|
31565
|
-
windowName = "",
|
|
31566
|
-
windowId = "",
|
|
31567
|
-
title = "",
|
|
31568
|
-
runtimeSessionId = "",
|
|
31569
|
-
paneIndexRaw = "",
|
|
31570
|
-
name = "",
|
|
31571
|
-
missionStamp = "",
|
|
31572
|
-
paneActiveRaw = "",
|
|
31573
|
-
windowActiveRaw = "",
|
|
31574
|
-
semanticWindowId = "",
|
|
31575
|
-
sessionName = "",
|
|
31576
|
-
windowPaneCountRaw = "",
|
|
31577
|
-
sessionWindowCountRaw = "",
|
|
31578
|
-
nativePaneBirthId = ""
|
|
31579
|
-
] = encoded.map(decodeTmuxArgument);
|
|
31580
|
-
if (!/^%(?:0|[1-9][0-9]*)$/u.test(runtimePaneId) || runtimePaneId.length > 32) continue;
|
|
31581
|
-
if (!/^\$(?:0|[1-9][0-9]*)$/u.test(runtimeSessionId) || runtimeSessionId.length > 32) continue;
|
|
31582
|
-
const parsedWindowIndex = Number(windowIndexRaw);
|
|
31583
|
-
const windowIndex = Number.isSafeInteger(parsedWindowIndex) && parsedWindowIndex >= 0 ? parsedWindowIndex : null;
|
|
31584
|
-
const paneIndex = Number(paneIndexRaw);
|
|
31585
|
-
const windowPaneCount = Number(windowPaneCountRaw);
|
|
31586
|
-
const sessionWindowCount = Number(sessionWindowCountRaw);
|
|
31587
|
-
if (!/^(?:0|[1-9][0-9]*)$/u.test(paneIndexRaw) || !Number.isSafeInteger(paneIndex)) continue;
|
|
31588
|
-
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)
|
|
31589
|
-
continue;
|
|
31590
|
-
if (!["0", "1"].includes(paneActiveRaw) || !["0", "1"].includes(windowActiveRaw)) continue;
|
|
31591
|
-
const bounded4 = (value, maximum) => value.length <= maximum && !/[\0\r\n\t]/u.test(value);
|
|
31592
|
-
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) {
|
|
31593
|
-
continue;
|
|
31594
|
-
}
|
|
31595
|
-
descriptors.push({
|
|
31596
|
-
sessionName,
|
|
31597
|
-
runtimePaneId,
|
|
31598
|
-
runtimeSessionId,
|
|
31599
|
-
semanticPaneId: nonempty(semanticPaneId3),
|
|
31600
|
-
role: nonempty(role),
|
|
31601
|
-
type: nonempty(type),
|
|
31602
|
-
currentCommand: nonempty(currentCommand),
|
|
31603
|
-
cwd: nonempty(cwd),
|
|
31604
|
-
title: nonempty(title),
|
|
31605
|
-
windowIndex,
|
|
31606
|
-
windowName: nonempty(windowName),
|
|
31607
|
-
windowId: /^@(?:0|[1-9][0-9]*)$/u.test(windowId) ? windowId : null,
|
|
31608
|
-
semanticWindowId: nonempty(semanticWindowId),
|
|
31609
|
-
paneIndex,
|
|
31610
|
-
name: nonempty(name),
|
|
31611
|
-
// Source metadata is persisted for mutations, while this hot inventory
|
|
31612
|
-
// stays wire-compatible. Generated names are recognized deterministically.
|
|
31613
|
-
nameSource: null,
|
|
31614
|
-
missionStamp: nonempty(missionStamp),
|
|
31615
|
-
nativePaneBirthId: nonempty(nativePaneBirthId),
|
|
31616
|
-
paneActive: paneActiveRaw === "1",
|
|
31617
|
-
windowActive: windowActiveRaw === "1",
|
|
31618
|
-
windowPaneCount,
|
|
31619
|
-
sessionWindowCount
|
|
31620
|
-
});
|
|
31621
|
-
}
|
|
31622
|
-
return { descriptors, malformedUtf8Records };
|
|
31623
|
-
}
|
|
31624
|
-
function nonempty(value) {
|
|
31625
|
-
return value.length > 0 ? value : null;
|
|
31626
|
-
}
|
|
31627
|
-
function decodeControlReplyUtf8(value) {
|
|
31628
|
-
try {
|
|
31629
|
-
return STRICT_UTF8_DECODER.decode(Buffer.from(value, "latin1"));
|
|
31630
|
-
} catch {
|
|
31631
|
-
return null;
|
|
31632
|
-
}
|
|
31633
|
-
}
|
|
31634
|
-
function positiveInteger2(value, fallback) {
|
|
31635
|
-
return Number.isSafeInteger(value) && value > 0 ? value : fallback;
|
|
31636
|
-
}
|
|
31637
|
-
var SESSION_PANE_DESCRIPTOR_FORMAT, SessionDescriptorDiscovery, STRICT_UTF8_DECODER;
|
|
31638
|
-
var init_session_descriptor_discovery = __esm({
|
|
31639
|
-
"packages/daemon/src/terminal/protocol/session-descriptor-discovery.ts"() {
|
|
31640
|
-
"use strict";
|
|
31641
|
-
SESSION_PANE_DESCRIPTOR_FORMAT = [
|
|
31642
|
-
"#{pane_id}",
|
|
31643
|
-
"#{qa:@tmux_ide_pane_id}",
|
|
31644
|
-
"#{qa:@ide_role}",
|
|
31645
|
-
"#{qa:@ide_type}",
|
|
31646
|
-
"#{qa:pane_current_command}",
|
|
31647
|
-
"#{qa:pane_current_path}",
|
|
31648
|
-
"#{window_index}",
|
|
31649
|
-
"#{qa:window_name}",
|
|
31650
|
-
"#{window_id}",
|
|
31651
|
-
"#{qa:pane_title}",
|
|
31652
|
-
"#{session_id}",
|
|
31653
|
-
"#{pane_index}",
|
|
31654
|
-
"#{qa:@ide_name}",
|
|
31655
|
-
"#{qa:@tmux_ide_mission}",
|
|
31656
|
-
"#{pane_active}",
|
|
31657
|
-
"#{?window_active,1,0}",
|
|
31658
|
-
"#{qa:@tmux_ide_window_id}",
|
|
31659
|
-
"#{qa:session_name}",
|
|
31660
|
-
"#{window_panes}",
|
|
31661
|
-
"#{session_windows}",
|
|
31662
|
-
"#{pane_birth_id}"
|
|
31663
|
-
].join(" ");
|
|
31664
|
-
SessionDescriptorDiscovery = class {
|
|
31665
|
-
options;
|
|
31666
|
-
epoch = 0;
|
|
31667
|
-
cancelScheduled = null;
|
|
31668
|
-
disposed = false;
|
|
31669
|
-
constructor(options) {
|
|
31670
|
-
this.options = {
|
|
31671
|
-
...options,
|
|
31672
|
-
maxAttempts: positiveInteger2(options.maxAttempts, 3),
|
|
31673
|
-
baseDelayMs: positiveInteger2(options.baseDelayMs, 50),
|
|
31674
|
-
schedule: options.schedule ?? ((callback, delayMs) => {
|
|
31675
|
-
const timer = setTimeout(callback, delayMs);
|
|
31676
|
-
return () => clearTimeout(timer);
|
|
31677
|
-
})
|
|
31678
|
-
};
|
|
31679
|
-
}
|
|
31680
|
-
discover(listedRuntimePaneIds) {
|
|
31681
|
-
if (this.disposed) return;
|
|
31682
|
-
this.invalidatePending();
|
|
31683
|
-
const epoch = this.epoch;
|
|
31684
|
-
this.attempt(epoch, new Set(listedRuntimePaneIds), 1);
|
|
31685
|
-
}
|
|
31686
|
-
invalidate() {
|
|
31687
|
-
if (this.disposed) return;
|
|
31688
|
-
this.invalidatePending();
|
|
31689
|
-
this.options.onStatus?.(null);
|
|
31690
|
-
}
|
|
31691
|
-
dispose() {
|
|
31692
|
-
if (this.disposed) return;
|
|
31693
|
-
this.invalidatePending();
|
|
31694
|
-
this.disposed = true;
|
|
31695
|
-
}
|
|
31696
|
-
invalidatePending() {
|
|
31697
|
-
this.epoch += 1;
|
|
31698
|
-
this.cancelScheduled?.();
|
|
31699
|
-
this.cancelScheduled = null;
|
|
31700
|
-
}
|
|
31701
|
-
attempt(epoch, listed, attempt) {
|
|
31702
|
-
void this.options.query().then((lines) => {
|
|
31703
|
-
if (!this.isCurrent(epoch)) return;
|
|
31704
|
-
const parsed = parseSessionPaneDescriptorReply(lines);
|
|
31705
|
-
const descriptorByRuntimePane = new Map(
|
|
31706
|
-
parsed.descriptors.filter((descriptor) => listed.has(descriptor.runtimePaneId)).map((descriptor) => [descriptor.runtimePaneId, descriptor])
|
|
31707
|
-
);
|
|
31708
|
-
const descriptors = [...descriptorByRuntimePane.values()];
|
|
31709
|
-
if (listed.size > 0 && descriptors.length === 0) {
|
|
31710
|
-
const malformedDetail = parsed.malformedUtf8Records > 0 ? `; ${parsed.malformedUtf8Records} malformed UTF-8 record${parsed.malformedUtf8Records === 1 ? " was" : "s were"} omitted` : "";
|
|
31711
|
-
throw new Error(
|
|
31712
|
-
`descriptor reply covered 0 of ${listed.size} live panes${malformedDetail}`
|
|
31713
|
-
);
|
|
31714
|
-
}
|
|
31715
|
-
if (descriptors.length !== listed.size || parsed.malformedUtf8Records > 0) {
|
|
31716
|
-
const malformedDetail = parsed.malformedUtf8Records > 0 ? `; omitted ${parsed.malformedUtf8Records} malformed UTF-8 record${parsed.malformedUtf8Records === 1 ? "" : "s"}` : "";
|
|
31717
|
-
this.options.onStatus?.({
|
|
31718
|
-
status: "partial",
|
|
31719
|
-
degraded: true,
|
|
31720
|
-
attempt,
|
|
31721
|
-
maxAttempts: this.options.maxAttempts,
|
|
31722
|
-
retryInMs: null,
|
|
31723
|
-
message: `Pane descriptor discovery published ${descriptors.length} of ${listed.size} live panes${malformedDetail}.`
|
|
31724
|
-
});
|
|
31725
|
-
} else {
|
|
31726
|
-
this.options.onStatus?.(null);
|
|
31727
|
-
}
|
|
31728
|
-
this.options.onDescriptors(descriptors, listed);
|
|
31729
|
-
}).catch((cause) => {
|
|
31730
|
-
if (!this.isCurrent(epoch)) return;
|
|
31731
|
-
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
31732
|
-
if (attempt >= this.options.maxAttempts) {
|
|
31733
|
-
this.options.onStatus?.({
|
|
31734
|
-
status: "failed",
|
|
31735
|
-
degraded: true,
|
|
31736
|
-
attempt,
|
|
31737
|
-
maxAttempts: this.options.maxAttempts,
|
|
31738
|
-
retryInMs: null,
|
|
31739
|
-
message: `Pane descriptor discovery failed after ${attempt} attempts: ${detail}`
|
|
31740
|
-
});
|
|
31741
|
-
return;
|
|
31742
|
-
}
|
|
31743
|
-
const retryInMs = this.options.baseDelayMs * 2 ** (attempt - 1);
|
|
31744
|
-
this.options.onStatus?.({
|
|
31745
|
-
status: "retrying",
|
|
31746
|
-
degraded: true,
|
|
31747
|
-
attempt,
|
|
31748
|
-
maxAttempts: this.options.maxAttempts,
|
|
31749
|
-
retryInMs,
|
|
31750
|
-
message: `Pane descriptor discovery attempt ${attempt} failed: ${detail}`
|
|
31751
|
-
});
|
|
31752
|
-
this.cancelScheduled = this.options.schedule(() => {
|
|
31753
|
-
this.cancelScheduled = null;
|
|
31754
|
-
if (this.isCurrent(epoch)) this.attempt(epoch, listed, attempt + 1);
|
|
31755
|
-
}, retryInMs);
|
|
31756
|
-
});
|
|
31757
|
-
}
|
|
31758
|
-
isCurrent(epoch) {
|
|
31759
|
-
return !this.disposed && epoch === this.epoch;
|
|
31760
|
-
}
|
|
31761
|
-
};
|
|
31762
|
-
STRICT_UTF8_DECODER = new TextDecoder("utf-8", { fatal: true });
|
|
31763
|
-
}
|
|
31764
|
-
});
|
|
31765
|
-
|
|
31766
31918
|
// packages/daemon/src/terminal/protocol/workspace-tmux-adapter.ts
|
|
31767
31919
|
function planWorkspaceTmuxReconciliation(input) {
|
|
31768
31920
|
const diagnostics = [];
|
|
@@ -34970,6 +35122,7 @@ var init_session_channel = __esm({
|
|
|
34970
35122
|
active: descriptor.paneActive && descriptor.windowActive,
|
|
34971
35123
|
role: descriptor.role,
|
|
34972
35124
|
name: descriptor.name,
|
|
35125
|
+
...descriptor.nameSource ? { nameSource: descriptor.nameSource } : {},
|
|
34973
35126
|
type: descriptor.type,
|
|
34974
35127
|
missionStamp: descriptor.missionStamp,
|
|
34975
35128
|
nativePaneBirthId: descriptor.nativePaneBirthId ?? null,
|
|
@@ -55895,13 +56048,13 @@ var init_registry2 = __esm({
|
|
|
55895
56048
|
if (!inventory) {
|
|
55896
56049
|
throw new Error(`SessionRuntime ${session} lost its retained inventory authority`);
|
|
55897
56050
|
}
|
|
55898
|
-
const
|
|
55899
|
-
this.#trustedInventoryTokens.set(
|
|
55900
|
-
return Object.freeze({ inventory, token });
|
|
56051
|
+
const token2 = Object.freeze({});
|
|
56052
|
+
this.#trustedInventoryTokens.set(token2, runtime);
|
|
56053
|
+
return Object.freeze({ inventory, token: token2 });
|
|
55901
56054
|
}
|
|
55902
|
-
isTrustedSessionInventoryCandidateCurrent(session,
|
|
56055
|
+
isTrustedSessionInventoryCandidateCurrent(session, token2) {
|
|
55903
56056
|
if (this.#disposed) return false;
|
|
55904
|
-
const runtime = this.#trustedInventoryTokens.get(
|
|
56057
|
+
const runtime = this.#trustedInventoryTokens.get(token2);
|
|
55905
56058
|
return runtime !== void 0 && this.#sessions.get(session) === runtime && runtime.trustedInventoryQualified();
|
|
55906
56059
|
}
|
|
55907
56060
|
hasProofQualifiedInventory(session) {
|
|
@@ -59794,7 +59947,7 @@ var init_MonotonicPtyInput = __esm({
|
|
|
59794
59947
|
|
|
59795
59948
|
// packages/daemon/src/terminal/NodePtyAdapter.ts
|
|
59796
59949
|
import { chmodSync as chmodSync6, existsSync as existsSync26, statSync as statSync12 } from "node:fs";
|
|
59797
|
-
import { dirname as dirname28, join as
|
|
59950
|
+
import { dirname as dirname28, join as join32 } from "node:path";
|
|
59798
59951
|
import { createRequire as createRequire2 } from "node:module";
|
|
59799
59952
|
import * as pty from "node-pty";
|
|
59800
59953
|
function candidateSpawnHelperPaths() {
|
|
@@ -59807,9 +59960,9 @@ function candidateSpawnHelperPaths() {
|
|
|
59807
59960
|
}
|
|
59808
59961
|
const pkgDir = dirname28(pkgJsonPath);
|
|
59809
59962
|
return [
|
|
59810
|
-
|
|
59811
|
-
|
|
59812
|
-
|
|
59963
|
+
join32(pkgDir, "build", "Release", "spawn-helper"),
|
|
59964
|
+
join32(pkgDir, "build", "Debug", "spawn-helper"),
|
|
59965
|
+
join32(pkgDir, "prebuilds", `${process.platform}-${process.arch}`, "spawn-helper")
|
|
59813
59966
|
];
|
|
59814
59967
|
}
|
|
59815
59968
|
function ensureNodePtySpawnHelperExecutable(options = {}) {
|
|
@@ -60744,7 +60897,7 @@ var init_tmux_view_executor = __esm({
|
|
|
60744
60897
|
|
|
60745
60898
|
// packages/daemon/src/terminal/attachments/pty-tmux-attachment-launcher.ts
|
|
60746
60899
|
import { accessSync as accessSync8, constants as constants12, realpathSync as realpathSync15, statSync as statSync13 } from "node:fs";
|
|
60747
|
-
import { delimiter as delimiter3, isAbsolute as isAbsolute16, join as
|
|
60900
|
+
import { delimiter as delimiter3, isAbsolute as isAbsolute16, join as join33 } from "node:path";
|
|
60748
60901
|
import { randomUUID as randomUUID23 } from "node:crypto";
|
|
60749
60902
|
import { execFileSync as execFileSync16 } from "node:child_process";
|
|
60750
60903
|
function defaultSchedule2(callback, delayMs) {
|
|
@@ -60773,7 +60926,7 @@ function selectorArgv(selector) {
|
|
|
60773
60926
|
function resolveTmuxExecutable3(pathValue = process.env.PATH) {
|
|
60774
60927
|
for (const directory of (pathValue ?? "").split(delimiter3)) {
|
|
60775
60928
|
if (!directory || !isAbsolute16(directory)) continue;
|
|
60776
|
-
const candidate =
|
|
60929
|
+
const candidate = join33(directory, "tmux");
|
|
60777
60930
|
try {
|
|
60778
60931
|
accessSync8(candidate, constants12.X_OK);
|
|
60779
60932
|
if (!statSync13(candidate).isFile()) continue;
|
|
@@ -61555,6 +61708,7 @@ function projectTrustedMirrorInventory(trusted2, workspaceName, expectedSessionN
|
|
|
61555
61708
|
active: pane.active,
|
|
61556
61709
|
role: nullable2(pane.role),
|
|
61557
61710
|
name: nullable2(pane.name),
|
|
61711
|
+
...pane.nameSource ? { nameSource: nullable2(pane.nameSource) } : {},
|
|
61558
61712
|
type: nullable2(pane.type),
|
|
61559
61713
|
missionStamp: nullable2(pane.missionStamp),
|
|
61560
61714
|
dir: boundedWireValue(pane.dir, 4096)
|
|
@@ -62124,7 +62278,7 @@ var init_native_runtime = __esm({
|
|
|
62124
62278
|
return (typeof qualify === "function" ? qualify.call(sessionRuntimeRegistry, sessionName, runtimeSessionId, signal) : sessionRuntimeRegistry.prewarmSession(sessionName, signal)).then(() => void 0);
|
|
62125
62279
|
};
|
|
62126
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;
|
|
62127
|
-
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;
|
|
62128
62282
|
this.#observeWorkspaceSession = (workspaceName, sessionName) => {
|
|
62129
62283
|
const previousSessionName = sessionsByWorkspace.get(workspaceName);
|
|
62130
62284
|
sessionsByWorkspace.set(workspaceName, sessionName);
|
|
@@ -63138,6 +63292,19 @@ function createTmuxAgentStatusProbe(deps2) {
|
|
|
63138
63292
|
});
|
|
63139
63293
|
emit(pane, raw, verdict, manifest.id);
|
|
63140
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
|
+
}
|
|
63141
63308
|
if (stagedVerdicts.size > SCRAPE_CACHE_MAX_ENTRIES) {
|
|
63142
63309
|
const byAge = [...stagedVerdicts.entries()].sort(
|
|
63143
63310
|
(a, b) => a[1].scrapedAtSec - b[1].scrapedAtSec
|
|
@@ -69266,9 +69433,9 @@ var init_pane_stream_upgrade = __esm({
|
|
|
69266
69433
|
|
|
69267
69434
|
// packages/daemon/src/lib/embedded-tmux-server-owners.ts
|
|
69268
69435
|
import { randomUUID as randomUUID30 } from "node:crypto";
|
|
69269
|
-
import { join as
|
|
69436
|
+
import { join as join34 } from "node:path";
|
|
69270
69437
|
async function createEmbeddedTmuxServerOwners(options) {
|
|
69271
|
-
const path2 =
|
|
69438
|
+
const path2 = join34(options.stateDirectory, "tmux-servers.json");
|
|
69272
69439
|
const persisted = readTmuxServerRegistrations(path2);
|
|
69273
69440
|
const probe = createTmuxServerProbe(options.defaultAuthority.executablePath);
|
|
69274
69441
|
const defaultObservation = await probe(options.defaultAuthority.socketSelector);
|
|
@@ -69329,7 +69496,7 @@ async function createEmbeddedTmuxServerOwners(options) {
|
|
|
69329
69496
|
...scope,
|
|
69330
69497
|
tmuxAuthority: observation2.authority,
|
|
69331
69498
|
nativeServerIdentity: observation2.nativeServerIdentity,
|
|
69332
|
-
stateDirectory:
|
|
69499
|
+
stateDirectory: join34(options.stateDirectory, "server-owners", registration.serverId),
|
|
69333
69500
|
webSocketUrl: new URL(route, options.webSocketBaseUrl).href
|
|
69334
69501
|
});
|
|
69335
69502
|
attachOwner(route, owner);
|
|
@@ -71497,7 +71664,7 @@ var init_daemon_fleet_facts_observer = __esm({
|
|
|
71497
71664
|
|
|
71498
71665
|
// packages/daemon/src/lib/directory-watcher.ts
|
|
71499
71666
|
import { watch as fsWatch } from "node:fs";
|
|
71500
|
-
import { join as
|
|
71667
|
+
import { join as join35, sep as sep9 } from "node:path";
|
|
71501
71668
|
async function loadParcel() {
|
|
71502
71669
|
if (parcel !== void 0) return parcel;
|
|
71503
71670
|
try {
|
|
@@ -71526,7 +71693,7 @@ function fsWatchDirectory(dir, onChange, ignore2, debounceMs, requireInstalled,
|
|
|
71526
71693
|
const rel = filename.toString();
|
|
71527
71694
|
if (rel.split(sep9).some((part) => ignoreSet.has(part))) return;
|
|
71528
71695
|
if (timeout) clearTimeout(timeout);
|
|
71529
|
-
timeout = setTimeout(() => onChange([{ type: "update", path:
|
|
71696
|
+
timeout = setTimeout(() => onChange([{ type: "update", path: join35(dir, rel) }]), debounceMs);
|
|
71530
71697
|
});
|
|
71531
71698
|
handle.on("error", reportUnavailable);
|
|
71532
71699
|
handle.on("close", () => {
|
|
@@ -72732,12 +72899,12 @@ var init_auth_token = __esm({
|
|
|
72732
72899
|
|
|
72733
72900
|
// packages/daemon/src/lib/app-settings.ts
|
|
72734
72901
|
import { existsSync as existsSync27, mkdirSync as mkdirSync23, readFileSync as readFileSync25, renameSync as renameSync14, writeFileSync as writeFileSync20 } from "node:fs";
|
|
72735
|
-
import { dirname as dirname31, join as
|
|
72902
|
+
import { dirname as dirname31, join as join36 } from "node:path";
|
|
72736
72903
|
function settingsDir() {
|
|
72737
72904
|
return resolveRuntimeNamespace().settingsDir;
|
|
72738
72905
|
}
|
|
72739
72906
|
function appSettingsPath() {
|
|
72740
|
-
return runtimeOwnedPath(
|
|
72907
|
+
return runtimeOwnedPath(join36(settingsDir(), "app-settings.json"));
|
|
72741
72908
|
}
|
|
72742
72909
|
function normalizeSettings(value) {
|
|
72743
72910
|
if (!value || typeof value !== "object") return structuredClone(DEFAULT_SETTINGS);
|
|
@@ -72745,8 +72912,8 @@ function normalizeSettings(value) {
|
|
|
72745
72912
|
if (!remote || typeof remote !== "object") return structuredClone(DEFAULT_SETTINGS);
|
|
72746
72913
|
const enabled = remote.enabled === true;
|
|
72747
72914
|
const rawToken = remote.token;
|
|
72748
|
-
const
|
|
72749
|
-
return { remoteAccess: { enabled, token } };
|
|
72915
|
+
const token2 = typeof rawToken === "string" && rawToken.length > 0 ? rawToken : null;
|
|
72916
|
+
return { remoteAccess: { enabled, token: token2 } };
|
|
72750
72917
|
}
|
|
72751
72918
|
function readAppSettings() {
|
|
72752
72919
|
const path2 = appSettingsPath();
|
|
@@ -72810,17 +72977,17 @@ async function appSetRemoteAccessHandler(input, deps2 = {}) {
|
|
|
72810
72977
|
const writeSettings = deps2.writeSettings ?? writeAppSettings;
|
|
72811
72978
|
const nextEnabled = input.enabled;
|
|
72812
72979
|
const current = readSettings2();
|
|
72813
|
-
const
|
|
72980
|
+
const token2 = nextEnabled ? current.remoteAccess.token ?? (deps2.generateToken ?? generateAuthToken)() : null;
|
|
72814
72981
|
const next = {
|
|
72815
72982
|
...current,
|
|
72816
|
-
remoteAccess: { enabled: nextEnabled, token }
|
|
72983
|
+
remoteAccess: { enabled: nextEnabled, token: token2 }
|
|
72817
72984
|
};
|
|
72818
72985
|
writeSettings(next);
|
|
72819
72986
|
const port = currentPort(deps2);
|
|
72820
72987
|
const request3 = {
|
|
72821
72988
|
enabled: nextEnabled,
|
|
72822
72989
|
bindHostname: nextEnabled ? "0.0.0.0" : "127.0.0.1",
|
|
72823
|
-
token,
|
|
72990
|
+
token: token2,
|
|
72824
72991
|
port
|
|
72825
72992
|
};
|
|
72826
72993
|
const restartDaemon = deps2.restartDaemon ?? remoteAccessRestartBackend;
|
|
@@ -72841,8 +73008,8 @@ async function appSetRemoteAccessHandler(input, deps2 = {}) {
|
|
|
72841
73008
|
return {
|
|
72842
73009
|
enabled: true,
|
|
72843
73010
|
url,
|
|
72844
|
-
token,
|
|
72845
|
-
qrPayload: `${url}?token=${encodeURIComponent(
|
|
73011
|
+
token: token2,
|
|
73012
|
+
qrPayload: `${url}?token=${encodeURIComponent(token2 ?? "")}`
|
|
72846
73013
|
};
|
|
72847
73014
|
}
|
|
72848
73015
|
var remoteAccessRestartBackend, remoteAccessListenerPort;
|
|
@@ -72972,7 +73139,7 @@ var init_daemon_shutdown = __esm({
|
|
|
72972
73139
|
// packages/daemon/src/lib/workspace-open.ts
|
|
72973
73140
|
import { createHash as createHash21 } from "node:crypto";
|
|
72974
73141
|
import { realpathSync as realpathSync19, statSync as statSync17 } from "node:fs";
|
|
72975
|
-
import { basename as
|
|
73142
|
+
import { basename as basename13, isAbsolute as isAbsolute19 } from "node:path";
|
|
72976
73143
|
function boundedAuthorityLimit3(value, fallback) {
|
|
72977
73144
|
if (value === void 0) return fallback;
|
|
72978
73145
|
if (!Number.isInteger(value) || value < 1 || value > MAX_OPERATIONS2) {
|
|
@@ -72987,7 +73154,7 @@ function boundedTmuxOutput2(value) {
|
|
|
72987
73154
|
return value.replace(/(?:\r?\n)+$/u, "");
|
|
72988
73155
|
}
|
|
72989
73156
|
function safeBaseName2(projectDir) {
|
|
72990
|
-
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);
|
|
72991
73158
|
return value || "workspace";
|
|
72992
73159
|
}
|
|
72993
73160
|
function deriveWorkspaceOpenIdentity(canonicalProjectDir3) {
|
|
@@ -73778,12 +73945,12 @@ var init_workspace_open_handoff2 = __esm({
|
|
|
73778
73945
|
const preferredPaneId = "initialPaneId" in opened.resource ? opened.resource.initialPaneId : void 0;
|
|
73779
73946
|
const proof = await this.#deps.prepareRuntime(workspaceName, preferredPaneId);
|
|
73780
73947
|
this.#assertCurrent(ownerClientId, revision, expectedDaemonInstanceId);
|
|
73781
|
-
const
|
|
73948
|
+
const token2 = randomUUID31();
|
|
73782
73949
|
const result2 = {
|
|
73783
73950
|
operationId,
|
|
73784
73951
|
daemonInstanceId: this.#deps.daemonInstanceId,
|
|
73785
73952
|
phase: "prepared",
|
|
73786
|
-
prepareToken:
|
|
73953
|
+
prepareToken: token2,
|
|
73787
73954
|
preparedRevision: revision,
|
|
73788
73955
|
outcome: opened.outcome,
|
|
73789
73956
|
workspaceName,
|
|
@@ -73791,10 +73958,10 @@ var init_workspace_open_handoff2 = __esm({
|
|
|
73791
73958
|
proof
|
|
73792
73959
|
};
|
|
73793
73960
|
this.#dropClientRecords(ownerClientId);
|
|
73794
|
-
const expiryTimer = this.#setTimer(() => this.#expire(
|
|
73795
|
-
this.#preparedByToken.set(
|
|
73961
|
+
const expiryTimer = this.#setTimer(() => this.#expire(token2), this.#prepareTtlMs);
|
|
73962
|
+
this.#preparedByToken.set(token2, {
|
|
73796
73963
|
ownerClientId,
|
|
73797
|
-
token,
|
|
73964
|
+
token: token2,
|
|
73798
73965
|
revision,
|
|
73799
73966
|
workspaceName,
|
|
73800
73967
|
previousWorkspaceName,
|
|
@@ -73886,10 +74053,10 @@ var init_workspace_open_handoff2 = __esm({
|
|
|
73886
74053
|
}
|
|
73887
74054
|
}
|
|
73888
74055
|
#dropClientRecords(ownerClientId) {
|
|
73889
|
-
for (const [
|
|
74056
|
+
for (const [token2, record] of this.#preparedByToken) {
|
|
73890
74057
|
if (record.ownerClientId === ownerClientId) {
|
|
73891
74058
|
this.#clearTimer(record.expiryTimer);
|
|
73892
|
-
this.#preparedByToken.delete(
|
|
74059
|
+
this.#preparedByToken.delete(token2);
|
|
73893
74060
|
}
|
|
73894
74061
|
}
|
|
73895
74062
|
}
|
|
@@ -73906,15 +74073,15 @@ var init_workspace_open_handoff2 = __esm({
|
|
|
73906
74073
|
this.#latestRevisionByClient.set(ownerClientId, revision);
|
|
73907
74074
|
return revision;
|
|
73908
74075
|
}
|
|
73909
|
-
#expire(
|
|
73910
|
-
const record = this.#preparedByToken.get(
|
|
74076
|
+
#expire(token2) {
|
|
74077
|
+
const record = this.#preparedByToken.get(token2);
|
|
73911
74078
|
if (!record) return;
|
|
73912
74079
|
this.#clearTimer(record.expiryTimer);
|
|
73913
|
-
this.#preparedByToken.delete(
|
|
74080
|
+
this.#preparedByToken.delete(token2);
|
|
73914
74081
|
if (this.#latestRevisionByClient.get(record.ownerClientId) === record.revision) {
|
|
73915
74082
|
this.#latestRevisionByClient.delete(record.ownerClientId);
|
|
73916
74083
|
}
|
|
73917
|
-
this.#expiredTokens.add(
|
|
74084
|
+
this.#expiredTokens.add(token2);
|
|
73918
74085
|
while (this.#expiredTokens.size > this.#maxLiveClients) {
|
|
73919
74086
|
const oldest = this.#expiredTokens.values().next().value;
|
|
73920
74087
|
if (!oldest) break;
|
|
@@ -75677,9 +75844,9 @@ var init_active_projects = __esm({
|
|
|
75677
75844
|
// packages/daemon/src/lib/environment-identity.ts
|
|
75678
75845
|
import { randomUUID as randomUUID32 } from "node:crypto";
|
|
75679
75846
|
import { linkSync as linkSync3, mkdirSync as mkdirSync24, readFileSync as readFileSync26, rmSync as rmSync4, writeFileSync as writeFileSync21 } from "node:fs";
|
|
75680
|
-
import { dirname as dirname32, join as
|
|
75847
|
+
import { dirname as dirname32, join as join37 } from "node:path";
|
|
75681
75848
|
function environmentIdentityPath() {
|
|
75682
|
-
return runtimeOwnedPath(
|
|
75849
|
+
return runtimeOwnedPath(join37(stateHome(), "environment.json"));
|
|
75683
75850
|
}
|
|
75684
75851
|
function readPersistedEnvironmentId(path2) {
|
|
75685
75852
|
try {
|
|
@@ -75760,7 +75927,7 @@ import {
|
|
|
75760
75927
|
realpathSync as realpathSync20,
|
|
75761
75928
|
statSync as statSync18
|
|
75762
75929
|
} from "node:fs";
|
|
75763
|
-
import { join as
|
|
75930
|
+
import { join as join38, resolve as resolve22 } from "node:path";
|
|
75764
75931
|
function classifySupervisor(facts) {
|
|
75765
75932
|
if (facts.launcher === "embedded")
|
|
75766
75933
|
return { kind: "embedded", evidence: "startEmbeddedDaemon host" };
|
|
@@ -76162,7 +76329,7 @@ function discoverLogFiles(options) {
|
|
|
76162
76329
|
}
|
|
76163
76330
|
for (const entry of entries) {
|
|
76164
76331
|
if (!entry.isFile() || !LOG_FILE_NAME.test(entry.name)) continue;
|
|
76165
|
-
consider(
|
|
76332
|
+
consider(join38(dir, entry.name));
|
|
76166
76333
|
}
|
|
76167
76334
|
}
|
|
76168
76335
|
for (const path2 of options.extraPaths ?? []) consider(resolve22(path2));
|
|
@@ -77580,9 +77747,9 @@ import {
|
|
|
77580
77747
|
unlinkSync as unlinkSync7,
|
|
77581
77748
|
writeFileSync as writeFileSync22
|
|
77582
77749
|
} from "node:fs";
|
|
77583
|
-
import { dirname as dirname33, join as
|
|
77750
|
+
import { dirname as dirname33, join as join39 } from "node:path";
|
|
77584
77751
|
function savedMachinesPath() {
|
|
77585
|
-
return runtimeOwnedPath(
|
|
77752
|
+
return runtimeOwnedPath(join39(resolveRuntimeNamespace().registryDir, "machines.json"));
|
|
77586
77753
|
}
|
|
77587
77754
|
function loadSavedMachines(path2 = savedMachinesPath()) {
|
|
77588
77755
|
let fd;
|
|
@@ -77713,9 +77880,9 @@ import {
|
|
|
77713
77880
|
writeFileSync as writeFileSync23
|
|
77714
77881
|
} from "node:fs";
|
|
77715
77882
|
import { randomUUID as randomUUID35 } from "node:crypto";
|
|
77716
|
-
import { dirname as dirname34, join as
|
|
77883
|
+
import { dirname as dirname34, join as join40 } from "node:path";
|
|
77717
77884
|
function fleetClientStatePath() {
|
|
77718
|
-
return runtimeOwnedPath(
|
|
77885
|
+
return runtimeOwnedPath(join40(resolveRuntimeNamespace().registryDir, "fleet-view.json"));
|
|
77719
77886
|
}
|
|
77720
77887
|
function loadFleetClientState(path2 = fleetClientStatePath()) {
|
|
77721
77888
|
let fd;
|
|
@@ -77948,14 +78115,14 @@ var init_schemas = __esm({
|
|
|
77948
78115
|
import { createHash as createHash23 } from "node:crypto";
|
|
77949
78116
|
import { realpathSync as realpathSync21 } from "node:fs";
|
|
77950
78117
|
import { existsSync as existsSync28, mkdirSync as mkdirSync27, readFileSync as readFileSync29, renameSync as renameSync17, writeFileSync as writeFileSync24 } from "node:fs";
|
|
77951
|
-
import { dirname as dirname35, join as
|
|
78118
|
+
import { dirname as dirname35, join as join41 } from "node:path";
|
|
77952
78119
|
function path(dir) {
|
|
77953
78120
|
const namespace = resolveRuntimeNamespace();
|
|
77954
78121
|
if (namespace.development) {
|
|
77955
78122
|
const identity2 = createHash23("sha256").update(realpathSync21(dir)).digest("hex");
|
|
77956
|
-
return runtimeOwnedPath(
|
|
78123
|
+
return runtimeOwnedPath(join41(namespace.stateHome, "projects", identity2, "terminals.json"));
|
|
77957
78124
|
}
|
|
77958
|
-
return
|
|
78125
|
+
return join41(dir, TERMINALS_FILE);
|
|
77959
78126
|
}
|
|
77960
78127
|
function ensureDir(dir) {
|
|
77961
78128
|
mkdirSync27(dirname35(path(dir)), { recursive: true });
|
|
@@ -78046,7 +78213,7 @@ __export(auth_service_exports, {
|
|
|
78046
78213
|
});
|
|
78047
78214
|
import * as crypto2 from "node:crypto";
|
|
78048
78215
|
import { readFileSync as readFileSync30, existsSync as existsSync29 } from "node:fs";
|
|
78049
|
-
import { join as
|
|
78216
|
+
import { join as join42 } from "node:path";
|
|
78050
78217
|
import { homedir as homedir5 } from "node:os";
|
|
78051
78218
|
function base64url(buf) {
|
|
78052
78219
|
const b = typeof buf === "string" ? Buffer.from(buf) : buf;
|
|
@@ -78065,8 +78232,8 @@ function signJwt(payload, secret, expiresInSec) {
|
|
|
78065
78232
|
segments.push(base64url(sig));
|
|
78066
78233
|
return segments.join(".");
|
|
78067
78234
|
}
|
|
78068
|
-
function verifyJwt(
|
|
78069
|
-
const parts =
|
|
78235
|
+
function verifyJwt(token2, secret) {
|
|
78236
|
+
const parts = token2.split(".");
|
|
78070
78237
|
if (parts.length !== 3) return { valid: false };
|
|
78071
78238
|
const sigInput = parts[0] + "." + parts[1];
|
|
78072
78239
|
const expected = crypto2.createHmac("sha256", secret).update(sigInput).digest();
|
|
@@ -78115,8 +78282,8 @@ var init_auth_service = __esm({
|
|
|
78115
78282
|
generateToken(userId) {
|
|
78116
78283
|
return signJwt({ userId }, this.jwtSecret, TOKEN_EXPIRY_SEC);
|
|
78117
78284
|
}
|
|
78118
|
-
verifyToken(
|
|
78119
|
-
const result2 = verifyJwt(
|
|
78285
|
+
verifyToken(token2) {
|
|
78286
|
+
const result2 = verifyJwt(token2, this.jwtSecret);
|
|
78120
78287
|
if (!result2.valid) return { valid: false };
|
|
78121
78288
|
return { valid: true, userId: result2.payload.userId };
|
|
78122
78289
|
}
|
|
@@ -78146,8 +78313,8 @@ var init_auth_service = __esm({
|
|
|
78146
78313
|
return { success: false, error: "SSH key not authorized for this user" };
|
|
78147
78314
|
}
|
|
78148
78315
|
this.challenges.delete(auth.challengeId);
|
|
78149
|
-
const
|
|
78150
|
-
return { success: true, userId: challenge.userId, token };
|
|
78316
|
+
const token2 = this.generateToken(challenge.userId);
|
|
78317
|
+
return { success: true, userId: challenge.userId, token: token2 };
|
|
78151
78318
|
}
|
|
78152
78319
|
// ---- SSH helpers -------------------------------------------------------
|
|
78153
78320
|
verifySSHSignature(challenge, signature, publicKeyStr) {
|
|
@@ -78192,7 +78359,7 @@ var init_auth_service = __esm({
|
|
|
78192
78359
|
if (resolveRuntimeNamespace().development) return false;
|
|
78193
78360
|
try {
|
|
78194
78361
|
const home = userId === process.env.USER ? homedir5() : `/home/${userId}`;
|
|
78195
|
-
const authKeysPath =
|
|
78362
|
+
const authKeysPath = join42(home, ".ssh", "authorized_keys");
|
|
78196
78363
|
if (!existsSync29(authKeysPath)) return false;
|
|
78197
78364
|
const authorizedKeys = readFileSync30(authKeysPath, "utf-8");
|
|
78198
78365
|
const parts = publicKey.trim().split(" ");
|
|
@@ -78223,8 +78390,8 @@ function authMiddleware(authService, config2) {
|
|
|
78223
78390
|
if (!authHeader?.startsWith("Bearer ")) {
|
|
78224
78391
|
return c.json({ error: "Missing or invalid Authorization header" }, 401);
|
|
78225
78392
|
}
|
|
78226
|
-
const
|
|
78227
|
-
const result2 = authService.verifyToken(
|
|
78393
|
+
const token2 = authHeader.slice(7);
|
|
78394
|
+
const result2 = authService.verifyToken(token2);
|
|
78228
78395
|
if (!result2.valid) {
|
|
78229
78396
|
return c.json({ error: "Invalid or expired token" }, 401);
|
|
78230
78397
|
}
|
|
@@ -81218,7 +81385,7 @@ var init_inspect = __esm({
|
|
|
81218
81385
|
// packages/daemon/src/lib/filesystem-browser.ts
|
|
81219
81386
|
import { realpathSync as realpathSync22, readdirSync as readdirSync6, statSync as statSync19 } from "node:fs";
|
|
81220
81387
|
import { homedir as homedir6 } from "node:os";
|
|
81221
|
-
import { isAbsolute as isAbsolute20, join as
|
|
81388
|
+
import { isAbsolute as isAbsolute20, join as join43, resolve as resolve29, sep as sep10 } from "node:path";
|
|
81222
81389
|
function isUnderRoot(canonical, root) {
|
|
81223
81390
|
if (canonical === root) return true;
|
|
81224
81391
|
const prefix = root.endsWith(sep10) ? root : root + sep10;
|
|
@@ -81253,7 +81420,7 @@ __export(detect_exports, {
|
|
|
81253
81420
|
detectStack: () => detectStack,
|
|
81254
81421
|
suggestConfig: () => suggestConfig
|
|
81255
81422
|
});
|
|
81256
|
-
import { resolve as resolve30, basename as
|
|
81423
|
+
import { resolve as resolve30, basename as basename14 } from "node:path";
|
|
81257
81424
|
import { readFileSync as readFileSync31, existsSync as existsSync31 } from "node:fs";
|
|
81258
81425
|
function fileExists(dir, name) {
|
|
81259
81426
|
return existsSync31(resolve30(dir, name));
|
|
@@ -81355,7 +81522,7 @@ function detectStack(dir) {
|
|
|
81355
81522
|
return detected;
|
|
81356
81523
|
}
|
|
81357
81524
|
function suggestConfig(dir, detected) {
|
|
81358
|
-
const name =
|
|
81525
|
+
const name = basename14(dir);
|
|
81359
81526
|
const pm = detected.packageManager ?? "npm";
|
|
81360
81527
|
const run = pm === "npm" ? "npm run" : pm;
|
|
81361
81528
|
const config2 = {
|
|
@@ -81659,7 +81826,7 @@ var init_workspace_resource_ids = __esm({
|
|
|
81659
81826
|
|
|
81660
81827
|
// packages/daemon/src/command-center/resources/workspace-files-authority.ts
|
|
81661
81828
|
import { lstatSync as lstatSync13, readdirSync as readdirSync7, readFileSync as readFileSync32, realpathSync as realpathSync23 } from "node:fs";
|
|
81662
|
-
import { basename as
|
|
81829
|
+
import { basename as basename15, dirname as dirname37, resolve as resolvePath, sep as sep11 } from "node:path";
|
|
81663
81830
|
import ignore from "ignore";
|
|
81664
81831
|
function extensionOf(name) {
|
|
81665
81832
|
const dot = name.lastIndexOf(".");
|
|
@@ -81912,7 +82079,7 @@ var init_workspace_files_authority = __esm({
|
|
|
81912
82079
|
if (WorkspaceFileEntrySafe(entry)) entries.push(entry);
|
|
81913
82080
|
}
|
|
81914
82081
|
const truncated = totalEntries > entries.length;
|
|
81915
|
-
const rootLabel = safeName(
|
|
82082
|
+
const rootLabel = safeName(basename15(realRoot), "workspace");
|
|
81916
82083
|
const revision = filesRevision(
|
|
81917
82084
|
JSON.stringify({ dir: relPath, entries: entries.map((e) => `${e.name}:${e.kind}`) })
|
|
81918
82085
|
);
|
|
@@ -81922,7 +82089,7 @@ var init_workspace_files_authority = __esm({
|
|
|
81922
82089
|
}
|
|
81923
82090
|
const directory = relPath === "" ? { id: rootId, name: rootLabel, relativePath: null, parentId: null } : {
|
|
81924
82091
|
id: targetId,
|
|
81925
|
-
name: safeName(
|
|
82092
|
+
name: safeName(basename15(relPath), rootLabel),
|
|
81926
82093
|
relativePath: relPath,
|
|
81927
82094
|
parentId: this.parentId(rootId, relPath)
|
|
81928
82095
|
};
|
|
@@ -82015,7 +82182,7 @@ var init_workspace_files_authority = __esm({
|
|
|
82015
82182
|
"The requested file is unavailable."
|
|
82016
82183
|
);
|
|
82017
82184
|
}
|
|
82018
|
-
if (!isWithin2(realRoot, resolvePath(realParent,
|
|
82185
|
+
if (!isWithin2(realRoot, resolvePath(realParent, basename15(abs)))) {
|
|
82019
82186
|
return this.previewUnavailable(
|
|
82020
82187
|
fileId,
|
|
82021
82188
|
"outside-workspace",
|
|
@@ -82025,7 +82192,7 @@ var init_workspace_files_authority = __esm({
|
|
|
82025
82192
|
if (stat3.isDirectory() || !stat3.isFile()) {
|
|
82026
82193
|
return this.previewUnavailable(fileId, "not-a-file", "The resource is not a regular file.");
|
|
82027
82194
|
}
|
|
82028
|
-
const name =
|
|
82195
|
+
const name = basename15(relPath);
|
|
82029
82196
|
const catalogRevision = filesRevision(`${relPath}:${stat3.size}:${stat3.mtimeMs}`);
|
|
82030
82197
|
const totalBytes = stat3.size;
|
|
82031
82198
|
if (totalBytes > WORKSPACE_FILE_PREVIEW_MAX_CHARACTERS) {
|
|
@@ -82173,11 +82340,11 @@ function parseStatusV2(buffer) {
|
|
|
82173
82340
|
let detached = false;
|
|
82174
82341
|
const changes = [];
|
|
82175
82342
|
for (let i = 0; i < tokens.length; i += 1) {
|
|
82176
|
-
const
|
|
82177
|
-
if (
|
|
82178
|
-
if (
|
|
82179
|
-
if (
|
|
82180
|
-
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);
|
|
82181
82348
|
if (value === "(detached)") {
|
|
82182
82349
|
detached = true;
|
|
82183
82350
|
branch = null;
|
|
@@ -82187,9 +82354,9 @@ function parseStatusV2(buffer) {
|
|
|
82187
82354
|
}
|
|
82188
82355
|
continue;
|
|
82189
82356
|
}
|
|
82190
|
-
const type =
|
|
82357
|
+
const type = token2[0];
|
|
82191
82358
|
if (type === "1" || type === "2") {
|
|
82192
|
-
const fields =
|
|
82359
|
+
const fields = token2.split(" ");
|
|
82193
82360
|
const xy = fields[1] ?? "..";
|
|
82194
82361
|
const pathFrom = type === "1" ? 8 : 9;
|
|
82195
82362
|
const path2 = fields.slice(pathFrom).join(" ");
|
|
@@ -82223,13 +82390,13 @@ function parseStatusV2(buffer) {
|
|
|
82223
82390
|
}
|
|
82224
82391
|
}
|
|
82225
82392
|
} else if (type === "u") {
|
|
82226
|
-
const fields =
|
|
82393
|
+
const fields = token2.split(" ");
|
|
82227
82394
|
const path2 = fields.slice(10).join(" ");
|
|
82228
82395
|
if (path2.length > 0) {
|
|
82229
82396
|
changes.push({ group: "unstaged", status: "conflicted", path: path2, originPath: null });
|
|
82230
82397
|
}
|
|
82231
82398
|
} else if (type === "?") {
|
|
82232
|
-
const path2 =
|
|
82399
|
+
const path2 = token2.slice(2);
|
|
82233
82400
|
if (path2.length > 0) {
|
|
82234
82401
|
changes.push({ group: "untracked", status: "untracked", path: path2, originPath: null });
|
|
82235
82402
|
}
|
|
@@ -82241,9 +82408,9 @@ function parseNumstatZ(buffer) {
|
|
|
82241
82408
|
const tokens = splitNul(buffer);
|
|
82242
82409
|
const map = /* @__PURE__ */ new Map();
|
|
82243
82410
|
for (let i = 0; i < tokens.length; i += 1) {
|
|
82244
|
-
const
|
|
82245
|
-
if (
|
|
82246
|
-
const parts =
|
|
82411
|
+
const token2 = tokens[i];
|
|
82412
|
+
if (token2.length === 0) continue;
|
|
82413
|
+
const parts = token2.split(" ");
|
|
82247
82414
|
if (parts.length < 3) continue;
|
|
82248
82415
|
const addRaw = parts[0];
|
|
82249
82416
|
const delRaw = parts[1];
|
|
@@ -82333,7 +82500,7 @@ var init_workspace_changes_git = __esm({
|
|
|
82333
82500
|
// packages/daemon/src/command-center/resources/workspace-changes-authority.ts
|
|
82334
82501
|
import { spawnSync } from "node:child_process";
|
|
82335
82502
|
import { readFileSync as readFileSync33, realpathSync as realpathSync24, statSync as statSync20 } from "node:fs";
|
|
82336
|
-
import { basename as
|
|
82503
|
+
import { basename as basename16, isAbsolute as isAbsolute22, relative as relative7, resolve as resolvePath2 } from "node:path";
|
|
82337
82504
|
function runGit(args, cwd) {
|
|
82338
82505
|
const result2 = spawnSync("git", args, {
|
|
82339
82506
|
cwd,
|
|
@@ -82387,7 +82554,7 @@ function buildChangeEntry(raw, displayPath, originPath, counts) {
|
|
|
82387
82554
|
id: changeResourceId(raw.group, displayPath),
|
|
82388
82555
|
group: raw.group,
|
|
82389
82556
|
status: raw.status,
|
|
82390
|
-
name:
|
|
82557
|
+
name: basename16(displayPath),
|
|
82391
82558
|
relativePath: displayPath,
|
|
82392
82559
|
originPath: carriesOrigin ? originPath ?? null : null,
|
|
82393
82560
|
binary: counts.binary,
|
|
@@ -83966,13 +84133,13 @@ function mountFleetResourceRoute(app, options) {
|
|
|
83966
84133
|
unavailableMessage: "Fleet catalog capability is unavailable",
|
|
83967
84134
|
mismatchMessage: "Fleet catalog access requires owner authority"
|
|
83968
84135
|
});
|
|
83969
|
-
app.get("/api/resources/fleet-catalog", (c) => {
|
|
84136
|
+
app.get("/api/resources/fleet-catalog", async (c) => {
|
|
83970
84137
|
const gate = authorize(c);
|
|
83971
84138
|
if (gate) return gate;
|
|
83972
84139
|
c.header("Cache-Control", "no-store");
|
|
83973
84140
|
let sessions;
|
|
83974
84141
|
try {
|
|
83975
|
-
sessions = options.readFleet ? options.readFleet() : readAdoptedFleet(options.registry);
|
|
84142
|
+
sessions = options.readFleet ? await options.readFleet() : readAdoptedFleet(options.registry);
|
|
83976
84143
|
} catch {
|
|
83977
84144
|
sessions = null;
|
|
83978
84145
|
}
|
|
@@ -84020,8 +84187,8 @@ function nodeLabel(value) {
|
|
|
84020
84187
|
return normalized.length > 0 ? normalized : null;
|
|
84021
84188
|
}
|
|
84022
84189
|
function groupId(missionId) {
|
|
84023
|
-
const
|
|
84024
|
-
return `group.${
|
|
84190
|
+
const token2 = createHash27("sha256").update(missionId).digest("hex").slice(0, 32);
|
|
84191
|
+
return `group.${token2}`;
|
|
84025
84192
|
}
|
|
84026
84193
|
function projectApplicationShellAgentGraphOverlay(input) {
|
|
84027
84194
|
const { session, appWindows, missionSnapshot, nowSec } = input;
|
|
@@ -84052,7 +84219,7 @@ function projectApplicationShellAgentGraphOverlay(input) {
|
|
|
84052
84219
|
status: nodeStatus(presentation.detectStatus),
|
|
84053
84220
|
statusSource: presentation.statusSource,
|
|
84054
84221
|
attention: presentation.attention,
|
|
84055
|
-
label: nodeLabel(
|
|
84222
|
+
label: nodeLabel(resolvedAgentLabel(pane, presentation, index))
|
|
84056
84223
|
});
|
|
84057
84224
|
nodeWindowIds.add(windowId);
|
|
84058
84225
|
if (pane.role === "lead") leadWindowIds.push(windowId);
|
|
@@ -84605,9 +84772,9 @@ import {
|
|
|
84605
84772
|
rmSync as rmSync5,
|
|
84606
84773
|
writeFileSync as writeFileSync25
|
|
84607
84774
|
} from "node:fs";
|
|
84608
|
-
import { join as
|
|
84775
|
+
import { join as join44 } from "node:path";
|
|
84609
84776
|
function assetRoot() {
|
|
84610
|
-
return runtimeOwnedPath(
|
|
84777
|
+
return runtimeOwnedPath(join44(stateHome(), ASSET_DIRECTORY));
|
|
84611
84778
|
}
|
|
84612
84779
|
function ensureAssetRoot() {
|
|
84613
84780
|
const root = assetRoot();
|
|
@@ -84627,8 +84794,8 @@ function safeName2(name) {
|
|
|
84627
84794
|
}
|
|
84628
84795
|
function assetPaths(root, assetId) {
|
|
84629
84796
|
return {
|
|
84630
|
-
data:
|
|
84631
|
-
metadata:
|
|
84797
|
+
data: join44(root, `${assetId}.bin`),
|
|
84798
|
+
metadata: join44(root, `${assetId}.json`)
|
|
84632
84799
|
};
|
|
84633
84800
|
}
|
|
84634
84801
|
function parseMetadata(raw) {
|
|
@@ -84653,7 +84820,7 @@ function parseMetadata(raw) {
|
|
|
84653
84820
|
}
|
|
84654
84821
|
function pruneAssets(root, now = Date.now()) {
|
|
84655
84822
|
const metadataFiles = readdirSync8(root).filter((name) => /^[0-9a-f]{64}\.json$/u.test(name)).map((name) => {
|
|
84656
|
-
const path2 =
|
|
84823
|
+
const path2 = join44(root, name);
|
|
84657
84824
|
try {
|
|
84658
84825
|
const stat3 = lstatSync14(path2);
|
|
84659
84826
|
return stat3.isFile() && !stat3.isSymbolicLink() ? { name, mtimeMs: stat3.mtimeMs } : null;
|
|
@@ -84664,8 +84831,8 @@ function pruneAssets(root, now = Date.now()) {
|
|
|
84664
84831
|
for (const [index, entry] of metadataFiles.entries()) {
|
|
84665
84832
|
if (index < MAX_ASSET_FILES && now - entry.mtimeMs <= WIDGET_ASSET_RETENTION_MS) continue;
|
|
84666
84833
|
const assetId = entry.name.slice(0, -".json".length);
|
|
84667
|
-
rmSync5(
|
|
84668
|
-
rmSync5(
|
|
84834
|
+
rmSync5(join44(root, `${assetId}.json`), { force: true });
|
|
84835
|
+
rmSync5(join44(root, `${assetId}.bin`), { force: true });
|
|
84669
84836
|
}
|
|
84670
84837
|
}
|
|
84671
84838
|
function publishWidgetAsset(bytes, options) {
|
|
@@ -84694,11 +84861,11 @@ function publishWidgetAsset(bytes, options) {
|
|
|
84694
84861
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
84695
84862
|
};
|
|
84696
84863
|
if (!existsSync33(paths.data)) {
|
|
84697
|
-
const temporary =
|
|
84864
|
+
const temporary = join44(root, `.${assetId}.${randomUUID37()}.bin`);
|
|
84698
84865
|
writeFileSync25(temporary, bytes, { mode: 384, flag: "wx" });
|
|
84699
84866
|
renameSync18(temporary, paths.data);
|
|
84700
84867
|
}
|
|
84701
|
-
const metadataTemporary =
|
|
84868
|
+
const metadataTemporary = join44(root, `.${assetId}.${randomUUID37()}.json`);
|
|
84702
84869
|
writeFileSync25(metadataTemporary, `${JSON.stringify(metadata)}
|
|
84703
84870
|
`, { mode: 384, flag: "wx" });
|
|
84704
84871
|
renameSync18(metadataTemporary, paths.metadata);
|
|
@@ -84760,7 +84927,7 @@ __export(server_exports2, {
|
|
|
84760
84927
|
import { execFile as execFile14 } from "node:child_process";
|
|
84761
84928
|
import { promisify as promisify4 } from "node:util";
|
|
84762
84929
|
import { existsSync as existsSync34, readdirSync as readdirSync9 } from "node:fs";
|
|
84763
|
-
import { join as
|
|
84930
|
+
import { join as join45, dirname as dirname38, basename as basename17 } from "node:path";
|
|
84764
84931
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
84765
84932
|
import { Hono as Hono3 } from "hono";
|
|
84766
84933
|
import { streamSSE as streamSSE3 } from "hono/streaming";
|
|
@@ -84789,12 +84956,12 @@ function workspaceDockSummary(projectDir, workspaceName) {
|
|
|
84789
84956
|
changeCount: safeCount(() => new ChangesAuthority(projectDir, workspaceName).changeCount())
|
|
84790
84957
|
};
|
|
84791
84958
|
}
|
|
84792
|
-
function requireAuth(
|
|
84959
|
+
function requireAuth(token2, localBypassToken) {
|
|
84793
84960
|
return async (c, next) => {
|
|
84794
|
-
if (!
|
|
84961
|
+
if (!token2) return next();
|
|
84795
84962
|
const url = new URL(c.req.url);
|
|
84796
84963
|
const suppliedToken = bearerToken(c.req.header("Authorization")) ?? url.searchParams.get("token");
|
|
84797
|
-
if (suppliedToken ===
|
|
84964
|
+
if (suppliedToken === token2 || localBypassToken && suppliedToken === localBypassToken) {
|
|
84798
84965
|
return next();
|
|
84799
84966
|
}
|
|
84800
84967
|
return c.json({ error: "Remote access token required" }, 401);
|
|
@@ -84988,8 +85155,8 @@ function createApp(options = {}) {
|
|
|
84988
85155
|
}
|
|
84989
85156
|
const body = await c.req.json();
|
|
84990
85157
|
const userId = body.userId ?? authService.getCurrentUser();
|
|
84991
|
-
const
|
|
84992
|
-
return c.json({ token, userId });
|
|
85158
|
+
const token2 = authService.generateToken(userId);
|
|
85159
|
+
return c.json({ token: token2, userId });
|
|
84993
85160
|
});
|
|
84994
85161
|
app.post(
|
|
84995
85162
|
"/api/v2/capabilities",
|
|
@@ -85187,7 +85354,7 @@ function createApp(options = {}) {
|
|
|
85187
85354
|
app.post("/api/workspaces", zValidator("json", AddWorkspaceRequestSchemaZ), async (c) => {
|
|
85188
85355
|
const body = c.req.valid("json");
|
|
85189
85356
|
const registry = getDefaultWorkspaceRegistry();
|
|
85190
|
-
const name = body.name ??
|
|
85357
|
+
const name = body.name ?? basename17(body.projectDir);
|
|
85191
85358
|
if (!name || name.length === 0) {
|
|
85192
85359
|
return c.json({ error: "Cannot derive workspace name from projectDir" }, 400);
|
|
85193
85360
|
}
|
|
@@ -86005,7 +86172,7 @@ function listAvailableTemplates() {
|
|
|
86005
86172
|
const __filename = fileURLToPath9(import.meta.url);
|
|
86006
86173
|
const __dir = dirname38(__filename);
|
|
86007
86174
|
const configuredTemplatesDir = process.env.TMUX_IDE_TEMPLATES_DIR;
|
|
86008
|
-
const templatesDir = configuredTemplatesDir && isAbsolute23(configuredTemplatesDir) ? configuredTemplatesDir :
|
|
86175
|
+
const templatesDir = configuredTemplatesDir && isAbsolute23(configuredTemplatesDir) ? configuredTemplatesDir : join45(__dir, "..", "..", "..", "..", "templates");
|
|
86009
86176
|
if (!existsSync34(templatesDir)) return [];
|
|
86010
86177
|
const labels = {
|
|
86011
86178
|
default: { label: "Default", description: "Single Claude pane + dev/shell row" },
|
|
@@ -86201,6 +86368,7 @@ var init_types = __esm({
|
|
|
86201
86368
|
});
|
|
86202
86369
|
|
|
86203
86370
|
// packages/daemon/src/lib/daemon-embed.ts
|
|
86371
|
+
import { join as join46 } from "node:path";
|
|
86204
86372
|
import { execFileSync as execFileSync20 } from "node:child_process";
|
|
86205
86373
|
import { randomBytes as randomBytes8, randomUUID as randomUUID39 } from "node:crypto";
|
|
86206
86374
|
import { createWriteStream } from "node:fs";
|
|
@@ -86321,11 +86489,11 @@ function isLoopbackRequest(req) {
|
|
|
86321
86489
|
function isLoopbackBind(bindHostname) {
|
|
86322
86490
|
return bindHostname === "127.0.0.1" || bindHostname === "::1" || bindHostname === "localhost";
|
|
86323
86491
|
}
|
|
86324
|
-
function isUpgradeAuthorized(req,
|
|
86325
|
-
if (!
|
|
86492
|
+
function isUpgradeAuthorized(req, token2, localBypassToken, bindHostname) {
|
|
86493
|
+
if (!token2) return true;
|
|
86326
86494
|
if (isLoopbackBind(bindHostname) && isLoopbackRequest(req)) return true;
|
|
86327
86495
|
const supplied = requestToken(req);
|
|
86328
|
-
return supplied ===
|
|
86496
|
+
return supplied === token2 || localBypassToken != null && supplied === localBypassToken;
|
|
86329
86497
|
}
|
|
86330
86498
|
function rejectUpgradeWithPolicy(wss, req, socket, head3) {
|
|
86331
86499
|
wss.handleUpgrade(req, socket, head3, (ws) => {
|
|
@@ -86858,6 +87026,9 @@ async function startEmbeddedDaemonGeneration(opts) {
|
|
|
86858
87026
|
}
|
|
86859
87027
|
}
|
|
86860
87028
|
const tmuxAuthority = resolveWorkspacePaneTmuxAuthority();
|
|
87029
|
+
const readTeamNames = createClaudeTeamNameReader(
|
|
87030
|
+
join46(resolveRuntimeNamespace().claudeDir, "teams")
|
|
87031
|
+
);
|
|
86861
87032
|
const catalogTmuxRunner = createPinnedWorkspaceTmuxRunner(tmuxAuthority);
|
|
86862
87033
|
const initialTmuxProof = captureTmuxServerProof(catalogTmuxRunner);
|
|
86863
87034
|
const initialNativeIdentityParts = initialTmuxProof ? catalogTmuxRunner(["display-message", "-p", "#{pid} #{start_time}"]).split(" ") : null;
|
|
@@ -87270,6 +87441,7 @@ async function startEmbeddedDaemonGeneration(opts) {
|
|
|
87270
87441
|
},
|
|
87271
87442
|
agentStatusProbeFactory: ({ run }) => createTmuxAgentStatusProbe({
|
|
87272
87443
|
run,
|
|
87444
|
+
readTeamNames,
|
|
87273
87445
|
captureNative: (pane, signal) => backgroundCapture?.(
|
|
87274
87446
|
{
|
|
87275
87447
|
paneId: pane.runtimePaneId,
|
|
@@ -87531,16 +87703,34 @@ async function startEmbeddedDaemonGeneration(opts) {
|
|
|
87531
87703
|
peekTerminalAttachmentRuntime,
|
|
87532
87704
|
paneStreamRuntime,
|
|
87533
87705
|
catalogLiveSessions: () => discoverLiveSessionSummaries(catalogTmuxRunner),
|
|
87534
|
-
catalogFleet: () =>
|
|
87535
|
-
|
|
87536
|
-
|
|
87537
|
-
|
|
87538
|
-
sessionName2,
|
|
87539
|
-
|
|
87540
|
-
|
|
87541
|
-
|
|
87542
|
-
|
|
87543
|
-
|
|
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
|
+
},
|
|
87544
87734
|
fleetPreviewCapture: createFleetPreviewCapture(fleetFactsTmuxRunner, {
|
|
87545
87735
|
serverEpoch: () => observationSelector?.nativeServerEpoch ?? null,
|
|
87546
87736
|
capture: (request3, signal) => backgroundCapture?.(request3, signal) ?? Promise.resolve(null)
|
|
@@ -87920,6 +88110,7 @@ var requireFromHere2, DEFAULT_HOSTNAME, DEFAULT_GRACEFUL_MS, EMBEDDED_SESSION_NA
|
|
|
87920
88110
|
var init_daemon_embed = __esm({
|
|
87921
88111
|
"packages/daemon/src/lib/daemon-embed.ts"() {
|
|
87922
88112
|
"use strict";
|
|
88113
|
+
init_claude_team_names();
|
|
87923
88114
|
init_pane_source_discovery();
|
|
87924
88115
|
init_background_native_capture();
|
|
87925
88116
|
init_owned_viewer_factory();
|
|
@@ -88360,7 +88551,7 @@ __export(development_owner_exports, {
|
|
|
88360
88551
|
verifyManagedDevelopmentAdmission: () => verifyManagedDevelopmentAdmission
|
|
88361
88552
|
});
|
|
88362
88553
|
import { realpathSync as realpathSync26, writeFileSync as writeFileSync26 } from "node:fs";
|
|
88363
|
-
import { join as
|
|
88554
|
+
import { join as join47 } from "node:path";
|
|
88364
88555
|
async function claimManagedDevelopmentLaunch(instance, attempt) {
|
|
88365
88556
|
if (!/^[a-f0-9-]{36}$/u.test(attempt)) throw new Error("Invalid development launch attempt");
|
|
88366
88557
|
const owner = readDevelopmentOwner(instance);
|
|
@@ -88368,7 +88559,7 @@ async function claimManagedDevelopmentLaunch(instance, attempt) {
|
|
|
88368
88559
|
throw new Error("A live or unknown managed owner is protected");
|
|
88369
88560
|
requireDevelopmentNotSuspended(instance);
|
|
88370
88561
|
writeFileSync26(
|
|
88371
|
-
|
|
88562
|
+
join47(instance.root, `launch-${attempt}.json`),
|
|
88372
88563
|
JSON.stringify({ version: 1, attempt, pid: process.pid }),
|
|
88373
88564
|
{ flag: "wx", mode: 384 }
|
|
88374
88565
|
);
|
|
@@ -88377,7 +88568,7 @@ async function claimManagedDevelopmentLaunch(instance, attempt) {
|
|
|
88377
88568
|
function verifyManagedDevelopmentAdmission(instance, attempt, expected) {
|
|
88378
88569
|
requireDevelopmentNotSuspended(instance);
|
|
88379
88570
|
const current = readPrivateDevelopmentRecord(
|
|
88380
|
-
|
|
88571
|
+
join47(instance.root, "startup.json")
|
|
88381
88572
|
);
|
|
88382
88573
|
if (!current || current.attempt !== attempt || current.attempt !== expected.attempt || current.generation !== expected.generation || current.manifestHash !== expected.manifestHash)
|
|
88383
88574
|
throw new Error("Managed owner admission changed before startup");
|
|
@@ -88388,7 +88579,7 @@ async function runManagedDevelopmentOwner() {
|
|
|
88388
88579
|
if (!instance) throw new Error("Managed development owner requires a development namespace");
|
|
88389
88580
|
const identity2 = await readDevelopmentIdentity(instance);
|
|
88390
88581
|
const attempt = process.env.TMUX_IDE_DEVELOPMENT_ATTEMPT;
|
|
88391
|
-
const pending = readPrivateDevelopmentRecord(
|
|
88582
|
+
const pending = readPrivateDevelopmentRecord(join47(instance.root, "startup.json"));
|
|
88392
88583
|
const build = readDevelopmentBuild(instance);
|
|
88393
88584
|
if (!identity2 || identity2.capability !== namespace.cleanupToken || !attempt || pending?.attempt !== attempt || pending.generation !== build.generation || pending.manifestHash !== process.env.TMUX_IDE_DEVELOPMENT_BUILD_HASH)
|
|
88394
88585
|
throw new Error("Development launch admission does not match owner");
|
|
@@ -88398,7 +88589,7 @@ async function runManagedDevelopmentOwner() {
|
|
|
88398
88589
|
if (!incarnation) throw new Error("Cannot establish managed owner incarnation");
|
|
88399
88590
|
await claimManagedDevelopmentLaunch(instance, attempt);
|
|
88400
88591
|
verifyManagedDevelopmentAdmission(instance, attempt, pending);
|
|
88401
|
-
const log = createBoundedDevelopmentLog(
|
|
88592
|
+
const log = createBoundedDevelopmentLog(join47(instance.root, "logs/owner.log"));
|
|
88402
88593
|
const originalOut = process.stdout.write;
|
|
88403
88594
|
const originalErr = process.stderr.write;
|
|
88404
88595
|
const writer = ((chunk, encodingOrCallback, callback) => {
|
|
@@ -88415,7 +88606,7 @@ async function runManagedDevelopmentOwner() {
|
|
|
88415
88606
|
json: true,
|
|
88416
88607
|
expectedVersion: build.packageVersion,
|
|
88417
88608
|
onOwnedReady: () => {
|
|
88418
|
-
writeDevelopmentRecord(
|
|
88609
|
+
writeDevelopmentRecord(join47(instance.root, "owner.json"), {
|
|
88419
88610
|
version: 1,
|
|
88420
88611
|
attempt,
|
|
88421
88612
|
pid: process.pid,
|
|
@@ -88462,7 +88653,7 @@ import {
|
|
|
88462
88653
|
readdirSync as readdirSync10,
|
|
88463
88654
|
copyFileSync as copyFileSync2
|
|
88464
88655
|
} from "node:fs";
|
|
88465
|
-
import { resolve as resolve32, join as
|
|
88656
|
+
import { resolve as resolve32, join as join48, basename as basename18, dirname as dirname39 } from "node:path";
|
|
88466
88657
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
88467
88658
|
function copyTemplateSkills(targetDir) {
|
|
88468
88659
|
const created = [];
|
|
@@ -88471,20 +88662,20 @@ function copyTemplateSkills(targetDir) {
|
|
|
88471
88662
|
mkdirSync29(targetDir, { recursive: true });
|
|
88472
88663
|
for (const file of readdirSync10(templateSkillsDir)) {
|
|
88473
88664
|
if (!file.endsWith(".md")) continue;
|
|
88474
|
-
const destination =
|
|
88475
|
-
copyFileSync2(
|
|
88665
|
+
const destination = join48(targetDir, file);
|
|
88666
|
+
copyFileSync2(join48(templateSkillsDir, file), destination);
|
|
88476
88667
|
created.push(destination);
|
|
88477
88668
|
}
|
|
88478
88669
|
return created;
|
|
88479
88670
|
}
|
|
88480
88671
|
function scaffoldLibraryStubs(dir) {
|
|
88481
88672
|
const created = [];
|
|
88482
|
-
const libraryDir =
|
|
88673
|
+
const libraryDir = join48(dir, ".tmux-ide", "library");
|
|
88483
88674
|
if (!existsSync35(libraryDir)) {
|
|
88484
88675
|
mkdirSync29(libraryDir, { recursive: true });
|
|
88485
88676
|
created.push(libraryDir);
|
|
88486
88677
|
}
|
|
88487
|
-
const archPath =
|
|
88678
|
+
const archPath = join48(libraryDir, "architecture.md");
|
|
88488
88679
|
if (!existsSync35(archPath)) {
|
|
88489
88680
|
writeFileSync27(
|
|
88490
88681
|
archPath,
|
|
@@ -88492,7 +88683,7 @@ function scaffoldLibraryStubs(dir) {
|
|
|
88492
88683
|
);
|
|
88493
88684
|
created.push(archPath);
|
|
88494
88685
|
}
|
|
88495
|
-
const learningsPath =
|
|
88686
|
+
const learningsPath = join48(libraryDir, "learnings.md");
|
|
88496
88687
|
if (!existsSync35(learningsPath)) {
|
|
88497
88688
|
writeFileSync27(
|
|
88498
88689
|
learningsPath,
|
|
@@ -88504,11 +88695,11 @@ function scaffoldLibraryStubs(dir) {
|
|
|
88504
88695
|
}
|
|
88505
88696
|
function scaffoldValidationContract(dir) {
|
|
88506
88697
|
const created = [];
|
|
88507
|
-
const tasksDir =
|
|
88698
|
+
const tasksDir = join48(dir, ".tasks");
|
|
88508
88699
|
if (!existsSync35(tasksDir)) {
|
|
88509
88700
|
mkdirSync29(tasksDir, { recursive: true });
|
|
88510
88701
|
}
|
|
88511
|
-
const contractPath =
|
|
88702
|
+
const contractPath = join48(tasksDir, "validation-contract.md");
|
|
88512
88703
|
if (!existsSync35(contractPath)) {
|
|
88513
88704
|
writeFileSync27(
|
|
88514
88705
|
contractPath,
|
|
@@ -88522,7 +88713,7 @@ function scaffoldAgentsMd(dir, name) {
|
|
|
88522
88713
|
const created = [];
|
|
88523
88714
|
const agentsTemplatePath = resolve32(__dirname4, "..", "..", "..", "templates", "AGENTS.md");
|
|
88524
88715
|
if (existsSync35(agentsTemplatePath)) {
|
|
88525
|
-
const agentsPath =
|
|
88716
|
+
const agentsPath = join48(dir, "AGENTS.md");
|
|
88526
88717
|
if (!existsSync35(agentsPath)) {
|
|
88527
88718
|
const content = readFileSync35(agentsTemplatePath, "utf-8").replace(/{{name}}/g, name);
|
|
88528
88719
|
writeFileSync27(agentsPath, content);
|
|
@@ -88543,7 +88734,7 @@ function scaffoldTeamWorkspace(dir, name) {
|
|
|
88543
88734
|
}
|
|
88544
88735
|
function scaffoldMissionsWorkspace(dir, name) {
|
|
88545
88736
|
const created = [];
|
|
88546
|
-
const skillsDir =
|
|
88737
|
+
const skillsDir = join48(dir, ".tmux-ide", "skills");
|
|
88547
88738
|
created.push(...copyTemplateSkills(skillsDir));
|
|
88548
88739
|
created.push(...scaffoldTeamWorkspace(dir, name));
|
|
88549
88740
|
return created;
|
|
@@ -88564,7 +88755,7 @@ async function init({
|
|
|
88564
88755
|
outputError(`Template "${template}" not found`, "NOT_FOUND");
|
|
88565
88756
|
}
|
|
88566
88757
|
let content = readFileSync35(templatePath, "utf-8");
|
|
88567
|
-
const name2 =
|
|
88758
|
+
const name2 = basename18(dir);
|
|
88568
88759
|
content = content.replace(/^name: .+/m, `name: ${name2}`);
|
|
88569
88760
|
const yaml6 = (await import("js-yaml")).default;
|
|
88570
88761
|
const workspace = WorkspaceConfigV1SchemaZ.parse(yaml6.load(content));
|
|
@@ -88575,11 +88766,11 @@ async function init({
|
|
|
88575
88766
|
created = scaffoldMissionsWorkspace(dir, name2);
|
|
88576
88767
|
} else if (isTeamTemplate(template)) {
|
|
88577
88768
|
created = [
|
|
88578
|
-
...copyTemplateSkills(
|
|
88769
|
+
...copyTemplateSkills(join48(dir, ".tmux-ide", "skills")),
|
|
88579
88770
|
...scaffoldTeamWorkspace(dir, name2)
|
|
88580
88771
|
];
|
|
88581
88772
|
} else {
|
|
88582
|
-
created = copyTemplateSkills(
|
|
88773
|
+
created = copyTemplateSkills(join48(dir, ".tmux-ide", "skills"));
|
|
88583
88774
|
}
|
|
88584
88775
|
if (json2) {
|
|
88585
88776
|
console.log(JSON.stringify({ created: true, template, name: name2, paths: created }));
|
|
@@ -88593,7 +88784,7 @@ async function init({
|
|
|
88593
88784
|
return;
|
|
88594
88785
|
}
|
|
88595
88786
|
const detected = detectStack(dir);
|
|
88596
|
-
const name =
|
|
88787
|
+
const name = basename18(dir);
|
|
88597
88788
|
if (detected.frameworks.length > 0) {
|
|
88598
88789
|
const config2 = suggestConfig(dir, detected);
|
|
88599
88790
|
writeConfig(dir, config2);
|
|
@@ -88621,7 +88812,7 @@ async function init({
|
|
|
88621
88812
|
console.log("Edit it to configure your workspace, then run: tmux-ide");
|
|
88622
88813
|
}
|
|
88623
88814
|
}
|
|
88624
|
-
const skillsDir =
|
|
88815
|
+
const skillsDir = join48(dir, ".tmux-ide", "skills");
|
|
88625
88816
|
if (!existsSync35(skillsDir)) {
|
|
88626
88817
|
const created = copyTemplateSkills(skillsDir);
|
|
88627
88818
|
if (created.length > 0 && !json2) {
|
|
@@ -89220,23 +89411,23 @@ __export(skill_sync_exports, {
|
|
|
89220
89411
|
versionMarker: () => versionMarker
|
|
89221
89412
|
});
|
|
89222
89413
|
import { existsSync as existsSync36, mkdirSync as mkdirSync30, readFileSync as readFileSync36, writeFileSync as writeFileSync28 } from "node:fs";
|
|
89223
|
-
import { dirname as dirname40, join as
|
|
89414
|
+
import { dirname as dirname40, join as join49 } from "node:path";
|
|
89224
89415
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
89225
89416
|
function claudeDir() {
|
|
89226
89417
|
return resolveRuntimeNamespace().claudeDir;
|
|
89227
89418
|
}
|
|
89228
89419
|
function skillTargetDir() {
|
|
89229
|
-
return runtimeOwnedPath(
|
|
89420
|
+
return runtimeOwnedPath(join49(claudeDir(), "skills", "tmux-ide"));
|
|
89230
89421
|
}
|
|
89231
89422
|
function skillTargetFile() {
|
|
89232
|
-
return
|
|
89423
|
+
return join49(skillTargetDir(), "SKILL.md");
|
|
89233
89424
|
}
|
|
89234
89425
|
function defaultSkillSource() {
|
|
89235
89426
|
const here = dirname40(fileURLToPath11(import.meta.url));
|
|
89236
89427
|
const candidates = [
|
|
89237
|
-
|
|
89428
|
+
join49(here, "../skill/SKILL.md"),
|
|
89238
89429
|
// bundled bin/cli.js → repo root
|
|
89239
|
-
|
|
89430
|
+
join49(here, "../../../../skill/SKILL.md")
|
|
89240
89431
|
// dev src/lib → repo root
|
|
89241
89432
|
];
|
|
89242
89433
|
return candidates.find((c) => existsSync36(c)) ?? candidates[0];
|
|
@@ -89253,7 +89444,7 @@ function rewriteVersionMarker(content, version) {
|
|
|
89253
89444
|
return content.replace(VERSION_MARKER_RE, versionMarker(version));
|
|
89254
89445
|
}
|
|
89255
89446
|
function installedSkillVersion(dir = skillTargetDir()) {
|
|
89256
|
-
const file =
|
|
89447
|
+
const file = join49(dir, "SKILL.md");
|
|
89257
89448
|
if (!existsSync36(file)) return null;
|
|
89258
89449
|
try {
|
|
89259
89450
|
return parseSkillVersion(readFileSync36(file, "utf-8"));
|
|
@@ -89269,7 +89460,7 @@ function syncSkill({
|
|
|
89269
89460
|
throw new Error("Automatic skill sync is disabled in development instances");
|
|
89270
89461
|
const rendered = rewriteVersionMarker(readFileSync36(source, "utf-8"), version);
|
|
89271
89462
|
const dir = skillTargetDir();
|
|
89272
|
-
const target =
|
|
89463
|
+
const target = join49(dir, "SKILL.md");
|
|
89273
89464
|
const existing = existsSync36(target) ? readFileSync36(target, "utf-8") : null;
|
|
89274
89465
|
if (existing === rendered) {
|
|
89275
89466
|
return { action: "unchanged", path: target, to: version };
|
|
@@ -92043,7 +92234,7 @@ __export(worktree_exports, {
|
|
|
92043
92234
|
worktreeSessionName: () => worktreeSessionName
|
|
92044
92235
|
});
|
|
92045
92236
|
import { execFileSync as execFileSync23 } from "node:child_process";
|
|
92046
|
-
import { basename as
|
|
92237
|
+
import { basename as basename19, dirname as dirname43, isAbsolute as isAbsolute24, join as join50, resolve as resolve39 } from "node:path";
|
|
92047
92238
|
function sanitizeForTmux(part) {
|
|
92048
92239
|
return part.replace(/[.:/\s]+/g, "-");
|
|
92049
92240
|
}
|
|
@@ -92052,11 +92243,11 @@ function worktreeSessionName(project, branch) {
|
|
|
92052
92243
|
}
|
|
92053
92244
|
function defaultWorktreeBaseDir(repoDir) {
|
|
92054
92245
|
const abs = resolve39(repoDir);
|
|
92055
|
-
return
|
|
92246
|
+
return join50(dirname43(abs), `${basename19(abs)}-worktrees`);
|
|
92056
92247
|
}
|
|
92057
92248
|
function worktreePath(repoDir, branch, configuredDir) {
|
|
92058
92249
|
const base2 = configuredDir && configuredDir.length > 0 ? isAbsolute24(configuredDir) ? configuredDir : resolve39(repoDir, configuredDir) : defaultWorktreeBaseDir(repoDir);
|
|
92059
|
-
return
|
|
92250
|
+
return join50(base2, branch);
|
|
92060
92251
|
}
|
|
92061
92252
|
function parseWorktreeList(porcelain) {
|
|
92062
92253
|
const entries = [];
|
|
@@ -92191,7 +92382,7 @@ var init_worktree = __esm({
|
|
|
92191
92382
|
|
|
92192
92383
|
// packages/daemon/src/lib/install-origin.ts
|
|
92193
92384
|
import { existsSync as existsSync38, readFileSync as readFileSync38, realpathSync as realpathSync27 } from "node:fs";
|
|
92194
|
-
import { dirname as dirname44, join as
|
|
92385
|
+
import { dirname as dirname44, join as join51 } from "node:path";
|
|
92195
92386
|
import { fileURLToPath as fileURLToPath13 } from "node:url";
|
|
92196
92387
|
function detectPackageManager(path2) {
|
|
92197
92388
|
if (/\/(?:Cellar|Caskroom)\//.test(path2)) return "homebrew";
|
|
@@ -92206,9 +92397,9 @@ function findGitCheckoutRoot(startDir) {
|
|
|
92206
92397
|
let dir = startDir;
|
|
92207
92398
|
for (; ; ) {
|
|
92208
92399
|
if (dir.endsWith("/node_modules")) return null;
|
|
92209
|
-
if (existsSync38(
|
|
92400
|
+
if (existsSync38(join51(dir, ".git"))) {
|
|
92210
92401
|
try {
|
|
92211
|
-
if (JSON.parse(readFileSync38(
|
|
92402
|
+
if (JSON.parse(readFileSync38(join51(dir, "package.json"), "utf8")).name === "tmux-ide")
|
|
92212
92403
|
return dir;
|
|
92213
92404
|
} catch {
|
|
92214
92405
|
}
|
|
@@ -92229,7 +92420,7 @@ function installOrigin(cliDir = dirname44(fileURLToPath13(import.meta.url))) {
|
|
|
92229
92420
|
let detected = detectPackageManager(path2);
|
|
92230
92421
|
if (detected === "npm" || detected === "pnpm" || detected === "bun") {
|
|
92231
92422
|
try {
|
|
92232
|
-
if (JSON.parse(readFileSync38(
|
|
92423
|
+
if (JSON.parse(readFileSync38(join51(path2, "../package.json"), "utf8")).name !== "tmux-ide")
|
|
92233
92424
|
detected = "unknown";
|
|
92234
92425
|
} catch {
|
|
92235
92426
|
detected = "unknown";
|
|
@@ -92255,7 +92446,7 @@ __export(update_exports, {
|
|
|
92255
92446
|
runUpdate: () => runUpdate
|
|
92256
92447
|
});
|
|
92257
92448
|
import { realpathSync as realpathSync28 } from "node:fs";
|
|
92258
|
-
import { dirname as dirname45, join as
|
|
92449
|
+
import { dirname as dirname45, join as join52 } from "node:path";
|
|
92259
92450
|
import { execFileSync as execFileSync24 } from "node:child_process";
|
|
92260
92451
|
function planUpdate(input) {
|
|
92261
92452
|
const current = input.currentVersion ?? getCurrentVersion();
|
|
@@ -92332,7 +92523,7 @@ function runUpdate({ cliDir, dryRun, json: json2 = false }, dependencies = {}) {
|
|
|
92332
92523
|
plan.executable === "bun" ? ["pm", "bin", "-g"] : ["root", "-g"]
|
|
92333
92524
|
).trim();
|
|
92334
92525
|
if (!root.startsWith("/")) throw new Error("invalid manager path");
|
|
92335
|
-
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"));
|
|
92336
92527
|
if (target !== source.path) throw new Error("different installation");
|
|
92337
92528
|
} catch {
|
|
92338
92529
|
plan = {
|
|
@@ -92389,7 +92580,7 @@ __export(pane_widget_exports, {
|
|
|
92389
92580
|
paneWidgetId: () => paneWidgetId,
|
|
92390
92581
|
paneWidgetIdForFile: () => paneWidgetIdForFile
|
|
92391
92582
|
});
|
|
92392
|
-
import { basename as
|
|
92583
|
+
import { basename as basename20, extname } from "node:path";
|
|
92393
92584
|
function imageMediaTypeFor(fileName) {
|
|
92394
92585
|
return IMAGE_MEDIA_BY_EXTENSION.get(extname(fileName).toLowerCase()) ?? null;
|
|
92395
92586
|
}
|
|
@@ -92407,7 +92598,7 @@ function buildMarkdownAnnouncement(text, title) {
|
|
|
92407
92598
|
}
|
|
92408
92599
|
}
|
|
92409
92600
|
function buildImageAnnouncement(bytes, filePath) {
|
|
92410
|
-
const name =
|
|
92601
|
+
const name = basename20(filePath);
|
|
92411
92602
|
const media = imageMediaTypeFor(name);
|
|
92412
92603
|
if (media === null) {
|
|
92413
92604
|
throw new PaneWidgetRefusal(
|
|
@@ -92461,7 +92652,7 @@ function paneWidgetIdForFile(fileName) {
|
|
|
92461
92652
|
if ([".md", ".markdown"].includes(extension)) return "markdown";
|
|
92462
92653
|
if (IMAGE_MEDIA_BY_EXTENSION.has(extension)) return "image";
|
|
92463
92654
|
if (extension === ".json") return "card";
|
|
92464
|
-
const name =
|
|
92655
|
+
const name = basename20(fileName) || fileName || "input";
|
|
92465
92656
|
throw new PaneWidgetRefusal(
|
|
92466
92657
|
"unsupported-source",
|
|
92467
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).`
|
|
@@ -92602,7 +92793,7 @@ var init_server3 = __esm({
|
|
|
92602
92793
|
|
|
92603
92794
|
// bin/cli.ts
|
|
92604
92795
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
92605
|
-
import { resolve as resolve40, dirname as dirname46, join as
|
|
92796
|
+
import { resolve as resolve40, dirname as dirname46, join as join53 } from "node:path";
|
|
92606
92797
|
import { execFileSync as execFileSync25 } from "node:child_process";
|
|
92607
92798
|
import { appendFileSync as appendFileSync2, existsSync as existsSync39, mkdirSync as mkdirSync31, writeFileSync as writeFileSync29 } from "node:fs";
|
|
92608
92799
|
import { fileURLToPath as fileURLToPath14 } from "node:url";
|
|
@@ -92917,9 +93108,9 @@ Install bun (https://bun.sh) \u2014 the TUI surfaces run on it. Sources ship wit
|
|
|
92917
93108
|
let automaticDiagnosticLog;
|
|
92918
93109
|
if (surface === "app" && !process.env.TMUX_IDE_TUI_PERF_LOG && !process.env.TMUX_IDE_TUI_LOG) {
|
|
92919
93110
|
try {
|
|
92920
|
-
const logDirectory =
|
|
93111
|
+
const logDirectory = join53(stateHome(), "logs");
|
|
92921
93112
|
mkdirSync31(logDirectory, { recursive: true, mode: 448 });
|
|
92922
|
-
automaticDiagnosticLog =
|
|
93113
|
+
automaticDiagnosticLog = join53(logDirectory, "tui-latest.jsonl");
|
|
92923
93114
|
writeFileSync29(
|
|
92924
93115
|
automaticDiagnosticLog,
|
|
92925
93116
|
`${JSON.stringify({
|
|
@@ -94380,7 +94571,7 @@ Known panels: ${POPUP_WIDGETS2.join(", ")}.`,
|
|
|
94380
94571
|
} = await Promise.resolve().then(() => (init_pane_widget(), pane_widget_exports));
|
|
94381
94572
|
const { publishWidgetAsset: publishWidgetAsset2, WidgetAssetStoreError: WidgetAssetStoreError2 } = await Promise.resolve().then(() => (init_widget_asset_store(), widget_asset_store_exports));
|
|
94382
94573
|
const { readFileSync: readFileSync39, watchFile, unwatchFile } = await import("node:fs");
|
|
94383
|
-
const { basename:
|
|
94574
|
+
const { basename: basename21 } = await import("node:path");
|
|
94384
94575
|
const readStdin = async () => {
|
|
94385
94576
|
const chunks = [];
|
|
94386
94577
|
for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk));
|
|
@@ -94401,9 +94592,9 @@ Known panels: ${POPUP_WIDGETS2.join(", ")}.`,
|
|
|
94401
94592
|
const publish = () => {
|
|
94402
94593
|
const asset = publishWidgetAsset2(readFileSync39(file), {
|
|
94403
94594
|
media: "text/markdown",
|
|
94404
|
-
name:
|
|
94595
|
+
name: basename21(file)
|
|
94405
94596
|
});
|
|
94406
|
-
return buildMarkdownAssetAnnouncement2(asset.assetId,
|
|
94597
|
+
return buildMarkdownAssetAnnouncement2(asset.assetId, basename21(file));
|
|
94407
94598
|
};
|
|
94408
94599
|
announcement = publish();
|
|
94409
94600
|
watchedFile = file;
|
|
@@ -94418,14 +94609,14 @@ Known panels: ${POPUP_WIDGETS2.join(", ")}.`,
|
|
|
94418
94609
|
if (!media) {
|
|
94419
94610
|
throw new PaneWidgetRefusal2(
|
|
94420
94611
|
"unsupported-media",
|
|
94421
|
-
`"${
|
|
94612
|
+
`"${basename21(file)}" is not a supported raster image.`
|
|
94422
94613
|
);
|
|
94423
94614
|
}
|
|
94424
94615
|
const asset = publishWidgetAsset2(readFileSync39(file), {
|
|
94425
94616
|
media,
|
|
94426
|
-
name:
|
|
94617
|
+
name: basename21(file)
|
|
94427
94618
|
});
|
|
94428
|
-
return buildImageAssetAnnouncement2(asset.assetId, { name:
|
|
94619
|
+
return buildImageAssetAnnouncement2(asset.assetId, { name: basename21(file) });
|
|
94429
94620
|
};
|
|
94430
94621
|
announcement = publish();
|
|
94431
94622
|
watchedFile = file;
|