Skip to content

Add PHP as a supported output language#103

Merged
kalil0321 merged 3 commits into
kalil0321:mainfrom
jarsh921:add-php-output-language
Jul 22, 2026
Merged

Add PHP as a supported output language#103
kalil0321 merged 3 commits into
kalil0321:mainfrom
jarsh921:add-php-output-language

Conversation

@jarsh921

@jarsh921 jarsh921 commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Follows the exact same pattern as python/javascript/typescript:

  • New prompt partial (prompts/partials/_language_php.md): uses the curl and json_encode/json_decode core extensions (ext-curl, ext-json) - both part of core PHP, so no Composer dependency is needed at all, no project/dependency file of any kind. Same auth-hardcoding/refresh guidance as the other languages.
  • base_engineer.py: added "php" to _OUTPUT_LANGUAGE_EXTENSIONS (.php) and _get_language_name() ("PHP"). _get_run_command() uses the full path rather than a bare relative "php api_client.php" - applying the same fix greptile-apps caught on the Go/Java/C# PRs proactively here from the start, since php has the identical shape (the agent's cwd is scripts_dir.parent.parent, not scripts_dir where the script is actually saved).
  • cli.py: added PHP to the interactive output_language config picker.
  • Updated the three docstrings/comments that listed the language set (config.py, engineer.py, prompts/init.py) and README.md's output language line.
  • Tests: mirrored the existing per-language test pattern in test_base_engineer.py (extension, run command, prompt content) and test_prompts.py (partial loading) for PHP.

Checked the partial for the literal-brace str.format_map() bug caught in the Java PR - no literal {/} anywhere in the new file.

Full test suite passes (49/49, run 3x). ruff check is clean on every file this touches (8 pre-existing lint errors elsewhere on main, none in the touched lines).


Summary by cubic

Add PHP as a supported output language for generating a standalone API client using cURL and ext-json. Adds a shell-safe, absolute-path run command and updates the CLI, prompts, docs, and tests.

  • New Features

    • Support output_language: "php" with .php extension and name "PHP"; run via php with an absolute path.
    • New prompt partial prompts/partials/_language_php.md using cURL and JSON; includes cookie jar handling, per-endpoint functions, example usage, and auth hardcoding with auto-refresh guidance.
    • Add php to the interactive settings picker in cli.py; update README.md, docstrings, and CHANGELOG.md; tests for extension mapping, prompt content, and partial loading.
  • Bug Fixes

    • Run command now uses shlex.quote() and resolves the script path to an absolute path to prevent command substitution and cwd mismatches; adds hostile-path and relative-path tests to verify correct tokenization and resolution.
    • Prompt clarifies ext-curl is optional and may be missing; adds check/install guidance when curl_init is unavailable.

Written for commit 72f2d90. Summary will update on new commits.

Review in cubic

Greptile Summary

This PR adds PHP as a supported output language. The main changes are:

  • PHP language selection, file extension, and display-name support.
  • A PHP client-generation prompt using cURL and JSON.
  • Shell-safe PHP execution with an absolute script path.
  • CLI, documentation, changelog, and test updates.

Confidence Score: 4/5

The remaining relative-path mismatch should be fixed before merging.

  • The PHP execution path is now absolute and shell-safe.
  • A relative output directory can still make the prompt's save path differ from the execution path.

src/reverse_api/base_engineer.py

Important Files Changed

Filename Overview
src/reverse_api/base_engineer.py Adds PHP language mappings and an absolute, shell-quoted execution command.
src/reverse_api/prompts/partials/_language_php.md Adds PHP client-generation guidance and correctly describes ext-curl as optional.
src/reverse_api/cli.py Adds PHP to the interactive output-language choices.
tests/test_base_engineer.py Adds coverage for PHP extensions, prompts, quoting, and relative execution paths.

Reviews (2): Last reviewed commit: "Resolve scripts_dir to an absolute path ..." | Re-trigger Greptile

Comment thread src/reverse_api/base_engineer.py
Comment thread src/reverse_api/prompts/partials/_language_php.md Outdated

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 10 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/reverse_api/base_engineer.py Outdated
Comment thread src/reverse_api/prompts/partials/_language_php.md Outdated
@kind-agent

kind-agent Bot commented Jul 21, 2026

Copy link
Copy Markdown

⚠️ Error — The test run failed unexpectedly.

Snapshot kind-sandbox is inactive

This is likely a transient issue. You can re-trigger a run from the dashboard.

Joshua Dunbar added 3 commits July 22, 2026 13:01
Follows the exact same pattern as python/javascript/typescript:

- New prompt partial (prompts/partials/_language_php.md): uses the
  curl and json_encode/json_decode core extensions (ext-curl,
  ext-json) - both part of core PHP, so no Composer dependency is
  needed at all, no project/dependency file of any kind. Same
  auth-hardcoding/refresh guidance as the other languages.
- base_engineer.py: added "php" to _OUTPUT_LANGUAGE_EXTENSIONS (.php)
  and _get_language_name() ("PHP"). _get_run_command() uses the full
  path rather than a bare relative "php api_client.php" - applying the
  same fix greptile-apps caught on the Go/Java/C# PRs proactively here
  from the start, since php <relative-path> has the identical shape
  (the agent's cwd is scripts_dir.parent.parent, not scripts_dir where
  the script is actually saved).
- cli.py: added PHP to the interactive `output_language` config picker.
- Updated the three docstrings/comments that listed the language set
  (config.py, engineer.py, prompts/__init__.py) and README.md's output
  language line.
- Tests: mirrored the existing per-language test pattern in
  test_base_engineer.py (extension, run command, prompt content) and
  test_prompts.py (partial loading) for PHP.

Checked the partial for the literal-brace str.format_map() bug caught
in the Java PR - no literal `{`/`}` anywhere in the new file.

Full test suite passes (49/49, run 3x). ruff check is clean on every
file this touches (8 pre-existing lint errors elsewhere on main, none
in the touched lines).
Two real bugs caught by greptile-apps and cubic-dev-ai independently
on the PR, both verified before fixing:

1. _get_run_command()'s "php \"{path}\"" only looked safe - manual
   double-quoting does NOT stop $() or backtick command substitution
   inside a double-quoted shell string, confirmed live. If scripts_dir
   (derived from output_dir, not something this function controls)
   ever contained shell metacharacters, the resulting {run_command}
   could execute something other than what was intended when the
   agent runs it. Replaced with shlex.quote(), the stdlib function
   built exactly for this - confirmed live it correctly single-quotes
   the whole path when metacharacters are present, and correctly
   escapes literal single quotes too (manual double-quoting handles
   neither case). Added a dedicated test with a deliberately hostile
   path (embedded $(rm -rf ~)) asserting the command round-trips
   through shlex.split() back to the literal path, not something a
   shell would expand.

2. The partial said ext-curl was "part of core PHP" alongside ext-json,
   but that's only true for ext-json - ext-curl is bundled-but-optional
   and not guaranteed enabled on every PHP install (some minimal/
   stripped installs omit it). Fixed the wording and added the same
   check-and-install guidance the C PR already gives for libcurl's
   equivalent gap, rather than silently assuming curl_init() exists.

Full test suite passes (50/50, run 2x) except the same pre-existing
flaky test noted on the other language PRs. ruff check clean on the
touched lines.
Same root cause cubic flagged on the C# and Ruby PRs: a relative
--output-dir leaves scripts_dir relative to the original cwd, but once
the agent's cwd moves to scripts_dir.parent.parent (see
analyze_and_generate), embedding that same relative string re-interprets
it from the new location and points at a doubly-nested, nonexistent
path. Resolve scripts_dir before interpolating it, proactively applying
the same fix here before it gets flagged.
@kalil0321
kalil0321 force-pushed the add-php-output-language branch from 26a9ca9 to 72f2d90 Compare July 22, 2026 11:05
@kalil0321

Copy link
Copy Markdown
Owner

@greptile review

@kalil0321
kalil0321 merged commit d7b24db into kalil0321:main Jul 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants