@daytonaio/opencode 0.143.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.
- package/.opencode/plugin/daytona/core/logger.d.ts +15 -0
- package/.opencode/plugin/daytona/core/logger.js +64 -0
- package/.opencode/plugin/daytona/core/logger.js.map +1 -0
- package/.opencode/plugin/daytona/core/project-data-storage.d.ts +42 -0
- package/.opencode/plugin/daytona/core/project-data-storage.js +171 -0
- package/.opencode/plugin/daytona/core/project-data-storage.js.map +1 -0
- package/.opencode/plugin/daytona/core/session-manager.d.ts +46 -0
- package/.opencode/plugin/daytona/core/session-manager.js +239 -0
- package/.opencode/plugin/daytona/core/session-manager.js.map +1 -0
- package/.opencode/plugin/daytona/core/toast.d.ts +47 -0
- package/.opencode/plugin/daytona/core/toast.js +73 -0
- package/.opencode/plugin/daytona/core/toast.js.map +1 -0
- package/.opencode/plugin/daytona/core/types.d.ts +53 -0
- package/.opencode/plugin/daytona/core/types.js +15 -0
- package/.opencode/plugin/daytona/core/types.js.map +1 -0
- package/.opencode/plugin/daytona/git/host-git-manager.d.ts +40 -0
- package/.opencode/plugin/daytona/git/host-git-manager.js +283 -0
- package/.opencode/plugin/daytona/git/host-git-manager.js.map +1 -0
- package/.opencode/plugin/daytona/git/index.d.ts +5 -0
- package/.opencode/plugin/daytona/git/index.js +10 -0
- package/.opencode/plugin/daytona/git/index.js.map +1 -0
- package/.opencode/plugin/daytona/git/sandbox-git-manager.d.ts +14 -0
- package/.opencode/plugin/daytona/git/sandbox-git-manager.js +68 -0
- package/.opencode/plugin/daytona/git/sandbox-git-manager.js.map +1 -0
- package/.opencode/plugin/daytona/git/session-git-manager.d.ts +43 -0
- package/.opencode/plugin/daytona/git/session-git-manager.js +132 -0
- package/.opencode/plugin/daytona/git/session-git-manager.js.map +1 -0
- package/.opencode/plugin/daytona/index.d.ts +10 -0
- package/.opencode/plugin/daytona/index.js +44 -0
- package/.opencode/plugin/daytona/index.js.map +1 -0
- package/.opencode/plugin/daytona/plugins/custom-tools.d.ts +11 -0
- package/.opencode/plugin/daytona/plugins/custom-tools.js +26 -0
- package/.opencode/plugin/daytona/plugins/custom-tools.js.map +1 -0
- package/.opencode/plugin/daytona/plugins/index.d.ts +11 -0
- package/.opencode/plugin/daytona/plugins/index.js +19 -0
- package/.opencode/plugin/daytona/plugins/index.js.map +1 -0
- package/.opencode/plugin/daytona/plugins/session-cleanup.d.ts +11 -0
- package/.opencode/plugin/daytona/plugins/session-cleanup.js +43 -0
- package/.opencode/plugin/daytona/plugins/session-cleanup.js.map +1 -0
- package/.opencode/plugin/daytona/plugins/session-idle-auto-commit.d.ts +10 -0
- package/.opencode/plugin/daytona/plugins/session-idle-auto-commit.js +54 -0
- package/.opencode/plugin/daytona/plugins/session-idle-auto-commit.js.map +1 -0
- package/.opencode/plugin/daytona/plugins/system-transform.d.ts +10 -0
- package/.opencode/plugin/daytona/plugins/system-transform.js +29 -0
- package/.opencode/plugin/daytona/plugins/system-transform.js.map +1 -0
- package/.opencode/plugin/daytona/tools/bash.d.ts +19 -0
- package/.opencode/plugin/daytona/tools/bash.js +42 -0
- package/.opencode/plugin/daytona/tools/bash.js.map +1 -0
- package/.opencode/plugin/daytona/tools/edit.d.ts +21 -0
- package/.opencode/plugin/daytona/tools/edit.js +27 -0
- package/.opencode/plugin/daytona/tools/edit.js.map +1 -0
- package/.opencode/plugin/daytona/tools/get-preview-url.d.ts +17 -0
- package/.opencode/plugin/daytona/tools/get-preview-url.js +21 -0
- package/.opencode/plugin/daytona/tools/get-preview-url.js.map +1 -0
- package/.opencode/plugin/daytona/tools/glob.d.ts +17 -0
- package/.opencode/plugin/daytona/tools/glob.js +25 -0
- package/.opencode/plugin/daytona/tools/glob.js.map +1 -0
- package/.opencode/plugin/daytona/tools/grep.d.ts +17 -0
- package/.opencode/plugin/daytona/tools/grep.js +25 -0
- package/.opencode/plugin/daytona/tools/grep.js.map +1 -0
- package/.opencode/plugin/daytona/tools/ls.d.ts +17 -0
- package/.opencode/plugin/daytona/tools/ls.js +26 -0
- package/.opencode/plugin/daytona/tools/ls.js.map +1 -0
- package/.opencode/plugin/daytona/tools/lsp.d.ts +21 -0
- package/.opencode/plugin/daytona/tools/lsp.js +21 -0
- package/.opencode/plugin/daytona/tools/lsp.js.map +1 -0
- package/.opencode/plugin/daytona/tools/multiedit.d.ts +25 -0
- package/.opencode/plugin/daytona/tools/multiedit.js +31 -0
- package/.opencode/plugin/daytona/tools/multiedit.js.map +1 -0
- package/.opencode/plugin/daytona/tools/patch.d.ts +19 -0
- package/.opencode/plugin/daytona/tools/patch.js +19 -0
- package/.opencode/plugin/daytona/tools/patch.js.map +1 -0
- package/.opencode/plugin/daytona/tools/read.d.ts +17 -0
- package/.opencode/plugin/daytona/tools/read.js +22 -0
- package/.opencode/plugin/daytona/tools/read.js.map +1 -0
- package/.opencode/plugin/daytona/tools/write.d.ts +19 -0
- package/.opencode/plugin/daytona/tools/write.js +22 -0
- package/.opencode/plugin/daytona/tools/write.js.map +1 -0
- package/.opencode/plugin/daytona/tools.d.ts +129 -0
- package/.opencode/plugin/daytona/tools.js +38 -0
- package/.opencode/plugin/daytona/tools.js.map +1 -0
- package/.opencode/plugin/index.d.ts +9 -0
- package/.opencode/plugin/index.js +13 -0
- package/.opencode/plugin/index.js.map +1 -0
- package/README.md +219 -0
- package/package.json +55 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Daytona Platforms Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import type { LogLevel } from './types';
|
|
6
|
+
export declare function setLogFilePath(path: string): void;
|
|
7
|
+
declare class Logger {
|
|
8
|
+
private get logFile();
|
|
9
|
+
log(message: string, level?: LogLevel): void;
|
|
10
|
+
info(message: string): void;
|
|
11
|
+
error(message: string): void;
|
|
12
|
+
warn(message: string): void;
|
|
13
|
+
}
|
|
14
|
+
export declare const logger: Logger;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright 2025 Daytona Platforms Inc.
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.logger = void 0;
|
|
8
|
+
exports.setLogFilePath = setLogFilePath;
|
|
9
|
+
/**
|
|
10
|
+
* Logger class for handling plugin logging
|
|
11
|
+
*/
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const types_1 = require("./types");
|
|
15
|
+
let logFilePath;
|
|
16
|
+
function setLogFilePath(path) {
|
|
17
|
+
logFilePath = path;
|
|
18
|
+
}
|
|
19
|
+
class Logger {
|
|
20
|
+
get logFile() {
|
|
21
|
+
if (!logFilePath)
|
|
22
|
+
throw new Error('Logger file path not set. Call setLogFilePath(path) before use.');
|
|
23
|
+
return logFilePath;
|
|
24
|
+
}
|
|
25
|
+
log(message, level = types_1.LOG_LEVEL_INFO) {
|
|
26
|
+
// Ensure log directory exists
|
|
27
|
+
try {
|
|
28
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(this.logFile), { recursive: true });
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
// Directory may already exist, ignore
|
|
32
|
+
}
|
|
33
|
+
// Trim log file if it exceeds 3MB (keep last 1MB)
|
|
34
|
+
try {
|
|
35
|
+
const stats = (0, fs_1.statSync)(this.logFile);
|
|
36
|
+
const maxSize = 3 * 1024 * 1024;
|
|
37
|
+
const keepSize = 1024 * 1024;
|
|
38
|
+
if (stats.size > maxSize) {
|
|
39
|
+
const content = (0, fs_1.readFileSync)(this.logFile, 'utf8');
|
|
40
|
+
const trimmed = content.slice(-keepSize);
|
|
41
|
+
// Drop partial first line so we don't start mid-log
|
|
42
|
+
const firstNewline = trimmed.indexOf('\n');
|
|
43
|
+
(0, fs_1.writeFileSync)(this.logFile, firstNewline >= 0 ? trimmed.slice(firstNewline + 1) : trimmed);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
// File may not exist yet, ignore
|
|
48
|
+
}
|
|
49
|
+
const timestamp = new Date().toISOString();
|
|
50
|
+
const logEntry = `[${timestamp}] [${level}] ${message}\n`;
|
|
51
|
+
(0, fs_1.appendFileSync)(this.logFile, logEntry);
|
|
52
|
+
}
|
|
53
|
+
info(message) {
|
|
54
|
+
this.log(message, types_1.LOG_LEVEL_INFO);
|
|
55
|
+
}
|
|
56
|
+
error(message) {
|
|
57
|
+
this.log(message, types_1.LOG_LEVEL_ERROR);
|
|
58
|
+
}
|
|
59
|
+
warn(message) {
|
|
60
|
+
this.log(message, types_1.LOG_LEVEL_WARN);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.logger = new Logger();
|
|
64
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../../../../../libs/opencode-plugin/.opencode/plugin/daytona/core/logger.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAaH,wCAEC;AAbD;;GAEG;AAEH,2BAAqF;AACrF,+BAA8B;AAE9B,mCAAyE;AAEzE,IAAI,WAA+B,CAAA;AAEnC,SAAgB,cAAc,CAAC,IAAY;IACzC,WAAW,GAAG,IAAI,CAAA;AACpB,CAAC;AAED,MAAM,MAAM;IACV,IAAY,OAAO;QACjB,IAAI,CAAC,WAAW;YAAE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;QACpG,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,GAAG,CAAC,OAAe,EAAE,QAAkB,sBAAc;QACnD,8BAA8B;QAC9B,IAAI,CAAC;YACH,IAAA,cAAS,EAAC,IAAA,cAAO,EAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACvD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,sCAAsC;QACxC,CAAC;QACD,kDAAkD;QAClD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAA,aAAQ,EAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACpC,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA;YAC/B,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAA;YAC5B,IAAI,KAAK,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,IAAA,iBAAY,EAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;gBAClD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAA;gBACxC,oDAAoD;gBACpD,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;gBAC1C,IAAA,kBAAa,EAAC,IAAI,CAAC,OAAO,EAAE,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;YAC5F,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,iCAAiC;QACnC,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QAC1C,MAAM,QAAQ,GAAG,IAAI,SAAS,MAAM,KAAK,KAAK,OAAO,IAAI,CAAA;QACzD,IAAA,mBAAc,EAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IACxC,CAAC;IAED,IAAI,CAAC,OAAe;QAClB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,sBAAc,CAAC,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,OAAe;QACnB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,uBAAe,CAAC,CAAA;IACpC,CAAC;IAED,IAAI,CAAC,OAAe;QAClB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,sBAAc,CAAC,CAAA;IACnC,CAAC;CACF;AAEY,QAAA,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Daytona Platforms Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import type { ProjectSessionData, SessionInfo } from './types';
|
|
6
|
+
export declare class ProjectDataStorage {
|
|
7
|
+
private readonly storageDir;
|
|
8
|
+
constructor(storageDir: string);
|
|
9
|
+
/**
|
|
10
|
+
* Get the file path for a project's session data
|
|
11
|
+
*/
|
|
12
|
+
private getProjectFilePath;
|
|
13
|
+
/**
|
|
14
|
+
* List known project IDs from storage.
|
|
15
|
+
*/
|
|
16
|
+
private listProjectIds;
|
|
17
|
+
/**
|
|
18
|
+
* Load project session data from disk
|
|
19
|
+
*/
|
|
20
|
+
load(projectId: string): ProjectSessionData | null;
|
|
21
|
+
/**
|
|
22
|
+
* Get a session for a project. If not found in the requested project, search all other
|
|
23
|
+
* projects on disk and, if found, migrate it into the requested project.
|
|
24
|
+
*/
|
|
25
|
+
getSession(projectId: string, worktree: string, sessionId: string): SessionInfo | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Save project session data to disk
|
|
28
|
+
*/
|
|
29
|
+
save(projectId: string, worktree: string, sessions: Record<string, SessionInfo>): void;
|
|
30
|
+
/**
|
|
31
|
+
* Get branch number for a sandbox
|
|
32
|
+
*/
|
|
33
|
+
getBranchNumberForSandbox(projectId: string, sandboxId: string): number | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Update a single session in the project file
|
|
36
|
+
*/
|
|
37
|
+
updateSession(projectId: string, worktree: string, sessionId: string, sandboxId: string, branchNumber?: number): void;
|
|
38
|
+
/**
|
|
39
|
+
* Remove a session from the project file
|
|
40
|
+
*/
|
|
41
|
+
removeSession(projectId: string, worktree: string, sessionId: string): void;
|
|
42
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright 2025 Daytona Platforms Inc.
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ProjectDataStorage = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* Handles file storage operations for project session data
|
|
10
|
+
* Stores data per-project in ~/.local/share/opencode/storage/daytona/{projectId}.json
|
|
11
|
+
*/
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const logger_1 = require("./logger");
|
|
15
|
+
class ProjectDataStorage {
|
|
16
|
+
storageDir;
|
|
17
|
+
constructor(storageDir) {
|
|
18
|
+
this.storageDir = storageDir;
|
|
19
|
+
// Ensure storage directory exists
|
|
20
|
+
if (!(0, fs_1.existsSync)(this.storageDir)) {
|
|
21
|
+
(0, fs_1.mkdirSync)(this.storageDir, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get the file path for a project's session data
|
|
26
|
+
*/
|
|
27
|
+
getProjectFilePath(projectId) {
|
|
28
|
+
return (0, path_1.join)(this.storageDir, `${projectId}.json`);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* List known project IDs from storage.
|
|
32
|
+
*/
|
|
33
|
+
listProjectIds() {
|
|
34
|
+
try {
|
|
35
|
+
return (0, fs_1.readdirSync)(this.storageDir)
|
|
36
|
+
.filter((name) => name.endsWith('.json'))
|
|
37
|
+
.map((name) => name.slice(0, -'.json'.length));
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
logger_1.logger.error(`Failed to list project data files: ${err}`);
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Load project session data from disk
|
|
46
|
+
*/
|
|
47
|
+
load(projectId) {
|
|
48
|
+
const filePath = this.getProjectFilePath(projectId);
|
|
49
|
+
try {
|
|
50
|
+
if ((0, fs_1.existsSync)(filePath)) {
|
|
51
|
+
return JSON.parse((0, fs_1.readFileSync)(filePath, 'utf-8'));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
logger_1.logger.error(`Failed to load project data for ${projectId}: ${err}`);
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get a session for a project. If not found in the requested project, search all other
|
|
61
|
+
* projects on disk and, if found, migrate it into the requested project.
|
|
62
|
+
*/
|
|
63
|
+
getSession(projectId, worktree, sessionId) {
|
|
64
|
+
const current = this.load(projectId);
|
|
65
|
+
const currentSession = current?.sessions?.[sessionId];
|
|
66
|
+
if (currentSession) {
|
|
67
|
+
return currentSession;
|
|
68
|
+
}
|
|
69
|
+
// Look in other projects and migrate if found.
|
|
70
|
+
for (const otherProjectId of this.listProjectIds()) {
|
|
71
|
+
if (otherProjectId === projectId)
|
|
72
|
+
continue;
|
|
73
|
+
const otherData = this.load(otherProjectId);
|
|
74
|
+
const found = otherData?.sessions?.[sessionId];
|
|
75
|
+
if (!found)
|
|
76
|
+
continue;
|
|
77
|
+
const destination = current ?? {
|
|
78
|
+
projectId,
|
|
79
|
+
worktree,
|
|
80
|
+
sessions: {},
|
|
81
|
+
};
|
|
82
|
+
// Remove from source first (best effort).
|
|
83
|
+
try {
|
|
84
|
+
delete otherData.sessions[sessionId];
|
|
85
|
+
this.save(otherProjectId, otherData.worktree, otherData.sessions);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
logger_1.logger.warn(`Failed to remove session ${sessionId} from project ${otherProjectId}: ${err}`);
|
|
89
|
+
}
|
|
90
|
+
// Add to destination and persist.
|
|
91
|
+
destination.sessions[sessionId] = found;
|
|
92
|
+
// Prefer the worktree for the project we're actually operating on.
|
|
93
|
+
destination.worktree = worktree;
|
|
94
|
+
this.save(projectId, destination.worktree, destination.sessions);
|
|
95
|
+
logger_1.logger.info(`Migrated session ${sessionId} from project ${otherProjectId} to project ${projectId}`);
|
|
96
|
+
return found;
|
|
97
|
+
}
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Save project session data to disk
|
|
102
|
+
*/
|
|
103
|
+
save(projectId, worktree, sessions) {
|
|
104
|
+
const filePath = this.getProjectFilePath(projectId);
|
|
105
|
+
const projectData = {
|
|
106
|
+
projectId,
|
|
107
|
+
worktree,
|
|
108
|
+
sessions,
|
|
109
|
+
};
|
|
110
|
+
try {
|
|
111
|
+
(0, fs_1.writeFileSync)(filePath, JSON.stringify(projectData, null, 2));
|
|
112
|
+
logger_1.logger.info(`Saved project data for ${projectId}`);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
logger_1.logger.error(`Failed to save project data for ${projectId}: ${err}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get branch number for a sandbox
|
|
120
|
+
*/
|
|
121
|
+
getBranchNumberForSandbox(projectId, sandboxId) {
|
|
122
|
+
const projectData = this.load(projectId);
|
|
123
|
+
if (!projectData) {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
const session = Object.values(projectData.sessions).find((s) => s.sandboxId === sandboxId);
|
|
127
|
+
return session?.branchNumber;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Update a single session in the project file
|
|
131
|
+
*/
|
|
132
|
+
updateSession(projectId, worktree, sessionId, sandboxId, branchNumber) {
|
|
133
|
+
const projectData = this.load(projectId) || {
|
|
134
|
+
projectId,
|
|
135
|
+
worktree,
|
|
136
|
+
sessions: {},
|
|
137
|
+
};
|
|
138
|
+
const now = Date.now();
|
|
139
|
+
if (!projectData.sessions[sessionId]) {
|
|
140
|
+
projectData.sessions[sessionId] = {
|
|
141
|
+
sandboxId,
|
|
142
|
+
...(branchNumber !== undefined ? { branchNumber } : {}),
|
|
143
|
+
created: now,
|
|
144
|
+
lastAccessed: now,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
projectData.sessions[sessionId].sandboxId = sandboxId;
|
|
149
|
+
projectData.sessions[sessionId].lastAccessed = now;
|
|
150
|
+
// Only update branch number if it wasn't set before
|
|
151
|
+
if (projectData.sessions[sessionId].branchNumber === undefined) {
|
|
152
|
+
if (branchNumber !== undefined) {
|
|
153
|
+
projectData.sessions[sessionId].branchNumber = branchNumber;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
this.save(projectId, worktree, projectData.sessions);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Remove a session from the project file
|
|
161
|
+
*/
|
|
162
|
+
removeSession(projectId, worktree, sessionId) {
|
|
163
|
+
const projectData = this.load(projectId);
|
|
164
|
+
if (projectData && projectData.sessions[sessionId]) {
|
|
165
|
+
delete projectData.sessions[sessionId];
|
|
166
|
+
this.save(projectId, worktree, projectData.sessions);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
exports.ProjectDataStorage = ProjectDataStorage;
|
|
171
|
+
//# sourceMappingURL=project-data-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-data-storage.js","sourceRoot":"","sources":["../../../../../../../libs/opencode-plugin/.opencode/plugin/daytona/core/project-data-storage.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;;GAGG;AAEH,2BAAoF;AACpF,+BAA2B;AAC3B,qCAAiC;AAGjC,MAAa,kBAAkB;IACZ,UAAU,CAAQ;IAEnC,YAAY,UAAkB;QAC5B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAE5B,kCAAkC;QAClC,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACjC,IAAA,cAAS,EAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACjD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,SAAiB;QAC1C,OAAO,IAAA,WAAI,EAAC,IAAI,CAAC,UAAU,EAAE,GAAG,SAAS,OAAO,CAAC,CAAA;IACnD,CAAC;IAED;;OAEG;IACK,cAAc;QACpB,IAAI,CAAC;YACH,OAAO,IAAA,gBAAW,EAAC,IAAI,CAAC,UAAU,CAAC;iBAChC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;iBACxC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,eAAM,CAAC,KAAK,CAAC,sCAAsC,GAAG,EAAE,CAAC,CAAA;YACzD,OAAO,EAAE,CAAA;QACX,CAAC;IACH,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,SAAiB;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAA;QACnD,IAAI,CAAC;YACH,IAAI,IAAA,eAAU,EAAC,QAAQ,CAAC,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAuB,CAAA;YAC1E,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,eAAM,CAAC,KAAK,CAAC,mCAAmC,SAAS,KAAK,GAAG,EAAE,CAAC,CAAA;QACtE,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,SAAiB,EAAE,QAAgB,EAAE,SAAiB;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACpC,MAAM,cAAc,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAA;QACrD,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,cAAc,CAAA;QACvB,CAAC;QAED,+CAA+C;QAC/C,KAAK,MAAM,cAAc,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YACnD,IAAI,cAAc,KAAK,SAAS;gBAAE,SAAQ;YAE1C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YAC3C,MAAM,KAAK,GAAG,SAAS,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAA;YAC9C,IAAI,CAAC,KAAK;gBAAE,SAAQ;YAEpB,MAAM,WAAW,GAAuB,OAAO,IAAI;gBACjD,SAAS;gBACT,QAAQ;gBACR,QAAQ,EAAE,EAAE;aACb,CAAA;YAED,0CAA0C;YAC1C,IAAI,CAAC;gBACH,OAAO,SAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;gBACrC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,SAAU,CAAC,QAAQ,EAAE,SAAU,CAAC,QAAQ,CAAC,CAAA;YACrE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,eAAM,CAAC,IAAI,CAAC,4BAA4B,SAAS,iBAAiB,cAAc,KAAK,GAAG,EAAE,CAAC,CAAA;YAC7F,CAAC;YAED,kCAAkC;YAClC,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,KAAK,CAAA;YACvC,mEAAmE;YACnE,WAAW,CAAC,QAAQ,GAAG,QAAQ,CAAA;YAC/B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;YAEhE,eAAM,CAAC,IAAI,CAAC,oBAAoB,SAAS,iBAAiB,cAAc,eAAe,SAAS,EAAE,CAAC,CAAA;YACnG,OAAO,KAAK,CAAA;QACd,CAAC;QAED,OAAO,SAAS,CAAA;IAClB,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,SAAiB,EAAE,QAAgB,EAAE,QAAqC;QAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAA;QACnD,MAAM,WAAW,GAAuB;YACtC,SAAS;YACT,QAAQ;YACR,QAAQ;SACT,CAAA;QAED,IAAI,CAAC;YACH,IAAA,kBAAa,EAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAC7D,eAAM,CAAC,IAAI,CAAC,0BAA0B,SAAS,EAAE,CAAC,CAAA;QACpD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,eAAM,CAAC,KAAK,CAAC,mCAAmC,SAAS,KAAK,GAAG,EAAE,CAAC,CAAA;QACtE,CAAC;IACH,CAAC;IAED;;OAEG;IACH,yBAAyB,CAAC,SAAiB,EAAE,SAAiB;QAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACxC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA;QAC1F,OAAO,OAAO,EAAE,YAAY,CAAA;IAC9B,CAAC;IAED;;OAEG;IACH,aAAa,CACX,SAAiB,EACjB,QAAgB,EAChB,SAAiB,EACjB,SAAiB,EACjB,YAAqB;QAErB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI;YAC1C,SAAS;YACT,QAAQ;YACR,QAAQ,EAAE,EAAE;SACb,CAAA;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACrC,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG;gBAChC,SAAS;gBACT,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvD,OAAO,EAAE,GAAG;gBACZ,YAAY,EAAE,GAAG;aAClB,CAAA;QACH,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,SAAS,GAAG,SAAS,CAAA;YACrD,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,YAAY,GAAG,GAAG,CAAA;YAClD,oDAAoD;YACpD,IAAI,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC/D,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;oBAC/B,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,YAAY,GAAG,YAAY,CAAA;gBAC7D,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;IACtD,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,SAAiB,EAAE,QAAgB,EAAE,SAAiB;QAClE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACxC,IAAI,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACnD,OAAO,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;YACtC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;QACtD,CAAC;IACH,CAAC;CACF;AA7KD,gDA6KC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Daytona Platforms Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Manages Daytona sandbox sessions and persists session-sandbox mappings
|
|
7
|
+
* Stores data per-project in ~/.local/share/opencode/storage/daytona/{projectId}.json
|
|
8
|
+
*/
|
|
9
|
+
import { type Sandbox } from '@daytonaio/sdk';
|
|
10
|
+
import type { PluginInput } from '@opencode-ai/plugin';
|
|
11
|
+
export declare class DaytonaSessionManager {
|
|
12
|
+
private readonly apiKey;
|
|
13
|
+
private readonly dataStorage;
|
|
14
|
+
private sessionSandboxes;
|
|
15
|
+
private currentProjectId?;
|
|
16
|
+
readonly repoPath: string;
|
|
17
|
+
constructor(apiKey: string, storageDir: string, repoPath: string);
|
|
18
|
+
/**
|
|
19
|
+
* Check if a sandbox is fully initialized (has process property)
|
|
20
|
+
*/
|
|
21
|
+
private isFullyInitialized;
|
|
22
|
+
/**
|
|
23
|
+
* Check if a sandbox is partially initialized (has id but not process)
|
|
24
|
+
*/
|
|
25
|
+
private isPartiallyInitialized;
|
|
26
|
+
/**
|
|
27
|
+
* Load sessions for a specific project into memory
|
|
28
|
+
*/
|
|
29
|
+
private loadProjectSessions;
|
|
30
|
+
/**
|
|
31
|
+
* Set the current project context
|
|
32
|
+
*/
|
|
33
|
+
setProjectContext(projectId: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Get branch number for a sandbox
|
|
36
|
+
*/
|
|
37
|
+
getBranchNumberForSandbox(projectId: string, sandboxId: string): number | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Get or create a sandbox for the given session ID
|
|
40
|
+
*/
|
|
41
|
+
getSandbox(sessionId: string, projectId: string, worktree: string, pluginCtx?: PluginInput): Promise<Sandbox>;
|
|
42
|
+
/**
|
|
43
|
+
* Delete the sandbox associated with the given session ID
|
|
44
|
+
*/
|
|
45
|
+
deleteSandbox(sessionId: string, projectId: string): Promise<void>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright 2025 Daytona Platforms Inc.
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.DaytonaSessionManager = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* Manages Daytona sandbox sessions and persists session-sandbox mappings
|
|
10
|
+
* Stores data per-project in ~/.local/share/opencode/storage/daytona/{projectId}.json
|
|
11
|
+
*/
|
|
12
|
+
const sdk_1 = require("@daytonaio/sdk");
|
|
13
|
+
const logger_1 = require("./logger");
|
|
14
|
+
const session_git_manager_1 = require("../git/session-git-manager");
|
|
15
|
+
const sandbox_git_manager_1 = require("../git/sandbox-git-manager");
|
|
16
|
+
const project_data_storage_1 = require("./project-data-storage");
|
|
17
|
+
const toast_1 = require("./toast");
|
|
18
|
+
class DaytonaSessionManager {
|
|
19
|
+
apiKey;
|
|
20
|
+
dataStorage;
|
|
21
|
+
sessionSandboxes;
|
|
22
|
+
currentProjectId;
|
|
23
|
+
repoPath;
|
|
24
|
+
constructor(apiKey, storageDir, repoPath) {
|
|
25
|
+
this.apiKey = apiKey;
|
|
26
|
+
this.dataStorage = new project_data_storage_1.ProjectDataStorage(storageDir);
|
|
27
|
+
this.repoPath = repoPath;
|
|
28
|
+
this.sessionSandboxes = new Map();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if a sandbox is fully initialized (has process property)
|
|
32
|
+
*/
|
|
33
|
+
isFullyInitialized(sandbox) {
|
|
34
|
+
return sandbox !== undefined && 'process' in sandbox;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check if a sandbox is partially initialized (has id but not process)
|
|
38
|
+
*/
|
|
39
|
+
isPartiallyInitialized(sandbox) {
|
|
40
|
+
return sandbox !== undefined && 'id' in sandbox && !('process' in sandbox);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Load sessions for a specific project into memory
|
|
44
|
+
*/
|
|
45
|
+
loadProjectSessions(projectId) {
|
|
46
|
+
const projectData = this.dataStorage.load(projectId);
|
|
47
|
+
if (projectData) {
|
|
48
|
+
for (const [sessionId, sessionInfo] of Object.entries(projectData.sessions)) {
|
|
49
|
+
this.sessionSandboxes.set(sessionId, { id: sessionInfo.sandboxId });
|
|
50
|
+
}
|
|
51
|
+
logger_1.logger.info(`Loaded ${Object.keys(projectData.sessions).length} sessions for project ${projectId}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Set the current project context
|
|
56
|
+
*/
|
|
57
|
+
setProjectContext(projectId) {
|
|
58
|
+
if (this.currentProjectId !== projectId) {
|
|
59
|
+
this.currentProjectId = projectId;
|
|
60
|
+
this.sessionSandboxes.clear();
|
|
61
|
+
this.loadProjectSessions(projectId);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get branch number for a sandbox
|
|
66
|
+
*/
|
|
67
|
+
getBranchNumberForSandbox(projectId, sandboxId) {
|
|
68
|
+
return this.dataStorage.getBranchNumberForSandbox(projectId, sandboxId);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get or create a sandbox for the given session ID
|
|
72
|
+
*/
|
|
73
|
+
async getSandbox(sessionId, projectId, worktree, pluginCtx) {
|
|
74
|
+
if (pluginCtx?.client?.tui) {
|
|
75
|
+
toast_1.toast.initialize(pluginCtx.client.tui);
|
|
76
|
+
}
|
|
77
|
+
if (!this.apiKey) {
|
|
78
|
+
logger_1.logger.error('DAYTONA_API_KEY is not set. Cannot create or retrieve sandbox.');
|
|
79
|
+
toast_1.toast.show({
|
|
80
|
+
title: 'Sandbox error',
|
|
81
|
+
message: 'DAYTONA_API_KEY is not set. Please set the environment variable to use Daytona sandboxes.',
|
|
82
|
+
variant: 'error',
|
|
83
|
+
});
|
|
84
|
+
throw new Error('DAYTONA_API_KEY is not set. Please set the environment variable to use Daytona sandboxes.');
|
|
85
|
+
}
|
|
86
|
+
// Load project sessions if needed
|
|
87
|
+
this.setProjectContext(projectId);
|
|
88
|
+
const existing = this.sessionSandboxes.get(sessionId);
|
|
89
|
+
// If we have a fully initialized sandbox, reuse it
|
|
90
|
+
if (this.isFullyInitialized(existing)) {
|
|
91
|
+
// Refresh sandbox state and ensure it's running
|
|
92
|
+
await existing.refreshData();
|
|
93
|
+
if (existing.state !== 'started') {
|
|
94
|
+
logger_1.logger.info(`Starting sandbox ${existing.id} (current state: ${existing.state})`);
|
|
95
|
+
await existing.start();
|
|
96
|
+
}
|
|
97
|
+
this.dataStorage.updateSession(projectId, worktree, sessionId, existing.id);
|
|
98
|
+
return existing;
|
|
99
|
+
}
|
|
100
|
+
// If we have a sandboxId but not a full sandbox object, reconnect to it
|
|
101
|
+
if (this.isPartiallyInitialized(existing)) {
|
|
102
|
+
logger_1.logger.info(`Reconnecting to existing sandbox: ${existing.id}`);
|
|
103
|
+
const daytona = new sdk_1.Daytona({ apiKey: this.apiKey });
|
|
104
|
+
const reconnectStart = Date.now();
|
|
105
|
+
logger_1.logger.info(`Daytona get begin sandboxId=${existing.id}`);
|
|
106
|
+
const sandbox = await daytona.get(existing.id);
|
|
107
|
+
logger_1.logger.info(`Daytona get done sandboxId=${existing.id} in ${Date.now() - reconnectStart}ms`);
|
|
108
|
+
logger_1.logger.info(`Starting sandbox begin sandboxId=${sandbox.id}`);
|
|
109
|
+
await sandbox.start();
|
|
110
|
+
logger_1.logger.info(`Starting sandbox done sandboxId=${sandbox.id} in ${Date.now() - reconnectStart}ms`);
|
|
111
|
+
this.sessionSandboxes.set(sessionId, sandbox);
|
|
112
|
+
// Preserve branch number if it exists for this sandbox
|
|
113
|
+
let branchNumber = this.dataStorage.getBranchNumberForSandbox(projectId, sandbox.id);
|
|
114
|
+
if (!branchNumber) {
|
|
115
|
+
try {
|
|
116
|
+
branchNumber = session_git_manager_1.SessionGitManager.allocateAndReserveBranchNumber(worktree);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// No local git repo (or git unavailable) shouldn't block sandbox usage.
|
|
120
|
+
branchNumber = undefined;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
this.dataStorage.updateSession(projectId, worktree, sessionId, sandbox.id, branchNumber);
|
|
124
|
+
toast_1.toast.show({
|
|
125
|
+
title: 'Sandbox connected',
|
|
126
|
+
message: `Connected to existing sandbox.`,
|
|
127
|
+
variant: 'info',
|
|
128
|
+
});
|
|
129
|
+
// Even if git syncing is disabled, ensure the project directory exists in the sandbox.
|
|
130
|
+
if (!branchNumber) {
|
|
131
|
+
try {
|
|
132
|
+
await new sandbox_git_manager_1.DaytonaSandboxGitManager(sandbox, this.repoPath).ensureDirectory();
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
logger_1.logger.warn(`Failed to ensure sandbox project directory exists: ${err}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return sandbox;
|
|
139
|
+
}
|
|
140
|
+
// If not in cache/storage for this project, try to recover from other projects and migrate.
|
|
141
|
+
if (!existing) {
|
|
142
|
+
const migrated = this.dataStorage.getSession(projectId, worktree, sessionId);
|
|
143
|
+
if (migrated?.sandboxId) {
|
|
144
|
+
logger_1.logger.info(`Recovered session ${sessionId} for project ${projectId} (migrated from another project)`);
|
|
145
|
+
this.sessionSandboxes.set(sessionId, { id: migrated.sandboxId });
|
|
146
|
+
// Re-run getSandbox to go through the normal reconnect path.
|
|
147
|
+
return this.getSandbox(sessionId, projectId, worktree, pluginCtx);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Otherwise, create a new sandbox
|
|
151
|
+
logger_1.logger.info(`Creating new sandbox for session: ${sessionId} in project: ${projectId}`);
|
|
152
|
+
const daytona = new sdk_1.Daytona({ apiKey: this.apiKey });
|
|
153
|
+
const createStart = Date.now();
|
|
154
|
+
logger_1.logger.info(`Daytona create begin sessionId=${sessionId}`);
|
|
155
|
+
const waitingLog = setTimeout(() => {
|
|
156
|
+
logger_1.logger.warn(`Daytona create still waiting after ${Date.now() - createStart}ms (sessionId=${sessionId})`);
|
|
157
|
+
}, 15_000);
|
|
158
|
+
const sandbox = await daytona.create().finally(() => clearTimeout(waitingLog));
|
|
159
|
+
logger_1.logger.info(`Daytona create done sessionId=${sessionId} sandboxId=${sandbox.id} in ${Date.now() - createStart}ms`);
|
|
160
|
+
this.sessionSandboxes.set(sessionId, sandbox);
|
|
161
|
+
// Get or assign branch number for this sandbox
|
|
162
|
+
let branchNumber = this.dataStorage.getBranchNumberForSandbox(projectId, sandbox.id);
|
|
163
|
+
if (!branchNumber) {
|
|
164
|
+
try {
|
|
165
|
+
branchNumber = session_git_manager_1.SessionGitManager.allocateAndReserveBranchNumber(worktree);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
logger_1.logger.warn(`allocateAndReserveBranchNumber failed sessionId=${sessionId}: ${err}`);
|
|
169
|
+
// No local git repo (or git unavailable) shouldn't block sandbox usage.
|
|
170
|
+
branchNumber = undefined;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
this.dataStorage.updateSession(projectId, worktree, sessionId, sandbox.id, branchNumber);
|
|
174
|
+
logger_1.logger.info(`Sandbox created successfully: ${sandbox.id}${branchNumber ? ` with branch number ${branchNumber}` : ''}`);
|
|
175
|
+
// Initialize git repo in the sandbox and sync with host
|
|
176
|
+
try {
|
|
177
|
+
if (branchNumber) {
|
|
178
|
+
const sessionGit = new session_git_manager_1.SessionGitManager(sandbox, this.repoPath, worktree, branchNumber);
|
|
179
|
+
await sessionGit.initializeAndSync(pluginCtx);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Git disabled; still ensure the directory exists so tools can operate.
|
|
183
|
+
await new sandbox_git_manager_1.DaytonaSandboxGitManager(sandbox, this.repoPath).ensureDirectory();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
logger_1.logger.error(`Failed to initialize git repo or push local changes in sandbox: ${err}`);
|
|
188
|
+
toast_1.toast.show({
|
|
189
|
+
title: 'Git error',
|
|
190
|
+
message: err?.message || 'Failed to initialize git repo in sandbox.',
|
|
191
|
+
variant: 'error',
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
toast_1.toast.show({
|
|
195
|
+
title: 'Sandbox created',
|
|
196
|
+
message: `Created new sandbox for session.`,
|
|
197
|
+
variant: 'success',
|
|
198
|
+
});
|
|
199
|
+
return sandbox;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Delete the sandbox associated with the given session ID
|
|
203
|
+
*/
|
|
204
|
+
async deleteSandbox(sessionId, projectId) {
|
|
205
|
+
let sandbox = this.sessionSandboxes.get(sessionId);
|
|
206
|
+
// If not in cache, try to load from storage and reconnect
|
|
207
|
+
if (!sandbox || this.isPartiallyInitialized(sandbox)) {
|
|
208
|
+
const storedWorktree = this.dataStorage.load(projectId)?.worktree ?? '';
|
|
209
|
+
const sessionInfo = this.dataStorage.getSession(projectId, storedWorktree, sessionId);
|
|
210
|
+
if (sessionInfo?.sandboxId) {
|
|
211
|
+
const daytona = new sdk_1.Daytona({ apiKey: this.apiKey });
|
|
212
|
+
try {
|
|
213
|
+
sandbox = await daytona.get(sessionInfo.sandboxId);
|
|
214
|
+
this.sessionSandboxes.set(sessionId, sandbox);
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
logger_1.logger.error(`Failed to reconnect to sandbox ${sessionInfo.sandboxId}: ${err}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Delete the sandbox if we have a fully initialized one
|
|
222
|
+
if (this.isFullyInitialized(sandbox)) {
|
|
223
|
+
logger_1.logger.info(`Removing sandbox for session: ${sessionId}`);
|
|
224
|
+
await sandbox.delete();
|
|
225
|
+
this.sessionSandboxes.delete(sessionId);
|
|
226
|
+
// Remove from storage
|
|
227
|
+
const projectData = this.dataStorage.load(projectId);
|
|
228
|
+
if (projectData) {
|
|
229
|
+
this.dataStorage.removeSession(projectId, projectData.worktree, sessionId);
|
|
230
|
+
}
|
|
231
|
+
logger_1.logger.info(`Sandbox deleted successfully.`);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
logger_1.logger.warn(`No sandbox found for session: ${sessionId}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
exports.DaytonaSessionManager = DaytonaSessionManager;
|
|
239
|
+
//# sourceMappingURL=session-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../../../../../../libs/opencode-plugin/.opencode/plugin/daytona/core/session-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Daytona Platforms Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Global toast notification singleton
|
|
7
|
+
* Queues toasts to prevent showing multiple at the same time
|
|
8
|
+
*/
|
|
9
|
+
type ToastVariant = 'success' | 'error' | 'warning' | 'info';
|
|
10
|
+
interface ToastOptions {
|
|
11
|
+
title: string;
|
|
12
|
+
message: string;
|
|
13
|
+
variant?: ToastVariant;
|
|
14
|
+
}
|
|
15
|
+
interface TuiShowToast {
|
|
16
|
+
showToast: (options: {
|
|
17
|
+
body: {
|
|
18
|
+
title: string;
|
|
19
|
+
message: string;
|
|
20
|
+
variant: ToastVariant;
|
|
21
|
+
};
|
|
22
|
+
}) => void;
|
|
23
|
+
}
|
|
24
|
+
declare class ToastManager {
|
|
25
|
+
private tui;
|
|
26
|
+
private queue;
|
|
27
|
+
private isShowing;
|
|
28
|
+
/**
|
|
29
|
+
* Initialize the toast manager with the TUI instance
|
|
30
|
+
*/
|
|
31
|
+
initialize(tui: TuiShowToast | null | undefined): void;
|
|
32
|
+
/**
|
|
33
|
+
* Show a toast notification
|
|
34
|
+
* If a toast is currently showing, this will be queued
|
|
35
|
+
*/
|
|
36
|
+
show(options: ToastOptions): void;
|
|
37
|
+
/**
|
|
38
|
+
* Process the toast queue, showing one toast at a time
|
|
39
|
+
*/
|
|
40
|
+
private processQueue;
|
|
41
|
+
/**
|
|
42
|
+
* Clear all pending toasts
|
|
43
|
+
*/
|
|
44
|
+
clear(): void;
|
|
45
|
+
}
|
|
46
|
+
export declare const toast: ToastManager;
|
|
47
|
+
export {};
|