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
61 changes: 61 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Release

on:
push:
tags:
- "v*.*.*"

permissions:
contents: write
id-token: write

concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false

env:
BUN_VERSION: 1.3.4

jobs:
release:
name: Publish exact artifact
if: github.repository == 'Mark1708/opencode-agents-sidebar'
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: ${{ env.BUN_VERSION }}
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 24
- name: Validate tag
run: test "$GITHUB_REF_NAME" = "v$(node -p "require('./package.json').version")"
- run: bun install --frozen-lockfile
- run: bun run typecheck
- run: bun test
- run: bun run build:all
- run: bun run verify:package
- name: Record artifact digest
run: sha256sum .artifacts/package.tgz | tee .artifacts/package.tgz.sha256
- name: Publish to npm with provenance
run: |
package=$(node -p "require('./package.json').name")
version=$(node -p "require('./package.json').version")
local_sha1=$(sha1sum .artifacts/package.tgz | cut -d' ' -f1)
registry_sha1=$(npm view "$package@$version" dist.shasum 2>/dev/null || true)
if [ -n "$registry_sha1" ]; then
test "$registry_sha1" = "$local_sha1"
echo "$package@$version already matches the verified artifact"
else
npm publish .artifacts/package.tgz --access public --provenance
fi
- name: Create GitHub release
env:
GH_TOKEN: ${{ github.token }}
run: |
if gh release view "$GITHUB_REF_NAME" >/dev/null 2>&1; then
gh release upload "$GITHUB_REF_NAME" .artifacts/package.tgz .artifacts/package.tgz.sha256 --clobber
else
gh release create "$GITHUB_REF_NAME" .artifacts/package.tgz .artifacts/package.tgz.sha256 --verify-tag --generate-notes --title "$GITHUB_REF_NAME"
fi
8 changes: 1 addition & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
node_modules/
tui.js
index.js
*.d.ts
*.d.ts.map
*.js.map
dist/
.artifacts/
.DS_Store
*.log
bun.lockb
src/tui.ts
.env
.env.*
*.pem
Expand Down
49 changes: 0 additions & 49 deletions .gitlab-ci.yml

This file was deleted.

87 changes: 49 additions & 38 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,65 @@
# AGENTS SIDEBAR PLUGIN

**Version:** 1.0.7 | **npm:** `opencode-agents-sidebar` | **Plugin ID:** `agents-sidebar:tui`
**Version:** 2.0.0 | **npm:** `opencode-agents-sidebar` | **Plugin IDs:** `agents-sidebar`, `agents-sidebar.tui`

## OVERVIEW

Displays OhMyOpenAgent agent lifecycle categories, collapsible sections, model info, and team status in sidebar. Reads agent config from `oh-my-openagent.json`.
OpenCode V2-only sidebar for OhMyOpenAgent lifecycle categories, collapsible groups, selection, model details, and config diagnostics. Current discovery reads only `oh-my-openagent.json`; the provider seam permits a future native OpenCode source but does not imply universal discovery.

## STRUCTURE

```text
src/
├── index.ts # V2 server entry (`@opencode/plugin`)
├── tui.ts # V2 setup, signals, reload ownership, teardown
├── render.ts # sole OpenTUI/Solid boundary and tracked mount
├── runtime.ts # runtime state and serialized reload controller
├── config-watcher.ts # directory watches with polling recovery
├── providers/ # agent provider seam and OMO source
├── agents.ts # categorization and group construction
├── config.ts # sidebar config parsing
├── defaults.ts # immutable defaults
├── format.ts # single-line render formatting
└── types.ts # domain and render types
scripts/verify-package.mjs
.github/workflows/
├── ci.yml # Required PR/push checks and package artifact
└── release.yml # Tag validation, npm OIDC publish, GitHub Release
```
agents-sidebar/
├── src/
│ ├── index.ts # Plugin API stub (definePlugin)
│ ├── tui.ts # Re-exports from all modules + render.ts default
│ ├── render.ts # TUI entry -- element/render/poll loop (uses @opentui/solid)
│ ├── agents.ts # Agent discovery, category mapping, group building
│ ├── config.ts # Reads ~/.config/opencode/oh-my-openagent.json
│ ├── defaults.ts # DEFAULTS object with all config fallbacks
│ ├── format.ts # Agent name/model/category formatting
│ └── types.ts # Core types: AgentEntry, CategoryGroup, OmoConfig, SidebarConfig
├── assets/ # Screenshots for README
├── .gitlab-ci.yml # CI: validate -> build -> publish
└── package.json
```

## WHERE TO LOOK
## CONTRACTS

- Server dependency: `@opencode/plugin@2.0.32`.
- Host/TUI peers: `@opencode/theme`, `@opentui/core`, `@opentui/solid`, and `solid-js`.
- Package exports are `.` and `./tui`; local-directory host smoke uses disposable root wrappers, never repository root shims.
- `@opentui/solid` is imported only in `src/render.ts`.
- A slot callback creates one stable container; `insert(container, () => ...)` owns reactive rendering.
- Runtime state is `loaded | missing | invalid | error`, with deterministic fingerprint and watch specification.
- Reload work is serialized/coalesced and generation-gated. Cleanup invalidates pending work before closing the slot, controller, and watcher.
- User collapse and selection state survives reload after first valid initialization.
- All display output is single-line and truncate-safe.

| Task | File |
|------|------|
| Add agent fields | `src/types.ts` (`AgentEntry`) + `src/agents.ts` (mapping logic) |
| Change category logic | `src/agents.ts` -- `categorizeAgents()`, `DEFAULT_CATEGORY` |
| Display formatting | `src/format.ts` -- agent row rendering, name truncation |
| Config options | `src/types.ts` (`SidebarConfig`) + `src/defaults.ts` (`DEFAULTS`) |
| Config parsing | `src/config.ts` -- `mergeConfig()`, type-safe value extractors |
| TUI rendering | `src/render.ts` -- sidebar layout, sections, keybind handling |
## COMMANDS

```bash
bun run typecheck
bun test
bun run build:all
bun run verify:package
```

## CONVENTIONS (THIS REPO)
## AUTOMATION

- **Config source**: Single file `~/.config/opencode/oh-my-openagent.json` with `tui` sub-key for sidebar config
- **Type-safe parsing**: `isRecord()`, `stringValue()`, `numberValue()`, `booleanValue()`, `enumValue()` -- no `as` casts
- **Agent categories**: Defined in `defaults.ts` (`DEFAULT_CATEGORY_ORDER`), users override via `tui.category_order`
- **Alias maps**: `provider_aliases`, `model_aliases`, `variant_aliases` for display name overrides
- **Model display modes**: `"inline"` (default), `"details-only"`, `"hidden"`
- **Show disabled modes**: `"hidden"`, `"dimmed"`, `"grouped"`
- **Config fingerprint**: `configFingerprint()` for change detection in poll loop
- GitHub is the source of truth. `CI / Typecheck`, `CI / Tests`, and `CI / Package` are required before merge.
- CI uploads the exact `.artifacts/package.tgz` produced by `verify:package`.
- A `vX.Y.Z` tag must equal `package.json.version`; the release workflow repeats every gate, publishes the verified tarball through npm Trusted Publishing/OIDC, and attaches it with its SHA-256 digest to the GitHub Release.
- GitLab is a read-only mirror and has no release pipeline.

## ANTI-PATTERNS

- NEVER add runtime dependencies beyond peer deps (`@opencode-ai/plugin`, `@opentui/solid`, `solid-js`)
- NEVER import `@opentui/solid` outside `render.ts`
- NEVER mutate `DEFAULTS` object -- always spread into new objects
- NEVER use `text()` for interactive elements -- use `box()` with `onMouseDown`
- All format output MUST be single-line, truncate-safe
- NEVER add `@opencode-ai/plugin`, `@opencode-ai/sdk`, V1 plugin lifecycle, dual runtime shapes, or root entry shims.
- NEVER import `@opentui/solid` outside `src/render.ts`.
- NEVER mutate defaults or accepted runtime state; create new values.
- NEVER publish an unchanged fingerprint or let an older reload generation commit.
- NEVER use `text()` for interactive elements; use `box()` with `onMouseDown`.
- NEVER restore removed `slot_order`; V2 contribution order follows package order in host config.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.0.0] - 2026-10-21

### Breaking

- Requires OpenCode v2 and the `@opencode/plugin` v2 server/TUI contracts. OpenCode v1 users must remain on `opencode-agents-sidebar@1.0.8`.
- Removes the V1 lifecycle, repository root entrypoint shim, and deprecated `slot_order`; v2 contribution order follows package order in host configuration.

### Added

- Adds deterministic `loaded`, `missing`, `invalid`, and `error` runtime states with full fingerprints and recovery watch specifications.
- Adds serialized, coalesced, generation-safe reloads that preserve user collapse and selection state.
- Adds directory-based config watching with delete/recreate, atomic-replacement, and polling recovery support.
- Adds strict declaration-closure, packed-artifact, clean-import, and consumer type checks.

### Changed

- Uses a stable tracked Solid render root so runtime, click, selection, and live theme changes render without host snapshot requests.
- Documents OhMyOpenAgent configuration as the only current agent source; the provider seam permits future native sources without claiming universal discovery.
- Moves required checks and exact-artifact npm releases from GitLab CI to GitHub Actions with Trusted Publishing/OIDC.

## [1.0.8] - 2026-05-30

### Changed
Expand Down
23 changes: 16 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@ Thank you for your interest in contributing. This document covers the developmen

## Prerequisites

- **Bun** (latest stable) -- <https://bun.sh>
- **Bun** >= 1.3.0 -- <https://bun.sh>
- **TypeScript** >= 5.5 (installed via `bun install`)

## Development Setup

```bash
git clone https://github.com/Mark1708/opencode-agents-sidebar.git
cd agents-sidebar
bun install
bun run build:all
bun test
bun install --frozen-lockfile
bun run typecheck
bun test
bun run build:all
bun run verify:package
```

## Build Commands
Expand Down Expand Up @@ -43,15 +44,23 @@ bun run typecheck
## Pull Request Process

1. Fork the repository and create a branch from `main`.
2. Run `bun run build:all && bun run typecheck && bun test` before pushing.
2. Run `bun install --frozen-lockfile && bun run typecheck && bun test && bun run build:all && bun run verify:package`.
3. Write clear, descriptive commit messages (lowercase, imperative mood).
4. Open a pull request against `main` with a description of the change.
5. All CI checks must pass before merge.
5. Required GitHub Actions `Typecheck`, `Tests`, and `Package` checks must pass before merge.

## Release process

GitHub is the source of truth. Maintainers release by pushing a `vX.Y.Z` tag
that matches `package.json.version`. The release workflow repeats every gate,
publishes the exact verified `.artifacts/package.tgz` through npm Trusted
Publishing/OIDC, and attaches the tarball plus its SHA-256 digest to the GitHub
Release. GitLab is maintained only as a read-only mirror.

## Language

Use English for all code comments, commit messages, issue descriptions, and pull request discussions.

## Project Context

This is an OpenCode TUI sidebar plugin built with `@opentui/solid` and `@opencode-ai/plugin`. It displays normalized provider agents, collapsible sections, and model information. In the Phase 0/1 foundation, [OhMyOpenAgent](https://github.com/oh-my-openagent) metadata remains only a temporary bootstrap source until the OpenCode-native provider is added.
This is an OpenCode v2 TUI sidebar plugin built with `@opentui/solid` and `@opencode/plugin`. Its current data source is `oh-my-openagent.json`; the provider seam permits a future native OpenCode source but does not claim universal discovery.
Loading
Loading