Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
cb0e656
build: package pinned native installer distributions
SaladDay Sep 28, 2026
67c8c03
refactor(install): retire user-managed Docker installer
SaladDay Sep 28, 2026
71b025c
feat(installer): install verified native Harnesses with additive reco…
SaladDay Sep 28, 2026
138a1f1
Merge commit '0e84edaa' into codex/unified-harness-installer-20260929
SaladDay Sep 28, 2026
d9df2e1
build: reuse verified MiniMax tool archive cache
SaladDay Sep 28, 2026
29dabf1
refactor(installer): keep native activation and checks in Harness ada…
SaladDay Sep 28, 2026
b549d02
Use native Runtime installation in Connect a host
SaladDay Sep 28, 2026
5ac1311
fix: resolve native bundle output aliases before containment checks
SaladDay Sep 28, 2026
42a9571
fix: archive Windows installer without drive-letter tar ambiguity
SaladDay Sep 28, 2026
8f43257
docs: define unified native installation and retire container setup g…
SaladDay Sep 28, 2026
5476f6e
Merge commit '9c060081d9d0bd6760d1b6d12772bec8290e5735' into codex/un…
SaladDay Sep 28, 2026
bcdfc60
docs: publish current native installation guide and README entry
SaladDay Sep 28, 2026
3e4951c
fix(installer): activate MiniMax MCP bridge rather than worker launcher
SaladDay Sep 28, 2026
98546d2
Merge commit '1bdd1433' into codex/unified-harness-installer-20260929
SaladDay Sep 28, 2026
fc23bd2
fix(installer): reject Claude bundles with retired preparation contracts
SaladDay Sep 28, 2026
221b48a
build: ship MiniMax in native Unix installer bundles
SaladDay Sep 28, 2026
f51f9e3
fix: resolve bundled ripgrep through its package API
SaladDay Sep 28, 2026
eab6b20
fix(installer): cancel native probes on installation interruption
SaladDay Sep 28, 2026
785f5de
Merge commit 'eae849bb' into codex/unified-harness-installer-20260929
SaladDay Sep 28, 2026
0c37059
Require stop before replacing native host credentials
SaladDay Sep 28, 2026
23f893e
docs: specify installer cancellation and system package boundaries
SaladDay Sep 28, 2026
7bcf828
fix: preserve runnable npm entrypoints in native bundles
SaladDay Sep 28, 2026
bcfd1df
fix(installer): propagate startup cancellation through enrollment and…
SaladDay Sep 28, 2026
16e1b74
Pair enrollment expiry checks with confirmed node data
SaladDay Sep 28, 2026
d902623
Merge commit '16a03428' into codex/unified-harness-installer-20260929
SaladDay Sep 28, 2026
19ac80f
fix(installer): validate MiniMax companion readiness before installat…
SaladDay Sep 28, 2026
eee762f
docs: align getting-started host connection with native installation
SaladDay Sep 28, 2026
54d4f11
Merge commit '781a4dcd' into codex/unified-harness-installer-20260929
SaladDay Sep 28, 2026
032ddc2
fix(installer): restrict startup to verified installed Harnesses
SaladDay Sep 28, 2026
326eaa1
fix(installer): reject direct connect for installed Runtimes
SaladDay Sep 28, 2026
eae2200
docs: align credential recovery and connection status guidance
SaladDay Sep 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions .github/workflows/native-installer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: native-installer

on:
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
bundle:
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, macos-14, windows-2022]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version-file: go.mod
- uses: actions/setup-node@v6
with:
node-version: '22.22.0'
- name: Build the native daemon and test bundle boundaries
run: |
go build -ldflags "-X github.com/MiniMax-AI-Dev/parsar/apps/parsar-daemon/internal/cli.Version=$GITHUB_SHA" -o "$RUNNER_TEMP/oac-daemon${{ runner.os == 'Windows' && '.exe' || '' }}" ./apps/parsar-daemon/cmd/parsar-daemon
node --test scripts/build-native-installer.test.mjs
- name: Build pinned native components
run: |
npm install --global pnpm@10.30.3
pnpm install --frozen-lockfile --filter @parsar/claude-sdk-adapter...
pnpm --filter @parsar/claude-sdk-adapter build --outDir "$RUNNER_TEMP/claude-compiled"
pnpm --config.inject-workspace-packages=true --config.extend-node-path=false --filter @parsar/claude-sdk-adapter deploy --prod "$RUNNER_TEMP/claude-runtime"
rm -rf "$RUNNER_TEMP/claude-runtime/dist"
mv "$RUNNER_TEMP/claude-compiled" "$RUNNER_TEMP/claude-runtime/dist"
# Reify the dedicated frozen export lock without pnpm's symlink layout.
# Flattening isolated package links changes Node dependency resolution.
rm -rf "$RUNNER_TEMP/claude-runtime/node_modules"
pnpm --dir "$RUNNER_TEMP/claude-runtime" install --prod --frozen-lockfile --config.node-linker=hoisted --ignore-scripts
npm install --prefix "$RUNNER_TEMP/native-tools" --no-save @openai/codex@0.153.4
- name: Build the pinned MiniMax companion on Unix
if: runner.os != 'Windows'
run: |
source_repository="$(node -p 'require("./packages/mcode-harness/source.json").repository')"
source_revision="$(node -p 'require("./packages/mcode-harness/source.json").revision')"
source_version="$(node -p 'require("./packages/mcode-harness/source.json").version')"
git init --quiet "$RUNNER_TEMP/mcode-source"
git -C "$RUNNER_TEMP/mcode-source" remote add origin "$source_repository"
git -C "$RUNNER_TEMP/mcode-source" fetch --depth 1 origin "$source_revision"
git -C "$RUNNER_TEMP/mcode-source" checkout --detach FETCH_HEAD
npm install --prefix "$RUNNER_TEMP/mcode-native" --no-audit --no-fund --include=optional --install-strategy=nested "@minimax-ai/code@$source_version"
MCODE_NATIVE_SOURCE="$RUNNER_TEMP/mcode-source" \
MCODE_CLI_DIR="$RUNNER_TEMP/mcode-native/node_modules/@minimax-ai/code" \
MCODE_HARNESS_BUILD_DIR="$RUNNER_TEMP/minimax-runtime" \
bash scripts/build-mcode-harness.sh
- name: Package and exercise CLI-only installation, additions and reuse
run: |
if [[ "$RUNNER_OS" == Windows ]]; then
export CLAUDE_CODE_GIT_BASH_PATH='C:\Program Files\Git\bin\bash.exe'
fi
node scripts/build-native-installer-ci.mjs
- name: Verify native Harness protocols without model requests
run: |
if [[ "$RUNNER_OS" == Windows ]]; then
export CLAUDE_CODE_GIT_BASH_PATH='C:\Program Files\Git\bin\bash.exe'
fi
node scripts/native-harness-smoke.mjs --codex-binary "$RUNNER_TEMP/native-installer/components/codex/bin/codex${{ runner.os == 'Windows' && '.exe' || '' }}" --claude-runtime "$RUNNER_TEMP/native-installer/components/claude"
- name: Archive the native distribution
run: |
cd "$RUNNER_TEMP"
tar -C native-installer -czf "oac-native-installer-${{ runner.os }}-${{ runner.arch }}.tar.gz" .
- uses: actions/upload-artifact@v6
with:
name: oac-native-installer-${{ runner.os }}-${{ runner.arch }}
path: ${{ runner.temp }}/oac-native-installer-*.tar.gz
if-no-files-found: error
60 changes: 50 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2246,13 +2246,11 @@ uninstall with the previous release before adding it again. The machine
configuration route rejects `X-Parsar-Node-ID` with `400 invalid_request`; only
`X-OAC-Node-ID` identifies a retained node credential.

Self-hosted installations use `oac-selfhost` and `~/.oac/self-hosted/<environment-id>`.
The installer refuses an existing `~/.parsar/self-hosted/<environment-id>` for the
same Environment, even with a custom new install directory. Old executors keep
running with their own image and history; operators explicitly stop and remove
them before replacing them. New installation never adopts their native history.
Credential replacement for a new installer-owned executor retains its existing
container and ownership checks.
User-managed hosts use the native daemon installer on Linux, macOS and Windows.
It does not select a supplier or create compute resources. The retired Docker
self-hosted installer/launcher and console payload are not retained as fallback.
Existing environments, credentials, workspaces and native history are never
automatically deleted or adopted by a new installation.

One Runtime image contains the existing daemon, shared helpers and three native
harness packages. Their differences remain in the adapters. Core keeps exclusive
Expand Down Expand Up @@ -3855,8 +3853,8 @@ and use its absolute `dist/main.js` as the private factory entrypoint. Validate
relocation and real provider cancellation/continuation before accepting an
artifact. Linux x64/glibc with Node22 is the currently exercised platform;
other hosts require their own native acceptance. Do not reuse a bundle across
platforms or libc variants. Automatic Node installation, managed activation and
release publication remain separate work. Operator-configured daemon discovery/registration is supported as
platforms or libc variants. Standalone Claude archives require operator-supplied Node. The native installer
bundles Node and owns user-managed activation; release publication remains separate. Operator-configured daemon discovery/registration is supported as
specified above.

The exported `dist/runtime_check.js` companion is the local readiness contract.
Expand All @@ -3870,7 +3868,7 @@ with shared process-group ownership, bounded output and a 15-second deadline
plus bounded cleanup. Both native and bridge probes have five-second limits.
Return unavailable on failed or malformed probes; never forward native diagnostics
or treat local readiness as provider authentication, public capability acceptance
or filesystem isolation. Automatic installation remains separate.
or filesystem isolation. The native installer reuses this readiness check after copying its release components.


### Harness selection and Agent defaults
Expand Down Expand Up @@ -4056,3 +4054,45 @@ terminal transaction: event/input receipt for normal terminal projections, one
post-lock database wall-clock sample for forced incomplete Items. Preserve
historical terminal nulls and public native completion times. See the
[diagnostics contract](contracts/agents-api/session-diagnostics.md).

## Native daemon and Harness installation

`oac-daemon install` owns interactive selection and CLI-only installation through
one options/validation path. No installation-options file input is supported.
Persisted installation state and explicitly supplied credential/tool-variable
files serve runtime operation, not a second installer configuration language.
The release bundles pinned Node/npm, native Harnesses and required adapter assets;
registration lives in CLI and native activation/readiness in each adapter's optional
`agent.Installation` descriptor. Core never selects native paths or OS-specific
installation steps. See [native installation](docs/self-hosted-native.md).
An installed daemon discovers and registers only the adapter kinds named by its
verified installation manifest. The host PATH stays available to tools; its other
Harness executables and activation variables cannot extend that installation.
Direct `connect` rejects an installation manifest and directs the operator to
`start`; unmanaged image bootstrap remains available without that manifest.

All mutations use the installation directory lock. Publish complete checksum-verified
components from staging, then commit configuration after native readiness passes.
Re-running with the same connection settings adds selected Harnesses and validates
existing contents. Never overwrite, upgrade, auto-repair or migrate installed
components. Missing, modified, wrong-platform or incompatible content is an explicit
error. A partial addition must preserve the old configuration and allow reuse of
complete components; it must not remove previous files or data.

Installers run as the current user in writable directories. Native subprocess
diagnostics must not expose sensitive parameters or environment values. Adapter
readiness checks receive the installer cancellation context and must reap owned
processes before returning after interruption. Readiness,
authenticated connection and model configuration are separate reported facts.
Starting execution must not download or install Harnesses. Ordinary stop/reconnect
must preserve capability snapshots and native Session state.

`scripts/build-native-installer.mjs` packages native inputs, validates pins/startup
and hashes every component file. It uses contained regular files and rejects
escaping links. Claude's dedicated frozen `pnpm deploy` export is reified with
the hoisted linker for this distribution before contained links are flattened;
the original standalone Claude archive contract remains unchanged. The native
installer workflow builds and tests on Linux, macOS and Windows, including actual
installation, addition/reuse, missing arguments and unsupported Windows MiniMax.
Native CI startup checks do not replace real model execution evidence or claim
manual Windows acceptance. Heavy builds belong on remote servers or CI.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
**Open-source Agents API infrastructure, with your choice of native harness.**

Run Codex, Claude Code and MiniMax Code behind the OpenAI Agents API, on machines you
control. Core serves the API and runs each Session in a sandbox; Web is the
control. Core serves the API and drives each Session through its Runtime; Web is the
administrator console that issues the keys applications call Core with.

## Get started
Expand Down Expand Up @@ -56,9 +56,9 @@ Applications then set `OPENAI_BASE_URL` to `https://core.example/v1` and
self-hosted executors.
- **One Runtime path.** The same daemon handles initial files, tool configuration,
packages, setup, Skills/Plugins and execution. Providers place and bootstrap
compute, then renew or reclaim it. The protocol is platform-neutral; the current
packaged implementation and isolation are Linux-only. Harness differences stay
in adapters.
compute, then renew or reclaim it. User-managed daemons support Linux, macOS and
Windows with the launching account's permissions. Managed Providers remain
Linux-only and provide outer isolation. Harness differences stay in adapters.
- **A console for administrators.** Web signs in with the Core key, issues Project API
keys, adds nodes, sets default models and shows metrics and Session history. It
never runs Agents on anyone's behalf.
Expand All @@ -75,6 +75,7 @@ native differences.
| [Install Core and Web](docs/getting-started/install.md) | Prerequisites, download, installer options, HTTPS and the reverse proxy, first sign-in |
| [Nodes](docs/getting-started/nodes.md) | Adding, removing and troubleshooting nodes |
| [Self-hosted executors](docs/getting-started/self-hosted.md) | Connecting an application's own machine to a Session |
| [Native daemon and Harness installer](docs/self-hosted-native.md) | Linux/macOS/Windows, interactive or CLI installation, adding Harnesses, prerequisites and operation |
| [Operations](docs/getting-started/operations.md) | The `oac` command, the Core key, backups, upgrades, troubleshooting |
| [Configuration reference](docs/configuration.md) | Every setting in `config.json` and in Web |
| [Call the API](docs/getting-started/quickstart.md) | The application developer's quickstart |
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/admin-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The browser uses the console's own origin and signs in with the
| `GET /console/auth` | No body | `200 {"mode":"login"}` or `200 {"mode":"authenticated"}` |
| `POST /console/auth/login` | `Content-Type: application/json`, body `{"core_key":"…"}`; other members are rejected | `200 {"mode":"authenticated"}` and an HttpOnly, SameSite=Strict session cookie (Secure over HTTPS) |
| `POST /console/auth/logout` | No credential payload | `200 {"mode":"login"}`; clears the cookie and the server-side session |
| `GET /console/config` | Signed-in session | `node_installer`, `node_installer_sha256`, `self_hosted_installer`, `self_hosted_installer_sha256`, and `node_artifacts`: the providers (`docker`, `microsandbox`) whose node assets this console holds |
| `GET /console/config` | Signed-in session | `node_installer`, `node_installer_sha256`, `node_artifacts`: the providers (`docker`, `microsandbox`) whose node assets this console holds |

Sign-in errors use the console's `{"error": "…"}` envelope: 400 for a malformed
body, 401 for a wrong key, 415 for a non-JSON body, 429 with `Retry-After` when
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/docs/configure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,8 @@ loads the file with `env_file` and systemd with `EnvironmentFile`, so Compose mu
A Web you run without the installer reads the variables in
[Connecting the administrator console to Core](/bootstrap-projects-keys#server-configuration-and-login),
plus `OAC_WEB_NODE_PAYLOAD_DIR`: the absolute path of the matched distribution's
node payload (the installer's `node-payload/`). Without it, Add node and the
self-hosted install command are unavailable.
node payload (the installer's `node-payload/`). Without it, Add node is
unavailable. Native self-hosted installation uses its separate platform bundle.

Core fails at startup, naming the replacement, while a retired variable is set:
`AGENTS_API_DAEMON_WS_URL` (use `OAC_PUBLIC_URL`), `AGENTS_API_CONFIG_FILE` (no
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/install.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ The installation directory, `~/.oac/core` by default, mode `0700`:
| `secrets/database.password` | PostgreSQL password |
| `state.json` | Format 2, installation ID, Compose project name, image IDs and source commit. Written by the tools only |
| `generated/` | Files derived from `config.json`: `compose.json`, `core.env`, `core-key-digests.json`, `settings.json`, `config.schema.json`, and `runtime-history.json` or the native Core unit when used. `oac apply` rewrites them; don't edit them |
| `node-payload/` | The node and self-hosted installers, the manifest and the node files that Web serves at `/node-install/` |
| `node-payload/` | The managed node installer, the manifest and the node files that Web serves at `/node-install/` |
| `state/e2b/` | Private E2B receipts |
| `native/` | Core binaries, with `--native-core` only |

Expand Down
13 changes: 7 additions & 6 deletions apps/docs/content/docs/self-hosted-execution.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,16 @@ Otherwise creation fails with 400 `model_provider_required`.
2. In Web, open **Session log**, then the Session's **Executor credentials**
section. Choose **Issue credential**, then **Download credential file**. Core
returns the credential only once; retain it privately before choosing **Done**.
3. On the host, run `oac-daemon install` with the returned `remote_url`, Environment
ID, matching workspace and absolute credential-file path, then `oac-daemon start`.
3. Extract the native distribution and run `oac-daemon install --interactive`
(or supply all options with `--non-interactive --harness`). Use the returned
remote URL, Environment ID, matching workspace and credential file path, then
start the installed `bin/oac-daemon`.
The [native guide](/self-hosted-native#install-and-start) has Linux/macOS and
PowerShell examples. No Docker installation is required for this native path.

The console's existing **Connect a host** download command targets the Linux
container installer, not the native installation command. Use the native guide for
this workflow; downloading an executor credential is independent of the console's
installer assets. Core must be reachable from the host: `wss://` is required
The console's **Connect a host** flow provides native installation guidance and
the executor credential download. Obtain the matching native distribution before
running its command. Core must be reachable from the host: `wss://` is required
outside loopback, while a local Core can use a loopback `ws://` URL.

A connected Environment proves only the machine connection. Send a Turn to check
Expand Down
Loading
Loading