Skip to content

Commit b3583ae

Browse files
RaycarlLeiclaude
andauthored
fix(integrations): map Pi JSON dispatch to --mode json (#5043)
PiIntegration inherited MarkdownIntegration.build_exec_args(), which appends --output-format json when output_json is true. Pi has no --output-format option: its parser keeps unknown long flags for extensions, and when no extension registers the flag, pi reports "Unknown option: --output-format" and exits 1 before the prompt is sent. This is reachable through dispatch_command(stream=False) when output_json is left unset (it then resolves to True), and through direct build_exec_args() calls. Override build_exec_args() to request --mode json, the flag Pi uses for JSONL events and the one the OMP integration already passes. The base requires_cli guard and argument order (EXTRA_ARGS before --model) are unchanged. docs/integrations/pi.md named the old flag and now names --mode json. Assisted-by: Claude Code (model: Claude Opus 5.5, autonomous) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 505781d commit b3583ae

3 files changed

Lines changed: 92 additions & 1 deletion

File tree

‎docs/integrations/pi.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ Invoke them in the agent's chat using dotted notation, for example
2626
## Workflow Dispatch and Tooling
2727

2828
Workflow steps use `pi -p <prompt>`, with `--model` when configured and
29-
`--output-format json` when structured output is requested.
29+
`--mode json` (JSONL events), not `--output-format`, when structured output is
30+
requested.
3031
There are no integration-specific setup options.
3132

3233
This integration scaffolds prompt files; it does not install or configure MCP

‎src/specify_cli/integrations/pi/__init__.py‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
"""Pi Coding Agent integration."""
22

3+
from __future__ import annotations
4+
5+
from collections.abc import Mapping, Sequence
6+
from pathlib import Path
7+
from typing import Any
8+
39
from ..base import MarkdownIntegration
410

511

@@ -19,3 +25,31 @@ class PiIntegration(MarkdownIntegration):
1925
"extension": ".md",
2026
}
2127
multi_install_safe = True
28+
29+
def build_exec_args(
30+
self,
31+
prompt: str,
32+
*,
33+
model: str | None = None,
34+
output_json: bool = True,
35+
integration_args: Sequence[str] | None = None,
36+
integration_options: Mapping[str, Any] | None = None,
37+
project_root: Path | None = None,
38+
) -> list[str] | None:
39+
"""Build CLI arguments for non-interactive ``pi`` execution.
40+
41+
``MarkdownIntegration``'s default requests ``--output-format json``,
42+
which Pi does not define: it rejects the unknown option and exits 1
43+
before the prompt runs. Pi selects JSONL events with ``--mode json``,
44+
the same flag the OMP integration already passes.
45+
"""
46+
self.validate_runtime_config(integration_args, integration_options)
47+
if not self.config or not self.config.get("requires_cli"):
48+
return None
49+
args = [self._resolve_executable(), "-p", prompt]
50+
self._apply_extra_args_env_var(args)
51+
if model:
52+
args.extend(["--model", model])
53+
if output_json:
54+
args.extend(["--mode", "json"])
55+
return args

‎tests/integrations/test_integration_pi.py‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,59 @@ def test_multi_install_safe(self):
1616
# every other integration, so it must be co-install safe (mirrors
1717
# qwen/shai/qodercli and the kiro-cli #3471 precedent).
1818
assert get_integration(self.KEY).multi_install_safe is True
19+
20+
def test_build_exec_args_uses_prompt_flag(self):
21+
integration = get_integration(self.KEY)
22+
23+
args = integration.build_exec_args(
24+
"/speckit.specify build a login page",
25+
output_json=False,
26+
)
27+
28+
assert args == ["pi", "-p", "/speckit.specify build a login page"]
29+
30+
def test_build_exec_args_requests_json_mode(self):
31+
"""Pi has no `--output-format`; JSONL events are selected with `--mode json`."""
32+
integration = get_integration(self.KEY)
33+
34+
args = integration.build_exec_args("/speckit.plan add OAuth", output_json=True)
35+
36+
assert args == ["pi", "-p", "/speckit.plan add OAuth", "--mode", "json"]
37+
assert "--output-format" not in args
38+
39+
def test_build_exec_args_forwards_model(self):
40+
integration = get_integration(self.KEY)
41+
42+
args = integration.build_exec_args(
43+
"/speckit.specify build a login page",
44+
model="openai/gpt-4o",
45+
output_json=False,
46+
)
47+
48+
assert args == [
49+
"pi",
50+
"-p",
51+
"/speckit.specify build a login page",
52+
"--model",
53+
"openai/gpt-4o",
54+
]
55+
56+
def test_build_exec_args_applies_extra_args(self, monkeypatch):
57+
monkeypatch.setenv("SPECKIT_INTEGRATION_PI_EXTRA_ARGS", "--thinking high")
58+
integration = get_integration(self.KEY)
59+
60+
args = integration.build_exec_args(
61+
"check the build", model="openai/gpt-4o", output_json=True
62+
)
63+
64+
assert args == [
65+
"pi",
66+
"-p",
67+
"check the build",
68+
"--thinking",
69+
"high",
70+
"--model",
71+
"openai/gpt-4o",
72+
"--mode",
73+
"json",
74+
]

0 commit comments

Comments
 (0)