MCPcopy Create free account
hub / github.com/agentforce314/clawcodex / spawn_background_bash

Function spawn_background_bash

src/tool_system/tools/bash/background.py:44–176  ·  view source on GitHub ↗

Spawn *command* in the background and register it on *context*. Returns a dict that mirrors the shape consumed by ``_bash_map_result_to_api``: it includes the background task id plus a human-readable message instructing the model how to poll the output.

(
    *,
    command: str,
    cwd: Path,
    description: str | None,
    context: ToolContext,
)

Source from the content-addressed store, hash-verified

42
43
44def spawn_background_bash(
45 *,
46 command: str,
47 cwd: Path,
48 description: str | None,
49 context: ToolContext,
50) -> dict[str, Any]:
51 """Spawn *command* in the background and register it on *context*.
52
53 Returns a dict that mirrors the shape consumed by
54 ``_bash_map_result_to_api``: it includes the background task id plus a
55 human-readable message instructing the model how to poll the output.
56 """
57 # Chapter-10 / WI-1.4: prefixed task id (``b<8 base36 chars>``) instead
58 # of the legacy ``uuid4().hex[:8]``. Mirrors TS Task.ts:79-105 — the
59 # ``b`` prefix is what TaskStop / TaskOutput dispatch on.
60 task_id = generate_task_id("local_bash")
61 output_path = _bg_output_dir() / f"{task_id}.log"
62 output_path.touch(exist_ok=True)
63
64 output_handle = open(output_path, "wb", buffering=0)
65
66 # Same wrapper the foreground path uses, so a trailing ``cd`` still writes
67 # the final PWD for inspection. Exit code is appended to the log after the
68 # process exits so ``TaskOutput`` can report it even if Popen.wait() races
69 # with the reader.
70 wrapped = (
71 f"{{ {command}\n}}; __rc=$?; "
72 f"echo \"__CLAWCODEX_EXIT__=$__rc\" >&2; "
73 f"exit $__rc"
74 )
75
76 # ``stdin=DEVNULL`` mirrors the foreground bash path: prevents background
77 # commands that read fd 0 from blocking on a TTY inherited from clawcodex's
78 # REPL (see bash_tool.py:_run_bash_with_abort for the same reasoning).
79 proc = subprocess.Popen(
80 ["bash", "-lc", wrapped],
81 cwd=str(cwd),
82 stdin=subprocess.DEVNULL,
83 stdout=output_handle,
84 stderr=subprocess.STDOUT,
85 start_new_session=True,
86 )
87
88 started_at = time.time()
89 state = LocalShellTaskState(
90 id=task_id,
91 type="local_bash",
92 status="running",
93 description=description or command,
94 start_time=started_at,
95 # ``output_file`` (chapter-10 base field) carries the same string
96 # as ``output_path`` (bash-specific name kept for legacy readers).
97 output_file=str(output_path),
98 command=command,
99 cwd=str(cwd),
100 pid=proc.pid,
101 output_path=str(output_path),

Calls 7

to_legacy_dictMethod · 0.95
generate_task_idFunction · 0.90
LocalShellTaskStateClass · 0.90
_bg_output_dirFunction · 0.85
touchMethod · 0.80
upsertMethod · 0.80
startMethod · 0.45