Repository navigation
[pi] Name workspaces after the first prompt #8866
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
9a52a7d
8e40696
c0224e8
e042364
22c6e83
4ec0b92
2bd0904
2c5e19a
3f9588a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,3 @@ | ||
| import Darwin | ||
| import Foundation | ||
|
|
||
| extension CMUXCLI { | ||
|
|
@@ -119,51 +118,56 @@ extension CMUXCLI { | |
| telemetry: CLISocketSentryTelemetry | ||
| ) { | ||
| let selfPath: String = { | ||
| if let first = ProcessInfo.processInfo.arguments.first, | ||
| first.hasPrefix("/"), | ||
| FileManager.default.isExecutableFile(atPath: first) { | ||
| return first | ||
| if let first = ProcessInfo.processInfo.arguments.first { | ||
| let resolved = URL( | ||
| fileURLWithPath: first, | ||
| relativeTo: URL(fileURLWithPath: FileManager.default.currentDirectoryPath, isDirectory: true) | ||
| ).standardizedFileURL.path | ||
| if isExecutableRegularFile(atPath: resolved) { | ||
| return resolved | ||
| } | ||
| } | ||
| if let bundled = normalizedHookValue(env["CMUX_BUNDLED_CLI_PATH"]), | ||
| FileManager.default.isExecutableFile(atPath: bundled) { | ||
| isExecutableRegularFile(atPath: bundled) { | ||
| return bundled | ||
| } | ||
| return "cmux" | ||
| }() | ||
| let process = Process() | ||
| process.executableURL = URL(fileURLWithPath: "/bin/sh") | ||
| process.arguments = [ | ||
| "-c", | ||
| "\"$0\" hooks \"$1\" auto-name --session \"$2\" --workspace \"$3\" --surface \"$4\" --transcript \"$5\" --cwd \"$6\" </dev/null >/dev/null 2>&1 &", | ||
| selfPath, | ||
| def.name, | ||
| sessionId, | ||
| workspaceId, | ||
| surfaceId, | ||
| transcriptPath ?? "", | ||
| cwd ?? "" | ||
| let hookArguments = [ | ||
| "hooks", def.name, "auto-name", | ||
| "--session", sessionId, | ||
| "--workspace", workspaceId, | ||
| "--surface", surfaceId, | ||
| "--transcript", transcriptPath ?? "", | ||
| "--cwd", cwd ?? "" | ||
| ] | ||
| let process = Process() | ||
| process.executableURL = URL(fileURLWithPath: selfPath.hasPrefix("/") ? selfPath : "/usr/bin/env") | ||
| process.arguments = selfPath.hasPrefix("/") ? hookArguments : [selfPath] + hookArguments | ||
| var spawnEnv = env | ||
| spawnEnv["CMUX_CLAUDE_HOOK_STATE_PATH"] = agentHookStatePath(sessionStoreSuffix: def.sessionStoreSuffix, env: env) | ||
| process.environment = spawnEnv | ||
| process.standardInput = FileHandle.nullDevice | ||
| process.standardOutput = FileHandle.nullDevice | ||
| process.standardError = FileHandle.nullDevice | ||
| do { | ||
| // Launch the bounded worker directly; the short-lived hook process must not own its lifetime. | ||
| try process.run() | ||
|
Comment on lines
153
to
155
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Files:"
git ls-files | rg '(^|/)CLI/CMUXCLI\+AutoNamingHooks\.swift$|AutoNaming|auto-name|llmTimeout|summarize' || true
echo
echo "Target file outline:"
ast-grep outline CLI/CMUXCLI+AutoNamingHooks.swift --view expanded || true
echo
echo "Target file around relevant lines:"
if [ -f CLI/CMUXCLI+AutoNamingHooks.swift ]; then
nl -ba CLI/CMUXCLI+AutoNamingHooks.swift | sed -n '1,240p'
fi
echo
echo "Search timeout/termination wrapper refs:"
rg -n "llmTimeout|summarize|auto-name|die|SIGKILL|process\.run|Process|run\(\)" CLI CodeRabbit Inc . --glob '!*.{png,jpg,jpeg,webp,gif,svg,aar,swiftinterface,xcstrings}' | head -n 250Repository: manaflow-ai/cmux Length of output: 1212 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Install available line-number alternatives and inspect file:"
for f in CLI/CMUXCLI+AutoNamingHooks.swift CLI/CMUXCLI+.AutoNamingHooks.swift; do
[ ${f%% *:-.} = "$f" ] || continue
done
wc -l CLI/CMUXCLI+AutoNamingHooks.swift
awk '{printf "%6d\t%s\n", NR, $0}' CLI/CMUXCLI+AutoNamingHooks.swift | sed -n '1,260p'
echo
echo "Search timeout/termination references:"
rg -n "llmTimeout|summarize|auto-name|SIGKILL|terminate\(|die|process\.run\(\)|Process\.init|run\(\)" -S . --glob '!*.{png,jpg,jpeg,webp,gif,svg,aar,swiftinterface,xcstrings}' || true
echo
echo "Diff around changed file if present:"
git diff -- CLI/CMUXCLI+AutoNamingHooks.swift | sed -n '1,240p' || trueRepository: manaflow-ai/cmux Length of output: 50373 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Limited source inspection for AutoNamingHooks and related auto-name files:"
for f in CLI/CMUXCLI+AutoNamingHooks.swift CLI/CMUXCLI+AutoNamingDispatch.swift CLI/CMUXCLI+AutoNamingGenericHooks.swift CLI/CMUXCLI+AutoNamingSummarizers.swift CLI/CMUXCLI+AutoNaming.swift; do
if [ -f "$f" ]; then
echo "===== $f: $(wc -l < "$f") lines ====="
fi
done
echo "===== CLI/CMUXCLI+AutoNamingHooks.swift lines 1-240 ====="
python3 - <<'PY'
from pathlib import Path
p=Path('CLI/CMUXCLI+AutoNamingHooks.swift')
if p.exists():
for i,line in enumerate(p.read_text().splitlines(), 1):
if 1 <= i <= 240:
print(f"{i:5d}\t{line}")
PY
echo "===== CLI/CMUXCLI+AutoNamingDispatch.swift lines 1-260 ====="
python3 - <<'PY'
from pathlib import Path
p=Path('CLI/CMUXCLI+AutoNamingDispatch.swift')
if p.exists():
for i,line in enumerate(p.read_text().splitlines(), 1):
if 1 <= i <= 260:
print(f"{i:5d}\t{line}")
PY
echo "===== Search timeout/termination/cleanup refs excluding broad file types ====="
rg -n "llmTimeout|summarize|\.run\(\)|Process|SIGKILL|SIGTERM|terminate\(|kill|timeout|AutoNamingHooks|spawnDetachedAgentAutoName|runClaudeAutoNameHook|runCodexAutoNameHook" CLI --glob '*.swift' || true
echo "===== Git diff stats and hunks for renamed/deleted hook files ====="
git diff --stat -- '*AutoNamingHook*' '*AutoNamingDispatch*' || true
git diff -- '*AutoNamingHook*' '*AutoNamingDispatch*' | sed -n '1,260p' || trueRepository: manaflow-ai/cmux Length of output: 50373 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "===== CLI/CMUXCLI+AutoNamingGenericHooks.swift lines 1-220 ====="
python3 - <<'PY'
from pathlib import Path
p=Path('CLI/CMUXCLI+AutoNamingGenericHooks.swift')
if p.exists():
for i,line in enumerate(p.read_text().splitlines(), 1):
if 1 <= i <= 220:
print(f"{i:5d}\t{line}")
PY
echo "===== CLI/CMUXCLI+AutoNamingSummarizers.swift lines 1-220 ====="
python3 - <<'PY'
from pathlib import Path
p=Path('CLI/CMUXCLI+AutoNamingSummarizers.swift')
if p.exists():
for i,line in enumerate(p.read_text().splitlines(), 1):
if 1 <= i <= 220:
print(f"{i:5d}\t{line}")
PY
echo "===== CLI/CMUXCLI+AutoNaming.swift lines 1-260 ====="
python3 - <<'PY'
from pathlib import Path
p=Path('CLI/CMUXCLI+AutoNaming.swift')
if p.exists():
for i,line in enumerate(p.read_text().splitlines(), 1):
if 1 <= i <= 260:
print(f"{i:5d}\t{line}")
PY
echo "===== CLI/CMUXCLI+Process.swift lines 290-500 ====="
python3 - <<'PY'
from pathlib import Path
p=Path('CLI/CMUXCLI+Process.swift')
if p.exists():
for i,line in enumerate(p.read_text().splitlines(), 1):
if 290 <= i <= 500:
print(f"{i:5d}\t{line}")
PY
echo "===== Direct invocation helper usages ====="
rg -n "runAutoNamingSummarizer|runProcessData|runProcess\\(|cliRunProcess\\(|timeout:|process\\.run\\(|spawnDetachedAgentAutoName\\(|AgentHook|auto-name" CLI --glob '*.swift' | sed -n '1,220p'Repository: manaflow-ai/cmux Length of output: 50372 Add a process owner/deadline to the detached worker or apply
🤖 Prompt for AI Agents |
||
| } catch { | ||
| telemetry.breadcrumb("\(def.name)-hook.auto-name.spawn-failed") | ||
| return | ||
| } | ||
| if ((try? waitForProcessExit(process, timeout: 2)) ?? false) == false { | ||
| process.terminate() | ||
| if ((try? waitForProcessExit(process, timeout: 1)) ?? false) == false { | ||
| kill(process.processIdentifier, SIGKILL) | ||
| _ = try? waitForProcessExit(process, timeout: 1) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private func isExecutableRegularFile(atPath path: String) -> Bool { | ||
| // Resolve symlinks before rejecting non-regular filesystem entries. | ||
| let resolvedURL = URL(fileURLWithPath: path).resolvingSymlinksInPath() | ||
| guard let values = try? resolvedURL.resourceValues(forKeys: [.isRegularFileKey]), | ||
| values.isRegularFile == true else { | ||
| return false | ||
| } | ||
| return FileManager.default.isExecutableFile(atPath: path) | ||
| } | ||
|
|
||
| /// Detached Codex naming pass. | ||
| func runCodexAutoNameHook( | ||
| commandArgs: [String], | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.