Skip to content

fix(integrations): pass the Junie dispatch prompt via --task - #5065

Merged
mnriem merged 1 commit into
github:mainfrom
RaycarlLei:fix/junie-dispatch-task-flag
Oct 23, 2026
Merged

mnriem merged 1 commit into
github:mainfrom
RaycarlLei:fix/junie-dispatch-task-flag

Conversation

@RaycarlLei

Copy link
Copy Markdown
Contributor

Description

JunieIntegration does not override build_exec_args(), so it inherits MarkdownIntegration.build_exec_args() (base.py#L1151-L1170), which passes the prompt as -p <prompt>.

In Junie CLI, -p is the short form of --project, the directory Junie runs in. A non-interactive task is given as a positional argument or with --task. From junie --help (@jetbrains/junie@3110.7.0, the npm package the JetBrains/junie README installs):

Usage: junie [<options>] [<task>]
...
Non-interactive mode:   junie "Fix the bug in the login function"
                        junie --task "Fix the bug"
...
  --task=<text>                     Task description (alternative to positional argument)
...
  -p, --project=<text>              Project directory (default: current directory)
...
  --output-format=<text>         Output format: text, json, json-stream
...
  --model=<text>                    Model to use for the primary agent

The same is in Junie's CLI reference and in the Junie skill JetBrains ships in its own repository: "-p is --project. Non-interactive is simply the positional task." (hermes-plugin/skills/junie/SKILL.md#L93).

Run inside a project created with specify init --integration junie, with HOME pointing at an empty directory (not logged in, no API key):

$ junie --version
Junie version: 26.9.7 (3110.7)
$ junie -p "/speckit-specify build a login page"
The project directory does not exist: /speckit-specify build a login page. Use --project to specify the correct path
$ echo $?
1
$ junie --task "/speckit-specify build a login page" --output-format json
{"errors":["Cannot find authorization. Please authenticate before running Junie."]}

The -p form fails before Junie looks for credentials, so this reproduces without an account. The --task form gets past option parsing and project resolution and stops only because this HOME has no authorization (Junie reports that with exit 0).

The same failure through Spec Kit on main (dc2cec4), with that junie on PATH, run from the project directory:

$ .venv/bin/python -c "from pathlib import Path; from specify_cli.integrations.junie import JunieIntegration as J; r = J().dispatch_command('speckit.plan', 'x', project_root=Path('.').resolve(), stream=False); print(r['exit_code'], r['stderr'].strip())"
1 The project directory does not exist: /speckit-plan x. Use --project to specify the correct path

On this branch the same call reaches Junie's authorization check: exit code 0, and stdout is the {"errors":["Cannot find authorization. ..."]} object above.

Reachability. Unlike the Kimi Code (#5031) and Pi (#5043) fixes, which only affected structured output, -p is passed in every mode, so the built-in workflows hit it. The command step dispatches through dispatch_command() (step/command/__init__.py#L333-L342), and the prompt step builds its argv with build_exec_args(..., output_json=False) (step/prompt/__init__.py#L248-L253); both use the inherited argv. Running the bundled workflow in the same project with a stand-in junie on PATH that only records its argv and exits 1:

$ cat "$(command -v junie)"
#!/bin/sh
# Records the argv Spec Kit passes, then exits 1 so the workflow stops at the first step.
{ printf 'argv:'; for a in "$@"; do printf ' [%s]' "$a"; done; printf '\n'; } >> "$JUNIE_SHIM_LOG"
echo "junie shim: argv recorded" >&2
exit 1
$ specify workflow run speckit -i spec="build a login page"
Running workflow: Full SDD Cycle (speckit)
Version: 1.0.1

  ▸ [specify] speckit.specify …
junie shim: argv recorded

Status: failed
Run ID: d56ce475
Error: Command exited with code 1
$ cat "$JUNIE_SHIM_LOG"
argv: [-p] [/speckit-specify build a login page]

On this branch the same run records argv: [--task] [/speckit-specify build a login page], which is the form Junie accepts above.

Not shown here, because it needs a logged-in Junie: whether a custom command passed as a non-interactive task is expanded from .junie/commands/. That also depends on #4794 (open), which reports that $ARGUMENTS in the installed commands keeps Junie from running them; this PR does not touch command content.

Fix. Override build_exec_args() in JunieIntegration to pass the prompt with --task. --task is used rather than a bare positional so the argv keeps the base shape, with the prompt right after its flag. The rest matches the base implementation: the requires_cli guard, SPECKIT_INTEGRATION_JUNIE_EXTRA_ARGS before --model, --model, and --output-format json. The full argv this branch builds, junie --task "/speckit-plan x" --skip-update-check --model sonnet --output-format json (with --skip-update-check from the extra-args variable), also gets to the authorization check above. The change stays inside the Junie integration package, its test file, and its agent page docs/integrations/junie.md#L32-L33, which named junie -p <prompt>. The new method sits at the end of the class, away from the lines the open Junie PRs (#4795, #4796, #4883, #4983) change.

Part of #2416, which lists Junie's inherited junie -p "prompt" --model X --output-format json argv as unverified. Same shape as #5031 and #5043.

Testing

  • Tested locally with uv run specify --help

  • Ran existing tests with uv sync && uv run pytest: run as .venv/bin/python -m pytest, results below

  • Tested with a sample project (if applicable): the specify init --integration junie project above, with junie 26.9.7 (3110.7) and with the argv-recording stand-in

  • tests/integrations/test_integration_junie.py gets four argv tests: text mode, --output-format json, --model, and SPECKIT_INTEGRATION_JUNIE_EXTRA_ARGS. Run against main, all four fail with '-p' != '--task'. All four pass on this branch, and the file passes as a whole (37 tests).

  • .venv/bin/python -m pytest tests/integrations tests/workflows tests/test_agent_config_consistency.py -q: 3660 passed, 8 skipped.

  • uvx ruff@0.15.0 check src tests: all checks passed.

  • markdownlint-cli2 0.23.2 (the version the lint workflow's action pins) on docs/integrations/junie.md: 0 issues.

  • Full suite, .venv/bin/python -m pytest tests -q (macOS, Python 3.14.3): 12696 passed, 434 skipped, 15 failed. All 15 are in 6 files this PR does not touch, and running those files against unmodified main on the same machine fails the same 15 test IDs. 11 are composed-template cases in test_*_python_parity.py, whose bash variant runs python3 from PATH, and that interpreter has no PyYAML on this machine; they pass with the venv's python3 first on PATH. The other 4 are in test_workflow_step_submission.py, where the fake curl gets a #!<sys.executable> shebang and the interpreter path on this machine contains a space.

AI Disclosure

  • I did not use AI assistance for this contribution
  • I did use AI assistance (fill in the disclosure below)

AI disclosure: Claude Code opened this PR on behalf of @RaycarlLei. Claude Code (model: Claude Opus 5.5, reasoning effort xhigh, autonomous agent mode with tool approvals bypassed) read Junie's documentation and JetBrains' Junie repository, installed @jetbrains/junie@3110.7.0 and ran it without logging in to reproduce the bug, reproduced the workflow argv with a stand-in junie, wrote the override, the four tests and the docs/integrations/junie.md update, ran the checks above, wrote this description, and pushed the branch. A read-only Claude Code subagent on the same model cross-checked the links, the reachability claims and the diff, and its corrections were applied. @RaycarlLei approved posting; he did not review the diff line by line, re-run the tests, or edit this description. The commit carries Assisted-by: Claude Code (model: Claude Opus 5.5, autonomous).

🤖 Generated with Claude Code

JunieIntegration inherited MarkdownIntegration.build_exec_args(), which
passes the prompt as -p <prompt>. Junie's -p is the short form of
--project <path>, so every dispatch, including the built-in workflow
command and prompt steps in text mode, asked Junie to run in a project
directory named after the prompt and gave it no task. Junie takes a
non-interactive task as a positional argument or --task.

Override build_exec_args() to pass the prompt with --task. The base
requires_cli guard and argument order (EXTRA_ARGS before --model) are
unchanged, and --model and --output-format json are flags Junie
documents. docs/integrations/junie.md named -p and now names --task.

Assisted-by: Claude Code (model: Claude Opus 5.5, autonomous)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@RaycarlLei
RaycarlLei requested a review from mnriem as a code owner October 22, 2026 19:55
@mnriem mnriem added the triage-must-have Verdict: high-value, important work for Spec Kit — do first label Oct 23, 2026
@mnriem
mnriem requested a max review from Copilot October 23, 2026 14:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused Junie-only correction preserves the existing dispatch contract, includes regression coverage, and has no unresolved findings.

No open issues 🎉

What changed in this PR

Corrects Junie’s non-interactive dispatch so prompts are treated as tasks rather than project directories, addressing part of the CLI dispatch audit in #2416.

Changes:

  • Adds a Junie-specific build_exec_args() override using --task, preserving existing runtime validation and other options.
  • Adds four regression tests covering prompt forwarding, JSON output, model selection, and extra arguments.
  • Updates the Junie integration guide to show the corrected invocation.

Validation relies on the PR’s reported before-and-after results; tests were not rerun here.

File Description
tests/​integrations/​test_integration_junie.py Adds regression coverage for Junie dispatch arguments.
src/​specify_cli/​integrations/​junie/​__init__.py Passes non-interactive prompts through --task.
docs/​integrations/​junie.md Documents the corrected task flag.

Review effort: Max

@mnriem
mnriem merged commit fe971dc into github:main Oct 23, 2026
15 of 16 checks passed
@mnriem

mnriem commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

triage-must-have Verdict: high-value, important work for Spec Kit — do first

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants