@tapicker/bridge 1.0.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 (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +46 -0
  3. package/dist/bridge/bridge-service.d.ts +46 -0
  4. package/dist/bridge/bridge-service.js +245 -0
  5. package/dist/bridge/control.d.ts +7 -0
  6. package/dist/bridge/control.js +211 -0
  7. package/dist/bridge/daemon.d.ts +16 -0
  8. package/dist/bridge/daemon.js +97 -0
  9. package/dist/bridge/extension-session.d.ts +43 -0
  10. package/dist/bridge/extension-session.js +204 -0
  11. package/dist/bridge/pairing-state.d.ts +22 -0
  12. package/dist/bridge/pairing-state.js +76 -0
  13. package/dist/cli.d.ts +3 -0
  14. package/dist/cli.js +835 -0
  15. package/dist/commands.d.ts +33 -0
  16. package/dist/commands.js +123 -0
  17. package/dist/constants.d.ts +10 -0
  18. package/dist/constants.js +10 -0
  19. package/dist/errors.d.ts +27 -0
  20. package/dist/errors.js +52 -0
  21. package/dist/index.d.ts +10 -0
  22. package/dist/index.js +8 -0
  23. package/dist/mcp.d.ts +13 -0
  24. package/dist/mcp.js +300 -0
  25. package/dist/protocol/schema.d.ts +149 -0
  26. package/dist/protocol/schema.js +155 -0
  27. package/dist/server.d.ts +63 -0
  28. package/dist/server.js +486 -0
  29. package/dist/workflow-watch.d.ts +31 -0
  30. package/dist/workflow-watch.js +304 -0
  31. package/docs/cli.md +112 -0
  32. package/docs/http-api.md +149 -0
  33. package/docs/mcp.md +90 -0
  34. package/docs/operations.md +85 -0
  35. package/docs/workflow-watch.md +86 -0
  36. package/package.json +55 -0
  37. package/src/bridge/bridge-service.ts +291 -0
  38. package/src/bridge/control.ts +281 -0
  39. package/src/bridge/daemon.ts +102 -0
  40. package/src/bridge/extension-session.ts +286 -0
  41. package/src/bridge/pairing-state.ts +92 -0
  42. package/src/cli.ts +1019 -0
  43. package/src/commands.ts +158 -0
  44. package/src/constants.ts +10 -0
  45. package/src/errors.ts +72 -0
  46. package/src/index.ts +35 -0
  47. package/src/mcp.ts +386 -0
  48. package/src/protocol/schema.ts +202 -0
  49. package/src/server.ts +623 -0
  50. package/src/workflow-watch.ts +364 -0
@@ -0,0 +1,202 @@
1
+ import { z } from 'zod'
2
+ import { randomUUID } from 'node:crypto'
3
+ import { PROTOCOL_VERSION } from '../constants.js'
4
+
5
+ export const MessageEnvelopeSchema = z
6
+ .object({
7
+ id: z.string().min(1),
8
+ time: z.number().int().nonnegative(),
9
+ type: z.string().min(1),
10
+ data: z.unknown().optional(),
11
+ cb: z.literal(false).optional(),
12
+ })
13
+ .strict()
14
+
15
+ export type MessageEnvelope = z.infer<typeof MessageEnvelopeSchema>
16
+
17
+ export const SafeResultSchema = z.union([
18
+ z
19
+ .object({
20
+ ok: z.literal(true),
21
+ data: z.unknown().optional(),
22
+ })
23
+ .strict(),
24
+ z
25
+ .object({
26
+ ok: z.literal(false),
27
+ error: z
28
+ .object({
29
+ code: z.string().min(1),
30
+ message: z.string(),
31
+ details: z.unknown().optional(),
32
+ })
33
+ .strict(),
34
+ })
35
+ .strict(),
36
+ ])
37
+
38
+ export type SafeResult = z.infer<typeof SafeResultSchema>
39
+
40
+ export const ExtensionHelloInputSchema = z
41
+ .object({
42
+ clientId: z.uuid(),
43
+ clientName: z.string().trim().min(1).max(80),
44
+ credential: z.string().min(1).optional(),
45
+ extensionVersion: z.string().min(1).optional(),
46
+ capabilities: z.array(z.string().min(1)).default([]),
47
+ })
48
+ .strict()
49
+
50
+ export type ExtensionHelloInput = z.infer<typeof ExtensionHelloInputSchema>
51
+
52
+ export const ExtensionPairInputSchema = z
53
+ .object({
54
+ clientId: z.uuid(),
55
+ clientName: z.string().trim().min(1).max(80),
56
+ pairingCode: z.string().regex(/^\d{4}$/),
57
+ })
58
+ .strict()
59
+
60
+ export type ExtensionPairInput = z.infer<typeof ExtensionPairInputSchema>
61
+
62
+ export const BridgeHelloDataSchema = z
63
+ .object({
64
+ accepted: z.boolean(),
65
+ requiresPairing: z.boolean(),
66
+ bridgeVersion: z.string().min(1),
67
+ protocolVersion: z.literal(PROTOCOL_VERSION),
68
+ capabilities: z.array(z.string().min(1)),
69
+ })
70
+ .strict()
71
+
72
+ export const BridgePairDataSchema = z
73
+ .object({
74
+ accepted: z.literal(true),
75
+ clientId: z.uuid(),
76
+ credential: z.string().min(1),
77
+ })
78
+ .strict()
79
+
80
+ export const TabTargetSchema = z.discriminatedUnion('mode', [
81
+ z.object({ mode: z.literal('active') }).strict(),
82
+ z.object({ mode: z.literal('new') }).strict(),
83
+ z.object({ mode: z.literal('id'), tabId: z.number().int().positive() }).strict(),
84
+ ])
85
+
86
+ export const WorkflowStartInputSchema = z
87
+ .object({
88
+ workflowId: z.string().min(1),
89
+ args: z.record(z.string(), z.unknown()).default({}),
90
+ tab: TabTargetSchema.default({ mode: 'active' }),
91
+ })
92
+ .strict()
93
+
94
+ export type WorkflowStartInput = z.infer<typeof WorkflowStartInputSchema>
95
+
96
+ export const WorkflowControlInputSchema = z
97
+ .object({
98
+ workflowId: z.string().min(1),
99
+ })
100
+ .strict()
101
+
102
+ export type WorkflowControlInput = z.infer<typeof WorkflowControlInputSchema>
103
+
104
+ export const DataInputSchema = z
105
+ .object({
106
+ tableId: z.string().trim().min(1).max(128),
107
+ })
108
+ .strict()
109
+
110
+ export type DataInput = z.infer<typeof DataInputSchema>
111
+
112
+ export const WorkflowLifecycleStateSchema = z.enum(['running', 'paused', 'stopping', 'completed', 'stopped', 'failed'])
113
+
114
+ export const WorkflowStatusDataSchema = z
115
+ .object({
116
+ workflowId: z.string().min(1),
117
+ state: WorkflowLifecycleStateSchema,
118
+ updatedAt: z.iso.datetime(),
119
+ })
120
+ .strict()
121
+
122
+ export type WorkflowStatusData = z.infer<typeof WorkflowStatusDataSchema>
123
+
124
+ export const WorkflowStatusEventSchema = z
125
+ .object({
126
+ clientId: z.uuid(),
127
+ ...WorkflowStatusDataSchema.shape,
128
+ })
129
+ .strict()
130
+
131
+ export type WorkflowStatusEvent = z.infer<typeof WorkflowStatusEventSchema>
132
+
133
+ export const WorkflowWatchRequestSchema = z
134
+ .object({
135
+ clientId: z.uuid().optional(),
136
+ input: WorkflowControlInputSchema,
137
+ })
138
+ .strict()
139
+
140
+ export type WorkflowWatchRequest = z.infer<typeof WorkflowWatchRequestSchema>
141
+
142
+ export const WorkflowStartResultSchema = z
143
+ .object({
144
+ clientId: z.uuid(),
145
+ workflowId: z.string().min(1),
146
+ workflowName: z.string().min(1),
147
+ state: z.enum(['accepted', 'starting', 'running']).optional(),
148
+ })
149
+ .strict()
150
+
151
+ export type WorkflowStartResult = z.infer<typeof WorkflowStartResultSchema>
152
+
153
+ export function createEnvelope<TData>(
154
+ type: string,
155
+ data: TData,
156
+ options: { id?: string; callback?: boolean } = {},
157
+ ): MessageEnvelope {
158
+ const envelope: MessageEnvelope = {
159
+ id: options.id ?? randomUUID(),
160
+ time: Date.now(),
161
+ type,
162
+ data,
163
+ }
164
+
165
+ if (options.callback === false) {
166
+ envelope.cb = false
167
+ }
168
+
169
+ return envelope
170
+ }
171
+
172
+ export function parseEnvelope(data: unknown) {
173
+ let value = data
174
+
175
+ if (Buffer.isBuffer(value)) {
176
+ value = value.toString('utf8')
177
+ }
178
+
179
+ if (typeof value === 'string') {
180
+ try {
181
+ value = JSON.parse(value) as unknown
182
+ } catch {
183
+ return {
184
+ success: false as const,
185
+ error: new Error('WebSocket message is not valid JSON'),
186
+ }
187
+ }
188
+ }
189
+
190
+ const result = MessageEnvelopeSchema.safeParse(value)
191
+ if (!result.success) {
192
+ return {
193
+ success: false as const,
194
+ error: result.error,
195
+ }
196
+ }
197
+
198
+ return {
199
+ success: true as const,
200
+ data: result.data,
201
+ }
202
+ }