@sentry/junior-plugin-api 0.197.0 → 0.199.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.d.ts +2021 -19
- package/package.json +4 -5
- package/dist/annotations.d.ts +0 -75
- package/dist/cli.d.ts +0 -39
- package/dist/code.d.ts +0 -37
- package/dist/context.d.ts +0 -158
- package/dist/conversation-events.d.ts +0 -80
- package/dist/credentials.d.ts +0 -184
- package/dist/dispatch.d.ts +0 -16
- package/dist/egress-policy.d.ts +0 -9
- package/dist/hooks.d.ts +0 -43
- package/dist/manifest.d.ts +0 -76
- package/dist/operations.d.ts +0 -153
- package/dist/prompt.d.ts +0 -56
- package/dist/registration.d.ts +0 -28
- package/dist/resource-events.d.ts +0 -128
- package/dist/schemas.d.ts +0 -261
- package/dist/state.d.ts +0 -10
- package/dist/tasks.d.ts +0 -250
- package/dist/tools.d.ts +0 -351
- package/dist/user-pages.d.ts +0 -97
- package/src/annotations.ts +0 -78
- package/src/cli.ts +0 -54
- package/src/code.ts +0 -37
- package/src/context.ts +0 -241
- package/src/conversation-events.ts +0 -136
- package/src/credentials.ts +0 -221
- package/src/dispatch.ts +0 -31
- package/src/egress-policy.ts +0 -15
- package/src/hooks.ts +0 -118
- package/src/index.ts +0 -29
- package/src/manifest.ts +0 -89
- package/src/operations.ts +0 -199
- package/src/prompt.ts +0 -99
- package/src/registration.ts +0 -173
- package/src/resource-events.ts +0 -320
- package/src/schemas.ts +0 -348
- package/src/state.ts +0 -15
- package/src/tasks.ts +0 -105
- package/src/tools.ts +0 -579
- package/src/user-pages.ts +0 -130
package/src/context.ts
DELETED
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import type { ZodTypeAny } from "zod";
|
|
3
|
-
import {
|
|
4
|
-
destinationSchema,
|
|
5
|
-
identitySchema,
|
|
6
|
-
locationSchema,
|
|
7
|
-
webActorSchema,
|
|
8
|
-
localActorSchema,
|
|
9
|
-
platformSchema,
|
|
10
|
-
actorSchema,
|
|
11
|
-
slackActorSchema,
|
|
12
|
-
systemActorSchema,
|
|
13
|
-
sourceSchema,
|
|
14
|
-
sourceVisibilitySchema,
|
|
15
|
-
slackLocationSchema,
|
|
16
|
-
userSchema,
|
|
17
|
-
} from "./schemas";
|
|
18
|
-
|
|
19
|
-
/** Runtime platform name without source or destination coordinates. */
|
|
20
|
-
export type Platform = z.output<typeof platformSchema>;
|
|
21
|
-
export type Actor = z.output<typeof actorSchema>;
|
|
22
|
-
export type SlackActor = z.output<typeof slackActorSchema>;
|
|
23
|
-
export type LocalActor = z.output<typeof localActorSchema>;
|
|
24
|
-
export type WebActor = z.output<typeof webActorSchema>;
|
|
25
|
-
export type SystemActor = z.output<typeof systemActorSchema>;
|
|
26
|
-
export type Identity = z.output<typeof identitySchema>;
|
|
27
|
-
export type User = z.output<typeof userSchema>;
|
|
28
|
-
export type Source = z.output<typeof sourceSchema>;
|
|
29
|
-
/** Validated Location associated with a Conversation. */
|
|
30
|
-
export type Location = z.output<typeof locationSchema>;
|
|
31
|
-
/** Complete Slack Location associated with a Conversation. */
|
|
32
|
-
export type SlackLocation = z.output<typeof slackLocationSchema>;
|
|
33
|
-
export type SlackSource = Extract<Source, { kind: "slack" }>;
|
|
34
|
-
export type LocalSource = Extract<Source, { kind: "local" }>;
|
|
35
|
-
export type WebSource = Extract<Source, { kind: "web" }>;
|
|
36
|
-
export type ResourceEventSource = Extract<Source, { kind: "resource_event" }>;
|
|
37
|
-
export type ScheduledTaskSource = Extract<Source, { kind: "scheduled_task" }>;
|
|
38
|
-
export type EventTaskSource = Extract<Source, { kind: "event_task" }>;
|
|
39
|
-
export type PluginDispatchSource = Extract<Source, { kind: "plugin_dispatch" }>;
|
|
40
|
-
export type AgentInvocationSource = Extract<
|
|
41
|
-
Source,
|
|
42
|
-
{ kind: "agent_invocation" }
|
|
43
|
-
>;
|
|
44
|
-
export type SourceVisibility = z.output<typeof sourceVisibilitySchema>;
|
|
45
|
-
|
|
46
|
-
export type Destination = z.output<typeof destinationSchema>;
|
|
47
|
-
|
|
48
|
-
export type SlackDestination = Extract<Destination, { platform: "slack" }>;
|
|
49
|
-
|
|
50
|
-
export type LocalDestination = Extract<Destination, { platform: "local" }>;
|
|
51
|
-
|
|
52
|
-
export interface PluginMetadata {
|
|
53
|
-
name: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface PluginLogger {
|
|
57
|
-
error(message: string, metadata?: Record<string, unknown>): void;
|
|
58
|
-
info(message: string, metadata?: Record<string, unknown>): void;
|
|
59
|
-
warn(message: string, metadata?: Record<string, unknown>): void;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export interface PluginModel {
|
|
63
|
-
/** Run a host-owned structured model call without exposing provider credentials. */
|
|
64
|
-
completeObject<TSchema extends ZodTypeAny>(input: {
|
|
65
|
-
maxTokens?: number;
|
|
66
|
-
prompt: string;
|
|
67
|
-
schema: TSchema;
|
|
68
|
-
system?: string;
|
|
69
|
-
}): Promise<{
|
|
70
|
-
/** Best-effort estimated provider cost for this completion. */
|
|
71
|
-
costUsd?: number;
|
|
72
|
-
object: z.infer<TSchema>;
|
|
73
|
-
}>;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export interface PluginEmbedder {
|
|
77
|
-
/** Embed plugin-owned text for derived retrieval without exposing provider credentials. */
|
|
78
|
-
embedTexts(input: { texts: string[] }): Promise<{
|
|
79
|
-
/** Best-effort estimated provider cost for this embedding call. */
|
|
80
|
-
costUsd?: number;
|
|
81
|
-
dimensions: number;
|
|
82
|
-
model: string;
|
|
83
|
-
provider: string;
|
|
84
|
-
vectors: number[][];
|
|
85
|
-
}>;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export interface PluginContext {
|
|
89
|
-
/** Shared Drizzle database connection for plugin runtime code. */
|
|
90
|
-
db: unknown;
|
|
91
|
-
log: PluginLogger;
|
|
92
|
-
plugin: PluginMetadata;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
interface BaseInvocationContext {
|
|
96
|
-
/**
|
|
97
|
-
* Opaque Junior conversation/session identity for this invocation.
|
|
98
|
-
* Interactive Slack turns use `slack:{channelId}:{threadTs}`.
|
|
99
|
-
*/
|
|
100
|
-
conversationId?: string;
|
|
101
|
-
/** Location associated with this Conversation. */
|
|
102
|
-
locationId?: string;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export interface SlackInvocationContext extends BaseInvocationContext {
|
|
106
|
-
/** Runtime-owned default outbound destination for this invocation. */
|
|
107
|
-
destination: SlackDestination;
|
|
108
|
-
actor?: SlackActor;
|
|
109
|
-
/** Runtime-owned source where the invocation came from. */
|
|
110
|
-
source: SlackSource;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export interface LocalInvocationContext extends BaseInvocationContext {
|
|
114
|
-
/** Runtime-owned default outbound destination for this invocation. */
|
|
115
|
-
destination: LocalDestination;
|
|
116
|
-
actor?: LocalActor;
|
|
117
|
-
/** Runtime-owned source where the invocation came from. */
|
|
118
|
-
source: LocalSource;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export interface WebInvocationContext extends BaseInvocationContext {
|
|
122
|
-
/** Existing conversation destination used for location and tool context. */
|
|
123
|
-
destination: Destination;
|
|
124
|
-
actor?: WebActor;
|
|
125
|
-
/** Runtime-owned dashboard/web source for this invocation. */
|
|
126
|
-
source: WebSource;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export interface ResourceEventInvocationContext extends BaseInvocationContext {
|
|
130
|
-
/** Existing conversation destination used for tool context. */
|
|
131
|
-
destination: Destination;
|
|
132
|
-
actor?: Actor;
|
|
133
|
-
/** Runtime-owned Resource event Source for this invocation. */
|
|
134
|
-
source: ResourceEventSource;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export type InvocationContext =
|
|
138
|
-
| LocalInvocationContext
|
|
139
|
-
| SlackInvocationContext
|
|
140
|
-
| WebInvocationContext
|
|
141
|
-
| (BaseInvocationContext & {
|
|
142
|
-
destination: Destination;
|
|
143
|
-
actor?: Actor;
|
|
144
|
-
source:
|
|
145
|
-
| AgentInvocationSource
|
|
146
|
-
| EventTaskSource
|
|
147
|
-
| PluginDispatchSource
|
|
148
|
-
| ResourceEventSource
|
|
149
|
-
| ScheduledTaskSource;
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
/** Build a normalized Slack source from runtime-owned Slack coordinates. */
|
|
153
|
-
export function createSlackSource(input: {
|
|
154
|
-
channelId: string;
|
|
155
|
-
messageTs?: string;
|
|
156
|
-
teamId: string;
|
|
157
|
-
threadTs?: string;
|
|
158
|
-
/** Runtime-normalized source visibility. */
|
|
159
|
-
visibility: SourceVisibility;
|
|
160
|
-
}): SlackSource {
|
|
161
|
-
return {
|
|
162
|
-
kind: "slack",
|
|
163
|
-
visibility: input.visibility,
|
|
164
|
-
teamId: input.teamId,
|
|
165
|
-
channelId: input.channelId,
|
|
166
|
-
...(input.messageTs ? { messageTs: input.messageTs } : undefined),
|
|
167
|
-
...(input.threadTs ? { threadTs: input.threadTs } : undefined),
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/** Build a normalized local source from a local conversation id. */
|
|
172
|
-
export function createLocalSource(conversationId: string): LocalSource {
|
|
173
|
-
return {
|
|
174
|
-
kind: "local",
|
|
175
|
-
visibility: "private",
|
|
176
|
-
conversationId,
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/** Build a normalized web/dashboard source from a conversation id. */
|
|
181
|
-
export function createWebSource(
|
|
182
|
-
conversationId: string,
|
|
183
|
-
visibility: SourceVisibility = "public",
|
|
184
|
-
): WebSource {
|
|
185
|
-
return {
|
|
186
|
-
kind: "web",
|
|
187
|
-
visibility,
|
|
188
|
-
conversationId,
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/** Build a normalized Resource event Source from one matched event. */
|
|
193
|
-
export function createResourceEventSource(input: {
|
|
194
|
-
eventKey: string;
|
|
195
|
-
eventType: string;
|
|
196
|
-
identifier: string;
|
|
197
|
-
namespace: string;
|
|
198
|
-
}): ResourceEventSource {
|
|
199
|
-
return {
|
|
200
|
-
kind: "resource_event",
|
|
201
|
-
eventKey: input.eventKey,
|
|
202
|
-
eventType: input.eventType,
|
|
203
|
-
identifier: input.identifier,
|
|
204
|
-
namespace: input.namespace,
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/** Return whether a source is private to a person or restricted group. */
|
|
209
|
-
export function isPrivateSource(source: Source): boolean {
|
|
210
|
-
return "visibility" in source && source.visibility === "private";
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/** Return the stable source identity used for idempotency and attribution. */
|
|
214
|
-
export function getSourceKey(source: Source): string | undefined {
|
|
215
|
-
switch (source.kind) {
|
|
216
|
-
case "web":
|
|
217
|
-
case "local":
|
|
218
|
-
return source.conversationId;
|
|
219
|
-
case "slack": {
|
|
220
|
-
const messageKey = source.threadTs ?? source.messageTs;
|
|
221
|
-
if (!messageKey) {
|
|
222
|
-
return undefined;
|
|
223
|
-
}
|
|
224
|
-
return `slack:${source.teamId}:${source.channelId}:${messageKey}`;
|
|
225
|
-
}
|
|
226
|
-
case "resource_event":
|
|
227
|
-
return `resource-event:${source.namespace}:${source.eventKey}`;
|
|
228
|
-
case "scheduled_task":
|
|
229
|
-
case "event_task":
|
|
230
|
-
case "plugin_dispatch":
|
|
231
|
-
case "agent_invocation":
|
|
232
|
-
return undefined;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/** Narrow a runtime destination to the Slack-specific address shape. */
|
|
237
|
-
export function isSlackDestination(
|
|
238
|
-
destination: Destination | undefined,
|
|
239
|
-
): destination is SlackDestination {
|
|
240
|
-
return destination?.platform === "slack";
|
|
241
|
-
}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
const conversationEventNameSchema = z
|
|
4
|
-
.string()
|
|
5
|
-
.trim()
|
|
6
|
-
.min(1)
|
|
7
|
-
.max(64)
|
|
8
|
-
.regex(/^[a-z][a-z0-9_]*$/);
|
|
9
|
-
|
|
10
|
-
export const conversationEventIconSchema = z.enum([
|
|
11
|
-
"activity",
|
|
12
|
-
"brain",
|
|
13
|
-
"calendar",
|
|
14
|
-
"check",
|
|
15
|
-
"database",
|
|
16
|
-
"info",
|
|
17
|
-
"key",
|
|
18
|
-
"link",
|
|
19
|
-
"sparkles",
|
|
20
|
-
"warning",
|
|
21
|
-
]);
|
|
22
|
-
|
|
23
|
-
const conversationEventDetailSchema = z
|
|
24
|
-
.object({
|
|
25
|
-
content: z
|
|
26
|
-
.string()
|
|
27
|
-
.min(1)
|
|
28
|
-
.max(32 * 1024)
|
|
29
|
-
.optional(),
|
|
30
|
-
description: z.string().trim().min(1).max(2_000).optional(),
|
|
31
|
-
metadata: z.array(z.string().trim().min(1).max(120)).max(8).optional(),
|
|
32
|
-
title: z.string().trim().min(1).max(4_000),
|
|
33
|
-
})
|
|
34
|
-
.strict();
|
|
35
|
-
|
|
36
|
-
/** Safe, core-rendered presentation for one plugin conversation event. */
|
|
37
|
-
export const conversationEventPresentationSchema = z
|
|
38
|
-
.object({
|
|
39
|
-
details: z.array(conversationEventDetailSchema).max(100).optional(),
|
|
40
|
-
icon: conversationEventIconSchema.optional(),
|
|
41
|
-
preview: z.string().trim().min(1).max(500).optional(),
|
|
42
|
-
title: z.string().trim().min(1).max(120),
|
|
43
|
-
})
|
|
44
|
-
.strict();
|
|
45
|
-
|
|
46
|
-
export type ConversationEventPresentation = z.output<
|
|
47
|
-
typeof conversationEventPresentationSchema
|
|
48
|
-
>;
|
|
49
|
-
|
|
50
|
-
/** One validated plugin event value waiting for conversation-bound emission. */
|
|
51
|
-
export interface PluginConversationEventValue {
|
|
52
|
-
readonly data: Record<string, unknown>;
|
|
53
|
-
readonly definition: PluginConversationEventDefinition;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** Registered schema and optional transcript presentation for one event version. */
|
|
57
|
-
export interface PluginConversationEventDefinition {
|
|
58
|
-
readonly eventName: string;
|
|
59
|
-
readonly version: number;
|
|
60
|
-
parse(data: unknown): Record<string, unknown>;
|
|
61
|
-
renderEvent(
|
|
62
|
-
data: Record<string, unknown>,
|
|
63
|
-
): ConversationEventPresentation | undefined;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/** Typed factory returned while authoring one plugin conversation event. */
|
|
67
|
-
export interface DefinedConversationEvent<
|
|
68
|
-
TInput,
|
|
69
|
-
> extends PluginConversationEventDefinition {
|
|
70
|
-
(data: TInput): PluginConversationEventValue;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/** Define one typed, versioned plugin-owned conversation event. */
|
|
74
|
-
export function defineConversationEvent<
|
|
75
|
-
TSchema extends z.ZodType<Record<string, unknown>>,
|
|
76
|
-
>(definition: {
|
|
77
|
-
name: string;
|
|
78
|
-
version: number;
|
|
79
|
-
schema: TSchema;
|
|
80
|
-
renderEvent(
|
|
81
|
-
event: z.output<TSchema>,
|
|
82
|
-
): z.input<typeof conversationEventPresentationSchema> | undefined;
|
|
83
|
-
}): DefinedConversationEvent<z.input<TSchema>> {
|
|
84
|
-
const identity = z
|
|
85
|
-
.object({
|
|
86
|
-
name: conversationEventNameSchema,
|
|
87
|
-
version: z.number().int().positive(),
|
|
88
|
-
})
|
|
89
|
-
.strict()
|
|
90
|
-
.parse({ name: definition.name, version: definition.version });
|
|
91
|
-
let eventDefinition: DefinedConversationEvent<z.input<TSchema>>;
|
|
92
|
-
const createEvent = (
|
|
93
|
-
data: z.input<TSchema>,
|
|
94
|
-
): PluginConversationEventValue => ({
|
|
95
|
-
data: definition.schema.parse(data),
|
|
96
|
-
definition: eventDefinition,
|
|
97
|
-
});
|
|
98
|
-
eventDefinition = Object.assign(createEvent, {
|
|
99
|
-
eventName: identity.name,
|
|
100
|
-
version: identity.version,
|
|
101
|
-
parse(data: unknown) {
|
|
102
|
-
return definition.schema.parse(data);
|
|
103
|
-
},
|
|
104
|
-
renderEvent(data: Record<string, unknown>) {
|
|
105
|
-
const parsed = definition.schema.parse(data);
|
|
106
|
-
const presentation = definition.renderEvent(parsed);
|
|
107
|
-
return presentation === undefined
|
|
108
|
-
? undefined
|
|
109
|
-
: conversationEventPresentationSchema.parse(presentation);
|
|
110
|
-
},
|
|
111
|
-
});
|
|
112
|
-
return eventDefinition;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/** Conversation-bound event writer supplied by Junior core. */
|
|
116
|
-
export interface PluginConversationEvents {
|
|
117
|
-
emit(event: PluginConversationEventValue): Promise<void>;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export interface PluginConversationEventCostDay {
|
|
121
|
-
costUsd: number;
|
|
122
|
-
date: string;
|
|
123
|
-
events: number;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/** Read aggregate costs for events owned by the current plugin namespace. */
|
|
127
|
-
export interface PluginConversationEventStats {
|
|
128
|
-
costsByDay(input: {
|
|
129
|
-
days: 7 | 30 | 90;
|
|
130
|
-
eventName: string;
|
|
131
|
-
}): Promise<PluginConversationEventCostDay[]>;
|
|
132
|
-
costsByHour(input: {
|
|
133
|
-
eventName: string;
|
|
134
|
-
hours?: number;
|
|
135
|
-
}): Promise<PluginConversationEventCostDay[]>;
|
|
136
|
-
}
|
package/src/credentials.ts
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import type { PluginContext } from "./context";
|
|
3
|
-
import { nonBlankStringSchema, pluginCredentialSubjectSchema } from "./schemas";
|
|
4
|
-
|
|
5
|
-
const pluginProviderNameSchema = z.string().regex(/^[a-z][a-z0-9-]*$/);
|
|
6
|
-
const pluginGrantNameSchema = z.string().regex(/^[a-z][a-z0-9.-]*$/);
|
|
7
|
-
const pluginGrantAccessSchema = z.union([
|
|
8
|
-
z.literal("read"),
|
|
9
|
-
z.literal("write"),
|
|
10
|
-
]);
|
|
11
|
-
|
|
12
|
-
/** Runtime schema for provider authorization a plugin may request. */
|
|
13
|
-
export const pluginAuthorizationSchema = z
|
|
14
|
-
.object({
|
|
15
|
-
provider: pluginProviderNameSchema,
|
|
16
|
-
scope: nonBlankStringSchema.optional(),
|
|
17
|
-
type: z.literal("oauth"),
|
|
18
|
-
})
|
|
19
|
-
.strict();
|
|
20
|
-
|
|
21
|
-
/** Runtime schema for a provider account attached to stored OAuth tokens. */
|
|
22
|
-
export const pluginProviderAccountSchema = z
|
|
23
|
-
.object({
|
|
24
|
-
displayName: nonBlankStringSchema.optional(),
|
|
25
|
-
handle: nonBlankStringSchema.optional(),
|
|
26
|
-
id: nonBlankStringSchema,
|
|
27
|
-
label: nonBlankStringSchema.optional(),
|
|
28
|
-
url: nonBlankStringSchema.optional(),
|
|
29
|
-
})
|
|
30
|
-
.strict();
|
|
31
|
-
|
|
32
|
-
/** Runtime schema for OAuth tokens stored by the host for plugin credentials. */
|
|
33
|
-
export const pluginStoredTokensSchema = z
|
|
34
|
-
.object({
|
|
35
|
-
account: pluginProviderAccountSchema.optional(),
|
|
36
|
-
accessToken: nonBlankStringSchema,
|
|
37
|
-
expiresAt: z.number().finite().optional(),
|
|
38
|
-
refreshToken: nonBlankStringSchema,
|
|
39
|
-
refreshTokenExpiresAt: z.number().finite().optional(),
|
|
40
|
-
scope: nonBlankStringSchema.optional(),
|
|
41
|
-
})
|
|
42
|
-
.strict();
|
|
43
|
-
|
|
44
|
-
/** Runtime schema for a plugin-defined outbound credential grant. */
|
|
45
|
-
export const pluginGrantSchema = z
|
|
46
|
-
.object({
|
|
47
|
-
access: pluginGrantAccessSchema,
|
|
48
|
-
leaseScope: nonBlankStringSchema.optional(),
|
|
49
|
-
name: pluginGrantNameSchema,
|
|
50
|
-
reason: nonBlankStringSchema.optional(),
|
|
51
|
-
requirements: z.array(nonBlankStringSchema).min(1).optional(),
|
|
52
|
-
})
|
|
53
|
-
.strict();
|
|
54
|
-
|
|
55
|
-
/** Runtime schema for plugin-issued header mutations. */
|
|
56
|
-
export const pluginCredentialHeaderTransformSchema = z
|
|
57
|
-
.object({
|
|
58
|
-
domain: z.string().min(1),
|
|
59
|
-
headers: z
|
|
60
|
-
.record(z.string(), z.string())
|
|
61
|
-
.refine((headers) => Object.keys(headers).length > 0),
|
|
62
|
-
})
|
|
63
|
-
.strict();
|
|
64
|
-
|
|
65
|
-
/** Runtime schema for a short-lived plugin-issued credential lease. */
|
|
66
|
-
export const pluginCredentialLeaseSchema = z
|
|
67
|
-
.object({
|
|
68
|
-
account: pluginProviderAccountSchema.optional(),
|
|
69
|
-
authorization: pluginAuthorizationSchema.optional(),
|
|
70
|
-
expiresAt: z.string().refine((value) => Number.isFinite(Date.parse(value))),
|
|
71
|
-
headerTransforms: z.array(pluginCredentialHeaderTransformSchema).min(1),
|
|
72
|
-
})
|
|
73
|
-
.strict();
|
|
74
|
-
|
|
75
|
-
/** Runtime schema for the result returned by a plugin credential hook. */
|
|
76
|
-
export const pluginCredentialResultSchema = z.discriminatedUnion("type", [
|
|
77
|
-
z
|
|
78
|
-
.object({
|
|
79
|
-
lease: pluginCredentialLeaseSchema,
|
|
80
|
-
type: z.literal("lease"),
|
|
81
|
-
})
|
|
82
|
-
.strict(),
|
|
83
|
-
z
|
|
84
|
-
.object({
|
|
85
|
-
authorization: pluginAuthorizationSchema.optional(),
|
|
86
|
-
message: nonBlankStringSchema,
|
|
87
|
-
type: z.literal("needed"),
|
|
88
|
-
})
|
|
89
|
-
.strict(),
|
|
90
|
-
z
|
|
91
|
-
.object({
|
|
92
|
-
message: nonBlankStringSchema,
|
|
93
|
-
type: z.literal("unavailable"),
|
|
94
|
-
})
|
|
95
|
-
.strict(),
|
|
96
|
-
]);
|
|
97
|
-
|
|
98
|
-
export type PluginCredentialSubject = z.output<
|
|
99
|
-
typeof pluginCredentialSubjectSchema
|
|
100
|
-
>;
|
|
101
|
-
|
|
102
|
-
export type PluginGrantAccess = z.output<typeof pluginGrantAccessSchema>;
|
|
103
|
-
|
|
104
|
-
/** Provider authorization Junior can start when a plugin-owned grant is missing. */
|
|
105
|
-
export type PluginAuthorization = z.output<typeof pluginAuthorizationSchema>;
|
|
106
|
-
|
|
107
|
-
/** Interrupt sandbox egress so Junior can start provider authorization. */
|
|
108
|
-
export class EgressAuthRequired extends Error {
|
|
109
|
-
authorization?: PluginAuthorization;
|
|
110
|
-
|
|
111
|
-
constructor(
|
|
112
|
-
message: string,
|
|
113
|
-
options?: {
|
|
114
|
-
authorization?: PluginAuthorization;
|
|
115
|
-
cause?: unknown;
|
|
116
|
-
},
|
|
117
|
-
) {
|
|
118
|
-
super(message, { cause: options?.cause });
|
|
119
|
-
this.name = "EgressAuthRequired";
|
|
120
|
-
this.authorization = options?.authorization;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/** Deny provider egress before Junior issues credentials for a disallowed operation. */
|
|
125
|
-
export class EgressPolicyDenied extends Error {
|
|
126
|
-
constructor(message: string, options?: { cause?: unknown }) {
|
|
127
|
-
super(message, { cause: options?.cause });
|
|
128
|
-
this.name = "EgressPolicyDenied";
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/** Provider account identity resolved by a plugin OAuth hook. */
|
|
133
|
-
export type PluginProviderAccount = z.output<
|
|
134
|
-
typeof pluginProviderAccountSchema
|
|
135
|
-
>;
|
|
136
|
-
|
|
137
|
-
/** Plugin-defined grant required before Junior can forward one outbound request. */
|
|
138
|
-
export type PluginGrant = z.output<typeof pluginGrantSchema>;
|
|
139
|
-
|
|
140
|
-
/** Request details available while selecting the grant for sandbox egress. */
|
|
141
|
-
export interface PluginEgressRequest {
|
|
142
|
-
/** Capped request body text when the host exposes it for provider-specific grant classification. */
|
|
143
|
-
bodyText?: string;
|
|
144
|
-
method: string;
|
|
145
|
-
/** Plugin-declared operation this request performs, used for grant classification and diagnostics. */
|
|
146
|
-
operation?: string;
|
|
147
|
-
url: string;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export interface EgressHookContext extends PluginContext {
|
|
151
|
-
request: PluginEgressRequest;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
export interface PluginEgressResponse {
|
|
155
|
-
/** Snapshot of upstream response headers; mutations do not affect pass-through. */
|
|
156
|
-
headers: Headers;
|
|
157
|
-
readText(maxBytes: number): Promise<string | undefined>;
|
|
158
|
-
status: number;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export interface EgressResponseHookContext extends PluginContext {
|
|
162
|
-
grant: PluginGrant;
|
|
163
|
-
permissionDenied(message: string): void;
|
|
164
|
-
request: Omit<PluginEgressRequest, "bodyText">;
|
|
165
|
-
response: PluginEgressResponse;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/** Header mutations a plugin-issued credential lease may apply to owned domains. */
|
|
169
|
-
export type PluginCredentialHeaderTransform = z.output<
|
|
170
|
-
typeof pluginCredentialHeaderTransformSchema
|
|
171
|
-
>;
|
|
172
|
-
|
|
173
|
-
/** Short-lived credential headers issued by a plugin for a selected grant. */
|
|
174
|
-
export type PluginCredentialLease = z.output<
|
|
175
|
-
typeof pluginCredentialLeaseSchema
|
|
176
|
-
>;
|
|
177
|
-
|
|
178
|
-
export type PluginCredentialResult = z.output<
|
|
179
|
-
typeof pluginCredentialResultSchema
|
|
180
|
-
>;
|
|
181
|
-
|
|
182
|
-
export type PluginCredentialActor =
|
|
183
|
-
| {
|
|
184
|
-
platform: "system";
|
|
185
|
-
name: string;
|
|
186
|
-
}
|
|
187
|
-
| {
|
|
188
|
-
type: "user";
|
|
189
|
-
userId: string;
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
export interface PluginResolvedCredentialUser {
|
|
193
|
-
type: "user";
|
|
194
|
-
userId: string;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
export type PluginStoredTokens = z.output<typeof pluginStoredTokensSchema>;
|
|
198
|
-
|
|
199
|
-
export interface PluginUserTokenSlot {
|
|
200
|
-
get(): Promise<PluginStoredTokens | undefined>;
|
|
201
|
-
set(tokens: PluginStoredTokens): Promise<void>;
|
|
202
|
-
/** Run token refresh work after the host has serialized this user/provider slot, or throw after a bounded wait. */
|
|
203
|
-
withRefresh<T>(callback: () => Promise<T>): Promise<T>;
|
|
204
|
-
userId: string;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
export interface PluginTokenStore {
|
|
208
|
-
credentialSubject?: PluginUserTokenSlot;
|
|
209
|
-
currentUser?: PluginUserTokenSlot;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
export interface ResolveOAuthAccountHookContext extends PluginContext {
|
|
213
|
-
tokens: PluginStoredTokens;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
export interface IssueCredentialHookContext extends PluginContext {
|
|
217
|
-
actor: PluginCredentialActor;
|
|
218
|
-
credentialSubject?: PluginResolvedCredentialUser;
|
|
219
|
-
grant: PluginGrant;
|
|
220
|
-
tokens: PluginTokenStore;
|
|
221
|
-
}
|
package/src/dispatch.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import {
|
|
3
|
-
destinationVisibilitySchema,
|
|
4
|
-
dispatchOptionsSchema,
|
|
5
|
-
replyAttributionSchema,
|
|
6
|
-
} from "./schemas";
|
|
7
|
-
|
|
8
|
-
export type DestinationVisibility = z.output<
|
|
9
|
-
typeof destinationVisibilitySchema
|
|
10
|
-
>;
|
|
11
|
-
export type DispatchOptions = z.output<typeof dispatchOptionsSchema>;
|
|
12
|
-
/** Compact destination-visible context explaining what produced a reply. */
|
|
13
|
-
export type ReplyAttribution = z.output<typeof replyAttributionSchema>;
|
|
14
|
-
|
|
15
|
-
export interface DispatchResult {
|
|
16
|
-
id: string;
|
|
17
|
-
status: "created" | "already_exists";
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface Dispatch {
|
|
21
|
-
errorMessage?: string;
|
|
22
|
-
id: string;
|
|
23
|
-
resultMessageTs?: string;
|
|
24
|
-
status:
|
|
25
|
-
| "pending"
|
|
26
|
-
| "running"
|
|
27
|
-
| "awaiting_resume"
|
|
28
|
-
| "completed"
|
|
29
|
-
| "failed"
|
|
30
|
-
| "blocked";
|
|
31
|
-
}
|
package/src/egress-policy.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { EgressPolicyDenied } from "./credentials";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Deny provider egress when a plugin policy does not allow the request.
|
|
5
|
-
*
|
|
6
|
-
* Call from a plugin `grantForEgress` hook before returning a write grant.
|
|
7
|
-
*/
|
|
8
|
-
export function enforceEgressPolicy(input: {
|
|
9
|
-
allowed: boolean;
|
|
10
|
-
denialMessage: string;
|
|
11
|
-
}): void {
|
|
12
|
-
if (!input.allowed) {
|
|
13
|
-
throw new EgressPolicyDenied(input.denialMessage);
|
|
14
|
-
}
|
|
15
|
-
}
|