From 7cf0363937fca445532bd68046c393208bab1dc5 Mon Sep 17 00:00:00 2001 From: fastsoab Date: Fri, 11 Sep 2026 07:01:37 +0200 Subject: [PATCH] Reshape docs for an open-source OpenCode plugin Lead with install-from-source, plugin id, and user-facing behavior. Move contributor and hook detail out of the README; add issue and PR templates. --- .github/ISSUE_TEMPLATE/bug.yml | 39 ++++++++ .github/ISSUE_TEMPLATE/config.yml | 8 ++ .github/pull_request_template.md | 6 ++ CONTRIBUTING.md | 79 +++++++++-------- README.md | 123 ++++++++++++-------------- SECURITY.md | 22 ++++- docs/installation.md | 142 +++++++++++++++--------------- docs/research.md | 4 + 8 files changed, 246 insertions(+), 177 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/pull_request_template.md diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 0000000..407057d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,39 @@ +name: Bug report +description: Something is wrong with loading, hooks, or documented behavior +title: "[Bug] " +labels: [] +body: + - type: markdown + attributes: + value: Do not paste secrets, API keys, full `opencode debug config` output, or private session exports. + - type: input + id: opencode + attributes: + label: OpenCode version + placeholder: "1.18.30" + validations: + required: true + - type: input + id: model + attributes: + label: Model (if relevant) + placeholder: "opencode/big-pickle" + - type: textarea + id: expected + attributes: + label: Expected + validations: + required: true + - type: textarea + id: actual + attributes: + label: Actual + validations: + required: true + - type: textarea + id: repro + attributes: + label: Sanitized reproduction + description: Minimal steps. Redact credentials and private paths. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..8f99d30 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: true +contact_links: + - name: Report a vulnerability + url: https://github.com/Neverdecel/OpenSkillGen/security/advisories/new + about: Private security reports only — do not file public issues for exploits or secrets + - name: OpenCode plugin docs + url: https://opencode.ai/docs/plugins/ + about: Official documentation for loading and writing plugins diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..ca93f68 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,6 @@ +## Summary + +## Checks + +- [ ] `npm run check` and `npm test` (or CI green) +- [ ] Docs/examples updated if options or behavior changed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 582c362..7dcd41f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,28 +1,43 @@ # Contributing -Keep this capability small: agent guidance, human approval, native skills. -Read [AGENTS.md](AGENTS.md) and [the API research](docs/research.md) before changing -the runtime. Avoid adding independent persistence, autonomous writes, or cleanup -infrastructure. +Keep the capability small: agent guidance, human approval, native skills. +Read [AGENTS.md](AGENTS.md) and [docs/research.md](docs/research.md) before +changing the runtime. Do not add independent persistence, autonomous writes, +or cleanup infrastructure. -## Local checks +## Development setup -Requires Node.js 24+ and npm: +Requires Node.js 24+ and npm. OpenCode 1.18.30 is required for live CLI tests. ```sh +git clone https://github.com/Neverdecel/OpenSkillGen.git +cd OpenSkillGen npm ci npm run check npm test ``` -GitHub Actions runs these deterministic checks. They verify hook registration, -context isolation between calls, options, and the example format; they do not +GitHub Actions runs the same deterministic checks. They cover hook +registration, isolation, options, and bundled skill format. They do **not** certify model consent or secret detection. -## Actual CLI and model checks +## Pull requests -On Linux, install Docker and the native OpenCode binary, then run from the -checkout root: +1. Branch from `main`. Direct pushes, force-pushes, and deleting `main` are + blocked. +2. Keep the change focused. Update docs and examples with options or behavior. +3. Inspect pinned `@opencode-ai/plugin` and SDK types before changing hooks. +4. Open a PR targeting `main`. The `check` CI job must pass. +5. Squash or rebase merge only (linear history). + +Ship product skills under `skills/` and load them via `skills.paths`. Keep +examples outside auto-discovery directories. Do not copy product skills into +another project’s `.opencode/skills/` in docs or tests unless the point is a +fork. + +## Live CLI and model checks + +Linux, Docker, and a native OpenCode binary. From the checkout root: ```sh # Actual OpenCode system request and persisted-session isolation; fake provider. @@ -31,32 +46,24 @@ EVAL_SCRIPT=context sh test/live.sh # Real model, native file tools, disposable skill libraries. sh test/live.sh -# Target one scenario or another credential-free model. EVAL_CASE=4 sh test/live.sh EVAL_MODEL=opencode/mimo-v2.5-free EVAL_CASE=4 sh test/live.sh ``` -The scripts mount the checkout and installed CLI read-only in a disposable -container. They do not mount a real home or credentials. The default live model -is `opencode/big-pickle`; availability depends on the provider. The noninteractive -runner uses text replies and disables the `question` tool. Model tests are -opt-in, not GitHub CI jobs. - -Review tool traces and generated prose as well as exit status. Live cases that -must not persist now fail on attempted skill/config writes, including blocked -tool calls. Keyword assertions are only smoke checks. Use [SCENARIOS.md](test/SCENARIOS.md) for the complete acceptance -criteria and additional manual regressions. Record failures honestly, including -intermittent failures; a successful rerun does not erase them. - -## Changes and issues - -- Inspect pinned `@opencode-ai/plugin` and SDK types before changing hooks. -- Update documentation and examples together with options or behavior changes. -- Keep example skills outside auto-discovery directories. Ship product skills - under `skills/`; users load them via `skills.paths`, not by copying into - another project's `.opencode/skills/` unless they want a fork. -- Submit focused pull requests targeting `main`. Direct pushes, force-pushes, - and deleting `main` are blocked. The `check` CI job must pass before merge. -- Include OpenCode/model versions and a minimal, sanitized reproduction in bug - reports. Do not upload configuration secrets, real credentials, or private - session exports. +The scripts mount the checkout and CLI read-only in a disposable container. +They do not mount a real home or credentials. Default live model: +`opencode/big-pickle` (provider-dependent). The noninteractive runner uses +text replies and disables the `question` tool. These tests are opt-in, not CI. + +Review tool traces and generated prose, not only exit status. No-write cases +fail on attempted skill/config writes, including blocked tool calls. Keyword +checks are smoke only. Acceptance criteria: +[test/SCENARIOS.md](test/SCENARIOS.md). Record intermittent failures; a later +pass does not erase them. Never run evaluation writes against a real skill +library. + +## Issues + +Include OpenCode and model versions and a minimal, sanitized reproduction. +Do not upload configuration secrets, credentials, or private session exports. +Security reports go through [SECURITY.md](SECURITY.md), not public issues. diff --git a/README.md b/README.md index 99a8617..84f57fa 100644 --- a/README.md +++ b/README.md @@ -5,42 +5,28 @@ **Agent notices. Human decides. OpenCode remembers.** -A lightweight [OpenCode plugin](https://opencode.ai/docs/plugins/) for user-guided -learning. During normal work, it nudges the agent to notice exceptionally useful, -durable procedures and ask whether to save them as native skills. +An [OpenCode](https://opencode.ai) [plugin](https://opencode.ai/docs/plugins/) that notices durable, reusable procedures during normal work and asks before saving them as native [skills](https://opencode.ai/docs/skills/). -> This looks reusable: review the saved Terraform plan with the on-call owner, -> then apply only that artifact. Save as `terraform-deploy-review` (project skill)? +It is not a memory store, skill database, or write sandbox. After you approve, saves use OpenCode’s existing file tools and [permissions](https://opencode.ai/docs/permissions/). -Reply naturally: **yes**, **no**, **make it global**, **rename it**, **add X**, or -**merge with Y**. Ordinary work should produce no suggestion. Task completion -comes first. +> This looks reusable: review the saved Terraform plan with the on-call owner, then apply only that artifact. Save as `terraform-deploy-review` (project skill)? -## Install +Reply **yes**, **no**, **make it global**, **rename it**, **add X**, or **merge with Y**. Ordinary work should produce no suggestion. -Tested with **OpenCode 1.18.30**. The plugin uses an experimental hook; later -versions need compatibility verification. Node.js 24+ and npm are needed for -development checks, not for OpenCode to load the TypeScript source. +## Requirements -Clone the repository to a permanent location: +- [OpenCode](https://opencode.ai) **1.18.30** (tested). The plugin uses experimental hooks; later versions need a compatibility check. +- A git clone of this repository at a stable path. -```sh -git clone https://github.com/Neverdecel/OpenSkillGen.git -``` +**Not published to npm.** Do not add `opencode-guided-learning` as a package name in `plugin`. Load the source file URL instead. -Append its **absolute source-file URL** to `plugin` in -`~/.config/opencode/opencode.json` for all projects, or your project's -`opencode.json` for that project only: +## Install -```json -{ - "$schema": "https://opencode.ai/config.json", - "plugin": ["file:///absolute/path/to/OpenSkillGen/src/index.ts"] -} +```sh +git clone https://github.com/Neverdecel/OpenSkillGen.git ``` -To invoke **skill-mining** and **skill-curation**, also add the checkout's -`skills` directory: +Add the **absolute** source-file URL to `plugin` in `~/.config/opencode/opencode.json` (all projects) or the project’s `opencode.json`: ```json { @@ -50,32 +36,34 @@ To invoke **skill-mining** and **skill-curation**, also add the checkout's } ``` -Replace the example paths and preserve existing config entries. OpenCode loads -the plugin file directly: **no build or npm publication is required**. Keep the -checkout at those paths. **Quit and restart OpenCode** (including its backend -when using OpenChamber). See [installation and troubleshooting](docs/installation.md). - -## Behavior - -- **Conservative:** confirmed workflows, meaningful corrections, team procedures, - and proven troubleshooting. Skip generic advice, temporary state, and guesses. -- **Existing skills first:** load relevant native skills; prefer updating them - over creating duplicates. Suggest cleanup only when overlap or conflicts arise - during actual work. Changes and deletions require explicit approval. -- **Two scopes:** project/team knowledge goes in - `.opencode/skills//SKILL.md`; general user workflows go in - `~/.config/opencode/skills//SKILL.md`. You can override the proposed scope. -- **Concise skills:** reusable rules and verification, not transcripts or secrets. - See the [example generated skill](examples/terraform-plan-review/SKILL.md). -- **On demand:** invoke `skill-mining` to extract candidates from the current - work, or `skill-curation` to review the existing library for merges, edits, or - deletions. Neither is a write permission. See - [skills/skill-mining/SKILL.md](skills/skill-mining/SKILL.md) and - [skills/skill-curation/SKILL.md](skills/skill-curation/SKILL.md). +`skills.paths` is optional; it enables the bundled `skill-mining` and `skill-curation` skills. Keep existing config entries. **Quit and restart OpenCode** (including its backend when using OpenChamber). + +Windows example: `file:///C:/projects/OpenSkillGen/src/index.ts`. + +Confirm with `opencode debug config` (the resolved plugin list should include the file URL). Do not paste that output into issues; it can contain secrets. Full steps and troubleshooting: [docs/installation.md](docs/installation.md). + +## Usage + +| You | Plugin | +| --- | --- | +| Ordinary work | No extra chatter | +| Confirm a durable team or personal procedure | Short save proposal at a stopping point | +| Approve, reject, rename, or merge | Writes only after that reply | +| Ask to mine or curate skills | Uses bundled skills if `skills.paths` is set | + +- **Project skills** (this repository only): `.opencode/skills//SKILL.md` +- **Global skills** (how you work across projects): `~/.config/opencode/skills//SKILL.md` + +Example of a saved skill: [examples/terraform-plan-review/SKILL.md](examples/terraform-plan-review/SKILL.md). Bundled skills are not copied into other projects unless you want a fork. ## Configuration -Both options are optional; the default is enabled and conservative. +Both options are optional. Defaults: enabled, conservative, no ignored topics. + +| Option | Type | Meaning | +| --- | --- | --- | +| `enabled` | boolean | `false` registers no hooks | +| `ignoredTopics` | nonempty strings | Labels or skill names to never suggest (not regexes) | ```json { @@ -87,37 +75,36 @@ Both options are optional; the default is enabled and conservative. } ``` -Ignored topics are natural-language labels or skill names, not regexes. “Never -suggest this kind again” authorizes saving that preference in these options. -Restart after config changes or skill writes to refresh discovery. +“Never suggest this kind again” may record that label in `ignoredTopics` of the existing config. Restart after config changes or skill writes. + +## Limits -## Architecture and limits +The runtime is one file: it appends guidance and a compaction note. No extra model calls, background work, or separate memory. -One source file appends guidance through `experimental.chat.system.transform` -and a short note through `experimental.session.compacting`. It skips 1.18.30 -hidden/read-only built-in system prompts (compaction, title, summary, explore) -because that hook has no agent id. It uses native skill discovery and editing -tools. No additional model calls, background work, skill database, write -interceptor, or automatic pruning. +**Consent and secret exclusion are model instructions, not a filesystem guard.** Hook tests do not prove model compliance. Live evaluations have shown inconsistent scope, verbosity, and skill quality, and an earlier unapproved write with weaker wording. See [test/RESULTS.md](test/RESULTS.md). -**Consent and secret exclusion are model instructions, not a filesystem security -boundary.** Existing OpenCode permissions still apply. Live evaluations have -shown inconsistent scope, verbosity, and skill quality, plus an earlier -unapproved write with weaker wording. Read the [verification record](test/RESULTS.md); -passing hook tests does not prove model compliance. +## Repository + +| Path | Role | +| --- | --- | +| [`src/index.ts`](src/index.ts) | Plugin (`id`: `opencode-guided-learning`) | +| [`skills/`](skills/) | Opt-in mining and curation skills | +| [`examples/`](examples/) | Sample generated skill (not auto-discovered) | +| [`test/`](test/) | Hook tests and isolated live eval | +| [`docs/`](docs/installation.md) | Install, troubleshooting, hook research | ## Contributing +PRs target `main`. The `check` CI job must pass. + ```sh npm ci npm run check npm test ``` -See [CONTRIBUTING.md](CONTRIBUTING.md) for isolated CLI/model tests and -[research notes](docs/research.md) for the V1/V2 API decision. Changes to -`main` go through pull requests; the `check` workflow must pass. +Node.js 24+ is for development checks only; OpenCode loads the TypeScript source directly. See [CONTRIBUTING.md](CONTRIBUTING.md), [AGENTS.md](AGENTS.md), and [docs/research.md](docs/research.md). ## License -[MIT](LICENSE). See [SECURITY.md](SECURITY.md) to report a vulnerability. +[MIT](LICENSE). Vulnerability reports: [SECURITY.md](SECURITY.md). diff --git a/SECURITY.md b/SECURITY.md index c455d2e..64d5f52 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,7 +1,23 @@ # Security -Report vulnerabilities privately through GitHub: **Security → Report a vulnerability** on [Neverdecel/OpenSkillGen](https://github.com/Neverdecel/OpenSkillGen/security/advisories/new). +Report vulnerabilities privately: **Security → Report a vulnerability** on +[Neverdecel/OpenSkillGen](https://github.com/Neverdecel/OpenSkillGen/security/advisories/new). -Do not open a public issue or pull request with exploit details, secrets, or credentials. +Do not open a public issue or pull request with exploit details, secrets, or +credentials. -This plugin injects instructions; it is not a filesystem sandbox. Skill writes still use OpenCode's normal tools and permissions. Do not treat conversational approval as a security boundary. +## Scope + +This plugin injects instructions. It is **not** a filesystem sandbox. Skill +writes use OpenCode’s normal tools and permissions. Conversational approval is +not a security boundary. + +In scope: unexpected code execution from this repository, secret leakage in +shipped examples or docs, install paths that load unintended code. + +Out of scope: a model ignoring consent, writing a low-quality skill, or +following a user request to store secrets — those are instruction-following +failures. Disable the plugin and use OpenCode permissions if you need a guard. + +Supported: the current `main` branch of this checkout, tested with OpenCode +1.18.30. diff --git a/docs/installation.md b/docs/installation.md index 0da5aa4..86583f6 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,84 +1,86 @@ -# Installation and maintenance - -OpenSkillGen is distributed as a GitHub source checkout. The package/plugin ID -is `opencode-guided-learning`; it has not been published to npm. Do not add that -bare package name to OpenCode's config: use the local source-file URL. - -## Install from source - -1. Check `opencode --version`. Version 1.18.30 was tested against its actual plugin - types and session runtime. The experimental hook may change in future releases. -2. Clone `https://github.com/Neverdecel/OpenSkillGen.git` to a permanent location. -3. Add a `file:///.../OpenSkillGen/src/index.ts` entry to the existing `plugin` - array in the global or project OpenCode config. An absolute file URL avoids - resolving a relative path against the wrong config directory. On Windows, - use a URL such as `file:///C:/projects/OpenSkillGen/src/index.ts`. -4. To use the bundled `skill-mining` and `skill-curation` skills, add the - checkout's `skills` directory to `skills.paths` (absolute path). Do not copy - them into `.opencode/skills/` of other projects unless you want a fork. -5. Quit and restart the OpenCode process. Restart the backend as well when a - frontend such as OpenChamber manages it. - -The source imports only TypeScript types from `@opencode-ai/plugin`. OpenCode's -TypeScript loader handles it directly, so no build or runtime dependency install -is required. `npm ci` installs the pinned SDK types and development tools for -contributors. Package metadata remains `private: true` to prevent accidental npm -publication; this does not affect local plugin loading or GitHub visibility. - -Global config normally lives at `~/.config/opencode/opencode.json` or -`opencode.jsonc`; respect custom config-directory settings. Project config lives -at the repository root or in `.opencode/`. Preserve comments, provider settings, -permissions, and other plugin entries when editing an existing file. - -## Verify installation - -Run `opencode debug config` from the project where you intend to use the plugin. -Confirm the resolved plugin list contains the source-file URL. If you enabled the bundled skills, `opencode debug skill` should list -`skill-mining` and `skill-curation`. This output can -include private configuration; do not paste the complete output into an issue. - -For transport verification, contributors can run the isolated test in -[CONTRIBUTING.md](../CONTRIBUTING.md). That test checks the actual model request, -not merely the presence of a config entry. A lack of learning suggestions during -ordinary work is expected and does not by itself indicate a loading problem. +# Installation and troubleshooting -## Update +OpenSkillGen is a **source checkout**, not an npm package. The plugin id is +`opencode-guided-learning`. Do not put that bare name in OpenCode’s `plugin` +array; use a `file:///` URL to `src/index.ts`. + +Official references: [plugins](https://opencode.ai/docs/plugins/), +[configuration](https://opencode.ai/docs/config/), +[skills](https://opencode.ai/docs/skills/), +[permissions](https://opencode.ai/docs/permissions/). + +## Install -From the plugin checkout, inspect local changes and pull the update: +1. Check `opencode --version`. **1.18.30** was tested against its plugin types + and session runtime. Experimental hooks may change. +2. Clone `https://github.com/Neverdecel/OpenSkillGen.git` to a path you will + keep. Moving the checkout later requires updating the config URL. +3. Add `file:///absolute/path/to/OpenSkillGen/src/index.ts` to the existing + `plugin` array in global or project config. An absolute file URL avoids + resolving against the wrong config directory. Windows: + `file:///C:/projects/OpenSkillGen/src/index.ts`. +4. Optional: add the checkout’s `skills` directory to `skills.paths` (absolute + path) so `skill-mining` and `skill-curation` are invocable. Do not copy them + into another project’s `.opencode/skills/` unless you want a fork. +5. Quit and restart OpenCode. Restart the backend as well when a frontend such + as OpenChamber manages it. + +OpenCode’s TypeScript loader runs `src/index.ts` directly. No build or +`npm install` is required to use the plugin. `npm ci` is for contributors +(pinned SDK types and tests). `package.json` is `private: true` so the package +is not published by accident; that does not affect GitHub or local loading. + +Global config: `~/.config/opencode/opencode.json` or `opencode.jsonc` (honor a +custom config directory). Project config: repository root or `.opencode/`. +Preserve comments, providers, permissions, and other plugin entries. + +## Verify + +From the project where you use the plugin: + +```sh +opencode debug config +``` + +The resolved plugin list should include the source-file URL. With bundled +skills enabled, `opencode debug skill` should list `skill-mining` and +`skill-curation`. That output can include private configuration — do not paste +it into an issue. + +A lack of learning suggestions during ordinary work is expected. Contributors +can run the isolated transport test in [CONTRIBUTING.md](../CONTRIBUTING.md). + +## Update ```sh git status git pull --ff-only ``` -Preserve local edits before updating. Contributors should rerun `npm ci` if the -lockfile changes, then `npm run check` and `npm test`. Restart OpenCode to load the -updated source. For a stable local deployment, keep the checkout at a reviewed -commit instead of following new commits automatically. +Keep local edits; pin a reviewed commit for a stable install. Restart OpenCode +after pulling. Contributors should rerun `npm ci` when the lockfile changes, +then `npm run check` and `npm test`. ## Disable or uninstall -- Temporarily disable: set `enabled: false` in the plugin's options tuple. -- Uninstall: remove its entry from the config where it was added. -- Restart OpenCode after either change. Previously approved skills remain native - skill files; remove or change them only if that is also your intent. +- Disable: `"enabled": false` in the plugin options tuple. +- Uninstall: remove the plugin (and `skills.paths` entry, if added) from the + config where you installed it. +- Restart OpenCode. Previously saved skills remain on disk until you delete + them. ## Troubleshooting -- **Plugin absent from resolved config:** check the config scope, file URL, and - custom config-directory environment settings. -- **File moved or deleted:** update the source-file URL and restart. -- **Config rejected:** check against the [official schema](https://opencode.ai/config.json). - Plugin options belong inside the tuple, not at the config's top level. -- **Changes not reflected:** restart the actual OpenCode backend, not only its UI. -- **Duplicate guidance:** avoid registering the checkout both in `plugin` and as - an auto-discovered `.opencode/plugins/` file. -- **Agent ignores consent or creates poor skills:** this is a model-behavior - failure, not a guaranteed write guard. Disable the plugin if needed and report - a credential-free reproduction with OpenCode/model versions and the relevant - sanitized tool calls. Never test fixes against a real skill library. - -Official references: [plugins](https://opencode.ai/docs/plugins/), -[configuration](https://opencode.ai/docs/config/), -[skills](https://opencode.ai/docs/skills/), and -[permissions](https://opencode.ai/docs/permissions/). +- **Not in resolved config:** check config scope, the `file:///` URL, and + `XDG` / custom config-directory settings. +- **Checkout moved:** update the URL and restart. +- **Schema error:** validate against [https://opencode.ai/config.json](https://opencode.ai/config.json). + Options belong in the plugin tuple, not at the top level of the config. +- **Stale behavior:** restart the OpenCode backend, not only the UI. +- **Duplicate guidance:** do not also drop `src/index.ts` into + `.opencode/plugins/` or `~/.config/opencode/plugins/` while it is listed in + `plugin`. +- **Ignores consent or writes a poor skill:** model behavior, not a write + guard. Disable the plugin if needed. File a credential-free issue with + OpenCode/model versions and sanitized tool calls. Never test against a real + skill library. diff --git a/docs/research.md b/docs/research.md index aa6e98b..2f352dd 100644 --- a/docs/research.md +++ b/docs/research.md @@ -1,5 +1,9 @@ # API and design notes — 2026-09-10 +Maintainer notes for hook and runtime changes. Users installing the plugin can +skip this file; see the [README](../README.md) and +[installation](installation.md) instead. + ## Inspected before implementation - Installed CLI: `opencode --version` → **1.18.30**; npm package metadata agrees.