@on-mission/sdk 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.
Files changed (46) hide show
  1. package/dist/api.d.ts +20 -0
  2. package/dist/api.d.ts.map +1 -0
  3. package/dist/api.js +39 -0
  4. package/dist/api.js.map +1 -0
  5. package/dist/auth.d.ts +65 -0
  6. package/dist/auth.d.ts.map +1 -0
  7. package/dist/auth.js +45 -0
  8. package/dist/auth.js.map +1 -0
  9. package/dist/config.d.ts +39 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +28 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/context.d.ts +24 -0
  14. package/dist/context.d.ts.map +1 -0
  15. package/dist/context.js +22 -0
  16. package/dist/context.js.map +1 -0
  17. package/dist/events.d.ts +62 -0
  18. package/dist/events.d.ts.map +1 -0
  19. package/dist/events.js +30 -0
  20. package/dist/events.js.map +1 -0
  21. package/dist/http-server.d.ts +51 -0
  22. package/dist/http-server.d.ts.map +1 -0
  23. package/dist/http-server.js +163 -0
  24. package/dist/http-server.js.map +1 -0
  25. package/dist/index.d.ts +21 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +12 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/ingress.d.ts +133 -0
  30. package/dist/ingress.d.ts.map +1 -0
  31. package/dist/ingress.js +89 -0
  32. package/dist/ingress.js.map +1 -0
  33. package/dist/logging.d.ts +31 -0
  34. package/dist/logging.d.ts.map +1 -0
  35. package/dist/logging.js +77 -0
  36. package/dist/logging.js.map +1 -0
  37. package/dist/sdk.d.ts +116 -0
  38. package/dist/sdk.d.ts.map +1 -0
  39. package/dist/sdk.js +327 -0
  40. package/dist/sdk.js.map +1 -0
  41. package/dist/tool-registry.d.ts +29 -0
  42. package/dist/tool-registry.d.ts.map +1 -0
  43. package/dist/tool-registry.js +37 -0
  44. package/dist/tool-registry.js.map +1 -0
  45. package/dist/tsconfig.tsbuildinfo +1 -0
  46. package/package.json +56 -0
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Mission SDK
3
+ *
4
+ * The SDK that plugin runtimes use to interact with the Mission platform.
5
+ * Communication is HTTP-native: outbound REST calls to the Mission API,
6
+ * inbound HTTP requests via Daytona Preview URLs.
7
+ *
8
+ * See docs/technical-designs/plugin-architecture.md.
9
+ * See docs/technical-designs/daytona-sandbox-runtime.md.
10
+ */
11
+ export type { Tool, ToolFunction, ToolFunctionPermission, ToolKind } from '@mission/models';
12
+ export type { ApiClient } from './api';
13
+ export type { AuthCredentials, AuthModule, OAuthCredentials } from './auth';
14
+ export type { ConfigModule } from './config';
15
+ export type { PluginContext } from './context';
16
+ export type { AgentMessage, EventsModule } from './events';
17
+ export type { IngressHandler, IngressModule, IngressRequest, IngressResponse, IngressStreamEvents, IngressUrl } from './ingress';
18
+ export type { MissionSDK, MissionSDKOptions } from './sdk';
19
+ export { createMissionSDK } from './sdk';
20
+ export type { ToolHandler, ToolsModule } from './tool-registry';
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,YAAY,EACV,IAAI,EACJ,YAAY,EACZ,sBAAsB,EACtB,QAAQ,EACT,MAAM,iBAAiB,CAAA;AACxB,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA;AAC3E,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAC9C,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC1D,YAAY,EACV,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,UAAU,EACX,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAA;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAA;AACxC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Mission SDK
3
+ *
4
+ * The SDK that plugin runtimes use to interact with the Mission platform.
5
+ * Communication is HTTP-native: outbound REST calls to the Mission API,
6
+ * inbound HTTP requests via Daytona Preview URLs.
7
+ *
8
+ * See docs/technical-designs/plugin-architecture.md.
9
+ * See docs/technical-designs/daytona-sandbox-runtime.md.
10
+ */
11
+ export { createMissionSDK } from './sdk';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAsBH,OAAO,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAA"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Ingress Module
3
+ *
4
+ * Handles inbound traffic from external services (webhooks, WebSocket streams).
5
+ * Plugins register handlers per endpoint name; the HTTP server routes traffic
6
+ * to them.
7
+ *
8
+ * Traffic flow (HTTP-native, no WebSocket control plane):
9
+ *
10
+ * Tool calls from Mission API:
11
+ * Mission API → Daytona Standard Preview URL → HTTP server → tool handler
12
+ *
13
+ * Webhooks from external services:
14
+ * External service → Daytona Signed Preview URL → HTTP server → ingress handler
15
+ *
16
+ * WebSocket streams (e.g., Twilio media):
17
+ * External service → Daytona Signed Preview URL → HTTP server → stream handler
18
+ *
19
+ * The HTTP server (started by mission.connect()) dispatches to the registered
20
+ * handler and sends the response back as a standard HTTP response.
21
+ *
22
+ * For WebSocket endpoints: event-based model (connect, message, disconnect).
23
+ * WebSocket support depends on Daytona Preview URL proxy supporting upgrades.
24
+ *
25
+ * Endpoint names are chosen by the plugin author at registration time.
26
+ * There is no need to pre-declare them in mission.json — the SDK registers
27
+ * them dynamically and reports them to the control plane at ready().
28
+ *
29
+ * See docs/technical-designs/plugin-architecture.md §4.4.
30
+ * See docs/technical-designs/daytona-sandbox-runtime.md §2-3.
31
+ */
32
+ import type { ApiClient } from './api';
33
+ export type IngressRequest = {
34
+ /** HTTP method (GET, POST, etc.). */
35
+ method: string;
36
+ /** Request path (relative to the ingress endpoint). */
37
+ path: string;
38
+ /** Request headers (lowercased keys). */
39
+ headers: Record<string, string>;
40
+ /** Raw request body as a string. */
41
+ body: string;
42
+ /** Parsed query parameters. */
43
+ query: Record<string, string>;
44
+ };
45
+ export type IngressResponse = {
46
+ /** HTTP status code. */
47
+ status: number;
48
+ /** Response headers. */
49
+ headers?: Record<string, string>;
50
+ /** Response body. */
51
+ body?: string;
52
+ };
53
+ export type IngressHandler = (request: IngressRequest) => Promise<IngressResponse>;
54
+ export type IngressStreamEvents = {
55
+ /** Called when a new WebSocket connection is established. */
56
+ onConnect: (streamId: string, metadata: Record<string, string>) => void;
57
+ /** Called when a message is received on the WebSocket. */
58
+ onMessage: (streamId: string, data: string) => void;
59
+ /** Called when the WebSocket disconnects. */
60
+ onDisconnect: (streamId: string) => void;
61
+ };
62
+ /**
63
+ * Result from requesting a public ingress URL.
64
+ * The URL is a Daytona Signed Preview URL with a configurable TTL.
65
+ * The plugin is responsible for monitoring expiry and re-requesting.
66
+ */
67
+ export type IngressUrl = {
68
+ /** The public URL to register with external services. */
69
+ url: string;
70
+ /** ISO 8601 timestamp when this URL expires. */
71
+ expiresAt: string;
72
+ };
73
+ export type IngressModule = {
74
+ /**
75
+ * Register a handler for an HTTP ingress endpoint.
76
+ * The endpoint name is chosen by the plugin author.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * mission.ingress.on('webhook', async (request) => {
81
+ * const payload = JSON.parse(request.body)
82
+ * // process webhook...
83
+ * return { status: 200 }
84
+ * })
85
+ * ```
86
+ */
87
+ on: (endpointName: string, handler: IngressHandler) => void;
88
+ /**
89
+ * Register handlers for a WebSocket ingress endpoint.
90
+ * The endpoint name is chosen by the plugin author.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * mission.ingress.onStream('media', {
95
+ * onConnect: (streamId, meta) => { startSession(streamId) },
96
+ * onMessage: (streamId, data) => { processAudio(streamId, data) },
97
+ * onDisconnect: (streamId) => { endSession(streamId) }
98
+ * })
99
+ * ```
100
+ */
101
+ onStream: (endpointName: string, handlers: IngressStreamEvents) => void;
102
+ /**
103
+ * Get a public URL for a named ingress endpoint.
104
+ *
105
+ * The control plane generates a Daytona Signed Preview URL with a
106
+ * configurable TTL. The plugin is responsible for:
107
+ * 1. Registering this URL with the external service.
108
+ * 2. Monitoring `expiresAt` and calling this again before expiry.
109
+ * 3. Re-registering the new URL with the external service.
110
+ *
111
+ * On sandbox restart, plugin processes restart and naturally
112
+ * re-register during their startup sequence.
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * const { url, expiresAt } = await mission.ingress.getPublicUrl('webhook')
117
+ * await twilio.incomingPhoneNumbers(sid).update({ voiceUrl: url })
118
+ * ```
119
+ */
120
+ getPublicUrl: (endpointName: string) => Promise<IngressUrl>;
121
+ };
122
+ export type IngressRegistry = IngressModule & {
123
+ /** Dispatch an HTTP request to the registered handler. */
124
+ dispatch: (endpointName: string, request: IngressRequest) => Promise<IngressResponse>;
125
+ /** Dispatch WebSocket events to the registered stream handlers. */
126
+ dispatchStreamEvent: (endpointName: string, event: 'connect' | 'message' | 'disconnect', streamId: string, data?: string, metadata?: Record<string, string>) => void;
127
+ /** Get all registered HTTP endpoint names. */
128
+ getHttpEndpointNames: () => string[];
129
+ /** Get all registered stream endpoint names. */
130
+ getStreamEndpointNames: () => string[];
131
+ };
132
+ export declare function createIngressRegistry(api: ApiClient): IngressRegistry;
133
+ //# sourceMappingURL=ingress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingress.d.ts","sourceRoot":"","sources":["../src/ingress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC,MAAM,MAAM,cAAc,GAAG;IAC3B,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAA;IACZ,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,qBAAqB;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,CAC3B,OAAO,EAAE,cAAc,KACpB,OAAO,CAAC,eAAe,CAAC,CAAA;AAI7B,MAAM,MAAM,mBAAmB,GAAG;IAChC,6DAA6D;IAC7D,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAA;IACvE,0DAA0D;IAC1D,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACnD,6CAA6C;IAC7C,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;CACzC,CAAA;AAID;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAA;IACX,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;;;;;;;;;OAYG;IACH,EAAE,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,KAAK,IAAI,CAAA;IAE3D;;;;;;;;;;;;OAYG;IACH,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,KAAK,IAAI,CAAA;IAEvE;;;;;;;;;;;;;;;;;OAiBG;IACH,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;CAC5D,CAAA;AAID,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG;IAC5C,0DAA0D;IAC1D,QAAQ,EAAE,CACR,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,cAAc,KACpB,OAAO,CAAC,eAAe,CAAC,CAAA;IAC7B,mEAAmE;IACnE,mBAAmB,EAAE,CACnB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,EAC3C,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC9B,IAAI,CAAA;IACT,8CAA8C;IAC9C,oBAAoB,EAAE,MAAM,MAAM,EAAE,CAAA;IACpC,gDAAgD;IAChD,sBAAsB,EAAE,MAAM,MAAM,EAAE,CAAA;CACvC,CAAA;AAID,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,SAAS,GAAG,eAAe,CA+ErE"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Ingress Module
3
+ *
4
+ * Handles inbound traffic from external services (webhooks, WebSocket streams).
5
+ * Plugins register handlers per endpoint name; the HTTP server routes traffic
6
+ * to them.
7
+ *
8
+ * Traffic flow (HTTP-native, no WebSocket control plane):
9
+ *
10
+ * Tool calls from Mission API:
11
+ * Mission API → Daytona Standard Preview URL → HTTP server → tool handler
12
+ *
13
+ * Webhooks from external services:
14
+ * External service → Daytona Signed Preview URL → HTTP server → ingress handler
15
+ *
16
+ * WebSocket streams (e.g., Twilio media):
17
+ * External service → Daytona Signed Preview URL → HTTP server → stream handler
18
+ *
19
+ * The HTTP server (started by mission.connect()) dispatches to the registered
20
+ * handler and sends the response back as a standard HTTP response.
21
+ *
22
+ * For WebSocket endpoints: event-based model (connect, message, disconnect).
23
+ * WebSocket support depends on Daytona Preview URL proxy supporting upgrades.
24
+ *
25
+ * Endpoint names are chosen by the plugin author at registration time.
26
+ * There is no need to pre-declare them in mission.json — the SDK registers
27
+ * them dynamically and reports them to the control plane at ready().
28
+ *
29
+ * See docs/technical-designs/plugin-architecture.md §4.4.
30
+ * See docs/technical-designs/daytona-sandbox-runtime.md §2-3.
31
+ */
32
+ // ─── Factory ─────────────────────────────────────────────────────────────────
33
+ export function createIngressRegistry(api) {
34
+ const httpHandlers = new Map();
35
+ const streamHandlers = new Map();
36
+ return {
37
+ on(endpointName, handler) {
38
+ if (httpHandlers.has(endpointName)) {
39
+ console.error(`[Ingress] Warning: overwriting handler for '${endpointName}'`);
40
+ }
41
+ httpHandlers.set(endpointName, handler);
42
+ },
43
+ onStream(endpointName, handlers) {
44
+ if (streamHandlers.has(endpointName)) {
45
+ console.error(`[Ingress] Warning: overwriting stream handlers for '${endpointName}'`);
46
+ }
47
+ streamHandlers.set(endpointName, handlers);
48
+ },
49
+ getPublicUrl: async (endpointName) => {
50
+ const result = (await api.trpc.plugin.getIngressUrl.query({
51
+ name: endpointName
52
+ }));
53
+ return result;
54
+ },
55
+ async dispatch(endpointName, request) {
56
+ const handler = httpHandlers.get(endpointName);
57
+ if (!handler) {
58
+ console.error(`[Ingress] No handler registered for endpoint '${endpointName}'`);
59
+ return { status: 404, body: `No handler for endpoint: ${endpointName}` };
60
+ }
61
+ return handler(request);
62
+ },
63
+ dispatchStreamEvent(endpointName, event, streamId, data, metadata) {
64
+ const handlers = streamHandlers.get(endpointName);
65
+ if (!handlers) {
66
+ console.error(`[Ingress] No stream handlers for endpoint '${endpointName}'`);
67
+ return;
68
+ }
69
+ switch (event) {
70
+ case 'connect':
71
+ handlers.onConnect(streamId, metadata ?? {});
72
+ break;
73
+ case 'message':
74
+ handlers.onMessage(streamId, data ?? '');
75
+ break;
76
+ case 'disconnect':
77
+ handlers.onDisconnect(streamId);
78
+ break;
79
+ }
80
+ },
81
+ getHttpEndpointNames() {
82
+ return Array.from(httpHandlers.keys());
83
+ },
84
+ getStreamEndpointNames() {
85
+ return Array.from(streamHandlers.keys());
86
+ }
87
+ };
88
+ }
89
+ //# sourceMappingURL=ingress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingress.js","sourceRoot":"","sources":["../src/ingress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAmIH,gFAAgF;AAEhF,MAAM,UAAU,qBAAqB,CAAC,GAAc;IAClD,MAAM,YAAY,GAAG,IAAI,GAAG,EAA0B,CAAA;IACtD,MAAM,cAAc,GAAG,IAAI,GAAG,EAA+B,CAAA;IAE7D,OAAO;QACL,EAAE,CAAC,YAAoB,EAAE,OAAuB;YAC9C,IAAI,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;gBACnC,OAAO,CAAC,KAAK,CACX,+CAA+C,YAAY,GAAG,CAC/D,CAAA;YACH,CAAC;YACD,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;QACzC,CAAC;QAED,QAAQ,CAAC,YAAoB,EAAE,QAA6B;YAC1D,IAAI,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;gBACrC,OAAO,CAAC,KAAK,CACX,uDAAuD,YAAY,GAAG,CACvE,CAAA;YACH,CAAC;YACD,cAAc,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;QAC5C,CAAC;QAED,YAAY,EAAE,KAAK,EAAE,YAAoB,EAAuB,EAAE;YAChE,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC;gBACxD,IAAI,EAAE,YAAY;aACnB,CAAC,CAAe,CAAA;YACjB,OAAO,MAAM,CAAA;QACf,CAAC;QAED,KAAK,CAAC,QAAQ,CACZ,YAAoB,EACpB,OAAuB;YAEvB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;YAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CACX,iDAAiD,YAAY,GAAG,CACjE,CAAA;gBACD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,4BAA4B,YAAY,EAAE,EAAE,CAAA;YAC1E,CAAC;YACD,OAAO,OAAO,CAAC,OAAO,CAAC,CAAA;QACzB,CAAC;QAED,mBAAmB,CACjB,YAAoB,EACpB,KAA2C,EAC3C,QAAgB,EAChB,IAAa,EACb,QAAiC;YAEjC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;YACjD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,CAAC,KAAK,CACX,8CAA8C,YAAY,GAAG,CAC9D,CAAA;gBACD,OAAM;YACR,CAAC;YACD,QAAQ,KAAK,EAAE,CAAC;gBACd,KAAK,SAAS;oBACZ,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAA;oBAC5C,MAAK;gBACP,KAAK,SAAS;oBACZ,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,CAAA;oBACxC,MAAK;gBACP,KAAK,YAAY;oBACf,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;oBAC/B,MAAK;YACT,CAAC;QACH,CAAC;QAED,oBAAoB;YAClB,OAAO,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAA;QACxC,CAAC;QAED,sBAAsB;YACpB,OAAO,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAA;QAC1C,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Logging Module
3
+ *
4
+ * Overrides the global `console` object to capture ALL log output.
5
+ * This means plugin authors use `console.log()` naturally and we
6
+ * automatically capture, structure, enrich, and forward logs.
7
+ *
8
+ * Each log entry is:
9
+ * 1. Written to stdout/stderr (so it appears in the sandbox terminal)
10
+ * 2. Sent to the platform's logging pipeline via tRPC
11
+ *
12
+ * The platform receives structured logs with:
13
+ * - level (log, error, warn, info, debug)
14
+ * - message (the formatted log content)
15
+ * - timestamp (ISO 8601)
16
+ *
17
+ * Transport: plugin.ingestLogs tRPC mutation (fire-and-forget).
18
+ *
19
+ * This approach ensures we never lose logs from developers who use
20
+ * `console.log` instead of a custom logging function.
21
+ */
22
+ import type { ApiClient } from './api';
23
+ /**
24
+ * Override the global console to capture and forward all log output.
25
+ *
26
+ * This should be called once during SDK initialization (in connect()).
27
+ * After this call, all console.log/error/warn/info/debug calls will
28
+ * be intercepted, enriched with metadata, and sent to the API.
29
+ */
30
+ export declare function installLogging(api: ApiClient): void;
31
+ //# sourceMappingURL=logging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAYtC;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CA+CnD"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Logging Module
3
+ *
4
+ * Overrides the global `console` object to capture ALL log output.
5
+ * This means plugin authors use `console.log()` naturally and we
6
+ * automatically capture, structure, enrich, and forward logs.
7
+ *
8
+ * Each log entry is:
9
+ * 1. Written to stdout/stderr (so it appears in the sandbox terminal)
10
+ * 2. Sent to the platform's logging pipeline via tRPC
11
+ *
12
+ * The platform receives structured logs with:
13
+ * - level (log, error, warn, info, debug)
14
+ * - message (the formatted log content)
15
+ * - timestamp (ISO 8601)
16
+ *
17
+ * Transport: plugin.ingestLogs tRPC mutation (fire-and-forget).
18
+ *
19
+ * This approach ensures we never lose logs from developers who use
20
+ * `console.log` instead of a custom logging function.
21
+ */
22
+ // ─── Install ─────────────────────────────────────────────────────────────────
23
+ /**
24
+ * Override the global console to capture and forward all log output.
25
+ *
26
+ * This should be called once during SDK initialization (in connect()).
27
+ * After this call, all console.log/error/warn/info/debug calls will
28
+ * be intercepted, enriched with metadata, and sent to the API.
29
+ */
30
+ export function installLogging(api) {
31
+ // Preserve original console methods
32
+ const original = {
33
+ log: console.log.bind(console),
34
+ error: console.error.bind(console),
35
+ warn: console.warn.bind(console),
36
+ info: console.info.bind(console),
37
+ debug: console.debug.bind(console)
38
+ };
39
+ const levels = ['log', 'error', 'warn', 'info', 'debug'];
40
+ for (const level of levels) {
41
+ console[level] = (...args) => {
42
+ // 1. Still output to stdout/stderr for local visibility
43
+ original[level](...args);
44
+ // 2. Format the message
45
+ const message = args
46
+ .map(arg => {
47
+ if (typeof arg === 'string')
48
+ return arg;
49
+ if (arg instanceof Error)
50
+ return `${arg.name}: ${arg.message}`;
51
+ try {
52
+ return JSON.stringify(arg);
53
+ }
54
+ catch {
55
+ return String(arg);
56
+ }
57
+ })
58
+ .join(' ');
59
+ // 3. Send structured log to the platform (fire-and-forget)
60
+ void api.trpc.plugin.ingestLogs
61
+ .mutate({
62
+ entries: [
63
+ {
64
+ level,
65
+ message,
66
+ args,
67
+ timestamp: new Date().toISOString()
68
+ }
69
+ ]
70
+ })
71
+ .catch((err) => {
72
+ original.error('[Logging] ingest failed:', err);
73
+ });
74
+ };
75
+ }
76
+ }
77
+ //# sourceMappingURL=logging.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAYH,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,GAAc;IAC3C,oCAAoC;IACpC,MAAM,QAAQ,GAAoB;QAChC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;QAC9B,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;QAClC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;QAChC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;KACnC,CAAA;IAED,MAAM,MAAM,GAAe,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IAEpE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE;YACtC,wDAAwD;YACxD,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;YAExB,wBAAwB;YACxB,MAAM,OAAO,GAAG,IAAI;iBACjB,GAAG,CAAC,GAAG,CAAC,EAAE;gBACT,IAAI,OAAO,GAAG,KAAK,QAAQ;oBAAE,OAAO,GAAG,CAAA;gBACvC,IAAI,GAAG,YAAY,KAAK;oBAAE,OAAO,GAAG,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,OAAO,EAAE,CAAA;gBAC9D,IAAI,CAAC;oBACH,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;gBAC5B,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;gBACpB,CAAC;YACH,CAAC,CAAC;iBACD,IAAI,CAAC,GAAG,CAAC,CAAA;YAEZ,2DAA2D;YAC3D,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU;iBAC5B,MAAM,CAAC;gBACN,OAAO,EAAE;oBACP;wBACE,KAAK;wBACL,OAAO;wBACP,IAAI;wBACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;qBACpC;iBACF;aACF,CAAC;iBACD,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;gBACtB,QAAQ,CAAC,KAAK,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAA;YACjD,CAAC,CAAC,CAAA;QACN,CAAC,CAAA;IACH,CAAC;AACH,CAAC"}
package/dist/sdk.d.ts ADDED
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Mission SDK — Main Entry
3
+ *
4
+ * Creates the SDK instance that a plugin uses to interact with the
5
+ * Mission platform. Communication is HTTP-native:
6
+ *
7
+ * Outbound (Plugin → Mission API):
8
+ * Standard REST calls via the API client.
9
+ *
10
+ * Inbound (Mission API → Plugin):
11
+ * HTTP requests to the plugin's HTTP server, exposed via
12
+ * Daytona Preview URLs.
13
+ *
14
+ * Lifecycle:
15
+ * 1. const mission = createMissionSDK() — create SDK (no connection yet)
16
+ * 2. await mission.connect() — start HTTP server, install logging
17
+ * 3. // auth, config, events are now usable
18
+ * 4. mission.tools.registerAll(handlers) — register tool handlers
19
+ * 5. mission.ingress.on('name', handler) — register ingress handlers
20
+ * 6. mission.onShutdown(() => cleanup()) — register shutdown hooks
21
+ * 7. await mission.ready() — signal readiness, accept traffic
22
+ *
23
+ * See docs/technical-designs/plugin-architecture.md §4 and §6.
24
+ * See docs/technical-designs/daytona-sandbox-runtime.md.
25
+ */
26
+ import { type AuthModule } from './auth';
27
+ import { type ConfigModule } from './config';
28
+ import { type PluginContext } from './context';
29
+ import { type EventsModule } from './events';
30
+ import { type IngressModule } from './ingress';
31
+ import { type ToolsModule } from './tool-registry';
32
+ export type MissionSDKOptions = {
33
+ /**
34
+ * Override the plugin context instead of reading from env.
35
+ * Useful for testing or local development.
36
+ */
37
+ context?: Partial<PluginContext>;
38
+ /**
39
+ * Override the plugin HTTP server port. Normally read from
40
+ * MISSION_PLUGIN_PORT (assigned by the control plane).
41
+ * Must be in the Daytona Preview URL range (3000-9999).
42
+ */
43
+ port?: number;
44
+ };
45
+ export type MissionSDK = {
46
+ /** The resolved plugin context. */
47
+ context: PluginContext;
48
+ /** Get authentication credentials (user-provided secrets and/or OAuth tokens). */
49
+ auth: AuthModule;
50
+ /** Fetch per-installation configuration. */
51
+ config: ConfigModule;
52
+ /** Send messages to the agent about external events. */
53
+ events: EventsModule;
54
+ /** Register ingress handlers and discover public URLs. */
55
+ ingress: IngressModule;
56
+ /** Register tool handlers that the platform can invoke. */
57
+ tools: ToolsModule;
58
+ /**
59
+ * Connect to the Mission platform.
60
+ *
61
+ * This starts the plugin's HTTP server (for inbound tool calls and
62
+ * ingress traffic), installs the console override for structured
63
+ * logging, and begins the keep-alive heartbeat loop.
64
+ *
65
+ * After this call, `auth`, `config`, `events`, and `ingress.getPublicUrl`
66
+ * are usable.
67
+ */
68
+ connect: () => Promise<void>;
69
+ /**
70
+ * Signal readiness and start accepting tool calls and ingress traffic.
71
+ *
72
+ * Call this AFTER registering all tools and ingress handlers.
73
+ * The returned promise resolves when the process receives a shutdown
74
+ * signal (SIGTERM/SIGINT) and graceful shutdown completes.
75
+ */
76
+ ready: () => Promise<void>;
77
+ /**
78
+ * Register a callback to run during graceful shutdown.
79
+ * Multiple handlers can be registered; they run in order.
80
+ *
81
+ * Shutdown is triggered by SIGTERM or SIGINT (standard container signals).
82
+ * The SDK stops the HTTP server, drains in-flight requests, runs
83
+ * shutdown handlers, then exits.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * mission.onShutdown(async () => {
88
+ * await database.close()
89
+ * await cache.flush()
90
+ * })
91
+ * ```
92
+ */
93
+ onShutdown: (handler: () => Promise<void> | void) => void;
94
+ };
95
+ /**
96
+ * Create a Mission SDK instance.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * import { createMissionSDK } from '@mission/sdk'
101
+ *
102
+ * const mission = createMissionSDK()
103
+ * await mission.connect()
104
+ *
105
+ * const auth = await mission.auth.get()
106
+ * const config = await mission.config.get<MyConfig>(defaults)
107
+ *
108
+ * mission.tools.registerAll(handlers)
109
+ * mission.ingress.on('webhook', handler)
110
+ * mission.onShutdown(() => cleanup())
111
+ *
112
+ * await mission.ready()
113
+ * ```
114
+ */
115
+ export declare function createMissionSDK(options?: MissionSDKOptions): MissionSDK;
116
+ //# sourceMappingURL=sdk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,QAAQ,CAAA;AAC1D,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,UAAU,CAAA;AAChE,OAAO,EAAE,KAAK,aAAa,EAAsB,MAAM,WAAW,CAAA;AAClE,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,UAAU,CAAA;AAEhE,OAAO,EAEL,KAAK,aAAa,EAEnB,MAAM,WAAW,CAAA;AAElB,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAA;AAIxB,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IAChC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,mCAAmC;IACnC,OAAO,EAAE,aAAa,CAAA;IACtB,kFAAkF;IAClF,IAAI,EAAE,UAAU,CAAA;IAChB,4CAA4C;IAC5C,MAAM,EAAE,YAAY,CAAA;IACpB,wDAAwD;IACxD,MAAM,EAAE,YAAY,CAAA;IACpB,0DAA0D;IAC1D,OAAO,EAAE,aAAa,CAAA;IACtB,2DAA2D;IAC3D,KAAK,EAAE,WAAW,CAAA;IAElB;;;;;;;;;OASG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAE5B;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAE1B;;;;;;;;;;;;;;;OAeG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,IAAI,CAAA;CAC1D,CAAA;AAaD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,UAAU,CAqTxE"}