@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,53 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ /**
6
+ * Type definitions and constants for the Daytona OpenCode plugin
7
+ */
8
+ import type { Sandbox } from '@daytona/sdk';
9
+ export type EventSessionDeleted = {
10
+ type: 'session.deleted';
11
+ properties: {
12
+ info: {
13
+ id: string;
14
+ };
15
+ };
16
+ };
17
+ export type EventSessionIdle = {
18
+ type: 'session.idle';
19
+ properties: {
20
+ sessionID: string;
21
+ };
22
+ };
23
+ export type ExperimentalChatSystemTransformInput = {
24
+ sessionID?: string;
25
+ model: any;
26
+ };
27
+ export type ExperimentalChatSystemTransformOutput = {
28
+ system: string[];
29
+ };
30
+ export declare const EVENT_TYPE_SESSION_DELETED = "session.deleted";
31
+ export declare const EVENT_TYPE_SESSION_IDLE = "session.idle";
32
+ export type LogLevel = 'INFO' | 'ERROR' | 'WARN';
33
+ export type SandboxInfo = {
34
+ id: string;
35
+ };
36
+ export type SessionInfo = {
37
+ sandboxId: string;
38
+ /**
39
+ * Only set when the local worktree is a git repo (used to create opencode/N branches/remotes).
40
+ */
41
+ branchNumber?: number;
42
+ created: number;
43
+ lastAccessed: number;
44
+ };
45
+ export type ProjectSessionData = {
46
+ projectId: string;
47
+ worktree: string;
48
+ sessions: Record<string, SessionInfo>;
49
+ };
50
+ export type SessionSandboxMap = Map<string, Sandbox | SandboxInfo>;
51
+ export declare const LOG_LEVEL_INFO: LogLevel;
52
+ export declare const LOG_LEVEL_ERROR: LogLevel;
53
+ export declare const LOG_LEVEL_WARN: LogLevel;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ // OpenCode constants
6
+ export const EVENT_TYPE_SESSION_DELETED = 'session.deleted';
7
+ export const EVENT_TYPE_SESSION_IDLE = 'session.idle';
8
+ // Daytona plugin constants
9
+ export const LOG_LEVEL_INFO = 'INFO';
10
+ export const LOG_LEVEL_ERROR = 'ERROR';
11
+ export const LOG_LEVEL_WARN = 'WARN';
12
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiCH,qBAAqB;AAErB,MAAM,CAAC,MAAM,0BAA0B,GAAG,iBAAiB,CAAA;AAC3D,MAAM,CAAC,MAAM,uBAAuB,GAAG,cAAc,CAAA;AA4BrD,2BAA2B;AAE3B,MAAM,CAAC,MAAM,cAAc,GAAa,MAAM,CAAA;AAC9C,MAAM,CAAC,MAAM,eAAe,GAAa,OAAO,CAAA;AAChD,MAAM,CAAC,MAAM,cAAc,GAAa,MAAM,CAAA"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ /**
7
+ * Type definitions and constants for the Daytona OpenCode plugin
8
+ */
9
+
10
+ import type { Sandbox } from '@daytona/sdk'
11
+
12
+ // OpenCode Types
13
+
14
+ export type EventSessionDeleted = {
15
+ type: 'session.deleted'
16
+ properties: {
17
+ info: { id: string }
18
+ }
19
+ }
20
+
21
+ export type EventSessionIdle = {
22
+ type: 'session.idle'
23
+ properties: {
24
+ sessionID: string
25
+ }
26
+ }
27
+
28
+ export type ExperimentalChatSystemTransformInput = {
29
+ sessionID?: string
30
+ model: any
31
+ }
32
+
33
+ export type ExperimentalChatSystemTransformOutput = {
34
+ system: string[]
35
+ }
36
+
37
+ // OpenCode constants
38
+
39
+ export const EVENT_TYPE_SESSION_DELETED = 'session.deleted'
40
+ export const EVENT_TYPE_SESSION_IDLE = 'session.idle'
41
+
42
+ // Daytona plugin types
43
+
44
+ export type LogLevel = 'INFO' | 'ERROR' | 'WARN'
45
+
46
+ export type SandboxInfo = {
47
+ id: string
48
+ }
49
+
50
+ export type SessionInfo = {
51
+ sandboxId: string
52
+ /**
53
+ * Only set when the local worktree is a git repo (used to create opencode/N branches/remotes).
54
+ */
55
+ branchNumber?: number
56
+ created: number
57
+ lastAccessed: number
58
+ }
59
+
60
+ export type ProjectSessionData = {
61
+ projectId: string
62
+ worktree: string
63
+ sessions: Record<string, SessionInfo>
64
+ }
65
+
66
+ export type SessionSandboxMap = Map<string, Sandbox | SandboxInfo>
67
+
68
+ // Daytona plugin constants
69
+
70
+ export const LOG_LEVEL_INFO: LogLevel = 'INFO'
71
+ export const LOG_LEVEL_ERROR: LogLevel = 'ERROR'
72
+ export const LOG_LEVEL_WARN: LogLevel = 'WARN'
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ export declare class HostGitManager {
6
+ private static operationQueues;
7
+ private static queueKeyCache;
8
+ /**
9
+ * Resolve the serialization key for a worktree: the CANONICAL absolute path of its
10
+ * shared git dir (common across linked worktrees of the same repo). Canonicalizing
11
+ * with realpath collapses symlinked aliases onto the same key, so two callers
12
+ * reaching the same repo via different symlink paths still share a queue and can't
13
+ * race on `.git/config`. Falls back to (canonical) cwd if git can't identify a repo.
14
+ */
15
+ private static queueKeyFor;
16
+ /**
17
+ * Chain `fn` onto the queue for the repo containing `cwd`. The stored promise is
18
+ * always-resolves so a failure doesn't poison the chain; callers still see errors via
19
+ * `await` on the returned promise. Cleared from the map when the tail settles to avoid
20
+ * leaking entries for repos that are no longer active.
21
+ */
22
+ private static enqueue;
23
+ /** Cached OID of an empty commit used to reserve branch refs (branches must point at commits, not blobs). */
24
+ private emptyCommitOidCache;
25
+ /**
26
+ * Checks if a git repository exists in the current directory
27
+ * @returns true if a git repo exists, false otherwise
28
+ */
29
+ hasRepo(cwd?: string): boolean;
30
+ /**
31
+ * Allocates the next available opencode/N branch number by scanning local refs and
32
+ * reserving the chosen number by creating the ref immediately.
33
+ *
34
+ * This avoids relying on OpenCode's project ID and works even in repos with no commits.
35
+ */
36
+ allocateAndReserveBranchNumber(cwd: string, prefix?: string): number;
37
+ private refExists;
38
+ /** Commit OID a local ref points at, or '' if the ref does not exist. */
39
+ getRefOid(cwd: string, ref: string): string;
40
+ /**
41
+ * Returns a commit OID that branch refs can point at. Uses HEAD if the repo has commits,
42
+ * otherwise creates and caches an empty commit (empty tree + commit). Branch refs must
43
+ * point at commits, not blobs.
44
+ */
45
+ private getOrCreateEmptyCommitOid;
46
+ /**
47
+ * Pushes local changes to the sandbox remote.
48
+ * @param remoteName Numbered remote (e.g. sandbox-2) matching opencode/N.
49
+ * @param sshUrl The SSH URL of the sandbox remote.
50
+ * @param branch The branch to push to.
51
+ * @param cwd Worktree path to run git in.
52
+ * @returns true if push succeeded, false if no repo exists. Throws if the push fails.
53
+ */
54
+ pushLocalToSandboxRemote(remoteName: string, sshUrl: string, branch: string, cwd: string): Promise<boolean>;
55
+ private setRemote;
56
+ pull(remoteName: string, sshUrl: string, branch: string, cwd: string, localBranch?: string): Promise<void>;
57
+ push(remoteName: string, sshUrl: string, branch: string, cwd: string): Promise<void>;
58
+ }
@@ -0,0 +1,342 @@
1
+ /**
2
+ * Copyright Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { logger } from '../core/logger';
6
+ import { spawnSync } from 'child_process';
7
+ import { realpathSync } from 'fs';
8
+ import { isAbsolute, resolve as pathResolve } from 'path';
9
+ // Runs git with an explicit argument vector and no shell, so interpolated values
10
+ // (SSH URLs, refs, remote names) can never be interpreted as shell syntax.
11
+ function execGit(args, options = {}) {
12
+ const res = spawnSync('git', args, {
13
+ stdio: ['ignore', 'pipe', 'pipe'],
14
+ encoding: 'utf8',
15
+ ...options,
16
+ });
17
+ if (res.error) {
18
+ return { ok: false, stdout: '', stderr: res.error.message, status: null };
19
+ }
20
+ const status = typeof res.status === 'number' ? res.status : null;
21
+ return { ok: status === 0, stdout: res.stdout ?? '', stderr: res.stderr ?? '', status };
22
+ }
23
+ // POSIX sh single-quoting (close, escape, reopen): GIT_SSH_COMMAND is parsed by the
24
+ // shell, so an unquoted known_hosts path containing spaces would split into ssh args.
25
+ function shellQuote(value) {
26
+ return `'${value.replace(/'/g, `'\\''`)}'`;
27
+ }
28
+ // When DAYTONA_SSH_KNOWN_HOSTS names a known_hosts file with the ssh.app.daytona.io
29
+ // host keys, pin host verification to it for sandbox git transfers. This lets the
30
+ // first noninteractive sync succeed without trust-on-first-use, and without changing
31
+ // SSH behavior for any other remote. Unset means inherited SSH behavior, as before.
32
+ //
33
+ // The value crosses two parsers. sh splits GIT_SSH_COMMAND into ssh's argv (outer
34
+ // single quotes), then OpenSSH splits the UserKnownHostsFile VALUE on whitespace as
35
+ // a file list (inner double quotes keep a spaced path as one file). OpenSSH's config
36
+ // grammar has no escape for a literal double quote inside a quoted value, so such
37
+ // paths are rejected instead of being silently mis-pinned.
38
+ function networkEnv() {
39
+ const knownHosts = process.env.DAYTONA_SSH_KNOWN_HOSTS?.trim();
40
+ if (!knownHosts)
41
+ return undefined;
42
+ if (knownHosts.includes('"')) {
43
+ throw new Error('DAYTONA_SSH_KNOWN_HOSTS must not contain a double quote (") character');
44
+ }
45
+ return {
46
+ ...process.env,
47
+ // GlobalKnownHostsFile=/dev/null: otherwise a matching entry in the system-wide
48
+ // /etc/ssh/ssh_known_hosts would also be accepted and verification would not be
49
+ // pinned to the configured file alone.
50
+ GIT_SSH_COMMAND: `ssh -o ${shellQuote(`UserKnownHostsFile="${knownHosts}"`)} -o GlobalKnownHostsFile=/dev/null -o StrictHostKeyChecking=yes`,
51
+ };
52
+ }
53
+ export class HostGitManager {
54
+ // Per-repo serialization: one queue per git-common-dir. Linked worktrees (git worktree
55
+ // add) of the same repo share `.git/config` and refs, so they must share a queue to
56
+ // avoid racing on `remote add/remove` and `.git/config.lock`. Different repos still
57
+ // proceed in parallel.
58
+ static operationQueues = new Map();
59
+ // cwd → queue-key cache. `git rev-parse --git-common-dir` shells out; caching avoids
60
+ // running it on every enqueue. Repo layout doesn't move at runtime, so this is stable.
61
+ static queueKeyCache = new Map();
62
+ /**
63
+ * Resolve the serialization key for a worktree: the CANONICAL absolute path of its
64
+ * shared git dir (common across linked worktrees of the same repo). Canonicalizing
65
+ * with realpath collapses symlinked aliases onto the same key, so two callers
66
+ * reaching the same repo via different symlink paths still share a queue and can't
67
+ * race on `.git/config`. Falls back to (canonical) cwd if git can't identify a repo.
68
+ */
69
+ static queueKeyFor(cwd) {
70
+ const cached = HostGitManager.queueKeyCache.get(cwd);
71
+ if (cached)
72
+ return cached;
73
+ const res = execGit(['rev-parse', '--git-common-dir'], { cwd });
74
+ const rawPath = !res.ok
75
+ ? cwd
76
+ : (() => {
77
+ const out = res.stdout.trim();
78
+ return isAbsolute(out) ? out : pathResolve(cwd, out);
79
+ })();
80
+ let key;
81
+ try {
82
+ key = realpathSync(rawPath);
83
+ }
84
+ catch {
85
+ // Path may have been deleted between git resolution and our stat; use as-is
86
+ key = rawPath;
87
+ }
88
+ HostGitManager.queueKeyCache.set(cwd, key);
89
+ return key;
90
+ }
91
+ /**
92
+ * Chain `fn` onto the queue for the repo containing `cwd`. The stored promise is
93
+ * always-resolves so a failure doesn't poison the chain; callers still see errors via
94
+ * `await` on the returned promise. Cleared from the map when the tail settles to avoid
95
+ * leaking entries for repos that are no longer active.
96
+ */
97
+ static enqueue(cwd, fn) {
98
+ const queueKey = HostGitManager.queueKeyFor(cwd);
99
+ const prev = HostGitManager.operationQueues.get(queueKey) ?? Promise.resolve();
100
+ const operation = prev.then(fn);
101
+ const stored = operation.then(() => undefined, () => undefined);
102
+ HostGitManager.operationQueues.set(queueKey, stored);
103
+ stored.then(() => {
104
+ if (HostGitManager.operationQueues.get(queueKey) === stored) {
105
+ HostGitManager.operationQueues.delete(queueKey);
106
+ }
107
+ });
108
+ return operation;
109
+ }
110
+ /** Cached OID of an empty commit used to reserve branch refs (branches must point at commits, not blobs). */
111
+ emptyCommitOidCache = new Map();
112
+ /**
113
+ * Checks if a git repository exists in the current directory
114
+ * @returns true if a git repo exists, false otherwise
115
+ */
116
+ hasRepo(cwd) {
117
+ return execGit(['rev-parse', '--is-inside-work-tree'], cwd ? { cwd } : {}).ok;
118
+ }
119
+ /**
120
+ * Allocates the next available opencode/N branch number by scanning local refs and
121
+ * reserving the chosen number by creating the ref immediately.
122
+ *
123
+ * This avoids relying on OpenCode's project ID and works even in repos with no commits.
124
+ */
125
+ allocateAndReserveBranchNumber(cwd, prefix = 'opencode') {
126
+ const start = Date.now();
127
+ if (!this.hasRepo(cwd)) {
128
+ throw new Error('No local git repository found.');
129
+ }
130
+ const base = `refs/heads/${prefix}/`;
131
+ const listRes = execGit(['for-each-ref', '--format=%(refname:strip=3)', base], { cwd });
132
+ if (!listRes.ok)
133
+ throw new Error(listRes.stderr);
134
+ const list = listRes.stdout.trim();
135
+ const nums = list.length === 0
136
+ ? []
137
+ : list
138
+ .split('\n')
139
+ .map((s) => s.trim())
140
+ .filter(Boolean)
141
+ .map((s) => Number.parseInt(s, 10))
142
+ .filter((n) => Number.isFinite(n) && n > 0);
143
+ let n = (nums.length ? Math.max(...nums) : 0) + 1;
144
+ const maxAttempts = 50; // Circuit-breaker
145
+ let attempts = 0;
146
+ while (n < 1_000_000 && attempts < maxAttempts) {
147
+ attempts++;
148
+ const ref = `${base}${n}`;
149
+ if (this.refExists(cwd, ref)) {
150
+ n++;
151
+ continue;
152
+ }
153
+ const oid = this.getOrCreateEmptyCommitOid(cwd);
154
+ const result = execGit(['update-ref', ref, oid], { cwd });
155
+ if (result.ok) {
156
+ logger.info(`[branch-alloc] reserved ${prefix}/${n} in ${Date.now() - start}ms`);
157
+ return n;
158
+ }
159
+ else {
160
+ // If we raced or hit an edge case, try the next number.
161
+ n++;
162
+ }
163
+ }
164
+ const oid = this.getOrCreateEmptyCommitOid(cwd);
165
+ const last = execGit(['update-ref', `${base}${n}`, oid], { cwd });
166
+ if (last.ok) {
167
+ logger.info(`[branch-alloc] reserved ${prefix}/${n} in ${Date.now() - start}ms`);
168
+ return n;
169
+ }
170
+ throw new Error(`Failed to allocate branch number after ${attempts} attempts. Last error: ${last.stderr}`);
171
+ }
172
+ refExists(cwd, ref) {
173
+ return execGit(['show-ref', '--verify', '--quiet', ref], { cwd }).ok;
174
+ }
175
+ /** Commit OID a local ref points at, or '' if the ref does not exist. */
176
+ getRefOid(cwd, ref) {
177
+ const res = execGit(['rev-parse', '--verify', '--quiet', ref], { cwd });
178
+ return res.ok ? res.stdout.trim() : '';
179
+ }
180
+ /**
181
+ * Returns a commit OID that branch refs can point at. Uses HEAD if the repo has commits,
182
+ * otherwise creates and caches an empty commit (empty tree + commit). Branch refs must
183
+ * point at commits, not blobs.
184
+ */
185
+ getOrCreateEmptyCommitOid(cwd) {
186
+ const cached = this.emptyCommitOidCache.get(cwd);
187
+ if (cached)
188
+ return cached;
189
+ const headRes = execGit(['rev-parse', 'HEAD'], { cwd });
190
+ const head = headRes.ok ? headRes.stdout.trim() : '';
191
+ if (head) {
192
+ this.emptyCommitOidCache.set(cwd, head);
193
+ return head;
194
+ }
195
+ // Create an empty tree (idempotent) then a commit pointing at it.
196
+ const treeResult = spawnSync('git', ['hash-object', '-t', 'tree', '-w', '--stdin'], {
197
+ input: '',
198
+ cwd,
199
+ encoding: 'utf8',
200
+ });
201
+ const treeOid = treeResult.stdout?.trim();
202
+ if (treeResult.status !== 0 || !treeOid) {
203
+ const errorMsg = treeResult.stderr?.toString() || treeResult.error?.message || String(treeResult.error || 'unknown');
204
+ throw new Error(`Failed to create empty tree: ${errorMsg}`);
205
+ }
206
+ // Provide a default identity for reservation commits when repo has no user.name/user.email (e.g. CI).
207
+ const reservationCommitName = 'OpenCode Plugin';
208
+ const reservationCommitEmail = 'opencode@daytona.io';
209
+ const reservationCommitMessage = 'OpenCode reservation';
210
+ const commitEnv = {
211
+ ...process.env,
212
+ GIT_AUTHOR_NAME: reservationCommitName,
213
+ GIT_AUTHOR_EMAIL: reservationCommitEmail,
214
+ GIT_COMMITTER_NAME: reservationCommitName,
215
+ GIT_COMMITTER_EMAIL: reservationCommitEmail,
216
+ };
217
+ const commitRes = execGit(['commit-tree', treeOid, '-m', reservationCommitMessage], { cwd, env: commitEnv });
218
+ if (!commitRes.ok)
219
+ throw new Error(`Failed to create empty commit: ${commitRes.stderr}`);
220
+ const commitOid = commitRes.stdout.trim();
221
+ this.emptyCommitOidCache.set(cwd, commitOid);
222
+ return commitOid;
223
+ }
224
+ /**
225
+ * Pushes local changes to the sandbox remote.
226
+ * @param remoteName Numbered remote (e.g. sandbox-2) matching opencode/N.
227
+ * @param sshUrl The SSH URL of the sandbox remote.
228
+ * @param branch The branch to push to.
229
+ * @param cwd Worktree path to run git in.
230
+ * @returns true if push succeeded, false if no repo exists. Throws if the push fails.
231
+ */
232
+ async pushLocalToSandboxRemote(remoteName, sshUrl, branch, cwd) {
233
+ if (!this.hasRepo(cwd)) {
234
+ logger.warn('No local git repository found. Skipping push to sandbox.');
235
+ return false;
236
+ }
237
+ logger.info(`Pushing to ${remoteName} (${sshUrl}) on branch ${branch}`);
238
+ await HostGitManager.enqueue(cwd, async () => {
239
+ const statusRes = execGit(['status', '--porcelain'], { cwd });
240
+ if (!statusRes.ok) {
241
+ throw new Error(statusRes.stderr);
242
+ }
243
+ if (statusRes.stdout.trim().length > 0) {
244
+ logger.warn('Local repository has uncommitted changes; pushing HEAD only (no auto-commit).');
245
+ }
246
+ this.setRemote(remoteName, sshUrl, cwd);
247
+ let attempts = 0;
248
+ while (attempts < 3) {
249
+ const pushRes = execGit(['push', remoteName, `HEAD:${branch}`], { cwd, env: networkEnv() });
250
+ if (pushRes.ok) {
251
+ logger.info(`✓ Pushed local changes to ${remoteName}`);
252
+ return;
253
+ }
254
+ attempts++;
255
+ if (attempts >= 3) {
256
+ logger.error(`Error pushing to ${remoteName} after 3 attempts: ${pushRes.stderr}`);
257
+ throw new Error(pushRes.stderr);
258
+ }
259
+ logger.warn(`Push attempt ${attempts} failed, retrying...`);
260
+ }
261
+ });
262
+ return true;
263
+ }
264
+ setRemote(remoteName, sshUrl, cwd) {
265
+ // Remote may not exist yet — ignore this result. `remote add` below is the check that matters.
266
+ execGit(['remote', 'remove', remoteName], { cwd });
267
+ const addRes = execGit(['remote', 'add', remoteName, sshUrl], { cwd });
268
+ if (!addRes.ok) {
269
+ throw new Error(`Failed to configure sandbox remote '${remoteName}': ${addRes.stderr}`);
270
+ }
271
+ }
272
+ async pull(remoteName, sshUrl, branch, cwd, localBranch) {
273
+ await HostGitManager.enqueue(cwd, async () => {
274
+ this.setRemote(remoteName, sshUrl, cwd);
275
+ let attempts = 0;
276
+ let lastError = undefined;
277
+ // The first pull attempt sometimes fails. I'm not sure what the cause is.
278
+ while (attempts < 3) {
279
+ try {
280
+ if (localBranch) {
281
+ // Fetch into FETCH_HEAD only (never into refs/heads) so we don't hit
282
+ // "refusing to fetch into branch checked out" when this branch is checked out.
283
+ const fetchRes = execGit(['fetch', remoteName, branch], { cwd, env: networkEnv() });
284
+ if (!fetchRes.ok)
285
+ throw new Error(fetchRes.stderr);
286
+ const updateRefRes = execGit(['update-ref', `refs/heads/${localBranch}`, 'FETCH_HEAD'], { cwd });
287
+ if (!updateRefRes.ok)
288
+ throw new Error(updateRefRes.stderr);
289
+ // Only reset working directory if we're currently on this branch
290
+ const currentBranchRes = execGit(['rev-parse', '--abbrev-ref', 'HEAD'], { cwd });
291
+ const currentBranch = currentBranchRes.ok ? currentBranchRes.stdout.trim() : '';
292
+ if (currentBranch === localBranch) {
293
+ const resetRes = execGit(['reset', '--hard', `refs/heads/${localBranch}`], { cwd });
294
+ if (!resetRes.ok)
295
+ throw new Error(resetRes.stderr);
296
+ }
297
+ logger.info(`✓ Force pulled latest changes from sandbox into ${localBranch}`);
298
+ }
299
+ else {
300
+ const pullRes = execGit(['pull', remoteName, branch], { cwd, env: networkEnv() });
301
+ if (!pullRes.ok)
302
+ throw new Error(pullRes.stderr);
303
+ logger.info('✓ Pulled latest changes from sandbox');
304
+ }
305
+ return;
306
+ }
307
+ catch (e) {
308
+ lastError = e;
309
+ attempts++;
310
+ if (attempts >= 3) {
311
+ logger.error(`Error pulling from sandbox after 3 attempts: ${e}`);
312
+ }
313
+ else {
314
+ logger.warn(`Pull attempt ${attempts} failed, retrying...`);
315
+ }
316
+ }
317
+ }
318
+ // If we got here, all attempts failed.
319
+ throw lastError ?? new Error('Pull failed after 3 attempts');
320
+ });
321
+ }
322
+ async push(remoteName, sshUrl, branch, cwd) {
323
+ await HostGitManager.enqueue(cwd, async () => {
324
+ this.setRemote(remoteName, sshUrl, cwd);
325
+ let attempts = 0;
326
+ while (attempts < 3) {
327
+ const pushRes = execGit(['push', remoteName, `HEAD:${branch}`], { cwd, env: networkEnv() });
328
+ if (pushRes.ok) {
329
+ logger.info('✓ Pushed changes to sandbox');
330
+ return;
331
+ }
332
+ attempts++;
333
+ if (attempts >= 3) {
334
+ logger.error(`Error pushing to sandbox after 3 attempts: ${pushRes.stderr}`);
335
+ throw new Error(pushRes.stderr);
336
+ }
337
+ logger.warn(`Push attempt ${attempts} failed, retrying...`);
338
+ }
339
+ });
340
+ }
341
+ }
342
+ //# sourceMappingURL=host-git-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-git-manager.js","sourceRoot":"","sources":["host-git-manager.ts"],"names":[],"mappings":"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"}