Skip to content

0.11.0#18

Open
dzikowski wants to merge 53 commits into
mainfrom
nightly
Open

0.11.0#18
dzikowski wants to merge 53 commits into
mainfrom
nightly

Conversation

@dzikowski

@dzikowski dzikowski commented Jul 13, 2026

Copy link
Copy Markdown
Contributor
  • Use Jaiph from MCP clients: run jaiph mcp to expose your workflows as tools in Claude Code, Cursor, and other MCP apps — with live progress and the ability to cancel long runs.
  • Pass secrets into sandboxed runs: --env GITHUB_TOKEN (and similar) forwards a host variable into Docker-backed runs when the default allowlist would block it.
  • Smarter config, clearer model setting: config { } values can reference variables and workflow parameters. Breaking: rename agent.default_model to agent.model; it applies per prompt step, not as a global env var.
  • Jaiph on Windows: install with PowerShell, run a native .exe, and get the same workflows without WSL or Docker on win32.

dzikowski and others added 24 commits July 13, 2026 13:00
jaiph run spawns the workflow leader detached and previously stopped it
with process.kill(-pid, signal) — a POSIX-only negative-PID group kill.
On win32 that throws, the child.kill() fallback terminated only the
leader, and the agent backends / script children it spawned were
orphaned.

Add src/runtime/kernel/portability.ts exporting killProcessTree(pid,
signal) as the single sanctioned home for group kills. On POSIX it
preserves prior behavior (negative-PID group kill with a per-process
ESRCH fallback); on win32 it force-kills the whole tree with
`taskkill /pid <pid> /T /F` (spawned, not shelled) via an injectable
seam, degrading to a per-process kill if taskkill cannot launch.
Because taskkill /F is already forceful, the SIGTERM->SIGKILL
escalation is a documented no-op on win32.

Repoint every group-kill call site at the helper: run teardown
(lifecycle.ts), the prompt watchdog (prompt.ts), and the Docker
run-timeout kill (docker.ts). New unit tests stub process.platform to
cover both branches (negative-PID kill on POSIX plus ESRCH fallback;
taskkill /T argv on win32) and prove win32 never calls process.kill
with a negative PID; a src/-wide lint test asserts no production file
outside portability.ts matches `process.kill(-`. Docs updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Script steps previously ran by spawning the emitted file directly,
relying on the `#!/usr/bin/env <lang>` shebang and the 0o755 exec bit.
Windows honors neither, and `noexec` mounts on Linux strip the exec bit,
both breaking script execution. The runtime already knows the
interpreter since it writes the shebang itself, so `executeScript` now
reads the emitted script's shebang, resolves the interpreter through the
new `resolveInterpreterFromShebang` (`src/parse/script-bash.ts`), and
spawns `<interpreter> <scriptPath> <args...>` explicitly. The shebang
line is still written into every emitted script so they remain directly
executable by hand on POSIX, but the runtime no longer depends on it or
on the exec bit being honored. A spawn ENOENT from a missing interpreter
now surfaces as a diagnosable Jaiph error naming the interpreter instead
of a raw `spawn <name> ENOENT`. New unit tests assert the resolved
interpreter and argv on an injectable `_scriptSpawn` seam, prove a script
with the exec bit stripped (0o644) still runs on POSIX, and prove a
missing-interpreter shebang produces the diagnosable error.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Inline workflow shell lines (executeShLine) and CLI hook commands used a
hardcoded spawn("sh", ["-c", ...]), which fails on win32 where there is no
sh on the default PATH. Add resolveShell() to the portability module as the
single seam both call sites go through: on POSIX it returns bare sh; on
win32 it locates Git for Windows' bundled sh.exe, first on PATH and then in
the standard install layouts (<Git>/bin/sh.exe, <Git>/usr/bin/sh.exe) under
each known root, throwing a diagnosable E_NO_POSIX_SHELL error naming Git
for Windows if none is found. Resolution is memoized per process. Inline
lines are never translated to cmd/PowerShell, so POSIX shell semantics are
unchanged. Unit tests stub process.platform and the PATH/existence lookup
across all branches, and a src/-wide lint test asserts no spawn("sh") call
site remains outside portability.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Close three remaining POSIX assumptions that broke a host-only Windows
runtime. prepareClaudeEnv now falls back to os.homedir() when neither
execEnv.HOME nor process.env.HOME is set, so USERPROFILE-only
environments resolve the .claude config dir; an explicit execEnv.HOME
still wins. resolveDockerConfig forces host-only mode on win32 with a
one-line notice (same UX as JAIPH_UNSAFE=true), so the CLI never probes
docker and never hard-fails on a missing daemon, and
JAIPH_DOCKER_ENABLED=true cannot override it. A new canUseAnsi() helper
in the portability module centralizes the isTTY + NO_COLOR gate; every
color/erase emission site routes through it so the policy lives in one
place. Adds unit tests for each and a src-wide lint test asserting no
production file outside portability.ts gates directly on isTTY &&
NO_COLOR. Docs updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a Windows x64 target to the release workflow so every release ships
a fifth standalone binary alongside darwin/linux x arm64/x64. A new
bun-windows-x64 matrix entry (with an ext field so the compiled outfile
and uploaded artifact carry the .exe suffix) produces jaiph-windows-x64.exe;
Bun has no windows-arm64 target so Windows is x64 only. The .exe is
included in SHA256SUMS generation and in both the stable and nightly
gh release upload lists.

A new sanity-windows job runs on windows-latest, downloads the .exe
artifact, and runs jaiph-windows-x64.exe --version through a version
gate; the publish job now needs [build, sanity-windows], so a Windows
version mismatch fails the whole release. The linux-x64 gate's inline
comparison is extracted into a shared, testable
scripts/release-version-check.sh that both gates delegate to.

Update the release asset naming contract in docs/contributing.md and
docs/architecture.md, and add integration/release-workflow.test.ts
asserting the five-binary matrix, SHA256SUMS and upload-list coverage,
the shared gate behavior, and naming-contract/installer parity.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add docs/install.ps1 as the Windows counterpart to the POSIX docs/install
(run with irm https://jaiph.org/install.ps1 | iex). It downloads
jaiph-windows-x64.exe and SHA256SUMS from the pinned release ref (default
the current stable tag, overridable via JAIPH_REPO_REF / first arg plus
JAIPH_RELEASE_BASE_URL for local file:// dirs used by tests), verifies the
SHA-256 with Get-FileHash and installs nothing on mismatch, then installs
to %LOCALAPPDATA%\jaiph\bin\jaiph.exe (overridable via JAIPH_BIN_DIR), adds
it to the user PATH if absent, and prints the same try-it hints as the bash
installer. Non-x64 / ARM Windows exits non-zero with a documented
unsupported-platform message.

The bash installer now rejects Windows-like uname values and points at the
PowerShell one-liner, and prepare_release.jh rewrites the pinned ref in both
installers in lockstep. CI gains an installer-powershell job on
windows-latest that cross-compiles the real .exe and runs
e2e/tests/installer_powershell.ps1 (checksum mismatch, unsupported arch,
happy-path install with no Node/npm/Bun on PATH); the Docker publish job now
needs it. Host-portable guards live in integration/installer-powershell.test.ts.
Docs updated (setup.md, index.html, architecture.md, contributing.md, README).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The landing page hero install card now offers a Windows PowerShell path
alongside the POSIX curl | bash one-liners. A new .os-switch sub-toggle
(macOS/Linux vs Windows) sits above the run-sample / init-project /
just-install tabs, and each panel wraps its content in .os-variant blocks.

On load, attachOsSwitch() (docs/assets/js/main.js) auto-selects the
Windows variant for Windows visitors via isWindowsPlatform(), which
prefers navigator.userAgentData?.platform and falls back to
navigator.platform. macOS/Linux visitors keep today's POSIX default with
no layout shift; manual switching stays available and is remembered
card-wide. The 'Just install' Windows variant exposes the copy-able
irm https://jaiph.org/install.ps1 | iex line; the run-sample and
init-project tabs (no PowerShell pipe equivalent) show the install
one-liner plus a short 'then run:' jaiph command instead of a bash-only
default. The static-render constraint holds: the POSIX variant carries
is-active in the markup and CSS hides inactive variants, so with JS
disabled all bash one-liners render and no panel is blank.

New Playwright cases in the docs suite assert the Windows default, the
unchanged macOS/Linux default, manual platform + tab switching, the
clipboard contents of the Windows copy button, and the JS-disabled
static render.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Config blocks now resolve `${identifier}` and bare-identifier sugar at runtime so workflows can parameterize agent settings like default_model.

Co-authored-by: Cursor <cursoragent@cursor.com>
…lementation)

Spiked MVP of `jaiph mcp <file.jh>` plus design doc and queue tasks.
PARTIAL — do not treat as landed: verification gaps are inventoried in
QUEUE.md ("MCP 1-4/8") and must be closed by the queue task before this
feature is considered done.

Implemented:
- src/cli/mcp/tools.ts     — tool derivation (exports narrowing, route-target
                             exclusion, default→file-slug rename, comment
                             descriptions, string schemas); 10 unit tests
- src/cli/mcp/server.ts    — newline-delimited JSON-RPC 2.0 stdio server
                             (initialize/ping/tools/list/tools/call,
                             list_changed); 16 unit tests
- src/cli/mcp/call.ts      — per-call runner spawn, event capture, result
                             composition (return_value.txt → logs → note)
- src/cli/commands/mcp.ts  — command wiring, hot reload (watchFile), host
                             execution like `jaiph run --raw`
- src/cli/index.ts, usage  — `mcp` subcommand + `--mcp` alias
- runtime: runRoot(name, args) generalizes runDefault; runner dispatches any
  symbol; workflow-launch.ts fix — buildRunModuleLaunch hardcoded "default"
  and dropped the requested workflow symbol
- design/2026-07-14-mcp-server.md — full design; QUEUE.md — grouped task with
  per-piece verification state + ENV --env passthrough task

Verified: tsc + build clean; 26/26 mcp unit tests; live stdio session
(handshake, list, calls incl. -32602 and isError legs, concurrency).

NOT verified (see QUEUE.md acceptance):
- `jaiph run` direction of the workflow-launch fix (touches every run)
- hot reload path (never exercised)
- runRoot/launch argv have no dedicated unit tests
- full `npm test` suite not run since these changes

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Land the verification and gap-closing work for the spiked `jaiph mcp`
MVP whose implementation was committed earlier as WIP. Adds the missing
automated coverage and user-facing docs; no runtime behaviour changes.

Tests: pin the launch argv (the workflow symbol must reach the runner
verbatim, guarding the fixed hardcoded-"default" bug, plus the empty
fallback); unit tests for runtime `runRoot` (non-default workflow runs
as root with positional param binding and return_value.txt on success,
unknown workflow returns 1 with no return value, runDefault delegates
unchanged); and an end-to-end scripted stdio session covering
initialize, tools/list with comment-derived descriptions, tools/call
return values, missing-arg -32602, workflow-failure isError, compile
diagnostics to stderr, --help/--mcp alias dispatch, hot reload
(list_changed) and broken-edit tolerance, and a `jaiph run` regression.

Docs: new docs/mcp.md how-to, a `jaiph mcp` reference section in
docs/cli.md, README and docs nav entries, CHANGELOG, and QUEUE cleanup.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Introduce a repeatable --env flag that lets a workflow receive a specific
host variable outside the fail-closed Docker env allowlist, with the flag
itself standing in as per-key consent. Supports both --env KEY=VALUE
(first = splits, value may contain =, empty allowed) and bare --env KEY
(forwards the host value, aborting with E_ENV_MISSING before spawning if
unset). Names must match [A-Za-z_][A-Za-z0-9_]* or abort with
E_ENV_INVALID, and sandbox-control / runtime-managed keys are refused with
E_ENV_RESERVED.

Semantics are uniform across every execution mode: in host modes the pairs
are applied to the runner env after resolveRuntimeEnv/applySandboxFlags; in
a Docker sandbox they are threaded through DockerSpawnOptions.extraEnv into
buildDockerArgs as explicit -e KEY=VALUE args that bypass isEnvAllowed, each
key emitted exactly once with the --env value winning. On jaiph mcp the
pairs are resolved once at startup and applied to every tool call for the
server's lifetime. Values cross verbatim with no path remapping.

Updates usage strings, docs (cli, env-vars, sandboxing), and adds parse,
buildDockerArgs, resolve-env, MCP, and e2e coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Complete the MCP how-to and cross-references for serving a .jh file's
workflows as MCP tools over stdio. Add JSON client-config examples
(Claude Desktop, Cursor) alongside the claude mcp add command in
docs/mcp.md, and correct the default exposure rule to match the tree.
Add an MCP server feature note to the landing page (docs/index.html)
and reflect it in the CHANGELOG. Close two test gaps that back
documented behaviour: a non-object JSON message is an invalid request
(-32600) with null id, and toolNameFromFile truncates the derived slug
to 128 characters. Drop the completed task from QUEUE.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add black-box e2e coverage of `jaiph mcp` through the real binary
entrypoint (e2e/tests/139_mcp_server_session.sh), wired into
`npm run test:e2e`. The script drives `jaiph mcp <fixture.jh>` as a
child process over stdio with a scripted JSON-RPC session — initialize,
tools/list, a successful tools/call round-tripping a param through the
workflow return, and a failing tools/call — then closes stdin. It
asserts every stdout line is valid JSON-RPC 2.0 (no banner or progress
leakage), the successful tool result text equals the workflow's return
value, the failing workflow yields isError:true rather than a protocol
error, and the server exits 0 on stdin close.

A regression leg asserts `jaiph run` on a default workflow still exits 0
and prints its return value, pinning the shared workflow-launch.ts
launch path in both the named-symbol and default directions after the
hardcoded-`default` fix. Update CHANGELOG.md and drop the completed task
from QUEUE.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Long-running `jaiph mcp` tool calls can now stream progress to the client
and be cancelled mid-run. When a `tools/call` carries a
`params._meta.progressToken`, each of the run's STEP_START/STEP_END events
is translated into a `notifications/progress` with a monotonically
increasing counter; notifications stop the moment the call's response is
sent, and calls without a progressToken emit none. A
`notifications/cancelled` for an in-flight request id terminates that
call's child process tree via the new `cancelRunProcess` in
lifecycle.ts (SIGINT then an unref'd force-kill timer escalating to
SIGKILL), sends no response for the cancelled id, and keeps the server
serving. Step events and the child terminator are surfaced through a new
per-call `McpCallContext` (`onStep` / `onCancelHandle`), wired by
`attachOutputCollector` off the existing `parseStepEvent` stderr stream.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
docs-lint caught the only failure in the full suite after the MCP queue
landed: cli.md linked mcp.md#stream-progress-and-cancel-a-long-call but the
heading is numbered ("## 7. Stream progress and cancel a long call"), so the
anchor needs the 7- prefix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…el to prompts only.

In-file agent.model no longer maps into JAIPH_AGENT_MODEL — it resolves per prompt
and is passed as --model to the backend CLI. JAIPH_AGENT_MODEL remains a shell-only
run-wide override. Parser, runtime, tests, docs, and in-repo .jh modules updated.

Co-authored-by: Cursor <cursoragent@cursor.com>
…onfigs.

install-from-local.sh builds runtime/Dockerfile and tags ghcr.io/jaiphlang/jaiph-runtime:<version> plus :nightly so sandbox runs match the checkout without JAIPH_DOCKER_IMAGE. Standalone CLI resolves the default image tag from embedded VERSION when package.json is absent. Update .jaiph workflows with per-step agent.model and claude backend defaults; queue 0.11.0 release task.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add a #dev-ready task to render prompt steps as `prompt <backend> <model> "…"` in the live run tree, using the already-resolved model from prompt invocation.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add a #dev-ready task requiring bare identifier, quoted, and bare ${ref}
forms to be equivalent everywhere the language accepts orchestration strings.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add a #dev-ready task to fix orphaned containers after SIGINT and extend e2e beyond sandbox-dir cleanup to assert the container exits.

Co-authored-by: Cursor <cursoragent@cursor.com>
…s scope.

Document a #dev-ready UX task for unsafe host-only consent, clearer workspace-vs-whole-machine warnings, and the inplace typo fix.

Co-authored-by: Cursor <cursoragent@cursor.com>
Accept bare ${name} interpolation refs everywhere Jaiph string RHS parsers
already allow bare identifiers or quoted strings. ensure_ci_passes unsets
inherited JAIPH_* variables before npm run test:ci so agent workflow env
does not leak into integration tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
@dzikowski dzikowski changed the title 0.10.1 0.11.0 Jul 15, 2026
dzikowski and others added 5 commits July 15, 2026 16:54
Cut v0.11.0 from the Unreleased changelog block. Bump package.json and
package-lock.json to 0.11.0, refresh the pinned installer ref v0.10.0 ->
v0.11.0 in both docs/install and docs/install.ps1, and stamp CHANGELOG.md:
rename Unreleased -> 0.11.0 with a new Summary section (MCP server + Docker
parity, --env passthrough, config interpolation + agent.model breaking
changes, Windows portability/distro) above the existing All changes bullets,
leaving a fresh empty Unreleased section at the top. Update remaining
user-facing "current release" literals from 0.10.0 to 0.11.0 across
docs/index.html, README.md, docs/setup.md, docs/env-vars.md, docs/cli.md,
and docs/contributing.md, and drop the completed release task from QUEUE.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Each NodeWorkflowRuntime run now clears the process-local mock response
queue so identical JAIPH_MOCK_RESPONSES_JSON does not exhaust shared mocks
and fall through to real backends with long retry backoff. resolveRuntimeEnv
sets JAIPH_AGENT_MODEL to "" when unset so scripts under set -u do not fail.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace implementation-heavy bullets with a short, human-facing feature
summary for MCP, --env, config/model changes, and Windows support.

Co-authored-by: Cursor <cursoragent@cursor.com>
Nightly prereleases are branch-driven only; the redundant git tag conflicted
with refs/heads/nightly and broke plain git push.

Co-authored-by: Cursor <cursoragent@cursor.com>
Prompt steps in the live run tree and non-TTY step labels now render the
effective model as a bare token between the backend and the quoted
preview: `▸ prompt claude sonnet "Classify this task…"` on start and
`✓ prompt claude sonnet (5s)` on completion. The model is the value
already passed to the backend for that invocation (whatever
`resolveModel` returns with a non-empty string); the token is omitted
when the backend auto-selects, falling back to the prior two-token
`prompt <backend> "…"` form. A custom `agent.command` still shows the
command basename with the model appended after it.

The resolved model is threaded to the display layer as a new `model`
field on the `STEP_START`/`STEP_END` events and parsed into
`StepEvent.model`, so the display formatters render the three-part label
without re-reading `PROMPT_START`. Existing truncation rules (24-char
preview, 96-char line cap) are unchanged. This is CLI/run-tree
presentation only — the `.jh` language is untouched and
`config { agent.model = … }` remains the authoring surface.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dzikowski and others added 24 commits July 15, 2026 17:40
Interrupting a Docker-backed `jaiph run` (SIGINT/SIGTERM on the host CLI)
previously killed the terminal session but left the `docker run` container
running, so orphaned containers kept executing workflow/agent work against
the sandbox workspace with no attached host CLI.

The signal path now reliably terminates the `docker run` child spawned by
`spawnDockerProcess` and awaits container exit before `cleanupDocker`
removes the copy-mode `.sandbox-*` clones, keeping cleanup and container
lifecycle coupled across copy, overlay, and inplace modes. The MCP
per-call Docker sandbox is aligned to the same stop contract.

Extends `e2e/tests/74b_docker_signal_cleanup.sh` to assert the container
is gone from `docker ps` within a bounded window after SIGINT (in addition
to the existing `.sandbox-*` cleanup assertion), and adds unit coverage in
`lifecycle.test.ts` and `docker.test.ts` that the handler terminates the
docker child. Docs and QUEUE updated accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Host-only runs triggered by --unsafe / JAIPH_UNSAFE previously started
immediately with no sandbox and no consent, unlike --inplace which
already gated launch behind a warning and Continue? [y/N]. Add a new
confirmUnsafeRun prompt (stronger than inplace) that leads with the
access scope: host-only, no sandbox, whole-machine filesystem reach, and
full host environment visible to scripts and agents. Restructure
formatInplaceWarning to lead with workspace-only scope and fix the
"therest" typo. On non-TTY, both modes now require an explicit --yes /
auto-confirm; unsafe aborts with E_UNSAFE_NO_CONFIRM otherwise. Adds
unit, run, and e2e coverage plus docs for cli, env-vars, and sandboxing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Call args like run to_lower(result.role) were stored as the literal text
"result.role" instead of typed-prompt field access. Classify bare dotted
names as var refs and reject unquoted ${…} outside strings.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the redundant "(live host edits)" parenthetical from the Docker
in-place run banner. Changelog also records bare IDENT.IDENT call-arg
resolution and unquoted ${…} rejection from the prior commit.

Co-authored-by: Cursor <cursoragent@cursor.com>
Emit `default` on STEP_START/STEP_END when the backend CLI picks its
own model, so the run tree always shows a model token without passing
--model to the backend.

Co-authored-by: Cursor <cursoragent@cursor.com>
Strip common leading whitespace at parse time so heredoc delimiters and
polyglot scripts run correctly when authors indent blocks for readability.

Co-authored-by: Cursor <cursoragent@cursor.com>
Stage and verify the binary before promote, rm+mv for a fresh inode
(macOS reinstall while jaiph is running), and refuse unsafe JAIPH_BIN_DIR
values (system dirs, directory targets, non-regular files).

Co-authored-by: Cursor <cursoragent@cursor.com>
Introduces logwarn as a say-level keyword parallel to log and logerr, with LOGWARN events, yellow ⚠ CLI rendering, and docs/changelog coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
Tracks stdout/stderr idle time at leaf executors and warns after JAIPH_STEP_IDLE_WARN_SEC (default 180s) with a message like "script name: no output for 180s".

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the git-tree/uncommitted-changes check from opt-out prompts, shorten the copy, show (Docker sandbox, unsafe) in the run banner, and emit a startup LOGWARN when unsafe mode proceeds.

Co-authored-by: Cursor <cursoragent@cursor.com>
Emit incremental LOGWARNs during continuous silence (180s, 360s, …) and rename the message to "no new output for Ns"; output chunks reset the cadence.

Co-authored-by: Cursor <cursoragent@cursor.com>
Ship a curated daily-coding toolset in jaiph-runtime (~3.2 GB) so sandbox
scripts can run common builds without ad-hoc installs, document the inventory,
and allowlist OPENAI_* so the codex backend works in Docker like other agents.

Co-authored-by: Cursor <cursoragent@cursor.com>
…eardown.

Sync golden AST with logwarn fixture, quote the recover payload path in e2e,
suppress the default model label for custom agent commands, kill Docker containers
before rm on interrupt to avoid macOS Desktop lock contention, and document the
unsafe-run banner and warning in the first-workflow tutorial.

Co-authored-by: Cursor <cursoragent@cursor.com>
Use ++waited instead of waited++ so the arithmetic expression is non-zero
on the first iteration and does not trigger set -e early exit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update expected CLI output in docs/first-workflow.md to match the new
Docker sandbox unsafe prompt format. Add gh_ci_passes.jh workflow and
the jaiphlang/gh_actions library (.jh + .sh) for automated CI monitoring
and recovery.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ility

Overlay mode depends on /dev/fuse being available, which is not reliably
present in all Docker environments (e.g. GitHub Actions Ubuntu runners).
Always return "copy" when isolation is requested to avoid the fuse probe.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Defer selectMcpSandboxMode isolation back to selectSandboxMode instead of
hardcoding copy, and force no-overlay in GHA docker jobs where fuse is unreliable.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ace.

Avoid polluting the workspace with .jaiph/claude-config when the default
config path is not writable; prefer JAIPH_RUN_DIR, then system temp.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add dev-ready specs with acceptance criteria for workflow if/else-if sugar
and match arm pattern alternation (e.g. "a" | "b" => …).

Co-authored-by: Cursor <cursoragent@cursor.com>
Overlay mode requires fuse-overlayfs inside the container, which is
unavailable on GitHub Actions Ubuntu runners. Copy mode provides the
same isolation guarantee and is reliably portable across all Docker
environments.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Accept `} else if <cond> {` arms after an `if` body, chaining to
arbitrary depth with the same condition grammar as a top-level `if`.
The parser desugars each arm into a nested `if`/`else` tree so no new
runtime step type is needed and existing execution paths keep working.
`if` remains statement-only. The formatter re-emits `else if` when the
nested AST matches the sugar shape, preserving author intent on
round-trip. Malformed arms (no condition, empty body, `else if` split
onto its own line, or without a preceding `if`) stay `E_PARSE`.

Updates grammar and language docs, adds a golden AST fixture, parser
and emit unit tests, negative parse cases, and an E2E three-arm chain
test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Allow match arms to combine multiple patterns with `|` so a single arm
matches if any alternand matches ("foo" | "bar" => body). Supports
pipe-separated string literals and regexes; the wildcard `_` cannot
participate in alternation and mixing kinds or a trailing `|` raises
E_PARSE. Adds an alternation node to MatchPatternDef, extends the parser,
runtime evaluation, formatter round-trip, and grammar docs, plus unit,
golden-AST, and e2e coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The 144_if_else_if_chain acceptance test was added with the feature but
never registered in the suite, so CI skipped it.

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

1 participant