@godwit/sdk 0.0.0-stage → 1.6.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.
Files changed (3) hide show
  1. package/godwit.d.ts +252 -0
  2. package/package.json +17 -4
  3. package/README.md +0 -3
package/godwit.d.ts ADDED
@@ -0,0 +1,252 @@
1
+ // @godwit/sdk: types for Godwit plugins (spec 5.3). Types only; import them
2
+ // with `import type { Ctx } from "@godwit/sdk"`. The host provides no way to
3
+ // send mail.
4
+
5
+ /** A label: a plain string, or a default plus translations by language tag. */
6
+ export type Text = string | ({ default: string } & { [lang: string]: string })
7
+
8
+ export interface AttachmentMeta {
9
+ name: string
10
+ type: string
11
+ size: number
12
+ }
13
+
14
+ export interface MailMessage {
15
+ id: number
16
+ subject: string
17
+ from: string
18
+ to: string[]
19
+ cc: string[]
20
+ /** RFC 3339 */
21
+ date: string
22
+ text: string
23
+ html: string
24
+ /** text or html was cut to the host's limit */
25
+ truncated: boolean
26
+ attachments: AttachmentMeta[]
27
+ }
28
+
29
+ export interface MailSummary {
30
+ id: number
31
+ subject: string
32
+ from: string
33
+ /** RFC 3339 */
34
+ date: string
35
+ snippet: string
36
+ }
37
+
38
+ export interface DraftInput {
39
+ accountId: number
40
+ to: string[]
41
+ cc?: string[]
42
+ subject: string
43
+ html: string
44
+ }
45
+
46
+ export interface DraftUpdate {
47
+ draftId: number
48
+ /** the revision read; a draft changed since then is not updated */
49
+ revision: number
50
+ html: string
51
+ }
52
+
53
+ /** The new message a message.received handler gets. */
54
+ export interface ReceivedMessage {
55
+ id: number
56
+ accountId: number
57
+ subject: string
58
+ from: string
59
+ /** RFC 3339 */
60
+ date: string
61
+ /** the message was deleted before delivery; id is still given */
62
+ deleted: boolean
63
+ }
64
+
65
+ export interface DeliveryInfo {
66
+ /** the same on every redelivery of this event */
67
+ idempotencyKey: string
68
+ }
69
+
70
+ /** The draft a message.beforeSend handler checks. */
71
+ export interface OutgoingDraft {
72
+ id: number
73
+ accountId: number
74
+ to: string[]
75
+ cc: string[]
76
+ subject: string
77
+ html: string
78
+ }
79
+
80
+ /** warn: the user may still send. block: the user must edit the draft or disable the plugin. */
81
+ export type SendCheck = { warn: string } | { block: string }
82
+
83
+ type MaybePromise<T> = T | Promise<T>
84
+
85
+ export type ActionOn = "message" | "thread" | "selection" | "draft"
86
+
87
+ export interface ActionTarget {
88
+ kind: ActionOn
89
+ id: number
90
+ /** the selected text, for "selection" */
91
+ text?: string
92
+ }
93
+
94
+ export type ActionResult = string | { text?: string; html?: string; draftId?: number } | void
95
+
96
+ export interface Action {
97
+ id: string
98
+ label: Text
99
+ on: ActionOn[]
100
+ run(target: ActionTarget): MaybePromise<ActionResult>
101
+ }
102
+
103
+ export interface CardField {
104
+ label: string
105
+ value: string
106
+ }
107
+
108
+ export interface CardButton {
109
+ label: string
110
+ /** copy: value is copied; open-url: value is an http(s) URL; run-action: value is an action id of this plugin */
111
+ kind: "copy" | "open-url" | "run-action"
112
+ value: string
113
+ }
114
+
115
+ /** Declarative card data; the client renders it. */
116
+ export interface Card {
117
+ title: string
118
+ fields?: CardField[]
119
+ buttons?: CardButton[]
120
+ }
121
+
122
+ export interface CardProvider {
123
+ match(message: MailMessage): MaybePromise<boolean>
124
+ render(message: MailMessage): MaybePromise<Card>
125
+ }
126
+
127
+ export interface Tool {
128
+ /** ^[a-z][a-z0-9_]{0,40}$ */
129
+ name: string
130
+ description: string
131
+ /** JSON Schema of the arguments */
132
+ schema: Record<string, unknown>
133
+ /** default true: every call is approved by the user first */
134
+ write?: boolean
135
+ run(args: Record<string, unknown>): MaybePromise<unknown>
136
+ }
137
+
138
+ export interface FetchInit {
139
+ method?: string
140
+ headers?: Record<string, string>
141
+ body?: string
142
+ }
143
+
144
+ export interface FetchResponse {
145
+ status: number
146
+ headers: Record<string, string>
147
+ text(): Promise<string>
148
+ }
149
+
150
+ export interface Mail {
151
+ get(id: number): Promise<MailMessage>
152
+ /** at most 50 results */
153
+ search(query: string, limit?: number): Promise<MailSummary[]>
154
+ setFlags(ids: number[], add: string[], remove: string[]): Promise<void>
155
+ move(ids: number[], folderId: number): Promise<void>
156
+ /** returns the new draft's id */
157
+ createDraft(draft: DraftInput): Promise<number>
158
+ /** returns the draft's new revision */
159
+ updateDraft(update: DraftUpdate): Promise<number>
160
+ }
161
+
162
+ /**
163
+ * a typed question for llm.decide, in the OpenAI Decisions API's shape whatever judge answers;
164
+ * name matches ^[a-z][a-z0-9_]{0,40}$
165
+ */
166
+ export type Question =
167
+ | { name: string; type: "predicate"; instructions: string }
168
+ /** 2 to 255 unique values */
169
+ | { name: string; type: "choice"; instructions: string; choices: ChoiceOption[] }
170
+ /** 2 to 10 levels, lowest first */
171
+ | { name: string; type: "score"; instructions: string; levels: Level[] }
172
+
173
+ export interface ChoiceOption {
174
+ value: string
175
+ description?: string
176
+ }
177
+
178
+ export interface Level {
179
+ label: string
180
+ description?: string
181
+ }
182
+
183
+ /**
184
+ * an answer in the Decisions API's shape: a predicate gives the probability it holds; a choice
185
+ * its value, a score a 0-based (possibly fractional) level index, each with probabilities and
186
+ * confidence when the judge gives them; a refusal nothing else
187
+ */
188
+ export type Answer =
189
+ | { type: "predicate"; name: string; probability: number }
190
+ | { type: "choice"; name: string; choice: string; probabilities?: { value: string; probability: number }[]; confidence?: number }
191
+ | { type: "score"; name: string; score: number; probabilities?: { value: number; label: string; probability: number }[]; confidence?: number }
192
+ | { type: "refusal"; name: string }
193
+
194
+ /**
195
+ * What a translator gets: the paragraphs of the mail (or selection) the user
196
+ * translates, and the target language (BCP 47). source is "" (detect it).
197
+ * The texts may be long: split them as your service requires.
198
+ */
199
+ export interface TranslateRequest {
200
+ texts: string[]
201
+ source: string
202
+ target: string
203
+ }
204
+
205
+ /** One translation per request text, in order, and the source language detected (BCP 47). */
206
+ export interface TranslateResult {
207
+ texts: string[]
208
+ source: string
209
+ }
210
+
211
+ /**
212
+ * A translation channel the user can pick in Settings › General. The plugin
213
+ * must declare "capabilities": ["translate"] in plugin.json and register in
214
+ * its default function. It may fetch from every host in permissions.net
215
+ * without asking each time; the user chose it and clicked Translate.
216
+ */
217
+ export interface Translator {
218
+ translate(req: TranslateRequest): MaybePromise<TranslateResult>
219
+ }
220
+
221
+ export interface Ctx {
222
+ on(event: "message.received", handler: (message: ReceivedMessage, info: DeliveryInfo) => MaybePromise<void>): void
223
+ on(event: "message.beforeSend", handler: (draft: OutgoingDraft) => MaybePromise<SendCheck | void>): void
224
+
225
+ actions: { register(action: Action): void }
226
+ cards: { register(card: CardProvider): void }
227
+ tools: { register(tool: Tool): void }
228
+ /** needs "capabilities": ["translate"]; at most one */
229
+ translators: { register(translator: Translator): void }
230
+
231
+ /** the user's configuration, secrets included; read-only */
232
+ readonly config: Readonly<Record<string, string | number | boolean | undefined>>
233
+ /** needs mail:read; setFlags, move, createDraft and updateDraft need mail:write */
234
+ mail: Mail
235
+ /**
236
+ * needs llm: true. complete runs on the user's default model service. decide runs on
237
+ * the user's judge service, which may be another vendor's (else the default model).
238
+ */
239
+ llm: {
240
+ complete(prompt: string): Promise<string>
241
+ /** input and all question text at most 64 KB; at most 128 questions; at most 2 calls at once */
242
+ decide(input: string, questions: Question[]): Promise<Answer[]>
243
+ }
244
+ /** https only, to hosts declared in permissions.net */
245
+ net: { fetch(url: string, init?: FetchInit): Promise<FetchResponse> }
246
+ /** this plugin's own key-value store */
247
+ storage: {
248
+ get(key: string): Promise<string | undefined>
249
+ set(key: string, value: string): Promise<void>
250
+ delete(key: string): Promise<void>
251
+ }
252
+ }
package/package.json CHANGED
@@ -1,6 +1,19 @@
1
1
  {
2
2
  "name": "@godwit/sdk",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.6.0",
4
+ "description": "Types for Godwit plugins",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/godwit-email/godwit.git",
9
+ "directory": "sdk"
10
+ },
11
+ "homepage": "https://github.com/godwit-email/godwit/tree/main/sdk",
12
+ "types": "godwit.d.ts",
13
+ "files": [
14
+ "godwit.d.ts"
15
+ ],
16
+ "publishConfig": {
17
+ "access": "public"
18
+ }
19
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.