@ericsanchezok/synergy-plugin 2.1.3 → 2.2.1

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.
@@ -0,0 +1,422 @@
1
+ import z from "zod";
2
+ const ToolRendererDef = z
3
+ .object({
4
+ tool: z.string().min(1),
5
+ exportName: z.string().optional().default("default"),
6
+ priority: z.number().int().min(0).max(100).optional().default(0),
7
+ fallback: z
8
+ .object({
9
+ icon: z.string().optional(),
10
+ title: z.string().optional(),
11
+ subtitleTemplate: z.string().optional(),
12
+ })
13
+ .optional(),
14
+ })
15
+ .strict();
16
+ const PartRendererDef = z
17
+ .object({
18
+ type: z.string().min(1),
19
+ exportName: z.string().optional().default("default"),
20
+ priority: z.number().int().min(0).max(100).optional().default(0),
21
+ })
22
+ .strict();
23
+ const PanelDef = z
24
+ .object({
25
+ id: z.string().min(1).max(64),
26
+ label: z.string().min(1).max(64),
27
+ icon: z.string().min(1),
28
+ exportName: z.string().optional().default("default"),
29
+ sandbox: z.boolean().optional().default(false),
30
+ sandboxEntry: z
31
+ .string()
32
+ .regex(/^[a-zA-Z0-9_/.-]+\.js$/)
33
+ .max(256)
34
+ .optional(),
35
+ })
36
+ .strict();
37
+ const SettingsDef = z
38
+ .object({
39
+ id: z.string().min(1).max(64),
40
+ label: z.string().min(1).max(64),
41
+ icon: z.string().min(1),
42
+ group: z.string(),
43
+ formSchema: z.record(z.string(), z.unknown()).optional(),
44
+ exportName: z.string().optional(),
45
+ sandbox: z.boolean().optional().default(false),
46
+ sandboxEntry: z
47
+ .string()
48
+ .regex(/^[a-zA-Z0-9_/.-]+\.js$/)
49
+ .max(256)
50
+ .optional(),
51
+ })
52
+ .strict();
53
+ const ChatComponentDef = z
54
+ .object({
55
+ id: z.string().min(1),
56
+ exportName: z.string().optional().default("default"),
57
+ slot: z.enum(["before-tools", "after-tools", "before-reasoning", "after-reasoning"]).optional(),
58
+ })
59
+ .strict();
60
+ const ThemeDef = z
61
+ .object({
62
+ id: z.string().min(1).max(64),
63
+ label: z.string().min(1).max(64),
64
+ path: z.string().min(1),
65
+ })
66
+ .strict();
67
+ const IconDef = z
68
+ .object({
69
+ name: z.string().min(1).max(128),
70
+ path: z.string().min(1),
71
+ })
72
+ .strict();
73
+ const RouteDef = z
74
+ .object({
75
+ path: z.string().min(1),
76
+ entry: z.string().min(1),
77
+ label: z.string().min(1),
78
+ icon: z.string().optional(),
79
+ })
80
+ .strict();
81
+ const UICommandDef = z
82
+ .object({
83
+ id: z.string().min(1).max(64),
84
+ label: z.string().min(1).max(64),
85
+ exportName: z.string().optional(),
86
+ description: z.string().max(256).optional(),
87
+ icon: z.string().optional(),
88
+ })
89
+ .strict();
90
+ const UIContribution = z
91
+ .object({
92
+ entry: z
93
+ .string()
94
+ .regex(/^[a-zA-Z0-9_/.-]+\.js$/)
95
+ .max(256)
96
+ .optional(),
97
+ minUIApiVersion: z
98
+ .string()
99
+ .regex(/^\d+\.\d+\.\d+$/)
100
+ .optional(),
101
+ toolRenderers: z.array(ToolRendererDef).optional(),
102
+ partRenderers: z.array(PartRendererDef).optional(),
103
+ workspacePanels: z.array(PanelDef).optional(),
104
+ globalPanels: z.array(PanelDef).optional(),
105
+ settings: z.array(SettingsDef).optional(),
106
+ chatComponents: z.array(ChatComponentDef).optional(),
107
+ themes: z.array(ThemeDef).optional(),
108
+ icons: z.array(IconDef).optional(),
109
+ routes: z.array(RouteDef).optional(),
110
+ commands: z.array(UICommandDef).optional(),
111
+ })
112
+ .partial()
113
+ .optional();
114
+ const PluginPermissionsSchema = z
115
+ .object({
116
+ /** Tool execution permissions */
117
+ tools: z
118
+ .object({
119
+ invoke: z.boolean().default(true),
120
+ shell: z.boolean().default(false),
121
+ filesystem: z.preprocess((val) => {
122
+ if (val === true)
123
+ return "write";
124
+ if (val === false)
125
+ return "none";
126
+ return val;
127
+ }, z.enum(["none", "read", "write"]).default("none")),
128
+ network: z.boolean().default(false),
129
+ mcp: z.enum(["none", "invoke", "spawn"]).default("none"),
130
+ })
131
+ .optional(),
132
+ /** Data access */
133
+ data: z
134
+ .object({
135
+ session: z.enum(["none", "metadata", "read"]).default("none"),
136
+ workspace: z.enum(["none", "metadata", "read"]).default("none"),
137
+ config: z.enum(["plugin", "global"]).default("plugin"),
138
+ secrets: z.enum(["none", "own"]).default("none"),
139
+ })
140
+ .optional(),
141
+ /** Network access */
142
+ network: z
143
+ .object({
144
+ connectDomains: z.array(z.string()).default([]),
145
+ resourceDomains: z.array(z.string()).default([]),
146
+ frameDomains: z.array(z.string()).default([]),
147
+ })
148
+ .optional(),
149
+ /** UI surface permissions */
150
+ ui: z
151
+ .object({
152
+ toolRenderers: z.boolean().default(false),
153
+ partRenderers: z.boolean().default(false),
154
+ workspacePanels: z.boolean().default(false),
155
+ globalPanels: z.boolean().default(false),
156
+ settings: z.boolean().default(false),
157
+ themes: z.boolean().default(false),
158
+ icons: z.boolean().default(false),
159
+ routes: z.boolean().default(false),
160
+ trustedImport: z.boolean().default(false),
161
+ sandboxIframe: z.boolean().default(false),
162
+ })
163
+ .optional(),
164
+ /** Hook permission declarations */
165
+ hooks: z
166
+ .object({
167
+ events: z.enum(["none", "selected", "all"]).default("selected"),
168
+ eventNames: z.array(z.string()).default([]),
169
+ toolExecute: z.enum(["none", "own", "declared", "all"]).default("own"),
170
+ permissionAsk: z.enum(["none", "own", "all"]).default("none"),
171
+ promptTransform: z.boolean().default(false),
172
+ compactionTransform: z.boolean().default(false),
173
+ })
174
+ .optional(),
175
+ })
176
+ .optional();
177
+ // PluginManifest: the declarative plugin descriptor (plugin.json)
178
+ export const PluginManifest = z
179
+ .object({
180
+ // Identity
181
+ name: z.string().min(1).max(128),
182
+ version: z.string().regex(/^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?(\+[a-zA-Z0-9.]+)?$/),
183
+ description: z.string().min(1).max(1024),
184
+ author: z.string().optional(),
185
+ homepage: z.string().url().optional(),
186
+ repository: z.string().optional(),
187
+ license: z.string().optional(),
188
+ icon: z.string().optional(),
189
+ keywords: z.array(z.string()).optional(),
190
+ // Compatibility
191
+ minSynergyVersion: z
192
+ .string()
193
+ .regex(/^\d+\.\d+\.\d+$/)
194
+ .optional(),
195
+ engines: z
196
+ .object({
197
+ synergy: z.string().optional(),
198
+ bun: z.string().optional(),
199
+ })
200
+ .optional(),
201
+ // Dependencies on other plugins
202
+ dependencies: z.record(z.string(), z.string()).optional(),
203
+ // Trust tier request
204
+ trust: z
205
+ .object({
206
+ requestedTier: z.enum(["declarative", "trusted-import", "sandbox"]).optional(),
207
+ reason: z.string().optional(),
208
+ })
209
+ .optional(),
210
+ // Permission / trust declaration
211
+ permissions: PluginPermissionsSchema,
212
+ // Declarative contributions
213
+ contributes: z
214
+ .object({
215
+ tools: z
216
+ .array(z.object({
217
+ id: z.string().optional(),
218
+ name: z.string(),
219
+ title: z.string().optional(),
220
+ description: z.string(),
221
+ icon: z.string().optional(),
222
+ category: z.string().optional(),
223
+ kind: z.string().optional(),
224
+ capabilities: z
225
+ .object({
226
+ filesystem: z.enum(["none", "read", "write"]).optional(),
227
+ network: z.boolean().optional(),
228
+ shell: z.boolean().optional(),
229
+ session: z.enum(["none", "metadata", "read"]).optional(),
230
+ workspace: z.enum(["none", "metadata", "read"]).optional(),
231
+ config: z.enum(["none", "plugin", "global"]).optional(),
232
+ })
233
+ .optional(),
234
+ risk: z.enum(["low", "medium", "high"]).optional(),
235
+ }))
236
+ .optional(),
237
+ skills: z
238
+ .array(z.object({
239
+ name: z.string(),
240
+ description: z.string(),
241
+ dir: z.string(),
242
+ }))
243
+ .optional(),
244
+ agents: z
245
+ .array(z.object({
246
+ name: z.string(),
247
+ description: z.string(),
248
+ mode: z.enum(["subagent", "primary", "all"]).default("subagent"),
249
+ model: z.string().optional(),
250
+ }))
251
+ .optional(),
252
+ mcp: z
253
+ .object({
254
+ defaults: z
255
+ .object({
256
+ startup: z.enum(["eager", "lazy", "manual"]).optional(),
257
+ required: z.boolean().optional(),
258
+ connectTimeout: z.number().optional(),
259
+ listTimeout: z.number().optional(),
260
+ callTimeout: z.number().optional(),
261
+ retry: z
262
+ .object({
263
+ maxAttempts: z.number().int().positive().optional(),
264
+ backoffMs: z.number().int().positive().optional(),
265
+ backoffMultiplier: z.number().positive().optional(),
266
+ cooldownMs: z.number().int().nonnegative().optional(),
267
+ })
268
+ .optional(),
269
+ idleShutdownMs: z.number().int().positive().optional(),
270
+ toolFilter: z
271
+ .object({
272
+ include: z.array(z.string()).optional(),
273
+ exclude: z.array(z.string()).optional(),
274
+ })
275
+ .optional(),
276
+ tools: z
277
+ .object({
278
+ approval: z.enum(["auto", "always", "per_session"]).optional(),
279
+ maxOutputBytes: z.number().int().positive().optional(),
280
+ })
281
+ .optional(),
282
+ toolCache: z
283
+ .object({
284
+ mode: z.enum(["disabled", "session", "persistent"]).optional(),
285
+ ttlMs: z.number().int().positive().optional(),
286
+ })
287
+ .optional(),
288
+ })
289
+ .optional()
290
+ .describe("Default lifecycle settings applied to all MCP servers contributed by this plugin"),
291
+ locked: z
292
+ .boolean()
293
+ .optional()
294
+ .describe("If true, the user cannot override this plugin's MCP server declarations"),
295
+ })
296
+ .catchall(z
297
+ .object({
298
+ type: z.literal("local"),
299
+ command: z.array(z.string()),
300
+ environment: z.record(z.string(), z.string()).optional(),
301
+ description: z.string().optional(),
302
+ timeout: z.number().optional(),
303
+ startup: z.enum(["eager", "lazy", "manual"]).optional(),
304
+ required: z.boolean().optional(),
305
+ connectTimeout: z.number().optional(),
306
+ listTimeout: z.number().optional(),
307
+ callTimeout: z.number().optional(),
308
+ retry: z
309
+ .object({
310
+ maxAttempts: z.number().int().positive().optional(),
311
+ backoffMs: z.number().int().positive().optional(),
312
+ backoffMultiplier: z.number().positive().optional(),
313
+ cooldownMs: z.number().int().nonnegative().optional(),
314
+ })
315
+ .optional(),
316
+ idleShutdownMs: z.number().int().positive().optional(),
317
+ toolFilter: z
318
+ .object({
319
+ include: z.array(z.string()).optional(),
320
+ exclude: z.array(z.string()).optional(),
321
+ })
322
+ .optional(),
323
+ tools: z
324
+ .object({
325
+ approval: z.enum(["auto", "always", "per_session"]).optional(),
326
+ maxOutputBytes: z.number().int().positive().optional(),
327
+ })
328
+ .optional(),
329
+ toolCache: z
330
+ .object({
331
+ mode: z.enum(["disabled", "session", "persistent"]).optional(),
332
+ ttlMs: z.number().int().positive().optional(),
333
+ })
334
+ .optional(),
335
+ })
336
+ .strict()
337
+ .or(z
338
+ .object({
339
+ type: z.literal("remote"),
340
+ url: z.string(),
341
+ headers: z.record(z.string(), z.string()).optional(),
342
+ description: z.string().optional(),
343
+ timeout: z.number().optional(),
344
+ startup: z.enum(["eager", "lazy", "manual"]).optional(),
345
+ required: z.boolean().optional(),
346
+ connectTimeout: z.number().optional(),
347
+ listTimeout: z.number().optional(),
348
+ callTimeout: z.number().optional(),
349
+ retry: z
350
+ .object({
351
+ maxAttempts: z.number().int().positive().optional(),
352
+ backoffMs: z.number().int().positive().optional(),
353
+ backoffMultiplier: z.number().positive().optional(),
354
+ cooldownMs: z.number().int().nonnegative().optional(),
355
+ })
356
+ .optional(),
357
+ idleShutdownMs: z.number().int().positive().optional(),
358
+ toolFilter: z
359
+ .object({
360
+ include: z.array(z.string()).optional(),
361
+ exclude: z.array(z.string()).optional(),
362
+ })
363
+ .optional(),
364
+ tools: z
365
+ .object({
366
+ approval: z.enum(["auto", "always", "per_session"]).optional(),
367
+ maxOutputBytes: z.number().int().positive().optional(),
368
+ })
369
+ .optional(),
370
+ toolCache: z
371
+ .object({
372
+ mode: z.enum(["disabled", "session", "persistent"]).optional(),
373
+ ttlMs: z.number().int().positive().optional(),
374
+ })
375
+ .optional(),
376
+ })
377
+ .strict()))
378
+ .optional(),
379
+ commands: z
380
+ .array(z.object({
381
+ name: z.string(),
382
+ description: z.string(),
383
+ }))
384
+ .optional(),
385
+ config: z
386
+ .object({
387
+ schema: z.record(z.string(), z.any()).optional(),
388
+ defaults: z.record(z.string(), z.any()).optional(),
389
+ })
390
+ .optional(),
391
+ permissions: PluginPermissionsSchema,
392
+ ui: UIContribution,
393
+ })
394
+ .partial()
395
+ .optional(),
396
+ // Lifecycle
397
+ main: z.string().optional().default("./src/index.ts"),
398
+ lifecycle: z
399
+ .object({
400
+ install: z.string().optional(),
401
+ uninstall: z.string().optional(),
402
+ update: z.string().optional(),
403
+ })
404
+ .optional(),
405
+ // Runtime preferences
406
+ runtime: z
407
+ .object({
408
+ mode: z.enum(["in-process", "worker", "process"]).optional(),
409
+ minRuntimeApiVersion: z.string().optional(),
410
+ resources: z
411
+ .object({
412
+ memoryMb: z.number().positive().optional(),
413
+ startupTimeoutMs: z.number().positive().optional(),
414
+ requestTimeoutMs: z.number().positive().optional(),
415
+ maxConcurrentRequests: z.number().positive().optional(),
416
+ maxLogBytesPerMinute: z.number().positive().optional(),
417
+ })
418
+ .optional(),
419
+ })
420
+ .optional(),
421
+ })
422
+ .strict();
package/dist/tool.d.ts CHANGED
@@ -16,6 +16,16 @@ export interface ToolResult {
16
16
  title?: string;
17
17
  output: string;
18
18
  metadata?: Record<string, any>;
19
+ attachments?: Array<{
20
+ type: "file";
21
+ id: string;
22
+ sessionID: string;
23
+ messageID: string;
24
+ mime: string;
25
+ filename?: string;
26
+ url: string;
27
+ localPath?: string;
28
+ }>;
19
29
  }
20
30
  export declare function tool<Args extends z.ZodRawShape>(input: {
21
31
  description: string;
package/dist/ui.d.ts ADDED
@@ -0,0 +1,45 @@
1
+ import type { Component } from "solid-js";
2
+ export interface PluginToolRendererProps {
3
+ input: Record<string, unknown>;
4
+ metadata: Record<string, unknown>;
5
+ tool: string;
6
+ title?: string;
7
+ output?: string;
8
+ status?: string;
9
+ raw?: string;
10
+ charsReceived?: number;
11
+ hideDetails?: boolean;
12
+ defaultOpen?: boolean;
13
+ forceOpen?: boolean;
14
+ }
15
+ export type PluginToolRenderer = Component<PluginToolRendererProps>;
16
+ export interface PluginPartRendererProps {
17
+ part: unknown;
18
+ message?: unknown;
19
+ }
20
+ export type PluginPartRenderer = Component<PluginPartRendererProps>;
21
+ export interface PluginPanelProps {
22
+ pluginId: string;
23
+ panelId: string;
24
+ scopeId?: string;
25
+ }
26
+ export type PluginWorkspacePanel = Component<PluginPanelProps>;
27
+ export type PluginGlobalPanel = Component<PluginPanelProps>;
28
+ export interface PluginSettingsProps {
29
+ pluginId: string;
30
+ values: Record<string, unknown>;
31
+ onChange(values: Record<string, unknown>): void;
32
+ }
33
+ export type PluginSettingsSection = Component<PluginSettingsProps>;
34
+ export type PluginChatSlot = "before-tools" | "after-tools" | "before-reasoning" | "after-reasoning";
35
+ export interface PluginChatComponentProps {
36
+ slot: PluginChatSlot;
37
+ sessionId?: string;
38
+ messageId?: string;
39
+ }
40
+ export type PluginChatComponent = Component<PluginChatComponentProps>;
41
+ export interface PluginCommandContext {
42
+ pluginId: string;
43
+ serverUrl: string;
44
+ }
45
+ export type PluginUICommand = (context: PluginCommandContext) => void | Promise<void>;
package/dist/ui.js ADDED
File without changes
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@ericsanchezok/synergy-plugin",
4
- "version": "2.1.3",
4
+ "version": "2.2.1",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -28,6 +28,14 @@
28
28
  "./hooks": {
29
29
  "import": "./dist/hooks.js",
30
30
  "types": "./dist/hooks.d.ts"
31
+ },
32
+ "./shell": {
33
+ "import": "./dist/shell.js",
34
+ "types": "./dist/shell.d.ts"
35
+ },
36
+ "./ui": {
37
+ "import": "./dist/ui.js",
38
+ "types": "./dist/ui.d.ts"
31
39
  }
32
40
  },
33
41
  "files": [