@veris-ai/daytona-opencode 0.1.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 (106) hide show
  1. package/.opencode/plugin/daytona/core/logger.d.ts +15 -0
  2. package/.opencode/plugin/daytona/core/logger.js +65 -0
  3. package/.opencode/plugin/daytona/core/logger.js.map +1 -0
  4. package/.opencode/plugin/daytona/core/logger.ts +71 -0
  5. package/.opencode/plugin/daytona/core/project-data-storage.d.ts +63 -0
  6. package/.opencode/plugin/daytona/core/project-data-storage.js +213 -0
  7. package/.opencode/plugin/daytona/core/project-data-storage.js.map +1 -0
  8. package/.opencode/plugin/daytona/core/project-data-storage.ts +234 -0
  9. package/.opencode/plugin/daytona/core/session-manager.d.ts +74 -0
  10. package/.opencode/plugin/daytona/core/session-manager.js +441 -0
  11. package/.opencode/plugin/daytona/core/session-manager.js.map +1 -0
  12. package/.opencode/plugin/daytona/core/session-manager.ts +471 -0
  13. package/.opencode/plugin/daytona/core/toast.d.ts +47 -0
  14. package/.opencode/plugin/daytona/core/toast.js +70 -0
  15. package/.opencode/plugin/daytona/core/toast.js.map +1 -0
  16. package/.opencode/plugin/daytona/core/toast.ts +96 -0
  17. package/.opencode/plugin/daytona/core/types.d.ts +53 -0
  18. package/.opencode/plugin/daytona/core/types.js +12 -0
  19. package/.opencode/plugin/daytona/core/types.js.map +1 -0
  20. package/.opencode/plugin/daytona/core/types.ts +72 -0
  21. package/.opencode/plugin/daytona/git/host-git-manager.d.ts +58 -0
  22. package/.opencode/plugin/daytona/git/host-git-manager.js +342 -0
  23. package/.opencode/plugin/daytona/git/host-git-manager.js.map +1 -0
  24. package/.opencode/plugin/daytona/git/host-git-manager.ts +372 -0
  25. package/.opencode/plugin/daytona/git/index.d.ts +5 -0
  26. package/.opencode/plugin/daytona/git/index.js +6 -0
  27. package/.opencode/plugin/daytona/git/index.js.map +1 -0
  28. package/.opencode/plugin/daytona/git/index.ts +6 -0
  29. package/.opencode/plugin/daytona/git/sandbox-git-manager.d.ts +22 -0
  30. package/.opencode/plugin/daytona/git/sandbox-git-manager.js +80 -0
  31. package/.opencode/plugin/daytona/git/sandbox-git-manager.js.map +1 -0
  32. package/.opencode/plugin/daytona/git/sandbox-git-manager.ts +92 -0
  33. package/.opencode/plugin/daytona/git/session-git-manager.d.ts +54 -0
  34. package/.opencode/plugin/daytona/git/session-git-manager.js +184 -0
  35. package/.opencode/plugin/daytona/git/session-git-manager.js.map +1 -0
  36. package/.opencode/plugin/daytona/git/session-git-manager.ts +203 -0
  37. package/.opencode/plugin/daytona/index.d.ts +125 -0
  38. package/.opencode/plugin/daytona/index.js +60 -0
  39. package/.opencode/plugin/daytona/index.js.map +1 -0
  40. package/.opencode/plugin/daytona/index.ts +73 -0
  41. package/.opencode/plugin/daytona/plugins/custom-tools.d.ts +122 -0
  42. package/.opencode/plugin/daytona/plugins/custom-tools.js +18 -0
  43. package/.opencode/plugin/daytona/plugins/custom-tools.js.map +1 -0
  44. package/.opencode/plugin/daytona/plugins/custom-tools.ts +21 -0
  45. package/.opencode/plugin/daytona/plugins/session-events.d.ts +10 -0
  46. package/.opencode/plugin/daytona/plugins/session-events.js +63 -0
  47. package/.opencode/plugin/daytona/plugins/session-events.js.map +1 -0
  48. package/.opencode/plugin/daytona/plugins/session-events.ts +61 -0
  49. package/.opencode/plugin/daytona/plugins/system-transform.d.ts +10 -0
  50. package/.opencode/plugin/daytona/plugins/system-transform.js +38 -0
  51. package/.opencode/plugin/daytona/plugins/system-transform.js.map +1 -0
  52. package/.opencode/plugin/daytona/plugins/system-transform.ts +43 -0
  53. package/.opencode/plugin/daytona/tools/bash.d.ts +19 -0
  54. package/.opencode/plugin/daytona/tools/bash.js +42 -0
  55. package/.opencode/plugin/daytona/tools/bash.js.map +1 -0
  56. package/.opencode/plugin/daytona/tools/bash.ts +51 -0
  57. package/.opencode/plugin/daytona/tools/edit.d.ts +21 -0
  58. package/.opencode/plugin/daytona/tools/edit.js +33 -0
  59. package/.opencode/plugin/daytona/tools/edit.js.map +1 -0
  60. package/.opencode/plugin/daytona/tools/edit.ts +44 -0
  61. package/.opencode/plugin/daytona/tools/get-preview-url.d.ts +17 -0
  62. package/.opencode/plugin/daytona/tools/get-preview-url.js +17 -0
  63. package/.opencode/plugin/daytona/tools/get-preview-url.js.map +1 -0
  64. package/.opencode/plugin/daytona/tools/get-preview-url.ts +26 -0
  65. package/.opencode/plugin/daytona/tools/git-sync.d.ts +12 -0
  66. package/.opencode/plugin/daytona/tools/git-sync.js +26 -0
  67. package/.opencode/plugin/daytona/tools/git-sync.js.map +1 -0
  68. package/.opencode/plugin/daytona/tools/git-sync.ts +36 -0
  69. package/.opencode/plugin/daytona/tools/glob.d.ts +17 -0
  70. package/.opencode/plugin/daytona/tools/glob.js +21 -0
  71. package/.opencode/plugin/daytona/tools/glob.js.map +1 -0
  72. package/.opencode/plugin/daytona/tools/glob.ts +30 -0
  73. package/.opencode/plugin/daytona/tools/grep.d.ts +17 -0
  74. package/.opencode/plugin/daytona/tools/grep.js +29 -0
  75. package/.opencode/plugin/daytona/tools/grep.js.map +1 -0
  76. package/.opencode/plugin/daytona/tools/grep.ts +39 -0
  77. package/.opencode/plugin/daytona/tools/ls.d.ts +17 -0
  78. package/.opencode/plugin/daytona/tools/ls.js +22 -0
  79. package/.opencode/plugin/daytona/tools/ls.js.map +1 -0
  80. package/.opencode/plugin/daytona/tools/ls.ts +32 -0
  81. package/.opencode/plugin/daytona/tools/multiedit.d.ts +25 -0
  82. package/.opencode/plugin/daytona/tools/multiedit.js +37 -0
  83. package/.opencode/plugin/daytona/tools/multiedit.js.map +1 -0
  84. package/.opencode/plugin/daytona/tools/multiedit.ts +54 -0
  85. package/.opencode/plugin/daytona/tools/read.d.ts +17 -0
  86. package/.opencode/plugin/daytona/tools/read.js +18 -0
  87. package/.opencode/plugin/daytona/tools/read.js.map +1 -0
  88. package/.opencode/plugin/daytona/tools/read.ts +27 -0
  89. package/.opencode/plugin/daytona/tools/veris-receipt.d.ts +26 -0
  90. package/.opencode/plugin/daytona/tools/veris-receipt.js +76 -0
  91. package/.opencode/plugin/daytona/tools/veris-receipt.js.map +1 -0
  92. package/.opencode/plugin/daytona/tools/veris-receipt.ts +103 -0
  93. package/.opencode/plugin/daytona/tools/write.d.ts +19 -0
  94. package/.opencode/plugin/daytona/tools/write.js +18 -0
  95. package/.opencode/plugin/daytona/tools/write.js.map +1 -0
  96. package/.opencode/plugin/daytona/tools/write.ts +27 -0
  97. package/.opencode/plugin/daytona/tools.d.ts +119 -0
  98. package/.opencode/plugin/daytona/tools.js +35 -0
  99. package/.opencode/plugin/daytona/tools.js.map +1 -0
  100. package/.opencode/plugin/daytona/tools.ts +45 -0
  101. package/.opencode/plugin/index.d.ts +9 -0
  102. package/.opencode/plugin/index.js +10 -0
  103. package/.opencode/plugin/index.js.map +1 -0
  104. package/.opencode/plugin/index.ts +11 -0
  105. package/README.md +87 -0
  106. package/package.json +52 -0
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Copyright Veris AI
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ *
5
+ * The eleventh tool, and the only one this fork adds.
6
+ *
7
+ * Every other tool tells the agent what its own code did. This one tells it
8
+ * what the VENDOR received — read from the twin, not from the sandbox — which
9
+ * is the only way to tell a real integration from a plausible-looking one. An
10
+ * agent that says "I called the Stripe API and it worked" and an agent that
11
+ * fabricated the response produce identical transcripts; they produce different
12
+ * receipts.
13
+ */
14
+ import { z } from 'zod';
15
+ import { isVerisSandbox } from '@veris-ai/daytona';
16
+ export const verisReceiptTool = (sessionManager, projectId, worktree, pluginCtx) => ({
17
+ description: 'Read the Veris receipt: what the vendor twin ACTUALLY received from this sandbox. ' +
18
+ 'Use it after any change that is supposed to reach an external API, and before ' +
19
+ 'reporting that the change works. A green run with an empty receipt means the code ' +
20
+ 'never reached the dependency — the two are indistinguishable from inside the sandbox. ' +
21
+ 'Pass a service name to see that service alone.',
22
+ args: {
23
+ service: z
24
+ .string()
25
+ .optional()
26
+ .describe('Service name (e.g. "stripe"). Omit for every service on the twin.'),
27
+ },
28
+ async execute(args, ctx) {
29
+ const sandbox = await sessionManager.getSandbox(ctx.sessionID, projectId, worktree, pluginCtx);
30
+ // Without this OpenCode renders the call as "verisReceipt Unknown".
31
+ const title = (t) => ctx.metadata({ title: t });
32
+ if (!isVerisSandbox(sandbox)) {
33
+ title('no twin attached');
34
+ return ('No Veris twin is attached to this sandbox, so there is no receipt to read.\n' +
35
+ 'Set VERIS_API_KEY and VERIS_ENVIRONMENT_ID and start a new session to get one.');
36
+ }
37
+ if (args.service) {
38
+ const entry = await sandbox.veris.receipt(args.service);
39
+ title(`${args.service}: ${entry.requests} request(s)`);
40
+ if (entry.requests === 0) {
41
+ return (`Receipt for '${args.service}': ZERO requests.\n\n` +
42
+ `The twin was reachable and answered nothing — the code under test never called it. ` +
43
+ `Do not report this change as working.`);
44
+ }
45
+ const lines = entry.entries
46
+ .slice(0, 50)
47
+ .map((r) => ` ${r.method} ${r.path} -> ${r.status ?? 'no response (fault)'}`);
48
+ return (`Receipt for '${args.service}': ${entry.requests} request(s).\n` +
49
+ `${lines.join('\n')}${entry.entries.length > 50 ? `\n … ${entry.entries.length - 50} more` : ''}`);
50
+ }
51
+ const receipt = await sandbox.veris.receipt();
52
+ const names = Object.keys(receipt.services);
53
+ const total = names.reduce((n, k) => n + (receipt.services[k]?.requests ?? 0), 0);
54
+ title(`${total} request(s) across ${names.length} service(s)`);
55
+ const header = `Veris receipt — twin ${sandbox.verisSandboxId}\n` +
56
+ ` interception: ${receipt.mode} integrity: ${receipt.integrity}\n` +
57
+ (receipt.leaks.length ? ` blind spots: ${receipt.leaks.join(', ')}\n` : '');
58
+ if (total === 0) {
59
+ return (header +
60
+ `\nZERO requests reached the twin, across ${names.length || 'no'} service(s).\n\n` +
61
+ `Whatever just ran did not touch its external dependencies. If you were asked to ` +
62
+ `make an integration work, it does not work yet — say so rather than reporting success.`);
63
+ }
64
+ const body = names
65
+ .map((name) => {
66
+ const e = receipt.services[name];
67
+ const calls = e.entries
68
+ .slice(0, 20)
69
+ .map((r) => ` ${r.method} ${r.path} -> ${r.status ?? 'no response (fault)'}`);
70
+ return ` ${name}: ${e.requests} request(s)\n${calls.join('\n')}`;
71
+ })
72
+ .join('\n');
73
+ return `${header}\n${total} request(s) reached the twin:\n${body}`;
74
+ },
75
+ });
76
+ //# sourceMappingURL=veris-receipt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"veris-receipt.js","sourceRoot":"","sources":["veris-receipt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Copyright Veris AI
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ *
5
+ * The eleventh tool, and the only one this fork adds.
6
+ *
7
+ * Every other tool tells the agent what its own code did. This one tells it
8
+ * what the VENDOR received — read from the twin, not from the sandbox — which
9
+ * is the only way to tell a real integration from a plausible-looking one. An
10
+ * agent that says "I called the Stripe API and it worked" and an agent that
11
+ * fabricated the response produce identical transcripts; they produce different
12
+ * receipts.
13
+ */
14
+
15
+ import { z } from 'zod'
16
+ import type { PluginInput } from '@opencode-ai/plugin'
17
+ import type { ToolContext } from '@opencode-ai/plugin/tool'
18
+ import { isVerisSandbox } from '@veris-ai/daytona'
19
+ import type { DaytonaSessionManager } from '../core/session-manager'
20
+
21
+ export const verisReceiptTool = (
22
+ sessionManager: DaytonaSessionManager,
23
+ projectId: string,
24
+ worktree: string,
25
+ pluginCtx: PluginInput,
26
+ ) => ({
27
+ description:
28
+ 'Read the Veris receipt: what the vendor twin ACTUALLY received from this sandbox. ' +
29
+ 'Use it after any change that is supposed to reach an external API, and before ' +
30
+ 'reporting that the change works. A green run with an empty receipt means the code ' +
31
+ 'never reached the dependency — the two are indistinguishable from inside the sandbox. ' +
32
+ 'Pass a service name to see that service alone.',
33
+ args: {
34
+ service: z
35
+ .string()
36
+ .optional()
37
+ .describe('Service name (e.g. "stripe"). Omit for every service on the twin.'),
38
+ },
39
+ async execute(args: { service?: string }, ctx: ToolContext) {
40
+ const sandbox = await sessionManager.getSandbox(ctx.sessionID, projectId, worktree, pluginCtx)
41
+
42
+ // Without this OpenCode renders the call as "verisReceipt Unknown".
43
+ const title = (t: string) => ctx.metadata({ title: t })
44
+
45
+ if (!isVerisSandbox(sandbox)) {
46
+ title('no twin attached')
47
+ return (
48
+ 'No Veris twin is attached to this sandbox, so there is no receipt to read.\n' +
49
+ 'Set VERIS_API_KEY and VERIS_ENVIRONMENT_ID and start a new session to get one.'
50
+ )
51
+ }
52
+
53
+ if (args.service) {
54
+ const entry = await sandbox.veris.receipt(args.service)
55
+ title(`${args.service}: ${entry.requests} request(s)`)
56
+ if (entry.requests === 0) {
57
+ return (
58
+ `Receipt for '${args.service}': ZERO requests.\n\n` +
59
+ `The twin was reachable and answered nothing — the code under test never called it. ` +
60
+ `Do not report this change as working.`
61
+ )
62
+ }
63
+ const lines = entry.entries
64
+ .slice(0, 50)
65
+ .map((r) => ` ${r.method} ${r.path} -> ${r.status ?? 'no response (fault)'}`)
66
+ return (
67
+ `Receipt for '${args.service}': ${entry.requests} request(s).\n` +
68
+ `${lines.join('\n')}${entry.entries.length > 50 ? `\n … ${entry.entries.length - 50} more` : ''}`
69
+ )
70
+ }
71
+
72
+ const receipt = await sandbox.veris.receipt()
73
+ const names = Object.keys(receipt.services)
74
+ const total = names.reduce((n, k) => n + (receipt.services[k]?.requests ?? 0), 0)
75
+ title(`${total} request(s) across ${names.length} service(s)`)
76
+
77
+ const header =
78
+ `Veris receipt — twin ${sandbox.verisSandboxId}\n` +
79
+ ` interception: ${receipt.mode} integrity: ${receipt.integrity}\n` +
80
+ (receipt.leaks.length ? ` blind spots: ${receipt.leaks.join(', ')}\n` : '')
81
+
82
+ if (total === 0) {
83
+ return (
84
+ header +
85
+ `\nZERO requests reached the twin, across ${names.length || 'no'} service(s).\n\n` +
86
+ `Whatever just ran did not touch its external dependencies. If you were asked to ` +
87
+ `make an integration work, it does not work yet — say so rather than reporting success.`
88
+ )
89
+ }
90
+
91
+ const body = names
92
+ .map((name) => {
93
+ const e = receipt.services[name]!
94
+ const calls = e.entries
95
+ .slice(0, 20)
96
+ .map((r) => ` ${r.method} ${r.path} -> ${r.status ?? 'no response (fault)'}`)
97
+ return ` ${name}: ${e.requests} request(s)\n${calls.join('\n')}`
98
+ })
99
+ .join('\n')
100
+
101
+ return `${header}\n${total} request(s) reached the twin:\n${body}`
102
+ },
103
+ })
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { z } from 'zod';
6
+ import type { PluginInput } from '@opencode-ai/plugin';
7
+ import type { ToolContext } from '@opencode-ai/plugin/tool';
8
+ import type { DaytonaSessionManager } from '../core/session-manager';
9
+ export declare const writeTool: (sessionManager: DaytonaSessionManager, projectId: string, worktree: string, pluginCtx: PluginInput) => {
10
+ description: string;
11
+ args: {
12
+ filePath: z.ZodString;
13
+ content: z.ZodString;
14
+ };
15
+ execute(args: {
16
+ filePath: string;
17
+ content: string;
18
+ }, ctx: ToolContext): Promise<string>;
19
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { z } from 'zod';
6
+ export const writeTool = (sessionManager, projectId, worktree, pluginCtx) => ({
7
+ description: 'Writes content to file in Daytona sandbox',
8
+ args: {
9
+ filePath: z.string(),
10
+ content: z.string(),
11
+ },
12
+ async execute(args, ctx) {
13
+ const sandbox = await sessionManager.getSandbox(ctx.sessionID, projectId, worktree, pluginCtx);
14
+ await sandbox.fs.uploadFile(Buffer.from(args.content), args.filePath);
15
+ return `Written ${Buffer.byteLength(args.content, 'utf8')} bytes to ${args.filePath}`;
16
+ },
17
+ });
18
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["write.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,cAAqC,EACrC,SAAiB,EACjB,QAAgB,EAChB,SAAsB,EACtB,EAAE,CAAC,CAAC;IACJ,WAAW,EAAE,2CAA2C;IACxD,IAAI,EAAE;QACJ,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;QACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;KACpB;IACD,KAAK,CAAC,OAAO,CAAC,IAA2C,EAAE,GAAgB;QACzE,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;QAC9F,MAAM,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;QACrE,OAAO,WAAW,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,aAAa,IAAI,CAAC,QAAQ,EAAE,CAAA;IACvF,CAAC;CACF,CAAC,CAAA"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import { z } from 'zod'
7
+ import type { PluginInput } from '@opencode-ai/plugin'
8
+ import type { ToolContext } from '@opencode-ai/plugin/tool'
9
+ import type { DaytonaSessionManager } from '../core/session-manager'
10
+
11
+ export const writeTool = (
12
+ sessionManager: DaytonaSessionManager,
13
+ projectId: string,
14
+ worktree: string,
15
+ pluginCtx: PluginInput,
16
+ ) => ({
17
+ description: 'Writes content to file in Daytona sandbox',
18
+ args: {
19
+ filePath: z.string(),
20
+ content: z.string(),
21
+ },
22
+ async execute(args: { filePath: string; content: string }, ctx: ToolContext) {
23
+ const sandbox = await sessionManager.getSandbox(ctx.sessionID, projectId, worktree, pluginCtx)
24
+ await sandbox.fs.uploadFile(Buffer.from(args.content), args.filePath)
25
+ return `Written ${Buffer.byteLength(args.content, 'utf8')} bytes to ${args.filePath}`
26
+ },
27
+ })
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import type { DaytonaSessionManager } from './core/session-manager';
6
+ import type { PluginInput } from '@opencode-ai/plugin';
7
+ export declare function createDaytonaTools(sessionManager: DaytonaSessionManager, projectId: string, worktree: string, pluginCtx: PluginInput): {
8
+ bash: {
9
+ description: string;
10
+ args: {
11
+ command: import("zod").ZodString;
12
+ background: import("zod").ZodOptional<import("zod").ZodBoolean>;
13
+ };
14
+ execute(args: {
15
+ command: string;
16
+ background?: boolean;
17
+ }, ctx: import("@opencode-ai/plugin").ToolContext): Promise<string>;
18
+ };
19
+ read: {
20
+ description: string;
21
+ args: {
22
+ filePath: import("zod").ZodString;
23
+ };
24
+ execute(args: {
25
+ filePath: string;
26
+ }, ctx: import("@opencode-ai/plugin").ToolContext): Promise<string>;
27
+ };
28
+ write: {
29
+ description: string;
30
+ args: {
31
+ filePath: import("zod").ZodString;
32
+ content: import("zod").ZodString;
33
+ };
34
+ execute(args: {
35
+ filePath: string;
36
+ content: string;
37
+ }, ctx: import("@opencode-ai/plugin").ToolContext): Promise<string>;
38
+ };
39
+ edit: {
40
+ description: string;
41
+ args: {
42
+ filePath: import("zod").ZodString;
43
+ oldString: import("zod").ZodString;
44
+ newString: import("zod").ZodString;
45
+ };
46
+ execute(args: {
47
+ filePath: string;
48
+ oldString: string;
49
+ newString: string;
50
+ }, ctx: import("@opencode-ai/plugin").ToolContext): Promise<string>;
51
+ };
52
+ multiedit: {
53
+ description: string;
54
+ args: {
55
+ filePath: import("zod").ZodString;
56
+ edits: import("zod").ZodArray<import("zod").ZodObject<{
57
+ oldString: import("zod").ZodString;
58
+ newString: import("zod").ZodString;
59
+ }, import("zod/v4/core").$strip>>;
60
+ };
61
+ execute(args: {
62
+ filePath: string;
63
+ edits: Array<{
64
+ oldString: string;
65
+ newString: string;
66
+ }>;
67
+ }, ctx: import("@opencode-ai/plugin").ToolContext): Promise<string>;
68
+ };
69
+ ls: {
70
+ description: string;
71
+ args: {
72
+ dirPath: import("zod").ZodOptional<import("zod").ZodString>;
73
+ };
74
+ execute(args: {
75
+ dirPath?: string;
76
+ }, ctx: import("@opencode-ai/plugin").ToolContext): Promise<string>;
77
+ };
78
+ glob: {
79
+ description: string;
80
+ args: {
81
+ pattern: import("zod").ZodString;
82
+ };
83
+ execute(args: {
84
+ pattern: string;
85
+ }, ctx: import("@opencode-ai/plugin").ToolContext): Promise<string>;
86
+ };
87
+ grep: {
88
+ description: string;
89
+ args: {
90
+ pattern: import("zod").ZodString;
91
+ };
92
+ execute(args: {
93
+ pattern: string;
94
+ }, ctx: import("@opencode-ai/plugin").ToolContext): Promise<string>;
95
+ };
96
+ getPreviewURL: {
97
+ description: string;
98
+ args: {
99
+ port: import("zod").ZodNumber;
100
+ };
101
+ execute(args: {
102
+ port: number;
103
+ }, ctx: import("@opencode-ai/plugin").ToolContext): Promise<string>;
104
+ };
105
+ gitSync: {
106
+ description: string;
107
+ args: {};
108
+ execute(_args: {}, ctx: import("@opencode-ai/plugin").ToolContext): Promise<string>;
109
+ };
110
+ verisReceipt: {
111
+ description: string;
112
+ args: {
113
+ service: import("zod").ZodOptional<import("zod").ZodString>;
114
+ };
115
+ execute(args: {
116
+ service?: string;
117
+ }, ctx: import("@opencode-ai/plugin").ToolContext): Promise<string>;
118
+ };
119
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ /**
6
+ * Tool implementations for Daytona sandbox integration
7
+ */
8
+ import { bashTool } from './tools/bash';
9
+ import { readTool } from './tools/read';
10
+ import { writeTool } from './tools/write';
11
+ import { editTool } from './tools/edit';
12
+ import { multieditTool } from './tools/multiedit';
13
+ import { lsTool } from './tools/ls';
14
+ import { globTool } from './tools/glob';
15
+ import { grepTool } from './tools/grep';
16
+ import { getPreviewURLTool } from './tools/get-preview-url';
17
+ import { gitSyncTool } from './tools/git-sync';
18
+ import { verisReceiptTool } from './tools/veris-receipt';
19
+ export function createDaytonaTools(sessionManager, projectId, worktree, pluginCtx) {
20
+ const repoPath = sessionManager.repoPath;
21
+ return {
22
+ bash: bashTool(sessionManager, projectId, worktree, pluginCtx, repoPath),
23
+ read: readTool(sessionManager, projectId, worktree, pluginCtx),
24
+ write: writeTool(sessionManager, projectId, worktree, pluginCtx),
25
+ edit: editTool(sessionManager, projectId, worktree, pluginCtx),
26
+ multiedit: multieditTool(sessionManager, projectId, worktree, pluginCtx),
27
+ ls: lsTool(sessionManager, projectId, worktree, pluginCtx),
28
+ glob: globTool(sessionManager, projectId, worktree, pluginCtx),
29
+ grep: grepTool(sessionManager, projectId, worktree, pluginCtx),
30
+ getPreviewURL: getPreviewURLTool(sessionManager, projectId, worktree, pluginCtx),
31
+ gitSync: gitSyncTool(sessionManager, projectId, worktree, pluginCtx),
32
+ verisReceipt: verisReceiptTool(sessionManager, projectId, worktree, pluginCtx),
33
+ };
34
+ }
35
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["tools.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAKxD,MAAM,UAAU,kBAAkB,CAChC,cAAqC,EACrC,SAAiB,EACjB,QAAgB,EAChB,SAAsB;IAEtB,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAA;IACxC,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;QACxE,IAAI,EAAE,QAAQ,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;QAC9D,KAAK,EAAE,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;QAChE,IAAI,EAAE,QAAQ,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;QAC9D,SAAS,EAAE,aAAa,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;QACxE,EAAE,EAAE,MAAM,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;QAC1D,IAAI,EAAE,QAAQ,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;QAC9D,IAAI,EAAE,QAAQ,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;QAC9D,aAAa,EAAE,iBAAiB,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;QAChF,OAAO,EAAE,WAAW,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;QACpE,YAAY,EAAE,gBAAgB,CAAC,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;KAC/E,CAAA;AACH,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ /**
7
+ * Tool implementations for Daytona sandbox integration
8
+ */
9
+
10
+ import { bashTool } from './tools/bash'
11
+ import { readTool } from './tools/read'
12
+ import { writeTool } from './tools/write'
13
+ import { editTool } from './tools/edit'
14
+ import { multieditTool } from './tools/multiedit'
15
+ import { lsTool } from './tools/ls'
16
+ import { globTool } from './tools/glob'
17
+ import { grepTool } from './tools/grep'
18
+ import { getPreviewURLTool } from './tools/get-preview-url'
19
+ import { gitSyncTool } from './tools/git-sync'
20
+ import { verisReceiptTool } from './tools/veris-receipt'
21
+
22
+ import type { DaytonaSessionManager } from './core/session-manager'
23
+ import type { PluginInput } from '@opencode-ai/plugin'
24
+
25
+ export function createDaytonaTools(
26
+ sessionManager: DaytonaSessionManager,
27
+ projectId: string,
28
+ worktree: string,
29
+ pluginCtx: PluginInput,
30
+ ) {
31
+ const repoPath = sessionManager.repoPath
32
+ return {
33
+ bash: bashTool(sessionManager, projectId, worktree, pluginCtx, repoPath),
34
+ read: readTool(sessionManager, projectId, worktree, pluginCtx),
35
+ write: writeTool(sessionManager, projectId, worktree, pluginCtx),
36
+ edit: editTool(sessionManager, projectId, worktree, pluginCtx),
37
+ multiedit: multieditTool(sessionManager, projectId, worktree, pluginCtx),
38
+ ls: lsTool(sessionManager, projectId, worktree, pluginCtx),
39
+ glob: globTool(sessionManager, projectId, worktree, pluginCtx),
40
+ grep: grepTool(sessionManager, projectId, worktree, pluginCtx),
41
+ getPreviewURL: getPreviewURLTool(sessionManager, projectId, worktree, pluginCtx),
42
+ gitSync: gitSyncTool(sessionManager, projectId, worktree, pluginCtx),
43
+ verisReceipt: verisReceiptTool(sessionManager, projectId, worktree, pluginCtx),
44
+ }
45
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ /**
6
+ * Main entry point for the OpenCode Daytona plugin.
7
+ * Re-exports the default plugin from daytona.
8
+ */
9
+ export { default } from './daytona/index';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ /**
6
+ * Main entry point for the OpenCode Daytona plugin.
7
+ * Re-exports the default plugin from daytona.
8
+ */
9
+ export { default } from './daytona/index';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ /**
7
+ * Main entry point for the OpenCode Daytona plugin.
8
+ * Re-exports the default plugin from daytona.
9
+ */
10
+
11
+ export { default } from './daytona/index'
package/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # @veris-ai/daytona-opencode
2
+
3
+ An [OpenCode](https://opencode.ai) plugin. Every session runs in a
4
+ [Daytona](https://daytona.io) sandbox whose calls to `api.stripe.com` and the
5
+ rest of your vendor stack are answered by **Veris twins** — stateful,
6
+ contract-accurate fakes — and the agent gets a tool that shows what the vendor
7
+ actually received.
8
+
9
+ ## Install
10
+
11
+ ```jsonc
12
+ // opencode.json
13
+ { "plugin": ["@veris-ai/daytona-opencode"] }
14
+ ```
15
+
16
+ | variable | where from |
17
+ |---|---|
18
+ | `DAYTONA_API_KEY` | [app.daytona.io/dashboard/keys](https://app.daytona.io/dashboard/keys) |
19
+ | `VERIS_API_KEY` | [studio.veris.ai](https://studio.veris.ai) |
20
+ | `VERIS_ENVIRONMENT_ID` | a Veris environment — it decides which vendor services your twin gets |
21
+
22
+ Then `opencode`. No image to build, no network configuration, nothing to start.
23
+
24
+ ## What the agent gets
25
+
26
+ The ten sandbox-backed tools from [`@daytona/opencode`](https://www.npmjs.com/package/@daytona/opencode)
27
+ — bash, read, write, edit, multiedit, ls, glob, grep, getPreviewURL, gitSync —
28
+ plus one.
29
+
30
+ **`verisReceipt`** reports what the twin *received*.
31
+
32
+ ```
33
+ Veris receipt — twin sbx_a1b2c3
34
+ interception: gateway integrity: verified
35
+
36
+ 1 request(s) reached the twin:
37
+ stripe: 1 request(s)
38
+ POST /v1/charges -> 200
39
+ ```
40
+
41
+ This is the tool that separates a real integration from a plausible-looking one.
42
+ Ask an agent to call the Stripe API and it will report success whether or not it
43
+ made the call — the transcripts are identical. The receipts are not:
44
+
45
+ ```
46
+ Receipt for 'stripe': ZERO requests.
47
+
48
+ The twin was reachable and answered nothing — the code under test never called
49
+ it. Do not report this change as working.
50
+ ```
51
+
52
+ The system prompt tells the agent to check it before claiming an integration
53
+ works. You can also just ask for it.
54
+
55
+ ## Why the sandbox cannot reach the real vendor
56
+
57
+ The sandbox is created with a `domainAllowList` — the vendor hostnames the twin
58
+ answers for, the Veris gateway, the twin's data planes, and package registries —
59
+ and an `outboundProxyUrl` pointing at the gateway. Daytona drops anything not on
60
+ the list and forwards the rest to the gateway, which answers vendor hostnames
61
+ from the twin. `npm install` still works; `api.stripe.com` reaches your twin.
62
+
63
+ Everything above happens inside `@veris-ai/daytona`, which this plugin uses in
64
+ place of `@daytona/sdk`. See [its README](https://www.npmjs.com/package/@veris-ai/daytona)
65
+ if you want the same thing without an agent.
66
+
67
+ ## Relationship to `@daytona/opencode`
68
+
69
+ This is a fork of `@daytona/opencode` 0.192.0 (Apache-2.0, Copyright Daytona
70
+ Platforms Inc.), and a deliberately small one: one changed import, one added
71
+ tool, one paragraph in the system prompt, and a check that the Veris
72
+ coordinates are set. The ten inherited tools, the git-sync flow and the session
73
+ bookkeeping are untouched, so upstream changes stay easy to take.
74
+
75
+ ## Limitations
76
+
77
+ - **Requires a Veris control plane that serves an HTTP CONNECT gateway.**
78
+ Without one, the first tool call fails saying exactly that.
79
+ - **Git sync into the sandbox can fail with `Host key verification failed`.**
80
+ Inherited from upstream; the agent works, but local changes are not pushed
81
+ into the sandbox. Setting `DAYTONA_SSH_KNOWN_HOSTS` is the likely fix.
82
+ - **QUIC/HTTP3 and ECH are not intercepted.** Both are reported in the receipt's
83
+ `leaks` rather than silently omitted.
84
+
85
+ ## License
86
+
87
+ Apache-2.0. Source: [veris-ai/veris-daytona](https://github.com/veris-ai/veris-daytona).
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@veris-ai/daytona-opencode",
3
+ "version": "0.1.0",
4
+ "description": "Run every OpenCode session in a Daytona sandbox whose vendor API calls are answered by a Veris twin. One line in opencode.json: unmodified code, real hostnames, and a receipt of what the vendor actually received.",
5
+ "main": "./.opencode/plugin/index.js",
6
+ "types": "./.opencode/plugin/index.d.ts",
7
+ "files": [
8
+ ".opencode",
9
+ "README.md"
10
+ ],
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/veris-ai/veris-daytona.git",
14
+ "directory": "daytona-opencode"
15
+ },
16
+ "author": "Veris (https://veris.ai)",
17
+ "license": "Apache-2.0",
18
+ "bugs": {
19
+ "url": "https://github.com/veris-ai/veris-daytona/issues"
20
+ },
21
+ "homepage": "https://github.com/veris-ai/veris-daytona/tree/main/daytona-opencode#readme",
22
+ "keywords": [
23
+ "opencode",
24
+ "opencode-plugin",
25
+ "veris",
26
+ "daytona",
27
+ "sandbox",
28
+ "integration-testing"
29
+ ],
30
+ "engines": {
31
+ "opencode": ">=1.16 <2"
32
+ },
33
+ "scripts": {
34
+ "build": "tsc",
35
+ "typecheck": "tsc --noEmit",
36
+ "prepublishOnly": "npm run build"
37
+ },
38
+ "dependencies": {
39
+ "@veris-ai/daytona": "^0.1.0",
40
+ "@daytona/sdk": "^0.204.1",
41
+ "@opencode-ai/plugin": "1.1.59",
42
+ "xdg-basedir": "^5.1.0",
43
+ "zod": "^4.2.1"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^22",
47
+ "typescript": "^5.6.0"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ }
52
+ }