opencode-skill-autodiscovery 1.1.4 → 1.3.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/README.md +87 -10
- package/dist/agents.d.ts +18 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +143 -0
- package/dist/agents.js.map +1 -0
- package/dist/discovery.d.ts +71 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +629 -0
- package/dist/discovery.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -275
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts +3 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +12 -0
- package/dist/log.js.map +1 -0
- package/dist/mcp.d.ts +18 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +169 -0
- package/dist/mcp.js.map +1 -0
- package/dist/schema.d.ts +5 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +9 -0
- package/dist/schema.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# opencode-skill-autodiscovery
|
|
2
2
|
|
|
3
3
|
An [opencode](https://opencode.ai) plugin that auto-discovers skills installed by
|
|
4
|
-
VS Code agent plugins
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
VS Code agent plugins, Claude Code plugins, and [Agent Plugins
|
|
5
|
+
1.0.0](https://agent-plugins.org) conformant packages on the current machine,
|
|
6
|
+
and registers them with opencode's `skills.paths` so they appear in every
|
|
7
|
+
session. Each discovered skill is also exposed as a `/skill-name` slash command
|
|
8
|
+
that loads the skill and routes the rest of your message through it.
|
|
8
9
|
|
|
9
10
|
## Why
|
|
10
11
|
|
|
@@ -26,10 +27,63 @@ setup:
|
|
|
26
27
|
- Claude Code plugins: `~/.claude/plugins/installed_plugins.json`
|
|
27
28
|
- Claude Code plugins on a remote host (SSH/remote sessions):
|
|
28
29
|
`~/.claude/remote/plugins/installed_plugins.json`
|
|
30
|
+
- **Agent Plugins 1.0.0 packages** distributed via npm. opencode installs npm
|
|
31
|
+
plugins into its own cache (`~/.cache/opencode/packages/...`), not the
|
|
32
|
+
project's `node_modules`, and a `skills.paths` entry relative to the project
|
|
33
|
+
dir silently resolves to nothing. This plugin scans both the opencode plugin
|
|
34
|
+
cache and the project's `node_modules` for packages carrying a root
|
|
35
|
+
`plugin.json` whose `$schema` is `https://agent-plugins.org/schemas/...`,
|
|
36
|
+
and registers their `skills/` with **absolute** paths — so an npm-distributed
|
|
37
|
+
Agent Plugins package (e.g. `@dodopayments/opencode-plugin`) just works with
|
|
38
|
+
`"plugin": ["opencode-skill-autodiscovery"]` and nothing else.
|
|
29
39
|
|
|
30
40
|
Each points at plugin directories that contain `SKILL.md` files. This plugin
|
|
31
41
|
reads the manifests (including the remote `cache.json` LRU), resolves each
|
|
32
42
|
entry to its on-disk skill directories, and registers them with opencode.
|
|
43
|
+
When a discovered package carries a conformant root `plugin.json`, that manifest
|
|
44
|
+
is preferred (its `skills/` children are registered as-is); otherwise the plugin
|
|
45
|
+
falls back to a tree walk so legacy layouts keep working.
|
|
46
|
+
|
|
47
|
+
### MCP servers (opt-in)
|
|
48
|
+
|
|
49
|
+
With the `mcp` option, the plugin also reads each discovered package's `mcp.json`
|
|
50
|
+
and maps it onto opencode's `config.mcp`:
|
|
51
|
+
|
|
52
|
+
| Agent Plugins server | opencode entry |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `{ "type": "stdio", "command", "args", "env" }` | `{ "type": "local", "command": [...], "environment": {...} }` |
|
|
55
|
+
| `{ "type": "streamable-http", "url" }` | `{ "type": "remote", "url" }` |
|
|
56
|
+
| `{ "type": "sse" }` | skipped (opencode has no SSE transport) |
|
|
57
|
+
|
|
58
|
+
`${PLUGIN_ROOT}` and `${PLUGIN_DATA}` placeholders are expanded in `args`/`env`,
|
|
59
|
+
and both variables are injected into each stdio server's environment
|
|
60
|
+
(`PLUGIN_DATA` points at
|
|
61
|
+
`{opencode state}/plugin-data/{packageName}`). Invalid entries are skipped
|
|
62
|
+
per-entry, never fatally. `sse` servers and stdio `cwd` (which opencode cannot
|
|
63
|
+
represent) are dropped with a log line.
|
|
64
|
+
|
|
65
|
+
### Agents (opt-in)
|
|
66
|
+
|
|
67
|
+
Agent Plugins 1.0.0 has no portable "agents" component type (only skills and
|
|
68
|
+
MCP servers), so agents are contributed through the spec's client-extension
|
|
69
|
+
mechanism. With the `agents` option, the plugin reads agents from three
|
|
70
|
+
sources, in order:
|
|
71
|
+
|
|
72
|
+
1. `plugin.json` → `extensions["dev.opencode"].agents` (a map of agent name →
|
|
73
|
+
opencode `agent` config).
|
|
74
|
+
2. A `dev.opencode/agents/<name>.json` extension directory (one opencode agent
|
|
75
|
+
config per file).
|
|
76
|
+
3. A legacy Claude Code plugin shim: `.claude-plugin/plugin.json` `agents`,
|
|
77
|
+
mapping `description` and `systemPrompt` (or the `agents/<name>/AGENTS.md`
|
|
78
|
+
body) onto an opencode agent.
|
|
79
|
+
|
|
80
|
+
Discovered agents are registered as `config.agent.<name>` with the same rules
|
|
81
|
+
as commands: user-defined agents are never overwritten, same-source mirrors are
|
|
82
|
+
collapsed, and cross-source collisions become `<package>-<agent>`.
|
|
83
|
+
|
|
84
|
+
**Trust note:** a package-supplied `permission` block is always dropped — agent
|
|
85
|
+
permissions are too powerful to inherit from a package by default. If you need
|
|
86
|
+
one, define the agent yourself in `opencode.json` (which always wins).
|
|
33
87
|
|
|
34
88
|
### Slash commands
|
|
35
89
|
|
|
@@ -45,7 +99,8 @@ Context: $ARGUMENTS
|
|
|
45
99
|
|
|
46
100
|
So `/spec plan the migration` loads the `spec` skill and runs it against
|
|
47
101
|
`plan the migration`. The command's description is taken from the skill's
|
|
48
|
-
frontmatter; existing commands with the same name are
|
|
102
|
+
frontmatter; existing commands with the same name are never overwritten (a
|
|
103
|
+
colliding skill from a different source is registered as `/package-skill`).
|
|
49
104
|
|
|
50
105
|
## Install
|
|
51
106
|
|
|
@@ -57,20 +112,33 @@ Add the package name to the `plugin` array in your `opencode.json`:
|
|
|
57
112
|
}
|
|
58
113
|
```
|
|
59
114
|
|
|
60
|
-
Use the tuple form to
|
|
61
|
-
VS Code data location on a remote host):
|
|
115
|
+
Use the tuple form to configure options:
|
|
62
116
|
|
|
63
117
|
```json
|
|
64
118
|
{
|
|
65
119
|
"plugin": [
|
|
66
120
|
[
|
|
67
121
|
"opencode-skill-autodiscovery",
|
|
68
|
-
{
|
|
122
|
+
{
|
|
123
|
+
"extraRoots": ["/home/user/.vscode-server"],
|
|
124
|
+
"scanCache": true,
|
|
125
|
+
"scanNodeModules": true,
|
|
126
|
+
"mcp": false,
|
|
127
|
+
"agents": false
|
|
128
|
+
}
|
|
69
129
|
]
|
|
70
130
|
]
|
|
71
131
|
}
|
|
72
132
|
```
|
|
73
133
|
|
|
134
|
+
| Option | Default | Meaning |
|
|
135
|
+
|---|---|---|
|
|
136
|
+
| `extraRoots` | `[]` | Extra root directories to scan (e.g. a non-standard VS Code data location on a remote host). |
|
|
137
|
+
| `scanCache` | `true` | Scan opencode's plugin cache (`~/.cache/opencode/packages/*`) for Agent Plugins packages. |
|
|
138
|
+
| `scanNodeModules` | `true` | Scan the project's `node_modules` (incl. `@scope/*`) for Agent Plugins packages. |
|
|
139
|
+
| `mcp` | `false` | Also register MCP servers from discovered packages' `mcp.json`. |
|
|
140
|
+
| `agents` | `false` | Also register agents from packages (see "Agents" above). |
|
|
141
|
+
|
|
74
142
|
## Notes
|
|
75
143
|
|
|
76
144
|
- Discovery is inherently **machine-local**: it reads manifests from the home
|
|
@@ -89,14 +157,23 @@ VS Code data location on a remote host):
|
|
|
89
157
|
cloned-but-uninstalled marketplaces on setups that do have a manifest.
|
|
90
158
|
- VS Code account sync only syncs your marketplace extension list; each machine
|
|
91
159
|
still has its own `installed.json`/`cache.json` that this plugin reads.
|
|
92
|
-
-
|
|
93
|
-
|
|
160
|
+
- A package is only treated as an Agent Plugins package when its root
|
|
161
|
+
`plugin.json` declares a `$schema` under `https://agent-plugins.org/schemas/`.
|
|
162
|
+
Everything else is ignored by the cache/node_modules scanners and falls back
|
|
163
|
+
to the tree walk elsewhere.
|
|
164
|
+
- The same plugin can be materialised in several VS Code layouts at once
|
|
165
|
+
(local clone + synced bundle + marketplace clone). `skills.paths` keeps all
|
|
166
|
+
paths; slash commands and MCP servers are de-duplicated so mirrors don't
|
|
167
|
+
create a wall of `/mirror-of-...` junk.
|
|
168
|
+
- The plugin is a no-op when no manifests or conformant packages exist, or when
|
|
169
|
+
they contain no skills.
|
|
94
170
|
|
|
95
171
|
## Development
|
|
96
172
|
|
|
97
173
|
```sh
|
|
98
174
|
npm install
|
|
99
175
|
npm run build # tsc -> dist/
|
|
176
|
+
npm test # build + node --test (fixture-based unit tests)
|
|
100
177
|
```
|
|
101
178
|
|
|
102
179
|
Publish:
|
package/dist/agents.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { PluginPackage } from "./discovery.js";
|
|
2
|
+
export type AgentConfig = {
|
|
3
|
+
model?: string;
|
|
4
|
+
temperature?: number;
|
|
5
|
+
top_p?: number;
|
|
6
|
+
prompt?: string;
|
|
7
|
+
tools?: Record<string, boolean>;
|
|
8
|
+
disable?: boolean;
|
|
9
|
+
description?: string;
|
|
10
|
+
mode?: "subagent" | "primary" | "all";
|
|
11
|
+
color?: string;
|
|
12
|
+
maxSteps?: number;
|
|
13
|
+
};
|
|
14
|
+
export declare function readAgents(pkg: PluginPackage): Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
agent: AgentConfig;
|
|
17
|
+
}>;
|
|
18
|
+
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,KAAK,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AA4EF,wBAAgB,UAAU,CACxB,GAAG,EAAE,aAAa,GACjB,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC,CA0D7C"}
|
package/dist/agents.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { readFileSync, readdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { log } from "./log.js";
|
|
4
|
+
// Reverse-DNS namespace this plugin (and opencode, by convention) owns for
|
|
5
|
+
// client-specific manifest data and extension directories (Agent Plugins 5.6/8).
|
|
6
|
+
const OPENCODE_NS = "dev.opencode";
|
|
7
|
+
const MODES = new Set(["subagent", "primary", "all"]);
|
|
8
|
+
function asRecord(value) {
|
|
9
|
+
return typeof value === "object" && value !== null
|
|
10
|
+
? value
|
|
11
|
+
: null;
|
|
12
|
+
}
|
|
13
|
+
function readJson(path) {
|
|
14
|
+
try {
|
|
15
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// Converts a raw, package-supplied agent object into an opencode AgentConfig.
|
|
22
|
+
// `permission` blocks are dropped (too powerful to inherit by default) and
|
|
23
|
+
// unknown/mistyped keys are ignored. Returns null when nothing usable is left.
|
|
24
|
+
function toAgentConfig(raw) {
|
|
25
|
+
const src = asRecord(raw);
|
|
26
|
+
if (!src)
|
|
27
|
+
return null;
|
|
28
|
+
const agent = {};
|
|
29
|
+
const stringValue = (key) => typeof src[key] === "string" ? src[key] : undefined;
|
|
30
|
+
const numberValue = (key) => typeof src[key] === "number" && Number.isFinite(src[key])
|
|
31
|
+
? src[key]
|
|
32
|
+
: undefined;
|
|
33
|
+
const model = stringValue("model");
|
|
34
|
+
const prompt = stringValue("prompt");
|
|
35
|
+
const description = stringValue("description");
|
|
36
|
+
const color = stringValue("color");
|
|
37
|
+
const temperature = numberValue("temperature");
|
|
38
|
+
const topP = numberValue("top_p");
|
|
39
|
+
const maxSteps = numberValue("maxSteps");
|
|
40
|
+
if (model)
|
|
41
|
+
agent.model = model;
|
|
42
|
+
if (prompt)
|
|
43
|
+
agent.prompt = prompt;
|
|
44
|
+
if (description)
|
|
45
|
+
agent.description = description;
|
|
46
|
+
if (color)
|
|
47
|
+
agent.color = color;
|
|
48
|
+
if (temperature !== undefined)
|
|
49
|
+
agent.temperature = temperature;
|
|
50
|
+
if (topP !== undefined)
|
|
51
|
+
agent.top_p = topP;
|
|
52
|
+
if (maxSteps !== undefined)
|
|
53
|
+
agent.maxSteps = maxSteps;
|
|
54
|
+
if (typeof src.disable === "boolean")
|
|
55
|
+
agent.disable = src.disable;
|
|
56
|
+
if (typeof src.mode === "string" && MODES.has(src.mode)) {
|
|
57
|
+
agent.mode = src.mode;
|
|
58
|
+
}
|
|
59
|
+
const tools = asRecord(src.tools);
|
|
60
|
+
if (tools) {
|
|
61
|
+
const filtered = {};
|
|
62
|
+
for (const [name, value] of Object.entries(tools)) {
|
|
63
|
+
if (typeof value === "boolean")
|
|
64
|
+
filtered[name] = value;
|
|
65
|
+
}
|
|
66
|
+
agent.tools = filtered;
|
|
67
|
+
}
|
|
68
|
+
if (src.permission !== undefined) {
|
|
69
|
+
log("dropping permission block from a package-supplied agent: too powerful to inherit");
|
|
70
|
+
}
|
|
71
|
+
if (!agent.description && !agent.prompt)
|
|
72
|
+
return null;
|
|
73
|
+
return agent;
|
|
74
|
+
}
|
|
75
|
+
// Discovers agents contributed by a package, in order:
|
|
76
|
+
// 1. plugin.json `extensions["dev.opencode"].agents` (Agent Plugins 5.6)
|
|
77
|
+
// 2. a `dev.opencode/agents/<name>.json` extension directory (Agent Plugins 8.2)
|
|
78
|
+
// 3. a legacy Claude Code plugin shim: `.claude-plugin/plugin.json` `agents`
|
|
79
|
+
// plus `agents/<name>/AGENTS.md` when no systemPrompt is declared.
|
|
80
|
+
// Returns a stable, de-duplicated list keyed by agent name.
|
|
81
|
+
export function readAgents(pkg) {
|
|
82
|
+
const out = new Map();
|
|
83
|
+
const manifest = asRecord(readJson(join(pkg.root, "plugin.json")));
|
|
84
|
+
const extensions = asRecord(manifest?.extensions);
|
|
85
|
+
const opencodeExt = asRecord(extensions?.[OPENCODE_NS]);
|
|
86
|
+
const manifestAgents = asRecord(opencodeExt?.agents);
|
|
87
|
+
if (manifestAgents) {
|
|
88
|
+
for (const [name, raw] of Object.entries(manifestAgents)) {
|
|
89
|
+
if (out.has(name))
|
|
90
|
+
continue;
|
|
91
|
+
const agent = toAgentConfig(raw);
|
|
92
|
+
if (agent)
|
|
93
|
+
out.set(name, agent);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const extDir = join(pkg.root, OPENCODE_NS, "agents");
|
|
97
|
+
let extEntries = [];
|
|
98
|
+
try {
|
|
99
|
+
extEntries = readdirSync(extDir);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
extEntries = [];
|
|
103
|
+
}
|
|
104
|
+
for (const entry of extEntries) {
|
|
105
|
+
if (!entry.endsWith(".json"))
|
|
106
|
+
continue;
|
|
107
|
+
const name = entry.slice(0, -".json".length);
|
|
108
|
+
if (out.has(name))
|
|
109
|
+
continue;
|
|
110
|
+
const agent = toAgentConfig(readJson(join(extDir, entry)));
|
|
111
|
+
if (agent)
|
|
112
|
+
out.set(name, agent);
|
|
113
|
+
}
|
|
114
|
+
const claudeManifest = asRecord(readJson(join(pkg.root, ".claude-plugin", "plugin.json")));
|
|
115
|
+
const claudeAgents = asRecord(claudeManifest?.agents);
|
|
116
|
+
if (claudeAgents) {
|
|
117
|
+
for (const [name, raw] of Object.entries(claudeAgents)) {
|
|
118
|
+
if (out.has(name))
|
|
119
|
+
continue;
|
|
120
|
+
const src = asRecord(raw);
|
|
121
|
+
if (!src || typeof src.description !== "string")
|
|
122
|
+
continue;
|
|
123
|
+
const agent = { description: src.description };
|
|
124
|
+
if (typeof src.systemPrompt === "string" && src.systemPrompt) {
|
|
125
|
+
agent.prompt = src.systemPrompt;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
try {
|
|
129
|
+
agent.prompt = readFileSync(join(pkg.root, "agents", name, "AGENTS.md"), "utf8");
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// No prompt file; the description alone is enough to register.
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (typeof src.model === "string")
|
|
136
|
+
agent.model = src.model;
|
|
137
|
+
if (agent.prompt || agent.description)
|
|
138
|
+
out.set(name, agent);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return [...out.entries()].map(([name, agent]) => ({ name, agent }));
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { AgentConfig } from "./agents.js";
|
|
2
|
+
import type { McpEntry } from "./mcp.js";
|
|
3
|
+
export { readAgents } from "./agents.js";
|
|
4
|
+
export type { AgentConfig } from "./agents.js";
|
|
5
|
+
export { readMcp } from "./mcp.js";
|
|
6
|
+
export type { McpEntry } from "./mcp.js";
|
|
7
|
+
export type PackageSource = "claude" | "vscode" | "opencode-cache" | "node_modules" | "extra";
|
|
8
|
+
export type PluginPackage = {
|
|
9
|
+
source: PackageSource;
|
|
10
|
+
name: string;
|
|
11
|
+
root: string;
|
|
12
|
+
skillDirs: string[];
|
|
13
|
+
mcpPath?: string;
|
|
14
|
+
/** Agent Plugins version declared by plugin.json, e.g. "1.0.0". */
|
|
15
|
+
schemaVersion?: string;
|
|
16
|
+
};
|
|
17
|
+
export type SkillInfo = {
|
|
18
|
+
dir: string;
|
|
19
|
+
name: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
export type ConfigPatch = {
|
|
23
|
+
skillPaths: string[];
|
|
24
|
+
commands: Array<{
|
|
25
|
+
name: string;
|
|
26
|
+
description: string;
|
|
27
|
+
template: string;
|
|
28
|
+
}>;
|
|
29
|
+
mcp: Array<{
|
|
30
|
+
key: string;
|
|
31
|
+
entry: McpEntry;
|
|
32
|
+
}>;
|
|
33
|
+
agents: Array<{
|
|
34
|
+
name: string;
|
|
35
|
+
agent: AgentConfig;
|
|
36
|
+
}>;
|
|
37
|
+
};
|
|
38
|
+
export type ConfigLike = {
|
|
39
|
+
skills?: {
|
|
40
|
+
paths?: string[];
|
|
41
|
+
};
|
|
42
|
+
command?: Record<string, {
|
|
43
|
+
description?: string;
|
|
44
|
+
template: string;
|
|
45
|
+
}>;
|
|
46
|
+
mcp?: Record<string, McpEntry>;
|
|
47
|
+
agent?: Record<string, AgentConfig | undefined>;
|
|
48
|
+
};
|
|
49
|
+
export declare function contains(parent: string, child: string): boolean;
|
|
50
|
+
export declare function readSkillInfo(dir: string): SkillInfo | null;
|
|
51
|
+
export declare function readPackage(root: string, source: PackageSource): PluginPackage | null;
|
|
52
|
+
export declare function findSkillDirs(root: string, out: Set<string>, seen: Set<string>): void;
|
|
53
|
+
export declare function packageFromDir(root: string, source: PackageSource): PluginPackage | null;
|
|
54
|
+
export declare function collectVscodeManifest(out: PluginPackage[], installedJson: string): void;
|
|
55
|
+
export declare function collectVscodeCache(out: PluginPackage[], cacheJson: string): void;
|
|
56
|
+
export declare function collectVscode(out: PluginPackage[], extra: string[]): void;
|
|
57
|
+
export declare function collectClaudeManifest(out: PluginPackage[], installedJson: string): void;
|
|
58
|
+
export declare function collectClaude(out: PluginPackage[]): void;
|
|
59
|
+
export declare function opencodeCacheRoot(): string;
|
|
60
|
+
export declare function collectOpencodeCache(packagesRoot: string, out: PluginPackage[]): void;
|
|
61
|
+
export declare function collectNodeModules(nodeModulesRoot: string, out: PluginPackage[]): void;
|
|
62
|
+
export declare function planConfig(packages: PluginPackage[], taken?: {
|
|
63
|
+
commands?: Iterable<string>;
|
|
64
|
+
mcp?: Iterable<string>;
|
|
65
|
+
agents?: Iterable<string>;
|
|
66
|
+
}): ConfigPatch;
|
|
67
|
+
export declare function applyConfigPatch(config: ConfigLike, plan: ConfigPatch, enabled: {
|
|
68
|
+
mcp: boolean;
|
|
69
|
+
agents: boolean;
|
|
70
|
+
}): void;
|
|
71
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|