@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/context.d.ts +59 -0
- package/dist/credentials.d.ts +158 -0
- package/dist/database.d.ts +13 -0
- package/dist/dispatch.d.ts +13 -0
- package/dist/hooks.d.ts +17 -0
- package/dist/index.d.ts +11 -616
- package/dist/index.js +79 -59
- package/dist/manifest.d.ts +74 -0
- package/dist/operations.d.ts +93 -0
- package/dist/prompt.d.ts +42 -0
- package/dist/registration.d.ts +13 -0
- package/dist/schemas.d.ts +108 -0
- package/dist/state.d.ts +20 -0
- package/dist/tools.d.ts +107 -0
- package/package.json +2 -1
- package/src/context.ts +72 -0
- package/src/credentials.ts +200 -0
- package/src/database.ts +22 -0
- package/src/dispatch.ts +22 -0
- package/src/hooks.ts +67 -0
- package/src/index.ts +11 -875
- package/src/manifest.ts +87 -0
- package/src/operations.ts +126 -0
- package/src/prompt.ts +59 -0
- package/src/registration.ts +62 -0
- package/src/schemas.ts +161 -0
- package/src/state.ts +26 -0
- package/src/tools.ts +130 -0
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/
|
|
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
|
|
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:
|
|
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
|
-
|
|
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 = "
|
|
125
|
+
this.name = "PluginToolInputError";
|
|
104
126
|
}
|
|
105
127
|
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
var
|
|
110
|
-
var
|
|
111
|
-
var
|
|
112
|
-
|
|
113
|
-
|
|
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
|
|
116
|
-
provider:
|
|
137
|
+
var pluginAuthorizationSchema = z2.object({
|
|
138
|
+
provider: pluginProviderNameSchema,
|
|
117
139
|
scope: nonBlankStringSchema.optional(),
|
|
118
|
-
type:
|
|
140
|
+
type: z2.literal("oauth")
|
|
119
141
|
}).strict();
|
|
120
|
-
var
|
|
142
|
+
var pluginProviderAccountSchema = z2.object({
|
|
121
143
|
id: nonBlankStringSchema,
|
|
122
144
|
label: nonBlankStringSchema.optional(),
|
|
123
145
|
url: nonBlankStringSchema.optional()
|
|
124
146
|
}).strict();
|
|
125
|
-
var
|
|
126
|
-
access:
|
|
127
|
-
name:
|
|
147
|
+
var pluginGrantSchema = z2.object({
|
|
148
|
+
access: pluginGrantAccessSchema,
|
|
149
|
+
name: pluginGrantNameSchema,
|
|
128
150
|
reason: nonBlankStringSchema.optional(),
|
|
129
|
-
requirements:
|
|
151
|
+
requirements: z2.array(nonBlankStringSchema).min(1).optional()
|
|
130
152
|
}).strict();
|
|
131
|
-
var
|
|
132
|
-
domain:
|
|
133
|
-
headers:
|
|
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
|
|
136
|
-
account:
|
|
137
|
-
authorization:
|
|
138
|
-
expiresAt:
|
|
139
|
-
headerTransforms:
|
|
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
|
|
142
|
-
|
|
143
|
-
lease:
|
|
144
|
-
type:
|
|
163
|
+
var pluginCredentialResultSchema = z2.discriminatedUnion("type", [
|
|
164
|
+
z2.object({
|
|
165
|
+
lease: pluginCredentialLeaseSchema,
|
|
166
|
+
type: z2.literal("lease")
|
|
145
167
|
}).strict(),
|
|
146
|
-
|
|
147
|
-
authorization:
|
|
168
|
+
z2.object({
|
|
169
|
+
authorization: pluginAuthorizationSchema.optional(),
|
|
148
170
|
message: nonBlankStringSchema,
|
|
149
|
-
type:
|
|
171
|
+
type: z2.literal("needed")
|
|
150
172
|
}).strict(),
|
|
151
|
-
|
|
173
|
+
z2.object({
|
|
152
174
|
message: nonBlankStringSchema,
|
|
153
|
-
type:
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
+
}
|
package/dist/prompt.d.ts
ADDED
|
@@ -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>;
|
package/dist/state.d.ts
ADDED
|
@@ -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
|
+
}
|
package/dist/tools.d.ts
ADDED
|
@@ -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 {};
|