diff --git a/.beads/.gitignore b/.beads/.gitignore deleted file mode 100644 index ad117ba..0000000 --- a/.beads/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Dolt database (managed by Dolt, not git) -dolt/ -dolt-access.lock - -# Runtime files -bd.sock -bd.sock.startlock -sync-state.json -last-touched -.exclusive-lock - -# Daemon runtime (lock, log, pid) -daemon.* - -# Interactions log (runtime, not versioned) -interactions.jsonl - -# Push state (runtime, per-machine) -push-state.json - -# Lock files (various runtime locks) -*.lock - -# Credential key (encryption key for federation peer auth β€” never commit) -.beads-credential-key - -# Local version tracking (prevents upgrade notification spam after git ops) -.local_version - -# Worktree redirect file (contains relative path to main repo's .beads/) -# Must not be committed as paths would be wrong in other clones -redirect - -# Sync state (local-only, per-machine) -# These files are machine-specific and should not be shared across clones -.sync.lock -export-state/ - -# Ephemeral store (SQLite - wisps/molecules, intentionally not versioned) -ephemeral.sqlite3 -ephemeral.sqlite3-journal -ephemeral.sqlite3-wal -ephemeral.sqlite3-shm - -# Dolt server management (auto-started by bd) -dolt-server.pid -dolt-server.log -dolt-server.lock -dolt-server.port -dolt-server.activity - -# Corrupt backup directories (created by bd doctor --fix recovery) -*.corrupt.backup/ - -# Backup data (auto-exported JSONL, local-only) -backup/ - -# Per-project environment file (Dolt connection config, GH#2520) -.env - -# Legacy files (from pre-Dolt versions) -*.db -*.db?* -*.db-journal -*.db-wal -*.db-shm -db.sqlite -bd.db -# NOTE: Do NOT add negation patterns here. -# They would override fork protection in .git/info/exclude. -# Config files (metadata.json, config.yaml) are tracked by git by default -# since no pattern above ignores them. diff --git a/.beads/README.md b/.beads/README.md deleted file mode 100644 index dbfe363..0000000 --- a/.beads/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# Beads - AI-Native Issue Tracking - -Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code. - -## What is Beads? - -Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git. - -**Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads) - -## Quick Start - -### Essential Commands - -```bash -# Create new issues -bd create "Add user authentication" - -# View all issues -bd list - -# View issue details -bd show - -# Update issue status -bd update --claim -bd update --status done - -# Sync with Dolt remote -bd dolt push -``` - -### Working with Issues - -Issues in Beads are: -- **Git-native**: Stored in Dolt database with version control and branching -- **AI-friendly**: CLI-first design works perfectly with AI coding agents -- **Branch-aware**: Issues can follow your branch workflow -- **Always in sync**: Auto-syncs with your commits - -## Why Beads? - -✨ **AI-Native Design** -- Built specifically for AI-assisted development workflows -- CLI-first interface works seamlessly with AI coding agents -- No context switching to web UIs - -πŸš€ **Developer Focused** -- Issues live in your repo, right next to your code -- Works offline, syncs when you push -- Fast, lightweight, and stays out of your way - -πŸ”§ **Git Integration** -- Automatic sync with git commits -- Branch-aware issue tracking -- Dolt-native three-way merge resolution - -## Get Started with Beads - -Try Beads in your own projects: - -```bash -# Install Beads -curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash - -# Initialize in your repo -bd init - -# Create your first issue -bd create "Try out Beads" -``` - -## Learn More - -- **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs) -- **Quick Start Guide**: Run `bd quickstart` -- **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples) - ---- - -*Beads: Issue tracking that moves at the speed of thought* ⚑ diff --git a/.beads/config.yaml b/.beads/config.yaml deleted file mode 100644 index 232b151..0000000 --- a/.beads/config.yaml +++ /dev/null @@ -1,54 +0,0 @@ -# Beads Configuration File -# This file configures default behavior for all bd commands in this repository -# All settings can also be set via environment variables (BD_* prefix) -# or overridden with command-line flags - -# Issue prefix for this repository (used by bd init) -# If not set, bd init will auto-detect from directory name -# Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc. -# issue-prefix: "" - -# Use no-db mode: JSONL-only, no Dolt database -# When true, bd will use .beads/issues.jsonl as the source of truth -# no-db: false - -# Enable JSON output by default -# json: false - -# Feedback title formatting for mutating commands (create/update/close/dep/edit) -# 0 = hide titles, N > 0 = truncate to N characters -# output: -# title-length: 255 - -# Default actor for audit trails (overridden by BEADS_ACTOR or --actor) -# actor: "" - -# Export events (audit trail) to .beads/events.jsonl on each flush/sync -# When enabled, new events are appended incrementally using a high-water mark. -# Use 'bd export --events' to trigger manually regardless of this setting. -# events-export: false - -# Multi-repo configuration (experimental - bd-307) -# Allows hydrating from multiple repositories and routing writes to the correct database -# repos: -# primary: "." # Primary repo (where this database lives) -# additional: # Additional repos to hydrate from (read-only) -# - ~/beads-planning # Personal planning repo -# - ~/work-planning # Work planning repo - -# JSONL backup (periodic export for off-machine recovery) -# Auto-enabled when a git remote exists. Override explicitly: -# backup: -# enabled: false # Disable auto-backup entirely -# interval: 15m # Minimum time between auto-exports -# git-push: false # Disable git push (export locally only) -# git-repo: "" # Separate git repo for backups (default: project repo) - -# Integration settings (access with 'bd config get/set') -# These are stored in the database, not in this file: -# - jira.url -# - jira.project -# - linear.url -# - linear.api-key -# - github.org -# - github.repo diff --git a/.beads/hooks/post-checkout b/.beads/hooks/post-checkout deleted file mode 100755 index 601ed4e..0000000 --- a/.beads/hooks/post-checkout +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env sh -# --- BEGIN BEADS INTEGRATION v0.62.0 --- -# This section is managed by beads. Do not remove these markers. -if command -v bd >/dev/null 2>&1; then - export BD_GIT_HOOK=1 - _bd_timeout=${BEADS_HOOK_TIMEOUT:-300} - if command -v timeout >/dev/null 2>&1; then - timeout "$_bd_timeout" bd hooks run post-checkout "$@" - _bd_exit=$? - if [ $_bd_exit -eq 124 ]; then - echo >&2 "beads: hook 'post-checkout' timed out after ${_bd_timeout}s β€” continuing without beads" - _bd_exit=0 - fi - else - bd hooks run post-checkout "$@" - _bd_exit=$? - fi - if [ $_bd_exit -eq 3 ]; then - echo >&2 "beads: database not initialized β€” skipping hook 'post-checkout'" - _bd_exit=0 - fi - if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi -fi -# --- END BEADS INTEGRATION v0.62.0 --- diff --git a/.beads/hooks/post-merge b/.beads/hooks/post-merge deleted file mode 100755 index ba26040..0000000 --- a/.beads/hooks/post-merge +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -# OpenZeus post-merge hook -# Automatically syncs OpenZeus repo changes to OpenCode config after git pull/merge - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)" - -# Only run if we're in an OpenZeus repo -if [[ -f "$SCRIPT_DIR/agents/OpenZeus.md" && -f "$SCRIPT_DIR/sync-utils.sh" ]]; then - echo "πŸ”„ OpenZeus post-merge: syncing changes to config..." - "$SCRIPT_DIR/sync-utils.sh" push - echo "βœ… Sync complete" -fi - -# --- BEGIN BEADS INTEGRATION v0.62.0 --- -# This section is managed by beads. Do not remove these markers. -if command -v bd >/dev/null 2>&1; then - export BD_GIT_HOOK=1 - _bd_timeout=${BEADS_HOOK_TIMEOUT:-300} - if command -v timeout >/dev/null 2>&1; then - timeout "$_bd_timeout" bd hooks run post-merge "$@" - _bd_exit=$? - if [ $_bd_exit -eq 124 ]; then - echo >&2 "beads: hook 'post-merge' timed out after ${_bd_timeout}s β€” continuing without beads" - _bd_exit=0 - fi - else - bd hooks run post-merge "$@" - _bd_exit=$? - fi - if [ $_bd_exit -eq 3 ]; then - echo >&2 "beads: database not initialized β€” skipping hook 'post-merge'" - _bd_exit=0 - fi - if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi -fi -# --- END BEADS INTEGRATION v0.62.0 --- diff --git a/.beads/hooks/pre-commit b/.beads/hooks/pre-commit deleted file mode 100755 index 888174e..0000000 --- a/.beads/hooks/pre-commit +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env sh -# --- BEGIN BEADS INTEGRATION v0.62.0 --- -# This section is managed by beads. Do not remove these markers. -if command -v bd >/dev/null 2>&1; then - export BD_GIT_HOOK=1 - _bd_timeout=${BEADS_HOOK_TIMEOUT:-300} - if command -v timeout >/dev/null 2>&1; then - timeout "$_bd_timeout" bd hooks run pre-commit "$@" - _bd_exit=$? - if [ $_bd_exit -eq 124 ]; then - echo >&2 "beads: hook 'pre-commit' timed out after ${_bd_timeout}s β€” continuing without beads" - _bd_exit=0 - fi - else - bd hooks run pre-commit "$@" - _bd_exit=$? - fi - if [ $_bd_exit -eq 3 ]; then - echo >&2 "beads: database not initialized β€” skipping hook 'pre-commit'" - _bd_exit=0 - fi - if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi -fi -# --- END BEADS INTEGRATION v0.62.0 --- diff --git a/.beads/hooks/pre-push b/.beads/hooks/pre-push deleted file mode 100755 index 300ecc0..0000000 --- a/.beads/hooks/pre-push +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env sh -# --- BEGIN BEADS INTEGRATION v0.62.0 --- -# This section is managed by beads. Do not remove these markers. -if command -v bd >/dev/null 2>&1; then - export BD_GIT_HOOK=1 - _bd_timeout=${BEADS_HOOK_TIMEOUT:-300} - if command -v timeout >/dev/null 2>&1; then - timeout "$_bd_timeout" bd hooks run pre-push "$@" - _bd_exit=$? - if [ $_bd_exit -eq 124 ]; then - echo >&2 "beads: hook 'pre-push' timed out after ${_bd_timeout}s β€” continuing without beads" - _bd_exit=0 - fi - else - bd hooks run pre-push "$@" - _bd_exit=$? - fi - if [ $_bd_exit -eq 3 ]; then - echo >&2 "beads: database not initialized β€” skipping hook 'pre-push'" - _bd_exit=0 - fi - if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi -fi -# --- END BEADS INTEGRATION v0.62.0 --- diff --git a/.beads/hooks/prepare-commit-msg b/.beads/hooks/prepare-commit-msg deleted file mode 100755 index d76e816..0000000 --- a/.beads/hooks/prepare-commit-msg +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env sh -# --- BEGIN BEADS INTEGRATION v0.62.0 --- -# This section is managed by beads. Do not remove these markers. -if command -v bd >/dev/null 2>&1; then - export BD_GIT_HOOK=1 - _bd_timeout=${BEADS_HOOK_TIMEOUT:-300} - if command -v timeout >/dev/null 2>&1; then - timeout "$_bd_timeout" bd hooks run prepare-commit-msg "$@" - _bd_exit=$? - if [ $_bd_exit -eq 124 ]; then - echo >&2 "beads: hook 'prepare-commit-msg' timed out after ${_bd_timeout}s β€” continuing without beads" - _bd_exit=0 - fi - else - bd hooks run prepare-commit-msg "$@" - _bd_exit=$? - fi - if [ $_bd_exit -eq 3 ]; then - echo >&2 "beads: database not initialized β€” skipping hook 'prepare-commit-msg'" - _bd_exit=0 - fi - if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi -fi -# --- END BEADS INTEGRATION v0.62.0 --- diff --git a/.beads/metadata.json b/.beads/metadata.json deleted file mode 100644 index aad805b..0000000 --- a/.beads/metadata.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "database": "dolt", - "backend": "dolt", - "dolt_mode": "server", - "dolt_database": "zeus", - "project_id": "307febf1-328c-42c5-b555-a060b5a72d15" -} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 20ed959..544c3fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,8 +2,6 @@ name: CI on: push: - branches: - - main pull_request: branches: - main @@ -25,22 +23,27 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: "20" + node-version: "22.19.0" + + - name: Install package dependencies + run: npm install --ignore-scripts --no-audit --no-fund - name: Run test suite - run: npm test + run: OPENZEUS_NODE="$(command -v node)" npm test + + - name: Test V2 plugin entrypoint + run: node tests/plugin.mjs - name: Validate package assets run: ./bin/openzeus validate --ci - - name: Validate clean install + - name: Validate agent bootstrap shell: bash run: | set -euo pipefail export OPENCODE_CONFIG_DIR="$RUNNER_TEMP/openzeus-config" - ./bin/openzeus install --all - ./bin/openzeus doctor --ci - ./bin/openzeus diff --summary --ci + ./bin/openzeus install-agent + cmp agents/OpenZeus.md "$OPENCODE_CONFIG_DIR/agents/OpenZeus.md" - name: Verify npm package contents run: npm pack --dry-run diff --git a/.gitignore b/.gitignore index eee8f3e..9d1e7a2 100644 --- a/.gitignore +++ b/.gitignore @@ -123,7 +123,8 @@ tui.json *.bak *.old -# Beads / Dolt files (added by bd init) +# Local Beads / Dolt state +.beads/ .dolt/ *.db .beads-credential-key diff --git a/AGENTS.md b/AGENTS.md index bca9e3a..c07042c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,346 +1,136 @@ # OpenZeus Developer Guide -This file provides guidelines for AI agents operating in the OpenZeus repository. +This file defines repository-level rules for agents and contributors working on OpenZeus. ---- +## Product -## Project Overview +OpenZeus is an OpenCode companion agent. Its target responsibilities are: -OpenZeus is an AI agent for OpenCode - a sophisticated configuration and automation system. The project consists of: +- inspect the user's effective OpenCode environment; +- explain source/provenance, precedence and shadowing; +- diagnose configuration and discovery problems; +- plan safe migrations to current OpenCode formats; +- help design high-quality OpenCode agents, skills and commands. -- **Bash scripts**: Installation, sync utilities, context-aware creator, git hooks -- **Markdown skills**: Domain expertise guides for OpenCode operations -- **Markdown commands**: Custom slash command templates -- **Markdown agents**: Agent definitions for OpenCode -- **NPM package**: Published distribution with install.sh +OpenZeus is not a replacement for OpenCode and not a generic knowledge pack. ---- +Before architecture work, read: -## Build & Test Commands +1. `docs/plans/openzeus-2-refocus.md` +2. `docs/continuity/openzeus-2.md` +3. `codemap.md` -### Running Tests +## Active branch policy -```bash -# Validate bash syntax (single file) -bash -n scripts/install.sh - -# Validate all bash scripts -bash -n scripts/install.sh && bash -n scripts/sync-utils.sh && bash -n scripts/create-utils.sh && bash -n scripts/setup-hooks.sh - -# Run package tests -npm test - -# Full validation - syntax + npm test -bash -n scripts/install.sh && npm test -``` - -### Publishing to npm +The OpenZeus 2 campaign is developed on a work branch until a coherent +checkpoint is ready. Do not publish npm releases or tags from refocus branches. -```bash -# Bump version in package.json, then: -npm publish - -# Check package contents before publishing -npm pack --dry-run -``` +Keep plans in `docs/plans/` and campaign continuity in `docs/continuity/`. +Do not create evidence branches, report branches, or parallel tracking layers. -### Git Workflow +## Native-first rule -```bash -# Check sync status (repo vs config) -./scripts/sync-utils.sh status +Prefer current OpenCode-native behavior over OpenZeus wrappers. -# Push changes from repo to config -./scripts/sync-utils.sh push +For exact OpenCode configuration shapes, use the current OpenCode schema and +official V2 docs. New OpenZeus-owned assets must use native-current syntax. -# Pull changes from config to repo -./scripts/sync-utils.sh pull +In particular: -# Auto-detect sync direction -./scripts/sync-utils.sh auto -``` +- use ordered `permissions` rules, not legacy `permission`; +- use permission action `shell`, not `bash`; +- use `subagent`, not legacy `subtask`/`task`; +- do not generate legacy top-level agent request fields such as + `temperature`, `top_p`, `prompt`, `tools`, `disable`, or + `maxSteps`; +- do not hard-code a model unless the feature specifically requires one. ---- +## Privacy and portability -## Code Style Guidelines +Never commit: -### Bash Scripts +- contributor-specific absolute paths; +- credentials, tokens, private keys, or copied local secrets; +- transient local tool state. -**Shebang & Error Handling** -```bash -#!/bin/bash -set -e # Exit on error (always use this) -set -u # Exit on undefined variable -set -o pipefail # Catch errors in pipelines -``` +Resolve user/config paths at runtime. Examples should use portable placeholders +or environment variables. -**Variables** -```bash -# Use UPPER_CASE for constants -CONSTANT_VALUE="fixed" +## Scope boundary -# Use lower_case for local variables -local user_input="" +A shipped skill or command must directly serve OpenCode operation, diagnosis, +migration, or authoring. -# Always quote variables to handle spaces -cp -f "$source_file" "$target_dir/" -``` +Do not add generic domain packs or copied documentation for unrelated tools. +If an external integration becomes valuable, implement a real optional adapter +rather than mirroring its documentation in a skill. -**Functions** -```bash -# Declare with local variables -function my_function() { - local arg1="$1" - local arg2="$2" - - # Use return for exit codes, not values - return 0 # success - return 1 # failure -} -``` +## Build and validation -**Conditionals** -```bash -# Use [[ ]] for tests (not [ ]) -if [[ -f "$file" ]]; then - echo "exists" -fi - -# String comparison -if [[ "$var" == "expected" ]]; then - echo "match" -fi -``` +Run: -**Loops** ```bash -# Always use proper quoting in loops -for file in "$directory"/*; do - if [[ -f "$file" ]]; then - process "$file" - fi -done -``` - -### Markdown Files - -**Skill Files** (`skills/*/SKILL.md`) -```markdown ---- -name: skill-name -description: Brief description of what the skill covers ---- - -# Skill Name - -## Section 1 - -Content... - ---- - -## Section 2 - -More content... - ---- - -End of skill. -``` - -**Agent Files** (`agents/*.md`) -```markdown -# Agent Name - -Description of the agent's role and capabilities. - ---- - -## Instructions - -Detailed agent instructions... - ---- - -## Tools - -- tool-name: what it does -- Another tool usage - ---- - -## Examples - -Example usage patterns... - ---- - -End of agent. -``` - -**Command Files** (`commands/*.md`) -```markdown -# Command: /command-name - -**Description**: What the command does - ---- - -## Template - -{{template content with placeholders}} - ---- - -## Usage - -`/command-name [arguments]` - ---- - -## Examples - -`/command-name example` β€” Description +npm test +./bin/openzeus validate --ci +npm pack --dry-run ``` -### File Naming - -| Type | Pattern | Example | -|------|---------|---------| -| Agents | `*.md` | `OpenZeus.md` | -| Skills | `*/SKILL.md` | `zeus-core/SKILL.md` | -| Commands | `*.md` | `zeus-git-commit.md` | -| Scripts | `scripts/*.sh` | `scripts/sync-utils.sh` | - -### Error Handling +For an isolated bootstrap check: ```bash -# Check for required tools -if ! command -v git &>/dev/null; then - echo "Error: git is required" >&2 - exit 1 -fi - -# Check for required files -if [[ ! -f "$required_file" ]]; then - echo "Error: required file not found: $required_file" >&2 - exit 1 -fi - -# Use subshells for isolated error handling -if (set -e; dangerous_command); then - echo "Success" -else - echo "Failed but continuing..." -fi +export OPENCODE_CONFIG_DIR="$(mktemp -d)" +./bin/openzeus install-agent +cmp agents/OpenZeus.md "$OPENCODE_CONFIG_DIR/agents/OpenZeus.md" ``` -### Naming Conventions - -| Item | Convention | Example | -|------|------------|---------| -| Bash functions | snake_case | `detect_zeus_repo` | -| Variables | snake_case | `opencode_dir` | -| Constants | UPPER_CASE | `DEFAULT_TIMEOUT` | -| Skills | prefix | `zeus-core`, `zeus-swarm` | -| Commands | prefix | `zeus-git-commit`, `zeus-kanban` | -| Agents | PascalCase | `OpenZeus`, `TaskManager` | - ---- - -## Sync Strategy - -This project uses a bidirectional sync system: - -1. **Repo** (``) - Version controlled, contains all source -2. **Config** (`~/.config/opencode/`) - Runtime location for OpenCode - -**Key principle**: Changes made in the repo must sync to config, and vice versa. - -Scripts in the `scripts/` folder are included in the npm package and installed to user config. The scripts folder contains: install.sh, sync-utils.sh, create-utils.sh, setup-hooks.sh - ---- +CI runs on branch pushes. A feature checkpoint is not complete while CI is +red. -## Common Tasks +## Code conventions -### Adding a New Skill +### Bash -1. Create `skills/zeus-newskill/SKILL.md` -2. Add skill metadata header (name, description) -3. Document the skill's purpose and usage -4. Update README.md skills table -5. Sync: `./scripts/sync-utils.sh push` +- `#!/bin/bash` +- `set -euo pipefail` +- quote path/user variables; +- default to non-mutating behavior; +- use `--dry-run`/plan flows for consequential changes where practical; +- do not silently overwrite user-owned files. -### Adding a New Command - -1. Create `commands/zeus-command.md` -2. Follow command template format -3. Update README.md commands table -4. Sync: `./scripts/sync-utils.sh push` - -### Publishing a Release - -1. Update `package.json` version -2. Update `CHANGELOG.md` -3. Commit with message: `Release v1.0.x: description` -4. Push to GitHub -5. Publish to npm: `npm publish` - ---- - - -## Beads Issue Tracker - -This project uses **bd (beads)** for issue tracking. Run `bd prime` to see full workflow context and commands. - -### Quick Reference - -```bash -bd ready # Find available work -bd show # View issue details -bd update --claim # Claim work -bd close # Complete work -``` +### Node -### Rules +Runtime-inspection code should: -- Use `bd` for ALL task tracking β€” do NOT use TodoWrite, TaskCreate, or markdown TODO lists -- Run `bd prime` for detailed command reference and session close protocol -- Use `bd remember` for persistent knowledge β€” do NOT use MEMORY.md files +- avoid network access unless explicitly part of the contract; +- never print secret values; +- expose machine-readable JSON when the agent needs deterministic evidence; +- report unresolved runtime-only information as a limitation instead of + guessing. -## Session Completion +### Markdown assets -**When ending a work session**, complete the applicable steps below. Remote pushes require explicit user authorization or an active project policy that clearly authorizes autonomous push for the current task. +Skills require `name` and trigger-oriented `description` frontmatter. -**MANDATORY WORKFLOW:** +Agents require a useful `description`; use current OpenCode modes and +permissions. -1. **File issues for remaining work** - Create issues for anything that needs follow-up -2. **Run quality gates** (if code changed) - Tests, linters, builds -3. **Update issue status** - Close finished work, update in-progress items -4. **Sync/push when authorized** - Only when authorized by the user or active project policy: - ```bash - git pull --rebase - bd dolt push - git push - git status # MUST show "up to date with origin" - ``` -5. **Clean up** - Clear stashes, prune remote branches -6. **Verify** - All authorized local/remote state changes succeeded -7. **Hand off** - Provide context for next session +Commands should represent genuinely reusable workflows rather than trivial +prompt aliases. -**CRITICAL RULES:** -- Do not push without user/project authorization -- If an authorized push fails, resolve and retry or report the blocker with exact evidence -- Do not claim remote work is complete unless the authorized push/sync succeeded - +## Git and remote mutations -## Repository Map +Normal commits/pushes on the authorized campaign branch are allowed for this +work. Destructive history rewrites, force-pushes, releases, registry +publication, credential changes, or deletion of canonical branches require +explicit authorization. -A full codemap is available at `codemap.md` in the project root. +## Current focused skills -Before working on any task, read `codemap.md` to understand: -- Project architecture and entry points -- Directory responsibilities and design patterns -- Data flow and integration points between modules +- `zeus-diagnostics` +- `zeus-migration` +- `zeus-agents` +- `zeus-commands` +- `zeus-skills` -For deep work on a specific folder, also read that folder's `codemap.md`. +Keep this set small unless a new skill has a clear OpenCode-specific reason to +exist. diff --git a/README.md b/README.md index d080a9d..cad44f8 100644 --- a/README.md +++ b/README.md @@ -4,263 +4,240 @@ [![npm](https://img.shields.io/npm/v/openzeus)](https://www.npmjs.com/package/openzeus) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) -**Guided OpenCode setup, validation, and asset generation.** +## Your OpenCode setup, explained -OpenZeus helps you make an OpenCode workspace useful fast: plan repo setup, install profile-aware assets, validate config, capture commands from prompts, and upgrade safely with local backups. +OpenZeus is an **OpenCode companion agent** for understanding and maintaining +your actual OpenCode environment. + +Ask it why an agent is not loading, where a skill comes from, which +configuration wins, whether an old definition should be migrated, or how to +design a new OpenCode skill or agent. + +```text +@OpenZeus why isn't my reviewer agent loading? +@OpenZeus where did this skill come from? +@OpenZeus audit my OpenCode setup and explain the problems. +@OpenZeus migrate this old agent to the current OpenCode format. +@OpenZeus design a portable skill for this workflow. +```

- OpenZeus + OpenZeus

-## What OpenZeus is useful for +OpenZeus uses OpenCode's native configuration, agents, skills, commands and +plugins wherever possible. Its value is the layer on top: inspection, +diagnosis, migration guidance and higher-level asset design. + +## What it is for -- **Plan setup**: preview repo-local `.opencode/` assets before writing. -- **Install profiles**: install `core`, `extras`, or `all` OpenZeus assets. -- **Validate CI**: fail fast on package, project, or config drift problems. -- **Create assets**: generate OpenCode agents, skills, and commands safely. -- **Capture commands**: turn repeatable prompts into slash commands. -- **Upgrade safely**: back up local config and preserve the active install profile. +- **Understand the effective setup** β€” global vs project configuration, + discovered assets, precedence and eventually provenance/shadowing. +- **Diagnose OpenCode problems** β€” invalid definitions, missing assets, + configuration drift and compatibility issues. +- **Evolve old setups safely** β€” inspect first, plan changes, validate, back up + and roll back when needed. +- **Design OpenCode assets** β€” especially reusable skills and more complex + agent/command setups where a simple scaffold is not enough. +- **Prefer native OpenCode behavior** β€” OpenZeus should not duplicate a core + feature just because it can. ## Installation -OpenZeus supports **Linux and macOS** directly. On Windows, use **WSL**; native -Windows is intentionally not listed in the npm package's supported OS targets. +OpenZeus 2 is moving to native OpenCode plugin delivery. The plugin owns the +focused five-skill core. Until OpenCode allows plugins to +add agents, one small bootstrap step installs only `agents/OpenZeus.md`. -### NPM +Linux and macOS are supported directly. On Windows, use WSL. ```bash npm install -g openzeus -openzeus install --all +opencode plugin add openzeus +openzeus install-agent ``` -### Manual +The current installer resolves the target at runtime. You can override it with +`OPENCODE_CONFIG_DIR`; repository files do not contain user-specific absolute +paths. -```bash -git clone https://github.com/Aveer/OpenZeus.git -cd OpenZeus -./scripts/install.sh --all -``` +> OpenZeus 2 includes a native OpenCode V2 Promise plugin. It registers the +> packaged `skills/` directory as a native skill source through +> `@opencode-ai/plugin/v2/promise`. Current OpenCode V2 cannot add a new agent +> from a plugin because `AgentDraft` has no `add()`; the small agent-file +> bootstrap therefore remains transitional until upstream exposes that API. -The installer copies assets into `${OPENCODE_CONFIG_DIR:-~/.config/opencode}`. +## Use OpenZeus -## 30-second golden path +The agent is the primary interface. The CLI is support machinery. -```bash -npm install -g openzeus -openzeus install --core # agent + helpers + core skills/commands -openzeus setup --plan # preview repo-local .opencode setup -openzeus setup --apply --target . # write starter assets -openzeus validate --ci # CI-friendly package/config validation -openzeus diff --summary # count config drift issues -``` - -For a stack-specific setup: +### Diagnose -```bash -openzeus recipes -openzeus setup --plan --recipe node --target . -openzeus setup --apply --recipe node --target . +```text +@OpenZeus audit my OpenCode setup. +@OpenZeus why isn't this skill available? +@OpenZeus explain which config applies here. ``` -## Common workflows - -### Install profiles +Current deterministic helpers: ```bash -openzeus install --core # OpenZeus agent, helpers, core skills/commands -openzeus install --extras # non-core skills/commands plus agent/helpers -openzeus install --all # everything +openzeus audit +openzeus audit --json +openzeus inspect --json +openzeus validate --ci ``` -The agent and helper scripts are always installed. Skills and commands are filtered by profile. `doctor`, `diff`, and `upgrade` use the saved `.openzeus-install-profile` so profile-filtered assets are not reported as missing. +`audit` is the user-facing diagnostic summary. `inspect` exposes the raw +filesystem evidence used for provenance, precedence and compatibility checks. -### Plan and apply project setup +### Create or improve a skill -```bash -openzeus recipes -openzeus setup --plan --recipe python --target . -openzeus setup --apply --recipe python --target . +```text +@OpenZeus create a reusable skill for our release workflow. +@OpenZeus review this SKILL.md for discovery and portability problems. ``` -Recipes: `node`, `python`, `docs`, `beads`, `solo-dev`. Add `--dry-run` to preview writes and `--force` to replace existing starter files. +OpenZeus keeps dedicated skill-authoring guidance because OpenCode can load +skills natively but does not currently provide an equivalent dedicated skill +creator workflow. + +### Work with agents -### Validate and inspect drift +For a basic agent scaffold, prefer OpenCode's native creator: ```bash -openzeus validate --ci -openzeus validate --ci --project . -openzeus doctor --ci -openzeus diff --summary --ci +opencode agent create ``` -`--ci` exits non-zero on validation failures or drift warnings. - -### Capture a slash command +Use OpenZeus when the problem is architectural rather than mechanical: -```bash -openzeus capture-command \ - --name release-notes \ - --prompt 'Draft release notes from $ARGUMENTS' \ - --target .opencode \ - --dry-run +```text +@OpenZeus design a reviewer agent with safe permissions and two specialist subagents. +@OpenZeus migrate this legacy agent definition without changing its behavior. ``` -Remove `--dry-run` to write `.opencode/commands/release-notes.md`. Use `--force` to overwrite. +## Focused skills -### Initialize project context +OpenZeus now ships only skills that directly help operate or author OpenCode. -```bash -openzeus context init --target . --dry-run -openzeus context init --target . -``` +| Skill | Role | +|---|---| +| `zeus-diagnostics` | Runtime/config discovery, precedence and troubleshooting | +| `zeus-migration` | Safe OpenCode migration planning | +| `zeus-agents` | Advanced agent design and maintenance | +| `zeus-commands` | Command design and maintenance | +| `zeus-skills` | Skill authoring, discovery and portability | -Writes `.opencode/context/{architecture.md,commands.md,testing.md}` with detected stack, test, and build notes. +Generic domain packs, pseudo-introspection skills and copied documentation for +external plugins are intentionally outside the OpenZeus core. -### Upgrade or rollback local config +## Current CLI -```bash -openzeus upgrade --dry-run -openzeus upgrade --apply -openzeus rollback --dry-run -openzeus rollback --apply +The CLI is intentionally small: + +```text +audit Summarize actionable findings; --ci fails on warnings +inspect Inventory filesystem-visible OpenCode sources and precedence +install-agent Install only the transitional @OpenZeus agent bootstrap +create Create an agent, skill, or command template +validate Validate OpenZeus/OpenCode asset structure ``` -Upgrade creates a local backup under the OpenCode config directory, then reinstalls using the saved install profile. +OpenZeus no longer ships generic project-management/Git slash commands. +Command authoring remains available through `@OpenZeus` and `openzeus create command`. -### Create agents, skills, and commands +The old generic `setup`, `init-project`, recipe, context-init and +prompt-capture helpers have been removed from the refocus branch. OpenCode's +native `/init` owns project initialization; OpenZeus stays focused on +inspection, diagnosis, migration and OpenCode-specific authoring. -The original OpenZeus idea is still first-class: it can create OpenCode assets directly, with valid frontmatter, no-overwrite defaults, `--dry-run`, and `--force` when you intentionally want replacement. +## Development ```bash -openzeus create agent reviewer "Reviews pull requests for correctness and maintainability" -openzeus create skill project-workflow "Use when following this repo's release workflow" -openzeus create command release-notes "Draft release notes" 'Use $ARGUMENTS to choose the release range.' +npm test +openzeus validate --ci +npm pack --dry-run ``` -| Asset | Output | -|---|---| -| Agent | Markdown agent with current `description`, `mode`, and conservative `permission` frontmatter | -| Skill | `SKILL.md` bundle with required `name` and `description` frontmatter | -| Command | Slash command Markdown with frontmatter and `$ARGUMENTS`-ready prompt body | +Architecture and campaign state: -Related generators: +- [OpenZeus 2 refocus plan](docs/plans/openzeus-2-refocus.md) +- [OpenZeus 2 continuity](docs/continuity/openzeus-2.md) -```bash -openzeus capture-command --name triage --prompt 'Triage $ARGUMENTS and propose next steps' --target .opencode -openzeus setup --plan --target . -openzeus setup --apply --target . -``` +## Version -### Sync safely +Current stable npm release: **1.2.0**. This branch prepares **2.0.0**. -```bash -openzeus sync status -openzeus sync auto # safe one-way sync or conflict refusal -``` +OpenZeus 2.0.0 is the breaking refocus release: native V2 plugin delivery, five focused skills, runtime inspection/audit, plan-only migration, and a minimal agent bootstrap. -## Use OpenZeus in OpenCode +## Links -Ask for outcomes, not file names: +- Repository: https://github.com/Aveer/OpenZeus +- Issues: https://github.com/Aveer/OpenZeus/issues +- OpenCode Docs: https://opencode.ai/docs/ +- NPM Package: https://npmjs.com/package/openzeus -```bash -@OpenZeus audit my OpenCode setup and explain what to fix -@OpenZeus plan setup for this repo, then apply it after I review -@OpenZeus turn this release process into a slash command -@OpenZeus validate this project for CI -``` -### Use commands +## OpenCode V2 plugin prototype -```bash -/zeus-git-commit # Draft and create a local commit; push only when authorized -/zeus-kanban # Manage docs/team/KANBAN.md -/zeus-roadmap # Manage docs/team/ROADMAP.md -/zeus-improve-project # Structured project improvement cycle +The refocus branch exposes the package itself as a V2 plugin: + +```jsonc +{ + "$schema": "https://opencode.ai/config.json", + "plugins": ["openzeus"] +} ``` -## Zeus Skills +The plugin registers the packaged `skills/` directory as a native OpenCode +skill source. OpenCode then owns normal skill discovery/loading. -OpenZeus currently ships **15** Zeus skills. Install the focused product surface with `openzeus install --core`, or install every skill with `openzeus install --all`. +Runtime diagnostics remain explicit CLI evidence through `openzeus inspect` +and `openzeus audit`; the current V2 Promise plugin context does not expose a +custom-tool registration surface, so OpenZeus does not claim one. -| Skill | Purpose | -|---|---| -| `zeus-core` | OpenCode config, paths, permissions, docs, and troubleshooting reference | -| `zeus-agents` | Design and create OpenCode agents with current modes and permissions | -| `zeus-commands` | Create reusable slash commands and prompt templates | -| `zeus-skills` | Canonical guide for writing OpenCode skills | -| `zeus-upskill` | Add/register new `zeus-*` capabilities into OpenZeus | -| `zeus-context` | Context management, session handoff, and repo knowledge workflows | -| `zeus-self` | Runtime self-diagnostics and OpenZeus operational awareness | -| `zeus-beads` | Beads issue-tracking workflows and command reference | -| `zeus-swarm` | opencode-swarm workflows and multi-agent orchestration | -| `zeus-oac` | OpenAgentsControl reference and plan-first workflows | -| `zeus-omo` | oh-my-opencode-slim reference and tmux/provider workflows | -| `zeus-docker` | Docker and containerization reference | -| `zeus-sql` | SQL/database patterns and query guidance | -| `zeus-llm` | Local LLM tooling: llama.cpp, llama-swap, Ollama | -| `zeus-boston-terrier` | Fun/example skill for Boston Terrier knowledge | - -Example routing: +The plugin does **not** yet register the `@OpenZeus` agent itself. Current +OpenCode V2 can inspect/update/remove agents from a plugin but cannot add one, +so the agent-file bootstrap remains until that upstream limitation changes. -```bash -@OpenZeus create a new agent for SQL reviews -# loads zeus-agents + zeus-core - -@OpenZeus help me containerize this service -# loads zeus-docker when available -``` -## Development +### Transitional agent bootstrap -### Test local package install +Once the OpenZeus 2 package is published, installation is intended to be: ```bash -npm pack -npm install -g ./openzeus-1.2.0.tgz -openzeus help +opencode plugin add openzeus +npx openzeus install-agent ``` -### Validate changes +If you already keep the CLI globally: ```bash -npm test -openzeus validate --ci -openzeus doctor --ci -openzeus diff --summary --ci -./scripts/sync-utils.sh status +openzeus install-agent ``` -### Project folders - -| Folder | Purpose | -|---|---| -| `agents/` | OpenCode agent definitions | -| `commands/` | Slash command templates | -| `skills/` | Zeus skill bundles | -| `scripts/` | Install, sync, creation, and hook utilities | -| `docs/` | Contributor, release, and package docs | +`install-agent` never copies skills, commands, plugin code, or private +machine state. It copies only `agents/OpenZeus.md`, refuses to overwrite a +different file unless `--force` is explicit, and supports `--backup`. -## Troubleshooting +The older `openzeus install` spelling remains only as a temporary alias to +`install-agent`. -| Issue | Try | -|---|---| -| `OpenZeus` not available | Run `npm install -g openzeus && openzeus install --core`, then restart OpenCode. | -| Skills not found | Check `${OPENCODE_CONFIG_DIR:-~/.config/opencode}/skills/`. | -| Commands not found | Check `${OPENCODE_CONFIG_DIR:-~/.config/opencode}/commands/`. | -| Config path differs | Set `OPENCODE_CONFIG_DIR` before installing/syncing. | -| CI fails on drift | Run `openzeus diff --summary` and `openzeus doctor --fix-plan`. | -## Version +### Migration planning -Current package version: **1.2.0**. +OpenZeus can now turn compatibility findings into an explicit, non-mutating +migration plan: -## Links - -- Repository: https://github.com/Aveer/OpenZeus -- Issues: https://github.com/Aveer/OpenZeus/issues -- OpenCode Docs: https://opencode.ai/docs/ -- NPM Package: https://npmjs.com/package/openzeus +```bash +openzeus migrate --plan +openzeus migrate --plan --json +``` ---- +Current plans cover legacy agent permissions/tools/request fields, legacy +command `subtask`, and legacy `tui.json(c)`. Every action is marked +`automatic: false`. -**πŸ›οΈ Welcome to the realm of OpenZeus!** +`openzeus migrate --apply` intentionally refuses to run. Automatic migration +will only be added when edits are parser-backed and each supported migration +has backup, validation and rollback guarantees. diff --git a/agents/OpenZeus.md b/agents/OpenZeus.md index 6144380..0ee66a5 100644 --- a/agents/OpenZeus.md +++ b/agents/OpenZeus.md @@ -1,224 +1,125 @@ --- -description: Guided OpenCode setup, audit, asset generation, and sync operator. +description: OpenCode companion for inspecting, diagnosing, migrating, and designing an OpenCode workspace. mode: all -model: opencode/big-pickle color: "#FFD700" -temperature: 0.1 -steps: 100 -permission: - edit: ask - webfetch: allow - bash: ask +permissions: + - action: edit + resource: "*" + effect: ask + - action: shell + resource: "*" + effect: ask + - action: webfetch + resource: "*" + effect: allow + - action: websearch + resource: "*" + effect: allow + - action: skill + resource: "zeus-*" + effect: allow --- -# OpenZeus β€” Guided OpenCode Operator +# OpenZeus β€” OpenCode Workspace Companion -You are **OpenZeus**, an OpenCode operator for setup planning, validation, command capture, context initialization, profile-aware installs, and safe config upgrades. Be concise, route to outcomes, load the right skill for deep work, and prefer current OpenCode conventions over stale examples. +You are **OpenZeus**, a focused assistant for the user's OpenCode environment. -## Core Responsibilities +Understand the setup that actually exists, explain why it behaves the way it +does, diagnose configuration/discovery problems, help migrate old definitions, +and design high-quality OpenCode agents, skills and commands. -- Answer OpenCode questions with current docs and local project context. -- Audit OpenCode setup and produce concrete fix plans or CI failures. -- Plan and apply repo-local OpenCode setup with recipe-aware dry-run previews. -- Create and update OpenCode assets: agents, commands, skills, and config docs. -- Convert user prompts and team workflows into reusable slash commands with `capture-command`. -- Initialize project context files for architecture, commands, and testing notes. -- Install `core`, `extras`, or `all` profiles and preserve that profile during doctor/diff/upgrade. -- Upgrade or roll back local OpenCode config using profile-preserving backups. -- Diagnose loading, discovery, permission, and repo ↔ config sync issues. -- Route work to Zeus skills or subagents when specialized guidance is useful. -- Keep operations safe: inspect before changing, explain high-risk actions, and ask when required. +You are not a replacement for OpenCode and not a generic software-development +expert. Prefer OpenCode's native capabilities over OpenZeus-specific wrappers. -## Safety Rules +## Operating principles -1. **Confirm remote or destructive mutations** unless project instructions unambiguously authorize them: `git push`, publishing, force-push, deleting files, destructive shell operations, credential changes. -2. **Do not grant yourself broad shell access.** Use bash only when needed; explain risky commands before running them. -3. **Never write secrets to disk** or stage credentials. -4. **Fetch docs when uncertain** about OpenCode behavior or changed APIs. -5. **Commit/push only when explicitly requested** or when repository instructions clearly require it and the user has authorized that autonomy. +1. Inspect before guessing. +2. Prefer current OpenCode features, schema and built-in customization + knowledge instead of maintaining a second copy. +3. For exact shapes, schema/docs beat remembered examples. +4. Explain precedence and provenance when multiple definitions exist. +5. Preserve behavior during migration; plan before mutation. +6. Never hard-code private machine paths into reusable assets. +7. Keep OpenZeus OpenCode-specific. +8. Ask before remote/destructive/publishing/credential mutations. -## Current OpenCode Terms +## Evidence to consider -| Term | Use | -|---|---| -| `primary` | Main interactive agent mode | -| `subagent` | Agent used by another agent/tool for delegated work | -| `all` | Agent can be used in both primary and subagent contexts | - -## Quick Paths - -| Path | Purpose | -|---|---| -| `${OPENCODE_CONFIG_DIR:-~/.config/opencode}` | Global OpenCode config root | -| `~/.config/opencode/opencode.json` | Main OpenCode config | -| `~/.config/opencode/tui.json` | TUI state/preferences; keep separate from agent config | -| `~/.config/opencode/agents/` | Global agents | -| `~/.config/opencode/commands/` | Global commands | -| `~/.config/opencode/skills/` | Global skills | -| `/.opencode/agents/` | Project agents | -| `/.opencode/commands/` | Project commands | -| `/.opencode/skills/` | Project skills | -| `/.claude/skills/`, `/.agents/skills/` | Additional skill discovery locations used by compatible tooling | - -## Skill Routing - -Load skills with the `skill` tool before deep or unfamiliar work. - -| User intent | Load | -|---|---| -| Audit setup, diagnose loading/sync issues, explain fix plan or CI failure | `zeus-core` | -| Plan/apply repo-local setup, choose recipes, initialize context | `zeus-core` + `zeus-agents` + `zeus-commands` | -| Turn a prompt/workflow into a slash command | `zeus-commands` + `zeus-core` | -| Install profiles, diff, upgrade, rollback | `zeus-core` | -| OpenCode config, paths, permissions, models, troubleshooting | `zeus-core` | -| Create/modify agents | `zeus-agents` + `zeus-core` | -| Create/modify slash commands | `zeus-commands` + `zeus-core` | -| Create skill bundles | `zeus-skills` + `zeus-core` | -| Add a new Zeus capability | `zeus-upskill` | -| Multi-agent orchestration | `zeus-swarm` | -| Local LLMs | `zeus-llm` | -| oh-my-opencode/tmux | `zeus-omo` | -| Docker/container work | `zeus-docker` | -| SQL/database work | `zeus-sql` | -| Beads issue tracking | `zeus-beads` | -| Context/session handoff | `zeus-context` or `zeus-self` | - -For non-Zeus domains, delegate to an appropriate subagent or load a matching specialized skill. - -When users ask what OpenZeus includes, answer from the current skill inventory: core OpenCode skills (`zeus-core`, `zeus-agents`, `zeus-commands`, `zeus-skills`, `zeus-upskill`), workflow skills (`zeus-context`, `zeus-self`, `zeus-beads`, `zeus-swarm`, `zeus-oac`, `zeus-omo`), technical skills (`zeus-docker`, `zeus-sql`, `zeus-llm`), and the example/fun `zeus-boston-terrier` skill. - -## Outcome Workflows - -### Audit setup - -```bash -openzeus doctor --fix-plan # non-mutating audit with planned fixes -openzeus doctor --ci # fail on warnings/failures -openzeus diff --summary --ci # fail on config drift -openzeus validate --ci # package/config validation -``` +Depending on the question, inspect: -Use this when users ask: β€œis OpenCode set up?”, β€œwhy is OpenZeus not loading?”, β€œwhat should CI run?”, β€œwhat should I fix?” +- OpenCode version and current format; +- global, project, explicit and inline configuration sources; +- agents and their mode/permissions; +- skills and discovery sources; +- commands; +- plugins; +- duplicate IDs, overrides and shadowing; +- compatibility-translated legacy fields. -### Plan or apply setup - -```bash -openzeus recipes -openzeus setup --plan --recipe node --target . -openzeus setup --apply --recipe node --target . -``` - -Recipes: `node`, `python`, `docs`, `beads`, `solo-dev`. Preview first. Use `--force` only after explaining overwrites and receiving confirmation. - -### Initialize project context - -```bash -openzeus context init --target . --dry-run -openzeus context init --target . -``` +For generic OpenCode configuration knowledge, prefer current OpenCode +customization guidance and `https://opencode.ai/config.json`. -Use this when users need persistent project notes for architecture, commands, and testing. +Use `openzeus inspect --json` for deterministic filesystem evidence such as +source precedence, collisions and legacy files. The native plugin supplies the +focused Zeus skills; it does not currently provide a custom runtime-inspection +tool because the V2 Promise plugin context has no tool-registration domain. -### Prompt to command +For a basic agent scaffold, prefer: ```bash -openzeus capture-command --name release-notes --prompt 'Draft release notes from $ARGUMENTS' --target .opencode --dry-run -openzeus capture-command --name release-notes --prompt 'Draft release notes from $ARGUMENTS' --target .opencode +opencode agent create ``` -Ask for the trigger, inputs, safety gates, and expected output. Add confirmation gates for git, publishing, deletion, or network mutation. - -### Create agents, skills, and commands - -```bash -openzeus create agent reviewer "Reviews pull requests for correctness and maintainability" -openzeus create skill project-workflow "Use when following this repo's release workflow" -openzeus create command release-notes "Draft release notes" 'Use $ARGUMENTS to choose the release range.' -``` +Use OpenZeus authoring guidance when architecture, migration, portability or a +multi-asset design is the actual problem. -This original OpenZeus workflow remains first-class. Prefer direct `openzeus create ...` for one asset, `openzeus capture-command ...` for repeated-prompt-to-command conversion, and `openzeus setup --plan/--apply` for a repo-local starter workspace. +## Focused skill routing -### Install, upgrade, or roll back +| Need | Skill | +|---|---| +| Diagnose loading, discovery, precedence or config state | `zeus-diagnostics` | +| Plan/review legacy-to-current migration | `zeus-migration` | +| Advanced agent design or maintenance | `zeus-agents` | +| Slash-command design or maintenance | `zeus-commands` | +| Skill creation, review and portability | `zeus-skills` | -```bash -openzeus install --core # agent/helpers + core skills/commands -openzeus install --extras # agent/helpers + non-core skills/commands -openzeus install --all # everything -openzeus upgrade --dry-run -openzeus upgrade --apply -openzeus rollback --dry-run -openzeus rollback --apply -``` +Load a skill only when it materially improves the task. -The installer always installs the OpenZeus agent and helper scripts. Skills and commands are filtered by profile. Upgrade uses local config backups and preserves the saved profile. +## Deterministic helpers -### Diagnose loading or sync issues +Use the smallest helper that answers the question: ```bash -openzeus doctor --fix-plan -openzeus diff --summary +openzeus audit --json +openzeus inspect --json +openzeus migrate --plan --json openzeus validate --ci ``` -Check paths, asset names, frontmatter, permissions, and repo/config drift before editing. +The native plugin supplies the focused skills. Runtime/config evidence comes +from `inspect`, `audit`, current OpenCode schema/docs and the environment +visible to the current session. -## Topic β†’ URL Lookup +## Migration planning -| Topic | URL | -|---|---| -| Agents/subagents | https://opencode.ai/docs/agents/ | -| Commands | https://opencode.ai/docs/commands/ | -| Permissions | https://opencode.ai/docs/permissions/ | -| Config | https://opencode.ai/docs/config/ | -| Models/providers | https://opencode.ai/docs/models/ | -| Skills | https://opencode.ai/docs/skills/ | -| Plugins | https://opencode.ai/docs/plugins/ | - -## Creation Workflows - -### Agents - -```text -1. Load zeus-agents + zeus-core. -2. Use openzeus create agent for standard generation unless a hand edit is clearly better. -3. Choose location: repo source when contributing to OpenZeus; project/global config otherwise. -4. Use current mode terms: primary, subagent, all. -5. Set minimal permissions; prefer ask for shell or destructive operations. -6. Report changed files and sync instructions. -``` +When legacy findings need a concrete change plan, use +`openzeus migrate --plan --json` and load `zeus-migration`. -### Commands +The current implementation is deliberately non-mutating. Do not invent an +automatic apply flow around it; review the plan and edit deliberately until a +parser-backed migration engine exists. -```text -1. Load zeus-commands + zeus-core. -2. Use openzeus create command or openzeus capture-command for standard generation. -3. Use Markdown command files with frontmatter and concise workflows. -4. Use supported syntax where helpful: $ARGUMENTS, $1/$2, shell injection, @file references. -5. Add safety gates for git, publishing, deletion, or network mutation. -``` +## Current-format baseline -### Skills +New OpenZeus-owned agents should use current ordered `permissions` rules and +current action names such as `shell`, `edit` and `subagent`. -```text -1. Load zeus-skills (+ zeus-upskill for new zeus-* capabilities). -2. Use openzeus create skill for standard generation unless custom supporting files are needed. -3. Create skills//SKILL.md with name + description frontmatter. -4. Keep guidance example-driven and scoped. -5. Update relevant docs/README when adding a public Zeus skill. -``` +Do not hard-code a model unless the user wants one. Do not generate legacy +top-level agent fields such as `permission`, `tools`, `temperature`, +`top_p`, `prompt`, `disable` or `maxSteps`. -## Sync Utilities - -```bash -openzeus sync status # Check repo ↔ config state -openzeus sync push # Repo β†’ config -openzeus sync pull # Config β†’ repo -openzeus sync auto # Safe one-way sync or conflict refusal - -./scripts/sync-utils.sh status # Direct script equivalent -./scripts/sync-utils.sh push -./scripts/sync-utils.sh pull -./scripts/sync-utils.sh auto -``` +## Scope boundary -End of prompt. +If the user asks about an unrelated technical domain, answer normally or route +to an appropriate general/specialist agent. OpenZeus becomes more useful by +understanding OpenCode better, not by accumulating unrelated knowledge packs. diff --git a/agents/codemap.md b/agents/codemap.md index b35f72d..833091e 100644 --- a/agents/codemap.md +++ b/agents/codemap.md @@ -1,84 +1,68 @@ -# agents/ β€” Agent Definitions +# agents/ β€” OpenZeus agent ## Responsibility -`agents/` contains OpenCode agent Markdown files. Agents define persona, mode, model preferences, permissions, and behavioral rules. +`agents/OpenZeus.md` defines the conversational OpenZeus companion. -## Current Agent Pattern +It is intentionally the only shipped agent. Current OpenCode V2 plugin APIs can +register skills/tools/commands but cannot add a new agent, so this file remains +a transitional bootstrap asset. -```markdown ---- -description: Human-readable summary -mode: all # primary | subagent | all -model: opencode/model -color: "#FFD700" -temperature: 0.1 -steps: 100 -permission: - edit: allow - webfetch: allow - bash: ask ---- +## Current format -# Agent Name +OpenZeus uses native-current agent conventions: -System prompt... +```yaml +--- +description: ... +mode: all +permissions: + - action: edit + resource: "*" + effect: ask + - action: shell + resource: "*" + effect: ask + - action: skill + resource: "zeus-*" + effect: allow + - action: openzeus_runtime + resource: "*" + effect: allow +--- ``` -## Mode Terms - -| Mode | Meaning | -|---|---| -| `primary` | Main interactive agent | -| `subagent` | Delegated agent called by another agent/tool | -| `all` | Available in both primary and subagent contexts | - -## Discovery Paths +Do not reintroduce legacy `permission`, `bash`, `tools`, `temperature`, +`top_p`, `prompt`, `disable`, or `maxSteps` fields. -| Scope | Agents path | -|---|---| -| Global | `${OPENCODE_CONFIG_DIR:-~/.config/opencode}/agents/` | -| Project | `/.opencode/agents/` | -| Source package | `/agents/` | - -Related config files: - -- `opencode.json`: runtime config such as agents, providers, and permissions. -- `tui.json`: TUI state/preferences; do not document it as the main runtime config. - -## Permission Pattern +## Model behavior -- Grant the minimum needed permissions. -- Prefer `ask` for shell and risky operations. -- Do not document unrestricted bash as the default. -- Remote or destructive mutations require explicit user confirmation unless repo policy clearly authorizes them. +No model is pinned. OpenZeus should inherit the user's configured/session model +unless the user explicitly chooses otherwise. -## OpenZeus Agent +## Skill routing -`OpenZeus.md` is the main operator agent. - -| Concern | Implementation | +| Need | Skill | |---|---| -| Mode | `all` | -| Steps | `100` | -| Routing | Loads Zeus skills for deeper domain guidance | -| Safety | Commit/push/publish/destructive actions gated by confirmation | +| Diagnostics / precedence / provenance | `zeus-diagnostics` | +| Migration planning | `zeus-migration` | +| Advanced agent design | `zeus-agents` | +| Command design | `zeus-commands` | +| Skill authoring | `zeus-skills` | -## Skill Integration +## Evidence sources -OpenZeus routes common intents to skills: +Prefer: -```text -config/permissions β†’ zeus-core -create agent β†’ zeus-agents + zeus-core -create command β†’ zeus-commands + zeus-core -create skill β†’ zeus-skills + zeus-core -docker/sql/llm β†’ matching Zeus skill -``` +1. `openzeus_runtime` for live OpenCode version/location/registry inventory; +2. `openzeus inspect --json` for filesystem provenance/collisions; +3. current OpenCode schema/docs for exact syntax; +4. `openzeus migrate --plan --json` when compatibility findings need a + concrete non-mutating migration plan. -## File Manifest +## Safety -| File | Purpose | -|---|---| -| `OpenZeus.md` | Main OpenCode operator agent | -| `codemap.md` | This map | +- Never hard-code user-specific absolute paths in reusable assets. +- Never print secret values for diagnostic proof. +- Ask before destructive, publishing, credential, or remote mutations. +- Preserve behavior when proposing migrations. diff --git a/bin/openzeus b/bin/openzeus index cfddd03..cffe28c 100755 --- a/bin/openzeus +++ b/bin/openzeus @@ -1,170 +1,86 @@ #!/bin/bash - set -euo pipefail resolve_root() { - local source="${BASH_SOURCE[0]}" - local dir="" - + local source="${BASH_SOURCE[0]}" dir="" while [[ -L "$source" ]]; do dir="$(cd -P "$(dirname "$source")" && pwd)" source="$(readlink "$source")" [[ "$source" == /* ]] || source="$dir/$source" done - cd -P "$(dirname "$source")/.." && pwd } SCRIPT_DIR="$(resolve_root)" +node_bin() { + local resolved="${OPENZEUS_NODE:-${npm_node_execpath:-}}" + if [[ -z "$resolved" ]]; then + resolved="$(command -v node 2>/dev/null || true)" + fi + [[ -n "$resolved" ]] || { echo "OpenZeus requires Node.js for this command" >&2; exit 1; } + printf '%s\n' "$resolved" +} + usage() { cat < [args...] +Usage: openzeus [args...] Commands: - install Install OpenZeus assets into an OpenCode config directory - sync Compare or sync repo assets with an OpenCode config directory - create Create an agent, skill, or command template - hooks Install optional Git hooks for repo/config sync checks - doctor Run non-mutating health checks - status Show install/sync health summary - list List package assets and installation status - examples Show copy-paste examples - init-project Create project-local .opencode starter assets - setup Plan or apply repo-local setup - validate Validate package, config, or project assets - capture-command Generate a command from a prompt - recipes List supported setup recipes - diff Show package/config drift summary - upgrade Backup and refresh installed config assets - rollback Restore the latest config backup - context Project context helpers + audit Summarize actionable OpenCode findings + inspect Inventory filesystem-visible OpenCode sources and precedence + install-agent Install only the @OpenZeus agent file + create Create an OpenCode agent, skill, or command template + validate Validate OpenZeus/OpenCode asset structure + examples Show common OpenZeus workflows +The five focused Zeus skills and live runtime tool are provided by the native +OpenCode V2 plugin. Manage it with: + opencode plugin add openzeus + opencode plugin list + opencode plugin update openzeus + opencode plugin remove openzeus EOF } -doctor() { - if [[ -x "$SCRIPT_DIR/scripts/doctor.sh" ]]; then - exec "$SCRIPT_DIR/scripts/doctor.sh" "$@" - fi - echo "doctor unavailable" - return 1 -} - -status() { - local config_dir="${OPENCODE_CONFIG_DIR:-${OPENZEUS_CONFIG_DIR:-$HOME/.config/opencode}}" - local skill_pkg_count command_pkg_count skill_inst_count command_inst_count drift_lines - skill_pkg_count=$(find "$SCRIPT_DIR/skills" -maxdepth 1 -mindepth 1 -type d -name 'zeus-*' | wc -l | tr -d ' ') - command_pkg_count=$(find "$SCRIPT_DIR/commands" -maxdepth 1 -type f -name 'zeus-*.md' | wc -l | tr -d ' ') - skill_inst_count=0; command_inst_count=0 - [[ -d "$config_dir/skills" ]] && skill_inst_count=$(find "$config_dir/skills" -maxdepth 1 -mindepth 1 -type d -name 'zeus-*' | wc -l | tr -d ' ') - [[ -d "$config_dir/commands" ]] && command_inst_count=$(find "$config_dir/commands" -maxdepth 1 -type f -name 'zeus-*.md' | wc -l | tr -d ' ') - echo "Package root: $SCRIPT_DIR" - echo "Config dir: $config_dir" - echo "OpenZeus agent: $( [[ -f "$config_dir/agents/OpenZeus.md" ]] && echo installed || echo missing )" - echo "Zeus skills: $skill_inst_count/$skill_pkg_count installed" - echo "Zeus commands: $command_inst_count/$command_pkg_count installed" - if [[ -d "$config_dir" ]]; then - local drift - drift="$($SCRIPT_DIR/scripts/sync-utils.sh --repo "$SCRIPT_DIR" --config "$config_dir" status 2>/dev/null || true)" - drift_lines=$(printf '%s\n' "$drift" | grep -E '^(DIFF|MISSING)([[:space:]]|:)' || true) - drift_lines=$(printf '%s\n' "$drift_lines" | sed '/^$/d' | wc -l | tr -d ' ') - if [[ "$drift_lines" -eq 0 ]]; then - echo "Sync drift: clean" - else - echo "Sync drift: $drift_lines issue(s)" - echo "Next: openzeus list all; openzeus sync status" - fi - else - echo "Sync drift: config missing" - echo "Next: openzeus install --dry-run" - fi -} - -list_assets() { - local kind="${1:-all}" config_dir="${OPENCODE_CONFIG_DIR:-${OPENZEUS_CONFIG_DIR:-$HOME/.config/opencode}}" - printf 'Package assets (%s)\n' "$kind" - list_agent() { - local pkg="$SCRIPT_DIR/agents/OpenZeus.md" cfg="$config_dir/agents/OpenZeus.md" status='[missing]' - [[ -f "$cfg" ]] && status='[different]' - [[ -f "$cfg" ]] && cmp -s "$pkg" "$cfg" && status='[installed]' - printf 'agent: agents/OpenZeus.md %s\n' "$status" - } - list_skills() { - local pkg name cfg status - for pkg in "$SCRIPT_DIR"/skills/zeus-*; do - [[ -d "$pkg" ]] || continue - name="$(basename "$pkg")" - cfg="$config_dir/skills/$name" - status='[missing]' - if [[ -d "$cfg" ]]; then - diff -qr "$pkg" "$cfg" >/dev/null 2>&1 && status='[installed]' || status='[different]' - fi - printf 'skill: %s %s\n' "$name" "$status" - done - } - list_commands() { - local pkg name cfg status - for pkg in "$SCRIPT_DIR"/commands/zeus-*.md; do - [[ -f "$pkg" ]] || continue - name="$(basename "$pkg")" - cfg="$config_dir/commands/$name" - status='[missing]' - if [[ -f "$cfg" ]]; then - cmp -s "$pkg" "$cfg" && status='[installed]' || status='[different]' - fi - printf 'command: %s %s\n' "$name" "$status" - done - } - case "$kind" in - agents) list_agent ;; - skills) list_skills ;; - commands) list_commands ;; - all) list_agent; list_skills; list_commands ;; - *) echo "Unknown list kind: $kind"; exit 1 ;; - esac -} - examples() { cat <&2 + exec "$SCRIPT_DIR/scripts/install-agent.sh" "${@:2}" + ;; create) exec "$SCRIPT_DIR/scripts/create-utils.sh" "${@:2}" ;; - hooks) exec "$SCRIPT_DIR/scripts/setup-hooks.sh" "${@:2}" ;; - status) shift || true; status "$@" ;; - list) shift || true; list_assets "${1:-all}" ;; - examples) examples ;; - init-project) exec "$SCRIPT_DIR/scripts/init-project.sh" "${@:2}" ;; - setup) exec "$SCRIPT_DIR/scripts/setup.sh" "${@:2}" ;; validate) exec "$SCRIPT_DIR/scripts/validate.sh" "${@:2}" ;; - capture-command) exec "$SCRIPT_DIR/scripts/capture-command.sh" "${@:2}" ;; - recipes) exec "$SCRIPT_DIR/scripts/setup.sh" recipes "${@:2}" ;; - diff) exec "$SCRIPT_DIR/scripts/diff.sh" "${@:2}" ;; - upgrade) exec "$SCRIPT_DIR/scripts/upgrade.sh" upgrade "${@:2}" ;; - rollback) exec "$SCRIPT_DIR/scripts/upgrade.sh" rollback "${@:2}" ;; - context) exec "$SCRIPT_DIR/scripts/setup.sh" context "${@:2}" ;; - doctor) shift || true; doctor "$@" ;; + examples) examples ;; help|-h|--help) usage ;; - *) echo "Unknown command: ${1:-}"; usage; exit 1 ;; + *) echo "Unknown command: ${1:-}" >&2; usage >&2; exit 1 ;; esac diff --git a/codemap.md b/codemap.md index 0932718..42d0657 100644 --- a/codemap.md +++ b/codemap.md @@ -1,95 +1,67 @@ # Repository Atlas: OpenZeus -## Project Responsibility +## Product responsibility -OpenZeus is a guided OpenCode setup, validation, and asset-generation product. It ships an OpenZeus agent, skill bundles, slash commands, and CLI utilities for profile-aware installs, repo setup plans, CI validation, command capture, context initialization, drift inspection, and safe upgrades. +OpenZeus is an OpenCode companion agent for understanding and maintaining the +user's effective OpenCode environment. -## Entry Points +The primary interface is `@OpenZeus`. Deterministic CLI/plugin primitives +supply evidence for diagnostics, provenance, compatibility and migration +planning. -| File | Purpose | -|---|---| -| `agents/OpenZeus.md` | Main OpenZeus agent definition | -| `bin/openzeus` | Package CLI entrypoint | -| `scripts/install.sh` | Installs assets into OpenCode config | -| `scripts/sync-utils.sh` | Syncs repository assets with config assets | -| `scripts/create-utils.sh` | Generates agents, skills, and commands | -| `scripts/doctor.sh` | Audits setup and reports fix plans | -| `scripts/setup.sh` | Plans/applies repo-local setup and context files | -| `scripts/validate.sh` | Validates package/config/project assets, including CI mode | -| `scripts/capture-command.sh` | Creates slash commands from prompt text | -| `scripts/diff.sh` | Reports profile-aware package/config drift | -| `scripts/upgrade.sh` | Backs up, upgrades, and rolls back local config assets | -| `README.md` | User-facing install and usage guide | -| `package.json` | NPM package metadata, version, and test script | - -## Directory Map - -| Directory | Responsibility | Detailed Map | -|---|---|---| -| `agents/` | Agent Markdown definitions | [agents/codemap.md](agents/codemap.md) | -| `commands/` | Slash command Markdown templates | [commands/codemap.md](commands/codemap.md) | -| `skills/` | Zeus skill bundles | [skills/codemap.md](skills/codemap.md) | -| `scripts/` | Install/sync/create/hook shell utilities | [scripts/codemap.md](scripts/codemap.md) | -| `docs/` | Contributor and publishing docs | β€” | - -## OpenCode Discovery Facts - -| Asset | Global location | Project location | -|---|---|---| -| Agents | `${OPENCODE_CONFIG_DIR:-~/.config/opencode}/agents/` | `/.opencode/agents/` | -| Commands | `${OPENCODE_CONFIG_DIR:-~/.config/opencode}/commands/` | `/.opencode/commands/` | -| Skills | `${OPENCODE_CONFIG_DIR:-~/.config/opencode}/skills/` | `/.opencode/skills/` | +## Canonical docs -Additional skill discovery locations used by compatible tooling may include `/.claude/skills/` and `/.agents/skills/`. +- Plan: [docs/plans/openzeus-2-refocus.md](docs/plans/openzeus-2-refocus.md) +- Continuity: [docs/continuity/openzeus-2.md](docs/continuity/openzeus-2.md) +- Contributing: [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) +- Publishing: [docs/PUBLISHING.md](docs/PUBLISHING.md) -Keep `opencode.json` and `tui.json` separate: `opencode.json` stores runtime configuration; `tui.json` stores TUI state/preferences. +## Entry points -## OpenCode Asset Conventions - -| Asset | Convention | +| File | Purpose | |---|---| -| Agent modes | `primary`, `subagent`, `all` | -| Agents | Markdown with frontmatter and system prompt body | -| Commands | Markdown with frontmatter, workflow, and supported placeholders | -| Skills | `skills//SKILL.md` with `name` and `description` frontmatter | - -## Data Flow +| `agents/OpenZeus.md` | Primary conversational agent and routing policy | +| `src/plugin.js` | Native OpenCode V2 plugin entrypoint | +| `bin/openzeus` | Extensionless executable shell entrypoint exposed by npm as `openzeus` | +| `scripts/inspect.mjs` | Filesystem inventory, source precedence and compatibility evidence | +| `scripts/audit.mjs` | Actionable diagnostic summary | +| `scripts/migrate.mjs` | Non-mutating migration planning | +| `scripts/create-utils.sh` | Agent/skill/command authoring primitive | +| `scripts/install-agent.sh` | Transitional one-file @OpenZeus agent bootstrap | +| `scripts/validate.sh` | Structural validation | +| `skills/` | Five focused OpenCode-specific skills | +| `docs/plans/` | Architecture plans | +| `docs/continuity/` | Campaign/session continuity | + +## Data flow ```text -User request - β†’ OpenZeus agent - β†’ optional skill loading - β†’ setup plan / validate / capture / context / diff workflow - β†’ dry-run, --plan, --ci, or --summary before writes - β†’ install, upgrade, rollback, or sync when explicitly needed +user question + -> @OpenZeus + -> filesystem evidence (inspect) + + current OpenCode schema/runtime context available to the session + -> focused skill when useful + -> audit / explanation / migration plan + -> deliberate mutation only after review ``` -## CLI Surface +## Distribution + +The V2 plugin owns: + +- five focused `zeus-*` skills; +- native registration of the packaged `skills/` directory. -| Command | Purpose | Safe behavior | -|---|---|---| -| `openzeus setup --plan|--apply [--recipe node|python|docs|beads|solo-dev] [--target DIR] [--dry-run] [--force]` | Plan or create repo-local `.opencode/` assets | `--plan` previews; `--dry-run` previews writes; `--force` required for replacement | -| `openzeus validate [--ci] [--project DIR]` | Validate package/config or project assets | `--ci` exits non-zero on failures or drift warnings | -| `openzeus capture-command --name NAME --prompt TEXT [--target DIR] [--dry-run] [--force]` | Generate a slash command from a prompt | Dry-run preview; skips existing files unless forced | -| `openzeus recipes` | List setup recipes | Read-only | -| `openzeus context init [--target DIR] [--dry-run] [--force]` | Create project context notes | Dry-run preview; skips existing files unless forced | -| `openzeus doctor --fix-plan|--ci` | Audit OpenCode setup | Prints planned fixes; CI mode fails on warnings/failures | -| `openzeus diff [--summary] [--ci]` | Report package/config drift | Profile-aware; CI mode fails on drift | -| `openzeus upgrade --dry-run|--apply` | Backup and refresh installed config assets | Preserves saved install profile | -| `openzeus rollback --dry-run|--apply` | Restore latest local config backup | Preview before restoring | -| `openzeus status` | Show installed assets and sync state | Inspection-first | -| `openzeus list [agents|skills|commands|all]` | List available assets | Read-only | -| `openzeus examples` | Show starter workflows | Read-only | -| `openzeus init-project [--target DIR] [--dry-run] [--force]` | Create repo-local `.opencode/` assets | Dry-run preview; `--force` for overwrites | -| `openzeus create ...` | Generate agents, skills, or commands | Uses asset templates and sync guidance | -| `openzeus sync ...` | Repo ↔ config sync | Status/auto prefer conflict refusal over guessing | -| `openzeus install --core|--extras|--all` | Install packaged assets by profile | Agent/helpers always installed; skills/commands filtered by profile | -| `openzeus hooks` | Install git sync hooks | Hooks warn/check before mutating push flow | +Current OpenCode V2 plugins cannot add agents, so `agents/OpenZeus.md` still +uses a small guarded `install-agent` bootstrap. That is the only intended +copy-installed OpenZeus asset. -## Development Patterns +## Durable rules -- Markdown-based OpenCode assets. -- Repository source of truth, synced into OpenCode config. -- Guided CLI workflows: install profile, setup plan/apply, validate, capture-command, context init, doctor, diff, upgrade, rollback. -- Minimal permissions and explicit confirmation for remote/destructive operations. -- Concise, example-driven docs. +- Prefer OpenCode-native functionality. +- Resolve user paths at runtime; never commit contributor-specific paths. +- Keep the shipped skill set small and OpenCode-specific. +- Inspect before mutation. +- Use current OpenCode schema/docs instead of copied reference tables. +- Keep migration apply disabled until parser-backed edits, backup, validation + and rollback are implemented. diff --git a/commands/codemap.md b/commands/codemap.md deleted file mode 100644 index 9fca9a5..0000000 --- a/commands/codemap.md +++ /dev/null @@ -1,77 +0,0 @@ -# commands/ β€” OpenCode Slash Commands - -## Responsibility - -`commands/` contains Markdown slash command templates for OpenCode. Commands bind a reusable workflow to a slash command name such as `/zeus-git-commit`. - -## Command Pattern - -```markdown ---- -description: Human-readable description -agent: OpenZeus ---- - -# Command Name - -Workflow instructions. - -**User's input**: $ARGUMENTS -``` - -## Supported Syntax - -| Syntax | Purpose | Example | -|---|---|---| -| `$ARGUMENTS` | Full user input after the command | `**User's input**: $ARGUMENTS` | -| `$1`, `$2` | Positional arguments | `$1` = first arg, `$2` = second arg | -| Shell injection | Inline shell output in command context when supported by OpenCode | Use for read-only context gathering, not secrets | -| `@file` | Reference file contents in user input/context | `/cmd review @README.md` | - -Prefer `$ARGUMENTS` for free-form prompts and `$1/$2` for strict command shapes. - -## Discovery Paths - -| Scope | Commands path | -|---|---| -| Global | `${OPENCODE_CONFIG_DIR:-~/.config/opencode}/commands/` | -| Project | `/.opencode/commands/` | -| Source package | `/commands/` | - -## Command Inventory - -| Command | File | Purpose | Safety | -|---|---|---|---| -| `/zeus-git-commit` | `zeus-git-commit.md` | Draft and create a local commit | High: no auto-push | -| `/zeus-kanban` | `zeus-kanban.md` | Manage `docs/team/KANBAN.md` | Low | -| `/zeus-roadmap` | `zeus-roadmap.md` | Manage `docs/team/ROADMAP.md` | Low | -| `/zeus-improve-project` | `zeus-improve-project.md` | Structured improvement workflow | Medium | - -## Git Command Safety - -`/zeus-git-commit` follows a local-first protocol: - -```text -inspect diff β†’ scan for unsafe files β†’ show commit plan β†’ commit locally β†’ push only if explicitly authorized -``` - -`--quick` may shorten output, but it must not push. - -## Integration Flow - -```text -User invokes /zeus-command args - β†’ OpenCode loads command Markdown - β†’ placeholders are resolved - β†’ configured agent executes workflow -``` - -## File Manifest - -| File | Purpose | -|---|---| -| `zeus-git-commit.md` | Safe local commit helper | -| `zeus-kanban.md` | Kanban board command | -| `zeus-roadmap.md` | Roadmap command | -| `zeus-improve-project.md` | Project improvement command | -| `codemap.md` | This map | diff --git a/commands/zeus-git-commit.md b/commands/zeus-git-commit.md deleted file mode 100644 index 929f9d3..0000000 --- a/commands/zeus-git-commit.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -description: Analyze changes, draft a conventional commit message, and create a local commit. Push only when explicitly requested and authorized. -agent: OpenZeus ---- - -You are `gitmaster`, a careful Git repository maintainer. - -## Purpose - -Create a **local commit** from the current worktree after showing the user exactly what will be staged and committed. - -## Flags - -- `--push`: After committing, request explicit confirmation before pushing. -- `--no-push`: Commit locally only. This is the default. -- `--quick` / `-q`: May shorten explanations, but **must not auto-push**. - -## Workflow - -1. **Analyze changes** - - Run `git status` and inspect relevant diffs. - - Identify added, modified, deleted, and untracked files. - -2. **Detect unsafe additions** - - Secrets: `.env`, `*.pem`, `*.key`, tokens, passwords, credentials. - - Large/binary files: files >1MB, archives, generated images unless expected. - - Build artifacts: `node_modules/`, `__pycache__/`, `*.pyc`, `.pytest_cache/`, dist outputs. - - If found, stop and ask before staging. - -3. **Draft commit message** - - Imperative mood: `Add feature`, not `Added feature`. - - Subject: max 72 characters. - - Optional body: 1–2 lines explaining why. - - Reference issues/PRs mentioned in the conversation. - -4. **Show plan before commit** - - Files to stage. - - Exact commit message. - - Exact git commands. - -5. **Commit locally** - - Stage only the intended files. - - Create the commit. - - Do not push unless the user explicitly requested push behavior. - -6. **Push gate** - - If `--push` was requested, ask for explicit confirmation before `git push`. - - If repo policy requires push and the user already authorized autonomous push, follow that policy and cite it. - -## Safety Rules - -- Never commit secrets or credentials. -- Never auto-push because of `--quick` or `-q`. -- Never force-push without explicit user authorization. -- If there are no uncommitted changes, report cleanly and stop. -- Keep commits atomic: one logical change per commit. - -**User's input**: $ARGUMENTS diff --git a/commands/zeus-improve-project.md b/commands/zeus-improve-project.md deleted file mode 100644 index 4011f5b..0000000 --- a/commands/zeus-improve-project.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -description: Project analysis, planning, and execution workflow ---- - -# Project improvement workflow -You are running a structured project improvement cycle. Work through the five phases below in strict order. Do not skip phases or proceed speculatively. - -All standard delegation rules, parallelism constraints, verification protocol, and beads requirements remain in effect throughout. - ---- - -## Phase 1 β€” Analyse -Build a complete picture of the project before touching anything. Do not delegate this phase β€” read and reason directly. -- Map the file and folder structure -- Identify the tech stack, dependencies, and entry points -- Read key files: config, main modules, shared utilities, tests -- Note anything that looks fragile, inconsistent, or unclear - ---- - -## Phase 2 β€” Identify Issues and Improvements -Produce two lists from the analysis: - -### Bugs -Things that are broken or likely to break: -- Runtime errors, unhandled edge cases, broken logic -- Missing error handling or null checks -- Dependency mismatches or unsafe assumptions - -### Improvements -Things that work but could be better: -- Performance bottlenecks -- Code duplication or structural debt -- Missing tests or poor coverage -- UX or output quality issues - -> Every item must reference a file, function, or line range. Vague findings are not actionable and must not appear on the list. - ---- - -## Phase 3 β€” Plan -Turn Phase 2 findings into an ordered execution plan. Each item must include: -- **What**: a one-line description of the change -- **Why**: which bug or improvement it addresses -- **Where**: the exact file(s) affected -- **Agent**: which agent will handle it -- **Dependencies**: which other items must complete first (if any) - -Sort by priority: bugs before improvements, high-impact before low-impact. - -Store the full plan as a beads issue before proceeding. - -> Present the plan and wait for confirmation. If the user revises it, update the beads issue and re-confirm before proceeding. Do not begin execution until the plan is confirmed. - ---- - -## Phase 4 β€” Execute -Work through the confirmed plan. -- Dispatch agents according to plan order and dependency graph -- Enforce all parallelism constraints at every dispatch decision -- Verify each agent's output before marking the item complete -- If a task fails twice, self-execute and report back to the user with what was done and why delegation failed - -> If a new issue is discovered mid-execution, log it as a beads issue for the next cycle. Do not expand the current plan's scope. - ---- - -## Phase 5 β€” Test -Run a full verification pass after all plan items are complete. -- Execute the project's existing test suite -- For any changed file, confirm the relevant tests still pass -- If a change has no test coverage, flag it explicitly β€” do not silently skip -- Confirm no regressions were introduced by cross-checking affected files - -If tests fail, treat each failure as a new fixer task under the standard delegation and verification protocol. Do not mark the cycle complete until all tests pass or failures are explicitly documented and understood. - ---- - -## Principles specific to this workflow -- **Analyse before acting.** Read first, plan second, execute third. Never guess at project structure. -- **Plan before executing.** No agent is dispatched without a confirmed plan item behind it. -- **Scope discipline.** Discoveries during execution go into the next cycle, not the current one. diff --git a/commands/zeus-kanban.md b/commands/zeus-kanban.md deleted file mode 100644 index 8c1bfa2..0000000 --- a/commands/zeus-kanban.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -description: Create or update kanban board for team contributors -agent: OpenZeus ---- - -# Kanban Command - -You are a project management assistant. Your task is to manage a KANBAN.md file that tracks tasks across team members in a kanban-style table format. - -## Kanban Principles - -A kanban board visualizes workflow with columns representing stages: -- **To Do** - Tasks waiting to be started -- **In Progress** - Tasks currently being worked on -- **Done** - Completed tasks with completion date - -## Command Modes - -### 1. Add Task: `/zeus-kanban ` -Adds a new task to a specific user's **To Do** column. - -### 2. In Progress: `/zeus-kanban inprogress ` -Moves a task from **To Do** β†’ **In Progress** for a user. - -### 3. Complete: `/zeus-kanban complete ` -Moves a task from **In Progress** β†’ **Done** for a user. - -### 4. View Board: `/zeus-kanban` or `/zeus-kanban status` -Displays the current kanban board without making changes. - -## Workflow - -### For Adding Tasks: - -1. **Check for KANBAN.md**: Look for a `KANBAN.md` file in `docs/team/` directory. - -2. **Create if missing**: If `KANBAN.md` doesn't exist, create it at `docs/team/KANBAN.md` with the following table structure: - -```markdown -# Team Kanban - -| User | To Do | In Progress | Done | -|------|-------|-------------|------| -| Tilmandel | - [ ] Task description | - [ ] Task description | - [x] Task description - Date | -| Aveer | - [ ] Task description | - [ ] Task description | - [x] Task description - Date | -| Unassigned | - [ ] Task description | - [ ] Task description | - [x] Task description - Date | -``` - -3. **Identify user and goal**: Parse the input to determine: - - **User**: Tilmandel, Aveer, or unspecified (defaults to "Unassigned") - - **Goal**: The task description - -4. **Refine the goal**: Before adding, improve the user's input by: - - **Fixing typos and grammar** while preserving the original meaning - - **Improving clarity and style** - make it concise, professional, and actionable - - **Adding relevant emoji** at the start based on the task type: - - πŸ§ͺ Testing: `πŸ§ͺ`, βœ…, πŸ›, πŸ” - - πŸ”§ Fixes/Bugs: `πŸ›`, πŸš‘, πŸ”¨, βš™οΈ - - ✨ Features: `✨`, πŸš€, πŸ†•, 🎯 - - πŸ“Š Data/ML: `πŸ“Š`, πŸ€–, πŸ“ˆ, 🧠 - - 🎨 UI/UX: `🎨`, πŸ’…, πŸ–ΌοΈ, 🎭 - - πŸ” Security: `πŸ”`, πŸ›‘οΈ, πŸ”’, πŸ”‘ - - ⚑ Performance: `⚑`, πŸš€, 🏎️, ⏱️ - - πŸ“š Documentation: `πŸ“š`, πŸ“–, πŸ“, ✍️ - - πŸ”„ Refactoring: `♻️`, πŸ”„, 🧹, πŸ”§ - - πŸ“¦ Dependencies: `πŸ“¦`, πŸ“₯, πŸ“€, πŸ”Œ - - πŸ› οΈ Infrastructure: `πŸ—οΈ`, ☁️, πŸš‡, βš™οΈ - - πŸ“‘ API/Integration: `πŸ”Œ`, 🌐, πŸ“‘, πŸ”— - - πŸ› οΈ Tools: `πŸ› οΈ`, 🧰, πŸ”¨, βš’οΈ - - πŸ“‹ Management: `πŸ“‹`, πŸ“Š, πŸ“, πŸ’Ό - -5. **Add to user's To Do column**: Add the refined task as a new unchecked item in the specified user's **To Do** column cell. - -### For Moving to In Progress: - -1. **Identify user and goal**: Parse the input. - -2. **Search for matching item**: Find the task in the user's **To Do** column. - -3. **Move to In Progress**: - - Remove from **To Do** column - - Add to **In Progress** column as `- [ ] Task description` - -4. **Handle missing item**: If not found, inform user and offer to add to To Do instead. - -### For Marking Complete: - -1. **Identify user and goal**: Parse the input. - -2. **Search for matching item**: Find the task in the user's **In Progress** column. - -3. **Move to Done**: - - Remove from **In Progress** column - - Add to **Done** column as `- [x] Task description - Date` - -4. **Handle missing item**: If not found in In Progress, check To Do and offer to move directly to Done. - -### For Viewing Board: - -1. **Display current state**: Show the full kanban board table with all users and their tasks. - - **CRITICAL**: When multiple tasks exist in a cell, use `
` HTML line breaks to separate them (NOT newlines) - - **Example**: `- [ ] Task 1
- [ ] Task 2` - - Never use actual newlines inside table cells - this breaks markdown table rendering - -2. **Summary statistics**: - - Total tasks per user - - Tasks in each column (To Do, In Progress, Done) - -## Response Format - -After updating the kanban board, provide: -- Summary of changes made (added/moved task) -- Show the **original** vs **refined** version if changes were made -- Current task count per user and column -- Any blockers or recommendations - ---- - -**User's input**: $ARGUMENTS \ No newline at end of file diff --git a/commands/zeus-roadmap.md b/commands/zeus-roadmap.md deleted file mode 100644 index 00f2a5f..0000000 --- a/commands/zeus-roadmap.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -description: Create or update project roadmap with planned and implemented features -agent: OpenZeus ---- - -# Roadmap Command - -You are a project planning assistant. Your task is to manage a ROADMAP.md file that tracks features in two sections: **Planned** and **Implemented**. - -## Command Modes - -### 1. Add New Feature: `/zeus-roadmap ` -Adds a new feature to the **Planned** section. - -### 2. Mark Complete: `/zeus-roadmap complete ` -Marks a feature as **Implemented** by moving it from Planned to Implemented. - -## Workflow - -### For Adding New Features: - -1. **Check for ROADMAP.md**: Look for a `ROADMAP.md` file in `docs/team/` directory. - -2. **Create if missing**: If `ROADMAP.md` doesn't exist, create it at `docs/team/ROADMAP.md` with the following template structure: - -```markdown -# Project Roadmap - -This file tracks planned and implemented features for the project. - -## Planned - -- [ ] Feature name - brief description - -## Implemented - -- [x] Feature name - brief description - Date -``` - -3. **Refine the goal**: Before adding, improve the user's input by: - - **Fixing typos and grammar** while preserving the original meaning - - **Improving clarity and style** - make it concise, professional, and actionable - - **Adding relevant emoji** at the start based on the feature type: - - πŸ§ͺ Testing: `πŸ§ͺ`, βœ…, πŸ›, πŸ” - - πŸ”§ Fixes/Bugs: `πŸ›`, πŸš‘, πŸ”¨, βš™οΈ - - ✨ Features: `✨`, πŸš€, πŸ†•, 🎯 - - πŸ“Š Data/ML: `πŸ“Š`, πŸ€–, πŸ“ˆ, 🧠 - - 🎨 UI/UX: `🎨`, πŸ’…, πŸ–ΌοΈ, 🎭 - - πŸ” Security: `πŸ”`, πŸ›‘οΈ, πŸ”’, πŸ”‘ - - ⚑ Performance: `⚑`, πŸš€, 🏎️, ⏱️ - - πŸ“š Documentation: `πŸ“š`, πŸ“–, πŸ“, ✍️ - - πŸ”„ Refactoring: `♻️`, πŸ”„, 🧹, πŸ”§ - - πŸ“¦ Dependencies: `πŸ“¦`, πŸ“₯, πŸ“€, πŸ”Œ - - πŸ› οΈ Infrastructure: `πŸ—οΈ`, ☁️, πŸš‡, βš™οΈ - - πŸ“‘ API/Integration: `πŸ”Œ`, 🌐, πŸ“‘, πŸ”— - - πŸ› οΈ Tools: `πŸ› οΈ`, 🧰, πŸ”¨, βš’οΈ - -4. **Add to Planned**: Add the refined goal with emoji as a new unchecked item in the **Planned** section. - -### For Marking Complete: - -1. **Check for ROADMAP.md**: Look for the file in `docs/team/` directory. - -2. **Search for matching item**: Find the item in **Planned** section that matches the provided goal. - -3. **Move to Implemented**: - - Remove the item from **Planned** section (delete the `[ ]` line) - - Add it to **Implemented** section as `[x] Feature name - Date` - -4. **Handle missing item**: If no matching item is found in Planned, inform the user and offer to add it anyway. - -## Response Format - -After updating the roadmap, provide: -- Summary of changes made (added/moved feature) -- Show the **original** vs **refined** version if changes were made -- Current count of planned vs implemented features -- Any recommendations for prioritization or related tasks - ---- - -**User's input**: $ARGUMENTS diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 9fb66aa..e3be6ad 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -6,6 +6,37 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) with [Semantic ## [Unreleased] +_No changes yet._ + +## [2.0.0] - 2026-10-04 + +### Added +- Add a native OpenCode V2 Promise plugin entrypoint using `@opencode-ai/plugin/v2/promise`, registering the packaged `skills/` directory as a native skill source. +- Add `openzeus audit [--json] [--ci]` as the user-facing diagnostic summary built on inspector evidence. +- Add focused `zeus-diagnostics` and `zeus-migration` skills. + +### Changed +- Remove the last stale 1.x helper references from the OpenZeus agent and refresh the agent/repository atlases for the V2 plugin architecture. +- Validate the package against the real current OpenCode V2 Promise plugin package/API. +- Rewrite publishing and contributing docs for the native-plugin/agent-bootstrap architecture. +- Move canonical refocus planning under `docs/plans/` and keep local Beads state out of the repository. +- Clean README/atlas wording after the CLI simplification; document the extensionless `bin/openzeus` npm executable explicitly. +- Reduce installation to a guarded `install-agent` bootstrap for `agents/OpenZeus.md`; the V2 plugin owns skills and runtime tooling. +- Collapse the old core/extras split around the focused five-skill core; legacy `--extras` now installs the focused core with a deprecation warning. +- Make OpenZeus generators emit native V2 agent permissions (`permissions` + `shell`) and make validation reject legacy fields in newly managed assets. +- Replace the stale contributor guide with the OpenZeus 2 native-first/privacy/CI contract. +- Refocus OpenZeus around the `@OpenZeus` companion-agent experience: OpenCode environment understanding, diagnostics, migration and asset design. +- Update the shipped OpenZeus agent to native V2-style `permissions`, remove the hard-coded model/request tuning, and prefer OpenCode-native features and schema. +- Rewrite README and repository architecture docs around the agent-first product direction. + +### Removed +- Retire 1.x copy-management helpers: repo/config sync, sync hooks, bundle doctor/diff, refresh/upgrade and rollback. Native OpenCode plugin lifecycle now owns the focused skills. +- Remove generic project bootstrap helpers: `setup`, `init-project`, recipes, `context init`, and `capture-command`; OpenCode's native `/init` owns project initialization. +- Remove bundled generic slash commands (`zeus-git-commit`, `zeus-kanban`, `zeus-roadmap`, `zeus-improve-project`); command authoring remains part of OpenZeus. +- Remove unrelated/general-purpose skills: `zeus-boston-terrier`, `zeus-docker`, `zeus-sql`, and `zeus-llm`. +- Remove copied external-integration skills from core: `zeus-beads`, `zeus-swarm`, `zeus-oac`, and `zeus-omo`. +- Remove legacy broad/meta skills `zeus-core`, `zeus-upskill`, `zeus-context`, and `zeus-self`; their useful responsibilities are folded into focused diagnostics/migration/authoring skills. + ## [1.2.0] - 2026-10-04 ### Added diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index ec63234..22dc74d 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -1,158 +1,145 @@ # Contributing to OpenZeus -Thanks for contributing. Keep changes small, documented, and tested against the OpenCode asset layout. +OpenZeus is an OpenCode companion agent. Contributions should improve +OpenCode-specific inspection, diagnostics, migration, or asset design rather +than turn the project back into a general-purpose toolkit. + +Read first: + +- [OpenZeus 2 plan](plans/openzeus-2-refocus.md) +- [OpenZeus 2 continuity](continuity/openzeus-2.md) +- [Repository atlas](../codemap.md) ## Setup +Use Node **22.19+**. + ```bash git clone https://github.com/Aveer/OpenZeus.git cd OpenZeus -npm install -./scripts/install.sh --all -openzeus validate --ci +npm install --ignore-scripts --no-audit --no-fund +npm test ``` -Use `${OPENCODE_CONFIG_DIR:-~/.config/opencode}` for global OpenCode assets. +Local tracker/tool state such as `.beads/`, `.slim/`, credentials and user +OpenCode config must remain untracked. -## Project Structure +## Project structure | Path | Purpose | |---|---| -| `agents/` | Agent definitions, including `OpenZeus.md` | -| `commands/` | Slash command templates | -| `skills/` | Zeus skill bundles (`skills//SKILL.md`) | -| `scripts/` | Install/sync/create/hook utilities | -| `docs/` | Contributor and publishing docs | -| `codemap.md` | Repository architecture map | +| `agents/OpenZeus.md` | Primary conversational agent | +| `src/plugin.js` | Native OpenCode V2 Promise plugin entrypoint; registers `skills/` as a directory source | +| `skills/` | Five focused OpenCode skills | +| `scripts/inspect.mjs` | Filesystem inventory/provenance | +| `scripts/audit.mjs` | User-facing diagnostics | +| `scripts/migrate.mjs` | Non-mutating migration planning | +| `scripts/create-utils.sh` | Asset authoring primitive | +| `scripts/install-agent.sh` | Transitional one-file agent bootstrap | +| `scripts/validate.sh` | Structural validation | +| `bin/openzeus` | Extensionless npm executable exposed as `openzeus` | +| `docs/plans/` | Architecture plans | +| `docs/continuity/` | Campaign/session continuity | -## Common Changes +## Native-first rule -Prefer guided workflows in user-facing docs and examples: +Do not reimplement an OpenCode feature without a concrete reason. -```bash -openzeus setup --plan --target . -openzeus validate --ci -openzeus doctor --fix-plan -openzeus diff --summary -``` +New OpenZeus-owned assets must use current OpenCode V2 conventions: -Document `--plan`, `--dry-run`, `--fix-plan`, or `--ci` behavior before commands that write files or fail automation. +- ordered `permissions`; +- `shell` rather than legacy `bash`; +- `subagent` rather than `subtask`/`task`; +- no legacy agent `tools`, `permission`, `temperature`, `top_p`, + `prompt`, `disable`, or `maxSteps` fields; +- no hard-coded model unless the feature explicitly needs one. -### Add a skill +## Focused skills -```bash -mkdir -p skills/zeus-example -$EDITOR skills/zeus-example/SKILL.md -``` - -```markdown ---- -name: zeus-example -description: Short purpose statement ---- - -# Zeus Example +The shipped core is intentionally limited to: -## Usage +- `zeus-diagnostics`; +- `zeus-migration`; +- `zeus-agents`; +- `zeus-commands`; +- `zeus-skills`. -Concrete examples first. -``` +A new skill must have a clear OpenCode-specific reason to exist. Do not add +generic Docker/SQL/LLM/domain packs or copied documentation for unrelated +plugins. -Then update README skill listings and OpenZeus routing if the skill should be public. +## Common authoring -### Add a command +Use the CLI primitive when useful: ```bash -$EDITOR commands/zeus-example.md +openzeus create skill release-workflow "Use for release preparation" +openzeus create agent reviewer "Reviews changes for correctness" +openzeus create command release-notes "Draft release notes" ``` -```markdown ---- -description: What this command does -agent: OpenZeus ---- - -# Zeus Example - -Workflow instructions. - -**User's input**: $ARGUMENTS -``` - -### Add or update an agent +For basic agent scaffolding in normal OpenCode usage, prefer the native: ```bash -$EDITOR agents/Example.md +opencode agent create ``` -Use current OpenCode modes: `primary`, `subagent`, or `all`. Grant minimal permissions. +## Validation -## Validate +Before pushing a coherent checkpoint: ```bash npm test -openzeus validate --ci -openzeus validate --ci --project . -openzeus doctor --ci -openzeus diff --summary --ci -./scripts/sync-utils.sh status +node tests/plugin.mjs +./bin/openzeus validate --ci +npm pack --dry-run ``` -For manual runtime testing: +CI runs on branch pushes and is part of the development loop; do not leave a +checkpoint red. -```bash -./scripts/install.sh --core -openzeus list all -openzeus examples -openzeus setup --plan --recipe node --target /tmp/openzeus-smoke -openzeus setup --apply --recipe node --target /tmp/openzeus-smoke --dry-run -openzeus capture-command --name smoke --prompt 'Echo $ARGUMENTS' --target /tmp/openzeus-smoke/.opencode --dry-run -openzeus context init --target /tmp/openzeus-smoke --dry-run -opencode run "@OpenZeus help" -``` +## Migration safety -Use install profiles deliberately: +`openzeus migrate --plan` is non-mutating. -```bash -openzeus install --core --dry-run -openzeus install --extras --dry-run -openzeus install --all --dry-run -``` +Do not add `--apply` as regex/text replacement. A supported automatic +migration requires: -`doctor`, `diff`, and `upgrade` respect the saved `.openzeus-install-profile`. +1. parser-backed understanding; +2. explicit change plan; +3. backup; +4. post-change validation; +5. rollback on failure. -## Sync +## Privacy and portability -```bash -./scripts/sync-utils.sh status # inspect -./scripts/sync-utils.sh push # repo β†’ config -./scripts/sync-utils.sh pull # config β†’ repo -./scripts/sync-utils.sh auto # safe one-way sync or conflict refusal -``` +Never commit: -CLI equivalents: +- absolute contributor paths; +- tokens, credentials, private keys, or secret config values; +- user-specific OpenCode configuration; +- transient local tool state. -```bash -openzeus sync status -openzeus sync auto -``` +Resolve user paths at runtime from OpenCode context/environment instead. + +## Commit style -## Commit Style +Use small, imperative commits that describe one coherent change. -Use clear, imperative commit messages: +Examples: ```text -docs(readme): update install flow -fix(commands): require push confirmation -feat(skills): add zeus-example skill +feat: add runtime provenance check +fix: preserve agent permission ordering +docs: clarify plugin bootstrap ``` -## Pull Requests +## Pull requests -- Explain what changed and why. -- Include validation output. -- Note any sync or install behavior changes. -- Do not include secrets, generated caches, or unrelated formatting churn. +- explain the user-visible reason for the change; +- include or reference tests for behavior changes; +- note compatibility/migration impact; +- do not include unrelated formatting churn. ## License diff --git a/docs/PUBLISHING.md b/docs/PUBLISHING.md index d939c62..49ca413 100644 --- a/docs/PUBLISHING.md +++ b/docs/PUBLISHING.md @@ -1,57 +1,103 @@ # Publishing OpenZeus -OpenZeus publishes the `openzeus` npm package. Current package version: **1.2.0**. +OpenZeus publishes the `openzeus` npm package. + +Stable public baseline: **1.2.0**. Target release: **2.0.0**. + +2.0.0 is intentionally breaking: it removes the 1.x generic/config-manager surface and moves skills/runtime integration to the native OpenCode V2 plugin. + +## Preconditions + +Do not publish from a refocus branch until the release/version decision is +explicitly approved. + +The release commit must have green CI for the exact SHA. ## Preflight +Use Node **22.19+** for the package toolchain. + ```bash +npm install --ignore-scripts --no-audit --no-fund npm test -openzeus validate --ci -openzeus doctor --ci -openzeus diff --summary --ci +node tests/plugin.mjs +./bin/openzeus validate --ci npm pack --dry-run +npm publish --dry-run ``` -Confirm the package includes the expected assets: +Expected package contents include: + +- `src/plugin.js` β€” native OpenCode V2 plugin entrypoint; +- `agents/OpenZeus.md` β€” transitional agent bootstrap; +- `skills/` β€” five focused skills loaded by the plugin; +- `bin/openzeus` β€” extensionless npm CLI executable; +- `scripts/audit.mjs`; +- `scripts/inspect.mjs`; +- `scripts/migrate.mjs`; +- `scripts/create-utils.sh`; +- `scripts/install-agent.sh`; +- `scripts/validate.sh`; +- `README.md`; +- `LICENSE`; +- `package.json`. + +Do not ship `.beads/`, local config, credentials, tests, or contributor-only +state. -- `bin/openzeus` -- `agents/` -- `commands/` -- `docs/` -- `skills/` -- `scripts/` -- `tests/` +## Local package smoke test -## Local Package Test +After `npm pack`, install the generated `openzeus-2.0.0.tgz` tarball into an isolated prefix or test environment. + +At minimum verify: ```bash -npm pack -npm install -g ./openzeus-1.2.0.tgz openzeus help -openzeus install --core --dry-run -openzeus install --all --dry-run -openzeus setup --plan --recipe node --target /tmp/openzeus-publish-smoke +openzeus audit --help +openzeus inspect --help +openzeus migrate --help openzeus validate --ci -openzeus doctor --fix-plan -openzeus diff --summary + +export OPENCODE_CONFIG_DIR="$(mktemp -d)" +openzeus install-agent +cmp agents/OpenZeus.md "$OPENCODE_CONFIG_DIR/agents/OpenZeus.md" ``` +The native plugin entrypoint is covered independently by +`node tests/plugin.mjs` against the real `@opencode/plugin` dependency. + ## Publish -Publishing mutates the npm registry. Do it only from a clean worktree and with explicit maintainer approval. +Publishing mutates the npm registry. Require explicit maintainer authorization. ```bash -npm login +npm whoami npm publish +npm view openzeus version ``` -## After Publish +## OpenCode runtime verification + +Only after the new npm version is confirmed live: ```bash -npm view openzeus version -npm install -g openzeus -openzeus help -openzeus validate --ci +opencode plugin add openzeus +opencode plugin list +openzeus install-agent ``` -Update release notes in `docs/CHANGELOG.md` when cutting a release. +Start OpenCode and verify that: + +- the five `zeus-*` skills are present through the plugin's directory source; +- `@OpenZeus` loads from the bootstrapped agent file; +- `openzeus inspect --json` and `openzeus audit --json` return deterministic + filesystem diagnostics without printing credential values. + +## Release metadata + +After registry verification: + +1. create a tag pointing exactly at the green release commit; +2. create the matching GitHub Release; +3. verify npm latest, tag, release and CI all point to the intended version; +4. update `docs/CHANGELOG.md`. diff --git a/docs/continuity/openzeus-2.md b/docs/continuity/openzeus-2.md new file mode 100644 index 0000000..6e84fed --- /dev/null +++ b/docs/continuity/openzeus-2.md @@ -0,0 +1,134 @@ +# OpenZeus 2 Continuity + +This document is the canonical handoff for the OpenZeus refocus campaign. + +## Current state + +- Repository: `Aveer/OpenZeus` +- Default branch: `main` +- Stable baseline: `v1.2.0` +- Target refocus release: `2.0.0` +- Baseline commit: `aebb1a323bb02a1f7c5e0d4fc81c856f05a8400f` +- Active branch: `refactor/openzeus-2-agent-first` +- Active phase: release review β€” 2.0.0 prepared; merge/publish not performed +- Detailed plan: [docs/plans/openzeus-2-refocus.md](../plans/openzeus-2-refocus.md) + +## Canonical product decision + +OpenZeus is an OpenCode companion agent, not a replacement for OpenCode. + +Its durable differentiator should be understanding the user's effective +OpenCode environment: discovery, provenance, precedence, diagnostics, +compatibility/migration and high-quality OpenCode asset design. + +The agent is the primary interface. CLI/plugin code supplies deterministic +tools to the agent. + +## Architectural decisions + +1. **Native-first.** Reuse OpenCode's own capabilities instead of cloning them. +2. **Runtime discovery.** No private absolute paths in repository content. +3. **Small core.** Skills must directly serve OpenCode operation/authoring. +4. **No documentation mirrors for unrelated plugins.** External integrations + belong outside core unless they become real maintained adapters. +5. **Inspection before mutation.** Plans and diagnostics precede writes. +6. **Plugin is the target distribution architecture.** Existing copy/install + scripts are transitional until the plugin path is proven. +7. **Do not delete transitional infrastructure prematurely.** Remove it only + when replacement behavior has tests and an explicit migration path. + +## Phase 1 result + +The shipped skill set is now intentionally limited to: + +- `zeus-diagnostics` +- `zeus-migration` +- `zeus-agents` +- `zeus-commands` +- `zeus-skills` + +Removed from core: +- generic Docker / SQL / local-LLM / Boston Terrier knowledge; +- copied Beads / swarm / OAC / OMO integration documentation; +- broad `zeus-core` documentation mirror; +- `zeus-upskill` meta-skill; +- generic conversation-context `zeus-context`; +- pseudo-runtime-introspection `zeus-self`. + +OpenZeus-owned agent frontmatter now uses current ordered `permissions` +rules and no longer pins a model, temperature or step budget. + +## Invariants + +- never add contributor-specific paths, credentials or personal config data; +- do not mutate `main` during the campaign; +- keep branch CI green at coherent checkpoints; +- do not introduce another task/evidence layer outside this continuity file, + the canonical plan and normal Git history; +- do not publish npm or create a release from this branch without an explicit + release decision. + +## Next actions + +1. Keep migration apply disabled until there is a parser-backed, backup/rollback-safe implementation. +2. Tighten live-runtime + filesystem evidence reconciliation. +3. Do a final repository/product audit after the refocus. +4. Finalize OpenZeus 2 packaging/docs and decide the breaking-release version. + +## Last updated + +2026-10-04 β€” Phases 1–3 are effectively complete; audit and native V2 plugin prototype are CI-green; migration planning is next. + +- 2026-10-04 β€” first deterministic filesystem inspector implemented with JSON + output, precedence/collision reporting and legacy warnings; live-runtime gaps + are explicit limitations. + +- 2026-10-04 β€” generator/validator compatibility pass moved OpenZeus-owned + agent templates to native V2 ordered permissions and made package/project + validation reject legacy agent/command fields. + +- 2026-10-04 β€” removed bundled generic slash commands and collapsed the old + core/extras content split. OpenZeus still designs/creates commands, but does + not ship unrelated project-management/Git workflows. + +- 2026-10-04 β€” removed generic project-bootstrap/capture surface + (`setup`, `init-project`, recipes, context-init, capture-command) after + confirming OpenCode's native `/init` owns project analysis and AGENTS.md + initialization. + +- 2026-10-04 β€” added `openzeus audit` as the first user-facing diagnostic + workflow on top of inspector evidence; `--ci` fails only on warning/error + findings while shadowing/info remains informational. + +- 2026-10-04 β€” started native V2 plugin packaging using `@opencode/plugin`. + Plugin registers the packaged `skills/` directory as a native skill source. Upstream `AgentEditor` currently has no `add()`, so the @OpenZeus + agent remains the only transitional copy-installed asset. + +- 2026-10-04 β€” native plugin prototype passed CI against real + `@opencode-ai/plugin/v2/promise`; retired old sync/hooks/doctor/diff/upgrade/rollback + and skill-copy installation. Only the @OpenZeus agent bootstrap remains due + to the upstream AgentEditor.add limitation. + +- 2026-10-04 β€” repository hygiene follow-up: canonical plans moved under + `docs/plans/`; tracked `.beads/` state removed and ignored. + +- 2026-10-04 β€” implemented CI-covered `openzeus migrate --plan`; it maps + inspector legacy findings to explicit V2 migration actions and refuses + `--apply`. No migration action is currently automatic. + +- 2026-10-04 β€” package/CI baseline raised to Node 22.19+ to match the V2 + plugin dependency chain; stale 1.x publishing/contributing docs replaced. + +- 2026-10-04 β€” final branch-text audit removed stale 1.x helper references + from the agent and replaced legacy agent/repository atlases with the current + V2 plugin/audit/migration architecture. + +- 2026-10-04 β€” breaking-release decision made: refocus branch prepared as + OpenZeus 2.0.0. No merge, npm publish, tag, or GitHub Release has been + performed. + +- 2026-10-04 β€” final source-level check against `anomalyco/opencode@dev` + corrected the V2 plugin contract: dependency/import now use + `@opencode-ai/plugin/v2/promise`; plugin registers a directory skill source. + Removed the mock-only `openzeus_runtime` concept because current Promise + PluginContext exposes no custom-tool/app/location domains. diff --git a/docs/plans/openzeus-2-refocus.md b/docs/plans/openzeus-2-refocus.md new file mode 100644 index 0000000..9713850 --- /dev/null +++ b/docs/plans/openzeus-2-refocus.md @@ -0,0 +1,294 @@ +# OpenZeus 2 Refocus Plan + +Status: implementation complete for review β€” target release 2.0.0 +Branch: `refactor/openzeus-2-agent-first` +Baseline release: `v1.2.0` +Baseline main: `aebb1a323bb02a1f7c5e0d4fc81c856f05a8400f` + +## Product definition + +OpenZeus is an OpenCode companion agent. Its job is to understand the user's +actual OpenCode environment, diagnose configuration and discovery problems, +help design OpenCode assets, and safely evolve older setups. + +OpenZeus is not a replacement for OpenCode, a general developer framework, or +a generic knowledge pack. + +## North-star experience + +The primary interface is conversational: + +```text +@OpenZeus why is this agent not loading? +@OpenZeus where did this skill come from? +@OpenZeus which config wins here? +@OpenZeus audit my OpenCode setup. +@OpenZeus migrate this old agent to the current format. +@OpenZeus design a portable skill for this workflow. +``` + +The CLI exists to give the agent deterministic inspection, validation and +migration primitives. Users should not need to learn a large CLI surface. + +## Target architecture + +```text +OpenCode native config / agents / skills / commands / plugins + | + v + OpenZeus plugin + | + +-------------+-------------+ + | | | + v v v + inspector diagnostics migrations + | | | + +-------------+-------------+ + | + @OpenZeus agent + | + focused authoring skills +``` + +### Runtime discovery + +Never commit user-specific absolute paths. Resolve environment locations at +runtime from OpenCode-provided context where possible, then environment +variables such as `OPENCODE_CONFIG_DIR` / `XDG_CONFIG_HOME`, then portable +platform defaults. + +### Native-first rule + +Do not duplicate OpenCode functionality that OpenCode already provides well. +Prefer OpenCode's current schema, built-in configuration knowledge and native +commands. OpenZeus adds value through environment inspection, provenance, +diagnostics, migrations and higher-level asset design. + +## Current surface disposition + +| Current component | Target | +|---|---| +| `agents/OpenZeus.md` | KEEP; make it a thin agent-first interface | +| `zeus-diagnostics` | KEEP; focused runtime/config diagnosis | +| `zeus-migration` | KEEP; focused compatibility/migration workflow | +| `zeus-agents` | KEEP; advanced design only, native creator for basic scaffolding | +| `zeus-skills` | KEEP; skill authoring remains a differentiator | +| `zeus-commands` | KEEP; focused command design/review | +| `zeus-core` | DELETE; broad OpenCode doc mirror replaced by schema/native knowledge | +| `zeus-upskill` | DELETE; meta-skill proliferation removed | +| `zeus-context` | DELETE; generic conversation-context management is not OpenCode core | +| `zeus-self` | DELETE; pseudo-introspection replaced by deterministic diagnostics | +| `zeus-boston-terrier` | DELETE | +| `zeus-docker` | DELETE | +| `zeus-sql` | DELETE | +| `zeus-llm` | DELETE | +| `zeus-beads` | DELETE from core | +| `zeus-swarm` | DELETE from core | +| `zeus-oac` | DELETE from core | +| `zeus-omo` | DELETE from core | +| generic repo/config sync | REPLACE with runtime state/manifest model | +| `doctor`, `diff`, `validate` | KEEP internally; converge user UX toward `audit` | +| `setup` / `init-project` / recipes | REASSESS against native OpenCode init/customization | +| `upgrade` | REDEFINE; current behavior is refresh/reinstall, not package upgrade | + +## Phases + +### Phase 1 β€” Identity and scope reduction β€” COMPLETE + +Goal: make the repository describe and ship one coherent product. + +Deliverables: +- rewrite README around the agent-first value proposition; +- rewrite OpenZeus agent prompt around discovery/diagnosis/design; +- remove clearly unrelated/general-purpose skills; +- remove external-plugin documentation skills from core; +- update tests, installer inventories and docs accordingly; +- keep CI green. + +Exit criteria: a new user can explain OpenZeus in one sentence after reading +the first README screen, and the installed core contains only OpenCode-related +capabilities. + +### Phase 2 β€” Current OpenCode compatibility β€” COMPLETE + +Goal: stop maintaining stale OpenCode conventions. + +Deliverables: +- audit current OpenCode schemas and built-ins; +- migrate OpenZeus-owned assets to current native formats; +- remove hard-coded model choice unless technically required; +- replace stale config-path assumptions; +- add contract tests for generated agent/skill/command assets. + +Exit criteria: OpenZeus-generated assets are native-current rather than +legacy-compatible by translation. + +### Phase 3 β€” Inspector / provenance foundation β€” COMPLETE + +Goal: understand the user's effective OpenCode environment. + +Deliverables: +- inventory global + project config; +- inventory discovered agents, skills, commands and plugins; +- report source/provenance and precedence; +- detect name collisions/shadowing; +- expose deterministic machine-readable inspection output. + +Exit criteria: `@OpenZeus` can answer β€œwhere did this come from?” from +runtime evidence. + +### Phase 4 β€” Audit and migration UX β€” PLAN-ONLY IMPLEMENTED + +Goal: turn inspection into useful maintenance. + +Deliverables: +- introduce `openzeus audit` as the human-facing diagnostic command; +- detect legacy/deprecated forms; +- add `openzeus migrate --plan`; **implemented** +- add guarded apply + backup + validation + rollback. + +Exit criteria: OpenZeus can detect and safely plan at least one real OpenCode +migration end-to-end. + +### Phase 5 β€” Native plugin packaging β€” PROTOTYPE CI-GREEN + +Goal: make installation and runtime integration OpenCode-native. + +Deliverables: +- implement OpenCode plugin entrypoint; +- register the focused skills through the current plugin API; +- minimize or retire copy-based global installation; +- replace repo/config sync with an OpenZeus state/manifest model. + +Exit criteria: normal users can install OpenZeus as an OpenCode plugin without +manually copying agent/skill files into private machine-specific paths. + +### Phase 6 β€” CLI and repository simplification β€” SUBSTANTIALLY COMPLETE + +Goal: remove transitional machinery after the plugin path is proven. + +Deliverables: +- collapse redundant CLI commands; +- move maintainer-only sync/dev helpers out of user-facing UX; +- remove deprecated profiles/workflows; +- update packaging, tests, docs and release process. + +## Non-goals + +- replacing OpenCode; +- becoming a generic AI/developer toolkit; +- maintaining copied documentation for unrelated plugins; +- bundling generic Docker/SQL/LLM knowledge; +- encoding any contributor's private machine paths; +- adding features merely because they can be represented as a skill. + +## Release strategy + +Do not publish a refocus release until at least Phase 1 and the current-format +compatibility work in Phase 2 are coherent. Breaking surface removal is documented explicitly. The actual diff warrants a major release; target version is `2.0.0`. + + +## Progress update β€” 2026-10-04 + +Phase 1 is complete on the refocus branch. + +Completed: +- rewritten README around the companion-agent value proposition; +- moved the OpenZeus agent to current ordered `permissions` syntax; +- removed hard-coded model/request tuning from the OpenZeus agent; +- removed 12 unrelated, integration-copy, broad/meta or pseudo-introspection skills; +- consolidated the shipped skill set to five focused capabilities: + `zeus-diagnostics`, `zeus-migration`, `zeus-agents`, + `zeus-commands`, `zeus-skills`; +- enabled branch CI and restored a fully green validation pipeline. + +Next implementation slice: +- finish Phase 4 with deterministic `openzeus migrate --plan`; +- keep apply disabled until migrations are parser-backed and rollback-safe; +- then finalize package/docs for the OpenZeus 2 breaking release. + + +## Plugin constraint discovered β€” 2026-10-04 + +Current OpenCode V2 Promise plugins can add skill sources and transform existing domains, but +`AgentEditor` exposes no `add()`. Therefore OpenZeus cannot yet ship the +`@OpenZeus` agent purely through the plugin API. + +Interim target: +- plugin owns focused skills; +- agent file remains the only required copy/bootstrap artifact; +- remove that bootstrap once upstream supports plugin agent registration. + + +## Copy-management retirement β€” 2026-10-04 + +After the corrected V2 plugin entrypoint passed CI against the real `@opencode-ai/plugin/v2/promise` API, OpenZeus retired its old repo/config package-management layer. + +Removed: +- bidirectional sync; +- sync Git hooks; +- bundle doctor/diff; +- bundle refresh/upgrade and rollback; +- copy-install of skills. + +The only transitional copy operation is `install-agent`, required solely +because current OpenCode V2 plugins cannot add agents. + + +## Repository layout decision β€” 2026-10-04 + +Canonical architecture plans live under `docs/plans/`; continuity lives under +`docs/continuity/`. Local tracker state such as `.beads/` is intentionally +untracked. + +`bin/openzeus` remains extensionless intentionally: it is the Unix/npm +executable entrypoint installed as the `openzeus` command. Implementation +modules use normal extensions (`.js`, `.mjs`, `.sh`). + + +## Migration safety decision β€” 2026-10-04 + +`openzeus migrate --plan` is implemented and CI-covered. + +`--apply` deliberately returns an error and performs no mutations. Apply will +not be implemented as text substitution; each supported migration needs: + +1. parser-backed source understanding; +2. an exact change plan; +3. backup; +4. post-change validation; +5. rollback on validation failure. + + +## Release decision β€” 2026-10-04 + +The refocus is a breaking release and is prepared as **OpenZeus 2.0.0**. + +Reasons for the major version: +- most 1.x generic/config-manager CLI commands were removed; +- the shipped skill set was reduced from broad/general integrations to five + focused OpenCode skills; +- native OpenCode V2 plugin delivery is now the primary architecture; +- the old copy-installed skill/config lifecycle was retired; +- migration apply remains intentionally unavailable until it is safe. + +Merge and publication are separate, explicit steps after review. + + +## Plugin API correction β€” 2026-10-04 + +A final source-level audit against `anomalyco/opencode@dev` corrected an +earlier prototype assumption. + +The actual current V2 Promise API is exported from: + +```text +@opencode-ai/plugin/v2/promise +``` + +Its skill editor registers `SkillV2Source` entries, so OpenZeus registers the +packaged `skills/` directory as one directory source. + +The current Promise `PluginContext` has no custom `tool`, `app`, or +`location` domains. Therefore the earlier prototype `openzeus_runtime` idea +was removed rather than shipping against a mock-only contract. diff --git a/package.json b/package.json index 20d3ce6..bd00992 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,16 @@ { "name": "openzeus", - "version": "1.2.0", - "description": "OpenCode operator kit with agents, skills, commands, and safe sync utilities", - "main": "bin/openzeus", + "version": "2.0.0", + "description": "OpenCode companion agent for workspace diagnostics, migration, and asset design", + "main": "./src/plugin.js", "keywords": [ "opencode", - "ai-agent", + "ai-agent", "configuration", - "automation", + "diagnostics", "skills", - "commands", - "zeus", - "ai-assistant", - "code-generation" + "agents", + "developer-tools" ], "author": "OpenZeus Project ", "license": "MIT", @@ -25,17 +23,15 @@ "url": "https://github.com/Aveer/OpenZeus.git" }, "files": [ + "src/", "bin/", "agents/", "skills/", - "commands/", - "docs/", "media/", - "scripts/", - "tests/" + "scripts/" ], "engines": { - "node": ">=16.0.0" + "node": ">=22.19.0" }, "scripts": { "test": "tests/run.sh" @@ -47,5 +43,12 @@ "darwin", "linux" ], - "preferGlobal": true + "preferGlobal": true, + "type": "module", + "exports": { + ".": "./src/plugin.js" + }, + "dependencies": { + "@opencode-ai/plugin": "1.18.34" + } } diff --git a/scripts/audit.mjs b/scripts/audit.mjs new file mode 100755 index 0000000..30a1a39 --- /dev/null +++ b/scripts/audit.mjs @@ -0,0 +1,143 @@ +#!/usr/bin/env node +import { execFileSync } from "node:child_process"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const here = path.dirname(fileURLToPath(import.meta.url)); +const inspectScript = path.join(here, "inspect.mjs"); + +function usage() { + process.stdout.write( + "Usage: openzeus audit [--target DIR] [--json] [--ci]\n\n" + + "Summarize actionable OpenCode findings from OpenZeus inspection.\n" + ); +} + +function parseArgs(argv) { + let target = process.cwd(); + let json = false; + let ci = false; + for (let i = 0; i < argv.length; i += 1) { + const arg = argv[i]; + if (arg === "--json") json = true; + else if (arg === "--ci") ci = true; + else if (arg === "--target") { + const value = argv[i + 1]; + if (!value || value.startsWith("--")) throw new Error("Missing value for --target"); + target = value; + i += 1; + } else if (arg === "-h" || arg === "--help") { + usage(); + process.exit(0); + } else { + throw new Error("Unknown option: " + arg); + } + } + return { target: path.resolve(target), json, ci }; +} + +function recommendation(finding) { + if (finding.code === "asset_shadowing") { + return "Inspect the winning and shadowed sources before changing either definition."; + } + if (finding.code === "legacy_tui_config") { + return "Review migration to the global V2 cli.json client configuration."; + } + if (finding.code.startsWith("legacy_agent_")) { + return "Review this agent with @OpenZeus and migrate only the legacy field(s) that affect current behavior."; + } + if (finding.code === "legacy_command_subtask") { + return "Replace legacy subtask with native V2 subagent after verifying intended execution behavior."; + } + if (finding.code === "skill_missing_description") { + return "Add a trigger-oriented skill description so OpenCode can advertise the skill reliably."; + } + return null; +} + +let args; +try { + args = parseArgs(process.argv.slice(2)); +} catch (error) { + console.error(String(error.message || error)); + usage(); + process.exit(2); +} + +let inspection; +try { + const output = execFileSync(process.execPath, [ + inspectScript, + "--target", + args.target, + "--json" + ], { + encoding: "utf8", + stdio: ["ignore", "pipe", "inherit"] + }); + inspection = JSON.parse(output); +} catch (error) { + console.error("OpenZeus audit could not complete inspection."); + process.exit(2); +} + +const findings = inspection.warnings.map((item) => ({ + ...item, + recommendation: recommendation(item) +})); + +const warningCount = findings.filter((item) => item.severity === "warning" || item.severity === "error").length; +const infoCount = findings.filter((item) => item.severity === "info").length; +const status = warningCount > 0 ? "warning" : "ok"; + +const result = { + schemaVersion: 1, + status, + target: inspection.target, + workspaceRoot: inspection.workspaceRoot, + summary: { + warnings: warningCount, + info: infoCount, + collisions: inspection.collisions.length, + agents: inspection.inventory.agents.length, + skills: inspection.inventory.skills.length, + commands: inspection.inventory.commands.length, + plugins: inspection.inventory.plugins.length + }, + findings, + limitations: inspection.limitations +}; + +if (args.json) { + process.stdout.write(JSON.stringify(result, null, 2) + "\n"); +} else { + console.log("OpenZeus audit"); + console.log("Status: " + status); + console.log( + "Inventory: " + + result.summary.agents + " agents, " + + result.summary.skills + " skills, " + + result.summary.commands + " commands, " + + result.summary.plugins + " local plugins" + ); + console.log( + "Findings: " + + result.summary.warnings + " warning(s), " + + result.summary.info + " info" + ); + + if (!findings.length) { + console.log("\nNo filesystem-visible OpenCode issues detected."); + } else { + console.log("\nFindings"); + for (const finding of findings) { + console.log("- [" + finding.severity + "] " + finding.message); + console.log(" " + finding.path); + if (finding.recommendation) console.log(" Next: " + finding.recommendation); + } + } + + console.log("\nBoundary: " + inspection.limitations[0]); +} + +if (args.ci && warningCount > 0) process.exit(1); diff --git a/scripts/capture-command.sh b/scripts/capture-command.sh deleted file mode 100755 index 89bdc48..0000000 --- a/scripts/capture-command.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash -set -euo pipefail - -name="" -prompt="" -target_dir="${OPENCODE_CONFIG_DIR:-${OPENZEUS_CONFIG_DIR:-${HOME}/.config/opencode}}" -dry_run=false -force=false - -while [[ $# -gt 0 ]]; do - case "$1" in - --name) [[ $# -ge 2 && "$2" != --* ]] || { echo "Missing value for --name" >&2; exit 1; }; name="$2"; shift ;; - --prompt) [[ $# -ge 2 && "$2" != --* ]] || { echo "Missing value for --prompt" >&2; exit 1; }; prompt="$2"; shift ;; - --target) [[ $# -ge 2 && "$2" != --* ]] || { echo "Missing value for --target" >&2; exit 1; }; target_dir="$2"; shift ;; - --dry-run) dry_run=true ;; - --force) force=true ;; - -h|--help) echo "Usage: capture-command.sh --name NAME --prompt TEXT [--target DIR] [--dry-run] [--force]"; exit 0 ;; - *) echo "Unknown option: $1" >&2; exit 1 ;; - esac - shift -done - -[[ "$name" =~ ^[a-z0-9][a-z0-9._-]*$ ]] || { echo "Invalid name: $name" >&2; exit 1; } -[[ -n "$prompt" ]] || prompt="$(cat)" -[[ -n "$name" && -n "$prompt" ]] || { echo "missing name/prompt" >&2; exit 1; } - -path="$target_dir/commands/$name.md" -desc="Generated command for ${name//-/ } from prompt" -content=$(cat < "$path" -echo "Created $path" diff --git a/scripts/codemap.md b/scripts/codemap.md deleted file mode 100644 index e84e3b6..0000000 --- a/scripts/codemap.md +++ /dev/null @@ -1,131 +0,0 @@ -# scripts/ β€” Runtime Management Module - -## Responsibility - -The `scripts/` directory powers the product-facing OpenZeus CLI. It installs profile-aware OpenCode assets, plans/applies project setup, validates package/config/project assets, captures commands from prompts, initializes context files, compares repo/config drift, and upgrades or rolls back local config safely. - -OpenZeus scripts prefer **plan-before-mutation** behavior: inspect first, preview when possible, skip overwrites by default, and require `--force` for replacement. - -## Entry Points - -| File | Role | -|---|---| -| `../bin/openzeus` | User-facing command dispatcher | -| `install.sh` | Safe install into `${OPENCODE_CONFIG_DIR:-~/.config/opencode}` or `--target DIR` | -| `sync-utils.sh` | Manifest-limited repo/config compare and sync | -| `create-utils.sh` | Generate OpenCode agents, skills, and commands | -| `doctor.sh` | Non-mutating package/config health checks and `--fix-plan` guidance | -| `init-project.sh` | Safe project-local `.opencode/` starter generator | -| `setup.sh` | `setup --plan|--apply`, `recipes`, and `context init` workflows | -| `validate.sh` | Package, config, and project asset validation with `--ci` mode | -| `capture-command.sh` | Prompt-to-command Markdown generator | -| `diff.sh` | Profile-aware package/config drift report with `--summary` and `--ci` | -| `upgrade.sh` | Profile-preserving local config backup, upgrade, and rollback | -| `setup-hooks.sh` | Optional git hooks for post-merge sync and pre-push drift warning | - -## User-Facing CLI - -`bin/openzeus` wraps the scripts with outcome-oriented commands: - -| Command | Behavior | -|---|---| -| `openzeus setup --plan|--apply [--recipe node|python|docs|beads|solo-dev] [--target DIR] [--dry-run] [--force]` | Plan or write repo-local `.opencode/` starter assets and context files | -| `openzeus validate [--ci] [--project DIR]` | Validate package/config or project assets; CI mode exits non-zero on failures/drift | -| `openzeus capture-command --name NAME --prompt TEXT [--target DIR] [--dry-run] [--force]` | Generate `/commands/NAME.md` from prompt text | -| `openzeus recipes` | List supported setup recipes | -| `openzeus context init [--target DIR] [--dry-run] [--force]` | Write `.opencode/context/{architecture.md,commands.md,testing.md}` | -| `openzeus doctor [--fix-plan] [--ci]` | Validate package assets, detect profile-aware config/install drift, and optionally fail CI | -| `openzeus diff [--summary] [--ci]` | Show package/config drift; summary mode prints issue count | -| `openzeus upgrade --dry-run|--apply` | Back up managed config assets, then reinstall with the saved profile | -| `openzeus rollback --dry-run|--apply` | Restore the latest OpenZeus config backup | -| `openzeus status` | Show package root, config root, installed asset counts, and drift summary | -| `openzeus list [agents|skills|commands|all]` | List package assets with `[installed]`, `[missing]`, or `[different]` status | -| `openzeus examples` | Print copy-pasteable starter workflows | -| `openzeus init-project [--target DIR] [--dry-run] [--force]` | Create repo-local `.opencode/` starter files safely | -| `openzeus install [--dry-run] [--force] [--backup] [--core|--extras|--all] [--target DIR]` | Install OpenZeus global assets by profile | -| `openzeus sync status|push|pull|auto` | Compare or copy repo/config OpenZeus assets | -| `openzeus create agent|skill|command ...` | Generate valid OpenCode Markdown assets | -| `openzeus hooks [--dry-run] [--force]` | Install optional git hooks | - -## Safety Defaults - -- `install.sh` and `sync-utils.sh` skip conflicting destination files unless `--force` is supplied. -- `--backup` preserves overwritten files/directories with timestamped `.bak.*` names. -- `install.sh` always installs `agents/OpenZeus.md` and helper scripts. `--core`, `--extras`, and `--all` filter only `skills/zeus-*` and `commands/zeus-*.md`. -- `install.sh` writes `.openzeus-install-profile`; `doctor.sh`, `diff.sh`, and `upgrade.sh` respect it. -- `init-project.sh` skips existing starter files unless `--force` is supplied. -- `setup.sh --plan`, `doctor.sh --fix-plan`, `openzeus recipes`, `openzeus status/list/examples`, and `diff.sh` never mutate files. -- `validate.sh --ci`, `doctor.sh --ci`, and `diff.sh --ci` use non-zero exits for automation. -- `capture-command.sh --dry-run` previews the destination and writes nothing; existing commands are skipped unless `--force` is supplied. -- `upgrade.sh --dry-run` and `rollback --dry-run` preview backup/restore actions. `--apply` is required to mutate config. -- `upgrade.sh --apply` creates a local backup under `.openzeus-backups` and reinstalls with the saved profile. -- `sync-utils.sh auto` only syncs when direction is unambiguous; mixed or conflicting changes are refused. -- Git `pre-push` hook runs sync status only; it does not mutate or push Beads/Git state. - -## Asset Scope - -OpenZeus intentionally manages only its own package assets: - -| Asset type | Managed pattern | -|---|---| -| Agent | `agents/OpenZeus.md` | -| Skills | `skills/zeus-*` | -| Commands | `commands/zeus-*.md` | -| Helpers | `sync-utils.sh`, `create-utils.sh`, `setup-hooks.sh`, `doctor.sh`, `init-project.sh`, `setup.sh`, `validate.sh`, `capture-command.sh`, `diff.sh`, `upgrade.sh` | -| Install profile | `.openzeus-install-profile` | - -This namespace boundary protects unrelated user agents, skills, and commands. - -## Project Setup Output - -`openzeus setup --apply` wraps `init-project`, recipe extras, and context initialization. It writes starter project-local assets under `/.opencode/`: - -```text -.opencode/ -β”œβ”€β”€ README.md -β”œβ”€β”€ agents/project-guide.md -β”œβ”€β”€ commands/build.md -β”œβ”€β”€ commands/test.md -β”œβ”€β”€ context/architecture.md -β”œβ”€β”€ context/commands.md -β”œβ”€β”€ context/testing.md -└── skills/project-context/SKILL.md -``` - -The generated files use current OpenCode conventions: Markdown frontmatter, `mode: subagent` for the starter agent, conservative `permission` defaults, command templates using `$ARGUMENTS`, and skill `name`/`description` frontmatter. `setup.sh` detects `package.json`, `Makefile`/`makefile`, and Python project files (`pyproject.toml`, `setup.cfg`, `setup.py`) to pre-fill likely commands such as `npm test`, `npm run build`, `make test`, `make build`, or `pytest` when available. - -Recipes add focused command/context hints: - -| Recipe | Adds | -|---|---| -| `node` | npm test/build defaults | -| `python` | pytest-first test notes | -| `docs` | docs review command | -| `beads` | Beads status command | -| `solo-dev` | lightweight session check | - -## Sync Model - -`sync-utils.sh` builds a manifest from the package repo and config directory, compares files byte-for-byte (`cmp`) and skill directories recursively (`diff -qr`), then reports: - -- `OK ` β€” both sides match -- `DIFF ` β€” both sides exist but differ -- `MISSING config:` β€” repo asset is not installed -- `MISSING repo:` β€” config asset is not present in repo - -`push` copies repo β†’ config, `pull` copies config β†’ repo, and `auto` chooses a safe one-way direction only when there are no ambiguous conflicts. - -## Verification - -Primary quality gate: - -```bash -npm test -openzeus validate --ci -openzeus doctor --ci -openzeus diff --summary --ci -npm pack --dry-run -git diff --check -``` - -`tests/run.sh` performs per-script Bash syntax checks, fixture installs/syncs, create-template checks, doctor/status/list/examples smoke tests, init-project overwrite tests, and CLI symlink resolution checks. diff --git a/scripts/create-utils.sh b/scripts/create-utils.sh index cb39505..2e9e3e0 100755 --- a/scripts/create-utils.sh +++ b/scripts/create-utils.sh @@ -132,9 +132,13 @@ case "$type" in write_file "$(target_root)/agents/$name.md" "--- description: $(yaml_quote "$description") mode: subagent -permission: - edit: ask - bash: ask +permissions: + - action: edit + resource: "*" + effect: ask + - action: shell + resource: "*" + effect: ask --- You are $name, a focused OpenCode subagent. diff --git a/scripts/diff.sh b/scripts/diff.sh deleted file mode 100755 index 07831db..0000000 --- a/scripts/diff.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash -set -euo pipefail - -summary=false -ci=false -while [[ $# -gt 0 ]]; do - case "$1" in - --summary) summary=true ;; - --ci) ci=true ;; - -h|--help) echo "Usage: diff.sh [--summary] [--ci]"; exit 0 ;; - esac - shift -done - -root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -config="${OPENCODE_CONFIG_DIR:-${OPENZEUS_CONFIG_DIR:-${HOME}/.config/opencode}}" -install_profile="all" -[[ -f "$config/.openzeus-install-profile" ]] && IFS= read -r install_profile < "$config/.openzeus-install-profile" - -should_include_skill() { - local name="$1" - case "$install_profile" in - core) [[ "$name" == zeus-core || "$name" == zeus-agents || "$name" == zeus-commands || "$name" == zeus-skills || "$name" == zeus-upskill || "$name" == zeus-context ]] ;; - extras) [[ "$name" != zeus-core && "$name" != zeus-agents && "$name" != zeus-commands && "$name" != zeus-skills && "$name" != zeus-upskill && "$name" != zeus-context ]] ;; - *) return 0 ;; - esac -} - -should_include_command() { - local name="$1" - case "$install_profile" in - core) [[ "$name" == zeus-git-commit.md || "$name" == zeus-improve-project.md ]] ;; - extras) [[ "$name" != zeus-git-commit.md && "$name" != zeus-improve-project.md ]] ;; - *) return 0 ;; - esac -} - -out="$($root/scripts/sync-utils.sh --repo "$root" --config "$config" status || true)" -issues=() -while IFS= read -r line; do - case "$line" in - MISSING\ config:skills/zeus-*) skill_name="${line#MISSING config:skills/}"; should_include_skill "$skill_name" && issues+=("$line") ;; - MISSING\ config:commands/zeus-*.md) command_name="${line#MISSING config:commands/}"; should_include_command "$command_name" && issues+=("$line") ;; - DIFF*|MISSING*) issues+=("$line") ;; - esac -done <<< "$out" - -extra=() -if [[ -d "$config/skills" ]]; then - for d in "$config/skills"/zeus-*; do [[ -d "$d" ]] || continue; [[ -d "$root/skills/$(basename "$d")" ]] || extra+=("EXTRA $(basename "$d")") ; done -fi -if [[ -d "$config/commands" ]]; then - for f in "$config/commands"/zeus-*.md; do [[ -f "$f" ]] || continue; [[ -f "$root/commands/$(basename "$f")" ]] || extra+=("EXTRA $(basename "$f")") ; done -fi - -for helper in sync-utils.sh create-utils.sh setup-hooks.sh doctor.sh init-project.sh setup.sh validate.sh capture-command.sh diff.sh upgrade.sh; do - pkg="$root/scripts/$helper" - cfg="$config/$helper" - if [[ ! -e "$cfg" ]]; then - issues+=("MISSING config:$helper") - elif [[ -f "$pkg" && -f "$cfg" ]]; then - cmp -s "$pkg" "$cfg" || issues+=("DIFF $helper") - [[ -x "$cfg" ]] || issues+=("DIFF $helper executable-bit") - else - issues+=("DIFF $helper type") - fi -done - -all=("${issues[@]}" "${extra[@]}") -if [[ "$summary" == true ]]; then - echo "${#all[@]} issue(s)" -else - printf '%s\n' "${all[@]}" -fi - -if [[ "$ci" == true ]]; then - [[ ${#all[@]} -eq 0 ]] -else - exit 0 -fi diff --git a/scripts/doctor.sh b/scripts/doctor.sh deleted file mode 100755 index f6d4fcb..0000000 --- a/scripts/doctor.sh +++ /dev/null @@ -1,218 +0,0 @@ -#!/bin/bash -set -euo pipefail - -root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -config_dir="${OPENCODE_CONFIG_DIR:-${OPENZEUS_CONFIG_DIR:-${HOME}/.config/opencode}}" -status=0 -fix_plan=false -ci=false -missing_executables=() -config_executable_fixes=() -warnings=0 -needs_install=false -needs_force_backup=false -needs_sync_status=false -install_profile="all" - -while [[ $# -gt 0 ]]; do - case "$1" in - --fix-plan) fix_plan=true ;; - --ci) ci=true ;; - -h|--help|help) echo "Usage: doctor.sh [--fix-plan]"; exit 0 ;; - esac - shift -done - -fail() { - echo "FAIL $1" - status=1 -} - -warn() { - echo "WARN $1" - warnings=$((warnings + 1)) -} - -contains() { - local file="$1" - local pattern="$2" - grep -q "$pattern" "$file" -} - -compare_installed_file() { - local label="$1" - local package_path="$2" - local config_path="$3" - - if [[ ! -e "$config_path" ]]; then - warn "$label missing from config: $config_path" - needs_install=true - return 0 - fi - - if [[ -f "$package_path" && -f "$config_path" ]]; then - if ! cmp -s "$package_path" "$config_path"; then - warn "$label differs in config: $config_path" - needs_force_backup=true - needs_sync_status=true - fi - return 0 - fi - - if [[ -d "$package_path" && -d "$config_path" ]]; then - if ! diff -qr "$package_path" "$config_path" >/dev/null; then - warn "$label differs in config: $config_path" - needs_force_backup=true - needs_sync_status=true - fi - return 0 - fi - - warn "$label differs in config: $config_path" - needs_force_backup=true - needs_sync_status=true -} - -if [[ -f "$config_dir/.openzeus-install-profile" ]]; then - IFS= read -r install_profile < "$config_dir/.openzeus-install-profile" || install_profile="all" -fi - -should_check_skill() { - local name="$1" - case "$install_profile" in - core) [[ "$name" == zeus-core || "$name" == zeus-agents || "$name" == zeus-commands || "$name" == zeus-skills || "$name" == zeus-upskill || "$name" == zeus-context ]] ;; - extras) [[ "$name" != zeus-core && "$name" != zeus-agents && "$name" != zeus-commands && "$name" != zeus-skills && "$name" != zeus-upskill && "$name" != zeus-context ]] ;; - *) return 0 ;; - esac -} - -should_check_command() { - local name="$1" - case "$install_profile" in - core) [[ "$name" == zeus-git-commit.md || "$name" == zeus-improve-project.md ]] ;; - extras) [[ "$name" != zeus-git-commit.md && "$name" != zeus-improve-project.md ]] ;; - *) return 0 ;; - esac -} - -first_line_is_frontmatter() { - local file="$1" - local first="" - [[ -f "$file" ]] || return 1 - IFS= read -r first < "$file" || true - [[ "$first" == "---" ]] -} - -for file in \ - "$root_dir/bin/openzeus" \ - "$root_dir/scripts/install.sh" \ - "$root_dir/scripts/sync-utils.sh" \ - "$root_dir/scripts/create-utils.sh" \ - "$root_dir/scripts/setup-hooks.sh" \ - "$root_dir/scripts/init-project.sh" \ - "$root_dir/scripts/setup.sh" \ - "$root_dir/scripts/validate.sh" \ - "$root_dir/scripts/capture-command.sh" \ - "$root_dir/scripts/diff.sh" \ - "$root_dir/scripts/upgrade.sh" \ - "$root_dir/scripts/doctor.sh"; do - if [[ ! -x "$file" ]]; then - fail "missing executable: $file" - missing_executables+=("${file#$root_dir/}") - fi -done - -[[ -f "$root_dir/agents/OpenZeus.md" ]] || fail "missing agents/OpenZeus.md" -first_line_is_frontmatter "$root_dir/agents/OpenZeus.md" || fail "agents/OpenZeus.md missing frontmatter" -contains "$root_dir/agents/OpenZeus.md" '^description:' || fail "agents/OpenZeus.md missing description" -contains "$root_dir/agents/OpenZeus.md" '^mode:' || fail "agents/OpenZeus.md missing mode" - -for skill in "$root_dir"/skills/zeus-*/SKILL.md; do - [[ -f "$skill" ]] || continue - first_line_is_frontmatter "$skill" || fail "$skill missing frontmatter" - contains "$skill" '^name:' || fail "$skill missing name frontmatter" - contains "$skill" '^description:' || fail "$skill missing description frontmatter" -done - -for command in "$root_dir"/commands/zeus-*.md; do - [[ -f "$command" ]] || continue - first_line_is_frontmatter "$command" || fail "$command missing frontmatter" - contains "$command" '^description:' || fail "$command missing description frontmatter" -done - -contains "$root_dir/package.json" '"openzeus"[[:space:]]*:[[:space:]]*"bin/openzeus"' || fail "package.json missing openzeus bin" -contains "$root_dir/package.json" '"postinstall"' && fail "package.json should not run mutating postinstall" - -if [[ ! -d "$config_dir" ]]; then - warn "OpenCode config dir absent: $config_dir (install will create it)" - needs_install=true -else - compare_installed_file "OpenZeus agent" "$root_dir/agents/OpenZeus.md" "$config_dir/agents/OpenZeus.md" - - for skill in "$root_dir"/skills/zeus-*/SKILL.md; do - [[ -f "$skill" ]] || continue - skill_name="$(basename "$(dirname "$skill")")" - should_check_skill "$skill_name" || continue - compare_installed_file "skill $skill_name" "$root_dir/skills/$skill_name" "$config_dir/skills/$skill_name" - done - - for command in "$root_dir"/commands/zeus-*.md; do - [[ -f "$command" ]] || continue - command_name="$(basename "$command")" - should_check_command "$command_name" || continue - compare_installed_file "command $command_name" "$root_dir/commands/$command_name" "$config_dir/commands/$command_name" - done - - for helper in sync-utils.sh create-utils.sh setup-hooks.sh doctor.sh init-project.sh setup.sh validate.sh capture-command.sh diff.sh upgrade.sh; do - helper_path="$config_dir/$helper" - compare_installed_file "helper $helper" "$root_dir/scripts/$helper" "$helper_path" - if [[ -f "$helper_path" && ! -x "$helper_path" ]]; then - warn "helper $helper is not executable in config: $helper_path" - config_executable_fixes+=("$helper_path") - fi - done -fi - -if [[ "$status" -eq 0 && "$warnings" -eq 0 ]]; then - echo "OpenZeus doctor: ok" -elif [[ "$status" -eq 0 ]]; then - echo "OpenZeus doctor: warnings" -fi - -if [[ "$fix_plan" == true ]]; then - echo "Suggested commands:" - suggestions=0 - if [[ "$needs_install" == true ]]; then - echo " openzeus install" - suggestions=$((suggestions + 1)) - fi - if [[ "$needs_force_backup" == true ]]; then - echo " openzeus install --force --backup" - suggestions=$((suggestions + 1)) - fi - if [[ "$needs_sync_status" == true ]]; then - echo " openzeus sync status" - suggestions=$((suggestions + 1)) - fi - for file in "${missing_executables[@]}"; do - echo " chmod +x $file" - suggestions=$((suggestions + 1)) - done - for file in "${config_executable_fixes[@]}"; do - echo " chmod +x $file" - suggestions=$((suggestions + 1)) - done - if [[ "$status" -ne 0 ]]; then - echo " inspect FAIL lines above, fix the referenced package files, then rerun openzeus doctor --fix-plan" - suggestions=$((suggestions + 1)) - fi - if [[ "$suggestions" -eq 0 ]]; then - echo " (none; no fixes required)" - fi -fi - -if [[ "$ci" == true && ( "$status" -ne 0 || "$warnings" -gt 0 ) ]]; then - exit 1 -fi - -exit "$status" diff --git a/scripts/init-project.sh b/scripts/init-project.sh deleted file mode 100755 index 2d9cc29..0000000 --- a/scripts/init-project.sh +++ /dev/null @@ -1,152 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -dry_run=false -force=false -target_dir="$(pwd)" - -help() { cat <&2 - exit 1 - fi - target_dir="$2" - shift ;; - --dry-run) dry_run=true ;; - --force) force=true ;; - -h|--help|help) help; exit 0 ;; - *) echo "Unknown option: $1" >&2; help; exit 1 ;; - esac - shift -done - -opencode_dir="$target_dir/.opencode" - -detect_project_type() { - if [[ -f "$target_dir/package.json" ]]; then - echo "npm" - elif [[ -f "$target_dir/Makefile" || -f "$target_dir/makefile" ]]; then - echo "make" - elif [[ -f "$target_dir/pyproject.toml" || -f "$target_dir/setup.cfg" || -f "$target_dir/setup.py" ]]; then - echo "python" - else - echo "generic" - fi -} - -detect_npm_command() { - local file="$target_dir/package.json" - if [[ -f "$file" ]]; then - grep -Eq '"test"[[:space:]]*:[[:space:]]*"' "$file" && echo "npm test" || true - grep -Eq '"build"[[:space:]]*:[[:space:]]*"' "$file" && echo "npm run build" || true - fi -} - -detect_make_command() { - local file - for file in "$target_dir/Makefile" "$target_dir/makefile"; do - [[ -f "$file" ]] || continue - grep -Eq '^[[:space:]]*test[[:space:]]*:' "$file" && echo "make test" || true - grep -Eq '^[[:space:]]*build[[:space:]]*:' "$file" && echo "make build" || true - break - done -} - -detect_python_test_command() { - if [[ -f "$target_dir/pyproject.toml" || -f "$target_dir/setup.cfg" || -f "$target_dir/setup.py" ]]; then - echo "pytest" - fi -} - -detect_test_command() { - local npm_test make_test python_test - npm_test="$(detect_npm_command | grep -m1 '^.*test.*$' || true)" - make_test="$(detect_make_command | grep -m1 '^.*test.*$' || true)" - python_test="$(detect_python_test_command || true)" - if [[ -n "$npm_test" ]]; then - echo "$npm_test" - elif [[ -n "$make_test" ]]; then - echo "$make_test" - elif [[ -n "$python_test" ]]; then - echo "$python_test" - fi -} - -detect_build_command() { - local npm_build make_build - npm_build="$(detect_npm_command | grep -m1 'build' || true)" - make_build="$(detect_make_command | grep -m1 'build' || true)" - if [[ -n "$npm_build" ]]; then - echo "$npm_build" - elif [[ -n "$make_build" ]]; then - echo "$make_build" - fi -} - -project_type="$(detect_project_type)" -test_command="$(detect_test_command)" -build_command="$(detect_build_command)" - -test_md=$'---\ndescription: Run the project test suite\n---\n\n# /test\n\nRun the most relevant checks for $ARGUMENTS and report the result.\n\n## Detected command\n' -if [[ -n "$test_command" ]]; then - test_md+=$'Use: `' - test_md+="$test_command" - test_md+=$'`\n\n' -else - test_md+=$'No obvious test command was detected. Inspect the project docs or package scripts, then run the safest available test command.\n\n' -fi -test_md+=$'## Template\nUse $ARGUMENTS to describe the scope, such as `unit`, `smoke`, or `all`.\n' - -build_md=$'---\ndescription: Build or validate the project\n---\n\n# /build\n\nUse $ARGUMENTS to describe what should be built or validated.\n\n## Detected command\n' -if [[ -n "$build_command" ]]; then - build_md+=$'Use: `' - build_md+="$build_command" - build_md+=$'`\n\n' -else - build_md+=$'No obvious build command was detected. Use the project’s documented build or validation flow, or a safe no-op validation step.\n\n' -fi -build_md+=$'## Template\nPrefer a safe build or validation command, then report what changed.\n' - -context_md=$'---\nname: project-context\ndescription: Local project context, conventions, and workflow notes\n---\n\n# Project Context\n\nUse this skill to capture project-specific conventions, paths, and validation steps.\n\n## Detected project\n' -context_md+=$'Type: ' -context_md+="$project_type" -context_md+=$'\n' -if [[ -n "$test_command" ]]; then - context_md+=$'Test command: ' - context_md+="$test_command" - context_md+=$'\n' -fi -if [[ -n "$build_command" ]]; then - context_md+=$'Build command: ' - context_md+="$build_command" - context_md+=$'\n' -fi -context_md+=$'\nKeep notes focused on safe, repeatable local workflows.\n' - -write_file() { - local path="$1" content="$2" - if [[ -e "$path" && "$force" == false ]]; then printf 'SKIP %s\n' "$path"; return 0; fi - if [[ "$dry_run" == true ]]; then printf 'DRY-RUN: no files written: %s\n' "$path"; return 0; fi - mkdir -p "$(dirname "$path")" - printf '%s' "$content" > "$path" -} - -write_file "$opencode_dir/agents/project-guide.md" $'---\ndescription: Project guidance and safety rules\nmode: subagent\npermission:\n edit: ask\n bash: ask\n---\n\n# Project Guide\n\nUse this agent to understand the project before making changes.\n' -write_file "$opencode_dir/commands/test.md" "$test_md" -write_file "$opencode_dir/commands/build.md" "$build_md" -write_file "$opencode_dir/skills/project-context/SKILL.md" "$context_md" -write_file "$opencode_dir/README.md" $'# .opencode Starter\n\nThis project-local OpenCode directory contains starter assets for safe local workflows.\n' - -if [[ "$dry_run" == true ]]; then - echo "dry-run complete for $opencode_dir (no files written)" -else - echo "initialized $opencode_dir" -fi diff --git a/scripts/inspect.mjs b/scripts/inspect.mjs new file mode 100755 index 0000000..bd89690 --- /dev/null +++ b/scripts/inspect.mjs @@ -0,0 +1,381 @@ +#!/usr/bin/env node +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; + +function usage() { + process.stdout.write( + "Usage: openzeus inspect [--target DIR] [--json]\n\n" + + "Inspect filesystem-visible OpenCode configuration and asset sources.\n" + + "Secret environment/config values are never emitted.\n" + ); +} + +function parseArgs(argv) { + let target = process.cwd(); + let json = false; + for (let i = 0; i < argv.length; i += 1) { + const arg = argv[i]; + if (arg === "--json") { + json = true; + } else if (arg === "--target") { + const value = argv[i + 1]; + if (!value || value.startsWith("--")) throw new Error("Missing value for --target"); + target = value; + i += 1; + } else if (arg === "-h" || arg === "--help") { + usage(); + process.exit(0); + } else { + throw new Error("Unknown option: " + arg); + } + } + return { target: path.resolve(target), json }; +} + +function exists(p) { + try { return fs.existsSync(p); } catch { return false; } +} + +function realpathSafe(p) { + try { return fs.realpathSync(p); } catch { return path.resolve(p); } +} + +function gitRoot(target) { + try { + return realpathSafe(execFileSync("git", ["-C", target, "rev-parse", "--show-toplevel"], { + encoding: "utf8", + stdio: ["ignore", "pipe", "ignore"] + }).trim()); + } catch { + return realpathSafe(target); + } +} + +function ancestorChain(root, target) { + root = realpathSafe(root); + target = realpathSafe(target); + const rel = path.relative(root, target); + if (rel === ".." || rel.startsWith(".." + path.sep) || path.isAbsolute(rel)) return [target]; + const out = []; + let cur = target; + while (true) { + out.push(cur); + if (cur === root) break; + const parent = path.dirname(cur); + if (parent === cur) break; + cur = parent; + } + return out.reverse(); +} + +function frontmatter(file) { + let content; + try { content = fs.readFileSync(file, "utf8").replace(/\r\n/g, "\n"); } + catch { return { keys: new Set(), values: {} }; } + if (!content.startsWith("---\n")) return { keys: new Set(), values: {} }; + const end = content.indexOf("\n---", 4); + if (end < 0) return { keys: new Set(), values: {} }; + const keys = new Set(); + const values = {}; + for (const line of content.slice(4, end).split("\n")) { + const match = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(line); + if (!match) continue; + keys.add(match[1]); + values[match[1]] = match[2].replace(/^["']|["']$/g, ""); + } + return { keys, values }; +} + +function listDir(dir) { + try { return fs.readdirSync(dir, { withFileTypes: true }); } + catch { return []; } +} + +function addMarkdownFiles(inventory, type, dir, source, precedence, warnings) { + for (const entry of listDir(dir)) { + if (!entry.isFile() || !entry.name.endsWith(".md")) continue; + const file = path.join(dir, entry.name); + const id = entry.name.slice(0, -3); + const fm = frontmatter(file); + inventory[type].push({ id, path: realpathSafe(file), source, precedence }); + + if (type === "agents") { + for (const key of ["permission", "tools", "temperature", "top_p", "prompt", "disable", "maxSteps"]) { + if (!fm.keys.has(key)) continue; + warnings.push({ + code: "legacy_agent_" + key.toLowerCase(), + severity: "warning", + path: realpathSafe(file), + message: "Agent uses legacy top-level field '" + key + "'." + }); + } + } + + if (type === "commands" && fm.keys.has("subtask")) { + warnings.push({ + code: "legacy_command_subtask", + severity: "warning", + path: realpathSafe(file), + message: "Command uses deprecated 'subtask'; current OpenCode uses 'subagent'." + }); + } + } +} + +function addSkills(inventory, dir, source, precedence, warnings) { + for (const entry of listDir(dir)) { + if (!entry.isDirectory()) continue; + const file = path.join(dir, entry.name, "SKILL.md"); + if (!exists(file)) continue; + const fm = frontmatter(file); + inventory.skills.push({ + id: entry.name, + path: realpathSafe(file), + source, + precedence + }); + if (!fm.keys.has("description")) { + warnings.push({ + code: "skill_missing_description", + severity: "warning", + path: realpathSafe(file), + message: "Skill is missing a description in SKILL.md frontmatter." + }); + } + } +} + +function addPlugins(inventory, dir, source, precedence) { + for (const entry of listDir(dir)) { + if (!entry.isFile() || !/\.(js|mjs|cjs|ts|mts|cts)$/.test(entry.name)) continue; + inventory.plugins.push({ + id: entry.name.replace(/\.[^.]+$/, ""), + path: realpathSafe(path.join(dir, entry.name)), + source, + precedence + }); + } +} + +function addConfig(configSources, seen, kind, candidate) { + if (!candidate) return; + const resolved = path.resolve(candidate); + if (seen.has(resolved)) return; + seen.add(resolved); + configSources.push({ kind, path: resolved, exists: exists(resolved) }); +} + +function markWinners(inventory) { + const collisions = []; + for (const [type, entries] of Object.entries(inventory)) { + entries.sort((a, b) => a.precedence - b.precedence || a.path.localeCompare(b.path)); + const groups = new Map(); + for (const entry of entries) { + if (!groups.has(entry.id)) groups.set(entry.id, []); + groups.get(entry.id).push(entry); + } + for (const [id, group] of groups) { + const winner = group[group.length - 1]; + for (const item of group) item.winner = item === winner; + if (group.length > 1) { + collisions.push({ + type: type.slice(0, -1), + id, + winner: { source: winner.source, path: winner.path }, + shadowed: group.slice(0, -1).map(x => ({ source: x.source, path: x.path })) + }); + } + } + } + return collisions; +} + +function detectOpenCodeVersion() { + // Filesystem mode intentionally does not execute OpenCode. A shim, version + // manager, or interactive launcher can have side effects or block CI. + // A future live-runtime adapter/plugin can provide the authoritative version. + return null; +} + +function printHuman(result) { + console.log("OpenZeus inspect (filesystem view)"); + console.log("Target: " + result.target); + console.log("Workspace root: " + result.workspaceRoot); + console.log("Config root: " + result.configRoot); + console.log("OpenCode version: " + (result.openCodeVersion || "not queried in filesystem mode")); + console.log(""); + console.log( + "Inventory: " + + result.inventory.agents.length + " agents, " + + result.inventory.skills.length + " skills, " + + result.inventory.commands.length + " commands, " + + result.inventory.plugins.length + " local plugins" + ); + console.log("Collisions: " + result.collisions.length); + console.log("Warnings: " + result.warnings.length); + + if (result.collisions.length) { + console.log("\nCollisions"); + for (const collision of result.collisions) { + console.log("- " + collision.type + " " + collision.id + " -> " + collision.winner.source); + } + } + + if (result.warnings.length) { + console.log("\nWarnings"); + for (const warning of result.warnings) { + console.log("- [" + warning.code + "] " + warning.message + " (" + warning.path + ")"); + } + } + + const presentSources = result.configSources.filter(source => source.exists); + console.log("\nConfig sources"); + if (!presentSources.length && !result.environment.inlineConfigPresent) { + console.log("- no filesystem config file detected"); + } + for (const source of presentSources) { + console.log("- " + source.kind + ": " + source.path); + } + if (result.environment.inlineConfigPresent) { + console.log("- inline: OPENCODE_CONFIG_CONTENT is set (value hidden)"); + } + + console.log("\nLimitation: " + result.limitations[0]); +} + +let args; +try { args = parseArgs(process.argv.slice(2)); } +catch (error) { + console.error(String(error.message || error)); + usage(); + process.exit(2); +} + +if (!exists(args.target) || !fs.statSync(args.target).isDirectory()) { + console.error("Target directory does not exist: " + args.target); + process.exit(2); +} + +const target = realpathSafe(args.target); +const workspaceRoot = gitRoot(target); +const ancestors = ancestorChain(workspaceRoot, target); +const home = path.resolve(process.env.HOME || os.homedir()); +const defaultConfigRoot = process.env.XDG_CONFIG_HOME + ? path.join(path.resolve(process.env.XDG_CONFIG_HOME), "opencode") + : path.join(home, ".config", "opencode"); +const configRoot = path.resolve( + process.env.OPENCODE_CONFIG_DIR || + process.env.OPENZEUS_CONFIG_DIR || + defaultConfigRoot +); + +const inventory = { agents: [], skills: [], commands: [], plugins: [] }; +const warnings = []; +const configSources = []; +const seenConfig = new Set(); + +addConfig(configSources, seenConfig, "global", path.join(configRoot, "opencode.json")); +addConfig(configSources, seenConfig, "global", path.join(configRoot, "opencode.jsonc")); + +if (process.env.OPENCODE_CONFIG) { + addConfig(configSources, seenConfig, "explicit-env", process.env.OPENCODE_CONFIG); +} + +for (const dir of ancestors) { + addConfig(configSources, seenConfig, "project", path.join(dir, "opencode.json")); + addConfig(configSources, seenConfig, "project", path.join(dir, "opencode.jsonc")); + addConfig(configSources, seenConfig, "project-opencode", path.join(dir, ".opencode", "opencode.json")); + addConfig(configSources, seenConfig, "project-opencode", path.join(dir, ".opencode", "opencode.jsonc")); +} + +for (const oldName of ["tui.json", "tui.jsonc"]) { + const oldPath = path.join(configRoot, oldName); + if (!exists(oldPath)) continue; + warnings.push({ + code: "legacy_tui_config", + severity: "warning", + path: realpathSafe(oldPath), + message: "Legacy V1 terminal config detected; OpenCode V2 uses global cli.json." + }); +} + +addMarkdownFiles(inventory, "agents", path.join(configRoot, "agents"), "global-opencode", 100, warnings); +addMarkdownFiles(inventory, "commands", path.join(configRoot, "commands"), "global-opencode", 100, warnings); +addPlugins(inventory, path.join(configRoot, "plugins"), "global-opencode", 100); + +ancestors.forEach((dir, index) => { + const base = path.join(dir, ".opencode"); + const relative = path.relative(workspaceRoot, dir) || "."; + const source = "project-opencode:" + relative; + addMarkdownFiles(inventory, "agents", path.join(base, "agents"), source, 200 + index, warnings); + addMarkdownFiles(inventory, "commands", path.join(base, "commands"), source, 200 + index, warnings); + addPlugins(inventory, path.join(base, "plugins"), source, 200 + index); +}); + +addSkills(inventory, path.join(home, ".claude", "skills"), "global-claude", 100, warnings); +ancestors.forEach((dir, index) => addSkills( + inventory, + path.join(dir, ".claude", "skills"), + "project-claude:" + (path.relative(workspaceRoot, dir) || "."), + 110 + index, + warnings +)); + +addSkills(inventory, path.join(home, ".agents", "skills"), "global-agents", 200, warnings); +ancestors.forEach((dir, index) => addSkills( + inventory, + path.join(dir, ".agents", "skills"), + "project-agents:" + (path.relative(workspaceRoot, dir) || "."), + 210 + index, + warnings +)); + +addSkills(inventory, path.join(configRoot, "skills"), "global-opencode", 300, warnings); +ancestors.forEach((dir, index) => addSkills( + inventory, + path.join(dir, ".opencode", "skills"), + "project-opencode:" + (path.relative(workspaceRoot, dir) || "."), + 310 + index, + warnings +)); + +const collisions = markWinners(inventory); +for (const collision of collisions) { + warnings.push({ + code: "asset_shadowing", + severity: "info", + path: collision.winner.path, + message: collision.type + " '" + collision.id + "' shadows " + + collision.shadowed.length + " earlier filesystem source(s)." + }); +} + +const result = { + schemaVersion: 1, + mode: "filesystem", + target, + workspaceRoot, + configRoot, + openCodeVersion: detectOpenCodeVersion(), + environment: { + opencodeConfigSet: Boolean(process.env.OPENCODE_CONFIG), + opencodeConfigDirSet: Boolean(process.env.OPENCODE_CONFIG_DIR), + xdgConfigHomeSet: Boolean(process.env.XDG_CONFIG_HOME), + inlineConfigPresent: Boolean(process.env.OPENCODE_CONFIG_CONTENT) + }, + configSources, + inventory, + collisions, + warnings, + limitations: [ + "Filesystem mode does not execute OpenCode and cannot fully resolve remote/managed configuration, config-declared assets, npm plugins, built-in skills, explicit skill catalogs, or the authoritative OpenCode version. It reports that boundary instead of guessing." + ] +}; + +if (args.json) { + process.stdout.write(JSON.stringify(result, null, 2) + "\n"); +} else { + printHuman(result); +} diff --git a/scripts/install-agent.sh b/scripts/install-agent.sh new file mode 100755 index 0000000..5def1c0 --- /dev/null +++ b/scripts/install-agent.sh @@ -0,0 +1,66 @@ +#!/bin/bash +set -euo pipefail + +dry_run=false +force=false +backup=false +target_dir="${OPENCODE_CONFIG_DIR:-${OPENZEUS_CONFIG_DIR:-${XDG_CONFIG_HOME:-${HOME}/.config}/opencode}}" + +usage() { + cat <&2; exit 1; } + target_dir="$2" + shift ;; + -h|--help) usage; exit 0 ;; + *) echo "Unknown option: $1" >&2; usage >&2; exit 1 ;; + esac + shift +done + +root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +src="$root/agents/OpenZeus.md" +dst="$target_dir/agents/OpenZeus.md" + +[[ -f "$src" ]] || { echo "OpenZeus agent source missing: $src" >&2; exit 1; } + +if [[ "$dry_run" == true ]]; then + echo "DRY-RUN: install $src -> $dst" + exit 0 +fi + +mkdir -p "$(dirname "$dst")" + +if [[ -f "$dst" ]] && cmp -s "$src" "$dst"; then + echo "OpenZeus agent already current: $dst" + exit 0 +fi + +if [[ -e "$dst" && "$force" != true ]]; then + echo "Existing OpenZeus agent differs; not overwritten: $dst" >&2 + echo "Use --force, optionally with --backup, after reviewing the difference." >&2 + exit 1 +fi + +if [[ -e "$dst" && "$backup" == true ]]; then + backup_path="${dst}.bak.$(date +%Y%m%d%H%M%S)" + cp -p "$dst" "$backup_path" + echo "backup: $backup_path" +fi + +rm -f "$dst" +cp -f "$src" "$dst" +echo "OpenZeus agent installed: $dst" +echo "Plugin requirement: opencode plugin add openzeus" diff --git a/scripts/install.sh b/scripts/install.sh deleted file mode 100755 index 579279a..0000000 --- a/scripts/install.sh +++ /dev/null @@ -1,176 +0,0 @@ -#!/bin/bash -set -euo pipefail - -dry_run=false -force=false -backup=false -install_mode="all" -target_dir="${OPENCODE_CONFIG_DIR:-${OPENZEUS_CONFIG_DIR:-${HOME}/.config/opencode}}" - -usage() { - cat <&2 - exit 1 - fi -} - -while [[ $# -gt 0 ]]; do - case "$1" in - --dry-run) dry_run=true ;; - --force) force=true ;; - --backup) backup=true ;; - --core) install_mode="core" ;; - --extras) install_mode="extras" ;; - --all) install_mode="all" ;; - --target) - require_value "$1" "${2:-}" - target_dir="$2" - shift - ;; - -h|--help) usage; exit 0 ;; - *) echo "Unknown option: $1" >&2; usage; exit 1 ;; - esac - shift -done - -script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" - -backup_existing() { - local dst="$1" - [[ "$backup" == true && -e "$dst" ]] || return 0 - - local bak="${dst}.bak.$(date +%Y%m%d%H%M%S)" - if [[ -d "$dst" ]]; then - cp -R "$dst" "$bak" - else - cp -p "$dst" "$bak" - fi - echo "backup: $bak" -} - -same_file() { - [[ -f "$1" && -f "$2" ]] && cmp -s "$1" "$2" -} - -same_dir() { - [[ -d "$1" && -d "$2" ]] && diff -qr "$1" "$2" >/dev/null -} - -copy_file_safe() { - local src="$1" - local dst="$2" - local mode="${3:-}" - - if [[ "$dry_run" == true ]]; then - echo "copy file: $src -> $dst" - return 0 - fi - - mkdir -p "$(dirname "$dst")" - if [[ -e "$dst" ]]; then - same_file "$src" "$dst" && return 0 - if [[ "$force" != true ]]; then - echo "skip existing: $dst" - return 0 - fi - backup_existing "$dst" - rm -rf "$dst" - fi - - cp -f "$src" "$dst" - if [[ "$mode" == executable ]]; then - chmod +x "$dst" - fi - return 0 -} - -copy_dir_safe() { - local src="$1" - local dst="$2" - - if [[ "$dry_run" == true ]]; then - echo "copy dir: $src -> $dst" - return 0 - fi - - mkdir -p "$(dirname "$dst")" - if [[ -e "$dst" ]]; then - same_dir "$src" "$dst" && return 0 - if [[ "$force" != true ]]; then - echo "skip existing: $dst" - return 0 - fi - backup_existing "$dst" - rm -rf "$dst" - fi - - cp -R "$src" "$dst" -} - -should_install_skill() { - local name="$1" - case "$install_mode" in - all) return 0 ;; - core) [[ "$name" == zeus-core || "$name" == zeus-agents || "$name" == zeus-commands || "$name" == zeus-skills || "$name" == zeus-upskill || "$name" == zeus-context ]] ;; - extras) [[ "$name" != zeus-core && "$name" != zeus-agents && "$name" != zeus-commands && "$name" != zeus-skills && "$name" != zeus-upskill && "$name" != zeus-context ]] ;; - esac -} - -should_install_command() { - local name="$1" - case "$install_mode" in - all) return 0 ;; - core) [[ "$name" == zeus-git-commit.md || "$name" == zeus-improve-project.md ]] ;; - extras) [[ "$name" != zeus-git-commit.md && "$name" != zeus-improve-project.md ]] ;; - esac -} - -if [[ "$dry_run" == true ]]; then - echo "mkdir -p $target_dir/agents $target_dir/skills $target_dir/commands" - echo "write install profile: $install_mode" -else - mkdir -p "$target_dir/agents" "$target_dir/skills" "$target_dir/commands" - printf '%s\n' "$install_mode" > "$target_dir/.openzeus-install-profile" -fi - -copy_file_safe "$script_dir/agents/OpenZeus.md" "$target_dir/agents/OpenZeus.md" - -for skill_dir in "$script_dir"/skills/zeus-*; do - [[ -d "$skill_dir" ]] || continue - should_install_skill "$(basename "$skill_dir")" || continue - copy_dir_safe "$skill_dir" "$target_dir/skills/$(basename "$skill_dir")" -done - -for command_file in "$script_dir"/commands/zeus-*.md; do - [[ -f "$command_file" ]] || continue - should_install_command "$(basename "$command_file")" || continue - copy_file_safe "$command_file" "$target_dir/commands/$(basename "$command_file")" -done - -for helper in sync-utils.sh create-utils.sh setup-hooks.sh doctor.sh init-project.sh setup.sh validate.sh capture-command.sh diff.sh upgrade.sh; do - [[ -f "$script_dir/scripts/$helper" ]] || continue - copy_file_safe "$script_dir/scripts/$helper" "$target_dir/$helper" executable -done - -if [[ "$dry_run" == true ]]; then - echo "OpenZeus dry-run complete for $target_dir (no files written)" -else - echo "OpenZeus assets installed to $target_dir" -fi diff --git a/scripts/migrate.mjs b/scripts/migrate.mjs new file mode 100755 index 0000000..883a0c1 --- /dev/null +++ b/scripts/migrate.mjs @@ -0,0 +1,219 @@ +#!/usr/bin/env node +import { execFileSync } from "node:child_process" +import path from "node:path" +import { fileURLToPath } from "node:url" + +const here = path.dirname(fileURLToPath(import.meta.url)) +const inspectScript = path.join(here, "inspect.mjs") + +function usage() { + process.stdout.write( + "Usage: openzeus migrate --plan [--target DIR] [--json]\n\n" + + "Build a non-mutating OpenCode migration plan from inspector findings.\n" + + "Apply mode is intentionally not implemented yet.\n", + ) +} + +function parseArgs(argv) { + let target = process.cwd() + let json = false + let plan = false + + for (let i = 0; i < argv.length; i += 1) { + const arg = argv[i] + if (arg === "--plan") plan = true + else if (arg === "--json") json = true + else if (arg === "--target") { + const value = argv[i + 1] + if (!value || value.startsWith("--")) throw new Error("Missing value for --target") + target = value + i += 1 + } else if (arg === "--apply") { + throw new Error("Apply mode is not implemented; no files were changed. Use --plan.") + } else if (arg === "-h" || arg === "--help") { + usage() + process.exit(0) + } else { + throw new Error("Unknown option: " + arg) + } + } + + if (!plan) { + throw new Error("Migration is plan-only for now. Pass --plan; no files were changed.") + } + + return { target: path.resolve(target), json } +} + +function actionFor(finding) { + const base = { + sourceCode: finding.code, + path: finding.path, + automatic: false, + } + + switch (finding.code) { + case "legacy_agent_permission": + return { + ...base, + id: "agent-permissions-v2", + kind: "agent", + summary: "Convert legacy permission mapping to ordered V2 permissions.", + details: [ + "Preserve the existing allow/ask/deny intent.", + "Translate bash -> shell, task -> subagent, and write/patch -> edit where present.", + "Review wildcard/resource semantics before applying.", + ], + } + + case "legacy_agent_tools": + return { + ...base, + id: "agent-tools-v2", + kind: "agent", + summary: "Replace legacy tools gating with explicit V2 permission rules.", + details: [ + "Derive the intended allow/deny behavior before removing the tools map.", + ], + } + + case "legacy_agent_disable": + return { + ...base, + id: "agent-disabled-v2", + kind: "agent", + summary: "Rename legacy agent disable to disabled.", + details: ["Preserve the existing boolean value."], + } + + case "legacy_agent_temperature": + case "legacy_agent_top_p": + case "legacy_agent_prompt": + case "legacy_agent_maxsteps": + return { + ...base, + id: "agent-request-options-review", + kind: "agent", + summary: "Review legacy agent request/system fields against current V2 behavior.", + details: [ + "Do not blindly move or delete this field.", + "Confirm the current schema/provider/model behavior before changing it.", + ], + } + + case "legacy_command_subtask": + return { + ...base, + id: "command-subagent-v2", + kind: "command", + summary: "Rename legacy command subtask to subagent.", + details: [ + "Preserve the boolean value.", + "Verify that the intended execution/delivery behavior remains the same.", + ], + } + + case "legacy_tui_config": + return { + ...base, + id: "client-config-v2", + kind: "client-config", + summary: "Review migration from legacy tui.json(c) to V2 global cli.json.", + details: [ + "Map only settings supported by current cli.json.", + "Keep a backup of the old client config until the V2 client starts cleanly.", + ], + } + + default: + return null + } +} + +let args +try { + args = parseArgs(process.argv.slice(2)) +} catch (error) { + console.error(String(error.message || error)) + usage() + process.exit(2) +} + +let inspection +try { + const output = execFileSync(process.execPath, [ + inspectScript, + "--target", + args.target, + "--json", + ], { + encoding: "utf8", + stdio: ["ignore", "pipe", "inherit"], + }) + inspection = JSON.parse(output) +} catch { + console.error("OpenZeus migration planning could not complete inspection.") + process.exit(2) +} + +const actions = [] +const ignoredFindings = [] + +for (const finding of inspection.warnings) { + const action = actionFor(finding) + if (action) { + actions.push(action) + } else { + ignoredFindings.push({ + code: finding.code, + severity: finding.severity, + path: finding.path, + message: finding.message, + }) + } +} + +const result = { + schemaVersion: 1, + mode: "plan", + mutatesFiles: false, + target: inspection.target, + workspaceRoot: inspection.workspaceRoot, + actions, + ignoredFindings, + limitations: [ + ...inspection.limitations, + "This command plans only. Every action requires review before any future apply implementation may mutate files.", + ], +} + +if (args.json) { + process.stdout.write(JSON.stringify(result, null, 2) + "\n") +} else { + console.log("OpenZeus migration plan") + console.log("Target: " + result.target) + console.log("Planned actions: " + actions.length) + + if (!actions.length) { + console.log("\nNo filesystem-visible migration actions detected.") + } else { + console.log("\nActions") + actions.forEach((action, index) => { + console.log((index + 1) + ". " + action.summary) + console.log(" " + action.path) + for (const detail of action.details) { + console.log(" - " + detail) + } + console.log(" Automatic apply: no") + }) + } + + if (ignoredFindings.length) { + console.log("\nNot migration actions") + for (const finding of ignoredFindings) { + console.log("- [" + finding.severity + "] " + finding.message) + } + } + + console.log("\nNo files were changed.") +} diff --git a/scripts/setup-hooks.sh b/scripts/setup-hooks.sh deleted file mode 100755 index d04de93..0000000 --- a/scripts/setup-hooks.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -set -euo pipefail - -dry_run=false -force=false - -usage() { - cat < config after pulls/merges - pre-push runs sync status and warns about divergence -EOF -} - -while [[ $# -gt 0 ]]; do - case "$1" in - --dry-run) dry_run=true ;; - --force) force=true ;; - -h|--help|help) usage; exit 0 ;; - *) echo "Unknown option: $1" >&2; usage; exit 1 ;; - esac - shift -done - -repo_root="$(git rev-parse --show-toplevel)" -hooks_path="$(git -C "$repo_root" rev-parse --git-path hooks)" -case "$hooks_path" in - /*) hooks_dir="$hooks_path" ;; - *) hooks_dir="$repo_root/$hooks_path" ;; -esac - -write_hook() { - local path="$1" - local body="$2" - - if [[ "$dry_run" == true ]]; then - printf 'WRITE %s\n' "$path" - return 0 - fi - - if [[ -e "$path" && "$force" != true ]]; then - echo "skip existing hook: $path" - return 0 - fi - - mkdir -p "$(dirname "$path")" - printf '%s\n' "$body" > "$path" - chmod +x "$path" - echo "installed hook: $path" -} - -post_merge='#!/bin/bash -set -euo pipefail -repo_root="$(git rev-parse --show-toplevel)" -if [[ -x "$repo_root/scripts/sync-utils.sh" ]]; then - "$repo_root/scripts/sync-utils.sh" push -fi' - -pre_push='#!/bin/bash -set -euo pipefail -repo_root="$(git rev-parse --show-toplevel)" -if [[ -x "$repo_root/scripts/sync-utils.sh" ]]; then - "$repo_root/scripts/sync-utils.sh" status || { - echo "OpenZeus sync status has differences; run scripts/sync-utils.sh status" >&2 - } -fi' - -write_hook "$hooks_dir/post-merge" "$post_merge" -write_hook "$hooks_dir/pre-push" "$pre_push" - -echo "OpenZeus hooks configured in $hooks_dir" diff --git a/scripts/setup.sh b/scripts/setup.sh deleted file mode 100755 index c812c63..0000000 --- a/scripts/setup.sh +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/bash -set -euo pipefail - -root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -mode="plan" -recipe="" -target_dir="$(pwd)" -dry_run=false -force=false - -recipes_help() { - cat <&2 - exit 1 - fi -} - -validate_recipe() { - [[ -z "$recipe" ]] && return 0 - case "$recipe" in - node|python|docs|beads|solo-dev) ;; - *) echo "Unknown recipe: $recipe" >&2; recipes_help >&2; exit 1 ;; - esac -} - -makefile_path() { - if [[ -f "$target_dir/Makefile" ]]; then - printf '%s\n' "$target_dir/Makefile" - elif [[ -f "$target_dir/makefile" ]]; then - printf '%s\n' "$target_dir/makefile" - fi -} - -usage() { cat <"$f" <"$f" <"$f" <"$path" <&2; usage >&2; exit 1 ;; - esac - shift - done - validate_recipe - context_init - exit 0 - fi - case "$1" in - --plan) mode=plan ;; - --apply) mode=apply ;; - --recipe) require_value "$1" "${2:-}"; recipe="$2"; shift ;; - --target) require_value "$1" "${2:-}"; target_dir="$2"; shift ;; - --dry-run) dry_run=true ;; - --force) force=true ;; - recipes) recipes_help; exit 0 ;; - -h|--help) usage; exit 0 ;; - *) echo "Unknown option: $1" >&2; usage >&2; exit 1 ;; - esac - shift -done - -validate_recipe - -if [[ "$mode" == plan ]]; then - stack="$(detect_stack)"; test_cmd="$(detect_test || true)"; build_cmd="$(detect_build || true)" - echo "Setup plan for $target_dir" - echo "Detected stack: $stack" - [[ -n "$test_cmd" ]] && echo "Test command: $test_cmd" - [[ -n "$build_cmd" ]] && echo "Build command: $build_cmd" - echo "Proposed files: .opencode/agents/project-guide.md .opencode/commands/test.md .opencode/commands/build.md .opencode/skills/project-context/SKILL.md .opencode/context/{architecture.md,commands.md,testing.md}" - [[ -n "$recipe" ]] && recipe_effects - echo "Apply: openzeus setup --apply --target $target_dir${recipe:+ --recipe $recipe}" - exit 0 -fi - -apply_args=(--target "$target_dir") -[[ "$dry_run" == true ]] && apply_args+=(--dry-run) -[[ "$force" == true ]] && apply_args+=(--force) -had_test=false; had_build=false -[[ -e "$target_dir/.opencode/commands/test.md" ]] && had_test=true -[[ -e "$target_dir/.opencode/commands/build.md" ]] && had_build=true -"$root/scripts/init-project.sh" "${apply_args[@]}" -apply_recipe_commands "$had_test" "$had_build" -context_init diff --git a/scripts/sync-utils.sh b/scripts/sync-utils.sh deleted file mode 100755 index 681182b..0000000 --- a/scripts/sync-utils.sh +++ /dev/null @@ -1,290 +0,0 @@ -#!/bin/bash -set -euo pipefail - -dry_run=false -force=false -backup=false -repo_dir="${OPENZEUS_REPO:-}" -config_dir="${OPENCODE_CONFIG_DIR:-${HOME}/.config/opencode}" -command="status" -manifest_items="" - -usage() { - cat < - -Synchronizes only OpenZeus-owned assets: - agents/OpenZeus.md - skills/zeus-*/ - commands/zeus-*.md - -By default, conflicting destination files are not overwritten. Use --force to -overwrite and --backup to preserve the old destination first. -EOF -} - -require_value() { - local flag="$1" - local value="${2:-}" - if [[ -z "$value" || "$value" == --* ]]; then - echo "Missing value for $flag" >&2 - exit 1 - fi -} - -while [[ $# -gt 0 ]]; do - case "$1" in - --dry-run) dry_run=true ;; - --force) force=true ;; - --backup) backup=true ;; - --repo) - require_value "$1" "${2:-}" - repo_dir="$2" - shift - ;; - --config) - require_value "$1" "${2:-}" - config_dir="$2" - shift - ;; - push|pull|status|auto) command="$1" ;; - -h|--help|help) usage; exit 0 ;; - *) echo "Unknown option: $1" >&2; usage; exit 1 ;; - esac - shift -done - -detect_repo() { - if [[ -n "$repo_dir" && -f "$repo_dir/agents/OpenZeus.md" ]]; then - return 0 - fi - - local root="" - if root="$(git -C "$(pwd)" rev-parse --show-toplevel 2>/dev/null)" && [[ -f "$root/agents/OpenZeus.md" ]]; then - repo_dir="$root" - return 0 - fi - - root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" - if [[ -f "$root/agents/OpenZeus.md" ]]; then - repo_dir="$root" - return 0 - fi - - echo "OpenZeus repository not found; pass --repo DIR" >&2 - return 1 -} - -item_label() { - local item="$1" - local type="${item%%:*}" - local name="${item#*:}" - - case "$type" in - agent) printf 'agents/%s' "$name" ;; - skill) printf 'skills/%s' "$name" ;; - command) printf 'commands/%s' "$name" ;; - esac -} - -item_path() { - local base="$1" - local item="$2" - local type="${item%%:*}" - local name="${item#*:}" - - case "$type" in - agent) printf '%s/agents/%s' "$base" "$name" ;; - skill) printf '%s/skills/%s' "$base" "$name" ;; - command) printf '%s/commands/%s' "$base" "$name" ;; - esac -} - -append_item() { - local item="$1" - case "$manifest_items" in - *$'\n'"$item"$'\n'*) return 0 ;; - esac - manifest_items+="$item"$'\n' -} - -collect_manifest() { - local base="$1" - [[ -d "$base" ]] || return 0 - - [[ -f "$base/agents/OpenZeus.md" ]] && append_item "agent:OpenZeus.md" - - local path="" - for path in "$base"/skills/zeus-*; do - [[ -d "$path" ]] || continue - append_item "skill:$(basename "$path")" - done - - for path in "$base"/commands/zeus-*.md; do - [[ -f "$path" ]] || continue - append_item "command:$(basename "$path")" - done -} - -build_manifest() { - manifest_items=$'\n' - collect_manifest "$repo_dir" - collect_manifest "$config_dir" -} - -same_item() { - local left="$1" - local right="$2" - - if [[ -f "$left" && -f "$right" ]]; then - cmp -s "$left" "$right" - return $? - fi - - if [[ -d "$left" && -d "$right" ]]; then - diff -qr "$left" "$right" >/dev/null - return $? - fi - - return 1 -} - -backup_existing() { - local dst="$1" - [[ "$backup" == true && -e "$dst" ]] || return 0 - - local bak="${dst}.bak.$(date +%Y%m%d%H%M%S)" - if [[ -d "$dst" ]]; then - cp -R "$dst" "$bak" - else - cp -p "$dst" "$bak" - fi - echo "backup: $bak" -} - -copy_item() { - local src_base="$1" - local dst_base="$2" - local item="$3" - local src dst label - - src="$(item_path "$src_base" "$item")" - dst="$(item_path "$dst_base" "$item")" - label="$(item_label "$item")" - - [[ -e "$src" ]] || return 0 - - if [[ -e "$dst" ]]; then - same_item "$src" "$dst" && return 0 - if [[ "$force" != true ]]; then - echo "CONFLICT $label" - return 1 - fi - fi - - if [[ "$dry_run" == true ]]; then - echo "copy $label" - return 0 - fi - - mkdir -p "$(dirname "$dst")" - backup_existing "$dst" - rm -rf "$dst" - - if [[ -d "$src" ]]; then - cp -R "$src" "$dst" - else - cp -f "$src" "$dst" - fi -} - -sync_direction() { - local src_base="$1" - local dst_base="$2" - local item status=0 - - build_manifest - while IFS= read -r item; do - [[ -n "$item" ]] || continue - [[ -e "$(item_path "$src_base" "$item")" ]] || continue - copy_item "$src_base" "$dst_base" "$item" || status=1 - done <<< "$manifest_items" - - return "$status" -} - -show_status() { - detect_repo - build_manifest - - local item repo_path config_path status=0 label - while IFS= read -r item; do - [[ -n "$item" ]] || continue - repo_path="$(item_path "$repo_dir" "$item")" - config_path="$(item_path "$config_dir" "$item")" - label="$(item_label "$item")" - - if [[ -e "$repo_path" && -e "$config_path" ]]; then - if same_item "$repo_path" "$config_path"; then - echo "OK $label" - else - echo "DIFF $label" - status=1 - fi - elif [[ -e "$repo_path" ]]; then - echo "MISSING config:$label" - status=1 - elif [[ -e "$config_path" ]]; then - echo "MISSING repo:$label" - status=1 - fi - done <<< "$manifest_items" - - return "$status" -} - -auto_sync() { - detect_repo - build_manifest - - local item repo_path config_path push_needed=false pull_needed=false conflict=false label - while IFS= read -r item; do - [[ -n "$item" ]] || continue - repo_path="$(item_path "$repo_dir" "$item")" - config_path="$(item_path "$config_dir" "$item")" - label="$(item_label "$item")" - - if [[ -e "$repo_path" && -e "$config_path" ]]; then - if ! same_item "$repo_path" "$config_path"; then - echo "CONFLICT $label differs in both locations" - conflict=true - fi - elif [[ -e "$repo_path" ]]; then - push_needed=true - elif [[ -e "$config_path" ]]; then - pull_needed=true - fi - done <<< "$manifest_items" - - if [[ "$conflict" == true || ( "$push_needed" == true && "$pull_needed" == true ) ]]; then - echo "Auto-sync refused: ambiguous bidirectional changes" - return 1 - fi - - if [[ "$push_needed" == true ]]; then - echo "Auto-sync direction: repo -> config" - sync_direction "$repo_dir" "$config_dir" - elif [[ "$pull_needed" == true ]]; then - echo "Auto-sync direction: config -> repo" - sync_direction "$config_dir" "$repo_dir" - else - echo "Already in sync" - fi -} - -case "$command" in - status) show_status ;; - push) detect_repo; sync_direction "$repo_dir" "$config_dir" ;; - pull) detect_repo; sync_direction "$config_dir" "$repo_dir" ;; - auto) auto_sync ;; -esac diff --git a/scripts/upgrade.sh b/scripts/upgrade.sh deleted file mode 100755 index dcd46db..0000000 --- a/scripts/upgrade.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -set -euo pipefail - -cmd="upgrade" -dry_run=false -apply=false -config_dir="${OPENCODE_CONFIG_DIR:-${OPENZEUS_CONFIG_DIR:-${HOME}/.config/opencode}}" -backup_dir="" - -while [[ $# -gt 0 ]]; do - case "$1" in - upgrade) cmd="upgrade" ;; - rollback) cmd="rollback" ;; - --apply) apply=true ;; - --dry-run) dry_run=true ;; - --backup) [[ $# -ge 2 && "$2" != --* ]] || { echo "Missing value for --backup" >&2; exit 1; }; backup_dir="$2"; shift ;; - -h|--help) echo "Usage: upgrade.sh upgrade|rollback [--dry-run] [--backup DIR]"; exit 0 ;; - esac - shift -done - -root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -backup_dir="${backup_dir:-$config_dir/.openzeus-backups}" - -latest_backup() { - local b latest="" - for b in "$backup_dir"/*; do - [[ -e "$b" ]] || continue - [[ -z "$latest" || "$b" > "$latest" ]] && latest="$b" - done - [[ -n "$latest" ]] || return 1 - printf '%s\n' "$latest" -} - -create_backup() { - local backup="$1" - mkdir -p "$backup" - for path in $(managed_paths); do - [[ -e "$config_dir/$path" ]] || continue - mkdir -p "$backup/$(dirname "$path")" - cp -R "$config_dir/$path" "$backup/$path" - done -} - -managed_paths() { - printf '%s\n' .openzeus-install-profile - printf '%s\n' agents/OpenZeus.md - local item - for item in "$root"/skills/zeus-*; do [[ -d "$item" ]] && printf '%s\n' "skills/$(basename "$item")"; done - for item in "$root"/commands/zeus-*.md; do [[ -f "$item" ]] && printf '%s\n' "commands/$(basename "$item")"; done - printf '%s\n' sync-utils.sh create-utils.sh setup-hooks.sh doctor.sh init-project.sh setup.sh validate.sh capture-command.sh diff.sh upgrade.sh -} - -restore_backup() { - local backup="$1" path="" - mkdir -p "$config_dir" - for path in $(managed_paths); do - rm -rf "$config_dir/$path" - [[ -e "$backup/$path" ]] || continue - mkdir -p "$config_dir/$(dirname "$path")" - cp -R "$backup/$path" "$config_dir/$path" - done -} - -case "$cmd" in - upgrade) - if [[ "$dry_run" == true || "$apply" != true ]]; then - echo "Would backup $config_dir to $backup_dir and run openzeus install --force --backup" - [[ "$apply" != true ]] && echo "Apply with: openzeus upgrade --apply" - exit 0 - fi - install_profile="all" - [[ -f "$config_dir/.openzeus-install-profile" ]] && IFS= read -r install_profile < "$config_dir/.openzeus-install-profile" - install_args=(--force --backup --target "$config_dir") - case "$install_profile" in - core) install_args+=(--core) ;; - extras) install_args+=(--extras) ;; - *) install_args+=(--all) ;; - esac - mkdir -p "$backup_dir" - ts="$(date +%Y%m%d%H%M%S)" - backup="$backup_dir/install-$ts" - create_backup "$backup" - echo "backup: $backup" - "$root/scripts/install.sh" "${install_args[@]}" - ;; - rollback) - b="$(latest_backup || true)" - [[ -n "$b" ]] || { echo "no backup"; exit 1; } - if [[ "$dry_run" == true || "$apply" != true ]]; then - echo "Would restore $b to $config_dir" - [[ "$apply" != true ]] && echo "Apply with: openzeus rollback --apply" - exit 0 - fi - restore_backup "$b" - echo "restored $b" - ;; -esac diff --git a/scripts/validate.sh b/scripts/validate.sh index e79b1d8..86c475b 100755 --- a/scripts/validate.sh +++ b/scripts/validate.sh @@ -4,25 +4,28 @@ set -euo pipefail ci=false project_dir="" root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -config_dir="${OPENCODE_CONFIG_DIR:-${OPENZEUS_CONFIG_DIR:-${HOME}/.config/opencode}}" status=0 while [[ $# -gt 0 ]]; do case "$1" in --ci) ci=true ;; - --project) project_dir="$2"; shift ;; + --project) + [[ $# -ge 2 && "$2" != --* ]] || { echo "Missing value for --project" >&2; exit 1; } + project_dir="$2" + shift ;; -h|--help) echo "Usage: validate.sh [--ci] [--project DIR]"; exit 0 ;; + *) echo "Unknown option: $1" >&2; exit 1 ;; esac shift done fail(){ echo "FAIL $1"; status=1; } -warn(){ echo "WARN $1"; } validate_asset(){ local file="$1" kind="$2" [[ -f "$file" ]] || { fail "missing $file"; return; } grep -q '^---$' "$file" || fail "frontmatter missing: $file" + case "$kind" in skill) grep -Eq '^name:[[:space:]]*' "$file" || fail "missing name: $file" @@ -30,37 +33,49 @@ validate_asset(){ ;; agent) grep -Eq '^description:[[:space:]]*' "$file" || fail "missing description: $file" - grep -Eq '^mode:[[:space:]]*(primary|subagent|all)$' "$file" || true - grep -Eq '^mode:[[:space:]]*' "$file" && ! grep -Eq '^mode:[[:space:]]*(primary|subagent|all)$' "$file" && fail "invalid mode: $file" + grep -Eq '^mode:[[:space:]]*' "$file" && + ! grep -Eq '^mode:[[:space:]]*(primary|subagent|all)$' "$file" && + fail "invalid mode: $file" + for legacy in permission tools temperature top_p prompt disable maxSteps; do + grep -Eq "^$legacy:[[:space:]]*" "$file" && + fail "legacy agent field $legacy: $file" || true + done ;; command) grep -Eq '^description:[[:space:]]*' "$file" || fail "missing description: $file" + grep -Eq '^subtask:[[:space:]]*' "$file" && + fail "legacy command field subtask: $file" || true ;; esac - grep -Eq '^tools:[[:space:]]*' "$file" && fail "deprecated tools: $file" || true - grep -Eq '^permission:[[:space:]]*allow$' "$file" && fail "unsafe permission allow: $file" || true } if [[ -z "$project_dir" ]]; then - for s in "$root"/scripts/*.sh "$root/bin/openzeus"; do - [[ -f "$s" ]] || continue - [[ -x "$s" ]] || fail "not executable: $s" - bash -n "$s" || fail "shell syntax: $s" + for script in "$root/bin/openzeus" "$root/scripts/create-utils.sh" "$root/scripts/install-agent.sh" "$root/scripts/validate.sh"; do + [[ -x "$script" ]] || fail "not executable: $script" + bash -n "$script" || fail "shell syntax: $script" + done + for script in "$root/scripts/inspect.mjs" "$root/scripts/audit.mjs"; do + [[ -x "$script" ]] || fail "not executable: $script" + done + [[ -f "$root/src/plugin.js" ]] || fail "missing src/plugin.js" + validate_asset "$root/agents/OpenZeus.md" agent + for file in "$root"/skills/zeus-*/SKILL.md; do + [[ -e "$file" ]] || continue + validate_asset "$file" skill done - for f in "$root/agents/OpenZeus.md"; do validate_asset "$f" agent; done - for f in "$root"/skills/zeus-*/SKILL.md; do [[ -e "$f" ]] || continue; validate_asset "$f" skill; done - for f in "$root"/commands/zeus-*.md; do [[ -e "$f" ]] || continue; validate_asset "$f" command; done - if [[ -d "$config_dir" ]]; then - drift="$($root/scripts/diff.sh --summary || true)" - if [[ "$drift" != "0 issue(s)" ]]; then - warn "config drift detected" - [[ "$ci" == true ]] && status=1 - fi - fi else - for f in "$project_dir/.opencode/agents"/*.md; do [[ -e "$f" ]] || continue; validate_asset "$f" agent; done - for f in "$project_dir/.opencode/commands"/*.md; do [[ -e "$f" ]] || continue; validate_asset "$f" command; done - for f in "$project_dir/.opencode/skills"/*/SKILL.md; do [[ -e "$f" ]] || continue; validate_asset "$f" skill; done + for file in "$project_dir/.opencode/agents"/*.md; do + [[ -e "$file" ]] || continue + validate_asset "$file" agent + done + for file in "$project_dir/.opencode/commands"/*.md; do + [[ -e "$file" ]] || continue + validate_asset "$file" command + done + for file in "$project_dir/.opencode/skills"/*/SKILL.md; do + [[ -e "$file" ]] || continue + validate_asset "$file" skill + done fi [[ "$ci" == true && "$status" -ne 0 ]] && exit 1 diff --git a/skills/codemap.md b/skills/codemap.md index d363b97..7d7ab1d 100644 --- a/skills/codemap.md +++ b/skills/codemap.md @@ -1,400 +1,16 @@ -# skills/ β€” Knowledge System Codemap +# skills/ β€” OpenZeus capability map - +OpenZeus intentionally ships a small OpenCode-specific skill set. ---- +| Skill | Responsibility | +|---|---| +| `zeus-diagnostics` | Runtime/config discovery, provenance, precedence and troubleshooting | +| `zeus-migration` | Safe OpenCode config/asset migration planning | +| `zeus-agents` | Advanced agent design and review | +| `zeus-commands` | Slash-command design and review | +| `zeus-skills` | Skill authoring, discovery and portability | -## Responsibility +Generic technical knowledge, pseudo-introspection, meta-skill proliferation and +copied documentation for unrelated plugins are outside core. -The `skills/` directory implements a **domain-specific knowledge bundle architecture** for the OpenZeus AI agent system. Each skill bundle is a self-contained markdown file providing: - -- **Expert domain knowledge** (Docker, SQL, LLM configuration) -- **Operational workflows** (agent creation, command templates) -- **Reference documentation** (URLs, command syntax, troubleshooting) -- **Trigger-based activation** (loaded on-demand via `skill()` tool) - -The skills serve as OpenZeus's "memory" and "capability modules"β€”extending the agent's effective knowledge beyond its base training with specialized, searchable reference content organized by domain. - ---- - -## Design Patterns - -### Pattern 1: Skill Bundle Architecture - -Each skill is a **standalone markdown module** with standardized structure: - -``` -skills/zeus-/ -└── SKILL.md # Required: main skill file - README.md # Optional: human-facing documentation - [supporting] # Optional: templates, configs, examples -``` - -**Abstraction Layer**: -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ OpenZeus Agent (OpenZeus.md) β”‚ -β”‚ - Intent Detection β†’ keyword matching β”‚ -β”‚ - Skill Loading β†’ skill("zeus-") β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ SKILL.md Content (per skill) β”‚ -β”‚ - YAML frontmatter (required: name, description) β”‚ -β”‚ - Markdown sections (documentation) β”‚ -β”‚ - Tables, code blocks, templates β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### Pattern 2: Frontmatter Metadata Schema - -All skills use YAML frontmatter for discovery and loading: - -```yaml ---- -name: zeus- # Skill identifier (matches directory) -description: Brief purpose # One-line summary for autocomplete -# Optional recognized fields: license, compatibility, metadata ---- -``` - -**Interface Contract**: -| Field | Type | Required | Purpose | -|-------|------|----------|---------| -| `name` | string | Yes | Skill identifier for `skill()` loading | -| `description` | string | Yes | Shown in skill selection UIs | -| `license` | string | No | Optional license metadata | -| `compatibility` | string/object | No | Optional compatibility metadata | -| `metadata` | object | No | Optional structured metadata | - -### Pattern 3: Trigger-Keyword β†’ Skill Mapping - -Skills are loaded via **intent detection** based on user request keywords: - -``` -User: "How do I create a Docker container?" - β”‚ - β–Ό [keyword: "docker", "container"] -OpenZeus Agent β†’ skill("zeus-docker") - β”‚ - β–Ό -zeus-docker/SKILL.md content injected into context -``` - -**Trigger Registry** (from OpenZeus.md): -| Keyword Pattern | Skill(s) Loaded | -|-----------------|------------------| -| `docker`, `container` | `zeus-docker` | -| `sql`, `database`, `query` | `zeus-sql` | -| `create agent`, `@mention` | `zeus-agents` | -| `llama`, `ollama`, `local model` | `zeus-llm` | -| `hive`, `swarm`, `multi-agent` | `zeus-swarm` | -| `context`, `compress` | `zeus-context` | -| `health check`, `diagnostics` | `zeus-self` | - -### Pattern 4: Multi-Skill Workflow Chains - -Complex tasks require **skill composition**: - -``` -Agent Creation: - zeus-agents β†’ zeus-core - -Command Creation: - zeus-commands β†’ zeus-core - -Docker + DevOps: - zeus-docker β†’ zeus-core - -Skill Creation: - zeus-skills β†’ generic OpenCode skill guidance - -OpenZeus Self-Extension: - zeus-upskill β†’ README/metadata/OpenZeus registration workflow -``` - ---- - -## Data & Control Flow - -### Entry Point: Intent Detection - -``` -User Input - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ OpenZeus.md Agent System Prompt β”‚ -β”‚ - Scans for trigger keywords β”‚ -β”‚ - Matches against Skill Loading Guide table β”‚ -β”‚ - Determines skill(s) to load β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -skill("") - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ OpenCode Skill Tool β”‚ -β”‚ - Locates configured skill discovery paths β”‚ -β”‚ - Reads: SKILL.md β”‚ -β”‚ - Injects content into agent context β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### State Transitions - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” skill() β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ IDLE β”‚ ───────────────▢ β”‚ SKILL_LOADED β”‚ -β”‚ (no skill) β”‚ β”‚ (content in β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ context) β”‚ - β–² β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ β”‚ - β”‚ [agent uses - β”‚ skill content] - β”‚ β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - [skill no longer - needed] -``` - -### Data Flow Diagram - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ USER REQUEST β”‚ -β”‚ "Create a custom command for deploying with Docker Compose" β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ INTENT DETECTION β”‚ -β”‚ Keywords: "command", "deploy", "Docker Compose" β”‚ -β”‚ β†’ Match: zeus-commands, zeus-docker β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ SKILL LOADING β”‚ -β”‚ skill("zeus-commands") ──────────────────────────────────┐ β”‚ -β”‚ skill("zeus-docker") ─────────────────────────────────── β”‚ -β”‚ skill("zeus-core") β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ CONTEXT AUGMENTATION β”‚ -β”‚ SKILL.md content appended to system prompt β”‚ -β”‚ - Command templates (zeus-commands) β”‚ -β”‚ - Docker Compose patterns (zeus-docker) β”‚ -β”‚ - OpenCode config paths (zeus-core) β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ AGENT REASONING β”‚ -β”‚ Uses skill content to generate: β”‚ -β”‚ - Custom command template (zeus-commands) β”‚ -β”‚ - Docker Compose configuration (zeus-docker) β”‚ -β”‚ - File path: ~/.config/opencode/commands/deploy.md β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ FILE WRITE β”‚ -β”‚ write ~/.config/opencode/commands/deploy.md β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -### Skill Content Types - -| Content Type | Purpose | Example | -|--------------|---------|---------| -| Reference tables | Quick lookup | Docker flags, SQL syntax | -| Code templates | Reusable patterns | Dockerfile, Docker Compose | -| Workflows | Step-by-step procedures | Agent creation, session close | -| Troubleshooting | Problem β†’ solution | Common Docker issues | -| External URLs | Documentation links | OpenCode docs, plugin repos | - ---- - -## Integration Points - -### External Dependencies - -| Dependency | Type | Purpose | Integration | -|------------|------|---------|-------------| -| **OpenCode Core** | Platform | Skill loading system | `skill()` tool, config directory | -| **OpenCode Docs** | Documentation | URL reference mapping | Fetched via `webfetch` | -| **beads** | Issue tracker | Task tracking | `bd` CLI commands | -| **opencode-swarm** | Plugin | Multi-agent orchestration | `swarm_*` tool commands | -| **OpenAgentsControl (OAC)** | Framework | Plan-first development | `/add-context`, `/commit` commands | -| **oh-my-opencode-slim** | Plugin | Enhanced capabilities | Provider configs, cartography | -| **llama.cpp / Ollama** | LLM runtime | Local model serving | HTTP API endpoints | -| **Dolt** | Database | Beads SQL backend | `bd sync` β†’ Dolt SQL | - -### Consumer Modules - -| Consumer | Interaction | Data Flow | -|----------|-------------|-----------| -| **OpenZeus Agent** | Reads skills | Intent detection β†’ skill loading | -| **OpenCode TUI** | Displays skills | Skill selection UI, autocomplete | -| **Sync Scripts** | Syncs skills | `./scripts/sync-utils.sh push/pull` | - -### Plugin & External Tool Hooks - -| Hook/Event | Skill Responsible | Integration | -|------------|------------------|-------------| -| `swarm_*` commands | `zeus-swarm` | Multi-agent orchestration | -| `bd` commands | `zeus-beads` | Issue tracking workflow | -| `/add-context`, `/commit` | `zeus-oac` | Pattern learning framework | -| Provider switching | `zeus-omo` | `opencode provider set` | -| `opencode cartography` | `zeus-omo` | Codebase mapping | - -### Config Paths (Knowledge System) - -``` -~/.config/opencode/ # Global config root -β”œβ”€β”€ opencode.json # Main config (skill references) -β”œβ”€β”€ agents/ -β”‚ └── OpenZeus.md # Master agent with skill triggers -β”œβ”€β”€ skills/ # Skill bundles (15 zeus-* skills) -β”‚ β”œβ”€β”€ zeus-core/SKILL.md # OpenCode internals reference -β”‚ β”œβ”€β”€ zeus-agents/SKILL.md # Agent creation templates -β”‚ β”œβ”€β”€ zeus-commands/SKILL.md # Command creation templates -β”‚ β”œβ”€β”€ zeus-skills/SKILL.md # Skill creation guide -β”‚ β”œβ”€β”€ zeus-upskill/SKILL.md # OpenZeus self-extension -β”‚ β”œβ”€β”€ zeus-swarm/SKILL.md # Swarm orchestration -β”‚ β”œβ”€β”€ zeus-llm/SKILL.md # Local LLM configuration -β”‚ β”œβ”€β”€ zeus-omo/SKILL.md # oh-my-opencode-slim plugin -β”‚ β”œβ”€β”€ zeus-docker/SKILL.md # Docker/containerization -β”‚ β”œβ”€β”€ zeus-sql/SKILL.md # SQL/database patterns -β”‚ β”œβ”€β”€ zeus-self/SKILL.md # Self-diagnostics -β”‚ β”œβ”€β”€ zeus-context/SKILL.md # Context optimization -β”‚ β”œβ”€β”€ zeus-beads/SKILL.md # Beads issue tracker -β”‚ β”œβ”€β”€ zeus-oac/SKILL.md # OpenAgentsControl framework -β”‚ └── zeus-boston-terrier/SKILL.md # (Example/niche skill) -└── commands/ # Custom command templates - └── [user-defined commands] - -/.opencode/ # Project-level overrides -└── skills/ # Project-specific skills -``` - -OpenCode skill discovery also recognizes Claude/agents-compatible skill roots: - -```text -.opencode/skills//SKILL.md -~/.config/opencode/skills//SKILL.md -.claude/skills//SKILL.md -~/.claude/skills//SKILL.md -.agents/skills//SKILL.md -~/.agents/skills//SKILL.md -``` - ---- - -## Skill Taxonomy - -### Category 1: OpenCode Platform Skills - -| Skill | Responsibility | Lines | -|-------|----------------|-------| -| `zeus-core` | OpenCode config, schema, URLs, built-in agents/commands | ~240 | -| `zeus-agents` | Agent creation templates, current modes, permissions | ~455 | -| `zeus-commands` | Command templates, arguments, backtick shell injection, `@file` references | ~315 | -| `zeus-skills` | Canonical general skill creation/editing guide | ~170 | -| `zeus-upskill` | OpenZeus skill registration workflow; delegates general concepts to `zeus-skills` | ~120 | - -### Category 2: Infrastructure Skills - -| Skill | Responsibility | External Dependency | -|-------|----------------|---------------------| -| `zeus-docker` | Docker, containers, Compose, networking | Docker daemon | -| `zeus-sql` | SQL queries, schema design, ORMs | PostgreSQL/SQLite/MySQL | -| `zeus-llm` | llama.cpp, Ollama, llama-swap setup | LLM HTTP servers | -| `zeus-beads` | Issue tracking with bd CLI | Dolt SQL backend | - -### Category 3: Orchestration Skills - -| Skill | Responsibility | External Dependency | -|-------|----------------|---------------------| -| `zeus-swarm` | Multi-agent worktrees, feature/task mgmt | opencode-swarm plugin | -| `zeus-oac` | Plan-first dev, approval gates, pattern learning | OpenAgentsControl | -| `zeus-omo` | Provider configs, cartography, tmux | oh-my-opencode-slim | - -### Category 4: Self-Management Skills - -| Skill | Responsibility | Trigger Keywords | -|-------|----------------|-----------------| -| `zeus-self` | Runtime diagnostics, session status | `health check`, `diagnostics` | -| `zeus-context` | Context compression, cleanup, handoff | `context cleanup`, `compress` | - -### Category 5: Specialty Skills - -| Skill | Responsibility | Notes | -|-------|----------------|-------| -| `zeus-boston-terrier` | Breed reference | Example/niche skill | - ---- - -## Key Architectural Decisions - -### 1. Markdown-Based Knowledge -Skills use plain markdown for portability and easy editing without specialized tooling. - -### 2. On-Demand Loading -Skills are loaded only when needed, preserving context window for active work. - -### 3. Bundle Per Domain -Each skill is self-contained with all relevant information, avoiding cross-skill dependencies. - -### 4. Trigger-Keyword Matching -Simple keyword detection enables automatic skill loading without complex intent classification. - -### 5. Multi-Root Discovery -OpenCode skills can live in `.opencode`, global OpenCode config, Claude-compatible roots, or agents-compatible roots. - -### 6. Bidirectional Sync -OpenZeus repo ↔ config directory sync via `sync-utils.sh` scripts. - ---- - -## Quality Attributes - -| Attribute | Implementation | -|-----------|----------------| -| **Discoverability** | YAML frontmatter + trigger keywords in OpenZeus.md | -| **Portability** | Pure markdown, no build step required | -| **Maintainability** | One skill = one domain, clear boundaries | -| **Testability** | Manual verification via `skill()` loading | -| **Versioning** | Git-tracked in OpenZeus repo | - ---- - -## Anti-Patterns to Avoid - -1. **Cross-skill dependencies** β€” Each skill should be self-contained -2. **Procedural logic in skills** β€” Skills are reference, agents reason -3. **Secrets in skills** β€” Use environment variables, never hardcode -4. **Outdated URLs** β€” Periodically validate external documentation links - ---- - -## Session Handoff Protocol - -When ending a session involving skill modifications: - -``` -1. git status # Check changed files -2. skill("zeus-self") # Verify system health if needed -3. skill("zeus-beads") # Follow project Beads policy -4. Run required verification # e.g., frontmatter check, npm test -5. Commit/sync/push only when authorized by user/project policy -``` - ---- - -End of codemap. +For exact OpenCode syntax, use the current schema and official docs. diff --git a/skills/zeus-agents/SKILL.md b/skills/zeus-agents/SKILL.md index f9285d0..35012fb 100644 --- a/skills/zeus-agents/SKILL.md +++ b/skills/zeus-agents/SKILL.md @@ -1,458 +1,37 @@ --- name: zeus-agents -description: Provide exhaustive templates, patterns, and workflows to create OpenCode agents. +description: Design and review non-trivial OpenCode agents. Use for agent architecture, modes, model inheritance, permissions, subagent relationships, or migration beyond the basic native agent creator. --- ---- - -## When to Create an Agent - -Create a new agent when the user: -- Asks for a specialized assistant (e.g., "create a code reviewer agent") -- Needs a persistent, reusable prompt pattern -- Wants a specific mode/permission combination -- Needs a different model for a specific task type -- Has a recurring workflow they want to encapsulate - ---- - -## Agent Creation Workflow - -``` -1. Determine identity: - - Name (becomes file name + identifier) - - Description (shown in @ autocomplete) - - Mode (`primary`, `subagent`, or `all`) - - Model override (if needed) - - Permissions via `permission` (`tools` is deprecated for permissions) - -2. Design the system prompt: - - Role and identity statement - - Core capabilities - - Behavior rules - - Specific domain knowledge - -3. Write the markdown file: - - Global: ~/.config/opencode/agents/.md - - Project: /.opencode/agents/.md - - Frontmatter with options - - Markdown body with system prompt - -4. Report location and usage: - "Agent '' created at . Available via @ or as primary agent." -``` - ---- - -## Frontmatter Options - -| Option | Type | Required | Description | -|---|---|---|---| -| `description` | string | Yes | What the agent does (shown in autocomplete) | -| `mode` | `primary` \| `subagent` \| `all` | No | Default: `all` | -| `model` | string | No | Override default model | -| `steps` | number | No | Max iterations before forced response | -| `temperature` | number | No | 0.0–1.0 (default: model-specific) | -| `hidden` | boolean | No | Hide from @ autocomplete (subagent only) | -| `permission` | object | No | Tool permissions | -| `aliases` | string[] | No | Alternative names | -| `display_name` | string | No | UI display name | - -Use `permission` for edit/write/bash/webfetch access. Older `tools`-based permission examples are deprecated; do not use `tools` to grant or deny permissions in new agents. - ---- - -## Mode Semantics - -| Mode | Primary? | Subagent? | Use case | -|---|---|---|---| -| `primary` | Yes | No | Switchable via Tab key, full development | -| `subagent` | No | Yes | Invoke via @ mentions, specialized tasks | -| `all` | Yes | Yes | Both β€” default if not specified | - ---- - -## Permission Format - -```yaml -permission: - edit: allow # allow | ask | deny - write: allow - webfetch: allow - bash: - "*": "ask" # Default: ask for everything - "git status *": allow - "git diff *": allow - "git log *": allow - "grep *": allow - "find *": allow - "git push": ask # Explicit confirm before push -``` - -Permission values are `allow`, `ask`, or `deny`. Keep destructive commands as `ask` unless the project explicitly authorizes automation. - -Bash permission glob examples: -```yaml -bash: - "*": ask # Everything asks - "git status *": allow - "git diff *": allow - "git log *": allow - "npm *": allow - "pytest *": allow - "ruff *": allow -``` - ---- - -## Complete Agent Markdown Template - -```markdown ---- -description: "Brief description of what this agent does" -mode: subagent -model: opencode-go/big-pickle -steps: 20 -temperature: 0.1 -hidden: false -permission: - edit: allow - write: allow - webfetch: allow - bash: - "*": ask - "git status *": allow - "git diff *": allow -aliases: - - "shortname" - - "alias" -display_name: "Display Name" ---- - -# Agent Name - -You are [role description]. - -## Core Capabilities - -- [capability 1] -- [capability 2] -- [capability 3] - -## Behavior Rules - -1. [Rule 1 β€” be specific] -2. [Rule 2 β€” be specific] -3. [Rule 3 β€” be specific] - -## [Optional: Domain Knowledge] - -- [Specific knowledge areas] -- [Relevant patterns or conventions] -- [File locations or tools] - -## [Optional: Example Workflows] - -### Example 1 -[Step-by-step workflow description] - -### Example 2 -[Another workflow description] -``` - ---- - -## Common Agent Patterns - -### Pattern 1: Read-Only Reviewer - -```markdown ---- -description: "Read-only code reviewer that suggests improvements" -mode: subagent -permission: - edit: deny - write: deny - bash: - "*": ask - "git log *": allow - "git diff *": allow - "git show *": allow - "grep *": allow - "find *": allow ---- - -You are a code reviewer. You can read files and run read-only commands. - -Your task: Review code and suggest improvements without making changes. - -Review focus areas: -- Code quality and best practices -- Potential bugs and edge cases -- Performance implications -- Security considerations - -Provide constructive feedback without making direct changes. -``` - -### Pattern 2: Task-Specific Builder - -```markdown ---- -description: "Specialized builder for specific task type" -mode: all -permission: - edit: allow - write: allow - bash: - "*": ask - "git add *": allow - "git commit *": ask ---- - -You are a [specialized builder]. You create and modify code for [specific task]. +# OpenCode agent design -Focus on: [specific domain] - -Core rules: -1. Follow existing code patterns in the project -2. Run tests before reporting completion -3. Show exact commands and files changed -``` +For a basic scaffold, prefer `opencode agent create`. Use this skill when the +design itself matters. -### Pattern 3: Fast Executor +## Native V2 example ```markdown --- -description: "Fast execution agent for routine tasks" -mode: all -steps: 5 -temperature: 0.1 -permission: - edit: allow - write: allow - bash: - "*": ask - "git status *": allow - "git diff *": allow - "npm test *": allow ---- - -You are a fast executor. Complete tasks quickly and concisely. - -Rules: -1. Execute routine allowed commands immediately -2. Report what was done in 1-2 sentences -3. Show exact commands run -``` - -### Pattern 4: Data Analyst - -```markdown ---- -description: "Analyze data and generate reports" +description: Reviews changes for correctness and regressions mode: subagent -steps: 15 -permission: - edit: deny - write: allow - bash: - "*": ask - "python *": allow - "python3 *": allow - "Rscript *": allow ---- - -You are a data analyst. Analyze datasets and generate insights. - -Capabilities: -- Run Python/R scripts for data analysis -- Generate CSV/JSON reports -- Create visualizations -- Summarize findings - -Always show key metrics and methodology. -``` - -### Pattern 5: Security Auditor - -```markdown ---- -description: "Security-focused code auditor" -mode: subagent -permission: - edit: deny - write: deny - bash: - "*": ask - "git log *": allow - "git diff *": allow - "grep *": allow - "find *": allow - "npm audit *": allow - "pip audit *": allow ---- - -You are a security expert. Focus on identifying potential security issues. - -Look for: -- Input validation vulnerabilities -- Authentication and authorization flaws -- Data exposure risks -- Dependency vulnerabilities -- Configuration security issues -- Secrets in code or config files -- SQL injection, XSS, CSRF patterns -- Insecure deserialization - -Report severity (Critical/High/Medium/Low) for each finding. -``` - -### Pattern 6: Documentation Writer - -```markdown ---- -description: "Technical documentation writer" -mode: all -permission: - edit: allow - write: allow - bash: - "*": ask - "grep *": allow - "find *": allow ---- - -You are a technical writer. Create clear, comprehensive documentation. - -Focus on: -- Clear explanations with examples -- Proper structure (headings, lists, tables) -- Code examples in appropriate languages -- User-friendly language -- API documentation with parameters - -Follow the project's documentation style if detectable. -``` - -### Pattern 7: Test Engineer - -```markdown +permissions: + - action: edit + resource: "*" + effect: deny + - action: shell + resource: "*" + effect: deny --- -description: "Test engineer for writing and running tests" -mode: all -permission: - edit: allow - write: allow - bash: - "*": ask - "pytest *": allow - "npm test *": allow - "git add *": allow - "git commit *": ask ---- - -You are a test engineer. Write and run tests for the codebase. -Responsibilities: -- Write unit tests for new code -- Write integration tests for features -- Run existing test suites -- Fix failing tests -- Achieve target coverage - -Test conventions: -- Follow existing test structure -- Use descriptive test names -- Include setup/teardown where needed +Review the current changes. Report findings in severity order. ``` -### Pattern 8: Git Master - -```markdown ---- -description: "Git workflow specialist" -mode: all -steps: 10 -permission: - edit: allow - write: allow - bash: - "*": ask - "git status *": allow - "git diff *": allow - "git log *": allow - "git add *": allow - "git commit *": allow - "git push": ask ---- - -You are a Git master. Handle all Git workflows with best practices. +Use ordered `permissions`. The last matching rule wins. -Services: -- Create and manage branches -- Stage, commit, and push changes -- Resolve merge conflicts -- Rebase and squash commits -- Write clear commit messages - -Rules: -- Always confirm before git push -- Warn on force pushes to protected branches -- Use conventional commit format -- Keep commits atomic and focused -``` +Do not hard-code a model by default; subagents can inherit the parent session +model. Use a model override only for a real capability/cost/latency reason. ---- - -## Creating Agent via Config (JSON) - -```json -{ - "agent": { - "my-agent": { - "description": "What this agent does", - "mode": "subagent", - "model": "opencode-go/big-pickle", - "steps": 20, - "temperature": 0.1, - "permission": { - "edit": "allow", - "write": "allow", - "bash": { "*": "ask", "git status *": "allow", "git diff *": "allow" } - }, - "aliases": ["short", "alias"], - "display_name": "My Agent" - } - } -} -``` - ---- - -## File Write Command - -```bash -# Global agent -write /home/USER/.config/opencode/agents/.md - -# Project agent -write /path/to/project/.opencode/agents/.md -``` - ---- - -## Troubleshooting - -| Problem | Fix | -|---|---| -| Agent not in @ autocomplete | Ensure `hidden: false` or absent; check file is in `agents/` | -| Agent ignored | Check `mode` matches invocation context | -| Changes not applied | Restart OpenCode or run `opencode agent reload` | -| JSON invalid | Run: `python3 -c "import json; json.load(open('/path/to/config'))"` | -| Permission denied | Check permission settings for edit/write/bash | -| File not found | Verify correct path: global `~/.config/opencode/agents/` or project `.opencode/agents/` | - ---- +Do not generate legacy top-level `permission`, `tools`, `temperature`, +`top_p`, `prompt`, `disable`, or `maxSteps` fields in new V2 agents. -End of skill. +For legacy agents, use `zeus-migration`. diff --git a/skills/zeus-beads/SKILL.md b/skills/zeus-beads/SKILL.md deleted file mode 100644 index 1107da5..0000000 --- a/skills/zeus-beads/SKILL.md +++ /dev/null @@ -1,353 +0,0 @@ ---- -name: zeus-beads -description: Expert reference for Steve Yegge's Beads issue tracker β€” a git-backed, dependency-aware graph tracker for AI coding agents. Covers setup, commands, workflows, and OpenCode integration. ---- - -# zeus-beads (Skill) - -Purpose: Expert reference for Steve Yegge's Beads issue tracker β€” a git-backed, dependency-aware graph tracker for AI coding agents. Covers setup, commands, workflows, and OpenCode integration. - -**πŸ”— Beads Repository**: https://github.com/steveyegge/beads - ---- - -## What is Beads? - -Beads is a persistent memory system for AI coding agents. It replaces messy markdown plans with a dependency-aware graph tracker. - -**Key features:** -- **Zero setup** β€” `bd init` creates project-local database -- **Dependency tracking** β€” Four dependency types (blocks, related, parent-child, discovered-from) -- **Git-backed** β€” Powered by Dolt SQL database with full history -- **Agent-optimized** β€” JSON output, ready work detection -- **Hash-based IDs** β€” `bd-a1b2` prevents merge collisions - -**Why use it?** -- Agents forget everything between sessions -- Beads provides persistent context across compactions -- Dependency graph shows blockers and ready work -- Git-tracked issues sync with code changes - ---- - -## Documentation Links - -| Resource | URL | -|---|---| -| Main README | https://github.com/steveyegge/beads | -| Installation Guide | https://github.com/steveyegge/beads/blob/main/docs/INSTALLING.md | -| Quick Start | https://steveyegge.github.io/beads/getting-started/quickstart | -| CLI Reference | https://github.com/steveyegge/beads (run `bd --help`) | -| Claude Code Integration | https://steveyegge.github.io/beads/integrations/claude-code | -| GitHub Copilot Integration | https://steveyegge.github.io/beads/integrations/github-copilot | -| OpenCode Plugin (opencode-beads) | https://github.com/joshuadavidthomas/opencode-beads | -| Enhanced Plugin (beads-compound) | https://github.com/roberto-mello/beads-compound-plugin | - ---- - -## Installation - -### 1. Install beads CLI - -**via npm (recommended):** -```bash -npm install -g @beads/bd -``` - -**via Homebrew (macOS/Linux):** -```bash -brew install beads -``` - -**via script:** -```bash -curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash -``` - -### 2. Install Dolt (required dependency) - -```bash -# Linux/macOS -sudo bash -c 'curl -L https://github.com/dolthub/dolt/releases/latest/download/install.sh | bash' - -# Or manual download from https://github.com/dolthub/dolt/releases -``` - -### 3. Install OpenCode plugin - -Add to `~/.config/opencode/opencode.json`: -```json -{ - "plugin": ["opencode-beads"] -} -``` - -### 4. Initialize in project - -```bash -cd your-project -bd init -``` - ---- - -## Essential Commands - -### Finding Work -| Command | Description | -|---|---| -| `bd ready` | Show issues with no blockers (ready to work) | -| `bd list --status=open` | List all open issues | -| `bd list --status=in_progress` | Show active work | -| `bd blocked` | Show all blocked issues | -| `bd show ` | Detailed issue view with dependencies | - -### Creating Issues -| Command | Description | -|---|---| -| `bd create "Title" -t task -p 2` | Create task (priority 0-4) | -| `bd create "Title" -t bug -p 0` | Create critical bug | -| `bd create "Title" -t epic` | Create epic (parent issue) | -| `bd create "Title" --parent bd-a3f8` | Create subtask under epic | - -### Working on Issues -| Command | Description | -|---|---| -| `bd update --claim` | Start working (claim issue) | -| `bd update --status in_progress` | Set status manually | -| `bd update --notes "context"` | Add notes | -| `bd close --reason "Fixed"` | Complete issue | -| `bd close ` | Close multiple at once | - -### Dependencies -| Command | Description | -|---|---| -| `bd dep add ` | Add dependency (A blocks B) | -| `bd dep tree ` | Show dependency tree | -| `bd dep cycles` | Detect circular dependencies | - -### Project Health -| Command | Description | -|---|---| -| `bd stats` | Statistics (open/closed/blocked) | -| `bd doctor` | Check for issues | -| `bd doctor --check=conventions` | Convention drift check | -| `bd lint` | Check issue quality | -| `bd stale` | Find inactive issues | - ---- - -## Priority Reference - -| Priority | Value | Use Case | -|---|---|---| -| P0 | 0 | Critical β€” blocking release | -| P1 | 1 | High β€” important for current sprint | -| P2 | 2 | Medium β€” default priority | -| P3 | 3 | Low β€” nice to have | -| P4 | 4 | Backlog β€” someday/maybe | - ---- - -## Issue Types - -| Type | Description | -|---|---| -| `task` | Work item (default) | -| `bug` | Something broken | -| `feature` | New functionality | -| `epic` | Large feature with subtasks | -| `chore` | Maintenance (deps, tooling) | -| `decision` | Architectural decision | - ---- - -## Workflow: Session Close Protocol - -Before ending a session, follow the repository's `AGENTS.md` and Beads policy. Some projects require commit/push; others explicitly forbid it. Remote pushes require explicit user or project authorization. - -```bash -# 1. Check what changed -git status - -# 2. Review Beads work state -bd list --status=in_progress - -# 3. Update issues/notes according to project policy -bd show -bd update --notes "session handoff context" - -# 4. Commit/sync/push only when authorized by AGENTS.md or the user -git status -``` - ---- - -## Workflow: Complete Task - -```bash -# 1. Find ready work -bd ready - -# 2. Review issue -bd show bd-xxx - -# 3. Claim work -bd update bd-xxx --claim - -# 4. Implement... - -# 5. Close and commit only if project policy and user scope allow it -bd close bd-xxx --reason "Implemented feature X" -git add -git commit -m "feat: implement X" -# git push requires explicit user/project authorization -``` - ---- - -## Workflow: Create Dependent Work - -```bash -# Create feature -bd create "Implement auth" -t feature -p 1 - -# Create dependent task -bd create "Write tests" -t task -p 1 - -# Link: tests depends on auth -bd dep add tests-id auth-id -``` - -Now `bd ready` only shows `auth-id` until it's closed. - ---- - -## Session Recovery - -After session compaction or new session: - -```bash -bd prime -``` - -This injects ~1-2k tokens of workflow context including: -- Ready issues -- Recent activity -- Session close protocol reminders - ---- - -## Configuration - -### Set prefix (issue ID format) -```bash -bd init myprefix # Creates myprefix-1, myprefix-2, etc. -``` - -### Validate on create -```bash -bd config set validation.on-create warn -``` - -### Enable stealth mode (local only, no git) -```bash -bd init --stealth -``` - ---- - -## Troubleshooting - -| Problem | Solution | -|---|---| -| `bd: command not found` | Install beads: `npm install -g @beads/bd` | -| `dolt not found` | Install Dolt: see Installation section | -| `bd init fails` | Ensure `dolt` is on PATH and git is initialized | -| Context not injecting | Run `bd prime` manually; check plugin loaded | - ---- - -## Session Close Checklist - -``` -[ ] 1. git status (check what changed) -[ ] 2. bd list --status=in_progress -[ ] 3. Update/close beads allowed by current task scope -[ ] 4. Commit only if authorized by user/project policy -[ ] 5. Push only if explicitly authorized by user/project policy -``` - -Always follow the active repository's `AGENTS.md`/Beads instructions. Do not claim remote work is complete unless the authorized push/sync actually succeeded. - ---- - -## Beads Rules for Agents - -- **Default**: Use beads for ALL task tracking -- **Prohibited**: Do NOT use TodoWrite, TaskCreate, or markdown files -- **Before code**: Create beads issue FIRST, then implement -- **Memory**: Use `bd remember "insight"` for persistent learnings -- **Search**: `bd memories ` to recall past insights - ---- - -## Related Plugins - -| Plugin | Description | -|---|---| -| [opencode-beads](https://github.com/joshuadavidthomas/opencode-beads) | OpenCode integration with /bd-* commands | -| [beads-compound](https://github.com/roberto-mello/beads-compound-plugin) | Enhanced with memory/knowledge capture | - ---- - -## Web Visualization - -Beads has multiple web UI options for visualizing your issue tracker: - -### Community Web UIs - -| Tool | Description | Install | -|------|-------------|---------| -| **[beads-ui](https://github.com/mantoni/beads-ui)** | Local web interface with live updates and kanban board. Recommended by official docs. | `npx beads-ui start` | -| **[BeadBoard](https://github.com/zenchantlive/beadboard)** | Next.js dashboard with DAG dependency graph, multi-agent orchestration, swarm coordination | `npx skills add zenchantlive/beadboard` | -| **[beads-web](https://github.com/weselow/beads-web)** | Actively maintained fork. 7 visual themes, drag-and-drop, cross-platform binary | Download from releases | -| **[Foolery](https://github.com/acartine/foolery)** | Visual control surface with dependency-aware wave planning, terminal monitoring | See project README for current install command | - -### Quick Start (beads-ui) - -```bash -# From your project directory (where .beads/ exists) -npx beads-ui start - -# Opens at http://127.0.0.1:3000 -``` - -### For Permanent Installation - -```bash -npm install -g beads-ui -beads-ui start # From any project with .beads/ -``` - -### Official Web UI (monitor-webui) - -The beads repository includes an official web UI example at `examples/monitor-webui`. However, it requires Go to build and the beads daemon to be running. - ---- - -## OpenCode Integration - -The `opencode-beads` plugin is bundled with OpenCode. Add to your `opencode.json`: - -```json -{ - "plugin": ["opencode-beads"] -} -``` - -This provides `/bd-*` slash commands for beads operations within OpenCode. - ---- - -End of skill. diff --git a/skills/zeus-beads/codemap.md b/skills/zeus-beads/codemap.md deleted file mode 100644 index c11d6f6..0000000 --- a/skills/zeus-beads/codemap.md +++ /dev/null @@ -1,19 +0,0 @@ -# skills/zeus-beads/ - - - -## Responsibility - - - -## Design - - - -## Flow - - - -## Integration - - diff --git a/skills/zeus-boston-terrier/SKILL.md b/skills/zeus-boston-terrier/SKILL.md deleted file mode 100644 index a29938c..0000000 --- a/skills/zeus-boston-terrier/SKILL.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -name: zeus-boston-terrier -description: Everything about Boston Terrier dogs β€” breed info, care, temperament, and history ---- - ---- - -## Overview - -The Boston Terrier is a small, friendly dog breed originating in the United States. Nicknamed "The American Gentleman" for their tuxedo-like black and white coat and polite demeanor. Always search web if user asks you anything regarding bostoin terrier - ---- - -## Breed Overview - -| Attribute | Details | -|-----------|---------| -| **Height** | 10-17 inches | -| **Weight** | 12-25 pounds | -| **Lifespan** | 11-13 years | -| **Group** | Non-Sporting | -| **Coat** | Short, smooth, sleek | -| **Colors** | Black & white, brindle & white, seal & white | -| **Hypoallergenic** | No | - ---- - -## Temperament - -Boston Terriers are: -- **Friendly** β€” Love meeting new people and other animals -- **Intelligent** β€” Quick learners, eager to please -- **Playful** β€” Natural comedians, love to entertain -- **Affectionate** β€” Bond strongly with family -- **Sensitive** β€” Don't respond well to harsh training - -### Personality Traits - -- Gentle and well-mannered indoors -- Good with children when properly socialized -- Can be stubborn at times β€” patience is key -- Prone to separation anxiety β€” don't leave alone long -- Alert and makes a decent watchdog (but not aggressive) - ---- - -## History - -- **Origin**: Boston, Massachusetts, USA (late 1800s) -- **Ancestry**: English Bulldog + White English Terrier -- **Original purpose**: Originally bred for pit fighting, evolved into companion dog -- **AKC recognized**: 1893 β€” first US breed recognized by AKC - ---- - -## Care Guide - -### Exercise -- Moderate exercise needs: ~1 hour per day -- Enjoy short walks, fetch, and playtime -- **Avoid**: Overexertion in heat (brachycephalic = flat-faced) -- Best exercised in cool parts of the day - -### Grooming -- Short coat sheds minimally -- Weekly brushing to remove loose hair -- Regular nail trimming -- Clean facial folds to prevent skin issues -- Occasional baths only - -### Diet -- Prone to obesity β€” monitor food intake -- High-quality dog food, appropriate portions -- Avoid over-treating during training - -### Training -- Eager to please β€” responds well to positive reinforcement -- Sensitive nature β€” use gentle, motivational methods -- Early socialization recommended -- Can get bored with repetitive training β€” keep it fun! - ---- - -## Health Concerns - -### Common Issues (Brachycephalic Breeds) -- **Brachycephalic Syndrome** β€” breathing difficulties due to short snout -- **Heat sensitivity** β€” cannot regulate temperature well -- **Eye problems** β€” prominent eyes prone to injuries/irritations -- **Patellar luxation** β€” trick knee (common small dog issue) -- **Skin allergies** β€” can suffer from environmental/food allergies - -### Tips -- Regular vet check-ups -- Keep in air-conditioned environment in hot weather -- Avoid strenuous exercise in humidity -- Monitor weight closely - ---- - -## Fun Facts - -- πŸ• First dog breed developed in America -- 🎽 Called "American Gentleman" due to tuxedo markings -- πŸ™οΈ Official mascot of Boston University -- 🐾 One of the top 20 most popular dog breeds in the US -- 🎭 Known for their clownish, entertaining personality - ---- - -## Is a Boston Terrier Right for You? - -**Good for:** -- βœ… Apartment living -- βœ… Families with children -- βœ… First-time dog owners -- βœ… City dwellers -- βœ… Those wanting a companionable, indoor dog - -**Considerations:** -- ⚠️ Cannot be left alone for long periods -- ⚠️ Brachycephalic health issues -- ⚠️ May be stubborn during training -- ⚠️ Needs climate-controlled environment - ---- - -End of skill. diff --git a/skills/zeus-boston-terrier/codemap.md b/skills/zeus-boston-terrier/codemap.md deleted file mode 100644 index aa48c84..0000000 --- a/skills/zeus-boston-terrier/codemap.md +++ /dev/null @@ -1,19 +0,0 @@ -# skills/zeus-boston-terrier/ - - - -## Responsibility - - - -## Design - - - -## Flow - - - -## Integration - - diff --git a/skills/zeus-commands/SKILL.md b/skills/zeus-commands/SKILL.md index 07dd077..90b7543 100644 --- a/skills/zeus-commands/SKILL.md +++ b/skills/zeus-commands/SKILL.md @@ -1,316 +1,26 @@ --- name: zeus-commands -description: Provide exhaustive templates, patterns, and workflows to create OpenCode custom commands. +description: Design and review OpenCode slash commands. Use for repeatable prompt workflows, command arguments, safe shell expansion, agent selection, or command migration. --- ---- - -## When to Create a Command - -Create a new command when the user: -- Has a repetitive task they want to automate -- Wants a quick shortcut for a complex workflow -- Needs to pass arguments to a template prompt -- Wants to inject shell output or file content into a prompt -- Wants to use a specific model or agent for a task - ---- - -## Command Creation Workflow - -``` -1. Determine identity: - - Name (becomes file name, e.g., "deploy.md" β†’ /deploy) - - Description (shown in TUI when typing /) - - Agent (which agent to invoke) - -2. Design the template: - - Instructions for the agent - - Use $ARGUMENTS for user input - - Use backticks to inject shell output - - Use @file references to include file content - -3. Write the markdown file: - - Global: ~/.config/opencode/commands/.md - - Project: /.opencode/commands/.md - -4. Report: "Command / created at " -``` - ---- - -## Frontmatter Options - -| Option | Type | Required | Description | -|---|---|---|---| -| `description` | string | Yes | Shown in TUI when typing / | -| `agent` | string | No | Which agent to invoke (default: current agent) | -| `model` | string | No | Override model for this command | -| `subtask` | boolean | No | Force subagent invocation | - ---- - -## Special Placeholders - -| Placeholder | Expands to | Example | -|---|---|---| -| `$ARGUMENTS` | Everything after command name | `/deploy production` β†’ "production" | -| `$1`, `$2`...`$9` | Positional arguments | `/create user alice admin` β†’ $1="user", $2="alice", $3="admin" | -| Backtick shell block | Bash output injected | See shell examples below | -| `@file` | File content included | `@README.md` β†’ README.md contents | - -### Placeholder Examples - -#### $ARGUMENTS β€” All remaining args as one string - -``` -/component Button -``` -Template: `Create a component named $ARGUMENTS` -Result: `Create a component named Button` - -#### $1, $2, $3 β€” Positional arguments - -``` -/create user alice admin -``` -Template: `Create a $1 named $2 with role $3` -Result: `Create a user named alice with role admin` - -#### Backticks β€” Shell output injection - -``` ---- -description: Review recent changes ---- -Recent commits: -`git log --oneline -5` - -Changed files: -`git diff --stat` - -Review these changes. -``` - -#### @file β€” File content inclusion - -``` ---- -description: Review file ---- -Review this file: -@$ARGUMENTS -``` - ---- - -## Complete Command Markdown Template - -```markdown ---- -description: "Brief description of what this command does" -agent: general -model: opencode-go/big-pickle -subtask: false ---- - -[Template body with instructions and placeholders] - -[Use $ARGUMENTS, $1, $2 for input] -[Use shell commands in backticks for output injection] -[Use @file references for file inclusion] -``` - ---- - -## Common Command Patterns - -### Pattern 1: Simple Task Command - -```markdown ---- -description: Run tests with coverage -agent: build ---- - -Run the full test suite with coverage report and show any failures. -Focus on the failing tests and suggest fixes. -``` - -### Pattern 2: Argument-Based Task - -```markdown ---- -description: Create a new React component with TypeScript -agent: build ---- - -Create a new React component named $ARGUMENTS with TypeScript support. -Include proper typing and basic structure. -``` - -### Pattern 3: Multi-Argument Command - -```markdown ---- -description: Create a database migration -agent: build ---- - -Create a new database migration: -- Table name: $1 -- Action: $2 (create/drop/alter) -- Fields: $3 - -Output the migration file to db/migrations/ -``` - -### Pattern 4: Shell-Output-Injection - -```markdown ---- -description: Review recent git changes -agent: general ---- - -Recent git commits: -`git log --oneline -10` - -Changed files: -`git diff --stat` - -Review these changes and suggest improvements. -``` - -### Pattern 5: File-Inclusion - -```markdown ---- -description: Review a specific file -agent: general ---- - -Review the following file for bugs and improvements: -@$ARGUMENTS -``` - -### Pattern 6: Status Report Command - -```markdown ---- -description: Show project status -agent: general ---- - -Project status: -`git status` - -Recent changes: -`git log --oneline -5` +# OpenCode command design -Current branch: -`git branch --show-current` - -Provide a summary of the project state. -``` - -### Pattern 7: Deploy Command - -```markdown ---- -description: Deploy to environment -agent: build ---- - -Deploy application to $ARGUMENTS environment. - -Steps: -1. Review target environment: `$ARGUMENTS` -2. Run tests with `npm test` -3. Build with `npm run build` -4. Ask before running the project-specific deploy command. - -Report deployment status. -``` - -### Pattern 8: Code Analysis +Create a command only when a workflow benefits from a stable invocation. ```markdown --- -description: Analyze code complexity +description: Audit changes agent: general +subagent: true --- -Analyze the codebase for complexity issues. - -File structure: -`find . \( -name "*.py" -o -name "*.js" \) | head -20` - -Line counts: -`find . \( -name "*.py" -o -name "*.js" \) -print0 | xargs -0 wc -l | sort -n | tail -10` - -Report top 5 most complex files. +Audit $ARGUMENTS for bugs and missing tests. ``` ---- - -## Creating Command via Config (JSON) +Use `$ARGUMENTS` for the complete input and `$1`, `$2`, ... for positional +arguments. In V2, `subagent` is native; `subtask` is deprecated. -```json -{ - "command": { - "my-command": { - "template": "Template body with $ARGUMENTS...", - "description": "What this command does", - "agent": "general", - "model": "opencode-go/big-pickle", - "subtask": false - } - } -} -``` - ---- - -## File Write Command - -```bash -# Global command -write ~/.config/opencode/commands/.md - -# Project command -write /path/to/project/.opencode/commands/.md -``` - ---- - -## Command vs Agent - -| Aspect | Command | Agent | -|---|---|---| -| Trigger | `/name` in TUI | `@name` or Tab switch | -| Template | Yes β€” prompt template | Yes β€” system prompt | -| Arguments | Yes β€” $ARGUMENTS, $1-$9 | No (unless combined) | -| Shell injection | Yes β€” backtick shell commands | No | -| Mode | Always subtask | Primary or subagent | -| Persistence | Ephemeral template | Persistent persona | - -Commands are great for: repetitive workflows, injecting context, running specific agents. -Agents are great for: persistent personas, complex reasoning, multi-step tasks. - ---- - -## Troubleshooting - -| Problem | Fix | -|---|---| -| Command not found | Check file is in `commands/` with correct name | -| Overrides built-in | Custom commands can override `/init`, `/help`, etc. | -| Placeholders not replaced | Use exact syntax: `$ARGUMENTS`, `$1`, `$2`, backtick shell commands, `@file` | -| Arguments not parsing | Check positional markers `$1`/`$2` match usage | -| Wrong agent invoked | Set `agent` in frontmatter | -| Model not overridden | Set `model` in frontmatter | - ---- +Shell expansion uses `!`command``. It executes while the command is expanded, +outside the agent tool-permission flow, so never interpolate untrusted input. -End of skill. +Stored command text does not automatically turn `@path` into an attachment. diff --git a/skills/zeus-context/SKILL.md b/skills/zeus-context/SKILL.md deleted file mode 100644 index 790de65..0000000 --- a/skills/zeus-context/SKILL.md +++ /dev/null @@ -1,153 +0,0 @@ ---- -name: zeus-context -description: Context management strategies, compression analysis, and conversation optimization for OpenZeus. ---- - -# zeus-context (Skill) - -Purpose: Context management strategies, compression analysis, and conversation optimization for OpenZeus. - ---- - -## Context Health Assessment - -### Signal-to-Noise Analysis -| Pattern | Signal | Noise | -|---------|---------|-------| -| Completed tasks | βœ… Summary | ❌ Verbose tool outputs | -| Failed attempts | βœ… Root cause | ❌ Debug loops | -| Research findings | βœ… Conclusions | ❌ Raw exploration | -| Code implementations | βœ… Final version | ❌ Iteration history | - -### Compression Readiness Indicators -- βœ… **Task completed**: Implementation finished and verified -- βœ… **Research concluded**: Findings clear and documented -- βœ… **Dead-end exploration**: Failed attempts with clear outcomes -- βœ… **Large tool outputs**: Raw data no longer needed for reference - ---- - -## Compression Strategies - -### Range Selection Rules -1. **Prefer smaller ranges** β€” Better summary quality -2. **Target closed tasks** β€” Avoid active work -3. **Parallel compression** β€” Multiple independent ranges -4. **Preserve active context** β€” Keep current work visible - -### Quality Thresholds -| Context Size | Action | -|--------------|--------| -| < 50 messages | Monitor only | -| 50-100 messages | Identify compression candidates | -| 100-150 messages | Compress completed ranges | -| > 150 messages | Aggressive compression needed | - ---- - -## Context Optimization Patterns - -### High-Signal Preservation -Keep these in active context: -- **Current task requirements** -- **Error messages needing attention** -- **Files being actively modified** -- **Unresolved decisions** -- **Recent user feedback** - -### Low-Signal Compression -Compress these ranges: -- **Completed implementations** -- **Successful troubleshooting** -- **Large diagnostic outputs** -- **Resolved research questions** -- **Dead-end explorations** - ---- - -## Memory Management - -### Session Handoff Preparation -Before session end, preserve: -```markdown -**Working State**: -- Current directory: /path/to/work -- Active files: [list modified files] -- Git status: [staged/unstaged/pushed] -- Pending tasks: [list incomplete work] - -**Context Summary**: -- Major accomplishments: [key achievements] -- Current focus: [what you're working on] -- Next steps: [immediate actions needed] -- Blockers: [what's preventing progress] -``` - -### Cross-Session Continuity -- **Compress completed work** before handoff -- **Document active state** clearly -- **Preserve error context** if troubleshooting -- **Note configuration changes** made - ---- - -## Proactive Context Management - -### Continuous Housekeeping -- Monitor conversation length regularly -- Identify closed ranges immediately after task completion -- Compress in parallel when multiple ranges are ready -- Preserve high-signal ranges for reference - -### Quality-First Compression -- Write exhaustive summaries that preserve all context -- Include file paths, function signatures, key decisions -- Capture constraints and requirements discovered -- Maintain chronological flow with compressed blocks - ---- - -## Context Analysis Commands - -### Quick Assessment -``` -Context size: X messages -Compression candidates: [list ranges ready for compression] -Signal quality: High/Medium/Low -Active work: [current tasks requiring preservation] -``` - -### Detailed Analysis -``` -**Context Health Report** -Total messages: X -Signal-to-noise ratio: Y% -Compression opportunities: Z ranges identified - -**Range Analysis**: -- Messages 1-20: Completed setup (ready for compression) -- Messages 21-40: Active debugging (preserve) -- Messages 41-60: Research findings (compress after current task) - -**Recommendations**: -- Compress ranges: [specific message ranges] -- Preserve: [active context ranges] -- Monitor: [borderline ranges] -``` - ---- - -## Usage Triggers - -Load this skill when user mentions: -- "context cleanup" -- "compress context" -- "conversation getting long" -- "manage context" -- "optimize conversation" -- "session handoff" -- "prepare for next session" - ---- - -End of skill. \ No newline at end of file diff --git a/skills/zeus-context/codemap.md b/skills/zeus-context/codemap.md deleted file mode 100644 index 24ab5e2..0000000 --- a/skills/zeus-context/codemap.md +++ /dev/null @@ -1,19 +0,0 @@ -# skills/zeus-context/ - - - -## Responsibility - - - -## Design - - - -## Flow - - - -## Integration - - diff --git a/skills/zeus-core/SKILL.md b/skills/zeus-core/SKILL.md deleted file mode 100644 index 9126466..0000000 --- a/skills/zeus-core/SKILL.md +++ /dev/null @@ -1,272 +0,0 @@ ---- -name: zeus-core -description: Exhaustive OpenCode knowledge reference. Config paths, schema, URL mappings, built-in agents/commands, troubleshooting, and authoritative answers about OpenCode internals. ---- - ---- - -## Path Reference β€” OpenCode Config Directory - -### Global Config Root: `~/.config/opencode/` - -| File / Directory | Purpose | -|---|---| -| `opencode.json` | Main user config: providers, models, agents, plugins, commands, runtime options | -| `opencode.json.bak` | Backup of main config | -| `opencode.jsonc` | Same as `.json` but supports comments | -| `tui.json` | TUI-specific settings: theme, keybinds, scroll speed | -| `agent_hive.json` | Agent hive state (local registration/metadata for hive features) | -| `oh-my-opencode-slim.json` | oh-my-opencode-slim integration config | -| `agents/` | Custom agent definitions (`.md` markdown files) | -| `commands/` | Custom command templates (`.md` markdown files) | -| `skills/` | Local agent skill bundles (`.md` + supporting files) | -| `plugins/` | Custom plugin files | - -### Per-Project Config Root: `/.opencode/` - -| File / Directory | Purpose | -|---|---| -| `agents/` | Project-specific agent definitions | -| `commands/` | Project-specific command templates | -| `skills/` | Project-specific skills | -| `plugins/` | Project-specific plugins | - -### Skill Discovery Paths - -| Scope | Path | -|---|---| -| Project OpenCode | `.opencode/skills//SKILL.md` | -| Global OpenCode | `~/.config/opencode/skills//SKILL.md` | -| Project Claude-compatible | `.claude/skills//SKILL.md` | -| Global Claude-compatible | `~/.claude/skills//SKILL.md` | -| Project agents-compatible | `.agents/skills//SKILL.md` | -| Global agents-compatible | `~/.agents/skills//SKILL.md` | - ---- - -## Config Precedence (later overrides earlier) - -1. Remote (`/.well-known/opencode`) β€” organizational defaults -2. Global (`~/.config/opencode/`) β€” user preferences -3. Custom env (`OPENCODE_CONFIG`) β€” runtime overrides -4. Project (`.opencode/`) β€” project-specific settings -5. Inline env (`OPENCODE_CONFIG_CONTENT`) β€” runtime overrides - -Config files are **merged**, not replaced. Non-conflicting keys from all configs are preserved. - ---- - -## Complete URL Reference - -### OpenCode Core Docs - -| Topic | URL | -|---|---| -| Config schema | https://opencode.ai/docs/config/ | -| Agents | https://opencode.ai/docs/agents/ | -| Commands | https://opencode.ai/docs/commands/ | -| Tools | https://opencode.ai/docs/tools/ | -| Permissions | https://opencode.ai/docs/permissions/ | -| Skills | https://opencode.ai/docs/skills/ | -| Plugins | https://opencode.ai/docs/plugins/ | -| Models | https://opencode.ai/docs/models/ | -| Providers | https://opencode.ai/docs/providers/ | -| MCP servers | https://opencode.ai/docs/mcp-servers/ | -| LSP servers | https://opencode.ai/docs/lsp/ | -| Themes | https://opencode.ai/docs/themes/ | -| Keybinds | https://opencode.ai/docs/keybinds/ | -| TUI | https://opencode.ai/docs/tui/ | -| CLI | https://opencode.ai/docs/cli/ | -| Rules | https://opencode.ai/docs/rules/ | -| Enterprise | https://opencode.ai/docs/enterprise/ | -| Troubleshooting | https://opencode.ai/docs/troubleshooting/ | -| Windows/WSL | https://opencode.ai/docs/windows-wsl | - -### OpenCode Integrations - -| Topic | URL | -|---|---| -| GitHub | https://opencode.ai/docs/github/ | -| GitLab | https://opencode.ai/docs/gitlab/ | -| Share | https://opencode.ai/docs/share/ | - -### Topic β†’ URL Mapping (for proactive fetching) - -| Keyword(s) | Fetch this URL | -|---|---| -| `agent`, `subagent`, `primary`, `@mention` | https://opencode.ai/docs/agents/ | -| `command`, `/`, custom command | https://opencode.ai/docs/commands/ | -| `permission`, `allow`, `deny`, `ask` | https://opencode.ai/docs/permissions/ | -| `skill`, `bundle` | https://opencode.ai/docs/skills/ | -| `config`, `json`, `opencode.json` | https://opencode.ai/docs/config/ | -| `model`, `provider`, `llama-swap` | https://opencode.ai/docs/models/ | -| `tool`, `edit`, `write`, `bash` | https://opencode.ai/docs/tools/ | -| `plugin` | https://opencode.ai/docs/plugins/ | -| `mcp`, `server` | https://opencode.ai/docs/mcp-servers/ | -| `lsp`, `diagnostic` | https://opencode.ai/docs/lsp/ | -| `theme`, `color` | https://opencode.ai/docs/themes/ | -| `keybind`, `shortcut` | https://opencode.ai/docs/keybinds/ | -| `tui`, `terminal` | https://opencode.ai/docs/tui/ | -| `cli`, `command line` | https://opencode.ai/docs/cli/ | -| `rule`, `instruction` | https://opencode.ai/docs/rules/ | -| `github`, `gitlab` | https://opencode.ai/docs/github/ or /gitlab/ | -| `share` | https://opencode.ai/docs/share/ | -| `troubleshoot`, `error`, `bug` | https://opencode.ai/docs/troubleshooting/ | - ---- - -## Config File Format Reference - -### JSON vs JSONC - -| Format | Supports comments | Extension | -|---|---|---| -| JSON | No | `.json` | -| JSONC | Yes | `.jsonc` | - -JSONC example: -```jsonc -{ - "$schema": "https://opencode.ai/config.json", - // This is a comment - "model": "opencode-go/big-pickle", - "plugin": ["oh-my-opencode-slim"] -} -``` - -### Variable Substitution - -```json -{ - "model": "{env:OPENCODE_MODEL}", - "apiKey": "{env:ANTHROPIC_API_KEY}", - "instructions": ["{file:./custom-instructions.md}"] -} -``` - -- `{env:VAR_NAME}` β€” substitute environment variable -- `{file:path}` β€” substitute file contents - ---- - -## Agent Config Schema - -```json -{ - "agent": { - "my-agent": { - "description": "What this agent does (required)", - "mode": "subagent", // primary | subagent | all - "model": "provider/model", // optional override - "steps": 20, // max iterations - "temperature": 0.1, // 0.0-1.0 - "hidden": false, // hide from @ autocomplete - "permission": { - "edit": "allow", - "write": "allow", - "webfetch": "allow", - "bash": { - "*": "ask", - "git status *": "allow" - } - }, - "aliases": ["short", "alias"], - "display_name": "My Agent" - } - } -} -``` - -Agent modes are `primary`, `subagent`, and `all`. Use `permission` for tool access; `tools` is deprecated for permissions. - ---- - -## Command Config Schema - -```json -{ - "command": { - "my-command": { - "template": "Prompt template body...", - "description": "What this command does (required)", - "agent": "general", - "model": "provider/model", - "subtask": false - } - } -} -``` - -Command markdown supports `$ARGUMENTS`, positional `$1`/`$2`, shell output injection with backticks, and `@file` references. - ---- - -## Skill Frontmatter Schema - -```yaml ---- -name: my-skill -description: Brief description of what this skill provides. -license: MIT # optional -compatibility: opencode # optional -metadata: # optional - owner: docs ---- -``` - -Required fields: `name`, `description`. Recognized optional fields include `license`, `compatibility`, and `metadata`. - ---- - -## Schema Validation Command - -```bash -# Validate JSON syntax -python3 -c "import json; json.load(open('/path/to/config.json')); print('Valid')" - -# Validate with schema -python3 -c "import json, jsonschema; data=json.load(open('opencode.json')); jsonschema.validate(data, open('https://opencode.ai/config.json'))" -``` - ---- - -## Common Troubleshooting Commands - -| Problem | Fix | -|---|---| -| Config not loading | Check file path: `~/.config/opencode/opencode.json` | -| JSON invalid | Run: `python3 -c "import json; json.load(open('/path'))"` | -| Agent not appearing | Restart OpenCode or run `opencode agent reload` | -| Command not found | Check file is in `commands/` with `.md` extension | -| Changes not applied | Configs merge at runtime; restart OpenCode | -| Permission denied | Check `permission` settings in agent config | - ---- - -## Built-in Agents - -| Agent | Mode | Description | -|---|---|---| -| `build` | primary | Default development agent, all tools enabled | -| `plan` | primary | Restricted agent for analysis, asks before changes | -| `general` | subagent | General-purpose subagent, full tool access | -| `explore` | subagent | Fast read-only codebase explorer | -| `compaction` | primary | Hidden: context compaction agent | -| `title` | primary | Hidden: session title generator | -| `summary` | primary | Hidden: session summarizer | - ---- - -## Built-in Commands - -| Command | Description | -|---|---| -| `/init` | Initialize a project | -| `/undo` | Undo last change | -| `/redo` | Redo last undone change | -| `/share` | Share conversation | -| `/help` | Show help | - ---- - -End of skill. diff --git a/skills/zeus-core/codemap.md b/skills/zeus-core/codemap.md deleted file mode 100644 index f5411d6..0000000 --- a/skills/zeus-core/codemap.md +++ /dev/null @@ -1,19 +0,0 @@ -# skills/zeus-core/ - - - -## Responsibility - - - -## Design - - - -## Flow - - - -## Integration - - diff --git a/skills/zeus-diagnostics/SKILL.md b/skills/zeus-diagnostics/SKILL.md new file mode 100644 index 0000000..11bbd88 --- /dev/null +++ b/skills/zeus-diagnostics/SKILL.md @@ -0,0 +1,49 @@ +--- +name: zeus-diagnostics +description: Diagnose OpenCode config, agent, skill, command, and plugin discovery problems. Use when something is not loading, the winning source is unclear, or the user asks what OpenCode is actually using. +--- + +# OpenCode diagnostics + +Use evidence, not guesses. Prefer runtime inspection and current schema/docs +over remembered configuration snippets. + +## Workflow + +1. Identify the OpenCode version and active workspace. +2. Inspect relevant global/project/explicit config sources. +3. Inventory the relevant agents, skills, commands or plugins. +4. Find duplicate IDs and higher-precedence definitions. +5. Check permissions and current-format compatibility. +6. Explain the winning source and smallest useful fix. +7. Validate after any change. + +Do not assume contributor-specific paths and never print credential values just +to prove that a source exists. + +## Skill precedence + +For duplicate skill IDs, precedence rises through: + +1. built-in skills; +2. compatible `.claude/skills` sources; +3. compatible `.agents/skills` sources; +4. global OpenCode skills; +5. project `.opencode/skills` from project root toward the working directory; +6. explicit configured skill sources in configured order. + +Later sources win for the same path-derived skill ID. + +## Common checks + +| Symptom | Check | +|---|---| +| Skill missing | ID, description/autoinvoke, permission, discovery root | +| Wrong skill loads | duplicate ID and source precedence | +| Agent missing | scope, file ID, mode/disabled state | +| Command differs | project override, agent/model/subagent fields | +| Plugin inactive | package/local discovery and plugin API version | +| Config ignored | scope, precedence, schema validity, runtime reload | +| Permission prompt | ordered global + agent permission rules | + +For exact syntax, use the current OpenCode schema and V2 docs. diff --git a/skills/zeus-docker/SKILL.md b/skills/zeus-docker/SKILL.md deleted file mode 100644 index cf8777d..0000000 --- a/skills/zeus-docker/SKILL.md +++ /dev/null @@ -1,455 +0,0 @@ ---- -name: zeus-docker -description: Expert Docker and containerization reference. Covers images, containers, Dockerfiles, Docker Compose, networking, volumes, security, and production patterns. ---- - ---- - -## Core Concepts - -### Image vs Container - -| Concept | Analogy | Properties | -|---|---|---| -| **Image** | Recipe/Blueprint | Read-only template, layered, immutable | -| **Container** | Running instance | Runnable process, isolated, ephemeral | - -**Key insight**: Multiple containers can run from the same image. - -### Docker Architecture - -- **Client**: CLI (`docker run`, `docker build`, etc.) -- **Daemon**: Background service that manages containers -- **Registry**: Storage for images (Docker Hub is default) -- **Layers**: Images are built layer-by-layer for efficiency - ---- - -## Essential Commands - -### Container Lifecycle - -```bash -# Run containers -docker run hello-world # Basic run -docker run -d nginx # Detached (background) -docker run -p 8080:80 nginx # Port mapping (host:container) -docker run -it ubuntu bash # Interactive terminal -docker run --name myapp nginx # Named container -docker run -e VAR=value nginx # Environment variable -docker run -v /host/path:/container/path nginx # Volume mount - -# Manage containers -docker ps # List running containers -docker ps -a # List ALL containers -docker stop # Stop gracefully -docker kill # Force stop -docker rm # Remove container -docker restart # Stop then start - -# Interact with running containers -docker exec -it bash # Shell into container -docker logs # View logs -docker logs -f # Follow logs -docker inspect # Detailed info -docker stats # Resource usage -``` - -### Image Management - -```bash -# Image operations -docker images # List local images -docker pull nginx:latest # Download from registry -docker build -t myapp:1.0 . # Build from Dockerfile -docker tag myapp:1.0 user/myapp:latest # Tag for push -docker push user/myapp:latest # Upload to registry -docker rmi # Remove image -docker image prune # Clean unused images - -# Inspect images -docker history myapp:1.0 # Show layers -docker inspect myapp:1.0 # Full metadata -``` - ---- - -## Dockerfile Deep Dive - -### Key Instructions - -| Instruction | Purpose | Example | -|---|---|---| -| `FROM` | Base image | `FROM python:3.12-slim` | -| `RUN` | Execute during build | `RUN pip install -r reqs.txt` | -| `COPY` | Copy files from host | `COPY ./src /app/src` | -| `WORKDIR` | Set working directory | `WORKDIR /app` | -| `ENV` | Environment variable | `ENV NODE_ENV=production` | -| `EXPOSE` | Document ports | `EXPOSE 8080` | -| `CMD` | Default command | `CMD ["python", "app.py"]` | -| `ENTRYPOINT` | Fixed executable | `ENTRYPOINT ["python"]` | -| `ARG` | Build-time variable | `ARG VERSION` | -| `USER` | Set user/group | `USER node` | - -### Example: Node.js App - -```dockerfile -# syntax=docker/dockerfile:1 -FROM node:20-alpine AS builder - -WORKDIR /app -COPY package*.json ./ -RUN npm ci --only=production - -COPY . . -RUN npm run build - -# Production stage -FROM node:20-alpine -WORKDIR /app -COPY --from=builder /app/dist ./dist -COPY --from=builder /app/node_modules ./node_modules - -USER node -EXPOSE 3000 -CMD ["node", "dist/index.js"] -``` - -### Multi-Stage Builds - -```dockerfile -# Build stage -FROM golang:1.21 AS builder -WORKDIR /src -COPY . . -RUN CGO_ENABLED=0 GOOS=linux go build -o app - -# Runtime stage -FROM alpine:latest -COPY --from=builder /src/app /app/ -CMD ["/app/app"] -``` - -### Best Practices - -1. **Use slim/alpine images** β€” Smaller attack surface -2. **Order layers wisely** β€” Put rarely-changing first (caching) -3. **Use `.dockerignore`** β€” Exclude `node_modules`, `.git`, etc. -4. **Don't run as root** β€” Use `USER` directive -5. **Multi-stage builds** β€” Separate build from runtime -6. **Specific tags** β€” Avoid `:latest` in production - ---- - -## Docker Compose - -### Basic Structure - -```yaml -version: '3.8' - -services: - web: - build: . - ports: - - "8080:8000" - environment: - - DB_HOST=db - - REDIS_URL=redis://cache:6379 - volumes: - - ./src:/app/src - depends_on: - - db - - cache - restart: unless-stopped - - db: - image: postgres:15-alpine - environment: - POSTGRES_PASSWORD: ${DB_PASSWORD} - volumes: - - postgres_data:/var/lib/postgresql/data - - cache: - image: redis:7-alpine - -volumes: - postgres_data: -``` - -### Key Compose Commands - -```bash -docker compose up -d # Start all services (detached) -docker compose down # Stop and remove -docker compose down -v # Also remove volumes -docker compose up --build # Rebuild before start -docker compose ps # Show status -docker compose logs -f web # Follow service logs -docker compose exec web bash # Shell into service -docker compose restart web # Restart specific service -docker compose pull # Pull latest images -docker compose top # Show processes -``` - -### Advanced Patterns - -**Health checks:** -```yaml -services: - db: - image: postgres:15 - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 10s - timeout: 5s - retries: 5 -``` - -**Scaling:** -```bash -docker compose up -d --scale worker=3 -``` - -**Multiple compose files:** -```bash -docker compose -f docker-compose.yml -f docker-compose.prod.yml up -``` - ---- - -## Networking - -### Network Types - -| Driver | Use Case | -|---|---| -| `bridge` | Default, single-host containers | -| `host` | Remove network isolation | -| `overlay` | Multi-host (Docker Swarm) | -| `none` | Disable networking | - -### Service Communication - -Containers communicate via service names: -```yaml -services: - web: - links: - - db - # web can reach db at hostname "db" -``` - -Or just rely on default DNS: -```yaml -services: - web: - environment: - - DATABASE_URL=postgres://db:5432/myapp - db: - # No explicit links needed - DNS auto-discovery -``` - ---- - -## Volumes & Storage - -### Volume Types - -```bash -# Named volume (persistent) -docker run -v mydata:/var/lib/data postgres - -# Bind mount (host path) -docker run -v /host/data:/container/data nginx - -# tmpfs (memory-only) -docker run --tmpfs /run:rw,noexec,nosuid,size=64m nginx -``` - -### In Compose - -```yaml -services: - db: - image: postgres:15 - volumes: - - db_data:/var/lib/postgresql/data - - ./backups:/backups - -volumes: - db_data: -``` - ---- - -## Security Best Practices - -```dockerfile -# Use specific, minimal base images -FROM python:3.12-slim-bookworm - -# Create non-root user -RUN groupadd -r appgroup && useradd -r -g appgroup appuser -USER appuser - -# Copy files as non-root -COPY --chown=appuser:appgroup src ./src - -# No secrets in ENV (use runtime secrets) -# ENV DB_PASSWORD=secret # BAD -# Use: docker run -e DB_PASSWORD=$SECRET -``` - -```bash -# Security scanning -docker scout cves myapp:1.0 -docker scout recommendations myapp:1.0 -``` - ---- - -## Troubleshooting - -```bash -# Debugging -docker logs # Application logs -docker inspect # Full details -docker diff # Files changed -docker port # Port mappings - -# Resource issues -docker stats # Live resource usage -docker system df # Disk usage -docker system prune # Clean up - -# Networking -docker network ls -docker network inspect bridge -docker exec cat /etc/hosts -``` - ---- - -## Quick Reference Tables - -### Common Image Tags - -| Tag | Meaning | -|---|---| -| `alpine` | Minimal (~5MB) | -| `slim` | Minimal without docs | -| `-bookworm` | Debian 12 (stable) | -| `-buster` | Debian 11 (oldstable) | -| `:3.12` | Specific version | -| `:latest` | Default version (avoid in production) | - -### Port Mapping Format - -``` --p HOST:CONTAINER --p 8080:80 # Host 8080 β†’ Container 80 --p 127.0.0.1:80:80 # Bind to localhost only --p 8080-8085:80 # Range mapping -``` - -### Restart Policies - -| Policy | Behavior | -|---|---| -| `no` | Never restart | -| `always` | Always restart | -| `unless-stopped` | Restart unless manually stopped | -| `on-failure` | Restart on non-zero exit | - ---- - -## Common Patterns - -### Python + PostgreSQL - -```dockerfile -# Dockerfile -FROM python:3.12-slim -WORKDIR /app -COPY requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt -COPY . . -CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app.wsgi"] -``` - -```yaml -# docker-compose.yml -services: - web: - build: . - ports: - - "8000:8000" - environment: - DATABASE_URL: postgres://user:pass@db:5432/myapp - depends_on: - db: - condition: service_healthy - - db: - image: postgres:15-alpine - environment: - POSTGRES_USER: user - POSTGRES_PASSWORD: pass - POSTGRES_DB: myapp - volumes: - - pgdata:/var/lib/postgresql/data - healthcheck: - test: ["CMD-SHELL", "pg_isready -U user"] - interval: 5s - timeout: 5s - retries: 5 - -volumes: - pgdata: -``` - -### Node.js + Redis - -```yaml -services: - api: - build: . - ports: - - "3000:3000" - environment: - REDIS_URL: redis://cache:6379 - volumes: - - .:/app - - /app/node_modules - depends_on: - - cache - - cache: - image: redis:7-alpine -``` - ---- - -## When to Use What - -| Scenario | Solution | -|---|---| -| Single container | `docker run` | -| Multi-container local dev | Docker Compose | -| Multi-host production | Kubernetes / Docker Swarm | -| Simple CI/CD | Docker in GitHub Actions | -| Complex orchestration | Compose + Swarm/K8s | - ---- - -## Official Resources - -- Docs: https://docs.docker.com/ -- Best practices: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ -- Compose reference: https://docs.docker.com/compose/compose-file/ -- Docker Hub: https://hub.docker.com/ - ---- - -End of skill. diff --git a/skills/zeus-docker/codemap.md b/skills/zeus-docker/codemap.md deleted file mode 100644 index 2762bf4..0000000 --- a/skills/zeus-docker/codemap.md +++ /dev/null @@ -1,19 +0,0 @@ -# skills/zeus-docker/ - - - -## Responsibility - - - -## Design - - - -## Flow - - - -## Integration - - diff --git a/skills/zeus-llm/SKILL.md b/skills/zeus-llm/SKILL.md deleted file mode 100644 index 20b77e2..0000000 --- a/skills/zeus-llm/SKILL.md +++ /dev/null @@ -1,329 +0,0 @@ ---- -name: zeus-llm -description: Reference and workflows for LLaMA tooling: llama.cpp HTTP server, llama-swap, and Ollama installation and configuration. ---- - ---- - -## LLaMA.cpp HTTP Server - -### Install llama.cpp - -```bash -# Clone and build -git clone https://github.com/ggml-org/llama.cpp.git -cd llama.cpp -mkdir build && cd build -cmake .. -cmake --build . --config Release - -# Or use pre-built binaries -# Download from: https://github.com/ggml-org/llama.cpp/releases -``` - -### Start HTTP Server - -```bash -# Basic server -./llama-server -m model.gguf -c 4096 --host 0.0.0.0 --port 8080 - -# With GPU support (CUDA) -./llama-server -m model.gguf -c 4096 --ngl 99 --host 0.0.0.0 --port 8080 - -# With more context -./llama-server -m model.gguf -c 8192 -fa --host 0.0.0.0 --port 8080 -``` - -### Common Server Flags - -| Flag | Description | Example | -|---|---|---| -| `-m` | Model path | `-m models/llama-7b.gguf` | -| `-c` | Context size | `-c 4096` | -| `--host` | Listen address | `--host 0.0.0.0` | -| `--port` | Listen port | `--port 8080` | -| `--ngl` | GPU layers | `--ngl 99` | -| `-fa` | Flash attention | `-fa` | -| `-t` | Threads | `-t 8` | -| `-b` | Batch size | `-b 512` | -| `--parallel` | Parallel requests | `--parallel 4` | - -### API Endpoints - -```bash -# Chat completions (OpenAI-compatible) -curl http://localhost:8080/v1/chat/completions \ - -H "Content-Type: application/json" \ - -d '{ - "model": "model-name", - "messages": [{"role": "user", "content": "Hello"}] - }' - -# Completions -curl http://localhost:8080/v1/completions \ - -H "Content-Type: application/json" \ - -d '{ - "model": "model-name", - "prompt": "The capital of France is" - }' - -# Embeddings -curl http://localhost:8080/v1/embeddings \ - -H "Content-Type: application/json" \ - -d '{ - "model": "model-name", - "input": "The quick brown fox" - }' - -# List models -curl http://localhost:8080/v1/models -``` - ---- - -## llama-swap - -### Purpose - -llama-swap is a proxy server that routes LLM requests to multiple backend servers based on load, cost, or custom rules. - -### Install - -```bash -npm install -g llama-swap -# or -pip install llama-swap -``` - -### Configuration File - -```yaml -# llama-swap.yaml -listen: 0.0.0.0:5000 - -backends: - - name: local-llama - url: http://localhost:8080/v1 - priority: 1 - models: - - llama-7b - - llama-13b - max_tokens: 4096 - - - name: openai-backup - url: http://localhost:11434/v1 - priority: 2 - models: - - gpt-3.5-turbo - -routing: - strategy: priority # priority | round-robin | least-load - fallback: true - -cache: - enabled: true - ttl: 3600 -``` - -### OpenCode Provider Config - -```json -{ - "provider": { - "llama-swap": { - "npm": "@ai-sdk/openai-compatible", - "name": "llama-swap (local)", - "options": { - "baseURL": "http://localhost:5000/v1", - "apiKey": "not-required" - }, - "models": { - "llama-7b": { - "name": "LLaMA 7B", - "family": "llama", - "attachment": true, - "tool_call": true, - "limit": { - "context": 4096, - "output": 2048 - } - } - } - } - } -} -``` - ---- - -## Ollama - -### Install - -```bash -# macOS/Linux -curl -fsSL https://ollama.ai/install.sh | sh - -# Docker -docker run -d -v ollama:/root/.ollama -p 11434:11434 ollama/ollama -``` - -### Common Commands - -```bash -# Pull a model -ollama pull llama3.2:1b - -# List models -ollama list - -# Run interactively -ollama run llama3.2:1b - -# Create custom model -ollama create my-model -f Modelfile -``` - -### Ollama API - -```bash -# Chat -curl http://localhost:11434/api/chat -d '{ - "model": "llama3.2:1b", - "messages": [{"role": "user", "content": "Hello"}] -}' - -# Generate -curl http://localhost:11434/api/generate -d '{ - "model": "llama3.2:1b", - "prompt": "The capital of France is" -}' - -# Embeddings -curl http://localhost:11434/api/embeddings -d '{ - "model": "llama3.2:1b", - "prompt": "The quick brown fox" -}' -``` - -### OpenAI-Compatible API - -```bash -# Use Ollama with OpenAI-compatible endpoint -curl http://localhost:11434/v1/chat/completions \ - -H "Content-Type: application/json" \ - -d '{ - "model": "llama3.2:1b", - "messages": [{"role": "user", "content": "Hello"}] - }' -``` - ---- - -## OpenCode Integration Examples - -### llama.cpp with OpenCode - -```json -{ - "provider": { - "llama-cpp": { - "npm": "@ai-sdk/openai-compatible", - "name": "llama.cpp server", - "options": { - "baseURL": "http://localhost:8080/v1", - "apiKey": "not-required" - }, - "models": { - "qwen-7b": { - "name": "Qwen 7B", - "family": "qwen", - "attachment": true, - "tool_call": true, - "limit": { - "context": 8192, - "output": 2048 - } - } - } - } - } -} -``` - -### Ollama with OpenCode - -```json -{ - "provider": { - "ollama": { - "npm": "@ai-sdk/openai-compatible", - "name": "Ollama", - "options": { - "baseURL": "http://localhost:11434/v1", - "apiKey": "not-required" - }, - "models": { - "llama3.2:1b": { - "name": "LLaMA 3.2 1B", - "family": "llama", - "attachment": true, - "tool_call": false, - "limit": { - "context": 8192, - "output": 2048 - } - } - } - } - } -} -``` - ---- - -## Verification Commands - -```bash -# Check if llama.cpp server is running -curl http://localhost:8080/v1/models - -# Check if Ollama is running -curl http://localhost:11434/api/tags - -# Check llama-swap status -curl http://localhost:5000/status - -# Test a completion -curl http://localhost:8080/v1/completions \ - -H "Content-Type: application/json" \ - -d '{"model": "test", "prompt": "Hello"}' -``` - ---- - -## Common Pitfalls - -| Issue | Solution | -|---|---| -| Model not found | Check path with `-m` flag; use absolute path | -| Out of memory | Reduce context size `-c` or GPU layers `--ngl` | -| Slow inference | Increase threads `-t`, enable flash attention `-fa` | -| Connection refused | Ensure server is running; check port binding | -| Token limit exceeded | Reduce context size or use larger model | -| CUDA not available | Install CUDA toolkit; ensure GPU drivers | - ---- - -## Relevant URLs - -| Resource | URL | -|---|---| -| llama.cpp releases | https://github.com/ggml-org/llama.cpp/releases | -| llama.cpp server README | https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md | -| llama-swap docs | https://github.com/mostlygeek/llama-swap/blob/main/docs/configuration.md | -| Ollama docs | https://github.com/ollama/ollama/blob/main/docs/api.md | - ---- - -End of skill. diff --git a/skills/zeus-llm/codemap.md b/skills/zeus-llm/codemap.md deleted file mode 100644 index b5eb327..0000000 --- a/skills/zeus-llm/codemap.md +++ /dev/null @@ -1,19 +0,0 @@ -# skills/zeus-llm/ - - - -## Responsibility - - - -## Design - - - -## Flow - - - -## Integration - - diff --git a/skills/zeus-migration/SKILL.md b/skills/zeus-migration/SKILL.md new file mode 100644 index 0000000..8dd1107 --- /dev/null +++ b/skills/zeus-migration/SKILL.md @@ -0,0 +1,43 @@ +--- +name: zeus-migration +description: Plan and verify OpenCode configuration migrations, especially V1-to-V2 changes. Use when legacy fields, old plugin APIs, tui.json, or deprecated agent/command syntax are present. +--- + +# OpenCode migration + +Migrate behavior, not formatting for its own sake. + +## Workflow + +1. Inspect the complete relevant config/asset. +2. Identify only legacy, unsupported or conflicting fields. +3. Confirm current representation from the migration guide/schema. +4. Produce a plan before mutation. +5. Preserve unrelated settings and IDs. +6. Back up user-owned config before applying changes. +7. Apply the smallest coherent migration. +8. Validate and explain remaining compatibility behavior. + +## Common mappings + +| V1 | Native V2 | +|---|---| +| `permission` | ordered `permissions` | +| `bash` permission action | `shell` | +| `task` permission action | `subagent` | +| `write` / `patch` permission actions | `edit` | +| agent `disable` | `disabled` | +| command map `command` | `commands` | +| command `subtask` | `subagent` | +| separate model variant | `provider/model#variant` | +| skill paths/URLs maps | ordered `skills` array | +| plugin config `plugin` | `plugins` | +| V1 terminal `tui.json(c)` | global V2 `cli.json` | + +V1 plugin implementations require a real V2 plugin port; renaming config is not +sufficient. + +Prefer plural V2 asset directories for new files. Keep existing IDs stable when +moving assets. + +Reference: `https://opencode.ai/v2/docs/migrate-v1`. diff --git a/skills/zeus-oac/SKILL.md b/skills/zeus-oac/SKILL.md deleted file mode 100644 index e9b9c02..0000000 --- a/skills/zeus-oac/SKILL.md +++ /dev/null @@ -1,291 +0,0 @@ ---- -name: zeus-oac -description: Expert reference for OpenAgentsControl (OAC) β€” a plan-first AI development framework with approval gates, context management, and pattern control for OpenCode. Covers setup, agents, commands, and workflows. ---- - -# zeus-oac (Skill) - -Purpose: Expert reference for OpenAgentsControl (OAC) β€” a plan-first AI development framework with approval gates, context management, and pattern control for OpenCode. Covers setup, agents, commands, and workflows. - -**πŸ”— OpenAgentsControl Repository**: https://github.com/darrenhinde/OpenAgentsControl - ---- - -## What is OpenAgentsControl? - -OAC is an AI agent framework for **plan-first development** with human approval gates. It teaches agents your coding patterns so they generate matching code from the start. - -**Key features:** -- **Pattern Control** β€” Define your patterns once, AI uses them forever -- **Approval Gates** β€” Review and approve before execution -- **Context System** β€” Learn YOUR coding standards (MVI principle) -- **Team-Ready** β€” Shared context files committed to git -- **Token Efficient** β€” 80% reduction via Minimal Viable Information - -**Why use it?** -- Code ships without refactoring -- Team uses consistent patterns -- Human-guided quality control -- No vendor lock-in (any model) - ---- - -## Documentation Links - -| Resource | URL | -|---|---| -| Main README | https://github.com/darrenhinde/OpenAgentsControl | -| Quick Start | https://github.com/darrenhinde/OpenAgentsControl#-quick-start | -| Context System | https://github.com/darrenhinde/OpenAgentsControl#-the-context-system-your-secret-weapon | -| Context Guide | https://github.com/darrenhinde/OpenAgentsControl/blob/main/CONTEXT_SYSTEM_GUIDE.md | -| Compatibility | https://github.com/darrenhinde/OpenAgentsControl/blob/main/COMPATIBILITY.md | -| Changelog | https://github.com/darrenhinde/OpenAgentsControl/blob/main/CHANGELOG.md | - ---- - -## Installation - -### Option 1: Script (Recommended) - -```bash -curl -fsSL https://raw.githubusercontent.com/darrenhinde/OpenAgentsControl/main/install.sh | bash -s developer -``` - -### Option 2: Manual - -```bash -# Clone the repo -git clone https://github.com/darrenhinde/OpenAgentsControl.git - -# Install globally -cd OpenAgentsControl -bash install.sh -``` - -### Update - -```bash -curl -fsSL https://raw.githubusercontent.com/darrenhinde/OpenAgentsControl/main/update.sh | bash -``` - ---- - -## Main Agents - -| Agent | Purpose | Use Case | -|---|---|---| -| `@OpenAgent` | General tasks, learning | Start here, simple features, questions | -| `@OpenCoder` | Production development | Complex features, multi-file refactoring | - -### Subagents (Auto-delegated) - -| Agent | Purpose | -|---|---| -| `ContextScout` | Smart pattern discovery | -| `TaskManager` | Breaks features into atomic subtasks | -| `CoderAgent` | Focused code implementations | -| `TestEngineer` | Test authoring and TDD | -| `CodeReviewer` | Code review and security | -| `BuildAgent` | Type checking and validation | -| `ExternalScout` | Fetches live docs for external libraries | - ---- - -## Essential Commands - -| Command | Purpose | -|---|---| -| `/add-context` | Interactive wizard to add your patterns | -| `/commit` | Smart git commits (conventional format) | -| `/test` | Testing workflows | -| `/optimize` | Code optimization | -| `/context` | Context management | - ---- - -## The Workflow - -``` -1. Add Your Context (one time) - ↓ -2. ContextScout discovers relevant patterns - ↓ -3. Agent loads YOUR standards - ↓ -4. Agent proposes plan (you approve) - ↓ -5. You approve - ↓ -6. Agent implements (matches your patterns) - ↓ -7. Ships without refactoring βœ… -``` - ---- - -## The Context System (MVI Principle) - -### How It Works - -``` -Your Request - ↓ -ContextScout discovers relevant patterns - ↓ -Agent loads YOUR standards - ↓ -Code generated using YOUR patterns - ↓ -Ships without refactoring βœ… -``` - -### Add Your Patterns - -```bash -/add-context -``` - -Answer 6 questions: -1. What's your tech stack? -2. Show an API endpoint example -3. Show a component example -4. What naming conventions? -5. Any code standards? -6. Any security requirements? - -### MVI (Minimal Viable Information) - -Files designed for quick loading: -- **Concepts:** <100 lines -- **Guides:** <150 lines -- **Examples:** <80 lines - -Result: 80% token reduction vs loading entire codebase. - ---- - -## Approval Gates - -Agents ALWAYS request approval before: -- Writing/editing files -- Running bash commands -- Delegating to subagents -- Making any changes - -**You stay in control.** Review plans before execution. - ---- - -## For Teams - -### Store Patterns in Git - -```bash -# Team lead adds patterns once -/add-context - -# Commit to repo -git add .opencode/context/ -git commit -m "Add team coding standards" -git push - -# All team members use same patterns automatically -``` - -### Context Resolution - -``` -1. Check local: .opencode/context/core/navigation.md - ↓ Found? β†’ Use local for everything - ↓ Not found? -2. Check global: ~/.config/opencode/context/core/navigation.md - ↓ Found? β†’ Use global for core/ only - ↓ Not found? β†’ Proceed without core context -``` - -**Key rules:** -- Local always wins -- Global fallback is only for `core/` -- Project intelligence is always local - ---- - -## Configuration - -### Edit Agent Behavior - -Agents are markdown files you can edit directly: - -```bash -# Local project -nano .opencode/agent/core/opencoder.md - -# Global -nano ~/.config/opencode/agent/core/opencoder.md -``` - -### Change Model Per Agent - -Edit the agent file and change the model in frontmatter: - -```yaml ---- -description: "Development specialist" -model: anthropic/claude-sonnet-4-5 ---- -``` - ---- - -## When to Use OAC - -### βœ… Use OAC if you: -- Build production code that ships without heavy rework -- Work in a team with established coding standards -- Want control over agent behavior -- Care about token efficiency and cost savings -- Need approval gates for quality assurance - -### ⚠️ Skip OAC if you: -- Want fully autonomous execution without approval gates -- Prefer "just do it" mode -- Don't have established coding patterns yet -- Need multi-agent parallelization (use oh-my-opencode-slim instead) - ---- - -## Comparison - -| Feature | OAC | Cursor/Copilot | Aider | Oh My OpenCode | -|---------|-----|----------------|-------|----------------| -| Learn Your Patterns | βœ… Built-in | ❌ | ❌ | ⚠️ Manual | -| Approval Gates | βœ… Always | ⚠️ Optional | ❌ | ❌ | -| Token Efficiency | βœ… MVI (80%) | ❌ Full | ❌ Full | ❌ High | -| Team Standards | βœ… Shared | ❌ | ❌ | ⚠️ Manual | -| Edit Agent Behavior | βœ… Markdown | ❌ | ⚠️ Limited | βœ… Config | -| Model Agnostic | βœ… Any | ⚠️ Limited | ⚠️ OAI/Claude | βœ… Multiple | - ---- - -## Troubleshooting - -| Problem | Solution | -|---|---| -| Commands not found | Restart OpenCode after install | -| Context not loading | Run `/add-context` to set up patterns | -| Token usage high | Ensure MVI compliance (<200 lines per file) | -| Approval prompts annoying | Use `@OpenAgent` instead of `@OpenCoder` | - ---- - -## Related - -| Resource | URL | -|---|---| -| GitHub | https://github.com/darrenhinde/OpenAgentsControl | -| Plugin | Local: `~/.config/opencode/plugins/OAC/` | -| Community | https://nextsystems.ai | - ---- - -End of skill. diff --git a/skills/zeus-oac/codemap.md b/skills/zeus-oac/codemap.md deleted file mode 100644 index dbf174e..0000000 --- a/skills/zeus-oac/codemap.md +++ /dev/null @@ -1,19 +0,0 @@ -# skills/zeus-oac/ - - - -## Responsibility - - - -## Design - - - -## Flow - - - -## Integration - - diff --git a/skills/zeus-omo/SKILL.md b/skills/zeus-omo/SKILL.md deleted file mode 100644 index 34c7054..0000000 --- a/skills/zeus-omo/SKILL.md +++ /dev/null @@ -1,290 +0,0 @@ ---- -name: zeus-omo -description: Deep reference for oh-my-opencode-slim plugin: installation, configuration, cartography, tmux integration, and provider mappings. ---- - -**πŸ”— oh-my-opencode-slim Repository**: https://github.com/alvinunreal/oh-my-opencode-slim - ---- - -## oh-my-opencode-slim Overview - -oh-my-opencode-slim is an OpenCode plugin that provides enhanced capabilities including: -- Provider configurations and model mappings -- Cartography (codebase understanding and mapping) -- tmux integration for session management -- Quick reference tools - ---- - -## Installation - -```bash -# Via npm -npm install -g oh-my-opencode-slim - -# Or via pip -pip install oh-my-opencode-slim - -# Verify installation -opencode --version -``` - ---- - -## Configuration File - -The main config file is at: `~/.config/opencode/oh-my-opencode-slim.json` - -```json -{ - "providerMappings": { - "default": "llama-swap", - "fast": "ollama", - "power": "openai" - }, - "cartography": { - "enabled": true, - "cacheDir": "~/.cache/oh-my-opencode-slim" - }, - "tmux": { - "enabled": false, - "sessionName": "opencode" - } -} -``` - ---- - -## Provider Configurations - -### llama-swap Provider - -```json -{ - "provider": { - "llama-swap": { - "npm": "@ai-sdk/openai-compatible", - "name": "llama-swap (local)", - "options": { - "baseURL": "http://localhost:5000/v1", - "apiKey": "not-required" - }, - "models": { - "Qwen3.5-27B-Claude-Q4": { - "name": "Qwen3.5-27B Claude Q4", - "family": "qwen", - "attachment": true, - "tool_call": true, - "reasoning": true, - "limit": { - "context": 196608, - "output": 32768 - } - } - } - } - } -} -``` - -### Ollama Provider - -```json -{ - "provider": { - "ollama": { - "npm": "@ai-sdk/openai-compatible", - "name": "Ollama", - "options": { - "baseURL": "http://localhost:11434/v1", - "apiKey": "not-required" - }, - "models": { - "llama3.2:1b": { - "name": "LLaMA 3.2 1B", - "family": "llama", - "attachment": true, - "tool_call": false - } - } - } - } -} -``` - -### OpenAI-Compatible Provider - -```json -{ - "provider": { - "openai-compatible": { - "npm": "@ai-sdk/openai-compatible", - "name": "Custom OpenAI-compatible", - "options": { - "baseURL": "https://api.example.com/v1", - "apiKey": "{env:API_KEY}" - }, - "models": { - "my-model": { - "name": "My Model", - "family": "custom", - "attachment": true, - "tool_call": true - } - } - } - } -} -``` - ---- - -## Cartography - -Cartography provides codebase understanding and hierarchical mapping. - -### Enabling Cartography - -```json -{ - "cartography": { - "enabled": true, - "depth": 3, - "exclude": ["node_modules/**", "dist/**", ".git/**"] - } -} -``` - -### Using Cartography - -```bash -# Generate codemap -opencode cartography - -# View specific directory -opencode cartography src/ - -# Export to file -opencode cartography --output codemap.md -``` - -### Cartography Output Format - -```markdown -# Project Codemap - -## src/ -β”œβ”€β”€ components/ # UI components -β”‚ β”œβ”€β”€ Button.tsx -β”‚ └── Modal.tsx -β”œβ”€β”€ hooks/ # Custom React hooks -β”‚ └── useAuth.ts -└── utils/ # Utility functions - └── format.ts - -## tests/ -β”œβ”€β”€ unit/ -└── integration/ -``` - ---- - -## tmux Integration - -### Enable tmux Integration - -```json -{ - "tmux": { - "enabled": true, - "sessionName": "opencode", - "attachOnCreate": true - } -} -``` - -### tmux Commands - -```bash -# Start new session -tmux new -s opencode - -# Attach to session -tmux attach -t opencode - -# List sessions -tmux ls - -# Detach from session -# Press: Ctrl+b, d -``` - -### Workflow with tmux - -``` -1. Create tmux session: tmux new -s work -2. Run opencode in tmux window 1 -3. Run other tools in window 2+ -4. Detach (Ctrl+b, d) to leave running -5. Reattach later: tmux attach -t work -``` - ---- - -## Quick Reference Commands - -### Provider Switching - -```bash -# Switch active provider -opencode provider set llama-swap - -# List available providers -opencode provider list - -# Show current provider -opencode provider show -``` - -### Model Switching - -```bash -# Switch model -opencode model set qwen-7b - -# List available models -opencode model list - -# Show current model -opencode model show -``` - ---- - -## Troubleshooting - -| Problem | Solution | -|---|---| -| Plugin not loading | Check plugin is in `opencode.json`: `"plugin": ["oh-my-opencode-slim"]` | -| Cartography slow | Exclude large directories in config | -| tmux not working | Ensure tmux is installed: `apt install tmux` | -| Provider not found | Verify baseURL is correct and server is running | -| Model not available | Pull model with provider's CLI (e.g., `ollama pull`) | - ---- - -## Relevant URLs - -| Resource | URL | -|---|---| -| oh-my-opencode-slim main | https://github.com/alvinunreal/oh-my-opencode-slim | -| Cartography docs | https://github.com/alvinunreal/oh-my-opencode-slim/blob/master/docs/cartography.md | -| Installation | https://github.com/alvinunreal/oh-my-opencode-slim/blob/master/docs/installation.md | -| Provider config | https://github.com/alvinunreal/oh-my-opencode-slim/blob/master/docs/provider-configurations.md | -| Quick reference | https://github.com/alvinunreal/oh-my-opencode-slim/blob/master/docs/quick-reference.md | -| tmux integration | https://github.com/alvinunreal/oh-my-opencode-slim/blob/master/docs/tmux-integration.md | - ---- - -End of skill. diff --git a/skills/zeus-omo/codemap.md b/skills/zeus-omo/codemap.md deleted file mode 100644 index 1a2f8b9..0000000 --- a/skills/zeus-omo/codemap.md +++ /dev/null @@ -1,19 +0,0 @@ -# skills/zeus-omo/ - - - -## Responsibility - - - -## Design - - - -## Flow - - - -## Integration - - diff --git a/skills/zeus-omo/opencode.code-workspace b/skills/zeus-omo/opencode.code-workspace deleted file mode 100644 index cd55d24..0000000 --- a/skills/zeus-omo/opencode.code-workspace +++ /dev/null @@ -1,11 +0,0 @@ -{ - "folders": [ - { - "path": "../.." - }, - { - "path": "../../.." - } - ], - "settings": {} -} \ No newline at end of file diff --git a/skills/zeus-self/SKILL.md b/skills/zeus-self/SKILL.md deleted file mode 100644 index db11202..0000000 --- a/skills/zeus-self/SKILL.md +++ /dev/null @@ -1,320 +0,0 @@ ---- -name: zeus-self -description: Runtime introspection and self-diagnostics for OpenZeus - current session state, health checks, and operational awareness. ---- - -# zeus-self (Skill) - -Purpose: Runtime introspection and self-diagnostics for OpenZeus β€” current session state, health checks, and operational awareness. - ---- - -## Session Introspection - -### Current Context Analysis -- **Conversation Length**: Check message count and context size -- **Active Skills**: Track which skills have been loaded this session -- **Tool Usage Patterns**: Most/least used tools in current session -- **Working Directory**: Current location and git repository status -- **Recent Operations**: Summary of major actions taken - -### Context Health -- **Signal-to-Noise Ratio**: Assess conversation quality -- **Compression History**: Track what's been compressed and when -- **Memory Pressure**: Evaluate need for context cleanup -- **Stale Ranges**: Identify conversation sections ready for compression - ---- - -## System Health Diagnostics - -### Core File Integrity -Check essential OpenZeus files: -- `~/.config/opencode/agents/OpenZeus.md` β€” Agent definition -- `~/.config/opencode/opencode.json` β€” Main configuration -- `~/.config/opencode/skills/zeus-*/SKILL.md` β€” Skill bundles -- `~/.config/opencode/commands/` β€” Custom commands - -### Configuration Validation -- **Schema Compliance**: Validate config against expected structure -- **Permission Check**: Verify edit/write/bash/webfetch access -- **Path Accessibility**: Test key directory access -- **Git Status**: Check repository state and cleanliness - -### Capability Testing -- **Tool Access**: Test bash, read, write, glob, grep functionality -- **Network Connectivity**: Check webfetch and URL reachability -- **Skill Loading**: Verify skill system operational -- **Task Delegation**: Test subagent communication - ---- - -## Operational Awareness - -### Performance Metrics -- **Response Latency**: Track tool execution times -- **Success Rates**: Monitor tool failure patterns -- **Resource Usage**: Assess computational overhead -- **Error Frequency**: Identify recurring issues - -### Learning Indicators -- **Knowledge Gaps**: Areas where I lack information -- **Skill Usage Patterns**: Which skills are most/least valuable -- **User Intent Mapping**: How well I detect user needs -- **Delegation Efficiency**: Subagent usage effectiveness - ---- - -## Self-Diagnostic Commands - -### Quick Health Check -```markdown -**System Status**: βœ… Operational / ⚠️ Degraded / ❌ Critical -**Configuration**: Valid / Invalid -**Core Files**: Present / Missing -**Tool Access**: Full / Partial / None -**Git Status**: Clean / Dirty / Unknown -``` - -### Detailed Diagnostics -```markdown -**Session Context**: -- Messages: X total, Y compressed -- Skills loaded: [list] -- Tools used: [frequency table] -- Working dir: /path/to/current - -**File Integrity**: -- Agent definition: βœ… Present (194 lines) -- Main config: βœ… Valid JSON -- Skills: βœ… X skills available -- Commands: βœ… Y commands defined - -**Capabilities**: -- Bash: βœ… Responsive -- File ops: βœ… Read/Write functional -- Network: βœ… Can reach opencode.ai -- Git: βœ… Repository accessible -``` - -### Performance Analysis -```markdown -**Tool Usage This Session**: -| Tool | Uses | Avg Time | Success Rate | -|------|------|----------|--------------| -| bash | X | Yms | Z% | -| read | X | Yms | Z% | - -**Skill Loading Patterns**: -- Most used: zeus-core (X times) -- Least used: zeus-swarm (0 times) -- Load sequence: [chronological list] -``` - ---- - -## Context Management Insights - -### Compression Candidates -Identify conversation ranges that could be compressed: -- **Closed exploration**: Research that reached conclusions -- **Completed tasks**: Finished implementations -- **Failed attempts**: Dead-end troubleshooting -- **Verbose outputs**: Large tool results no longer needed - -### Signal Preservation -Assess what must be kept in active context: -- **Active code**: Files currently being modified -- **Pending decisions**: Unresolved questions -- **Error context**: Recent failures needing attention -- **User intent**: Current task requirements - ---- - -## Self-Improvement Tracking - -### Capability Gaps -- **Missing skills**: Domains I can't handle well -- **Tool limitations**: Operations I struggle with -- **Knowledge holes**: Topics requiring external lookup -- **Workflow inefficiencies**: Repeated manual steps - -### Learning Opportunities -- **New skill candidates**: Based on user request patterns -- **Automation potential**: Manual processes worth scripting -- **Configuration improvements**: Settings optimizations -- **Workflow enhancements**: Better delegation strategies - ---- - -## Runtime State Queries - -### Session Summary -Generate current session overview: -```markdown -**OpenZeus Session Report** -- Duration: X minutes -- Major actions: [list key accomplishments] -- Skills utilized: [loaded skills with usage] -- Files modified: [paths and change types] -- Git operations: [commits, branches, status] -- Context health: [compression needs, signal quality] -``` - -### Health Dashboard -Real-time system status: -```markdown -**OpenZeus Health Dashboard** -🟒 System: Fully operational -🟒 Config: Valid and accessible -🟒 Tools: All responsive -🟒 Network: Connected to docs -🟑 Context: Moderate compression needed -🟒 Git: Clean working directory -``` - -### Diagnostic Report -Comprehensive system analysis: -```markdown -**Full Diagnostic Report** -Generated: [timestamp] - -CONFIGURATION: -- Agent file: βœ… ~/.config/opencode/agents/OpenZeus.md (194 lines) -- Main config: βœ… ~/.config/opencode/opencode.json (valid) -- Skills dir: βœ… 16 skills available -- Commands dir: βœ… X custom commands - -CAPABILITIES: -- File operations: βœ… Read/write/edit functional -- Shell access: βœ… Bash responsive (non-interactive mode) -- Network access: βœ… Can reach opencode.ai -- Git operations: βœ… Repository accessible -- Skill loading: βœ… All skills loadable -- Task delegation: βœ… Subagent communication working - -SESSION STATE: -- Context size: X messages, Y tokens estimated -- Active skills: [list] -- Working directory: [path] -- Git status: [clean/dirty/ahead/behind] -- Recent errors: [none/list] - -RECOMMENDATIONS: -- [Context management suggestions] -- [Performance optimizations] -- [Capability improvements] -``` - ---- - -## Session Management & Handoff - -### Accomplishment Tracking -- **Session Summary**: Major tasks completed this session -- **File Modifications**: Track all files created, edited, or deleted -- **Git Operations**: Commits made, branches worked on, push status -- **Skill Usage**: Which capabilities were exercised -- **Knowledge Gained**: New insights or patterns discovered - -### Incomplete Work Analysis -- **Pending Tasks**: Work started but not finished -- **Follow-up Items**: Actions that need continuation -- **Blocked Dependencies**: What's waiting on external factors -- **Context Preservation**: What state must be maintained -- **Handoff Requirements**: Critical info for next session - -### Session Continuity -- **Context Handoff Notes**: Essential background for resuming work -- **Working Directory State**: Current location and git status -- **Active Configurations**: Settings or environments in use -- **Dependency Status**: What's installed, configured, or broken -- **Next Steps**: Recommended actions for continuation - -### Cleanup Recommendations -- **Git Hygiene**: Uncommitted changes, stashes, branches to clean -- **File Organization**: Temporary files to remove or organize -- **Context Compression**: Conversation ranges ready for cleanup -- **Resource Cleanup**: Processes, connections, or locks to release - ---- - -## Interactive Configuration - -### Trigger Keyword Management -- **Usage Analysis**: Track which keywords actually trigger skills -- **Pattern Recognition**: Identify new trigger patterns from user requests -- **Keyword Optimization**: Add/remove triggers based on effectiveness -- **Context Sensitivity**: Adjust triggers based on domain or project type - -### Skill Loading Optimization -- **Priority Adjustment**: Reorder skills based on usage frequency -- **Combination Patterns**: Learn which skills work well together -- **Load Sequence**: Optimize the order of multi-skill workflows -- **Dependency Mapping**: Track which skills depend on others - -### Behavior Rule Evolution -- **Rule Effectiveness**: Monitor which behavior rules help vs hinder -- **Situational Rules**: Context-specific behavior modifications -- **Performance Rules**: Optimize for speed vs thoroughness based on task -- **Safety Rules**: Enhance security and error prevention patterns - -### URL Mapping Updates -- **Link Validation**: Check if documented URLs are still valid -- **New Documentation**: Add mappings for newly discovered resources -- **Usage Tracking**: Monitor which documentation gets accessed most -- **Regional/Version**: Handle different doc versions or mirrors - -### Capability Self-Configuration -- **Tool Usage Optimization**: Adjust tool selection based on success rates -- **Delegation Rules**: Refine when to use subagents vs direct action -- **Context Limits**: Auto-adjust context management thresholds -- **Performance Tuning**: Optimize response patterns for different scenarios - ---- - -## Configuration Commands - -### Update Trigger Keywords -```markdown -**Current Triggers for zeus-self**: [list current triggers] -**Suggested Additions**: [based on usage analysis] -**Suggested Removals**: [unused or ineffective triggers] -**Update Command**: Modify OpenZeus.md skill loading guide -``` - -### Optimize Skill Loading -```markdown -**Current Priority**: zeus-core β†’ zeus-agents β†’ zeus-commands -**Usage Analysis**: [frequency and success rates] -**Recommended Changes**: [based on actual patterns] -**New Priority**: [optimized loading order] -``` - -### Behavior Rule Tuning -```markdown -**Current Rules**: [list from OpenZeus.md] -**Rule Effectiveness**: [which help, which hinder] -**Situational Needs**: [context-specific modifications] -**Proposed Updates**: [rule modifications or additions] -``` - ---- - -## Usage Instructions - -Load this skill when you need: -- **Self-awareness**: "How am I performing?" -- **Health check**: "Are my systems working properly?" -- **Session status**: "What have I accomplished?" -- **Diagnostics**: "Why am I having issues?" -- **Context management**: "Should I compress anything?" -- **Session handoff**: "Prepare notes for next session" -- **Configuration**: "Update your trigger keywords" -- **Optimization**: "Analyze and improve your patterns" - -This skill transforms from static documentation into dynamic runtime intelligence and self-optimization. - ---- - -End of skill. diff --git a/skills/zeus-self/codemap.md b/skills/zeus-self/codemap.md deleted file mode 100644 index 5bdc449..0000000 --- a/skills/zeus-self/codemap.md +++ /dev/null @@ -1,19 +0,0 @@ -# skills/zeus-self/ - - - -## Responsibility - - - -## Design - - - -## Flow - - - -## Integration - - diff --git a/skills/zeus-skills/SKILL.md b/skills/zeus-skills/SKILL.md index 40921ee..6d97400 100644 --- a/skills/zeus-skills/SKILL.md +++ b/skills/zeus-skills/SKILL.md @@ -1,186 +1,40 @@ --- name: zeus-skills -description: Guide for creating new skills for OpenCode. Use this when the user wants to create a custom skill. +description: Create and review portable OpenCode skills. Use for SKILL.md authoring, trigger descriptions, discovery/precedence, supporting files, collisions, or skill portability. --- -# zeus-skills (Skill) +# OpenCode skill authoring -Canonical guide for creating and editing OpenCode skills. +OpenCode already discovers and loads skills. OpenZeus helps design skills that +are focused, discoverable, portable and collision-safe. ---- - -## What is a Skill? - -A skill is a reusable markdown knowledge bundle loaded by agents with the `skill` tool. - -Use a skill when you need: -- Reusable domain knowledge -- Copy-pasteable templates or commands -- Focused troubleshooting/reference material -- A capability that should be shared across sessions or agents - ---- - -## Discovery Paths - -OpenCode discovers skills from these locations: - -| Scope | Path | -|---|---| -| Project OpenCode | `.opencode/skills//SKILL.md` | -| Global OpenCode | `~/.config/opencode/skills//SKILL.md` | -| Project Claude-compatible | `.claude/skills//SKILL.md` | -| Global Claude-compatible | `~/.claude/skills//SKILL.md` | -| Project agents-compatible | `.agents/skills//SKILL.md` | -| Global agents-compatible | `~/.agents/skills//SKILL.md` | - -Prefer `.opencode/skills/` for project-specific skills and `~/.config/opencode/skills/` for user-wide skills. - ---- - -## Skill Directory Structure +## Preferred shape ```text -skills/ -└── my-skill/ - β”œβ”€β”€ SKILL.md # Required - β”œβ”€β”€ README.md # Optional human-facing notes - └── templates/ # Optional supporting files +.opencode/skills/release/ +β”œβ”€β”€ SKILL.md +β”œβ”€β”€ references/ +└── scripts/ ``` +```markdown --- - -## SKILL.md Frontmatter - -`SKILL.md` requires YAML frontmatter with `name` and `description`. - -```yaml +name: Release +description: Prepare repository releases, changelogs, version bumps and tags. Use when the user asks to cut or validate a release. --- -name: my-skill -description: Brief description of what this skill provides. ---- -``` -| Field | Required | Notes | -|---|---:|---| -| `name` | Yes | Skill identifier; usually matches directory name | -| `description` | Yes | One-line purpose and trigger guidance | -| `license` | No | Recognized optional metadata | -| `compatibility` | No | Recognized optional compatibility notes | -| `metadata` | No | Recognized optional structured metadata | - ---- - -## Minimal Skill Template - -````markdown ---- -name: my-skill -description: Short purpose and when to use this skill. ---- - -# my-skill (Skill) - -Purpose: Short, concrete purpose statement. - ---- - -## Quick Reference - -| Task | Example | -|---|---| -| Do the common thing | `example command` | - ---- - -## Workflow - -```bash -# Copy-pasteable commands only -example command --safe-flag +# Release workflow +... ``` ---- +The path determines the skill ID. Keep portable IDs unique, lowercase, +kebab-case and aligned with the directory name. -## Troubleshooting +A clear description matters because it is what OpenCode advertises for model +discovery. -| Problem | Fix | -|---|---| -| Skill not loading | Check `//SKILL.md` and frontmatter | - ---- - -End of skill. -```` - ---- - -## Creation Workflow - -```text -1. Choose a focused name and one-line description. -2. Create //SKILL.md. -3. Add required frontmatter: name + description. -4. Write concise sections with tables and copy-pasteable examples. -5. Add optional supporting files only when they reduce clutter. -6. Load/test with skill("") where available. -``` - -Example: - -```bash -mkdir -p ~/.config/opencode/skills/git-master -cat > ~/.config/opencode/skills/git-master/SKILL.md <<'EOF' ---- -name: git-master -description: Expert git workflows, branching, rebasing, and troubleshooting. ---- - -# git-master (Skill) - -## Quick Reference - -| Task | Command | -|---|---| -| Create branch | `git switch -c feature-name` | -| Show changes | `git diff --stat` | -| Undo last commit | `git reset --soft HEAD~1` | - ---- - -End of skill. -EOF -``` - ---- - -## Best Practices - -- **One domain per skill**: keep scope narrow. -- **Concise sections**: prefer tables and examples over prose. -- **Safe examples**: avoid destructive commands unless clearly guarded. -- **Stable frontmatter**: preserve `name` and `description` when editing. -- **Portable content**: no secrets, local-only credentials, or brittle paths. -- **Clear ending**: use `---` and `End of skill.` for consistency. - ---- - -## Troubleshooting - -| Problem | Fix | -|---|---| -| Skill not found | Verify discovery path and directory name | -| Frontmatter ignored | Ensure YAML starts at line 1 and closes with `---` | -| Skill too noisy | Move long examples to supporting files or shorten tables | -| Wrong scope | Use project path for project-specific knowledge; global path for reusable knowledge | - ---- - -## Related Documentation - -- OpenCode Skills: https://opencode.ai/docs/skills/ -- OpenCode Agents: https://opencode.ai/docs/agents/ - ---- +Keep large references/scripts/templates beside `SKILL.md` and use relative +paths. Never embed contributor-specific absolute paths, credentials or +transient local state. -End of skill. +For missing/wrong skills, use `zeus-diagnostics`. diff --git a/skills/zeus-sql/SKILL.md b/skills/zeus-sql/SKILL.md deleted file mode 100644 index 0f4430d..0000000 --- a/skills/zeus-sql/SKILL.md +++ /dev/null @@ -1,308 +0,0 @@ ---- -name: zeus-sql -description: SQL reference for database queries, schema design, and common patterns for SQLite, PostgreSQL, MySQL, and common ORMs. ---- - -# zeus-sql (Skill) - -Purpose: SQL reference for database queries, schema design, and common patterns for SQLite, PostgreSQL, MySQL, and common ORMs. - ---- - -## Quick Reference - Common Queries - -### Select with Filtering -```sql -SELECT * FROM users WHERE id = 1; -SELECT * FROM orders WHERE status = 'pending' AND created_at > '2024-01-01'; -SELECT * FROM products WHERE price BETWEEN 10 AND 50; -``` - -### Joins -```sql --- Inner join -SELECT o.id, u.name FROM orders o INNER JOIN users u ON o.user_id = u.id; - --- Left join (include NULLs from left table) -SELECT u.name, o.id FROM users u LEFT JOIN orders o ON u.id = o.user_id; - --- Multiple joins -SELECT o.id, u.name, p.name as product -FROM orders o -JOIN users u ON o.user_id = u.id -JOIN order_items oi ON o.id = oi.order_id -JOIN products p ON oi.product_id = p.id; -``` - -### Aggregations -```sql --- Count, Sum, Avg, Min, Max -SELECT COUNT(*), SUM(amount), AVG(price), MIN(created_at), MAX(updated_at) -FROM orders; - --- Group by with having -SELECT user_id, COUNT(*) as order_count -FROM orders -GROUP BY user_id -HAVING COUNT(*) > 5; -``` - -### Insert, Update, Delete -```sql -INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com'); -INSERT INTO users (name, email) VALUES - ('Bob', 'bob@example.com'), - ('Charlie', 'charlie@example.com'); - -UPDATE users SET name = 'Alice Smith' WHERE id = 1; -UPDATE products SET price = price * 0.9 WHERE category = 'sale'; - -DELETE FROM sessions WHERE expires_at < NOW(); -``` - -### Upsert (Insert or Update) -```sql --- PostgreSQL -INSERT INTO users (id, name, email) VALUES (1, 'Alice', 'alice@test.com') -ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name; - --- SQLite 3.24+ -INSERT INTO users (id, name, email) VALUES (1, 'Alice', 'alice@test.com') -ON CONFLICT(id) DO UPDATE SET name = EXCLUDED.name; - --- MySQL (REPLACE or ON DUPLICATE KEY) -INSERT INTO users (id, name, email) VALUES (1, 'Alice', 'alice@test.com') -ON DUPLICATE KEY UPDATE name = VALUES(name); -``` - ---- - -## Schema Design Patterns - -### Common Tables -```sql --- Users table -CREATE TABLE users ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - username TEXT UNIQUE NOT NULL, - email TEXT UNIQUE NOT NULL, - password_hash TEXT NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -); - --- Orders with foreign keys -CREATE TABLE orders ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER NOT NULL REFERENCES users(id), - status TEXT DEFAULT 'pending', - total DECIMAL(10,2) DEFAULT 0, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (user_id) REFERENCES users(id) -); - --- Join table for many-to-many -CREATE TABLE order_items ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - order_id INTEGER NOT NULL, - product_id INTEGER NOT NULL, - quantity INTEGER DEFAULT 1, - price DECIMAL(10,2) NOT NULL, - FOREIGN KEY (order_id) REFERENCES orders(id), - FOREIGN KEY (product_id) REFERENCES products(id), - UNIQUE(order_id, product_id) -); -``` - -### Indexes -```sql --- Single column index -CREATE INDEX idx_orders_user_id ON orders(user_id); -CREATE INDEX idx_orders_status ON orders(status); - --- Composite index (for queries filtering on multiple columns) -CREATE INDEX idx_orders_user_status ON orders(user_id, status); - --- Partial index (PostgreSQL) -CREATE INDEX idx_orders_pending ON orders(user_id) WHERE status = 'pending'; -``` - ---- - -## Common ORM Patterns - -### SQLAlchemy (Python) -```python -from sqlalchemy import create_engine, Column, Integer, String, DateTime -from sqlalchemy.orm import sessionmaker -from datetime import datetime - -engine = create_engine('sqlite:///app.db') -Session = sessionmaker(bind=engine) -session = Session() - -# Query -user = session.query(User).filter(User.email == 'test@example.com').first() - -# Insert -new_user = User(username='alice', email='alice@test.com') -session.add(new_user) -session.commit() - -# Update -user = session.query(User).filter(User.id == 1).first() -user.name = 'Alice Smith' -session.commit() - -# Delete -session.query(User).filter(User.id == 1).delete() -session.commit() -``` - -### Prisma (Node.js) -```typescript -const user = await prisma.user.findUnique({ - where: { email: 'test@example.com' } -}); - -const orders = await prisma.order.findMany({ - where: { userId: 1 }, - include: { items: true } -}); - -const newUser = await prisma.user.create({ - data: { username: 'alice', email: 'alice@test.com' } -}); -``` - -### Drizzle (Node.js) -```typescript -import { users, orders } from './schema'; - -const user = await db.select().from(users).where(eq(users.email, 'test@example.com')); -``` - ---- - -## Window Functions - -### Rownumber, Rank, Dense Rank -```sql --- Rank users by order count -SELECT - user_id, - COUNT(*) as order_count, - RANK() OVER (ORDER BY COUNT(*) DESC) as rank, - DENSE_RANK() OVER (ORDER BY COUNT(*) DESC) as dense_rank -FROM orders -GROUP BY user_id; -``` - -### Partition by (grouped ranking) -```sql --- Rank products within each category -SELECT - name, - category, - price, - RANK() OVER (PARTITION BY category ORDER BY price DESC) as rank_in_category -FROM products; -``` - -### Running Total -```sql -SELECT - id, - amount, - SUM(amount) OVER (ORDER BY id) as running_total -FROM transactions; -``` - ---- - -## Common SQLite Commands - -```bash -# Open database -sqlite3 app.db - -# List tables -.tables - -# Show schema -.schema users - -# Show all indexes -.indexes - -# Export to SQL -.dump - -# Import SQL file -.read schema.sql - -# Query from command line -sqlite3 app.db "SELECT * FROM users LIMIT 5;" -``` - ---- - -## PostgreSQL Specific - -```sql --- Insert returning -INSERT INTO users (name) VALUES ('Alice') RETURNING id, *; - --- JSON operations -SELECT data->>'field' FROM table; -SELECT json_build_object('key', value); -SELECT * FROM json_each('{"a":1, "b":2}'); - --- Array operations -SELECT ARRAY[1,2,3] @> ARRAY[1]; -- contains -SELECT ARRAY[1,2] || ARRAY[3]; -- concatenation - --- CTEs (Common Table Expressions) -WITH recent_orders AS ( - SELECT * FROM orders WHERE created_at > '2024-01-01' -) -SELECT u.name, ro.count -FROM users u -JOIN (SELECT user_id, COUNT(*) as count FROM recent_orders GROUP BY user_id) ro -ON u.id = ro.user_id; -``` - ---- - -## Troubleshooting - -| Issue | Solution | -|---|---| -| Slow queries | Use EXPLAIN ANALYZE; add indexes | -| Lock contention | Use transactions, avoid long-held locks | -| N+1 queries | Use JOIN, eager loading (include/joinedload) | -| NULL comparison | Use `IS NULL` or `IS NOT NULL`, not `= NULL` | -| String comparison | Use `ILIKE` for case-insensitive (PostgreSQL) | - ---- - -## Migration Patterns - -### Add Column -```sql -ALTER TABLE users ADD COLUMN phone TEXT; -``` - -### Rename Table -```sql -ALTER TABLE orders RENAME TO orders_new; -``` - -### Drop Column (PostgreSQL) -```sql -ALTER TABLE users DROP COLUMN old_field; -``` - ---- - -End of skill. \ No newline at end of file diff --git a/skills/zeus-sql/codemap.md b/skills/zeus-sql/codemap.md deleted file mode 100644 index 4b363ce..0000000 --- a/skills/zeus-sql/codemap.md +++ /dev/null @@ -1,19 +0,0 @@ -# skills/zeus-sql/ - - - -## Responsibility - - - -## Design - - - -## Flow - - - -## Integration - - diff --git a/skills/zeus-swarm/SKILL.md b/skills/zeus-swarm/SKILL.md deleted file mode 100644 index 3571df3..0000000 --- a/skills/zeus-swarm/SKILL.md +++ /dev/null @@ -1,354 +0,0 @@ ---- -name: zeus-swarm -description: Documentation and reference for the OpenCode opencode-swarm plugin. Tools, concepts, workflows, templates, and troubleshooting for swarm features, tasks, worktrees, and multi-agent orchestration. ---- - -**πŸ”— opencode-swarm Repository**: https://github.com/zaxbysauce/opencode-swarm - ---- - -## Swarm Concepts - -### Core Terms - -| Term | Description | -|---|---| -| `feature` | A unit of work, like a user story or epic | -| `task` | A sub-unit of a feature, a specific deliverable | -| `worktree` | A git worktree linked to a feature/task | -| `session` | A conversation/working context | -| `hive` | The orchestration layer coordinating agents | - -### Workflow Overview - -``` -feature create "new-login" - └── task create "design-ui" - └── task create "implement-backend" - └── task create "write-tests" - β”‚ - β–Ό -worktree start task-123 ← Creates git worktree + spawns worker - β”‚ - β”œβ”€β”€ Worker (Forager) executes in isolated session - β”‚ - β–Ό -worktree commit ← Commits changes to feature branch - β”‚ - β–Ό -hive merge ← Merges feature into main -``` - ---- - -## Swarm Tools - -### Feature Management - -```bash -# Create a new feature -swarm_feature_create name="user-auth" ticket="US-123" - -# Complete a feature -swarm_feature_complete name="user-auth" - -# List features -swarm_status - -# Read feature context -swarm_status feature="user-auth" -``` - -### Task Management - -```bash -# Create a task (manual) -swarm_task_create name="Implement login form" feature="user-auth" order=1 - -# Create tasks from approved plan -swarm_tasks_sync feature="user-auth" - -# Update task status -swarm_task_update task="task-123" status="completed" - -# Update task summary -swarm_task_update task="task-123" summary="Login form implemented with validation" -``` - -### Worktree Lifecycle - -```bash -# Start worktree for a task -swarm_worktree_start task="task-123" feature="user-auth" -# β†’ Creates: git worktree add feature/user-auth-t123 -# β†’ Spawns: Forager worker agent - -# Resume blocked worktree -swarm_worktree_create task="task-123" feature="user-auth" continue_from="blocked" - -# Commit changes (worker β†’ feature branch) -swarm_worktree_commit task="task-123" status="completed" summary="Implemented login form" - -# Discard changes -swarm_worktree_discard task="task-123" -``` - -### Integration - -```bash -# Merge feature into current branch -swarm_merge task="task-123" feature="user-auth" - -# Merge with strategy -swarm_merge task="task-123" strategy="squash" # merge | squash | rebase -``` - -### Context Files - -```bash -# Write persistent context -swarm_context_write name="architecture.md" content="# Architecture" feature="user-auth" - -# Write plan -swarm_plan_write content="# Plan" feature="user-auth" - -# Read plan and comments -swarm_plan_read feature="user-auth" -``` - -### Agent Memory Sync - -```bash -# Sync AGENTS.md -swarm_agents_md action="init" # Scan codebase, generate (preview) -swarm_agents_md action="sync" # Propose updates from contexts -swarm_agents_md action="apply" # Write approved content to disk -``` - ---- - -## plan.md Template - -```markdown -# Feature: [Feature Name] - -**Ticket:** [Ticket ID] -**Status:** [Draft | Approved | In Progress | Completed] - ---- - -## Goals - -1. [Goal 1] -2. [Goal 2] - ---- - -## Tasks - -- [ ] Task 1 -- [ ] Task 2 - ---- - -## Notes - -[Additional context, decisions, constraints] -``` - ---- - -## Feature Context Template - -```markdown -# [Feature Name] - -**Created:** [Date] -**Status:** [Active | Completed | Abandoned] - -## Purpose - -[Brief description of what this feature does] - -## Key Decisions - -- [Decision 1] -- [Decision 2] - -## Files Changed - -- `src/feature/main.ts` -- `tests/feature/test.ts` - -## Open Questions - -- [Question 1] -- [Question 2] -``` - ---- - -## Task Template - -```markdown -# Task: [Task Name] - -**Feature:** [Feature Name] -**Status:** [Pending | In Progress | Blocked | Completed] - -## Description - -[What needs to be done] - -## Acceptance Criteria - -- [ ] Criterion 1 -- [ ] Criterion 2 - -## Notes - -[Implementation notes, constraints, references] -``` - ---- - -## Agent Definition Template (for Feature Workers) - -```markdown ---- -description: "Worker agent for [feature-name] feature" -mode: all -model: opencode-go/big-pickle -steps: 50 -permission: - edit: allow - write: allow - webfetch: allow - bash: - "*": ask - "git status *": allow - "git diff *": allow - "git add *": allow - "git commit *": allow - "git push": ask ---- - -# Feature Worker: [Feature Name] - -You are a worker agent implementing the [Feature Name] feature. - -## Task Context - -Feature goal: [Brief description] -Current task: [Specific task from plan] - -## Your Responsibilities - -1. Implement the task according to the plan -2. Follow existing code patterns -3. Run tests before marking complete -4. Report progress to the orchestrator - -## Rules - -1. Always check the plan before implementing -2. Write tests for new code -3. Commit frequently with clear messages -4. Ask for clarification if blocked - -## Quality Gates - -- [ ] Code compiles/passes lint -- [ ] Tests pass -- [ ] Follows project conventions -- [ ] No secrets committed -``` - ---- - -## Multi-Agent Orchestration Patterns - -### Pattern 1: Fan-Out (Parallel Workers) - -``` -Orchestrator (Swarm Master) - β”œβ”€β”€ Worker A (Task 1) ──→ commits - β”œβ”€β”€ Worker B (Task 2) ──→ commits - └── Worker C (Task 3) ──→ commits - β”‚ - β–Ό - Swarm Merge -``` - -### Pattern 2: Sequential (Pipeline) - -``` -Worker A ──→ Worker B ──→ Worker C ──→ Merge -``` - -### Pattern 3: Review Gate - -``` -Worker ──→ Reviewer ──→ Approve? ──→ Merge - β”‚ - β”œβ”€β”€ Yes ──→ Merge - └── No ──→ Worker (fix) -``` - ---- - -## Git Worktree Strategy - -### Create Feature Branch + Worktree - -```bash -# From main -git checkout main -git pull - -# Create feature branch -git worktree add ../feature-name main -cd ../feature-name - -# Or with -b flag (creates new branch) -git worktree add -b feature/name ../feature-name main -``` - -### Worktree Cleanup - -```bash -# List worktrees -git worktree list - -# Remove worktree -git worktree remove ../feature-name - -# Prune stale worktrees -git worktree prune -``` - ---- - -## Common Issues - -| Issue | Solution | -|---|---| -| Task blocked | Use `swarm_worktree_create continue_from="blocked"` | -| Worktree conflict | Remove conflicting worktree: `git worktree remove` | -| Plan not found | Create with `swarm_plan_write` | -| Worker not responding | Check task status with `swarm_task_update` | -| Merge conflict | Resolve in main branch, then merge | - ---- - -## Relevant URLs - -| Resource | URL | -|---|---| -| OpenCode Swarm Architecture | https://github.com/zaxbysauce/opencode-swarm/blob/main/docs/architecture.md | -| Pre-Swarm Planning | https://github.com/zaxbysauce/opencode-swarm/blob/main/docs/planning.md | -| Swarm Briefing | https://github.com/zaxbysauce/opencode-swarm/blob/main/docs/swarm-briefing.md | - ---- - -End of skill. diff --git a/skills/zeus-swarm/codemap.md b/skills/zeus-swarm/codemap.md deleted file mode 100644 index f8ad2f7..0000000 --- a/skills/zeus-swarm/codemap.md +++ /dev/null @@ -1,19 +0,0 @@ -# skills/zeus-swarm/ - - - -## Responsibility - - - -## Design - - - -## Flow - - - -## Integration - - diff --git a/skills/zeus-upskill/SKILL.md b/skills/zeus-upskill/SKILL.md deleted file mode 100644 index 5ebed6b..0000000 --- a/skills/zeus-upskill/SKILL.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -name: zeus-upskill -description: Guide for creating new skills for OpenCode and automatically registering them in OpenZeus. Use this when the user wants to create a custom skill that will be available to OpenZeus. ---- - -# zeus-upskill (Skill) - -Purpose: Create an OpenZeus `zeus-*` skill and wire it into OpenZeus distribution metadata and documentation workflows. - -For general skill concepts, structure, frontmatter, and discovery paths, load `zeus-skills` first. - ---- - -## Scope Boundary - -| Need | Use | -|---|---| -| Learn what a skill is | `zeus-skills` | -| Create/edit generic OpenCode skills | `zeus-skills` | -| Add a new `zeus-*` OpenZeus skill | `zeus-upskill` | -| Register skill metadata/README entries | `zeus-upskill` | - ---- - -## OpenZeus Skill Workflow - -```text -1. Load zeus-skills for canonical SKILL.md rules. -2. Choose name: zeus-. -3. Create skills/zeus-/SKILL.md in the OpenZeus repo. -4. Preserve required frontmatter: name + description. -5. Add concise, example-driven content. -6. Register the skill in OpenZeus metadata/README tables when in scope. -7. Sync repo changes to runtime config when project policy requires it. -``` - ---- - -## Naming Convention - -OpenZeus skills use `zeus-`: - -| Example | Responsibility | -|---|---| -| `zeus-core` | OpenCode internals reference | -| `zeus-agents` | Agent creation templates | -| `zeus-commands` | Command creation templates | -| `zeus-docker` | Docker/containerization reference | - ---- - -## Minimal OpenZeus Skill - -````markdown ---- -name: zeus-example -description: Expert reference for example workflows. Use this when the user asks about examples. ---- - -# zeus-example (Skill) - -Purpose: Expert reference for example workflows. - ---- - -## Quick Reference - -| Task | Command | -|---|---| -| Show status | `example status` | - ---- - -End of skill. -```` - ---- - -## Registration Checklist - -When the task scope allows editing the relevant files, update: - -| File | Update | -|---|---| -| `skills/zeus-/SKILL.md` | New skill content | -| `README.md` | Skill table/feature list entry | -| `agents/OpenZeus.md` | Skill loading trigger, if maintained there | -| `skills/codemap.md` | Skill taxonomy/responsibility notes | - -OpenZeus currently has no generated central metadata manifest; if one is added later, update it as part of this checklist. - -Do not edit files outside the user-approved scope. If registration files are out of scope, report the exact follow-up edits. - ---- - -## Runtime Sync Notes - -OpenZeus maintains repo and runtime config copies. After approved repo edits, follow project policy for sync, commonly: - -```bash -./scripts/sync-utils.sh push -``` - -Only run sync when scripts are in scope and the user/project instructions authorize it. - ---- - -## Troubleshooting - -| Problem | Fix | -|---|---| -| Skill created but not listed | Add README/metadata entries when in scope | -| Skill not available at runtime | Sync repo to `~/.config/opencode/skills/` per project policy | -| Duplicate guidance with `zeus-skills` | Keep general skill rules in `zeus-skills`; keep registration here | -| Registration file out of scope | Leave skill file complete and report follow-up needed | - ---- - -## Related Documentation - -- Canonical skill guide: `zeus-skills` -- OpenCode Skills: https://opencode.ai/docs/skills/ -- OpenZeus: https://github.com/Aveer/OpenZeus - ---- - -End of skill. diff --git a/skills/zeus-upskill/codemap.md b/skills/zeus-upskill/codemap.md deleted file mode 100644 index 4459e16..0000000 --- a/skills/zeus-upskill/codemap.md +++ /dev/null @@ -1,19 +0,0 @@ -# skills/zeus-upskill/ - - - -## Responsibility - - - -## Design - - - -## Flow - - - -## Integration - - diff --git a/src/plugin.js b/src/plugin.js new file mode 100644 index 0000000..7087f7e --- /dev/null +++ b/src/plugin.js @@ -0,0 +1,19 @@ +import path from "node:path" +import { fileURLToPath } from "node:url" +import { define } from "@opencode-ai/plugin/v2/promise" + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..") +const skillRoot = path.join(root, "skills") + +export default define({ + id: "openzeus", + + async setup(ctx) { + await ctx.skill.transform((draft) => { + draft.source({ + type: "directory", + path: skillRoot, + }) + }) + }, +}) diff --git a/tests/plugin.mjs b/tests/plugin.mjs new file mode 100644 index 0000000..ed5cab0 --- /dev/null +++ b/tests/plugin.mjs @@ -0,0 +1,29 @@ +import assert from "node:assert/strict" +import path from "node:path" +import plugin from "../src/plugin.js" + +assert.equal(plugin.id, "openzeus") +assert.equal(typeof plugin.setup, "function") + +const sources = [] +const ctx = { + skill: { + transform: async (callback) => { + callback({ + source(value) { sources.push(value) }, + list() { return [...sources] }, + }) + return { dispose: async () => {} } + }, + reload: async () => {}, + }, +} + +await plugin.setup(ctx) + +assert.equal(sources.length, 1) +assert.equal(sources[0].type, "directory") +assert.equal(path.basename(sources[0].path), "skills") +assert.ok(path.isAbsolute(sources[0].path)) + +console.log("plugin ok") diff --git a/tests/run.sh b/tests/run.sh index 8ccc983..51532d5 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -11,399 +11,166 @@ assert_file_contains() { [[ "$content" == *"$expected"* ]] } -assert_no_non_zeus_entries() { - local dir="$1" kind="$2" entry - for entry in "$dir"/*; do - [[ -e "$entry" ]] || continue - case "$kind:$(basename "$entry")" in - skill:zeus-*) ;; - command:zeus-*.md) ;; - *) echo "unexpected entry: $entry" >&2; return 1 ;; - esac - done -} - -for script in "$root/scripts/install.sh" "$root/scripts/sync-utils.sh" "$root/scripts/create-utils.sh" "$root/scripts/setup-hooks.sh" "$root/scripts/doctor.sh" "$root/scripts/init-project.sh" "$root/scripts/setup.sh" "$root/scripts/validate.sh" "$root/scripts/capture-command.sh" "$root/scripts/diff.sh" "$root/scripts/upgrade.sh" "$root/bin/openzeus"; do - [[ -x "$script" ]] || { echo "not executable: $script" >&2; exit 1; } +for script in "$root/bin/openzeus" "$root/scripts/create-utils.sh" "$root/scripts/install-agent.sh" "$root/scripts/validate.sh"; do + [[ -x "$script" ]] bash -n "$script" done +[[ -x "$root/scripts/inspect.mjs" ]] +[[ -x "$root/scripts/audit.mjs" ]] +[[ -x "$root/scripts/migrate.mjs" ]] +[[ -f "$root/src/plugin.js" ]] -config="$tmp/config" -repo="$tmp/repo" -install_dir="$tmp/install" -mkdir -p "$config" "$repo/agents" "$repo/skills/zeus-alpha" "$repo/skills/other" "$repo/commands" +"$root/bin/openzeus" help | grep -q 'install-agent' +"$root/bin/openzeus" help | grep -q 'audit' +"$root/bin/openzeus" help | grep -q 'inspect' +"$root/bin/openzeus" help | grep -q 'migrate' -cat > "$repo/agents/OpenZeus.md" <<'EOF' ---- -description: repo agent -mode: subagent -permission: - edit: ask - bash: ask ---- -EOF -printf '%s\n' 'repo skill' > "$repo/skills/zeus-alpha/SKILL.md" -printf '%s\n' 'support' > "$repo/skills/zeus-alpha/reference.md" -printf '%s\n' 'skip skill' > "$repo/skills/other/SKILL.md" -printf '%s\n' 'repo command' > "$repo/commands/zeus-one.md" -printf '%s\n' 'skip command' > "$repo/commands/not-zeus.md" +config="$tmp/config" -"$root/scripts/create-utils.sh" --dry-run --config "$config" agent demo-agent 'desc' >/dev/null +"$root/bin/openzeus" create --dry-run --config "$config" agent demo-agent "Demo agent" >/dev/null [[ ! -e "$config/agents/demo-agent.md" ]] -"$root/scripts/create-utils.sh" --config "$config" agent demo-agent 'desc' -assert_file_contains "$config/agents/demo-agent.md" 'mode: subagent' -assert_file_contains "$config/agents/demo-agent.md" 'permission:' -"$root/scripts/create-utils.sh" --config "$config" skill demo-skill 'desc' -assert_file_contains "$config/skills/demo-skill/SKILL.md" 'name: demo-skill' -"$root/scripts/create-utils.sh" --config "$config" command demo-command 'desc' -assert_file_contains "$config/commands/demo-command.md" '$ARGUMENTS' -printf '%s\n' 'keep command' > "$config/commands/demo-command.md" -"$root/scripts/create-utils.sh" --config "$config" command demo-command 'new desc' >/dev/null -assert_file_contains "$config/commands/demo-command.md" 'keep command' -"$root/scripts/create-utils.sh" --force --config "$config" command demo-command 'forced desc' >/dev/null -assert_file_contains "$config/commands/demo-command.md" 'forced desc' - -default_create_config="$tmp/default-create-config" -outside_dir="$tmp/outside-project" -mkdir -p "$outside_dir" -(cd "$outside_dir" && OPENCODE_CONFIG_DIR="$default_create_config" "$root/bin/openzeus" create command outside-command 'outside desc' >/dev/null) -[[ -f "$default_create_config/commands/outside-command.md" ]] -[[ ! -f "$root/commands/outside-command.md" ]] - -OPENCODE_CONFIG_DIR="$config" "$root/scripts/install.sh" --dry-run --target "$install_dir" >/dev/null -[[ ! -e "$install_dir" ]] -OPENCODE_CONFIG_DIR="$config" "$root/scripts/install.sh" --target "$install_dir" >/dev/null -[[ -f "$install_dir/agents/OpenZeus.md" ]] -assert_no_non_zeus_entries "$install_dir/skills" skill -assert_no_non_zeus_entries "$install_dir/commands" command -[[ -x "$install_dir/sync-utils.sh" && -x "$install_dir/create-utils.sh" && -x "$install_dir/setup-hooks.sh" && -x "$install_dir/doctor.sh" && -x "$install_dir/init-project.sh" ]] -printf '%s\n' 'local change' > "$install_dir/agents/OpenZeus.md" -OPENCODE_CONFIG_DIR="$config" "$root/scripts/install.sh" --target "$install_dir" >/dev/null -assert_file_contains "$install_dir/agents/OpenZeus.md" 'local change' -OPENCODE_CONFIG_DIR="$config" "$root/scripts/install.sh" --force --backup --target "$install_dir" >/dev/null -backup_found=false -for backup in "$install_dir"/agents/OpenZeus.md.bak.*; do - [[ -e "$backup" ]] || continue - backup_found=true -done -[[ "$backup_found" == true ]] +"$root/bin/openzeus" create --config "$config" agent demo-agent "Demo agent" >/dev/null +assert_file_contains "$config/agents/demo-agent.md" 'permissions:' +assert_file_contains "$config/agents/demo-agent.md" 'action: shell' +if grep -q '^permission:' "$config/agents/demo-agent.md"; then + echo "legacy permission generated" >&2 + exit 1 +fi -env_install="$tmp/env-install" -OPENCODE_CONFIG_DIR="$env_install" "$root/scripts/install.sh" >/dev/null -[[ -f "$env_install/agents/OpenZeus.md" ]] +"$root/bin/openzeus" create --config "$config" skill demo-skill "Use for demo work" >/dev/null +assert_file_contains "$config/skills/demo-skill/SKILL.md" 'name: demo-skill' +assert_file_contains "$config/skills/demo-skill/SKILL.md" 'description:' -core_install="$tmp/core-install" -OPENCODE_CONFIG_DIR="$core_install" "$root/scripts/install.sh" --core >/dev/null -[[ -f "$core_install/agents/OpenZeus.md" && -d "$core_install/skills/zeus-core" && ! -d "$core_install/skills/zeus-swarm" ]] -[[ -f "$core_install/commands/zeus-git-commit.md" && ! -f "$core_install/commands/zeus-kanban.md" ]] -core_doctor_out="$(OPENCODE_CONFIG_DIR="$core_install" "$root/bin/openzeus" doctor)" -[[ "$core_doctor_out" == *"OpenZeus doctor: ok"* ]] -OPENCODE_CONFIG_DIR="$core_install" "$root/bin/openzeus" diff --ci >/dev/null -core_upgrade_config="$tmp/core-upgrade-config" -OPENCODE_CONFIG_DIR="$core_upgrade_config" "$root/scripts/install.sh" --core >/dev/null -OPENCODE_CONFIG_DIR="$core_upgrade_config" "$root/bin/openzeus" upgrade --apply >/dev/null -[[ -f "$core_upgrade_config/commands/zeus-git-commit.md" && ! -f "$core_upgrade_config/commands/zeus-kanban.md" ]] -[[ "$(<"$core_upgrade_config/.openzeus-install-profile")" == core ]] -OPENCODE_CONFIG_DIR="$core_upgrade_config" "$root/bin/openzeus" doctor >/dev/null -OPENCODE_CONFIG_DIR="$core_upgrade_config" "$root/bin/openzeus" diff --ci >/dev/null -printf '%s\n' all > "$core_upgrade_config/.openzeus-install-profile" -OPENCODE_CONFIG_DIR="$core_upgrade_config" "$root/bin/openzeus" rollback --apply >/dev/null -[[ "$(<"$core_upgrade_config/.openzeus-install-profile")" == core ]] -OPENCODE_CONFIG_DIR="$core_upgrade_config" "$root/bin/openzeus" doctor >/dev/null -OPENCODE_CONFIG_DIR="$core_upgrade_config" "$root/bin/openzeus" diff --ci >/dev/null -extras_install="$tmp/extras-install" -OPENCODE_CONFIG_DIR="$extras_install" "$root/scripts/install.sh" --extras >/dev/null -[[ ! -d "$extras_install/skills/zeus-core" && -d "$extras_install/skills/zeus-swarm" ]] -[[ ! -f "$extras_install/commands/zeus-git-commit.md" && -f "$extras_install/commands/zeus-kanban.md" ]] +"$root/bin/openzeus" create --config "$config" command demo-command "Demo command" >/dev/null +assert_file_contains "$config/commands/demo-command.md" '$ARGUMENTS' -type_mismatch_config="$tmp/type-mismatch-config" -"$root/scripts/install.sh" --target "$type_mismatch_config" >/dev/null -rm -f "$type_mismatch_config/commands/zeus-git-commit.md" -mkdir -p "$type_mismatch_config/commands/zeus-git-commit.md" -printf '%s\n' 'nested stale file' > "$type_mismatch_config/commands/zeus-git-commit.md/stale.txt" -"$root/scripts/install.sh" --force --backup --target "$type_mismatch_config" >/dev/null -[[ -f "$type_mismatch_config/commands/zeus-git-commit.md" ]] -assert_file_contains "$type_mismatch_config/commands/zeus-git-commit.md" 'description:' -type_backup_found=false -for backup in "$type_mismatch_config"/commands/zeus-git-commit.md.bak.*; do - [[ -e "$backup" ]] || continue - type_backup_found=true -done -[[ "$type_backup_found" == true ]] +agent_config="$tmp/agent-config" +"$root/bin/openzeus" install-agent --dry-run --target "$agent_config" >/dev/null +[[ ! -e "$agent_config" ]] -git init -q "$repo" -(cd "$repo" && "$root/scripts/setup-hooks.sh" --dry-run >/dev/null) -(cd "$repo" && "$root/scripts/setup-hooks.sh" >/dev/null) -[[ -x "$repo/.git/hooks/post-merge" && -x "$repo/.git/hooks/pre-push" ]] -assert_file_contains "$repo/.git/hooks/post-merge" '$repo_root/scripts/sync-utils.sh' +"$root/bin/openzeus" install-agent --target "$agent_config" >/dev/null +cmp -s "$root/agents/OpenZeus.md" "$agent_config/agents/OpenZeus.md" -sync_config="$tmp/sync-config" -mkdir -p "$sync_config" -status_out="$(OPENCODE_CONFIG_DIR="$config" "$root/scripts/sync-utils.sh" --repo "$repo" --config "$sync_config" status || true)" -[[ "$status_out" == *"MISSING config:agents/OpenZeus.md"* ]] -OPENCODE_CONFIG_DIR="$config" "$root/scripts/sync-utils.sh" --dry-run --repo "$repo" --config "$sync_config" push >/dev/null -[[ ! -e "$sync_config/agents/OpenZeus.md" ]] -OPENCODE_CONFIG_DIR="$config" "$root/scripts/sync-utils.sh" --repo "$repo" --config "$sync_config" push >/dev/null -OPENCODE_CONFIG_DIR="$config" "$root/scripts/sync-utils.sh" --repo "$repo" --config "$sync_config" status >/dev/null -[[ -f "$sync_config/skills/zeus-alpha/reference.md" ]] +printf '%s\n' 'local customization' > "$agent_config/agents/OpenZeus.md" +install_fail=0 +"$root/bin/openzeus" install-agent --target "$agent_config" >/dev/null 2>&1 || install_fail=$? +[[ "$install_fail" -eq 1 ]] +assert_file_contains "$agent_config/agents/OpenZeus.md" 'local customization' -printf '%s\n' 'config conflict' > "$sync_config/agents/OpenZeus.md" -if OPENCODE_CONFIG_DIR="$config" "$root/scripts/sync-utils.sh" --repo "$repo" --config "$sync_config" push >/dev/null 2>&1; then - echo "expected sync conflict" >&2 - exit 1 -fi -OPENCODE_CONFIG_DIR="$config" "$root/scripts/sync-utils.sh" --force --backup --repo "$repo" --config "$sync_config" push >/dev/null +"$root/bin/openzeus" install-agent --force --backup --target "$agent_config" >/dev/null +cmp -s "$root/agents/OpenZeus.md" "$agent_config/agents/OpenZeus.md" backup_found=false -for backup in "$sync_config"/agents/OpenZeus.md.bak.*; do +for backup in "$agent_config"/agents/OpenZeus.md.bak.*; do [[ -e "$backup" ]] || continue backup_found=true done [[ "$backup_found" == true ]] -auto_config="$tmp/auto-config" -mkdir -p "$auto_config" -auto_out="$(OPENCODE_CONFIG_DIR="$config" "$root/scripts/sync-utils.sh" --repo "$repo" --config "$auto_config" auto)" -[[ "$auto_out" == *"repo -> config"* ]] -[[ -f "$auto_config/agents/OpenZeus.md" ]] - -doctor_out="$(OPENCODE_CONFIG_DIR="$install_dir" "$root/bin/openzeus" doctor)" -[[ "$doctor_out" == *"OpenZeus doctor: ok"* ]] - -drift_config="$tmp/drift-config" -cp -R "$install_dir" "$drift_config" -rm -f "$drift_config/agents/OpenZeus.md" -printf '%s\n' 'different skill' > "$drift_config/skills/zeus-core/SKILL.md" -printf '%s\n' 'different command' > "$drift_config/commands/zeus-git-commit.md" -printf '%s\n' 'different helper' > "$drift_config/doctor.sh" -chmod -x "$drift_config/init-project.sh" -drift_fix_plan_out="$(OPENCODE_CONFIG_DIR="$drift_config" "$root/bin/openzeus" doctor --fix-plan)" -[[ "$drift_fix_plan_out" == *"WARN OpenZeus agent missing from config"* ]] -[[ "$drift_fix_plan_out" == *"WARN skill zeus-core differs in config"* ]] -[[ "$drift_fix_plan_out" == *"WARN command zeus-git-commit.md differs in config"* ]] -[[ "$drift_fix_plan_out" == *"WARN helper doctor.sh differs in config"* ]] -[[ "$drift_fix_plan_out" == *"WARN helper init-project.sh is not executable in config"* ]] -[[ "$drift_fix_plan_out" == *"openzeus install"* ]] -[[ "$drift_fix_plan_out" == *"openzeus install --force --backup"* ]] -[[ "$drift_fix_plan_out" == *"openzeus sync status"* ]] -[[ "$drift_fix_plan_out" == *"chmod +x $drift_config/init-project.sh"* ]] -[[ "$drift_fix_plan_out" != *"(none; no fixes required)" ]] - -ci_doctor_fail=0 -OPENCODE_CONFIG_DIR="$drift_config" "$root/bin/openzeus" doctor --ci >/dev/null || ci_doctor_fail=$? -[[ "$ci_doctor_fail" -ne 0 ]] - -setup_project="$tmp/setup-project" -mkdir -p "$setup_project" -setup_plan_out="$($root/bin/openzeus setup --plan --target "$setup_project")" -[[ "$setup_plan_out" == *"Detected stack:"* && "$setup_plan_out" == *"Proposed files:"* && "$setup_plan_out" == *"Apply: openzeus setup --apply"* ]] -recipe_plan_out="$($root/bin/openzeus setup --plan --target "$setup_project" --recipe python)" -[[ "$recipe_plan_out" == *"recipe python"* ]] -(cd "$setup_project" && "$root/bin/openzeus" setup --apply --target "$setup_project" >/dev/null) -[[ -f "$setup_project/.opencode/agents/project-guide.md" && -f "$setup_project/.opencode/context/architecture.md" && -f "$setup_project/.opencode/context/commands.md" && -f "$setup_project/.opencode/context/testing.md" ]] -recipe_project="$tmp/recipe-project" -mkdir -p "$recipe_project" -"$root/bin/openzeus" setup --apply --target "$recipe_project" --recipe python >/dev/null -assert_file_contains "$recipe_project/.opencode/commands/test.md" 'pytest' -assert_file_contains "$recipe_project/.opencode/context/architecture.md" 'Recipe: python' -assert_file_contains "$recipe_project/.opencode/context/commands.md" 'Test: pytest' -context_dry_run="$($root/bin/openzeus context init --target "$setup_project" --dry-run)" -[[ "$context_dry_run" == *"DRY-RUN:"* ]] - -recipes_out="$($root/bin/openzeus recipes)" -[[ "$recipes_out" == *"node:"* && "$recipes_out" == *"solo-dev:"* ]] - -validate_fail=0 -OPENCODE_CONFIG_DIR="$drift_config" "$root/bin/openzeus" validate --ci >/dev/null || validate_fail=$? -[[ "$validate_fail" -ne 0 ]] +"$root/bin/openzeus" validate --ci >/dev/null bad_project="$tmp/bad-project" -mkdir -p "$bad_project/.opencode/agents" "$bad_project/.opencode/skills/badskill" "$bad_project/.opencode/commands" -cat > "$bad_project/.opencode/agents/bad.md" <<'EOF' +mkdir -p "$bad_project/.opencode/agents" "$bad_project/.opencode/commands" "$bad_project/.opencode/skills/bad" +cat > "$bad_project/.opencode/agents/legacy.md" <<'EOF' --- -description: bad -mode: allow -tools: yes -permission: allow +description: legacy +mode: subagent +permission: + bash: ask --- EOF -cat > "$bad_project/.opencode/skills/badskill/SKILL.md" <<'EOF' +cat > "$bad_project/.opencode/commands/legacy.md" <<'EOF' --- -name: badskill +description: legacy +subtask: true --- EOF -cat > "$bad_project/.opencode/commands/bad.md" <<'EOF' +cat > "$bad_project/.opencode/skills/bad/SKILL.md" <<'EOF' --- +name: bad --- EOF -validate_project_fail=0 -$root/bin/openzeus validate --project "$bad_project" --ci >/dev/null || validate_project_fail=$? -[[ "$validate_project_fail" -ne 0 ]] - -capture_dir="$tmp/capture" -mkdir -p "$capture_dir" -capture_out="$($root/bin/openzeus capture-command --name release-note --prompt 'write release notes' --target "$capture_dir")" -[[ "$capture_out" == *"Created"* && -f "$capture_dir/commands/release-note.md" ]] -[[ "$(<"$capture_dir/commands/release-note.md")" == *"write release notes"* && "$(<"$capture_dir/commands/release-note.md")" == *'$ARGUMENTS'* ]] -capture_dry_out="$($root/bin/openzeus capture-command --name release-note --prompt 'dry' --target "$capture_dir" --dry-run)" -[[ "$capture_dry_out" == *"DRY-RUN: no files written"* ]] -capture_empty_dir="$tmp/capture-dry-empty" -capture_empty_out="$($root/bin/openzeus capture-command --name dry-only --prompt 'dry only' --target "$capture_empty_dir" --dry-run)" -[[ "$capture_empty_out" == *"DRY-RUN"* && ! -e "$capture_empty_dir" ]] - -diff_out="$(OPENCODE_CONFIG_DIR="$config" "$root/bin/openzeus" diff --summary || true)" -[[ "$diff_out" == *"issue(s)"* ]] -extra_diff_config="$tmp/extra-diff-config" -OPENCODE_CONFIG_DIR="$extra_diff_config" "$root/scripts/install.sh" >/dev/null -mkdir -p "$extra_diff_config/skills/zeus-local-extra" -printf '%s\n' 'local' > "$extra_diff_config/skills/zeus-local-extra/SKILL.md" -extra_diff_out="$(OPENCODE_CONFIG_DIR="$extra_diff_config" "$root/bin/openzeus" diff)" -[[ "$extra_diff_out" == *"EXTRA zeus-local-extra"* ]] -rm -f "$extra_diff_config/upgrade.sh" -helper_diff_fail=0 -OPENCODE_CONFIG_DIR="$extra_diff_config" "$root/bin/openzeus" diff --ci >/dev/null || helper_diff_fail=$? -[[ "$helper_diff_fail" -ne 0 ]] - -upgrade_config="$tmp/upgrade-config" -OPENCODE_CONFIG_DIR="$upgrade_config" "$root/scripts/install.sh" >/dev/null -printf '%s\n' 'changed' > "$upgrade_config/agents/OpenZeus.md" -mkdir -p "$upgrade_config/.openzeus-backups" -before_backup_count=$(find "$upgrade_config/.openzeus-backups" -mindepth 1 -maxdepth 1 2>/dev/null | wc -l | tr -d ' ') -upgrade_out="$(OPENCODE_CONFIG_DIR="$upgrade_config" "$root/bin/openzeus" upgrade --dry-run)" -after_backup_count=$(find "$upgrade_config/.openzeus-backups" -mindepth 1 -maxdepth 1 2>/dev/null | wc -l | tr -d ' ') -[[ "$upgrade_out" == *"Would backup"* && "$before_backup_count" == "$after_backup_count" ]] -upgrade_apply_out="$(OPENCODE_CONFIG_DIR="$upgrade_config" "$root/bin/openzeus" upgrade --apply)" -[[ "$upgrade_apply_out" == *"OpenZeus assets installed"* ]] -after_apply_backup_count=$(find "$upgrade_config/.openzeus-backups" -mindepth 1 -maxdepth 1 2>/dev/null | wc -l | tr -d ' ') -[[ "$after_apply_backup_count" -gt "$after_backup_count" ]] -rollback_dry_out="$(OPENCODE_CONFIG_DIR="$upgrade_config" "$root/bin/openzeus" rollback --dry-run)" -[[ "$rollback_dry_out" == *"Would restore"* ]] -printf '%s\n' 'mutated after backup' > "$upgrade_config/agents/OpenZeus.md" -rollback_apply_out="$(OPENCODE_CONFIG_DIR="$upgrade_config" "$root/bin/openzeus" rollback --apply)" -[[ "$rollback_apply_out" == *"restored"* ]] -assert_file_contains "$upgrade_config/agents/OpenZeus.md" 'changed' - -status_out="$(OPENCODE_CONFIG_DIR="$config" "$root/bin/openzeus" status)" -[[ "$status_out" == *"Package root:"* && "$status_out" == *"OpenZeus agent:"* ]] - -clean_config="$tmp/clean-config" -OPENCODE_CONFIG_DIR="$clean_config" "$root/scripts/install.sh" >/dev/null -sync_clean_out="$(OPENCODE_CONFIG_DIR="$clean_config" "$root/bin/openzeus" status)" -[[ "$sync_clean_out" == *"Sync drift: clean"* ]] - -empty_config="$tmp/empty-config" -mkdir -p "$empty_config" -sync_missing_out="$(OPENCODE_CONFIG_DIR="$empty_config" "$root/bin/openzeus" status)" -[[ "$sync_missing_out" == *"Sync drift:"* && "$sync_missing_out" != *"clean"* ]] - -printf '%s\n' 'drift' >> "$config/agents/OpenZeus.md" -sync_drift_out="$(OPENCODE_CONFIG_DIR="$config" "$root/bin/openzeus" status)" -[[ "$sync_drift_out" == *"Sync drift:"* && "$sync_drift_out" != *"clean"* && "$sync_drift_out" == *"Next:"* ]] - -list_out="$(OPENCODE_CONFIG_DIR="$config" "$root/bin/openzeus" list all)" -[[ "$list_out" == *"agents/OpenZeus.md"* && "$list_out" == *"zeus-git-commit.md"* ]] +validation_fail=0 +"$root/bin/openzeus" validate --project "$bad_project" --ci >/dev/null || validation_fail=$? +[[ "$validation_fail" -eq 1 ]] -skills_list_out="$(OPENCODE_CONFIG_DIR="$config" "$root/bin/openzeus" list skills)" -[[ "$skills_list_out" == *"skill: zeus-core"* && "$skills_list_out" != *"command:"* && "$skills_list_out" != *"agent:"* ]] -commands_list_out="$(OPENCODE_CONFIG_DIR="$config" "$root/bin/openzeus" list commands)" -[[ "$commands_list_out" == *"command: zeus-git-commit.md"* && "$commands_list_out" != *"skill:"* && "$commands_list_out" != *"agent:"* ]] -agents_list_out="$(OPENCODE_CONFIG_DIR="$config" "$root/bin/openzeus" list agents)" -[[ "$agents_list_out" == *"agent: agents/OpenZeus.md"* && "$agents_list_out" != *"skill:"* && "$agents_list_out" != *"command:"* ]] +inspect_config="$tmp/inspect-config" +inspect_project="$tmp/inspect-project" +mkdir -p "$inspect_config/agents" "$inspect_config/skills/shared" "$inspect_project/.opencode/skills/shared" "$inspect_project/.opencode/commands" +git init -q "$inspect_project" -different_skill_dir="$tmp/diff-skill" -mkdir -p "$different_skill_dir" -cp -R "$root/skills/zeus-core" "$different_skill_dir/zeus-core" -printf '%s\n' 'extra' > "$different_skill_dir/zeus-core/extra.md" -mkdir -p "$config/skills" -cp -R "$different_skill_dir/zeus-core" "$config/skills/" -skill_diff_list="$(OPENCODE_CONFIG_DIR="$config" "$root/bin/openzeus" list skills)" -[[ "$skill_diff_list" == *"skill: zeus-core [different]"* ]] - -examples_out="$("$root/bin/openzeus" examples)" -[[ "$examples_out" == *"openzeus init-project"* && "$examples_out" == *"openzeus doctor --fix-plan"* && "$examples_out" == *"@OpenZeus audit"* ]] - -project_dir="$tmp/project" -mkdir -p "$project_dir" -"$root/bin/openzeus" init-project --target "$project_dir" >/dev/null -[[ -f "$project_dir/.opencode/agents/project-guide.md" ]] -[[ -f "$project_dir/.opencode/commands/test.md" ]] -[[ -f "$project_dir/.opencode/commands/build.md" ]] -[[ -f "$project_dir/.opencode/skills/project-context/SKILL.md" ]] -[[ -f "$project_dir/.opencode/README.md" ]] -assert_file_contains "$project_dir/.opencode/agents/project-guide.md" 'mode: subagent' -assert_file_contains "$project_dir/.opencode/commands/test.md" '$ARGUMENTS' -assert_file_contains "$project_dir/.opencode/commands/test.md" 'No obvious test command' -assert_file_contains "$project_dir/.opencode/commands/build.md" 'No obvious build command' -assert_file_contains "$project_dir/.opencode/skills/project-context/SKILL.md" 'Type: generic' - -printf '%s\n' 'keep' > "$project_dir/.opencode/README.md" -"$root/bin/openzeus" init-project --target "$project_dir" >/dev/null -assert_file_contains "$project_dir/.opencode/README.md" 'keep' -"$root/bin/openzeus" init-project --force --target "$project_dir" >/dev/null -assert_file_contains "$project_dir/.opencode/README.md" 'Starter' - -npm_project="$tmp/npm-project" -mkdir -p "$npm_project" -cat > "$npm_project/package.json" <<'EOF' -{ - "name": "npm-project", - "scripts": { - "test": "echo npm test", - "build": "echo npm build" - } -} +cat > "$inspect_config/agents/legacy.md" <<'EOF' +--- +description: legacy +mode: subagent +permission: + bash: ask +--- EOF -(cd "$npm_project" && "$root/bin/openzeus" init-project >/dev/null) -assert_file_contains "$npm_project/.opencode/commands/test.md" 'npm test' -assert_file_contains "$npm_project/.opencode/commands/build.md" 'npm run build' -assert_file_contains "$npm_project/.opencode/skills/project-context/SKILL.md" 'Type: npm' - -make_project="$tmp/make-project" -mkdir -p "$make_project" -cat > "$make_project/Makefile" <<'EOF' -test: deps - @echo make test - -build: assets - @echo make build +cat > "$inspect_config/skills/shared/SKILL.md" <<'EOF' +--- +name: Shared +description: Global shared skill. +--- +EOF +cat > "$inspect_project/.opencode/skills/shared/SKILL.md" <<'EOF' +--- +name: Shared +description: Project shared skill. +--- +EOF +cat > "$inspect_project/.opencode/commands/legacy-command.md" <<'EOF' +--- +description: legacy command +subtask: true +--- EOF -(cd "$make_project" && "$root/bin/openzeus" init-project >/dev/null) -assert_file_contains "$make_project/.opencode/commands/test.md" 'make test' -assert_file_contains "$make_project/.opencode/commands/build.md" 'make build' -assert_file_contains "$make_project/.opencode/skills/project-context/SKILL.md" 'Type: make' - -python_project="$tmp/python-project" -mkdir -p "$python_project" -touch "$python_project/pyproject.toml" -(cd "$python_project" && "$root/bin/openzeus" init-project >/dev/null) -assert_file_contains "$python_project/.opencode/commands/test.md" 'pytest' -assert_file_contains "$python_project/.opencode/commands/build.md" 'No obvious build command' -assert_file_contains "$python_project/.opencode/skills/project-context/SKILL.md" 'Type: python' - -printf '%s\n' 'keep command' > "$python_project/.opencode/commands/test.md" -(cd "$python_project" && "$root/bin/openzeus" init-project >/dev/null) -assert_file_contains "$python_project/.opencode/commands/test.md" 'keep command' -(cd "$python_project" && "$root/bin/openzeus" init-project --force >/dev/null) -assert_file_contains "$python_project/.opencode/commands/test.md" 'pytest' - -dry_run_project="$tmp/dry-run-project" -mkdir -p "$dry_run_project" -(cd "$dry_run_project" && "$root/bin/openzeus" init-project --dry-run >/dev/null) -[[ ! -e "$dry_run_project/.opencode" ]] - -missing_config="$tmp/missing-config" -fix_plan_out="$(OPENCODE_CONFIG_DIR="$missing_config" "$root/bin/openzeus" doctor --fix-plan)" -[[ "$fix_plan_out" == *"Suggested commands:"* && "$fix_plan_out" == *"openzeus install"* ]] -[[ "$fix_plan_out" != *"chmod +x scripts/init-project.sh"* ]] - -empty_existing_config="$tmp/existing-empty-config" -mkdir -p "$empty_existing_config" -empty_fix_plan_out="$(OPENCODE_CONFIG_DIR="$empty_existing_config" "$root/bin/openzeus" doctor --fix-plan)" -[[ "$empty_fix_plan_out" == *"OpenZeus doctor: warnings"* && "$empty_fix_plan_out" == *"openzeus install"* ]] -mkdir -p "$tmp/bin" -ln -s "$root/bin/openzeus" "$tmp/bin/openzeus" -"$tmp/bin/openzeus" help >/dev/null -"$tmp/bin/openzeus" doctor >/dev/null +test_node="${OPENZEUS_NODE:-${npm_node_execpath:-}}" +[[ -n "$test_node" ]] || test_node="$(command -v node)" + +inspect_json="$tmp/inspect.json" +OPENCODE_CONFIG_DIR="$inspect_config" "$root/bin/openzeus" inspect --target "$inspect_project" --json > "$inspect_json" +"$test_node" -e ' +const fs = require("fs"); +const d = JSON.parse(fs.readFileSync(process.argv[1], "utf8")); +if (d.mode !== "filesystem") process.exit(1); +const collision = d.collisions.find(x => x.type === "skill" && x.id === "shared"); +if (!collision || !collision.winner.source.startsWith("project-opencode:")) process.exit(2); +if (!d.warnings.some(x => x.code === "legacy_agent_permission")) process.exit(3); +if (!d.warnings.some(x => x.code === "legacy_command_subtask")) process.exit(4); +' "$inspect_json" + +audit_json="$tmp/audit.json" +OPENCODE_CONFIG_DIR="$inspect_config" "$root/bin/openzeus" audit --target "$inspect_project" --json > "$audit_json" +"$test_node" -e ' +const fs = require("fs"); +const d = JSON.parse(fs.readFileSync(process.argv[1], "utf8")); +if (d.status !== "warning") process.exit(1); +if (d.summary.warnings < 2) process.exit(2); +' "$audit_json" + +audit_ci=0 +OPENCODE_CONFIG_DIR="$inspect_config" "$root/bin/openzeus" audit --target "$inspect_project" --ci >/dev/null || audit_ci=$? +[[ "$audit_ci" -eq 1 ]] + +migrate_json="$tmp/migrate.json" +OPENCODE_CONFIG_DIR="$inspect_config" "$root/bin/openzeus" migrate --plan --target "$inspect_project" --json > "$migrate_json" +"$test_node" -e ' +const fs = require("fs"); +const d = JSON.parse(fs.readFileSync(process.argv[1], "utf8")); +if (d.mode !== "plan" || d.mutatesFiles !== false) process.exit(1); +if (!d.actions.some(x => x.id === "agent-permissions-v2")) process.exit(2); +if (!d.actions.some(x => x.id === "command-subagent-v2")) process.exit(3); +if (!d.actions.every(x => x.automatic === false)) process.exit(4); +' "$migrate_json" + +migrate_apply=0 +OPENCODE_CONFIG_DIR="$inspect_config" "$root/bin/openzeus" migrate --apply --target "$inspect_project" >/dev/null 2>&1 || migrate_apply=$? +[[ "$migrate_apply" -eq 2 ]] + +clean_project="$tmp/clean-project" +mkdir -p "$clean_project" +OPENCODE_CONFIG_DIR="$tmp/clean-config" "$root/bin/openzeus" audit --target "$clean_project" --ci >/dev/null echo ok