@kisev/agentomatic 11.0.0-dev.81.g683e7ae64567 → 11.0.2-dev.101.gae2702b7284e
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 +25 -12
- package/README.ru.md +25 -11
- package/dist/agent-profiles.js +33 -48
- package/dist/assets/agents/architect.md +4 -4
- package/dist/assets/agents/critic.md +10 -11
- package/dist/assets/agents/manager.md +11 -12
- package/dist/assets/agents/mapper.md +4 -4
- package/dist/assets/agents/review.md +11 -12
- package/dist/assets/agents/worker.md +29 -32
- package/dist/assets/commands/rtk-stats.md +2 -2
- package/dist/cli.js +8 -5
- package/dist/config-setup.d.ts +2 -7
- package/dist/config-setup.js +82 -53
- package/dist/contracts.js +26 -0
- package/dist/doctor.d.ts +0 -1
- package/dist/doctor.js +34 -53
- package/dist/index.d.ts +2 -128
- package/dist/index.js +109 -168
- package/dist/jsonc.d.ts +12 -1
- package/dist/jsonc.js +82 -5
- package/dist/opencode-config.d.ts +9 -0
- package/dist/opencode-config.js +158 -0
- package/dist/plugins/events.d.ts +20 -0
- package/dist/plugins/events.js +48 -0
- package/dist/plugins/rtk.d.ts +4 -17
- package/dist/plugins/rtk.js +15 -7
- package/dist/plugins/rules-injector.d.ts +15 -28
- package/dist/plugins/rules-injector.js +38 -33
- package/dist/plugins/zed-bell.d.ts +2 -13
- package/dist/plugins/zed-bell.js +5 -4
- package/dist/registry.js +1 -1
- package/dist/routing.d.ts +5 -3
- package/dist/routing.js +57 -22
- package/package.json +2 -7
- package/dist/plugins/compatibility.d.ts +0 -30
- package/dist/plugins/compatibility.js +0 -87
package/dist/config-setup.js
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
2
1
|
import { randomUUID } from "node:crypto";
|
|
3
2
|
import { lstat } from "node:fs/promises";
|
|
4
3
|
import { homedir } from "node:os";
|
|
5
|
-
import {
|
|
6
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
7
5
|
import { archiveMutations } from "./installer.js";
|
|
8
6
|
import { requirePackageVersion } from "./package-metadata.js";
|
|
9
7
|
import { ensureDependency, planDependency } from "./self-install.js";
|
|
10
8
|
import { applyTransaction, archiveRoot, deploymentRoot, LifecycleError, lifecycleRoot, inspectTransaction, readRegular, recoverTransaction, sha256, withLifecycleLock, } from "./lifecycle.js";
|
|
11
9
|
import { applyJsoncEdits, parseJsonc } from "./jsonc.js";
|
|
10
|
+
import { corePluginEdits, permissionEdits } from "./opencode-config.js";
|
|
12
11
|
const PACKAGE_NAME = "@kisev/agentomatic";
|
|
13
|
-
const LEGACY_PACKAGE_NAME = "@kisev/skills-opencode";
|
|
14
|
-
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
15
12
|
const XDG_STATE_GLOB = "~/.local/state/agent-skills/**";
|
|
16
13
|
const OPENCODE_SKILLS_GLOB = "~/.config/opencode/skills/**";
|
|
14
|
+
const AGENTS_SKILLS_GLOB = "~/.agents/skills/**";
|
|
17
15
|
const SECRET_PATHS = [
|
|
18
16
|
"**/.env",
|
|
19
17
|
"**/.env.*",
|
|
@@ -48,16 +46,10 @@ export const CONFIG_FRAGMENTS = [
|
|
|
48
46
|
},
|
|
49
47
|
{
|
|
50
48
|
name: "skills-state-permissions",
|
|
51
|
-
description: "Allow the
|
|
49
|
+
description: "Allow the canonical ~/.agents/skills tree and legacy skills state paths without per-run prompts",
|
|
52
50
|
targets: ["opencode", "kilo", "mimo"],
|
|
53
51
|
file: "main",
|
|
54
52
|
},
|
|
55
|
-
{
|
|
56
|
-
name: "lsp-preset",
|
|
57
|
-
description: "Add LSP servers from the shared catalog (OpenCode only)",
|
|
58
|
-
targets: ["opencode"],
|
|
59
|
-
file: "main",
|
|
60
|
-
},
|
|
61
53
|
{
|
|
62
54
|
name: "secrets-guard",
|
|
63
55
|
description: "Deny reads and edits of common secret files",
|
|
@@ -72,7 +64,7 @@ export const CONFIG_FRAGMENTS = [
|
|
|
72
64
|
},
|
|
73
65
|
{
|
|
74
66
|
name: "tui-schema",
|
|
75
|
-
description: "
|
|
67
|
+
description: "Configure terminal settings: OpenCode V2 cli.json or Kilo/MiMo TUI files",
|
|
76
68
|
targets: ["opencode", "kilo", "mimo"],
|
|
77
69
|
file: "tui",
|
|
78
70
|
},
|
|
@@ -137,23 +129,26 @@ const UNIFIED_TUI_KEYBINDS = {
|
|
|
137
129
|
messages_toggle_conceal: "<leader>h,<leader>р",
|
|
138
130
|
tips_toggle: "<leader>h,<leader>р",
|
|
139
131
|
};
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
132
|
+
const OPENCODE_KEYBINDS = {
|
|
133
|
+
"command.palette.show": "alt+p",
|
|
134
|
+
"app.exit": "ctrl+d,<leader>q,<leader>й",
|
|
135
|
+
"session.first": "ctrl+g",
|
|
136
|
+
"session.last": "ctrl+alt+g",
|
|
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>к",
|
|
145
151
|
};
|
|
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
|
-
}
|
|
157
152
|
function mapAllowsAll(value) {
|
|
158
153
|
return Boolean(value &&
|
|
159
154
|
typeof value === "object" &&
|
|
@@ -171,21 +166,28 @@ function fragmentEdits(fragment, target, current) {
|
|
|
171
166
|
? value.permission
|
|
172
167
|
: {};
|
|
173
168
|
if (fragment === "core-plugin") {
|
|
174
|
-
|
|
175
|
-
return [
|
|
176
|
-
{ kind: "set-if-absent", path: ["$schema"], value: "https://opencode.ai/config.json" },
|
|
177
|
-
{ kind: "set-if-absent", path: [key], value: [] },
|
|
178
|
-
{
|
|
179
|
-
kind: "replace-array-value",
|
|
180
|
-
path: [key],
|
|
181
|
-
from: LEGACY_PACKAGE_NAME,
|
|
182
|
-
to: PACKAGE_NAME,
|
|
183
|
-
},
|
|
184
|
-
{ kind: "append-unique", path: [key], value: PACKAGE_NAME },
|
|
185
|
-
];
|
|
169
|
+
return corePluginEdits(value);
|
|
186
170
|
}
|
|
187
171
|
if (fragment === "skills-state-permissions") {
|
|
188
|
-
const statePaths = target === "opencode"
|
|
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
|
+
// Directory enumeration (glob/list) targets the roots themselves, which
|
|
183
|
+
// the tree globs above do not match; allow those exact directories.
|
|
184
|
+
...statePaths.map((resource) => ({
|
|
185
|
+
action: "external_directory",
|
|
186
|
+
resource: resource.replace(/\/\*\*$/, ""),
|
|
187
|
+
effect: "allow",
|
|
188
|
+
})),
|
|
189
|
+
{ action: "external_directory", resource: "~/.agents", effect: "allow" },
|
|
190
|
+
]);
|
|
189
191
|
const edits = [];
|
|
190
192
|
if (!mapAllowsAll(permission.read))
|
|
191
193
|
edits.push(...permissionMapEdits(["permission", "read"], Object.fromEntries(statePaths.map((glob) => [glob, "allow"]))));
|
|
@@ -195,14 +197,15 @@ function fragmentEdits(fragment, target, current) {
|
|
|
195
197
|
edits.push(...permissionMapEdits(["permission", "external_directory"], Object.fromEntries(statePaths.map((glob) => [glob, "allow"]))));
|
|
196
198
|
return edits;
|
|
197
199
|
}
|
|
198
|
-
if (fragment === "lsp-preset") {
|
|
199
|
-
return lspCatalog().map((server) => ({
|
|
200
|
-
kind: "set-if-absent",
|
|
201
|
-
path: ["lsp", server.name],
|
|
202
|
-
value: { command: LSP_SERVER_COMMANDS[server.name], extensions: server.extensions },
|
|
203
|
-
}));
|
|
204
|
-
}
|
|
205
200
|
if (fragment === "secrets-guard") {
|
|
201
|
+
if (target === "opencode")
|
|
202
|
+
return permissionEdits(value, [
|
|
203
|
+
...SECRET_PATHS.flatMap((glob) => [
|
|
204
|
+
{ action: "read", resource: glob.replace(/^\*\*\//, "*"), effect: "deny" },
|
|
205
|
+
{ action: "edit", resource: glob.replace(/^\*\*\//, "*"), effect: "deny" },
|
|
206
|
+
]),
|
|
207
|
+
{ action: "read", resource: "*.env.example", effect: "allow" },
|
|
208
|
+
]);
|
|
206
209
|
const deny = Object.fromEntries(SECRET_PATHS.map((glob) => [glob, "deny"]));
|
|
207
210
|
return [
|
|
208
211
|
...permissionMapEdits(["permission", "read"], {
|
|
@@ -220,8 +223,18 @@ function fragmentEdits(fragment, target, current) {
|
|
|
220
223
|
{ kind: "set-if-absent", path: ["mcp_tool_display"], value: "expanded" },
|
|
221
224
|
];
|
|
222
225
|
}
|
|
226
|
+
if (target === "opencode")
|
|
227
|
+
return [
|
|
228
|
+
{ kind: "set-if-absent", path: ["$schema"], value: "https://opencode.ai/v2/cli.json" },
|
|
229
|
+
{ kind: "set-if-absent", path: ["theme", "name"], value: "ayu" },
|
|
230
|
+
...Object.entries(OPENCODE_KEYBINDS).map(([key, value]) => ({
|
|
231
|
+
kind: "set-if-absent",
|
|
232
|
+
path: ["keybinds", key],
|
|
233
|
+
value,
|
|
234
|
+
})),
|
|
235
|
+
];
|
|
223
236
|
const tuiSchemas = {
|
|
224
|
-
opencode:
|
|
237
|
+
opencode: undefined,
|
|
225
238
|
kilo: undefined,
|
|
226
239
|
mimo: "https://mimo.xiaomi.com/mimocode/tui.json",
|
|
227
240
|
};
|
|
@@ -309,9 +322,9 @@ async function resolveTargetFile(target, scope, cwd, home, kind = "main") {
|
|
|
309
322
|
return {
|
|
310
323
|
target,
|
|
311
324
|
root: globalRoot,
|
|
312
|
-
path: "
|
|
313
|
-
absolute: join(globalRoot, "
|
|
314
|
-
exists: await existing(globalRoot, "
|
|
325
|
+
path: "cli.json",
|
|
326
|
+
absolute: join(globalRoot, "cli.json"),
|
|
327
|
+
exists: await existing(globalRoot, "cli.json"),
|
|
315
328
|
};
|
|
316
329
|
}
|
|
317
330
|
if (target === "opencode") {
|
|
@@ -405,6 +418,20 @@ async function build(selection, scope, cwd = process.cwd(), home = homedir()) {
|
|
|
405
418
|
for (const fragment of selection.fragments) {
|
|
406
419
|
if (!applicable(fragment, target) || fragmentFileKind(fragment) !== kind)
|
|
407
420
|
continue;
|
|
421
|
+
if (target === "opencode" &&
|
|
422
|
+
kind === "tui" &&
|
|
423
|
+
!file.exists &&
|
|
424
|
+
((await readRegular(join(file.root, "tui.json"))) ||
|
|
425
|
+
(await readRegular(join(file.root, "tui.jsonc"))))) {
|
|
426
|
+
operations.push({
|
|
427
|
+
target,
|
|
428
|
+
path: file.absolute,
|
|
429
|
+
fragment,
|
|
430
|
+
operation: "conflict",
|
|
431
|
+
reason: "Start OpenCode V2 once to migrate existing TUI preferences into cli.json before applying terminal presets",
|
|
432
|
+
});
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
408
435
|
let parsed = undefined;
|
|
409
436
|
try {
|
|
410
437
|
parsed = parseJsonc(text);
|
|
@@ -575,6 +602,8 @@ export async function applyConfigSetup(selection, scope, cwd = process.cwd(), ho
|
|
|
575
602
|
await provision();
|
|
576
603
|
return built.plan;
|
|
577
604
|
}
|
|
605
|
+
if (!built.plan.operations.some((operation) => operation.operation === "conflict"))
|
|
606
|
+
return built.plan;
|
|
578
607
|
throw new ConfigSetupError("invalid_state", "Config setup plan has no applicable changes");
|
|
579
608
|
}
|
|
580
609
|
const backups = [];
|
package/dist/contracts.js
CHANGED
|
@@ -9,6 +9,32 @@ function strings(value) {
|
|
|
9
9
|
export function validateAgentReport(agent, report, card) {
|
|
10
10
|
if (!object(report))
|
|
11
11
|
throw new Error("agent report must be an object");
|
|
12
|
+
if ((agent === "review" || agent === "critic") &&
|
|
13
|
+
!card &&
|
|
14
|
+
report.schema === "portable-gitlab/critic-receipt/v2") {
|
|
15
|
+
const required = [
|
|
16
|
+
"schema",
|
|
17
|
+
"evidence_digest",
|
|
18
|
+
"run_id",
|
|
19
|
+
"session_id",
|
|
20
|
+
"findings",
|
|
21
|
+
"external_mutations",
|
|
22
|
+
];
|
|
23
|
+
const allowed = [...required, "scope_digest", "target_finding_ids"];
|
|
24
|
+
if (!required.every((key) => key in report) ||
|
|
25
|
+
Object.keys(report).some((key) => !allowed.includes(key)) ||
|
|
26
|
+
!/^[0-9a-f]{64}$/.test(String(report.evidence_digest)) ||
|
|
27
|
+
typeof report.run_id !== "string" ||
|
|
28
|
+
!report.run_id ||
|
|
29
|
+
typeof report.session_id !== "string" ||
|
|
30
|
+
!report.session_id ||
|
|
31
|
+
!Array.isArray(report.findings) ||
|
|
32
|
+
report.external_mutations !== false ||
|
|
33
|
+
("scope_digest" in report && !/^[0-9a-f]{64}$/.test(String(report.scope_digest))) ||
|
|
34
|
+
("target_finding_ids" in report && !strings(report.target_finding_ids)))
|
|
35
|
+
throw new Error("code-review critic receipt has an invalid transport envelope");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
12
38
|
if (agent === "critic" && !card && "review_report" in report) {
|
|
13
39
|
validateAgentReport("review", report);
|
|
14
40
|
return;
|
package/dist/doctor.d.ts
CHANGED
package/dist/doctor.js
CHANGED
|
@@ -12,6 +12,7 @@ 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";
|
|
15
16
|
import { readRtkStats, rtkCharsSaved, rtkStatsPath, rtkTokensSavedEstimate, } from "./plugins/rtk.js";
|
|
16
17
|
import { stateRoot } from "./runtime/state.js";
|
|
17
18
|
const run = promisify(execFile);
|
|
@@ -114,20 +115,19 @@ function agentManifestValid(raw) {
|
|
|
114
115
|
}
|
|
115
116
|
function redactedConfig(value) {
|
|
116
117
|
const object = value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
117
|
-
const configuredPlugins = object.plugins
|
|
118
|
+
const configuredPlugins = object.plugins;
|
|
118
119
|
const rawPlugins = Array.isArray(configuredPlugins)
|
|
119
120
|
? configuredPlugins.flatMap((item) => {
|
|
120
121
|
if (typeof item === "string")
|
|
121
122
|
return [item];
|
|
122
|
-
if (Array.isArray(item) && typeof item[0] === "string")
|
|
123
|
-
return [item[0]];
|
|
124
123
|
if (item && typeof item === "object" && typeof item.package === "string")
|
|
125
124
|
return [item.package];
|
|
126
125
|
return [];
|
|
127
126
|
})
|
|
128
127
|
: [];
|
|
129
128
|
const knownPlugins = new Set([packageName, ...CATALOG.plugins]);
|
|
130
|
-
const
|
|
129
|
+
const normalizePlugin = (plugin) => plugin === packageName || plugin.startsWith(`${packageName}@`) ? packageName : plugin;
|
|
130
|
+
const plugins = rawPlugins.map(normalizePlugin).filter((plugin) => knownPlugins.has(plugin));
|
|
131
131
|
const enabled = plugins.filter((plugin) => plugin === packageName ||
|
|
132
132
|
CATALOG.plugins.includes(plugin));
|
|
133
133
|
return {
|
|
@@ -138,18 +138,14 @@ function redactedConfig(value) {
|
|
|
138
138
|
keys: Object.keys(object)
|
|
139
139
|
.filter((key) => [
|
|
140
140
|
"$schema",
|
|
141
|
-
"
|
|
142
|
-
"keybinds",
|
|
143
|
-
"logLevel",
|
|
144
|
-
"command",
|
|
141
|
+
"commands",
|
|
145
142
|
"watcher",
|
|
146
|
-
"plugin",
|
|
147
143
|
"plugins",
|
|
148
144
|
"lsp",
|
|
149
145
|
"formatter",
|
|
150
|
-
"
|
|
151
|
-
"
|
|
152
|
-
"
|
|
146
|
+
"providers",
|
|
147
|
+
"agents",
|
|
148
|
+
"permissions",
|
|
153
149
|
"compaction",
|
|
154
150
|
"model",
|
|
155
151
|
].includes(key))
|
|
@@ -159,12 +155,26 @@ function redactedConfig(value) {
|
|
|
159
155
|
}
|
|
160
156
|
async function localConfig(scope, cwd, home) {
|
|
161
157
|
const paths = scope === "project"
|
|
162
|
-
? [
|
|
163
|
-
|
|
158
|
+
? [
|
|
159
|
+
join(cwd, "opencode.json"),
|
|
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
|
+
];
|
|
164
168
|
for (const path of paths) {
|
|
165
169
|
const value = await regular(path);
|
|
166
170
|
if (value.status === "present") {
|
|
167
|
-
|
|
171
|
+
let parsed;
|
|
172
|
+
try {
|
|
173
|
+
parsed = parseJsonc(value.raw.toString("utf8"));
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
parsed = undefined;
|
|
177
|
+
}
|
|
168
178
|
return parsed
|
|
169
179
|
? { projection: redactedConfig(parsed), source: path }
|
|
170
180
|
: { incomplete: true, source: path };
|
|
@@ -254,7 +264,7 @@ async function executableAvailable(name) {
|
|
|
254
264
|
}
|
|
255
265
|
return false;
|
|
256
266
|
}
|
|
257
|
-
async function lspFacts(project,
|
|
267
|
+
async function lspFacts(project, partial) {
|
|
258
268
|
const suffixes = new Set();
|
|
259
269
|
let scanIncomplete = false;
|
|
260
270
|
const visit = async (root) => {
|
|
@@ -281,7 +291,6 @@ async function lspFacts(project, host, partial) {
|
|
|
281
291
|
await visit(project);
|
|
282
292
|
if (scanIncomplete)
|
|
283
293
|
partial.push("lsp.project-files");
|
|
284
|
-
const disabled = process.env.OPENCODE_DISABLE_LSP_DOWNLOAD === "true";
|
|
285
294
|
const servers = await Promise.all(lspCatalog.servers.map(async (server) => {
|
|
286
295
|
let available = false;
|
|
287
296
|
available = await executableAvailable(server.executable);
|
|
@@ -289,48 +298,20 @@ async function lspFacts(project, host, partial) {
|
|
|
289
298
|
return {
|
|
290
299
|
name: server.name,
|
|
291
300
|
applicable,
|
|
292
|
-
configured:
|
|
301
|
+
configured: false,
|
|
293
302
|
binary_available: available,
|
|
294
|
-
active:
|
|
295
|
-
runtime_status: "
|
|
303
|
+
active: false,
|
|
304
|
+
runtime_status: "unsupported",
|
|
296
305
|
requirement_class: server.requirement_class,
|
|
297
|
-
reason:
|
|
298
|
-
? "not-selected"
|
|
299
|
-
: disabled
|
|
300
|
-
? "download-disabled"
|
|
301
|
-
: !available
|
|
302
|
-
? "missing-dependency"
|
|
303
|
-
: "available",
|
|
306
|
+
reason: "unsupported-in-opencode-v2",
|
|
304
307
|
missing: available ? [] : [server.executable],
|
|
305
308
|
install: `Install ${server.executable} with your project toolchain.`,
|
|
306
309
|
};
|
|
307
310
|
}));
|
|
308
|
-
let runtimeStatus = "unavailable";
|
|
309
|
-
if (host?.lsp) {
|
|
310
|
-
try {
|
|
311
|
-
const value = await host.lsp();
|
|
312
|
-
runtimeStatus = Array.isArray(value)
|
|
313
|
-
? value.map((item) => {
|
|
314
|
-
const entry = item && typeof item === "object" ? item : {};
|
|
315
|
-
return {
|
|
316
|
-
id: typeof entry.id === "string" ? entry.id : "unknown",
|
|
317
|
-
name: typeof entry.name === "string" ? entry.name : "unknown",
|
|
318
|
-
status: entry.status === "connected" || entry.status === "error" ? entry.status : "unknown",
|
|
319
|
-
};
|
|
320
|
-
})
|
|
321
|
-
: { status: "unavailable" };
|
|
322
|
-
}
|
|
323
|
-
catch {
|
|
324
|
-
partial.push("lsp.runtime-status");
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
else
|
|
328
|
-
partial.push("lsp.runtime-status");
|
|
329
311
|
return {
|
|
330
312
|
schema_version: 1,
|
|
331
313
|
catalog_version: lspCatalog.catalog_version,
|
|
332
|
-
|
|
333
|
-
runtime_status: runtimeStatus,
|
|
314
|
+
runtime_status: "unsupported",
|
|
334
315
|
servers,
|
|
335
316
|
};
|
|
336
317
|
}
|
|
@@ -495,7 +476,7 @@ export async function collectDoctorFacts(scope, cwd = process.cwd(), home = home
|
|
|
495
476
|
source: config.source ?? "host-or-file-unavailable",
|
|
496
477
|
}, [
|
|
497
478
|
"Inspect OpenCode configuration without exposing secrets.",
|
|
498
|
-
"Local plugin wrappers in the deployment plugins directory load automatically without a
|
|
479
|
+
"Local plugin wrappers in the deployment plugins directory load automatically without a plugins array entry.",
|
|
499
480
|
]));
|
|
500
481
|
const wired = (config.projection?.enabled_plugins ?? []).includes(packageName) ||
|
|
501
482
|
(hostConfig?.enabled_plugins ?? []).includes(packageName);
|
|
@@ -627,7 +608,7 @@ export async function collectDoctorFacts(scope, cwd = process.cwd(), home = home
|
|
|
627
608
|
}, lifecycleFiles.incomplete
|
|
628
609
|
? ["Resolve inaccessible lifecycle state before applying a mutation."]
|
|
629
610
|
: undefined));
|
|
630
|
-
const tools = await Promise.all(["opencode"
|
|
611
|
+
const tools = await Promise.all(["opencode"].map(async (name) => {
|
|
631
612
|
try {
|
|
632
613
|
const result = await run(name, ["--version"], { timeout: 1000 });
|
|
633
614
|
return {
|
|
@@ -644,7 +625,7 @@ export async function collectDoctorFacts(scope, cwd = process.cwd(), home = home
|
|
|
644
625
|
}
|
|
645
626
|
}));
|
|
646
627
|
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."]));
|
|
647
|
-
const lsp = await lspFacts(project,
|
|
628
|
+
const lsp = await lspFacts(project, partial);
|
|
648
629
|
const counts = { pass: 0, warn: 0, fail: 0, incomplete: 0 };
|
|
649
630
|
for (const item of checks)
|
|
650
631
|
counts[item.status] += 1;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import type { Plugin
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import { type Category, type RoutingInput } from "./routing.js";
|
|
1
|
+
import type { Plugin } from "@opencode/plugin";
|
|
4
2
|
import { rulesInjector, type RulesInjectorOptions } from "./plugins/rules-injector.js";
|
|
5
3
|
import { rtk, type RtkOptions } from "./plugins/rtk.js";
|
|
6
4
|
import { zedBell, type ZedBellOptions } from "./plugins/zed-bell.js";
|
|
@@ -10,132 +8,8 @@ export type OpenCodeOptions = {
|
|
|
10
8
|
rtk?: RtkOptions;
|
|
11
9
|
zedBell?: ZedBellOptions;
|
|
12
10
|
};
|
|
13
|
-
type RuntimeInput = {
|
|
14
|
-
directory: string;
|
|
15
|
-
client?: {
|
|
16
|
-
app?: {
|
|
17
|
-
agents?: (input: {
|
|
18
|
-
query: {
|
|
19
|
-
directory: string;
|
|
20
|
-
};
|
|
21
|
-
}) => Promise<{
|
|
22
|
-
data?: unknown;
|
|
23
|
-
}>;
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
export declare const server: (input: RuntimeInput) => Promise<{
|
|
28
|
-
tool: {
|
|
29
|
-
route: {
|
|
30
|
-
description: string;
|
|
31
|
-
args: {
|
|
32
|
-
action: z.ZodEnum<{
|
|
33
|
-
dispatch: "dispatch";
|
|
34
|
-
preview: "preview";
|
|
35
|
-
}>;
|
|
36
|
-
category: z.ZodEnum<{
|
|
37
|
-
architecture: "architecture";
|
|
38
|
-
exploration: "exploration";
|
|
39
|
-
implementation: "implementation";
|
|
40
|
-
review: "review";
|
|
41
|
-
}>;
|
|
42
|
-
task: z.ZodString;
|
|
43
|
-
requirements: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
44
|
-
execution_card: z.ZodOptional<z.ZodAny>;
|
|
45
|
-
override: z.ZodOptional<z.ZodString>;
|
|
46
|
-
trusted_override: z.ZodOptional<z.ZodBoolean>;
|
|
47
|
-
budget: z.ZodOptional<z.ZodObject<{
|
|
48
|
-
cost_class: z.ZodOptional<z.ZodString>;
|
|
49
|
-
latency_class: z.ZodOptional<z.ZodString>;
|
|
50
|
-
}, z.core.$strip>>;
|
|
51
|
-
decision: z.ZodOptional<z.ZodAny>;
|
|
52
|
-
};
|
|
53
|
-
execute(args: {
|
|
54
|
-
action: "preview" | "dispatch";
|
|
55
|
-
category: Category;
|
|
56
|
-
task: string;
|
|
57
|
-
requirements: string[];
|
|
58
|
-
execution_card?: unknown;
|
|
59
|
-
override?: string;
|
|
60
|
-
trusted_override?: boolean;
|
|
61
|
-
budget?: RoutingInput["budget"];
|
|
62
|
-
decision?: unknown;
|
|
63
|
-
}, context: {
|
|
64
|
-
sessionID: string;
|
|
65
|
-
}): Promise<string>;
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
"tool.execute.before": (input: {
|
|
69
|
-
tool: string;
|
|
70
|
-
sessionID: string;
|
|
71
|
-
}, output: {
|
|
72
|
-
args: unknown;
|
|
73
|
-
}) => Promise<void>;
|
|
74
|
-
"tool.execute.after": (input: {
|
|
75
|
-
tool: string;
|
|
76
|
-
sessionID: string;
|
|
77
|
-
args: unknown;
|
|
78
|
-
}, output: {
|
|
79
|
-
output: string;
|
|
80
|
-
}) => Promise<void>;
|
|
81
|
-
}>;
|
|
82
11
|
declare const _default: {
|
|
83
12
|
id: string;
|
|
84
|
-
|
|
85
|
-
tool: {
|
|
86
|
-
route: {
|
|
87
|
-
description: string;
|
|
88
|
-
args: {
|
|
89
|
-
action: z.ZodEnum<{
|
|
90
|
-
dispatch: "dispatch";
|
|
91
|
-
preview: "preview";
|
|
92
|
-
}>;
|
|
93
|
-
category: z.ZodEnum<{
|
|
94
|
-
architecture: "architecture";
|
|
95
|
-
exploration: "exploration";
|
|
96
|
-
implementation: "implementation";
|
|
97
|
-
review: "review";
|
|
98
|
-
}>;
|
|
99
|
-
task: z.ZodString;
|
|
100
|
-
requirements: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
101
|
-
execution_card: z.ZodOptional<z.ZodAny>;
|
|
102
|
-
override: z.ZodOptional<z.ZodString>;
|
|
103
|
-
trusted_override: z.ZodOptional<z.ZodBoolean>;
|
|
104
|
-
budget: z.ZodOptional<z.ZodObject<{
|
|
105
|
-
cost_class: z.ZodOptional<z.ZodString>;
|
|
106
|
-
latency_class: z.ZodOptional<z.ZodString>;
|
|
107
|
-
}, z.core.$strip>>;
|
|
108
|
-
decision: z.ZodOptional<z.ZodAny>;
|
|
109
|
-
};
|
|
110
|
-
execute(args: {
|
|
111
|
-
action: "preview" | "dispatch";
|
|
112
|
-
category: Category;
|
|
113
|
-
task: string;
|
|
114
|
-
requirements: string[];
|
|
115
|
-
execution_card?: unknown;
|
|
116
|
-
override?: string;
|
|
117
|
-
trusted_override?: boolean;
|
|
118
|
-
budget?: RoutingInput["budget"];
|
|
119
|
-
decision?: unknown;
|
|
120
|
-
}, context: {
|
|
121
|
-
sessionID: string;
|
|
122
|
-
}): Promise<string>;
|
|
123
|
-
};
|
|
124
|
-
};
|
|
125
|
-
"tool.execute.before": (input: {
|
|
126
|
-
tool: string;
|
|
127
|
-
sessionID: string;
|
|
128
|
-
}, output: {
|
|
129
|
-
args: unknown;
|
|
130
|
-
}) => Promise<void>;
|
|
131
|
-
"tool.execute.after": (input: {
|
|
132
|
-
tool: string;
|
|
133
|
-
sessionID: string;
|
|
134
|
-
args: unknown;
|
|
135
|
-
}, output: {
|
|
136
|
-
output: string;
|
|
137
|
-
}) => Promise<void>;
|
|
138
|
-
}>;
|
|
139
|
-
setup(ctx: V2Plugin.Context): Promise<(() => Promise<void>) | undefined>;
|
|
13
|
+
setup(ctx: Plugin.Context): Promise<void>;
|
|
140
14
|
};
|
|
141
15
|
export default _default;
|