Skip to content
Merged
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
5 changes: 2 additions & 3 deletions .github/nightly-step-coverage.json
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,7 @@
"Wait through GitHub API rate limits in this job's gh calls": {"pr": "ci-guards.yml:workflow-guard-tests:Validate nightly publish-path gh calls wait through a rate limit"},

"Pick the Blacksmith macOS label with a moving queue": {"pr": "ci-guards.yml:workflow-guard-tests:Validate the nightly signing jobs take a Blacksmith label with a moving queue"},
"List newer pending nightly-next notarizations": {"pr": "ci-guards.yml:workflow-guard-tests:Validate the nightly-next pending notarization continuation"},
"Read the visual gate's verdicts": {"pr": "ci-guards.yml:workflow-guard-tests:Test the cmux NEXT nightly visual gate"}},
"List newer pending nightly-next notarizations": {"pr": "ci-guards.yml:workflow-guard-tests:Validate the nightly-next pending notarization continuation"}},
"recover-nightly-next-notarization": {
"Mint the release App token for this job's gh calls": {"nightly_only": "mints release GitHub App token"},
"Send this job's gh calls as the release App, github.token as the fallback": {"pr": "ci-guards.yml:workflow-guard-tests:Validate the nightly publish jobs send gh calls as the release App first"},
Expand Down Expand Up @@ -442,7 +441,7 @@
"Enforce the verdict": {"plumbing": true}},
"visual-gate-nightly-verdict": {
"Wait for the visual gate, at most 10 min past the signed build": {"pr": "ci-guards.yml:workflow-guard-tests:Test the cmux NEXT nightly visual gate"},
"Fail with the gate when it holds the build": {"plumbing": true}},
"Record failed advisory verdict": {"plumbing": true}},
"report-visual-gate-nightly": {
"Record the verdict in the visual gate issue": {"nightly_only": "writes the verdict comment to the nightly-next visual gate issue with the run's token"}}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,78 @@
"state": "translated",
"value": "コンパクトなワークスペース一覧"
}
},
"bs": {
"stringUnit": {
"state": "needs_review",
"value": "Kompaktna lista radnih prostora"
}
},
"da": {
"stringUnit": {
"state": "needs_review",
"value": "Kompakt liste over arbejdsområder"
}
},
"it": {
"stringUnit": {
"state": "needs_review",
"value": "Elenco compatto delle aree di lavoro"
}
},
"km": {
"stringUnit": {
"state": "needs_review",
"value": "បញ្ជីកន្លែងធ្វើការបង្រួម"
}
},
"nb": {
"stringUnit": {
"state": "needs_review",
"value": "Kompakt liste over arbeidsområder"
}
},
"pl": {
"stringUnit": {
"state": "needs_review",
"value": "Kompaktowa lista przestrzeni roboczych"
}
},
"pt-BR": {
"stringUnit": {
"state": "needs_review",
"value": "Lista Compacta de Áreas de Trabalho"
}
},
"ru": {
"stringUnit": {
"state": "needs_review",
"value": "Компактный список рабочих пространств"
}
},
"th": {
"stringUnit": {
"state": "needs_review",
"value": "รายการเวิร์กสเปซแบบกะทัดรัด"
}
},
"tr": {
"stringUnit": {
"state": "needs_review",
"value": "Kompakt Çalışma Alanı Listesi"
}
},
"uk": {
"stringUnit": {
"state": "needs_review",
"value": "Компактний список робочих областей"
}
},
"vi": {
"stringUnit": {
"state": "needs_review",
"value": "Danh sách không gian làm việc thu gọn"
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15141,6 +15141,12 @@
"ja" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "%lld件のアップデートがあります"
}
},
"other" : {
"stringUnit" : {
"state" : "needs_review",
Expand All @@ -15153,6 +15159,12 @@
"km" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "មានបច្ចុប្បន្នភាព %lld"
}
},
"other" : {
"stringUnit" : {
"state" : "needs_review",
Expand All @@ -15165,6 +15177,12 @@
"ko" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "%lld개 업데이트 가능"
}
},
"other" : {
"stringUnit" : {
"state" : "needs_review",
Expand Down Expand Up @@ -15279,6 +15297,12 @@
"th" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "มีการอัปเดต %lld รายการ"
}
},
"other" : {
"stringUnit" : {
"state" : "needs_review",
Expand Down Expand Up @@ -15339,6 +15363,12 @@
"vi" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Có %lld bản cập nhật"
}
},
"other" : {
"stringUnit" : {
"state" : "needs_review",
Expand All @@ -15351,6 +15381,12 @@
"zh-Hans" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "有 %lld 项更新"
}
},
"other" : {
"stringUnit" : {
"state" : "needs_review",
Expand All @@ -15363,6 +15399,12 @@
"zh-Hant" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "有 %lld 項更新"
}
},
"other" : {
"stringUnit" : {
"state" : "needs_review",
Expand Down
1 change: 1 addition & 0 deletions release-notes/next/highlights/chat-title-plain.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
title: A plain chat title
category: improved
pr: https://github.com/manaflow-ai/cmux/pull/29920

The chat's name in the header is plain text, with no pill or dropdown. Double-click it or press ⌘R to rename; Move to machine and Delete join the chat's ⋮ menu with its other actions.
1 change: 1 addition & 0 deletions release-notes/next/highlights/cloud-live-previews.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
title: Open Cloud web previews in the browser
category: improved
pr: https://github.com/manaflow-ai/cmux/pull/30334

Cloud Machine Ports discovers your running servers and lets you open a private preview in the app's browser. The same preview links are available from the CLI.
1 change: 1 addition & 0 deletions release-notes/next/highlights/working-harness-tab-icons.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
title: Working chats keep their custom tab icons
category: fixed
pr: https://github.com/manaflow-ai/cmux/pull/27905

Pinned and narrow chat tabs keep their custom harness icon visible beside the working spinner, so you can still tell your agents apart.
2 changes: 1 addition & 1 deletion scripts/cmux-next/check-daemon-capabilities.sh
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ runtime_only = {
"agent-inventory-watch-admission-v1", "agent-inventory-watch-v1",
"agent-session-attach-v1", "agent-session-children-v1", "agent-session-folders-v1", "agent-session-observe-v1",
"agent-session-presence-v1", "agent-session-settings-v1", "agent-session-start-keyed-reason-v1", "agent-session-start-v1",
"agent-session-start-vm-kind-v1", "agent-session-start-model-v1", "agent-session-trust-v1", "agent-session-trust-vm-kind-v1",
"agent-session-start-vm-kind-v1", "agent-session-start-model-v1", "agent-session-start-no-cwd-v1", "agent-session-trust-v1", "agent-session-trust-vm-kind-v1",
"cloud-attachments-v1", "cloud-chief-live-v1",
"cloud-conversation-runs-v1", "cloud-conversation-typing-v1", "cloud-conversations-v1",
"cloud-host-replica-v1", "cloud-selfhost-v1", "history-v1", "terminal-reaper-active-v1",
Expand Down
32 changes: 31 additions & 1 deletion tests/test-execution.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2265,7 +2265,8 @@ lane = "linux-guard"

[[test]]
path = "tests/test_ci_blacksmith_linux_sizes.py"
lane = "linux-guard"
lane = "manual"
reason = "Lawrence 2026-10-23: no new CI tests. #30360 registered it as linux-guard without a ci-guards.yml step, which reddened tooling-tests on every pull request. Checks .github/runners.json linux_sizes against every Blacksmith Linux runs-on; run python3 tests/test_ci_blacksmith_linux_sizes.py yourself after changing a runs-on label or that table (about 3 s, no build)."

[[test]]
path = "tests/test_cmux_tui_artifacts_linux_runner_set.py"
Expand Down Expand Up @@ -2395,3 +2396,32 @@ lane = "linux-guard"
path = "tests/test_nightly_tree_source_marker.py"
lane = "manual"
reason = "Portable source-contract test; run python3 tests/test_nightly_tree_source_marker.py through cmux-ci when tree observations change. No new CI gate."

[[test]]
path = "tests/test_nightly_dedicated_mini.py"
lane = "linux-guard"

[[test]]
path = "tests/test_cloud_pair_proof.py"
lane = "manual"
reason = "Lawrence 2026-10-23: no new CI tests. Guardrails of scripts/ci/cmux_next_cloud_pair_proof.py, the fleet Cloud chat proof (#30473); run python3 tests/test_cloud_pair_proof.py yourself after changing that script (under 1 s, no build)."

[[test]]
path = "tests/test_cmux_next_gate_plan_suite_steps.py"
lane = "manual"
reason = "Lawrence 2026-10-23: no new CI tests. Checks gate-plan.py's CmuxNext suite steps against the cmux-ci controller's ci-step limits; run python3 tests/test_cmux_next_gate_plan_suite_steps.py yourself after changing scripts/cmux-next/gate-plan.py or gate-run.sh (about 1 s, no build)."

[[test]]
path = "tests/test_cmux_next_guardrails_qos.py"
lane = "manual"
reason = "Lawrence 2026-10-23: no new CI gates. The file says so itself: run python3 tests/test_cmux_next_guardrails_qos.py yourself after changing guardrails.py's task-priority rule (about 2 s, no build)."

[[test]]
path = "tests/test_cmux_next_perf_budgets.py"
lane = "manual"
reason = "Lawrence 2026-10-23: no new CI tests. Checks scripts/cmux-next/perf-budgets.py's table and gate; run python3 tests/test_cmux_next_perf_budgets.py yourself after changing it (under 1 s, no build)."

[[test]]
path = "tests/test_cmux_tui_no_bundled_webpki_roots.py"
lane = "manual"
reason = "Lawrence 2026-10-23: no new CI tests. Checks that cmux-tui compiles in no webpki root list (#25452); run python3 tests/test_cmux_tui_no_bundled_webpki_roots.py yourself after changing a cmux-tui Cargo.toml, Cargo.lock or TLS setup (about 1 s, no build)."
17 changes: 12 additions & 5 deletions tests/test_cmux_next_checks_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -907,10 +907,10 @@ def test_dispatch_runs_every_tier_on_any_ref(self):
self.assertNotIn("next-batch", jobs["request-cmux-next-dev-publish"]["if"])

def test_branch_lookup_uses_git_https_basic_auth_and_a_timeout(self):
for filename, job_id in (("cmux-next.yml", "push-head-preflight"),
("cmux-tui-artifacts.yml", "tree-preflight")):
for filename, job_id, step_id in (("cmux-next.yml", "push-head-preflight", "head"),
("cmux-tui-artifacts.yml", "tree-preflight", "inspect")):
document = yaml.safe_load((WORKFLOW.parent / filename).read_text())
script = document["jobs"][job_id]["steps"][-1]["run"]
script = preflight_step(document, job_id, step_id)["run"]
with self.subTest(workflow=filename):
self.assertIn("Authorization: Basic", script)
self.assertIn("x-access-token:%s", script)
Expand Down Expand Up @@ -995,6 +995,13 @@ def test_a_timed_out_step_takes_its_children_with_it(self):
self.fail(f"step child {child} outlived the timed-out step")


def preflight_step(document, job_id, step_id):
"""The preflight step by id: steps after it (tree-preflight's owner observation, #30221) do not move it."""
steps = [step for step in document["jobs"][job_id]["steps"] if step.get("id") == step_id]
assert len(steps) == 1, f"{job_id} has {len(steps)} steps with id {step_id!r}"
return steps[0]


class PushPreflightBehavior(unittest.TestCase):
"""Execute the workflow shell with bounded fake network and git responses."""

Expand All @@ -1003,8 +1010,8 @@ def run_preflight(self, *, artifacts=False, event="push", ref="refs/heads/feat-c
missing="", malformed=False, fork=False):
filename = "cmux-tui-artifacts.yml" if artifacts else "cmux-next.yml"
workflow = yaml.safe_load((WORKFLOW.parent / filename).read_text())
job_id = "tree-preflight" if artifacts else "push-head-preflight"
script = workflow["jobs"][job_id]["steps"][-1]["run"]
job_id, step_id = ("tree-preflight", "inspect") if artifacts else ("push-head-preflight", "head")
script = preflight_step(workflow, job_id, step_id)["run"]
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
git = root / "git"
Expand Down
7 changes: 5 additions & 2 deletions tests/test_cmux_next_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,10 +747,13 @@ def setUpClass(cls):
import cmux_next_route as route_module
cls.route = route_module

# Page JavaScript a suite runs, and the ways a suite gives the page its own document.
# Page JavaScript a suite runs, and the ways a suite gives the page its own document. An agent pane
# pointed at a dev server URL (AgentPaneSource.devURLVariable, honored in Debug test builds) loads that
# URL, not the built bundle: AgentPageHibernationTests points it at a loopback port nobody serves and
# waits for that load to end (#30312).
TALKS_TO_PAGE = re.compile(r"\b(?:evaluateJavaScript|callAsyncJavaScript|waitUntilLoaded|WKUserScript)\b")
OWN_DOCUMENT = re.compile(r'loadHTMLString|registerBundledRoot|allowFixtureRoot|AgentPageTestRoot'
r'|source:\s*\.bundled\(|index\.html|\.html"')
r'|source:\s*\.bundled\(|index\.html|\.html"|AgentPaneSource\.devURLVariable')
OPT_IN = re.compile(r"\.enabled\(if:\s*ProcessInfo\.processInfo\.environment\[")

def test_the_bundle_targets_are_the_ones_the_bundle_build_writes_into(self):
Expand Down
4 changes: 4 additions & 0 deletions tests/test_nightly_next_arm64_only.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ def compile_commands(outputs):
(root / "scripts/ci/background_build.py").write_text((ROOT / "scripts/ci/background_build.py").read_text())
(root / "scripts/lib").mkdir(parents=True)
(root / "scripts/lib/rust-targets.sh").write_text((ROOT / "scripts/lib/rust-targets.sh").read_text())
# The Release step sources the shared cache-failure classifier (#30107).
(root / "scripts/cmux-next/lib").mkdir(parents=True)
(root / "scripts/cmux-next/lib/compilation-cache.sh").write_text(
(ROOT / "scripts/cmux-next/lib/compilation-cache.sh").read_text())
capture = root / "capture"
capture.mkdir()
steps = (
Expand Down
10 changes: 9 additions & 1 deletion tests/test_nightly_next_identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,15 @@ def job_containing(text: str) -> str:
def job_env(block: str, name: str) -> str:
match = re.search(rf"\n {name}: ([^\n]+)\n", block)
assert match, f"no job env {name}"
return match.group(1)
value = match.group(1)
# A YAML anchor (`&name value`) or alias (`*name`, #30278 shares env values to keep nightly.yml
# under GitHub's size limit) reads as the anchored value, as YAML does.
alias = re.fullmatch(r"\*([A-Za-z0-9_-]+)", value)
if alias:
anchors = re.findall(rf"[ :]&{re.escape(alias[1])} ([^\n]+)\n", WORKFLOW)
assert len(anchors) == 1, f"alias *{alias[1]} has {len(anchors)} anchors"
value = anchors[0]
return re.sub(r"^&[A-Za-z0-9_-]+ ", "", value)


def test_each_app_reads_the_feed_its_publisher_writes():
Expand Down
Loading