@cloudflare/sandbox 0.0.0-bb855ca → 0.0.0-c1f057e

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 (95) hide show
  1. package/CHANGELOG.md +159 -0
  2. package/Dockerfile +107 -66
  3. package/README.md +88 -710
  4. package/dist/chunk-BFVUNTP4.js +104 -0
  5. package/dist/chunk-BFVUNTP4.js.map +1 -0
  6. package/dist/chunk-EKSWCBCA.js +86 -0
  7. package/dist/chunk-EKSWCBCA.js.map +1 -0
  8. package/dist/chunk-JXZMAU2C.js +559 -0
  9. package/dist/chunk-JXZMAU2C.js.map +1 -0
  10. package/dist/chunk-KWOEDJUN.js +7 -0
  11. package/dist/chunk-KWOEDJUN.js.map +1 -0
  12. package/dist/chunk-Y52QYTSM.js +2420 -0
  13. package/dist/chunk-Y52QYTSM.js.map +1 -0
  14. package/dist/chunk-Z532A7QC.js +78 -0
  15. package/dist/chunk-Z532A7QC.js.map +1 -0
  16. package/dist/file-stream.d.ts +43 -0
  17. package/dist/file-stream.js +9 -0
  18. package/dist/file-stream.js.map +1 -0
  19. package/dist/index.d.ts +9 -0
  20. package/dist/index.js +67 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/interpreter.d.ts +33 -0
  23. package/dist/interpreter.js +8 -0
  24. package/dist/interpreter.js.map +1 -0
  25. package/dist/request-handler.d.ts +18 -0
  26. package/dist/request-handler.js +13 -0
  27. package/dist/request-handler.js.map +1 -0
  28. package/dist/sandbox-DMlNr93l.d.ts +596 -0
  29. package/dist/sandbox.d.ts +4 -0
  30. package/dist/sandbox.js +13 -0
  31. package/dist/sandbox.js.map +1 -0
  32. package/dist/security.d.ts +31 -0
  33. package/dist/security.js +13 -0
  34. package/dist/security.js.map +1 -0
  35. package/dist/sse-parser.d.ts +28 -0
  36. package/dist/sse-parser.js +11 -0
  37. package/dist/sse-parser.js.map +1 -0
  38. package/dist/version.d.ts +8 -0
  39. package/dist/version.js +7 -0
  40. package/dist/version.js.map +1 -0
  41. package/package.json +13 -5
  42. package/src/clients/base-client.ts +280 -0
  43. package/src/clients/command-client.ts +115 -0
  44. package/src/clients/file-client.ts +269 -0
  45. package/src/clients/git-client.ts +92 -0
  46. package/src/clients/index.ts +64 -0
  47. package/src/clients/interpreter-client.ts +329 -0
  48. package/src/clients/port-client.ts +105 -0
  49. package/src/clients/process-client.ts +177 -0
  50. package/src/clients/sandbox-client.ts +41 -0
  51. package/src/clients/types.ts +84 -0
  52. package/src/clients/utility-client.ts +119 -0
  53. package/src/errors/adapter.ts +180 -0
  54. package/src/errors/classes.ts +469 -0
  55. package/src/errors/index.ts +105 -0
  56. package/src/file-stream.ts +164 -0
  57. package/src/index.ts +85 -21
  58. package/src/interpreter.ts +22 -13
  59. package/src/request-handler.ts +69 -43
  60. package/src/sandbox.ts +663 -444
  61. package/src/security.ts +14 -23
  62. package/src/sse-parser.ts +4 -8
  63. package/src/version.ts +6 -0
  64. package/startup.sh +3 -0
  65. package/tests/base-client.test.ts +328 -0
  66. package/tests/command-client.test.ts +407 -0
  67. package/tests/file-client.test.ts +643 -0
  68. package/tests/file-stream.test.ts +306 -0
  69. package/tests/get-sandbox.test.ts +110 -0
  70. package/tests/git-client.test.ts +328 -0
  71. package/tests/port-client.test.ts +301 -0
  72. package/tests/process-client.test.ts +658 -0
  73. package/tests/sandbox.test.ts +465 -0
  74. package/tests/sse-parser.test.ts +290 -0
  75. package/tests/utility-client.test.ts +332 -0
  76. package/tests/version.test.ts +16 -0
  77. package/tests/wrangler.jsonc +35 -0
  78. package/tsconfig.json +9 -1
  79. package/vitest.config.ts +31 -0
  80. package/container_src/bun.lock +0 -122
  81. package/container_src/handler/exec.ts +0 -340
  82. package/container_src/handler/file.ts +0 -844
  83. package/container_src/handler/git.ts +0 -182
  84. package/container_src/handler/ports.ts +0 -314
  85. package/container_src/handler/process.ts +0 -640
  86. package/container_src/index.ts +0 -531
  87. package/container_src/jupyter-server.ts +0 -336
  88. package/container_src/mime-processor.ts +0 -255
  89. package/container_src/package.json +0 -18
  90. package/container_src/startup.sh +0 -52
  91. package/container_src/types.ts +0 -108
  92. package/src/client.ts +0 -1021
  93. package/src/interpreter-types.ts +0 -383
  94. package/src/jupyter-client.ts +0 -266
  95. package/src/types.ts +0 -401
@@ -0,0 +1,31 @@
1
+ import { defineWorkersConfig } from '@cloudflare/vitest-pool-workers/config';
2
+
3
+ /**
4
+ * Workers runtime test configuration
5
+ *
6
+ * Tests the SDK code in Cloudflare Workers environment with Durable Objects.
7
+ * Uses @cloudflare/vitest-pool-workers to run tests in workerd runtime.
8
+ *
9
+ * Run with: npm test
10
+ */
11
+ export default defineWorkersConfig({
12
+ test: {
13
+ globals: true,
14
+ include: ['tests/**/*.test.ts'],
15
+ testTimeout: 10000,
16
+ hookTimeout: 10000,
17
+ teardownTimeout: 10000,
18
+ poolOptions: {
19
+ workers: {
20
+ wrangler: {
21
+ configPath: './tests/wrangler.jsonc',
22
+ },
23
+ singleWorker: true,
24
+ isolatedStorage: false,
25
+ },
26
+ },
27
+ },
28
+ esbuild: {
29
+ target: 'esnext',
30
+ },
31
+ });
@@ -1,122 +0,0 @@
1
- {
2
- "lockfileVersion": 1,
3
- "workspaces": {
4
- "": {
5
- "name": "sandbox-server",
6
- "dependencies": {
7
- "@jupyterlab/services": "^7.0.0",
8
- "uuid": "^9.0.1",
9
- "ws": "^8.16.0",
10
- },
11
- "devDependencies": {
12
- "@types/uuid": "^9.0.7",
13
- "@types/ws": "^8.5.10",
14
- },
15
- },
16
- },
17
- "packages": {
18
- "@jupyter/ydoc": ["@jupyter/ydoc@3.1.0", "", { "dependencies": { "@jupyterlab/nbformat": "^3.0.0 || ^4.0.0-alpha.21 || ^4.0.0", "@lumino/coreutils": "^1.11.0 || ^2.0.0", "@lumino/disposable": "^1.10.0 || ^2.0.0", "@lumino/signaling": "^1.10.0 || ^2.0.0", "y-protocols": "^1.0.5", "yjs": "^13.5.40" } }, "sha512-+hLNUBZr8Zz8NiuaoYKINDURDJHbjFGxg8EcSU52y+rBe412TsoFxfPSng4eP7w3cZFrVlm7D+8K0nAMHxj0ZQ=="],
19
-
20
- "@jupyterlab/coreutils": ["@jupyterlab/coreutils@6.4.5", "", { "dependencies": { "@lumino/coreutils": "^2.2.1", "@lumino/disposable": "^2.1.4", "@lumino/signaling": "^2.1.4", "minimist": "~1.2.0", "path-browserify": "^1.0.0", "url-parse": "~1.5.4" } }, "sha512-fNEefnqTNP/3alrmGYDb0Mu1heS5Cu39FIDiDDoZuuWv4bsdE2xf7VaStuwjljsQm7VZwi5aeholi1+ciBkZKg=="],
21
-
22
- "@jupyterlab/nbformat": ["@jupyterlab/nbformat@4.4.5", "", { "dependencies": { "@lumino/coreutils": "^2.2.1" } }, "sha512-VOlm1klsb1LUNp47AL8iDZPP71pXu9a+WqukJFuuWVxg//+iR6wdqTYcunE9Lx/7SZDqMsXGD+doBZC36Lzenw=="],
23
-
24
- "@jupyterlab/services": ["@jupyterlab/services@7.4.5", "", { "dependencies": { "@jupyter/ydoc": "^3.0.4", "@jupyterlab/coreutils": "^6.4.5", "@jupyterlab/nbformat": "^4.4.5", "@jupyterlab/settingregistry": "^4.4.5", "@jupyterlab/statedb": "^4.4.5", "@lumino/coreutils": "^2.2.1", "@lumino/disposable": "^2.1.4", "@lumino/polling": "^2.1.4", "@lumino/properties": "^2.0.3", "@lumino/signaling": "^2.1.4", "ws": "^8.11.0" } }, "sha512-JEr8+4VS2MqFyYHh4AnpK/g5V0qRBpmnfXmU0p9YFjcIgGR365D8JF0880IJ0e8+jaW88gSAvZFB8x3o9xRoAQ=="],
25
-
26
- "@jupyterlab/settingregistry": ["@jupyterlab/settingregistry@4.4.5", "", { "dependencies": { "@jupyterlab/nbformat": "^4.4.5", "@jupyterlab/statedb": "^4.4.5", "@lumino/commands": "^2.3.2", "@lumino/coreutils": "^2.2.1", "@lumino/disposable": "^2.1.4", "@lumino/signaling": "^2.1.4", "@rjsf/utils": "^5.13.4", "ajv": "^8.12.0", "json5": "^2.2.3" }, "peerDependencies": { "react": ">=16" } }, "sha512-6hEBq3qI99VZwO97W0AM0mP1is57bWC8Vk2xudic1a90wA9G6ovUBzayqSMm/6QhTuIbCY+vruznwhhsLrVMeg=="],
27
-
28
- "@jupyterlab/statedb": ["@jupyterlab/statedb@4.4.5", "", { "dependencies": { "@lumino/commands": "^2.3.2", "@lumino/coreutils": "^2.2.1", "@lumino/disposable": "^2.1.4", "@lumino/properties": "^2.0.3", "@lumino/signaling": "^2.1.4" } }, "sha512-UpqhOujKwoWoxtNBL2Qk0nrw+ORLJ3ckwiJg2eA0CI+n5kO3IBYAnPzak0tSS0mQNspayXr3KAm4GQ80op5yuA=="],
29
-
30
- "@lumino/algorithm": ["@lumino/algorithm@2.0.3", "", {}, "sha512-DIcF7cIrGEC1Wh8DNjdwaL7IdcNs4Jj1VjO/90oHefeQPszKgc6DSfCxvbQiRanKR6tl/JL7tq4ZRPZES2oVAA=="],
31
-
32
- "@lumino/commands": ["@lumino/commands@2.3.2", "", { "dependencies": { "@lumino/algorithm": "^2.0.3", "@lumino/coreutils": "^2.2.1", "@lumino/disposable": "^2.1.4", "@lumino/domutils": "^2.0.3", "@lumino/keyboard": "^2.0.3", "@lumino/signaling": "^2.1.4", "@lumino/virtualdom": "^2.0.3" } }, "sha512-aAFEiUpp2hrkQU82Z85w1L80g0iDzsQRncLBa+pqVR/k0k1lz6H9F6xZ1ff+lBumZKKtsxBxNomvd0hfxLLqGw=="],
33
-
34
- "@lumino/coreutils": ["@lumino/coreutils@2.2.1", "", { "dependencies": { "@lumino/algorithm": "^2.0.3" } }, "sha512-yij4TnxDIum7xfFUsVvZB0oLv4shs2mNbn3juwtEIsruvVBPmurNzKX0Y8z2QetbP2AZ6MSFtBzEKsihf0H0VA=="],
35
-
36
- "@lumino/disposable": ["@lumino/disposable@2.1.4", "", { "dependencies": { "@lumino/signaling": "^2.1.4" } }, "sha512-qTJiDbglPE2QnG4x4gtBcRbcfKQibxyyinNGKcNDrcK2TGTbbhK5PpMQ8d70l2V2Xw2pb/LfksBAg5pxkJ/G4A=="],
37
-
38
- "@lumino/domutils": ["@lumino/domutils@2.0.3", "", {}, "sha512-bXAbZg3mf2ZDNdBBpCGDike3U+osRGHePTh8H2Ud2KwaN4g/5IryFJm/TiO4K5IYs91bWF2Zqhf3FsdbZKHlGw=="],
39
-
40
- "@lumino/keyboard": ["@lumino/keyboard@2.0.3", "", {}, "sha512-bU2OxAR8a9eNBdV0YFjU6/lVVpbOw1gM7yHOuDGDdNu4J0UpKapFoR9gopNGSaHTmTwDtx9RHdFfIAgHwjZ+VQ=="],
41
-
42
- "@lumino/polling": ["@lumino/polling@2.1.4", "", { "dependencies": { "@lumino/coreutils": "^2.2.1", "@lumino/disposable": "^2.1.4", "@lumino/signaling": "^2.1.4" } }, "sha512-gSkxlIJ/4/esY2G7bsRrY9A4KimDMHTo0shaD+MCbhd09fZMCWJoDMcA447/dykB1rM5NXgugNLjpdGGL/e8cw=="],
43
-
44
- "@lumino/properties": ["@lumino/properties@2.0.3", "", {}, "sha512-zkXIU5uYz/ScHCHGl5Bt4gMYsfPxZEduZd80zqDslBWvTIMro3NnzLe66NMnecbdr5N3hDJagYyA8//Qy3XjiA=="],
45
-
46
- "@lumino/signaling": ["@lumino/signaling@2.1.4", "", { "dependencies": { "@lumino/algorithm": "^2.0.3", "@lumino/coreutils": "^2.2.1" } }, "sha512-nC5Z6d9om369Jkh1Vp3b7C89hV4cjr1fQDVcxhemyKXwc9r6VW7FpKixC+jElcAknP5KLj1FAa8Np+K06mMkEA=="],
47
-
48
- "@lumino/virtualdom": ["@lumino/virtualdom@2.0.3", "", { "dependencies": { "@lumino/algorithm": "^2.0.3" } }, "sha512-q2C8eBxPvvOOQjN3KuxZ+vJi082JH/GF7KwMdaWsy5g+7wjKdnXPuLQFTBLOrVqIzmbxBDlLeFr93CEhdQXcyQ=="],
49
-
50
- "@rjsf/utils": ["@rjsf/utils@5.24.12", "", { "dependencies": { "json-schema-merge-allof": "^0.8.1", "jsonpointer": "^5.0.1", "lodash": "^4.17.21", "lodash-es": "^4.17.21", "react-is": "^18.2.0" }, "peerDependencies": { "react": "^16.14.0 || >=17" } }, "sha512-fDwQB0XkjZjpdFUz5UAnuZj8nnbxDbX5tp+jTOjjJKw2TMQ9gFFYCQ12lSpdhezA2YgEGZfxyYTGW0DKDL5Drg=="],
51
-
52
- "@types/node": ["@types/node@24.1.0", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w=="],
53
-
54
- "@types/uuid": ["@types/uuid@9.0.8", "", {}, "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA=="],
55
-
56
- "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
57
-
58
- "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
59
-
60
- "compute-gcd": ["compute-gcd@1.2.1", "", { "dependencies": { "validate.io-array": "^1.0.3", "validate.io-function": "^1.0.2", "validate.io-integer-array": "^1.0.0" } }, "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg=="],
61
-
62
- "compute-lcm": ["compute-lcm@1.1.2", "", { "dependencies": { "compute-gcd": "^1.2.1", "validate.io-array": "^1.0.3", "validate.io-function": "^1.0.2", "validate.io-integer-array": "^1.0.0" } }, "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ=="],
63
-
64
- "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
65
-
66
- "fast-uri": ["fast-uri@3.0.6", "", {}, "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw=="],
67
-
68
- "isomorphic.js": ["isomorphic.js@0.2.5", "", {}, "sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw=="],
69
-
70
- "json-schema-compare": ["json-schema-compare@0.2.2", "", { "dependencies": { "lodash": "^4.17.4" } }, "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ=="],
71
-
72
- "json-schema-merge-allof": ["json-schema-merge-allof@0.8.1", "", { "dependencies": { "compute-lcm": "^1.1.2", "json-schema-compare": "^0.2.2", "lodash": "^4.17.20" } }, "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w=="],
73
-
74
- "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
75
-
76
- "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
77
-
78
- "jsonpointer": ["jsonpointer@5.0.1", "", {}, "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ=="],
79
-
80
- "lib0": ["lib0@0.2.114", "", { "dependencies": { "isomorphic.js": "^0.2.4" }, "bin": { "0gentesthtml": "bin/gentesthtml.js", "0serve": "bin/0serve.js", "0ecdsa-generate-keypair": "bin/0ecdsa-generate-keypair.js" } }, "sha512-gcxmNFzA4hv8UYi8j43uPlQ7CGcyMJ2KQb5kZASw6SnAKAf10hK12i2fjrS3Cl/ugZa5Ui6WwIu1/6MIXiHttQ=="],
81
-
82
- "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
83
-
84
- "lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="],
85
-
86
- "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
87
-
88
- "path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="],
89
-
90
- "querystringify": ["querystringify@2.2.0", "", {}, "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="],
91
-
92
- "react": ["react@19.1.1", "", {}, "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="],
93
-
94
- "react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
95
-
96
- "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
97
-
98
- "requires-port": ["requires-port@1.0.0", "", {}, "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="],
99
-
100
- "undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
101
-
102
- "url-parse": ["url-parse@1.5.10", "", { "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" } }, "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ=="],
103
-
104
- "uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="],
105
-
106
- "validate.io-array": ["validate.io-array@1.0.6", "", {}, "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg=="],
107
-
108
- "validate.io-function": ["validate.io-function@1.0.2", "", {}, "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ=="],
109
-
110
- "validate.io-integer": ["validate.io-integer@1.0.5", "", { "dependencies": { "validate.io-number": "^1.0.3" } }, "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ=="],
111
-
112
- "validate.io-integer-array": ["validate.io-integer-array@1.0.0", "", { "dependencies": { "validate.io-array": "^1.0.3", "validate.io-integer": "^1.0.4" } }, "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA=="],
113
-
114
- "validate.io-number": ["validate.io-number@1.0.3", "", {}, "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg=="],
115
-
116
- "ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
117
-
118
- "y-protocols": ["y-protocols@1.0.6", "", { "dependencies": { "lib0": "^0.2.85" }, "peerDependencies": { "yjs": "^13.0.0" } }, "sha512-vHRF2L6iT3rwj1jub/K5tYcTT/mEYDUppgNPXwp8fmLpui9f7Yeq3OEtTLVF012j39QnV+KEQpNqoN7CWU7Y9Q=="],
119
-
120
- "yjs": ["yjs@13.6.27", "", { "dependencies": { "lib0": "^0.2.99" } }, "sha512-OIDwaflOaq4wC6YlPBy2L6ceKeKuF7DeTxx+jPzv1FHn9tCZ0ZwSRnUBxD05E3yed46fv/FWJbvR+Ud7x0L7zw=="],
121
- }
122
- }
@@ -1,340 +0,0 @@
1
- import { type SpawnOptions, spawn } from "node:child_process";
2
- import type { ExecuteOptions, ExecuteRequest, SessionData } from "../types";
3
-
4
- function executeCommand(
5
- sessions: Map<string, SessionData>,
6
- command: string,
7
- options: ExecuteOptions,
8
- ): Promise<{
9
- success: boolean;
10
- stdout: string;
11
- stderr: string;
12
- exitCode: number;
13
- }> {
14
- return new Promise((resolve, reject) => {
15
- const spawnOptions: SpawnOptions = {
16
- shell: true,
17
- stdio: ["pipe", "pipe", "pipe"] as const,
18
- detached: options.background || false,
19
- cwd: options.cwd || "/workspace", // Default to clean /workspace directory
20
- env: options.env ? { ...process.env, ...options.env } : process.env
21
- };
22
-
23
- const child = spawn(command, spawnOptions);
24
-
25
- // Store the process reference for cleanup if sessionId is provided
26
- if (options.sessionId && sessions.has(options.sessionId)) {
27
- const session = sessions.get(options.sessionId)!;
28
- session.activeProcess = child;
29
- }
30
-
31
- let stdout = "";
32
- let stderr = "";
33
-
34
- child.stdout?.on("data", (data) => {
35
- stdout += data.toString();
36
- });
37
-
38
- child.stderr?.on("data", (data) => {
39
- stderr += data.toString();
40
- });
41
-
42
- if (options.background) {
43
- // For background processes, unref and return quickly
44
- child.unref();
45
-
46
- // Collect initial output for 100ms then return
47
- setTimeout(() => {
48
- resolve({
49
- exitCode: 0, // Process is still running
50
- stderr,
51
- stdout,
52
- success: true,
53
- });
54
- }, 100);
55
-
56
- // Still handle errors
57
- child.on("error", (error) => {
58
- console.error(`[Server] Background process error: ${command}`, error);
59
- // Don't reject since we might have already resolved
60
- });
61
- } else {
62
- // Normal synchronous execution
63
- child.on("close", (code) => {
64
- // Clear the active process reference
65
- if (options.sessionId && sessions.has(options.sessionId)) {
66
- const session = sessions.get(options.sessionId)!;
67
- session.activeProcess = null;
68
- }
69
-
70
- console.log(`[Server] Command completed: ${command}, Exit code: ${code}`);
71
-
72
- resolve({
73
- exitCode: code || 0,
74
- stderr,
75
- stdout,
76
- success: code === 0,
77
- });
78
- });
79
-
80
- child.on("error", (error) => {
81
- // Clear the active process reference
82
- if (options.sessionId && sessions.has(options.sessionId)) {
83
- const session = sessions.get(options.sessionId)!;
84
- session.activeProcess = null;
85
- }
86
-
87
- reject(error);
88
- });
89
- }
90
- });
91
- }
92
-
93
- export async function handleExecuteRequest(
94
- sessions: Map<string, SessionData>,
95
- req: Request,
96
- corsHeaders: Record<string, string>
97
- ): Promise<Response> {
98
- try {
99
- const body = (await req.json()) as ExecuteRequest;
100
- const { command, sessionId, background, cwd, env } = body;
101
-
102
- if (!command || typeof command !== "string") {
103
- return new Response(
104
- JSON.stringify({
105
- error: "Command is required and must be a string",
106
- }),
107
- {
108
- headers: {
109
- "Content-Type": "application/json",
110
- ...corsHeaders,
111
- },
112
- status: 400,
113
- }
114
- );
115
- }
116
-
117
- console.log(`[Server] Executing command: ${command}`);
118
-
119
- const result = await executeCommand(sessions, command, { sessionId, background, cwd, env });
120
-
121
- return new Response(
122
- JSON.stringify({
123
- command,
124
- exitCode: result.exitCode,
125
- stderr: result.stderr,
126
- stdout: result.stdout,
127
- success: result.success,
128
- timestamp: new Date().toISOString(),
129
- }),
130
- {
131
- headers: {
132
- "Content-Type": "application/json",
133
- ...corsHeaders,
134
- },
135
- }
136
- );
137
- } catch (error) {
138
- console.error("[Server] Error in handleExecuteRequest:", error);
139
- return new Response(
140
- JSON.stringify({
141
- error: "Failed to execute command",
142
- message: error instanceof Error ? error.message : "Unknown error",
143
- }),
144
- {
145
- headers: {
146
- "Content-Type": "application/json",
147
- ...corsHeaders,
148
- },
149
- status: 500,
150
- }
151
- );
152
- }
153
- }
154
-
155
- export async function handleStreamingExecuteRequest(
156
- sessions: Map<string, SessionData>,
157
- req: Request,
158
- corsHeaders: Record<string, string>
159
- ): Promise<Response> {
160
- try {
161
- const body = (await req.json()) as ExecuteRequest;
162
- const { command, sessionId, background, cwd, env } = body;
163
-
164
- if (!command || typeof command !== "string") {
165
- return new Response(
166
- JSON.stringify({
167
- error: "Command is required and must be a string",
168
- }),
169
- {
170
- headers: {
171
- "Content-Type": "application/json",
172
- ...corsHeaders,
173
- },
174
- status: 400,
175
- }
176
- );
177
- }
178
-
179
- console.log(
180
- `[Server] Executing streaming command: ${command}`
181
- );
182
-
183
- const stream = new ReadableStream({
184
- start(controller) {
185
- const spawnOptions: SpawnOptions = {
186
- shell: true,
187
- stdio: ["pipe", "pipe", "pipe"] as const,
188
- detached: background || false,
189
- cwd: cwd || "/workspace", // Default to clean /workspace directory
190
- env: env ? { ...process.env, ...env } : process.env
191
- };
192
-
193
- const child = spawn(command, spawnOptions);
194
-
195
- // Store the process reference for cleanup if sessionId is provided
196
- if (sessionId && sessions.has(sessionId)) {
197
- const session = sessions.get(sessionId)!;
198
- session.activeProcess = child;
199
- }
200
-
201
- // For background processes, unref to prevent blocking
202
- if (background) {
203
- child.unref();
204
- }
205
-
206
- let stdout = "";
207
- let stderr = "";
208
-
209
- // Send command start event
210
- controller.enqueue(
211
- new TextEncoder().encode(
212
- `data: ${JSON.stringify({
213
- type: "start",
214
- timestamp: new Date().toISOString(),
215
- command,
216
- background: background || false,
217
- })}\n\n`
218
- )
219
- );
220
-
221
- child.stdout?.on("data", (data) => {
222
- const output = data.toString();
223
- stdout += output;
224
-
225
- // Send real-time output
226
- controller.enqueue(
227
- new TextEncoder().encode(
228
- `data: ${JSON.stringify({
229
- type: "stdout",
230
- timestamp: new Date().toISOString(),
231
- data: output,
232
- command,
233
- })}\n\n`
234
- )
235
- );
236
- });
237
-
238
- child.stderr?.on("data", (data) => {
239
- const output = data.toString();
240
- stderr += output;
241
-
242
- // Send real-time error output
243
- controller.enqueue(
244
- new TextEncoder().encode(
245
- `data: ${JSON.stringify({
246
- type: "stderr",
247
- timestamp: new Date().toISOString(),
248
- data: output,
249
- command,
250
- })}\n\n`
251
- )
252
- );
253
- });
254
-
255
- child.on("close", (code) => {
256
- // Clear the active process reference
257
- if (sessionId && sessions.has(sessionId)) {
258
- const session = sessions.get(sessionId)!;
259
- session.activeProcess = null;
260
- }
261
-
262
- console.log(
263
- `[Server] Command completed: ${command}, Exit code: ${code}`
264
- );
265
-
266
- // Send command completion event
267
- controller.enqueue(
268
- new TextEncoder().encode(
269
- `data: ${JSON.stringify({
270
- type: "complete",
271
- timestamp: new Date().toISOString(),
272
- command,
273
- exitCode: code,
274
- result: {
275
- success: code === 0,
276
- exitCode: code,
277
- stdout,
278
- stderr,
279
- command,
280
- timestamp: new Date().toISOString(),
281
- },
282
- })}\n\n`
283
- )
284
- );
285
-
286
- // For non-background processes, close the stream
287
- // For background processes with streaming, the stream stays open
288
- if (!background) {
289
- controller.close();
290
- }
291
- });
292
-
293
- child.on("error", (error) => {
294
- // Clear the active process reference
295
- if (sessionId && sessions.has(sessionId)) {
296
- const session = sessions.get(sessionId)!;
297
- session.activeProcess = null;
298
- }
299
-
300
- controller.enqueue(
301
- new TextEncoder().encode(
302
- `data: ${JSON.stringify({
303
- type: "error",
304
- timestamp: new Date().toISOString(),
305
- error: error.message,
306
- command,
307
- })}\n\n`
308
- )
309
- );
310
-
311
- controller.close();
312
- });
313
- },
314
- });
315
-
316
- return new Response(stream, {
317
- headers: {
318
- "Cache-Control": "no-cache",
319
- Connection: "keep-alive",
320
- "Content-Type": "text/event-stream",
321
- ...corsHeaders,
322
- },
323
- });
324
- } catch (error) {
325
- console.error("[Server] Error in handleStreamingExecuteRequest:", error);
326
- return new Response(
327
- JSON.stringify({
328
- error: "Failed to execute streaming command",
329
- message: error instanceof Error ? error.message : "Unknown error",
330
- }),
331
- {
332
- headers: {
333
- "Content-Type": "application/json",
334
- ...corsHeaders,
335
- },
336
- status: 500,
337
- }
338
- );
339
- }
340
- }