pty-auto 0.3.6

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 (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +515 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +3 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/src/plugin/constants.d.ts +5 -0
  8. package/dist/src/plugin/constants.d.ts.map +1 -0
  9. package/dist/src/plugin/constants.js +7 -0
  10. package/dist/src/plugin/constants.js.map +1 -0
  11. package/dist/src/plugin/pty/buffer.d.ts +19 -0
  12. package/dist/src/plugin/pty/buffer.d.ts.map +1 -0
  13. package/dist/src/plugin/pty/buffer.js +61 -0
  14. package/dist/src/plugin/pty/buffer.js.map +1 -0
  15. package/dist/src/plugin/pty/formatters.d.ts +4 -0
  16. package/dist/src/plugin/pty/formatters.d.ts.map +1 -0
  17. package/dist/src/plugin/pty/formatters.js +22 -0
  18. package/dist/src/plugin/pty/formatters.js.map +1 -0
  19. package/dist/src/plugin/pty/manager.d.ts +33 -0
  20. package/dist/src/plugin/pty/manager.d.ts.map +1 -0
  21. package/dist/src/plugin/pty/manager.js +108 -0
  22. package/dist/src/plugin/pty/manager.js.map +1 -0
  23. package/dist/src/plugin/pty/notification-manager.d.ts +9 -0
  24. package/dist/src/plugin/pty/notification-manager.d.ts.map +1 -0
  25. package/dist/src/plugin/pty/notification-manager.js +69 -0
  26. package/dist/src/plugin/pty/notification-manager.js.map +1 -0
  27. package/dist/src/plugin/pty/output-manager.d.ts +7 -0
  28. package/dist/src/plugin/pty/output-manager.d.ts.map +1 -0
  29. package/dist/src/plugin/pty/output-manager.js +26 -0
  30. package/dist/src/plugin/pty/output-manager.js.map +1 -0
  31. package/dist/src/plugin/pty/permissions.d.ts +27 -0
  32. package/dist/src/plugin/pty/permissions.d.ts.map +1 -0
  33. package/dist/src/plugin/pty/permissions.js +54 -0
  34. package/dist/src/plugin/pty/permissions.js.map +1 -0
  35. package/dist/src/plugin/pty/session-lifecycle.d.ts +20 -0
  36. package/dist/src/plugin/pty/session-lifecycle.d.ts.map +1 -0
  37. package/dist/src/plugin/pty/session-lifecycle.js +177 -0
  38. package/dist/src/plugin/pty/session-lifecycle.js.map +1 -0
  39. package/dist/src/plugin/pty/tools/kill.d.ts +12 -0
  40. package/dist/src/plugin/pty/tools/kill.d.ts.map +1 -0
  41. package/dist/src/plugin/pty/tools/kill.js +37 -0
  42. package/dist/src/plugin/pty/tools/kill.js.map +1 -0
  43. package/dist/src/plugin/pty/tools/kill.txt +25 -0
  44. package/dist/src/plugin/pty/tools/list.d.ts +6 -0
  45. package/dist/src/plugin/pty/tools/list.d.ts.map +1 -0
  46. package/dist/src/plugin/pty/tools/list.js +22 -0
  47. package/dist/src/plugin/pty/tools/list.js.map +1 -0
  48. package/dist/src/plugin/pty/tools/list.txt +22 -0
  49. package/dist/src/plugin/pty/tools/read.d.ts +18 -0
  50. package/dist/src/plugin/pty/tools/read.d.ts.map +1 -0
  51. package/dist/src/plugin/pty/tools/read.js +165 -0
  52. package/dist/src/plugin/pty/tools/read.js.map +1 -0
  53. package/dist/src/plugin/pty/tools/read.txt +39 -0
  54. package/dist/src/plugin/pty/tools/spawn.d.ts +24 -0
  55. package/dist/src/plugin/pty/tools/spawn.d.ts.map +1 -0
  56. package/dist/src/plugin/pty/tools/spawn.js +75 -0
  57. package/dist/src/plugin/pty/tools/spawn.js.map +1 -0
  58. package/dist/src/plugin/pty/tools/spawn.txt +52 -0
  59. package/dist/src/plugin/pty/tools/write.d.ts +12 -0
  60. package/dist/src/plugin/pty/tools/write.d.ts.map +1 -0
  61. package/dist/src/plugin/pty/tools/write.js +62 -0
  62. package/dist/src/plugin/pty/tools/write.js.map +1 -0
  63. package/dist/src/plugin/pty/tools/write.txt +28 -0
  64. package/dist/src/plugin/pty/types.d.ts +70 -0
  65. package/dist/src/plugin/pty/types.d.ts.map +1 -0
  66. package/dist/src/plugin/pty/types.js +1 -0
  67. package/dist/src/plugin/pty/types.js.map +1 -0
  68. package/dist/src/plugin/pty/utils.d.ts +12 -0
  69. package/dist/src/plugin/pty/utils.d.ts.map +1 -0
  70. package/dist/src/plugin/pty/utils.js +17 -0
  71. package/dist/src/plugin/pty/utils.js.map +1 -0
  72. package/dist/src/plugin/pty/wildcard.d.ts +7 -0
  73. package/dist/src/plugin/pty/wildcard.d.ts.map +1 -0
  74. package/dist/src/plugin/pty/wildcard.js +51 -0
  75. package/dist/src/plugin/pty/wildcard.js.map +1 -0
  76. package/dist/src/plugin/types.d.ts +5 -0
  77. package/dist/src/plugin/types.d.ts.map +1 -0
  78. package/dist/src/plugin/types.js +1 -0
  79. package/dist/src/plugin/types.js.map +1 -0
  80. package/dist/src/plugin.d.ts +3 -0
  81. package/dist/src/plugin.d.ts.map +1 -0
  82. package/dist/src/plugin.js +71 -0
  83. package/dist/src/plugin.js.map +1 -0
  84. package/dist/src/shared/constants.d.ts +5 -0
  85. package/dist/src/shared/constants.d.ts.map +1 -0
  86. package/dist/src/shared/constants.js +7 -0
  87. package/dist/src/shared/constants.js.map +1 -0
  88. package/dist/src/web/server/callback-manager.d.ts +8 -0
  89. package/dist/src/web/server/callback-manager.d.ts.map +1 -0
  90. package/dist/src/web/server/callback-manager.js +23 -0
  91. package/dist/src/web/server/callback-manager.js.map +1 -0
  92. package/dist/src/web/server/handlers/health.d.ts +3 -0
  93. package/dist/src/web/server/handlers/health.d.ts.map +1 -0
  94. package/dist/src/web/server/handlers/health.js +33 -0
  95. package/dist/src/web/server/handlers/health.js.map +1 -0
  96. package/dist/src/web/server/handlers/responses.d.ts +10 -0
  97. package/dist/src/web/server/handlers/responses.d.ts.map +1 -0
  98. package/dist/src/web/server/handlers/responses.js +26 -0
  99. package/dist/src/web/server/handlers/responses.js.map +1 -0
  100. package/dist/src/web/server/handlers/sessions.d.ts +13 -0
  101. package/dist/src/web/server/handlers/sessions.d.ts.map +1 -0
  102. package/dist/src/web/server/handlers/sessions.js +96 -0
  103. package/dist/src/web/server/handlers/sessions.js.map +1 -0
  104. package/dist/src/web/server/handlers/static.d.ts +2 -0
  105. package/dist/src/web/server/handlers/static.d.ts.map +1 -0
  106. package/dist/src/web/server/handlers/static.js +38 -0
  107. package/dist/src/web/server/handlers/static.js.map +1 -0
  108. package/dist/src/web/server/handlers/upgrade.d.ts +2 -0
  109. package/dist/src/web/server/handlers/upgrade.d.ts.map +1 -0
  110. package/dist/src/web/server/handlers/upgrade.js +11 -0
  111. package/dist/src/web/server/handlers/upgrade.js.map +1 -0
  112. package/dist/src/web/server/handlers/websocket.d.ts +3 -0
  113. package/dist/src/web/server/handlers/websocket.d.ts.map +1 -0
  114. package/dist/src/web/server/handlers/websocket.js +119 -0
  115. package/dist/src/web/server/handlers/websocket.js.map +1 -0
  116. package/dist/src/web/server/server.d.ts +12 -0
  117. package/dist/src/web/server/server.d.ts.map +1 -0
  118. package/dist/src/web/server/server.js +73 -0
  119. package/dist/src/web/server/server.js.map +1 -0
  120. package/dist/src/web/shared/api-client.d.ts +132 -0
  121. package/dist/src/web/shared/api-client.d.ts.map +1 -0
  122. package/dist/src/web/shared/api-client.js +79 -0
  123. package/dist/src/web/shared/api-client.js.map +1 -0
  124. package/dist/src/web/shared/constants.d.ts +11 -0
  125. package/dist/src/web/shared/constants.d.ts.map +1 -0
  126. package/dist/src/web/shared/constants.js +23 -0
  127. package/dist/src/web/shared/constants.js.map +1 -0
  128. package/dist/src/web/shared/route-builder.d.ts +30 -0
  129. package/dist/src/web/shared/route-builder.d.ts.map +1 -0
  130. package/dist/src/web/shared/route-builder.js +42 -0
  131. package/dist/src/web/shared/route-builder.js.map +1 -0
  132. package/dist/src/web/shared/routes.d.ts +37 -0
  133. package/dist/src/web/shared/routes.d.ts.map +1 -0
  134. package/dist/src/web/shared/routes.js +39 -0
  135. package/dist/src/web/shared/routes.js.map +1 -0
  136. package/dist/src/web/shared/types.d.ts +87 -0
  137. package/dist/src/web/shared/types.d.ts.map +1 -0
  138. package/dist/src/web/shared/types.js +15 -0
  139. package/dist/src/web/shared/types.js.map +1 -0
  140. package/dist/web/assets/index-CYWtqpTG.js +24 -0
  141. package/dist/web/assets/index-DDGTF8rc.css +1 -0
  142. package/dist/web/index.html +204 -0
  143. package/package.json +107 -0
@@ -0,0 +1,38 @@
1
+ import { readdirSync, statSync } from 'node:fs';
2
+ import { extname, join, resolve } from 'node:path';
3
+ import { ASSET_CONTENT_TYPES } from "../../shared/constants.js";
4
+ // ----- MODULE-SCOPE CONSTANTS -----
5
+ // Resolve project root regardless of whether we're running from source or dist/
6
+ const MODULE_DIR = resolve(import.meta.dir, '../../../..');
7
+ const PROJECT_ROOT = MODULE_DIR.replace(/[\\/]dist$/, '');
8
+ const SECURITY_HEADERS = {
9
+ 'X-Content-Type-Options': 'nosniff',
10
+ 'X-Frame-Options': 'DENY',
11
+ 'X-XSS-Protection': '1; mode=block',
12
+ 'Referrer-Policy': 'strict-origin-when-cross-origin',
13
+ 'Content-Security-Policy': "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';",
14
+ };
15
+ const STATIC_DIR = join(PROJECT_ROOT, 'dist/web');
16
+ export async function buildStaticRoutes() {
17
+ const routes = {};
18
+ const files = readdirSync(STATIC_DIR, { recursive: true });
19
+ for (const file of files) {
20
+ if (typeof file === 'string' && !statSync(join(STATIC_DIR, file)).isDirectory()) {
21
+ const ext = extname(file);
22
+ const routeKey = `/${file.replace(/\\/g, '/')}`; // e.g., /assets/js/bundle.js
23
+ const fullPath = join(STATIC_DIR, file);
24
+ const fileObj = Bun.file(fullPath);
25
+ const contentType = fileObj.type || ASSET_CONTENT_TYPES[ext] || 'application/octet-stream';
26
+ // Buffer all files in memory
27
+ routes[routeKey] = new Response(await fileObj.bytes(), {
28
+ headers: {
29
+ 'Content-Type': contentType,
30
+ 'Cache-Control': 'public, max-age=31536000, immutable',
31
+ ...SECURITY_HEADERS,
32
+ },
33
+ });
34
+ }
35
+ }
36
+ return routes;
37
+ }
38
+ //# sourceMappingURL=static.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static.js","sourceRoot":"","sources":["../../../../../src/web/server/handlers/static.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAE/D,qCAAqC;AACrC,gFAAgF;AAChF,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;AAC1D,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;AACzD,MAAM,gBAAgB,GAAG;IACvB,wBAAwB,EAAE,SAAS;IACnC,iBAAiB,EAAE,MAAM;IACzB,kBAAkB,EAAE,eAAe;IACnC,iBAAiB,EAAE,iCAAiC;IACpD,yBAAyB,EACvB,0FAA0F;CACpF,CAAA;AACV,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;AAEjD,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,MAAM,GAA6B,EAAE,CAAA;IAC3C,MAAM,KAAK,GAAG,WAAW,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YAChF,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;YACzB,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,6BAA6B;YAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;YACvC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAClC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,IAAI,mBAAmB,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAA;YAE1F,6BAA6B;YAC7B,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,QAAQ,CAAC,MAAM,OAAO,CAAC,KAAK,EAAE,EAAE;gBACrD,OAAO,EAAE;oBACP,cAAc,EAAE,WAAW;oBAC3B,eAAe,EAAE,qCAAqC;oBACtD,GAAG,gBAAgB;iBACpB;aACF,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function handleUpgrade(server: Bun.Server<undefined>, req: Request): Response | undefined;
2
+ //# sourceMappingURL=upgrade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../../../../src/web/server/handlers/upgrade.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,wBASxE"}
@@ -0,0 +1,11 @@
1
+ export function handleUpgrade(server, req) {
2
+ if (!(req.headers.get('upgrade') === 'websocket')) {
3
+ return new Response('WebSocket endpoint - use WebSocket upgrade', { status: 426 });
4
+ }
5
+ const success = server.upgrade(req);
6
+ if (success) {
7
+ return undefined; // Upgrade succeeded, Bun sends 101 automatically
8
+ }
9
+ return new Response('WebSocket upgrade failed', { status: 400 });
10
+ }
11
+ //# sourceMappingURL=upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../../../../src/web/server/handlers/upgrade.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa,CAAC,MAA6B,EAAE,GAAY;IACvE,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,WAAW,CAAC,EAAE,CAAC;QAClD,OAAO,IAAI,QAAQ,CAAC,4CAA4C,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IACpF,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACnC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,SAAS,CAAA,CAAC,iDAAiD;IACpE,CAAC;IACD,OAAO,IAAI,QAAQ,CAAC,0BAA0B,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;AAClE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ServerWebSocket } from 'bun';
2
+ export declare function handleWebSocketMessage(ws: ServerWebSocket<undefined>, data: string | Buffer<ArrayBuffer>): void;
3
+ //# sourceMappingURL=websocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../../../../src/web/server/handlers/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,KAAK,CAAA;AA4J1C,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,eAAe,CAAC,SAAS,CAAC,EAC9B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,GACjC,IAAI,CAGN"}
@@ -0,0 +1,119 @@
1
+ import { manager } from '../../../plugin/pty/manager';
2
+ import { CustomError, } from '../../shared/types';
3
+ class WebSocketHandler {
4
+ sendSessionList(ws) {
5
+ const sessions = manager.list();
6
+ const message = { type: 'session_list', sessions };
7
+ ws.send(JSON.stringify(message));
8
+ }
9
+ handleSubscribe(ws, message) {
10
+ const session = manager.get(message.sessionId);
11
+ if (!session) {
12
+ const error = {
13
+ type: 'error',
14
+ error: new CustomError(`Session ${message.sessionId} not found`),
15
+ };
16
+ ws.send(JSON.stringify(error));
17
+ }
18
+ else {
19
+ ws.subscribe(`session:${message.sessionId}`);
20
+ const response = {
21
+ type: 'subscribed',
22
+ sessionId: message.sessionId,
23
+ };
24
+ ws.send(JSON.stringify(response));
25
+ }
26
+ }
27
+ handleUnsubscribe(ws, message) {
28
+ const topic = `session:${message.sessionId}`;
29
+ ws.unsubscribe(topic);
30
+ const response = {
31
+ type: 'unsubscribed',
32
+ sessionId: message.sessionId,
33
+ };
34
+ ws.send(JSON.stringify(response));
35
+ }
36
+ handleSessionListRequest(ws, _message) {
37
+ this.sendSessionList(ws);
38
+ }
39
+ handleUnknownMessage(ws, message) {
40
+ const error = {
41
+ type: 'error',
42
+ error: new CustomError(`Unknown message type ${message.type}`),
43
+ };
44
+ ws.send(JSON.stringify(error));
45
+ }
46
+ handleWebSocketMessage(ws, data) {
47
+ if (typeof data !== 'string') {
48
+ const error = {
49
+ type: 'error',
50
+ error: new CustomError('Binary messages are not supported yet. File an issue.'),
51
+ };
52
+ ws.send(JSON.stringify(error));
53
+ return;
54
+ }
55
+ try {
56
+ const message = JSON.parse(data);
57
+ switch (message.type) {
58
+ case 'subscribe':
59
+ this.handleSubscribe(ws, message);
60
+ break;
61
+ case 'unsubscribe':
62
+ this.handleUnsubscribe(ws, message);
63
+ break;
64
+ case 'session_list':
65
+ this.handleSessionListRequest(ws, message);
66
+ break;
67
+ case 'spawn':
68
+ this.handleSpawn(ws, message);
69
+ break;
70
+ case 'input':
71
+ this.handleInput(message);
72
+ break;
73
+ case 'readRaw':
74
+ this.handleReadRaw(ws, message);
75
+ break;
76
+ default:
77
+ this.handleUnknownMessage(ws, message);
78
+ }
79
+ }
80
+ catch (err) {
81
+ const error = {
82
+ type: 'error',
83
+ error: new CustomError(Bun.inspect(err)),
84
+ };
85
+ ws.send(JSON.stringify(error));
86
+ }
87
+ }
88
+ handleSpawn(ws, message) {
89
+ const sessionInfo = manager.spawn(message);
90
+ if (message.subscribe) {
91
+ this.handleSubscribe(ws, { type: 'subscribe', sessionId: sessionInfo.id });
92
+ }
93
+ }
94
+ handleInput(message) {
95
+ manager.write(message.sessionId, message.data);
96
+ }
97
+ handleReadRaw(ws, message) {
98
+ const rawData = manager.getRawBuffer(message.sessionId);
99
+ if (!rawData) {
100
+ const error = {
101
+ type: 'error',
102
+ error: new CustomError(`Session ${message.sessionId} not found`),
103
+ };
104
+ ws.send(JSON.stringify(error));
105
+ return;
106
+ }
107
+ const response = {
108
+ type: 'readRawResponse',
109
+ sessionId: message.sessionId,
110
+ rawData: rawData.raw,
111
+ };
112
+ ws.send(JSON.stringify(response));
113
+ }
114
+ }
115
+ export function handleWebSocketMessage(ws, data) {
116
+ const handler = new WebSocketHandler();
117
+ handler.handleWebSocketMessage(ws, data);
118
+ }
119
+ //# sourceMappingURL=websocket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../../../../src/web/server/handlers/websocket.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Server } from 'bun';
2
+ export declare class PTYServer implements Disposable {
3
+ readonly server: Server<undefined>;
4
+ private readonly staticRoutes;
5
+ private readonly stack;
6
+ private constructor();
7
+ [Symbol.dispose](): void;
8
+ static createServer(): Promise<PTYServer>;
9
+ private startWebServer;
10
+ getWsUrl(): string;
11
+ }
12
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../src/web/server/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AAmBjC,qBAAa,SAAU,YAAW,UAAU;IAC1C,SAAgB,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAA;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;IACvD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwB;IAE9C,OAAO;IAOP,CAAC,MAAM,CAAC,OAAO,CAAC;WAII,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;IAMtD,OAAO,CAAC,cAAc;IAgDf,QAAQ,IAAI,MAAM;CAG1B"}
@@ -0,0 +1,73 @@
1
+ import { routes } from "../shared/routes.js";
2
+ import { CallbackManager } from "./callback-manager.js";
3
+ import { handleHealth } from "./handlers/health.js";
4
+ import { cleanupSession, clearSessions, createSession, getPlainBuffer, getRawBuffer, getSession, getSessions, killSession, sendInput, } from "./handlers/sessions.js";
5
+ import { buildStaticRoutes } from "./handlers/static.js";
6
+ import { handleUpgrade } from "./handlers/upgrade.js";
7
+ import { handleWebSocketMessage } from "./handlers/websocket.js";
8
+ export class PTYServer {
9
+ server;
10
+ staticRoutes;
11
+ stack = new DisposableStack();
12
+ constructor(staticRoutes) {
13
+ this.staticRoutes = staticRoutes;
14
+ this.server = this.startWebServer();
15
+ this.stack.use(this.server);
16
+ this.stack.use(new CallbackManager(this.server));
17
+ }
18
+ [Symbol.dispose]() {
19
+ this.stack.dispose();
20
+ }
21
+ static async createServer() {
22
+ const staticRoutes = await buildStaticRoutes();
23
+ return new PTYServer(staticRoutes);
24
+ }
25
+ startWebServer() {
26
+ return Bun.serve({
27
+ port: process.env.PTY_WEB_PORT ? parseInt(process.env.PTY_WEB_PORT, 10) : 0,
28
+ hostname: process.env.PTY_WEB_HOSTNAME ?? '::1',
29
+ routes: {
30
+ ...this.staticRoutes,
31
+ [routes.websocket.path]: (req) => handleUpgrade(this.server, req),
32
+ [routes.health.path]: () => handleHealth(this.server),
33
+ [routes.sessions.path]: {
34
+ GET: getSessions,
35
+ POST: createSession,
36
+ DELETE: clearSessions,
37
+ },
38
+ [routes.session.path]: {
39
+ GET: getSession,
40
+ DELETE: killSession,
41
+ },
42
+ [routes.session.cleanup.path]: {
43
+ DELETE: cleanupSession,
44
+ },
45
+ [routes.session.input.path]: {
46
+ POST: sendInput,
47
+ },
48
+ [routes.session.buffer.raw.path]: {
49
+ GET: getRawBuffer,
50
+ },
51
+ [routes.session.buffer.plain.path]: {
52
+ GET: getPlainBuffer,
53
+ },
54
+ },
55
+ websocket: {
56
+ data: undefined,
57
+ perMessageDeflate: true,
58
+ open: (ws) => ws.subscribe('sessions:update'),
59
+ message: handleWebSocketMessage,
60
+ close: (ws) => {
61
+ ws.subscriptions.forEach((topic) => {
62
+ ws.unsubscribe(topic);
63
+ });
64
+ },
65
+ },
66
+ fetch: () => new Response(null, { status: 302, headers: { Location: '/index.html' } }),
67
+ });
68
+ }
69
+ getWsUrl() {
70
+ return `${this.server.url.origin.replace(/^http/, 'ws')}${routes.websocket.path}`;
71
+ }
72
+ }
73
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../../src/web/server/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,132 @@
1
+ import type { HealthResponse, PTYSessionInfo } from 'pty-auto/web/shared/types';
2
+ type ExtractParams<T extends string> = T extends `${infer _}:${infer Param}/${infer Rest}` ? {
3
+ [K in Param | keyof ExtractParams<Rest>]: string | number;
4
+ } : T extends `${infer _}:${infer Param}` ? {
5
+ [K in Param]: string | number;
6
+ } : Record<string, never>;
7
+ type AllowedMethods<T> = T extends {
8
+ methods: readonly string[];
9
+ } ? T['methods'][number] : never;
10
+ type ApiFetchOptions<Route extends {
11
+ path: string;
12
+ methods: readonly string[];
13
+ }, Method extends AllowedMethods<Route>> = {
14
+ method: Method;
15
+ params?: ExtractParams<Route['path']>;
16
+ body?: Method extends 'POST' ? unknown : never;
17
+ baseUrl?: string;
18
+ };
19
+ export declare function apiFetch<Route extends {
20
+ path: string;
21
+ methods: readonly string[];
22
+ }, Method extends AllowedMethods<Route>>(route: Route, options: ApiFetchOptions<Route, Method>): Promise<Response>;
23
+ export declare function apiFetchJson<Route extends {
24
+ path: string;
25
+ methods: readonly string[];
26
+ }, Method extends AllowedMethods<Route>, T = unknown>(route: Route, options: ApiFetchOptions<Route, Method>): Promise<T>;
27
+ export declare function createApiClient(baseUrl: string): {
28
+ readonly sessions: {
29
+ readonly list: () => Promise<PTYSessionInfo[]>;
30
+ readonly create: (body: {
31
+ command: string;
32
+ args?: string[];
33
+ description?: string;
34
+ workdir?: string;
35
+ timeoutSeconds: number;
36
+ }) => Promise<PTYSessionInfo>;
37
+ readonly clear: () => Promise<{
38
+ success: boolean;
39
+ }>;
40
+ };
41
+ readonly session: {
42
+ readonly get: (params: {
43
+ id: string;
44
+ }) => Promise<PTYSessionInfo>;
45
+ readonly kill: (params: {
46
+ id: string;
47
+ }) => Promise<{
48
+ success: boolean;
49
+ }>;
50
+ readonly input: (params: {
51
+ id: string;
52
+ }, body: {
53
+ data: string;
54
+ }) => Promise<{
55
+ success: boolean;
56
+ }>;
57
+ readonly cleanup: (params: {
58
+ id: string;
59
+ }) => Promise<{
60
+ success: boolean;
61
+ }>;
62
+ readonly buffer: {
63
+ readonly raw: (params: {
64
+ id: string;
65
+ }) => Promise<{
66
+ raw: string;
67
+ byteLength: number;
68
+ }>;
69
+ readonly plain: (params: {
70
+ id: string;
71
+ }) => Promise<{
72
+ plain: string;
73
+ byteLength: number;
74
+ }>;
75
+ };
76
+ };
77
+ readonly health: () => Promise<HealthResponse>;
78
+ };
79
+ export declare const api: {
80
+ readonly sessions: {
81
+ readonly list: () => Promise<PTYSessionInfo[]>;
82
+ readonly create: (body: {
83
+ command: string;
84
+ args?: string[];
85
+ description?: string;
86
+ workdir?: string;
87
+ timeoutSeconds: number;
88
+ }) => Promise<PTYSessionInfo>;
89
+ readonly clear: () => Promise<{
90
+ success: boolean;
91
+ }>;
92
+ };
93
+ readonly session: {
94
+ readonly get: (params: {
95
+ id: string;
96
+ }) => Promise<PTYSessionInfo>;
97
+ readonly kill: (params: {
98
+ id: string;
99
+ }) => Promise<{
100
+ success: boolean;
101
+ }>;
102
+ readonly input: (params: {
103
+ id: string;
104
+ }, body: {
105
+ data: string;
106
+ }) => Promise<{
107
+ success: boolean;
108
+ }>;
109
+ readonly cleanup: (params: {
110
+ id: string;
111
+ }) => Promise<{
112
+ success: boolean;
113
+ }>;
114
+ readonly buffer: {
115
+ readonly raw: (params: {
116
+ id: string;
117
+ }) => Promise<{
118
+ raw: string;
119
+ byteLength: number;
120
+ }>;
121
+ readonly plain: (params: {
122
+ id: string;
123
+ }) => Promise<{
124
+ plain: string;
125
+ byteLength: number;
126
+ }>;
127
+ };
128
+ };
129
+ readonly health: () => Promise<HealthResponse>;
130
+ };
131
+ export {};
132
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../../../src/web/shared/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ // Type-safe API client for making HTTP requests with compile-time validation
2
+ // Uses the structured routes to ensure correct methods and parameters
3
+ import { routes } from './routes';
4
+ // Build URL by replacing path parameters
5
+ function buildUrl(path, params) {
6
+ if (!params)
7
+ return path;
8
+ let result = path;
9
+ for (const [key, value] of Object.entries(params)) {
10
+ result = result.replace(`:${key}`, String(value));
11
+ }
12
+ return result;
13
+ }
14
+ // Type-safe fetch function
15
+ export async function apiFetch(route, options) {
16
+ const baseUrl = options.baseUrl || `${location.protocol}//${location.host}`;
17
+ const url = baseUrl + buildUrl(route.path, options.params);
18
+ const fetchOptions = {
19
+ method: options.method,
20
+ headers: { 'Content-Type': 'application/json' },
21
+ };
22
+ if (options.body && options.method === 'POST') {
23
+ fetchOptions.body = JSON.stringify(options.body);
24
+ }
25
+ return fetch(url, fetchOptions);
26
+ }
27
+ // Type-safe JSON fetch with response parsing
28
+ export async function apiFetchJson(route, options) {
29
+ const response = await apiFetch(route, options);
30
+ if (!response.ok) {
31
+ throw new Error(`API error: ${response.status} ${response.statusText}`);
32
+ }
33
+ return response.json();
34
+ }
35
+ // Factory function to create API client with fixed baseUrl (for tests)
36
+ export function createApiClient(baseUrl) {
37
+ return {
38
+ sessions: {
39
+ list: () => apiFetchJson(routes.sessions, {
40
+ method: 'GET',
41
+ baseUrl,
42
+ }),
43
+ create: (body) => apiFetchJson(routes.sessions, {
44
+ method: 'POST',
45
+ body,
46
+ baseUrl,
47
+ }),
48
+ clear: () => apiFetchJson(routes.sessions, {
49
+ method: 'DELETE',
50
+ baseUrl,
51
+ }),
52
+ },
53
+ session: {
54
+ get: (params) => apiFetchJson(routes.session, {
55
+ method: 'GET',
56
+ params,
57
+ baseUrl,
58
+ }),
59
+ kill: (params) => apiFetchJson(routes.session, {
60
+ method: 'DELETE',
61
+ params,
62
+ baseUrl,
63
+ }),
64
+ input: (params, body) => apiFetchJson(routes.session.input, { method: 'POST', params, body, baseUrl }),
65
+ cleanup: (params) => apiFetchJson(routes.session.cleanup, { method: 'DELETE', params, baseUrl }),
66
+ buffer: {
67
+ raw: (params) => apiFetchJson(routes.session.buffer.raw, { method: 'GET', params, baseUrl }),
68
+ plain: (params) => apiFetchJson(routes.session.buffer.plain, { method: 'GET', params, baseUrl }),
69
+ },
70
+ },
71
+ health: () => apiFetchJson(routes.health, {
72
+ method: 'GET',
73
+ baseUrl,
74
+ }),
75
+ };
76
+ }
77
+ // Convenience API for browser use (auto-detects baseUrl from location)
78
+ export const api = createApiClient('');
79
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../../../src/web/shared/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export declare const WEBSOCKET_PING_INTERVAL = 30000;
2
+ export declare const WEBSOCKET_RECONNECT_DELAY = 100;
3
+ export declare const RETRY_DELAY = 500;
4
+ export declare const SESSION_LOAD_TIMEOUT = 2000;
5
+ export declare const OUTPUT_LOAD_TIMEOUT = 5000;
6
+ export declare const SKIP_AUTOSELECT_KEY = "skip-autoselect";
7
+ export declare const TEST_SERVER_PORT_BASE = 8765;
8
+ export declare const TEST_TIMEOUT_BUFFER = 1000;
9
+ export declare const TEST_SESSION_CLEANUP_DELAY = 500;
10
+ export declare const ASSET_CONTENT_TYPES: Record<string, string>;
11
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/web/shared/constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,uBAAuB,QAAQ,CAAA;AAC5C,eAAO,MAAM,yBAAyB,MAAM,CAAA;AAC5C,eAAO,MAAM,WAAW,MAAM,CAAA;AAC9B,eAAO,MAAM,oBAAoB,OAAO,CAAA;AACxC,eAAO,MAAM,mBAAmB,OAAO,CAAA;AACvC,eAAO,MAAM,mBAAmB,oBAAoB,CAAA;AAGpD,eAAO,MAAM,qBAAqB,OAAO,CAAA;AACzC,eAAO,MAAM,mBAAmB,OAAO,CAAA;AACvC,eAAO,MAAM,0BAA0B,MAAM,CAAA;AAG7C,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQtD,CAAA"}
@@ -0,0 +1,23 @@
1
+ // Web-specific constants for the web server and related components
2
+ // WebSocket and session related constants
3
+ export const WEBSOCKET_PING_INTERVAL = 30000;
4
+ export const WEBSOCKET_RECONNECT_DELAY = 100;
5
+ export const RETRY_DELAY = 500;
6
+ export const SESSION_LOAD_TIMEOUT = 2000;
7
+ export const OUTPUT_LOAD_TIMEOUT = 5000;
8
+ export const SKIP_AUTOSELECT_KEY = 'skip-autoselect';
9
+ // Test-related constants
10
+ export const TEST_SERVER_PORT_BASE = 8765;
11
+ export const TEST_TIMEOUT_BUFFER = 1000;
12
+ export const TEST_SESSION_CLEANUP_DELAY = 500;
13
+ // Asset and file serving constants
14
+ export const ASSET_CONTENT_TYPES = {
15
+ '.js': 'application/javascript',
16
+ '.css': 'text/css',
17
+ '.json': 'application/json',
18
+ '.html': 'text/html',
19
+ '.png': 'image/png',
20
+ '.jpg': 'image/jpeg',
21
+ '.svg': 'image/svg+xml',
22
+ };
23
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/web/shared/constants.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAEnE,0CAA0C;AAC1C,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAA;AAC5C,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAA;AAC5C,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAA;AAC9B,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAA;AACxC,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAA;AACvC,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAA;AAEpD,yBAAyB;AACzB,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAA;AACzC,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAA;AACvC,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAA;AAE7C,mCAAmC;AACnC,MAAM,CAAC,MAAM,mBAAmB,GAA2B;IACzD,KAAK,EAAE,wBAAwB;IAC/B,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,kBAAkB;IAC3B,OAAO,EAAE,WAAW;IACpB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,eAAe;CACxB,CAAA"}
@@ -0,0 +1,30 @@
1
+ export declare const RouteBuilder: {
2
+ websocket(): string;
3
+ health(): string;
4
+ sessions: {
5
+ list: () => string;
6
+ create: () => string;
7
+ clear: () => string;
8
+ };
9
+ session: {
10
+ get: (params: {
11
+ id: string | number;
12
+ }) => string;
13
+ kill: (params: {
14
+ id: string | number;
15
+ }) => string;
16
+ cleanup: (params: {
17
+ id: string | number;
18
+ }) => string;
19
+ input: (params: {
20
+ id: string | number;
21
+ }) => string;
22
+ rawBuffer: (params: {
23
+ id: string | number;
24
+ }) => string;
25
+ plainBuffer: (params: {
26
+ id: string | number;
27
+ }) => string;
28
+ };
29
+ };
30
+ //# sourceMappingURL=route-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-builder.d.ts","sourceRoot":"","sources":["../../../../src/web/shared/route-builder.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,YAAY;iBAEV,MAAM;cAKT,MAAM;;oBAMJ,MAAM;sBACJ,MAAM;qBACP,MAAM;;;sBAKH;YAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,KAAG,MAAM;uBAE/B;YAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,KAAG,MAAM;0BAE7B;YAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,KAAG,MAAM;wBAGlC;YAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,KAAG,MAAM;4BAE5B;YAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,KAAG,MAAM;8BAG9B;YAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,KAAG,MAAM;;CAGzD,CAAA"}
@@ -0,0 +1,42 @@
1
+ // Type-safe URL builder using constants and manual parameter validation
2
+ // Provides compile-time type checking for route parameters
3
+ // Simple URL builder that validates parameters are present
4
+ function buildUrl(template, params) {
5
+ let result = template;
6
+ const requiredParams = template.match(/:(\w+)/g)?.map((p) => p.slice(1)) || [];
7
+ for (const param of requiredParams) {
8
+ if (!(param in params)) {
9
+ throw new Error(`Missing required parameter '${param}' for route '${template}'`);
10
+ }
11
+ result = result.replace(`:${param}`, String(params[param]));
12
+ }
13
+ return result;
14
+ }
15
+ // Import route templates from shared constants
16
+ import { routes } from './routes';
17
+ export const RouteBuilder = {
18
+ // WebSocket routes
19
+ websocket() {
20
+ return routes.websocket.path;
21
+ },
22
+ // Health check routes
23
+ health() {
24
+ return routes.health.path;
25
+ },
26
+ // Session collection routes
27
+ sessions: {
28
+ list: () => routes.sessions.path,
29
+ create: () => routes.sessions.path,
30
+ clear: () => routes.sessions.path,
31
+ },
32
+ // Individual session routes with type-safe parameter building
33
+ session: {
34
+ get: (params) => buildUrl(routes.session.path, params),
35
+ kill: (params) => buildUrl(routes.session.path, params),
36
+ cleanup: (params) => buildUrl(routes.session.cleanup.path, params),
37
+ input: (params) => buildUrl(routes.session.input.path, params),
38
+ rawBuffer: (params) => buildUrl(routes.session.buffer.raw.path, params),
39
+ plainBuffer: (params) => buildUrl(routes.session.buffer.plain.path, params),
40
+ },
41
+ };
42
+ //# sourceMappingURL=route-builder.js.map