@sinatra-dev/sdk 0.0.0-stage → 0.1.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.
@@ -0,0 +1,929 @@
1
+ type AuthToken = string | undefined;
2
+ interface Auth {
3
+ /**
4
+ * Which part of the request do we use to send the auth?
5
+ *
6
+ * @default 'header'
7
+ */
8
+ in?: 'header' | 'query' | 'cookie';
9
+ /**
10
+ * A unique identifier for the security scheme.
11
+ *
12
+ * Defined only when there are multiple security schemes whose `Auth`
13
+ * shape would otherwise be identical.
14
+ */
15
+ key?: string;
16
+ /**
17
+ * Header or query parameter name.
18
+ *
19
+ * @default 'Authorization'
20
+ */
21
+ name?: string;
22
+ scheme?: 'basic' | 'bearer';
23
+ type: 'apiKey' | 'http';
24
+ }
25
+
26
+ interface SerializerOptions<T> {
27
+ /**
28
+ * @default true
29
+ */
30
+ explode: boolean;
31
+ style: T;
32
+ }
33
+ type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited';
34
+ type ObjectStyle = 'form' | 'deepObject';
35
+
36
+ type QuerySerializer = (query: Record<string, unknown>) => string;
37
+ type BodySerializer = (body: unknown) => unknown;
38
+ type QuerySerializerOptionsObject = {
39
+ allowReserved?: boolean;
40
+ array?: Partial<SerializerOptions<ArrayStyle>>;
41
+ object?: Partial<SerializerOptions<ObjectStyle>>;
42
+ };
43
+ type QuerySerializerOptions = QuerySerializerOptionsObject & {
44
+ /**
45
+ * Per-parameter serialization overrides. When provided, these settings
46
+ * override the global array/object settings for specific parameter names.
47
+ */
48
+ parameters?: Record<string, QuerySerializerOptionsObject>;
49
+ };
50
+
51
+ type HttpMethod = 'connect' | 'delete' | 'get' | 'head' | 'options' | 'patch' | 'post' | 'put' | 'trace';
52
+ type Client$1<RequestFn = never, Config = unknown, MethodFn = never, BuildUrlFn = never, SseFn = never> = {
53
+ /**
54
+ * Returns the final request URL.
55
+ */
56
+ buildUrl: BuildUrlFn;
57
+ getConfig: () => Config;
58
+ request: RequestFn;
59
+ setConfig: (config: Config) => Config;
60
+ } & {
61
+ [K in HttpMethod]: MethodFn;
62
+ } & ([SseFn] extends [never] ? {
63
+ sse?: never;
64
+ } : {
65
+ sse: {
66
+ [K in HttpMethod]: SseFn;
67
+ };
68
+ });
69
+ interface Config$1 {
70
+ /**
71
+ * Auth token or a function returning auth token. The resolved value will be
72
+ * added to the request payload as defined by its `security` array.
73
+ */
74
+ auth?: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken;
75
+ /**
76
+ * A function for serializing request body parameter. By default,
77
+ * {@link JSON.stringify()} will be used.
78
+ */
79
+ bodySerializer?: BodySerializer | null;
80
+ /**
81
+ * An object containing any HTTP headers that you want to pre-populate your
82
+ * `Headers` object with.
83
+ *
84
+ * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more}
85
+ */
86
+ headers?: RequestInit['headers'] | Record<string, string | number | boolean | (string | number | boolean)[] | null | undefined | unknown>;
87
+ /**
88
+ * The request method.
89
+ *
90
+ * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more}
91
+ */
92
+ method?: Uppercase<HttpMethod>;
93
+ /**
94
+ * A function for serializing request query parameters. By default, arrays
95
+ * will be exploded in form style, objects will be exploded in deepObject
96
+ * style, and reserved characters are percent-encoded.
97
+ *
98
+ * This method will have no effect if the native `paramsSerializer()` Axios
99
+ * API function is used.
100
+ *
101
+ * {@link https://swagger.io/docs/specification/serialization/#query View examples}
102
+ */
103
+ querySerializer?: QuerySerializer | QuerySerializerOptions;
104
+ /**
105
+ * A function validating request data. This is useful if you want to ensure
106
+ * the request conforms to the desired shape, so it can be safely sent to
107
+ * the server.
108
+ */
109
+ requestValidator?: (data: unknown) => Promise<unknown>;
110
+ /**
111
+ * A function transforming response data before it's returned. This is useful
112
+ * for post-processing data, e.g., converting ISO strings into Date objects.
113
+ */
114
+ responseTransformer?: (data: unknown) => Promise<unknown>;
115
+ /**
116
+ * A function validating response data. This is useful if you want to ensure
117
+ * the response conforms to the desired shape, so it can be safely passed to
118
+ * the transformers and returned to the user.
119
+ */
120
+ responseValidator?: (data: unknown) => Promise<unknown>;
121
+ }
122
+
123
+ type ServerSentEventsOptions<TData = unknown> = Omit<RequestInit, 'method'> & Pick<Config$1, 'method' | 'responseTransformer' | 'responseValidator'> & {
124
+ /**
125
+ * Fetch API implementation. You can use this option to provide a custom
126
+ * fetch instance.
127
+ *
128
+ * @default globalThis.fetch
129
+ */
130
+ fetch?: typeof fetch;
131
+ /**
132
+ * Implementing clients can call request interceptors inside this hook.
133
+ */
134
+ onRequest?: (url: string, init: RequestInit) => Promise<Request>;
135
+ /**
136
+ * Callback invoked when a network or parsing error occurs during streaming.
137
+ *
138
+ * This option applies only if the endpoint returns a stream of events.
139
+ *
140
+ * @param error The error that occurred.
141
+ */
142
+ onSseError?: (error: unknown) => void;
143
+ /**
144
+ * Callback invoked when an event is streamed from the server.
145
+ *
146
+ * This option applies only if the endpoint returns a stream of events.
147
+ *
148
+ * @param event Event streamed from the server.
149
+ * @returns Nothing (void).
150
+ */
151
+ onSseEvent?: (event: StreamEvent<TData>) => void;
152
+ serializedBody?: RequestInit['body'];
153
+ /**
154
+ * Default retry delay in milliseconds.
155
+ *
156
+ * This option applies only if the endpoint returns a stream of events.
157
+ *
158
+ * @default 3000
159
+ */
160
+ sseDefaultRetryDelay?: number;
161
+ /**
162
+ * Maximum number of retry attempts before giving up.
163
+ */
164
+ sseMaxRetryAttempts?: number;
165
+ /**
166
+ * Maximum retry delay in milliseconds.
167
+ *
168
+ * Applies only when exponential backoff is used.
169
+ *
170
+ * This option applies only if the endpoint returns a stream of events.
171
+ *
172
+ * @default 30000
173
+ */
174
+ sseMaxRetryDelay?: number;
175
+ /**
176
+ * Optional sleep function for retry backoff.
177
+ *
178
+ * Defaults to using `setTimeout`.
179
+ */
180
+ sseSleepFn?: (ms: number) => Promise<void>;
181
+ url: string;
182
+ };
183
+ interface StreamEvent<TData = unknown> {
184
+ data: TData;
185
+ event?: string;
186
+ id?: string;
187
+ retry?: number;
188
+ }
189
+ type ServerSentEventsResult<TData = unknown, TReturn = void, TNext = unknown> = {
190
+ stream: AsyncGenerator<TData extends Record<string, unknown> ? TData[keyof TData] : TData, TReturn, TNext>;
191
+ };
192
+
193
+ type ErrInterceptor<Err, Res, Req, Options> = (error: Err,
194
+ /** response may be undefined due to a network error where no response object is produced */
195
+ response: Res | undefined,
196
+ /** request may be undefined, because error may be from building the request object itself */
197
+ request: Req | undefined, options: Options) => Err | Promise<Err>;
198
+ type ReqInterceptor<Req, Options> = (request: Req, options: Options) => Req | Promise<Req>;
199
+ type ResInterceptor<Res, Req, Options> = (response: Res, request: Req, options: Options) => Res | Promise<Res>;
200
+ declare class Interceptors<Interceptor> {
201
+ fns: Array<Interceptor | null>;
202
+ clear(): void;
203
+ eject(id: number | Interceptor): void;
204
+ exists(id: number | Interceptor): boolean;
205
+ getInterceptorIndex(id: number | Interceptor): number;
206
+ update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false;
207
+ use(fn: Interceptor): number;
208
+ }
209
+ interface Middleware<Req, Res, Err, Options> {
210
+ error: Interceptors<ErrInterceptor<Err, Res, Req, Options>>;
211
+ request: Interceptors<ReqInterceptor<Req, Options>>;
212
+ response: Interceptors<ResInterceptor<Res, Req, Options>>;
213
+ }
214
+
215
+ type ResponseStyle = 'data' | 'fields';
216
+ interface Config<T extends ClientOptions = ClientOptions> extends Omit<RequestInit, 'body' | 'headers' | 'method'>, Config$1 {
217
+ /**
218
+ * Base URL for all requests made by this client.
219
+ */
220
+ baseUrl?: T['baseUrl'];
221
+ /**
222
+ * Fetch API implementation. You can use this option to provide a custom
223
+ * fetch instance.
224
+ *
225
+ * @default globalThis.fetch
226
+ */
227
+ fetch?: typeof fetch;
228
+ /**
229
+ * Please don't use the Fetch client for Next.js applications. The `next`
230
+ * options won't have any effect.
231
+ *
232
+ * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead.
233
+ */
234
+ next?: never;
235
+ /**
236
+ * Return the response data parsed in a specified format. By default, `auto`
237
+ * will infer the appropriate method from the `Content-Type` response header.
238
+ * You can override this behavior with any of the {@link Body} methods.
239
+ * Select `stream` if you don't want to parse response data at all.
240
+ *
241
+ * @default 'auto'
242
+ */
243
+ parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text';
244
+ /**
245
+ * Should we return only data or multiple fields (data, error, response, etc.)?
246
+ *
247
+ * @default 'fields'
248
+ */
249
+ responseStyle?: ResponseStyle;
250
+ /**
251
+ * Throw an error instead of returning it in the response?
252
+ *
253
+ * @default false
254
+ */
255
+ throwOnError?: T['throwOnError'];
256
+ }
257
+ interface RequestOptions<TData = unknown, TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string> extends Config<{
258
+ responseStyle: TResponseStyle;
259
+ throwOnError: ThrowOnError;
260
+ }>, Pick<ServerSentEventsOptions<TData>, 'onRequest' | 'onSseError' | 'onSseEvent' | 'sseDefaultRetryDelay' | 'sseMaxRetryAttempts' | 'sseMaxRetryDelay'> {
261
+ /**
262
+ * Any body that you want to add to your request.
263
+ *
264
+ * {@link https://developer.mozilla.org/docs/Web/API/fetch#body}
265
+ */
266
+ body?: unknown;
267
+ path?: Record<string, unknown>;
268
+ query?: Record<string, unknown>;
269
+ /**
270
+ * Security mechanism(s) to use for the request.
271
+ */
272
+ security?: ReadonlyArray<Auth>;
273
+ url: Url;
274
+ }
275
+ interface ResolvedRequestOptions<TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string> extends RequestOptions<unknown, TResponseStyle, ThrowOnError, Url> {
276
+ headers: Headers;
277
+ serializedBody?: string;
278
+ }
279
+ type RequestResult<TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = 'fields'> = ThrowOnError extends true ? Promise<TResponseStyle extends 'data' ? TData extends Record<string, unknown> ? TData[keyof TData] : TData : {
280
+ data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
281
+ request: Request;
282
+ response: Response;
283
+ }> : Promise<TResponseStyle extends 'data' ? (TData extends Record<string, unknown> ? TData[keyof TData] : TData) | undefined : ({
284
+ data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
285
+ error: undefined;
286
+ } | {
287
+ data: undefined;
288
+ error: TError extends Record<string, unknown> ? TError[keyof TError] : TError;
289
+ }) & {
290
+ /** request may be undefined, because error may be from building the request object itself */
291
+ request?: Request;
292
+ /** response may be undefined, because error may be from building the request object itself or from a network error */
293
+ response?: Response;
294
+ }>;
295
+ interface ClientOptions {
296
+ baseUrl?: string;
297
+ responseStyle?: ResponseStyle;
298
+ throwOnError?: boolean;
299
+ }
300
+ type MethodFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
301
+ type SseFn = <TData = unknown, _TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<never, TResponseStyle, ThrowOnError>, 'method'>) => Promise<ServerSentEventsResult<TData>>;
302
+ type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'> & Pick<Required<RequestOptions<TData, TResponseStyle, ThrowOnError>>, 'method'>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
303
+ type BuildUrlFn = <TData extends {
304
+ body?: unknown;
305
+ path?: Record<string, unknown>;
306
+ query?: Record<string, unknown>;
307
+ url: string;
308
+ }>(options: TData & Options<TData>) => string;
309
+ type Client = Client$1<RequestFn, Config, MethodFn, BuildUrlFn, SseFn> & {
310
+ interceptors: Middleware<Request, Response, unknown, ResolvedRequestOptions>;
311
+ };
312
+ interface TDataShape {
313
+ body?: unknown;
314
+ headers?: unknown;
315
+ path?: unknown;
316
+ query?: unknown;
317
+ url: string;
318
+ }
319
+ type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>;
320
+ type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown, TResponseStyle extends ResponseStyle = 'fields'> = OmitKeys<RequestOptions<TResponse, TResponseStyle, ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & ([TData] extends [never] ? unknown : Omit<TData, 'url'>);
321
+
322
+ /**
323
+ * A message to send on a task.
324
+ */
325
+ type CreateMessageRequest = {
326
+ /**
327
+ * The message, up to 100,000 characters after trimming.
328
+ */
329
+ text: string;
330
+ };
331
+ /**
332
+ * The message that was sent.
333
+ */
334
+ type CreateMessageResponse = {
335
+ /**
336
+ * The message's id: the `Idempotency-Key` you sent, or a generated id.
337
+ */
338
+ messageId: string;
339
+ };
340
+ /**
341
+ * A task to start.
342
+ */
343
+ type CreateTaskRequest = {
344
+ /**
345
+ * What to do, as you'd ask a teammate. Up to 100,000 characters, after trimming.
346
+ */
347
+ prompt: string;
348
+ /**
349
+ * The task's title, up to 200 characters. Defaults to the prompt's first line, cut to 80 characters.
350
+ */
351
+ title?: string | null;
352
+ /**
353
+ * `owner/name` of a repository connected to the workspace. Omit it to let the agent choose.
354
+ */
355
+ repo?: string | null;
356
+ };
357
+ /**
358
+ * The task that started, and the id of your first message.
359
+ */
360
+ type CreateTaskResponse = {
361
+ task: Task;
362
+ /**
363
+ * The id of your first message: the `Idempotency-Key` you sent, or a generated id.
364
+ */
365
+ messageId: string;
366
+ };
367
+ /**
368
+ * A GitHub issue to delegate, by its repository and number.
369
+ */
370
+ type DelegateGithubTicket = {
371
+ /**
372
+ * `github` to delegate a GitHub issue.
373
+ */
374
+ source: 'github';
375
+ /**
376
+ * `owner/name` of a repository enabled in the workspace.
377
+ */
378
+ repo: string;
379
+ /**
380
+ * The issue's number in that repository.
381
+ */
382
+ number: number;
383
+ };
384
+ /**
385
+ * A Linear issue to delegate, by its identifier or id.
386
+ */
387
+ type DelegateLinearTicket = {
388
+ /**
389
+ * `linear` to delegate a Linear issue.
390
+ */
391
+ source: 'linear';
392
+ /**
393
+ * The issue's identifier, such as `ENG-123`, or its id.
394
+ */
395
+ id: string;
396
+ };
397
+ /**
398
+ * An issue to delegate: a Linear issue by `id`, or a GitHub issue by `repo` and `number`.
399
+ */
400
+ type DelegateTicketRequest = ({
401
+ source: 'linear';
402
+ } & DelegateLinearTicket) | ({
403
+ source: 'github';
404
+ } & DelegateGithubTicket);
405
+ /**
406
+ * The issue was delegated.
407
+ */
408
+ type DelegateTicketResponse = {
409
+ /**
410
+ * Always `true`: the issue was handed to Sinatra.
411
+ */
412
+ ok: true;
413
+ };
414
+ /**
415
+ * The body of every error response.
416
+ */
417
+ type Error$1 = {
418
+ /**
419
+ * A machine-readable code, such as `invalid_prompt`. Branch on this, not on `reason`. New codes can appear. Known codes: `assigned_to_other`, `bad_request`, `capacity_full`, `github_identity_required`, `github_not_connected`, `github_rate_limited`, `idempotency_conflict`, `internal_error`, `invalid_body`, `invalid_cursor`, `invalid_idempotency_key`, `invalid_limit`, `invalid_prompt`, `invalid_repo`, `invalid_status`, `invalid_title`, `invalid_token`, `issue_closed`, `issue_not_found`, `linear_app_user_missing`, `linear_identity_unlinked`, `linear_not_connected`, `linear_reconnect_required`, `not_an_api_task`, `not_an_issue`, `not_found`, `not_running`, `payment_required`, `repo_disabled`, `unavailable`.
420
+ */
421
+ error: string;
422
+ /**
423
+ * A sentence saying what went wrong and, where it helps, what to do. Written to show to a person.
424
+ */
425
+ reason?: string;
426
+ /**
427
+ * The request's id. Present on some errors, not all; the `x-request-id` response header always carries it. Share it with support.
428
+ */
429
+ requestId?: string;
430
+ /**
431
+ * Why a start was refused, on `payment_required` and `github_not_connected`. For `payment_required`: `own_credentials_required` or `subscription_inactive`. For `github_not_connected`: `missing` or `suspended`.
432
+ */
433
+ refusal?: string;
434
+ /**
435
+ * The settings section that fixes the refusal: your model credentials or billing, on `payment_required`; billing, when starting a task, on `capacity_full`.
436
+ */
437
+ billingUrl?: string;
438
+ /**
439
+ * The settings page that fixes the refusal, on `github_not_connected`.
440
+ */
441
+ settingsUrl?: string;
442
+ /**
443
+ * The workspace's plan, on `capacity_full` when starting a task.
444
+ */
445
+ plan?: string;
446
+ /**
447
+ * How many tasks the plan runs at a time, on `capacity_full` when starting a task.
448
+ */
449
+ running?: number;
450
+ /**
451
+ * How many tasks the plan queues, on `capacity_full` when starting a task.
452
+ */
453
+ queued?: number;
454
+ /**
455
+ * On `unavailable` after a start: the task that was made. Retry with the same key, or send a message on it.
456
+ */
457
+ taskId?: string;
458
+ /**
459
+ * On `unavailable`: the message that was saved but not sent yet. Retry with it as the `Idempotency-Key`.
460
+ */
461
+ messageId?: string;
462
+ };
463
+ /**
464
+ * The token's user and workspaces.
465
+ */
466
+ type Me = {
467
+ /**
468
+ * The user the token acts as.
469
+ */
470
+ user: {
471
+ /**
472
+ * The user's id.
473
+ */
474
+ id: string;
475
+ /**
476
+ * The user's GitHub login. `null` for a user without GitHub.
477
+ */
478
+ githubLogin: string | null;
479
+ /**
480
+ * The user's name, if they have one.
481
+ */
482
+ name: string | null;
483
+ /**
484
+ * The user's email address: the one they sign in with by email, or their primary GitHub email.
485
+ */
486
+ email: string;
487
+ };
488
+ /**
489
+ * The workspaces the user belongs to, ordered by name.
490
+ */
491
+ workspaces: Array<Workspace>;
492
+ };
493
+ /**
494
+ * An entry in a task's conversation.
495
+ */
496
+ type Message = {
497
+ /**
498
+ * The entry's id. Pass the last one you read as `after` to get only later entries.
499
+ */
500
+ id: string;
501
+ /**
502
+ * For a message a person sent: the id it was sent with, which is its idempotency key or a generated id. `null` on every other entry.
503
+ */
504
+ messageId: string | null;
505
+ /**
506
+ * Who wrote it: `user` for a person, `agent` for the agent, `platform` for Sinatra itself. New roles can appear.
507
+ */
508
+ role: string;
509
+ /**
510
+ * What it is: `message` (a person's message), `response` (the agent's answer for a turn, or a notice from Sinatra such as a stop or files the agent produced), `clarify` (a question the agent needs answered to continue) or `error` (a refusal or failure from Sinatra). New kinds can appear.
511
+ */
512
+ kind: string;
513
+ /**
514
+ * The text.
515
+ */
516
+ body: string;
517
+ /**
518
+ * When it was written.
519
+ */
520
+ createdAt: string;
521
+ };
522
+ /**
523
+ * A page of a task's conversation.
524
+ */
525
+ type MessageList = {
526
+ /**
527
+ * The page's entries, oldest first.
528
+ */
529
+ messages: Array<Message>;
530
+ /**
531
+ * When it isn't `null`, more entries follow: pass it as `after` to get them. `null` on the last page.
532
+ */
533
+ next: string | null;
534
+ };
535
+ /**
536
+ * The pull request a task opened.
537
+ */
538
+ type PullRequest = {
539
+ /**
540
+ * The pull request's address on GitHub.
541
+ */
542
+ url: string;
543
+ /**
544
+ * `true` once the pull request is merged.
545
+ */
546
+ merged: boolean;
547
+ };
548
+ /**
549
+ * The stop was accepted.
550
+ */
551
+ type StopTaskResponse = {
552
+ /**
553
+ * Always `true`: the task was told to stop.
554
+ */
555
+ accepted: true;
556
+ };
557
+ /**
558
+ * A task: one piece of work Sinatra does, from any source.
559
+ */
560
+ type Task = {
561
+ /**
562
+ * The task's id. Use it as `taskId` in the task endpoints.
563
+ */
564
+ id: string;
565
+ /**
566
+ * Where the task is in its life, such as `pending`, `implementing`, `replied`, `pr_open` or `completed`. New statuses can appear, so don't treat the list as closed. See [Raw statuses](https://docs.sinatra.dev/docs/getting-started/how-it-works#raw-statuses) for each one.
567
+ */
568
+ status: string;
569
+ /**
570
+ * Where the task started: `api` for the CLI, MCP, this API or the dashboard, `linear` or `github_issue` for an issue, `slack` or `telegram` for a chat. Other sources can appear, so treat an unknown value as a task started elsewhere.
571
+ */
572
+ source: string;
573
+ /**
574
+ * The task's title. `null` for a task whose issue has no title.
575
+ */
576
+ title: string | null;
577
+ /**
578
+ * `owner/name` of the task's repository. `null` until a repository is chosen.
579
+ */
580
+ repo: string | null;
581
+ /**
582
+ * The task's pull request. `null` until one opens.
583
+ */
584
+ pullRequest: PullRequest | null;
585
+ /**
586
+ * `true` while a turn waits because the workspace is already running as many tasks at a time as its plan allows. The dashboard shows this as Queued.
587
+ */
588
+ queued: boolean;
589
+ /**
590
+ * When the task was created.
591
+ */
592
+ createdAt: string;
593
+ /**
594
+ * When the task last did something. `null` if it hasn't yet.
595
+ */
596
+ lastActivityAt: string | null;
597
+ /**
598
+ * The task's page in the Sinatra dashboard, where anyone in the workspace can follow it. On a task started from the CLI, MCP, API or dashboard they can reply there too.
599
+ */
600
+ url: string | null;
601
+ };
602
+ /**
603
+ * A page of tasks.
604
+ */
605
+ type TaskList = {
606
+ /**
607
+ * The page's tasks, most recently active first.
608
+ */
609
+ tasks: Array<Task>;
610
+ /**
611
+ * Pass it back as `cursor` to get the next page. Treat it as opaque. `null` on the last page.
612
+ */
613
+ nextCursor: string | null;
614
+ };
615
+ /**
616
+ * An open issue you could delegate to Sinatra.
617
+ */
618
+ type Ticket = {
619
+ /**
620
+ * The issue's id on Sinatra's side. For GitHub it looks like `github:owner/name#42`.
621
+ */
622
+ id: string;
623
+ /**
624
+ * Where the issue lives: `linear` or `github`. New sources can appear.
625
+ */
626
+ source: string;
627
+ /**
628
+ * What to delegate it by. A Linear identifier such as `ENG-123` (send it as `id`), or a GitHub `owner/name#42` (send `owner/name` as `repo` and `42` as `number`).
629
+ */
630
+ identifier: string;
631
+ /**
632
+ * The issue's title.
633
+ */
634
+ title: string;
635
+ /**
636
+ * `true` if the issue is assigned to you or you wrote it.
637
+ */
638
+ yours: boolean;
639
+ /**
640
+ * A GitHub issue's state, such as `open`. `null` for a Linear issue.
641
+ */
642
+ state: string | null;
643
+ /**
644
+ * The Linear team's name, or the GitHub repository's name.
645
+ */
646
+ context: string | null;
647
+ /**
648
+ * The issue's address on its tracker.
649
+ */
650
+ url: string;
651
+ /**
652
+ * The id of the workspace that was searched.
653
+ */
654
+ workspaceId: string;
655
+ /**
656
+ * The name the dashboard's ticket picker gives that workspace.
657
+ */
658
+ workspaceLabel: string;
659
+ };
660
+ /**
661
+ * The issues you could delegate, and how the workspace is connected to each tracker.
662
+ */
663
+ type TicketSearchResult = {
664
+ /**
665
+ * The issues you could delegate. Linear issues come first, then GitHub's, each with yours before your team's unassigned ones.
666
+ */
667
+ tickets: Array<Ticket>;
668
+ /**
669
+ * The workspace's Linear connection, as it applies to you.
670
+ */
671
+ linear: {
672
+ /**
673
+ * Whether the workspace is connected to Linear.
674
+ */
675
+ connected: boolean;
676
+ /**
677
+ * Whether your Linear account is linked in this workspace. Linear issues are listed only when it is.
678
+ */
679
+ identityLinked: boolean;
680
+ /**
681
+ * Whether your Linear identity is tied to your Sinatra user.
682
+ */
683
+ identityBound: boolean;
684
+ };
685
+ /**
686
+ * The workspace's GitHub connection.
687
+ */
688
+ github: {
689
+ /**
690
+ * Whether the workspace is connected to GitHub.
691
+ */
692
+ connected: boolean;
693
+ /**
694
+ * The repository the GitHub search covered, when the `repo` query matched an enabled one and had open issues. Otherwise `null`.
695
+ */
696
+ repo: string | null;
697
+ };
698
+ };
699
+ /**
700
+ * A workspace you belong to.
701
+ */
702
+ type Workspace = {
703
+ /**
704
+ * The workspace's id. Use it as `workspaceId` in the workspace endpoints.
705
+ */
706
+ id: string;
707
+ /**
708
+ * The workspace's name.
709
+ */
710
+ name: string;
711
+ /**
712
+ * Your role in it: `owner`, `admin` or `member`. New roles can appear.
713
+ */
714
+ role: string;
715
+ };
716
+ type TasksListData = {
717
+ body?: never;
718
+ path: {
719
+ /**
720
+ * The workspace's id, from `GET /v1/me`.
721
+ */
722
+ workspaceId: string;
723
+ };
724
+ query?: {
725
+ /**
726
+ * Only tasks in this status, such as `implementing` or `pr_open`. A name that isn't a task status is `invalid_status`.
727
+ */
728
+ status?: string;
729
+ /**
730
+ * How many tasks to return, 1 to 100.
731
+ */
732
+ limit?: number;
733
+ /**
734
+ * `nextCursor` from the previous page. Treat it as opaque.
735
+ */
736
+ cursor?: string;
737
+ };
738
+ url: '/v1/workspaces/{workspaceId}/tasks';
739
+ };
740
+ type MessagesListData = {
741
+ body?: never;
742
+ path: {
743
+ /**
744
+ * The workspace's id, from `GET /v1/me`.
745
+ */
746
+ workspaceId: string;
747
+ /**
748
+ * The task's id.
749
+ */
750
+ taskId: string;
751
+ };
752
+ query?: {
753
+ /**
754
+ * The `id` of the last entry you've read. Returns only later entries. An id that isn't an entry of this task is `invalid_cursor`.
755
+ */
756
+ after?: string;
757
+ /**
758
+ * How many entries to return, 1 to 200.
759
+ */
760
+ limit?: number;
761
+ };
762
+ url: '/v1/workspaces/{workspaceId}/tasks/{taskId}/messages';
763
+ };
764
+ type TicketsSearchData = {
765
+ body?: never;
766
+ path: {
767
+ /**
768
+ * The workspace's id, from `GET /v1/me`.
769
+ */
770
+ workspaceId: string;
771
+ };
772
+ query?: {
773
+ /**
774
+ * Text to match: GitHub search terms, and a substring of a Linear issue's title. Up to 200 characters.
775
+ */
776
+ q?: string;
777
+ /**
778
+ * `owner/name` of an enabled repository to search first on GitHub. A repository that isn't enabled is ignored.
779
+ */
780
+ repo?: string;
781
+ };
782
+ url: '/v1/workspaces/{workspaceId}/tickets';
783
+ };
784
+
785
+ interface CallOptions {
786
+ /** Cancels the call, including a retry it is waiting to make. */
787
+ signal?: AbortSignal;
788
+ /** Milliseconds each attempt may take before it is aborted with a `TimeoutError`. `0` for none; at most 2^31-1 (about 24.8 days). */
789
+ timeout?: number;
790
+ }
791
+
792
+ /**
793
+ * The one error the client throws for an HTTP error response.
794
+ *
795
+ * `code` is the API's machine-readable `error` code, such as `capacity_full`.
796
+ * New codes can appear at any time, so treat it as an open string. Branch on
797
+ * `code`, not on `reason` or `message`.
798
+ *
799
+ * Network failures (DNS, refused connections) are not wrapped: they reject
800
+ * with the error `fetch` threw.
801
+ */
802
+ declare class SinatraError extends Error {
803
+ readonly name = "SinatraError";
804
+ /** The HTTP status, such as `409`. */
805
+ readonly status: number;
806
+ /**
807
+ * The API's `error` code, such as `not_running`. `http_error` when the
808
+ * response had no code, for example an HTML page from a proxy.
809
+ */
810
+ readonly code: string;
811
+ /** A sentence saying what went wrong, written to show to a person. */
812
+ readonly reason: string | undefined;
813
+ /** The request's id, from the body or the `x-request-id` header. Share it with support. */
814
+ readonly requestId: string | undefined;
815
+ /** The response body: the parsed JSON object, or the text when it wasn't JSON. */
816
+ readonly body: unknown;
817
+ /** The response headers. */
818
+ readonly headers: Headers;
819
+ constructor(status: number, body: unknown, headers: Headers);
820
+ }
821
+
822
+ declare const DEFAULT_BASE_URL = "https://api.sinatra.dev";
823
+ /** How long one attempt may take, by default. */
824
+ declare const DEFAULT_TIMEOUT_MS = 60000;
825
+
826
+ interface SinatraOptions {
827
+ /** An API token (`sntr_...`). Defaults to the `SINATRA_TOKEN` environment variable. */
828
+ token?: string;
829
+ /** Defaults to `https://api.sinatra.dev`. */
830
+ baseUrl?: string;
831
+ /** A `fetch` to use instead of the global one. */
832
+ fetch?: typeof fetch;
833
+ /**
834
+ * Milliseconds each attempt may take before it is aborted with a
835
+ * `TimeoutError`. Defaults to 60 seconds; `0` for none. A call can
836
+ * override it, and pass a `signal`, in its last argument.
837
+ */
838
+ timeout?: number;
839
+ }
840
+ interface IdempotencyOptions extends CallOptions {
841
+ /**
842
+ * 1 to 128 printable ASCII characters, with no spaces. When you leave it
843
+ * out, the client makes a random UUID. Either way, every retry of the call
844
+ * sends the same key, so a retried start never starts a second task.
845
+ */
846
+ idempotencyKey?: string;
847
+ }
848
+ type ListTasksQuery = NonNullable<TasksListData["query"]>;
849
+ type ListMessagesQuery = NonNullable<MessagesListData["query"]>;
850
+ type SearchTicketsQuery = NonNullable<TicketsSearchData["query"]>;
851
+ /**
852
+ * A client for the Sinatra API. Its namespaces mirror the API's operations:
853
+ * `me.get` is `GET /v1/me`, `tasks.create` is `POST /v1/workspaces/{workspaceId}/tasks`.
854
+ *
855
+ * Requests that are safe to repeat (GETs, the token DELETE, and starts and
856
+ * messages, which always carry an `Idempotency-Key`) are retried up to 3 times
857
+ * on `429` and `503`. `tasks.stop` is retried on `503` only. Errors throw
858
+ * {@link SinatraError}.
859
+ *
860
+ * Reference: https://docs.sinatra.dev/docs/api-reference
861
+ */
862
+ declare class Sinatra {
863
+ readonly me: MeApi;
864
+ readonly tasks: TasksApi;
865
+ readonly messages: MessagesApi;
866
+ readonly tickets: TicketsApi;
867
+ constructor(options?: SinatraOptions);
868
+ }
869
+ /** What every namespace shares: the generated client and the default timeout. */
870
+ interface Context {
871
+ client: Client;
872
+ timeout: number;
873
+ }
874
+ declare class MeApi {
875
+ private readonly ctx;
876
+ /** @internal */
877
+ constructor(ctx: Context);
878
+ /** `me.get`: the user the token acts as, and their workspaces. */
879
+ get(options?: CallOptions): Promise<Me>;
880
+ /** `me.revokeToken`: revokes the token this client sends. Later requests get `401`. */
881
+ revokeToken(options?: CallOptions): Promise<void>;
882
+ }
883
+ declare class TasksApi {
884
+ private readonly ctx;
885
+ /** @internal */
886
+ constructor(ctx: Context);
887
+ /** `tasks.list`: one page of the workspace's tasks, most recently active first. */
888
+ list(workspaceId: string, query?: ListTasksQuery, options?: CallOptions): Promise<TaskList>;
889
+ /** Every task from `query.cursor` on (or from the start), following `nextCursor` page by page. */
890
+ listAll(workspaceId: string, query?: ListTasksQuery, options?: CallOptions): AsyncGenerator<Task, void, undefined>;
891
+ /** `tasks.get`: one task, wherever it started. */
892
+ get(workspaceId: string, taskId: string, options?: CallOptions): Promise<Task>;
893
+ /**
894
+ * `tasks.create`: starts a task. Answers once the task is made, not when it's done:
895
+ * poll `tasks.get` and `messages.list` to follow it.
896
+ */
897
+ create(workspaceId: string, body: CreateTaskRequest, options?: IdempotencyOptions): Promise<CreateTaskResponse>;
898
+ /** `tasks.stop`: stops the task's running turn. A task that isn't running is `409 not_running`. */
899
+ stop(workspaceId: string, taskId: string, options?: CallOptions): Promise<StopTaskResponse>;
900
+ }
901
+ declare class MessagesApi {
902
+ private readonly ctx;
903
+ /** @internal */
904
+ constructor(ctx: Context);
905
+ /** `messages.create`: sends a follow-up on a task started from the API, CLI, MCP or dashboard. */
906
+ create(workspaceId: string, taskId: string, body: CreateMessageRequest, options?: IdempotencyOptions): Promise<CreateMessageResponse>;
907
+ /**
908
+ * `messages.list`: one page of the task's conversation, oldest first. To wait
909
+ * for a reply, poll with `after` set to the `id` of the last entry you read.
910
+ */
911
+ list(workspaceId: string, taskId: string, query?: ListMessagesQuery, options?: CallOptions): Promise<MessageList>;
912
+ /** Every entry after `query.after` (or from the start), following `next` page by page. */
913
+ listAll(workspaceId: string, taskId: string, query?: ListMessagesQuery, options?: CallOptions): AsyncGenerator<Message, void, undefined>;
914
+ }
915
+ declare class TicketsApi {
916
+ private readonly ctx;
917
+ /** @internal */
918
+ constructor(ctx: Context);
919
+ /** `tickets.search`: open Linear and GitHub issues you could delegate. */
920
+ search(workspaceId: string, query?: SearchTicketsQuery, options?: CallOptions): Promise<TicketSearchResult>;
921
+ /**
922
+ * `tickets.delegate`: hands Sinatra an existing issue as you. Not retried:
923
+ * the operation takes no `Idempotency-Key`.
924
+ */
925
+ delegate(workspaceId: string, body: DelegateTicketRequest, options?: CallOptions): Promise<DelegateTicketResponse>;
926
+ }
927
+
928
+ export { DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, MeApi, MessagesApi, Sinatra, SinatraError, TasksApi, TicketsApi };
929
+ export type { CallOptions, CreateMessageRequest, CreateMessageResponse, CreateTaskRequest, CreateTaskResponse, DelegateGithubTicket, DelegateLinearTicket, DelegateTicketRequest, DelegateTicketResponse, Error$1 as ErrorBody, IdempotencyOptions, ListMessagesQuery, ListTasksQuery, Me, Message, MessageList, PullRequest, SearchTicketsQuery, SinatraOptions, StopTaskResponse, Task, TaskList, Ticket, TicketSearchResult, Workspace };