opencode-plugin-kit 1.0.0-alpha.6 → 1.0.0-alpha.7
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/README.md +59 -2
- package/package.json +5 -4
- package/src/collapsible.tsx +39 -2
- package/src/toast.ts +1 -1
package/README.md
CHANGED
|
@@ -16,6 +16,12 @@ Published on [npm](https://www.npmjs.com/package/opencode-plugin-kit):
|
|
|
16
16
|
npm install opencode-plugin-kit
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
> **Still a prerelease.** `latest` currently resolves to `1.0.0-alpha.6` — the
|
|
20
|
+
> first OpenCode v2 build. The publish workflow tags every prerelease under
|
|
21
|
+
> its own identifier (`alpha`, `beta`, …) and leaves `latest` alone, so later
|
|
22
|
+
> alphas will _not_ move `latest` automatically. To track the newest build,
|
|
23
|
+
> install `opencode-plugin-kit@alpha`.
|
|
24
|
+
|
|
19
25
|
Plugins depending on the kit declare it in `dependencies`; the host peer
|
|
20
26
|
(`@opencode/plugin`) must match your OpenCode v2 runtime version (see each
|
|
21
27
|
plugin's README).
|
|
@@ -189,6 +195,41 @@ const totals = walkMessages(
|
|
|
189
195
|
const { input, output, cost } = sumProviderTokens(context, sessionID, "opencode")
|
|
190
196
|
```
|
|
191
197
|
|
|
198
|
+
### Collapsible
|
|
199
|
+
|
|
200
|
+
Imported from the `collapsible` subpath so the Solid JSX stays out of the main
|
|
201
|
+
entry.
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
import { CollapsibleSection, CollapsibleGroup } from "opencode-plugin-kit/collapsible"
|
|
205
|
+
|
|
206
|
+
// From a host component that already has the plugin context:
|
|
207
|
+
const { theme } = usePlugin()
|
|
208
|
+
|
|
209
|
+
CollapsibleSection({
|
|
210
|
+
title: "Skills",
|
|
211
|
+
count: items.length,
|
|
212
|
+
threshold: 2, // Collapse the body at or below this count
|
|
213
|
+
pinned: <Note />, // Always visible between header and body
|
|
214
|
+
theme, // Header colors; pass the host's theme
|
|
215
|
+
children: <List />,
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
CollapsibleGroup({
|
|
219
|
+
title: "Providers",
|
|
220
|
+
count: ids.length,
|
|
221
|
+
defaultCollapsed: true,
|
|
222
|
+
theme,
|
|
223
|
+
children: (collapsed) => (collapsed() ? <Summary /> : <List />),
|
|
224
|
+
})
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
`theme` is optional but **recommended**. Without it the kit falls back to
|
|
228
|
+
`usePlugin()`, which throws when the kit is installed from `node_modules`
|
|
229
|
+
(it resolves its own copy of `@opencode/plugin` / `solid-js`, so the host's
|
|
230
|
+
plugin context is not visible). If the context is missing the header falls back
|
|
231
|
+
to unthemed text rather than throwing.
|
|
232
|
+
|
|
192
233
|
## Consuming Plugins
|
|
193
234
|
|
|
194
235
|
| Plugin | What it does |
|
|
@@ -198,14 +239,30 @@ const { input, output, cost } = sumProviderTokens(context, sessionID, "opencode"
|
|
|
198
239
|
| [opencode-skill-lister](https://github.com/ranjithrajv/opencode-skill-lister) | Skills list in sidebar |
|
|
199
240
|
| [opencode-plugin-manager](https://github.com/ranjithrajv/opencode-plugin-manager) | Plugin manager in sidebar |
|
|
200
241
|
|
|
201
|
-
|
|
202
|
-
|
|
242
|
+
Install from the registry:
|
|
243
|
+
|
|
244
|
+
```sh
|
|
245
|
+
npm install opencode-plugin-kit@alpha
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The `latest` dist-tag tracks the newest v1 alpha; v2 releases ship under the
|
|
249
|
+
`alpha` dist-tag, so pin `opencode-plugin-kit@alpha` (or an explicit range) until
|
|
250
|
+
`latest` moves to v2.
|
|
251
|
+
|
|
252
|
+
For local development, link the sibling checkout with
|
|
253
|
+
`"opencode-plugin-kit": "file:../opencode-plugin-kit"` in the consumer's
|
|
254
|
+
`package.json`, then `npm install` (or `bun install`). Note that a linked
|
|
255
|
+
checkout shares one module graph with the host, so the collapsible components
|
|
256
|
+
find the plugin context without a `theme` prop; a registry install does not.
|
|
203
257
|
|
|
204
258
|
## Compatibility
|
|
205
259
|
|
|
206
260
|
The OpenCode v2 host plugin API's types are the spec. Kit consumes the context
|
|
207
261
|
structurally — anything the host ships with the expected members satisfies it.
|
|
208
262
|
|
|
263
|
+
- **Floor: `@opencode/plugin` 2.0.3.** Earlier 2.x releases have no `./tui`
|
|
264
|
+
subpath export, so nothing that imports `@opencode/plugin/tui` can resolve it.
|
|
265
|
+
Verified by typecheck and the type-tripwire against 2.0.3, 2.0.10 and 2.0.18.
|
|
209
266
|
- **No runtime dependency** on `@opencode/plugin` — types only
|
|
210
267
|
- **Optional peer** — declared as optional so consumers share one copy
|
|
211
268
|
- **CI tripwire** — `host.test-d.ts` pins published host types against kit's
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-plugin-kit",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.7",
|
|
4
4
|
"description": "Shared building blocks for OpenCode sidebar plugins: provider vocabulary, row formatting, defensive message traversal, connected-provider tracking, polling fetcher, cached resources, and a persisted view/filter picker (registry + slash command + dialog + toast).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"opencode",
|
|
@@ -32,8 +32,9 @@
|
|
|
32
32
|
"fmt": "vp fmt",
|
|
33
33
|
"lint": "vp lint",
|
|
34
34
|
"typecheck": "tsc --noEmit",
|
|
35
|
-
"test
|
|
36
|
-
"test:
|
|
35
|
+
"test": "vp test",
|
|
36
|
+
"test:types": "vp test --typecheck",
|
|
37
|
+
"test:coverage": "vp exec vitest run --coverage"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
40
|
"@opencode/plugin": "2.0.15",
|
|
@@ -53,7 +54,7 @@
|
|
|
53
54
|
"zod": "^4.5.4"
|
|
54
55
|
},
|
|
55
56
|
"peerDependencies": {
|
|
56
|
-
"@opencode/plugin": "^2.0.
|
|
57
|
+
"@opencode/plugin": "^2.0.3",
|
|
57
58
|
"solid-js": "^1.9.12",
|
|
58
59
|
"zod": "^4.5.4"
|
|
59
60
|
},
|
package/src/collapsible.tsx
CHANGED
|
@@ -14,6 +14,39 @@ import { createSignal, Show } from "solid-js"
|
|
|
14
14
|
import type { JSX } from "solid-js"
|
|
15
15
|
import { usePlugin } from "@opencode/plugin/tui"
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Theme tokens a collapsible header needs. Derived from the host theme so
|
|
19
|
+
* callers can pass their `usePlugin().theme` straight through, and so we
|
|
20
|
+
* don't pin the host's color type (e.g. `RGBA`) here.
|
|
21
|
+
*/
|
|
22
|
+
type HostTheme = ReturnType<typeof usePlugin>["theme"]
|
|
23
|
+
export interface CollapsibleTheme {
|
|
24
|
+
text: {
|
|
25
|
+
base?: HostTheme["text"]["base"]
|
|
26
|
+
muted?: HostTheme["text"]["muted"]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Resolve the theme for a header.
|
|
32
|
+
*
|
|
33
|
+
* Prefer an explicitly passed `theme`. When this package is consumed from
|
|
34
|
+
* `node_modules`, `usePlugin()` here resolves a different copy of
|
|
35
|
+
* `@opencode/plugin` (and `solid-js`) than the host renders with, so the
|
|
36
|
+
* host's plugin context is not visible and `usePlugin()` throws
|
|
37
|
+
* "PluginContextProvider is missing". Callers that already hold the host
|
|
38
|
+
* context pass `theme` down; the `usePlugin()` fallback keeps working for
|
|
39
|
+
* consumers whose module graph is deduped (tests, monorepos).
|
|
40
|
+
*/
|
|
41
|
+
function resolveTheme(explicit?: CollapsibleTheme): CollapsibleTheme {
|
|
42
|
+
if (explicit) return explicit
|
|
43
|
+
try {
|
|
44
|
+
return usePlugin().theme
|
|
45
|
+
} catch {
|
|
46
|
+
return { text: {} }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
17
50
|
/** The top-level collapsible sidebar section. */
|
|
18
51
|
export function CollapsibleSection(props: {
|
|
19
52
|
title: string
|
|
@@ -26,9 +59,11 @@ export function CollapsibleSection(props: {
|
|
|
26
59
|
/** Always-visible content between the header and the collapsible body
|
|
27
60
|
* (e.g. the plugin manager's status note). */
|
|
28
61
|
pinned?: JSX.Element
|
|
62
|
+
/** Header colors; pass the host's `usePlugin().theme` from the consumer. */
|
|
63
|
+
theme?: CollapsibleTheme
|
|
29
64
|
children: JSX.Element
|
|
30
65
|
}) {
|
|
31
|
-
const theme =
|
|
66
|
+
const theme = resolveTheme(props.theme)
|
|
32
67
|
const [expanded, setExpanded] = createSignal(false)
|
|
33
68
|
const count = () => props.count ?? 0
|
|
34
69
|
const threshold = () => props.threshold ?? 2
|
|
@@ -62,9 +97,11 @@ export function CollapsibleGroup(props: {
|
|
|
62
97
|
title: string
|
|
63
98
|
count: number
|
|
64
99
|
defaultCollapsed?: boolean
|
|
100
|
+
/** Header colors; pass the host's `usePlugin().theme` from the consumer. */
|
|
101
|
+
theme?: CollapsibleTheme
|
|
65
102
|
children: JSX.Element | ((collapsed: () => boolean) => JSX.Element)
|
|
66
103
|
}) {
|
|
67
|
-
const theme =
|
|
104
|
+
const theme = resolveTheme(props.theme)
|
|
68
105
|
const [collapsed, setCollapsed] = createSignal(props.defaultCollapsed ?? false)
|
|
69
106
|
return (
|
|
70
107
|
<box flexDirection="column">
|
package/src/toast.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// The host's toast UI is optional at the edges (beta API): every plugin
|
|
4
4
|
// hand-rolled the same try/catch fallback around `ui.toast.show`.
|
|
5
|
-
import type {
|
|
5
|
+
import type { KitUI, ToastInput } from "./host.ts"
|
|
6
6
|
|
|
7
7
|
/** Show a toast; silently no-ops when the host has no toast UI or it throws.
|
|
8
8
|
* Takes a minimal structural slice — the full host context's `ui.slot` is
|