diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8eca03b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,55 @@ +name: Release + +on: + push: + tags: ["v*"] + +permissions: + contents: write # create the GitHub Release + id-token: write # npm provenance (public repo) + +jobs: + npm: + name: Publish to npm + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Setup Node (npm publish + provenance) + uses: actions/setup-node@v4 + with: + node-version: 22 + registry-url: "https://registry.npmjs.org" + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Build web UI + run: cd web && bun install --frozen-lockfile && bun run build + + - name: Test + run: bun run test + + - name: Verify package version matches the tag + run: | + PKG="$(node -p "require('./package.json').version")" + TAG="${GITHUB_REF_NAME#v}" + if [ "$PKG" != "$TAG" ]; then + echo "::error::package.json version ($PKG) does not match tag ($TAG)" + exit 1 + fi + + - name: Publish to npm + run: npm publish --provenance --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7512a7a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,30 @@ +# Changelog + +All notable changes to **codeoid** are documented here. The format follows +[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project adheres +to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.1.0] - 2026-06-23 + +Initial public release. + +### Added + +- Identity-first daemon (Bun) that owns every session; stateless clients attach + over a versioned WebSocket protocol (`PROTOCOL_VERSION`). +- Cross-session **verbatim memory** — SQLite + FTS5 + vectors, exposed to Claude + as an in-process MCP server (`recall`, `recall_file`, `timeline`), workspace-scoped + on `git-common-dir` so worktrees share one memory. +- Frontends: built-in Ink TUI, SolidJS web UI (served at `/ui`), Telegram bot. + The recommended native Rust TUI lives in + [codeoid-ui](https://github.com/saucam/codeoid-ui). +- Execution modes (`guarded` / `interactive` / `autonomous` with a write-action + budget), mid-turn streaming input, backing-session auto-rotation, declarative + CLI-output compression, and device handoff with scrollback replay. +- ZeroID identity per session plus attenuated sub-agent tokens; every tool call + is stamped with the acting agent's SPIFFE identity. + +[Unreleased]: https://github.com/saucam/codeoid/compare/v0.1.0...HEAD +[0.1.0]: https://github.com/saucam/codeoid/releases/tag/v0.1.0 diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..43d36ac --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,47 @@ +# Releasing codeoid + +Releases are automated. Pushing a `vX.Y.Z` tag publishes `codeoid` to npm with +[provenance](https://docs.npmjs.com/generating-provenance-statements) and opens a +GitHub Release — see [`.github/workflows/release.yml`](.github/workflows/release.yml). + +## One-time setup + +Add an **`NPM_TOKEN`** repository secret (Settings → Secrets and variables → +Actions → New repository secret): + +1. On npmjs.com → **Access Tokens** → create a **Granular** (or Automation) token + with publish rights for the `codeoid` package. +2. Save it as `NPM_TOKEN`. + +## Cutting a release + +1. Bump `version` in [`package.json`](package.json) (SemVer). +2. Move the `## [Unreleased]` notes into a new `## [X.Y.Z]` section in + [`CHANGELOG.md`](CHANGELOG.md). +3. Open a PR, get CI green, merge to `main`. +4. Tag from `main` and push (tags are not branch-protected): + + ```bash + git checkout main && git pull + git tag vX.Y.Z + git push origin vX.Y.Z + ``` + +The workflow then builds the web UI, runs the test suite, verifies the tag matches +`package.json`, `npm publish`es, and creates the GitHub Release. Install with: + +```bash +bun install -g codeoid # or: bunx codeoid +``` + +## Notes + +- **codeoid runs under [Bun](https://bun.sh).** The published package ships `src/` + plus the prebuilt `web/dist`, and points `bin` at `src/cli.ts` (Bun executes + TypeScript directly — no bundling step, and the web UI path resolves inside the + package). +- The **wire protocol** is versioned independently via `PROTOCOL_VERSION` in + [`src/protocol/types.ts`](src/protocol/types.ts). Bump it only on wire-breaking + changes, and keep it in lockstep with the `codeoid-protocol` crate in + [codeoid-ui](https://github.com/saucam/codeoid-ui). App versions and the protocol + version move independently; the handshake negotiates compatibility. diff --git a/package.json b/package.json index b6ecf9f..192849d 100644 --- a/package.json +++ b/package.json @@ -1,20 +1,56 @@ { "name": "codeoid", "version": "0.1.0", - "description": "Identity-first remote control plane for AI coding agents", + "description": "Identity-first control plane for AI coding agents — multi-session, multi-frontend, with cross-session memory", "type": "module", "bin": { - "codeoid": "./dist/cli.js" + "codeoid": "./src/cli.ts" }, + "files": [ + "src", + "!src/tests", + "!src/**/*.test.ts", + "web/dist", + "!web/dist/**/*.map", + "README.md", + "LICENSE", + "CONTRIBUTING.md", + "SECURITY.md", + "docs/architecture.png" + ], + "engines": { + "bun": ">=1.0.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/saucam/codeoid.git" + }, + "homepage": "https://github.com/saucam/codeoid#readme", + "bugs": { + "url": "https://github.com/saucam/codeoid/issues" + }, + "keywords": [ + "claude", + "claude-code", + "ai-agents", + "coding-agent", + "agent-identity", + "zeroid", + "tui", + "bun", + "mcp" + ], "scripts": { "build": "bun build src/cli.ts --outdir dist --target bun --sourcemap", + "build:web": "cd web && bun install --frozen-lockfile && bun run build", "dev": "bun --watch src/cli.ts", "lint": "biome check src/", "lint:fix": "biome check --write src/", "format": "biome format --write src/", "test": "bun test src/tests src/daemon", "test:web": "cd web && bun run test", - "typecheck": "bun x tsc --noEmit" + "typecheck": "bun x tsc --noEmit", + "prepublishOnly": "bun run build:web" }, "dependencies": { "@anthropic-ai/claude-agent-sdk": "^0.3.175", diff --git a/web/.npmignore b/web/.npmignore new file mode 100644 index 0000000..3f3b774 --- /dev/null +++ b/web/.npmignore @@ -0,0 +1,3 @@ +# Intentionally minimal. Its presence makes npm ignore web/.gitignore (which +# excludes dist/) when packing the parent "codeoid" package, so the prebuilt +# web/dist — referenced by the "files" allowlist in ../package.json — ships.