Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 6 additions & 4 deletions .github/actions/setup-bun/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,14 @@ runs:
# node-gyp@latest (invoked via bunx for native install scripts) requires Node >=22;
# some runner images ship an older system Node on PATH
- name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "24"
uses: ./.github/actions/setup-node

- name: Get baseline download URL
id: bun-url
shell: bash
run: |
if [ "$RUNNER_ARCH" = "X64" ]; then
V=$(node -p "require('./package.json').packageManager.split('@')[1]")
V=$(node script/toolchain.mjs get bun)
case "$RUNNER_OS" in
macOS) OS=darwin ;;
Linux) OS=linux ;;
Expand All @@ -39,6 +37,10 @@ runs:
bun-version-file: ${{ !steps.bun-url.outputs.url && 'package.json' || '' }}
bun-download-url: ${{ steps.bun-url.outputs.url }}

- name: Verify toolchain
shell: bash
run: node script/toolchain.mjs check

- name: Get cache directory
id: cache
shell: bash
Expand Down
9 changes: 9 additions & 0 deletions .github/actions/setup-node/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: Setup Node
description: Install the exact repository Node version
runs:
using: composite
steps:
- name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: .node-version
60 changes: 60 additions & 0 deletions .github/releases/v1.0.60.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
## opencode {VERSION}

{Prerelease/Stable} release from `{branch}` branch. Adds durable DAG parent-node communication and delivers audited runtime, authorization, and toolchain repairs.

---

### 🎯 Features

- **DAG agent communication**: The main conversation can observe its nodes and exchange messages with them. Nodes can ask questions or report progress before final output. Messages retain exact attempt identity and survive restart; queue acceptance and model-input delivery remain distinct.
- **Model-led orchestration**: Runtime guidance describes optional DAG capabilities without AHE routing rules. The model chooses its strategy while the host enforces permissions, lifecycle, schema, review evidence, and budget contracts.
- **Capability descriptions**: Core and legacy requests share truthful descriptions of Hooks, DAG, Project Memory, reasoning distillation, and available extension mechanisms.

---

### 🐛 Bug Fixes

- **DAG settlement and recovery**: Fence stale results against newly accepted input, persist bounded result nudges, release capture and fiber ownership after failures, and retain valid null outputs. Replanning rejects dangling dependencies atomically.
- **Structured output responsiveness**: Run schema validation in a cancellable worker thread with a 250 ms deadline, retaining JavaScript regex behavior and fencing old results after registry re-registration. Package the worker for compiled CLI, Node and Electron backends.
- **Session and lease races**: Make mailbox wake admission durable, preserve preparation failures, and repair Memory migration, Goal registration, automation lease, event deduplication, watcher cleanup, and provider stream cancellation races.
- **Authorization and content handling**: Repair audited share identity and revocation, Markdown sanitization, repository-scoped GitHub token issuance, billing ownership and idempotency, Feishu verification, and installer temporary-file handling.

---

### ⚙️ CI / Engineering

- Use central exact runtime versions in local validation, CI, builds, and containers. Discover actual workspace test scripts and retain the pruned stats dependency lock during image installation.
- Use a shared desktop build entrypoint with an exact-version check and a build-only 4 GiB Node heap budget; retain runtime flags and source maps. Invoke the detected absolute macOS signing binary during native builds. Refresh Nix inputs and native dependency measurement. Four native platform jobs verify exact runtimes and both CLI and desktop derivations using reviewed official sources.

---

### 📦 Dependencies / Tooling

- Review and update compatible dependencies, consolidate workspace catalog pins and locks, verify registry integrity, and preserve matched Effect, Drizzle, and native package families.
- Pin Bun 1.4.2, Node 24.21.0, Go 1.27.1, and auxiliary Rust 1.98.1. Document the vendor-owned Electron embedded Node and VS Code extension-host compatibility boundaries.

---

### 🧪 Test Summary

```text
Combined local DAG gate: 1062 passed, 1 skipped; all existing coverage floors passed
Prepared-parent waiting-node regression and affected prompt phase: 14 passed
HTTP contract exerciser: 708 passed, 0 skipped, 0 missing
Configured Qwen / GLM / DeepSeek communication: 3 passed in isolated source-runtime sessions
Workspace typecheck: 31 tasks passed; lint stayed under the unchanged warning cap
Clean docs dependency proof: baseline and corrected peer graph built all 649 HTML routes
Delivery gates: current-head native CI, Linux/Windows E2E, and four native Nix builds
```

---

### 🔍 Verification

The DAG feature received multiple Astra review rounds and deterministic regressions for reproduced race conditions, including a node waiting for its parent answer and capture authority across scheduler and database-connection waits. Isolated calls to configured Qwen, GLM, and DeepSeek providers verified source-runtime communication and capability behavior. Those calls do not represent acceptance of an installed binary. The combined delivery requires current-head CI and native Nix build evidence before merge, followed by review of the merged main tree before publication.

The source audit is bounded and does not claim exhaustive dependency or line coverage. The worker isolates schema computation with a deadline. Data cloning remains synchronous and timers depend on host scheduling; other host work and remaining historical validation topics are outside that guarantee. Cached CDN objects, distributed orphan cleanup, and existing partial-refund policy are not described as resolved. Feishu deployments must provide FEISHU_VERIFICATION_TOKEN; this release does not change deployment credentials.

---

**Full changelog:** [`{previous_tag}`...`{current_tag}`](https://github.com/LeXwDeX/OpenCode-GraphAgent/compare/{previous_tag}...{current_tag})
33 changes: 20 additions & 13 deletions .github/workflows/ci-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ permissions:

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
GOTOOLCHAIN: local

jobs:
unit-tests:
Expand Down Expand Up @@ -74,6 +75,9 @@ jobs:
with:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Setup Node
uses: ./.github/actions/setup-node

- name: Setup GitHub CLI
uses: ./.github/actions/setup-gh

Expand All @@ -85,12 +89,6 @@ jobs:
job-name: Unit Tests (${{ matrix.settings.name }})
runner-label: ${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.user.login != 'dependabot[bot]' && github.actor != 'dependabot[bot]')) && join(matrix.settings.selfHosted, ',') || matrix.settings.host }}

- name: Setup Node
if: steps.evidence.outputs.reused != 'true'
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "24"

- name: Setup Go
if: steps.evidence.outputs.reused != 'true' && (runner.os == 'Linux')
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
Expand All @@ -107,6 +105,10 @@ jobs:
# only restores, to avoid racing on the same {OS}-bun-{hash} key.
save-cache: false

- name: Verify Go toolchain
if: steps.evidence.outputs.reused != 'true' && runner.os == 'Linux'
run: node script/toolchain.mjs check --go

- name: Configure Git Identity
if: steps.evidence.outputs.reused != 'true'
run: |
Expand Down Expand Up @@ -230,6 +232,10 @@ jobs:
with:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Setup Node
# Browser installation below checks extraction on the shared Node pin.
uses: ./.github/actions/setup-node

- name: Setup GitHub CLI
uses: ./.github/actions/setup-gh

Expand All @@ -241,13 +247,6 @@ jobs:
job-name: E2E Tests (${{ matrix.settings.name }})
runner-label: ${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.event.pull_request.user.login != 'dependabot[bot]' && github.actor != 'dependabot[bot]')) && join(matrix.settings.selfHosted, ',') || matrix.settings.host }}

- name: Setup Node
if: steps.evidence.outputs.reused != 'true'
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
# Playwright 1.59 hangs while extracting Chromium with Node 24.16.
node-version: "24.15"

- name: Setup Bun
if: steps.evidence.outputs.reused != 'true'
uses: ./.github/actions/setup-bun
Expand Down Expand Up @@ -303,6 +302,14 @@ jobs:
run: bun test --timeout 30000 --only-failures test/dag/dag-output-ref.test.ts test/dag/dag-output-ref-result.test.ts test/dag/dag-input-mapping-runtime.test.ts test/dag/dag-artifact-permissions.test.ts
timeout-minutes: 5

- name: Verify shared Markdown in Chromium
if: steps.evidence.outputs.reused != 'true'
working-directory: packages/web
run: bun test test/sanitize-markdown.test.ts --timeout 30000 --only-failures
env:
OPENCODE_TEST_BROWSER: "1"
timeout-minutes: 3

- name: Run app e2e tests
if: steps.evidence.outputs.reused != 'true'
run: bun --cwd packages/app test:e2e:local
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/ci-typecheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ jobs:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

- name: Setup Node
uses: ./.github/actions/setup-node

- name: Setup GitHub CLI
uses: ./.github/actions/setup-gh

Expand All @@ -60,7 +63,7 @@ jobs:
uses: ./.github/actions/setup-bun

- name: Test CI verification fingerprint
run: node --test script/ci-fingerprint.test.mjs script/ci-evidence.test.mjs script/ci-runner-routing.test.mjs script/ci-runner-smoke.test.mjs
run: node --test script/ci-fingerprint.test.mjs script/ci-evidence.test.mjs script/ci-runner-routing.test.mjs script/ci-runner-smoke.test.mjs script/toolchain.test.mjs

- name: Test GitHub CLI bootstrap
run: bash script/setup-gh.test.sh
Expand Down
71 changes: 71 additions & 0 deletions .github/workflows/nix-verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Nix verification

on:
pull_request:
paths:
- flake.nix
- flake.lock
- nix/**
- package.json
- bun.lock
- .node-version
- config_assistant/go.mod
- packages/desktop/package.json
- .github/workflows/nix-verify.yml
workflow_dispatch:
inputs:
regenerate_hashes:
description: Measure and apply native hashes before building; return artifacts for review
type: boolean
default: false

permissions:
contents: read

concurrency:
group: nix-verify-${{ github.ref }}
cancel-in-progress: true

jobs:
native-build:
name: Nix (${{ matrix.system }})
strategy:
fail-fast: false
matrix:
include:
- system: x86_64-linux
runner: ubuntu-24.04
- system: aarch64-linux
runner: ubuntu-24.04-arm
- system: aarch64-darwin
runner: macos-15
- system: x86_64-darwin
runner: macos-15-intel
runs-on: ${{ matrix.runner }}
timeout-minutes: 90
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
persist-credentials: false
- uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1
with:
install_url: https://releases.nixos.org/nix/nix-2.35.0/install
extra_nix_config: |
experimental-features = nix-command flakes
- name: Verify native toolchain, dependency hash and both packages
shell: bash
env:
NIX_SYSTEM: ${{ matrix.system }}
REGENERATE_HASHES: ${{ inputs.regenerate_hashes || false }}
run: |
python3 nix/scripts/test_verify_build.py
args=(--system "$NIX_SYSTEM")
if [[ "$REGENERATE_HASHES" == true ]]; then args+=(--apply); fi
python3 nix/scripts/verify_build.py "${args[@]}"
- name: Preserve measured hashes and native build evidence
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: nix-${{ matrix.system }}-${{ github.sha }}
path: nix-evidence/
if-no-files-found: error
2 changes: 1 addition & 1 deletion .github/workflows/release-fork.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ permissions:
contents: read

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: false
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

concurrency:
group: release-fork
Expand Down
18 changes: 1 addition & 17 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -1,20 +1,4 @@
#!/bin/sh
set -e
# Check if bun version matches package.json
# keep in sync with packages/script/src/index.ts semver qualifier
bun -e '
import { semver } from "bun";
const pkg = await Bun.file("package.json").json();
const expectedBunVersion = pkg.packageManager?.split("@")[1];
if (!expectedBunVersion) {
throw new Error("packageManager field not found in root package.json");
}
const expectedBunVersionRange = `^${expectedBunVersion}`;
if (!semver.satisfies(process.versions.bun, expectedBunVersionRange)) {
throw new Error(`This script requires bun@${expectedBunVersionRange}, but you are using bun@${process.versions.bun}`);
}
if (process.versions.bun !== expectedBunVersion) {
console.warn(`Warning: Bun version ${process.versions.bun} differs from expected ${expectedBunVersion}`);
}
'
node script/toolchain.mjs check --go
sh .husky/run-typecheck
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24.21.0
6 changes: 0 additions & 6 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,5 @@
// Warn when spreading non-plain objects (Headers, class instances, etc.)
"typescript/no-misused-spread": "warn"
},
"options": {
"typeAware": true
},
"options": {
"typeAware": true
},
"ignorePatterns": ["**/node_modules", "**/dist", "**/.build", "**/.sst", "**/*.d.ts", "**/sdk.gen.ts"]
}
16 changes: 15 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ Guidance for coding agents in this repository (GraphAgent — an opencode fork w
## Scope and layout

- GraphAgent v1 is in focused maintenance: DAG configuration, curated workflow templates, and reproducible defect fixes. No new platform features, no foundational refactors.
- Bun workspace + Turbo. Bun is pinned via `packageManager` in `package.json`; `.husky/pre-push` fails pushes from mismatched Bun majors.
- Bun workspace + Turbo. Runtime pins have one source each: Bun in `package.json` (`packageManager`), Node in `.node-version`, Go in `config_assistant/go.mod`. `bun run toolchain:check` and `.husky/pre-push` reject any differing runtime patch; CI and container builds read the same pins. Electron owns its embedded Node runtime; VSCode extension host types retain their own compatibility major.
- `packages/core`: DAG engine primitives (`src/dag/` — store/projector/sql, exported as `./dag/core/*` and `./dag/*`) plus DB schema/migrations ownership.
- `packages/opencode`: agent runtime. Services compose in `AppLayer` (`src/effect/app-runtime.ts`). Effect v4 (beta) rules, `makeRuntime`/`InstanceState`, tool-schema, and module-shape contracts are owned by `packages/opencode/AGENTS.md` (pattern reference: `packages/opencode/specs/effect/migration.md`).
- Curated workflow YAML, composable blocks, and worker prompts live in the `LeXwDeX/opencode-dag-config` repo; builtin templates are compiled into release binaries from a snapshot injected via `DAG_TEMPLATES_DIR` (`packages/opencode/script/generate.ts`). Config-only changes belong there, not in this runtime repo.

## Commands (from repo root unless noted)

- Install: `bun install`. Installs are exact-pinned; newly resolved releases must be ≥3 days old unless excluded (root `bunfig.toml`).
- Toolchain: `bun run toolchain:check` checks installed Bun, Node and Go before validation; build scripts check Bun and Node. Go CI sets `GOTOOLCHAIN=local` to prevent automatic toolchain substitution. Auxiliary Rust containers read `packages/containers/rust-toolchain.toml` and verify the installed compiler against it.
- Nix: shared runtime assertions reject stale nixpkgs packages; the current April 2026 input and `nix/hashes.json` still require regeneration and real builds on a Nix host. See `nix/README.md`; local validation without Nix does not certify those hashes.
- Dev: `bun run dev` (opencode CLI — starts the interactive TUI; use the tmux pattern from `packages/opencode/AGENTS.md`, never a blocking foreground run), `bun run dev:web`, `bun run dev:desktop`.
- Typecheck: `bun run typecheck` (turbo → per-package `tsgo --noEmit`). Use package scripts, never raw `tsc`. `bun run build` bundles without typechecking — a green build is not type soundness.
- Lint: `bun run lint` = `oxlint` with a `--max-warnings` ratchet. The ratchet only tightens: fix warnings, never raise the cap (contract: `_lint_ratchet_note` in `package.json` and the `.oxlintrc.json` header).
Expand Down Expand Up @@ -69,6 +71,7 @@ Repository-specific mapping; shared pre-push verification requirements live in t
- Issues/PRDs: GitHub Issues via `gh` — `docs/agents/issue-tracker.md`. Triage labels: `needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix` — `docs/agents/triage-labels.md`.

<!-- specgit:v2:start -->

## SpecGit 2

Runtime: 2.3.0. Declaration: `.specgit.yaml` (v2).
Expand All @@ -81,3 +84,14 @@ Completion requires native readback of the intended target merge and closure of

Declared rules: `{"agent":{"close_issues_after_merge":false,"native_auto_merge":false},"issue_template":"builtin","language":"en","pr_template":"builtin","validation":{"bodies":true,"labels":"off","titles":true}}`
<!-- specgit:v2:end -->

<!-- BEGIN:turborepo-agent-rules -->

# This is NOT the Turborepo you know

Turborepo configuration, task behavior, and CLI commands can vary between installed versions and may differ from your training data. Resolve the `turbo` package from this file's directory or relevant workspace; in monorepos, it may not be visible from the repository root. For example, run `node -p "require.resolve('turbo/package.json')"` from a workspace that depends on `turbo`.

Read `docs/README.md` inside that installed package first, then read the relevant pages from its `docs/` directory before changing Turborepo configuration or commands. Heed deprecation notices. These bundled docs match the installed package version and are available without network access.

This block is written and re-added by `turbo` before repository-scoped commands when an AI agent is detected. In the Turborepo source repository, its template is defined in `crates/turborepo-cli/src/cli/agent_guidance.rs`. Removing the managed block while updates are enabled means a later qualifying invocation will add it again. Set `"agentGuidance": false` in the root `turbo.json` or `turbo.jsonc` to opt out; this does not remove an existing block. Keep the block committed with your work to avoid an uncommitted change on the next agent invocation.
<!-- END:turborepo-agent-rules -->
Loading
Loading