@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.
@@ -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 { dirname, join, resolve } from "node:path";
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 standard skills XDG state paths without per-run prompts",
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: "Unify each agent TUI file: schema, theme, stacked diffs, and leader keybinds",
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 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"],
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
- const key = "plugins" in value ? "plugins" : "plugin";
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" ? [XDG_STATE_GLOB, OPENCODE_SKILLS_GLOB] : [XDG_STATE_GLOB];
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: "https://opencode.ai/tui.json",
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: "tui.json",
313
- absolute: join(globalRoot, "tui.json"),
314
- exists: await existing(globalRoot, "tui.json"),
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
@@ -9,7 +9,6 @@ export type DoctorCheck = {
9
9
  };
10
10
  export type DoctorHost = {
11
11
  config?: () => Promise<unknown>;
12
- lsp?: () => Promise<unknown>;
13
12
  };
14
13
  export type DoctorReport = {
15
14
  schema_version: 1;
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 ?? object.plugin;
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 plugins = rawPlugins.filter((plugin) => knownPlugins.has(plugin));
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
- "theme",
142
- "keybinds",
143
- "logLevel",
144
- "command",
141
+ "commands",
145
142
  "watcher",
146
- "plugin",
147
143
  "plugins",
148
144
  "lsp",
149
145
  "formatter",
150
- "provider",
151
- "agent",
152
- "permission",
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
- ? [join(cwd, "opencode.json"), join(cwd, ".opencode", "opencode.json")]
163
- : [join(home, ".config", "opencode", "opencode.json")];
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
- const parsed = json(value.raw);
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, host, partial) {
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: applicable,
301
+ configured: false,
293
302
  binary_available: available,
294
- active: applicable && available && !disabled,
295
- runtime_status: "unavailable",
303
+ active: false,
304
+ runtime_status: "unsupported",
296
305
  requirement_class: server.requirement_class,
297
- reason: !applicable
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
- download_disabled: disabled,
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 plugin array entry.",
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", ...lspCatalog.servers.map((server) => server.executable)].map(async (name) => {
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, host, partial);
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 as V2Plugin } from "@opencode/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
- server: (input: RuntimeInput) => Promise<{
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;