Skip to content

sync: upstream just-bash@2.14.4 (manual resolve)#7

Merged
subsetpark merged 9 commits into
flowglad-mainfrom
sync-just-bash@2.14.4
May 4, 2026
Merged

sync: upstream just-bash@2.14.4 (manual resolve)#7
subsetpark merged 9 commits into
flowglad-mainfrom
sync-just-bash@2.14.4

Conversation

@subsetpark

@subsetpark subsetpark commented May 3, 2026

Copy link
Copy Markdown

Summary

Manual upstream sync to just-bash@2.14.4 after the scheduled Sync upstream action failed:

  1. First run hit gh label create → 403 against vercel-labs/just-bash (fixed in ci(sync-upstream): pin gh CLI to fork repo #6).
  2. Second run made it past labels but the push was rejected by GITHUB_TOKEN because the merge contains .github/workflows/release.yml changes — a platform-level restriction that can't be granted via YAML permissions:. Pushed manually via my own creds here so we can land this tag's sync today; the workflow-permission limitation is a separate decision (PAT/App vs. excluding workflow files from sync).

Conflict resolutions

  • packages/just-bash/package.json
    • build:worker script: took upstream's version. It follows the same src/dist/... + dist/bin/chunks/... + dist/bundle/chunks/... copy chain as the python3 and js-exec workers, and the src/commands/sqlite3/worker.js artifact is already gitignored. Flowglad's prior version (--outfile=dist/commands/sqlite3/worker.js only) wouldn't populate the bundled chunks paths.
    • files array: deduped — both sides added "dist/commands/sqlite3/worker.js", the auto-merge produced two copies. Kept one.
  • packages/just-bash/src/commands/awk/lexer.tsnextToken newline handling: took upstream's version. CONTINUES_ACROSS_NEWLINE (defined upstream at line 148) is a strict superset of HEAD's COMMA-only check, and the existing comment block at the call site already described this broader behavior (commas, {, &&, ||, ?, :, do, else, if, while).

Other notable merge content

  • release.yml: upstream pinned the three third-party actions to full commit SHAs (security hardening). Auto-merge cleanly preserved flowglad's Node 24 + OIDC customizations alongside the SHA pins.
  • New upstream features carried in: src/network/dns-pin*, src/commands/rg/rg-parser-threads.test.ts, src/commands/sqlite3/sqlite3.worker-resolution.test.ts + sqlite3.writeback-edge-cases.test.ts, src/commands/xan/moonblade-parser.test.ts. No flowglad-side changes touched these areas.

Validation

  • pnpm install --frozen-lockfile — lockfile up to date
  • pnpm --filter just-bash build — clean
  • pnpm --filter just-bash typecheck — clean
  • pnpm --filter just-bash exec vitest run src/commands/sqlite3/sqlite3.test.ts src/commands/python3/python3.optin.test.ts — 23/23 passed
  • git add -f packages/just-bash/dist committed (worker chunks land as expected, including new sqlite3-worker.js in dist/bin/chunks/ and dist/bundle/chunks/)

After merge

Cut the next Flowglad package-root tag with pnpm flowglad:tag --tag v2.14.4-fgp.<n> --push.

🤖 Generated with Claude Code


View in Codesmith
Need help on this PR? Tag @codesmith with what you need.

  • Let Codesmith autofix CI failures and bot reviews

subsetpark and others added 7 commits April 28, 2026 17:11
…labs#206)

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.
`parseArgs` allowed `-` as the first non-flag arg but then fell into
the generic else branch that sets `result.scriptFile = arg`, so
`execute()` tried to open a file literally named `-` and returned
`python3: can't open file '-': [Errno 2] No such file or directory`
(exit 2). This breaks every CPython-conventional invocation that
passes the program on stdin via the explicit `-` sentinel:

    python3 -                    # interactive / piped stdin
    python3 - <<'EOF' ... EOF    # heredoc
    echo 'print(1)' | python3 -  # piped stdin

Per `man python3`: `-` means "read program from standard input."

Carry `-` through `parseArgs` as a sentinel (still capturing trailing
scriptArgs), and add a branch in `execute()` that routes the sentinel
to `ctx.stdin` with `argv[0] = "-"` (matching CPython). Empty stdin
runs an empty program and exits 0, matching CPython's non-interactive
behavior when no program is supplied.

Adds four regression tests covering the dash form via pipe, the dash
form via heredoc, trailing-arg propagation into `sys.argv`, and the
empty-stdin case.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…#190)

The sqlite3 command was broken when consumed via the published npm
tarball: `findWorkerPath()` falls through to `<chunks>/worker.js` (the
python3 worker, which `build:worker` placed there), causing every
sqlite3 invocation to fail with "Expected ArrayBuffer for the first
argument" on protocol mismatch. The bug was invisible in this repo
because `tsc` emits `dist/commands/sqlite3/worker.js` locally before the
buggy fallback is reached, but the `files` allowlist excluded that path
from the tarball.

Mirror the js-exec worker pattern: bundle the sqlite3 worker, place it
at `dist/commands/sqlite3/worker.js`, `dist/bin/chunks/sqlite3-worker.js`,
and `dist/bundle/chunks/sqlite3-worker.js`, and ship the first one in
`files`. Update `findWorkerPath()` to prefer the uniquely-named
`sqlite3-worker.js` chunk and gate the bare `<currentDir>/worker.js`
lookup on the directory actually being `commands/sqlite3` so the silent
fallback to a wrong-command worker can't return. Add a unit test that
pins the resolution order and would have caught the original bug.

Also wire sqlite3 into `check-worker-sync.js` so the bundled worker
stays in sync with `worker.ts`, and exclude the generated artifact from
biome / banned-patterns lints (matching the existing python3 / js-exec
treatment).

Verified end-to-end by `npm pack` + install in a clean consumer:
sqlite3 now executes successfully without any post-install patching.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Resolutions:
- packages/just-bash/package.json: keep upstream's build:worker (full
  src/->dist + bin/chunks + bundle/chunks copy chain, matching the
  python3/js-exec pattern); dedupe duplicate dist/commands/sqlite3/worker.js
  files entry.
- packages/just-bash/src/commands/awk/lexer.ts: take upstream's
  CONTINUES_ACROSS_NEWLINE check (strict superset of HEAD's COMMA-only
  case; comment block already described the broader behavior).
@CLAassistant

CLAassistant commented May 3, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 3 committers have signed the CLA.

✅ subsetpark
❌ github-actions[bot]
❌ cramforce
You have signed the CLA already but the status is still pending? Let us recheck it.

@flowglad-review-service flowglad-review-service Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review: 3 comments

Comment thread packages/just-bash/src/commands/sqlite3/sqlite3.ts
Comment thread packages/just-bash/src/network/dns-pin.ts
Comment thread packages/just-bash/src/network/fetch.ts Outdated
@flowglad-review-service

Copy link
Copy Markdown

Review Summary

The PR is a clean upstream sync (2.14.3 → 2.14.4) with well-handled conflict resolutions. The core feature additions — awk newline continuation, sqlite3 dot-commands, worker resolution fix, python3 - stdin support, rg -j thread-count isolation, xan partition collision-safe filenames, moonblade parser backtrack fix, and DNS rebinding protection — are all logically sound with good test coverage.

Two must-fix findings:

  1. sqlite3.ts dot-command error reporting inconsistency (line 617): Dot-command errors (non-bail mode) are placed in stderr while SQL results go to stdout and inline SQL errors are appended to stdout. This channel split is surprising and will break agents that expect errors inline with output.

  2. dns-pin.ts dual-stack family mismatch (line 99): The patcher pins a single {address, family}. If the preflight resolves IPv6-first and undici requests IPv4 (common on modern Linux with verbatim: true), the family-mismatch guard fires ENOTFOUND even for legitimately-allowed hostnames — silently breaking fetch on dual-stack hosts.

One should-fix finding:

  1. fetch.ts addresses[0] may be IPv6 (line 183): checkAllowed returns the first resolved address to pin. On IPv6-first systems this could produce a pin that is incompatible with undici's IPv4 connect path, compounding the must-fix above.
    | Severity | Count |
    |----------|-------|
    | Must-fix | 2 |
    | Should-fix | 1 |
    | Note | 0 |

3 comments posted · Model: claude-sonnet-4-6 (sonnet) · Tokens: 353570 in / 7046 out · Cache: 1140133 created / 4187377 read · Context: 14 items · Review mode: agentic · Turns: 15 · Tool calls: 13 · Forced submit: yes · Tool mix: read_file=13

subsetpark added 2 commits May 4, 2026 09:52
sqlite3: dot-command errors are now appended to stdout (not stderr) so
they interleave with SQL results in script order, matching how inline
SQL errors are reported by the result loop. Avoids the surprise of a
dot-command error appearing on a different channel than a SQL error in
the same script. The -bail path still emits to stderr.

dns-pin: PinnedAddress now carries every preflight-validated address
(addresses: { address, family }[]) and patchedLookup filters by the
requested family at call time. Previously a single (address, family)
pair was pinned, so an IPv6-first dual-stack hostname would trigger
ENOTFOUND when undici later asked for IPv4 explicitly. ENOTFOUND now
fires only when no pinned address satisfies the requested family.

fetch: checkAllowed returns the full validated list instead of just
addresses[0], so both families survive into the pinning context.

Each address still passes the same isPrivateIp gate, so pinning more
addresses doesn't widen the threat surface.
@subsetpark subsetpark merged commit 9e9109b into flowglad-main May 4, 2026
1 of 3 checks passed

@flowglad-review-service flowglad-review-service Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review: 1 comment

@@ -13,7 +13,7 @@

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[MUST FIX] packages/just-bash/src/commands/sqlite3/sqlite3.ts:614 — When dotError is set and there is SQL that runs (the non-bail, non-empty-SQL path), the dot-command error is appended to stdout after the SQL results (line ~749 in context: stdout += \${dotError}\n`). But the -bailearly-return path (line 614:return { stdout: "", stderr: `${dotError}\n`, exitCode: 1 }) puts the dot-command error in **stderr**. This means the channel where dotErroris reported is different depending on whether-bail` is active:

  • With -bail: stderr contains the error, stdout is empty.
  • Without -bail (non-empty SQL): stderr is empty, the error is in stdout after the SQL results.

A caller that inspects stderr to detect errors (the normal pattern) will miss dot-command errors in the non-bail case entirely, seeing only exitCode: 1 with empty stderr. The test fixtures updated in this PR already codify the stdout-based path (expect(result.stdout).toBe("Error: ...\n") with expect(result.stderr).toBe("")), which entrenches the inconsistency.

Suggestion: route dotError to stderr consistently (both bail and non-bail), matching the error channel already used for SQL errors surfaced by the worker (those go to stderr: \Error: ...`\nunder-bail, or to stdoutfor non-bail inline errors). The test expectations insqlite3.dot-commands.test.tsthat were updated in this PR to usestdoutshould be reverted to usestderr`.

Reviewed at 96ab94b

@flowglad-review-service

Copy link
Copy Markdown

Review Summary

This PR is a well-structured upstream sync of just-bash@2.14.4 with three Flowglad patches (sqlite3 worker, awk comma-continuation, jq control chars). The major upstream changes include: OSC-8 XSS fixes in the website terminal, DNS rebinding mitigation via dns-pin.ts, rg -j/--threads correctness fix, moonblade parser backtracking fix, sqlite3 dot-command support, and sqlite3 writeback for CTE-prefixed writes.

One must-fix finding: the dotError channel is inconsistent between -bail (goes to stderr) and non-bail (appended to stdout). Callers checking stderr for errors will silently miss dot-command errors in the non-bail path. The test expectations updated in this PR already encode the stdout path, which entrenches the inconsistency.

All other areas reviewed are correct: DNS-pinning (AsyncLocalStorage scoping, family filtering, dual-stack, ENOTFOUND on mismatch), rg ignored: true fix, moonblade startPos backtrack, awk CONTINUES_ACROSS_NEWLINE set, sqlite3 worker path resolution, and the XSS sanitization chain in the website terminal.

Severity Count
Must-fix 1
Should-fix 0
Note 0

1 comment posted · Model: claude-sonnet-4-6 (sonnet) · Tokens: 357167 in / 4183 out · Cache: 1148956 created / 4275807 read · Context: 15 items · Review mode: agentic · Turns: 15 · Tool calls: 16 · Forced submit: yes · Tool mix: read_file=16

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.

3 participants