@markstanden/opencode-docs-plugin 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CONVENTION.md ADDED
@@ -0,0 +1,60 @@
1
+ # Knowledge-doc convention
2
+
3
+ This plugin owns this convention: it is what the `docs` tool's `add` writes,
4
+ what `check` validates, and what the registered `docs` skill teaches. A
5
+ repository that adopts the plugin takes the convention with it.
6
+
7
+ ## Where knowledge lives
8
+
9
+ Durable knowledge is one Markdown file per topic under the docs root, grouped by
10
+ area: `<area>/<name>.md` (the root is the plugin's `root` option; default
11
+ `<location>/docs`). The excluded areas — never scanned, never validated —
12
+ are `plans/` (scratch, gitignored, deleted when the work lands),
13
+ `requirements/` and `wiki/` (vendored mirrors).
14
+
15
+ ## Front-matter
16
+
17
+ Every doc opens with a `---` front-matter block. The fields, in canonical order:
18
+
19
+ | Field | Required | Meaning |
20
+ | ------------ | -------- | ----------------------------------------------------------------------- |
21
+ | `Area` | yes | One top-level path segment; the doc's group. |
22
+ | `Keywords` | yes | Comma-separated search terms; the second half of the doc's identity. |
23
+ | `Summary` | yes | One self-contained sentence: enough to decide whether to open the file. |
24
+ | `Status` | no | `active` (the default) or `superseded`. |
25
+ | `Supersedes` | no | The doc this one replaces. |
26
+
27
+ `Date` is **derived, never written**: the file's last git commit date, falling
28
+ back to mtime. A hand-maintained `Date` is a finding, not a field.
29
+
30
+ The tool serialises the front-matter — never copy it by hand.
31
+
32
+ ## Body
33
+
34
+ - An `H1` title: the first half of the doc's identity.
35
+ - At least one claim section as an `H2`/`H3` heading — `Facts`, `Inferred`,
36
+ `Tested`, `Open questions` — so a reader knows how much to rely on each claim.
37
+ Group claims by section rather than mixing them.
38
+
39
+ ## Identity and duplicates
40
+
41
+ - A doc's identity is its `H1` plus its `Keywords`, and it must carry a term of
42
+ at least `MIN_TERM_LENGTH` (3) characters. A shorter identity is too weak to
43
+ search and is rejected.
44
+ - `check` flags **near-twins**: docs in the same area whose identities overlap.
45
+ `add` refuses a near-twin write and returns the candidates to reconcile
46
+ against — edit before add, merge near-twins, split a bloated doc into
47
+ per-topic files.
48
+
49
+ ## Lifecycle
50
+
51
+ `Status` and `Supersedes` are load-bearing, not decoration. A doc marked
52
+ `Status: superseded` is flagged `(superseded)` in search results and ranks below
53
+ an active doc on a tie; `check` flags a `Supersedes` that names no doc in the
54
+ tree.
55
+
56
+ ## Adopting it
57
+
58
+ Run `check` to audit an existing tree, and the gate's `defined comply` before
59
+ proposing a commit. A missing docs root is not an error: the plugin scans
60
+ what is there and reports per-doc findings for what is not.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mark Standen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,42 @@
1
- # Temporary Holding Version
1
+ # opencode-docs-plugin
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ An [OpenCode](https://opencode.ai) V2 plugin that gives an agent a knowledge
4
+ tree it can actually use: a `docs` tool and a `/docs` command over the
5
+ configured docs root's `*.md` files (the `root` plugin option; default
6
+ `<location>/docs`), plus the writing convention those docs follow.
7
+
8
+ - `docs` (tool) — blank search lists the 10 most recently changed docs
9
+ (`path — Area — date — Summary`); a search ranks docs over their
10
+ front-matter, path and body identifiers, falling back to the closest
11
+ matches rather than a dead end; `add` writes knowledge through a typed DTO;
12
+ `check` validates the tree against the convention.
13
+ - `/docs` (command) — the same core, driven from the prompt:
14
+ `search <text>` (bare text searches too), `add <text>`, `check`, `help`.
15
+ - The plugin also registers the `docs` skill, so the convention travels with
16
+ the tool rather than living in always-loaded prose.
17
+
18
+ Reading a matched doc stays OpenCode's built-in `read`.
19
+
20
+ ## Status
21
+
22
+ Standalone extract of the docs tooling, under active development.
23
+
24
+ ## Development
25
+
26
+ ```bash
27
+ npm install
28
+ npm test # node --test
29
+ npm run typecheck
30
+ defined comply # the gate: bootstrap, repair and verify
31
+ ```
32
+
33
+ Tests run the plugin source directly under Node's type-stripping (`noEmit`,
34
+ `erasableSyntaxOnly`), so the file OpenCode loads is the file under test.
35
+
36
+ `tests/fixtures/docs-corpus.json` is a hand-authored synthetic corpus the
37
+ ranking harness pins behaviour against — edit it directly. It holds invented
38
+ paths and summaries only; never snapshot a real docs tree into it.
39
+
40
+ ## Licence
41
+
42
+ MIT — see [LICENSE](LICENSE).
package/package.json CHANGED
@@ -1,6 +1,37 @@
1
1
  {
2
- "name": "@markstanden/opencode-docs-plugin",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@markstanden/opencode-docs-plugin",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "description": "OpenCode V2 plugin: a `docs` tool and `/docs` command over a repository's knowledge tree, with the writing convention it owns",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/markstanden/opencode-docs-plugin.git"
9
+ },
10
+ "exports": {
11
+ ".": "./src/index.ts"
12
+ },
13
+ "files": [
14
+ "src",
15
+ "CONVENTION.md",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "engines": {
20
+ "node": ">=26"
21
+ },
22
+ "scripts": {
23
+ "test": "node --test 'tests/**/*.test.ts'",
24
+ "test:watch": "node --test --watch 'tests/**/*.test.ts'",
25
+ "typecheck": "tsc --noEmit"
26
+ },
27
+ "dependencies": {
28
+ "@opencode/plugin": "2.0.23",
29
+ "@opencode/schema": "2.0.23",
30
+ "effect": "4.0.0-rc.112"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^26.6.4",
34
+ "typescript": "^6.0.3"
35
+ },
36
+ "license": "MIT"
37
+ }
package/src/SKILL.md ADDED
@@ -0,0 +1,87 @@
1
+ # Docs
2
+
3
+ Durable knowledge lives under the configured docs root (the plugin's `root`
4
+ option; default `<location>/docs`). This skill covers both
5
+ halves of the loop: **find** (discover with the `docs` tool, read the match) and
6
+ **record** (write or update a doc for the current task).
7
+
8
+ Call the `docs` tool directly at top level. It is a plugin-registered tool and
9
+ is **not** reachable from the `execute` (Code Mode) catalog — do not try to
10
+ batch it inside `execute`, and do not be misled by the unknown-tool suggestion.
11
+
12
+ ## Find it
13
+
14
+ Call the `docs` tool:
15
+
16
+ - **blank `search`** — the most recently changed docs, one line per doc
17
+ (`path — Area — date — Summary`).
18
+ - **a `search`** — those docs ranked over title, path, keywords, body headings
19
+ and code spans, area and summary. When no doc contains every term it returns
20
+ the closest matches under a `Closest matches` header rather than a dead end.
21
+ A term must appear as a **substring** to match — a typo returns nothing, by
22
+ design. Terms shorter than `MIN_TERM_LENGTH` (3) are ignored unless they are
23
+ the whole query, so filler words cannot drag in the catalogue.
24
+ - **every call** caps at `MAX_RESULTS` (10), preferring the best matches and
25
+ then the most recent edits, and ends with `… and N more not shown.` when
26
+ anything was cut.
27
+ - **exactly `help`** — plain text explaining the weights, the hit qualities and
28
+ the outcomes, instead of a search.
29
+
30
+ Then open the match with the built-in `read` tool. The tool only discovers; it
31
+ never returns a doc's body. `/docs [search]` runs the same search into the
32
+ session (`/docs search <text>` is the explicit form).
33
+
34
+ Every `*.md` under the root is covered except the excluded areas — scratch (`plans/`)
35
+ and vendored mirrors (`requirements/`, `wiki/`). `Area` comes from the path,
36
+ `date` from git. A doc marked `Status: superseded` carries a `(superseded)`
37
+ marker in results and ranks below an active doc on a tie.
38
+
39
+ ## Read it
40
+
41
+ - Consult matching docs before a broad grep: they are the curated knowledge.
42
+ - A `Summary` is a self-contained sentence — enough to decide whether to open
43
+ the file.
44
+
45
+ ## Record it
46
+
47
+ Write durable findings and task documentation to `<area>/<title>.md` under the
48
+ root so the
49
+ next human or agent skips the rediscovery. The convention is this plugin's
50
+ `CONVENTION.md`, restated here.
51
+
52
+ Before writing:
53
+
54
+ 1. **Read first, never duplicate.** List the tree with the `docs` tool and read
55
+ the docs relevant to the task: the same `<area>/` neighbourhood, keyword
56
+ hits on the task's entities (service names, file paths, error strings, class
57
+ names), or links from touched docs.
58
+ 2. **Reconcile, then add.** Edit before add; merge near-twins; split a bloated
59
+ doc into per-topic files; after any split, merge or move, grep for inbound
60
+ references and repoint them, leaving a stub if needed.
61
+
62
+ Then record through the `docs` tool's typed `add`: metadata (`Area`, `Keywords`
63
+ as a list, `Summary`; optionally `Status`/`Supersedes`) plus a body carrying an
64
+ `H1` and the claim sections (`Facts`, `Inferred`, `Tested`, `Open questions`).
65
+ The tool serialises the front-matter — never copy it — and derives
66
+ the target (`<Area>/<slug>.md`) when `path` is omitted; pass `path` to
67
+ update an existing doc, replacing its body wholesale. Its guardrails refuse
68
+ blank metadata, path traversal, a body without an `H1`, and a same-area
69
+ near-twin (returning the candidates to reconcile against). A plan for an
70
+ in-flight effort is scratch, not a doc — a `plans/` area, excluded from the
71
+ index and deleted when the work lands. `/docs add <text>` runs this record
72
+ loop for a fact supplied inline.
73
+
74
+ ## Check it
75
+
76
+ To audit the tree instead of writing it, call the tool's `check` (`/docs check`
77
+ runs it into the session): it validates every doc against the convention —
78
+ required front-matter, an `H1`, at least one claim section, no hand-maintained
79
+ `Date`, an `H1`+`Keywords` identity with a term of `MIN_TERM_LENGTH` (3) or
80
+ longer, a `Supersedes` naming a doc in the tree, and same-area near-twins — and
81
+ reports findings per doc. An empty report means compliant. `add` enforces the
82
+ same rules at the trust boundary.
83
+
84
+ Finally, run the repo's gate (`defined comply` where `.defined.json` exists,
85
+ else what its README documents) before proposing a commit. Fix failures; never
86
+ paper over a red gate with a docs commit. Prepare the commit and **wait for
87
+ explicit approval** — recording findings is not commit approval. Never push.