coding-tool-x 3.7.0 → 3.7.1
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/README.md +5 -6
- package/dist/web/assets/{Analytics-Dma_j2Rq.js → Analytics-Dpje9L84.js} +1 -1
- package/dist/web/assets/{ConfigTemplates-C49Y1PLH.js → ConfigTemplates-Cz6kasek.js} +1 -1
- package/dist/web/assets/Home-BwTaYu3q.js +1 -0
- package/dist/web/assets/Home-Jom_ZcdY.css +1 -0
- package/dist/web/assets/{PluginManager-B1ECTHyY.js → PluginManager-DsN-xNXx.js} +1 -1
- package/dist/web/assets/ProjectList-4BCObimU.js +1 -0
- package/dist/web/assets/{ProjectList-B_L55-l9.css → ProjectList-D3a0oRum.css} +1 -1
- package/dist/web/assets/{SessionList-CH5GwwiJ.js → SessionList-D4c8FRzq.js} +1 -1
- package/dist/web/assets/{SkillManager-CRyVhjYQ.js → SkillManager-C-KYbXB5.js} +1 -1
- package/dist/web/assets/{WorkspaceManager-CO9tclVt.js → WorkspaceManager-B-BlPJHX.js} +1 -1
- package/dist/web/assets/index-Btfvh0GG.js +2 -0
- package/dist/web/assets/{index-CM26UrnJ.css → index-CLNa6DhH.css} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +2 -1
- package/src/commands/channels.js +8 -8
- package/src/commands/daemon.js +4 -4
- package/src/commands/doctor.js +1 -1
- package/src/commands/logs.js +1 -3
- package/src/commands/port-config.js +4 -4
- package/src/commands/proxy-control.js +13 -13
- package/src/commands/stats.js +6 -6
- package/src/commands/toggle-proxy.js +8 -8
- package/src/config/default.js +3 -3
- package/src/config/paths.js +46 -49
- package/src/index.js +4 -5
- package/src/server/api/commands.js +1 -1
- package/src/server/api/config-export.js +2 -2
- package/src/server/api/config-registry.js +1 -1
- package/src/server/api/config.js +1 -1
- package/src/server/api/dashboard.js +16 -16
- package/src/server/api/mcp.js +2 -2
- package/src/server/api/{pi-channels.js → omp-channels.js} +15 -15
- package/src/server/api/{pi-config.js → omp-config.js} +13 -13
- package/src/server/api/{pi-projects.js → omp-projects.js} +5 -5
- package/src/server/api/{pi-proxy.js → omp-proxy.js} +18 -18
- package/src/server/api/{pi-sessions.js → omp-sessions.js} +21 -21
- package/src/server/api/{pi-statistics.js → omp-statistics.js} +1 -1
- package/src/server/api/plugins.js +1 -1
- package/src/server/api/skills.js +1 -1
- package/src/server/api/workspaces.js +1 -1
- package/src/server/index.js +10 -10
- package/src/server/{pi-proxy-server.js → omp-proxy-server.js} +13 -13
- package/src/server/services/channel-balance.js +3 -3
- package/src/server/services/channel-scheduler.js +4 -4
- package/src/server/services/commands-service.js +5 -5
- package/src/server/services/config-export-service.js +53 -53
- package/src/server/services/config-registry-service.js +8 -8
- package/src/server/services/config-sync-manager.js +26 -26
- package/src/server/services/config-templates-service.js +28 -28
- package/src/server/services/mcp-service.js +20 -20
- package/src/server/services/notification-hooks.js +138 -6
- package/src/server/services/{pi-auth-providers.js → omp-auth-providers.js} +2 -2
- package/src/server/services/{pi-channels.js → omp-channels.js} +5 -5
- package/src/server/services/{pi-config.js → omp-config.js} +47 -65
- package/src/server/services/{pi-sessions.js → omp-sessions.js} +20 -20
- package/src/server/services/{pi-settings-manager.js → omp-settings-manager.js} +422 -18
- package/src/server/services/{pi-statistics-service.js → omp-statistics-service.js} +2 -2
- package/src/server/services/plugins-service.js +122 -122
- package/src/server/services/prompts-service.js +20 -20
- package/src/server/services/proxy-log-helper.js +1 -1
- package/src/server/services/proxy-runtime.js +1 -1
- package/src/server/services/skill-service.js +7 -7
- package/src/server/services/speed-test.js +29 -29
- package/src/server/services/ui-config.js +3 -3
- package/src/server/services/workspace-service.js +8 -8
- package/src/server/websocket-server.js +4 -4
- package/src/shared/platforms.js +201 -0
- package/dist/web/assets/Home-DGGC8H4g.js +0 -1
- package/dist/web/assets/Home-ewgeIhF7.css +0 -1
- package/dist/web/assets/ProjectList-DyiGyT-H.js +0 -1
- package/dist/web/assets/index-EQq56pRa.js +0 -2
|
@@ -2,10 +2,9 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { execFileSync } = require('child_process');
|
|
4
4
|
const yaml = require('js-yaml');
|
|
5
|
-
const { HOME_DIR } = require('../../config/paths');
|
|
5
|
+
const { HOME_DIR, PATHS = {} } = require('../../config/paths');
|
|
6
6
|
|
|
7
7
|
const DEFAULT_OMP_COMMAND = 'omp';
|
|
8
|
-
const LEGACY_PI_COMMAND = 'pi';
|
|
9
8
|
|
|
10
9
|
function expandHome(input = '') {
|
|
11
10
|
const value = String(input || '').trim();
|
|
@@ -22,10 +21,7 @@ function normalizeProfileName(profile = '') {
|
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
function getOmpProfile(env = process.env) {
|
|
25
|
-
|
|
26
|
-
return normalizeProfileName(env.OMP_PROFILE);
|
|
27
|
-
}
|
|
28
|
-
return normalizeProfileName(env.PI_PROFILE);
|
|
24
|
+
return normalizeProfileName(env.OMP_PROFILE);
|
|
29
25
|
}
|
|
30
26
|
|
|
31
27
|
function isAbsolutePathLike(value = '') {
|
|
@@ -33,7 +29,7 @@ function isAbsolutePathLike(value = '') {
|
|
|
33
29
|
}
|
|
34
30
|
|
|
35
31
|
function getOmpConfigRoot(env = process.env) {
|
|
36
|
-
const configured = expandHome(env.
|
|
32
|
+
const configured = expandHome(env.OMP_CONFIG_DIR || '');
|
|
37
33
|
if (!configured) return path.join(HOME_DIR, '.omp');
|
|
38
34
|
return isAbsolutePathLike(configured) ? configured : path.join(HOME_DIR, configured);
|
|
39
35
|
}
|
|
@@ -46,14 +42,10 @@ function getDefaultOmpAgentDir(env = process.env) {
|
|
|
46
42
|
: path.join(configRoot, 'agent');
|
|
47
43
|
}
|
|
48
44
|
|
|
49
|
-
function
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function getFallbackPiAgentDir(runtime, env = process.env) {
|
|
54
|
-
const configured = expandHome(env.PI_CODING_AGENT_DIR || '');
|
|
45
|
+
function getFallbackOmpAgentDir(runtime, env = process.env) {
|
|
46
|
+
const configured = expandHome(env.OMP_CODING_AGENT_DIR || '');
|
|
55
47
|
if (configured) return configured;
|
|
56
|
-
return
|
|
48
|
+
return getDefaultOmpAgentDir(env);
|
|
57
49
|
}
|
|
58
50
|
|
|
59
51
|
function buildCommandEnv(env = process.env) {
|
|
@@ -63,7 +55,7 @@ function buildCommandEnv(env = process.env) {
|
|
|
63
55
|
};
|
|
64
56
|
}
|
|
65
57
|
|
|
66
|
-
function
|
|
58
|
+
function runOmpCommand(command, args = [], env = process.env, options = {}, stdio = ['ignore', 'pipe', 'pipe']) {
|
|
67
59
|
const runner = options.commandRunner || execFileSync;
|
|
68
60
|
return runner(command, args, {
|
|
69
61
|
encoding: 'utf8',
|
|
@@ -75,7 +67,7 @@ function runPiCommand(command, args = [], env = process.env, options = {}, stdio
|
|
|
75
67
|
|
|
76
68
|
function readOmpAgentDirFromCommand(command, env = process.env, options = {}) {
|
|
77
69
|
try {
|
|
78
|
-
const output =
|
|
70
|
+
const output = runOmpCommand(command, ['config', 'path'], env, options);
|
|
79
71
|
const agentDir = String(output || '').trim().split(/\r?\n/).find(Boolean);
|
|
80
72
|
return agentDir ? path.resolve(expandHome(agentDir)) : '';
|
|
81
73
|
} catch {
|
|
@@ -83,20 +75,20 @@ function readOmpAgentDirFromCommand(command, env = process.env, options = {}) {
|
|
|
83
75
|
}
|
|
84
76
|
}
|
|
85
77
|
|
|
86
|
-
function
|
|
87
|
-
const runtime = options.runtime ||
|
|
78
|
+
function getOmpAgentDir(env = process.env, options = {}) {
|
|
79
|
+
const runtime = options.runtime || resolveOmpRuntime(env, options);
|
|
88
80
|
if (runtime.runtime === 'omp' && runtime.installed) {
|
|
89
81
|
const commandAgentDir = readOmpAgentDirFromCommand(runtime.command, env, options);
|
|
90
82
|
if (commandAgentDir) {
|
|
91
83
|
return commandAgentDir;
|
|
92
84
|
}
|
|
93
85
|
}
|
|
94
|
-
return path.resolve(expandHome(
|
|
86
|
+
return path.resolve(expandHome(getFallbackOmpAgentDir(runtime, env)));
|
|
95
87
|
}
|
|
96
88
|
|
|
97
|
-
function
|
|
98
|
-
const runtime = options.runtime ||
|
|
99
|
-
const agentDir =
|
|
89
|
+
function getOmpPaths(env = process.env, options = {}) {
|
|
90
|
+
const runtime = options.runtime || resolveOmpRuntime(env, options);
|
|
91
|
+
const agentDir = getOmpAgentDir(env, { ...options, runtime });
|
|
100
92
|
return {
|
|
101
93
|
agentDir,
|
|
102
94
|
config: path.join(agentDir, 'config.yml'),
|
|
@@ -115,11 +107,12 @@ function getPiPaths(env = process.env, options = {}) {
|
|
|
115
107
|
extensions: path.join(agentDir, 'extensions'),
|
|
116
108
|
themes: path.join(agentDir, 'themes'),
|
|
117
109
|
packages: path.join(agentDir, 'packages'),
|
|
118
|
-
managedProviderExtension: path.join(agentDir, 'extensions', 'coding-tool-x-provider.ts')
|
|
110
|
+
managedProviderExtension: path.join(agentDir, 'extensions', 'coding-tool-x-provider.ts'),
|
|
111
|
+
managedVisibilityState: path.join(PATHS.storage || path.join(HOME_DIR, '.cc-tool', 'storage'), 'omp-managed-visibility.json')
|
|
119
112
|
};
|
|
120
113
|
}
|
|
121
114
|
|
|
122
|
-
function
|
|
115
|
+
function ensureOmpDir(dirPath) {
|
|
123
116
|
if (!fs.existsSync(dirPath)) {
|
|
124
117
|
fs.mkdirSync(dirPath, { recursive: true });
|
|
125
118
|
}
|
|
@@ -136,7 +129,7 @@ function readJsonFile(filePath, fallback = {}) {
|
|
|
136
129
|
}
|
|
137
130
|
|
|
138
131
|
function writeJsonFile(filePath, data) {
|
|
139
|
-
|
|
132
|
+
ensureOmpDir(path.dirname(filePath));
|
|
140
133
|
fs.writeFileSync(filePath, JSON.stringify(data || {}, null, 2), 'utf8');
|
|
141
134
|
}
|
|
142
135
|
|
|
@@ -153,7 +146,7 @@ function readYamlFile(filePath, fallback = {}) {
|
|
|
153
146
|
}
|
|
154
147
|
|
|
155
148
|
function writeYamlFile(filePath, data) {
|
|
156
|
-
|
|
149
|
+
ensureOmpDir(path.dirname(filePath));
|
|
157
150
|
fs.writeFileSync(filePath, yaml.dump(data || {}, {
|
|
158
151
|
lineWidth: 120,
|
|
159
152
|
noRefs: true,
|
|
@@ -161,39 +154,38 @@ function writeYamlFile(filePath, data) {
|
|
|
161
154
|
}), 'utf8');
|
|
162
155
|
}
|
|
163
156
|
|
|
164
|
-
function
|
|
165
|
-
const paths =
|
|
157
|
+
function readOmpSettings() {
|
|
158
|
+
const paths = getOmpPaths();
|
|
166
159
|
return readYamlFile(paths.settings, readJsonFile(paths.settingsJsonLegacy, {}));
|
|
167
160
|
}
|
|
168
161
|
|
|
169
|
-
function
|
|
170
|
-
writeYamlFile(
|
|
162
|
+
function writeOmpSettings(settings) {
|
|
163
|
+
writeYamlFile(getOmpPaths().settings, settings || {});
|
|
171
164
|
}
|
|
172
165
|
|
|
173
|
-
function
|
|
174
|
-
return String(env.OMP_COMMAND ||
|
|
166
|
+
function getOmpCommand(env = process.env) {
|
|
167
|
+
return String(env.OMP_COMMAND || DEFAULT_OMP_COMMAND).trim() || DEFAULT_OMP_COMMAND;
|
|
175
168
|
}
|
|
176
169
|
|
|
177
170
|
function commandExists(command, env = process.env, options = {}) {
|
|
178
171
|
try {
|
|
179
|
-
|
|
172
|
+
runOmpCommand(command, ['--version'], env, options, 'ignore');
|
|
180
173
|
return true;
|
|
181
174
|
} catch {
|
|
182
175
|
return false;
|
|
183
176
|
}
|
|
184
177
|
}
|
|
185
178
|
|
|
186
|
-
function
|
|
187
|
-
const configured = env.OMP_COMMAND
|
|
179
|
+
function resolveOmpRuntime(env = process.env, options = {}) {
|
|
180
|
+
const configured = env.OMP_COMMAND;
|
|
188
181
|
if (configured) {
|
|
189
|
-
const command =
|
|
190
|
-
const source = env.OMP_COMMAND ? 'OMP_COMMAND' : 'PI_COMMAND';
|
|
182
|
+
const command = getOmpCommand(env);
|
|
191
183
|
return {
|
|
192
184
|
command,
|
|
193
|
-
runtime:
|
|
185
|
+
runtime: 'omp',
|
|
194
186
|
installed: commandExists(command, env, options),
|
|
195
187
|
configured: true,
|
|
196
|
-
commandSource:
|
|
188
|
+
commandSource: 'OMP_COMMAND'
|
|
197
189
|
};
|
|
198
190
|
}
|
|
199
191
|
|
|
@@ -207,16 +199,6 @@ function resolvePiRuntime(env = process.env, options = {}) {
|
|
|
207
199
|
};
|
|
208
200
|
}
|
|
209
201
|
|
|
210
|
-
if (commandExists(LEGACY_PI_COMMAND, env, options)) {
|
|
211
|
-
return {
|
|
212
|
-
command: LEGACY_PI_COMMAND,
|
|
213
|
-
runtime: 'pi',
|
|
214
|
-
installed: true,
|
|
215
|
-
configured: false,
|
|
216
|
-
commandSource: 'path'
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
|
|
220
202
|
return {
|
|
221
203
|
command: DEFAULT_OMP_COMMAND,
|
|
222
204
|
runtime: 'omp',
|
|
@@ -226,12 +208,12 @@ function resolvePiRuntime(env = process.env, options = {}) {
|
|
|
226
208
|
};
|
|
227
209
|
}
|
|
228
210
|
|
|
229
|
-
function
|
|
230
|
-
const runtime = options.runtime ||
|
|
211
|
+
function isOmpInstalled(env = process.env, options = {}) {
|
|
212
|
+
const runtime = options.runtime || resolveOmpRuntime(env, options);
|
|
231
213
|
if (runtime.installed) {
|
|
232
214
|
return true;
|
|
233
215
|
}
|
|
234
|
-
return fs.existsSync(
|
|
216
|
+
return fs.existsSync(getOmpPaths(env, { ...options, runtime }).agentDir);
|
|
235
217
|
}
|
|
236
218
|
|
|
237
219
|
function readTextFile(filePath, fallback = '') {
|
|
@@ -243,11 +225,11 @@ function readTextFile(filePath, fallback = '') {
|
|
|
243
225
|
}
|
|
244
226
|
}
|
|
245
227
|
|
|
246
|
-
function
|
|
247
|
-
const runtime =
|
|
248
|
-
const paths =
|
|
228
|
+
function getOmpStatus(env = process.env, options = {}) {
|
|
229
|
+
const runtime = resolveOmpRuntime(env, options);
|
|
230
|
+
const paths = getOmpPaths(env, { ...options, runtime });
|
|
249
231
|
return {
|
|
250
|
-
installed:
|
|
232
|
+
installed: isOmpInstalled(env, { ...options, runtime }),
|
|
251
233
|
runtime: runtime.runtime,
|
|
252
234
|
command: runtime.command,
|
|
253
235
|
commandSource: runtime.commandSource,
|
|
@@ -269,19 +251,19 @@ function getPiStatus(env = process.env, options = {}) {
|
|
|
269
251
|
|
|
270
252
|
module.exports = {
|
|
271
253
|
expandHome,
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
254
|
+
getOmpAgentDir,
|
|
255
|
+
getOmpPaths,
|
|
256
|
+
ensureOmpDir,
|
|
275
257
|
readJsonFile,
|
|
276
258
|
readYamlFile,
|
|
277
259
|
readTextFile,
|
|
278
260
|
writeJsonFile,
|
|
279
261
|
writeYamlFile,
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
262
|
+
readOmpSettings,
|
|
263
|
+
writeOmpSettings,
|
|
264
|
+
getOmpCommand,
|
|
283
265
|
getOmpProfile,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
266
|
+
resolveOmpRuntime,
|
|
267
|
+
isOmpInstalled,
|
|
268
|
+
getOmpStatus
|
|
287
269
|
};
|
|
@@ -2,10 +2,10 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { execFileSync } = require('child_process');
|
|
4
4
|
const { PATHS, HOME_DIR } = require('../../config/paths');
|
|
5
|
-
const {
|
|
5
|
+
const { getOmpCommand, getOmpPaths, isOmpInstalled, resolveOmpRuntime } = require('./omp-config');
|
|
6
6
|
|
|
7
|
-
const PROJECT_ORDER_FILE = PATHS.
|
|
8
|
-
const SESSION_ORDER_FILE = PATHS.
|
|
7
|
+
const PROJECT_ORDER_FILE = PATHS.ompProjectOrder;
|
|
8
|
+
const SESSION_ORDER_FILE = PATHS.ompSessionOrder;
|
|
9
9
|
|
|
10
10
|
function ensureDir(dirPath) {
|
|
11
11
|
if (!fs.existsSync(dirPath)) {
|
|
@@ -52,7 +52,7 @@ function getDisplayName(cwd = '') {
|
|
|
52
52
|
return path.basename(normalized) || normalized;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
function
|
|
55
|
+
function parseOmpSessionId(filePath = '') {
|
|
56
56
|
const base = path.basename(filePath, '.jsonl');
|
|
57
57
|
const match = base.match(/([0-9a-f]{8}-[0-9a-f-]{8,})$/i);
|
|
58
58
|
if (match) return match[1];
|
|
@@ -138,7 +138,7 @@ function readJsonLines(filePath) {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
function
|
|
141
|
+
function convertOmpEntry(entry = {}, index = 0) {
|
|
142
142
|
if (!entry || entry.type !== 'message') {
|
|
143
143
|
return null;
|
|
144
144
|
}
|
|
@@ -174,12 +174,12 @@ function parseSessionFile(filePath) {
|
|
|
174
174
|
const stat = fs.statSync(filePath);
|
|
175
175
|
const entries = readJsonLines(filePath);
|
|
176
176
|
const header = entries.find(entry => entry?.type === 'session') || {};
|
|
177
|
-
const messages = entries.map(
|
|
177
|
+
const messages = entries.map(convertOmpEntry).filter(Boolean);
|
|
178
178
|
const modelChange = [...entries].reverse().find(entry => entry?.type === 'model_change');
|
|
179
179
|
const firstUser = messages.find(message => message.type === 'user');
|
|
180
180
|
const lastAssistant = [...messages].reverse().find(message => message.type === 'assistant') || {};
|
|
181
181
|
const cwd = header.cwd || messages.find(message => message.cwd)?.cwd || path.dirname(filePath);
|
|
182
|
-
const sessionId = header.id ||
|
|
182
|
+
const sessionId = header.id || parseOmpSessionId(filePath);
|
|
183
183
|
const usage = messages.reduce((acc, message) => {
|
|
184
184
|
if (message.type !== 'assistant') return acc;
|
|
185
185
|
const current = parseUsage(message.usage || {});
|
|
@@ -207,11 +207,11 @@ function parseSessionFile(filePath) {
|
|
|
207
207
|
mtime: new Date(stat.mtimeMs).toISOString(),
|
|
208
208
|
mtimeMs: stat.mtimeMs,
|
|
209
209
|
timestamp: header.timestamp || null,
|
|
210
|
-
source: '
|
|
210
|
+
source: 'omp'
|
|
211
211
|
};
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
function scanSessionFiles(rootDir =
|
|
214
|
+
function scanSessionFiles(rootDir = getOmpPaths().sessions) {
|
|
215
215
|
if (!fs.existsSync(rootDir)) {
|
|
216
216
|
return [];
|
|
217
217
|
}
|
|
@@ -273,7 +273,7 @@ function getProjects() {
|
|
|
273
273
|
latestSession: null,
|
|
274
274
|
mtime: session.mtime,
|
|
275
275
|
mtimeMs: 0,
|
|
276
|
-
source: '
|
|
276
|
+
source: 'omp'
|
|
277
277
|
};
|
|
278
278
|
existing.sessionCount += 1;
|
|
279
279
|
if ((session.mtimeMs || 0) > (existing.mtimeMs || 0)) {
|
|
@@ -324,7 +324,7 @@ function normalizeSession(session) {
|
|
|
324
324
|
firstMessage: session.firstMessage || null,
|
|
325
325
|
gitBranch: null,
|
|
326
326
|
forkedFrom: null,
|
|
327
|
-
source: '
|
|
327
|
+
source: 'omp',
|
|
328
328
|
provider: session.provider || '',
|
|
329
329
|
model: session.model || '',
|
|
330
330
|
size: session.size || 0,
|
|
@@ -345,7 +345,7 @@ function getSessionMessages(sessionId) {
|
|
|
345
345
|
if (!session) {
|
|
346
346
|
throw new Error('Session not found');
|
|
347
347
|
}
|
|
348
|
-
return readJsonLines(session.filePath).map(
|
|
348
|
+
return readJsonLines(session.filePath).map(convertOmpEntry).filter(Boolean);
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
function getRecentSessions(limit = 5) {
|
|
@@ -359,7 +359,7 @@ function searchSessions(keyword, contextLength = 35, projectName = null) {
|
|
|
359
359
|
return getAllSessions()
|
|
360
360
|
.filter(session => !projectName || session.projectName === projectName)
|
|
361
361
|
.map((session) => {
|
|
362
|
-
const messages = readJsonLines(session.filePath).map(
|
|
362
|
+
const messages = readJsonLines(session.filePath).map(convertOmpEntry).filter(Boolean);
|
|
363
363
|
const matches = [];
|
|
364
364
|
messages.forEach((message) => {
|
|
365
365
|
const text = String(message.content || '');
|
|
@@ -412,7 +412,7 @@ function forkSession(sessionId) {
|
|
|
412
412
|
const forkId = `fork-${Date.now()}`;
|
|
413
413
|
const targetPath = path.join(parsed.dir, `${parsed.name}-${forkId}${parsed.ext}`);
|
|
414
414
|
fs.copyFileSync(session.filePath, targetPath);
|
|
415
|
-
return { success: true, newSessionId:
|
|
415
|
+
return { success: true, newSessionId: parseOmpSessionId(targetPath), filePath: targetPath };
|
|
416
416
|
}
|
|
417
417
|
|
|
418
418
|
function saveProjectOrder(order) {
|
|
@@ -446,19 +446,19 @@ function buildLaunchCommand(sessionId, cwd, options = {}) {
|
|
|
446
446
|
} else {
|
|
447
447
|
args.push('--session', shellQuote(sessionId));
|
|
448
448
|
}
|
|
449
|
-
return `${
|
|
449
|
+
return `${getOmpCommand()} ${args.join(' ')}`;
|
|
450
450
|
}
|
|
451
451
|
|
|
452
452
|
function shellQuote(value) {
|
|
453
453
|
return `"${String(value).replace(/"/g, '\\"')}"`;
|
|
454
454
|
}
|
|
455
455
|
|
|
456
|
-
function
|
|
457
|
-
if (
|
|
458
|
-
const runtime =
|
|
456
|
+
function isOmpCliInstalled() {
|
|
457
|
+
if (isOmpInstalled()) return true;
|
|
458
|
+
const runtime = resolveOmpRuntime();
|
|
459
459
|
if (runtime.installed) return true;
|
|
460
460
|
try {
|
|
461
|
-
execFileSync(
|
|
461
|
+
execFileSync(getOmpCommand(), ['--version'], { stdio: 'ignore', timeout: 3000 });
|
|
462
462
|
return true;
|
|
463
463
|
} catch {
|
|
464
464
|
return false;
|
|
@@ -479,7 +479,7 @@ module.exports = {
|
|
|
479
479
|
getSessionById,
|
|
480
480
|
getSessionMessages,
|
|
481
481
|
getSessionsByProject,
|
|
482
|
-
|
|
482
|
+
isOmpInstalled: isOmpCliInstalled,
|
|
483
483
|
normalizeSession,
|
|
484
484
|
parseSessionFile,
|
|
485
485
|
scanSessionFiles,
|