Command: python -c "import sys,inspect;sys.path.insert(0,'..');import sheet_relay as sr;print(inspect.getsource(sr._execute_command));print('===START===');print(inspect.getsource(sr.start_bridge_job))"
Directory: projects
Status: SUCCESS
Exit code: 0
Cancel Job Rerun Command Refresh
def _execute_command(cfg, command):
action = command.get("action", "")
payload = json.loads(command.get("payload_json") or "{}")
started = time.time()
command_id = command["id"]
allowed, policy_error = policy_check(action, payload)
if action != "policy_explain" and not allowed:
return result(command_id, "error", 403, "", policy_error, started, {"policy": "deny", "action": action})
if action in {"capabilities", "capabilities_summary", "capabilities_categories", "capabilities_get"}:
data = capabilities() if action == "capabilities" else capabilities_summary() if action == "capabilities_summary" else capabilities_categories(payload) if action == "capabilities_categories" else capabilities_get(payload)
status = "done" if data.get("ok", True) else "error"
return result(command_id, status, 200 if status == "done" else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"capability_query": action})
if action in {"task_gc", "task_archive"}:
data = task_gc(payload) if action == "task_gc" else task_archive(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"task_cleanup": action, "archived_count": data.get("archived_count", 0)})
if action == "task_run_step":
data = task_run_step(cfg, payload, started, command_id)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"task_id": data.get("task_id", ""), "job_id": data.get("job_id", ""), "step": data.get("step", "")})
if action == "task_run_next":
data = task_run_next(cfg, payload, started, command_id)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"task_id": data.get("task_id", ""), "job_id": data.get("job_id", ""), "step": data.get("step", "")})
if action == "task_retry_step":
data = task_retry_step(cfg, payload, started, command_id)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"task_id": data.get("task_id", ""), "job_id": data.get("job_id", ""), "step": data.get("step", "")})
if action == "task_refresh":
data = task_refresh(cfg, payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 404, json.dumps(data, indent=2), data.get("error", ""), started, {"task_id": data.get("task_id", ""), "changed_steps": len(data.get("changed", []))})
if action == "task_next_actions":
data = task_next_actions(cfg, payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 404, json.dumps(data, indent=2), data.get("error", ""), started, {"task_id": data.get("task_id", ""), "state": data.get("state", "")})
if action == "task_evidence":
data = task_evidence(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 404, json.dumps(data, indent=2), data.get("error", ""), started, {"task_id": data.get("task_id", ""), "evidence_path": data.get("evidence_path", "")})
if action == "task_summary":
data = task_summary(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 404, json.dumps(data, indent=2), data.get("error", ""), started, {"task_id": data.get("task_id", ""), "summary": True})
if action in {"adb_select", "adb_selection_status"}:
data = adb_selection(action, payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"adb_serial": data.get("serial", "")})
if action == "task_group_next_actions":
payload_out = task_group_next_actions(payload)
status = "done" if payload_out.get("ok") else "error"
return result(command_id, status, 200 if payload_out.get("ok") else 404, json.dumps(payload_out, indent=2), payload_out.get("error", ""), started, {"group_id": payload_out.get("group_id", ""), "state": payload_out.get("state", "")})
if action == "task_group_refresh":
payload_out = task_group_refresh(cfg, payload)
status = "done" if payload_out.get("ok") else "error"
return result(command_id, status, 200 if payload_out.get("ok") else 404, json.dumps(payload_out, indent=2), payload_out.get("error", ""), started, {"group_id": payload_out.get("group", {}).get("group_id", ""), "job_states": len(payload_out.get("job_states", []))})
if action == "task_group_run":
payload_out = task_group_run(cfg, payload, command_id)
status = "done" if payload_out.get("ok") else "error"
http_status = 200 if payload_out.get("ok") else 400
return result(command_id, status, http_status, json.dumps(payload_out, indent=2), payload_out.get("error", ""), started, {"group_id": payload_out.get("group_id", ""), "run_id": payload_out.get("run_id", ""), "job_count": len(payload_out.get("results", []))})
if action.startswith("task_group_") or action in {"task_spawn", "task_join"}:
payload_out = group_action(cfg, action, payload)
status = "done" if payload_out.get("ok") else "error"
http_status = 200 if payload_out.get("ok") else 400
group_id = payload_out.get("group_id") or payload_out.get("group", {}).get("group_id", "")
return result(command_id, status, http_status, json.dumps(payload_out, indent=2), payload_out.get("error", ""), started, {"group_id": group_id, "group_action": action})
if action.startswith("task_"):
payload_out = task_action(action, payload)
status = "done" if payload_out.get("ok") else "error"
http_status = 200 if payload_out.get("ok") else 400
return result(command_id, status, http_status, json.dumps(payload_out, indent=2), payload_out.get("error", ""), started, {"task_id": payload_out.get("task_id") or payload_out.get("task", {}).get("task_id", ""), "task_action": action})
if action == "agent_status":
data = agent_status(cfg)
return result(command_id, "done", 200, json.dumps(data, indent=2), "", started, {"relay_revision": REVISION})
if action == "policy_status":
data = policy_status()
return result(command_id, "done", 200, json.dumps(data, indent=2), "", started, {"policy_source": data["source"]})
if action == "policy_explain":
data = policy_explain(payload)
return result(command_id, "done", 200, json.dumps(data, indent=2), "", started, {"decision": data["decision"]})
if action == "hook_status":
data = hook_status()
return result(command_id, "done", 200, json.dumps(data, indent=2), "", started, {"hook_events": len(data["recent_events"])})
if action == "recent_add":
data = recent_add(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"recent_category": data.get("category", "")})
if action in {"project_memory", "project_memory_save"}:
data = project_memory(payload, write=action == "project_memory_save")
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"memory_category": data.get("category", ""), "memory_source": data.get("source", "")})
if action == "recent_status":
data = recent_status()
return result(command_id, "done", 200, json.dumps(data, indent=2), "", started)
if action == "self_check":
data = self_check(cfg)
return result(command_id, "done" if data["ok"] else "error", 200 if data["ok"] else 503, json.dumps(data, indent=2), "" if data["ok"] else "self_check_failed", started, {"self_check": data["ok"], "legacy_routes_ok": data["all_legacy_http_ok"]})
if action.startswith("verify_"):
if action == "verify_next_actions":
data = verify_next_actions(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 404, json.dumps(data, indent=2), data.get("error", ""), started, {"verify_id": data.get("verify_id", ""), "verify_status": data.get("status", "")})
payload_out = verify_action(action, payload)
status = "done" if payload_out.get("ok") else "error"
http_status = 200 if payload_out.get("ok") else 400
verify_id = payload_out.get("verify_id") or payload_out.get("verify", {}).get("verify_id", "")
return result(command_id, status, http_status, json.dumps(payload_out, indent=2), payload_out.get("error", ""), started, {"verify_id": verify_id, "verify_action": action})
if action == "parallel_run":
data = parallel_run(cfg, payload, command_id)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"parallel_jobs": len(data.get("results", [])), "max_parallel": data.get("max_parallel", 0)})
if action == "hook_run":
return hook_run(cfg, payload, started, command_id)
if action == "hook_run_declared":
return hook_run_declared(cfg, payload, started, command_id)
if action == "diagnostics":
source = str(payload.get("text", ""))
if payload.get("job_id"):
out = call_bridge(cfg, "/job", {"id": payload["job_id"]}, 30)
if out["http_status"] >= 400:
return result(command_id, "error", out["http_status"], out["text"], out["text"][-2000:], started, {"job_id": payload["job_id"]})
source = out["text"]
parsed = parse_diagnostics(source)
data = {"ok": True, "diagnostics": diagnostic_navigation(parsed, payload.get("radius", 10)), "count": len(parsed), "parser": "best-effort-compiler-patterns"}
return result(command_id, "done", 200, json.dumps(data, indent=2), "", started, {"diagnostics": data["count"]})
if action == "evidence_save":
data = payload.get("data", {})
if not isinstance(data, dict):
return result(command_id, "error", 400, "", "data must be an object", started)
path = save_evidence(payload.get("name", command_id), data)
return result(command_id, "done", 200, json.dumps({"ok": True, "path": path}, indent=2), "", started, {"evidence_path": path})
if action == "evidence_catalog":
data = evidence_catalog(payload)
return result(command_id, "done", 200, json.dumps(data, indent=2), "", started, {"evidence_count": data["count"]})
if action == "evidence_read":
data = evidence_read(payload)
return result(command_id, "done" if data.get("ok") else "error", 200 if data.get("ok") else 404, json.dumps(data, indent=2), data.get("error", ""), started, {"evidence_path": data.get("path", "")})
gradle_tasks = {
"gradle_tasks": "tasks",
"gradle_test": "test",
"gradle_lint": "lint",
"gradle_dependencies": "dependencies",
}
if action in gradle_tasks:
return start_bridge_job(cfg, "/gradle/run", {"cwd": payload.get("cwd", ""), "task": gradle_tasks[action]}, started, command_id, action)
if action == "gradle_build":
variant = str(payload.get("variant", "debug")).lower()
task = "assembleRelease" if variant == "release" else "assembleDebug"
return start_bridge_job(cfg, "/gradle/run", {"cwd": payload.get("cwd", ""), "task": task}, started, command_id, action)
if action in {"adb_devices", "adb_logcat", "adb_logcat_clear", "adb_shell", "adb_activity", "adb_ui_tree", "adb_screenshot", "adb_crash_lines", "adb_install_latest", "adb_install", "adb_uninstall", "adb_pull", "adb_push"}:
serial = str(payload.get("serial", "")).strip()
if action != "adb_devices" and not serial:
selected = load_json(ADB_STATE_PATH, {})
if isinstance(selected, dict):
serial = str(selected.get("serial", "")).strip()
if action == "adb_devices":
command_text = "adb devices"
elif action == "adb_logcat_clear":
command_text = "adb logcat -c"
elif action == "adb_shell":
shell_command = str(payload.get("cmd", "")).strip()
if not shell_command:
return result(command_id, "error", 400, "", "cmd_required", started)
command_text = "adb shell " + shell_command
elif action == "adb_activity":
command_text = "adb shell dumpsys activity activities"
elif action == "adb_ui_tree":
command_text = "adb shell uiautomator dump /sdcard/window.xml && adb shell cat /sdcard/window.xml"
elif action == "adb_screenshot":
command_text = "adb exec-out screencap -p"
elif action == "adb_crash_lines":
command_text = "adb logcat -d -t 500 *:E"
elif action == "adb_install_latest":
artifact_root = ROOT / "bridge-output"
apks = [item for item in artifact_root.rglob("*.apk") if item.is_file() and not any(part in EXCLUDED_DIRS for part in item.parts)] if artifact_root.exists() else []
if not apks:
return result(command_id, "error", 404, "", "no_apk_artifact_found", started)
latest = max(apks, key=lambda item: item.stat().st_mtime).resolve()
command_text = "adb install -r \"" + str(latest).replace('"', '') + "\""
elif action == "adb_install":
apk = safe_adb_host_file(payload.get("path", payload.get("apk", "")))
if not apk or apk.suffix.lower() != ".apk":
return result(command_id, "error", 400, "", "apk_path_not_in_workspace_or_artifacts", started)
command_text = "adb install -r \"" + str(apk).replace('"', '') + "\""
elif action == "adb_uninstall":
package = str(payload.get("package", "")).strip()
if not re.fullmatch(r"[A-Za-z][A-Za-z0-9_.]{0,254}", package):
return result(command_id, "error", 400, "", "invalid_package_name", started)
command_text = "adb uninstall " + package
elif action == "adb_pull":
remote = safe_adb_remote(payload.get("remote", ""))
local = safe_adb_host_file(payload.get("local", ""), allow_missing=True)
if not remote or not local:
return result(command_id, "error", 400, "", "invalid_adb_pull_path", started)
command_text = "adb pull \"" + remote + "\" \"" + str(local).replace('"', '') + "\""
elif action == "adb_push":
local = safe_adb_host_file(payload.get("local", payload.get("path", "")))
remote = safe_adb_remote(payload.get("remote", ""))
if not local or not remote:
return result(command_id, "error", 400, "", "invalid_adb_push_path", started)
command_text = "adb push \"" + str(local).replace('"', '') + "\" \"" + remote + "\""
else:
command_text = "adb logcat -d -t 200"
if payload.get("filter"):
log_filter = str(payload["filter"]).strip()
if not re.fullmatch(r"[A-Za-z0-9_.*:#=+\-, ]{1,200}", log_filter):
return result(command_id, "error", 400, "", "invalid_logcat_filter", started)
command_text += " " + log_filter
if serial:
if not re.fullmatch(r"[A-Za-z0-9._:-]{1,100}", serial):
return result(command_id, "error", 400, "", "invalid_device_serial", started)
command_text = "adb -s " + serial + " " + command_text[4:]
params = {"cmd": b64url(command_text)}
if str(payload.get("confirm", "")) != "1":
out = call_bridge(cfg, "/adb/run", params, 45)
return result(command_id, "done" if out["http_status"] < 400 else "error", out["http_status"], out["text"], "", started, {"operation": action, "requires_confirm": True})
params["confirm"] = "1"
out = call_bridge(cfg, "/adb/run", params, 60)
job_id = parse_job_id(out["text"])
return result(command_id, "done" if out["http_status"] < 400 and job_id else "error", out["http_status"], out["text"], "" if job_id else "ADB job id not found", started, {"operation": action, "job_id": job_id})
if action == "system_info":
return result(command_id, "done", 200, json.dumps(system_info(), indent=2), "", started)
if action == "command_palette":
data = command_palette(payload)
if not data.get("ok"):
return result(command_id, "error", 400, json.dumps(data, indent=2), data.get("error", ""), started)
return start_bridge_job(cfg, "/stage/run", {"cwd": data["cwd"], "cmd": b64url(data["cmd"])}, started, command_id, "command_palette")
if action == "workspace_info":
return result(command_id, "done", 200, json.dumps(workspace_info(cfg, payload), indent=2), "", started)
if action == "project_profile":
data = project_profile(payload)
return result(command_id, "done" if data.get("ok") else "error", 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"project": data.get("path", "")})
if action == "project_context":
data = project_context(payload)
ok = not bool(data.get("error"))
return result(command_id, "done" if ok else "error", 200 if ok else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"context_files": data.get("count", 0)})
if action in {"file_symbols", "symbol_search", "workspace_symbols"}:
data = file_symbols(payload) if action == "file_symbols" else workspace_symbols(payload) if action == "workspace_symbols" else symbol_search(payload)
if data.get("ok"):
if payload.get("path"):
record_recent_safely("files", payload.get("path"))
if action == "symbol_search" and payload.get("query"):
record_recent_safely("symbols", payload.get("query"))
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 403, json.dumps(data, indent=2), data.get("error", ""), started, {"parser": data.get("parser", "best-effort-regex")})
if action in {"symbol_definition", "symbol_references", "symbol_callers"}:
data = symbol_references(payload, definitions_only=action == "symbol_definition")
if action == "symbol_callers":
data = symbol_callers(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"parser": data.get("parser", "best-effort-regex")})
if action == "symbol_callees":
data = symbol_callees(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"parser": data.get("parser", "best-effort-call-expression-regex")})
if action == "symbol_context":
data = symbol_context(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"parser": data.get("parser", "best-effort-regex-with-source-ranges"), "matches": len(data.get("results", []))})
if action == "symbol_block":
data = symbol_block(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"parser": data.get("parser", "line-fallback"), "confidence": data.get("confidence", "")})
if action == "project_tokens":
data = project_tokens(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"parser": data.get("parser", "bounded-regex-token-scan"), "scanned_files": data.get("scanned_files", 0)})
if action == "dependency_scan":
data = dependency_scan(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"parser": data.get("parser", "bounded-import-patterns"), "scanned_files": data.get("scanned_files", 0)})
if action == "dependency_graph":
data = dependency_graph(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"parser": data.get("parser", "bounded-import-patterns"), "nodes": len(data.get("nodes", [])), "edges": len(data.get("edges", []))})
if action == "impact_analysis":
data = impact_analysis(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"parser": data.get("parser", "symbol-references"), "files": data.get("file_count", 0), "references": data.get("reference_count", 0)})
if action.startswith("git_worktree_") or action.startswith("worktree_"):
normalized = action[len("git_"):] if action.startswith("git_worktree_") else action
data = worktree_action(normalized, payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"worktree_action": normalized, "worktree": data.get("target", data.get("worktree", ""))})
if action in {"git_branch", "git_changed_files", "git_show", "git_blame", "git_diff_staged"}:
data = git_read_action(action, payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"git_action": action})
if action in {"git_stash", "git_revert"}:
data = git_history_mutation(action, payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"git_action": action})
if action in {"git_merge_preview", "git_merge", "git_cherry_pick"}:
data = git_merge_action(action, payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"git_action": action, "revision": data.get("revision", payload.get("branch", ""))})
if action in {"job_output", "job_tail", "job_error_summary", "job_first_error", "job_retry", "job_rerun", "job_cancel"}:
return job_action(cfg, action, payload, started, command_id)
if action == "job_next_actions":
data = job_next_actions(cfg, payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, data.get("http_status", 200 if data.get("ok") else 400), json.dumps(data, indent=2), data.get("error", ""), started, {"job_id": data.get("job_id", ""), "state": data.get("state", "")})
if action == "changeset_next_actions":
data = changeset_next_actions(cfg, payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, data.get("http_status", 200 if data.get("ok") else 400), json.dumps(data, indent=2), data.get("error", ""), started, {"changeset_id": data.get("changeset_id", ""), "state": data.get("state", "")})
if action == "changeset_add_many":
data = changeset_add_many(cfg, payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"changeset_id": data.get("changeset_id", ""), "steps": data.get("count", 0)})
if action in {"artifact_catalog", "artifact_text"}:
data = artifact_catalog(payload) if action == "artifact_catalog" else artifact_text(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"artifact_action": action, "artifact_count": len(data.get("artifacts", []))})
if action in {"stat_file", "calculate_sha256", "search_filename"}:
data = fs_readonly("stat_file" if action == "calculate_sha256" else action, payload)
if action == "calculate_sha256" and data.get("ok"):
data = {"ok": True, "path": data["path"], "sha256": data["sha256"]}
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"filesystem_action": action})
if action == "read_range":
params = {"path": payload.get("path", ""), "start": payload.get("start", 1), "lines": payload.get("lines", 100)}
out = call_bridge(cfg, "/read", params, 30)
ok = out["http_status"] < 400
if ok:
record_recent_safely("files", params["path"])
record_recent_safely("selections", f"{params['path']}:{params['start']}+{params['lines']}")
return result(command_id, "done" if ok else "error", out["http_status"], out["text"], "" if ok else out["text"][-2000:], started, {"filesystem_action": action})
if action == "tail_file":
path = safe_workspace_file(payload.get("path"))
if not path:
return result(command_id, "error", 400, "", "file_not_in_workspace", started)
count = max(1, min(int(payload.get("lines", 100)), 500))
try:
text = read_tail_lines(path, count)
except OSError as exc:
return result(command_id, "error", 400, "", f"tail_read_failed: {type(exc).__name__}", started)
return result(command_id, "done", 200, text, "", started, {"filesystem_action": action, "lines": count, "bounded": True})
if action in {"create_file", "create_directory", "rename_file", "move_file", "copy_file", "delete_file", "restore_file"}:
data = fs_stage(action, payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"stage_id": data.get("stage_id", ""), "filesystem_action": action})
if action == "fs_stage":
operation = str(payload.get("operation", "")).strip()
if operation not in {"create_file", "create_directory", "rename_file", "copy_file", "move_file", "delete_file", "restore_file"}:
return result(command_id, "error", 400, "", "unsupported filesystem operation", started)
data = fs_stage(operation, payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else 400, json.dumps(data, indent=2), data.get("error", ""), started, {"stage_id": data.get("stage_id", ""), "filesystem_action": operation})
if action == "fs_apply":
data = fs_apply(payload)
status = "done" if data.get("ok") else "error"
return result(command_id, status, 200 if data.get("ok") else (409 if data.get("error") == "FILE_CHANGED" else 400), json.dumps(data, indent=2), data.get("error", ""), started, {"stage_id": data.get("stage_id", ""), "filesystem_action": data.get("action", "")})
if action == "bridge_route":
out = bridge_route_action(cfg, payload, started)
status = "done" if out["http_status"] < 400 else "error"
return result(command_id, status, out["http_status"], out["text"], "" if status == "done" else out["text"], started)
# Keep ChangeSet execution structured; the generic route mapping cannot
# distinguish HTTP success from a failed step inside the ChangeSet.
if action == "changeset_execute":
params = {"id": payload.get("id", payload.get("changeset_id", ""))}
if str(payload.get("confirm", "")).lower() in {"1", "yes", "true"}:
params["confirm"] = "1"
out = call_bridge(cfg, "/changeset/execute", params, int(payload.get("timeout", 120)))
failed = has_failed_step(out["text"])
statuses = extract_step_statuses(out["text"])
status = "error" if failed or out["http_status"] >= 400 else "done"
error = "one or more ChangeSet steps failed" if failed else ""
meta = {"changeset_id": payload.get("id", ""), "step_status": statuses, "steps_failed": failed}
return result(command_id, status, out["http_status"], out["text"], error, started, meta)
if action == "changeset_rollback":
params = {"id": payload.get("id", payload.get("changeset_id", ""))}
if str(payload.get("confirm", "")).lower() in {"1", "yes", "true"}:
params["confirm"] = "1"
out = call_bridge(cfg, "/changeset/rollback", params, int(payload.get("timeout", 120)))
return result(command_id, "done" if out["http_status"] < 400 else "error", out["http_status"], out["text"], "", started, {"changeset_id": params["id"], "rollback": True})
if action == "buffer_save":
params = {"name": payload.get("name", "A"), "path": payload.get("path", "")}
http_status, raw_html = http_text(bridge_url(cfg, "/buffer/save", params), timeout=60)
stage_id = parse_stage_id(raw_html)
text = strip_html(raw_html)
status = "done" if http_status < 400 and stage_id else "error"
return result(command_id, status, http_status, text, "buffer save stage id not found" if not stage_id else "", started, {"stage_kind": "write", "stage_id": stage_id, "buffer": params["name"]})
if action == "buffer_use" and str(payload.get("as", "new")).lower() == "patch":
params = {"name": payload.get("name", "A"), "as": "patch"}
http_status, raw_html = http_text(bridge_url(cfg, "/buffer/use", params), timeout=60)
stage_id = parse_stage_id(raw_html)
text = strip_html(raw_html)
status = "done" if http_status < 400 and stage_id else "error"
return result(command_id, status, http_status, text, "buffer patch stage id not found" if not stage_id else "", started, {"stage_kind": "patch", "stage_id": stage_id, "buffer": params["name"]})
if action == "new_clone_old":
out = call_bridge(cfg, "/new/clone-old", {}, 60)
return bridge_result(command_id, out, started, {"operation": "clone_old_to_new"})
if action == "new_use" and str(payload.get("as", "new")).lower() == "patch":
http_status, raw_html = http_text(bridge_url(cfg, "/new/use", {"as": "patch"}), timeout=60)
stage_id = parse_stage_id(raw_html)
text = strip_html(raw_html)
status = "done" if http_status < 400 and stage_id else "error"
return result(command_id, status, http_status, text, "NEW patch stage id not found" if not stage_id else "", started, {"stage_kind": "patch", "stage_id": stage_id, "operation": "new_to_patch"})
if action in direct_bridge_actions():
route, mapping = direct_bridge_actions()[action]
params = map_params(payload, mapping)
if "confirm" in params and str(params["confirm"]).lower() in {"yes", "true"}:
params["confirm"] = "1"
out = call_bridge(cfg, route, params, int(payload.get("timeout", 60)))
return bridge_result(command_id, out, started, {"route": route})
if action == "health":
status, text = http_text(cfg["bridge_base"].rstrip("/") + "/health", timeout=15)
return result(command_id, "done" if status < 400 else "error", status, text, "" if status < 400 else "bridge health check failed", started)
if action in {"bridge_home", "home"}:
out = call_bridge(cfg, "/", {}, 30)
return bridge_result(command_id, out, started, {"route": "/"})
if action == "download_artifact":
out = call_bridge(cfg, "/artifact", {"path": payload.get("path", "")}, 60)
return bridge_result(command_id, out, started, {"route": "/artifact"})
if action in {"ls", "list_directory", "list_projects"}:
out = call_bridge(cfg, "/ls", {"path": payload.get("path", "")}, 30)
return bridge_result(command_id, out, started, {"route": "/ls"})
if action == "read_file":
params = {"path": payload.get("path", ""), "start": payload.get("start", 1), "lines": payload.get("lines", 120)}
out = call_bridge(cfg, "/read", params, 30)
if out["http_status"] < 400:
record_recent_safely("files", params["path"])
return bridge_result(command_id, out, started, {"route": "/read"})
if action in {"search", "search_text"}:
params = {"q": payload.get("q", payload.get("query", "")), "path": payload.get("path", "")}
out = call_bridge(cfg, "/search", params, 45)
if out["http_status"] < 400 and params["q"]:
record_recent_safely("selections", f"search:{params['q']}")
return bridge_result(command_id, out, started, {"route": "/search"})
if action == "git_status":
out = call_bridge(cfg, "/git/status", {"path": payload.get("path", "")}, 45)
return bridge_result(command_id, out, started, {"route": "/git/status"})
if action in {"git_diff", "git_diff_file"}:
out = call_bridge(cfg, "/git/diff", {"path": payload.get("path", "")}, 45)
return bridge_result(command_id, out, started, {"route": "/git/diff"})
if action in {"git_log", "git_history", "file_history"}:
out = call_bridge(cfg, "/git/log", {"path": payload.get("path", "")}, 45)
return bridge_result(command_id, out, started, {"route": "/git/log"})
if action == "stage_write":
params = {"path": payload.get("path", ""), "data": b64url(payload.get("content", ""))}
http_status, raw_html = http_text(bridge_url(cfg, "/stage/write", params), timeout=45)
out = {"http_status": http_status, "text": strip_html(raw_html)}
stage_id = parse_stage_id(raw_html)
meta = {"stage_kind": "write", "stage_id": stage_id} if stage_id else {"stage_kind": "write"}
status = "done" if out["http_status"] == 200 and stage_id else "error"
error = "stage id not found" if not stage_id else ""
return result(command_id, status, out["http_status"], out["text"], error, started, meta)
if action == "stage_patch":
http_status, raw_html = http_text(bridge_url(cfg, "/stage/patch", {"data": b64url(payload.get("patch", ""))}), timeout=45)
out = {"http_status": http_status, "text": strip_html(raw_html)}
stage_id = parse_stage_id(raw_html)
meta = {"stage_kind": "patch", "stage_id": stage_id} if stage_id else {"stage_kind": "patch"}
status = "done" if out["http_status"] == 200 and stage_id else "error"
error = "stage id not found" if not stage_id else ""
return result(command_id, status, out["http_status"], out["text"], error, started, meta)
if action in {"apply_stage", "apply_patch", "apply_write"}:
stage_id = payload.get("stage_id", "")
kind = "write" if action == "apply_write" else "patch" if action == "apply_patch" else payload.get("kind", "patch")
route = "/apply/write" if kind == "write" else "/apply/patch"
out = call_bridge(cfg, route, {"id": stage_id}, 60)
return result(command_id, "done" if out["http_status"] == 200 else "error", out["http_status"], out["text"], "", started, {"stage_kind": kind, "stage_id": stage_id})
if action in {"stage_run", "stage_command"}:
params = {"cwd": payload.get("cwd", ""), "cmd": b64url(payload.get("cmd", ""))}
out = call_bridge(cfg, "/stage/run", params, 45)
return bridge_result(command_id, out, started, {"route": "/stage/run", "operation": "stage_command"})
if action == "run_stage":
out = call_bridge(cfg, "/run", {"id": payload.get("stage_id", payload.get("id", ""))}, 45)
job_id = parse_job_id(out["text"])
return result(command_id, "done" if out["http_status"] == 200 else "error", out["http_status"], out["text"], "", started, {"stage_id": payload.get("stage_id", payload.get("id", "")), "job_id": job_id})
if action == "compose_append":
out = call_bridge(cfg, "/compose/append", {"id": payload.get("id", ""), "data": b64url(payload.get("text", payload.get("value", "")))}, 45)
return bridge_result(command_id, out, started, {"route": "/compose/append"})
if action == "compose_replace":
params = {"id": payload.get("id", ""), "marker": payload.get("marker", ""), "value": b64url(payload.get("value", ""))}
out = call_bridge(cfg, "/compose/replace", params, 45)
return bridge_result(command_id, out, started, {"route": "/compose/replace"})
if action == "patch_context_set":
params = {"field": payload.get("field", ""), "value": b64url(payload.get("value", ""))}
for key in ("file", "line", "return"):
if payload.get(key):
params[key] = payload[key]
out = call_bridge(cfg, "/patch-context/set", params, 45)
return bridge_result(command_id, out, started, {"route": "/patch-context/set"})
if action == "buffer_set":
params = {"name": payload.get("name", "A"), "value": b64url(payload.get("value", ""))}
if payload.get("append") is not None:
params["append"] = payload.get("append")
out = call_bridge(cfg, "/buffer/set", params, 45)
return bridge_result(command_id, out, started, {"route": "/buffer/set", "buffer": params["name"]})
if action == "buffer_append_line":
line = str(payload.get("line", payload.get("value", "")))
params = {"name": payload.get("name", "A"), "value": b64url(line + "\n"), "append": "1"}
out = call_bridge(cfg, "/buffer/set", params, 45)
return bridge_result(command_id, out, started, {"route": "/buffer/set", "buffer": params["name"], "appended_lines": 1})
if action == "new_op" and payload.get("op") == "append_token":
out = call_bridge(cfg, "/new/op", {"op": "append_token", "value": b64url(payload.get("value", ""))}, 45)
return bridge_result(command_id, out, started, {"route": "/new/op"})
if action == "changeset_add":
params = {}
for key in ("id", "kind", "path", "content", "patch", "cmd", "cwd"):
if key in payload:
params[key] = payload[key]
out = call_bridge(cfg, "/changeset/add", params, 60)
return bridge_result(command_id, out, started, {"route": "/changeset/add", "changeset_id": params.get("id", "")})
if action == "adb_run":
params = {"cmd": b64url(payload.get("cmd", ""))}
if payload.get("confirm"):
params["confirm"] = payload.get("confirm")
out = call_bridge(cfg, "/adb/run", params, 45)
return bridge_result(command_id, out, started, {"route": "/adb/run"})
if action == "run_command":
params = {"cwd": payload.get("cwd", ""), "cmd": b64url(payload.get("cmd", ""))}
return start_bridge_job(cfg, "/stage/run", params, started, command_id, "run_command")
if action == "job_status":
out = call_bridge(cfg, "/job", {"id": payload.get("job_id", "")}, 30)
return bridge_result(command_id, out, started, {"route": "/job", "job_id": payload.get("job_id", "")})
if action == "gradle":
params = {"cwd": payload.get("cwd", ""), "task": payload.get("task", "assembleDebug")}
stage_status, stage_html = http_text(bridge_url(cfg, "/gradle/run", params), timeout=45)
stage_id = parse_stage_id(stage_html)
if not stage_id:
return result(command_id, "error", stage_status, strip_html(stage_html), "gradle stage id not found", started)
run_status, run_html = http_text(bridge_url(cfg, "/run", {"id": stage_id}), timeout=45)
return result(command_id, "done" if run_status < 400 else "error", run_status, strip_html(run_html), "" if run_status < 400 else "gradle job start failed", started, {"stage_id": stage_id, "job_id": parse_job_id(run_html)})
return result(command_id, "error", 400, "", f"unsupported action: {action}", started)
===START===
def start_bridge_job(cfg, route, params, started, command_id, label):
stage_status, stage_html = http_text(bridge_url(cfg, route, params), timeout=60)
stage_id = parse_stage_id(stage_html)
if not stage_id:
return result(command_id, "error", stage_status, strip_html(stage_html), f"{label} stage id not found", started, {"operation": label})
run_status, run_html = http_text(bridge_url(cfg, "/run", {"id": stage_id}), timeout=60)
job_id = parse_job_id(run_html)
if job_id:
history = load_json(JOB_HISTORY_PATH, {})
if not isinstance(history, dict):
history = {}
history[job_id] = {
"route": route, "params": params, "label": label, "created_at": now(),
"command_id": command_id, "terminal_sent": False
}
save_json(JOB_HISTORY_PATH, history)
status = "running" if run_status < 400 and job_id else "error"
return result(command_id, status, run_status, strip_html(run_html), "" if job_id else f"{label} job id not found", started, {"operation": label, "stage_id": stage_id, "job_id": job_id})