@kisev/agentomatic 11.0.0-dev.76.ge1ca4a43f0f3 → 11.0.0-dev.77.g09da04664b2e

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 CHANGED
@@ -61,7 +61,7 @@ migration guide](../../docs/how-to/memomatic.md).
61
61
  ## Requirements
62
62
 
63
63
  - Node.js 22 or later.
64
- - OpenCode `>=1.18.29 <1.19.0`.
64
+ - OpenCode `>=1.18.0 <1.19.0 || >=2.0.0 <2.1.0`.
65
65
  - A persistent npm project that owns the dependency.
66
66
 
67
67
  ## Project Install
package/README.ru.md CHANGED
@@ -63,7 +63,7 @@ Agentomatic не зависит от memomatic. См. [настройку MCP и
63
63
  ## Требования
64
64
 
65
65
  - Node.js 22 или новее.
66
- - OpenCode `>=1.18.29 <1.19.0`.
66
+ - OpenCode `>=1.18.0 <1.19.0 || >=2.0.0 <2.1.0`.
67
67
  - Постоянный npm-проект, которому принадлежит зависимость.
68
68
 
69
69
  ## Установка в проект
@@ -1,3 +1,3 @@
1
1
  import plugin from "@kisev/agentomatic/plugins/rtk";
2
2
 
3
- export default (input) => plugin(input);
3
+ export default plugin;
@@ -1,3 +1,3 @@
1
1
  import plugin from "@kisev/agentomatic/plugins/rules-injector";
2
2
 
3
- export default (input) => plugin(input);
3
+ export default plugin;
@@ -1,3 +1,3 @@
1
1
  import plugin from "@kisev/agentomatic/plugins/zed-bell";
2
2
 
3
- export default (input) => plugin(input, { enabled: false });
3
+ export default plugin;
@@ -171,16 +171,17 @@ function fragmentEdits(fragment, target, current) {
171
171
  ? value.permission
172
172
  : {};
173
173
  if (fragment === "core-plugin") {
174
+ const key = "plugins" in value ? "plugins" : "plugin";
174
175
  return [
175
176
  { kind: "set-if-absent", path: ["$schema"], value: "https://opencode.ai/config.json" },
176
- { kind: "set-if-absent", path: ["plugin"], value: [] },
177
+ { kind: "set-if-absent", path: [key], value: [] },
177
178
  {
178
179
  kind: "replace-array-value",
179
- path: ["plugin"],
180
+ path: [key],
180
181
  from: LEGACY_PACKAGE_NAME,
181
182
  to: PACKAGE_NAME,
182
183
  },
183
- { kind: "append-unique", path: ["plugin"], value: PACKAGE_NAME },
184
+ { kind: "append-unique", path: [key], value: PACKAGE_NAME },
184
185
  ];
185
186
  }
186
187
  if (fragment === "skills-state-permissions") {
package/dist/doctor.js CHANGED
@@ -114,12 +114,15 @@ function agentManifestValid(raw) {
114
114
  }
115
115
  function redactedConfig(value) {
116
116
  const object = value && typeof value === "object" && !Array.isArray(value) ? value : {};
117
- const rawPlugins = Array.isArray(object.plugin)
118
- ? object.plugin.flatMap((item) => {
117
+ const configuredPlugins = object.plugins ?? object.plugin;
118
+ const rawPlugins = Array.isArray(configuredPlugins)
119
+ ? configuredPlugins.flatMap((item) => {
119
120
  if (typeof item === "string")
120
121
  return [item];
121
122
  if (Array.isArray(item) && typeof item[0] === "string")
122
123
  return [item[0]];
124
+ if (item && typeof item === "object" && typeof item.package === "string")
125
+ return [item.package];
123
126
  return [];
124
127
  })
125
128
  : [];
@@ -141,6 +144,7 @@ function redactedConfig(value) {
141
144
  "command",
142
145
  "watcher",
143
146
  "plugin",
147
+ "plugins",
144
148
  "lsp",
145
149
  "formatter",
146
150
  "provider",
package/dist/index.d.ts CHANGED
@@ -1,109 +1,68 @@
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";
1
+ import type { Plugin as V2Plugin } from "@opencode/plugin";
2
+ import { z } from "zod";
3
+ import { type Category, type RoutingInput } from "./routing.js";
4
+ import { rulesInjector, type RulesInjectorOptions } from "./plugins/rules-injector.js";
5
+ import { rtk, type RtkOptions } from "./plugins/rtk.js";
6
+ import { zedBell, type ZedBellOptions } from "./plugins/zed-bell.js";
5
7
  export { rulesInjector, rtk, zedBell };
6
8
  export type OpenCodeOptions = {
7
9
  rulesInjector?: RulesInjectorOptions;
8
10
  rtk?: RtkOptions;
9
11
  zedBell?: ZedBellOptions;
10
12
  };
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>;
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
+ }>;
51
24
  };
52
25
  };
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<{
26
+ };
27
+ export declare const server: (input: RuntimeInput) => Promise<{
68
28
  tool: {
69
29
  route: {
70
30
  description: string;
71
31
  args: {
72
- action: import("zod").ZodEnum<{
32
+ action: z.ZodEnum<{
73
33
  dispatch: "dispatch";
74
34
  preview: "preview";
75
35
  }>;
76
- category: import("zod").ZodEnum<{
36
+ category: z.ZodEnum<{
77
37
  architecture: "architecture";
78
38
  exploration: "exploration";
79
39
  implementation: "implementation";
80
40
  review: "review";
81
41
  }>;
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>;
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>;
92
52
  };
93
53
  execute(args: {
94
- action: "dispatch" | "preview";
95
- category: "architecture" | "exploration" | "implementation" | "review";
54
+ action: "preview" | "dispatch";
55
+ category: Category;
96
56
  task: string;
97
57
  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>;
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>;
107
66
  };
108
67
  };
109
68
  "tool.execute.before": (input: {
@@ -120,4 +79,63 @@ export declare const server: (input: PluginInput) => Promise<{
120
79
  output: string;
121
80
  }) => Promise<void>;
122
81
  }>;
123
- export default plugin;
82
+ declare const _default: {
83
+ 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>;
140
+ };
141
+ export default _default;
package/dist/index.js CHANGED
@@ -1,8 +1,9 @@
1
- import { tool } from "@opencode-ai/plugin";
1
+ import { z } from "zod";
2
+ import { registerV2Hooks } from "./plugins/compatibility.js";
2
3
  import { CATEGORIES, RoutingGate, } from "./routing.js";
3
- import rulesInjector from "./plugins/rules-injector.js";
4
- import rtk from "./plugins/rtk.js";
5
- import zedBell from "./plugins/zed-bell.js";
4
+ import { rulesInjector } from "./plugins/rules-injector.js";
5
+ import { rtk } from "./plugins/rtk.js";
6
+ import { zedBell } from "./plugins/zed-bell.js";
6
7
  import { digest } from "./lifecycle.js";
7
8
  export { rulesInjector, rtk, zedBell };
8
9
  const plugin = (async (input) => {
@@ -44,23 +45,23 @@ const plugin = (async (input) => {
44
45
  });
45
46
  return { agents, revision: digest(raw) };
46
47
  };
47
- const route = tool({
48
+ const route = {
48
49
  description: "Resolve a capability category and dispatch one eligible agent through a one-use Task receipt gate.",
49
50
  args: {
50
- action: tool.schema.enum(["preview", "dispatch"]),
51
- category: tool.schema.enum(CATEGORIES),
52
- task: tool.schema.string(),
53
- requirements: tool.schema.array(tool.schema.string()).default([]),
54
- execution_card: tool.schema.any().optional(),
55
- override: tool.schema.string().optional(),
56
- trusted_override: tool.schema.boolean().optional(),
57
- budget: tool.schema
51
+ action: z.enum(["preview", "dispatch"]),
52
+ category: z.enum(CATEGORIES),
53
+ task: z.string(),
54
+ requirements: z.array(z.string()).default([]),
55
+ execution_card: z.any().optional(),
56
+ override: z.string().optional(),
57
+ trusted_override: z.boolean().optional(),
58
+ budget: z
58
59
  .object({
59
- cost_class: tool.schema.string().optional(),
60
- latency_class: tool.schema.string().optional(),
60
+ cost_class: z.string().optional(),
61
+ latency_class: z.string().optional(),
61
62
  })
62
63
  .optional(),
63
- decision: tool.schema.any().optional(),
64
+ decision: z.any().optional(),
64
65
  },
65
66
  async execute(args, context) {
66
67
  const inventory = await hostInventory();
@@ -87,7 +88,7 @@ const plugin = (async (input) => {
87
88
  });
88
89
  return JSON.stringify({ decision, receipt, status: "routed" });
89
90
  },
90
- });
91
+ };
91
92
  return {
92
93
  tool: { route },
93
94
  "tool.execute.before": async (input, output) => {
@@ -137,4 +138,54 @@ const plugin = (async (input) => {
137
138
  };
138
139
  });
139
140
  export const server = plugin;
140
- export default plugin;
141
+ export default {
142
+ id: "agentomatic",
143
+ server,
144
+ async setup(ctx) {
145
+ const hooks = await plugin({
146
+ directory: ctx.location.directory,
147
+ client: {
148
+ app: {
149
+ agents: async () => {
150
+ const { data: agents } = await ctx.agent.list({
151
+ location: { directory: ctx.location.directory },
152
+ });
153
+ return {
154
+ data: agents.map((agent) => ({
155
+ name: agent.id,
156
+ tools: Object.fromEntries(["read", "glob", "grep", "edit", "bash"].map((tool) => [
157
+ tool,
158
+ [...agent.permissions]
159
+ .reverse()
160
+ .find((rule) => (rule.action === (tool === "bash" ? "shell" : tool) ||
161
+ rule.action === "*") &&
162
+ rule.resource === "*")?.effect !== "deny",
163
+ ])),
164
+ permission: {
165
+ edit: agent.permissions.some((rule) => rule.action === "edit" && rule.resource === "*" && rule.effect === "deny")
166
+ ? "deny"
167
+ : "allow",
168
+ bash: Object.fromEntries(agent.permissions
169
+ .filter((rule) => rule.action === "shell")
170
+ .map((rule) => [rule.resource, rule.effect])),
171
+ },
172
+ })),
173
+ };
174
+ },
175
+ },
176
+ },
177
+ });
178
+ await ctx.tool.transform((editor) => {
179
+ const route = hooks.tool.route;
180
+ editor.add({
181
+ name: "route",
182
+ description: route.description,
183
+ input: z.object(route.args),
184
+ async execute(args, context) {
185
+ return { content: await route.execute(args, context) };
186
+ },
187
+ });
188
+ });
189
+ return registerV2Hooks(ctx, hooks);
190
+ },
191
+ };
@@ -0,0 +1,30 @@
1
+ import type { Plugin } from "@opencode/plugin";
2
+ type Input = {
3
+ tool: string;
4
+ sessionID: string;
5
+ args: Record<string, unknown>;
6
+ directory?: string;
7
+ };
8
+ type Hooks = {
9
+ "tool.execute.before"?: (input: Input, output: {
10
+ args: unknown;
11
+ }) => Promise<void>;
12
+ "tool.execute.after"?: (input: Input, output: {
13
+ output: string;
14
+ }) => Promise<void>;
15
+ event?: (input: {
16
+ event: {
17
+ type: string;
18
+ properties?: Record<string, unknown>;
19
+ };
20
+ }) => Promise<void>;
21
+ "experimental.chat.system.transform"?: (input: {
22
+ sessionID: string;
23
+ }, output: {
24
+ system: string[];
25
+ }) => Promise<void>;
26
+ };
27
+ export declare function registerV2Hooks(ctx: Plugin.Context, hooks: Hooks, options?: {
28
+ sessionDirectory?: boolean;
29
+ }): Promise<(() => Promise<void>) | undefined>;
30
+ export {};
@@ -0,0 +1,87 @@
1
+ function toolName(name) {
2
+ return name === "shell" ? "bash" : name === "subagent" ? "task" : name;
3
+ }
4
+ function args(value) {
5
+ return value && typeof value === "object" && !Array.isArray(value)
6
+ ? value
7
+ : {};
8
+ }
9
+ function text(result) {
10
+ if (typeof result.content === "string")
11
+ return result.content;
12
+ if (Array.isArray(result.content))
13
+ return result.content
14
+ .filter((part) => part.type === "text")
15
+ .map((part) => part.text)
16
+ .join("\n");
17
+ return undefined;
18
+ }
19
+ function replaceText(result, output) {
20
+ if (!Array.isArray(result.content))
21
+ return { ...result, content: output };
22
+ let replaced = false;
23
+ return {
24
+ ...result,
25
+ content: result.content.flatMap((part) => {
26
+ if (part.type !== "text")
27
+ return [part];
28
+ if (replaced)
29
+ return [];
30
+ replaced = true;
31
+ return [{ type: "text", text: output }];
32
+ }),
33
+ };
34
+ }
35
+ export async function registerV2Hooks(ctx, hooks, options = {}) {
36
+ if (hooks["tool.execute.before"])
37
+ await ctx.tool.hook("execute.before", async (event) => {
38
+ const output = { args: event.input };
39
+ await hooks["tool.execute.before"]({ ...event, tool: toolName(event.tool), args: args(event.input) }, output);
40
+ event.input = output.args;
41
+ });
42
+ if (hooks["tool.execute.after"])
43
+ await ctx.tool.hook("execute.after", async (event) => {
44
+ if (event.status !== "completed")
45
+ return;
46
+ const original = text(event.result);
47
+ if (original === undefined)
48
+ return;
49
+ const output = { output: original };
50
+ let directory = ctx.location.directory;
51
+ if (options.sessionDirectory && (event.tool === "read" || event.tool === "edit")) {
52
+ const session = await ctx.session
53
+ .get({ sessionID: event.sessionID })
54
+ .catch(() => undefined);
55
+ if (!session)
56
+ return;
57
+ directory = session.location.directory;
58
+ }
59
+ await hooks["tool.execute.after"]({ ...event, tool: toolName(event.tool), args: args(event.input), directory }, output);
60
+ if (output.output !== original)
61
+ event.result = replaceText(event.result, output.output);
62
+ });
63
+ if (hooks["experimental.chat.system.transform"])
64
+ await ctx.session.hook("context", async (event) => {
65
+ const output = { system: [] };
66
+ await hooks["experimental.chat.system.transform"]({ sessionID: event.sessionID }, output);
67
+ event.system.push(...output.system.map((text) => ({ type: "text", text })));
68
+ });
69
+ if (!hooks.event)
70
+ return;
71
+ const controller = new AbortController();
72
+ const subscription = (async () => {
73
+ try {
74
+ for await (const event of ctx.event.subscribe({ signal: controller.signal })) {
75
+ await hooks.event({ event: { type: event.type, properties: args(event.data) } });
76
+ }
77
+ }
78
+ catch (error) {
79
+ if (!controller.signal.aborted)
80
+ console.error("agentomatic event subscription failed", error);
81
+ }
82
+ })();
83
+ return async () => {
84
+ controller.abort();
85
+ await subscription;
86
+ };
87
+ }
@@ -1,3 +1,4 @@
1
+ import type { Plugin } from "@opencode/plugin";
1
2
  type HookInput = {
2
3
  tool: string;
3
4
  args?: {
@@ -38,4 +39,13 @@ export declare function rtk(options?: RtkOptions): Promise<{
38
39
  } | {
39
40
  "tool.execute.after": (input: HookInput, output: HookOutput) => Promise<void>;
40
41
  }>;
41
- export default rtk;
42
+ declare const _default: {
43
+ id: string;
44
+ server: (_input: unknown, options?: RtkOptions) => Promise<{
45
+ "tool.execute.after"?: undefined;
46
+ } | {
47
+ "tool.execute.after": (input: HookInput, output: HookOutput) => Promise<void>;
48
+ }>;
49
+ setup(ctx: Plugin.Context): Promise<(() => Promise<void>) | undefined>;
50
+ };
51
+ export default _default;
@@ -1,3 +1,4 @@
1
+ import { registerV2Hooks } from "./compatibility.js";
1
2
  import { spawn } from "node:child_process";
2
3
  import { readFile } from "node:fs/promises";
3
4
  import { homedir } from "node:os";
@@ -174,4 +175,10 @@ export async function rtk(options = {}) {
174
175
  },
175
176
  };
176
177
  }
177
- export default rtk;
178
+ export default {
179
+ id: "agentomatic.rtk",
180
+ server: async (_input, options = {}) => rtk(options),
181
+ async setup(ctx) {
182
+ return registerV2Hooks(ctx, await rtk(ctx.options));
183
+ },
184
+ };
@@ -1,3 +1,4 @@
1
+ import type { Plugin } from "@opencode/plugin";
1
2
  export type RulesInjectorOptions = {
2
3
  budget?: number;
3
4
  cwd?: string;
@@ -19,4 +20,26 @@ export declare function rulesInjector(options?: RulesInjectorOptions): Promise<{
19
20
  system?: unknown[];
20
21
  }) => Promise<void>;
21
22
  }>;
22
- export default rulesInjector;
23
+ declare const _default: {
24
+ id: string;
25
+ server: (input: {
26
+ directory?: string;
27
+ }, options?: RulesInjectorOptions) => Promise<{
28
+ "tool.execute.after"?: undefined;
29
+ event?: undefined;
30
+ "experimental.chat.system.transform"?: undefined;
31
+ } | {
32
+ "tool.execute.after": (input: unknown, result: unknown) => Promise<void>;
33
+ event: ({ event, }: {
34
+ event?: {
35
+ type?: string;
36
+ properties?: Record<string, unknown>;
37
+ };
38
+ }) => Promise<void>;
39
+ "experimental.chat.system.transform": (input: unknown, result: {
40
+ system?: unknown[];
41
+ }) => Promise<void>;
42
+ }>;
43
+ setup(ctx: Plugin.Context): Promise<(() => Promise<void>) | undefined>;
44
+ };
45
+ export default _default;
@@ -1,3 +1,4 @@
1
+ import { registerV2Hooks } from "./compatibility.js";
1
2
  import { lstat, readFile, realpath } from "node:fs/promises";
2
3
  import { homedir } from "node:os";
3
4
  import { dirname, resolve } from "node:path";
@@ -112,7 +113,7 @@ export async function rulesInjector(options = {}) {
112
113
  return {
113
114
  "tool.execute.after": inject,
114
115
  event: async ({ event, }) => {
115
- if (event?.type?.includes("compaction")) {
116
+ if (event?.type === "session.compacted" || event?.type?.includes("compaction")) {
116
117
  const identifier = sessionID(event.properties);
117
118
  if (identifier)
118
119
  state(identifier).replay = true;
@@ -128,4 +129,10 @@ export async function rulesInjector(options = {}) {
128
129
  },
129
130
  };
130
131
  }
131
- export default rulesInjector;
132
+ export default {
133
+ id: "agentomatic.rules-injector",
134
+ server: async (input, options = {}) => rulesInjector({ ...options, cwd: options.cwd ?? input.directory }),
135
+ async setup(ctx) {
136
+ return registerV2Hooks(ctx, await rulesInjector({ ...ctx.options, cwd: ctx.location.directory }), { sessionDirectory: true });
137
+ },
138
+ };
@@ -1,3 +1,4 @@
1
+ import type { Plugin } from "@opencode/plugin";
1
2
  export type ZedBellOptions = {
2
3
  enabled?: boolean;
3
4
  };
@@ -10,4 +11,17 @@ export declare function zedBell(options?: ZedBellOptions): Promise<{
10
11
  };
11
12
  }) => Promise<void>;
12
13
  }>;
13
- export default zedBell;
14
+ declare const _default: {
15
+ id: string;
16
+ server: (_input: unknown, options?: ZedBellOptions) => Promise<{
17
+ event?: undefined;
18
+ } | {
19
+ event: ({ event }: {
20
+ event: {
21
+ type?: string;
22
+ };
23
+ }) => Promise<void>;
24
+ }>;
25
+ setup(ctx: Plugin.Context): Promise<(() => Promise<void>) | undefined>;
26
+ };
27
+ export default _default;
@@ -1,3 +1,4 @@
1
+ import { registerV2Hooks } from "./compatibility.js";
1
2
  export async function zedBell(options = {}) {
2
3
  if (!options.enabled)
3
4
  return {};
@@ -11,4 +12,10 @@ export async function zedBell(options = {}) {
11
12
  },
12
13
  };
13
14
  }
14
- export default zedBell;
15
+ export default {
16
+ id: "agentomatic.zed-bell",
17
+ server: async (_input, options = {}) => zedBell(options),
18
+ async setup(ctx) {
19
+ return registerV2Hooks(ctx, await zedBell(ctx.options));
20
+ },
21
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kisev/agentomatic",
3
- "version": "11.0.0-dev.76.ge1ca4a43f0f3",
3
+ "version": "11.0.0-dev.77.g09da04664b2e",
4
4
  "description": "OpenCode integration and opt-in installer for portable Agent Skills.",
5
5
  "homepage": "https://github.com/kisev/skills#readme",
6
6
  "bugs": {
@@ -40,26 +40,32 @@
40
40
  },
41
41
  "scripts": {
42
42
  "build": "node scripts/clean-dist.mjs && tsc --project tsconfig.json && node dist/generate-assets.js",
43
- "test": "node --test test/agent-profiles.test.mjs test/config-setup.test.mjs test/legacy-migration.test.mjs test/doctor.test.mjs test/package.test.mjs test/rtk.test.mjs test/self-install.test.mjs test/stage19.test.mjs test/surface-coverage.test.mjs",
43
+ "test": "node --test test/agent-profiles.test.mjs test/config-setup.test.mjs test/legacy-migration.test.mjs test/doctor.test.mjs test/package.test.mjs test/rtk.test.mjs test/self-install.test.mjs test/stage19.test.mjs test/surface-coverage.test.mjs test/opencode-compatibility.test.mjs",
44
44
  "smoke": "node test/smoke.mjs",
45
45
  "pack:check": "node test/pack-allowlist.mjs"
46
46
  },
47
47
  "dependencies": {
48
48
  "@clack/prompts": "^1.8.1",
49
- "@kisev/safe-fs": "1.0.0-dev.76.ge1ca4a43f0f3",
50
- "commander": "15.0.0"
49
+ "@kisev/safe-fs": "1.0.0-dev.77.g09da04664b2e",
50
+ "commander": "15.0.0",
51
+ "zod": "4.1.8"
51
52
  },
52
53
  "devDependencies": {
53
- "@opencode-ai/plugin": "1.18.29",
54
+ "@opencode-ai/plugin": "1.18.32",
55
+ "@opencode/plugin": "2.0.19",
54
56
  "@types/node": "22.15.30",
55
57
  "typescript": "7.0.2"
56
58
  },
57
59
  "peerDependencies": {
58
- "@opencode-ai/plugin": ">=1.18.29 <1.19.0"
60
+ "@opencode-ai/plugin": ">=1.18.0 <1.19.0",
61
+ "@opencode/plugin": ">=2.0.0 <2.1.0"
59
62
  },
60
63
  "peerDependenciesMeta": {
61
64
  "@opencode-ai/plugin": {
62
65
  "optional": true
66
+ },
67
+ "@opencode/plugin": {
68
+ "optional": true
63
69
  }
64
70
  },
65
71
  "engines": {