@sentry/junior-plugin-api 0.74.1 → 0.75.0

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/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // src/index.ts
1
+ // src/schemas.ts
2
2
  import { z } from "zod";
3
3
  var slackTeamIdSchema = z.string().regex(/^T[A-Z0-9]+$/);
4
4
  var slackConversationIdSchema = z.string().regex(/^(C|G|D)[A-Z0-9]+$/);
@@ -32,7 +32,7 @@ var sourceSchema = z.discriminatedUnion("platform", [
32
32
  slackSourceSchema,
33
33
  localSourceSchema
34
34
  ]);
35
- var agentPluginCredentialSubjectSchema = z.object({
35
+ var pluginCredentialSubjectSchema = z.object({
36
36
  type: z.literal("user"),
37
37
  userId: exactActorUserIdSchema,
38
38
  allowedWhen: z.literal("private-direct-conversation")
@@ -81,6 +81,20 @@ var dispatchMetadataSchema = z.record(z.string(), z.string()).superRefine((metad
81
81
  path: [key]
82
82
  });
83
83
  }
84
+ if (/[\r\n]/.test(key)) {
85
+ ctx.addIssue({
86
+ code: z.ZodIssueCode.custom,
87
+ message: "Dispatch metadata keys must be single-line strings",
88
+ path: [key]
89
+ });
90
+ }
91
+ if (/[\r\n]/.test(value)) {
92
+ ctx.addIssue({
93
+ code: z.ZodIssueCode.custom,
94
+ message: "Dispatch metadata values must be single-line strings",
95
+ path: [key]
96
+ });
97
+ }
84
98
  if (value.length > 512) {
85
99
  ctx.addIssue({
86
100
  code: z.ZodIssueCode.custom,
@@ -92,65 +106,73 @@ var dispatchMetadataSchema = z.record(z.string(), z.string()).superRefine((metad
92
106
  });
93
107
  var dispatchOptionsSchema = z.object({
94
108
  idempotencyKey: nonBlankStringSchema.pipe(z.string().max(512)),
95
- credentialSubject: agentPluginCredentialSubjectSchema.optional(),
109
+ credentialSubject: pluginCredentialSubjectSchema.optional(),
96
110
  destination: slackDestinationSchema,
97
111
  input: nonBlankStringSchema.pipe(z.string().max(32e3)),
98
- metadata: dispatchMetadataSchema.optional()
112
+ metadata: dispatchMetadataSchema.optional(),
113
+ source: sourceSchema
99
114
  }).strict();
100
- var AgentPluginToolInputError = class extends Error {
115
+
116
+ // src/context.ts
117
+ function isSlackDestination(destination) {
118
+ return destination?.platform === "slack";
119
+ }
120
+
121
+ // src/tools.ts
122
+ var PluginToolInputError = class extends Error {
101
123
  constructor(message, options) {
102
124
  super(message, options);
103
- this.name = "AgentPluginToolInputError";
125
+ this.name = "PluginToolInputError";
104
126
  }
105
127
  };
106
- function isSlackDestination(destination) {
107
- return destination?.platform === "slack";
108
- }
109
- var agentPluginProviderNameSchema = z.string().regex(/^[a-z][a-z0-9-]*$/);
110
- var agentPluginGrantNameSchema = z.string().regex(/^[a-z][a-z0-9.-]*$/);
111
- var agentPluginGrantAccessSchema = z.union([
112
- z.literal("read"),
113
- z.literal("write")
128
+
129
+ // src/credentials.ts
130
+ import { z as z2 } from "zod";
131
+ var pluginProviderNameSchema = z2.string().regex(/^[a-z][a-z0-9-]*$/);
132
+ var pluginGrantNameSchema = z2.string().regex(/^[a-z][a-z0-9.-]*$/);
133
+ var pluginGrantAccessSchema = z2.union([
134
+ z2.literal("read"),
135
+ z2.literal("write")
114
136
  ]);
115
- var agentPluginAuthorizationSchema = z.object({
116
- provider: agentPluginProviderNameSchema,
137
+ var pluginAuthorizationSchema = z2.object({
138
+ provider: pluginProviderNameSchema,
117
139
  scope: nonBlankStringSchema.optional(),
118
- type: z.literal("oauth")
140
+ type: z2.literal("oauth")
119
141
  }).strict();
120
- var agentPluginProviderAccountSchema = z.object({
142
+ var pluginProviderAccountSchema = z2.object({
121
143
  id: nonBlankStringSchema,
122
144
  label: nonBlankStringSchema.optional(),
123
145
  url: nonBlankStringSchema.optional()
124
146
  }).strict();
125
- var agentPluginGrantSchema = z.object({
126
- access: agentPluginGrantAccessSchema,
127
- name: agentPluginGrantNameSchema,
147
+ var pluginGrantSchema = z2.object({
148
+ access: pluginGrantAccessSchema,
149
+ name: pluginGrantNameSchema,
128
150
  reason: nonBlankStringSchema.optional(),
129
- requirements: z.array(nonBlankStringSchema).min(1).optional()
151
+ requirements: z2.array(nonBlankStringSchema).min(1).optional()
130
152
  }).strict();
131
- var agentPluginCredentialHeaderTransformSchema = z.object({
132
- domain: z.string().min(1),
133
- headers: z.record(z.string(), z.string()).refine((headers) => Object.keys(headers).length > 0)
153
+ var pluginCredentialHeaderTransformSchema = z2.object({
154
+ domain: z2.string().min(1),
155
+ headers: z2.record(z2.string(), z2.string()).refine((headers) => Object.keys(headers).length > 0)
134
156
  }).strict();
135
- var agentPluginCredentialLeaseSchema = z.object({
136
- account: agentPluginProviderAccountSchema.optional(),
137
- authorization: agentPluginAuthorizationSchema.optional(),
138
- expiresAt: z.string().refine((value) => Number.isFinite(Date.parse(value))),
139
- headerTransforms: z.array(agentPluginCredentialHeaderTransformSchema).min(1)
157
+ var pluginCredentialLeaseSchema = z2.object({
158
+ account: pluginProviderAccountSchema.optional(),
159
+ authorization: pluginAuthorizationSchema.optional(),
160
+ expiresAt: z2.string().refine((value) => Number.isFinite(Date.parse(value))),
161
+ headerTransforms: z2.array(pluginCredentialHeaderTransformSchema).min(1)
140
162
  }).strict();
141
- var agentPluginCredentialResultSchema = z.discriminatedUnion("type", [
142
- z.object({
143
- lease: agentPluginCredentialLeaseSchema,
144
- type: z.literal("lease")
163
+ var pluginCredentialResultSchema = z2.discriminatedUnion("type", [
164
+ z2.object({
165
+ lease: pluginCredentialLeaseSchema,
166
+ type: z2.literal("lease")
145
167
  }).strict(),
146
- z.object({
147
- authorization: agentPluginAuthorizationSchema.optional(),
168
+ z2.object({
169
+ authorization: pluginAuthorizationSchema.optional(),
148
170
  message: nonBlankStringSchema,
149
- type: z.literal("needed")
171
+ type: z2.literal("needed")
150
172
  }).strict(),
151
- z.object({
173
+ z2.object({
152
174
  message: nonBlankStringSchema,
153
- type: z.literal("unavailable")
175
+ type: z2.literal("unavailable")
154
176
  }).strict()
155
177
  ]);
156
178
  var EgressAuthRequired = class extends Error {
@@ -161,24 +183,27 @@ var EgressAuthRequired = class extends Error {
161
183
  this.authorization = options?.authorization;
162
184
  }
163
185
  };
186
+
187
+ // src/registration.ts
164
188
  var PLUGIN_NAME_RE = /^[a-z][a-z0-9-]*$/;
165
189
  function defineJuniorPlugin(plugin) {
166
190
  if ("pluginConfig" in plugin) {
167
191
  throw new Error(
168
- "pluginConfig is no longer supported. Put runtime metadata in manifest and state prefixes on the plugin registration."
192
+ "pluginConfig is no longer supported. Put runtime metadata in manifest or plugin registration fields."
169
193
  );
170
194
  }
195
+ if ("name" in plugin) {
196
+ throw new Error("defineJuniorPlugin() uses manifest.name for identity.");
197
+ }
171
198
  const manifest = plugin.manifest;
172
199
  if (!manifest) {
173
200
  throw new Error(
174
201
  "defineJuniorPlugin() requires a manifest. Use a package name string in defineJuniorPlugins([...]) for plugin.yaml packages."
175
202
  );
176
203
  }
177
- const name = plugin.name ?? manifest.name;
204
+ const name = manifest.name;
178
205
  if (!name) {
179
- throw new Error(
180
- "Junior plugin registrations must include name or manifest.name."
181
- );
206
+ throw new Error("Junior plugin manifest.name is required.");
182
207
  }
183
208
  if (!PLUGIN_NAME_RE.test(name)) {
184
209
  throw new Error(
@@ -195,26 +220,13 @@ function defineJuniorPlugin(plugin) {
195
220
  `Junior plugin "${name}" manifest.description is required.`
196
221
  );
197
222
  }
198
- if (plugin.name && manifest.name && plugin.name !== manifest.name) {
199
- throw new Error(
200
- `Junior plugin registration name "${plugin.name}" must match manifest.name "${manifest.name}".`
201
- );
202
- }
203
223
  return {
204
- ...plugin,
205
- name
224
+ ...plugin
206
225
  };
207
226
  }
208
227
  export {
209
- AgentPluginToolInputError,
210
228
  EgressAuthRequired,
211
- agentPluginAuthorizationSchema,
212
- agentPluginCredentialHeaderTransformSchema,
213
- agentPluginCredentialLeaseSchema,
214
- agentPluginCredentialResultSchema,
215
- agentPluginCredentialSubjectSchema,
216
- agentPluginGrantSchema,
217
- agentPluginProviderAccountSchema,
229
+ PluginToolInputError,
218
230
  defineJuniorPlugin,
219
231
  destinationSchema,
220
232
  dispatchOptionsSchema,
@@ -222,6 +234,14 @@ export {
222
234
  localDestinationSchema,
223
235
  localRequesterSchema,
224
236
  localSourceSchema,
237
+ nonBlankStringSchema,
238
+ pluginAuthorizationSchema,
239
+ pluginCredentialHeaderTransformSchema,
240
+ pluginCredentialLeaseSchema,
241
+ pluginCredentialResultSchema,
242
+ pluginCredentialSubjectSchema,
243
+ pluginGrantSchema,
244
+ pluginProviderAccountSchema,
225
245
  requesterSchema,
226
246
  slackDestinationSchema,
227
247
  slackRequesterSchema,
@@ -0,0 +1,74 @@
1
+ export interface PluginOAuthConfig {
2
+ authorizeEndpoint: string;
3
+ authorizeParams?: Record<string, string>;
4
+ clientIdEnv: string;
5
+ clientSecretEnv: string;
6
+ scope?: string;
7
+ /**
8
+ * Treat a provider token response with `scope: ""` like an omitted scope and
9
+ * fall back to the requested scope string when storing the token.
10
+ */
11
+ treatEmptyScopeAsUnreported?: boolean;
12
+ tokenAuthMethod?: "body" | "basic";
13
+ tokenEndpoint: string;
14
+ tokenExtraHeaders?: Record<string, string>;
15
+ }
16
+ export interface PluginOAuthBearerCredentials {
17
+ apiHeaders?: Record<string, string>;
18
+ authTokenEnv: string;
19
+ authTokenPlaceholder?: string;
20
+ domains: string[];
21
+ type: "oauth-bearer";
22
+ }
23
+ export type PluginCredentials = PluginOAuthBearerCredentials;
24
+ export interface PluginNpmRuntimeDependency {
25
+ package: string;
26
+ type: "npm";
27
+ version: string;
28
+ }
29
+ export interface PluginSystemRuntimeDependency {
30
+ package: string;
31
+ type: "system";
32
+ }
33
+ export interface PluginSystemRuntimeDependencyFromUrl {
34
+ sha256: string;
35
+ type: "system";
36
+ url: string;
37
+ }
38
+ export type PluginRuntimeDependency = PluginNpmRuntimeDependency | PluginSystemRuntimeDependency | PluginSystemRuntimeDependencyFromUrl;
39
+ export interface PluginRuntimePostinstallCommand {
40
+ args?: string[];
41
+ cmd: string;
42
+ sudo?: boolean;
43
+ }
44
+ export interface PluginMcpConfig {
45
+ allowedTools?: string[];
46
+ headers?: Record<string, string>;
47
+ transport: "http";
48
+ url: string;
49
+ }
50
+ export interface PluginEnvVarDeclaration {
51
+ default?: string;
52
+ exposeToCommandEnv?: boolean;
53
+ }
54
+ export interface PluginManifest {
55
+ apiHeaders?: Record<string, string>;
56
+ capabilities?: string[];
57
+ commandEnv?: Record<string, string>;
58
+ configKeys?: string[];
59
+ credentials?: PluginCredentials;
60
+ description: string;
61
+ displayName: string;
62
+ domains?: string[];
63
+ envVars?: Record<string, PluginEnvVarDeclaration>;
64
+ mcp?: PluginMcpConfig;
65
+ name: string;
66
+ oauth?: PluginOAuthConfig;
67
+ runtimeDependencies?: PluginRuntimeDependency[];
68
+ runtimePostinstall?: PluginRuntimePostinstallCommand[];
69
+ target?: {
70
+ commandFlags?: string[];
71
+ configKey: string;
72
+ type: string;
73
+ };
74
+ }
@@ -0,0 +1,93 @@
1
+ import type { PluginContext } from "./context";
2
+ import type { PluginDb } from "./database";
3
+ import type { Dispatch, DispatchOptions, DispatchResult } from "./dispatch";
4
+ import type { PluginReadState, PluginState } from "./state";
5
+ export type PluginConversationStatus = "active" | "completed" | "failed" | "hung" | "superseded";
6
+ export interface PluginConversationSummary {
7
+ channelName?: string;
8
+ conversationId: string;
9
+ displayTitle: string;
10
+ lastActivityAt: string;
11
+ lastUpdatedAt: string;
12
+ source?: "api" | "internal" | "local" | "plugin" | "scheduler" | "slack";
13
+ status: PluginConversationStatus;
14
+ }
15
+ export interface PluginConversations {
16
+ listRecent(options?: {
17
+ limit?: number;
18
+ }): Promise<PluginConversationSummary[]>;
19
+ }
20
+ export interface HeartbeatHookContext extends PluginContext {
21
+ agent: {
22
+ dispatch(options: DispatchOptions): Promise<DispatchResult>;
23
+ get(id: string): Promise<Dispatch | undefined>;
24
+ };
25
+ nowMs: number;
26
+ state: PluginState;
27
+ }
28
+ export interface HeartbeatResult {
29
+ dispatchCount?: number;
30
+ }
31
+ export interface StorageMigrationResult {
32
+ existing: number;
33
+ migrated: number;
34
+ missing: number;
35
+ scanned: number;
36
+ skipped?: number;
37
+ }
38
+ export interface StorageMigrationContext extends PluginContext {
39
+ db: PluginDb;
40
+ state: PluginState;
41
+ }
42
+ export type PluginOperationalTone = "danger" | "good" | "neutral" | "warning";
43
+ export interface PluginOperationalMetric {
44
+ label: string;
45
+ tone?: PluginOperationalTone;
46
+ value: string;
47
+ }
48
+ export interface PluginOperationalField {
49
+ key: string;
50
+ label: string;
51
+ }
52
+ export interface PluginOperationalRecord {
53
+ id: string;
54
+ tone?: PluginOperationalTone;
55
+ values: Record<string, string>;
56
+ }
57
+ export interface PluginOperationalRecordSet {
58
+ fields?: PluginOperationalField[];
59
+ emptyText?: string;
60
+ records?: PluginOperationalRecord[];
61
+ title: string;
62
+ }
63
+ export interface PluginOperationalReportContent {
64
+ generatedAt?: string;
65
+ metrics?: PluginOperationalMetric[];
66
+ recordSets?: PluginOperationalRecordSet[];
67
+ title?: string;
68
+ }
69
+ export interface PluginOperationalReport extends PluginOperationalReportContent {
70
+ pluginName: string;
71
+ }
72
+ export interface OperationalReportHookContext extends PluginContext {
73
+ conversations: PluginConversations;
74
+ nowMs: number;
75
+ state: PluginReadState;
76
+ }
77
+ export type PluginRouteMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | "ALL";
78
+ export type PluginRouteHandler = {
79
+ bivarianceHack(request: Request): Promise<Response> | Response;
80
+ }["bivarianceHack"];
81
+ export interface PluginRoute {
82
+ handler: PluginRouteHandler;
83
+ method?: PluginRouteMethod | PluginRouteMethod[];
84
+ path: string;
85
+ }
86
+ export interface RouteRegistrationHookContext extends PluginContext {
87
+ }
88
+ export interface SlackConversationLink {
89
+ url: string;
90
+ }
91
+ export interface SlackConversationLinkHookContext extends PluginContext {
92
+ conversationId: string;
93
+ }
@@ -0,0 +1,42 @@
1
+ import type { InvocationContext, PluginContext } from "./context";
2
+ import type { PluginSessionState, PluginSessionStateAppend, PluginState } from "./state";
3
+ export interface UserPromptContribution {
4
+ id: string;
5
+ text: string;
6
+ }
7
+ export interface UserPromptContributionResult {
8
+ contributions?: UserPromptContribution[];
9
+ sessionState?: PluginSessionStateAppend[];
10
+ }
11
+ export type UserPromptHookContext = PluginContext & InvocationContext & {
12
+ isFirstPrompt: boolean;
13
+ session: PluginSessionState;
14
+ state: PluginState;
15
+ userText: string;
16
+ };
17
+ export interface PluginTaskEnqueueOptions {
18
+ idempotencyKey: string;
19
+ name: string;
20
+ payload?: unknown;
21
+ }
22
+ export interface PluginTaskEnqueueResult {
23
+ id: string;
24
+ status: "created" | "already_exists";
25
+ }
26
+ export interface PluginTaskQueue {
27
+ enqueue(options: PluginTaskEnqueueOptions): Promise<PluginTaskEnqueueResult>;
28
+ }
29
+ export type TurnObservationHookContext = PluginContext & InvocationContext & {
30
+ observationId: string;
31
+ tasks: PluginTaskQueue;
32
+ };
33
+ export interface PluginTaskContext extends PluginContext {
34
+ id: string;
35
+ name: string;
36
+ observation?: {
37
+ load(): Promise<unknown | undefined>;
38
+ };
39
+ payload?: unknown;
40
+ state: PluginState;
41
+ }
42
+ export type PluginTaskHandler = (ctx: PluginTaskContext) => Promise<void> | void;
@@ -0,0 +1,13 @@
1
+ import type { PluginDatabaseConfig } from "./database";
2
+ import type { PluginHooks } from "./hooks";
3
+ import type { PluginManifest } from "./manifest";
4
+ export type PluginRegistrationInput = {
5
+ database?: PluginDatabaseConfig;
6
+ hooks?: PluginHooks;
7
+ manifest: PluginManifest;
8
+ packageName?: string;
9
+ };
10
+ export interface PluginRegistration extends PluginRegistrationInput {
11
+ }
12
+ /** Define one Junior plugin registration for app and build-time wiring. */
13
+ export declare function defineJuniorPlugin(plugin: PluginRegistrationInput): PluginRegistration;
@@ -0,0 +1,108 @@
1
+ import { z } from "zod";
2
+ export declare const nonBlankStringSchema: z.ZodString;
3
+ /** Runtime-owned Slack address for routing future work or side effects. */
4
+ export declare const slackDestinationSchema: z.ZodObject<{
5
+ platform: z.ZodLiteral<"slack">;
6
+ teamId: z.ZodString;
7
+ channelId: z.ZodString;
8
+ }, z.core.$strict>;
9
+ /** Runtime-owned local CLI conversation address. */
10
+ export declare const localDestinationSchema: z.ZodObject<{
11
+ platform: z.ZodLiteral<"local">;
12
+ conversationId: z.ZodString;
13
+ }, z.core.$strict>;
14
+ /** Runtime-owned provider-neutral address for routing future work or side effects. */
15
+ export declare const destinationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
16
+ platform: z.ZodLiteral<"slack">;
17
+ teamId: z.ZodString;
18
+ channelId: z.ZodString;
19
+ }, z.core.$strict>, z.ZodObject<{
20
+ platform: z.ZodLiteral<"local">;
21
+ conversationId: z.ZodString;
22
+ }, z.core.$strict>], "platform">;
23
+ /** Runtime-owned Slack coordinates for the inbound invocation. */
24
+ export declare const slackSourceSchema: z.ZodObject<{
25
+ platform: z.ZodLiteral<"slack">;
26
+ teamId: z.ZodString;
27
+ channelId: z.ZodString;
28
+ messageTs: z.ZodOptional<z.ZodString>;
29
+ threadTs: z.ZodOptional<z.ZodString>;
30
+ }, z.core.$strict>;
31
+ /** Runtime-owned local CLI coordinates for the inbound invocation. */
32
+ export declare const localSourceSchema: z.ZodObject<{
33
+ platform: z.ZodLiteral<"local">;
34
+ conversationId: z.ZodString;
35
+ }, z.core.$strict>;
36
+ /** Runtime-owned provider-neutral coordinates for the inbound invocation. */
37
+ export declare const sourceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
38
+ platform: z.ZodLiteral<"slack">;
39
+ teamId: z.ZodString;
40
+ channelId: z.ZodString;
41
+ messageTs: z.ZodOptional<z.ZodString>;
42
+ threadTs: z.ZodOptional<z.ZodString>;
43
+ }, z.core.$strict>, z.ZodObject<{
44
+ platform: z.ZodLiteral<"local">;
45
+ conversationId: z.ZodString;
46
+ }, z.core.$strict>], "platform">;
47
+ /** Stable user credential subject shape accepted from plugins. */
48
+ export declare const pluginCredentialSubjectSchema: z.ZodObject<{
49
+ type: z.ZodLiteral<"user">;
50
+ userId: z.ZodString;
51
+ allowedWhen: z.ZodLiteral<"private-direct-conversation">;
52
+ }, z.core.$strict>;
53
+ export declare const slackRequesterSchema: z.ZodObject<{
54
+ platform: z.ZodLiteral<"slack">;
55
+ teamId: z.ZodString;
56
+ email: z.ZodOptional<z.ZodString>;
57
+ fullName: z.ZodOptional<z.ZodString>;
58
+ userId: z.ZodString;
59
+ userName: z.ZodOptional<z.ZodString>;
60
+ }, z.core.$strict>;
61
+ export declare const localRequesterSchema: z.ZodObject<{
62
+ platform: z.ZodLiteral<"local">;
63
+ email: z.ZodOptional<z.ZodString>;
64
+ fullName: z.ZodOptional<z.ZodString>;
65
+ userId: z.ZodString;
66
+ userName: z.ZodOptional<z.ZodString>;
67
+ }, z.core.$strict>;
68
+ /** Runtime-provided requester identity visible to plugin hooks. */
69
+ export declare const requesterSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
70
+ platform: z.ZodLiteral<"slack">;
71
+ teamId: z.ZodString;
72
+ email: z.ZodOptional<z.ZodString>;
73
+ fullName: z.ZodOptional<z.ZodString>;
74
+ userId: z.ZodString;
75
+ userName: z.ZodOptional<z.ZodString>;
76
+ }, z.core.$strict>, z.ZodObject<{
77
+ platform: z.ZodLiteral<"local">;
78
+ email: z.ZodOptional<z.ZodString>;
79
+ fullName: z.ZodOptional<z.ZodString>;
80
+ userId: z.ZodString;
81
+ userName: z.ZodOptional<z.ZodString>;
82
+ }, z.core.$strict>], "platform">;
83
+ /** Plugin dispatch request accepted by Junior core. */
84
+ export declare const dispatchOptionsSchema: z.ZodObject<{
85
+ idempotencyKey: z.ZodPipe<z.ZodString, z.ZodString>;
86
+ credentialSubject: z.ZodOptional<z.ZodObject<{
87
+ type: z.ZodLiteral<"user">;
88
+ userId: z.ZodString;
89
+ allowedWhen: z.ZodLiteral<"private-direct-conversation">;
90
+ }, z.core.$strict>>;
91
+ destination: z.ZodObject<{
92
+ platform: z.ZodLiteral<"slack">;
93
+ teamId: z.ZodString;
94
+ channelId: z.ZodString;
95
+ }, z.core.$strict>;
96
+ input: z.ZodPipe<z.ZodString, z.ZodString>;
97
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
98
+ source: z.ZodDiscriminatedUnion<[z.ZodObject<{
99
+ platform: z.ZodLiteral<"slack">;
100
+ teamId: z.ZodString;
101
+ channelId: z.ZodString;
102
+ messageTs: z.ZodOptional<z.ZodString>;
103
+ threadTs: z.ZodOptional<z.ZodString>;
104
+ }, z.core.$strict>, z.ZodObject<{
105
+ platform: z.ZodLiteral<"local">;
106
+ conversationId: z.ZodString;
107
+ }, z.core.$strict>], "platform">;
108
+ }, z.core.$strict>;
@@ -0,0 +1,20 @@
1
+ export interface PluginState {
2
+ delete(key: string): Promise<void>;
3
+ get<T = unknown>(key: string): Promise<T | undefined>;
4
+ set(key: string, value: unknown, ttlMs?: number): Promise<void>;
5
+ setIfNotExists(key: string, value: unknown, ttlMs?: number): Promise<boolean>;
6
+ withLock<T>(key: string, ttlMs: number, callback: () => Promise<T>): Promise<T>;
7
+ }
8
+ export interface PluginReadState {
9
+ get<T = unknown>(key: string): Promise<T | undefined>;
10
+ }
11
+ export interface PluginSessionStateAppend {
12
+ key: string;
13
+ value: unknown;
14
+ }
15
+ export interface PluginSessionState {
16
+ list<T = unknown>(key: string): Promise<Array<{
17
+ createdAtMs: number;
18
+ value: T;
19
+ }>>;
20
+ }
@@ -0,0 +1,107 @@
1
+ import type { PluginContext, LocalInvocationContext, Requester, SlackInvocationContext } from "./context";
2
+ import type { PluginCredentialSubject } from "./credentials";
3
+ import type { PluginState } from "./state";
4
+ export interface PluginEnv {
5
+ get(key: string): string | undefined;
6
+ set(key: string, value: string): void;
7
+ }
8
+ export interface PluginDecision {
9
+ deny(message: string): void;
10
+ replaceInput(input: Record<string, unknown>): void;
11
+ }
12
+ /** Thrown when a plugin tool rejects invalid model or user input. */
13
+ export declare class PluginToolInputError extends Error {
14
+ constructor(message: string, options?: {
15
+ cause?: unknown;
16
+ });
17
+ }
18
+ export interface PluginSandbox {
19
+ juniorRoot: string;
20
+ root: string;
21
+ readFile(path: string): Promise<Uint8Array | null>;
22
+ run(input: {
23
+ args?: string[];
24
+ cmd: string;
25
+ cwd?: string;
26
+ env?: Record<string, string>;
27
+ sudo?: boolean;
28
+ }): Promise<{
29
+ exitCode: number;
30
+ stderr: string;
31
+ stdout: string;
32
+ }>;
33
+ writeFile(input: {
34
+ content: string | Uint8Array;
35
+ mode?: number;
36
+ path: string;
37
+ }): Promise<void>;
38
+ }
39
+ export interface SandboxPrepareHookContext extends PluginContext {
40
+ requester?: Requester;
41
+ sandbox: PluginSandbox;
42
+ }
43
+ export interface BeforeToolExecuteHookContext extends PluginContext {
44
+ decision: PluginDecision;
45
+ env: PluginEnv;
46
+ requester?: Requester;
47
+ tool: {
48
+ input: Record<string, unknown>;
49
+ name: string;
50
+ };
51
+ }
52
+ export type PluginToolExecute<TInput = unknown> = {
53
+ bivarianceHack(input: TInput, options: {
54
+ experimental_context?: unknown;
55
+ }): Promise<unknown> | unknown;
56
+ }["bivarianceHack"];
57
+ export interface PluginToolDefinition<TInput = unknown> {
58
+ annotations?: unknown;
59
+ description: string;
60
+ executionMode?: unknown;
61
+ inputSchema: unknown;
62
+ prepareArguments?: (args: unknown) => unknown;
63
+ /**
64
+ * @deprecated Put tool-selection and usage guidance directly in `description`
65
+ * and parameter descriptions. Retained for compatibility; may be removed in a
66
+ * future major version.
67
+ */
68
+ promptGuidelines?: string[];
69
+ /**
70
+ * @deprecated Put tool-selection and usage guidance directly in `description`
71
+ * and parameter descriptions. Retained for compatibility; may be removed in a
72
+ * future major version.
73
+ */
74
+ promptSnippet?: string;
75
+ execute?: PluginToolExecute<TInput>;
76
+ }
77
+ export interface SlackToolRegistrationHookContext {
78
+ /**
79
+ * Capabilities of the source Slack conversation exposed to this plugin.
80
+ * Recomputed from `source.channelId`, not from `destination`.
81
+ */
82
+ channelCapabilities: {
83
+ canAddReactions: boolean;
84
+ canCreateCanvas: boolean;
85
+ canPostToChannel: boolean;
86
+ };
87
+ credentialSubject?: PluginCredentialSubject;
88
+ }
89
+ interface BaseToolRegistrationHookContext extends PluginContext {
90
+ /**
91
+ * Opaque Junior conversation/session identity for this turn.
92
+ * Interactive Slack turns use `slack:{channelId}:{threadTs}`.
93
+ * Scheduled/API turns use an internal id such as `agent-dispatch:{id}`.
94
+ * Do not parse as Slack unless the value starts with `slack:`.
95
+ */
96
+ conversationId?: string;
97
+ state: PluginState;
98
+ userText?: string;
99
+ }
100
+ interface SlackToolRegistrationContext extends BaseToolRegistrationHookContext, SlackInvocationContext {
101
+ slack: SlackToolRegistrationHookContext;
102
+ }
103
+ interface LocalToolRegistrationContext extends BaseToolRegistrationHookContext, LocalInvocationContext {
104
+ slack?: never;
105
+ }
106
+ export type ToolRegistrationHookContext = LocalToolRegistrationContext | SlackToolRegistrationContext;
107
+ export {};