@tickernelz/paperclip-pro-plugin-daytona 2026.925.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 (58) hide show
  1. package/README.md +49 -0
  2. package/dist/duplex-command-stream.d.ts +97 -0
  3. package/dist/duplex-command-stream.d.ts.map +1 -0
  4. package/dist/duplex-command-stream.js +205 -0
  5. package/dist/duplex-command-stream.js.map +1 -0
  6. package/dist/duplex-command-stream.live.test.d.ts +2 -0
  7. package/dist/duplex-command-stream.live.test.d.ts.map +1 -0
  8. package/dist/duplex-command-stream.live.test.js +324 -0
  9. package/dist/duplex-command-stream.live.test.js.map +1 -0
  10. package/dist/duplex-command-stream.test.d.ts +2 -0
  11. package/dist/duplex-command-stream.test.d.ts.map +1 -0
  12. package/dist/duplex-command-stream.test.js +519 -0
  13. package/dist/duplex-command-stream.test.js.map +1 -0
  14. package/dist/file-sync.d.ts +77 -0
  15. package/dist/file-sync.d.ts.map +1 -0
  16. package/dist/file-sync.js +1055 -0
  17. package/dist/file-sync.js.map +1 -0
  18. package/dist/file-sync.test.d.ts +2 -0
  19. package/dist/file-sync.test.d.ts.map +1 -0
  20. package/dist/file-sync.test.js +974 -0
  21. package/dist/file-sync.test.js.map +1 -0
  22. package/dist/index.d.ts +3 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +3 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/login-pty.d.ts +162 -0
  27. package/dist/login-pty.d.ts.map +1 -0
  28. package/dist/login-pty.js +258 -0
  29. package/dist/login-pty.js.map +1 -0
  30. package/dist/login-pty.test.d.ts +2 -0
  31. package/dist/login-pty.test.d.ts.map +1 -0
  32. package/dist/login-pty.test.js +319 -0
  33. package/dist/login-pty.test.js.map +1 -0
  34. package/dist/manifest.d.ts +4 -0
  35. package/dist/manifest.d.ts.map +1 -0
  36. package/dist/manifest.js +179 -0
  37. package/dist/manifest.js.map +1 -0
  38. package/dist/plugin.d.ts +49 -0
  39. package/dist/plugin.d.ts.map +1 -0
  40. package/dist/plugin.js +2563 -0
  41. package/dist/plugin.js.map +1 -0
  42. package/dist/plugin.test.d.ts +2 -0
  43. package/dist/plugin.test.d.ts.map +1 -0
  44. package/dist/plugin.test.js +4701 -0
  45. package/dist/plugin.test.js.map +1 -0
  46. package/dist/pty-chunked-input.d.ts +48 -0
  47. package/dist/pty-chunked-input.d.ts.map +1 -0
  48. package/dist/pty-chunked-input.js +74 -0
  49. package/dist/pty-chunked-input.js.map +1 -0
  50. package/dist/pty-chunked-input.test.d.ts +2 -0
  51. package/dist/pty-chunked-input.test.d.ts.map +1 -0
  52. package/dist/pty-chunked-input.test.js +115 -0
  53. package/dist/pty-chunked-input.test.js.map +1 -0
  54. package/dist/worker.d.ts +3 -0
  55. package/dist/worker.d.ts.map +1 -0
  56. package/dist/worker.js +5 -0
  57. package/dist/worker.js.map +1 -0
  58. package/package.json +44 -0
@@ -0,0 +1,115 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { PTY_INPUT_CHUNK_BYTES, PTY_MESSAGE_CAP_BYTES, sendPtyInputInChunks, } from "./pty-chunked-input.js";
3
+ /**
4
+ * A fake `sendInput`. It records each raw byte chunk, so a test asserts the chunk
5
+ * count, the chunk sizes, and the rejoined bytes. It copies each chunk, because
6
+ * the chunker passes a `subarray` view of one shared byte array.
7
+ */
8
+ function createByteRecorder() {
9
+ const chunks = [];
10
+ return {
11
+ chunks,
12
+ async sendInput(chunk) {
13
+ chunks.push(Uint8Array.from(chunk));
14
+ },
15
+ };
16
+ }
17
+ /** Concatenate the recorded chunks into one byte array. */
18
+ function concatChunks(chunks) {
19
+ const total = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
20
+ const joined = new Uint8Array(total);
21
+ let offset = 0;
22
+ for (const chunk of chunks) {
23
+ joined.set(chunk, offset);
24
+ offset += chunk.length;
25
+ }
26
+ return joined;
27
+ }
28
+ describe("sendPtyInputInChunks", () => {
29
+ it("sends a payload below the cap as exactly one send", async () => {
30
+ const recorder = createByteRecorder();
31
+ await sendPtyInputInChunks(recorder.sendInput, "a small frame\n");
32
+ expect(recorder.chunks).toHaveLength(1);
33
+ expect(recorder.chunks[0]?.length).toBeLessThanOrEqual(PTY_MESSAGE_CAP_BYTES);
34
+ });
35
+ it("splits a payload above the cap into more than one send, each at or below the cap", async () => {
36
+ const recorder = createByteRecorder();
37
+ // A fixed payload well above the provider message cap. It stays fixed, so a
38
+ // raised chunk size above this size makes the payload one send and fails this
39
+ // test.
40
+ const payload = new Uint8Array(150_416).fill(65);
41
+ await sendPtyInputInChunks(recorder.sendInput, payload);
42
+ expect(recorder.chunks.length).toBeGreaterThan(1);
43
+ for (const chunk of recorder.chunks) {
44
+ expect(chunk.length).toBeLessThanOrEqual(PTY_INPUT_CHUNK_BYTES);
45
+ expect(chunk.length).toBeLessThanOrEqual(PTY_MESSAGE_CAP_BYTES);
46
+ }
47
+ expect(concatChunks(recorder.chunks)).toEqual(payload);
48
+ });
49
+ it("slices a multi-byte character across a boundary by bytes and rejoins it", async () => {
50
+ const recorder = createByteRecorder();
51
+ // A fixed payload: one 1-byte "x", then the 3-byte character "€" repeated. It
52
+ // stays fixed, so a raised chunk size above this size makes the payload one
53
+ // send and fails this test. The chunk size is a multiple of 3, so a pure "€"
54
+ // run would put every boundary on a character edge. The 1-byte prefix shifts
55
+ // the "€" run by one byte, so the first chunk boundary lands inside one "€"
56
+ // sequence.
57
+ const text = `x${"€".repeat(30_000)}`;
58
+ const inputBytes = new TextEncoder().encode(text);
59
+ expect(inputBytes.length).toBe(90_001);
60
+ await sendPtyInputInChunks(recorder.sendInput, text);
61
+ expect(recorder.chunks.length).toBeGreaterThan(1);
62
+ // The first chunk holds exactly the byte cap and ends inside a "€" sequence,
63
+ // because the 1-byte prefix shifts the 3-byte run off the cap boundary. A
64
+ // character-index slice could never end mid-sequence, so the slice is by bytes.
65
+ expect(recorder.chunks[0]?.length).toBe(PTY_INPUT_CHUNK_BYTES);
66
+ // The rejoined bytes equal the input bytes, so a split multi-byte sequence is
67
+ // whole again. A streaming decoder on the read side then decodes it.
68
+ const joined = concatChunks(recorder.chunks);
69
+ expect(joined).toEqual(inputBytes);
70
+ expect(new TextDecoder("utf-8").decode(joined)).toBe(text);
71
+ });
72
+ it("resolves each send before it starts the next send", async () => {
73
+ let active = 0;
74
+ let maxActive = 0;
75
+ const sendCount = { value: 0 };
76
+ // A `sendInput` that stays active across a microtask. The awaited loop starts
77
+ // the next send only after the previous send resolves, so at most one send is
78
+ // active at a time. A synchronous burst would start every send at once.
79
+ const sendInput = async () => {
80
+ active += 1;
81
+ maxActive = Math.max(maxActive, active);
82
+ await Promise.resolve();
83
+ sendCount.value += 1;
84
+ active -= 1;
85
+ };
86
+ // Three chunks of the byte cap plus a short tail.
87
+ const payload = new Uint8Array(PTY_INPUT_CHUNK_BYTES * 3 + 10).fill(65);
88
+ await sendPtyInputInChunks(sendInput, payload);
89
+ expect(sendCount.value).toBe(4);
90
+ expect(maxActive).toBe(1);
91
+ });
92
+ it("stops sending later chunks after a chunk rejects", async () => {
93
+ const chunks = [];
94
+ let errorCount = 0;
95
+ // A `sendInput` that records the chunk, then rejects on a later microtask. The
96
+ // rejection is asynchronous, so a synchronous burst could not stop the later
97
+ // sends. The awaited loop learns the rejection before the next send, so it
98
+ // sends one chunk only.
99
+ const sendInput = async (chunk) => {
100
+ chunks.push(chunk);
101
+ await Promise.resolve();
102
+ throw new Error("RAW-PROVIDER-BROKEN-PIPE");
103
+ };
104
+ // A payload above the cap, so the chunker would fire more than one chunk with
105
+ // no fail-fast. The loop stops after the first rejected chunk.
106
+ await sendPtyInputInChunks(sendInput, new Uint8Array(150_416).fill(65), () => {
107
+ errorCount += 1;
108
+ });
109
+ // The loop sent one chunk, learned the rejection, and started no later send.
110
+ expect(chunks).toHaveLength(1);
111
+ // The error handler ran one time for the whole payload.
112
+ expect(errorCount).toBe(1);
113
+ });
114
+ });
115
+ //# sourceMappingURL=pty-chunked-input.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pty-chunked-input.test.js","sourceRoot":"","sources":["../src/pty-chunked-input.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import plugin from "./plugin.js";
2
+ export default plugin;
3
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,eAAe,MAAM,CAAC"}
package/dist/worker.js ADDED
@@ -0,0 +1,5 @@
1
+ import { runWorker } from "@tickernelz/paperclip-pro-plugin-sdk";
2
+ import plugin from "./plugin.js";
3
+ export default plugin;
4
+ runWorker(plugin, import.meta.url);
5
+ //# sourceMappingURL=worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,eAAe,MAAM,CAAC;AACtB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@tickernelz/paperclip-pro-plugin-daytona",
3
+ "version": "2026.925.0",
4
+ "description": "Daytona sandbox provider plugin for Paperclip environments",
5
+ "license": "MIT",
6
+ "homepage": "https://github.com/tickernelz/paperclip-pro",
7
+ "bugs": {
8
+ "url": "https://github.com/tickernelz/paperclip-pro/issues"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/tickernelz/paperclip-pro",
13
+ "directory": "packages/plugins/sandbox-providers/daytona"
14
+ },
15
+ "type": "module",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js"
20
+ }
21
+ },
22
+ "main": "./dist/index.js",
23
+ "types": "./dist/index.d.ts",
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "paperclipPlugin": {
31
+ "manifest": "./dist/manifest.js",
32
+ "worker": "./dist/worker.js"
33
+ },
34
+ "keywords": [
35
+ "paperclip",
36
+ "plugin",
37
+ "sandbox",
38
+ "daytona"
39
+ ],
40
+ "dependencies": {
41
+ "@daytonaio/sdk": "0.203.0",
42
+ "@tickernelz/paperclip-pro-plugin-sdk": "2026.925.0"
43
+ }
44
+ }