9535122c99
Plane: paginated issue/comment/state/label/member access, one client per terminal identity. Transports: local (setsid-detached runner) and warpgate-ssh (win10-ps.sh / win10-put.sh relay, schtasks launch, taskkill on timeout). Executors share a runner shape (prompt.md, exit.txt marker) with codex, claude-code and shell adapters for last message and thread id.
39 lines
1.6 KiB
Python
39 lines
1.6 KiB
Python
"""Claude Code CLI: `claude -p --output-format json` with the prompt on stdin and cwd = repo;
|
|
resume with `--resume <session_id>`. The JSON result carries `result` (last message) and `session_id`."""
|
|
import json
|
|
|
|
from .base import ExecResult, RunnerExecutor
|
|
|
|
|
|
def parse_output(text):
|
|
"""Return the result object from `--output-format json` output (whole text or its last JSON line)."""
|
|
text = (text or "").strip()
|
|
candidates = [text] + list(reversed(text.splitlines()))
|
|
for c in candidates:
|
|
try:
|
|
obj = json.loads(c)
|
|
except ValueError:
|
|
continue
|
|
if isinstance(obj, dict):
|
|
return obj
|
|
if isinstance(obj, list): # stream-json style array: take the result event
|
|
res = [o for o in obj if isinstance(o, dict) and o.get("type") == "result"]
|
|
if res:
|
|
return res[-1]
|
|
return {}
|
|
|
|
|
|
class ClaudeCodeExecutor(RunnerExecutor):
|
|
stdout_name = "out.json"
|
|
|
|
def collect(self, handle):
|
|
t, d = self.transport, handle["run_dir"]
|
|
obj = parse_output(t.read_text(t.join(d, "out.json")))
|
|
err = bool(obj.get("is_error")) or obj.get("subtype", "success") != "success"
|
|
last = "" if err else (obj.get("result") or "")
|
|
tail = self.stderr_tail(handle)
|
|
if err:
|
|
tail = ("%s %s" % (obj.get("subtype", ""), str(obj.get("result", ""))[:400]) + "\n" + tail).strip()
|
|
return ExecResult(last.strip(), self.exit_code(handle), obj.get("session_id") or handle.get("thread_id"),
|
|
self.logs(handle, "out.json", "stderr.txt"), tail)
|