@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,92 @@
1
+ import { randomUUID } from 'node:crypto'
2
+ import { mkdir, open, readFile, rename, unlink } from 'node:fs/promises'
3
+ import { homedir } from 'node:os'
4
+ import { dirname, join } from 'node:path'
5
+ import { z } from 'zod'
6
+ import { BridgeError } from '../errors.js'
7
+
8
+ const PairingStateSchema = z
9
+ .object({
10
+ version: z.literal(1),
11
+ clients: z
12
+ .array(
13
+ z
14
+ .object({
15
+ clientId: z.uuid(),
16
+ credential: z.uuid(),
17
+ })
18
+ .strict(),
19
+ )
20
+ .default([]),
21
+ })
22
+ .strict()
23
+
24
+ export type PairedExtensionIdentity = z.infer<typeof PairingStateSchema>['clients'][number]
25
+
26
+ export interface PairingStatePersistence {
27
+ load(): Promise<PairedExtensionIdentity[]>
28
+ save(identities: PairedExtensionIdentity[]): Promise<void>
29
+ }
30
+
31
+ export class PairingStateFile implements PairingStatePersistence {
32
+ constructor(private readonly filePath: string) {}
33
+
34
+ async load(): Promise<PairedExtensionIdentity[]> {
35
+ await mkdir(dirname(this.filePath), { recursive: true, mode: 0o700 })
36
+
37
+ let content: string
38
+ try {
39
+ content = await readFile(this.filePath, 'utf8')
40
+ } catch (error) {
41
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') return []
42
+ throw error
43
+ }
44
+
45
+ let value: unknown
46
+ try {
47
+ value = JSON.parse(content)
48
+ } catch (cause) {
49
+ throw new BridgeError('InvalidPairingState', 'Saved Bridge pairing state is not valid JSON', {
50
+ status: 500,
51
+ cause,
52
+ })
53
+ }
54
+
55
+ const parsed = PairingStateSchema.safeParse(value)
56
+ if (!parsed.success) {
57
+ throw new BridgeError(
58
+ 'InvalidPairingState',
59
+ `Saved Bridge pairing state at ${this.filePath} has an unsupported format. This pre-release version does not migrate old state automatically; update it to the version 1 clients-array format or remove it and pair Extensions again.`,
60
+ { status: 500, details: parsed.error.issues },
61
+ )
62
+ }
63
+
64
+ return parsed.data.clients
65
+ }
66
+
67
+ async save(identities: PairedExtensionIdentity[]): Promise<void> {
68
+ const directory = dirname(this.filePath)
69
+ await mkdir(directory, { recursive: true, mode: 0o700 })
70
+
71
+ const temporaryPath = join(directory, `.paired-clients-${process.pid}-${randomUUID()}.tmp`)
72
+ const content = JSON.stringify({ version: 1, clients: identities }, null, 2)
73
+ let file: Awaited<ReturnType<typeof open>> | undefined
74
+
75
+ try {
76
+ file = await open(temporaryPath, 'wx', 0o600)
77
+ await file.writeFile(content, 'utf8')
78
+ await file.sync()
79
+ await file.close()
80
+ file = undefined
81
+ await rename(temporaryPath, this.filePath)
82
+ } catch (error) {
83
+ await file?.close().catch(() => undefined)
84
+ await unlink(temporaryPath).catch(() => undefined)
85
+ throw error
86
+ }
87
+ }
88
+ }
89
+
90
+ export function getDefaultBridgeDataDir(home = homedir()) {
91
+ return join(home, '.tapicker')
92
+ }