@sentry/junior-plugin-api 0.268.0 → 0.269.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/README.md +7 -181
- package/dist/index.d.ts +46 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,185 +1,11 @@
|
|
|
1
1
|
# @sentry/junior-plugin-api
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Types and helpers for Junior code plugins. Use `defineJuniorPlugin()` to
|
|
4
|
+
declare a manifest, hooks, tasks, CLI commands, user pages, and conversation
|
|
5
|
+
events.
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @sentry/junior-plugin-api
|
|
9
|
+
```
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
`defineJuniorPlugin({ manifest, hooks, tasks, cli, model, conversationEvents })`.
|
|
10
|
-
A plugin name is a lowercase identifier and is unique within the enabled app
|
|
11
|
-
plugin set.
|
|
12
|
-
|
|
13
|
-
Packages with JavaScript registration export one callable factory named
|
|
14
|
-
`<domain>Plugin`, such as `githubPlugin(options?)`. Do not use a public
|
|
15
|
-
`create<Domain>Plugin` alias or export a prebuilt registration. Call the factory
|
|
16
|
-
even when it accepts no options.
|
|
17
|
-
|
|
18
|
-
A plugin may instead be a declarative `plugin.yaml` package when it has no
|
|
19
|
-
host-executed hooks. Do not combine an inline manifest with a second YAML
|
|
20
|
-
definition for the same plugin.
|
|
21
|
-
|
|
22
|
-
## Manifest
|
|
23
|
-
|
|
24
|
-
The manifest declares runtime metadata such as:
|
|
25
|
-
|
|
26
|
-
- plugin identity and description;
|
|
27
|
-
- skill roots and MCP tool sources;
|
|
28
|
-
- provider domains, grants, OAuth, API-header transformations, and safe command
|
|
29
|
-
environment placeholders;
|
|
30
|
-
- runtime dependencies and snapshot installation steps;
|
|
31
|
-
- configuration fields;
|
|
32
|
-
- signed-in user pages backed by core-owned discovery and read routes.
|
|
33
|
-
|
|
34
|
-
Manifest values are validated before runtime activation. Secret deployment
|
|
35
|
-
values remain host-only; sandbox-exposed command environment must be explicitly
|
|
36
|
-
safe.
|
|
37
|
-
|
|
38
|
-
## Hooks
|
|
39
|
-
|
|
40
|
-
Plugins may contribute tools, prompt messages, lifecycle work, operational
|
|
41
|
-
reports, and other typed hook surfaces exported by this package.
|
|
42
|
-
|
|
43
|
-
- Hook context carries the active source, actor, conversation, plugin metadata,
|
|
44
|
-
database, logging, and only the host capabilities required by that hook.
|
|
45
|
-
- Source uses `kind` to state what produced the input. Events,
|
|
46
|
-
scheduled automations, event automations, Plugin dispatches, and Agent invocations do not
|
|
47
|
-
name a provider. Actor and Destination still use `platform` to name one.
|
|
48
|
-
- Prompt hooks return bounded structured prompt messages rather than mutate the
|
|
49
|
-
core prompt.
|
|
50
|
-
- `formatMarkdown` is a pure text rewrite into ordinary Markdown before delivery.
|
|
51
|
-
- `conversationTitleContext` returns short facts about objects that the first
|
|
52
|
-
human message refers to, such as an issue number and title. The hook gets the
|
|
53
|
-
plugin's config values, such as a default repository. It must read provider
|
|
54
|
-
data through `ctx.egress`, which uses Junior's system identity and never
|
|
55
|
-
starts authorization. Only the title model sees the facts. Junior bounds the
|
|
56
|
-
wait and ignores a failed hook.
|
|
57
|
-
- User prompt hooks for durable turns may emit registered structured events
|
|
58
|
-
through `ctx.events` for auxiliary work completed while building context.
|
|
59
|
-
- Tool hooks return model-visible schemas aligned with their executor inputs.
|
|
60
|
-
- Tool registration hooks may use `ctx.sandbox` for plugin-owned workspace
|
|
61
|
-
files and commands; Junior still owns sandbox lifecycle, cancellation,
|
|
62
|
-
provider egress, and authorization recovery.
|
|
63
|
-
- Host-owned structured model and embedding calls do not expose provider
|
|
64
|
-
credentials to plugins. Both return a best-effort provider cost estimate when
|
|
65
|
-
one is available.
|
|
66
|
-
- Operational report and authenticated API hooks may aggregate `costUsd` from
|
|
67
|
-
their own registered conversation events through `ctx.eventStats`. Core
|
|
68
|
-
binds the plugin namespace and owns access to the conversation event log.
|
|
69
|
-
Event `costUsd` is additive operation cost and must not duplicate cost
|
|
70
|
-
already recorded in the conversation's agent model usage.
|
|
71
|
-
- Profile report hooks return the same bounded operational report content for
|
|
72
|
-
one subject user on a person profile. Core owns viewer authorization,
|
|
73
|
-
collection, sanitization, and browser rendering.
|
|
74
|
-
- Tool hooks may resolve the active Actor's Identity and User through
|
|
75
|
-
`ctx.users.resolveActor()`, and the Actor's timezone through
|
|
76
|
-
`ctx.users.resolveTimezone()`.
|
|
77
|
-
- Authenticated API route hooks receive `ctx.users.resolve(email)` for lazy
|
|
78
|
-
User lookup. Routes that do not need User data do not query identity storage.
|
|
79
|
-
- User page readers receive the signed-in `User`. Plugins return limited data.
|
|
80
|
-
They do not mount their own page routes or browser code.
|
|
81
|
-
|
|
82
|
-
## User Pages
|
|
83
|
-
|
|
84
|
-
Register signed-in pages through `userPages` beside `hooks`, `tasks`, and `cli`.
|
|
85
|
-
Each definition owns its navigation metadata and `read(ctx, input)` function,
|
|
86
|
-
so a page cannot be advertised without an implementation. List readers receive
|
|
87
|
-
validated search and cursor input and may return an opaque continuation cursor.
|
|
88
|
-
Set `navigation: "primary"` for a top-level dashboard navigation item. The
|
|
89
|
-
default `profile` placement keeps account-oriented pages in the signed-in user
|
|
90
|
-
menu. Junior always renders core System navigation after plugin pages.
|
|
91
|
-
Set `navigation: "admin"` for setup that only Junior admins may use. Core lists
|
|
92
|
-
these pages on the dashboard Admin page and serves them only to admins. Core
|
|
93
|
-
reads the admin role from the user record on every request.
|
|
94
|
-
Records may expose bounded `DELETE` actions inside their own authenticated
|
|
95
|
-
plugin API namespace. Records may also expose `GET` actions. The dashboard opens
|
|
96
|
-
them as normal browser links, for example to start an OAuth sign-in. Core owns
|
|
97
|
-
discovery, authentication, user resolution, routing, response validation,
|
|
98
|
-
rendering, confirmation, and query state.
|
|
99
|
-
|
|
100
|
-
Authenticated plugin API routes receive `context.auth.user.isAdmin`. Core sets
|
|
101
|
-
it from the stored user on every request. Admin-only routes must check it on
|
|
102
|
-
the server, because a hidden link does not protect a route.
|
|
103
|
-
|
|
104
|
-
## Durable Work
|
|
105
|
-
|
|
106
|
-
- Heartbeat hooks perform bounded periodic maintenance and must be safe to run
|
|
107
|
-
repeatedly.
|
|
108
|
-
- Background tasks are registered by name, receive validated parameters, and
|
|
109
|
-
execute through the host queue/callback lifecycle.
|
|
110
|
-
- Conversation-bound background tasks may emit registered structured events
|
|
111
|
-
through `ctx.events`. Define each version with `defineConversationEvent()`;
|
|
112
|
-
the host supplies the plugin namespace, conversation, turn, ordering, and
|
|
113
|
-
timestamps without treating background work as new conversation activity.
|
|
114
|
-
Event definitions return bounded transcript presentation data, while Junior
|
|
115
|
-
owns browser rendering.
|
|
116
|
-
- `ctx.agent.dispatch` creates durable agent work with an explicit actor,
|
|
117
|
-
destination, source, metadata, and idempotency identity.
|
|
118
|
-
- Dispatches may include compact `replyAttribution` for destination-visible
|
|
119
|
-
context about what produced the reply. Core owns platform rendering; opaque
|
|
120
|
-
dispatch metadata remains internal.
|
|
121
|
-
- Delegated credential subjects declare the narrow action that authorized them.
|
|
122
|
-
Core owns runtime bindings; scheduler task subjects are accepted only from the
|
|
123
|
-
scheduler plugin and are bound to the exact task id.
|
|
124
|
-
- Completed dispatch and task projections are durable plugin inputs, not an
|
|
125
|
-
invitation to inspect unrestricted conversation state.
|
|
126
|
-
|
|
127
|
-
## Conversation Events
|
|
128
|
-
|
|
129
|
-
Register plugin-owned event definitions through `conversationEvents`. A
|
|
130
|
-
definition owns one local name, version, content schema, and `renderEvent()`
|
|
131
|
-
projection. A renderer may return `undefined` when an event should remain
|
|
132
|
-
durable without producing a transcript row. The active plugin context supplies
|
|
133
|
-
the namespace, so plugins cannot emit native events or impersonate another
|
|
134
|
-
plugin. The `junior` plugin name is reserved for host-owned native events.
|
|
135
|
-
Versions of the same event name share one operation idempotency identity,
|
|
136
|
-
so keep previous definitions registered when evolving an event. Stored events
|
|
137
|
-
remain durable when a plugin is removed, but normal transcript projection skips
|
|
138
|
-
definitions that are not currently registered.
|
|
139
|
-
|
|
140
|
-
## Database
|
|
141
|
-
|
|
142
|
-
- Packaged migrations create plugin-owned tables through the host migration
|
|
143
|
-
runner.
|
|
144
|
-
- Generate migration artifacts from the package schema; do not hand-maintain a
|
|
145
|
-
second schema contract.
|
|
146
|
-
- Runtime hooks and CLI actions use host-provided `ctx.db`.
|
|
147
|
-
- Migrations are expand-first, deterministic, ordered by plugin name, and safe
|
|
148
|
-
to retry. A failure blocks upgrade rather than partially enabling the plugin.
|
|
149
|
-
- Cross-plugin or core-table access is a review boundary for trusted app code;
|
|
150
|
-
introduce a facade only when a concrete security or lifecycle boundary
|
|
151
|
-
requires it.
|
|
152
|
-
|
|
153
|
-
## CLI
|
|
154
|
-
|
|
155
|
-
Code plugins may register one namespaced host CLI command with one or more
|
|
156
|
-
subcommands. Core command names win. Actions use the host action wrapper and
|
|
157
|
-
receive plugin metadata, configuration, database, safe output writers, and
|
|
158
|
-
logging—not model, Slack, sandbox, or provider credential context.
|
|
159
|
-
|
|
160
|
-
## Security
|
|
161
|
-
|
|
162
|
-
Plugins and skills follow `../../policies/security.md`,
|
|
163
|
-
`../../policies/data-redaction.md`, and
|
|
164
|
-
`../../policies/provider-boundaries.md`. Skills explain capability use; they do
|
|
165
|
-
not bootstrap runtimes or credentials.
|
|
166
|
-
|
|
167
|
-
## Object annotations
|
|
168
|
-
|
|
169
|
-
A tool can return `objectAnnotations` through `pluginToolOutputSchema` to save
|
|
170
|
-
object facts and attach a card to the next visible reply. The host assigns the
|
|
171
|
-
plugin owner. Use a stable `key` within the plugin, a compact `label`, a `title`,
|
|
172
|
-
a verified HTTP(S) `url` (or null), and an `objectType`: `task`, `code_change`,
|
|
173
|
-
`automation`, or `item`. Status and description are optional. Automations also
|
|
174
|
-
use `trigger` and `warning`. Do not send Slack layout JSON or infer facts that
|
|
175
|
-
the provider did not return.
|
|
176
|
-
|
|
177
|
-
Show at most four fact attributes plus status. Hide code-change size counts
|
|
178
|
-
and source update times without removing them from saved annotations.
|
|
179
|
-
|
|
180
|
-
The `afterMcpTool` hook can return `{ objectAnnotations }` after a successful
|
|
181
|
-
hosted tool call. Use `ctx.annotations.upsert` instead when facts must change
|
|
182
|
-
without selecting a reply card, such as a background webhook update. Only return
|
|
183
|
-
facts that can be shared with the current Conversation. Message cards reference
|
|
184
|
-
the latest saved annotation. Tool results remain immutable for agent history.
|
|
185
|
-
Neither cards nor annotations grant access to the provider.
|
|
11
|
+
Build a plugin: https://junior.sentry.dev/extend/build-a-plugin/
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { Command } from "commander";
|
|
|
9
9
|
* selects the fields it needs; preview rules must not remove saved facts.
|
|
10
10
|
*
|
|
11
11
|
* Keep raw responses, diffs, logs, credentials, and comments out of this schema.
|
|
12
|
-
* See "Object
|
|
12
|
+
* See "Object annotations and Message cards" in packages/junior/src/chat/conversations/AGENTS.md.
|
|
13
13
|
*/
|
|
14
14
|
export declare const objectAnnotationSchema: z.ZodObject<{
|
|
15
15
|
kind: z.ZodLiteral<"object">;
|
|
@@ -1869,6 +1869,44 @@ export interface IssueCredentialHookContext extends PluginContext {
|
|
|
1869
1869
|
grant: PluginGrant;
|
|
1870
1870
|
tokens: PluginTokenStore;
|
|
1871
1871
|
}
|
|
1872
|
+
/** A notice that a plugin puts on the review desk. */
|
|
1873
|
+
export interface PluginReviewNotice {
|
|
1874
|
+
/** Junior assigns the User linked to each Identity. */
|
|
1875
|
+
assigneeIdentityIds: string[];
|
|
1876
|
+
/** Markdown details for the person. */
|
|
1877
|
+
body: string;
|
|
1878
|
+
/**
|
|
1879
|
+
* Stable key for what the notice is about. A plugin has at most one open
|
|
1880
|
+
* item for each key.
|
|
1881
|
+
*/
|
|
1882
|
+
dedupeKey: string;
|
|
1883
|
+
/** What the notice is about, such as a pull request. Search matches `id`. */
|
|
1884
|
+
subject?: {
|
|
1885
|
+
id: string;
|
|
1886
|
+
title?: string;
|
|
1887
|
+
url?: string;
|
|
1888
|
+
};
|
|
1889
|
+
title: string;
|
|
1890
|
+
}
|
|
1891
|
+
/**
|
|
1892
|
+
* Review items that a plugin adds and closes from its own events. Each item
|
|
1893
|
+
* belongs to one Conversation. Core owns visibility, assignment rules, and
|
|
1894
|
+
* the Slack cards.
|
|
1895
|
+
*/
|
|
1896
|
+
export interface PluginReviewItems {
|
|
1897
|
+
/** Add an open notice, or replace the content of the open one with the key. */
|
|
1898
|
+
upsert(notice: PluginReviewNotice): Promise<void>;
|
|
1899
|
+
/** Close the open item with the key. Do nothing when no item is open. */
|
|
1900
|
+
close(input: {
|
|
1901
|
+
dedupeKey: string;
|
|
1902
|
+
reason: string;
|
|
1903
|
+
status: "done" | "dismissed";
|
|
1904
|
+
}): Promise<void>;
|
|
1905
|
+
}
|
|
1906
|
+
/** Review items of a plugin, for the Conversation that each item belongs to. */
|
|
1907
|
+
export interface PluginConversationReviewItems {
|
|
1908
|
+
forConversation(conversationId: string): PluginReviewItems;
|
|
1909
|
+
}
|
|
1872
1910
|
export interface HeartbeatHookContext extends PluginContext {
|
|
1873
1911
|
agent: {
|
|
1874
1912
|
dispatch(options: DispatchOptions): Promise<DispatchResult>;
|
|
@@ -1988,6 +2026,8 @@ export interface RouteRegistrationHookContext extends PluginContext {
|
|
|
1988
2026
|
codeChanges: CodeChangePublisher;
|
|
1989
2027
|
/** Core-owned delivery boundary for provider webhook events. */
|
|
1990
2028
|
events: EventPublisher;
|
|
2029
|
+
/** Review desk items that the plugin adds and closes from its events. */
|
|
2030
|
+
reviewItems: PluginConversationReviewItems;
|
|
1991
2031
|
users: {
|
|
1992
2032
|
/**
|
|
1993
2033
|
* Read one stored identity and the user it links to now, with every
|
|
@@ -2534,6 +2574,11 @@ export interface PluginHooks {
|
|
|
2534
2574
|
* that changes per request in `userPrompt`. See `policies/system-prompt.md`.
|
|
2535
2575
|
*/
|
|
2536
2576
|
systemPrompt?(ctx: SystemPromptContext): Promise<PromptMessage[]> | PromptMessage[];
|
|
2577
|
+
/**
|
|
2578
|
+
* Return per-request context for a new prompt, such as recalled memories.
|
|
2579
|
+
* Junior runs this hook at the same time as Turn routing and sandbox setup,
|
|
2580
|
+
* so it must not depend on either.
|
|
2581
|
+
*/
|
|
2537
2582
|
userPrompt?(ctx: UserPromptContext): Promise<UserPromptContribution[] | undefined> | UserPromptContribution[] | undefined;
|
|
2538
2583
|
beforeToolExecute?(ctx: BeforeToolExecuteHookContext): Promise<void> | void;
|
|
2539
2584
|
/**
|
package/dist/index.js
CHANGED
|
@@ -157,7 +157,7 @@ function objectIconPath(icon) {
|
|
|
157
157
|
* selects the fields it needs; preview rules must not remove saved facts.
|
|
158
158
|
*
|
|
159
159
|
* Keep raw responses, diffs, logs, credentials, and comments out of this schema.
|
|
160
|
-
* See "Object
|
|
160
|
+
* See "Object annotations and Message cards" in packages/junior/src/chat/conversations/AGENTS.md.
|
|
161
161
|
*/
|
|
162
162
|
const objectAnnotationSchema = z.object({
|
|
163
163
|
kind: z.literal("object"),
|