@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 +1 -1
- package/README.ru.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/config-setup.js +4 -3
- package/dist/doctor.js +6 -2
- package/dist/index.d.ts +101 -83
- package/dist/index.js +69 -18
- package/dist/plugins/compatibility.d.ts +30 -0
- package/dist/plugins/compatibility.js +87 -0
- package/dist/plugins/rtk.d.ts +11 -1
- package/dist/plugins/rtk.js +8 -1
- package/dist/plugins/rules-injector.d.ts +24 -1
- package/dist/plugins/rules-injector.js +9 -2
- package/dist/plugins/zed-bell.d.ts +15 -1
- package/dist/plugins/zed-bell.js +8 -1
- package/package.json +12 -6
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.
|
|
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.
|
|
66
|
+
- OpenCode `>=1.18.0 <1.19.0 || >=2.0.0 <2.1.0`.
|
|
67
67
|
- Постоянный npm-проект, которому принадлежит зависимость.
|
|
68
68
|
|
|
69
69
|
## Установка в проект
|
package/dist/config-setup.js
CHANGED
|
@@ -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: [
|
|
177
|
+
{ kind: "set-if-absent", path: [key], value: [] },
|
|
177
178
|
{
|
|
178
179
|
kind: "replace-array-value",
|
|
179
|
-
path: [
|
|
180
|
+
path: [key],
|
|
180
181
|
from: LEGACY_PACKAGE_NAME,
|
|
181
182
|
to: PACKAGE_NAME,
|
|
182
183
|
},
|
|
183
|
-
{ kind: "append-unique", path: [
|
|
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
|
|
118
|
-
|
|
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 {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
54
|
-
|
|
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:
|
|
32
|
+
action: z.ZodEnum<{
|
|
73
33
|
dispatch: "dispatch";
|
|
74
34
|
preview: "preview";
|
|
75
35
|
}>;
|
|
76
|
-
category:
|
|
36
|
+
category: z.ZodEnum<{
|
|
77
37
|
architecture: "architecture";
|
|
78
38
|
exploration: "exploration";
|
|
79
39
|
implementation: "implementation";
|
|
80
40
|
review: "review";
|
|
81
41
|
}>;
|
|
82
|
-
task:
|
|
83
|
-
requirements:
|
|
84
|
-
execution_card:
|
|
85
|
-
override:
|
|
86
|
-
trusted_override:
|
|
87
|
-
budget:
|
|
88
|
-
cost_class:
|
|
89
|
-
latency_class:
|
|
90
|
-
},
|
|
91
|
-
decision:
|
|
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: "
|
|
95
|
-
category:
|
|
54
|
+
action: "preview" | "dispatch";
|
|
55
|
+
category: Category;
|
|
96
56
|
task: string;
|
|
97
57
|
requirements: string[];
|
|
98
|
-
execution_card?:
|
|
99
|
-
override?: string
|
|
100
|
-
trusted_override?: boolean
|
|
101
|
-
budget?:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
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 {
|
|
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 =
|
|
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:
|
|
51
|
-
category:
|
|
52
|
-
task:
|
|
53
|
-
requirements:
|
|
54
|
-
execution_card:
|
|
55
|
-
override:
|
|
56
|
-
trusted_override:
|
|
57
|
-
budget:
|
|
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:
|
|
60
|
-
latency_class:
|
|
60
|
+
cost_class: z.string().optional(),
|
|
61
|
+
latency_class: z.string().optional(),
|
|
61
62
|
})
|
|
62
63
|
.optional(),
|
|
63
|
-
decision:
|
|
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
|
|
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
|
+
}
|
package/dist/plugins/rtk.d.ts
CHANGED
|
@@ -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
|
-
|
|
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;
|
package/dist/plugins/rtk.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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;
|
package/dist/plugins/zed-bell.js
CHANGED
|
@@ -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
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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": {
|