Skip to content

feat(ai-harness): build artifacts, worker mode, and remote harnessText - #1521

Open
AlemTuzlak wants to merge 7 commits into
feat/harness-p4-subagentsfrom
feat/harness-p5-build
Open

AlemTuzlak wants to merge 7 commits into
feat/harness-p4-subagentsfrom
feat/harness-p5-build

Conversation

@AlemTuzlak

@AlemTuzlak AlemTuzlak commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

A harness can now run outside your server: as a worker process built with Bun, on another machine behind --serve, or as a single executable. buildHarness writes a bundle and a manifest, artifactText(dir) runs it as a model, and harnessText({ url, token }) talks to a remote harness. This is Phase 5 of the harness stack.

Stacked on #1520 (Phase 4) → #1519 → #1518 → #1515 → #1513 → #1509. Merge those first.

🎯 Changes

  • @tanstack/ai-harness/build: buildHarness({ entry, export, outDir, compile? }) bundles with Bun into harness.js and writes harness.manifest.json (name, agents, plugins, requirements, sha256 digest). artifactText(dir) checks the digest, starts one worker per outer thread, and is a text adapter with dispose(). readManifest(dir).
  • @tanstack/ai-harness/worker: runHarnessWorker(harness) serves session-tier frames as NDJSON on stdin and stdout.
  • harnessText({ url, token }): a remote harness (served by createHarnessHandler or runCli --serve) as a text adapter. It sends only the new message, because the remote session keeps the history.
  • Docs: docs/harness/deploy.md. Changeset: harness (minor).

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with pnpm run test:pr, or these tests do not apply to this pull request.
  • I fully understand the code in this pull request, including any code generated with AI assistance.
  • Docs: I updated docs/ for this change, or this change is not user-facing.
  • Changeset: I added a changeset (pnpm changeset), or this PR does not change a published package.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Testing

Commands run (not the full pnpm test:pr, see below):

  • @tanstack/ai-harness: vitest run (72 passed, including a real Bun build and a worker process), tsc --noEmit, test:oxlint, build, test:build. @tanstack/ai-harness-cli: vitest run (8 passed).
  • testing/e2e: tsc --noEmit, playwright test tests/harness.spec.ts tests/harness-protocol.spec.ts (9 passed, including a remote harness over HTTP).
  • pnpm test:docs, kiira check docs/harness/deploy.md, pnpm test:sherif, pnpm test:knip.
  • Skipped the full pnpm test:pr run because it is slow on this machine. CI runs it.
  • The compile option is not run in tests (a Bun executable is about 100 MB).

Manual test

  1. Install Bun. Run pnpm --filter @tanstack/ai-harness exec vitest run tests/build.test.ts. It writes a harness file, builds it, and chats with the worker twice.
  2. Or follow docs/harness/deploy.md: buildHarness on a harness file, then chat({ adapter: await artifactText('./dist/studio'), ... }).

How this PR makes testing easy

  • packages/ai-harness/tests/build.test.ts: worker frames, remote harnessText, a real buildHarness run, artifactText keeping the conversation across calls, and a refused tampered bundle.
  • E2E: the remote scenario in testing/e2e/tests/harness.spec.ts calls the app's own protocol route over HTTP.

Risk / rollback

Low. New subpaths and a new harnessText overload. The build imports the user's entry in a child process (documented). Revert the PR to undo.

Public API change

Before

chat({ adapter: harnessText(studio, { host }), messages })

After

await buildHarness({ entry: './src/studio.ts', export: 'studio', outDir: './dist/studio' })
chat({ adapter: await artifactText('./dist/studio'), messages })
chat({ adapter: harnessText({ url: 'http://build-box:8787', token }), messages })

🤖 Generated with Claude Code

https://claude.ai/code/session_01APYv1qshKyjPPpkFyRZhfZ

Summary by CodeRabbit

  • New Features
    • Harnesses can now connect to remote servers and stream text responses, with optional bearer-token authorization.
    • Build harness artifacts or standalone executables, then run artifacts with per-thread conversations.
    • Run harnesses as workers using a line-based protocol.
  • Documentation
    • Added deployment guidance for running harnesses in servers, as worker artifacts, on remote machines, or as executables.

@tanstack/ai-harness/build: buildHarness bundles a harness with Bun into a
worker artifact (harness.js) plus harness.manifest.json (name, agents,
plugins, requirements, sha256 digest), and can compile a single executable.
artifactText(dir) checks the digest, starts one worker process per thread,
and uses it as a text adapter.

@tanstack/ai-harness/worker: runHarnessWorker serves session-tier frames as
NDJSON on stdin and stdout.

harnessText({ url, token }) uses a harness served on another machine (for
example with runCli --serve) as a text adapter.
@coderabbitai

coderabbitai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Repository: TanStack/ai/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 4c76a1f1-9a29-4ca4-a5d2-cbfb4a98b81d

📥 Commits

Reviewing files that changed from the base of the PR and between c2e6fb3 and b68dd47.

📒 Files selected for processing (14)
  • .changeset/harness-p5-build.md
  • docs/config.json
  • docs/harness/deploy.md
  • packages/ai-harness/package.json
  • packages/ai-harness/src/build.ts
  • packages/ai-harness/src/harness-text.ts
  • packages/ai-harness/src/index.ts
  • packages/ai-harness/src/worker.ts
  • packages/ai-harness/tests/build-stub.test.ts
  • packages/ai-harness/tests/build.test.ts
  • packages/ai-harness/tests/remote-worker.test.ts
  • packages/ai-harness/vite.config.ts
  • testing/e2e/src/routes/api.harness-test.ts
  • testing/e2e/tests/harness.spec.ts
 _____________________________________________________________________
< No matter how far down the wrong road you have gone, turn back now. >
 ---------------------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 458f665

Command Status Duration Result
nx run-many --targets=build --exclude=examples/... ✅ Succeeded 3s View ↗

☁️ Nx Cloud last updated this comment at 2026-09-26 14:10:17 UTC

@pkg-pr-new

pkg-pr-new Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai@1521

@tanstack/ai-acp

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-acp@1521

@tanstack/ai-angular

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-angular@1521

@tanstack/ai-anthropic

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-anthropic@1521

@tanstack/ai-bedrock

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-bedrock@1521

@tanstack/ai-byteplus

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-byteplus@1521

@tanstack/ai-claude-code

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-claude-code@1521

@tanstack/ai-client

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-client@1521

@tanstack/ai-cloudflare

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-cloudflare@1521

@tanstack/ai-code-mode

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-code-mode@1521

@tanstack/ai-code-mode-snippets

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-code-mode-snippets@1521

@tanstack/ai-codex

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-codex@1521

@tanstack/ai-cohere

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-cohere@1521

@tanstack/ai-compaction

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-compaction@1521

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-devtools-core@1521

@tanstack/ai-durable-stream

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-durable-stream@1521

@tanstack/ai-elevenlabs

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-elevenlabs@1521

@tanstack/ai-event-client

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-event-client@1521

@tanstack/ai-fal

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-fal@1521

@tanstack/ai-gemini

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-gemini@1521

@tanstack/ai-grok

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-grok@1521

@tanstack/ai-grok-build

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-grok-build@1521

@tanstack/ai-groq

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-groq@1521

@tanstack/ai-harness

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-harness@1521

@tanstack/ai-harness-cli

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-harness-cli@1521

@tanstack/ai-isolate-cloudflare

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-isolate-cloudflare@1521

@tanstack/ai-isolate-daytona

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-isolate-daytona@1521

@tanstack/ai-isolate-node

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-isolate-node@1521

@tanstack/ai-isolate-quickjs

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-isolate-quickjs@1521

@tanstack/ai-isolate-quickjs-bun

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-isolate-quickjs-bun@1521

@tanstack/ai-llmgateway

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-llmgateway@1521

@tanstack/ai-lovable

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-lovable@1521

@tanstack/ai-mcp

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-mcp@1521

@tanstack/ai-memory

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-memory@1521

@tanstack/ai-mistral

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-mistral@1521

@tanstack/ai-octane

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-octane@1521

@tanstack/ai-ollama

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-ollama@1521

@tanstack/ai-openai

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-openai@1521

@tanstack/ai-opencode

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-opencode@1521

@tanstack/ai-openrouter

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-openrouter@1521

@tanstack/ai-perplexity

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-perplexity@1521

@tanstack/ai-persistence

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-persistence@1521

@tanstack/ai-preact

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-preact@1521

@tanstack/ai-react

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-react@1521

@tanstack/ai-react-ui

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-react-ui@1521

@tanstack/ai-reactor

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-reactor@1521

@tanstack/ai-remix

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-remix@1521

@tanstack/ai-sandbox

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-sandbox@1521

@tanstack/ai-sandbox-blaxel

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-sandbox-blaxel@1521

@tanstack/ai-sandbox-boxd

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-sandbox-boxd@1521

@tanstack/ai-sandbox-cloudflare

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-sandbox-cloudflare@1521

@tanstack/ai-sandbox-daytona

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-sandbox-daytona@1521

@tanstack/ai-sandbox-docker

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-sandbox-docker@1521

@tanstack/ai-sandbox-e2b

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-sandbox-e2b@1521

@tanstack/ai-sandbox-local-process

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-sandbox-local-process@1521

@tanstack/ai-sandbox-sprites

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-sandbox-sprites@1521

@tanstack/ai-sandbox-upstash-box

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-sandbox-upstash-box@1521

@tanstack/ai-sandbox-vercel

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-sandbox-vercel@1521

@tanstack/ai-skills

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-skills@1521

@tanstack/ai-solid

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-solid@1521

@tanstack/ai-solid-ui

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-solid-ui@1521

@tanstack/ai-svelte

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-svelte@1521

@tanstack/ai-typesafe

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-typesafe@1521

@tanstack/ai-utils

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-utils@1521

@tanstack/ai-vercel-gateway

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-vercel-gateway@1521

@tanstack/ai-vertex

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-vertex@1521

@tanstack/ai-vue

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-vue@1521

@tanstack/ai-vue-ui

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-vue-ui@1521

@tanstack/ai-worldlabs

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-worldlabs@1521

@tanstack/openai-base

npm i https://pkg.pr.new/TanStack/ai/@tanstack/openai-base@1521

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/TanStack/ai/@tanstack/preact-ai-devtools@1521

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/TanStack/ai/@tanstack/react-ai-devtools@1521

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/TanStack/ai/@tanstack/solid-ai-devtools@1521

@tanstack/svelte-ai-devtools

npm i https://pkg.pr.new/TanStack/ai/@tanstack/svelte-ai-devtools@1521

commit: b68dd47

@github-actions github-actions Bot added waiting-on: maintainer The ball is in the maintainers’ court and removed waiting-on: author Waiting for the author to respond or update labels Sep 26, 2026
@AlemTuzlak
AlemTuzlak added this pull request to stack #1536 September 28, 2026 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-on: maintainer The ball is in the maintainers’ court

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants