Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
On Windows, path.join() / path.resolve() produce paths with backslash separators. isPathWithinRoot() hardcoded '/' in its startsWith check, causing every stat/read/write on OverlayFs to ENOENT on Windows. - Accept both '/' and '\' as valid separators after the root prefix - Normalize backslash to '/' in sanitizeSymlinkTarget relativePath - Add Windows backslash test cases for isPathWithinRoot
* Fix #194 * deflake-test * Disable strip types in node22
* Refactor just-bash into monorepo layout * Fix website content generator * Move website into workspace
* Introduce changesets and prep OIDC publishing * pnpm-i
* Enable changset/oidc publishing * Run all checks in release task
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
The awk lexer emitted a NEWLINE token unconditionally when it saw `\n`,
even when the previous token was one of the continuation-allowing tokens
POSIX awk specifies (`,`, `{`, `&&`, `||`, `?`, `:`, `do`, `else`, `if`,
`while`). Common multi-line idioms like
printf "%s=%d\n",
$1, $2
(comma at end-of-line followed by indented args on the next line) parsed
as two separate statements with a stray NEWLINE in the middle, surfacing
as "Unexpected token: NEWLINE" — even though gawk, mawk, and the BSD
one-true-awk all accept this form.
The lexer already tracks `lastTokenType` as an instance property, so the
fix is a small inject in `nextToken`: when the next character is `\n`
and `lastTokenType` is in `CONTINUES_ACROSS_NEWLINE`, swallow the
newline and recurse to the next real token instead of emitting one.
Adds eight regression tests covering each continuation-allowing token
plus the TSV → SQL INSERT printf idiom that motivated the fix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat: experimental executor tool invocation for js-exec
Summary
Add
experimental_executoroption toBashOptionsthat gives JavaScript coderunning in
js-execaccess to atoolsproxy for calling external tools, andauto-generates bash CLI commands from those tools so they work directly from
the shell.
Tool calls are synchronous from the QuickJS sandbox's perspective — they block
via
SharedArrayBuffer/Atomicswhile the host resolves them asynchronously.Integrates with
@executor-js/sdkand the official plugins (declared asoptional peer dependencies — see Risk-mitigation choices
below):
@executor-js/plugin-graphql— auto-discovers tools from GraphQL schemas via introspection@executor-js/plugin-openapi— auto-discovers tools from OpenAPI specs@executor-js/plugin-mcp— connects to MCP servers and discovers toolsRisk-mitigation choices
This is a sizeable feature surface and we want to land it with minimal blast
radius. Three deliberate decisions to make that easier:
experimental_executor(notexecutor). The shape issubject to change; the prefix makes that obvious at every call site and
gives us room to iterate on the API without a breaking-change cycle.
@executor-js/*packages are optional peer dependencies, not directdependencies. This keeps the just-bash install footprint unchanged for
users who don't use the feature, and it means SDK version bumps don't
force-update every just-bash consumer. Inline
toolswork without any peerdeps installed;
setup(SDK-driven discovery) requires consumers to installthe relevant packages themselves.
packages/just-bash/docs/EXECUTOR.md,linked from the main package README and from
src/commands/js-exec/README.md.Keeps the experimental surface visible in one place and out of the
stable-feature docs.
A
.npmrcis added at the repo root withminimum-release-age-excludefor the four@executor-js/*packages socontributors with a global age constraint don't need a per-command flag.
Auto-generated CLI commands
Every tool automatically becomes a bash command using the namespace +
subcommand pattern (like
git commit,gh pr create):Input modes (Speakeasy-style three-tier precedence)
Help output (gh CLI style)
camelCase → kebab-case with aliases
Opt-out
js-exec tool proxy
Tools are also available from JavaScript code via the
toolsproxy:Passing
experimental_executorimplicitly enablesjavascript: true, so youdon't need both.
GraphQL tool discovery
Requires
@executor-js/sdkand@executor-js/plugin-graphqlpeerdependencies installed by the consumer.
Offline introspection (no network call during setup):
OpenAPI tool discovery
Requires
@executor-js/sdkand@executor-js/plugin-openapipeerdependencies installed by the consumer.
Tool approval and elicitation
Credentials (never exposed to sandbox)
ExecutorConfig API
toolsRecord<string, { description?; execute }>setup(sdk) => Promise<void>pluginsany[]onToolApproval"allow-all" | "deny-all" | callback"allow-all"onElicitationhandler | "accept-all"exposeToolsAsCommandsbooleantrueSupported source kinds
"graphql"@executor-js/plugin-graphqlendpoint,name,introspectionJson?,headers?"openapi"@executor-js/plugin-openapispec,endpoint,name,headers?"mcp"@executor-js/plugin-mcptransport,endpointorcommand,name"custom"name,tools: { [name]: { execute } }Packaging
0.0.1-beta.5because the published0.0.1("latest" tag) and0.0.1-beta.6both have a broken transitive dep (@executor/config404s onthe registry).
build:lib,build:lib:cjs,build:cli), so the published bundle never inlines them.Implementation details
CLI command generation:
src/commands/tool-command.ts— argument parser, help formatter, namespace command factory--json> stdin (modeled after Speakeasy CLI)ghCLI-style help output (USAGE/COMMANDS/FLAGS/EXAMPLES)camelToKebab()for subcommand names, with original camelCase aliasesbuildNamespaceCommands()groups tools by first dot-segmentensureExecutorReady()Tool invocation bridge:
INVOKE_TOOL(400) opcode in the SharedArrayBuffer bridge protocolSyncBackend.invokeTool()— worker-side sync call viaAtomics.wait__invokeToolnative function +toolsProxy whenhasExecutorToolsis setSDK integration:
experimental_executor.setuplazily initializes@executor-js/sdkon firstexec()(dynamic import — no SDK code touched until you actually use it)sources.add()dispatches bykind:"graphql"→ plugin-graphql,"openapi"→ plugin-openapi,"mcp"→ plugin-mcp,"custom"→discovery plugin
introspectionJsonexec()Security:
undefinedonElicitationdefaults to declining all requestsheadersconfig never reach the sandbox@banned-pattern-ignoreannotation explaining they are author-supplied, not host data
Test plan
pnpm test:run— all 13,244 unit tests pass (389 test files)pnpm test:wasm— all 596 wasm tests pass (executor + js-exec integration)pnpm test:dist— bundled output smoke tests passpnpm typecheck,pnpm lint,pnpm knipcleanpnpm installsucceeds without flags after the.npmrcexemptionMigration notes
The option is new (
experimental_executor), so there is nothing to migratefrom. Anyone who used the option name
executorfrom earlier iterations ofthis branch needs to rename it. No other API surface changes.