Skip to content

Add --script mode to run command for inline metadata scripts#21

Open
pirate wants to merge 1 commit intomainfrom
claude/add-shebang-dependencies-0Tijt
Open

Add --script mode to run command for inline metadata scripts#21
pirate wants to merge 1 commit intomainfrom
claude/add-shebang-dependencies-0Tijt

Conversation

@pirate
Copy link
Copy Markdown
Member

@pirate pirate commented Apr 10, 2026

Summary

This PR adds a new --script mode to the abx-pkg run command that enables executing scripts with inline /// script metadata blocks. The feature automatically parses script metadata, resolves declared dependencies, and executes the script with a PATH that includes all resolved binaries.

Key Changes

  • New parse_script_metadata() function: Extracts TOML-formatted metadata from /// script blocks in script files. Supports multiple comment styles (#, //, --, ;, etc.) and handles multi-line TOML structures with proper indentation preservation.

  • --script flag for run command: When enabled, treats the binary name as an interpreter and the first argument as a script file path. Parses the script's metadata, resolves all declared dependencies, and executes the script with an augmented PATH.

  • Metadata-driven dependency resolution: Scripts can declare dependencies as strings or objects with additional options (custom binproviders, min_version). The resolver collects PATH entries from all successfully resolved binaries.

  • Tool configuration support: Scripts can include [tool.abx-pkg] sections in metadata to set defaults for postinstall_scripts, min_release_age, and min_version. CLI flags take precedence over metadata settings.

  • Comprehensive test coverage: Added 16 unit tests for metadata parsing (various comment styles, edge cases, TOML structures) and 7 integration tests for the full run --script workflow (argument passing, error handling, exit code propagation, CLI override behavior).

Implementation Details

  • Metadata parsing scans only the first 50 lines by default to avoid performance issues with large files
  • Metadata blocks must be properly closed with a /// marker; unclosed blocks return None
  • The script path is resolved to absolute before execution to ensure correct working directory behavior
  • Exit codes from executed scripts propagate through abx-pkg unchanged
  • Dry-run mode (--dry-run) resolves dependencies but skips actual script execution

https://claude.ai/code/session_0125eDj24UMFUhMUN8x2zmHB


Open with Devin

Summary by cubic

Adds a new --script mode to abx-pkg run that parses inline /// script TOML, resolves dependencies, builds PATH and ENV from providers, and runs the script with the chosen interpreter. Also centralizes installer discovery and dynamic install-root resolution for shebang-friendly usage and consistent runtime envs.

  • New Features

    • Usage: run --script INTERPRETER SCRIPT_PATH [ARGS...] (shebang: #!/usr/bin/env -S abx-pkg run --script node). Implies --install; --dry-run only resolves.
    • Comment-agnostic parser scans the first 50 lines for a closed /// script TOML block.
    • Dependencies can be strings or objects {name, binproviders, min_version}; PATH/ENV assembled from resolved providers.
    • [tool.abx-pkg] values export as env vars verbatim; CLI flags still override.
  • Refactors

    • Runtime env: new BinProvider.ENV + apply_env() with merge rules ("value" overwrite, ":value" append, "value:" prepend); implemented across all providers (pip, uv, npm, pnpm, yarn, bun, deno, brew, cargo, gem, goget, nix, apt, docker, chromewebstore, playwright, puppeteer).
    • Installer discovery centralized via INSTALLER_BINARY() with env overrides (NPM_BINARY, PNPM_BINARY, YARN_BINARY, UV_BINARY, DENO_BINARY, BUN_BINARY).
    • Install roots: providers resolve via abx_pkg_install_root_default() which reads ABX_PKG_LIB_DIR fresh at runtime; removed MANAGED_PROVIDER_ROOTS.
    • playwright/puppeteer: add global/managed/hermetic npm resolution; subprocess output formatter now accepts bytes.

Written for commit 48996d7. Summary will update on new commits.

cubic-dev-ai[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

cubic-dev-ai[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

cubic-dev-ai[bot]

This comment was marked as resolved.

cubic-dev-ai[bot]

This comment was marked as resolved.

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai bot commented Apr 10, 2026

You're iterating quickly on this pull request. To help protect your rate limits, cubic has paused automatic reviews on new pushes for now—when you're ready for another review, comment @cubic-dev-ai review.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@pirate
Copy link
Copy Markdown
Member Author

pirate commented Apr 10, 2026

@cubic-dev-ai review

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai bot commented Apr 10, 2026

@cubic-dev-ai review

@pirate I have started the AI code review. It will take a few minutes to complete.

cubic-dev-ai[bot]

This comment was marked as resolved.

@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch 4 times, most recently from 41370ca to 74ae064 Compare April 10, 2026 12:16
devin-ai-integration[bot]

This comment was marked as resolved.

@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch 5 times, most recently from 1608e20 to e9523c0 Compare April 10, 2026 12:50
devin-ai-integration[bot]

This comment was marked as resolved.

@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch 5 times, most recently from f5604fd to d41aec6 Compare April 10, 2026 18:13
devin-ai-integration[bot]

This comment was marked as resolved.

@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch from 6c09913 to 4dfcded Compare April 10, 2026 21:35
devin-ai-integration[bot]

This comment was marked as resolved.

@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch 8 times, most recently from 7379279 to 8dfbb1f Compare April 10, 2026 22:20
Comment on lines +375 to +382
def default_abspath_handler(
self,
bin_name: BinName | HostBinPath,
no_cache: bool = False,
**context,
) -> HostBinPath | None:
result = super().default_abspath_handler(bin_name, **context)
return TypeAdapter(HostBinPath).validate_python(result) if result else None
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this is not doing anything just remove it and let it use the base class method

@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch from 8dfbb1f to 40dcd80 Compare April 10, 2026 22:25
Comment on lines +188 to +195
def default_abspath_handler(
self,
bin_name: BinName | HostBinPath,
no_cache: bool = False,
**context,
) -> HostBinPath | None:
result = super().default_abspath_handler(bin_name, **context)
return TypeAdapter(HostBinPath).validate_python(result) if result else None
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this is also not doing anything, just remove it let the base class handle it

@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch from 40dcd80 to 78aafd7 Compare April 10, 2026 22:26
Comment on lines +373 to +376
try:
return self.INSTALLER_BINARY(no_cache=no_cache).loaded_abspath
except Exception:
return None
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

shouldnt this be in the base method not the override?

@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch from 78aafd7 to 130e145 Compare April 10, 2026 22:29
Comment on lines 350 to 363
def default_abspath_handler(
self,
bin_name: BinName | HostBinPath,
no_cache: bool = False,
**context,
) -> HostBinPath | None:
if str(bin_name) == self.INSTALLER_BIN:
return self.INSTALLER_BIN_ABSPATH
try:
return self.INSTALLER_BINARY(no_cache=no_cache).loaded_abspath
except Exception:
return None
bin_dir = self.bin_dir
assert bin_dir is not None
link_path = bin_dir / str(bin_name)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

cant this just be on the base? then we dont need this same override everywhere.

Checking bin_dir for the bin_name seems like the most common pattern

@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch 3 times, most recently from 8aad844 to 8536a0f Compare April 10, 2026 22:43
devin-ai-integration[bot]

This comment was marked as resolved.

@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch from 8536a0f to d899150 Compare April 10, 2026 22:55
devin-ai-integration[bot]

This comment was marked as resolved.

@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch from d899150 to bbe308c Compare April 10, 2026 23:04
devin-ai-integration[bot]

This comment was marked as resolved.

@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch from bbe308c to d168e0d Compare April 10, 2026 23:17
devin-ai-integration[bot]

This comment was marked as resolved.

- parse_script_metadata(): comment-syntax-agnostic /// script parser
- --script flag on run command with automatic dep resolution
- BinProvider.ENV computed property + apply_env() for runtime env vars
- ENV overrides on all 14 providers
- [tool.abx-pkg] values passed through as env vars verbatim
- Removed MANAGED_PROVIDER_ROOTS — providers resolve install_root
  from ABX_PKG_LIB_DIR via default_factory
- abx_pkg_install_root_default reads env vars fresh (not cached)
- Playwright/puppeteer: 3-mode npm resolution (global/managed/hermetic)

https://claude.ai/code/session_0125eDj24UMFUhMUN8x2zmHB
@pirate pirate force-pushed the claude/add-shebang-dependencies-0Tijt branch from d168e0d to 48996d7 Compare April 10, 2026 23:31
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