Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
@@ -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
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## Summary

## Checks

- [ ] `npm run check` and `npm test` (or CI green)
- [ ] Docs/examples updated if options or behavior changed
79 changes: 43 additions & 36 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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.
123 changes: 55 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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/<name>/SKILL.md`; general user workflows go in
`~/.config/opencode/skills/<name>/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/<name>/SKILL.md`
- **Global skills** (how you work across projects): `~/.config/opencode/skills/<name>/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
{
Expand All @@ -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).
22 changes: 19 additions & 3 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -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.
Loading