diff --git a/.github/workflows/release-sdk.yml b/.github/workflows/release-sdk.yml new file mode 100644 index 0000000..70d4cad --- /dev/null +++ b/.github/workflows/release-sdk.yml @@ -0,0 +1,143 @@ +name: Release SDK + +on: + push: + branches: [main] + paths: + - "sdk/**" + - ".github/workflows/release-sdk.yml" + workflow_dispatch: + + +permissions: {} + +concurrency: + group: release-sdk + cancel-in-progress: false + +jobs: + status: + name: Check for pending changesets + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + outputs: + pending: ${{ steps.check.outputs.pending }} + steps: + - name: Check out repository + uses: actions/checkout@v7 + with: + persist-credentials: false + + - name: Count changesets + id: check + run: | + count=$(find sdk/.changeset -maxdepth 1 -name '*.md' ! -name 'README.md' | wc -l | tr -d ' ') + echo "$count pending changeset(s)" + if [ "$count" -gt 0 ]; then + echo "pending=true" >> "$GITHUB_OUTPUT" + else + echo "pending=false" >> "$GITHUB_OUTPUT" + fi + + version: + name: Open release pull request + needs: status + if: needs.status.outputs.pending == 'true' + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: write # push the release branch + pull-requests: write # open or update the release pull request + steps: + - name: Check out repository + uses: actions/checkout@v7 + with: + persist-credentials: false + + - name: Set up pnpm + uses: pnpm/action-setup@v6 + with: + package_json_file: sdk/package.json + + - name: Set up Node + uses: actions/setup-node@v7 + with: + node-version: 24 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + working-directory: sdk + + - name: Apply changesets + run: pnpm changeset version + working-directory: sdk + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Open or update release pull request + uses: peter-evans/create-pull-request@v8 + with: + branch: changeset-release/main + add-paths: sdk + delete-branch: true + commit-message: "chore(sdk): version @hjyup/patchdock-sdk" + title: "chore(sdk): release @hjyup/patchdock-sdk" + body: | + Applies the pending changesets for `@hjyup/patchdock-sdk`. + + Merging this pull request publishes the new version to npm. Review + the version bump and `sdk/CHANGELOG.md` before merging; to hold the + release back, close this pull request and it will be recreated on + the next push to `main`. + + publish: + name: Publish to npm + needs: status + if: needs.status.outputs.pending == 'false' + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: write # push the release tag + id-token: write # npm trusted publishing + steps: + - name: Check out repository + uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - name: Set up pnpm + uses: pnpm/action-setup@v6 + with: + package_json_file: sdk/package.json + + - name: Set up Node + uses: actions/setup-node@v7 + with: + node-version: 24 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + working-directory: sdk + + - name: Test + run: pnpm test + working-directory: sdk + + - name: Build + run: pnpm run build + working-directory: sdk + + - name: Configure git identity + # changeset publish tags each released package, and annotated tags need an author. + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Publish + run: pnpm changeset publish + working-directory: sdk + + - name: Push release tags + run: git push origin --tags diff --git a/.patchdock/Dockerfile b/.patchdock/Dockerfile deleted file mode 100644 index d507d37..0000000 --- a/.patchdock/Dockerfile +++ /dev/null @@ -1,68 +0,0 @@ -# Patchdock agent runtime image. One container per pipeline stage. - -FROM node:22-bookworm-slim - -ARG TSX_VERSION=4.22.4 -ARG CODEX_VERSION=0.142.4 - -# ── System packages ─────────────────────────────────────────────────────────── -RUN apt-get update && apt-get install -y --no-install-recommends \ - ca-certificates \ - curl \ - git \ - make \ - ripgrep \ - && rm -rf /var/lib/apt/lists/* - -# ── Git configuration ───────────────────────────────────────────────────────── -# Mounts are owned by the host user, so git rejects them without safe.directory. -RUN git config --system --add safe.directory '*' \ - && git config --system core.pager cat - -# ── Codex configuration ─────────────────────────────────────────────────────── -# The scaffolded agents shell out to `codex exec`. Credentials are mounted by -# the host at run time. -RUN npm install -g "@openai/codex@${CODEX_VERSION}" - -# ── SDK runtime ─────────────────────────────────────────────────────────────── -# Agents are .ts files imported unbuilt, so tsx is required. -RUN npm install -g "tsx@${TSX_VERSION}" - -# The SDK comes from this directory's node_modules (`pnpm install` in -# .patchdock), not from source. /node_modules is where agents mounted at /agents -# resolve a bare "@patchdock/sdk". -COPY node_modules /node_modules - -# The host passes no command, so this line is the whole contract. -ENTRYPOINT ["tsx", "/node_modules/@patchdock/sdk/runtime/main.ts"] - -# ── Stream hygiene ──────────────────────────────────────────────────────────── -# No tty: stop git prompting, and keep ANSI out of the JSON logs. CI is -# deliberately not set — test suites read it as "this environment guarantees -# services", and a stage container guarantees none. -ENV GIT_TERMINAL_PROMPT=0 \ - NO_COLOR=1 - -# ══ PROJECT SCOPE — everything below this line is yours ═══════════════════════ -# Patchdock is a Go CLI plus a TypeScript SDK, so agents need both toolchains. - -# ── Go ──────────────────────────────────────────────────────────────────────── -# Pinned to the `go` directive in go.mod. GOTOOLCHAIN=local makes a version -# mismatch fail loudly instead of silently downloading another toolchain. -COPY --from=golang:1.26.3-bookworm /usr/local/go /usr/local/go -ENV PATH="/usr/local/go/bin:/root/go/bin:${PATH}" \ - GOTOOLCHAIN=local - -# gcc and libc6-dev are here for one reason: `go test -race` needs cgo. -RUN apt-get update && apt-get install -y --no-install-recommends \ - gcc \ - libc6-dev \ - && rm -rf /var/lib/apt/lists/* - -# ── TypeScript ──────────────────────────────────────────────────────────────── -# pnpm drives sdk/: typecheck, lint and vitest. Pinned to the packageManager -# field in sdk/package.json. -RUN corepack enable && corepack prepare pnpm@10.33.0 --activate - -# Injected verbatim into every agent prompt — keep it accurate. -ENV PATCHDOCK_TOOLCHAIN_SUMMARY="Debian Bookworm. Go 1.26.3 with gcc for -race, gofmt and go vet. Node.js 22 with pnpm 10.33.0 and tsx for TypeScript. Git, ripgrep (rg), make and curl. Repository dependencies are NOT prewarmed: run `go mod download` and, in sdk/, `pnpm install --frozen-lockfile` before building or testing. The docker tests in internal/docker need a daemon and cannot pass inside a stage container." diff --git a/.patchdock/config.yml b/.patchdock/config.yml deleted file mode 100644 index 56272a1..0000000 --- a/.patchdock/config.yml +++ /dev/null @@ -1,41 +0,0 @@ -# Generated by `dock init`. - -# Names the agent image built for this project, so subsequent runs reuse the -# same container instead of rebuilding. Lowercase letters and digits, separated -# by '.', '_' or '-'. -name_space: patchdock - -# Per-container limits. Each pipeline stage runs in its own container and is -# governed by these. -container: - # Wall-clock ceiling for a single container. When it elapses the container is - # killed and the stage fails. Accepts Go duration strings: "90s", "10m", "1h". - # Set to 0 for no wall-clock limit. - timeout: 10m - - # Maximum tokens a single container may spend. Set to 0 for no token limit. - token_budget: 100000 - -# How many times the executor may be re-run after the reviewer rejects, before -# the run gives up. 0 means a single attempt with no retry. Every retry is -# another full executor + reviewer round, so this multiplies what a run costs -retries: - max: 1 - -# Host files mounted read-only into every stage container, so the agent can -# authenticate. -credentials: - - host: ~/.codex/auth.json - target: /codex-auth/auth.json - env: - CODEX_HOME: /codex-auth - -# Which filepath drives each stage. -# -# Currently pointed at the mock agents in mock/, which sleep and return canned -# output instead of calling a model. Swap back to planner.ts / executor.ts / -# reviewer.ts to use Codex again. -stages: - planner: mock/planner.ts - executor: mock/executor.ts - reviewer: mock/reviewer.ts diff --git a/.patchdock/executor.ts b/.patchdock/executor.ts deleted file mode 100644 index ed5e205..0000000 --- a/.patchdock/executor.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { codex, defineExecutor } from "@patchdock/sdk"; - -export default defineExecutor({ - async run(ctx, input) { - return codex(ctx, input); - }, -}); diff --git a/.patchdock/mock/executor.ts b/.patchdock/mock/executor.ts deleted file mode 100644 index 1990abf..0000000 --- a/.patchdock/mock/executor.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { defineExecutor } from "@patchdock/sdk"; -import { writeFile } from "node:fs/promises"; -import { join } from "node:path"; -import { jitter, pace } from "./lib.ts"; - -const MIN_SECONDS = 45; -const MAX_SECONDS = 60; -const MARKER_FILE = "MOCK_RUN.md"; - -export default defineExecutor({ - async run(ctx, input) { - const workspace = ctx.paths.workspace; - if (workspace === undefined) { - throw new Error("executor stage started without a workspace mount"); - } - - const total = jitter(MIN_SECONDS, MAX_SECONDS); - - await pace(ctx, total * 0.6, [ - { source: "agent", event: "process_started" }, - { source: "agent", event: "session_started" }, - { - source: "agent", - event: "command_completed", - command: "git status --short", - }, - { - source: "agent", - event: "tool_call_completed", - server: "fs", - tool: "list_dir", - }, - ]); - - const rejection = input.reviews.at(-1); - const body = [ - "# Mock run", - "", - `- run: ${ctx.runId}`, - `- attempt: ${ctx.attempt} of ${ctx.maxAttempts}`, - `- plan: ${input.plan.summary}`, - `- written: ${new Date().toISOString()}`, - "", - rejection === undefined - ? "First attempt." - : `Retrying after review feedback: ${rejection.feedback ?? rejection.summary}`, - "", - "This file was written by the mock executor. No model was called.", - ].join("\n"); - - await writeFile(join(workspace, MARKER_FILE), `${body}\n`, "utf8"); - - ctx.log({ - source: "agent", - event: "file_change_completed", - changes: [{ path: MARKER_FILE }], - }); - - await pace(ctx, total * 0.4, [ - { - source: "agent", - event: "command_completed", - command: "git diff --stat", - }, - { source: "agent", event: "turn_completed" }, - ]); - - return { - status: "success", - notes: `Mock executor wrote ${MARKER_FILE} on attempt ${ctx.attempt}.`, - }; - }, -}); diff --git a/.patchdock/mock/lib.ts b/.patchdock/mock/lib.ts deleted file mode 100644 index 740d47c..0000000 --- a/.patchdock/mock/lib.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { StageContext, StageLogEvent } from "@patchdock/sdk"; - -export function jitter(minSeconds: number, maxSeconds: number): number { - return (minSeconds + Math.random() * (maxSeconds - minSeconds)) * 1000; -} - -export function sleep(ms: number): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -// Spreads steps evenly across totalMs so the live activity feed has something -// to render while the stage pretends to work. -export async function pace( - ctx: StageContext, - totalMs: number, - steps: StageLogEvent[], -): Promise { - const slice = totalMs / steps.length; - - for (const step of steps) { - ctx.log(step); - await sleep(slice); - } -} - -export function firstLine(text: string): string { - const line = text.split("\n").find((candidate) => candidate.trim() !== ""); - return line?.trim() ?? "untitled task"; -} diff --git a/.patchdock/mock/planner.ts b/.patchdock/mock/planner.ts deleted file mode 100644 index 7e2e539..0000000 --- a/.patchdock/mock/planner.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { definePlanner } from "@patchdock/sdk"; -import { firstLine, jitter, pace } from "./lib.ts"; - -const MIN_SECONDS = 15; -const MAX_SECONDS = 20; - -export default definePlanner({ - async run(ctx, input) { - const title = firstLine(input.task.description); - - await pace(ctx, jitter(MIN_SECONDS, MAX_SECONDS), [ - { source: "agent", event: "process_started" }, - { source: "agent", event: "session_started" }, - { - source: "agent", - event: "command_completed", - command: "rg -n 'TODO' .", - }, - { - source: "agent", - event: "tool_call_completed", - server: "fs", - tool: "read_file", - }, - { source: "agent", event: "turn_completed" }, - ]); - - return { - summary: `Mock plan: ${title}`, - body: [ - `Mock plan for run ${ctx.runId}.`, - "", - `Request: ${title}`, - "", - "Steps:", - "1. Write a marker file into the workspace.", - "2. Hand the diff to the reviewer.", - "", - "No model was called to produce this plan.", - ].join("\n"), - }; - }, -}); diff --git a/.patchdock/mock/reviewer.ts b/.patchdock/mock/reviewer.ts deleted file mode 100644 index 5506047..0000000 --- a/.patchdock/mock/reviewer.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { defineReviewer } from "@patchdock/sdk"; -import { jitter, pace } from "./lib.ts"; - -const MIN_SECONDS = 10; -const MAX_SECONDS = 15; -const REJECT_CHANCE = 0.25; - -export default defineReviewer({ - async run(ctx, input) { - const bytes = input.patch.length; - - if (input.patch.trim() === "") { - ctx.log({ - source: "agent", - event: "message", - level: "warn", - message: "reviewer received an empty patch", - }); - } - - await pace(ctx, jitter(MIN_SECONDS, MAX_SECONDS), [ - { source: "agent", event: "process_started" }, - { source: "agent", event: "session_started" }, - { - source: "agent", - event: "command_completed", - command: `git diff --stat # ${bytes} bytes`, - }, - { source: "agent", event: "turn_completed" }, - ]); - - if (Math.random() < REJECT_CHANCE) { - return { - decision: "reject", - summary: `Mock reviewer rejected attempt ${ctx.attempt}`, - feedback: [ - "Rejected by the mock reviewer on a coin flip, not on the diff.", - `Attempt ${ctx.attempt} of ${ctx.maxAttempts}, patch was ${bytes} bytes.`, - ].join(" "), - }; - } - - return { - decision: "accept", - summary: `Mock reviewer accepted attempt ${ctx.attempt} (${bytes}-byte patch)`, - }; - }, -}); diff --git a/.patchdock/package.json b/.patchdock/package.json deleted file mode 100644 index 638312d..0000000 --- a/.patchdock/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "patchdock-agents", - "version": "0.0.0", - "private": true, - "type": "module", - "description": "Agent definitions for this repository. `pnpm install` links @patchdock/sdk into node_modules, which serves two purposes: editors and tsc resolve the SDK while authoring, and the Dockerfile copies that same tree into the image instead of vendoring SDK source.", - "dependencies": { - "@patchdock/sdk": "file:../sdk" - }, - "devDependencies": { - "@types/node": "^25.9.3" - } -} diff --git a/.patchdock/planner.ts b/.patchdock/planner.ts deleted file mode 100644 index e52cce9..0000000 --- a/.patchdock/planner.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { codex, definePlanner } from "@patchdock/sdk"; - -export default definePlanner({ - async run(ctx, input) { - return codex(ctx, input); - }, -}); diff --git a/.patchdock/pnpm-lock.yaml b/.patchdock/pnpm-lock.yaml deleted file mode 100644 index c72bce5..0000000 --- a/.patchdock/pnpm-lock.yaml +++ /dev/null @@ -1,45 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@patchdock/sdk': - specifier: file:../sdk - version: file:../sdk - devDependencies: - '@types/node': - specifier: ^25.9.3 - version: 25.9.5 - -packages: - - '@patchdock/sdk@file:../sdk': - resolution: {directory: ../sdk, type: directory} - - '@types/node@25.9.5': - resolution: {integrity: sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg==} - - undici-types@7.24.6: - resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} - - zod@4.4.3: - resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} - -snapshots: - - '@patchdock/sdk@file:../sdk': - dependencies: - zod: 4.4.3 - - '@types/node@25.9.5': - dependencies: - undici-types: 7.24.6 - - undici-types@7.24.6: {} - - zod@4.4.3: {} diff --git a/.patchdock/reviewer.ts b/.patchdock/reviewer.ts deleted file mode 100644 index f19d58b..0000000 --- a/.patchdock/reviewer.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { codex, defineReviewer } from "@patchdock/sdk"; - -export default defineReviewer({ - async run(ctx, input) { - return codex(ctx, input); - }, -}); diff --git a/.patchdock/tsconfig.json b/.patchdock/tsconfig.json deleted file mode 100644 index a91da6a..0000000 --- a/.patchdock/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2022", - "module": "NodeNext", - "moduleResolution": "NodeNext", - "lib": ["ES2022"], - "types": ["node"], - "strict": true, - "noUncheckedIndexedAccess": true, - "noImplicitOverride": true, - "forceConsistentCasingInFileNames": true, - "verbatimModuleSyntax": true, - "allowImportingTsExtensions": true, - "skipLibCheck": true, - "noEmit": true - }, - "include": ["*.ts", "mock"] -} diff --git a/Makefile b/Makefile index f81e024..848a427 100644 --- a/Makefile +++ b/Makefile @@ -3,3 +3,10 @@ install: go install ./... @echo "patchdock has been installed" + +# Compile the SDK into sdk/dist, which is what the package publishes. +.PHONY: sdk +sdk: + pnpm --dir sdk install + pnpm --dir sdk run build + @echo "sdk built into sdk/dist" diff --git a/README.md b/README.md index 15980f6..8b59c2f 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,10 @@ commit on a `patchdock/…` branch in your repository, ready to review and merge ## Getting started > [!NOTE] -> Patchdock is not yet distributed through Homebrew or npm. Distribution will -> be added after critical work is complete, including Docker runtime -> hardening, cancellation support, and daemon lifecycle improvements. +> The `dock` binary is not yet distributed through Homebrew, and is installed +> from source for now. Distribution will be added after critical work is +> complete, including Docker runtime hardening, cancellation support, and +> daemon lifecycle improvements. Building Patchdock requires Go; running it requires a Docker Engine. Install the `dock` binary from source: @@ -43,15 +44,26 @@ definitions Patchdock uses during execution: .patchdock/ ├── config.yml ├── Dockerfile +├── package.json +├── .gitignore ├── planner.ts ├── executor.ts └── reviewer.ts ``` +Install the agent SDK. The Dockerfile copies this `node_modules` tree into the +agent image, so it has to exist before the first run: + +```bash +cd .patchdock +npm install +``` + Adapt the Dockerfile to your repository's toolchain, then open Patchdock and submit your first task: ```bash +cd .. dock ``` diff --git a/internal/cli/init.go b/internal/cli/init.go index 4f4b60d..0c085e3 100644 --- a/internal/cli/init.go +++ b/internal/cli/init.go @@ -15,8 +15,9 @@ var force bool var initCmd = &cobra.Command{ Use: "init", Short: "Scaffold .patchdock/ in a repository", - Long: `Writes .patchdock/ with a config, a Dockerfile and three working - agents, so "dock init" followed by "dock run" works as-is. + Long: `Writes .patchdock/ with a config, a Dockerfile, a package.json pinning the + agent SDK, and three working agents, so "dock init", "npm install" and + "dock run" work as-is. Refuses to touch an existing .patchdock/ unless --force is given.`, Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -32,7 +33,10 @@ var initCmd = &cobra.Command{ return err } - fmt.Fprintf(cmd.OutOrStdout(), "created %s\n", filepath.Join(repoDir, ".patchdock")) + dir := filepath.Join(repoDir, ".patchdock") + fmt.Fprintf(cmd.OutOrStdout(), "created %s\n\n", dir) + + fmt.Fprintf(cmd.OutOrStdout(), "next: install the agent SDK\n\n cd %s && npm install\n", dir) return nil }, } diff --git a/internal/scaffold/init.go b/internal/scaffold/init.go index 9e21d50..cb856d3 100644 --- a/internal/scaffold/init.go +++ b/internal/scaffold/init.go @@ -25,6 +25,8 @@ type fileSource struct { var scaffoldFiles = []fileSource{ {src: "templates/config.template.yml", dst: "config.yml"}, + {src: "templates/package.json.tmpl", dst: "package.json"}, + {src: "templates/gitignore.tmpl", dst: ".gitignore"}, {src: "templates/planner.ts.tmpl", dst: "planner.ts"}, {src: "templates/executor.ts.tmpl", dst: "executor.ts"}, {src: "templates/reviewer.ts.tmpl", dst: "reviewer.ts"}, diff --git a/internal/scaffold/templates/Dockerfile.tmpl b/internal/scaffold/templates/Dockerfile.tmpl index dbc6d45..7396210 100644 --- a/internal/scaffold/templates/Dockerfile.tmpl +++ b/internal/scaffold/templates/Dockerfile.tmpl @@ -25,16 +25,16 @@ RUN git config --system --add safe.directory '*' \ RUN npm install -g "@openai/codex@${CODEX_VERSION}" # ── SDK runtime ─────────────────────────────────────────────────────────────── -# Agents are .ts files imported unbuilt, so tsx is required. +# The agents mounted at /agents are .ts files imported unbuilt, so the harness +# process itself has to run under tsx. RUN npm install -g "tsx@${TSX_VERSION}" -# The SDK comes from this directory's node_modules (`pnpm install` in +# The SDK comes from this directory's node_modules (`npm install` in # .patchdock), not from source. /node_modules is where agents mounted at /agents # resolve a bare "@patchdock/sdk". COPY node_modules /node_modules -# The host passes no command, so this line is the whole contract. -ENTRYPOINT ["tsx", "/node_modules/@patchdock/sdk/runtime/main.ts"] +ENTRYPOINT ["tsx", "/node_modules/@patchdock/sdk/dist/runtime/main.js"] # ── Stream hygiene ──────────────────────────────────────────────────────────── # No tty: stop git prompting, and keep ANSI and spinners out of the JSON logs. diff --git a/internal/scaffold/templates/gitignore.tmpl b/internal/scaffold/templates/gitignore.tmpl new file mode 100644 index 0000000..238f298 --- /dev/null +++ b/internal/scaffold/templates/gitignore.tmpl @@ -0,0 +1,2 @@ +node_modules/ +logs/ diff --git a/internal/scaffold/templates/package.json.tmpl b/internal/scaffold/templates/package.json.tmpl new file mode 100644 index 0000000..7c1fa61 --- /dev/null +++ b/internal/scaffold/templates/package.json.tmpl @@ -0,0 +1,13 @@ +{ + "name": "patchdock-agents", + "version": "0.0.0", + "private": true, + "type": "module", + "description": "Agent definitions for this repository. `npm install` puts @patchdock/sdk in node_modules, which serves two purposes: editors resolve the SDK while authoring, and the Dockerfile copies that same tree into the agent image.", + "dependencies": { + "@patchdock/sdk": "alpha" + }, + "devDependencies": { + "@types/node": "^25.9.3" + } +} diff --git a/sdk/.changeset/README.md b/sdk/.changeset/README.md new file mode 100644 index 0000000..a8d33a8 --- /dev/null +++ b/sdk/.changeset/README.md @@ -0,0 +1,16 @@ +# Changesets + +This directory holds the pending release notes for `@hjyup/patchdock-sdk`. Every change +that should reach npm gets a changeset: a small markdown file recording the bump +type (`patch`, `minor`, `major`) and a line for the changelog. + +```bash +cd sdk +pnpm changeset # describe the change, then commit the generated file +``` + +Merging a changeset to `main` makes CI open a release pull request that applies +the bumps and rewrites `CHANGELOG.md`. Merging _that_ pull request publishes to +npm. + +Full docs: diff --git a/sdk/.changeset/config.json b/sdk/.changeset/config.json new file mode 100644 index 0000000..794ee79 --- /dev/null +++ b/sdk/.changeset/config.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@4.0.0/schema.json", + "changelog": ["@changesets/changelog-github", { "repo": "HJyup/patchdock" }], + "commit": false, + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/sdk/.changeset/pre.json b/sdk/.changeset/pre.json new file mode 100644 index 0000000..9a89b8a --- /dev/null +++ b/sdk/.changeset/pre.json @@ -0,0 +1,4 @@ +{ + "mode": "pre", + "tag": "alpha" +} diff --git a/sdk/.changeset/pre/first-alpha.md b/sdk/.changeset/pre/first-alpha.md new file mode 100644 index 0000000..0516bb3 --- /dev/null +++ b/sdk/.changeset/pre/first-alpha.md @@ -0,0 +1,7 @@ +--- +"@hjyup/patchdock-sdk": minor +--- + +First public alpha of the Patchdock agent SDK: stage definitions (`definePlanner`, +`defineExecutor`, `defineReviewer`), the Codex agent adapter, the shared prompt +set, the typed stage contracts, and the container runtime harness. diff --git a/sdk/.prettierignore b/sdk/.prettierignore index 327ad85..5a25203 100644 --- a/sdk/.prettierignore +++ b/sdk/.prettierignore @@ -3,3 +3,5 @@ package-lock.json pnpm-lock.yaml dist coverage + +CHANGELOG.md diff --git a/sdk/CHANGELOG.md b/sdk/CHANGELOG.md new file mode 100644 index 0000000..c4692d7 --- /dev/null +++ b/sdk/CHANGELOG.md @@ -0,0 +1,9 @@ +# @patchdock/sdk + +## 0.1.0-alpha.0 + +### Minor Changes + +- First public alpha of the Patchdock agent SDK: stage definitions (`definePlanner`, + `defineExecutor`, `defineReviewer`), the Codex agent adapter, the shared prompt + set, the typed stage contracts, and the container runtime harness. diff --git a/sdk/LICENSE b/sdk/LICENSE new file mode 100644 index 0000000..9656f4a --- /dev/null +++ b/sdk/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 danyilbutov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sdk/README.md b/sdk/README.md index 567e0de..53527a0 100644 --- a/sdk/README.md +++ b/sdk/README.md @@ -26,6 +26,9 @@ To add the SDK to an existing TypeScript project instead: pnpm add @patchdock/sdk ``` +The SDK is in alpha, so releases land on the `alpha` dist-tag and the API may +still change between versions. Pin an exact version if you need stability. + ## Define agents and their contracts Every agent file must default-export one of the three stage definitions: diff --git a/sdk/package.json b/sdk/package.json index 359ba4c..b435ef7 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -1,16 +1,49 @@ { "name": "@patchdock/sdk", - "version": "0.1.0", - "private": true, + "version": "0.1.0-alpha.0", "type": "module", "packageManager": "pnpm@10.33.0", "description": "Patchdock agent SDK: typed contracts, stage definitions, and the container runtime harness.", + "license": "MIT", + "homepage": "https://github.com/HJyup/patchdock/tree/main/sdk#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/HJyup/patchdock.git", + "directory": "sdk" + }, + "bugs": { + "url": "https://github.com/HJyup/patchdock/issues" + }, + "keywords": [ + "patchdock", + "agent", + "codex", + "code-review", + "sdk" + ], + "engines": { + "node": ">=22" + }, + "main": "./dist/src/index.js", + "types": "./dist/src/index.d.ts", "exports": { - ".": "./src/index.ts" + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + }, + "./runtime": "./dist/runtime/main.js", + "./package.json": "./package.json" + }, + "files": [ + "dist" + ], + "publishConfig": { + "access": "public" }, - "main": "./src/index.ts", - "types": "./src/index.ts", "scripts": { + "build": "tsc -p tsconfig.build.json", + "clean": "rm -rf dist", + "prepack": "pnpm run build", "typecheck": "tsc --noEmit", "lint": "eslint .", "format": "prettier --write .", @@ -22,6 +55,8 @@ "zod": "^4.4.3" }, "devDependencies": { + "@changesets/changelog-github": "^1.0.0", + "@changesets/cli": "^3.0.0", "@eslint/js": "^10.0.1", "@types/node": "^25.9.3", "eslint": "^10.4.1", diff --git a/sdk/pnpm-lock.yaml b/sdk/pnpm-lock.yaml index 8ba5076..b526114 100644 --- a/sdk/pnpm-lock.yaml +++ b/sdk/pnpm-lock.yaml @@ -12,6 +12,12 @@ importers: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@changesets/changelog-github': + specifier: ^1.0.0 + version: 1.0.0 + '@changesets/cli': + specifier: ^3.0.0 + version: 3.0.0 '@eslint/js': specifier: ^10.0.1 version: 10.0.1(eslint@10.4.1) @@ -38,10 +44,87 @@ importers: version: 8.61.0(eslint@10.4.1)(typescript@6.0.3) vitest: specifier: ^4.1.8 - version: 4.1.8(@types/node@25.9.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)) + version: 4.1.8(@types/node@25.9.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0)) packages: + '@changesets/apply-release-plan@8.0.0': + resolution: {integrity: sha512-kUd2pbf1w5/AYmBMb0Tt+rkIPCjFJdT0SZMrkOjJT/WV/QbtmvkyB5jkV0oaNPheavprZk+SfUiozUti7TIL2w==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/assemble-release-plan@7.0.0': + resolution: {integrity: sha512-oEW8BxdA604kGGtDSCiHr5w9Tv4UWe9I2k61IBNZzCOE1kbYaJj4v+lFQNgcEZFkUc2pV/+hASErGDvpJOZCTg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/changelog-git@1.0.0': + resolution: {integrity: sha512-3Dst2Ime2Op5nd4XmWJLPIgp11ZFqJqSkVug9izK6TDcIV4YlhPS4ECbEVR+eGI0bk0r1ItogD4j2Oli87bJrA==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/changelog-github@1.0.0': + resolution: {integrity: sha512-PNCSH5CGJrqOKxRjrMp2NLhceQv2QBs6HkjrLvYQqsEE2/ItN5R8GD/mskZZluoNWYvjPYFsY9T6swXfp5E0UA==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/cli@3.0.0': + resolution: {integrity: sha512-V7Gm+GP5OT3mJinMI2YcJD/JyO/a4WChnaMCCzTRhWHgu1zhtsyY7zCjP6n5W6zsgSjJKs+yPmvtREvE0F2g8A==} + engines: {node: ^22.11 || ^24 || >=26, npm: '>=10.9.0', pnpm: '>=10.0.0', yarn: '>=4.5.2'} + hasBin: true + + '@changesets/config@4.0.0': + resolution: {integrity: sha512-mw95/YrkOuhZZxfnVAA4bSXOFUi+KlhzOBTM8C4x777NhUU6HWIl9Z+K+nME+E4PVsv5NQVQwTfiHihAS1A/ow==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/errors@1.0.0': + resolution: {integrity: sha512-ElN/mEzn6zmETgjwf5MclCMa9ef59sAR0lfO8VSYIsiRvbC2FbLB/92EoYw10Sl0kGixxHFiJZUSv7dA+YpR8g==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/format@0.1.1': + resolution: {integrity: sha512-OBN/xfe+lcNWCv8P4Ogop9EOTi5QRKd1c2JJfZRBT9AT3AybzDYDfHeX4Y7j20Q4e16BPu3XvcdOe9sPZmTEig==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/get-dependents-graph@3.0.0': + resolution: {integrity: sha512-ji/t5wFA1zREKXRUePE6Qi+Qu2UgxCeSSGQrphezwvQZrp49B7sJ+8+wvM0tA7zPeSxYKCojDy3WWgrl+s+awg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/get-github-info@1.0.0': + resolution: {integrity: sha512-nf5zPSqEKW0eXiJ4ltbjyIQ/srUHfxbghkLCjKdOLI3LehKXhiqxXcpja39eGPaj6qqGx2lFCrLJ7VWYUf9H2w==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/git@4.0.0': + resolution: {integrity: sha512-uIEswpPUgzBBqrC0qg13byNaPorzhf05LE2T+gRizEKCXvMsJC6NPJp5iNDSV/gYj4Viqh09UiOF5E7XWeH5lQ==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/parse@1.0.0': + resolution: {integrity: sha512-P0iaMb9p9CRYZiTgAllEIF9AUMQHIy1G72tKlcIqJp61icZSsKQNiOPdxAMZG8m/DvZwt/oz5xEbTpike//dWg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/pre@3.0.0': + resolution: {integrity: sha512-Zm/6YliV/a2oeWTqHJf6KxLrQwgcK1i/BRDl2m0EKZvbnxV5fG9QRhwJJGshjsZTUTS6dkfURQ2K6aAvgNw/3Q==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/read@1.0.0': + resolution: {integrity: sha512-8TdE2PwG6yArPt5Ozej83Z6iHz1G8BDBKvIEKZ455MccR4K3GNbLR2XqjBxa+5yLFnEd3xAOPXYboBg1pt8stQ==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/should-skip-package@1.0.0': + resolution: {integrity: sha512-pwqoJmbONn1XgXmZXPEExgAaT+HdZLjALFTDgIm+PnS5KeO2nLtzA2/Q+4aMFY14kFMuXKG30MObhvDzWgzDgg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/types@7.0.0': + resolution: {integrity: sha512-c5GoiQyt3pxiXjrWSNoP8/GRf4kG+VnKzovx1OQM8dYYALlSwgedmkPmJ+ZqGxqwg9D3Bkj85Uo4KLd5BN3A0w==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/write@1.0.0': + resolution: {integrity: sha512-xCK3/4C7Z7muQB/wguE6HcbjtY9iOtaK9orZKE+7xi573cMGD8rLZz7qlo6IvK7s+SIUIKajzj1l+F1QuP97tw==} + engines: {node: ^22.11 || ^24 || >=26} + + '@clack/core@1.4.3': + resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} + engines: {node: '>= 20.12.0'} + + '@clack/prompts@1.7.0': + resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==} + engines: {node: '>= 20.12.0'} + '@emnapi/core@1.10.0': resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} @@ -269,6 +352,18 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@manypkg/find-root@3.1.0': + resolution: {integrity: sha512-BcSqCyKhBVZ5YkSzOiheMCV41kqAFptW6xGqYSTjkVTl9XQpr+pqHhwgGCOHQtjDCv7Is6EFyA14Sm5GVbVABA==} + engines: {node: '>=20.0.0'} + + '@manypkg/get-packages@3.1.0': + resolution: {integrity: sha512-0TbBVyvPrP7xGYBI/cP8UP+yl/z+HtbTttAD7FMAJgn/kXOTwh5/60TsqP9ZYY710forNfyV0N8P/IE/ujGZJg==} + engines: {node: '>=20.0.0'} + + '@manypkg/tools@2.1.2': + resolution: {integrity: sha512-6QEf6yqFbETdwGITKq57aYoPfX/3K8XFNwsAlx0C1M7o8cb79sv1M3w+tWuWvIcSbNqrLF7OD7YpZMVVz335hQ==} + engines: {node: '>=20.0.0'} + '@napi-rs/wasm-runtime@1.1.5': resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} peerDependencies: @@ -278,6 +373,10 @@ packages: '@oxc-project/types@0.133.0': resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} + '@pnpm/deps.graph-sequencer@1100.0.1': + resolution: {integrity: sha512-pOr5+q1fLYKwFN3LAJuGZEnfXDcQ73zqgDHMtGy+K+uIoUqyY+6MeDCWFwfu+4EFuq76I5EPFofoNAI+Bmmq4A==} + engines: {node: '>=22.13'} + '@rolldown/binding-android-arm64@1.0.3': resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -513,6 +612,10 @@ packages: resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} engines: {node: 18 || 20 || >=22} + cac@7.0.0: + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + engines: {node: '>=20.19.0'} + chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} @@ -524,6 +627,9 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + dataloader@2.2.3: + resolution: {integrity: sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==} + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -616,6 +722,15 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -649,6 +764,10 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + human-id@4.2.0: + resolution: {integrity: sha512-K3GbkIWqyvvlpfhBPlbEvD97TtqBpAYA4kt+cn2lD2x2HuohzZCibcA2nOlnJT6exqvJLggoB5nv2dNf192nEA==} + hasBin: true + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -657,6 +776,9 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -672,6 +794,9 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -681,9 +806,15 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + launch-editor@2.14.1: + resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -800,6 +931,9 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + package-manager-detector@1.8.0: + resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -853,9 +987,16 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shell-quote@1.10.0: + resolution: {integrity: sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -873,6 +1014,10 @@ packages: resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} engines: {node: '>=18'} + tinyexec@1.3.0: + resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==} + engines: {node: '>=18'} + tinyglobby@0.2.17: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} @@ -1015,6 +1160,11 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -1024,6 +1174,131 @@ packages: snapshots: + '@changesets/apply-release-plan@8.0.0': + dependencies: + '@changesets/config': 4.0.0 + '@changesets/format': 0.1.1 + '@changesets/git': 4.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + import-meta-resolve: 4.2.0 + jsonc-parser: 3.3.1 + semver: 7.8.4 + + '@changesets/assemble-release-plan@7.0.0': + dependencies: + '@changesets/errors': 1.0.0 + '@changesets/get-dependents-graph': 3.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + semver: 7.8.4 + + '@changesets/changelog-git@1.0.0': + dependencies: + '@changesets/types': 7.0.0 + + '@changesets/changelog-github@1.0.0': + dependencies: + '@changesets/get-github-info': 1.0.0 + '@changesets/types': 7.0.0 + + '@changesets/cli@3.0.0': + dependencies: + '@changesets/apply-release-plan': 8.0.0 + '@changesets/assemble-release-plan': 7.0.0 + '@changesets/changelog-git': 1.0.0 + '@changesets/config': 4.0.0 + '@changesets/errors': 1.0.0 + '@changesets/get-dependents-graph': 3.0.0 + '@changesets/git': 4.0.0 + '@changesets/pre': 3.0.0 + '@changesets/read': 1.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + '@changesets/write': 1.0.0 + '@clack/prompts': 1.7.0 + '@manypkg/get-packages': 3.1.0 + '@pnpm/deps.graph-sequencer': 1100.0.1 + cac: 7.0.0 + import-meta-resolve: 4.2.0 + launch-editor: 2.14.1 + package-manager-detector: 1.8.0 + semver: 7.8.4 + tinyexec: 1.3.0 + + '@changesets/config@4.0.0': + dependencies: + '@changesets/get-dependents-graph': 3.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + '@manypkg/get-packages': 3.1.0 + picomatch: 4.0.4 + + '@changesets/errors@1.0.0': {} + + '@changesets/format@0.1.1': + dependencies: + package-manager-detector: 1.8.0 + tinyexec: 1.3.0 + + '@changesets/get-dependents-graph@3.0.0': + dependencies: + '@changesets/types': 7.0.0 + semver: 7.8.4 + + '@changesets/get-github-info@1.0.0': + dependencies: + dataloader: 2.2.3 + + '@changesets/git@4.0.0': + dependencies: + '@changesets/errors': 1.0.0 + '@changesets/types': 7.0.0 + '@manypkg/get-packages': 3.1.0 + picomatch: 4.0.4 + tinyexec: 1.3.0 + + '@changesets/parse@1.0.0': + dependencies: + '@changesets/types': 7.0.0 + yaml: 2.9.0 + + '@changesets/pre@3.0.0': + dependencies: + '@changesets/errors': 1.0.0 + '@changesets/types': 7.0.0 + '@manypkg/get-packages': 3.1.0 + + '@changesets/read@1.0.0': + dependencies: + '@changesets/git': 4.0.0 + '@changesets/parse': 1.0.0 + '@changesets/types': 7.0.0 + + '@changesets/should-skip-package@1.0.0': + dependencies: + '@changesets/types': 7.0.0 + + '@changesets/types@7.0.0': {} + + '@changesets/write@1.0.0': + dependencies: + '@changesets/format': 0.1.1 + '@changesets/types': 7.0.0 + human-id: 4.2.0 + + '@clack/core@1.4.3': + dependencies: + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + + '@clack/prompts@1.7.0': + dependencies: + '@clack/core': 1.4.3 + fast-string-width: 3.0.2 + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + '@emnapi/core@1.10.0': dependencies: '@emnapi/wasi-threads': 1.2.1 @@ -1170,6 +1445,21 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.5': {} + '@manypkg/find-root@3.1.0': + dependencies: + '@manypkg/tools': 2.1.2 + + '@manypkg/get-packages@3.1.0': + dependencies: + '@manypkg/find-root': 3.1.0 + '@manypkg/tools': 2.1.2 + + '@manypkg/tools@2.1.2': + dependencies: + jju: 1.4.0 + tinyglobby: 0.2.17 + yaml: 2.9.0 + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: '@emnapi/core': 1.10.0 @@ -1179,6 +1469,8 @@ snapshots: '@oxc-project/types@0.133.0': {} + '@pnpm/deps.graph-sequencer@1100.0.1': {} + '@rolldown/binding-android-arm64@1.0.3': optional: true @@ -1354,13 +1646,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.8(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4))': + '@vitest/mocker@4.1.8(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.8 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4) + vite: 8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0) '@vitest/pretty-format@4.1.8': dependencies: @@ -1407,6 +1699,8 @@ snapshots: dependencies: balanced-match: 4.0.4 + cac@7.0.0: {} + chai@6.2.2: {} convert-source-map@2.0.0: {} @@ -1417,6 +1711,8 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + dataloader@2.2.3: {} + debug@4.4.3: dependencies: ms: 2.1.3 @@ -1538,6 +1834,16 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + + fast-wrap-ansi@0.2.2: + dependencies: + fast-string-width: 3.0.2 + fdir@6.5.0(picomatch@4.0.4): optionalDependencies: picomatch: 4.0.4 @@ -1565,10 +1871,14 @@ snapshots: dependencies: is-glob: 4.0.3 + human-id@4.2.0: {} + ignore@5.3.2: {} ignore@7.0.5: {} + import-meta-resolve@4.2.0: {} + imurmurhash@0.1.4: {} is-extglob@2.1.1: {} @@ -1579,16 +1889,25 @@ snapshots: isexe@2.0.0: {} + jju@1.4.0: {} + json-buffer@3.0.1: {} json-schema-traverse@0.4.1: {} json-stable-stringify-without-jsonify@1.0.1: {} + jsonc-parser@3.3.1: {} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 + launch-editor@2.14.1: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.10.0 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -1680,6 +1999,8 @@ snapshots: dependencies: p-limit: 3.1.0 + package-manager-detector@1.8.0: {} + path-exists@4.0.0: {} path-key@3.1.1: {} @@ -1731,8 +2052,12 @@ snapshots: shebang-regex@3.0.0: {} + shell-quote@1.10.0: {} + siginfo@2.0.0: {} + sisteransi@1.0.5: {} + source-map-js@1.2.1: {} stackback@0.0.2: {} @@ -1743,6 +2068,8 @@ snapshots: tinyexec@1.2.4: {} + tinyexec@1.3.0: {} + tinyglobby@0.2.17: dependencies: fdir: 6.5.0(picomatch@4.0.4) @@ -1786,7 +2113,7 @@ snapshots: dependencies: punycode: 2.3.1 - vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4): + vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -1798,11 +2125,12 @@ snapshots: esbuild: 0.28.1 fsevents: 2.3.3 tsx: 4.22.4 + yaml: 2.9.0 - vitest@4.1.8(@types/node@25.9.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)): + vitest@4.1.8(@types/node@25.9.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.8 - '@vitest/mocker': 4.1.8(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)) + '@vitest/mocker': 4.1.8(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.8 '@vitest/runner': 4.1.8 '@vitest/snapshot': 4.1.8 @@ -1819,7 +2147,7 @@ snapshots: tinyexec: 1.2.4 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4) + vite: 8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 25.9.3 @@ -1837,6 +2165,8 @@ snapshots: word-wrap@1.2.5: {} + yaml@2.9.0: {} + yocto-queue@0.1.0: {} zod@4.4.3: {} diff --git a/sdk/src/context.ts b/sdk/src/context.ts index 14c06c5..0cc1b07 100644 --- a/sdk/src/context.ts +++ b/sdk/src/context.ts @@ -11,10 +11,6 @@ export interface StageLogEvent { [field: string]: unknown; } -// Mount paths handed to the agent: -// Planner - repo -// Executor - workspace -// Reviewer - workspace (read only) interface MountPaths { repo?: string; workspace?: string; diff --git a/sdk/tsconfig.build.json b/sdk/tsconfig.build.json new file mode 100644 index 0000000..79371f2 --- /dev/null +++ b/sdk/tsconfig.build.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": false, + "rootDir": ".", + "outDir": "dist", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "rewriteRelativeImportExtensions": true + }, + "include": ["src", "runtime"], + "exclude": ["**/*.test.ts", "src/testing"] +}