@kisev/agentomatic 11.0.2-dev.93.g810c3f0460fa → 11.0.2
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 +8 -10
- package/README.ru.md +8 -11
- package/dist/agent-profiles.js +48 -33
- package/dist/assets/agents/architect.md +4 -4
- package/dist/assets/agents/critic.md +11 -10
- package/dist/assets/agents/manager.md +12 -11
- package/dist/assets/agents/mapper.md +4 -4
- package/dist/assets/agents/review.md +12 -11
- package/dist/assets/agents/worker.md +32 -29
- package/dist/assets/commands/rtk-stats.md +1 -1
- package/dist/assets/plugins/rtk.js +1 -1
- package/dist/assets/plugins/rules-injector.js +1 -1
- package/dist/assets/plugins/zed-bell.js +1 -1
- package/dist/cli.js +5 -8
- package/dist/config-setup.d.ts +7 -2
- package/dist/config-setup.js +52 -74
- package/dist/doctor.d.ts +1 -0
- package/dist/doctor.js +54 -39
- package/dist/index.d.ts +117 -9
- package/dist/index.js +125 -100
- package/dist/jsonc.d.ts +1 -12
- package/dist/jsonc.js +5 -82
- package/dist/plugins/rtk.d.ts +12 -9
- package/dist/plugins/rtk.js +5 -20
- package/dist/plugins/rules-injector.d.ts +11 -21
- package/dist/plugins/rules-injector.js +31 -43
- package/dist/plugins/zed-bell.d.ts +5 -8
- package/dist/plugins/zed-bell.js +2 -10
- package/dist/registry.js +1 -1
- package/dist/routing.js +1 -1
- package/package.json +7 -8
- package/dist/opencode-config.d.ts +0 -9
- package/dist/opencode-config.js +0 -158
- package/dist/plugins/events.d.ts +0 -20
- package/dist/plugins/events.js +0 -48
package/dist/config-setup.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
1
2
|
import { randomUUID } from "node:crypto";
|
|
2
3
|
import { lstat } from "node:fs/promises";
|
|
3
4
|
import { homedir } from "node:os";
|
|
4
|
-
import { join, resolve } from "node:path";
|
|
5
|
+
import { dirname, join, resolve } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
5
7
|
import { archiveMutations } from "./installer.js";
|
|
6
8
|
import { requirePackageVersion } from "./package-metadata.js";
|
|
7
9
|
import { ensureDependency, planDependency } from "./self-install.js";
|
|
8
10
|
import { applyTransaction, archiveRoot, deploymentRoot, LifecycleError, lifecycleRoot, inspectTransaction, readRegular, recoverTransaction, sha256, withLifecycleLock, } from "./lifecycle.js";
|
|
9
11
|
import { applyJsoncEdits, parseJsonc } from "./jsonc.js";
|
|
10
|
-
import { corePluginEdits, permissionEdits } from "./opencode-config.js";
|
|
11
12
|
const PACKAGE_NAME = "@kisev/agentomatic";
|
|
13
|
+
const LEGACY_PACKAGE_NAME = "@kisev/skills-opencode";
|
|
14
|
+
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
12
15
|
const XDG_STATE_GLOB = "~/.local/state/agent-skills/**";
|
|
13
16
|
const OPENCODE_SKILLS_GLOB = "~/.config/opencode/skills/**";
|
|
14
|
-
const AGENTS_SKILLS_GLOB = "~/.agents/skills/**";
|
|
15
17
|
const SECRET_PATHS = [
|
|
16
18
|
"**/.env",
|
|
17
19
|
"**/.env.*",
|
|
@@ -46,10 +48,16 @@ export const CONFIG_FRAGMENTS = [
|
|
|
46
48
|
},
|
|
47
49
|
{
|
|
48
50
|
name: "skills-state-permissions",
|
|
49
|
-
description: "Allow the
|
|
51
|
+
description: "Allow the standard skills XDG state paths without per-run prompts",
|
|
50
52
|
targets: ["opencode", "kilo", "mimo"],
|
|
51
53
|
file: "main",
|
|
52
54
|
},
|
|
55
|
+
{
|
|
56
|
+
name: "lsp-preset",
|
|
57
|
+
description: "Add LSP servers from the shared catalog (OpenCode only)",
|
|
58
|
+
targets: ["opencode"],
|
|
59
|
+
file: "main",
|
|
60
|
+
},
|
|
53
61
|
{
|
|
54
62
|
name: "secrets-guard",
|
|
55
63
|
description: "Deny reads and edits of common secret files",
|
|
@@ -64,7 +72,7 @@ export const CONFIG_FRAGMENTS = [
|
|
|
64
72
|
},
|
|
65
73
|
{
|
|
66
74
|
name: "tui-schema",
|
|
67
|
-
description: "
|
|
75
|
+
description: "Unify each agent TUI file: schema, theme, stacked diffs, and leader keybinds",
|
|
68
76
|
targets: ["opencode", "kilo", "mimo"],
|
|
69
77
|
file: "tui",
|
|
70
78
|
},
|
|
@@ -129,26 +137,23 @@ const UNIFIED_TUI_KEYBINDS = {
|
|
|
129
137
|
messages_toggle_conceal: "<leader>h,<leader>р",
|
|
130
138
|
tips_toggle: "<leader>h,<leader>р",
|
|
131
139
|
};
|
|
132
|
-
const
|
|
133
|
-
"
|
|
134
|
-
"
|
|
135
|
-
"
|
|
136
|
-
"
|
|
137
|
-
"prompt.editor": "<leader>e,<leader>у",
|
|
138
|
-
"theme.switch": "<leader>t,<leader>е",
|
|
139
|
-
"session.sidebar.toggle": "<leader>b,<leader>и",
|
|
140
|
-
"opencode.status": "<leader>s,<leader>ы",
|
|
141
|
-
"session.export": "<leader>x,<leader>ч",
|
|
142
|
-
"session.new": "<leader>n,<leader>т",
|
|
143
|
-
"session.list": "<leader>l,<leader>д",
|
|
144
|
-
"session.timeline": "<leader>g,<leader>п",
|
|
145
|
-
"session.compact": "<leader>c,<leader>с",
|
|
146
|
-
"model.list": "<leader>m,<leader>ь",
|
|
147
|
-
"agent.list": "<leader>a,<leader>ф",
|
|
148
|
-
"messages.copy": "<leader>y,<leader>н",
|
|
149
|
-
"session.undo": "<leader>u,<leader>г",
|
|
150
|
-
"session.redo": "<leader>r,<leader>к",
|
|
140
|
+
const LSP_SERVER_COMMANDS = {
|
|
141
|
+
python: ["basedpyright-langserver", "--stdio"],
|
|
142
|
+
typescript: ["typescript-language-server", "--stdio"],
|
|
143
|
+
yaml: ["yaml-language-server", "--stdio"],
|
|
144
|
+
shell: ["bash-language-server", "start"],
|
|
151
145
|
};
|
|
146
|
+
function lspCatalog() {
|
|
147
|
+
const raw = readFileSync(resolve(packageRoot, "dist", "assets", "lsp-catalog.json"), "utf8");
|
|
148
|
+
const catalog = JSON.parse(raw);
|
|
149
|
+
if (!Array.isArray(catalog.servers))
|
|
150
|
+
throw new ConfigSetupError("invalid_package", "LSP catalog is unavailable");
|
|
151
|
+
return catalog.servers
|
|
152
|
+
.filter((server) => typeof server.name === "string" &&
|
|
153
|
+
Array.isArray(server.extensions) &&
|
|
154
|
+
server.extensions.every((extension) => typeof extension === "string"))
|
|
155
|
+
.filter((server) => LSP_SERVER_COMMANDS[server.name]);
|
|
156
|
+
}
|
|
152
157
|
function mapAllowsAll(value) {
|
|
153
158
|
return Boolean(value &&
|
|
154
159
|
typeof value === "object" &&
|
|
@@ -166,20 +171,20 @@ function fragmentEdits(fragment, target, current) {
|
|
|
166
171
|
? value.permission
|
|
167
172
|
: {};
|
|
168
173
|
if (fragment === "core-plugin") {
|
|
169
|
-
return
|
|
174
|
+
return [
|
|
175
|
+
{ kind: "set-if-absent", path: ["$schema"], value: "https://opencode.ai/config.json" },
|
|
176
|
+
{ kind: "set-if-absent", path: ["plugin"], value: [] },
|
|
177
|
+
{
|
|
178
|
+
kind: "replace-array-value",
|
|
179
|
+
path: ["plugin"],
|
|
180
|
+
from: LEGACY_PACKAGE_NAME,
|
|
181
|
+
to: PACKAGE_NAME,
|
|
182
|
+
},
|
|
183
|
+
{ kind: "append-unique", path: ["plugin"], value: PACKAGE_NAME },
|
|
184
|
+
];
|
|
170
185
|
}
|
|
171
186
|
if (fragment === "skills-state-permissions") {
|
|
172
|
-
const statePaths = target === "opencode"
|
|
173
|
-
? [XDG_STATE_GLOB, OPENCODE_SKILLS_GLOB, AGENTS_SKILLS_GLOB]
|
|
174
|
-
: [XDG_STATE_GLOB];
|
|
175
|
-
if (target === "opencode")
|
|
176
|
-
return permissionEdits(value, [
|
|
177
|
-
...statePaths.flatMap((resource) => [
|
|
178
|
-
{ action: "read", resource, effect: "allow" },
|
|
179
|
-
{ action: "external_directory", resource, effect: "allow" },
|
|
180
|
-
]),
|
|
181
|
-
{ action: "edit", resource: XDG_STATE_GLOB, effect: "allow" },
|
|
182
|
-
]);
|
|
187
|
+
const statePaths = target === "opencode" ? [XDG_STATE_GLOB, OPENCODE_SKILLS_GLOB] : [XDG_STATE_GLOB];
|
|
183
188
|
const edits = [];
|
|
184
189
|
if (!mapAllowsAll(permission.read))
|
|
185
190
|
edits.push(...permissionMapEdits(["permission", "read"], Object.fromEntries(statePaths.map((glob) => [glob, "allow"]))));
|
|
@@ -189,15 +194,14 @@ function fragmentEdits(fragment, target, current) {
|
|
|
189
194
|
edits.push(...permissionMapEdits(["permission", "external_directory"], Object.fromEntries(statePaths.map((glob) => [glob, "allow"]))));
|
|
190
195
|
return edits;
|
|
191
196
|
}
|
|
197
|
+
if (fragment === "lsp-preset") {
|
|
198
|
+
return lspCatalog().map((server) => ({
|
|
199
|
+
kind: "set-if-absent",
|
|
200
|
+
path: ["lsp", server.name],
|
|
201
|
+
value: { command: LSP_SERVER_COMMANDS[server.name], extensions: server.extensions },
|
|
202
|
+
}));
|
|
203
|
+
}
|
|
192
204
|
if (fragment === "secrets-guard") {
|
|
193
|
-
if (target === "opencode")
|
|
194
|
-
return permissionEdits(value, [
|
|
195
|
-
...SECRET_PATHS.flatMap((glob) => [
|
|
196
|
-
{ action: "read", resource: glob.replace(/^\*\*\//, "*"), effect: "deny" },
|
|
197
|
-
{ action: "edit", resource: glob.replace(/^\*\*\//, "*"), effect: "deny" },
|
|
198
|
-
]),
|
|
199
|
-
{ action: "read", resource: "*.env.example", effect: "allow" },
|
|
200
|
-
]);
|
|
201
205
|
const deny = Object.fromEntries(SECRET_PATHS.map((glob) => [glob, "deny"]));
|
|
202
206
|
return [
|
|
203
207
|
...permissionMapEdits(["permission", "read"], {
|
|
@@ -215,18 +219,8 @@ function fragmentEdits(fragment, target, current) {
|
|
|
215
219
|
{ kind: "set-if-absent", path: ["mcp_tool_display"], value: "expanded" },
|
|
216
220
|
];
|
|
217
221
|
}
|
|
218
|
-
if (target === "opencode")
|
|
219
|
-
return [
|
|
220
|
-
{ kind: "set-if-absent", path: ["$schema"], value: "https://opencode.ai/v2/cli.json" },
|
|
221
|
-
{ kind: "set-if-absent", path: ["theme", "name"], value: "ayu" },
|
|
222
|
-
...Object.entries(OPENCODE_KEYBINDS).map(([key, value]) => ({
|
|
223
|
-
kind: "set-if-absent",
|
|
224
|
-
path: ["keybinds", key],
|
|
225
|
-
value,
|
|
226
|
-
})),
|
|
227
|
-
];
|
|
228
222
|
const tuiSchemas = {
|
|
229
|
-
opencode:
|
|
223
|
+
opencode: "https://opencode.ai/tui.json",
|
|
230
224
|
kilo: undefined,
|
|
231
225
|
mimo: "https://mimo.xiaomi.com/mimocode/tui.json",
|
|
232
226
|
};
|
|
@@ -314,9 +308,9 @@ async function resolveTargetFile(target, scope, cwd, home, kind = "main") {
|
|
|
314
308
|
return {
|
|
315
309
|
target,
|
|
316
310
|
root: globalRoot,
|
|
317
|
-
path: "
|
|
318
|
-
absolute: join(globalRoot, "
|
|
319
|
-
exists: await existing(globalRoot, "
|
|
311
|
+
path: "tui.json",
|
|
312
|
+
absolute: join(globalRoot, "tui.json"),
|
|
313
|
+
exists: await existing(globalRoot, "tui.json"),
|
|
320
314
|
};
|
|
321
315
|
}
|
|
322
316
|
if (target === "opencode") {
|
|
@@ -410,20 +404,6 @@ async function build(selection, scope, cwd = process.cwd(), home = homedir()) {
|
|
|
410
404
|
for (const fragment of selection.fragments) {
|
|
411
405
|
if (!applicable(fragment, target) || fragmentFileKind(fragment) !== kind)
|
|
412
406
|
continue;
|
|
413
|
-
if (target === "opencode" &&
|
|
414
|
-
kind === "tui" &&
|
|
415
|
-
!file.exists &&
|
|
416
|
-
((await readRegular(join(file.root, "tui.json"))) ||
|
|
417
|
-
(await readRegular(join(file.root, "tui.jsonc"))))) {
|
|
418
|
-
operations.push({
|
|
419
|
-
target,
|
|
420
|
-
path: file.absolute,
|
|
421
|
-
fragment,
|
|
422
|
-
operation: "conflict",
|
|
423
|
-
reason: "Start OpenCode V2 once to migrate existing TUI preferences into cli.json before applying terminal presets",
|
|
424
|
-
});
|
|
425
|
-
continue;
|
|
426
|
-
}
|
|
427
407
|
let parsed = undefined;
|
|
428
408
|
try {
|
|
429
409
|
parsed = parseJsonc(text);
|
|
@@ -594,8 +574,6 @@ export async function applyConfigSetup(selection, scope, cwd = process.cwd(), ho
|
|
|
594
574
|
await provision();
|
|
595
575
|
return built.plan;
|
|
596
576
|
}
|
|
597
|
-
if (!built.plan.operations.some((operation) => operation.operation === "conflict"))
|
|
598
|
-
return built.plan;
|
|
599
577
|
throw new ConfigSetupError("invalid_state", "Config setup plan has no applicable changes");
|
|
600
578
|
}
|
|
601
579
|
const backups = [];
|
package/dist/doctor.d.ts
CHANGED
package/dist/doctor.js
CHANGED
|
@@ -12,7 +12,6 @@ import { archiveRoot, assertSafePath, deploymentRoot, lifecycleRoot, } from "./l
|
|
|
12
12
|
import { inspectReconcile } from "./reconcile.js";
|
|
13
13
|
import { readPackageVersion } from "./package-metadata.js";
|
|
14
14
|
import { planDependency } from "./self-install.js";
|
|
15
|
-
import { parseJsonc } from "./jsonc.js";
|
|
16
15
|
import { readRtkStats, rtkCharsSaved, rtkStatsPath, rtkTokensSavedEstimate, } from "./plugins/rtk.js";
|
|
17
16
|
import { stateRoot } from "./runtime/state.js";
|
|
18
17
|
const run = promisify(execFile);
|
|
@@ -115,19 +114,17 @@ function agentManifestValid(raw) {
|
|
|
115
114
|
}
|
|
116
115
|
function redactedConfig(value) {
|
|
117
116
|
const object = value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
? configuredPlugins.flatMap((item) => {
|
|
117
|
+
const rawPlugins = Array.isArray(object.plugin)
|
|
118
|
+
? object.plugin.flatMap((item) => {
|
|
121
119
|
if (typeof item === "string")
|
|
122
120
|
return [item];
|
|
123
|
-
if (item && typeof item === "
|
|
124
|
-
return [item
|
|
121
|
+
if (Array.isArray(item) && typeof item[0] === "string")
|
|
122
|
+
return [item[0]];
|
|
125
123
|
return [];
|
|
126
124
|
})
|
|
127
125
|
: [];
|
|
128
126
|
const knownPlugins = new Set([packageName, ...CATALOG.plugins]);
|
|
129
|
-
const
|
|
130
|
-
const plugins = rawPlugins.map(normalizePlugin).filter((plugin) => knownPlugins.has(plugin));
|
|
127
|
+
const plugins = rawPlugins.filter((plugin) => knownPlugins.has(plugin));
|
|
131
128
|
const enabled = plugins.filter((plugin) => plugin === packageName ||
|
|
132
129
|
CATALOG.plugins.includes(plugin));
|
|
133
130
|
return {
|
|
@@ -138,14 +135,17 @@ function redactedConfig(value) {
|
|
|
138
135
|
keys: Object.keys(object)
|
|
139
136
|
.filter((key) => [
|
|
140
137
|
"$schema",
|
|
141
|
-
"
|
|
138
|
+
"theme",
|
|
139
|
+
"keybinds",
|
|
140
|
+
"logLevel",
|
|
141
|
+
"command",
|
|
142
142
|
"watcher",
|
|
143
|
-
"
|
|
143
|
+
"plugin",
|
|
144
144
|
"lsp",
|
|
145
145
|
"formatter",
|
|
146
|
-
"
|
|
147
|
-
"
|
|
148
|
-
"
|
|
146
|
+
"provider",
|
|
147
|
+
"agent",
|
|
148
|
+
"permission",
|
|
149
149
|
"compaction",
|
|
150
150
|
"model",
|
|
151
151
|
].includes(key))
|
|
@@ -155,26 +155,12 @@ function redactedConfig(value) {
|
|
|
155
155
|
}
|
|
156
156
|
async function localConfig(scope, cwd, home) {
|
|
157
157
|
const paths = scope === "project"
|
|
158
|
-
? [
|
|
159
|
-
|
|
160
|
-
join(cwd, "opencode.jsonc"),
|
|
161
|
-
join(cwd, ".opencode", "opencode.json"),
|
|
162
|
-
join(cwd, ".opencode", "opencode.jsonc"),
|
|
163
|
-
]
|
|
164
|
-
: [
|
|
165
|
-
join(home, ".config", "opencode", "opencode.json"),
|
|
166
|
-
join(home, ".config", "opencode", "opencode.jsonc"),
|
|
167
|
-
];
|
|
158
|
+
? [join(cwd, "opencode.json"), join(cwd, ".opencode", "opencode.json")]
|
|
159
|
+
: [join(home, ".config", "opencode", "opencode.json")];
|
|
168
160
|
for (const path of paths) {
|
|
169
161
|
const value = await regular(path);
|
|
170
162
|
if (value.status === "present") {
|
|
171
|
-
|
|
172
|
-
try {
|
|
173
|
-
parsed = parseJsonc(value.raw.toString("utf8"));
|
|
174
|
-
}
|
|
175
|
-
catch {
|
|
176
|
-
parsed = undefined;
|
|
177
|
-
}
|
|
163
|
+
const parsed = json(value.raw);
|
|
178
164
|
return parsed
|
|
179
165
|
? { projection: redactedConfig(parsed), source: path }
|
|
180
166
|
: { incomplete: true, source: path };
|
|
@@ -264,7 +250,7 @@ async function executableAvailable(name) {
|
|
|
264
250
|
}
|
|
265
251
|
return false;
|
|
266
252
|
}
|
|
267
|
-
async function lspFacts(project, partial) {
|
|
253
|
+
async function lspFacts(project, host, partial) {
|
|
268
254
|
const suffixes = new Set();
|
|
269
255
|
let scanIncomplete = false;
|
|
270
256
|
const visit = async (root) => {
|
|
@@ -291,6 +277,7 @@ async function lspFacts(project, partial) {
|
|
|
291
277
|
await visit(project);
|
|
292
278
|
if (scanIncomplete)
|
|
293
279
|
partial.push("lsp.project-files");
|
|
280
|
+
const disabled = process.env.OPENCODE_DISABLE_LSP_DOWNLOAD === "true";
|
|
294
281
|
const servers = await Promise.all(lspCatalog.servers.map(async (server) => {
|
|
295
282
|
let available = false;
|
|
296
283
|
available = await executableAvailable(server.executable);
|
|
@@ -298,20 +285,48 @@ async function lspFacts(project, partial) {
|
|
|
298
285
|
return {
|
|
299
286
|
name: server.name,
|
|
300
287
|
applicable,
|
|
301
|
-
configured:
|
|
288
|
+
configured: applicable,
|
|
302
289
|
binary_available: available,
|
|
303
|
-
active:
|
|
304
|
-
runtime_status: "
|
|
290
|
+
active: applicable && available && !disabled,
|
|
291
|
+
runtime_status: "unavailable",
|
|
305
292
|
requirement_class: server.requirement_class,
|
|
306
|
-
reason:
|
|
293
|
+
reason: !applicable
|
|
294
|
+
? "not-selected"
|
|
295
|
+
: disabled
|
|
296
|
+
? "download-disabled"
|
|
297
|
+
: !available
|
|
298
|
+
? "missing-dependency"
|
|
299
|
+
: "available",
|
|
307
300
|
missing: available ? [] : [server.executable],
|
|
308
301
|
install: `Install ${server.executable} with your project toolchain.`,
|
|
309
302
|
};
|
|
310
303
|
}));
|
|
304
|
+
let runtimeStatus = "unavailable";
|
|
305
|
+
if (host?.lsp) {
|
|
306
|
+
try {
|
|
307
|
+
const value = await host.lsp();
|
|
308
|
+
runtimeStatus = Array.isArray(value)
|
|
309
|
+
? value.map((item) => {
|
|
310
|
+
const entry = item && typeof item === "object" ? item : {};
|
|
311
|
+
return {
|
|
312
|
+
id: typeof entry.id === "string" ? entry.id : "unknown",
|
|
313
|
+
name: typeof entry.name === "string" ? entry.name : "unknown",
|
|
314
|
+
status: entry.status === "connected" || entry.status === "error" ? entry.status : "unknown",
|
|
315
|
+
};
|
|
316
|
+
})
|
|
317
|
+
: { status: "unavailable" };
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
partial.push("lsp.runtime-status");
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
else
|
|
324
|
+
partial.push("lsp.runtime-status");
|
|
311
325
|
return {
|
|
312
326
|
schema_version: 1,
|
|
313
327
|
catalog_version: lspCatalog.catalog_version,
|
|
314
|
-
|
|
328
|
+
download_disabled: disabled,
|
|
329
|
+
runtime_status: runtimeStatus,
|
|
315
330
|
servers,
|
|
316
331
|
};
|
|
317
332
|
}
|
|
@@ -476,7 +491,7 @@ export async function collectDoctorFacts(scope, cwd = process.cwd(), home = home
|
|
|
476
491
|
source: config.source ?? "host-or-file-unavailable",
|
|
477
492
|
}, [
|
|
478
493
|
"Inspect OpenCode configuration without exposing secrets.",
|
|
479
|
-
"Local plugin wrappers in the deployment plugins directory load automatically without a
|
|
494
|
+
"Local plugin wrappers in the deployment plugins directory load automatically without a plugin array entry.",
|
|
480
495
|
]));
|
|
481
496
|
const wired = (config.projection?.enabled_plugins ?? []).includes(packageName) ||
|
|
482
497
|
(hostConfig?.enabled_plugins ?? []).includes(packageName);
|
|
@@ -608,7 +623,7 @@ export async function collectDoctorFacts(scope, cwd = process.cwd(), home = home
|
|
|
608
623
|
}, lifecycleFiles.incomplete
|
|
609
624
|
? ["Resolve inaccessible lifecycle state before applying a mutation."]
|
|
610
625
|
: undefined));
|
|
611
|
-
const tools = await Promise.all(["opencode"].map(async (name) => {
|
|
626
|
+
const tools = await Promise.all(["opencode", ...lspCatalog.servers.map((server) => server.executable)].map(async (name) => {
|
|
612
627
|
try {
|
|
613
628
|
const result = await run(name, ["--version"], { timeout: 1000 });
|
|
614
629
|
return {
|
|
@@ -625,7 +640,7 @@ export async function collectDoctorFacts(scope, cwd = process.cwd(), home = home
|
|
|
625
640
|
}
|
|
626
641
|
}));
|
|
627
642
|
checks.push(check("host.tools", tools.some((item) => item.name === "opencode" && item.available) ? "pass" : "incomplete", "External tool availability is reported", { tools: tools.map((item) => `${item.name}:${item.available ? "available" : "missing"}`) }, ["Install OpenCode or missing external tools when needed."]));
|
|
628
|
-
const lsp = await lspFacts(project, partial);
|
|
643
|
+
const lsp = await lspFacts(project, host, partial);
|
|
629
644
|
const counts = { pass: 0, warn: 0, fail: 0, incomplete: 0 };
|
|
630
645
|
for (const item of checks)
|
|
631
646
|
counts[item.status] += 1;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,123 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
1
|
+
import { type PluginInput } from "@opencode-ai/plugin";
|
|
2
|
+
import rulesInjector, { type RulesInjectorOptions } from "./plugins/rules-injector.js";
|
|
3
|
+
import rtk, { type RtkOptions } from "./plugins/rtk.js";
|
|
4
|
+
import zedBell, { type ZedBellOptions } from "./plugins/zed-bell.js";
|
|
5
5
|
export { rulesInjector, rtk, zedBell };
|
|
6
6
|
export type OpenCodeOptions = {
|
|
7
7
|
rulesInjector?: RulesInjectorOptions;
|
|
8
8
|
rtk?: RtkOptions;
|
|
9
9
|
zedBell?: ZedBellOptions;
|
|
10
10
|
};
|
|
11
|
-
declare const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
declare const plugin: (input: PluginInput) => Promise<{
|
|
12
|
+
tool: {
|
|
13
|
+
route: {
|
|
14
|
+
description: string;
|
|
15
|
+
args: {
|
|
16
|
+
action: import("zod").ZodEnum<{
|
|
17
|
+
dispatch: "dispatch";
|
|
18
|
+
preview: "preview";
|
|
19
|
+
}>;
|
|
20
|
+
category: import("zod").ZodEnum<{
|
|
21
|
+
architecture: "architecture";
|
|
22
|
+
exploration: "exploration";
|
|
23
|
+
implementation: "implementation";
|
|
24
|
+
review: "review";
|
|
25
|
+
}>;
|
|
26
|
+
task: import("zod").ZodString;
|
|
27
|
+
requirements: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodString>>;
|
|
28
|
+
execution_card: import("zod").ZodOptional<import("zod").ZodAny>;
|
|
29
|
+
override: import("zod").ZodOptional<import("zod").ZodString>;
|
|
30
|
+
trusted_override: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
31
|
+
budget: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
32
|
+
cost_class: import("zod").ZodOptional<import("zod").ZodString>;
|
|
33
|
+
latency_class: import("zod").ZodOptional<import("zod").ZodString>;
|
|
34
|
+
}, import("zod/v4/core").$strip>>;
|
|
35
|
+
decision: import("zod").ZodOptional<import("zod").ZodAny>;
|
|
36
|
+
};
|
|
37
|
+
execute(args: {
|
|
38
|
+
action: "dispatch" | "preview";
|
|
39
|
+
category: "architecture" | "exploration" | "implementation" | "review";
|
|
40
|
+
task: string;
|
|
41
|
+
requirements: string[];
|
|
42
|
+
execution_card?: any;
|
|
43
|
+
override?: string | undefined;
|
|
44
|
+
trusted_override?: boolean | undefined;
|
|
45
|
+
budget?: {
|
|
46
|
+
cost_class?: string | undefined;
|
|
47
|
+
latency_class?: string | undefined;
|
|
48
|
+
} | undefined;
|
|
49
|
+
decision?: any;
|
|
50
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<import("@opencode-ai/plugin").ToolResult>;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
"tool.execute.before": (input: {
|
|
54
|
+
tool: string;
|
|
55
|
+
sessionID: string;
|
|
56
|
+
}, output: {
|
|
57
|
+
args: unknown;
|
|
58
|
+
}) => Promise<void>;
|
|
59
|
+
"tool.execute.after": (input: {
|
|
60
|
+
tool: string;
|
|
61
|
+
sessionID: string;
|
|
62
|
+
args: unknown;
|
|
63
|
+
}, output: {
|
|
64
|
+
output: string;
|
|
65
|
+
}) => Promise<void>;
|
|
66
|
+
}>;
|
|
67
|
+
export declare const server: (input: PluginInput) => Promise<{
|
|
68
|
+
tool: {
|
|
69
|
+
route: {
|
|
70
|
+
description: string;
|
|
71
|
+
args: {
|
|
72
|
+
action: import("zod").ZodEnum<{
|
|
73
|
+
dispatch: "dispatch";
|
|
74
|
+
preview: "preview";
|
|
75
|
+
}>;
|
|
76
|
+
category: import("zod").ZodEnum<{
|
|
77
|
+
architecture: "architecture";
|
|
78
|
+
exploration: "exploration";
|
|
79
|
+
implementation: "implementation";
|
|
80
|
+
review: "review";
|
|
81
|
+
}>;
|
|
82
|
+
task: import("zod").ZodString;
|
|
83
|
+
requirements: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodString>>;
|
|
84
|
+
execution_card: import("zod").ZodOptional<import("zod").ZodAny>;
|
|
85
|
+
override: import("zod").ZodOptional<import("zod").ZodString>;
|
|
86
|
+
trusted_override: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
87
|
+
budget: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
88
|
+
cost_class: import("zod").ZodOptional<import("zod").ZodString>;
|
|
89
|
+
latency_class: import("zod").ZodOptional<import("zod").ZodString>;
|
|
90
|
+
}, import("zod/v4/core").$strip>>;
|
|
91
|
+
decision: import("zod").ZodOptional<import("zod").ZodAny>;
|
|
92
|
+
};
|
|
93
|
+
execute(args: {
|
|
94
|
+
action: "dispatch" | "preview";
|
|
95
|
+
category: "architecture" | "exploration" | "implementation" | "review";
|
|
96
|
+
task: string;
|
|
97
|
+
requirements: string[];
|
|
98
|
+
execution_card?: any;
|
|
99
|
+
override?: string | undefined;
|
|
100
|
+
trusted_override?: boolean | undefined;
|
|
101
|
+
budget?: {
|
|
102
|
+
cost_class?: string | undefined;
|
|
103
|
+
latency_class?: string | undefined;
|
|
104
|
+
} | undefined;
|
|
105
|
+
decision?: any;
|
|
106
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<import("@opencode-ai/plugin").ToolResult>;
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
"tool.execute.before": (input: {
|
|
110
|
+
tool: string;
|
|
111
|
+
sessionID: string;
|
|
112
|
+
}, output: {
|
|
113
|
+
args: unknown;
|
|
114
|
+
}) => Promise<void>;
|
|
115
|
+
"tool.execute.after": (input: {
|
|
116
|
+
tool: string;
|
|
117
|
+
sessionID: string;
|
|
118
|
+
args: unknown;
|
|
119
|
+
}, output: {
|
|
120
|
+
output: string;
|
|
121
|
+
}) => Promise<void>;
|
|
122
|
+
}>;
|
|
123
|
+
export default plugin;
|