@vibesdotdev/client 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 (117) hide show
  1. package/SPEC.md +107 -0
  2. package/dist/factory.d.ts +34 -0
  3. package/dist/factory.d.ts.map +1 -0
  4. package/dist/factory.js +80 -0
  5. package/dist/factory.js.map +1 -0
  6. package/dist/index.d.ts +10 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +6 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/lib/client/core.d.ts +8 -0
  11. package/dist/lib/client/core.d.ts.map +1 -0
  12. package/dist/lib/client/core.js +5 -0
  13. package/dist/lib/client/core.js.map +1 -0
  14. package/dist/lib/client/internal/base-client.d.ts +19 -0
  15. package/dist/lib/client/internal/base-client.d.ts.map +1 -0
  16. package/dist/lib/client/internal/base-client.js +92 -0
  17. package/dist/lib/client/internal/base-client.js.map +1 -0
  18. package/dist/lib/client/internal/base-helpers.d.ts +9 -0
  19. package/dist/lib/client/internal/base-helpers.d.ts.map +1 -0
  20. package/dist/lib/client/internal/base-helpers.js +79 -0
  21. package/dist/lib/client/internal/base-helpers.js.map +1 -0
  22. package/dist/lib/client/internal/base-types.d.ts +35 -0
  23. package/dist/lib/client/internal/base-types.d.ts.map +1 -0
  24. package/dist/lib/client/internal/base-types.js +15 -0
  25. package/dist/lib/client/internal/base-types.js.map +1 -0
  26. package/dist/lib/client/internal/endpoint.d.ts +22 -0
  27. package/dist/lib/client/internal/endpoint.d.ts.map +1 -0
  28. package/dist/lib/client/internal/endpoint.js +35 -0
  29. package/dist/lib/client/internal/endpoint.js.map +1 -0
  30. package/dist/lib/client/internal/generator.d.ts +20 -0
  31. package/dist/lib/client/internal/generator.d.ts.map +1 -0
  32. package/dist/lib/client/internal/generator.js +173 -0
  33. package/dist/lib/client/internal/generator.js.map +1 -0
  34. package/dist/lib/client/internal/index.d.ts +5 -0
  35. package/dist/lib/client/internal/index.d.ts.map +1 -0
  36. package/dist/lib/client/internal/index.js +4 -0
  37. package/dist/lib/client/internal/index.js.map +1 -0
  38. package/dist/lib/client/internal/node/http2-fetch.node.d.ts +2 -0
  39. package/dist/lib/client/internal/node/http2-fetch.node.d.ts.map +1 -0
  40. package/dist/lib/client/internal/node/http2-fetch.node.js +131 -0
  41. package/dist/lib/client/internal/node/http2-fetch.node.js.map +1 -0
  42. package/dist/lib/client/internal/request-builder.d.ts +15 -0
  43. package/dist/lib/client/internal/request-builder.d.ts.map +1 -0
  44. package/dist/lib/client/internal/request-builder.js +158 -0
  45. package/dist/lib/client/internal/request-builder.js.map +1 -0
  46. package/dist/lib/client/internal/sse-stream.d.ts +23 -0
  47. package/dist/lib/client/internal/sse-stream.d.ts.map +1 -0
  48. package/dist/lib/client/internal/sse-stream.js +110 -0
  49. package/dist/lib/client/internal/sse-stream.js.map +1 -0
  50. package/dist/lib/client/internal/vibes-client.d.ts +32 -0
  51. package/dist/lib/client/internal/vibes-client.d.ts.map +1 -0
  52. package/dist/lib/client/internal/vibes-client.js +120 -0
  53. package/dist/lib/client/internal/vibes-client.js.map +1 -0
  54. package/dist/lib/client/internal/wrap-fetch.d.ts +6 -0
  55. package/dist/lib/client/internal/wrap-fetch.d.ts.map +1 -0
  56. package/dist/lib/client/internal/wrap-fetch.js +46 -0
  57. package/dist/lib/client/internal/wrap-fetch.js.map +1 -0
  58. package/dist/lib/client/node.d.ts +5 -0
  59. package/dist/lib/client/node.d.ts.map +1 -0
  60. package/dist/lib/client/node.js +33 -0
  61. package/dist/lib/client/node.js.map +1 -0
  62. package/dist/lib/client/types.d.ts +145 -0
  63. package/dist/lib/client/types.d.ts.map +1 -0
  64. package/dist/lib/client/types.js +21 -0
  65. package/dist/lib/client/types.js.map +1 -0
  66. package/dist/plugin.d.ts +19 -0
  67. package/dist/plugin.d.ts.map +1 -0
  68. package/dist/plugin.js +80 -0
  69. package/dist/plugin.js.map +1 -0
  70. package/dist/schemas.d.ts +90 -0
  71. package/dist/schemas.d.ts.map +1 -0
  72. package/dist/schemas.js +9 -0
  73. package/dist/schemas.js.map +1 -0
  74. package/dist/sse-client.d.ts +39 -0
  75. package/dist/sse-client.d.ts.map +1 -0
  76. package/dist/sse-client.js +124 -0
  77. package/dist/sse-client.js.map +1 -0
  78. package/dist/tools/api-request/api-request.descriptor.d.ts +48 -0
  79. package/dist/tools/api-request/api-request.descriptor.d.ts.map +1 -0
  80. package/dist/tools/api-request/api-request.descriptor.js +27 -0
  81. package/dist/tools/api-request/api-request.descriptor.js.map +1 -0
  82. package/dist/tools/api-request/api-request.impl.consumer.d.ts +13 -0
  83. package/dist/tools/api-request/api-request.impl.consumer.d.ts.map +1 -0
  84. package/dist/tools/api-request/api-request.impl.consumer.js +51 -0
  85. package/dist/tools/api-request/api-request.impl.consumer.js.map +1 -0
  86. package/dist/tools/api-request/index.d.ts +5 -0
  87. package/dist/tools/api-request/index.d.ts.map +1 -0
  88. package/dist/tools/api-request/index.js +4 -0
  89. package/dist/tools/api-request/index.js.map +1 -0
  90. package/dist/tools/api-request/schemas/index.d.ts +33 -0
  91. package/dist/tools/api-request/schemas/index.d.ts.map +1 -0
  92. package/dist/tools/api-request/schemas/index.js +24 -0
  93. package/dist/tools/api-request/schemas/index.js.map +1 -0
  94. package/package.json +99 -0
  95. package/src/factory.ts +114 -0
  96. package/src/index.ts +15 -0
  97. package/src/lib/client/core.ts +13 -0
  98. package/src/lib/client/internal/base-client.ts +107 -0
  99. package/src/lib/client/internal/base-helpers.ts +74 -0
  100. package/src/lib/client/internal/base-types.ts +42 -0
  101. package/src/lib/client/internal/endpoint.ts +51 -0
  102. package/src/lib/client/internal/generator.ts +181 -0
  103. package/src/lib/client/internal/index.ts +4 -0
  104. package/src/lib/client/internal/node/http2-fetch.node.ts +138 -0
  105. package/src/lib/client/internal/request-builder.ts +147 -0
  106. package/src/lib/client/internal/sse-stream.ts +130 -0
  107. package/src/lib/client/internal/vibes-client.ts +167 -0
  108. package/src/lib/client/internal/wrap-fetch.ts +59 -0
  109. package/src/lib/client/node.ts +36 -0
  110. package/src/lib/client/types.ts +156 -0
  111. package/src/plugin.ts +104 -0
  112. package/src/schemas.ts +91 -0
  113. package/src/sse-client.ts +155 -0
  114. package/src/tools/api-request/api-request.descriptor.ts +28 -0
  115. package/src/tools/api-request/api-request.impl.consumer.ts +66 -0
  116. package/src/tools/api-request/index.ts +4 -0
  117. package/src/tools/api-request/schemas/index.ts +29 -0
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Client-side SSE (Server-Sent Events) client.
3
+ *
4
+ * Provides a typed interface for connecting to SSE endpoints,
5
+ * handling reconnection, and dispatching events.
6
+ */
7
+
8
+ export type SSEConnectionStatus =
9
+ | 'connecting'
10
+ | 'connected'
11
+ | 'reconnecting'
12
+ | 'disconnected'
13
+ | 'error';
14
+
15
+ export interface SSEClientOptions {
16
+ url: string;
17
+ reconnectDelay?: number;
18
+ maxReconnectAttempts?: number;
19
+ onStatusChange?: (status: SSEConnectionStatus) => void;
20
+ onError?: (error: string) => void;
21
+ }
22
+
23
+ type EventHandler = (data: unknown) => void;
24
+
25
+ export class SSEClient {
26
+ private url: string;
27
+ private reconnectDelay: number;
28
+ private maxReconnectAttempts: number;
29
+ private onStatusChange?: (status: SSEConnectionStatus) => void;
30
+ private onError?: (error: string) => void;
31
+
32
+ private eventSource: EventSource | null = null;
33
+ private handlers = new Map<string, Set<EventHandler>>();
34
+ private reconnectAttempts = 0;
35
+ private reconnectTimer: ReturnType<typeof setTimeout> | null = null;
36
+ private _status: SSEConnectionStatus = 'disconnected';
37
+
38
+ constructor(options: SSEClientOptions) {
39
+ this.url = options.url;
40
+ this.reconnectDelay = options.reconnectDelay ?? 5000;
41
+ this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;
42
+ this.onStatusChange = options.onStatusChange;
43
+ this.onError = options.onError;
44
+ }
45
+
46
+ get status(): SSEConnectionStatus {
47
+ return this._status;
48
+ }
49
+
50
+ connect(): void {
51
+ this.setStatus('connecting');
52
+
53
+ try {
54
+ const EventSourceCtor = globalThis.EventSource as {
55
+ new (url: string): EventSource;
56
+ };
57
+ this.eventSource = new EventSourceCtor(this.url);
58
+
59
+ this.eventSource.onopen = () => {
60
+ this.reconnectAttempts = 0;
61
+ this.setStatus('connected');
62
+ };
63
+
64
+ this.eventSource.onerror = () => {
65
+ const error = `SSE connection error`;
66
+ this.onError?.(error);
67
+
68
+ if (this.reconnectAttempts < this.maxReconnectAttempts) {
69
+ this.setStatus('reconnecting');
70
+ this.reconnectAttempts++;
71
+ this.scheduleReconnect();
72
+ } else {
73
+ this.setStatus('error');
74
+ this.cleanup();
75
+ }
76
+ };
77
+
78
+ // Dispatch events to registered handlers
79
+ this.eventSource.onmessage = (event) => {
80
+ this.dispatch('message', event.data);
81
+ };
82
+
83
+ // Listen for named events by iterating registered handlers
84
+ for (const eventName of this.handlers.keys()) {
85
+ if (eventName === 'message') continue;
86
+ this.eventSource.addEventListener(eventName, (event) => {
87
+ try {
88
+ const data = JSON.parse((event as MessageEvent).data);
89
+ this.dispatch(eventName, data);
90
+ } catch {
91
+ this.dispatch(eventName, (event as MessageEvent).data);
92
+ }
93
+ });
94
+ }
95
+ } catch (e) {
96
+ const error = e instanceof Error ? e.message : 'Failed to create SSE connection';
97
+ this.onError?.(error);
98
+ this.setStatus('error');
99
+ }
100
+ }
101
+
102
+ disconnect(): void {
103
+ this.cleanup();
104
+ this.setStatus('disconnected');
105
+ }
106
+
107
+ on(event: string, handler: EventHandler): () => void {
108
+ if (!this.handlers.has(event)) {
109
+ this.handlers.set(event, new Set());
110
+ }
111
+ this.handlers.get(event)!.add(handler);
112
+
113
+ // Return unsubscribe function
114
+ return () => {
115
+ this.handlers.get(event)?.delete(handler);
116
+ };
117
+ }
118
+
119
+ private dispatch(event: string, data: unknown): void {
120
+ this.handlers.get(event)?.forEach((handler) => {
121
+ try {
122
+ handler(data);
123
+ } catch (e) {
124
+ console.error(`[SSEClient] Error in handler for "${event}":`, e);
125
+ }
126
+ });
127
+ }
128
+
129
+ private setStatus(status: SSEConnectionStatus): void {
130
+ this._status = status;
131
+ this.onStatusChange?.(status);
132
+ }
133
+
134
+ private scheduleReconnect(): void {
135
+ if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
136
+ this.reconnectTimer = setTimeout(() => {
137
+ this.connect();
138
+ }, this.reconnectDelay);
139
+ }
140
+
141
+ private cleanup(): void {
142
+ if (this.reconnectTimer) {
143
+ clearTimeout(this.reconnectTimer);
144
+ this.reconnectTimer = null;
145
+ }
146
+ if (this.eventSource) {
147
+ this.eventSource.close();
148
+ this.eventSource = null;
149
+ }
150
+ }
151
+ }
152
+
153
+ export function createSSEClient(options: SSEClientOptions): SSEClient {
154
+ return new SSEClient(options);
155
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * api-request Tool Descriptor
3
+ *
4
+ * Metadata for the api-request tool. Safe to import anywhere.
5
+ */
6
+
7
+ import { createRuntimeAsset } from '@vibesdotdev/runtime/factory';
8
+ import { apiRequestInputSchema, apiRequestOutputSchema } from './schemas/index.ts';
9
+
10
+ export default createRuntimeAsset({
11
+ kind: 'tools/tool',
12
+ id: 'api-request',
13
+ name: 'API Request',
14
+ description: 'Make an authenticated API request to any Vibes endpoint.',
15
+ mcpDescription: 'Make authenticated API request to Vibes endpoints. Ex: {method:"GET",path:"/api/health"}.',
16
+ hardware: ['consumer'],
17
+ purpose: ['direct', 'worker', 'mcp', 'agent'],
18
+ category: 'execution',
19
+ subcategory: 'api-request',
20
+ tags: ['api', 'network'],
21
+ safety: 'write',
22
+ requiresApproval: true,
23
+ permissions: ['canAccessNetwork'],
24
+ schemas: {
25
+ input: apiRequestInputSchema,
26
+ output: apiRequestOutputSchema
27
+ }
28
+ });
@@ -0,0 +1,66 @@
1
+ /**
2
+ * api-request Tool Implementation (Consumer)
3
+ *
4
+ * Consumer-scoped implementation for making authenticated API requests.
5
+ * Resolves the `api/client` runtime kind and delegates to its `.request()`.
6
+ */
7
+
8
+ import type { VibesRuntime, ToolCallContext } from '@vibesdotdev/runtime';
9
+ import type { ApiClientImplementation } from '../../schemas.ts';
10
+ import type { ApiRequestInput, ApiRequestOutput } from './schemas/index.ts';
11
+
12
+ async function resolveApiClient(runtime: VibesRuntime): Promise<ApiClientImplementation> {
13
+ try {
14
+ const apiClient = (await runtime.query('api/client').resolve()) as
15
+ | ApiClientImplementation
16
+ | undefined;
17
+ if (apiClient) {
18
+ return apiClient;
19
+ }
20
+ } catch {
21
+ // Query failed, fall through
22
+ }
23
+
24
+ throw new Error(
25
+ 'API client not available in runtime context. Ensure api/client kind is registered.'
26
+ );
27
+ }
28
+
29
+ export default {
30
+ async execute(
31
+ input: ApiRequestInput,
32
+ runtime: VibesRuntime,
33
+ _ctx: ToolCallContext
34
+ ): Promise<ApiRequestOutput> {
35
+ const method = input.method;
36
+ const path = input.path;
37
+ const query = input.query ?? {};
38
+ const body = input.body ?? undefined;
39
+ const headers = input.headers ?? {};
40
+
41
+ try {
42
+ const apiClient = await resolveApiClient(runtime);
43
+
44
+ const response = await apiClient.request(path, {
45
+ method,
46
+ query,
47
+ body,
48
+ headers
49
+ });
50
+
51
+ return {
52
+ status: 'success',
53
+ response
54
+ };
55
+ } catch (error) {
56
+ const message = error instanceof Error ? error.message : String(error);
57
+ return {
58
+ status: 'error',
59
+ error: {
60
+ message,
61
+ code: 'API_REQUEST_FAILED'
62
+ }
63
+ };
64
+ }
65
+ }
66
+ };
@@ -0,0 +1,4 @@
1
+ export { default as apiRequestToolDescriptor } from './api-request.descriptor.ts';
2
+ export { default as apiRequestToolImplementation } from './api-request.impl.consumer.ts';
3
+ export { apiRequestInputSchema, apiRequestOutputSchema } from './schemas/index.ts';
4
+ export type { ApiRequestInput, ApiRequestOutput } from './schemas/index.ts';
@@ -0,0 +1,29 @@
1
+ /**
2
+ * API Request Tool Schemas
3
+ *
4
+ * Input/output schemas for the api-request tool.
5
+ */
6
+
7
+ import * as z from 'zod/v4';
8
+
9
+ export const apiRequestInputSchema = z.object({
10
+ method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']),
11
+ path: z.string().min(1),
12
+ query: z.record(z.string(), z.any()).optional(),
13
+ body: z.any().optional(),
14
+ headers: z.record(z.string(), z.string()).optional()
15
+ });
16
+
17
+ export const apiRequestOutputSchema = z.object({
18
+ status: z.enum(['success', 'error']),
19
+ response: z.unknown().optional(),
20
+ error: z
21
+ .object({
22
+ message: z.string(),
23
+ code: z.string().optional()
24
+ })
25
+ .optional()
26
+ });
27
+
28
+ export type ApiRequestInput = z.infer<typeof apiRequestInputSchema>;
29
+ export type ApiRequestOutput = z.infer<typeof apiRequestOutputSchema>;