Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion packages/api/src/services/container-tasks-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ const commandSuggestsSsh = (command: string): boolean => command.startsWith("ssh
const commandSuggestsAgent = (command: string): boolean =>
interactiveAgentPattern.test(command) || command.includes("docker-git-agent-")

// Rust browser MCP helpers (`browser-connection`, `docker-git-browser-connection`)
// run on an allocated pty, so without this they would be misclassified as visible
// `ssh` terminals and flood the task manager (issue #383).
const browserConnectionPattern = /(?:^|\/)(?:docker-git-browser-connection|browser-connection)\b/u

const commandSuggestsBrowserHelper = (command: string): boolean => browserConnectionPattern.test(command)

const resolveAncestorManagedId = (
process: RawContainerProcess,
pidToProcess: ReadonlyMap<number, RawContainerProcess>,
Expand All @@ -49,6 +56,9 @@ const classifyProcess = (
process: RawContainerProcess,
managedId: string | undefined
): ContainerTaskKind => {
if (commandSuggestsBrowserHelper(process.command)) {
return "system"
}
if (managedId !== undefined || commandSuggestsAgent(process.command)) {
return "agent"
}
Expand Down Expand Up @@ -78,7 +88,7 @@ const compareTasks = (left: ContainerTask, right: ContainerTask): number => {
// FORMAT THEOREM: forall p in Processes: classify(p) in ContainerTaskKind
// PURITY: CORE
// EFFECT: none
// INVARIANT: includeDefault=false excludes only baseline system processes
// INVARIANT: includeDefault=false excludes system processes (baseline + browser helpers)
// COMPLEXITY: O(n * h) where h is maximum process ancestry depth
export const buildContainerTasks = (
processes: ReadonlyArray<RawContainerProcess>,
Expand Down
24 changes: 24 additions & 0 deletions packages/api/tests/container-tasks-core.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,30 @@ describe("container task classification", () => {
.toHaveLength(1)
})

it("hides browser-connection MCP helpers as internal system tasks", () => {
const browserCommand =
"browser-connection --project dg-docker-git-issue-376 --network container:dg-docker-git-issue-376"
const visible = buildContainerTasks(
[
processOf({ command: browserCommand, pid: 11502, ppid: 5142, tty: "pts/1" }),
processOf({ command: "/usr/local/bin/docker-git-browser-connection start", pid: 11600, ppid: 5142, tty: "pts/1" }),
processOf({ command: "node server.js", pid: 20, ppid: 1, tty: "pts/2" })
],
[],
false
)

expect(visible.map((task) => task.pid)).toEqual([20])

const withSystem = buildContainerTasks(
[processOf({ command: browserCommand, pid: 11502, ppid: 5142, tty: "pts/1" })],
[],
true
)

expect(withSystem.map((task) => [task.pid, task.kind])).toEqual([[11502, "system"]])
})

it("marks descendants of managed agent pid as agent tasks", () => {
const tasks = buildContainerTasks(
[
Expand Down
Loading